From 8c72246ce7e7d6442c0d811a55faa516ecd5aa6c Mon Sep 17 00:00:00 2001 From: Maliakal Dhanya Date: Wed, 21 May 2014 09:59:37 +0200 Subject: [PATCH 001/474] new separate receiver --- slsReceiverSoftware/Makefile | 71 + slsReceiverSoftware/MySocketTCP/._.DS_Store | Bin 0 -> 82 bytes slsReceiverSoftware/MySocketTCP/Makefile | 23 + slsReceiverSoftware/MySocketTCP/MySocketTCP.c | 1 + .../MySocketTCP/MySocketTCP.cpp | 1 + .../MySocketTCP/MySocketTCP.cxx | 53 + slsReceiverSoftware/MySocketTCP/MySocketTCP.h | 79 + .../MySocketTCP/genericSocket.h | 686 ++++++ slsReceiverSoftware/MySocketTCP/rec | Bin 0 -> 14727 bytes slsReceiverSoftware/MySocketTCP/rec.cxx | 31 + slsReceiverSoftware/MySocketTCP/send | Bin 0 -> 14960 bytes slsReceiverSoftware/MySocketTCP/send.cxx | 40 + slsReceiverSoftware/includes/circularFifo.h | 261 +++ slsReceiverSoftware/includes/receiver_defs.h | 72 + .../includes/sls_receiver_defs.h | 118 + .../includes/sls_receiver_funcs.h | 55 + .../includes/svnInfoReceiver.h | 11 + .../includes/svnInfoReceiverTmp.h | 11 + .../slsDetectorCalibration/MovingStat.h | 130 ++ .../slsDetectorCalibration/RunningStat.h | 55 + .../chiptestBoardData.h | 89 + .../commonModeSubtraction.h | 82 + .../slsDetectorCalibration/demoCreateTree.C | 31 + .../slsDetectorCalibration/doxy.config | 85 + .../energyCalibration.cpp | 527 +++++ .../energyCalibration.h | 452 ++++ .../slsDetectorCalibration/gMapDemo.C | 11 + .../slsDetectorCalibration/gainMap.C | 228 ++ .../gotthardModuleData.h | 148 ++ .../gotthardShortModuleData.h | 127 ++ .../slsDetectorCalibration/jungfrau02Data.h | 156 ++ .../slsDetectorCalibration/jungfrauReadData.C | 264 +++ .../moench02ModuleData.h | 137 ++ .../slsDetectorCalibration/moenchCommonMode.h | 45 + .../slsDetectorCalibration/moenchMakeTree.C | 244 ++ .../slsDetectorCalibration/moenchReadData.C | 236 ++ .../slsDetectorCalibration/moenchReadDataMT.C | 52 + .../pedestalSubtraction.h | 48 + .../slsDetectorCalibration/raedNoiseData.C | 136 ++ .../slsDetectorCalibration/readJungfrauData.C | 31 + .../singlePhotonDetector.h | 387 ++++ .../single_photon_hit.h | 62 + .../slsDetectorCalibration/slsDetectorData.h | 251 +++ .../slsDetectorCalibration/slsReceiverData.h | 171 ++ slsReceiverSoftware/slsReceiver/.cproject | 51 + slsReceiverSoftware/slsReceiver/.project | 28 + slsReceiverSoftware/slsReceiver/Makefile | 68 + .../slsReceiver/eigerReceiver/RestHelper.h | 195 ++ .../eigerReceiver/eigerReceiver.cpp | 254 +++ .../slsReceiver/eigerReceiver/eigerReceiver.h | 211 ++ .../eigerReceiver/eigerReceiverDummy.cpp | 99 + .../eigerReceiver/eigerReceiverTest.cpp | 97 + .../slsReceiver/slsReceiver.cpp | 81 + .../slsReceiver/slsReceiverTCPIPInterface.cpp | 1991 +++++++++++++++++ .../slsReceiver/slsReceiverTCPIPInterface.h | 238 ++ .../slsReceiver/slsReceiverUDPFunctions.cpp | 1968 ++++++++++++++++ .../slsReceiver/slsReceiverUDPFunctions.h | 685 ++++++ .../slsReceiver/slsReceiverUsers.cpp | 43 + .../slsReceiver/slsReceiverUsers.h | 85 + 59 files changed, 11792 insertions(+) create mode 100644 slsReceiverSoftware/Makefile create mode 100644 slsReceiverSoftware/MySocketTCP/._.DS_Store create mode 100644 slsReceiverSoftware/MySocketTCP/Makefile create mode 120000 slsReceiverSoftware/MySocketTCP/MySocketTCP.c create mode 120000 slsReceiverSoftware/MySocketTCP/MySocketTCP.cpp create mode 100644 slsReceiverSoftware/MySocketTCP/MySocketTCP.cxx create mode 100644 slsReceiverSoftware/MySocketTCP/MySocketTCP.h create mode 100644 slsReceiverSoftware/MySocketTCP/genericSocket.h create mode 100755 slsReceiverSoftware/MySocketTCP/rec create mode 100644 slsReceiverSoftware/MySocketTCP/rec.cxx create mode 100755 slsReceiverSoftware/MySocketTCP/send create mode 100644 slsReceiverSoftware/MySocketTCP/send.cxx create mode 100644 slsReceiverSoftware/includes/circularFifo.h create mode 100755 slsReceiverSoftware/includes/receiver_defs.h create mode 100755 slsReceiverSoftware/includes/sls_receiver_defs.h create mode 100644 slsReceiverSoftware/includes/sls_receiver_funcs.h create mode 100644 slsReceiverSoftware/includes/svnInfoReceiver.h create mode 100644 slsReceiverSoftware/includes/svnInfoReceiverTmp.h create mode 100755 slsReceiverSoftware/slsDetectorCalibration/MovingStat.h create mode 100755 slsReceiverSoftware/slsDetectorCalibration/RunningStat.h create mode 100644 slsReceiverSoftware/slsDetectorCalibration/chiptestBoardData.h create mode 100644 slsReceiverSoftware/slsDetectorCalibration/commonModeSubtraction.h create mode 100644 slsReceiverSoftware/slsDetectorCalibration/demoCreateTree.C create mode 100644 slsReceiverSoftware/slsDetectorCalibration/doxy.config create mode 100644 slsReceiverSoftware/slsDetectorCalibration/energyCalibration.cpp create mode 100644 slsReceiverSoftware/slsDetectorCalibration/energyCalibration.h create mode 100644 slsReceiverSoftware/slsDetectorCalibration/gMapDemo.C create mode 100644 slsReceiverSoftware/slsDetectorCalibration/gainMap.C create mode 100644 slsReceiverSoftware/slsDetectorCalibration/gotthardModuleData.h create mode 100644 slsReceiverSoftware/slsDetectorCalibration/gotthardShortModuleData.h create mode 100644 slsReceiverSoftware/slsDetectorCalibration/jungfrau02Data.h create mode 100644 slsReceiverSoftware/slsDetectorCalibration/jungfrauReadData.C create mode 100644 slsReceiverSoftware/slsDetectorCalibration/moench02ModuleData.h create mode 100644 slsReceiverSoftware/slsDetectorCalibration/moenchCommonMode.h create mode 100644 slsReceiverSoftware/slsDetectorCalibration/moenchMakeTree.C create mode 100644 slsReceiverSoftware/slsDetectorCalibration/moenchReadData.C create mode 100644 slsReceiverSoftware/slsDetectorCalibration/moenchReadDataMT.C create mode 100644 slsReceiverSoftware/slsDetectorCalibration/pedestalSubtraction.h create mode 100644 slsReceiverSoftware/slsDetectorCalibration/raedNoiseData.C create mode 100644 slsReceiverSoftware/slsDetectorCalibration/readJungfrauData.C create mode 100644 slsReceiverSoftware/slsDetectorCalibration/singlePhotonDetector.h create mode 100644 slsReceiverSoftware/slsDetectorCalibration/single_photon_hit.h create mode 100644 slsReceiverSoftware/slsDetectorCalibration/slsDetectorData.h create mode 100644 slsReceiverSoftware/slsDetectorCalibration/slsReceiverData.h create mode 100644 slsReceiverSoftware/slsReceiver/.cproject create mode 100644 slsReceiverSoftware/slsReceiver/.project create mode 100644 slsReceiverSoftware/slsReceiver/Makefile create mode 100644 slsReceiverSoftware/slsReceiver/eigerReceiver/RestHelper.h create mode 100644 slsReceiverSoftware/slsReceiver/eigerReceiver/eigerReceiver.cpp create mode 100644 slsReceiverSoftware/slsReceiver/eigerReceiver/eigerReceiver.h create mode 100644 slsReceiverSoftware/slsReceiver/eigerReceiver/eigerReceiverDummy.cpp create mode 100644 slsReceiverSoftware/slsReceiver/eigerReceiver/eigerReceiverTest.cpp create mode 100644 slsReceiverSoftware/slsReceiver/slsReceiver.cpp create mode 100644 slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.cpp create mode 100644 slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.h create mode 100644 slsReceiverSoftware/slsReceiver/slsReceiverUDPFunctions.cpp create mode 100644 slsReceiverSoftware/slsReceiver/slsReceiverUDPFunctions.h create mode 100644 slsReceiverSoftware/slsReceiver/slsReceiverUsers.cpp create mode 100644 slsReceiverSoftware/slsReceiver/slsReceiverUsers.h diff --git a/slsReceiverSoftware/Makefile b/slsReceiverSoftware/Makefile new file mode 100644 index 000000000..f8df05639 --- /dev/null +++ b/slsReceiverSoftware/Makefile @@ -0,0 +1,71 @@ + +include ../Makefile.include + +DESTDIR ?= ../bin +LIBDIR ?= $(DESTDIR) +DOCDIR ?= docs + + +CFLAGS= -g -DC_ONLY -fPIC +#FLAGS+= #-DVERBOSE -DVERYVERBOSE + +DFLAGS= -g -DDACS_INT -DSLS_RECEIVER_UDP_FUNCTIONS + +INCLUDES?= -I. -Iincludes -IMySocketTCP -IslsReceiver -IslsDetectorCalibration -IslsReceiver/eigerReceiver -I$(ASM) +#-IslsReceiverInterface + +SRC_CLNT= MySocketTCP/MySocketTCP.cpp slsReceiver/slsReceiverUDPFunctions.cpp slsReceiver/slsReceiverTCPIPInterface.cpp slsReceiver/slsReceiverUsers.cpp +#slsReceiverInterface/receiverInterface.cpp + +OBJS = $(SRC_CLNT:.cpp=.o) +OBJS += slsReceiver/eigerReceiver.o + + +.PHONY: all intdoc package eigerReceiver clean + +all: package $(SRC_CLNT) + +intdoc: $(SRC_H) $(SRC_CLNT) + doxygen doxy.config + + +%.o : %.cpp %.h Makefile +ifeq ($(EIGERSLS),yes) + $(CXX) -DEIGERSLS -o $@ -c $< $(INCLUDES) $(DFLAGS) $(EIGERFLAGS) -fPIC $(EPICSFLAGS) -L/usr/lib64/ #$(FLAGS) +else ifeq ($(ROOTSLS),yes) + echo "with root" + $(CXX) -DROOTSLS -o $@ -c $< $(INCLUDES) $(DFLAGS) $(ROOTFLAGS) -fPIC $(EPICSFLAGS) -L/usr/lib64/ #$(FLAGS) +else + echo "without root" + $(CXX) -o $@ -c $< $(INCLUDES) $(DFLAGS) -fPIC $(EPICSFLAGS) -lpthread #$(FLAGS) +endif + +# LEO: not satisfied by eigerReceiver +package: eigerReceiver $(OBJS) $(DESTDIR)/libSlsReceiver.so $(DESTDIR)/libSlsReceiver.a + +eigerReceiver: + cd slsReceiver && make eigerReceiver + +$(DESTDIR)/libSlsReceiver.so: $(OBJS) + $(CXX) -shared -Wl,-soname,libSlsReceiver.so -o libSlsReceiver.so $(OBJS) -lc $(INCLUDES) $(DFLAGS) $(FLAGS) $(EPICSFLAGS) -L/usr/lib64 -lpthread + $(shell test -d $(DESTDIR) || mkdir -p $(DESTDIR)) + mv libSlsReceiver.so $(DESTDIR) + +$(DESTDIR)/libSlsReceiver.a: $(OBJS) + ar rcs libSlsReceiver.a $(OBJS) + mv libSlsReceiver.a $(DESTDIR) + +clean: + rm -rf $(OBJS) + cd slsReceiver && make clean + cd + +#------------------------------------------------------------------------------- + +install: package + +install_inc: + $(shell test -d $(DESTDIR) || mkdir -p $(DESTDIR)) + cp -P slsReceiver/slsReceiverUsers.h $(DESTDIR) + + diff --git a/slsReceiverSoftware/MySocketTCP/._.DS_Store b/slsReceiverSoftware/MySocketTCP/._.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..c9474ea62235481b7d27ae5a878d2b4070bc6e05 GIT binary patch literal 82 jcmZQz6=P>$V!#9-F-{;h0%8Rq2JwS{7!DlZEK~*nFE;@e literal 0 HcmV?d00001 diff --git a/slsReceiverSoftware/MySocketTCP/Makefile b/slsReceiverSoftware/MySocketTCP/Makefile new file mode 100644 index 000000000..69634f361 --- /dev/null +++ b/slsReceiverSoftware/MySocketTCP/Makefile @@ -0,0 +1,23 @@ + +TOBECLEANED = MySocketTCP.o + +PROGRAMS = rec send + +all: $(PROGRAMS) + +clean: + @rm -f $(TOBECLEANED) $(PROGRAMS) + +rec: MySocketTCP.o rec.cxx + g++ -o $@ $^ + @echo "$@ done" + +send: MySocketTCP.o send.cxx + g++ -o $@ $^ + @echo "$@ done" + +MySocketTCP.o: MySocketTCP.cxx MySocketTCP.h + g++ -c $< + @echo "$@ done" + + diff --git a/slsReceiverSoftware/MySocketTCP/MySocketTCP.c b/slsReceiverSoftware/MySocketTCP/MySocketTCP.c new file mode 120000 index 000000000..a995312db --- /dev/null +++ b/slsReceiverSoftware/MySocketTCP/MySocketTCP.c @@ -0,0 +1 @@ +MySocketTCP.cxx \ No newline at end of file diff --git a/slsReceiverSoftware/MySocketTCP/MySocketTCP.cpp b/slsReceiverSoftware/MySocketTCP/MySocketTCP.cpp new file mode 120000 index 000000000..a995312db --- /dev/null +++ b/slsReceiverSoftware/MySocketTCP/MySocketTCP.cpp @@ -0,0 +1 @@ +MySocketTCP.cxx \ No newline at end of file diff --git a/slsReceiverSoftware/MySocketTCP/MySocketTCP.cxx b/slsReceiverSoftware/MySocketTCP/MySocketTCP.cxx new file mode 100644 index 000000000..ba9583c1c --- /dev/null +++ b/slsReceiverSoftware/MySocketTCP/MySocketTCP.cxx @@ -0,0 +1,53 @@ + +//version 1.0, base development, Ian 19/01/09 + + +#include "MySocketTCP.h" +#include +#include +#include + +using namespace std; + + + + + + + + + +int MySocketTCP::SendData(void* buf,int length){//length in characters + int ndata = SendDataAndKeepConnection(buf,length); + Disconnect(); + return ndata; +} + +int MySocketTCP::SendDataAndKeepConnection(void* buf,int length){//length in characters + if(last_keep_connection_open_action_was_a_send) Disconnect(); //to keep a structured data flow; + + Connect(); + int total_sent=SendDataOnly(buf,length); + last_keep_connection_open_action_was_a_send=1; + return total_sent; +} + + + + +int MySocketTCP::ReceiveData(void* buf,int length){//length in characters + int ndata = ReceiveDataAndKeepConnection(buf,length); + Disconnect(); + return ndata; +} + +int MySocketTCP::ReceiveDataAndKeepConnection(void* buf,int length){//length in characters + if(!last_keep_connection_open_action_was_a_send) Disconnect(); //to a keep structured data flow; + + Connect(); + // should preform two reads one to receive incomming char count + int total_received=ReceiveDataOnly(buf,length); + last_keep_connection_open_action_was_a_send=0; + return total_received; +} + diff --git a/slsReceiverSoftware/MySocketTCP/MySocketTCP.h b/slsReceiverSoftware/MySocketTCP/MySocketTCP.h new file mode 100644 index 000000000..31f56d453 --- /dev/null +++ b/slsReceiverSoftware/MySocketTCP/MySocketTCP.h @@ -0,0 +1,79 @@ + +#ifndef MY_SOCKET_TCP_H +#define MY_SOCKET_TCP_H + + + + +/** + * + * @libdoc The MySocketTCP class provides a simple interface for creating and sending/receiving data over a TCP socket. + * + * @short This class provides a simple interface for creating and sending/receiving data over a TCP socket. + * @author Ian Johnson + * @version 1.0 + */ + + + +//version 1.0, base development, Ian 19/01/09 + +/* Modified by anna on 19.01.2009 */ +/* + canceled SetupParameters() and varaibles intialized in the constructors' headers; + defined SEND_REC_MAX_SIZE (for compatibilty with mythen (and possibly other) pure C servers (i would move it to the common header file) + + added #ifndef C_ONLY... to cutout class definition when including in pure C servers (can be removed if SEND_REC_MAX_SIZE is moved to the common header file) + + defined private variables char hostname[1000] and int portno to store connection informations; + + defined public functions int getHostname(char *name) and int getPortNumber() to retrieve connection informations + + added public function int getErrorStatus() returning 1 if socketDescriptor<0 + + remove exits in the constructors and replace them with socketDescriptor=-1 + + replaced the argument of send/receive data with void (to avoid too much casting or compiler errors/warnings) + + added a function which really does not close the socket between send/receive (senddataonly, receivedataonly) + +*/ + + +/* Modified by Anna on 31.10.2012 + +developed and + +*/ + + +#include "genericSocket.h" +#define TCP_PACKET_SIZE 4096 + +class MySocketTCP: public genericSocket { + + public: + MySocketTCP(const char* const host_ip_or_name, unsigned short int const port_number): genericSocket(host_ip_or_name, port_number,TCP), last_keep_connection_open_action_was_a_send(0){setPacketSize(TCP_PACKET_SIZE);}; // sender (client): where to? ip + MySocketTCP(unsigned short int const port_number):genericSocket(port_number,TCP), last_keep_connection_open_action_was_a_send(0) {setPacketSize(TCP_PACKET_SIZE);}; // receiver (server) local no need for ip + + + //The following two functions will connectioned->send/receive->disconnect + int SendData(void* buf,int length);//length in characters + int ReceiveData(void* buf,int length); + + + //The following two functions stay connected, blocking other connections, and must be manually disconnected, + // when the last call is a SendData() or ReceiveData() the disconnection will be done automatically + //These function will also automatically disconnect->reconnect if + // two reads (or two writes) are called in a row to preserve the data send/receive structure + int SendDataAndKeepConnection(void* buf,int length); + int ReceiveDataAndKeepConnection(void* buf,int length); + + private: + + + bool last_keep_connection_open_action_was_a_send; + + +}; +#endif diff --git a/slsReceiverSoftware/MySocketTCP/genericSocket.h b/slsReceiverSoftware/MySocketTCP/genericSocket.h new file mode 100644 index 000000000..28ae7b650 --- /dev/null +++ b/slsReceiverSoftware/MySocketTCP/genericSocket.h @@ -0,0 +1,686 @@ + +#ifndef GENERIC_SOCKET_H +#define GENERIC_SOCKET_H + + + + + +/** + * + * @libdoc genericSocket provides some functions to open/close sockets both TCP and UDP + * + * @short some functions to open/close sockets both TCP and UDP + * @author Anna Bergamaschi + * @version 0.0 + */ + + + +//version 1.0, base development, Ian 19/01/09 + +/* Modified by anna on 19.01.2009 */ +/* + canceled SetupParameters() and varaibles intialized in the constructors' headers; + defined SEND_REC_MAX_SIZE (for compatibilty with mythen (and possibly other) pure C servers (i would move it to the common header file) + + added #ifndef C_ONLY... to cutout class definition when including in pure C servers (can be removed if SEND_REC_MAX_SIZE is moved to the common header file) + + defined private variables char hostname[1000] and int portno to store connection informations; + + defined public functions int getHostname(char *name) and int getPortNumber() to retrieve connection informations + + added public function int getErrorStatus() returning 1 if socketDescriptor<0 + + remove exits in the constructors and replace them with socketDescriptor=-1 + + replaced the argument of send/receive data with void (to avoid too much casting or compiler errors/warnings) + + added a function which really does not close the socket between send/receive (senddataonly, receivedataonly) +*/ + +#ifdef __CINT__ +//class sockaddr_in; +class socklen_t; +class uint32_t; +class uint32_t_ss; +// CINT view of types: +class sockaddr_in; +// { +// unsigned short int sa_family; +// unsigned char sa_data[14]; +// }; +#else + +#include +#include +#include +#include +#include +#include + +#endif + +#include +#include +#include + +#include +#include +#include + +using namespace std; + +#define DEFAULT_PACKET_SIZE 1286 +#define DEFAULT_PACKETS_PER_FRAME 2 +#define SOCKET_BUFFER_SIZE (100*1024*1024) //100MB +#define DEFAULT_PORTNO 1952 +#define DEFAULT_BACKLOG 5 +#define DEFAULT_UDP_PORTNO 50001 +#define DEFAULT_GUI_PORTNO 65000 + +class genericSocket{ + + public: + + /** + Communication protocol +*/ +enum communicationProtocol{ + TCP, /**< TCP/IP */ + UDP /**< UDP */ +}; + + + genericSocket(const char* const host_ip_or_name, unsigned short int const port_number, communicationProtocol p, int ps = DEFAULT_PACKET_SIZE, int t = DEFAULT_PACKETS_PER_FRAME) : + // portno(port_number), + protocol(p), + is_a_server(0), + socketDescriptor(-1), + file_des(-1), + packet_size(ps), + nsending(0), + nsent(0), + total_sent(0), + packets_per_frame(t)// sender (client): where to? ip + { + + // strcpy(hostname,host_ip_or_name); + struct hostent *hostInfo = gethostbyname(host_ip_or_name); + if (hostInfo == NULL){ + cerr << "Exiting: Problem interpreting host: " << host_ip_or_name << "\n"; + } else { + // Set some fields in the serverAddress structure. + serverAddress.sin_family = hostInfo->h_addrtype; + memcpy((char *) &serverAddress.sin_addr.s_addr, + hostInfo->h_addr_list[0], hostInfo->h_length); + serverAddress.sin_port = htons(port_number); + socketDescriptor=0; //You can use send and recv, //would it work????? + } + clientAddress_length=sizeof(clientAddress); + } + + + int getProtocol(communicationProtocol p) { + switch (p) { + case TCP: + return SOCK_STREAM; + break; + case UDP: + return SOCK_DGRAM; + + default: + cerr << "unknow protocol " << p << endl; + return -1; + } + } + + int getProtocol() {return getProtocol(protocol);}; + + + + + /** + The constructor for a server + @short the contructor for a server + \param port_number port number to listen to + \param p TCP or UDP + \param eth interface name or IP address to listen to (if NULL, listen to all interfaces) + + */ + + genericSocket(unsigned short int const port_number, communicationProtocol p, int ps = DEFAULT_PACKET_SIZE, int t = DEFAULT_PACKETS_PER_FRAME, const char *eth=NULL): + //portno(port_number), + protocol(p), + is_a_server(1), + socketDescriptor(-1), + file_des(-1), + packet_size(ps), + nsending(0), + nsent(0), + total_sent(0), + packets_per_frame(t) + { + +/* // you can specify an IP address: */ +/* */ + +/* // or you can let it automatically select one: */ +/* myaddr.sin_addr.s_addr = INADDR_ANY; */ + + if(serverAddress.sin_port == htons(port_number)){ + socketDescriptor = -10; + return; + } + + char ip[20]; + + strcpy(ip,"0.0.0.0"); + clientAddress_length=sizeof(clientAddress); + if (eth) { + strcpy(ip,nameToIp(string(eth)).c_str()); + if (string(ip)==string("0.0.0.0")) + strcpy(ip,eth); + } + + // strcpy(hostname,"localhost"); //needed?!?!?!? + + + socketDescriptor = socket(AF_INET, getProtocol(),0); //tcp + + if (socketDescriptor < 0) { + cerr << "Can not create socket "<= 0){ \ + close(socketDescriptor); \ + } \ + file_des=-1; \ + serverAddress.sin_port=-1; \ + }; + + +/* /\** @short if client returns hostname for connection */ +/* \param name string to write the hostname to */ +/* \returns 0 if client, 1 if server (in this case ignore name return value) */ + +/* *\/ */ +/* int getHostname(char *name){ */ +/* if (is_a_server==0) { */ +/* strcpy(name,getHostname().c_str()); */ +/* } */ +/* return is_a_server; */ +/* }; */ +/* /\** @short if client returns hostname for connection */ +/* \returns hostname */ + +/* *\/ */ +/* string getHostname(){return string(hostname);}; */ + +/* /\** @short returns port number for connection */ +/* \returns port number */ +/* *\/ */ +/* int getPortNumber(){return portno;}; */ + + /** @short returns communication protocol + \returns TCP or UDP + */ + int getCommunicationProtocol(){return protocol;}; + + + /** @short returns error status + \returns 1 if error + */ + int getErrorStatus(){if (socketDescriptor==-10) return -10; else if (socketDescriptor<0) return 1; else return 0;}; + + + /** @short etablishes connection; disconnect should always follow + \returns 1 if error + */ + int Connect(){//cout<<"connect"<0) return file_des; + if (protocol==UDP) return -1; + + if(is_a_server && protocol==TCP){ //server tcp; the server will wait for the clients connection + if (socketDescriptor>0) { + if ((file_des = accept(socketDescriptor,(struct sockaddr *) &clientAddress, &clientAddress_length)) < 0) { + cerr << "Error: with server accept, connection refused"<=0){ //then was open + if(is_a_server){ + close(file_des); + } + else { + close(socketDescriptor); + socketDescriptor=-1; + } + file_des=-1; + } + } + }; + + + void ShutDownSocket(){ + while(!shutdown(socketDescriptor, SHUT_RDWR)); + }; + + + + /** Set the socket timeout ts is in seconds */ + int SetTimeOut(int ts){ + + + if (ts<=0) + return -1; + + //cout << "socketdescriptor "<< socketDescriptor << endl; + struct timeval tout; + tout.tv_sec = 0; + tout.tv_usec = 0; + if(::setsockopt(socketDescriptor, SOL_SOCKET, SO_RCVTIMEO, &tout, sizeof(struct timeval)) <0) + { + cerr << "Error in setsockopt SO_RCVTIMEO "<< 0 << endl; + } + tout.tv_sec = ts; + tout.tv_usec = 0; + if(::setsockopt(socketDescriptor, SOL_SOCKET, SO_SNDTIMEO, &tout, sizeof(struct timeval)) < 0) + { + cerr << "Error in setsockopt SO_SNDTIMEO " << ts << endl; + } + return 0; + + + }; + + + int setPacketSize(int i=-1) { if (i>=0) packet_size=i; return packet_size;}; + + + + static string ipToName(string ip) { + struct ifaddrs *addrs, *iap; + struct sockaddr_in *sa; + char buf[32]; + + strcpy(buf,"none"); + + getifaddrs(&addrs); + for (iap = addrs; iap != NULL; iap = iap->ifa_next) { + if (iap->ifa_addr && (iap->ifa_flags & IFF_UP) && iap->ifa_addr->sa_family == AF_INET) { + sa = (struct sockaddr_in *)(iap->ifa_addr); + inet_ntop(iap->ifa_addr->sa_family, (void *)&(sa->sin_addr), buf, sizeof(buf)); + if (ip==string(buf)) { + //printf("%s\n", iap->ifa_name); + strcpy(buf,iap->ifa_name); + break; + } + } + } + freeifaddrs(addrs); + return string(buf); + }; + + static string nameToMac(string inf) { + struct ifreq ifr; + int sock, j, k; + char mac[32]; + + sock=getSock(inf,&ifr); + + if (-1==ioctl(sock, SIOCGIFHWADDR, &ifr)) { + perror("ioctl(SIOCGIFHWADDR) "); + return string("00:00:00:00:00:00"); + } + for (j=0, k=0; j<6; j++) { + k+=snprintf(mac+k, sizeof(mac)-k-1, j ? ":%02X" : "%02X", + (int)(unsigned int)(unsigned char)ifr.ifr_hwaddr.sa_data[j]); + } + mac[sizeof(mac)-1]='\0'; + + return string(mac); + + }; + + + + static string nameToIp(string inf){ + struct ifreq ifr; + int sock; + char *p, addr[32]; + + sock=getSock(inf,&ifr); + + if (-1==ioctl(sock, SIOCGIFADDR, &ifr)) { + perror("ioctl(SIOCGIFADDR) "); + return string("0.0.0.0"); + } + p=inet_ntoa(((struct sockaddr_in *)(&ifr.ifr_addr))->sin_addr); + strncpy(addr,p,sizeof(addr)-1); + addr[sizeof(addr)-1]='\0'; + + return string(addr); + + }; + + static int getSock(string inf, struct ifreq *ifr) { + + int sock; + sock=socket(PF_INET, SOCK_STREAM, 0); + if (-1==sock) { + perror("socket() "); + return 1; + } + strncpy(ifr->ifr_name,inf.c_str(),sizeof(ifr->ifr_name)-1); + ifr->ifr_name[sizeof(ifr->ifr_name)-1]='\0'; + + return sock; + + }; + + + int ReceiveDataOnly(void* buf,int length=0){ + + + if (buf==NULL) return -1; + + + total_sent=0; + + switch(protocol) { + case TCP: + if (file_des<0) return -1; + while(length>0){ + nsending = (length>packet_size) ? packet_size:length; + nsent = read(file_des,(char*)buf+total_sent,nsending); + if(!nsent) break; + length-=nsent; + total_sent+=nsent; + } + break; + case UDP: + if (socketDescriptor<0) return -1; + //if length given + if(length){ + while(length>0){ + nsending=packet_size; + nsent = recvfrom(socketDescriptor,(char*)buf+total_sent,nsending, 0, (struct sockaddr *) &clientAddress, &clientAddress_length); + if(!nsent) break; + length-=nsent; + total_sent+=nsent; + } + } + //depends on packets per frame + else{ + for(int i=0;i0) + strcpy(thisClientIP,dummyClientIP); + + if (strcmp(lastClientIP,thisClientIP)) + differentClients=1; + else + differentClients=0; + + return total_sent; + + + + } + + + int SendDataOnly(void *buf, int length) { +#ifdef VERY_VERBOSE + cout << "want to send "<< length << " Bytes" << endl; +#endif + if (buf==NULL) return -1; + + total_sent=0; + + + switch(protocol) { + case TCP: + if (file_des<0) return -1; + while(length>0){ + nsending = (length>packet_size) ? packet_size:length; + nsent = write(file_des,(char*)buf+total_sent,nsending); + if(!nsent) break; + length-=nsent; + total_sent+=nsent; + } + break; + case UDP: + if (socketDescriptor<0) return -1; + while(length>0){ + nsending = (length>packet_size) ? packet_size:length; + nsent = sendto(socketDescriptor,(char*)buf+total_sent,nsending, 0, (struct sockaddr *) &clientAddress, clientAddress_length); + if(!nsent) break; + length-=nsent; + total_sent+=nsent; + } + + break; + default: + ; + } +#ifdef VERY_VERBOSE + cout << "sent "<< total_sent << " Bytes" << endl; +#endif + return total_sent; + + + } + + char lastClientIP[INET_ADDRSTRLEN]; + char thisClientIP[INET_ADDRSTRLEN]; + int differentClients; + + + protected: + + communicationProtocol protocol; + + + + int is_a_server; + + + int socketDescriptor; + int file_des; + + int packet_size; + + struct sockaddr_in clientAddress, serverAddress; + socklen_t clientAddress_length; + + + char dummyClientIP[INET_ADDRSTRLEN]; + + + private: + + int nsending; + int nsent; + int total_sent; + int packets_per_frame; + + + + // pthread_mutex_t mp; +}; +#endif diff --git a/slsReceiverSoftware/MySocketTCP/rec b/slsReceiverSoftware/MySocketTCP/rec new file mode 100755 index 0000000000000000000000000000000000000000..b652bb8f4795994f4cbe47c47317b9aff8e3a018 GIT binary patch literal 14727 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 +#include "MySocketTCP.h" + +using namespace std; + +int main(){ + + char data[50000]; + int length=50000; + + unsigned short int portnum = 1952; + MySocketTCP* sock = new MySocketTCP(portnum); + + cout<<"\tReceived :"<ReceiveDataAndKeepConnection(data,23000)<ReceiveData(data,32200)<ReceiveData(data,33300)<ReceiveData(data,30000)<ReceiveData(data,3222)<tUs8btl_^5hG?LnEib2eRuL^ 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 +#include "MySocketTCP.h" + +using namespace std; + +int main(int argc, char *argv[]){ + + if(argc!=2){ + cout<<"Usage: send ip_addess/hostName"<SendDataAndKeepConnection(data,2000)<SendData(data,2200)<SendData(data,1200)<SendData(data,25000)<SendData(data,222)< +#include +#include +using namespace std; + +typedef double double32_t; +typedef float float32_t; +typedef int int32_t; + + + +/** Circular Fifo (a.k.a. Circular Buffer) +* Thread safe for one reader, and one writer */ +template +class CircularFifo { +public: + + CircularFifo(unsigned int Size) : tail(0), head(0){ + Capacity = Size + 1; + array.resize(Capacity); + sem_init(&free_mutex,0,0); + } + virtual ~CircularFifo() {} + + bool push(Element*& item_); + bool pop(Element*& item_); + + bool isEmpty() const; + bool isFull() const; + + int getSemValue(); + +private: + volatile unsigned int tail; // input index + vector array; + volatile unsigned int head; // output index + unsigned int Capacity; + sem_t free_mutex; + + unsigned int increment(unsigned int idx_) const; +}; + +template +int CircularFifo::getSemValue() +{ + int value; + sem_getvalue(&free_mutex, &value); + return value; +} + + +/** Producer only: Adds item to the circular queue. +* If queue is full at 'push' operation no update/overwrite +* will happen, it is up to the caller to handle this case +* +* \param item_ copy by reference the input item +* \return whether operation was successful or not */ +template +bool CircularFifo::push(Element*& item_) +{ + + int nextTail = increment(tail); + if(nextTail != head) + { + array[tail] = item_; + tail = nextTail; + sem_post(&free_mutex); + return true; + } + + // queue was full + return false; +} + +/** Consumer only: Removes and returns item from the queue +* If queue is empty at 'pop' operation no retrieve will happen +* It is up to the caller to handle this case +* +* \param item_ return by reference the wanted item +* \return whether operation was successful or not */ +template +bool CircularFifo::pop(Element*& item_) +{ + // if(head == tail) + // return false; // empty queue + sem_wait(&free_mutex); + + item_ = array[head]; + head = increment(head); + return true; +} + +/** Useful for testinng and Consumer check of status + * Remember that the 'empty' status can change quickly + * as the Procuder adds more items. + * + * \return true if circular buffer is empty */ +template +bool CircularFifo::isEmpty() const +{ + return (head == tail); +} + +/** Useful for testing and Producer check of status + * Remember that the 'full' status can change quickly + * as the Consumer catches up. + * + * \return true if circular buffer is full. */ +template +bool CircularFifo::isFull() const +{ + int tailCheck = (tail+1) % Capacity; + return (tailCheck == head); +} + +/** Increment helper function for index of the circular queue +* index is inremented or wrapped +* +* \param idx_ the index to the incremented/wrapped +* \return new value for the index */ +template +unsigned int CircularFifo::increment(unsigned int idx_) const +{ + // increment or wrap + // ================= + // index++; + // if(index == array.lenght) -> index = 0; + // + //or as written below: + // index = (index+1) % array.length + idx_ = (idx_+1) % Capacity; + return idx_; +} + +#endif /* CIRCULARFIFO_H_ */ + + + + + +/* +#ifndef CIRCULARFIFO_H_ +#define CIRCULARFIFO_H_ + +#include "sls_receiver_defs.h" + +#include "/usr/include/alsa/atomic.h" +#include +using namespace std; + +template +class CircularFifo { +public: + + CircularFifo(unsigned int Size) : tail(0), head(0){ + Capacity = Size + 1; + array.resize(Capacity); + } + virtual ~CircularFifo() {} + + bool push(Element*& item_); + bool pop(Element*& item_); + + bool wasEmpty() const; + bool wasFull() const; + bool isLockFree() const; + +private: + vector array; + unsigned int Capacity; + + std::atomic tail; // input index + std::atomic head; // output index + + unsigned int increment(unsigned int idx_) const; +}; + + +template +bool CircularFifo::push(Element*& item_) +{ + auto currentTail = tail.load(); + auto nextTail = increment(currentTail); + if(nextTail != head.load()) + { + array[currentTail] = item_; + tail.store(nextTail); + return true; + } + + // queue was full + return false; +} + + +template +bool CircularFifo::pop(Element*& item_) +{ + const auto currentHead = head.load(); + if(currentHead == tail.load()) + return false; // empty queue + + item_ = array[currentHead]; + head.store(increment(currentHead)); + return true; +} + + +template +bool CircularFifo::wasEmpty() const +{ + return (head.load() == tail.load()); +} + + +template +bool CircularFifo::wasFull() const +{ + const auto nextTail = increment(tail.load()); + return (nextTail == head.load()); +} + +template +bool CircularFifo::isLockFree() const +{ + return (tail.is_lock_free() && head.is_lock_free()); +} + + +template +unsigned int CircularFifo::increment(unsigned int idx_) const +{ + // increment or wrap + // ================= + // index++; + // if(index == array.lenght) -> index = 0; + // + //or as written below: + // index = (index+1) % array.length + return (idx_ + 1) % Capacity; +} + +#endif */ diff --git a/slsReceiverSoftware/includes/receiver_defs.h b/slsReceiverSoftware/includes/receiver_defs.h new file mode 100755 index 000000000..8dfbf7c99 --- /dev/null +++ b/slsReceiverSoftware/includes/receiver_defs.h @@ -0,0 +1,72 @@ +#ifndef RECEIVER_DEFS_H +#define RECEIVER_DEFS_H + +#include "sls_receiver_defs.h" + +#include + +#define GOODBYE -200 + +#define DO_NOTHING 0 +#define CREATE_FILES 1 +#define DO_EVERYTHING 2 + +#define BUF_SIZE (16*1024*1024) //16mb +#define SAMPLE_TIME_IN_NS 100000000//100ms +#define MAX_JOBS_PER_THREAD 1000 +#define HEADER_SIZE_NUM_TOT_PACKETS 2 +#define HEADER_SIZE_NUM_FRAMES 2 +#define HEADER_SIZE_NUM_PACKETS 1 + + +//all max frames defined in sls_receiver_defs.h. 20000 gotthard, 100000 for short gotthard, 1000 for moench + + +#define GOTTHARD_FIFO_SIZE 25000 //cannot be less than max jobs per thread = 1000 +/*#define GOTTHARD_ALIGNED_FRAME_SIZE 4096*/ +#define GOTTHARD_PACKETS_PER_FRAME 2 +#define GOTTHARD_ONE_PACKET_SIZE 1286 +#define GOTTHARD_BUFFER_SIZE (GOTTHARD_ONE_PACKET_SIZE*GOTTHARD_PACKETS_PER_FRAME) //1286*2 +#define GOTTHARD_DATA_BYTES (1280*GOTTHARD_PACKETS_PER_FRAME) //1280*2 + +#define GOTTHARD_SHORT_PACKETS_PER_FRAME 1 +#define GOTTHARD_SHORT_BUFFER_SIZE 518 +#define GOTTHARD_SHORT_DATABYTES 512 +#define GOTTHARD_SHORT_FRAME_INDEX_MASK 0xFFFFFFFF +#define GOTTHARD_SHORT_FRAME_INDEX_OFFSET 0 +#define GOTTHARD_SHORT_PACKET_INDEX_MASK 0 +#define GOTTHARD_SHORT_PIXELS_IN_ROW 256 +#define GOTTHARD_SHORT_PIXELS_IN_COL 1 + + +#define GOTTHARD_FRAME_INDEX_MASK 0xFFFFFFFE +#define GOTTHARD_FRAME_INDEX_OFFSET 1 +#define GOTTHARD_PACKET_INDEX_MASK 0x1 + +#define GOTTHARD_PIXELS_IN_ROW 1280 +#define GOTTHARD_PIXELS_IN_COL 1 + + + +#define MOENCH_FIFO_SIZE 2500 //cannot be less than max jobs per thread = 1000 +/*#define MOENCH_ALIGNED_FRAME_SIZE 65536*/ +#define MOENCH_PACKETS_PER_FRAME 40 +#define MOENCH_ONE_PACKET_SIZE 1286 +#define MOENCH_BUFFER_SIZE (MOENCH_ONE_PACKET_SIZE*MOENCH_PACKETS_PER_FRAME) //1286*40 +#define MOENCH_DATA_BYTES (1280*MOENCH_PACKETS_PER_FRAME) //1280*40 + +#define MOENCH_BYTES_PER_ADC (40*2) +#define MOENCH_PIXELS_IN_ONE_ROW 160 +#define MOENCH_BYTES_IN_ONE_ROW (MOENCH_PIXELS_IN_ONE_ROW*2) + + +#define MOENCH_FRAME_INDEX_MASK 0xFFFFFF00 +#define MOENCH_FRAME_INDEX_OFFSET 8 +#define MOENCH_PACKET_INDEX_MASK 0xFF + + + + + +//#define THIS_SOFTWARE_VERSION 0x20120919 +#endif diff --git a/slsReceiverSoftware/includes/sls_receiver_defs.h b/slsReceiverSoftware/includes/sls_receiver_defs.h new file mode 100755 index 000000000..c4c1fc63e --- /dev/null +++ b/slsReceiverSoftware/includes/sls_receiver_defs.h @@ -0,0 +1,118 @@ +#ifndef SLS_RECEIVER_DEFS_H +#define SLS_RECEIVER_DEFS_H + + +#ifdef __CINT__ +#define MYROOT +#define __cplusplus +#endif + +#include + + +typedef double double32_t; +typedef float float32_t; +typedef int int32_t; + +/** default maximum string length */ +#define MAX_STR_LENGTH 1000 +#define MAX_FRAMES_PER_FILE 20000 +#define SHORT_MAX_FRAMES_PER_FILE 100000 +#define MOENCH_MAX_FRAMES_PER_FILE 1000 + + +/** + \file sls_receiver_defs.h +This file contains all the basic definitions common to the slsReceiver class +and to the server programs running on the receiver + * @author Anna Bergamaschi + * @version 0.1alpha (any string) + * @see slsDetector +$Revision: 809 $ + */ + + +#ifdef __cplusplus + +/** @short class containing all the constants and enum definitions */ +class slsReceiverDefs { +public: + + slsReceiverDefs(){}; + +#endif + + /** + Type of the detector + */ + enum detectorType { + GET_DETECTOR_TYPE=-1, /**< the detector will return its type */ + GENERIC, /**< generic sls detector */ + MYTHEN, /**< mythen */ + PILATUS, /**< pilatus */ + EIGER, /**< eiger */ + GOTTHARD, /**< gotthard */ + PICASSO, /**< picasso */ + AGIPD, /**< agipd */ + MOENCH /**< moench */ + }; + + + /** + return values + */ + enum { + OK, /**< function succeeded */ + FAIL, /**< function failed */ + FINISHED, /**< acquisition finished */ + FORCE_UPDATE + }; + + + /** + indexes for the acquisition timers + */ + enum timerIndex { + FRAME_NUMBER, /**< number of real time frames: total number of acquisitions is number or frames*number of cycles */ + ACQUISITION_TIME, /**< exposure time */ + FRAME_PERIOD, /**< period between exposures */ + DELAY_AFTER_TRIGGER, /**< delay between trigger and start of exposure or readout (in triggered mode) */ + GATES_NUMBER, /**< number of gates per frame (in gated mode) */ + PROBES_NUMBER, /**< number of probe types in pump-probe mode */ + CYCLES_NUMBER, /**< number of cycles: total number of acquisitions is number or frames*number of cycles */ + ACTUAL_TIME, /**< Actual time of the detector's internal timer */ + MEASUREMENT_TIME, /**< Time of the measurement from the detector (fifo) */ + + PROGRESS, /**< fraction of measurement elapsed - only get! */ + MEASUREMENTS_NUMBER + }; + + + /** + staus mask + */ + enum runStatus { + IDLE, /**< detector ready to start acquisition - no data in memory */ + ERROR, /**< error i.e. normally fifo full */ + WAITING, /**< waiting for trigger or gate signal */ + RUN_FINISHED, /**< acquisition not running but data in memory */ + TRANSMITTING, /**< acquisition running and data in memory */ + RUNNING /**< acquisition running, no data in memory */ + }; + + + +#ifdef __cplusplus +protected: +#endif + +#ifndef MYROOT +#include "sls_receiver_funcs.h" +#endif + +#ifdef __cplusplus +}; +#endif +; +#endif +; diff --git a/slsReceiverSoftware/includes/sls_receiver_funcs.h b/slsReceiverSoftware/includes/sls_receiver_funcs.h new file mode 100644 index 000000000..298eb39b1 --- /dev/null +++ b/slsReceiverSoftware/includes/sls_receiver_funcs.h @@ -0,0 +1,55 @@ +/** + @internal + function indexes to call on the server + All set functions with argument -1 work as get, when possible + */ +#ifndef SLS_RECEIVER_FUNCS_H +#define SLS_RECEIVER_FUNCS_H + +enum { + //General functions + F_EXEC_RECEIVER_COMMAND=0, /**< command is executed */ + F_EXIT_RECEIVER, /**< turn off receiver server */ + F_LOCK_RECEIVER, /**< Locks/Unlocks server communication to the given client */ + F_GET_LAST_RECEIVER_CLIENT_IP, /**< returns the IP of the client last connected to the receiver */ + F_SET_RECEIVER_PORT, /**< Changes communication port of the receiver */ + F_UPDATE_RECEIVER_CLIENT, /**< Returns all the important parameters to update the shared memory of the client */ + + // Identification + F_GET_RECEIVER_ID, /**< get receiver id of version */ + F_GET_RECEIVER_TYPE, /**< return receiver type */ + F_SEND_RECEIVER_DETHOSTNAME, /**< set detector hostname to receiver */ + + //network functions + F_RECEIVER_SHORT_FRAME, /**< Sets receiver to receive short frames */ + F_SETUP_RECEIVER_UDP, /**< sets the receiver udp connection and returns receiver mac address */ + + //Acquisition setup functions + F_SET_RECEIVER_TIMER, /**< set/get timer value */ + F_SET_RECEIVER_DYNAMIC_RANGE, /**< set/get detector dynamic range */ + F_READ_RECEIVER_FREQUENCY, /**< sets the frequency of receiver sending frames to gui */ + + // Acquisition functions + F_GET_RECEIVER_STATUS, /**< gets the status of receiver listening mode */ + F_START_RECEIVER, /**< starts the receiver listening mode */ + F_STOP_RECEIVER, /**< stops the receiver listening mode */ + F_START_RECEIVER_READOUT, /**< acquisition has stopped. start remaining readout in receiver */ + F_READ_RECEIVER_FRAME, /**< read one frame to gui*/ + + //file functions + F_SET_RECEIVER_FILE_PATH, /**< sets receiver file directory */ + F_SET_RECEIVER_FILE_NAME, /**< sets receiver file name */ + F_SET_RECEIVER_FILE_INDEX, /**< sets receiver file index */ + F_SET_RECEIVER_FRAME_INDEX, /**< sets the receiver frame index */ + F_GET_RECEIVER_FRAME_INDEX, /**< gets the receiver frame index */ + F_GET_RECEIVER_FRAMES_CAUGHT, /**< gets the number of frames caught by receiver */ + F_RESET_RECEIVER_FRAMES_CAUGHT, /**< resets the frames caught by receiver */ + F_ENABLE_RECEIVER_FILE_WRITE, /**< sets the receiver file write */ + F_ENABLE_RECEIVER_COMPRESSION, /**< enable compression in receiver */ + F_ENABLE_RECEIVER_OVERWRITE /**< set overwrite flag in receiver */ + + /* Always append functions hereafter!!! */ +}; + +#endif +/** @endinternal */ diff --git a/slsReceiverSoftware/includes/svnInfoReceiver.h b/slsReceiverSoftware/includes/svnInfoReceiver.h new file mode 100644 index 000000000..5b0ab940b --- /dev/null +++ b/slsReceiverSoftware/includes/svnInfoReceiver.h @@ -0,0 +1,11 @@ +//#define SVNPATH "" +#define SVNURL "file:///afs/psi.ch/project/sls_det_software/svn/slsReceiverSoftware/includes" +//#define SVNREPPATH "" +#define SVNREPUUID "5644e8d6-1a0c-4dbd-ab0e-45e7522ac187" +//#define SVNREV 0x5 +//#define SVNKIND "" +//#define SVNSCHED "" +#define SVNAUTH "l_maliakal_d" +#define SVNREV 0x5 +#define SVNDATE 0x20140515 +// diff --git a/slsReceiverSoftware/includes/svnInfoReceiverTmp.h b/slsReceiverSoftware/includes/svnInfoReceiverTmp.h new file mode 100644 index 000000000..58e48f497 --- /dev/null +++ b/slsReceiverSoftware/includes/svnInfoReceiverTmp.h @@ -0,0 +1,11 @@ +//#define SVNPATH "" +#define SVNURL "" +//#define SVNREPPATH "" +#define SVNREPUUID "" +//#define SVNREV "" +//#define SVNKIND "" +//#define SVNSCHED "" +#define SVNAUTH "" +#define SVNREV "" +#define SVNDATE "" +// diff --git a/slsReceiverSoftware/slsDetectorCalibration/MovingStat.h b/slsReceiverSoftware/slsDetectorCalibration/MovingStat.h new file mode 100755 index 000000000..9d3720b1b --- /dev/null +++ b/slsReceiverSoftware/slsDetectorCalibration/MovingStat.h @@ -0,0 +1,130 @@ +#ifndef MOVINGSTAT_H +#define MOVINGSTAT_H + +#include + + +class MovingStat + { + + /** @short approximated moving average structure */ + public: + + + /** constructor + \param nn number of samples parameter to be used + */ + MovingStat(int nn=1000) : n(nn), m_n(0) {} + + /** + clears the moving average number of samples parameter, mean and standard deviation + */ + void Clear() + { + m_n = 0; + m_newM=0; + m_newM2=0; + } + + + /** sets number of samples parameter + \param i number of samples parameter to be set + */ + + void SetN(int i) {if (i>=1) n=i;}; + + /** + gets number of samples parameter + \returns actual number of samples parameter + */ + int GetN() {return n;}; + + /** calculates the moving average i.e. adds if number of elements is lower than number of samples parameter, pushes otherwise + \param x value to calculate the moving average + */ + inline void Calc(double x) { + if (m_n 0) ? m_newM/m_n : 0.0; + } + + /** returns the squared mean, 0 if no elements are inside + \returns returns the squared average + */ + double M2() const + { + return ( (m_n > 1) ? m_newM2/m_n : 0.0 ); + } + + /** returns the variance, 0 if no elements are inside + \returns returns the variance + */ + inline double Variance() const + { + return ( (m_n > 1) ? (M2()-Mean()*Mean()) : 0.0 ); + } + + /** returns the standard deviation, 0 if no elements are inside + \returns returns the standard deviation + */ + inline double StandardDeviation() const + { + return ( (Variance() > 0) ? sqrt( Variance() ) : -1 ); + } + + private: + int n; /**< number of samples parameter */ + int m_n; /**< current number of elements */ + double m_newM; /**< accumulated average */ + double m_newM2; /**< accumulated squared average */ + }; +#endif diff --git a/slsReceiverSoftware/slsDetectorCalibration/RunningStat.h b/slsReceiverSoftware/slsDetectorCalibration/RunningStat.h new file mode 100755 index 000000000..1197ffc0f --- /dev/null +++ b/slsReceiverSoftware/slsDetectorCalibration/RunningStat.h @@ -0,0 +1,55 @@ + class RunningStat + { + public: + RunningStat() : m_n(0) {} + + void Clear() + { + m_n = 0; + } + + void Push(double x) + { + m_n++; + + // See Knuth TAOCP vol 2, 3rd edition, page 232 + if (m_n == 1) + { + m_oldM = m_newM = x; + m_oldS = 0.0; + } + else + { + m_newM = m_oldM + (x - m_oldM)/m_n; + m_newS = m_oldS + (x - m_oldM)*(x - m_newM); + + // set up for next iteration + m_oldM = m_newM; + m_oldS = m_newS; + } + } + + int NumDataValues() const + { + return m_n; + } + + double Mean() const + { + return (m_n > 0) ? m_newM : 0.0; + } + + double Variance() const + { + return ( (m_n > 1) ? m_newS/(m_n - 1) : 0.0 ); + } + + double StandardDeviation() const + { + return sqrt( Variance() ); + } + + private: + int m_n; + double m_oldM, m_newM, m_oldS, m_newS; + }; diff --git a/slsReceiverSoftware/slsDetectorCalibration/chiptestBoardData.h b/slsReceiverSoftware/slsDetectorCalibration/chiptestBoardData.h new file mode 100644 index 000000000..0ef633c44 --- /dev/null +++ b/slsReceiverSoftware/slsDetectorCalibration/chiptestBoardData.h @@ -0,0 +1,89 @@ +#ifndef CHIPTESTDATA_H +#define CHIPTESTDATA_H + +#include "slsDetectorData.h" + +class chiptestBoardData : public slsDetectorData { + + + public: + + /** + chiptestBoard data structure. Works for data acquired using the chiptestBoard. + Inherits and implements slsDetectorData. + + Constructor (no error checking if datasize and offsets are compatible!) + \param npx number of pixels in the x direction + \param npy number of pixels in the y direction (1 for strips) + \param nadc number of adcs + \param offset offset at the beginning of the pattern + \param dMap array of size nx*ny storing the pointers to the data in the dataset (as offset) + \param dMask Array of size nx*ny storing the polarity of the data in the dataset (should be 0 if no inversion is required, 0xffffffff is inversion is required) + \param dROI Array of size nx*ny. The elements are 1s if the channel is good or in the ROI, 0 is bad or out of the ROI. NULL (default) means all 1s. + + */ + chiptestBoardData(int npx, int npy, int nadc, int offset, int **dMap=NULL, uint16_t **dMask=NULL, int **dROI=NULL): slsDetectorData(npx, npy, nadc*(npx*npy)+offset, dMap, dMask, dROI), nAdc(nadc), offSize(offset), iframe(0) {}; // should be? nadc*(npx*npy+offset) + + + + /** + + Returns the frame number for the given dataset. Virtual func: works for slsDetectorReceiver data (also for each packet), but can be overloaded. + \param buff pointer to the dataset + \returns frame number + + */ + + virtual int getFrameNumber(char *buff){(void)buff; return iframe;}; + + + /** + + Loops over a memory slot until a complete frame is found (i.e. all packets 0 to nPackets, same frame number). Can be overloaded for different kind of detectors! + \param data pointer to the memory to be analyzed + \param ndata size of frame returned + \param dsize size of the memory slot to be analyzed + \returns always return the pointer to data (no frame loss!) + */ + + virtual char *findNextFrame(char *data, int &ndata, int dsize) {ndata=dsize;setDataSize(dsize); return data;}; + + /** + Loops over a file stream until a complete frame is found (i.e. all packets 0 to nPackets, same frame number). Can be overloaded for different kind of detectors! + \param filebin input file stream (binary) + \returns pointer to the first packet of the last good frame, NULL if no frame is found or last frame is incomplete + */ + + virtual char *readNextFrame(ifstream &filebin) { + + int afifo_length=0; + uint16_t *afifo_cont; + + if (filebin.is_open()) { + if (filebin.read((char*)&afifo_length,sizeof(uint32_t))) { + setDataSize(afifo_length*nAdc*sizeof(uint16_t)); + afifo_cont=new uint16_t[afifo_length*nAdc]; + if (filebin.read((char*)afifo_cont,afifo_length*sizeof(uint16_t)*nAdc)) { + iframe++; + return (char*)afifo_cont; + } else { + delete [] afifo_cont; + return NULL; + } + } else { + return NULL; + } + } + return NULL; + }; + + private: + const int nAdc; /**0) cmStat[i].Calc(cmPed[i]/nCm[i]); + nCm[i]=0; + cmPed[i]=0; + }}; + + /** adds the pixel to the sum of pedestals -- virtual func must be overloaded to define the regions of interest + \param val value to add + \param ix pixel x coordinate + \param iy pixel y coordinate + */ + virtual void addToCommonMode(double val, int ix=0, int iy=0) { + (void) ix; (void) iy; + + //if (isc>=0 && isc0) return cmPed[0]/nCm[0]-cmStat[0].Mean(); + return 0;}; + + + + + + protected: + MovingStat *cmStat; /**SetName("cds_g4"); + hs2N->SetTitle("cds_g4"); + (TH2F*)(hs2N->GetHists()->At(0))->Write(); + + (TH2F*)(hs2N->GetHists()->At(1))->Write(); + (TH2F*)(hs2N->GetHists()->At(2))->Write(); + (TH2F*)(hs2N->GetHists()->At(3))->Write(); + (TH2F*)(hs2N->GetHists()->At(4))->Write(); + + + fout->Close(); + + + +} + diff --git a/slsReceiverSoftware/slsDetectorCalibration/doxy.config b/slsReceiverSoftware/slsDetectorCalibration/doxy.config new file mode 100644 index 000000000..7d2a396ff --- /dev/null +++ b/slsReceiverSoftware/slsDetectorCalibration/doxy.config @@ -0,0 +1,85 @@ +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + + + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = YES + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = YES + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base +# name of the file that contains the anonymous namespace. By default +# anonymous namespace are hidden. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +INTERNAL_DOCS = NO + +SHOW_INCLUDE_FILES = NO + +SHOW_FILES = NO + +SHOW_NAMESPACES = NO + +COMPACT_LATEX = YES + +PAPER_TYPE = a4 + +PDF_HYPERLINKS = YES + +USE_PDFLATEX = YES + +LATEX_HIDE_INDICES = YES + +PREDEFINED = __cplusplus + +INPUT = MovingStat.h slsDetectorData.h slsReceiverData.h moench02ModuleData.h pedestalSubtraction.h commonModeSubtraction.h moenchCommonMode.h singlePhotonDetector.h energyCalibration.h moenchReadData.C single_photon_hit.h chiptestBoardData.h jungfrau02Data.h jungfrauReadData.C jungfrau02CommonMode.h +OUTPUT_DIRECTORY = docs + diff --git a/slsReceiverSoftware/slsDetectorCalibration/energyCalibration.cpp b/slsReceiverSoftware/slsDetectorCalibration/energyCalibration.cpp new file mode 100644 index 000000000..691122095 --- /dev/null +++ b/slsReceiverSoftware/slsDetectorCalibration/energyCalibration.cpp @@ -0,0 +1,527 @@ +#include "energyCalibration.h" + +#ifdef __CINT +#define MYROOT +#endif + + +#ifdef MYROOT +#include +#include +#include +#include +#endif + +#include + +#define max(a,b) ((a) > (b) ? (a) : (b)) +#define min(a,b) ((a) < (b) ? (a) : (b)) +#define ELEM_SWAP(a,b) { register int t=(a);(a)=(b);(b)=t; } + + +using namespace std; + +#ifdef MYROOT + +Double_t energyCalibrationFunctions::pedestal(Double_t *x, Double_t *par) { + return par[0]-par[1]*sign*x[0]; +} + + +Double_t energyCalibrationFunctions::gaussChargeSharing(Double_t *x, Double_t *par) { + Double_t f, arg=0; + if (par[3]!=0) arg=sign*(x[0]-par[2])/par[3]; + f=TMath::Exp(-1*arg*arg/2.); + f=f+par[5]/2.*(TMath::Erfc(arg/(TMath::Sqrt(2.)))); + return par[4]*f+pedestal(x,par); +} + +Double_t energyCalibrationFunctions::gaussChargeSharingPixel(Double_t *x, Double_t *par) { + Double_t f; + if (par[3]<=0 || par[2]*(*x)<=0 || par[5]<0 || par[4]<=0) return 0; + + Double_t pp[3]; + + pp[0]=0; + pp[1]=par[2]; + pp[2]=par[3]; + + + f=(par[5]-par[6]*(TMath::Log(*x/par[2])))*erfBox(x,pp); + f+=par[4]*TMath::Gaus(*x, par[2], par[3], kTRUE); + return f+pedestal(x,par); +} + +Double_t energyCalibrationFunctions::erfBox(Double_t *z, Double_t *par) { + + + + Double_t m=par[0]; + Double_t M=par[1]; + + if (par[0]>par[1]) { + m=par[1]; + M=par[0]; + } + + if (m==M) + return 0; + + + if (par[2]<=0) { + if (*z>=m && *z<=M) + return 1./(M-m); + else + return 0; + + } + + return (TMath::Erfc((z[0]-M)/par[2])-TMath::Erfc((z[0]-m)/par[2]))*0.5/(M-m); + +} + + +// basic erf function +Double_t energyCalibrationFunctions::erfFunction(Double_t *x, Double_t *par) { + double arg=0; + if (par[1]!=0) arg=(par[0]-x[0])/par[1]; + return ((par[2]/2.*(1+TMath::Erf(sign*arg/(TMath::Sqrt(2)))))); +}; + + +Double_t energyCalibrationFunctions::erfFunctionChargeSharing(Double_t *x, Double_t *par) { + Double_t f; + + f=erfFunction(x, par+2)*(1+par[5]*(par[2]-x[0]))+par[0]-par[1]*x[0]*sign; + return f; +}; + + +Double_t energyCalibrationFunctions::erfFuncFluo(Double_t *x, Double_t *par) { + Double_t f; + f=erfFunctionChargeSharing(x, par)+erfFunction(x, par+6)*(1+par[9]*(par[6]-x[0])); + return f; +}; +#endif + +double energyCalibrationFunctions::median(double *x, int n){ + // sorts x into xmed array and returns median + // n is number of values already in the xmed array + double xmed[n]; + int k,i,j; + + for (i=0; i*(x+j)) + k++; + if (*(x+i)==*(x+j)) { + if (i>j) + k++; + } + } + xmed[k]=*(x+i); + } + k=n/2; + return xmed[k]; +} + + +int energyCalibrationFunctions::quick_select(int arr[], int n){ + int low, high ; + int median; + int middle, ll, hh; + + low = 0 ; high = n-1 ; median = (low + high) / 2; + for (;;) { + if (high <= low) /* One element only */ + return arr[median] ; + + if (high == low + 1) { /* Two elements only */ + if (arr[low] > arr[high]) + ELEM_SWAP(arr[low], arr[high]) ; + return arr[median] ; + } + + /* Find median of low, middle and high items; swap into position low */ + middle = (low + high) / 2; + if (arr[middle] > arr[high]) ELEM_SWAP(arr[middle], arr[high]) ; + if (arr[low] > arr[high]) ELEM_SWAP(arr[low], arr[high]) ; + if (arr[middle] > arr[low]) ELEM_SWAP(arr[middle], arr[low]) ; + + /* Swap low item (now in position middle) into position (low+1) */ + ELEM_SWAP(arr[middle], arr[low+1]) ; + + /* Nibble from each end towards middle, swapping items when stuck */ + ll = low + 1; + hh = high; + for (;;) { + do ll++; while (arr[low] > arr[ll]) ; + do hh--; while (arr[hh] > arr[low]) ; + + if (hh < ll) + break; + + ELEM_SWAP(arr[ll], arr[hh]) ; + } + + /* Swap middle item (in position low) back into correct position */ + ELEM_SWAP(arr[low], arr[hh]) ; + + /* Re-set active partition */ + if (hh <= median) + low = ll; + if (hh >= median) + high = hh - 1; + } +} + +int energyCalibrationFunctions::kth_smallest(int *a, int n, int k){ + register int i,j,l,m ; + register double x ; + + l=0 ; m=n-1 ; + while (lSetParNames("Background Offset","Background Slope","Inflection Point","Noise RMS", "Number of Photons","Charge Sharing Slope"); + + fspectrum=new TF1("fspectrum",funcs,&energyCalibrationFunctions::spectrum,0,1000,6,"energyCalibrationFunctions","spectrum"); + fspectrum->SetParNames("Background Pedestal","Background slope", "Peak position","Noise RMS", "Number of Photons","Charge Sharing Pedestal"); + + fspixel=new TF1("fspixel",funcs,&energyCalibrationFunctions::spectrumPixel,0,1000,7,"energyCalibrationFunctions","spectrumPixel"); + fspixel->SetParNames("Background Pedestal","Background slope", "Peak position","Noise RMS", "Number of Photons","Charge Sharing Pedestal","Corner"); + +#endif + + +} + + + +void energyCalibration::fixParameter(int ip, Double_t val){ + + fscurve->FixParameter(ip, val); + fspectrum->FixParameter(ip, val); +} + + +void energyCalibration::releaseParameter(int ip){ + + fscurve->ReleaseParameter(ip); + fspectrum->ReleaseParameter(ip); +} + + + + + + + +energyCalibration::~energyCalibration(){ +#ifdef MYROOT + delete fscurve; + delete fspectrum; +#endif + +} + +#ifdef MYROOT + + + + + +TH1F* energyCalibration::createMedianHistogram(TH2F* h2, int ch0, int nch, int direction) { + + if (h2==NULL || nch==0) + return NULL; + + double *x=new double[nch]; + TH1F *h1=NULL; + + double val=-1; + + if (direction==0) { + h1=new TH1F("median","Median",h2->GetYaxis()->GetNbins(),h2->GetYaxis()->GetXmin(),h2->GetYaxis()->GetXmax()); + for (int ib=0; ibGetXaxis()->GetNbins(); ib++) { + for (int ich=0; ichGetBinContent(ch0+ich+1,ib+1); + } + val=energyCalibrationFunctions::median(x, nch); + h1->SetBinContent(ib+1,val); + } + } else if (direction==1) { + h1=new TH1F("median","Median",h2->GetXaxis()->GetNbins(),h2->GetXaxis()->GetXmin(),h2->GetXaxis()->GetXmax()); + for (int ib=0; ibGetYaxis()->GetNbins(); ib++) { + for (int ich=0; ichGetBinContent(ib+1,ch0+ich+1); + } + val=energyCalibrationFunctions::median(x, nch); + h1->SetBinContent(ib+1,val); + } + } + delete [] x; + + return h1; + +} + + + + + + + + + + + + + + +void energyCalibration::setStartParameters(Double_t *par){ + bg_offset=par[0]; + bg_slope=par[1]; + flex=par[2]; + noise=par[3]; + ampl=par[4]; + cs_slope=par[5]; +} + + +void energyCalibration::getStartParameters(Double_t *par){ + par[0]=bg_offset; + par[1]=bg_slope; + par[2]=flex; + par[3]=noise; + par[4]=ampl; + par[5]=cs_slope; +} + +#endif +int energyCalibration::setChargeSharing(int p) { + if (p>=0) { + cs_flag=p; +#ifdef MYROOT + if (p) { + fscurve->ReleaseParameter(5); + fspectrum->ReleaseParameter(1); + } else { + fscurve->FixParameter(5,0); + fspectrum->FixParameter(1,0); + } +#endif + } + + return cs_flag; +} + + +#ifdef MYROOT +void energyCalibration::initFitFunction(TF1 *fun, TH1 *h1) { + + Double_t min=fit_min, max=fit_max; + + Double_t mypar[6]; + + if (max==-1) + max=h1->GetXaxis()->GetXmax(); + + if (min==-1) + min=h1->GetXaxis()->GetXmin(); + + + if (bg_offset==-1) + mypar[0]=0; + else + mypar[0]=bg_offset; + + + if (bg_slope==-1) + mypar[1]=0; + else + mypar[1]=bg_slope; + + + if (flex==-1) + mypar[2]=(min+max)/2.; + else + mypar[2]=flex; + + + if (noise==-1) + mypar[3]=0.1; + else + mypar[3]=noise; + + if (ampl==-1) + mypar[4]=h1->GetBinContent(h1->GetXaxis()->FindBin(0.5*(max+min))); + else + mypar[4]=ampl; + + if (cs_slope==-1) + mypar[5]=0; + else + mypar[5]=cs_slope; + + fun->SetParameters(mypar); + + fun->SetRange(min,max); + +} + + +TF1* energyCalibration::fitFunction(TF1 *fun, TH1 *h1, Double_t *mypar, Double_t *emypar) { + + + TF1* fitfun; + + char fname[100]; + + strcpy(fname, fun->GetName()); + + if (plot_flag) { + h1->Fit(fname,"R0Q"); + } else + h1->Fit(fname,"R0Q"); + + + fitfun= h1->GetFunction(fname); + fitfun->GetParameters(mypar); + for (int ip=0; ip<6; ip++) { + emypar[ip]=fitfun->GetParError(ip); + } + return fitfun; +} + +TF1* energyCalibration::fitSCurve(TH1 *h1, Double_t *mypar, Double_t *emypar) { + initFitFunction(fscurve,h1); + return fitFunction(fscurve, h1, mypar, emypar); +} + + + + + +TF1* energyCalibration::fitSpectrum(TH1 *h1, Double_t *mypar, Double_t *emypar) { + initFitFunction(fspectrum,h1); + return fitFunction(fspectrum, h1, mypar, emypar); +} + + + +TGraphErrors* energyCalibration::linearCalibration(int nscan, Double_t *en, Double_t *een, Double_t *fl, Double_t *efl, Double_t &gain, Double_t &off, Double_t &egain, Double_t &eoff) { + + TGraphErrors *gr; + + Double_t mypar[2]; + + gr = new TGraphErrors(nscan,en,fl,een,efl); + + if (plot_flag) { + gr->Fit("pol1"); + gr->SetMarkerStyle(20); + } else + gr->Fit("pol1","0Q"); + + TF1 *fitfun= gr->GetFunction("pol1"); + fitfun->GetParameters(mypar); + + egain=fitfun->GetParError(1); + eoff=fitfun->GetParError(0); + + gain=funcs->setScanSign()*mypar[1]; + + off=mypar[0]; + + return gr; +} + + +TGraphErrors* energyCalibration::calibrate(int nscan, Double_t *en, Double_t *een, TH1F **h1, Double_t &gain, Double_t &off, Double_t &egain, Double_t &eoff, int integral) { + + TH1F *h; + + Double_t mypar[6], emypar[6]; + Double_t fl[nscan], efl[nscan]; + + + for (int ien=0; ien +#include +class TH1F; +class TH2F; +class TGraphErrors; +#endif + + +using namespace std; + + + + +const double conven=1000./3.6; /**< electrons/keV */ +const double el=1.67E-4; /**< electron charge in fC */ + + + +/** + \mainpage Common Root library for SLS detectors data analysis + * + * \section intro_sec Introduction + We know very well s-curves etc. but at the end everybody uses different functions ;-). + + * \subsection mot_sec Motivation + It would be greate to use everybody the same functions... + +*/ + + +/** + * + * +@libdoc The energiCalibration class contains all the necessary functions for s-curve fitting and linear calibration of the threshold. + * + * @short Energy calibration functions + * @author Anna Bergamaschi + * @version 0.1alpha + + + */ + +/** + class containing all the possible energy calibration functions (scurves with and without charge sharing, gaussian spectrum with and without charge sharing, possibility of chosing the sign of the X-axis) + +*/ +class energyCalibrationFunctions { + + public: + + energyCalibrationFunctions(int s=-1) {setScanSign(s);}; + + /** sets scan sign + \param s can be 1 (energy and x-axis have the same direction) or -1 (energy and x-axis have opposite directions) otherwise gets + \returns current scan sign can be 1 (energy and x-axis have the same direction) or -1 (energy and x-axis have opposite directions) + */ + int setScanSign(int s=0) {if (s==1 || s==-1) sign=s; return sign;};; + + +#ifdef MYROOT + /** + Gaussian Function with charge sharing pedestal + par[0] is the absolute height of the background pedestal + par[1] is the slope of the background pedestal + */ + Double_t pedestal(Double_t *x, Double_t *par); + + /** + Gaussian Function with charge sharing pedestal + par[0] is the absolute height of the background pedestal + par[1] is the slope of the background pedestal + par[2] is the gaussian peak position + par[3] is the RMS of the gaussian (and of the pedestal) + par[4] is the height of the function + par[5] is the fractional height of the charge sharing pedestal (scales with par[3]) + */ + Double_t gaussChargeSharing(Double_t *x, Double_t *par); + /** + Gaussian Function with charge sharing pedestal + par[0] is the absolute height of the background pedestal + par[1] is the slope of the background pedestal + par[2] is the gaussian peak position + par[3] is the RMS of the gaussian (and of the pedestal) + par[4] is the height of the function + par[5] is the fractional height of the charge sharing pedestal (scales with par[3]) + */ + Double_t gaussChargeSharingPixel(Double_t *x, Double_t *par); + + /** + Basic erf function + par[0] is the inflection point + par[1] is the RMS + par[2] is the amplitude + */ +Double_t erfFunction(Double_t *x, Double_t *par) ; + Double_t erfBox(Double_t *z, Double_t *par); + /** Erf function with charge sharing slope + par[0] is the pedestal + par[1] is the slope of the pedestal + par[2] is the inflection point + par[3] is the RMS + par[4] is the amplitude + par[5] is the angual coefficient of the charge sharing slope (scales with par[3]) + */ +Double_t erfFunctionChargeSharing(Double_t *x, Double_t *par); + + /** Double Erf function with charge sharing slope + par[0] is the pedestal + par[1] is the slope of the pedestal + par[2] is the inflection point of the first energy + par[3] is the RMS of the first energy + par[4] is the amplitude of the first energy + par[5] is the angual coefficient of the charge sharing slope of the first energy (scales with par[3]) + par[6] is the inflection point of the second energy + par[7] is the RMS of the second energy + par[8] is the amplitude of the second energy + par[9] is the angual coefficient of the charge sharing slope of the second energy (scales with par[8]) + */ + +Double_t erfFuncFluo(Double_t *x, Double_t *par); + + + /** + static function Gaussian with charge sharing pedestal with the correct scan sign + par[0] is the absolute height of the background pedestal + par[1] is the slope of the pedestal + par[2] is the gaussian peak position + par[3] is the RMS of the gaussian (and of the pedestal) + par[4] is the height of the function + par[5] is the fractional height of the charge sharing pedestal (scales with par[4] + */ + Double_t spectrum(Double_t *x, Double_t *par); + + /** + static function Gaussian with charge sharing pedestal with the correct scan sign + par[0] is the absolute height of the background pedestal + par[1] is the slope of the pedestal + par[2] is the gaussian peak position + par[3] is the RMS of the gaussian (and of the pedestal) + par[4] is the height of the function + par[5] is the fractional height of the charge sharing pedestal (scales with par[4] + */ + Double_t spectrumPixel(Double_t *x, Double_t *par); + + + /** Erf function with charge sharing slope with the correct scan sign + par[0] is the pedestal + par[1] is the slope of the pedestal + par[2] is the inflection point + par[3] is the RMS + par[4] is the amplitude + par[5] is the angual coefficient of the charge sharing slope (scales with par[3]) + */ + Double_t scurve(Double_t *x, Double_t *par); + + + + /** Double Erf function with charge sharing slope + par[0] is the pedestal + par[1] is the slope of the pedestal + par[2] is the inflection point of the first energy + par[3] is the RMS of the first energy + par[4] is the amplitude of the first energy + par[5] is the angual coefficient of the charge sharing slope of the first energy (scales with par[3]) + par[6] is the inflection point of the second energy + par[7] is the RMS of the second energy + par[8] is the amplitude of the second energy + par[9] is the angual coefficient of the charge sharing slope of the second energy (scales with par[8]) + */ + Double_t scurveFluo(Double_t *x, Double_t *par); + +#endif + +/** Calculates the median of an array of n elements */ + static double median(double *x, int n); +/** Calculates the median of an array of n elements (swaps the arrays!)*/ + static int quick_select(int arr[], int n); +/** Calculates the median of an array of n elements (swaps the arrays!)*/ + static int kth_smallest(int *a, int n, int k); + + private: + int sign; + + +}; + +/** + class alowing the energy calibration of photon counting and anlogue detectors + +*/ + +class energyCalibration { + + + public: + /** + default constructor - creates the function with which the s-curves will be fitted + */ + energyCalibration(); + + /** + default destructor - deletes the function with which the s-curves will be fitted + */ + ~energyCalibration(); + + /** sets plot flag + \param p plot flag (-1 gets, 0 unsets, >0 plot) + \returns current plot flag + */ + int setPlotFlag(int p=-1) {if (p>=0) plot_flag=p; return plot_flag;}; + + /** sets scan sign + \param s can be 1 (energy and x-axis have the same direction) or -1 (energy and x-axis have opposite directions) otherwise gets + \returns current scan sign can be 1 (energy and x-axis have the same direction) or -1 (energy and x-axis have opposite directions) + */ + int setScanSign(int s=0) {return funcs->setScanSign(s);}; + + /** sets plot flag + \param p plot flag (-1 gets, 0 unsets, >0 plot) + \returns current plot flag + */ + int setChargeSharing(int p=-1); + + + void fixParameter(int ip, Double_t val); + + void releaseParameter(int ip); + +#ifdef MYROOT + + /** + Creates an histogram with the median of nchannels starting from a specified one. the direction on which it is mediated can be selected (defaults to x=0) + \param h2 2D histogram on which the median will be calculated + \param ch0 starting channel + \param nch number of channels to be mediated + \param direction can be either 0 (x, default) or 1 (y) + \returns a TH1F histogram with the X-axis as a clone of the h2 Y (if direction=0) or X (if direction=0) axis, and on the Y axis the median of the counts of the mediated channels f h2 + */ + static TH1F* createMedianHistogram(TH2F* h2, int ch0, int nch, int direction=0); + + + /** sets the s-curve fit range + \param mi minimum of the fit range (-1 is histogram x-min) + \param ma maximum of the fit range (-1 is histogram x-max) + */ + void setFitRange(Double_t mi, Double_t ma){fit_min=mi; fit_max=ma;}; + + /** gets the s-curve fit range + \param mi reference for minimum of the fit range (-1 is histogram x-min) + \param ma reference for maximum of the fit range (-1 is histogram x-max) + */ + void getFitRange(Double_t &mi, Double_t &ma){mi=fit_min; ma=fit_max;}; + + +/** set start parameters for the s-curve function + \param par parameters, -1 sets to auto-calculation + par[0] is the pedestal + par[1] is the slope of the pedestal + par[2] is the inflection point + par[3] is the RMS + par[4] is the amplitude + par[5] is the angual coefficient of the charge sharing slope (scales with par[3]) -- always positive + */ + void setStartParameters(Double_t *par); + +/** get start parameters for the s-curve function + \param par parameters, -1 means auto-calculated + par[0] is the pedestal + par[1] is the slope of the pedestal + par[2] is the inflection point + par[3] is the RMS + par[4] is the amplitude + par[5] is the angual coefficient of the charge sharing slope (scales with par[3]) -- always positive + */ + void getStartParameters(Double_t *par); + + /** + fits histogram with the s-curve function + \param h1 1d-histogram to be fitted + \param mypar pointer to fit parameters array + \param emypar pointer to fit parameter errors + \returns the fitted function - can be used e.g. to get the Chi2 or similar + */ + TF1 *fitSCurve(TH1 *h1, Double_t *mypar, Double_t *emypar); + + + /** + fits histogram with the spectrum + \param h1 1d-histogram to be fitted + \param mypar pointer to fit parameters array + \param emypar pointer to fit parameter errors + \returns the fitted function - can be used e.g. to get the Chi2 or similar + */ + TF1 *fitSpectrum(TH1 *h1, Double_t *mypar, Double_t *emypar); + + + /** + calculates gain and offset for the set of inflection points + \param nscan number of energy scans + \param en array of energies (nscan long) + \param een array of errors on energies (nscan long) - can be NULL! + \param fl array of inflection points (nscan long) + \param efl array of errors on the inflection points (nscan long) + \param gain reference to gain resulting from the fit + \param off reference to offset resulting from the fit + \param egain reference to error on the gain resulting from the fit + \param eoff reference to the error on the offset resulting from the fit + \returns graph energy vs inflection point + */ + TGraphErrors* linearCalibration(int nscan, Double_t *en, Double_t *een, Double_t *fl, Double_t *efl, Double_t &gain, Double_t &off, Double_t &egain, Double_t &eoff); + + /** + calculates gain and offset for the set of energy scans + \param nscan number of energy scans + \param en array of energies (nscan long) + \param een array of errors on energies (nscan long) - can be NULL! + \param h1 array of TH1 + \param gain reference to gain resulting from the fit + \param off reference to offset resulting from the fit + \param egain reference to error on the gain resulting from the fit + \param eoff reference to the error on the offset resulting from the fit + \returns graph energy vs inflection point + */ + TGraphErrors* calibrateScurves(int nscan, Double_t *en, Double_t *een, TH1F **h1, Double_t &gain, Double_t &off, Double_t &egain, Double_t &eoff){return calibrate(nscan, en, een, h1, gain, off, egain, eoff, 1);}; + + /** + calculates gain and offset for the set of energy spectra + \param nscan number of energy scans + \param en array of energies (nscan long) + \param een array of errors on energies (nscan long) - can be NULL! + \param h1 array of TH1 + \param gain reference to gain resulting from the fit + \param off reference to offset resulting from the fit + \param egain reference to error on the gain resulting from the fit + \param eoff reference to the error on the offset resulting from the fit + \returns graph energy vs peak + */ + TGraphErrors* calibrateSpectra(int nscan, Double_t *en, Double_t *een, TH1F **h1, Double_t &gain, Double_t &off, Double_t &egain, Double_t &eoff){return calibrate(nscan, en, een, h1, gain, off, egain, eoff, 0);}; + + +#endif + private: + +#ifdef MYROOT + /** + calculates gain and offset for the set of energies + \param nscan number of energy scans + \param en array of energies (nscan long) + \param een array of errors on energies (nscan long) - can be NULL! + \param h1 array of TH1 + \param gain reference to gain resulting from the fit + \param off reference to offset resulting from the fit + \param egain reference to error on the gain resulting from the fit + \param eoff reference to the error on the offset resulting from the fit + \param integral 1 is an s-curve set (default), 0 spectra + \returns graph energy vs peak/inflection point + */ + TGraphErrors* calibrate(int nscan, Double_t *en, Double_t *een, TH1F **h1, Double_t &gain, Double_t &off, Double_t &egain, Double_t &eoff, int integral=1); + + + /** + Initializes the start parameters and the range of the fit depending on the histogram characteristics and/or on the start parameters specified by the user + \param fun pointer to function to be initialized + \param h1 histogram from which to extract the range and start parameters, if not already specified by the user + +*/ + + void initFitFunction(TF1 *fun, TH1 *h1); + + + /** + Performs the fit according to the flags specified and returns the fitted function + \param fun function to fit + \param h1 histogram to fit + \param mypar pointer to fit parameters array + \param emypar pointer to fit parameter errors + \returns the fitted function - can be used e.g. to get the Chi2 or similar + */ + TF1 *fitFunction(TF1 *fun, TH1 *h1, Double_t *mypar, Double_t *emypar); + +#endif + +#ifdef MYROOT + Double_t fit_min; /**< minimum of the s-curve fitting range, -1 is histogram x-min */ + Double_t fit_max; /**< maximum of the s-curve fitting range, -1 is histogram x-max */ + + Double_t bg_offset; /**< start value for the background pedestal */ + Double_t bg_slope; /**< start value for the background slope */ + Double_t flex; /**< start value for the inflection point */ + Double_t noise; /**< start value for the noise */ + Double_t ampl; /**< start value for the number of photons */ + Double_t cs_slope; /**< start value for the charge sharing slope */ + + + TF1 *fscurve; /**< function with which the s-curve will be fitted */ + + TF1 *fspectrum; /**< function with which the spectrum will be fitted */ + + TF1 *fspixel; /**< function with which the spectrum will be fitted */ + +#endif + + energyCalibrationFunctions *funcs; + int plot_flag; /**< 0 does not plot, >0 plots (flags?) */ + + int cs_flag; /**< 0 functions without charge sharing contribution, >0 with charge sharing contribution */ + +}; + +#endif + + + + + + + + + + + + + + + + + + + diff --git a/slsReceiverSoftware/slsDetectorCalibration/gMapDemo.C b/slsReceiverSoftware/slsDetectorCalibration/gMapDemo.C new file mode 100644 index 000000000..51addf69a --- /dev/null +++ b/slsReceiverSoftware/slsDetectorCalibration/gMapDemo.C @@ -0,0 +1,11 @@ +{ + //.L energyCalibration.cpp+ + //.L gainMap.C+ + TFile fin("/data/moench_xbox_20140113/MoTarget_45kV_0_8mA_120V_cds_g4.root"); + TH2F *h2=fin.Get("h2"); + TH2F *gMap=gainMap(h2,4); + gMap->Draw("colz"); + + + +} diff --git a/slsReceiverSoftware/slsDetectorCalibration/gainMap.C b/slsReceiverSoftware/slsDetectorCalibration/gainMap.C new file mode 100644 index 000000000..7923fe687 --- /dev/null +++ b/slsReceiverSoftware/slsDetectorCalibration/gainMap.C @@ -0,0 +1,228 @@ +#define MYROOT +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; + + +#define FOPT "0" + +TH2F *gainMap(TH2F *h2, float g) { + // int npx, npy; + int npx=160, npy=160; + // det->getDetectorSize(npx, npy); + + TH2F *gMap=new TH2F("gmap",h2->GetTitle(), npx, -0.5, npx-0.5, npy, -0.5, npy-0.5); + + Double_t ens[3]={0,8,17.5}, eens[3]={0.,0.1,0.1}; + Double_t peaks[3], epeaks[3]; + + + + int ibin; + TH1D *px; + + + energyCalibration *enCal=new energyCalibration(); + enCal->setPlotFlag(0); + // enCal->setChargeSharing(0); + enCal->setScanSign(1); + + Double_t gain, off, egain, eoff; + + + TList *functions; + TPolyMarker *pm ; + Double_t *peakX, *peakY; + TSpectrum *s=new TSpectrum(); + Double_t mypar[10], emypar[10]; + Double_t prms, np; + int iit=0; + TGraph *glin; + Double_t peakdum, hpeakdum; + + for (int ix=1; ixProjectionX("px",ibin+1,ibin+1); + prms=10*g; + iit=0; + np=s->Search(px,prms,"",0.2); + while (np !=2) { + if (np>2) + prms+=0.5*prms; + else + prms-=0.5*prms; + iit++; + if (iit>=10) + break; + np=s->Search(px,prms,"",0.2); + } + if (np!=2) + cout << "peak search could not converge " << ibin << endl; + if (np==2) { + pm=NULL; + functions=px->GetListOfFunctions(); + if (functions) + pm = (TPolyMarker*)functions->FindObject("TPolyMarker"); + if (pm) { + peakX=pm->GetX(); + peakY=pm->GetY(); + + + if (peakX[0]>peakX[1]) { + peakdum=peakX[0]; + hpeakdum=peakY[0]; + peakX[0]= peakX[1]; + peakY[0]= peakY[1]; + peakX[1]= peakdum; + peakY[1]= hpeakdum; + + } + + cout << "("<< ix << "," << iy << ") " << endl; + for (int ip=0; ipsetFitRange(peakX[ip]-10*g,peakX[ip]+10*g); + mypar[0]=0; + mypar[1]=0; + mypar[2]=peakX[ip]; + mypar[3]=g*10; + mypar[4]=peakY[ip]; + mypar[5]=0; + + + + enCal->setStartParameters(mypar); + enCal->fitSpectrum(px,mypar,emypar); + + + peaks[ip+1]=mypar[2]; + epeaks[ip+1]=emypar[2]; + } + + peaks[0]=0; + epeaks[0]=1; + + // for (int i=0; i<3; i++) cout << i << " " << ens[i] << " " << eens[i]<< " "<< peaks[i]<< " " << epeaks[i] << endl; + + glin= enCal->linearCalibration(3,ens,eens,peaks,epeaks,gain,off,egain,eoff); + + // cout << "Gain " << gain << " off " << off << endl; + if (off>-10 && off<10) { + gMap->SetBinContent(ix+1,iy+1,gain); + gMap->SetBinError(ix+1,iy+1,egain); + } + if (glin) + delete glin; + } + } + + + } + } + + return gMap; +} + + +TH2F *noiseMap(TH2F *h2) { + // int npx, npy; + int npx=160, npy=160; + // det->getDetectorSize(npx, npy); + + TH2F *nMap=new TH2F("nmap",h2->GetTitle(), npx, -0.5, npx-0.5, npy, -0.5, npy-0.5); + + int ibin; + TH1D *px; + + for (int ix=0; ixProjectionX("px",ibin+1,ibin+1); + px->Fit("gaus", FOPT); + if (px->GetFunction("gaus")) { + nMap->SetBinContent(ix+1,iy+1,px->GetFunction("gaus")->GetParameter(2)); + } + // delete px; + } + } + + return nMap; +} + + +THStack *noiseHistos(char *tit) { + char fname[10000]; + + sprintf(fname,"/data/moench_xbox_20140116/noise_map_%s.root",tit); + TFile *fn=new TFile(fname); + TH2F *nmap=(TH2F*)fn->Get("nmap"); + + if (nmap==NULL) { + cout << "No noise map in file " << fname << endl; + + return NULL; + } + + sprintf(fname,"/data/moench_xbox_20140113/gain_map_%s.root",tit); + TFile *fg=new TFile(fname); + TH2F *gmap=(TH2F*)fg->Get("gmap"); + + if (gmap==NULL) { + cout << "No gain map in file " << fname << endl; + + return NULL; + } + + nmap->Divide(gmap); + nmap->Scale(1000./3.6); + + THStack *hs=new THStack(tit,tit); + hs->SetTitle(tit); + + TH1F *h; + char hname[100]; + + cout << tit << endl; + for (int is=0; is<4; is++) { + sprintf(hname,"h%ds",is+1); + + h=new TH1F(hname,tit,500,0,500); + hs->Add(h); + // cout << hs->GetHists()->GetEntries() << endl; + for (int ix=40*is+2; ix<40*(is+1)-2; ix++) { + + for (int iy=2; iy<158; iy++) { + if (ix<100 || ix>120) + h->Fill(nmap->GetBinContent(ix+1,iy+1)); + } + } + cout << is+1 << "SC: " << "" << h->GetMean() << "+-" << h->GetRMS(); + h->Fit("gaus","0Q"); + h->SetLineColor(is+1); + if (h->GetFunction("gaus")) { + h->GetFunction("gaus")->SetLineColor(is+1); + cout << " or " << h->GetFunction("gaus")->GetParameter(1) << "+-" << h->GetFunction("gaus")->GetParError(1); + } + cout << endl; + } + + // cout << hs->GetHists()->GetEntries() << endl; + + return hs; + + +} diff --git a/slsReceiverSoftware/slsDetectorCalibration/gotthardModuleData.h b/slsReceiverSoftware/slsDetectorCalibration/gotthardModuleData.h new file mode 100644 index 000000000..3f674af57 --- /dev/null +++ b/slsReceiverSoftware/slsDetectorCalibration/gotthardModuleData.h @@ -0,0 +1,148 @@ +#ifndef GOTTHARDMODULEDATA_H +#define GOTTHARDMODULEDATA_H +#include "slsReceiverData.h" + + + + + +#define FRAMEMASK 0xFFFFFFFE +#define PACKETMASK 1 +#define FRAMEOFFSET 0x1 + + +class gotthardModuleData : public slsReceiverData { +public: + + + + + /** + Implements the slsReceiverData structure for the gotthard read out by a module i.e. using the slsReceiver + (1x1280 pixels, 2 packets 1286 large etc.) + \param c crosstalk parameter for the output buffer + + */ + + + gotthardModuleData(double c=0): slsReceiverData(xpixels, ypixels, npackets, buffersize), xtalk(c) { + + uint16_t **dMask; + int **dMap; + int ix, iy; + int initial_offset = 2; + int offset = initial_offset; + + dMask=new uint16_t*[ypixels]; + dMap=new int*[ypixels]; + for (int i = 0; i < ypixels; i++) { + dMap[i] = new int[xpixels]; + dMask[i] = new uint16_t[xpixels]; + } + + for(ix=0; ix>FRAMEOFFSET); + }; + + + + /** + gets the packets number (last packet is labelled with 0 and is replaced with 40) + \param buff pointer to the memory + \returns packet number + + */ + + int getPacketNumber(char *buff){ + int np=(*(int*)buff); + //gotthards frame header must be incremented + ++np; + //packet index should be 1 or 2 + return ((np&PACKETMASK)+1); + }; + + + /** + returns the pixel value as double correcting for the output buffer crosstalk + \param data pointer to the memory + \param ix coordinate in the x direction + \param iy coordinate in the y direction + \returns channel value as double + + */ + double getValue(char *data, int ix, int iy=0) { + //check how it is for gotthard + if (xtalk==0) + return slsDetectorData::getValue(data, ix, iy); + else + return slsDetectorData::getValue(data, ix, iy)-xtalk*slsDetectorData::getValue(data, ix-1, iy); + }; + + + + /** sets the output buffer crosstalk correction parameter + \param c output buffer crosstalk correction parameter to be set + \returns current value for the output buffer crosstalk correction parameter + + */ + double setXTalk(double c) {xtalk=c; return xtalk;} + + + /** gets the output buffer crosstalk parameter + \returns current value for the output buffer crosstalk correction parameter + */ + double getXTalk() {return xtalk;} + + + + + + + +private: + + double xtalk; /** { +public: + + + + + /** + Implements the slsReceiverData structure for the gotthard short read out by a module i.e. using the slsReceiver + (1x256 pixels, 1 packet 256 large etc.) + \param c crosstalk parameter for the output buffer + + */ + + + gotthardShortModuleData(double c=0): slsReceiverData(xpixels, ypixels, npackets, buffersize), xtalk(c){ + + uint16_t **dMask; + int **dMap; + int ix, iy; + int offset = 2; + + dMask=new uint16_t*[ypixels]; + dMap=new int*[ypixels]; + for (int i = 0; i < ypixels; i++) { + dMap[i] = new int[xpixels]; + dMask[i] = new uint16_t[xpixels]; + } + + for(ix=0; ix::getValue(data, ix, iy); + else + return slsDetectorData::getValue(data, ix, iy)-xtalk*slsDetectorData::getValue(data, ix-1, iy); + }; + + + + /** sets the output buffer crosstalk correction parameter + \param c output buffer crosstalk correction parameter to be set + \returns current value for the output buffer crosstalk correction parameter + + */ + double setXTalk(double c) {xtalk=c; return xtalk;} + + + /** gets the output buffer crosstalk parameter + \returns current value for the output buffer crosstalk correction parameter + */ + double getXTalk() {return xtalk;} + + + + + + + +private: + + double xtalk; /**=0 && ix=0 && iy=0 && dataMap[iy][ix]8000) //exchange if gainBits==2 is returned! + d|=(1<<14); // gain bit 1 + if (*((uint16_t*)(data)+dataMap[iy][ix]+1)>8000) //exchange if gainBits==2 is returned! + d|=(1<<15); // gain bit 0 + + } + + } + return d^m; + }; + + /** + returns the pixel value as double correcting for the output buffer crosstalk + \param data pointer to the memory + \param ix coordinate in the x direction + \param iy coordinate in the y direction + \returns channel value as double + + */ + double getValue(char *data, int ix, int iy=0) { + // cout << "##" << (void*)data << " " << ix << " " < the gain bits are read out the wrong way around (i.e. GB0 and GB1 have to be reversed!) + \param data pointer to the memory + \param ix coordinate in the x direction + \param iy coordinate in the y direction + \returns gain bits as int + */ + int getGainBits(char *data, int ix, int iy=0) { + uint16_t d=getChannel(data, ix, iy); + return ((d&0xc000)>>14); + }; + //*/ + + + + + /** sets the output buffer crosstalk correction parameter + \param c output buffer crosstalk correction parameter to be set + \returns current value for the output buffer crosstalk correction parameter + + */ + double setXTalk(double c) {xtalk=c; return xtalk;} + + + /** gets the output buffer crosstalk parameter + \returns current value for the output buffer crosstalk correction parameter + */ + double getXTalk() {return xtalk;} + + + + + + + + private: + + double xtalk; /** +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +//#include +//#include +//#include +#include +#include "jungfrau02Data.h" +#include "jungfrau02CommonMode.h" +#include "singlePhotonDetector.h" + +//#include "MovingStat.h" + +using namespace std; + +#define NC 48 +#define NR 48 + + +#define MY_DEBUG 1 +#ifdef MY_DEBUG +#include +#endif + +/** + +Loops over data file to find single photons, fills the tree (and writes it to file, although the root file should be opened before) and creates 1x1, 2x2, 3x3 cluster histograms with ADCu on the x axis, channel number (48*x+y) on the y axis. + + \param fformat file name format + \param tit title of the tree etc. + \param runmin minimum run number + \param runmax max run number + \param nbins number of bins for spectrum hists + \param hmin histo minimum for spectrum hists + \param hmax histo maximum for spectrum hists + \param sign sign of the spectrum to find hits + \param hc readout correlation coefficient with previous pixel + \param xmin minimum x coordinate + \param xmax maximum x coordinate + \param ymin minimum y coordinate + \param ymax maximum y coordinate + \param cmsub enable commonmode subtraction + \param hitfinder if 0: performs pedestal subtraction, not hit finding; if 1: performs both pedestal subtraction and hit finding + \returns pointer to histo stack with cluster spectra +*/ + + +THStack *jungfrauReadData(char *fformat, char *tit, int runmin, int runmax, int nbins=1500, int hmin=-500, int hmax=1000, int sign=1, double hc=0, int xmin=1, int xmax=NC-1, int ymin=1, int ymax=NR-1, int cmsub=0, int hitfinder=1){ +/* + // read in calibration file + ifstream calfile("/home/l_msdetect/TriesteBeam2014/dummy data for scripts/CalibrationParametersTest_fake.txt"); + if (calfile.is_open()==0){cout << "Unable to open calibration file!" << endl;} + int pix; + double of0,sl0,of1,sl1,of2,sl2; + double of_0[NC*NR], of_1[NC*NR], of_2[NC*NR], sl_0[NC*NR], sl_1[NC*NR], sl_2[NC*NR]; + while (calfile >> pix >> of0 >> sl0 >> of1 >> sl1 >> of2 >> sl2){ + of_0[pix]=of0; + sl_0[pix]=sl0; + of_1[pix]=of1; + sl_1[pix]=sl1; + of_2[pix]=of2; + sl_2[pix]=sl2; //if(pix==200) cout << "sl_2[200] " << sl_2[200] << endl; + } + calfile.close(); +*/ + double adc_value, num_photon; + + jungfrau02Data *decoder=new jungfrau02Data(1,0,0);//(1,0,0); // (adc,offset,crosstalk) //(1,0,0) //(3,0,0) for readout of GB + jungfrau02CommonMode *cmSub=NULL; + if (cmsub) + cmSub=new jungfrau02CommonMode(); + + int nph=0; + int iev=0; + singlePhotonDetector *filter=new singlePhotonDetector(decoder, 3, 5, sign, cmSub); + + char *buff; + char fname[10000]; + int nf=0; + + eventType thisEvent=PEDESTAL; + + // int iframe; + // double *data, ped, sigma; + + // data=decoder->getCluster(); + + TH2F *h2; + TH2F *h3; + TH2F *hetaX; // not needed for JF? + TH2F *hetaY; // not needed for JF? + + THStack *hs=new THStack("hs",fformat); + + + TH2F *h1=new TH2F("h1",tit,nbins,hmin-0.5,hmax-0.5,NC*NR,-0.5,NC*NR-0.5); + hs->Add(h1); + + if (hitfinder) { + h2=new TH2F("h2",tit,nbins,hmin-0.5,hmax-0.5,NC*NR,-0.5,NC*NR-0.5); + h3=new TH2F("h3",tit,nbins,hmin-0.5,hmax-0.5,NC*NR,-0.5,NC*NR-0.5); + hetaX=new TH2F("hetaX",tit,nbins,-1,2,NC*NR,-0.5,NC*NR-0.5); // not needed for JF? + hetaY=new TH2F("hetaY",tit,nbins,-1,2,NC*NR,-0.5,NC*NR-0.5); // not needed for JF? + hs->Add(h2); + hs->Add(h3); + hs->Add(hetaX); // not needed for JF? + hs->Add(hetaY); // not needed for JF? + } + + + ifstream filebin; + + + int ix=20, iy=20, ir, ic; + + + Int_t iFrame; + TTree *tall; + if (hitfinder) + tall=filter->initEventTree(tit, &iFrame); + + + + +#ifdef MY_DEBUG + + TCanvas *myC; + TH2F *he; + TCanvas *cH1; + TCanvas *cH2; + TCanvas *cH3; + + if (hitfinder) { + myC=new TCanvas(); + he=new TH2F("he","Event Mask",xmax-xmin, xmin, xmax, ymax-ymin, ymin, ymax); + he->SetStats(kFALSE); + he->Draw("colz"); + cH1=new TCanvas(); + cH1->SetLogz(); + h1->Draw("colz"); + cH2=new TCanvas(); + cH2->SetLogz(); + h2->Draw("colz"); + cH3=new TCanvas(); + cH3->SetLogz(); + h3->Draw("colz"); + } +#endif + filter->newDataSet(); + + + for (int irun=runmin; irun<=runmax; irun++){ + sprintf(fname,fformat,irun); + cout << "file name " << fname << endl; + filebin.open((const char *)(fname), ios::in | ios::binary); + nph=0; + while ((buff=decoder->readNextFrame(filebin))) { + + + if (hitfinder) { + filter->newFrame(); + + //calculate pedestals and common modes + if (cmsub) { + // cout << "cm" << endl; + for (ix=xmin-1; ixgetEventType(buff, ix, iy,0); + } + } + } + + // cout << "new frame " << endl; + + for (ix=xmin-1; ixgetEventType(buff, ix, iy, cmsub); + int gainBits=decoder->getGainBits(buff,ix,iy); //XXX + +#ifdef MY_DEBUG + if (hitfinder) { + if (iev%1000==0) + //he->SetBinContent(ix+1-xmin, iy+1-ymin, (int)thisEvent); // show single photon hits // original + //he->SetBinContent(ix+1-xmin, iy+1-ymin, cmSub->getCommonMode(ix,iy)); //show common mode! + he->SetBinContent(iy+1-ymin, ix+1-xmin, (int)gainBits); //show gain bits + //he->SetBinContent(ix+1-xmin, iy+1-ymin, (int)gainBits); // rows and columns reversed!!! + } +#endif + + if (nf>1000) { // only start filing data after 1000 frames + + // h1->Fill(decoder->getValue(buff,ix,iy), iy+NR*ix); + h1->Fill(filter->getClusterTotal(1), iy+NR*ix); + + + if (hitfinder) { + + if (thisEvent==PHOTON_MAX ) { + nph++; + + h2->Fill(filter->getClusterTotal(2), iy+NR*ix); + h3->Fill(filter->getClusterTotal(3), iy+NR*ix); + iFrame=decoder->getFrameNumber(buff); + + tall->Fill(); + + + } + + + } + + + } + } + ////////////////////////////////////////////////////////// + +#ifdef MY_DEBUG + if (iev%1000==0) { + myC->Modified(); + myC->Update(); + cH1->Modified(); + cH1->Update(); + cH2->Modified(); + cH2->Update(); + cH3->Modified(); + cH3->Update(); + } + iev++; +#endif + nf++; + + cout << "="; // one "=" for every frame that's been processed + delete [] buff; + } + cout << nph << endl; // number of photons found in file + if (filebin.is_open()) + filebin.close(); + else + cout << "Could not open file :( ... " << fname << endl; + } + if (hitfinder) + tall->Write(tall->GetName(),TObject::kOverwrite); + + + + delete decoder; + cout << "Read " << nf << " frames." << endl; + return hs; +} + diff --git a/slsReceiverSoftware/slsDetectorCalibration/moench02ModuleData.h b/slsReceiverSoftware/slsDetectorCalibration/moench02ModuleData.h new file mode 100644 index 000000000..34b4f1783 --- /dev/null +++ b/slsReceiverSoftware/slsDetectorCalibration/moench02ModuleData.h @@ -0,0 +1,137 @@ +#ifndef MOENCH02MODULEDATA_H +#define MOENCH02MODULEDATA_H +#include "slsReceiverData.h" + + + +class moench02ModuleData : public slsReceiverData { + public: + + + + + /** + Implements the slsReceiverData structure for the moench02 prototype read out by a module i.e. using the slsReceiver + (160x160 pixels, 40 packets 1286 large etc.) + \param c crosstalk parameter for the output buffer + + */ + + + moench02ModuleData(double c=0): slsReceiverData(160, 160, 40, 1286), + xtalk(c) { + + + + + uint16_t **dMask; + int **dMap; + int ix, iy; + + + + dMask=new uint16_t*[160]; + dMap=new int*[160]; + for (int i = 0; i < 160; i++) { + dMap[i] = new int[160]; + dMask[i] = new uint16_t[160]; + } + + for (int isc=0; isc<4; isc++) { + for (int ip=0; ip<10; ip++) { + + for (int ir=0; ir<16; ir++) { + for (int ic=0; ic<40; ic++) { + + ix=isc*40+ic; + iy=ip*16+ir; + + dMap[iy][ix]=1286*(isc*10+ip)+2*ir*40+2*ic+4; + // cout << ix << " " << iy << " " << dMap[ix][iy] << endl; + } + } + } + } + + for (ix=0; ix<120; ix++) { + for (iy=0; iy<160; iy++) + dMask[iy][ix]=0x3fff; + } + for (ix=120; ix<160; ix++) { + for (iy=0; iy<160; iy++) + dMask[iy][ix]=0x0; + } + + + setDataMap(dMap); + setDataMask(dMask); + + + + + }; + + + + /** + gets the packets number (last packet is labelled with 0 and is replaced with 40) + \param buff pointer to the memory + \returns packet number + + */ + + int getPacketNumber(char *buff){ + int np=(*(int*)buff)&0xff; + if (np==0) + np=40; + return np; + }; + + + /** + returns the pixel value as double correcting for the output buffer crosstalk + \param data pointer to the memory + \param ix coordinate in the x direction + \param iy coordinate in the y direction + \returns channel value as double + + */ + double getValue(char *data, int ix, int iy=0) { + // cout << "##" << (void*)data << " " << ix << " " <::getValue(data, ix, iy); + else + return slsDetectorData::getValue(data, ix, iy)-xtalk*slsDetectorData::getValue(data, ix-1, iy); + }; + + + + /** sets the output buffer crosstalk correction parameter + \param c output buffer crosstalk correction parameter to be set + \returns current value for the output buffer crosstalk correction parameter + + */ + double setXTalk(double c) {xtalk=c; return xtalk;} + + + /** gets the output buffer crosstalk parameter + \returns current value for the output buffer crosstalk correction parameter + */ + double getXTalk() {return xtalk;} + + + + + + + + private: + + double xtalk; /**=0 && isc=0 && isc0) return cmPed[isc]/nCm[isc]-cmStat[isc].Mean(); + } + return 0; + }; + +}; + + +#endif diff --git a/slsReceiverSoftware/slsDetectorCalibration/moenchMakeTree.C b/slsReceiverSoftware/slsDetectorCalibration/moenchMakeTree.C new file mode 100644 index 000000000..372052285 --- /dev/null +++ b/slsReceiverSoftware/slsDetectorCalibration/moenchMakeTree.C @@ -0,0 +1,244 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "RunningStat.h" +#include "MovingStat.h" +#include "moench02ModuleData.h" +#include + +using namespace std; + + +//tree variables + int xC,yC,iFrameC; + double meC,sigC; + Double_t dataC[3][3]; +TTree* tall; + +typedef struct task_s{ + char *fformat; + char *tname; + int runmin; + int runmax; + int sign; +} Task; + +void setUpTree(char *tname){ + tall=new TTree(tname,tname); + tall->Branch("iFrame",&iFrameC,"iframe/I"); + tall->Branch("x",&xC,"x/I"); + tall->Branch("y",&yC,"y/I"); + tall->Branch("data",dataC,"data[3][3]/D"); + tall->Branch("pedestal",&meC,"pedestal/D"); + tall->Branch("rms",&sigC,"rms/D"); +} + +inline void storeEvent(int iF,int x,int y, Double_t data[][3], double me, double sig){ + TThread::Lock(); + xC = x; yC = y; iFrameC = iF; + memcpy(dataC,data,sizeof(Double_t)*3*3); + //cout << "X: " << x << " Y: " << y << endl; + /* for(int i = 0; i < 3; i++){ + for(int j = 0; j < 3; j++){ + cout << "i: " << i << " j: " << j << " dataC " << dataC[i][j] << " data " << data[i][j] << endl; + } + }*/ + meC = me; sigC = sig; + tall->Fill(); + TThread::UnLock(); +} + +void moenchMakeTree(char *fformat, char *tname, int runmin, int runmax, int sign=1) { + double nThSigma = 3.; + moench02ModuleData *decoder=new moench02ModuleData(); + char *buff; + char fname[10000]; + + int nf=0; + + int dum, nPhotons; + double me, sig, tot, maxNei, val, valNei; + + MovingStat stat[160][160]; + MovingStat nPhotonsStat; + + ifstream filebin; + + int nbg=20; + + int ix, iy, ir, ic, mx,my; + Double_t data[3][3]; + + nPhotonsStat.Clear(); + nPhotonsStat.SetN(1000); + + for (ir=0; ir<160; ir++) { + for (ic=0; ic<160; ic++) { + stat[ir][ic].Clear(); + stat[ir][ic].SetN(nbg); + } + } + + for (int irun=runmin; irunreadNextFrame(filebin))) { + nPhotons=0; + //for (ix=0; ix<160; ix++){ + for (ix=0; ix<40; ix++){ + for (iy=0; iy<160; iy++) { + + + + dum=0; //no hit + // tot=0; + + me=stat[iy][ix].Mean(); + sig=stat[iy][ix].StandardDeviation(); + val=sign*(decoder->getChannelShort(buff,ix,iy)-me); + + + if (nf>nbg) { + me=stat[iy][ix].Mean(); + sig=stat[iy][ix].StandardDeviation(); + val=sign*decoder->getChannel(buff,ix,iy)-me; + + // dum=0; //no hit + tot=0; + maxNei = 0; + + if (val>nThSigma*sig)//{ //hit check if neighbors are higher + dum=1; + for (ir=-1; ir<2; ir++){ + for (ic=-1; ic<2; ic++){ + if ((ix+ic)>=0 && (ix+ic)<160 && (iy+ir)>=0 && (iy+ir)<160) { + valNei = sign*decoder->getChannel(buff,ix+ic,iy+ir)-stat[iy+ir][ix+ic].Mean(); + if (sign*decoder->getChannel(buff,ix+ic,iy+ir)>(stat[iy+ir][ix+ic].Mean()+3.*stat[iy+ir][ix+ic].StandardDeviation())) dum=1; //is a hit or neighbour is a hit! + tot+=valNei; + data[ir+1][ic+1] = valNei; + if(valNei/stat[iy+ir][ix+ic].StandardDeviation() > maxNei){ + maxNei = valNei/stat[iy+ir][ix+ic].StandardDeviation(); + mx = ir; + my = ic; + } + } + } + } + // } + + if (val<(-nThSigma*sig)) dum=2; //discard negative events! + + if(dum == 1 && mx == 0 && my == 0){ // this is an event and we are in the center + storeEvent(nf,ix,iy,data,me,sig); + nPhotons++; + //cout << "BF X: " << ix << " Y: " << iy << " val: " << val << " tot: " << tot << " me: " << me << " sig: " << sig << endl; + } + + + //if (tot>9.*sig && dum == 1){ dum=3;} + //cout << dum; + } + //if (ix==20 && iy==40) + //cout << decoder->getChannelShort(buff,ix,iy)<< " " << val << " " << me << " " << sig << " " << dum << endl; + + if ( dum==0) { + + stat[iy][ix].Calc(decoder->getChannelShort(buff,ix,iy)); + } + if (nfgetChannel(buff,ix,iy)); + + } + } + delete [] buff; + //cout << "="; cout.flush(); + if(nf>nbg) nPhotonsStat.Calc((double)nPhotons); + nf++; + } + //cout << endl; + cout << "processed File " << fname << " done. Avg. Photons/Frame: " << nPhotonsStat.Mean() << " sig: " << nPhotonsStat.StandardDeviation() << " " << runmax-irun << " files need processing" << endl; + if (filebin.is_open()) + filebin.close(); + else + cout << "could not open file " << fname << endl; + } + + delete decoder; + cout << "Read " << nf << " frames" << endl; + + +} + +void *moenchMakeTreeTask(void *p){ + Task *t = (Task *)p; + moenchMakeTree(t->fformat,t->tname,t->runmin,t->runmax,t->sign); + return 0; +} + + +//to compile: g++ -DMYROOT -g `root-config --cflags --glibs` -o moenchMakeTree moenchMakeTree.C +int main(int argc, char **argv){ + if(argc != 6){ cout << "Usage: inFile outdir tname fileNrStart fileNrEnd" << endl; exit(-1); } + + int nThreads = 10; + TThread *threads[nThreads]; + + char *inFile = argv[1]; + char *outDir = argv[2]; + char *tName = argv[3]; + int start = atoi(argv[4]); + int end = atoi(argv[5]); + + TFile *f; + char outfname[1000]; + char threadName[1000]; + + sprintf(outfname,"%s/%s.root",outDir,tName); + f=new TFile(outfname,"RECREATE"); + + cout << "outputfile: " << outfname << endl; + setUpTree(tName); + + for(int i = 0; i < nThreads; i++){ + sprintf(threadName,"t%i",i); + Task *t = (Task *)malloc(sizeof(Task)); + t->fformat = inFile; + t->tname = tName; + t->sign = 1.; + t->runmin = start + (end-start)/(nThreads)*i; + t->runmax = start + (end-start)/(nThreads)*(i+1); + if(i == nThreads - 1) t->runmax = end; + cout << "start thread " << i << " start: " << t->runmin << " end " << t->runmax << endl; + threads[i] = new TThread(threadName, moenchMakeTreeTask, t); + threads[i]->Run(); + //moenchMakeTreeTask(t); + } + + + //TThread::Ps(); + + for(int i = 0; i < nThreads; i++){ + threads[i]->Join(); + } + + + tall->Write(); + tall->Print(); + f->Close(); +} + diff --git a/slsReceiverSoftware/slsDetectorCalibration/moenchReadData.C b/slsReceiverSoftware/slsDetectorCalibration/moenchReadData.C new file mode 100644 index 000000000..bf7173f0b --- /dev/null +++ b/slsReceiverSoftware/slsDetectorCalibration/moenchReadData.C @@ -0,0 +1,236 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +//#include +//#include +//#include +#include +#include "moench02ModuleData.h" +#include "moenchCommonMode.h" +#include "singlePhotonDetector.h" + +//#include "MovingStat.h" + +using namespace std; + +#define NC 160 +#define NR 160 + + +#define MY_DEBUG 1 +#ifdef MY_DEBUG +#include +#endif + +/** + +Loops over data file to find single photons, fills the tree (and writes it to file, althoug the root file should be opened before) and creates 1x1, 2x2, 3x3 cluster histograms with ADCu on the x axis, channel number (160*x+y) on the y axis. + + \param fformat file name format + \param tit title of the tree etc. + \param runmin minimum run number + \param runmax max run number + \param nbins number of bins for spectrum hists + \param hmin histo minimum for spectrum hists + \param hmax histo maximum for spectrum hists + \param sign sign of the spectrum to find hits + \param hc readout correlation coefficient with previous pixel + \param xmin minimum x coordinate + \param xmax maximum x coordinate + \param ymin minimum y coordinate + \param ymax maximum y coordinate + \param cmsub enable commonmode subtraction + \returns pointer to histo stack with cluster spectra +*/ + + +THStack *moenchReadData(char *fformat, char *tit, int runmin, int runmax, int nbins=1500, int hmin=-500, int hmax=1000, int sign=1, double hc=0, int xmin=1, int xmax=NC-1, int ymin=1, int ymax=NR-1, int cmsub=0, int hitfinder=1) { + + moench02ModuleData *decoder=new moench02ModuleData(hc); + moenchCommonMode *cmSub=NULL; + if (cmsub) + cmSub=new moenchCommonMode(); + + int nph=0; + + singlePhotonDetector *filter=new singlePhotonDetector(decoder, 3, 5, sign, cmSub); + + char *buff; + char fname[10000]; + int nf=0; + + eventType thisEvent=PEDESTAL; + + // int iframe; + // double *data, ped, sigma; + + // data=decoder->getCluster(); + + TH2F *h2; + TH2F *h3; + TH2F *hetaX; + TH2F *hetaY; + + THStack *hs=new THStack("hs",fformat); + + + + TH2F *h1=new TH2F("h1",tit,nbins,hmin-0.5,hmax-0.5,NC*NR,-0.5,NC*NR-0.5); + hs->Add(h1); + + if (hitfinder) { + h2=new TH2F("h2",tit,nbins,hmin-0.5,hmax-0.5,NC*NR,-0.5,NC*NR-0.5); + h3=new TH2F("h3",tit,nbins,hmin-0.5,hmax-0.5,NC*NR,-0.5,NC*NR-0.5); + hetaX=new TH2F("hetaX",tit,nbins,-1,2,NC*NR,-0.5,NC*NR-0.5); + hetaY=new TH2F("hetaY",tit,nbins,-1,2,NC*NR,-0.5,NC*NR-0.5); + hs->Add(h2); + hs->Add(h3); + hs->Add(hetaX); + hs->Add(hetaY); + } + + + + ifstream filebin; + + + int ix=20, iy=20, ir, ic; + + + Int_t iFrame; + TTree *tall; + if (hitfinder) + tall=filter->initEventTree(tit, &iFrame); + + + + +#ifdef MY_DEBUG + + TCanvas *myC; + TH2F *he; + TCanvas *cH1; + TCanvas *cH2; + TCanvas *cH3; + + if (hitfinder) { + myC=new TCanvas(); + he=new TH2F("he","Event Mask",xmax-xmin, xmin, xmax, ymax-ymin, ymin, ymax); + he->SetStats(kFALSE); + he->Draw("colz"); + cH1=new TCanvas(); + cH1->SetLogz(); + h1->Draw("colz"); + cH2=new TCanvas(); + cH2->SetLogz(); + h2->Draw("colz"); + cH3=new TCanvas(); + cH3->SetLogz(); + h3->Draw("colz"); + } +#endif + filter->newDataSet(); + + + for (int irun=runmin; irunreadNextFrame(filebin))) { + + + if (hitfinder) { + filter->newFrame(); + + //calculate pedestals and common modes + if (cmsub) { + // cout << "cm" << endl; + for (ix=xmin-1; ixgetEventType(buff, ix, iy,0); + } + } + } + + // cout << "new frame " << endl; + + for (ix=xmin-1; ixgetEventType(buff, ix, iy, cmsub); + +#ifdef MY_DEBUG + if (hitfinder) { + if (iev%1000==0) + he->SetBinContent(ix+1-xmin, iy+1-ymin, (int)thisEvent); + } +#endif + + if (nf>1000) { + h1->Fill(filter->getClusterTotal(1), iy+NR*ix); + if (hitfinder) { + + if (thisEvent==PHOTON_MAX ) { + nph++; + + h2->Fill(filter->getClusterTotal(2), iy+NR*ix); + h3->Fill(filter->getClusterTotal(3), iy+NR*ix); + iFrame=decoder->getFrameNumber(buff); + + tall->Fill(); + + + } + + + } + + + } + } + ////////////////////////////////////////////////////////// + +#ifdef MY_DEBUG + if (iev%1000==0) { + myC->Modified(); + myC->Update(); + cH1->Modified(); + cH1->Update(); + cH2->Modified(); + cH2->Update(); + cH3->Modified(); + cH3->Update(); + } + iev++; +#endif + nf++; + + cout << "=" ; + delete [] buff; + } + cout << nph << endl; + if (filebin.is_open()) + filebin.close(); + else + cout << "could not open file " << fname << endl; + } + if (hitfinder) + tall->Write(tall->GetName(),TObject::kOverwrite); + + + + delete decoder; + cout << "Read " << nf << " frames" << endl; + return hs; +} + diff --git a/slsReceiverSoftware/slsDetectorCalibration/moenchReadDataMT.C b/slsReceiverSoftware/slsDetectorCalibration/moenchReadDataMT.C new file mode 100644 index 000000000..0720909c4 --- /dev/null +++ b/slsReceiverSoftware/slsDetectorCalibration/moenchReadDataMT.C @@ -0,0 +1,52 @@ +#include +#include +#include "moenchReadData.C" + +typedef struct task_s{ + char *fformat; + char *tname; + char *tdir; + int runmin; + int runmax; + int treeIndex; +} Task; + +void *moenchMakeTreeTask(void *p){ + TThread::Lock(); + char fname[1000]; + Task *t = (Task *)p; + sprintf(fname,"%s%s_%i.root",t->tdir,t->tname,t->treeIndex); + TFile *f = new TFile(fname,"RECREATE"); + cout << "Call moenchReadData(" << t->fformat << "," << t->tname << "," << t->runmin<< "," << t->runmax <<")" << endl; + TThread::UnLock(); + moenchReadData(t->fformat,t->tname,t->runmin,t->runmax); + f->Close(); + return 0; +} + + +void moenchReadDataMT(char *fformat, char *tit, char *tdir, int runmin, int runoffset, int nThreads, int treeIndexStart=0){ + char threadName[1000]; + TThread *threads[nThreads]; + for(int i = 0; i < nThreads; i++){ + sprintf(threadName,"t%i",i); + Task *t = (Task *)malloc(sizeof(Task)); + t->fformat = fformat; + t->tname = tit; + t->tdir = tdir; + t->runmin = runmin + i*runoffset; + t->runmax = runmin + (i+1)*runoffset - 1; + t->treeIndex = treeIndexStart + i; + cout << "start thread " << i << " start: " << t->runmin << " end " << t->runmax << endl; + threads[i] = new TThread(threadName, moenchMakeTreeTask, t); + threads[i]->Run(); + } + + for(int i = 0; i < nThreads; i++){ + threads[i]->Join(); + } + +} + + + diff --git a/slsReceiverSoftware/slsDetectorCalibration/pedestalSubtraction.h b/slsReceiverSoftware/slsDetectorCalibration/pedestalSubtraction.h new file mode 100644 index 000000000..ee3aff8aa --- /dev/null +++ b/slsReceiverSoftware/slsDetectorCalibration/pedestalSubtraction.h @@ -0,0 +1,48 @@ +#ifndef PEDESTALSUBTRACTION_H +#define PEDESTALSUBTRACTION_H + +#include "MovingStat.h" + +class pedestalSubtraction { + /** @short class defining the pedestal subtraction based on an approximated moving average */ + public: + /** constructor + \param nn number of samples to calculate the moving average (defaults to 1000) + */ + pedestalSubtraction (int nn=1000) : stat(nn) {}; + + /** virtual destructorr + */ + virtual ~pedestalSubtraction() {}; + + /** clears the moving average */ + virtual void Clear() {stat.Clear();} + + /** adds the element to the moving average + \param val value to be added + */ + virtual void addToPedestal(double val){stat.Calc(val);}; + + /** returns the average value of the pedestal + \returns mean of the moving average + */ + virtual double getPedestal(){return stat.Mean();}; + + /** returns the standard deviation of the moving average + \returns standard deviation of the moving average + */ + virtual double getPedestalRMS(){return stat.StandardDeviation();}; + + /**sets/gets the number of samples for the moving average + \param i number of elements for the moving average. If -1 (default) or negative, gets. + \returns actual number of samples for the moving average + */ + virtual int SetNPedestals(int i=-1) {if (i>0) stat.SetN(i); return stat.GetN();}; + + + + private: + MovingStat stat; /**< approximated moving average struct */ + +}; +#endif diff --git a/slsReceiverSoftware/slsDetectorCalibration/raedNoiseData.C b/slsReceiverSoftware/slsDetectorCalibration/raedNoiseData.C new file mode 100644 index 000000000..b2021b29f --- /dev/null +++ b/slsReceiverSoftware/slsDetectorCalibration/raedNoiseData.C @@ -0,0 +1,136 @@ +#include "moenchReadData.C" + + + +void raedNoiseData(char *tit, int sign=1){ + + + + + + char fname[1000]; + char f[1000]; + TFile *fout; + THStack *hs2N; + + sprintf(fname,"/data/moench_xbox_20140113/MoTarget_45kV_0_8mA_120V_%s_0.root",tit); + fout=new TFile(fname,"RECREATE"); + + sprintf(fname,"/data/moench_xbox_20140113/MoTarget_45kV_0_8mA_120V_%s_f00000%%04d000_0.raw",tit); + + hs2N=moenchReadData(fname,0,3000,1500,-500,2500,1,0.,1,159,1,159, 0,1); + hs2N->SetName(tit); + hs2N->SetTitle(tit); + (TH2F*)(hs2N->GetHists()->At(0))->Write(); + + (TH2F*)(hs2N->GetHists()->At(1))->Write(); + (TH2F*)(hs2N->GetHists()->At(2))->Write(); + (TH2F*)(hs2N->GetHists()->At(3))->Write(); + (TH2F*)(hs2N->GetHists()->At(4))->Write(); + + + fout->Close(); + + + +} + + + +void raedNoiseDataN(char *tit, int sign=1){ + + + + char fname[1000]; + char f[1000]; + TFile *fout; + THStack *hs2N; + + sprintf(fname,"/data/moench_xbox_20140116/noise_%s.root",tit); + fout=new TFile(fname,"RECREATE"); + + sprintf(fname,"/data/moench_xbox_20140116/noise_%s_f00000%%04d000_0.raw",tit); + + hs2N=moenchReadData(fname,tit,0,3000,1500,-500,2500,sign,0.,1,159,1,159, 0,0); + hs2N->SetName(tit); + hs2N->SetTitle(tit); + (TH2F*)(hs2N->GetHists()->At(0))->Write(); + + // (TH2F*)(hs2N->GetHists()->At(1))->Write(); + // (TH2F*)(hs2N->GetHists()->At(2))->Write(); + // (TH2F*)(hs2N->GetHists()->At(3))->Write(); + // (TH2F*)(hs2N->GetHists()->At(4))->Write(); + + + fout->Close(); + + + +} + + + +void g4() { + + raedNoiseData("cds_g4_low_gain"); + raedNoiseData("cds_g4_sto1_only"); + raedNoiseData("cds_g4_no sto"); + + + +} + +void no_cds() { + + raedNoiseData("cds_disable_low_gain",-1); + raedNoiseData("cds_disable_sto1_only",-1); + raedNoiseData("cds_disable_no sto",-1); + + + +} + +void all_gains() { + + raedNoiseData("cds_g2"); + raedNoiseData("cds_g2HC"); + raedNoiseData("cds_g1_2"); + raedNoiseData("cds_g2_3"); + + + +} + +void all_low_gains() { + + raedNoiseData("cds_g2_low_gain"); + raedNoiseData("cds_g2HC_low_gain"); + raedNoiseData("cds_g1_2_low_gain"); + raedNoiseData("cds_g2_3_low_gain"); +} + +/* +clkdivider data +/data/moench_xbox_20140114/MoTarget_45kV_0_8mA_12us_120V_cds_g1_clkdiv17_f000000010000_0.raw +-rw-rw-r-- 1 l_msdetect l_msdetect 51440000 Jan 14 12:40 /data/moench_xbox_20140114/MoTarget_45kV_0_8mA_12us_120V_cds_g1_clkdiv25_f000000010000_0.raw +-rw-rw-r-- 1 l_msdetect l_msdetect 51440000 Jan 14 13:26 /data/moench_xbox_20140114/MoTarget_45kV_0_8mA_12us_120V_cds_g1_clkdiv35_f000000010000_0.raw +-rw-rw-r-- 1 l_msdetect l_msdetect 51440000 Jan 14 14:09 /data/moench_xbox_20140114/MoTarget_45kV_0_8mA_12us_120V_cds_g1_clkdiv50_f000000010000_0.raw +-rw-rw-r-- 1 l_msdetect l_msdetect 51440000 Jan 14 14:54 /data/moench_xbox_20140114/MoTarget_45kV_0_8mA_12us_120V_cds_g1_clkdiv70_f000000010000_0.raw +-rw-rw-r-- 1 l_msdetect l_msdetect 51440000 Jan 14 16:42 /data/moench_xbox_20140114/MoTarget_45kV_0_8mA_12us_120V_cds_g1_clkdiv110_f000000010000_0.raw +-rw-rw-r-- 1 l_msdetect l_msdetect 51440000 Jan 14 17:27 /data/moench_xbox_20140114/MoTarget_45kV_0_8mA_12us_120V_cds_g1_clkdiv170_f000000010000_0.raw +*/ + + +/* oversampled data +-rw-rw-r-- 1 l_msdetect l_msdetect 51440000 Jan 14 18:12 /data/moench_xbox_20140114/MoTarget_45kV_0_8mA_12us_120V_os10_16rows_f000000010000_0.raw +-rw-rw-r-- 1 l_msdetect l_msdetect 51440000 Jan 14 18:47 /data/moench_xbox_20140114/MoTarget_45kV_0_8mA_12us_120V_os10_16rows_f000000010000_1.raw +-rw-rw-r-- 1 l_msdetect l_msdetect 51440000 Jan 14 19:22 /data/moench_xbox_20140114/MoTarget_45kV_0_8mA_12us_120V_os10_16rows_f000000010000_2.raw +-rw-rw-r-- 1 l_msdetect l_msdetect 51440000 Jan 14 20:02 /data/moench_xbox_20140114/MoTarget_45kV_0_8mA_12us_120V_os10_16rows_f000000010000_3.raw +-rw-rw-r-- 1 l_msdetect l_msdetect 51440000 Jan 14 20:41 /data/moench_xbox_20140114/MoTarget_45kV_0_8mA_12us_120V_os10_16rows_f000000010000_4.raw +-rw-rw-r-- 1 l_msdetect l_msdetect 51440000 Jan 14 21:16 /data/moench_xbox_20140114/MoTarget_45kV_0_8mA_12us_120V_os10_16rows_f000000010000_5.raw +-rw-rw-r-- 1 l_msdetect l_msdetect 51440000 Jan 14 21:56 /data/moench_xbox_20140114/MoTarget_45kV_0_8mA_12us_120V_os10_16rows_f000000010000_6.raw +-rw-rw-r-- 1 l_msdetect l_msdetect 51440000 Jan 14 22:35 /data/moench_xbox_20140114/MoTarget_45kV_0_8mA_12us_120V_os10_16rows_f000000010000_7.raw +-rw-rw-r-- 1 l_msdetect l_msdetect 51440000 Jan 14 23:11 /data/moench_xbox_20140114/MoTarget_45kV_0_8mA_12us_120V_os10_16rows_f000000010000_8.raw +-rw-rw-r-- 1 l_msdetect l_msdetect 51440000 Jan 14 23:50 /data/moench_xbox_20140114/MoTarget_45kV_0_8mA_12us_120V_os10_16rows_f000000010000_9.raw +*/ + diff --git a/slsReceiverSoftware/slsDetectorCalibration/readJungfrauData.C b/slsReceiverSoftware/slsDetectorCalibration/readJungfrauData.C new file mode 100644 index 000000000..504a15258 --- /dev/null +++ b/slsReceiverSoftware/slsDetectorCalibration/readJungfrauData.C @@ -0,0 +1,31 @@ +{ // script to run Jungfrau data analysis + + gROOT->ProcessLine(".L jungfrauReadData.C++");//"); + + TFile *fout; // output file + THStack *hs2N; // collection of objects + + //fout=new TFile("/mnt/slitnas/datadir_jungfrau02/analysis_tests/tests_random.root","RECREATE"); // + fout=new TFile("/mnt/slitnas/datadir_jungfrau02/20140404_lowEXrays/test.root","RECREATE"); + + hs2N=jungfrauReadData("/mnt/slitnas/datadir_jungfrau02/20140404_lowEXrays/Ti_1000clk_13kV40mA_%d.bin","tit",0,86,3000,-499.5,2500.5,1,0,1,47,1,47,1,1); //1,1); + + //hs2N=jungfrauReadData("/mnt/slitnas/datadir_jungfrau02/20140228_GainBits/GSdata_laser_%d.bin","tit",0,5,1500,-500,2500,1,0.,1,47,1,47,0,1);//,"/mnt/slitnas/datadir_jungfrau02/analysis_tests/CalibrationParametersTest_fake.txt"); //1,1); // data set test GB -> set (3,0,0) in junfrauReadData.C + + //hs2N=jungfrauReadData("/mnt/slitnas/datadir_jungfrau02/digital_bit_adc_test/vb_1825_%d.bin","tit",0,7,1500,-500,2500,1,0.,1,47,1,47,0,1);//,"/mnt/slitnas/datadir_jungfrau02/analysis_tests/CalibrationParametersTest_fake.txt"); //1,1); // data set test GB -> set (3,0,0) in junfrauReadData.C + + //hs2N->SetName("cds_g4"); + //hs2N->SetTitle("cds_g4"); + + (TH2F*)(hs2N->GetHists()->At(0))->Write(); // write hists + (TH2F*)(hs2N->GetHists()->At(1))->Write(); + (TH2F*)(hs2N->GetHists()->At(2))->Write(); + (TH2F*)(hs2N->GetHists()->At(3))->Write(); + (TH2F*)(hs2N->GetHists()->At(4))->Write(); + //(TH2F*)(hs2N->GetHists()->At(5))->Write(); + //(TH2F*)(hs2N->GetHists()->At(6))->Write(); + + fout->Close(); // uncomment + +} + diff --git a/slsReceiverSoftware/slsDetectorCalibration/singlePhotonDetector.h b/slsReceiverSoftware/slsDetectorCalibration/singlePhotonDetector.h new file mode 100644 index 000000000..f090730a1 --- /dev/null +++ b/slsReceiverSoftware/slsDetectorCalibration/singlePhotonDetector.h @@ -0,0 +1,387 @@ +#ifndef SINGLEPHOTONDETECTOR_H +#define SINGLEPHOTONDETECTOR_H + + +#include "slsDetectorData.h" + +#include "single_photon_hit.h" +#include "pedestalSubtraction.h" +#include "commonModeSubtraction.h" + + +//#define MYROOT1 + +#ifdef MYROOT1 +#include + +#endif + + +#include + +using namespace std; + + + enum eventType { + PEDESTAL=0, + NEIGHBOUR=1, + PHOTON=2, + PHOTON_MAX=3, + NEGATIVE_PEDESTAL=4, + UNDEFINED_EVENT=-1 + }; + + enum quadrant { + TOP_LEFT=0, + TOP_RIGHT=1, + BOTTOM_LEFT=2, + BOTTOM_RIGHT=3, + UNDEFINED_QUADRANT=-1 + }; + + + +template +class singlePhotonDetector { + + /** @short class to perform pedestal subtraction etc. and find single photon clusters for an analog detector */ + + public: + + + /** + + Constructor (no error checking if datasize and offsets are compatible!) + \param d detector data structure to be used + \param csize cluster size (should be an odd number). Defaults to 3 + \param nsigma number of rms to discriminate from the noise. Defaults to 5 + \param sign 1 if photons are positive, -1 if negative + \param cm common mode subtraction algorithm, if any. Defaults to NULL i.e. none + \param nped number of samples for pedestal averaging + \param nd number of dark frames to average as pedestals without photon discrimination at the beginning of the measurement + + + */ + + + singlePhotonDetector(slsDetectorData *d, + int csize=3, + double nsigma=5, + int sign=1, + commonModeSubtraction *cm=NULL, + int nped=1000, + int nd=100) : det(d), nx(0), ny(0), stat(NULL), cmSub(cm), nDark(nd), eventMask(NULL),nSigma (nsigma), clusterSize(csize), clusterSizeY(csize), cluster(NULL), iframe(-1), dataSign(sign), quad(UNDEFINED_QUADRANT), tot(0), quadTot(0) { + + + det->getDetectorSize(nx,ny); + + + + stat=new pedestalSubtraction*[ny]; + eventMask=new eventType*[ny]; + for (int i=0; iSetNPedestals(nped); + eventMask[i]=new eventType[nx]; + } + + if (ny==1) + clusterSizeY=1; + + cluster=new single_photon_hit(clusterSize,clusterSizeY); + setClusterSize(csize); + + }; + /** + destructor. Deletes the cluster structure and the pdestalSubtraction array + */ + virtual ~singlePhotonDetector() {delete cluster; for (int i=0; iClear(); }; + + /** resets the eventMask to undefined and the commonModeSubtraction */ + void newFrame(){iframe++; for (int iy=0; iynewFrame();}; + + + /** sets the commonModeSubtraction algorithm to be used + \param cm commonModeSubtraction algorithm to be used (NULL unsets) + \returns pointer to the actual common mode subtraction algorithm + */ + commonModeSubtraction setCommonModeSubtraction(commonModeSubtraction *cm) {cmSub=cm; return cmSub;}; + + + /** + sets the sign of the data + \param sign 1 means positive values for photons, -1 negative, 0 gets + \returns current sign for the data + */ + int setDataSign(int sign=0) {if (sign==1 || sign==-1) dataSign=sign; return dataSign;}; + + + /** + adds value to pedestal (and common mode) for the given pixel + \param val value to be added + \param ix pixel x coordinate + \param iy pixel y coordinate + */ + virtual void addToPedestal(double val, int ix, int iy){ + // cout << "*"<< ix << " " << iy << " " << val << endl; + if (ix>=0 && ix=0 && iyisGood(ix, iy) ) + cmSub->addToCommonMode(val, ix, iy); + }; + }; + + /** + gets pedestal (and common mode) + \param ix pixel x coordinate + \param iy pixel y coordinate + \param cm 0 (default) without common mode subtraction, 1 with common mode subtraction (if defined) + */ + virtual double getPedestal(int ix, int iy, int cm=0){if (ix>=0 && ix=0 && iy0) return stat[iy][ix].getPedestal()-cmSub->getCommonMode(); else return stat[iy][ix].getPedestal(); else return -1;}; + + /** + gets pedestal rms (i.e. noise) + \param ix pixel x coordinate + \param iy pixel y coordinate + */ + double getPedestalRMS(int ix, int iy){if (ix>=0 && ix=0 && iy0) nSigma=n; return nSigma;} + + /** sets/gets cluster size + \param n cluster size to be set, (0 or negative gets). If even is incremented by 1. + \returns actual cluster size + */ + int setClusterSize(int n=-1){ + if (n>0 && n!=clusterSize) { + if (n%2==0) + n+=1; + clusterSize=n; + if (cluster) + delete cluster; + if (ny>1) + clusterSizeY=clusterSize; + cluster=new single_photon_hit(clusterSize,clusterSizeY); + } + return clusterSize; + } + + + + + /** finds event type for pixel and fills cluster structure. The algorithm loops only if the evenMask for this pixel is still undefined. + if pixel or cluster around it are above threshold (nsigma*pedestalRMS) cluster is filled and pixel mask is PHOTON_MAX (if maximum in cluster) or NEIGHBOUR; If PHOTON_MAX, the elements of the cluster are also set as NEIGHBOURs in order to speed up the looping + if below threshold the pixel is either marked as PEDESTAL (and added to the pedestal calculator) or NEGATIVE_PEDESTAL is case it's lower than -threshold, otherwise the pedestal average would drift to negative values while it should be 0. + + /param data pointer to the data + /param ix pixel x coordinate + /param iy pixel y coordinate + /param cm enable(1)/disable(0) common mode subtraction (if defined). + /returns event type for the given pixel + */ + eventType getEventType(char *data, int ix, int iy, int cm=0) { + + // eventType ret=PEDESTAL; + double max=0, tl=0, tr=0, bl=0,br=0, v; + // cout << iframe << endl; + + tot=0; + quadTot=0; + quad=UNDEFINED_QUADRANT; + + + if (iframex=ix; + cluster->y=iy; + cluster->rms=getPedestalRMS(ix,iy); + cluster->ped=getPedestal(ix,iy, cm); + + + for (int ir=-(clusterSizeY/2); ir<(clusterSizeY/2)+1; ir++) { + for (int ic=-(clusterSize/2); ic<(clusterSize/2)+1; ic++) { + if ((iy+ir)>=0 && (iy+ir)=0 && (ix+ic)set_data(dataSign*(det->getValue(data, ix+ic, iy+ir)-getPedestal(ix+ic,iy+ir,cm)), ic, ir ); + v=cluster->get_data(ic,ir); + tot+=v; + if (ir<=0 && ic<=0) + bl+=v; + if (ir<=0 && ic>=0) + br+=v; + if (ir>=0 && ic<=0) + tl+=v; + if (ir>=0 && ic>=0) + tr+=v; + + if (cluster->get_data(ic,ir)>max) { + max=v; + } + if (ir==0 && ic==0) { + if (v>nSigma*cluster->rms) { + eventMask[iy][ix]=PHOTON; + } else if (cluster->get_data(ic,ir)<-nSigma*cluster->rms) + eventMask[iy][ix]=NEGATIVE_PEDESTAL; + } + } + } + } + + if (eventMask[iy][ix]!=PHOTON && tot>sqrt(clusterSizeY*clusterSize)*nSigma*cluster->rms) { + eventMask[iy][ix]=NEIGHBOUR; + } else if (eventMask[iy][ix]==PHOTON) { + if (cluster->get_data(0,0)>=max) { + eventMask[iy][ix]=PHOTON_MAX; + } + } else if (eventMask[iy][ix]==PEDESTAL) { + if (cm==0) + addToPedestal(det->getValue(data, ix, iy),ix,iy); + } + + + if (bl>=br && bl>=tl && bl>=tr) { + quad=BOTTOM_LEFT; + quadTot=bl; + } else if (br>=bl && br>=tl && br>=tr) { + quad=BOTTOM_RIGHT; + quadTot=br; + } else if (tl>=br && tl>=bl && tl>=tr) { + quad=TOP_LEFT; + quadTot=tl; + } else if (tr>=bl && tr>=tl && tr>=br) { + quad=TOP_RIGHT; + quadTot=tr; + } + + + return eventMask[iy][ix]; + + }; + + /**< + retrurns the total signal in a cluster + \param size cluser size should be 1,2 or 3 + \returns cluster center if size=1, sum of the maximum quadrant if size=2, total of the cluster if size=3 or anything else + */ + + double getClusterTotal(int size) { + switch (size) { + case 1: + return getClusterElement(0,0); + case 2: + return quadTot; + default: + return tot; + }; + }; + + /**< + retrurns the quadrant with maximum signal + \returns quadrant where the cluster is located */ + + quadrant getQuadrant() {return quad;}; + + /** sets/gets number of samples for moving average pedestal calculation + \param i number of samples to be set (0 or negative gets) + \returns actual number of samples + */ + int SetNPedestals(int i=-1) {int ix=0, iy=0; if (i>0) for (ix=0; ixget_data(ic,ir);}; + + /** returns event mask for the given pixel + \param ic x coordinate (center is (0,0)) + \param ir y coordinate (center is (0,0)) + \returns event mask enum for the given pixel + */ + eventType getEventMask(int ic, int ir=0){return eventMask[ir][ic];}; + + +#ifdef MYROOT1 + /** generates a tree and maps the branches + \param tname name for the tree + \param iFrame pointer to the frame number + \returns returns pointer to the TTree + */ + TTree *initEventTree(char *tname, int *iFrame=NULL) { + TTree* tall=new TTree(tname,tname); + + if (iFrame) + tall->Branch("iFrame",iFrame,"iframe/I"); + else + tall->Branch("iFrame",&(cluster->iframe),"iframe/I"); + + tall->Branch("x",&(cluster->x),"x/I"); + tall->Branch("y",&(cluster->y),"y/I"); + char tit[100]; + sprintf(tit,"data[%d]/D",clusterSize*clusterSizeY); + tall->Branch("data",cluster->data,tit); + tall->Branch("pedestal",&(cluster->ped),"pedestal/D"); + tall->Branch("rms",&(cluster->rms),"rms/D"); + return tall; + }; +#else + /** write cluster to filer*/ + void writeCluster(FILE* myFile){cluster->write(myFile);}; + +#endif + + + private: + + slsDetectorData *det; /**< slsDetectorData to be used */ + int nx; /**< Size of the detector in x direction */ + int ny; /**< Size of the detector in y direction */ + + + pedestalSubtraction **stat; /**< pedestalSubtraction class */ + commonModeSubtraction *cmSub;/**< commonModeSubtraction class */ + int nDark; /**< number of frames to be used at the beginning of the dataset to calculate pedestal without applying photon discrimination */ + eventType **eventMask; /**< matrix of event type or each pixel */ + double nSigma; /**< number of sigma parameter for photon discrimination */ + int clusterSize; /**< cluster size in the x direction */ + int clusterSizeY; /**< cluster size in the y direction i.e. 1 for strips, clusterSize for pixels */ + single_photon_hit *cluster; /**< single photon hit data structure */ + int iframe; /**< frame number (not from file but incremented within the dataset every time newFrame is called */ + int dataSign; /**< sign of the data i.e. 1 if photon is positive, -1 if negative */ + quadrant quad; /**< quadrant where the photon is located */ + double tot; /**< sum of the 3x3 cluster */ + double quadTot; /**< sum of the maximum 2x2cluster */ + + +}; + + + + + +#endif diff --git a/slsReceiverSoftware/slsDetectorCalibration/single_photon_hit.h b/slsReceiverSoftware/slsDetectorCalibration/single_photon_hit.h new file mode 100644 index 000000000..dda4d7571 --- /dev/null +++ b/slsReceiverSoftware/slsDetectorCalibration/single_photon_hit.h @@ -0,0 +1,62 @@ +#ifndef SINGLE_PHOTON_HIT_H +#define SINGLE_PHOTON_HIT_h + +typedef double double32_t; +typedef float float32_t; +typedef int int32_t; + + +class single_photon_hit { + + /** @short Structure for a single photon hit */ + + public: + /** constructor, instantiates the data array -- all class elements are public! + \param nx cluster size in x direction + \param ny cluster size in y direction (defaults to 1 for 1D detectors) + */ + single_photon_hit(int nx, int ny=1): dx(nx), dy(ny) {data=new double[dx*dy];}; + + ~single_photon_hit(){delete [] data;}; /**< destructor, deletes the data array */ + + /** binary write to file of all elements of the structure, except size of the cluster + \param myFile file descriptor + */ + void write(FILE *myFile) {fwrite((void*)this, 1, 3*sizeof(int)+2*sizeof(double), myFile); fwrite((void*)data, 1, dx*dy*sizeof(double), myFile);}; + + /** + binary read from file of all elements of the structure, except size of the cluster. The structure is then filled with those args + \param myFile file descriptor + */ + void read(FILE *myFile) {fread((void*)this, 1, 3*sizeof(int)+2*sizeof(double), myFile); fread((void*)data, 1, dx*dy*sizeof(double), myFile);}; + + /** + assign the value to the element of the cluster matrix, with relative coordinates where the center of the cluster is (0,0) + \param v value to be set + \param ix coordinate x within the cluster (center is (0,0)) + \param iy coordinate y within the cluster (center is (0,0)) + */ + void set_data(double v, int ix, int iy=0){data[(iy+dy/2)*dx+ix+dx/2]=v;}; + + + /** + gets the value to the element of the cluster matrix, with relative coordinates where the center of the cluster is (0,0) + \param ix coordinate x within the cluster (center is (0,0)) + \param iy coordinate y within the cluster (center is (0,0)) + \returns value of the cluster element + */ + double get_data(int ix, int iy=0){return data[(iy+dy/2)*dx+ix+dx/2];}; + + int x; /**< x-coordinate of the center of hit */ + int y; /**< x-coordinate of the center of hit */ + double rms; /**< noise of central pixel l -- at some point it can be removed*/ + double ped; /**< pedestal of the central pixel -- at some point it can be removed*/ + int iframe; /**< frame number */ + double *data; /**< pointer to data */ + const int dx; /**< size of data cluster in x */ + const int dy; /**< size of data cluster in y */ +}; + + + +#endif diff --git a/slsReceiverSoftware/slsDetectorCalibration/slsDetectorData.h b/slsReceiverSoftware/slsDetectorCalibration/slsDetectorData.h new file mode 100644 index 000000000..294f7c871 --- /dev/null +++ b/slsReceiverSoftware/slsDetectorCalibration/slsDetectorData.h @@ -0,0 +1,251 @@ +#ifndef SLSDETECTORDATA_H +#define SLSDETECTORDATA_H + +#include +#include +#include + +using namespace std; + + +template +class slsDetectorData { + + + public: + + /** + + + General slsDetectors data structure. Works for data acquired using the slsDetectorReceiver. Can be generalized to other detectors (many virtual funcs). + + Constructor (no error checking if datasize and offsets are compatible!) + \param npx number of pixels in the x direction + \param npy number of pixels in the y direction (1 for strips) + \param dsize size of the data + \param dMap array of size nx*ny storing the pointers to the data in the dataset (as offset) + \param dMask Array of size nx*ny storing the polarity of the data in the dataset (should be 0 if no inversion is required, 0xffffffff is inversion is required) + \param dROI Array of size nx*ny. The elements are 1s if the channel is good or in the ROI, 0 is bad or out of the ROI. NULL (default) means all 1s. + + */ + slsDetectorData(int npx, int npy, int dsize, int **dMap=NULL, dataType **dMask=NULL, int **dROI=NULL): nx(npx), ny(npy), dataSize(dsize) { + + + + dataMask=new dataType*[ny]; + for(int i = 0; i < ny; i++) { + dataMask[i] = new dataType[nx]; + } + dataMap=new int*[ny]; + for(int i = 0; i < ny; i++) { + dataMap[i] = new int[nx]; + } + + dataROIMask=new int*[ny]; + for(int i = 0; i < ny; i++) { + dataROIMask[i] = new int[nx]; + for (int j=0; j=0 && ix=0 && iy=0 && ix=0 && iy=0 && ix=0 && iy=0 && dataMap[iy][ix] +class slsReceiverData : public slsDetectorData { + + +public: + + /** + slsReceiver data structure. Works for data acquired using the slsDetectorReceiver subdivided in different packets with headers and footers. + Inherits and implements slsDetectorData. + + Constructor (no error checking if datasize and offsets are compatible!) + \param npx number of pixels in the x direction + \param npy number of pixels in the y direction (1 for strips) + \param np number of packets + \param psize packets size + \param dMap array of size nx*ny storing the pointers to the data in the dataset (as offset) + \param dMask Array of size nx*ny storing the polarity of the data in the dataset (should be 0 if no inversion is required, 0xffffffff is inversion is required) + \param dROI Array of size nx*ny. The elements are 1s if the channel is good or in the ROI, 0 is bad or out of the ROI. NULL (default) means all 1s. + + */ + slsReceiverData(int npx, int npy, int np, int psize, int **dMap=NULL, dataType **dMask=NULL, int **dROI=NULL): slsDetectorData(npx, npy, np*psize, dMap, dMask, dROI), nPackets(np), packetSize(psize) {}; + + + /** + + Returns the frame number for the given dataset. Virtual func: works for slsDetectorReceiver data (also for each packet), but can be overloaded. + \param buff pointer to the dataset + \returns frame number + + */ + + virtual int getFrameNumber(char *buff){return ((*(int*)buff)&(0xffffff00))>>8;}; + + /** + + Returns the packet number for the given dataset. Virtual func: works for slsDetectorReceiver packets, but can be overloaded. + \param buff pointer to the dataset + \returns packet number number + + */ + + virtual int getPacketNumber(char *buff){return (*(int*)buff)&0xff;}; + + + + + /** + + Loops over a memory slot until a complete frame is found (i.e. all packets 0 to nPackets, same frame number). Can be overloaded for different kind of detectors! + \param data pointer to the memory to be analyzed + \param ndata size of frame returned + \param dsize size of the memory slot to be analyzed + \returns pointer to the first packet of the last good frame (might be incomplete if npackets lower than the number of packets), or NULL if no frame is found + + */ + + virtual char *findNextFrame(char *data, int &ndata, int dsize) { + char *retval=NULL, *p=data; + int dd=0; + int fn, fnum=-1, np=0, pnum=-1; + while (dd<=(dsize-packetSize)) { + pnum=getPacketNumber(p); + fn=getFrameNumber(p); + + + if (pnum<1 || pnum>nPackets) { + cout << "Bad packet number " << pnum << " frame "<< fn << endl; + retval=NULL; + np=0; + } else if (pnum==1) { + retval=p; + if (np>0) + /*cout << "*Incomplete frame number " << fnum << endl;*/ + np=0; + fnum=fn; + } else if (fn!=fnum) { + if (fnum!=-1) { + /* cout << " **Incomplete frame number " << fnum << " pnum " << pnum << " " << getFrameNumber(p) << endl;*/ + retval=NULL; + } + np=0; + } + p+=packetSize; + dd+=packetSize; + np++; + // cout << pnum << " " << fn << " " << np << " " << dd << " " << dsize << endl; + if (np==nPackets) + if (pnum==nPackets) { + // cout << "Frame found!" << endl; + break; + } else { + cout << "Too many packets for this frame! "<< fnum << " " << pnum << endl; + retval=NULL; + } + } + if (np0) + cout << "Too few packets for this frame! "<< fnum << " " << pnum << endl; + } + + ndata=np*packetSize; + // cout << "return " << ndata << endl; + return retval; + }; + + /** + + Loops over a file stream until a complete frame is found (i.e. all packets 0 to nPackets, same frame number). Can be overloaded for different kind of detectors! + \param filebin input file stream (binary) + \returns pointer to the first packet of the last good frame, NULL if no frame is found or last frame is incomplete + + */ + + virtual char *readNextFrame(ifstream &filebin) { + char *data=new char[packetSize*nPackets]; + char *retval=0; + int np=0, nd; + + if (filebin.is_open()) { + while (filebin.read(data+np*packetSize,packetSize)) { + + if (np==(nPackets-1)) { + + retval=findNextFrame(data,nd,packetSize*nPackets); + np=nd/packetSize; + // cout << np << endl; + + + if (retval==data && np==nPackets) { + // cout << "-" << endl; + return data; + + } else if (np>nPackets) { + cout << "too many packets!!!!!!!!!!" << endl; + delete [] data; + return NULL; + } else if (retval!=NULL) { + // cout << "+" << endl;; + for (int ip=0; ipnPackets) { + cout << "*******too many packets!!!!!!!!!!" << endl; + delete [] data; + return NULL; + } else { + // cout << "." << endl;; + np++; + } + } + } + delete [] data; + return NULL; + }; + + + +private: + const int nPackets; /** + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/slsReceiverSoftware/slsReceiver/.project b/slsReceiverSoftware/slsReceiver/.project new file mode 100644 index 000000000..3c7b96561 --- /dev/null +++ b/slsReceiverSoftware/slsReceiver/.project @@ -0,0 +1,28 @@ + + + Receiver + + + newMythenSoftware + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.core.ccnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + diff --git a/slsReceiverSoftware/slsReceiver/Makefile b/slsReceiverSoftware/slsReceiver/Makefile new file mode 100644 index 000000000..0fd416ca0 --- /dev/null +++ b/slsReceiverSoftware/slsReceiver/Makefile @@ -0,0 +1,68 @@ +include ../../Makefile.include + +DESTDIR ?= ../../bin +LIBDIR ?= $(DESTDIR) +PROGS = $(DESTDIR)/slsReceiver + + +CFLAGS += -DSLS_RECEIVER_UDP_FUNCTIONS -O3 +CPPFLAGS = ${CFLAGS} # for MAC + + +LDFLAGRXR ?= -L$(LIBDIR) -lSlsReceiver -L/usr/lib64/ -lpthread +LDFLAGRXR += -lm -lstdc++ + + +INCLUDES ?= -I ../MySocketTCP -I ../slsDetectorCalibration -I ../includes -I eigerReceiver -I . +SRC_CLNT = slsReceiver.cpp + + +INSTMODE = 0777 +OBJS = $(SRC_CLNT:.cpp=.o) + + +.PHONY: all receiver clean static_receiver boot eigerReceiver lib + +all: receiver + +receiver: $(DESTDIR)/slsReceiver + +static_receiver: $(DESTDIR)/sslsReceiver + +boot: $(OBJS) + +$(DESTDIR)/sslsReceiver: lib + echo $(OBJS) + echo $(LDFLAGRXR) + echo $(LIBS) + mkdir -p $(DESTDIR) + $(CXX) -static -o $@ $(SRC_CLNT) $(FLAGS) $(INCLUDES) $(CLAGS) $(LIBS) $(LDFLAGRXR) + + +$(DESTDIR)/slsReceiver: eigerReceiver lib + $(CXX) -o $@ $(SRC_CLNT) $(FLAGS) $(INCLUDES) $(CLAGS) $(LIBS) $(LDFLAGRXR) -fPIC +#$(EIGERFLAGS) + + +ifeq ($(EIGERSLS), yes) +eigerReceiver: + $(CXX) $(FLAGS) $(CFLAGS) -fPIC -c -o eigerReceiverTest.o eigerReceiver/eigerReceiverTest.cpp $(EIGERFLAGS) + $(CXX) $(FLAGS) $(CFLAGS) -fPIC -c -o eigerReceiver.o eigerReceiver/eigerReceiver.cpp $(EIGERFLAGS) + $(CXX) eigerReceiverTest.o eigerReceiver.o -o eigerReceiver/eigerReceiverTest $(EIGERFLAGS) +else ifeq ($(ROOTSLS), yes) +eigerReceiver: eigerReceiver/eigerReceiverDummy.cpp + echo "Compiling with root" + $(CXX) $(FLAGS) $(CFLAGS) -fPIC -c -o eigerReceiver.o eigerReceiver/eeigerReceiverDummy.cpp $(ROOTFLAGS) +else +eigerReceiver: eigerReceiver/eigerReceiverDummy.cpp + $(CXX) $(FLAGS) $(CFLAGS) $(INCLUDES) -fPIC -c -o eigerReceiver.o eigerReceiver/eigerReceiverDummy.cpp +endif + +lib: + cd ../ && $(MAKE) DESTDIR=../bin LIBDIR=../bin + +clean: + rm -rf $(PROGS) *.o eigerReceiverTest $(DESTDIR)/libSlsReceiver.a $(DESTDIR)/libSlsReceiver.so core + + + diff --git a/slsReceiverSoftware/slsReceiver/eigerReceiver/RestHelper.h b/slsReceiverSoftware/slsReceiver/eigerReceiver/RestHelper.h new file mode 100644 index 000000000..6f423f5e1 --- /dev/null +++ b/slsReceiverSoftware/slsReceiver/eigerReceiver/RestHelper.h @@ -0,0 +1,195 @@ +/** + * @file RestHelper.h + * @author Leonardo Sala + * @date Tue Mar 25 09:28:19 2014 + * + * @brief + * + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "JsonBox/Value.h" + +#include +#include +#include + +/// HTTP timeout in seconds, default is 8 +#define HTTP_TIMEOUT 10 +/// Number of connection tries +#define N_CONNECTION_TRIES 3 + +using namespace Poco::Net; +using namespace Poco; +using namespace std; + +class RestHelper { + public: + + ~RestHelper(){}; + + void init(string hostname, int port){ + /** Initialize the RestHelper. Hostname and port parameters are not supposed to change. + * + * + * @param hostname FQDN of the host to connect to , e.g. www.iamfake.org, or sodoi.org + * @param port + * + * @return + */ + + full_hostname = "http://"+hostname; + session = new HTTPClientSession(hostname,port ); + session->setKeepAliveTimeout( Timespan( HTTP_TIMEOUT,0) ); + }; + + + int get_json(string request, string* answer){ + /** Retrieves a reply from the RESTful webservice. + * + * + * @param request Request without the hostname, e.g. if the full request would have been http://fake.org/fakemethod, request=fakemethod + * @param answer + * + * @return 0 if successful, -1 if failure happens. + */ + URI * uri = new URI(full_hostname+"/"+request); + string path(uri->getPathAndQuery()); + if (path.empty()) path = "/"; + + // send request + HTTPRequest req(HTTPRequest::HTTP_GET, path, HTTPMessage::HTTP_1_1); + req.setContentType("application/json\r\n"); + int code = send_request(session, req, answer); + delete uri; + return code; + }; + + + int get_json(string request, JsonBox::Value* json_value){ + /** + * + * + * @param request + * @param json_value + * + * @return + */ + URI *uri = new URI(full_hostname+"/"+request); + string path(uri->getPathAndQuery()); + if (path.empty()) path = "/"; + // send request + HTTPRequest req(HTTPRequest::HTTP_GET, path, HTTPMessage::HTTP_1_1); + req.setContentType("application/json\r\n"); + string answer; + int code = send_request(session, req, &answer); + json_value->loadFromString(answer); + delete uri; + return code; + }; + + + int post_json(string request, string *answer, string request_body=""){ + /** + * + * + * @param request + * @param answer + * @param request_body Eventual arguments to the URL, e.g. action=login&name=mammamia + * + * @return + */ + //from: http://stackoverflow.com/questions/1499086/poco-c-net-ssl-how-to-post-https-request + URI *uri = new URI(full_hostname+"/"+request); + string path(uri->getPathAndQuery()); + if (path.empty()) path = "/"; + HTTPRequest req(HTTPRequest::HTTP_POST, path, HTTPMessage::HTTP_1_1 ); + req.setContentType("application/json\r\n"); + req.setContentLength( request.length() ); + int code = send_request(session, req, answer, request_body); + delete uri; + return code; + } + + + int post_json(string request, JsonBox::Value* json_value, string request_body=""){ + /** + * + * + * @param request + * @param json_value + * @param request_body Eventual arguments to the URL, e.g. action=login&name=mammamia + * + * @return + */ + + URI *uri = new URI(full_hostname+"/"+request); + string path(uri->getPathAndQuery()); + if (path.empty()) path = "/"; + HTTPRequest req(HTTPRequest::HTTP_POST, path, HTTPMessage::HTTP_1_1 ); + req.setContentType("application/json\r\n"); + req.setContentLength( request.length() ); + string answer; + int code = send_request(session, req, &answer, request_body); + json_value->loadFromString(answer); + delete uri; + return code; + } + + + private: + //URI * uri; + HTTPClientSession *session; + string full_hostname; + + int send_request(HTTPClientSession *session, HTTPRequest &req, string *answer, string request_body=""){ + /** + * + * + * @param session + * @param req + * @param answer + * @param request_body + * + * @return + */ + + int n=0; + int code = -1; + while(nsendRequest( (req) ); + else + session->sendRequest( (req) ) << request_body; + + HTTPResponse res; + istream &is = session->receiveResponse(res); + StreamCopier::copyToString(is, *answer); + code = res.getStatus(); + if (code != 200){ + cout << "HTTP ERROR " << res.getStatus() << ": " << res.getReason() << endl; + code = -1; + } + return code; + } + catch (exception& e){ + cout << "Exception connecting to "<< full_hostname << ": "<< e.what() << ", sleeping " << HTTP_TIMEOUT << " seconds\n"; + sleep(HTTP_TIMEOUT); + } + n+=1; + } + + return code; + } + +}; diff --git a/slsReceiverSoftware/slsReceiver/eigerReceiver/eigerReceiver.cpp b/slsReceiverSoftware/slsReceiver/eigerReceiver/eigerReceiver.cpp new file mode 100644 index 000000000..fa19895be --- /dev/null +++ b/slsReceiverSoftware/slsReceiver/eigerReceiver/eigerReceiver.cpp @@ -0,0 +1,254 @@ +/* + * eigerReceiver.cpp + * + * Created on: Mar 11, 2014 + * Author: billich + */ + +#include +#include +#include "eigerReceiver.h" + + +/* uncomment next line to enable debug output */ +#define EIGER_DEBUG + +/* macro for debug output http://stackoverflow.com/a/14256296 */ +#ifdef EIGER_DEBUG +#define DEBUG(x) do { std::cerr << x << std::endl; } while (0) +#else +#define DEBUG(x) +#endif + + +using namespace std; + +struct EigerReceiverInitializationConfiguration { + + string detectorHostname; +}; + +struct EigerReceiverScanConfiguration { + + string fileName; + string filePath; + int dynamicRange; + int scanTag; + int numberOfFrames; + bool doFileWrite; + bool doFileOverWrite; + + EigerReceiverScanConfiguration(): + dynamicRange(-1), + scanTag(-1), + numberOfFrames(-1), + doFileWrite(false), + doFileOverWrite(false){}; +}; + +class EigerReceiverImplementation: public EigerReceiver { + +public: + + EigerReceiverImplementation() : isInitialized(false), status(slsReceiverDefs::ERROR) {}; + + void initialize(const char *detectorHostname) { + + string name; + if (detectorHostname != NULL) { + name = detectorHostname; + } + + if (name.empty()) { + DEBUG("initialize(): can't initialize with empty string or NULL for detectorHostname"); + } else if (isInitialized == true) { + DEBUG("initialize(): already initialized, can't initialize several times"); + } else { + DEBUG("initialize(): initialize() with: detectorHostName=" << name << "."); + init_config.detectorHostname = name; + isInitialized = true; + status = slsReceiverDefs::IDLE; + } + +#ifdef SALA + //REST call - hardcoded + RestHelper rest ; + rest.init("localhost",8080); + std::string answer; + std::cout << "---- REST test 1: true, string "<< std::endl; + int code = rest.get_json("status", &answer); + std::cout << "Answer: " << answer << std::endl; + + std::cout << "---- REST test 2: 404, string "<< std::endl; + code = rest.get_json("statuss", &answer); + if (code != 0){ + //throw -1; + std::cout << "I SHOULD THROW AN EXCEPTION!!!" << std::endl; + } + + std::cout << "---- REST test 3: true, json object "<< std::endl; + JsonBox::Value json_value; + code = rest.get_json("status", &json_value); + std::cout << "JSON " << json_value["status"] << std::endl; + + answer = ""; + std::cout << "---- REST test 4: POST, string "<< std::endl; + code = rest.post_json("recipes/cassoela", &answer); + std::cout << "POST answer: " << answer << std::endl; + if (code != 0){ + //throw -1; + std::cout << "I SHOULD THROW AN EXCEPTION!!!" << std::endl; + } + + RestHelper rest2 ; + rest2.init("reallyfake",8080); + std::cout << "---- REST test 4: host not found, json object "<< std::endl; + JsonBox::Value json_value2; + code = rest2.get_json("status", &json_value2); + if (code != 0){ + //throw -1; + std::cout << "I SHOULD THROW AN EXCEPTION!!!" << std::endl; + } + +#endif + } + + + char *getDetectorHostname() const { + string name = init_config.detectorHostname; + if (name.empty()) { + DEBUG("getDetectorHostname(): Return NULL"); + return(NULL); + } + char *c = new char[name.length()+1]; + name.copy(c, name.length()); + c[name.length()] = '\0'; + DEBUG("getDetectorHostname(): Return " << c << "."); + return(c); + } + + char *getFileName() const { + string name = scan_config.fileName; + + char *c = new char[name.length()+1]; + name.copy(c, name.length()); + c[name.length()] = '\0'; + DEBUG("getFileName(): Return " << c); + return(c); + } + + char *getFilePath() const { + string name = scan_config.filePath; + + char *c = new char[name.length()+1]; + name.copy(c, name.length()); + c[name.length()] = '\0'; + DEBUG("getFilePath(): Return " << c); + return(c); + } + + int getDynamicRange() const { + DEBUG("getDynamicRange(): Return " << scan_config.dynamicRange); + return(scan_config.dynamicRange); + } + + int getScanTag() const { + DEBUG("getScanTag(): returns " << scan_config.scanTag); + return(scan_config.scanTag); + } + + int getNumberOfFrames() const { + DEBUG("getNumberOfFrames(): return " << scan_config.numberOfFrames); + return(scan_config.numberOfFrames); + } + + int getEnableFileWrite() const { + DEBUG("getEnableFileWrite() returns " << scan_config.doFileWrite); + return(scan_config.doFileWrite); + } + + int getEnableOverwrite() const { + DEBUG("getEnableOverwrite() returns " << scan_config.doFileOverWrite); + return(scan_config.doFileOverWrite); + } + + slsReceiverDefs::runStatus getStatus() const { + DEBUG("getStatus(): return " <getFileName()); + } + + char *setFilePath(const char c[]) { + DEBUG("setFilePath() called with " << c << "."); + scan_config.filePath = c; + return(this->getFilePath()); + } + + int setDynamicRange (const int dr) { + DEBUG("setDynamicRange() called with " << dr << '.'); + scan_config.dynamicRange = dr; + return(getDynamicRange()); + } + + int setScanTag (const int tag) { + DEBUG("setScanTag() called with " << tag); + scan_config.scanTag = tag; + return(getScanTag()); + } + + int setNumberOfFrames (const int fnum) { + DEBUG("setNumberOfFrames() called with " << fnum); + scan_config.numberOfFrames = fnum; + return(getNumberOfFrames()); + } + + int setEnableFileWrite(const int i) { + DEBUG("enableFileWrite() called with " << i); + scan_config.doFileWrite = i; + return(getEnableFileWrite()); + } + + int setEnableOverwrite(const int i) { + DEBUG("setEnableOverwrite() called with " << i); + scan_config.doFileOverWrite = i; + return(getEnableOverwrite()); + } + + int startReceiver(char message[]) { + DEBUG("startReceiver(): return 0."); + status = slsReceiverDefs::RUNNING; + message = NULL; + return(0); + } + + int stopReceiver() { + DEBUG("stopReceiver(): return 0."); + status = slsReceiverDefs::IDLE; + return(0); + } + + void abort() { + DEBUG("abort(): return 0."); + status = slsReceiverDefs::IDLE; + } + +private: + EigerReceiverScanConfiguration scan_config; + EigerReceiverInitializationConfiguration init_config; + bool isInitialized; + slsReceiverDefs::runStatus status; +}; + +EigerReceiver *EigerReceiver::create(void) { + DEBUG("create(): Return new EigerReceiverImplementation instance."); + return new EigerReceiverImplementation(); +} + + + + diff --git a/slsReceiverSoftware/slsReceiver/eigerReceiver/eigerReceiver.h b/slsReceiverSoftware/slsReceiver/eigerReceiver/eigerReceiver.h new file mode 100644 index 000000000..9d26b185b --- /dev/null +++ b/slsReceiverSoftware/slsReceiver/eigerReceiver/eigerReceiver.h @@ -0,0 +1,211 @@ +#ifndef EIGERRECEIVER_H +#define EIGERRECEIVER_H +/*********************************************** + * @file eigerReceiver.h + * @short does all the functions for a receiver, set/get parameters, start/stop etc. + ***********************************************/ + +/** + * @short does all the functions for a receiver, set/get parameters, start/stop etc. + */ + +#include "sls_receiver_defs.h" +#ifdef SALA +#include "RestHelper.h" +#endif +class EigerReceiver { + /* abstract class that defines the public interface of an eiger data receiver. + * + * Use the factory method EigerReceiver::create() to get an instance: + * + * EigerReceiver *receiver = EigerReceiver::create() + * + * supported sequence of method-calls: + * + * initialize() : once and only once after create() + * + * get*() : anytime after initialize(), multiples times + * set*() : anytime after initialize(), multiple times + * + * startReceiver(): anytime after initialize(). Will fail if state already is 'running' + * + * abort(), + * stopReceiver() : anytime after initialize(). Will do nothing if state already is idle. + * + * getStatus() returns the actual state of the data receiver - running or idle. All other + * get*() and set*() methods access the local cache of configuration values only and *do not* modify the data receiver settings. + * + * Only startReceiver() does change the data receiver configuration, it does pass the whole configuration cache to the data receiver. + * + * get- and set-methods that return a char array (char *) allocate a new array at each call. The caller is responsible to free the allocated space: + * + * char *c = receiver->getFileName(); + * .... + * delete[] c; + * + * always: 1:YES 0:NO for int as bool-like arguments + * + */ + +public: + + /** + * factory method to create instances + */ + static EigerReceiver *create(); + + /** + * Destructor + */ + virtual ~EigerReceiver() {}; + + /** + * Initialize the Receiver + @param detectorHostName detector hostname + * you can call this function only once. You must call it before you call startReceiver() for the first time. + */ + virtual void initialize(const char *detectorHostName) = 0; + + + /* Returns detector hostname + /returns hostname + * caller needs to deallocate the returned char array. + * if uninitialized, it must return NULL + */ + virtual char *getDetectorHostname() const = 0; + + /** + * Returns status of receiver: idle, running or error + */ + virtual slsReceiverDefs::runStatus getStatus() const = 0; + + /** + * Returns File Name + * caller is responsible to deallocate the returned char array. + */ + virtual char *getFileName() const = 0; + + + /** + * Returns File Path + * caller is responsible to deallocate the returned char array + */ + virtual char *getFilePath() const = 0; //FIXME: Does the caller need to free() the returned pointer? + + + /** + * Returns the number of bits per pixel + */ + virtual int getDynamicRange() const = 0; + + /** + * Returns scan tag + */ + virtual int getScanTag() const = 0; + + /* + * Returns number of frames to receive + * This is the number of frames to expect to receiver from the detector. + * The data receiver will change from running to idle when it got this number of frames + */ + virtual int getNumberOfFrames() const = 0; + + /** + * Returns file write enable + * 1: YES 0: NO + */ + virtual int getEnableFileWrite() const = 0; + + /** + * Returns file over write enable + * 1: YES 0: NO + */ + virtual int getEnableOverwrite() const = 0; + + /** + * Set File Name (without frame index, file index and extension) + @param c file name + /returns file name + * returns NULL on failure (like bad file name) + * does not check the existence of the file - we don't know which path we'll finally use, so no point to check. + * caller is responsible to deallocate the returned char array. + */ + virtual char* setFileName(const char c[]) = 0; + + /** + * Set File Path + @param c file path + /returns file path + * checks the existence of the directory. returns NULL if directory does not exist or is not readable. + * caller is responsible to deallocate the returned char array. + */ + virtual char* setFilePath(const char c[]) = 0; + + /** + * Returns the number of bits per pixel + @param dr sets dynamic range + /returns dynamic range + * returns -1 on failure + * FIXME: what are the allowd values - should we use an enum as argument? + */ + virtual int setDynamicRange(const int dr) = 0; + + + /** + * Set scan tag + @param tag scan tag + /returns scan tag (always non-negative) + * FIXME: valid range - only positive? 16bit ore 32bit? + * returns -1 on failure + */ + virtual int setScanTag(const int tag) = 0; + + /** + * Sets number of frames + @param fnum number of frames + /returns number of frames + */ + virtual int setNumberOfFrames(const int fnum) = 0; + + /** + * Set enable file write + * @param i file write enable + /returns file write enable + */ + virtual int setEnableFileWrite(const int i) = 0; + + /** + * Set enable file overwrite + * @param i file overwrite enable + /returns file overwrite enable + */ + virtual int setEnableOverwrite(const int i) = 0; + + /** + * Starts Receiver - activate all configuration settings to the eiger receiver and start to listen for packets + @param message is the error message if there is an error + /returns 0 on success or -1 on failure + */ + //FIXME: success == 0 or success == 1? + virtual int startReceiver(char message[]) = 0; //FIXME: who allocates message[]? + + /** + * Stops Receiver - stops listening for packets + /returns success + * same as abort(). Always returns 0. + */ + virtual int stopReceiver() = 0; + + /** + * abort acquisition with minimum damage: close open files, cleanup. + * does nothing if state already is 'idle' + */ + virtual void abort() = 0; + +protected: + +private: + +}; + +#endif /* #ifndef EIGERRECEIVER_H */ diff --git a/slsReceiverSoftware/slsReceiver/eigerReceiver/eigerReceiverDummy.cpp b/slsReceiverSoftware/slsReceiver/eigerReceiver/eigerReceiverDummy.cpp new file mode 100644 index 000000000..f45c7517e --- /dev/null +++ b/slsReceiverSoftware/slsReceiver/eigerReceiver/eigerReceiverDummy.cpp @@ -0,0 +1,99 @@ +/* + * eigerReceiver.cpp + * + * Created on: Mar 11, 2014 + * Author: billich + */ + +#include +#include +#include "eigerReceiver.h" + + +using namespace std; + +struct EigerReceiverInitializationConfiguration { + string detectorHostname; +}; + +struct EigerReceiverScanConfiguration { + + string fileName; + string filePath; + int dynamicRange; + int scanTag; + int numberOfFrames; + bool doFileWrite; + bool doFileOverWrite; + + EigerReceiverScanConfiguration(): + dynamicRange(-1), + scanTag(-1), + numberOfFrames(-1), + doFileWrite(false), + doFileOverWrite(false){}; +}; + +class EigerReceiverImplementation: public EigerReceiver { + +public: + + EigerReceiverImplementation(){}; + + ~EigerReceiverImplementation(){}; + + void initialize(const char *detectorHostname) {} + + char *getDetectorHostname() const { return (char*)"";} + + char *getFileName() const {return (char*)"";} + + char *getFilePath() const {return (char*)"";} + + int getDynamicRange() const { return 0;} + + int getScanTag() const {return 0;} + + int getNumberOfFrames() const {return 0;} + + int getEnableFileWrite() const {return 0;} + + int getEnableOverwrite() const {return 0;} + + slsReceiverDefs::runStatus getStatus() const { return slsReceiverDefs::IDLE;} + + char *setFileName(const char c[]) {return (char*)"";} + + char *setFilePath(const char c[]) {return (char*)"";} + + int setDynamicRange (const int dr) {return 0;} + + int setScanTag (const int tag) {return 0;} + + int setNumberOfFrames (const int fnum) {return 0;} + + int setEnableFileWrite(const int i) {return 0;} + + int setEnableOverwrite(const int i) {return 0;} + + int startReceiver(char message[]) {return 0;} + + int stopReceiver() {return 0;} + + void abort() {} + +private: + EigerReceiverScanConfiguration scan_config; + EigerReceiverInitializationConfiguration init_config; + bool isInitialized; + slsReceiverDefs::runStatus status; + +}; + +EigerReceiver *EigerReceiver::create(void) { + return new EigerReceiverImplementation(); +} + + + + diff --git a/slsReceiverSoftware/slsReceiver/eigerReceiver/eigerReceiverTest.cpp b/slsReceiverSoftware/slsReceiver/eigerReceiver/eigerReceiverTest.cpp new file mode 100644 index 000000000..bdfcba7a1 --- /dev/null +++ b/slsReceiverSoftware/slsReceiver/eigerReceiver/eigerReceiverTest.cpp @@ -0,0 +1,97 @@ +/* + * eigerReceiverTest.cpp + + * + * Created on: Mar 11, 2014 + * Author: billich + */ + +#include +#include +#include "eigerReceiver.h" + +using namespace std; + +int main(int argc, char *argv[]){ + + const char *name = "detectors_host_name"; + const char *empty = ""; + std::string prefix = "main: "; + cout <getStatus(); + char *c0 = receiver->getDetectorHostname(); + if (c0 == NULL) { + cout <initialize(empty); + status = receiver->getStatus(); + receiver->initialize(name); + status = receiver->getStatus(); + receiver->initialize(name); + status = receiver->getStatus(); + receiver->initialize((char *)NULL); + + cout << endl; + + status = receiver->getStatus(); + char *c6 = receiver->getDetectorHostname(); + cout <getFileName(); + cout <." << endl; + delete[] c1; + + char *c2 = receiver->getFilePath(); + cout <." << endl; + delete[]c2; + + int range = receiver->getDynamicRange(); + cout <getScanTag(); + cout <setFileName( "some_other_name"); + cout < after setting to " << endl << endl; + delete[] c3; + + char *c4 = receiver->setFilePath( "some_other_path"); + cout < after setting to " << endl << endl; + delete[] c4; + + range = receiver->setDynamicRange(8); + cout <setScanTag(99); + cout << "got scan tag " << tag << " after setting to 99." << endl << endl; + + int n = receiver->setNumberOfFrames(11); + cout << "got number of frames " << n << " after setting to 11." << endl << endl; + + int w = receiver->setEnableFileWrite(1); + cout << "got enable file write " << w << " after setting to 1." << endl << endl; + + char *c5; + status = receiver->getStatus(); + receiver->startReceiver(c5); + status = receiver->getStatus(); + receiver->stopReceiver(); + status = receiver->getStatus(); + receiver->abort(); + status = receiver->getStatus(); + +} + + + + diff --git a/slsReceiverSoftware/slsReceiver/slsReceiver.cpp b/slsReceiverSoftware/slsReceiver/slsReceiver.cpp new file mode 100644 index 000000000..104fafad9 --- /dev/null +++ b/slsReceiverSoftware/slsReceiver/slsReceiver.cpp @@ -0,0 +1,81 @@ +/* A simple server in the internet domain using TCP + The port number is passed as an argument */ + +#include "sls_receiver_defs.h" +#include "slsReceiverUsers.h" + +#include +using namespace std; + + + + + + +int main(int argc, char *argv[]) { + int ret = slsReceiverDefs::OK; + + slsReceiverUsers *user = new slsReceiverUsers(argc, argv, ret); + + if(ret==slsReceiverDefs::FAIL) + return -1; + + + //register callbacks + + + /** + callback arguments are + filepath + filename + fileindex + datasize + + return value is + 0 raw data ready callback takes care of open,close,write file + 1 callback writes file, we have to open, close it + 2 we open, close, write file, callback does not do anything + + + registerCallBackStartAcquisition(int (*func)(char*, char*,int, int, void*),void *arg); + */ + + //receiver->registerCallBackStartAcquisition(func,arg); + + + /** + callback argument is + total farmes caught + registerCallBackAcquisitionFinished(void (*func)(int, void*),void *arg); + */ + + + //receiver->registerCallBackAcquisitionFinished(func,arg); + + + + /** + args to raw data ready callback are + framenum + datapointer + file descriptor + guidatapointer (NULL, no data required) + + NEVER DELETE THE DATA POINTER + REMEMBER THAT THE CALLBACK IS BLOCKING + + registerCallBackRawDataReady(void (*func)(int, char*, FILE*, char*, void*),void *arg); + + */ + + //receiver->registerCallBackRawDataReady(func,arg); + + + + + user->start(); + + + return 0; +} + diff --git a/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.cpp b/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.cpp new file mode 100644 index 000000000..c3720ad05 --- /dev/null +++ b/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.cpp @@ -0,0 +1,1991 @@ +/********************************************//** + * @file slsReceiverTCPIPInterface.h + * @short interface between receiver and client + ***********************************************/ + +#include "slsReceiverTCPIPInterface.h" +#include "slsReceiverUDPFunctions.h" +#include "svnInfoReceiver.h" +#include "slsReceiverUsers.h" + +#include //SIGINT +#include //EXIT + +#include +#include +#include +#include +#include +using namespace std; + + +int slsReceiverTCPIPInterface::file_des(-1); +int slsReceiverTCPIPInterface::socketDescriptor(-1); + + +slsReceiverTCPIPInterface::~slsReceiverTCPIPInterface() { + if(socket) delete socket; + closeFile(0); +} + + +slsReceiverTCPIPInterface::slsReceiverTCPIPInterface(int argc, char *argv[], int &success): + myDetectorType(GOTTHARD), + ret(OK), + lockStatus(0), + shortFrame(-1), + packetsPerFrame(GOTTHARD_PACKETS_PER_FRAME), + socket(NULL){ + + int port_no = DEFAULT_PORTNO+2; + ifstream infile; + string sLine,sargname; + int iline = 0; + + + success=OK; + string fname = ""; + + //parse command line for config + for(int iarg=1;iarg> sargname; + + //tcp port + if(sargname=="rx_tcpport"){ + if(sstr.good()) { + sstr >> sargname; + if(sscanf(sargname.c_str(),"%d",&port_no)) + cout<<"dataport:"<getErrorStatus()) { + success = FAIL; + delete socket; + socket=NULL; + } else { + //initialize variables + strcpy(socket->lastClientIP,"none"); + strcpy(socket->thisClientIP,"none1"); + strcpy(mess,"dummy message"); + + function_table(); +#ifdef VERBOSE + cout << "Function table assigned." << endl; +#endif + slsReceiverFunctions = new slsReceiverUDPFunctions(); + + //Catch signal SIGINT to close files properly + signal(SIGINT,staticCloseFile); + + + file_des=socket->getFileDes(); + socketDescriptor=socket->getsocketDescriptor(); + + //success = OK; + } + } + +} + +void slsReceiverTCPIPInterface::start(){ + + int v=slsReceiverDefs::OK; + + while(v!=GOODBYE) { +#ifdef VERBOSE + cout<< endl; +#endif +#ifdef VERY_VERBOSE + cout << "Waiting for client call" << endl; +#endif + if(socket->Connect()>=0){ +#ifdef VERY_VERBOSE + cout << "Conenction accepted" << endl; +#endif + v = decode_function(); +#ifdef VERY_VERBOSE + cout << "function executed" << endl; +#endif + socket->Disconnect(); +#ifdef VERY_VERBOSE + cout << "connection closed" << endl; +#endif + } + } + + + +} + + +int slsReceiverTCPIPInterface::function_table(){ + + for (int i=0;iReceiveDataOnly(&fnum,sizeof(fnum)); + if (n <= 0) { +#ifdef VERBOSE + cout << "ERROR reading from socket " << n << ", " << fnum << endl; +#endif + return FAIL; + } +#ifdef VERBOSE + else + cout << "size of data received " << n <numberOfFunctions-1) + fnum = numberOfFunctions-1; + //calling function + (this->*flist[fnum])(); + if (ret==FAIL) + cout << "Error executing the function = " << fnum << endl; + + return ret; +} + + + + + + +int slsReceiverTCPIPInterface::M_nofunc(){ + + ret=FAIL; + sprintf(mess,"Unrecognized Function\n"); + cout << mess << endl; + + socket->SendDataOnly(&ret,sizeof(ret)); + socket->SendDataOnly(mess,sizeof(mess)); + + return GOODBYE; +} + + + + +void slsReceiverTCPIPInterface::closeFile(int p){ + cout<<"Closing Files... "<closeFile(); + cout << "Goodbye!" << endl; + exit(-1); +} + +void slsReceiverTCPIPInterface::staticCloseFile(int p){ + slsReceiverUsers::receiver->closeFile(p); +} + + +int slsReceiverTCPIPInterface::set_detector_type(){ + ret=OK; + int retval=FAIL; + detectorType dr; + strcpy(mess,"Could not set detector type range\n"); + + + // receive arguments + if(socket->ReceiveDataOnly(&dr,sizeof(dr)) < 0 ){ + strcpy(mess,"Error reading from socket\n"); + ret = FAIL; + } + + // execute action if the arguments correctly arrived +#ifdef SLS_RECEIVER_UDP_FUNCTIONS + if (ret==OK) { + if (lockStatus==1 && socket->differentClients==1){ + sprintf(mess,"Receiver locked by %s\n", socket->lastClientIP); + ret=FAIL; + } + else{ + myDetectorType = dr; + ret=slsReceiverFunctions->setDetectorType(dr); + retval = myDetectorType; + } + } +//#ifdef VERBOSE + if(ret!=FAIL) + cout << "detector type" << dr << endl; + else + cout << mess << endl; +//#endif +#endif + + if(ret==OK && socket->differentClients){ + cout << "Force update" << endl; + ret=FORCE_UPDATE; + } + + // send answer + socket->SendDataOnly(&ret,sizeof(ret)); + if(ret==FAIL) + socket->SendDataOnly(mess,sizeof(mess)); + socket->SendDataOnly(&retval,sizeof(retval)); + + //return ok/fail + return ret; +} + + + + + + + +int slsReceiverTCPIPInterface::set_file_name() { + ret=OK; + char retval[MAX_STR_LENGTH]=""; + char fName[MAX_STR_LENGTH]; + strcpy(mess,"Could not set file name"); + + // receive arguments + if(socket->ReceiveDataOnly(fName,MAX_STR_LENGTH) < 0 ){ + strcpy(mess,"Error reading from socket\n"); + ret = FAIL; + } + + // execute action if the arguments correctly arrived +#ifdef SLS_RECEIVER_UDP_FUNCTIONS + if (ret==OK) { + + if (lockStatus==1 && socket->differentClients==1){ + sprintf(mess,"Receiver locked by %s\n", socket->lastClientIP); + ret=FAIL; + } + else + strcpy(retval,slsReceiverFunctions->setFileName(fName)); + } +#ifdef VERBOSE + if(ret!=FAIL) + cout << "file name:" << retval << endl; + else + cout << mess << endl; +#endif +#endif + + if(ret==OK && socket->differentClients){ + cout << "Force update" << endl; + ret=FORCE_UPDATE; + } + + // send answer + socket->SendDataOnly(&ret,sizeof(ret)); + if(ret==FAIL) + socket->SendDataOnly(mess,sizeof(mess)); + socket->SendDataOnly(retval,MAX_STR_LENGTH); + + //return ok/fail + return ret; +} + + + + + + +int slsReceiverTCPIPInterface::set_file_dir() { + ret=OK; + char retval[MAX_STR_LENGTH]=""; + char fPath[MAX_STR_LENGTH]; + strcpy(mess,"Could not set file path\n"); + + // receive arguments + if(socket->ReceiveDataOnly(fPath,MAX_STR_LENGTH) < 0 ){ + strcpy(mess,"Error reading from socket\n"); + ret = FAIL; + } + + // execute action if the arguments correctly arrived +#ifdef SLS_RECEIVER_UDP_FUNCTIONS + if (ret==OK) { + if (lockStatus==1 && socket->differentClients==1){ + sprintf(mess,"Receiver locked by %s\n", socket->lastClientIP); + ret=FAIL; + }/* + else if((strlen(fPath))&&(slsReceiverFunctions->getStatus()==RUNNING)){ + strcpy(mess,"Can not set file path while receiver running\n"); + ret = FAIL; + }*/ + else{ + strcpy(retval,slsReceiverFunctions->setFilePath(fPath)); + // if file path doesnt exist + if(strlen(fPath)) + if (strcmp(retval,fPath)){ + strcpy(mess,"receiver file path does not exist\n"); + ret=FAIL; + } + } + + } +#ifdef VERBOSE + if(ret!=FAIL) + cout << "file path:" << retval << endl; + else + cout << mess << endl; +#endif +#endif + + if(ret==OK && socket->differentClients){ + cout << "Force update" << endl; + ret=FORCE_UPDATE; + } + + // send answer + socket->SendDataOnly(&ret,sizeof(ret)); + if(ret==FAIL) + socket->SendDataOnly(mess,sizeof(mess)); + socket->SendDataOnly(retval,MAX_STR_LENGTH); + + //return ok/fail + return ret; +} + + + + + + +int slsReceiverTCPIPInterface::set_file_index() { + ret=OK; + int retval=-1; + int index; + strcpy(mess,"Could not set file index\n"); + + + // receive arguments + if(socket->ReceiveDataOnly(&index,sizeof(index)) < 0 ){ + strcpy(mess,"Error reading from socket\n"); + ret = FAIL; + } + + // execute action if the arguments correctly arrived +#ifdef SLS_RECEIVER_UDP_FUNCTIONS + if (ret==OK) { + if (lockStatus==1 && socket->differentClients==1){ + sprintf(mess,"Receiver locked by %s\n", socket->lastClientIP); + ret=FAIL; + } + else + retval=slsReceiverFunctions->setFileIndex(index); + } +#ifdef VERBOSE + if(ret!=FAIL) + cout << "file index:" << retval << endl; + else + cout << mess << endl; +#endif +#endif + + if(ret==OK && socket->differentClients){ + cout << "Force update" << endl; + ret=FORCE_UPDATE; + } + + // send answer + socket->SendDataOnly(&ret,sizeof(ret)); + if(ret==FAIL) + socket->SendDataOnly(mess,sizeof(mess)); + socket->SendDataOnly(&retval,sizeof(retval)); + + //return ok/fail + return ret; +} + + + + + + + + +int slsReceiverTCPIPInterface::set_frame_index() { + ret=OK; + int retval=-1; + int index; + strcpy(mess,"Could not set frame index\n"); + + + // receive arguments + if(socket->ReceiveDataOnly(&index,sizeof(index)) < 0 ){ + strcpy(mess,"Error reading from socket\n"); + ret = FAIL; + } + + // execute action if the arguments correctly arrived +#ifdef SLS_RECEIVER_UDP_FUNCTIONS + if (ret==OK) { + if (lockStatus==1 && socket->differentClients==1){ + sprintf(mess,"Receiver locked by %s\n", socket->lastClientIP); + ret=FAIL; + } + else + retval=slsReceiverFunctions->setFrameIndexNeeded(index); + } +#ifdef VERBOSE + if(ret!=FAIL) + cout << "frame index:" << retval << endl; + else + cout << mess << endl; +#endif +#endif + + if(ret==OK && socket->differentClients){ + cout << "Force update" << endl; + ret=FORCE_UPDATE; + } + + // send answer + socket->SendDataOnly(&ret,sizeof(ret)); + if(ret==FAIL) + socket->SendDataOnly(mess,sizeof(mess)); + socket->SendDataOnly(&retval,sizeof(retval)); + + //return ok/fail + return ret; +} + + + + + + + +int slsReceiverTCPIPInterface::setup_udp(){ + ret=OK; + strcpy(mess,"could not set up udp connection"); + char retval[MAX_STR_LENGTH]=""; + char args[2][MAX_STR_LENGTH]; + + string temp; + int udpport; + char eth[MAX_STR_LENGTH]; + + + // receive arguments + + if(socket->ReceiveDataOnly(args,sizeof(args)) < 0 ){ + strcpy(mess,"Error reading from socket\n"); + ret = FAIL; + } + + // execute action if the arguments correctly arrived +#ifdef SLS_RECEIVER_UDP_FUNCTIONS + if (ret==OK) { + if (lockStatus==1 && socket->differentClients==1){ + sprintf(mess,"Receiver locked by %s\n", socket->lastClientIP); + ret=FAIL; + } + else if(slsReceiverFunctions->getStatus()==RUNNING){ + ret = FAIL; + strcpy(mess,"cannot set up udp when receiver is running\n"); + } + else{ + //set up udp port + sscanf(args[1],"%d",&udpport); + slsReceiverFunctions->setUDPPortNo(udpport); + + //setup udpip + //get ethernet interface or IP to listen to + temp = genericSocket::ipToName(args[0]); + if(temp=="none"){ + ret = FAIL; + strcpy(mess, "failed to get ethernet interface or IP to listen to\n"); + } + else{ + strcpy(eth,temp.c_str()); + if (strchr(eth,'.')!=NULL) { + strcpy(eth,""); + ret = FAIL; + } + cout<<"eth:"<setEthernetInterface(eth); + + //get mac address from ethernet interface + if (ret != FAIL) + temp = genericSocket::nameToMac(eth); + + + if ((temp=="00:00:00:00:00:00") || (ret == FAIL)){ + ret = FAIL; + strcpy(mess,"failed to get mac adddress to listen to\n"); + cout << "mess:" << mess << endl; + } + else{ + strcpy(retval,temp.c_str()); + cout<<"mac:"<differentClients){ + cout << "Force update" << endl; + ret=FORCE_UPDATE; + } + + // send answer + socket->SendDataOnly(&ret,sizeof(ret)); + if(ret==FAIL) + socket->SendDataOnly(mess,sizeof(mess)); + socket->SendDataOnly(retval,MAX_STR_LENGTH); + + //return ok/fail + return ret; +} + + + + + + +int slsReceiverTCPIPInterface::start_receiver(){ + ret=OK; + ret=OK; + enum runStatus s; + char cstatus[15]; + strcpy(mess,"Could not start receiver\n"); + + // execute action if the arguments correctly arrived +#ifdef SLS_RECEIVER_UDP_FUNCTIONS + if (lockStatus==1 && socket->differentClients==1){ + sprintf(mess,"Receiver locked by %s\n", socket->lastClientIP); + ret=FAIL; + } + /* + else if(!strlen(slsReceiverFunctions->getFilePath())){ + strcpy(mess,"receiver not set up. set receiver ip again.\n"); + ret = FAIL; + } + */ + else { + s = slsReceiverFunctions->getStatus(); + switch (s) { + case ERROR: strcpy(cstatus,"error"); break; + case WAITING: strcpy(cstatus,"waiting"); break; + case RUNNING: strcpy(cstatus,"running"); break; + case TRANSMITTING: strcpy(cstatus,"data"); break; + case RUN_FINISHED: strcpy(cstatus,"finished"); break; + default: strcpy(cstatus,"idle"); break; + } + if(s == IDLE) + ret=slsReceiverFunctions->startReceiver(mess); + else{ + sprintf(mess,"Cannot start Receiver as it is in %s state\n",cstatus); + ret=FAIL; + } + } + +#endif + + if(ret==OK && socket->differentClients){ + cout << "Force update" << endl; + ret=FORCE_UPDATE; + } + + // send answer + socket->SendDataOnly(&ret,sizeof(ret)); + if(ret==FAIL) + socket->SendDataOnly(mess,sizeof(mess)); + cout<<"ret of start receiver:"<differentClients==1){ + sprintf(mess,"Receiver locked by %s\n", socket->lastClientIP); + ret=FAIL; + } + else if(slsReceiverFunctions->getStatus()!=IDLE) + ret=slsReceiverFunctions->stopReceiver(); +#endif + + if(ret==OK && socket->differentClients){ + cout << "Force update" << endl; + ret=FORCE_UPDATE; + } + + // send answer + socket->SendDataOnly(&ret,sizeof(ret)); + if(ret==FAIL) + socket->SendDataOnly(mess,sizeof(mess)); + //return ok/fail + return ret; + + +} + + +int slsReceiverTCPIPInterface::get_status(){ + ret=OK; + enum runStatus retval; + + // execute action if the arguments correctly arrived +#ifdef SLS_RECEIVER_UDP_FUNCTIONS + retval=slsReceiverFunctions->getStatus(); +#endif + + if(socket->differentClients){ + cout << "Force update" << endl; + ret=FORCE_UPDATE; + } + + // send answer + socket->SendDataOnly(&ret,sizeof(ret)); + socket->SendDataOnly(&retval,sizeof(retval)); + //return ok/fail + return ret; + + +} + + +int slsReceiverTCPIPInterface::get_frames_caught(){ + ret=OK; + int retval=-1; + + // execute action if the arguments correctly arrived +#ifdef SLS_RECEIVER_UDP_FUNCTIONS + retval=slsReceiverFunctions->getTotalFramesCaught(); +#endif + if(socket->differentClients){ + cout << "Force update" << endl; + ret=FORCE_UPDATE; + } + + // send answer + socket->SendDataOnly(&ret,sizeof(ret)); + socket->SendDataOnly(&retval,sizeof(retval)); + //return ok/fail + return ret; + + +} + + +int slsReceiverTCPIPInterface::get_frame_index(){ + ret=OK; + int retval=-1; + + // execute action if the arguments correctly arrived +#ifdef SLS_RECEIVER_UDP_FUNCTIONS + retval=slsReceiverFunctions->getAcquisitionIndex(); +#endif + + if(socket->differentClients){ + cout << "Force update" << endl; + ret=FORCE_UPDATE; + } + + // send answer + socket->SendDataOnly(&ret,sizeof(ret)); + socket->SendDataOnly(&retval,sizeof(retval)); + //return ok/fail + return ret; + + +} + + +int slsReceiverTCPIPInterface::reset_frames_caught(){ + ret=OK; + + strcpy(mess,"Could not reset frames caught\n"); + + + // execute action if the arguments correctly arrived +#ifdef SLS_RECEIVER_UDP_FUNCTIONS + if (ret==OK) { + if (lockStatus==1 && socket->differentClients==1){ + sprintf(mess,"Receiver locked by %s\n", socket->lastClientIP); + ret=FAIL; + } + else + slsReceiverFunctions->resetTotalFramesCaught(); + } +#endif + + if(ret==OK && socket->differentClients){ + cout << "Force update" << endl; + ret=FORCE_UPDATE; + } + + // send answer + socket->SendDataOnly(&ret,sizeof(ret)); + if(ret==FAIL) + socket->SendDataOnly(mess,sizeof(mess)); + + //return ok/fail + return ret; + + +} + + + + + + +int slsReceiverTCPIPInterface::set_short_frame() { + ret=OK; + int index=0; + int retval=-100; + strcpy(mess,"Could not set/reset short frame for receiver\n"); + + //does not exist for moench + if(myDetectorType==MOENCH){ + strcpy(mess,"can not set short frame for moench\n"); + ret = FAIL; + } + + // receive arguments + if(socket->ReceiveDataOnly(&index,sizeof(index)) < 0 ){ + strcpy(mess,"Error reading from socket\n"); + ret = FAIL; + } + + + // execute action if the arguments correctly arrived +#ifdef SLS_RECEIVER_UDP_FUNCTIONS + if (ret==OK) { + if (lockStatus==1 && socket->differentClients==1){ + sprintf(mess,"Receiver locked by %s\n", socket->lastClientIP); + ret=FAIL; + } + else if(slsReceiverFunctions->getStatus()==RUNNING){ + strcpy(mess,"Cannot set short frame while status is running\n"); + ret=FAIL; + } + else{ + retval=slsReceiverFunctions->setShortFrame(index); + shortFrame = retval; + if(shortFrame==-1) + packetsPerFrame=GOTTHARD_PACKETS_PER_FRAME; + else + packetsPerFrame=GOTTHARD_SHORT_PACKETS_PER_FRAME; + } + } +#endif + + if(ret==OK && socket->differentClients){ + cout << "Force update" << endl; + ret=FORCE_UPDATE; + } + + // send answer + socket->SendDataOnly(&ret,sizeof(ret)); + if(ret==FAIL) + socket->SendDataOnly(mess,sizeof(mess)); + socket->SendDataOnly(&retval,sizeof(retval)); + + //return ok/fail + return ret; +} + + + + +int slsReceiverTCPIPInterface::read_frame(){ + switch(myDetectorType){ + case MOENCH: + return moench_read_frame(); + default: + return gotthard_read_frame(); + } +} + + + +int slsReceiverTCPIPInterface::moench_read_frame(){ + ret=OK; + char fName[MAX_STR_LENGTH]=""; + int arg = -1,i; + + + int bufferSize = MOENCH_BUFFER_SIZE; + int rnel = bufferSize/(sizeof(int)); + int* retval = new int[rnel]; + int* origVal = new int[rnel]; + //all initialized to 0 + for(i=0;igetFramesCaught()){ + arg = -1; + cout<<"haven't caught any frame yet"<getStartFrameIndex(); + slsReceiverFunctions->readFrame(fName,&raw); + + /**send garbage with -1 index to try again*/ + if (raw == NULL){ + arg = -1; +#ifdef VERBOSE + cout<<"data not ready for gui yet"<> MOENCH_FRAME_INDEX_OFFSET); + + uint32_t numPackets = MOENCH_PACKETS_PER_FRAME; //40 + uint32_t onePacketSize = MOENCH_DATA_BYTES / MOENCH_PACKETS_PER_FRAME; //1280*40 / 40 = 1280 + uint32_t packetDatabytes_row = onePacketSize * (MOENCH_BYTES_IN_ONE_ROW / MOENCH_BYTES_PER_ADC); //1280 * 4 = 5120 + uint32_t partsPerFrame = onePacketSize / MOENCH_BYTES_PER_ADC; // 1280 / 80 = 16 + uint32_t packetOffset = 0; + int packetIndex,x,y; + int iPacket = 0; + offset = 4; + + + while (iPacket < (int)numPackets){ +#ifdef VERBOSE + printf("iPacket:%d\n",iPacket);cout << endl; +#endif + //if missing packets, dont send to gui + bindex = (*((uint32_t*)(((char*)origVal)+packetOffset))); + if (bindex == 0xFFFFFFFF){ + cout << "Missing Packet,Not sending to gui" << endl; + index = startIndex - 1; + break;//use continue and change index above if you want to display missing packets with 0 value anyway in gui + } + + packetIndex = bindex & MOENCH_PACKET_INDEX_MASK; + //cout<<"packetIndex:"<= 40) && (packetIndex < 0)) + cout << "cannot decode packet index:" << packetIndex << endl; + else{ + + x = packetIndex / 10; + y = packetIndex % 10; +#ifdef VERBOSE + cout<<"x:"<differentClients){ + cout << "Force update" << endl; + ret=FORCE_UPDATE; + } + + // send answer + socket->SendDataOnly(&ret,sizeof(ret)); + if(ret==FAIL){ + cout << "mess:" << mess << endl; + socket->SendDataOnly(mess,sizeof(mess)); + } + else{ + socket->SendDataOnly(fName,MAX_STR_LENGTH); + socket->SendDataOnly(&arg,sizeof(arg)); + socket->SendDataOnly(retval,MOENCH_DATA_BYTES); + } + //return ok/fail + + + delete [] retval; + delete [] origVal; + delete [] raw; + + return ret; + +} + + + + +int slsReceiverTCPIPInterface::gotthard_read_frame(){ + ret=OK; + char fName[MAX_STR_LENGTH]=""; + int arg = -1,i; + + + //retval is a full frame + int bufferSize = GOTTHARD_BUFFER_SIZE; + int rnel = bufferSize/(sizeof(int)); + int* retval = new int[rnel]; + int* origVal = new int[rnel]; + //all initialized to 0 + for(i=0;igetFramesCaught()){ + arg=-1; + cout<<"haven't caught any frame yet"<getStartFrameIndex(); + slsReceiverFunctions->readFrame(fName,&raw); + + /**send garbage with -1 index to try again*/ + if (raw == NULL){ + arg = -1; +#ifdef VERBOSE + cout<<"data not ready for gui yet"<> GOTTHARD_SHORT_FRAME_INDEX_OFFSET); +#ifdef VERBOSE + cout << "index:" << hex << index << endl; +#endif + }else{ + bindex = ((uint32_t)(*((uint32_t*)raw)))+1; + pindex = (bindex & GOTTHARD_PACKET_INDEX_MASK); + index = ((bindex & GOTTHARD_FRAME_INDEX_MASK) >> GOTTHARD_FRAME_INDEX_OFFSET); + bindex2 = ((uint32_t)(*((uint32_t*)((char*)(raw+onebuffersize)))))+1; + pindex2 =(bindex2 & GOTTHARD_PACKET_INDEX_MASK); + index2 =((bindex2 & GOTTHARD_FRAME_INDEX_MASK) >> GOTTHARD_FRAME_INDEX_OFFSET); +#ifdef VERBOSE + cout << "index1:" << hex << index << endl; + cout << "index2:" << hex << index << endl; +#endif + } + + memcpy(origVal,raw,bufferSize); + raw=NULL; + + + //1 adc + if(shortFrame!=-1){ + if(bindex != 0xFFFFFFFF) + memcpy((((char*)retval)+(GOTTHARD_SHORT_DATABYTES*shortFrame)),((char*) origVal)+4, GOTTHARD_SHORT_DATABYTES); + else{ + index = startIndex - 1; + cout << "Missing Packet,Not sending to gui" << endl; + } + } + //all adc + else{ + //ignore if half frame is missing + if ((bindex != 0xFFFFFFFF) && (bindex2 != 0xFFFFFFFF)){ + + //should be same frame + if (index == index2){ + //ideal situation (should be odd, even(index+1)) + if(!pindex){ + memcpy(retval,((char*) origVal)+4, onedatasize); + memcpy((((char*)retval)+onedatasize), ((char*) origVal)+10+onedatasize, onedatasize); + } + //swap to even,odd + else{ + memcpy((((char*)retval)+onedatasize),((char*) origVal)+4, onedatasize); + memcpy(retval, ((char*) origVal)+10+onedatasize, onedatasize); + index=index2; + } + }else + cout << "different frames caught. frame1:"<< hex << index << ":"<differentClients){ + cout << "Force update" << endl; + ret=FORCE_UPDATE; + } + + // send answer + socket->SendDataOnly(&ret,sizeof(ret)); + if(ret==FAIL){ + cout << "mess:" << mess << endl; + socket->SendDataOnly(mess,sizeof(mess)); + } + else{ + socket->SendDataOnly(fName,MAX_STR_LENGTH); + socket->SendDataOnly(&arg,sizeof(arg)); + socket->SendDataOnly(retval,GOTTHARD_DATA_BYTES); + } + + delete [] retval; + delete [] origVal; + delete [] raw; + + return ret; +} + + + + +int slsReceiverTCPIPInterface::set_read_frequency(){ + ret=OK; + int retval=-1; + int index; + strcpy(mess,"Could not set receiver read frequency\n"); + + + // receive arguments + if(socket->ReceiveDataOnly(&index,sizeof(index)) < 0 ){ + strcpy(mess,"Error reading from socket\n"); + ret = FAIL; + } + + // execute action if the arguments correctly arrived +#ifdef SLS_RECEIVER_UDP_FUNCTIONS + if (ret==OK) { + if (lockStatus==1 && socket->differentClients==1){ + sprintf(mess,"Receiver locked by %s\n", socket->lastClientIP); + ret=FAIL; + }/* + else if((slsReceiverFunctions->getStatus()==RUNNING) && (index >= 0)){ + ret = FAIL; + strcpy(mess,"cannot set up receiver mode when receiver is running\n"); + }*/ + else + retval=slsReceiverFunctions->setNFrameToGui(index); + } + +#endif + + if(ret==OK && socket->differentClients){ + cout << "Force update" << endl; + ret=FORCE_UPDATE; + } + + // send answer + socket->SendDataOnly(&ret,sizeof(ret)); + if(ret==FAIL) + socket->SendDataOnly(mess,sizeof(mess)); + socket->SendDataOnly(&retval,sizeof(retval)); + + //return ok/fail + return ret; +} + + + + + + +int slsReceiverTCPIPInterface::enable_file_write(){ + ret=OK; + int retval=-1; + int enable; + strcpy(mess,"Could not set/get enable file write\n"); + + + // receive arguments + if(socket->ReceiveDataOnly(&enable,sizeof(enable)) < 0 ){ + strcpy(mess,"Error reading from socket\n"); + ret = FAIL; + } + + // execute action if the arguments correctly arrived +#ifdef SLS_RECEIVER_UDP_FUNCTIONS + if (ret==OK) { + if (lockStatus==1 && socket->differentClients==1){ + sprintf(mess,"Receiver locked by %s\n", socket->lastClientIP); + ret=FAIL; + } + else{ + retval=slsReceiverFunctions->setEnableFileWrite(enable); + if((enable!=-1)&&(enable!=retval)) + ret=FAIL; + } + } +#endif + + if(ret==OK && socket->differentClients){ + cout << "Force update" << endl; + ret=FORCE_UPDATE; + } + + // send answer + socket->SendDataOnly(&ret,sizeof(ret)); + if(ret==FAIL) + socket->SendDataOnly(mess,sizeof(mess)); + socket->SendDataOnly(&retval,sizeof(retval)); + + //return ok/fail + return ret; +} + + + +int slsReceiverTCPIPInterface::get_id(){ + ret=OK; + int64_t retval=-1; + + // execute action if the arguments correctly arrived +#ifdef SLS_RECEIVER_UDP_FUNCTIONS + retval = get_version(); +#endif + + if(socket->differentClients){ + cout << "Force update" << endl; + ret=FORCE_UPDATE; + } + + // send answer + socket->SendDataOnly(&ret,sizeof(ret)); + socket->SendDataOnly(&retval,sizeof(retval)); + + //return ok/fail + return ret; +} + + + +int64_t slsReceiverTCPIPInterface::get_version(){ + int64_t retval = SVNREV; + retval= (retval <<32) | SVNDATE; + return retval; +} + + + + +int slsReceiverTCPIPInterface::start_readout(){ + ret=OK; + enum runStatus retval; + + // execute action if the arguments correctly arrived +#ifdef SLS_RECEIVER_UDP_FUNCTIONS + slsReceiverFunctions->startReadout(); + retval = slsReceiverFunctions->getStatus(); + if((retval == TRANSMITTING) || (retval == RUN_FINISHED) || (retval == IDLE)) + ret = OK; + else + ret = FAIL; +#endif + + if(socket->differentClients){ + cout << "Force update" << endl; + ret=FORCE_UPDATE; + } + + // send answer + socket->SendDataOnly(&ret,sizeof(ret)); + socket->SendDataOnly(&retval,sizeof(retval)); + //return ok/fail + return ret; + + +} + + + + +int slsReceiverTCPIPInterface::set_timer() { + ret=OK; + int64_t retval = -1; + int64_t index[2]; + index[1] = -1; + strcpy(mess,"Could not set acquisition period or frame number in receiver\n"); + + + // receive arguments + if(socket->ReceiveDataOnly(index,sizeof(index)) < 0 ){ + strcpy(mess,"Error reading from socket\n"); + ret = FAIL; + } + + // execute action if the arguments correctly arrived +#ifdef SLS_RECEIVER_UDP_FUNCTIONS + if (ret==OK) { + if (lockStatus==1 && socket->differentClients==1){ + sprintf(mess,"Receiver locked by %s\n", socket->lastClientIP); + ret=FAIL; + } + else{ + if(index[0] == slsReceiverDefs::FRAME_PERIOD) + retval=slsReceiverFunctions->setAcquisitionPeriod(index[1]); + else + retval=slsReceiverFunctions->setNumberOfFrames(index[1]); + } + } +#ifdef VERBOSE + if(ret!=FAIL){ + if(index[0] == slsReceiverDefs::FRAME_PERIOD) + cout << "acquisition period:" << retval << endl; + else + cout << "frame number:" << retval << endl; + }else + cout << mess << endl; +#endif +#endif + + if(ret==OK && socket->differentClients){ + cout << "Force update" << endl; + ret=FORCE_UPDATE; + } + + // send answer + socket->SendDataOnly(&ret,sizeof(ret)); + if(ret==FAIL) + socket->SendDataOnly(mess,sizeof(mess)); + socket->SendDataOnly(&retval,sizeof(retval)); + + //return ok/fail + return ret; +} + + + + + + +int slsReceiverTCPIPInterface::enable_compression() { + ret=OK; + int enable=-1; + int retval=-100; + strcpy(mess,"Could not enable/disable compression for receiver\n"); + + // receive arguments + if(socket->ReceiveDataOnly(&enable,sizeof(enable)) < 0 ){ + strcpy(mess,"Error reading from socket\n"); + ret = FAIL; + } + + + // execute action if the arguments correctly arrived +#ifdef SLS_RECEIVER_UDP_FUNCTIONS + if (ret==OK) { + if(enable >= 0){ + if (lockStatus==1 && socket->differentClients==1){ + sprintf(mess,"Receiver locked by %s\n", socket->lastClientIP); + ret=FAIL; + } + else if(slsReceiverFunctions->getStatus()==RUNNING){ + strcpy(mess,"Cannot enable/disable compression while status is running\n"); + ret=FAIL; + } + else + ret = slsReceiverFunctions->enableDataCompression(enable); + } + + retval=slsReceiverFunctions->getDataCompression(); + } +#endif + + if(ret==OK && socket->differentClients){ + cout << "Force update" << endl; + ret=FORCE_UPDATE; + } + + // send answer + socket->SendDataOnly(&ret,sizeof(ret)); + if(ret==FAIL) + socket->SendDataOnly(mess,sizeof(mess)); + socket->SendDataOnly(&retval,sizeof(retval)); + + //return ok/fail + return ret; +} + + + + +int slsReceiverTCPIPInterface::set_detector_hostname() { + ret=OK; + char retval[MAX_STR_LENGTH]=""; + char hostname[MAX_STR_LENGTH]=""; + strcpy(mess,"Could not set detector hostname"); + + // receive arguments + if(socket->ReceiveDataOnly(hostname,MAX_STR_LENGTH) < 0 ){ + strcpy(mess,"Error reading from socket\n"); + ret = FAIL; + } + + // execute action if the arguments correctly arrived +#ifdef SLS_RECEIVER_UDP_FUNCTIONS + if (ret==OK) { + + if (lockStatus==1 && socket->differentClients==1){ + sprintf(mess,"Receiver locked by %s\n", socket->lastClientIP); + ret=FAIL; + } + else + strcpy(retval,slsReceiverFunctions->setDetectorHostname(hostname)); + } +#ifdef VERBOSE + if(ret!=FAIL) + cout << "hostname:" << retval << endl; + else + cout << mess << endl; +#endif +#endif + + if(ret==OK && socket->differentClients){ + cout << "Force update" << endl; + ret=FORCE_UPDATE; + } + + // send answer + socket->SendDataOnly(&ret,sizeof(ret)); + if(ret==FAIL) + socket->SendDataOnly(mess,sizeof(mess)); + socket->SendDataOnly(retval,MAX_STR_LENGTH); + + //return ok/fail + return ret; +} + + + + + + + +int slsReceiverTCPIPInterface::set_dynamic_range() { + ret=OK; + int retval=-1; + int dr; + strcpy(mess,"Could not set dynamic range\n"); + + + // receive arguments + if(socket->ReceiveDataOnly(&dr,sizeof(dr)) < 0 ){ + strcpy(mess,"Error reading from socket\n"); + ret = FAIL; + } + + // execute action if the arguments correctly arrived +#ifdef SLS_RECEIVER_UDP_FUNCTIONS + if (ret==OK) { + if (lockStatus==1 && socket->differentClients==1){ + sprintf(mess,"Receiver locked by %s\n", socket->lastClientIP); + ret=FAIL; + } + else + retval=slsReceiverFunctions->setDynamicRange(dr); + } +#ifdef VERBOSE + if(ret!=FAIL) + cout << "dynamic range" << dr << endl; + else + cout << mess << endl; +#endif +#endif + + if(ret==OK && socket->differentClients){ + cout << "Force update" << endl; + ret=FORCE_UPDATE; + } + + // send answer + socket->SendDataOnly(&ret,sizeof(ret)); + if(ret==FAIL) + socket->SendDataOnly(mess,sizeof(mess)); + socket->SendDataOnly(&retval,sizeof(retval)); + + //return ok/fail + return ret; +} + + + + + + + +int slsReceiverTCPIPInterface::enable_overwrite() { + ret=OK; + int retval=-1; + int index; + strcpy(mess,"Could not enable/disable overwrite\n"); + + + // receive arguments + if(socket->ReceiveDataOnly(&index,sizeof(index)) < 0 ){ + strcpy(mess,"Error reading from socket\n"); + ret = FAIL; + } + + // execute action if the arguments correctly arrived +#ifdef SLS_RECEIVER_UDP_FUNCTIONS + if (ret==OK) { + if (lockStatus==1 && socket->differentClients==1){ + sprintf(mess,"Receiver locked by %s\n", socket->lastClientIP); + ret=FAIL; + } + else + retval=slsReceiverFunctions->enableOverwrite(index); + } +#ifdef VERBOSE + if(ret!=FAIL) + cout << "overwrite:" << retval << endl; + else + cout << mess << endl; +#endif +#endif + + if(ret==OK && socket->differentClients){ + cout << "Force update" << endl; + ret=FORCE_UPDATE; + } + + // send answer + socket->SendDataOnly(&ret,sizeof(ret)); + if(ret==FAIL) + socket->SendDataOnly(mess,sizeof(mess)); + socket->SendDataOnly(&retval,sizeof(retval)); + + //return ok/fail + return ret; +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +int slsReceiverTCPIPInterface::lock_receiver() { + ret=OK; + int lock; + + // receive arguments + if(socket->ReceiveDataOnly(&lock,sizeof(lock)) < 0 ){ + sprintf(mess,"Error reading from socket\n"); + cout << "Error reading from socket (lock)" << endl; + ret=FAIL; + } + // execute action if the arguments correctly arrived + if(ret==OK){ + if (lock>=0) { + if (lockStatus==0 || strcmp(socket->lastClientIP,socket->thisClientIP)==0 || strcmp(socket->lastClientIP,"none")==0) { + lockStatus=lock; + strcpy(socket->lastClientIP,socket->thisClientIP); + } else { + ret=FAIL; + sprintf(mess,"Receiver already locked by %s\n", socket->lastClientIP); + } + } + } + + if (socket->differentClients && ret==OK) + ret=FORCE_UPDATE; + + // send answer + socket->SendDataOnly(&ret,sizeof(ret)); + if (ret==FAIL) + socket->SendDataOnly(mess,sizeof(mess)); + else + socket->SendDataOnly(&lockStatus,sizeof(lockStatus)); + + //return ok/fail + return ret; +} + + + + + + + +int slsReceiverTCPIPInterface::set_port() { + ret=OK; + MySocketTCP* mySocket=NULL; + int sd=-1; + enum runStatus p_type; /* just to get the input */ + int p_number; + + // receive arguments + if(socket->ReceiveDataOnly(&p_type,sizeof(p_type)) < 0 ){ + strcpy(mess,"Error reading from socket\n"); + cout << mess << endl; + ret=FAIL; + } + + if(socket->ReceiveDataOnly(&p_number,sizeof(p_number)) < 0 ){ + strcpy(mess,"Error reading from socket\n"); + cout << mess << endl; + ret=FAIL; + } + + // execute action if the arguments correctly arrived + if (ret==OK) { + if (socket->differentClients==1 && lockStatus==1 ) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",socket->lastClientIP); + } + else { + if (p_number<1024) { + sprintf(mess,"Too low port number %d\n", p_number); + cout << mess << endl; + ret=FAIL; + } + cout << "set port " << p_type << " to " << p_number <getErrorStatus(); + if (!sd){ + ret=OK; + if (mySocket->differentClients) + ret=FORCE_UPDATE; + } else { + ret=FAIL; + sprintf(mess,"Could not bind port %d\n", p_number); + cout << mess << endl; + if (sd==-10) { + sprintf(mess,"Port %d already set\n", p_number); + cout << mess << endl; + } + } + } + } + + // send answer + socket->SendDataOnly(&ret,sizeof(ret)); + if (ret==FAIL) { + socket->SendDataOnly(mess,sizeof(mess)); + } else { + socket->SendDataOnly(&p_number,sizeof(p_number)); + if(sd>=0){ + socket->Disconnect(); + delete socket; + socket = mySocket; + file_des=socket->getFileDes(); + } + } + + //return ok/fail + return ret; +} + + + + + + +int slsReceiverTCPIPInterface::get_last_client_ip() { + ret=OK; + + if (socket->differentClients ) + ret=FORCE_UPDATE; + + socket->SendDataOnly(&ret,sizeof(ret)); + socket->SendDataOnly(socket->lastClientIP,sizeof(socket->lastClientIP)); + + return ret; +} + + + + + + + +int slsReceiverTCPIPInterface::send_update() { + ret=OK; + int ind; + char path[MAX_STR_LENGTH]; + + socket->SendDataOnly(socket->lastClientIP,sizeof(socket->lastClientIP)); + + //index +#ifdef SLS_RECEIVER_UDP_FUNCTIONS + + /*if(myDetectorType != EIGER)*/ + ind=slsReceiverFunctions->getFileIndex(); + + socket->SendDataOnly(&ind,sizeof(ind)); +#endif + + //filepath +#ifdef SLS_RECEIVER_UDP_FUNCTIONS + strcpy(path,slsReceiverFunctions->getFilePath()); +#endif + socket->SendDataOnly(path,MAX_STR_LENGTH); + + + //filename +#ifdef SLS_RECEIVER_UDP_FUNCTIONS + strcpy(path,slsReceiverFunctions->getFileName()); +#endif + socket->SendDataOnly(path,MAX_STR_LENGTH); + + + if (lockStatus==0) { + strcpy(socket->lastClientIP,socket->thisClientIP); + } + + return ret; + + +} + + + + + + +int slsReceiverTCPIPInterface::update_client() { + ret=OK; + socket->SendDataOnly(&ret,sizeof(ret)); + + return send_update(); +} + + + + + + + +int slsReceiverTCPIPInterface::exit_server() { + ret=GOODBYE; + socket->SendDataOnly(&ret,sizeof(ret)); + strcpy(mess,"closing server"); + socket->SendDataOnly(mess,sizeof(mess)); + cout << mess << endl; + return ret; +} + + + + + +int slsReceiverTCPIPInterface::exec_command() { + ret = OK; + char cmd[MAX_STR_LENGTH]; + char answer[MAX_STR_LENGTH]; + int sysret=0; + + // receive arguments + if(socket->ReceiveDataOnly(cmd,MAX_STR_LENGTH) < 0 ){ + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + + // execute action if the arguments correctly arrived + if (ret==OK) { +#ifdef VERBOSE + cout << "executing command " << cmd << endl; +#endif + if (lockStatus==0 || socket->differentClients==0) + sysret=system(cmd); + + //should be replaced by popen + if (sysret==0) { + strcpy(answer,"Succeeded\n"); + if (lockStatus==1 && socket->differentClients==1) + sprintf(answer,"Detector locked by %s\n", socket->lastClientIP); + } else { + strcpy(answer,"Failed\n"); + ret=FAIL; + } + } else + strcpy(answer,"Could not receive the command\n"); + + + // send answer + socket->SendDataOnly(&ret,sizeof(ret)); + if(socket->SendDataOnly(answer,MAX_STR_LENGTH) < 0){ + strcpy(mess,"Error writing to socket"); + ret=FAIL; + } + + //return ok/fail + return ret; +} + + + + + diff --git a/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.h b/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.h new file mode 100644 index 000000000..b0cd6e780 --- /dev/null +++ b/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.h @@ -0,0 +1,238 @@ + /********************************************//** + * @file slsReceiverTCPIPInterface.h + * @short interface between receiver and client + ***********************************************/ +#ifndef SLS_RECEIVER_TCP_IP_INTERFACE_H +#define SLS_RECEIVER_TCP_IP_INTERFACE_H + + +#include "sls_receiver_defs.h" +#include "receiver_defs.h" +#include "MySocketTCP.h" +#include "slsReceiverUDPFunctions.h" + + + +/** + *@short interface between receiver and client + */ + +class slsReceiverTCPIPInterface : private virtual slsReceiverDefs { + +public: + /** + * Constructor + * reads config file, creates socket, assigns function table + * @param argc from command line + * @param argv from command line + * @param succecc socket creation was successfull + */ + slsReceiverTCPIPInterface(int argc, char *argv[], int &success); + + + /** starts listening on the TCP port for client comminication */ + + void start(); + + /** Destructor */ + virtual ~slsReceiverTCPIPInterface(); + + /** Close all threaded Files and exit */ + void closeFile(int p); + + /** Static function to call closeFile */ + static void staticCloseFile(int p); + + /** gets version */ + int64_t get_version(); + + /** + callback arguments are + filepath + filename + fileindex + data size + + return value is + 0 callback takes care of open,close,wrie file + 1 callback writes file, we have to open, close it + 2 we open, close, write file, callback does not do anything + + */ + + void registerCallBackStartAcquisition(int (*func)(char*, char*,int, int, void*),void *arg){slsReceiverFunctions->registerCallBackStartAcquisition(func,arg);};; + + + /** + callback argument is + toatal farmes caught + + */ + + + void registerCallBackAcquisitionFinished(void (*func)(int, void*),void *arg){slsReceiverFunctions->registerCallBackAcquisitionFinished(func,arg);}; + + + + /** + args to raw data ready callback are + framenum + datapointer + datasize in bytes + file descriptor + guidatapointer (NULL, no data required) + */ + + void registerCallBackRawDataReady(void (*func)(int, char*, int, FILE*, char*, void*),void *arg){slsReceiverFunctions->registerCallBackRawDataReady(func,arg);}; + + + private: + /** assigns functions to the fnum enum */ + int function_table(); + + /** Decodes Function */ + int decode_function(); + + /** Unrecognized Function */ + int M_nofunc(); + + /** Set detector type */ + int set_detector_type(); + + /** Set File name without frame index, file index and extension */ + int set_file_name(); + + /** Set File path */ + int set_file_dir(); + + /** Set up UDP Details */ + int setup_udp(); + + /** Set File index */ + int set_file_index(); + + /** Set Frame index */ + int set_frame_index(); + + /** Start Receiver - starts listening to udp packets from detector */ + int start_receiver(); + + /** Stop Receiver - stops listening to udp packets from detector*/ + int stop_receiver(); + + /** Gets receiver status */ + int get_status(); + + /** Gets Total Frames Caught */ + int get_frames_caught(); + + /** Gets frame index for each acquisition */ + int get_frame_index(); + + /** Resets Total Frames Caught */ + int reset_frames_caught(); + + /** set short frame */ + int set_short_frame(); + + /** Reads Frame/ buffer */ + int read_frame(); + + /** gotthard specific read frame */ + int gotthard_read_frame(); + + /** moench specific read frame */ + int moench_read_frame(); + + /** Sets the receiver to send every nth frame to gui, or only upon gui request */ + int set_read_frequency(); + + /** Enable File Write*/ + int enable_file_write(); + + /** get version, calls get_version */ + int get_id(); + + /** set status to transmitting and + * when fifo is empty later, sets status to run_finished */ + int start_readout(); + + /** set acquisition period, frame number etc */ + int set_timer(); + + /** enable compression */ + int enable_compression(); + + /** set detector hostname */ + int set_detector_hostname(); + + /** set dynamic range */ + int set_dynamic_range(); + + /** enable overwrite */ + int enable_overwrite(); + + + //General Functions + /** Locks Receiver */ + int lock_receiver(); + + /** Set port */ + int set_port(); + + /** Get Last Client IP*/ + int get_last_client_ip(); + + /** Updates Client if different clients connect */ + int update_client(); + + /** Sends the updated parameters to client */ + int send_update(); + + /** Exit Receiver Server */ + int exit_server(); + + /** Execute command */ + int exec_command(); + + + + //private: + /** detector type */ + detectorType myDetectorType; + + /** slsReceiverUDPFunctions object */ + slsReceiverUDPFunctions *slsReceiverFunctions; + + /** Number of functions */ + static const int numberOfFunctions = 256; + + /** Function List */ + int (slsReceiverTCPIPInterface::*flist[numberOfFunctions])(); + + /** Message */ + char mess[MAX_STR_LENGTH]; + + /** success/failure */ + int ret; + + /** Lock Status if server locked to a client */ + int lockStatus; + + /** Short frame */ + int shortFrame; + + /** Packets per frame */ + int packetsPerFrame; + + static int file_des; + static int socketDescriptor; + +//private: + protected: + /** Socket */ + MySocketTCP* socket; +}; + + +#endif diff --git a/slsReceiverSoftware/slsReceiver/slsReceiverUDPFunctions.cpp b/slsReceiverSoftware/slsReceiver/slsReceiverUDPFunctions.cpp new file mode 100644 index 000000000..0b710f199 --- /dev/null +++ b/slsReceiverSoftware/slsReceiver/slsReceiverUDPFunctions.cpp @@ -0,0 +1,1968 @@ +#ifdef SLS_RECEIVER_UDP_FUNCTIONS +/********************************************//** + * @file slsReceiverUDPFunctions.cpp + * @short does all the functions for a receiver, set/get parameters, start/stop etc. + ***********************************************/ + + +#include "slsReceiverUDPFunctions.h" + +#include "moench02ModuleData.h" +#include "gotthardModuleData.h" +#include "gotthardShortModuleData.h" + + +#include // SIGINT +#include // stat +#include // socket(), bind(), listen(), accept(), shut down +#include // sock_addr_in, htonl, INADDR_ANY +#include // exit() +#include //set precision +#include //munmap + + + +#include +#include +using namespace std; + + + + +slsReceiverUDPFunctions::slsReceiverUDPFunctions(): + receiver(NULL), + server_port(DEFAULT_UDP_PORTNO), + thread_started(0), + udpSocket(NULL), + eth(NULL), + latestData(NULL), + guiFileName(NULL), + mem0(NULL), + fifo(NULL), + fifoFree(NULL){ + + for(int i=0;i /proc/sys/net/core/rmem_max")) + cout << "\nWARNING: Could not change socket receiver buffer size in file /proc/sys/net/core/rmem_max" << endl; + else if(system("echo 250000 > /proc/sys/net/core/netdev_max_backlog")) + cout << "\nWARNING: Could not change max length of input queue in file /proc/sys/net/core/netdev_max_backlog" << endl; + /** permanent setting heiner + net.core.rmem_max = 104857600 # 100MiB + net.core.netdev_max_backlog = 250000 + sysctl -p + // from the manual + sysctl -w net.core.rmem_max=16777216 + sysctl -w net.core.netdev_max_backlog=250000 + */ +} + + + +slsReceiverUDPFunctions::~slsReceiverUDPFunctions(){ + createListeningThreads(true); + createWriterThreads(true); + deleteMembers(); +} + + + + +void slsReceiverUDPFunctions::deleteMembers(){ + //kill threads + if(thread_started){ + createListeningThreads(true); + createWriterThreads(true); + } + + for(int i=0;isetFileName(fileName); + } + + onePacketSize = bufferSize/packetsPerFrame; + latestData = new char[bufferSize]; + + + setupFifoStructure(); + + if(createListeningThreads() == FAIL){ + cout << "ERROR: Could not create listening thread" << endl; + exit (-1); + } + + if(createWriterThreads() == FAIL){ + cout << "ERROR: Could not create writer threads" << endl; + exit (-1); + } + + setThreadPriorities(); + + cout << "Ready..." << endl; + + return OK; +} + + + + + +/*Frame indices and numbers caught*/ + +bool slsReceiverUDPFunctions::getAcquistionStarted(){return acqStarted;}; + +bool slsReceiverUDPFunctions::getMeasurementStarted(){return measurementStarted;}; + +int slsReceiverUDPFunctions::getFramesCaught(){return (packetsCaught/packetsPerFrame);} + +int slsReceiverUDPFunctions::getTotalFramesCaught(){return (totalPacketsCaught/packetsPerFrame);} + +uint32_t slsReceiverUDPFunctions::getStartFrameIndex(){return startFrameIndex;} + +uint32_t slsReceiverUDPFunctions::getFrameIndex(){ + if(!packetsCaught) + frameIndex=0; + else + frameIndex = currframenum - startFrameIndex; + return frameIndex; +} + +uint32_t slsReceiverUDPFunctions::getAcquisitionIndex(){ + if(!totalPacketsCaught) + acquisitionIndex=0; + else + acquisitionIndex = currframenum - startAcquisitionIndex; + return acquisitionIndex; +} + + +void slsReceiverUDPFunctions::resetTotalFramesCaught(){ + acqStarted = false; + startAcquisitionIndex = 0; + totalPacketsCaught = 0; +} + + + + + + + + + +/*file parameters*/ + +char* slsReceiverUDPFunctions::getFilePath(){ + if(myDetectorType == EIGER) + return receiver->getFilePath(); + else + return filePath; +} + +char* slsReceiverUDPFunctions::setFilePath(char c[]){ + if(strlen(c)){ + //check if filepath exists + struct stat st; + if(stat(c,&st) == 0){ + if(myDetectorType == EIGER) + receiver->setFilePath(c); + else + strcpy(filePath,c); + }else{ + strcpy(filePath,""); + cout << "FilePath does not exist:" << filePath << endl; + } + } + return getFilePath(); +} + + +char* slsReceiverUDPFunctions::getFileName(){ + if(myDetectorType == EIGER) + return receiver->getFileName(); + else + return fileName; +} + +char* slsReceiverUDPFunctions::setFileName(char c[]){ + if(strlen(c)){ + if(myDetectorType == EIGER) + receiver->setFileName(c); + else + strcpy(fileName,c); + + } + return getFileName(); + +} + + +int slsReceiverUDPFunctions::getFileIndex(){ + return fileIndex; +} + +int slsReceiverUDPFunctions::setFileIndex(int i){ + if(i>=0) + fileIndex = i; + return getFileIndex(); +} + + +int slsReceiverUDPFunctions::setFrameIndexNeeded(int i){ + frameIndexNeeded = i; + return frameIndexNeeded; +} + + +int slsReceiverUDPFunctions::setEnableFileWrite(int i){ + if(i!=-1){ + if(myDetectorType == EIGER) + receiver->setEnableFileWrite(i); + else + enableFileWrite=i; + + } + if(myDetectorType == EIGER) + return receiver->getEnableFileWrite(); + else + return enableFileWrite; + +} + + + +int slsReceiverUDPFunctions::enableOverwrite(int i){ + if(i!=-1){ + if(myDetectorType == EIGER) + receiver->setEnableOverwrite(i); + else + overwrite=i; + + } + if(myDetectorType == EIGER) + return receiver->getEnableOverwrite(); + else + return overwrite; + +} + + + + +/*other parameters*/ + +slsReceiverDefs::runStatus slsReceiverUDPFunctions::getStatus(){ + if(myDetectorType == EIGER) + return receiver->getStatus(); + else + return status; +} + + +char* slsReceiverUDPFunctions::setDetectorHostname(char c[]){ + if(strlen(c)){ + if(myDetectorType == EIGER){ + if(receiver->getDetectorHostname()== NULL) + receiver->initialize(c); + }else + strcpy(detHostname,c); + } + + if(myDetectorType == EIGER) + return receiver->getDetectorHostname(); + else + return detHostname; +} + + +void slsReceiverUDPFunctions::setEthernetInterface(char* c){ + strcpy(eth,c); +} + + +void slsReceiverUDPFunctions::setUDPPortNo(int p){ + server_port = p; +} + + +int32_t slsReceiverUDPFunctions::setNumberOfFrames(int32_t fnum){ + if(fnum >= 0){ + if(myDetectorType == EIGER) + receiver->setNumberOfFrames(fnum); + else + numberOfFrames = fnum; + } + + if(myDetectorType == EIGER) + return receiver->getNumberOfFrames(); + else + return numberOfFrames; +} + +int32_t slsReceiverUDPFunctions::setScanTag(int32_t stag){ + if(stag >= 0){ + if(myDetectorType == EIGER) + receiver->setScanTag(stag); + else + scanTag = stag; + } + + if(myDetectorType == EIGER) + return receiver->getScanTag(); + else + return scanTag; +} + +int32_t slsReceiverUDPFunctions::setDynamicRange(int32_t dr){ + if(dr >= 0){ + if(myDetectorType == EIGER) + receiver->setDynamicRange(dr); + else + dynamicRange = dr; + } + + if(myDetectorType == EIGER) + return receiver->getDynamicRange(); + else + return dynamicRange; +} + + + +int slsReceiverUDPFunctions::setShortFrame(int i){ + shortFrame=i; + + if(shortFrame!=-1){ + bufferSize = GOTTHARD_SHORT_BUFFER_SIZE; + maxPacketsPerFile = SHORT_MAX_FRAMES_PER_FILE * GOTTHARD_SHORT_PACKETS_PER_FRAME; + packetsPerFrame = GOTTHARD_SHORT_PACKETS_PER_FRAME; + frameIndexMask = GOTTHARD_SHORT_FRAME_INDEX_MASK; + frameIndexOffset = GOTTHARD_SHORT_FRAME_INDEX_OFFSET; + + }else{ + bufferSize = GOTTHARD_BUFFER_SIZE; + maxPacketsPerFile = MAX_FRAMES_PER_FILE * GOTTHARD_PACKETS_PER_FRAME; + packetsPerFrame = GOTTHARD_PACKETS_PER_FRAME; + frameIndexMask = GOTTHARD_FRAME_INDEX_MASK; + frameIndexOffset = GOTTHARD_FRAME_INDEX_OFFSET; + } + + onePacketSize = bufferSize/packetsPerFrame; + + deleteFilter(); + if(dataCompression) + setupFilter(); + + return shortFrame; +} + + +int slsReceiverUDPFunctions::setNFrameToGui(int i){ + if(i>=0){ + nFrameToGui = i; + setupFifoStructure(); + } + return nFrameToGui; +} + + + +int64_t slsReceiverUDPFunctions::setAcquisitionPeriod(int64_t index){ + + if(index >= 0){ + if(index != acquisitionPeriod){ + acquisitionPeriod = index; + if(myDetectorType != EIGER) + setupFifoStructure(); + } + } + return acquisitionPeriod; +} + + +bool slsReceiverUDPFunctions::getDataCompression(){return dataCompression;} + +int slsReceiverUDPFunctions::enableDataCompression(bool enable){ + cout << "Data compression "; + if(enable) + cout << "enabled" << endl; + else + cout << "disabled" << endl; +#ifdef MYROOT1 + cout << " WITH ROOT" << endl; +#else + cout << " WITHOUT ROOT" << endl; +#endif + //delete filter for the current number of threads + deleteFilter(); + + dataCompression = enable; + pthread_mutex_lock(&status_mutex); + writerthreads_mask = 0x0; + pthread_mutex_unlock(&(status_mutex)); + + createWriterThreads(true); + + if(enable) + numWriterThreads = MAX_NUM_WRITER_THREADS; + else + numWriterThreads = 1; + + if(createWriterThreads() == FAIL){ + cout << "ERROR: Could not create writer threads" << endl; + return FAIL; + } + setThreadPriorities(); + + + if(enable) + setupFilter(); + + return OK; +} + + + + + + + + + + + + +/*other functions*/ + + +void slsReceiverUDPFunctions::deleteFilter(){ + int i; + cmSub=NULL; + + for(i=0;i(receiverdata[i], csize, sigma, sign, cmSub); + +} + + + + +void slsReceiverUDPFunctions::setupFifoStructure(){ + int64_t i; + int oldn = numJobsPerThread; + + //if every nth frame mode + if(nFrameToGui) + numJobsPerThread = nFrameToGui; + + //random nth frame mode + else{ + if(!acquisitionPeriod) + i = SAMPLE_TIME_IN_NS; + else + i = SAMPLE_TIME_IN_NS/acquisitionPeriod; + if (i > MAX_JOBS_PER_THREAD) + numJobsPerThread = MAX_JOBS_PER_THREAD; + else if (i < 1) + numJobsPerThread = 1; + else + numJobsPerThread = i; + } + + //if same, return + if(oldn == numJobsPerThread) + return; + + + //otherwise memory too much if numjobsperthread is at max = 1000 + fifosize = GOTTHARD_FIFO_SIZE; + if(myDetectorType == MOENCH) + fifosize = MOENCH_FIFO_SIZE; + + if(fifosize % numJobsPerThread) + fifosize = (fifosize/numJobsPerThread)+1; + else + fifosize = fifosize/numJobsPerThread; + + + cout << "Number of Frames per buffer:" << numJobsPerThread << endl; + cout << "Fifo Size:" << fifosize << endl; + + /* + //for testing + numJobsPerThread = 3; fifosize = 11; + */ + + //deleting old structure and creating fifo structure + if(fifoFree){ + while(!fifoFree->isEmpty()) + fifoFree->pop(buffer); + delete fifoFree; + } + if(fifo) delete fifo; + if(mem0) free(mem0); + fifoFree = new CircularFifo(fifosize); + fifo = new CircularFifo(fifosize); + + + //allocate memory + mem0=(char*)malloc((bufferSize * numJobsPerThread + HEADER_SIZE_NUM_TOT_PACKETS)*fifosize); + /** shud let the client know about this */ + if (mem0==NULL){ + cout<<"++++++++++++++++++++++ COULD NOT ALLOCATE MEMORY FOR LISTENING !!!!!!!+++++++++++++++++++++" << endl; + exit(-1); + } + buffer=mem0; + //push the addresses into freed fifoFree and writingFifoFree + while (buffer<(mem0+(bufferSize * numJobsPerThread + HEADER_SIZE_NUM_TOT_PACKETS)*(fifosize-1))) { + fifoFree->push(buffer); + buffer+=(bufferSize * numJobsPerThread + HEADER_SIZE_NUM_TOT_PACKETS); + } + + cout << "Fifo structure reconstructed" << endl; +} + + + + + + + +/** acquisition functions */ + +void slsReceiverUDPFunctions::readFrame(char* c,char** raw){ + //point to gui data + if (guiData == NULL) + guiData = latestData; + + //copy data and filename + strcpy(c,guiFileName); + + //could not get gui data + if(!guiDataReady){ + *raw = NULL; + } + //data ready, set guidata to receive new data + else{ + *raw = guiData; + guiData = NULL; + + pthread_mutex_lock(&dataReadyMutex); + guiDataReady = 0; + pthread_mutex_unlock(&dataReadyMutex); + if((nFrameToGui) && (writerthreads_mask)){ + //release after getting data + sem_post(&smp); + } + } +} + + + + + +void slsReceiverUDPFunctions::copyFrameToGui(char* startbuf){ + + //random read when gui not ready + if((!nFrameToGui) && (!guiData)){ + pthread_mutex_lock(&dataReadyMutex); + guiDataReady=0; + pthread_mutex_unlock(&dataReadyMutex); + } + + //random read or nth frame read, gui needs data now + else{ + //nth frame read, block current process if the guireader hasnt read it yet + if(nFrameToGui) + sem_wait(&smp); + + pthread_mutex_lock(&dataReadyMutex); + guiDataReady=0; + //send the first one + memcpy(latestData,startbuf,bufferSize); + strcpy(guiFileName,savefilename); + guiDataReady=1; + pthread_mutex_unlock(&dataReadyMutex); + } +} + + + + + +int slsReceiverUDPFunctions::createUDPSocket(){ + + if(udpSocket) + udpSocket->ShutDownSocket(); + + //if eth is mistaken with ip address + if (strchr(eth,'.')!=NULL) + strcpy(eth,""); + + if(udpSocket){delete udpSocket; udpSocket = NULL;} + + //if no eth, listen to all + if(!strlen(eth)){ + cout<<"warning:eth is empty.listening to all"<getErrorStatus(); + if (iret){ +#ifdef VERBOSE + cout << "Could not create UDP socket on port " << server_port << " error:" << iret << endl; +#endif + + return FAIL; + } + return OK; +} + + + + +int slsReceiverUDPFunctions::createListeningThreads(bool destroy){ + void* status; + + killListeningThread = 0; + + pthread_mutex_lock(&status_mutex); + listening_thread_running = 0; + pthread_mutex_unlock(&(status_mutex)); + + if(!destroy){ + //listening thread + cout << "Creating Listening Thread" << endl; + sem_init(&listensmp,1,0); + if(pthread_create(&listening_thread, NULL,startListeningThread, (void*) this)){ + cout << "Could not create listening thread" << endl; + return FAIL; + } +#ifdef VERBOSE + cout << "Listening thread created successfully." << endl; +#endif + }else{ + cout<<"Destroying Listening Thread"<initEventTree(temp, &iframe); + //resets the pedestalSubtraction array and the commonModeSubtraction + singlePhotonDet[ithr]->newDataSet(); + if(myFile[ithr]==NULL){ + cout<<"file null"<IsOpen()){ + cout<<"file not open"< DO_NOTHING){ + //close + if(sfilefd){ + fclose(sfilefd); + sfilefd = NULL; + } + //open file + if(!overwrite){ + if (NULL == (sfilefd = fopen((const char *) (savefilename), "wx"))){ + cout << "Error: Could not create new file " << savefilename << endl; + return FAIL; + } + }else if (NULL == (sfilefd = fopen((const char *) (savefilename), "w"))){ + cout << "Error: Could not create file " << savefilename << endl; + return FAIL; + } + //setting buffer + setvbuf(sfilefd,NULL,_IOFBF,BUF_SIZE); + + //printing packet losses and file names + if(!packetsCaught) + cout << savefilename << endl; + else{ + cout << savefilename + << "\tpacket loss " + << setw(4)<GetCurrentFile(); + + if(myFile[ithr]->Write()) + //->Write(tall->GetName(),TObject::kOverwrite); + cout << "Thread " << ithr <<": wrote frames to file" << endl; + else + cout << "Thread " << ithr << ": could not write frames to file" << endl; + + }else + cout << "Thread " << ithr << ": could not write frames to file: No file or No Tree" << endl; + //close file + if(myTree[ithr] && myFile[ithr]) + myFile[ithr] = myTree[ithr]->GetCurrentFile(); + if(myFile[ithr] != NULL) + myFile[ithr]->Close(); + myFile[ithr] = NULL; + myTree[ithr] = NULL; + pthread_mutex_unlock(&write_mutex); + +#endif + } +} + + + + + +int slsReceiverUDPFunctions::startReceiver(char message[]){ + + if(myDetectorType == EIGER) + return receiver->startReceiver(message); + + +// #ifdef VERBOSE + cout << "Starting Receiver" << endl; +//#endif + + + //reset listening thread variables + measurementStarted = false; + startFrameIndex = 0; + totalListeningFrameCount = 0; + + //udp socket + if(createUDPSocket() == FAIL){ + strcpy(message,"Could not create UDP Socket.\n"); + cout << endl << message << endl; + return FAIL; + } + cout << "UDP socket created successfully on port " << server_port << endl; + + + if(setupWriter() == FAIL){ + //stop udp socket + if(udpSocket) + udpSocket->ShutDownSocket(); + + sprintf(message,"Could not create file %s.\n",savefilename); + return FAIL; + } + cout << "Successfully created file(s)" << endl; + + //done to give the gui some proper name instead of always the last file name + if(dataCompression) + sprintf(savefilename, "%s/%s_fxxx_%d_xx.root", filePath,fileName,fileIndex); + + //initialize semaphore + sem_init(&smp,1,0); + + //status + pthread_mutex_lock(&status_mutex); + status = RUNNING; + for(int i=0;istopReceiver(); + + +//#ifdef VERBOSE + cout << "Stopping Receiver" << endl; +//#endif + + if(status == RUNNING) + startReadout(); + + while(status == TRANSMITTING) + usleep(5000); + + //semaphore destroy + sem_post(&smp); + sem_destroy(&smp); + + //change status + pthread_mutex_lock(&status_mutex); + status = IDLE; + pthread_mutex_unlock(&(status_mutex)); + + cout << "Receiver Stopped.\nStatus:" << status << endl; + return OK; +} + + + + + +void slsReceiverUDPFunctions::startReadout(){ + + if(myDetectorType == EIGER){ + receiver->stopReceiver(); + return; + } + + + //wait so that all packets which take time has arrived + usleep(50000); + + pthread_mutex_lock(&status_mutex); + status = TRANSMITTING; + pthread_mutex_unlock(&status_mutex); + cout << "Status: Transmitting" << endl; + + //kill udp socket to tell the listening thread to push last packet + if(udpSocket){ + udpSocket->ShutDownSocket(); + delete udpSocket; + udpSocket = NULL; + } + +} + + + +void* slsReceiverUDPFunctions::startListeningThread(void* this_pointer){ + ((slsReceiverUDPFunctions*)this_pointer)->startListening(); + + return this_pointer; +} + + + +void* slsReceiverUDPFunctions::startWritingThread(void* this_pointer){ + ((slsReceiverUDPFunctions*)this_pointer)->startWriting(); + return this_pointer; +} + + + + + + +int slsReceiverUDPFunctions::startListening(){ +#ifdef VERYVERBOSE + cout << "In startListening()" << endl; +#endif + + int lastpacketoffset, expected, rc, packetcount, maxBufferSize, carryonBufferSize; + uint32_t lastframeheader;// for moench to check for all the packets in last frame + char* tempchar = NULL; + + + while(1){ + //variables that need to be checked/set before each acquisition + carryonBufferSize = 0; + maxBufferSize = packetsPerFrame * numJobsPerThread * onePacketSize; + if(tempchar) {delete [] tempchar;tempchar = NULL;} + tempchar = new char[onePacketSize * (packetsPerFrame - 1)]; //gotthard: 1packet size, moench:39 packet size + + + while(listening_thread_running){ + + //pop + fifoFree->pop(buffer); +#ifdef VERYDEBUG + cout << "*** popped from fifo free" << (void*)buffer << endl; +#endif + + //receive + if(udpSocket == NULL) + rc = 0; + else if(!carryonBufferSize){ + rc = udpSocket->ReceiveDataOnly(buffer + HEADER_SIZE_NUM_TOT_PACKETS, maxBufferSize); + expected = maxBufferSize; + }else{ +#ifdef VERYDEBUG + cout << "***carry on buffer" << carryonBufferSize << endl; + cout<<"framennum in temochar:"<<((((uint32_t)(*((uint32_t*)tempchar))) + & (frameIndexMask)) >> frameIndexOffset)<ReceiveDataOnly((buffer + HEADER_SIZE_NUM_TOT_PACKETS + carryonBufferSize),maxBufferSize - carryonBufferSize); + expected = maxBufferSize - carryonBufferSize; + } + +#ifdef VERYDEBUG + cout << "*** rc:" << dec << rc << endl; + cout << "*** expected:" << dec << expected << endl; +#endif + //start indices + //start of scan + if((!measurementStarted) && (rc > 0)){ + //gotthard has +1 for frame number + if ((myDetectorType == GOTTHARD) && (shortFrame == -1)) + startFrameIndex = (((((uint32_t)(*((uint32_t*)(buffer + HEADER_SIZE_NUM_TOT_PACKETS))))+1) + & (frameIndexMask)) >> frameIndexOffset); + else + startFrameIndex = ((((uint32_t)(*((uint32_t*)(buffer+HEADER_SIZE_NUM_TOT_PACKETS)))) + & (frameIndexMask)) >> frameIndexOffset); + cout<<"startFrameIndex:"<push(buffer); + exit(-1); + continue; + } + //push the last buffer into fifo + if(rc > 0){ + packetcount = (rc/onePacketSize); +#ifdef VERYDEBUG + cout << "*** last packetcount:" << packetcount << endl; +#endif + (*((uint16_t*)(buffer))) = packetcount; + totalListeningFrameCount += packetcount; + while(!fifo->push(buffer)); +#ifdef VERYDEBUG + cout << "*** last lbuf1:" << (void*)buffer << endl; +#endif + } + + + //push dummy buffer + for(int i=0;ipop(buffer); + (*((uint16_t*)(buffer))) = 0xFFFF; + while(!fifo->push(buffer)); +#ifdef VERYDEBUG + cout << "pushed in dummy buffer:" << (void*)buffer << endl; +#endif + } + cout << "Total count listened to " << totalListeningFrameCount/packetsPerFrame << endl; + pthread_mutex_lock(&status_mutex); + listening_thread_running = 0; + pthread_mutex_unlock(&(status_mutex)); + break; + } + + + //reset + packetcount = packetsPerFrame * numJobsPerThread; + carryonBufferSize = 0; + + + //check if last packet valid and calculate packet count + switch(myDetectorType){ + + + + case MOENCH: + lastpacketoffset = (((numJobsPerThread * packetsPerFrame - 1) * onePacketSize) + HEADER_SIZE_NUM_TOT_PACKETS); +#ifdef VERYDEBUG + cout <<"first packet:"<< ((((uint32_t)(*((uint32_t*)(buffer+HEADER_SIZE_NUM_TOT_PACKETS))))) & (packetIndexMask)) << endl; + cout <<"first header:"<< (((((uint32_t)(*((uint32_t*)(buffer+HEADER_SIZE_NUM_TOT_PACKETS))))) & (frameIndexMask)) >> frameIndexOffset) << endl; + cout << "last packet offset:" << lastpacketoffset << endl; + cout <<"last packet:"<< ((((uint32_t)(*((uint32_t*)(buffer+lastpacketoffset))))) & (packetIndexMask)) << endl; + cout <<"last header:"<< (((((uint32_t)(*((uint32_t*)(buffer+lastpacketoffset))))) & (frameIndexMask)) >> frameIndexOffset) << endl; +#endif + //moench last packet value is 0 + if( ((((uint32_t)(*((uint32_t*)(buffer+lastpacketoffset))))) & (packetIndexMask))){ + lastframeheader = ((((uint32_t)(*((uint32_t*)(buffer+lastpacketoffset))))) & (frameIndexMask)) >> frameIndexOffset; + carryonBufferSize += onePacketSize; + lastpacketoffset -= onePacketSize; + --packetcount; + while (lastframeheader == (((((uint32_t)(*((uint32_t*)(buffer+lastpacketoffset))))) & (frameIndexMask)) >> frameIndexOffset)){ + carryonBufferSize += onePacketSize; + lastpacketoffset -= onePacketSize; + --packetcount; + } + memcpy(tempchar, buffer+(lastpacketoffset+onePacketSize), carryonBufferSize); +#ifdef VERYDEBUG + cout << "tempchar header:" << (((((uint32_t)(*((uint32_t*)(tempchar))))) + & (frameIndexMask)) >> frameIndexOffset) << endl; + cout <<"tempchar packet:"<< ((((uint32_t)(*((uint32_t*)(tempchar))))) + & (packetIndexMask)) << endl; +#endif + } + break; + + + + default: + if(shortFrame == -1){ + lastpacketoffset = (((numJobsPerThread * packetsPerFrame - 1) * onePacketSize) + HEADER_SIZE_NUM_TOT_PACKETS); +#ifdef VERYDEBUG + cout << "last packet offset:" << lastpacketoffset << endl; +#endif + + if((unsigned int)(packetsPerFrame -1) != ((((uint32_t)(*((uint32_t*)(buffer+lastpacketoffset))))+1) & (packetIndexMask))){ + memcpy(tempchar,buffer+lastpacketoffset, onePacketSize); +#ifdef VERYDEBUG + cout << "tempchar header:" << (((((uint32_t)(*((uint32_t*)(tempchar))))+1) + & (frameIndexMask)) >> frameIndexOffset) << endl; +#endif + carryonBufferSize = onePacketSize; + --packetcount; + } + } +#ifdef VERYDEBUG + cout << "header:" << (((((uint32_t)(*((uint32_t*)(buffer + HEADER_SIZE_NUM_TOT_PACKETS))))+1) + & (frameIndexMask)) >> frameIndexOffset) << endl; +#endif + break; + + + + + } +#ifdef VERYDEBUG + cout << "*** packetcount:" << packetcount << " carryonbuffer:" << carryonBufferSize << endl; +#endif + //write packet count and push + (*((uint16_t*)(buffer))) = packetcount; + totalListeningFrameCount += packetcount; + while(!fifo->push(buffer)); +#ifdef VERYDEBUG + cout << "*** pushed into listening fifo" << endl; +#endif + } + + sem_wait(&listensmp); + + //make sure its not exiting thread + if(killListeningThread) + pthread_exit(NULL); + } + + return OK; +} + + + + + + + + + + + + + + + +int slsReceiverUDPFunctions::startWriting(){ + int ithread = currentWriterThreadIndex; +#ifdef VERYVERBOSE + cout << ithread << "In startWriting()" <pop(wbuf); + numpackets = (uint16_t)(*((uint16_t*)wbuf)); +#ifdef VERYDEBUG + cout << ithread << " numpackets:" << dec << numpackets << endl; + cout << ithread << " *** popped from fifo " << numpackets << endl; +#endif + + + + + + + //last dummy packet + if(numpackets == 0xFFFF){ +#ifdef VERYDEBUG + cout << ithread << " **********************popped last dummy frame:" << (void*)wbuf << endl; +#endif + + //free fifo + while(!fifoFree->push(wbuf)); +#ifdef VERYDEBUG + cout << ithread << " fifo freed:" << (void*)wbuf << endl; +#endif + + + + //all threads need to close file, reset mask and exit loop + closeFile(ithread); + pthread_mutex_lock(&status_mutex); + writerthreads_mask^=(1<> frameIndexOffset); + else + tempframenum = ((((uint32_t)(*((uint32_t*)(wbuf + HEADER_SIZE_NUM_TOT_PACKETS))))& (frameIndexMask)) >> frameIndexOffset); + + if(numWriterThreads == 1) + currframenum = tempframenum; + else{ + pthread_mutex_lock(&progress_mutex); + if(tempframenum > currframenum) + currframenum = tempframenum; + pthread_mutex_unlock(&progress_mutex); + } +#ifdef VERYDEBUG + cout << ithread << " tempframenum:" << dec << tempframenum << " curframenum:" << currframenum << endl; +#endif + + + + + + //without datacompression: write datacall back, or write data, free fifo + if(!dataCompression){ + if (cbAction < DO_EVERYTHING) + rawDataReadyCallBack(currframenum, wbuf, numpackets * onePacketSize, sfilefd, guiData,pRawDataReady); + else if (numpackets > 0){ + writeToFile_withoutCompression(wbuf, numpackets); + } + //copy to gui + copyFrameToGui(wbuf + HEADER_SIZE_NUM_TOT_PACKETS); + + while(!fifoFree->push(wbuf)); +#ifdef VERYVERBOSE + cout<<"buf freed:"<<(void*)wbuf<findNextFrame(data,ndata,remainingsize)){ + np = ndata/onePacketSize; + + //cout<<"buff framnum:"<> frameIndexOffset)<newFrame(); + + //only for moench + if(commonModeSubtractionEnable){ + for(ix = xmin - 1; ix < xmax+1; ix++){ + for(iy = ymin - 1; iy < ymax+1; iy++){ + thisEvent = singlePhotonDet[ithread]->getEventType(buff, ix, iy, 0); + } + } + } + + + for(ix = xmin - 1; ix < xmax+1; ix++) + for(iy = ymin - 1; iy < ymax+1; iy++){ + thisEvent=singlePhotonDet[ithread]->getEventType(buff, ix, iy, commonModeSubtractionEnable); + if (nf>1000) { + tot=0; + tl=0; + tr=0; + bl=0; + br=0; + if (thisEvent==PHOTON_MAX) { + + iFrame=receiverdata[ithread]->getFrameNumber(buff); +#ifdef MYROOT1 + myTree[ithread]->Fill(); + //cout << "Fill in event: frmNr: " << iFrame << " ix " << ix << " iy " << iy << " type " << thisEvent << endl; +#else + pthread_mutex_lock(&write_mutex); + if((enableFileWrite) && (sfilefd)) + singlePhotonDet[ithread]->writeCluster(sfilefd); + pthread_mutex_unlock(&write_mutex); +#endif + } + } + } + + nf++; +#ifndef ALLFILE + pthread_mutex_lock(&progress_mutex); + packetsInFile += packetsPerFrame; + packetsCaught += packetsPerFrame; + totalPacketsCaught += packetsPerFrame; + if(packetsInFile >= maxPacketsPerFile) + createNewFile(); + pthread_mutex_unlock(&progress_mutex); + +#endif + if(!once){ + copyFrameToGui(buff); + once = 1; + } + } + + remainingsize -= ((buff + ndata) - data); + data = buff + ndata; + if(data > (wbuf + HEADER_SIZE_NUM_TOT_PACKETS + numpackets * onePacketSize) ) + cout <<" **************ERROR SHOULD NOT COME HERE, Error 142536!"<push(wbuf)); +#ifdef VERYVERBOSE + cout<<"buf freed:"<<(void*)wbuf< 0){ + + //for progress and packet loss calculation(new files) + if ((myDetectorType == GOTTHARD) && (shortFrame == -1)) + tempframenum = (((((uint32_t)(*((uint32_t*)(buf + HEADER_SIZE_NUM_TOT_PACKETS))))+1)& (frameIndexMask)) >> frameIndexOffset); + else + tempframenum = ((((uint32_t)(*((uint32_t*)(buf + HEADER_SIZE_NUM_TOT_PACKETS))))& (frameIndexMask)) >> frameIndexOffset); + + if(numWriterThreads == 1) + currframenum = tempframenum; + else{ + if(tempframenum > currframenum) + currframenum = tempframenum; + } +#ifdef VERYDEBUG + cout << "tempframenum:" << dec << tempframenum << " curframenum:" << currframenum << endl; +#endif + + //lock + if(numWriterThreads > 1) + pthread_mutex_lock(&write_mutex); + + + //to create new file when max reached + packetsToSave = maxPacketsPerFile - packetsInFile; + if(packetsToSave > numpackets) + packetsToSave = numpackets; + + fwrite(buf+offset, 1, packetsToSave * onePacketSize, sfilefd); + packetsInFile += packetsToSave; + packetsCaught += packetsToSave; + totalPacketsCaught += packetsToSave; + + + //new file + if(packetsInFile >= maxPacketsPerFile){ + //for packet loss + lastpacket = (((packetsToSave - 1) * onePacketSize) + offset); + if ((myDetectorType == GOTTHARD) && (shortFrame == -1)) + tempframenum = (((((uint32_t)(*((uint32_t*)(buf + lastpacket))))+1)& (frameIndexMask)) >> frameIndexOffset); + else + tempframenum = ((((uint32_t)(*((uint32_t*)(buf + lastpacket))))& (frameIndexMask)) >> frameIndexOffset); + + if(numWriterThreads == 1) + currframenum = tempframenum; + else{ + if(tempframenum > currframenum) + currframenum = tempframenum; + } +#ifdef VERYDEBUG + cout << "tempframenum:" << dec << tempframenum << " curframenum:" << currframenum << endl; +#endif + //create + createNewFile(); + } + + //unlock + if(numWriterThreads > 1) + pthread_mutex_unlock(&write_mutex); + + + offset += (packetsToSave * onePacketSize); + numpackets -= packetsToSave; + } + + } + else{ + if(numWriterThreads > 1) + pthread_mutex_lock(&write_mutex); + packetsInFile += numpackets; + packetsCaught += numpackets; + totalPacketsCaught += numpackets; + if(numWriterThreads > 1) + pthread_mutex_unlock(&write_mutex); + } + + + +} + + +#endif diff --git a/slsReceiverSoftware/slsReceiver/slsReceiverUDPFunctions.h b/slsReceiverSoftware/slsReceiver/slsReceiverUDPFunctions.h new file mode 100644 index 000000000..c1408a12a --- /dev/null +++ b/slsReceiverSoftware/slsReceiver/slsReceiverUDPFunctions.h @@ -0,0 +1,685 @@ +#ifdef SLS_RECEIVER_UDP_FUNCTIONS +#ifndef SLS_RECEIVER_UDP_FUNCTIONS_H +#define SLS_RECEIVER_UDP_FUNCTIONS_H +/********************************************//** + * @file slsReceiverUDPFunctions.h + * @short does all the functions for a receiver, set/get parameters, start/stop etc. + ***********************************************/ + + +#include "sls_receiver_defs.h" +#include "receiver_defs.h" +#include "genericSocket.h" +#include "circularFifo.h" +#include "singlePhotonDetector.h" +#include "slsReceiverData.h" +#include "moenchCommonMode.h" +#include "eigerReceiver.h" + +#ifdef MYROOT1 +#include +#include +#endif + + +#include +#include +#include +#include + + +/** + * @short does all the functions for a receiver, set/get parameters, start/stop etc. + */ + +class slsReceiverUDPFunctions : private virtual slsReceiverDefs { + +public: + /** + * Constructor + */ + slsReceiverUDPFunctions(); + + /** + * Destructor + */ + virtual ~slsReceiverUDPFunctions(); + + /** + * delete and free member parameters + */ + void deleteMembers(); + + /** + * initialize member parameters + */ + void initializeMembers(); + + /** + * Set receiver type + * @param det detector type + * Returns success or FAIL + */ + int setDetectorType(detectorType det); + + + //Frame indices and numbers caught + /** + * Returns current Frame Index Caught for an entire acquisition (including all scans) + */ + uint32_t getAcquisitionIndex(); + + /** + * Returns if acquisition started + */ + bool getAcquistionStarted(); + + /** + * Returns Frames Caught for each real time acquisition (eg. for each scan) + */ + int getFramesCaught(); + + /** + * Returns Total Frames Caught for an entire acquisition (including all scans) + */ + int getTotalFramesCaught(); + + /** + * Returns the frame index at start of each real time acquisition (eg. for each scan) + */ + uint32_t getStartFrameIndex(); + + /** + * Returns current Frame Index for each real time acquisition (eg. for each scan) + */ + uint32_t getFrameIndex(); + + /** + * Returns if measurement started + */ + bool getMeasurementStarted(); + + /** + * Resets the Total Frames Caught + * This is how the receiver differentiates between entire acquisitions + * Returns 0 + */ + void resetTotalFramesCaught(); + + + + + //file parameters + /** + * Returns File Path + */ + char* getFilePath(); + + /** + * Set File Path + * @param c file path + */ + char* setFilePath(char c[]); + + /** + * Returns File Name + */ + char* getFileName(); + + /** + * Set File Name (without frame index, file index and extension) + * @param c file name + */ + char* setFileName(char c[]); + + /** + * Returns File Index + */ + int getFileIndex(); + + /** + * Set File Index + * @param i file index + */ + int setFileIndex(int i); + + /** + * Set Frame Index Needed + * @param i frame index needed + */ + int setFrameIndexNeeded(int i); + + /** + * Set enable file write + * @param i file write enable + * Returns file write enable + */ + int setEnableFileWrite(int i); + + /** + * Enable/disable overwrite + * @param i enable + * Returns enable over write + */ + int enableOverwrite(int i); + + + +//other parameters + + /** + * Returns status of receiver: idle, running or error + */ + runStatus getStatus(); + + /** + * Set detector hostname + * @param c hostname + */ + char* setDetectorHostname(char c[]); + + /** + * Set Ethernet Interface or IP to listen to + */ + void setEthernetInterface(char* c); + + /** + * Set UDP Port Number + */ + void setUDPPortNo(int p); + + /** + * set frame number if a positive number + */ + int32_t setNumberOfFrames(int32_t fnum); + + /** + * set scan tag if its is a positive number + */ + int32_t setScanTag(int32_t stag); + + /** + * set dynamic range if its is a positive number + */ + int32_t setDynamicRange(int32_t dr); + + /** + * Set short frame + * @param i if shortframe i=1 + */ + int setShortFrame(int i); + + /** + * Set the variable to send every nth frame to gui + * or if 0,send frame only upon gui request + */ + int setNFrameToGui(int i); + + /** set acquisition period if a positive number + */ + int64_t setAcquisitionPeriod(int64_t index); + + /** get data compression, by saving only hits + */ + bool getDataCompression(); + + /** enabl data compression, by saving only hits + /returns if failed + */ + int enableDataCompression(bool enable); + + + + + + +//other functions + + /** + * Returns the buffer-current frame read by receiver + * @param c pointer to current file name + * @param raw address of pointer, pointing to current frame to send to gui + */ + void readFrame(char* c,char** raw); + + /** + * Closes all files + * @param ithr thread index + */ + void closeFile(int ithr = -1); + + /** + * Starts Receiver - starts to listen for packets + * @param message is the error message if there is an error + * Returns success + */ + int startReceiver(char message[]); + + /** + * Stops Receiver - stops listening for packets + * Returns success + */ + int stopReceiver(); + + /** set status to transmitting and + * when fifo is empty later, sets status to run_finished + */ + void startReadout(); + + +private: + /** + * Deletes all the filter objects for single photon data + */ + void deleteFilter(); + + /** + * Constructs the filter for single photon data + */ + void setupFilter(); + + /** + * set up fifo according to the new numjobsperthread + */ + void setupFifoStructure (); + + /** + * Copy frames to gui + * uses semaphore for nth frame mode + */ + void copyFrameToGui(char* startbuf); + + /** + * creates udp socket + * \returns if success or fail + */ + int createUDPSocket(); + + /** + * create listening thread + * @param destroy is true to kill all threads and start again + */ + int createListeningThreads(bool destroy = false); + + /** + * create writer threads + * @param destroy is true to kill all threads and start again + */ + int createWriterThreads(bool destroy = false); + + /** + * set thread priorities + */ + void setThreadPriorities(); + + /** + * initializes variables and creates the first file + * also does the startAcquisitionCallBack + * \returns FAIL or OK + */ + int setupWriter(); + + /** + * Creates new tree and file for compression + * @param ithr thread number + * @param iframe frame number + *\returns OK for succces or FAIL for failure + */ + int createCompressionFile(int ithr, int iframe); + + /** + * Creates new file + *\returns OK for succces or FAIL for failure + */ + int createNewFile(); + + /** + * Static function - Thread started which listens to packets. + * Called by startReceiver() + * @param this_pointer pointer to this object + */ + static void* startListeningThread(void *this_pointer); + + /** + * Static function - Thread started which writes packets to file. + * Called by startReceiver() + * @param this_pointer pointer to this object + */ + static void* startWritingThread(void *this_pointer); + + /** + * Thread started which listens to packets. + * Called by startReceiver() + * + */ + int startListening(); + + /** + * Thread started which writes packets to file. + * Called by startReceiver() + * + */ + int startWriting(); + + + /** + * Writing to file without compression + * @param buf is the address of buffer popped out of fifo + * @param numpackets is the number of packets + */ + void writeToFile_withoutCompression(char* buf,int numpackets); + + + + + /** Eiger Receiver */ + EigerReceiver *receiver; + + /** detector type */ + detectorType myDetectorType; + + /** detector hostname */ + char detHostname[MAX_STR_LENGTH]; + + /** status of receiver */ + runStatus status; + + /** UDP Socket between Receiver and Detector */ + genericSocket* udpSocket; + + /** Server UDP Port*/ + int server_port; + + /** ethernet interface or IP to listen to */ + char *eth; + + /** max packets per file **/ + int maxPacketsPerFile; + + /** File write enable */ + int enableFileWrite; + + /** File over write enable */ + int overwrite; + + /** Complete File name */ + char savefilename[MAX_STR_LENGTH]; + + /** File Name without frame index, file index and extension*/ + char fileName[MAX_STR_LENGTH]; + + /** File Path */ + char filePath[MAX_STR_LENGTH]; + + /** File Index */ + int fileIndex; + + /** scan tag */ + int scanTag; + + /** if frame index required in file name */ + int frameIndexNeeded; + + /* Acquisition started */ + bool acqStarted; + + /* Measurement started */ + bool measurementStarted; + + /** Frame index at start of each real time acquisition (eg. for each scan) */ + uint32_t startFrameIndex; + + /** Actual current frame index of each time acquisition (eg. for each scan) */ + uint32_t frameIndex; + + /** Frames Caught for each real time acquisition (eg. for each scan) */ + int packetsCaught; + + /** Total packets caught for an entire acquisition (including all scans) */ + int totalPacketsCaught; + + /** Pckets currently in current file, starts new file when it reaches max */ + int packetsInFile; + + /** Frame index at start of an entire acquisition (including all scans) */ + uint32_t startAcquisitionIndex; + + /** Actual current frame index of an entire acquisition (including all scans) */ + uint32_t acquisitionIndex; + + /** number of packets per frame*/ + int packetsPerFrame; + + /** frame index mask */ + uint32_t frameIndexMask; + + /** packet index mask */ + uint32_t packetIndexMask; + + /** frame index offset */ + int frameIndexOffset; + + /** acquisition period */ + int64_t acquisitionPeriod; + + /** frame number */ + int32_t numberOfFrames; + + /** dynamic range */ + int dynamicRange; + + /** short frames */ + int shortFrame; + + /** current frame number */ + uint32_t currframenum; + + /** Previous Frame number from buffer */ + uint32_t prevframenum; + + /** buffer size can be 1286*2 or 518 or 1286*40 */ + int bufferSize; + + /** oen buffer size */ + int onePacketSize; + + /** latest data */ + char* latestData; + + /** gui data ready */ + int guiDataReady; + + /** points to the data to send to gui */ + char* guiData; + + /** points to the filename to send to gui */ + char* guiFileName; + + /** send every nth frame to gui or only upon gui request*/ + int nFrameToGui; + + /** fifo size */ + unsigned int fifosize; + + /** number of jobs per thread for data compression */ + int numJobsPerThread; + + /** memory allocated for the buffer */ + char *mem0; + + /** datacompression - save only hits */ + bool dataCompression; + + /** circular fifo to store addresses of data read */ + CircularFifo* fifo; + + /** circular fifo to store addresses of data already written and ready to be resued*/ + CircularFifo* fifoFree; + + /** Receiver buffer */ + char *buffer; + + /** max number of writer threads */ + const static int MAX_NUM_WRITER_THREADS = 15; + + /** number of writer threads */ + int numWriterThreads; + + /** to know if listening and writer threads created properly */ + int thread_started; + + /** current writer thread index*/ + int currentWriterThreadIndex; + + /** thread listening to packets */ + pthread_t listening_thread; + + /** thread writing packets */ + pthread_t writing_thread[MAX_NUM_WRITER_THREADS]; + + /** total frame count the listening thread has listened to */ + int totalListeningFrameCount; + + /** mask showing which threads are running */ + volatile uint32_t writerthreads_mask; + + /** mask showing which threads have created files*/ + volatile uint32_t createfile_mask; + + /** OK if file created was successful */ + int ret_createfile; + + /** 0 if listening thread is idle, 1 otherwise */ + int listening_thread_running; + + /** variable used to self terminate threads waiting for semaphores */ + int killListeningThread; + + /** variable used to self terminate threads waiting for semaphores */ + int killAllWritingThreads; + + + + +//semaphores + /** semaphore to synchronize writer and guireader threads */ + sem_t smp; + /** semaphore to synchronize listener thread */ + sem_t listensmp; + /** semaphore to synchronize writer threads */ + sem_t writersmp[MAX_NUM_WRITER_THREADS]; + + +//mutex + /** guiDataReady mutex */ + pthread_mutex_t dataReadyMutex; + + /** mutex for status */ + pthread_mutex_t status_mutex; + + /** mutex for progress variable currframenum */ + pthread_mutex_t progress_mutex; + + /** mutex for writing data to file */ + pthread_mutex_t write_mutex; + + /** File Descriptor */ + FILE *sfilefd; + + //filter + singlePhotonDetector *singlePhotonDet[MAX_NUM_WRITER_THREADS]; + slsReceiverData *receiverdata[MAX_NUM_WRITER_THREADS]; + moenchCommonMode *cmSub; + bool commonModeSubtractionEnable; + +#ifdef MYROOT1 + /** Tree where the hits are stored */ + TTree *myTree[MAX_NUM_WRITER_THREADS]; + + /** File where the tree is saved */ + TFile *myFile[MAX_NUM_WRITER_THREADS]; +#endif + + + + /** + callback arguments are + filepath + filename + fileindex + data size + + return value is + 0 callback takes care of open,close,write file + 1 callback writes file, we have to open, close it + 2 we open, close, write file, callback does not do anything + + */ + int (*startAcquisitionCallBack)(char*, char*,int, int, void*); + void *pStartAcquisition; + + /** + args to acquisition finished callback + total frames caught + + */ + void (*acquisitionFinishedCallBack)(int, void*); + void *pAcquisitionFinished; + + + /** + args to raw data ready callback are + framenum + datapointer + datasize in bytes + file descriptor + guidatapointer (NULL, no data required) + */ + void (*rawDataReadyCallBack)(int, char*, int, FILE*, char*, void*); + void *pRawDataReady; + + /** The action which decides what the user and default responsibilites to save data are + * 0 raw data ready callback takes care of open,close,write file + * 1 callback writes file, we have to open, close it + * 2 we open, close, write file, callback does not do anything */ + int cbAction; + + +public: + + + /** + callback arguments are + filepath + filename + fileindex + datasize + + return value is + 0 callback takes care of open,close,wrie file + 1 callback writes file, we have to open, close it + 2 we open, close, write file, callback does not do anything + */ + void registerCallBackStartAcquisition(int (*func)(char*, char*,int, int, void*),void *arg){startAcquisitionCallBack=func; pStartAcquisition=arg;}; + + /** + callback argument is + toatal frames caught + */ + void registerCallBackAcquisitionFinished(void (*func)(int, void*),void *arg){acquisitionFinishedCallBack=func; pAcquisitionFinished=arg;}; + + /** + args to raw data ready callback are + framenum + datapointer + datasize in bytes + file descriptor + guidatapointer (NULL, no data required) + */ + void registerCallBackRawDataReady(void (*func)(int, char*, int, FILE*, char*, void*),void *arg){rawDataReadyCallBack=func; pRawDataReady=arg;}; +}; + + +#endif + +#endif diff --git a/slsReceiverSoftware/slsReceiver/slsReceiverUsers.cpp b/slsReceiverSoftware/slsReceiver/slsReceiverUsers.cpp new file mode 100644 index 000000000..ce2001721 --- /dev/null +++ b/slsReceiverSoftware/slsReceiver/slsReceiverUsers.cpp @@ -0,0 +1,43 @@ +#include "slsReceiverUsers.h" +#include "slsReceiverTCPIPInterface.h" + +slsReceiverTCPIPInterface* slsReceiverUsers::receiver(NULL); + +slsReceiverUsers::slsReceiverUsers(int argc, char *argv[], int &success) { + slsReceiverUsers::receiver=new slsReceiverTCPIPInterface(argc, argv, success); +} + +slsReceiverUsers::~slsReceiverUsers() { + delete slsReceiverUsers::receiver; +} + +void slsReceiverUsers::start() { + slsReceiverUsers::receiver->start(); +} + + +void slsReceiverUsers::closeFile(int p) { + slsReceiverUsers::receiver->closeFile(p); +} + +int64_t slsReceiverUsers::getReceiverVersion(){ + slsReceiverUsers::receiver->get_version(); +} + + +void slsReceiverUsers::registerCallBackStartAcquisition(int (*func)(char*, char*,int, int, void*),void *arg){ + slsReceiverUsers::receiver->registerCallBackStartAcquisition(func,arg); +} + + + +void slsReceiverUsers::registerCallBackAcquisitionFinished(void (*func)(int, void*),void *arg){ + slsReceiverUsers::receiver->registerCallBackAcquisitionFinished(func,arg); +} + + +void slsReceiverUsers::registerCallBackRawDataReady(void (*func)(int, char*, int, FILE*, char*, void*),void *arg){ + slsReceiverUsers::receiver->registerCallBackRawDataReady(func,arg); +} + + diff --git a/slsReceiverSoftware/slsReceiver/slsReceiverUsers.h b/slsReceiverSoftware/slsReceiver/slsReceiverUsers.h new file mode 100644 index 000000000..aab02b699 --- /dev/null +++ b/slsReceiverSoftware/slsReceiver/slsReceiverUsers.h @@ -0,0 +1,85 @@ + +#ifndef SLS_RECEIVER_USERS_H +#define SLS_RECEIVER_USERS_H + +#include +#include + +class slsReceiverTCPIPInterface; + + /** +@short Class for implementing the SLS data receiver in the users application. Callbacks can be defined for processing and/or saving data + */ +/** + + + @libdoc slsReceiverUsers is a class that can be instantiated in the users software to receive the data from the detectors. Callbacks can be defined for processing and/or saving data + + + ***********************************************/ + +class slsReceiverUsers { + +public: + /** + * Constructor + * reads config file, creates socket, assigns function table + * @param argc from command line + * @param argv from command line + * @param succecc socket creation was successfull + */ + slsReceiverUsers(int argc, char *argv[], int &success); + + + /** Destructor */ + ~slsReceiverUsers(); + + /** Close File and exits receiver server */ + void closeFile(int p); + + /** starts listening on the TCP port for client comminication */ + void start(); + + /** + get get Receiver Version + \returns id + */ + int64_t getReceiverVersion(); + + /** + + @sort register calbback for starting the acquisition + \param func callback to be called when starting the acquisition. Its arguments are filepath filename fileindex data size + + \returns 0 callback takes care of open,close,write file; 1 callback writes file, we have to open, close it; 2 we open, close, write file, callback does not do anything + + */ + + void registerCallBackStartAcquisition(int (*func)(char* filepath, char* filename,int fileindex, int datasize, void*),void *arg); + + + /** + @sort register callback for end of acquisition + \param func end of acquisition callback. Argument nf is total frames caught + \returns nothing + */ + + + void registerCallBackAcquisitionFinished(void (*func)(int nf, void*),void *arg); + + + + /** + @sort register callback to be called when data are available (to process and/or save the data). + \param func raw data ready callback. arguments are framenum datapointer datasize file descriptor guidatapointer (NULL, no data required) + \returns nothing + */ + + void registerCallBackRawDataReady(void (*func)(int framenumber, char* datapointer, int datasize, FILE* filedescriptor, char* guidatapointer, void*),void *arg); + + // made static to close thread files with ctrl+c + static slsReceiverTCPIPInterface* receiver; +}; + + +#endif From af89269c0c94e7dc8a7ae0ad90e5d7f7275c2672 Mon Sep 17 00:00:00 2001 From: Maliakal Dhanya Date: Wed, 21 May 2014 10:41:33 +0200 Subject: [PATCH 002/474] ignoring binaries --- slsReceiverSoftware/.gitignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 slsReceiverSoftware/.gitignore diff --git a/slsReceiverSoftware/.gitignore b/slsReceiverSoftware/.gitignore new file mode 100644 index 000000000..5761abcfd --- /dev/null +++ b/slsReceiverSoftware/.gitignore @@ -0,0 +1 @@ +*.o From 567501c6f762e05450de2c59456cdce9fa89eced Mon Sep 17 00:00:00 2001 From: Maliakal Dhanya Date: Fri, 23 May 2014 14:50:11 +0200 Subject: [PATCH 003/474] included the stop receiver function for the users --- .../slsReceiver/slsReceiverTCPIPInterface.cpp | 14 ++++++- .../slsReceiver/slsReceiverTCPIPInterface.h | 39 ++++++++++--------- .../slsReceiver/slsReceiverUDPFunctions.cpp | 32 +++++++++------ .../slsReceiver/slsReceiverUDPFunctions.h | 5 +++ .../slsReceiver/slsReceiverUsers.cpp | 4 ++ .../slsReceiver/slsReceiverUsers.h | 3 ++ 6 files changed, 64 insertions(+), 33 deletions(-) diff --git a/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.cpp b/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.cpp index c3720ad05..2c9e9b5f4 100644 --- a/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.cpp +++ b/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.cpp @@ -31,6 +31,7 @@ slsReceiverTCPIPInterface::~slsReceiverTCPIPInterface() { slsReceiverTCPIPInterface::slsReceiverTCPIPInterface(int argc, char *argv[], int &success): myDetectorType(GOTTHARD), + slsReceiverFunctions(NULL), ret(OK), lockStatus(0), shortFrame(-1), @@ -168,7 +169,6 @@ slsReceiverTCPIPInterface::slsReceiverTCPIPInterface(int argc, char *argv[], int //Catch signal SIGINT to close files properly signal(SIGINT,staticCloseFile); - file_des=socket->getFileDes(); socketDescriptor=socket->getsocketDescriptor(); @@ -178,6 +178,7 @@ slsReceiverTCPIPInterface::slsReceiverTCPIPInterface(int argc, char *argv[], int } + void slsReceiverTCPIPInterface::start(){ int v=slsReceiverDefs::OK; @@ -203,9 +204,18 @@ void slsReceiverTCPIPInterface::start(){ #endif } } - +} +void slsReceiverTCPIPInterface::stop(){ + //shut down udp socket + if(slsReceiverFunctions) + slsReceiverFunctions->shutDownUDPSocket(); + //disconnect and delete socket + socket->Disconnect(); + delete socket; + //close file and exit + closeFile(0); } diff --git a/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.h b/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.h index b0cd6e780..75dc920a8 100644 --- a/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.h +++ b/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.h @@ -1,4 +1,4 @@ - /********************************************//** +/********************************************//** * @file slsReceiverTCPIPInterface.h * @short interface between receiver and client ***********************************************/ @@ -14,8 +14,8 @@ /** - *@short interface between receiver and client - */ + *@short interface between receiver and client + */ class slsReceiverTCPIPInterface : private virtual slsReceiverDefs { @@ -27,13 +27,14 @@ public: * @param argv from command line * @param succecc socket creation was successfull */ - slsReceiverTCPIPInterface(int argc, char *argv[], int &success); + slsReceiverTCPIPInterface(int argc, char *argv[], int &success); - - /** starts listening on the TCP port for client comminication */ - + /** starts listening on the TCP port for client comminication */ void start(); + /** stop listening on the TCP & UDP port for client comminication and exit receiver */ + void stop(); + /** Destructor */ virtual ~slsReceiverTCPIPInterface(); @@ -52,14 +53,14 @@ public: filename fileindex data size - + return value is 0 callback takes care of open,close,wrie file 1 callback writes file, we have to open, close it 2 we open, close, write file, callback does not do anything - */ - + */ + void registerCallBackStartAcquisition(int (*func)(char*, char*,int, int, void*),void *arg){slsReceiverFunctions->registerCallBackStartAcquisition(func,arg);};; @@ -67,11 +68,11 @@ public: callback argument is toatal farmes caught - */ - - + */ + + void registerCallBackAcquisitionFinished(void (*func)(int, void*),void *arg){slsReceiverFunctions->registerCallBackAcquisitionFinished(func,arg);}; - + /** @@ -81,12 +82,12 @@ public: datasize in bytes file descriptor guidatapointer (NULL, no data required) - */ - + */ + void registerCallBackRawDataReady(void (*func)(int, char*, int, FILE*, char*, void*),void *arg){slsReceiverFunctions->registerCallBackRawDataReady(func,arg);}; - private: +private: /** assigns functions to the fnum enum */ int function_table(); @@ -228,8 +229,8 @@ public: static int file_des; static int socketDescriptor; -//private: - protected: + //private: +protected: /** Socket */ MySocketTCP* socket; }; diff --git a/slsReceiverSoftware/slsReceiver/slsReceiverUDPFunctions.cpp b/slsReceiverSoftware/slsReceiver/slsReceiverUDPFunctions.cpp index 0b710f199..4fc0fabec 100644 --- a/slsReceiverSoftware/slsReceiver/slsReceiverUDPFunctions.cpp +++ b/slsReceiverSoftware/slsReceiver/slsReceiverUDPFunctions.cpp @@ -105,7 +105,7 @@ void slsReceiverUDPFunctions::deleteMembers(){ receiverdata[i] = NULL; } } - if(udpSocket) {delete udpSocket; udpSocket = NULL;} + shutDownUDPSocket(); if(eth) {delete [] eth; eth = NULL;} if(latestData) {delete [] latestData; latestData = NULL;} if(guiFileName) {delete [] guiFileName; guiFileName = NULL;} @@ -802,14 +802,11 @@ void slsReceiverUDPFunctions::copyFrameToGui(char* startbuf){ int slsReceiverUDPFunctions::createUDPSocket(){ - if(udpSocket) - udpSocket->ShutDownSocket(); - //if eth is mistaken with ip address if (strchr(eth,'.')!=NULL) strcpy(eth,""); - if(udpSocket){delete udpSocket; udpSocket = NULL;} + shutDownUDPSocket(); //if no eth, listen to all if(!strlen(eth)){ @@ -838,6 +835,22 @@ int slsReceiverUDPFunctions::createUDPSocket(){ + + + +int slsReceiverUDPFunctions::shutDownUDPSocket(){ + if(udpSocket){ + udpSocket->ShutDownSocket(); + delete udpSocket; + udpSocket = NULL; + } + return OK; +} + + + + + int slsReceiverUDPFunctions::createListeningThreads(bool destroy){ void* status; @@ -1224,8 +1237,7 @@ int slsReceiverUDPFunctions::startReceiver(char message[]){ if(setupWriter() == FAIL){ //stop udp socket - if(udpSocket) - udpSocket->ShutDownSocket(); + shutDownUDPSocket(); sprintf(message,"Could not create file %s.\n",savefilename); return FAIL; @@ -1312,11 +1324,7 @@ void slsReceiverUDPFunctions::startReadout(){ cout << "Status: Transmitting" << endl; //kill udp socket to tell the listening thread to push last packet - if(udpSocket){ - udpSocket->ShutDownSocket(); - delete udpSocket; - udpSocket = NULL; - } + shutDownUDPSocket(); } diff --git a/slsReceiverSoftware/slsReceiver/slsReceiverUDPFunctions.h b/slsReceiverSoftware/slsReceiver/slsReceiverUDPFunctions.h index c1408a12a..2029b3126 100644 --- a/slsReceiverSoftware/slsReceiver/slsReceiverUDPFunctions.h +++ b/slsReceiverSoftware/slsReceiver/slsReceiverUDPFunctions.h @@ -266,6 +266,11 @@ public: */ void startReadout(); + /** + * shuts down the udp socket + * \returns if success or fail + */ + int shutDownUDPSocket(); private: /** diff --git a/slsReceiverSoftware/slsReceiver/slsReceiverUsers.cpp b/slsReceiverSoftware/slsReceiver/slsReceiverUsers.cpp index ce2001721..7e97ef63f 100644 --- a/slsReceiverSoftware/slsReceiver/slsReceiverUsers.cpp +++ b/slsReceiverSoftware/slsReceiver/slsReceiverUsers.cpp @@ -15,6 +15,10 @@ void slsReceiverUsers::start() { slsReceiverUsers::receiver->start(); } +void slsReceiverUsers::stop() { + slsReceiverUsers::receiver->stop(); +} + void slsReceiverUsers::closeFile(int p) { slsReceiverUsers::receiver->closeFile(p); diff --git a/slsReceiverSoftware/slsReceiver/slsReceiverUsers.h b/slsReceiverSoftware/slsReceiver/slsReceiverUsers.h index aab02b699..a2b5502b6 100644 --- a/slsReceiverSoftware/slsReceiver/slsReceiverUsers.h +++ b/slsReceiverSoftware/slsReceiver/slsReceiverUsers.h @@ -40,6 +40,9 @@ public: /** starts listening on the TCP port for client comminication */ void start(); + /** stops listening to the TCP & UDP port and exit receiver program*/ + void stop(); + /** get get Receiver Version \returns id From 90f5fb39dba7dd1c787f374306ef29423ea7f8db Mon Sep 17 00:00:00 2001 From: Maliakal Dhanya Date: Fri, 23 May 2014 18:28:42 +0200 Subject: [PATCH 004/474] started receiver start on a separate thread and returns, whereas stop receiver will end udp, tcp socket and exit thread --- .../slsReceiver/slsReceiver.cpp | 49 +++++---- .../slsReceiver/slsReceiverTCPIPInterface.cpp | 104 +++++++++++++----- .../slsReceiver/slsReceiverTCPIPInterface.h | 31 +++++- .../slsReceiver/slsReceiverUsers.cpp | 4 +- .../slsReceiver/slsReceiverUsers.h | 7 +- 5 files changed, 137 insertions(+), 58 deletions(-) diff --git a/slsReceiverSoftware/slsReceiver/slsReceiver.cpp b/slsReceiverSoftware/slsReceiver/slsReceiver.cpp index 104fafad9..3513a26c7 100644 --- a/slsReceiverSoftware/slsReceiver/slsReceiver.cpp +++ b/slsReceiverSoftware/slsReceiver/slsReceiver.cpp @@ -5,6 +5,7 @@ #include "slsReceiverUsers.h" #include +#include using namespace std; @@ -13,15 +14,15 @@ using namespace std; int main(int argc, char *argv[]) { - int ret = slsReceiverDefs::OK; - - slsReceiverUsers *user = new slsReceiverUsers(argc, argv, ret); - - if(ret==slsReceiverDefs::FAIL) - return -1; - + int ret = slsReceiverDefs::OK; - //register callbacks + slsReceiverUsers *user = new slsReceiverUsers(argc, argv, ret); + + if(ret==slsReceiverDefs::FAIL) + return -1; + + + //register callbacks /** @@ -30,7 +31,7 @@ int main(int argc, char *argv[]) { filename fileindex datasize - + return value is 0 raw data ready callback takes care of open,close,write file 1 callback writes file, we have to open, close it @@ -38,8 +39,8 @@ int main(int argc, char *argv[]) { registerCallBackStartAcquisition(int (*func)(char*, char*,int, int, void*),void *arg); - */ - + */ + //receiver->registerCallBackStartAcquisition(func,arg); @@ -47,11 +48,11 @@ int main(int argc, char *argv[]) { callback argument is total farmes caught registerCallBackAcquisitionFinished(void (*func)(int, void*),void *arg); - */ - + */ + //receiver->registerCallBackAcquisitionFinished(func,arg); - + /** @@ -60,22 +61,30 @@ int main(int argc, char *argv[]) { datapointer file descriptor guidatapointer (NULL, no data required) - + NEVER DELETE THE DATA POINTER REMEMBER THAT THE CALLBACK IS BLOCKING registerCallBackRawDataReady(void (*func)(int, char*, FILE*, char*, void*),void *arg); - */ + */ //receiver->registerCallBackRawDataReady(func,arg); + //start tcp server thread + if(user->start() == slsReceiverDefs::OK){ + string str; + cin>>str; + //wait and look for an exit keyword + while(str.find("exit") == string::npos) + cin>>str; + //stop tcp server thread, stop udp socket + user->stop(); + } - user->start(); - - - return 0; + cout << "Goodbye!" << endl; + return 0; } diff --git a/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.cpp b/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.cpp index 2c9e9b5f4..244c685b1 100644 --- a/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.cpp +++ b/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.cpp @@ -19,8 +19,6 @@ using namespace std; -int slsReceiverTCPIPInterface::file_des(-1); -int slsReceiverTCPIPInterface::socketDescriptor(-1); slsReceiverTCPIPInterface::~slsReceiverTCPIPInterface() { @@ -36,7 +34,8 @@ slsReceiverTCPIPInterface::slsReceiverTCPIPInterface(int argc, char *argv[], int lockStatus(0), shortFrame(-1), packetsPerFrame(GOTTHARD_PACKETS_PER_FRAME), - socket(NULL){ + socket(NULL), + killTCPServerThread(0){ int port_no = DEFAULT_PORTNO+2; ifstream infile; @@ -169,21 +168,64 @@ slsReceiverTCPIPInterface::slsReceiverTCPIPInterface(int argc, char *argv[], int //Catch signal SIGINT to close files properly signal(SIGINT,staticCloseFile); - file_des=socket->getFileDes(); - socketDescriptor=socket->getsocketDescriptor(); - - //success = OK; } } } -void slsReceiverTCPIPInterface::start(){ +int slsReceiverTCPIPInterface::start(){ + cout << "Creating TCP Server Thread" << endl; + killTCPServerThread = 0; + if(pthread_create(&TCPServer_thread, NULL,startTCPServerThread, (void*) this)){ + cout << "Could not create TCP Server thread" << endl; + return FAIL; + } +#ifdef VERBOSE + cout << "TCP Server thread created successfully." << endl; +#endif + return OK; +} - int v=slsReceiverDefs::OK; - while(v!=GOODBYE) { +void slsReceiverTCPIPInterface::stop(){ + + cout << "Shutting down UDP Socket" << endl; + if(slsReceiverFunctions) + slsReceiverFunctions->shutDownUDPSocket(); + + cout << "Closing Files... " << endl; + slsReceiverFunctions->closeFile(); + + + cout<<"Shutting down TCP Socket and TCP thread"<ShutDownSocket(); + void* status; + pthread_join(TCPServer_thread, &status); + killTCPServerThread = 0; + +} + + + + + +void* slsReceiverTCPIPInterface::startTCPServerThread(void *this_pointer){ + ((slsReceiverTCPIPInterface*)this_pointer)->startTCPServer(); + return this_pointer; +} + + +void slsReceiverTCPIPInterface::startTCPServer(){ + + +#ifdef VERYVERBOSE + cout << "Starting Receiver TCP Server" << endl; +#endif + int v=slsReceiverDefs::OK; + + while(1) { #ifdef VERBOSE cout<< endl; #endif @@ -192,31 +234,39 @@ void slsReceiverTCPIPInterface::start(){ #endif if(socket->Connect()>=0){ #ifdef VERY_VERBOSE - cout << "Conenction accepted" << endl; + cout << "Conenction accepted" << endl; #endif - v = decode_function(); + v = decode_function(); #ifdef VERY_VERBOSE - cout << "function executed" << endl; + cout << "function executed" << endl; #endif - socket->Disconnect(); + socket->Disconnect(); #ifdef VERY_VERBOSE - cout << "connection closed" << endl; + cout << "connection closed" << endl; #endif } + + //if tcp command was to exit server + if(v==GOODBYE){ + cout << "Shutting down UDP Socket" << endl; + if(slsReceiverFunctions) + slsReceiverFunctions->shutDownUDPSocket(); + + cout << "Closing Files... " << endl; + slsReceiverFunctions->closeFile(); + + pthread_exit(NULL); + } + + //if user entered exit + if(killTCPServerThread) + pthread_exit(NULL); + } } -void slsReceiverTCPIPInterface::stop(){ - //shut down udp socket - if(slsReceiverFunctions) - slsReceiverFunctions->shutDownUDPSocket(); - //disconnect and delete socket - socket->Disconnect(); - delete socket; - //close file and exit - closeFile(0); -} + int slsReceiverTCPIPInterface::function_table(){ @@ -330,8 +380,7 @@ int slsReceiverTCPIPInterface::M_nofunc(){ void slsReceiverTCPIPInterface::closeFile(int p){ - cout<<"Closing Files... "<closeFile(); + stop(); cout << "Goodbye!" << endl; exit(-1); } @@ -1850,7 +1899,6 @@ int slsReceiverTCPIPInterface::set_port() { socket->Disconnect(); delete socket; socket = mySocket; - file_des=socket->getFileDes(); } } diff --git a/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.h b/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.h index 75dc920a8..cc0d48752 100644 --- a/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.h +++ b/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.h @@ -29,10 +29,13 @@ public: */ slsReceiverTCPIPInterface(int argc, char *argv[], int &success); - /** starts listening on the TCP port for client comminication */ - void start(); + /** + * Starts listening on the TCP port for client comminication + \returns OK or FAIL + */ + int start(); - /** stop listening on the TCP & UDP port for client comminication and exit receiver */ + /** stop listening on the TCP & UDP port for client comminication */ void stop(); /** Destructor */ @@ -88,6 +91,20 @@ public: private: + + /** + * Static function - Thread started which is a TCP server + * Called by start() + * @param this_pointer pointer to this object + */ + static void* startTCPServerThread(void *this_pointer); + + /** + * Thread started which is a TCP server + * Called by start() + */ + void startTCPServer(); + /** assigns functions to the fnum enum */ int function_table(); @@ -226,10 +243,12 @@ private: /** Packets per frame */ int packetsPerFrame; - static int file_des; - static int socketDescriptor; + /** kill tcp server thread */ + int killTCPServerThread; + + /** thread for TCP server */ + pthread_t TCPServer_thread; - //private: protected: /** Socket */ MySocketTCP* socket; diff --git a/slsReceiverSoftware/slsReceiver/slsReceiverUsers.cpp b/slsReceiverSoftware/slsReceiver/slsReceiverUsers.cpp index 7e97ef63f..f0e655f3c 100644 --- a/slsReceiverSoftware/slsReceiver/slsReceiverUsers.cpp +++ b/slsReceiverSoftware/slsReceiver/slsReceiverUsers.cpp @@ -11,8 +11,8 @@ slsReceiverUsers::~slsReceiverUsers() { delete slsReceiverUsers::receiver; } -void slsReceiverUsers::start() { - slsReceiverUsers::receiver->start(); +int slsReceiverUsers::start() { + return slsReceiverUsers::receiver->start(); } void slsReceiverUsers::stop() { diff --git a/slsReceiverSoftware/slsReceiver/slsReceiverUsers.h b/slsReceiverSoftware/slsReceiver/slsReceiverUsers.h index a2b5502b6..2dee1e151 100644 --- a/slsReceiverSoftware/slsReceiver/slsReceiverUsers.h +++ b/slsReceiverSoftware/slsReceiver/slsReceiverUsers.h @@ -37,8 +37,11 @@ public: /** Close File and exits receiver server */ void closeFile(int p); - /** starts listening on the TCP port for client comminication */ - void start(); + /** + * starts listening on the TCP port for client comminication + \return 0 for success or 1 for FAIL in creating TCP server + */ + int start(); /** stops listening to the TCP & UDP port and exit receiver program*/ void stop(); From d133d7eb8f46d1e641032d96aed7a195374bc6fa Mon Sep 17 00:00:00 2001 From: Maliakal Dhanya Date: Wed, 28 May 2014 18:06:00 +0200 Subject: [PATCH 005/474] some changes on the eiger receiver side --- slsReceiverSoftware/includes/receiver_defs.h | 38 +++++--- .../includes/sls_receiver_defs.h | 1 + slsReceiverSoftware/slsReceiver/Makefile | 2 +- .../slsReceiver/slsReceiverTCPIPInterface.cpp | 4 +- .../slsReceiver/slsReceiverUDPFunctions.cpp | 94 +++++++++++-------- 5 files changed, 86 insertions(+), 53 deletions(-) diff --git a/slsReceiverSoftware/includes/receiver_defs.h b/slsReceiverSoftware/includes/receiver_defs.h index 8dfbf7c99..42ee131a1 100755 --- a/slsReceiverSoftware/includes/receiver_defs.h +++ b/slsReceiverSoftware/includes/receiver_defs.h @@ -19,16 +19,24 @@ #define HEADER_SIZE_NUM_PACKETS 1 -//all max frames defined in sls_receiver_defs.h. 20000 gotthard, 100000 for short gotthard, 1000 for moench +//all max frames defined in sls_receiver_defs.h. 20000 gotthard, 100000 for short gotthard, 1000 for moench, eiger 20000 #define GOTTHARD_FIFO_SIZE 25000 //cannot be less than max jobs per thread = 1000 -/*#define GOTTHARD_ALIGNED_FRAME_SIZE 4096*/ +/*#define GOTTHARD_ALIGNED_FRAME_SIZE 4096*/ #define GOTTHARD_PACKETS_PER_FRAME 2 #define GOTTHARD_ONE_PACKET_SIZE 1286 #define GOTTHARD_BUFFER_SIZE (GOTTHARD_ONE_PACKET_SIZE*GOTTHARD_PACKETS_PER_FRAME) //1286*2 #define GOTTHARD_DATA_BYTES (1280*GOTTHARD_PACKETS_PER_FRAME) //1280*2 +#define GOTTHARD_FRAME_INDEX_MASK 0xFFFFFFFE +#define GOTTHARD_FRAME_INDEX_OFFSET 1 +#define GOTTHARD_PACKET_INDEX_MASK 0x1 + +#define GOTTHARD_PIXELS_IN_ROW 1280 +#define GOTTHARD_PIXELS_IN_COL 1 + + #define GOTTHARD_SHORT_PACKETS_PER_FRAME 1 #define GOTTHARD_SHORT_BUFFER_SIZE 518 #define GOTTHARD_SHORT_DATABYTES 512 @@ -39,13 +47,6 @@ #define GOTTHARD_SHORT_PIXELS_IN_COL 1 -#define GOTTHARD_FRAME_INDEX_MASK 0xFFFFFFFE -#define GOTTHARD_FRAME_INDEX_OFFSET 1 -#define GOTTHARD_PACKET_INDEX_MASK 0x1 - -#define GOTTHARD_PIXELS_IN_ROW 1280 -#define GOTTHARD_PIXELS_IN_COL 1 - #define MOENCH_FIFO_SIZE 2500 //cannot be less than max jobs per thread = 1000 @@ -55,18 +56,29 @@ #define MOENCH_BUFFER_SIZE (MOENCH_ONE_PACKET_SIZE*MOENCH_PACKETS_PER_FRAME) //1286*40 #define MOENCH_DATA_BYTES (1280*MOENCH_PACKETS_PER_FRAME) //1280*40 +#define MOENCH_FRAME_INDEX_MASK 0xFFFFFF00 +#define MOENCH_FRAME_INDEX_OFFSET 8 +#define MOENCH_PACKET_INDEX_MASK 0xFF + #define MOENCH_BYTES_PER_ADC (40*2) #define MOENCH_PIXELS_IN_ONE_ROW 160 #define MOENCH_BYTES_IN_ONE_ROW (MOENCH_PIXELS_IN_ONE_ROW*2) -#define MOENCH_FRAME_INDEX_MASK 0xFFFFFF00 -#define MOENCH_FRAME_INDEX_OFFSET 8 -#define MOENCH_PACKET_INDEX_MASK 0xFF +#define EIGER_FIFO_SIZE 2500 //cannot be less than max jobs per thread = 1000 +/*#define EIGER_ALIGNED_FRAME_SIZE 65536*/ +#define EIGER_PACKETS_PER_FRAME 1 //default for 16B +#define EIGER_ONE_PACKET_SIZE 1040 //default for 16B +#define EIGER_BUFFER_SIZE (EIGER_ONE_PACKET_SIZE*EIGER_PACKETS_PER_FRAME) //1040*1 //default for 16B +#define EIGER_DATA_BYTES (1032*EIGER_PACKETS_PER_FRAME) //1280*40 //default for 16B + +#define EIGER_FRAME_INDEX_MASK 0xFFFFFF00 +#define EIGER_FRAME_INDEX_OFFSET 8 +#define EIGER_PACKET_INDEX_MASK 0xFF + -//#define THIS_SOFTWARE_VERSION 0x20120919 #endif diff --git a/slsReceiverSoftware/includes/sls_receiver_defs.h b/slsReceiverSoftware/includes/sls_receiver_defs.h index c4c1fc63e..70fc6ece8 100755 --- a/slsReceiverSoftware/includes/sls_receiver_defs.h +++ b/slsReceiverSoftware/includes/sls_receiver_defs.h @@ -19,6 +19,7 @@ typedef int int32_t; #define MAX_FRAMES_PER_FILE 20000 #define SHORT_MAX_FRAMES_PER_FILE 100000 #define MOENCH_MAX_FRAMES_PER_FILE 1000 +#define EIGER_MAX_FRAMES_PER_FILE 20000 /** diff --git a/slsReceiverSoftware/slsReceiver/Makefile b/slsReceiverSoftware/slsReceiver/Makefile index 0fd416ca0..92428c957 100644 --- a/slsReceiverSoftware/slsReceiver/Makefile +++ b/slsReceiverSoftware/slsReceiver/Makefile @@ -40,7 +40,7 @@ $(DESTDIR)/sslsReceiver: lib $(DESTDIR)/slsReceiver: eigerReceiver lib - $(CXX) -o $@ $(SRC_CLNT) $(FLAGS) $(INCLUDES) $(CLAGS) $(LIBS) $(LDFLAGRXR) -fPIC + $(CXX) -o $@ $(SRC_CLNT) $(FLAGS) $(INCLUDES) $(CLAGS) $(LIBS) $(LDFLAGRXR) -fPIC #$(EIGERFLAGS) diff --git a/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.cpp b/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.cpp index 244c685b1..74c12dbca 100644 --- a/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.cpp +++ b/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.cpp @@ -798,9 +798,9 @@ int slsReceiverTCPIPInterface::start_receiver(){ // send answer socket->SendDataOnly(&ret,sizeof(ret)); - if(ret==FAIL) + if(ret==FAIL){ socket->SendDataOnly(mess,sizeof(mess)); - cout<<"ret of start receiver:"<setFileName(fileName); - } +#endif - onePacketSize = bufferSize/packetsPerFrame; + } latestData = new char[bufferSize]; @@ -322,7 +336,7 @@ void slsReceiverUDPFunctions::resetTotalFramesCaught(){ /*file parameters*/ char* slsReceiverUDPFunctions::getFilePath(){ - if(myDetectorType == EIGER) + if(receiver != NULL) return receiver->getFilePath(); else return filePath; @@ -333,7 +347,7 @@ char* slsReceiverUDPFunctions::setFilePath(char c[]){ //check if filepath exists struct stat st; if(stat(c,&st) == 0){ - if(myDetectorType == EIGER) + if(receiver != NULL) receiver->setFilePath(c); else strcpy(filePath,c); @@ -347,7 +361,7 @@ char* slsReceiverUDPFunctions::setFilePath(char c[]){ char* slsReceiverUDPFunctions::getFileName(){ - if(myDetectorType == EIGER) + if(receiver != NULL) return receiver->getFileName(); else return fileName; @@ -355,7 +369,7 @@ char* slsReceiverUDPFunctions::getFileName(){ char* slsReceiverUDPFunctions::setFileName(char c[]){ if(strlen(c)){ - if(myDetectorType == EIGER) + if(receiver != NULL) receiver->setFileName(c); else strcpy(fileName,c); @@ -385,13 +399,13 @@ int slsReceiverUDPFunctions::setFrameIndexNeeded(int i){ int slsReceiverUDPFunctions::setEnableFileWrite(int i){ if(i!=-1){ - if(myDetectorType == EIGER) + if(receiver != NULL) receiver->setEnableFileWrite(i); else enableFileWrite=i; } - if(myDetectorType == EIGER) + if(receiver != NULL) return receiver->getEnableFileWrite(); else return enableFileWrite; @@ -402,13 +416,13 @@ int slsReceiverUDPFunctions::setEnableFileWrite(int i){ int slsReceiverUDPFunctions::enableOverwrite(int i){ if(i!=-1){ - if(myDetectorType == EIGER) + if(receiver != NULL) receiver->setEnableOverwrite(i); else overwrite=i; } - if(myDetectorType == EIGER) + if(receiver != NULL) return receiver->getEnableOverwrite(); else return overwrite; @@ -421,7 +435,7 @@ int slsReceiverUDPFunctions::enableOverwrite(int i){ /*other parameters*/ slsReceiverDefs::runStatus slsReceiverUDPFunctions::getStatus(){ - if(myDetectorType == EIGER) + if(receiver != NULL) return receiver->getStatus(); else return status; @@ -430,14 +444,14 @@ slsReceiverDefs::runStatus slsReceiverUDPFunctions::getStatus(){ char* slsReceiverUDPFunctions::setDetectorHostname(char c[]){ if(strlen(c)){ - if(myDetectorType == EIGER){ + if(receiver != NULL){ if(receiver->getDetectorHostname()== NULL) receiver->initialize(c); }else strcpy(detHostname,c); } - if(myDetectorType == EIGER) + if(receiver != NULL) return receiver->getDetectorHostname(); else return detHostname; @@ -456,13 +470,13 @@ void slsReceiverUDPFunctions::setUDPPortNo(int p){ int32_t slsReceiverUDPFunctions::setNumberOfFrames(int32_t fnum){ if(fnum >= 0){ - if(myDetectorType == EIGER) + if(receiver != NULL) receiver->setNumberOfFrames(fnum); else numberOfFrames = fnum; } - if(myDetectorType == EIGER) + if(receiver != NULL) return receiver->getNumberOfFrames(); else return numberOfFrames; @@ -470,13 +484,13 @@ int32_t slsReceiverUDPFunctions::setNumberOfFrames(int32_t fnum){ int32_t slsReceiverUDPFunctions::setScanTag(int32_t stag){ if(stag >= 0){ - if(myDetectorType == EIGER) + if(receiver != NULL) receiver->setScanTag(stag); else scanTag = stag; } - if(myDetectorType == EIGER) + if(receiver != NULL) return receiver->getScanTag(); else return scanTag; @@ -484,13 +498,13 @@ int32_t slsReceiverUDPFunctions::setScanTag(int32_t stag){ int32_t slsReceiverUDPFunctions::setDynamicRange(int32_t dr){ if(dr >= 0){ - if(myDetectorType == EIGER) + if(receiver != NULL) receiver->setDynamicRange(dr); else dynamicRange = dr; } - if(myDetectorType == EIGER) + if(receiver != NULL) return receiver->getDynamicRange(); else return dynamicRange; @@ -541,7 +555,7 @@ int64_t slsReceiverUDPFunctions::setAcquisitionPeriod(int64_t index){ if(index >= 0){ if(index != acquisitionPeriod){ acquisitionPeriod = index; - if(myDetectorType != EIGER) + if(receiver != NULL) setupFifoStructure(); } } @@ -658,6 +672,10 @@ void slsReceiverUDPFunctions::setupFilter(){ void slsReceiverUDPFunctions::setupFifoStructure(){ + + if(receiver != NULL) + return; + int64_t i; int oldn = numJobsPerThread; @@ -688,6 +706,8 @@ void slsReceiverUDPFunctions::setupFifoStructure(){ fifosize = GOTTHARD_FIFO_SIZE; if(myDetectorType == MOENCH) fifosize = MOENCH_FIFO_SIZE; + else if(myDetectorType == EIGER) + fifosize = EIGER_FIFO_SIZE; if(fifosize % numJobsPerThread) fifosize = (fifosize/numJobsPerThread)+1; @@ -1212,7 +1232,7 @@ void slsReceiverUDPFunctions::closeFile(int ithr){ int slsReceiverUDPFunctions::startReceiver(char message[]){ - if(myDetectorType == EIGER) + if(receiver != NULL) return receiver->startReceiver(message); @@ -1276,7 +1296,7 @@ int slsReceiverUDPFunctions::startReceiver(char message[]){ int slsReceiverUDPFunctions::stopReceiver(){ - if(myDetectorType == EIGER) + if(receiver != NULL) return receiver->stopReceiver(); @@ -1309,7 +1329,7 @@ int slsReceiverUDPFunctions::stopReceiver(){ void slsReceiverUDPFunctions::startReadout(){ - if(myDetectorType == EIGER){ + if(receiver != NULL){ receiver->stopReceiver(); return; } From 21a3b68d812f8a11881c2aeaccd8304f21a5f4a3 Mon Sep 17 00:00:00 2001 From: Maliakal Dhanya Date: Tue, 3 Jun 2014 12:06:57 +0200 Subject: [PATCH 006/474] git version history --- slsReceiverSoftware/gitInfo.txt | 9 +++++++++ slsReceiverSoftware/includes/gitInfoReceiver.h | 11 +++++++++++ .../{svnInfoReceiverTmp.h => gitInfoReceiverTmp.h} | 0 slsReceiverSoftware/includes/svnInfoReceiver.h | 11 ----------- 4 files changed, 20 insertions(+), 11 deletions(-) create mode 100644 slsReceiverSoftware/gitInfo.txt create mode 100644 slsReceiverSoftware/includes/gitInfoReceiver.h rename slsReceiverSoftware/includes/{svnInfoReceiverTmp.h => gitInfoReceiverTmp.h} (100%) delete mode 100644 slsReceiverSoftware/includes/svnInfoReceiver.h diff --git a/slsReceiverSoftware/gitInfo.txt b/slsReceiverSoftware/gitInfo.txt new file mode 100644 index 000000000..b09cfef5c --- /dev/null +++ b/slsReceiverSoftware/gitInfo.txt @@ -0,0 +1,9 @@ +Path: slsDetectorsPackage/slsReceiverSoftware +URL: origin git@gitorious.psi.ch:sls_det_software/sls_receiver_software.git +Repository Root: origin git@gitorious.psi.ch:sls_det_software/sls_receiver_software.git +Repsitory UUID: 77af4677a040fe113b5115475c18fd27f2453def +Revision: 5 +Branch: master +Last Changed Author: Maliakal_Dhanya +Last Changed Rev: 5 +Last Changed Date: 2014-05-28 18:06:00 +0200 diff --git a/slsReceiverSoftware/includes/gitInfoReceiver.h b/slsReceiverSoftware/includes/gitInfoReceiver.h new file mode 100644 index 000000000..641a0bdef --- /dev/null +++ b/slsReceiverSoftware/includes/gitInfoReceiver.h @@ -0,0 +1,11 @@ +//#define SVNPATH "" +#define SVNURL "git@gitorious.psi.ch:sls_det_software/sls_receiver_software.git" +//#define SVNREPPATH "" +#define SVNREPUUID "77af4677a040fe113b5115475c18fd27f2453def" +//#define SVNREV 0x5 +//#define SVNKIND "" +//#define SVNSCHED "" +#define SVNAUTH "Maliakal_Dhanya" +#define SVNREV 0x5 +#define SVNDATE 0x20140528 +// diff --git a/slsReceiverSoftware/includes/svnInfoReceiverTmp.h b/slsReceiverSoftware/includes/gitInfoReceiverTmp.h similarity index 100% rename from slsReceiverSoftware/includes/svnInfoReceiverTmp.h rename to slsReceiverSoftware/includes/gitInfoReceiverTmp.h diff --git a/slsReceiverSoftware/includes/svnInfoReceiver.h b/slsReceiverSoftware/includes/svnInfoReceiver.h deleted file mode 100644 index 5b0ab940b..000000000 --- a/slsReceiverSoftware/includes/svnInfoReceiver.h +++ /dev/null @@ -1,11 +0,0 @@ -//#define SVNPATH "" -#define SVNURL "file:///afs/psi.ch/project/sls_det_software/svn/slsReceiverSoftware/includes" -//#define SVNREPPATH "" -#define SVNREPUUID "5644e8d6-1a0c-4dbd-ab0e-45e7522ac187" -//#define SVNREV 0x5 -//#define SVNKIND "" -//#define SVNSCHED "" -#define SVNAUTH "l_maliakal_d" -#define SVNREV 0x5 -#define SVNDATE 0x20140515 -// From c922005f07c7f768e694b600507284b8090c44fd Mon Sep 17 00:00:00 2001 From: Maliakal Dhanya Date: Tue, 3 Jun 2014 13:56:16 +0200 Subject: [PATCH 007/474] git version history --- slsReceiverSoftware/gitInfo.txt | 8 ++++---- slsReceiverSoftware/includes/gitInfoReceiver.h | 8 ++++---- .../slsReceiver/slsReceiverTCPIPInterface.cpp | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/slsReceiverSoftware/gitInfo.txt b/slsReceiverSoftware/gitInfo.txt index b09cfef5c..cf5def048 100644 --- a/slsReceiverSoftware/gitInfo.txt +++ b/slsReceiverSoftware/gitInfo.txt @@ -1,9 +1,9 @@ Path: slsDetectorsPackage/slsReceiverSoftware URL: origin git@gitorious.psi.ch:sls_det_software/sls_receiver_software.git Repository Root: origin git@gitorious.psi.ch:sls_det_software/sls_receiver_software.git -Repsitory UUID: 77af4677a040fe113b5115475c18fd27f2453def -Revision: 5 +Repsitory UUID: 1c259aeba8b068b9f6e550d63a9a3a14bd7d3ab7 +Revision: 6 Branch: master Last Changed Author: Maliakal_Dhanya -Last Changed Rev: 5 -Last Changed Date: 2014-05-28 18:06:00 +0200 +Last Changed Rev: 6 +Last Changed Date: 2014-06-03 12:06:57 +0200 diff --git a/slsReceiverSoftware/includes/gitInfoReceiver.h b/slsReceiverSoftware/includes/gitInfoReceiver.h index 641a0bdef..05f3c2ab6 100644 --- a/slsReceiverSoftware/includes/gitInfoReceiver.h +++ b/slsReceiverSoftware/includes/gitInfoReceiver.h @@ -1,11 +1,11 @@ //#define SVNPATH "" #define SVNURL "git@gitorious.psi.ch:sls_det_software/sls_receiver_software.git" //#define SVNREPPATH "" -#define SVNREPUUID "77af4677a040fe113b5115475c18fd27f2453def" -//#define SVNREV 0x5 +#define SVNREPUUID "1c259aeba8b068b9f6e550d63a9a3a14bd7d3ab7" +//#define SVNREV 0x6 //#define SVNKIND "" //#define SVNSCHED "" #define SVNAUTH "Maliakal_Dhanya" -#define SVNREV 0x5 -#define SVNDATE 0x20140528 +#define SVNREV 0x6 +#define SVNDATE 0x20140603 // diff --git a/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.cpp b/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.cpp index 74c12dbca..ebb3d954d 100644 --- a/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.cpp +++ b/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.cpp @@ -5,7 +5,7 @@ #include "slsReceiverTCPIPInterface.h" #include "slsReceiverUDPFunctions.h" -#include "svnInfoReceiver.h" +#include "gitInfoReceiver.h" #include "slsReceiverUsers.h" #include //SIGINT From 3a71049f1cca6d4c6070ec1161748024f8ec1229 Mon Sep 17 00:00:00 2001 From: Maliakal Dhanya Date: Mon, 16 Jun 2014 16:53:36 +0200 Subject: [PATCH 008/474] added multiple listenign threads to incorporate multiple eiger ports, refactored the code a little bit --- .../MySocketTCP/genericSocket.h | 31 +- slsReceiverSoftware/includes/receiver_defs.h | 18 +- .../slsReceiver/slsReceiverTCPIPInterface.cpp | 4 +- .../slsReceiver/slsReceiverUDPFunctions.cpp | 688 +++++++++++------- .../slsReceiver/slsReceiverUDPFunctions.h | 100 ++- 5 files changed, 528 insertions(+), 313 deletions(-) diff --git a/slsReceiverSoftware/MySocketTCP/genericSocket.h b/slsReceiverSoftware/MySocketTCP/genericSocket.h index 28ae7b650..59126cf67 100644 --- a/slsReceiverSoftware/MySocketTCP/genericSocket.h +++ b/slsReceiverSoftware/MySocketTCP/genericSocket.h @@ -72,7 +72,6 @@ class sockaddr_in; using namespace std; #define DEFAULT_PACKET_SIZE 1286 -#define DEFAULT_PACKETS_PER_FRAME 2 #define SOCKET_BUFFER_SIZE (100*1024*1024) //100MB #define DEFAULT_PORTNO 1952 #define DEFAULT_BACKLOG 5 @@ -91,8 +90,7 @@ enum communicationProtocol{ UDP /**< UDP */ }; - - genericSocket(const char* const host_ip_or_name, unsigned short int const port_number, communicationProtocol p, int ps = DEFAULT_PACKET_SIZE, int t = DEFAULT_PACKETS_PER_FRAME) : + genericSocket(const char* const host_ip_or_name, unsigned short int const port_number, communicationProtocol p, int ps = DEFAULT_PACKET_SIZE) : // portno(port_number), protocol(p), is_a_server(0), @@ -101,8 +99,7 @@ enum communicationProtocol{ packet_size(ps), nsending(0), nsent(0), - total_sent(0), - packets_per_frame(t)// sender (client): where to? ip + total_sent(0)// sender (client): where to? ip { // strcpy(hostname,host_ip_or_name); @@ -149,7 +146,7 @@ enum communicationProtocol{ */ - genericSocket(unsigned short int const port_number, communicationProtocol p, int ps = DEFAULT_PACKET_SIZE, int t = DEFAULT_PACKETS_PER_FRAME, const char *eth=NULL): + genericSocket(unsigned short int const port_number, communicationProtocol p, int ps = DEFAULT_PACKET_SIZE, const char *eth=NULL): //portno(port_number), protocol(p), is_a_server(1), @@ -158,8 +155,7 @@ enum communicationProtocol{ packet_size(ps), nsending(0), nsent(0), - total_sent(0), - packets_per_frame(t) + total_sent(0) { /* // you can specify an IP address: */ @@ -562,25 +558,23 @@ enum communicationProtocol{ break; case UDP: if (socketDescriptor<0) return -1; - //if length given + //if length given, listens to length, else listens for packetsize till length is reached if(length){ while(length>0){ - nsending=packet_size; + nsending = (length>packet_size) ? packet_size:length; nsent = recvfrom(socketDescriptor,(char*)buf+total_sent,nsending, 0, (struct sockaddr *) &clientAddress, &clientAddress_length); if(!nsent) break; length-=nsent; total_sent+=nsent; } } - //depends on packets per frame + //listens to only 1 packet else{ - for(int i=0;ishutDownUDPSocket(); + slsReceiverFunctions->shutDownUDPSockets(); cout << "Closing Files... " << endl; slsReceiverFunctions->closeFile(); @@ -250,7 +250,7 @@ void slsReceiverTCPIPInterface::startTCPServer(){ if(v==GOODBYE){ cout << "Shutting down UDP Socket" << endl; if(slsReceiverFunctions) - slsReceiverFunctions->shutDownUDPSocket(); + slsReceiverFunctions->shutDownUDPSockets(); cout << "Closing Files... " << endl; slsReceiverFunctions->closeFile(); diff --git a/slsReceiverSoftware/slsReceiver/slsReceiverUDPFunctions.cpp b/slsReceiverSoftware/slsReceiver/slsReceiverUDPFunctions.cpp index b30d58aa2..18ba264a0 100644 --- a/slsReceiverSoftware/slsReceiver/slsReceiverUDPFunctions.cpp +++ b/slsReceiverSoftware/slsReceiver/slsReceiverUDPFunctions.cpp @@ -1,4 +1,4 @@ -#ifdef SLS_RECEIVER_UDP_FUNCTIONS +/*#ifdef SLS_RECEIVER_UDP_FUNCTIONS*/ /********************************************//** * @file slsReceiverUDPFunctions.cpp * @short does all the functions for a receiver, set/get parameters, start/stop etc. @@ -31,17 +31,19 @@ using namespace std; slsReceiverUDPFunctions::slsReceiverUDPFunctions(): receiver(NULL), - server_port(DEFAULT_UDP_PORTNO), thread_started(0), - udpSocket(NULL), eth(NULL), latestData(NULL), - guiFileName(NULL), - mem0(NULL), - fifo(NULL), - fifoFree(NULL){ + guiFileName(NULL){ + for(int i=0;iisEmpty()) - fifoFree->pop(buffer); - delete fifoFree; - } - if(fifo) delete fifo; - if(mem0) free(mem0); - fifoFree = new CircularFifo(fifosize); - fifo = new CircularFifo(fifosize); + for(int i=0;iisEmpty()) + fifoFree[i]->pop(buffer[i]); + delete fifoFree[i]; + } + if(fifo[i]) delete fifo[i]; + if(mem0[i]) free(mem0[i]); + fifoFree[i] = new CircularFifo(fifosize); + fifo[i] = new CircularFifo(fifosize); - //allocate memory - mem0=(char*)malloc((bufferSize * numJobsPerThread + HEADER_SIZE_NUM_TOT_PACKETS)*fifosize); - /** shud let the client know about this */ - if (mem0==NULL){ - cout<<"++++++++++++++++++++++ COULD NOT ALLOCATE MEMORY FOR LISTENING !!!!!!!+++++++++++++++++++++" << endl; - exit(-1); + //allocate memory + mem0[i]=(char*)malloc((bufferSize * numJobsPerThread + HEADER_SIZE_NUM_TOT_PACKETS)*fifosize); + /** shud let the client know about this */ + if (mem0[i]==NULL){ + cout<<"++++++++++++++++++++++ COULD NOT ALLOCATE MEMORY FOR LISTENING !!!!!!!+++++++++++++++++++++" << endl; + exit(-1); + } + buffer[i]=mem0[i]; + //push the addresses into freed fifoFree and writingFifoFree + while (buffer[i]<(mem0[i]+(bufferSize * numJobsPerThread + HEADER_SIZE_NUM_TOT_PACKETS)*(fifosize-1))) { + fifoFree[i]->push(buffer[i]); + buffer[i]+=(bufferSize * numJobsPerThread + HEADER_SIZE_NUM_TOT_PACKETS); + } } - buffer=mem0; - //push the addresses into freed fifoFree and writingFifoFree - while (buffer<(mem0+(bufferSize * numJobsPerThread + HEADER_SIZE_NUM_TOT_PACKETS)*(fifosize-1))) { - fifoFree->push(buffer); - buffer+=(bufferSize * numJobsPerThread + HEADER_SIZE_NUM_TOT_PACKETS); - } - - cout << "Fifo structure reconstructed" << endl; + cout << "Fifo structure(s) reconstructed" << endl; } @@ -792,7 +820,6 @@ void slsReceiverUDPFunctions::readFrame(char* c,char** raw){ void slsReceiverUDPFunctions::copyFrameToGui(char* startbuf){ - //random read when gui not ready if((!nFrameToGui) && (!guiData)){ pthread_mutex_lock(&dataReadyMutex); @@ -809,7 +836,8 @@ void slsReceiverUDPFunctions::copyFrameToGui(char* startbuf){ pthread_mutex_lock(&dataReadyMutex); guiDataReady=0; //send the first one - memcpy(latestData,startbuf,bufferSize); + for(int i=0;igetErrorStatus(); - if (iret){ + int iret; + for(int i=0;igetErrorStatus(); + if(iret){ #ifdef VERBOSE - cout << "Could not create UDP socket on port " << server_port << " error:" << iret << endl; + cout << "Could not create UDP socket on port " << server_port[i] << " error:" << iret << endl; #endif - - return FAIL; + return FAIL; + } } + return OK; } @@ -858,11 +893,13 @@ int slsReceiverUDPFunctions::createUDPSocket(){ -int slsReceiverUDPFunctions::shutDownUDPSocket(){ - if(udpSocket){ - udpSocket->ShutDownSocket(); - delete udpSocket; - udpSocket = NULL; +int slsReceiverUDPFunctions::shutDownUDPSockets(){ + for(int i=0;iShutDownSocket(); + delete udpSocket[i]; + udpSocket[i] = NULL; + } } return OK; } @@ -872,37 +909,53 @@ int slsReceiverUDPFunctions::shutDownUDPSocket(){ int slsReceiverUDPFunctions::createListeningThreads(bool destroy){ + int i; void* status; - killListeningThread = 0; + killAllListeningThreads = 0; pthread_mutex_lock(&status_mutex); - listening_thread_running = 0; + listeningthreads_mask = 0x0; pthread_mutex_unlock(&(status_mutex)); if(!destroy){ - //listening thread - cout << "Creating Listening Thread" << endl; - sem_init(&listensmp,1,0); - if(pthread_create(&listening_thread, NULL,startListeningThread, (void*) this)){ - cout << "Could not create listening thread" << endl; - return FAIL; + + //start listening threads + cout << "Creating Listening Threads(s)"; + + currentListeningThreadIndex = -1; + + for(i = 0; i < numListeningThreads; ++i){ + sem_init(&listensmp[i],1,0); + thread_started = 0; + currentListeningThreadIndex = i; + if(pthread_create(&listening_thread[i], NULL,startListeningThread, (void*) this)){ + cout << "Could not create listening thread with index " << i << endl; + return FAIL; + } + while(!thread_started); + cout << "."; + cout << flush; } #ifdef VERBOSE - cout << "Listening thread created successfully." << endl; + cout << "Listening thread(s) created successfully." << endl; +#else + cout << endl; #endif }else{ - cout<<"Destroying Listening Thread"<startReceiver(message); @@ -1244,20 +1303,21 @@ int slsReceiverUDPFunctions::startReceiver(char message[]){ //reset listening thread variables measurementStarted = false; startFrameIndex = 0; - totalListeningFrameCount = 0; + for(int i = 0; i < numListeningThreads; ++i) + totalListeningFrameCount[i] = 0; //udp socket - if(createUDPSocket() == FAIL){ - strcpy(message,"Could not create UDP Socket.\n"); + if(createUDPSockets() == FAIL){ + strcpy(message,"Could not create UDP Socket(s).\n"); cout << endl << message << endl; return FAIL; } - cout << "UDP socket created successfully on port " << server_port << endl; + cout << "UDP socket(s) created successfully. 1st port " << server_port[0] << endl; if(setupWriter() == FAIL){ //stop udp socket - shutDownUDPSocket(); + shutDownUDPSockets(); sprintf(message,"Could not create file %s.\n",savefilename); return FAIL; @@ -1274,17 +1334,19 @@ int slsReceiverUDPFunctions::startReceiver(char message[]){ //status pthread_mutex_lock(&status_mutex); status = RUNNING; - for(int i=0;istopReceiver(); return; } - + //#ifdef VERBOSE + cout << "Start Receiver Readout" << endl; + //#endif //wait so that all packets which take time has arrived usleep(50000); @@ -1344,7 +1408,7 @@ void slsReceiverUDPFunctions::startReadout(){ cout << "Status: Transmitting" << endl; //kill udp socket to tell the listening thread to push last packet - shutDownUDPSocket(); + shutDownUDPSockets(); } @@ -1369,152 +1433,142 @@ void* slsReceiverUDPFunctions::startWritingThread(void* this_pointer){ int slsReceiverUDPFunctions::startListening(){ + int ithread = currentListeningThreadIndex; #ifdef VERYVERBOSE - cout << "In startListening()" << endl; + cout << "In startListening() " << endl; #endif + thread_started = 1; + + int i,total; int lastpacketoffset, expected, rc, packetcount, maxBufferSize, carryonBufferSize; uint32_t lastframeheader;// for moench to check for all the packets in last frame char* tempchar = NULL; + int imageheader = 0; + if(myDetectorType==EIGER) + imageheader = EIGER_IMAGE_HEADER_SIZE; while(1){ //variables that need to be checked/set before each acquisition carryonBufferSize = 0; - maxBufferSize = packetsPerFrame * numJobsPerThread * onePacketSize; - if(tempchar) {delete [] tempchar;tempchar = NULL;} - tempchar = new char[onePacketSize * (packetsPerFrame - 1)]; //gotthard: 1packet size, moench:39 packet size - - - while(listening_thread_running){ - - //pop - fifoFree->pop(buffer); + //if more than 1 listening thread, listen one packet at a time, else need to interleaved frame later + maxBufferSize = bufferSize * numJobsPerThread; #ifdef VERYDEBUG - cout << "*** popped from fifo free" << (void*)buffer << endl; + cout << " maxBufferSize:" << maxBufferSize << ",carryonBufferSize:" << carryonBufferSize << endl; #endif - //receive - if(udpSocket == NULL) - rc = 0; - else if(!carryonBufferSize){ - rc = udpSocket->ReceiveDataOnly(buffer + HEADER_SIZE_NUM_TOT_PACKETS, maxBufferSize); - expected = maxBufferSize; - }else{ + if(tempchar) {delete [] tempchar;tempchar = NULL;} + if(myDetectorType == EIGER) + tempchar = new char[bufferSize]; + else + tempchar = new char[onePacketSize * (packetsPerFrame - 1)]; //gotthard: 1packet size, moench:39 packet size + + + + while((1<pop(buffer[ithread]); +#ifdef VERYDEBUG + cout << ithread << " *** popped from fifo free" << (void*)buffer[ithread] << endl; +#endif + + + //receive + if(udpSocket[ithread] == NULL){ + rc = 0; + cout << ithread << "UDP Socket is NULL" << endl; + } + //normal listening + else if(!carryonBufferSize){ + //eiger + if (imageheader){ + rc = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS); + //if it was the header + if(rc == EIGER_HEADER_LENGTH){ +#ifdef VERYDEBUG + cout << "rc for header2:" << dec << rc << endl; +#endif + expected = EIGER_HEADER_LENGTH; + }else{ + expected = maxBufferSize; + } + } + //not eiger + else{ + rc = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS, maxBufferSize); + expected = maxBufferSize; + } + } + //the remaining packets from previous buffer + else{ +#ifdef VERYDEBUG + cout << ithread << " ***carry on buffer" << carryonBufferSize << endl; + cout << ithread << " framennum in temochar:"<<((((uint32_t)(*((uint32_t*)tempchar))) & (frameIndexMask)) >> frameIndexOffset)<ReceiveDataOnly((buffer + HEADER_SIZE_NUM_TOT_PACKETS + carryonBufferSize),maxBufferSize - carryonBufferSize); + memcpy(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS, tempchar, carryonBufferSize); + rc = udpSocket[ithread]->ReceiveDataOnly((buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS + carryonBufferSize),maxBufferSize - carryonBufferSize); expected = maxBufferSize - carryonBufferSize; } #ifdef VERYDEBUG - cout << "*** rc:" << dec << rc << endl; - cout << "*** expected:" << dec << expected << endl; + cout << ithread << " *** rc:" << dec << rc << endl; + cout << ithread << " *** expected:" << dec << expected << endl; #endif - //start indices - //start of scan - if((!measurementStarted) && (rc > 0)){ - //gotthard has +1 for frame number - if ((myDetectorType == GOTTHARD) && (shortFrame == -1)) - startFrameIndex = (((((uint32_t)(*((uint32_t*)(buffer + HEADER_SIZE_NUM_TOT_PACKETS))))+1) - & (frameIndexMask)) >> frameIndexOffset); - else - startFrameIndex = ((((uint32_t)(*((uint32_t*)(buffer+HEADER_SIZE_NUM_TOT_PACKETS)))) - & (frameIndexMask)) >> frameIndexOffset); - cout<<"startFrameIndex:"< 0)) + startFrameIndices(ithread); + //problem in receiving or end of acquisition if((rc < expected)||(rc <= 0)){ -#ifdef VERYVERBOSE - cerr << "recvfrom() failed:"<push(buffer); - exit(-1); - continue; - } - //push the last buffer into fifo - if(rc > 0){ - packetcount = (rc/onePacketSize); -#ifdef VERYDEBUG - cout << "*** last packetcount:" << packetcount << endl; -#endif - (*((uint16_t*)(buffer))) = packetcount; - totalListeningFrameCount += packetcount; - while(!fifo->push(buffer)); -#ifdef VERYDEBUG - cout << "*** last lbuf1:" << (void*)buffer << endl; -#endif - } - - - //push dummy buffer - for(int i=0;ipop(buffer); - (*((uint16_t*)(buffer))) = 0xFFFF; - while(!fifo->push(buffer)); -#ifdef VERYDEBUG - cout << "pushed in dummy buffer:" << (void*)buffer << endl; -#endif - } - cout << "Total count listened to " << totalListeningFrameCount/packetsPerFrame << endl; - pthread_mutex_lock(&status_mutex); - listening_thread_running = 0; - pthread_mutex_unlock(&(status_mutex)); - break; + stopListening(ithread,rc,packetcount,total); + continue; } + //reset packetcount = packetsPerFrame * numJobsPerThread; carryonBufferSize = 0; + //check if last packet valid and calculate packet count switch(myDetectorType){ - - case MOENCH: lastpacketoffset = (((numJobsPerThread * packetsPerFrame - 1) * onePacketSize) + HEADER_SIZE_NUM_TOT_PACKETS); #ifdef VERYDEBUG - cout <<"first packet:"<< ((((uint32_t)(*((uint32_t*)(buffer+HEADER_SIZE_NUM_TOT_PACKETS))))) & (packetIndexMask)) << endl; - cout <<"first header:"<< (((((uint32_t)(*((uint32_t*)(buffer+HEADER_SIZE_NUM_TOT_PACKETS))))) & (frameIndexMask)) >> frameIndexOffset) << endl; + cout <<"first packet:"<< ((((uint32_t)(*((uint32_t*)(buffer[ithread]+HEADER_SIZE_NUM_TOT_PACKETS))))) & (packetIndexMask)) << endl; + cout <<"first header:"<< (((((uint32_t)(*((uint32_t*)(buffer[ithread]+HEADER_SIZE_NUM_TOT_PACKETS))))) & (frameIndexMask)) >> frameIndexOffset) << endl; cout << "last packet offset:" << lastpacketoffset << endl; - cout <<"last packet:"<< ((((uint32_t)(*((uint32_t*)(buffer+lastpacketoffset))))) & (packetIndexMask)) << endl; - cout <<"last header:"<< (((((uint32_t)(*((uint32_t*)(buffer+lastpacketoffset))))) & (frameIndexMask)) >> frameIndexOffset) << endl; + cout <<"last packet:"<< ((((uint32_t)(*((uint32_t*)(buffer[ithread]+lastpacketoffset))))) & (packetIndexMask)) << endl; + cout <<"last header:"<< (((((uint32_t)(*((uint32_t*)(buffer[ithread]+lastpacketoffset))))) & (frameIndexMask)) >> frameIndexOffset) << endl; #endif //moench last packet value is 0 - if( ((((uint32_t)(*((uint32_t*)(buffer+lastpacketoffset))))) & (packetIndexMask))){ - lastframeheader = ((((uint32_t)(*((uint32_t*)(buffer+lastpacketoffset))))) & (frameIndexMask)) >> frameIndexOffset; + if( ((((uint32_t)(*((uint32_t*)(buffer[ithread]+lastpacketoffset))))) & (packetIndexMask))){ + lastframeheader = ((((uint32_t)(*((uint32_t*)(buffer[ithread]+lastpacketoffset))))) & (frameIndexMask)) >> frameIndexOffset; carryonBufferSize += onePacketSize; lastpacketoffset -= onePacketSize; --packetcount; - while (lastframeheader == (((((uint32_t)(*((uint32_t*)(buffer+lastpacketoffset))))) & (frameIndexMask)) >> frameIndexOffset)){ + while (lastframeheader == (((((uint32_t)(*((uint32_t*)(buffer[ithread]+lastpacketoffset))))) & (frameIndexMask)) >> frameIndexOffset)){ carryonBufferSize += onePacketSize; lastpacketoffset -= onePacketSize; --packetcount; } - memcpy(tempchar, buffer+(lastpacketoffset+onePacketSize), carryonBufferSize); + memcpy(tempchar, buffer[ithread]+(lastpacketoffset+onePacketSize), carryonBufferSize); #ifdef VERYDEBUG cout << "tempchar header:" << (((((uint32_t)(*((uint32_t*)(tempchar))))) & (frameIndexMask)) >> frameIndexOffset) << endl; @@ -1524,17 +1578,15 @@ int slsReceiverUDPFunctions::startListening(){ } break; - - - default: + case GOTTHARD: if(shortFrame == -1){ lastpacketoffset = (((numJobsPerThread * packetsPerFrame - 1) * onePacketSize) + HEADER_SIZE_NUM_TOT_PACKETS); #ifdef VERYDEBUG cout << "last packet offset:" << lastpacketoffset << endl; #endif - if((unsigned int)(packetsPerFrame -1) != ((((uint32_t)(*((uint32_t*)(buffer+lastpacketoffset))))+1) & (packetIndexMask))){ - memcpy(tempchar,buffer+lastpacketoffset, onePacketSize); + if((unsigned int)(packetsPerFrame -1) != ((((uint32_t)(*((uint32_t*)(buffer[ithread]+lastpacketoffset))))+1) & (packetIndexMask))){ + memcpy(tempchar,buffer[ithread]+lastpacketoffset, onePacketSize); #ifdef VERYDEBUG cout << "tempchar header:" << (((((uint32_t)(*((uint32_t*)(tempchar))))+1) & (frameIndexMask)) >> frameIndexOffset) << endl; @@ -1544,32 +1596,45 @@ int slsReceiverUDPFunctions::startListening(){ } } #ifdef VERYDEBUG - cout << "header:" << (((((uint32_t)(*((uint32_t*)(buffer + HEADER_SIZE_NUM_TOT_PACKETS))))+1) + cout << "header:" << (((((uint32_t)(*((uint32_t*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS))))+1) & (frameIndexMask)) >> frameIndexOffset) << endl; #endif break; - - - + default: + if(rc==EIGER_HEADER_LENGTH) + packetcount=0; + else + packetcount = 1; + break; } + + + + + #ifdef VERYDEBUG cout << "*** packetcount:" << packetcount << " carryonbuffer:" << carryonBufferSize << endl; #endif //write packet count and push - (*((uint16_t*)(buffer))) = packetcount; - totalListeningFrameCount += packetcount; - while(!fifo->push(buffer)); + (*((uint16_t*)(buffer[ithread]))) = packetcount; + totalListeningFrameCount[ithread] += packetcount; +#ifdef VERYDEBUG + if(!ithread) cout << "totalListeningFrameCount[" << ithread << "]:" << totalListeningFrameCount[ithread] << endl; +#endif + while(!fifo[ithread]->push(buffer[ithread])); #ifdef VERYDEBUG cout << "*** pushed into listening fifo" << endl; #endif } - sem_wait(&listensmp); + sem_wait(&listensmp[ithread]); //make sure its not exiting thread - if(killListeningThread) + if(killAllListeningThreads){ + cout << ithread << " good bye listening thread" << endl; pthread_exit(NULL); + } } return OK; @@ -1599,12 +1664,11 @@ int slsReceiverUDPFunctions::startWriting(){ int numpackets, nf; uint32_t tempframenum; - char* wbuf; + char* wbuf[MAX_NUM_LISTENING_THREADS]; char *data=new char[bufferSize]; int iFrame = 0; int xmax=0,ymax=0; - int ret; - + int ret,i; while(1){ @@ -1626,11 +1690,12 @@ int slsReceiverUDPFunctions::startWriting(){ while((1<pop(wbuf); - numpackets = (uint16_t)(*((uint16_t*)wbuf)); + for(i=0;ipop(wbuf[i]); + numpackets = (uint16_t)(*((uint16_t*)wbuf[0])); #ifdef VERYDEBUG cout << ithread << " numpackets:" << dec << numpackets << endl; cout << ithread << " *** popped from fifo " << numpackets << endl; @@ -1644,13 +1709,14 @@ int slsReceiverUDPFunctions::startWriting(){ //last dummy packet if(numpackets == 0xFFFF){ #ifdef VERYDEBUG - cout << ithread << " **********************popped last dummy frame:" << (void*)wbuf << endl; + cout << ithread << " **********************popped last dummy frame:" << (void*)wbuf[0] << endl; #endif //free fifo - while(!fifoFree->push(wbuf)); + for(i=0;ipush(wbuf[i])); #ifdef VERYDEBUG - cout << ithread << " fifo freed:" << (void*)wbuf << endl; + cout << ithread << " fifo freed:" << (void*)wbuf[i] << endl; #endif @@ -1660,7 +1726,7 @@ int slsReceiverUDPFunctions::startWriting(){ pthread_mutex_lock(&status_mutex); writerthreads_mask^=(1<> frameIndexOffset); + if(myDetectorType == EIGER){ + if(!numpackets) + tempframenum = htonl(*(unsigned int*)((eiger_image_header *)((char*)(wbuf[0] + HEADER_SIZE_NUM_TOT_PACKETS)))->fnum); + }else if ((myDetectorType == GOTTHARD) && (shortFrame == -1)) + tempframenum = (((((uint32_t)(*((uint32_t*)(wbuf[0] + HEADER_SIZE_NUM_TOT_PACKETS))))+1)& (frameIndexMask)) >> frameIndexOffset); else - tempframenum = ((((uint32_t)(*((uint32_t*)(wbuf + HEADER_SIZE_NUM_TOT_PACKETS))))& (frameIndexMask)) >> frameIndexOffset); + tempframenum = ((((uint32_t)(*((uint32_t*)(wbuf[0] + HEADER_SIZE_NUM_TOT_PACKETS))))& (frameIndexMask)) >> frameIndexOffset); if(numWriterThreads == 1) currframenum = tempframenum; @@ -1715,28 +1784,38 @@ int slsReceiverUDPFunctions::startWriting(){ pthread_mutex_unlock(&progress_mutex); } #ifdef VERYDEBUG - cout << ithread << " tempframenum:" << dec << tempframenum << " curframenum:" << currframenum << endl; + cout << endl <num2)&0xff)<<"\t\t"< 0){ - writeToFile_withoutCompression(wbuf, numpackets); - } - //copy to gui - copyFrameToGui(wbuf + HEADER_SIZE_NUM_TOT_PACKETS); + if(!dataCompression){ - while(!fifoFree->push(wbuf)); -#ifdef VERYVERBOSE - cout<<"buf freed:"<<(void*)wbuf< 0){ + for(i=0;i 0){ + cout<<"numpackets:"<push(wbuf[i])); +#ifdef VERYVERBOSE + cout<<"buf freed:"<<(void*)wbuf[0]< (wbuf + HEADER_SIZE_NUM_TOT_PACKETS + numpackets * onePacketSize) ) + if(data > (wbuf[0] + HEADER_SIZE_NUM_TOT_PACKETS + numpackets * onePacketSize) ) cout <<" **************ERROR SHOULD NOT COME HERE, Error 142536!"<push(wbuf)); + while(!fifoFree[0]->push(wbuf[0])); #ifdef VERYVERBOSE - cout<<"buf freed:"<<(void*)wbuf<fnum); + //gotthard has +1 for frame number and not a short frame + else if ((myDetectorType == GOTTHARD) && (shortFrame == -1)) + startFrameIndex = (((((uint32_t)(*((uint32_t*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS))))+1) + & (frameIndexMask)) >> frameIndexOffset); + else + startFrameIndex = ((((uint32_t)(*((uint32_t*)(buffer[ithread]+HEADER_SIZE_NUM_TOT_PACKETS)))) + & (frameIndexMask)) >> frameIndexOffset); + + + cout << "startFrameIndex:" << startFrameIndex<push(buffer[ithread]); + exit(-1); + } + //push the last buffer into fifo + if(rc > 0){ + pc = (rc/onePacketSize); +#ifdef VERYDEBUG + cout << ithread << " *** last packetcount:" << packetcount << endl; +#endif + (*((uint16_t*)(buffer[ithread]))) = pc; + totalListeningFrameCount[ithread] += pc; + while(!fifo[ithread]->push(buffer[ithread])); +#ifdef VERYDEBUG + cout << ithread << " *** last lbuf1:" << (void*)buffer[ithread] << endl; +#endif + } + + + //push dummy buffer to all writer threads + for(i=0;ipop(buffer[ithread]); + (*((uint16_t*)(buffer[ithread]))) = 0xFFFF; + while(!fifo[ithread]->push(buffer[ithread])); +#ifdef VERYDEBUG + cout << ithread << " pushed in dummy buffer:" << (void*)buffer[ithread] << endl; +#endif + } + + //reset mask and exit loop + pthread_mutex_lock(&status_mutex); + listeningthreads_mask^=(1< 1) + cout << "Waiting for listening to be done.. current mask:" << hex << listeningthreads_mask << endl; +#endif + while(listeningthreads_mask) + usleep(5000); +#ifdef VERYDEBUG + t = 0; + for(i=0;i 0){ //for progress and packet loss calculation(new files) - if ((myDetectorType == GOTTHARD) && (shortFrame == -1)) + if(myDetectorType == EIGER){ + if(((uint16_t)(*((uint16_t*)buf)))==0) + tempframenum = htonl(*(unsigned int*)((eiger_image_header *)((char*)(buf + HEADER_SIZE_NUM_TOT_PACKETS)))->fnum); + }else if ((myDetectorType == GOTTHARD) && (shortFrame == -1)) tempframenum = (((((uint32_t)(*((uint32_t*)(buf + HEADER_SIZE_NUM_TOT_PACKETS))))+1)& (frameIndexMask)) >> frameIndexOffset); else tempframenum = ((((uint32_t)(*((uint32_t*)(buf + HEADER_SIZE_NUM_TOT_PACKETS))))& (frameIndexMask)) >> frameIndexOffset); @@ -1950,7 +2119,10 @@ void slsReceiverUDPFunctions::writeToFile_withoutCompression(char* buf,int numpa if(packetsInFile >= maxPacketsPerFile){ //for packet loss lastpacket = (((packetsToSave - 1) * onePacketSize) + offset); - if ((myDetectorType == GOTTHARD) && (shortFrame == -1)) + if(myDetectorType == EIGER){ + if(((uint16_t)(*((uint16_t*)buf)))==0) + tempframenum = htonl(*(unsigned int*)((eiger_image_header *)((char*)(buf + lastpacket)))->fnum); + }else if ((myDetectorType == GOTTHARD) && (shortFrame == -1)) tempframenum = (((((uint32_t)(*((uint32_t*)(buf + lastpacket))))+1)& (frameIndexMask)) >> frameIndexOffset); else tempframenum = ((((uint32_t)(*((uint32_t*)(buf + lastpacket))))& (frameIndexMask)) >> frameIndexOffset); @@ -1993,4 +2165,4 @@ void slsReceiverUDPFunctions::writeToFile_withoutCompression(char* buf,int numpa } -#endif +/*#endif*/ diff --git a/slsReceiverSoftware/slsReceiver/slsReceiverUDPFunctions.h b/slsReceiverSoftware/slsReceiver/slsReceiverUDPFunctions.h index 2029b3126..691c417be 100644 --- a/slsReceiverSoftware/slsReceiver/slsReceiverUDPFunctions.h +++ b/slsReceiverSoftware/slsReceiver/slsReceiverUDPFunctions.h @@ -1,4 +1,4 @@ -#ifdef SLS_RECEIVER_UDP_FUNCTIONS +/*#ifdef SLS_RECEIVER_UDP_FUNCTIONS*/ #ifndef SLS_RECEIVER_UDP_FUNCTIONS_H #define SLS_RECEIVER_UDP_FUNCTIONS_H /********************************************//** @@ -267,10 +267,10 @@ public: void startReadout(); /** - * shuts down the udp socket + * shuts down the udp sockets * \returns if success or fail */ - int shutDownUDPSocket(); + int shutDownUDPSockets(); private: /** @@ -295,10 +295,10 @@ private: void copyFrameToGui(char* startbuf); /** - * creates udp socket + * creates udp sockets * \returns if success or fail */ - int createUDPSocket(); + int createUDPSockets(); /** * create listening thread @@ -366,17 +366,55 @@ private: */ int startWriting(); - /** * Writing to file without compression * @param buf is the address of buffer popped out of fifo * @param numpackets is the number of packets + * @param framenum current frame number */ - void writeToFile_withoutCompression(char* buf,int numpackets); + void writeToFile_withoutCompression(char* buf,int numpackets, uint32_t framenum); + + /** + * Its called for the first packet of a scan or acquistion + * Sets the startframeindices and the variables to know if acquisition started + * @param ithread listening thread number + */ + void startFrameIndices(int ithread); + + /** + * This is called when udp socket is shut down + * It pops ffff instead of packet number into fifo + * to inform writers about the end of listening session + * @param ithread listening thread number + * @param rc number of bytes received + * @param pc packet count + * @param t total packets listened to + */ + void stopListening(int ithread, int rc, int &pc, int &t); + /** structure of an eiger image header*/ + typedef struct + { + unsigned char header_before[20]; + unsigned char fnum[4]; + unsigned char header_after[24]; + } eiger_image_header; + /** structure of an eiger image header*/ + typedef struct + { + unsigned char num1[4]; + unsigned char num2[4]; + } eiger_packet_header; + + /** max number of listening threads */ + const static int MAX_NUM_LISTENING_THREADS = MAX_EIGER_PORTS; + + /** max number of writer threads */ + const static int MAX_NUM_WRITER_THREADS = 15; + /** Eiger Receiver */ EigerReceiver *receiver; @@ -390,10 +428,10 @@ private: runStatus status; /** UDP Socket between Receiver and Detector */ - genericSocket* udpSocket; + genericSocket* udpSocket[MAX_NUM_LISTENING_THREADS]; /** Server UDP Port*/ - int server_port; + int server_port[MAX_NUM_LISTENING_THREADS]; /** ethernet interface or IP to listen to */ char *eth; @@ -482,7 +520,10 @@ private: /** Previous Frame number from buffer */ uint32_t prevframenum; - /** buffer size can be 1286*2 or 518 or 1286*40 */ + /** size of one frame */ + int frameSize; + + /** buffer size. different from framesize as we wait for one packet instead of frame for eiger */ int bufferSize; /** oen buffer size */ @@ -509,23 +550,23 @@ private: /** number of jobs per thread for data compression */ int numJobsPerThread; - /** memory allocated for the buffer */ - char *mem0; - /** datacompression - save only hits */ bool dataCompression; + /** memory allocated for the buffer */ + char *mem0[MAX_NUM_LISTENING_THREADS]; + /** circular fifo to store addresses of data read */ - CircularFifo* fifo; + CircularFifo* fifo[MAX_NUM_LISTENING_THREADS]; /** circular fifo to store addresses of data already written and ready to be resued*/ - CircularFifo* fifoFree; + CircularFifo* fifoFree[MAX_NUM_LISTENING_THREADS]; /** Receiver buffer */ - char *buffer; + char *buffer[MAX_NUM_LISTENING_THREADS]; - /** max number of writer threads */ - const static int MAX_NUM_WRITER_THREADS = 15; + /** number of writer threads */ + int numListeningThreads; /** number of writer threads */ int numWriterThreads; @@ -533,19 +574,25 @@ private: /** to know if listening and writer threads created properly */ int thread_started; + /** current listening thread index*/ + int currentListeningThreadIndex; + /** current writer thread index*/ int currentWriterThreadIndex; /** thread listening to packets */ - pthread_t listening_thread; + pthread_t listening_thread[MAX_NUM_LISTENING_THREADS]; /** thread writing packets */ pthread_t writing_thread[MAX_NUM_WRITER_THREADS]; /** total frame count the listening thread has listened to */ - int totalListeningFrameCount; + int totalListeningFrameCount[MAX_NUM_LISTENING_THREADS]; - /** mask showing which threads are running */ + /** mask showing which listening threads are running */ + volatile uint32_t listeningthreads_mask; + + /** mask showing which writer threads are running */ volatile uint32_t writerthreads_mask; /** mask showing which threads have created files*/ @@ -554,11 +601,8 @@ private: /** OK if file created was successful */ int ret_createfile; - /** 0 if listening thread is idle, 1 otherwise */ - int listening_thread_running; - /** variable used to self terminate threads waiting for semaphores */ - int killListeningThread; + int killAllListeningThreads; /** variable used to self terminate threads waiting for semaphores */ int killAllWritingThreads; @@ -569,8 +613,8 @@ private: //semaphores /** semaphore to synchronize writer and guireader threads */ sem_t smp; - /** semaphore to synchronize listener thread */ - sem_t listensmp; + /** semaphore to synchronize listener threads */ + sem_t listensmp[MAX_NUM_LISTENING_THREADS]; /** semaphore to synchronize writer threads */ sem_t writersmp[MAX_NUM_WRITER_THREADS]; @@ -687,4 +731,4 @@ public: #endif -#endif +/*#endif*/ From 5f82381b1e5677d2e41bee21fefbdbc31e954e3b Mon Sep 17 00:00:00 2001 From: Maliakal Dhanya Date: Wed, 18 Jun 2014 16:35:34 +0200 Subject: [PATCH 009/474] eiger gui works and can read frames, other gui functionalities not implemented --- .../slsReceiver/slsReceiverTCPIPInterface.cpp | 130 ++++- .../slsReceiver/slsReceiverTCPIPInterface.h | 3 + .../slsReceiver/slsReceiverUDPFunctions.cpp | 489 +++++++++++------- .../slsReceiver/slsReceiverUDPFunctions.h | 33 +- 4 files changed, 449 insertions(+), 206 deletions(-) diff --git a/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.cpp b/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.cpp index c5fa0eab3..19f74baa8 100644 --- a/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.cpp +++ b/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.cpp @@ -1012,6 +1012,8 @@ int slsReceiverTCPIPInterface::read_frame(){ switch(myDetectorType){ case MOENCH: return moench_read_frame(); + case EIGER: + return eiger_read_frame(); default: return gotthard_read_frame(); } @@ -1036,7 +1038,7 @@ int slsReceiverTCPIPInterface::moench_read_frame(){ char* raw = new char[bufferSize]; uint32_t startIndex=0; - int index = 0,bindex = 0, offset=0; + uint32_t index = 0,bindex = 0, offset=0; strcpy(mess,"Could not read frame\n"); @@ -1053,7 +1055,7 @@ int slsReceiverTCPIPInterface::moench_read_frame(){ else{ ret = OK; startIndex=slsReceiverFunctions->getStartFrameIndex(); - slsReceiverFunctions->readFrame(fName,&raw); + slsReceiverFunctions->readFrame(fName,&raw,index); /**send garbage with -1 index to try again*/ if (raw == NULL){ @@ -1223,7 +1225,7 @@ int slsReceiverTCPIPInterface::gotthard_read_frame(){ }else{ ret = OK; startIndex=slsReceiverFunctions->getStartFrameIndex(); - slsReceiverFunctions->readFrame(fName,&raw); + slsReceiverFunctions->readFrame(fName,&raw,index); /**send garbage with -1 index to try again*/ if (raw == NULL){ @@ -1334,6 +1336,128 @@ int slsReceiverTCPIPInterface::gotthard_read_frame(){ + + + + + +int slsReceiverTCPIPInterface::eiger_read_frame(){ + ret=OK; + char fName[MAX_STR_LENGTH]=""; + int arg = -1,i; + uint32_t index=0; + + int bufferSize = EIGER_BUFFER_SIZE; + int onebuffersize = EIGER_BUFFER_SIZE/EIGER_PACKETS_PER_FRAME; + int onedatasize = EIGER_DATA_BYTES/EIGER_PACKETS_PER_FRAME; + int numpackets = EIGER_PACKETS_PER_FRAME; + + char* raw = new char[bufferSize]; + char* origVal = new char[bufferSize]; + char* retval = new char[EIGER_DATA_BYTES]; + + /* + //retval is a full frame + int rnel = bufferSize/(sizeof(int)); + int* retval = new int[rnel]; + int* origVal = new int[rnel]; + //all initialized to 0 + for(i=0;igetFramesCaught()){ + arg=-1; + cout<<"haven't caught any frame yet"<readFrame(fName,&raw, index); +#ifdef VERBOSE + cout << "index:" << dec << index << endl; +#endif + /**send garbage with -1 index to try again*/ + if (raw == NULL){ + arg = -1; +#ifdef VERBOSE + cout<<"data not ready for gui yet"<num2)&0xff)<<"\t\t"; + memcpy(retval+retindex ,origVal+copyindex ,onedatasize); + copyindex += 16+onedatasize; + retindex += onedatasize; + } + arg = index-1; + } + } + +#ifdef VERBOSE + if(arg!=-1){ + cout << "fName:" << fName << endl; + cout << "findex:" << arg << endl; + } +#endif + + + +#endif + + if(ret==OK && socket->differentClients){ + cout << "Force update" << endl; + ret=FORCE_UPDATE; + } + + // send answer + socket->SendDataOnly(&ret,sizeof(ret)); + if(ret==FAIL){ + cout << "mess:" << mess << endl; + socket->SendDataOnly(mess,sizeof(mess)); + } + else{ + socket->SendDataOnly(fName,MAX_STR_LENGTH); + socket->SendDataOnly(&arg,sizeof(arg)); + socket->SendDataOnly(retval,EIGER_DATA_BYTES); + } + + delete [] retval; + delete [] origVal; + delete [] raw; + + return ret; +} + + int slsReceiverTCPIPInterface::set_read_frequency(){ ret=OK; int retval=-1; diff --git a/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.h b/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.h index cc0d48752..94126d59f 100644 --- a/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.h +++ b/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.h @@ -162,6 +162,9 @@ private: /** moench specific read frame */ int moench_read_frame(); + /** eiger specific read frame */ + int eiger_read_frame(); + /** Sets the receiver to send every nth frame to gui, or only upon gui request */ int set_read_frequency(); diff --git a/slsReceiverSoftware/slsReceiver/slsReceiverUDPFunctions.cpp b/slsReceiverSoftware/slsReceiver/slsReceiverUDPFunctions.cpp index 18ba264a0..470a41efb 100644 --- a/slsReceiverSoftware/slsReceiver/slsReceiverUDPFunctions.cpp +++ b/slsReceiverSoftware/slsReceiver/slsReceiverUDPFunctions.cpp @@ -1,4 +1,4 @@ -/*#ifdef SLS_RECEIVER_UDP_FUNCTIONS*/ +#ifdef SLS_RECEIVER_UDP_FUNCTIONS /********************************************//** * @file slsReceiverUDPFunctions.cpp * @short does all the functions for a receiver, set/get parameters, start/stop etc. @@ -34,7 +34,8 @@ slsReceiverUDPFunctions::slsReceiverUDPFunctions(): thread_started(0), eth(NULL), latestData(NULL), - guiFileName(NULL){ + guiFileName(NULL), + guiFrameNumber(0){ for(int i=0;inum2)&0xff)<<"\t\t"; + } + guiFrameNumber = fnum; + }else//other detectors + memcpy(latestData,buf,bufferSize); + + strcpy(guiFileName,savefilename); guiDataReady=1; pthread_mutex_unlock(&dataReadyMutex); @@ -1071,6 +1084,7 @@ int slsReceiverUDPFunctions::setupWriter(){ guiData = NULL; guiDataReady=0; strcpy(guiFileName,""); + guiFrameNumber = 0; cbAction = DO_EVERYTHING; pthread_mutex_lock(&status_mutex); @@ -1402,6 +1416,8 @@ void slsReceiverUDPFunctions::startReadout(){ //wait so that all packets which take time has arrived usleep(50000); + /********************************************/ + usleep(1000000); pthread_mutex_lock(&status_mutex); status = TRANSMITTING; pthread_mutex_unlock(&status_mutex); @@ -1528,7 +1544,7 @@ int slsReceiverUDPFunctions::startListening(){ //start indices for each start of scan/acquisition - eiger does it before - if((!measurementStarted) && (rc > 0)) + if((!measurementStarted) && (rc > 0) && (!ithread)) startFrameIndices(ithread); //problem in receiving or end of acquisition @@ -1620,11 +1636,11 @@ int slsReceiverUDPFunctions::startListening(){ (*((uint16_t*)(buffer[ithread]))) = packetcount; totalListeningFrameCount[ithread] += packetcount; #ifdef VERYDEBUG - if(!ithread) cout << "totalListeningFrameCount[" << ithread << "]:" << totalListeningFrameCount[ithread] << endl; + cout<push(buffer[ithread])); #ifdef VERYDEBUG - cout << "*** pushed into listening fifo" << endl; + if(!ithread) cout << ithread << " *** pushed into listening fifo" << endl; #endif } @@ -1652,8 +1668,6 @@ int slsReceiverUDPFunctions::startListening(){ - - int slsReceiverUDPFunctions::startWriting(){ int ithread = currentWriterThreadIndex; #ifdef VERYVERBOSE @@ -1664,16 +1678,17 @@ int slsReceiverUDPFunctions::startWriting(){ int numpackets, nf; uint32_t tempframenum; - char* wbuf[MAX_NUM_LISTENING_THREADS]; - char *data=new char[bufferSize]; - int iFrame = 0; + char* wbuf[packetsPerFrame+numListeningThreads];//interleaved + 2 ports header + char *d=new char[bufferSize]; int xmax=0,ymax=0; - int ret,i; + int ret,i,j; + int w_index=0; + int packetsPerThread = packetsPerFrame/numListeningThreads; while(1){ nf = 0; - iFrame = 0; + w_index = 0; if(myDetectorType == MOENCH){ xmax = MOENCH_PIXELS_IN_ONE_ROW-1; ymax = MOENCH_PIXELS_IN_ONE_ROW-1; @@ -1688,92 +1703,48 @@ int slsReceiverUDPFunctions::startWriting(){ } + + while((1<pop(wbuf[i]); - numpackets = (uint16_t)(*((uint16_t*)wbuf[0])); + for(i=0;ipop(wbuf[w_index+i]); + numpackets = (uint16_t)(*((uint16_t*)wbuf[w_index])); #ifdef VERYDEBUG - cout << ithread << " numpackets:" << dec << numpackets << endl; - cout << ithread << " *** popped from fifo " << numpackets << endl; + if((!w_index)||(!numpackets)) cout << ithread << " numpackets:" << dec << numpackets << endl; #endif + } - +#ifdef VERYDEBUG + cout << ithread << " numpackets:" << dec << numpackets << endl; + cout << ithread << " *** writer popped from fifo " << (void*) wbuf[w_index]<< endl; + cout << ithread << " *** writer popped from fifo " << (void*) wbuf[w_index+1]<< endl; +#endif //last dummy packet if(numpackets == 0xFFFF){ -#ifdef VERYDEBUG - cout << ithread << " **********************popped last dummy frame:" << (void*)wbuf[0] << endl; -#endif - - //free fifo - for(i=0;ipush(wbuf[i])); -#ifdef VERYDEBUG - cout << ithread << " fifo freed:" << (void*)wbuf[i] << endl; -#endif - - - - //all threads need to close file, reset mask and exit loop - closeFile(ithread); - pthread_mutex_lock(&status_mutex); - writerthreads_mask^=(1<fnum); + tempframenum = htonl(*(unsigned int*)((eiger_image_header *)((char*)(wbuf[w_index] + HEADER_SIZE_NUM_TOT_PACKETS)))->fnum); }else if ((myDetectorType == GOTTHARD) && (shortFrame == -1)) - tempframenum = (((((uint32_t)(*((uint32_t*)(wbuf[0] + HEADER_SIZE_NUM_TOT_PACKETS))))+1)& (frameIndexMask)) >> frameIndexOffset); + tempframenum = (((((uint32_t)(*((uint32_t*)(wbuf[w_index] + HEADER_SIZE_NUM_TOT_PACKETS))))+1)& (frameIndexMask)) >> frameIndexOffset); else - tempframenum = ((((uint32_t)(*((uint32_t*)(wbuf[0] + HEADER_SIZE_NUM_TOT_PACKETS))))& (frameIndexMask)) >> frameIndexOffset); + tempframenum = ((((uint32_t)(*((uint32_t*)(wbuf[w_index] + HEADER_SIZE_NUM_TOT_PACKETS))))& (frameIndexMask)) >> frameIndexOffset); if(numWriterThreads == 1) currframenum = tempframenum; @@ -1784,136 +1755,58 @@ int slsReceiverUDPFunctions::startWriting(){ pthread_mutex_unlock(&progress_mutex); } #ifdef VERYDEBUG - cout << endl <num2)&0xff)<<"\t\t"< 0){ - for(i=0;i 0){ - cout<<"numpackets:"<push(wbuf[i])); -#ifdef VERYVERBOSE - cout<<"buf freed:"<<(void*)wbuf[0]<findNextFrame(data,ndata,remainingsize)){ - np = ndata/onePacketSize; - - //cout<<"buff framnum:"<> frameIndexOffset)<newFrame(); - - //only for moench - if(commonModeSubtractionEnable){ - for(ix = xmin - 1; ix < xmax+1; ix++){ - for(iy = ymin - 1; iy < ymax+1; iy++){ - thisEvent = singlePhotonDet[ithread]->getEventType(buff, ix, iy, 0); - } - } - } - - - for(ix = xmin - 1; ix < xmax+1; ix++) - for(iy = ymin - 1; iy < ymax+1; iy++){ - thisEvent=singlePhotonDet[ithread]->getEventType(buff, ix, iy, commonModeSubtractionEnable); - if (nf>1000) { - tot=0; - tl=0; - tr=0; - bl=0; - br=0; - if (thisEvent==PHOTON_MAX) { - - iFrame=receiverdata[ithread]->getFrameNumber(buff); -#ifdef MYROOT1 - myTree[ithread]->Fill(); - //cout << "Fill in event: frmNr: " << iFrame << " ix " << ix << " iy " << iy << " type " << thisEvent << endl; -#else - pthread_mutex_lock(&write_mutex); - if((enableFileWrite) && (sfilefd)) - singlePhotonDet[ithread]->writeCluster(sfilefd); - pthread_mutex_unlock(&write_mutex); -#endif - } - } - } - - nf++; -#ifndef ALLFILE - pthread_mutex_lock(&progress_mutex); - packetsInFile += packetsPerFrame; - packetsCaught += packetsPerFrame; - totalPacketsCaught += packetsPerFrame; - if(packetsInFile >= maxPacketsPerFile) - createNewFile(); - pthread_mutex_unlock(&progress_mutex); - -#endif - if(!once){ - copyFrameToGui(buff); - once = 1; - } - } - - remainingsize -= ((buff + ndata) - data); - data = buff + ndata; - if(data > (wbuf[0] + HEADER_SIZE_NUM_TOT_PACKETS + numpackets * onePacketSize) ) - cout <<" **************ERROR SHOULD NOT COME HERE, Error 142536!"< 0){ + for(i=0;ipush(wbuf[0])); + + if(myDetectorType == EIGER) { + //last packet + if((packetsPerThread-1)==(htonl(*(uint32_t*)((eiger_packet_header *)((uint32_t*)(wbuf[w_index] + HEADER_SIZE_NUM_TOT_PACKETS)))->num2)&0xff)){ + copyFrameToGui(wbuf,currframenum); + for(j=0;jpush(wbuf[j+i])); + } + } + w_index = 0; + }else + w_index+=numListeningThreads; + } + else{ + //copy to gui + copyFrameToGui(NULL,-1,wbuf[0]+HEADER_SIZE_NUM_TOT_PACKETS); +#ifdef VERYVERBOSE + cout << ithread << " finished copying" << endl; +#endif + while(!fifoFree[0]->push(wbuf[0])); #ifdef VERYVERBOSE cout<<"buf freed:"<<(void*)wbuf[0]< 0){ pc = (rc/onePacketSize); #ifdef VERYDEBUG - cout << ithread << " *** last packetcount:" << packetcount << endl; + cout << ithread << " *** last packetcount:" << pc << endl; #endif (*((uint16_t*)(buffer[ithread]))) = pc; totalListeningFrameCount[ithread] += pc; @@ -2031,6 +1924,9 @@ int i; for(i=0;ipop(buffer[ithread]); (*((uint16_t*)(buffer[ithread]))) = 0xFFFF; +#ifdef VERYDEBUG + cout << ithread << " going to push in dummy buffer:" << (void*)buffer[ithread] << " with num packets:"<< (*((uint16_t*)(buffer[ithread]))) << endl; +#endif while(!fifo[ithread]->push(buffer[ithread])); #ifdef VERYDEBUG cout << ithread << " pushed in dummy buffer:" << (void*)buffer[ithread] << endl; @@ -2046,7 +1942,7 @@ int i; pthread_mutex_unlock(&(status_mutex)); #ifdef VERYDEBUG - cout << ithread << ": Frames listened to " << ((totalListeningFrameCount[ithread]/packetsPerFrame)/numListeningThreads) << endl; + cout << ithread << ": Frames listened to " << dec << ((totalListeningFrameCount[ithread]*numListeningThreads)/packetsPerFrame) << endl; #endif //waiting for all listening threads to be done, to print final count of frames listened to @@ -2061,7 +1957,7 @@ int i; t = 0; for(i=0;ipush(wbuffer[wIndex+j])); +#ifdef VERYDEBUG + cout << ithread << " fifo freed:" << (void*)wbuffer[wIndex+j] << endl; +#endif + } + + + //all threads need to close file, reset mask and exit loop + closeFile(ithread); + pthread_mutex_lock(&status_mutex); + writerthreads_mask^=(1< 1) pthread_mutex_unlock(&write_mutex); } +} + + + + + + + + + + + +void slsReceiverUDPFunctions::handleDataCompression(int ithread, char* wbuffer[], int &npackets, char* data, int xmax, int ymax, int &nf){ + +#if defined(MYROOT1) && defined(ALLFILE_DEBUG) + writeToFile_withoutCompression(wbuf[0], numpackets,currframenum); +#endif + + eventType thisEvent = PEDESTAL; + int ndata; + char* buff = 0; + data = wbuffer[0]+ HEADER_SIZE_NUM_TOT_PACKETS; + int remainingsize = npackets * onePacketSize; + int np; + int once = 0; + double tot, tl, tr, bl, br; + int xmin = 1, ymin = 1, ix, iy; + + + while(buff = receiverdata[ithread]->findNextFrame(data,ndata,remainingsize)){ + np = ndata/onePacketSize; + + //cout<<"buff framnum:"<> frameIndexOffset)<newFrame(); + + //only for moench + if(commonModeSubtractionEnable){ + for(ix = xmin - 1; ix < xmax+1; ix++){ + for(iy = ymin - 1; iy < ymax+1; iy++){ + thisEvent = singlePhotonDet[ithread]->getEventType(buff, ix, iy, 0); + } + } + } + + + for(ix = xmin - 1; ix < xmax+1; ix++) + for(iy = ymin - 1; iy < ymax+1; iy++){ + thisEvent=singlePhotonDet[ithread]->getEventType(buff, ix, iy, commonModeSubtractionEnable); + if (nf>1000) { + tot=0; + tl=0; + tr=0; + bl=0; + br=0; + if (thisEvent==PHOTON_MAX) { + receiverdata[ithread]->getFrameNumber(buff); + //iFrame=receiverdata[ithread]->getFrameNumber(buff); +#ifdef MYROOT1 + myTree[ithread]->Fill(); + //cout << "Fill in event: frmNr: " << iFrame << " ix " << ix << " iy " << iy << " type " << thisEvent << endl; +#else + pthread_mutex_lock(&write_mutex); + if((enableFileWrite) && (sfilefd)) + singlePhotonDet[ithread]->writeCluster(sfilefd); + pthread_mutex_unlock(&write_mutex); +#endif + } + } + } + + nf++; +#ifndef ALLFILE + pthread_mutex_lock(&progress_mutex); + packetsInFile += packetsPerFrame; + packetsCaught += packetsPerFrame; + totalPacketsCaught += packetsPerFrame; + if(packetsInFile >= maxPacketsPerFile) + createNewFile(); + pthread_mutex_unlock(&progress_mutex); + +#endif + if(!once){ + copyFrameToGui(NULL,-1,buff); + once = 1; + } + } + + remainingsize -= ((buff + ndata) - data); + data = buff + ndata; + if(data > (wbuffer[0] + HEADER_SIZE_NUM_TOT_PACKETS + npackets * onePacketSize) ) + cout <<" **************ERROR SHOULD NOT COME HERE, Error 142536!"<push(wbuffer[0])); +#ifdef VERYVERBOSE + cout<<"buf freed:"<<(void*)wbuffer[0]< Date: Wed, 2 Jul 2014 10:51:13 +0200 Subject: [PATCH 010/474] eiger receiver, receiving many packets at a time, with 16,8, 4 bitmode sort of working --- .../MySocketTCP/genericSocket.h | 3 +- slsReceiverSoftware/includes/circularFifo.h | 112 +-------- slsReceiverSoftware/includes/receiver_defs.h | 17 +- .../includes/sls_receiver_funcs.h | 4 +- .../slsReceiver/slsReceiverTCPIPInterface.cpp | 171 +++++++++++--- .../slsReceiver/slsReceiverTCPIPInterface.h | 5 + .../slsReceiver/slsReceiverUDPFunctions.cpp | 212 ++++++++++-------- .../slsReceiver/slsReceiverUDPFunctions.h | 5 +- 8 files changed, 285 insertions(+), 244 deletions(-) diff --git a/slsReceiverSoftware/MySocketTCP/genericSocket.h b/slsReceiverSoftware/MySocketTCP/genericSocket.h index 59126cf67..bb899f35b 100644 --- a/slsReceiverSoftware/MySocketTCP/genericSocket.h +++ b/slsReceiverSoftware/MySocketTCP/genericSocket.h @@ -570,10 +570,9 @@ enum communicationProtocol{ } //listens to only 1 packet else{ + //normal nsending=packet_size; nsent = recvfrom(socketDescriptor,(char*)buf+total_sent,nsending, 0, (struct sockaddr *) &clientAddress, &clientAddress_length); - if(!nsent) break; - length-=nsent; total_sent+=nsent; } break; diff --git a/slsReceiverSoftware/includes/circularFifo.h b/slsReceiverSoftware/includes/circularFifo.h index 8eaa13382..6f779aafc 100644 --- a/slsReceiverSoftware/includes/circularFifo.h +++ b/slsReceiverSoftware/includes/circularFifo.h @@ -38,7 +38,9 @@ public: array.resize(Capacity); sem_init(&free_mutex,0,0); } - virtual ~CircularFifo() {} + virtual ~CircularFifo() { + sem_destroy(&free_mutex); + } bool push(Element*& item_); bool pop(Element*& item_); @@ -151,111 +153,3 @@ unsigned int CircularFifo::increment(unsigned int idx_) const } #endif /* CIRCULARFIFO_H_ */ - - - - - -/* -#ifndef CIRCULARFIFO_H_ -#define CIRCULARFIFO_H_ - -#include "sls_receiver_defs.h" - -#include "/usr/include/alsa/atomic.h" -#include -using namespace std; - -template -class CircularFifo { -public: - - CircularFifo(unsigned int Size) : tail(0), head(0){ - Capacity = Size + 1; - array.resize(Capacity); - } - virtual ~CircularFifo() {} - - bool push(Element*& item_); - bool pop(Element*& item_); - - bool wasEmpty() const; - bool wasFull() const; - bool isLockFree() const; - -private: - vector array; - unsigned int Capacity; - - std::atomic tail; // input index - std::atomic head; // output index - - unsigned int increment(unsigned int idx_) const; -}; - - -template -bool CircularFifo::push(Element*& item_) -{ - auto currentTail = tail.load(); - auto nextTail = increment(currentTail); - if(nextTail != head.load()) - { - array[currentTail] = item_; - tail.store(nextTail); - return true; - } - - // queue was full - return false; -} - - -template -bool CircularFifo::pop(Element*& item_) -{ - const auto currentHead = head.load(); - if(currentHead == tail.load()) - return false; // empty queue - - item_ = array[currentHead]; - head.store(increment(currentHead)); - return true; -} - - -template -bool CircularFifo::wasEmpty() const -{ - return (head.load() == tail.load()); -} - - -template -bool CircularFifo::wasFull() const -{ - const auto nextTail = increment(tail.load()); - return (nextTail == head.load()); -} - -template -bool CircularFifo::isLockFree() const -{ - return (tail.is_lock_free() && head.is_lock_free()); -} - - -template -unsigned int CircularFifo::increment(unsigned int idx_) const -{ - // increment or wrap - // ================= - // index++; - // if(index == array.lenght) -> index = 0; - // - //or as written below: - // index = (index+1) % array.length - return (idx_ + 1) % Capacity; -} - -#endif */ diff --git a/slsReceiverSoftware/includes/receiver_defs.h b/slsReceiverSoftware/includes/receiver_defs.h index 0df2113b3..2ffd4500d 100755 --- a/slsReceiverSoftware/includes/receiver_defs.h +++ b/slsReceiverSoftware/includes/receiver_defs.h @@ -69,21 +69,24 @@ -#define MAX_EIGER_PORTS 2 +#define EIGER_MAX_PORTS 2 #define EIGER_HEADER_LENGTH 48 -#define EIGER_FIFO_SIZE 2500 //cannot be less than max jobs per thread = 1000 +#define EIGER_FIFO_SIZE 250 //cannot be less than max jobs per thread = 1000 /*#define EIGER_ALIGNED_FRAME_SIZE 65536*/ -#define EIGER_PACKETS_PER_FRAME (256*MAX_EIGER_PORTS) //default for 16B -#define EIGER_ONE_PACKET_SIZE 1040 //default for 16B -#define EIGER_BUFFER_SIZE (EIGER_ONE_PACKET_SIZE*EIGER_PACKETS_PER_FRAME) //1040*256//default for 16B -#define EIGER_DATA_BYTES (1024*EIGER_PACKETS_PER_FRAME) //1024*256 //default for 16B +#define EIGER_PACKETS_PER_FRAME_COSTANT (16*EIGER_MAX_PORTS)//*bit mode 4*16=64, 8*16=128, 16*16=256, 32*16=512 +#define EIGER_ONE_PACKET_SIZE 1040 +#define EIGER_ONE_DATA_SIZE 1024 +#define EIGER_BUFFER_SIZE_CONSTANT (EIGER_ONE_PACKET_SIZE*EIGER_PACKETS_PER_FRAME_COSTANT)//1040*16*2//*bit mode +#define EIGER_DATA_BYTES_CONSTANT (EIGER_ONE_DATA_SIZE*EIGER_PACKETS_PER_FRAME_COSTANT) //1024*16*2//*bit mode #define EIGER_FRAME_INDEX_MASK 0xFFFF #define EIGER_FRAME_INDEX_OFFSET 0 #define EIGER_PACKET_INDEX_MASK 0x0 -#define EIGER_IMAGE_HEADER_SIZE 32 +#define EIGER_IMAGE_HEADER_SIZE 48 + +#define EIGER_PIXELS_IN_ONE_ROW (256*4) diff --git a/slsReceiverSoftware/includes/sls_receiver_funcs.h b/slsReceiverSoftware/includes/sls_receiver_funcs.h index 298eb39b1..bb7655481 100644 --- a/slsReceiverSoftware/includes/sls_receiver_funcs.h +++ b/slsReceiverSoftware/includes/sls_receiver_funcs.h @@ -46,7 +46,9 @@ enum { F_RESET_RECEIVER_FRAMES_CAUGHT, /**< resets the frames caught by receiver */ F_ENABLE_RECEIVER_FILE_WRITE, /**< sets the receiver file write */ F_ENABLE_RECEIVER_COMPRESSION, /**< enable compression in receiver */ - F_ENABLE_RECEIVER_OVERWRITE /**< set overwrite flag in receiver */ + F_ENABLE_RECEIVER_OVERWRITE, /**< set overwrite flag in receiver */ + + F_ENABLE_RECEIVER_TEN_GIGA /**< enable 10Gbe in receiver */ /* Always append functions hereafter!!! */ }; diff --git a/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.cpp b/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.cpp index 19f74baa8..bbd1dc094 100644 --- a/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.cpp +++ b/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.cpp @@ -34,6 +34,7 @@ slsReceiverTCPIPInterface::slsReceiverTCPIPInterface(int argc, char *argv[], int lockStatus(0), shortFrame(-1), packetsPerFrame(GOTTHARD_PACKETS_PER_FRAME), + dynamicrange(16), socket(NULL), killTCPServerThread(0){ @@ -1347,37 +1348,23 @@ int slsReceiverTCPIPInterface::eiger_read_frame(){ int arg = -1,i; uint32_t index=0; - int bufferSize = EIGER_BUFFER_SIZE; - int onebuffersize = EIGER_BUFFER_SIZE/EIGER_PACKETS_PER_FRAME; - int onedatasize = EIGER_DATA_BYTES/EIGER_PACKETS_PER_FRAME; - int numpackets = EIGER_PACKETS_PER_FRAME; - + int bufferSize = EIGER_BUFFER_SIZE_CONSTANT * dynamicrange; char* raw = new char[bufferSize]; char* origVal = new char[bufferSize]; - char* retval = new char[EIGER_DATA_BYTES]; - - /* - //retval is a full frame - int rnel = bufferSize/(sizeof(int)); - int* retval = new int[rnel]; - int* origVal = new int[rnel]; - //all initialized to 0 - for(i=0;inum2)&0xff)<<"\t\t"; - memcpy(retval+retindex ,origVal+copyindex ,onedatasize); - copyindex += 16+onedatasize; - retindex += onedatasize; + + int c1=8; + int c2=(bufferSize/2) + 8; //only 2 ports + int retindex=0; + int irow,ibytesperpacket,irepeat; + int repeat=1; + int linesperpacket = 16/dynamicrange;// 16:1 line, 8:2 lines, 4:4 lines, 32: 0.5 + int numbytesperlineperport=(EIGER_PIXELS_IN_ONE_ROW/EIGER_MAX_PORTS)*dynamicrange/8;//16:1024,8:512,4:256,32:2048 + if(dynamicrange == 32){ + repeat=2; + numbytesperlineperport = 1024; + linesperpacket = 1; //we repeat this twice anyway } + + //cout <<"linesperpacket:" <num2)&0xff)<<"\t\t"; + memcpy(retval+retindex ,origVal+c1 ,EIGER_ONE_DATA_SIZE); + c1 += 16+EIGER_ONE_DATA_SIZE; + retindex += EIGER_ONE_DATA_SIZE; + + //cout<num2)&0xff)<differentClients){ cout << "Force update" << endl; @@ -1447,7 +1497,7 @@ int slsReceiverTCPIPInterface::eiger_read_frame(){ else{ socket->SendDataOnly(fName,MAX_STR_LENGTH); socket->SendDataOnly(&arg,sizeof(arg)); - socket->SendDataOnly(retval,EIGER_DATA_BYTES); + socket->SendDataOnly(retval,(EIGER_DATA_BYTES_CONSTANT*dynamicrange)); } delete [] retval; @@ -1799,8 +1849,24 @@ int slsReceiverTCPIPInterface::set_dynamic_range() { sprintf(mess,"Receiver locked by %s\n", socket->lastClientIP); ret=FAIL; } - else + else if(myDetectorType == EIGER){ + switch(dr){ + case 4: + case 8: + case 16: + case 32:break; + default: + sprintf(mess,"This dynamic range does not exist for eiger: %d\n",dr); + ret=FAIL; + break; + } + } + if(ret!=FAIL){ retval=slsReceiverFunctions->setDynamicRange(dr); + dynamicrange = dr; + if(myDetectorType == EIGER) + packetsPerFrame = dr*EIGER_PACKETS_PER_FRAME_COSTANT; + } } #ifdef VERBOSE if(ret!=FAIL) @@ -1883,8 +1949,52 @@ int slsReceiverTCPIPInterface::enable_overwrite() { +int slsReceiverTCPIPInterface::enable_tengiga() { + ret=OK; + int retval=-1; + int val; + strcpy(mess,"Could not enable/disable 10Gbe\n"); + // receive arguments + if(socket->ReceiveDataOnly(&val,sizeof(val)) < 0 ){ + strcpy(mess,"Error reading from socket\n"); + ret = FAIL; + } + + // execute action if the arguments correctly arrived +#ifdef SLS_RECEIVER_UDP_FUNCTIONS + if (ret==OK) { + if (lockStatus==1 && socket->differentClients==1){ + sprintf(mess,"Receiver locked by %s\n", socket->lastClientIP); + ret=FAIL; + } + else + ;//retval=slsReceiverFunctions->enable10GbE(val); + } +#ifdef VERBOSE + if(ret!=FAIL) + cout << "10Gbe:" << val << endl; + else + cout << mess << endl; +#endif +#endif + + if(ret==OK && socket->differentClients){ + cout << "Force update" << endl; + ret=FORCE_UPDATE; + } + + // send answer + socket->SendDataOnly(&ret,sizeof(ret)); + if(ret==FAIL) + socket->SendDataOnly(mess,sizeof(mess)); + socket->SendDataOnly(&retval,sizeof(retval)); + + //return ok/fail + return ret; +} + @@ -2063,8 +2173,7 @@ int slsReceiverTCPIPInterface::send_update() { //index #ifdef SLS_RECEIVER_UDP_FUNCTIONS - /*if(myDetectorType != EIGER)*/ - ind=slsReceiverFunctions->getFileIndex(); + ind=slsReceiverFunctions->getFileIndex(); socket->SendDataOnly(&ind,sizeof(ind)); #endif diff --git a/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.h b/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.h index 94126d59f..63016e7d7 100644 --- a/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.h +++ b/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.h @@ -193,6 +193,8 @@ private: /** enable overwrite */ int enable_overwrite(); + /** enable 10Gbe */ + int enable_tengiga(); //General Functions /** Locks Receiver */ @@ -246,6 +248,9 @@ private: /** Packets per frame */ int packetsPerFrame; + /** Dynamic Range */ + int dynamicrange; + /** kill tcp server thread */ int killTCPServerThread; diff --git a/slsReceiverSoftware/slsReceiver/slsReceiverUDPFunctions.cpp b/slsReceiverSoftware/slsReceiver/slsReceiverUDPFunctions.cpp index 470a41efb..d659945ba 100644 --- a/slsReceiverSoftware/slsReceiver/slsReceiverUDPFunctions.cpp +++ b/slsReceiverSoftware/slsReceiver/slsReceiverUDPFunctions.cpp @@ -143,7 +143,7 @@ void slsReceiverUDPFunctions::initializeMembers(){ frameIndexOffset = 0; acquisitionPeriod = SAMPLE_TIME_IN_NS; numberOfFrames = 0; - dynamicRange = 0; + dynamicRange = 16; shortFrame = -1; currframenum = 0; prevframenum = 0; @@ -262,11 +262,11 @@ int slsReceiverUDPFunctions::setDetectorType(detectorType det){ #ifndef EIGERSLS cout << "SLS Eiger Receiver" << endl; fifosize = EIGER_FIFO_SIZE; - packetsPerFrame = EIGER_PACKETS_PER_FRAME; + packetsPerFrame = EIGER_PACKETS_PER_FRAME_COSTANT * dynamicRange; onePacketSize = EIGER_ONE_PACKET_SIZE; - frameSize = EIGER_BUFFER_SIZE; - bufferSize = EIGER_ONE_PACKET_SIZE; // because if you listen to a whole frame on one port, it will be interleaved - maxPacketsPerFile = EIGER_MAX_FRAMES_PER_FILE * EIGER_PACKETS_PER_FRAME; + frameSize = EIGER_BUFFER_SIZE_CONSTANT * dynamicRange; + bufferSize = (frameSize/EIGER_MAX_PORTS) + EIGER_HEADER_LENGTH;//for only one port + maxPacketsPerFile = EIGER_MAX_FRAMES_PER_FILE * packetsPerFrame; frameIndexMask = EIGER_FRAME_INDEX_MASK; frameIndexOffset = EIGER_FRAME_INDEX_OFFSET; packetIndexMask = EIGER_PACKET_INDEX_MASK; @@ -522,11 +522,52 @@ int32_t slsReceiverUDPFunctions::setScanTag(int32_t stag){ } int32_t slsReceiverUDPFunctions::setDynamicRange(int32_t dr){ + cout << "Setting Dynamic Range" << endl; + + int olddr = dynamicRange; if(dr >= 0){ if(receiver != NULL) receiver->setDynamicRange(dr); - else + else{ dynamicRange = dr; + packetsPerFrame = EIGER_PACKETS_PER_FRAME_COSTANT * dynamicRange; + frameSize = EIGER_BUFFER_SIZE_CONSTANT * dynamicRange; + bufferSize = (frameSize/EIGER_MAX_PORTS) + EIGER_HEADER_LENGTH;//for only one port + maxPacketsPerFile = EIGER_MAX_FRAMES_PER_FILE * packetsPerFrame; + + if(olddr != dr){ + + //del + if(thread_started){ + createListeningThreads(true); + createWriterThreads(true); + } + for(int i=0;inum2)&0xff)<<"\t\t"; + int offset = 0; + int size = frameSize/EIGER_MAX_PORTS; + for(int j=0;jReceiveDataOnly(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS); - //if it was the header - if(rc == EIGER_HEADER_LENGTH){ -#ifdef VERYDEBUG - cout << "rc for header2:" << dec << rc << endl; -#endif - expected = EIGER_HEADER_LENGTH; - }else{ - expected = maxBufferSize; - } - } - //not eiger - else{ - rc = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS, maxBufferSize); - expected = maxBufferSize; - } + + rc = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS, maxBufferSize); + expected = maxBufferSize; + } //the remaining packets from previous buffer else{ @@ -1536,10 +1571,17 @@ int slsReceiverUDPFunctions::startListening(){ } #ifdef VERYDEBUG - cout << ithread << " *** rc:" << dec << rc << endl; - cout << ithread << " *** expected:" << dec << expected << endl; + cout << ithread << " *** rc:" << dec << rc << ". expected:" << dec << expected << endl; #endif +/* + if(ithread){ + for(int j=25;j<27;++j) + for(int i=1000;i<1010;i=i+2) + //cout<<"startbuf:"<pop(wbuf[w_index+i]); - numpackets = (uint16_t)(*((uint16_t*)wbuf[w_index])); + fifo[i]->pop(wbuf[i]); + numpackets = (uint16_t)(*((uint16_t*)wbuf[i])); #ifdef VERYDEBUG - if((!w_index)||(!numpackets)) cout << ithread << " numpackets:" << dec << numpackets << endl; + cout << ithread << " numpackets:" << dec << numpackets << endl; #endif } #ifdef VERYDEBUG cout << ithread << " numpackets:" << dec << numpackets << endl; - cout << ithread << " *** writer popped from fifo " << (void*) wbuf[w_index]<< endl; - cout << ithread << " *** writer popped from fifo " << (void*) wbuf[w_index+1]<< endl; + cout << ithread << " *** writer popped from fifo " << (void*) wbuf[0]<< endl; + cout << ithread << " *** writer popped from fifo " << (void*) wbuf[1]<< endl; #endif - - //last dummy packet if(numpackets == 0xFFFF){ - stopWriting(ithread,wbuf,w_index); + stopWriting(ithread,wbuf); continue; } - //for progress if(myDetectorType == EIGER){ - if(!numpackets) - tempframenum = htonl(*(unsigned int*)((eiger_image_header *)((char*)(wbuf[w_index] + HEADER_SIZE_NUM_TOT_PACKETS)))->fnum); + tempframenum = htonl(*(unsigned int*)((eiger_image_header *)((char*)(wbuf[ithread] + HEADER_SIZE_NUM_TOT_PACKETS)))->fnum); }else if ((myDetectorType == GOTTHARD) && (shortFrame == -1)) - tempframenum = (((((uint32_t)(*((uint32_t*)(wbuf[w_index] + HEADER_SIZE_NUM_TOT_PACKETS))))+1)& (frameIndexMask)) >> frameIndexOffset); + tempframenum = (((((uint32_t)(*((uint32_t*)(wbuf[ithread] + HEADER_SIZE_NUM_TOT_PACKETS))))+1)& (frameIndexMask)) >> frameIndexOffset); else - tempframenum = ((((uint32_t)(*((uint32_t*)(wbuf[w_index] + HEADER_SIZE_NUM_TOT_PACKETS))))& (frameIndexMask)) >> frameIndexOffset); + tempframenum = ((((uint32_t)(*((uint32_t*)(wbuf[ithread] + HEADER_SIZE_NUM_TOT_PACKETS))))& (frameIndexMask)) >> frameIndexOffset); if(numWriterThreads == 1) currframenum = tempframenum; @@ -1754,12 +1791,9 @@ int slsReceiverUDPFunctions::startWriting(){ currframenum = tempframenum; pthread_mutex_unlock(&progress_mutex); } -#ifdef VERYDEBUG - if(!numpackets) cout << endl < 0){ for(i=0;inum2)&0xff)){ - copyFrameToGui(wbuf,currframenum); - for(j=0;jpush(wbuf[j+i])); - } - } - w_index = 0; - }else - w_index+=numListeningThreads; + copyFrameToGui(wbuf,currframenum); + for(i=0;ipush(wbuf[i])); +#ifdef VERYDEBUG + cout << ithread << ":" << i+j << " fifo freed:" << (void*)wbuf[i] << endl; +#endif + } + + } else{ //copy to gui @@ -1972,20 +2004,20 @@ int i; -void slsReceiverUDPFunctions::stopWriting(int ithread, char* wbuffer[], int wIndex){ +void slsReceiverUDPFunctions::stopWriting(int ithread, char* wbuffer[]){ int i,j; #ifdef VERYDEBUG cout << ithread << " **********************popped last dummy frame:" << (void*)wbuffer[wIndex] << endl; #endif //free fifo - for(i=0;ipush(wbuffer[wIndex+j])); + for(i=0;ipush(wbuffer[i])); #ifdef VERYDEBUG - cout << ithread << " fifo freed:" << (void*)wbuffer[wIndex+j] << endl; + cout << ithread << ":" << i<< " fifo freed:" << (void*)wbuffer[i] << endl; #endif - } + } + //all threads need to close file, reset mask and exit loop @@ -2047,13 +2079,13 @@ void slsReceiverUDPFunctions::writeToFile_withoutCompression(char* buf,int numpa if((enableFileWrite) && (sfilefd)){ offset = HEADER_SIZE_NUM_TOT_PACKETS; + if(myDetectorType == EIGER) + offset += EIGER_HEADER_LENGTH; while(numpackets > 0){ //for progress and packet loss calculation(new files) - if(myDetectorType == EIGER){ - if(((uint16_t)(*((uint16_t*)buf)))==0) - tempframenum = htonl(*(unsigned int*)((eiger_image_header *)((char*)(buf + HEADER_SIZE_NUM_TOT_PACKETS)))->fnum); - }else if ((myDetectorType == GOTTHARD) && (shortFrame == -1)) + if(myDetectorType == EIGER); + else if ((myDetectorType == GOTTHARD) && (shortFrame == -1)) tempframenum = (((((uint32_t)(*((uint32_t*)(buf + HEADER_SIZE_NUM_TOT_PACKETS))))+1)& (frameIndexMask)) >> frameIndexOffset); else tempframenum = ((((uint32_t)(*((uint32_t*)(buf + HEADER_SIZE_NUM_TOT_PACKETS))))& (frameIndexMask)) >> frameIndexOffset); @@ -2077,7 +2109,7 @@ void slsReceiverUDPFunctions::writeToFile_withoutCompression(char* buf,int numpa packetsToSave = maxPacketsPerFile - packetsInFile; if(packetsToSave > numpackets) packetsToSave = numpackets; - +/**next time offset is still plus header length*/ fwrite(buf+offset, 1, packetsToSave * onePacketSize, sfilefd); packetsInFile += packetsToSave; packetsCaught += packetsToSave; @@ -2088,10 +2120,8 @@ void slsReceiverUDPFunctions::writeToFile_withoutCompression(char* buf,int numpa if(packetsInFile >= maxPacketsPerFile){ //for packet loss lastpacket = (((packetsToSave - 1) * onePacketSize) + offset); - if(myDetectorType == EIGER){ - if(((uint16_t)(*((uint16_t*)buf)))==0) - tempframenum = htonl(*(unsigned int*)((eiger_image_header *)((char*)(buf + lastpacket)))->fnum); - }else if ((myDetectorType == GOTTHARD) && (shortFrame == -1)) + if(myDetectorType == EIGER); + else if ((myDetectorType == GOTTHARD) && (shortFrame == -1)) tempframenum = (((((uint32_t)(*((uint32_t*)(buf + lastpacket))))+1)& (frameIndexMask)) >> frameIndexOffset); else tempframenum = ((((uint32_t)(*((uint32_t*)(buf + lastpacket))))& (frameIndexMask)) >> frameIndexOffset); diff --git a/slsReceiverSoftware/slsReceiver/slsReceiverUDPFunctions.h b/slsReceiverSoftware/slsReceiver/slsReceiverUDPFunctions.h index 43319ecd0..6cafcfcff 100644 --- a/slsReceiverSoftware/slsReceiver/slsReceiverUDPFunctions.h +++ b/slsReceiverSoftware/slsReceiver/slsReceiverUDPFunctions.h @@ -397,9 +397,8 @@ private: * When acquisition is over, this is called * @param ithread listening thread number * @param wbuffer writer buffer - * @param wIndex writer Index */ - void stopWriting(int ithread, char* wbuffer[], int wIndex); + void stopWriting(int ithread, char* wbuffer[]); /** @@ -432,7 +431,7 @@ private: } eiger_packet_header; /** max number of listening threads */ - const static int MAX_NUM_LISTENING_THREADS = MAX_EIGER_PORTS; + const static int MAX_NUM_LISTENING_THREADS = EIGER_MAX_PORTS; /** max number of writer threads */ const static int MAX_NUM_WRITER_THREADS = 15; From bbb0a05fca7fe888e1d734a37107aa51d636467c Mon Sep 17 00:00:00 2001 From: Maliakal Dhanya Date: Fri, 11 Jul 2014 12:53:53 +0200 Subject: [PATCH 011/474] incorporating ten giga into the receiver --- slsReceiverSoftware/includes/receiver_defs.h | 16 +- .../slsReceiver/slsReceiverTCPIPInterface.cpp | 132 ++++++------ .../slsReceiver/slsReceiverTCPIPInterface.h | 3 + .../slsReceiver/slsReceiverUDPFunctions.cpp | 191 +++++++++++++----- .../slsReceiver/slsReceiverUDPFunctions.h | 15 +- 5 files changed, 228 insertions(+), 129 deletions(-) diff --git a/slsReceiverSoftware/includes/receiver_defs.h b/slsReceiverSoftware/includes/receiver_defs.h index 2ffd4500d..4b0d10161 100755 --- a/slsReceiverSoftware/includes/receiver_defs.h +++ b/slsReceiverSoftware/includes/receiver_defs.h @@ -74,11 +74,15 @@ #define EIGER_FIFO_SIZE 250 //cannot be less than max jobs per thread = 1000 /*#define EIGER_ALIGNED_FRAME_SIZE 65536*/ -#define EIGER_PACKETS_PER_FRAME_COSTANT (16*EIGER_MAX_PORTS)//*bit mode 4*16=64, 8*16=128, 16*16=256, 32*16=512 -#define EIGER_ONE_PACKET_SIZE 1040 -#define EIGER_ONE_DATA_SIZE 1024 -#define EIGER_BUFFER_SIZE_CONSTANT (EIGER_ONE_PACKET_SIZE*EIGER_PACKETS_PER_FRAME_COSTANT)//1040*16*2//*bit mode -#define EIGER_DATA_BYTES_CONSTANT (EIGER_ONE_DATA_SIZE*EIGER_PACKETS_PER_FRAME_COSTANT) //1024*16*2//*bit mode +#define EIGER_ONE_GIGA_CONSTANT 16 +#define EIGER_TEN_GIGA_CONSTANT 4 +//#define EIGER_PACKETS_PER_FRAME_COSTANT (16*EIGER_MAX_PORTS)//*bit mode 4*16=64, 8*16=128, 16*16=256, 32*16=512 +#define EIGER_ONE_GIGA_ONE_PACKET_SIZE 1040 +#define EIGER_ONE_GIGA_ONE_DATA_SIZE 1024 +#define EIGER_TEN_GIGA_ONE_PACKET_SIZE 4112 +#define EIGER_TEN_GIGA_ONE_DATA_SIZE 4096 +//#define EIGER_BUFFER_SIZE_CONSTANT (EIGER_ONE_PACKET_SIZE*EIGER_PACKETS_PER_FRAME_COSTANT)//1040*16*2//*bit mode +//#define EIGER_DATA_BYTES_CONSTANT (EIGER_ONE_DATA_SIZE*EIGER_PACKETS_PER_FRAME_COSTANT) //1024*16*2//*bit mode #define EIGER_FRAME_INDEX_MASK 0xFFFF #define EIGER_FRAME_INDEX_OFFSET 0 @@ -87,7 +91,7 @@ #define EIGER_IMAGE_HEADER_SIZE 48 #define EIGER_PIXELS_IN_ONE_ROW (256*4) - +#define EIGER_PIXELS_IN_ONE_COL (256) #endif diff --git a/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.cpp b/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.cpp index bbd1dc094..703987822 100644 --- a/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.cpp +++ b/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.cpp @@ -36,7 +36,8 @@ slsReceiverTCPIPInterface::slsReceiverTCPIPInterface(int argc, char *argv[], int packetsPerFrame(GOTTHARD_PACKETS_PER_FRAME), dynamicrange(16), socket(NULL), - killTCPServerThread(0){ + killTCPServerThread(0), + tenGigaEnable(0){ int port_no = DEFAULT_PORTNO+2; ifstream infile; @@ -316,6 +317,9 @@ int slsReceiverTCPIPInterface::function_table(){ flist[F_ENABLE_RECEIVER_COMPRESSION] = &slsReceiverTCPIPInterface::enable_compression; flist[F_ENABLE_RECEIVER_OVERWRITE] = &slsReceiverTCPIPInterface::enable_overwrite; + flist[F_ENABLE_RECEIVER_TEN_GIGA] = &slsReceiverTCPIPInterface::enable_tengiga; + + #ifdef VERBOSE for (int i=0;inum2)&0xff)<<"\t\t"; - memcpy(retval+retindex ,origVal+c1 ,EIGER_ONE_DATA_SIZE); - c1 += 16+EIGER_ONE_DATA_SIZE; - retindex += EIGER_ONE_DATA_SIZE; - - //cout<num2)&0xff)<> 8) & 0x00FF00FF00FF00FFULL ); + temp = ((temp << 16) & 0xFFFF0000FFFF0000ULL ) | ((temp >> 16) & 0x0000FFFF0000FFFFULL ); + temp = (temp << 32) | ((temp >> 32) & 0xFFFFFFFFULL); + (*(((uint64_t*)retval)+i)) = temp; } - -*/ - - - for(i=0;i<(1024*(16*dynamicrange)*2)/4;i++) - (*((uint32_t*)retval+i)) = htonl((uint32_t)(*((uint32_t*)retval+i))); - +/* + ( (((val) >> 56) & 0x00000000000000FF) | (((val) >> 40) & 0x000000000000FF00) | \ + (((val) >> 24) & 0x0000000000FF0000) | (((val) >> 8) & 0x00000000FF000000) | \ + (((val) << 8) & 0x000000FF00000000) | (((val) << 24) & 0x0000FF0000000000) | \ + (((val) << 40) & 0x00FF000000000000) | (((val) << 56) & 0xFF00000000000000) ) + */ /* - for(int j=25;j<27;++j) - for(int i=1000;i<1010;i=i+2) - //cout<<"retval:"<differentClients){ cout << "Force update" << endl; @@ -1497,7 +1489,7 @@ int slsReceiverTCPIPInterface::eiger_read_frame(){ else{ socket->SendDataOnly(fName,MAX_STR_LENGTH); socket->SendDataOnly(&arg,sizeof(arg)); - socket->SendDataOnly(retval,(EIGER_DATA_BYTES_CONSTANT*dynamicrange)); + socket->SendDataOnly(retval,dataSize); } delete [] retval; @@ -1508,6 +1500,11 @@ int slsReceiverTCPIPInterface::eiger_read_frame(){ } + + + + + int slsReceiverTCPIPInterface::set_read_frequency(){ ret=OK; int retval=-1; @@ -1864,8 +1861,12 @@ int slsReceiverTCPIPInterface::set_dynamic_range() { if(ret!=FAIL){ retval=slsReceiverFunctions->setDynamicRange(dr); dynamicrange = dr; - if(myDetectorType == EIGER) - packetsPerFrame = dr*EIGER_PACKETS_PER_FRAME_COSTANT; + if(myDetectorType == EIGER){ + if(!tenGigaEnable) + packetsPerFrame = EIGER_ONE_GIGA_CONSTANT * dynamicrange * EIGER_MAX_PORTS; + else + packetsPerFrame = EIGER_TEN_GIGA_CONSTANT * dynamicrange * EIGER_MAX_PORTS; + } } } #ifdef VERBOSE @@ -1969,8 +1970,13 @@ int slsReceiverTCPIPInterface::enable_tengiga() { sprintf(mess,"Receiver locked by %s\n", socket->lastClientIP); ret=FAIL; } - else - ;//retval=slsReceiverFunctions->enable10GbE(val); + else{ + retval=slsReceiverFunctions->enableTenGiga(val); + if((val!=-1) && (val != retval)) + ret = FAIL; + else + tenGigaEnable = retval; + } } #ifdef VERBOSE if(ret!=FAIL) diff --git a/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.h b/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.h index 63016e7d7..bddce2bd8 100644 --- a/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.h +++ b/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.h @@ -257,6 +257,9 @@ private: /** thread for TCP server */ pthread_t TCPServer_thread; + /** size of one frame*/ + int tenGigaEnable; + protected: /** Socket */ MySocketTCP* socket; diff --git a/slsReceiverSoftware/slsReceiver/slsReceiverUDPFunctions.cpp b/slsReceiverSoftware/slsReceiver/slsReceiverUDPFunctions.cpp index d659945ba..382fae74e 100644 --- a/slsReceiverSoftware/slsReceiver/slsReceiverUDPFunctions.cpp +++ b/slsReceiverSoftware/slsReceiver/slsReceiverUDPFunctions.cpp @@ -1,4 +1,4 @@ -#ifdef SLS_RECEIVER_UDP_FUNCTIONS +//#ifdef SLS_RECEIVER_UDP_FUNCTIONS /********************************************//** * @file slsReceiverUDPFunctions.cpp * @short does all the functions for a receiver, set/get parameters, start/stop etc. @@ -35,7 +35,8 @@ slsReceiverUDPFunctions::slsReceiverUDPFunctions(): eth(NULL), latestData(NULL), guiFileName(NULL), - guiFrameNumber(0){ + guiFrameNumber(0), + tengigaEnable(0){ for(int i=0;isetDynamicRange(dr); else{ dynamicRange = dr; - packetsPerFrame = EIGER_PACKETS_PER_FRAME_COSTANT * dynamicRange; - frameSize = EIGER_BUFFER_SIZE_CONSTANT * dynamicRange; - bufferSize = (frameSize/EIGER_MAX_PORTS) + EIGER_HEADER_LENGTH;//for only one port - maxPacketsPerFile = EIGER_MAX_FRAMES_PER_FILE * packetsPerFrame; - if(olddr != dr){ + if(myDetectorType == EIGER){ - //del - if(thread_started){ - createListeningThreads(true); - createWriterThreads(true); - } - for(int i=0;ifnum)<push(buffer[ithread]); @@ -1960,37 +1965,37 @@ int i; cout << ithread << " going to push in dummy buffer:" << (void*)buffer[ithread] << " with num packets:"<< (*((uint16_t*)(buffer[ithread]))) << endl; #endif while(!fifo[ithread]->push(buffer[ithread])); -#ifdef VERYDEBUG +//#ifdef VERYDEBUG cout << ithread << " pushed in dummy buffer:" << (void*)buffer[ithread] << endl; -#endif +//#endif } //reset mask and exit loop pthread_mutex_lock(&status_mutex); listeningthreads_mask^=(1< 1) cout << "Waiting for listening to be done.. current mask:" << hex << listeningthreads_mask << endl; -#endif +//#endif while(listeningthreads_mask) usleep(5000); -#ifdef VERYDEBUG +//#ifdef VERYDEBUG t = 0; for(i=0;i= 0){ + if(receiver != NULL) + ;/*receiver->setTenGigaBitEthernet(enable);*/ + else{ + tengigaEnable = enable; + + if(myDetectorType == EIGER){ + + if(!tengigaEnable){ + packetsPerFrame = EIGER_ONE_GIGA_CONSTANT * dynamicRange * EIGER_MAX_PORTS; + onePacketSize = EIGER_ONE_GIGA_ONE_PACKET_SIZE; + maxPacketsPerFile = EIGER_MAX_FRAMES_PER_FILE * packetsPerFrame; + }else{ + packetsPerFrame = EIGER_TEN_GIGA_CONSTANT * dynamicRange * EIGER_MAX_PORTS; + onePacketSize = EIGER_TEN_GIGA_ONE_PACKET_SIZE; + maxPacketsPerFile = EIGER_MAX_FRAMES_PER_FILE * packetsPerFrame*4; + } + frameSize = onePacketSize * packetsPerFrame; + bufferSize = (frameSize/EIGER_MAX_PORTS) + EIGER_HEADER_LENGTH;//everything one port gets (img header plus packets) + //maxPacketsPerFile = EIGER_MAX_FRAMES_PER_FILE * packetsPerFrame; + + + cout<<"packetsPerFrame:"<getTenGigaBitEthernet();*/ + else + return tengigaEnable; + +} @@ -2285,5 +2365,4 @@ void slsReceiverUDPFunctions::handleDataCompression(int ithread, char* wbuffer[] - -#endif +//#endif diff --git a/slsReceiverSoftware/slsReceiver/slsReceiverUDPFunctions.h b/slsReceiverSoftware/slsReceiver/slsReceiverUDPFunctions.h index 6cafcfcff..3cb1872cf 100644 --- a/slsReceiverSoftware/slsReceiver/slsReceiverUDPFunctions.h +++ b/slsReceiverSoftware/slsReceiver/slsReceiverUDPFunctions.h @@ -1,4 +1,4 @@ -#ifdef SLS_RECEIVER_UDP_FUNCTIONS +//#ifdef SLS_RECEIVER_UDP_FUNCTIONS #ifndef SLS_RECEIVER_UDP_FUNCTIONS_H #define SLS_RECEIVER_UDP_FUNCTIONS_H /********************************************//** @@ -228,8 +228,12 @@ public: */ int enableDataCompression(bool enable); - - + /** + * enable 10Gbe + @param enable 1 for 10Gbe or 0 for 1 Gbe, -1 to read out + \returns enable for 10Gbe + */ + int enableTenGiga(int enable = -1); @@ -631,6 +635,9 @@ private: /** variable used to self terminate threads waiting for semaphores */ int killAllWritingThreads; + /** 10Gbe enable*/ + int tengigaEnable; + @@ -755,4 +762,4 @@ public: #endif -#endif +//#endif From 4814fd56c17d97c8583fd04052ed71a03aeb89cf Mon Sep 17 00:00:00 2001 From: Maliakal Dhanya Date: Wed, 16 Jul 2014 15:34:58 +0200 Subject: [PATCH 012/474] slsdetectorcalibration is a repository on its own --- .../slsDetectorCalibration/MovingStat.h | 130 ----- .../slsDetectorCalibration/RunningStat.h | 55 -- .../chiptestBoardData.h | 89 --- .../commonModeSubtraction.h | 82 --- .../slsDetectorCalibration/demoCreateTree.C | 31 -- .../slsDetectorCalibration/doxy.config | 85 --- .../energyCalibration.cpp | 527 ------------------ .../energyCalibration.h | 452 --------------- .../slsDetectorCalibration/gMapDemo.C | 11 - .../slsDetectorCalibration/gainMap.C | 228 -------- .../gotthardModuleData.h | 148 ----- .../gotthardShortModuleData.h | 127 ----- .../slsDetectorCalibration/jungfrau02Data.h | 156 ------ .../slsDetectorCalibration/jungfrauReadData.C | 264 --------- .../moench02ModuleData.h | 137 ----- .../slsDetectorCalibration/moenchCommonMode.h | 45 -- .../slsDetectorCalibration/moenchMakeTree.C | 244 -------- .../slsDetectorCalibration/moenchReadData.C | 236 -------- .../slsDetectorCalibration/moenchReadDataMT.C | 52 -- .../pedestalSubtraction.h | 48 -- .../slsDetectorCalibration/raedNoiseData.C | 136 ----- .../slsDetectorCalibration/readJungfrauData.C | 31 -- .../singlePhotonDetector.h | 387 ------------- .../single_photon_hit.h | 62 --- .../slsDetectorCalibration/slsDetectorData.h | 251 --------- .../slsDetectorCalibration/slsReceiverData.h | 171 ------ 26 files changed, 4185 deletions(-) delete mode 100755 slsReceiverSoftware/slsDetectorCalibration/MovingStat.h delete mode 100755 slsReceiverSoftware/slsDetectorCalibration/RunningStat.h delete mode 100644 slsReceiverSoftware/slsDetectorCalibration/chiptestBoardData.h delete mode 100644 slsReceiverSoftware/slsDetectorCalibration/commonModeSubtraction.h delete mode 100644 slsReceiverSoftware/slsDetectorCalibration/demoCreateTree.C delete mode 100644 slsReceiverSoftware/slsDetectorCalibration/doxy.config delete mode 100644 slsReceiverSoftware/slsDetectorCalibration/energyCalibration.cpp delete mode 100644 slsReceiverSoftware/slsDetectorCalibration/energyCalibration.h delete mode 100644 slsReceiverSoftware/slsDetectorCalibration/gMapDemo.C delete mode 100644 slsReceiverSoftware/slsDetectorCalibration/gainMap.C delete mode 100644 slsReceiverSoftware/slsDetectorCalibration/gotthardModuleData.h delete mode 100644 slsReceiverSoftware/slsDetectorCalibration/gotthardShortModuleData.h delete mode 100644 slsReceiverSoftware/slsDetectorCalibration/jungfrau02Data.h delete mode 100644 slsReceiverSoftware/slsDetectorCalibration/jungfrauReadData.C delete mode 100644 slsReceiverSoftware/slsDetectorCalibration/moench02ModuleData.h delete mode 100644 slsReceiverSoftware/slsDetectorCalibration/moenchCommonMode.h delete mode 100644 slsReceiverSoftware/slsDetectorCalibration/moenchMakeTree.C delete mode 100644 slsReceiverSoftware/slsDetectorCalibration/moenchReadData.C delete mode 100644 slsReceiverSoftware/slsDetectorCalibration/moenchReadDataMT.C delete mode 100644 slsReceiverSoftware/slsDetectorCalibration/pedestalSubtraction.h delete mode 100644 slsReceiverSoftware/slsDetectorCalibration/raedNoiseData.C delete mode 100644 slsReceiverSoftware/slsDetectorCalibration/readJungfrauData.C delete mode 100644 slsReceiverSoftware/slsDetectorCalibration/singlePhotonDetector.h delete mode 100644 slsReceiverSoftware/slsDetectorCalibration/single_photon_hit.h delete mode 100644 slsReceiverSoftware/slsDetectorCalibration/slsDetectorData.h delete mode 100644 slsReceiverSoftware/slsDetectorCalibration/slsReceiverData.h diff --git a/slsReceiverSoftware/slsDetectorCalibration/MovingStat.h b/slsReceiverSoftware/slsDetectorCalibration/MovingStat.h deleted file mode 100755 index 9d3720b1b..000000000 --- a/slsReceiverSoftware/slsDetectorCalibration/MovingStat.h +++ /dev/null @@ -1,130 +0,0 @@ -#ifndef MOVINGSTAT_H -#define MOVINGSTAT_H - -#include - - -class MovingStat - { - - /** @short approximated moving average structure */ - public: - - - /** constructor - \param nn number of samples parameter to be used - */ - MovingStat(int nn=1000) : n(nn), m_n(0) {} - - /** - clears the moving average number of samples parameter, mean and standard deviation - */ - void Clear() - { - m_n = 0; - m_newM=0; - m_newM2=0; - } - - - /** sets number of samples parameter - \param i number of samples parameter to be set - */ - - void SetN(int i) {if (i>=1) n=i;}; - - /** - gets number of samples parameter - \returns actual number of samples parameter - */ - int GetN() {return n;}; - - /** calculates the moving average i.e. adds if number of elements is lower than number of samples parameter, pushes otherwise - \param x value to calculate the moving average - */ - inline void Calc(double x) { - if (m_n 0) ? m_newM/m_n : 0.0; - } - - /** returns the squared mean, 0 if no elements are inside - \returns returns the squared average - */ - double M2() const - { - return ( (m_n > 1) ? m_newM2/m_n : 0.0 ); - } - - /** returns the variance, 0 if no elements are inside - \returns returns the variance - */ - inline double Variance() const - { - return ( (m_n > 1) ? (M2()-Mean()*Mean()) : 0.0 ); - } - - /** returns the standard deviation, 0 if no elements are inside - \returns returns the standard deviation - */ - inline double StandardDeviation() const - { - return ( (Variance() > 0) ? sqrt( Variance() ) : -1 ); - } - - private: - int n; /**< number of samples parameter */ - int m_n; /**< current number of elements */ - double m_newM; /**< accumulated average */ - double m_newM2; /**< accumulated squared average */ - }; -#endif diff --git a/slsReceiverSoftware/slsDetectorCalibration/RunningStat.h b/slsReceiverSoftware/slsDetectorCalibration/RunningStat.h deleted file mode 100755 index 1197ffc0f..000000000 --- a/slsReceiverSoftware/slsDetectorCalibration/RunningStat.h +++ /dev/null @@ -1,55 +0,0 @@ - class RunningStat - { - public: - RunningStat() : m_n(0) {} - - void Clear() - { - m_n = 0; - } - - void Push(double x) - { - m_n++; - - // See Knuth TAOCP vol 2, 3rd edition, page 232 - if (m_n == 1) - { - m_oldM = m_newM = x; - m_oldS = 0.0; - } - else - { - m_newM = m_oldM + (x - m_oldM)/m_n; - m_newS = m_oldS + (x - m_oldM)*(x - m_newM); - - // set up for next iteration - m_oldM = m_newM; - m_oldS = m_newS; - } - } - - int NumDataValues() const - { - return m_n; - } - - double Mean() const - { - return (m_n > 0) ? m_newM : 0.0; - } - - double Variance() const - { - return ( (m_n > 1) ? m_newS/(m_n - 1) : 0.0 ); - } - - double StandardDeviation() const - { - return sqrt( Variance() ); - } - - private: - int m_n; - double m_oldM, m_newM, m_oldS, m_newS; - }; diff --git a/slsReceiverSoftware/slsDetectorCalibration/chiptestBoardData.h b/slsReceiverSoftware/slsDetectorCalibration/chiptestBoardData.h deleted file mode 100644 index 0ef633c44..000000000 --- a/slsReceiverSoftware/slsDetectorCalibration/chiptestBoardData.h +++ /dev/null @@ -1,89 +0,0 @@ -#ifndef CHIPTESTDATA_H -#define CHIPTESTDATA_H - -#include "slsDetectorData.h" - -class chiptestBoardData : public slsDetectorData { - - - public: - - /** - chiptestBoard data structure. Works for data acquired using the chiptestBoard. - Inherits and implements slsDetectorData. - - Constructor (no error checking if datasize and offsets are compatible!) - \param npx number of pixels in the x direction - \param npy number of pixels in the y direction (1 for strips) - \param nadc number of adcs - \param offset offset at the beginning of the pattern - \param dMap array of size nx*ny storing the pointers to the data in the dataset (as offset) - \param dMask Array of size nx*ny storing the polarity of the data in the dataset (should be 0 if no inversion is required, 0xffffffff is inversion is required) - \param dROI Array of size nx*ny. The elements are 1s if the channel is good or in the ROI, 0 is bad or out of the ROI. NULL (default) means all 1s. - - */ - chiptestBoardData(int npx, int npy, int nadc, int offset, int **dMap=NULL, uint16_t **dMask=NULL, int **dROI=NULL): slsDetectorData(npx, npy, nadc*(npx*npy)+offset, dMap, dMask, dROI), nAdc(nadc), offSize(offset), iframe(0) {}; // should be? nadc*(npx*npy+offset) - - - - /** - - Returns the frame number for the given dataset. Virtual func: works for slsDetectorReceiver data (also for each packet), but can be overloaded. - \param buff pointer to the dataset - \returns frame number - - */ - - virtual int getFrameNumber(char *buff){(void)buff; return iframe;}; - - - /** - - Loops over a memory slot until a complete frame is found (i.e. all packets 0 to nPackets, same frame number). Can be overloaded for different kind of detectors! - \param data pointer to the memory to be analyzed - \param ndata size of frame returned - \param dsize size of the memory slot to be analyzed - \returns always return the pointer to data (no frame loss!) - */ - - virtual char *findNextFrame(char *data, int &ndata, int dsize) {ndata=dsize;setDataSize(dsize); return data;}; - - /** - Loops over a file stream until a complete frame is found (i.e. all packets 0 to nPackets, same frame number). Can be overloaded for different kind of detectors! - \param filebin input file stream (binary) - \returns pointer to the first packet of the last good frame, NULL if no frame is found or last frame is incomplete - */ - - virtual char *readNextFrame(ifstream &filebin) { - - int afifo_length=0; - uint16_t *afifo_cont; - - if (filebin.is_open()) { - if (filebin.read((char*)&afifo_length,sizeof(uint32_t))) { - setDataSize(afifo_length*nAdc*sizeof(uint16_t)); - afifo_cont=new uint16_t[afifo_length*nAdc]; - if (filebin.read((char*)afifo_cont,afifo_length*sizeof(uint16_t)*nAdc)) { - iframe++; - return (char*)afifo_cont; - } else { - delete [] afifo_cont; - return NULL; - } - } else { - return NULL; - } - } - return NULL; - }; - - private: - const int nAdc; /**0) cmStat[i].Calc(cmPed[i]/nCm[i]); - nCm[i]=0; - cmPed[i]=0; - }}; - - /** adds the pixel to the sum of pedestals -- virtual func must be overloaded to define the regions of interest - \param val value to add - \param ix pixel x coordinate - \param iy pixel y coordinate - */ - virtual void addToCommonMode(double val, int ix=0, int iy=0) { - (void) ix; (void) iy; - - //if (isc>=0 && isc0) return cmPed[0]/nCm[0]-cmStat[0].Mean(); - return 0;}; - - - - - - protected: - MovingStat *cmStat; /**SetName("cds_g4"); - hs2N->SetTitle("cds_g4"); - (TH2F*)(hs2N->GetHists()->At(0))->Write(); - - (TH2F*)(hs2N->GetHists()->At(1))->Write(); - (TH2F*)(hs2N->GetHists()->At(2))->Write(); - (TH2F*)(hs2N->GetHists()->At(3))->Write(); - (TH2F*)(hs2N->GetHists()->At(4))->Write(); - - - fout->Close(); - - - -} - diff --git a/slsReceiverSoftware/slsDetectorCalibration/doxy.config b/slsReceiverSoftware/slsDetectorCalibration/doxy.config deleted file mode 100644 index 7d2a396ff..000000000 --- a/slsReceiverSoftware/slsDetectorCalibration/doxy.config +++ /dev/null @@ -1,85 +0,0 @@ -# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in -# documentation are documented, even if no documentation was available. -# Private class members and static file members will be hidden unless -# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES - -EXTRACT_ALL = YES - -# If the EXTRACT_PRIVATE tag is set to YES all private members of a class -# will be included in the documentation. - -EXTRACT_PRIVATE = NO - - - -# If the EXTRACT_STATIC tag is set to YES all static members of a file -# will be included in the documentation. - -EXTRACT_STATIC = YES - -# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) -# defined locally in source files will be included in the documentation. -# If set to NO only classes defined in header files are included. - -EXTRACT_LOCAL_CLASSES = YES - -# This flag is only useful for Objective-C code. When set to YES local -# methods, which are defined in the implementation section but not in -# the interface are included in the documentation. -# If set to NO (the default) only methods in the interface are included. - -EXTRACT_LOCAL_METHODS = YES - -# If this flag is set to YES, the members of anonymous namespaces will be -# extracted and appear in the documentation as a namespace called -# 'anonymous_namespace{file}', where file will be replaced with the base -# name of the file that contains the anonymous namespace. By default -# anonymous namespace are hidden. - -EXTRACT_ANON_NSPACES = NO - -# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all -# undocumented members of documented classes, files or namespaces. -# If set to NO (the default) these members will be included in the -# various overviews, but no documentation section is generated. -# This option has no effect if EXTRACT_ALL is enabled. - -HIDE_UNDOC_MEMBERS = NO - -# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all -# undocumented classes that are normally visible in the class hierarchy. -# If set to NO (the default) these classes will be included in the various -# overviews. This option has no effect if EXTRACT_ALL is enabled. - -HIDE_UNDOC_CLASSES = NO - -# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all -# friend (class|struct|union) declarations. -# If set to NO (the default) these declarations will be included in the -# documentation. - -HIDE_FRIEND_COMPOUNDS = NO - -INTERNAL_DOCS = NO - -SHOW_INCLUDE_FILES = NO - -SHOW_FILES = NO - -SHOW_NAMESPACES = NO - -COMPACT_LATEX = YES - -PAPER_TYPE = a4 - -PDF_HYPERLINKS = YES - -USE_PDFLATEX = YES - -LATEX_HIDE_INDICES = YES - -PREDEFINED = __cplusplus - -INPUT = MovingStat.h slsDetectorData.h slsReceiverData.h moench02ModuleData.h pedestalSubtraction.h commonModeSubtraction.h moenchCommonMode.h singlePhotonDetector.h energyCalibration.h moenchReadData.C single_photon_hit.h chiptestBoardData.h jungfrau02Data.h jungfrauReadData.C jungfrau02CommonMode.h -OUTPUT_DIRECTORY = docs - diff --git a/slsReceiverSoftware/slsDetectorCalibration/energyCalibration.cpp b/slsReceiverSoftware/slsDetectorCalibration/energyCalibration.cpp deleted file mode 100644 index 691122095..000000000 --- a/slsReceiverSoftware/slsDetectorCalibration/energyCalibration.cpp +++ /dev/null @@ -1,527 +0,0 @@ -#include "energyCalibration.h" - -#ifdef __CINT -#define MYROOT -#endif - - -#ifdef MYROOT -#include -#include -#include -#include -#endif - -#include - -#define max(a,b) ((a) > (b) ? (a) : (b)) -#define min(a,b) ((a) < (b) ? (a) : (b)) -#define ELEM_SWAP(a,b) { register int t=(a);(a)=(b);(b)=t; } - - -using namespace std; - -#ifdef MYROOT - -Double_t energyCalibrationFunctions::pedestal(Double_t *x, Double_t *par) { - return par[0]-par[1]*sign*x[0]; -} - - -Double_t energyCalibrationFunctions::gaussChargeSharing(Double_t *x, Double_t *par) { - Double_t f, arg=0; - if (par[3]!=0) arg=sign*(x[0]-par[2])/par[3]; - f=TMath::Exp(-1*arg*arg/2.); - f=f+par[5]/2.*(TMath::Erfc(arg/(TMath::Sqrt(2.)))); - return par[4]*f+pedestal(x,par); -} - -Double_t energyCalibrationFunctions::gaussChargeSharingPixel(Double_t *x, Double_t *par) { - Double_t f; - if (par[3]<=0 || par[2]*(*x)<=0 || par[5]<0 || par[4]<=0) return 0; - - Double_t pp[3]; - - pp[0]=0; - pp[1]=par[2]; - pp[2]=par[3]; - - - f=(par[5]-par[6]*(TMath::Log(*x/par[2])))*erfBox(x,pp); - f+=par[4]*TMath::Gaus(*x, par[2], par[3], kTRUE); - return f+pedestal(x,par); -} - -Double_t energyCalibrationFunctions::erfBox(Double_t *z, Double_t *par) { - - - - Double_t m=par[0]; - Double_t M=par[1]; - - if (par[0]>par[1]) { - m=par[1]; - M=par[0]; - } - - if (m==M) - return 0; - - - if (par[2]<=0) { - if (*z>=m && *z<=M) - return 1./(M-m); - else - return 0; - - } - - return (TMath::Erfc((z[0]-M)/par[2])-TMath::Erfc((z[0]-m)/par[2]))*0.5/(M-m); - -} - - -// basic erf function -Double_t energyCalibrationFunctions::erfFunction(Double_t *x, Double_t *par) { - double arg=0; - if (par[1]!=0) arg=(par[0]-x[0])/par[1]; - return ((par[2]/2.*(1+TMath::Erf(sign*arg/(TMath::Sqrt(2)))))); -}; - - -Double_t energyCalibrationFunctions::erfFunctionChargeSharing(Double_t *x, Double_t *par) { - Double_t f; - - f=erfFunction(x, par+2)*(1+par[5]*(par[2]-x[0]))+par[0]-par[1]*x[0]*sign; - return f; -}; - - -Double_t energyCalibrationFunctions::erfFuncFluo(Double_t *x, Double_t *par) { - Double_t f; - f=erfFunctionChargeSharing(x, par)+erfFunction(x, par+6)*(1+par[9]*(par[6]-x[0])); - return f; -}; -#endif - -double energyCalibrationFunctions::median(double *x, int n){ - // sorts x into xmed array and returns median - // n is number of values already in the xmed array - double xmed[n]; - int k,i,j; - - for (i=0; i*(x+j)) - k++; - if (*(x+i)==*(x+j)) { - if (i>j) - k++; - } - } - xmed[k]=*(x+i); - } - k=n/2; - return xmed[k]; -} - - -int energyCalibrationFunctions::quick_select(int arr[], int n){ - int low, high ; - int median; - int middle, ll, hh; - - low = 0 ; high = n-1 ; median = (low + high) / 2; - for (;;) { - if (high <= low) /* One element only */ - return arr[median] ; - - if (high == low + 1) { /* Two elements only */ - if (arr[low] > arr[high]) - ELEM_SWAP(arr[low], arr[high]) ; - return arr[median] ; - } - - /* Find median of low, middle and high items; swap into position low */ - middle = (low + high) / 2; - if (arr[middle] > arr[high]) ELEM_SWAP(arr[middle], arr[high]) ; - if (arr[low] > arr[high]) ELEM_SWAP(arr[low], arr[high]) ; - if (arr[middle] > arr[low]) ELEM_SWAP(arr[middle], arr[low]) ; - - /* Swap low item (now in position middle) into position (low+1) */ - ELEM_SWAP(arr[middle], arr[low+1]) ; - - /* Nibble from each end towards middle, swapping items when stuck */ - ll = low + 1; - hh = high; - for (;;) { - do ll++; while (arr[low] > arr[ll]) ; - do hh--; while (arr[hh] > arr[low]) ; - - if (hh < ll) - break; - - ELEM_SWAP(arr[ll], arr[hh]) ; - } - - /* Swap middle item (in position low) back into correct position */ - ELEM_SWAP(arr[low], arr[hh]) ; - - /* Re-set active partition */ - if (hh <= median) - low = ll; - if (hh >= median) - high = hh - 1; - } -} - -int energyCalibrationFunctions::kth_smallest(int *a, int n, int k){ - register int i,j,l,m ; - register double x ; - - l=0 ; m=n-1 ; - while (lSetParNames("Background Offset","Background Slope","Inflection Point","Noise RMS", "Number of Photons","Charge Sharing Slope"); - - fspectrum=new TF1("fspectrum",funcs,&energyCalibrationFunctions::spectrum,0,1000,6,"energyCalibrationFunctions","spectrum"); - fspectrum->SetParNames("Background Pedestal","Background slope", "Peak position","Noise RMS", "Number of Photons","Charge Sharing Pedestal"); - - fspixel=new TF1("fspixel",funcs,&energyCalibrationFunctions::spectrumPixel,0,1000,7,"energyCalibrationFunctions","spectrumPixel"); - fspixel->SetParNames("Background Pedestal","Background slope", "Peak position","Noise RMS", "Number of Photons","Charge Sharing Pedestal","Corner"); - -#endif - - -} - - - -void energyCalibration::fixParameter(int ip, Double_t val){ - - fscurve->FixParameter(ip, val); - fspectrum->FixParameter(ip, val); -} - - -void energyCalibration::releaseParameter(int ip){ - - fscurve->ReleaseParameter(ip); - fspectrum->ReleaseParameter(ip); -} - - - - - - - -energyCalibration::~energyCalibration(){ -#ifdef MYROOT - delete fscurve; - delete fspectrum; -#endif - -} - -#ifdef MYROOT - - - - - -TH1F* energyCalibration::createMedianHistogram(TH2F* h2, int ch0, int nch, int direction) { - - if (h2==NULL || nch==0) - return NULL; - - double *x=new double[nch]; - TH1F *h1=NULL; - - double val=-1; - - if (direction==0) { - h1=new TH1F("median","Median",h2->GetYaxis()->GetNbins(),h2->GetYaxis()->GetXmin(),h2->GetYaxis()->GetXmax()); - for (int ib=0; ibGetXaxis()->GetNbins(); ib++) { - for (int ich=0; ichGetBinContent(ch0+ich+1,ib+1); - } - val=energyCalibrationFunctions::median(x, nch); - h1->SetBinContent(ib+1,val); - } - } else if (direction==1) { - h1=new TH1F("median","Median",h2->GetXaxis()->GetNbins(),h2->GetXaxis()->GetXmin(),h2->GetXaxis()->GetXmax()); - for (int ib=0; ibGetYaxis()->GetNbins(); ib++) { - for (int ich=0; ichGetBinContent(ib+1,ch0+ich+1); - } - val=energyCalibrationFunctions::median(x, nch); - h1->SetBinContent(ib+1,val); - } - } - delete [] x; - - return h1; - -} - - - - - - - - - - - - - - -void energyCalibration::setStartParameters(Double_t *par){ - bg_offset=par[0]; - bg_slope=par[1]; - flex=par[2]; - noise=par[3]; - ampl=par[4]; - cs_slope=par[5]; -} - - -void energyCalibration::getStartParameters(Double_t *par){ - par[0]=bg_offset; - par[1]=bg_slope; - par[2]=flex; - par[3]=noise; - par[4]=ampl; - par[5]=cs_slope; -} - -#endif -int energyCalibration::setChargeSharing(int p) { - if (p>=0) { - cs_flag=p; -#ifdef MYROOT - if (p) { - fscurve->ReleaseParameter(5); - fspectrum->ReleaseParameter(1); - } else { - fscurve->FixParameter(5,0); - fspectrum->FixParameter(1,0); - } -#endif - } - - return cs_flag; -} - - -#ifdef MYROOT -void energyCalibration::initFitFunction(TF1 *fun, TH1 *h1) { - - Double_t min=fit_min, max=fit_max; - - Double_t mypar[6]; - - if (max==-1) - max=h1->GetXaxis()->GetXmax(); - - if (min==-1) - min=h1->GetXaxis()->GetXmin(); - - - if (bg_offset==-1) - mypar[0]=0; - else - mypar[0]=bg_offset; - - - if (bg_slope==-1) - mypar[1]=0; - else - mypar[1]=bg_slope; - - - if (flex==-1) - mypar[2]=(min+max)/2.; - else - mypar[2]=flex; - - - if (noise==-1) - mypar[3]=0.1; - else - mypar[3]=noise; - - if (ampl==-1) - mypar[4]=h1->GetBinContent(h1->GetXaxis()->FindBin(0.5*(max+min))); - else - mypar[4]=ampl; - - if (cs_slope==-1) - mypar[5]=0; - else - mypar[5]=cs_slope; - - fun->SetParameters(mypar); - - fun->SetRange(min,max); - -} - - -TF1* energyCalibration::fitFunction(TF1 *fun, TH1 *h1, Double_t *mypar, Double_t *emypar) { - - - TF1* fitfun; - - char fname[100]; - - strcpy(fname, fun->GetName()); - - if (plot_flag) { - h1->Fit(fname,"R0Q"); - } else - h1->Fit(fname,"R0Q"); - - - fitfun= h1->GetFunction(fname); - fitfun->GetParameters(mypar); - for (int ip=0; ip<6; ip++) { - emypar[ip]=fitfun->GetParError(ip); - } - return fitfun; -} - -TF1* energyCalibration::fitSCurve(TH1 *h1, Double_t *mypar, Double_t *emypar) { - initFitFunction(fscurve,h1); - return fitFunction(fscurve, h1, mypar, emypar); -} - - - - - -TF1* energyCalibration::fitSpectrum(TH1 *h1, Double_t *mypar, Double_t *emypar) { - initFitFunction(fspectrum,h1); - return fitFunction(fspectrum, h1, mypar, emypar); -} - - - -TGraphErrors* energyCalibration::linearCalibration(int nscan, Double_t *en, Double_t *een, Double_t *fl, Double_t *efl, Double_t &gain, Double_t &off, Double_t &egain, Double_t &eoff) { - - TGraphErrors *gr; - - Double_t mypar[2]; - - gr = new TGraphErrors(nscan,en,fl,een,efl); - - if (plot_flag) { - gr->Fit("pol1"); - gr->SetMarkerStyle(20); - } else - gr->Fit("pol1","0Q"); - - TF1 *fitfun= gr->GetFunction("pol1"); - fitfun->GetParameters(mypar); - - egain=fitfun->GetParError(1); - eoff=fitfun->GetParError(0); - - gain=funcs->setScanSign()*mypar[1]; - - off=mypar[0]; - - return gr; -} - - -TGraphErrors* energyCalibration::calibrate(int nscan, Double_t *en, Double_t *een, TH1F **h1, Double_t &gain, Double_t &off, Double_t &egain, Double_t &eoff, int integral) { - - TH1F *h; - - Double_t mypar[6], emypar[6]; - Double_t fl[nscan], efl[nscan]; - - - for (int ien=0; ien -#include -class TH1F; -class TH2F; -class TGraphErrors; -#endif - - -using namespace std; - - - - -const double conven=1000./3.6; /**< electrons/keV */ -const double el=1.67E-4; /**< electron charge in fC */ - - - -/** - \mainpage Common Root library for SLS detectors data analysis - * - * \section intro_sec Introduction - We know very well s-curves etc. but at the end everybody uses different functions ;-). - - * \subsection mot_sec Motivation - It would be greate to use everybody the same functions... - -*/ - - -/** - * - * -@libdoc The energiCalibration class contains all the necessary functions for s-curve fitting and linear calibration of the threshold. - * - * @short Energy calibration functions - * @author Anna Bergamaschi - * @version 0.1alpha - - - */ - -/** - class containing all the possible energy calibration functions (scurves with and without charge sharing, gaussian spectrum with and without charge sharing, possibility of chosing the sign of the X-axis) - -*/ -class energyCalibrationFunctions { - - public: - - energyCalibrationFunctions(int s=-1) {setScanSign(s);}; - - /** sets scan sign - \param s can be 1 (energy and x-axis have the same direction) or -1 (energy and x-axis have opposite directions) otherwise gets - \returns current scan sign can be 1 (energy and x-axis have the same direction) or -1 (energy and x-axis have opposite directions) - */ - int setScanSign(int s=0) {if (s==1 || s==-1) sign=s; return sign;};; - - -#ifdef MYROOT - /** - Gaussian Function with charge sharing pedestal - par[0] is the absolute height of the background pedestal - par[1] is the slope of the background pedestal - */ - Double_t pedestal(Double_t *x, Double_t *par); - - /** - Gaussian Function with charge sharing pedestal - par[0] is the absolute height of the background pedestal - par[1] is the slope of the background pedestal - par[2] is the gaussian peak position - par[3] is the RMS of the gaussian (and of the pedestal) - par[4] is the height of the function - par[5] is the fractional height of the charge sharing pedestal (scales with par[3]) - */ - Double_t gaussChargeSharing(Double_t *x, Double_t *par); - /** - Gaussian Function with charge sharing pedestal - par[0] is the absolute height of the background pedestal - par[1] is the slope of the background pedestal - par[2] is the gaussian peak position - par[3] is the RMS of the gaussian (and of the pedestal) - par[4] is the height of the function - par[5] is the fractional height of the charge sharing pedestal (scales with par[3]) - */ - Double_t gaussChargeSharingPixel(Double_t *x, Double_t *par); - - /** - Basic erf function - par[0] is the inflection point - par[1] is the RMS - par[2] is the amplitude - */ -Double_t erfFunction(Double_t *x, Double_t *par) ; - Double_t erfBox(Double_t *z, Double_t *par); - /** Erf function with charge sharing slope - par[0] is the pedestal - par[1] is the slope of the pedestal - par[2] is the inflection point - par[3] is the RMS - par[4] is the amplitude - par[5] is the angual coefficient of the charge sharing slope (scales with par[3]) - */ -Double_t erfFunctionChargeSharing(Double_t *x, Double_t *par); - - /** Double Erf function with charge sharing slope - par[0] is the pedestal - par[1] is the slope of the pedestal - par[2] is the inflection point of the first energy - par[3] is the RMS of the first energy - par[4] is the amplitude of the first energy - par[5] is the angual coefficient of the charge sharing slope of the first energy (scales with par[3]) - par[6] is the inflection point of the second energy - par[7] is the RMS of the second energy - par[8] is the amplitude of the second energy - par[9] is the angual coefficient of the charge sharing slope of the second energy (scales with par[8]) - */ - -Double_t erfFuncFluo(Double_t *x, Double_t *par); - - - /** - static function Gaussian with charge sharing pedestal with the correct scan sign - par[0] is the absolute height of the background pedestal - par[1] is the slope of the pedestal - par[2] is the gaussian peak position - par[3] is the RMS of the gaussian (and of the pedestal) - par[4] is the height of the function - par[5] is the fractional height of the charge sharing pedestal (scales with par[4] - */ - Double_t spectrum(Double_t *x, Double_t *par); - - /** - static function Gaussian with charge sharing pedestal with the correct scan sign - par[0] is the absolute height of the background pedestal - par[1] is the slope of the pedestal - par[2] is the gaussian peak position - par[3] is the RMS of the gaussian (and of the pedestal) - par[4] is the height of the function - par[5] is the fractional height of the charge sharing pedestal (scales with par[4] - */ - Double_t spectrumPixel(Double_t *x, Double_t *par); - - - /** Erf function with charge sharing slope with the correct scan sign - par[0] is the pedestal - par[1] is the slope of the pedestal - par[2] is the inflection point - par[3] is the RMS - par[4] is the amplitude - par[5] is the angual coefficient of the charge sharing slope (scales with par[3]) - */ - Double_t scurve(Double_t *x, Double_t *par); - - - - /** Double Erf function with charge sharing slope - par[0] is the pedestal - par[1] is the slope of the pedestal - par[2] is the inflection point of the first energy - par[3] is the RMS of the first energy - par[4] is the amplitude of the first energy - par[5] is the angual coefficient of the charge sharing slope of the first energy (scales with par[3]) - par[6] is the inflection point of the second energy - par[7] is the RMS of the second energy - par[8] is the amplitude of the second energy - par[9] is the angual coefficient of the charge sharing slope of the second energy (scales with par[8]) - */ - Double_t scurveFluo(Double_t *x, Double_t *par); - -#endif - -/** Calculates the median of an array of n elements */ - static double median(double *x, int n); -/** Calculates the median of an array of n elements (swaps the arrays!)*/ - static int quick_select(int arr[], int n); -/** Calculates the median of an array of n elements (swaps the arrays!)*/ - static int kth_smallest(int *a, int n, int k); - - private: - int sign; - - -}; - -/** - class alowing the energy calibration of photon counting and anlogue detectors - -*/ - -class energyCalibration { - - - public: - /** - default constructor - creates the function with which the s-curves will be fitted - */ - energyCalibration(); - - /** - default destructor - deletes the function with which the s-curves will be fitted - */ - ~energyCalibration(); - - /** sets plot flag - \param p plot flag (-1 gets, 0 unsets, >0 plot) - \returns current plot flag - */ - int setPlotFlag(int p=-1) {if (p>=0) plot_flag=p; return plot_flag;}; - - /** sets scan sign - \param s can be 1 (energy and x-axis have the same direction) or -1 (energy and x-axis have opposite directions) otherwise gets - \returns current scan sign can be 1 (energy and x-axis have the same direction) or -1 (energy and x-axis have opposite directions) - */ - int setScanSign(int s=0) {return funcs->setScanSign(s);}; - - /** sets plot flag - \param p plot flag (-1 gets, 0 unsets, >0 plot) - \returns current plot flag - */ - int setChargeSharing(int p=-1); - - - void fixParameter(int ip, Double_t val); - - void releaseParameter(int ip); - -#ifdef MYROOT - - /** - Creates an histogram with the median of nchannels starting from a specified one. the direction on which it is mediated can be selected (defaults to x=0) - \param h2 2D histogram on which the median will be calculated - \param ch0 starting channel - \param nch number of channels to be mediated - \param direction can be either 0 (x, default) or 1 (y) - \returns a TH1F histogram with the X-axis as a clone of the h2 Y (if direction=0) or X (if direction=0) axis, and on the Y axis the median of the counts of the mediated channels f h2 - */ - static TH1F* createMedianHistogram(TH2F* h2, int ch0, int nch, int direction=0); - - - /** sets the s-curve fit range - \param mi minimum of the fit range (-1 is histogram x-min) - \param ma maximum of the fit range (-1 is histogram x-max) - */ - void setFitRange(Double_t mi, Double_t ma){fit_min=mi; fit_max=ma;}; - - /** gets the s-curve fit range - \param mi reference for minimum of the fit range (-1 is histogram x-min) - \param ma reference for maximum of the fit range (-1 is histogram x-max) - */ - void getFitRange(Double_t &mi, Double_t &ma){mi=fit_min; ma=fit_max;}; - - -/** set start parameters for the s-curve function - \param par parameters, -1 sets to auto-calculation - par[0] is the pedestal - par[1] is the slope of the pedestal - par[2] is the inflection point - par[3] is the RMS - par[4] is the amplitude - par[5] is the angual coefficient of the charge sharing slope (scales with par[3]) -- always positive - */ - void setStartParameters(Double_t *par); - -/** get start parameters for the s-curve function - \param par parameters, -1 means auto-calculated - par[0] is the pedestal - par[1] is the slope of the pedestal - par[2] is the inflection point - par[3] is the RMS - par[4] is the amplitude - par[5] is the angual coefficient of the charge sharing slope (scales with par[3]) -- always positive - */ - void getStartParameters(Double_t *par); - - /** - fits histogram with the s-curve function - \param h1 1d-histogram to be fitted - \param mypar pointer to fit parameters array - \param emypar pointer to fit parameter errors - \returns the fitted function - can be used e.g. to get the Chi2 or similar - */ - TF1 *fitSCurve(TH1 *h1, Double_t *mypar, Double_t *emypar); - - - /** - fits histogram with the spectrum - \param h1 1d-histogram to be fitted - \param mypar pointer to fit parameters array - \param emypar pointer to fit parameter errors - \returns the fitted function - can be used e.g. to get the Chi2 or similar - */ - TF1 *fitSpectrum(TH1 *h1, Double_t *mypar, Double_t *emypar); - - - /** - calculates gain and offset for the set of inflection points - \param nscan number of energy scans - \param en array of energies (nscan long) - \param een array of errors on energies (nscan long) - can be NULL! - \param fl array of inflection points (nscan long) - \param efl array of errors on the inflection points (nscan long) - \param gain reference to gain resulting from the fit - \param off reference to offset resulting from the fit - \param egain reference to error on the gain resulting from the fit - \param eoff reference to the error on the offset resulting from the fit - \returns graph energy vs inflection point - */ - TGraphErrors* linearCalibration(int nscan, Double_t *en, Double_t *een, Double_t *fl, Double_t *efl, Double_t &gain, Double_t &off, Double_t &egain, Double_t &eoff); - - /** - calculates gain and offset for the set of energy scans - \param nscan number of energy scans - \param en array of energies (nscan long) - \param een array of errors on energies (nscan long) - can be NULL! - \param h1 array of TH1 - \param gain reference to gain resulting from the fit - \param off reference to offset resulting from the fit - \param egain reference to error on the gain resulting from the fit - \param eoff reference to the error on the offset resulting from the fit - \returns graph energy vs inflection point - */ - TGraphErrors* calibrateScurves(int nscan, Double_t *en, Double_t *een, TH1F **h1, Double_t &gain, Double_t &off, Double_t &egain, Double_t &eoff){return calibrate(nscan, en, een, h1, gain, off, egain, eoff, 1);}; - - /** - calculates gain and offset for the set of energy spectra - \param nscan number of energy scans - \param en array of energies (nscan long) - \param een array of errors on energies (nscan long) - can be NULL! - \param h1 array of TH1 - \param gain reference to gain resulting from the fit - \param off reference to offset resulting from the fit - \param egain reference to error on the gain resulting from the fit - \param eoff reference to the error on the offset resulting from the fit - \returns graph energy vs peak - */ - TGraphErrors* calibrateSpectra(int nscan, Double_t *en, Double_t *een, TH1F **h1, Double_t &gain, Double_t &off, Double_t &egain, Double_t &eoff){return calibrate(nscan, en, een, h1, gain, off, egain, eoff, 0);}; - - -#endif - private: - -#ifdef MYROOT - /** - calculates gain and offset for the set of energies - \param nscan number of energy scans - \param en array of energies (nscan long) - \param een array of errors on energies (nscan long) - can be NULL! - \param h1 array of TH1 - \param gain reference to gain resulting from the fit - \param off reference to offset resulting from the fit - \param egain reference to error on the gain resulting from the fit - \param eoff reference to the error on the offset resulting from the fit - \param integral 1 is an s-curve set (default), 0 spectra - \returns graph energy vs peak/inflection point - */ - TGraphErrors* calibrate(int nscan, Double_t *en, Double_t *een, TH1F **h1, Double_t &gain, Double_t &off, Double_t &egain, Double_t &eoff, int integral=1); - - - /** - Initializes the start parameters and the range of the fit depending on the histogram characteristics and/or on the start parameters specified by the user - \param fun pointer to function to be initialized - \param h1 histogram from which to extract the range and start parameters, if not already specified by the user - -*/ - - void initFitFunction(TF1 *fun, TH1 *h1); - - - /** - Performs the fit according to the flags specified and returns the fitted function - \param fun function to fit - \param h1 histogram to fit - \param mypar pointer to fit parameters array - \param emypar pointer to fit parameter errors - \returns the fitted function - can be used e.g. to get the Chi2 or similar - */ - TF1 *fitFunction(TF1 *fun, TH1 *h1, Double_t *mypar, Double_t *emypar); - -#endif - -#ifdef MYROOT - Double_t fit_min; /**< minimum of the s-curve fitting range, -1 is histogram x-min */ - Double_t fit_max; /**< maximum of the s-curve fitting range, -1 is histogram x-max */ - - Double_t bg_offset; /**< start value for the background pedestal */ - Double_t bg_slope; /**< start value for the background slope */ - Double_t flex; /**< start value for the inflection point */ - Double_t noise; /**< start value for the noise */ - Double_t ampl; /**< start value for the number of photons */ - Double_t cs_slope; /**< start value for the charge sharing slope */ - - - TF1 *fscurve; /**< function with which the s-curve will be fitted */ - - TF1 *fspectrum; /**< function with which the spectrum will be fitted */ - - TF1 *fspixel; /**< function with which the spectrum will be fitted */ - -#endif - - energyCalibrationFunctions *funcs; - int plot_flag; /**< 0 does not plot, >0 plots (flags?) */ - - int cs_flag; /**< 0 functions without charge sharing contribution, >0 with charge sharing contribution */ - -}; - -#endif - - - - - - - - - - - - - - - - - - - diff --git a/slsReceiverSoftware/slsDetectorCalibration/gMapDemo.C b/slsReceiverSoftware/slsDetectorCalibration/gMapDemo.C deleted file mode 100644 index 51addf69a..000000000 --- a/slsReceiverSoftware/slsDetectorCalibration/gMapDemo.C +++ /dev/null @@ -1,11 +0,0 @@ -{ - //.L energyCalibration.cpp+ - //.L gainMap.C+ - TFile fin("/data/moench_xbox_20140113/MoTarget_45kV_0_8mA_120V_cds_g4.root"); - TH2F *h2=fin.Get("h2"); - TH2F *gMap=gainMap(h2,4); - gMap->Draw("colz"); - - - -} diff --git a/slsReceiverSoftware/slsDetectorCalibration/gainMap.C b/slsReceiverSoftware/slsDetectorCalibration/gainMap.C deleted file mode 100644 index 7923fe687..000000000 --- a/slsReceiverSoftware/slsDetectorCalibration/gainMap.C +++ /dev/null @@ -1,228 +0,0 @@ -#define MYROOT -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace std; - - -#define FOPT "0" - -TH2F *gainMap(TH2F *h2, float g) { - // int npx, npy; - int npx=160, npy=160; - // det->getDetectorSize(npx, npy); - - TH2F *gMap=new TH2F("gmap",h2->GetTitle(), npx, -0.5, npx-0.5, npy, -0.5, npy-0.5); - - Double_t ens[3]={0,8,17.5}, eens[3]={0.,0.1,0.1}; - Double_t peaks[3], epeaks[3]; - - - - int ibin; - TH1D *px; - - - energyCalibration *enCal=new energyCalibration(); - enCal->setPlotFlag(0); - // enCal->setChargeSharing(0); - enCal->setScanSign(1); - - Double_t gain, off, egain, eoff; - - - TList *functions; - TPolyMarker *pm ; - Double_t *peakX, *peakY; - TSpectrum *s=new TSpectrum(); - Double_t mypar[10], emypar[10]; - Double_t prms, np; - int iit=0; - TGraph *glin; - Double_t peakdum, hpeakdum; - - for (int ix=1; ixProjectionX("px",ibin+1,ibin+1); - prms=10*g; - iit=0; - np=s->Search(px,prms,"",0.2); - while (np !=2) { - if (np>2) - prms+=0.5*prms; - else - prms-=0.5*prms; - iit++; - if (iit>=10) - break; - np=s->Search(px,prms,"",0.2); - } - if (np!=2) - cout << "peak search could not converge " << ibin << endl; - if (np==2) { - pm=NULL; - functions=px->GetListOfFunctions(); - if (functions) - pm = (TPolyMarker*)functions->FindObject("TPolyMarker"); - if (pm) { - peakX=pm->GetX(); - peakY=pm->GetY(); - - - if (peakX[0]>peakX[1]) { - peakdum=peakX[0]; - hpeakdum=peakY[0]; - peakX[0]= peakX[1]; - peakY[0]= peakY[1]; - peakX[1]= peakdum; - peakY[1]= hpeakdum; - - } - - cout << "("<< ix << "," << iy << ") " << endl; - for (int ip=0; ipsetFitRange(peakX[ip]-10*g,peakX[ip]+10*g); - mypar[0]=0; - mypar[1]=0; - mypar[2]=peakX[ip]; - mypar[3]=g*10; - mypar[4]=peakY[ip]; - mypar[5]=0; - - - - enCal->setStartParameters(mypar); - enCal->fitSpectrum(px,mypar,emypar); - - - peaks[ip+1]=mypar[2]; - epeaks[ip+1]=emypar[2]; - } - - peaks[0]=0; - epeaks[0]=1; - - // for (int i=0; i<3; i++) cout << i << " " << ens[i] << " " << eens[i]<< " "<< peaks[i]<< " " << epeaks[i] << endl; - - glin= enCal->linearCalibration(3,ens,eens,peaks,epeaks,gain,off,egain,eoff); - - // cout << "Gain " << gain << " off " << off << endl; - if (off>-10 && off<10) { - gMap->SetBinContent(ix+1,iy+1,gain); - gMap->SetBinError(ix+1,iy+1,egain); - } - if (glin) - delete glin; - } - } - - - } - } - - return gMap; -} - - -TH2F *noiseMap(TH2F *h2) { - // int npx, npy; - int npx=160, npy=160; - // det->getDetectorSize(npx, npy); - - TH2F *nMap=new TH2F("nmap",h2->GetTitle(), npx, -0.5, npx-0.5, npy, -0.5, npy-0.5); - - int ibin; - TH1D *px; - - for (int ix=0; ixProjectionX("px",ibin+1,ibin+1); - px->Fit("gaus", FOPT); - if (px->GetFunction("gaus")) { - nMap->SetBinContent(ix+1,iy+1,px->GetFunction("gaus")->GetParameter(2)); - } - // delete px; - } - } - - return nMap; -} - - -THStack *noiseHistos(char *tit) { - char fname[10000]; - - sprintf(fname,"/data/moench_xbox_20140116/noise_map_%s.root",tit); - TFile *fn=new TFile(fname); - TH2F *nmap=(TH2F*)fn->Get("nmap"); - - if (nmap==NULL) { - cout << "No noise map in file " << fname << endl; - - return NULL; - } - - sprintf(fname,"/data/moench_xbox_20140113/gain_map_%s.root",tit); - TFile *fg=new TFile(fname); - TH2F *gmap=(TH2F*)fg->Get("gmap"); - - if (gmap==NULL) { - cout << "No gain map in file " << fname << endl; - - return NULL; - } - - nmap->Divide(gmap); - nmap->Scale(1000./3.6); - - THStack *hs=new THStack(tit,tit); - hs->SetTitle(tit); - - TH1F *h; - char hname[100]; - - cout << tit << endl; - for (int is=0; is<4; is++) { - sprintf(hname,"h%ds",is+1); - - h=new TH1F(hname,tit,500,0,500); - hs->Add(h); - // cout << hs->GetHists()->GetEntries() << endl; - for (int ix=40*is+2; ix<40*(is+1)-2; ix++) { - - for (int iy=2; iy<158; iy++) { - if (ix<100 || ix>120) - h->Fill(nmap->GetBinContent(ix+1,iy+1)); - } - } - cout << is+1 << "SC: " << "" << h->GetMean() << "+-" << h->GetRMS(); - h->Fit("gaus","0Q"); - h->SetLineColor(is+1); - if (h->GetFunction("gaus")) { - h->GetFunction("gaus")->SetLineColor(is+1); - cout << " or " << h->GetFunction("gaus")->GetParameter(1) << "+-" << h->GetFunction("gaus")->GetParError(1); - } - cout << endl; - } - - // cout << hs->GetHists()->GetEntries() << endl; - - return hs; - - -} diff --git a/slsReceiverSoftware/slsDetectorCalibration/gotthardModuleData.h b/slsReceiverSoftware/slsDetectorCalibration/gotthardModuleData.h deleted file mode 100644 index 3f674af57..000000000 --- a/slsReceiverSoftware/slsDetectorCalibration/gotthardModuleData.h +++ /dev/null @@ -1,148 +0,0 @@ -#ifndef GOTTHARDMODULEDATA_H -#define GOTTHARDMODULEDATA_H -#include "slsReceiverData.h" - - - - - -#define FRAMEMASK 0xFFFFFFFE -#define PACKETMASK 1 -#define FRAMEOFFSET 0x1 - - -class gotthardModuleData : public slsReceiverData { -public: - - - - - /** - Implements the slsReceiverData structure for the gotthard read out by a module i.e. using the slsReceiver - (1x1280 pixels, 2 packets 1286 large etc.) - \param c crosstalk parameter for the output buffer - - */ - - - gotthardModuleData(double c=0): slsReceiverData(xpixels, ypixels, npackets, buffersize), xtalk(c) { - - uint16_t **dMask; - int **dMap; - int ix, iy; - int initial_offset = 2; - int offset = initial_offset; - - dMask=new uint16_t*[ypixels]; - dMap=new int*[ypixels]; - for (int i = 0; i < ypixels; i++) { - dMap[i] = new int[xpixels]; - dMask[i] = new uint16_t[xpixels]; - } - - for(ix=0; ix>FRAMEOFFSET); - }; - - - - /** - gets the packets number (last packet is labelled with 0 and is replaced with 40) - \param buff pointer to the memory - \returns packet number - - */ - - int getPacketNumber(char *buff){ - int np=(*(int*)buff); - //gotthards frame header must be incremented - ++np; - //packet index should be 1 or 2 - return ((np&PACKETMASK)+1); - }; - - - /** - returns the pixel value as double correcting for the output buffer crosstalk - \param data pointer to the memory - \param ix coordinate in the x direction - \param iy coordinate in the y direction - \returns channel value as double - - */ - double getValue(char *data, int ix, int iy=0) { - //check how it is for gotthard - if (xtalk==0) - return slsDetectorData::getValue(data, ix, iy); - else - return slsDetectorData::getValue(data, ix, iy)-xtalk*slsDetectorData::getValue(data, ix-1, iy); - }; - - - - /** sets the output buffer crosstalk correction parameter - \param c output buffer crosstalk correction parameter to be set - \returns current value for the output buffer crosstalk correction parameter - - */ - double setXTalk(double c) {xtalk=c; return xtalk;} - - - /** gets the output buffer crosstalk parameter - \returns current value for the output buffer crosstalk correction parameter - */ - double getXTalk() {return xtalk;} - - - - - - - -private: - - double xtalk; /** { -public: - - - - - /** - Implements the slsReceiverData structure for the gotthard short read out by a module i.e. using the slsReceiver - (1x256 pixels, 1 packet 256 large etc.) - \param c crosstalk parameter for the output buffer - - */ - - - gotthardShortModuleData(double c=0): slsReceiverData(xpixels, ypixels, npackets, buffersize), xtalk(c){ - - uint16_t **dMask; - int **dMap; - int ix, iy; - int offset = 2; - - dMask=new uint16_t*[ypixels]; - dMap=new int*[ypixels]; - for (int i = 0; i < ypixels; i++) { - dMap[i] = new int[xpixels]; - dMask[i] = new uint16_t[xpixels]; - } - - for(ix=0; ix::getValue(data, ix, iy); - else - return slsDetectorData::getValue(data, ix, iy)-xtalk*slsDetectorData::getValue(data, ix-1, iy); - }; - - - - /** sets the output buffer crosstalk correction parameter - \param c output buffer crosstalk correction parameter to be set - \returns current value for the output buffer crosstalk correction parameter - - */ - double setXTalk(double c) {xtalk=c; return xtalk;} - - - /** gets the output buffer crosstalk parameter - \returns current value for the output buffer crosstalk correction parameter - */ - double getXTalk() {return xtalk;} - - - - - - - -private: - - double xtalk; /**=0 && ix=0 && iy=0 && dataMap[iy][ix]8000) //exchange if gainBits==2 is returned! - d|=(1<<14); // gain bit 1 - if (*((uint16_t*)(data)+dataMap[iy][ix]+1)>8000) //exchange if gainBits==2 is returned! - d|=(1<<15); // gain bit 0 - - } - - } - return d^m; - }; - - /** - returns the pixel value as double correcting for the output buffer crosstalk - \param data pointer to the memory - \param ix coordinate in the x direction - \param iy coordinate in the y direction - \returns channel value as double - - */ - double getValue(char *data, int ix, int iy=0) { - // cout << "##" << (void*)data << " " << ix << " " < the gain bits are read out the wrong way around (i.e. GB0 and GB1 have to be reversed!) - \param data pointer to the memory - \param ix coordinate in the x direction - \param iy coordinate in the y direction - \returns gain bits as int - */ - int getGainBits(char *data, int ix, int iy=0) { - uint16_t d=getChannel(data, ix, iy); - return ((d&0xc000)>>14); - }; - //*/ - - - - - /** sets the output buffer crosstalk correction parameter - \param c output buffer crosstalk correction parameter to be set - \returns current value for the output buffer crosstalk correction parameter - - */ - double setXTalk(double c) {xtalk=c; return xtalk;} - - - /** gets the output buffer crosstalk parameter - \returns current value for the output buffer crosstalk correction parameter - */ - double getXTalk() {return xtalk;} - - - - - - - - private: - - double xtalk; /** -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -//#include -//#include -//#include -#include -#include "jungfrau02Data.h" -#include "jungfrau02CommonMode.h" -#include "singlePhotonDetector.h" - -//#include "MovingStat.h" - -using namespace std; - -#define NC 48 -#define NR 48 - - -#define MY_DEBUG 1 -#ifdef MY_DEBUG -#include -#endif - -/** - -Loops over data file to find single photons, fills the tree (and writes it to file, although the root file should be opened before) and creates 1x1, 2x2, 3x3 cluster histograms with ADCu on the x axis, channel number (48*x+y) on the y axis. - - \param fformat file name format - \param tit title of the tree etc. - \param runmin minimum run number - \param runmax max run number - \param nbins number of bins for spectrum hists - \param hmin histo minimum for spectrum hists - \param hmax histo maximum for spectrum hists - \param sign sign of the spectrum to find hits - \param hc readout correlation coefficient with previous pixel - \param xmin minimum x coordinate - \param xmax maximum x coordinate - \param ymin minimum y coordinate - \param ymax maximum y coordinate - \param cmsub enable commonmode subtraction - \param hitfinder if 0: performs pedestal subtraction, not hit finding; if 1: performs both pedestal subtraction and hit finding - \returns pointer to histo stack with cluster spectra -*/ - - -THStack *jungfrauReadData(char *fformat, char *tit, int runmin, int runmax, int nbins=1500, int hmin=-500, int hmax=1000, int sign=1, double hc=0, int xmin=1, int xmax=NC-1, int ymin=1, int ymax=NR-1, int cmsub=0, int hitfinder=1){ -/* - // read in calibration file - ifstream calfile("/home/l_msdetect/TriesteBeam2014/dummy data for scripts/CalibrationParametersTest_fake.txt"); - if (calfile.is_open()==0){cout << "Unable to open calibration file!" << endl;} - int pix; - double of0,sl0,of1,sl1,of2,sl2; - double of_0[NC*NR], of_1[NC*NR], of_2[NC*NR], sl_0[NC*NR], sl_1[NC*NR], sl_2[NC*NR]; - while (calfile >> pix >> of0 >> sl0 >> of1 >> sl1 >> of2 >> sl2){ - of_0[pix]=of0; - sl_0[pix]=sl0; - of_1[pix]=of1; - sl_1[pix]=sl1; - of_2[pix]=of2; - sl_2[pix]=sl2; //if(pix==200) cout << "sl_2[200] " << sl_2[200] << endl; - } - calfile.close(); -*/ - double adc_value, num_photon; - - jungfrau02Data *decoder=new jungfrau02Data(1,0,0);//(1,0,0); // (adc,offset,crosstalk) //(1,0,0) //(3,0,0) for readout of GB - jungfrau02CommonMode *cmSub=NULL; - if (cmsub) - cmSub=new jungfrau02CommonMode(); - - int nph=0; - int iev=0; - singlePhotonDetector *filter=new singlePhotonDetector(decoder, 3, 5, sign, cmSub); - - char *buff; - char fname[10000]; - int nf=0; - - eventType thisEvent=PEDESTAL; - - // int iframe; - // double *data, ped, sigma; - - // data=decoder->getCluster(); - - TH2F *h2; - TH2F *h3; - TH2F *hetaX; // not needed for JF? - TH2F *hetaY; // not needed for JF? - - THStack *hs=new THStack("hs",fformat); - - - TH2F *h1=new TH2F("h1",tit,nbins,hmin-0.5,hmax-0.5,NC*NR,-0.5,NC*NR-0.5); - hs->Add(h1); - - if (hitfinder) { - h2=new TH2F("h2",tit,nbins,hmin-0.5,hmax-0.5,NC*NR,-0.5,NC*NR-0.5); - h3=new TH2F("h3",tit,nbins,hmin-0.5,hmax-0.5,NC*NR,-0.5,NC*NR-0.5); - hetaX=new TH2F("hetaX",tit,nbins,-1,2,NC*NR,-0.5,NC*NR-0.5); // not needed for JF? - hetaY=new TH2F("hetaY",tit,nbins,-1,2,NC*NR,-0.5,NC*NR-0.5); // not needed for JF? - hs->Add(h2); - hs->Add(h3); - hs->Add(hetaX); // not needed for JF? - hs->Add(hetaY); // not needed for JF? - } - - - ifstream filebin; - - - int ix=20, iy=20, ir, ic; - - - Int_t iFrame; - TTree *tall; - if (hitfinder) - tall=filter->initEventTree(tit, &iFrame); - - - - -#ifdef MY_DEBUG - - TCanvas *myC; - TH2F *he; - TCanvas *cH1; - TCanvas *cH2; - TCanvas *cH3; - - if (hitfinder) { - myC=new TCanvas(); - he=new TH2F("he","Event Mask",xmax-xmin, xmin, xmax, ymax-ymin, ymin, ymax); - he->SetStats(kFALSE); - he->Draw("colz"); - cH1=new TCanvas(); - cH1->SetLogz(); - h1->Draw("colz"); - cH2=new TCanvas(); - cH2->SetLogz(); - h2->Draw("colz"); - cH3=new TCanvas(); - cH3->SetLogz(); - h3->Draw("colz"); - } -#endif - filter->newDataSet(); - - - for (int irun=runmin; irun<=runmax; irun++){ - sprintf(fname,fformat,irun); - cout << "file name " << fname << endl; - filebin.open((const char *)(fname), ios::in | ios::binary); - nph=0; - while ((buff=decoder->readNextFrame(filebin))) { - - - if (hitfinder) { - filter->newFrame(); - - //calculate pedestals and common modes - if (cmsub) { - // cout << "cm" << endl; - for (ix=xmin-1; ixgetEventType(buff, ix, iy,0); - } - } - } - - // cout << "new frame " << endl; - - for (ix=xmin-1; ixgetEventType(buff, ix, iy, cmsub); - int gainBits=decoder->getGainBits(buff,ix,iy); //XXX - -#ifdef MY_DEBUG - if (hitfinder) { - if (iev%1000==0) - //he->SetBinContent(ix+1-xmin, iy+1-ymin, (int)thisEvent); // show single photon hits // original - //he->SetBinContent(ix+1-xmin, iy+1-ymin, cmSub->getCommonMode(ix,iy)); //show common mode! - he->SetBinContent(iy+1-ymin, ix+1-xmin, (int)gainBits); //show gain bits - //he->SetBinContent(ix+1-xmin, iy+1-ymin, (int)gainBits); // rows and columns reversed!!! - } -#endif - - if (nf>1000) { // only start filing data after 1000 frames - - // h1->Fill(decoder->getValue(buff,ix,iy), iy+NR*ix); - h1->Fill(filter->getClusterTotal(1), iy+NR*ix); - - - if (hitfinder) { - - if (thisEvent==PHOTON_MAX ) { - nph++; - - h2->Fill(filter->getClusterTotal(2), iy+NR*ix); - h3->Fill(filter->getClusterTotal(3), iy+NR*ix); - iFrame=decoder->getFrameNumber(buff); - - tall->Fill(); - - - } - - - } - - - } - } - ////////////////////////////////////////////////////////// - -#ifdef MY_DEBUG - if (iev%1000==0) { - myC->Modified(); - myC->Update(); - cH1->Modified(); - cH1->Update(); - cH2->Modified(); - cH2->Update(); - cH3->Modified(); - cH3->Update(); - } - iev++; -#endif - nf++; - - cout << "="; // one "=" for every frame that's been processed - delete [] buff; - } - cout << nph << endl; // number of photons found in file - if (filebin.is_open()) - filebin.close(); - else - cout << "Could not open file :( ... " << fname << endl; - } - if (hitfinder) - tall->Write(tall->GetName(),TObject::kOverwrite); - - - - delete decoder; - cout << "Read " << nf << " frames." << endl; - return hs; -} - diff --git a/slsReceiverSoftware/slsDetectorCalibration/moench02ModuleData.h b/slsReceiverSoftware/slsDetectorCalibration/moench02ModuleData.h deleted file mode 100644 index 34b4f1783..000000000 --- a/slsReceiverSoftware/slsDetectorCalibration/moench02ModuleData.h +++ /dev/null @@ -1,137 +0,0 @@ -#ifndef MOENCH02MODULEDATA_H -#define MOENCH02MODULEDATA_H -#include "slsReceiverData.h" - - - -class moench02ModuleData : public slsReceiverData { - public: - - - - - /** - Implements the slsReceiverData structure for the moench02 prototype read out by a module i.e. using the slsReceiver - (160x160 pixels, 40 packets 1286 large etc.) - \param c crosstalk parameter for the output buffer - - */ - - - moench02ModuleData(double c=0): slsReceiverData(160, 160, 40, 1286), - xtalk(c) { - - - - - uint16_t **dMask; - int **dMap; - int ix, iy; - - - - dMask=new uint16_t*[160]; - dMap=new int*[160]; - for (int i = 0; i < 160; i++) { - dMap[i] = new int[160]; - dMask[i] = new uint16_t[160]; - } - - for (int isc=0; isc<4; isc++) { - for (int ip=0; ip<10; ip++) { - - for (int ir=0; ir<16; ir++) { - for (int ic=0; ic<40; ic++) { - - ix=isc*40+ic; - iy=ip*16+ir; - - dMap[iy][ix]=1286*(isc*10+ip)+2*ir*40+2*ic+4; - // cout << ix << " " << iy << " " << dMap[ix][iy] << endl; - } - } - } - } - - for (ix=0; ix<120; ix++) { - for (iy=0; iy<160; iy++) - dMask[iy][ix]=0x3fff; - } - for (ix=120; ix<160; ix++) { - for (iy=0; iy<160; iy++) - dMask[iy][ix]=0x0; - } - - - setDataMap(dMap); - setDataMask(dMask); - - - - - }; - - - - /** - gets the packets number (last packet is labelled with 0 and is replaced with 40) - \param buff pointer to the memory - \returns packet number - - */ - - int getPacketNumber(char *buff){ - int np=(*(int*)buff)&0xff; - if (np==0) - np=40; - return np; - }; - - - /** - returns the pixel value as double correcting for the output buffer crosstalk - \param data pointer to the memory - \param ix coordinate in the x direction - \param iy coordinate in the y direction - \returns channel value as double - - */ - double getValue(char *data, int ix, int iy=0) { - // cout << "##" << (void*)data << " " << ix << " " <::getValue(data, ix, iy); - else - return slsDetectorData::getValue(data, ix, iy)-xtalk*slsDetectorData::getValue(data, ix-1, iy); - }; - - - - /** sets the output buffer crosstalk correction parameter - \param c output buffer crosstalk correction parameter to be set - \returns current value for the output buffer crosstalk correction parameter - - */ - double setXTalk(double c) {xtalk=c; return xtalk;} - - - /** gets the output buffer crosstalk parameter - \returns current value for the output buffer crosstalk correction parameter - */ - double getXTalk() {return xtalk;} - - - - - - - - private: - - double xtalk; /**=0 && isc=0 && isc0) return cmPed[isc]/nCm[isc]-cmStat[isc].Mean(); - } - return 0; - }; - -}; - - -#endif diff --git a/slsReceiverSoftware/slsDetectorCalibration/moenchMakeTree.C b/slsReceiverSoftware/slsDetectorCalibration/moenchMakeTree.C deleted file mode 100644 index 372052285..000000000 --- a/slsReceiverSoftware/slsDetectorCalibration/moenchMakeTree.C +++ /dev/null @@ -1,244 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "RunningStat.h" -#include "MovingStat.h" -#include "moench02ModuleData.h" -#include - -using namespace std; - - -//tree variables - int xC,yC,iFrameC; - double meC,sigC; - Double_t dataC[3][3]; -TTree* tall; - -typedef struct task_s{ - char *fformat; - char *tname; - int runmin; - int runmax; - int sign; -} Task; - -void setUpTree(char *tname){ - tall=new TTree(tname,tname); - tall->Branch("iFrame",&iFrameC,"iframe/I"); - tall->Branch("x",&xC,"x/I"); - tall->Branch("y",&yC,"y/I"); - tall->Branch("data",dataC,"data[3][3]/D"); - tall->Branch("pedestal",&meC,"pedestal/D"); - tall->Branch("rms",&sigC,"rms/D"); -} - -inline void storeEvent(int iF,int x,int y, Double_t data[][3], double me, double sig){ - TThread::Lock(); - xC = x; yC = y; iFrameC = iF; - memcpy(dataC,data,sizeof(Double_t)*3*3); - //cout << "X: " << x << " Y: " << y << endl; - /* for(int i = 0; i < 3; i++){ - for(int j = 0; j < 3; j++){ - cout << "i: " << i << " j: " << j << " dataC " << dataC[i][j] << " data " << data[i][j] << endl; - } - }*/ - meC = me; sigC = sig; - tall->Fill(); - TThread::UnLock(); -} - -void moenchMakeTree(char *fformat, char *tname, int runmin, int runmax, int sign=1) { - double nThSigma = 3.; - moench02ModuleData *decoder=new moench02ModuleData(); - char *buff; - char fname[10000]; - - int nf=0; - - int dum, nPhotons; - double me, sig, tot, maxNei, val, valNei; - - MovingStat stat[160][160]; - MovingStat nPhotonsStat; - - ifstream filebin; - - int nbg=20; - - int ix, iy, ir, ic, mx,my; - Double_t data[3][3]; - - nPhotonsStat.Clear(); - nPhotonsStat.SetN(1000); - - for (ir=0; ir<160; ir++) { - for (ic=0; ic<160; ic++) { - stat[ir][ic].Clear(); - stat[ir][ic].SetN(nbg); - } - } - - for (int irun=runmin; irunreadNextFrame(filebin))) { - nPhotons=0; - //for (ix=0; ix<160; ix++){ - for (ix=0; ix<40; ix++){ - for (iy=0; iy<160; iy++) { - - - - dum=0; //no hit - // tot=0; - - me=stat[iy][ix].Mean(); - sig=stat[iy][ix].StandardDeviation(); - val=sign*(decoder->getChannelShort(buff,ix,iy)-me); - - - if (nf>nbg) { - me=stat[iy][ix].Mean(); - sig=stat[iy][ix].StandardDeviation(); - val=sign*decoder->getChannel(buff,ix,iy)-me; - - // dum=0; //no hit - tot=0; - maxNei = 0; - - if (val>nThSigma*sig)//{ //hit check if neighbors are higher - dum=1; - for (ir=-1; ir<2; ir++){ - for (ic=-1; ic<2; ic++){ - if ((ix+ic)>=0 && (ix+ic)<160 && (iy+ir)>=0 && (iy+ir)<160) { - valNei = sign*decoder->getChannel(buff,ix+ic,iy+ir)-stat[iy+ir][ix+ic].Mean(); - if (sign*decoder->getChannel(buff,ix+ic,iy+ir)>(stat[iy+ir][ix+ic].Mean()+3.*stat[iy+ir][ix+ic].StandardDeviation())) dum=1; //is a hit or neighbour is a hit! - tot+=valNei; - data[ir+1][ic+1] = valNei; - if(valNei/stat[iy+ir][ix+ic].StandardDeviation() > maxNei){ - maxNei = valNei/stat[iy+ir][ix+ic].StandardDeviation(); - mx = ir; - my = ic; - } - } - } - } - // } - - if (val<(-nThSigma*sig)) dum=2; //discard negative events! - - if(dum == 1 && mx == 0 && my == 0){ // this is an event and we are in the center - storeEvent(nf,ix,iy,data,me,sig); - nPhotons++; - //cout << "BF X: " << ix << " Y: " << iy << " val: " << val << " tot: " << tot << " me: " << me << " sig: " << sig << endl; - } - - - //if (tot>9.*sig && dum == 1){ dum=3;} - //cout << dum; - } - //if (ix==20 && iy==40) - //cout << decoder->getChannelShort(buff,ix,iy)<< " " << val << " " << me << " " << sig << " " << dum << endl; - - if ( dum==0) { - - stat[iy][ix].Calc(decoder->getChannelShort(buff,ix,iy)); - } - if (nfgetChannel(buff,ix,iy)); - - } - } - delete [] buff; - //cout << "="; cout.flush(); - if(nf>nbg) nPhotonsStat.Calc((double)nPhotons); - nf++; - } - //cout << endl; - cout << "processed File " << fname << " done. Avg. Photons/Frame: " << nPhotonsStat.Mean() << " sig: " << nPhotonsStat.StandardDeviation() << " " << runmax-irun << " files need processing" << endl; - if (filebin.is_open()) - filebin.close(); - else - cout << "could not open file " << fname << endl; - } - - delete decoder; - cout << "Read " << nf << " frames" << endl; - - -} - -void *moenchMakeTreeTask(void *p){ - Task *t = (Task *)p; - moenchMakeTree(t->fformat,t->tname,t->runmin,t->runmax,t->sign); - return 0; -} - - -//to compile: g++ -DMYROOT -g `root-config --cflags --glibs` -o moenchMakeTree moenchMakeTree.C -int main(int argc, char **argv){ - if(argc != 6){ cout << "Usage: inFile outdir tname fileNrStart fileNrEnd" << endl; exit(-1); } - - int nThreads = 10; - TThread *threads[nThreads]; - - char *inFile = argv[1]; - char *outDir = argv[2]; - char *tName = argv[3]; - int start = atoi(argv[4]); - int end = atoi(argv[5]); - - TFile *f; - char outfname[1000]; - char threadName[1000]; - - sprintf(outfname,"%s/%s.root",outDir,tName); - f=new TFile(outfname,"RECREATE"); - - cout << "outputfile: " << outfname << endl; - setUpTree(tName); - - for(int i = 0; i < nThreads; i++){ - sprintf(threadName,"t%i",i); - Task *t = (Task *)malloc(sizeof(Task)); - t->fformat = inFile; - t->tname = tName; - t->sign = 1.; - t->runmin = start + (end-start)/(nThreads)*i; - t->runmax = start + (end-start)/(nThreads)*(i+1); - if(i == nThreads - 1) t->runmax = end; - cout << "start thread " << i << " start: " << t->runmin << " end " << t->runmax << endl; - threads[i] = new TThread(threadName, moenchMakeTreeTask, t); - threads[i]->Run(); - //moenchMakeTreeTask(t); - } - - - //TThread::Ps(); - - for(int i = 0; i < nThreads; i++){ - threads[i]->Join(); - } - - - tall->Write(); - tall->Print(); - f->Close(); -} - diff --git a/slsReceiverSoftware/slsDetectorCalibration/moenchReadData.C b/slsReceiverSoftware/slsDetectorCalibration/moenchReadData.C deleted file mode 100644 index bf7173f0b..000000000 --- a/slsReceiverSoftware/slsDetectorCalibration/moenchReadData.C +++ /dev/null @@ -1,236 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -//#include -//#include -//#include -#include -#include "moench02ModuleData.h" -#include "moenchCommonMode.h" -#include "singlePhotonDetector.h" - -//#include "MovingStat.h" - -using namespace std; - -#define NC 160 -#define NR 160 - - -#define MY_DEBUG 1 -#ifdef MY_DEBUG -#include -#endif - -/** - -Loops over data file to find single photons, fills the tree (and writes it to file, althoug the root file should be opened before) and creates 1x1, 2x2, 3x3 cluster histograms with ADCu on the x axis, channel number (160*x+y) on the y axis. - - \param fformat file name format - \param tit title of the tree etc. - \param runmin minimum run number - \param runmax max run number - \param nbins number of bins for spectrum hists - \param hmin histo minimum for spectrum hists - \param hmax histo maximum for spectrum hists - \param sign sign of the spectrum to find hits - \param hc readout correlation coefficient with previous pixel - \param xmin minimum x coordinate - \param xmax maximum x coordinate - \param ymin minimum y coordinate - \param ymax maximum y coordinate - \param cmsub enable commonmode subtraction - \returns pointer to histo stack with cluster spectra -*/ - - -THStack *moenchReadData(char *fformat, char *tit, int runmin, int runmax, int nbins=1500, int hmin=-500, int hmax=1000, int sign=1, double hc=0, int xmin=1, int xmax=NC-1, int ymin=1, int ymax=NR-1, int cmsub=0, int hitfinder=1) { - - moench02ModuleData *decoder=new moench02ModuleData(hc); - moenchCommonMode *cmSub=NULL; - if (cmsub) - cmSub=new moenchCommonMode(); - - int nph=0; - - singlePhotonDetector *filter=new singlePhotonDetector(decoder, 3, 5, sign, cmSub); - - char *buff; - char fname[10000]; - int nf=0; - - eventType thisEvent=PEDESTAL; - - // int iframe; - // double *data, ped, sigma; - - // data=decoder->getCluster(); - - TH2F *h2; - TH2F *h3; - TH2F *hetaX; - TH2F *hetaY; - - THStack *hs=new THStack("hs",fformat); - - - - TH2F *h1=new TH2F("h1",tit,nbins,hmin-0.5,hmax-0.5,NC*NR,-0.5,NC*NR-0.5); - hs->Add(h1); - - if (hitfinder) { - h2=new TH2F("h2",tit,nbins,hmin-0.5,hmax-0.5,NC*NR,-0.5,NC*NR-0.5); - h3=new TH2F("h3",tit,nbins,hmin-0.5,hmax-0.5,NC*NR,-0.5,NC*NR-0.5); - hetaX=new TH2F("hetaX",tit,nbins,-1,2,NC*NR,-0.5,NC*NR-0.5); - hetaY=new TH2F("hetaY",tit,nbins,-1,2,NC*NR,-0.5,NC*NR-0.5); - hs->Add(h2); - hs->Add(h3); - hs->Add(hetaX); - hs->Add(hetaY); - } - - - - ifstream filebin; - - - int ix=20, iy=20, ir, ic; - - - Int_t iFrame; - TTree *tall; - if (hitfinder) - tall=filter->initEventTree(tit, &iFrame); - - - - -#ifdef MY_DEBUG - - TCanvas *myC; - TH2F *he; - TCanvas *cH1; - TCanvas *cH2; - TCanvas *cH3; - - if (hitfinder) { - myC=new TCanvas(); - he=new TH2F("he","Event Mask",xmax-xmin, xmin, xmax, ymax-ymin, ymin, ymax); - he->SetStats(kFALSE); - he->Draw("colz"); - cH1=new TCanvas(); - cH1->SetLogz(); - h1->Draw("colz"); - cH2=new TCanvas(); - cH2->SetLogz(); - h2->Draw("colz"); - cH3=new TCanvas(); - cH3->SetLogz(); - h3->Draw("colz"); - } -#endif - filter->newDataSet(); - - - for (int irun=runmin; irunreadNextFrame(filebin))) { - - - if (hitfinder) { - filter->newFrame(); - - //calculate pedestals and common modes - if (cmsub) { - // cout << "cm" << endl; - for (ix=xmin-1; ixgetEventType(buff, ix, iy,0); - } - } - } - - // cout << "new frame " << endl; - - for (ix=xmin-1; ixgetEventType(buff, ix, iy, cmsub); - -#ifdef MY_DEBUG - if (hitfinder) { - if (iev%1000==0) - he->SetBinContent(ix+1-xmin, iy+1-ymin, (int)thisEvent); - } -#endif - - if (nf>1000) { - h1->Fill(filter->getClusterTotal(1), iy+NR*ix); - if (hitfinder) { - - if (thisEvent==PHOTON_MAX ) { - nph++; - - h2->Fill(filter->getClusterTotal(2), iy+NR*ix); - h3->Fill(filter->getClusterTotal(3), iy+NR*ix); - iFrame=decoder->getFrameNumber(buff); - - tall->Fill(); - - - } - - - } - - - } - } - ////////////////////////////////////////////////////////// - -#ifdef MY_DEBUG - if (iev%1000==0) { - myC->Modified(); - myC->Update(); - cH1->Modified(); - cH1->Update(); - cH2->Modified(); - cH2->Update(); - cH3->Modified(); - cH3->Update(); - } - iev++; -#endif - nf++; - - cout << "=" ; - delete [] buff; - } - cout << nph << endl; - if (filebin.is_open()) - filebin.close(); - else - cout << "could not open file " << fname << endl; - } - if (hitfinder) - tall->Write(tall->GetName(),TObject::kOverwrite); - - - - delete decoder; - cout << "Read " << nf << " frames" << endl; - return hs; -} - diff --git a/slsReceiverSoftware/slsDetectorCalibration/moenchReadDataMT.C b/slsReceiverSoftware/slsDetectorCalibration/moenchReadDataMT.C deleted file mode 100644 index 0720909c4..000000000 --- a/slsReceiverSoftware/slsDetectorCalibration/moenchReadDataMT.C +++ /dev/null @@ -1,52 +0,0 @@ -#include -#include -#include "moenchReadData.C" - -typedef struct task_s{ - char *fformat; - char *tname; - char *tdir; - int runmin; - int runmax; - int treeIndex; -} Task; - -void *moenchMakeTreeTask(void *p){ - TThread::Lock(); - char fname[1000]; - Task *t = (Task *)p; - sprintf(fname,"%s%s_%i.root",t->tdir,t->tname,t->treeIndex); - TFile *f = new TFile(fname,"RECREATE"); - cout << "Call moenchReadData(" << t->fformat << "," << t->tname << "," << t->runmin<< "," << t->runmax <<")" << endl; - TThread::UnLock(); - moenchReadData(t->fformat,t->tname,t->runmin,t->runmax); - f->Close(); - return 0; -} - - -void moenchReadDataMT(char *fformat, char *tit, char *tdir, int runmin, int runoffset, int nThreads, int treeIndexStart=0){ - char threadName[1000]; - TThread *threads[nThreads]; - for(int i = 0; i < nThreads; i++){ - sprintf(threadName,"t%i",i); - Task *t = (Task *)malloc(sizeof(Task)); - t->fformat = fformat; - t->tname = tit; - t->tdir = tdir; - t->runmin = runmin + i*runoffset; - t->runmax = runmin + (i+1)*runoffset - 1; - t->treeIndex = treeIndexStart + i; - cout << "start thread " << i << " start: " << t->runmin << " end " << t->runmax << endl; - threads[i] = new TThread(threadName, moenchMakeTreeTask, t); - threads[i]->Run(); - } - - for(int i = 0; i < nThreads; i++){ - threads[i]->Join(); - } - -} - - - diff --git a/slsReceiverSoftware/slsDetectorCalibration/pedestalSubtraction.h b/slsReceiverSoftware/slsDetectorCalibration/pedestalSubtraction.h deleted file mode 100644 index ee3aff8aa..000000000 --- a/slsReceiverSoftware/slsDetectorCalibration/pedestalSubtraction.h +++ /dev/null @@ -1,48 +0,0 @@ -#ifndef PEDESTALSUBTRACTION_H -#define PEDESTALSUBTRACTION_H - -#include "MovingStat.h" - -class pedestalSubtraction { - /** @short class defining the pedestal subtraction based on an approximated moving average */ - public: - /** constructor - \param nn number of samples to calculate the moving average (defaults to 1000) - */ - pedestalSubtraction (int nn=1000) : stat(nn) {}; - - /** virtual destructorr - */ - virtual ~pedestalSubtraction() {}; - - /** clears the moving average */ - virtual void Clear() {stat.Clear();} - - /** adds the element to the moving average - \param val value to be added - */ - virtual void addToPedestal(double val){stat.Calc(val);}; - - /** returns the average value of the pedestal - \returns mean of the moving average - */ - virtual double getPedestal(){return stat.Mean();}; - - /** returns the standard deviation of the moving average - \returns standard deviation of the moving average - */ - virtual double getPedestalRMS(){return stat.StandardDeviation();}; - - /**sets/gets the number of samples for the moving average - \param i number of elements for the moving average. If -1 (default) or negative, gets. - \returns actual number of samples for the moving average - */ - virtual int SetNPedestals(int i=-1) {if (i>0) stat.SetN(i); return stat.GetN();}; - - - - private: - MovingStat stat; /**< approximated moving average struct */ - -}; -#endif diff --git a/slsReceiverSoftware/slsDetectorCalibration/raedNoiseData.C b/slsReceiverSoftware/slsDetectorCalibration/raedNoiseData.C deleted file mode 100644 index b2021b29f..000000000 --- a/slsReceiverSoftware/slsDetectorCalibration/raedNoiseData.C +++ /dev/null @@ -1,136 +0,0 @@ -#include "moenchReadData.C" - - - -void raedNoiseData(char *tit, int sign=1){ - - - - - - char fname[1000]; - char f[1000]; - TFile *fout; - THStack *hs2N; - - sprintf(fname,"/data/moench_xbox_20140113/MoTarget_45kV_0_8mA_120V_%s_0.root",tit); - fout=new TFile(fname,"RECREATE"); - - sprintf(fname,"/data/moench_xbox_20140113/MoTarget_45kV_0_8mA_120V_%s_f00000%%04d000_0.raw",tit); - - hs2N=moenchReadData(fname,0,3000,1500,-500,2500,1,0.,1,159,1,159, 0,1); - hs2N->SetName(tit); - hs2N->SetTitle(tit); - (TH2F*)(hs2N->GetHists()->At(0))->Write(); - - (TH2F*)(hs2N->GetHists()->At(1))->Write(); - (TH2F*)(hs2N->GetHists()->At(2))->Write(); - (TH2F*)(hs2N->GetHists()->At(3))->Write(); - (TH2F*)(hs2N->GetHists()->At(4))->Write(); - - - fout->Close(); - - - -} - - - -void raedNoiseDataN(char *tit, int sign=1){ - - - - char fname[1000]; - char f[1000]; - TFile *fout; - THStack *hs2N; - - sprintf(fname,"/data/moench_xbox_20140116/noise_%s.root",tit); - fout=new TFile(fname,"RECREATE"); - - sprintf(fname,"/data/moench_xbox_20140116/noise_%s_f00000%%04d000_0.raw",tit); - - hs2N=moenchReadData(fname,tit,0,3000,1500,-500,2500,sign,0.,1,159,1,159, 0,0); - hs2N->SetName(tit); - hs2N->SetTitle(tit); - (TH2F*)(hs2N->GetHists()->At(0))->Write(); - - // (TH2F*)(hs2N->GetHists()->At(1))->Write(); - // (TH2F*)(hs2N->GetHists()->At(2))->Write(); - // (TH2F*)(hs2N->GetHists()->At(3))->Write(); - // (TH2F*)(hs2N->GetHists()->At(4))->Write(); - - - fout->Close(); - - - -} - - - -void g4() { - - raedNoiseData("cds_g4_low_gain"); - raedNoiseData("cds_g4_sto1_only"); - raedNoiseData("cds_g4_no sto"); - - - -} - -void no_cds() { - - raedNoiseData("cds_disable_low_gain",-1); - raedNoiseData("cds_disable_sto1_only",-1); - raedNoiseData("cds_disable_no sto",-1); - - - -} - -void all_gains() { - - raedNoiseData("cds_g2"); - raedNoiseData("cds_g2HC"); - raedNoiseData("cds_g1_2"); - raedNoiseData("cds_g2_3"); - - - -} - -void all_low_gains() { - - raedNoiseData("cds_g2_low_gain"); - raedNoiseData("cds_g2HC_low_gain"); - raedNoiseData("cds_g1_2_low_gain"); - raedNoiseData("cds_g2_3_low_gain"); -} - -/* -clkdivider data -/data/moench_xbox_20140114/MoTarget_45kV_0_8mA_12us_120V_cds_g1_clkdiv17_f000000010000_0.raw --rw-rw-r-- 1 l_msdetect l_msdetect 51440000 Jan 14 12:40 /data/moench_xbox_20140114/MoTarget_45kV_0_8mA_12us_120V_cds_g1_clkdiv25_f000000010000_0.raw --rw-rw-r-- 1 l_msdetect l_msdetect 51440000 Jan 14 13:26 /data/moench_xbox_20140114/MoTarget_45kV_0_8mA_12us_120V_cds_g1_clkdiv35_f000000010000_0.raw --rw-rw-r-- 1 l_msdetect l_msdetect 51440000 Jan 14 14:09 /data/moench_xbox_20140114/MoTarget_45kV_0_8mA_12us_120V_cds_g1_clkdiv50_f000000010000_0.raw --rw-rw-r-- 1 l_msdetect l_msdetect 51440000 Jan 14 14:54 /data/moench_xbox_20140114/MoTarget_45kV_0_8mA_12us_120V_cds_g1_clkdiv70_f000000010000_0.raw --rw-rw-r-- 1 l_msdetect l_msdetect 51440000 Jan 14 16:42 /data/moench_xbox_20140114/MoTarget_45kV_0_8mA_12us_120V_cds_g1_clkdiv110_f000000010000_0.raw --rw-rw-r-- 1 l_msdetect l_msdetect 51440000 Jan 14 17:27 /data/moench_xbox_20140114/MoTarget_45kV_0_8mA_12us_120V_cds_g1_clkdiv170_f000000010000_0.raw -*/ - - -/* oversampled data --rw-rw-r-- 1 l_msdetect l_msdetect 51440000 Jan 14 18:12 /data/moench_xbox_20140114/MoTarget_45kV_0_8mA_12us_120V_os10_16rows_f000000010000_0.raw --rw-rw-r-- 1 l_msdetect l_msdetect 51440000 Jan 14 18:47 /data/moench_xbox_20140114/MoTarget_45kV_0_8mA_12us_120V_os10_16rows_f000000010000_1.raw --rw-rw-r-- 1 l_msdetect l_msdetect 51440000 Jan 14 19:22 /data/moench_xbox_20140114/MoTarget_45kV_0_8mA_12us_120V_os10_16rows_f000000010000_2.raw --rw-rw-r-- 1 l_msdetect l_msdetect 51440000 Jan 14 20:02 /data/moench_xbox_20140114/MoTarget_45kV_0_8mA_12us_120V_os10_16rows_f000000010000_3.raw --rw-rw-r-- 1 l_msdetect l_msdetect 51440000 Jan 14 20:41 /data/moench_xbox_20140114/MoTarget_45kV_0_8mA_12us_120V_os10_16rows_f000000010000_4.raw --rw-rw-r-- 1 l_msdetect l_msdetect 51440000 Jan 14 21:16 /data/moench_xbox_20140114/MoTarget_45kV_0_8mA_12us_120V_os10_16rows_f000000010000_5.raw --rw-rw-r-- 1 l_msdetect l_msdetect 51440000 Jan 14 21:56 /data/moench_xbox_20140114/MoTarget_45kV_0_8mA_12us_120V_os10_16rows_f000000010000_6.raw --rw-rw-r-- 1 l_msdetect l_msdetect 51440000 Jan 14 22:35 /data/moench_xbox_20140114/MoTarget_45kV_0_8mA_12us_120V_os10_16rows_f000000010000_7.raw --rw-rw-r-- 1 l_msdetect l_msdetect 51440000 Jan 14 23:11 /data/moench_xbox_20140114/MoTarget_45kV_0_8mA_12us_120V_os10_16rows_f000000010000_8.raw --rw-rw-r-- 1 l_msdetect l_msdetect 51440000 Jan 14 23:50 /data/moench_xbox_20140114/MoTarget_45kV_0_8mA_12us_120V_os10_16rows_f000000010000_9.raw -*/ - diff --git a/slsReceiverSoftware/slsDetectorCalibration/readJungfrauData.C b/slsReceiverSoftware/slsDetectorCalibration/readJungfrauData.C deleted file mode 100644 index 504a15258..000000000 --- a/slsReceiverSoftware/slsDetectorCalibration/readJungfrauData.C +++ /dev/null @@ -1,31 +0,0 @@ -{ // script to run Jungfrau data analysis - - gROOT->ProcessLine(".L jungfrauReadData.C++");//"); - - TFile *fout; // output file - THStack *hs2N; // collection of objects - - //fout=new TFile("/mnt/slitnas/datadir_jungfrau02/analysis_tests/tests_random.root","RECREATE"); // - fout=new TFile("/mnt/slitnas/datadir_jungfrau02/20140404_lowEXrays/test.root","RECREATE"); - - hs2N=jungfrauReadData("/mnt/slitnas/datadir_jungfrau02/20140404_lowEXrays/Ti_1000clk_13kV40mA_%d.bin","tit",0,86,3000,-499.5,2500.5,1,0,1,47,1,47,1,1); //1,1); - - //hs2N=jungfrauReadData("/mnt/slitnas/datadir_jungfrau02/20140228_GainBits/GSdata_laser_%d.bin","tit",0,5,1500,-500,2500,1,0.,1,47,1,47,0,1);//,"/mnt/slitnas/datadir_jungfrau02/analysis_tests/CalibrationParametersTest_fake.txt"); //1,1); // data set test GB -> set (3,0,0) in junfrauReadData.C - - //hs2N=jungfrauReadData("/mnt/slitnas/datadir_jungfrau02/digital_bit_adc_test/vb_1825_%d.bin","tit",0,7,1500,-500,2500,1,0.,1,47,1,47,0,1);//,"/mnt/slitnas/datadir_jungfrau02/analysis_tests/CalibrationParametersTest_fake.txt"); //1,1); // data set test GB -> set (3,0,0) in junfrauReadData.C - - //hs2N->SetName("cds_g4"); - //hs2N->SetTitle("cds_g4"); - - (TH2F*)(hs2N->GetHists()->At(0))->Write(); // write hists - (TH2F*)(hs2N->GetHists()->At(1))->Write(); - (TH2F*)(hs2N->GetHists()->At(2))->Write(); - (TH2F*)(hs2N->GetHists()->At(3))->Write(); - (TH2F*)(hs2N->GetHists()->At(4))->Write(); - //(TH2F*)(hs2N->GetHists()->At(5))->Write(); - //(TH2F*)(hs2N->GetHists()->At(6))->Write(); - - fout->Close(); // uncomment - -} - diff --git a/slsReceiverSoftware/slsDetectorCalibration/singlePhotonDetector.h b/slsReceiverSoftware/slsDetectorCalibration/singlePhotonDetector.h deleted file mode 100644 index f090730a1..000000000 --- a/slsReceiverSoftware/slsDetectorCalibration/singlePhotonDetector.h +++ /dev/null @@ -1,387 +0,0 @@ -#ifndef SINGLEPHOTONDETECTOR_H -#define SINGLEPHOTONDETECTOR_H - - -#include "slsDetectorData.h" - -#include "single_photon_hit.h" -#include "pedestalSubtraction.h" -#include "commonModeSubtraction.h" - - -//#define MYROOT1 - -#ifdef MYROOT1 -#include - -#endif - - -#include - -using namespace std; - - - enum eventType { - PEDESTAL=0, - NEIGHBOUR=1, - PHOTON=2, - PHOTON_MAX=3, - NEGATIVE_PEDESTAL=4, - UNDEFINED_EVENT=-1 - }; - - enum quadrant { - TOP_LEFT=0, - TOP_RIGHT=1, - BOTTOM_LEFT=2, - BOTTOM_RIGHT=3, - UNDEFINED_QUADRANT=-1 - }; - - - -template -class singlePhotonDetector { - - /** @short class to perform pedestal subtraction etc. and find single photon clusters for an analog detector */ - - public: - - - /** - - Constructor (no error checking if datasize and offsets are compatible!) - \param d detector data structure to be used - \param csize cluster size (should be an odd number). Defaults to 3 - \param nsigma number of rms to discriminate from the noise. Defaults to 5 - \param sign 1 if photons are positive, -1 if negative - \param cm common mode subtraction algorithm, if any. Defaults to NULL i.e. none - \param nped number of samples for pedestal averaging - \param nd number of dark frames to average as pedestals without photon discrimination at the beginning of the measurement - - - */ - - - singlePhotonDetector(slsDetectorData *d, - int csize=3, - double nsigma=5, - int sign=1, - commonModeSubtraction *cm=NULL, - int nped=1000, - int nd=100) : det(d), nx(0), ny(0), stat(NULL), cmSub(cm), nDark(nd), eventMask(NULL),nSigma (nsigma), clusterSize(csize), clusterSizeY(csize), cluster(NULL), iframe(-1), dataSign(sign), quad(UNDEFINED_QUADRANT), tot(0), quadTot(0) { - - - det->getDetectorSize(nx,ny); - - - - stat=new pedestalSubtraction*[ny]; - eventMask=new eventType*[ny]; - for (int i=0; iSetNPedestals(nped); - eventMask[i]=new eventType[nx]; - } - - if (ny==1) - clusterSizeY=1; - - cluster=new single_photon_hit(clusterSize,clusterSizeY); - setClusterSize(csize); - - }; - /** - destructor. Deletes the cluster structure and the pdestalSubtraction array - */ - virtual ~singlePhotonDetector() {delete cluster; for (int i=0; iClear(); }; - - /** resets the eventMask to undefined and the commonModeSubtraction */ - void newFrame(){iframe++; for (int iy=0; iynewFrame();}; - - - /** sets the commonModeSubtraction algorithm to be used - \param cm commonModeSubtraction algorithm to be used (NULL unsets) - \returns pointer to the actual common mode subtraction algorithm - */ - commonModeSubtraction setCommonModeSubtraction(commonModeSubtraction *cm) {cmSub=cm; return cmSub;}; - - - /** - sets the sign of the data - \param sign 1 means positive values for photons, -1 negative, 0 gets - \returns current sign for the data - */ - int setDataSign(int sign=0) {if (sign==1 || sign==-1) dataSign=sign; return dataSign;}; - - - /** - adds value to pedestal (and common mode) for the given pixel - \param val value to be added - \param ix pixel x coordinate - \param iy pixel y coordinate - */ - virtual void addToPedestal(double val, int ix, int iy){ - // cout << "*"<< ix << " " << iy << " " << val << endl; - if (ix>=0 && ix=0 && iyisGood(ix, iy) ) - cmSub->addToCommonMode(val, ix, iy); - }; - }; - - /** - gets pedestal (and common mode) - \param ix pixel x coordinate - \param iy pixel y coordinate - \param cm 0 (default) without common mode subtraction, 1 with common mode subtraction (if defined) - */ - virtual double getPedestal(int ix, int iy, int cm=0){if (ix>=0 && ix=0 && iy0) return stat[iy][ix].getPedestal()-cmSub->getCommonMode(); else return stat[iy][ix].getPedestal(); else return -1;}; - - /** - gets pedestal rms (i.e. noise) - \param ix pixel x coordinate - \param iy pixel y coordinate - */ - double getPedestalRMS(int ix, int iy){if (ix>=0 && ix=0 && iy0) nSigma=n; return nSigma;} - - /** sets/gets cluster size - \param n cluster size to be set, (0 or negative gets). If even is incremented by 1. - \returns actual cluster size - */ - int setClusterSize(int n=-1){ - if (n>0 && n!=clusterSize) { - if (n%2==0) - n+=1; - clusterSize=n; - if (cluster) - delete cluster; - if (ny>1) - clusterSizeY=clusterSize; - cluster=new single_photon_hit(clusterSize,clusterSizeY); - } - return clusterSize; - } - - - - - /** finds event type for pixel and fills cluster structure. The algorithm loops only if the evenMask for this pixel is still undefined. - if pixel or cluster around it are above threshold (nsigma*pedestalRMS) cluster is filled and pixel mask is PHOTON_MAX (if maximum in cluster) or NEIGHBOUR; If PHOTON_MAX, the elements of the cluster are also set as NEIGHBOURs in order to speed up the looping - if below threshold the pixel is either marked as PEDESTAL (and added to the pedestal calculator) or NEGATIVE_PEDESTAL is case it's lower than -threshold, otherwise the pedestal average would drift to negative values while it should be 0. - - /param data pointer to the data - /param ix pixel x coordinate - /param iy pixel y coordinate - /param cm enable(1)/disable(0) common mode subtraction (if defined). - /returns event type for the given pixel - */ - eventType getEventType(char *data, int ix, int iy, int cm=0) { - - // eventType ret=PEDESTAL; - double max=0, tl=0, tr=0, bl=0,br=0, v; - // cout << iframe << endl; - - tot=0; - quadTot=0; - quad=UNDEFINED_QUADRANT; - - - if (iframex=ix; - cluster->y=iy; - cluster->rms=getPedestalRMS(ix,iy); - cluster->ped=getPedestal(ix,iy, cm); - - - for (int ir=-(clusterSizeY/2); ir<(clusterSizeY/2)+1; ir++) { - for (int ic=-(clusterSize/2); ic<(clusterSize/2)+1; ic++) { - if ((iy+ir)>=0 && (iy+ir)=0 && (ix+ic)set_data(dataSign*(det->getValue(data, ix+ic, iy+ir)-getPedestal(ix+ic,iy+ir,cm)), ic, ir ); - v=cluster->get_data(ic,ir); - tot+=v; - if (ir<=0 && ic<=0) - bl+=v; - if (ir<=0 && ic>=0) - br+=v; - if (ir>=0 && ic<=0) - tl+=v; - if (ir>=0 && ic>=0) - tr+=v; - - if (cluster->get_data(ic,ir)>max) { - max=v; - } - if (ir==0 && ic==0) { - if (v>nSigma*cluster->rms) { - eventMask[iy][ix]=PHOTON; - } else if (cluster->get_data(ic,ir)<-nSigma*cluster->rms) - eventMask[iy][ix]=NEGATIVE_PEDESTAL; - } - } - } - } - - if (eventMask[iy][ix]!=PHOTON && tot>sqrt(clusterSizeY*clusterSize)*nSigma*cluster->rms) { - eventMask[iy][ix]=NEIGHBOUR; - } else if (eventMask[iy][ix]==PHOTON) { - if (cluster->get_data(0,0)>=max) { - eventMask[iy][ix]=PHOTON_MAX; - } - } else if (eventMask[iy][ix]==PEDESTAL) { - if (cm==0) - addToPedestal(det->getValue(data, ix, iy),ix,iy); - } - - - if (bl>=br && bl>=tl && bl>=tr) { - quad=BOTTOM_LEFT; - quadTot=bl; - } else if (br>=bl && br>=tl && br>=tr) { - quad=BOTTOM_RIGHT; - quadTot=br; - } else if (tl>=br && tl>=bl && tl>=tr) { - quad=TOP_LEFT; - quadTot=tl; - } else if (tr>=bl && tr>=tl && tr>=br) { - quad=TOP_RIGHT; - quadTot=tr; - } - - - return eventMask[iy][ix]; - - }; - - /**< - retrurns the total signal in a cluster - \param size cluser size should be 1,2 or 3 - \returns cluster center if size=1, sum of the maximum quadrant if size=2, total of the cluster if size=3 or anything else - */ - - double getClusterTotal(int size) { - switch (size) { - case 1: - return getClusterElement(0,0); - case 2: - return quadTot; - default: - return tot; - }; - }; - - /**< - retrurns the quadrant with maximum signal - \returns quadrant where the cluster is located */ - - quadrant getQuadrant() {return quad;}; - - /** sets/gets number of samples for moving average pedestal calculation - \param i number of samples to be set (0 or negative gets) - \returns actual number of samples - */ - int SetNPedestals(int i=-1) {int ix=0, iy=0; if (i>0) for (ix=0; ixget_data(ic,ir);}; - - /** returns event mask for the given pixel - \param ic x coordinate (center is (0,0)) - \param ir y coordinate (center is (0,0)) - \returns event mask enum for the given pixel - */ - eventType getEventMask(int ic, int ir=0){return eventMask[ir][ic];}; - - -#ifdef MYROOT1 - /** generates a tree and maps the branches - \param tname name for the tree - \param iFrame pointer to the frame number - \returns returns pointer to the TTree - */ - TTree *initEventTree(char *tname, int *iFrame=NULL) { - TTree* tall=new TTree(tname,tname); - - if (iFrame) - tall->Branch("iFrame",iFrame,"iframe/I"); - else - tall->Branch("iFrame",&(cluster->iframe),"iframe/I"); - - tall->Branch("x",&(cluster->x),"x/I"); - tall->Branch("y",&(cluster->y),"y/I"); - char tit[100]; - sprintf(tit,"data[%d]/D",clusterSize*clusterSizeY); - tall->Branch("data",cluster->data,tit); - tall->Branch("pedestal",&(cluster->ped),"pedestal/D"); - tall->Branch("rms",&(cluster->rms),"rms/D"); - return tall; - }; -#else - /** write cluster to filer*/ - void writeCluster(FILE* myFile){cluster->write(myFile);}; - -#endif - - - private: - - slsDetectorData *det; /**< slsDetectorData to be used */ - int nx; /**< Size of the detector in x direction */ - int ny; /**< Size of the detector in y direction */ - - - pedestalSubtraction **stat; /**< pedestalSubtraction class */ - commonModeSubtraction *cmSub;/**< commonModeSubtraction class */ - int nDark; /**< number of frames to be used at the beginning of the dataset to calculate pedestal without applying photon discrimination */ - eventType **eventMask; /**< matrix of event type or each pixel */ - double nSigma; /**< number of sigma parameter for photon discrimination */ - int clusterSize; /**< cluster size in the x direction */ - int clusterSizeY; /**< cluster size in the y direction i.e. 1 for strips, clusterSize for pixels */ - single_photon_hit *cluster; /**< single photon hit data structure */ - int iframe; /**< frame number (not from file but incremented within the dataset every time newFrame is called */ - int dataSign; /**< sign of the data i.e. 1 if photon is positive, -1 if negative */ - quadrant quad; /**< quadrant where the photon is located */ - double tot; /**< sum of the 3x3 cluster */ - double quadTot; /**< sum of the maximum 2x2cluster */ - - -}; - - - - - -#endif diff --git a/slsReceiverSoftware/slsDetectorCalibration/single_photon_hit.h b/slsReceiverSoftware/slsDetectorCalibration/single_photon_hit.h deleted file mode 100644 index dda4d7571..000000000 --- a/slsReceiverSoftware/slsDetectorCalibration/single_photon_hit.h +++ /dev/null @@ -1,62 +0,0 @@ -#ifndef SINGLE_PHOTON_HIT_H -#define SINGLE_PHOTON_HIT_h - -typedef double double32_t; -typedef float float32_t; -typedef int int32_t; - - -class single_photon_hit { - - /** @short Structure for a single photon hit */ - - public: - /** constructor, instantiates the data array -- all class elements are public! - \param nx cluster size in x direction - \param ny cluster size in y direction (defaults to 1 for 1D detectors) - */ - single_photon_hit(int nx, int ny=1): dx(nx), dy(ny) {data=new double[dx*dy];}; - - ~single_photon_hit(){delete [] data;}; /**< destructor, deletes the data array */ - - /** binary write to file of all elements of the structure, except size of the cluster - \param myFile file descriptor - */ - void write(FILE *myFile) {fwrite((void*)this, 1, 3*sizeof(int)+2*sizeof(double), myFile); fwrite((void*)data, 1, dx*dy*sizeof(double), myFile);}; - - /** - binary read from file of all elements of the structure, except size of the cluster. The structure is then filled with those args - \param myFile file descriptor - */ - void read(FILE *myFile) {fread((void*)this, 1, 3*sizeof(int)+2*sizeof(double), myFile); fread((void*)data, 1, dx*dy*sizeof(double), myFile);}; - - /** - assign the value to the element of the cluster matrix, with relative coordinates where the center of the cluster is (0,0) - \param v value to be set - \param ix coordinate x within the cluster (center is (0,0)) - \param iy coordinate y within the cluster (center is (0,0)) - */ - void set_data(double v, int ix, int iy=0){data[(iy+dy/2)*dx+ix+dx/2]=v;}; - - - /** - gets the value to the element of the cluster matrix, with relative coordinates where the center of the cluster is (0,0) - \param ix coordinate x within the cluster (center is (0,0)) - \param iy coordinate y within the cluster (center is (0,0)) - \returns value of the cluster element - */ - double get_data(int ix, int iy=0){return data[(iy+dy/2)*dx+ix+dx/2];}; - - int x; /**< x-coordinate of the center of hit */ - int y; /**< x-coordinate of the center of hit */ - double rms; /**< noise of central pixel l -- at some point it can be removed*/ - double ped; /**< pedestal of the central pixel -- at some point it can be removed*/ - int iframe; /**< frame number */ - double *data; /**< pointer to data */ - const int dx; /**< size of data cluster in x */ - const int dy; /**< size of data cluster in y */ -}; - - - -#endif diff --git a/slsReceiverSoftware/slsDetectorCalibration/slsDetectorData.h b/slsReceiverSoftware/slsDetectorCalibration/slsDetectorData.h deleted file mode 100644 index 294f7c871..000000000 --- a/slsReceiverSoftware/slsDetectorCalibration/slsDetectorData.h +++ /dev/null @@ -1,251 +0,0 @@ -#ifndef SLSDETECTORDATA_H -#define SLSDETECTORDATA_H - -#include -#include -#include - -using namespace std; - - -template -class slsDetectorData { - - - public: - - /** - - - General slsDetectors data structure. Works for data acquired using the slsDetectorReceiver. Can be generalized to other detectors (many virtual funcs). - - Constructor (no error checking if datasize and offsets are compatible!) - \param npx number of pixels in the x direction - \param npy number of pixels in the y direction (1 for strips) - \param dsize size of the data - \param dMap array of size nx*ny storing the pointers to the data in the dataset (as offset) - \param dMask Array of size nx*ny storing the polarity of the data in the dataset (should be 0 if no inversion is required, 0xffffffff is inversion is required) - \param dROI Array of size nx*ny. The elements are 1s if the channel is good or in the ROI, 0 is bad or out of the ROI. NULL (default) means all 1s. - - */ - slsDetectorData(int npx, int npy, int dsize, int **dMap=NULL, dataType **dMask=NULL, int **dROI=NULL): nx(npx), ny(npy), dataSize(dsize) { - - - - dataMask=new dataType*[ny]; - for(int i = 0; i < ny; i++) { - dataMask[i] = new dataType[nx]; - } - dataMap=new int*[ny]; - for(int i = 0; i < ny; i++) { - dataMap[i] = new int[nx]; - } - - dataROIMask=new int*[ny]; - for(int i = 0; i < ny; i++) { - dataROIMask[i] = new int[nx]; - for (int j=0; j=0 && ix=0 && iy=0 && ix=0 && iy=0 && ix=0 && iy=0 && dataMap[iy][ix] -class slsReceiverData : public slsDetectorData { - - -public: - - /** - slsReceiver data structure. Works for data acquired using the slsDetectorReceiver subdivided in different packets with headers and footers. - Inherits and implements slsDetectorData. - - Constructor (no error checking if datasize and offsets are compatible!) - \param npx number of pixels in the x direction - \param npy number of pixels in the y direction (1 for strips) - \param np number of packets - \param psize packets size - \param dMap array of size nx*ny storing the pointers to the data in the dataset (as offset) - \param dMask Array of size nx*ny storing the polarity of the data in the dataset (should be 0 if no inversion is required, 0xffffffff is inversion is required) - \param dROI Array of size nx*ny. The elements are 1s if the channel is good or in the ROI, 0 is bad or out of the ROI. NULL (default) means all 1s. - - */ - slsReceiverData(int npx, int npy, int np, int psize, int **dMap=NULL, dataType **dMask=NULL, int **dROI=NULL): slsDetectorData(npx, npy, np*psize, dMap, dMask, dROI), nPackets(np), packetSize(psize) {}; - - - /** - - Returns the frame number for the given dataset. Virtual func: works for slsDetectorReceiver data (also for each packet), but can be overloaded. - \param buff pointer to the dataset - \returns frame number - - */ - - virtual int getFrameNumber(char *buff){return ((*(int*)buff)&(0xffffff00))>>8;}; - - /** - - Returns the packet number for the given dataset. Virtual func: works for slsDetectorReceiver packets, but can be overloaded. - \param buff pointer to the dataset - \returns packet number number - - */ - - virtual int getPacketNumber(char *buff){return (*(int*)buff)&0xff;}; - - - - - /** - - Loops over a memory slot until a complete frame is found (i.e. all packets 0 to nPackets, same frame number). Can be overloaded for different kind of detectors! - \param data pointer to the memory to be analyzed - \param ndata size of frame returned - \param dsize size of the memory slot to be analyzed - \returns pointer to the first packet of the last good frame (might be incomplete if npackets lower than the number of packets), or NULL if no frame is found - - */ - - virtual char *findNextFrame(char *data, int &ndata, int dsize) { - char *retval=NULL, *p=data; - int dd=0; - int fn, fnum=-1, np=0, pnum=-1; - while (dd<=(dsize-packetSize)) { - pnum=getPacketNumber(p); - fn=getFrameNumber(p); - - - if (pnum<1 || pnum>nPackets) { - cout << "Bad packet number " << pnum << " frame "<< fn << endl; - retval=NULL; - np=0; - } else if (pnum==1) { - retval=p; - if (np>0) - /*cout << "*Incomplete frame number " << fnum << endl;*/ - np=0; - fnum=fn; - } else if (fn!=fnum) { - if (fnum!=-1) { - /* cout << " **Incomplete frame number " << fnum << " pnum " << pnum << " " << getFrameNumber(p) << endl;*/ - retval=NULL; - } - np=0; - } - p+=packetSize; - dd+=packetSize; - np++; - // cout << pnum << " " << fn << " " << np << " " << dd << " " << dsize << endl; - if (np==nPackets) - if (pnum==nPackets) { - // cout << "Frame found!" << endl; - break; - } else { - cout << "Too many packets for this frame! "<< fnum << " " << pnum << endl; - retval=NULL; - } - } - if (np0) - cout << "Too few packets for this frame! "<< fnum << " " << pnum << endl; - } - - ndata=np*packetSize; - // cout << "return " << ndata << endl; - return retval; - }; - - /** - - Loops over a file stream until a complete frame is found (i.e. all packets 0 to nPackets, same frame number). Can be overloaded for different kind of detectors! - \param filebin input file stream (binary) - \returns pointer to the first packet of the last good frame, NULL if no frame is found or last frame is incomplete - - */ - - virtual char *readNextFrame(ifstream &filebin) { - char *data=new char[packetSize*nPackets]; - char *retval=0; - int np=0, nd; - - if (filebin.is_open()) { - while (filebin.read(data+np*packetSize,packetSize)) { - - if (np==(nPackets-1)) { - - retval=findNextFrame(data,nd,packetSize*nPackets); - np=nd/packetSize; - // cout << np << endl; - - - if (retval==data && np==nPackets) { - // cout << "-" << endl; - return data; - - } else if (np>nPackets) { - cout << "too many packets!!!!!!!!!!" << endl; - delete [] data; - return NULL; - } else if (retval!=NULL) { - // cout << "+" << endl;; - for (int ip=0; ipnPackets) { - cout << "*******too many packets!!!!!!!!!!" << endl; - delete [] data; - return NULL; - } else { - // cout << "." << endl;; - np++; - } - } - } - delete [] data; - return NULL; - }; - - - -private: - const int nPackets; /** Date: Fri, 18 Jul 2014 12:27:32 +0200 Subject: [PATCH 013/474] added receiver interface, have not separated from eigerDummyReceiver yet --- slsReceiverSoftware/.gitignore | 1 + slsReceiverSoftware/Makefile | 3 +- slsReceiverSoftware/slsReceiver/Makefile | 2 +- slsReceiverSoftware/slsReceiver/main.cpp | 90 +++++ .../slsReceiver/slsReceiver.cpp | 138 +++---- slsReceiverSoftware/slsReceiver/slsReceiver.h | 89 +++++ .../slsReceiver/slsReceiverBase.h | 335 ++++++++++++++++ .../slsReceiver/slsReceiverTCPIPInterface.cpp | 127 +++--- .../slsReceiver/slsReceiverTCPIPInterface.h | 17 +- .../slsReceiver/slsReceiverUDPFunctions.cpp | 377 +++++++----------- .../slsReceiver/slsReceiverUDPFunctions.h | 63 ++- .../slsReceiver/slsReceiverUsers.cpp | 8 +- .../slsReceiver/slsReceiverUsers.h | 5 +- slsReceiverSoftware/slsReceiverUsers.doxy | 86 ++++ 14 files changed, 944 insertions(+), 397 deletions(-) create mode 100644 slsReceiverSoftware/slsReceiver/main.cpp create mode 100644 slsReceiverSoftware/slsReceiver/slsReceiver.h create mode 100644 slsReceiverSoftware/slsReceiver/slsReceiverBase.h create mode 100644 slsReceiverSoftware/slsReceiverUsers.doxy diff --git a/slsReceiverSoftware/.gitignore b/slsReceiverSoftware/.gitignore index 5761abcfd..ccb33f18f 100644 --- a/slsReceiverSoftware/.gitignore +++ b/slsReceiverSoftware/.gitignore @@ -1 +1,2 @@ *.o +slsDetectorCalibration diff --git a/slsReceiverSoftware/Makefile b/slsReceiverSoftware/Makefile index f8df05639..4aa0c3fde 100644 --- a/slsReceiverSoftware/Makefile +++ b/slsReceiverSoftware/Makefile @@ -14,7 +14,7 @@ DFLAGS= -g -DDACS_INT -DSLS_RECEIVER_UDP_FUNCTIONS INCLUDES?= -I. -Iincludes -IMySocketTCP -IslsReceiver -IslsDetectorCalibration -IslsReceiver/eigerReceiver -I$(ASM) #-IslsReceiverInterface -SRC_CLNT= MySocketTCP/MySocketTCP.cpp slsReceiver/slsReceiverUDPFunctions.cpp slsReceiver/slsReceiverTCPIPInterface.cpp slsReceiver/slsReceiverUsers.cpp +SRC_CLNT= MySocketTCP/MySocketTCP.cpp slsReceiver/slsReceiver.cpp slsReceiver/slsReceiverUDPFunctions.cpp slsReceiver/slsReceiverTCPIPInterface.cpp slsReceiver/slsReceiverUsers.cpp #slsReceiverInterface/receiverInterface.cpp OBJS = $(SRC_CLNT:.cpp=.o) @@ -44,6 +44,7 @@ endif package: eigerReceiver $(OBJS) $(DESTDIR)/libSlsReceiver.so $(DESTDIR)/libSlsReceiver.a eigerReceiver: + echo "src client:" $(SRC_CLNT) cd slsReceiver && make eigerReceiver $(DESTDIR)/libSlsReceiver.so: $(OBJS) diff --git a/slsReceiverSoftware/slsReceiver/Makefile b/slsReceiverSoftware/slsReceiver/Makefile index 92428c957..d5f02c2ea 100644 --- a/slsReceiverSoftware/slsReceiver/Makefile +++ b/slsReceiverSoftware/slsReceiver/Makefile @@ -14,7 +14,7 @@ LDFLAGRXR += -lm -lstdc++ INCLUDES ?= -I ../MySocketTCP -I ../slsDetectorCalibration -I ../includes -I eigerReceiver -I . -SRC_CLNT = slsReceiver.cpp +SRC_CLNT = main.cpp INSTMODE = 0777 diff --git a/slsReceiverSoftware/slsReceiver/main.cpp b/slsReceiverSoftware/slsReceiver/main.cpp new file mode 100644 index 000000000..3513a26c7 --- /dev/null +++ b/slsReceiverSoftware/slsReceiver/main.cpp @@ -0,0 +1,90 @@ +/* A simple server in the internet domain using TCP + The port number is passed as an argument */ + +#include "sls_receiver_defs.h" +#include "slsReceiverUsers.h" + +#include +#include +using namespace std; + + + + + + +int main(int argc, char *argv[]) { + int ret = slsReceiverDefs::OK; + + slsReceiverUsers *user = new slsReceiverUsers(argc, argv, ret); + + if(ret==slsReceiverDefs::FAIL) + return -1; + + + //register callbacks + + + /** + callback arguments are + filepath + filename + fileindex + datasize + + return value is + 0 raw data ready callback takes care of open,close,write file + 1 callback writes file, we have to open, close it + 2 we open, close, write file, callback does not do anything + + + registerCallBackStartAcquisition(int (*func)(char*, char*,int, int, void*),void *arg); + */ + + //receiver->registerCallBackStartAcquisition(func,arg); + + + /** + callback argument is + total farmes caught + registerCallBackAcquisitionFinished(void (*func)(int, void*),void *arg); + */ + + + //receiver->registerCallBackAcquisitionFinished(func,arg); + + + + /** + args to raw data ready callback are + framenum + datapointer + file descriptor + guidatapointer (NULL, no data required) + + NEVER DELETE THE DATA POINTER + REMEMBER THAT THE CALLBACK IS BLOCKING + + registerCallBackRawDataReady(void (*func)(int, char*, FILE*, char*, void*),void *arg); + + */ + + //receiver->registerCallBackRawDataReady(func,arg); + + + + //start tcp server thread + if(user->start() == slsReceiverDefs::OK){ + string str; + cin>>str; + //wait and look for an exit keyword + while(str.find("exit") == string::npos) + cin>>str; + //stop tcp server thread, stop udp socket + user->stop(); + } + + cout << "Goodbye!" << endl; + return 0; +} + diff --git a/slsReceiverSoftware/slsReceiver/slsReceiver.cpp b/slsReceiverSoftware/slsReceiver/slsReceiver.cpp index 3513a26c7..9491c3a92 100644 --- a/slsReceiverSoftware/slsReceiver/slsReceiver.cpp +++ b/slsReceiverSoftware/slsReceiver/slsReceiver.cpp @@ -1,90 +1,60 @@ -/* A simple server in the internet domain using TCP - The port number is passed as an argument */ +/********************************************//** + * @file slsReceiver.cpp + * @short creates the UDP and TCP class objects + ***********************************************/ -#include "sls_receiver_defs.h" -#include "slsReceiverUsers.h" - -#include -#include -using namespace std; +#include "slsReceiver.h" +#include "slsReceiverUDPFunctions.h" +#include "eigerReceiver.h" +slsReceiver::slsReceiver(int argc, char *argv[], int &success){ + //creating base receiver + cout << "SLS Receiver" << endl; + receiverBase = new slsReceiverUDPFunctions(); - - - -int main(int argc, char *argv[]) { - int ret = slsReceiverDefs::OK; - - slsReceiverUsers *user = new slsReceiverUsers(argc, argv, ret); - - if(ret==slsReceiverDefs::FAIL) - return -1; - - - //register callbacks - - - /** - callback arguments are - filepath - filename - fileindex - datasize - - return value is - 0 raw data ready callback takes care of open,close,write file - 1 callback writes file, we have to open, close it - 2 we open, close, write file, callback does not do anything - - - registerCallBackStartAcquisition(int (*func)(char*, char*,int, int, void*),void *arg); - */ - - //receiver->registerCallBackStartAcquisition(func,arg); - - - /** - callback argument is - total farmes caught - registerCallBackAcquisitionFinished(void (*func)(int, void*),void *arg); - */ - - - //receiver->registerCallBackAcquisitionFinished(func,arg); - - - - /** - args to raw data ready callback are - framenum - datapointer - file descriptor - guidatapointer (NULL, no data required) - - NEVER DELETE THE DATA POINTER - REMEMBER THAT THE CALLBACK IS BLOCKING - - registerCallBackRawDataReady(void (*func)(int, char*, FILE*, char*, void*),void *arg); - - */ - - //receiver->registerCallBackRawDataReady(func,arg); - - - - //start tcp server thread - if(user->start() == slsReceiverDefs::OK){ - string str; - cin>>str; - //wait and look for an exit keyword - while(str.find("exit") == string::npos) - cin>>str; - //stop tcp server thread, stop udp socket - user->stop(); - } - - cout << "Goodbye!" << endl; - return 0; + //tcp ip interface + tcpipInterface = new slsReceiverTCPIPInterface(argc,argv,success,receiverBase); } + +slsReceiver::~slsReceiver() {if(receiverBase) delete receiverBase; if(tcpipInterface) delete tcpipInterface;} + + +int slsReceiver::start() { + return tcpipInterface->start(); +} + + +void slsReceiver::stop() { + tcpipInterface->stop(); +} + + +void slsReceiver::closeFile(int p) { + tcpipInterface->closeFile(p); +} + + + +int64_t slsReceiver::getReceiverVersion(){ + tcpipInterface->getReceiverVersion(); +} + + +void slsReceiver::registerCallBackStartAcquisition(int (*func)(char*, char*,int, int, void*),void *arg){ + tcpipInterface->registerCallBackStartAcquisition(func,arg); +} + + + +void slsReceiver::registerCallBackAcquisitionFinished(void (*func)(int, void*),void *arg){ + tcpipInterface->registerCallBackAcquisitionFinished(func,arg); +} + + +void slsReceiver::registerCallBackRawDataReady(void (*func)(int, char*, int, FILE*, char*, void*),void *arg){ + tcpipInterface->registerCallBackRawDataReady(func,arg); +} + + diff --git a/slsReceiverSoftware/slsReceiver/slsReceiver.h b/slsReceiverSoftware/slsReceiver/slsReceiver.h new file mode 100644 index 000000000..1ab8c764a --- /dev/null +++ b/slsReceiverSoftware/slsReceiver/slsReceiver.h @@ -0,0 +1,89 @@ +/********************************************//** + * @file slsReceiver.h + * @short creates the UDP and TCP class objects + ***********************************************/ +#ifndef SLS_RECEIVER_H +#define SLS_RECEIVER_H + + +#include "slsReceiverTCPIPInterface.h" +#include "slsReceiverBase.h" + + + + +/** + *@short creates the UDP and TCP class objects + */ + +class slsReceiver : private virtual slsReceiverDefs { + +public: + /** + * Constructor + * creates the tcp interface and the udp class + * @param argc from command line + * @param argv from command line + * @param succecc socket creation was successfull + */ + slsReceiver(int argc, char *argv[], int &success); + + /** + * Destructor + */ + ~slsReceiver(); + + /** + * starts listening on the TCP port for client comminication + \return 0 for success or 1 for FAIL in creating TCP server + */ + int start(); + + /** + * stops listening to the TCP & UDP port and exit receiver program + */ + void stop(); + + /** + * Close File and exits receiver server + */ + void closeFile(int p); + + /** + * get get Receiver Version + \returns id + */ + int64_t getReceiverVersion(); + + /** + @sort register calbback for starting the acquisition + @param func callback to be called when starting the acquisition. Its arguments are filepath filename fileindex data size + \returns 0 callback takes care of open,close,write file; 1 callback writes file, we have to open, close it; 2 we open, close, write file, callback does not do anything + */ + void registerCallBackStartAcquisition(int (*func)(char*, char*,int, int, void*),void *arg); + + + /** + callback argument is + toatal farmes caught + */ + void registerCallBackAcquisitionFinished(void (*func)(int, void*),void *arg); + + /** + args to raw data ready callback are + framenum + datapointer + datasize in bytes + file descriptor + guidatapointer (NULL, no data required) + */ + void registerCallBackRawDataReady(void (*func)(int, char*, int, FILE*, char*, void*),void *arg); + + +private: + slsReceiverTCPIPInterface* tcpipInterface; + slsReceiverBase* receiverBase; +}; + + +#endif diff --git a/slsReceiverSoftware/slsReceiver/slsReceiverBase.h b/slsReceiverSoftware/slsReceiver/slsReceiverBase.h new file mode 100644 index 000000000..007bf4a97 --- /dev/null +++ b/slsReceiverSoftware/slsReceiver/slsReceiverBase.h @@ -0,0 +1,335 @@ +#ifndef SLSRECEIVERBASE_H +#define SLSRECEIVERBASE_H +/*********************************************** + * @file slsReceiverBase.h + * @short base class with all the functions for a receiver, set/get parameters, start/stop etc. + ***********************************************/ +/** + * \mainpage Base class with all the functions for a receiver, set/get parameters, start/stop etc. + */ + +/** + * @short base class with all the functions for a receiver, set/get parameters, start/stop etc. + */ + +class slsReceiverBase { + +public: + + /** + * constructor + */ + slsReceiverBase(){}; + + /** + * Destructor + */ + virtual ~slsReceiverBase() {}; + + /** + * Initialize the Receiver + @param detectorHostName detector hostname + * you can call this function only once. You must call it before you call startReceiver() for the first time. + */ + virtual void initialize(const char *detectorHostName) = 0; + + + /* Returns detector hostname + /returns hostname + * caller needs to deallocate the returned char array. + * if uninitialized, it must return NULL + */ + virtual char *getDetectorHostname() const = 0; + + /** + * Returns status of receiver: idle, running or error + */ + virtual slsReceiverDefs::runStatus getStatus() const = 0; + + /** + * Returns File Name + * caller is responsible to deallocate the returned char array. + */ + virtual char *getFileName() const = 0; + + + /** + * Returns File Path + * caller is responsible to deallocate the returned char array + */ + virtual char *getFilePath() const = 0; //FIXME: Does the caller need to free() the returned pointer? + + + /** + * Returns the number of bits per pixel + */ + virtual int getDynamicRange() const = 0; + + /** + * Returns scan tag + */ + virtual int getScanTag() const = 0; + + /* + * Returns number of frames to receive + * This is the number of frames to expect to receiver from the detector. + * The data receiver will change from running to idle when it got this number of frames + */ + virtual int getNumberOfFrames() const = 0; + + /** + * Returns file write enable + * 1: YES 0: NO + */ + virtual int getEnableFileWrite() const = 0; + + /** + * Returns file over write enable + * 1: YES 0: NO + */ + virtual int getEnableOverwrite() const = 0; + + /** + * Set File Name (without frame index, file index and extension) + @param c file name + /returns file name + * returns NULL on failure (like bad file name) + * does not check the existence of the file - we don't know which path we'll finally use, so no point to check. + * caller is responsible to deallocate the returned char array. + */ + virtual char* setFileName(const char c[]) = 0; + + /** + * Set File Path + @param c file path + /returns file path + * checks the existence of the directory. returns NULL if directory does not exist or is not readable. + * caller is responsible to deallocate the returned char array. + */ + virtual char* setFilePath(const char c[]) = 0; + + /** + * Returns the number of bits per pixel + @param dr sets dynamic range + /returns dynamic range + * returns -1 on failure + * FIXME: what are the allowd values - should we use an enum as argument? + */ + virtual int setDynamicRange(const int dr) = 0; + + + /** + * Set scan tag + @param tag scan tag + /returns scan tag (always non-negative) + * FIXME: valid range - only positive? 16bit ore 32bit? + * returns -1 on failure + */ + virtual int setScanTag(const int tag) = 0; + + /** + * Sets number of frames + @param fnum number of frames + /returns number of frames + */ + virtual int setNumberOfFrames(const int fnum) = 0; + + /** + * Set enable file write + * @param i file write enable + /returns file write enable + */ + virtual int setEnableFileWrite(const int i) = 0; + + /** + * Set enable file overwrite + * @param i file overwrite enable + /returns file overwrite enable + */ + virtual int setEnableOverwrite(const int i) = 0; + + /** + * Starts Receiver - activate all configuration settings to the eiger receiver and start to listen for packets + @param message is the error message if there is an error + /returns 0 on success or -1 on failure + */ + //FIXME: success == 0 or success == 1? + virtual int startReceiver(char *message=NULL) = 0; //FIXME: who allocates message[]? + + /** + * Stops Receiver - stops listening for packets + /returns success + * same as abort(). Always returns 0. + */ + virtual int stopReceiver() = 0; + + /** + * abort acquisition with minimum damage: close open files, cleanup. + * does nothing if state already is 'idle' + */ + virtual void abort() = 0; + + + +/******************************************************************************************************************* + **************************************** Added by Dhanya ********************************************************* + *******************************************************************************************************************/ + + /** + * Returns File Index + */ + virtual int getFileIndex() = 0; + + /** + * Returns Total Frames Caught for an entire acquisition (including all scans) + */ + virtual int getTotalFramesCaught() = 0; + + /** + * Returns Frames Caught for each real time acquisition (eg. for each scan) + */ + virtual int getFramesCaught() = 0; + + /** + * Returns current Frame Index Caught for an entire acquisition (including all scans) + */ + virtual uint32_t getAcquisitionIndex() = 0; + + /** + * Returns the frame index at start of each real time acquisition (eg. for each scan) + */ + virtual uint32_t getStartFrameIndex() = 0; + + /** get data compression, by saving only hits + */ + virtual bool getDataCompression() = 0; + + /** + * Set receiver type + * @param det detector type + * Returns success or FAIL + */ + virtual int setDetectorType(slsReceiverDefs::detectorType det) = 0; + + /** + * Set File Index + * @param i file index + */ + virtual int setFileIndex(int i) = 0; + + /** set acquisition period if a positive number + */ + virtual int64_t setAcquisitionPeriod(int64_t index) = 0; + + /** + * Set Frame Index Needed + * @param i frame index needed + */ + virtual int setFrameIndexNeeded(int i) = 0; + + /** + * Set UDP Port Number + */ + virtual void setUDPPortNo(int p) = 0; + + /** + * Set Ethernet Interface or IP to listen to + */ + virtual void setEthernetInterface(char* c) = 0; + + /** + * Set short frame + * @param i if shortframe i=1 + */ + virtual int setShortFrame(int i) = 0; + + /** + * Set the variable to send every nth frame to gui + * or if 0,send frame only upon gui request + */ + virtual int setNFrameToGui(int i) = 0; + + /** + * Resets the Total Frames Caught + * This is how the receiver differentiates between entire acquisitions + * Returns 0 + */ + virtual void resetTotalFramesCaught() = 0; + + /** enabl data compression, by saving only hits + /returns if failed + */ + virtual int enableDataCompression(bool enable) = 0; + + /** + * enable 10Gbe + @param enable 1 for 10Gbe or 0 for 1 Gbe, -1 to read out + \returns enable for 10Gbe + */ + virtual int enableTenGiga(int enable = -1) = 0; + + /** + * Returns the buffer-current frame read by receiver + * @param c pointer to current file name + * @param raw address of pointer, pointing to current frame to send to gui + * @param fnum frame number for eiger as it is not in the packet + */ + virtual void readFrame(char* c,char** raw, uint32_t &fnum) = 0; + + /** set status to transmitting and + * when fifo is empty later, sets status to run_finished + */ + virtual void startReadout() = 0; + + /** + * shuts down the udp sockets + * \returns if success or fail + */ + virtual int shutDownUDPSockets() = 0; + + /** + * Closes all files + * @param ithr thread index, -1 for all threads + */ + virtual void closeFile(int ithr = -1) = 0; + + /** + * Call back for start acquisition + callback arguments are + filepath + filename + fileindex + datasize + + return value is + 0 callback takes care of open,close,wrie file + 1 callback writes file, we have to open, close it + 2 we open, close, write file, callback does not do anything + */ + virtual void registerCallBackStartAcquisition(int (*func)(char*, char*,int, int, void*),void *arg) = 0; + + /** + * Call back for acquisition finished + callback argument is + total frames caught + */ + virtual void registerCallBackAcquisitionFinished(void (*func)(int, void*),void *arg) = 0; + + /** + * Call back for raw data + args to raw data ready callback are + framenum + datapointer + datasize in bytes + file descriptor + guidatapointer (NULL, no data required) + */ + virtual void registerCallBackRawDataReady(void (*func)(int, char*, int, FILE*, char*, void*),void *arg) = 0; + +protected: + +private: + +}; + +#endif /* #ifndef SLSRECEIVERBASE_H */ diff --git a/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.cpp b/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.cpp index 703987822..da7d26cbb 100644 --- a/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.cpp +++ b/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.cpp @@ -1,12 +1,13 @@ /********************************************//** - * @file slsReceiverTCPIPInterface.h + * @file slsReceiverTCPIPInterface.cpp * @short interface between receiver and client ***********************************************/ #include "slsReceiverTCPIPInterface.h" -#include "slsReceiverUDPFunctions.h" +#include "slsReceiverBase.h" #include "gitInfoReceiver.h" #include "slsReceiverUsers.h" +#include "slsReceiver.h" #include //SIGINT #include //EXIT @@ -27,9 +28,9 @@ slsReceiverTCPIPInterface::~slsReceiverTCPIPInterface() { } -slsReceiverTCPIPInterface::slsReceiverTCPIPInterface(int argc, char *argv[], int &success): +slsReceiverTCPIPInterface::slsReceiverTCPIPInterface(int argc, char *argv[], int &success, slsReceiverBase* rbase): myDetectorType(GOTTHARD), - slsReceiverFunctions(NULL), + receiverBase(rbase), ret(OK), lockStatus(0), shortFrame(-1), @@ -165,7 +166,6 @@ slsReceiverTCPIPInterface::slsReceiverTCPIPInterface(int argc, char *argv[], int #ifdef VERBOSE cout << "Function table assigned." << endl; #endif - slsReceiverFunctions = new slsReceiverUDPFunctions(); //Catch signal SIGINT to close files properly signal(SIGINT,staticCloseFile); @@ -193,11 +193,11 @@ int slsReceiverTCPIPInterface::start(){ void slsReceiverTCPIPInterface::stop(){ cout << "Shutting down UDP Socket" << endl; - if(slsReceiverFunctions) - slsReceiverFunctions->shutDownUDPSockets(); + if(receiverBase) + receiverBase->shutDownUDPSockets(); cout << "Closing Files... " << endl; - slsReceiverFunctions->closeFile(); + receiverBase->closeFile(); cout<<"Shutting down TCP Socket and TCP thread"<shutDownUDPSockets(); + if(receiverBase) + receiverBase->shutDownUDPSockets(); cout << "Closing Files... " << endl; - slsReceiverFunctions->closeFile(); + receiverBase->closeFile(); pthread_exit(NULL); } @@ -417,7 +417,7 @@ int slsReceiverTCPIPInterface::set_detector_type(){ } else{ myDetectorType = dr; - ret=slsReceiverFunctions->setDetectorType(dr); + ret=receiverBase->setDetectorType(dr); retval = myDetectorType; } } @@ -471,7 +471,7 @@ int slsReceiverTCPIPInterface::set_file_name() { ret=FAIL; } else - strcpy(retval,slsReceiverFunctions->setFileName(fName)); + strcpy(retval,receiverBase->setFileName(fName)); } #ifdef VERBOSE if(ret!=FAIL) @@ -520,12 +520,12 @@ int slsReceiverTCPIPInterface::set_file_dir() { sprintf(mess,"Receiver locked by %s\n", socket->lastClientIP); ret=FAIL; }/* - else if((strlen(fPath))&&(slsReceiverFunctions->getStatus()==RUNNING)){ + else if((strlen(fPath))&&(receiverBase->getStatus()==RUNNING)){ strcpy(mess,"Can not set file path while receiver running\n"); ret = FAIL; }*/ else{ - strcpy(retval,slsReceiverFunctions->setFilePath(fPath)); + strcpy(retval,receiverBase->setFilePath(fPath)); // if file path doesnt exist if(strlen(fPath)) if (strcmp(retval,fPath)){ @@ -584,7 +584,7 @@ int slsReceiverTCPIPInterface::set_file_index() { ret=FAIL; } else - retval=slsReceiverFunctions->setFileIndex(index); + retval=receiverBase->setFileIndex(index); } #ifdef VERBOSE if(ret!=FAIL) @@ -637,7 +637,7 @@ int slsReceiverTCPIPInterface::set_frame_index() { ret=FAIL; } else - retval=slsReceiverFunctions->setFrameIndexNeeded(index); + retval=receiverBase->setFrameIndexNeeded(index); } #ifdef VERBOSE if(ret!=FAIL) @@ -693,14 +693,14 @@ int slsReceiverTCPIPInterface::setup_udp(){ sprintf(mess,"Receiver locked by %s\n", socket->lastClientIP); ret=FAIL; } - else if(slsReceiverFunctions->getStatus()==RUNNING){ + else if(receiverBase->getStatus()==RUNNING){ ret = FAIL; strcpy(mess,"cannot set up udp when receiver is running\n"); } else{ //set up udp port sscanf(args[1],"%d",&udpport); - slsReceiverFunctions->setUDPPortNo(udpport); + receiverBase->setUDPPortNo(udpport); //setup udpip //get ethernet interface or IP to listen to @@ -716,7 +716,7 @@ int slsReceiverTCPIPInterface::setup_udp(){ ret = FAIL; } cout<<"eth:"<setEthernetInterface(eth); + receiverBase->setEthernetInterface(eth); //get mac address from ethernet interface if (ret != FAIL) @@ -771,13 +771,13 @@ int slsReceiverTCPIPInterface::start_receiver(){ ret=FAIL; } /* - else if(!strlen(slsReceiverFunctions->getFilePath())){ + else if(!strlen(receiverBase->getFilePath())){ strcpy(mess,"receiver not set up. set receiver ip again.\n"); ret = FAIL; } */ else { - s = slsReceiverFunctions->getStatus(); + s = receiverBase->getStatus(); switch (s) { case ERROR: strcpy(cstatus,"error"); break; case WAITING: strcpy(cstatus,"waiting"); break; @@ -787,7 +787,7 @@ int slsReceiverTCPIPInterface::start_receiver(){ default: strcpy(cstatus,"idle"); break; } if(s == IDLE) - ret=slsReceiverFunctions->startReceiver(mess); + ret=receiverBase->startReceiver(mess); else{ sprintf(mess,"Cannot start Receiver as it is in %s state\n",cstatus); ret=FAIL; @@ -824,8 +824,8 @@ int slsReceiverTCPIPInterface::stop_receiver(){ sprintf(mess,"Receiver locked by %s\n", socket->lastClientIP); ret=FAIL; } - else if(slsReceiverFunctions->getStatus()!=IDLE) - ret=slsReceiverFunctions->stopReceiver(); + else if(receiverBase->getStatus()!=IDLE) + ret=receiverBase->stopReceiver(); #endif if(ret==OK && socket->differentClients){ @@ -850,7 +850,7 @@ int slsReceiverTCPIPInterface::get_status(){ // execute action if the arguments correctly arrived #ifdef SLS_RECEIVER_UDP_FUNCTIONS - retval=slsReceiverFunctions->getStatus(); + retval=receiverBase->getStatus(); #endif if(socket->differentClients){ @@ -874,7 +874,7 @@ int slsReceiverTCPIPInterface::get_frames_caught(){ // execute action if the arguments correctly arrived #ifdef SLS_RECEIVER_UDP_FUNCTIONS - retval=slsReceiverFunctions->getTotalFramesCaught(); + retval=receiverBase->getTotalFramesCaught(); #endif if(socket->differentClients){ cout << "Force update" << endl; @@ -897,7 +897,7 @@ int slsReceiverTCPIPInterface::get_frame_index(){ // execute action if the arguments correctly arrived #ifdef SLS_RECEIVER_UDP_FUNCTIONS - retval=slsReceiverFunctions->getAcquisitionIndex(); + retval=receiverBase->getAcquisitionIndex(); #endif if(socket->differentClients){ @@ -929,7 +929,7 @@ int slsReceiverTCPIPInterface::reset_frames_caught(){ ret=FAIL; } else - slsReceiverFunctions->resetTotalFramesCaught(); + receiverBase->resetTotalFramesCaught(); } #endif @@ -980,12 +980,12 @@ int slsReceiverTCPIPInterface::set_short_frame() { sprintf(mess,"Receiver locked by %s\n", socket->lastClientIP); ret=FAIL; } - else if(slsReceiverFunctions->getStatus()==RUNNING){ + else if(receiverBase->getStatus()==RUNNING){ strcpy(mess,"Cannot set short frame while status is running\n"); ret=FAIL; } else{ - retval=slsReceiverFunctions->setShortFrame(index); + retval=receiverBase->setShortFrame(index); shortFrame = retval; if(shortFrame==-1) packetsPerFrame=GOTTHARD_PACKETS_PER_FRAME; @@ -1052,15 +1052,15 @@ int slsReceiverTCPIPInterface::moench_read_frame(){ #ifdef SLS_RECEIVER_UDP_FUNCTIONS /**send garbage with -1 index to try again*/ - if(!slsReceiverFunctions->getFramesCaught()){ + if(!receiverBase->getFramesCaught()){ arg = -1; cout<<"haven't caught any frame yet"<getStartFrameIndex(); - slsReceiverFunctions->readFrame(fName,&raw,index); + startIndex=receiverBase->getStartFrameIndex(); + receiverBase->readFrame(fName,&raw,index); /**send garbage with -1 index to try again*/ if (raw == NULL){ @@ -1224,13 +1224,13 @@ int slsReceiverTCPIPInterface::gotthard_read_frame(){ /**send garbage with -1 index to try again*/ - if(!slsReceiverFunctions->getFramesCaught()){ + if(!receiverBase->getFramesCaught()){ arg=-1; cout<<"haven't caught any frame yet"<getStartFrameIndex(); - slsReceiverFunctions->readFrame(fName,&raw,index); + startIndex=receiverBase->getStartFrameIndex(); + receiverBase->readFrame(fName,&raw,index); /**send garbage with -1 index to try again*/ if (raw == NULL){ @@ -1375,7 +1375,7 @@ int slsReceiverTCPIPInterface::eiger_read_frame(){ /**send garbage with -1 index to try again*/ - if(!slsReceiverFunctions->getFramesCaught()){ + if(!receiverBase->getFramesCaught()){ arg=-1; cout<<"haven't caught any frame yet"<readFrame(fName,&raw, index); + receiverBase->readFrame(fName,&raw, index); #ifdef VERBOSE cout << "index:" << dec << index << endl; #endif @@ -1525,12 +1525,12 @@ int slsReceiverTCPIPInterface::set_read_frequency(){ sprintf(mess,"Receiver locked by %s\n", socket->lastClientIP); ret=FAIL; }/* - else if((slsReceiverFunctions->getStatus()==RUNNING) && (index >= 0)){ + else if((receiverBase->getStatus()==RUNNING) && (index >= 0)){ ret = FAIL; strcpy(mess,"cannot set up receiver mode when receiver is running\n"); }*/ else - retval=slsReceiverFunctions->setNFrameToGui(index); + retval=receiverBase->setNFrameToGui(index); } #endif @@ -1576,7 +1576,9 @@ int slsReceiverTCPIPInterface::enable_file_write(){ ret=FAIL; } else{ - retval=slsReceiverFunctions->setEnableFileWrite(enable); + if(enable >= 0) + receiverBase->setEnableFileWrite(enable); + retval=receiverBase->getEnableFileWrite(); if((enable!=-1)&&(enable!=retval)) ret=FAIL; } @@ -1606,7 +1608,7 @@ int slsReceiverTCPIPInterface::get_id(){ // execute action if the arguments correctly arrived #ifdef SLS_RECEIVER_UDP_FUNCTIONS - retval = get_version(); + retval = getReceiverVersion(); #endif if(socket->differentClients){ @@ -1624,7 +1626,7 @@ int slsReceiverTCPIPInterface::get_id(){ -int64_t slsReceiverTCPIPInterface::get_version(){ +int64_t slsReceiverTCPIPInterface::getReceiverVersion(){ int64_t retval = SVNREV; retval= (retval <<32) | SVNDATE; return retval; @@ -1639,8 +1641,8 @@ int slsReceiverTCPIPInterface::start_readout(){ // execute action if the arguments correctly arrived #ifdef SLS_RECEIVER_UDP_FUNCTIONS - slsReceiverFunctions->startReadout(); - retval = slsReceiverFunctions->getStatus(); + receiverBase->startReadout(); + retval = receiverBase->getStatus(); if((retval == TRANSMITTING) || (retval == RUN_FINISHED) || (retval == IDLE)) ret = OK; else @@ -1687,9 +1689,9 @@ int slsReceiverTCPIPInterface::set_timer() { } else{ if(index[0] == slsReceiverDefs::FRAME_PERIOD) - retval=slsReceiverFunctions->setAcquisitionPeriod(index[1]); + retval=receiverBase->setAcquisitionPeriod(index[1]); else - retval=slsReceiverFunctions->setNumberOfFrames(index[1]); + retval=receiverBase->setNumberOfFrames(index[1]); } } #ifdef VERBOSE @@ -1744,15 +1746,15 @@ int slsReceiverTCPIPInterface::enable_compression() { sprintf(mess,"Receiver locked by %s\n", socket->lastClientIP); ret=FAIL; } - else if(slsReceiverFunctions->getStatus()==RUNNING){ + else if(receiverBase->getStatus()==RUNNING){ strcpy(mess,"Cannot enable/disable compression while status is running\n"); ret=FAIL; } else - ret = slsReceiverFunctions->enableDataCompression(enable); + ret = receiverBase->enableDataCompression(enable); } - retval=slsReceiverFunctions->getDataCompression(); + retval=receiverBase->getDataCompression(); } #endif @@ -1794,8 +1796,10 @@ int slsReceiverTCPIPInterface::set_detector_hostname() { sprintf(mess,"Receiver locked by %s\n", socket->lastClientIP); ret=FAIL; } - else - strcpy(retval,slsReceiverFunctions->setDetectorHostname(hostname)); + else{ + receiverBase->initialize(hostname); + strcpy(retval,receiverBase->getDetectorHostname()); + } } #ifdef VERBOSE if(ret!=FAIL) @@ -1859,7 +1863,7 @@ int slsReceiverTCPIPInterface::set_dynamic_range() { } } if(ret!=FAIL){ - retval=slsReceiverFunctions->setDynamicRange(dr); + retval=receiverBase->setDynamicRange(dr); dynamicrange = dr; if(myDetectorType == EIGER){ if(!tenGigaEnable) @@ -1918,8 +1922,11 @@ int slsReceiverTCPIPInterface::enable_overwrite() { sprintf(mess,"Receiver locked by %s\n", socket->lastClientIP); ret=FAIL; } - else - retval=slsReceiverFunctions->enableOverwrite(index); + else{ + if(index >= 0) + receiverBase->setEnableOverwrite(index); + retval=receiverBase->getEnableOverwrite(); + } } #ifdef VERBOSE if(ret!=FAIL) @@ -1971,7 +1978,7 @@ int slsReceiverTCPIPInterface::enable_tengiga() { ret=FAIL; } else{ - retval=slsReceiverFunctions->enableTenGiga(val); + retval=receiverBase->enableTenGiga(val); if((val!=-1) && (val != retval)) ret = FAIL; else @@ -2179,21 +2186,21 @@ int slsReceiverTCPIPInterface::send_update() { //index #ifdef SLS_RECEIVER_UDP_FUNCTIONS - ind=slsReceiverFunctions->getFileIndex(); + ind=receiverBase->getFileIndex(); socket->SendDataOnly(&ind,sizeof(ind)); #endif //filepath #ifdef SLS_RECEIVER_UDP_FUNCTIONS - strcpy(path,slsReceiverFunctions->getFilePath()); + strcpy(path,receiverBase->getFilePath()); #endif socket->SendDataOnly(path,MAX_STR_LENGTH); //filename #ifdef SLS_RECEIVER_UDP_FUNCTIONS - strcpy(path,slsReceiverFunctions->getFileName()); + strcpy(path,receiverBase->getFileName()); #endif socket->SendDataOnly(path,MAX_STR_LENGTH); diff --git a/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.h b/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.h index bddce2bd8..9ceacb21e 100644 --- a/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.h +++ b/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.h @@ -9,7 +9,7 @@ #include "sls_receiver_defs.h" #include "receiver_defs.h" #include "MySocketTCP.h" -#include "slsReceiverUDPFunctions.h" +#include "slsReceiverBase.h" @@ -26,8 +26,9 @@ public: * @param argc from command line * @param argv from command line * @param succecc socket creation was successfull + * rbase pointer to the receiver base */ - slsReceiverTCPIPInterface(int argc, char *argv[], int &success); + slsReceiverTCPIPInterface(int argc, char *argv[], int &success, slsReceiverBase* rbase); /** * Starts listening on the TCP port for client comminication @@ -48,7 +49,7 @@ public: static void staticCloseFile(int p); /** gets version */ - int64_t get_version(); + int64_t getReceiverVersion(); /** callback arguments are @@ -64,7 +65,7 @@ public: */ - void registerCallBackStartAcquisition(int (*func)(char*, char*,int, int, void*),void *arg){slsReceiverFunctions->registerCallBackStartAcquisition(func,arg);};; + void registerCallBackStartAcquisition(int (*func)(char*, char*,int, int, void*),void *arg){receiverBase->registerCallBackStartAcquisition(func,arg);};; /** @@ -74,7 +75,7 @@ public: */ - void registerCallBackAcquisitionFinished(void (*func)(int, void*),void *arg){slsReceiverFunctions->registerCallBackAcquisitionFinished(func,arg);}; + void registerCallBackAcquisitionFinished(void (*func)(int, void*),void *arg){receiverBase->registerCallBackAcquisitionFinished(func,arg);}; @@ -87,7 +88,7 @@ public: guidatapointer (NULL, no data required) */ - void registerCallBackRawDataReady(void (*func)(int, char*, int, FILE*, char*, void*),void *arg){slsReceiverFunctions->registerCallBackRawDataReady(func,arg);}; + void registerCallBackRawDataReady(void (*func)(int, char*, int, FILE*, char*, void*),void *arg){receiverBase->registerCallBackRawDataReady(func,arg);}; private: @@ -224,8 +225,8 @@ private: /** detector type */ detectorType myDetectorType; - /** slsReceiverUDPFunctions object */ - slsReceiverUDPFunctions *slsReceiverFunctions; + /** slsReceiverBase object */ + slsReceiverBase *receiverBase; /** Number of functions */ static const int numberOfFunctions = 256; diff --git a/slsReceiverSoftware/slsReceiver/slsReceiverUDPFunctions.cpp b/slsReceiverSoftware/slsReceiver/slsReceiverUDPFunctions.cpp index 382fae74e..2a630f1de 100644 --- a/slsReceiverSoftware/slsReceiver/slsReceiverUDPFunctions.cpp +++ b/slsReceiverSoftware/slsReceiver/slsReceiverUDPFunctions.cpp @@ -30,7 +30,6 @@ using namespace std; slsReceiverUDPFunctions::slsReceiverUDPFunctions(): - receiver(NULL), thread_started(0), eth(NULL), latestData(NULL), @@ -261,8 +260,6 @@ int slsReceiverUDPFunctions::setDetectorType(detectorType det){ packetIndexMask = MOENCH_PACKET_INDEX_MASK; } else if(myDetectorType == EIGER){ -#ifndef EIGERSLS - cout << "SLS Eiger Receiver" << endl; fifosize = EIGER_FIFO_SIZE; packetsPerFrame = EIGER_ONE_GIGA_CONSTANT * dynamicRange * EIGER_MAX_PORTS; onePacketSize = EIGER_ONE_GIGA_ONE_PACKET_SIZE; @@ -280,14 +277,6 @@ int slsReceiverUDPFunctions::setDetectorType(detectorType det){ createListeningThreads(true); numListeningThreads = MAX_NUM_LISTENING_THREADS; - -#else - cout << "Heiner's Receiver" << endl; - if(receiver == NULL) - receiver = EigerReceiver::create(); - receiver->setFileName(fileName); -#endif - } latestData = new char[frameSize]; @@ -360,23 +349,17 @@ void slsReceiverUDPFunctions::resetTotalFramesCaught(){ /*file parameters*/ -char* slsReceiverUDPFunctions::getFilePath(){ - if(receiver != NULL) - return receiver->getFilePath(); - else - return filePath; +char* slsReceiverUDPFunctions::getFilePath() const{ + return (char*)filePath; } -char* slsReceiverUDPFunctions::setFilePath(char c[]){ +char* slsReceiverUDPFunctions::setFilePath(const char c[]){ if(strlen(c)){ //check if filepath exists struct stat st; - if(stat(c,&st) == 0){ - if(receiver != NULL) - receiver->setFilePath(c); - else - strcpy(filePath,c); - }else{ + if(stat(c,&st) == 0) + strcpy(filePath,c); + else{ strcpy(filePath,""); cout << "FilePath does not exist:" << filePath << endl; } @@ -385,23 +368,14 @@ char* slsReceiverUDPFunctions::setFilePath(char c[]){ } -char* slsReceiverUDPFunctions::getFileName(){ - if(receiver != NULL) - return receiver->getFileName(); - else - return fileName; +char* slsReceiverUDPFunctions::getFileName() const{ + return (char*)fileName; } -char* slsReceiverUDPFunctions::setFileName(char c[]){ - if(strlen(c)){ - if(receiver != NULL) - receiver->setFileName(c); - else - strcpy(fileName,c); - - } +char* slsReceiverUDPFunctions::setFileName(const char c[]){ + if(strlen(c)) + strcpy(fileName,c); return getFileName(); - } @@ -422,67 +396,45 @@ int slsReceiverUDPFunctions::setFrameIndexNeeded(int i){ } +int slsReceiverUDPFunctions::getEnableFileWrite() const{ + return enableFileWrite; +} + int slsReceiverUDPFunctions::setEnableFileWrite(int i){ - if(i!=-1){ - if(receiver != NULL) - receiver->setEnableFileWrite(i); - else - enableFileWrite=i; - - } - if(receiver != NULL) - return receiver->getEnableFileWrite(); - else - return enableFileWrite; - + enableFileWrite=i; + return getEnableFileWrite(); } - - -int slsReceiverUDPFunctions::enableOverwrite(int i){ - if(i!=-1){ - if(receiver != NULL) - receiver->setEnableOverwrite(i); - else - overwrite=i; - - } - if(receiver != NULL) - return receiver->getEnableOverwrite(); - else - return overwrite; - +int slsReceiverUDPFunctions::getEnableOverwrite() const{ + return overwrite; } +int slsReceiverUDPFunctions::setEnableOverwrite(int i){ + overwrite=i; + return getEnableOverwrite(); +} + + /*other parameters*/ -slsReceiverDefs::runStatus slsReceiverUDPFunctions::getStatus(){ - if(receiver != NULL) - return receiver->getStatus(); - else - return status; +slsReceiverDefs::runStatus slsReceiverUDPFunctions::getStatus() const{ + return status; } -char* slsReceiverUDPFunctions::setDetectorHostname(char c[]){ - if(strlen(c)){ - if(receiver != NULL){ - if(receiver->getDetectorHostname()== NULL) - receiver->initialize(c); - }else - strcpy(detHostname,c); - } - - if(receiver != NULL) - return receiver->getDetectorHostname(); - else - return detHostname; +void slsReceiverUDPFunctions::initialize(const char *detectorHostName){ + if(strlen(detectorHostName)) + strcpy(detHostname,detectorHostName); } +char *slsReceiverUDPFunctions::getDetectorHostname() const{ + return (char*)detHostname; +} + void slsReceiverUDPFunctions::setEthernetInterface(char* c){ strcpy(eth,c); } @@ -495,32 +447,33 @@ void slsReceiverUDPFunctions::setUDPPortNo(int p){ } -int32_t slsReceiverUDPFunctions::setNumberOfFrames(int32_t fnum){ - if(fnum >= 0){ - if(receiver != NULL) - receiver->setNumberOfFrames(fnum); - else - numberOfFrames = fnum; - } - - if(receiver != NULL) - return receiver->getNumberOfFrames(); - else - return numberOfFrames; +int slsReceiverUDPFunctions::getNumberOfFrames() const { + return numberOfFrames; } -int32_t slsReceiverUDPFunctions::setScanTag(int32_t stag){ - if(stag >= 0){ - if(receiver != NULL) - receiver->setScanTag(stag); - else - scanTag = stag; - } - if(receiver != NULL) - return receiver->getScanTag(); - else - return scanTag; +int32_t slsReceiverUDPFunctions::setNumberOfFrames(int32_t fnum){ + if(fnum >= 0) + numberOfFrames = fnum; + + return getNumberOfFrames(); +} + +int slsReceiverUDPFunctions::getScanTag() const{ + return scanTag; +} + + +int32_t slsReceiverUDPFunctions::setScanTag(int32_t stag){ + if(stag >= 0) + scanTag = stag; + + return getScanTag(); +} + + +int slsReceiverUDPFunctions::getDynamicRange() const{ + return dynamicRange; } int32_t slsReceiverUDPFunctions::setDynamicRange(int32_t dr){ @@ -528,63 +481,57 @@ int32_t slsReceiverUDPFunctions::setDynamicRange(int32_t dr){ int olddr = dynamicRange; if(dr >= 0){ - if(receiver != NULL) - receiver->setDynamicRange(dr); - else{ - dynamicRange = dr; + dynamicRange = dr; - if(myDetectorType == EIGER){ + if(myDetectorType == EIGER){ - if(!tengigaEnable) - packetsPerFrame = EIGER_ONE_GIGA_CONSTANT * dynamicRange * EIGER_MAX_PORTS; - else - packetsPerFrame = EIGER_TEN_GIGA_CONSTANT * dynamicRange * EIGER_MAX_PORTS; - frameSize = onePacketSize * packetsPerFrame; - bufferSize = (frameSize/EIGER_MAX_PORTS) + EIGER_HEADER_LENGTH;//everything one port gets (img header plus packets) - maxPacketsPerFile = EIGER_MAX_FRAMES_PER_FILE * packetsPerFrame; + if(!tengigaEnable) + packetsPerFrame = EIGER_ONE_GIGA_CONSTANT * dynamicRange * EIGER_MAX_PORTS; + else + packetsPerFrame = EIGER_TEN_GIGA_CONSTANT * dynamicRange * EIGER_MAX_PORTS; + frameSize = onePacketSize * packetsPerFrame; + bufferSize = (frameSize/EIGER_MAX_PORTS) + EIGER_HEADER_LENGTH;//everything one port gets (img header plus packets) + maxPacketsPerFile = EIGER_MAX_FRAMES_PER_FILE * packetsPerFrame; - if(olddr != dr){ + if(olddr != dr){ - //del - if(thread_started){ - createListeningThreads(true); - createWriterThreads(true); - } - for(int i=0;igetDynamicRange(); - else - return dynamicRange; + return getDynamicRange(); } @@ -634,8 +581,7 @@ int64_t slsReceiverUDPFunctions::setAcquisitionPeriod(int64_t index){ if(index >= 0){ if(index != acquisitionPeriod){ acquisitionPeriod = index; - if(receiver != NULL) - setupFifoStructure(); + setupFifoStructure(); } } return acquisitionPeriod; @@ -752,9 +698,6 @@ void slsReceiverUDPFunctions::setupFilter(){ void slsReceiverUDPFunctions::setupFifoStructure(){ - if(receiver != NULL) - return; - int64_t i; int oldn = numJobsPerThread; @@ -1368,9 +1311,6 @@ void slsReceiverUDPFunctions::closeFile(int ithr){ int slsReceiverUDPFunctions::startReceiver(char message[]){ int i; - if(receiver != NULL) - return receiver->startReceiver(message); - // #ifdef VERBOSE cout << "Starting Receiver" << endl; @@ -1435,9 +1375,6 @@ int slsReceiverUDPFunctions::startReceiver(char message[]){ int slsReceiverUDPFunctions::stopReceiver(){ - if(receiver != NULL) - return receiver->stopReceiver(); - //#ifdef VERBOSE cout << "Stopping Receiver" << endl; @@ -1468,10 +1405,6 @@ int slsReceiverUDPFunctions::stopReceiver(){ void slsReceiverUDPFunctions::startReadout(){ - if(receiver != NULL){ - receiver->stopReceiver(); - return; - } //#ifdef VERBOSE cout << "Start Receiver Readout" << endl; //#endif @@ -2283,74 +2216,68 @@ int slsReceiverUDPFunctions::enableTenGiga(int enable){ int oldtengiga = tengigaEnable; if(enable >= 0){ - if(receiver != NULL) - ;/*receiver->setTenGigaBitEthernet(enable);*/ - else{ - tengigaEnable = enable; - if(myDetectorType == EIGER){ + tengigaEnable = enable; - if(!tengigaEnable){ - packetsPerFrame = EIGER_ONE_GIGA_CONSTANT * dynamicRange * EIGER_MAX_PORTS; - onePacketSize = EIGER_ONE_GIGA_ONE_PACKET_SIZE; - maxPacketsPerFile = EIGER_MAX_FRAMES_PER_FILE * packetsPerFrame; - }else{ - packetsPerFrame = EIGER_TEN_GIGA_CONSTANT * dynamicRange * EIGER_MAX_PORTS; - onePacketSize = EIGER_TEN_GIGA_ONE_PACKET_SIZE; - maxPacketsPerFile = EIGER_MAX_FRAMES_PER_FILE * packetsPerFrame*4; + if(myDetectorType == EIGER){ + + if(!tengigaEnable){ + packetsPerFrame = EIGER_ONE_GIGA_CONSTANT * dynamicRange * EIGER_MAX_PORTS; + onePacketSize = EIGER_ONE_GIGA_ONE_PACKET_SIZE; + maxPacketsPerFile = EIGER_MAX_FRAMES_PER_FILE * packetsPerFrame; + }else{ + packetsPerFrame = EIGER_TEN_GIGA_CONSTANT * dynamicRange * EIGER_MAX_PORTS; + onePacketSize = EIGER_TEN_GIGA_ONE_PACKET_SIZE; + maxPacketsPerFile = EIGER_MAX_FRAMES_PER_FILE * packetsPerFrame*4; + } + frameSize = onePacketSize * packetsPerFrame; + bufferSize = (frameSize/EIGER_MAX_PORTS) + EIGER_HEADER_LENGTH;//everything one port gets (img header plus packets) + //maxPacketsPerFile = EIGER_MAX_FRAMES_PER_FILE * packetsPerFrame; + + + cout<<"packetsPerFrame:"<getTenGigaBitEthernet();*/ - else - return tengigaEnable; - + return tengigaEnable; } diff --git a/slsReceiverSoftware/slsReceiver/slsReceiverUDPFunctions.h b/slsReceiverSoftware/slsReceiver/slsReceiverUDPFunctions.h index 3cb1872cf..99424aaea 100644 --- a/slsReceiverSoftware/slsReceiver/slsReceiverUDPFunctions.h +++ b/slsReceiverSoftware/slsReceiver/slsReceiverUDPFunctions.h @@ -14,7 +14,9 @@ #include "singlePhotonDetector.h" #include "slsReceiverData.h" #include "moenchCommonMode.h" -#include "eigerReceiver.h" + +#include "slsReceiverBase.h" + #ifdef MYROOT1 #include @@ -32,7 +34,7 @@ * @short does all the functions for a receiver, set/get parameters, start/stop etc. */ -class slsReceiverUDPFunctions : private virtual slsReceiverDefs { +class slsReceiverUDPFunctions : private virtual slsReceiverDefs, public slsReceiverBase { public: /** @@ -113,24 +115,24 @@ public: /** * Returns File Path */ - char* getFilePath(); + char* getFilePath() const; /** * Set File Path * @param c file path */ - char* setFilePath(char c[]); + char* setFilePath(const char c[]); /** * Returns File Name */ - char* getFileName(); + char* getFileName() const; /** * Set File Name (without frame index, file index and extension) * @param c file name */ - char* setFileName(char c[]); + char* setFileName(const char c[]); /** * Returns File Index @@ -161,22 +163,45 @@ public: * @param i enable * Returns enable over write */ - int enableOverwrite(int i); + int setEnableOverwrite(int i); + /** + * Returns file write enable + * 1: YES 0: NO + */ + int getEnableFileWrite() const; + /** + * Returns file over write enable + * 1: YES 0: NO + */ + int getEnableOverwrite() const; //other parameters + /** + * abort acquisition with minimum damage: close open files, cleanup. + * does nothing if state already is 'idle' + */ + void abort() {}; + /** * Returns status of receiver: idle, running or error */ - runStatus getStatus(); + runStatus getStatus() const; /** * Set detector hostname * @param c hostname */ - char* setDetectorHostname(char c[]); + void initialize(const char *detectorHostName); + + /* Returns detector hostname + /returns hostname + * caller needs to deallocate the returned char array. + * if uninitialized, it must return NULL + */ + char *getDetectorHostname() const; /** * Set Ethernet Interface or IP to listen to @@ -188,16 +213,33 @@ public: */ void setUDPPortNo(int p); + /* + * Returns number of frames to receive + * This is the number of frames to expect to receiver from the detector. + * The data receiver will change from running to idle when it got this number of frames + */ + int getNumberOfFrames() const; + /** * set frame number if a positive number */ int32_t setNumberOfFrames(int32_t fnum); + /** + * Returns scan tag + */ + int getScanTag() const; + /** * set scan tag if its is a positive number */ int32_t setScanTag(int32_t stag); + /** + * Returns the number of bits per pixel + */ + int getDynamicRange() const; + /** * set dynamic range if its is a positive number */ @@ -440,9 +482,6 @@ private: /** max number of writer threads */ const static int MAX_NUM_WRITER_THREADS = 15; - /** Eiger Receiver */ - EigerReceiver *receiver; - /** detector type */ detectorType myDetectorType; diff --git a/slsReceiverSoftware/slsReceiver/slsReceiverUsers.cpp b/slsReceiverSoftware/slsReceiver/slsReceiverUsers.cpp index f0e655f3c..9b1f147da 100644 --- a/slsReceiverSoftware/slsReceiver/slsReceiverUsers.cpp +++ b/slsReceiverSoftware/slsReceiver/slsReceiverUsers.cpp @@ -1,10 +1,10 @@ #include "slsReceiverUsers.h" -#include "slsReceiverTCPIPInterface.h" +#include "slsReceiver.h" -slsReceiverTCPIPInterface* slsReceiverUsers::receiver(NULL); +slsReceiver* slsReceiverUsers::receiver(NULL); slsReceiverUsers::slsReceiverUsers(int argc, char *argv[], int &success) { - slsReceiverUsers::receiver=new slsReceiverTCPIPInterface(argc, argv, success); + slsReceiverUsers::receiver=new slsReceiver(argc, argv, success); } slsReceiverUsers::~slsReceiverUsers() { @@ -25,7 +25,7 @@ void slsReceiverUsers::closeFile(int p) { } int64_t slsReceiverUsers::getReceiverVersion(){ - slsReceiverUsers::receiver->get_version(); + slsReceiverUsers::receiver->getReceiverVersion(); } diff --git a/slsReceiverSoftware/slsReceiver/slsReceiverUsers.h b/slsReceiverSoftware/slsReceiver/slsReceiverUsers.h index 2dee1e151..a9d3626d2 100644 --- a/slsReceiverSoftware/slsReceiver/slsReceiverUsers.h +++ b/slsReceiverSoftware/slsReceiver/slsReceiverUsers.h @@ -5,7 +5,8 @@ #include #include -class slsReceiverTCPIPInterface; + +class slsReceiver; /** @short Class for implementing the SLS data receiver in the users application. Callbacks can be defined for processing and/or saving data @@ -84,7 +85,7 @@ public: void registerCallBackRawDataReady(void (*func)(int framenumber, char* datapointer, int datasize, FILE* filedescriptor, char* guidatapointer, void*),void *arg); // made static to close thread files with ctrl+c - static slsReceiverTCPIPInterface* receiver; + static slsReceiver* receiver; }; diff --git a/slsReceiverSoftware/slsReceiverUsers.doxy b/slsReceiverSoftware/slsReceiverUsers.doxy new file mode 100644 index 000000000..b5d37ae18 --- /dev/null +++ b/slsReceiverSoftware/slsReceiverUsers.doxy @@ -0,0 +1,86 @@ +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + + + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = YES + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = YES + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base +# name of the file that contains the anonymous namespace. By default +# anonymous namespace are hidden. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +INTERNAL_DOCS = NO + +SHOW_INCLUDE_FILES = NO + +SHOW_FILES = NO + +SHOW_NAMESPACES = NO + +COMPACT_LATEX = YES + +PAPER_TYPE = a4 + +PDF_HYPERLINKS = YES + +USE_PDFLATEX = YES + +LATEX_HIDE_INDICES = YES + + +PREDEFINED = __cplusplus + +INPUT = slsReceiver/slsReceiverBase.h + +OUTPUT_DIRECTORY = slsReceiverUsersDocs From 4f04fc54575e4275e0acde23933304f2cc4e4789 Mon Sep 17 00:00:00 2001 From: Anna Bergamaschi Date: Fri, 18 Jul 2014 12:57:10 +0200 Subject: [PATCH 014/474] removed callbacks from tcpip interface --- .../slsReceiver/slsReceiver.cpp | 9 ++-- .../slsReceiver/slsReceiverTCPIPInterface.h | 52 +++++++++---------- 2 files changed, 32 insertions(+), 29 deletions(-) diff --git a/slsReceiverSoftware/slsReceiver/slsReceiver.cpp b/slsReceiverSoftware/slsReceiver/slsReceiver.cpp index 9491c3a92..72e9bf7fb 100644 --- a/slsReceiverSoftware/slsReceiver/slsReceiver.cpp +++ b/slsReceiverSoftware/slsReceiver/slsReceiver.cpp @@ -43,18 +43,21 @@ int64_t slsReceiver::getReceiverVersion(){ void slsReceiver::registerCallBackStartAcquisition(int (*func)(char*, char*,int, int, void*),void *arg){ - tcpipInterface->registerCallBackStartAcquisition(func,arg); + //tcpipInterface + receiverBase->registerCallBackStartAcquisition(func,arg); } void slsReceiver::registerCallBackAcquisitionFinished(void (*func)(int, void*),void *arg){ - tcpipInterface->registerCallBackAcquisitionFinished(func,arg); + //tcpipInterface + receiverBase->registerCallBackAcquisitionFinished(func,arg); } void slsReceiver::registerCallBackRawDataReady(void (*func)(int, char*, int, FILE*, char*, void*),void *arg){ - tcpipInterface->registerCallBackRawDataReady(func,arg); + //tcpipInterface + receiverBase->registerCallBackRawDataReady(func,arg); } diff --git a/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.h b/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.h index 9ceacb21e..d4c1681b5 100644 --- a/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.h +++ b/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.h @@ -51,44 +51,44 @@ public: /** gets version */ int64_t getReceiverVersion(); - /** - callback arguments are - filepath - filename - fileindex - data size +/* /\** */ +/* callback arguments are */ +/* filepath */ +/* filename */ +/* fileindex */ +/* data size */ - return value is - 0 callback takes care of open,close,wrie file - 1 callback writes file, we have to open, close it - 2 we open, close, write file, callback does not do anything +/* return value is */ +/* 0 callback takes care of open,close,wrie file */ +/* 1 callback writes file, we have to open, close it */ +/* 2 we open, close, write file, callback does not do anything */ - */ +/* *\/ */ - void registerCallBackStartAcquisition(int (*func)(char*, char*,int, int, void*),void *arg){receiverBase->registerCallBackStartAcquisition(func,arg);};; +/* void registerCallBackStartAcquisition(int (*func)(char*, char*,int, int, void*),void *arg){receiverBase->registerCallBackStartAcquisition(func,arg);};; */ - /** - callback argument is - toatal farmes caught +/* /\** */ +/* callback argument is */ +/* toatal farmes caught */ - */ +/* *\/ */ - void registerCallBackAcquisitionFinished(void (*func)(int, void*),void *arg){receiverBase->registerCallBackAcquisitionFinished(func,arg);}; +/* void registerCallBackAcquisitionFinished(void (*func)(int, void*),void *arg){receiverBase->registerCallBackAcquisitionFinished(func,arg);}; */ - /** - args to raw data ready callback are - framenum - datapointer - datasize in bytes - file descriptor - guidatapointer (NULL, no data required) - */ +/* /\** */ +/* args to raw data ready callback are */ +/* framenum */ +/* datapointer */ +/* datasize in bytes */ +/* file descriptor */ +/* guidatapointer (NULL, no data required) */ +/* *\/ */ - void registerCallBackRawDataReady(void (*func)(int, char*, int, FILE*, char*, void*),void *arg){receiverBase->registerCallBackRawDataReady(func,arg);}; +/* void registerCallBackRawDataReady(void (*func)(int, char*, int, FILE*, char*, void*),void *arg){receiverBase->registerCallBackRawDataReady(func,arg);}; */ private: From 91c0a083b3d87f5e9b24a733bbfa9e42e00d48e7 Mon Sep 17 00:00:00 2001 From: Anna Bergamaschi Date: Fri, 25 Jul 2014 10:28:56 +0200 Subject: [PATCH 015/474] argv, argc moved from tcpip interface to slsReceiver --- .../slsReceiver/slsReceiver.cpp | 126 +++++++++++++- .../slsReceiver/slsReceiverTCPIPInterface.cpp | 155 ++++++------------ .../slsReceiver/slsReceiverTCPIPInterface.h | 20 ++- 3 files changed, 188 insertions(+), 113 deletions(-) diff --git a/slsReceiverSoftware/slsReceiver/slsReceiver.cpp b/slsReceiverSoftware/slsReceiver/slsReceiver.cpp index 72e9bf7fb..cd5ab551d 100644 --- a/slsReceiverSoftware/slsReceiver/slsReceiver.cpp +++ b/slsReceiverSoftware/slsReceiver/slsReceiver.cpp @@ -3,18 +3,140 @@ * @short creates the UDP and TCP class objects ***********************************************/ +#include +#include +#include +#include +#include + #include "slsReceiver.h" #include "slsReceiverUDPFunctions.h" #include "eigerReceiver.h" +using namespace std; slsReceiver::slsReceiver(int argc, char *argv[], int &success){ //creating base receiver cout << "SLS Receiver" << endl; receiverBase = new slsReceiverUDPFunctions(); + int tcpip_port_no=-1; + + + + ifstream infile; + string sLine,sargname; + int iline = 0; + + + success=OK; + + string fname = ""; + + //parse command line for config + for(int iarg=1;iarg> sargname; + + //tcp port + if(sargname=="rx_tcpport"){ + if(sstr.good()) { + sstr >> sargname; + if(sscanf(sargname.c_str(),"%d",&tcpip_port_no)) + cout<<"dataport:"<> sargname; - - //tcp port - if(sargname=="rx_tcpport"){ - if(sstr.good()) { - sstr >> sargname; - if(sscanf(sargname.c_str(),"%d",&port_no)) - cout<<"dataport:"<0) + port_no = pn; + success=OK; //create socket if(success == OK){ @@ -157,6 +56,7 @@ slsReceiverTCPIPInterface::slsReceiverTCPIPInterface(int argc, char *argv[], int delete socket; socket=NULL; } else { + portNumber=port_no; //initialize variables strcpy(socket->lastClientIP,"none"); strcpy(socket->thisClientIP,"none1"); @@ -175,6 +75,47 @@ slsReceiverTCPIPInterface::slsReceiverTCPIPInterface(int argc, char *argv[], int } +int slsReceiverTCPIPInterface::setPortNumber(int pn){ + int p_number; + MySocketTCP *oldsocket=NULL;; + int sd=0; + + if (pn>0) { + p_number = pn; + + if (p_number<1024) { + sprintf(mess,"Too low port number %d\n", p_number); + cout << mess << endl; + } else { + + oldsocket=socket; + socket = new MySocketTCP(p_number); + if(socket){ + sd = socket->getErrorStatus(); + if (!sd){ + portNumber=p_number; + delete oldsocket; + } else { + cout << "Could not bind port " << p_number << endl; + if (sd==-10) { + + cout << "Port "<< p_number << " already set" << endl; + } else { + delete socket; + socket=oldsocket; + } + } + + } else { + socket=oldsocket; + } + } + } + + return portNumber; +} + + int slsReceiverTCPIPInterface::start(){ cout << "Creating TCP Server Thread" << endl; diff --git a/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.h b/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.h index d4c1681b5..423d0949a 100644 --- a/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.h +++ b/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.h @@ -23,12 +23,19 @@ public: /** * Constructor * reads config file, creates socket, assigns function table - * @param argc from command line - * @param argv from command line * @param succecc socket creation was successfull - * rbase pointer to the receiver base + * @param rbase pointer to the receiver base + * @param pn port number (defaults to default port number) */ - slsReceiverTCPIPInterface(int argc, char *argv[], int &success, slsReceiverBase* rbase); + slsReceiverTCPIPInterface(int &success, slsReceiverBase* rbase, int pn=-1); + + /** + * Sets the port number to listen to. + Take care that the client must know to whcih port it has to listen to, so normally it is better to use a fixes port from the instatiation or change it from the client. + @param pn port number (-1 only get) + \returns actual port number + */ + int setPortNumber(int pn=-1); /** * Starts listening on the TCP port for client comminication @@ -100,6 +107,7 @@ private: */ static void* startTCPServerThread(void *this_pointer); + /** * Thread started which is a TCP server * Called by start() @@ -261,6 +269,10 @@ private: /** size of one frame*/ int tenGigaEnable; + /** port number */ + int portNumber; + + protected: /** Socket */ MySocketTCP* socket; From 3e36b603f95f7e50c0489a470ee454387c73dbb4 Mon Sep 17 00:00:00 2001 From: Maliakal Dhanya Date: Thu, 31 Jul 2014 12:13:15 +0200 Subject: [PATCH 016/474] receiver nth frame and acquisition indices for eiger --- .../slsReceiver/slsReceiverTCPIPInterface.cpp | 3 + .../slsReceiver/slsReceiverUDPFunctions.cpp | 63 ++++++++++++------- .../slsReceiver/slsReceiverUDPFunctions.h | 4 +- 3 files changed, 46 insertions(+), 24 deletions(-) diff --git a/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.cpp b/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.cpp index cadde6508..cc143efc4 100644 --- a/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.cpp +++ b/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.cpp @@ -1318,7 +1318,9 @@ int slsReceiverTCPIPInterface::eiger_read_frame(){ /**send garbage with -1 index to try again*/ if(!receiverBase->getFramesCaught()){ arg=-1; +#ifdef VERBOSE cout<<"haven't caught any frame yet"<fnum); + tempframenum += (startFrameIndex-1); //eiger frame numbers start at 1, so need to -1 }else if ((myDetectorType == GOTTHARD) && (shortFrame == -1)) tempframenum = (((((uint32_t)(*((uint32_t*)(wbuf[ithread] + HEADER_SIZE_NUM_TOT_PACKETS))))+1)& (frameIndexMask)) >> frameIndexOffset); else @@ -1840,6 +1852,7 @@ int loop; void slsReceiverUDPFunctions::startFrameIndices(int ithread){ if (myDetectorType == EIGER) + //add currframenum later in this method for scans startFrameIndex = htonl(*(unsigned int*)((eiger_image_header *)((char*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS)))->fnum); //gotthard has +1 for frame number and not a short frame else if ((myDetectorType == GOTTHARD) && (shortFrame == -1)) @@ -1850,9 +1863,6 @@ void slsReceiverUDPFunctions::startFrameIndices(int ithread){ & (frameIndexMask)) >> frameIndexOffset); - cout << "startFrameIndex:" << startFrameIndex<push(buffer[ithread]); @@ -1898,37 +1917,37 @@ int i; cout << ithread << " going to push in dummy buffer:" << (void*)buffer[ithread] << " with num packets:"<< (*((uint16_t*)(buffer[ithread]))) << endl; #endif while(!fifo[ithread]->push(buffer[ithread])); -//#ifdef VERYDEBUG +#ifdef VERYDEBUG cout << ithread << " pushed in dummy buffer:" << (void*)buffer[ithread] << endl; -//#endif +#endif } //reset mask and exit loop pthread_mutex_lock(&status_mutex); listeningthreads_mask^=(1< 1) cout << "Waiting for listening to be done.. current mask:" << hex << listeningthreads_mask << endl; -//#endif +#endif while(listeningthreads_mask) usleep(5000); -//#ifdef VERYDEBUG +#ifdef VERYDEBUG t = 0; for(i=0;i Date: Tue, 5 Aug 2014 11:08:11 +0200 Subject: [PATCH 017/474] added old (workaround) EigerReceiver. Still not using slsReceiverBase --- slsReceiverSoftware/Makefile | 3 +- slsReceiverSoftware/slsReceiver/Makefile | 10 +- .../eigerReceiver/eigerReceiver.cpp | 169 +++++++++--------- .../eigerReceiver/eigerReceiverDummy.cpp | 2 + .../eigerReceiver/eigerReceiverTest.cpp | 2 +- .../slsReceiver/slsReceiverBase.h | 70 ++++++-- 6 files changed, 153 insertions(+), 103 deletions(-) diff --git a/slsReceiverSoftware/Makefile b/slsReceiverSoftware/Makefile index 4aa0c3fde..338686cef 100644 --- a/slsReceiverSoftware/Makefile +++ b/slsReceiverSoftware/Makefile @@ -11,7 +11,7 @@ CFLAGS= -g -DC_ONLY -fPIC DFLAGS= -g -DDACS_INT -DSLS_RECEIVER_UDP_FUNCTIONS -INCLUDES?= -I. -Iincludes -IMySocketTCP -IslsReceiver -IslsDetectorCalibration -IslsReceiver/eigerReceiver -I$(ASM) +INCLUDES?= -I. -Iincludes -IMySocketTCP -IslsReceiver -IslsDetectorCalibration -IslsReceiver/eigerReceiver -I$(ASM) -I../slsDetectorSoftware/commonFiles #-IslsReceiverInterface SRC_CLNT= MySocketTCP/MySocketTCP.cpp slsReceiver/slsReceiver.cpp slsReceiver/slsReceiverUDPFunctions.cpp slsReceiver/slsReceiverTCPIPInterface.cpp slsReceiver/slsReceiverUsers.cpp @@ -37,6 +37,7 @@ else ifeq ($(ROOTSLS),yes) $(CXX) -DROOTSLS -o $@ -c $< $(INCLUDES) $(DFLAGS) $(ROOTFLAGS) -fPIC $(EPICSFLAGS) -L/usr/lib64/ #$(FLAGS) else echo "without root" + echo $(INCLUDES) $(CXX) -o $@ -c $< $(INCLUDES) $(DFLAGS) -fPIC $(EPICSFLAGS) -lpthread #$(FLAGS) endif diff --git a/slsReceiverSoftware/slsReceiver/Makefile b/slsReceiverSoftware/slsReceiver/Makefile index d5f02c2ea..c94528eeb 100644 --- a/slsReceiverSoftware/slsReceiver/Makefile +++ b/slsReceiverSoftware/slsReceiver/Makefile @@ -13,7 +13,7 @@ LDFLAGRXR ?= -L$(LIBDIR) -lSlsReceiver -L/usr/lib64/ -lpthread LDFLAGRXR += -lm -lstdc++ -INCLUDES ?= -I ../MySocketTCP -I ../slsDetectorCalibration -I ../includes -I eigerReceiver -I . +INCLUDES ?= -I ../MySocketTCP -I ../slsDetectorCalibration -I ../includes -I eigerReceiver -I . -I ../slsDetectorSoftware/commonFiles SRC_CLNT = main.cpp @@ -46,13 +46,13 @@ $(DESTDIR)/slsReceiver: eigerReceiver lib ifeq ($(EIGERSLS), yes) eigerReceiver: - $(CXX) $(FLAGS) $(CFLAGS) -fPIC -c -o eigerReceiverTest.o eigerReceiver/eigerReceiverTest.cpp $(EIGERFLAGS) - $(CXX) $(FLAGS) $(CFLAGS) -fPIC -c -o eigerReceiver.o eigerReceiver/eigerReceiver.cpp $(EIGERFLAGS) + $(CXX) $(FLAGS) $(CFLAGS) $(INCLUDES) -fPIC -c -o eigerReceiverTest.o eigerReceiver/eigerReceiverTest.cpp $(EIGERFLAGS) + $(CXX) $(FLAGS) $(CFLAGS) $(INCLUDES) -fPIC -c -o eigerReceiver.o eigerReceiver/eigerReceiver.cpp $(EIGERFLAGS) $(CXX) eigerReceiverTest.o eigerReceiver.o -o eigerReceiver/eigerReceiverTest $(EIGERFLAGS) else ifeq ($(ROOTSLS), yes) eigerReceiver: eigerReceiver/eigerReceiverDummy.cpp echo "Compiling with root" - $(CXX) $(FLAGS) $(CFLAGS) -fPIC -c -o eigerReceiver.o eigerReceiver/eeigerReceiverDummy.cpp $(ROOTFLAGS) + $(CXX) $(FLAGS) $(CFLAGS) $(INCLUDES) -fPIC -c -o eigerReceiver.o eigerReceiver/eigerReceiverDummy.cpp $(ROOTFLAGS) else eigerReceiver: eigerReceiver/eigerReceiverDummy.cpp $(CXX) $(FLAGS) $(CFLAGS) $(INCLUDES) -fPIC -c -o eigerReceiver.o eigerReceiver/eigerReceiverDummy.cpp @@ -63,6 +63,6 @@ lib: clean: rm -rf $(PROGS) *.o eigerReceiverTest $(DESTDIR)/libSlsReceiver.a $(DESTDIR)/libSlsReceiver.so core - + diff --git a/slsReceiverSoftware/slsReceiver/eigerReceiver/eigerReceiver.cpp b/slsReceiverSoftware/slsReceiver/eigerReceiver/eigerReceiver.cpp index fa19895be..48024c5d0 100644 --- a/slsReceiverSoftware/slsReceiver/eigerReceiver/eigerReceiver.cpp +++ b/slsReceiverSoftware/slsReceiver/eigerReceiver/eigerReceiver.cpp @@ -39,77 +39,77 @@ struct EigerReceiverScanConfiguration { bool doFileOverWrite; EigerReceiverScanConfiguration(): - dynamicRange(-1), - scanTag(-1), - numberOfFrames(-1), - doFileWrite(false), - doFileOverWrite(false){}; + dynamicRange(-1), + scanTag(-1), + numberOfFrames(-1), + doFileWrite(false), + doFileOverWrite(false){}; }; class EigerReceiverImplementation: public EigerReceiver { - + public: - + EigerReceiverImplementation() : isInitialized(false), status(slsReceiverDefs::ERROR) {}; - + void initialize(const char *detectorHostname) { - - string name; - if (detectorHostname != NULL) { - name = detectorHostname; - } - - if (name.empty()) { - DEBUG("initialize(): can't initialize with empty string or NULL for detectorHostname"); - } else if (isInitialized == true) { - DEBUG("initialize(): already initialized, can't initialize several times"); - } else { - DEBUG("initialize(): initialize() with: detectorHostName=" << name << "."); - init_config.detectorHostname = name; - isInitialized = true; - status = slsReceiverDefs::IDLE; - } - + + string name; + if (detectorHostname != NULL) { + name = detectorHostname; + } + + if (name.empty()) { + DEBUG("initialize(): can't initialize with empty string or NULL for detectorHostname"); + } else if (isInitialized == true) { + DEBUG("initialize(): already initialized, can't initialize several times"); + } else { + DEBUG("initialize(): initialize() with: detectorHostName=" << name << "."); + init_config.detectorHostname = name; + isInitialized = true; + status = slsReceiverDefs::IDLE; + } + #ifdef SALA - //REST call - hardcoded - RestHelper rest ; - rest.init("localhost",8080); - std::string answer; - std::cout << "---- REST test 1: true, string "<< std::endl; - int code = rest.get_json("status", &answer); - std::cout << "Answer: " << answer << std::endl; - - std::cout << "---- REST test 2: 404, string "<< std::endl; - code = rest.get_json("statuss", &answer); - if (code != 0){ - //throw -1; - std::cout << "I SHOULD THROW AN EXCEPTION!!!" << std::endl; - } - - std::cout << "---- REST test 3: true, json object "<< std::endl; - JsonBox::Value json_value; - code = rest.get_json("status", &json_value); - std::cout << "JSON " << json_value["status"] << std::endl; - - answer = ""; - std::cout << "---- REST test 4: POST, string "<< std::endl; - code = rest.post_json("recipes/cassoela", &answer); - std::cout << "POST answer: " << answer << std::endl; - if (code != 0){ - //throw -1; - std::cout << "I SHOULD THROW AN EXCEPTION!!!" << std::endl; - } - - RestHelper rest2 ; - rest2.init("reallyfake",8080); - std::cout << "---- REST test 4: host not found, json object "<< std::endl; - JsonBox::Value json_value2; - code = rest2.get_json("status", &json_value2); - if (code != 0){ - //throw -1; - std::cout << "I SHOULD THROW AN EXCEPTION!!!" << std::endl; - } - + //REST call - hardcoded + RestHelper rest ; + rest.init("localhost",8080); + std::string answer; + std::cout << "---- REST test 1: true, string "<< std::endl; + int code = rest.get_json("status", &answer); + std::cout << "Answer: " << answer << std::d::endl; + + std::cout << "---- REST test 2: 404, string "<< std::endl; + code = rest.get_json("statuss", &answer); + if (code != 0){ + //throw -1; + std::cout << "I SHOULD THROW AN EXCEPTION!!!" << std::endl; + } + + std::cout << "---- REST test 3: true, json object "<< std::endl; + JsonBox::Value json_value; + code = rest.get_json("status", &json_value); + std::cout << "JSON " << json_value["status"] << std::endl; + + answer = ""; + std::cout << "---- REST test 4: POST, string "<< std::endl; + code = rest.post_json("recipes/cassoela", &answer); + std::cout << "POST answer: " << answer << std::endl; + if (code != 0){ + //throw -1; + std::cout << "I SHOULD THROW AN EXCEPTION!!!" << std::endl; + } + + RestHelper rest2 ; + rest2.init("reallyfake",8080); + std::cout << "---- REST test 4: host not found, json object "<< std::endl; + JsonBox::Value json_value2; + code = rest2.get_json("status", &json_value2); + if (code != 0){ + //throw -1; + std::cout << "I SHOULD THROW AN EXCEPTION!!!" << std::endl; + } + #endif } @@ -120,31 +120,31 @@ public: DEBUG("getDetectorHostname(): Return NULL"); return(NULL); } - char *c = new char[name.length()+1]; - name.copy(c, name.length()); - c[name.length()] = '\0'; - DEBUG("getDetectorHostname(): Return " << c << "."); - return(c); + char *c = new char[name.length()+1]; + name.copy(c, name.length()); + c[name.length()] = '\0'; + DEBUG("getDetectorHostname(): Return " << c << "."); + return(c); } - + char *getFileName() const { string name = scan_config.fileName; - - char *c = new char[name.length()+1]; - name.copy(c, name.length()); - c[name.length()] = '\0'; - DEBUG("getFileName(): Return " << c); - return(c); + + char *c = new char[name.length()+1]; + name.copy(c, name.length()); + c[name.length()] = '\0'; + DEBUG("getFileName(): Return " << c); + return(c); } - + char *getFilePath() const { string name = scan_config.filePath; - char *c = new char[name.length()+1]; - name.copy(c, name.length()); - c[name.length()] = '\0'; - DEBUG("getFilePath(): Return " << c); - return(c); + char *c = new char[name.length()+1]; + name.copy(c, name.length()); + c[name.length()] = '\0'; + DEBUG("getFilePath(): Return " << c); + return(c); } int getDynamicRange() const { @@ -237,6 +237,11 @@ public: status = slsReceiverDefs::IDLE; } + // Temporary workaround + int setDetectorType(slsReceiverDefs::detectorType det){ + return 0; + } + private: EigerReceiverScanConfiguration scan_config; EigerReceiverInitializationConfiguration init_config; diff --git a/slsReceiverSoftware/slsReceiver/eigerReceiver/eigerReceiverDummy.cpp b/slsReceiverSoftware/slsReceiver/eigerReceiver/eigerReceiverDummy.cpp index f45c7517e..ad8139cd8 100644 --- a/slsReceiverSoftware/slsReceiver/eigerReceiver/eigerReceiverDummy.cpp +++ b/slsReceiverSoftware/slsReceiver/eigerReceiver/eigerReceiverDummy.cpp @@ -49,6 +49,8 @@ public: char *getFileName() const {return (char*)"";} char *getFilePath() const {return (char*)"";} + + int getFileIndex() const {return 0;} int getDynamicRange() const { return 0;} diff --git a/slsReceiverSoftware/slsReceiver/eigerReceiver/eigerReceiverTest.cpp b/slsReceiverSoftware/slsReceiver/eigerReceiver/eigerReceiverTest.cpp index bdfcba7a1..7eb80f690 100644 --- a/slsReceiverSoftware/slsReceiver/eigerReceiver/eigerReceiverTest.cpp +++ b/slsReceiverSoftware/slsReceiver/eigerReceiver/eigerReceiverTest.cpp @@ -29,7 +29,7 @@ int main(int argc, char *argv[]){ } delete[] c0; - cout <initialize(empty); status = receiver->getStatus(); receiver->initialize(name); diff --git a/slsReceiverSoftware/slsReceiver/slsReceiverBase.h b/slsReceiverSoftware/slsReceiver/slsReceiverBase.h index 007bf4a97..5ea2e570e 100644 --- a/slsReceiverSoftware/slsReceiver/slsReceiverBase.h +++ b/slsReceiverSoftware/slsReceiver/slsReceiverBase.h @@ -1,5 +1,6 @@ #ifndef SLSRECEIVERBASE_H #define SLSRECEIVERBASE_H + /*********************************************** * @file slsReceiverBase.h * @short base class with all the functions for a receiver, set/get parameters, start/stop etc. @@ -12,20 +13,61 @@ * @short base class with all the functions for a receiver, set/get parameters, start/stop etc. */ + +#include "sls_detector_defs.h" + class slsReceiverBase { - + /* abstract class that defines the public interface of an sls detector data receiver. + * + * Use the factory method slsReceiverBase::create() to get an instance: + * + * slsReceiverBase *receiver = slsReceiverBase::create() + * + * supported sequence of method-calls: + * + * initialize() : once and only once after create() + * + * get*() : anytime after initialize(), multiples times + * set*() : anytime after initialize(), multiple times + * + * startReceiver(): anytime after initialize(). Will fail if state already is 'running' + * + * abort(), + * stopReceiver() : anytime after initialize(). Will do nothing if state already is idle. + * + * getStatus() returns the actual state of the data receiver - running or idle. All other + * get*() and set*() methods access the local cache of configuration values only and *do not* modify the data receiver settings. + * + * Only startReceiver() does change the data receiver configuration, it does pass the whole configuration cache to the data receiver. + * + * get- and set-methods that return a char array (char *) allocate a new array at each call. The caller is responsible to free the allocated space: + * + * char *c = receiver->getFileName(); + * .... + * delete[] c; + * + * always: 1:YES 0:NO for int as bool-like arguments + * + */ public: - - /** - * constructor - */ - slsReceiverBase(){}; - - /** - * Destructor - */ - virtual ~slsReceiverBase() {}; - + + // Using Factory instead + /** + * constructor + */ + //slsReceiverBase(){}; + + /** + * factory method to create instances + */ + static slsReceiverBase *create(); + + + /** + * Destructor + */ + virtual ~slsReceiverBase() {}; + /** * Initialize the Receiver @param detectorHostName detector hostname @@ -44,8 +86,8 @@ public: /** * Returns status of receiver: idle, running or error */ - virtual slsReceiverDefs::runStatus getStatus() const = 0; - + virtual slsReceiverDefs::runStatus getStatus() const = 0; + /** * Returns File Name * caller is responsible to deallocate the returned char array. From dc6045a14c80e7faed1ea6c20aa0864fa83c706a Mon Sep 17 00:00:00 2001 From: Sala Leonardo Date: Fri, 5 Sep 2014 16:54:32 +0200 Subject: [PATCH 018/474] first factory-based version compiling, still very very preliminary --- slsReceiverSoftware/Makefile | 4 +- slsReceiverSoftware/slsReceiver/Makefile | 14 +- .../slsReceiver/UDPBaseImplementation.cpp | 2317 +++++++++++++++++ .../slsReceiver/UDPBaseImplementation.h | 811 ++++++ .../slsReceiver/UDPInterface.cpp | 43 + .../{slsReceiverBase.h => UDPInterface.h} | 48 +- slsReceiverSoftware/slsReceiver/main.cpp | 1 + .../slsReceiver/slsReceiver.cpp | 76 +- slsReceiverSoftware/slsReceiver/slsReceiver.h | 16 +- .../slsReceiver/slsReceiverTCPIPInterface.cpp | 14 +- .../slsReceiver/slsReceiverTCPIPInterface.h | 18 +- .../slsReceiver/slsReceiverUDPFunctions.cpp | 7 +- .../slsReceiver/slsReceiverUDPFunctions.h | 15 +- .../slsReceiver/slsReceiverUsers.h | 3 +- 14 files changed, 3295 insertions(+), 92 deletions(-) create mode 100644 slsReceiverSoftware/slsReceiver/UDPBaseImplementation.cpp create mode 100644 slsReceiverSoftware/slsReceiver/UDPBaseImplementation.h create mode 100644 slsReceiverSoftware/slsReceiver/UDPInterface.cpp rename slsReceiverSoftware/slsReceiver/{slsReceiverBase.h => UDPInterface.h} (93%) diff --git a/slsReceiverSoftware/Makefile b/slsReceiverSoftware/Makefile index 4aa0c3fde..8f6e00910 100644 --- a/slsReceiverSoftware/Makefile +++ b/slsReceiverSoftware/Makefile @@ -14,8 +14,10 @@ DFLAGS= -g -DDACS_INT -DSLS_RECEIVER_UDP_FUNCTIONS INCLUDES?= -I. -Iincludes -IMySocketTCP -IslsReceiver -IslsDetectorCalibration -IslsReceiver/eigerReceiver -I$(ASM) #-IslsReceiverInterface -SRC_CLNT= MySocketTCP/MySocketTCP.cpp slsReceiver/slsReceiver.cpp slsReceiver/slsReceiverUDPFunctions.cpp slsReceiver/slsReceiverTCPIPInterface.cpp slsReceiver/slsReceiverUsers.cpp +SRC_CLNT= MySocketTCP/MySocketTCP.cpp slsReceiver/slsReceiver.cpp slsReceiver/UDPInterface.cpp slsReceiver/UDPBaseImplementation.cpp slsReceiver/slsReceiverTCPIPInterface.cpp slsReceiver/slsReceiverUsers.cpp + #slsReceiverInterface/receiverInterface.cpp +#slsReceiver/slsReceiverUDPFunctions.cpp OBJS = $(SRC_CLNT:.cpp=.o) OBJS += slsReceiver/eigerReceiver.o diff --git a/slsReceiverSoftware/slsReceiver/Makefile b/slsReceiverSoftware/slsReceiver/Makefile index d5f02c2ea..b4a681c3f 100644 --- a/slsReceiverSoftware/slsReceiver/Makefile +++ b/slsReceiverSoftware/slsReceiver/Makefile @@ -13,7 +13,7 @@ LDFLAGRXR ?= -L$(LIBDIR) -lSlsReceiver -L/usr/lib64/ -lpthread LDFLAGRXR += -lm -lstdc++ -INCLUDES ?= -I ../MySocketTCP -I ../slsDetectorCalibration -I ../includes -I eigerReceiver -I . +INCLUDES ?= -I ../MySocketTCP -I ../slsDetectorCalibration -I ../includes/ -I eigerReceiver -I . SRC_CLNT = main.cpp @@ -40,19 +40,21 @@ $(DESTDIR)/sslsReceiver: lib $(DESTDIR)/slsReceiver: eigerReceiver lib + echo "AAAAAAAAAAAA" $(CXX) -o $@ $(SRC_CLNT) $(FLAGS) $(INCLUDES) $(CLAGS) $(LIBS) $(LDFLAGRXR) -fPIC $(CXX) -o $@ $(SRC_CLNT) $(FLAGS) $(INCLUDES) $(CLAGS) $(LIBS) $(LDFLAGRXR) -fPIC #$(EIGERFLAGS) ifeq ($(EIGERSLS), yes) eigerReceiver: - $(CXX) $(FLAGS) $(CFLAGS) -fPIC -c -o eigerReceiverTest.o eigerReceiver/eigerReceiverTest.cpp $(EIGERFLAGS) - $(CXX) $(FLAGS) $(CFLAGS) -fPIC -c -o eigerReceiver.o eigerReceiver/eigerReceiver.cpp $(EIGERFLAGS) - $(CXX) eigerReceiverTest.o eigerReceiver.o -o eigerReceiver/eigerReceiverTest $(EIGERFLAGS) +# $(CXX) $(FLAGS) $(CFLAGS) -fPIC -c -o eigerReceiverTest.o eigerReceiver/eigerReceiverTest.cpp $(EIGERFLAGS) +# $(CXX) $(FLAGS) $(CFLAGS) -fPIC -c -o eigerReceiver.o eigerReceiver/eigerReceiver.cpp $(EIGERFLAGS) +# $(CXX) eigerReceiverTest.o eigerReceiver.o -o eigerReceiver/eigerReceiverTest $(EIGERFLAGS) + $(CXX) $(FLAGS) $(CFLAGS) $(INCLUDES) -fPIC -c -o eigerReceiver.o eigerReceiverImplementation.cpp $(EIGERFLAGS) else ifeq ($(ROOTSLS), yes) eigerReceiver: eigerReceiver/eigerReceiverDummy.cpp echo "Compiling with root" - $(CXX) $(FLAGS) $(CFLAGS) -fPIC -c -o eigerReceiver.o eigerReceiver/eeigerReceiverDummy.cpp $(ROOTFLAGS) + $(CXX) $(FLAGS) $(CFLAGS) -fPIC -c -o eigerReceiver.o eigerReceiver/eigerReceiverDummy.cpp $(ROOTFLAGS) else eigerReceiver: eigerReceiver/eigerReceiverDummy.cpp $(CXX) $(FLAGS) $(CFLAGS) $(INCLUDES) -fPIC -c -o eigerReceiver.o eigerReceiver/eigerReceiverDummy.cpp @@ -63,6 +65,6 @@ lib: clean: rm -rf $(PROGS) *.o eigerReceiverTest $(DESTDIR)/libSlsReceiver.a $(DESTDIR)/libSlsReceiver.so core - + diff --git a/slsReceiverSoftware/slsReceiver/UDPBaseImplementation.cpp b/slsReceiverSoftware/slsReceiver/UDPBaseImplementation.cpp new file mode 100644 index 000000000..aa0aa77e1 --- /dev/null +++ b/slsReceiverSoftware/slsReceiver/UDPBaseImplementation.cpp @@ -0,0 +1,2317 @@ +#ifdef SLS_RECEIVER_UDP_FUNCTIONS +/********************************************//** + * @file UDPBaseImplementation.cpp + * @short does all the functions for a receiver, set/get parameters, start/stop etc. + ***********************************************/ + + +#include "UDPBaseImplementation.h" + +#include "moench02ModuleData.h" +#include "gotthardModuleData.h" +#include "gotthardShortModuleData.h" + + +#include // SIGINT +#include // stat +#include // socket(), bind(), listen(), accept(), shut down +#include // sock_addr_in, htonl, INADDR_ANY +#include // exit() +#include //set precision +#include //munmap + + + +#include +#include + + + +using namespace std; + + + +UDPBaseImplementation::UDPBaseImplementation(): + thread_started(0), + eth(NULL), + latestData(NULL), + guiFileName(NULL), + guiFrameNumber(0), + tengigaEnable(0){ + + for(int i=0;i /proc/sys/net/core/rmem_max")) + cout << "\nWARNING: Could not change socket receiver buffer size in file /proc/sys/net/core/rmem_max" << endl; + else if(system("echo 250000 > /proc/sys/net/core/netdev_max_backlog")) + cout << "\nWARNING: Could not change max length of input queue in file /proc/sys/net/core/netdev_max_backlog" << endl; + /** permanent setting heiner + net.core.rmem_max = 104857600 # 100MiB + net.core.netdev_max_backlog = 250000 + sysctl -p + // from the manual + sysctl -w net.core.rmem_max=16777216 + sysctl -w net.core.netdev_max_backlog=250000 + */ +} + + + +UDPBaseImplementation::~UDPBaseImplementation(){ + createListeningThreads(true); + createWriterThreads(true); + deleteMembers(); +} + + + + +void UDPBaseImplementation::deleteMembers(){ + //kill threads + if(thread_started){ + createListeningThreads(true); + createWriterThreads(true); + } + + for(int i=0;i=0) + fileIndex = i; + return getFileIndex(); +} + + +int UDPBaseImplementation::setFrameIndexNeeded(int i){ + frameIndexNeeded = i; + return frameIndexNeeded; +} + + +int UDPBaseImplementation::getEnableFileWrite() const{ + return enableFileWrite; +} + +int UDPBaseImplementation::setEnableFileWrite(int i){ + enableFileWrite=i; + return getEnableFileWrite(); +} + +int UDPBaseImplementation::getEnableOverwrite() const{ + return overwrite; +} + +int UDPBaseImplementation::setEnableOverwrite(int i){ + overwrite=i; + return getEnableOverwrite(); +} + + + + + +/*other parameters*/ + +slsReceiverDefs::runStatus UDPBaseImplementation::getStatus() const{ + return status; +} + + +void UDPBaseImplementation::initialize(const char *detectorHostName){ + if(strlen(detectorHostName)) + strcpy(detHostname,detectorHostName); +} + + +char *UDPBaseImplementation::getDetectorHostname() const{ + return (char*)detHostname; +} + +void UDPBaseImplementation::setEthernetInterface(char* c){ + strcpy(eth,c); +} + + +void UDPBaseImplementation::setUDPPortNo(int p){ + for(int i=0;i= 0) + numberOfFrames = fnum; + + return getNumberOfFrames(); +} + +int UDPBaseImplementation::getScanTag() const{ + return scanTag; +} + + +int32_t UDPBaseImplementation::setScanTag(int32_t stag){ + if(stag >= 0) + scanTag = stag; + + return getScanTag(); +} + + +int UDPBaseImplementation::getDynamicRange() const{ + return dynamicRange; +} + +int32_t UDPBaseImplementation::setDynamicRange(int32_t dr){ + cout << "Setting Dynamic Range" << endl; + + int olddr = dynamicRange; + if(dr >= 0){ + dynamicRange = dr; + + if(myDetectorType == EIGER){ + + + if(!tengigaEnable) + packetsPerFrame = EIGER_ONE_GIGA_CONSTANT * dynamicRange * EIGER_MAX_PORTS; + else + packetsPerFrame = EIGER_TEN_GIGA_CONSTANT * dynamicRange * EIGER_MAX_PORTS; + frameSize = onePacketSize * packetsPerFrame; + bufferSize = (frameSize/EIGER_MAX_PORTS) + EIGER_HEADER_LENGTH;//everything one port gets (img header plus packets) + maxPacketsPerFile = EIGER_MAX_FRAMES_PER_FILE * packetsPerFrame; + + + + if(olddr != dr){ + + //del + if(thread_started){ + createListeningThreads(true); + createWriterThreads(true); + } + for(int i=0;i=0){ + nFrameToGui = i; + setupFifoStructure(); + } + return nFrameToGui; +} + + + +int64_t UDPBaseImplementation::setAcquisitionPeriod(int64_t index){ + + if(index >= 0){ + if(index != acquisitionPeriod){ + acquisitionPeriod = index; + setupFifoStructure(); + } + } + return acquisitionPeriod; +} + + +bool UDPBaseImplementation::getDataCompression(){return dataCompression;} + +int UDPBaseImplementation::enableDataCompression(bool enable){ + cout << "Data compression "; + if(enable) + cout << "enabled" << endl; + else + cout << "disabled" << endl; +#ifdef MYROOT1 + cout << " WITH ROOT" << endl; +#else + cout << " WITHOUT ROOT" << endl; +#endif + //delete filter for the current number of threads + deleteFilter(); + + dataCompression = enable; + pthread_mutex_lock(&status_mutex); + writerthreads_mask = 0x0; + pthread_mutex_unlock(&(status_mutex)); + + createWriterThreads(true); + + if(enable) + numWriterThreads = MAX_NUM_WRITER_THREADS; + else + numWriterThreads = 1; + + if(createWriterThreads() == FAIL){ + cout << "ERROR: Could not create writer threads" << endl; + return FAIL; + } + setThreadPriorities(); + + + if(enable) + setupFilter(); + + return OK; +} + + + + + + + + + + + + +/*other functions*/ + + +void UDPBaseImplementation::deleteFilter(){ + int i; + cmSub=NULL; + + for(i=0;i(receiverdata[i], csize, sigma, sign, cmSub); + +} + + + +//LEO: it is not clear to me.. +void UDPBaseImplementation::setupFifoStructure(){ + + int64_t i; + int oldn = numJobsPerThread; + + //if every nth frame mode + if(nFrameToGui) + numJobsPerThread = nFrameToGui; + + //random nth frame mode + else{ + if(!acquisitionPeriod) + i = SAMPLE_TIME_IN_NS; + else + i = SAMPLE_TIME_IN_NS/acquisitionPeriod; + if (i > MAX_JOBS_PER_THREAD) + numJobsPerThread = MAX_JOBS_PER_THREAD; + else if (i < 1) + numJobsPerThread = 1; + else + numJobsPerThread = i; + } + + //if same, return + if(oldn == numJobsPerThread) + return; + + if(myDetectorType == EIGER) + numJobsPerThread = 1; + + //otherwise memory too much if numjobsperthread is at max = 1000 + fifosize = GOTTHARD_FIFO_SIZE; + if(myDetectorType == MOENCH) + fifosize = MOENCH_FIFO_SIZE; + else if(myDetectorType == EIGER) + fifosize = EIGER_FIFO_SIZE; + + if(fifosize % numJobsPerThread) + fifosize = (fifosize/numJobsPerThread)+1; + else + fifosize = fifosize/numJobsPerThread; + + + cout << "Number of Frames per buffer:" << numJobsPerThread << endl; + cout << "Fifo Size:" << fifosize << endl; + + /* + //for testing + numJobsPerThread = 3; fifosize = 11; + */ + + for(int i=0;iisEmpty()) + fifoFree[i]->pop(buffer[i]); + delete fifoFree[i]; + } + if(fifo[i]) delete fifo[i]; + if(mem0[i]) free(mem0[i]); + fifoFree[i] = new CircularFifo(fifosize); + fifo[i] = new CircularFifo(fifosize); + + + //allocate memory + mem0[i]=(char*)malloc((bufferSize * numJobsPerThread + HEADER_SIZE_NUM_TOT_PACKETS)*fifosize); + /** shud let the client know about this */ + if (mem0[i]==NULL){ + cout<<"++++++++++++++++++++++ COULD NOT ALLOCATE MEMORY FOR LISTENING !!!!!!!+++++++++++++++++++++" << endl; + exit(-1); + } + buffer[i]=mem0[i]; + //push the addresses into freed fifoFree and writingFifoFree + while (buffer[i]<(mem0[i]+(bufferSize * numJobsPerThread + HEADER_SIZE_NUM_TOT_PACKETS)*(fifosize-1))) { + fifoFree[i]->push(buffer[i]); + buffer[i]+=(bufferSize * numJobsPerThread + HEADER_SIZE_NUM_TOT_PACKETS); + } + } + cout << "Fifo structure(s) reconstructed" << endl; +} + + + + + + + +/** acquisition functions */ + +void UDPBaseImplementation::readFrame(char* c,char** raw, uint32_t &fnum){ + //point to gui data + if (guiData == NULL) + guiData = latestData; + + //copy data and filename + strcpy(c,guiFileName); + fnum = guiFrameNumber; + + + //could not get gui data + if(!guiDataReady){ + *raw = NULL; + } + //data ready, set guidata to receive new data + else{ + *raw = guiData; + guiData = NULL; + + pthread_mutex_lock(&dataReadyMutex); + guiDataReady = 0; + pthread_mutex_unlock(&dataReadyMutex); + if((nFrameToGui) && (writerthreads_mask)){ + /*if(nFrameToGui){*/ + //release after getting data + sem_post(&smp); + } + } +} + + + + + +void UDPBaseImplementation::copyFrameToGui(char* startbuf[], uint32_t fnum, char* buf){ + + //random read when gui not ready + if((!nFrameToGui) && (!guiData)){ + pthread_mutex_lock(&dataReadyMutex); + guiDataReady=0; + pthread_mutex_unlock(&dataReadyMutex); + } + + //random read or nth frame read, gui needs data now + else{ + /* + //nth frame read, block current process if the guireader hasnt read it yet + if(nFrameToGui) + sem_wait(&smp); +*/ + pthread_mutex_lock(&dataReadyMutex); + guiDataReady=0; + //eiger + if(startbuf != NULL){ + int offset = 0; + int size = frameSize/EIGER_MAX_PORTS; + for(int j=0;jgetErrorStatus(); + if(iret){ +#ifdef VERBOSE + cout << "Could not create UDP socket on port " << server_port[i] << " error:" << iret << endl; +#endif + return FAIL; + } + } + + return OK; +} + + + + + + + +int UDPBaseImplementation::shutDownUDPSockets(){ + for(int i=0;iShutDownSocket(); + delete udpSocket[i]; + udpSocket[i] = NULL; + } + } + return OK; +} + + + + + +int UDPBaseImplementation::createListeningThreads(bool destroy){ + int i; + void* status; + + killAllListeningThreads = 0; + + pthread_mutex_lock(&status_mutex); + listeningthreads_mask = 0x0; + pthread_mutex_unlock(&(status_mutex)); + + if(!destroy){ + + //start listening threads + cout << "Creating Listening Threads(s)"; + + currentListeningThreadIndex = -1; + + for(i = 0; i < numListeningThreads; ++i){ + sem_init(&listensmp[i],1,0); + thread_started = 0; + currentListeningThreadIndex = i; + if(pthread_create(&listening_thread[i], NULL,startListeningThread, (void*) this)){ + cout << "Could not create listening thread with index " << i << endl; + return FAIL; + } + while(!thread_started); + cout << "."; + cout << flush; + } +#ifdef VERBOSE + cout << "Listening thread(s) created successfully." << endl; +#else + cout << endl; +#endif + }else{ + cout<<"Destroying Listening Thread(s)"<initEventTree(temp, &iframe); + //resets the pedestalSubtraction array and the commonModeSubtraction + singlePhotonDet[ithr]->newDataSet(); + if(myFile[ithr]==NULL){ + cout<<"file null"<IsOpen()){ + cout<<"file not open"< DO_NOTHING){ + //close + if(sfilefd){ + fclose(sfilefd); + sfilefd = NULL; + } + //open file + if(!overwrite){ + if (NULL == (sfilefd = fopen((const char *) (savefilename), "wx"))){ + cout << "Error: Could not create new file " << savefilename << endl; + return FAIL; + } + }else if (NULL == (sfilefd = fopen((const char *) (savefilename), "w"))){ + cout << "Error: Could not create file " << savefilename << endl; + return FAIL; + } + //setting buffer + setvbuf(sfilefd,NULL,_IOFBF,BUF_SIZE); + + //printing packet losses and file names + if(!packetsCaught) + cout << savefilename << endl; + else{ + cout << savefilename + << "\tpacket loss " + << setw(4)<GetCurrentFile(); + + if(myFile[ithr]->Write()) + //->Write(tall->GetName(),TObject::kOverwrite); + cout << "Thread " << ithr <<": wrote frames to file" << endl; + else + cout << "Thread " << ithr << ": could not write frames to file" << endl; + + }else + cout << "Thread " << ithr << ": could not write frames to file: No file or No Tree" << endl; + //close file + if(myTree[ithr] && myFile[ithr]) + myFile[ithr] = myTree[ithr]->GetCurrentFile(); + if(myFile[ithr] != NULL) + myFile[ithr]->Close(); + myFile[ithr] = NULL; + myTree[ithr] = NULL; + pthread_mutex_unlock(&write_mutex); + +#endif + } +} + + + + + +int UDPBaseImplementation::startReceiver(char message[]){ + int i; + + +// #ifdef VERBOSE + cout << "Starting Receiver" << endl; +//#endif + + + //reset listening thread variables + measurementStarted = false; + //should be set to zero as its added to get next start frame indices for scans for eiger + if(!acqStarted) currframenum = 0; + startFrameIndex = 0; + + for(int i = 0; i < numListeningThreads; ++i) + totalListeningFrameCount[i] = 0; + + //udp socket + if(createUDPSockets() == FAIL){ + strcpy(message,"Could not create UDP Socket(s).\n"); + cout << endl << message << endl; + return FAIL; + } + cout << "UDP socket(s) created successfully. 1st port " << server_port[0] << endl; + + + if(setupWriter() == FAIL){ + //stop udp socket + shutDownUDPSockets(); + + sprintf(message,"Could not create file %s.\n",savefilename); + return FAIL; + } + cout << "Successfully created file(s)" << endl; + + //done to give the gui some proper name instead of always the last file name + if(dataCompression) + sprintf(savefilename, "%s/%s_fxxx_%d_xx.root", filePath,fileName,fileIndex); + + //initialize semaphore + sem_init(&smp,1,0); + + //status + pthread_mutex_lock(&status_mutex); + status = RUNNING; + for(i=0;istartListening(); + + return this_pointer; +} + + + +void* UDPBaseImplementation::startWritingThread(void* this_pointer){ + ((UDPBaseImplementation*)this_pointer)->startWriting(); + return this_pointer; +} + + + + + + +int UDPBaseImplementation::startListening(){ + int ithread = currentListeningThreadIndex; +#ifdef VERYVERBOSE + cout << "In startListening() " << endl; +#endif + + thread_started = 1; + + int i,total; + int lastpacketoffset, expected, rc, rc1,packetcount, maxBufferSize, carryonBufferSize; + uint32_t lastframeheader;// for moench to check for all the packets in last frame + char* tempchar = NULL; + int imageheader = 0; + if(myDetectorType==EIGER) + imageheader = EIGER_IMAGE_HEADER_SIZE; + + + while(1){ + //variables that need to be checked/set before each acquisition + carryonBufferSize = 0; + //if more than 1 listening thread, listen one packet at a time, else need to interleaved frame later + maxBufferSize = bufferSize * numJobsPerThread; +#ifdef VERYDEBUG + cout << " maxBufferSize:" << maxBufferSize << ",carryonBufferSize:" << carryonBufferSize << endl; +#endif + + if(tempchar) {delete [] tempchar;tempchar = NULL;} + if(myDetectorType != EIGER) + tempchar = new char[onePacketSize * ((packetsPerFrame/numListeningThreads) - 1)]; //gotthard: 1packet size, moench:39 packet size + + + while((1<pop(buffer[ithread]); +#ifdef VERYDEBUG + cout << ithread << " *** popped from fifo free" << (void*)buffer[ithread] << endl; +#endif + + + //receive + if(udpSocket[ithread] == NULL){ + rc = 0; + cout << ithread << "UDP Socket is NULL" << endl; + } + //normal listening + else if(!carryonBufferSize){ + + rc = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS, maxBufferSize); + expected = maxBufferSize; + + } + //the remaining packets from previous buffer + else{ +#ifdef VERYDEBUG + cout << ithread << " ***carry on buffer" << carryonBufferSize << endl; + cout << ithread << " framennum in temochar:"<<((((uint32_t)(*((uint32_t*)tempchar))) + & (frameIndexMask)) >> frameIndexOffset)<ReceiveDataOnly((buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS + carryonBufferSize),maxBufferSize - carryonBufferSize); + expected = maxBufferSize - carryonBufferSize; + } + +#ifdef VERYDEBUG + cout << ithread << " *** rc:" << dec << rc << ". expected:" << dec << expected << endl; +#endif + + + + + //start indices for each start of scan/acquisition - eiger does it before + if((!measurementStarted) && (rc > 0) && (!ithread)) + startFrameIndices(ithread); + + //problem in receiving or end of acquisition + if((rc < expected)||(rc <= 0)){ + stopListening(ithread,rc,packetcount,total); + continue; + } + + + + //reset + packetcount = (packetsPerFrame/numListeningThreads) * numJobsPerThread; + carryonBufferSize = 0; + + + + //check if last packet valid and calculate packet count + switch(myDetectorType){ + + case MOENCH: + lastpacketoffset = (((numJobsPerThread * packetsPerFrame - 1) * onePacketSize) + HEADER_SIZE_NUM_TOT_PACKETS); +#ifdef VERYDEBUG + cout <<"first packet:"<< ((((uint32_t)(*((uint32_t*)(buffer[ithread]+HEADER_SIZE_NUM_TOT_PACKETS))))) & (packetIndexMask)) << endl; + cout <<"first header:"<< (((((uint32_t)(*((uint32_t*)(buffer[ithread]+HEADER_SIZE_NUM_TOT_PACKETS))))) & (frameIndexMask)) >> frameIndexOffset) << endl; + cout << "last packet offset:" << lastpacketoffset << endl; + cout <<"last packet:"<< ((((uint32_t)(*((uint32_t*)(buffer[ithread]+lastpacketoffset))))) & (packetIndexMask)) << endl; + cout <<"last header:"<< (((((uint32_t)(*((uint32_t*)(buffer[ithread]+lastpacketoffset))))) & (frameIndexMask)) >> frameIndexOffset) << endl; +#endif + //moench last packet value is 0 + if( ((((uint32_t)(*((uint32_t*)(buffer[ithread]+lastpacketoffset))))) & (packetIndexMask))){ + lastframeheader = ((((uint32_t)(*((uint32_t*)(buffer[ithread]+lastpacketoffset))))) & (frameIndexMask)) >> frameIndexOffset; + carryonBufferSize += onePacketSize; + lastpacketoffset -= onePacketSize; + --packetcount; + while (lastframeheader == (((((uint32_t)(*((uint32_t*)(buffer[ithread]+lastpacketoffset))))) & (frameIndexMask)) >> frameIndexOffset)){ + carryonBufferSize += onePacketSize; + lastpacketoffset -= onePacketSize; + --packetcount; + } + memcpy(tempchar, buffer[ithread]+(lastpacketoffset+onePacketSize), carryonBufferSize); +#ifdef VERYDEBUG + cout << "tempchar header:" << (((((uint32_t)(*((uint32_t*)(tempchar))))) + & (frameIndexMask)) >> frameIndexOffset) << endl; + cout <<"tempchar packet:"<< ((((uint32_t)(*((uint32_t*)(tempchar))))) + & (packetIndexMask)) << endl; +#endif + } + break; + + case GOTTHARD: + if(shortFrame == -1){ + lastpacketoffset = (((numJobsPerThread * packetsPerFrame - 1) * onePacketSize) + HEADER_SIZE_NUM_TOT_PACKETS); +#ifdef VERYDEBUG + cout << "last packet offset:" << lastpacketoffset << endl; +#endif + + if((unsigned int)(packetsPerFrame -1) != ((((uint32_t)(*((uint32_t*)(buffer[ithread]+lastpacketoffset))))+1) & (packetIndexMask))){ + memcpy(tempchar,buffer[ithread]+lastpacketoffset, onePacketSize); +#ifdef VERYDEBUG + cout << "tempchar header:" << (((((uint32_t)(*((uint32_t*)(tempchar))))+1) + & (frameIndexMask)) >> frameIndexOffset) << endl; +#endif + carryonBufferSize = onePacketSize; + --packetcount; + } + } +#ifdef VERYDEBUG + cout << "header:" << (((((uint32_t)(*((uint32_t*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS))))+1) + & (frameIndexMask)) >> frameIndexOffset) << endl; +#endif + break; + default: + + break; + + } + + + // cout<<"*********** "<fnum)<push(buffer[ithread])); +#ifdef VERYDEBUG + if(!ithread) cout << ithread << " *** pushed into listening fifo" << endl; +#endif + } + + sem_wait(&listensmp[ithread]); + + //make sure its not exiting thread + if(killAllListeningThreads){ + cout << ithread << " good bye listening thread" << endl; + if(tempchar) {delete [] tempchar;tempchar = NULL;} + pthread_exit(NULL); + } + } + + return OK; +} + + + + + + + + + + + + + +int UDPBaseImplementation::startWriting(){ + int ithread = currentWriterThreadIndex; +#ifdef VERYVERBOSE + cout << ithread << "In startWriting()" <pop(wbuf[i]); + numpackets = (uint16_t)(*((uint16_t*)wbuf[i])); +#ifdef VERYDEBUG + cout << ithread << " numpackets:" << dec << numpackets << endl; +#endif + } + +#ifdef VERYDEBUG + cout << ithread << " numpackets:" << dec << numpackets << endl; + cout << ithread << " *** writer popped from fifo " << (void*) wbuf[0]<< endl; + cout << ithread << " *** writer popped from fifo " << (void*) wbuf[1]<< endl; +#endif + + + //last dummy packet + if(numpackets == 0xFFFF){ + stopWriting(ithread,wbuf); + continue; + } + + + + + //for progress + if(myDetectorType == EIGER){ + tempframenum = htonl(*(unsigned int*)((eiger_image_header *)((char*)(wbuf[ithread] + HEADER_SIZE_NUM_TOT_PACKETS)))->fnum); + tempframenum += (startFrameIndex-1); //eiger frame numbers start at 1, so need to -1 + }else if ((myDetectorType == GOTTHARD) && (shortFrame == -1)) + tempframenum = (((((uint32_t)(*((uint32_t*)(wbuf[ithread] + HEADER_SIZE_NUM_TOT_PACKETS))))+1)& (frameIndexMask)) >> frameIndexOffset); + else + tempframenum = ((((uint32_t)(*((uint32_t*)(wbuf[ithread] + HEADER_SIZE_NUM_TOT_PACKETS))))& (frameIndexMask)) >> frameIndexOffset); + + if(numWriterThreads == 1) + currframenum = tempframenum; + else{ + pthread_mutex_lock(&progress_mutex); + if(tempframenum > currframenum) + currframenum = tempframenum; + pthread_mutex_unlock(&progress_mutex); + } +//#ifdef VERYDEBUG + if(myDetectorType == EIGER) + cout << endl < 0){ + for(i=0;ipush(wbuf[i])); +#ifdef VERYDEBUG + cout << ithread << ":" << i+j << " fifo freed:" << (void*)wbuf[i] << endl; +#endif + } + + + } + else{ + //copy to gui + copyFrameToGui(NULL,-1,wbuf[0]+HEADER_SIZE_NUM_TOT_PACKETS); +#ifdef VERYVERBOSE + cout << ithread << " finished copying" << endl; +#endif + while(!fifoFree[0]->push(wbuf[0])); +#ifdef VERYVERBOSE + cout<<"buf freed:"<<(void*)wbuf[0]<fnum); + //gotthard has +1 for frame number and not a short frame + else if ((myDetectorType == GOTTHARD) && (shortFrame == -1)) + startFrameIndex = (((((uint32_t)(*((uint32_t*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS))))+1) + & (frameIndexMask)) >> frameIndexOffset); + else + startFrameIndex = ((((uint32_t)(*((uint32_t*)(buffer[ithread]+HEADER_SIZE_NUM_TOT_PACKETS)))) + & (frameIndexMask)) >> frameIndexOffset); + + + //start of acquisition + if(!acqStarted){ + startAcquisitionIndex=startFrameIndex; + currframenum = startAcquisitionIndex; + acqStarted = true; + cout << "startAcquisitionIndex:" << startAcquisitionIndex<push(buffer[ithread]); + exit(-1); + } + //push the last buffer into fifo + if(rc > 0){ + pc = (rc/onePacketSize); +#ifdef VERYDEBUG + cout << ithread << " *** last packetcount:" << pc << endl; +#endif + (*((uint16_t*)(buffer[ithread]))) = pc; + totalListeningFrameCount[ithread] += pc; + while(!fifo[ithread]->push(buffer[ithread])); +#ifdef VERYDEBUG + cout << ithread << " *** last lbuf1:" << (void*)buffer[ithread] << endl; +#endif + } + + + //push dummy buffer to all writer threads + for(i=0;ipop(buffer[ithread]); + (*((uint16_t*)(buffer[ithread]))) = 0xFFFF; +#ifdef VERYDEBUG + cout << ithread << " going to push in dummy buffer:" << (void*)buffer[ithread] << " with num packets:"<< (*((uint16_t*)(buffer[ithread]))) << endl; +#endif + while(!fifo[ithread]->push(buffer[ithread])); +#ifdef VERYDEBUG + cout << ithread << " pushed in dummy buffer:" << (void*)buffer[ithread] << endl; +#endif + } + + //reset mask and exit loop + pthread_mutex_lock(&status_mutex); + listeningthreads_mask^=(1< 1) + cout << "Waiting for listening to be done.. current mask:" << hex << listeningthreads_mask << endl; +#endif + while(listeningthreads_mask) + usleep(5000); +#ifdef VERYDEBUG + t = 0; + for(i=0;ipush(wbuffer[i])); +#ifdef VERYDEBUG + cout << ithread << ":" << i<< " fifo freed:" << (void*)wbuffer[i] << endl; +#endif + } + + + + //all threads need to close file, reset mask and exit loop + closeFile(ithread); + pthread_mutex_lock(&status_mutex); + writerthreads_mask^=(1< 0){ + + //for progress and packet loss calculation(new files) + if(myDetectorType == EIGER); + else if ((myDetectorType == GOTTHARD) && (shortFrame == -1)) + tempframenum = (((((uint32_t)(*((uint32_t*)(buf + HEADER_SIZE_NUM_TOT_PACKETS))))+1)& (frameIndexMask)) >> frameIndexOffset); + else + tempframenum = ((((uint32_t)(*((uint32_t*)(buf + HEADER_SIZE_NUM_TOT_PACKETS))))& (frameIndexMask)) >> frameIndexOffset); + + if(numWriterThreads == 1) + currframenum = tempframenum; + else{ + if(tempframenum > currframenum) + currframenum = tempframenum; + } +#ifdef VERYDEBUG + cout << "tempframenum:" << dec << tempframenum << " curframenum:" << currframenum << endl; +#endif + + //lock + if(numWriterThreads > 1) + pthread_mutex_lock(&write_mutex); + + + //to create new file when max reached + packetsToSave = maxPacketsPerFile - packetsInFile; + if(packetsToSave > numpackets) + packetsToSave = numpackets; +/**next time offset is still plus header length*/ + fwrite(buf+offset, 1, packetsToSave * onePacketSize, sfilefd); + packetsInFile += packetsToSave; + packetsCaught += packetsToSave; + totalPacketsCaught += packetsToSave; + + + //new file + if(packetsInFile >= maxPacketsPerFile){ + //for packet loss + lastpacket = (((packetsToSave - 1) * onePacketSize) + offset); + if(myDetectorType == EIGER); + else if ((myDetectorType == GOTTHARD) && (shortFrame == -1)) + tempframenum = (((((uint32_t)(*((uint32_t*)(buf + lastpacket))))+1)& (frameIndexMask)) >> frameIndexOffset); + else + tempframenum = ((((uint32_t)(*((uint32_t*)(buf + lastpacket))))& (frameIndexMask)) >> frameIndexOffset); + + if(numWriterThreads == 1) + currframenum = tempframenum; + else{ + if(tempframenum > currframenum) + currframenum = tempframenum; + } +#ifdef VERYDEBUG + cout << "tempframenum:" << dec << tempframenum << " curframenum:" << currframenum << endl; +#endif + //create + createNewFile(); + } + + //unlock + if(numWriterThreads > 1) + pthread_mutex_unlock(&write_mutex); + + + offset += (packetsToSave * onePacketSize); + numpackets -= packetsToSave; + } + + } + else{ + if(numWriterThreads > 1) + pthread_mutex_lock(&write_mutex); + packetsInFile += numpackets; + packetsCaught += numpackets; + totalPacketsCaught += numpackets; + if(numWriterThreads > 1) + pthread_mutex_unlock(&write_mutex); + } +} + + + + + + + + + + + + + + +void UDPBaseImplementation::handleDataCompression(int ithread, char* wbuffer[], int &npackets, char* data, int xmax, int ymax, int &nf){ + +#if defined(MYROOT1) && defined(ALLFILE_DEBUG) + writeToFile_withoutCompression(wbuf[0], numpackets,currframenum); +#endif + + eventType thisEvent = PEDESTAL; + int ndata; + char* buff = 0; + data = wbuffer[0]+ HEADER_SIZE_NUM_TOT_PACKETS; + int remainingsize = npackets * onePacketSize; + int np; + int once = 0; + double tot, tl, tr, bl, br; + int xmin = 1, ymin = 1, ix, iy; + + + while(buff = receiverdata[ithread]->findNextFrame(data,ndata,remainingsize)){ + np = ndata/onePacketSize; + + //cout<<"buff framnum:"<> frameIndexOffset)<newFrame(); + + //only for moench + if(commonModeSubtractionEnable){ + for(ix = xmin - 1; ix < xmax+1; ix++){ + for(iy = ymin - 1; iy < ymax+1; iy++){ + thisEvent = singlePhotonDet[ithread]->getEventType(buff, ix, iy, 0); + } + } + } + + + for(ix = xmin - 1; ix < xmax+1; ix++) + for(iy = ymin - 1; iy < ymax+1; iy++){ + thisEvent=singlePhotonDet[ithread]->getEventType(buff, ix, iy, commonModeSubtractionEnable); + if (nf>1000) { + tot=0; + tl=0; + tr=0; + bl=0; + br=0; + if (thisEvent==PHOTON_MAX) { + receiverdata[ithread]->getFrameNumber(buff); + //iFrame=receiverdata[ithread]->getFrameNumber(buff); +#ifdef MYROOT1 + myTree[ithread]->Fill(); + //cout << "Fill in event: frmNr: " << iFrame << " ix " << ix << " iy " << iy << " type " << thisEvent << endl; +#else + pthread_mutex_lock(&write_mutex); + if((enableFileWrite) && (sfilefd)) + singlePhotonDet[ithread]->writeCluster(sfilefd); + pthread_mutex_unlock(&write_mutex); +#endif + } + } + } + + nf++; +#ifndef ALLFILE + pthread_mutex_lock(&progress_mutex); + packetsInFile += packetsPerFrame; + packetsCaught += packetsPerFrame; + totalPacketsCaught += packetsPerFrame; + if(packetsInFile >= maxPacketsPerFile) + createNewFile(); + pthread_mutex_unlock(&progress_mutex); + +#endif + if(!once){ + copyFrameToGui(NULL,-1,buff); + once = 1; + } + } + + remainingsize -= ((buff + ndata) - data); + data = buff + ndata; + if(data > (wbuffer[0] + HEADER_SIZE_NUM_TOT_PACKETS + npackets * onePacketSize) ) + cout <<" **************ERROR SHOULD NOT COME HERE, Error 142536!"<push(wbuffer[0])); +#ifdef VERYVERBOSE + cout<<"buf freed:"<<(void*)wbuffer[0]<= 0){ + + tengigaEnable = enable; + + if(myDetectorType == EIGER){ + + if(!tengigaEnable){ + packetsPerFrame = EIGER_ONE_GIGA_CONSTANT * dynamicRange * EIGER_MAX_PORTS; + onePacketSize = EIGER_ONE_GIGA_ONE_PACKET_SIZE; + maxPacketsPerFile = EIGER_MAX_FRAMES_PER_FILE * packetsPerFrame; + }else{ + packetsPerFrame = EIGER_TEN_GIGA_CONSTANT * dynamicRange * EIGER_MAX_PORTS; + onePacketSize = EIGER_TEN_GIGA_ONE_PACKET_SIZE; + maxPacketsPerFile = EIGER_MAX_FRAMES_PER_FILE * packetsPerFrame*4; + } + frameSize = onePacketSize * packetsPerFrame; + bufferSize = (frameSize/EIGER_MAX_PORTS) + EIGER_HEADER_LENGTH;//everything one port gets (img header plus packets) + //maxPacketsPerFile = EIGER_MAX_FRAMES_PER_FILE * packetsPerFrame; + + + cout<<"packetsPerFrame:"< +#include +#endif + + +#include +#include +#include +#include + + +/** + * @short does all the functions for a receiver, set/get parameters, start/stop etc. + */ + +class UDPBaseImplementation : private virtual slsReceiverDefs, public UDPInterface { + + public: + /** + * Constructor + */ + UDPBaseImplementation(); + + /** + * Destructor + */ + virtual ~UDPBaseImplementation(); + + + + /** + * delete and free member parameters + */ + void deleteMembers(); + + /** + * initialize member parameters + */ + void initializeMembers(); + + /** + * Set receiver type + * @param det detector type + * Returns success or FAIL + */ + int setDetectorType(detectorType det); + + + //Frame indices and numbers caught + /** + * Returns current Frame Index Caught for an entire acquisition (including all scans) + */ + uint32_t getAcquisitionIndex(); + + /** + * Returns if acquisition started + */ + bool getAcquistionStarted(); + + /** + * Returns Frames Caught for each real time acquisition (eg. for each scan) + */ + int getFramesCaught(); + + /** + * Returns Total Frames Caught for an entire acquisition (including all scans) + */ + int getTotalFramesCaught(); + + /** + * Returns the frame index at start of each real time acquisition (eg. for each scan) + */ + uint32_t getStartFrameIndex(); + + /** + * Returns current Frame Index for each real time acquisition (eg. for each scan) + */ + uint32_t getFrameIndex(); + + /** + * Returns if measurement started + */ + bool getMeasurementStarted(); + + /** + * Resets the Total Frames Caught + * This is how the receiver differentiates between entire acquisitions + * Returns 0 + */ + void resetTotalFramesCaught(); + + + + + //file parameters + /** + * Returns File Path + */ + char* getFilePath() const; + + /** + * Set File Path + * @param c file path + */ + char* setFilePath(const char c[]); + + /** + * Returns File Name + */ + char* getFileName() const; + + /** + * Set File Name (without frame index, file index and extension) + * @param c file name + */ + char* setFileName(const char c[]); + + /** + * Returns File Index + */ + int getFileIndex(); + + /** + * Set File Index + * @param i file index + */ + int setFileIndex(int i); + + /** + * Set Frame Index Needed + * @param i frame index needed + */ + int setFrameIndexNeeded(int i); + + /** + * Set enable file write + * @param i file write enable + * Returns file write enable + */ + int setEnableFileWrite(int i); + + /** + * Enable/disable overwrite + * @param i enable + * Returns enable over write + */ + int setEnableOverwrite(int i); + + /** + * Returns file write enable + * 1: YES 0: NO + */ + int getEnableFileWrite() const; + + /** + * Returns file over write enable + * 1: YES 0: NO + */ + int getEnableOverwrite() const; + +//other parameters + + /** + * abort acquisition with minimum damage: close open files, cleanup. + * does nothing if state already is 'idle' + */ + void abort() {}; + + /** + * Returns status of receiver: idle, running or error + */ + runStatus getStatus() const; + + /** + * Set detector hostname + * @param c hostname + */ + void initialize(const char *detectorHostName); + + /* Returns detector hostname + /returns hostname + * caller needs to deallocate the returned char array. + * if uninitialized, it must return NULL + */ + char *getDetectorHostname() const; + + /** + * Set Ethernet Interface or IP to listen to + */ + void setEthernetInterface(char* c); + + /** + * Set UDP Port Number + */ + void setUDPPortNo(int p); + + /* + * Returns number of frames to receive + * This is the number of frames to expect to receiver from the detector. + * The data receiver will change from running to idle when it got this number of frames + */ + int getNumberOfFrames() const; + + /** + * set frame number if a positive number + */ + int32_t setNumberOfFrames(int32_t fnum); + + /** + * Returns scan tag + */ + int getScanTag() const; + + /** + * set scan tag if its is a positive number + */ + int32_t setScanTag(int32_t stag); + + /** + * Returns the number of bits per pixel + */ + int getDynamicRange() const; + + /** + * set dynamic range if its is a positive number + */ + int32_t setDynamicRange(int32_t dr); + + /** + * Set short frame + * @param i if shortframe i=1 + */ + int setShortFrame(int i); + + /** + * Set the variable to send every nth frame to gui + * or if 0,send frame only upon gui request + */ + int setNFrameToGui(int i); + + /** set acquisition period if a positive number + */ + int64_t setAcquisitionPeriod(int64_t index); + + /** get data compression, by saving only hits + */ + bool getDataCompression(); + + /** enabl data compression, by saving only hits + /returns if failed + */ + int enableDataCompression(bool enable); + + /** + * enable 10Gbe + @param enable 1 for 10Gbe or 0 for 1 Gbe, -1 to read out + \returns enable for 10Gbe + */ + int enableTenGiga(int enable = -1); + + + +//other functions + + /** + * Returns the buffer-current frame read by receiver + * @param c pointer to current file name + * @param raw address of pointer, pointing to current frame to send to gui + * @param fnum frame number for eiger as it is not in the packet + */ + void readFrame(char* c,char** raw, uint32_t &fnum); + + /** + * Closes all files + * @param ithr thread index + */ + void closeFile(int ithr = -1); + + /** + * Starts Receiver - starts to listen for packets + * @param message is the error message if there is an error + * Returns success + */ + int startReceiver(char message[]); + + /** + * Stops Receiver - stops listening for packets + * Returns success + */ + int stopReceiver(); + + /** set status to transmitting and + * when fifo is empty later, sets status to run_finished + */ + void startReadout(); + + /** + * shuts down the udp sockets + * \returns if success or fail + */ + int shutDownUDPSockets(); + +private: + + /* + void not_implemented(string method_name){ + std::cout << "[WARNING] Method " << method_name << " not implemented!" << std::endl; + }; + */ + /** + * Deletes all the filter objects for single photon data + */ + void deleteFilter(); + + /** + * Constructs the filter for single photon data + */ + void setupFilter(); + + /** + * set up fifo according to the new numjobsperthread + */ + void setupFifoStructure (); + + /** + * Copy frames to gui + * uses semaphore for nth frame mode + */ + void copyFrameToGui(char* startbuf[], uint32_t fnum=-1, char* buf=NULL); + + /** + * creates udp sockets + * \returns if success or fail + */ + int createUDPSockets(); + + /** + * create listening thread + * @param destroy is true to kill all threads and start again + */ + int createListeningThreads(bool destroy = false); + + /** + * create writer threads + * @param destroy is true to kill all threads and start again + */ + int createWriterThreads(bool destroy = false); + + /** + * set thread priorities + */ + void setThreadPriorities(); + + /** + * initializes variables and creates the first file + * also does the startAcquisitionCallBack + * \returns FAIL or OK + */ + int setupWriter(); + + /** + * Creates new tree and file for compression + * @param ithr thread number + * @param iframe frame number + *\returns OK for succces or FAIL for failure + */ + int createCompressionFile(int ithr, int iframe); + + /** + * Creates new file + *\returns OK for succces or FAIL for failure + */ + int createNewFile(); + + /** + * Static function - Thread started which listens to packets. + * Called by startReceiver() + * @param this_pointer pointer to this object + */ + static void* startListeningThread(void *this_pointer); + + /** + * Static function - Thread started which writes packets to file. + * Called by startReceiver() + * @param this_pointer pointer to this object + */ + static void* startWritingThread(void *this_pointer); + + /** + * Thread started which listens to packets. + * Called by startReceiver() + * + */ + int startListening(); + + /** + * Thread started which writes packets to file. + * Called by startReceiver() + * + */ + int startWriting(); + + /** + * Writing to file without compression + * @param buf is the address of buffer popped out of fifo + * @param numpackets is the number of packets + * @param framenum current frame number + */ + void writeToFile_withoutCompression(char* buf,int numpackets, uint32_t framenum); + + /** + * Its called for the first packet of a scan or acquistion + * Sets the startframeindices and the variables to know if acquisition started + * @param ithread listening thread number + */ + void startFrameIndices(int ithread); + + /** + * This is called when udp socket is shut down + * It pops ffff instead of packet number into fifo + * to inform writers about the end of listening session + * @param ithread listening thread number + * @param rc number of bytes received + * @param pc packet count + * @param t total packets listened to + */ + void stopListening(int ithread, int rc, int &pc, int &t); + + /** + * When acquisition is over, this is called + * @param ithread listening thread number + * @param wbuffer writer buffer + */ + void stopWriting(int ithread, char* wbuffer[]); + + + /** + * data compression for each fifo output + * @param ithread listening thread number + * @param wbuffer writer buffer + * @param npackets number of packets from the fifo + * @param data pointer to the next packet start + * @param xmax max pixels in x direction + * @param ymax max pixels in y direction + * @param nf nf + */ + void handleDataCompression(int ithread, char* wbuffer[], int &npackets, char* data, int xmax, int ymax, int &nf); + + + /** structure of an eiger image header*/ + typedef struct + { + unsigned char header_before[20]; + unsigned char fnum[4]; + unsigned char header_after[24]; + } eiger_image_header; + + + /** structure of an eiger image header*/ + typedef struct + { + unsigned char num1[4]; + unsigned char num2[4]; + } eiger_packet_header; + + /** max number of listening threads */ + const static int MAX_NUM_LISTENING_THREADS = EIGER_MAX_PORTS; + + /** max number of writer threads */ + const static int MAX_NUM_WRITER_THREADS = 15; + + /** detector type */ + detectorType myDetectorType; + + /** detector hostname */ + char detHostname[MAX_STR_LENGTH]; + + /** status of receiver */ + runStatus status; + + /** UDP Socket between Receiver and Detector */ + genericSocket* udpSocket[MAX_NUM_LISTENING_THREADS]; + + /** Server UDP Port*/ + int server_port[MAX_NUM_LISTENING_THREADS]; + + /** ethernet interface or IP to listen to */ + char *eth; + + /** max packets per file **/ + int maxPacketsPerFile; + + /** File write enable */ + int enableFileWrite; + + /** File over write enable */ + int overwrite; + + /** Complete File name */ + char savefilename[MAX_STR_LENGTH]; + + /** File Name without frame index, file index and extension*/ + char fileName[MAX_STR_LENGTH]; + + /** File Path */ + char filePath[MAX_STR_LENGTH]; + + /** File Index */ + int fileIndex; + + /** scan tag */ + int scanTag; + + /** if frame index required in file name */ + int frameIndexNeeded; + + /* Acquisition started */ + bool acqStarted; + + /* Measurement started */ + bool measurementStarted; + + /** Frame index at start of each real time acquisition (eg. for each scan) */ + uint32_t startFrameIndex; + + /** Actual current frame index of each time acquisition (eg. for each scan) */ + uint32_t frameIndex; + + /** Frames Caught for each real time acquisition (eg. for each scan) */ + int packetsCaught; + + /** Total packets caught for an entire acquisition (including all scans) */ + int totalPacketsCaught; + + /** Pckets currently in current file, starts new file when it reaches max */ + int packetsInFile; + + /** Frame index at start of an entire acquisition (including all scans) */ + uint32_t startAcquisitionIndex; + + /** Actual current frame index of an entire acquisition (including all scans) */ + uint32_t acquisitionIndex; + + /** number of packets per frame*/ + int packetsPerFrame; + + /** frame index mask */ + uint32_t frameIndexMask; + + /** packet index mask */ + uint32_t packetIndexMask; + + /** frame index offset */ + int frameIndexOffset; + + /** acquisition period */ + int64_t acquisitionPeriod; + + /** frame number */ + int32_t numberOfFrames; + + /** dynamic range */ + int dynamicRange; + + /** short frames */ + int shortFrame; + + /** current frame number */ + uint32_t currframenum; + + /** Previous Frame number from buffer */ + uint32_t prevframenum; + + /** size of one frame */ + int frameSize; + + /** buffer size. different from framesize as we wait for one packet instead of frame for eiger */ + int bufferSize; + + /** oen buffer size */ + int onePacketSize; + + /** latest data */ + char* latestData; + + /** gui data ready */ + int guiDataReady; + + /** points to the data to send to gui */ + char* guiData; + + /** points to the filename to send to gui */ + char* guiFileName; + + /** temporary number for eiger frame number as its not included in the packet */ + uint32_t guiFrameNumber; + + /** send every nth frame to gui or only upon gui request*/ + int nFrameToGui; + + /** fifo size */ + unsigned int fifosize; + + /** number of jobs per thread for data compression */ + int numJobsPerThread; + + /** datacompression - save only hits */ + bool dataCompression; + + /** memory allocated for the buffer */ + char *mem0[MAX_NUM_LISTENING_THREADS]; + + /** circular fifo to store addresses of data read */ + CircularFifo* fifo[MAX_NUM_LISTENING_THREADS]; + + /** circular fifo to store addresses of data already written and ready to be resued*/ + CircularFifo* fifoFree[MAX_NUM_LISTENING_THREADS]; + + /** Receiver buffer */ + char *buffer[MAX_NUM_LISTENING_THREADS]; + + /** number of writer threads */ + int numListeningThreads; + + /** number of writer threads */ + int numWriterThreads; + + /** to know if listening and writer threads created properly */ + int thread_started; + + /** current listening thread index*/ + int currentListeningThreadIndex; + + /** current writer thread index*/ + int currentWriterThreadIndex; + + /** thread listening to packets */ + pthread_t listening_thread[MAX_NUM_LISTENING_THREADS]; + + /** thread writing packets */ + pthread_t writing_thread[MAX_NUM_WRITER_THREADS]; + + /** total frame count the listening thread has listened to */ + int totalListeningFrameCount[MAX_NUM_LISTENING_THREADS]; + + /** mask showing which listening threads are running */ + volatile uint32_t listeningthreads_mask; + + /** mask showing which writer threads are running */ + volatile uint32_t writerthreads_mask; + + /** mask showing which threads have created files*/ + volatile uint32_t createfile_mask; + + /** OK if file created was successful */ + int ret_createfile; + + /** variable used to self terminate threads waiting for semaphores */ + int killAllListeningThreads; + + /** variable used to self terminate threads waiting for semaphores */ + int killAllWritingThreads; + + /** 10Gbe enable*/ + int tengigaEnable; + + + + +//semaphores + /** semaphore to synchronize writer and guireader threads */ + sem_t smp; + /** semaphore to synchronize listener threads */ + sem_t listensmp[MAX_NUM_LISTENING_THREADS]; + /** semaphore to synchronize writer threads */ + sem_t writersmp[MAX_NUM_WRITER_THREADS]; + + +//mutex + /** guiDataReady mutex */ + pthread_mutex_t dataReadyMutex; + + /** mutex for status */ + pthread_mutex_t status_mutex; + + /** mutex for progress variable currframenum */ + pthread_mutex_t progress_mutex; + + /** mutex for writing data to file */ + pthread_mutex_t write_mutex; + + /** File Descriptor */ + FILE *sfilefd; + + //filter + singlePhotonDetector *singlePhotonDet[MAX_NUM_WRITER_THREADS]; + slsReceiverData *receiverdata[MAX_NUM_WRITER_THREADS]; + moenchCommonMode *cmSub; + bool commonModeSubtractionEnable; + +#ifdef MYROOT1 + /** Tree where the hits are stored */ + TTree *myTree[MAX_NUM_WRITER_THREADS]; + + /** File where the tree is saved */ + TFile *myFile[MAX_NUM_WRITER_THREADS]; +#endif + + + + /** + callback arguments are + filepath + filename + fileindex + data size + + return value is + 0 callback takes care of open,close,write file + 1 callback writes file, we have to open, close it + 2 we open, close, write file, callback does not do anything + + */ + int (*startAcquisitionCallBack)(char*, char*,int, int, void*); + void *pStartAcquisition; + + /** + args to acquisition finished callback + total frames caught + + */ + void (*acquisitionFinishedCallBack)(int, void*); + void *pAcquisitionFinished; + + + /** + args to raw data ready callback are + framenum + datapointer + datasize in bytes + file descriptor + guidatapointer (NULL, no data required) + */ + void (*rawDataReadyCallBack)(int, char*, int, FILE*, char*, void*); + void *pRawDataReady; + + /** The action which decides what the user and default responsibilites to save data are + * 0 raw data ready callback takes care of open,close,write file + * 1 callback writes file, we have to open, close it + * 2 we open, close, write file, callback does not do anything */ + int cbAction; + + +public: + + + /** + callback arguments are + filepath + filename + fileindex + datasize + + return value is + 0 callback takes care of open,close,wrie file + 1 callback writes file, we have to open, close it + 2 we open, close, write file, callback does not do anything + */ + void registerCallBackStartAcquisition(int (*func)(char*, char*,int, int, void*),void *arg){startAcquisitionCallBack=func; pStartAcquisition=arg;}; + + /** + callback argument is + toatal frames caught + */ + void registerCallBackAcquisitionFinished(void (*func)(int, void*),void *arg){acquisitionFinishedCallBack=func; pAcquisitionFinished=arg;}; + + /** + args to raw data ready callback are + framenum + datapointer + datasize in bytes + file descriptor + guidatapointer (NULL, no data required) + */ + void registerCallBackRawDataReady(void (*func)(int, char*, int, FILE*, char*, void*),void *arg){rawDataReadyCallBack=func; pRawDataReady=arg;}; +}; + + +#endif + +//#endif diff --git a/slsReceiverSoftware/slsReceiver/UDPInterface.cpp b/slsReceiverSoftware/slsReceiver/UDPInterface.cpp new file mode 100644 index 000000000..d53166f9e --- /dev/null +++ b/slsReceiverSoftware/slsReceiver/UDPInterface.cpp @@ -0,0 +1,43 @@ +//#ifdef SLS_RECEIVER_UDP_FUNCTIONS +/********************************************//** + * @file slsReceiverUDPFunctions.cpp + * @short does all the functions for a receiver, set/get parameters, start/stop etc. + ***********************************************/ + + + + +#include // SIGINT +#include // stat +#include // socket(), bind(), listen(), accept(), shut down +#include // sock_addr_in, htonl, INADDR_ANY +#include // exit() +#include //set precision +#include //munmap + +#include +#include +using namespace std; + +#include "UDPInterface.h" +#include "UDPBaseImplementation.h" + +#include "moench02ModuleData.h" +#include "gotthardModuleData.h" +#include "gotthardShortModuleData.h" + + +using namespace std; + +UDPInterface * UDPInterface::create(string receiver_type){ + + if (receiver_type == "standard") + return new UDPBaseImplementation(); + else{ + cout << "[ERROR] UDP interface not supported, using standard implementation" << endl; + return new UDPBaseImplementation(); + } +} + + +//#endif diff --git a/slsReceiverSoftware/slsReceiver/slsReceiverBase.h b/slsReceiverSoftware/slsReceiver/UDPInterface.h similarity index 93% rename from slsReceiverSoftware/slsReceiver/slsReceiverBase.h rename to slsReceiverSoftware/slsReceiver/UDPInterface.h index 007bf4a97..74f471ae0 100644 --- a/slsReceiverSoftware/slsReceiver/slsReceiverBase.h +++ b/slsReceiverSoftware/slsReceiver/UDPInterface.h @@ -1,7 +1,7 @@ -#ifndef SLSRECEIVERBASE_H -#define SLSRECEIVERBASE_H +#ifndef UDPINTERFACE_H +#define UDPINTERFACE_H /*********************************************** - * @file slsReceiverBase.h + * @file UDPInterface.h * @short base class with all the functions for a receiver, set/get parameters, start/stop etc. ***********************************************/ /** @@ -12,19 +12,35 @@ * @short base class with all the functions for a receiver, set/get parameters, start/stop etc. */ -class slsReceiverBase { +#include "sls_receiver_defs.h" +#include "receiver_defs.h" +#include "MySocketTCP.h" -public: +/* +void print_not_implemented(string method_name){ + std::cout << "[WARNING] Method " << method_name << " not implemented!" << std::endl; +} +*/ - /** - * constructor - */ - slsReceiverBase(){}; - - /** - * Destructor - */ - virtual ~slsReceiverBase() {}; +class UDPInterface { + + public: + + /** + * constructor + */ + //UDPInterface(){}; + + /** + * Destructor + */ + virtual ~UDPInterface() {}; + + /** + * Factory create method + */ + static UDPInterface *create(string receiver_type = "standard"); + /** * Initialize the Receiver @@ -32,7 +48,7 @@ public: * you can call this function only once. You must call it before you call startReceiver() for the first time. */ virtual void initialize(const char *detectorHostName) = 0; - + /* Returns detector hostname /returns hostname @@ -44,7 +60,7 @@ public: /** * Returns status of receiver: idle, running or error */ - virtual slsReceiverDefs::runStatus getStatus() const = 0; + virtual slsReceiverDefs::runStatus getStatus() const = 0; /** * Returns File Name diff --git a/slsReceiverSoftware/slsReceiver/main.cpp b/slsReceiverSoftware/slsReceiver/main.cpp index 3513a26c7..87d947a7d 100644 --- a/slsReceiverSoftware/slsReceiver/main.cpp +++ b/slsReceiverSoftware/slsReceiver/main.cpp @@ -75,6 +75,7 @@ int main(int argc, char *argv[]) { //start tcp server thread if(user->start() == slsReceiverDefs::OK){ + cout << "DONE!" << endl; string str; cin>>str; //wait and look for an exit keyword diff --git a/slsReceiverSoftware/slsReceiver/slsReceiver.cpp b/slsReceiverSoftware/slsReceiver/slsReceiver.cpp index cd5ab551d..45359d02f 100644 --- a/slsReceiverSoftware/slsReceiver/slsReceiver.cpp +++ b/slsReceiverSoftware/slsReceiver/slsReceiver.cpp @@ -10,24 +10,26 @@ #include #include "slsReceiver.h" -#include "slsReceiverUDPFunctions.h" -#include "eigerReceiver.h" +//#include "slsReceiverUDPFunctions.h" +//#include "eigerReceiver.h" + +#include "UDPInterface.h" +//#include "UDPBaseImplementation.h" + + +#include "utilities.h" using namespace std; slsReceiver::slsReceiver(int argc, char *argv[], int &success){ + //creating base receiver - cout << "SLS Receiver" << endl; - receiverBase = new slsReceiverUDPFunctions(); int tcpip_port_no=-1; - - ifstream infile; string sLine,sargname; int iline = 0; - success=OK; string fname = ""; @@ -38,34 +40,34 @@ slsReceiver::slsReceiver(int argc, char *argv[], int &success){ if(iarg+1==argc){ cout << "no config file name given. Exiting." << endl; success=FAIL; - }else + } + else fname.assign(argv[iarg+1]); } } if((!fname.empty()) && (success == OK)){ -#ifdef VERBOSE - std::cout<< "config file name "<< fname << std::endl; -#endif + + VERBOSE_PRINT("config file name " + fname ); + infile.open(fname.c_str(), ios_base::in); if (infile.is_open()) { while(infile.good()){ getline(infile,sLine); iline++; -#ifdef VERBOSE - cout << sLine << endl; -#endif + + VERBOSE_PRINT(sLine); + if(sLine.find('#')!=string::npos){ -#ifdef VERBOSE - cout << "Line is a comment " << endl; -#endif + VERBOSE_PRINT( "Line is a comment "); continue; - }else if(sLine.length()<2){ -#ifdef VERBOSE - cout << "Empty line " << endl; -#endif + } + else if(sLine.length()<2){ + VERBOSE_PRINT("Empty line "); continue; - }else{ + } + else{ istringstream sstr(sLine); + //parameter name if(sstr.good()) sstr >> sargname; @@ -85,14 +87,13 @@ slsReceiver::slsReceiver(int argc, char *argv[], int &success){ } } infile.close(); - }else { + } + else { cout << "Error opening configuration file " << fname << endl; success = FAIL; } -#ifdef VERBOSE - cout << "Read configuration file of " << iline << " lines" << endl; -#endif + VERBOSE_PRINT("Read configuration file of " + iline + " lines"); } @@ -131,16 +132,16 @@ slsReceiver::slsReceiver(int argc, char *argv[], int &success){ } - if (success==OK) - tcpipInterface = new slsReceiverTCPIPInterface(success,receiverBase, tcpip_port_no); - //tcp ip interface - - - + if (success==OK){ + cout << "SLS Receiver" << endl; + udp_interface = UDPInterface::create("stasndard"); + tcpipInterface = new slsReceiverTCPIPInterface(success, udp_interface, tcpip_port_no); + //tcp ip interface + } } -slsReceiver::~slsReceiver() {if(receiverBase) delete receiverBase; if(tcpipInterface) delete tcpipInterface;} +slsReceiver::~slsReceiver() {if(udp_interface) delete udp_interface; if(tcpipInterface) delete tcpipInterface;} int slsReceiver::start() { @@ -158,7 +159,6 @@ void slsReceiver::closeFile(int p) { } - int64_t slsReceiver::getReceiverVersion(){ tcpipInterface->getReceiverVersion(); } @@ -166,20 +166,20 @@ int64_t slsReceiver::getReceiverVersion(){ void slsReceiver::registerCallBackStartAcquisition(int (*func)(char*, char*,int, int, void*),void *arg){ //tcpipInterface - receiverBase->registerCallBackStartAcquisition(func,arg); + udp_interface->registerCallBackStartAcquisition(func,arg); } void slsReceiver::registerCallBackAcquisitionFinished(void (*func)(int, void*),void *arg){ //tcpipInterface - receiverBase->registerCallBackAcquisitionFinished(func,arg); + udp_interface->registerCallBackAcquisitionFinished(func,arg); } void slsReceiver::registerCallBackRawDataReady(void (*func)(int, char*, int, FILE*, char*, void*),void *arg){ - //tcpipInterface - receiverBase->registerCallBackRawDataReady(func,arg); + //tcpipInterface + udp_interface->registerCallBackRawDataReady(func,arg); } diff --git a/slsReceiverSoftware/slsReceiver/slsReceiver.h b/slsReceiverSoftware/slsReceiver/slsReceiver.h index 1ab8c764a..899dabe8d 100644 --- a/slsReceiverSoftware/slsReceiver/slsReceiver.h +++ b/slsReceiverSoftware/slsReceiver/slsReceiver.h @@ -7,8 +7,12 @@ #include "slsReceiverTCPIPInterface.h" -#include "slsReceiverBase.h" +#include "UDPInterface.h" +#include "UDPBaseImplementation.h" +#include "sls_receiver_defs.h" +#include "receiver_defs.h" +#include "MySocketTCP.h" @@ -17,8 +21,8 @@ */ class slsReceiver : private virtual slsReceiverDefs { - -public: + + public: /** * Constructor * creates the tcp interface and the udp class @@ -80,9 +84,9 @@ public: void registerCallBackRawDataReady(void (*func)(int, char*, int, FILE*, char*, void*),void *arg); -private: - slsReceiverTCPIPInterface* tcpipInterface; - slsReceiverBase* receiverBase; + private: + slsReceiverTCPIPInterface* tcpipInterface; + UDPInterface* udp_interface; }; diff --git a/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.cpp b/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.cpp index cc143efc4..ea59d4bce 100644 --- a/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.cpp +++ b/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.cpp @@ -4,7 +4,7 @@ ***********************************************/ #include "slsReceiverTCPIPInterface.h" -#include "slsReceiverBase.h" +#include "UDPInterface.h" #include "gitInfoReceiver.h" #include "slsReceiverUsers.h" #include "slsReceiver.h" @@ -28,7 +28,7 @@ slsReceiverTCPIPInterface::~slsReceiverTCPIPInterface() { } -slsReceiverTCPIPInterface::slsReceiverTCPIPInterface(int &success, slsReceiverBase* rbase, int pn): +slsReceiverTCPIPInterface::slsReceiverTCPIPInterface(int &success, UDPInterface* rbase, int pn): myDetectorType(GOTTHARD), receiverBase(rbase), ret(OK), @@ -124,9 +124,9 @@ int slsReceiverTCPIPInterface::start(){ cout << "Could not create TCP Server thread" << endl; return FAIL; } -#ifdef VERBOSE + //#ifdef VERBOSE cout << "TCP Server thread created successfully." << endl; -#endif + //#endif return OK; } @@ -503,7 +503,7 @@ int slsReceiverTCPIPInterface::set_file_dir() { - +// LEO: do we need it in the base class? int slsReceiverTCPIPInterface::set_file_index() { ret=OK; int retval=-1; @@ -608,7 +608,7 @@ int slsReceiverTCPIPInterface::set_frame_index() { - +//LEO: is the client that commands the setup, or you just need the args? int slsReceiverTCPIPInterface::setup_udp(){ ret=OK; strcpy(mess,"could not set up udp connection"); @@ -1773,7 +1773,7 @@ int slsReceiverTCPIPInterface::set_detector_hostname() { - +//LEO: why the receiver should set the dynamic range? int slsReceiverTCPIPInterface::set_dynamic_range() { ret=OK; int retval=-1; diff --git a/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.h b/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.h index 423d0949a..adff81697 100644 --- a/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.h +++ b/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.h @@ -9,7 +9,7 @@ #include "sls_receiver_defs.h" #include "receiver_defs.h" #include "MySocketTCP.h" -#include "slsReceiverBase.h" +#include "UDPInterface.h" @@ -18,8 +18,8 @@ */ class slsReceiverTCPIPInterface : private virtual slsReceiverDefs { - -public: + + public: /** * Constructor * reads config file, creates socket, assigns function table @@ -27,16 +27,16 @@ public: * @param rbase pointer to the receiver base * @param pn port number (defaults to default port number) */ - slsReceiverTCPIPInterface(int &success, slsReceiverBase* rbase, int pn=-1); - + slsReceiverTCPIPInterface(int &success, UDPInterface* rbase, int pn=-1); + /** * Sets the port number to listen to. Take care that the client must know to whcih port it has to listen to, so normally it is better to use a fixes port from the instatiation or change it from the client. @param pn port number (-1 only get) \returns actual port number - */ - int setPortNumber(int pn=-1); - + */ + int setPortNumber(int pn=-1); + /** * Starts listening on the TCP port for client comminication \returns OK or FAIL @@ -234,7 +234,7 @@ private: detectorType myDetectorType; /** slsReceiverBase object */ - slsReceiverBase *receiverBase; + UDPInterface *receiverBase; /** Number of functions */ static const int numberOfFunctions = 256; diff --git a/slsReceiverSoftware/slsReceiver/slsReceiverUDPFunctions.cpp b/slsReceiverSoftware/slsReceiver/slsReceiverUDPFunctions.cpp index 3cc4fef38..bb8f213a5 100644 --- a/slsReceiverSoftware/slsReceiver/slsReceiverUDPFunctions.cpp +++ b/slsReceiverSoftware/slsReceiver/slsReceiverUDPFunctions.cpp @@ -6,6 +6,8 @@ #include "slsReceiverUDPFunctions.h" +#include "UDPBaseImplementation.h" + #include "moench02ModuleData.h" #include "gotthardModuleData.h" @@ -28,6 +30,9 @@ using namespace std; +slsReceiverUDPFunctions * slsReceiverUDPFunctions::create(void){ + return slsReceiverUDPFunctions(); +} slsReceiverUDPFunctions::slsReceiverUDPFunctions(): thread_started(0), @@ -695,7 +700,7 @@ void slsReceiverUDPFunctions::setupFilter(){ - +//LEO: it is not clear to me.. void slsReceiverUDPFunctions::setupFifoStructure(){ int64_t i; diff --git a/slsReceiverSoftware/slsReceiver/slsReceiverUDPFunctions.h b/slsReceiverSoftware/slsReceiver/slsReceiverUDPFunctions.h index 347a14358..6adce30ad 100644 --- a/slsReceiverSoftware/slsReceiver/slsReceiverUDPFunctions.h +++ b/slsReceiverSoftware/slsReceiver/slsReceiverUDPFunctions.h @@ -7,15 +7,17 @@ ***********************************************/ -#include "sls_receiver_defs.h" -#include "receiver_defs.h" -#include "genericSocket.h" +//#include "sls_receiver_defs.h" +//#include "receiver_defs.h" +//#include "genericSocket.h" #include "circularFifo.h" #include "singlePhotonDetector.h" #include "slsReceiverData.h" #include "moenchCommonMode.h" -#include "slsReceiverBase.h" + +#include "UDPInterface.h" +#include "UDPBaseImplementation.h" #ifdef MYROOT1 @@ -34,9 +36,10 @@ * @short does all the functions for a receiver, set/get parameters, start/stop etc. */ -class slsReceiverUDPFunctions : private virtual slsReceiverDefs, public slsReceiverBase { -public: +class slsReceiverUDPFunctions : private virtual slsReceiverDefs, public UDPInterface { + + public: /** * Constructor */ diff --git a/slsReceiverSoftware/slsReceiver/slsReceiverUsers.h b/slsReceiverSoftware/slsReceiver/slsReceiverUsers.h index a9d3626d2..50d6f38fe 100644 --- a/slsReceiverSoftware/slsReceiver/slsReceiverUsers.h +++ b/slsReceiverSoftware/slsReceiver/slsReceiverUsers.h @@ -1,4 +1,3 @@ - #ifndef SLS_RECEIVER_USERS_H #define SLS_RECEIVER_USERS_H @@ -29,7 +28,7 @@ public: * @param argv from command line * @param succecc socket creation was successfull */ - slsReceiverUsers(int argc, char *argv[], int &success); + slsReceiverUsers(int argc, char *argv[], int &success); /** Destructor */ From 9489cb8040cc7de4fee7acca82e56e9c12bfdb88 Mon Sep 17 00:00:00 2001 From: Sala Leonardo Date: Mon, 8 Sep 2014 11:44:58 +0200 Subject: [PATCH 019/474] moved config reading to utilities.h using GetOpt for CLI option reading --- .../slsReceiver/slsReceiver.cpp | 165 +++++++----------- 1 file changed, 66 insertions(+), 99 deletions(-) diff --git a/slsReceiverSoftware/slsReceiver/slsReceiver.cpp b/slsReceiverSoftware/slsReceiver/slsReceiver.cpp index 45359d02f..fd1223b71 100644 --- a/slsReceiverSoftware/slsReceiver/slsReceiver.cpp +++ b/slsReceiverSoftware/slsReceiver/slsReceiver.cpp @@ -9,132 +9,99 @@ #include #include +#include + #include "slsReceiver.h" -//#include "slsReceiverUDPFunctions.h" -//#include "eigerReceiver.h" - #include "UDPInterface.h" -//#include "UDPBaseImplementation.h" - #include "utilities.h" using namespace std; + + slsReceiver::slsReceiver(int argc, char *argv[], int &success){ + + /** + * Constructor method to start up a Receiver server. Reads configuration file, options, and + * assembles a Receiver using TCP and UDP detector interfaces + * + * @param iarg + * + * @return + */ //creating base receiver - int tcpip_port_no=-1; - - ifstream infile; - string sLine,sargname; - int iline = 0; - + int tcpip_port_no = 1984; success=OK; - string fname = ""; //parse command line for config - for(int iarg=1;iarg> sargname; - - //tcp port - if(sargname=="rx_tcpport"){ - if(sstr.good()) { - sstr >> sargname; - if(sscanf(sargname.c_str(),"%d",&tcpip_port_no)) - cout<<"dataport:"< Date: Mon, 8 Sep 2014 11:45:33 +0200 Subject: [PATCH 020/474] cleaning --- .../slsReceiver/slsReceiverUDPFunctions.cpp | 2319 ----------------- 1 file changed, 2319 deletions(-) delete mode 100644 slsReceiverSoftware/slsReceiver/slsReceiverUDPFunctions.cpp diff --git a/slsReceiverSoftware/slsReceiver/slsReceiverUDPFunctions.cpp b/slsReceiverSoftware/slsReceiver/slsReceiverUDPFunctions.cpp deleted file mode 100644 index bb8f213a5..000000000 --- a/slsReceiverSoftware/slsReceiver/slsReceiverUDPFunctions.cpp +++ /dev/null @@ -1,2319 +0,0 @@ -#ifdef SLS_RECEIVER_UDP_FUNCTIONS -/********************************************//** - * @file slsReceiverUDPFunctions.cpp - * @short does all the functions for a receiver, set/get parameters, start/stop etc. - ***********************************************/ - - -#include "slsReceiverUDPFunctions.h" -#include "UDPBaseImplementation.h" - - -#include "moench02ModuleData.h" -#include "gotthardModuleData.h" -#include "gotthardShortModuleData.h" - - -#include // SIGINT -#include // stat -#include // socket(), bind(), listen(), accept(), shut down -#include // sock_addr_in, htonl, INADDR_ANY -#include // exit() -#include //set precision -#include //munmap - - - -#include -#include -using namespace std; - - - -slsReceiverUDPFunctions * slsReceiverUDPFunctions::create(void){ - return slsReceiverUDPFunctions(); -} - -slsReceiverUDPFunctions::slsReceiverUDPFunctions(): - thread_started(0), - eth(NULL), - latestData(NULL), - guiFileName(NULL), - guiFrameNumber(0), - tengigaEnable(0){ - for(int i=0;i /proc/sys/net/core/rmem_max")) - cout << "\nWARNING: Could not change socket receiver buffer size in file /proc/sys/net/core/rmem_max" << endl; - else if(system("echo 250000 > /proc/sys/net/core/netdev_max_backlog")) - cout << "\nWARNING: Could not change max length of input queue in file /proc/sys/net/core/netdev_max_backlog" << endl; - /** permanent setting heiner - net.core.rmem_max = 104857600 # 100MiB - net.core.netdev_max_backlog = 250000 - sysctl -p - // from the manual - sysctl -w net.core.rmem_max=16777216 - sysctl -w net.core.netdev_max_backlog=250000 - */ -} - - - -slsReceiverUDPFunctions::~slsReceiverUDPFunctions(){ - createListeningThreads(true); - createWriterThreads(true); - deleteMembers(); -} - - - - -void slsReceiverUDPFunctions::deleteMembers(){ - //kill threads - if(thread_started){ - createListeningThreads(true); - createWriterThreads(true); - } - - for(int i=0;i=0) - fileIndex = i; - return getFileIndex(); -} - - -int slsReceiverUDPFunctions::setFrameIndexNeeded(int i){ - frameIndexNeeded = i; - return frameIndexNeeded; -} - - -int slsReceiverUDPFunctions::getEnableFileWrite() const{ - return enableFileWrite; -} - -int slsReceiverUDPFunctions::setEnableFileWrite(int i){ - enableFileWrite=i; - return getEnableFileWrite(); -} - -int slsReceiverUDPFunctions::getEnableOverwrite() const{ - return overwrite; -} - -int slsReceiverUDPFunctions::setEnableOverwrite(int i){ - overwrite=i; - return getEnableOverwrite(); -} - - - - - -/*other parameters*/ - -slsReceiverDefs::runStatus slsReceiverUDPFunctions::getStatus() const{ - return status; -} - - -void slsReceiverUDPFunctions::initialize(const char *detectorHostName){ - if(strlen(detectorHostName)) - strcpy(detHostname,detectorHostName); -} - - -char *slsReceiverUDPFunctions::getDetectorHostname() const{ - return (char*)detHostname; -} - -void slsReceiverUDPFunctions::setEthernetInterface(char* c){ - strcpy(eth,c); -} - - -void slsReceiverUDPFunctions::setUDPPortNo(int p){ - for(int i=0;i= 0) - numberOfFrames = fnum; - - return getNumberOfFrames(); -} - -int slsReceiverUDPFunctions::getScanTag() const{ - return scanTag; -} - - -int32_t slsReceiverUDPFunctions::setScanTag(int32_t stag){ - if(stag >= 0) - scanTag = stag; - - return getScanTag(); -} - - -int slsReceiverUDPFunctions::getDynamicRange() const{ - return dynamicRange; -} - -int32_t slsReceiverUDPFunctions::setDynamicRange(int32_t dr){ - cout << "Setting Dynamic Range" << endl; - - int olddr = dynamicRange; - if(dr >= 0){ - dynamicRange = dr; - - if(myDetectorType == EIGER){ - - - if(!tengigaEnable) - packetsPerFrame = EIGER_ONE_GIGA_CONSTANT * dynamicRange * EIGER_MAX_PORTS; - else - packetsPerFrame = EIGER_TEN_GIGA_CONSTANT * dynamicRange * EIGER_MAX_PORTS; - frameSize = onePacketSize * packetsPerFrame; - bufferSize = (frameSize/EIGER_MAX_PORTS) + EIGER_HEADER_LENGTH;//everything one port gets (img header plus packets) - maxPacketsPerFile = EIGER_MAX_FRAMES_PER_FILE * packetsPerFrame; - - - - if(olddr != dr){ - - //del - if(thread_started){ - createListeningThreads(true); - createWriterThreads(true); - } - for(int i=0;i=0){ - nFrameToGui = i; - setupFifoStructure(); - } - return nFrameToGui; -} - - - -int64_t slsReceiverUDPFunctions::setAcquisitionPeriod(int64_t index){ - - if(index >= 0){ - if(index != acquisitionPeriod){ - acquisitionPeriod = index; - setupFifoStructure(); - } - } - return acquisitionPeriod; -} - - -bool slsReceiverUDPFunctions::getDataCompression(){return dataCompression;} - -int slsReceiverUDPFunctions::enableDataCompression(bool enable){ - cout << "Data compression "; - if(enable) - cout << "enabled" << endl; - else - cout << "disabled" << endl; -#ifdef MYROOT1 - cout << " WITH ROOT" << endl; -#else - cout << " WITHOUT ROOT" << endl; -#endif - //delete filter for the current number of threads - deleteFilter(); - - dataCompression = enable; - pthread_mutex_lock(&status_mutex); - writerthreads_mask = 0x0; - pthread_mutex_unlock(&(status_mutex)); - - createWriterThreads(true); - - if(enable) - numWriterThreads = MAX_NUM_WRITER_THREADS; - else - numWriterThreads = 1; - - if(createWriterThreads() == FAIL){ - cout << "ERROR: Could not create writer threads" << endl; - return FAIL; - } - setThreadPriorities(); - - - if(enable) - setupFilter(); - - return OK; -} - - - - - - - - - - - - -/*other functions*/ - - -void slsReceiverUDPFunctions::deleteFilter(){ - int i; - cmSub=NULL; - - for(i=0;i(receiverdata[i], csize, sigma, sign, cmSub); - -} - - - -//LEO: it is not clear to me.. -void slsReceiverUDPFunctions::setupFifoStructure(){ - - int64_t i; - int oldn = numJobsPerThread; - - //if every nth frame mode - if(nFrameToGui) - numJobsPerThread = nFrameToGui; - - //random nth frame mode - else{ - if(!acquisitionPeriod) - i = SAMPLE_TIME_IN_NS; - else - i = SAMPLE_TIME_IN_NS/acquisitionPeriod; - if (i > MAX_JOBS_PER_THREAD) - numJobsPerThread = MAX_JOBS_PER_THREAD; - else if (i < 1) - numJobsPerThread = 1; - else - numJobsPerThread = i; - } - - //if same, return - if(oldn == numJobsPerThread) - return; - - if(myDetectorType == EIGER) - numJobsPerThread = 1; - - //otherwise memory too much if numjobsperthread is at max = 1000 - fifosize = GOTTHARD_FIFO_SIZE; - if(myDetectorType == MOENCH) - fifosize = MOENCH_FIFO_SIZE; - else if(myDetectorType == EIGER) - fifosize = EIGER_FIFO_SIZE; - - if(fifosize % numJobsPerThread) - fifosize = (fifosize/numJobsPerThread)+1; - else - fifosize = fifosize/numJobsPerThread; - - - cout << "Number of Frames per buffer:" << numJobsPerThread << endl; - cout << "Fifo Size:" << fifosize << endl; - - /* - //for testing - numJobsPerThread = 3; fifosize = 11; - */ - - for(int i=0;iisEmpty()) - fifoFree[i]->pop(buffer[i]); - delete fifoFree[i]; - } - if(fifo[i]) delete fifo[i]; - if(mem0[i]) free(mem0[i]); - fifoFree[i] = new CircularFifo(fifosize); - fifo[i] = new CircularFifo(fifosize); - - - //allocate memory - mem0[i]=(char*)malloc((bufferSize * numJobsPerThread + HEADER_SIZE_NUM_TOT_PACKETS)*fifosize); - /** shud let the client know about this */ - if (mem0[i]==NULL){ - cout<<"++++++++++++++++++++++ COULD NOT ALLOCATE MEMORY FOR LISTENING !!!!!!!+++++++++++++++++++++" << endl; - exit(-1); - } - buffer[i]=mem0[i]; - //push the addresses into freed fifoFree and writingFifoFree - while (buffer[i]<(mem0[i]+(bufferSize * numJobsPerThread + HEADER_SIZE_NUM_TOT_PACKETS)*(fifosize-1))) { - fifoFree[i]->push(buffer[i]); - buffer[i]+=(bufferSize * numJobsPerThread + HEADER_SIZE_NUM_TOT_PACKETS); - } - } - cout << "Fifo structure(s) reconstructed" << endl; -} - - - - - - - -/** acquisition functions */ - -void slsReceiverUDPFunctions::readFrame(char* c,char** raw, uint32_t &fnum){ - //point to gui data - if (guiData == NULL) - guiData = latestData; - - //copy data and filename - strcpy(c,guiFileName); - fnum = guiFrameNumber; - - - //could not get gui data - if(!guiDataReady){ - *raw = NULL; - } - //data ready, set guidata to receive new data - else{ - *raw = guiData; - guiData = NULL; - - pthread_mutex_lock(&dataReadyMutex); - guiDataReady = 0; - pthread_mutex_unlock(&dataReadyMutex); - if((nFrameToGui) && (writerthreads_mask)){ - /*if(nFrameToGui){*/ - //release after getting data - sem_post(&smp); - } - } -} - - - - - -void slsReceiverUDPFunctions::copyFrameToGui(char* startbuf[], uint32_t fnum, char* buf){ - - //random read when gui not ready - if((!nFrameToGui) && (!guiData)){ - pthread_mutex_lock(&dataReadyMutex); - guiDataReady=0; - pthread_mutex_unlock(&dataReadyMutex); - } - - //random read or nth frame read, gui needs data now - else{ - /* - //nth frame read, block current process if the guireader hasnt read it yet - if(nFrameToGui) - sem_wait(&smp); -*/ - pthread_mutex_lock(&dataReadyMutex); - guiDataReady=0; - //eiger - if(startbuf != NULL){ - int offset = 0; - int size = frameSize/EIGER_MAX_PORTS; - for(int j=0;jgetErrorStatus(); - if(iret){ -#ifdef VERBOSE - cout << "Could not create UDP socket on port " << server_port[i] << " error:" << iret << endl; -#endif - return FAIL; - } - } - - return OK; -} - - - - - - - -int slsReceiverUDPFunctions::shutDownUDPSockets(){ - for(int i=0;iShutDownSocket(); - delete udpSocket[i]; - udpSocket[i] = NULL; - } - } - return OK; -} - - - - - -int slsReceiverUDPFunctions::createListeningThreads(bool destroy){ - int i; - void* status; - - killAllListeningThreads = 0; - - pthread_mutex_lock(&status_mutex); - listeningthreads_mask = 0x0; - pthread_mutex_unlock(&(status_mutex)); - - if(!destroy){ - - //start listening threads - cout << "Creating Listening Threads(s)"; - - currentListeningThreadIndex = -1; - - for(i = 0; i < numListeningThreads; ++i){ - sem_init(&listensmp[i],1,0); - thread_started = 0; - currentListeningThreadIndex = i; - if(pthread_create(&listening_thread[i], NULL,startListeningThread, (void*) this)){ - cout << "Could not create listening thread with index " << i << endl; - return FAIL; - } - while(!thread_started); - cout << "."; - cout << flush; - } -#ifdef VERBOSE - cout << "Listening thread(s) created successfully." << endl; -#else - cout << endl; -#endif - }else{ - cout<<"Destroying Listening Thread(s)"<initEventTree(temp, &iframe); - //resets the pedestalSubtraction array and the commonModeSubtraction - singlePhotonDet[ithr]->newDataSet(); - if(myFile[ithr]==NULL){ - cout<<"file null"<IsOpen()){ - cout<<"file not open"< DO_NOTHING){ - //close - if(sfilefd){ - fclose(sfilefd); - sfilefd = NULL; - } - //open file - if(!overwrite){ - if (NULL == (sfilefd = fopen((const char *) (savefilename), "wx"))){ - cout << "Error: Could not create new file " << savefilename << endl; - return FAIL; - } - }else if (NULL == (sfilefd = fopen((const char *) (savefilename), "w"))){ - cout << "Error: Could not create file " << savefilename << endl; - return FAIL; - } - //setting buffer - setvbuf(sfilefd,NULL,_IOFBF,BUF_SIZE); - - //printing packet losses and file names - if(!packetsCaught) - cout << savefilename << endl; - else{ - cout << savefilename - << "\tpacket loss " - << setw(4)<GetCurrentFile(); - - if(myFile[ithr]->Write()) - //->Write(tall->GetName(),TObject::kOverwrite); - cout << "Thread " << ithr <<": wrote frames to file" << endl; - else - cout << "Thread " << ithr << ": could not write frames to file" << endl; - - }else - cout << "Thread " << ithr << ": could not write frames to file: No file or No Tree" << endl; - //close file - if(myTree[ithr] && myFile[ithr]) - myFile[ithr] = myTree[ithr]->GetCurrentFile(); - if(myFile[ithr] != NULL) - myFile[ithr]->Close(); - myFile[ithr] = NULL; - myTree[ithr] = NULL; - pthread_mutex_unlock(&write_mutex); - -#endif - } -} - - - - - -int slsReceiverUDPFunctions::startReceiver(char message[]){ - int i; - - -// #ifdef VERBOSE - cout << "Starting Receiver" << endl; -//#endif - - - //reset listening thread variables - measurementStarted = false; - //should be set to zero as its added to get next start frame indices for scans for eiger - if(!acqStarted) currframenum = 0; - startFrameIndex = 0; - - for(int i = 0; i < numListeningThreads; ++i) - totalListeningFrameCount[i] = 0; - - //udp socket - if(createUDPSockets() == FAIL){ - strcpy(message,"Could not create UDP Socket(s).\n"); - cout << endl << message << endl; - return FAIL; - } - cout << "UDP socket(s) created successfully. 1st port " << server_port[0] << endl; - - - if(setupWriter() == FAIL){ - //stop udp socket - shutDownUDPSockets(); - - sprintf(message,"Could not create file %s.\n",savefilename); - return FAIL; - } - cout << "Successfully created file(s)" << endl; - - //done to give the gui some proper name instead of always the last file name - if(dataCompression) - sprintf(savefilename, "%s/%s_fxxx_%d_xx.root", filePath,fileName,fileIndex); - - //initialize semaphore - sem_init(&smp,1,0); - - //status - pthread_mutex_lock(&status_mutex); - status = RUNNING; - for(i=0;istartListening(); - - return this_pointer; -} - - - -void* slsReceiverUDPFunctions::startWritingThread(void* this_pointer){ - ((slsReceiverUDPFunctions*)this_pointer)->startWriting(); - return this_pointer; -} - - - - - - -int slsReceiverUDPFunctions::startListening(){ - int ithread = currentListeningThreadIndex; -#ifdef VERYVERBOSE - cout << "In startListening() " << endl; -#endif - - thread_started = 1; - - int i,total; - int lastpacketoffset, expected, rc, rc1,packetcount, maxBufferSize, carryonBufferSize; - uint32_t lastframeheader;// for moench to check for all the packets in last frame - char* tempchar = NULL; - int imageheader = 0; - if(myDetectorType==EIGER) - imageheader = EIGER_IMAGE_HEADER_SIZE; - - - while(1){ - //variables that need to be checked/set before each acquisition - carryonBufferSize = 0; - //if more than 1 listening thread, listen one packet at a time, else need to interleaved frame later - maxBufferSize = bufferSize * numJobsPerThread; -#ifdef VERYDEBUG - cout << " maxBufferSize:" << maxBufferSize << ",carryonBufferSize:" << carryonBufferSize << endl; -#endif - - if(tempchar) {delete [] tempchar;tempchar = NULL;} - if(myDetectorType != EIGER) - tempchar = new char[onePacketSize * ((packetsPerFrame/numListeningThreads) - 1)]; //gotthard: 1packet size, moench:39 packet size - - - while((1<pop(buffer[ithread]); -#ifdef VERYDEBUG - cout << ithread << " *** popped from fifo free" << (void*)buffer[ithread] << endl; -#endif - - - //receive - if(udpSocket[ithread] == NULL){ - rc = 0; - cout << ithread << "UDP Socket is NULL" << endl; - } - //normal listening - else if(!carryonBufferSize){ - - rc = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS, maxBufferSize); - expected = maxBufferSize; - - } - //the remaining packets from previous buffer - else{ -#ifdef VERYDEBUG - cout << ithread << " ***carry on buffer" << carryonBufferSize << endl; - cout << ithread << " framennum in temochar:"<<((((uint32_t)(*((uint32_t*)tempchar))) - & (frameIndexMask)) >> frameIndexOffset)<ReceiveDataOnly((buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS + carryonBufferSize),maxBufferSize - carryonBufferSize); - expected = maxBufferSize - carryonBufferSize; - } - -#ifdef VERYDEBUG - cout << ithread << " *** rc:" << dec << rc << ". expected:" << dec << expected << endl; -#endif - - - - - //start indices for each start of scan/acquisition - eiger does it before - if((!measurementStarted) && (rc > 0) && (!ithread)) - startFrameIndices(ithread); - - //problem in receiving or end of acquisition - if((rc < expected)||(rc <= 0)){ - stopListening(ithread,rc,packetcount,total); - continue; - } - - - - //reset - packetcount = (packetsPerFrame/numListeningThreads) * numJobsPerThread; - carryonBufferSize = 0; - - - - //check if last packet valid and calculate packet count - switch(myDetectorType){ - - case MOENCH: - lastpacketoffset = (((numJobsPerThread * packetsPerFrame - 1) * onePacketSize) + HEADER_SIZE_NUM_TOT_PACKETS); -#ifdef VERYDEBUG - cout <<"first packet:"<< ((((uint32_t)(*((uint32_t*)(buffer[ithread]+HEADER_SIZE_NUM_TOT_PACKETS))))) & (packetIndexMask)) << endl; - cout <<"first header:"<< (((((uint32_t)(*((uint32_t*)(buffer[ithread]+HEADER_SIZE_NUM_TOT_PACKETS))))) & (frameIndexMask)) >> frameIndexOffset) << endl; - cout << "last packet offset:" << lastpacketoffset << endl; - cout <<"last packet:"<< ((((uint32_t)(*((uint32_t*)(buffer[ithread]+lastpacketoffset))))) & (packetIndexMask)) << endl; - cout <<"last header:"<< (((((uint32_t)(*((uint32_t*)(buffer[ithread]+lastpacketoffset))))) & (frameIndexMask)) >> frameIndexOffset) << endl; -#endif - //moench last packet value is 0 - if( ((((uint32_t)(*((uint32_t*)(buffer[ithread]+lastpacketoffset))))) & (packetIndexMask))){ - lastframeheader = ((((uint32_t)(*((uint32_t*)(buffer[ithread]+lastpacketoffset))))) & (frameIndexMask)) >> frameIndexOffset; - carryonBufferSize += onePacketSize; - lastpacketoffset -= onePacketSize; - --packetcount; - while (lastframeheader == (((((uint32_t)(*((uint32_t*)(buffer[ithread]+lastpacketoffset))))) & (frameIndexMask)) >> frameIndexOffset)){ - carryonBufferSize += onePacketSize; - lastpacketoffset -= onePacketSize; - --packetcount; - } - memcpy(tempchar, buffer[ithread]+(lastpacketoffset+onePacketSize), carryonBufferSize); -#ifdef VERYDEBUG - cout << "tempchar header:" << (((((uint32_t)(*((uint32_t*)(tempchar))))) - & (frameIndexMask)) >> frameIndexOffset) << endl; - cout <<"tempchar packet:"<< ((((uint32_t)(*((uint32_t*)(tempchar))))) - & (packetIndexMask)) << endl; -#endif - } - break; - - case GOTTHARD: - if(shortFrame == -1){ - lastpacketoffset = (((numJobsPerThread * packetsPerFrame - 1) * onePacketSize) + HEADER_SIZE_NUM_TOT_PACKETS); -#ifdef VERYDEBUG - cout << "last packet offset:" << lastpacketoffset << endl; -#endif - - if((unsigned int)(packetsPerFrame -1) != ((((uint32_t)(*((uint32_t*)(buffer[ithread]+lastpacketoffset))))+1) & (packetIndexMask))){ - memcpy(tempchar,buffer[ithread]+lastpacketoffset, onePacketSize); -#ifdef VERYDEBUG - cout << "tempchar header:" << (((((uint32_t)(*((uint32_t*)(tempchar))))+1) - & (frameIndexMask)) >> frameIndexOffset) << endl; -#endif - carryonBufferSize = onePacketSize; - --packetcount; - } - } -#ifdef VERYDEBUG - cout << "header:" << (((((uint32_t)(*((uint32_t*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS))))+1) - & (frameIndexMask)) >> frameIndexOffset) << endl; -#endif - break; - default: - - break; - - } - - - // cout<<"*********** "<fnum)<push(buffer[ithread])); -#ifdef VERYDEBUG - if(!ithread) cout << ithread << " *** pushed into listening fifo" << endl; -#endif - } - - sem_wait(&listensmp[ithread]); - - //make sure its not exiting thread - if(killAllListeningThreads){ - cout << ithread << " good bye listening thread" << endl; - if(tempchar) {delete [] tempchar;tempchar = NULL;} - pthread_exit(NULL); - } - } - - return OK; -} - - - - - - - - - - - - - -int slsReceiverUDPFunctions::startWriting(){ - int ithread = currentWriterThreadIndex; -#ifdef VERYVERBOSE - cout << ithread << "In startWriting()" <pop(wbuf[i]); - numpackets = (uint16_t)(*((uint16_t*)wbuf[i])); -#ifdef VERYDEBUG - cout << ithread << " numpackets:" << dec << numpackets << endl; -#endif - } - -#ifdef VERYDEBUG - cout << ithread << " numpackets:" << dec << numpackets << endl; - cout << ithread << " *** writer popped from fifo " << (void*) wbuf[0]<< endl; - cout << ithread << " *** writer popped from fifo " << (void*) wbuf[1]<< endl; -#endif - - - //last dummy packet - if(numpackets == 0xFFFF){ - stopWriting(ithread,wbuf); - continue; - } - - - - - //for progress - if(myDetectorType == EIGER){ - tempframenum = htonl(*(unsigned int*)((eiger_image_header *)((char*)(wbuf[ithread] + HEADER_SIZE_NUM_TOT_PACKETS)))->fnum); - tempframenum += (startFrameIndex-1); //eiger frame numbers start at 1, so need to -1 - }else if ((myDetectorType == GOTTHARD) && (shortFrame == -1)) - tempframenum = (((((uint32_t)(*((uint32_t*)(wbuf[ithread] + HEADER_SIZE_NUM_TOT_PACKETS))))+1)& (frameIndexMask)) >> frameIndexOffset); - else - tempframenum = ((((uint32_t)(*((uint32_t*)(wbuf[ithread] + HEADER_SIZE_NUM_TOT_PACKETS))))& (frameIndexMask)) >> frameIndexOffset); - - if(numWriterThreads == 1) - currframenum = tempframenum; - else{ - pthread_mutex_lock(&progress_mutex); - if(tempframenum > currframenum) - currframenum = tempframenum; - pthread_mutex_unlock(&progress_mutex); - } -//#ifdef VERYDEBUG - if(myDetectorType == EIGER) - cout << endl < 0){ - for(i=0;ipush(wbuf[i])); -#ifdef VERYDEBUG - cout << ithread << ":" << i+j << " fifo freed:" << (void*)wbuf[i] << endl; -#endif - } - - - } - else{ - //copy to gui - copyFrameToGui(NULL,-1,wbuf[0]+HEADER_SIZE_NUM_TOT_PACKETS); -#ifdef VERYVERBOSE - cout << ithread << " finished copying" << endl; -#endif - while(!fifoFree[0]->push(wbuf[0])); -#ifdef VERYVERBOSE - cout<<"buf freed:"<<(void*)wbuf[0]<fnum); - //gotthard has +1 for frame number and not a short frame - else if ((myDetectorType == GOTTHARD) && (shortFrame == -1)) - startFrameIndex = (((((uint32_t)(*((uint32_t*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS))))+1) - & (frameIndexMask)) >> frameIndexOffset); - else - startFrameIndex = ((((uint32_t)(*((uint32_t*)(buffer[ithread]+HEADER_SIZE_NUM_TOT_PACKETS)))) - & (frameIndexMask)) >> frameIndexOffset); - - - //start of acquisition - if(!acqStarted){ - startAcquisitionIndex=startFrameIndex; - currframenum = startAcquisitionIndex; - acqStarted = true; - cout << "startAcquisitionIndex:" << startAcquisitionIndex<push(buffer[ithread]); - exit(-1); - } - //push the last buffer into fifo - if(rc > 0){ - pc = (rc/onePacketSize); -#ifdef VERYDEBUG - cout << ithread << " *** last packetcount:" << pc << endl; -#endif - (*((uint16_t*)(buffer[ithread]))) = pc; - totalListeningFrameCount[ithread] += pc; - while(!fifo[ithread]->push(buffer[ithread])); -#ifdef VERYDEBUG - cout << ithread << " *** last lbuf1:" << (void*)buffer[ithread] << endl; -#endif - } - - - //push dummy buffer to all writer threads - for(i=0;ipop(buffer[ithread]); - (*((uint16_t*)(buffer[ithread]))) = 0xFFFF; -#ifdef VERYDEBUG - cout << ithread << " going to push in dummy buffer:" << (void*)buffer[ithread] << " with num packets:"<< (*((uint16_t*)(buffer[ithread]))) << endl; -#endif - while(!fifo[ithread]->push(buffer[ithread])); -#ifdef VERYDEBUG - cout << ithread << " pushed in dummy buffer:" << (void*)buffer[ithread] << endl; -#endif - } - - //reset mask and exit loop - pthread_mutex_lock(&status_mutex); - listeningthreads_mask^=(1< 1) - cout << "Waiting for listening to be done.. current mask:" << hex << listeningthreads_mask << endl; -#endif - while(listeningthreads_mask) - usleep(5000); -#ifdef VERYDEBUG - t = 0; - for(i=0;ipush(wbuffer[i])); -#ifdef VERYDEBUG - cout << ithread << ":" << i<< " fifo freed:" << (void*)wbuffer[i] << endl; -#endif - } - - - - //all threads need to close file, reset mask and exit loop - closeFile(ithread); - pthread_mutex_lock(&status_mutex); - writerthreads_mask^=(1< 0){ - - //for progress and packet loss calculation(new files) - if(myDetectorType == EIGER); - else if ((myDetectorType == GOTTHARD) && (shortFrame == -1)) - tempframenum = (((((uint32_t)(*((uint32_t*)(buf + HEADER_SIZE_NUM_TOT_PACKETS))))+1)& (frameIndexMask)) >> frameIndexOffset); - else - tempframenum = ((((uint32_t)(*((uint32_t*)(buf + HEADER_SIZE_NUM_TOT_PACKETS))))& (frameIndexMask)) >> frameIndexOffset); - - if(numWriterThreads == 1) - currframenum = tempframenum; - else{ - if(tempframenum > currframenum) - currframenum = tempframenum; - } -#ifdef VERYDEBUG - cout << "tempframenum:" << dec << tempframenum << " curframenum:" << currframenum << endl; -#endif - - //lock - if(numWriterThreads > 1) - pthread_mutex_lock(&write_mutex); - - - //to create new file when max reached - packetsToSave = maxPacketsPerFile - packetsInFile; - if(packetsToSave > numpackets) - packetsToSave = numpackets; -/**next time offset is still plus header length*/ - fwrite(buf+offset, 1, packetsToSave * onePacketSize, sfilefd); - packetsInFile += packetsToSave; - packetsCaught += packetsToSave; - totalPacketsCaught += packetsToSave; - - - //new file - if(packetsInFile >= maxPacketsPerFile){ - //for packet loss - lastpacket = (((packetsToSave - 1) * onePacketSize) + offset); - if(myDetectorType == EIGER); - else if ((myDetectorType == GOTTHARD) && (shortFrame == -1)) - tempframenum = (((((uint32_t)(*((uint32_t*)(buf + lastpacket))))+1)& (frameIndexMask)) >> frameIndexOffset); - else - tempframenum = ((((uint32_t)(*((uint32_t*)(buf + lastpacket))))& (frameIndexMask)) >> frameIndexOffset); - - if(numWriterThreads == 1) - currframenum = tempframenum; - else{ - if(tempframenum > currframenum) - currframenum = tempframenum; - } -#ifdef VERYDEBUG - cout << "tempframenum:" << dec << tempframenum << " curframenum:" << currframenum << endl; -#endif - //create - createNewFile(); - } - - //unlock - if(numWriterThreads > 1) - pthread_mutex_unlock(&write_mutex); - - - offset += (packetsToSave * onePacketSize); - numpackets -= packetsToSave; - } - - } - else{ - if(numWriterThreads > 1) - pthread_mutex_lock(&write_mutex); - packetsInFile += numpackets; - packetsCaught += numpackets; - totalPacketsCaught += numpackets; - if(numWriterThreads > 1) - pthread_mutex_unlock(&write_mutex); - } -} - - - - - - - - - - - - - - -void slsReceiverUDPFunctions::handleDataCompression(int ithread, char* wbuffer[], int &npackets, char* data, int xmax, int ymax, int &nf){ - -#if defined(MYROOT1) && defined(ALLFILE_DEBUG) - writeToFile_withoutCompression(wbuf[0], numpackets,currframenum); -#endif - - eventType thisEvent = PEDESTAL; - int ndata; - char* buff = 0; - data = wbuffer[0]+ HEADER_SIZE_NUM_TOT_PACKETS; - int remainingsize = npackets * onePacketSize; - int np; - int once = 0; - double tot, tl, tr, bl, br; - int xmin = 1, ymin = 1, ix, iy; - - - while(buff = receiverdata[ithread]->findNextFrame(data,ndata,remainingsize)){ - np = ndata/onePacketSize; - - //cout<<"buff framnum:"<> frameIndexOffset)<newFrame(); - - //only for moench - if(commonModeSubtractionEnable){ - for(ix = xmin - 1; ix < xmax+1; ix++){ - for(iy = ymin - 1; iy < ymax+1; iy++){ - thisEvent = singlePhotonDet[ithread]->getEventType(buff, ix, iy, 0); - } - } - } - - - for(ix = xmin - 1; ix < xmax+1; ix++) - for(iy = ymin - 1; iy < ymax+1; iy++){ - thisEvent=singlePhotonDet[ithread]->getEventType(buff, ix, iy, commonModeSubtractionEnable); - if (nf>1000) { - tot=0; - tl=0; - tr=0; - bl=0; - br=0; - if (thisEvent==PHOTON_MAX) { - receiverdata[ithread]->getFrameNumber(buff); - //iFrame=receiverdata[ithread]->getFrameNumber(buff); -#ifdef MYROOT1 - myTree[ithread]->Fill(); - //cout << "Fill in event: frmNr: " << iFrame << " ix " << ix << " iy " << iy << " type " << thisEvent << endl; -#else - pthread_mutex_lock(&write_mutex); - if((enableFileWrite) && (sfilefd)) - singlePhotonDet[ithread]->writeCluster(sfilefd); - pthread_mutex_unlock(&write_mutex); -#endif - } - } - } - - nf++; -#ifndef ALLFILE - pthread_mutex_lock(&progress_mutex); - packetsInFile += packetsPerFrame; - packetsCaught += packetsPerFrame; - totalPacketsCaught += packetsPerFrame; - if(packetsInFile >= maxPacketsPerFile) - createNewFile(); - pthread_mutex_unlock(&progress_mutex); - -#endif - if(!once){ - copyFrameToGui(NULL,-1,buff); - once = 1; - } - } - - remainingsize -= ((buff + ndata) - data); - data = buff + ndata; - if(data > (wbuffer[0] + HEADER_SIZE_NUM_TOT_PACKETS + npackets * onePacketSize) ) - cout <<" **************ERROR SHOULD NOT COME HERE, Error 142536!"<push(wbuffer[0])); -#ifdef VERYVERBOSE - cout<<"buf freed:"<<(void*)wbuffer[0]<= 0){ - - tengigaEnable = enable; - - if(myDetectorType == EIGER){ - - if(!tengigaEnable){ - packetsPerFrame = EIGER_ONE_GIGA_CONSTANT * dynamicRange * EIGER_MAX_PORTS; - onePacketSize = EIGER_ONE_GIGA_ONE_PACKET_SIZE; - maxPacketsPerFile = EIGER_MAX_FRAMES_PER_FILE * packetsPerFrame; - }else{ - packetsPerFrame = EIGER_TEN_GIGA_CONSTANT * dynamicRange * EIGER_MAX_PORTS; - onePacketSize = EIGER_TEN_GIGA_ONE_PACKET_SIZE; - maxPacketsPerFile = EIGER_MAX_FRAMES_PER_FILE * packetsPerFrame*4; - } - frameSize = onePacketSize * packetsPerFrame; - bufferSize = (frameSize/EIGER_MAX_PORTS) + EIGER_HEADER_LENGTH;//everything one port gets (img header plus packets) - //maxPacketsPerFile = EIGER_MAX_FRAMES_PER_FILE * packetsPerFrame; - - - cout<<"packetsPerFrame:"< Date: Mon, 8 Sep 2014 11:45:52 +0200 Subject: [PATCH 021/474] cleaning --- slsReceiverSoftware/slsReceiver/UDPInterface.cpp | 6 ++---- slsReceiverSoftware/slsReceiver/slsReceiver.h | 1 - 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/slsReceiverSoftware/slsReceiver/UDPInterface.cpp b/slsReceiverSoftware/slsReceiver/UDPInterface.cpp index d53166f9e..b82d497b6 100644 --- a/slsReceiverSoftware/slsReceiver/UDPInterface.cpp +++ b/slsReceiverSoftware/slsReceiver/UDPInterface.cpp @@ -6,7 +6,7 @@ - +/* #include // SIGINT #include // stat #include // socket(), bind(), listen(), accept(), shut down @@ -14,6 +14,7 @@ #include // exit() #include //set precision #include //munmap +*/ #include #include @@ -22,9 +23,6 @@ using namespace std; #include "UDPInterface.h" #include "UDPBaseImplementation.h" -#include "moench02ModuleData.h" -#include "gotthardModuleData.h" -#include "gotthardShortModuleData.h" using namespace std; diff --git a/slsReceiverSoftware/slsReceiver/slsReceiver.h b/slsReceiverSoftware/slsReceiver/slsReceiver.h index 899dabe8d..0cd195c72 100644 --- a/slsReceiverSoftware/slsReceiver/slsReceiver.h +++ b/slsReceiverSoftware/slsReceiver/slsReceiver.h @@ -10,7 +10,6 @@ #include "UDPInterface.h" #include "UDPBaseImplementation.h" -#include "sls_receiver_defs.h" #include "receiver_defs.h" #include "MySocketTCP.h" From 56411017051d85b5bcbc807227edf073dd4af978 Mon Sep 17 00:00:00 2001 From: Sala Leonardo Date: Mon, 8 Sep 2014 16:01:18 +0200 Subject: [PATCH 022/474] added logger --- slsReceiverSoftware/Makefile | 24 ++-- slsReceiverSoftware/slsReceiver/Makefile | 26 ++-- .../slsReceiver/UDPBaseImplementation.cpp | 113 +++--------------- .../slsReceiver/UDPBaseImplementation.h | 1 - .../slsReceiver/UDPInterface.cpp | 5 +- .../slsReceiver/UDPInterface.h | 3 + slsReceiverSoftware/slsReceiver/main.cpp | 3 + .../slsReceiver/slsReceiver.cpp | 35 ++++-- slsReceiverSoftware/slsReceiver/slsReceiver.h | 4 +- 9 files changed, 76 insertions(+), 138 deletions(-) diff --git a/slsReceiverSoftware/Makefile b/slsReceiverSoftware/Makefile index 8f6e00910..2b159dad3 100644 --- a/slsReceiverSoftware/Makefile +++ b/slsReceiverSoftware/Makefile @@ -11,16 +11,16 @@ CFLAGS= -g -DC_ONLY -fPIC DFLAGS= -g -DDACS_INT -DSLS_RECEIVER_UDP_FUNCTIONS -INCLUDES?= -I. -Iincludes -IMySocketTCP -IslsReceiver -IslsDetectorCalibration -IslsReceiver/eigerReceiver -I$(ASM) +INCLUDES?= -I. -Iincludes -IMySocketTCP -IslsReceiver -IslsDetectorCalibration -I$(ASM) #-IslsReceiverInterface -SRC_CLNT= MySocketTCP/MySocketTCP.cpp slsReceiver/slsReceiver.cpp slsReceiver/UDPInterface.cpp slsReceiver/UDPBaseImplementation.cpp slsReceiver/slsReceiverTCPIPInterface.cpp slsReceiver/slsReceiverUsers.cpp - +SRC_CLNT= MySocketTCP/MySocketTCP.cpp slsReceiver/UDPInterface.cpp slsReceiver/UDPBaseImplementation.cpp slsReceiver/UDPStandardImplementation.cpp slsReceiver/slsReceiverTCPIPInterface.cpp slsReceiver/slsReceiver.cpp slsReceiver/slsReceiverUsers.cpp includes/utilities.h #slsReceiverInterface/receiverInterface.cpp #slsReceiver/slsReceiverUDPFunctions.cpp OBJS = $(SRC_CLNT:.cpp=.o) -OBJS += slsReceiver/eigerReceiver.o +OBJS += includes/utilities.h +#OBJS += slsReceiver/eigerReceiver.o .PHONY: all intdoc package eigerReceiver clean @@ -31,10 +31,8 @@ intdoc: $(SRC_H) $(SRC_CLNT) doxygen doxy.config -%.o : %.cpp %.h Makefile -ifeq ($(EIGERSLS),yes) - $(CXX) -DEIGERSLS -o $@ -c $< $(INCLUDES) $(DFLAGS) $(EIGERFLAGS) -fPIC $(EPICSFLAGS) -L/usr/lib64/ #$(FLAGS) -else ifeq ($(ROOTSLS),yes) +%.o : %.cpp Makefile +ifeq ($(ROOTSLS),yes) echo "with root" $(CXX) -DROOTSLS -o $@ -c $< $(INCLUDES) $(DFLAGS) $(ROOTFLAGS) -fPIC $(EPICSFLAGS) -L/usr/lib64/ #$(FLAGS) else @@ -43,14 +41,14 @@ else endif # LEO: not satisfied by eigerReceiver -package: eigerReceiver $(OBJS) $(DESTDIR)/libSlsReceiver.so $(DESTDIR)/libSlsReceiver.a +package: $(OBJS) $(DESTDIR)/libSlsReceiver.so $(DESTDIR)/libSlsReceiver.a -eigerReceiver: - echo "src client:" $(SRC_CLNT) - cd slsReceiver && make eigerReceiver +#eigerReceiver: +# echo "src client:" $(SRC_CLNT) +# cd slsReceiver && make eigerReceiver $(DESTDIR)/libSlsReceiver.so: $(OBJS) - $(CXX) -shared -Wl,-soname,libSlsReceiver.so -o libSlsReceiver.so $(OBJS) -lc $(INCLUDES) $(DFLAGS) $(FLAGS) $(EPICSFLAGS) -L/usr/lib64 -lpthread + $(CXX) -shared -Wl,-soname,libSlsReceiver.so -o libSlsReceiver.so $(OBJS) -lc $(INCLUDES) $(DFLAGS) $(FLAGS) $(EPICSFLAGS) -L/usr/lib64 -lpthread $(shell test -d $(DESTDIR) || mkdir -p $(DESTDIR)) mv libSlsReceiver.so $(DESTDIR) diff --git a/slsReceiverSoftware/slsReceiver/Makefile b/slsReceiverSoftware/slsReceiver/Makefile index b4a681c3f..0592e962e 100644 --- a/slsReceiverSoftware/slsReceiver/Makefile +++ b/slsReceiverSoftware/slsReceiver/Makefile @@ -39,26 +39,26 @@ $(DESTDIR)/sslsReceiver: lib $(CXX) -static -o $@ $(SRC_CLNT) $(FLAGS) $(INCLUDES) $(CLAGS) $(LIBS) $(LDFLAGRXR) -$(DESTDIR)/slsReceiver: eigerReceiver lib +$(DESTDIR)/slsReceiver: lib echo "AAAAAAAAAAAA" $(CXX) -o $@ $(SRC_CLNT) $(FLAGS) $(INCLUDES) $(CLAGS) $(LIBS) $(LDFLAGRXR) -fPIC $(CXX) -o $@ $(SRC_CLNT) $(FLAGS) $(INCLUDES) $(CLAGS) $(LIBS) $(LDFLAGRXR) -fPIC #$(EIGERFLAGS) -ifeq ($(EIGERSLS), yes) -eigerReceiver: -# $(CXX) $(FLAGS) $(CFLAGS) -fPIC -c -o eigerReceiverTest.o eigerReceiver/eigerReceiverTest.cpp $(EIGERFLAGS) +#ifeq ($(EIGERSLS), yes) +#eigerReceiver: +# $(CXX) $(FLAGS) $(CFLAGS) -fPIC -c -o eigerReceiverTest.o eigerReceiver/eigerReceiverTest.cpp #$(EIGERFLAGS) # $(CXX) $(FLAGS) $(CFLAGS) -fPIC -c -o eigerReceiver.o eigerReceiver/eigerReceiver.cpp $(EIGERFLAGS) # $(CXX) eigerReceiverTest.o eigerReceiver.o -o eigerReceiver/eigerReceiverTest $(EIGERFLAGS) - $(CXX) $(FLAGS) $(CFLAGS) $(INCLUDES) -fPIC -c -o eigerReceiver.o eigerReceiverImplementation.cpp $(EIGERFLAGS) -else ifeq ($(ROOTSLS), yes) -eigerReceiver: eigerReceiver/eigerReceiverDummy.cpp - echo "Compiling with root" - $(CXX) $(FLAGS) $(CFLAGS) -fPIC -c -o eigerReceiver.o eigerReceiver/eigerReceiverDummy.cpp $(ROOTFLAGS) -else -eigerReceiver: eigerReceiver/eigerReceiverDummy.cpp - $(CXX) $(FLAGS) $(CFLAGS) $(INCLUDES) -fPIC -c -o eigerReceiver.o eigerReceiver/eigerReceiverDummy.cpp -endif +# $(CXX) $(FLAGS) $(CFLAGS) $(INCLUDES) -fPIC -c -o eigerReceiver.o eigerReceiverImplementation.cpp $(EIGERFLAGS) +#else ifeq ($(ROOTSLS), yes) +#eigerReceiver: eigerReceiver/eigerReceiverDummy.cpp +# echo "Compiling with root" +# $(CXX) $(FLAGS) $(CFLAGS) -fPIC -c -o eigerReceiver.o eigerReceiver/eigerReceiverDummy.cpp $(ROOTFLAGS) +#else +#eigerReceiver: eigerReceiver/eigerReceiverDummy.cpp +# $(CXX) $(FLAGS) $(CFLAGS) $(INCLUDES) -fPIC -c -o eigerReceiver.o eigerReceiver/eigerReceiverDummy.cpp +#endif lib: cd ../ && $(MAKE) DESTDIR=../bin LIBDIR=../bin diff --git a/slsReceiverSoftware/slsReceiver/UDPBaseImplementation.cpp b/slsReceiverSoftware/slsReceiver/UDPBaseImplementation.cpp index aa0aa77e1..2cb7773cc 100644 --- a/slsReceiverSoftware/slsReceiver/UDPBaseImplementation.cpp +++ b/slsReceiverSoftware/slsReceiver/UDPBaseImplementation.cpp @@ -20,12 +20,10 @@ #include //set precision #include //munmap - - #include #include - +//#include "utilities.h" using namespace std; @@ -216,90 +214,9 @@ void UDPBaseImplementation::initializeMembers(){ } + int UDPBaseImplementation::setDetectorType(detectorType det){ - cout << "Setting Receiver Type " << endl; - - deleteMembers(); - initializeMembers(); - - myDetectorType = det; - - switch(myDetectorType){ - case GOTTHARD: - cout << endl << "***** This is a GOTTHARD Receiver *****" << endl << endl; - break; - case MOENCH: - cout << endl << "***** This is a MOENCH Receiver *****" << endl << endl; - break; - case EIGER: - cout << endl << "***** This is a EIGER Receiver *****" << endl << endl; - break; - default: - cout << endl << "***** Unknown Receiver *****" << endl << endl; - return FAIL; - break; - } - - //moench variables - if(myDetectorType == GOTTHARD){ - fifosize = GOTTHARD_FIFO_SIZE; - packetsPerFrame = GOTTHARD_PACKETS_PER_FRAME; - onePacketSize = GOTTHARD_ONE_PACKET_SIZE; - frameSize = GOTTHARD_BUFFER_SIZE; - bufferSize = GOTTHARD_BUFFER_SIZE; - maxPacketsPerFile = MAX_FRAMES_PER_FILE * GOTTHARD_PACKETS_PER_FRAME; - frameIndexMask = GOTTHARD_FRAME_INDEX_MASK; - frameIndexOffset = GOTTHARD_FRAME_INDEX_OFFSET; - packetIndexMask = GOTTHARD_PACKET_INDEX_MASK; - }else if(myDetectorType == MOENCH){ - fifosize = MOENCH_FIFO_SIZE; - packetsPerFrame = MOENCH_PACKETS_PER_FRAME; - onePacketSize = MOENCH_ONE_PACKET_SIZE; - frameSize = MOENCH_BUFFER_SIZE; - bufferSize = MOENCH_BUFFER_SIZE; - maxPacketsPerFile = MOENCH_MAX_FRAMES_PER_FILE * MOENCH_PACKETS_PER_FRAME; - frameIndexMask = MOENCH_FRAME_INDEX_MASK; - frameIndexOffset = MOENCH_FRAME_INDEX_OFFSET; - packetIndexMask = MOENCH_PACKET_INDEX_MASK; - } - else if(myDetectorType == EIGER){ - fifosize = EIGER_FIFO_SIZE; - packetsPerFrame = EIGER_ONE_GIGA_CONSTANT * dynamicRange * EIGER_MAX_PORTS; - onePacketSize = EIGER_ONE_GIGA_ONE_PACKET_SIZE; - frameSize = onePacketSize * packetsPerFrame; - bufferSize = (frameSize/EIGER_MAX_PORTS) + EIGER_HEADER_LENGTH;//everything one port gets (img header plus packets) - maxPacketsPerFile = EIGER_MAX_FRAMES_PER_FILE * packetsPerFrame; - frameIndexMask = EIGER_FRAME_INDEX_MASK; - frameIndexOffset = EIGER_FRAME_INDEX_OFFSET; - packetIndexMask = EIGER_PACKET_INDEX_MASK; - - pthread_mutex_lock(&status_mutex); - listeningthreads_mask = 0x0; - pthread_mutex_unlock(&(status_mutex)); - if(thread_started) - createListeningThreads(true); - - numListeningThreads = MAX_NUM_LISTENING_THREADS; - } - latestData = new char[frameSize]; - - - setupFifoStructure(); - - if(createListeningThreads() == FAIL){ - cout << "ERROR: Could not create listening thread" << endl; - exit (-1); - } - - if(createWriterThreads() == FAIL){ - cout << "ERROR: Could not create writer threads" << endl; - exit (-1); - } - - setThreadPriorities(); - - cout << "Ready..." << endl; - + cout << "[WARNING] This is a base implementation, " << __func__ << " not correctly implemented" << endl; return OK; } @@ -327,6 +244,7 @@ uint32_t UDPBaseImplementation::getFrameIndex(){ return frameIndex; } + uint32_t UDPBaseImplementation::getAcquisitionIndex(){ if(!totalPacketsCaught) acquisitionIndex=-1; @@ -343,20 +261,17 @@ void UDPBaseImplementation::resetTotalFramesCaught(){ } - - - - - - - /*file parameters*/ char* UDPBaseImplementation::getFilePath() const{ - return (char*)filePath; + FILE_LOG(logWARNING) << "[WARNING] This is a base implementation, " << __func__ << " could have no effects.x" << endl; + return (char*)filePath; } char* UDPBaseImplementation::setFilePath(const char c[]){ + cout << "[WARNING] This is a base implementation, " << __func__ << " could have no effects." << endl; + + /* if(strlen(c)){ //check if filepath exists struct stat st; @@ -367,6 +282,7 @@ char* UDPBaseImplementation::setFilePath(const char c[]){ cout << "FilePath does not exist:" << filePath << endl; } } + */ return getFilePath(); } @@ -376,8 +292,11 @@ char* UDPBaseImplementation::getFileName() const{ } char* UDPBaseImplementation::setFileName(const char c[]){ - if(strlen(c)) + cout << "[WARNING] This is a base implementation, " << __func__ << " could have no effects." << endl; + /* + if(strlen(c)) strcpy(fileName,c); + */ return getFileName(); } @@ -387,13 +306,17 @@ int UDPBaseImplementation::getFileIndex(){ } int UDPBaseImplementation::setFileIndex(int i){ + cout << "[WARNING] This is a base implementation, " << __func__ << " could have no effects." << endl; + /* if(i>=0) fileIndex = i; + */ return getFileIndex(); } int UDPBaseImplementation::setFrameIndexNeeded(int i){ + cout << "[WARNING] This is a base implementation, " << __func__ << " could have no effects." << endl; frameIndexNeeded = i; return frameIndexNeeded; } diff --git a/slsReceiverSoftware/slsReceiver/UDPBaseImplementation.h b/slsReceiverSoftware/slsReceiver/UDPBaseImplementation.h index 8a1f84178..7b9068a63 100644 --- a/slsReceiverSoftware/slsReceiver/UDPBaseImplementation.h +++ b/slsReceiverSoftware/slsReceiver/UDPBaseImplementation.h @@ -28,7 +28,6 @@ #include #include - /** * @short does all the functions for a receiver, set/get parameters, start/stop etc. */ diff --git a/slsReceiverSoftware/slsReceiver/UDPInterface.cpp b/slsReceiverSoftware/slsReceiver/UDPInterface.cpp index b82d497b6..4a14933ae 100644 --- a/slsReceiverSoftware/slsReceiver/UDPInterface.cpp +++ b/slsReceiverSoftware/slsReceiver/UDPInterface.cpp @@ -22,6 +22,7 @@ using namespace std; #include "UDPInterface.h" #include "UDPBaseImplementation.h" +#include "UDPStandardImplementation.h" @@ -30,7 +31,9 @@ using namespace std; UDPInterface * UDPInterface::create(string receiver_type){ if (receiver_type == "standard") - return new UDPBaseImplementation(); + return new UDPStandardImplementation(); + //else if (receiver_type == "REST") + // return new UDPRESTImplementation(); else{ cout << "[ERROR] UDP interface not supported, using standard implementation" << endl; return new UDPBaseImplementation(); diff --git a/slsReceiverSoftware/slsReceiver/UDPInterface.h b/slsReceiverSoftware/slsReceiver/UDPInterface.h index 74f471ae0..77cfe3e7e 100644 --- a/slsReceiverSoftware/slsReceiver/UDPInterface.h +++ b/slsReceiverSoftware/slsReceiver/UDPInterface.h @@ -16,6 +16,9 @@ #include "receiver_defs.h" #include "MySocketTCP.h" +#include "utilities.h" + + /* void print_not_implemented(string method_name){ std::cout << "[WARNING] Method " << method_name << " not implemented!" << std::endl; diff --git a/slsReceiverSoftware/slsReceiver/main.cpp b/slsReceiverSoftware/slsReceiver/main.cpp index 87d947a7d..14fb01d0e 100644 --- a/slsReceiverSoftware/slsReceiver/main.cpp +++ b/slsReceiverSoftware/slsReceiver/main.cpp @@ -6,6 +6,9 @@ #include #include + +#include "utilities.h" + using namespace std; diff --git a/slsReceiverSoftware/slsReceiver/slsReceiver.cpp b/slsReceiverSoftware/slsReceiver/slsReceiver.cpp index fd1223b71..5dbeaea32 100644 --- a/slsReceiverSoftware/slsReceiver/slsReceiver.cpp +++ b/slsReceiverSoftware/slsReceiver/slsReceiver.cpp @@ -12,9 +12,7 @@ #include #include "slsReceiver.h" -#include "UDPInterface.h" - -#include "utilities.h" +//#include "UDPInterface.h" using namespace std; @@ -35,6 +33,7 @@ slsReceiver::slsReceiver(int argc, char *argv[], int &success){ int tcpip_port_no = 1984; success=OK; string fname = ""; + string udp_interface_type = "standard"; //parse command line for config static struct option long_options[] = { @@ -42,6 +41,7 @@ slsReceiver::slsReceiver(int argc, char *argv[], int &success){ //{"verbose", no_argument, &verbose_flag, 1}, /* These options don’t set a flag. We distinguish them by their indices. */ + {"type", required_argument, 0, 't'}, {"config", required_argument, 0, 'f'}, {"rx_tcpport", required_argument, 0, 'b'}, {"help", no_argument, 0, 'h'}, @@ -52,7 +52,7 @@ slsReceiver::slsReceiver(int argc, char *argv[], int &success){ int c; while ( c != -1 ){ - c = getopt_long (argc, argv, "bfh", long_options, &option_index); + c = getopt_long (argc, argv, "bfht", long_options, &option_index); /* Detect the end of the options. */ if (c == -1) @@ -61,12 +61,15 @@ slsReceiver::slsReceiver(int argc, char *argv[], int &success){ switch(c){ case 'f': fname = optarg; - cout << long_options[option_index].name << " " << optarg << endl; + //cout << long_options[option_index].name << " " << optarg << endl; break; case 'b': - sscanf(optarg,"%d",&tcpip_port_no); - cout << long_options[option_index].name << " " << optarg << endl; + sscanf(optarg, "%d", &tcpip_port_no); + break; + + case 't': + udp_interface_type = optarg; break; case 'h': @@ -74,6 +77,7 @@ slsReceiver::slsReceiver(int argc, char *argv[], int &success){ help_message += """usage: slsReceiver --config config_fname [--rx_tcpport port]\n\n"""; help_message += """\t--config:\t configuration filename for SLS Detector receiver\n"""; help_message += """\t--rx_tcpport:\t TCP Communication Port with the client. Default: 1954.\n\n"""; + help_message += """\t--type:\t Type of the receiver. Possible arguments are: standard, REST. Default: standard.\n\n"""; cout << help_message << endl; break; @@ -85,30 +89,35 @@ slsReceiver::slsReceiver(int argc, char *argv[], int &success){ success = FAIL; if((!fname.empty()) && (success == OK)){ - VERBOSE_PRINT("config file name " + fname ); + FILE_LOG(logINFO) << "config file name " << fname; success = read_config_file(fname, &tcpip_port_no); - VERBOSE_PRINT("Read configuration file of " + iline + " lines"); + //VERBOSE_PRINT("Read configuration file of " + iline + " lines"); } else { - cout << "Error opening configuration file " << fname << endl; + FILE_LOG(logERROR) << "Error opening configuration file " << fname ; success = FAIL; } if(success != OK){ - cout << "Failed: see output above for more information " << endl; + FILE_LOG(logERROR) << "Failed: see output above for more information " ; } if (success==OK){ cout << "SLS Receiver starting" << endl; - udp_interface = UDPInterface::create("standard"); + udp_interface = UDPInterface::create(udp_interface_type); tcpipInterface = new slsReceiverTCPIPInterface(success, udp_interface, tcpip_port_no); //tcp ip interface } } -slsReceiver::~slsReceiver() {if(udp_interface) delete udp_interface; if(tcpipInterface) delete tcpipInterface;} +slsReceiver::~slsReceiver() { + if(udp_interface) + delete udp_interface; + if(tcpipInterface) + delete tcpipInterface; +} int slsReceiver::start() { diff --git a/slsReceiverSoftware/slsReceiver/slsReceiver.h b/slsReceiverSoftware/slsReceiver/slsReceiver.h index 0cd195c72..4eb024776 100644 --- a/slsReceiverSoftware/slsReceiver/slsReceiver.h +++ b/slsReceiverSoftware/slsReceiver/slsReceiver.h @@ -8,11 +8,11 @@ #include "slsReceiverTCPIPInterface.h" #include "UDPInterface.h" -#include "UDPBaseImplementation.h" +//#include "UDPBaseImplementation.h" #include "receiver_defs.h" #include "MySocketTCP.h" - +//#include "utilities.h" /** From 59980a4b9033149adc318c0d470feb596b8959af Mon Sep 17 00:00:00 2001 From: Sala Leonardo Date: Tue, 9 Sep 2014 15:46:58 +0200 Subject: [PATCH 023/474] beginning of reimplementation of the REST interface --- slsReceiverSoftware/Makefile | 4 +- .../slsReceiver/UDPBaseImplementation.cpp | 195 +----------------- .../slsReceiver/UDPInterface.cpp | 6 +- .../slsReceiver/slsReceiver.cpp | 2 +- 4 files changed, 18 insertions(+), 189 deletions(-) diff --git a/slsReceiverSoftware/Makefile b/slsReceiverSoftware/Makefile index 2b159dad3..07de13672 100644 --- a/slsReceiverSoftware/Makefile +++ b/slsReceiverSoftware/Makefile @@ -14,7 +14,7 @@ DFLAGS= -g -DDACS_INT -DSLS_RECEIVER_UDP_FUNCTIONS INCLUDES?= -I. -Iincludes -IMySocketTCP -IslsReceiver -IslsDetectorCalibration -I$(ASM) #-IslsReceiverInterface -SRC_CLNT= MySocketTCP/MySocketTCP.cpp slsReceiver/UDPInterface.cpp slsReceiver/UDPBaseImplementation.cpp slsReceiver/UDPStandardImplementation.cpp slsReceiver/slsReceiverTCPIPInterface.cpp slsReceiver/slsReceiver.cpp slsReceiver/slsReceiverUsers.cpp includes/utilities.h +SRC_CLNT= MySocketTCP/MySocketTCP.cpp slsReceiver/UDPInterface.cpp slsReceiver/UDPBaseImplementation.cpp slsReceiver/UDPStandardImplementation.cpp slsReceiver/UDPRESTImplementation.cpp slsReceiver/slsReceiverTCPIPInterface.cpp slsReceiver/slsReceiver.cpp slsReceiver/slsReceiverUsers.cpp includes/utilities.h #slsReceiverInterface/receiverInterface.cpp #slsReceiver/slsReceiverUDPFunctions.cpp @@ -35,7 +35,7 @@ intdoc: $(SRC_H) $(SRC_CLNT) ifeq ($(ROOTSLS),yes) echo "with root" $(CXX) -DROOTSLS -o $@ -c $< $(INCLUDES) $(DFLAGS) $(ROOTFLAGS) -fPIC $(EPICSFLAGS) -L/usr/lib64/ #$(FLAGS) -else +else echo "without root" $(CXX) -o $@ -c $< $(INCLUDES) $(DFLAGS) -fPIC $(EPICSFLAGS) -lpthread #$(FLAGS) endif diff --git a/slsReceiverSoftware/slsReceiver/UDPBaseImplementation.cpp b/slsReceiverSoftware/slsReceiver/UDPBaseImplementation.cpp index 2cb7773cc..14207ce65 100644 --- a/slsReceiverSoftware/slsReceiver/UDPBaseImplementation.cpp +++ b/slsReceiverSoftware/slsReceiver/UDPBaseImplementation.cpp @@ -29,189 +29,19 @@ using namespace std; -UDPBaseImplementation::UDPBaseImplementation(): - thread_started(0), - eth(NULL), - latestData(NULL), - guiFileName(NULL), - guiFrameNumber(0), - tengigaEnable(0){ - - for(int i=0;i /proc/sys/net/core/rmem_max")) - cout << "\nWARNING: Could not change socket receiver buffer size in file /proc/sys/net/core/rmem_max" << endl; - else if(system("echo 250000 > /proc/sys/net/core/netdev_max_backlog")) - cout << "\nWARNING: Could not change max length of input queue in file /proc/sys/net/core/netdev_max_backlog" << endl; - /** permanent setting heiner - net.core.rmem_max = 104857600 # 100MiB - net.core.netdev_max_backlog = 250000 - sysctl -p - // from the manual - sysctl -w net.core.rmem_max=16777216 - sysctl -w net.core.netdev_max_backlog=250000 - */ -} - - - -UDPBaseImplementation::~UDPBaseImplementation(){ - createListeningThreads(true); - createWriterThreads(true); - deleteMembers(); -} +UDPBaseImplementation::UDPBaseImplementation(){} +UDPBaseImplementation::~UDPBaseImplementation(){} void UDPBaseImplementation::deleteMembers(){ - //kill threads - if(thread_started){ - createListeningThreads(true); - createWriterThreads(true); - } - - for(int i=0;i Date: Tue, 9 Sep 2014 16:37:35 +0200 Subject: [PATCH 024/474] added logger --- slsReceiverSoftware/includes/logger.h | 172 +++++++++++++++++++++++ slsReceiverSoftware/includes/utilities.h | 29 ++++ 2 files changed, 201 insertions(+) create mode 100644 slsReceiverSoftware/includes/logger.h create mode 100644 slsReceiverSoftware/includes/utilities.h diff --git a/slsReceiverSoftware/includes/logger.h b/slsReceiverSoftware/includes/logger.h new file mode 100644 index 000000000..a230a5266 --- /dev/null +++ b/slsReceiverSoftware/includes/logger.h @@ -0,0 +1,172 @@ +#ifndef __LOG_H__ +#define __LOG_H__ + +#include +#include +#include + +inline std::string NowTime(); + +enum TLogLevel {logERROR, logWARNING, logINFO, logDEBUG, logDEBUG1, logDEBUG2, logDEBUG3, logDEBUG4}; + +template +class Log +{ +public: + Log(); + virtual ~Log(); + std::ostringstream& Get(TLogLevel level = logINFO); +public: + static TLogLevel& ReportingLevel(); + static std::string ToString(TLogLevel level); + static TLogLevel FromString(const std::string& level); +protected: + std::ostringstream os; +private: + Log(const Log&); + Log& operator =(const Log&); +}; + +template +Log::Log() +{ +} + +template +std::ostringstream& Log::Get(TLogLevel level) +{ + os << "- " << NowTime(); + os << " " << ToString(level) << ": "; + os << std::string(level > logDEBUG ? level - logDEBUG : 0, '\t'); + return os; +} + +template +Log::~Log() +{ + os << std::endl; + T::Output(os.str()); +} + +template +TLogLevel& Log::ReportingLevel() +{ + static TLogLevel reportingLevel = logDEBUG4; + return reportingLevel; +} + +template +std::string Log::ToString(TLogLevel level) +{ + static const char* const buffer[] = {"ERROR", "WARNING", "INFO", "DEBUG", "DEBUG1", "DEBUG2", "DEBUG3", "DEBUG4"}; + return buffer[level]; +} + +template +TLogLevel Log::FromString(const std::string& level) +{ + if (level == "DEBUG4") + return logDEBUG4; + if (level == "DEBUG3") + return logDEBUG3; + if (level == "DEBUG2") + return logDEBUG2; + if (level == "DEBUG1") + return logDEBUG1; + if (level == "DEBUG") + return logDEBUG; + if (level == "INFO") + return logINFO; + if (level == "WARNING") + return logWARNING; + if (level == "ERROR") + return logERROR; + Log().Get(logWARNING) << "Unknown logging level '" << level << "'. Using INFO level as default."; + return logINFO; +} + +class Output2FILE +{ +public: + static FILE*& Stream(); + static void Output(const std::string& msg); +}; + +inline FILE*& Output2FILE::Stream() +{ + static FILE* pStream = stderr; + return pStream; +} + +inline void Output2FILE::Output(const std::string& msg) +{ + FILE* pStream = Stream(); + if (!pStream) + return; + fprintf(pStream, "%s", msg.c_str()); + fflush(pStream); +} + +#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) +# if defined (BUILDING_FILELOG_DLL) +# define FILELOG_DECLSPEC __declspec (dllexport) +# elif defined (USING_FILELOG_DLL) +# define FILELOG_DECLSPEC __declspec (dllimport) +# else +# define FILELOG_DECLSPEC +# endif // BUILDING_DBSIMPLE_DLL +#else +# define FILELOG_DECLSPEC +#endif // _WIN32 + +class FILELOG_DECLSPEC FILELog : public Log {}; +//typedef Log FILELog; + +#ifndef FILELOG_MAX_LEVEL +#define FILELOG_MAX_LEVEL logDEBUG4 +#endif + +#define FILE_LOG(level) \ + if (level > FILELOG_MAX_LEVEL) ; \ + else if (level > FILELog::ReportingLevel() || !Output2FILE::Stream()) ; \ + else FILELog().Get(level) + +#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) + +#include + +inline std::string NowTime() +{ + const int MAX_LEN = 200; + char buffer[MAX_LEN]; + if (GetTimeFormatA(LOCALE_USER_DEFAULT, 0, 0, + "HH':'mm':'ss", buffer, MAX_LEN) == 0) + return "Error in NowTime()"; + + char result[100] = {0}; + static DWORD first = GetTickCount(); + sprintf(result, "%s.%03ld", buffer, (long)(GetTickCount() - first) % 1000); + return result; +} + +#else + +#include + +inline std::string NowTime() +{ + char buffer[11]; + time_t t; + time(&t); + tm r = {0}; + strftime(buffer, sizeof(buffer), "%X", localtime_r(&t, &r)); + struct timeval tv; + gettimeofday(&tv, 0); + char result[100] = {0}; + sprintf(result, "%s.%03ld", buffer, (long)tv.tv_usec / 1000); + return result; +} + +#endif //WIN32 + +#endif //__LOG_H__ diff --git a/slsReceiverSoftware/includes/utilities.h b/slsReceiverSoftware/includes/utilities.h new file mode 100644 index 000000000..e55d81598 --- /dev/null +++ b/slsReceiverSoftware/includes/utilities.h @@ -0,0 +1,29 @@ +#include +#include +#include +#include +using namespace std; + +/* uncomment next line to enable debug output */ +//#define EIGER_DEBUG + +/* macro for debug output http://stackoverflow.com/a/14256296 */ +#ifdef EIGER_DEBUG +#define DEBUG(x) do { std::cerr << x << std::endl; } while (0) +#else +#define DEBUG(x) +#endif + +#ifdef VERBOSE +#define VERBOSE_PRINT(x) do { std::cout << "[VERBOSE]" << x << std::endl; } while (0) +#else +#define VERBOSE_PRINT(x) +#endif + + + + + + +inline int read_config_file(string fname, int *tcpip_port_no); + From c62594c7abb4892efffe30f13835ea0c00fc473e Mon Sep 17 00:00:00 2001 From: Sala Leonardo Date: Tue, 9 Sep 2014 16:38:27 +0200 Subject: [PATCH 025/474] added REST and Standard implementations --- slsReceiverSoftware/slsReceiver/RestHelper.h | 295 +++ .../slsReceiver/UDPRESTImplementation.cpp | 2009 ++++++++++++++ .../slsReceiver/UDPRESTImplementation.h | 819 ++++++ .../slsReceiver/UDPStandardImplementation.cpp | 2330 +++++++++++++++++ .../slsReceiver/UDPStandardImplementation.h | 810 ++++++ 5 files changed, 6263 insertions(+) create mode 100644 slsReceiverSoftware/slsReceiver/RestHelper.h create mode 100644 slsReceiverSoftware/slsReceiver/UDPRESTImplementation.cpp create mode 100644 slsReceiverSoftware/slsReceiver/UDPRESTImplementation.h create mode 100644 slsReceiverSoftware/slsReceiver/UDPStandardImplementation.cpp create mode 100644 slsReceiverSoftware/slsReceiver/UDPStandardImplementation.h diff --git a/slsReceiverSoftware/slsReceiver/RestHelper.h b/slsReceiverSoftware/slsReceiver/RestHelper.h new file mode 100644 index 000000000..fc4056c43 --- /dev/null +++ b/slsReceiverSoftware/slsReceiver/RestHelper.h @@ -0,0 +1,295 @@ +/** + * @file RestHelper.h + * @author Leonardo Sala + * @date Tue Mar 25 09:28:19 2014 + * + * @brief + * + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "JsonBox/Value.h" + +#include +#include +#include +#include + +#define EIGER_DEBUG +#ifdef EIGER_DEBUG +#define DEBUG(x) do { std::cerr << "[DEBUG] " << x << std::endl; } while (0) +#else +#define DEBUG(x) +#endif + + +using namespace Poco::Net; +using namespace Poco; +using namespace std; + +class RestHelper { + public: + + RestHelper(int timeout=10, int n_tries=3){ + /** + * + * + * @param timeout default=10 + * @param n_tries default=3 + */ + + http_timeout = timeout; + n_connection_tries = n_tries; + } + + ~RestHelper(){}; + + + void set_connection_params(int timeout, int n_tries){ + http_timeout = timeout; + n_connection_tries = n_tries; + } + + + void get_connection_params(int *timeout, int *n_tries){ + *timeout = http_timeout; + *n_tries = n_connection_tries; + + } + + + void init(string hostname, int port){ + /** Initialize the RestHelper. Hostname and port parameters are not supposed to change. + * + * + * @param hostname FQDN of the host to connect to , e.g. www.iamfake.org, or sodoi.org + * @param port + * + * @return + */ + + //Check for http:// string + string proto_str = "http://"; + if( size_t found = hostname.find(proto_str) != string::npos ){ + char c1[hostname.size()-found-1]; + size_t length1 = hostname.copy(c1, hostname.size()-found-1, proto_str.size()); + c1[length1]='\0'; + hostname = c1; + } + + full_hostname = "http://"+hostname; + session = new HTTPClientSession(hostname,port ); + session->setKeepAliveTimeout( Timespan( http_timeout,0) ); + + }; + + + void init(string hostname_port){ + /** Initialize the RestHelper. Hostname_port parameters are not supposed to change. + * + * + * @param hostname FQDN and port of the host to connect to , e.g. www.iamfake.org:8080, or sodoi.org:1111. Default port is 8080 + * + * @return + */ + + //Check for http:// string + string proto_str = "http://"; + if( size_t found = hostname_port.find(proto_str) != string::npos ){ + char c1[hostname_port.size()-found-1]; + size_t length1 = hostname_port.copy(c1, hostname_port.size()-found-1, proto_str.size()); + c1[length1]='\0'; + hostname_port = c1; + } + + size_t found = hostname_port.rfind(":"); + char c1[ found ], c2[hostname_port.size()-found-1]; + string hostname; + size_t length1 = hostname_port.copy(c1, found); + + c1[length1]='\0'; + hostname = c1; + size_t length2 = hostname_port.copy(c2, found-1, found+1); + c2[length2]='\0'; + int port = atoi(c2); + + full_hostname = proto_str+hostname; + session = new HTTPClientSession(hostname,port ); + session->setKeepAliveTimeout( Timespan( http_timeout,0) ); + }; + + + int get_json(string request, string* answer){ + /** Retrieves a reply from the RESTful webservice. + * + * + * @param request Request without the hostname, e.g. if the full request would have been http://fake.org/fakemethod, request=fakemethod + * @param answer + * + * @return 0 if successful, -1 if failure happens. + */ + URI * uri = new URI(full_hostname+"/"+request); + string path(uri->getPathAndQuery()); + if (path.empty()) path = "/"; + + // send request + HTTPRequest req(HTTPRequest::HTTP_GET, path, HTTPMessage::HTTP_1_1); + req.setContentType("application/json\r\n"); + int code = send_request(session, req, answer); + delete uri; + return code; + }; + + + int get_json(string request, JsonBox::Value* json_value){ + /** + * + * + * @param request + * @param json_value + * + * @return + */ + URI *uri = new URI(full_hostname+"/"+request); + string path(uri->getPathAndQuery()); + if (path.empty()) path = "/"; + // send request + HTTPRequest req(HTTPRequest::HTTP_GET, path, HTTPMessage::HTTP_1_1); + req.setContentType("application/json\r\n"); + string answer; + int code = send_request(session, req, &answer); + if(code == 0 ) { + DEBUG("ANSWER " << answer ); + json_value->loadFromString(answer); + } + delete uri; + return code; + }; + + + int post_json(string request, string *answer, string request_body=""){ + /** + * + * + * @param request + * @param answer + * @param request_body Eventual arguments to the URL, e.g. action=login&name=mammamia + * + * @return + */ + //from: http://stackoverflow.com/questions/1499086/poco-c-net-ssl-how-to-post-https-request + URI *uri = new URI(full_hostname+"/"+request); + string path(uri->getPathAndQuery()); + if (path.empty()) path = "/"; + HTTPRequest req(HTTPRequest::HTTP_POST, path, HTTPMessage::HTTP_1_1 ); + req.setContentType("application/json\r\n"); + req.setContentLength( request.length() ); + + int code = send_request(session, req, answer, request_body); + delete uri; + return code; + } + + + int post_json(string request, JsonBox::Value* json_value, string request_body=""){ + /** + * + * + * @param request + * @param json_value + * @param request_body Eventual arguments to the URL, e.g. action=login&name=mammamia + * + * @return + */ + + URI *uri = new URI(full_hostname+"/"+request); + string path(uri->getPathAndQuery()); + if (path.empty()) path = "/"; + HTTPRequest req(HTTPRequest::HTTP_POST, path, HTTPMessage::HTTP_1_1 ); + //this does not work + //req.setContentType("application/json\r\n"); + //req.setContentLength( request.length() ); + string answer; + int code = send_request(session, req, &answer, request_body); + if(code==0){ + json_value->loadFromString(answer); + } + delete uri; + return code; + } + + + private: + + HTTPClientSession *session; + string full_hostname; + /// HTTP timeout in seconds, default is 8 + int http_timeout; + /// Number of connection tries + int n_connection_tries; + + + int send_request(HTTPClientSession *session, HTTPRequest &req, string *answer, string request_body=""){ + /** + * + * + * @param session + * @param req + * @param answer + * @param request_body + * + * @return + */ + + int n=0; + int code = -1; + while(nsendRequest( (req) ); + else{ + cout << request_body << endl; + ostream &os = session->sendRequest( req ) ; + os << request_body; + } + + HTTPResponse res; + istream &is = session->receiveResponse(res); + StreamCopier::copyToString(is, *answer); + code = res.getStatus(); + if (code != 200){ + cout << "HTTP ERROR " << res.getStatus() << ": " << res.getReason() << endl; + code = -1; + } + else + code = 0; + return code; + } + catch (exception& e){ + cout << "Exception connecting to "<< full_hostname << ": "<< e.what() << ", sleeping 5 seconds (" << n << "/"< // SIGINT +#include // stat +#include // socket(), bind(), listen(), accept(), shut down +#include // sock_addr_in, htonl, INADDR_ANY +#include // exit() +#include //set precision +#include //munmap + +#include +#include + +//#include "utilities.h" + +using namespace std; + + + +UDPRESTImplementation::UDPRESTImplementation() : isInitialized(false), status(slsReceiverDefs::ERROR) {} + + +UDPRESTImplementation::~UDPRESTImplementation(){} + + +void UDPRESTImplementation::initialize(const char *detectorHostName){ + + string name; + if (detectorHostName != NULL) + name = detectorHostName; + + if (name.empty()) { + FILE_LOG(logDEBUG) << "initialize(): can't initialize with empty string or NULL for detectorHostname"; + } else if (isInitialized == true) { + FILE_LOG(logDEBUG) << "initialize(): already initialized, can't initialize several times"; + } else { + FILE_LOG(logDEBUG) << "initialize(): initialize() with: detectorHostName=" << name; + strcpy(detHostname,detectorHostName); + //init_config.detectorHostname = name; + + //REST call - hardcoded + //RestHelper rest ; + rest->init(detHostname, 8080); + std::string answer; + int code = rest->get_json("status", &answer); + if (code != 0){ + //throw -1; + std::cout << "I SHOULD THROW AN EXCEPTION!!!" << std::endl; + } + else{ + isInitialized = true; + status = slsReceiverDefs::IDLE; + } + std::cout << "Answer: " << answer << std::endl; + + + /* + std::std::cout << string << std::endl; << "---- REST test 3: true, json object "<< std::endl; + JsonBox::Value json_value; + code = rest.get_json("status", &json_value); + std::cout << "JSON " << json_value["status"] << std::endl; + */ + } +} + + +int UDPRESTImplementation::setDetectorType(detectorType det){ + cout << "[WARNING] This is a base implementation, " << __func__ << " not correctly implemented" << endl; + return OK; +} + + + +/*Frame indices and numbers caught*/ + +bool UDPRESTImplementation::getAcquistionStarted(){return acqStarted;}; + +bool UDPRESTImplementation::getMeasurementStarted(){return measurementStarted;}; + +int UDPRESTImplementation::getFramesCaught(){return (packetsCaught/packetsPerFrame);} + +int UDPRESTImplementation::getTotalFramesCaught(){return (totalPacketsCaught/packetsPerFrame);} + +uint32_t UDPRESTImplementation::getStartFrameIndex(){return startFrameIndex;} + +uint32_t UDPRESTImplementation::getFrameIndex(){ + if(!packetsCaught) + frameIndex=-1; + else + frameIndex = currframenum - startFrameIndex; + return frameIndex; +} + + +uint32_t UDPRESTImplementation::getAcquisitionIndex(){ + if(!totalPacketsCaught) + acquisitionIndex=-1; + else + acquisitionIndex = currframenum - startAcquisitionIndex; + return acquisitionIndex; +} + + +void UDPRESTImplementation::resetTotalFramesCaught(){ + acqStarted = false; + startAcquisitionIndex = 0; + totalPacketsCaught = 0; +} + + +/*file parameters*/ +int UDPRESTImplementation::getFileIndex(){ + return fileIndex; +} + +int UDPRESTImplementation::setFileIndex(int i){ + cout << "[WARNING] This is a base implementation, " << __func__ << " could have no effects." << endl; + /* + if(i>=0) + fileIndex = i; + */ + return getFileIndex(); +} + + +int UDPRESTImplementation::setFrameIndexNeeded(int i){ + cout << "[WARNING] This is a base implementation, " << __func__ << " could have no effects." << endl; + frameIndexNeeded = i; + return frameIndexNeeded; +} + + +/* +int UDPRESTImplementation::getEnableFileWrite() const{ + return enableFileWrite; +} + +int UDPRESTImplementation::setEnableFileWrite(int i){ + enableFileWrite=i; + return getEnableFileWrite(); +} + +int UDPRESTImplementation::getEnableOverwrite() const{ + return overwrite; +} + +int UDPRESTImplementation::setEnableOverwrite(int i){ + overwrite=i; + return getEnableOverwrite(); +} +*/ + + + + +/*other parameters*/ + +slsReceiverDefs::runStatus UDPRESTImplementation::getStatus() const{ + return status; +} + + + +/* +char *UDPRESTImplementation::getDetectorHostname() const{ + return (char*)detHostname; +} +*/ + +void UDPRESTImplementation::setEthernetInterface(char* c){ + strcpy(eth,c); +} + + +void UDPRESTImplementation::setUDPPortNo(int p){ + for(int i=0;i= 0) + numberOfFrames = fnum; + + return getNumberOfFrames(); +} +*/ +/* +int UDPRESTImplementation::getScanTag() const{ + return scanTag; +} +*/ + +/* +int32_t UDPRESTImplementation::setScanTag(int32_t stag){ + if(stag >= 0) + scanTag = stag; + + return getScanTag(); +} +*/ + +int32_t UDPRESTImplementation::setDynamicRange(int32_t dr){ + cout << "Setting Dynamic Range" << endl; + + int olddr = dynamicRange; + if(dr >= 0){ + dynamicRange = dr; + } + + return getDynamicRange(); +} + + + +int UDPRESTImplementation::setShortFrame(int i){ + shortFrame=i; + + if(shortFrame!=-1){ + bufferSize = GOTTHARD_SHORT_ONE_PACKET_SIZE; + frameSize = GOTTHARD_SHORT_BUFFER_SIZE; + maxPacketsPerFile = SHORT_MAX_FRAMES_PER_FILE * GOTTHARD_SHORT_PACKETS_PER_FRAME; + packetsPerFrame = GOTTHARD_SHORT_PACKETS_PER_FRAME; + frameIndexMask = GOTTHARD_SHORT_FRAME_INDEX_MASK; + frameIndexOffset = GOTTHARD_SHORT_FRAME_INDEX_OFFSET; + + }else{ + onePacketSize = GOTTHARD_ONE_PACKET_SIZE; + bufferSize = GOTTHARD_BUFFER_SIZE; + frameSize = GOTTHARD_BUFFER_SIZE; + maxPacketsPerFile = MAX_FRAMES_PER_FILE * GOTTHARD_PACKETS_PER_FRAME; + packetsPerFrame = GOTTHARD_PACKETS_PER_FRAME; + frameIndexMask = GOTTHARD_FRAME_INDEX_MASK; + frameIndexOffset = GOTTHARD_FRAME_INDEX_OFFSET; + } + + + deleteFilter(); + if(dataCompression) + setupFilter(); + + return shortFrame; +} + + +int UDPRESTImplementation::setNFrameToGui(int i){ + if(i>=0){ + nFrameToGui = i; + setupFifoStructure(); + } + return nFrameToGui; +} + + + +int64_t UDPRESTImplementation::setAcquisitionPeriod(int64_t index){ + + if(index >= 0){ + if(index != acquisitionPeriod){ + acquisitionPeriod = index; + setupFifoStructure(); + } + } + return acquisitionPeriod; +} + + +bool UDPRESTImplementation::getDataCompression(){return dataCompression;} + +int UDPRESTImplementation::enableDataCompression(bool enable){ + cout << "Data compression "; + if(enable) + cout << "enabled" << endl; + else + cout << "disabled" << endl; +#ifdef MYROOT1 + cout << " WITH ROOT" << endl; +#else + cout << " WITHOUT ROOT" << endl; +#endif + //delete filter for the current number of threads + deleteFilter(); + + dataCompression = enable; + pthread_mutex_lock(&status_mutex); + writerthreads_mask = 0x0; + pthread_mutex_unlock(&(status_mutex)); + + createWriterThreads(true); + + if(enable) + numWriterThreads = MAX_NUM_WRITER_THREADS; + else + numWriterThreads = 1; + + if(createWriterThreads() == FAIL){ + cout << "ERROR: Could not create writer threads" << endl; + return FAIL; + } + setThreadPriorities(); + + + if(enable) + setupFilter(); + + return OK; +} + + + + + + + + + + + + +/*other functions*/ + + +void UDPRESTImplementation::deleteFilter(){ + int i; + cmSub=NULL; + + for(i=0;i(receiverdata[i], csize, sigma, sign, cmSub); + +} + + + +//LEO: it is not clear to me.. +void UDPRESTImplementation::setupFifoStructure(){ + + int64_t i; + int oldn = numJobsPerThread; + + //if every nth frame mode + if(nFrameToGui) + numJobsPerThread = nFrameToGui; + + //random nth frame mode + else{ + if(!acquisitionPeriod) + i = SAMPLE_TIME_IN_NS; + else + i = SAMPLE_TIME_IN_NS/acquisitionPeriod; + if (i > MAX_JOBS_PER_THREAD) + numJobsPerThread = MAX_JOBS_PER_THREAD; + else if (i < 1) + numJobsPerThread = 1; + else + numJobsPerThread = i; + } + + //if same, return + if(oldn == numJobsPerThread) + return; + + if(myDetectorType == EIGER) + numJobsPerThread = 1; + + //otherwise memory too much if numjobsperthread is at max = 1000 + fifosize = GOTTHARD_FIFO_SIZE; + if(myDetectorType == MOENCH) + fifosize = MOENCH_FIFO_SIZE; + else if(myDetectorType == EIGER) + fifosize = EIGER_FIFO_SIZE; + + if(fifosize % numJobsPerThread) + fifosize = (fifosize/numJobsPerThread)+1; + else + fifosize = fifosize/numJobsPerThread; + + + cout << "Number of Frames per buffer:" << numJobsPerThread << endl; + cout << "Fifo Size:" << fifosize << endl; + + /* + //for testing + numJobsPerThread = 3; fifosize = 11; + */ + + for(int i=0;iisEmpty()) + fifoFree[i]->pop(buffer[i]); + delete fifoFree[i]; + } + if(fifo[i]) delete fifo[i]; + if(mem0[i]) free(mem0[i]); + fifoFree[i] = new CircularFifo(fifosize); + fifo[i] = new CircularFifo(fifosize); + + + //allocate memory + mem0[i]=(char*)malloc((bufferSize * numJobsPerThread + HEADER_SIZE_NUM_TOT_PACKETS)*fifosize); + /** shud let the client know about this */ + if (mem0[i]==NULL){ + cout<<"++++++++++++++++++++++ COULD NOT ALLOCATE MEMORY FOR LISTENING !!!!!!!+++++++++++++++++++++" << endl; + exit(-1); + } + buffer[i]=mem0[i]; + //push the addresses into freed fifoFree and writingFifoFree + while (buffer[i]<(mem0[i]+(bufferSize * numJobsPerThread + HEADER_SIZE_NUM_TOT_PACKETS)*(fifosize-1))) { + fifoFree[i]->push(buffer[i]); + buffer[i]+=(bufferSize * numJobsPerThread + HEADER_SIZE_NUM_TOT_PACKETS); + } + } + cout << "Fifo structure(s) reconstructed" << endl; +} + + + + + + + +/** acquisition functions */ + +void UDPRESTImplementation::readFrame(char* c,char** raw, uint32_t &fnum){ + //point to gui data + if (guiData == NULL) + guiData = latestData; + + //copy data and filename + strcpy(c,guiFileName); + fnum = guiFrameNumber; + + + //could not get gui data + if(!guiDataReady){ + *raw = NULL; + } + //data ready, set guidata to receive new data + else{ + *raw = guiData; + guiData = NULL; + + pthread_mutex_lock(&dataReadyMutex); + guiDataReady = 0; + pthread_mutex_unlock(&dataReadyMutex); + if((nFrameToGui) && (writerthreads_mask)){ + /*if(nFrameToGui){*/ + //release after getting data + sem_post(&smp); + } + } +} + + + + + +void UDPRESTImplementation::copyFrameToGui(char* startbuf[], uint32_t fnum, char* buf){ + + //random read when gui not ready + if((!nFrameToGui) && (!guiData)){ + pthread_mutex_lock(&dataReadyMutex); + guiDataReady=0; + pthread_mutex_unlock(&dataReadyMutex); + } + + //random read or nth frame read, gui needs data now + else{ + /* + //nth frame read, block current process if the guireader hasnt read it yet + if(nFrameToGui) + sem_wait(&smp); +*/ + pthread_mutex_lock(&dataReadyMutex); + guiDataReady=0; + //eiger + if(startbuf != NULL){ + int offset = 0; + int size = frameSize/EIGER_MAX_PORTS; + for(int j=0;jgetErrorStatus(); + if(iret){ +#ifdef VERBOSE + cout << "Could not create UDP socket on port " << server_port[i] << " error:" << iret << endl; +#endif + return FAIL; + } + } + + return OK; +} + + + + + + + +int UDPRESTImplementation::shutDownUDPSockets(){ + for(int i=0;iShutDownSocket(); + delete udpSocket[i]; + udpSocket[i] = NULL; + } + } + return OK; +} + + + + + +int UDPRESTImplementation::createListeningThreads(bool destroy){ + int i; + void* status; + + killAllListeningThreads = 0; + + pthread_mutex_lock(&status_mutex); + listeningthreads_mask = 0x0; + pthread_mutex_unlock(&(status_mutex)); + + if(!destroy){ + + //start listening threads + cout << "Creating Listening Threads(s)"; + + currentListeningThreadIndex = -1; + + for(i = 0; i < numListeningThreads; ++i){ + sem_init(&listensmp[i],1,0); + thread_started = 0; + currentListeningThreadIndex = i; + if(pthread_create(&listening_thread[i], NULL,startListeningThread, (void*) this)){ + cout << "Could not create listening thread with index " << i << endl; + return FAIL; + } + while(!thread_started); + cout << "."; + cout << flush; + } +#ifdef VERBOSE + cout << "Listening thread(s) created successfully." << endl; +#else + cout << endl; +#endif + }else{ + cout<<"Destroying Listening Thread(s)"<initEventTree(temp, &iframe); + //resets the pedestalSubtraction array and the commonModeSubtraction + singlePhotonDet[ithr]->newDataSet(); + if(myFile[ithr]==NULL){ + cout<<"file null"<IsOpen()){ + cout<<"file not open"< DO_NOTHING){ + //close + if(sfilefd){ + fclose(sfilefd); + sfilefd = NULL; + } + //open file + if(!overwrite){ + if (NULL == (sfilefd = fopen((const char *) (savefilename), "wx"))){ + cout << "Error: Could not create new file " << savefilename << endl; + return FAIL; + } + }else if (NULL == (sfilefd = fopen((const char *) (savefilename), "w"))){ + cout << "Error: Could not create file " << savefilename << endl; + return FAIL; + } + //setting buffer + setvbuf(sfilefd,NULL,_IOFBF,BUF_SIZE); + + //printing packet losses and file names + if(!packetsCaught) + cout << savefilename << endl; + else{ + cout << savefilename + << "\tpacket loss " + << setw(4)<GetCurrentFile(); + + if(myFile[ithr]->Write()) + //->Write(tall->GetName(),TObject::kOverwrite); + cout << "Thread " << ithr <<": wrote frames to file" << endl; + else + cout << "Thread " << ithr << ": could not write frames to file" << endl; + + }else + cout << "Thread " << ithr << ": could not write frames to file: No file or No Tree" << endl; + //close file + if(myTree[ithr] && myFile[ithr]) + myFile[ithr] = myTree[ithr]->GetCurrentFile(); + if(myFile[ithr] != NULL) + myFile[ithr]->Close(); + myFile[ithr] = NULL; + myTree[ithr] = NULL; + pthread_mutex_unlock(&write_mutex); + +#endif + } +} + + + + + +int UDPRESTImplementation::startReceiver(char message[]){ + int i; + + +// #ifdef VERBOSE + cout << "Starting Receiver" << endl; +//#endif + + + //reset listening thread variables + measurementStarted = false; + //should be set to zero as its added to get next start frame indices for scans for eiger + if(!acqStarted) currframenum = 0; + startFrameIndex = 0; + + for(int i = 0; i < numListeningThreads; ++i) + totalListeningFrameCount[i] = 0; + + //udp socket + if(createUDPSockets() == FAIL){ + strcpy(message,"Could not create UDP Socket(s).\n"); + cout << endl << message << endl; + return FAIL; + } + cout << "UDP socket(s) created successfully. 1st port " << server_port[0] << endl; + + + if(setupWriter() == FAIL){ + //stop udp socket + shutDownUDPSockets(); + + sprintf(message,"Could not create file %s.\n",savefilename); + return FAIL; + } + cout << "Successfully created file(s)" << endl; + + //done to give the gui some proper name instead of always the last file name + if(dataCompression) + sprintf(savefilename, "%s/%s_fxxx_%d_xx.root", filePath,fileName,fileIndex); + + //initialize semaphore + sem_init(&smp,1,0); + + //status + pthread_mutex_lock(&status_mutex); + status = RUNNING; + for(i=0;istartListening(); + + return this_pointer; +} + + + +void* UDPRESTImplementation::startWritingThread(void* this_pointer){ + ((UDPRESTImplementation*)this_pointer)->startWriting(); + return this_pointer; +} + + + + + + +int UDPRESTImplementation::startListening(){ + int ithread = currentListeningThreadIndex; +#ifdef VERYVERBOSE + cout << "In startListening() " << endl; +#endif + + thread_started = 1; + + int i,total; + int lastpacketoffset, expected, rc, rc1,packetcount, maxBufferSize, carryonBufferSize; + uint32_t lastframeheader;// for moench to check for all the packets in last frame + char* tempchar = NULL; + int imageheader = 0; + if(myDetectorType==EIGER) + imageheader = EIGER_IMAGE_HEADER_SIZE; + + + while(1){ + //variables that need to be checked/set before each acquisition + carryonBufferSize = 0; + //if more than 1 listening thread, listen one packet at a time, else need to interleaved frame later + maxBufferSize = bufferSize * numJobsPerThread; +#ifdef VERYDEBUG + cout << " maxBufferSize:" << maxBufferSize << ",carryonBufferSize:" << carryonBufferSize << endl; +#endif + + if(tempchar) {delete [] tempchar;tempchar = NULL;} + if(myDetectorType != EIGER) + tempchar = new char[onePacketSize * ((packetsPerFrame/numListeningThreads) - 1)]; //gotthard: 1packet size, moench:39 packet size + + + while((1<pop(buffer[ithread]); +#ifdef VERYDEBUG + cout << ithread << " *** popped from fifo free" << (void*)buffer[ithread] << endl; +#endif + + + //receive + if(udpSocket[ithread] == NULL){ + rc = 0; + cout << ithread << "UDP Socket is NULL" << endl; + } + //normal listening + else if(!carryonBufferSize){ + + rc = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS, maxBufferSize); + expected = maxBufferSize; + + } + //the remaining packets from previous buffer + else{ +#ifdef VERYDEBUG + cout << ithread << " ***carry on buffer" << carryonBufferSize << endl; + cout << ithread << " framennum in temochar:"<<((((uint32_t)(*((uint32_t*)tempchar))) + & (frameIndexMask)) >> frameIndexOffset)<ReceiveDataOnly((buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS + carryonBufferSize),maxBufferSize - carryonBufferSize); + expected = maxBufferSize - carryonBufferSize; + } + +#ifdef VERYDEBUG + cout << ithread << " *** rc:" << dec << rc << ". expected:" << dec << expected << endl; +#endif + + + + + //start indices for each start of scan/acquisition - eiger does it before + if((!measurementStarted) && (rc > 0) && (!ithread)) + startFrameIndices(ithread); + + //problem in receiving or end of acquisition + if((rc < expected)||(rc <= 0)){ + stopListening(ithread,rc,packetcount,total); + continue; + } + + + + //reset + packetcount = (packetsPerFrame/numListeningThreads) * numJobsPerThread; + carryonBufferSize = 0; + + + + //check if last packet valid and calculate packet count + switch(myDetectorType){ + + case MOENCH: + lastpacketoffset = (((numJobsPerThread * packetsPerFrame - 1) * onePacketSize) + HEADER_SIZE_NUM_TOT_PACKETS); +#ifdef VERYDEBUG + cout <<"first packet:"<< ((((uint32_t)(*((uint32_t*)(buffer[ithread]+HEADER_SIZE_NUM_TOT_PACKETS))))) & (packetIndexMask)) << endl; + cout <<"first header:"<< (((((uint32_t)(*((uint32_t*)(buffer[ithread]+HEADER_SIZE_NUM_TOT_PACKETS))))) & (frameIndexMask)) >> frameIndexOffset) << endl; + cout << "last packet offset:" << lastpacketoffset << endl; + cout <<"last packet:"<< ((((uint32_t)(*((uint32_t*)(buffer[ithread]+lastpacketoffset))))) & (packetIndexMask)) << endl; + cout <<"last header:"<< (((((uint32_t)(*((uint32_t*)(buffer[ithread]+lastpacketoffset))))) & (frameIndexMask)) >> frameIndexOffset) << endl; +#endif + //moench last packet value is 0 + if( ((((uint32_t)(*((uint32_t*)(buffer[ithread]+lastpacketoffset))))) & (packetIndexMask))){ + lastframeheader = ((((uint32_t)(*((uint32_t*)(buffer[ithread]+lastpacketoffset))))) & (frameIndexMask)) >> frameIndexOffset; + carryonBufferSize += onePacketSize; + lastpacketoffset -= onePacketSize; + --packetcount; + while (lastframeheader == (((((uint32_t)(*((uint32_t*)(buffer[ithread]+lastpacketoffset))))) & (frameIndexMask)) >> frameIndexOffset)){ + carryonBufferSize += onePacketSize; + lastpacketoffset -= onePacketSize; + --packetcount; + } + memcpy(tempchar, buffer[ithread]+(lastpacketoffset+onePacketSize), carryonBufferSize); +#ifdef VERYDEBUG + cout << "tempchar header:" << (((((uint32_t)(*((uint32_t*)(tempchar))))) + & (frameIndexMask)) >> frameIndexOffset) << endl; + cout <<"tempchar packet:"<< ((((uint32_t)(*((uint32_t*)(tempchar))))) + & (packetIndexMask)) << endl; +#endif + } + break; + + case GOTTHARD: + if(shortFrame == -1){ + lastpacketoffset = (((numJobsPerThread * packetsPerFrame - 1) * onePacketSize) + HEADER_SIZE_NUM_TOT_PACKETS); +#ifdef VERYDEBUG + cout << "last packet offset:" << lastpacketoffset << endl; +#endif + + if((unsigned int)(packetsPerFrame -1) != ((((uint32_t)(*((uint32_t*)(buffer[ithread]+lastpacketoffset))))+1) & (packetIndexMask))){ + memcpy(tempchar,buffer[ithread]+lastpacketoffset, onePacketSize); +#ifdef VERYDEBUG + cout << "tempchar header:" << (((((uint32_t)(*((uint32_t*)(tempchar))))+1) + & (frameIndexMask)) >> frameIndexOffset) << endl; +#endif + carryonBufferSize = onePacketSize; + --packetcount; + } + } +#ifdef VERYDEBUG + cout << "header:" << (((((uint32_t)(*((uint32_t*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS))))+1) + & (frameIndexMask)) >> frameIndexOffset) << endl; +#endif + break; + default: + + break; + + } + + + // cout<<"*********** "<fnum)<push(buffer[ithread])); +#ifdef VERYDEBUG + if(!ithread) cout << ithread << " *** pushed into listening fifo" << endl; +#endif + } + + sem_wait(&listensmp[ithread]); + + //make sure its not exiting thread + if(killAllListeningThreads){ + cout << ithread << " good bye listening thread" << endl; + if(tempchar) {delete [] tempchar;tempchar = NULL;} + pthread_exit(NULL); + } + } + + return OK; +} + + + + + + + + + + + + + +int UDPRESTImplementation::startWriting(){ + int ithread = currentWriterThreadIndex; +#ifdef VERYVERBOSE + cout << ithread << "In startWriting()" <pop(wbuf[i]); + numpackets = (uint16_t)(*((uint16_t*)wbuf[i])); +#ifdef VERYDEBUG + cout << ithread << " numpackets:" << dec << numpackets << endl; +#endif + } + +#ifdef VERYDEBUG + cout << ithread << " numpackets:" << dec << numpackets << endl; + cout << ithread << " *** writer popped from fifo " << (void*) wbuf[0]<< endl; + cout << ithread << " *** writer popped from fifo " << (void*) wbuf[1]<< endl; +#endif + + + //last dummy packet + if(numpackets == 0xFFFF){ + stopWriting(ithread,wbuf); + continue; + } + + + + + //for progress + if(myDetectorType == EIGER){ + tempframenum = htonl(*(unsigned int*)((eiger_image_header *)((char*)(wbuf[ithread] + HEADER_SIZE_NUM_TOT_PACKETS)))->fnum); + tempframenum += (startFrameIndex-1); //eiger frame numbers start at 1, so need to -1 + }else if ((myDetectorType == GOTTHARD) && (shortFrame == -1)) + tempframenum = (((((uint32_t)(*((uint32_t*)(wbuf[ithread] + HEADER_SIZE_NUM_TOT_PACKETS))))+1)& (frameIndexMask)) >> frameIndexOffset); + else + tempframenum = ((((uint32_t)(*((uint32_t*)(wbuf[ithread] + HEADER_SIZE_NUM_TOT_PACKETS))))& (frameIndexMask)) >> frameIndexOffset); + + if(numWriterThreads == 1) + currframenum = tempframenum; + else{ + pthread_mutex_lock(&progress_mutex); + if(tempframenum > currframenum) + currframenum = tempframenum; + pthread_mutex_unlock(&progress_mutex); + } +//#ifdef VERYDEBUG + if(myDetectorType == EIGER) + cout << endl < 0){ + for(i=0;ipush(wbuf[i])); +#ifdef VERYDEBUG + cout << ithread << ":" << i+j << " fifo freed:" << (void*)wbuf[i] << endl; +#endif + } + + + } + else{ + //copy to gui + copyFrameToGui(NULL,-1,wbuf[0]+HEADER_SIZE_NUM_TOT_PACKETS); +#ifdef VERYVERBOSE + cout << ithread << " finished copying" << endl; +#endif + while(!fifoFree[0]->push(wbuf[0])); +#ifdef VERYVERBOSE + cout<<"buf freed:"<<(void*)wbuf[0]<fnum); + //gotthard has +1 for frame number and not a short frame + else if ((myDetectorType == GOTTHARD) && (shortFrame == -1)) + startFrameIndex = (((((uint32_t)(*((uint32_t*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS))))+1) + & (frameIndexMask)) >> frameIndexOffset); + else + startFrameIndex = ((((uint32_t)(*((uint32_t*)(buffer[ithread]+HEADER_SIZE_NUM_TOT_PACKETS)))) + & (frameIndexMask)) >> frameIndexOffset); + + + //start of acquisition + if(!acqStarted){ + startAcquisitionIndex=startFrameIndex; + currframenum = startAcquisitionIndex; + acqStarted = true; + cout << "startAcquisitionIndex:" << startAcquisitionIndex<push(buffer[ithread]); + exit(-1); + } + //push the last buffer into fifo + if(rc > 0){ + pc = (rc/onePacketSize); +#ifdef VERYDEBUG + cout << ithread << " *** last packetcount:" << pc << endl; +#endif + (*((uint16_t*)(buffer[ithread]))) = pc; + totalListeningFrameCount[ithread] += pc; + while(!fifo[ithread]->push(buffer[ithread])); +#ifdef VERYDEBUG + cout << ithread << " *** last lbuf1:" << (void*)buffer[ithread] << endl; +#endif + } + + + //push dummy buffer to all writer threads + for(i=0;ipop(buffer[ithread]); + (*((uint16_t*)(buffer[ithread]))) = 0xFFFF; +#ifdef VERYDEBUG + cout << ithread << " going to push in dummy buffer:" << (void*)buffer[ithread] << " with num packets:"<< (*((uint16_t*)(buffer[ithread]))) << endl; +#endif + while(!fifo[ithread]->push(buffer[ithread])); +#ifdef VERYDEBUG + cout << ithread << " pushed in dummy buffer:" << (void*)buffer[ithread] << endl; +#endif + } + + //reset mask and exit loop + pthread_mutex_lock(&status_mutex); + listeningthreads_mask^=(1< 1) + cout << "Waiting for listening to be done.. current mask:" << hex << listeningthreads_mask << endl; +#endif + while(listeningthreads_mask) + usleep(5000); +#ifdef VERYDEBUG + t = 0; + for(i=0;ipush(wbuffer[i])); +#ifdef VERYDEBUG + cout << ithread << ":" << i<< " fifo freed:" << (void*)wbuffer[i] << endl; +#endif + } + + + + //all threads need to close file, reset mask and exit loop + closeFile(ithread); + pthread_mutex_lock(&status_mutex); + writerthreads_mask^=(1< 0){ + + //for progress and packet loss calculation(new files) + if(myDetectorType == EIGER); + else if ((myDetectorType == GOTTHARD) && (shortFrame == -1)) + tempframenum = (((((uint32_t)(*((uint32_t*)(buf + HEADER_SIZE_NUM_TOT_PACKETS))))+1)& (frameIndexMask)) >> frameIndexOffset); + else + tempframenum = ((((uint32_t)(*((uint32_t*)(buf + HEADER_SIZE_NUM_TOT_PACKETS))))& (frameIndexMask)) >> frameIndexOffset); + + if(numWriterThreads == 1) + currframenum = tempframenum; + else{ + if(tempframenum > currframenum) + currframenum = tempframenum; + } +#ifdef VERYDEBUG + cout << "tempframenum:" << dec << tempframenum << " curframenum:" << currframenum << endl; +#endif + + //lock + if(numWriterThreads > 1) + pthread_mutex_lock(&write_mutex); + + + //to create new file when max reached + packetsToSave = maxPacketsPerFile - packetsInFile; + if(packetsToSave > numpackets) + packetsToSave = numpackets; +/**next time offset is still plus header length*/ + fwrite(buf+offset, 1, packetsToSave * onePacketSize, sfilefd); + packetsInFile += packetsToSave; + packetsCaught += packetsToSave; + totalPacketsCaught += packetsToSave; + + + //new file + if(packetsInFile >= maxPacketsPerFile){ + //for packet loss + lastpacket = (((packetsToSave - 1) * onePacketSize) + offset); + if(myDetectorType == EIGER); + else if ((myDetectorType == GOTTHARD) && (shortFrame == -1)) + tempframenum = (((((uint32_t)(*((uint32_t*)(buf + lastpacket))))+1)& (frameIndexMask)) >> frameIndexOffset); + else + tempframenum = ((((uint32_t)(*((uint32_t*)(buf + lastpacket))))& (frameIndexMask)) >> frameIndexOffset); + + if(numWriterThreads == 1) + currframenum = tempframenum; + else{ + if(tempframenum > currframenum) + currframenum = tempframenum; + } +#ifdef VERYDEBUG + cout << "tempframenum:" << dec << tempframenum << " curframenum:" << currframenum << endl; +#endif + //create + createNewFile(); + } + + //unlock + if(numWriterThreads > 1) + pthread_mutex_unlock(&write_mutex); + + + offset += (packetsToSave * onePacketSize); + numpackets -= packetsToSave; + } + + } + else{ + if(numWriterThreads > 1) + pthread_mutex_lock(&write_mutex); + packetsInFile += numpackets; + packetsCaught += numpackets; + totalPacketsCaught += numpackets; + if(numWriterThreads > 1) + pthread_mutex_unlock(&write_mutex); + } +} + + + + + + + + + + + + + + +void UDPRESTImplementation::handleDataCompression(int ithread, char* wbuffer[], int &npackets, char* data, int xmax, int ymax, int &nf){ + +#if defined(MYROOT1) && defined(ALLFILE_DEBUG) + writeToFile_withoutCompression(wbuf[0], numpackets,currframenum); +#endif + + eventType thisEvent = PEDESTAL; + int ndata; + char* buff = 0; + data = wbuffer[0]+ HEADER_SIZE_NUM_TOT_PACKETS; + int remainingsize = npackets * onePacketSize; + int np; + int once = 0; + double tot, tl, tr, bl, br; + int xmin = 1, ymin = 1, ix, iy; + + + while(buff = receiverdata[ithread]->findNextFrame(data,ndata,remainingsize)){ + np = ndata/onePacketSize; + + //cout<<"buff framnum:"<> frameIndexOffset)<newFrame(); + + //only for moench + if(commonModeSubtractionEnable){ + for(ix = xmin - 1; ix < xmax+1; ix++){ + for(iy = ymin - 1; iy < ymax+1; iy++){ + thisEvent = singlePhotonDet[ithread]->getEventType(buff, ix, iy, 0); + } + } + } + + + for(ix = xmin - 1; ix < xmax+1; ix++) + for(iy = ymin - 1; iy < ymax+1; iy++){ + thisEvent=singlePhotonDet[ithread]->getEventType(buff, ix, iy, commonModeSubtractionEnable); + if (nf>1000) { + tot=0; + tl=0; + tr=0; + bl=0; + br=0; + if (thisEvent==PHOTON_MAX) { + receiverdata[ithread]->getFrameNumber(buff); + //iFrame=receiverdata[ithread]->getFrameNumber(buff); +#ifdef MYROOT1 + myTree[ithread]->Fill(); + //cout << "Fill in event: frmNr: " << iFrame << " ix " << ix << " iy " << iy << " type " << thisEvent << endl; +#else + pthread_mutex_lock(&write_mutex); + if((enableFileWrite) && (sfilefd)) + singlePhotonDet[ithread]->writeCluster(sfilefd); + pthread_mutex_unlock(&write_mutex); +#endif + } + } + } + + nf++; +#ifndef ALLFILE + pthread_mutex_lock(&progress_mutex); + packetsInFile += packetsPerFrame; + packetsCaught += packetsPerFrame; + totalPacketsCaught += packetsPerFrame; + if(packetsInFile >= maxPacketsPerFile) + createNewFile(); + pthread_mutex_unlock(&progress_mutex); + +#endif + if(!once){ + copyFrameToGui(NULL,-1,buff); + once = 1; + } + } + + remainingsize -= ((buff + ndata) - data); + data = buff + ndata; + if(data > (wbuffer[0] + HEADER_SIZE_NUM_TOT_PACKETS + npackets * onePacketSize) ) + cout <<" **************ERROR SHOULD NOT COME HERE, Error 142536!"<push(wbuffer[0])); +#ifdef VERYVERBOSE + cout<<"buf freed:"<<(void*)wbuffer[0]<= 0){ + + tengigaEnable = enable; + + if(myDetectorType == EIGER){ + + if(!tengigaEnable){ + packetsPerFrame = EIGER_ONE_GIGA_CONSTANT * dynamicRange * EIGER_MAX_PORTS; + onePacketSize = EIGER_ONE_GIGA_ONE_PACKET_SIZE; + maxPacketsPerFile = EIGER_MAX_FRAMES_PER_FILE * packetsPerFrame; + }else{ + packetsPerFrame = EIGER_TEN_GIGA_CONSTANT * dynamicRange * EIGER_MAX_PORTS; + onePacketSize = EIGER_TEN_GIGA_ONE_PACKET_SIZE; + maxPacketsPerFile = EIGER_MAX_FRAMES_PER_FILE * packetsPerFrame*4; + } + frameSize = onePacketSize * packetsPerFrame; + bufferSize = (frameSize/EIGER_MAX_PORTS) + EIGER_HEADER_LENGTH;//everything one port gets (img header plus packets) + //maxPacketsPerFile = EIGER_MAX_FRAMES_PER_FILE * packetsPerFrame; + + + cout<<"packetsPerFrame:"< +#include +#endif + +#include "RestHelper.h" + + +#include +#include +#include +#include + +/** + * @short does all the functions for a receiver, set/get parameters, start/stop etc. + */ + +class UDPRESTImplementation : private virtual slsReceiverDefs, public UDPBaseImplementation { + + public: + /** + * Constructor + */ + UDPRESTImplementation(); + + /** + * Destructor + */ + virtual ~UDPRESTImplementation(); + + + + /** + * delete and free member parameters + */ + void deleteMembers(); + + /** + * initialize member parameters + */ + void initializeMembers(); + + /** + * Set receiver type + * @param det detector type + * Returns success or FAIL + */ + int setDetectorType(detectorType det); + + + //Frame indices and numbers caught + /** + * Returns current Frame Index Caught for an entire acquisition (including all scans) + */ + uint32_t getAcquisitionIndex(); + + /** + * Returns if acquisition started + */ + bool getAcquistionStarted(); + + /** + * Returns Frames Caught for each real time acquisition (eg. for each scan) + */ + int getFramesCaught(); + + /** + * Returns Total Frames Caught for an entire acquisition (including all scans) + */ + int getTotalFramesCaught(); + + /** + * Returns the frame index at start of each real time acquisition (eg. for each scan) + */ + uint32_t getStartFrameIndex(); + + /** + * Returns current Frame Index for each real time acquisition (eg. for each scan) + */ + uint32_t getFrameIndex(); + + /** + * Returns if measurement started + */ + bool getMeasurementStarted(); + + /** + * Resets the Total Frames Caught + * This is how the receiver differentiates between entire acquisitions + * Returns 0 + */ + void resetTotalFramesCaught(); + + + + + //file parameters + /** + * Returns File Path + */ + //char* getFilePath() const; + + /** + * Set File Path + * @param c file path + */ + //char* setFilePath(const char c[]); + + /** + * Returns File Name + */ + //char* getFileName() const; + + /** + * Set File Name (without frame index, file index and extension) + * @param c file name + */ + //char* setFileName(const char c[]); + + /** + * Returns File Index + */ + int getFileIndex(); + + /** + * Set File Index + * @param i file index + */ + int setFileIndex(int i); + + /** + * Set Frame Index Needed + * @param i frame index needed + */ + int setFrameIndexNeeded(int i); + + /** + * Set enable file write + * @param i file write enable + * Returns file write enable + */ + //int setEnableFileWrite(int i); + + /** + * Enable/disable overwrite + * @param i enable + * Returns enable over write + */ + //int setEnableOverwrite(int i); + + /** + * Returns file write enable + * 1: YES 0: NO + */ + //int getEnableFileWrite() const; + + /** + * Returns file over write enable + * 1: YES 0: NO + */ + //int getEnableOverwrite() const; + +//other parameters + + /** + * abort acquisition with minimum damage: close open files, cleanup. + * does nothing if state already is 'idle' + */ + void abort() {}; + + /** + * Returns status of receiver: idle, running or error + */ + runStatus getStatus() const; + + /** + * Set detector hostname + * @param c hostname + */ + void initialize(const char *detectorHostName); + + /* Returns detector hostname + /returns hostname + * caller needs to deallocate the returned char array. + * if uninitialized, it must return NULL + */ + //char *getDetectorHostname() const; + + /** + * Set Ethernet Interface or IP to listen to + */ + void setEthernetInterface(char* c); + + /** + * Set UDP Port Number + */ + void setUDPPortNo(int p); + + /* + * Returns number of frames to receive + * This is the number of frames to expect to receiver from the detector. + * The data receiver will change from running to idle when it got this number of frames + */ + + //int getNumberOfFrames() const; + + /** + * set frame number if a positive number + */ + //int32_t setNumberOfFrames(int32_t fnum); + + + /** + * Returns scan tag + */ + //int getScanTag() const; + + /** + * set scan tag if its is a positive number + */ + //int32_t setScanTag(int32_t stag); + + /** + * Returns the number of bits per pixel + */ + //int getDynamicRange() const; + + /** + * set dynamic range if its is a positive number + */ + int32_t setDynamicRange(int32_t dr); + + /** + * Set short frame + * @param i if shortframe i=1 + */ + int setShortFrame(int i); + + /** + * Set the variable to send every nth frame to gui + * or if 0,send frame only upon gui request + */ + int setNFrameToGui(int i); + + /** set acquisition period if a positive number + */ + int64_t setAcquisitionPeriod(int64_t index); + + /** get data compression, by saving only hits + */ + bool getDataCompression(); + + /** enabl data compression, by saving only hits + /returns if failed + */ + int enableDataCompression(bool enable); + + /** + * enable 10Gbe + @param enable 1 for 10Gbe or 0 for 1 Gbe, -1 to read out + \returns enable for 10Gbe + */ + int enableTenGiga(int enable = -1); + + + +//other functions + + /** + * Returns the buffer-current frame read by receiver + * @param c pointer to current file name + * @param raw address of pointer, pointing to current frame to send to gui + * @param fnum frame number for eiger as it is not in the packet + */ + void readFrame(char* c,char** raw, uint32_t &fnum); + + /** + * Closes all files + * @param ithr thread index + */ + void closeFile(int ithr = -1); + + /** + * Starts Receiver - starts to listen for packets + * @param message is the error message if there is an error + * Returns success + */ + int startReceiver(char message[]); + + /** + * Stops Receiver - stops listening for packets + * Returns success + */ + int stopReceiver(); + + /** set status to transmitting and + * when fifo is empty later, sets status to run_finished + */ + void startReadout(); + + /** + * shuts down the udp sockets + * \returns if success or fail + */ + int shutDownUDPSockets(); + +private: + + /* + void not_implemented(string method_name){ + std::cout << "[WARNING] Method " << method_name << " not implemented!" << std::endl; + }; + */ + /** + * Deletes all the filter objects for single photon data + */ + void deleteFilter(); + + /** + * Constructs the filter for single photon data + */ + void setupFilter(); + + /** + * set up fifo according to the new numjobsperthread + */ + void setupFifoStructure (); + + /** + * Copy frames to gui + * uses semaphore for nth frame mode + */ + void copyFrameToGui(char* startbuf[], uint32_t fnum=-1, char* buf=NULL); + + /** + * creates udp sockets + * \returns if success or fail + */ + int createUDPSockets(); + + /** + * create listening thread + * @param destroy is true to kill all threads and start again + */ + int createListeningThreads(bool destroy = false); + + /** + * create writer threads + * @param destroy is true to kill all threads and start again + */ + int createWriterThreads(bool destroy = false); + + /** + * set thread priorities + */ + void setThreadPriorities(); + + /** + * initializes variables and creates the first file + * also does the startAcquisitionCallBack + * \returns FAIL or OK + */ + int setupWriter(); + + /** + * Creates new tree and file for compression + * @param ithr thread number + * @param iframe frame number + *\returns OK for succces or FAIL for failure + */ + int createCompressionFile(int ithr, int iframe); + + /** + * Creates new file + *\returns OK for succces or FAIL for failure + */ + int createNewFile(); + + /** + * Static function - Thread started which listens to packets. + * Called by startReceiver() + * @param this_pointer pointer to this object + */ + static void* startListeningThread(void *this_pointer); + + /** + * Static function - Thread started which writes packets to file. + * Called by startReceiver() + * @param this_pointer pointer to this object + */ + static void* startWritingThread(void *this_pointer); + + /** + * Thread started which listens to packets. + * Called by startReceiver() + * + */ + int startListening(); + + /** + * Thread started which writes packets to file. + * Called by startReceiver() + * + */ + int startWriting(); + + /** + * Writing to file without compression + * @param buf is the address of buffer popped out of fifo + * @param numpackets is the number of packets + * @param framenum current frame number + */ + void writeToFile_withoutCompression(char* buf,int numpackets, uint32_t framenum); + + /** + * Its called for the first packet of a scan or acquistion + * Sets the startframeindices and the variables to know if acquisition started + * @param ithread listening thread number + */ + void startFrameIndices(int ithread); + + /** + * This is called when udp socket is shut down + * It pops ffff instead of packet number into fifo + * to inform writers about the end of listening session + * @param ithread listening thread number + * @param rc number of bytes received + * @param pc packet count + * @param t total packets listened to + */ + void stopListening(int ithread, int rc, int &pc, int &t); + + /** + * When acquisition is over, this is called + * @param ithread listening thread number + * @param wbuffer writer buffer + */ + void stopWriting(int ithread, char* wbuffer[]); + + + /** + * data compression for each fifo output + * @param ithread listening thread number + * @param wbuffer writer buffer + * @param npackets number of packets from the fifo + * @param data pointer to the next packet start + * @param xmax max pixels in x direction + * @param ymax max pixels in y direction + * @param nf nf + */ + void handleDataCompression(int ithread, char* wbuffer[], int &npackets, char* data, int xmax, int ymax, int &nf); + + + /** structure of an eiger image header*/ + typedef struct + { + unsigned char header_before[20]; + unsigned char fnum[4]; + unsigned char header_after[24]; + } eiger_image_header; + + + /** structure of an eiger image header*/ + typedef struct + { + unsigned char num1[4]; + unsigned char num2[4]; + } eiger_packet_header; + + /** max number of listening threads */ + const static int MAX_NUM_LISTENING_THREADS = EIGER_MAX_PORTS; + + /** max number of writer threads */ + const static int MAX_NUM_WRITER_THREADS = 15; + + /** detector type */ + detectorType myDetectorType; + + /** detector hostname */ + char detHostname[MAX_STR_LENGTH]; + + /** status of receiver */ + runStatus status; + + /** UDP Socket between Receiver and Detector */ + genericSocket* udpSocket[MAX_NUM_LISTENING_THREADS]; + + /** Server UDP Port*/ + int server_port[MAX_NUM_LISTENING_THREADS]; + + /** ethernet interface or IP to listen to */ + char *eth; + + /** max packets per file **/ + int maxPacketsPerFile; + + /** File write enable */ + int enableFileWrite; + + /** File over write enable */ + int overwrite; + + /** Complete File name */ + char savefilename[MAX_STR_LENGTH]; + + /** File Name without frame index, file index and extension*/ + char fileName[MAX_STR_LENGTH]; + + /** File Path */ + char filePath[MAX_STR_LENGTH]; + + /** File Index */ + int fileIndex; + + /** scan tag */ + int scanTag; + + /** if frame index required in file name */ + int frameIndexNeeded; + + /* Acquisition started */ + bool acqStarted; + + /* Measurement started */ + bool measurementStarted; + + /** Frame index at start of each real time acquisition (eg. for each scan) */ + uint32_t startFrameIndex; + + /** Actual current frame index of each time acquisition (eg. for each scan) */ + uint32_t frameIndex; + + /** Frames Caught for each real time acquisition (eg. for each scan) */ + int packetsCaught; + + /** Total packets caught for an entire acquisition (including all scans) */ + int totalPacketsCaught; + + /** Pckets currently in current file, starts new file when it reaches max */ + int packetsInFile; + + /** Frame index at start of an entire acquisition (including all scans) */ + uint32_t startAcquisitionIndex; + + /** Actual current frame index of an entire acquisition (including all scans) */ + uint32_t acquisitionIndex; + + /** number of packets per frame*/ + int packetsPerFrame; + + /** frame index mask */ + uint32_t frameIndexMask; + + /** packet index mask */ + uint32_t packetIndexMask; + + /** frame index offset */ + int frameIndexOffset; + + /** acquisition period */ + int64_t acquisitionPeriod; + + /** frame number */ + int32_t numberOfFrames; + + /** dynamic range */ + int dynamicRange; + + /** short frames */ + int shortFrame; + + /** current frame number */ + uint32_t currframenum; + + /** Previous Frame number from buffer */ + uint32_t prevframenum; + + /** size of one frame */ + int frameSize; + + /** buffer size. different from framesize as we wait for one packet instead of frame for eiger */ + int bufferSize; + + /** oen buffer size */ + int onePacketSize; + + /** latest data */ + char* latestData; + + /** gui data ready */ + int guiDataReady; + + /** points to the data to send to gui */ + char* guiData; + + /** points to the filename to send to gui */ + char* guiFileName; + + /** temporary number for eiger frame number as its not included in the packet */ + uint32_t guiFrameNumber; + + /** send every nth frame to gui or only upon gui request*/ + int nFrameToGui; + + /** fifo size */ + unsigned int fifosize; + + /** number of jobs per thread for data compression */ + int numJobsPerThread; + + /** datacompression - save only hits */ + bool dataCompression; + + /** memory allocated for the buffer */ + char *mem0[MAX_NUM_LISTENING_THREADS]; + + /** circular fifo to store addresses of data read */ + CircularFifo* fifo[MAX_NUM_LISTENING_THREADS]; + + /** circular fifo to store addresses of data already written and ready to be resued*/ + CircularFifo* fifoFree[MAX_NUM_LISTENING_THREADS]; + + /** Receiver buffer */ + char *buffer[MAX_NUM_LISTENING_THREADS]; + + /** number of writer threads */ + int numListeningThreads; + + /** number of writer threads */ + int numWriterThreads; + + /** to know if listening and writer threads created properly */ + int thread_started; + + /** current listening thread index*/ + int currentListeningThreadIndex; + + /** current writer thread index*/ + int currentWriterThreadIndex; + + /** thread listening to packets */ + pthread_t listening_thread[MAX_NUM_LISTENING_THREADS]; + + /** thread writing packets */ + pthread_t writing_thread[MAX_NUM_WRITER_THREADS]; + + /** total frame count the listening thread has listened to */ + int totalListeningFrameCount[MAX_NUM_LISTENING_THREADS]; + + /** mask showing which listening threads are running */ + volatile uint32_t listeningthreads_mask; + + /** mask showing which writer threads are running */ + volatile uint32_t writerthreads_mask; + + /** mask showing which threads have created files*/ + volatile uint32_t createfile_mask; + + /** OK if file created was successful */ + int ret_createfile; + + /** variable used to self terminate threads waiting for semaphores */ + int killAllListeningThreads; + + /** variable used to self terminate threads waiting for semaphores */ + int killAllWritingThreads; + + /** 10Gbe enable*/ + int tengigaEnable; + + + + +//semaphores + /** semaphore to synchronize writer and guireader threads */ + sem_t smp; + /** semaphore to synchronize listener threads */ + sem_t listensmp[MAX_NUM_LISTENING_THREADS]; + /** semaphore to synchronize writer threads */ + sem_t writersmp[MAX_NUM_WRITER_THREADS]; + + +//mutex + /** guiDataReady mutex */ + pthread_mutex_t dataReadyMutex; + + /** mutex for status */ + pthread_mutex_t status_mutex; + + /** mutex for progress variable currframenum */ + pthread_mutex_t progress_mutex; + + /** mutex for writing data to file */ + pthread_mutex_t write_mutex; + + /** File Descriptor */ + FILE *sfilefd; + + //filter + singlePhotonDetector *singlePhotonDet[MAX_NUM_WRITER_THREADS]; + slsReceiverData *receiverdata[MAX_NUM_WRITER_THREADS]; + moenchCommonMode *cmSub; + bool commonModeSubtractionEnable; + +#ifdef MYROOT1 + /** Tree where the hits are stored */ + TTree *myTree[MAX_NUM_WRITER_THREADS]; + + /** File where the tree is saved */ + TFile *myFile[MAX_NUM_WRITER_THREADS]; +#endif + + + + /** + callback arguments are + filepath + filename + fileindex + data size + + return value is + 0 callback takes care of open,close,write file + 1 callback writes file, we have to open, close it + 2 we open, close, write file, callback does not do anything + + */ + int (*startAcquisitionCallBack)(char*, char*,int, int, void*); + void *pStartAcquisition; + + /** + args to acquisition finished callback + total frames caught + + */ + void (*acquisitionFinishedCallBack)(int, void*); + void *pAcquisitionFinished; + + + /** + args to raw data ready callback are + framenum + datapointer + datasize in bytes + file descriptor + guidatapointer (NULL, no data required) + */ + void (*rawDataReadyCallBack)(int, char*, int, FILE*, char*, void*); + void *pRawDataReady; + + /** The action which decides what the user and default responsibilites to save data are + * 0 raw data ready callback takes care of open,close,write file + * 1 callback writes file, we have to open, close it + * 2 we open, close, write file, callback does not do anything */ + int cbAction; + + +public: + + + /** + callback arguments are + filepath + filename + fileindex + datasize + + return value is + 0 callback takes care of open,close,wrie file + 1 callback writes file, we have to open, close it + 2 we open, close, write file, callback does not do anything + */ + void registerCallBackStartAcquisition(int (*func)(char*, char*,int, int, void*),void *arg){startAcquisitionCallBack=func; pStartAcquisition=arg;}; + + /** + callback argument is + toatal frames caught + */ + void registerCallBackAcquisitionFinished(void (*func)(int, void*),void *arg){acquisitionFinishedCallBack=func; pAcquisitionFinished=arg;}; + + /** + args to raw data ready callback are + framenum + datapointer + datasize in bytes + file descriptor + guidatapointer (NULL, no data required) + */ + void registerCallBackRawDataReady(void (*func)(int, char*, int, FILE*, char*, void*),void *arg){rawDataReadyCallBack=func; pRawDataReady=arg;}; + + + //REST specific + bool isInitialized; + RestHelper * rest ; +}; + + +#endif + +//#endif /*REST*/ diff --git a/slsReceiverSoftware/slsReceiver/UDPStandardImplementation.cpp b/slsReceiverSoftware/slsReceiver/UDPStandardImplementation.cpp new file mode 100644 index 000000000..1314f2d5c --- /dev/null +++ b/slsReceiverSoftware/slsReceiver/UDPStandardImplementation.cpp @@ -0,0 +1,2330 @@ +/********************************************//** + * @file UDPStandardImplementation.cpp + * @short does all the functions for a receiver, set/get parameters, start/stop etc. + ***********************************************/ + + +#include "UDPStandardImplementation.h" + +#include "moench02ModuleData.h" +#include "gotthardModuleData.h" +#include "gotthardShortModuleData.h" + + +#include // SIGINT +#include // stat +#include // socket(), bind(), listen(), accept(), shut down +#include // sock_addr_in, htonl, INADDR_ANY +#include // exit() +#include //set precision +#include //munmap + + + +#include +#include + + + +using namespace std; + +void UDPStandardImplementation::initializeMembers(){ + myDetectorType = GENERIC; + maxPacketsPerFile = 0; + enableFileWrite = 1; + overwrite = 1; + fileIndex = 0; + scanTag = 0; + frameIndexNeeded = 0; + acqStarted = false; + measurementStarted = false; + startFrameIndex = 0; + frameIndex = 0; + packetsCaught = 0; + totalPacketsCaught = 0; + packetsInFile = 0; + startAcquisitionIndex = 0; + acquisitionIndex = 0; + packetsPerFrame = 0; + frameIndexMask = 0; + packetIndexMask = 0; + frameIndexOffset = 0; + acquisitionPeriod = SAMPLE_TIME_IN_NS; + numberOfFrames = 0; + dynamicRange = 16; + shortFrame = -1; + currframenum = 0; + prevframenum = 0; + frameSize = 0; + bufferSize = 0; + onePacketSize = 0; + guiDataReady = 0; + nFrameToGui = 0; + fifosize = 0; + numJobsPerThread = -1; + dataCompression = false; + numListeningThreads = 1; + numWriterThreads = 1; + thread_started = 0; + currentListeningThreadIndex = -1; + currentWriterThreadIndex = -1; + for(int i=0;i /proc/sys/net/core/rmem_max")) + cout << "\nWARNING: Could not change socket receiver buffer size in file /proc/sys/net/core/rmem_max" << endl; + else if(system("echo 250000 > /proc/sys/net/core/netdev_max_backlog")) + cout << "\nWARNING: Could not change max length of input queue in file /proc/sys/net/core/netdev_max_backlog" << endl; + /** permanent setting heiner + net.core.rmem_max = 104857600 # 100MiB + net.core.netdev_max_backlog = 250000 + sysctl -p + // from the manual + sysctl -w net.core.rmem_max=16777216 + sysctl -w net.core.netdev_max_backlog=250000 + */ +} + + + +UDPStandardImplementation::~UDPStandardImplementation(){ + createListeningThreads(true); + createWriterThreads(true); + deleteMembers(); +} + + + + +void UDPStandardImplementation::deleteMembers(){ + //kill threads + if(thread_started){ + createListeningThreads(true); + createWriterThreads(true); + } + + for(int i=0;i=0) + fileIndex = i; + return getFileIndex(); +} +*/ + +/* +int UDPStandardImplementation::setFrameIndexNeeded(int i){ + frameIndexNeeded = i; + return frameIndexNeeded; +} +*/ + +/* +int UDPStandardImplementation::getEnableFileWrite() const{ + return enableFileWrite; +} +*/ + +/* +int UDPStandardImplementation::setEnableFileWrite(int i){ + enableFileWrite=i; + return getEnableFileWrite(); +} +*/ + +/* +int UDPStandardImplementation::getEnableOverwrite() const{ + return overwrite; +} +*/ + +/* +int UDPStandardImplementation::setEnableOverwrite(int i){ + overwrite=i; + return getEnableOverwrite(); +} +*/ + + + + +/*other parameters*/ + +slsReceiverDefs::runStatus UDPStandardImplementation::getStatus() const{ + return status; +} + + +void UDPStandardImplementation::initialize(const char *detectorHostName){ + if(strlen(detectorHostName)) + strcpy(detHostname,detectorHostName); +} + + +char *UDPStandardImplementation::getDetectorHostname() const{ + return (char*)detHostname; +} + +void UDPStandardImplementation::setEthernetInterface(char* c){ + strcpy(eth,c); +} + + +void UDPStandardImplementation::setUDPPortNo(int p){ + for(int i=0;i= 0) + numberOfFrames = fnum; + + return getNumberOfFrames(); +} + +int UDPStandardImplementation::getScanTag() const{ + return scanTag; +} + + +int32_t UDPStandardImplementation::setScanTag(int32_t stag){ + if(stag >= 0) + scanTag = stag; + + return getScanTag(); +} + + +int UDPStandardImplementation::getDynamicRange() const{ + return dynamicRange; +} + +int32_t UDPStandardImplementation::setDynamicRange(int32_t dr){ + cout << "Setting Dynamic Range" << endl; + + int olddr = dynamicRange; + if(dr >= 0){ + dynamicRange = dr; + + if(myDetectorType == EIGER){ + + + if(!tengigaEnable) + packetsPerFrame = EIGER_ONE_GIGA_CONSTANT * dynamicRange * EIGER_MAX_PORTS; + else + packetsPerFrame = EIGER_TEN_GIGA_CONSTANT * dynamicRange * EIGER_MAX_PORTS; + frameSize = onePacketSize * packetsPerFrame; + bufferSize = (frameSize/EIGER_MAX_PORTS) + EIGER_HEADER_LENGTH;//everything one port gets (img header plus packets) + maxPacketsPerFile = EIGER_MAX_FRAMES_PER_FILE * packetsPerFrame; + + + + if(olddr != dr){ + + //del + if(thread_started){ + createListeningThreads(true); + createWriterThreads(true); + } + for(int i=0;i=0){ + nFrameToGui = i; + setupFifoStructure(); + } + return nFrameToGui; +} + + + +int64_t UDPStandardImplementation::setAcquisitionPeriod(int64_t index){ + + if(index >= 0){ + if(index != acquisitionPeriod){ + acquisitionPeriod = index; + setupFifoStructure(); + } + } + return acquisitionPeriod; +} + + +bool UDPStandardImplementation::getDataCompression(){return dataCompression;} + +int UDPStandardImplementation::enableDataCompression(bool enable){ + cout << "Data compression "; + if(enable) + cout << "enabled" << endl; + else + cout << "disabled" << endl; +#ifdef MYROOT1 + cout << " WITH ROOT" << endl; +#else + cout << " WITHOUT ROOT" << endl; +#endif + //delete filter for the current number of threads + deleteFilter(); + + dataCompression = enable; + pthread_mutex_lock(&status_mutex); + writerthreads_mask = 0x0; + pthread_mutex_unlock(&(status_mutex)); + + createWriterThreads(true); + + if(enable) + numWriterThreads = MAX_NUM_WRITER_THREADS; + else + numWriterThreads = 1; + + if(createWriterThreads() == FAIL){ + cout << "ERROR: Could not create writer threads" << endl; + return FAIL; + } + setThreadPriorities(); + + + if(enable) + setupFilter(); + + return OK; +} + + + + + + + + + + + + +/*other functions*/ + + +void UDPStandardImplementation::deleteFilter(){ + int i; + cmSub=NULL; + + for(i=0;i(receiverdata[i], csize, sigma, sign, cmSub); + +} + + + +//LEO: it is not clear to me.. +void UDPStandardImplementation::setupFifoStructure(){ + + int64_t i; + int oldn = numJobsPerThread; + + //if every nth frame mode + if(nFrameToGui) + numJobsPerThread = nFrameToGui; + + //random nth frame mode + else{ + if(!acquisitionPeriod) + i = SAMPLE_TIME_IN_NS; + else + i = SAMPLE_TIME_IN_NS/acquisitionPeriod; + if (i > MAX_JOBS_PER_THREAD) + numJobsPerThread = MAX_JOBS_PER_THREAD; + else if (i < 1) + numJobsPerThread = 1; + else + numJobsPerThread = i; + } + + //if same, return + if(oldn == numJobsPerThread) + return; + + if(myDetectorType == EIGER) + numJobsPerThread = 1; + + //otherwise memory too much if numjobsperthread is at max = 1000 + fifosize = GOTTHARD_FIFO_SIZE; + if(myDetectorType == MOENCH) + fifosize = MOENCH_FIFO_SIZE; + else if(myDetectorType == EIGER) + fifosize = EIGER_FIFO_SIZE; + + if(fifosize % numJobsPerThread) + fifosize = (fifosize/numJobsPerThread)+1; + else + fifosize = fifosize/numJobsPerThread; + + + cout << "Number of Frames per buffer:" << numJobsPerThread << endl; + cout << "Fifo Size:" << fifosize << endl; + + /* + //for testing + numJobsPerThread = 3; fifosize = 11; + */ + + for(int i=0;iisEmpty()) + fifoFree[i]->pop(buffer[i]); + delete fifoFree[i]; + } + if(fifo[i]) delete fifo[i]; + if(mem0[i]) free(mem0[i]); + fifoFree[i] = new CircularFifo(fifosize); + fifo[i] = new CircularFifo(fifosize); + + + //allocate memory + mem0[i]=(char*)malloc((bufferSize * numJobsPerThread + HEADER_SIZE_NUM_TOT_PACKETS)*fifosize); + /** shud let the client know about this */ + if (mem0[i]==NULL){ + cout<<"++++++++++++++++++++++ COULD NOT ALLOCATE MEMORY FOR LISTENING !!!!!!!+++++++++++++++++++++" << endl; + exit(-1); + } + buffer[i]=mem0[i]; + //push the addresses into freed fifoFree and writingFifoFree + while (buffer[i]<(mem0[i]+(bufferSize * numJobsPerThread + HEADER_SIZE_NUM_TOT_PACKETS)*(fifosize-1))) { + fifoFree[i]->push(buffer[i]); + buffer[i]+=(bufferSize * numJobsPerThread + HEADER_SIZE_NUM_TOT_PACKETS); + } + } + cout << "Fifo structure(s) reconstructed" << endl; +} + + + + + + + +/** acquisition functions */ + +void UDPStandardImplementation::readFrame(char* c,char** raw, uint32_t &fnum){ + //point to gui data + if (guiData == NULL) + guiData = latestData; + + //copy data and filename + strcpy(c,guiFileName); + fnum = guiFrameNumber; + + + //could not get gui data + if(!guiDataReady){ + *raw = NULL; + } + //data ready, set guidata to receive new data + else{ + *raw = guiData; + guiData = NULL; + + pthread_mutex_lock(&dataReadyMutex); + guiDataReady = 0; + pthread_mutex_unlock(&dataReadyMutex); + if((nFrameToGui) && (writerthreads_mask)){ + /*if(nFrameToGui){*/ + //release after getting data + sem_post(&smp); + } + } +} + + + + + +void UDPStandardImplementation::copyFrameToGui(char* startbuf[], uint32_t fnum, char* buf){ + + //random read when gui not ready + if((!nFrameToGui) && (!guiData)){ + pthread_mutex_lock(&dataReadyMutex); + guiDataReady=0; + pthread_mutex_unlock(&dataReadyMutex); + } + + //random read or nth frame read, gui needs data now + else{ + /* + //nth frame read, block current process if the guireader hasnt read it yet + if(nFrameToGui) + sem_wait(&smp); +*/ + pthread_mutex_lock(&dataReadyMutex); + guiDataReady=0; + //eiger + if(startbuf != NULL){ + int offset = 0; + int size = frameSize/EIGER_MAX_PORTS; + for(int j=0;jgetErrorStatus(); + if(iret){ +#ifdef VERBOSE + cout << "Could not create UDP socket on port " << server_port[i] << " error:" << iret << endl; +#endif + return FAIL; + } + } + + return OK; +} + + + + + + + +int UDPStandardImplementation::shutDownUDPSockets(){ + for(int i=0;iShutDownSocket(); + delete udpSocket[i]; + udpSocket[i] = NULL; + } + } + return OK; +} + + + + + +int UDPStandardImplementation::createListeningThreads(bool destroy){ + int i; + void* status; + + killAllListeningThreads = 0; + + pthread_mutex_lock(&status_mutex); + listeningthreads_mask = 0x0; + pthread_mutex_unlock(&(status_mutex)); + + if(!destroy){ + + //start listening threads + cout << "Creating Listening Threads(s)"; + + currentListeningThreadIndex = -1; + + for(i = 0; i < numListeningThreads; ++i){ + sem_init(&listensmp[i],1,0); + thread_started = 0; + currentListeningThreadIndex = i; + if(pthread_create(&listening_thread[i], NULL,startListeningThread, (void*) this)){ + cout << "Could not create listening thread with index " << i << endl; + return FAIL; + } + while(!thread_started); + cout << "."; + cout << flush; + } +#ifdef VERBOSE + cout << "Listening thread(s) created successfully." << endl; +#else + cout << endl; +#endif + }else{ + cout<<"Destroying Listening Thread(s)"<initEventTree(temp, &iframe); + //resets the pedestalSubtraction array and the commonModeSubtraction + singlePhotonDet[ithr]->newDataSet(); + if(myFile[ithr]==NULL){ + cout<<"file null"<IsOpen()){ + cout<<"file not open"< DO_NOTHING){ + //close + if(sfilefd){ + fclose(sfilefd); + sfilefd = NULL; + } + //open file + if(!overwrite){ + if (NULL == (sfilefd = fopen((const char *) (savefilename), "wx"))){ + cout << "Error: Could not create new file " << savefilename << endl; + return FAIL; + } + }else if (NULL == (sfilefd = fopen((const char *) (savefilename), "w"))){ + cout << "Error: Could not create file " << savefilename << endl; + return FAIL; + } + //setting buffer + setvbuf(sfilefd,NULL,_IOFBF,BUF_SIZE); + + //printing packet losses and file names + if(!packetsCaught) + cout << savefilename << endl; + else{ + cout << savefilename + << "\tpacket loss " + << setw(4)<GetCurrentFile(); + + if(myFile[ithr]->Write()) + //->Write(tall->GetName(),TObject::kOverwrite); + cout << "Thread " << ithr <<": wrote frames to file" << endl; + else + cout << "Thread " << ithr << ": could not write frames to file" << endl; + + }else + cout << "Thread " << ithr << ": could not write frames to file: No file or No Tree" << endl; + //close file + if(myTree[ithr] && myFile[ithr]) + myFile[ithr] = myTree[ithr]->GetCurrentFile(); + if(myFile[ithr] != NULL) + myFile[ithr]->Close(); + myFile[ithr] = NULL; + myTree[ithr] = NULL; + pthread_mutex_unlock(&write_mutex); + +#endif + } +} + + + + + +int UDPStandardImplementation::startReceiver(char message[]){ + int i; + + +// #ifdef VERBOSE + cout << "Starting Receiver" << endl; +//#endif + + + //reset listening thread variables + measurementStarted = false; + //should be set to zero as its added to get next start frame indices for scans for eiger + if(!acqStarted) currframenum = 0; + startFrameIndex = 0; + + for(int i = 0; i < numListeningThreads; ++i) + totalListeningFrameCount[i] = 0; + + //udp socket + if(createUDPSockets() == FAIL){ + strcpy(message,"Could not create UDP Socket(s).\n"); + cout << endl << message << endl; + return FAIL; + } + cout << "UDP socket(s) created successfully. 1st port " << server_port[0] << endl; + + + if(setupWriter() == FAIL){ + //stop udp socket + shutDownUDPSockets(); + + sprintf(message,"Could not create file %s.\n",savefilename); + return FAIL; + } + cout << "Successfully created file(s)" << endl; + + //done to give the gui some proper name instead of always the last file name + if(dataCompression) + sprintf(savefilename, "%s/%s_fxxx_%d_xx.root", filePath,fileName,fileIndex); + + //initialize semaphore + sem_init(&smp,1,0); + + //status + pthread_mutex_lock(&status_mutex); + status = RUNNING; + for(i=0;istartListening(); + + return this_pointer; +} + + + +void* UDPStandardImplementation::startWritingThread(void* this_pointer){ + ((UDPStandardImplementation*)this_pointer)->startWriting(); + return this_pointer; +} + + + + + + +int UDPStandardImplementation::startListening(){ + int ithread = currentListeningThreadIndex; +#ifdef VERYVERBOSE + cout << "In startListening() " << endl; +#endif + + thread_started = 1; + + int i,total; + int lastpacketoffset, expected, rc, rc1,packetcount, maxBufferSize, carryonBufferSize; + uint32_t lastframeheader;// for moench to check for all the packets in last frame + char* tempchar = NULL; + int imageheader = 0; + if(myDetectorType==EIGER) + imageheader = EIGER_IMAGE_HEADER_SIZE; + + + while(1){ + //variables that need to be checked/set before each acquisition + carryonBufferSize = 0; + //if more than 1 listening thread, listen one packet at a time, else need to interleaved frame later + maxBufferSize = bufferSize * numJobsPerThread; +#ifdef VERYDEBUG + cout << " maxBufferSize:" << maxBufferSize << ",carryonBufferSize:" << carryonBufferSize << endl; +#endif + + if(tempchar) {delete [] tempchar;tempchar = NULL;} + if(myDetectorType != EIGER) + tempchar = new char[onePacketSize * ((packetsPerFrame/numListeningThreads) - 1)]; //gotthard: 1packet size, moench:39 packet size + + + while((1<pop(buffer[ithread]); +#ifdef VERYDEBUG + cout << ithread << " *** popped from fifo free" << (void*)buffer[ithread] << endl; +#endif + + + //receive + if(udpSocket[ithread] == NULL){ + rc = 0; + cout << ithread << "UDP Socket is NULL" << endl; + } + //normal listening + else if(!carryonBufferSize){ + + rc = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS, maxBufferSize); + expected = maxBufferSize; + + } + //the remaining packets from previous buffer + else{ +#ifdef VERYDEBUG + cout << ithread << " ***carry on buffer" << carryonBufferSize << endl; + cout << ithread << " framennum in temochar:"<<((((uint32_t)(*((uint32_t*)tempchar))) + & (frameIndexMask)) >> frameIndexOffset)<ReceiveDataOnly((buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS + carryonBufferSize),maxBufferSize - carryonBufferSize); + expected = maxBufferSize - carryonBufferSize; + } + +#ifdef VERYDEBUG + cout << ithread << " *** rc:" << dec << rc << ". expected:" << dec << expected << endl; +#endif + + + + + //start indices for each start of scan/acquisition - eiger does it before + if((!measurementStarted) && (rc > 0) && (!ithread)) + startFrameIndices(ithread); + + //problem in receiving or end of acquisition + if((rc < expected)||(rc <= 0)){ + stopListening(ithread,rc,packetcount,total); + continue; + } + + + + //reset + packetcount = (packetsPerFrame/numListeningThreads) * numJobsPerThread; + carryonBufferSize = 0; + + + + //check if last packet valid and calculate packet count + switch(myDetectorType){ + + case MOENCH: + lastpacketoffset = (((numJobsPerThread * packetsPerFrame - 1) * onePacketSize) + HEADER_SIZE_NUM_TOT_PACKETS); +#ifdef VERYDEBUG + cout <<"first packet:"<< ((((uint32_t)(*((uint32_t*)(buffer[ithread]+HEADER_SIZE_NUM_TOT_PACKETS))))) & (packetIndexMask)) << endl; + cout <<"first header:"<< (((((uint32_t)(*((uint32_t*)(buffer[ithread]+HEADER_SIZE_NUM_TOT_PACKETS))))) & (frameIndexMask)) >> frameIndexOffset) << endl; + cout << "last packet offset:" << lastpacketoffset << endl; + cout <<"last packet:"<< ((((uint32_t)(*((uint32_t*)(buffer[ithread]+lastpacketoffset))))) & (packetIndexMask)) << endl; + cout <<"last header:"<< (((((uint32_t)(*((uint32_t*)(buffer[ithread]+lastpacketoffset))))) & (frameIndexMask)) >> frameIndexOffset) << endl; +#endif + //moench last packet value is 0 + if( ((((uint32_t)(*((uint32_t*)(buffer[ithread]+lastpacketoffset))))) & (packetIndexMask))){ + lastframeheader = ((((uint32_t)(*((uint32_t*)(buffer[ithread]+lastpacketoffset))))) & (frameIndexMask)) >> frameIndexOffset; + carryonBufferSize += onePacketSize; + lastpacketoffset -= onePacketSize; + --packetcount; + while (lastframeheader == (((((uint32_t)(*((uint32_t*)(buffer[ithread]+lastpacketoffset))))) & (frameIndexMask)) >> frameIndexOffset)){ + carryonBufferSize += onePacketSize; + lastpacketoffset -= onePacketSize; + --packetcount; + } + memcpy(tempchar, buffer[ithread]+(lastpacketoffset+onePacketSize), carryonBufferSize); +#ifdef VERYDEBUG + cout << "tempchar header:" << (((((uint32_t)(*((uint32_t*)(tempchar))))) + & (frameIndexMask)) >> frameIndexOffset) << endl; + cout <<"tempchar packet:"<< ((((uint32_t)(*((uint32_t*)(tempchar))))) + & (packetIndexMask)) << endl; +#endif + } + break; + + case GOTTHARD: + if(shortFrame == -1){ + lastpacketoffset = (((numJobsPerThread * packetsPerFrame - 1) * onePacketSize) + HEADER_SIZE_NUM_TOT_PACKETS); +#ifdef VERYDEBUG + cout << "last packet offset:" << lastpacketoffset << endl; +#endif + + if((unsigned int)(packetsPerFrame -1) != ((((uint32_t)(*((uint32_t*)(buffer[ithread]+lastpacketoffset))))+1) & (packetIndexMask))){ + memcpy(tempchar,buffer[ithread]+lastpacketoffset, onePacketSize); +#ifdef VERYDEBUG + cout << "tempchar header:" << (((((uint32_t)(*((uint32_t*)(tempchar))))+1) + & (frameIndexMask)) >> frameIndexOffset) << endl; +#endif + carryonBufferSize = onePacketSize; + --packetcount; + } + } +#ifdef VERYDEBUG + cout << "header:" << (((((uint32_t)(*((uint32_t*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS))))+1) + & (frameIndexMask)) >> frameIndexOffset) << endl; +#endif + break; + default: + + break; + + } + + + // cout<<"*********** "<fnum)<push(buffer[ithread])); +#ifdef VERYDEBUG + if(!ithread) cout << ithread << " *** pushed into listening fifo" << endl; +#endif + } + + sem_wait(&listensmp[ithread]); + + //make sure its not exiting thread + if(killAllListeningThreads){ + cout << ithread << " good bye listening thread" << endl; + if(tempchar) {delete [] tempchar;tempchar = NULL;} + pthread_exit(NULL); + } + } + + return OK; +} + + + + + + + + + + + + + +int UDPStandardImplementation::startWriting(){ + int ithread = currentWriterThreadIndex; +#ifdef VERYVERBOSE + cout << ithread << "In startWriting()" <pop(wbuf[i]); + numpackets = (uint16_t)(*((uint16_t*)wbuf[i])); +#ifdef VERYDEBUG + cout << ithread << " numpackets:" << dec << numpackets << endl; +#endif + } + +#ifdef VERYDEBUG + cout << ithread << " numpackets:" << dec << numpackets << endl; + cout << ithread << " *** writer popped from fifo " << (void*) wbuf[0]<< endl; + cout << ithread << " *** writer popped from fifo " << (void*) wbuf[1]<< endl; +#endif + + + //last dummy packet + if(numpackets == 0xFFFF){ + stopWriting(ithread,wbuf); + continue; + } + + + + + //for progress + if(myDetectorType == EIGER){ + tempframenum = htonl(*(unsigned int*)((eiger_image_header *)((char*)(wbuf[ithread] + HEADER_SIZE_NUM_TOT_PACKETS)))->fnum); + tempframenum += (startFrameIndex-1); //eiger frame numbers start at 1, so need to -1 + }else if ((myDetectorType == GOTTHARD) && (shortFrame == -1)) + tempframenum = (((((uint32_t)(*((uint32_t*)(wbuf[ithread] + HEADER_SIZE_NUM_TOT_PACKETS))))+1)& (frameIndexMask)) >> frameIndexOffset); + else + tempframenum = ((((uint32_t)(*((uint32_t*)(wbuf[ithread] + HEADER_SIZE_NUM_TOT_PACKETS))))& (frameIndexMask)) >> frameIndexOffset); + + if(numWriterThreads == 1) + currframenum = tempframenum; + else{ + pthread_mutex_lock(&progress_mutex); + if(tempframenum > currframenum) + currframenum = tempframenum; + pthread_mutex_unlock(&progress_mutex); + } +//#ifdef VERYDEBUG + if(myDetectorType == EIGER) + cout << endl < 0){ + for(i=0;ipush(wbuf[i])); +#ifdef VERYDEBUG + cout << ithread << ":" << i+j << " fifo freed:" << (void*)wbuf[i] << endl; +#endif + } + + + } + else{ + //copy to gui + copyFrameToGui(NULL,-1,wbuf[0]+HEADER_SIZE_NUM_TOT_PACKETS); +#ifdef VERYVERBOSE + cout << ithread << " finished copying" << endl; +#endif + while(!fifoFree[0]->push(wbuf[0])); +#ifdef VERYVERBOSE + cout<<"buf freed:"<<(void*)wbuf[0]<fnum); + //gotthard has +1 for frame number and not a short frame + else if ((myDetectorType == GOTTHARD) && (shortFrame == -1)) + startFrameIndex = (((((uint32_t)(*((uint32_t*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS))))+1) + & (frameIndexMask)) >> frameIndexOffset); + else + startFrameIndex = ((((uint32_t)(*((uint32_t*)(buffer[ithread]+HEADER_SIZE_NUM_TOT_PACKETS)))) + & (frameIndexMask)) >> frameIndexOffset); + + + //start of acquisition + if(!acqStarted){ + startAcquisitionIndex=startFrameIndex; + currframenum = startAcquisitionIndex; + acqStarted = true; + cout << "startAcquisitionIndex:" << startAcquisitionIndex<push(buffer[ithread]); + exit(-1); + } + //push the last buffer into fifo + if(rc > 0){ + pc = (rc/onePacketSize); +#ifdef VERYDEBUG + cout << ithread << " *** last packetcount:" << pc << endl; +#endif + (*((uint16_t*)(buffer[ithread]))) = pc; + totalListeningFrameCount[ithread] += pc; + while(!fifo[ithread]->push(buffer[ithread])); +#ifdef VERYDEBUG + cout << ithread << " *** last lbuf1:" << (void*)buffer[ithread] << endl; +#endif + } + + + //push dummy buffer to all writer threads + for(i=0;ipop(buffer[ithread]); + (*((uint16_t*)(buffer[ithread]))) = 0xFFFF; +#ifdef VERYDEBUG + cout << ithread << " going to push in dummy buffer:" << (void*)buffer[ithread] << " with num packets:"<< (*((uint16_t*)(buffer[ithread]))) << endl; +#endif + while(!fifo[ithread]->push(buffer[ithread])); +#ifdef VERYDEBUG + cout << ithread << " pushed in dummy buffer:" << (void*)buffer[ithread] << endl; +#endif + } + + //reset mask and exit loop + pthread_mutex_lock(&status_mutex); + listeningthreads_mask^=(1< 1) + cout << "Waiting for listening to be done.. current mask:" << hex << listeningthreads_mask << endl; +#endif + while(listeningthreads_mask) + usleep(5000); +#ifdef VERYDEBUG + t = 0; + for(i=0;ipush(wbuffer[i])); +#ifdef VERYDEBUG + cout << ithread << ":" << i<< " fifo freed:" << (void*)wbuffer[i] << endl; +#endif + } + + + + //all threads need to close file, reset mask and exit loop + closeFile(ithread); + pthread_mutex_lock(&status_mutex); + writerthreads_mask^=(1< 0){ + + //for progress and packet loss calculation(new files) + if(myDetectorType == EIGER); + else if ((myDetectorType == GOTTHARD) && (shortFrame == -1)) + tempframenum = (((((uint32_t)(*((uint32_t*)(buf + HEADER_SIZE_NUM_TOT_PACKETS))))+1)& (frameIndexMask)) >> frameIndexOffset); + else + tempframenum = ((((uint32_t)(*((uint32_t*)(buf + HEADER_SIZE_NUM_TOT_PACKETS))))& (frameIndexMask)) >> frameIndexOffset); + + if(numWriterThreads == 1) + currframenum = tempframenum; + else{ + if(tempframenum > currframenum) + currframenum = tempframenum; + } +#ifdef VERYDEBUG + cout << "tempframenum:" << dec << tempframenum << " curframenum:" << currframenum << endl; +#endif + + //lock + if(numWriterThreads > 1) + pthread_mutex_lock(&write_mutex); + + + //to create new file when max reached + packetsToSave = maxPacketsPerFile - packetsInFile; + if(packetsToSave > numpackets) + packetsToSave = numpackets; +/**next time offset is still plus header length*/ + fwrite(buf+offset, 1, packetsToSave * onePacketSize, sfilefd); + packetsInFile += packetsToSave; + packetsCaught += packetsToSave; + totalPacketsCaught += packetsToSave; + + + //new file + if(packetsInFile >= maxPacketsPerFile){ + //for packet loss + lastpacket = (((packetsToSave - 1) * onePacketSize) + offset); + if(myDetectorType == EIGER); + else if ((myDetectorType == GOTTHARD) && (shortFrame == -1)) + tempframenum = (((((uint32_t)(*((uint32_t*)(buf + lastpacket))))+1)& (frameIndexMask)) >> frameIndexOffset); + else + tempframenum = ((((uint32_t)(*((uint32_t*)(buf + lastpacket))))& (frameIndexMask)) >> frameIndexOffset); + + if(numWriterThreads == 1) + currframenum = tempframenum; + else{ + if(tempframenum > currframenum) + currframenum = tempframenum; + } +#ifdef VERYDEBUG + cout << "tempframenum:" << dec << tempframenum << " curframenum:" << currframenum << endl; +#endif + //create + createNewFile(); + } + + //unlock + if(numWriterThreads > 1) + pthread_mutex_unlock(&write_mutex); + + + offset += (packetsToSave * onePacketSize); + numpackets -= packetsToSave; + } + + } + else{ + if(numWriterThreads > 1) + pthread_mutex_lock(&write_mutex); + packetsInFile += numpackets; + packetsCaught += numpackets; + totalPacketsCaught += numpackets; + if(numWriterThreads > 1) + pthread_mutex_unlock(&write_mutex); + } +} + + + + + + + + + + + + + + +void UDPStandardImplementation::handleDataCompression(int ithread, char* wbuffer[], int &npackets, char* data, int xmax, int ymax, int &nf){ + +#if defined(MYROOT1) && defined(ALLFILE_DEBUG) + writeToFile_withoutCompression(wbuf[0], numpackets,currframenum); +#endif + + eventType thisEvent = PEDESTAL; + int ndata; + char* buff = 0; + data = wbuffer[0]+ HEADER_SIZE_NUM_TOT_PACKETS; + int remainingsize = npackets * onePacketSize; + int np; + int once = 0; + double tot, tl, tr, bl, br; + int xmin = 1, ymin = 1, ix, iy; + + + while(buff = receiverdata[ithread]->findNextFrame(data,ndata,remainingsize)){ + np = ndata/onePacketSize; + + //cout<<"buff framnum:"<> frameIndexOffset)<newFrame(); + + //only for moench + if(commonModeSubtractionEnable){ + for(ix = xmin - 1; ix < xmax+1; ix++){ + for(iy = ymin - 1; iy < ymax+1; iy++){ + thisEvent = singlePhotonDet[ithread]->getEventType(buff, ix, iy, 0); + } + } + } + + + for(ix = xmin - 1; ix < xmax+1; ix++) + for(iy = ymin - 1; iy < ymax+1; iy++){ + thisEvent=singlePhotonDet[ithread]->getEventType(buff, ix, iy, commonModeSubtractionEnable); + if (nf>1000) { + tot=0; + tl=0; + tr=0; + bl=0; + br=0; + if (thisEvent==PHOTON_MAX) { + receiverdata[ithread]->getFrameNumber(buff); + //iFrame=receiverdata[ithread]->getFrameNumber(buff); +#ifdef MYROOT1 + myTree[ithread]->Fill(); + //cout << "Fill in event: frmNr: " << iFrame << " ix " << ix << " iy " << iy << " type " << thisEvent << endl; +#else + pthread_mutex_lock(&write_mutex); + if((enableFileWrite) && (sfilefd)) + singlePhotonDet[ithread]->writeCluster(sfilefd); + pthread_mutex_unlock(&write_mutex); +#endif + } + } + } + + nf++; +#ifndef ALLFILE + pthread_mutex_lock(&progress_mutex); + packetsInFile += packetsPerFrame; + packetsCaught += packetsPerFrame; + totalPacketsCaught += packetsPerFrame; + if(packetsInFile >= maxPacketsPerFile) + createNewFile(); + pthread_mutex_unlock(&progress_mutex); + +#endif + if(!once){ + copyFrameToGui(NULL,-1,buff); + once = 1; + } + } + + remainingsize -= ((buff + ndata) - data); + data = buff + ndata; + if(data > (wbuffer[0] + HEADER_SIZE_NUM_TOT_PACKETS + npackets * onePacketSize) ) + cout <<" **************ERROR SHOULD NOT COME HERE, Error 142536!"<push(wbuffer[0])); +#ifdef VERYVERBOSE + cout<<"buf freed:"<<(void*)wbuffer[0]<= 0){ + + tengigaEnable = enable; + + if(myDetectorType == EIGER){ + + if(!tengigaEnable){ + packetsPerFrame = EIGER_ONE_GIGA_CONSTANT * dynamicRange * EIGER_MAX_PORTS; + onePacketSize = EIGER_ONE_GIGA_ONE_PACKET_SIZE; + maxPacketsPerFile = EIGER_MAX_FRAMES_PER_FILE * packetsPerFrame; + }else{ + packetsPerFrame = EIGER_TEN_GIGA_CONSTANT * dynamicRange * EIGER_MAX_PORTS; + onePacketSize = EIGER_TEN_GIGA_ONE_PACKET_SIZE; + maxPacketsPerFile = EIGER_MAX_FRAMES_PER_FILE * packetsPerFrame*4; + } + frameSize = onePacketSize * packetsPerFrame; + bufferSize = (frameSize/EIGER_MAX_PORTS) + EIGER_HEADER_LENGTH;//everything one port gets (img header plus packets) + //maxPacketsPerFile = EIGER_MAX_FRAMES_PER_FILE * packetsPerFrame; + + + cout<<"packetsPerFrame:"< +#include +#endif + + +#include +#include +#include +#include + + +/** + * @short does all the functions for a receiver, set/get parameters, start/stop etc. + */ + + +class UDPStandardImplementation: private virtual slsReceiverDefs, public UDPBaseImplementation { + public: + /** + * Constructor + */ +UDPStandardImplementation(); + + /** + * Destructor + */ + virtual ~UDPStandardImplementation(); + + + + /** + * delete and free member parameters + */ + void deleteMembers(); + + /** + * initialize member parameters + */ + void initializeMembers(); + + /** + * Set receiver type + * @param det detector type + * Returns success or FAIL + */ + int setDetectorType(detectorType det); + + + //Frame indices and numbers caught + /** + * Returns current Frame Index Caught for an entire acquisition (including all scans) + */ + //uint32_t getAcquisitionIndex(); + + /** + * Returns if acquisition started + */ + //bool getAcquistionStarted(); + + /** + * Returns Frames Caught for each real time acquisition (eg. for each scan) + */ + //int getFramesCaught(); + + /** + * Returns Total Frames Caught for an entire acquisition (including all scans) + */ + //int getTotalFramesCaught(); + + /** + * Returns the frame index at start of each real time acquisition (eg. for each scan) + */ + //uint32_t getStartFrameIndex(); + + /** + * Returns current Frame Index for each real time acquisition (eg. for each scan) + */ + //uint32_t getFrameIndex(); + + /** + * Returns if measurement started + */ + //bool getMeasurementStarted(); + + /** + * Resets the Total Frames Caught + * This is how the receiver differentiates between entire acquisitions + * Returns 0 + */ + //void resetTotalFramesCaught(); + + + //file parameters + /** + * Returns File Path + */ + //char* getFilePath() const; + + /** + * Set File Path + * @param c file path + */ + //char* setFilePath(const char c[]); + + /** + * Returns File Name + */ + //char* getFileName() const; + + /** + * Set File Name (without frame index, file index and extension) + * @param c file name + */ + //char* setFileName(const char c[]); + + /** + * Returns File Index + */ + //int getFileIndex(); + + /** + * Set File Index + * @param i file index + */ + //int setFileIndex(int i); + + /** + * Set Frame Index Needed + * @param i frame index needed + */ + //int setFrameIndexNeeded(int i); + + /** + * Set enable file write + * @param i file write enable + * Returns file write enable + */ + //int setEnableFileWrite(int i); + + /** + * Enable/disable overwrite + * @param i enable + * Returns enable over write + */ + //int setEnableOverwrite(int i); + + /** + * Returns file write enable + * 1: YES 0: NO + */ + //int getEnableFileWrite() const; + + /** + * Returns file over write enable + * 1: YES 0: NO + */ + //int getEnableOverwrite() const; + +//other parameters + + /** + * abort acquisition with minimum damage: close open files, cleanup. + * does nothing if state already is 'idle' + */ + void abort() {}; + + /** + * Returns status of receiver: idle, running or error + */ + runStatus getStatus() const; + + /** + * Set detector hostname + * @param c hostname + */ + void initialize(const char *detectorHostName); + + /* Returns detector hostname + /returns hostname + * caller needs to deallocate the returned char array. + * if uninitialized, it must return NULL + */ + char *getDetectorHostname() const; + + /** + * Set Ethernet Interface or IP to listen to + */ + void setEthernetInterface(char* c); + + /** + * Set UDP Port Number + */ + void setUDPPortNo(int p); + + /* + * Returns number of frames to receive + * This is the number of frames to expect to receiver from the detector. + * The data receiver will change from running to idle when it got this number of frames + */ + int getNumberOfFrames() const; + + /** + * set frame number if a positive number + */ + int32_t setNumberOfFrames(int32_t fnum); + + /** + * Returns scan tag + */ + int getScanTag() const; + + /** + * set scan tag if its is a positive number + */ + int32_t setScanTag(int32_t stag); + + /** + * Returns the number of bits per pixel + */ + int getDynamicRange() const; + + /** + * set dynamic range if its is a positive number + */ + int32_t setDynamicRange(int32_t dr); + + /** + * Set short frame + * @param i if shortframe i=1 + */ + int setShortFrame(int i); + + /** + * Set the variable to send every nth frame to gui + * or if 0,send frame only upon gui request + */ + int setNFrameToGui(int i); + + /** set acquisition period if a positive number + */ + int64_t setAcquisitionPeriod(int64_t index); + + /** get data compression, by saving only hits + */ + bool getDataCompression(); + + /** enabl data compression, by saving only hits + /returns if failed + */ + int enableDataCompression(bool enable); + + /** + * enable 10Gbe + @param enable 1 for 10Gbe or 0 for 1 Gbe, -1 to read out + \returns enable for 10Gbe + */ + int enableTenGiga(int enable = -1); + + + +//other functions + + /** + * Returns the buffer-current frame read by receiver + * @param c pointer to current file name + * @param raw address of pointer, pointing to current frame to send to gui + * @param fnum frame number for eiger as it is not in the packet + */ + void readFrame(char* c,char** raw, uint32_t &fnum); + + /** + * Closes all files + * @param ithr thread index + */ + void closeFile(int ithr = -1); + + /** + * Starts Receiver - starts to listen for packets + * @param message is the error message if there is an error + * Returns success + */ + int startReceiver(char message[]); + + /** + * Stops Receiver - stops listening for packets + * Returns success + */ + int stopReceiver(); + + /** set status to transmitting and + * when fifo is empty later, sets status to run_finished + */ + void startReadout(); + + /** + * shuts down the udp sockets + * \returns if success or fail + */ + int shutDownUDPSockets(); + +private: + + /* + void not_implemented(string method_name){ + std::cout << "[WARNING] Method " << method_name << " not implemented!" << std::endl; + }; + */ + /** + * Deletes all the filter objects for single photon data + */ + void deleteFilter(); + + /** + * Constructs the filter for single photon data + */ + void setupFilter(); + + /** + * set up fifo according to the new numjobsperthread + */ + void setupFifoStructure (); + + /** + * Copy frames to gui + * uses semaphore for nth frame mode + */ + void copyFrameToGui(char* startbuf[], uint32_t fnum=-1, char* buf=NULL); + + /** + * creates udp sockets + * \returns if success or fail + */ + int createUDPSockets(); + + /** + * create listening thread + * @param destroy is true to kill all threads and start again + */ + int createListeningThreads(bool destroy = false); + + /** + * create writer threads + * @param destroy is true to kill all threads and start again + */ + int createWriterThreads(bool destroy = false); + + /** + * set thread priorities + */ + void setThreadPriorities(); + + /** + * initializes variables and creates the first file + * also does the startAcquisitionCallBack + * \returns FAIL or OK + */ + int setupWriter(); + + /** + * Creates new tree and file for compression + * @param ithr thread number + * @param iframe frame number + *\returns OK for succces or FAIL for failure + */ + int createCompressionFile(int ithr, int iframe); + + /** + * Creates new file + *\returns OK for succces or FAIL for failure + */ + int createNewFile(); + + /** + * Static function - Thread started which listens to packets. + * Called by startReceiver() + * @param this_pointer pointer to this object + */ + static void* startListeningThread(void *this_pointer); + + /** + * Static function - Thread started which writes packets to file. + * Called by startReceiver() + * @param this_pointer pointer to this object + */ + static void* startWritingThread(void *this_pointer); + + /** + * Thread started which listens to packets. + * Called by startReceiver() + * + */ + int startListening(); + + /** + * Thread started which writes packets to file. + * Called by startReceiver() + * + */ + int startWriting(); + + /** + * Writing to file without compression + * @param buf is the address of buffer popped out of fifo + * @param numpackets is the number of packets + * @param framenum current frame number + */ + void writeToFile_withoutCompression(char* buf,int numpackets, uint32_t framenum); + + /** + * Its called for the first packet of a scan or acquistion + * Sets the startframeindices and the variables to know if acquisition started + * @param ithread listening thread number + */ + void startFrameIndices(int ithread); + + /** + * This is called when udp socket is shut down + * It pops ffff instead of packet number into fifo + * to inform writers about the end of listening session + * @param ithread listening thread number + * @param rc number of bytes received + * @param pc packet count + * @param t total packets listened to + */ + void stopListening(int ithread, int rc, int &pc, int &t); + + /** + * When acquisition is over, this is called + * @param ithread listening thread number + * @param wbuffer writer buffer + */ + void stopWriting(int ithread, char* wbuffer[]); + + + /** + * data compression for each fifo output + * @param ithread listening thread number + * @param wbuffer writer buffer + * @param npackets number of packets from the fifo + * @param data pointer to the next packet start + * @param xmax max pixels in x direction + * @param ymax max pixels in y direction + * @param nf nf + */ + void handleDataCompression(int ithread, char* wbuffer[], int &npackets, char* data, int xmax, int ymax, int &nf); + + + /** structure of an eiger image header*/ + typedef struct + { + unsigned char header_before[20]; + unsigned char fnum[4]; + unsigned char header_after[24]; + } eiger_image_header; + + + /** structure of an eiger image header*/ + typedef struct + { + unsigned char num1[4]; + unsigned char num2[4]; + } eiger_packet_header; + + /** max number of listening threads */ + const static int MAX_NUM_LISTENING_THREADS = EIGER_MAX_PORTS; + + /** max number of writer threads */ + const static int MAX_NUM_WRITER_THREADS = 15; + + /** detector type */ + detectorType myDetectorType; + + /** detector hostname */ + char detHostname[MAX_STR_LENGTH]; + + /** status of receiver */ + runStatus status; + + /** UDP Socket between Receiver and Detector */ + genericSocket* udpSocket[MAX_NUM_LISTENING_THREADS]; + + /** Server UDP Port*/ + int server_port[MAX_NUM_LISTENING_THREADS]; + + /** ethernet interface or IP to listen to */ + char *eth; + + /** max packets per file **/ + int maxPacketsPerFile; + + /** File write enable */ + int enableFileWrite; + + /** File over write enable */ + int overwrite; + + /** Complete File name */ + char savefilename[MAX_STR_LENGTH]; + + /** File Name without frame index, file index and extension*/ + char fileName[MAX_STR_LENGTH]; + + /** File Path */ + char filePath[MAX_STR_LENGTH]; + + /** File Index */ + int fileIndex; + + /** scan tag */ + int scanTag; + + /** if frame index required in file name */ + int frameIndexNeeded; + + /* Acquisition started */ + bool acqStarted; + + /* Measurement started */ + bool measurementStarted; + + /** Frame index at start of each real time acquisition (eg. for each scan) */ + uint32_t startFrameIndex; + + /** Actual current frame index of each time acquisition (eg. for each scan) */ + uint32_t frameIndex; + + /** Frames Caught for each real time acquisition (eg. for each scan) */ + int packetsCaught; + + /** Total packets caught for an entire acquisition (including all scans) */ + int totalPacketsCaught; + + /** Pckets currently in current file, starts new file when it reaches max */ + int packetsInFile; + + /** Frame index at start of an entire acquisition (including all scans) */ + uint32_t startAcquisitionIndex; + + /** Actual current frame index of an entire acquisition (including all scans) */ + uint32_t acquisitionIndex; + + /** number of packets per frame*/ + int packetsPerFrame; + + /** frame index mask */ + uint32_t frameIndexMask; + + /** packet index mask */ + uint32_t packetIndexMask; + + /** frame index offset */ + int frameIndexOffset; + + /** acquisition period */ + int64_t acquisitionPeriod; + + /** frame number */ + int32_t numberOfFrames; + + /** dynamic range */ + int dynamicRange; + + /** short frames */ + int shortFrame; + + /** current frame number */ + uint32_t currframenum; + + /** Previous Frame number from buffer */ + uint32_t prevframenum; + + /** size of one frame */ + int frameSize; + + /** buffer size. different from framesize as we wait for one packet instead of frame for eiger */ + int bufferSize; + + /** oen buffer size */ + int onePacketSize; + + /** latest data */ + char* latestData; + + /** gui data ready */ + int guiDataReady; + + /** points to the data to send to gui */ + char* guiData; + + /** points to the filename to send to gui */ + char* guiFileName; + + /** temporary number for eiger frame number as its not included in the packet */ + uint32_t guiFrameNumber; + + /** send every nth frame to gui or only upon gui request*/ + int nFrameToGui; + + /** fifo size */ + unsigned int fifosize; + + /** number of jobs per thread for data compression */ + int numJobsPerThread; + + /** datacompression - save only hits */ + bool dataCompression; + + /** memory allocated for the buffer */ + char *mem0[MAX_NUM_LISTENING_THREADS]; + + /** circular fifo to store addresses of data read */ + CircularFifo* fifo[MAX_NUM_LISTENING_THREADS]; + + /** circular fifo to store addresses of data already written and ready to be resued*/ + CircularFifo* fifoFree[MAX_NUM_LISTENING_THREADS]; + + /** Receiver buffer */ + char *buffer[MAX_NUM_LISTENING_THREADS]; + + /** number of writer threads */ + int numListeningThreads; + + /** number of writer threads */ + int numWriterThreads; + + /** to know if listening and writer threads created properly */ + int thread_started; + + /** current listening thread index*/ + int currentListeningThreadIndex; + + /** current writer thread index*/ + int currentWriterThreadIndex; + + /** thread listening to packets */ + pthread_t listening_thread[MAX_NUM_LISTENING_THREADS]; + + /** thread writing packets */ + pthread_t writing_thread[MAX_NUM_WRITER_THREADS]; + + /** total frame count the listening thread has listened to */ + int totalListeningFrameCount[MAX_NUM_LISTENING_THREADS]; + + /** mask showing which listening threads are running */ + volatile uint32_t listeningthreads_mask; + + /** mask showing which writer threads are running */ + volatile uint32_t writerthreads_mask; + + /** mask showing which threads have created files*/ + volatile uint32_t createfile_mask; + + /** OK if file created was successful */ + int ret_createfile; + + /** variable used to self terminate threads waiting for semaphores */ + int killAllListeningThreads; + + /** variable used to self terminate threads waiting for semaphores */ + int killAllWritingThreads; + + /** 10Gbe enable*/ + int tengigaEnable; + + + + +//semaphores + /** semaphore to synchronize writer and guireader threads */ + sem_t smp; + /** semaphore to synchronize listener threads */ + sem_t listensmp[MAX_NUM_LISTENING_THREADS]; + /** semaphore to synchronize writer threads */ + sem_t writersmp[MAX_NUM_WRITER_THREADS]; + + +//mutex + /** guiDataReady mutex */ + pthread_mutex_t dataReadyMutex; + + /** mutex for status */ + pthread_mutex_t status_mutex; + + /** mutex for progress variable currframenum */ + pthread_mutex_t progress_mutex; + + /** mutex for writing data to file */ + pthread_mutex_t write_mutex; + + /** File Descriptor */ + FILE *sfilefd; + + //filter + singlePhotonDetector *singlePhotonDet[MAX_NUM_WRITER_THREADS]; + slsReceiverData *receiverdata[MAX_NUM_WRITER_THREADS]; + moenchCommonMode *cmSub; + bool commonModeSubtractionEnable; + +#ifdef MYROOT1 + /** Tree where the hits are stored */ + TTree *myTree[MAX_NUM_WRITER_THREADS]; + + /** File where the tree is saved */ + TFile *myFile[MAX_NUM_WRITER_THREADS]; +#endif + + + + /** + callback arguments are + filepath + filename + fileindex + data size + + return value is + 0 callback takes care of open,close,write file + 1 callback writes file, we have to open, close it + 2 we open, close, write file, callback does not do anything + + */ + int (*startAcquisitionCallBack)(char*, char*,int, int, void*); + void *pStartAcquisition; + + /** + args to acquisition finished callback + total frames caught + + */ + void (*acquisitionFinishedCallBack)(int, void*); + void *pAcquisitionFinished; + + + /** + args to raw data ready callback are + framenum + datapointer + datasize in bytes + file descriptor + guidatapointer (NULL, no data required) + */ + void (*rawDataReadyCallBack)(int, char*, int, FILE*, char*, void*); + void *pRawDataReady; + + /** The action which decides what the user and default responsibilites to save data are + * 0 raw data ready callback takes care of open,close,write file + * 1 callback writes file, we have to open, close it + * 2 we open, close, write file, callback does not do anything */ + int cbAction; + + +public: + + + /** + callback arguments are + filepath + filename + fileindex + datasize + + return value is + 0 callback takes care of open,close,wrie file + 1 callback writes file, we have to open, close it + 2 we open, close, write file, callback does not do anything + */ + void registerCallBackStartAcquisition(int (*func)(char*, char*,int, int, void*),void *arg){startAcquisitionCallBack=func; pStartAcquisition=arg;}; + + /** + callback argument is + toatal frames caught + */ + void registerCallBackAcquisitionFinished(void (*func)(int, void*),void *arg){acquisitionFinishedCallBack=func; pAcquisitionFinished=arg;}; + + /** + args to raw data ready callback are + framenum + datapointer + datasize in bytes + file descriptor + guidatapointer (NULL, no data required) + */ + void registerCallBackRawDataReady(void (*func)(int, char*, int, FILE*, char*, void*),void *arg){rawDataReadyCallBack=func; pRawDataReady=arg;}; +}; + + +#endif + +//#endif From c2b885f2306f368a92c411332607d0fa0253282c Mon Sep 17 00:00:00 2001 From: Maliakal Dhanya Date: Tue, 9 Sep 2014 17:01:43 +0200 Subject: [PATCH 026/474] version --- slsReceiverSoftware/gitInfo.txt | 8 ++++---- slsReceiverSoftware/includes/gitInfoReceiver.h | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/slsReceiverSoftware/gitInfo.txt b/slsReceiverSoftware/gitInfo.txt index cf5def048..355fd1524 100644 --- a/slsReceiverSoftware/gitInfo.txt +++ b/slsReceiverSoftware/gitInfo.txt @@ -1,9 +1,9 @@ Path: slsDetectorsPackage/slsReceiverSoftware URL: origin git@gitorious.psi.ch:sls_det_software/sls_receiver_software.git Repository Root: origin git@gitorious.psi.ch:sls_det_software/sls_receiver_software.git -Repsitory UUID: 1c259aeba8b068b9f6e550d63a9a3a14bd7d3ab7 -Revision: 6 +Repsitory UUID: d2553484f575ec21e35c0a782cc307f9e0115554 +Revision: 16 Branch: master Last Changed Author: Maliakal_Dhanya -Last Changed Rev: 6 -Last Changed Date: 2014-06-03 12:06:57 +0200 +Last Changed Rev: 16 +Last Changed Date: 2014-07-31 12:13:15 +0200 diff --git a/slsReceiverSoftware/includes/gitInfoReceiver.h b/slsReceiverSoftware/includes/gitInfoReceiver.h index 05f3c2ab6..586f715b0 100644 --- a/slsReceiverSoftware/includes/gitInfoReceiver.h +++ b/slsReceiverSoftware/includes/gitInfoReceiver.h @@ -1,11 +1,11 @@ //#define SVNPATH "" #define SVNURL "git@gitorious.psi.ch:sls_det_software/sls_receiver_software.git" //#define SVNREPPATH "" -#define SVNREPUUID "1c259aeba8b068b9f6e550d63a9a3a14bd7d3ab7" -//#define SVNREV 0x6 +#define SVNREPUUID "d2553484f575ec21e35c0a782cc307f9e0115554" +//#define SVNREV 0x16 //#define SVNKIND "" //#define SVNSCHED "" #define SVNAUTH "Maliakal_Dhanya" -#define SVNREV 0x6 -#define SVNDATE 0x20140603 +#define SVNREV 0x16 +#define SVNDATE 0x20140731 // From 811bac16ecc1a86ba329f6c327d17f04c408d926 Mon Sep 17 00:00:00 2001 From: Sala Leonardo Date: Tue, 9 Sep 2014 17:16:51 +0200 Subject: [PATCH 027/474] trying to make it work... --- slsReceiverSoftware/includes/logger.h | 56 +++++++++++---------------- 1 file changed, 23 insertions(+), 33 deletions(-) diff --git a/slsReceiverSoftware/includes/logger.h b/slsReceiverSoftware/includes/logger.h index a230a5266..be93f9fac 100644 --- a/slsReceiverSoftware/includes/logger.h +++ b/slsReceiverSoftware/includes/logger.h @@ -10,30 +10,25 @@ inline std::string NowTime(); enum TLogLevel {logERROR, logWARNING, logINFO, logDEBUG, logDEBUG1, logDEBUG2, logDEBUG3, logDEBUG4}; template -class Log -{ -public: - Log(); - virtual ~Log(); - std::ostringstream& Get(TLogLevel level = logINFO); -public: - static TLogLevel& ReportingLevel(); - static std::string ToString(TLogLevel level); - static TLogLevel FromString(const std::string& level); -protected: - std::ostringstream os; -private: - Log(const Log&); - Log& operator =(const Log&); +class Log{ + public: + Log(); + virtual ~Log(); + std::ostringstream& Get(TLogLevel level = logINFO); + public: + static TLogLevel& ReportingLevel(); + static std::string ToString(TLogLevel level); + static TLogLevel FromString(const std::string& level); + protected: + std::ostringstream os; + private: + Log(const Log&); + Log& operator =(const Log&); }; -template -Log::Log() -{ -} +template Log::Log() {} -template -std::ostringstream& Log::Get(TLogLevel level) +template std::ostringstream& Log::Get(TLogLevel level) { os << "- " << NowTime(); os << " " << ToString(level) << ": "; @@ -41,29 +36,25 @@ std::ostringstream& Log::Get(TLogLevel level) return os; } -template -Log::~Log() +template Log::~Log() { os << std::endl; T::Output(os.str()); } -template -TLogLevel& Log::ReportingLevel() +template TLogLevel& Log::ReportingLevel() { static TLogLevel reportingLevel = logDEBUG4; return reportingLevel; } -template -std::string Log::ToString(TLogLevel level) +template std::string Log::ToString(TLogLevel level) { static const char* const buffer[] = {"ERROR", "WARNING", "INFO", "DEBUG", "DEBUG1", "DEBUG2", "DEBUG3", "DEBUG4"}; return buffer[level]; } -template -TLogLevel Log::FromString(const std::string& level) +template TLogLevel Log::FromString(const std::string& level) { if (level == "DEBUG4") return logDEBUG4; @@ -85,15 +76,13 @@ TLogLevel Log::FromString(const std::string& level) return logINFO; } -class Output2FILE -{ +class Output2FILE { public: static FILE*& Stream(); static void Output(const std::string& msg); }; -inline FILE*& Output2FILE::Stream() -{ +inline FILE*& Output2FILE::Stream() { static FILE* pStream = stderr; return pStream; } @@ -136,6 +125,7 @@ class FILELOG_DECLSPEC FILELog : public Log {}; #include inline std::string NowTime() + { const int MAX_LEN = 200; char buffer[MAX_LEN]; From dc04efbbb1723d618b54540e56607959c3cff2c4 Mon Sep 17 00:00:00 2001 From: Sala Leonardo Date: Tue, 9 Sep 2014 18:13:31 +0200 Subject: [PATCH 028/474] working logger! --- slsReceiverSoftware/Makefile | 21 ++- slsReceiverSoftware/includes/logger.h | 157 ++++++++++-------- slsReceiverSoftware/includes/utilities.h | 20 +-- .../slsReceiver/UDPInterface.cpp | 7 +- .../slsReceiver/UDPInterface.h | 2 +- slsReceiverSoftware/slsReceiver/main.cpp | 1 + slsReceiverSoftware/slsReceiver/utilities.cpp | 66 ++++++++ 7 files changed, 180 insertions(+), 94 deletions(-) create mode 100644 slsReceiverSoftware/slsReceiver/utilities.cpp diff --git a/slsReceiverSoftware/Makefile b/slsReceiverSoftware/Makefile index 07de13672..a9f9f57dc 100644 --- a/slsReceiverSoftware/Makefile +++ b/slsReceiverSoftware/Makefile @@ -12,17 +12,25 @@ CFLAGS= -g -DC_ONLY -fPIC DFLAGS= -g -DDACS_INT -DSLS_RECEIVER_UDP_FUNCTIONS INCLUDES?= -I. -Iincludes -IMySocketTCP -IslsReceiver -IslsDetectorCalibration -I$(ASM) + #-IslsReceiverInterface -SRC_CLNT= MySocketTCP/MySocketTCP.cpp slsReceiver/UDPInterface.cpp slsReceiver/UDPBaseImplementation.cpp slsReceiver/UDPStandardImplementation.cpp slsReceiver/UDPRESTImplementation.cpp slsReceiver/slsReceiverTCPIPInterface.cpp slsReceiver/slsReceiver.cpp slsReceiver/slsReceiverUsers.cpp includes/utilities.h +SRC_CLNT = MySocketTCP/MySocketTCP.cpp slsReceiver/UDPInterface.cpp slsReceiver/UDPBaseImplementation.cpp slsReceiver/UDPStandardImplementation.cpp slsReceiver/slsReceiverTCPIPInterface.cpp slsReceiver/slsReceiver.cpp slsReceiver/slsReceiverUsers.cpp slsReceiver/utilities.cpp #slsReceiverInterface/receiverInterface.cpp #slsReceiver/slsReceiverUDPFunctions.cpp +#slsReceiver/utilities.cpp includes/logger.h +#ifeq ($(REST),yes) +# SRC_CLNT += slsReceiver/UDPRESTImplementation.cpp +# INCLUDES += $(RESTINCLUDE) +#endif -OBJS = $(SRC_CLNT:.cpp=.o) -OBJS += includes/utilities.h +OBJS=$(SRC_CLNT:.cpp=.o) +#OBJS = $(OBJS1:.h=.o) +#OBJS += slsReceiver/logger.o #OBJS += slsReceiver/eigerReceiver.o + .PHONY: all intdoc package eigerReceiver clean all: package $(SRC_CLNT) @@ -30,19 +38,23 @@ all: package $(SRC_CLNT) intdoc: $(SRC_H) $(SRC_CLNT) doxygen doxy.config - %.o : %.cpp Makefile ifeq ($(ROOTSLS),yes) echo "with root" $(CXX) -DROOTSLS -o $@ -c $< $(INCLUDES) $(DFLAGS) $(ROOTFLAGS) -fPIC $(EPICSFLAGS) -L/usr/lib64/ #$(FLAGS) else echo "without root" + echo $(REST) + echo $(INCLUDES) $(CXX) -o $@ -c $< $(INCLUDES) $(DFLAGS) -fPIC $(EPICSFLAGS) -lpthread #$(FLAGS) endif # LEO: not satisfied by eigerReceiver package: $(OBJS) $(DESTDIR)/libSlsReceiver.so $(DESTDIR)/libSlsReceiver.a +#slsReceiver/logger.o: +# $(CXX) -o $@ -c includes/logger.h $(INCLUDES) $(DFLAGS) -fPIC $(EPICSFLAGS) -lpthread #$(FLAGS) + #eigerReceiver: # echo "src client:" $(SRC_CLNT) # cd slsReceiver && make eigerReceiver @@ -57,6 +69,7 @@ $(DESTDIR)/libSlsReceiver.a: $(OBJS) mv libSlsReceiver.a $(DESTDIR) clean: + echo rm -rf $(OBJS) rm -rf $(OBJS) cd slsReceiver && make clean cd diff --git a/slsReceiverSoftware/includes/logger.h b/slsReceiverSoftware/includes/logger.h index be93f9fac..eda43b0b0 100644 --- a/slsReceiverSoftware/includes/logger.h +++ b/slsReceiverSoftware/includes/logger.h @@ -1,5 +1,5 @@ -#ifndef __LOG_H__ -#define __LOG_H__ +//#ifndef __LOG_H__ +//#define __LOG_H__ #include #include @@ -9,13 +9,11 @@ inline std::string NowTime(); enum TLogLevel {logERROR, logWARNING, logINFO, logDEBUG, logDEBUG1, logDEBUG2, logDEBUG3, logDEBUG4}; -template -class Log{ +template class Log{ public: Log(); virtual ~Log(); std::ostringstream& Get(TLogLevel level = logINFO); - public: static TLogLevel& ReportingLevel(); static std::string ToString(TLogLevel level); static TLogLevel FromString(const std::string& level); @@ -26,55 +24,6 @@ class Log{ Log& operator =(const Log&); }; -template Log::Log() {} - -template std::ostringstream& Log::Get(TLogLevel level) -{ - os << "- " << NowTime(); - os << " " << ToString(level) << ": "; - os << std::string(level > logDEBUG ? level - logDEBUG : 0, '\t'); - return os; -} - -template Log::~Log() -{ - os << std::endl; - T::Output(os.str()); -} - -template TLogLevel& Log::ReportingLevel() -{ - static TLogLevel reportingLevel = logDEBUG4; - return reportingLevel; -} - -template std::string Log::ToString(TLogLevel level) -{ - static const char* const buffer[] = {"ERROR", "WARNING", "INFO", "DEBUG", "DEBUG1", "DEBUG2", "DEBUG3", "DEBUG4"}; - return buffer[level]; -} - -template TLogLevel Log::FromString(const std::string& level) -{ - if (level == "DEBUG4") - return logDEBUG4; - if (level == "DEBUG3") - return logDEBUG3; - if (level == "DEBUG2") - return logDEBUG2; - if (level == "DEBUG1") - return logDEBUG1; - if (level == "DEBUG") - return logDEBUG; - if (level == "INFO") - return logINFO; - if (level == "WARNING") - return logWARNING; - if (level == "ERROR") - return logERROR; - Log().Get(logWARNING) << "Unknown logging level '" << level << "'. Using INFO level as default."; - return logINFO; -} class Output2FILE { public: @@ -82,20 +31,6 @@ public: static void Output(const std::string& msg); }; -inline FILE*& Output2FILE::Stream() { - static FILE* pStream = stderr; - return pStream; -} - -inline void Output2FILE::Output(const std::string& msg) -{ - FILE* pStream = Stream(); - if (!pStream) - return; - fprintf(pStream, "%s", msg.c_str()); - fflush(pStream); -} - #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) # if defined (BUILDING_FILELOG_DLL) # define FILELOG_DECLSPEC __declspec (dllexport) @@ -124,6 +59,8 @@ class FILELOG_DECLSPEC FILELog : public Log {}; #include + + inline std::string NowTime() { @@ -159,4 +96,86 @@ inline std::string NowTime() #endif //WIN32 -#endif //__LOG_H__ + +template Log::Log(){} + +template std::ostringstream& Log::Get(TLogLevel level) +{ + os << "- " << NowTime(); + os << " " << ToString(level) << ": "; + os << std::string(level > logDEBUG ? level - logDEBUG : 0, '\t'); + return os; +} + +template Log::~Log() +{ + os << std::endl; + T::Output(os.str()); +} + +template TLogLevel& Log::ReportingLevel() +{ + static TLogLevel reportingLevel = logDEBUG4; + return reportingLevel; +} + +template std::string Log::ToString(TLogLevel level) +{ + static const char* const buffer[] = {"ERROR", "WARNING", "INFO", "DEBUG", "DEBUG1", "DEBUG2", "DEBUG3", "DEBUG4"}; + return buffer[level]; +} + +template +TLogLevel Log::FromString(const std::string& level) +{ + if (level == "DEBUG4") + return logDEBUG4; + if (level == "DEBUG3") + return logDEBUG3; + if (level == "DEBUG2") + return logDEBUG2; + if (level == "DEBUG1") + return logDEBUG1; + if (level == "DEBUG") + return logDEBUG; + if (level == "INFO") + return logINFO; + if (level == "WARNING") + return logWARNING; + if (level == "ERROR") + return logERROR; + Log().Get(logWARNING) << "Unknown logging level '" << level << "'. Using INFO level as default."; + return logINFO; +} + + +inline FILE*& Output2FILE::Stream() +{ + static FILE* pStream = stderr; + return pStream; +} + +inline void Output2FILE::Output(const std::string& msg) +{ + FILE* pStream = Stream(); + if (!pStream) + return; + fprintf(pStream, "%s", msg.c_str()); + fflush(pStream); +} + +#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) +# if defined (BUILDING_FILELOG_DLL) +# define FILELOG_DECLSPEC __declspec (dllexport) +# elif defined (USING_FILELOG_DLL) +# define FILELOG_DECLSPEC __declspec (dllimport) +# else +# define FILELOG_DECLSPEC +# endif // BUILDING_DBSIMPLE_DLL +#else +# define FILELOG_DECLSPEC +#endif // _WIN32 + + + +//#endif //__LOG_H__ diff --git a/slsReceiverSoftware/includes/utilities.h b/slsReceiverSoftware/includes/utilities.h index e55d81598..78a99bcbc 100644 --- a/slsReceiverSoftware/includes/utilities.h +++ b/slsReceiverSoftware/includes/utilities.h @@ -3,27 +3,11 @@ #include #include using namespace std; +#include "sls_receiver_defs.h" /* uncomment next line to enable debug output */ //#define EIGER_DEBUG -/* macro for debug output http://stackoverflow.com/a/14256296 */ -#ifdef EIGER_DEBUG -#define DEBUG(x) do { std::cerr << x << std::endl; } while (0) -#else -#define DEBUG(x) -#endif -#ifdef VERBOSE -#define VERBOSE_PRINT(x) do { std::cout << "[VERBOSE]" << x << std::endl; } while (0) -#else -#define VERBOSE_PRINT(x) -#endif - - - - - - -inline int read_config_file(string fname, int *tcpip_port_no); +int read_config_file(string fname, int *tcpip_port_no); diff --git a/slsReceiverSoftware/slsReceiver/UDPInterface.cpp b/slsReceiverSoftware/slsReceiver/UDPInterface.cpp index 650166a6e..a0d771687 100644 --- a/slsReceiverSoftware/slsReceiver/UDPInterface.cpp +++ b/slsReceiverSoftware/slsReceiver/UDPInterface.cpp @@ -34,8 +34,11 @@ UDPInterface * UDPInterface::create(string receiver_type){ cout << "Starting " << receiver_type << endl; return new UDPStandardImplementation(); } - //else if (receiver_type == "REST") - // return new UDPRESTImplementation(); + +#ifdef REST + else if (receiver_type == "REST") + return new UDPRESTImplementation(); +#endif else{ FILE_LOG(logWARNING) << "[ERROR] UDP interface not supported, using standard implementation"; return new UDPBaseImplementation(); diff --git a/slsReceiverSoftware/slsReceiver/UDPInterface.h b/slsReceiverSoftware/slsReceiver/UDPInterface.h index 77cfe3e7e..5c497167d 100644 --- a/slsReceiverSoftware/slsReceiver/UDPInterface.h +++ b/slsReceiverSoftware/slsReceiver/UDPInterface.h @@ -17,7 +17,7 @@ #include "MySocketTCP.h" #include "utilities.h" - +#include "logger.h" /* void print_not_implemented(string method_name){ diff --git a/slsReceiverSoftware/slsReceiver/main.cpp b/slsReceiverSoftware/slsReceiver/main.cpp index 14fb01d0e..32adb96be 100644 --- a/slsReceiverSoftware/slsReceiver/main.cpp +++ b/slsReceiverSoftware/slsReceiver/main.cpp @@ -8,6 +8,7 @@ #include #include "utilities.h" +#include "logger.h" using namespace std; diff --git a/slsReceiverSoftware/slsReceiver/utilities.cpp b/slsReceiverSoftware/slsReceiver/utilities.cpp new file mode 100644 index 000000000..ae401a5cc --- /dev/null +++ b/slsReceiverSoftware/slsReceiver/utilities.cpp @@ -0,0 +1,66 @@ +#include +#include +#include +#include +#include +#include + +#include "utilities.h" + + +using namespace std; + + +int read_config_file(string fname, int *tcpip_port_no){ + + ifstream infile; + string sLine,sargname; + int iline = 0; + int success = slsReceiverDefs::OK; + + infile.open(fname.c_str(), ios_base::in); + if (infile.is_open()) { + while(infile.good()){ + getline(infile,sLine); + iline++; + + //VERBOSE_PRINT(sLine); + + if(sLine.find('#')!=string::npos){ + //VERBOSE_PRINT( "Line is a comment "); + continue; + } + else if(sLine.length()<2){ + //VERBOSE_PRINT("Empty line "); + continue; + } + else{ + istringstream sstr(sLine); + + //parameter name + if(sstr.good()) + sstr >> sargname; + + //tcp port + if(sargname=="rx_tcpport"){ + if(sstr.good()) { + sstr >> sargname; + if(sscanf(sargname.c_str(),"%d",tcpip_port_no)) + cout<<"dataport:"< Date: Wed, 10 Sep 2014 09:19:35 +0200 Subject: [PATCH 029/474] cleaning the project --- slsReceiverSoftware/Makefile | 52 ++++++++---------- slsReceiverSoftware/MySocketTCP/._.DS_Store | Bin 82 -> 0 bytes slsReceiverSoftware/MySocketTCP/Makefile | 23 -------- slsReceiverSoftware/MySocketTCP/MySocketTCP.c | 1 - .../MySocketTCP/MySocketTCP.cpp | 1 - slsReceiverSoftware/MySocketTCP/rec | Bin 14727 -> 0 bytes slsReceiverSoftware/MySocketTCP/send | Bin 14960 -> 0 bytes .../{MySocketTCP => include}/MySocketTCP.h | 0 .../{includes => include}/circularFifo.h | 0 .../{MySocketTCP => include}/genericSocket.h | 0 .../{includes => include}/gitInfoReceiver.h | 0 .../gitInfoReceiverTmp.h | 0 .../{includes => include}/logger.h | 0 .../{includes => include}/receiver_defs.h | 0 .../{includes => include}/sls_receiver_defs.h | 0 .../sls_receiver_funcs.h | 0 .../{includes => include}/utilities.h | 0 .../{slsReceiver => src}/.cproject | 0 .../{slsReceiver => src}/.project | 0 .../{slsReceiver => src}/Makefile | 4 -- .../MySocketTCP.cxx => src/MySocketTCP.cpp} | 0 .../{slsReceiver => src}/RestHelper.h | 0 .../UDPBaseImplementation.cpp | 0 .../UDPBaseImplementation.h | 0 .../{slsReceiver => src}/UDPInterface.cpp | 0 .../{slsReceiver => src}/UDPInterface.h | 0 .../UDPRESTImplementation.cpp | 0 .../UDPRESTImplementation.h | 0 .../UDPStandardImplementation.cpp | 0 .../UDPStandardImplementation.h | 0 .../eigerReceiver/RestHelper.h | 0 .../eigerReceiver/eigerReceiver.cpp | 0 .../eigerReceiver/eigerReceiver.h | 0 .../eigerReceiver/eigerReceiverDummy.cpp | 0 .../eigerReceiver/eigerReceiverTest.cpp | 0 .../{slsReceiver => src}/main.cpp | 0 .../{MySocketTCP => src}/rec.cxx | 0 .../{MySocketTCP => src}/send.cxx | 0 .../{slsReceiver => src}/slsReceiver.cpp | 0 .../{slsReceiver => src}/slsReceiver.h | 0 .../slsReceiverTCPIPInterface.cpp | 0 .../slsReceiverTCPIPInterface.h | 0 .../slsReceiverUDPFunctions.h | 0 .../{slsReceiver => src}/slsReceiverUsers.cpp | 0 .../{slsReceiver => src}/slsReceiverUsers.h | 0 .../{slsReceiver => src}/utilities.cpp | 0 46 files changed, 24 insertions(+), 57 deletions(-) delete mode 100644 slsReceiverSoftware/MySocketTCP/._.DS_Store delete mode 100644 slsReceiverSoftware/MySocketTCP/Makefile delete mode 120000 slsReceiverSoftware/MySocketTCP/MySocketTCP.c delete mode 120000 slsReceiverSoftware/MySocketTCP/MySocketTCP.cpp delete mode 100755 slsReceiverSoftware/MySocketTCP/rec delete mode 100755 slsReceiverSoftware/MySocketTCP/send rename slsReceiverSoftware/{MySocketTCP => include}/MySocketTCP.h (100%) rename slsReceiverSoftware/{includes => include}/circularFifo.h (100%) rename slsReceiverSoftware/{MySocketTCP => include}/genericSocket.h (100%) rename slsReceiverSoftware/{includes => include}/gitInfoReceiver.h (100%) rename slsReceiverSoftware/{includes => include}/gitInfoReceiverTmp.h (100%) rename slsReceiverSoftware/{includes => include}/logger.h (100%) rename slsReceiverSoftware/{includes => include}/receiver_defs.h (100%) rename slsReceiverSoftware/{includes => include}/sls_receiver_defs.h (100%) rename slsReceiverSoftware/{includes => include}/sls_receiver_funcs.h (100%) rename slsReceiverSoftware/{includes => include}/utilities.h (100%) rename slsReceiverSoftware/{slsReceiver => src}/.cproject (100%) rename slsReceiverSoftware/{slsReceiver => src}/.project (100%) rename slsReceiverSoftware/{slsReceiver => src}/Makefile (92%) rename slsReceiverSoftware/{MySocketTCP/MySocketTCP.cxx => src/MySocketTCP.cpp} (100%) rename slsReceiverSoftware/{slsReceiver => src}/RestHelper.h (100%) rename slsReceiverSoftware/{slsReceiver => src}/UDPBaseImplementation.cpp (100%) rename slsReceiverSoftware/{slsReceiver => src}/UDPBaseImplementation.h (100%) rename slsReceiverSoftware/{slsReceiver => src}/UDPInterface.cpp (100%) rename slsReceiverSoftware/{slsReceiver => src}/UDPInterface.h (100%) rename slsReceiverSoftware/{slsReceiver => src}/UDPRESTImplementation.cpp (100%) rename slsReceiverSoftware/{slsReceiver => src}/UDPRESTImplementation.h (100%) rename slsReceiverSoftware/{slsReceiver => src}/UDPStandardImplementation.cpp (100%) rename slsReceiverSoftware/{slsReceiver => src}/UDPStandardImplementation.h (100%) rename slsReceiverSoftware/{slsReceiver => src}/eigerReceiver/RestHelper.h (100%) rename slsReceiverSoftware/{slsReceiver => src}/eigerReceiver/eigerReceiver.cpp (100%) rename slsReceiverSoftware/{slsReceiver => src}/eigerReceiver/eigerReceiver.h (100%) rename slsReceiverSoftware/{slsReceiver => src}/eigerReceiver/eigerReceiverDummy.cpp (100%) rename slsReceiverSoftware/{slsReceiver => src}/eigerReceiver/eigerReceiverTest.cpp (100%) rename slsReceiverSoftware/{slsReceiver => src}/main.cpp (100%) rename slsReceiverSoftware/{MySocketTCP => src}/rec.cxx (100%) rename slsReceiverSoftware/{MySocketTCP => src}/send.cxx (100%) rename slsReceiverSoftware/{slsReceiver => src}/slsReceiver.cpp (100%) rename slsReceiverSoftware/{slsReceiver => src}/slsReceiver.h (100%) rename slsReceiverSoftware/{slsReceiver => src}/slsReceiverTCPIPInterface.cpp (100%) rename slsReceiverSoftware/{slsReceiver => src}/slsReceiverTCPIPInterface.h (100%) rename slsReceiverSoftware/{slsReceiver => src}/slsReceiverUDPFunctions.h (100%) rename slsReceiverSoftware/{slsReceiver => src}/slsReceiverUsers.cpp (100%) rename slsReceiverSoftware/{slsReceiver => src}/slsReceiverUsers.h (100%) rename slsReceiverSoftware/{slsReceiver => src}/utilities.cpp (100%) diff --git a/slsReceiverSoftware/Makefile b/slsReceiverSoftware/Makefile index a9f9f57dc..3b3f6c526 100644 --- a/slsReceiverSoftware/Makefile +++ b/slsReceiverSoftware/Makefile @@ -4,6 +4,8 @@ include ../Makefile.include DESTDIR ?= ../bin LIBDIR ?= $(DESTDIR) DOCDIR ?= docs +SRCDIR = src +PROGS = $(DESTDIR)/slsReceiver CFLAGS= -g -DC_ONLY -fPIC @@ -11,53 +13,34 @@ CFLAGS= -g -DC_ONLY -fPIC DFLAGS= -g -DDACS_INT -DSLS_RECEIVER_UDP_FUNCTIONS -INCLUDES?= -I. -Iincludes -IMySocketTCP -IslsReceiver -IslsDetectorCalibration -I$(ASM) +INCLUDES?= -Iinclude -IMySocketTCP -I../slsDetectorCalibration -I$(ASM) -#-IslsReceiverInterface +#-I$(SRCDIR)Interface -SRC_CLNT = MySocketTCP/MySocketTCP.cpp slsReceiver/UDPInterface.cpp slsReceiver/UDPBaseImplementation.cpp slsReceiver/UDPStandardImplementation.cpp slsReceiver/slsReceiverTCPIPInterface.cpp slsReceiver/slsReceiver.cpp slsReceiver/slsReceiverUsers.cpp slsReceiver/utilities.cpp -#slsReceiverInterface/receiverInterface.cpp -#slsReceiver/slsReceiverUDPFunctions.cpp -#slsReceiver/utilities.cpp includes/logger.h -#ifeq ($(REST),yes) -# SRC_CLNT += slsReceiver/UDPRESTImplementation.cpp -# INCLUDES += $(RESTINCLUDE) -#endif +SRC_CLNT = $(SRCDIR)/MySocketTCP.cpp $(SRCDIR)/UDPInterface.cpp $(SRCDIR)/UDPBaseImplementation.cpp $(SRCDIR)/UDPStandardImplementation.cpp $(SRCDIR)/slsReceiverTCPIPInterface.cpp $(SRCDIR)/slsReceiver.cpp $(SRCDIR)/slsReceiverUsers.cpp $(SRCDIR)/utilities.cpp +MAIN_SRC = $(SRCDIR)/main.cpp OBJS=$(SRC_CLNT:.cpp=.o) -#OBJS = $(OBJS1:.h=.o) -#OBJS += slsReceiver/logger.o -#OBJS += slsReceiver/eigerReceiver.o - .PHONY: all intdoc package eigerReceiver clean -all: package $(SRC_CLNT) +all: lib $(SRC_CLNT) receiver intdoc: $(SRC_H) $(SRC_CLNT) doxygen doxy.config %.o : %.cpp Makefile ifeq ($(ROOTSLS),yes) - echo "with root" $(CXX) -DROOTSLS -o $@ -c $< $(INCLUDES) $(DFLAGS) $(ROOTFLAGS) -fPIC $(EPICSFLAGS) -L/usr/lib64/ #$(FLAGS) else - echo "without root" - echo $(REST) - echo $(INCLUDES) $(CXX) -o $@ -c $< $(INCLUDES) $(DFLAGS) -fPIC $(EPICSFLAGS) -lpthread #$(FLAGS) endif -# LEO: not satisfied by eigerReceiver -package: $(OBJS) $(DESTDIR)/libSlsReceiver.so $(DESTDIR)/libSlsReceiver.a +lib: $(OBJS) $(DESTDIR)/libSlsReceiver.so $(DESTDIR)/libSlsReceiver.a -#slsReceiver/logger.o: -# $(CXX) -o $@ -c includes/logger.h $(INCLUDES) $(DFLAGS) -fPIC $(EPICSFLAGS) -lpthread #$(FLAGS) +receiver: $(DESTDIR)/slsReceiver -#eigerReceiver: -# echo "src client:" $(SRC_CLNT) -# cd slsReceiver && make eigerReceiver $(DESTDIR)/libSlsReceiver.so: $(OBJS) $(CXX) -shared -Wl,-soname,libSlsReceiver.so -o libSlsReceiver.so $(OBJS) -lc $(INCLUDES) $(DFLAGS) $(FLAGS) $(EPICSFLAGS) -L/usr/lib64 -lpthread @@ -68,10 +51,23 @@ $(DESTDIR)/libSlsReceiver.a: $(OBJS) ar rcs libSlsReceiver.a $(OBJS) mv libSlsReceiver.a $(DESTDIR) + +$(DESTDIR)/slsReceiver: lib + $(CXX) -o $@ $(MAIN_SRC) $(FLAGS) $(INCLUDES) $(CLAGS) $(LIBS) $(LDFLAGRXR) -fPIC +#$(EIGERFLAGS) + + +# Stand-alone Mysocket tests +mysocket_test: + g++ -c $(SRCDIR)/MySocketTCP.cpp -I include + g++ -o rec MySocketTCP.o $(SRCDIR)/rec.cxx -I include + g++ -o send MySocketTCP.o $(SRCDIR)/send.cxx -I include + + clean: - echo rm -rf $(OBJS) rm -rf $(OBJS) - cd slsReceiver && make clean + rm $(PROGS) + rm $(DESTDIR)/libSlsReceiver.a $(DESTDIR)/libSlsReceiver.so cd #------------------------------------------------------------------------------- diff --git a/slsReceiverSoftware/MySocketTCP/._.DS_Store b/slsReceiverSoftware/MySocketTCP/._.DS_Store deleted file mode 100644 index c9474ea62235481b7d27ae5a878d2b4070bc6e05..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 82 jcmZQz6=P>$V!#9-F-{;h0%8Rq2JwS{7!DlZEK~*nFE;@e diff --git a/slsReceiverSoftware/MySocketTCP/Makefile b/slsReceiverSoftware/MySocketTCP/Makefile deleted file mode 100644 index 69634f361..000000000 --- a/slsReceiverSoftware/MySocketTCP/Makefile +++ /dev/null @@ -1,23 +0,0 @@ - -TOBECLEANED = MySocketTCP.o - -PROGRAMS = rec send - -all: $(PROGRAMS) - -clean: - @rm -f $(TOBECLEANED) $(PROGRAMS) - -rec: MySocketTCP.o rec.cxx - g++ -o $@ $^ - @echo "$@ done" - -send: MySocketTCP.o send.cxx - g++ -o $@ $^ - @echo "$@ done" - -MySocketTCP.o: MySocketTCP.cxx MySocketTCP.h - g++ -c $< - @echo "$@ done" - - diff --git a/slsReceiverSoftware/MySocketTCP/MySocketTCP.c b/slsReceiverSoftware/MySocketTCP/MySocketTCP.c deleted file mode 120000 index a995312db..000000000 --- a/slsReceiverSoftware/MySocketTCP/MySocketTCP.c +++ /dev/null @@ -1 +0,0 @@ -MySocketTCP.cxx \ No newline at end of file diff --git a/slsReceiverSoftware/MySocketTCP/MySocketTCP.cpp b/slsReceiverSoftware/MySocketTCP/MySocketTCP.cpp deleted file mode 120000 index a995312db..000000000 --- a/slsReceiverSoftware/MySocketTCP/MySocketTCP.cpp +++ /dev/null @@ -1 +0,0 @@ -MySocketTCP.cxx \ No newline at end of file diff --git a/slsReceiverSoftware/MySocketTCP/rec b/slsReceiverSoftware/MySocketTCP/rec deleted file mode 100755 index b652bb8f4795994f4cbe47c47317b9aff8e3a018..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14727 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 Date: Wed, 10 Sep 2014 09:20:49 +0200 Subject: [PATCH 030/474] update gitignore --- slsReceiverSoftware/.gitignore | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/slsReceiverSoftware/.gitignore b/slsReceiverSoftware/.gitignore index ccb33f18f..b7e550b01 100644 --- a/slsReceiverSoftware/.gitignore +++ b/slsReceiverSoftware/.gitignore @@ -1,2 +1,6 @@ +*~ *.o -slsDetectorCalibration +GPATH +GRTAGS +GSYMS +GTAGS From 59fc6fbaf8ce255eb7fa3fef9166197300909f25 Mon Sep 17 00:00:00 2001 From: Sala Leonardo Date: Wed, 10 Sep 2014 09:39:11 +0200 Subject: [PATCH 031/474] moved .h into include. Second round of cleaning --- slsReceiverSoftware/.gitignore | 1 + slsReceiverSoftware/Makefile | 38 ++- .../{src => include}/RestHelper.h | 0 .../{src => include}/UDPBaseImplementation.h | 0 .../{src => include}/UDPInterface.h | 0 .../{src => include}/UDPRESTImplementation.h | 0 .../UDPStandardImplementation.h | 0 .../{src => include}/slsReceiver.h | 0 .../slsReceiverTCPIPInterface.h | 0 .../slsReceiverUDPFunctions.h | 0 .../{src => include}/slsReceiverUsers.h | 0 slsReceiverSoftware/src/Makefile | 66 ----- .../src/eigerReceiver/RestHelper.h | 195 -------------- .../src/eigerReceiver/eigerReceiver.cpp | 254 ------------------ .../src/eigerReceiver/eigerReceiver.h | 211 --------------- .../src/eigerReceiver/eigerReceiverDummy.cpp | 99 ------- .../src/eigerReceiver/eigerReceiverTest.cpp | 97 ------- slsReceiverSoftware/{src => test}/rec.cxx | 0 slsReceiverSoftware/{src => test}/send.cxx | 0 19 files changed, 25 insertions(+), 936 deletions(-) rename slsReceiverSoftware/{src => include}/RestHelper.h (100%) rename slsReceiverSoftware/{src => include}/UDPBaseImplementation.h (100%) rename slsReceiverSoftware/{src => include}/UDPInterface.h (100%) rename slsReceiverSoftware/{src => include}/UDPRESTImplementation.h (100%) rename slsReceiverSoftware/{src => include}/UDPStandardImplementation.h (100%) rename slsReceiverSoftware/{src => include}/slsReceiver.h (100%) rename slsReceiverSoftware/{src => include}/slsReceiverTCPIPInterface.h (100%) rename slsReceiverSoftware/{src => include}/slsReceiverUDPFunctions.h (100%) rename slsReceiverSoftware/{src => include}/slsReceiverUsers.h (100%) delete mode 100644 slsReceiverSoftware/src/Makefile delete mode 100644 slsReceiverSoftware/src/eigerReceiver/RestHelper.h delete mode 100644 slsReceiverSoftware/src/eigerReceiver/eigerReceiver.cpp delete mode 100644 slsReceiverSoftware/src/eigerReceiver/eigerReceiver.h delete mode 100644 slsReceiverSoftware/src/eigerReceiver/eigerReceiverDummy.cpp delete mode 100644 slsReceiverSoftware/src/eigerReceiver/eigerReceiverTest.cpp rename slsReceiverSoftware/{src => test}/rec.cxx (100%) rename slsReceiverSoftware/{src => test}/send.cxx (100%) diff --git a/slsReceiverSoftware/.gitignore b/slsReceiverSoftware/.gitignore index b7e550b01..038cff97e 100644 --- a/slsReceiverSoftware/.gitignore +++ b/slsReceiverSoftware/.gitignore @@ -1,5 +1,6 @@ *~ *.o +build GPATH GRTAGS GSYMS diff --git a/slsReceiverSoftware/Makefile b/slsReceiverSoftware/Makefile index 3b3f6c526..338cc9d9b 100644 --- a/slsReceiverSoftware/Makefile +++ b/slsReceiverSoftware/Makefile @@ -5,6 +5,8 @@ DESTDIR ?= ../bin LIBDIR ?= $(DESTDIR) DOCDIR ?= docs SRCDIR = src +TESTDIR = test +BUILDDIR = build PROGS = $(DESTDIR)/slsReceiver @@ -13,24 +15,24 @@ CFLAGS= -g -DC_ONLY -fPIC DFLAGS= -g -DDACS_INT -DSLS_RECEIVER_UDP_FUNCTIONS -INCLUDES?= -Iinclude -IMySocketTCP -I../slsDetectorCalibration -I$(ASM) +INCLUDES?= -Iinclude -I../slsDetectorCalibration -I$(ASM) #-I$(SRCDIR)Interface -SRC_CLNT = $(SRCDIR)/MySocketTCP.cpp $(SRCDIR)/UDPInterface.cpp $(SRCDIR)/UDPBaseImplementation.cpp $(SRCDIR)/UDPStandardImplementation.cpp $(SRCDIR)/slsReceiverTCPIPInterface.cpp $(SRCDIR)/slsReceiver.cpp $(SRCDIR)/slsReceiverUsers.cpp $(SRCDIR)/utilities.cpp -MAIN_SRC = $(SRCDIR)/main.cpp +SRC_CLNT = MySocketTCP.cpp UDPInterface.cpp UDPBaseImplementation.cpp UDPStandardImplementation.cpp slsReceiverTCPIPInterface.cpp slsReceiver.cpp slsReceiverUsers.cpp utilities.cpp +MAIN_SRC = main.cpp -OBJS=$(SRC_CLNT:.cpp=.o) +OBJS=$(SRC_CLNT:%.cpp=$(BUILDDIR)/%.o) .PHONY: all intdoc package eigerReceiver clean -all: lib $(SRC_CLNT) receiver +all: lib receiver intdoc: $(SRC_H) $(SRC_CLNT) doxygen doxy.config -%.o : %.cpp Makefile +$(BUILDDIR)/%.o : $(SRCDIR)/%.cpp Makefile ifeq ($(ROOTSLS),yes) $(CXX) -DROOTSLS -o $@ -c $< $(INCLUDES) $(DFLAGS) $(ROOTFLAGS) -fPIC $(EPICSFLAGS) -L/usr/lib64/ #$(FLAGS) else @@ -53,22 +55,30 @@ $(DESTDIR)/libSlsReceiver.a: $(OBJS) $(DESTDIR)/slsReceiver: lib - $(CXX) -o $@ $(MAIN_SRC) $(FLAGS) $(INCLUDES) $(CLAGS) $(LIBS) $(LDFLAGRXR) -fPIC + $(CXX) -o $@ $(SRCDIR)/$(MAIN_SRC) $(FLAGS) $(INCLUDES) $(CLAGS) $(LIBS) $(LDFLAGRXR) -fPIC #$(EIGERFLAGS) # Stand-alone Mysocket tests mysocket_test: - g++ -c $(SRCDIR)/MySocketTCP.cpp -I include - g++ -o rec MySocketTCP.o $(SRCDIR)/rec.cxx -I include - g++ -o send MySocketTCP.o $(SRCDIR)/send.cxx -I include + g++ -o $(TESTDIR)/MySocketTCP.o -c $(SRCDIR)/MySocketTCP.cpp -I include + g++ -o $(TESTDIR)/rec $(TESTDIR)/MySocketTCP.o $(TESTDIR)/rec.cxx -I include + g++ -o $(TESTDIR)/send $(TESTDIR)/MySocketTCP.o $(TESTDIR)/send.cxx -I include -clean: - rm -rf $(OBJS) +clean: buildclean + rm $(DESTDIR)/libSlsReceiver.a $(DESTDIR)/libSlsReceiver.so rm $(PROGS) - rm $(DESTDIR)/libSlsReceiver.a $(DESTDIR)/libSlsReceiver.so - cd + ifeq (,$(wildcard $(TESTDIR/rec))) + make testclean + endif + +buildclean: + rm -rf $(OBJS) + +testclean: + cd $(TESTDIR) && rm *.o rec send + #------------------------------------------------------------------------------- diff --git a/slsReceiverSoftware/src/RestHelper.h b/slsReceiverSoftware/include/RestHelper.h similarity index 100% rename from slsReceiverSoftware/src/RestHelper.h rename to slsReceiverSoftware/include/RestHelper.h diff --git a/slsReceiverSoftware/src/UDPBaseImplementation.h b/slsReceiverSoftware/include/UDPBaseImplementation.h similarity index 100% rename from slsReceiverSoftware/src/UDPBaseImplementation.h rename to slsReceiverSoftware/include/UDPBaseImplementation.h diff --git a/slsReceiverSoftware/src/UDPInterface.h b/slsReceiverSoftware/include/UDPInterface.h similarity index 100% rename from slsReceiverSoftware/src/UDPInterface.h rename to slsReceiverSoftware/include/UDPInterface.h diff --git a/slsReceiverSoftware/src/UDPRESTImplementation.h b/slsReceiverSoftware/include/UDPRESTImplementation.h similarity index 100% rename from slsReceiverSoftware/src/UDPRESTImplementation.h rename to slsReceiverSoftware/include/UDPRESTImplementation.h diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.h b/slsReceiverSoftware/include/UDPStandardImplementation.h similarity index 100% rename from slsReceiverSoftware/src/UDPStandardImplementation.h rename to slsReceiverSoftware/include/UDPStandardImplementation.h diff --git a/slsReceiverSoftware/src/slsReceiver.h b/slsReceiverSoftware/include/slsReceiver.h similarity index 100% rename from slsReceiverSoftware/src/slsReceiver.h rename to slsReceiverSoftware/include/slsReceiver.h diff --git a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.h b/slsReceiverSoftware/include/slsReceiverTCPIPInterface.h similarity index 100% rename from slsReceiverSoftware/src/slsReceiverTCPIPInterface.h rename to slsReceiverSoftware/include/slsReceiverTCPIPInterface.h diff --git a/slsReceiverSoftware/src/slsReceiverUDPFunctions.h b/slsReceiverSoftware/include/slsReceiverUDPFunctions.h similarity index 100% rename from slsReceiverSoftware/src/slsReceiverUDPFunctions.h rename to slsReceiverSoftware/include/slsReceiverUDPFunctions.h diff --git a/slsReceiverSoftware/src/slsReceiverUsers.h b/slsReceiverSoftware/include/slsReceiverUsers.h similarity index 100% rename from slsReceiverSoftware/src/slsReceiverUsers.h rename to slsReceiverSoftware/include/slsReceiverUsers.h diff --git a/slsReceiverSoftware/src/Makefile b/slsReceiverSoftware/src/Makefile deleted file mode 100644 index 88d8caf2e..000000000 --- a/slsReceiverSoftware/src/Makefile +++ /dev/null @@ -1,66 +0,0 @@ -include ../../Makefile.include - -DESTDIR ?= ../../bin -LIBDIR ?= $(DESTDIR) -PROGS = $(DESTDIR)/slsReceiver - - -CFLAGS += -DSLS_RECEIVER_UDP_FUNCTIONS -O3 -CPPFLAGS = ${CFLAGS} # for MAC - - -LDFLAGRXR ?= -L$(LIBDIR) -lSlsReceiver -L/usr/lib64/ -lpthread -LDFLAGRXR += -lm -lstdc++ - - -INCLUDES ?= -I ../MySocketTCP -I ../slsDetectorCalibration -I ../includes/ -I eigerReceiver -I . -SRC_CLNT = main.cpp - - -INSTMODE = 0777 -OBJS = $(SRC_CLNT:.cpp=.o) - - -.PHONY: all receiver clean static_receiver boot eigerReceiver lib - -all: receiver - -receiver: $(DESTDIR)/slsReceiver - -static_receiver: $(DESTDIR)/sslsReceiver - -boot: $(OBJS) - -$(DESTDIR)/sslsReceiver: lib - mkdir -p $(DESTDIR) - $(CXX) -static -o $@ $(SRC_CLNT) $(FLAGS) $(INCLUDES) $(CLAGS) $(LIBS) $(LDFLAGRXR) - - -$(DESTDIR)/slsReceiver: lib - $(CXX) -o $@ $(SRC_CLNT) $(FLAGS) $(INCLUDES) $(CLAGS) $(LIBS) $(LDFLAGRXR) -fPIC -#$(EIGERFLAGS) - - -#ifeq ($(EIGERSLS), yes) -#eigerReceiver: -# $(CXX) $(FLAGS) $(CFLAGS) -fPIC -c -o eigerReceiverTest.o eigerReceiver/eigerReceiverTest.cpp #$(EIGERFLAGS) -# $(CXX) $(FLAGS) $(CFLAGS) -fPIC -c -o eigerReceiver.o eigerReceiver/eigerReceiver.cpp $(EIGERFLAGS) -# $(CXX) eigerReceiverTest.o eigerReceiver.o -o eigerReceiver/eigerReceiverTest $(EIGERFLAGS) -# $(CXX) $(FLAGS) $(CFLAGS) $(INCLUDES) -fPIC -c -o eigerReceiver.o eigerReceiverImplementation.cpp $(EIGERFLAGS) -#else ifeq ($(ROOTSLS), yes) -#eigerReceiver: eigerReceiver/eigerReceiverDummy.cpp -# echo "Compiling with root" -# $(CXX) $(FLAGS) $(CFLAGS) -fPIC -c -o eigerReceiver.o eigerReceiver/eigerReceiverDummy.cpp $(ROOTFLAGS) -#else -#eigerReceiver: eigerReceiver/eigerReceiverDummy.cpp -# $(CXX) $(FLAGS) $(CFLAGS) $(INCLUDES) -fPIC -c -o eigerReceiver.o eigerReceiver/eigerReceiverDummy.cpp -#endif - -lib: - cd ../ && $(MAKE) DESTDIR=../bin LIBDIR=../bin - -clean: - rm -rf $(PROGS) *.o eigerReceiverTest $(DESTDIR)/libSlsReceiver.a $(DESTDIR)/libSlsReceiver.so core - - - diff --git a/slsReceiverSoftware/src/eigerReceiver/RestHelper.h b/slsReceiverSoftware/src/eigerReceiver/RestHelper.h deleted file mode 100644 index 6f423f5e1..000000000 --- a/slsReceiverSoftware/src/eigerReceiver/RestHelper.h +++ /dev/null @@ -1,195 +0,0 @@ -/** - * @file RestHelper.h - * @author Leonardo Sala - * @date Tue Mar 25 09:28:19 2014 - * - * @brief - * - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "JsonBox/Value.h" - -#include -#include -#include - -/// HTTP timeout in seconds, default is 8 -#define HTTP_TIMEOUT 10 -/// Number of connection tries -#define N_CONNECTION_TRIES 3 - -using namespace Poco::Net; -using namespace Poco; -using namespace std; - -class RestHelper { - public: - - ~RestHelper(){}; - - void init(string hostname, int port){ - /** Initialize the RestHelper. Hostname and port parameters are not supposed to change. - * - * - * @param hostname FQDN of the host to connect to , e.g. www.iamfake.org, or sodoi.org - * @param port - * - * @return - */ - - full_hostname = "http://"+hostname; - session = new HTTPClientSession(hostname,port ); - session->setKeepAliveTimeout( Timespan( HTTP_TIMEOUT,0) ); - }; - - - int get_json(string request, string* answer){ - /** Retrieves a reply from the RESTful webservice. - * - * - * @param request Request without the hostname, e.g. if the full request would have been http://fake.org/fakemethod, request=fakemethod - * @param answer - * - * @return 0 if successful, -1 if failure happens. - */ - URI * uri = new URI(full_hostname+"/"+request); - string path(uri->getPathAndQuery()); - if (path.empty()) path = "/"; - - // send request - HTTPRequest req(HTTPRequest::HTTP_GET, path, HTTPMessage::HTTP_1_1); - req.setContentType("application/json\r\n"); - int code = send_request(session, req, answer); - delete uri; - return code; - }; - - - int get_json(string request, JsonBox::Value* json_value){ - /** - * - * - * @param request - * @param json_value - * - * @return - */ - URI *uri = new URI(full_hostname+"/"+request); - string path(uri->getPathAndQuery()); - if (path.empty()) path = "/"; - // send request - HTTPRequest req(HTTPRequest::HTTP_GET, path, HTTPMessage::HTTP_1_1); - req.setContentType("application/json\r\n"); - string answer; - int code = send_request(session, req, &answer); - json_value->loadFromString(answer); - delete uri; - return code; - }; - - - int post_json(string request, string *answer, string request_body=""){ - /** - * - * - * @param request - * @param answer - * @param request_body Eventual arguments to the URL, e.g. action=login&name=mammamia - * - * @return - */ - //from: http://stackoverflow.com/questions/1499086/poco-c-net-ssl-how-to-post-https-request - URI *uri = new URI(full_hostname+"/"+request); - string path(uri->getPathAndQuery()); - if (path.empty()) path = "/"; - HTTPRequest req(HTTPRequest::HTTP_POST, path, HTTPMessage::HTTP_1_1 ); - req.setContentType("application/json\r\n"); - req.setContentLength( request.length() ); - int code = send_request(session, req, answer, request_body); - delete uri; - return code; - } - - - int post_json(string request, JsonBox::Value* json_value, string request_body=""){ - /** - * - * - * @param request - * @param json_value - * @param request_body Eventual arguments to the URL, e.g. action=login&name=mammamia - * - * @return - */ - - URI *uri = new URI(full_hostname+"/"+request); - string path(uri->getPathAndQuery()); - if (path.empty()) path = "/"; - HTTPRequest req(HTTPRequest::HTTP_POST, path, HTTPMessage::HTTP_1_1 ); - req.setContentType("application/json\r\n"); - req.setContentLength( request.length() ); - string answer; - int code = send_request(session, req, &answer, request_body); - json_value->loadFromString(answer); - delete uri; - return code; - } - - - private: - //URI * uri; - HTTPClientSession *session; - string full_hostname; - - int send_request(HTTPClientSession *session, HTTPRequest &req, string *answer, string request_body=""){ - /** - * - * - * @param session - * @param req - * @param answer - * @param request_body - * - * @return - */ - - int n=0; - int code = -1; - while(nsendRequest( (req) ); - else - session->sendRequest( (req) ) << request_body; - - HTTPResponse res; - istream &is = session->receiveResponse(res); - StreamCopier::copyToString(is, *answer); - code = res.getStatus(); - if (code != 200){ - cout << "HTTP ERROR " << res.getStatus() << ": " << res.getReason() << endl; - code = -1; - } - return code; - } - catch (exception& e){ - cout << "Exception connecting to "<< full_hostname << ": "<< e.what() << ", sleeping " << HTTP_TIMEOUT << " seconds\n"; - sleep(HTTP_TIMEOUT); - } - n+=1; - } - - return code; - } - -}; diff --git a/slsReceiverSoftware/src/eigerReceiver/eigerReceiver.cpp b/slsReceiverSoftware/src/eigerReceiver/eigerReceiver.cpp deleted file mode 100644 index fa19895be..000000000 --- a/slsReceiverSoftware/src/eigerReceiver/eigerReceiver.cpp +++ /dev/null @@ -1,254 +0,0 @@ -/* - * eigerReceiver.cpp - * - * Created on: Mar 11, 2014 - * Author: billich - */ - -#include -#include -#include "eigerReceiver.h" - - -/* uncomment next line to enable debug output */ -#define EIGER_DEBUG - -/* macro for debug output http://stackoverflow.com/a/14256296 */ -#ifdef EIGER_DEBUG -#define DEBUG(x) do { std::cerr << x << std::endl; } while (0) -#else -#define DEBUG(x) -#endif - - -using namespace std; - -struct EigerReceiverInitializationConfiguration { - - string detectorHostname; -}; - -struct EigerReceiverScanConfiguration { - - string fileName; - string filePath; - int dynamicRange; - int scanTag; - int numberOfFrames; - bool doFileWrite; - bool doFileOverWrite; - - EigerReceiverScanConfiguration(): - dynamicRange(-1), - scanTag(-1), - numberOfFrames(-1), - doFileWrite(false), - doFileOverWrite(false){}; -}; - -class EigerReceiverImplementation: public EigerReceiver { - -public: - - EigerReceiverImplementation() : isInitialized(false), status(slsReceiverDefs::ERROR) {}; - - void initialize(const char *detectorHostname) { - - string name; - if (detectorHostname != NULL) { - name = detectorHostname; - } - - if (name.empty()) { - DEBUG("initialize(): can't initialize with empty string or NULL for detectorHostname"); - } else if (isInitialized == true) { - DEBUG("initialize(): already initialized, can't initialize several times"); - } else { - DEBUG("initialize(): initialize() with: detectorHostName=" << name << "."); - init_config.detectorHostname = name; - isInitialized = true; - status = slsReceiverDefs::IDLE; - } - -#ifdef SALA - //REST call - hardcoded - RestHelper rest ; - rest.init("localhost",8080); - std::string answer; - std::cout << "---- REST test 1: true, string "<< std::endl; - int code = rest.get_json("status", &answer); - std::cout << "Answer: " << answer << std::endl; - - std::cout << "---- REST test 2: 404, string "<< std::endl; - code = rest.get_json("statuss", &answer); - if (code != 0){ - //throw -1; - std::cout << "I SHOULD THROW AN EXCEPTION!!!" << std::endl; - } - - std::cout << "---- REST test 3: true, json object "<< std::endl; - JsonBox::Value json_value; - code = rest.get_json("status", &json_value); - std::cout << "JSON " << json_value["status"] << std::endl; - - answer = ""; - std::cout << "---- REST test 4: POST, string "<< std::endl; - code = rest.post_json("recipes/cassoela", &answer); - std::cout << "POST answer: " << answer << std::endl; - if (code != 0){ - //throw -1; - std::cout << "I SHOULD THROW AN EXCEPTION!!!" << std::endl; - } - - RestHelper rest2 ; - rest2.init("reallyfake",8080); - std::cout << "---- REST test 4: host not found, json object "<< std::endl; - JsonBox::Value json_value2; - code = rest2.get_json("status", &json_value2); - if (code != 0){ - //throw -1; - std::cout << "I SHOULD THROW AN EXCEPTION!!!" << std::endl; - } - -#endif - } - - - char *getDetectorHostname() const { - string name = init_config.detectorHostname; - if (name.empty()) { - DEBUG("getDetectorHostname(): Return NULL"); - return(NULL); - } - char *c = new char[name.length()+1]; - name.copy(c, name.length()); - c[name.length()] = '\0'; - DEBUG("getDetectorHostname(): Return " << c << "."); - return(c); - } - - char *getFileName() const { - string name = scan_config.fileName; - - char *c = new char[name.length()+1]; - name.copy(c, name.length()); - c[name.length()] = '\0'; - DEBUG("getFileName(): Return " << c); - return(c); - } - - char *getFilePath() const { - string name = scan_config.filePath; - - char *c = new char[name.length()+1]; - name.copy(c, name.length()); - c[name.length()] = '\0'; - DEBUG("getFilePath(): Return " << c); - return(c); - } - - int getDynamicRange() const { - DEBUG("getDynamicRange(): Return " << scan_config.dynamicRange); - return(scan_config.dynamicRange); - } - - int getScanTag() const { - DEBUG("getScanTag(): returns " << scan_config.scanTag); - return(scan_config.scanTag); - } - - int getNumberOfFrames() const { - DEBUG("getNumberOfFrames(): return " << scan_config.numberOfFrames); - return(scan_config.numberOfFrames); - } - - int getEnableFileWrite() const { - DEBUG("getEnableFileWrite() returns " << scan_config.doFileWrite); - return(scan_config.doFileWrite); - } - - int getEnableOverwrite() const { - DEBUG("getEnableOverwrite() returns " << scan_config.doFileOverWrite); - return(scan_config.doFileOverWrite); - } - - slsReceiverDefs::runStatus getStatus() const { - DEBUG("getStatus(): return " <getFileName()); - } - - char *setFilePath(const char c[]) { - DEBUG("setFilePath() called with " << c << "."); - scan_config.filePath = c; - return(this->getFilePath()); - } - - int setDynamicRange (const int dr) { - DEBUG("setDynamicRange() called with " << dr << '.'); - scan_config.dynamicRange = dr; - return(getDynamicRange()); - } - - int setScanTag (const int tag) { - DEBUG("setScanTag() called with " << tag); - scan_config.scanTag = tag; - return(getScanTag()); - } - - int setNumberOfFrames (const int fnum) { - DEBUG("setNumberOfFrames() called with " << fnum); - scan_config.numberOfFrames = fnum; - return(getNumberOfFrames()); - } - - int setEnableFileWrite(const int i) { - DEBUG("enableFileWrite() called with " << i); - scan_config.doFileWrite = i; - return(getEnableFileWrite()); - } - - int setEnableOverwrite(const int i) { - DEBUG("setEnableOverwrite() called with " << i); - scan_config.doFileOverWrite = i; - return(getEnableOverwrite()); - } - - int startReceiver(char message[]) { - DEBUG("startReceiver(): return 0."); - status = slsReceiverDefs::RUNNING; - message = NULL; - return(0); - } - - int stopReceiver() { - DEBUG("stopReceiver(): return 0."); - status = slsReceiverDefs::IDLE; - return(0); - } - - void abort() { - DEBUG("abort(): return 0."); - status = slsReceiverDefs::IDLE; - } - -private: - EigerReceiverScanConfiguration scan_config; - EigerReceiverInitializationConfiguration init_config; - bool isInitialized; - slsReceiverDefs::runStatus status; -}; - -EigerReceiver *EigerReceiver::create(void) { - DEBUG("create(): Return new EigerReceiverImplementation instance."); - return new EigerReceiverImplementation(); -} - - - - diff --git a/slsReceiverSoftware/src/eigerReceiver/eigerReceiver.h b/slsReceiverSoftware/src/eigerReceiver/eigerReceiver.h deleted file mode 100644 index 9d26b185b..000000000 --- a/slsReceiverSoftware/src/eigerReceiver/eigerReceiver.h +++ /dev/null @@ -1,211 +0,0 @@ -#ifndef EIGERRECEIVER_H -#define EIGERRECEIVER_H -/*********************************************** - * @file eigerReceiver.h - * @short does all the functions for a receiver, set/get parameters, start/stop etc. - ***********************************************/ - -/** - * @short does all the functions for a receiver, set/get parameters, start/stop etc. - */ - -#include "sls_receiver_defs.h" -#ifdef SALA -#include "RestHelper.h" -#endif -class EigerReceiver { - /* abstract class that defines the public interface of an eiger data receiver. - * - * Use the factory method EigerReceiver::create() to get an instance: - * - * EigerReceiver *receiver = EigerReceiver::create() - * - * supported sequence of method-calls: - * - * initialize() : once and only once after create() - * - * get*() : anytime after initialize(), multiples times - * set*() : anytime after initialize(), multiple times - * - * startReceiver(): anytime after initialize(). Will fail if state already is 'running' - * - * abort(), - * stopReceiver() : anytime after initialize(). Will do nothing if state already is idle. - * - * getStatus() returns the actual state of the data receiver - running or idle. All other - * get*() and set*() methods access the local cache of configuration values only and *do not* modify the data receiver settings. - * - * Only startReceiver() does change the data receiver configuration, it does pass the whole configuration cache to the data receiver. - * - * get- and set-methods that return a char array (char *) allocate a new array at each call. The caller is responsible to free the allocated space: - * - * char *c = receiver->getFileName(); - * .... - * delete[] c; - * - * always: 1:YES 0:NO for int as bool-like arguments - * - */ - -public: - - /** - * factory method to create instances - */ - static EigerReceiver *create(); - - /** - * Destructor - */ - virtual ~EigerReceiver() {}; - - /** - * Initialize the Receiver - @param detectorHostName detector hostname - * you can call this function only once. You must call it before you call startReceiver() for the first time. - */ - virtual void initialize(const char *detectorHostName) = 0; - - - /* Returns detector hostname - /returns hostname - * caller needs to deallocate the returned char array. - * if uninitialized, it must return NULL - */ - virtual char *getDetectorHostname() const = 0; - - /** - * Returns status of receiver: idle, running or error - */ - virtual slsReceiverDefs::runStatus getStatus() const = 0; - - /** - * Returns File Name - * caller is responsible to deallocate the returned char array. - */ - virtual char *getFileName() const = 0; - - - /** - * Returns File Path - * caller is responsible to deallocate the returned char array - */ - virtual char *getFilePath() const = 0; //FIXME: Does the caller need to free() the returned pointer? - - - /** - * Returns the number of bits per pixel - */ - virtual int getDynamicRange() const = 0; - - /** - * Returns scan tag - */ - virtual int getScanTag() const = 0; - - /* - * Returns number of frames to receive - * This is the number of frames to expect to receiver from the detector. - * The data receiver will change from running to idle when it got this number of frames - */ - virtual int getNumberOfFrames() const = 0; - - /** - * Returns file write enable - * 1: YES 0: NO - */ - virtual int getEnableFileWrite() const = 0; - - /** - * Returns file over write enable - * 1: YES 0: NO - */ - virtual int getEnableOverwrite() const = 0; - - /** - * Set File Name (without frame index, file index and extension) - @param c file name - /returns file name - * returns NULL on failure (like bad file name) - * does not check the existence of the file - we don't know which path we'll finally use, so no point to check. - * caller is responsible to deallocate the returned char array. - */ - virtual char* setFileName(const char c[]) = 0; - - /** - * Set File Path - @param c file path - /returns file path - * checks the existence of the directory. returns NULL if directory does not exist or is not readable. - * caller is responsible to deallocate the returned char array. - */ - virtual char* setFilePath(const char c[]) = 0; - - /** - * Returns the number of bits per pixel - @param dr sets dynamic range - /returns dynamic range - * returns -1 on failure - * FIXME: what are the allowd values - should we use an enum as argument? - */ - virtual int setDynamicRange(const int dr) = 0; - - - /** - * Set scan tag - @param tag scan tag - /returns scan tag (always non-negative) - * FIXME: valid range - only positive? 16bit ore 32bit? - * returns -1 on failure - */ - virtual int setScanTag(const int tag) = 0; - - /** - * Sets number of frames - @param fnum number of frames - /returns number of frames - */ - virtual int setNumberOfFrames(const int fnum) = 0; - - /** - * Set enable file write - * @param i file write enable - /returns file write enable - */ - virtual int setEnableFileWrite(const int i) = 0; - - /** - * Set enable file overwrite - * @param i file overwrite enable - /returns file overwrite enable - */ - virtual int setEnableOverwrite(const int i) = 0; - - /** - * Starts Receiver - activate all configuration settings to the eiger receiver and start to listen for packets - @param message is the error message if there is an error - /returns 0 on success or -1 on failure - */ - //FIXME: success == 0 or success == 1? - virtual int startReceiver(char message[]) = 0; //FIXME: who allocates message[]? - - /** - * Stops Receiver - stops listening for packets - /returns success - * same as abort(). Always returns 0. - */ - virtual int stopReceiver() = 0; - - /** - * abort acquisition with minimum damage: close open files, cleanup. - * does nothing if state already is 'idle' - */ - virtual void abort() = 0; - -protected: - -private: - -}; - -#endif /* #ifndef EIGERRECEIVER_H */ diff --git a/slsReceiverSoftware/src/eigerReceiver/eigerReceiverDummy.cpp b/slsReceiverSoftware/src/eigerReceiver/eigerReceiverDummy.cpp deleted file mode 100644 index f45c7517e..000000000 --- a/slsReceiverSoftware/src/eigerReceiver/eigerReceiverDummy.cpp +++ /dev/null @@ -1,99 +0,0 @@ -/* - * eigerReceiver.cpp - * - * Created on: Mar 11, 2014 - * Author: billich - */ - -#include -#include -#include "eigerReceiver.h" - - -using namespace std; - -struct EigerReceiverInitializationConfiguration { - string detectorHostname; -}; - -struct EigerReceiverScanConfiguration { - - string fileName; - string filePath; - int dynamicRange; - int scanTag; - int numberOfFrames; - bool doFileWrite; - bool doFileOverWrite; - - EigerReceiverScanConfiguration(): - dynamicRange(-1), - scanTag(-1), - numberOfFrames(-1), - doFileWrite(false), - doFileOverWrite(false){}; -}; - -class EigerReceiverImplementation: public EigerReceiver { - -public: - - EigerReceiverImplementation(){}; - - ~EigerReceiverImplementation(){}; - - void initialize(const char *detectorHostname) {} - - char *getDetectorHostname() const { return (char*)"";} - - char *getFileName() const {return (char*)"";} - - char *getFilePath() const {return (char*)"";} - - int getDynamicRange() const { return 0;} - - int getScanTag() const {return 0;} - - int getNumberOfFrames() const {return 0;} - - int getEnableFileWrite() const {return 0;} - - int getEnableOverwrite() const {return 0;} - - slsReceiverDefs::runStatus getStatus() const { return slsReceiverDefs::IDLE;} - - char *setFileName(const char c[]) {return (char*)"";} - - char *setFilePath(const char c[]) {return (char*)"";} - - int setDynamicRange (const int dr) {return 0;} - - int setScanTag (const int tag) {return 0;} - - int setNumberOfFrames (const int fnum) {return 0;} - - int setEnableFileWrite(const int i) {return 0;} - - int setEnableOverwrite(const int i) {return 0;} - - int startReceiver(char message[]) {return 0;} - - int stopReceiver() {return 0;} - - void abort() {} - -private: - EigerReceiverScanConfiguration scan_config; - EigerReceiverInitializationConfiguration init_config; - bool isInitialized; - slsReceiverDefs::runStatus status; - -}; - -EigerReceiver *EigerReceiver::create(void) { - return new EigerReceiverImplementation(); -} - - - - diff --git a/slsReceiverSoftware/src/eigerReceiver/eigerReceiverTest.cpp b/slsReceiverSoftware/src/eigerReceiver/eigerReceiverTest.cpp deleted file mode 100644 index bdfcba7a1..000000000 --- a/slsReceiverSoftware/src/eigerReceiver/eigerReceiverTest.cpp +++ /dev/null @@ -1,97 +0,0 @@ -/* - * eigerReceiverTest.cpp - - * - * Created on: Mar 11, 2014 - * Author: billich - */ - -#include -#include -#include "eigerReceiver.h" - -using namespace std; - -int main(int argc, char *argv[]){ - - const char *name = "detectors_host_name"; - const char *empty = ""; - std::string prefix = "main: "; - cout <getStatus(); - char *c0 = receiver->getDetectorHostname(); - if (c0 == NULL) { - cout <initialize(empty); - status = receiver->getStatus(); - receiver->initialize(name); - status = receiver->getStatus(); - receiver->initialize(name); - status = receiver->getStatus(); - receiver->initialize((char *)NULL); - - cout << endl; - - status = receiver->getStatus(); - char *c6 = receiver->getDetectorHostname(); - cout <getFileName(); - cout <." << endl; - delete[] c1; - - char *c2 = receiver->getFilePath(); - cout <." << endl; - delete[]c2; - - int range = receiver->getDynamicRange(); - cout <getScanTag(); - cout <setFileName( "some_other_name"); - cout < after setting to " << endl << endl; - delete[] c3; - - char *c4 = receiver->setFilePath( "some_other_path"); - cout < after setting to " << endl << endl; - delete[] c4; - - range = receiver->setDynamicRange(8); - cout <setScanTag(99); - cout << "got scan tag " << tag << " after setting to 99." << endl << endl; - - int n = receiver->setNumberOfFrames(11); - cout << "got number of frames " << n << " after setting to 11." << endl << endl; - - int w = receiver->setEnableFileWrite(1); - cout << "got enable file write " << w << " after setting to 1." << endl << endl; - - char *c5; - status = receiver->getStatus(); - receiver->startReceiver(c5); - status = receiver->getStatus(); - receiver->stopReceiver(); - status = receiver->getStatus(); - receiver->abort(); - status = receiver->getStatus(); - -} - - - - diff --git a/slsReceiverSoftware/src/rec.cxx b/slsReceiverSoftware/test/rec.cxx similarity index 100% rename from slsReceiverSoftware/src/rec.cxx rename to slsReceiverSoftware/test/rec.cxx diff --git a/slsReceiverSoftware/src/send.cxx b/slsReceiverSoftware/test/send.cxx similarity index 100% rename from slsReceiverSoftware/src/send.cxx rename to slsReceiverSoftware/test/send.cxx From 3e0f618fbe85b8cd855714ed594a28f5b6cf10b7 Mon Sep 17 00:00:00 2001 From: Sala Leonardo Date: Wed, 10 Sep 2014 10:09:29 +0200 Subject: [PATCH 032/474] cleaning --- slsReceiverSoftware/slsReceiver/Makefile | 68 ----- .../eigerReceiver/eigerReceiver.cpp | 259 ------------------ .../eigerReceiver/eigerReceiverDummy.cpp | 101 ------- .../eigerReceiver/eigerReceiverTest.cpp | 97 ------- 4 files changed, 525 deletions(-) delete mode 100644 slsReceiverSoftware/slsReceiver/Makefile delete mode 100644 slsReceiverSoftware/slsReceiver/eigerReceiver/eigerReceiver.cpp delete mode 100644 slsReceiverSoftware/slsReceiver/eigerReceiver/eigerReceiverDummy.cpp delete mode 100644 slsReceiverSoftware/slsReceiver/eigerReceiver/eigerReceiverTest.cpp diff --git a/slsReceiverSoftware/slsReceiver/Makefile b/slsReceiverSoftware/slsReceiver/Makefile deleted file mode 100644 index c94528eeb..000000000 --- a/slsReceiverSoftware/slsReceiver/Makefile +++ /dev/null @@ -1,68 +0,0 @@ -include ../../Makefile.include - -DESTDIR ?= ../../bin -LIBDIR ?= $(DESTDIR) -PROGS = $(DESTDIR)/slsReceiver - - -CFLAGS += -DSLS_RECEIVER_UDP_FUNCTIONS -O3 -CPPFLAGS = ${CFLAGS} # for MAC - - -LDFLAGRXR ?= -L$(LIBDIR) -lSlsReceiver -L/usr/lib64/ -lpthread -LDFLAGRXR += -lm -lstdc++ - - -INCLUDES ?= -I ../MySocketTCP -I ../slsDetectorCalibration -I ../includes -I eigerReceiver -I . -I ../slsDetectorSoftware/commonFiles -SRC_CLNT = main.cpp - - -INSTMODE = 0777 -OBJS = $(SRC_CLNT:.cpp=.o) - - -.PHONY: all receiver clean static_receiver boot eigerReceiver lib - -all: receiver - -receiver: $(DESTDIR)/slsReceiver - -static_receiver: $(DESTDIR)/sslsReceiver - -boot: $(OBJS) - -$(DESTDIR)/sslsReceiver: lib - echo $(OBJS) - echo $(LDFLAGRXR) - echo $(LIBS) - mkdir -p $(DESTDIR) - $(CXX) -static -o $@ $(SRC_CLNT) $(FLAGS) $(INCLUDES) $(CLAGS) $(LIBS) $(LDFLAGRXR) - - -$(DESTDIR)/slsReceiver: eigerReceiver lib - $(CXX) -o $@ $(SRC_CLNT) $(FLAGS) $(INCLUDES) $(CLAGS) $(LIBS) $(LDFLAGRXR) -fPIC -#$(EIGERFLAGS) - - -ifeq ($(EIGERSLS), yes) -eigerReceiver: - $(CXX) $(FLAGS) $(CFLAGS) $(INCLUDES) -fPIC -c -o eigerReceiverTest.o eigerReceiver/eigerReceiverTest.cpp $(EIGERFLAGS) - $(CXX) $(FLAGS) $(CFLAGS) $(INCLUDES) -fPIC -c -o eigerReceiver.o eigerReceiver/eigerReceiver.cpp $(EIGERFLAGS) - $(CXX) eigerReceiverTest.o eigerReceiver.o -o eigerReceiver/eigerReceiverTest $(EIGERFLAGS) -else ifeq ($(ROOTSLS), yes) -eigerReceiver: eigerReceiver/eigerReceiverDummy.cpp - echo "Compiling with root" - $(CXX) $(FLAGS) $(CFLAGS) $(INCLUDES) -fPIC -c -o eigerReceiver.o eigerReceiver/eigerReceiverDummy.cpp $(ROOTFLAGS) -else -eigerReceiver: eigerReceiver/eigerReceiverDummy.cpp - $(CXX) $(FLAGS) $(CFLAGS) $(INCLUDES) -fPIC -c -o eigerReceiver.o eigerReceiver/eigerReceiverDummy.cpp -endif - -lib: - cd ../ && $(MAKE) DESTDIR=../bin LIBDIR=../bin - -clean: - rm -rf $(PROGS) *.o eigerReceiverTest $(DESTDIR)/libSlsReceiver.a $(DESTDIR)/libSlsReceiver.so core - - - diff --git a/slsReceiverSoftware/slsReceiver/eigerReceiver/eigerReceiver.cpp b/slsReceiverSoftware/slsReceiver/eigerReceiver/eigerReceiver.cpp deleted file mode 100644 index 48024c5d0..000000000 --- a/slsReceiverSoftware/slsReceiver/eigerReceiver/eigerReceiver.cpp +++ /dev/null @@ -1,259 +0,0 @@ -/* - * eigerReceiver.cpp - * - * Created on: Mar 11, 2014 - * Author: billich - */ - -#include -#include -#include "eigerReceiver.h" - - -/* uncomment next line to enable debug output */ -#define EIGER_DEBUG - -/* macro for debug output http://stackoverflow.com/a/14256296 */ -#ifdef EIGER_DEBUG -#define DEBUG(x) do { std::cerr << x << std::endl; } while (0) -#else -#define DEBUG(x) -#endif - - -using namespace std; - -struct EigerReceiverInitializationConfiguration { - - string detectorHostname; -}; - -struct EigerReceiverScanConfiguration { - - string fileName; - string filePath; - int dynamicRange; - int scanTag; - int numberOfFrames; - bool doFileWrite; - bool doFileOverWrite; - - EigerReceiverScanConfiguration(): - dynamicRange(-1), - scanTag(-1), - numberOfFrames(-1), - doFileWrite(false), - doFileOverWrite(false){}; -}; - -class EigerReceiverImplementation: public EigerReceiver { - -public: - - EigerReceiverImplementation() : isInitialized(false), status(slsReceiverDefs::ERROR) {}; - - void initialize(const char *detectorHostname) { - - string name; - if (detectorHostname != NULL) { - name = detectorHostname; - } - - if (name.empty()) { - DEBUG("initialize(): can't initialize with empty string or NULL for detectorHostname"); - } else if (isInitialized == true) { - DEBUG("initialize(): already initialized, can't initialize several times"); - } else { - DEBUG("initialize(): initialize() with: detectorHostName=" << name << "."); - init_config.detectorHostname = name; - isInitialized = true; - status = slsReceiverDefs::IDLE; - } - -#ifdef SALA - //REST call - hardcoded - RestHelper rest ; - rest.init("localhost",8080); - std::string answer; - std::cout << "---- REST test 1: true, string "<< std::endl; - int code = rest.get_json("status", &answer); - std::cout << "Answer: " << answer << std::d::endl; - - std::cout << "---- REST test 2: 404, string "<< std::endl; - code = rest.get_json("statuss", &answer); - if (code != 0){ - //throw -1; - std::cout << "I SHOULD THROW AN EXCEPTION!!!" << std::endl; - } - - std::cout << "---- REST test 3: true, json object "<< std::endl; - JsonBox::Value json_value; - code = rest.get_json("status", &json_value); - std::cout << "JSON " << json_value["status"] << std::endl; - - answer = ""; - std::cout << "---- REST test 4: POST, string "<< std::endl; - code = rest.post_json("recipes/cassoela", &answer); - std::cout << "POST answer: " << answer << std::endl; - if (code != 0){ - //throw -1; - std::cout << "I SHOULD THROW AN EXCEPTION!!!" << std::endl; - } - - RestHelper rest2 ; - rest2.init("reallyfake",8080); - std::cout << "---- REST test 4: host not found, json object "<< std::endl; - JsonBox::Value json_value2; - code = rest2.get_json("status", &json_value2); - if (code != 0){ - //throw -1; - std::cout << "I SHOULD THROW AN EXCEPTION!!!" << std::endl; - } - -#endif - } - - - char *getDetectorHostname() const { - string name = init_config.detectorHostname; - if (name.empty()) { - DEBUG("getDetectorHostname(): Return NULL"); - return(NULL); - } - char *c = new char[name.length()+1]; - name.copy(c, name.length()); - c[name.length()] = '\0'; - DEBUG("getDetectorHostname(): Return " << c << "."); - return(c); - } - - char *getFileName() const { - string name = scan_config.fileName; - - char *c = new char[name.length()+1]; - name.copy(c, name.length()); - c[name.length()] = '\0'; - DEBUG("getFileName(): Return " << c); - return(c); - } - - char *getFilePath() const { - string name = scan_config.filePath; - - char *c = new char[name.length()+1]; - name.copy(c, name.length()); - c[name.length()] = '\0'; - DEBUG("getFilePath(): Return " << c); - return(c); - } - - int getDynamicRange() const { - DEBUG("getDynamicRange(): Return " << scan_config.dynamicRange); - return(scan_config.dynamicRange); - } - - int getScanTag() const { - DEBUG("getScanTag(): returns " << scan_config.scanTag); - return(scan_config.scanTag); - } - - int getNumberOfFrames() const { - DEBUG("getNumberOfFrames(): return " << scan_config.numberOfFrames); - return(scan_config.numberOfFrames); - } - - int getEnableFileWrite() const { - DEBUG("getEnableFileWrite() returns " << scan_config.doFileWrite); - return(scan_config.doFileWrite); - } - - int getEnableOverwrite() const { - DEBUG("getEnableOverwrite() returns " << scan_config.doFileOverWrite); - return(scan_config.doFileOverWrite); - } - - slsReceiverDefs::runStatus getStatus() const { - DEBUG("getStatus(): return " <getFileName()); - } - - char *setFilePath(const char c[]) { - DEBUG("setFilePath() called with " << c << "."); - scan_config.filePath = c; - return(this->getFilePath()); - } - - int setDynamicRange (const int dr) { - DEBUG("setDynamicRange() called with " << dr << '.'); - scan_config.dynamicRange = dr; - return(getDynamicRange()); - } - - int setScanTag (const int tag) { - DEBUG("setScanTag() called with " << tag); - scan_config.scanTag = tag; - return(getScanTag()); - } - - int setNumberOfFrames (const int fnum) { - DEBUG("setNumberOfFrames() called with " << fnum); - scan_config.numberOfFrames = fnum; - return(getNumberOfFrames()); - } - - int setEnableFileWrite(const int i) { - DEBUG("enableFileWrite() called with " << i); - scan_config.doFileWrite = i; - return(getEnableFileWrite()); - } - - int setEnableOverwrite(const int i) { - DEBUG("setEnableOverwrite() called with " << i); - scan_config.doFileOverWrite = i; - return(getEnableOverwrite()); - } - - int startReceiver(char message[]) { - DEBUG("startReceiver(): return 0."); - status = slsReceiverDefs::RUNNING; - message = NULL; - return(0); - } - - int stopReceiver() { - DEBUG("stopReceiver(): return 0."); - status = slsReceiverDefs::IDLE; - return(0); - } - - void abort() { - DEBUG("abort(): return 0."); - status = slsReceiverDefs::IDLE; - } - - // Temporary workaround - int setDetectorType(slsReceiverDefs::detectorType det){ - return 0; - } - -private: - EigerReceiverScanConfiguration scan_config; - EigerReceiverInitializationConfiguration init_config; - bool isInitialized; - slsReceiverDefs::runStatus status; -}; - -EigerReceiver *EigerReceiver::create(void) { - DEBUG("create(): Return new EigerReceiverImplementation instance."); - return new EigerReceiverImplementation(); -} - - - - diff --git a/slsReceiverSoftware/slsReceiver/eigerReceiver/eigerReceiverDummy.cpp b/slsReceiverSoftware/slsReceiver/eigerReceiver/eigerReceiverDummy.cpp deleted file mode 100644 index ad8139cd8..000000000 --- a/slsReceiverSoftware/slsReceiver/eigerReceiver/eigerReceiverDummy.cpp +++ /dev/null @@ -1,101 +0,0 @@ -/* - * eigerReceiver.cpp - * - * Created on: Mar 11, 2014 - * Author: billich - */ - -#include -#include -#include "eigerReceiver.h" - - -using namespace std; - -struct EigerReceiverInitializationConfiguration { - string detectorHostname; -}; - -struct EigerReceiverScanConfiguration { - - string fileName; - string filePath; - int dynamicRange; - int scanTag; - int numberOfFrames; - bool doFileWrite; - bool doFileOverWrite; - - EigerReceiverScanConfiguration(): - dynamicRange(-1), - scanTag(-1), - numberOfFrames(-1), - doFileWrite(false), - doFileOverWrite(false){}; -}; - -class EigerReceiverImplementation: public EigerReceiver { - -public: - - EigerReceiverImplementation(){}; - - ~EigerReceiverImplementation(){}; - - void initialize(const char *detectorHostname) {} - - char *getDetectorHostname() const { return (char*)"";} - - char *getFileName() const {return (char*)"";} - - char *getFilePath() const {return (char*)"";} - - int getFileIndex() const {return 0;} - - int getDynamicRange() const { return 0;} - - int getScanTag() const {return 0;} - - int getNumberOfFrames() const {return 0;} - - int getEnableFileWrite() const {return 0;} - - int getEnableOverwrite() const {return 0;} - - slsReceiverDefs::runStatus getStatus() const { return slsReceiverDefs::IDLE;} - - char *setFileName(const char c[]) {return (char*)"";} - - char *setFilePath(const char c[]) {return (char*)"";} - - int setDynamicRange (const int dr) {return 0;} - - int setScanTag (const int tag) {return 0;} - - int setNumberOfFrames (const int fnum) {return 0;} - - int setEnableFileWrite(const int i) {return 0;} - - int setEnableOverwrite(const int i) {return 0;} - - int startReceiver(char message[]) {return 0;} - - int stopReceiver() {return 0;} - - void abort() {} - -private: - EigerReceiverScanConfiguration scan_config; - EigerReceiverInitializationConfiguration init_config; - bool isInitialized; - slsReceiverDefs::runStatus status; - -}; - -EigerReceiver *EigerReceiver::create(void) { - return new EigerReceiverImplementation(); -} - - - - diff --git a/slsReceiverSoftware/slsReceiver/eigerReceiver/eigerReceiverTest.cpp b/slsReceiverSoftware/slsReceiver/eigerReceiver/eigerReceiverTest.cpp deleted file mode 100644 index 7eb80f690..000000000 --- a/slsReceiverSoftware/slsReceiver/eigerReceiver/eigerReceiverTest.cpp +++ /dev/null @@ -1,97 +0,0 @@ -/* - * eigerReceiverTest.cpp - - * - * Created on: Mar 11, 2014 - * Author: billich - */ - -#include -#include -#include "eigerReceiver.h" - -using namespace std; - -int main(int argc, char *argv[]){ - - const char *name = "detectors_host_name"; - const char *empty = ""; - std::string prefix = "main: "; - cout <getStatus(); - char *c0 = receiver->getDetectorHostname(); - if (c0 == NULL) { - cout <initialize(empty); - status = receiver->getStatus(); - receiver->initialize(name); - status = receiver->getStatus(); - receiver->initialize(name); - status = receiver->getStatus(); - receiver->initialize((char *)NULL); - - cout << endl; - - status = receiver->getStatus(); - char *c6 = receiver->getDetectorHostname(); - cout <getFileName(); - cout <." << endl; - delete[] c1; - - char *c2 = receiver->getFilePath(); - cout <." << endl; - delete[]c2; - - int range = receiver->getDynamicRange(); - cout <getScanTag(); - cout <setFileName( "some_other_name"); - cout < after setting to " << endl << endl; - delete[] c3; - - char *c4 = receiver->setFilePath( "some_other_path"); - cout < after setting to " << endl << endl; - delete[] c4; - - range = receiver->setDynamicRange(8); - cout <setScanTag(99); - cout << "got scan tag " << tag << " after setting to 99." << endl << endl; - - int n = receiver->setNumberOfFrames(11); - cout << "got number of frames " << n << " after setting to 11." << endl << endl; - - int w = receiver->setEnableFileWrite(1); - cout << "got enable file write " << w << " after setting to 1." << endl << endl; - - char *c5; - status = receiver->getStatus(); - receiver->startReceiver(c5); - status = receiver->getStatus(); - receiver->stopReceiver(); - status = receiver->getStatus(); - receiver->abort(); - status = receiver->getStatus(); - -} - - - - From 50d049539e324634977a3665afa95576cd323b1b Mon Sep 17 00:00:00 2001 From: Sala Leonardo Date: Wed, 10 Sep 2014 10:17:36 +0200 Subject: [PATCH 033/474] minor --- slsReceiverSoftware/include/UDPInterface.h | 31 +++++++++------------- 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/slsReceiverSoftware/include/UDPInterface.h b/slsReceiverSoftware/include/UDPInterface.h index 590ee67d8..aee09d7ff 100644 --- a/slsReceiverSoftware/include/UDPInterface.h +++ b/slsReceiverSoftware/include/UDPInterface.h @@ -3,14 +3,14 @@ /*********************************************** * @file UDPInterface.h - * @short base class with all the functions for a receiver, set/get parameters, start/stop etc. + * @short Base class with all the functions for the UDP inteface of the receiver ***********************************************/ /** - * \mainpage Base class with all the functions for a receiver, set/get parameters, start/stop etc. + * \mainpage Base class with all the functions for the UDP inteface of the receiver */ /** - * @short base class with all the functions for a receiver, set/get parameters, start/stop etc. + * @short Base class with all the functions for the UDP inteface of the receiver */ @@ -21,19 +21,14 @@ #include "utilities.h" #include "logger.h" -/* -void print_not_implemented(string method_name){ - std::cout << "[WARNING] Method " << method_name << " not implemented!" << std::endl; -} -*/ class UDPInterface { - /* abstract class that defines the public interface of an sls detector data receiver. + /* abstract class that defines the UDP interface of an sls detector data receiver. * - * Use the factory method slsReceiverBase::create() to get an instance: + * Use the factory method UDPInterface::create() to get an instance: * - * slsReceiverBase *receiver = slsReceiverBase::create() + * UDPInterface *udp_interface = UDPInterface::create() * * supported sequence of method-calls: * @@ -80,9 +75,9 @@ class UDPInterface { static UDPInterface *create(string receiver_type = "standard"); -public: + public: + - /** * Initialize the Receiver @@ -383,11 +378,11 @@ public: guidatapointer (NULL, no data required) */ virtual void registerCallBackRawDataReady(void (*func)(int, char*, int, FILE*, char*, void*),void *arg) = 0; - -protected: - -private: + + protected: + + private: }; -#endif /* #ifndef SLSRECEIVERBASE_H */ +#endif /* #ifndef UDPINTERFACE_H */ From eb1f9db9afcf0f25f0fe00f30e1cfa60bc53cd17 Mon Sep 17 00:00:00 2001 From: Leonardo Sala Date: Fri, 12 Sep 2014 13:24:08 +0200 Subject: [PATCH 034/474] added build dir --- slsReceiverSoftware/.gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/slsReceiverSoftware/.gitignore b/slsReceiverSoftware/.gitignore index 038cff97e..31dd1b8d2 100644 --- a/slsReceiverSoftware/.gitignore +++ b/slsReceiverSoftware/.gitignore @@ -1,6 +1,6 @@ *~ *.o -build +build/* GPATH GRTAGS GSYMS From e0ee1fb386a3c4e8d4d6de8306d183fec4591657 Mon Sep 17 00:00:00 2001 From: Leonardo Sala Date: Fri, 12 Sep 2014 16:09:43 +0200 Subject: [PATCH 035/474] fixed bug in config reading; added printout in MAkefile --- slsReceiverSoftware/Makefile | 7 +++++++ slsReceiverSoftware/src/slsReceiver.cpp | 24 +++++++++++++----------- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/slsReceiverSoftware/Makefile b/slsReceiverSoftware/Makefile index 7bbc89d5b..981b44f1f 100644 --- a/slsReceiverSoftware/Makefile +++ b/slsReceiverSoftware/Makefile @@ -23,6 +23,13 @@ MAIN_SRC = main.cpp OBJS=$(SRC_CLNT:%.cpp=$(BUILDDIR)/%.o) +$(info ) +$(info #######################################) +$(info # Compiling slsReceiverSoftware #) +$(info #######################################) +$(info ) + + .PHONY: all intdoc package eigerReceiver clean all: lib receiver diff --git a/slsReceiverSoftware/src/slsReceiver.cpp b/slsReceiverSoftware/src/slsReceiver.cpp index a59e773de..f051592ce 100644 --- a/slsReceiverSoftware/src/slsReceiver.cpp +++ b/slsReceiverSoftware/src/slsReceiver.cpp @@ -30,7 +30,7 @@ slsReceiver::slsReceiver(int argc, char *argv[], int &success){ */ //creating base receiver - int tcpip_port_no = 1984; + int tcpip_port_no = 1954; success=OK; string fname = ""; string udp_interface_type = "standard"; @@ -85,17 +85,19 @@ slsReceiver::slsReceiver(int argc, char *argv[], int &success){ } // if required fname parameter not available, fail - if (fname == "") - success = FAIL; + //if (fname == "") + // success = FAIL; - if((!fname.empty()) && (success == OK)){ - FILE_LOG(logINFO) << "config file name " << fname; - success = read_config_file(fname, &tcpip_port_no); - //VERBOSE_PRINT("Read configuration file of " + iline + " lines"); - } - else { - FILE_LOG(logERROR) << "Error opening configuration file " << fname ; + if( !fname.empty() ){ + try{ + FILE_LOG(logINFO) << "config file name " << fname; + success = read_config_file(fname, &tcpip_port_no); + //VERBOSE_PRINT("Read configuration file of " + iline + " lines"); + } + catch(...){ + FILE_LOG(logERROR) << "Error opening configuration file " << fname ; success = FAIL; + } } @@ -104,7 +106,7 @@ slsReceiver::slsReceiver(int argc, char *argv[], int &success){ } if (success==OK){ - cout << "SLS Receiver starting " << udp_interface_type << endl; + FILE_LOG(logINFO) << "SLS Receiver starting " << udp_interface_type << " on port " << tcpip_port_no << endl; udp_interface = UDPInterface::create(udp_interface_type); tcpipInterface = new slsReceiverTCPIPInterface(success, udp_interface, tcpip_port_no); //tcp ip interface From 7986746194d4fa88482d51b2b9afca50a7d6a630 Mon Sep 17 00:00:00 2001 From: Leonardo Sala Date: Mon, 15 Sep 2014 16:33:57 +0200 Subject: [PATCH 036/474] from private to protected --- slsReceiverSoftware/Makefile | 4 +- .../include/UDPBaseImplementation.h | 9 +- .../include/UDPStandardImplementation.h | 304 +----------------- .../src/UDPBaseImplementation.cpp | 33 +- .../src/UDPStandardImplementation.cpp | 26 +- 5 files changed, 49 insertions(+), 327 deletions(-) diff --git a/slsReceiverSoftware/Makefile b/slsReceiverSoftware/Makefile index 981b44f1f..4bc760e82 100644 --- a/slsReceiverSoftware/Makefile +++ b/slsReceiverSoftware/Makefile @@ -32,7 +32,7 @@ $(info ) .PHONY: all intdoc package eigerReceiver clean -all: lib receiver +all: builddir lib receiver intdoc: $(SRC_H) $(SRC_CLNT) doxygen doxy.config @@ -76,6 +76,8 @@ clean: buildclean rm $(DESTDIR)/libSlsReceiver.a $(DESTDIR)/libSlsReceiver.so rm $(PROGS) +builddir: + if [ ! -d $(BUILDDIR) ]; then mkdir $(BUILDDIR); fi buildclean: rm -rf $(OBJS) diff --git a/slsReceiverSoftware/include/UDPBaseImplementation.h b/slsReceiverSoftware/include/UDPBaseImplementation.h index 7b9068a63..5528e34f0 100644 --- a/slsReceiverSoftware/include/UDPBaseImplementation.h +++ b/slsReceiverSoftware/include/UDPBaseImplementation.h @@ -319,7 +319,7 @@ class UDPBaseImplementation : private virtual slsReceiverDefs, public UDPInterfa */ int shutDownUDPSockets(); -private: +protected: /* void not_implemented(string method_name){ @@ -466,6 +466,10 @@ private: void handleDataCompression(int ithread, char* wbuffer[], int &npackets, char* data, int xmax, int ymax, int &nf); + + //// Could be done more fine-grained... TODO + // private: + protected: /** structure of an eiger image header*/ typedef struct { @@ -683,6 +687,9 @@ private: /** 10Gbe enable*/ int tengigaEnable; + // TODO: not properly sure where to put these... + /** structure of an eiger image header*/ + diff --git a/slsReceiverSoftware/include/UDPStandardImplementation.h b/slsReceiverSoftware/include/UDPStandardImplementation.h index e161c8d81..b6c25a144 100644 --- a/slsReceiverSoftware/include/UDPStandardImplementation.h +++ b/slsReceiverSoftware/include/UDPStandardImplementation.h @@ -40,7 +40,7 @@ class UDPStandardImplementation: private virtual slsReceiverDefs, public UDPBase /** * Constructor */ -UDPStandardImplementation(); + UDPStandardImplementation(); /** * Destructor @@ -466,308 +466,6 @@ private: void handleDataCompression(int ithread, char* wbuffer[], int &npackets, char* data, int xmax, int ymax, int &nf); - /** structure of an eiger image header*/ - typedef struct - { - unsigned char header_before[20]; - unsigned char fnum[4]; - unsigned char header_after[24]; - } eiger_image_header; - - - /** structure of an eiger image header*/ - typedef struct - { - unsigned char num1[4]; - unsigned char num2[4]; - } eiger_packet_header; - - /** max number of listening threads */ - const static int MAX_NUM_LISTENING_THREADS = EIGER_MAX_PORTS; - - /** max number of writer threads */ - const static int MAX_NUM_WRITER_THREADS = 15; - - /** detector type */ - detectorType myDetectorType; - - /** detector hostname */ - char detHostname[MAX_STR_LENGTH]; - - /** status of receiver */ - runStatus status; - - /** UDP Socket between Receiver and Detector */ - genericSocket* udpSocket[MAX_NUM_LISTENING_THREADS]; - - /** Server UDP Port*/ - int server_port[MAX_NUM_LISTENING_THREADS]; - - /** ethernet interface or IP to listen to */ - char *eth; - - /** max packets per file **/ - int maxPacketsPerFile; - - /** File write enable */ - int enableFileWrite; - - /** File over write enable */ - int overwrite; - - /** Complete File name */ - char savefilename[MAX_STR_LENGTH]; - - /** File Name without frame index, file index and extension*/ - char fileName[MAX_STR_LENGTH]; - - /** File Path */ - char filePath[MAX_STR_LENGTH]; - - /** File Index */ - int fileIndex; - - /** scan tag */ - int scanTag; - - /** if frame index required in file name */ - int frameIndexNeeded; - - /* Acquisition started */ - bool acqStarted; - - /* Measurement started */ - bool measurementStarted; - - /** Frame index at start of each real time acquisition (eg. for each scan) */ - uint32_t startFrameIndex; - - /** Actual current frame index of each time acquisition (eg. for each scan) */ - uint32_t frameIndex; - - /** Frames Caught for each real time acquisition (eg. for each scan) */ - int packetsCaught; - - /** Total packets caught for an entire acquisition (including all scans) */ - int totalPacketsCaught; - - /** Pckets currently in current file, starts new file when it reaches max */ - int packetsInFile; - - /** Frame index at start of an entire acquisition (including all scans) */ - uint32_t startAcquisitionIndex; - - /** Actual current frame index of an entire acquisition (including all scans) */ - uint32_t acquisitionIndex; - - /** number of packets per frame*/ - int packetsPerFrame; - - /** frame index mask */ - uint32_t frameIndexMask; - - /** packet index mask */ - uint32_t packetIndexMask; - - /** frame index offset */ - int frameIndexOffset; - - /** acquisition period */ - int64_t acquisitionPeriod; - - /** frame number */ - int32_t numberOfFrames; - - /** dynamic range */ - int dynamicRange; - - /** short frames */ - int shortFrame; - - /** current frame number */ - uint32_t currframenum; - - /** Previous Frame number from buffer */ - uint32_t prevframenum; - - /** size of one frame */ - int frameSize; - - /** buffer size. different from framesize as we wait for one packet instead of frame for eiger */ - int bufferSize; - - /** oen buffer size */ - int onePacketSize; - - /** latest data */ - char* latestData; - - /** gui data ready */ - int guiDataReady; - - /** points to the data to send to gui */ - char* guiData; - - /** points to the filename to send to gui */ - char* guiFileName; - - /** temporary number for eiger frame number as its not included in the packet */ - uint32_t guiFrameNumber; - - /** send every nth frame to gui or only upon gui request*/ - int nFrameToGui; - - /** fifo size */ - unsigned int fifosize; - - /** number of jobs per thread for data compression */ - int numJobsPerThread; - - /** datacompression - save only hits */ - bool dataCompression; - - /** memory allocated for the buffer */ - char *mem0[MAX_NUM_LISTENING_THREADS]; - - /** circular fifo to store addresses of data read */ - CircularFifo* fifo[MAX_NUM_LISTENING_THREADS]; - - /** circular fifo to store addresses of data already written and ready to be resued*/ - CircularFifo* fifoFree[MAX_NUM_LISTENING_THREADS]; - - /** Receiver buffer */ - char *buffer[MAX_NUM_LISTENING_THREADS]; - - /** number of writer threads */ - int numListeningThreads; - - /** number of writer threads */ - int numWriterThreads; - - /** to know if listening and writer threads created properly */ - int thread_started; - - /** current listening thread index*/ - int currentListeningThreadIndex; - - /** current writer thread index*/ - int currentWriterThreadIndex; - - /** thread listening to packets */ - pthread_t listening_thread[MAX_NUM_LISTENING_THREADS]; - - /** thread writing packets */ - pthread_t writing_thread[MAX_NUM_WRITER_THREADS]; - - /** total frame count the listening thread has listened to */ - int totalListeningFrameCount[MAX_NUM_LISTENING_THREADS]; - - /** mask showing which listening threads are running */ - volatile uint32_t listeningthreads_mask; - - /** mask showing which writer threads are running */ - volatile uint32_t writerthreads_mask; - - /** mask showing which threads have created files*/ - volatile uint32_t createfile_mask; - - /** OK if file created was successful */ - int ret_createfile; - - /** variable used to self terminate threads waiting for semaphores */ - int killAllListeningThreads; - - /** variable used to self terminate threads waiting for semaphores */ - int killAllWritingThreads; - - /** 10Gbe enable*/ - int tengigaEnable; - - - - -//semaphores - /** semaphore to synchronize writer and guireader threads */ - sem_t smp; - /** semaphore to synchronize listener threads */ - sem_t listensmp[MAX_NUM_LISTENING_THREADS]; - /** semaphore to synchronize writer threads */ - sem_t writersmp[MAX_NUM_WRITER_THREADS]; - - -//mutex - /** guiDataReady mutex */ - pthread_mutex_t dataReadyMutex; - - /** mutex for status */ - pthread_mutex_t status_mutex; - - /** mutex for progress variable currframenum */ - pthread_mutex_t progress_mutex; - - /** mutex for writing data to file */ - pthread_mutex_t write_mutex; - - /** File Descriptor */ - FILE *sfilefd; - - //filter - singlePhotonDetector *singlePhotonDet[MAX_NUM_WRITER_THREADS]; - slsReceiverData *receiverdata[MAX_NUM_WRITER_THREADS]; - moenchCommonMode *cmSub; - bool commonModeSubtractionEnable; - -#ifdef MYROOT1 - /** Tree where the hits are stored */ - TTree *myTree[MAX_NUM_WRITER_THREADS]; - - /** File where the tree is saved */ - TFile *myFile[MAX_NUM_WRITER_THREADS]; -#endif - - - - /** - callback arguments are - filepath - filename - fileindex - data size - - return value is - 0 callback takes care of open,close,write file - 1 callback writes file, we have to open, close it - 2 we open, close, write file, callback does not do anything - - */ - int (*startAcquisitionCallBack)(char*, char*,int, int, void*); - void *pStartAcquisition; - - /** - args to acquisition finished callback - total frames caught - - */ - void (*acquisitionFinishedCallBack)(int, void*); - void *pAcquisitionFinished; - - - /** - args to raw data ready callback are - framenum - datapointer - datasize in bytes - file descriptor - guidatapointer (NULL, no data required) - */ - void (*rawDataReadyCallBack)(int, char*, int, FILE*, char*, void*); - void *pRawDataReady; - - /** The action which decides what the user and default responsibilites to save data are - * 0 raw data ready callback takes care of open,close,write file - * 1 callback writes file, we have to open, close it - * 2 we open, close, write file, callback does not do anything */ - int cbAction; public: diff --git a/slsReceiverSoftware/src/UDPBaseImplementation.cpp b/slsReceiverSoftware/src/UDPBaseImplementation.cpp index 14207ce65..247c2b329 100644 --- a/slsReceiverSoftware/src/UDPBaseImplementation.cpp +++ b/slsReceiverSoftware/src/UDPBaseImplementation.cpp @@ -94,11 +94,12 @@ void UDPBaseImplementation::resetTotalFramesCaught(){ /*file parameters*/ char* UDPBaseImplementation::getFilePath() const{ - FILE_LOG(logWARNING) << "[WARNING] This is a base implementation, " << __func__ << " could have no effects."; + //FILE_LOG(logWARNING) << "[WARNING] This is a base implementation, " << __func__ << " could have no effects."; return (char*)filePath; } -char* UDPBaseImplementation::setFilePath(const char c[]){ +inline char* UDPBaseImplementation::setFilePath(const char c[]){ + cout << "SET FILE PATH " << c << endl; if(strlen(c)){ //check if filepath exists struct stat st; @@ -109,6 +110,7 @@ char* UDPBaseImplementation::setFilePath(const char c[]){ FILE_LOG(logWARNING) << "FilePath does not exist:" << filePath; } } + cout << getFilePath() << " " << filePath << endl; return getFilePath(); } @@ -117,7 +119,7 @@ char* UDPBaseImplementation::getFileName() const{ return (char*)fileName; } -char* UDPBaseImplementation::setFileName(const char c[]){ +inline char* UDPBaseImplementation::setFileName(const char c[]){ //cout << "[WARNING] This is a base implementation, " << __func__ << " could have no effects." << endl; if(strlen(c)) @@ -132,17 +134,15 @@ int UDPBaseImplementation::getFileIndex(){ } int UDPBaseImplementation::setFileIndex(int i){ - cout << "[WARNING] This is a base implementation, " << __func__ << " could have no effects." << endl; - /* + //cout << "[WARNING] This is a base implementation, " << __func__ << " could have no effects." << endl; if(i>=0) fileIndex = i; - */ return getFileIndex(); } int UDPBaseImplementation::setFrameIndexNeeded(int i){ - cout << "[WARNING] This is a base implementation, " << __func__ << " could have no effects." << endl; + //cout << "[WARNING] This is a base implementation, " << __func__ << " could have no effects." << endl; frameIndexNeeded = i; return frameIndexNeeded; } @@ -871,8 +871,10 @@ int UDPBaseImplementation::setupWriter(){ //acquisition start call back returns enable write - if (startAcquisitionCallBack) + if (startAcquisitionCallBack){ + cout << filePath << " - " << fileName << endl; cbAction=startAcquisitionCallBack(filePath,fileName,fileIndex,bufferSize,pStartAcquisition); + } if(cbAction < DO_EVERYTHING) cout << endl << "Note: Call back activated. Data saving must be taken care of by user in call back." << endl; @@ -952,14 +954,21 @@ int UDPBaseImplementation::createCompressionFile(int ithr, int iframe){ int UDPBaseImplementation::createNewFile(){ - int gt = getFrameIndex(); - if(gt==-1) gt=0; + + cout << "[WARNING] This is a base implementation, " << __func__ << " not correctly implemented" << endl; + + + /* + int gt = getFrameIndex(); + if(gt==-1) gt=0; //create file name if(frameIndexNeeded==-1) sprintf(savefilename, "%s/%s_%d.raw", filePath,fileName,fileIndex); else sprintf(savefilename, "%s/%s_f%012d_%d.raw", filePath,fileName,(packetsCaught/packetsPerFrame),fileIndex); + cout << filePath << " + " << fileName << endl; + //if filewrite and we are allowed to write if(enableFileWrite && cbAction > DO_NOTHING){ //close @@ -974,7 +983,7 @@ int UDPBaseImplementation::createNewFile(){ return FAIL; } }else if (NULL == (sfilefd = fopen((const char *) (savefilename), "w"))){ - cout << "Error: Could not create file " << savefilename << endl; + cout << "Error: Could not creat dsdasdserwe file " << savefilename << endl; return FAIL; } //setting buffer @@ -1001,7 +1010,7 @@ int UDPBaseImplementation::createNewFile(){ prevframenum = currframenum; packetsInFile = 0; } - + */ return OK; } diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 1314f2d5c..19ea6cced 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -110,8 +110,11 @@ void UDPStandardImplementation::initializeMembers(){ strcpy(detHostname,""); strcpy(guiFileName,""); strcpy(savefilename,""); - strcpy(filePath,""); - strcpy(fileName,"run"); + + setFileName("run"); + setFilePath(""); + //strcpy(filePath,""); + //strcpy(fileName,"run"); //status @@ -122,16 +125,17 @@ void UDPStandardImplementation::initializeMembers(){ } -UDPStandardImplementation::UDPStandardImplementation(): - thread_started(0), - eth(NULL), - latestData(NULL), - guiFileName(NULL), - guiFrameNumber(0), - tengigaEnable(0){ +UDPStandardImplementation::UDPStandardImplementation(){ cout << "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAa" << endl; + thread_started = 0; + eth = NULL; + latestData = NULL; + guiFileName = NULL; + guiFrameNumber = 0; + tengigaEnable = 0; + for(int i=0;i DO_NOTHING){ //close From cfacc6ad6ed831548a42c7288d01d82431bb9757 Mon Sep 17 00:00:00 2001 From: Leonardo Sala Date: Mon, 15 Sep 2014 16:52:53 +0200 Subject: [PATCH 037/474] modified to support REST receiver, still not properly working --- slsReceiverSoftware/Makefile | 9 ++++++++- slsReceiverSoftware/src/UDPInterface.cpp | 8 +++++--- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/slsReceiverSoftware/Makefile b/slsReceiverSoftware/Makefile index 4bc760e82..b245a634f 100644 --- a/slsReceiverSoftware/Makefile +++ b/slsReceiverSoftware/Makefile @@ -15,9 +15,16 @@ CFLAGS= -g -DC_ONLY -fPIC DFLAGS= -g -DDACS_INT -DSLS_RECEIVER_UDP_FUNCTIONS -INCLUDES?= -Iinclude -I../slsDetectorCalibration -I$(ASM) +INCLUDES?= $(INCLUDESRXR) -I include/ -I ../slsDetectorCalibration + +#-Iinclude -I../slsDetectorCalibration -I$(ASM) SRC_CLNT = MySocketTCP.cpp UDPInterface.cpp UDPBaseImplementation.cpp UDPStandardImplementation.cpp slsReceiverTCPIPInterface.cpp slsReceiver.cpp slsReceiverUsers.cpp utilities.cpp + +ifeq ($(REST), yes) + SRC_CLNT += UDPRESTImplementation.cpp +endif + MAIN_SRC = main.cpp OBJS=$(SRC_CLNT:%.cpp=$(BUILDDIR)/%.o) diff --git a/slsReceiverSoftware/src/UDPInterface.cpp b/slsReceiverSoftware/src/UDPInterface.cpp index a0d771687..0d7d0503c 100644 --- a/slsReceiverSoftware/src/UDPInterface.cpp +++ b/slsReceiverSoftware/src/UDPInterface.cpp @@ -23,6 +23,7 @@ using namespace std; #include "UDPInterface.h" #include "UDPBaseImplementation.h" #include "UDPStandardImplementation.h" +#include "UDPRESTImplementation.h" @@ -35,10 +36,11 @@ UDPInterface * UDPInterface::create(string receiver_type){ return new UDPStandardImplementation(); } -#ifdef REST - else if (receiver_type == "REST") + //#ifdef REST + else if (receiver_type == "REST"){ return new UDPRESTImplementation(); -#endif + } + //#endif else{ FILE_LOG(logWARNING) << "[ERROR] UDP interface not supported, using standard implementation"; return new UDPBaseImplementation(); From 5cfe7b433832f1510eb6776a172b77caeb2d87bc Mon Sep 17 00:00:00 2001 From: Maliakal Dhanya Date: Tue, 16 Sep 2014 16:29:36 +0200 Subject: [PATCH 038/474] 32 bit image, and 32 bit mode frame number for eiger fixed, startframeindex included in readframe for all det in tcpip class --- .../MySocketTCP/genericSocket.h | 12 +++++++++ .../slsReceiver/slsReceiverBase.h | 3 ++- .../slsReceiver/slsReceiverTCPIPInterface.cpp | 27 ++++++++++--------- .../slsReceiver/slsReceiverUDPFunctions.cpp | 27 ++++++++++++++----- .../slsReceiver/slsReceiverUDPFunctions.h | 4 +-- 5 files changed, 51 insertions(+), 22 deletions(-) diff --git a/slsReceiverSoftware/MySocketTCP/genericSocket.h b/slsReceiverSoftware/MySocketTCP/genericSocket.h index bb899f35b..a798a0fef 100644 --- a/slsReceiverSoftware/MySocketTCP/genericSocket.h +++ b/slsReceiverSoftware/MySocketTCP/genericSocket.h @@ -61,6 +61,8 @@ class sockaddr_in; #endif +#include /******exit */ + #include #include #include @@ -558,6 +560,16 @@ enum communicationProtocol{ break; case UDP: if (socketDescriptor<0) return -1; + +/* + cout <<"******listening inside genericsocket"<0){ diff --git a/slsReceiverSoftware/slsReceiver/slsReceiverBase.h b/slsReceiverSoftware/slsReceiver/slsReceiverBase.h index 007bf4a97..97d21bec4 100644 --- a/slsReceiverSoftware/slsReceiver/slsReceiverBase.h +++ b/slsReceiverSoftware/slsReceiver/slsReceiverBase.h @@ -273,8 +273,9 @@ public: * @param c pointer to current file name * @param raw address of pointer, pointing to current frame to send to gui * @param fnum frame number for eiger as it is not in the packet + * @param fstartind is the start index of the acquisition */ - virtual void readFrame(char* c,char** raw, uint32_t &fnum) = 0; + virtual void readFrame(char* c,char** raw, uint32_t &fnum, uint32_t &fstartind ) = 0; /** set status to transmitting and * when fifo is empty later, sets status to run_finished diff --git a/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.cpp b/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.cpp index cc143efc4..2ebfd3826 100644 --- a/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.cpp +++ b/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.cpp @@ -1000,8 +1000,8 @@ int slsReceiverTCPIPInterface::moench_read_frame(){ else{ ret = OK; - startIndex=receiverBase->getStartFrameIndex(); - receiverBase->readFrame(fName,&raw,index); + /*startIndex=receiverBase->getStartFrameIndex();*/ + receiverBase->readFrame(fName,&raw,index,startIndex); /**send garbage with -1 index to try again*/ if (raw == NULL){ @@ -1170,8 +1170,8 @@ int slsReceiverTCPIPInterface::gotthard_read_frame(){ cout<<"haven't caught any frame yet"<getStartFrameIndex(); - receiverBase->readFrame(fName,&raw,index); + /*startIndex=receiverBase->getStartFrameIndex();*/ + receiverBase->readFrame(fName,&raw,index,startIndex); /**send garbage with -1 index to try again*/ if (raw == NULL){ @@ -1302,13 +1302,9 @@ int slsReceiverTCPIPInterface::eiger_read_frame(){ char* raw = new char[frameSize]; char* origVal = new char[frameSize]; char* retval = new char[dataSize]; - + uint32_t startIndex=0; strcpy(mess,"Could not read frame\n"); -/* typedef struct{ - unsigned char num1[4]; - unsigned char num2[4]; - } eiger_packet_header;*/ // execute action if the arguments correctly arrived #ifdef SLS_RECEIVER_UDP_FUNCTIONS @@ -1326,7 +1322,7 @@ int slsReceiverTCPIPInterface::eiger_read_frame(){ else{ ret = OK; /** read a frame */ - receiverBase->readFrame(fName,&raw, index); + receiverBase->readFrame(fName,&raw,index,startIndex); #ifdef VERBOSE cout << "index:" << dec << index << endl; #endif @@ -1373,16 +1369,21 @@ int slsReceiverTCPIPInterface::eiger_read_frame(){ memcpy(retval+retindex ,origVal+c1 ,numbytesperlineperport); retindex += numbytesperlineperport; c1 += numbytesperlineperport; + if(repeat == 2) c1 += 16; } for(irepeat=0;irepeat using namespace std; +#define EIGER_32BIT_INITIAL_CONSTANT 0x17c + @@ -785,7 +787,7 @@ void slsReceiverUDPFunctions::setupFifoStructure(){ /** acquisition functions */ -void slsReceiverUDPFunctions::readFrame(char* c,char** raw, uint32_t &fnum){ +void slsReceiverUDPFunctions::readFrame(char* c,char** raw, uint32_t &fnum, uint32_t &fstartind){ //point to gui data if (guiData == NULL) guiData = latestData; @@ -793,7 +795,7 @@ void slsReceiverUDPFunctions::readFrame(char* c,char** raw, uint32_t &fnum){ //copy data and filename strcpy(c,guiFileName); fnum = guiFrameNumber; - + fstartind = getStartFrameIndex(); //could not get gui data if(!guiDataReady){ @@ -1506,9 +1508,13 @@ int slsReceiverUDPFunctions::startListening(){ //normal listening else if(!carryonBufferSize){ + /* if(!ithread){*/ rc = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS, maxBufferSize); expected = maxBufferSize; - + /*}else{ + while(1) usleep(100000000); + } +*/ } //the remaining packets from previous buffer else{ @@ -1726,7 +1732,10 @@ int loop; //for progress if(myDetectorType == EIGER){ tempframenum = htonl(*(unsigned int*)((eiger_image_header *)((char*)(wbuf[ithread] + HEADER_SIZE_NUM_TOT_PACKETS)))->fnum); - tempframenum += (startFrameIndex-1); //eiger frame numbers start at 1, so need to -1 + if(dynamicRange != 32) + tempframenum += (startFrameIndex-1); //eiger frame numbers start at 1, so need to -1 + else + tempframenum = ((tempframenum / EIGER_32BIT_INITIAL_CONSTANT) + startFrameIndex)-1;//eiger 32 bit mode is a multiple of 17c. +startframeindex for scans }else if ((myDetectorType == GOTTHARD) && (shortFrame == -1)) tempframenum = (((((uint32_t)(*((uint32_t*)(wbuf[ithread] + HEADER_SIZE_NUM_TOT_PACKETS))))+1)& (frameIndexMask)) >> frameIndexOffset); else @@ -1751,6 +1760,7 @@ int loop; if (cbAction < DO_EVERYTHING){ for(i=0;i 0){ for(i=0;i Date: Wed, 17 Sep 2014 15:56:27 +0200 Subject: [PATCH 039/474] able to send data to eigerbe tweaks on logging added configuration_map, to flexibly pass options to the different receivers some more fixes to method overloads still very preliminary --- slsReceiverSoftware/include/RestHelper.h | 31 +-- .../include/UDPBaseImplementation.h | 5 +- slsReceiverSoftware/include/UDPInterface.h | 7 +- .../include/UDPRESTImplementation.h | 40 ++-- slsReceiverSoftware/include/logger.h | 15 +- slsReceiverSoftware/include/utilities.h | 4 +- .../src/UDPBaseImplementation.cpp | 116 +++++++++-- .../src/UDPRESTImplementation.cpp | 191 +++++++++++++----- .../src/UDPStandardImplementation.cpp | 8 +- slsReceiverSoftware/src/slsReceiver.cpp | 17 +- .../src/slsReceiverTCPIPInterface.cpp | 9 +- slsReceiverSoftware/src/utilities.cpp | 26 ++- 12 files changed, 352 insertions(+), 117 deletions(-) diff --git a/slsReceiverSoftware/include/RestHelper.h b/slsReceiverSoftware/include/RestHelper.h index fc4056c43..5c10d0ff9 100644 --- a/slsReceiverSoftware/include/RestHelper.h +++ b/slsReceiverSoftware/include/RestHelper.h @@ -19,17 +19,13 @@ #include "JsonBox/Value.h" +//#include "logger.h" + #include #include #include #include -#define EIGER_DEBUG -#ifdef EIGER_DEBUG -#define DEBUG(x) do { std::cerr << "[DEBUG] " << x << std::endl; } while (0) -#else -#define DEBUG(x) -#endif using namespace Poco::Net; @@ -39,7 +35,7 @@ using namespace std; class RestHelper { public: - RestHelper(int timeout=10, int n_tries=3){ + RestHelper(int timeout=10, int n_tries=10){ /** * * @@ -78,18 +74,22 @@ class RestHelper { */ //Check for http:// string + FILE_LOG(logDEBUG) << __func__ << " starting"; string proto_str = "http://"; + if( size_t found = hostname.find(proto_str) != string::npos ){ + cout << hostname << endl; + char c1[hostname.size()-found-1]; + cout << c1 << endl; size_t length1 = hostname.copy(c1, hostname.size()-found-1, proto_str.size()); c1[length1]='\0'; hostname = c1; } full_hostname = "http://"+hostname; - session = new HTTPClientSession(hostname,port ); + session = new HTTPClientSession(hostname, port ); session->setKeepAliveTimeout( Timespan( http_timeout,0) ); - }; @@ -168,7 +168,7 @@ class RestHelper { string answer; int code = send_request(session, req, &answer); if(code == 0 ) { - DEBUG("ANSWER " << answer ); + FILE_LOG(logDEBUG) << "ANSWER " << answer; json_value->loadFromString(answer); } delete uri; @@ -176,7 +176,7 @@ class RestHelper { }; - int post_json(string request, string *answer, string request_body=""){ + int post_json(string request, string *answer, string request_body="{}"){ /** * * @@ -192,15 +192,16 @@ class RestHelper { if (path.empty()) path = "/"; HTTPRequest req(HTTPRequest::HTTP_POST, path, HTTPMessage::HTTP_1_1 ); req.setContentType("application/json\r\n"); - req.setContentLength( request.length() ); - + cout << "REQUEST BODY " << request_body << endl; + req.setContentLength( request_body.length() ); int code = send_request(session, req, answer, request_body); + delete uri; return code; } - int post_json(string request, JsonBox::Value* json_value, string request_body=""){ + int post_json(string request, JsonBox::Value* json_value, string request_body="{}"){ /** * * @@ -283,7 +284,7 @@ class RestHelper { return code; } catch (exception& e){ - cout << "Exception connecting to "<< full_hostname << ": "<< e.what() << ", sleeping 5 seconds (" << n << "/"< config_map); + /** * delete and free member parameters diff --git a/slsReceiverSoftware/include/UDPInterface.h b/slsReceiverSoftware/include/UDPInterface.h index 590ee67d8..e2454e09b 100644 --- a/slsReceiverSoftware/include/UDPInterface.h +++ b/slsReceiverSoftware/include/UDPInterface.h @@ -13,6 +13,7 @@ * @short base class with all the functions for a receiver, set/get parameters, start/stop etc. */ +#include #include "sls_receiver_defs.h" #include "receiver_defs.h" @@ -20,7 +21,6 @@ #include "utilities.h" #include "logger.h" - /* void print_not_implemented(string method_name){ std::cout << "[WARNING] Method " << method_name << " not implemented!" << std::endl; @@ -78,9 +78,10 @@ class UDPInterface { * Factory create method */ static UDPInterface *create(string receiver_type = "standard"); - -public: + virtual void configure(map config_map) = 0; + + public: diff --git a/slsReceiverSoftware/include/UDPRESTImplementation.h b/slsReceiverSoftware/include/UDPRESTImplementation.h index 32c55e4ff..30cd782ed 100644 --- a/slsReceiverSoftware/include/UDPRESTImplementation.h +++ b/slsReceiverSoftware/include/UDPRESTImplementation.h @@ -34,7 +34,7 @@ * @short does all the functions for a receiver, set/get parameters, start/stop etc. */ -class UDPRESTImplementation : private virtual slsReceiverDefs, public UDPBaseImplementation { +class UDPRESTImplementation : protected virtual slsReceiverDefs, public UDPBaseImplementation { public: /** @@ -47,7 +47,10 @@ class UDPRESTImplementation : private virtual slsReceiverDefs, public UDPBaseImp */ virtual ~UDPRESTImplementation(); - + + void initialize_REST(); + + void configure(map config_map); /** * delete and free member parameters @@ -57,14 +60,28 @@ class UDPRESTImplementation : private virtual slsReceiverDefs, public UDPBaseImp /** * initialize member parameters */ - void initializeMembers(); + //void initializeMembers(); + + /** + * Set detector hostname + * @param c hostname + */ + //void initialize(const char *detectorHostName); + + /* Returns detector hostname + /returns hostname + * caller needs to deallocate the returned char array. + * if uninitialized, it must return NULL + */ + //char *getDetectorHostname() const; + /** * Set receiver type * @param det detector type * Returns success or FAIL */ - int setDetectorType(detectorType det); + //int setDetectorType(detectorType det); //Frame indices and numbers caught @@ -192,18 +209,6 @@ class UDPRESTImplementation : private virtual slsReceiverDefs, public UDPBaseImp */ runStatus getStatus() const; - /** - * Set detector hostname - * @param c hostname - */ - void initialize(const char *detectorHostName); - - /* Returns detector hostname - /returns hostname - * caller needs to deallocate the returned char array. - * if uninitialized, it must return NULL - */ - //char *getDetectorHostname() const; /** * Set Ethernet Interface or IP to listen to @@ -811,6 +816,9 @@ public: //REST specific bool isInitialized; RestHelper * rest ; + int rest_port; // receiver backend port + string rest_hostname; // receiver hostname + }; diff --git a/slsReceiverSoftware/include/logger.h b/slsReceiverSoftware/include/logger.h index eda43b0b0..3d6d5703e 100644 --- a/slsReceiverSoftware/include/logger.h +++ b/slsReceiverSoftware/include/logger.h @@ -5,6 +5,19 @@ #include #include +#define STRINGIFY(x) #x +#define TOSTRING(x) STRINGIFY(x) +#define MYCONCAT(x,y) +#define __AT__ string(__FILE__) + string("::") + string(__func__) + string("(): ") + +//":" TOSTRING(__LINE__) + +/* +void error(const char *location, const char *msg){ + printf("Error at %s: %s\n", location, msg); +} +*/ + inline std::string NowTime(); enum TLogLevel {logERROR, logWARNING, logINFO, logDEBUG, logDEBUG1, logDEBUG2, logDEBUG3, logDEBUG4}; @@ -110,7 +123,7 @@ template std::ostringstream& Log::Get(TLogLevel level) template Log::~Log() { os << std::endl; - T::Output(os.str()); + T::Output( os.str()); } template TLogLevel& Log::ReportingLevel() diff --git a/slsReceiverSoftware/include/utilities.h b/slsReceiverSoftware/include/utilities.h index 78a99bcbc..b28d4f32c 100644 --- a/slsReceiverSoftware/include/utilities.h +++ b/slsReceiverSoftware/include/utilities.h @@ -2,6 +2,8 @@ #include #include #include +#include + using namespace std; #include "sls_receiver_defs.h" @@ -9,5 +11,5 @@ using namespace std; //#define EIGER_DEBUG -int read_config_file(string fname, int *tcpip_port_no); +int read_config_file(string fname, int *tcpip_port_no, map * configuration_map); diff --git a/slsReceiverSoftware/src/UDPBaseImplementation.cpp b/slsReceiverSoftware/src/UDPBaseImplementation.cpp index 247c2b329..c831621ee 100644 --- a/slsReceiverSoftware/src/UDPBaseImplementation.cpp +++ b/slsReceiverSoftware/src/UDPBaseImplementation.cpp @@ -35,6 +35,11 @@ UDPBaseImplementation::UDPBaseImplementation(){} UDPBaseImplementation::~UDPBaseImplementation(){} +void UDPBaseImplementation::configure(map config_map){ + FILE_LOG(logWARNING) << __AT__ << "doing nothing..."; +}; + + void UDPBaseImplementation::deleteMembers(){ FILE_LOG(logWARNING) << "[WARNING] This is a base implementation, " << __func__ << " could have no effects."; } @@ -47,6 +52,92 @@ void UDPBaseImplementation::initializeMembers(){ int UDPBaseImplementation::setDetectorType(detectorType det){ cout << "[WARNING] This is a base implementation, " << __func__ << " not correctly implemented" << endl; + + cout << "Setting Receiver Type " << endl; + + deleteMembers(); + initializeMembers(); + + myDetectorType = det; + + switch(myDetectorType){ + case GOTTHARD: + cout << endl << "***** This is a GOTTHARD Receiver *****" << endl << endl; + break; + case MOENCH: + cout << endl << "***** This is a MOENCH Receiver *****" << endl << endl; + break; + case EIGER: + cout << endl << "***** This is a EIGER Receiver *****" << endl << endl; + break; + default: + cout << endl << "***** Unknown Receiver *****" << endl << endl; + return FAIL; + break; + } + + //moench variables + if(myDetectorType == GOTTHARD){ + fifosize = GOTTHARD_FIFO_SIZE; + packetsPerFrame = GOTTHARD_PACKETS_PER_FRAME; + onePacketSize = GOTTHARD_ONE_PACKET_SIZE; + frameSize = GOTTHARD_BUFFER_SIZE; + bufferSize = GOTTHARD_BUFFER_SIZE; + maxPacketsPerFile = MAX_FRAMES_PER_FILE * GOTTHARD_PACKETS_PER_FRAME; + frameIndexMask = GOTTHARD_FRAME_INDEX_MASK; + frameIndexOffset = GOTTHARD_FRAME_INDEX_OFFSET; + packetIndexMask = GOTTHARD_PACKET_INDEX_MASK; + }else if(myDetectorType == MOENCH){ + fifosize = MOENCH_FIFO_SIZE; + packetsPerFrame = MOENCH_PACKETS_PER_FRAME; + onePacketSize = MOENCH_ONE_PACKET_SIZE; + frameSize = MOENCH_BUFFER_SIZE; + bufferSize = MOENCH_BUFFER_SIZE; + maxPacketsPerFile = MOENCH_MAX_FRAMES_PER_FILE * MOENCH_PACKETS_PER_FRAME; + frameIndexMask = MOENCH_FRAME_INDEX_MASK; + frameIndexOffset = MOENCH_FRAME_INDEX_OFFSET; + packetIndexMask = MOENCH_PACKET_INDEX_MASK; + } + else if(myDetectorType == EIGER){ + fifosize = EIGER_FIFO_SIZE; + packetsPerFrame = EIGER_ONE_GIGA_CONSTANT * dynamicRange * EIGER_MAX_PORTS; + onePacketSize = EIGER_ONE_GIGA_ONE_PACKET_SIZE; + frameSize = onePacketSize * packetsPerFrame; + bufferSize = (frameSize/EIGER_MAX_PORTS) + EIGER_HEADER_LENGTH;//everything one port gets (img header plus packets) + maxPacketsPerFile = EIGER_MAX_FRAMES_PER_FILE * packetsPerFrame; + frameIndexMask = EIGER_FRAME_INDEX_MASK; + frameIndexOffset = EIGER_FRAME_INDEX_OFFSET; + packetIndexMask = EIGER_PACKET_INDEX_MASK; + + pthread_mutex_lock(&status_mutex); + listeningthreads_mask = 0x0; + pthread_mutex_unlock(&(status_mutex)); + if(thread_started) + createListeningThreads(true); + + numListeningThreads = MAX_NUM_LISTENING_THREADS; + } + latestData = new char[frameSize]; + + + setupFifoStructure(); + + if(createListeningThreads() == FAIL){ + cout << "ERROR: Could not create listening thread" << endl; + exit (-1); + } + + if(createWriterThreads() == FAIL){ + cout << "ERROR: Could not create writer threads" << endl; + exit (-1); + } + + setThreadPriorities(); + + cout << "Ready..." << endl; + + return OK; + return OK; } @@ -94,12 +185,11 @@ void UDPBaseImplementation::resetTotalFramesCaught(){ /*file parameters*/ char* UDPBaseImplementation::getFilePath() const{ - //FILE_LOG(logWARNING) << "[WARNING] This is a base implementation, " << __func__ << " could have no effects."; return (char*)filePath; } inline char* UDPBaseImplementation::setFilePath(const char c[]){ - cout << "SET FILE PATH " << c << endl; + FILE_LOG(logDEBUG) << __AT__ << "called"; if(strlen(c)){ //check if filepath exists struct stat st; @@ -110,6 +200,7 @@ inline char* UDPBaseImplementation::setFilePath(const char c[]){ FILE_LOG(logWARNING) << "FilePath does not exist:" << filePath; } } + FILE_LOG(logDEBUG) << __AT__ << getFilePath(); cout << getFilePath() << " " << filePath << endl; return getFilePath(); } @@ -628,6 +719,7 @@ void UDPBaseImplementation::copyFrameToGui(char* startbuf[], uint32_t fnum, char int UDPBaseImplementation::createUDPSockets(){ + FILE_LOG(logDEBUG) << __FILE__ << "::" << __func__ << " starting"; //if eth is mistaken with ip address @@ -1015,17 +1107,12 @@ int UDPBaseImplementation::createNewFile(){ } - - - - - - -void UDPBaseImplementation::closeFile(int ithr){ -#ifdef VERBOSE - cout << "In closeFile for thread " << ithr << endl; -#endif - +// This is actually called on CTRL-C +void UDPBaseImplementation::closeFile(int ithr) +{ + + FILE_LOG(logDEBUG) << __AT__ << "called"; + if(!dataCompression){ if(sfilefd){ #ifdef VERBOSE @@ -1072,6 +1159,9 @@ void UDPBaseImplementation::closeFile(int ithr){ #endif } + + FILE_LOG(logDEBUG) << __AT__ << "exited"; + } diff --git a/slsReceiverSoftware/src/UDPRESTImplementation.cpp b/slsReceiverSoftware/src/UDPRESTImplementation.cpp index 3dc6b210a..8f40e9552 100644 --- a/slsReceiverSoftware/src/UDPRESTImplementation.cpp +++ b/slsReceiverSoftware/src/UDPRESTImplementation.cpp @@ -16,55 +16,113 @@ #include // stat #include // socket(), bind(), listen(), accept(), shut down #include // sock_addr_in, htonl, INADDR_ANY -#include // exit() -#include //set precision -#include //munmap +#include // exit() +#include // set precision +#include // munmap #include #include +#include //#include "utilities.h" using namespace std; +/* + TODO + + filePath != getFilePath + +*/ -UDPRESTImplementation::UDPRESTImplementation() : isInitialized(false), status(slsReceiverDefs::ERROR) {} +UDPRESTImplementation::UDPRESTImplementation(){ + + rest_hostname = "localhost"; + rest_port = 8081; +} UDPRESTImplementation::~UDPRESTImplementation(){} -void UDPRESTImplementation::initialize(const char *detectorHostName){ +void UDPRESTImplementation::configure(map config_map){ + FILE_LOG(logWARNING) << __AT__ << " called"; - string name; - if (detectorHostName != NULL) - name = detectorHostName; + map::const_iterator pos; - if (name.empty()) { - FILE_LOG(logDEBUG) << "initialize(): can't initialize with empty string or NULL for detectorHostname"; - } else if (isInitialized == true) { - FILE_LOG(logDEBUG) << "initialize(): already initialized, can't initialize several times"; - } else { - FILE_LOG(logDEBUG) << "initialize(): initialize() with: detectorHostName=" << name; - strcpy(detHostname,detectorHostName); - //init_config.detectorHostname = name; + pos = config_map.find("rest_hostname"); + if (pos != config_map.end() ){ + string host_port_str = pos->second; + std::size_t pos = host_port_str.find(":"); // position of "live" in str + if(pos != string::npos){ + istringstream (host_port_str.substr (pos)) >> rest_port; + rest_hostname = host_port_str.substr(0, pos); + cout << rest_hostname << " " << rest_port << endl; + } + } + + for(map::const_iterator i=config_map.begin(); i != config_map.end(); i++){ + std::cout << i->first << " " << i->second<< std::endl; + } + + +}; + + + +void UDPRESTImplementation::initialize_REST(){ + + if (rest_hostname.empty()) { + FILE_LOG(logDEBUG) << __AT__ <<"can't initialize with empty string or NULL for detectorHostname"; + } + else if (isInitialized == true) { + FILE_LOG(logDEBUG) << __AT__ << "already initialized, can't initialize several times"; + } + else { + FILE_LOG(logDEBUG) << __AT__ << "with receiverHostName=" << rest_hostname << ":" << rest_port; - //REST call - hardcoded - //RestHelper rest ; - rest->init(detHostname, 8080); + rest = new RestHelper() ; std::string answer; - int code = rest->get_json("status", &answer); - if (code != 0){ - //throw -1; - std::cout << "I SHOULD THROW AN EXCEPTION!!!" << std::endl; - } - else{ - isInitialized = true; - status = slsReceiverDefs::IDLE; - } - std::cout << "Answer: " << answer << std::endl; + int code; + try{ + rest->init(rest_hostname, rest_port); + code = rest->get_json("state", &answer); + if (code != 0){ + throw answer; + } + else{ + isInitialized = true; + status = slsReceiverDefs::IDLE; + } + FILE_LOG(logDEBUG) << __func__ << "Answer: " << answer; + } + catch(std::string e){ + FILE_LOG(logERROR) << __func__ << ": " << e; + throw; + } + + //JsonBox::Object json_object; + //json_object["configfile"] = JsonBox::Value("FILENAME"); + JsonBox::Value json_request; + //json_request["configfile"] = "config.py"; + json_request["path"] = filePath; + + stringstream ss; + string test; + std::cout << "GetSTring: " << json_request << std::endl; + json_request.writeToStream(ss, false); + //ss << json_request; + ss >> test; + + + cout << "aaaa" <post_json("state/initialize", &answer, test); + FILE_LOG(logDEBUG) << __AT__ << "state/configure got " << code; + code = rest->get_json("state", &answer); + FILE_LOG(logDEBUG) << __AT__ << "state got " << code << " " << answer; + /* std::std::cout << string << std::endl; << "---- REST test 3: true, json object "<< std::endl; @@ -73,14 +131,18 @@ void UDPRESTImplementation::initialize(const char *detectorHostName){ std::cout << "JSON " << json_value["status"] << std::endl; */ } + + FILE_LOG(logDEBUG) << __func__ << ": initialize() done"; + } +/* int UDPRESTImplementation::setDetectorType(detectorType det){ cout << "[WARNING] This is a base implementation, " << __func__ << " not correctly implemented" << endl; return OK; } - +*/ /*Frame indices and numbers caught*/ @@ -180,7 +242,9 @@ char *UDPRESTImplementation::getDetectorHostname() const{ */ void UDPRESTImplementation::setEthernetInterface(char* c){ - strcpy(eth,c); + FILE_LOG(logDEBUG) << __FILE__ << "::" << __func__ << " starting"; + //strcpy(eth,c); + FILE_LOG(logDEBUG) << __FILE__ << "::" << __func__ << " done"; } @@ -219,14 +283,17 @@ int32_t UDPRESTImplementation::setScanTag(int32_t stag){ */ int32_t UDPRESTImplementation::setDynamicRange(int32_t dr){ - cout << "Setting Dynamic Range" << endl; + FILE_LOG(logDEBUG) << __FILE__ << "::" << __func__ << " starting"; int olddr = dynamicRange; if(dr >= 0){ dynamicRange = dr; } + FILE_LOG(logDEBUG) << __FILE__ << "::" << __func__ << " " << getDynamicRange(); return getDynamicRange(); + + } @@ -571,6 +638,8 @@ void UDPRESTImplementation::copyFrameToGui(char* startbuf[], uint32_t fnum, char int UDPRESTImplementation::createUDPSockets(){ + FILE_LOG(logDEBUG) << __FILE__ << "::" << __func__ << " starting"; + std::cout << "AAAAAAAAAAAa" << std::endl; //if eth is mistaken with ip address if (strchr(eth,'.')!=NULL) @@ -615,13 +684,24 @@ int UDPRESTImplementation::createUDPSockets(){ int UDPRESTImplementation::shutDownUDPSockets(){ + + FILE_LOG(logDEBUG) << __AT__ << "called"; + FILE_LOG(logDEBUG) << __AT__ << "doing nothing"; + + + /* for(int i=0;iShutDownSocket(); delete udpSocket[i]; udpSocket[i] = NULL; } } + */ + + FILE_LOG(logDEBUG) << __AT__ << "finished"; + return OK; } @@ -955,9 +1035,7 @@ int UDPRESTImplementation::createNewFile(){ void UDPRESTImplementation::closeFile(int ithr){ -#ifdef VERBOSE - cout << "In closeFile for thread " << ithr << endl; -#endif + FILE_LOG(logDEBUG) << __AT__ << "called for thread " << ithr; if(!dataCompression){ if(sfilefd){ @@ -1005,6 +1083,8 @@ void UDPRESTImplementation::closeFile(int ithr){ #endif } + + FILE_LOG(logDEBUG) << __AT__ << "exited for thread " << ithr; } @@ -1014,13 +1094,32 @@ void UDPRESTImplementation::closeFile(int ithr){ int UDPRESTImplementation::startReceiver(char message[]){ int i; + FILE_LOG(logDEBUG) << __FILE__ << "::" << __func__ << " starting"; + initialize_REST(); + FILE_LOG(logDEBUG) << __FILE__ << "::" << __func__ << " initialized"; // #ifdef VERBOSE cout << "Starting Receiver" << endl; //#endif + std::string answer; + int code; + + + //test = "{\"configfile\":\"config.pu\", \"path\":\"patto\"}"; + code = rest->post_json("state/configure", &answer); + std::cout << answer << std::endl; + code = rest->get_json("state", &answer); + std::cout << answer << std::endl; + + code = rest->post_json("state/open", &answer); + std::cout << answer << std::endl; + code = rest->get_json("state", &answer); + std::cout << answer << std::endl; + //reset listening thread variables + /* measurementStarted = false; //should be set to zero as its added to get next start frame indices for scans for eiger if(!acqStarted) currframenum = 0; @@ -1028,8 +1127,9 @@ int UDPRESTImplementation::startReceiver(char message[]){ for(int i = 0; i < numListeningThreads; ++i) totalListeningFrameCount[i] = 0; - + */ //udp socket + /* if(createUDPSockets() == FAIL){ strcpy(message,"Could not create UDP Socket(s).\n"); cout << endl << message << endl; @@ -1037,7 +1137,8 @@ int UDPRESTImplementation::startReceiver(char message[]){ } cout << "UDP socket(s) created successfully. 1st port " << server_port[0] << endl; - + */ + /* if(setupWriter() == FAIL){ //stop udp socket shutDownUDPSockets(); @@ -1069,7 +1170,7 @@ int UDPRESTImplementation::startReceiver(char message[]){ sem_post(&listensmp[i]); for(i=0; i < numWriterThreads; ++i) sem_post(&writersmp[i]); - + */ cout << "Receiver Started.\nStatus:" << status << endl; @@ -1081,10 +1182,7 @@ int UDPRESTImplementation::startReceiver(char message[]){ int UDPRESTImplementation::stopReceiver(){ - -//#ifdef VERBOSE - cout << "Stopping Receiver" << endl; -//#endif + FILE_LOG(logDEBUG) << __AT__ << "called"; if(status == RUNNING) startReadout(); @@ -1101,7 +1199,8 @@ int UDPRESTImplementation::stopReceiver(){ status = IDLE; pthread_mutex_unlock(&(status_mutex)); - cout << "Receiver Stopped.\nStatus:" << status << endl << endl; + FILE_LOG(logDEBUG) << __AT__ << "exited, status " << endl; + return OK; } @@ -1110,10 +1209,7 @@ int UDPRESTImplementation::stopReceiver(){ void UDPRESTImplementation::startReadout(){ - - //#ifdef VERBOSE - cout << "Start Receiver Readout" << endl; - //#endif + FILE_LOG(logDEBUG) << __FILE__ << "::" << __func__ << " starting"; //wait so that all packets which take time has arrived usleep(50000); @@ -1127,6 +1223,7 @@ void UDPRESTImplementation::startReadout(){ //kill udp socket to tell the listening thread to push last packet shutDownUDPSockets(); + FILE_LOG(logDEBUG) << __FILE__ << "::" << __func__ << " done"; } diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 19ea6cced..6f2f7eb69 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -127,8 +127,8 @@ void UDPStandardImplementation::initializeMembers(){ UDPStandardImplementation::UDPStandardImplementation(){ - cout << "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAa" << endl; - + FILE_LOG(logDEBUG) << __FILE__ << "::" << __func__ << " starting" ; + thread_started = 0; eth = NULL; latestData = NULL; @@ -963,7 +963,7 @@ int UDPStandardImplementation::shutDownUDPSockets(){ - +// TODO: add a destroyListeningThreads int UDPStandardImplementation::createListeningThreads(bool destroy){ int i; void* status; @@ -974,6 +974,8 @@ int UDPStandardImplementation::createListeningThreads(bool destroy){ listeningthreads_mask = 0x0; pthread_mutex_unlock(&(status_mutex)); + FILE_LOG(logDEBUG) << "Starting " << __func__ << endl; + if(!destroy){ //start listening threads diff --git a/slsReceiverSoftware/src/slsReceiver.cpp b/slsReceiverSoftware/src/slsReceiver.cpp index f051592ce..fcb0bb101 100644 --- a/slsReceiverSoftware/src/slsReceiver.cpp +++ b/slsReceiverSoftware/src/slsReceiver.cpp @@ -8,7 +8,7 @@ #include #include #include - +#include #include #include "slsReceiver.h" @@ -30,10 +30,12 @@ slsReceiver::slsReceiver(int argc, char *argv[], int &success){ */ //creating base receiver + map configuration_map; int tcpip_port_no = 1954; success=OK; string fname = ""; string udp_interface_type = "standard"; + string rest_hostname = "localhost:8081"; //parse command line for config static struct option long_options[] = { @@ -44,6 +46,7 @@ slsReceiver::slsReceiver(int argc, char *argv[], int &success){ {"type", required_argument, 0, 't'}, {"config", required_argument, 0, 'f'}, {"rx_tcpport", required_argument, 0, 'b'}, + {"rest_hostname", required_argument, 0, 'r'}, {"help", no_argument, 0, 'h'}, {0, 0, 0, 0} }; @@ -52,7 +55,7 @@ slsReceiver::slsReceiver(int argc, char *argv[], int &success){ int c; while ( c != -1 ){ - c = getopt_long (argc, argv, "bfht", long_options, &option_index); + c = getopt_long (argc, argv, "bfhtr", long_options, &option_index); /* Detect the end of the options. */ if (c == -1) @@ -72,12 +75,19 @@ slsReceiver::slsReceiver(int argc, char *argv[], int &success){ udp_interface_type = optarg; break; + case 'r': + rest_hostname = optarg; + break; + case 'h': string help_message = """\nSLS Receiver Server\n\n"""; help_message += """usage: slsReceiver --config config_fname [--rx_tcpport port]\n\n"""; help_message += """\t--config:\t configuration filename for SLS Detector receiver\n"""; help_message += """\t--rx_tcpport:\t TCP Communication Port with the client. Default: 1954.\n\n"""; + help_message += """\t--rest_hostname:\t Receiver hostname:port. It applies only to REST receivers, and indicates the hostname of the REST backend. Default: localhost:8081.\n\n"""; + help_message += """\t--type:\t Type of the receiver. Possible arguments are: standard, REST. Default: standard.\n\n"""; + cout << help_message << endl; break; @@ -91,7 +101,7 @@ slsReceiver::slsReceiver(int argc, char *argv[], int &success){ if( !fname.empty() ){ try{ FILE_LOG(logINFO) << "config file name " << fname; - success = read_config_file(fname, &tcpip_port_no); + success = read_config_file(fname, &tcpip_port_no, &configuration_map); //VERBOSE_PRINT("Read configuration file of " + iline + " lines"); } catch(...){ @@ -108,6 +118,7 @@ slsReceiver::slsReceiver(int argc, char *argv[], int &success){ if (success==OK){ FILE_LOG(logINFO) << "SLS Receiver starting " << udp_interface_type << " on port " << tcpip_port_no << endl; udp_interface = UDPInterface::create(udp_interface_type); + udp_interface->configure(configuration_map); tcpipInterface = new slsReceiverTCPIPInterface(success, udp_interface, tcpip_port_no); //tcp ip interface } diff --git a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp index ea59d4bce..275a6c932 100644 --- a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp +++ b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp @@ -69,14 +69,13 @@ slsReceiverTCPIPInterface::slsReceiverTCPIPInterface(int &success, UDPInterface* //Catch signal SIGINT to close files properly signal(SIGINT,staticCloseFile); - } } } int slsReceiverTCPIPInterface::setPortNumber(int pn){ - int p_number; + int p_number; MySocketTCP *oldsocket=NULL;; int sd=0; @@ -144,10 +143,12 @@ void slsReceiverTCPIPInterface::stop(){ cout<<"Shutting down TCP Socket and TCP thread"<ShutDownSocket(); + cout<<"Socket closed"<setEthernetInterface(eth); //get mac address from ethernet interface diff --git a/slsReceiverSoftware/src/utilities.cpp b/slsReceiverSoftware/src/utilities.cpp index ae401a5cc..afb5a6c65 100644 --- a/slsReceiverSoftware/src/utilities.cpp +++ b/slsReceiverSoftware/src/utilities.cpp @@ -5,19 +5,23 @@ #include #include +#include + #include "utilities.h" using namespace std; -int read_config_file(string fname, int *tcpip_port_no){ +int read_config_file(string fname, int *tcpip_port_no, map * configuration_map ){ ifstream infile; - string sLine,sargname; + string sLine,sargname, sargvalue; int iline = 0; int success = slsReceiverDefs::OK; + + infile.open(fname.c_str(), ios_base::in); if (infile.is_open()) { while(infile.good()){ @@ -26,21 +30,25 @@ int read_config_file(string fname, int *tcpip_port_no){ //VERBOSE_PRINT(sLine); - if(sLine.find('#')!=string::npos){ - //VERBOSE_PRINT( "Line is a comment "); + if(sLine.find('#') != string::npos) continue; - } - else if(sLine.length()<2){ - //VERBOSE_PRINT("Empty line "); + + else if(sLine.length()<2) continue; - } + else{ istringstream sstr(sLine); //parameter name - if(sstr.good()) + if(sstr.good()){ sstr >> sargname; + if (! sstr.good()) + continue; + + sstr >> sargvalue; + (*configuration_map)[sargname] = sargvalue; + } //tcp port if(sargname=="rx_tcpport"){ if(sstr.good()) { From e5864d4343a0df9c2a8eed524a793c4a828a4728 Mon Sep 17 00:00:00 2001 From: Leonardo Sala Date: Mon, 22 Sep 2014 11:45:01 +0200 Subject: [PATCH 040/474] Added status resetting for REST --- slsReceiverSoftware/include/UDPInterface.h | 26 +--- .../include/UDPRESTImplementation.h | 2 + .../src/UDPBaseImplementation.cpp | 20 ++- slsReceiverSoftware/src/UDPInterface.cpp | 11 -- .../src/UDPRESTImplementation.cpp | 137 ++++++++++++++---- .../src/slsReceiverTCPIPInterface.cpp | 47 +++--- 6 files changed, 157 insertions(+), 86 deletions(-) diff --git a/slsReceiverSoftware/include/UDPInterface.h b/slsReceiverSoftware/include/UDPInterface.h index e2454e09b..60d9cc75b 100644 --- a/slsReceiverSoftware/include/UDPInterface.h +++ b/slsReceiverSoftware/include/UDPInterface.h @@ -21,19 +21,15 @@ #include "utilities.h" #include "logger.h" -/* -void print_not_implemented(string method_name){ - std::cout << "[WARNING] Method " << method_name << " not implemented!" << std::endl; -} -*/ + class UDPInterface { - /* abstract class that defines the public interface of an sls detector data receiver. + /* abstract class that defines the public interface of an sls detector data receiver UDP part. * * Use the factory method slsReceiverBase::create() to get an instance: * - * slsReceiverBase *receiver = slsReceiverBase::create() + * UDPInterface *receiver = UDPInterface::create() * * supported sequence of method-calls: * @@ -64,11 +60,6 @@ class UDPInterface { public: - /** - * constructor - */ - //UDPInterface(){}; - /** * Destructor */ @@ -80,11 +71,10 @@ class UDPInterface { static UDPInterface *create(string receiver_type = "standard"); virtual void configure(map config_map) = 0; + public: - - /** * Initialize the Receiver @param detectorHostName detector hostname @@ -94,10 +84,10 @@ class UDPInterface { /* Returns detector hostname - /returns hostname - * caller needs to deallocate the returned char array. - * if uninitialized, it must return NULL - */ + /returns hostname + * caller needs to deallocate the returned char array. + * if uninitialized, it must return NULL + */ virtual char *getDetectorHostname() const = 0; /** diff --git a/slsReceiverSoftware/include/UDPRESTImplementation.h b/slsReceiverSoftware/include/UDPRESTImplementation.h index 30cd782ed..32213f50c 100644 --- a/slsReceiverSoftware/include/UDPRESTImplementation.h +++ b/slsReceiverSoftware/include/UDPRESTImplementation.h @@ -48,8 +48,10 @@ class UDPRESTImplementation : protected virtual slsReceiverDefs, public UDPBaseI virtual ~UDPRESTImplementation(); + protected: void initialize_REST(); + public: void configure(map config_map); /** diff --git a/slsReceiverSoftware/src/UDPBaseImplementation.cpp b/slsReceiverSoftware/src/UDPBaseImplementation.cpp index c831621ee..58d0f2395 100644 --- a/slsReceiverSoftware/src/UDPBaseImplementation.cpp +++ b/slsReceiverSoftware/src/UDPBaseImplementation.cpp @@ -2121,12 +2121,24 @@ int UDPBaseImplementation::enableTenGiga(int enable){ createWriterThreads(true); } for(int i=0;i // SIGINT -#include // stat -#include // socket(), bind(), listen(), accept(), shut down -#include // sock_addr_in, htonl, INADDR_ANY -#include // exit() -#include //set precision -#include //munmap -*/ - #include #include using namespace std; @@ -35,7 +25,6 @@ UDPInterface * UDPInterface::create(string receiver_type){ cout << "Starting " << receiver_type << endl; return new UDPStandardImplementation(); } - //#ifdef REST else if (receiver_type == "REST"){ return new UDPRESTImplementation(); diff --git a/slsReceiverSoftware/src/UDPRESTImplementation.cpp b/slsReceiverSoftware/src/UDPRESTImplementation.cpp index 8f40e9552..5ae3e670c 100644 --- a/slsReceiverSoftware/src/UDPRESTImplementation.cpp +++ b/slsReceiverSoftware/src/UDPRESTImplementation.cpp @@ -31,12 +31,14 @@ using namespace std; /* TODO + filePath != getFilePath - + + better state handling. Now it is only IDLE - RUNNING - IDLE */ UDPRESTImplementation::UDPRESTImplementation(){ - + FILE_LOG(logDEBUG) << __AT__ << " called"; + + // Default values rest_hostname = "localhost"; rest_port = 8081; } @@ -57,20 +59,21 @@ void UDPRESTImplementation::configure(map config_map){ if(pos != string::npos){ istringstream (host_port_str.substr (pos)) >> rest_port; rest_hostname = host_port_str.substr(0, pos); - cout << rest_hostname << " " << rest_port << endl; } } - + + /* for(map::const_iterator i=config_map.begin(); i != config_map.end(); i++){ std::cout << i->first << " " << i->second<< std::endl; } - + */ }; void UDPRESTImplementation::initialize_REST(){ + FILE_LOG(logDEBUG) << __AT__ << " called"; if (rest_hostname.empty()) { FILE_LOG(logDEBUG) << __AT__ <<"can't initialize with empty string or NULL for detectorHostname"; @@ -116,7 +119,6 @@ void UDPRESTImplementation::initialize_REST(){ ss >> test; - cout << "aaaa" <post_json("state/initialize", &answer, test); FILE_LOG(logDEBUG) << __AT__ << "state/configure got " << code; @@ -147,17 +149,34 @@ int UDPRESTImplementation::setDetectorType(detectorType det){ /*Frame indices and numbers caught*/ -bool UDPRESTImplementation::getAcquistionStarted(){return acqStarted;}; +bool UDPRESTImplementation::getAcquistionStarted(){ + FILE_LOG(logDEBUG) << __AT__ << " called"; + return acqStarted; +}; -bool UDPRESTImplementation::getMeasurementStarted(){return measurementStarted;}; +bool UDPRESTImplementation::getMeasurementStarted(){ + FILE_LOG(logDEBUG) << __AT__ << " called"; + return measurementStarted; +}; -int UDPRESTImplementation::getFramesCaught(){return (packetsCaught/packetsPerFrame);} +int UDPRESTImplementation::getFramesCaught(){ + FILE_LOG(logDEBUG) << __AT__ << " called"; + return (packetsCaught/packetsPerFrame); +} -int UDPRESTImplementation::getTotalFramesCaught(){return (totalPacketsCaught/packetsPerFrame);} +int UDPRESTImplementation::getTotalFramesCaught(){ + FILE_LOG(logDEBUG) << __AT__ << " called"; + return (totalPacketsCaught/packetsPerFrame); +} -uint32_t UDPRESTImplementation::getStartFrameIndex(){return startFrameIndex;} +uint32_t UDPRESTImplementation::getStartFrameIndex(){ + FILE_LOG(logDEBUG) << __AT__ << " called"; + return startFrameIndex; +} uint32_t UDPRESTImplementation::getFrameIndex(){ + FILE_LOG(logDEBUG) << __AT__ << " called"; + if(!packetsCaught) frameIndex=-1; else @@ -167,15 +186,22 @@ uint32_t UDPRESTImplementation::getFrameIndex(){ uint32_t UDPRESTImplementation::getAcquisitionIndex(){ + //FILE_LOG(logDEBUG) << __AT__ << " called, idx: " << acquisitionIndex; if(!totalPacketsCaught) - acquisitionIndex=-1; + acquisitionIndex = -1; else acquisitionIndex = currframenum - startAcquisitionIndex; + + //FILE_LOG(logDEBUG) << __AT__ << " idx: " << acquisitionIndex + // << " currframenum: " << currframenum + // << " startAcqIdx: " << startAcquisitionIndex; + return acquisitionIndex; } void UDPRESTImplementation::resetTotalFramesCaught(){ + FILE_LOG(logDEBUG) << __AT__ << " called"; acqStarted = false; startAcquisitionIndex = 0; totalPacketsCaught = 0; @@ -184,21 +210,23 @@ void UDPRESTImplementation::resetTotalFramesCaught(){ /*file parameters*/ int UDPRESTImplementation::getFileIndex(){ + FILE_LOG(logDEBUG) << __AT__ << " called"; return fileIndex; } int UDPRESTImplementation::setFileIndex(int i){ + FILE_LOG(logDEBUG) << __AT__ << " called"; cout << "[WARNING] This is a base implementation, " << __func__ << " could have no effects." << endl; - /* + if(i>=0) fileIndex = i; - */ + return getFileIndex(); } int UDPRESTImplementation::setFrameIndexNeeded(int i){ - cout << "[WARNING] This is a base implementation, " << __func__ << " could have no effects." << endl; + FILE_LOG(logDEBUG) << __AT__ << " called"; frameIndexNeeded = i; return frameIndexNeeded; } @@ -230,6 +258,7 @@ int UDPRESTImplementation::setEnableOverwrite(int i){ /*other parameters*/ slsReceiverDefs::runStatus UDPRESTImplementation::getStatus() const{ + FILE_LOG(logDEBUG) << __AT__ << " called, status: " << status; return status; } @@ -243,12 +272,15 @@ char *UDPRESTImplementation::getDetectorHostname() const{ void UDPRESTImplementation::setEthernetInterface(char* c){ FILE_LOG(logDEBUG) << __FILE__ << "::" << __func__ << " starting"; + + // TODO: this segfaults //strcpy(eth,c); - FILE_LOG(logDEBUG) << __FILE__ << "::" << __func__ << " done"; + //FILE_LOG(logDEBUG) << __FILE__ << "::" << __func__ << " done"; } void UDPRESTImplementation::setUDPPortNo(int p){ + FILE_LOG(logDEBUG) << __AT__ << " called"; for(int i=0;i=0){ nFrameToGui = i; setupFifoStructure(); @@ -339,7 +373,7 @@ int UDPRESTImplementation::setNFrameToGui(int i){ int64_t UDPRESTImplementation::setAcquisitionPeriod(int64_t index){ - + FILE_LOG(logDEBUG) << __AT__ << " called"; if(index >= 0){ if(index != acquisitionPeriod){ acquisitionPeriod = index; @@ -350,9 +384,13 @@ int64_t UDPRESTImplementation::setAcquisitionPeriod(int64_t index){ } -bool UDPRESTImplementation::getDataCompression(){return dataCompression;} +bool UDPRESTImplementation::getDataCompression(){ + FILE_LOG(logDEBUG) << __AT__ << " called"; + return dataCompression; +} int UDPRESTImplementation::enableDataCompression(bool enable){ + FILE_LOG(logDEBUG) << __AT__ << " called"; cout << "Data compression "; if(enable) cout << "enabled" << endl; @@ -406,6 +444,7 @@ int UDPRESTImplementation::enableDataCompression(bool enable){ void UDPRESTImplementation::deleteFilter(){ + FILE_LOG(logDEBUG) << __AT__ << " called"; int i; cmSub=NULL; @@ -423,6 +462,7 @@ void UDPRESTImplementation::deleteFilter(){ void UDPRESTImplementation::setupFilter(){ + FILE_LOG(logDEBUG) << __AT__ << " called"; double hc = 0; double sigma = 5; int sign = 1; @@ -459,6 +499,11 @@ void UDPRESTImplementation::setupFilter(){ //LEO: it is not clear to me.. void UDPRESTImplementation::setupFifoStructure(){ + FILE_LOG(logDEBUG) << __AT__ << " called, doing nothing"; +} +/* +void UDPRESTImplementation::setupFifoStructure(){ + FILE_LOG(logDEBUG) << __AT__ << " called"; int64_t i; int oldn = numJobsPerThread; @@ -504,10 +549,6 @@ void UDPRESTImplementation::setupFifoStructure(){ cout << "Number of Frames per buffer:" << numJobsPerThread << endl; cout << "Fifo Size:" << fifosize << endl; - /* - //for testing - numJobsPerThread = 3; fifosize = 11; - */ for(int i=0;iget_json("state", &answer); + std::cout << answer << std::endl; + + code = rest->post_json("state/close", &answer); + std::cout << answer << std::endl; + code = rest->post_json("state/reset", &answer); + std::cout << answer << std::endl; + + code = rest->get_json("state", &answer); + std::cout << answer << std::endl; + + status = slsReceiverDefs::IDLE; + + /* for(int i=0;iget_json("state", &answer); std::cout << answer << std::endl; + status = slsReceiverDefs::RUNNING; //reset listening thread variables /* @@ -1172,8 +1237,6 @@ int UDPRESTImplementation::startReceiver(char message[]){ sem_post(&writersmp[i]); */ - cout << "Receiver Started.\nStatus:" << status << endl; - return OK; } @@ -1230,6 +1293,8 @@ void UDPRESTImplementation::startReadout(){ void* UDPRESTImplementation::startListeningThread(void* this_pointer){ + FILE_LOG(logDEBUG) << __AT__ << " called"; + ((UDPRESTImplementation*)this_pointer)->startListening(); return this_pointer; @@ -1238,6 +1303,7 @@ void* UDPRESTImplementation::startListeningThread(void* this_pointer){ void* UDPRESTImplementation::startWritingThread(void* this_pointer){ + FILE_LOG(logDEBUG) << __AT__ << " called"; ((UDPRESTImplementation*)this_pointer)->startWriting(); return this_pointer; } @@ -1248,6 +1314,8 @@ void* UDPRESTImplementation::startWritingThread(void* this_pointer){ int UDPRESTImplementation::startListening(){ + FILE_LOG(logDEBUG) << __AT__ << " called"; + int ithread = currentListeningThreadIndex; #ifdef VERYVERBOSE cout << "In startListening() " << endl; @@ -1449,6 +1517,7 @@ int UDPRESTImplementation::startListening(){ int UDPRESTImplementation::startWriting(){ + FILE_LOG(logDEBUG) << __AT__ << " called"; int ithread = currentWriterThreadIndex; #ifdef VERYVERBOSE cout << ithread << "In startWriting()" <0) - port_no = pn; - - success=OK; - + myDetectorType(GOTTHARD), + receiverBase(rbase), + ret(OK), + lockStatus(0), + shortFrame(-1), + packetsPerFrame(GOTTHARD_PACKETS_PER_FRAME), + dynamicrange(16), + socket(NULL), + killTCPServerThread(0), + tenGigaEnable(0), portNumber(DEFAULT_PORTNO+2){ + + int port_no=portNumber; + + + if (pn>0) + port_no = pn; + + success=OK; + //create socket if(success == OK){ socket = new MySocketTCP(port_no); @@ -56,24 +56,25 @@ slsReceiverTCPIPInterface::slsReceiverTCPIPInterface(int &success, UDPInterface* delete socket; socket=NULL; } else { - portNumber=port_no; + portNumber=port_no; //initialize variables strcpy(socket->lastClientIP,"none"); strcpy(socket->thisClientIP,"none1"); strcpy(mess,"dummy message"); - + function_table(); #ifdef VERBOSE cout << "Function table assigned." << endl; #endif - + //Catch signal SIGINT to close files properly signal(SIGINT,staticCloseFile); } } - + } + int slsReceiverTCPIPInterface::setPortNumber(int pn){ int p_number; MySocketTCP *oldsocket=NULL;; From f05248cd3202613e989dbd9215fc2e71b5ff65d4 Mon Sep 17 00:00:00 2001 From: Leonardo Sala Date: Mon, 22 Sep 2014 14:09:31 +0200 Subject: [PATCH 041/474] fixes --- .../src/UDPRESTImplementation.cpp | 190 +++++++----------- .../src/UDPStandardImplementation.cpp | 90 +++++++-- 2 files changed, 153 insertions(+), 127 deletions(-) diff --git a/slsReceiverSoftware/src/UDPRESTImplementation.cpp b/slsReceiverSoftware/src/UDPRESTImplementation.cpp index 5ae3e670c..c3f6bf836 100644 --- a/slsReceiverSoftware/src/UDPRESTImplementation.cpp +++ b/slsReceiverSoftware/src/UDPRESTImplementation.cpp @@ -44,7 +44,9 @@ UDPRESTImplementation::UDPRESTImplementation(){ } -UDPRESTImplementation::~UDPRESTImplementation(){} +UDPRESTImplementation::~UDPRESTImplementation(){ + delete rest; +} void UDPRESTImplementation::configure(map config_map){ @@ -74,67 +76,67 @@ void UDPRESTImplementation::configure(map config_map){ void UDPRESTImplementation::initialize_REST(){ FILE_LOG(logDEBUG) << __AT__ << " called"; - - if (rest_hostname.empty()) { - FILE_LOG(logDEBUG) << __AT__ <<"can't initialize with empty string or NULL for detectorHostname"; - } - else if (isInitialized == true) { - FILE_LOG(logDEBUG) << __AT__ << "already initialized, can't initialize several times"; - } - else { - FILE_LOG(logDEBUG) << __AT__ << "with receiverHostName=" << rest_hostname << ":" << rest_port; - - rest = new RestHelper() ; - std::string answer; - int code; - try{ - rest->init(rest_hostname, rest_port); - code = rest->get_json("state", &answer); - - if (code != 0){ - throw answer; - } - else{ - isInitialized = true; - status = slsReceiverDefs::IDLE; - } - FILE_LOG(logDEBUG) << __func__ << "Answer: " << answer; - } - catch(std::string e){ - FILE_LOG(logERROR) << __func__ << ": " << e; - throw; - } - - //JsonBox::Object json_object; - //json_object["configfile"] = JsonBox::Value("FILENAME"); - JsonBox::Value json_request; - //json_request["configfile"] = "config.py"; - json_request["path"] = filePath; - - stringstream ss; - string test; - std::cout << "GetSTring: " << json_request << std::endl; - json_request.writeToStream(ss, false); - //ss << json_request; - ss >> test; - - - test = "{\"path\":\"" + string( getFilePath() ) + "\"}"; - code = rest->post_json("state/initialize", &answer, test); - FILE_LOG(logDEBUG) << __AT__ << "state/configure got " << code; - code = rest->get_json("state", &answer); - FILE_LOG(logDEBUG) << __AT__ << "state got " << code << " " << answer; - - - /* - std::std::cout << string << std::endl; << "---- REST test 3: true, json object "<< std::endl; - JsonBox::Value json_value; - code = rest.get_json("status", &json_value); - std::cout << "JSON " << json_value["status"] << std::endl; + + if (rest_hostname.empty()) { + FILE_LOG(logDEBUG) << __AT__ <<"can't initialize with empty string or NULL for detectorHostname"; + } + else if (isInitialized == true) { + FILE_LOG(logDEBUG) << __AT__ << "already initialized, can't initialize several times"; + } + else { + FILE_LOG(logDEBUG) << __AT__ << "with receiverHostName=" << rest_hostname << ":" << rest_port; + + rest = new RestHelper() ; + std::string answer; + int code; + try{ + rest->init(rest_hostname, rest_port); + code = rest->get_json("state", &answer); + + if (code != 0){ + throw answer; + } + else{ + isInitialized = true; + status = slsReceiverDefs::IDLE; + } + FILE_LOG(logDEBUG) << __func__ << "Answer: " << answer; + } + catch(std::string e){ + FILE_LOG(logERROR) << __func__ << ": " << e; + throw; + } + + //JsonBox::Object json_object; + //json_object["configfile"] = JsonBox::Value("FILENAME"); + JsonBox::Value json_request; + //json_request["configfile"] = "config.py"; + json_request["path"] = filePath; + + stringstream ss; + string test; + std::cout << "GetSTring: " << json_request << std::endl; + json_request.writeToStream(ss, false); + //ss << json_request; + ss >> test; + + + test = "{\"path\":\"" + string( getFilePath() ) + "\"}"; + code = rest->post_json("state/initialize", &answer, test); + FILE_LOG(logDEBUG) << __AT__ << "state/configure got " << code; + code = rest->get_json("state", &answer); + FILE_LOG(logDEBUG) << __AT__ << "state got " << code << " " << answer; + + + /* + std::std::cout << string << std::endl; << "---- REST test 3: true, json object "<< std::endl; + JsonBox::Value json_value; + code = rest.get_json("status", &json_value); + std::cout << "JSON " << json_value["status"] << std::endl; */ - } - - FILE_LOG(logDEBUG) << __func__ << ": initialize() done"; + } + + FILE_LOG(logDEBUG) << __func__ << ": initialize() done"; } @@ -166,6 +168,10 @@ int UDPRESTImplementation::getFramesCaught(){ int UDPRESTImplementation::getTotalFramesCaught(){ FILE_LOG(logDEBUG) << __AT__ << " called"; + if (packetsPerFrame == 0){ + FILE_LOG(logWARNING) << __AT__ << " packetsPerFrame is 0!!!"; + return 0; + } return (totalPacketsCaught/packetsPerFrame); } @@ -216,7 +222,6 @@ int UDPRESTImplementation::getFileIndex(){ int UDPRESTImplementation::setFileIndex(int i){ FILE_LOG(logDEBUG) << __AT__ << " called"; - cout << "[WARNING] This is a base implementation, " << __func__ << " could have no effects." << endl; if(i>=0) fileIndex = i; @@ -390,56 +395,12 @@ bool UDPRESTImplementation::getDataCompression(){ } int UDPRESTImplementation::enableDataCompression(bool enable){ - FILE_LOG(logDEBUG) << __AT__ << " called"; - cout << "Data compression "; - if(enable) - cout << "enabled" << endl; - else - cout << "disabled" << endl; -#ifdef MYROOT1 - cout << " WITH ROOT" << endl; -#else - cout << " WITHOUT ROOT" << endl; -#endif - //delete filter for the current number of threads - deleteFilter(); - - dataCompression = enable; - pthread_mutex_lock(&status_mutex); - writerthreads_mask = 0x0; - pthread_mutex_unlock(&(status_mutex)); - - createWriterThreads(true); - - if(enable) - numWriterThreads = MAX_NUM_WRITER_THREADS; - else - numWriterThreads = 1; - - if(createWriterThreads() == FAIL){ - cout << "ERROR: Could not create writer threads" << endl; - return FAIL; - } - setThreadPriorities(); - - - if(enable) - setupFilter(); - + FILE_LOG(logDEBUG) << __AT__ << " called, doing nothing"; return OK; } - - - - - - - - - /*other functions*/ @@ -462,6 +423,8 @@ void UDPRESTImplementation::deleteFilter(){ void UDPRESTImplementation::setupFilter(){ + //LEO: check + FILE_LOG(logDEBUG) << __AT__ << " called"; double hc = 0; double sigma = 5; @@ -698,7 +661,7 @@ int UDPRESTImplementation::createUDPSockets(){ } //normal socket else{ - cout<<"eth:"<get_json("state", &answer); @@ -742,7 +704,7 @@ int UDPRESTImplementation::shutDownUDPSockets(){ code = rest->get_json("state", &answer); std::cout << answer << std::endl; - status = slsReceiverDefs::IDLE; + status = slsReceiverDefs::RUN_FINISHED; @@ -1744,7 +1706,11 @@ void UDPRESTImplementation::startFrameIndices(int ithread){ } +void UDPRESTImplementation::stopListening(int ithread, int rc, int &pc, int &t){ + FILE_LOG(logDEBUG) << __AT__ << " called, doing nothing"; +}; +/* void UDPRESTImplementation::stopListening(int ithread, int rc, int &pc, int &t){ FILE_LOG(logDEBUG) << __AT__ << " called"; @@ -1754,7 +1720,7 @@ int i; cerr << ithread << " recvfrom() failed:"<push(buffer[ithread]); exit(-1); } @@ -1815,7 +1781,7 @@ int i; } } - +*/ diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 6f2f7eb69..b3e8aa098 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -125,7 +125,8 @@ void UDPStandardImplementation::initializeMembers(){ } -UDPStandardImplementation::UDPStandardImplementation(){ +UDPStandardImplementation::UDPStandardImplementation(){ FILE_LOG(logDEBUG) << __AT__ << " called"; + FILE_LOG(logDEBUG) << __FILE__ << "::" << __func__ << " starting" ; @@ -182,7 +183,8 @@ UDPStandardImplementation::UDPStandardImplementation(){ -UDPStandardImplementation::~UDPStandardImplementation(){ +UDPStandardImplementation::~UDPStandardImplementation(){ FILE_LOG(logDEBUG) << __AT__ << " called"; + createListeningThreads(true); createWriterThreads(true); deleteMembers(); @@ -191,7 +193,8 @@ UDPStandardImplementation::~UDPStandardImplementation(){ -void UDPStandardImplementation::deleteMembers(){ +void UDPStandardImplementation::deleteMembers(){ FILE_LOG(logDEBUG) << __AT__ << " called"; + //kill threads if(thread_started){ createListeningThreads(true); @@ -224,7 +227,8 @@ void UDPStandardImplementation::deleteMembers(){ -int UDPStandardImplementation::setDetectorType(detectorType det){ +int UDPStandardImplementation::setDetectorType(detectorType det){ FILE_LOG(logDEBUG) << __AT__ << " called"; + cout << "Setting Receiver Type " << endl; deleteMembers(); @@ -451,6 +455,9 @@ int UDPStandardImplementation::setEnableOverwrite(int i){ /*other parameters*/ slsReceiverDefs::runStatus UDPStandardImplementation::getStatus() const{ + FILE_LOG(logDEBUG) << __AT__ << " called, status: " << status; + + return status; } @@ -465,12 +472,14 @@ char *UDPStandardImplementation::getDetectorHostname() const{ return (char*)detHostname; } -void UDPStandardImplementation::setEthernetInterface(char* c){ +void UDPStandardImplementation::setEthernetInterface(char* c){ FILE_LOG(logDEBUG) << __AT__ << " called"; + strcpy(eth,c); } -void UDPStandardImplementation::setUDPPortNo(int p){ +void UDPStandardImplementation::setUDPPortNo(int p){ FILE_LOG(logDEBUG) << __AT__ << " called"; + for(int i=0;i= 0) numberOfFrames = fnum; @@ -494,7 +504,8 @@ int UDPStandardImplementation::getScanTag() const{ } -int32_t UDPStandardImplementation::setScanTag(int32_t stag){ +int32_t UDPStandardImplementation::setScanTag(int32_t stag){ FILE_LOG(logDEBUG) << __AT__ << " called"; + if(stag >= 0) scanTag = stag; @@ -506,7 +517,8 @@ int UDPStandardImplementation::getDynamicRange() const{ return dynamicRange; } -int32_t UDPStandardImplementation::setDynamicRange(int32_t dr){ +int32_t UDPStandardImplementation::setDynamicRange(int32_t dr){ FILE_LOG(logDEBUG) << __AT__ << " called"; + cout << "Setting Dynamic Range" << endl; int olddr = dynamicRange; @@ -566,7 +578,8 @@ int32_t UDPStandardImplementation::setDynamicRange(int32_t dr){ -int UDPStandardImplementation::setShortFrame(int i){ +int UDPStandardImplementation::setShortFrame(int i){ FILE_LOG(logDEBUG) << __AT__ << " called"; + shortFrame=i; if(shortFrame!=-1){ @@ -596,7 +609,8 @@ int UDPStandardImplementation::setShortFrame(int i){ } -int UDPStandardImplementation::setNFrameToGui(int i){ +int UDPStandardImplementation::setNFrameToGui(int i){ FILE_LOG(logDEBUG) << __AT__ << " called"; + if(i>=0){ nFrameToGui = i; setupFifoStructure(); @@ -606,7 +620,8 @@ int UDPStandardImplementation::setNFrameToGui(int i){ -int64_t UDPStandardImplementation::setAcquisitionPeriod(int64_t index){ +int64_t UDPStandardImplementation::setAcquisitionPeriod(int64_t index){ FILE_LOG(logDEBUG) << __AT__ << " called"; + if(index >= 0){ if(index != acquisitionPeriod){ @@ -618,9 +633,11 @@ int64_t UDPStandardImplementation::setAcquisitionPeriod(int64_t index){ } -bool UDPStandardImplementation::getDataCompression(){return dataCompression;} +bool UDPStandardImplementation::getDataCompression(){ FILE_LOG(logDEBUG) << __AT__ << " called"; +return dataCompression;} + +int UDPStandardImplementation::enableDataCompression(bool enable){ FILE_LOG(logDEBUG) << __AT__ << " called"; -int UDPStandardImplementation::enableDataCompression(bool enable){ cout << "Data compression "; if(enable) cout << "enabled" << endl; @@ -673,7 +690,8 @@ int UDPStandardImplementation::enableDataCompression(bool enable){ /*other functions*/ -void UDPStandardImplementation::deleteFilter(){ +void UDPStandardImplementation::deleteFilter(){ FILE_LOG(logDEBUG) << __AT__ << " called"; + int i; cmSub=NULL; @@ -691,6 +709,8 @@ void UDPStandardImplementation::deleteFilter(){ void UDPStandardImplementation::setupFilter(){ + FILE_LOG(logDEBUG) << __AT__ << " called"; + double hc = 0; double sigma = 5; int sign = 1; @@ -727,6 +747,7 @@ void UDPStandardImplementation::setupFilter(){ //LEO: it is not clear to me.. void UDPStandardImplementation::setupFifoStructure(){ + FILE_LOG(logDEBUG) << __AT__ << " called"; int64_t i; int oldn = numJobsPerThread; @@ -816,6 +837,8 @@ void UDPStandardImplementation::setupFifoStructure(){ /** acquisition functions */ void UDPStandardImplementation::readFrame(char* c,char** raw, uint32_t &fnum){ + FILE_LOG(logDEBUG) << __AT__ << " called"; + //point to gui data if (guiData == NULL) guiData = latestData; @@ -850,6 +873,8 @@ void UDPStandardImplementation::readFrame(char* c,char** raw, uint32_t &fnum){ void UDPStandardImplementation::copyFrameToGui(char* startbuf[], uint32_t fnum, char* buf){ + FILE_LOG(logDEBUG) << __AT__ << " called"; + //random read when gui not ready if((!nFrameToGui) && (!guiData)){ @@ -905,6 +930,7 @@ void UDPStandardImplementation::copyFrameToGui(char* startbuf[], uint32_t fnum, int UDPStandardImplementation::createUDPSockets(){ + FILE_LOG(logDEBUG) << __AT__ << " called"; //if eth is mistaken with ip address @@ -950,6 +976,8 @@ int UDPStandardImplementation::createUDPSockets(){ int UDPStandardImplementation::shutDownUDPSockets(){ + FILE_LOG(logDEBUG) << __AT__ << " called"; + for(int i=0;iShutDownSocket(); @@ -965,6 +993,8 @@ int UDPStandardImplementation::shutDownUDPSockets(){ // TODO: add a destroyListeningThreads int UDPStandardImplementation::createListeningThreads(bool destroy){ + FILE_LOG(logDEBUG) << __AT__ << " called"; + int i; void* status; @@ -1022,6 +1052,8 @@ int UDPStandardImplementation::createListeningThreads(bool destroy){ int UDPStandardImplementation::createWriterThreads(bool destroy){ + FILE_LOG(logDEBUG) << __AT__ << " called"; + int i; void* status; @@ -1083,6 +1115,8 @@ int UDPStandardImplementation::createWriterThreads(bool destroy){ void UDPStandardImplementation::setThreadPriorities(){ + FILE_LOG(logDEBUG) << __AT__ << " called"; + int i; //assign priorities struct sched_param tcp_param, listen_param, write_param; @@ -1120,6 +1154,7 @@ void UDPStandardImplementation::setThreadPriorities(){ int UDPStandardImplementation::setupWriter(){ + FILE_LOG(logDEBUG) << __AT__ << " called"; //reset writing thread variables packetsInFile=0; @@ -1203,6 +1238,8 @@ int UDPStandardImplementation::setupWriter(){ int UDPStandardImplementation::createCompressionFile(int ithr, int iframe){ + FILE_LOG(logDEBUG) << __AT__ << " called"; + #ifdef MYROOT1 char temp[MAX_STR_LENGTH]; //create file name for gui purposes, and set up acquistion parameters @@ -1231,6 +1268,8 @@ int UDPStandardImplementation::createCompressionFile(int ithr, int iframe){ int UDPStandardImplementation::createNewFile(){ + FILE_LOG(logDEBUG) << __AT__ << " called"; + int gt = getFrameIndex(); if(gt==-1) gt=0; //create file name @@ -1295,6 +1334,8 @@ int UDPStandardImplementation::createNewFile(){ void UDPStandardImplementation::closeFile(int ithr){ + FILE_LOG(logDEBUG) << __AT__ << " called"; + #ifdef VERBOSE cout << "In closeFile for thread " << ithr << endl; #endif @@ -1352,6 +1393,8 @@ void UDPStandardImplementation::closeFile(int ithr){ int UDPStandardImplementation::startReceiver(char message[]){ + FILE_LOG(logDEBUG) << __AT__ << " called"; + int i; @@ -1420,6 +1463,7 @@ int UDPStandardImplementation::startReceiver(char message[]){ int UDPStandardImplementation::stopReceiver(){ + FILE_LOG(logDEBUG) << __AT__ << " called"; //#ifdef VERBOSE @@ -1450,6 +1494,7 @@ int UDPStandardImplementation::stopReceiver(){ void UDPStandardImplementation::startReadout(){ + FILE_LOG(logDEBUG) << __AT__ << " called"; //#ifdef VERBOSE cout << "Start Receiver Readout" << endl; @@ -1473,6 +1518,7 @@ void UDPStandardImplementation::startReadout(){ void* UDPStandardImplementation::startListeningThread(void* this_pointer){ + FILE_LOG(logDEBUG) << __AT__ << " called"; ((UDPStandardImplementation*)this_pointer)->startListening(); return this_pointer; @@ -1481,6 +1527,7 @@ void* UDPStandardImplementation::startListeningThread(void* this_pointer){ void* UDPStandardImplementation::startWritingThread(void* this_pointer){ + FILE_LOG(logDEBUG) << __AT__ << " called"; ((UDPStandardImplementation*)this_pointer)->startWriting(); return this_pointer; } @@ -1491,6 +1538,7 @@ void* UDPStandardImplementation::startWritingThread(void* this_pointer){ int UDPStandardImplementation::startListening(){ + FILE_LOG(logDEBUG) << __AT__ << " called"; int ithread = currentListeningThreadIndex; #ifdef VERYVERBOSE cout << "In startListening() " << endl; @@ -1692,6 +1740,8 @@ int UDPStandardImplementation::startListening(){ int UDPStandardImplementation::startWriting(){ + FILE_LOG(logDEBUG) << __AT__ << " called"; + int ithread = currentWriterThreadIndex; #ifdef VERYVERBOSE cout << ithread << "In startWriting()" < Date: Fri, 26 Sep 2014 11:19:26 +0200 Subject: [PATCH 042/474] udpport2 module --- .../slsReceiver/slsReceiverBase.h | 5 +++++ .../slsReceiver/slsReceiverTCPIPInterface.cpp | 7 ++++--- .../slsReceiver/slsReceiverUDPFunctions.cpp | 17 +++++++++++++---- .../slsReceiver/slsReceiverUDPFunctions.h | 5 +++++ 4 files changed, 27 insertions(+), 7 deletions(-) diff --git a/slsReceiverSoftware/slsReceiver/slsReceiverBase.h b/slsReceiverSoftware/slsReceiver/slsReceiverBase.h index 97d21bec4..41408f7e7 100644 --- a/slsReceiverSoftware/slsReceiver/slsReceiverBase.h +++ b/slsReceiverSoftware/slsReceiver/slsReceiverBase.h @@ -232,6 +232,11 @@ public: */ virtual void setUDPPortNo(int p) = 0; + /** + * Set UDP Port Number + */ + virtual void setUDPPortNo2(int p) = 0; + /** * Set Ethernet Interface or IP to listen to */ diff --git a/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.cpp b/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.cpp index 2ebfd3826..ef854bc59 100644 --- a/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.cpp +++ b/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.cpp @@ -613,10 +613,10 @@ int slsReceiverTCPIPInterface::setup_udp(){ ret=OK; strcpy(mess,"could not set up udp connection"); char retval[MAX_STR_LENGTH]=""; - char args[2][MAX_STR_LENGTH]; + char args[3][MAX_STR_LENGTH]; string temp; - int udpport; + int udpport,udpport2; char eth[MAX_STR_LENGTH]; @@ -641,8 +641,9 @@ int slsReceiverTCPIPInterface::setup_udp(){ else{ //set up udp port sscanf(args[1],"%d",&udpport); + sscanf(args[2],"%d",&udpport2); receiverBase->setUDPPortNo(udpport); - + receiverBase->setUDPPortNo2(udpport2); //setup udpip //get ethernet interface or IP to listen to temp = genericSocket::ipToName(args[0]); diff --git a/slsReceiverSoftware/slsReceiver/slsReceiverUDPFunctions.cpp b/slsReceiverSoftware/slsReceiver/slsReceiverUDPFunctions.cpp index ac73e78c0..388272b6b 100644 --- a/slsReceiverSoftware/slsReceiver/slsReceiverUDPFunctions.cpp +++ b/slsReceiverSoftware/slsReceiver/slsReceiverUDPFunctions.cpp @@ -443,9 +443,16 @@ void slsReceiverUDPFunctions::setEthernetInterface(char* c){ void slsReceiverUDPFunctions::setUDPPortNo(int p){ - for(int i=0;igetErrorStatus(); - if(iret){ + if(!iret) + cout << "UDP port opened at port " << server_port[i] << endl; + else{ #ifdef VERBOSE cout << "Could not create UDP socket on port " << server_port[i] << " error:" << iret << endl; #endif diff --git a/slsReceiverSoftware/slsReceiver/slsReceiverUDPFunctions.h b/slsReceiverSoftware/slsReceiver/slsReceiverUDPFunctions.h index c955ee1c4..20c5d7633 100644 --- a/slsReceiverSoftware/slsReceiver/slsReceiverUDPFunctions.h +++ b/slsReceiverSoftware/slsReceiver/slsReceiverUDPFunctions.h @@ -213,6 +213,11 @@ public: */ void setUDPPortNo(int p); + /** + * Set UDP Port Number2 + */ + void setUDPPortNo2(int p); + /* * Returns number of frames to receive * This is the number of frames to expect to receiver from the detector. From e94e678f7ddf5cd4eb8d38c0818bca585148e1de Mon Sep 17 00:00:00 2001 From: Maliakal Dhanya Date: Tue, 14 Oct 2014 15:42:32 +0200 Subject: [PATCH 043/474] receiver bottom module included, and image reconstruction works for all bit modes, receiver still for a half module each, although two of them combined to make one module image --- .../slsReceiver/slsReceiver.cpp | 32 ++++- .../slsReceiver/slsReceiverTCPIPInterface.cpp | 118 +++++++++++++----- .../slsReceiver/slsReceiverTCPIPInterface.h | 6 +- .../slsReceiver/slsReceiverUDPFunctions.cpp | 40 +++--- .../slsReceiver/slsReceiverUDPFunctions.h | 5 +- 5 files changed, 146 insertions(+), 55 deletions(-) diff --git a/slsReceiverSoftware/slsReceiver/slsReceiver.cpp b/slsReceiverSoftware/slsReceiver/slsReceiver.cpp index cd5ab551d..f044f7b7f 100644 --- a/slsReceiverSoftware/slsReceiver/slsReceiver.cpp +++ b/slsReceiverSoftware/slsReceiver/slsReceiver.cpp @@ -18,9 +18,8 @@ using namespace std; slsReceiver::slsReceiver(int argc, char *argv[], int &success){ //creating base receiver cout << "SLS Receiver" << endl; - receiverBase = new slsReceiverUDPFunctions(); int tcpip_port_no=-1; - + bool bottom = false; ifstream infile; @@ -116,6 +115,31 @@ slsReceiver::slsReceiver(int argc, char *argv[], int &success){ } } } + + //mode top:bottom + else if(!strcasecmp(argv[iarg],"-mode")){ + if(iarg+1==argc){ + cout << "no mode given after -mode in command line. Exiting." << endl; + success=FAIL; + }else{ + if(!strcasecmp(argv[iarg+1],"bottom")){ + cout<<"mode: bottom"< #include #include +#include //linux5 +#define be64toh(x) __bswap_64 (x) //linux5 +//#include //linux6 using namespace std; @@ -28,7 +31,7 @@ slsReceiverTCPIPInterface::~slsReceiverTCPIPInterface() { } -slsReceiverTCPIPInterface::slsReceiverTCPIPInterface(int &success, slsReceiverBase* rbase, int pn): +slsReceiverTCPIPInterface::slsReceiverTCPIPInterface(int &success, slsReceiverBase* rbase, int pn, bool bot): myDetectorType(GOTTHARD), receiverBase(rbase), ret(OK), @@ -38,7 +41,8 @@ slsReceiverTCPIPInterface::slsReceiverTCPIPInterface(int &success, slsReceiverBa dynamicrange(16), socket(NULL), killTCPServerThread(0), - tenGigaEnable(0), portNumber(DEFAULT_PORTNO+2){ + tenGigaEnable(0), portNumber(DEFAULT_PORTNO+2), + bottom(bot){ int port_no=portNumber; @@ -1336,7 +1340,7 @@ int slsReceiverTCPIPInterface::eiger_read_frame(){ } /**proper frame*/ - else{ + else{//cout<<"**** got proper frame ******"<> 8) & 0x00FF00FF00FF00FFULL ); temp = ((temp << 16) & 0xFFFF0000FFFF0000ULL ) | ((temp >> 16) & 0x0000FFFF0000FFFFULL ); temp = (temp << 32) | ((temp >> 32) & 0xFFFFFFFFULL); (*(((uint64_t*)retval)+i)) = temp; + */ } -/* - ( (((val) >> 56) & 0x00000000000000FF) | (((val) >> 40) & 0x000000000000FF00) | \ - (((val) >> 24) & 0x0000000000FF0000) | (((val) >> 8) & 0x00000000FF000000) | \ - (((val) << 8) & 0x000000FF00000000) | (((val) << 24) & 0x0000FF0000000000) | \ - (((val) << 40) & 0x00FF000000000000) | (((val) << 56) & 0xFF00000000000000) ) - */ - /* - for(i=0;i<(1024*(16*dynamicrange)*2)/4;i++) - (*(((uint32_t*)retval)+i)) = htonl((uint32_t)(*(((uint32_t*)retval)+i))); - */ arg = index-startIndex; } } diff --git a/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.h b/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.h index 423d0949a..ccd27c255 100644 --- a/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.h +++ b/slsReceiverSoftware/slsReceiver/slsReceiverTCPIPInterface.h @@ -26,8 +26,9 @@ public: * @param succecc socket creation was successfull * @param rbase pointer to the receiver base * @param pn port number (defaults to default port number) + * @param bot mode is bottom if true, else its a top half module */ - slsReceiverTCPIPInterface(int &success, slsReceiverBase* rbase, int pn=-1); + slsReceiverTCPIPInterface(int &success, slsReceiverBase* rbase, int pn=-1, bool bot=false); /** * Sets the port number to listen to. @@ -272,6 +273,9 @@ private: /** port number */ int portNumber; + /** true if bottom half module for eiger */ + bool bottom; + protected: /** Socket */ diff --git a/slsReceiverSoftware/slsReceiver/slsReceiverUDPFunctions.cpp b/slsReceiverSoftware/slsReceiver/slsReceiverUDPFunctions.cpp index 388272b6b..aa9458377 100644 --- a/slsReceiverSoftware/slsReceiver/slsReceiverUDPFunctions.cpp +++ b/slsReceiverSoftware/slsReceiver/slsReceiverUDPFunctions.cpp @@ -31,13 +31,14 @@ using namespace std; -slsReceiverUDPFunctions::slsReceiverUDPFunctions(): +slsReceiverUDPFunctions::slsReceiverUDPFunctions(bool bot): thread_started(0), eth(NULL), latestData(NULL), guiFileName(NULL), guiFrameNumber(0), - tengigaEnable(0){ + tengigaEnable(0), + bottom(bot){ for(int i=0;igetErrorStatus(); if(!iret) - cout << "UDP port opened at port " << server_port[i] << endl; + cout << "UDP port opened at port " << port[i] << endl; else{ #ifdef VERBOSE - cout << "Could not create UDP socket on port " << server_port[i] << " error:" << iret << endl; + cout << "Could not create UDP socket on port " << port[i] << " error:" << iret << endl; #endif return FAIL; } @@ -1351,7 +1357,7 @@ int slsReceiverUDPFunctions::startReceiver(char message[]){ cout << endl << message << endl; return FAIL; } - cout << "UDP socket(s) created successfully. 1st port " << server_port[0] << endl; + cout << "UDP socket(s) created successfully." << endl; if(setupWriter() == FAIL){ @@ -1540,9 +1546,9 @@ int slsReceiverUDPFunctions::startListening(){ expected = maxBufferSize - carryonBufferSize; } -#ifdef VERYDEBUG +//#ifdef VERYDEBUG cout << ithread << " *** rc:" << dec << rc << ". expected:" << dec << expected << endl; -#endif +//#endif @@ -1954,9 +1960,9 @@ int i; #endif pthread_mutex_unlock(&(status_mutex)); -#ifdef VERYDEBUG +//#ifdef VERYDEBUG cout << ithread << ": Frames listened to " << dec << ((totalListeningFrameCount[ithread]*numListeningThreads)/packetsPerFrame) << endl; -#endif +//#endif //waiting for all listening threads to be done, to print final count of frames listened to if(ithread == 0){ diff --git a/slsReceiverSoftware/slsReceiver/slsReceiverUDPFunctions.h b/slsReceiverSoftware/slsReceiver/slsReceiverUDPFunctions.h index 20c5d7633..d0efecfc3 100644 --- a/slsReceiverSoftware/slsReceiver/slsReceiverUDPFunctions.h +++ b/slsReceiverSoftware/slsReceiver/slsReceiverUDPFunctions.h @@ -40,7 +40,7 @@ public: /** * Constructor */ - slsReceiverUDPFunctions(); + slsReceiverUDPFunctions(bool bot); /** * Destructor @@ -768,6 +768,9 @@ private: * 2 we open, close, write file, callback does not do anything */ int cbAction; + /** true if bottom half module for eiger */ + bool bottom; + public: From f2dddd88cd1973d9d8e29921153d9c7be2e3d173 Mon Sep 17 00:00:00 2001 From: Anna Bergamaschi Date: Wed, 15 Oct 2014 09:22:17 +0200 Subject: [PATCH 044/474] JUNGFRAU detector type added --- slsReceiverSoftware/includes/sls_receiver_defs.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/slsReceiverSoftware/includes/sls_receiver_defs.h b/slsReceiverSoftware/includes/sls_receiver_defs.h index 70fc6ece8..2381621c0 100755 --- a/slsReceiverSoftware/includes/sls_receiver_defs.h +++ b/slsReceiverSoftware/includes/sls_receiver_defs.h @@ -55,7 +55,9 @@ public: GOTTHARD, /**< gotthard */ PICASSO, /**< picasso */ AGIPD, /**< agipd */ - MOENCH /**< moench */ + MOENCH, /**< moench */ + JUNGFRAU, /**< jungfrau */ + JUNGFRAUCTB /**< jungfrauCTBversion */ }; From b85490b528faa7e0f1db0a1b7a3936c26c254b12 Mon Sep 17 00:00:00 2001 From: Maliakal Dhanya Date: Thu, 16 Oct 2014 14:14:20 +0200 Subject: [PATCH 045/474] the version given to esrf --- slsReceiverSoftware/gitInfo.txt | 10 +++++----- slsReceiverSoftware/includes/gitInfoReceiver.h | 10 +++++----- .../slsReceiver/slsReceiverUDPFunctions.cpp | 14 ++++++++------ 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/slsReceiverSoftware/gitInfo.txt b/slsReceiverSoftware/gitInfo.txt index 355fd1524..410c414c3 100644 --- a/slsReceiverSoftware/gitInfo.txt +++ b/slsReceiverSoftware/gitInfo.txt @@ -1,9 +1,9 @@ Path: slsDetectorsPackage/slsReceiverSoftware URL: origin git@gitorious.psi.ch:sls_det_software/sls_receiver_software.git Repository Root: origin git@gitorious.psi.ch:sls_det_software/sls_receiver_software.git -Repsitory UUID: d2553484f575ec21e35c0a782cc307f9e0115554 -Revision: 16 +Repsitory UUID: e019a6ce7d96d4ac9cb5762b7137245aedb4d5b8 +Revision: 22 Branch: master -Last Changed Author: Maliakal_Dhanya -Last Changed Rev: 16 -Last Changed Date: 2014-07-31 12:13:15 +0200 +Last Changed Author: Anna_Bergamaschi +Last Changed Rev: 22 +Last Changed Date: 2014-10-15 09:22:40 +0200 diff --git a/slsReceiverSoftware/includes/gitInfoReceiver.h b/slsReceiverSoftware/includes/gitInfoReceiver.h index 586f715b0..967f26e15 100644 --- a/slsReceiverSoftware/includes/gitInfoReceiver.h +++ b/slsReceiverSoftware/includes/gitInfoReceiver.h @@ -1,11 +1,11 @@ //#define SVNPATH "" #define SVNURL "git@gitorious.psi.ch:sls_det_software/sls_receiver_software.git" //#define SVNREPPATH "" -#define SVNREPUUID "d2553484f575ec21e35c0a782cc307f9e0115554" -//#define SVNREV 0x16 +#define SVNREPUUID "e019a6ce7d96d4ac9cb5762b7137245aedb4d5b8" +//#define SVNREV 0x22 //#define SVNKIND "" //#define SVNSCHED "" -#define SVNAUTH "Maliakal_Dhanya" -#define SVNREV 0x16 -#define SVNDATE 0x20140731 +#define SVNAUTH "Anna_Bergamaschi" +#define SVNREV 0x22 +#define SVNDATE 0x20141015 // diff --git a/slsReceiverSoftware/slsReceiver/slsReceiverUDPFunctions.cpp b/slsReceiverSoftware/slsReceiver/slsReceiverUDPFunctions.cpp index aa9458377..4be1529b4 100644 --- a/slsReceiverSoftware/slsReceiver/slsReceiverUDPFunctions.cpp +++ b/slsReceiverSoftware/slsReceiver/slsReceiverUDPFunctions.cpp @@ -1551,19 +1551,21 @@ int slsReceiverUDPFunctions::startListening(){ //#endif - - //start indices for each start of scan/acquisition - eiger does it before - if((!measurementStarted) && (rc > 0) && (!ithread)) - startFrameIndices(ithread); + if((!measurementStarted) && (rc > 0) && (!ithread)) + startFrameIndices(ithread); + //problem in receiving or end of acquisition if((rc < expected)||(rc <= 0)){ stopListening(ithread,rc,packetcount,total); continue; } - - +/* + //start indices for each start of scan/acquisition - eiger does it before + if((!measurementStarted) && (rc > 0) && (!ithread)) + startFrameIndices(ithread); +*/ //reset packetcount = (packetsPerFrame/numListeningThreads) * numJobsPerThread; From 72ba2ae90151d7315314e11dc376c66c8818c68a Mon Sep 17 00:00:00 2001 From: Anna Bergamaschi Date: Mon, 27 Oct 2014 12:01:29 +0100 Subject: [PATCH 046/474] offset added to receiver funcs --- slsReceiverSoftware/includes/sls_receiver_defs.h | 4 +++- slsReceiverSoftware/includes/sls_receiver_funcs.h | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/slsReceiverSoftware/includes/sls_receiver_defs.h b/slsReceiverSoftware/includes/sls_receiver_defs.h index 2381621c0..f21579ae9 100755 --- a/slsReceiverSoftware/includes/sls_receiver_defs.h +++ b/slsReceiverSoftware/includes/sls_receiver_defs.h @@ -87,7 +87,9 @@ public: MEASUREMENT_TIME, /**< Time of the measurement from the detector (fifo) */ PROGRESS, /**< fraction of measurement elapsed - only get! */ - MEASUREMENTS_NUMBER + MEASUREMENTS_NUMBER, + FRAMES_FROM_START, + FRAMES_FROM_START_PG }; diff --git a/slsReceiverSoftware/includes/sls_receiver_funcs.h b/slsReceiverSoftware/includes/sls_receiver_funcs.h index bb7655481..7f3842576 100644 --- a/slsReceiverSoftware/includes/sls_receiver_funcs.h +++ b/slsReceiverSoftware/includes/sls_receiver_funcs.h @@ -8,7 +8,7 @@ enum { //General functions - F_EXEC_RECEIVER_COMMAND=0, /**< command is executed */ + F_EXEC_RECEIVER_COMMAND=128, /**< command is executed */ F_EXIT_RECEIVER, /**< turn off receiver server */ F_LOCK_RECEIVER, /**< Locks/Unlocks server communication to the given client */ F_GET_LAST_RECEIVER_CLIENT_IP, /**< returns the IP of the client last connected to the receiver */ From 8a63e7e184133b0543c2c3829bef29b8840fc652 Mon Sep 17 00:00:00 2001 From: Leonardo Sala Date: Wed, 5 Nov 2014 11:43:17 +0100 Subject: [PATCH 047/474] added log printouts. Added hardcoded REST configuration --- slsReceiverSoftware/Makefile | 1 - slsReceiverSoftware/include/RestHelper.h | 15 +-- .../include/UDPRESTImplementation.h | 2 + .../src/UDPBaseImplementation.cpp | 118 ++++++++++-------- .../src/UDPRESTImplementation.cpp | 76 ++++++----- 5 files changed, 115 insertions(+), 97 deletions(-) diff --git a/slsReceiverSoftware/Makefile b/slsReceiverSoftware/Makefile index b245a634f..4f90d6107 100644 --- a/slsReceiverSoftware/Makefile +++ b/slsReceiverSoftware/Makefile @@ -1,4 +1,3 @@ - include ../Makefile.include DESTDIR ?= ../bin diff --git a/slsReceiverSoftware/include/RestHelper.h b/slsReceiverSoftware/include/RestHelper.h index 5c10d0ff9..93382a610 100644 --- a/slsReceiverSoftware/include/RestHelper.h +++ b/slsReceiverSoftware/include/RestHelper.h @@ -74,14 +74,11 @@ class RestHelper { */ //Check for http:// string - FILE_LOG(logDEBUG) << __func__ << " starting"; + FILE_LOG(logDEBUG4) << __func__ << " starting"; string proto_str = "http://"; if( size_t found = hostname.find(proto_str) != string::npos ){ - cout << hostname << endl; - char c1[hostname.size()-found-1]; - cout << c1 << endl; size_t length1 = hostname.copy(c1, hostname.size()-found-1, proto_str.size()); c1[length1]='\0'; hostname = c1; @@ -168,7 +165,7 @@ class RestHelper { string answer; int code = send_request(session, req, &answer); if(code == 0 ) { - FILE_LOG(logDEBUG) << "ANSWER " << answer; + FILE_LOG(logDEBUG4) << "REQUEST: " << " ANSWER: " << answer; json_value->loadFromString(answer); } delete uri; @@ -192,7 +189,6 @@ class RestHelper { if (path.empty()) path = "/"; HTTPRequest req(HTTPRequest::HTTP_POST, path, HTTPMessage::HTTP_1_1 ); req.setContentType("application/json\r\n"); - cout << "REQUEST BODY " << request_body << endl; req.setContentLength( request_body.length() ); int code = send_request(session, req, answer, request_body); @@ -266,9 +262,8 @@ class RestHelper { if (request_body == "") session->sendRequest( (req) ); else{ - cout << request_body << endl; - ostream &os = session->sendRequest( req ) ; - os << request_body; + ostream &os = session->sendRequest( req ) ; + os << request_body; } HTTPResponse res; @@ -276,7 +271,7 @@ class RestHelper { StreamCopier::copyToString(is, *answer); code = res.getStatus(); if (code != 200){ - cout << "HTTP ERROR " << res.getStatus() << ": " << res.getReason() << endl; + FILE_LOG(logERROR) << "HTTP ERROR " << res.getStatus() << ": " << res.getReason() ; code = -1; } else diff --git a/slsReceiverSoftware/include/UDPRESTImplementation.h b/slsReceiverSoftware/include/UDPRESTImplementation.h index 32213f50c..19dd034c2 100644 --- a/slsReceiverSoftware/include/UDPRESTImplementation.h +++ b/slsReceiverSoftware/include/UDPRESTImplementation.h @@ -50,6 +50,8 @@ class UDPRESTImplementation : protected virtual slsReceiverDefs, public UDPBaseI protected: void initialize_REST(); + int get_rest_state(RestHelper * rest, string *rest_state); + public: void configure(map config_map); diff --git a/slsReceiverSoftware/src/UDPBaseImplementation.cpp b/slsReceiverSoftware/src/UDPBaseImplementation.cpp index 58d0f2395..42296fda4 100644 --- a/slsReceiverSoftware/src/UDPBaseImplementation.cpp +++ b/slsReceiverSoftware/src/UDPBaseImplementation.cpp @@ -147,17 +147,17 @@ int UDPBaseImplementation::setDetectorType(detectorType det){ /*Frame indices and numbers caught*/ -bool UDPBaseImplementation::getAcquistionStarted(){return acqStarted;}; +bool UDPBaseImplementation::getAcquistionStarted(){ FILE_LOG(logDEBUG) << __AT__ << " starting";return acqStarted;}; -bool UDPBaseImplementation::getMeasurementStarted(){return measurementStarted;}; +bool UDPBaseImplementation::getMeasurementStarted(){ FILE_LOG(logDEBUG) << __AT__ << " starting";return measurementStarted;}; -int UDPBaseImplementation::getFramesCaught(){return (packetsCaught/packetsPerFrame);} +int UDPBaseImplementation::getFramesCaught(){ FILE_LOG(logDEBUG) << __AT__ << " starting";return (packetsCaught/packetsPerFrame);} -int UDPBaseImplementation::getTotalFramesCaught(){return (totalPacketsCaught/packetsPerFrame);} +int UDPBaseImplementation::getTotalFramesCaught(){ FILE_LOG(logDEBUG) << __AT__ << " starting";return (totalPacketsCaught/packetsPerFrame);} -uint32_t UDPBaseImplementation::getStartFrameIndex(){return startFrameIndex;} +uint32_t UDPBaseImplementation::getStartFrameIndex(){ FILE_LOG(logDEBUG) << __AT__ << " starting";return startFrameIndex;} -uint32_t UDPBaseImplementation::getFrameIndex(){ +uint32_t UDPBaseImplementation::getFrameIndex(){ FILE_LOG(logDEBUG) << __AT__ << " starting"; if(!packetsCaught) frameIndex=-1; else @@ -166,7 +166,7 @@ uint32_t UDPBaseImplementation::getFrameIndex(){ } -uint32_t UDPBaseImplementation::getAcquisitionIndex(){ +uint32_t UDPBaseImplementation::getAcquisitionIndex(){ FILE_LOG(logDEBUG) << __AT__ << " starting"; if(!totalPacketsCaught) acquisitionIndex=-1; else @@ -175,7 +175,7 @@ uint32_t UDPBaseImplementation::getAcquisitionIndex(){ } -void UDPBaseImplementation::resetTotalFramesCaught(){ +void UDPBaseImplementation::resetTotalFramesCaught(){ FILE_LOG(logDEBUG) << __AT__ << " starting"; acqStarted = false; startAcquisitionIndex = 0; totalPacketsCaught = 0; @@ -185,10 +185,12 @@ void UDPBaseImplementation::resetTotalFramesCaught(){ /*file parameters*/ char* UDPBaseImplementation::getFilePath() const{ + FILE_LOG(logDEBUG) << __FILE__ << "::" << __func__ << " starting"; + return (char*)filePath; } -inline char* UDPBaseImplementation::setFilePath(const char c[]){ +inline char* UDPBaseImplementation::setFilePath(const char c[]){ FILE_LOG(logDEBUG) << __AT__ << " starting"; FILE_LOG(logDEBUG) << __AT__ << "called"; if(strlen(c)){ //check if filepath exists @@ -207,10 +209,12 @@ inline char* UDPBaseImplementation::setFilePath(const char c[]){ char* UDPBaseImplementation::getFileName() const{ + FILE_LOG(logDEBUG) << __FILE__ << "::" << __func__ << " starting"; + return (char*)fileName; } -inline char* UDPBaseImplementation::setFileName(const char c[]){ +inline char* UDPBaseImplementation::setFileName(const char c[]){ FILE_LOG(logDEBUG) << __AT__ << " starting"; //cout << "[WARNING] This is a base implementation, " << __func__ << " could have no effects." << endl; if(strlen(c)) @@ -220,11 +224,11 @@ inline char* UDPBaseImplementation::setFileName(const char c[]){ } -int UDPBaseImplementation::getFileIndex(){ +int UDPBaseImplementation::getFileIndex(){ FILE_LOG(logDEBUG) << __AT__ << " starting"; return fileIndex; } -int UDPBaseImplementation::setFileIndex(int i){ +int UDPBaseImplementation::setFileIndex(int i){ FILE_LOG(logDEBUG) << __AT__ << " starting"; //cout << "[WARNING] This is a base implementation, " << __func__ << " could have no effects." << endl; if(i>=0) fileIndex = i; @@ -232,7 +236,7 @@ int UDPBaseImplementation::setFileIndex(int i){ } -int UDPBaseImplementation::setFrameIndexNeeded(int i){ +int UDPBaseImplementation::setFrameIndexNeeded(int i){ FILE_LOG(logDEBUG) << __AT__ << " starting"; //cout << "[WARNING] This is a base implementation, " << __func__ << " could have no effects." << endl; frameIndexNeeded = i; return frameIndexNeeded; @@ -240,19 +244,23 @@ int UDPBaseImplementation::setFrameIndexNeeded(int i){ int UDPBaseImplementation::getEnableFileWrite() const{ - return enableFileWrite; + FILE_LOG(logDEBUG) << __FILE__ << "::" << __func__ << " starting"; + +return enableFileWrite; } -int UDPBaseImplementation::setEnableFileWrite(int i){ +int UDPBaseImplementation::setEnableFileWrite(int i){ FILE_LOG(logDEBUG) << __AT__ << " starting"; enableFileWrite=i; return getEnableFileWrite(); } int UDPBaseImplementation::getEnableOverwrite() const{ + FILE_LOG(logDEBUG) << __FILE__ << "::" << __func__ << " starting"; + return overwrite; } -int UDPBaseImplementation::setEnableOverwrite(int i){ +int UDPBaseImplementation::setEnableOverwrite(int i){ FILE_LOG(logDEBUG) << __AT__ << " starting"; overwrite=i; return getEnableOverwrite(); } @@ -268,7 +276,7 @@ slsReceiverDefs::runStatus UDPBaseImplementation::getStatus() const{ } -void UDPBaseImplementation::initialize(const char *detectorHostName){ +void UDPBaseImplementation::initialize(const char *detectorHostName){ FILE_LOG(logDEBUG) << __AT__ << " starting"; if(strlen(detectorHostName)) strcpy(detHostname,detectorHostName); } @@ -278,12 +286,12 @@ char *UDPBaseImplementation::getDetectorHostname() const{ return (char*)detHostname; } -void UDPBaseImplementation::setEthernetInterface(char* c){ +void UDPBaseImplementation::setEthernetInterface(char* c){ FILE_LOG(logDEBUG) << __AT__ << " starting"; strcpy(eth,c); } -void UDPBaseImplementation::setUDPPortNo(int p){ +void UDPBaseImplementation::setUDPPortNo(int p){ FILE_LOG(logDEBUG) << __AT__ << " starting"; for(int i=0;i= 0) numberOfFrames = fnum; @@ -308,7 +316,7 @@ int UDPBaseImplementation::getScanTag() const{ } -int32_t UDPBaseImplementation::setScanTag(int32_t stag){ +int32_t UDPBaseImplementation::setScanTag(int32_t stag){ FILE_LOG(logDEBUG) << __AT__ << " starting"; if(stag >= 0) scanTag = stag; @@ -320,7 +328,7 @@ int UDPBaseImplementation::getDynamicRange() const{ return dynamicRange; } -int32_t UDPBaseImplementation::setDynamicRange(int32_t dr){ +int32_t UDPBaseImplementation::setDynamicRange(int32_t dr){ FILE_LOG(logDEBUG) << __AT__ << " starting"; cout << "Setting Dynamic Range" << endl; int olddr = dynamicRange; @@ -380,7 +388,7 @@ int32_t UDPBaseImplementation::setDynamicRange(int32_t dr){ -int UDPBaseImplementation::setShortFrame(int i){ +int UDPBaseImplementation::setShortFrame(int i){ FILE_LOG(logDEBUG) << __AT__ << " starting"; shortFrame=i; if(shortFrame!=-1){ @@ -410,7 +418,7 @@ int UDPBaseImplementation::setShortFrame(int i){ } -int UDPBaseImplementation::setNFrameToGui(int i){ +int UDPBaseImplementation::setNFrameToGui(int i){ FILE_LOG(logDEBUG) << __AT__ << " starting"; if(i>=0){ nFrameToGui = i; setupFifoStructure(); @@ -420,7 +428,7 @@ int UDPBaseImplementation::setNFrameToGui(int i){ -int64_t UDPBaseImplementation::setAcquisitionPeriod(int64_t index){ +int64_t UDPBaseImplementation::setAcquisitionPeriod(int64_t index){ FILE_LOG(logDEBUG) << __AT__ << " starting"; if(index >= 0){ if(index != acquisitionPeriod){ @@ -432,9 +440,9 @@ int64_t UDPBaseImplementation::setAcquisitionPeriod(int64_t index){ } -bool UDPBaseImplementation::getDataCompression(){return dataCompression;} +bool UDPBaseImplementation::getDataCompression(){ FILE_LOG(logDEBUG) << __AT__ << " starting";return dataCompression;} -int UDPBaseImplementation::enableDataCompression(bool enable){ +int UDPBaseImplementation::enableDataCompression(bool enable){ FILE_LOG(logDEBUG) << __AT__ << " starting"; cout << "Data compression "; if(enable) cout << "enabled" << endl; @@ -487,7 +495,7 @@ int UDPBaseImplementation::enableDataCompression(bool enable){ /*other functions*/ -void UDPBaseImplementation::deleteFilter(){ +void UDPBaseImplementation::deleteFilter(){ FILE_LOG(logDEBUG) << __AT__ << " starting"; int i; cmSub=NULL; @@ -504,7 +512,7 @@ void UDPBaseImplementation::deleteFilter(){ } -void UDPBaseImplementation::setupFilter(){ +void UDPBaseImplementation::setupFilter(){ FILE_LOG(logDEBUG) << __AT__ << " starting"; double hc = 0; double sigma = 5; int sign = 1; @@ -540,7 +548,7 @@ void UDPBaseImplementation::setupFilter(){ //LEO: it is not clear to me.. -void UDPBaseImplementation::setupFifoStructure(){ +void UDPBaseImplementation::setupFifoStructure(){ FILE_LOG(logDEBUG) << __AT__ << " starting"; int64_t i; int oldn = numJobsPerThread; @@ -629,7 +637,7 @@ void UDPBaseImplementation::setupFifoStructure(){ /** acquisition functions */ -void UDPBaseImplementation::readFrame(char* c,char** raw, uint32_t &fnum){ +void UDPBaseImplementation::readFrame(char* c,char** raw, uint32_t &fnum){ FILE_LOG(logDEBUG) << __AT__ << " starting"; //point to gui data if (guiData == NULL) guiData = latestData; @@ -663,7 +671,7 @@ void UDPBaseImplementation::readFrame(char* c,char** raw, uint32_t &fnum){ -void UDPBaseImplementation::copyFrameToGui(char* startbuf[], uint32_t fnum, char* buf){ +void UDPBaseImplementation::copyFrameToGui(char* startbuf[], uint32_t fnum, char* buf){ FILE_LOG(logDEBUG) << __AT__ << " starting"; //random read when gui not ready if((!nFrameToGui) && (!guiData)){ @@ -718,9 +726,7 @@ void UDPBaseImplementation::copyFrameToGui(char* startbuf[], uint32_t fnum, char -int UDPBaseImplementation::createUDPSockets(){ - FILE_LOG(logDEBUG) << __FILE__ << "::" << __func__ << " starting"; - +int UDPBaseImplementation::createUDPSockets(){ FILE_LOG(logDEBUG) << __AT__ << " starting"; //if eth is mistaken with ip address if (strchr(eth,'.')!=NULL) @@ -764,7 +770,7 @@ int UDPBaseImplementation::createUDPSockets(){ -int UDPBaseImplementation::shutDownUDPSockets(){ +int UDPBaseImplementation::shutDownUDPSockets(){ FILE_LOG(logDEBUG) << __AT__ << " starting"; for(int i=0;iShutDownSocket(); @@ -779,7 +785,7 @@ int UDPBaseImplementation::shutDownUDPSockets(){ -int UDPBaseImplementation::createListeningThreads(bool destroy){ +int UDPBaseImplementation::createListeningThreads(bool destroy){ FILE_LOG(logDEBUG) << __AT__ << " starting"; int i; void* status; @@ -834,7 +840,7 @@ int UDPBaseImplementation::createListeningThreads(bool destroy){ -int UDPBaseImplementation::createWriterThreads(bool destroy){ +int UDPBaseImplementation::createWriterThreads(bool destroy){ FILE_LOG(logDEBUG) << __AT__ << " starting"; int i; void* status; @@ -895,7 +901,7 @@ int UDPBaseImplementation::createWriterThreads(bool destroy){ -void UDPBaseImplementation::setThreadPriorities(){ +void UDPBaseImplementation::setThreadPriorities(){ FILE_LOG(logDEBUG) << __AT__ << " starting"; int i; //assign priorities struct sched_param tcp_param, listen_param, write_param; @@ -932,7 +938,7 @@ void UDPBaseImplementation::setThreadPriorities(){ -int UDPBaseImplementation::setupWriter(){ +int UDPBaseImplementation::setupWriter(){ FILE_LOG(logDEBUG) << __AT__ << " starting"; //reset writing thread variables packetsInFile=0; @@ -1017,7 +1023,7 @@ int UDPBaseImplementation::setupWriter(){ -int UDPBaseImplementation::createCompressionFile(int ithr, int iframe){ +int UDPBaseImplementation::createCompressionFile(int ithr, int iframe){ FILE_LOG(logDEBUG) << __AT__ << " starting"; #ifdef MYROOT1 char temp[MAX_STR_LENGTH]; //create file name for gui purposes, and set up acquistion parameters @@ -1045,7 +1051,7 @@ int UDPBaseImplementation::createCompressionFile(int ithr, int iframe){ -int UDPBaseImplementation::createNewFile(){ +int UDPBaseImplementation::createNewFile(){ FILE_LOG(logDEBUG) << __AT__ << " starting"; cout << "[WARNING] This is a base implementation, " << __func__ << " not correctly implemented" << endl; @@ -1168,7 +1174,7 @@ void UDPBaseImplementation::closeFile(int ithr) -int UDPBaseImplementation::startReceiver(char message[]){ +int UDPBaseImplementation::startReceiver(char message[]){ FILE_LOG(logDEBUG) << __AT__ << " starting"; int i; @@ -1236,7 +1242,7 @@ int UDPBaseImplementation::startReceiver(char message[]){ -int UDPBaseImplementation::stopReceiver(){ +int UDPBaseImplementation::stopReceiver(){ FILE_LOG(logDEBUG) << __AT__ << " starting"; //#ifdef VERBOSE @@ -1266,7 +1272,7 @@ int UDPBaseImplementation::stopReceiver(){ -void UDPBaseImplementation::startReadout(){ +void UDPBaseImplementation::startReadout(){ FILE_LOG(logDEBUG) << __AT__ << " starting"; //#ifdef VERBOSE cout << "Start Receiver Readout" << endl; @@ -1289,7 +1295,7 @@ void UDPBaseImplementation::startReadout(){ -void* UDPBaseImplementation::startListeningThread(void* this_pointer){ +void* UDPBaseImplementation::startListeningThread(void* this_pointer){ FILE_LOG(logDEBUG) << __AT__ << " starting"; ((UDPBaseImplementation*)this_pointer)->startListening(); return this_pointer; @@ -1297,7 +1303,7 @@ void* UDPBaseImplementation::startListeningThread(void* this_pointer){ -void* UDPBaseImplementation::startWritingThread(void* this_pointer){ +void* UDPBaseImplementation::startWritingThread(void* this_pointer){ FILE_LOG(logDEBUG) << __AT__ << " starting"; ((UDPBaseImplementation*)this_pointer)->startWriting(); return this_pointer; } @@ -1307,7 +1313,7 @@ void* UDPBaseImplementation::startWritingThread(void* this_pointer){ -int UDPBaseImplementation::startListening(){ +int UDPBaseImplementation::startListening(){ FILE_LOG(logDEBUG) << __AT__ << " starting"; int ithread = currentListeningThreadIndex; #ifdef VERYVERBOSE cout << "In startListening() " << endl; @@ -1508,7 +1514,7 @@ int UDPBaseImplementation::startListening(){ -int UDPBaseImplementation::startWriting(){ +int UDPBaseImplementation::startWriting(){ FILE_LOG(logDEBUG) << __AT__ << " starting"; int ithread = currentWriterThreadIndex; #ifdef VERYVERBOSE cout << ithread << "In startWriting()" < config_map){ }; +int UDPRESTImplementation::get_rest_state(RestHelper * rest, string *rest_state){ + + JsonBox::Value answer; + //string rest_state = ""; + int code = rest->get_json("state", &answer); + if ( code != -1 ){ + (*rest_state) = answer["state"].getString(); + } + + return code; +}; void UDPRESTImplementation::initialize_REST(){ FILE_LOG(logDEBUG) << __AT__ << " called"; @@ -91,7 +102,7 @@ void UDPRESTImplementation::initialize_REST(){ int code; try{ rest->init(rest_hostname, rest_port); - code = rest->get_json("state", &answer); + code = get_rest_state(rest, &answer); if (code != 0){ throw answer; @@ -115,7 +126,7 @@ void UDPRESTImplementation::initialize_REST(){ stringstream ss; string test; - std::cout << "GetSTring: " << json_request << std::endl; + //std::cout << "GetSTring: " << json_request << std::endl; json_request.writeToStream(ss, false); //ss << json_request; ss >> test; @@ -125,7 +136,7 @@ void UDPRESTImplementation::initialize_REST(){ code = rest->post_json("state/initialize", &answer, test); FILE_LOG(logDEBUG) << __AT__ << "state/configure got " << code; code = rest->get_json("state", &answer); - FILE_LOG(logDEBUG) << __AT__ << "state got " << code << " " << answer; + FILE_LOG(logDEBUG) << __AT__ << "state got " << code << " " << answer << "\n"; /* @@ -692,32 +703,28 @@ int UDPRESTImplementation::shutDownUDPSockets(){ FILE_LOG(logDEBUG) << __AT__ << "called"; - std::string answer; - int code = rest->get_json("state", &answer); - std::cout << answer << std::endl; + JsonBox::Value answer; + int code; + string be_state = ""; - code = rest->post_json("state/close", &answer); - std::cout << answer << std::endl; - code = rest->post_json("state/reset", &answer); - std::cout << answer << std::endl; - - code = rest->get_json("state", &answer); - std::cout << answer << std::endl; - - status = slsReceiverDefs::RUN_FINISHED; - - - - /* - for(int i=0;iShutDownSocket(); - delete udpSocket[i]; - udpSocket[i] = NULL; + // LEO: this is probably wrong + if (be_state == "OPEN"){ + while (be_state != "TRANSIENT"){ + code = rest->get_json("state", &answer); + be_state = answer["state"].getString(); + cout << be_state << endl; + usleep(10000); } } - */ + code = rest->post_json("state/close", &answer); + std::cout <post_json("state/reset", &answer); + std::cout << code << " " << answer << std::endl; + + code = rest->get_json("state", &answer); + std::cout << code << " " << answer << std::endl; + + status = slsReceiverDefs::RUN_FINISHED; FILE_LOG(logDEBUG) << __AT__ << "finished"; @@ -1131,17 +1138,14 @@ int UDPRESTImplementation::startReceiver(char message[]){ std::string answer; int code; - - //test = "{\"configfile\":\"config.pu\", \"path\":\"patto\"}"; - code = rest->post_json("state/configure", &answer); - std::cout << answer << std::endl; + // TODO: remove hardcode!!! + std::string request_body = "{\"settings\": {\"bit_depth\": 16, \"nimages\": 1}}"; //"{\"nimages\":\"1\", \"bit_depth\":\"16\"}"; + FILE_LOG(logDEBUG) << __FILE__ << "::" << " sending this configuration body: " << request_body; + code = rest->post_json("state/configure", &answer, request_body); code = rest->get_json("state", &answer); - std::cout << answer << std::endl; code = rest->post_json("state/open", &answer); - std::cout << answer << std::endl; code = rest->get_json("state", &answer); - std::cout << answer << std::endl; status = slsReceiverDefs::RUNNING; @@ -1234,17 +1238,21 @@ int UDPRESTImplementation::stopReceiver(){ void UDPRESTImplementation::startReadout(){ - FILE_LOG(logDEBUG) << __FILE__ << "::" << __func__ << " starting"; + FILE_LOG(logDEBUG) << __AT__ << " starting"; //wait so that all packets which take time has arrived usleep(50000); + status = TRANSMITTING; + /********************************************/ + /* usleep(2000000); pthread_mutex_lock(&status_mutex); status = TRANSMITTING; pthread_mutex_unlock(&status_mutex); cout << "Status: Transmitting" << endl; + */ //kill udp socket to tell the listening thread to push last packet shutDownUDPSockets(); From 9ec5541b582332d11be2d4f3fc9e969530f1a80d Mon Sep 17 00:00:00 2001 From: Leonardo Sala Date: Fri, 7 Nov 2014 14:42:56 +0100 Subject: [PATCH 048/474] removed hardcoded DR and nframes --- slsReceiverSoftware/src/UDPRESTImplementation.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/slsReceiverSoftware/src/UDPRESTImplementation.cpp b/slsReceiverSoftware/src/UDPRESTImplementation.cpp index 42118de14..dcb57a3e9 100644 --- a/slsReceiverSoftware/src/UDPRESTImplementation.cpp +++ b/slsReceiverSoftware/src/UDPRESTImplementation.cpp @@ -1137,9 +1137,17 @@ int UDPRESTImplementation::startReceiver(char message[]){ std::string answer; int code; - + //char *intStr = itoa(a); + //string str = string(intStr); // TODO: remove hardcode!!! - std::string request_body = "{\"settings\": {\"bit_depth\": 16, \"nimages\": 1}}"; //"{\"nimages\":\"1\", \"bit_depth\":\"16\"}"; + stringstream ss; + ss << getDynamicRange(); + string str_dr = ss.str(); + ss << getNumberOfFrames(); + string str_n = ss.str(); + + std::string request_body = "{\"settings\": {\"bit_depth\": " + str_dr + ", \"nimages\": " + str_n + "}}"; + //"{\"nimages\":\"1\", \"bit_depth\":\"16\"}"; FILE_LOG(logDEBUG) << __FILE__ << "::" << " sending this configuration body: " << request_body; code = rest->post_json("state/configure", &answer, request_body); code = rest->get_json("state", &answer); From 3a07f0d785a2091b8bd8f96a9a4bbb5c5cdd547e Mon Sep 17 00:00:00 2001 From: Leonardo Sala Date: Fri, 7 Nov 2014 15:49:01 +0100 Subject: [PATCH 049/474] fixed dr bug --- .../include/UDPRESTImplementation.h | 2 +- .../src/UDPRESTImplementation.cpp | 26 ++++++++++++------- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/slsReceiverSoftware/include/UDPRESTImplementation.h b/slsReceiverSoftware/include/UDPRESTImplementation.h index 19dd034c2..6ee2be4b9 100644 --- a/slsReceiverSoftware/include/UDPRESTImplementation.h +++ b/slsReceiverSoftware/include/UDPRESTImplementation.h @@ -592,7 +592,7 @@ private: int32_t numberOfFrames; /** dynamic range */ - int dynamicRange; + //int dynamicRange; /** short frames */ int shortFrame; diff --git a/slsReceiverSoftware/src/UDPRESTImplementation.cpp b/slsReceiverSoftware/src/UDPRESTImplementation.cpp index dcb57a3e9..291e021f8 100644 --- a/slsReceiverSoftware/src/UDPRESTImplementation.cpp +++ b/slsReceiverSoftware/src/UDPRESTImplementation.cpp @@ -344,7 +344,13 @@ int32_t UDPRESTImplementation::setDynamicRange(int32_t dr){ } +/* +int32_t UDPRESTImplementation::getDynamicRange() const{ + FILE_LOG(logDEBUG) << __FILE__ << "::" << __func__ << " starting"; + return dynamicRange; +} +*/ int UDPRESTImplementation::setShortFrame(int i){ FILE_LOG(logDEBUG) << __AT__ << " called"; @@ -708,14 +714,15 @@ int UDPRESTImplementation::shutDownUDPSockets(){ string be_state = ""; // LEO: this is probably wrong - if (be_state == "OPEN"){ + cout << "AAAAAAAAAAAAA " << be_state << " " << status << endl; + //if (be_state == "OPEN"){ while (be_state != "TRANSIENT"){ - code = rest->get_json("state", &answer); - be_state = answer["state"].getString(); - cout << be_state << endl; - usleep(10000); + code = rest->get_json("state", &answer); + be_state = answer["state"].getString(); + cout << "be_State: " << be_state << endl; + usleep(10000); } - } + //} code = rest->post_json("state/close", &answer); std::cout <post_json("state/reset", &answer); @@ -1143,11 +1150,12 @@ int UDPRESTImplementation::startReceiver(char message[]){ stringstream ss; ss << getDynamicRange(); string str_dr = ss.str(); - ss << getNumberOfFrames(); - string str_n = ss.str(); + stringstream ss2; + ss2 << getNumberOfFrames(); + string str_n = ss2.str(); std::string request_body = "{\"settings\": {\"bit_depth\": " + str_dr + ", \"nimages\": " + str_n + "}}"; - //"{\"nimages\":\"1\", \"bit_depth\":\"16\"}"; + //std::string request_body = "{\"settings\": {\"nimages\":1, \"scanid\":999, \"bit_depth\":16}}"; FILE_LOG(logDEBUG) << __FILE__ << "::" << " sending this configuration body: " << request_body; code = rest->post_json("state/configure", &answer, request_body); code = rest->get_json("state", &answer); From eb0ca1c9446ae12595f704aff154e3cc1ea08dce Mon Sep 17 00:00:00 2001 From: Leonardo Sala Date: Fri, 7 Nov 2014 16:02:24 +0100 Subject: [PATCH 050/474] commented overloaded data members --- .../include/UDPRESTImplementation.h | 152 +++++++++--------- 1 file changed, 76 insertions(+), 76 deletions(-) diff --git a/slsReceiverSoftware/include/UDPRESTImplementation.h b/slsReceiverSoftware/include/UDPRESTImplementation.h index 6ee2be4b9..7cfe2b23d 100644 --- a/slsReceiverSoftware/include/UDPRESTImplementation.h +++ b/slsReceiverSoftware/include/UDPRESTImplementation.h @@ -502,233 +502,233 @@ private: const static int MAX_NUM_WRITER_THREADS = 15; /** detector type */ - detectorType myDetectorType; + //detectorType myDetectorType; /** detector hostname */ - char detHostname[MAX_STR_LENGTH]; + //char detHostname[MAX_STR_LENGTH]; /** status of receiver */ - runStatus status; + //runStatus status; /** UDP Socket between Receiver and Detector */ - genericSocket* udpSocket[MAX_NUM_LISTENING_THREADS]; + //genericSocket* udpSocket[MAX_NUM_LISTENING_THREADS]; /** Server UDP Port*/ - int server_port[MAX_NUM_LISTENING_THREADS]; + //int server_port[MAX_NUM_LISTENING_THREADS]; /** ethernet interface or IP to listen to */ - char *eth; + //char *eth; /** max packets per file **/ - int maxPacketsPerFile; + //int maxPacketsPerFile; /** File write enable */ - int enableFileWrite; + //int enableFileWrite; /** File over write enable */ - int overwrite; + //int overwrite; /** Complete File name */ - char savefilename[MAX_STR_LENGTH]; + //char savefilename[MAX_STR_LENGTH]; /** File Name without frame index, file index and extension*/ - char fileName[MAX_STR_LENGTH]; + //char fileName[MAX_STR_LENGTH]; /** File Path */ - char filePath[MAX_STR_LENGTH]; + //char filePath[MAX_STR_LENGTH]; /** File Index */ - int fileIndex; + //int fileIndex; /** scan tag */ - int scanTag; + //int scanTag; /** if frame index required in file name */ - int frameIndexNeeded; + //int frameIndexNeeded; /* Acquisition started */ - bool acqStarted; + //bool acqStarted; /* Measurement started */ - bool measurementStarted; + //bool measurementStarted; /** Frame index at start of each real time acquisition (eg. for each scan) */ - uint32_t startFrameIndex; + //uint32_t startFrameIndex; /** Actual current frame index of each time acquisition (eg. for each scan) */ - uint32_t frameIndex; + //uint32_t frameIndex; /** Frames Caught for each real time acquisition (eg. for each scan) */ - int packetsCaught; + //int packetsCaught; /** Total packets caught for an entire acquisition (including all scans) */ - int totalPacketsCaught; + //int totalPacketsCaught; /** Pckets currently in current file, starts new file when it reaches max */ - int packetsInFile; + //int packetsInFile; /** Frame index at start of an entire acquisition (including all scans) */ - uint32_t startAcquisitionIndex; + //uint32_t startAcquisitionIndex; /** Actual current frame index of an entire acquisition (including all scans) */ - uint32_t acquisitionIndex; + //uint32_t acquisitionIndex; /** number of packets per frame*/ - int packetsPerFrame; + //int packetsPerFrame; /** frame index mask */ - uint32_t frameIndexMask; + //uint32_t frameIndexMask; /** packet index mask */ - uint32_t packetIndexMask; + //uint32_t packetIndexMask; /** frame index offset */ - int frameIndexOffset; + //int frameIndexOffset; /** acquisition period */ - int64_t acquisitionPeriod; + //int64_t acquisitionPeriod; /** frame number */ - int32_t numberOfFrames; + //int32_t numberOfFrames; /** dynamic range */ //int dynamicRange; /** short frames */ - int shortFrame; + //int shortFrame; /** current frame number */ - uint32_t currframenum; + //uint32_t currframenum; /** Previous Frame number from buffer */ - uint32_t prevframenum; + //uint32_t prevframenum; /** size of one frame */ - int frameSize; + //int frameSize; /** buffer size. different from framesize as we wait for one packet instead of frame for eiger */ - int bufferSize; + //int bufferSize; /** oen buffer size */ - int onePacketSize; + //int onePacketSize; /** latest data */ - char* latestData; + //char* latestData; /** gui data ready */ - int guiDataReady; + //int guiDataReady; /** points to the data to send to gui */ - char* guiData; + //char* guiData; /** points to the filename to send to gui */ - char* guiFileName; + //char* guiFileName; /** temporary number for eiger frame number as its not included in the packet */ - uint32_t guiFrameNumber; + //uint32_t guiFrameNumber; /** send every nth frame to gui or only upon gui request*/ - int nFrameToGui; + //int nFrameToGui; /** fifo size */ - unsigned int fifosize; + //unsigned int fifosize; /** number of jobs per thread for data compression */ - int numJobsPerThread; + //int numJobsPerThread; /** datacompression - save only hits */ - bool dataCompression; + //bool dataCompression; /** memory allocated for the buffer */ - char *mem0[MAX_NUM_LISTENING_THREADS]; + //char *mem0[MAX_NUM_LISTENING_THREADS]; /** circular fifo to store addresses of data read */ - CircularFifo* fifo[MAX_NUM_LISTENING_THREADS]; + //CircularFifo* fifo[MAX_NUM_LISTENING_THREADS]; /** circular fifo to store addresses of data already written and ready to be resued*/ - CircularFifo* fifoFree[MAX_NUM_LISTENING_THREADS]; + //CircularFifo* fifoFree[MAX_NUM_LISTENING_THREADS]; /** Receiver buffer */ - char *buffer[MAX_NUM_LISTENING_THREADS]; + //char *buffer[MAX_NUM_LISTENING_THREADS]; /** number of writer threads */ - int numListeningThreads; + //intt numListeningThreads; /** number of writer threads */ - int numWriterThreads; + //int numWriterThreads; /** to know if listening and writer threads created properly */ - int thread_started; + //int thread_started; /** current listening thread index*/ - int currentListeningThreadIndex; + //int currentListeningThreadIndex; /** current writer thread index*/ - int currentWriterThreadIndex; + //int currentWriterThreadIndex; /** thread listening to packets */ - pthread_t listening_thread[MAX_NUM_LISTENING_THREADS]; + //pthread_t listening_thread[MAX_NUM_LISTENING_THREADS]; /** thread writing packets */ - pthread_t writing_thread[MAX_NUM_WRITER_THREADS]; + //pthread_t writing_thread[MAX_NUM_WRITER_THREADS]; /** total frame count the listening thread has listened to */ - int totalListeningFrameCount[MAX_NUM_LISTENING_THREADS]; + //int totalListeningFrameCount[MAX_NUM_LISTENING_THREADS]; /** mask showing which listening threads are running */ - volatile uint32_t listeningthreads_mask; + //volatile uint32_t listeningthreads_mask; /** mask showing which writer threads are running */ - volatile uint32_t writerthreads_mask; + //volatile uint32_t writerthreads_mask; /** mask showing which threads have created files*/ - volatile uint32_t createfile_mask; + //volatile uint32_t createfile_mask; /** OK if file created was successful */ - int ret_createfile; + //int ret_createfile; /** variable used to self terminate threads waiting for semaphores */ - int killAllListeningThreads; + //int killAllListeningThreads; /** variable used to self terminate threads waiting for semaphores */ - int killAllWritingThreads; + //int killAllWritingThreads; /** 10Gbe enable*/ - int tengigaEnable; + //int tengigaEnable; //semaphores /** semaphore to synchronize writer and guireader threads */ - sem_t smp; + //sem_t smp; /** semaphore to synchronize listener threads */ - sem_t listensmp[MAX_NUM_LISTENING_THREADS]; + //sem_t listensmp[MAX_NUM_LISTENING_THREADS]; /** semaphore to synchronize writer threads */ - sem_t writersmp[MAX_NUM_WRITER_THREADS]; + //sem_t writersmp[MAX_NUM_WRITER_THREADS]; //mutex /** guiDataReady mutex */ - pthread_mutex_t dataReadyMutex; + //pthread_mutex_t dataReadyMutex; /** mutex for status */ - pthread_mutex_t status_mutex; + //pthread_mutex_t status_mutex; /** mutex for progress variable currframenum */ - pthread_mutex_t progress_mutex; + //pthread_mutex_t progress_mutex; /** mutex for writing data to file */ - pthread_mutex_t write_mutex; + //pthread_mutex_t write_mutex; /** File Descriptor */ - FILE *sfilefd; + //FILE *sfilefd; //filter - singlePhotonDetector *singlePhotonDet[MAX_NUM_WRITER_THREADS]; - slsReceiverData *receiverdata[MAX_NUM_WRITER_THREADS]; - moenchCommonMode *cmSub; - bool commonModeSubtractionEnable; + //singlePhotonDetector *singlePhotonDet[MAX_NUM_WRITER_THREADS]; + //slsReceiverData *receiverdata[MAX_NUM_WRITER_THREADS]; + //moenchCommonMode *cmSub; + //bool commonModeSubtractionEnable; #ifdef MYROOT1 /** Tree where the hits are stored */ From 72bf64ff57ea94bebfd7418d926aabd357bae225 Mon Sep 17 00:00:00 2001 From: Leonardo Sala Date: Tue, 11 Nov 2014 17:01:55 +0100 Subject: [PATCH 051/474] cleaning --- .../include/slsReceiverUDPFunctions.h | 815 ------------------ 1 file changed, 815 deletions(-) delete mode 100644 slsReceiverSoftware/include/slsReceiverUDPFunctions.h diff --git a/slsReceiverSoftware/include/slsReceiverUDPFunctions.h b/slsReceiverSoftware/include/slsReceiverUDPFunctions.h deleted file mode 100644 index e9ff00590..000000000 --- a/slsReceiverSoftware/include/slsReceiverUDPFunctions.h +++ /dev/null @@ -1,815 +0,0 @@ -#ifdef SLS_RECEIVER_UDP_FUNCTIONS -#ifndef SLS_RECEIVER_UDP_FUNCTIONS_H -#define SLS_RECEIVER_UDP_FUNCTIONS_H -/********************************************//** - * @file slsReceiverUDPFunctions.h - * @short does all the functions for a receiver, set/get parameters, start/stop etc. - ***********************************************/ - - -//#include "sls_receiver_defs.h" -//#include "receiver_defs.h" -//#include "genericSocket.h" -#include "circularFifo.h" -#include "singlePhotonDetector.h" -#include "slsReceiverData.h" -#include "moenchCommonMode.h" - - -#include "UDPInterface.h" -#include "UDPBaseImplementation.h" - - -#ifdef MYROOT1 -#include -#include -#endif - - -#include -#include -#include -#include - - -/** - * @short does all the functions for a receiver, set/get parameters, start/stop etc. - */ - - -class slsReceiverUDPFunctions : private virtual slsReceiverDefs, public UDPInterface { - - public: - /** - * Constructor - */ - slsReceiverUDPFunctions(bool bot); - - /** - * Destructor - */ - virtual ~slsReceiverUDPFunctions(); - - /** - * delete and free member parameters - */ - void deleteMembers(); - - /** - * initialize member parameters - */ - void initializeMembers(); - - /** - * Set receiver type - * @param det detector type - * Returns success or FAIL - */ - int setDetectorType(detectorType det); - - - //Frame indices and numbers caught - /** - * Returns current Frame Index Caught for an entire acquisition (including all scans) - */ - uint32_t getAcquisitionIndex(); - - /** - * Returns if acquisition started - */ - bool getAcquistionStarted(); - - /** - * Returns Frames Caught for each real time acquisition (eg. for each scan) - */ - int getFramesCaught(); - - /** - * Returns Total Frames Caught for an entire acquisition (including all scans) - */ - int getTotalFramesCaught(); - - /** - * Returns the frame index at start of each real time acquisition (eg. for each scan) - */ - uint32_t getStartFrameIndex(); - - /** - * Returns current Frame Index for each real time acquisition (eg. for each scan) - */ - uint32_t getFrameIndex(); - - /** - * Returns if measurement started - */ - bool getMeasurementStarted(); - - /** - * Resets the Total Frames Caught - * This is how the receiver differentiates between entire acquisitions - * Returns 0 - */ - void resetTotalFramesCaught(); - - - - - //file parameters - /** - * Returns File Path - */ - char* getFilePath() const; - - /** - * Set File Path - * @param c file path - */ - char* setFilePath(const char c[]); - - /** - * Returns File Name - */ - char* getFileName() const; - - /** - * Set File Name (without frame index, file index and extension) - * @param c file name - */ - char* setFileName(const char c[]); - - /** - * Returns File Index - */ - int getFileIndex(); - - /** - * Set File Index - * @param i file index - */ - int setFileIndex(int i); - - /** - * Set Frame Index Needed - * @param i frame index needed - */ - int setFrameIndexNeeded(int i); - - /** - * Set enable file write - * @param i file write enable - * Returns file write enable - */ - int setEnableFileWrite(int i); - - /** - * Enable/disable overwrite - * @param i enable - * Returns enable over write - */ - int setEnableOverwrite(int i); - - /** - * Returns file write enable - * 1: YES 0: NO - */ - int getEnableFileWrite() const; - - /** - * Returns file over write enable - * 1: YES 0: NO - */ - int getEnableOverwrite() const; - -//other parameters - - /** - * abort acquisition with minimum damage: close open files, cleanup. - * does nothing if state already is 'idle' - */ - void abort() {}; - - /** - * Returns status of receiver: idle, running or error - */ - runStatus getStatus() const; - - /** - * Set detector hostname - * @param c hostname - */ - void initialize(const char *detectorHostName); - - /* Returns detector hostname - /returns hostname - * caller needs to deallocate the returned char array. - * if uninitialized, it must return NULL - */ - char *getDetectorHostname() const; - - /** - * Set Ethernet Interface or IP to listen to - */ - void setEthernetInterface(char* c); - - /** - * Set UDP Port Number - */ - void setUDPPortNo(int p); - - /** - * Set UDP Port Number2 - */ - void setUDPPortNo2(int p); - - /* - * Returns number of frames to receive - * This is the number of frames to expect to receiver from the detector. - * The data receiver will change from running to idle when it got this number of frames - */ - int getNumberOfFrames() const; - - /** - * set frame number if a positive number - */ - int32_t setNumberOfFrames(int32_t fnum); - - /** - * Returns scan tag - */ - int getScanTag() const; - - /** - * set scan tag if its is a positive number - */ - int32_t setScanTag(int32_t stag); - - /** - * Returns the number of bits per pixel - */ - int getDynamicRange() const; - - /** - * set dynamic range if its is a positive number - */ - int32_t setDynamicRange(int32_t dr); - - /** - * Set short frame - * @param i if shortframe i=1 - */ - int setShortFrame(int i); - - /** - * Set the variable to send every nth frame to gui - * or if 0,send frame only upon gui request - */ - int setNFrameToGui(int i); - - /** set acquisition period if a positive number - */ - int64_t setAcquisitionPeriod(int64_t index); - - /** get data compression, by saving only hits - */ - bool getDataCompression(); - - /** enabl data compression, by saving only hits - /returns if failed - */ - int enableDataCompression(bool enable); - - /** - * enable 10Gbe - @param enable 1 for 10Gbe or 0 for 1 Gbe, -1 to read out - \returns enable for 10Gbe - */ - int enableTenGiga(int enable = -1); - - - -//other functions - - /** - * Returns the buffer-current frame read by receiver - * @param c pointer to current file name - * @param raw address of pointer, pointing to current frame to send to gui - * @param fnum frame number for eiger as it is not in the packet - * @param fstartind is the start index of the acquisition - */ - void readFrame(char* c,char** raw, uint32_t &fnum, uint32_t &fstartind); - - /** - * Closes all files - * @param ithr thread index - */ - void closeFile(int ithr = -1); - - /** - * Starts Receiver - starts to listen for packets - * @param message is the error message if there is an error - * Returns success - */ - int startReceiver(char message[]); - - /** - * Stops Receiver - stops listening for packets - * Returns success - */ - int stopReceiver(); - - /** set status to transmitting and - * when fifo is empty later, sets status to run_finished - */ - void startReadout(); - - /** - * shuts down the udp sockets - * \returns if success or fail - */ - int shutDownUDPSockets(); - -private: - /** - * Deletes all the filter objects for single photon data - */ - void deleteFilter(); - - /** - * Constructs the filter for single photon data - */ - void setupFilter(); - - /** - * set up fifo according to the new numjobsperthread - */ - void setupFifoStructure (); - - /** - * Copy frames to gui - * uses semaphore for nth frame mode - */ - void copyFrameToGui(char* startbuf[], uint32_t fnum=-1, char* buf=NULL); - - /** - * creates udp sockets - * \returns if success or fail - */ - int createUDPSockets(); - - /** - * create listening thread - * @param destroy is true to kill all threads and start again - */ - int createListeningThreads(bool destroy = false); - - /** - * create writer threads - * @param destroy is true to kill all threads and start again - */ - int createWriterThreads(bool destroy = false); - - /** - * set thread priorities - */ - void setThreadPriorities(); - - /** - * initializes variables and creates the first file - * also does the startAcquisitionCallBack - * \returns FAIL or OK - */ - int setupWriter(); - - /** - * Creates new tree and file for compression - * @param ithr thread number - * @param iframe frame number - *\returns OK for succces or FAIL for failure - */ - int createCompressionFile(int ithr, int iframe); - - /** - * Creates new file - *\returns OK for succces or FAIL for failure - */ - int createNewFile(); - - /** - * Static function - Thread started which listens to packets. - * Called by startReceiver() - * @param this_pointer pointer to this object - */ - static void* startListeningThread(void *this_pointer); - - /** - * Static function - Thread started which writes packets to file. - * Called by startReceiver() - * @param this_pointer pointer to this object - */ - static void* startWritingThread(void *this_pointer); - - /** - * Thread started which listens to packets. - * Called by startReceiver() - * - */ - int startListening(); - - /** - * Thread started which writes packets to file. - * Called by startReceiver() - * - */ - int startWriting(); - - /** - * Writing to file without compression - * @param buf is the address of buffer popped out of fifo - * @param numpackets is the number of packets - * @param framenum current frame number - */ - void writeToFile_withoutCompression(char* buf,int numpackets, uint32_t framenum); - - /** - * Its called for the first packet of a scan or acquistion - * Sets the startframeindices and the variables to know if acquisition started - * @param ithread listening thread number - */ - void startFrameIndices(int ithread); - - /** - * This is called when udp socket is shut down - * It pops ffff instead of packet number into fifo - * to inform writers about the end of listening session - * @param ithread listening thread number - * @param rc number of bytes received - * @param pc packet count - * @param t total packets listened to - */ - void stopListening(int ithread, int rc, int &pc, int &t); - - /** - * When acquisition is over, this is called - * @param ithread listening thread number - * @param wbuffer writer buffer - */ - void stopWriting(int ithread, char* wbuffer[]); - - - /** - * data compression for each fifo output - * @param ithread listening thread number - * @param wbuffer writer buffer - * @param npackets number of packets from the fifo - * @param data pointer to the next packet start - * @param xmax max pixels in x direction - * @param ymax max pixels in y direction - * @param nf nf - */ - void handleDataCompression(int ithread, char* wbuffer[], int &npackets, char* data, int xmax, int ymax, int &nf); - - - /** structure of an eiger image header*/ - typedef struct - { - unsigned char header_before[20]; - unsigned char fnum[4]; - unsigned char header_after[24]; - } eiger_image_header; - - /** structure of an eiger image header*/ - typedef struct - { - unsigned char num1[4]; - unsigned char num2[4]; - } eiger_packet_header; - - /** max number of listening threads */ - const static int MAX_NUM_LISTENING_THREADS = EIGER_MAX_PORTS; - - /** max number of writer threads */ - const static int MAX_NUM_WRITER_THREADS = 15; - - /** detector type */ - detectorType myDetectorType; - - /** detector hostname */ - char detHostname[MAX_STR_LENGTH]; - - /** status of receiver */ - runStatus status; - - /** UDP Socket between Receiver and Detector */ - genericSocket* udpSocket[MAX_NUM_LISTENING_THREADS]; - - /** Server UDP Port*/ - int server_port[MAX_NUM_LISTENING_THREADS]; - - /** ethernet interface or IP to listen to */ - char *eth; - - /** max packets per file **/ - int maxPacketsPerFile; - - /** File write enable */ - int enableFileWrite; - - /** File over write enable */ - int overwrite; - - /** Complete File name */ - char savefilename[MAX_STR_LENGTH]; - - /** File Name without frame index, file index and extension*/ - char fileName[MAX_STR_LENGTH]; - - /** File Path */ - char filePath[MAX_STR_LENGTH]; - - /** File Index */ - int fileIndex; - - /** scan tag */ - int scanTag; - - /** if frame index required in file name */ - int frameIndexNeeded; - - /* Acquisition started */ - bool acqStarted; - - /* Measurement started */ - bool measurementStarted; - - /** Frame index at start of each real time acquisition (eg. for each scan) */ - uint32_t startFrameIndex; - - /** Actual current frame index of each time acquisition (eg. for each scan) */ - uint32_t frameIndex; - - /** Frames Caught for each real time acquisition (eg. for each scan) */ - int packetsCaught; - - /** Total packets caught for an entire acquisition (including all scans) */ - int totalPacketsCaught; - - /** Pckets currently in current file, starts new file when it reaches max */ - int packetsInFile; - - /** Frame index at start of an entire acquisition (including all scans) */ - uint32_t startAcquisitionIndex; - - /** Actual current frame index of an entire acquisition (including all scans) */ - uint32_t acquisitionIndex; - - /** number of packets per frame*/ - int packetsPerFrame; - - /** frame index mask */ - uint32_t frameIndexMask; - - /** packet index mask */ - uint32_t packetIndexMask; - - /** frame index offset */ - int frameIndexOffset; - - /** acquisition period */ - int64_t acquisitionPeriod; - - /** frame number */ - int32_t numberOfFrames; - - /** dynamic range */ - int dynamicRange; - - /** short frames */ - int shortFrame; - - /** current frame number */ - uint32_t currframenum; - - /** Previous Frame number from buffer */ - uint32_t prevframenum; - - /** size of one frame */ - int frameSize; - - /** buffer size. different from framesize as we wait for one packet instead of frame for eiger */ - int bufferSize; - - /** oen buffer size */ - int onePacketSize; - - /** latest data */ - char* latestData; - - /** gui data ready */ - int guiDataReady; - - /** points to the data to send to gui */ - char* guiData; - - /** points to the filename to send to gui */ - char* guiFileName; - - /** temporary number for eiger frame number as its not included in the packet */ - uint32_t guiFrameNumber; - - /** send every nth frame to gui or only upon gui request*/ - int nFrameToGui; - - /** fifo size */ - unsigned int fifosize; - - /** number of jobs per thread for data compression */ - int numJobsPerThread; - - /** datacompression - save only hits */ - bool dataCompression; - - /** memory allocated for the buffer */ - char *mem0[MAX_NUM_LISTENING_THREADS]; - - /** circular fifo to store addresses of data read */ - CircularFifo* fifo[MAX_NUM_LISTENING_THREADS]; - - /** circular fifo to store addresses of data already written and ready to be resued*/ - CircularFifo* fifoFree[MAX_NUM_LISTENING_THREADS]; - - /** Receiver buffer */ - char *buffer[MAX_NUM_LISTENING_THREADS]; - - /** number of writer threads */ - int numListeningThreads; - - /** number of writer threads */ - int numWriterThreads; - - /** to know if listening and writer threads created properly */ - int thread_started; - - /** current listening thread index*/ - int currentListeningThreadIndex; - - /** current writer thread index*/ - int currentWriterThreadIndex; - - /** thread listening to packets */ - pthread_t listening_thread[MAX_NUM_LISTENING_THREADS]; - - /** thread writing packets */ - pthread_t writing_thread[MAX_NUM_WRITER_THREADS]; - - /** total frame count the listening thread has listened to */ - int totalListeningFrameCount[MAX_NUM_LISTENING_THREADS]; - - /** mask showing which listening threads are running */ - volatile uint32_t listeningthreads_mask; - - /** mask showing which writer threads are running */ - volatile uint32_t writerthreads_mask; - - /** mask showing which threads have created files*/ - volatile uint32_t createfile_mask; - - /** OK if file created was successful */ - int ret_createfile; - - /** variable used to self terminate threads waiting for semaphores */ - int killAllListeningThreads; - - /** variable used to self terminate threads waiting for semaphores */ - int killAllWritingThreads; - - /** 10Gbe enable*/ - int tengigaEnable; - - - - -//semaphores - /** semaphore to synchronize writer and guireader threads */ - sem_t smp; - /** semaphore to synchronize listener threads */ - sem_t listensmp[MAX_NUM_LISTENING_THREADS]; - /** semaphore to synchronize writer threads */ - sem_t writersmp[MAX_NUM_WRITER_THREADS]; - - -//mutex - /** guiDataReady mutex */ - pthread_mutex_t dataReadyMutex; - - /** mutex for status */ - pthread_mutex_t status_mutex; - - /** mutex for progress variable currframenum */ - pthread_mutex_t progress_mutex; - - /** mutex for writing data to file */ - pthread_mutex_t write_mutex; - - /** File Descriptor */ - FILE *sfilefd; - - //filter - singlePhotonDetector *singlePhotonDet[MAX_NUM_WRITER_THREADS]; - slsReceiverData *receiverdata[MAX_NUM_WRITER_THREADS]; - moenchCommonMode *cmSub; - bool commonModeSubtractionEnable; - -#ifdef MYROOT1 - /** Tree where the hits are stored */ - TTree *myTree[MAX_NUM_WRITER_THREADS]; - - /** File where the tree is saved */ - TFile *myFile[MAX_NUM_WRITER_THREADS]; -#endif - - - - /** - callback arguments are - filepath - filename - fileindex - data size - - return value is - 0 callback takes care of open,close,write file - 1 callback writes file, we have to open, close it - 2 we open, close, write file, callback does not do anything - - */ - int (*startAcquisitionCallBack)(char*, char*,int, int, void*); - void *pStartAcquisition; - - /** - args to acquisition finished callback - total frames caught - - */ - void (*acquisitionFinishedCallBack)(int, void*); - void *pAcquisitionFinished; - - - /** - args to raw data ready callback are - framenum - datapointer - datasize in bytes - file descriptor - guidatapointer (NULL, no data required) - */ - void (*rawDataReadyCallBack)(int, char*, int, FILE*, char*, void*); - void *pRawDataReady; - - /** The action which decides what the user and default responsibilites to save data are - * 0 raw data ready callback takes care of open,close,write file - * 1 callback writes file, we have to open, close it - * 2 we open, close, write file, callback does not do anything */ - int cbAction; - - /** true if bottom half module for eiger */ - bool bottom; - - -public: - - - /** - callback arguments are - filepath - filename - fileindex - datasize - - return value is - 0 callback takes care of open,close,wrie file - 1 callback writes file, we have to open, close it - 2 we open, close, write file, callback does not do anything - */ - void registerCallBackStartAcquisition(int (*func)(char*, char*,int, int, void*),void *arg){startAcquisitionCallBack=func; pStartAcquisition=arg;}; - - /** - callback argument is - toatal frames caught - */ - void registerCallBackAcquisitionFinished(void (*func)(int, void*),void *arg){acquisitionFinishedCallBack=func; pAcquisitionFinished=arg;}; - - /** - args to raw data ready callback are - framenum - datapointer - datasize in bytes - file descriptor - guidatapointer (NULL, no data required) - */ - void registerCallBackRawDataReady(void (*func)(int, char*, int, FILE*, char*, void*),void *arg){rawDataReadyCallBack=func; pRawDataReady=arg;}; -}; - - -#endif - -#endif From 3324667d05092fe6cc88ebfde6d67cf1148d8bad Mon Sep 17 00:00:00 2001 From: Leonardo Sala Date: Wed, 12 Nov 2014 11:54:12 +0100 Subject: [PATCH 052/474] proper thread handling for the REST receiver --- slsReceiverSoftware/include/RestHelper.h | 15 +++-- slsReceiverSoftware/include/logger.h | 3 +- .../src/UDPBaseImplementation.cpp | 11 ++- .../src/UDPRESTImplementation.cpp | 67 +++++++++++++------ 4 files changed, 64 insertions(+), 32 deletions(-) diff --git a/slsReceiverSoftware/include/RestHelper.h b/slsReceiverSoftware/include/RestHelper.h index 93382a610..b3d679b26 100644 --- a/slsReceiverSoftware/include/RestHelper.h +++ b/slsReceiverSoftware/include/RestHelper.h @@ -25,6 +25,7 @@ #include #include #include +#include @@ -35,19 +36,21 @@ using namespace std; class RestHelper { public: - RestHelper(int timeout=10, int n_tries=10){ + RestHelper(int timeout=10, int n_tries=1){ /** * * * @param timeout default=10 - * @param n_tries default=3 + * @param n_tries default=1 */ http_timeout = timeout; n_connection_tries = n_tries; } - ~RestHelper(){}; + ~RestHelper(){ + delete session; + }; void set_connection_params(int timeout, int n_tries){ @@ -74,7 +77,6 @@ class RestHelper { */ //Check for http:// string - FILE_LOG(logDEBUG4) << __func__ << " starting"; string proto_str = "http://"; if( size_t found = hostname.find(proto_str) != string::npos ){ @@ -165,7 +167,7 @@ class RestHelper { string answer; int code = send_request(session, req, &answer); if(code == 0 ) { - FILE_LOG(logDEBUG4) << "REQUEST: " << " ANSWER: " << answer; + FILE_LOG(logDEBUG) << __AT__ << " REQUEST: " << " ANSWER: " << answer; json_value->loadFromString(answer); } delete uri; @@ -285,7 +287,8 @@ class RestHelper { n+=1; } - return code; + throw std::string("Cannot connect to the REST server! Please check..."); + //return code; } }; diff --git a/slsReceiverSoftware/include/logger.h b/slsReceiverSoftware/include/logger.h index 3d6d5703e..74f5c9a12 100644 --- a/slsReceiverSoftware/include/logger.h +++ b/slsReceiverSoftware/include/logger.h @@ -4,11 +4,12 @@ #include #include #include +#include #define STRINGIFY(x) #x #define TOSTRING(x) STRINGIFY(x) #define MYCONCAT(x,y) -#define __AT__ string(__FILE__) + string("::") + string(__func__) + string("(): ") +#define __AT__ string(__FILE__) + string("::") + string(__func__) + string("(): ") //":" TOSTRING(__LINE__) diff --git a/slsReceiverSoftware/src/UDPBaseImplementation.cpp b/slsReceiverSoftware/src/UDPBaseImplementation.cpp index 351255df3..de09ae694 100644 --- a/slsReceiverSoftware/src/UDPBaseImplementation.cpp +++ b/slsReceiverSoftware/src/UDPBaseImplementation.cpp @@ -53,8 +53,7 @@ void UDPBaseImplementation::initializeMembers(){ int UDPBaseImplementation::setDetectorType(detectorType det){ cout << "[WARNING] This is a base implementation, " << __func__ << " not correctly implemented" << endl; - - cout << "Setting Receiver Type " << endl; + cout << "Setting Receiver Type " << endl; deleteMembers(); initializeMembers(); @@ -76,7 +75,7 @@ int UDPBaseImplementation::setDetectorType(detectorType det){ return FAIL; break; } - + /* //moench variables if(myDetectorType == GOTTHARD){ fifosize = GOTTHARD_FIFO_SIZE; @@ -138,7 +137,7 @@ int UDPBaseImplementation::setDetectorType(detectorType det){ cout << "Ready..." << endl; return OK; - + */ return OK; } @@ -1124,7 +1123,7 @@ void UDPBaseImplementation::closeFile(int ithr) { FILE_LOG(logDEBUG) << __AT__ << "called"; - + /* if(!dataCompression){ if(sfilefd){ #ifdef VERBOSE @@ -1171,7 +1170,7 @@ void UDPBaseImplementation::closeFile(int ithr) #endif } - + */ FILE_LOG(logDEBUG) << __AT__ << "exited"; } diff --git a/slsReceiverSoftware/src/UDPRESTImplementation.cpp b/slsReceiverSoftware/src/UDPRESTImplementation.cpp index fe6696058..be929dd0d 100644 --- a/slsReceiverSoftware/src/UDPRESTImplementation.cpp +++ b/slsReceiverSoftware/src/UDPRESTImplementation.cpp @@ -36,7 +36,7 @@ using namespace std; UDPRESTImplementation::UDPRESTImplementation(){ - FILE_LOG(logDEBUG) << __AT__ << " called"; + FILE_LOG(logDEBUG) << "PID: " << getpid() << __AT__ << " called"; //TODO I do not really know what to do with bottom... // Default values @@ -718,32 +718,54 @@ int UDPRESTImplementation::shutDownUDPSockets(){ FILE_LOG(logDEBUG) << __AT__ << "called"; + // this is just to be sure, it could be removed + for(int i=0;iShutDownSocket(); + delete udpSocket[i]; + udpSocket[i] = NULL; + } + } + JsonBox::Value answer; int code; string be_state = ""; + FILE_LOG(logDEBUG) << __AT__ << " numListeningThreads=" << numListeningThreads; + if (rest == NULL){ + FILE_LOG(logWARNING) << __AT__ << "No REST object initialized, closing..."; + return OK; + } + + // getting the state + FILE_LOG(logWARNING) << "PLEASE WAIT WHILE CHECKING AND SHUTTING DOWN ALL CONNECTIONS!"; + code = rest->get_json("state", &answer); + be_state = answer["state"].getString(); + // LEO: this is probably wrong - cout << "AAAAAAAAAAAAA " << be_state << " " << status << endl; - //if (be_state == "OPEN"){ + if (be_state == "OPEN"){ while (be_state != "TRANSIENT"){ code = rest->get_json("state", &answer); be_state = answer["state"].getString(); cout << "be_State: " << be_state << endl; usleep(10000); } - //} - code = rest->post_json("state/close", &answer); - std::cout <post_json("state/reset", &answer); - std::cout << code << " " << answer << std::endl; - - code = rest->get_json("state", &answer); - std::cout << code << " " << answer << std::endl; + + code = rest->post_json("state/close", &answer); + std::cout <post_json("state/reset", &answer); + std::cout << code << " " << answer << std::endl; + code = rest->get_json("state", &answer); + std::cout << code << " " << answer << std::endl; + } status = slsReceiverDefs::RUN_FINISHED; - FILE_LOG(logDEBUG) << __AT__ << "finished"; + //LEO: not sure it's needed + delete rest; + FILE_LOG(logDEBUG) << __AT__ << "finished"; return OK; } @@ -1289,8 +1311,9 @@ void UDPRESTImplementation::startReadout(){ void* UDPRESTImplementation::startListeningThread(void* this_pointer){ FILE_LOG(logDEBUG) << __AT__ << " called"; + FILE_LOG(logDEBUG) << __AT__ << " doing a big bunch of nothing"; - ((UDPRESTImplementation*)this_pointer)->startListening(); + //((UDPRESTImplementation*)this_pointer)->startListening(); return this_pointer; } @@ -1299,7 +1322,9 @@ void* UDPRESTImplementation::startListeningThread(void* this_pointer){ void* UDPRESTImplementation::startWritingThread(void* this_pointer){ FILE_LOG(logDEBUG) << __AT__ << " called"; - ((UDPRESTImplementation*)this_pointer)->startWriting(); + FILE_LOG(logDEBUG) << __AT__ << " doing a big bunch of nothing"; + + //((UDPRESTImplementation*)this_pointer)->startWriting(); return this_pointer; } @@ -1310,7 +1335,9 @@ void* UDPRESTImplementation::startWritingThread(void* this_pointer){ int UDPRESTImplementation::startListening(){ FILE_LOG(logDEBUG) << __AT__ << " called"; + FILE_LOG(logDEBUG) << __AT__ << " doing a big bunch of nothing"; + /* int ithread = currentListeningThreadIndex; #ifdef VERYVERBOSE cout << "In startListening() " << endl; @@ -1495,7 +1522,7 @@ int UDPRESTImplementation::startListening(){ pthread_exit(NULL); } } - + */ return OK; } @@ -1513,6 +1540,8 @@ int UDPRESTImplementation::startListening(){ int UDPRESTImplementation::startWriting(){ FILE_LOG(logDEBUG) << __AT__ << " called"; + FILE_LOG(logDEBUG) << __AT__ << " doing a big bunch of nothing"; + /* int ithread = currentWriterThreadIndex; #ifdef VERYVERBOSE cout << ithread << "In startWriting()" < Date: Mon, 17 Nov 2014 17:06:50 +0100 Subject: [PATCH 053/474] fixed non-rest compilation --- slsReceiverSoftware/Makefile | 4 ++-- slsReceiverSoftware/src/UDPInterface.cpp | 7 ++++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/slsReceiverSoftware/Makefile b/slsReceiverSoftware/Makefile index 4f90d6107..c16db2438 100644 --- a/slsReceiverSoftware/Makefile +++ b/slsReceiverSoftware/Makefile @@ -45,9 +45,9 @@ intdoc: $(SRC_H) $(SRC_CLNT) $(BUILDDIR)/%.o : $(SRCDIR)/%.cpp Makefile ifeq ($(ROOTSLS),yes) - $(CXX) -DROOTSLS -o $@ -c $< $(INCLUDES) $(DFLAGS) $(ROOTFLAGS) -fPIC $(EPICSFLAGS) -L/usr/lib64/ #$(FLAGS) + $(CXX) -DROOTSLS -o $@ -c $< $(INCLUDES) $(DFLAGS) $(ROOTFLAGS) -fPIC $(EPICSFLAGS) $(LDFLAGRXR) -L/usr/lib64/ #$(FLAGS) else - $(CXX) -o $@ -c $< $(INCLUDES) $(DFLAGS) -fPIC $(EPICSFLAGS) -lpthread #$(FLAGS) + $(CXX) -o $@ -c $< $(INCLUDES) $(DFLAGS) -fPIC $(EPICSFLAGS) $(LDFLAGRXR) -lpthread #$(FLAGS) endif lib: $(OBJS) $(DESTDIR)/libSlsReceiver.so $(DESTDIR)/libSlsReceiver.a diff --git a/slsReceiverSoftware/src/UDPInterface.cpp b/slsReceiverSoftware/src/UDPInterface.cpp index 3d8ffb767..a0b3d1371 100644 --- a/slsReceiverSoftware/src/UDPInterface.cpp +++ b/slsReceiverSoftware/src/UDPInterface.cpp @@ -13,8 +13,9 @@ using namespace std; #include "UDPInterface.h" #include "UDPBaseImplementation.h" #include "UDPStandardImplementation.h" +#ifdef REST #include "UDPRESTImplementation.h" - +#endif using namespace std; @@ -26,11 +27,11 @@ UDPInterface * UDPInterface::create(string receiver_type){ cout << "Starting " << receiver_type << endl; return new UDPStandardImplementation(); } - //#ifdef REST +#ifdef REST else if (receiver_type == "REST"){ return new UDPRESTImplementation(); } - //#endif +#endif else{ FILE_LOG(logWARNING) << "[ERROR] UDP interface not supported, using standard implementation"; return new UDPBaseImplementation(); From 2eaefaba3adc33050dca46f6d42d5ca9fc92d28b Mon Sep 17 00:00:00 2001 From: Sala Leonardo Date: Tue, 18 Nov 2014 10:51:52 +0100 Subject: [PATCH 054/474] added log level control --- slsReceiverSoftware/Makefile | 4 ++-- slsReceiverSoftware/include/logger.h | 17 +++++++++++++---- slsReceiverSoftware/src/main.cpp | 4 ---- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/slsReceiverSoftware/Makefile b/slsReceiverSoftware/Makefile index c16db2438..2a6303f93 100644 --- a/slsReceiverSoftware/Makefile +++ b/slsReceiverSoftware/Makefile @@ -45,9 +45,9 @@ intdoc: $(SRC_H) $(SRC_CLNT) $(BUILDDIR)/%.o : $(SRCDIR)/%.cpp Makefile ifeq ($(ROOTSLS),yes) - $(CXX) -DROOTSLS -o $@ -c $< $(INCLUDES) $(DFLAGS) $(ROOTFLAGS) -fPIC $(EPICSFLAGS) $(LDFLAGRXR) -L/usr/lib64/ #$(FLAGS) + $(CXX) -DROOTSLS -o $@ -c $< $(INCLUDES) $(DFLAGS) $(ROOTFLAGS) -fPIC $(EPICSFLAGS) $(LDFLAGRXR) -L/usr/lib64/ $(FLAGS) else - $(CXX) -o $@ -c $< $(INCLUDES) $(DFLAGS) -fPIC $(EPICSFLAGS) $(LDFLAGRXR) -lpthread #$(FLAGS) + $(CXX) -o $@ -c $< $(INCLUDES) $(DFLAGS) -fPIC $(EPICSFLAGS) $(LDFLAGRXR) -lpthread $(FLAGS) endif lib: $(OBJS) $(DESTDIR)/libSlsReceiver.so $(DESTDIR)/libSlsReceiver.a diff --git a/slsReceiverSoftware/include/logger.h b/slsReceiverSoftware/include/logger.h index 74f5c9a12..cba284fb1 100644 --- a/slsReceiverSoftware/include/logger.h +++ b/slsReceiverSoftware/include/logger.h @@ -6,6 +6,19 @@ #include #include +#ifdef VERBOSE +#define FILELOG_MAX_LEVEL logDEBUG +#endif + +#ifdef VERYVERBOSE +#define FILELOG_MAX_LEVEL logDEBUG4 +#endif + +#ifndef FILELOG_MAX_LEVEL +#define FILELOG_MAX_LEVEL logINFO +#endif + + #define STRINGIFY(x) #x #define TOSTRING(x) STRINGIFY(x) #define MYCONCAT(x,y) @@ -60,10 +73,6 @@ public: class FILELOG_DECLSPEC FILELog : public Log {}; //typedef Log FILELog; -#ifndef FILELOG_MAX_LEVEL -#define FILELOG_MAX_LEVEL logDEBUG4 -#endif - #define FILE_LOG(level) \ if (level > FILELOG_MAX_LEVEL) ; \ else if (level > FILELog::ReportingLevel() || !Output2FILE::Stream()) ; \ diff --git a/slsReceiverSoftware/src/main.cpp b/slsReceiverSoftware/src/main.cpp index 32adb96be..c2dde5fc4 100644 --- a/slsReceiverSoftware/src/main.cpp +++ b/slsReceiverSoftware/src/main.cpp @@ -13,10 +13,6 @@ using namespace std; - - - - int main(int argc, char *argv[]) { int ret = slsReceiverDefs::OK; From 4770d74c121ae4ad68568d9c8ecdeb234fedc774 Mon Sep 17 00:00:00 2001 From: Maliakal Dhanya Date: Tue, 18 Nov 2014 17:29:12 +0100 Subject: [PATCH 055/474] return even if eiger got only 16 bytes of a packet --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 3b6f4a654..6c92bf98e 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -2019,7 +2019,7 @@ int i; exit(-1); } //push the last buffer into fifo - if(rc > 0){ + if((myDetectorType != EIGER) && (rc > 0)){ //for eiger throw away incomplete frames pc = (rc/onePacketSize); #ifdef VERYDEBUG cout << ithread << " *** last packetcount:" << pc << endl; @@ -2030,7 +2030,8 @@ int i; #ifdef VERYDEBUG cout << ithread << " *** last lbuf1:" << (void*)buffer[ithread] << endl; #endif - } + }else + fifoFree[ithread]->push(buffer[ithread]);//for all detectors too. why was this not there? for rc=0? //push dummy buffer to all writer threads From 1d5580b0d4cbdf7102100f698ba6b96b0bebf0b8 Mon Sep 17 00:00:00 2001 From: Anna Bergamaschi Date: Tue, 25 Nov 2014 11:54:54 +0100 Subject: [PATCH 056/474] JMCB max frames --- slsReceiverSoftware/include/sls_receiver_defs.h | 1 + 1 file changed, 1 insertion(+) diff --git a/slsReceiverSoftware/include/sls_receiver_defs.h b/slsReceiverSoftware/include/sls_receiver_defs.h index f21579ae9..7f39ff05d 100755 --- a/slsReceiverSoftware/include/sls_receiver_defs.h +++ b/slsReceiverSoftware/include/sls_receiver_defs.h @@ -20,6 +20,7 @@ typedef int int32_t; #define SHORT_MAX_FRAMES_PER_FILE 100000 #define MOENCH_MAX_FRAMES_PER_FILE 1000 #define EIGER_MAX_FRAMES_PER_FILE 20000 +#define JFCTB_MAX_FRAMES_PER_FILE 100000 /** From 5b2a896ed3b815162f4a54f9bd1b81f582e42064 Mon Sep 17 00:00:00 2001 From: Maliakal Dhanya Date: Fri, 28 Nov 2014 14:28:56 +0100 Subject: [PATCH 057/474] to return if it catches only 16 bytes or less than expected, but compensates for first frame being only 266240 for eiger --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 6c92bf98e..5822a11ca 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1647,6 +1647,7 @@ int UDPStandardImplementation::startListening(){ stopListening(ithread,rc,packetcount,total); continue; } + /* //start indices for each start of scan/acquisition - eiger does it before if((!measurementStarted) && (rc > 0) && (!ithread)) @@ -2004,7 +2005,7 @@ void UDPStandardImplementation::startFrameIndices(int ithread){ -void UDPStandardImplementation::stopListening(int ithread, int rc, int &pc, int &t){ +void UDPStandardImplementation::stopListening(int ithread, int rc, int &pc, int &t){cout << "Stop Listening" << endl; FILE_LOG(logDEBUG) << __AT__ << " called"; @@ -2019,7 +2020,9 @@ int i; exit(-1); } //push the last buffer into fifo - if((myDetectorType != EIGER) && (rc > 0)){ //for eiger throw away incomplete frames + if((myDetectorType == EIGER) && (rc < 266240) )//for eiger throw away incomplete frames + fifoFree[ithread]->push(buffer[ithread]); + else if(rc > 0){cout<< ithread << " last rc:"<push(buffer[ithread]);//for all detectors too. why was this not there? for rc=0? + } //push dummy buffer to all writer threads From 6787c2e1e0f9c3ced0adc8e7ce731d51cc29f195 Mon Sep 17 00:00:00 2001 From: Maliakal Dhanya Date: Mon, 1 Dec 2014 17:18:26 +0100 Subject: [PATCH 058/474] got rid of unnecessary usleep before transmitting in receiver --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 5822a11ca..0ac51c321 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1521,10 +1521,10 @@ void UDPStandardImplementation::startReadout(){ //#endif //wait so that all packets which take time has arrived - usleep(50000); + usleep(5000); /********************************************/ - usleep(2000000); + //usleep(2000000); pthread_mutex_lock(&status_mutex); status = TRANSMITTING; pthread_mutex_unlock(&status_mutex); From 52d3140a3aa19b68ea6e9560f8848090d0164f03 Mon Sep 17 00:00:00 2001 From: Maliakal Dhanya Date: Tue, 2 Dec 2014 10:12:00 +0100 Subject: [PATCH 059/474] a version of receiver for gemma with bottom --- .../include/UDPStandardImplementation.h | 2 +- .../src/UDPStandardImplementation.cpp | 20 +++++++++++++++++-- slsReceiverSoftware/src/slsReceiver.cpp | 13 +++++++++--- 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/slsReceiverSoftware/include/UDPStandardImplementation.h b/slsReceiverSoftware/include/UDPStandardImplementation.h index 6b5c0c0c4..dca52e6a4 100644 --- a/slsReceiverSoftware/include/UDPStandardImplementation.h +++ b/slsReceiverSoftware/include/UDPStandardImplementation.h @@ -47,7 +47,7 @@ class UDPStandardImplementation: private virtual slsReceiverDefs, public UDPBase */ virtual ~UDPStandardImplementation(); - + void configure(map config_map); /** * delete and free member parameters diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 0ac51c321..cb8d66c25 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -91,6 +91,22 @@ UDPStandardImplementation::UDPStandardImplementation() } +void UDPStandardImplementation::configure(map config_map){ + FILE_LOG(logWARNING) << __AT__ << " called"; + + map::const_iterator pos; + pos = config_map.find("mode"); + if (pos != config_map.end() ){ + int b; + if(!sscanf(pos->second.c_str(), "%d", &b)){ + cout << "Warning: Could not parse mode. Assuming top mode." << endl; + b = 0; + } + bottom = b!= 0; + cout << "bottom:"<< bottom << endl; + } +}; + void UDPStandardImplementation::initializeMembers(){ myDetectorType = GENERIC; maxPacketsPerFile = 0; @@ -945,12 +961,12 @@ int UDPStandardImplementation::createUDPSockets(){ port[1] = server_port[1]; /** eiger specific */ - /* + if(bottom){ port[0] = server_port[1]; port[1] = server_port[0]; } - */ + //if eth is mistaken with ip address if (strchr(eth,'.')!=NULL) strcpy(eth,""); diff --git a/slsReceiverSoftware/src/slsReceiver.cpp b/slsReceiverSoftware/src/slsReceiver.cpp index 595a39868..6ffc2fdf9 100644 --- a/slsReceiverSoftware/src/slsReceiver.cpp +++ b/slsReceiverSoftware/src/slsReceiver.cpp @@ -65,6 +65,13 @@ slsReceiver::slsReceiver(int argc, char *argv[], int &success){ switch(c){ + case 'm': + int b; + sscanf(optarg, "%d", &b); + bottom = b != 0; + configuration_map["mode"] = optarg; + break; + case 'f': fname = optarg; //cout << long_options[option_index].name << " " << optarg << endl; @@ -86,7 +93,7 @@ slsReceiver::slsReceiver(int argc, char *argv[], int &success){ string help_message = """\nSLS Receiver Server\n\n"""; help_message += """usage: slsReceiver --config config_fname [--rx_tcpport port]\n\n"""; help_message += """\t--config:\t configuration filename for SLS Detector receiver\n"""; - help_message += """\t--mode:\t ???\n"""; + help_message += """\t--mode:\t 1 for bottom and 0 for top\n"""; help_message += """\t--rx_tcpport:\t TCP Communication Port with the client. Default: 1954.\n\n"""; help_message += """\t--rest_hostname:\t Receiver hostname:port. It applies only to REST receivers, and indicates the hostname of the REST backend. Default: localhost:8081.\n\n"""; @@ -120,10 +127,10 @@ slsReceiver::slsReceiver(int argc, char *argv[], int &success){ } if (success==OK){ - FILE_LOG(logINFO) << "SLS Receiver starting " << udp_interface_type << " on port " << tcpip_port_no << endl; + FILE_LOG(logINFO) << "SLS Receiver starting " << udp_interface_type << " on port " << tcpip_port_no << " with mode " << bottom << endl; udp_interface = UDPInterface::create(udp_interface_type); udp_interface->configure(configuration_map); - tcpipInterface = new slsReceiverTCPIPInterface(success, udp_interface, tcpip_port_no); + tcpipInterface = new slsReceiverTCPIPInterface(success, udp_interface, tcpip_port_no, bottom); //tcp ip interface } } From dc4e74087dea563df969849754d820cd6bba2b9c Mon Sep 17 00:00:00 2001 From: Maliakal Dhanya Date: Mon, 8 Dec 2014 09:16:19 +0100 Subject: [PATCH 060/474] makefile crash if files dont exist in make clean, fixed --- slsReceiverSoftware/Makefile | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/slsReceiverSoftware/Makefile b/slsReceiverSoftware/Makefile index 2a6303f93..c445eaa8c 100644 --- a/slsReceiverSoftware/Makefile +++ b/slsReceiverSoftware/Makefile @@ -79,8 +79,9 @@ mysocket_test: clean: buildclean make testclean - rm $(DESTDIR)/libSlsReceiver.a $(DESTDIR)/libSlsReceiver.so - rm $(PROGS) + if test -e $(DESTDIR)/libSlsReceiver.a; then rm $(DESTDIR)/libSlsReceiver.a;fi + if test -e $(DESTDIR)/libSlsReceiver.so; then rm $(DESTDIR)/libSlsReceiver.so;fi + if test -e $(PROGS); then rm $(PROGS);fi builddir: if [ ! -d $(BUILDDIR) ]; then mkdir $(BUILDDIR); fi From f79f3cf0217417819b8e7a9293375f16da76d7a6 Mon Sep 17 00:00:00 2001 From: Maliakal Dhanya Date: Mon, 8 Dec 2014 09:17:56 +0100 Subject: [PATCH 061/474] makefile crash if files dont exist in make clean, fixed --- slsReceiverSoftware/Makefile | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/slsReceiverSoftware/Makefile b/slsReceiverSoftware/Makefile index 2a6303f93..c445eaa8c 100644 --- a/slsReceiverSoftware/Makefile +++ b/slsReceiverSoftware/Makefile @@ -79,8 +79,9 @@ mysocket_test: clean: buildclean make testclean - rm $(DESTDIR)/libSlsReceiver.a $(DESTDIR)/libSlsReceiver.so - rm $(PROGS) + if test -e $(DESTDIR)/libSlsReceiver.a; then rm $(DESTDIR)/libSlsReceiver.a;fi + if test -e $(DESTDIR)/libSlsReceiver.so; then rm $(DESTDIR)/libSlsReceiver.so;fi + if test -e $(PROGS); then rm $(PROGS);fi builddir: if [ ! -d $(BUILDDIR) ]; then mkdir $(BUILDDIR); fi From 169c0a43cef9bcf1176315f475cf6eee6d363f92 Mon Sep 17 00:00:00 2001 From: Maliakal Dhanya Date: Mon, 8 Dec 2014 10:25:42 +0100 Subject: [PATCH 062/474] updating version numbers --- slsReceiverSoftware/gitInfo.txt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/slsReceiverSoftware/gitInfo.txt b/slsReceiverSoftware/gitInfo.txt index 410c414c3..d680dad1d 100644 --- a/slsReceiverSoftware/gitInfo.txt +++ b/slsReceiverSoftware/gitInfo.txt @@ -1,9 +1,9 @@ Path: slsDetectorsPackage/slsReceiverSoftware URL: origin git@gitorious.psi.ch:sls_det_software/sls_receiver_software.git Repository Root: origin git@gitorious.psi.ch:sls_det_software/sls_receiver_software.git -Repsitory UUID: e019a6ce7d96d4ac9cb5762b7137245aedb4d5b8 -Revision: 22 -Branch: master -Last Changed Author: Anna_Bergamaschi -Last Changed Rev: 22 -Last Changed Date: 2014-10-15 09:22:40 +0200 +Repsitory UUID: 879c5e2ee129acfd70aba4ae6fab829cc5409350 +Revision: 67 +Branch: gemma +Last Changed Author: Maliakal_Dhanya +Last Changed Rev: 67 +Last Changed Date: 2014-12-08 09:17:56 +0100 From 76c9d2c61bd839d5126ac2400a2463a73ef760d5 Mon Sep 17 00:00:00 2001 From: Maliakal Dhanya Date: Wed, 14 Jan 2015 10:48:36 +0100 Subject: [PATCH 063/474] lot of couts and some pre and post --- .../src/UDPStandardImplementation.cpp | 118 ++++++++++-------- 1 file changed, 69 insertions(+), 49 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index cb8d66c25..ca8715eda 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -864,8 +864,10 @@ void UDPStandardImplementation::setupFifoStructure(){ void UDPStandardImplementation::readFrame(char* c,char** raw, uint32_t &fnum, uint32_t &fstartind){ FILE_LOG(logDEBUG) << __AT__ << " called"; //point to gui data - if (guiData == NULL) + if (guiData == NULL){ guiData = latestData; + cout <<"gui data not null anymore" << endl; + } //copy data and filename strcpy(c,guiFileName); @@ -873,22 +875,22 @@ void UDPStandardImplementation::readFrame(char* c,char** raw, uint32_t &fnum, ui fstartind = getStartFrameIndex(); //could not get gui data - if(!guiDataReady){ + if(!guiDataReady){cout<<"gui data not ready"<ReceiveDataOnly(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS, maxBufferSize); + cout<<"value:"<fnum)<pop(wbuf[i]); numpackets = (uint16_t)(*((uint16_t*)wbuf[i])); -#ifdef VERYDEBUG - cout << ithread << " numpackets:" << dec << numpackets << endl; -#endif +//#ifdef VERYDEBUG + cout << ithread << " numpackets:" << dec << numpackets << "for fifo :"<< i << endl; +//#endif } -#ifdef VERYDEBUG +//#ifdef VERYDEBUG cout << ithread << " numpackets:" << dec << numpackets << endl; cout << ithread << " *** writer popped from fifo " << (void*) wbuf[0]<< endl; cout << ithread << " *** writer popped from fifo " << (void*) wbuf[1]<< endl; -#endif +//#endif //last dummy packet @@ -1890,8 +1910,8 @@ int loop; } - if(myDetectorType == EIGER) { - copyFrameToGui(wbuf,currframenum); + if(myDetectorType == EIGER) {cout<<"gonna copy frame"<push(wbuf[i])); #ifdef VERYDEBUG @@ -2001,7 +2021,7 @@ void UDPStandardImplementation::startFrameIndices(int ithread){ startAcquisitionIndex=startFrameIndex; currframenum = startAcquisitionIndex; acqStarted = true; - cout << "startAcquisitionIndex:" << startAcquisitionIndex<push(buffer[ithread])); -#ifdef VERYDEBUG +//#ifdef VERYDEBUG cout << ithread << " pushed in dummy buffer:" << (void*)buffer[ithread] << endl; -#endif +//#endif } //reset mask and exit loop @@ -2108,9 +2128,9 @@ void UDPStandardImplementation::stopWriting(int ithread, char* wbuffer[]){ FILE_LOG(logDEBUG) << __AT__ << " called"; int i,j; -#ifdef VERYDEBUG - cout << ithread << " **********************popped last dummy frame:" << (void*)wbuffer[wIndex] << endl; -#endif +//#ifdef VERYDEBUG + cout << ithread << " **********************popped last dummy frame:" << (void*)wbuffer[0] << endl; +//#endif //free fifo for(i=0;i Date: Fri, 30 Jan 2015 10:58:30 +0100 Subject: [PATCH 064/474] unnecessary long wait in receiver --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index ca8715eda..145ad5ca0 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1495,7 +1495,7 @@ int UDPStandardImplementation::startReceiver(char message[]){ for(i=0; i < numWriterThreads; ++i) sem_post(&writersmp[i]); - usleep(5000000); + //usleep(5000000); cout << "Receiver Started.\nStatus:" << status << endl; return OK; From f30833a4608e69e542b0a60e1213b1e331338e35 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Fri, 30 Jan 2015 15:03:35 +0100 Subject: [PATCH 065/474] got rid of unnecessary printouts in receiver --- slsReceiverSoftware/src/UDPBaseImplementation.cpp | 2 ++ slsReceiverSoftware/src/UDPStandardImplementation.cpp | 7 ++++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/slsReceiverSoftware/src/UDPBaseImplementation.cpp b/slsReceiverSoftware/src/UDPBaseImplementation.cpp index de09ae694..1c6b1a976 100644 --- a/slsReceiverSoftware/src/UDPBaseImplementation.cpp +++ b/slsReceiverSoftware/src/UDPBaseImplementation.cpp @@ -203,7 +203,9 @@ inline char* UDPBaseImplementation::setFilePath(const char c[]){ FILE_LOG(logDEB } } FILE_LOG(logDEBUG) << __AT__ << getFilePath(); +#ifdef VERBOSE cout << getFilePath() << " " << filePath << endl; +#endif return getFilePath(); } diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 0ac51c321..16b9de1f4 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1298,8 +1298,9 @@ int UDPStandardImplementation::createNewFile(){ else sprintf(savefilename, "%s/%s_f%012d_%d.raw", filePath,fileName,(packetsCaught/packetsPerFrame),fileIndex); - +#ifdef VERBOSE cout << filePath << " + " << fileName << endl; +#endif //if filewrite and we are allowed to write if(enableFileWrite && cbAction > DO_NOTHING){ @@ -1632,9 +1633,9 @@ int UDPStandardImplementation::startListening(){ expected = maxBufferSize - carryonBufferSize; } -//#ifdef VERYDEBUG +#ifdef VERYDEBUG cout << ithread << " *** rc:" << dec << rc << ". expected:" << dec << expected << endl; -//#endif +#endif //start indices for each start of scan/acquisition - eiger does it before From 7fd12f97b4b08b3192ecd4b8436a23d8360d76e7 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Fri, 30 Jan 2015 16:49:30 +0100 Subject: [PATCH 066/474] some unnecessary printouts --- .../src/UDPBaseImplementation.cpp | 2 + .../src/UDPStandardImplementation.cpp | 48 +++++++++++-------- 2 files changed, 31 insertions(+), 19 deletions(-) diff --git a/slsReceiverSoftware/src/UDPBaseImplementation.cpp b/slsReceiverSoftware/src/UDPBaseImplementation.cpp index de09ae694..1c6b1a976 100644 --- a/slsReceiverSoftware/src/UDPBaseImplementation.cpp +++ b/slsReceiverSoftware/src/UDPBaseImplementation.cpp @@ -203,7 +203,9 @@ inline char* UDPBaseImplementation::setFilePath(const char c[]){ FILE_LOG(logDEB } } FILE_LOG(logDEBUG) << __AT__ << getFilePath(); +#ifdef VERBOSE cout << getFilePath() << " " << filePath << endl; +#endif return getFilePath(); } diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 145ad5ca0..29843ff94 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -866,7 +866,7 @@ void UDPStandardImplementation::readFrame(char* c,char** raw, uint32_t &fnum, ui //point to gui data if (guiData == NULL){ guiData = latestData; - cout <<"gui data not null anymore" << endl; + //cout <<"gui data not null anymore" << endl; } //copy data and filename @@ -875,22 +875,26 @@ void UDPStandardImplementation::readFrame(char* c,char** raw, uint32_t &fnum, ui fstartind = getStartFrameIndex(); //could not get gui data - if(!guiDataReady){cout<<"gui data not ready"< DO_NOTHING){ @@ -1645,7 +1653,7 @@ int UDPStandardImplementation::startListening(){ /* if(!ithread){*/ rc = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS, maxBufferSize); - cout<<"value:"<fnum)<fnum)<pop(wbuf[i]); numpackets = (uint16_t)(*((uint16_t*)wbuf[i])); //#ifdef VERYDEBUG @@ -1855,11 +1863,11 @@ int loop; //#endif } -//#ifdef VERYDEBUG +#ifdef VERYDEBUG cout << ithread << " numpackets:" << dec << numpackets << endl; cout << ithread << " *** writer popped from fifo " << (void*) wbuf[0]<< endl; cout << ithread << " *** writer popped from fifo " << (void*) wbuf[1]<< endl; -//#endif +#endif //last dummy packet @@ -1910,8 +1918,10 @@ int loop; } - if(myDetectorType == EIGER) {cout<<"gonna copy frame"<push(wbuf[i])); #ifdef VERYDEBUG @@ -2080,9 +2090,9 @@ int i; cout << ithread << " going to push in dummy buffer:" << (void*)buffer[ithread] << " with num packets:"<< (*((uint16_t*)(buffer[ithread]))) << endl; #endif while(!fifo[ithread]->push(buffer[ithread])); -//#ifdef VERYDEBUG +#ifdef VERYDEBUG cout << ithread << " pushed in dummy buffer:" << (void*)buffer[ithread] << endl; -//#endif +#endif } //reset mask and exit loop @@ -2128,9 +2138,9 @@ void UDPStandardImplementation::stopWriting(int ithread, char* wbuffer[]){ FILE_LOG(logDEBUG) << __AT__ << " called"; int i,j; -//#ifdef VERYDEBUG +#ifdef VERYDEBUG cout << ithread << " **********************popped last dummy frame:" << (void*)wbuffer[0] << endl; -//#endif +#endif //free fifo for(i=0;i Date: Wed, 4 Feb 2015 16:11:13 +0100 Subject: [PATCH 067/474] some code refraction to get rid of memeory leakage --- slsReceiverSoftware/include/genericSocket.h | 1 - .../src/UDPBaseImplementation.cpp | 7 ++-- .../src/UDPStandardImplementation.cpp | 40 +++++++++++-------- slsReceiverSoftware/src/main.cpp | 1 + .../src/slsReceiverTCPIPInterface.cpp | 11 ++--- 5 files changed, 33 insertions(+), 27 deletions(-) diff --git a/slsReceiverSoftware/include/genericSocket.h b/slsReceiverSoftware/include/genericSocket.h index a798a0fef..bbe119439 100644 --- a/slsReceiverSoftware/include/genericSocket.h +++ b/slsReceiverSoftware/include/genericSocket.h @@ -103,7 +103,6 @@ enum communicationProtocol{ nsent(0), total_sent(0)// sender (client): where to? ip { - // strcpy(hostname,host_ip_or_name); struct hostent *hostInfo = gethostbyname(host_ip_or_name); if (hostInfo == NULL){ diff --git a/slsReceiverSoftware/src/UDPBaseImplementation.cpp b/slsReceiverSoftware/src/UDPBaseImplementation.cpp index 1c6b1a976..7641a5a1e 100644 --- a/slsReceiverSoftware/src/UDPBaseImplementation.cpp +++ b/slsReceiverSoftware/src/UDPBaseImplementation.cpp @@ -1328,8 +1328,8 @@ int UDPBaseImplementation::startListening(){ FILE_LOG(logDEBUG) << __AT__ << " s thread_started = 1; - int i,total; - int lastpacketoffset, expected, rc, rc1,packetcount, maxBufferSize, carryonBufferSize; + int total; + int lastpacketoffset, expected, rc,packetcount, maxBufferSize, carryonBufferSize; uint32_t lastframeheader;// for moench to check for all the packets in last frame char* tempchar = NULL; int imageheader = 0; @@ -1534,9 +1534,8 @@ int UDPBaseImplementation::startWriting(){ FILE_LOG(logDEBUG) << __AT__ << " sta char* wbuf[numListeningThreads];//interleaved char *d=new char[bufferSize*numListeningThreads]; int xmax=0,ymax=0; - int ret,i,j; + int ret,i; int packetsPerThread = packetsPerFrame/numListeningThreads; -int loop; while(1){ diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 16b9de1f4..a2ddd6e39 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -67,7 +67,6 @@ UDPStandardImplementation::UDPStandardImplementation() rawDataReadyCallBack = NULL; pRawDataReady = NULL; - initializeMembers(); //mutex pthread_mutex_init(&dataReadyMutex,NULL); @@ -75,6 +74,8 @@ UDPStandardImplementation::UDPStandardImplementation() pthread_mutex_init(&progress_mutex,NULL); pthread_mutex_init(&write_mutex,NULL); + initializeMembers(); + //to increase socket receiver buffer size and max length of input queue by changing kernel settings if(system("echo $((100*1024*1024)) > /proc/sys/net/core/rmem_max")) cout << "\nWARNING: Could not change socket receiver buffer size in file /proc/sys/net/core/rmem_max" << endl; @@ -1567,8 +1568,8 @@ int UDPStandardImplementation::startListening(){ thread_started = 1; - int i,total; - int lastpacketoffset, expected, rc, rc1,packetcount, maxBufferSize, carryonBufferSize; + int total; + int lastpacketoffset, expected, rc,packetcount, maxBufferSize, carryonBufferSize; uint32_t lastframeheader;// for moench to check for all the packets in last frame char* tempchar = NULL; int imageheader = 0; @@ -1750,6 +1751,8 @@ int UDPStandardImplementation::startListening(){ if(tempchar) {delete [] tempchar;tempchar = NULL;} pthread_exit(NULL); } + + if(tempchar) {delete [] tempchar;tempchar = NULL;} } return OK; @@ -1782,9 +1785,8 @@ int UDPStandardImplementation::startWriting(){ char* wbuf[numListeningThreads];//interleaved char *d=new char[bufferSize*numListeningThreads]; int xmax=0,ymax=0; - int ret,i,j; + int ret,i; int packetsPerThread = packetsPerFrame/numListeningThreads; -int loop; while(1){ @@ -1792,17 +1794,17 @@ int loop; nf = 0; packetsPerThread = packetsPerFrame/numListeningThreads; if(myDetectorType == MOENCH){ - xmax = MOENCH_PIXELS_IN_ONE_ROW-1; - ymax = MOENCH_PIXELS_IN_ONE_ROW-1; - }else{ - if(shortFrame == -1){ + xmax = MOENCH_PIXELS_IN_ONE_ROW-1; + ymax = MOENCH_PIXELS_IN_ONE_ROW-1; + }else{ + if(shortFrame == -1){ xmax = GOTTHARD_PIXELS_IN_ROW-1; ymax = GOTTHARD_PIXELS_IN_COL-1; - }else{ - xmax = GOTTHARD_SHORT_PIXELS_IN_ROW-1; - ymax = GOTTHARD_SHORT_PIXELS_IN_COL-1; - } + }else{ + xmax = GOTTHARD_SHORT_PIXELS_IN_ROW-1; + ymax = GOTTHARD_SHORT_PIXELS_IN_COL-1; } + } @@ -1880,7 +1882,7 @@ int loop; for(i=0;ipush(wbuf[i])); #ifdef VERYDEBUG - cout << ithread << ":" << i+j << " fifo freed:" << (void*)wbuf[i] << endl; + cout << ithread << ":" << i << " fifo freed:" << (void*)wbuf[i] << endl; #endif } @@ -1888,10 +1890,12 @@ int loop; } else{ //copy to gui - copyFrameToGui(NULL,-1,wbuf[0]+HEADER_SIZE_NUM_TOT_PACKETS); + if((packetsPerFrame * numpackets) == bufferSize){ + copyFrameToGui(NULL,-1,wbuf[0]+HEADER_SIZE_NUM_TOT_PACKETS); #ifdef VERYVERBOSE - cout << ithread << " finished copying" << endl; + cout << ithread << " finished copying" << endl; #endif + }//else cout << "unfinished buffersize" << endl; while(!fifoFree[0]->push(wbuf[0])); #ifdef VERYVERBOSE cout<<"buf freed:"<<(void*)wbuf[0]<push(buffer[ithread]); - else if(rc > 0){cout<< ithread << " last rc:"< 0){ pc = (rc/onePacketSize); #ifdef VERYDEBUG + cout << ithread << " last rc:"<stop(); } + delete user; cout << "Goodbye!" << endl; return 0; } diff --git a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp index 20c95a051..b1fe40aca 100644 --- a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp +++ b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp @@ -26,7 +26,8 @@ using namespace std; slsReceiverTCPIPInterface::~slsReceiverTCPIPInterface() { - if(socket) delete socket; + if(socket) {delete socket; socket=NULL;} + if(receiverBase) {delete receiverBase; receiverBase=NULL;} closeFile(0); } @@ -1221,8 +1222,8 @@ int slsReceiverTCPIPInterface::gotthard_read_frame(){ } //all adc else{ - //ignore if half frame is missing - if ((bindex != 0xFFFFFFFF) && (bindex2 != 0xFFFFFFFF)){ + /*//ignore if half frame is missing + if ((bindex != 0xFFFFFFFF) && (bindex2 != 0xFFFFFFFF)){*/ //should be same frame if (index == index2){ @@ -1239,11 +1240,11 @@ int slsReceiverTCPIPInterface::gotthard_read_frame(){ } }else cout << "different frames caught. frame1:"<< hex << index << ":"< Date: Tue, 10 Feb 2015 12:21:31 +0100 Subject: [PATCH 068/474] initializing variables and copying ot gui only full frames --- slsReceiverSoftware/include/genericSocket.h | 9 ++++++++- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 2 +- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/slsReceiverSoftware/include/genericSocket.h b/slsReceiverSoftware/include/genericSocket.h index bbe119439..d6a102201 100644 --- a/slsReceiverSoftware/include/genericSocket.h +++ b/slsReceiverSoftware/include/genericSocket.h @@ -103,6 +103,10 @@ enum communicationProtocol{ nsent(0), total_sent(0)// sender (client): where to? ip { + memset(&serverAddress, 0, sizeof(sockaddr_in)); + memset(&clientAddress, 0, sizeof(sockaddr_in)); + // serverAddress = {0}; + // clientAddress = {0}; // strcpy(hostname,host_ip_or_name); struct hostent *hostInfo = gethostbyname(host_ip_or_name); if (hostInfo == NULL){ @@ -158,7 +162,10 @@ enum communicationProtocol{ nsent(0), total_sent(0) { - + memset(&serverAddress, 0, sizeof(sockaddr_in)); + memset(&clientAddress, 0, sizeof(sockaddr_in)); + // serverAddress = {0}; + // clientAddress = {0}; /* // you can specify an IP address: */ /* */ diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index a2ddd6e39..d97adf49a 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1890,7 +1890,7 @@ int UDPStandardImplementation::startWriting(){ } else{ //copy to gui - if((packetsPerFrame * numpackets) == bufferSize){ + if(numpackets == packetsPerFrame * numJobsPerThread){ //only full frames copyFrameToGui(NULL,-1,wbuf[0]+HEADER_SIZE_NUM_TOT_PACKETS); #ifdef VERYVERBOSE cout << ithread << " finished copying" << endl; From 1e55577fc2125a2a53f61625d862bdf04c0fa750 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 10 Feb 2015 16:54:39 +0100 Subject: [PATCH 069/474] no change --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index b74f9c6cf..9f1b765fd 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1676,9 +1676,9 @@ int UDPStandardImplementation::startListening(){ expected = maxBufferSize - carryonBufferSize; } -#ifdef VERYDEBUG +//#ifdef VERYDEBUG cout << ithread << " *** rc:" << dec << rc << ". expected:" << dec << expected << endl; -#endif +//#endif //start indices for each start of scan/acquisition - eiger does it before From 6d8fcaa4230594f096985e3153008bf0dcc058e3 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Fri, 13 Feb 2015 11:58:36 +0100 Subject: [PATCH 070/474] debugging output change --- slsReceiverSoftware/include/genericSocket.h | 8 ++++---- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 10 +++++----- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/slsReceiverSoftware/include/genericSocket.h b/slsReceiverSoftware/include/genericSocket.h index d6a102201..a10e07649 100644 --- a/slsReceiverSoftware/include/genericSocket.h +++ b/slsReceiverSoftware/include/genericSocket.h @@ -103,8 +103,8 @@ enum communicationProtocol{ nsent(0), total_sent(0)// sender (client): where to? ip { - memset(&serverAddress, 0, sizeof(sockaddr_in)); - memset(&clientAddress, 0, sizeof(sockaddr_in)); + //memset(&serverAddress, 0, sizeof(sockaddr_in)); + //memset(&clientAddress, 0, sizeof(sockaddr_in)); // serverAddress = {0}; // clientAddress = {0}; // strcpy(hostname,host_ip_or_name); @@ -162,8 +162,8 @@ enum communicationProtocol{ nsent(0), total_sent(0) { - memset(&serverAddress, 0, sizeof(sockaddr_in)); - memset(&clientAddress, 0, sizeof(sockaddr_in)); + //memset(&serverAddress, 0, sizeof(sockaddr_in)); + // memset(&clientAddress, 0, sizeof(sockaddr_in)); // serverAddress = {0}; // clientAddress = {0}; /* // you can specify an IP address: */ diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 9f1b765fd..e7ee3fe22 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1564,7 +1564,7 @@ void UDPStandardImplementation::startReadout(){ //wait so that all packets which take time has arrived usleep(5000); /********************************************/ - //usleep(10000000); + //usleep(1000000); //usleep(2000000); pthread_mutex_lock(&status_mutex); @@ -1860,9 +1860,9 @@ int UDPStandardImplementation::startWriting(){ //cout<<"writer gonna pop from fifo:"<pop(wbuf[i]); numpackets = (uint16_t)(*((uint16_t*)wbuf[i])); -//#ifdef VERYDEBUG +#ifdef VERYDEBUG cout << ithread << " numpackets:" << dec << numpackets << "for fifo :"<< i << endl; -//#endif +#endif } #ifdef VERYDEBUG @@ -2109,9 +2109,9 @@ int i; #endif pthread_mutex_unlock(&(status_mutex)); -//#ifdef VERYDEBUG +#ifdef VERYDEBUG cout << ithread << ": Frames listened to " << dec << ((totalListeningFrameCount[ithread]*numListeningThreads)/packetsPerFrame) << endl; -//#endif +#endif //waiting for all listening threads to be done, to print final count of frames listened to if(ithread == 0){ From 651a13f811fd7c814bdc46918e409be7464f7f1d Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Mon, 23 Feb 2015 15:25:06 +0100 Subject: [PATCH 071/474] so that gui can reread the same frame from receiver, guidataready is set to zero only once --- .../src/UDPStandardImplementation.cpp | 63 +++++++++++++------ .../src/slsReceiverTCPIPInterface.cpp | 18 +++--- 2 files changed, 55 insertions(+), 26 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index e7ee3fe22..05e195208 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -867,7 +867,9 @@ void UDPStandardImplementation::readFrame(char* c,char** raw, uint32_t &fnum, ui //point to gui data if (guiData == NULL){ guiData = latestData; - //cout <<"gui data not null anymore" << endl; +#ifdef VERY_VERY_DEBUG + cout <<"gui data not null anymore" << endl; +#endif } //copy data and filename @@ -877,25 +879,33 @@ void UDPStandardImplementation::readFrame(char* c,char** raw, uint32_t &fnum, ui //could not get gui data if(!guiDataReady){ - //cout<<"gui data not ready"<pop(wbuf[i]); numpackets = (uint16_t)(*((uint16_t*)wbuf[i])); #ifdef VERYDEBUG - cout << ithread << " numpackets:" << dec << numpackets << "for fifo :"<< i << endl; + cout << i << " numpackets:" << dec << numpackets << "for fifo :"<< i << endl; #endif } @@ -1874,10 +1887,15 @@ int UDPStandardImplementation::startWriting(){ //last dummy packet if(numpackets == 0xFFFF){ +#ifdef VERYDEBUG + cout << "LAST dummy packet" << endl; +#endif stopWriting(ithread,wbuf); continue; } - +#ifdef VERYDEBUG + else cout <<"NOT a dummy packet"< 0){ for(i=0;ipush(wbuf[i])); #ifdef VERYDEBUG @@ -2056,7 +2081,7 @@ void UDPStandardImplementation::startFrameIndices(int ithread){ -void UDPStandardImplementation::stopListening(int ithread, int rc, int &pc, int &t){cout << "Stop Listening" << endl; +void UDPStandardImplementation::stopListening(int ithread, int rc, int &pc, int &t){ FILE_LOG(logDEBUG) << __AT__ << " called"; diff --git a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp index b1fe40aca..d98a7ddd7 100644 --- a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp +++ b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp @@ -1336,9 +1336,9 @@ int slsReceiverTCPIPInterface::eiger_read_frame(){ /**send garbage with -1 index to try again*/ if (raw == NULL){ arg = -1; -#ifdef VERBOSE +//#ifdef VERBOSE cout<<"data not ready for gui yet"< Date: Tue, 24 Feb 2015 16:19:33 +0100 Subject: [PATCH 072/474] moved start of frame to after stoplistening, for eiger to ignore incomplete frames --- .../src/UDPBaseImplementation.cpp | 1 + .../src/UDPStandardImplementation.cpp | 61 ++++++++++++------- .../src/slsReceiverTCPIPInterface.cpp | 12 ++-- 3 files changed, 45 insertions(+), 29 deletions(-) diff --git a/slsReceiverSoftware/src/UDPBaseImplementation.cpp b/slsReceiverSoftware/src/UDPBaseImplementation.cpp index 7641a5a1e..9c6c26460 100644 --- a/slsReceiverSoftware/src/UDPBaseImplementation.cpp +++ b/slsReceiverSoftware/src/UDPBaseImplementation.cpp @@ -171,6 +171,7 @@ uint32_t UDPBaseImplementation::getAcquisitionIndex(){ FILE_LOG(logDEBUG) << __A acquisitionIndex=-1; else acquisitionIndex = currframenum - startAcquisitionIndex; + //cout<<"acquisitionIndex:"< 0) && (!ithread)) startFrameIndices(ithread); - +*/ //problem in receiving or end of acquisition if((rc < expected)||(rc <= 0)){ @@ -1703,11 +1703,11 @@ int UDPStandardImplementation::startListening(){ continue; } -/* - //start indices for each start of scan/acquisition - eiger does it before +///* + //start indices for each start of scan/acquisition - this should be done after to ignore first incomplete frames if((!measurementStarted) && (rc > 0) && (!ithread)) startFrameIndices(ithread); -*/ +//*/ //reset packetcount = (packetsPerFrame/numListeningThreads) * numJobsPerThread; @@ -1884,17 +1884,16 @@ int UDPStandardImplementation::startWriting(){ cout << ithread << " *** writer popped from fifo " << (void*) wbuf[1]<< endl; #endif - //last dummy packet if(numpackets == 0xFFFF){ #ifdef VERYDEBUG - cout << "LAST dummy packet" << endl; + cout << "**LAST dummy packet" << endl; #endif stopWriting(ithread,wbuf); continue; } #ifdef VERYDEBUG - else cout <<"NOT a dummy packet"<push(buffer[ithread]); exit(-1); } + //push the last buffer into fifo - if((myDetectorType == EIGER) && (rc < 266240) )//for eiger throw away incomplete frames - fifoFree[ithread]->push(buffer[ithread]); - else if(rc > 0){ - pc = (rc/onePacketSize); + if(rc > 0){ + //eiger (incomplete frames) - throw away + if((myDetectorType == EIGER) && (rc < (bufferSize * numJobsPerThread)) ){ + if(rc == 266240) + cout << ithread << " Start of detector: Received test frame of 266240 bytes." << endl; + cout << ithread << "Discarding incomplete frame" << endl; + fifoFree[ithread]->push(buffer[ithread]); + } + //eiger (complete frames) + other detectors + else{ + pc = (rc/onePacketSize); #ifdef VERYDEBUG - cout << ithread << " last rc:"<push(buffer[ithread])); + (*((uint16_t*)(buffer[ithread]))) = pc; + totalListeningFrameCount[ithread] += pc; + while(!fifo[ithread]->push(buffer[ithread])); #ifdef VERYDEBUG - cout << ithread << " *** last lbuf1:" << (void*)buffer[ithread] << endl; + cout << ithread << " *** last lbuf1:" << (void*)buffer[ithread] << endl; #endif + } } + //free buffer + else{ + cout << ithread << "Discarding empty frame" << endl; + fifoFree[ithread]->push(buffer[ithread]); + } + //push dummy buffer to all writer threads @@ -2279,8 +2293,9 @@ void UDPStandardImplementation::writeToFile_withoutCompression(char* buf,int num packetsInFile += packetsToSave; packetsCaught += packetsToSave; totalPacketsCaught += packetsToSave; - - +#ifdef VERYDEBUG + cout << "/totalPacketsCaught:" << dec << totalPacketsCaught <= maxPacketsPerFile){ //for packet loss diff --git a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp index d98a7ddd7..8b0d52195 100644 --- a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp +++ b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp @@ -1336,9 +1336,9 @@ int slsReceiverTCPIPInterface::eiger_read_frame(){ /**send garbage with -1 index to try again*/ if (raw == NULL){ arg = -1; -//#ifdef VERBOSE +#ifdef VERBOSE cout<<"data not ready for gui yet"< Date: Wed, 25 Feb 2015 10:34:57 +0100 Subject: [PATCH 073/474] moved startframeindice to before stop listening for gotthard --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 3fbba8a7e..7f8429d2f 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1699,12 +1699,17 @@ int UDPStandardImplementation::startListening(){ //problem in receiving or end of acquisition if((rc < expected)||(rc <= 0)){ + if(myDetectorType != EIGER){ + //start indices for each start of scan/acquisition - this should be done earlier for normal detectors + if((!measurementStarted) && (rc > 0) && (!ithread)) + startFrameIndices(ithread); + } stopListening(ithread,rc,packetcount,total); continue; } ///* - //start indices for each start of scan/acquisition - this should be done after to ignore first incomplete frames + //eiger - start indices for each start of scan/acquisition - this should be done after to ignore first incomplete frames if((!measurementStarted) && (rc > 0) && (!ithread)) startFrameIndices(ithread); //*/ From 2f824695313242f29d40f6d89f4f8eaeab7685c2 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Thu, 5 Mar 2015 15:21:12 +0100 Subject: [PATCH 074/474] fifo debug with color done --- slsReceiverSoftware/include/ansi.h | 59 ++++++++++ .../include/sls_receiver_defs.h | 2 +- .../src/UDPBaseImplementation.cpp | 8 +- .../src/UDPStandardImplementation.cpp | 103 ++++++++++-------- 4 files changed, 124 insertions(+), 48 deletions(-) create mode 100644 slsReceiverSoftware/include/ansi.h diff --git a/slsReceiverSoftware/include/ansi.h b/slsReceiverSoftware/include/ansi.h new file mode 100644 index 000000000..1a24d403e --- /dev/null +++ b/slsReceiverSoftware/include/ansi.h @@ -0,0 +1,59 @@ +#define RED "\x1b[31m" +#define GREEN "\x1b[32m" +#define YELLOW "\x1b[33m" +#define BLUE "\x1b[34m" +#define MAGENTA "\x1b[35m" +#define CYAN "\x1b[36m" +#define BG_RED "\x1b[41m" +#define BG_GREEN "\x1b[42m" +#define BG_YELLOW "\x1b[43m" +#define BG_BLUE "\x1b[44m" +#define BG_MAGENTA "\x1b[45m" +#define BG_CYAN "\x1b[46m" +#define RESET "\x1b[0m" +#define BOLD "\x1b[1m" + +#define cprintf(code, format, ...) printf(code format RESET, ##__VA_ARGS__) + +/* + +Code examples + +example 1 (a snippet): + + +#ifdef MARTIN + cprintf(BLUE, "LL Write - Len: %2d - If: %X - Data: ",buffer_len, ll->ll_fifo_base); + for (i=0; i < buffer_len/4; i++) + cprintf(BLUE, "%.8X ",*(((unsigned *) buffer)+i)); + printf("\n"); +#endif + +#ifdef MARTIN + cprintf(CYAN, "LL Read - If: %X - Data: ",ll->ll_fifo_base); +#endif + + + +example 2: + +int main() +{ + int i=1; + printf("Normal %i\n", i); + cprintf(RED, "Red\n"); + cprintf(GREEN, "Green\n"); + cprintf(YELLOW, "Yellow\n"); + cprintf(BLUE, "Blue\n"); + cprintf(MAGENTA, "Mangenta %i\n", i); + cprintf(CYAN, "Cyan %i\n", i); + cprintf(BOLD, "White %i\n", i); + cprintf(RED BOLD, "Red %i\n", i); + cprintf(GREEN BOLD, "Green\n"); + cprintf(YELLOW BOLD, "Yellow\n"); + cprintf(BLUE BOLD, "Blue\n"); + cprintf(MAGENTA BOLD, "Mangenta %i\n", i); + cprintf(CYAN BOLD, "Cyan %i\n", i); +} + +*/ diff --git a/slsReceiverSoftware/include/sls_receiver_defs.h b/slsReceiverSoftware/include/sls_receiver_defs.h index 7f39ff05d..7e3af64c2 100755 --- a/slsReceiverSoftware/include/sls_receiver_defs.h +++ b/slsReceiverSoftware/include/sls_receiver_defs.h @@ -8,7 +8,7 @@ #endif #include - +#include "ansi.h" typedef double double32_t; typedef float float32_t; diff --git a/slsReceiverSoftware/src/UDPBaseImplementation.cpp b/slsReceiverSoftware/src/UDPBaseImplementation.cpp index 9c6c26460..f12890aa2 100644 --- a/slsReceiverSoftware/src/UDPBaseImplementation.cpp +++ b/slsReceiverSoftware/src/UDPBaseImplementation.cpp @@ -374,12 +374,12 @@ int32_t UDPBaseImplementation::setDynamicRange(int32_t dr){ FILE_LOG(logDEBUG) < setupFifoStructure(); if(createListeningThreads() == FAIL){ - cout << "ERROR: Could not create listening thread" << endl; + cprintf(BG_RED,"ERROR: Could not create listening thread\n"); exit (-1); } if(createWriterThreads() == FAIL){ - cout << "ERROR: Could not create writer threads" << endl; + cprintf(BG_RED,"ERROR: Could not create writer threads\n"); exit (-1); } @@ -475,7 +475,7 @@ int UDPBaseImplementation::enableDataCompression(bool enable){ FILE_LOG(logDEBUG numWriterThreads = 1; if(createWriterThreads() == FAIL){ - cout << "ERROR: Could not create writer threads" << endl; + cprintf(BG_RED,"ERROR: Could not create writer threads\n"); return FAIL; } setThreadPriorities(); @@ -763,7 +763,7 @@ int UDPBaseImplementation::createUDPSockets(){ FILE_LOG(logDEBUG) << __AT__ << " iret = udpSocket[i]->getErrorStatus(); if(iret){ #ifdef VERBOSE - cout << "Could not create UDP socket on port " << server_port[i] << " error:" << iret << endl; + cprintf(BG_RED,"Could not create UDP socket on port %d error: %d\n",server_port[i], iret); #endif return FAIL; } diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 7f8429d2f..6f454ab57 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -322,12 +322,12 @@ int UDPStandardImplementation::setDetectorType(detectorType det){ FILE_LOG(logD setupFifoStructure(); if(createListeningThreads() == FAIL){ - cout << "ERROR: Could not create listening thread" << endl; + cprintf(BG_RED,"ERROR: Could not create listening thread\n"); exit (-1); } if(createWriterThreads() == FAIL){ - cout << "ERROR: Could not create writer threads" << endl; + cprintf(BG_RED,"ERROR: Could not create writer threads\n"); exit (-1); } @@ -585,12 +585,12 @@ int32_t UDPStandardImplementation::setDynamicRange(int32_t dr){ FILE_LOG(logDEB setupFifoStructure(); if(createListeningThreads() == FAIL){ - cout << "ERROR: Could not create listening thread" << endl; + cprintf(BG_RED,"ERROR: Could not create listening thread\n"); exit (-1); } if(createWriterThreads() == FAIL){ - cout << "ERROR: Could not create writer threads" << endl; + cprintf(BG_RED,"ERROR: Could not create writer threads\n"); exit (-1); } @@ -691,7 +691,7 @@ int UDPStandardImplementation::enableDataCompression(bool enable){ FILE_LOG(log numWriterThreads = 1; if(createWriterThreads() == FAIL){ - cout << "ERROR: Could not create writer threads" << endl; + cprintf(BG_RED,"ERROR: Could not create writer threads\n"); return FAIL; } setThreadPriorities(); @@ -830,6 +830,9 @@ void UDPStandardImplementation::setupFifoStructure(){ if(fifoFree[i]){ while(!fifoFree[i]->isEmpty()) fifoFree[i]->pop(buffer[i]); +#ifdef FIFO_DEBUG + //cprintf(GREEN,"%d fifostructure popped from fifofree %x\n", i, (void*)(buffer[i])); +#endif delete fifoFree[i]; } if(fifo[i]) delete fifo[i]; @@ -849,6 +852,9 @@ void UDPStandardImplementation::setupFifoStructure(){ //push the addresses into freed fifoFree and writingFifoFree while (buffer[i]<(mem0[i]+(bufferSize * numJobsPerThread + HEADER_SIZE_NUM_TOT_PACKETS)*(fifosize-1))) { fifoFree[i]->push(buffer[i]); +#ifdef FIFO_DEBUG + cprintf(BLUE,"%d fifostructure free pushed into fifofree %x\n", i, (void*)(buffer[i])); +#endif buffer[i]+=(bufferSize * numJobsPerThread + HEADER_SIZE_NUM_TOT_PACKETS); } } @@ -1017,7 +1023,7 @@ int UDPStandardImplementation::createUDPSockets(){ cout << "UDP port opened at port " << port[i] << endl; else{ #ifdef VERBOSE - cout << "Could not create UDP socket on port " << port[i] << " error:" << iret << endl; + cprintf(BG_RED,"Could not create UDP socket on port %d error: %d\n", port[i], iret); #endif return FAIL; } @@ -1349,11 +1355,11 @@ int UDPStandardImplementation::createNewFile(){ //open file if(!overwrite){ if (NULL == (sfilefd = fopen((const char *) (savefilename), "wx"))){ - cout << "Error: Could not create new file " << savefilename << endl; + cprintf(BG_RED,"Error: Could not create new file %s\n",savefilename); return FAIL; } }else if (NULL == (sfilefd = fopen((const char *) (savefilename), "w"))){ - cout << "Error: Could not create file " << savefilename << endl; + cprintf(BG_RED,"Error: Could not create file %s\n",savefilename); return FAIL; } //setting buffer @@ -1650,8 +1656,8 @@ int UDPStandardImplementation::startListening(){ #endif //pop fifoFree[ithread]->pop(buffer[ithread]); -#ifdef VERYDEBUG - cout << ithread << " *** popped from fifo free" << (void*)buffer[ithread] << endl; +#ifdef FIFO_DEBUG + cprintf(GREEN,"%d listener popped from fifofree %x\n", ithread, (void*)(buffer[ithread])); #endif @@ -1687,9 +1693,9 @@ int UDPStandardImplementation::startListening(){ expected = maxBufferSize - carryonBufferSize; } -#ifdef VERYDEBUG +//#ifdef VERDEBUG cout << ithread << " *** rc:" << dec << rc << ". expected:" << dec << expected << endl; -#endif +//#endif /* //start indices for each start of scan/acquisition - eiger does it before @@ -1796,8 +1802,9 @@ int UDPStandardImplementation::startListening(){ cout<push(buffer[ithread])); -#ifdef VERYDEBUG - if(!ithread) cout << ithread << " *** pushed into listening fifo" << endl; +#ifdef FIFO_DEBUG + //if(!ithread) + cprintf(RED, "%d listener pushed into fifo %x\n",ithread, (void*)(buffer[ithread])); #endif } @@ -1877,29 +1884,27 @@ int UDPStandardImplementation::startWriting(){ cout << "writer gonna pop from fifo:" << i << endl; #endif fifo[i]->pop(wbuf[i]); +#ifdef FIFO_DEBUG + cprintf(MAGENTA,"%d writer poped from fifo %x\n", ithread, (void*)(wbuf[i])); +#endif numpackets = (uint16_t)(*((uint16_t*)wbuf[i])); #ifdef VERYDEBUG cout << i << " numpackets:" << dec << numpackets << "for fifo :"<< i << endl; #endif } -#ifdef VERYDEBUG - cout << ithread << " numpackets:" << dec << numpackets << endl; - cout << ithread << " *** writer popped from fifo " << (void*) wbuf[0]<< endl; - cout << ithread << " *** writer popped from fifo " << (void*) wbuf[1]<< endl; -#endif //last dummy packet if(numpackets == 0xFFFF){ -#ifdef VERYDEBUG +//#ifdef VERYDEBUG cout << "**LAST dummy packet" << endl; -#endif +//#endif stopWriting(ithread,wbuf); continue; } -#ifdef VERYDEBUG +//#ifdef VERYDEBUG else cout <<"**NOT a dummy packet"<push(wbuf[i])); -#ifdef VERYDEBUG - cout << ithread << ":" << i << " fifo freed:" << (void*)wbuf[i] << endl; +#ifdef FIFO_DEBUG + cprintf(BLUE,"%d writer freed pushed into fifofree %x for listener %d\n",ithread, (void*)(wbuf[i]),i); #endif } @@ -1971,8 +1976,8 @@ int UDPStandardImplementation::startWriting(){ #endif }//else cout << "unfinished buffersize" << endl; while(!fifoFree[0]->push(wbuf[0])); -#ifdef VERYVERBOSE - cout<<"buf freed:"<<(void*)wbuf[0]<push(buffer[ithread]); +#ifdef FIFO_DEBUG + cprintf(BLUE,"%d listener not txm free pushed into fifofree %x\n", ithread,(void*)(buffer[ithread])); +#endif exit(-1); } @@ -2108,6 +2116,9 @@ int i; cout << ithread << " Start of detector: Received test frame of 266240 bytes." << endl; cout << ithread << "Discarding incomplete frame" << endl; fifoFree[ithread]->push(buffer[ithread]); +#ifdef FIFO_DEBUG + cprintf(BLUE,"%d listener last buffer free pushed into fifofree %x\n", ithread,(void*)(buffer[ithread])); +#endif } //eiger (complete frames) + other detectors else{ @@ -2119,8 +2130,8 @@ int i; (*((uint16_t*)(buffer[ithread]))) = pc; totalListeningFrameCount[ithread] += pc; while(!fifo[ithread]->push(buffer[ithread])); -#ifdef VERYDEBUG - cout << ithread << " *** last lbuf1:" << (void*)buffer[ithread] << endl; +#ifdef FIFO_DEBUG + cprintf(RED,"%d listener last buffer pushed into fifo %x\n", ithread,(void*)(buffer[ithread])); #endif } } @@ -2128,6 +2139,9 @@ int i; else{ cout << ithread << "Discarding empty frame" << endl; fifoFree[ithread]->push(buffer[ithread]); +#ifdef FIFO_DEBUG + cprintf(BLUE,"%d listener empty buffer pushed into fifofree %x\n", ithread, (void*)(buffer[ithread])); +#endif } @@ -2135,13 +2149,16 @@ int i; //push dummy buffer to all writer threads for(i=0;ipop(buffer[ithread]); +#ifdef FIFO_DEBUG + cprintf(GREEN,"%d listener popped dummy buffer from fifofree %x\n", ithread,(void*)(buffer[ithread])); +#endif (*((uint16_t*)(buffer[ithread]))) = 0xFFFF; #ifdef VERYDEBUG - cout << ithread << " going to push in dummy buffer:" << (void*)buffer[ithread] << " with num packets:"<< (*((uint16_t*)(buffer[ithread]))) << endl; + cout << ithread << " dummy buffer num packets:"<< (*((uint16_t*)(buffer[ithread]))) << endl; #endif while(!fifo[ithread]->push(buffer[ithread])); -#ifdef VERYDEBUG - cout << ithread << " pushed in dummy buffer:" << (void*)buffer[ithread] << endl; +#ifdef FIFO_DEBUG + cprintf(RED,"%d listener pushed dummy buffer into fifo %x\n", ithread,(void*)(buffer[ithread])); #endif } @@ -2195,8 +2212,8 @@ void UDPStandardImplementation::stopWriting(int ithread, char* wbuffer[]){ //free fifo for(i=0;ipush(wbuffer[i])); -#ifdef VERYDEBUG - cout << ithread << ":" << i<< " fifo freed:" << (void*)wbuffer[i] << endl; +#ifdef FIFO_DEBUG + cprintf(BLUE,"%d writer free dummy pushed into fifofree %x for listener %d\n", ithread,(void*)(wbuffer[i]),i); #endif } @@ -2233,9 +2250,10 @@ void UDPStandardImplementation::stopWriting(int ithread, char* wbuffer[]){ status = RUN_FINISHED; pthread_mutex_unlock(&(status_mutex)); //report - cout << "Status: Run Finished" << endl; - cout << "Total Packets Caught:" << dec << totalPacketsCaught << endl; - cout << "Total Frames Caught:"<< dec << (totalPacketsCaught/packetsPerFrame) << endl; + + cprintf(GREEN, "Status: Run Finished\n"); + cprintf(GREEN, "Total Packets Caught:%d\n", totalPacketsCaught); + cprintf(GREEN, "Total Frames Caught:%d\n",(totalPacketsCaught/packetsPerFrame)); //acquisition end if (acquisitionFinishedCallBack) acquisitionFinishedCallBack((totalPacketsCaught/packetsPerFrame), pAcquisitionFinished); @@ -2442,16 +2460,15 @@ void UDPStandardImplementation::handleDataCompression(int ithread, char* wbuffer remainingsize -= ((buff + ndata) - data); data = buff + ndata; if(data > (wbuffer[0] + HEADER_SIZE_NUM_TOT_PACKETS + npackets * onePacketSize) ) - cout <<" **************ERROR SHOULD NOT COME HERE, Error 142536!"<push(wbuffer[0])); -#ifdef VERYVERBOSE - cout<<"buf freed:"<<(void*)wbuffer[0]< Date: Fri, 6 Mar 2015 10:43:05 +0100 Subject: [PATCH 075/474] Some changes for the JCTB software --- slsReceiverSoftware/include/sls_receiver_defs.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/slsReceiverSoftware/include/sls_receiver_defs.h b/slsReceiverSoftware/include/sls_receiver_defs.h index 7f39ff05d..ee104c632 100755 --- a/slsReceiverSoftware/include/sls_receiver_defs.h +++ b/slsReceiverSoftware/include/sls_receiver_defs.h @@ -90,7 +90,8 @@ public: PROGRESS, /**< fraction of measurement elapsed - only get! */ MEASUREMENTS_NUMBER, FRAMES_FROM_START, - FRAMES_FROM_START_PG + FRAMES_FROM_START_PG, + SAMPLES_JCTB }; From 6063c712f734a93a08a1e90765e187de2e0690ec Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 10 Mar 2015 15:04:50 +0100 Subject: [PATCH 076/474] copy first frame to latest data no matter what and also copy only if more than packets per frame --- .../src/UDPBaseImplementation.cpp | 2 +- .../src/UDPStandardImplementation.cpp | 75 +++++++++++-------- .../src/slsReceiverTCPIPInterface.cpp | 4 +- 3 files changed, 45 insertions(+), 36 deletions(-) diff --git a/slsReceiverSoftware/src/UDPBaseImplementation.cpp b/slsReceiverSoftware/src/UDPBaseImplementation.cpp index f12890aa2..8b2cdb598 100644 --- a/slsReceiverSoftware/src/UDPBaseImplementation.cpp +++ b/slsReceiverSoftware/src/UDPBaseImplementation.cpp @@ -688,7 +688,7 @@ void UDPBaseImplementation::copyFrameToGui(char* startbuf[], uint32_t fnum, char pthread_mutex_unlock(&dataReadyMutex); } - //random read or nth frame read, gui needs data now + //random read or nth frame read, gui needs data now or it is the first frame else{ /* //nth frame read, block current process if the guireader hasnt read it yet diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 6f454ab57..55e8775f7 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -874,7 +874,7 @@ void UDPStandardImplementation::readFrame(char* c,char** raw, uint32_t &fnum, ui if (guiData == NULL){ guiData = latestData; #ifdef VERY_VERY_DEBUG - cout <<"gui data not null anymore" << endl; + cout << "gui data not null anymore" << endl; #endif } @@ -886,14 +886,14 @@ void UDPStandardImplementation::readFrame(char* c,char** raw, uint32_t &fnum, ui //could not get gui data if(!guiDataReady){ #ifdef VERY_VERY_DEBUG - cout<<"gui data not ready"<= packetsPerFrame){//min 1 frame, but neednt be + //if(numpackets == packetsPerFrame * numJobsPerThread){ //only full frames copyFrameToGui(NULL,-1,wbuf[0]+HEADER_SIZE_NUM_TOT_PACKETS); #ifdef VERYVERBOSE cout << ithread << " finished copying" << endl; @@ -2108,8 +2117,16 @@ int i; exit(-1); } + //free buffer + if(rc <= 0){ + cout << ithread << "Discarding empty frame" << endl; + fifoFree[ithread]->push(buffer[ithread]); +#ifdef FIFO_DEBUG + cprintf(BLUE,"%d listener empty buffer pushed into fifofree %x\n", ithread, (void*)(buffer[ithread])); +#endif + } //push the last buffer into fifo - if(rc > 0){ + else{ //eiger (incomplete frames) - throw away if((myDetectorType == EIGER) && (rc < (bufferSize * numJobsPerThread)) ){ if(rc == 266240) @@ -2135,14 +2152,6 @@ int i; #endif } } - //free buffer - else{ - cout << ithread << "Discarding empty frame" << endl; - fifoFree[ithread]->push(buffer[ithread]); -#ifdef FIFO_DEBUG - cprintf(BLUE,"%d listener empty buffer pushed into fifofree %x\n", ithread, (void*)(buffer[ithread])); -#endif - } diff --git a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp index 8b0d52195..8c3815c19 100644 --- a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp +++ b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp @@ -1252,10 +1252,10 @@ int slsReceiverTCPIPInterface::gotthard_read_frame(){ } #ifdef VERBOSE - if(arg!=-1){ + //if(arg!=-1){ cout << "fName:" << fName << endl; cout << "findex:" << arg << endl; - } + //} #endif From 89ad2112c6b397a340635b5573e2ef645321aa0b Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Thu, 12 Mar 2015 12:25:23 +0100 Subject: [PATCH 077/474] difference between acquisition index and frame index --- .../include/UDPBaseImplementation.h | 18 ++- slsReceiverSoftware/include/UDPInterface.h | 10 +- .../include/UDPRESTImplementation.h | 9 +- .../include/UDPStandardImplementation.h | 10 +- .../src/UDPBaseImplementation.cpp | 59 +++++---- .../src/UDPRESTImplementation.cpp | 19 +-- .../src/UDPStandardImplementation.cpp | 36 ++++-- .../src/slsReceiverTCPIPInterface.cpp | 117 +++++++++++++----- 8 files changed, 190 insertions(+), 88 deletions(-) diff --git a/slsReceiverSoftware/include/UDPBaseImplementation.h b/slsReceiverSoftware/include/UDPBaseImplementation.h index 90aaf52b9..6450f85f0 100644 --- a/slsReceiverSoftware/include/UDPBaseImplementation.h +++ b/slsReceiverSoftware/include/UDPBaseImplementation.h @@ -67,6 +67,11 @@ class UDPBaseImplementation : protected virtual slsReceiverDefs, public UDPInter //Frame indices and numbers caught + /** + * Returns the frame index at start of entire acquisition (including all scans) + */ + uint32_t getStartAcquisitionIndex(); + /** * Returns current Frame Index Caught for an entire acquisition (including all scans) */ @@ -288,9 +293,11 @@ class UDPBaseImplementation : protected virtual slsReceiverDefs, public UDPInter * @param c pointer to current file name * @param raw address of pointer, pointing to current frame to send to gui * @param fnum frame number for eiger as it is not in the packet - * @param fstartind is the start index of the acquisition + * @param startAcquisitionIndex is the start index of the acquisition + * @param startFrameIndex is the start index of the scan */ - void readFrame(char* c,char** raw, uint32_t &fnum, uint32_t &fstartind); + void readFrame(char* c,char** raw, uint32_t &fnum, uint32_t &startAcquisitionIndex, uint32_t &startFrameIndex); + /** * Closes all files * @param ithr thread index @@ -479,6 +486,13 @@ protected: unsigned char fnum[4]; unsigned char header_after[24]; } eiger_image_header; + /** structure of an eiger image header*/ + typedef struct + { + unsigned char header_before[35]; + unsigned char fnum[4]; + unsigned char header_after[9]; + } eiger_image_header32; /** structure of an eiger image header*/ diff --git a/slsReceiverSoftware/include/UDPInterface.h b/slsReceiverSoftware/include/UDPInterface.h index 831b9bb62..8f3ce3f41 100644 --- a/slsReceiverSoftware/include/UDPInterface.h +++ b/slsReceiverSoftware/include/UDPInterface.h @@ -240,6 +240,11 @@ class UDPInterface { */ virtual int getFramesCaught() = 0; + /** + * Returns the frame index at start of entire acquisition (including all scans) + */ + virtual uint32_t getStartAcquisitionIndex()=0; + /** * Returns current Frame Index Caught for an entire acquisition (including all scans) */ @@ -328,9 +333,10 @@ class UDPInterface { * @param c pointer to current file name * @param raw address of pointer, pointing to current frame to send to gui * @param fnum frame number for eiger as it is not in the packet - * @param fstartind is the start index of the acquisition + * @param startAcquisitionIndex is the start index of the acquisition + * @param startFrameIndex is the start index of the scan */ - virtual void readFrame(char* c,char** raw, uint32_t &fnum, uint32_t &fstartind ) = 0; + virtual void readFrame(char* c,char** raw, uint32_t &fnum, uint32_t &startAcquisitionIndex, uint32_t &startFrameIndex)=0; /** set status to transmitting and * when fifo is empty later, sets status to run_finished diff --git a/slsReceiverSoftware/include/UDPRESTImplementation.h b/slsReceiverSoftware/include/UDPRESTImplementation.h index 6f59c30c2..f335ba9d2 100644 --- a/slsReceiverSoftware/include/UDPRESTImplementation.h +++ b/slsReceiverSoftware/include/UDPRESTImplementation.h @@ -89,6 +89,11 @@ class UDPRESTImplementation : protected virtual slsReceiverDefs, public UDPBaseI //Frame indices and numbers caught + /** + * Returns the frame index at start of entire acquisition (including all scans) + */ + uint32_t getStartAcquisitionIndex(); + /** * Returns current Frame Index Caught for an entire acquisition (including all scans) */ @@ -300,8 +305,10 @@ class UDPRESTImplementation : protected virtual slsReceiverDefs, public UDPBaseI * @param c pointer to current file name * @param raw address of pointer, pointing to current frame to send to gui * @param fnum frame number for eiger as it is not in the packet + * @param startAcquisitionIndex is the start index of the acquisition + * @param startFrameIndex is the start index of the scan */ - void readFrame(char* c,char** raw, uint32_t &fnum, uint32_t &fstartind); + void readFrame(char* c,char** raw, uint32_t &fnum, uint32_t &startAcquisitionIndex, uint32_t &startFrameIndex); /** * Closes all files diff --git a/slsReceiverSoftware/include/UDPStandardImplementation.h b/slsReceiverSoftware/include/UDPStandardImplementation.h index dca52e6a4..bad7f7a2e 100644 --- a/slsReceiverSoftware/include/UDPStandardImplementation.h +++ b/slsReceiverSoftware/include/UDPStandardImplementation.h @@ -68,6 +68,11 @@ class UDPStandardImplementation: private virtual slsReceiverDefs, public UDPBase //Frame indices and numbers caught + /** + * Returns the frame index at start of entire acquisition (including all scans) + */ + //uint32_t getStartAcquisitionIndex(); + /** * Returns current Frame Index Caught for an entire acquisition (including all scans) */ @@ -290,8 +295,11 @@ class UDPStandardImplementation: private virtual slsReceiverDefs, public UDPBase * @param c pointer to current file name * @param raw address of pointer, pointing to current frame to send to gui * @param fnum frame number for eiger as it is not in the packet + * @param startAcquisitionIndex is the start index of the acquisition + * @param startFrameIndex is the start index of the scan */ - void readFrame(char* c,char** raw, uint32_t &fnum, uint32_t &fstartind); + void readFrame(char* c,char** raw, uint32_t &fnum, uint32_t &startAcquisitionIndex, uint32_t &startFrameIndex); + /** * Closes all files * @param ithr thread index diff --git a/slsReceiverSoftware/src/UDPBaseImplementation.cpp b/slsReceiverSoftware/src/UDPBaseImplementation.cpp index 8b2cdb598..c70be5b7d 100644 --- a/slsReceiverSoftware/src/UDPBaseImplementation.cpp +++ b/slsReceiverSoftware/src/UDPBaseImplementation.cpp @@ -155,6 +155,8 @@ int UDPBaseImplementation::getFramesCaught(){ FILE_LOG(logDEBUG) << __AT__ << " int UDPBaseImplementation::getTotalFramesCaught(){ FILE_LOG(logDEBUG) << __AT__ << " starting";return (totalPacketsCaught/packetsPerFrame);} +uint32_t UDPBaseImplementation::getStartAcquisitionIndex(){ FILE_LOG(logDEBUG) << __AT__ << " starting";return startAcquisitionIndex;} + uint32_t UDPBaseImplementation::getStartFrameIndex(){ FILE_LOG(logDEBUG) << __AT__ << " starting";return startFrameIndex;} uint32_t UDPBaseImplementation::getFrameIndex(){ FILE_LOG(logDEBUG) << __AT__ << " starting"; @@ -642,36 +644,33 @@ void UDPBaseImplementation::setupFifoStructure(){ FILE_LOG(logDEBUG) << __AT__ < /** acquisition functions */ -void UDPBaseImplementation::readFrame(char* c,char** raw, uint32_t &fnum, uint32_t& fstartind){ - FILE_LOG(logDEBUG) << __AT__ << " starting"; - - //point to gui data - if (guiData == NULL) - guiData = latestData; - - //copy data and filename - strcpy(c,guiFileName); - fnum = guiFrameNumber; - fstartind = getStartFrameIndex(); - - //could not get gui data - if(!guiDataReady){ - *raw = NULL; - } - //data ready, set guidata to receive new data - else{ - *raw = guiData; - guiData = NULL; - - pthread_mutex_lock(&dataReadyMutex); - guiDataReady = 0; - pthread_mutex_unlock(&dataReadyMutex); - if((nFrameToGui) && (writerthreads_mask)){ - /*if(nFrameToGui){*/ - //release after getting data - sem_post(&smp); - } - } +void UDPBaseImplementation::readFrame(char* c,char** raw, uint32_t &fnum, uint32_t &startAcquisitionIndex, uint32_t &startFrameIndex){ + FILE_LOG(logDEBUG) << __AT__ << " called"; + //point to gui data + if (guiData == NULL){ + guiData = latestData; + } + + //copy data and filename + strcpy(c,guiFileName); + fnum = guiFrameNumber; + startAcquisitionIndex = getStartAcquisitionIndex(); + startFrameIndex = getStartFrameIndex(); + + + //could not get gui data + if(!guiDataReady){ + *raw = NULL; + } + //data ready, set guidata to receive new data + else{ + *raw = guiData; + guiData = NULL; + if((nFrameToGui) && (writerthreads_mask)){ + //release after getting data + sem_post(&smp); + } + } } diff --git a/slsReceiverSoftware/src/UDPRESTImplementation.cpp b/slsReceiverSoftware/src/UDPRESTImplementation.cpp index be929dd0d..b03f92a18 100644 --- a/slsReceiverSoftware/src/UDPRESTImplementation.cpp +++ b/slsReceiverSoftware/src/UDPRESTImplementation.cpp @@ -187,6 +187,11 @@ int UDPRESTImplementation::getTotalFramesCaught(){ return (totalPacketsCaught/packetsPerFrame); } +uint32_t UDPRESTImplementation::getStartAcquisitionIndex(){ + FILE_LOG(logDEBUG) << __AT__ << " called"; + return startAcquisitionIndex; +} + uint32_t UDPRESTImplementation::getStartFrameIndex(){ FILE_LOG(logDEBUG) << __AT__ << " called"; return startFrameIndex; @@ -577,16 +582,19 @@ void UDPRESTImplementation::setupFifoStructure(){ /** acquisition functions */ -void UDPRESTImplementation::readFrame(char* c,char** raw, uint32_t &fnum, uint32_t &fstartind){ +void UDPRESTImplementation::readFrame(char* c,char** raw, uint32_t &fnum, uint32_t &startAcquisitionIndex, uint32_t &startFrameIndex){ FILE_LOG(logDEBUG) << __AT__ << " called"; //point to gui data - if (guiData == NULL) + if (guiData == NULL){ guiData = latestData; + } //copy data and filename strcpy(c,guiFileName); fnum = guiFrameNumber; - fstartind = getStartFrameIndex(); + startAcquisitionIndex = getStartAcquisitionIndex(); + startFrameIndex = getStartFrameIndex(); + //could not get gui data if(!guiDataReady){ @@ -596,12 +604,7 @@ void UDPRESTImplementation::readFrame(char* c,char** raw, uint32_t &fnum, uint32 else{ *raw = guiData; guiData = NULL; - - pthread_mutex_lock(&dataReadyMutex); - guiDataReady = 0; - pthread_mutex_unlock(&dataReadyMutex); if((nFrameToGui) && (writerthreads_mask)){ - /*if(nFrameToGui){*/ //release after getting data sem_post(&smp); } diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 55e8775f7..f44ed6017 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -352,6 +352,8 @@ int UDPStandardImplementation::setDetectorType(detectorType det){ FILE_LOG(logD //int UDPStandardImplementation::getTotalFramesCaught(){return (totalPacketsCaught/packetsPerFrame);} +//uint32_t UDPStandardImplementation::getStartAcquisitionIndex(){return startAcquisitionIndex;} + //uint32_t UDPStandardImplementation::getStartFrameIndex(){return startFrameIndex;} /* @@ -868,7 +870,7 @@ void UDPStandardImplementation::setupFifoStructure(){ /** acquisition functions */ -void UDPStandardImplementation::readFrame(char* c,char** raw, uint32_t &fnum, uint32_t &fstartind){ +void UDPStandardImplementation::readFrame(char* c,char** raw, uint32_t &fnum, uint32_t &startAcquisitionIndex, uint32_t &startFrameIndex){ FILE_LOG(logDEBUG) << __AT__ << " called"; //point to gui data if (guiData == NULL){ @@ -881,7 +883,9 @@ void UDPStandardImplementation::readFrame(char* c,char** raw, uint32_t &fnum, ui //copy data and filename strcpy(c,guiFileName); fnum = guiFrameNumber; - fstartind = getStartFrameIndex(); + startAcquisitionIndex = getStartAcquisitionIndex(); + startFrameIndex = getStartFrameIndex(); + //could not get gui data if(!guiDataReady){ @@ -975,9 +979,13 @@ cout << "copyframe" << endl; #endif //nth frame read, block current process if the guireader hasnt read it yet if(nFrameToGui){ - //cout<<"waiting after copying"<fnum); if(dynamicRange != 32) tempframenum += (startFrameIndex-1); //eiger frame numbers start at 1, so need to -1 - else + else{ + cout << " 32 bit eiger could be "<< dec << htonl(*(unsigned int*)((eiger_image_header *)((char*)(wbuf[ithread] + HEADER_SIZE_NUM_TOT_PACKETS)))->fnum) << endl; + cout << " 32 bit eiger32 could be "<< dec << htonl(*(unsigned int*)((eiger_image_header32 *)((char*)(wbuf[ithread] + HEADER_SIZE_NUM_TOT_PACKETS)))->fnum) << endl; tempframenum = ((tempframenum / EIGER_32BIT_INITIAL_CONSTANT) + startFrameIndex)-1;//eiger 32 bit mode is a multiple of 17c. +startframeindex for scans + } }else if ((myDetectorType == GOTTHARD) && (shortFrame == -1)) tempframenum = (((((uint32_t)(*((uint32_t*)(wbuf[ithread] + HEADER_SIZE_NUM_TOT_PACKETS))))+1)& (frameIndexMask)) >> frameIndexOffset); else @@ -1936,10 +1947,10 @@ int UDPStandardImplementation::startWriting(){ currframenum = tempframenum; pthread_mutex_unlock(&progress_mutex); } -//#ifdef VERYDEBUG +#ifdef VERYDEBUG if(myDetectorType == EIGER) cout << endl <push(buffer[ithread]); #ifdef FIFO_DEBUG @@ -2261,8 +2272,13 @@ void UDPStandardImplementation::stopWriting(int ithread, char* wbuffer[]){ //report cprintf(GREEN, "Status: Run Finished\n"); - cprintf(GREEN, "Total Packets Caught:%d\n", totalPacketsCaught); - cprintf(GREEN, "Total Frames Caught:%d\n",(totalPacketsCaught/packetsPerFrame)); + if(!totalPacketsCaught){ + cprintf(RED, "Total Packets Caught:%d\n", totalPacketsCaught); + cprintf(RED, "Total Frames Caught:%d\n",(totalPacketsCaught/packetsPerFrame)); + }else{ + cprintf(GREEN, "Total Packets Caught:%d\n", totalPacketsCaught); + cprintf(GREEN, "Total Frames Caught:%d\n",(totalPacketsCaught/packetsPerFrame)); + } //acquisition end if (acquisitionFinishedCallBack) acquisitionFinishedCallBack((totalPacketsCaught/packetsPerFrame), pAcquisitionFinished); diff --git a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp index 8c3815c19..23d1d0147 100644 --- a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp +++ b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp @@ -977,7 +977,9 @@ int slsReceiverTCPIPInterface::read_frame(){ int slsReceiverTCPIPInterface::moench_read_frame(){ ret=OK; char fName[MAX_STR_LENGTH]=""; - int arg = -1,i; + int acquisitionIndex = -1; + int frameIndex= -1; + int i; int bufferSize = MOENCH_BUFFER_SIZE; @@ -990,7 +992,8 @@ int slsReceiverTCPIPInterface::moench_read_frame(){ char* raw = new char[bufferSize]; - uint32_t startIndex=0; + uint32_t startAcquisitionIndex=0; + uint32_t startFrameIndex=0; uint32_t index = 0,bindex = 0, offset=0; strcpy(mess,"Could not read frame\n"); @@ -1001,18 +1004,18 @@ int slsReceiverTCPIPInterface::moench_read_frame(){ /**send garbage with -1 index to try again*/ if(!receiverBase->getFramesCaught()){ - arg = -1; + startAcquisitionIndex = -1; cout<<"haven't caught any frame yet"<getStartFrameIndex();*/ - receiverBase->readFrame(fName,&raw,index,startIndex); + receiverBase->readFrame(fName,&raw,index,startAcquisitionIndex,startFrameIndex); /**send garbage with -1 index to try again*/ if (raw == NULL){ - arg = -1; + startAcquisitionIndex = -1; #ifdef VERBOSE cout<<"data not ready for gui yet"<SendDataOnly(fName,MAX_STR_LENGTH); - socket->SendDataOnly(&arg,sizeof(arg)); + socket->SendDataOnly(&acquisitionIndex,sizeof(acquisitionIndex)); + socket->SendDataOnly(&frameIndex,sizeof(frameIndex)); socket->SendDataOnly(retval,MOENCH_DATA_BYTES); } //return ok/fail @@ -1135,7 +1151,9 @@ int slsReceiverTCPIPInterface::moench_read_frame(){ int slsReceiverTCPIPInterface::gotthard_read_frame(){ ret=OK; char fName[MAX_STR_LENGTH]=""; - int arg = -1,i; + int acquisitionIndex = -1; + int frameIndex= -1; + int i; //retval is a full frame @@ -1161,7 +1179,8 @@ int slsReceiverTCPIPInterface::gotthard_read_frame(){ uint32_t index=0,index2=0; uint32_t pindex=0,pindex2=0; uint32_t bindex=0,bindex2=0; - uint32_t startIndex=0; + uint32_t startAcquisitionIndex=0; + uint32_t startFrameIndex=0; strcpy(mess,"Could not read frame\n"); @@ -1173,16 +1192,16 @@ int slsReceiverTCPIPInterface::gotthard_read_frame(){ /**send garbage with -1 index to try again*/ if(!receiverBase->getFramesCaught()){ - arg=-1; + startAcquisitionIndex=-1; cout<<"haven't caught any frame yet"<getStartFrameIndex();*/ - receiverBase->readFrame(fName,&raw,index,startIndex); + receiverBase->readFrame(fName,&raw,index,startAcquisitionIndex,startFrameIndex); /**send garbage with -1 index to try again*/ if (raw == NULL){ - arg = -1; + startAcquisitionIndex = -1; #ifdef VERBOSE cout<<"data not ready for gui yet"<SendDataOnly(fName,MAX_STR_LENGTH); - socket->SendDataOnly(&arg,sizeof(arg)); + socket->SendDataOnly(&acquisitionIndex,sizeof(acquisitionIndex)); + socket->SendDataOnly(&frameIndex,sizeof(frameIndex)); socket->SendDataOnly(retval,GOTTHARD_DATA_BYTES); } @@ -1297,7 +1332,9 @@ int slsReceiverTCPIPInterface::gotthard_read_frame(){ int slsReceiverTCPIPInterface::eiger_read_frame(){ ret=OK; char fName[MAX_STR_LENGTH]=""; - int arg = -1,i; + int acquisitionIndex = -1; + int frameIndex= -1; + int i; uint32_t index=0; int frameSize = EIGER_ONE_GIGA_ONE_PACKET_SIZE * packetsPerFrame; @@ -1309,7 +1346,8 @@ int slsReceiverTCPIPInterface::eiger_read_frame(){ char* raw = new char[frameSize]; char* origVal = new char[frameSize]; char* retval = new char[dataSize]; - uint32_t startIndex=0; + uint32_t startAcquisitionIndex=0; + uint32_t startFrameIndex=0; strcpy(mess,"Could not read frame\n"); @@ -1320,7 +1358,7 @@ int slsReceiverTCPIPInterface::eiger_read_frame(){ /**send garbage with -1 index to try again*/ if(!receiverBase->getFramesCaught()){ - arg=-1; + startAcquisitionIndex=-1; #ifdef VERBOSE cout<<"haven't caught any frame yet"<readFrame(fName,&raw,index,startIndex); + receiverBase->readFrame(fName,&raw,index,startAcquisitionIndex,startFrameIndex); #ifdef VERBOSE cout << "index:" << dec << index << endl; #endif /**send garbage with -1 index to try again*/ if (raw == NULL){ - arg = -1; + startAcquisitionIndex = -1; #ifdef VERBOSE cout<<"data not ready for gui yet"<SendDataOnly(fName,MAX_STR_LENGTH); - socket->SendDataOnly(&arg,sizeof(arg)); + socket->SendDataOnly(&acquisitionIndex,sizeof(acquisitionIndex)); + socket->SendDataOnly(&frameIndex,sizeof(frameIndex)); socket->SendDataOnly(retval,dataSize); } From 9e78bae6148c9b2f9c107de614289596faf1291f Mon Sep 17 00:00:00 2001 From: Leonardo Sala Date: Mon, 23 Mar 2015 11:18:05 +0100 Subject: [PATCH 078/474] solved bad_alloc --- .../src/UDPRESTImplementation.cpp | 36 +++++++++++++------ 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/slsReceiverSoftware/src/UDPRESTImplementation.cpp b/slsReceiverSoftware/src/UDPRESTImplementation.cpp index be929dd0d..e1b3a1114 100644 --- a/slsReceiverSoftware/src/UDPRESTImplementation.cpp +++ b/slsReceiverSoftware/src/UDPRESTImplementation.cpp @@ -87,7 +87,9 @@ int UDPRESTImplementation::get_rest_state(RestHelper * rest, string *rest_state) }; void UDPRESTImplementation::initialize_REST(){ + FILE_LOG(logDEBUG) << __AT__ << " called"; + FILE_LOG(logDEBUG) << __AT__ << " REST status is initialized: " << isInitialized; if (rest_hostname.empty()) { FILE_LOG(logDEBUG) << __AT__ <<"can't initialize with empty string or NULL for detectorHostname"; @@ -104,7 +106,9 @@ void UDPRESTImplementation::initialize_REST(){ try{ rest->init(rest_hostname, rest_port); code = get_rest_state(rest, &answer); + std::cout << "AAAAAAAa " << answer << std::endl; + if (code != 0){ throw answer; } @@ -133,11 +137,19 @@ void UDPRESTImplementation::initialize_REST(){ ss >> test; - test = "{\"path\":\"" + string( getFilePath() ) + "\"}"; - code = rest->post_json("state/initialize", &answer, test); - FILE_LOG(logDEBUG) << __AT__ << "state/configure got " << code; code = rest->get_json("state", &answer); - FILE_LOG(logDEBUG) << __AT__ << "state got " << code << " " << answer << "\n"; + FILE_LOG(logDEBUG) << __AT__ << " state got " << code << " " << answer << "\n"; + if (answer != "INITIALIZED"){ + test = "{\"path\":\"" + string( getFilePath() ) + "\"}"; + code = rest->post_json("state/initialize", &answer, test); + } + else{ + test = "{\"path\":\"" + string( getFilePath() ) + "\"}"; + code = rest->post_json("state/configure", &answer, test); + } + FILE_LOG(logDEBUG) << __AT__ << " state/configure got " << code; + code = rest->get_json("state", &answer); + FILE_LOG(logDEBUG) << __AT__ << " state got " << code << " " << answer << "\n"; /* @@ -1169,10 +1181,8 @@ int UDPRESTImplementation::startReceiver(char message[]){ initialize_REST(); FILE_LOG(logDEBUG) << __FILE__ << "::" << __func__ << " initialized"; -// #ifdef VERBOSE cout << "Starting Receiver" << endl; -//#endif - + std::string answer; int code; //char *intStr = itoa(a); @@ -1184,17 +1194,21 @@ int UDPRESTImplementation::startReceiver(char message[]){ stringstream ss2; ss2 << getNumberOfFrames(); string str_n = ss2.str(); + + cout << "Starting Receiver" << endl; + std::string request_body = "{\"settings\": {\"bit_depth\": " + str_dr + ", \"nimages\": " + str_n + "}}"; //std::string request_body = "{\"settings\": {\"nimages\":1, \"scanid\":999, \"bit_depth\":16}}"; FILE_LOG(logDEBUG) << __FILE__ << "::" << " sending this configuration body: " << request_body; code = rest->post_json("state/configure", &answer, request_body); - code = rest->get_json("state", &answer); + //code = rest->get_json("state", &answer); + //FILE_LOG(logDEBUG) << __FILE__ << "::" << " got: " << answer; - code = rest->post_json("state/open", &answer); - code = rest->get_json("state", &answer); + //code = rest->post_json("state/open", &answer); + //code = rest->get_json("state", &answer); - status = slsReceiverDefs::RUNNING; + status = RUNNING; //reset listening thread variables /* From 1df89d4ce20357c7815acd56686d3c58054c0eb8 Mon Sep 17 00:00:00 2001 From: Leonardo Sala Date: Mon, 23 Mar 2015 11:41:19 +0100 Subject: [PATCH 079/474] test --- slsReceiverSoftware/include/RestHelper.h | 76 ++++++++++--------- .../src/UDPRESTImplementation.cpp | 7 +- 2 files changed, 43 insertions(+), 40 deletions(-) diff --git a/slsReceiverSoftware/include/RestHelper.h b/slsReceiverSoftware/include/RestHelper.h index b3d679b26..92846750d 100644 --- a/slsReceiverSoftware/include/RestHelper.h +++ b/slsReceiverSoftware/include/RestHelper.h @@ -249,45 +249,47 @@ class RestHelper { * @return */ - int n=0; + int n = 0; int code = -1; - while(nsendRequest( (req) ); - else{ - ostream &os = session->sendRequest( req ) ; - os << request_body; - } - - HTTPResponse res; - istream &is = session->receiveResponse(res); - StreamCopier::copyToString(is, *answer); - code = res.getStatus(); - if (code != 200){ - FILE_LOG(logERROR) << "HTTP ERROR " << res.getStatus() << ": " << res.getReason() ; - code = -1; - } - else - code = 0; - return code; - } - catch (exception& e){ - FILE_LOG(logERROR) << "Exception connecting to "<< full_hostname << ": "<< e.what() << ", sleeping 5 seconds (" << n << "/"<sendRequest( (req) ); + else{ + ostream &os = session->sendRequest( req ) ; + os << request_body; + } + + HTTPResponse res; + istream &is = session->receiveResponse(res); + StreamCopier::copyToString(is, *answer); + code = res.getStatus(); + if (code != 200){ + FILE_LOG(logERROR) << "HTTP ERROR " << res.getStatus() << ": " << res.getReason() ; + code = -1; + } + else + code = 0; + return code; + } + catch (exception& e){ + FILE_LOG(logERROR) << "Exception connecting to "<< full_hostname << ": "<< e.what() << ", sleeping 5 seconds (" << n << "/"<post_json("state/configure", &answer, request_body); - //code = rest->get_json("state", &answer); - //FILE_LOG(logDEBUG) << __FILE__ << "::" << " got: " << answer; + code = rest->get_json("state", &answer); + FILE_LOG(logDEBUG) << __FILE__ << "::" << " got: " << answer; //code = rest->post_json("state/open", &answer); //code = rest->get_json("state", &answer); From e35867227f7fed34610dbfe70c8f517e0d57289d Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Mon, 30 Mar 2015 17:16:31 +0200 Subject: [PATCH 080/474] writing frame number to the file for eiger --- slsReceiverSoftware/include/UDPBaseImplementation.h | 3 ++- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 7 ++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/slsReceiverSoftware/include/UDPBaseImplementation.h b/slsReceiverSoftware/include/UDPBaseImplementation.h index 6450f85f0..779827778 100644 --- a/slsReceiverSoftware/include/UDPBaseImplementation.h +++ b/slsReceiverSoftware/include/UDPBaseImplementation.h @@ -499,7 +499,8 @@ protected: typedef struct { unsigned char num1[4]; - unsigned char num2[4]; + unsigned char num2[3]; + unsigned char num3[1]; } eiger_packet_header; /** max number of listening threads */ diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index f44ed6017..012d675a5 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -2306,8 +2306,13 @@ void UDPStandardImplementation::writeToFile_withoutCompression(char* buf,int num if((enableFileWrite) && (sfilefd)){ offset = HEADER_SIZE_NUM_TOT_PACKETS; - if(myDetectorType == EIGER) + if(myDetectorType == EIGER){ offset += EIGER_HEADER_LENGTH; + (*(uint32_t*)(((eiger_packet_header *)((char*)(buf + offset)))->num1)) = framenum; + //cprintf(RED, "framenum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf + offset)))->num1))); + //cprintf(RED, "2packetnumber:0x%x\n", (*(uint16_t*)(((eiger_packet_header *)((char*)(buf + offset)))->num3))); + //cprintf(RED, "22packetnumber:0x%x\n",(*(uint16_t*)(((eiger_packet_header *)((char*)(buf + offset +1040)))->num3))); + } while(numpackets > 0){ //for progress and packet loss calculation(new files) From b5e8c104dbb6b0048dc9094bbfba8a4ac2753397 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 31 Mar 2015 14:45:41 +0200 Subject: [PATCH 081/474] printouts for eigermapping --- .../src/UDPStandardImplementation.cpp | 6 ++-- .../src/slsReceiverTCPIPInterface.cpp | 28 +++++++++++++++++++ 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 012d675a5..0e5adf38e 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -2309,9 +2309,9 @@ void UDPStandardImplementation::writeToFile_withoutCompression(char* buf,int num if(myDetectorType == EIGER){ offset += EIGER_HEADER_LENGTH; (*(uint32_t*)(((eiger_packet_header *)((char*)(buf + offset)))->num1)) = framenum; - //cprintf(RED, "framenum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf + offset)))->num1))); - //cprintf(RED, "2packetnumber:0x%x\n", (*(uint16_t*)(((eiger_packet_header *)((char*)(buf + offset)))->num3))); - //cprintf(RED, "22packetnumber:0x%x\n",(*(uint16_t*)(((eiger_packet_header *)((char*)(buf + offset +1040)))->num3))); + cprintf(RED, "framenum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf + offset)))->num1))); + cprintf(RED, "2packetnumber:0x%x\n", (*(uint16_t*)(((eiger_packet_header *)((char*)(buf + offset)))->num3))); + cprintf(RED, "22packetnumber:0x%x\n",(*(uint16_t*)(((eiger_packet_header *)((char*)(buf + offset +1040)))->num3))); } while(numpackets > 0){ diff --git a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp index 23d1d0147..1daf40ae0 100644 --- a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp +++ b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp @@ -1489,6 +1489,19 @@ int slsReceiverTCPIPInterface::eiger_read_frame(){ } + /*int inum = 0; + //dr = 16, hence uint16_t + for(inum = 0; inum < 2; inum++) + cprintf(YELLOW,"before htonl %d,0 :%d\n",inum,((uint16_t)(*((uint16_t*)((char*)(retval+(inum*(dynamicrange/8)))))))); + for(inum = 254; inum < 258; inum++) + cprintf(YELLOW,"before htonl %d,0 :%d\n",inum,((uint16_t)(*((uint16_t*)((char*)(retval+(inum*(dynamicrange/8)))))))); + for(inum = 0; inum < 2; inum++) + cprintf(YELLOW,"before htonl %d,2 :%d\n",inum,((uint16_t)(*((uint16_t*)((char*)(retval+((2048+inum)*(dynamicrange/8)))))))); + for(inum = 254; inum < 258; inum++) + cprintf(YELLOW,"before htonl %d,2 :%d\n",inum,((uint16_t)(*((uint16_t*)((char*)(retval+((2048+inum)*(dynamicrange/8)))))))); + + */ + //64 bit htonl cuz of endianness for(i=0;i<(1024*(16*dynamicrange)*2)/8;i++){ (*(((uint64_t*)retval)+i)) = be64toh(((uint64_t)(*(((uint64_t*)retval)+i)))); @@ -1501,6 +1514,21 @@ int slsReceiverTCPIPInterface::eiger_read_frame(){ (*(((uint64_t*)retval)+i)) = temp; */ } + + /* + //dr = 16, hence uint16_t + for(inum = 0; inum < 2; inum++) + cprintf(MAGENTA,"after htonl %d,0 :%d\n",inum,((uint16_t)(*((uint16_t*)((char*)(retval+(inum*(dynamicrange/8)))))))); + for(inum = 254; inum < 258; inum++) + cprintf(MAGENTA,"after htonl %d,0 :%d\n",inum,((uint16_t)(*((uint16_t*)((char*)(retval+(inum*(dynamicrange/8)))))))); + for(inum = 0; inum < 2; inum++) + cprintf(MAGENTA,"after htonl %d,2 :%d\n",inum,((uint16_t)(*((uint16_t*)((char*)(retval+((2048+inum)*(dynamicrange/8)))))))); + for(inum = 254; inum < 258; inum++) + cprintf(MAGENTA,"after htonl %d,2 :%d\n",inum,((uint16_t)(*((uint16_t*)((char*)(retval+((2048+inum)*(dynamicrange/8)))))))); + */ + + + acquisitionIndex = index-startAcquisitionIndex; if(acquisitionIndex == -1) startFrameIndex = -1; From 6cd28165ca79c4ea9eb5043ce2acdc2ccec75de7 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Fri, 10 Apr 2015 17:11:26 +0200 Subject: [PATCH 082/474] top image reconstruct works with make flga --- .../include/UDPBaseImplementation.h | 4 ++-- .../src/UDPStandardImplementation.cpp | 20 +++++++++++++++---- .../src/slsReceiverTCPIPInterface.cpp | 10 +++++----- 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/slsReceiverSoftware/include/UDPBaseImplementation.h b/slsReceiverSoftware/include/UDPBaseImplementation.h index 779827778..eac9fd0da 100644 --- a/slsReceiverSoftware/include/UDPBaseImplementation.h +++ b/slsReceiverSoftware/include/UDPBaseImplementation.h @@ -498,8 +498,8 @@ protected: /** structure of an eiger image header*/ typedef struct { - unsigned char num1[4]; - unsigned char num2[3]; + unsigned char num1[6]; + unsigned char num2[1]; unsigned char num3[1]; } eiger_packet_header; diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 0e5adf38e..4a337fce2 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1963,6 +1963,7 @@ int UDPStandardImplementation::startWriting(){ }else if (numpackets > 0){ for(i=0;inum1)) = framenum; - cprintf(RED, "framenum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf + offset)))->num1))); - cprintf(RED, "2packetnumber:0x%x\n", (*(uint16_t*)(((eiger_packet_header *)((char*)(buf + offset)))->num3))); - cprintf(RED, "22packetnumber:0x%x\n",(*(uint16_t*)(((eiger_packet_header *)((char*)(buf + offset +1040)))->num3))); +#ifdef WRITE_HEADERS + for (int i = 0; i < packetsPerFrame; i++) + (*(uint32_t*)(((eiger_packet_header *)((char*)(buf + offset + 1040*i)))->num1)) = framenum; + + cprintf(RED, "\np1 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf + offset)))->num1))); + cprintf(RED, "p1:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset)))->num2))); + cprintf(RED, "p1 num:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset)))->num3))); + cprintf(RED, "p2 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf + offset +1040)))->num1))); + cprintf(RED, "p2:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset +1040)))->num2))); + cprintf(RED, "p2 num:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset +1040)))->num3))); + cprintf(RED, "p3 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf + offset + 2080)))->num1))); + cprintf(RED, "p3:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset +2080)))->num2))); + cprintf(RED, "p3 num:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset +2080)))->num3))); + +#endif } while(numpackets > 0){ diff --git a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp index 1daf40ae0..97b87e68b 100644 --- a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp +++ b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp @@ -1488,8 +1488,8 @@ int slsReceiverTCPIPInterface::eiger_read_frame(){ } } - - /*int inum = 0; +/* + int inum = 0; //dr = 16, hence uint16_t for(inum = 0; inum < 2; inum++) cprintf(YELLOW,"before htonl %d,0 :%d\n",inum,((uint16_t)(*((uint16_t*)((char*)(retval+(inum*(dynamicrange/8)))))))); @@ -1499,8 +1499,8 @@ int slsReceiverTCPIPInterface::eiger_read_frame(){ cprintf(YELLOW,"before htonl %d,2 :%d\n",inum,((uint16_t)(*((uint16_t*)((char*)(retval+((2048+inum)*(dynamicrange/8)))))))); for(inum = 254; inum < 258; inum++) cprintf(YELLOW,"before htonl %d,2 :%d\n",inum,((uint16_t)(*((uint16_t*)((char*)(retval+((2048+inum)*(dynamicrange/8)))))))); +*/ - */ //64 bit htonl cuz of endianness for(i=0;i<(1024*(16*dynamicrange)*2)/8;i++){ @@ -1515,7 +1515,7 @@ int slsReceiverTCPIPInterface::eiger_read_frame(){ */ } - /* +/* //dr = 16, hence uint16_t for(inum = 0; inum < 2; inum++) cprintf(MAGENTA,"after htonl %d,0 :%d\n",inum,((uint16_t)(*((uint16_t*)((char*)(retval+(inum*(dynamicrange/8)))))))); @@ -1525,7 +1525,7 @@ int slsReceiverTCPIPInterface::eiger_read_frame(){ cprintf(MAGENTA,"after htonl %d,2 :%d\n",inum,((uint16_t)(*((uint16_t*)((char*)(retval+((2048+inum)*(dynamicrange/8)))))))); for(inum = 254; inum < 258; inum++) cprintf(MAGENTA,"after htonl %d,2 :%d\n",inum,((uint16_t)(*((uint16_t*)((char*)(retval+((2048+inum)*(dynamicrange/8)))))))); - */ +*/ From 15bbb099d378500ac369f35b030ff0ee0cba0cb0 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 14 Apr 2015 17:11:56 +0200 Subject: [PATCH 083/474] for mapping 32 bit eiger --- .../include/UDPBaseImplementation.h | 9 +- .../src/UDPStandardImplementation.cpp | 131 ++++++++++++++---- .../src/slsReceiverTCPIPInterface.cpp | 16 +-- 3 files changed, 118 insertions(+), 38 deletions(-) diff --git a/slsReceiverSoftware/include/UDPBaseImplementation.h b/slsReceiverSoftware/include/UDPBaseImplementation.h index eac9fd0da..4801c751e 100644 --- a/slsReceiverSoftware/include/UDPBaseImplementation.h +++ b/slsReceiverSoftware/include/UDPBaseImplementation.h @@ -489,18 +489,19 @@ protected: /** structure of an eiger image header*/ typedef struct { - unsigned char header_before[35]; + unsigned char header_before[19]; unsigned char fnum[4]; - unsigned char header_after[9]; + unsigned char header_after[25]; } eiger_image_header32; /** structure of an eiger image header*/ typedef struct { - unsigned char num1[6]; - unsigned char num2[1]; + unsigned char num1[4]; + unsigned char num2[2]; unsigned char num3[1]; + unsigned char num4[1]; } eiger_packet_header; /** max number of listening threads */ diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 4a337fce2..93ad2c8d1 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1860,12 +1860,13 @@ int UDPStandardImplementation::startWriting(){ thread_started = 1; + int totalheader = HEADER_SIZE_NUM_TOT_PACKETS + EIGER_HEADER_LENGTH; int numpackets, nf; uint32_t tempframenum; char* wbuf[numListeningThreads];//interleaved char *d=new char[bufferSize*numListeningThreads]; int xmax=0,ymax=0; - int ret,i; + int ret,i,j; int packetsPerThread = packetsPerFrame/numListeningThreads; while(1){ @@ -1926,14 +1927,16 @@ int UDPStandardImplementation::startWriting(){ //for progress if(myDetectorType == EIGER){ - tempframenum = htonl(*(unsigned int*)((eiger_image_header *)((char*)(wbuf[ithread] + HEADER_SIZE_NUM_TOT_PACKETS)))->fnum); + if(dynamicRange != 32) - tempframenum += (startFrameIndex-1); //eiger frame numbers start at 1, so need to -1 - else{ - cout << " 32 bit eiger could be "<< dec << htonl(*(unsigned int*)((eiger_image_header *)((char*)(wbuf[ithread] + HEADER_SIZE_NUM_TOT_PACKETS)))->fnum) << endl; - cout << " 32 bit eiger32 could be "<< dec << htonl(*(unsigned int*)((eiger_image_header32 *)((char*)(wbuf[ithread] + HEADER_SIZE_NUM_TOT_PACKETS)))->fnum) << endl; - tempframenum = ((tempframenum / EIGER_32BIT_INITIAL_CONSTANT) + startFrameIndex)-1;//eiger 32 bit mode is a multiple of 17c. +startframeindex for scans - } + tempframenum = htonl(*(unsigned int*)((eiger_image_header *)((char*)(wbuf[ithread] + HEADER_SIZE_NUM_TOT_PACKETS)))->fnum); + else + tempframenum = htonl(*(unsigned int*)((eiger_image_header32 *)((char*)(wbuf[ithread] + HEADER_SIZE_NUM_TOT_PACKETS)))->fnum); + + + tempframenum += (startFrameIndex-1); //eiger frame numbers start at 1, so need to -1 + //tempframenum = ((tempframenum / EIGER_32BIT_INITIAL_CONSTANT) + startFrameIndex)-1;//eiger 32 bit mode is a multiple of 17c. +startframeindex for scans + }else if ((myDetectorType == GOTTHARD) && (shortFrame == -1)) tempframenum = (((((uint32_t)(*((uint32_t*)(wbuf[ithread] + HEADER_SIZE_NUM_TOT_PACKETS))))+1)& (frameIndexMask)) >> frameIndexOffset); else @@ -1961,9 +1964,53 @@ int UDPStandardImplementation::startWriting(){ /* for eiger 32 bit mode, currframenum like gotthard, does not start from 0 or 1 */ rawDataReadyCallBack(currframenum, wbuf[i], numpackets * onePacketSize, sfilefd, guiData,pRawDataReady); }else if (numpackets > 0){ - for(i=0;inum1)) = currframenum; + //for 32 bit,port number needs to be changed and packet number reconstructed + if(dynamicRange == 32){ + for (i = 0; i < packetsPerFrame/4; i++){ + //new packet number that has space for 16 bit + (*(uint16_t*)(((eiger_packet_header *)((char*)(wbuf[j] + totalheader + EIGER_ONE_GIGA_ONE_PACKET_SIZE*i)))->num2)) + = ((*(uint8_t*)(((eiger_packet_header *)((char*)(wbuf[j] + totalheader + EIGER_ONE_GIGA_ONE_PACKET_SIZE*i)))->num4))); + + //new port number as its the same everywhere for 32 bit!! + if(!j) (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuf[j] + totalheader + EIGER_ONE_GIGA_ONE_PACKET_SIZE*i)))->num3)) = 0x00; + + +#ifdef VERYDEBUG + cprintf(RED, "%d - 0x%x - %d - %d\n", i, + (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuf[j] + totalheader +i*EIGER_ONE_GIGA_ONE_PACKET_SIZE)))->num3)), + (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuf[j] + totalheader +i*EIGER_ONE_GIGA_ONE_PACKET_SIZE)))->num4)), + (*(uint16_t*)(((eiger_packet_header *)((char*)(wbuf[j] + totalheader +i*EIGER_ONE_GIGA_ONE_PACKET_SIZE)))->num2))); +#endif + } + for (i = packetsPerFrame/4; i < packetsPerFrame/2; i++){ + //new packet number that has space for 16 bit + (*(uint16_t*)(((eiger_packet_header *)((char*)(wbuf[j] + totalheader + EIGER_ONE_GIGA_ONE_PACKET_SIZE*i)))->num2)) + = ((*(uint8_t*)(((eiger_packet_header *)((char*)(wbuf[j] + totalheader + EIGER_ONE_GIGA_ONE_PACKET_SIZE*i)))->num4))+(packetsPerFrame/4)); + + //new port number as its the same everywhere for 32 bit!! + if(!j) (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuf[j] + totalheader + EIGER_ONE_GIGA_ONE_PACKET_SIZE*i)))->num3)) = 0x00; + + +#ifdef VERYDEBUG + cprintf(RED, "%d -0x%x - %d - %d\n", i, + (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuf[j] + totalheader +i*EIGER_ONE_GIGA_ONE_PACKET_SIZE)))->num3)), + (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuf[j] + totalheader +i*EIGER_ONE_GIGA_ONE_PACKET_SIZE)))->num4)), + (*(uint16_t*)(((eiger_packet_header *)((char*)(wbuf[j] + totalheader +i*EIGER_ONE_GIGA_ONE_PACKET_SIZE)))->num2))); +#endif + } + } + } +#endif + + writeToFile_withoutCompression(wbuf[j], numpackets,currframenum); + } #ifdef VERYDEBUG cout << "written everyting" << endl; #endif @@ -2074,9 +2121,13 @@ int UDPStandardImplementation::startWriting(){ void UDPStandardImplementation::startFrameIndices(int ithread){ FILE_LOG(logDEBUG) << __AT__ << " called"; - if (myDetectorType == EIGER) + if (myDetectorType == EIGER){ //add currframenum later in this method for scans - startFrameIndex = htonl(*(unsigned int*)((eiger_image_header *)((char*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS)))->fnum); + if(dynamicRange == 32) + startFrameIndex = htonl(*(unsigned int*)((eiger_image_header32 *)((char*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS)))->fnum); + else + startFrameIndex = htonl(*(unsigned int*)((eiger_image_header *)((char*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS)))->fnum); + } //gotthard has +1 for frame number and not a short frame else if ((myDetectorType == GOTTHARD) && (shortFrame == -1)) startFrameIndex = (((((uint32_t)(*((uint32_t*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS))))+1) @@ -2131,7 +2182,7 @@ int i; //free buffer if(rc <= 0){ - cout << ithread << "Discarding empty frame" << endl; + cout << ithread << "Discarding empty frame/ End of acquisition" << endl; fifoFree[ithread]->push(buffer[ithread]); #ifdef FIFO_DEBUG cprintf(BLUE,"%d listener empty buffer pushed into fifofree %x\n", ithread, (void*)(buffer[ithread])); @@ -2310,19 +2361,47 @@ void UDPStandardImplementation::writeToFile_withoutCompression(char* buf,int num if(myDetectorType == EIGER){ offset += EIGER_HEADER_LENGTH; #ifdef WRITE_HEADERS - for (int i = 0; i < packetsPerFrame; i++) - (*(uint32_t*)(((eiger_packet_header *)((char*)(buf + offset + 1040*i)))->num1)) = framenum; - - cprintf(RED, "\np1 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf + offset)))->num1))); - cprintf(RED, "p1:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset)))->num2))); - cprintf(RED, "p1 num:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset)))->num3))); - cprintf(RED, "p2 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf + offset +1040)))->num1))); - cprintf(RED, "p2:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset +1040)))->num2))); - cprintf(RED, "p2 num:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset +1040)))->num3))); - cprintf(RED, "p3 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf + offset + 2080)))->num1))); - cprintf(RED, "p3:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset +2080)))->num2))); - cprintf(RED, "p3 num:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset +2080)))->num3))); - +#ifdef VERY_DEBUG + int k = 0; + if(dynamicRange != 32){ + cprintf(RED, "\np1 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf + offset+k*1040)))->num1))); + cprintf(RED, "p1:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset+k*1040)))->num3))); + cprintf(RED, "p0 num:%d - %d\n", k, (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset+k*1040)))->num4))); + k = 1; + cprintf(RED, "p2 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num1))); + cprintf(RED, "p2:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num3))); + cprintf(RED, "p1 num:%d - %d\n", k,(*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num4))); + k = 2; + cprintf(RED, "p3 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf + offset + k*1040)))->num1))); + cprintf(RED, "p3:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num3))); + cprintf(RED, "p2 num:%d - %d\n", k,(*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num4))); + }else{ + k = 0; + cprintf(RED, "\np1 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf + offset+k*1040)))->num1))); + cprintf(RED, "p1:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset+k*1040)))->num3))); + cprintf(RED, "p0 num:%d - %d\n", k, (*(uint16_t*)(((eiger_packet_header *)((char*)(buf + offset+k*1040)))->num2))); + k = 1; + cprintf(RED, "p2 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num1))); + cprintf(RED, "p2:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num3))); + cprintf(RED, "p1 num:%d - %d\n", k, (*(uint16_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num2))); + k = 2; + cprintf(RED, "p3 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf + offset + k*1040)))->num1))); + cprintf(RED, "p3:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num3))); + cprintf(RED, "p2 num:%d - %d\n", k, (*(uint16_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num2))); + k = 256; + cprintf(RED, "p257 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf + offset + k*1040)))->num1))); + cprintf(RED, "p257:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num3))); + cprintf(RED, "p256 num:%d - %d\n", k, (*(uint16_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num2))); + k = 512; + cprintf(RED, "p513 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf + offset + k*1040)))->num1))); + cprintf(RED, "p513:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num3))); + cprintf(RED, "p512 num:%d - %d\n", k, (*(uint16_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num2))); + k = 768; + cprintf(RED, "p769 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf + offset + k*1040)))->num1))); + cprintf(RED, "p769:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num3))); + cprintf(RED, "p768 num:%d - %d\n", k,(*(uint16_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num2))); + } +#endif #endif } while(numpackets > 0){ diff --git a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp index 97b87e68b..240784ea5 100644 --- a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp +++ b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp @@ -1492,13 +1492,13 @@ int slsReceiverTCPIPInterface::eiger_read_frame(){ int inum = 0; //dr = 16, hence uint16_t for(inum = 0; inum < 2; inum++) - cprintf(YELLOW,"before htonl %d,0 :%d\n",inum,((uint16_t)(*((uint16_t*)((char*)(retval+(inum*(dynamicrange/8)))))))); + cprintf(YELLOW,"before htonl %d,0 :%d\n",inum,((uint8_t)(*((uint8_t*)((char*)(retval+(inum*(dynamicrange/8)))))))); for(inum = 254; inum < 258; inum++) - cprintf(YELLOW,"before htonl %d,0 :%d\n",inum,((uint16_t)(*((uint16_t*)((char*)(retval+(inum*(dynamicrange/8)))))))); + cprintf(YELLOW,"before htonl %d,0 :%d\n",inum,((uint8_t)(*((uint8_t*)((char*)(retval+(inum*(dynamicrange/8)))))))); for(inum = 0; inum < 2; inum++) - cprintf(YELLOW,"before htonl %d,2 :%d\n",inum,((uint16_t)(*((uint16_t*)((char*)(retval+((2048+inum)*(dynamicrange/8)))))))); + cprintf(YELLOW,"before htonl %d,2 :%d\n",inum,((uint8_t)(*((uint8_t*)((char*)(retval+((2048+inum)*(dynamicrange/8)))))))); for(inum = 254; inum < 258; inum++) - cprintf(YELLOW,"before htonl %d,2 :%d\n",inum,((uint16_t)(*((uint16_t*)((char*)(retval+((2048+inum)*(dynamicrange/8)))))))); + cprintf(YELLOW,"before htonl %d,2 :%d\n",inum,((uint8_t)(*((uint8_t*)((char*)(retval+((2048+inum)*(dynamicrange/8)))))))); */ @@ -1518,13 +1518,13 @@ int slsReceiverTCPIPInterface::eiger_read_frame(){ /* //dr = 16, hence uint16_t for(inum = 0; inum < 2; inum++) - cprintf(MAGENTA,"after htonl %d,0 :%d\n",inum,((uint16_t)(*((uint16_t*)((char*)(retval+(inum*(dynamicrange/8)))))))); + cprintf(MAGENTA,"after htonl %d,0 :%d\n",inum,((uint8_t)(*((uint8_t*)((char*)(retval+(inum*(dynamicrange/8)))))))); for(inum = 254; inum < 258; inum++) - cprintf(MAGENTA,"after htonl %d,0 :%d\n",inum,((uint16_t)(*((uint16_t*)((char*)(retval+(inum*(dynamicrange/8)))))))); + cprintf(MAGENTA,"after htonl %d,0 :%d\n",inum,((uint8_t)(*((uint8_t*)((char*)(retval+(inum*(dynamicrange/8)))))))); for(inum = 0; inum < 2; inum++) - cprintf(MAGENTA,"after htonl %d,2 :%d\n",inum,((uint16_t)(*((uint16_t*)((char*)(retval+((2048+inum)*(dynamicrange/8)))))))); + cprintf(MAGENTA,"after htonl %d,2 :%d\n",inum,((uint8_t)(*((uint8_t*)((char*)(retval+((2048+inum)*(dynamicrange/8)))))))); for(inum = 254; inum < 258; inum++) - cprintf(MAGENTA,"after htonl %d,2 :%d\n",inum,((uint16_t)(*((uint16_t*)((char*)(retval+((2048+inum)*(dynamicrange/8)))))))); + cprintf(MAGENTA,"after htonl %d,2 :%d\n",inum,((uint8_t)(*((uint8_t*)((char*)(retval+((2048+inum)*(dynamicrange/8)))))))); */ From 992a298abc9be2ceb9e8be5e16912b3537350f6b Mon Sep 17 00:00:00 2001 From: Anna Bergamaschi Date: Tue, 21 Apr 2015 15:09:50 +0200 Subject: [PATCH 084/474] added dunny implementation as an example to combine TCPIP interface and custom UDP reciever --- slsReceiverSoftware/Makefile | 9 + .../include/dummyUDPInterface.h | 419 ++++++++++++++++++ slsReceiverSoftware/include/receiver_defs.h | 17 + .../src/UDPStandardImplementation.cpp | 16 + slsReceiverSoftware/src/dummyMain.cpp | 46 ++ .../src/slsReceiverTCPIPInterface.cpp | 7 +- 6 files changed, 512 insertions(+), 2 deletions(-) create mode 100644 slsReceiverSoftware/include/dummyUDPInterface.h create mode 100644 slsReceiverSoftware/src/dummyMain.cpp diff --git a/slsReceiverSoftware/Makefile b/slsReceiverSoftware/Makefile index c445eaa8c..b7d1c10a9 100644 --- a/slsReceiverSoftware/Makefile +++ b/slsReceiverSoftware/Makefile @@ -26,6 +26,8 @@ endif MAIN_SRC = main.cpp +DUMMY_MAIN_SRC = dummyMain.cpp + OBJS=$(SRC_CLNT:%.cpp=$(BUILDDIR)/%.o) @@ -40,6 +42,8 @@ $(info ) all: builddir lib receiver +dummy: $(DESTDIR)/dummyReceiver + intdoc: $(SRC_H) $(SRC_CLNT) doxygen doxy.config @@ -70,6 +74,11 @@ $(DESTDIR)/slsReceiver: lib #$(EIGERFLAGS) +$(DESTDIR)/dummyReceiver: lib + $(CXX) -o $@ $(SRCDIR)/$(DUMMY_MAIN_SRC) $(FLAGS) $(INCLUDES) $(CLAGS) $(LIBS) $(LDFLAGRXR) -fPIC +#$(EIGERFLAGS) + + # Stand-alone Mysocket tests mysocket_test: g++ -o $(TESTDIR)/MySocketTCP.o -c $(SRCDIR)/MySocketTCP.cpp -I include diff --git a/slsReceiverSoftware/include/dummyUDPInterface.h b/slsReceiverSoftware/include/dummyUDPInterface.h new file mode 100644 index 000000000..479de4584 --- /dev/null +++ b/slsReceiverSoftware/include/dummyUDPInterface.h @@ -0,0 +1,419 @@ +#ifndef DUMMYUDPINTERFACE_H +#define DUMMYUDPINTERFACE_H + +/*********************************************** + * @file UDPInterface.h + * @short Base class with all the functions for the UDP inteface of the receiver + ***********************************************/ +/** + * \mainpage Base class with all the functions for the UDP inteface of the receiver + */ + +/** + * @short Base class with all the functions for the UDP inteface of the receiver + */ + +#include "UDPInterface.h" +#include "sls_receiver_defs.h" + + +class dummyUDPInterface : public UDPInterface { + + + /* abstract class that defines the UDP interface of an sls detector data receiver. + * + * Use the factory method UDPInterface::create() to get an instance: + * + * UDPInterface *udp_interface = UDPInterface::create() + * + * supported sequence of method-calls: + * + * initialize() : once and only once after create() + * + * get*() : anytime after initialize(), multiples times + * set*() : anytime after initialize(), multiple times + * + * startReceiver(): anytime after initialize(). Will fail if state already is 'running' + * + * abort(), + * stopReceiver() : anytime after initialize(). Will do nothing if state already is idle. + * + * getStatus() returns the actual state of the data receiver - running or idle. All other + * get*() and set*() methods access the local cache of configuration values only and *do not* modify the data receiver settings. + * + * Only startReceiver() does change the data receiver configuration, it does pass the whole configuration cache to the data receiver. + * + * get- and set-methods that return a char array (char *) allocate a new array at each call. The caller is responsible to free the allocated space: + * + * char *c = receiver->getFileName(); + * .... + * delete[] c; + * + * always: 1:YES 0:NO for int as bool-like arguments + * + */ + + public: + + /** + * Destructor + */ + dummyUDPInterface() : UDPInterface(), dynamicRange(16), scanTag(1000), nFrames(100), fWrite(1), fOverwrite(1), fIndex(0), fCaught(0), totfCaught(0), startAcqIndex(0), startFrameIndex(0), acqIndex(0), dataCompression(false), period(0), type(slsReceiverDefs::GENERIC), framesNeeded(100), udpPort1(1900), udpPort2(1901), shortFrame(0), nFramesToGui(0), e10G(0) {strcpy(detHostname,"none"); strcpy(fName,"run"); strcpy(fPath,"/scratch/"); strcpy(eth,"eth0"); cout << "New dummy UDP Interface" << endl;}; + + ~dummyUDPInterface() {cout << "Destroying dummy UDP Interface" << endl;}; + + + void del(){cout << "Destroying dummy UDP Interface" << endl;}; + + virtual void configure(map config_map) {}; + /** + * Initialize the Receiver + @param detectorHostName detector hostname + * you can call this function only once. You must call it before you call startReceiver() for the first time. + */ + virtual void initialize(const char *detectorHostName){ cout << "set detector hostname to" << detHostname << endl; strcpy(detHostname,detectorHostName);}; + + + /* Returns detector hostname + /returns hostname + * caller needs to deallocate the returned char array. + * if uninitialized, it must return NULL + */ + virtual char *getDetectorHostname() const { cout << "get detector hostname " << detHostname << endl; return (char*) detHostname;}; + + /** + * Returns status of receiver: idle, running or error + */ + virtual slsReceiverDefs::runStatus getStatus() const { cout << "get dsummy status IDLE " << endl; return slsReceiverDefs::IDLE;};; + + /** + * Returns File Name + * caller is responsible to deallocate the returned char array. + */ + virtual char *getFileName() const { cout << "get file name " << fName << endl; return (char*) fName;}; + + + /** + * Returns File Path + * caller is responsible to deallocate the returned char array + */ + virtual char *getFilePath() const { cout << "get file path " << fPath << endl; return (char*) fPath;};; + + + /** + * Returns the number of bits per pixel + */ + virtual int getDynamicRange() const { cout << "get dynamic range " << dynamicRange << endl; return dynamicRange;};; + + /** + * Returns scan tag + */ + virtual int getScanTag() const { cout << "get scan tag " << scanTag << endl; return scanTag;}; + + /* + * Returns number of frames to receive + * This is the number of frames to expect to receiver from the detector. + * The data receiver will change from running to idle when it got this number of frames + */ + virtual int getNumberOfFrames() const { cout << "get number of frames " << nFrames << endl; return nFrames;}; + + /** + * Returns file write enable + * 1: YES 0: NO + */ + virtual int getEnableFileWrite() const { cout << "get enable file write " << fWrite << endl; return fWrite;}; + + /** + * Returns file over write enable + * 1: YES 0: NO + */ + virtual int getEnableOverwrite() const { cout << "get enable file overwrite " << fOverwrite << endl; return fOverwrite;}; + + /** + * Set File Name (without frame index, file index and extension) + @param c file name + /returns file name + * returns NULL on failure (like bad file name) + * does not check the existence of the file - we don't know which path we'll finally use, so no point to check. + * caller is responsible to deallocate the returned char array. + */ + virtual char* setFileName(const char c[]) { strcpy(fName,c); cout << "set file name " << fName << endl; return fName; }; + + /** + * Set File Path + @param c file path + /returns file path + * checks the existence of the directory. returns NULL if directory does not exist or is not readable. + * caller is responsible to deallocate the returned char array. + */ + virtual char* setFilePath(const char c[]) { strcpy(fPath,c); cout << "set file path " << fPath << endl; return fPath; }; + + /** + * Returns the number of bits per pixel + @param dr sets dynamic range + /returns dynamic range + * returns -1 on failure + * FIXME: what are the allowd values - should we use an enum as argument? + */ + virtual int setDynamicRange(const int dr) {dynamicRange=dr; cout << "set dynamic range " << dynamicRange << endl; return dynamicRange; }; + + + /** + * Set scan tag + @param tag scan tag + /returns scan tag (always non-negative) + * FIXME: valid range - only positive? 16bit ore 32bit? + * returns -1 on failure + */ + virtual int setScanTag(const int tag) {scanTag=tag; cout << "set scan tag " << scanTag << endl; return scanTag; }; + + + /** + * Sets number of frames + @param fnum number of frames + /returns number of frames + */ + virtual int setNumberOfFrames(const int fnum) {nFrames=fnum; cout << "set number of frames " << nFrames << endl; return nFrames; }; + + + /** + * Set enable file write + * @param i file write enable + /returns file write enable + */ + virtual int setEnableFileWrite(const int i) {fWrite=i; cout << "set enable file write " << fWrite << endl; return fWrite; }; + + + /** + * Set enable file overwrite + * @param i file overwrite enable + /returns file overwrite enable + */ + virtual int setEnableOverwrite(const int i) {fOverwrite=i; cout << "set enable file overwrite " << fOverwrite << endl; return fOverwrite; }; + + + /** + * Starts Receiver - activate all configuration settings to the eiger receiver and start to listen for packets + @param message is the error message if there is an error + /returns 0 on success or -1 on failure + */ + //FIXME: success == 0 or success == 1? + virtual int startReceiver(char *message=NULL) {cout << "dummy start receiver" << endl; return 0;}; + + /** + * Stops Receiver - stops listening for packets + /returns success + * same as abort(). Always returns 0. + */ + virtual int stopReceiver() {cout << "dummy stop receiver" << endl; return 0;}; + + /** + * abort acquisition with minimum damage: close open files, cleanup. + * does nothing if state already is 'idle' + */ + virtual void abort() {cout << "Aborting receiver" << endl; }; + + + +/******************************************************************************************************************* + **************************************** Added by Dhanya ********************************************************* + *******************************************************************************************************************/ + + /** + * Returns File Index + */ + virtual int getFileIndex() {cout << "get file index " << fIndex << endl; return fIndex;}; + + /** + * Returns Total Frames Caught for an entire acquisition (including all scans) + */ + virtual int getTotalFramesCaught() {cout << "get total frames caught " << totfCaught << endl ; return totfCaught;}; + + /** + * Returns Frames Caught for each real time acquisition (eg. for each scan) + */ + virtual int getFramesCaught() {cout << "get frames caught " << fCaught << endl; return fCaught;}; + + + /** + * Returns the frame index at start of entire acquisition (including all scans) + */ + virtual uint32_t getStartAcquisitionIndex(){ cout << "get start acquisition index " << startAcqIndex << endl; return startAcqIndex; }; + + /** + * Returns current Frame Index Caught for an entire acquisition (including all scans) + */ + virtual uint32_t getAcquisitionIndex(){ cout << "get acquisition index " << acqIndex << endl; return acqIndex; }; + + + /** + * Returns the frame index at start of each real time acquisition (eg. for each scan) + */ + virtual uint32_t getStartFrameIndex() { cout << "get start frame index " << startFrameIndex << endl; return startFrameIndex; }; + + + /** get data compression, by saving only hits + */ + virtual bool getDataCompression() { cout << "get data compression " << dataCompression << endl; return dataCompression;}; + + /** + * Set receiver type + * @param det detector type + * Returns success or FAIL + */ + virtual int setDetectorType(slsReceiverDefs::detectorType det) {type=det; cout << "set detector type " << det << endl; return slsReceiverDefs::OK;}; + + /** + * Set File Index + * @param i file index + */ + virtual int setFileIndex(int i) {fIndex=i; cout << "get file index " << fIndex << endl; return fIndex;}; + + /** set acquisition period if a positive number + */ + virtual int64_t setAcquisitionPeriod(int64_t index) {if (index>=0) {period=index; cout << "set period " << period << endl;} else { cout << "get period " << period << endl;} return period;}; + + /** + * Set Frame Index Needed + * @param i frame index needed + */ + virtual int setFrameIndexNeeded(int i) {framesNeeded=i; cout << "set frame index needed " << period << endl; return framesNeeded;}; + + /** + * Set UDP Port Number + */ + virtual void setUDPPortNo(int p){udpPort1=p; cout << "set UDP port 1 " << udpPort1 << endl; }; + + + /** + * Set UDP Port Number + */ + virtual void setUDPPortNo2(int p) {udpPort2=p; cout << "set UDP port 2 " << udpPort2 << endl; }; + + /** + * Set Ethernet Interface or IP to listen to + */ + virtual void setEthernetInterface(char* c){strcpy(eth,c); cout << "set eth " << c;}; + + /** + * Set short frame + * @param i if shortframe i=1 + */ + virtual int setShortFrame(int i){shortFrame=i; cout << " set short frame" << shortFrame << endl; return shortFrame;}; + + /** + * Set the variable to send every nth frame to gui + * or if 0,send frame only upon gui request + */ + virtual int setNFrameToGui(int i) {nFramesToGui=i; cout << "set nframes to gui " << nFramesToGui << endl; return nFramesToGui;}; + + /** + * Resets the Total Frames Caught + * This is how the receiver differentiates between entire acquisitions + * Returns 0 + */ + virtual void resetTotalFramesCaught() {totfCaught=0; cout << "total frames caugh reset " << totfCaught << endl;}; + + /** enabl data compression, by saving only hits + /returns if failed + */ + virtual int enableDataCompression(bool enable) {dataCompression=enable; cout << "set data compression " << dataCompression<< endl; return dataCompression;}; + + /** + * enable 10Gbe + @param enable 1 for 10Gbe or 0 for 1 Gbe, -1 to read out + \returns enable for 10Gbe + */ + virtual int enableTenGiga(int enable = -1) {if (enable>=0) {e10G=enable; cout << "set 10Gb "<< e10G << endl;} else cout << "get 10Gb "<< e10G << endl; return e10G;}; + + /** + * Returns the buffer-current frame read by receiver + * @param c pointer to current file name + * @param raw address of pointer, pointing to current frame to send to gui + * @param fnum frame number for eiger as it is not in the packet + * @param startAcquisitionIndex is the start index of the acquisition + * @param startFrameIndex is the start index of the scan + */ + virtual void readFrame(char* c,char** raw, uint32_t &fnum, uint32_t &startAcquisitionIndex, uint32_t &startFrameIndex){cout << "dummy read frame" << endl; }; + + /** set status to transmitting and + * when fifo is empty later, sets status to run_finished + */ + virtual void startReadout(){cout << "dummy start readout" << endl; }; + + /** + * shuts down the udp sockets + * \returns if success or fail + */ + virtual int shutDownUDPSockets(){cout << "dummy shut down udp sockets" << endl; return slsReceiverDefs::OK;}; + + /** + * Closes all files + * @param ithr thread index, -1 for all threads + */ + virtual void closeFile(int ithr = -1){cout << "dummy close file" << ithr << endl; }; + + /** + * Call back for start acquisition + callback arguments are + filepath + filename + fileindex + datasize + + return value is + 0 callback takes care of open,close,wrie file + 1 callback writes file, we have to open, close it + 2 we open, close, write file, callback does not do anything + */ + virtual void registerCallBackStartAcquisition(int (*func)(char*, char*,int, int, void*),void *arg){cout << "dummy register callback start acquisition" << endl; }; + + /** + * Call back for acquisition finished + callback argument is + total frames caught + */ + virtual void registerCallBackAcquisitionFinished(void (*func)(int, void*),void *arg){cout << "dummy register callback acquisition finished" << endl; }; + + /** + * Call back for raw data + args to raw data ready callback are + framenum + datapointer + datasize in bytes + file descriptor + guidatapointer (NULL, no data required) + */ +virtual void registerCallBackRawDataReady(void (*func)(int, char*, int, FILE*, char*, void*),void *arg){cout << "dummy register callback get raw data" << endl; }; + + protected: + + private: + char detHostname[1000]; + char fName[10000]; + char fPath[10000]; + int dynamicRange; + int scanTag; + int nFrames; + int fWrite; + int fOverwrite; + + int fIndex; + int fCaught; +int totfCaught; +int startAcqIndex; +int startFrameIndex; +int acqIndex; +bool dataCompression; + int64_t period; + slsReceiverDefs::detectorType type; + int framesNeeded; + int udpPort1; + int udpPort2; + char eth[1000]; + int shortFrame; + int nFramesToGui; + int e10G; +}; + +#endif /* #ifndef DUMMYUDPINTERFACE_H */ diff --git a/slsReceiverSoftware/include/receiver_defs.h b/slsReceiverSoftware/include/receiver_defs.h index 4b0d10161..6f3b1acd3 100755 --- a/slsReceiverSoftware/include/receiver_defs.h +++ b/slsReceiverSoftware/include/receiver_defs.h @@ -68,6 +68,23 @@ +#define JCTB_FIFO_SIZE 2500 //cannot be less than max jobs per thread = 1000 +/*#define MOENCH_ALIGNED_FRAME_SIZE 65536*/ +#define JCTB_PACKETS_PER_FRAME 50 +#define JCTB_ONE_PACKET_SIZE 8214 +#define JCTB_BUFFER_SIZE (MOENCH_ONE_PACKET_SIZE*MOENCH_PACKETS_PER_FRAME) +#define JCTB_DATA_BYTES (JCTB_BUFFER_PER_FRAME) + +#define JCTB_FRAME_INDEX_MASK 0xFFFFFF00 +#define JCTB_FRAME_INDEX_OFFSET 8 +#define JCTB_PACKET_INDEX_MASK 0xFF + +#define JCTB_BYTES_PER_ADC (2) +#define JCTB_PIXELS_IN_ONE_ROW 32 +#define JCTB_BYTES_IN_ONE_ROW (JCTB_PIXELS_IN_ONE_ROW*2) + + + #define EIGER_MAX_PORTS 2 #define EIGER_HEADER_LENGTH 48 diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 93ad2c8d1..3b3a30b02 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -269,6 +269,12 @@ int UDPStandardImplementation::setDetectorType(detectorType det){ FILE_LOG(logD case EIGER: cout << endl << "***** This is a EIGER Receiver *****" << endl << endl; break; + case JUNGFRAUCTB: + cout << endl << "***** This is a JUNGFRAUCTB Receiver *****" << endl << endl; + break; + case JUNGFRAU: + cout << endl << "***** This is a JUNGFRAU Receiver *****" << endl << endl; + break; default: cout << endl << "***** Unknown Receiver *****" << endl << endl; return FAIL; @@ -315,6 +321,16 @@ int UDPStandardImplementation::setDetectorType(detectorType det){ FILE_LOG(logD createListeningThreads(true); numListeningThreads = MAX_NUM_LISTENING_THREADS; + } else if(myDetectorType == JUNGFRAUCTB || myDetectorType == JUNGFRAU ){ + fifosize = JCTB_FIFO_SIZE; + packetsPerFrame = JCTB_PACKETS_PER_FRAME; + onePacketSize = JCTB_ONE_PACKET_SIZE; + frameSize = JCTB_BUFFER_SIZE; + bufferSize = JCTB_BUFFER_SIZE; + maxPacketsPerFile = JFCTB_MAX_FRAMES_PER_FILE * JCTB_PACKETS_PER_FRAME; + frameIndexMask = JCTB_FRAME_INDEX_MASK; + frameIndexOffset = JCTB_FRAME_INDEX_OFFSET; + packetIndexMask = JCTB_PACKET_INDEX_MASK; } latestData = new char[frameSize]; diff --git a/slsReceiverSoftware/src/dummyMain.cpp b/slsReceiverSoftware/src/dummyMain.cpp new file mode 100644 index 000000000..41494fd99 --- /dev/null +++ b/slsReceiverSoftware/src/dummyMain.cpp @@ -0,0 +1,46 @@ +/* A simple server in the internet domain using TCP + The port number is passed as an argument */ + +#include "sls_receiver_defs.h" +#include "dummyUDPInterface.h" +#include "slsReceiverTCPIPInterface.h" + +#include +#include + + +using namespace std; + + +int main(int argc, char *argv[]) { + int success; + int tcpip_port_no; + bool bottom = false; + cout << "CCCCCC" << endl; + dummyUDPInterface *udp=new dummyUDPInterface(); + slsReceiverTCPIPInterface *tcpipInterface = new slsReceiverTCPIPInterface(success, udp, tcpip_port_no, bottom); + + + + + if(tcpipInterface->start() == slsReceiverDefs::OK){ + cout << "DONE!" << endl; + string str; + cin>>str; + //wait and look for an exit keyword + while(str.find("exit") == string::npos) + cin>>str; + //stop tcp server thread, stop udp socket + tcpipInterface->stop(); + } + + if (tcpipInterface) + delete tcpipInterface; + if(udp) + delete udp; + return 0; + + + +} + diff --git a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp index 240784ea5..54a52cc90 100644 --- a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp +++ b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp @@ -26,9 +26,9 @@ using namespace std; slsReceiverTCPIPInterface::~slsReceiverTCPIPInterface() { + closeFile(0); if(socket) {delete socket; socket=NULL;} if(receiverBase) {delete receiverBase; receiverBase=NULL;} - closeFile(0); } slsReceiverTCPIPInterface::slsReceiverTCPIPInterface(int &success, UDPInterface* rbase, int pn, bool bot): @@ -652,7 +652,9 @@ int slsReceiverTCPIPInterface::setup_udp(){ receiverBase->setUDPPortNo2(udpport2); //setup udpip //get ethernet interface or IP to listen to + cout << "Ethernet interface is " << args[0] << endl; temp = genericSocket::ipToName(args[0]); + cout << temp << endl; if(temp=="none"){ ret = FAIL; strcpy(mess, "failed to get ethernet interface or IP to listen to\n"); @@ -666,10 +668,11 @@ int slsReceiverTCPIPInterface::setup_udp(){ FILE_LOG(logDEBUG) << __FILE__ << "::" << __func__ << " " << eth; receiverBase->setEthernetInterface(eth); + cout << eth << endl; //get mac address from ethernet interface if (ret != FAIL) temp = genericSocket::nameToMac(eth); - + if ((temp=="00:00:00:00:00:00") || (ret == FAIL)){ ret = FAIL; From d9809925af3efb2e164ecfdde98934f7fb13478b Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 12 May 2015 14:28:13 +0200 Subject: [PATCH 085/474] debugging statements --- slsReceiverSoftware/include/genericSocket.h | 32 +++++++++++++++++++ .../src/UDPStandardImplementation.cpp | 5 ++- 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/slsReceiverSoftware/include/genericSocket.h b/slsReceiverSoftware/include/genericSocket.h index a10e07649..63de4b5de 100644 --- a/slsReceiverSoftware/include/genericSocket.h +++ b/slsReceiverSoftware/include/genericSocket.h @@ -92,6 +92,13 @@ enum communicationProtocol{ UDP /**< UDP */ }; +typedef struct +{ + unsigned char header_before[20]; + unsigned char fnum[4]; + unsigned char header_after[24]; +} eiger_image_header; + genericSocket(const char* const host_ip_or_name, unsigned short int const port_number, communicationProtocol p, int ps = DEFAULT_PACKET_SIZE) : // portno(port_number), protocol(p), @@ -578,8 +585,33 @@ enum communicationProtocol{ //if length given, listens to length, else listens for packetsize till length is reached if(length){ + +/*int k =0;*/ while(length>0){ nsending = (length>packet_size) ? packet_size:length; + +/* + //created for debugging on 11.05.2015 + nsending=5000; + + nsent = recvfrom(socketDescriptor,(char*)buf,nsending, 0, (struct sockaddr *) &clientAddress, &clientAddress_length); + + if(nsent <1000){ + if(nsent < 48){ + cout << " "<fnum)<< "\t"; + + cout << k <<" packets" << endl; + k = 0; + } + } + else + k++; +*/ + + nsent = recvfrom(socketDescriptor,(char*)buf+total_sent,nsending, 0, (struct sockaddr *) &clientAddress, &clientAddress_length); if(!nsent) break; length-=nsent; diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 93ad2c8d1..1b9a97c7f 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1950,9 +1950,8 @@ int UDPStandardImplementation::startWriting(){ currframenum = tempframenum; pthread_mutex_unlock(&progress_mutex); } -#ifdef VERYDEBUG - if(myDetectorType == EIGER) - cout << endl < Date: Wed, 13 May 2015 10:30:39 +0200 Subject: [PATCH 086/474] not significant --- slsReceiverSoftware/include/genericSocket.h | 22 +-------------------- 1 file changed, 1 insertion(+), 21 deletions(-) diff --git a/slsReceiverSoftware/include/genericSocket.h b/slsReceiverSoftware/include/genericSocket.h index 63de4b5de..519fd52e5 100644 --- a/slsReceiverSoftware/include/genericSocket.h +++ b/slsReceiverSoftware/include/genericSocket.h @@ -586,30 +586,10 @@ typedef struct //if length given, listens to length, else listens for packetsize till length is reached if(length){ -/*int k =0;*/ + while(length>0){ nsending = (length>packet_size) ? packet_size:length; -/* - //created for debugging on 11.05.2015 - nsending=5000; - - nsent = recvfrom(socketDescriptor,(char*)buf,nsending, 0, (struct sockaddr *) &clientAddress, &clientAddress_length); - - if(nsent <1000){ - if(nsent < 48){ - cout << " "<fnum)<< "\t"; - - cout << k <<" packets" << endl; - k = 0; - } - } - else - k++; -*/ nsent = recvfrom(socketDescriptor,(char*)buf+total_sent,nsending, 0, (struct sockaddr *) &clientAddress, &clientAddress_length); From 92dfb366f6962b5b814895392df6d077842cb604 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 19 May 2015 10:12:09 +0200 Subject: [PATCH 087/474] gemma offline reading works --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 1cc19d7bb..29de72ada 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1994,7 +1994,7 @@ int UDPStandardImplementation::startWriting(){ = ((*(uint8_t*)(((eiger_packet_header *)((char*)(wbuf[j] + totalheader + EIGER_ONE_GIGA_ONE_PACKET_SIZE*i)))->num4))); //new port number as its the same everywhere for 32 bit!! - if(!j) (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuf[j] + totalheader + EIGER_ONE_GIGA_ONE_PACKET_SIZE*i)))->num3)) = 0x00; + if((!j)&& (!bottom)) (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuf[j] + totalheader + EIGER_ONE_GIGA_ONE_PACKET_SIZE*i)))->num3)) = 0x00; #ifdef VERYDEBUG From c8403051891445ab4d0870f658d840d10ee3171b Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Thu, 21 May 2015 17:39:17 +0200 Subject: [PATCH 088/474] starting receiver only at set detector type works --- slsReceiverSoftware/include/UDPBaseImplementation.h | 5 +++++ slsReceiverSoftware/include/UDPInterface.h | 6 ++++++ slsReceiverSoftware/src/UDPBaseImplementation.cpp | 2 +- slsReceiverSoftware/src/slsReceiver.cpp | 4 +++- .../src/slsReceiverTCPIPInterface.cpp | 13 +++++++++---- 5 files changed, 24 insertions(+), 6 deletions(-) diff --git a/slsReceiverSoftware/include/UDPBaseImplementation.h b/slsReceiverSoftware/include/UDPBaseImplementation.h index 4801c751e..ed7889ae8 100644 --- a/slsReceiverSoftware/include/UDPBaseImplementation.h +++ b/slsReceiverSoftware/include/UDPBaseImplementation.h @@ -65,6 +65,11 @@ class UDPBaseImplementation : protected virtual slsReceiverDefs, public UDPInter */ int setDetectorType(detectorType det); + /** + * Set bottom to bot + * @param bot = 1 if bottom + */ + void setBottom(int bot); //Frame indices and numbers caught /** diff --git a/slsReceiverSoftware/include/UDPInterface.h b/slsReceiverSoftware/include/UDPInterface.h index 8f3ce3f41..8952396f3 100644 --- a/slsReceiverSoftware/include/UDPInterface.h +++ b/slsReceiverSoftware/include/UDPInterface.h @@ -225,6 +225,12 @@ class UDPInterface { **************************************** Added by Dhanya ********************************************************* *******************************************************************************************************************/ + /** + * Set bottom to bot + * @param bot = 1 if bottom + */ + virtual void setBottom(int bot)= 0; + /** * Returns File Index */ diff --git a/slsReceiverSoftware/src/UDPBaseImplementation.cpp b/slsReceiverSoftware/src/UDPBaseImplementation.cpp index c70be5b7d..bbb8b331d 100644 --- a/slsReceiverSoftware/src/UDPBaseImplementation.cpp +++ b/slsReceiverSoftware/src/UDPBaseImplementation.cpp @@ -143,7 +143,7 @@ int UDPBaseImplementation::setDetectorType(detectorType det){ - +void UDPBaseImplementation::setBottom(int bot){bottom=bot;}; /*Frame indices and numbers caught*/ diff --git a/slsReceiverSoftware/src/slsReceiver.cpp b/slsReceiverSoftware/src/slsReceiver.cpp index 6ffc2fdf9..e43820613 100644 --- a/slsReceiverSoftware/src/slsReceiver.cpp +++ b/slsReceiverSoftware/src/slsReceiver.cpp @@ -36,6 +36,7 @@ slsReceiver::slsReceiver(int argc, char *argv[], int &success){ string fname = ""; string udp_interface_type = "standard"; string rest_hostname = "localhost:8081"; + udp_interface = NULL; bool bottom = false; //TODO: properly set new parameter -> mode? //parse command line for config @@ -128,10 +129,11 @@ slsReceiver::slsReceiver(int argc, char *argv[], int &success){ if (success==OK){ FILE_LOG(logINFO) << "SLS Receiver starting " << udp_interface_type << " on port " << tcpip_port_no << " with mode " << bottom << endl; +#ifdef REST udp_interface = UDPInterface::create(udp_interface_type); udp_interface->configure(configuration_map); +#endif tcpipInterface = new slsReceiverTCPIPInterface(success, udp_interface, tcpip_port_no, bottom); - //tcp ip interface } } diff --git a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp index 54a52cc90..c12e82ff2 100644 --- a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp +++ b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp @@ -45,7 +45,7 @@ slsReceiverTCPIPInterface::slsReceiverTCPIPInterface(int &success, UDPInterface* bottom(bot){ int port_no=portNumber; - + if(receiverBase == NULL) receiverBase = 0; if (pn>0) port_no = pn; @@ -198,11 +198,12 @@ void slsReceiverTCPIPInterface::startTCPServer(){ //if tcp command was to exit server if(v==GOODBYE){ cout << "Shutting down UDP Socket" << endl; - if(receiverBase) + if(receiverBase){ receiverBase->shutDownUDPSockets(); - cout << "Closing Files... " << endl; - receiverBase->closeFile(); + cout << "Closing Files... " << endl; + receiverBase->closeFile(); + } pthread_exit(NULL); } @@ -364,6 +365,10 @@ int slsReceiverTCPIPInterface::set_detector_type(){ } else{ myDetectorType = dr; +#ifndef REST + receiverBase = UDPInterface::create("standard"); + receiverBase->setBottom(bottom); +#endif ret=receiverBase->setDetectorType(dr); retval = myDetectorType; } From 99196aa272231ff3deafb3a6f6f95a8969686999 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 26 May 2015 12:08:21 +0200 Subject: [PATCH 089/474] ignore 16 byte messages --- slsReceiverSoftware/include/genericSocket.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/slsReceiverSoftware/include/genericSocket.h b/slsReceiverSoftware/include/genericSocket.h index 519fd52e5..58c9bb5a4 100644 --- a/slsReceiverSoftware/include/genericSocket.h +++ b/slsReceiverSoftware/include/genericSocket.h @@ -589,11 +589,12 @@ typedef struct while(length>0){ nsending = (length>packet_size) ? packet_size:length; - - - nsent = recvfrom(socketDescriptor,(char*)buf+total_sent,nsending, 0, (struct sockaddr *) &clientAddress, &clientAddress_length); if(!nsent) break; + if(nsent == 16) { + //cout << "."; + continue; + } length-=nsent; total_sent+=nsent; } From 4f88e831c40b2e0319c638564ae20b66802539f5 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 26 May 2015 17:01:42 +0200 Subject: [PATCH 090/474] checks if receiver udp object was created before executing functions and hence always returns a ret --- .../src/slsReceiverTCPIPInterface.cpp | 174 +++++++++++++++--- 1 file changed, 144 insertions(+), 30 deletions(-) diff --git a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp index c12e82ff2..720784b14 100644 --- a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp +++ b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp @@ -421,6 +421,10 @@ int slsReceiverTCPIPInterface::set_file_name() { if (lockStatus==1 && socket->differentClients==1){ sprintf(mess,"Receiver locked by %s\n", socket->lastClientIP); ret=FAIL; + } + else if (receiverBase == NULL){ + strcpy(mess,"Receiver not set up\n"); + ret=FAIL; } else strcpy(retval,receiverBase->setFileName(fName)); @@ -476,6 +480,10 @@ int slsReceiverTCPIPInterface::set_file_dir() { strcpy(mess,"Can not set file path while receiver running\n"); ret = FAIL; }*/ + else if (receiverBase == NULL){ + strcpy(mess,"Receiver not set up\n"); + ret=FAIL; + } else{ strcpy(retval,receiverBase->setFilePath(fPath)); // if file path doesnt exist @@ -535,6 +543,10 @@ int slsReceiverTCPIPInterface::set_file_index() { sprintf(mess,"Receiver locked by %s\n", socket->lastClientIP); ret=FAIL; } + else if (receiverBase == NULL){ + strcpy(mess,"Receiver not set up\n"); + ret=FAIL; + } else retval=receiverBase->setFileIndex(index); } @@ -588,6 +600,10 @@ int slsReceiverTCPIPInterface::set_frame_index() { sprintf(mess,"Receiver locked by %s\n", socket->lastClientIP); ret=FAIL; } + else if (receiverBase == NULL){ + strcpy(mess,"Receiver not set up\n"); + ret=FAIL; + } else retval=receiverBase->setFrameIndexNeeded(index); } @@ -645,6 +661,10 @@ int slsReceiverTCPIPInterface::setup_udp(){ sprintf(mess,"Receiver locked by %s\n", socket->lastClientIP); ret=FAIL; } + else if (receiverBase == NULL){ + strcpy(mess,"Receiver not set up\n"); + ret=FAIL; + } else if(receiverBase->getStatus()==RUNNING){ ret = FAIL; strcpy(mess,"cannot set up udp when receiver is running\n"); @@ -732,6 +752,10 @@ int slsReceiverTCPIPInterface::start_receiver(){ ret = FAIL; } */ + else if (receiverBase == NULL){ + strcpy(mess,"Receiver not set up\n"); + ret=FAIL; + } else { s = receiverBase->getStatus(); switch (s) { @@ -780,6 +804,10 @@ int slsReceiverTCPIPInterface::stop_receiver(){ sprintf(mess,"Receiver locked by %s\n", socket->lastClientIP); ret=FAIL; } + else if (receiverBase == NULL){ + strcpy(mess,"Receiver not set up\n"); + ret=FAIL; + } else if(receiverBase->getStatus()!=IDLE) ret=receiverBase->stopReceiver(); #endif @@ -802,20 +830,25 @@ int slsReceiverTCPIPInterface::stop_receiver(){ int slsReceiverTCPIPInterface::get_status(){ ret=OK; - enum runStatus retval; + enum runStatus retval = ERROR; // execute action if the arguments correctly arrived #ifdef SLS_RECEIVER_UDP_FUNCTIONS - retval=receiverBase->getStatus(); + if (receiverBase == NULL){ + strcpy(mess,"Receiver not set up\n"); + ret=FAIL; + }else retval=receiverBase->getStatus(); #endif - if(socket->differentClients){ + if(ret==OK && socket->differentClients){ cout << "Force update" << endl; ret=FORCE_UPDATE; } // send answer socket->SendDataOnly(&ret,sizeof(ret)); + if(ret==FAIL) + socket->SendDataOnly(mess,sizeof(mess)); socket->SendDataOnly(&retval,sizeof(retval)); //return ok/fail return ret; @@ -830,15 +863,20 @@ int slsReceiverTCPIPInterface::get_frames_caught(){ // execute action if the arguments correctly arrived #ifdef SLS_RECEIVER_UDP_FUNCTIONS - retval=receiverBase->getTotalFramesCaught(); + if (receiverBase == NULL){ + strcpy(mess,"Receiver not set up\n"); + ret=FAIL; + }else retval=receiverBase->getTotalFramesCaught(); #endif - if(socket->differentClients){ + if(ret==OK && socket->differentClients){ cout << "Force update" << endl; ret=FORCE_UPDATE; } // send answer socket->SendDataOnly(&ret,sizeof(ret)); + if(ret==FAIL) + socket->SendDataOnly(mess,sizeof(mess)); socket->SendDataOnly(&retval,sizeof(retval)); //return ok/fail return ret; @@ -853,16 +891,22 @@ int slsReceiverTCPIPInterface::get_frame_index(){ // execute action if the arguments correctly arrived #ifdef SLS_RECEIVER_UDP_FUNCTIONS - retval=receiverBase->getAcquisitionIndex(); + if (receiverBase == NULL){ + strcpy(mess,"Receiver not set up\n"); + ret=FAIL; + }else + retval=receiverBase->getAcquisitionIndex(); #endif - if(socket->differentClients){ + if(ret==OK && socket->differentClients){ cout << "Force update" << endl; ret=FORCE_UPDATE; } // send answer socket->SendDataOnly(&ret,sizeof(ret)); + if(ret==FAIL) + socket->SendDataOnly(mess,sizeof(mess)); socket->SendDataOnly(&retval,sizeof(retval)); //return ok/fail return ret; @@ -884,6 +928,10 @@ int slsReceiverTCPIPInterface::reset_frames_caught(){ sprintf(mess,"Receiver locked by %s\n", socket->lastClientIP); ret=FAIL; } + else if (receiverBase == NULL){ + strcpy(mess,"Receiver not set up\n"); + ret=FAIL; + } else receiverBase->resetTotalFramesCaught(); } @@ -936,6 +984,10 @@ int slsReceiverTCPIPInterface::set_short_frame() { sprintf(mess,"Receiver locked by %s\n", socket->lastClientIP); ret=FAIL; } + else if (receiverBase == NULL){ + strcpy(mess,"Receiver not set up\n"); + ret=FAIL; + } else if(receiverBase->getStatus()==RUNNING){ strcpy(mess,"Cannot set short frame while status is running\n"); ret=FAIL; @@ -1009,9 +1061,12 @@ int slsReceiverTCPIPInterface::moench_read_frame(){ // execute action if the arguments correctly arrived #ifdef SLS_RECEIVER_UDP_FUNCTIONS - + if (receiverBase == NULL){ + strcpy(mess,"Receiver not set up\n"); + ret=FAIL; + } /**send garbage with -1 index to try again*/ - if(!receiverBase->getFramesCaught()){ + else if(!receiverBase->getFramesCaught()){ startAcquisitionIndex = -1; cout<<"haven't caught any frame yet"<getFramesCaught()){ + else if(!receiverBase->getFramesCaught()){ startAcquisitionIndex=-1; cout<<"haven't caught any frame yet"<getFramesCaught()){ + else if(!receiverBase->getFramesCaught()){ startAcquisitionIndex=-1; #ifdef VERBOSE cout<<"haven't caught any frame yet"<differentClients==1){ sprintf(mess,"Receiver locked by %s\n", socket->lastClientIP); ret=FAIL; - }/* + } + else if (receiverBase == NULL){ + strcpy(mess,"Receiver not set up\n"); + ret=FAIL; + } + /* else if((receiverBase->getStatus()==RUNNING) && (index >= 0)){ ret = FAIL; strcpy(mess,"cannot set up receiver mode when receiver is running\n"); @@ -1667,6 +1733,10 @@ int slsReceiverTCPIPInterface::enable_file_write(){ sprintf(mess,"Receiver locked by %s\n", socket->lastClientIP); ret=FAIL; } + else if (receiverBase == NULL){ + strcpy(mess,"Receiver not set up\n"); + ret=FAIL; + } else{ if(enable >= 0) receiverBase->setEnableFileWrite(enable); @@ -1733,21 +1803,28 @@ int slsReceiverTCPIPInterface::start_readout(){ // execute action if the arguments correctly arrived #ifdef SLS_RECEIVER_UDP_FUNCTIONS - receiverBase->startReadout(); - retval = receiverBase->getStatus(); - if((retval == TRANSMITTING) || (retval == RUN_FINISHED) || (retval == IDLE)) - ret = OK; - else - ret = FAIL; + if (receiverBase == NULL){ + strcpy(mess,"Receiver not set up\n"); + ret=FAIL; + }else{ + receiverBase->startReadout(); + retval = receiverBase->getStatus(); + if((retval == TRANSMITTING) || (retval == RUN_FINISHED) || (retval == IDLE)) + ret = OK; + else + ret = FAIL; + } #endif - if(socket->differentClients){ + if(ret==OK && socket->differentClients){ cout << "Force update" << endl; ret=FORCE_UPDATE; } // send answer socket->SendDataOnly(&ret,sizeof(ret)); + if(ret==FAIL) + socket->SendDataOnly(mess,sizeof(mess)); socket->SendDataOnly(&retval,sizeof(retval)); //return ok/fail return ret; @@ -1779,6 +1856,10 @@ int slsReceiverTCPIPInterface::set_timer() { sprintf(mess,"Receiver locked by %s\n", socket->lastClientIP); ret=FAIL; } + else if (receiverBase == NULL){ + strcpy(mess,"Receiver not set up\n"); + ret=FAIL; + } else{ if(index[0] == slsReceiverDefs::FRAME_PERIOD) retval=receiverBase->setAcquisitionPeriod(index[1]); @@ -1838,6 +1919,10 @@ int slsReceiverTCPIPInterface::enable_compression() { sprintf(mess,"Receiver locked by %s\n", socket->lastClientIP); ret=FAIL; } + else if (receiverBase == NULL){ + strcpy(mess,"Receiver not set up\n"); + ret=FAIL; + } else if(receiverBase->getStatus()==RUNNING){ strcpy(mess,"Cannot enable/disable compression while status is running\n"); ret=FAIL; @@ -1846,7 +1931,11 @@ int slsReceiverTCPIPInterface::enable_compression() { ret = receiverBase->enableDataCompression(enable); } - retval=receiverBase->getDataCompression(); + if (receiverBase == NULL){ + strcpy(mess,"Receiver not set up\n"); + ret=FAIL; + }else + retval=receiverBase->getDataCompression(); } #endif @@ -1887,6 +1976,10 @@ int slsReceiverTCPIPInterface::set_detector_hostname() { if (lockStatus==1 && socket->differentClients==1){ sprintf(mess,"Receiver locked by %s\n", socket->lastClientIP); ret=FAIL; + } + else if (receiverBase == NULL){ + strcpy(mess,"Receiver not set up\n"); + ret=FAIL; } else{ receiverBase->initialize(hostname); @@ -1955,14 +2048,19 @@ int slsReceiverTCPIPInterface::set_dynamic_range() { } } if(ret!=FAIL){ - retval=receiverBase->setDynamicRange(dr); - dynamicrange = dr; - if(myDetectorType == EIGER){ - if(!tenGigaEnable) - packetsPerFrame = EIGER_ONE_GIGA_CONSTANT * dynamicrange * EIGER_MAX_PORTS; - else - packetsPerFrame = EIGER_TEN_GIGA_CONSTANT * dynamicrange * EIGER_MAX_PORTS; - } + if (receiverBase == NULL){ + strcpy(mess,"Receiver not set up\n"); + ret=FAIL; + }else{ + retval=receiverBase->setDynamicRange(dr); + dynamicrange = dr; + if(myDetectorType == EIGER){ + if(!tenGigaEnable) + packetsPerFrame = EIGER_ONE_GIGA_CONSTANT * dynamicrange * EIGER_MAX_PORTS; + else + packetsPerFrame = EIGER_TEN_GIGA_CONSTANT * dynamicrange * EIGER_MAX_PORTS; + } + } } } #ifdef VERBOSE @@ -2014,6 +2112,10 @@ int slsReceiverTCPIPInterface::enable_overwrite() { sprintf(mess,"Receiver locked by %s\n", socket->lastClientIP); ret=FAIL; } + else if (receiverBase == NULL){ + strcpy(mess,"Receiver not set up\n"); + ret=FAIL; + } else{ if(index >= 0) receiverBase->setEnableOverwrite(index); @@ -2069,6 +2171,10 @@ int slsReceiverTCPIPInterface::enable_tengiga() { sprintf(mess,"Receiver locked by %s\n", socket->lastClientIP); ret=FAIL; } + else if (receiverBase == NULL){ + strcpy(mess,"Receiver not set up\n"); + ret=FAIL; + } else{ retval=receiverBase->enableTenGiga(val); if((val!=-1) && (val != retval)) @@ -2313,7 +2419,15 @@ int slsReceiverTCPIPInterface::send_update() { int slsReceiverTCPIPInterface::update_client() { ret=OK; + if (receiverBase == NULL){ + strcpy(mess,"Receiver not set up\n"); + ret=FAIL; + } socket->SendDataOnly(&ret,sizeof(ret)); + if(ret == FAIL){ + socket->SendDataOnly(mess,sizeof(mess)); + return ret; + } return send_update(); } From 849d0de5cbc2fb2047f494fa453c1580f04e47da Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Wed, 10 Jun 2015 12:23:38 +0200 Subject: [PATCH 091/474] not much valuable change --- .../include/UDPBaseImplementation.h | 8 ----- slsReceiverSoftware/include/genericSocket.h | 31 ++++++++++++++++++- .../src/UDPStandardImplementation.cpp | 2 -- 3 files changed, 30 insertions(+), 11 deletions(-) diff --git a/slsReceiverSoftware/include/UDPBaseImplementation.h b/slsReceiverSoftware/include/UDPBaseImplementation.h index ed7889ae8..cb5c08195 100644 --- a/slsReceiverSoftware/include/UDPBaseImplementation.h +++ b/slsReceiverSoftware/include/UDPBaseImplementation.h @@ -491,14 +491,6 @@ protected: unsigned char fnum[4]; unsigned char header_after[24]; } eiger_image_header; - /** structure of an eiger image header*/ - typedef struct - { - unsigned char header_before[19]; - unsigned char fnum[4]; - unsigned char header_after[25]; - } eiger_image_header32; - /** structure of an eiger image header*/ typedef struct diff --git a/slsReceiverSoftware/include/genericSocket.h b/slsReceiverSoftware/include/genericSocket.h index 58c9bb5a4..0ccc80adf 100644 --- a/slsReceiverSoftware/include/genericSocket.h +++ b/slsReceiverSoftware/include/genericSocket.h @@ -99,6 +99,13 @@ typedef struct unsigned char header_after[24]; } eiger_image_header; +typedef struct +{ + unsigned char header_before[19]; + unsigned char fnum[4]; + unsigned char header_after[25]; +} eiger_image_header32; + genericSocket(const char* const host_ip_or_name, unsigned short int const port_number, communicationProtocol p, int ps = DEFAULT_PACKET_SIZE) : // portno(port_number), protocol(p), @@ -585,10 +592,32 @@ typedef struct //if length given, listens to length, else listens for packetsize till length is reached if(length){ - +/*int k = 0;*/ while(length>0){ nsending = (length>packet_size) ? packet_size:length; + + /* + + //created for debugging on 11.05.2015 + nsending=5000; + nsent = recvfrom(socketDescriptor,(char*)buf,nsending, 0, (struct sockaddr *) &clientAddress, &clientAddress_length); + if(nsent <1000){ + if(nsent < 48){ + cout << " "<fnum)<< "\t"; + cout << k <<" packets" << endl; + k = 0; + } + } + else + k++; + */ + + + nsent = recvfrom(socketDescriptor,(char*)buf+total_sent,nsending, 0, (struct sockaddr *) &clientAddress, &clientAddress_length); if(!nsent) break; if(nsent == 16) { diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 29de72ada..f6fe25fcb 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -26,8 +26,6 @@ using namespace std; -#define EIGER_32BIT_INITIAL_CONSTANT 0x17c - From fdaca8822583fced5db1d0fc231bd23046ec11e2 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Wed, 10 Jun 2015 13:26:51 +0200 Subject: [PATCH 092/474] includes 32 bit subframes --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index f6fe25fcb..d6e85c5c7 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1945,7 +1945,7 @@ int UDPStandardImplementation::startWriting(){ if(dynamicRange != 32) tempframenum = htonl(*(unsigned int*)((eiger_image_header *)((char*)(wbuf[ithread] + HEADER_SIZE_NUM_TOT_PACKETS)))->fnum); else - tempframenum = htonl(*(unsigned int*)((eiger_image_header32 *)((char*)(wbuf[ithread] + HEADER_SIZE_NUM_TOT_PACKETS)))->fnum); + tempframenum = htonl(*(unsigned int*)((eiger_image_header *)((char*)(wbuf[ithread] + HEADER_SIZE_NUM_TOT_PACKETS)))->fnum); tempframenum += (startFrameIndex-1); //eiger frame numbers start at 1, so need to -1 @@ -2136,9 +2136,9 @@ void UDPStandardImplementation::startFrameIndices(int ithread){ if (myDetectorType == EIGER){ //add currframenum later in this method for scans - if(dynamicRange == 32) + /*if(dynamicRange == 32) startFrameIndex = htonl(*(unsigned int*)((eiger_image_header32 *)((char*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS)))->fnum); - else + else*/ startFrameIndex = htonl(*(unsigned int*)((eiger_image_header *)((char*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS)))->fnum); } //gotthard has +1 for frame number and not a short frame From 28ed7d6b2d4e492c196e45fcc449d105e3f10e8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Br=C3=BCckner?= Date: Thu, 11 Jun 2015 11:25:49 +0200 Subject: [PATCH 093/474] Solved merge conflicts --- slsReceiverSoftware/include/genericSocket.h | 33 ++------------------- 1 file changed, 2 insertions(+), 31 deletions(-) diff --git a/slsReceiverSoftware/include/genericSocket.h b/slsReceiverSoftware/include/genericSocket.h index 0ccc80adf..e113f24b8 100644 --- a/slsReceiverSoftware/include/genericSocket.h +++ b/slsReceiverSoftware/include/genericSocket.h @@ -99,13 +99,6 @@ typedef struct unsigned char header_after[24]; } eiger_image_header; -typedef struct -{ - unsigned char header_before[19]; - unsigned char fnum[4]; - unsigned char header_after[25]; -} eiger_image_header32; - genericSocket(const char* const host_ip_or_name, unsigned short int const port_number, communicationProtocol p, int ps = DEFAULT_PACKET_SIZE) : // portno(port_number), protocol(p), @@ -592,38 +585,16 @@ typedef struct //if length given, listens to length, else listens for packetsize till length is reached if(length){ -/*int k = 0;*/ + while(length>0){ nsending = (length>packet_size) ? packet_size:length; - /* - //created for debugging on 11.05.2015 - nsending=5000; - nsent = recvfrom(socketDescriptor,(char*)buf,nsending, 0, (struct sockaddr *) &clientAddress, &clientAddress_length); - if(nsent <1000){ - if(nsent < 48){ - cout << " "<fnum)<< "\t"; - cout << k <<" packets" << endl; - k = 0; - } - } - else - k++; - */ - - nsent = recvfrom(socketDescriptor,(char*)buf+total_sent,nsending, 0, (struct sockaddr *) &clientAddress, &clientAddress_length); if(!nsent) break; - if(nsent == 16) { - //cout << "."; - continue; - } + if (nsent == 16) continue; length-=nsent; total_sent+=nsent; } From b27f691d036a7171db732ff1c4e16a15f92164fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Br=C3=BCckner?= Date: Thu, 11 Jun 2015 11:30:40 +0200 Subject: [PATCH 094/474] Revert "Solved merge conflicts" This reverts commit c222221d18bd5db7d9a8c86071fe2fbdc0ce25ac. --- slsReceiverSoftware/include/genericSocket.h | 33 +++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/slsReceiverSoftware/include/genericSocket.h b/slsReceiverSoftware/include/genericSocket.h index e113f24b8..0ccc80adf 100644 --- a/slsReceiverSoftware/include/genericSocket.h +++ b/slsReceiverSoftware/include/genericSocket.h @@ -99,6 +99,13 @@ typedef struct unsigned char header_after[24]; } eiger_image_header; +typedef struct +{ + unsigned char header_before[19]; + unsigned char fnum[4]; + unsigned char header_after[25]; +} eiger_image_header32; + genericSocket(const char* const host_ip_or_name, unsigned short int const port_number, communicationProtocol p, int ps = DEFAULT_PACKET_SIZE) : // portno(port_number), protocol(p), @@ -585,16 +592,38 @@ typedef struct //if length given, listens to length, else listens for packetsize till length is reached if(length){ - +/*int k = 0;*/ while(length>0){ nsending = (length>packet_size) ? packet_size:length; + /* + //created for debugging on 11.05.2015 + nsending=5000; + nsent = recvfrom(socketDescriptor,(char*)buf,nsending, 0, (struct sockaddr *) &clientAddress, &clientAddress_length); + if(nsent <1000){ + if(nsent < 48){ + cout << " "<fnum)<< "\t"; + cout << k <<" packets" << endl; + k = 0; + } + } + else + k++; + */ + + nsent = recvfrom(socketDescriptor,(char*)buf+total_sent,nsending, 0, (struct sockaddr *) &clientAddress, &clientAddress_length); if(!nsent) break; - if (nsent == 16) continue; + if(nsent == 16) { + //cout << "."; + continue; + } length-=nsent; total_sent+=nsent; } From bcf8d40fd2f7349fb7bb8651d4749ed8cf8dd4c5 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Fri, 12 Jun 2015 17:46:50 +0200 Subject: [PATCH 095/474] minor changes, but posted semaphore in stop receiver so rxr not waiting forever for gui when it will never come --- .../src/UDPStandardImplementation.cpp | 45 ++++++++++--------- 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index d6e85c5c7..bd2e7560a 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -890,7 +890,7 @@ void UDPStandardImplementation::readFrame(char* c,char** raw, uint32_t &fnum, ui if (guiData == NULL){ guiData = latestData; #ifdef VERY_VERY_DEBUG - cout << "gui data not null anymore" << endl; + cprintf(CYAN,"gui data not null anymore\n"); #endif } @@ -904,14 +904,14 @@ void UDPStandardImplementation::readFrame(char* c,char** raw, uint32_t &fnum, ui //could not get gui data if(!guiDataReady){ #ifdef VERY_VERY_DEBUG - cout << "gui data not ready" << endl; + cprintf(CYAN,"gui data not ready\n"); #endif *raw = NULL; } //data ready, set guidata to receive new data else{ #ifdef VERY_VERY_DEBUG - cout << "gui data ready" << endl; + cprintf(CYAN,"gui data ready\n"); #endif *raw = guiData; guiData = NULL; @@ -921,14 +921,14 @@ void UDPStandardImplementation::readFrame(char* c,char** raw, uint32_t &fnum, ui pthread_mutex_unlock(&dataReadyMutex);*/ if((nFrameToGui) && (writerthreads_mask)){ #ifdef VERY_VERY_DEBUG - cout << "gonna post" << endl; + cprintf(CYAN,"gonna post\n"); #endif /*if(nFrameToGui){*/ //release after getting data sem_post(&smp); } #ifdef VERY_VERY_DEBUG - cout << "done post" << endl; + cprintf(CYAN,"done post\n"); #endif } } @@ -947,7 +947,7 @@ cout << "copyframe" << endl; //else guidata always null as guidataready is always 1 after 1st frame, and seccond data never gets copied if((!nFrameToGui) && (!guiData)){ #ifdef VERY_VERY_DEBUG - cout << "doing nothing" << endl; + cprintf(GREEN,"doing nothing\n"); #endif pthread_mutex_lock(&dataReadyMutex); guiDataReady=0; @@ -957,12 +957,12 @@ cout << "copyframe" << endl; //random read or nth frame read, gui needs data now or it is the first frame else{ #ifdef VERY_VERY_DEBUG - cout << "gui needs data now or 1st frame" << endl; + cprintf(GREEN,"gui needs data now or 1st frame\n"); #endif pthread_mutex_lock(&dataReadyMutex); guiDataReady=0; #ifdef VERY_VERY_DEBUG - cout << "guidataready is 0, copying data" << endl; + cprintf(GREEN,"guidataready is 0, copying data\n"); #endif //eiger if(startbuf != NULL){ @@ -989,16 +989,16 @@ cout << "copyframe" << endl; guiDataReady=1; pthread_mutex_unlock(&dataReadyMutex); #ifdef VERY_VERY_DEBUG - cout << "guidataready = 1" << endl; + cprintf(GREEN,"guidataready = 1\n"); #endif //nth frame read, block current process if the guireader hasnt read it yet if(nFrameToGui){ #ifdef VERY_VERY_DEBUG - cout<<"waiting after copying"<push(buffer[ithread])); #ifdef FIFO_DEBUG //if(!ithread) - cprintf(RED, "%d listener pushed into fifo %x\n",ithread, (void*)(buffer[ithread])); + cprintf(MAGENTA, "%d listener pushed into fifo %x\n",ithread, (void*)(buffer[ithread])); #endif } @@ -1934,7 +1939,7 @@ int UDPStandardImplementation::startWriting(){ continue; } #ifdef VERYDEBUG - else cout <<"**NOT a dummy packet"<push(wbuf[i])); @@ -2196,7 +2201,7 @@ int i; //free buffer if(rc <= 0){ cout << ithread << "Discarding empty frame/ End of acquisition" << endl; - fifoFree[ithread]->push(buffer[ithread]); + fifoFree[ithread]->push(buffer[ithread]);/** why not while(!)*/ #ifdef FIFO_DEBUG cprintf(BLUE,"%d listener empty buffer pushed into fifofree %x\n", ithread, (void*)(buffer[ithread])); #endif @@ -2208,7 +2213,7 @@ int i; if(rc == 266240) cprintf(GREEN, "%d Start of detector: Received test frame of 266240 bytes.\n",ithread); cout << ithread << "Discarding incomplete frame" << endl; - fifoFree[ithread]->push(buffer[ithread]); + fifoFree[ithread]->push(buffer[ithread]);/** why not while(!)*/ #ifdef FIFO_DEBUG cprintf(BLUE,"%d listener last buffer free pushed into fifofree %x\n", ithread,(void*)(buffer[ithread])); #endif From 9a61841ac769d8d46e07fa95ab1047be14f816b5 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 16 Jun 2015 12:00:02 +0200 Subject: [PATCH 096/474] git version update --- slsReceiverSoftware/gitInfo.txt | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/slsReceiverSoftware/gitInfo.txt b/slsReceiverSoftware/gitInfo.txt index d680dad1d..a8b18fa13 100644 --- a/slsReceiverSoftware/gitInfo.txt +++ b/slsReceiverSoftware/gitInfo.txt @@ -1,9 +1,9 @@ Path: slsDetectorsPackage/slsReceiverSoftware -URL: origin git@gitorious.psi.ch:sls_det_software/sls_receiver_software.git -Repository Root: origin git@gitorious.psi.ch:sls_det_software/sls_receiver_software.git -Repsitory UUID: 879c5e2ee129acfd70aba4ae6fab829cc5409350 -Revision: 67 -Branch: gemma -Last Changed Author: Maliakal_Dhanya -Last Changed Rev: 67 -Last Changed Date: 2014-12-08 09:17:56 +0100 +URL: origin maliakal_d@gitorious.psi.ch:sls_det_software/sls_receiver_software.git +Repository Root: origin maliakal_d@gitorious.psi.ch:sls_det_software/sls_receiver_software.git +Repsitory UUID: 44d2a6ae0422ef1d792890a409d202d3cec5b7f7 +Revision: 108 +Branch: master +Last Changed Author: Dhanya_Maliakal +Last Changed Rev: 108 +Last Changed Date: 2015-06-12 17:46:50 +0200 From 8b282e3bbe4d9a15ae2de2157498aba31270dc6e Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 16 Jun 2015 16:28:24 +0200 Subject: [PATCH 097/474] write headers is compulsory for eiger --- .../src/UDPStandardImplementation.cpp | 79 ++++++++++--------- 1 file changed, 41 insertions(+), 38 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index bd2e7560a..e6722aeda 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -27,6 +27,7 @@ using namespace std; +#define WRITE_HEADERS UDPStandardImplementation::UDPStandardImplementation() @@ -2380,44 +2381,46 @@ void UDPStandardImplementation::writeToFile_withoutCompression(char* buf,int num offset += EIGER_HEADER_LENGTH; #ifdef WRITE_HEADERS #ifdef VERY_DEBUG - int k = 0; - if(dynamicRange != 32){ - cprintf(RED, "\np1 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf + offset+k*1040)))->num1))); - cprintf(RED, "p1:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset+k*1040)))->num3))); - cprintf(RED, "p0 num:%d - %d\n", k, (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset+k*1040)))->num4))); - k = 1; - cprintf(RED, "p2 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num1))); - cprintf(RED, "p2:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num3))); - cprintf(RED, "p1 num:%d - %d\n", k,(*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num4))); - k = 2; - cprintf(RED, "p3 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf + offset + k*1040)))->num1))); - cprintf(RED, "p3:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num3))); - cprintf(RED, "p2 num:%d - %d\n", k,(*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num4))); - }else{ - k = 0; - cprintf(RED, "\np1 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf + offset+k*1040)))->num1))); - cprintf(RED, "p1:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset+k*1040)))->num3))); - cprintf(RED, "p0 num:%d - %d\n", k, (*(uint16_t*)(((eiger_packet_header *)((char*)(buf + offset+k*1040)))->num2))); - k = 1; - cprintf(RED, "p2 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num1))); - cprintf(RED, "p2:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num3))); - cprintf(RED, "p1 num:%d - %d\n", k, (*(uint16_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num2))); - k = 2; - cprintf(RED, "p3 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf + offset + k*1040)))->num1))); - cprintf(RED, "p3:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num3))); - cprintf(RED, "p2 num:%d - %d\n", k, (*(uint16_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num2))); - k = 256; - cprintf(RED, "p257 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf + offset + k*1040)))->num1))); - cprintf(RED, "p257:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num3))); - cprintf(RED, "p256 num:%d - %d\n", k, (*(uint16_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num2))); - k = 512; - cprintf(RED, "p513 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf + offset + k*1040)))->num1))); - cprintf(RED, "p513:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num3))); - cprintf(RED, "p512 num:%d - %d\n", k, (*(uint16_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num2))); - k = 768; - cprintf(RED, "p769 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf + offset + k*1040)))->num1))); - cprintf(RED, "p769:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num3))); - cprintf(RED, "p768 num:%d - %d\n", k,(*(uint16_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num2))); + if(myDetectorType == EIGER){ + int k = 0; + if(dynamicRange != 32){ + cprintf(RED, "\np1 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf + offset+k*1040)))->num1))); + cprintf(RED, "p1:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset+k*1040)))->num3))); + cprintf(RED, "p0 num:%d - %d\n", k, (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset+k*1040)))->num4))); + k = 1; + cprintf(RED, "p2 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num1))); + cprintf(RED, "p2:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num3))); + cprintf(RED, "p1 num:%d - %d\n", k,(*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num4))); + k = 2; + cprintf(RED, "p3 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf + offset + k*1040)))->num1))); + cprintf(RED, "p3:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num3))); + cprintf(RED, "p2 num:%d - %d\n", k,(*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num4))); + }else{ + k = 0; + cprintf(RED, "\np1 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf + offset+k*1040)))->num1))); + cprintf(RED, "p1:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset+k*1040)))->num3))); + cprintf(RED, "p0 num:%d - %d\n", k, (*(uint16_t*)(((eiger_packet_header *)((char*)(buf + offset+k*1040)))->num2))); + k = 1; + cprintf(RED, "p2 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num1))); + cprintf(RED, "p2:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num3))); + cprintf(RED, "p1 num:%d - %d\n", k, (*(uint16_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num2))); + k = 2; + cprintf(RED, "p3 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf + offset + k*1040)))->num1))); + cprintf(RED, "p3:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num3))); + cprintf(RED, "p2 num:%d - %d\n", k, (*(uint16_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num2))); + k = 256; + cprintf(RED, "p257 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf + offset + k*1040)))->num1))); + cprintf(RED, "p257:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num3))); + cprintf(RED, "p256 num:%d - %d\n", k, (*(uint16_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num2))); + k = 512; + cprintf(RED, "p513 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf + offset + k*1040)))->num1))); + cprintf(RED, "p513:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num3))); + cprintf(RED, "p512 num:%d - %d\n", k, (*(uint16_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num2))); + k = 768; + cprintf(RED, "p769 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf + offset + k*1040)))->num1))); + cprintf(RED, "p769:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num3))); + cprintf(RED, "p768 num:%d - %d\n", k,(*(uint16_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num2))); + } } #endif #endif From 237c5286cad8988da0d94dc1158498cdecd19bdf Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Fri, 26 Jun 2015 11:49:26 +0200 Subject: [PATCH 098/474] includes dynamic range in offline headers for eiger --- slsReceiverSoftware/gitInfo.txt | 8 +++--- slsReceiverSoftware/include/gitInfoReceiver.h | 12 ++++---- .../src/UDPStandardImplementation.cpp | 28 +++++++++++-------- 3 files changed, 27 insertions(+), 21 deletions(-) diff --git a/slsReceiverSoftware/gitInfo.txt b/slsReceiverSoftware/gitInfo.txt index a8b18fa13..787a95474 100644 --- a/slsReceiverSoftware/gitInfo.txt +++ b/slsReceiverSoftware/gitInfo.txt @@ -1,9 +1,9 @@ Path: slsDetectorsPackage/slsReceiverSoftware URL: origin maliakal_d@gitorious.psi.ch:sls_det_software/sls_receiver_software.git Repository Root: origin maliakal_d@gitorious.psi.ch:sls_det_software/sls_receiver_software.git -Repsitory UUID: 44d2a6ae0422ef1d792890a409d202d3cec5b7f7 -Revision: 108 +Repsitory UUID: 2afc468d30f3078b2bb8637584ae3a88f476f20b +Revision: 110 Branch: master Last Changed Author: Dhanya_Maliakal -Last Changed Rev: 108 -Last Changed Date: 2015-06-12 17:46:50 +0200 +Last Changed Rev: 110 +Last Changed Date: 2015-06-16 16:28:24 +0200 diff --git a/slsReceiverSoftware/include/gitInfoReceiver.h b/slsReceiverSoftware/include/gitInfoReceiver.h index 967f26e15..59e2a1dff 100644 --- a/slsReceiverSoftware/include/gitInfoReceiver.h +++ b/slsReceiverSoftware/include/gitInfoReceiver.h @@ -1,11 +1,11 @@ //#define SVNPATH "" -#define SVNURL "git@gitorious.psi.ch:sls_det_software/sls_receiver_software.git" +#define SVNURL "maliakal_d@gitorious.psi.ch:sls_det_software/sls_receiver_software.git" //#define SVNREPPATH "" -#define SVNREPUUID "e019a6ce7d96d4ac9cb5762b7137245aedb4d5b8" -//#define SVNREV 0x22 +#define SVNREPUUID "2afc468d30f3078b2bb8637584ae3a88f476f20b" +//#define SVNREV 0x110 //#define SVNKIND "" //#define SVNSCHED "" -#define SVNAUTH "Anna_Bergamaschi" -#define SVNREV 0x22 -#define SVNDATE 0x20141015 +#define SVNAUTH "Dhanya_Maliakal" +#define SVNREV 0x110 +#define SVNDATE 0x20150616 // diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index e6722aeda..7c6f9ee4e 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1982,13 +1982,27 @@ int UDPStandardImplementation::startWriting(){ for(i=0;i 0){ + } + + else if (numpackets > 0){ for(j=0;jnum1)) = currframenum; + //overwriting port number and dynamic range + if (!j) (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuf[j] + totalheader + EIGER_ONE_GIGA_ONE_PACKET_SIZE*i)))->num3)) = (dynamicRange<<2); + else (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuf[j] + totalheader + EIGER_ONE_GIGA_ONE_PACKET_SIZE*i)))->num3)) = ((dynamicRange<<2)|(0x1)); + +#ifdef VERYDEBUG + cprintf(RED, "%d - 0x%x - %d\n", i, + (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuf[j] + totalheader +i*EIGER_ONE_GIGA_ONE_PACKET_SIZE)))->num3)), + (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuf[j] + totalheader +i*EIGER_ONE_GIGA_ONE_PACKET_SIZE)))->num4))); +#endif + + } //for 32 bit,port number needs to be changed and packet number reconstructed if(dynamicRange == 32){ @@ -1997,10 +2011,6 @@ int UDPStandardImplementation::startWriting(){ (*(uint16_t*)(((eiger_packet_header *)((char*)(wbuf[j] + totalheader + EIGER_ONE_GIGA_ONE_PACKET_SIZE*i)))->num2)) = ((*(uint8_t*)(((eiger_packet_header *)((char*)(wbuf[j] + totalheader + EIGER_ONE_GIGA_ONE_PACKET_SIZE*i)))->num4))); - //new port number as its the same everywhere for 32 bit!! - if((!j)&& (!bottom)) (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuf[j] + totalheader + EIGER_ONE_GIGA_ONE_PACKET_SIZE*i)))->num3)) = 0x00; - - #ifdef VERYDEBUG cprintf(RED, "%d - 0x%x - %d - %d\n", i, (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuf[j] + totalheader +i*EIGER_ONE_GIGA_ONE_PACKET_SIZE)))->num3)), @@ -2013,10 +2023,6 @@ int UDPStandardImplementation::startWriting(){ (*(uint16_t*)(((eiger_packet_header *)((char*)(wbuf[j] + totalheader + EIGER_ONE_GIGA_ONE_PACKET_SIZE*i)))->num2)) = ((*(uint8_t*)(((eiger_packet_header *)((char*)(wbuf[j] + totalheader + EIGER_ONE_GIGA_ONE_PACKET_SIZE*i)))->num4))+(packetsPerFrame/4)); - //new port number as its the same everywhere for 32 bit!! - if(!j) (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuf[j] + totalheader + EIGER_ONE_GIGA_ONE_PACKET_SIZE*i)))->num3)) = 0x00; - - #ifdef VERYDEBUG cprintf(RED, "%d -0x%x - %d - %d\n", i, (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuf[j] + totalheader +i*EIGER_ONE_GIGA_ONE_PACKET_SIZE)))->num3)), From 7e02a9d3d18c8d4d4c220c5d535fc7a8144baae1 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Fri, 26 Jun 2015 15:57:28 +0200 Subject: [PATCH 099/474] resolved flip bytes in eiger --- .../src/slsReceiverTCPIPInterface.cpp | 39 ------------------- 1 file changed, 39 deletions(-) diff --git a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp index 720784b14..5fc7ced7d 100644 --- a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp +++ b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp @@ -1557,45 +1557,6 @@ int slsReceiverTCPIPInterface::eiger_read_frame(){ } } -/* - int inum = 0; - //dr = 16, hence uint16_t - for(inum = 0; inum < 2; inum++) - cprintf(YELLOW,"before htonl %d,0 :%d\n",inum,((uint8_t)(*((uint8_t*)((char*)(retval+(inum*(dynamicrange/8)))))))); - for(inum = 254; inum < 258; inum++) - cprintf(YELLOW,"before htonl %d,0 :%d\n",inum,((uint8_t)(*((uint8_t*)((char*)(retval+(inum*(dynamicrange/8)))))))); - for(inum = 0; inum < 2; inum++) - cprintf(YELLOW,"before htonl %d,2 :%d\n",inum,((uint8_t)(*((uint8_t*)((char*)(retval+((2048+inum)*(dynamicrange/8)))))))); - for(inum = 254; inum < 258; inum++) - cprintf(YELLOW,"before htonl %d,2 :%d\n",inum,((uint8_t)(*((uint8_t*)((char*)(retval+((2048+inum)*(dynamicrange/8)))))))); -*/ - - - //64 bit htonl cuz of endianness - for(i=0;i<(1024*(16*dynamicrange)*2)/8;i++){ - (*(((uint64_t*)retval)+i)) = be64toh(((uint64_t)(*(((uint64_t*)retval)+i)))); - /* - int64_t temp; - temp = ((uint64_t)(*(((uint64_t*)retval)+i))); - temp = ((temp << 8) & 0xFF00FF00FF00FF00ULL ) | ((temp >> 8) & 0x00FF00FF00FF00FFULL ); - temp = ((temp << 16) & 0xFFFF0000FFFF0000ULL ) | ((temp >> 16) & 0x0000FFFF0000FFFFULL ); - temp = (temp << 32) | ((temp >> 32) & 0xFFFFFFFFULL); - (*(((uint64_t*)retval)+i)) = temp; - */ - } - -/* - //dr = 16, hence uint16_t - for(inum = 0; inum < 2; inum++) - cprintf(MAGENTA,"after htonl %d,0 :%d\n",inum,((uint8_t)(*((uint8_t*)((char*)(retval+(inum*(dynamicrange/8)))))))); - for(inum = 254; inum < 258; inum++) - cprintf(MAGENTA,"after htonl %d,0 :%d\n",inum,((uint8_t)(*((uint8_t*)((char*)(retval+(inum*(dynamicrange/8)))))))); - for(inum = 0; inum < 2; inum++) - cprintf(MAGENTA,"after htonl %d,2 :%d\n",inum,((uint8_t)(*((uint8_t*)((char*)(retval+((2048+inum)*(dynamicrange/8)))))))); - for(inum = 254; inum < 258; inum++) - cprintf(MAGENTA,"after htonl %d,2 :%d\n",inum,((uint8_t)(*((uint8_t*)((char*)(retval+((2048+inum)*(dynamicrange/8)))))))); -*/ - acquisitionIndex = index-startAcquisitionIndex; From 3600fb6304554178923167b6d50412a693100944 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Mon, 29 Jun 2015 16:57:16 +0200 Subject: [PATCH 100/474] git rev in --- slsReceiverSoftware/gitInfo.txt | 8 ++++---- slsReceiverSoftware/include/gitInfoReceiver.h | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/slsReceiverSoftware/gitInfo.txt b/slsReceiverSoftware/gitInfo.txt index 787a95474..71d112f95 100644 --- a/slsReceiverSoftware/gitInfo.txt +++ b/slsReceiverSoftware/gitInfo.txt @@ -1,9 +1,9 @@ Path: slsDetectorsPackage/slsReceiverSoftware URL: origin maliakal_d@gitorious.psi.ch:sls_det_software/sls_receiver_software.git Repository Root: origin maliakal_d@gitorious.psi.ch:sls_det_software/sls_receiver_software.git -Repsitory UUID: 2afc468d30f3078b2bb8637584ae3a88f476f20b -Revision: 110 +Repsitory UUID: 750a0a06945a748a18d0b8b19b7cf94ecf2fec23 +Revision: 112 Branch: master Last Changed Author: Dhanya_Maliakal -Last Changed Rev: 110 -Last Changed Date: 2015-06-16 16:28:24 +0200 +Last Changed Rev: 112 +Last Changed Date: 2015-06-26 15:57:28 +0200 diff --git a/slsReceiverSoftware/include/gitInfoReceiver.h b/slsReceiverSoftware/include/gitInfoReceiver.h index 59e2a1dff..19ffa6835 100644 --- a/slsReceiverSoftware/include/gitInfoReceiver.h +++ b/slsReceiverSoftware/include/gitInfoReceiver.h @@ -1,11 +1,11 @@ //#define SVNPATH "" #define SVNURL "maliakal_d@gitorious.psi.ch:sls_det_software/sls_receiver_software.git" //#define SVNREPPATH "" -#define SVNREPUUID "2afc468d30f3078b2bb8637584ae3a88f476f20b" -//#define SVNREV 0x110 +#define SVNREPUUID "750a0a06945a748a18d0b8b19b7cf94ecf2fec23" +//#define SVNREV 0x112 //#define SVNKIND "" //#define SVNSCHED "" #define SVNAUTH "Dhanya_Maliakal" -#define SVNREV 0x110 -#define SVNDATE 0x20150616 +#define SVNREV 0x112 +#define SVNDATE 0x20150626 // From 88e96d45e7da69dea0f98eb6f6001d41a6abf3cb Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 30 Jun 2015 17:21:45 +0200 Subject: [PATCH 101/474] getting dr from rxr fixed --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 8 +++++--- slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp | 8 +++++--- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 7c6f9ee4e..0b22d8888 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -563,10 +563,11 @@ int UDPStandardImplementation::getDynamicRange() const{ int32_t UDPStandardImplementation::setDynamicRange(int32_t dr){ FILE_LOG(logDEBUG) << __AT__ << " called"; - cout << "Setting Dynamic Range" << endl; - int olddr = dynamicRange; + if(dr >= 0){ + cout << "Setting Dynamic Range to " << dr << endl; + dynamicRange = dr; if(myDetectorType == EIGER){ @@ -615,7 +616,8 @@ int32_t UDPStandardImplementation::setDynamicRange(int32_t dr){ FILE_LOG(logDEB } } - } + }else cout << "Getting Dynamic Range " << endl; + return getDynamicRange(); } diff --git a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp index 5fc7ced7d..2c882b139 100644 --- a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp +++ b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp @@ -1996,7 +1996,7 @@ int slsReceiverTCPIPInterface::set_dynamic_range() { sprintf(mess,"Receiver locked by %s\n", socket->lastClientIP); ret=FAIL; } - else if(myDetectorType == EIGER){ + else if ((dr>0) && (myDetectorType == EIGER)){ switch(dr){ case 4: case 8: @@ -2004,6 +2004,7 @@ int slsReceiverTCPIPInterface::set_dynamic_range() { case 32:break; default: sprintf(mess,"This dynamic range does not exist for eiger: %d\n",dr); + cprintf(RED,"%s", mess); ret=FAIL; break; } @@ -2013,8 +2014,9 @@ int slsReceiverTCPIPInterface::set_dynamic_range() { strcpy(mess,"Receiver not set up\n"); ret=FAIL; }else{ - retval=receiverBase->setDynamicRange(dr); - dynamicrange = dr; + if(dr > 0) receiverBase->setDynamicRange(dr); + retval = receiverBase->getDynamicRange(); + dynamicrange = retval; if(myDetectorType == EIGER){ if(!tenGigaEnable) packetsPerFrame = EIGER_ONE_GIGA_CONSTANT * dynamicrange * EIGER_MAX_PORTS; From fbfafb98fd0686471ddb64e66309160c5ba3c5e1 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Fri, 3 Jul 2015 16:10:04 +0200 Subject: [PATCH 102/474] small change --- .../include/UDPStandardImplementation.h | 11 +- .../src/UDPBaseImplementation.cpp | 2 +- .../src/UDPStandardImplementation.cpp | 173 +++++++++++++----- 3 files changed, 140 insertions(+), 46 deletions(-) diff --git a/slsReceiverSoftware/include/UDPStandardImplementation.h b/slsReceiverSoftware/include/UDPStandardImplementation.h index bad7f7a2e..99c159bcb 100644 --- a/slsReceiverSoftware/include/UDPStandardImplementation.h +++ b/slsReceiverSoftware/include/UDPStandardImplementation.h @@ -463,10 +463,19 @@ private: */ void stopWriting(int ithread, char* wbuffer[]); + /** + * updates parameters and writes to file when not a dummy frame + * Also calls writeToFile_withoutCompression or handleDataCompression + * Called by startWriting() + * @param ithread writing thread number + * @param wbuffer writer buffer + * @param npackets number of packets from the fifo + */ + int handleWithoutDataCompression(int ithread, char* wbuffer[], int &npackets); /** * data compression for each fifo output - * @param ithread listening thread number + * @param ithread writing thread number * @param wbuffer writer buffer * @param npackets number of packets from the fifo * @param data pointer to the next packet start diff --git a/slsReceiverSoftware/src/UDPBaseImplementation.cpp b/slsReceiverSoftware/src/UDPBaseImplementation.cpp index bbb8b331d..98adfb6e7 100644 --- a/slsReceiverSoftware/src/UDPBaseImplementation.cpp +++ b/slsReceiverSoftware/src/UDPBaseImplementation.cpp @@ -1826,7 +1826,7 @@ int i; void UDPBaseImplementation::stopWriting(int ithread, char* wbuffer[]){ FILE_LOG(logDEBUG) << __AT__ << " starting"; - int i,j; + int i; #ifdef VERYDEBUG cout << ithread << " **********************popped last dummy frame:" << (void*)wbuffer[wIndex] << endl; #endif diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 0b22d8888..c93b52f9a 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1734,19 +1734,19 @@ int UDPStandardImplementation::startListening(){ cout << ithread << " *** rc:" << dec << rc << ". expected:" << dec << expected << endl; #endif -/* + //start indices for each start of scan/acquisition - eiger does it before if((!measurementStarted) && (rc > 0) && (!ithread)) startFrameIndices(ithread); -*/ + //problem in receiving or end of acquisition if((rc < expected)||(rc <= 0)){ - if(myDetectorType != EIGER){ + /*if(myDetectorType != EIGER){ //start indices for each start of scan/acquisition - this should be done earlier for normal detectors if((!measurementStarted) && (rc > 0) && (!ithread)) startFrameIndices(ithread); - } + }*/ stopListening(ithread,rc,packetcount,total); continue; } @@ -1882,13 +1882,12 @@ int UDPStandardImplementation::startWriting(){ thread_started = 1; - int totalheader = HEADER_SIZE_NUM_TOT_PACKETS + EIGER_HEADER_LENGTH; int numpackets, nf; uint32_t tempframenum; char* wbuf[numListeningThreads];//interleaved char *d=new char[bufferSize*numListeningThreads]; int xmax=0,ymax=0; - int ret,i,j; + int ret,i; int packetsPerThread = packetsPerFrame/numListeningThreads; while(1){ @@ -1927,9 +1926,9 @@ int UDPStandardImplementation::startWriting(){ cprintf(MAGENTA,"%d writer poped from fifo %x\n", ithread, (void*)(wbuf[i])); #endif numpackets = (uint16_t)(*((uint16_t*)wbuf[i])); -#ifdef VERYDEBUG +//#ifdef VERYDEBUG cout << i << " numpackets:" << dec << numpackets << "for fifo :"<< i << endl; -#endif +//#endif } @@ -1947,7 +1946,7 @@ int UDPStandardImplementation::startWriting(){ - //for progress + //update current frame number for progress if(myDetectorType == EIGER){ if(dynamicRange != 32) @@ -1977,12 +1976,12 @@ int UDPStandardImplementation::startWriting(){ #endif - //without datacompression: write datacall back, or write data, free fifo + /* //without datacompression: write datacall back, or write data, free fifo if(!dataCompression){ if (cbAction < DO_EVERYTHING){ for(i=0;ifnum); - else*/ - startFrameIndex = htonl(*(unsigned int*)((eiger_image_header *)((char*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS)))->fnum); + startFrameIndex = htonl(*(unsigned int*)((eiger_image_header *)((char*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS)))->fnum); } //gotthard has +1 for frame number and not a short frame else if ((myDetectorType == GOTTHARD) && (shortFrame == -1)) @@ -2169,19 +2167,19 @@ void UDPStandardImplementation::startFrameIndices(int ithread){ startAcquisitionIndex=startFrameIndex; currframenum = startAcquisitionIndex; acqStarted = true; - cout << "startAcquisitionIndex:" << hex << startAcquisitionIndex<push(buffer[ithread]);/** why not while(!)*/ -#ifdef FIFO_DEBUG - cprintf(BLUE,"%d listener last buffer free pushed into fifofree %x\n", ithread,(void*)(buffer[ithread])); -#endif - } //eiger (complete frames) + other detectors - else{ - pc = (rc/onePacketSize); + pc = (rc/onePacketSize); #ifdef VERYDEBUG - cout << ithread << " last rc:"<push(buffer[ithread])); + (*((uint16_t*)(buffer[ithread]))) = pc; + totalListeningFrameCount[ithread] += pc; + while(!fifo[ithread]->push(buffer[ithread])); #ifdef FIFO_DEBUG - cprintf(RED,"%d listener last buffer pushed into fifo %x\n", ithread,(void*)(buffer[ithread])); + cprintf(RED,"%d listener last buffer pushed into fifo %x\n", ithread,(void*)(buffer[ithread])); #endif - } + } @@ -2269,9 +2256,9 @@ int i; #endif pthread_mutex_unlock(&(status_mutex)); -#ifdef VERYDEBUG +//#ifdef VERYDEBUG cout << ithread << ": Frames listened to " << dec << ((totalListeningFrameCount[ithread]*numListeningThreads)/packetsPerFrame) << endl; -#endif +//#endif //waiting for all listening threads to be done, to print final count of frames listened to if(ithread == 0){ @@ -2281,12 +2268,12 @@ int i; #endif while(listeningthreads_mask) usleep(5000); -#ifdef VERYDEBUG +//#ifdef VERYDEBUG t = 0; for(i=0;i 0){ + for(j=0;jnum1)) = currframenum; + //overwriting port number and dynamic range + if (!j) (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[j] + totalheader + EIGER_ONE_GIGA_ONE_PACKET_SIZE*i)))->num3)) = (dynamicRange<<2); + else (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[j] + totalheader + EIGER_ONE_GIGA_ONE_PACKET_SIZE*i)))->num3)) = ((dynamicRange<<2)|(0x1)); + +#ifdef VERYDEBUG + cprintf(RED, "%d - 0x%x - %d\n", i, + (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[j] + totalheader +i*EIGER_ONE_GIGA_ONE_PACKET_SIZE)))->num3)), + (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[j] + totalheader +i*EIGER_ONE_GIGA_ONE_PACKET_SIZE)))->num4))); +#endif + + } + + //for 32 bit,port number needs to be changed and packet number reconstructed + if(dynamicRange == 32){ + for (i = 0; i < packetsPerFrame/4; i++){ + //new packet number that has space for 16 bit + (*(uint16_t*)(((eiger_packet_header *)((char*)(wbuffer[j] + totalheader + EIGER_ONE_GIGA_ONE_PACKET_SIZE*i)))->num2)) + = ((*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[j] + totalheader + EIGER_ONE_GIGA_ONE_PACKET_SIZE*i)))->num4))); + +#ifdef VERYDEBUG + cprintf(RED, "%d - 0x%x - %d - %d\n", i, + (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[j] + totalheader +i*EIGER_ONE_GIGA_ONE_PACKET_SIZE)))->num3)), + (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[j] + totalheader +i*EIGER_ONE_GIGA_ONE_PACKET_SIZE)))->num4)), + (*(uint16_t*)(((eiger_packet_header *)((char*)(wbuffer[j] + totalheader +i*EIGER_ONE_GIGA_ONE_PACKET_SIZE)))->num2))); +#endif + } + for (i = packetsPerFrame/4; i < packetsPerFrame/2; i++){ + //new packet number that has space for 16 bit + (*(uint16_t*)(((eiger_packet_header *)((char*)(wbuffer[j] + totalheader + EIGER_ONE_GIGA_ONE_PACKET_SIZE*i)))->num2)) + = ((*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[j] + totalheader + EIGER_ONE_GIGA_ONE_PACKET_SIZE*i)))->num4))+(packetsPerFrame/4)); + +#ifdef VERYDEBUG + cprintf(RED, "%d -0x%x - %d - %d\n", i, + (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[j] + totalheader +i*EIGER_ONE_GIGA_ONE_PACKET_SIZE)))->num3)), + (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[j] + totalheader +i*EIGER_ONE_GIGA_ONE_PACKET_SIZE)))->num4)), + (*(uint16_t*)(((eiger_packet_header *)((char*)(wbuffer[j] + totalheader +i*EIGER_ONE_GIGA_ONE_PACKET_SIZE)))->num2))); +#endif + } + } + } +#endif + + writeToFile_withoutCompression(wbuffer[j], npackets,currframenum); + } +#ifdef VERYDEBUG + cprintf(BLUE,"written everyting\n"); +#endif + } + + + if(myDetectorType == EIGER) { +#ifdef VERYDEBUG + cprintf(BLUE,"gonna copy frame\n"); +#endif + copyFrameToGui(wbuffer,currframenum); +#ifdef VERYDEBUG + cprintf(BLUE,"copied frame\n"); +#endif + for(i=0;ipush(wbuffer[i])); +#ifdef FIFO_DEBUG + cprintf(BLUE,"%d writer freed pushed into fifofree %x for listener %d\n",ithread, (void*)(wbuffer[i]),i); +#endif + } + + + } + else{ + //copy to gui + if(npackets >= packetsPerFrame){//min 1 frame, but neednt be + //if(npackets == packetsPerFrame * numJobsPerThread){ //only full frames + copyFrameToGui(NULL,-1,wbuffer[0]+HEADER_SIZE_NUM_TOT_PACKETS); +#ifdef VERYVERBOSE + cout << ithread << " finished copying" << endl; +#endif + }//else cout << "unfinished buffersize" << endl; + while(!fifoFree[0]->push(wbuffer[0])); +#ifdef FIFO_DEBUG + cprintf(BLUE,"%d writer freed pushed into fifofree %x for listener 0\n",ithread, (void*)(wbuffer[0])); +#endif + } +} From 476d1b452f61a1212c8eaf39d90fd28bd5ab89e1 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Fri, 10 Jul 2015 16:04:29 +0200 Subject: [PATCH 103/474] some changes --- .../include/UDPBaseImplementation.h | 3 +- .../include/UDPStandardImplementation.h | 11 +- .../include/sls_receiver_defs.h | 2 +- .../src/UDPBaseImplementation.cpp | 5 +- .../src/UDPStandardImplementation.cpp | 591 +++++++++--------- slsReceiverSoftware/src/slsReceiver.cpp | 2 +- .../src/slsReceiverTCPIPInterface.cpp | 253 ++++---- slsReceiverSoftware/src/slsReceiverUsers.cpp | 2 +- 8 files changed, 444 insertions(+), 425 deletions(-) diff --git a/slsReceiverSoftware/include/UDPBaseImplementation.h b/slsReceiverSoftware/include/UDPBaseImplementation.h index cb5c08195..6a8c53bd3 100644 --- a/slsReceiverSoftware/include/UDPBaseImplementation.h +++ b/slsReceiverSoftware/include/UDPBaseImplementation.h @@ -471,13 +471,12 @@ protected: * data compression for each fifo output * @param ithread listening thread number * @param wbuffer writer buffer - * @param npackets number of packets from the fifo * @param data pointer to the next packet start * @param xmax max pixels in x direction * @param ymax max pixels in y direction * @param nf nf */ - void handleDataCompression(int ithread, char* wbuffer[], int &npackets, char* data, int xmax, int ymax, int &nf); + void handleDataCompression(int ithread, char* wbuffer[], char* data, int xmax, int ymax, int &nf); diff --git a/slsReceiverSoftware/include/UDPStandardImplementation.h b/slsReceiverSoftware/include/UDPStandardImplementation.h index 99c159bcb..4c04265d4 100644 --- a/slsReceiverSoftware/include/UDPStandardImplementation.h +++ b/slsReceiverSoftware/include/UDPStandardImplementation.h @@ -459,9 +459,8 @@ private: /** * When acquisition is over, this is called * @param ithread listening thread number - * @param wbuffer writer buffer */ - void stopWriting(int ithread, char* wbuffer[]); + void stopWriting(int ithread); /** * updates parameters and writes to file when not a dummy frame @@ -469,21 +468,21 @@ private: * Called by startWriting() * @param ithread writing thread number * @param wbuffer writer buffer - * @param npackets number of packets from the fifo + * @param partialframe is 1 if both ports of eiger dont have same frame + * @param smaller is which port is the smaller frame number if only partial frame received */ - int handleWithoutDataCompression(int ithread, char* wbuffer[], int &npackets); + void handleWithoutDataCompression(int ithread, char* wbuffer[], int partialframe = 0, int smaller = 0); /** * data compression for each fifo output * @param ithread writing thread number * @param wbuffer writer buffer - * @param npackets number of packets from the fifo * @param data pointer to the next packet start * @param xmax max pixels in x direction * @param ymax max pixels in y direction * @param nf nf */ - void handleDataCompression(int ithread, char* wbuffer[], int &npackets, char* data, int xmax, int ymax, int &nf); + void handleDataCompression(int ithread, char* wbuffer[], char* data, int xmax, int ymax, int &nf); diff --git a/slsReceiverSoftware/include/sls_receiver_defs.h b/slsReceiverSoftware/include/sls_receiver_defs.h index 025e3b9cf..7ed6e0837 100755 --- a/slsReceiverSoftware/include/sls_receiver_defs.h +++ b/slsReceiverSoftware/include/sls_receiver_defs.h @@ -19,7 +19,7 @@ typedef int int32_t; #define MAX_FRAMES_PER_FILE 20000 #define SHORT_MAX_FRAMES_PER_FILE 100000 #define MOENCH_MAX_FRAMES_PER_FILE 1000 -#define EIGER_MAX_FRAMES_PER_FILE 20000 +#define EIGER_MAX_FRAMES_PER_FILE 20 #define JFCTB_MAX_FRAMES_PER_FILE 100000 diff --git a/slsReceiverSoftware/src/UDPBaseImplementation.cpp b/slsReceiverSoftware/src/UDPBaseImplementation.cpp index 98adfb6e7..b279147ae 100644 --- a/slsReceiverSoftware/src/UDPBaseImplementation.cpp +++ b/slsReceiverSoftware/src/UDPBaseImplementation.cpp @@ -1647,7 +1647,7 @@ int UDPBaseImplementation::startWriting(){ FILE_LOG(logDEBUG) << __AT__ << " sta } //data compression else - handleDataCompression(ithread,wbuf,numpackets,d, xmax, ymax, nf); + handleDataCompression(ithread,wbuf,d, xmax, ymax, nf); @@ -1998,7 +1998,7 @@ void UDPBaseImplementation::writeToFile_withoutCompression(char* buf,int numpack -void UDPBaseImplementation::handleDataCompression(int ithread, char* wbuffer[], int &npackets, char* data, int xmax, int ymax, int &nf){ +void UDPBaseImplementation::handleDataCompression(int ithread, char* wbuffer[], char* data, int xmax, int ymax, int &nf){ FILE_LOG(logDEBUG) << __FILE__ << "::" << __func__ << " starting"; @@ -2009,6 +2009,7 @@ void UDPBaseImplementation::handleDataCompression(int ithread, char* wbuffer[], eventType thisEvent = PEDESTAL; int ndata; char* buff = 0; + int npackets = (uint16_t)(*((uint16_t*)wbuffer[0])); data = wbuffer[0]+ HEADER_SIZE_NUM_TOT_PACKETS; int remainingsize = npackets * onePacketSize; int np; diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index c93b52f9a..cd4963e4b 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1,6 +1,10 @@ /********************************************//** * @file UDPStandardImplementation.cpp * @short does all the functions for a receiver, set/get parameters, start/stop etc. + * update: 08 July 2015 + * startwriting assumes that for eiger numberoflisteningthreads is limited to 2. + * Otherwise logic to compare n number of frame numbers and store previous frames + * is more complicated compared to just 2 threads. ***********************************************/ @@ -850,7 +854,7 @@ void UDPStandardImplementation::setupFifoStructure(){ while(!fifoFree[i]->isEmpty()) fifoFree[i]->pop(buffer[i]); #ifdef FIFO_DEBUG - //cprintf(GREEN,"%d fifostructure popped from fifofree %x\n", i, (void*)(buffer[i])); + cprintf(CYAN,"%d fifostructure popped from fifofree %x\n", i, (void*)(buffer[i])); #endif delete fifoFree[i]; } @@ -872,7 +876,7 @@ void UDPStandardImplementation::setupFifoStructure(){ while (buffer[i]<(mem0[i]+(bufferSize * numJobsPerThread + HEADER_SIZE_NUM_TOT_PACKETS)*(fifosize-1))) { fifoFree[i]->push(buffer[i]); #ifdef FIFO_DEBUG - cprintf(BLUE,"%d fifostructure free pushed into fifofree %x\n", i, (void*)(buffer[i])); + cprintf(CYAN,"%d fifostructure free pushed into fifofree %x\n", i, (void*)(buffer[i])); #endif buffer[i]+=(bufferSize * numJobsPerThread + HEADER_SIZE_NUM_TOT_PACKETS); } @@ -893,7 +897,7 @@ void UDPStandardImplementation::readFrame(char* c,char** raw, uint32_t &fnum, ui if (guiData == NULL){ guiData = latestData; #ifdef VERY_VERY_DEBUG - cprintf(CYAN,"gui data not null anymore\n"); + cprintf(MAGENTA,"gui data not null anymore\n"); #endif } @@ -907,14 +911,14 @@ void UDPStandardImplementation::readFrame(char* c,char** raw, uint32_t &fnum, ui //could not get gui data if(!guiDataReady){ #ifdef VERY_VERY_DEBUG - cprintf(CYAN,"gui data not ready\n"); + cprintf(MAGENTA,"gui data not ready\n"); #endif *raw = NULL; } //data ready, set guidata to receive new data else{ #ifdef VERY_VERY_DEBUG - cprintf(CYAN,"gui data ready\n"); + cprintf(MAGENTA,"gui data ready\n"); #endif *raw = guiData; guiData = NULL; @@ -924,14 +928,14 @@ void UDPStandardImplementation::readFrame(char* c,char** raw, uint32_t &fnum, ui pthread_mutex_unlock(&dataReadyMutex);*/ if((nFrameToGui) && (writerthreads_mask)){ #ifdef VERY_VERY_DEBUG - cprintf(CYAN,"gonna post\n"); + cprintf(MAGENTA,"gonna post\n"); #endif /*if(nFrameToGui){*/ //release after getting data sem_post(&smp); } #ifdef VERY_VERY_DEBUG - cprintf(CYAN,"done post\n"); + cprintf(MAGENTA,"done post\n"); #endif } } @@ -1367,6 +1371,9 @@ int UDPStandardImplementation::createNewFile(){ int gt = getFrameIndex(); if(gt==-1) gt=0; + //just because currframenum will start from 1, while getframeindex will start from 0 + else if(myDetectorType == EIGER) + gt++; //create file name if(frameIndexNeeded==-1) sprintf(savefilename, "%s/%s_%d.raw", filePath,fileName,fileIndex); @@ -1401,6 +1408,8 @@ int UDPStandardImplementation::createNewFile(){ if(!packetsCaught) cout << savefilename << endl; else{ + + cout << savefilename << "\tpacket loss " << setw(4)<pop(buffer[ithread]); #ifdef FIFO_DEBUG - cprintf(GREEN,"%d listener popped from fifofree %x\n", ithread, (void*)(buffer[ithread])); + cprintf(BLUE,"%d listener popped from fifofree %x\n", ithread, (void*)(buffer[ithread])); #endif @@ -1706,14 +1721,17 @@ int UDPStandardImplementation::startListening(){ //normal listening else if(!carryonBufferSize){ - /* if(!ithread){*/ +#ifdef SOCKET_DEBUG + if(!ithread){ +#endif rc = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS, maxBufferSize); //cout<<"value:"<fnum)< 0) && (!ithread)) startFrameIndices(ithread); -//*/ +*/ //reset packetcount = (packetsPerFrame/numListeningThreads) * numJobsPerThread; carryonBufferSize = 0; - //check if last packet valid and calculate packet count switch(myDetectorType){ @@ -1818,30 +1835,72 @@ int UDPStandardImplementation::startListening(){ & (frameIndexMask)) >> frameIndexOffset) << endl; #endif break; - default: + + case EIGER: + lastpacketoffset = (((numJobsPerThread * packetsPerFrame/numListeningThreads - 1) * onePacketSize) + EIGER_HEADER_LENGTH + HEADER_SIZE_NUM_TOT_PACKETS); +#ifdef VERYDEBUG + cprintf(BLUE,"%d fnum: 0x%x\n", ithread, htonl(*(unsigned int*)((eiger_image_header *)((char*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS)))->fnum)); + cprintf(BLUE,"%d 1st pnum: 0x%x\n", ithread, ((*(uint8_t*)(((eiger_packet_header *)((char*)(buffer[ithread] + EIGER_HEADER_LENGTH + HEADER_SIZE_NUM_TOT_PACKETS)))->num4)))); + cprintf(BLUE,"%d last packet offset: %d\n",ithread,lastpacketoffset); + cprintf(BLUE,"%d last pnum: 0x%x\n", ithread,((*(uint8_t*)(((eiger_packet_header *)((char*)(buffer[ithread] + lastpacketoffset)))->num4)))); +/*for 32 bit try to print 64 bit value of packet header to rule out no other byte changes value other than num4 */ +#endif + //if eiger last packet value is NOT as expected according to bit mode + cprintf(BLUE,"%d lastpacket value: %d\n",ithread,((*(uint8_t*)(((eiger_packet_header *)((char*)(buffer[ithread] + lastpacketoffset)))->num4)))); + cprintf(BLUE,"%d lastpacket value -1: %d\n",ithread,((*(uint8_t*)(((eiger_packet_header *)((char*)(buffer[ithread] + lastpacketoffset - onePacketSize)))->num4)))); + + if( ((*(uint8_t*)(((eiger_packet_header *)((char*)(buffer[ithread] + lastpacketoffset)))->num4))) != last_packet_value){ +//#ifdef VERYDEBUG + cprintf(RED,"NOT full frame\n"); +//#endif + lastpacketheader = ((*(uint8_t*)(((eiger_packet_header *)((char*)(buffer[ithread] + lastpacketoffset)))->num4))); + carryonBufferSize += onePacketSize; + cprintf(BLUE,"%d lastpacket value: %d packet count: %d\n",ithread,lastpacketheader,packetcount); + lastpacketoffset -= onePacketSize; + --packetcount; + + cprintf(BLUE,"%d lastpacket value -1: %d\n",ithread,((*(uint8_t*)(((eiger_packet_header *)((char*)(buffer[ithread] + lastpacketoffset - onePacketSize)))->num4)))); + + //while last packet value is greater than current offset packet value (till we reach ff) + while (lastpacketheader > ((*(uint8_t*)(((eiger_packet_header *)((char*)(buffer[ithread] + lastpacketoffset)))->num4))) ){ + lastpacketheader = ((*(uint8_t*)(((eiger_packet_header *)((char*)(buffer[ithread] + lastpacketoffset)))->num4))); + carryonBufferSize += onePacketSize; + cprintf(BLUE,"%d check value: %d lastpacket value: %d packet count: %d\n",ithread,lastpacketheader,packetcount); + lastpacketoffset -= onePacketSize; + --packetcount; + cprintf(BLUE,"%d lastpacket value -1: %d\n",ithread,((*(uint8_t*)(((eiger_packet_header *)((char*)(buffer[ithread] + lastpacketoffset - onePacketSize)))->num4)))); + + } + memcpy(tempchar, buffer[ithread]+(lastpacketoffset+onePacketSize), carryonBufferSize); +//#ifdef VERYDEBUG + cprintf(BLUE,"%d tempchar 1st pnum: 0x%x\n", ithread, ((*(uint8_t*)(((eiger_packet_header *)((char*)(tempchar)))->num4)))); +//#endif + + } + break; + + + default: break; } - // cout<<"*********** "<fnum)<push(buffer[ithread])); #ifdef FIFO_DEBUG //if(!ithread) - cprintf(MAGENTA, "%d listener pushed into fifo %x\n",ithread, (void*)(buffer[ithread])); + cprintf(BLUE, "%d listener pushed into fifo %x\n",ithread, (void*)(buffer[ithread])); #endif } @@ -1877,18 +1936,20 @@ int UDPStandardImplementation::startWriting(){ int ithread = currentWriterThreadIndex; #ifdef VERYVERBOSE - cout << ithread << "In startWriting()" <pop(wbuf[i]); -#ifdef FIFO_DEBUG - cprintf(MAGENTA,"%d writer poped from fifo %x\n", ithread, (void*)(wbuf[i])); -#endif - numpackets = (uint16_t)(*((uint16_t*)wbuf[i])); + //if previous popped out frame was last dummy frame, dont pop out or you're stuck + //also check if there is a previous frame, then also dont pop out or you miss one frame + if(!previousframe[i]){ //#ifdef VERYDEBUG - cout << i << " numpackets:" << dec << numpackets << "for fifo :"<< i << endl; + cprintf(GREEN,"%d writer gonna pop from fifo: %d\n",ithread,i); //#endif + fifo[i]->pop(wbuf[i]); +#ifdef FIFO_DEBUG + cprintf(GREEN,"%d writer poped from fifo %x\n", ithread, (void*)(wbuf[i])); +#endif + numpackets[i] = (uint16_t)(*((uint16_t*)wbuf[i])); +//#ifdef VERYDEBUG + cprintf(GREEN,"%d numpackets: %d for fifo :%d\n", ithread, numpackets[i], i); +//#endif + + + //if last dummy packet, free it + if(numpackets[i] == 0xFFFF){ +//#ifdef VERYDEBUG + cprintf(GREEN, "%d popped last dummy frame:0x%x for listen thread %d\n", ithread, (void*)wbuf[i], i); +//#endif + while(!fifoFree[i]->push(wbuf[i])); +#ifdef FIFO_DEBUG + cprintf(GREEN,"%d writer free dummy pushed into fifofree %x for listener %d\n", ithread,(void*)(wbuf[i]),i); +#endif + + }else allDummyFramesPopped = 0; + } } - //last dummy packet - if(numpackets == 0xFFFF){ + + //if all last dummy frames popped + if(allDummyFramesPopped){ #ifdef VERYDEBUG - cout << "**LAST dummy packet" << endl; + cprintf(GREEN,"%d all dummy frames popped\n", ithread); #endif - stopWriting(ithread,wbuf); + stopWriting(ithread); continue; } #ifdef VERYDEBUG - else cout <<"**NOT a dummy packet"<< dec << numpackets<< endl; + else cprintf(GREEN,"%d NOT all dummy frames popped\n", ,ithread); #endif @@ -1949,14 +2036,42 @@ int UDPStandardImplementation::startWriting(){ //update current frame number for progress if(myDetectorType == EIGER){ - if(dynamicRange != 32) - tempframenum = htonl(*(unsigned int*)((eiger_image_header *)((char*)(wbuf[ithread] + HEADER_SIZE_NUM_TOT_PACKETS)))->fnum); + /* Assuming there are only 2 listening threads of eiger, + * else logic is more complex to find smallest frame number + * and store n number of previous frames for n number of threads */ + + if (numpackets[0] == 0xFFFF) + tempframenum = 0xFFFF; else - tempframenum = htonl(*(unsigned int*)((eiger_image_header *)((char*)(wbuf[ithread] + HEADER_SIZE_NUM_TOT_PACKETS)))->fnum); + tempframenum = htonl(*(unsigned int*)((eiger_image_header *)((char*)(wbuf[0] + HEADER_SIZE_NUM_TOT_PACKETS)))->fnum); + + if (numpackets[1] == 0xFFFF) + tempframenum2 = 0xFFFF; + else + tempframenum2 = htonl(*(unsigned int*)((eiger_image_header *)((char*)(wbuf[1] + HEADER_SIZE_NUM_TOT_PACKETS)))->fnum); - tempframenum += (startFrameIndex-1); //eiger frame numbers start at 1, so need to -1 - //tempframenum = ((tempframenum / EIGER_32BIT_INITIAL_CONSTANT) + startFrameIndex)-1;//eiger 32 bit mode is a multiple of 17c. +startframeindex for scans + //check if one of them is less than the other (both dummies wouldnt reach here) + if(tempframenum!=tempframenum2){ + //frame number of the smaller one + onlyoneport = 1; + smaller = (tempframenum > tempframenum2); + //dummy frame will always be bigger fnum,previousframe = 1 means dont pop out that fifo next time + previousframe[!smaller] = 1; + previousframe[smaller] = 0; + + //update only the smaller number + if (smaller) + tempframenum = tempframenum2; + tempframenum += (startFrameIndex-1); //eiger frame numbers start at 1, so need to -1 + } + //no leftover frames left when you write both + else{ + onlyoneport = 0; + previousframe[0] = 0; + previousframe[1] = 0; + } + }else if ((myDetectorType == GOTTHARD) && (shortFrame == -1)) tempframenum = (((((uint32_t)(*((uint32_t*)(wbuf[ithread] + HEADER_SIZE_NUM_TOT_PACKETS))))+1)& (frameIndexMask)) >> frameIndexOffset); @@ -1972,122 +2087,18 @@ int UDPStandardImplementation::startWriting(){ pthread_mutex_unlock(&progress_mutex); } #ifdef EIGER_DEBUG2 - cout << endl < 0){ - for(j=0;jnum1)) = currframenum; - //overwriting port number and dynamic range - if (!j) (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuf[j] + totalheader + EIGER_ONE_GIGA_ONE_PACKET_SIZE*i)))->num3)) = (dynamicRange<<2); - else (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuf[j] + totalheader + EIGER_ONE_GIGA_ONE_PACKET_SIZE*i)))->num3)) = ((dynamicRange<<2)|(0x1)); - -#ifdef VERYDEBUG - cprintf(RED, "%d - 0x%x - %d\n", i, - (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuf[j] + totalheader +i*EIGER_ONE_GIGA_ONE_PACKET_SIZE)))->num3)), - (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuf[j] + totalheader +i*EIGER_ONE_GIGA_ONE_PACKET_SIZE)))->num4))); -#endif - - } - - //for 32 bit,port number needs to be changed and packet number reconstructed - if(dynamicRange == 32){ - for (i = 0; i < packetsPerFrame/4; i++){ - //new packet number that has space for 16 bit - (*(uint16_t*)(((eiger_packet_header *)((char*)(wbuf[j] + totalheader + EIGER_ONE_GIGA_ONE_PACKET_SIZE*i)))->num2)) - = ((*(uint8_t*)(((eiger_packet_header *)((char*)(wbuf[j] + totalheader + EIGER_ONE_GIGA_ONE_PACKET_SIZE*i)))->num4))); - -#ifdef VERYDEBUG - cprintf(RED, "%d - 0x%x - %d - %d\n", i, - (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuf[j] + totalheader +i*EIGER_ONE_GIGA_ONE_PACKET_SIZE)))->num3)), - (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuf[j] + totalheader +i*EIGER_ONE_GIGA_ONE_PACKET_SIZE)))->num4)), - (*(uint16_t*)(((eiger_packet_header *)((char*)(wbuf[j] + totalheader +i*EIGER_ONE_GIGA_ONE_PACKET_SIZE)))->num2))); -#endif - } - for (i = packetsPerFrame/4; i < packetsPerFrame/2; i++){ - //new packet number that has space for 16 bit - (*(uint16_t*)(((eiger_packet_header *)((char*)(wbuf[j] + totalheader + EIGER_ONE_GIGA_ONE_PACKET_SIZE*i)))->num2)) - = ((*(uint8_t*)(((eiger_packet_header *)((char*)(wbuf[j] + totalheader + EIGER_ONE_GIGA_ONE_PACKET_SIZE*i)))->num4))+(packetsPerFrame/4)); - -#ifdef VERYDEBUG - cprintf(RED, "%d -0x%x - %d - %d\n", i, - (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuf[j] + totalheader +i*EIGER_ONE_GIGA_ONE_PACKET_SIZE)))->num3)), - (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuf[j] + totalheader +i*EIGER_ONE_GIGA_ONE_PACKET_SIZE)))->num4)), - (*(uint16_t*)(((eiger_packet_header *)((char*)(wbuf[j] + totalheader +i*EIGER_ONE_GIGA_ONE_PACKET_SIZE)))->num2))); -#endif - } - } - } -#endif - - writeToFile_withoutCompression(wbuf[j], numpackets,currframenum); - } -#ifdef VERYDEBUG - cprintf(BLUE,"written everyting\n"); -#endif - } - - - if(myDetectorType == EIGER) { -#ifdef VERYDEBUG - cprintf(BLUE,"gonna copy frame\n"); -#endif - copyFrameToGui(wbuf,currframenum); -#ifdef VERYDEBUG - cprintf(BLUE,"copied frame\n"); -#endif - for(i=0;ipush(wbuf[i])); -#ifdef FIFO_DEBUG - cprintf(BLUE,"%d writer freed pushed into fifofree %x for listener %d\n",ithread, (void*)(wbuf[i]),i); -#endif - } - - - } - else{ - //copy to gui - if(numpackets >= packetsPerFrame){//min 1 frame, but neednt be - //if(numpackets == packetsPerFrame * numJobsPerThread){ //only full frames - copyFrameToGui(NULL,-1,wbuf[0]+HEADER_SIZE_NUM_TOT_PACKETS); -#ifdef VERYVERBOSE - cout << ithread << " finished copying" << endl; -#endif - }//else cout << "unfinished buffersize" << endl; - while(!fifoFree[0]->push(wbuf[0])); -#ifdef FIFO_DEBUG - cprintf(BLUE,"%d writer freed pushed into fifofree %x for listener 0\n",ithread, (void*)(wbuf[0])); -#endif - } - } - */ //without datacompression: write datacall back, or write data, free fifo - if(!dataCompression) handleWithoutDataCompression(ithread,wbuf,numpackets); + if(!dataCompression) handleWithoutDataCompression(ithread,wbuf,onlyoneport,smaller); //data compression - else handleDataCompression(ithread,wbuf,numpackets,d, xmax, ymax, nf); - - - + else handleDataCompression(ithread,wbuf,d, xmax, ymax, nf); } #ifdef VERYVERBOSE - cout << ithread << " gonna wait for 1st sem" << endl; + cprintf(GREEN,"%d gonna wait for 1st sem\n", ithread); #endif //wait sem_wait(&writersmp[ithread]); @@ -2097,7 +2108,7 @@ int UDPStandardImplementation::startWriting(){ pthread_exit(NULL); } #ifdef VERYVERBOSE - cout << ithread << " got 1st post" << endl; + cprintf(GREEN,"%d got 1st post\n", ithread); #endif @@ -2124,7 +2135,7 @@ int UDPStandardImplementation::startWriting(){ #ifdef VERYVERBOSE - cout << ithread << " gonna wait for 2nd sem" << endl; + cprintf(GREEN,"%d gonna wait for 2nd sem\n", ithread); #endif //wait sem_wait(&writersmp[ithread]); @@ -2134,7 +2145,7 @@ int UDPStandardImplementation::startWriting(){ pthread_exit(NULL); } #ifdef VERYVERBOSE - cout << ithread << " got 2nd post" << endl; + cprintf(GREEN,"%d got 2nd post\n", ithread); #endif } @@ -2167,7 +2178,7 @@ void UDPStandardImplementation::startFrameIndices(int ithread){ startAcquisitionIndex=startFrameIndex; currframenum = startAcquisitionIndex; acqStarted = true; - cout << "startAcquisitionIndex:" << dec << startAcquisitionIndex<push(buffer[ithread]); #ifdef FIFO_DEBUG cprintf(BLUE,"%d listener not txm free pushed into fifofree %x\n", ithread,(void*)(buffer[ithread])); @@ -2207,7 +2218,7 @@ int i; //free buffer if(rc <= 0){ - cout << ithread << "Discarding empty frame/ End of acquisition" << endl; + cprintf(BLUE,"%d End of acquisition\n", ithread); fifoFree[ithread]->push(buffer[ithread]);/** why not while(!)*/ #ifdef FIFO_DEBUG cprintf(BLUE,"%d listener empty buffer pushed into fifofree %x\n", ithread, (void*)(buffer[ithread])); @@ -2215,17 +2226,20 @@ int i; } //push the last buffer into fifo else{ + + if (rc < (bufferSize * numJobsPerThread)) + cprintf(RED,"%d Pushing Incomplete frame into fifo\n", ithread); //eiger (complete frames) + other detectors pc = (rc/onePacketSize); -#ifdef VERYDEBUG - cout << ithread << " last rc:"<push(buffer[ithread])); #ifdef FIFO_DEBUG - cprintf(RED,"%d listener last buffer pushed into fifo %x\n", ithread,(void*)(buffer[ithread])); + cprintf(BLUE,"%d listener last buffer pushed into fifo %x\n", ithread,(void*)(buffer[ithread])); #endif } @@ -2236,15 +2250,15 @@ int i; for(i=0;ipop(buffer[ithread]); #ifdef FIFO_DEBUG - cprintf(GREEN,"%d listener popped dummy buffer from fifofree %x\n", ithread,(void*)(buffer[ithread])); + cprintf(BLUE,"%d listener popped dummy buffer from fifofree %x\n", ithread,(void*)(buffer[ithread])); #endif (*((uint16_t*)(buffer[ithread]))) = 0xFFFF; #ifdef VERYDEBUG - cout << ithread << " dummy buffer num packets:"<< (*((uint16_t*)(buffer[ithread]))) << endl; + cprintf(BLUE,"%d dummy buffer num packets:%d\n", ithread(*((uint16_t*)(buffer[ithread])))); #endif while(!fifo[ithread]->push(buffer[ithread])); #ifdef FIFO_DEBUG - cprintf(RED,"%d listener pushed dummy buffer into fifo %x\n", ithread,(void*)(buffer[ithread])); + cprintf(BLUE,"%d listener pushed dummy buffer into fifo %x\n", ithread,(void*)(buffer[ithread])); #endif } @@ -2252,19 +2266,19 @@ int i; pthread_mutex_lock(&status_mutex); listeningthreads_mask^=(1< 1) - cout << "Waiting for listening to be done.. current mask:" << hex << listeningthreads_mask << endl; + cprintf(BLUE,"%d Waiting for listening to be done.. current mask:0x%x\n", ithread, listeningthreads_mask); #endif while(listeningthreads_mask) usleep(5000); @@ -2272,7 +2286,7 @@ int i; t = 0; for(i=0;ipush(wbuffer[i])); -#ifdef FIFO_DEBUG - cprintf(BLUE,"%d writer free dummy pushed into fifofree %x for listener %d\n", ithread,(void*)(wbuffer[i]),i); -#endif - } - - - //all threads need to close file, reset mask and exit loop closeFile(ithread); pthread_mutex_lock(&status_mutex); writerthreads_mask^=(1<num1))); - cprintf(RED, "p1:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset+k*1040)))->num3))); - cprintf(RED, "p0 num:%d - %d\n", k, (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset+k*1040)))->num4))); + cprintf(GREEN, "\np1 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf + offset+k*1040)))->num1))); + cprintf(GREEN, "p1:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset+k*1040)))->num3))); + cprintf(GREEN, "p0 num:%d - %d\n", k, (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset+k*1040)))->num4))); k = 1; - cprintf(RED, "p2 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num1))); - cprintf(RED, "p2:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num3))); - cprintf(RED, "p1 num:%d - %d\n", k,(*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num4))); + cprintf(GREEN, "p2 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num1))); + cprintf(GREEN, "p2:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num3))); + cprintf(GREEN, "p1 num:%d - %d\n", k,(*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num4))); k = 2; - cprintf(RED, "p3 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf + offset + k*1040)))->num1))); - cprintf(RED, "p3:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num3))); - cprintf(RED, "p2 num:%d - %d\n", k,(*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num4))); + cprintf(GREEN, "p3 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf + offset + k*1040)))->num1))); + cprintf(GREEN, "p3:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num3))); + cprintf(GREEN, "p2 num:%d - %d\n", k,(*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num4))); }else{ k = 0; - cprintf(RED, "\np1 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf + offset+k*1040)))->num1))); - cprintf(RED, "p1:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset+k*1040)))->num3))); - cprintf(RED, "p0 num:%d - %d\n", k, (*(uint16_t*)(((eiger_packet_header *)((char*)(buf + offset+k*1040)))->num2))); + cprintf(GREEN, "\np1 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf + offset+k*1040)))->num1))); + cprintf(GREEN, "p1:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset+k*1040)))->num3))); + cprintf(GREEN, "p0 num:%d - %d\n", k, (*(uint16_t*)(((eiger_packet_header *)((char*)(buf + offset+k*1040)))->num2))); k = 1; - cprintf(RED, "p2 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num1))); - cprintf(RED, "p2:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num3))); - cprintf(RED, "p1 num:%d - %d\n", k, (*(uint16_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num2))); + cprintf(GREEN, "p2 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num1))); + cprintf(GREEN, "p2:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num3))); + cprintf(GREEN, "p1 num:%d - %d\n", k, (*(uint16_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num2))); k = 2; - cprintf(RED, "p3 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf + offset + k*1040)))->num1))); - cprintf(RED, "p3:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num3))); - cprintf(RED, "p2 num:%d - %d\n", k, (*(uint16_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num2))); + cprintf(GREEN, "p3 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf + offset + k*1040)))->num1))); + cprintf(GREEN, "p3:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num3))); + cprintf(GREEN, "p2 num:%d - %d\n", k, (*(uint16_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num2))); k = 256; - cprintf(RED, "p257 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf + offset + k*1040)))->num1))); - cprintf(RED, "p257:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num3))); - cprintf(RED, "p256 num:%d - %d\n", k, (*(uint16_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num2))); + cprintf(GREEN, "p257 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf + offset + k*1040)))->num1))); + cprintf(GREEN, "p257:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num3))); + cprintf(GREEN, "p256 num:%d - %d\n", k, (*(uint16_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num2))); k = 512; - cprintf(RED, "p513 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf + offset + k*1040)))->num1))); - cprintf(RED, "p513:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num3))); - cprintf(RED, "p512 num:%d - %d\n", k, (*(uint16_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num2))); + cprintf(GREEN, "p513 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf + offset + k*1040)))->num1))); + cprintf(GREEN, "p513:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num3))); + cprintf(GREEN, "p512 num:%d - %d\n", k, (*(uint16_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num2))); k = 768; - cprintf(RED, "p769 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf + offset + k*1040)))->num1))); - cprintf(RED, "p769:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num3))); - cprintf(RED, "p768 num:%d - %d\n", k,(*(uint16_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num2))); + cprintf(GREEN, "p769 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf + offset + k*1040)))->num1))); + cprintf(GREEN, "p769:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num3))); + cprintf(GREEN, "p768 num:%d - %d\n", k,(*(uint16_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num2))); } } #endif @@ -2435,9 +2434,9 @@ void UDPStandardImplementation::writeToFile_withoutCompression(char* buf,int num if(tempframenum > currframenum) currframenum = tempframenum; } -#ifdef VERYDEBUG - cout << "tempframenum:" << dec << tempframenum << " curframenum:" << currframenum << endl; -#endif +//#ifdef VERYDEBUG + cprintf(GREEN,"tempframenum: %d curframenum: %d\n",tempframenum,currframenum); +//#endif //lock if(numWriterThreads > 1) @@ -2454,7 +2453,7 @@ void UDPStandardImplementation::writeToFile_withoutCompression(char* buf,int num packetsCaught += packetsToSave; totalPacketsCaught += packetsToSave; #ifdef VERYDEBUG - cout << "/totalPacketsCaught:" << dec << totalPacketsCaught <= maxPacketsPerFile){ @@ -2472,9 +2471,9 @@ void UDPStandardImplementation::writeToFile_withoutCompression(char* buf,int num if(tempframenum > currframenum) currframenum = tempframenum; } -#ifdef VERYDEBUG - cout << "tempframenum:" << dec << tempframenum << " curframenum:" << currframenum << endl; -#endif +//#ifdef VERYDEBUG + cprintf(GREEN,"tempframenum: %d curframenum: %d\n", tempframenum ,currframenum); +//#endif //create createNewFile(); } @@ -2503,87 +2502,102 @@ void UDPStandardImplementation::writeToFile_withoutCompression(char* buf,int num -int UDPStandardImplementation::handleWithoutDataCompression(int ithread, char* wbuffer[], int &npackets){ +void UDPStandardImplementation::handleWithoutDataCompression(int ithread, char* wbuffer[], int partialframe, int smaller){ int totalheader = HEADER_SIZE_NUM_TOT_PACKETS + EIGER_HEADER_LENGTH; - int i,j; + int i,j,npackets; if (cbAction < DO_EVERYTHING){ - for(i=0;i 0){ + else { for(j=0;j 0){ + #ifdef WRITE_HEADERS - if (myDetectorType == EIGER){ + if (myDetectorType == EIGER){ - for (i = 0; i < packetsPerFrame/2; i++){ - //overwriting frame number in header - (*(uint32_t*)(((eiger_packet_header *)((char*)(wbuffer[j] + totalheader + EIGER_ONE_GIGA_ONE_PACKET_SIZE*i)))->num1)) = currframenum; - //overwriting port number and dynamic range - if (!j) (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[j] + totalheader + EIGER_ONE_GIGA_ONE_PACKET_SIZE*i)))->num3)) = (dynamicRange<<2); - else (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[j] + totalheader + EIGER_ONE_GIGA_ONE_PACKET_SIZE*i)))->num3)) = ((dynamicRange<<2)|(0x1)); + for (i = 0; i < packetsPerFrame/2; i++){ + //overwriting frame number in header + (*(uint32_t*)(((eiger_packet_header *)((char*)(wbuffer[j] + totalheader + onePacketSize*i)))->num1)) = currframenum; + //overwriting port number and dynamic range + if (!j) (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[j] + totalheader + onePacketSize*i)))->num3)) = (dynamicRange<<2); + else (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[j] + totalheader + onePacketSize*i)))->num3)) = ((dynamicRange<<2)|(0x1)); #ifdef VERYDEBUG - cprintf(RED, "%d - 0x%x - %d\n", i, - (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[j] + totalheader +i*EIGER_ONE_GIGA_ONE_PACKET_SIZE)))->num3)), - (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[j] + totalheader +i*EIGER_ONE_GIGA_ONE_PACKET_SIZE)))->num4))); + cprintf(GREEN, "%d - 0x%x - %d\n", i, + (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[j] + totalheader +i*onePacketSize)))->num3)), + (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[j] + totalheader +i*onePacketSize)))->num4))); #endif - } - - //for 32 bit,port number needs to be changed and packet number reconstructed - if(dynamicRange == 32){ - for (i = 0; i < packetsPerFrame/4; i++){ - //new packet number that has space for 16 bit - (*(uint16_t*)(((eiger_packet_header *)((char*)(wbuffer[j] + totalheader + EIGER_ONE_GIGA_ONE_PACKET_SIZE*i)))->num2)) - = ((*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[j] + totalheader + EIGER_ONE_GIGA_ONE_PACKET_SIZE*i)))->num4))); - -#ifdef VERYDEBUG - cprintf(RED, "%d - 0x%x - %d - %d\n", i, - (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[j] + totalheader +i*EIGER_ONE_GIGA_ONE_PACKET_SIZE)))->num3)), - (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[j] + totalheader +i*EIGER_ONE_GIGA_ONE_PACKET_SIZE)))->num4)), - (*(uint16_t*)(((eiger_packet_header *)((char*)(wbuffer[j] + totalheader +i*EIGER_ONE_GIGA_ONE_PACKET_SIZE)))->num2))); -#endif } - for (i = packetsPerFrame/4; i < packetsPerFrame/2; i++){ - //new packet number that has space for 16 bit - (*(uint16_t*)(((eiger_packet_header *)((char*)(wbuffer[j] + totalheader + EIGER_ONE_GIGA_ONE_PACKET_SIZE*i)))->num2)) - = ((*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[j] + totalheader + EIGER_ONE_GIGA_ONE_PACKET_SIZE*i)))->num4))+(packetsPerFrame/4)); + + //for 32 bit,port number needs to be changed and packet number reconstructed + if(dynamicRange == 32){ + for (i = 0; i < packetsPerFrame/4; i++){ + //new packet number that has space for 16 bit + (*(uint16_t*)(((eiger_packet_header *)((char*)(wbuffer[j] + totalheader + onePacketSize*i)))->num2)) + = ((*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[j] + totalheader + onePacketSize*i)))->num4))); #ifdef VERYDEBUG - cprintf(RED, "%d -0x%x - %d - %d\n", i, - (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[j] + totalheader +i*EIGER_ONE_GIGA_ONE_PACKET_SIZE)))->num3)), - (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[j] + totalheader +i*EIGER_ONE_GIGA_ONE_PACKET_SIZE)))->num4)), - (*(uint16_t*)(((eiger_packet_header *)((char*)(wbuffer[j] + totalheader +i*EIGER_ONE_GIGA_ONE_PACKET_SIZE)))->num2))); + cprintf(GREEN, "%d - 0x%x - %d - %d\n", i, + (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[j] + totalheader +i*onePacketSize)))->num3)), + (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[j] + totalheader +i*onePacketSize)))->num4)), + (*(uint16_t*)(((eiger_packet_header *)((char*)(wbuffer[j] + totalheader +i*onePacketSize)))->num2))); #endif + } + for (i = packetsPerFrame/4; i < packetsPerFrame/2; i++){ + //new packet number that has space for 16 bit + (*(uint16_t*)(((eiger_packet_header *)((char*)(wbuffer[j] + totalheader + onePacketSize*i)))->num2)) + = ((*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[j] + totalheader + onePacketSize*i)))->num4))+(packetsPerFrame/4)); + +#ifdef VERYDEBUG + cprintf(GREEN, "%d -0x%x - %d - %d\n", i, + (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[j] + totalheader +i*onePacketSize)))->num3)), + (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[j] + totalheader +i*onePacketSize)))->num4)), + (*(uint16_t*)(((eiger_packet_header *)((char*)(wbuffer[j] + totalheader +i*onePacketSize)))->num2))); +#endif + } } } +#endif + + writeToFile_withoutCompression(wbuffer[j], npackets,currframenum); } -#endif - - writeToFile_withoutCompression(wbuffer[j], npackets,currframenum); } #ifdef VERYDEBUG - cprintf(BLUE,"written everyting\n"); + cprintf(GREEN,"written everyting\n"); #endif } if(myDetectorType == EIGER) { + if(!partialframe){ #ifdef VERYDEBUG - cprintf(BLUE,"gonna copy frame\n"); -#endif - copyFrameToGui(wbuffer,currframenum); -#ifdef VERYDEBUG - cprintf(BLUE,"copied frame\n"); + cprintf(GREEN,"gonna copy frame\n"); #endif + copyFrameToGui(wbuffer,currframenum); +//#ifdef VERYDEBUG + cprintf(GREEN,"copied frame\n"); +//#endif + } for(i=0;ipush(wbuffer[i])); #ifdef FIFO_DEBUG - cprintf(BLUE,"%d writer freed pushed into fifofree %x for listener %d\n",ithread, (void*)(wbuffer[i]),i); + cprintf(GREEN,"%d writer freed pushed into fifofree %x for listener %d\n",ithread, (void*)(wbuffer[i]),i); #endif } @@ -2600,7 +2614,7 @@ int UDPStandardImplementation::handleWithoutDataCompression(int ithread, char* w }//else cout << "unfinished buffersize" << endl; while(!fifoFree[0]->push(wbuffer[0])); #ifdef FIFO_DEBUG - cprintf(BLUE,"%d writer freed pushed into fifofree %x for listener 0\n",ithread, (void*)(wbuffer[0])); + cprintf(GREEN,"%d writer freed pushed into fifofree %x for listener 0\n",ithread, (void*)(wbuffer[0])); #endif } } @@ -2611,7 +2625,7 @@ int UDPStandardImplementation::handleWithoutDataCompression(int ithread, char* w -void UDPStandardImplementation::handleDataCompression(int ithread, char* wbuffer[], int &npackets, char* data, int xmax, int ymax, int &nf){ +void UDPStandardImplementation::handleDataCompression(int ithread, char* wbuffer[], char* data, int xmax, int ymax, int &nf){ FILE_LOG(logDEBUG) << __AT__ << " called"; #if defined(MYROOT1) && defined(ALLFILE_DEBUG) @@ -2621,6 +2635,7 @@ void UDPStandardImplementation::handleDataCompression(int ithread, char* wbuffer eventType thisEvent = PEDESTAL; int ndata; char* buff = 0; + int npackets = (uint16_t)(*((uint16_t*)wbuffer[0])); data = wbuffer[0]+ HEADER_SIZE_NUM_TOT_PACKETS; int remainingsize = npackets * onePacketSize; int np; @@ -2701,7 +2716,7 @@ void UDPStandardImplementation::handleDataCompression(int ithread, char* wbuffer while(!fifoFree[0]->push(wbuffer[0])); #ifdef FIFO_DEBUG - cprintf(BLUE,"%d writer compression free pushed into fifofree %x for listerner 0\n", ithread, (void*)(wbuffer[0])); + cprintf(GREEN,"%d writer compression free pushed into fifofree %x for listerner 0\n", ithread, (void*)(wbuffer[0])); #endif } diff --git a/slsReceiverSoftware/src/slsReceiver.cpp b/slsReceiverSoftware/src/slsReceiver.cpp index e43820613..5783e601c 100644 --- a/slsReceiverSoftware/src/slsReceiver.cpp +++ b/slsReceiverSoftware/src/slsReceiver.cpp @@ -162,7 +162,7 @@ void slsReceiver::closeFile(int p) { int64_t slsReceiver::getReceiverVersion(){ - tcpipInterface->getReceiverVersion(); + return tcpipInterface->getReceiverVersion(); } diff --git a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp index 2c882b139..bcefc85d8 100644 --- a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp +++ b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp @@ -32,25 +32,25 @@ slsReceiverTCPIPInterface::~slsReceiverTCPIPInterface() { } slsReceiverTCPIPInterface::slsReceiverTCPIPInterface(int &success, UDPInterface* rbase, int pn, bool bot): - myDetectorType(GOTTHARD), - receiverBase(rbase), - ret(OK), - lockStatus(0), - shortFrame(-1), - packetsPerFrame(GOTTHARD_PACKETS_PER_FRAME), - dynamicrange(16), - socket(NULL), - killTCPServerThread(0), - tenGigaEnable(0), portNumber(DEFAULT_PORTNO+2), - bottom(bot){ + myDetectorType(GOTTHARD), + receiverBase(rbase), + ret(OK), + lockStatus(0), + shortFrame(-1), + packetsPerFrame(GOTTHARD_PACKETS_PER_FRAME), + dynamicrange(16), + socket(NULL), + killTCPServerThread(0), + tenGigaEnable(0), portNumber(DEFAULT_PORTNO+2), + bottom(bot){ - int port_no=portNumber; - if(receiverBase == NULL) receiverBase = 0; + int port_no=portNumber; + if(receiverBase == NULL) receiverBase = 0; - if (pn>0) - port_no = pn; + if (pn>0) + port_no = pn; - success=OK; + success=OK; //create socket if(success == OK){ @@ -65,58 +65,60 @@ slsReceiverTCPIPInterface::slsReceiverTCPIPInterface(int &success, UDPInterface* strcpy(socket->lastClientIP,"none"); strcpy(socket->thisClientIP,"none1"); strcpy(mess,"dummy message"); - + function_table(); #ifdef VERBOSE cout << "Function table assigned." << endl; #endif - + //Catch signal SIGINT to close files properly signal(SIGINT,staticCloseFile); } } - + } int slsReceiverTCPIPInterface::setPortNumber(int pn){ int p_number; - MySocketTCP *oldsocket=NULL;; - int sd=0; - if (pn>0) { - p_number = pn; - - if (p_number<1024) { - sprintf(mess,"Too low port number %d\n", p_number); - cout << mess << endl; - } else { - - oldsocket=socket; - socket = new MySocketTCP(p_number); - if(socket){ - sd = socket->getErrorStatus(); - if (!sd){ - portNumber=p_number; - delete oldsocket; - } else { - cout << "Could not bind port " << p_number << endl; - if (sd==-10) { - - cout << "Port "<< p_number << " already set" << endl; - } else { - delete socket; - socket=oldsocket; - } + MySocketTCP *oldsocket=NULL;; + int sd=0; + + if (pn>0) { + p_number = pn; + + if (p_number<1024) { + sprintf(mess,"Too low port number %d\n", p_number); + cout << mess << endl; + } else { + + oldsocket=socket; + socket = new MySocketTCP(p_number); + if(socket){ + sd = socket->getErrorStatus(); + if (!sd){ + portNumber=p_number; + strcpy(socket->lastClientIP,oldsocket->lastClientIP); + delete oldsocket; + } else { + cout << "Could not bind port " << p_number << endl; + if (sd==-10) { + + cout << "Port "<< p_number << " already set" << endl; + } else { + delete socket; + socket=oldsocket; + } + } + + } else { + socket=oldsocket; + } + } } - - } else { - socket=oldsocket; - } - } - } - return portNumber; + return portNumber; } @@ -142,7 +144,7 @@ void slsReceiverTCPIPInterface::stop(){ receiverBase->shutDownUDPSockets(); cout << "Closing Files... " << endl; - receiverBase->closeFile(); + receiverBase->closeFile(); cout<<"Shutting down TCP Socket and TCP thread"<differentClients){ @@ -426,7 +428,7 @@ int slsReceiverTCPIPInterface::set_file_name() { strcpy(mess,"Receiver not set up\n"); ret=FAIL; } - else + else strcpy(retval,receiverBase->setFileName(fName)); } #ifdef VERBOSE @@ -671,44 +673,44 @@ int slsReceiverTCPIPInterface::setup_udp(){ } else{ //set up udp port - sscanf(args[1],"%d",&udpport); - sscanf(args[2],"%d",&udpport2); - receiverBase->setUDPPortNo(udpport); - receiverBase->setUDPPortNo2(udpport2); - //setup udpip - //get ethernet interface or IP to listen to - cout << "Ethernet interface is " << args[0] << endl; - temp = genericSocket::ipToName(args[0]); - cout << temp << endl; - if(temp=="none"){ - ret = FAIL; - strcpy(mess, "failed to get ethernet interface or IP to listen to\n"); - } - else{ - strcpy(eth,temp.c_str()); - if (strchr(eth,'.')!=NULL) { - strcpy(eth,""); - ret = FAIL; - } - FILE_LOG(logDEBUG) << __FILE__ << "::" << __func__ << " " << eth; - receiverBase->setEthernetInterface(eth); + sscanf(args[1],"%d",&udpport); + sscanf(args[2],"%d",&udpport2); + receiverBase->setUDPPortNo(udpport); + receiverBase->setUDPPortNo2(udpport2); + //setup udpip + //get ethernet interface or IP to listen to + cout << "Ethernet interface is " << args[0] << endl; + temp = genericSocket::ipToName(args[0]); + cout << temp << endl; + if(temp=="none"){ + ret = FAIL; + strcpy(mess, "failed to get ethernet interface or IP to listen to\n"); + } + else{ + strcpy(eth,temp.c_str()); + if (strchr(eth,'.')!=NULL) { + strcpy(eth,""); + ret = FAIL; + } + FILE_LOG(logDEBUG) << __FILE__ << "::" << __func__ << " " << eth; + receiverBase->setEthernetInterface(eth); - cout << eth << endl; - //get mac address from ethernet interface - if (ret != FAIL) + cout << eth << endl; + //get mac address from ethernet interface + if (ret != FAIL) temp = genericSocket::nameToMac(eth); - - if ((temp=="00:00:00:00:00:00") || (ret == FAIL)){ - ret = FAIL; - strcpy(mess,"failed to get mac adddress to listen to\n"); - cout << "mess:" << mess << endl; - } - else{ - strcpy(retval,temp.c_str()); - cout<<"mac:"<> GOTTHARD_FRAME_INDEX_OFFSET); #ifdef VERBOSE - cout << "index1:" << hex << index << endl; - cout << "index2:" << hex << index << endl; + cout << "index1:" << hex << index << endl; + cout << "index2:" << hex << index << endl; #endif } @@ -1310,21 +1312,21 @@ int slsReceiverTCPIPInterface::gotthard_read_frame(){ /*//ignore if half frame is missing if ((bindex != 0xFFFFFFFF) && (bindex2 != 0xFFFFFFFF)){*/ - //should be same frame - if (index == index2){ - //ideal situation (should be odd, even(index+1)) - if(!pindex){ - memcpy(retval,((char*) origVal)+4, onedatasize); - memcpy((((char*)retval)+onedatasize), ((char*) origVal)+10+onedatasize, onedatasize); - } - //swap to even,odd - else{ - memcpy((((char*)retval)+onedatasize),((char*) origVal)+4, onedatasize); - memcpy(retval, ((char*) origVal)+10+onedatasize, onedatasize); - index=index2; - } - }else - cout << "different frames caught. frame1:"<< hex << index << ":"<initialize(hostname); + else{ + receiverBase->initialize(hostname); strcpy(retval,receiverBase->getDetectorHostname()); - } + } } #ifdef VERBOSE if(ret!=FAIL) @@ -1998,15 +2000,15 @@ int slsReceiverTCPIPInterface::set_dynamic_range() { } else if ((dr>0) && (myDetectorType == EIGER)){ switch(dr){ - case 4: - case 8: - case 16: - case 32:break; - default: - sprintf(mess,"This dynamic range does not exist for eiger: %d\n",dr); - cprintf(RED,"%s", mess); - ret=FAIL; - break; + case 4: + case 8: + case 16: + case 32:break; + default: + sprintf(mess,"This dynamic range does not exist for eiger: %d\n",dr); + cprintf(RED,"%s", mess); + ret=FAIL; + break; } } if(ret!=FAIL){ @@ -2247,6 +2249,7 @@ int slsReceiverTCPIPInterface::lock_receiver() { int slsReceiverTCPIPInterface::set_port() { ret=OK; MySocketTCP* mySocket=NULL; + char oldLastClientIP[INET_ADDRSTRLEN]; int sd=-1; enum runStatus p_type; /* just to get the input */ int p_number; @@ -2277,12 +2280,14 @@ int slsReceiverTCPIPInterface::set_port() { ret=FAIL; } cout << "set port " << p_type << " to " << p_number <lastClientIP); mySocket = new MySocketTCP(p_number); } if(mySocket){ sd = mySocket->getErrorStatus(); if (!sd){ ret=OK; + strcpy(socket->lastClientIP,oldLastClientIP); if (mySocket->differentClients) ret=FORCE_UPDATE; } else { diff --git a/slsReceiverSoftware/src/slsReceiverUsers.cpp b/slsReceiverSoftware/src/slsReceiverUsers.cpp index 9b1f147da..c27f1efc2 100644 --- a/slsReceiverSoftware/src/slsReceiverUsers.cpp +++ b/slsReceiverSoftware/src/slsReceiverUsers.cpp @@ -25,7 +25,7 @@ void slsReceiverUsers::closeFile(int p) { } int64_t slsReceiverUsers::getReceiverVersion(){ - slsReceiverUsers::receiver->getReceiverVersion(); + return slsReceiverUsers::receiver->getReceiverVersion(); } From ca9f195f0bd0de0d45e021e2d6cd3866efd53a3a Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Thu, 16 Jul 2015 13:33:34 +0200 Subject: [PATCH 104/474] starting of a new change --- .../include/UDPBaseImplementation.h | 5 +- slsReceiverSoftware/include/genericSocket.h | 27 +- .../src/UDPBaseImplementation.cpp | 4 +- .../src/UDPStandardImplementation.cpp | 233 +++++++++++++----- 4 files changed, 185 insertions(+), 84 deletions(-) diff --git a/slsReceiverSoftware/include/UDPBaseImplementation.h b/slsReceiverSoftware/include/UDPBaseImplementation.h index 6a8c53bd3..3ece433dd 100644 --- a/slsReceiverSoftware/include/UDPBaseImplementation.h +++ b/slsReceiverSoftware/include/UDPBaseImplementation.h @@ -486,7 +486,10 @@ protected: /** structure of an eiger image header*/ typedef struct { - unsigned char header_before[20]; + //unsigned char header_before1[5]; + //unsigned char header_confirm[1]; + //unsigned char header_before2[14]; + unsigned char header_before[20]; unsigned char fnum[4]; unsigned char header_after[24]; } eiger_image_header; diff --git a/slsReceiverSoftware/include/genericSocket.h b/slsReceiverSoftware/include/genericSocket.h index 0ccc80adf..ed5d386a1 100644 --- a/slsReceiverSoftware/include/genericSocket.h +++ b/slsReceiverSoftware/include/genericSocket.h @@ -94,18 +94,11 @@ enum communicationProtocol{ typedef struct { - unsigned char header_before[20]; + unsigned char header_before[20]; unsigned char fnum[4]; unsigned char header_after[24]; } eiger_image_header; -typedef struct -{ - unsigned char header_before[19]; - unsigned char fnum[4]; - unsigned char header_after[25]; -} eiger_image_header32; - genericSocket(const char* const host_ip_or_name, unsigned short int const port_number, communicationProtocol p, int ps = DEFAULT_PACKET_SIZE) : // portno(port_number), protocol(p), @@ -581,24 +574,13 @@ typedef struct case UDP: if (socketDescriptor<0) return -1; -/* - cout <<"******listening inside genericsocket"<0){ nsending = (length>packet_size) ? packet_size:length; - - /* - +/* //created for debugging on 11.05.2015 nsending=5000; nsent = recvfrom(socketDescriptor,(char*)buf,nsending, 0, (struct sockaddr *) &clientAddress, &clientAddress_length); @@ -616,14 +598,9 @@ typedef struct k++; */ - nsent = recvfrom(socketDescriptor,(char*)buf+total_sent,nsending, 0, (struct sockaddr *) &clientAddress, &clientAddress_length); if(!nsent) break; - if(nsent == 16) { - //cout << "."; - continue; - } length-=nsent; total_sent+=nsent; } diff --git a/slsReceiverSoftware/src/UDPBaseImplementation.cpp b/slsReceiverSoftware/src/UDPBaseImplementation.cpp index b279147ae..e1a630103 100644 --- a/slsReceiverSoftware/src/UDPBaseImplementation.cpp +++ b/slsReceiverSoftware/src/UDPBaseImplementation.cpp @@ -624,7 +624,7 @@ void UDPBaseImplementation::setupFifoStructure(){ FILE_LOG(logDEBUG) << __AT__ < mem0[i]=(char*)malloc((bufferSize * numJobsPerThread + HEADER_SIZE_NUM_TOT_PACKETS)*fifosize); /** shud let the client know about this */ if (mem0[i]==NULL){ - cout<<"++++++++++++++++++++++ COULD NOT ALLOCATE MEMORY FOR LISTENING !!!!!!!+++++++++++++++++++++" << endl; + cprintf(BG_RED,"++++++++++++++++++++++ COULD NOT ALLOCATE MEMORY FOR LISTENING !!!!!!!+++++++++++++++++++++\n"); exit(-1); } buffer[i]=mem0[i]; @@ -1754,7 +1754,7 @@ int i; cerr << ithread << " recvfrom() failed:"<push(buffer[ithread]); exit(-1); } diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index cd4963e4b..5b6ca4bdf 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -839,14 +839,13 @@ void UDPStandardImplementation::setupFifoStructure(){ else fifosize = fifosize/numJobsPerThread; + //one packet per buffer + if(myDetectorType == EIGER) + fifosize *= (packetsPerFrame/(numListeningThreads)); cout << "Number of Frames per buffer:" << numJobsPerThread << endl; cout << "Fifo Size:" << fifosize << endl; - /* - //for testing - numJobsPerThread = 3; fifosize = 11; - */ for(int i=0;i(fifosize); fifo[i] = new CircularFifo(fifosize); //allocate memory - mem0[i]=(char*)malloc((bufferSize * numJobsPerThread + HEADER_SIZE_NUM_TOT_PACKETS)*fifosize); + //if eiger, allocate only one packet size per buffer + if(myDetectorType == EIGER) + mem0[i]=(char*)malloc((onePacketSize * numJobsPerThread)*fifosize); + else + mem0[i]=(char*)malloc((bufferSize * numJobsPerThread + HEADER_SIZE_NUM_TOT_PACKETS)*fifosize); + /** shud let the client know about this */ if (mem0[i]==NULL){ - cout<<"++++++++++++++++++++++ COULD NOT ALLOCATE MEMORY FOR LISTENING !!!!!!!+++++++++++++++++++++" << endl; + cprintf(BG_RED,"++++++++++++++++++++++ COULD NOT ALLOCATE MEMORY FOR LISTENING !!!!!!!+++++++++++++++++++++\n"); exit(-1); } buffer[i]=mem0[i]; + + //push the addresses into freed fifoFree and writingFifoFree - while (buffer[i]<(mem0[i]+(bufferSize * numJobsPerThread + HEADER_SIZE_NUM_TOT_PACKETS)*(fifosize-1))) { - fifoFree[i]->push(buffer[i]); + if(myDetectorType == EIGER){ + while (buffer[i]<(mem0[i]+(onePacketSize * numJobsPerThread)*(fifosize-1))) { + fifoFree[i]->push(buffer[i]); #ifdef FIFO_DEBUG - cprintf(CYAN,"%d fifostructure free pushed into fifofree %x\n", i, (void*)(buffer[i])); + cprintf(CYAN,"%d fifostructure free pushed into fifofree %x\n", i, (void*)(buffer[i])); #endif - buffer[i]+=(bufferSize * numJobsPerThread + HEADER_SIZE_NUM_TOT_PACKETS); + buffer[i]+=(onePacketSize * numJobsPerThread); + } } + else{ + while (buffer[i]<(mem0[i]+(bufferSize * numJobsPerThread + HEADER_SIZE_NUM_TOT_PACKETS)*(fifosize-1))) { + fifoFree[i]->push(buffer[i]); +#ifdef FIFO_DEBUG + cprintf(CYAN,"%d fifostructure free pushed into fifofree %x\n", i, (void*)(buffer[i])); +#endif + buffer[i]+=(bufferSize * numJobsPerThread + HEADER_SIZE_NUM_TOT_PACKETS); + } + } + } cout << "Fifo structure(s) reconstructed" << endl; } @@ -1674,17 +1693,8 @@ int UDPStandardImplementation::startListening(){ int total; int lastpacketoffset, expected, rc,packetcount, maxBufferSize, carryonBufferSize; - uint32_t lastframeheader, lastpacketheader;// for moench to check for all the packets in last frame + uint32_t lastframeheader = 0, lastpacketheader = -1, tempframenum = 0;// for moench to check for all the packets in last frame char* tempchar = NULL; - int last_packet_value = 0xff; - if(myDetectorType == EIGER){ - switch(dynamicRange){ - case 4: last_packet_value = 0x40; break; - case 8: last_packet_value = 0x80; break; - case 16: last_packet_value = 0xff; break; - default: last_packet_value = 0xff; break; // 32 bit mode currently gives pnum only upto 0xff and then resets - } - } while(1){ @@ -1692,10 +1702,12 @@ int UDPStandardImplementation::startListening(){ carryonBufferSize = 0; //if more than 1 listening thread, listen one packet at a time, else need to interleaved frame later maxBufferSize = bufferSize * numJobsPerThread; + #ifdef VERYDEBUG - cprintf(BLUE, "%d maxBufferSize:%d carryonBufferSize:%d\n", ithread, maxBufferSize,carryonBufferSize); + cprintf(BLUE, "%d listenTo:%d maxBufferSize:%d carryonBufferSize:%d\n", ithread,listenTo,maxBufferSize,carryonBufferSize); #endif + //temporary buffer to copy initial packets for next frames if(tempchar) {delete [] tempchar;tempchar = NULL;} if(myDetectorType != EIGER) tempchar = new char[onePacketSize * ((packetsPerFrame/numListeningThreads) - 1)]; //gotthard: 1packet size, moench:39 packet size @@ -1724,9 +1736,32 @@ int UDPStandardImplementation::startListening(){ #ifdef SOCKET_DEBUG if(!ithread){ #endif - rc = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS, maxBufferSize); - //cout<<"value:"<fnum)<ReceiveDataOnly(buffer[ithread]); + //headers or crazy byte size + while (rc != onePacketSize){ + //end of acquisition + if((rc == 0) && (status == TRANSMITTING)){ + stopListening(ithread,rc,packetcount,total); + continue; + } + //16 byte or crazy packet size + if(rc != EIGER_HEADER_LENGTH) + rc = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread]); + //header + else{ + tempframenum = htonl(*(unsigned int*)((eiger_image_header *)((char*)(buffer[ithread])))->fnum); + rc = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread]); + } + } + } + //other detectors + else{ + rc = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS, maxBufferSize); + //cout<<"value:"<fnum)< 0) && (!ithread)) + + if( (!measurementStarted) && (myDetectorType != EIGER) && (rc > 0) && (!ithread)) startFrameIndices(ithread); //problem in receiving or end of acquisition - if((rc < expected)||(rc <= 0)){ + //if(((rc < expected) && (status == TRANSMITTING)) || (rc<0)){ + if((status == TRANSMITTING)&& (myDetectorType != EIGER)) { /*if(myDetectorType != EIGER){ //start indices for each start of scan/acquisition - this should be done earlier for normal detectors if((!measurementStarted) && (rc > 0) && (!ithread)) @@ -1776,8 +1813,10 @@ int UDPStandardImplementation::startListening(){ */ //reset - packetcount = (packetsPerFrame/numListeningThreads) * numJobsPerThread; - carryonBufferSize = 0; + if (myDetectorType != EIGER){ + packetcount = (packetsPerFrame/numListeningThreads) * numJobsPerThread; + carryonBufferSize = 0; + } //check if last packet valid and calculate packet count @@ -1838,46 +1877,126 @@ int UDPStandardImplementation::startListening(){ case EIGER: - lastpacketoffset = (((numJobsPerThread * packetsPerFrame/numListeningThreads - 1) * onePacketSize) + EIGER_HEADER_LENGTH + HEADER_SIZE_NUM_TOT_PACKETS); -#ifdef VERYDEBUG - cprintf(BLUE,"%d fnum: 0x%x\n", ithread, htonl(*(unsigned int*)((eiger_image_header *)((char*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS)))->fnum)); - cprintf(BLUE,"%d 1st pnum: 0x%x\n", ithread, ((*(uint8_t*)(((eiger_packet_header *)((char*)(buffer[ithread] + EIGER_HEADER_LENGTH + HEADER_SIZE_NUM_TOT_PACKETS)))->num4)))); - cprintf(BLUE,"%d last packet offset: %d\n",ithread,lastpacketoffset); - cprintf(BLUE,"%d last pnum: 0x%x\n", ithread,((*(uint8_t*)(((eiger_packet_header *)((char*)(buffer[ithread] + lastpacketoffset)))->num4)))); -/*for 32 bit try to print 64 bit value of packet header to rule out no other byte changes value other than num4 */ -#endif - //if eiger last packet value is NOT as expected according to bit mode - cprintf(BLUE,"%d lastpacket value: %d\n",ithread,((*(uint8_t*)(((eiger_packet_header *)((char*)(buffer[ithread] + lastpacketoffset)))->num4)))); - cprintf(BLUE,"%d lastpacket value -1: %d\n",ithread,((*(uint8_t*)(((eiger_packet_header *)((char*)(buffer[ithread] + lastpacketoffset - onePacketSize)))->num4)))); - if( ((*(uint8_t*)(((eiger_packet_header *)((char*)(buffer[ithread] + lastpacketoffset)))->num4))) != last_packet_value){ -//#ifdef VERYDEBUG - cprintf(RED,"NOT full frame\n"); -//#endif + + //push missing packet if any by looking at last packetheader values + + + //packetnumber is smaller = different frame + if(lastpacketheader >= ((*(uint8_t*)(((eiger_packet_header *)((char*)(buffer[ithread])))->num4)))) + tempframenum++; + + + + + //tag framenumber to the packet + (*(uint32_t*)(((eiger_packet_header *)((char*)(buffer[ithread])))->num1)) = tempframenum; + //remember last packet value + lastpacketheader = ((*(uint8_t*)(((eiger_packet_header *)((char*)(buffer[ithread])))->num4))); + + + + + + + + + + //literally end of buffer + lastpacketoffset = rc + HEADER_SIZE_NUM_TOT_PACKETS; + + //extra header + //or less than 1 frame caught(end of acquisition) + if(rc < expected){ + cprintf(RED,"%d rc:%d expectted:%d\n", ithread, rc, expected); + //extra header, looking at last byte of buffer + if ((*((uint8_t*)((char*)buffer[ithread]+lastpacketoffset-1))) == 0x1){ + cprintf(RED,"%d extra header\n", ithread); + //copy extra header + lastpacketoffset-= EIGER_HEADER_LENGTH; + carryonBufferSize += EIGER_HEADER_LENGTH; + memcpy(tempchar, buffer[ithread]+(lastpacketoffset-EIGER_HEADER_LENGTH), EIGER_HEADER_LENGTH); + cprintf(RED,"%d lastpacketoffset:%d\n",ithread, lastpacketoffset); + } + + //less than 1 frame caught + else cprintf(RED,"%d less than 1 frame \n", ithread); + + //find number of packets from last packet number + lastpacketoffset -= onePacketSize; + cprintf(RED,"%d lastpacketoffset:%d\n",ithread, lastpacketoffset); + + for (k=0;k*1040num4)))); + } + + packetcount = ((*(uint8_t*)(((eiger_packet_header *)((char*)(buffer[ithread] + lastpacketoffset)))->num4)))+1; + cprintf(RED,"%d num packets caught:%d\n",ithread, packetcount); + + + + cout <<"EXITING"<< endl; + exit(-1); + + } + //more than 1 frame caught but missed the frame header packet + //or exactly 1 frame caught + else { + //points to last packet + lastpacketoffset = rc + HEADER_SIZE_NUM_TOT_PACKETS - onePacketSize; lastpacketheader = ((*(uint8_t*)(((eiger_packet_header *)((char*)(buffer[ithread] + lastpacketoffset)))->num4))); +#ifdef VERYDEBUG + cprintf(BLUE,"%d fnum: 0x%x\n", ithread, htonl(*(unsigned int*)((eiger_image_header *)((char*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS)))->fnum)); + cprintf(BLUE,"%d 1st pnum: 0x%x\n", ithread, ((*(uint8_t*)(((eiger_packet_header *)((char*)(buffer[ithread] + EIGER_HEADER_LENGTH + HEADER_SIZE_NUM_TOT_PACKETS)))->num4)))); + cprintf(BLUE,"%d last packet offset: %d\n",ithread,lastpacketoffset); + cprintf(BLUE,"%d last pnum: 0x%x\n", ithread,((*(uint8_t*)(((eiger_packet_header *)((char*)(buffer[ithread] + lastpacketoffset)))->num4)))); + //for 32 bit try to print 64 bit value of packet header to rule out no other byte changes value other than num4 +#endif + + //proper 1 frame + if((rc == expected) && (lastpacketheader == last_packet_value)){ + break; + } + + //incomplete frame, more than 1 frame caught, but missed header packet + cprintf(RED,"%d INCOMPLETE frame, rc:%d, expected:%d\n", ithread, rc, expected); + cprintf(RED,"%d fnum: 0x%x\n", ithread, htonl(*(unsigned int*)((eiger_image_header *)((char*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS)))->fnum)); + + //if eiger last packet value is NOT as expected according to bit mode carryonBufferSize += onePacketSize; - cprintf(BLUE,"%d lastpacket value: %d packet count: %d\n",ithread,lastpacketheader,packetcount); lastpacketoffset -= onePacketSize; --packetcount; - cprintf(BLUE,"%d lastpacket value -1: %d\n",ithread,((*(uint8_t*)(((eiger_packet_header *)((char*)(buffer[ithread] + lastpacketoffset - onePacketSize)))->num4)))); + cprintf(RED,"%d lastpacketheader:%d last packet value:%d packetcount: %d\n",ithread,lastpacketheader,((*(uint8_t*)(((eiger_packet_header *)((char*)(buffer[ithread] + lastpacketoffset)))->num4))), packetcount); //while last packet value is greater than current offset packet value (till we reach ff) while (lastpacketheader > ((*(uint8_t*)(((eiger_packet_header *)((char*)(buffer[ithread] + lastpacketoffset)))->num4))) ){ + lastpacketheader = ((*(uint8_t*)(((eiger_packet_header *)((char*)(buffer[ithread] + lastpacketoffset)))->num4))); carryonBufferSize += onePacketSize; - cprintf(BLUE,"%d check value: %d lastpacket value: %d packet count: %d\n",ithread,lastpacketheader,packetcount); lastpacketoffset -= onePacketSize; --packetcount; - cprintf(BLUE,"%d lastpacket value -1: %d\n",ithread,((*(uint8_t*)(((eiger_packet_header *)((char*)(buffer[ithread] + lastpacketoffset - onePacketSize)))->num4)))); + + cprintf(RED,"%d lastpacketheader:%d last packet value:%d packetcount: %d\n",ithread,lastpacketheader,((*(uint8_t*)(((eiger_packet_header *)((char*)(buffer[ithread] + lastpacketoffset)))->num4))), packetcount); } - memcpy(tempchar, buffer[ithread]+(lastpacketoffset+onePacketSize), carryonBufferSize); -//#ifdef VERYDEBUG - cprintf(BLUE,"%d tempchar 1st pnum: 0x%x\n", ithread, ((*(uint8_t*)(((eiger_packet_header *)((char*)(tempchar)))->num4)))); -//#endif + + cprintf(RED,"%d to copy: %d\n", ithread, carryonBufferSize); + cprintf(RED,"%d lastpacketheader:%d last packet value:%d packetcount: %d\n",ithread,lastpacketheader,((*(uint8_t*)(((eiger_packet_header *)((char*)(buffer[ithread] + lastpacketoffset+onePacketSize)))->num4))), packetcount); + + memcpy(tempchar , buffer[ithread]+(HEADER_SIZE_NUM_TOT_PACKETS), EIGER_HEADER_LENGTH); + memcpy((char*)(tempchar + EIGER_HEADER_LENGTH), buffer[ithread]+(lastpacketoffset+onePacketSize), carryonBufferSize); + (*(unsigned int*)((eiger_image_header *)((char*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS)))->fnum) = htonl(lastframeheader+1); + cprintf(RED,"%d copied\n", ithread); + //#ifdef VERYDEBUG + cprintf(RED,"%d tempchar 1st pnum: 0x%x\n", ithread, ((*(uint8_t*)(((eiger_packet_header *)((char*)(tempchar+EIGER_HEADER_LENGTH)))->num4)))); + //#endif + } + //when we lose frame header packet + lastframeheader = htonl(*(unsigned int*)((eiger_image_header *)((char*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS)))->fnum); + cprintf(RED,"%d lastframeheader : %d\n", ithread, lastframeheader); break; @@ -2208,7 +2327,7 @@ int i; cprintf(BLUE, "%d recvfrom() failed\n", ithread); #endif if(status != TRANSMITTING){ - cprintf(BLUE,"%d *** should never be here********* status not transmitting***********************\n", ithread);/**/ + cprintf(BG_RED,"%d *** should never be here********* status not transmitting***********************\n", ithread);/**/ fifoFree[ithread]->push(buffer[ithread]); #ifdef FIFO_DEBUG cprintf(BLUE,"%d listener not txm free pushed into fifofree %x\n", ithread,(void*)(buffer[ithread])); @@ -2257,9 +2376,9 @@ int i; cprintf(BLUE,"%d dummy buffer num packets:%d\n", ithread(*((uint16_t*)(buffer[ithread])))); #endif while(!fifo[ithread]->push(buffer[ithread])); -#ifdef FIFO_DEBUG +//#ifdef FIFO_DEBUG cprintf(BLUE,"%d listener pushed dummy buffer into fifo %x\n", ithread,(void*)(buffer[ithread])); -#endif +//#endif } //reset mask and exit loop @@ -2504,7 +2623,7 @@ void UDPStandardImplementation::writeToFile_withoutCompression(char* buf,int num void UDPStandardImplementation::handleWithoutDataCompression(int ithread, char* wbuffer[], int partialframe, int smaller){ int totalheader = HEADER_SIZE_NUM_TOT_PACKETS + EIGER_HEADER_LENGTH; - int i,j,npackets; + int i,j,npackets, ntotpackets=0; if (cbAction < DO_EVERYTHING){ @@ -2513,6 +2632,7 @@ void UDPStandardImplementation::handleWithoutDataCompression(int ithread, char* if(partialframe && (i!=smaller) ) continue; //for eiger 32 bit mode, currframenum like gotthard, does not start from 0 or 1 npackets = (uint16_t)(*((uint16_t*)wbuffer[i])); + ntotpackets += npackets; rawDataReadyCallBack(currframenum, wbuffer[i], npackets * onePacketSize, sfilefd, guiData,pRawDataReady); } } @@ -2523,6 +2643,7 @@ void UDPStandardImplementation::handleWithoutDataCompression(int ithread, char* if(partialframe && (j!=smaller) ) continue; npackets = (uint16_t)(*((uint16_t*)wbuffer[j])); + ntotpackets += npackets; if (npackets > 0){ #ifdef WRITE_HEADERS @@ -2583,7 +2704,7 @@ void UDPStandardImplementation::handleWithoutDataCompression(int ithread, char* if(myDetectorType == EIGER) { - if(!partialframe){ + if(ntotpackets >= packetsPerFrame ) { #ifdef VERYDEBUG cprintf(GREEN,"gonna copy frame\n"); #endif From 26a42d8f67d5714b74689a1c0d3e06c8d64e2691 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Fri, 17 Jul 2015 13:29:23 +0200 Subject: [PATCH 105/474] new way --- .../include/UDPBaseImplementation.h | 3 + .../src/UDPStandardImplementation.cpp | 136 ++++++++++++------ 2 files changed, 98 insertions(+), 41 deletions(-) diff --git a/slsReceiverSoftware/include/UDPBaseImplementation.h b/slsReceiverSoftware/include/UDPBaseImplementation.h index 3ece433dd..9daf2ab79 100644 --- a/slsReceiverSoftware/include/UDPBaseImplementation.h +++ b/slsReceiverSoftware/include/UDPBaseImplementation.h @@ -659,6 +659,9 @@ protected: /** Receiver buffer */ char *buffer[MAX_NUM_LISTENING_THREADS]; + /** Missing Packet */ + char *missingPacket; + /** number of writer threads */ int numListeningThreads; diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 5b6ca4bdf..004ba1fb1 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -54,6 +54,7 @@ UDPStandardImplementation::UDPStandardImplementation() udpSocket[i] = NULL; server_port[i] = DEFAULT_UDP_PORTNO+i; mem0[i] = NULL; + missingPacket[i] = NULL; fifo[i] = NULL; fifoFree[i] = NULL; } @@ -163,6 +164,7 @@ void UDPStandardImplementation::initializeMembers(){ for(int i=0;inum4))); + numberofmissingpackets = 0; - //push missing packet if any by looking at last packetheader values - - - //packetnumber is smaller = different frame - if(lastpacketheader >= ((*(uint8_t*)(((eiger_packet_header *)((char*)(buffer[ithread])))->num4)))) + //update tempframenumber if header packet missed out, ie. if packetnumber is smaller = different frame + if(lastpacketheader >= currentpacketheader){ tempframenum++; + //add missing packets for previous frame + numberofmissingpackets += (LAST_PACKET_VALUE - lastpacketheader); + //add for missing frames + numberofmissingpackets += ((tempframenum-lastframeheader -1) * (packetsPerFrame/numListeningThreads)); + //add missing packets for current frame + numberofmissingpackets += (currentpacketheader); + } - //tag framenumber to the packet - (*(uint32_t*)(((eiger_packet_header *)((char*)(buffer[ithread])))->num1)) = tempframenum; //remember last packet value lastpacketheader = ((*(uint8_t*)(((eiger_packet_header *)((char*)(buffer[ithread])))->num4))); + lastframeheader = tempframenum; + + //temporarily store current buffer if there are missing packets + if(numberofmissingpackets) + tempchar = buffer[ithread]; + + for(i=0;inum1)) = tempframenum; +#ifdef VERYDEBUG + cprintf(BLUE,"%d listener going to push fifo: 0x%x\n", ithread,(void*)(buffer[ithread])); +#endif + while(!fifo[ithread]->push(buffer[ithread])); +#ifdef FIFO_DEBUG + //if(!ithread) + cprintf(BLUE, "%d listener pushed into fifo %x\n",ithread, (void*)(buffer[ithread])); +#endif +#ifdef VERYDEBUG + cprintf(BLUE, "%d waiting to pop out of listeningfifo\n",ithread); +#endif + //pop + fifoFree[ithread]->pop(buffer[ithread]); +#ifdef FIFO_DEBUG + cprintf(BLUE,"%d listener popped from fifofree %x\n", ithread, (void*)(buffer[ithread])); +#endif + } + + buffer[ithread] = tempchar; + //tag framenumber to the packet + (*(uint32_t*)(((eiger_packet_header *)((char*)(buffer[ithread])))->num1)) = tempframenum; + packetcount = 1; - - - - +/* //literally end of buffer lastpacketoffset = rc + HEADER_SIZE_NUM_TOT_PACKETS; @@ -1997,6 +2068,8 @@ int UDPStandardImplementation::startListening(){ //when we lose frame header packet lastframeheader = htonl(*(unsigned int*)((eiger_image_header *)((char*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS)))->fnum); cprintf(RED,"%d lastframeheader : %d\n", ithread, lastframeheader); + + */ break; @@ -2007,11 +2080,14 @@ int UDPStandardImplementation::startListening(){ + + //#ifdef VERYDEBUG cprintf(BLUE, "%d packetcount:%d carryonbuffer:%d\n", ithread, packetcount, carryonBufferSize); //#endif //write packet count and push - (*((uint16_t*)(buffer[ithread]))) = packetcount; + if(myDetectorType != EIGER) + (*((uint16_t*)(buffer[ithread]))) = packetcount; totalListeningFrameCount[ithread] += packetcount; #ifdef VERYDEBUG cprintf(BLUE,"%d listener going to push fifo: 0x%x\n", ithread,(void*)(buffer[ithread])); @@ -2067,8 +2143,7 @@ int UDPStandardImplementation::startWriting(){ int xmax=0,ymax=0; int ret,i; int packetsPerThread = packetsPerFrame/numListeningThreads; - int allDummyFramesPopped; - int smaller, onlyoneport=0; + while(1){ @@ -2099,16 +2174,10 @@ int UDPStandardImplementation::startWriting(){ while((1<push(wbuf[i])); -#ifdef FIFO_DEBUG - cprintf(GREEN,"%d writer free dummy pushed into fifofree %x for listener %d\n", ithread,(void*)(wbuf[i]),i); -#endif - - }else allDummyFramesPopped = 0; - } } - //if all last dummy frames popped - if(allDummyFramesPopped){ + if(numpackets[i] == 0xFFFF){ #ifdef VERYDEBUG cprintf(GREEN,"%d all dummy frames popped\n", ithread); #endif From 878c12d43ed874a217f448a64fc342f05d6bab27 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 21 Jul 2015 13:36:14 +0200 Subject: [PATCH 106/474] still long way to go --- .../include/UDPBaseImplementation.h | 11 +- .../include/UDPStandardImplementation.h | 4 +- slsReceiverSoftware/include/receiver_defs.h | 2 +- .../src/UDPStandardImplementation.cpp | 1008 ++++++++--------- 4 files changed, 503 insertions(+), 522 deletions(-) diff --git a/slsReceiverSoftware/include/UDPBaseImplementation.h b/slsReceiverSoftware/include/UDPBaseImplementation.h index 9daf2ab79..8db022a69 100644 --- a/slsReceiverSoftware/include/UDPBaseImplementation.h +++ b/slsReceiverSoftware/include/UDPBaseImplementation.h @@ -486,10 +486,10 @@ protected: /** structure of an eiger image header*/ typedef struct { - //unsigned char header_before1[5]; - //unsigned char header_confirm[1]; - //unsigned char header_before2[14]; - unsigned char header_before[20]; + unsigned char header_before1[5]; + unsigned char header_confirm[1]; + unsigned char header_before2[14]; + //unsigned char header_before[20]; unsigned char fnum[4]; unsigned char header_after[24]; } eiger_image_header; @@ -659,9 +659,6 @@ protected: /** Receiver buffer */ char *buffer[MAX_NUM_LISTENING_THREADS]; - /** Missing Packet */ - char *missingPacket; - /** number of writer threads */ int numListeningThreads; diff --git a/slsReceiverSoftware/include/UDPStandardImplementation.h b/slsReceiverSoftware/include/UDPStandardImplementation.h index 4c04265d4..42650e9bb 100644 --- a/slsReceiverSoftware/include/UDPStandardImplementation.h +++ b/slsReceiverSoftware/include/UDPStandardImplementation.h @@ -468,10 +468,8 @@ private: * Called by startWriting() * @param ithread writing thread number * @param wbuffer writer buffer - * @param partialframe is 1 if both ports of eiger dont have same frame - * @param smaller is which port is the smaller frame number if only partial frame received */ - void handleWithoutDataCompression(int ithread, char* wbuffer[], int partialframe = 0, int smaller = 0); + void handleWithoutDataCompression(int ithread, char* wbuffer[]); /** * data compression for each fifo output diff --git a/slsReceiverSoftware/include/receiver_defs.h b/slsReceiverSoftware/include/receiver_defs.h index 6f3b1acd3..6a28654b3 100755 --- a/slsReceiverSoftware/include/receiver_defs.h +++ b/slsReceiverSoftware/include/receiver_defs.h @@ -14,7 +14,7 @@ #define BUF_SIZE (16*1024*1024) //16mb #define SAMPLE_TIME_IN_NS 100000000//100ms #define MAX_JOBS_PER_THREAD 1000 -#define HEADER_SIZE_NUM_TOT_PACKETS 2 +#define HEADER_SIZE_NUM_TOT_PACKETS 4 #define HEADER_SIZE_NUM_FRAMES 2 #define HEADER_SIZE_NUM_PACKETS 1 diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 004ba1fb1..84d1adcbc 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1,10 +1,6 @@ /********************************************//** * @file UDPStandardImplementation.cpp * @short does all the functions for a receiver, set/get parameters, start/stop etc. - * update: 08 July 2015 - * startwriting assumes that for eiger numberoflisteningthreads is limited to 2. - * Otherwise logic to compare n number of frame numbers and store previous frames - * is more complicated compared to just 2 threads. ***********************************************/ @@ -54,7 +50,6 @@ UDPStandardImplementation::UDPStandardImplementation() udpSocket[i] = NULL; server_port[i] = DEFAULT_UDP_PORTNO+i; mem0[i] = NULL; - missingPacket[i] = NULL; fifo[i] = NULL; fifoFree[i] = NULL; } @@ -164,7 +159,6 @@ void UDPStandardImplementation::initializeMembers(){ for(int i=0;iisEmpty()) fifoFree[i]->pop(buffer[i]); #ifdef FIFO_DEBUG - cprintf(CYAN,"%d fifostructure popped from fifofree %x\n", i, (void*)(buffer[i])); + //cprintf(GREEN,"%d fifostructure popped from fifofree %x\n", i, (void*)(buffer[i])); #endif delete fifoFree[i]; } if(fifo[i]) delete fifo[i]; if(mem0[i]) free(mem0[i]); - fifoFree[i] = new CircularFifo(fifosize); fifo[i] = new CircularFifo(fifosize); //allocate memory - //if eiger, allocate only one packet size per buffer - if(myDetectorType == EIGER) - mem0[i]=(char*)malloc((onePacketSize * numJobsPerThread)*fifosize); - else - mem0[i]=(char*)malloc((bufferSize * numJobsPerThread + HEADER_SIZE_NUM_TOT_PACKETS)*fifosize); - + mem0[i]=(char*)malloc((bufferSize * numJobsPerThread + HEADER_SIZE_NUM_TOT_PACKETS)*fifosize); /** shud let the client know about this */ if (mem0[i]==NULL){ - cprintf(BG_RED,"++++++++++++++++++++++ COULD NOT ALLOCATE MEMORY FOR LISTENING !!!!!!!+++++++++++++++++++++\n"); + cout<<"++++++++++++++++++++++ COULD NOT ALLOCATE MEMORY FOR LISTENING !!!!!!!+++++++++++++++++++++" << endl; exit(-1); } buffer[i]=mem0[i]; - - //push the addresses into freed fifoFree and writingFifoFree - if(myDetectorType == EIGER){ - while (buffer[i]<(mem0[i]+(onePacketSize * numJobsPerThread)*(fifosize-1))) { - fifoFree[i]->push(buffer[i]); + while (buffer[i]<(mem0[i]+(bufferSize * numJobsPerThread + HEADER_SIZE_NUM_TOT_PACKETS)*(fifosize-1))) { + fifoFree[i]->push(buffer[i]); #ifdef FIFO_DEBUG - cprintf(CYAN,"%d fifostructure free pushed into fifofree %x\n", i, (void*)(buffer[i])); + cprintf(BLUE,"%d fifostructure free pushed into fifofree %x\n", i, (void*)(buffer[i])); #endif - buffer[i]+=(onePacketSize * numJobsPerThread); - } + buffer[i]+=(bufferSize * numJobsPerThread + HEADER_SIZE_NUM_TOT_PACKETS); } - else{ - while (buffer[i]<(mem0[i]+(bufferSize * numJobsPerThread + HEADER_SIZE_NUM_TOT_PACKETS)*(fifosize-1))) { - fifoFree[i]->push(buffer[i]); -#ifdef FIFO_DEBUG - cprintf(CYAN,"%d fifostructure free pushed into fifofree %x\n", i, (void*)(buffer[i])); -#endif - buffer[i]+=(bufferSize * numJobsPerThread + HEADER_SIZE_NUM_TOT_PACKETS); - } - } - } cout << "Fifo structure(s) reconstructed" << endl; - - - //missing packet - if(myDetectorType == EIGER){ - - if (missingPacket) - free(missingPacket); - - missingPacket=(char*)malloc(onePacketSize); - if (missingPacket==NULL){ - cprintf(BG_RED,"++++++++++++++++++++++ COULD NOT ALLOCATE MEMORY FOR missing packet !!!!!!!+++++++++++++++++++++\n"); - exit(-1); - } - //fill missing packet - else{ - - for(int j = 0; j < onePacketSize/4; j++) - (*((uint32_t*)(missingPacket + j))) = 0xffffffff; - - //to check - for(int j = 0; j < onePacketSize/4; j++) - cout << i << ":"<< (*((uint32_t*)(missingPacket + j))) << endl; - } - } } @@ -945,7 +893,7 @@ void UDPStandardImplementation::readFrame(char* c,char** raw, uint32_t &fnum, ui if (guiData == NULL){ guiData = latestData; #ifdef VERY_VERY_DEBUG - cprintf(MAGENTA,"gui data not null anymore\n"); + cprintf(CYAN,"gui data not null anymore\n"); #endif } @@ -959,14 +907,14 @@ void UDPStandardImplementation::readFrame(char* c,char** raw, uint32_t &fnum, ui //could not get gui data if(!guiDataReady){ #ifdef VERY_VERY_DEBUG - cprintf(MAGENTA,"gui data not ready\n"); + cprintf(CYAN,"gui data not ready\n"); #endif *raw = NULL; } //data ready, set guidata to receive new data else{ #ifdef VERY_VERY_DEBUG - cprintf(MAGENTA,"gui data ready\n"); + cprintf(CYAN,"gui data ready\n"); #endif *raw = guiData; guiData = NULL; @@ -976,14 +924,14 @@ void UDPStandardImplementation::readFrame(char* c,char** raw, uint32_t &fnum, ui pthread_mutex_unlock(&dataReadyMutex);*/ if((nFrameToGui) && (writerthreads_mask)){ #ifdef VERY_VERY_DEBUG - cprintf(MAGENTA,"gonna post\n"); + cprintf(CYAN,"gonna post\n"); #endif /*if(nFrameToGui){*/ //release after getting data sem_post(&smp); } #ifdef VERY_VERY_DEBUG - cprintf(MAGENTA,"done post\n"); + cprintf(CYAN,"done post\n"); #endif } } @@ -1419,9 +1367,6 @@ int UDPStandardImplementation::createNewFile(){ int gt = getFrameIndex(); if(gt==-1) gt=0; - //just because currframenum will start from 1, while getframeindex will start from 0 - else if(myDetectorType == EIGER) - gt++; //create file name if(frameIndexNeeded==-1) sprintf(savefilename, "%s/%s_%d.raw", filePath,fileName,fileIndex); @@ -1456,8 +1401,6 @@ int UDPStandardImplementation::createNewFile(){ if(!packetsCaught) cout << savefilename << endl; else{ - - cout << savefilename << "\tpacket loss " << setw(4)<pop(buffer[ithread]); #ifdef FIFO_DEBUG cprintf(BLUE,"%d listener popped from fifofree %x\n", ithread, (void*)(buffer[ithread])); #endif - //receive + + //ensure udpsocket exists if(udpSocket[ithread] == NULL){ rc = 0; - cout << ithread << "UDP Socket is NULL" << endl; + cprintf(BLUE, "%d UDP Socket is NULL\n",ithread); } + + //normal listening else if(!carryonBufferSize){ - #ifdef SOCKET_DEBUG - if(!ithread){ + if(!ithread){ #endif - if(myDetectorType == EIGER){ - //listen to only 1 packet at a time - rc = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread]); - //headers or crazy byte size - while (rc != onePacketSize){ - //end of acquisition - if((rc == 0) && (status == TRANSMITTING)){ - stopListening(ithread,rc,packetcount,total); - continue; - } - //16 byte or crazy packet size - if(rc != EIGER_HEADER_LENGTH) - rc = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread]); - //header - else{ - tempframenum = htonl(*(unsigned int*)((eiger_image_header *)((char*)(buffer[ithread])))->fnum); - rc = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread]); - } - } - } - //other detectors - else{ rc = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS, maxBufferSize); - //cout<<"value:"<fnum)<> frameIndexOffset)<> frameIndexOffset)); + cprintf(BLUE, "%d tempchar packet:%d\n", ((((uint32_t)(*((uint32_t*)(tempchar))))) + & (packetIndexMask))); #endif - //if there is a packet from previous buffer, copy it and listen to n less frame memcpy(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS, tempchar, carryonBufferSize); rc = udpSocket[ithread]->ReceiveDataOnly((buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS + carryonBufferSize),maxBufferSize - carryonBufferSize); expected = maxBufferSize - carryonBufferSize; } + #ifdef EIGER_DEBUG cprintf(BLUE, "%d rc: %d. expected: %d\n", ithread, rc, expected); #endif - //start indices for each start of scan/acquisition - eiger does it before - - if( (!measurementStarted) && (myDetectorType != EIGER) && (rc > 0) && (!ithread)) - startFrameIndices(ithread); + //start indices for each start of scan/acquisition + if((!measurementStarted) && (rc > 0)){ + pthread_mutex_lock(&progress_mutex); + startFrameIndices(ithread); + pthread_mutex_unlock(&progress_mutex); + } //problem in receiving or end of acquisition - //if(((rc < expected) && (status == TRANSMITTING)) || (rc<0)){ - if((status == TRANSMITTING)&& (myDetectorType != EIGER)) { - /*if(myDetectorType != EIGER){ - //start indices for each start of scan/acquisition - this should be done earlier for normal detectors - if((!measurementStarted) && (rc > 0) && (!ithread)) - startFrameIndices(ithread); - }*/ + if (status == TRANSMITTING){ stopListening(ithread,rc,packetcount,total); continue; } -/* other detectors do after - //eiger - start indices for each start of scan/acquisition - this should be done after to ignore first incomplete frames - if((!measurementStarted) && (rc > 0) && (!ithread)) - startFrameIndices(ithread); -*/ //reset - if (myDetectorType != EIGER){ - packetcount = (packetsPerFrame/numListeningThreads) * numJobsPerThread; - carryonBufferSize = 0; - } + packetcount = (packetsPerFrame/numListeningThreads) * numJobsPerThread; + carryonBufferSize = 0; + //check if last packet valid and calculate packet count switch(myDetectorType){ - case MOENCH: lastpacketoffset = (((numJobsPerThread * packetsPerFrame - 1) * onePacketSize) + HEADER_SIZE_NUM_TOT_PACKETS); #ifdef VERYDEBUG @@ -1887,216 +1794,62 @@ int UDPStandardImplementation::startListening(){ cout <<"tempchar packet:"<< ((((uint32_t)(*((uint32_t*)(tempchar))))) & (packetIndexMask)) << endl; #endif - } + } break; case GOTTHARD: if(shortFrame == -1){ lastpacketoffset = (((numJobsPerThread * packetsPerFrame - 1) * onePacketSize) + HEADER_SIZE_NUM_TOT_PACKETS); #ifdef VERYDEBUG - cout << "last packet offset:" << lastpacketoffset << endl; + cprintf(BLUE, "%d last packet offset:%d\n",ithread, lastpacketoffset); #endif - + //if not last packet if((unsigned int)(packetsPerFrame -1) != ((((uint32_t)(*((uint32_t*)(buffer[ithread]+lastpacketoffset))))+1) & (packetIndexMask))){ memcpy(tempchar,buffer[ithread]+lastpacketoffset, onePacketSize); #ifdef VERYDEBUG - cout << "tempchar header:" << (((((uint32_t)(*((uint32_t*)(tempchar))))+1) - & (frameIndexMask)) >> frameIndexOffset) << endl; + cprintf(BLUE, "%d tempchar header:%d\n",ithread,(((((uint32_t)(*((uint32_t*)(tempchar))))+1) + & (frameIndexMask)) >> frameIndexOffset)); #endif carryonBufferSize = onePacketSize; --packetcount; } } #ifdef VERYDEBUG - cout << "header:" << (((((uint32_t)(*((uint32_t*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS))))+1) - & (frameIndexMask)) >> frameIndexOffset) << endl; + cprintf(BLUE, "%d header:%d\n", (((((uint32_t)(*((uint32_t*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS))))+1) + & (frameIndexMask)) >> frameIndexOffset)); #endif break; + case EIGER: - - currentpacketheader = ((*(uint8_t*)(((eiger_packet_header *)((char*)(buffer[ithread])))->num4))); - numberofmissingpackets = 0; - - //update tempframenumber if header packet missed out, ie. if packetnumber is smaller = different frame - if(lastpacketheader >= currentpacketheader){ - tempframenum++; - - //add missing packets for previous frame - numberofmissingpackets += (LAST_PACKET_VALUE - lastpacketheader); - - //add for missing frames - numberofmissingpackets += ((tempframenum-lastframeheader -1) * (packetsPerFrame/numListeningThreads)); - - //add missing packets for current frame - numberofmissingpackets += (currentpacketheader); - } - - //remember last packet value - lastpacketheader = ((*(uint8_t*)(((eiger_packet_header *)((char*)(buffer[ithread])))->num4))); - lastframeheader = tempframenum; - - //temporarily store current buffer if there are missing packets - if(numberofmissingpackets) - tempchar = buffer[ithread]; - - for(i=0;inum1)) = tempframenum; -#ifdef VERYDEBUG - cprintf(BLUE,"%d listener going to push fifo: 0x%x\n", ithread,(void*)(buffer[ithread])); -#endif - while(!fifo[ithread]->push(buffer[ithread])); -#ifdef FIFO_DEBUG - //if(!ithread) - cprintf(BLUE, "%d listener pushed into fifo %x\n",ithread, (void*)(buffer[ithread])); -#endif -#ifdef VERYDEBUG - cprintf(BLUE, "%d waiting to pop out of listeningfifo\n",ithread); -#endif - //pop - fifoFree[ithread]->pop(buffer[ithread]); -#ifdef FIFO_DEBUG - cprintf(BLUE,"%d listener popped from fifofree %x\n", ithread, (void*)(buffer[ithread])); -#endif - } - - buffer[ithread] = tempchar; - //tag framenumber to the packet - (*(uint32_t*)(((eiger_packet_header *)((char*)(buffer[ithread])))->num1)) = tempframenum; - packetcount = 1; - - - - -/* - - //literally end of buffer - lastpacketoffset = rc + HEADER_SIZE_NUM_TOT_PACKETS; - - //extra header - //or less than 1 frame caught(end of acquisition) - if(rc < expected){ - cprintf(RED,"%d rc:%d expectted:%d\n", ithread, rc, expected); - //extra header, looking at last byte of buffer - if ((*((uint8_t*)((char*)buffer[ithread]+lastpacketoffset-1))) == 0x1){ - cprintf(RED,"%d extra header\n", ithread); - //copy extra header - lastpacketoffset-= EIGER_HEADER_LENGTH; - carryonBufferSize += EIGER_HEADER_LENGTH; - memcpy(tempchar, buffer[ithread]+(lastpacketoffset-EIGER_HEADER_LENGTH), EIGER_HEADER_LENGTH); - cprintf(RED,"%d lastpacketoffset:%d\n",ithread, lastpacketoffset); - } - - //less than 1 frame caught - else cprintf(RED,"%d less than 1 frame \n", ithread); - - //find number of packets from last packet number - lastpacketoffset -= onePacketSize; - cprintf(RED,"%d lastpacketoffset:%d\n",ithread, lastpacketoffset); - - for (k=0;k*1040num4)))); - } - - packetcount = ((*(uint8_t*)(((eiger_packet_header *)((char*)(buffer[ithread] + lastpacketoffset)))->num4)))+1; - cprintf(RED,"%d num packets caught:%d\n",ithread, packetcount); - - - - cout <<"EXITING"<< endl; - exit(-1); - - } - //more than 1 frame caught but missed the frame header packet - //or exactly 1 frame caught - else { - //points to last packet - lastpacketoffset = rc + HEADER_SIZE_NUM_TOT_PACKETS - onePacketSize; - lastpacketheader = ((*(uint8_t*)(((eiger_packet_header *)((char*)(buffer[ithread] + lastpacketoffset)))->num4))); -#ifdef VERYDEBUG - cprintf(BLUE,"%d fnum: 0x%x\n", ithread, htonl(*(unsigned int*)((eiger_image_header *)((char*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS)))->fnum)); - cprintf(BLUE,"%d 1st pnum: 0x%x\n", ithread, ((*(uint8_t*)(((eiger_packet_header *)((char*)(buffer[ithread] + EIGER_HEADER_LENGTH + HEADER_SIZE_NUM_TOT_PACKETS)))->num4)))); - cprintf(BLUE,"%d last packet offset: %d\n",ithread,lastpacketoffset); - cprintf(BLUE,"%d last pnum: 0x%x\n", ithread,((*(uint8_t*)(((eiger_packet_header *)((char*)(buffer[ithread] + lastpacketoffset)))->num4)))); - //for 32 bit try to print 64 bit value of packet header to rule out no other byte changes value other than num4 -#endif - - //proper 1 frame - if((rc == expected) && (lastpacketheader == last_packet_value)){ - break; - } - - //incomplete frame, more than 1 frame caught, but missed header packet - cprintf(RED,"%d INCOMPLETE frame, rc:%d, expected:%d\n", ithread, rc, expected); - cprintf(RED,"%d fnum: 0x%x\n", ithread, htonl(*(unsigned int*)((eiger_image_header *)((char*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS)))->fnum)); - - //if eiger last packet value is NOT as expected according to bit mode - carryonBufferSize += onePacketSize; - lastpacketoffset -= onePacketSize; - --packetcount; - - cprintf(RED,"%d lastpacketheader:%d last packet value:%d packetcount: %d\n",ithread,lastpacketheader,((*(uint8_t*)(((eiger_packet_header *)((char*)(buffer[ithread] + lastpacketoffset)))->num4))), packetcount); - - //while last packet value is greater than current offset packet value (till we reach ff) - while (lastpacketheader > ((*(uint8_t*)(((eiger_packet_header *)((char*)(buffer[ithread] + lastpacketoffset)))->num4))) ){ - - lastpacketheader = ((*(uint8_t*)(((eiger_packet_header *)((char*)(buffer[ithread] + lastpacketoffset)))->num4))); - carryonBufferSize += onePacketSize; - lastpacketoffset -= onePacketSize; - --packetcount; - - cprintf(RED,"%d lastpacketheader:%d last packet value:%d packetcount: %d\n",ithread,lastpacketheader,((*(uint8_t*)(((eiger_packet_header *)((char*)(buffer[ithread] + lastpacketoffset)))->num4))), packetcount); - - } - - cprintf(RED,"%d to copy: %d\n", ithread, carryonBufferSize); - cprintf(RED,"%d lastpacketheader:%d last packet value:%d packetcount: %d\n",ithread,lastpacketheader,((*(uint8_t*)(((eiger_packet_header *)((char*)(buffer[ithread] + lastpacketoffset+onePacketSize)))->num4))), packetcount); - - memcpy(tempchar , buffer[ithread]+(HEADER_SIZE_NUM_TOT_PACKETS), EIGER_HEADER_LENGTH); - memcpy((char*)(tempchar + EIGER_HEADER_LENGTH), buffer[ithread]+(lastpacketoffset+onePacketSize), carryonBufferSize); - (*(unsigned int*)((eiger_image_header *)((char*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS)))->fnum) = htonl(lastframeheader+1); - cprintf(RED,"%d copied\n", ithread); - //#ifdef VERYDEBUG - cprintf(RED,"%d tempchar 1st pnum: 0x%x\n", ithread, ((*(uint8_t*)(((eiger_packet_header *)((char*)(tempchar+EIGER_HEADER_LENGTH)))->num4)))); - //#endif - - - } - //when we lose frame header packet - lastframeheader = htonl(*(unsigned int*)((eiger_image_header *)((char*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS)))->fnum); - cprintf(RED,"%d lastframeheader : %d\n", ithread, lastframeheader); - - */ + //because even headers might be included, so not packet count + (*((uint32_t*)(buffer[ithread]))) = rc; break; - default: break; - } - - -//#ifdef VERYDEBUG - cprintf(BLUE, "%d packetcount:%d carryonbuffer:%d\n", ithread, packetcount, carryonBufferSize); -//#endif //write packet count and push +#ifdef VERYDEBUG + cprintf(BLUE, "%d packetcount:%d carryonbuffer:%d\n", ithread, packetcount, carryonBufferSize); +#endif if(myDetectorType != EIGER) - (*((uint16_t*)(buffer[ithread]))) = packetcount; + (*((uint32_t*)(buffer[ithread]))) = packetcount; totalListeningFrameCount[ithread] += packetcount; #ifdef VERYDEBUG cprintf(BLUE,"%d listener going to push fifo: 0x%x\n", ithread,(void*)(buffer[ithread])); #endif while(!fifo[ithread]->push(buffer[ithread])); #ifdef FIFO_DEBUG - //if(!ithread) cprintf(BLUE, "%d listener pushed into fifo %x\n",ithread, (void*)(buffer[ithread])); #endif + + + } sem_wait(&listensmp[ithread]); @@ -2136,20 +1889,29 @@ int UDPStandardImplementation::startWriting(){ thread_started = 1; - int numpackets[numListeningThreads],previousframe[numListeningThreads] ,nf; - uint32_t tempframenum, tempframenum2; + int totalheader = HEADER_SIZE_NUM_TOT_PACKETS + EIGER_HEADER_LENGTH; + int numpackets[numListeningThreads], popready[numListeningThreads], woffset[numListeningThreads], nf; + bool endofacquisition, startheader[numListeningThreads]; + uint32_t tempframenum[numListeningThreads]; + + uint32_t lastpacketheader[numListeningThreads], currentpacketheader[numListeningThreads]; + int numberofmissingpackets[numListeningThreads]; + char* tempbuffer[numListeningThreads] = NULL; + int tempoffset[numListeningThreads]; + int LAST_PACKET_VALUE; + bool fullframe; + + char* wbuf[numListeningThreads];//interleaved char *d=new char[bufferSize*numListeningThreads]; int xmax=0,ymax=0; - int ret,i; - int packetsPerThread = packetsPerFrame/numListeningThreads; + int ret,i,j; while(1){ nf = 0; - packetsPerThread = packetsPerFrame/numListeningThreads; if(myDetectorType == MOENCH){ xmax = MOENCH_PIXELS_IN_ONE_ROW-1; ymax = MOENCH_PIXELS_IN_ONE_ROW-1; @@ -2162,113 +1924,323 @@ int UDPStandardImplementation::startWriting(){ ymax = GOTTHARD_SHORT_PIXELS_IN_COL-1; } } - //checking for previous numpackets of that thread should be correct - for(i=0;ipop(wbuf[i]); #ifdef FIFO_DEBUG - cprintf(GREEN,"%d writer poped from fifo %x\n", ithread, (void*)(wbuf[i])); + cprintf(MAGENTA,"%d writer poped from fifo %x\n", ithread, (void*)(wbuf[i])); #endif - numpackets[i] = (uint16_t)(*((uint16_t*)wbuf[i])); -//#ifdef VERYDEBUG - cprintf(GREEN,"%d numpackets: %d for fifo :%d\n", ithread, numpackets[i], i); -//#endif + numpackets[i] = (uint32_t)(*((uint32_t*)wbuf[i])); +#ifdef VERYDEBUG + cout << i << " numpackets:" << dec << numpackets[i] << "for fifo :"<< i << endl; +#endif + //dont pop until ready + popready[i] = 0; + //reset offset + woffset[i] = 0; + } } - //if all last dummy frames popped - if(numpackets[i] == 0xFFFF){ + + //check for end of acquisition + endofacquisition = true; + for(i=0;ifnum); + for(i=0;ifnum); + //makes sure it doesnt add the finished thread packet all over again + if(tempframenum == currframenum) + while(woffset[i] <= numpackets[i]){ - //check if one of them is less than the other (both dummies wouldnt reach here) - if(tempframenum!=tempframenum2){ - //frame number of the smaller one - onlyoneport = 1; - smaller = (tempframenum > tempframenum2); - //dummy frame will always be bigger fnum,previousframe = 1 means dont pop out that fifo next time - previousframe[!smaller] = 1; - previousframe[smaller] = 0; + //offset outside boundaries to even check for header + if((woffset[i] + EIGER_HEADER_LENGTH)>= numpackets[i]){ + popready[i] = 1; + fullframe = false; + break; + } - //update only the smaller number - if (smaller) - tempframenum = tempframenum2; - tempframenum += (startFrameIndex-1); //eiger frame numbers start at 1, so need to -1 - } - //no leftover frames left when you write both - else{ - onlyoneport = 0; - previousframe[0] = 0; - previousframe[1] = 0; + //check if header + if( 0x01 == (*(uint16_t*)(((eiger_image_header *)((char*)(wbuf[i] + woffset[i])))->header_confirm))){ + //expected frame header -eiger frame numbers start at 1, so need to -1 + if(tempframenum[i] == (htonl(*(unsigned int*)((eiger_image_header *)((char*)(wbuf[ithread] + woffset[i])))->fnum)+(startFrameIndex-1))){ + woffset[i] += EIGER_HEADER_LENGTH; + startheader[i] = true; + numberofmissingpackets[i] = 0; + lastpacketheader[i] = -1; + tempoffset[i] = 0; + } + //wrong header - leave + else{ + numberofmissingpackets[i] += (LAST_PACKET_VALUE - lastpacketheader[i]); + tempframenum[i]++; + //add missing packets + for(j=0;jnum4))); + //last packet - leave + if(currentpacketheader[i] == LAST_PACKET_VALUE){ + //fill buffer + tempbuffer[i][tempoffset[i]] = wbuf[i] + woffset[i]; + woffset[i] += onePacketSize; + //reset + startheader[i] = false; + lastpacketheader[i] = -1; + tempoffset[i] = 0; + break; + } + //same frame packet + if(currentpacketheader[i] > lastpacketheader[i]){ + + if(!startheader[i]){ + tempframenum[i]++; + } + else + startheader[i] = false; + lastpacketheader[i] = -1; + numberofmissingpackets[i] = 0; + numberofmissingpackets[i] += (currentpacketheader[i] - lastpacketheader[i] -1); + //add missing packets + for(j=0;jnum1)) = currframenum; + //overwriting port number and dynamic range + if (!j) (*(uint8_t*)(((eiger_packet_header *)((char*)(tempoffset[j] + onePacketSize*i)))->num3)) = (dynamicRange<<2); + else (*(uint8_t*)(((eiger_packet_header *)((char*)(tempoffset[j] + onePacketSize*i)))->num3)) = ((dynamicRange<<2)|(0x1)); + + #ifdef VERYDEBUG + cprintf(GREEN, "%d - 0x%x - %d\n", i, + (*(uint8_t*)(((eiger_packet_header *)((char*)(tempoffset[j] + i*onePacketSize)))->num3)), + (*(uint8_t*)(((eiger_packet_header *)((char*)(tempoffset[j] + i*onePacketSize)))->num4))); + #endif + + } + + //for 32 bit,port number needs to be changed and packet number reconstructed + if(dynamicRange == 32){ + for (i = 0; i < packetsPerFrame/4; i++){ + //new packet number that has space for 16 bit + (*(uint16_t*)(((eiger_packet_header *)((char*)(tempoffset[j] + onePacketSize*i)))->num2)) + = ((*(uint8_t*)(((eiger_packet_header *)((char*)(tempoffset[j] + onePacketSize*i)))->num4))); + + #ifdef VERYDEBUG + cprintf(GREEN, "%d - 0x%x - %d - %d\n", i, + (*(uint8_t*)(((eiger_packet_header *)((char*)(tempoffset[j] + i*onePacketSize)))->num3)), + (*(uint8_t*)(((eiger_packet_header *)((char*)(tempoffset[j] + i*onePacketSize)))->num4)), + (*(uint16_t*)(((eiger_packet_header *)((char*)(tempoffset[j] + i*onePacketSize)))->num2))); + #endif + } + for (i = packetsPerFrame/4; i < packetsPerFrame/2; i++){ + //new packet number that has space for 16 bit + (*(uint16_t*)(((eiger_packet_header *)((char*)(tempoffset[j] + onePacketSize*i)))->num2)) + = ((*(uint8_t*)(((eiger_packet_header *)((char*)(tempoffset[j] + onePacketSize*i)))->num4))+(packetsPerFrame/4)); + + #ifdef VERYDEBUG + cprintf(GREEN, "%d -0x%x - %d - %d\n", i, + (*(uint8_t*)(((eiger_packet_header *)((char*)(tempoffset[j] + i*onePacketSize)))->num3)), + (*(uint8_t*)(((eiger_packet_header *)((char*)(tempoffset[j] + i*onePacketSize)))->num4)), + (*(uint16_t*)(((eiger_packet_header *)((char*)(tempoffset[j] + i*onePacketSize)))->num2))); + #endif + } + } - }else if ((myDetectorType == GOTTHARD) && (shortFrame == -1)) - tempframenum = (((((uint32_t)(*((uint32_t*)(wbuf[ithread] + HEADER_SIZE_NUM_TOT_PACKETS))))+1)& (frameIndexMask)) >> frameIndexOffset); - else - tempframenum = ((((uint32_t)(*((uint32_t*)(wbuf[ithread] + HEADER_SIZE_NUM_TOT_PACKETS))))& (frameIndexMask)) >> frameIndexOffset); - if(numWriterThreads == 1) - currframenum = tempframenum; - else{ - pthread_mutex_lock(&progress_mutex); - if(tempframenum > currframenum) - currframenum = tempframenum; - pthread_mutex_unlock(&progress_mutex); - } -#ifdef EIGER_DEBUG2 - cprintf(GREEN,"%d tempframenum:%d curframenum:%d\n",ithread, tempframenum, currframenum); #endif - //without datacompression: write datacall back, or write data, free fifo - if(!dataCompression) handleWithoutDataCompression(ithread,wbuf,onlyoneport,smaller); - //data compression - else handleDataCompression(ithread,wbuf,d, xmax, ymax, nf); + //writeToFile_withoutCompression(wbuffer[j], npackets,currframenum); + + + + + } + } + + +#ifdef VERYDEBUG + cprintf(GREEN,"gonna copy frame\n"); +#endif + copyFrameToGui(wbuffer,currframenum); +//#ifdef VERYDEBUG + cprintf(GREEN,"copied frame\n"); +//#endif + + for(i=0;ipush(tempoffset[i])); + #ifdef FIFO_DEBUG + cprintf(GREEN,"%d writer freed pushed into fifofree %x for listener %d\n",ithread, (void*)(tempoffset[i]),i); + #endif + } + + +#ifdef EIGER_DEBUG2 + cout << endl <> frameIndexOffset); + else + tempframenum[0] = ((((uint32_t)(*((uint32_t*)(wbuf[ithread] + HEADER_SIZE_NUM_TOT_PACKETS))))& (frameIndexMask)) >> frameIndexOffset); + + if(numWriterThreads == 1) + currframenum = tempframenum[0]; + else{ + pthread_mutex_lock(&progress_mutex); + if(tempframenum[0] > currframenum) + currframenum = tempframenum[0]; + pthread_mutex_unlock(&progress_mutex); + } + + + //without datacompression: write datacall back, or write data, free fifo + if(!dataCompression) handleWithoutDataCompression(ithread,wbuf); + //data compression + else handleDataCompression(ithread,wbuf,d, xmax, ymax, nf); + + } + } #ifdef VERYVERBOSE cprintf(GREEN,"%d gonna wait for 1st sem\n", ithread); @@ -2276,7 +2248,7 @@ int UDPStandardImplementation::startWriting(){ //wait sem_wait(&writersmp[ithread]); if(killAllWritingThreads){ - cout << ithread << " good bye writing thread" << endl; + cprintf(GREEN,"%d good bye writing thread\n", ithread); closeFile(ithread); pthread_exit(NULL); } @@ -2313,7 +2285,7 @@ int UDPStandardImplementation::startWriting(){ //wait sem_wait(&writersmp[ithread]); if(killAllWritingThreads){ - cout << ithread << " Goodbye thread" << endl; + cprintf(GREEN,"%d Goodbye thread\n", ithread); closeFile(ithread); pthread_exit(NULL); } @@ -2355,11 +2327,7 @@ void UDPStandardImplementation::startFrameIndices(int ithread){ } //for scans, cuz currfraenum resets else if (myDetectorType == EIGER){ - /*if(dynamicRange == 32) - startFrameIndex = (currframenum + 1);// to be added later for scans - else*/ - startFrameIndex += currframenum; - + startFrameIndex += currframenum; } @@ -2375,93 +2343,95 @@ void UDPStandardImplementation::stopListening(int ithread, int rc, int &pc, int FILE_LOG(logDEBUG) << __AT__ << " called"; -int i; + int i; #ifdef VERYVERBOSE - cprintf(BLUE, "%d recvfrom() failed\n", ithread); + cprintf(BLUE, "%d Stop Listening\n", ithread); #endif - if(status != TRANSMITTING){ - cprintf(BG_RED,"%d *** should never be here********* status not transmitting***********************\n", ithread);/**/ - fifoFree[ithread]->push(buffer[ithread]); + + + if(status != TRANSMITTING){ + cprintf(BG_RED,"%d *** udp socket not shut down from client ***********************\n", ithread); + while(!fifoFree[ithread]->push(buffer[ithread])); + exit(-1); + } + + + //free buffer + if(rc <= 0){ + cprintf(BLUE,"%d End of acquisition\n", ithread); + while(!fifoFree[ithread]->push(buffer[ithread])); #ifdef FIFO_DEBUG - cprintf(BLUE,"%d listener not txm free pushed into fifofree %x\n", ithread,(void*)(buffer[ithread])); + cprintf(BLUE,"%d listener empty buffer pushed into fifofree %x\n", ithread, (void*)(buffer[ithread])); #endif - exit(-1); - } - - //free buffer - if(rc <= 0){ - cprintf(BLUE,"%d End of acquisition\n", ithread); - fifoFree[ithread]->push(buffer[ithread]);/** why not while(!)*/ -#ifdef FIFO_DEBUG - cprintf(BLUE,"%d listener empty buffer pushed into fifofree %x\n", ithread, (void*)(buffer[ithread])); -#endif - } - //push the last buffer into fifo - else{ - - if (rc < (bufferSize * numJobsPerThread)) - cprintf(RED,"%d Pushing Incomplete frame into fifo\n", ithread); - //eiger (complete frames) + other detectors - pc = (rc/onePacketSize); -//#ifdef VERYDEBUG - cprintf(BLUE,"%d last rc:%d\n",ithread, rc); - cprintf(BLUE,"%d last packetcount:%d\n", ithread, pc); -//#endif - (*((uint16_t*)(buffer[ithread]))) = pc; - totalListeningFrameCount[ithread] += pc; - while(!fifo[ithread]->push(buffer[ithread])); -#ifdef FIFO_DEBUG - cprintf(BLUE,"%d listener last buffer pushed into fifo %x\n", ithread,(void*)(buffer[ithread])); -#endif - - } + } - - //push dummy buffer to all writer threads - for(i=0;ipop(buffer[ithread]); -#ifdef FIFO_DEBUG - cprintf(BLUE,"%d listener popped dummy buffer from fifofree %x\n", ithread,(void*)(buffer[ithread])); -#endif - (*((uint16_t*)(buffer[ithread]))) = 0xFFFF; + //push the last buffer into fifo + else{ + pc = (rc/onePacketSize); #ifdef VERYDEBUG - cprintf(BLUE,"%d dummy buffer num packets:%d\n", ithread(*((uint16_t*)(buffer[ithread])))); + cprintf(BLUE,"%d last rc:%d\n",ithread, rc); + cprintf(BLUE,"%d last packetcount:%d\n", ithread, pc); #endif - while(!fifo[ithread]->push(buffer[ithread])); -//#ifdef FIFO_DEBUG - cprintf(BLUE,"%d listener pushed dummy buffer into fifo %x\n", ithread,(void*)(buffer[ithread])); -//#endif - } + (*((uint32_t*)(buffer[ithread]))) = pc; + totalListeningFrameCount[ithread] += pc; + while(!fifo[ithread]->push(buffer[ithread])); +#ifdef FIFO_DEBUG + cprintf(BLUE,"%d listener last buffer pushed into fifo %x\n", ithread,(void*)(buffer[ithread])); +#endif + } - //reset mask and exit loop - pthread_mutex_lock(&status_mutex); - listeningthreads_mask^=(1<pop(buffer[ithread]); +#ifdef FIFO_DEBUG + cprintf(BLUE,"%d listener popped dummy buffer from fifofree %x\n", ithread,(void*)(buffer[ithread])); +#endif + (*((uint32_t*)(buffer[ithread]))) = 0x0; #ifdef VERYDEBUG - cprintf(BLUE,"%d Resetting mask of current listening thread. New Mask: 0x%x", ithread, listeningthreads_mask); + cprintf(BLUE,"%d dummy buffer num packets:%d\n", ithread(*((uint16_t*)(buffer[ithread])))); #endif - pthread_mutex_unlock(&(status_mutex)); + while(!fifo[ithread]->push(buffer[ithread])); +#ifdef FIFO_DEBUG + cprintf(BLUE,"%d listener pushed dummy buffer into fifo %x\n", ithread,(void*)(buffer[ithread])); +#endif + } -//#ifdef VERYDEBUG - cprintf(BLUE,"%d: Frames listened to %d\n",ithread, ((totalListeningFrameCount[ithread]*numListeningThreads)/packetsPerFrame)); -//#endif - //waiting for all listening threads to be done, to print final count of frames listened to - if(ithread == 0){ + + //reset mask and exit loop + pthread_mutex_lock(&status_mutex); + listeningthreads_mask^=(1< 1) - cprintf(BLUE,"%d Waiting for listening to be done.. current mask:0x%x\n", ithread, listeningthreads_mask); + cprintf(BLUE,"%d Resetting mask of current listening thread. New Mask: 0x%x", ithread, listeningthreads_mask); #endif - while(listeningthreads_mask) - usleep(5000); -//#ifdef VERYDEBUG - t = 0; - for(i=0;i 1) + cprintf(BLUE,"%d Waiting for listening to be done.. current mask:0x%x\n", ithread, listeningthreads_mask); +#endif + while(listeningthreads_mask) + usleep(5000); +#ifdef VERYDEBUG + t = 0; + for(i=0;ipush(wbuffer[i])); +#ifdef FIFO_DEBUG + cprintf(GREEN,"%d writer free dummy pushed into fifofree %x for listener %d\n", ithread,(void*)(wbuffer[i]),i); +#endif + } + + + //all threads need to close file, reset mask and exit loop closeFile(ithread); pthread_mutex_lock(&status_mutex); @@ -2551,42 +2536,42 @@ void UDPStandardImplementation::writeToFile_withoutCompression(char* buf,int num if(myDetectorType == EIGER){ int k = 0; if(dynamicRange != 32){ - cprintf(GREEN, "\np1 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf + offset+k*1040)))->num1))); - cprintf(GREEN, "p1:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset+k*1040)))->num3))); - cprintf(GREEN, "p0 num:%d - %d\n", k, (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset+k*1040)))->num4))); + cprintf(RED, "\np1 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf + offset+k*1040)))->num1))); + cprintf(RED, "p1:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset+k*1040)))->num3))); + cprintf(RED, "p0 num:%d - %d\n", k, (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset+k*1040)))->num4))); k = 1; - cprintf(GREEN, "p2 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num1))); - cprintf(GREEN, "p2:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num3))); - cprintf(GREEN, "p1 num:%d - %d\n", k,(*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num4))); + cprintf(RED, "p2 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num1))); + cprintf(RED, "p2:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num3))); + cprintf(RED, "p1 num:%d - %d\n", k,(*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num4))); k = 2; - cprintf(GREEN, "p3 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf + offset + k*1040)))->num1))); - cprintf(GREEN, "p3:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num3))); - cprintf(GREEN, "p2 num:%d - %d\n", k,(*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num4))); + cprintf(RED, "p3 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf + offset + k*1040)))->num1))); + cprintf(RED, "p3:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num3))); + cprintf(RED, "p2 num:%d - %d\n", k,(*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num4))); }else{ k = 0; - cprintf(GREEN, "\np1 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf + offset+k*1040)))->num1))); - cprintf(GREEN, "p1:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset+k*1040)))->num3))); - cprintf(GREEN, "p0 num:%d - %d\n", k, (*(uint16_t*)(((eiger_packet_header *)((char*)(buf + offset+k*1040)))->num2))); + cprintf(RED, "\np1 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf + offset+k*1040)))->num1))); + cprintf(RED, "p1:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset+k*1040)))->num3))); + cprintf(RED, "p0 num:%d - %d\n", k, (*(uint16_t*)(((eiger_packet_header *)((char*)(buf + offset+k*1040)))->num2))); k = 1; - cprintf(GREEN, "p2 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num1))); - cprintf(GREEN, "p2:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num3))); - cprintf(GREEN, "p1 num:%d - %d\n", k, (*(uint16_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num2))); + cprintf(RED, "p2 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num1))); + cprintf(RED, "p2:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num3))); + cprintf(RED, "p1 num:%d - %d\n", k, (*(uint16_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num2))); k = 2; - cprintf(GREEN, "p3 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf + offset + k*1040)))->num1))); - cprintf(GREEN, "p3:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num3))); - cprintf(GREEN, "p2 num:%d - %d\n", k, (*(uint16_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num2))); + cprintf(RED, "p3 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf + offset + k*1040)))->num1))); + cprintf(RED, "p3:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num3))); + cprintf(RED, "p2 num:%d - %d\n", k, (*(uint16_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num2))); k = 256; - cprintf(GREEN, "p257 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf + offset + k*1040)))->num1))); - cprintf(GREEN, "p257:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num3))); - cprintf(GREEN, "p256 num:%d - %d\n", k, (*(uint16_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num2))); + cprintf(RED, "p257 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf + offset + k*1040)))->num1))); + cprintf(RED, "p257:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num3))); + cprintf(RED, "p256 num:%d - %d\n", k, (*(uint16_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num2))); k = 512; - cprintf(GREEN, "p513 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf + offset + k*1040)))->num1))); - cprintf(GREEN, "p513:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num3))); - cprintf(GREEN, "p512 num:%d - %d\n", k, (*(uint16_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num2))); + cprintf(RED, "p513 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf + offset + k*1040)))->num1))); + cprintf(RED, "p513:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num3))); + cprintf(RED, "p512 num:%d - %d\n", k, (*(uint16_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num2))); k = 768; - cprintf(GREEN, "p769 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf + offset + k*1040)))->num1))); - cprintf(GREEN, "p769:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num3))); - cprintf(GREEN, "p768 num:%d - %d\n", k,(*(uint16_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num2))); + cprintf(RED, "p769 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf + offset + k*1040)))->num1))); + cprintf(RED, "p769:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num3))); + cprintf(RED, "p768 num:%d - %d\n", k,(*(uint16_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num2))); } } #endif @@ -2607,9 +2592,9 @@ void UDPStandardImplementation::writeToFile_withoutCompression(char* buf,int num if(tempframenum > currframenum) currframenum = tempframenum; } -//#ifdef VERYDEBUG - cprintf(GREEN,"tempframenum: %d curframenum: %d\n",tempframenum,currframenum); -//#endif +#ifdef VERYDEBUG + cout << "tempframenum:" << dec << tempframenum << " curframenum:" << currframenum << endl; +#endif //lock if(numWriterThreads > 1) @@ -2626,7 +2611,7 @@ void UDPStandardImplementation::writeToFile_withoutCompression(char* buf,int num packetsCaught += packetsToSave; totalPacketsCaught += packetsToSave; #ifdef VERYDEBUG - cprintf(GREEN,"%d totalPacketsCaught: %d\n", ithread, totalPacketsCaught); + cout << "/totalPacketsCaught:" << dec << totalPacketsCaught <= maxPacketsPerFile){ @@ -2644,9 +2629,9 @@ void UDPStandardImplementation::writeToFile_withoutCompression(char* buf,int num if(tempframenum > currframenum) currframenum = tempframenum; } -//#ifdef VERYDEBUG - cprintf(GREEN,"tempframenum: %d curframenum: %d\n", tempframenum ,currframenum); -//#endif +#ifdef VERYDEBUG + cout << "tempframenum:" << dec << tempframenum << " curframenum:" << currframenum << endl; +#endif //create createNewFile(); } @@ -2675,16 +2660,17 @@ void UDPStandardImplementation::writeToFile_withoutCompression(char* buf,int num -void UDPStandardImplementation::handleWithoutDataCompression(int ithread, char* wbuffer[], int partialframe, int smaller){ + + + + +void UDPStandardImplementation::handleWithoutDataCompression(int ithread, char* wbuffer[]){ int totalheader = HEADER_SIZE_NUM_TOT_PACKETS + EIGER_HEADER_LENGTH; int i,j,npackets, ntotpackets=0; if (cbAction < DO_EVERYTHING){ for(i=0;ipush(wbuffer[0])); #ifdef FIFO_DEBUG - cprintf(GREEN,"%d writer compression free pushed into fifofree %x for listerner 0\n", ithread, (void*)(wbuffer[0])); + cprintf(BLUE,"%d writer compression free pushed into fifofree %x for listerner 0\n", ithread, (void*)(wbuffer[0])); #endif } From 4e5209699152d8a6f83754c8ff34fc2f6803838c Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 21 Jul 2015 16:25:56 +0200 Subject: [PATCH 107/474] included propix receiver --- slsReceiverSoftware/include/receiver_defs.h | 38 ++++- .../include/slsReceiverTCPIPInterface.h | 3 + .../include/sls_receiver_defs.h | 3 +- .../src/UDPStandardImplementation.cpp | 26 ++- .../src/slsReceiverTCPIPInterface.cpp | 158 ++++++++++++++++++ 5 files changed, 213 insertions(+), 15 deletions(-) diff --git a/slsReceiverSoftware/include/receiver_defs.h b/slsReceiverSoftware/include/receiver_defs.h index 6f3b1acd3..6466a45b5 100755 --- a/slsReceiverSoftware/include/receiver_defs.h +++ b/slsReceiverSoftware/include/receiver_defs.h @@ -51,6 +51,26 @@ + +#define PROPIX_PIXELS_IN_ROW 22 +#define PROPIX_PIXELS_IN_COL 22 +#define PROPIX_DATABYTES_PER_PIXEL 2 + +#define PROPIX_FIFO_SIZE 25000 //cannot be less than max jobs per thread = 1000 +#define PROPIX_PACKETS_PER_FRAME 2 +#define PROPIX_ONE_PACKET_SIZE 1286 +#define PROPIX_BUFFER_SIZE (PROPIX_ONE_PACKET_SIZE*PROPIX_PACKETS_PER_FRAME) //1286*2 +//#define PROPIX_DATA_BYTES (1280*PROPIX_PACKETS_PER_FRAME) //1280*2 +#define PROPIX_DATA_BYTES (PROPIX_PIXELS_IN_ROW * PROPIX_PIXELS_IN_COL * PROPIX_DATABYTES_PER_PIXEL) //22 * 22 * 2 + +#define PROPIX_FRAME_INDEX_MASK 0xFFFFFFFE +#define PROPIX_FRAME_INDEX_OFFSET 1 +#define PROPIX_PACKET_INDEX_MASK 0x1 + + + + + #define MOENCH_FIFO_SIZE 2500 //cannot be less than max jobs per thread = 1000 /*#define MOENCH_ALIGNED_FRAME_SIZE 65536*/ #define MOENCH_PACKETS_PER_FRAME 40 @@ -68,19 +88,19 @@ -#define JCTB_FIFO_SIZE 2500 //cannot be less than max jobs per thread = 1000 +#define JCTB_FIFO_SIZE 2500 //cannot be less than max jobs per thread = 1000 /*#define MOENCH_ALIGNED_FRAME_SIZE 65536*/ -#define JCTB_PACKETS_PER_FRAME 50 +#define JCTB_PACKETS_PER_FRAME 50 #define JCTB_ONE_PACKET_SIZE 8214 -#define JCTB_BUFFER_SIZE (MOENCH_ONE_PACKET_SIZE*MOENCH_PACKETS_PER_FRAME) -#define JCTB_DATA_BYTES (JCTB_BUFFER_PER_FRAME) +#define JCTB_BUFFER_SIZE (MOENCH_ONE_PACKET_SIZE*MOENCH_PACKETS_PER_FRAME) +#define JCTB_DATA_BYTES (JCTB_BUFFER_PER_FRAME) -#define JCTB_FRAME_INDEX_MASK 0xFFFFFF00 -#define JCTB_FRAME_INDEX_OFFSET 8 -#define JCTB_PACKET_INDEX_MASK 0xFF +#define JCTB_FRAME_INDEX_MASK 0xFFFFFF00 +#define JCTB_FRAME_INDEX_OFFSET 8 +#define JCTB_PACKET_INDEX_MASK 0xFF -#define JCTB_BYTES_PER_ADC (2) -#define JCTB_PIXELS_IN_ONE_ROW 32 +#define JCTB_BYTES_PER_ADC (2) +#define JCTB_PIXELS_IN_ONE_ROW 32 #define JCTB_BYTES_IN_ONE_ROW (JCTB_PIXELS_IN_ONE_ROW*2) diff --git a/slsReceiverSoftware/include/slsReceiverTCPIPInterface.h b/slsReceiverSoftware/include/slsReceiverTCPIPInterface.h index ea0e1a3d0..83d9416aa 100644 --- a/slsReceiverSoftware/include/slsReceiverTCPIPInterface.h +++ b/slsReceiverSoftware/include/slsReceiverTCPIPInterface.h @@ -170,6 +170,9 @@ private: /** gotthard specific read frame */ int gotthard_read_frame(); + /** propix specific read frame */ + int propix_read_frame(); + /** moench specific read frame */ int moench_read_frame(); diff --git a/slsReceiverSoftware/include/sls_receiver_defs.h b/slsReceiverSoftware/include/sls_receiver_defs.h index 025e3b9cf..6abb30887 100755 --- a/slsReceiverSoftware/include/sls_receiver_defs.h +++ b/slsReceiverSoftware/include/sls_receiver_defs.h @@ -58,7 +58,8 @@ public: AGIPD, /**< agipd */ MOENCH, /**< moench */ JUNGFRAU, /**< jungfrau */ - JUNGFRAUCTB /**< jungfrauCTBversion */ + JUNGFRAUCTB, /**< jungfrauCTBversion */ + PROPIX /**< propix */ }; diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 0b22d8888..12edd0720 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -262,6 +262,9 @@ int UDPStandardImplementation::setDetectorType(detectorType det){ FILE_LOG(logD case GOTTHARD: cout << endl << "***** This is a GOTTHARD Receiver *****" << endl << endl; break; + case PROPIX: + cout << endl << "***** This is a PROPIX Receiver *****" << endl << endl; + break; case MOENCH: cout << endl << "***** This is a MOENCH Receiver *****" << endl << endl; break; @@ -280,7 +283,7 @@ int UDPStandardImplementation::setDetectorType(detectorType det){ FILE_LOG(logD break; } - //moench variables + //detector specific variables if(myDetectorType == GOTTHARD){ fifosize = GOTTHARD_FIFO_SIZE; packetsPerFrame = GOTTHARD_PACKETS_PER_FRAME; @@ -291,6 +294,16 @@ int UDPStandardImplementation::setDetectorType(detectorType det){ FILE_LOG(logD frameIndexMask = GOTTHARD_FRAME_INDEX_MASK; frameIndexOffset = GOTTHARD_FRAME_INDEX_OFFSET; packetIndexMask = GOTTHARD_PACKET_INDEX_MASK; + }else if(myDetectorType == PROPIX){ + fifosize = PROPIX_FIFO_SIZE; + packetsPerFrame = PROPIX_PACKETS_PER_FRAME; + onePacketSize = PROPIX_ONE_PACKET_SIZE; + frameSize = PROPIX_BUFFER_SIZE; + bufferSize = PROPIX_BUFFER_SIZE; + maxPacketsPerFile = MAX_FRAMES_PER_FILE * PROPIX_PACKETS_PER_FRAME; + frameIndexMask = PROPIX_FRAME_INDEX_MASK; + frameIndexOffset = PROPIX_FRAME_INDEX_OFFSET; + packetIndexMask = PROPIX_PACKET_INDEX_MASK; }else if(myDetectorType == MOENCH){ fifosize = MOENCH_FIFO_SIZE; packetsPerFrame = MOENCH_PACKETS_PER_FRAME; @@ -827,6 +840,8 @@ void UDPStandardImplementation::setupFifoStructure(){ fifosize = GOTTHARD_FIFO_SIZE; if(myDetectorType == MOENCH) fifosize = MOENCH_FIFO_SIZE; + if(myDetectorType == PROPIX) + fifosize = PROPIX_FIFO_SIZE; else if(myDetectorType == EIGER) fifosize = EIGER_FIFO_SIZE; @@ -1797,6 +1812,7 @@ int UDPStandardImplementation::startListening(){ break; case GOTTHARD: + case PROPIX: if(shortFrame == -1){ lastpacketoffset = (((numJobsPerThread * packetsPerFrame - 1) * onePacketSize) + HEADER_SIZE_NUM_TOT_PACKETS); #ifdef VERYDEBUG @@ -1959,7 +1975,7 @@ int UDPStandardImplementation::startWriting(){ tempframenum += (startFrameIndex-1); //eiger frame numbers start at 1, so need to -1 //tempframenum = ((tempframenum / EIGER_32BIT_INITIAL_CONSTANT) + startFrameIndex)-1;//eiger 32 bit mode is a multiple of 17c. +startframeindex for scans - }else if ((myDetectorType == GOTTHARD) && (shortFrame == -1)) + }else if ((myDetectorType == PROPIX) || ((myDetectorType == GOTTHARD) && (shortFrame == -1))) tempframenum = (((((uint32_t)(*((uint32_t*)(wbuf[ithread] + HEADER_SIZE_NUM_TOT_PACKETS))))+1)& (frameIndexMask)) >> frameIndexOffset); else tempframenum = ((((uint32_t)(*((uint32_t*)(wbuf[ithread] + HEADER_SIZE_NUM_TOT_PACKETS))))& (frameIndexMask)) >> frameIndexOffset); @@ -2156,7 +2172,7 @@ void UDPStandardImplementation::startFrameIndices(int ithread){ startFrameIndex = htonl(*(unsigned int*)((eiger_image_header *)((char*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS)))->fnum); } //gotthard has +1 for frame number and not a short frame - else if ((myDetectorType == GOTTHARD) && (shortFrame == -1)) + else if ((myDetectorType == PROPIX) || ((myDetectorType == GOTTHARD) && (shortFrame == -1))) startFrameIndex = (((((uint32_t)(*((uint32_t*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS))))+1) & (frameIndexMask)) >> frameIndexOffset); else @@ -2437,7 +2453,7 @@ void UDPStandardImplementation::writeToFile_withoutCompression(char* buf,int num //for progress and packet loss calculation(new files) if(myDetectorType == EIGER); - else if ((myDetectorType == GOTTHARD) && (shortFrame == -1)) + else if ((myDetectorType == PROPIX)||((myDetectorType == GOTTHARD) && (shortFrame == -1))) tempframenum = (((((uint32_t)(*((uint32_t*)(buf + HEADER_SIZE_NUM_TOT_PACKETS))))+1)& (frameIndexMask)) >> frameIndexOffset); else tempframenum = ((((uint32_t)(*((uint32_t*)(buf + HEADER_SIZE_NUM_TOT_PACKETS))))& (frameIndexMask)) >> frameIndexOffset); @@ -2474,7 +2490,7 @@ void UDPStandardImplementation::writeToFile_withoutCompression(char* buf,int num //for packet loss lastpacket = (((packetsToSave - 1) * onePacketSize) + offset); if(myDetectorType == EIGER); - else if ((myDetectorType == GOTTHARD) && (shortFrame == -1)) + else if ((myDetectorType == PROPIX)||((myDetectorType == GOTTHARD) && (shortFrame == -1))) tempframenum = (((((uint32_t)(*((uint32_t*)(buf + lastpacket))))+1)& (frameIndexMask)) >> frameIndexOffset); else tempframenum = ((((uint32_t)(*((uint32_t*)(buf + lastpacket))))& (frameIndexMask)) >> frameIndexOffset); diff --git a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp index 2c882b139..631df46d1 100644 --- a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp +++ b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp @@ -1027,6 +1027,8 @@ int slsReceiverTCPIPInterface::read_frame(){ return moench_read_frame(); case EIGER: return eiger_read_frame(); + case PROPIX: + return propix_read_frame(); default: return gotthard_read_frame(); } @@ -1393,6 +1395,162 @@ int slsReceiverTCPIPInterface::gotthard_read_frame(){ +int slsReceiverTCPIPInterface::propix_read_frame(){ + ret=OK; + char fName[MAX_STR_LENGTH]=""; + int acquisitionIndex = -1; + int frameIndex= -1; + int i; + + + //retval is a full frame + int bufferSize = PROPIX_BUFFER_SIZE; + int onebuffersize = bufferSize/PROPIX_PACKETS_PER_FRAME; + int onedatasize = PROPIX_DATA_BYTES; + + char* raw = new char[bufferSize]; + int rnel = bufferSize/(sizeof(int)); + int* retval = new int[rnel]; + int* origVal = new int[rnel]; + //all initialized to 0 + for(i=0;igetFramesCaught()){ + startAcquisitionIndex=-1; + cout<<"haven't caught any frame yet"<getStartFrameIndex();*/ + receiverBase->readFrame(fName,&raw,index,startAcquisitionIndex,startFrameIndex); + + /**send garbage with -1 index to try again*/ + if (raw == NULL){ + startAcquisitionIndex = -1; +#ifdef VERBOSE + cout<<"data not ready for gui yet"<> PROPIX_FRAME_INDEX_OFFSET); + bindex2 = ((uint32_t)(*((uint32_t*)((char*)(raw+onebuffersize)))))+1; + pindex2 =(bindex2 & PROPIX_PACKET_INDEX_MASK); + index2 =((bindex2 & PROPIX_FRAME_INDEX_MASK) >> PROPIX_FRAME_INDEX_OFFSET); +#ifdef VERBOSE + cout << "index1:" << hex << index << endl; + cout << "index2:" << hex << index << endl; +#endif + + memcpy(origVal,raw,bufferSize); + raw=NULL; + + /*//ignore if half frame is missing + if ((bindex != 0xFFFFFFFF) && (bindex2 != 0xFFFFFFFF)){*/ + + //should be same frame + if (index == index2){ + //ideal situation (should be odd, even(index+1)) + if(!pindex){ + memcpy(retval,((char*) origVal)+4, onedatasize); + memcpy((((char*)retval)+onedatasize), ((char*) origVal)+10+onedatasize, onedatasize); + } + //swap to even,odd + else{ + memcpy((((char*)retval)+onedatasize),((char*) origVal)+4, onedatasize); + memcpy(retval, ((char*) origVal)+10+onedatasize, onedatasize); + index=index2; + } + }else + cout << "different frames caught. frame1:"<< hex << index << ":"<differentClients){ + cout << "Force update" << endl; + ret=FORCE_UPDATE; + } + + // send answer + socket->SendDataOnly(&ret,sizeof(ret)); + if(ret==FAIL){ + cout << "mess:" << mess << endl; + socket->SendDataOnly(mess,sizeof(mess)); + } + else{ + socket->SendDataOnly(fName,MAX_STR_LENGTH); + socket->SendDataOnly(&acquisitionIndex,sizeof(acquisitionIndex)); + socket->SendDataOnly(&frameIndex,sizeof(frameIndex)); + socket->SendDataOnly(retval,PROPIX_DATA_BYTES); + } + + delete [] retval; + delete [] origVal; + delete [] raw; + + return ret; +} + + + + + + + + int slsReceiverTCPIPInterface::eiger_read_frame(){ From f970baf1b827031ca32861a0f330594c4d60267a Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Mon, 27 Jul 2015 12:36:45 +0200 Subject: [PATCH 108/474] write and copy to gui left --- .../include/UDPStandardImplementation.h | 3 +- .../src/UDPStandardImplementation.cpp | 370 +++++++----------- 2 files changed, 144 insertions(+), 229 deletions(-) diff --git a/slsReceiverSoftware/include/UDPStandardImplementation.h b/slsReceiverSoftware/include/UDPStandardImplementation.h index 42650e9bb..3462ded22 100644 --- a/slsReceiverSoftware/include/UDPStandardImplementation.h +++ b/slsReceiverSoftware/include/UDPStandardImplementation.h @@ -442,8 +442,9 @@ private: * Its called for the first packet of a scan or acquistion * Sets the startframeindices and the variables to know if acquisition started * @param ithread listening thread number + * @param numbytes number of bytes it listened to */ - void startFrameIndices(int ithread); + void startFrameIndices(int ithread, int numbytes); /** * This is called when udp socket is shut down diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 84d1adcbc..ed0df1b47 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -828,15 +828,17 @@ void UDPStandardImplementation::setupFifoStructure(){ if(myDetectorType == MOENCH) fifosize = MOENCH_FIFO_SIZE; else if(myDetectorType == EIGER) - fifosize = EIGER_FIFO_SIZE; + fifosize = EIGER_FIFO_SIZE * packetsPerFrame; if(fifosize % numJobsPerThread) fifosize = (fifosize/numJobsPerThread)+1; else fifosize = fifosize/numJobsPerThread; - - cout << "Number of Frames per buffer:" << numJobsPerThread << endl; + if(myDetectorType == EIGER) + cout << "1 packet per buffer" << endl; + else + cout << "Number of Frames per buffer:" << numJobsPerThread << endl; cout << "Fifo Size:" << fifosize << endl; /* @@ -854,27 +856,32 @@ void UDPStandardImplementation::setupFifoStructure(){ #endif delete fifoFree[i]; } - if(fifo[i]) delete fifo[i]; + if(fifo[i]) delete fifo[i]; if(mem0[i]) free(mem0[i]); fifoFree[i] = new CircularFifo(fifosize); fifo[i] = new CircularFifo(fifosize); + int whatperbuffer = bufferSize; + if(myDetectorType == EIGER) + whatperbuffer = onePacketSize; + //allocate memory - mem0[i]=(char*)malloc((bufferSize * numJobsPerThread + HEADER_SIZE_NUM_TOT_PACKETS)*fifosize); + mem0[i]=(char*)malloc((whatperbuffer * numJobsPerThread + HEADER_SIZE_NUM_TOT_PACKETS)*fifosize); /** shud let the client know about this */ if (mem0[i]==NULL){ cout<<"++++++++++++++++++++++ COULD NOT ALLOCATE MEMORY FOR LISTENING !!!!!!!+++++++++++++++++++++" << endl; exit(-1); } + buffer[i]=mem0[i]; //push the addresses into freed fifoFree and writingFifoFree - while (buffer[i]<(mem0[i]+(bufferSize * numJobsPerThread + HEADER_SIZE_NUM_TOT_PACKETS)*(fifosize-1))) { + while (buffer[i]<(mem0[i]+(whatperbuffer * numJobsPerThread + HEADER_SIZE_NUM_TOT_PACKETS)*(fifosize-1))) { fifoFree[i]->push(buffer[i]); #ifdef FIFO_DEBUG cprintf(BLUE,"%d fifostructure free pushed into fifofree %x\n", i, (void*)(buffer[i])); #endif - buffer[i]+=(bufferSize * numJobsPerThread + HEADER_SIZE_NUM_TOT_PACKETS); + buffer[i]+=(whatperbuffer * numJobsPerThread + HEADER_SIZE_NUM_TOT_PACKETS); } } cout << "Fifo structure(s) reconstructed" << endl; @@ -1683,7 +1690,8 @@ int UDPStandardImplementation::startListening(){ if(tempchar) {delete [] tempchar;tempchar = NULL;} if(myDetectorType != EIGER) tempchar = new char[onePacketSize * ((packetsPerFrame/numListeningThreads) - 1)]; //gotthard: 1packet size, moench:39 packet size - + else + maxBufferSize = 0; @@ -1747,7 +1755,7 @@ int UDPStandardImplementation::startListening(){ //start indices for each start of scan/acquisition if((!measurementStarted) && (rc > 0)){ pthread_mutex_lock(&progress_mutex); - startFrameIndices(ithread); + startFrameIndices(ithread, rc); pthread_mutex_unlock(&progress_mutex); } @@ -1825,6 +1833,7 @@ int UDPStandardImplementation::startListening(){ case EIGER: //because even headers might be included, so not packet count (*((uint32_t*)(buffer[ithread]))) = rc; + packetcount = 1; break; default: @@ -1890,16 +1899,16 @@ int UDPStandardImplementation::startWriting(){ thread_started = 1; int totalheader = HEADER_SIZE_NUM_TOT_PACKETS + EIGER_HEADER_LENGTH; - int numpackets[numListeningThreads], popready[numListeningThreads], woffset[numListeningThreads], nf; - bool endofacquisition, startheader[numListeningThreads]; + int numpackets[numListeningThreads], popready[numListeningThreads], nf; + bool startdatapacket[numListeningThreads],fullframe[numListeningThreads]; uint32_t tempframenum[numListeningThreads]; uint32_t lastpacketheader[numListeningThreads], currentpacketheader[numListeningThreads]; int numberofmissingpackets[numListeningThreads]; - char* tempbuffer[numListeningThreads] = NULL; + char* tempbuffer = NULL; int tempoffset[numListeningThreads]; int LAST_PACKET_VALUE; - bool fullframe; + char* wbuf[numListeningThreads];//interleaved @@ -1930,31 +1939,33 @@ int UDPStandardImplementation::startWriting(){ //allow them all to be popped initially for(i=0;ipop(wbuf[i]); #ifdef FIFO_DEBUG @@ -1977,27 +1985,18 @@ int UDPStandardImplementation::startWriting(){ #endif numpackets[i] = (uint32_t)(*((uint32_t*)wbuf[i])); #ifdef VERYDEBUG - cout << i << " numpackets:" << dec << numpackets[i] << "for fifo :"<< i << endl; + cprintf(GREEN,"%d numpackets: %d for fifo :%d\n", ithread, numpackets[i], i); #endif - //dont pop until ready - popready[i] = 0; - //reset offset - woffset[i] = 0; + //dont pop again if dummy packet + if(!numpackets[i]) + popready[i] = 0; } } - //check for end of acquisition - endofacquisition = true; - for(i=0;i= numpackets[i]){ - popready[i] = 1; - fullframe = false; - break; - } + //header packet + if( 0x01 == (*(uint8_t*)(((eiger_image_header *)((char*)(wbuf[i])))->header_confirm))){ - //check if header - if( 0x01 == (*(uint16_t*)(((eiger_image_header *)((char*)(wbuf[i] + woffset[i])))->header_confirm))){ - //expected frame header -eiger frame numbers start at 1, so need to -1 - if(tempframenum[i] == (htonl(*(unsigned int*)((eiger_image_header *)((char*)(wbuf[ithread] + woffset[i])))->fnum)+(startFrameIndex-1))){ - woffset[i] += EIGER_HEADER_LENGTH; - startheader[i] = true; - numberofmissingpackets[i] = 0; - lastpacketheader[i] = -1; - tempoffset[i] = 0; - } - //wrong header - leave - else{ - numberofmissingpackets[i] += (LAST_PACKET_VALUE - lastpacketheader[i]); - tempframenum[i]++; - //add missing packets - for(j=0;jfnum)+(startFrameIndex-1); + //next frame, leave else{ - //update current packet - currentpacketheader[i] = ((*(uint8_t*)(((eiger_packet_header *)((char*)(wbuf[i] + woffset[i])))->num4))); - //last packet - leave - if(currentpacketheader[i] == LAST_PACKET_VALUE){ - //fill buffer - tempbuffer[i][tempoffset[i]] = wbuf[i] + woffset[i]; - woffset[i] += onePacketSize; - //reset - startheader[i] = false; - lastpacketheader[i] = -1; - tempoffset[i] = 0; - break; - } - //same frame packet - if(currentpacketheader[i] > lastpacketheader[i]){ - - if(!startheader[i]){ - tempframenum[i]++; - } - else - startheader[i] = false; - lastpacketheader[i] = -1; - numberofmissingpackets[i] = 0; - numberofmissingpackets[i] += (currentpacketheader[i] - lastpacketheader[i] -1); - //add missing packets - for(j=0;jnum4))); + //same frame packet - continue building frame + if(currentpacketheader[i] > lastpacketheader[i]){ + //add missing packets + numberofmissingpackets[i] += (currentpacketheader[i] - lastpacketheader[i] -1); + for(j=0;jnum1)) = currframenum; - //overwriting port number and dynamic range - if (!j) (*(uint8_t*)(((eiger_packet_header *)((char*)(tempoffset[j] + onePacketSize*i)))->num3)) = (dynamicRange<<2); - else (*(uint8_t*)(((eiger_packet_header *)((char*)(tempoffset[j] + onePacketSize*i)))->num3)) = ((dynamicRange<<2)|(0x1)); - - #ifdef VERYDEBUG - cprintf(GREEN, "%d - 0x%x - %d\n", i, - (*(uint8_t*)(((eiger_packet_header *)((char*)(tempoffset[j] + i*onePacketSize)))->num3)), - (*(uint8_t*)(((eiger_packet_header *)((char*)(tempoffset[j] + i*onePacketSize)))->num4))); - #endif - - } - - //for 32 bit,port number needs to be changed and packet number reconstructed - if(dynamicRange == 32){ - for (i = 0; i < packetsPerFrame/4; i++){ - //new packet number that has space for 16 bit - (*(uint16_t*)(((eiger_packet_header *)((char*)(tempoffset[j] + onePacketSize*i)))->num2)) - = ((*(uint8_t*)(((eiger_packet_header *)((char*)(tempoffset[j] + onePacketSize*i)))->num4))); - - #ifdef VERYDEBUG - cprintf(GREEN, "%d - 0x%x - %d - %d\n", i, - (*(uint8_t*)(((eiger_packet_header *)((char*)(tempoffset[j] + i*onePacketSize)))->num3)), - (*(uint8_t*)(((eiger_packet_header *)((char*)(tempoffset[j] + i*onePacketSize)))->num4)), - (*(uint16_t*)(((eiger_packet_header *)((char*)(tempoffset[j] + i*onePacketSize)))->num2))); - #endif - } - for (i = packetsPerFrame/4; i < packetsPerFrame/2; i++){ - //new packet number that has space for 16 bit - (*(uint16_t*)(((eiger_packet_header *)((char*)(tempoffset[j] + onePacketSize*i)))->num2)) - = ((*(uint8_t*)(((eiger_packet_header *)((char*)(tempoffset[j] + onePacketSize*i)))->num4))+(packetsPerFrame/4)); - - #ifdef VERYDEBUG - cprintf(GREEN, "%d -0x%x - %d - %d\n", i, - (*(uint8_t*)(((eiger_packet_header *)((char*)(tempoffset[j] + i*onePacketSize)))->num3)), - (*(uint8_t*)(((eiger_packet_header *)((char*)(tempoffset[j] + i*onePacketSize)))->num4)), - (*(uint16_t*)(((eiger_packet_header *)((char*)(tempoffset[j] + i*onePacketSize)))->num2))); - #endif + //next frame packet - leave + else{ + //add missing packets + numberofmissingpackets += (LAST_PACKET_VALUE = lastpacketheader[i]); + for(j=0;jpush(tempoffset[i])); - #ifdef FIFO_DEBUG - cprintf(GREEN,"%d writer freed pushed into fifofree %x for listener %d\n",ithread, (void*)(tempoffset[i]),i); - #endif - } + //check if a full frame received + if(fullframe[0] && fullframe[1]){ + for(int i=0;ifnum); + //check if its a header + if(EIGER_HEADER_LENGTH == numbytes) + startFrameIndex = (htonl(*(unsigned int*)((eiger_image_header *)((char*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS)))->fnum))-1; + //missed header packet, so default value + else + startFrameIndex = 0; } //gotthard has +1 for frame number and not a short frame else if ((myDetectorType == GOTTHARD) && (shortFrame == -1)) @@ -2321,13 +2229,13 @@ void UDPStandardImplementation::startFrameIndices(int ithread){ //start of acquisition if(!acqStarted){ startAcquisitionIndex=startFrameIndex; - currframenum = startAcquisitionIndex; + //currframenum = startAcquisitionIndex; acqStarted = true; cprintf(BLUE,"%d startAcquisitionIndex:%d\n", ithread, startAcquisitionIndex); } //for scans, cuz currfraenum resets else if (myDetectorType == EIGER){ - startFrameIndex += currframenum; + startFrameIndex += (currframenum+1); } @@ -2369,12 +2277,18 @@ void UDPStandardImplementation::stopListening(int ithread, int rc, int &pc, int //push the last buffer into fifo else{ - pc = (rc/onePacketSize); + if(myDetectorType == EIGER){ + (*((uint32_t*)(buffer[ithread]))) = rc; + pc = 1; + }else{ + pc = (rc/onePacketSize); + (*((uint32_t*)(buffer[ithread]))) = pc; + } #ifdef VERYDEBUG cprintf(BLUE,"%d last rc:%d\n",ithread, rc); cprintf(BLUE,"%d last packetcount:%d\n", ithread, pc); #endif - (*((uint32_t*)(buffer[ithread]))) = pc; + totalListeningFrameCount[ithread] += pc; while(!fifo[ithread]->push(buffer[ithread])); #ifdef FIFO_DEBUG From fa156f337ec3b51c9c4d78d03bc4359e2dca228e Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 28 Jul 2015 18:15:09 +0200 Subject: [PATCH 109/474] sorta done without missing packet identifiers --- .../include/UDPBaseImplementation.h | 3 + .../include/UDPStandardImplementation.h | 4 +- .../include/sls_receiver_defs.h | 4 +- .../src/UDPStandardImplementation.cpp | 263 ++++++++++-------- 4 files changed, 154 insertions(+), 120 deletions(-) diff --git a/slsReceiverSoftware/include/UDPBaseImplementation.h b/slsReceiverSoftware/include/UDPBaseImplementation.h index 8db022a69..1e1c7bdf9 100644 --- a/slsReceiverSoftware/include/UDPBaseImplementation.h +++ b/slsReceiverSoftware/include/UDPBaseImplementation.h @@ -575,6 +575,9 @@ protected: /** Pckets currently in current file, starts new file when it reaches max */ int packetsInFile; + /** Number of missing packets in file (sometimes packetsinFile is incorrect due to padded packets for eiger)*/ + int numTotMissingPacketsInFile; + /** Frame index at start of an entire acquisition (including all scans) */ uint32_t startAcquisitionIndex; diff --git a/slsReceiverSoftware/include/UDPStandardImplementation.h b/slsReceiverSoftware/include/UDPStandardImplementation.h index 3462ded22..40c3ab54c 100644 --- a/slsReceiverSoftware/include/UDPStandardImplementation.h +++ b/slsReceiverSoftware/include/UDPStandardImplementation.h @@ -461,7 +461,7 @@ private: * When acquisition is over, this is called * @param ithread listening thread number */ - void stopWriting(int ithread); + void stopWriting(int ithread, char* wbuffer[]); /** * updates parameters and writes to file when not a dummy frame @@ -470,7 +470,7 @@ private: * @param ithread writing thread number * @param wbuffer writer buffer */ - void handleWithoutDataCompression(int ithread, char* wbuffer[]); + void handleWithoutDataCompression(int ithread, char* wbuffer); /** * data compression for each fifo output diff --git a/slsReceiverSoftware/include/sls_receiver_defs.h b/slsReceiverSoftware/include/sls_receiver_defs.h index 7ed6e0837..a9f6d30c2 100755 --- a/slsReceiverSoftware/include/sls_receiver_defs.h +++ b/slsReceiverSoftware/include/sls_receiver_defs.h @@ -19,8 +19,8 @@ typedef int int32_t; #define MAX_FRAMES_PER_FILE 20000 #define SHORT_MAX_FRAMES_PER_FILE 100000 #define MOENCH_MAX_FRAMES_PER_FILE 1000 -#define EIGER_MAX_FRAMES_PER_FILE 20 -#define JFCTB_MAX_FRAMES_PER_FILE 100000 +#define EIGER_MAX_FRAMES_PER_FILE 2000 +#define JFCTB_MAX_FRAMES_PER_FILE 100000 /** diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index ed0df1b47..48d53098e 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -122,6 +122,7 @@ void UDPStandardImplementation::initializeMembers(){ packetsCaught = 0; totalPacketsCaught = 0; packetsInFile = 0; + numTotMissingPacketsInFile = 0; startAcquisitionIndex = 0; acquisitionIndex = 0; packetsPerFrame = 0; @@ -1260,6 +1261,7 @@ int UDPStandardImplementation::setupWriter(){ //reset writing thread variables packetsInFile=0; + numTotMissingPacketsInFile = 0; packetsCaught=0; frameIndex=0; if(sfilefd) sfilefd=NULL; @@ -1377,6 +1379,8 @@ int UDPStandardImplementation::createNewFile(){ //create file name if(frameIndexNeeded==-1) sprintf(savefilename, "%s/%s_%d.raw", filePath,fileName,fileIndex); + else if (myDetectorType == EIGER) + sprintf(savefilename, "%s/%s_f%012d_%d.raw", filePath,fileName,currframenum,fileIndex); else sprintf(savefilename, "%s/%s_f%012d_%d.raw", filePath,fileName,(packetsCaught/packetsPerFrame),fileIndex); @@ -1411,11 +1415,11 @@ int UDPStandardImplementation::createNewFile(){ cout << savefilename << "\tpacket loss " << setw(4)<header_confirm))){ + if( 0x01 == (*(uint8_t*)(((eiger_image_header *)((char*)(wbuf[i] + HEADER_SIZE_NUM_TOT_PACKETS)))->header_confirm))){ //new frame (no datapacket received yet), update frame num and corrected for fnum reset for scans if(!startdatapacket[i]) - tempframenum[i] = htonl(*(unsigned int*)((eiger_image_header *)((char*)(wbuf[ithread] + woffset[i])))->fnum)+(startFrameIndex-1); + tempframenum[i] = htonl(*(unsigned int*)((eiger_image_header *)((char*)(wbuf[ithread] + HEADER_SIZE_NUM_TOT_PACKETS)))->fnum)+(startFrameIndex-1); //next frame, leave else{ //add missing packets - numberofmissingpackets += (LAST_PACKET_VALUE = lastpacketheader[i]); + numberofmissingpackets[i] = (LAST_PACKET_VALUE - lastpacketheader[i]); + //to decrement from packetsInFile to calculate packet loss + numTotMissingPacketsInFile += numberofmissingpackets[i]; for(j=0;jnum4))); + currentpacketheader[i] = ((*(uint8_t*)(((eiger_packet_header *)((char*)(wbuf[i] + HEADER_SIZE_NUM_TOT_PACKETS)))->num4))); //same frame packet - continue building frame if(currentpacketheader[i] > lastpacketheader[i]){ //add missing packets - numberofmissingpackets[i] += (currentpacketheader[i] - lastpacketheader[i] -1); + numberofmissingpackets[i] = (currentpacketheader[i] - lastpacketheader[i] -1); + //to decrement from packetsInFile to calculate packet loss + numTotMissingPacketsInFile += numberofmissingpackets[i]; for(j=0;jpush(wbuffer[i])); + if(myDetectorType == EIGER) { + //push every packet + for(j=0;jpush(wbuffer[i]+j*onePacketSize)); #ifdef FIFO_DEBUG - cprintf(GREEN,"%d writer free dummy pushed into fifofree %x for listener %d\n", ithread,(void*)(wbuffer[i]),i); + cprintf(GREEN,"%d writer freed pushed into fifofree %x for listener %d\n",ithread, (void*)(wbuffer[i]+j*onePacketSize)); #endif + } + }else{ + while(!fifoFree[i]->push(wbuffer[i])); +#ifdef FIFO_DEBUG + cprintf(GREEN,"%d writer free dummy pushed into fifofree %x for listener %d\n", ithread,(void*)(wbuffer[i]),i); +#endif + } } @@ -2444,7 +2490,6 @@ void UDPStandardImplementation::writeToFile_withoutCompression(char* buf,int num offset = HEADER_SIZE_NUM_TOT_PACKETS; if(myDetectorType == EIGER){ - offset += EIGER_HEADER_LENGTH; #ifdef WRITE_HEADERS #ifdef VERY_DEBUG if(myDetectorType == EIGER){ @@ -2531,7 +2576,7 @@ void UDPStandardImplementation::writeToFile_withoutCompression(char* buf,int num if(packetsInFile >= maxPacketsPerFile){ //for packet loss lastpacket = (((packetsToSave - 1) * onePacketSize) + offset); - if(myDetectorType == EIGER); + if(myDetectorType == EIGER);//because currframenum is the latest one for eiger else if ((myDetectorType == GOTTHARD) && (shortFrame == -1)) tempframenum = (((((uint32_t)(*((uint32_t*)(buf + lastpacket))))+1)& (frameIndexMask)) >> frameIndexOffset); else @@ -2578,79 +2623,67 @@ void UDPStandardImplementation::writeToFile_withoutCompression(char* buf,int num -void UDPStandardImplementation::handleWithoutDataCompression(int ithread, char* wbuffer[]){ - int totalheader = HEADER_SIZE_NUM_TOT_PACKETS + EIGER_HEADER_LENGTH; - int i,j,npackets, ntotpackets=0; +void UDPStandardImplementation::handleWithoutDataCompression(int ithread, char* wbuffer){ + int i,npackets; if (cbAction < DO_EVERYTHING){ - for(i=0;i 0){ + npackets = (uint32_t)(*((uint32_t*)wbuffer)); + if (npackets > 0){ #ifdef WRITE_HEADERS - if (myDetectorType == EIGER){ + if (myDetectorType == EIGER){ - for (i = 0; i < packetsPerFrame/2; i++){ - //overwriting frame number in header - (*(uint32_t*)(((eiger_packet_header *)((char*)(wbuffer[j] + totalheader + onePacketSize*i)))->num1)) = currframenum; - //overwriting port number and dynamic range - if (!j) (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[j] + totalheader + onePacketSize*i)))->num3)) = (dynamicRange<<2); - else (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[j] + totalheader + onePacketSize*i)))->num3)) = ((dynamicRange<<2)|(0x1)); + for (i = 0; i < packetsPerFrame; i++){ + //overwriting frame number in header + (*(uint32_t*)(((eiger_packet_header *)((char*)(wbuffer + HEADER_SIZE_NUM_TOT_PACKETS + onePacketSize*i)))->num1)) = currframenum; + //overwriting port number and dynamic range + if (i<(packetsPerFrame/2)) + (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer + HEADER_SIZE_NUM_TOT_PACKETS + onePacketSize*i)))->num3)) = (dynamicRange<<2); + else + (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer + HEADER_SIZE_NUM_TOT_PACKETS + onePacketSize*i)))->num3)) = ((dynamicRange<<2)|(0x1)); #ifdef VERYDEBUG - cprintf(GREEN, "%d - 0x%x - %d\n", i, - (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[j] + totalheader +i*onePacketSize)))->num3)), - (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[j] + totalheader +i*onePacketSize)))->num4))); + cprintf(GREEN, "%d - 0x%x - %d\n", i, + (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer + HEADER_SIZE_NUM_TOT_PACKETS +i*onePacketSize)))->num3)), + (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer + HEADER_SIZE_NUM_TOT_PACKETS +i*onePacketSize)))->num4))); #endif - } + } - //for 32 bit,port number needs to be changed and packet number reconstructed - if(dynamicRange == 32){ - for (i = 0; i < packetsPerFrame/4; i++){ + //for 32 bit,port number needs to be changed and packet number reconstructed + if(dynamicRange == 32){ + for (i = 0; i < packetsPerFrame; i++){ + if( (i < (packetsPerFrame/4)) || ((i > (packetsPerFrame/2)) && (i < (3*packetsPerFrame/4))) ){ //new packet number that has space for 16 bit - (*(uint16_t*)(((eiger_packet_header *)((char*)(wbuffer[j] + totalheader + onePacketSize*i)))->num2)) - = ((*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[j] + totalheader + onePacketSize*i)))->num4))); - -#ifdef VERYDEBUG - cprintf(GREEN, "%d - 0x%x - %d - %d\n", i, - (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[j] + totalheader +i*onePacketSize)))->num3)), - (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[j] + totalheader +i*onePacketSize)))->num4)), - (*(uint16_t*)(((eiger_packet_header *)((char*)(wbuffer[j] + totalheader +i*onePacketSize)))->num2))); -#endif - } - for (i = packetsPerFrame/4; i < packetsPerFrame/2; i++){ + (*(uint16_t*)(((eiger_packet_header *)((char*)(wbuffer + HEADER_SIZE_NUM_TOT_PACKETS + onePacketSize*i)))->num2)) + = ((*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer + HEADER_SIZE_NUM_TOT_PACKETS + onePacketSize*i)))->num4))); + }else{ //new packet number that has space for 16 bit - (*(uint16_t*)(((eiger_packet_header *)((char*)(wbuffer[j] + totalheader + onePacketSize*i)))->num2)) - = ((*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[j] + totalheader + onePacketSize*i)))->num4))+(packetsPerFrame/4)); + (*(uint16_t*)(((eiger_packet_header *)((char*)(wbuffer + HEADER_SIZE_NUM_TOT_PACKETS + onePacketSize*i)))->num2)) + = ((*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer + HEADER_SIZE_NUM_TOT_PACKETS + onePacketSize*i)))->num4))+(packetsPerFrame/4)); -#ifdef VERYDEBUG - cprintf(GREEN, "%d -0x%x - %d - %d\n", i, - (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[j] + totalheader +i*onePacketSize)))->num3)), - (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[j] + totalheader +i*onePacketSize)))->num4)), - (*(uint16_t*)(((eiger_packet_header *)((char*)(wbuffer[j] + totalheader +i*onePacketSize)))->num2))); -#endif } +#ifdef VERYDEBUG + cprintf(GREEN, "%d - 0x%x - %d - %d\n", i, + (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer + HEADER_SIZE_NUM_TOT_PACKETS +i*onePacketSize)))->num3)), + (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer + HEADER_SIZE_NUM_TOT_PACKETS +i*onePacketSize)))->num4)), + (*(uint16_t*)(((eiger_packet_header *)((char*)(wbuffer + HEADER_SIZE_NUM_TOT_PACKETS +i*onePacketSize)))->num2))); +#endif + } } + } #endif - writeToFile_withoutCompression(wbuffer[j], npackets,currframenum); - } + writeToFile_withoutCompression(wbuffer, npackets,currframenum); } + #ifdef VERYDEBUG cprintf(GREEN,"written everyting\n"); #endif @@ -2658,25 +2691,23 @@ void UDPStandardImplementation::handleWithoutDataCompression(int ithread, char* if(myDetectorType == EIGER) { - if(ntotpackets >= packetsPerFrame ) { + #ifdef VERYDEBUG - cprintf(GREEN,"gonna copy frame\n"); + cprintf(GREEN,"gonna copy frame\n"); #endif - copyFrameToGui(wbuffer,currframenum); -//#ifdef VERYDEBUG - cprintf(GREEN,"copied frame\n"); -//#endif - } - for(i=0;ipush(wbuffer[i])); + copyFrameToGui(wbuffer,currframenum); + //#ifdef VERYDEBUG + cprintf(GREEN,"copied frame\n"); + //#endif + + for(i=0;inum3)) != 0xFF) + while(!fifoFree[i]->push(wbuffer+i*onePacketSize)); #ifdef FIFO_DEBUG - cprintf(GREEN,"%d writer freed pushed into fifofree %x for listener %d\n",ithread, (void*)(wbuffer[i]),i); + cprintf(GREEN,"%d writer freed pushed into fifofree %x for listener %d\n",ithread, (void*)(wbuffer+i*onePacketSize)); #endif } - - } else{ //copy to gui From d49da66daefca78bcfc6459b335abfc0a22138d3 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Thu, 30 Jul 2015 10:42:10 +0200 Subject: [PATCH 110/474] almost done with changes --- .../include/UDPStandardImplementation.h | 5 +- .../src/UDPStandardImplementation.cpp | 278 +++++++++--------- 2 files changed, 148 insertions(+), 135 deletions(-) diff --git a/slsReceiverSoftware/include/UDPStandardImplementation.h b/slsReceiverSoftware/include/UDPStandardImplementation.h index 40c3ab54c..67443f21c 100644 --- a/slsReceiverSoftware/include/UDPStandardImplementation.h +++ b/slsReceiverSoftware/include/UDPStandardImplementation.h @@ -436,7 +436,7 @@ private: * @param numpackets is the number of packets * @param framenum current frame number */ - void writeToFile_withoutCompression(char* buf,int numpackets, uint32_t framenum); + void writeToFile_withoutCompression(char* buf[],int numpackets, uint32_t framenum); /** * Its called for the first packet of a scan or acquistion @@ -469,8 +469,9 @@ private: * Called by startWriting() * @param ithread writing thread number * @param wbuffer writer buffer + * @param npackets number of packets */ - void handleWithoutDataCompression(int ithread, char* wbuffer); + void handleWithoutDataCompression(int ithread, char* wbuffer[],int npackets); /** * data compression for each fifo output diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 3f18ddea9..8e8c930b6 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -992,12 +992,8 @@ cout << "copyframe" << endl; #endif //eiger if(startbuf != NULL){ - int offset = 0; - int size = frameSize/EIGER_MAX_PORTS; - for(int j=0;jpop(wbuf[i]); #ifdef FIFO_DEBUG - cprintf(MAGENTA,"%d writer poped from fifo %x\n", ithread, (void*)(wbuf[i])); + cprintf(GREEN,"%d writer poped from fifo %x\n", ithread, (void*)(wbuf[i])); #endif numpackets[i] = (uint32_t)(*((uint32_t*)wbuf[i])); #ifdef VERYDEBUG @@ -2070,18 +2071,23 @@ int UDPStandardImplementation::startWriting(){ if( 0x01 == (*(uint8_t*)(((eiger_image_header *)((char*)(wbuf[i] + HEADER_SIZE_NUM_TOT_PACKETS)))->header_confirm))){ //new frame (no datapacket received yet), update frame num and corrected for fnum reset for scans - if(!startdatapacket[i]) + if(!startdatapacket[i]){ + tempframenum[i] = htonl(*(unsigned int*)((eiger_image_header *)((char*)(wbuf[ithread] + HEADER_SIZE_NUM_TOT_PACKETS)))->fnum)+(startFrameIndex-1); - //next frame, leave +//#ifdef VERYVERBOSE + cprintf(GREEN,"**tempfraemnum of %d: %d\n",i,tempframenum[i]); +//#endif + }//next frame, leave else{ + cprintf(RED,"**missing packets and got header\n"); //add missing packets numberofmissingpackets[i] = (LAST_PACKET_VALUE - lastpacketheader[i]); //to decrement from packetsInFile to calculate packet loss numTotMissingPacketsInFile += numberofmissingpackets[i]; for(j=0;jnum4))); +#ifdef VERYVERBOSE + cprintf(GREEN,"** got current packet header of %d: %d lastpacketheader %d\n",i,currentpacketheader[i],lastpacketheader[i]); +#endif //same frame packet - continue building frame if(currentpacketheader[i] > lastpacketheader[i]){ //add missing packets @@ -2100,30 +2109,31 @@ int UDPStandardImplementation::startWriting(){ numTotMissingPacketsInFile += numberofmissingpackets[i]; for(j=0;jpush(buffer[ithread])); #ifdef FIFO_DEBUG cprintf(BLUE,"%d listener empty buffer pushed into fifofree %x\n", ithread, (void*)(buffer[ithread])); @@ -2415,27 +2429,15 @@ void UDPStandardImplementation::stopListening(int ithread, int rc, int &pc, int void UDPStandardImplementation::stopWriting(int ithread, char* wbuffer[]){ FILE_LOG(logDEBUG) << __AT__ << " called"; - int i,j; -#ifdef VERBOSE - cprintf(GREEN,"%d End of Acquisition\n",ithread); -#endif + cprintf(GREEN,"%d End of Acquisition for Writing Thread\n",ithread); + int i,j; //free fifo for(i=0;ipush(wbuffer[i]+j*onePacketSize)); + while(!fifoFree[i]->push(wbuffer[i])); #ifdef FIFO_DEBUG - cprintf(GREEN,"%d writer freed pushed into fifofree %x for listener %d\n",ithread, (void*)(wbuffer[i]+j*onePacketSize)); + cprintf(GREEN,"%d writer free dummy pushed into fifofree %x for listener %d\n", ithread,(void*)(wbuffer[i]),i); #endif - } - }else{ - while(!fifoFree[i]->push(wbuffer[i])); -#ifdef FIFO_DEBUG - cprintf(GREEN,"%d writer free dummy pushed into fifofree %x for listener %d\n", ithread,(void*)(wbuffer[i]),i); -#endif - } } @@ -2497,10 +2499,10 @@ void UDPStandardImplementation::stopWriting(int ithread, char* wbuffer[]){ -void UDPStandardImplementation::writeToFile_withoutCompression(char* buf,int numpackets, uint32_t framenum){ +void UDPStandardImplementation::writeToFile_withoutCompression(char* buf[],int numpackets, uint32_t framenum){ FILE_LOG(logDEBUG) << __AT__ << " called"; - int packetsToSave, offset,lastpacket; + int packetsToSave, offset,lastpacket,i; uint32_t tempframenum = framenum; //file write @@ -2513,42 +2515,42 @@ void UDPStandardImplementation::writeToFile_withoutCompression(char* buf,int num if(myDetectorType == EIGER){ int k = 0; if(dynamicRange != 32){ - cprintf(RED, "\np1 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf + offset+k*1040)))->num1))); - cprintf(RED, "p1:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset+k*1040)))->num3))); - cprintf(RED, "p0 num:%d - %d\n", k, (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset+k*1040)))->num4))); + cprintf(RED, "\np1 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf[k])))->num1))); + cprintf(RED, "p1:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf[k])))->num3))); + cprintf(RED, "p0 num:%d - %d\n", k, (*(uint8_t*)(((eiger_packet_header *)((char*)(buf[k])))->num4))); k = 1; - cprintf(RED, "p2 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num1))); - cprintf(RED, "p2:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num3))); - cprintf(RED, "p1 num:%d - %d\n", k,(*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num4))); + cprintf(RED, "p2 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf[k])))->num1))); + cprintf(RED, "p2:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf[k])))->num3))); + cprintf(RED, "p1 num:%d - %d\n", k,(*(uint8_t*)(((eiger_packet_header *)((char*)(buf[k])))->num4))); k = 2; - cprintf(RED, "p3 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf + offset + k*1040)))->num1))); - cprintf(RED, "p3:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num3))); - cprintf(RED, "p2 num:%d - %d\n", k,(*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num4))); + cprintf(RED, "p3 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf[k])))->num1))); + cprintf(RED, "p3:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf[k])))->num3))); + cprintf(RED, "p2 num:%d - %d\n", k,(*(uint8_t*)(((eiger_packet_header *)((char*)(buf[k])))->num4))); }else{ k = 0; - cprintf(RED, "\np1 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf + offset+k*1040)))->num1))); - cprintf(RED, "p1:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset+k*1040)))->num3))); - cprintf(RED, "p0 num:%d - %d\n", k, (*(uint16_t*)(((eiger_packet_header *)((char*)(buf + offset+k*1040)))->num2))); + cprintf(RED, "\np1 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf[k])))->num1))); + cprintf(RED, "p1:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf[k])))->num3))); + cprintf(RED, "p0 num:%d - %d\n", k, (*(uint16_t*)(((eiger_packet_header *)((char*)(buf[k])))->num2))); k = 1; - cprintf(RED, "p2 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num1))); - cprintf(RED, "p2:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num3))); - cprintf(RED, "p1 num:%d - %d\n", k, (*(uint16_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num2))); + cprintf(RED, "p2 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf[k])))->num1))); + cprintf(RED, "p2:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf[k])))->num3))); + cprintf(RED, "p1 num:%d - %d\n", k, (*(uint16_t*)(((eiger_packet_header *)((char*)(buf[k])))->num2))); k = 2; - cprintf(RED, "p3 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf + offset + k*1040)))->num1))); - cprintf(RED, "p3:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num3))); - cprintf(RED, "p2 num:%d - %d\n", k, (*(uint16_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num2))); + cprintf(RED, "p3 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf[k])))->num1))); + cprintf(RED, "p3:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf[k])))->num3))); + cprintf(RED, "p2 num:%d - %d\n", k, (*(uint16_t*)(((eiger_packet_header *)((char*)(buf[k])))->num2))); k = 256; - cprintf(RED, "p257 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf + offset + k*1040)))->num1))); - cprintf(RED, "p257:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num3))); - cprintf(RED, "p256 num:%d - %d\n", k, (*(uint16_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num2))); + cprintf(RED, "p257 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf[k])))->num1))); + cprintf(RED, "p257:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf[k])))->num3))); + cprintf(RED, "p256 num:%d - %d\n", k, (*(uint16_t*)(((eiger_packet_header *)((char*)(buf[k])))->num2))); k = 512; - cprintf(RED, "p513 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf + offset + k*1040)))->num1))); - cprintf(RED, "p513:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num3))); - cprintf(RED, "p512 num:%d - %d\n", k, (*(uint16_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num2))); + cprintf(RED, "p513 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf[k])))->num1))); + cprintf(RED, "p513:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf[k])))->num3))); + cprintf(RED, "p512 num:%d - %d\n", k, (*(uint16_t*)(((eiger_packet_header *)((char*)(buf[k])))->num2))); k = 768; - cprintf(RED, "p769 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf + offset + k*1040)))->num1))); - cprintf(RED, "p769:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num3))); - cprintf(RED, "p768 num:%d - %d\n", k,(*(uint16_t*)(((eiger_packet_header *)((char*)(buf + offset +k*1040)))->num2))); + cprintf(RED, "p769 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf[k])))->num1))); + cprintf(RED, "p769:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf[k])))->num3))); + cprintf(RED, "p768 num:%d - %d\n", k,(*(uint16_t*)(((eiger_packet_header *)((char*)(buf[k])))->num2))); } } #endif @@ -2559,9 +2561,9 @@ void UDPStandardImplementation::writeToFile_withoutCompression(char* buf,int num //for progress and packet loss calculation(new files) if(myDetectorType == EIGER); else if ((myDetectorType == PROPIX)||((myDetectorType == GOTTHARD) && (shortFrame == -1))) - tempframenum = (((((uint32_t)(*((uint32_t*)(buf + HEADER_SIZE_NUM_TOT_PACKETS))))+1)& (frameIndexMask)) >> frameIndexOffset); + tempframenum = (((((uint32_t)(*((uint32_t*)(buf[0] + HEADER_SIZE_NUM_TOT_PACKETS))))+1)& (frameIndexMask)) >> frameIndexOffset); else - tempframenum = ((((uint32_t)(*((uint32_t*)(buf + HEADER_SIZE_NUM_TOT_PACKETS))))& (frameIndexMask)) >> frameIndexOffset); + tempframenum = ((((uint32_t)(*((uint32_t*)(buf[0] + HEADER_SIZE_NUM_TOT_PACKETS))))& (frameIndexMask)) >> frameIndexOffset); if(numWriterThreads == 1) currframenum = tempframenum; @@ -2583,7 +2585,12 @@ void UDPStandardImplementation::writeToFile_withoutCompression(char* buf,int num if(packetsToSave > numpackets) packetsToSave = numpackets; /**next time offset is still plus header length*/ - fwrite(buf+offset, 1, packetsToSave * onePacketSize, sfilefd); + if(myDetectorType == EIGER) + for(i=0;i= maxPacketsPerFile){ - //for packet loss - lastpacket = (((packetsToSave - 1) * onePacketSize) + offset); - if(myDetectorType == EIGER);//because currframenum is the latest one for eiger - else if ((myDetectorType == PROPIX)||((myDetectorType == GOTTHARD) && (shortFrame == -1))) + //for packet loss, because currframenum is the latest one for eiger + if(myDetectorType != EIGER){ + lastpacket = (((packetsToSave - 1) * onePacketSize) + offset); - tempframenum = (((((uint32_t)(*((uint32_t*)(buf + lastpacket))))+1)& (frameIndexMask)) >> frameIndexOffset); - else - tempframenum = ((((uint32_t)(*((uint32_t*)(buf + lastpacket))))& (frameIndexMask)) >> frameIndexOffset); + if ((myDetectorType == PROPIX)||((myDetectorType == GOTTHARD) && (shortFrame == -1))) + tempframenum = (((((uint32_t)(*((uint32_t*)(buf[0] + lastpacket))))+1)& (frameIndexMask)) >> frameIndexOffset); + else + tempframenum = ((((uint32_t)(*((uint32_t*)(buf[0] + lastpacket))))& (frameIndexMask)) >> frameIndexOffset); + } if(numWriterThreads == 1) currframenum = tempframenum; else{ @@ -2619,8 +2627,8 @@ void UDPStandardImplementation::writeToFile_withoutCompression(char* buf,int num if(numWriterThreads > 1) pthread_mutex_unlock(&write_mutex); - - offset += (packetsToSave * onePacketSize); + if(myDetectorType != EIGER) + offset += (packetsToSave * onePacketSize); numpackets -= packetsToSave; } @@ -2643,17 +2651,19 @@ void UDPStandardImplementation::writeToFile_withoutCompression(char* buf,int num -void UDPStandardImplementation::handleWithoutDataCompression(int ithread, char* wbuffer){ - int i,npackets; +void UDPStandardImplementation::handleWithoutDataCompression(int ithread, char* wbuffer[],int npackets){ + int i,j; if (cbAction < DO_EVERYTHING){ - npackets = (uint32_t)(*((uint32_t*)wbuffer)); - rawDataReadyCallBack(currframenum, wbuffer + HEADER_SIZE_NUM_TOT_PACKETS, npackets * onePacketSize, sfilefd, guiData,pRawDataReady); + if (myDetectorType == EIGER){ + for(i=0;i 0){ #ifdef WRITE_HEADERS @@ -2661,17 +2671,17 @@ void UDPStandardImplementation::handleWithoutDataCompression(int ithread, char* for (i = 0; i < packetsPerFrame; i++){ //overwriting frame number in header - (*(uint32_t*)(((eiger_packet_header *)((char*)(wbuffer + HEADER_SIZE_NUM_TOT_PACKETS + onePacketSize*i)))->num1)) = currframenum; + (*(uint32_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num1)) = currframenum; //overwriting port number and dynamic range if (i<(packetsPerFrame/2)) - (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer + HEADER_SIZE_NUM_TOT_PACKETS + onePacketSize*i)))->num3)) = (dynamicRange<<2); + (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num3)) = (dynamicRange<<2); else - (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer + HEADER_SIZE_NUM_TOT_PACKETS + onePacketSize*i)))->num3)) = ((dynamicRange<<2)|(0x1)); + (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num3)) = ((dynamicRange<<2)|(0x1)); #ifdef VERYDEBUG cprintf(GREEN, "%d - 0x%x - %d\n", i, - (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer + HEADER_SIZE_NUM_TOT_PACKETS +i*onePacketSize)))->num3)), - (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer + HEADER_SIZE_NUM_TOT_PACKETS +i*onePacketSize)))->num4))); + (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num3)), + (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num4))); #endif } @@ -2681,19 +2691,19 @@ void UDPStandardImplementation::handleWithoutDataCompression(int ithread, char* for (i = 0; i < packetsPerFrame; i++){ if( (i < (packetsPerFrame/4)) || ((i > (packetsPerFrame/2)) && (i < (3*packetsPerFrame/4))) ){ //new packet number that has space for 16 bit - (*(uint16_t*)(((eiger_packet_header *)((char*)(wbuffer + HEADER_SIZE_NUM_TOT_PACKETS + onePacketSize*i)))->num2)) - = ((*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer + HEADER_SIZE_NUM_TOT_PACKETS + onePacketSize*i)))->num4))); + (*(uint16_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num2)) + = ((*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num4))); }else{ //new packet number that has space for 16 bit - (*(uint16_t*)(((eiger_packet_header *)((char*)(wbuffer + HEADER_SIZE_NUM_TOT_PACKETS + onePacketSize*i)))->num2)) - = ((*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer + HEADER_SIZE_NUM_TOT_PACKETS + onePacketSize*i)))->num4))+(packetsPerFrame/4)); + (*(uint16_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num2)) + = ((*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num4))+(packetsPerFrame/4)); } #ifdef VERYDEBUG cprintf(GREEN, "%d - 0x%x - %d - %d\n", i, - (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer + HEADER_SIZE_NUM_TOT_PACKETS +i*onePacketSize)))->num3)), - (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer + HEADER_SIZE_NUM_TOT_PACKETS +i*onePacketSize)))->num4)), - (*(uint16_t*)(((eiger_packet_header *)((char*)(wbuffer + HEADER_SIZE_NUM_TOT_PACKETS +i*onePacketSize)))->num2))); + (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num3)), + (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num4)), + (*(uint16_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num2))); #endif } @@ -2720,13 +2730,15 @@ void UDPStandardImplementation::handleWithoutDataCompression(int ithread, char* cprintf(GREEN,"copied frame\n"); //#endif - for(i=0;inum3)) != 0xFF) - while(!fifoFree[i]->push(wbuffer+i*onePacketSize)); + for(i=0;inum3)) != 0xFF) + while(!fifoFree[i]->push(wbuffer[j+i*(packetsPerFrame/2)])); #ifdef FIFO_DEBUG - cprintf(GREEN,"%d writer freed pushed into fifofree %x for listener %d\n",ithread, (void*)(wbuffer+i*onePacketSize)); + cprintf(GREEN,"%d writer freed pushed into fifofree %x for listener %d\n",ithread, (void*)(wbuffer[j+i*(packetsPerFrame/2)])); #endif + } } } else{ @@ -2752,13 +2764,13 @@ void UDPStandardImplementation::handleWithoutDataCompression(int ithread, char* -void UDPStandardImplementation::handleDataCompression(int ithread, char* wbuffer[], int &npackets, char* data, int xmax, int ymax, int &nf){ +void UDPStandardImplementation::handleDataCompression(int ithread, char* wbuffer[], char* data, int xmax, int ymax, int &nf){ FILE_LOG(logDEBUG) << __AT__ << " called"; #if defined(MYROOT1) && defined(ALLFILE_DEBUG) writeToFile_withoutCompression(wbuf[0], numpackets,currframenum); #endif - + int npackets = (uint32_t)(*((uint32_t*)wbuffer[0])); eventType thisEvent = PEDESTAL; int ndata; char* buff = 0; From c0f2e5c6c2ce4475f4d56dd465f55255f7e24a04 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Thu, 30 Jul 2015 11:00:36 +0200 Subject: [PATCH 111/474] onepacketsize not consistent for 10g bug fix --- .../src/UDPStandardImplementation.cpp | 45 ++++++++++--------- 1 file changed, 24 insertions(+), 21 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 12edd0720..03bada066 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -586,10 +586,15 @@ int32_t UDPStandardImplementation::setDynamicRange(int32_t dr){ FILE_LOG(logDEB if(myDetectorType == EIGER){ - if(!tengigaEnable) + if(!tengigaEnable){ packetsPerFrame = EIGER_ONE_GIGA_CONSTANT * dynamicRange * EIGER_MAX_PORTS; - else + onePacketSize = EIGER_ONE_GIGA_ONE_PACKET_SIZE; + + }else{ packetsPerFrame = EIGER_TEN_GIGA_CONSTANT * dynamicRange * EIGER_MAX_PORTS; + onePacketSize = EIGER_TEN_GIGA_ONE_PACKET_SIZE; + } + frameSize = onePacketSize * packetsPerFrame; bufferSize = (frameSize/EIGER_MAX_PORTS) + EIGER_HEADER_LENGTH;//everything one port gets (img header plus packets) maxPacketsPerFile = EIGER_MAX_FRAMES_PER_FILE * packetsPerFrame; @@ -2009,15 +2014,15 @@ int UDPStandardImplementation::startWriting(){ for (i = 0; i < packetsPerFrame/2; i++){ //overwriting frame number in header - (*(uint32_t*)(((eiger_packet_header *)((char*)(wbuf[j] + totalheader + EIGER_ONE_GIGA_ONE_PACKET_SIZE*i)))->num1)) = currframenum; + (*(uint32_t*)(((eiger_packet_header *)((char*)(wbuf[j] + totalheader + onePacketSize*i)))->num1)) = currframenum; //overwriting port number and dynamic range - if (!j) (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuf[j] + totalheader + EIGER_ONE_GIGA_ONE_PACKET_SIZE*i)))->num3)) = (dynamicRange<<2); - else (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuf[j] + totalheader + EIGER_ONE_GIGA_ONE_PACKET_SIZE*i)))->num3)) = ((dynamicRange<<2)|(0x1)); + if (!j) (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuf[j] + totalheader + onePacketSize*i)))->num3)) = (dynamicRange<<2); + else (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuf[j] + totalheader + onePacketSize*i)))->num3)) = ((dynamicRange<<2)|(0x1)); #ifdef VERYDEBUG cprintf(RED, "%d - 0x%x - %d\n", i, - (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuf[j] + totalheader +i*EIGER_ONE_GIGA_ONE_PACKET_SIZE)))->num3)), - (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuf[j] + totalheader +i*EIGER_ONE_GIGA_ONE_PACKET_SIZE)))->num4))); + (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuf[j] + totalheader +i*onePacketSize)))->num3)), + (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuf[j] + totalheader +i*onePacketSize)))->num4))); #endif } @@ -2026,26 +2031,26 @@ int UDPStandardImplementation::startWriting(){ if(dynamicRange == 32){ for (i = 0; i < packetsPerFrame/4; i++){ //new packet number that has space for 16 bit - (*(uint16_t*)(((eiger_packet_header *)((char*)(wbuf[j] + totalheader + EIGER_ONE_GIGA_ONE_PACKET_SIZE*i)))->num2)) - = ((*(uint8_t*)(((eiger_packet_header *)((char*)(wbuf[j] + totalheader + EIGER_ONE_GIGA_ONE_PACKET_SIZE*i)))->num4))); + (*(uint16_t*)(((eiger_packet_header *)((char*)(wbuf[j] + totalheader + onePacketSize*i)))->num2)) + = ((*(uint8_t*)(((eiger_packet_header *)((char*)(wbuf[j] + totalheader + onePacketSize*i)))->num4))); #ifdef VERYDEBUG cprintf(RED, "%d - 0x%x - %d - %d\n", i, - (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuf[j] + totalheader +i*EIGER_ONE_GIGA_ONE_PACKET_SIZE)))->num3)), - (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuf[j] + totalheader +i*EIGER_ONE_GIGA_ONE_PACKET_SIZE)))->num4)), - (*(uint16_t*)(((eiger_packet_header *)((char*)(wbuf[j] + totalheader +i*EIGER_ONE_GIGA_ONE_PACKET_SIZE)))->num2))); + (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuf[j] + totalheader +i*onePacketSize)))->num3)), + (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuf[j] + totalheader +i*onePacketSize)))->num4)), + (*(uint16_t*)(((eiger_packet_header *)((char*)(wbuf[j] + totalheader +i*onePacketSize)))->num2))); #endif } for (i = packetsPerFrame/4; i < packetsPerFrame/2; i++){ //new packet number that has space for 16 bit - (*(uint16_t*)(((eiger_packet_header *)((char*)(wbuf[j] + totalheader + EIGER_ONE_GIGA_ONE_PACKET_SIZE*i)))->num2)) - = ((*(uint8_t*)(((eiger_packet_header *)((char*)(wbuf[j] + totalheader + EIGER_ONE_GIGA_ONE_PACKET_SIZE*i)))->num4))+(packetsPerFrame/4)); + (*(uint16_t*)(((eiger_packet_header *)((char*)(wbuf[j] + totalheader + onePacketSize*i)))->num2)) + = ((*(uint8_t*)(((eiger_packet_header *)((char*)(wbuf[j] + totalheader + onePacketSize*i)))->num4))+(packetsPerFrame/4)); #ifdef VERYDEBUG cprintf(RED, "%d -0x%x - %d - %d\n", i, - (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuf[j] + totalheader +i*EIGER_ONE_GIGA_ONE_PACKET_SIZE)))->num3)), - (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuf[j] + totalheader +i*EIGER_ONE_GIGA_ONE_PACKET_SIZE)))->num4)), - (*(uint16_t*)(((eiger_packet_header *)((char*)(wbuf[j] + totalheader +i*EIGER_ONE_GIGA_ONE_PACKET_SIZE)))->num2))); + (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuf[j] + totalheader +i*onePacketSize)))->num3)), + (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuf[j] + totalheader +i*onePacketSize)))->num4)), + (*(uint16_t*)(((eiger_packet_header *)((char*)(wbuf[j] + totalheader +i*onePacketSize)))->num2))); #endif } } @@ -2656,20 +2661,18 @@ int UDPStandardImplementation::enableTenGiga(int enable){ if(!tengigaEnable){ packetsPerFrame = EIGER_ONE_GIGA_CONSTANT * dynamicRange * EIGER_MAX_PORTS; onePacketSize = EIGER_ONE_GIGA_ONE_PACKET_SIZE; - maxPacketsPerFile = EIGER_MAX_FRAMES_PER_FILE * packetsPerFrame; }else{ packetsPerFrame = EIGER_TEN_GIGA_CONSTANT * dynamicRange * EIGER_MAX_PORTS; onePacketSize = EIGER_TEN_GIGA_ONE_PACKET_SIZE; - maxPacketsPerFile = EIGER_MAX_FRAMES_PER_FILE * packetsPerFrame*4; } frameSize = onePacketSize * packetsPerFrame; bufferSize = (frameSize/EIGER_MAX_PORTS) + EIGER_HEADER_LENGTH;//everything one port gets (img header plus packets) - //maxPacketsPerFile = EIGER_MAX_FRAMES_PER_FILE * packetsPerFrame; + maxPacketsPerFile = EIGER_MAX_FRAMES_PER_FILE * packetsPerFrame; cout<<"packetsPerFrame:"< Date: Mon, 3 Aug 2015 16:29:59 +0200 Subject: [PATCH 112/474] almost done --- .../include/UDPBaseImplementation.h | 11 +- .../src/UDPStandardImplementation.cpp | 368 +++++++++++------- 2 files changed, 236 insertions(+), 143 deletions(-) diff --git a/slsReceiverSoftware/include/UDPBaseImplementation.h b/slsReceiverSoftware/include/UDPBaseImplementation.h index 1e1c7bdf9..4e29e0bc6 100644 --- a/slsReceiverSoftware/include/UDPBaseImplementation.h +++ b/slsReceiverSoftware/include/UDPBaseImplementation.h @@ -567,16 +567,19 @@ protected: uint32_t frameIndex; /** Frames Caught for each real time acquisition (eg. for each scan) */ - int packetsCaught; + uint32_t packetsCaught; /** Total packets caught for an entire acquisition (including all scans) */ - int totalPacketsCaught; + uint32_t totalPacketsCaught; /** Pckets currently in current file, starts new file when it reaches max */ - int packetsInFile; + uint32_t packetsInFile; /** Number of missing packets in file (sometimes packetsinFile is incorrect due to padded packets for eiger)*/ - int numTotMissingPacketsInFile; + uint32_t numTotMissingPacketsInFile; + + /** Number of missing packets in an acquisition(sometimes packetsinFile is incorrect due to padded packets for eiger)*/ + uint32_t numMissingPackets; /** Frame index at start of an entire acquisition (including all scans) */ uint32_t startAcquisitionIndex; diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index f53897625..3cd559b52 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -123,6 +123,7 @@ void UDPStandardImplementation::initializeMembers(){ totalPacketsCaught = 0; packetsInFile = 0; numTotMissingPacketsInFile = 0; + numMissingPackets = 0; startAcquisitionIndex = 0; acquisitionIndex = 0; packetsPerFrame = 0; @@ -1278,6 +1279,7 @@ int UDPStandardImplementation::setupWriter(){ //reset writing thread variables packetsInFile=0; numTotMissingPacketsInFile = 0; + numMissingPackets = 0; packetsCaught=0; frameIndex=0; if(sfilefd) sfilefd=NULL; @@ -1936,16 +1938,37 @@ int UDPStandardImplementation::startWriting(){ int ret,i,j; + char* tofree[packetsPerFrame] ; + int tofreeoffset[packetsPerFrame]; char* tempbuffer[packetsPerFrame]; char* blankframe[packetsPerFrame]; int blankoffset; int tempoffset[numListeningThreads]; - if(myDetectorType == EIGER) + if(myDetectorType == EIGER){ for(i=0;inum3)) != 0xFF) + cprintf(RED,"blank frame header is not FF\n"); + + cprintf(GREEN,"packet %d blank frame 0x%x\n",i,(void*)(blankframe[i])); } + //last packet numbers for different dynamic ranges + switch(dynamicRange){ + case 4: LAST_PACKET_VALUE = 0x40; break; + case 8: LAST_PACKET_VALUE = 0x80; break; + case 16: LAST_PACKET_VALUE = 0xff; break; + case 32: LAST_PACKET_VALUE = 0xff; break; + default: break; + } + + } + while(1){ @@ -1972,6 +1995,7 @@ int UDPStandardImplementation::startWriting(){ popready[i] = true; startdatapacket[i] = false; tempoffset[i] = (i*packetsPerFrame/numListeningThreads); + tofreeoffset[i] = (i*packetsPerFrame/numListeningThreads); blankoffset = 0; lastpacketheader[i] = -1; currentpacketheader[i] = -1; @@ -1983,34 +2007,6 @@ int UDPStandardImplementation::startWriting(){ - if(myDetectorType == EIGER){ - - for(i=0;ipop(wbuf[i]); #ifdef FIFO_DEBUG - cprintf(GREEN,"%d writer poped from fifo %x\n", ithread, (void*)(wbuf[i])); + cprintf(GREEN,"%d writer poped 0x%x from fifo %d\n", ithread, (void*)(wbuf[i]), i); #endif numpackets[i] = (uint32_t)(*((uint32_t*)wbuf[i])); #ifdef VERYDEBUG cprintf(GREEN,"%d numpackets: %d for fifo :%d\n", ithread, numpackets[i], i); #endif //dont pop again if dummy packet - if(!numpackets[i]) + if(!numpackets[i]){ popready[i] = false; + cprintf(RED,"%d dummy frame popped out of fifo %d",ithread, i); + }else{ + tofree[tofreeoffset[i]] = wbuf[i]; + tofreeoffset[i]++; + } + } } @@ -2040,11 +2042,31 @@ int UDPStandardImplementation::startWriting(){ //end of acquisition if((!numpackets[0])&& (!numpackets[1])){ -#ifdef VERYDEBUG - cprintf(GREEN,"%d End of Acquisition in Writing Thread\n", ithread); -#endif - stopWriting(ithread,wbuf); - continue; +//#ifdef VERYDEBUG + cprintf(GREEN,"%d Both dummy frames\n", ithread); +//#endif + //remaning packets to be written + if((myDetectorType == EIGER) && + ((tempoffset[0]!=0) || (tempoffset[1]!=(packetsPerFrame/numListeningThreads)))){ + cprintf(RED,"**missing packets and end of acquisition\n"); + for(i=0;iheader_confirm))){ - - //new frame (no datapacket received yet), update frame num and corrected for fnum reset for scans - if(!startdatapacket[i]){ - tempframenum[i] = htonl(*(unsigned int*)((eiger_image_header *)((char*)(wbuf[ithread] + HEADER_SIZE_NUM_TOT_PACKETS)))->fnum)+(startFrameIndex-1); -//#ifdef VERYVERBOSE - cprintf(GREEN,"**tempfraemnum of %d: %d\n",i,tempframenum[i]); -//#endif - }//next frame, leave - else{ - cprintf(RED,"**missing packets and got header\n"); - //add missing packets - numberofmissingpackets[i] = (LAST_PACKET_VALUE - lastpacketheader[i]); - //to decrement from packetsInFile to calculate packet loss - numTotMissingPacketsInFile += numberofmissingpackets[i]; - for(j=0;jnum4))); -#ifdef VERYVERBOSE - cprintf(GREEN,"** got current packet header of %d: %d lastpacketheader %d\n",i,currentpacketheader[i],lastpacketheader[i]); +#ifdef VERBOSE + else + cprintf(RED, "WARNING: Dummy packet: %d from fifo %d\n", numpackets[i],i); #endif - //same frame packet - continue building frame - if(currentpacketheader[i] > lastpacketheader[i]){ - //add missing packets - numberofmissingpackets[i] = (currentpacketheader[i] - lastpacketheader[i] -1); - //to decrement from packetsInFile to calculate packet loss - numTotMissingPacketsInFile += numberofmissingpackets[i]; - for(j=0;jpush((wbuf[i]))); +//#ifdef FIFO_DEBUG + cprintf(GREEN,"%d writer freed unknown length pushed into fifofree %x for listener %d\n",ithread, (void*)(wbuf[i]),i); +//#endif + } + continue; + } + + //not dummy buffer and not after getting a full frame + if(numpackets[i] && (!fullframe[i])){ + + //header packet + if( 0x01 == (*(uint8_t*)(((eiger_image_header *)((char*)(wbuf[i] + HEADER_SIZE_NUM_TOT_PACKETS)))->header_confirm))){ + + //new frame (no datapacket received yet), update frame num and corrected for fnum reset for scans + if(!startdatapacket[i]){ + tempframenum[i] = (htonl(*(unsigned int*)((eiger_image_header *)((char*)(wbuf[i] + HEADER_SIZE_NUM_TOT_PACKETS)))->fnum)); + if(!tempframenum[i]) + cprintf(RED,"**VERY WEIRD frame numbers for fifo %d: %d\n",i,tempframenum[i]); + tempframenum[i] += (startFrameIndex-1); + //#ifdef VERYVERBOSE + cprintf(GREEN,"**tempfraemnum of %d: %d\n",i,tempframenum[i]); + //#endif + }//next frame, leave + else{ + cprintf(RED,"**missing packets and got header\n"); + //add missing packets + numberofmissingpackets[i] = (LAST_PACKET_VALUE - lastpacketheader[i]); + //to decrement from packetsInFile to calculate packet loss + for(j=0;jnum4))); +#ifdef VERYVERBOSE + cprintf(GREEN,"**fifo:%d currentpacketheader: %d lastpacketheader %d\n",i,currentpacketheader[i],lastpacketheader[i]); +#endif + //same frame packet - continue building frame + if(currentpacketheader[i] > lastpacketheader[i]){ + //add missing packets + numberofmissingpackets[i] = (currentpacketheader[i] - lastpacketheader[i] -1); + //to decrement from packetsInFile to calculate packet loss + for(j=0;jpush(tofree[j])); +#ifdef FIFO_DEBUG + cprintf(GREEN,"%d writer freed pushed into fifofree %x for listener %d\n",ithread, (void*)(tofree[j]),0); +#endif + } + for(j=(packetsPerFrame/numListeningThreads);jpush(tofree[j])); +#ifdef FIFO_DEBUG + cprintf(GREEN,"%d writer freed pushed into fifofree %x for listener %d\n",ithread, (void*)(tofree[j]),1); +#endif + } + + + +//#ifdef VERYDEBUG + cprintf(GREEN,"finished freeing\n"); +//#endif //reset a few stuff for(int i=0;ipush(wbuffer[i])); -#ifdef FIFO_DEBUG +//#ifdef FIFO_DEBUG cprintf(GREEN,"%d writer free dummy pushed into fifofree %x for listener %d\n", ithread,(void*)(wbuffer[i]),i); -#endif +//#endif } @@ -2480,8 +2559,8 @@ void UDPStandardImplementation::stopWriting(int ithread, char* wbuffer[]){ cprintf(GREEN, "Status: Run Finished\n"); if(!totalPacketsCaught){ - cprintf(GREEN, "Total Packets Caught:%d\n", totalPacketsCaught); - cprintf(GREEN, "Total Frames Caught:%d\n",(totalPacketsCaught/packetsPerFrame)); + cprintf(RED, "Total Packets Caught: 0\n"); + cprintf(RED, "Total Frames Caught: 0\n"); }else{ cprintf(GREEN, "Total Packets Caught:%d\n", totalPacketsCaught); cprintf(GREEN, "Total Frames Caught:%d\n",(totalPacketsCaught/packetsPerFrame)); @@ -2505,7 +2584,7 @@ void UDPStandardImplementation::stopWriting(int ithread, char* wbuffer[]){ void UDPStandardImplementation::writeToFile_withoutCompression(char* buf[],int numpackets, uint32_t framenum){ FILE_LOG(logDEBUG) << __AT__ << " called"; - +cout<<"in write to file numpackets:"< numpackets) packetsToSave = numpackets; /**next time offset is still plus header length*/ - if(myDetectorType == EIGER) - for(i=0;i= maxPacketsPerFile){ @@ -2641,8 +2724,9 @@ void UDPStandardImplementation::writeToFile_withoutCompression(char* buf[],int n if(numWriterThreads > 1) pthread_mutex_lock(&write_mutex); packetsInFile += numpackets; - packetsCaught += numpackets; - totalPacketsCaught += numpackets; + packetsCaught += (numpackets - numMissingPackets); + totalPacketsCaught += (numpackets - numMissingPackets); + numMissingPackets = 0; if(numWriterThreads > 1) pthread_mutex_unlock(&write_mutex); } @@ -2734,16 +2818,22 @@ void UDPStandardImplementation::handleWithoutDataCompression(int ithread, char* cprintf(GREEN,"copied frame\n"); //#endif - for(i=0;inum3)) != 0xFF) - while(!fifoFree[i]->push(wbuffer[j+i*(packetsPerFrame/2)])); -#ifdef FIFO_DEBUG - cprintf(GREEN,"%d writer freed pushed into fifofree %x for listener %d\n",ithread, (void*)(wbuffer[j+i*(packetsPerFrame/2)])); -#endif - } +/* + for(j=0;jnum3)) != 0xFF){ + + while(!fifoFree[(j/(packetsPerFrame/2))]->push(&(wbuffer[j] - HEADER_SIZE_NUM_TOT_PACKETS))); + + //#ifdef FIFO_DEBUG + cprintf(GREEN,"%d writer freed pushed into fifofree %x for listener %d\n",ithread, (void*)(wbuffer[j]- HEADER_SIZE_NUM_TOT_PACKETS),(j/(packetsPerFrame/2))); + //#endif + }else cprintf(GREEN,"blank frame 0x%x\n",(void*)(wbuffer[j])); } + + //#ifdef VERYDEBUG + cprintf(GREEN,"finished freeing\n"); + //#endif + */ } else{ //copy to gui From 4fbfe186ef636f06bd9f17d651cc78da00bc6ade Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 4 Aug 2015 15:20:00 +0200 Subject: [PATCH 113/474] done --- .../src/UDPStandardImplementation.cpp | 225 +++++++++--------- 1 file changed, 119 insertions(+), 106 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 3cd559b52..9f365d4b0 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1922,43 +1922,34 @@ int UDPStandardImplementation::startWriting(){ thread_started = 1; - int numpackets[numListeningThreads], nf; - bool startdatapacket[numListeningThreads],fullframe[numListeningThreads],popready[numListeningThreads]; - uint32_t tempframenum[numListeningThreads]; - - int lastpacketheader[numListeningThreads], currentpacketheader[numListeningThreads]; - int numberofmissingpackets[numListeningThreads]; - int LAST_PACKET_VALUE; - - - char* wbuf[numListeningThreads];//interleaved char *d=new char[bufferSize*numListeningThreads]; int xmax=0,ymax=0; int ret,i,j; + int numpackets[numListeningThreads], nf; + bool startdatapacket[numListeningThreads],fullframe[numListeningThreads],popready[numListeningThreads]; + uint32_t tempframenum[numListeningThreads]; + int lastpacketheader[numListeningThreads], currentpacketheader[numListeningThreads]; + int numberofmissingpackets[numListeningThreads]; - char* tofree[packetsPerFrame] ; - int tofreeoffset[packetsPerFrame]; - char* tempbuffer[packetsPerFrame]; - char* blankframe[packetsPerFrame]; - int blankoffset; + int MAX_VALUE = 1024; + char* tofree[MAX_VALUE]; + char* tempbuffer[MAX_VALUE]; + char* blankframe[MAX_VALUE]; + int tofreeoffset[numListeningThreads]; int tempoffset[numListeningThreads]; + int blankoffset; + for(i=0;inum3)) != 0xFF) - cprintf(RED,"blank frame header is not FF\n"); - - cprintf(GREEN,"packet %d blank frame 0x%x\n",i,(void*)(blankframe[i])); - } - - //last packet numbers for different dynamic ranges switch(dynamicRange){ case 4: LAST_PACKET_VALUE = 0x40; break; case 8: LAST_PACKET_VALUE = 0x80; break; @@ -1966,9 +1957,10 @@ int UDPStandardImplementation::startWriting(){ case 32: LAST_PACKET_VALUE = 0xff; break; default: break; } - } + + while(1){ @@ -1989,6 +1981,20 @@ int UDPStandardImplementation::startWriting(){ //so that the first frame is always copied guiData = latestData; + //blank frame + if(myDetectorType == EIGER){ + for(i=0;ipush((wbuf[i]))); -//#ifdef FIFO_DEBUG - cprintf(GREEN,"%d writer freed unknown length pushed into fifofree %x for listener %d\n",ithread, (void*)(wbuf[i]),i); -//#endif - } continue; } //not dummy buffer and not after getting a full frame if(numpackets[i] && (!fullframe[i])){ - //header packet + //IMAGE HEADER PACKET if( 0x01 == (*(uint8_t*)(((eiger_image_header *)((char*)(wbuf[i] + HEADER_SIZE_NUM_TOT_PACKETS)))->header_confirm))){ //new frame (no datapacket received yet), update frame num and corrected for fnum reset for scans @@ -2114,12 +2115,37 @@ int UDPStandardImplementation::startWriting(){ if(!tempframenum[i]) cprintf(RED,"**VERY WEIRD frame numbers for fifo %d: %d\n",i,tempframenum[i]); tempframenum[i] += (startFrameIndex-1); - //#ifdef VERYVERBOSE - cprintf(GREEN,"**tempfraemnum of %d: %d\n",i,tempframenum[i]); - //#endif - }//next frame, leave + + //normal frame packet (also exception of tempnum 0 and currfnum 0) + if((tempframenum[i] == (currframenum+1))||(!tempframenum[i] && !currframenum)){ +#ifdef EIGER_DEBUG3 + cprintf(GREEN,"**tempfraemnum of %d: %d\n",i,tempframenum[i]); +#endif + } + //frame too far ahead + else{ +#ifdef EIGER_DEBUG3 + cprintf(RED,"frame number too far ahead, missing packets\n"); +#endif + tempframenum[i] = currframenum + 1; + //add missing packets + numberofmissingpackets[i] = (LAST_PACKET_VALUE); + //to decrement from packetsInFile to calculate packet loss + for(j=0;jpush(wbuffer[i])); -//#ifdef FIFO_DEBUG +#ifdef FIFO_DEBUG cprintf(GREEN,"%d writer free dummy pushed into fifofree %x for listener %d\n", ithread,(void*)(wbuffer[i]),i); -//#endif +#endif } @@ -2584,7 +2610,7 @@ void UDPStandardImplementation::stopWriting(int ithread, char* wbuffer[]){ void UDPStandardImplementation::writeToFile_withoutCompression(char* buf[],int numpackets, uint32_t framenum){ FILE_LOG(logDEBUG) << __AT__ << " called"; -cout<<"in write to file numpackets:"<= maxPacketsPerFile){ @@ -2814,28 +2842,10 @@ void UDPStandardImplementation::handleWithoutDataCompression(int ithread, char* cprintf(GREEN,"gonna copy frame\n"); #endif copyFrameToGui(wbuffer,currframenum); - //#ifdef VERYDEBUG +#ifdef VERYDEBUG cprintf(GREEN,"copied frame\n"); - //#endif - -/* - for(j=0;jnum3)) != 0xFF){ - - while(!fifoFree[(j/(packetsPerFrame/2))]->push(&(wbuffer[j] - HEADER_SIZE_NUM_TOT_PACKETS))); - - //#ifdef FIFO_DEBUG - cprintf(GREEN,"%d writer freed pushed into fifofree %x for listener %d\n",ithread, (void*)(wbuffer[j]- HEADER_SIZE_NUM_TOT_PACKETS),(j/(packetsPerFrame/2))); - //#endif - }else cprintf(GREEN,"blank frame 0x%x\n",(void*)(wbuffer[j])); - } - - //#ifdef VERYDEBUG - cprintf(GREEN,"finished freeing\n"); - //#endif - */ - } - else{ +#endif + }else{ //copy to gui if(npackets >= packetsPerFrame){//min 1 frame, but neednt be //if(npackets == packetsPerFrame * numJobsPerThread){ //only full frames @@ -2843,11 +2853,14 @@ void UDPStandardImplementation::handleWithoutDataCompression(int ithread, char* #ifdef VERYVERBOSE cout << ithread << " finished copying" << endl; #endif - }//else cout << "unfinished buffersize" << endl; + } + /* freeing now done at function call + //else cout << "unfinished buffersize" << endl; while(!fifoFree[0]->push(wbuffer[0])); #ifdef FIFO_DEBUG cprintf(GREEN,"%d writer freed pushed into fifofree %x for listener 0\n",ithread, (void*)(wbuffer[0])); #endif + */ } } From a26cbced57b022050ebd3ad66de7cee903303be4 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Wed, 5 Aug 2015 09:11:50 +0200 Subject: [PATCH 114/474] corrected 10g mapping for gui --- .../src/slsReceiverTCPIPInterface.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp index 631df46d1..5cb2f0fb5 100644 --- a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp +++ b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp @@ -1616,13 +1616,13 @@ int slsReceiverTCPIPInterface::eiger_read_frame(){ int c2=(frameSize/2) + 8; //second port int retindex=0; int irow,ibytesperpacket; - int linesperpacket = (16/dynamicrange)* 1;// 16:1 line, 8:2 lines, 4:4 lines, 32: 0.5 + int linesperpacket = (16*1/dynamicrange);// 16:1 line, 8:2 lines, 4:4 lines, 32: 0.5 int numbytesperlineperport=(EIGER_PIXELS_IN_ONE_ROW/EIGER_MAX_PORTS)*dynamicrange/8;//16:1024,8:512,4:256,32:2048 int datapacketlength = EIGER_ONE_GIGA_ONE_DATA_SIZE; int total_num_bytes = 1040*(16*dynamicrange)*2; if(tenGigaEnable){ - linesperpacket = (16/dynamicrange)* 4;// 16:4 line, 8:8 lines, 4:16 lines, 32: 2 + linesperpacket = (16*4/dynamicrange);// 16:4 line, 8:8 lines, 4:16 lines, 32: 2 datapacketlength = EIGER_TEN_GIGA_ONE_DATA_SIZE; } //if 1GbE, one line is split into two packets for 32 bit mode, so its special @@ -1640,7 +1640,7 @@ int slsReceiverTCPIPInterface::eiger_read_frame(){ memcpy(retval+retindex ,origVal+c1 ,numbytesperlineperport); retindex += numbytesperlineperport; c1 += numbytesperlineperport; - if(dynamicrange == 32){ + if(dynamicrange == 32 && !tenGigaEnable){ c1 += 16; memcpy(retval+retindex ,origVal+c1 ,numbytesperlineperport); retindex += numbytesperlineperport; @@ -1651,7 +1651,7 @@ int slsReceiverTCPIPInterface::eiger_read_frame(){ memcpy(retval+retindex ,origVal+c2 ,numbytesperlineperport); retindex += numbytesperlineperport; c2 += numbytesperlineperport; - if(dynamicrange == 32){ + if(dynamicrange == 32 && !tenGigaEnable){ c2 += 16; memcpy(retval+retindex ,origVal+c2 ,numbytesperlineperport); retindex += numbytesperlineperport; @@ -1660,7 +1660,7 @@ int slsReceiverTCPIPInterface::eiger_read_frame(){ } ibytesperpacket += numbytesperlineperport; } - if(dynamicrange != 32) { + if(dynamicrange != 32 || tenGigaEnable) { c1 += 16; c2 += 16; } @@ -1677,7 +1677,7 @@ int slsReceiverTCPIPInterface::eiger_read_frame(){ for(irow=0;irow Date: Wed, 5 Aug 2015 12:08:28 +0200 Subject: [PATCH 115/474] proper freeng after udpsocket shutdown --- slsReceiverSoftware/include/genericSocket.h | 2 ++ slsReceiverSoftware/src/UDPStandardImplementation.cpp | 1 + 2 files changed, 3 insertions(+) diff --git a/slsReceiverSoftware/include/genericSocket.h b/slsReceiverSoftware/include/genericSocket.h index 0ccc80adf..216a9fa11 100644 --- a/slsReceiverSoftware/include/genericSocket.h +++ b/slsReceiverSoftware/include/genericSocket.h @@ -443,6 +443,8 @@ typedef struct void ShutDownSocket(){ while(!shutdown(socketDescriptor, SHUT_RDWR)); + close(socketDescriptor); + socketDescriptor = -1; }; diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 03bada066..0104f9b47 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1077,6 +1077,7 @@ int UDPStandardImplementation::createUDPSockets(){ #ifdef VERBOSE cprintf(BG_RED,"Could not create UDP socket on port %d error: %d\n", port[i], iret); #endif + shutDownUDPSockets(); return FAIL; } } From d2f53aaf64f6f603307debf3d8145bc86e21aece Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Fri, 7 Aug 2015 12:06:10 +0200 Subject: [PATCH 116/474] bugs --- .../src/UDPStandardImplementation.cpp | 206 ++++++++++++------ 1 file changed, 137 insertions(+), 69 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index ff275d805..0f05e0678 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1987,8 +1987,14 @@ int UDPStandardImplementation::startWriting(){ for(i=0;inum3)) = 0xFE; + + for(j=0;j<(onePacketSize-16);++j) + (*((uint8_t*)((char*)(blankframe[i])+8+j))) = 0xFF; + if ((*(uint8_t*)(((eiger_packet_header *)((char*)(blankframe[i])))->num3)) != 0xFE){ + cprintf(RED,"blank frame not detected at %d: 0x%x\n",i,(*(uint8_t*)(((eiger_packet_header *)((char*)(blankframe[i])))->num3)) ); + exit(-1); + } #ifdef FIFO_DEBUG cprintf(GREEN,"packet %d blank frame 0x%x\n",i,(void*)(blankframe[i])); #endif @@ -2036,12 +2042,14 @@ int UDPStandardImplementation::startWriting(){ //dont pop again if dummy packet if(!numpackets[i]){ popready[i] = false; -#ifdef EIGER_DEBUG3 +//#ifdef EIGER_DEBUG3 cprintf(RED,"%d Dummy frame popped out of fifo %d",ithread, i); -#endif +//#endif }else{ - tofree[tofreeoffset[i]] = wbuf[i]; - tofreeoffset[i]++; + if(myDetectorType == EIGER){ + tofree[tofreeoffset[i]] = wbuf[i]; + tofreeoffset[i]++; + } } } @@ -2051,21 +2059,24 @@ int UDPStandardImplementation::startWriting(){ //END OF ACQUISITION if((!numpackets[0])&& (!numpackets[1])){ -#ifdef VERYDEBUG +//#ifdef VERYDEBUG cprintf(GREEN,"%d Both dummy frames\n", ithread); -#endif +//#endif //remaning packets to be written if((myDetectorType == EIGER) && ((tempoffset[0]!=0) || (tempoffset[1]!=(packetsPerFrame/numListeningThreads)))){ -#ifdef EIGER_DEBUG3 +//#ifdef EIGER_DEBUG3 cprintf(RED,"**End of Acquisition but didnt get last packet\n"); -#endif +//#endif for(i=0;inum3)) == 0xFE) + cprintf(RED,"1 fifo:%d missing packet added at pnum:%d\n",i,tempoffset[i]); + else cprintf(RED, "1 fifo:%d WEird at pnum:%d\n",i,tempoffset[i]); tempoffset[i] ++; blankoffset ++; } @@ -2097,10 +2108,10 @@ int UDPStandardImplementation::startWriting(){ if((numpackets[i] != EIGER_HEADER_LENGTH) && (numpackets[i] != onePacketSize)){ if(numpackets[i]) cprintf(RED, "WARNING: Got a weird packet size: %d from fifo %d\n", numpackets[i],i); -#ifdef VERBOSE +//#ifdef VERBOSE else cprintf(RED, "WARNING: Dummy packet: %d from fifo %d\n", numpackets[i],i); -#endif +//#endif continue; } @@ -2119,23 +2130,29 @@ int UDPStandardImplementation::startWriting(){ //normal frame packet (also exception of tempnum 0 and currfnum 0) if((tempframenum[i] == (currframenum+1))||(!tempframenum[i] && !currframenum)){ -#ifdef EIGER_DEBUG3 +//#ifdef EIGER_DEBUG3 cprintf(GREEN,"**tempfraemnum of %d: %d\n",i,tempframenum[i]); -#endif +//#endif } //frame too far ahead else{ -#ifdef EIGER_DEBUG3 +//#ifdef EIGER_DEBUG3 cprintf(RED,"frame number too far ahead, missing packets\n"); -#endif +//#endif tempframenum[i] = currframenum + 1; //add missing packets numberofmissingpackets[i] = (LAST_PACKET_VALUE); + if(numberofmissingpackets[i]>0) + cprintf(BG_RED,"fifo:%d missing packet from: %d\n",i,lastpacketheader[i]); //to decrement from packetsInFile to calculate packet loss for(j=0;jnum3)) == 0xFE) + cprintf(RED,"2 fifo:%d missing packet added at pnum:%d\n",i,tempoffset[i]); + else cprintf(RED, "2 fifo:%d WEird at pnum:%d\n",i,tempoffset[i]); tempoffset[i] ++; blankoffset ++; + } //set fullframe and dont let fifo pop over it until written fullframe[i] = true; @@ -2144,14 +2161,19 @@ int UDPStandardImplementation::startWriting(){ } }//two image headers at a time = next frame, leave else{ -#ifdef EIGER_DEBUG3 +//#ifdef EIGER_DEBUG3 cprintf(RED,"received frame header twice, missing packets\n"); -#endif +//#endif //add missing packets numberofmissingpackets[i] = (LAST_PACKET_VALUE - lastpacketheader[i]); + if(numberofmissingpackets[i]>0) + cprintf(BG_RED,"fifo:%d missing packet from: %d\n",i,lastpacketheader[i]); //to decrement from packetsInFile to calculate packet loss for(j=0;jnum3)) == 0xFE) + cprintf(RED,"3 fifo:%d missing packet added at pnum:%d\n",i,tempoffset[i]); + else cprintf(RED, "3 fifo:%d WEird at pnum:%d\n",i,tempoffset[i]); tempoffset[i] ++; blankoffset ++; } @@ -2165,16 +2187,21 @@ int UDPStandardImplementation::startWriting(){ startdatapacket[i] = true; //update current packet currentpacketheader[i] = ((*(uint8_t*)(((eiger_packet_header *)((char*)(wbuf[i] + HEADER_SIZE_NUM_TOT_PACKETS)))->num4))); -#ifdef VERYVERBOSE - cprintf(GREEN,"**fifo:%d currentpacketheader: %d lastpacketheader %d\n",i,currentpacketheader[i],lastpacketheader[i]); -#endif +//#ifdef VERYVERBOSE + cprintf(GREEN,"**fifo:%d currentpacketheader: %d lastpacketheader %d tempoffset:%d\n",i,currentpacketheader[i],lastpacketheader[i], tempoffset[i]); +//#endif //same frame packet - continue building frame if(currentpacketheader[i] > lastpacketheader[i]){ //add missing packets numberofmissingpackets[i] = (currentpacketheader[i] - lastpacketheader[i] -1); + if(numberofmissingpackets[i]>0) + cprintf(BG_RED,"fifo:%d missing packet from: %d now at :%d tempoffset:%d\n",i,lastpacketheader[i],currentpacketheader[i],tempoffset[i]); //to decrement from packetsInFile to calculate packet loss for(j=0;jnum3)) == 0xFE) + cprintf(RED,"4 fifo:%d missing packet added at pnum:%d\n",i,tempoffset[i]); + else cprintf(RED, "4 fifo:%d WEird at pnum:%d\n",i,tempoffset[i]); tempoffset[i] ++; blankoffset ++; } @@ -2185,24 +2212,29 @@ int UDPStandardImplementation::startWriting(){ lastpacketheader[i] = currentpacketheader[i]; //last frame got, this will save time and also for last frames, it doesnt wait for stop receiver if(currentpacketheader[i] == LAST_PACKET_VALUE){ -#ifdef EIGER_DEBUG3 +//#ifdef EIGER_DEBUG3 cprintf(GREEN, "Got last packet\n"); -#endif +//#endif fullframe[i] = true; popready[i] = false; } } //next frame packet - leave else{ -#ifdef EIGER_DEBUG3 - cprintf(RED,"packet from next frame, missing packets"<0) + cprintf(BG_RED,"fifo:%d missing packet from: %d now at :%d\n",i,lastpacketheader[i],currentpacketheader[i]); //to decrement from packetsInFile to calculate packet loss for(j=0;jnum3)) == 0xFE) + cprintf(RED,"5 fifo:%d missing packet added at pnum:%d\n",i,tempoffset[i]); + else cprintf(RED, "5 fifo:%d WEird at pnum:%d\n",i,tempoffset[i]); tempoffset[i] ++; blankoffset ++; } @@ -2231,17 +2263,22 @@ int UDPStandardImplementation::startWriting(){ numMissingPackets += (numberofmissingpackets[0]+numberofmissingpackets[1]); numTotMissingPacketsInFile += numMissingPackets; -#ifdef EIGER_DEBUG2 - cprintf(GREEN,"%d **fnum:%d**\n",currframenum); -#endif -#ifdef EIGER_DEBUG3 +//#ifdef EIGER_DEBUG2 + cprintf(GREEN,"**fnum:%d**\n",currframenum); +//#endif +//#ifdef EIGER_DEBUG3 if(numberofmissingpackets[0]) - cprintf(RED, "fifo 0 missing packets:%d\n",numberofmissingpackets[0]); + cprintf(RED, "fifo 0 missing packets:%d fnum:%d\n",numberofmissingpackets[0],currframenum); if(numberofmissingpackets[1]) - cprintf(RED, "fifo 1 missing packets:%d\n",numberofmissingpackets[1]); - if(numMissingPackets) - cprintf(RED, "numMissingPackets:%d\n",numMissingPackets); -#endif + cprintf(RED, "fifo 1 missing packets:%d fnum:%d\n",numberofmissingpackets[1],currframenum); + if(numMissingPackets){ + cprintf(RED, "numMissingPackets:%d fnum:%d\n",numMissingPackets,currframenum); + + for (j=0;jnum3)) == 0xFE) + cprintf(RED,"found the missing packet at pnum:%d\n",j); + } +//#endif //write and copy to gui @@ -2264,9 +2301,9 @@ int UDPStandardImplementation::startWriting(){ -#ifdef VERYDEBUG +//#ifdef VERYDEBUG cprintf(GREEN,"finished freeing\n"); -#endif +//#endif //reset a few stuff for(int i=0;inum1)) = currframenum; - //overwriting port number and dynamic range - if (i<(packetsPerFrame/2)) - (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num3)) = (dynamicRange<<2); - else - (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num3)) = ((dynamicRange<<2)|(0x1)); -#ifdef VERYDEBUG - cprintf(GREEN, "%d - 0x%x - %d\n", i, - (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num3)), - (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num4))); -#endif + //which port + if (i ==(packetsPerFrame/2)) + port = 1; + //missing packet + if ((*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num3)) == 0xFE){ + missingpacket = 1; + //add packet numbers + (*(uint16_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num2)) = (i+1); + }else{ + missingpacket = 0; - } - - //for 32 bit,port number needs to be changed and packet number reconstructed - if(dynamicRange == 32){ - for (i = 0; i < packetsPerFrame; i++){ - if( (i < (packetsPerFrame/4)) || ((i > (packetsPerFrame/2)) && (i < (3*packetsPerFrame/4))) ){ - //new packet number that has space for 16 bit + if(dynamicRange != 32){ + //move packet numbers to num2, and compensate for port1 starting pnum from 0 + if(!port) + (*(uint16_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num2)) = + ((*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num4))+1); + else + (*(uint16_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num2)) = + ((*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num4))+(packetsPerFrame/2) +1); + } + //dr == 32 + else{ + if(i == 0) + pnuminc = 0; + else if(i == (packetsPerFrame/4)) + pnuminc = (packetsPerFrame/4); + else if(i == (packetsPerFrame/2)) + pnuminc = (packetsPerFrame/2); + else if(i == (3*packetsPerFrame/4)) + pnuminc = (3*packetsPerFrame/4); (*(uint16_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num2)) - = ((*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num4))); - }else{ - //new packet number that has space for 16 bit - (*(uint16_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num2)) - = ((*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num4))+(packetsPerFrame/4)); + = ((*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num4))+pnuminc+1); } + } + + + if((*(uint16_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num2)) != (i+1)){ + cprintf(BG_RED, "pnum mismatch! i:%d pnum:%d fnum:%d\n",i,(*(uint16_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num2)),currframenum); + if ((*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num3)) == 0xFE) + cprintf(BG_RED,"missing packet though\n"); + exit(-1); + } + + //overwriting port number and dynamic range + (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num3)) = + ((dynamicRange<<2)|(missingpacket<<1)|(port)); + + //frame number + (*(uint32_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num1)) = currframenum; + #ifdef VERYDEBUG - cprintf(GREEN, "%d - 0x%x - %d - %d\n", i, - (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num3)), - (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num4)), - (*(uint16_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num2))); + if((i==0)||(i==1)){ + cprintf(GREEN, "%d packet header:0x%016llx num3:0x%x\n",i, + ((uint64_t)(*((uint64_t*)(wbuffer[i])))), + (uint8_t)(*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num3))); + } + cprintf(GREEN, "%d - 0x%x - %d - %d\n", i, + (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num3)), + (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num4)), + (*(uint16_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num2))); #endif - } + + } } #endif @@ -2855,13 +2923,13 @@ void UDPStandardImplementation::handleWithoutDataCompression(int ithread, char* cout << ithread << " finished copying" << endl; #endif } - /* freeing now done at function call + //else cout << "unfinished buffersize" << endl; while(!fifoFree[0]->push(wbuffer[0])); #ifdef FIFO_DEBUG cprintf(GREEN,"%d writer freed pushed into fifofree %x for listener 0\n",ithread, (void*)(wbuffer[0])); #endif - */ + } } From 52f83b9249bc9a32300053de62ba7adb46533725 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Mon, 10 Aug 2015 13:44:57 +0200 Subject: [PATCH 117/474] do not push, debug commands involved --- slsReceiverSoftware/include/genericSocket.h | 50 ++++++++++++++++--- .../src/UDPBaseImplementation.cpp | 8 ++- .../src/UDPStandardImplementation.cpp | 41 ++++++++++----- .../src/slsReceiverTCPIPInterface.cpp | 1 - 4 files changed, 79 insertions(+), 21 deletions(-) diff --git a/slsReceiverSoftware/include/genericSocket.h b/slsReceiverSoftware/include/genericSocket.h index 216a9fa11..3bb4adcff 100644 --- a/slsReceiverSoftware/include/genericSocket.h +++ b/slsReceiverSoftware/include/genericSocket.h @@ -60,7 +60,7 @@ class sockaddr_in; #include #endif - +#include "ansi.h" #include /******exit */ #include @@ -71,6 +71,8 @@ class sockaddr_in; #include #include +#include //SIGINT + using namespace std; #define DEFAULT_PACKET_SIZE 1286 @@ -125,6 +127,7 @@ typedef struct struct hostent *hostInfo = gethostbyname(host_ip_or_name); if (hostInfo == NULL){ cerr << "Exiting: Problem interpreting host: " << host_ip_or_name << "\n"; + cprintf(RED,"Exiting: Problem interpreting host:%s\n",host_ip_or_name); } else { // Set some fields in the serverAddress structure. serverAddress.sin_family = hostInfo->h_addrtype; @@ -134,6 +137,7 @@ typedef struct socketDescriptor=0; //You can use send and recv, //would it work????? } clientAddress_length=sizeof(clientAddress); + cprintf(MAGENTA, "client socket created %d \n",socketDescriptor,protocol); } @@ -176,6 +180,7 @@ typedef struct nsent(0), total_sent(0) { + signal(SIGCHLD,SIG_IGN); //memset(&serverAddress, 0, sizeof(sockaddr_in)); // memset(&clientAddress, 0, sizeof(sockaddr_in)); // serverAddress = {0}; @@ -205,9 +210,12 @@ typedef struct socketDescriptor = socket(AF_INET, getProtocol(),0); //tcp + cprintf(MAGENTA, "socket created %d protocol:%d\n",socketDescriptor,protocol); + if (socketDescriptor < 0) { cerr << "Can not create socket "<0) { if ((file_des = accept(socketDescriptor,(struct sockaddr *) &clientAddress, &clientAddress_length)) < 0) { cerr << "Error: with server accept, connection refused"<=0){ + close(file_des); + file_des=-1; + } + } +*/ + + if(file_des>=0){ //then was open if(is_a_server){ - close(file_des); + // cprintf(MAGENTA, "file_des disconnected %d \n",file_des); + if(close(file_des)) + cprintf(RED,"file_des not disconnected %d\n", file_des); + // cprintf(MAGENTA, "file_des disconnected %d \n",file_des); } else { - close(socketDescriptor); + //cprintf(MAGENTA, "socketDescriptor disconnected %d \n",socketDescriptor); + if(close(socketDescriptor)) + cprintf(RED,"socketDescriptor not disconnected %d\n", file_des); + // cprintf(MAGENTA, "socketDescriptor disconnected %d \n",socketDescriptor); socketDescriptor=-1; } file_des=-1; } + + + } }; void ShutDownSocket(){ - while(!shutdown(socketDescriptor, SHUT_RDWR)); - close(socketDescriptor); - socketDescriptor = -1; + while(!shutdown(socketDescriptor, SHUT_RDWR)); + Disconnect(); }; diff --git a/slsReceiverSoftware/src/UDPBaseImplementation.cpp b/slsReceiverSoftware/src/UDPBaseImplementation.cpp index bbb8b331d..80ce6b2c7 100644 --- a/slsReceiverSoftware/src/UDPBaseImplementation.cpp +++ b/slsReceiverSoftware/src/UDPBaseImplementation.cpp @@ -745,15 +745,19 @@ int UDPBaseImplementation::createUDPSockets(){ FILE_LOG(logDEBUG) << __AT__ << " if(!strlen(eth)){ cout<<"warning:eth is empty.listening to all"< /proc/sys/net/core/netdev_max_backlog")) cout << "\nWARNING: Could not change max length of input queue in file /proc/sys/net/core/netdev_max_backlog" << endl; + /** permanent setting heiner net.core.rmem_max = 104857600 # 100MiB net.core.netdev_max_backlog = 250000 @@ -1056,24 +1057,29 @@ int UDPStandardImplementation::createUDPSockets(){ if(!strlen(eth)){ cout<<"warning:eth is empty.listening to all"<getErrorStatus(); - if(!iret) + if(!iret){ cout << "UDP port opened at port " << port[i] << endl; - else{ + cprintf(YELLOW, "socket of port %d descriptor:%d\n",i,udpSocket[i]->getsocketDescriptor()); + }else{ #ifdef VERBOSE cprintf(BG_RED,"Could not create UDP socket on port %d error: %d\n", port[i], iret); #endif @@ -1082,6 +1088,8 @@ int UDPStandardImplementation::createUDPSockets(){ } } + + return OK; } @@ -1276,7 +1284,7 @@ int UDPStandardImplementation::setupWriter(){ packetsInFile=0; packetsCaught=0; frameIndex=0; - if(sfilefd) sfilefd=NULL; + if(sfilefd) {cprintf(RED,"**FILE not closed!\n");fclose(sfilefd);sfilefd=NULL;} guiData = NULL; guiDataReady=0; strcpy(guiFileName,""); @@ -1402,9 +1410,13 @@ int UDPStandardImplementation::createNewFile(){ if(enableFileWrite && cbAction > DO_NOTHING){ //close if(sfilefd){ - fclose(sfilefd); + if(fclose(sfilefd)){ + cprintf(YELLOW, "file clsoe problem %d\n",fileno(sfilefd)); + fclose(sfilefd); + } sfilefd = NULL; } + //open file if(!overwrite){ if (NULL == (sfilefd = fopen((const char *) (savefilename), "wx"))){ @@ -1418,6 +1430,9 @@ int UDPStandardImplementation::createNewFile(){ //setting buffer setvbuf(sfilefd,NULL,_IOFBF,BUF_SIZE); + cprintf(YELLOW, "file value:%d\n",fileno(sfilefd)); + + //cprintf(YELLOW, "file valuex:%d",(int)sfilefd); //printing packet losses and file names if(!packetsCaught) cout << savefilename << endl; @@ -1459,10 +1474,12 @@ void UDPStandardImplementation::closeFile(int ithr){ if(!dataCompression){ if(sfilefd){ -#ifdef VERBOSE - cout << "sfield:" << (int)sfilefd << endl; -#endif - fclose(sfilefd); +//#ifdef VERBOSE + cprintf(YELLOW, "gonna close file:%d\n",fileno(sfilefd)); +//#endif + if(fclose(sfilefd)) + perror("close ERRROR"); + cprintf(YELLOW, "check close file:%d\n",fileno(sfilefd)); sfilefd = NULL; } } @@ -1473,7 +1490,8 @@ void UDPStandardImplementation::closeFile(int ithr){ #ifdef VERBOSE cout << "sfield:" << (int)sfilefd << endl; #endif - fclose(sfilefd); + if(fclose(sfilefd)) + perror("close ERRROR"); sfilefd = NULL; } #endif @@ -1612,7 +1630,6 @@ int UDPStandardImplementation::stopReceiver(){ }else cout <<" Not idle to stop receiver" << endl; - //sem_post(&smp); return OK; diff --git a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp index 5cb2f0fb5..dfa01e6e3 100644 --- a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp +++ b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp @@ -65,7 +65,6 @@ slsReceiverTCPIPInterface::slsReceiverTCPIPInterface(int &success, UDPInterface* strcpy(socket->lastClientIP,"none"); strcpy(socket->thisClientIP,"none1"); strcpy(mess,"dummy message"); - function_table(); #ifdef VERBOSE cout << "Function table assigned." << endl; From 0a24778ff8f4629bb6dd564e13006989dc573d93 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Mon, 10 Aug 2015 14:45:43 +0200 Subject: [PATCH 118/474] missing packets should work now --- .../include/UDPBaseImplementation.h | 5 +- .../src/UDPStandardImplementation.cpp | 89 ++++++++++++------- 2 files changed, 60 insertions(+), 34 deletions(-) diff --git a/slsReceiverSoftware/include/UDPBaseImplementation.h b/slsReceiverSoftware/include/UDPBaseImplementation.h index 4e29e0bc6..05b992975 100644 --- a/slsReceiverSoftware/include/UDPBaseImplementation.h +++ b/slsReceiverSoftware/include/UDPBaseImplementation.h @@ -575,10 +575,13 @@ protected: /** Pckets currently in current file, starts new file when it reaches max */ uint32_t packetsInFile; + /** Number of missing packets in acquisition*/ + uint32_t numTotMissingPackets; + /** Number of missing packets in file (sometimes packetsinFile is incorrect due to padded packets for eiger)*/ uint32_t numTotMissingPacketsInFile; - /** Number of missing packets in an acquisition(sometimes packetsinFile is incorrect due to padded packets for eiger)*/ + /** Number of missing packets per buffer*/ uint32_t numMissingPackets; /** Frame index at start of an entire acquisition (including all scans) */ diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 0f05e0678..87fc042e0 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -122,6 +122,7 @@ void UDPStandardImplementation::initializeMembers(){ packetsCaught = 0; totalPacketsCaught = 0; packetsInFile = 0; + numTotMissingPackets = 0; numTotMissingPacketsInFile = 0; numMissingPackets = 0; startAcquisitionIndex = 0; @@ -861,8 +862,9 @@ void UDPStandardImplementation::setupFifoStructure(){ cout << "1 packet per buffer" << endl; else cout << "Number of Frames per buffer:" << numJobsPerThread << endl; +#ifdef VERBOSE cout << "Fifo Size:" << fifosize << endl; - +#endif /* //for testing numJobsPerThread = 3; fifosize = 11; @@ -1279,6 +1281,7 @@ int UDPStandardImplementation::setupWriter(){ //reset writing thread variables packetsInFile=0; + numTotMissingPackets = 0; numTotMissingPacketsInFile = 0; numMissingPackets = 0; packetsCaught=0; @@ -2042,9 +2045,9 @@ int UDPStandardImplementation::startWriting(){ //dont pop again if dummy packet if(!numpackets[i]){ popready[i] = false; -//#ifdef EIGER_DEBUG3 - cprintf(RED,"%d Dummy frame popped out of fifo %d",ithread, i); -//#endif +#ifdef EIGER_DEBUG3 + cprintf(GREEN,"%d Dummy frame popped out of fifo %d",ithread, i); +#endif }else{ if(myDetectorType == EIGER){ tofree[tofreeoffset[i]] = wbuf[i]; @@ -2059,24 +2062,26 @@ int UDPStandardImplementation::startWriting(){ //END OF ACQUISITION if((!numpackets[0])&& (!numpackets[1])){ -//#ifdef VERYDEBUG +#ifdef VERYDEBUG cprintf(GREEN,"%d Both dummy frames\n", ithread); -//#endif +#endif //remaning packets to be written if((myDetectorType == EIGER) && ((tempoffset[0]!=0) || (tempoffset[1]!=(packetsPerFrame/numListeningThreads)))){ -//#ifdef EIGER_DEBUG3 +#ifdef EIGER_DEBUG3 cprintf(RED,"**End of Acquisition but didnt get last packet\n"); -//#endif +#endif for(i=0;inum3)) == 0xFE) cprintf(RED,"1 fifo:%d missing packet added at pnum:%d\n",i,tempoffset[i]); - else cprintf(RED, "1 fifo:%d WEird at pnum:%d\n",i,tempoffset[i]); + else cprintf(RED, "1 fifo:%d Weird at pnum:%d\n",i,tempoffset[i]); +#endif tempoffset[i] ++; blankoffset ++; } @@ -2106,12 +2111,12 @@ int UDPStandardImplementation::startWriting(){ //offset outside boundaries, also eliminates dummy packet if((numpackets[i] != EIGER_HEADER_LENGTH) && (numpackets[i] != onePacketSize)){ +#ifdef EIGER_DEBUG3 if(numpackets[i]) cprintf(RED, "WARNING: Got a weird packet size: %d from fifo %d\n", numpackets[i],i); -//#ifdef VERBOSE else cprintf(RED, "WARNING: Dummy packet: %d from fifo %d\n", numpackets[i],i); -//#endif +#endif continue; } @@ -2130,26 +2135,30 @@ int UDPStandardImplementation::startWriting(){ //normal frame packet (also exception of tempnum 0 and currfnum 0) if((tempframenum[i] == (currframenum+1))||(!tempframenum[i] && !currframenum)){ -//#ifdef EIGER_DEBUG3 +#ifdef EIGER_DEBUG3 cprintf(GREEN,"**tempfraemnum of %d: %d\n",i,tempframenum[i]); -//#endif +#endif } //frame too far ahead else{ -//#ifdef EIGER_DEBUG3 +#ifdef EIGER_DEBUG3 cprintf(RED,"frame number too far ahead, missing packets\n"); -//#endif +#endif tempframenum[i] = currframenum + 1; //add missing packets numberofmissingpackets[i] = (LAST_PACKET_VALUE); +#ifdef VERYDEBUG if(numberofmissingpackets[i]>0) cprintf(BG_RED,"fifo:%d missing packet from: %d\n",i,lastpacketheader[i]); +#endif //to decrement from packetsInFile to calculate packet loss for(j=0;jnum3)) == 0xFE) cprintf(RED,"2 fifo:%d missing packet added at pnum:%d\n",i,tempoffset[i]); else cprintf(RED, "2 fifo:%d WEird at pnum:%d\n",i,tempoffset[i]); +#endif tempoffset[i] ++; blankoffset ++; @@ -2161,19 +2170,23 @@ int UDPStandardImplementation::startWriting(){ } }//two image headers at a time = next frame, leave else{ -//#ifdef EIGER_DEBUG3 +#ifdef EIGER_DEBUG3 cprintf(RED,"received frame header twice, missing packets\n"); -//#endif +#endif //add missing packets numberofmissingpackets[i] = (LAST_PACKET_VALUE - lastpacketheader[i]); +#ifdef VERYDEBUG if(numberofmissingpackets[i]>0) cprintf(BG_RED,"fifo:%d missing packet from: %d\n",i,lastpacketheader[i]); +#endif //to decrement from packetsInFile to calculate packet loss for(j=0;jnum3)) == 0xFE) cprintf(RED,"3 fifo:%d missing packet added at pnum:%d\n",i,tempoffset[i]); else cprintf(RED, "3 fifo:%d WEird at pnum:%d\n",i,tempoffset[i]); +#endif tempoffset[i] ++; blankoffset ++; } @@ -2187,21 +2200,25 @@ int UDPStandardImplementation::startWriting(){ startdatapacket[i] = true; //update current packet currentpacketheader[i] = ((*(uint8_t*)(((eiger_packet_header *)((char*)(wbuf[i] + HEADER_SIZE_NUM_TOT_PACKETS)))->num4))); -//#ifdef VERYVERBOSE +#ifdef VERYVERBOSE cprintf(GREEN,"**fifo:%d currentpacketheader: %d lastpacketheader %d tempoffset:%d\n",i,currentpacketheader[i],lastpacketheader[i], tempoffset[i]); -//#endif +#endif //same frame packet - continue building frame if(currentpacketheader[i] > lastpacketheader[i]){ //add missing packets numberofmissingpackets[i] = (currentpacketheader[i] - lastpacketheader[i] -1); +#ifdef VERYDEBUG if(numberofmissingpackets[i]>0) cprintf(BG_RED,"fifo:%d missing packet from: %d now at :%d tempoffset:%d\n",i,lastpacketheader[i],currentpacketheader[i],tempoffset[i]); +#endif //to decrement from packetsInFile to calculate packet loss for(j=0;jnum3)) == 0xFE) cprintf(RED,"4 fifo:%d missing packet added at pnum:%d\n",i,tempoffset[i]); else cprintf(RED, "4 fifo:%d WEird at pnum:%d\n",i,tempoffset[i]); +#endif tempoffset[i] ++; blankoffset ++; } @@ -2212,29 +2229,33 @@ int UDPStandardImplementation::startWriting(){ lastpacketheader[i] = currentpacketheader[i]; //last frame got, this will save time and also for last frames, it doesnt wait for stop receiver if(currentpacketheader[i] == LAST_PACKET_VALUE){ -//#ifdef EIGER_DEBUG3 +#ifdef EIGER_DEBUG3 cprintf(GREEN, "Got last packet\n"); -//#endif +#endif fullframe[i] = true; popready[i] = false; } } //next frame packet - leave else{ -//#ifdef EIGER_DEBUG3 +#ifdef EIGER_DEBUG3 cprintf(RED,"packet from next frame, missing packets\n"); -//#endif +#endif //add missing packets numberofmissingpackets[i] = (LAST_PACKET_VALUE - lastpacketheader[i]); +#ifdef VERYDEBUG if(numberofmissingpackets[i]>0) cprintf(BG_RED,"fifo:%d missing packet from: %d now at :%d\n",i,lastpacketheader[i],currentpacketheader[i]); +#endif //to decrement from packetsInFile to calculate packet loss for(j=0;jnum3)) == 0xFE) cprintf(RED,"5 fifo:%d missing packet added at pnum:%d\n",i,tempoffset[i]); else cprintf(RED, "5 fifo:%d WEird at pnum:%d\n",i,tempoffset[i]); +#endif tempoffset[i] ++; blankoffset ++; } @@ -2262,11 +2283,11 @@ int UDPStandardImplementation::startWriting(){ tempframenum[1]++; numMissingPackets += (numberofmissingpackets[0]+numberofmissingpackets[1]); numTotMissingPacketsInFile += numMissingPackets; - -//#ifdef EIGER_DEBUG2 + numTotMissingPackets += numMissingPackets; +#ifdef EIGER_DEBUG2 cprintf(GREEN,"**fnum:%d**\n",currframenum); -//#endif -//#ifdef EIGER_DEBUG3 +#endif +#ifdef EIGER_DEBUG3 if(numberofmissingpackets[0]) cprintf(RED, "fifo 0 missing packets:%d fnum:%d\n",numberofmissingpackets[0],currframenum); if(numberofmissingpackets[1]) @@ -2278,7 +2299,7 @@ int UDPStandardImplementation::startWriting(){ if ((*(uint8_t*)(((eiger_packet_header *)((char*)(tempbuffer[j])))->num3)) == 0xFE) cprintf(RED,"found the missing packet at pnum:%d\n",j); } -//#endif +#endif //write and copy to gui @@ -2301,9 +2322,9 @@ int UDPStandardImplementation::startWriting(){ -//#ifdef VERYDEBUG +#ifdef VERYDEBUG cprintf(GREEN,"finished freeing\n"); -//#endif +#endif //reset a few stuff for(int i=0;i= 0){ @@ -3062,13 +3085,13 @@ int UDPStandardImplementation::enableTenGiga(int enable){ bufferSize = (frameSize/EIGER_MAX_PORTS) + EIGER_HEADER_LENGTH;//everything one port gets (img header plus packets) maxPacketsPerFile = EIGER_MAX_FRAMES_PER_FILE * packetsPerFrame; - +#ifdef VERBOSE cout<<"packetsPerFrame:"< Date: Thu, 13 Aug 2015 14:46:57 +0200 Subject: [PATCH 119/474] need to chek --- .../src/UDPStandardImplementation.cpp | 377 +++++++++--------- 1 file changed, 198 insertions(+), 179 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 87fc042e0..374322684 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1702,7 +1702,7 @@ int UDPStandardImplementation::startListening(){ uint32_t lastframeheader;// for moench to check for all the packets in last frame char* tempchar = NULL; - + uint32_t prenum=0; while(1){ @@ -1720,7 +1720,7 @@ int UDPStandardImplementation::startListening(){ else maxBufferSize = 0; - + prenum=0; while((1<ReceiveDataOnly(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS, maxBufferSize); + if(rc == 1040){ + cprintf(YELLOW,"tempframenum[%d]:%d\n",ithread,((*(uint32_t*)(((eiger_packet_header *)((char*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS)))->num1)))); + cprintf(YELLOW,"packetnum[%d]:%d\n",ithread,((*(uint8_t*)(((eiger_packet_header *)((char*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS)))->num4)))); + + if(((*(uint32_t*)(((eiger_packet_header *)((char*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS)))->num1)))< prenum){ + cprintf(BG_RED, "framenumber weird:previous:%d\n",prenum); + exit(-1); + } + prenum = ((*(uint32_t*)(((eiger_packet_header *)((char*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS)))->num1))); + + } expected = maxBufferSize; #ifdef SOCKET_DEBUG }else{ @@ -1782,7 +1793,8 @@ int UDPStandardImplementation::startListening(){ //start indices for each start of scan/acquisition if((!measurementStarted) && (rc > 0)){ pthread_mutex_lock(&progress_mutex); - startFrameIndices(ithread, rc); + if(!measurementStarted) + startFrameIndices(ithread, rc); pthread_mutex_unlock(&progress_mutex); } @@ -1931,8 +1943,9 @@ int UDPStandardImplementation::startWriting(){ int xmax=0,ymax=0; int ret,i,j; + bool endofacquisition; int numpackets[numListeningThreads], nf; - bool startdatapacket[numListeningThreads],fullframe[numListeningThreads],popready[numListeningThreads]; + bool fullframe[numListeningThreads],popready[numListeningThreads]; uint32_t tempframenum[numListeningThreads]; int lastpacketheader[numListeningThreads], currentpacketheader[numListeningThreads]; int numberofmissingpackets[numListeningThreads]; @@ -1990,11 +2003,11 @@ int UDPStandardImplementation::startWriting(){ for(i=0;inum3)) = 0xFE; + (*(uint8_t*)(((eiger_packet_header *)((char*)(blankframe[i])))->num3)) = 0xFF; for(j=0;j<(onePacketSize-16);++j) (*((uint8_t*)((char*)(blankframe[i])+8+j))) = 0xFF; - if ((*(uint8_t*)(((eiger_packet_header *)((char*)(blankframe[i])))->num3)) != 0xFE){ + if ((*(uint8_t*)(((eiger_packet_header *)((char*)(blankframe[i])))->num3)) != 0xFF){ cprintf(RED,"blank frame not detected at %d: 0x%x\n",i,(*(uint8_t*)(((eiger_packet_header *)((char*)(blankframe[i])))->num3)) ); exit(-1); } @@ -2009,7 +2022,6 @@ int UDPStandardImplementation::startWriting(){ for(i=0;inum1)))); + cprintf(BLUE,"packetnum[%d]:%d\n",i,((*(uint8_t*)(((eiger_packet_header *)((char*)(wbuf[i] + HEADER_SIZE_NUM_TOT_PACKETS)))->num4)))); + + + }if(myDetectorType == EIGER){ tofree[tofreeoffset[i]] = wbuf[i]; tofreeoffset[i]++; } @@ -2061,36 +2080,15 @@ int UDPStandardImplementation::startWriting(){ //END OF ACQUISITION - if((!numpackets[0])&& (!numpackets[1])){ -#ifdef VERYDEBUG + if(endofacquisition){ +//#ifdef VERYDEBUG cprintf(GREEN,"%d Both dummy frames\n", ithread); -#endif - //remaning packets to be written +//#endif + //remaining packets to be written if((myDetectorType == EIGER) && - ((tempoffset[0]!=0) || (tempoffset[1]!=(packetsPerFrame/numListeningThreads)))){ -#ifdef EIGER_DEBUG3 - cprintf(RED,"**End of Acquisition but didnt get last packet\n"); -#endif - for(i=0;inum3)) == 0xFE) - cprintf(RED,"1 fifo:%d missing packet added at pnum:%d\n",i,tempoffset[i]); - else cprintf(RED, "1 fifo:%d Weird at pnum:%d\n",i,tempoffset[i]); -#endif - tempoffset[i] ++; - blankoffset ++; - } - //set fullframe and dont let fifo pop over it until written - fullframe[i] = true; - popready[i] = false; + ((tempoffset[0]!=0) || (tempoffset[1]!=(packetsPerFrame/numListeningThreads)))); + else{ - } - }else{ stopWriting(ithread,wbuf); continue; } @@ -2098,95 +2096,48 @@ int UDPStandardImplementation::startWriting(){ - - if(myDetectorType == EIGER){ - //trying to find a full frame + //NOT FULL FRAME if(!fullframe[0] || !fullframe[1]){ - - for(i=0;iheader_confirm))){ - - //new frame (no datapacket received yet), update frame num and corrected for fnum reset for scans - if(!startdatapacket[i]){ - tempframenum[i] = (htonl(*(unsigned int*)((eiger_image_header *)((char*)(wbuf[i] + HEADER_SIZE_NUM_TOT_PACKETS)))->fnum)); - if(!tempframenum[i]) - cprintf(RED,"**VERY WEIRD frame numbers for fifo %d: %d\n",i,tempframenum[i]); - tempframenum[i] += (startFrameIndex-1); - - //normal frame packet (also exception of tempnum 0 and currfnum 0) - if((tempframenum[i] == (currframenum+1))||(!tempframenum[i] && !currframenum)){ -#ifdef EIGER_DEBUG3 - cprintf(GREEN,"**tempfraemnum of %d: %d\n",i,tempframenum[i]); -#endif - } - //frame too far ahead - else{ -#ifdef EIGER_DEBUG3 - cprintf(RED,"frame number too far ahead, missing packets\n"); -#endif - tempframenum[i] = currframenum + 1; - //add missing packets - numberofmissingpackets[i] = (LAST_PACKET_VALUE); -#ifdef VERYDEBUG - if(numberofmissingpackets[i]>0) - cprintf(BG_RED,"fifo:%d missing packet from: %d\n",i,lastpacketheader[i]); -#endif - //to decrement from packetsInFile to calculate packet loss - for(j=0;jnum3)) == 0xFE) - cprintf(RED,"2 fifo:%d missing packet added at pnum:%d\n",i,tempoffset[i]); - else cprintf(RED, "2 fifo:%d WEird at pnum:%d\n",i,tempoffset[i]); -#endif - tempoffset[i] ++; - blankoffset ++; - - } - //set fullframe and dont let fifo pop over it until written - fullframe[i] = true; - popready[i] = false; - - } - }//two image headers at a time = next frame, leave - else{ -#ifdef EIGER_DEBUG3 - cprintf(RED,"received frame header twice, missing packets\n"); -#endif + //anything that is not a data packet of right size + if(numpackets[i] != onePacketSize){ + //header packet + if(numpackets[i] == EIGER_HEADER_LENGTH) continue; + //dummy packet + else if(!numpackets[i]){ +//#ifdef VERYDEBUG + cprintf(RED, "Dummy packet: %d from fifo %d\n", numpackets[i],i); +//#endif + cout<<"tempoffset["<0) - cprintf(BG_RED,"fifo:%d missing packet from: %d\n",i,lastpacketheader[i]); -#endif //to decrement from packetsInFile to calculate packet loss for(j=0;jnum3)) == 0xFE) - cprintf(RED,"3 fifo:%d missing packet added at pnum:%d\n",i,tempoffset[i]); - else cprintf(RED, "3 fifo:%d WEird at pnum:%d\n",i,tempoffset[i]); + if ((*(uint8_t*)(((eiger_packet_header *)((char*)(tempbuffer[tempoffset[i]])))->num3)) == 0xFF) + cprintf(RED,"1 fifo:%d missing packet added at pnum:%d\n",i,tempoffset[i]); + else cprintf(RED, "1 fifo:%d Weird at pnum:%d\n",i,tempoffset[i]); #endif + if ((*(uint8_t*)(((eiger_packet_header *)((char*)(tempbuffer[tempoffset[i]])))->num3)) != 0xFF){ + cprintf(BG_RED, "pnum mismatch num4 earlier2! i:%d pnum:%d fnum:%d num3:0x%x actual num3:0x%x\n", + i,tempoffset[i],tempframenum[i], + (*(uint8_t*)(((eiger_packet_header *)((char*)(tempbuffer[tempoffset[i]])))->num3)), + (*(uint8_t*)(((eiger_packet_header *)((char*)(blankframe[blankoffset])))->num3))); + exit(-1); + }else + cprintf(GREEN, "blank packet i:%d pnum:%d fnum:%d num3:0x%x\n",i,tempoffset[i],tempframenum[i],(*(uint8_t*)(((eiger_packet_header *)((char*)(tempbuffer[tempoffset[i]])))->num3))); + tempoffset[i] ++; blankoffset ++; } @@ -2195,83 +2146,142 @@ int UDPStandardImplementation::startWriting(){ popready[i] = false; } } - //DATA PACKET +//#ifdef EIGER_DEBUG3 else{ - startdatapacket[i] = true; - //update current packet - currentpacketheader[i] = ((*(uint8_t*)(((eiger_packet_header *)((char*)(wbuf[i] + HEADER_SIZE_NUM_TOT_PACKETS)))->num4))); -#ifdef VERYVERBOSE - cprintf(GREEN,"**fifo:%d currentpacketheader: %d lastpacketheader %d tempoffset:%d\n",i,currentpacketheader[i],lastpacketheader[i], tempoffset[i]); -#endif - //same frame packet - continue building frame - if(currentpacketheader[i] > lastpacketheader[i]){ - //add missing packets - numberofmissingpackets[i] = (currentpacketheader[i] - lastpacketheader[i] -1); -#ifdef VERYDEBUG - if(numberofmissingpackets[i]>0) - cprintf(BG_RED,"fifo:%d missing packet from: %d now at :%d tempoffset:%d\n",i,lastpacketheader[i],currentpacketheader[i],tempoffset[i]); -#endif - //to decrement from packetsInFile to calculate packet loss - for(j=0;jnum3)) == 0xFE) - cprintf(RED,"4 fifo:%d missing packet added at pnum:%d\n",i,tempoffset[i]); - else cprintf(RED, "4 fifo:%d WEird at pnum:%d\n",i,tempoffset[i]); -#endif - tempoffset[i] ++; - blankoffset ++; - } - //add current packet - tempbuffer[tempoffset[i]] = wbuf[i] + HEADER_SIZE_NUM_TOT_PACKETS; - tempoffset[i] ++; - //update last packet - lastpacketheader[i] = currentpacketheader[i]; - //last frame got, this will save time and also for last frames, it doesnt wait for stop receiver - if(currentpacketheader[i] == LAST_PACKET_VALUE){ -#ifdef EIGER_DEBUG3 - cprintf(GREEN, "Got last packet\n"); -#endif - fullframe[i] = true; - popready[i] = false; - } - } - //next frame packet - leave - else{ -#ifdef EIGER_DEBUG3 - cprintf(RED,"packet from next frame, missing packets\n"); -#endif + cprintf(RED, "WARNING: Got a weird packet size: %d from fifo %d\n", numpackets[i],i); + continue; + } +//#endif + } + + + + + //not a full frame + if(!fullframe[i]){ + + //update frame number + //tempframenum[i] = (htonl(*(uint32_t*)(((eiger_packet_header *)((char*)(wbuf[i] + HEADER_SIZE_NUM_TOT_PACKETS)))->num1))); + tempframenum[i] = ((*(uint32_t*)(((eiger_packet_header *)((char*)(wbuf[i] + HEADER_SIZE_NUM_TOT_PACKETS)))->num1))); + + + if(!tempframenum[i]) + cprintf(RED,"**VERY WEIRD frame numbers for fifo %d: %d\n",i,tempframenum[i]); + tempframenum[i] += (startFrameIndex-1); + + + //WRONG FRAME - leave (also includes exception of tempnum 0 and currfnum 0) + if((tempframenum[i] != (currframenum+1))&&(tempframenum[i] || currframenum)){cout<<"wrong packet"<num1))), + ((*(uint8_t*)(((eiger_packet_header *)((char*)(wbuf[i] + HEADER_SIZE_NUM_TOT_PACKETS)))->num4)))); +//#endif + tempframenum[i] = currframenum+1; //add missing packets numberofmissingpackets[i] = (LAST_PACKET_VALUE - lastpacketheader[i]); #ifdef VERYDEBUG if(numberofmissingpackets[i]>0) - cprintf(BG_RED,"fifo:%d missing packet from: %d now at :%d\n",i,lastpacketheader[i],currentpacketheader[i]); + cprintf(BG_RED,"fifo:%d missing packet from: %d now\n",i,lastpacketheader[i]); #endif //to decrement from packetsInFile to calculate packet loss for(j=0;jnum3)) == 0xFE) + if ((*(uint8_t*)(((eiger_packet_header *)((char*)(tempbuffer[tempoffset[i]])))->num3)) == 0xFF) cprintf(RED,"5 fifo:%d missing packet added at pnum:%d\n",i,tempoffset[i]); else cprintf(RED, "5 fifo:%d WEird at pnum:%d\n",i,tempoffset[i]); #endif + if ((*(uint8_t*)(((eiger_packet_header *)((char*)(tempbuffer[tempoffset[i]])))->num3)) != 0xFF){ + cprintf(BG_RED, "pnum mismatch num4 earlier2! i:%d pnum:%d fnum:%d num3:0x%x actual num3:0x%x\n", + i,tempoffset[i],tempframenum[i], + (*(uint8_t*)(((eiger_packet_header *)((char*)(tempbuffer[tempoffset[i]])))->num3)), + (*(uint8_t*)(((eiger_packet_header *)((char*)(blankframe[blankoffset])))->num3))); + exit(-1); + }else + cprintf(GREEN, "blank packet i:%d pnum:%d fnum:%d num3:0x%x\n",i,tempoffset[i],tempframenum[i],(*(uint8_t*)(((eiger_packet_header *)((char*)(tempbuffer[tempoffset[i]])))->num3))); + tempoffset[i] ++; blankoffset ++; } //set fullframe and dont let fifo pop over it until written fullframe[i] = true; popready[i] = false; + } + + + //CORRECT FRAME - continue building frame + else {cout<<"correct packet"<num4))); +//#ifdef VERYVERBOSE + cprintf(GREEN,"**fifo:%d currentpacketheader: %d lastpacketheader %d tempoffset:%d\n",i,currentpacketheader[i],lastpacketheader[i], tempoffset[i]); +//#endif + //add missing packets + numberofmissingpackets[i] = (currentpacketheader[i] - lastpacketheader[i] -1); +#ifdef VERYDEBUG + if(numberofmissingpackets[i]>0) + cprintf(BG_RED,"fifo:%d missing packet from: %d now at :%d tempoffset:%d\n",i,lastpacketheader[i],currentpacketheader[i],tempoffset[i]); +#endif + //to decrement from packetsInFile to calculate packet loss + for(j=0;jnum3)) == 0xFF) + cprintf(RED,"4 fifo:%d missing packet added at pnum:%d\n",i,tempoffset[i]); + else cprintf(RED, "4 fifo:%d WEird at pnum:%d\n",i,tempoffset[i]); +#endif + if ((*(uint8_t*)(((eiger_packet_header *)((char*)(tempbuffer[tempoffset[i]])))->num3)) != 0xFF){ + cprintf(BG_RED, "pnum mismatch num4 earlier2! i:%d pnum:%d fnum:%d num3:0x%x actual num3:0x%x\n", + i,tempoffset[i],tempframenum[i], + (*(uint8_t*)(((eiger_packet_header *)((char*)(tempbuffer[tempoffset[i]])))->num3)), + (*(uint8_t*)(((eiger_packet_header *)((char*)(blankframe[blankoffset])))->num3))); + exit(-1); + }else + cprintf(GREEN, "blank packet i:%d pnum:%d fnum:%d num3:0x%x\n",i,tempoffset[i],tempframenum[i],(*(uint8_t*)(((eiger_packet_header *)((char*)(tempbuffer[tempoffset[i]])))->num3))); + tempoffset[i] ++; + blankoffset ++; + } + //add current packet + + if(currentpacketheader[i] != (tempoffset[i]-(i*packetsPerFrame/numListeningThreads))){ + cprintf(BG_RED, "pnum mismatch earlier! tempoffset[%d]:%d pnum:%d fnum:%d\n",i,tempoffset[i],currentpacketheader[i],tempframenum[i]); + exit(-1); + } + tempbuffer[tempoffset[i]] = wbuf[i] + HEADER_SIZE_NUM_TOT_PACKETS; +#ifdef EIGER_DEBUG3 + cprintf(GREEN,"**fifo:%d currentpacketheader: %d tempoffset:%d\n",i,(*(uint8_t*)(((eiger_packet_header *)((char*)(tempbuffer[tempoffset[i]])))->num4)),tempoffset[i]); +#endif + if((*(uint8_t*)(((eiger_packet_header *)((char*)(tempbuffer[tempoffset[i]])))->num4)) != (tempoffset[i]-(i*packetsPerFrame/numListeningThreads))){ + cprintf(BG_RED, "pnum mismatch num4 earlier! i:%d pnum:%d fnum:%d\n",i,(*(uint8_t*)(((eiger_packet_header *)((char*)(tempbuffer[tempoffset[i]])))->num4)),tempframenum[i]); + exit(-1); + } + cprintf(GREEN, "normal packet i:%d pnum:%d fnum:%d num3:0x%x\n",i,tempoffset[i],tempframenum[i],(*(uint8_t*)(((eiger_packet_header *)((char*)(tempbuffer[tempoffset[i]])))->num3))); + tempoffset[i] ++; + //update last packet + lastpacketheader[i] = currentpacketheader[i]; + popready[i] = true; + //last frame got, this will save time and also for last frames, it doesnt wait for stop receiver + if(currentpacketheader[i] == LAST_PACKET_VALUE){ +#ifdef EIGER_DEBUG3 + cprintf(GREEN, "Got last packet\n"); +#endif + fullframe[i] = true; + popready[i] = false; } } } - } } - //check if a full frame received + //FULL FRAME if(fullframe[0] && fullframe[1]){ //determine frame number @@ -2284,9 +2294,9 @@ int UDPStandardImplementation::startWriting(){ numMissingPackets += (numberofmissingpackets[0]+numberofmissingpackets[1]); numTotMissingPacketsInFile += numMissingPackets; numTotMissingPackets += numMissingPackets; -#ifdef EIGER_DEBUG2 - cprintf(GREEN,"**fnum:%d**\n",currframenum); -#endif +//#ifdef EIGER_DEBUG2 + cprintf(GREEN,"**fnum:%d**\n",currframenum); +//#endif #ifdef EIGER_DEBUG3 if(numberofmissingpackets[0]) cprintf(RED, "fifo 0 missing packets:%d fnum:%d\n",numberofmissingpackets[0],currframenum); @@ -2296,7 +2306,7 @@ int UDPStandardImplementation::startWriting(){ cprintf(RED, "numMissingPackets:%d fnum:%d\n",numMissingPackets,currframenum); for (j=0;jnum3)) == 0xFE) + if ((*(uint8_t*)(((eiger_packet_header *)((char*)(tempbuffer[j])))->num3)) == 0xFF) cprintf(RED,"found the missing packet at pnum:%d\n",j); } #endif @@ -2319,12 +2329,10 @@ int UDPStandardImplementation::startWriting(){ cprintf(GREEN,"%d writer freed pushed into fifofree %x for listener %d\n",ithread, (void*)(tofree[j]),1); #endif } - - - -#ifdef VERYDEBUG +//#ifdef VERYDEBUG cprintf(GREEN,"finished freeing\n"); -#endif +//#endif + //reset a few stuff for(int i=0;ifnum))-1; //missed header packet, so default value else - startFrameIndex = 0; + startFrameIndex = ((*(uint32_t*)(((eiger_packet_header *)((char*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS)))->num1))-1); + cout<<"startFrameIndex["<push(wbuffer[i])); @@ -2853,14 +2862,23 @@ void UDPStandardImplementation::handleWithoutDataCompression(int ithread, char* //which port if (i ==(packetsPerFrame/2)) port = 1; + + + //missing packet - if ((*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num3)) == 0xFE){ + if ((*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num3)) == 0xFF){ missingpacket = 1; //add packet numbers (*(uint16_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num2)) = (i+1); }else{ missingpacket = 0; + if((*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num4)) != (i-(port*packetsPerFrame/numListeningThreads))){ + cprintf(BG_RED, "pnum mismatch num4! i:%d pnum:%d fnum:%d\n",i,(*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num4)),currframenum); + exit(-1); + } + + if(dynamicRange != 32){ //move packet numbers to num2, and compensate for port1 starting pnum from 0 if(!port) @@ -2889,7 +2907,7 @@ void UDPStandardImplementation::handleWithoutDataCompression(int ithread, char* if((*(uint16_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num2)) != (i+1)){ cprintf(BG_RED, "pnum mismatch! i:%d pnum:%d fnum:%d\n",i,(*(uint16_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num2)),currframenum); - if ((*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num3)) == 0xFE) + if ((*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num3)) == 0xFF) cprintf(BG_RED,"missing packet though\n"); exit(-1); } @@ -2898,8 +2916,9 @@ void UDPStandardImplementation::handleWithoutDataCompression(int ithread, char* (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num3)) = ((dynamicRange<<2)|(missingpacket<<1)|(port)); + //frame number - (*(uint32_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num1)) = currframenum; + //(*(uint32_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num1)) = currframenum; #ifdef VERYDEBUG if((i==0)||(i==1)){ From 80f33997d41d76652a8fbe2bcf56ddfa34562600 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Mon, 17 Aug 2015 15:37:28 +0200 Subject: [PATCH 120/474] almost works test stage still --- .../src/UDPStandardImplementation.cpp | 73 +++++++++---------- 1 file changed, 35 insertions(+), 38 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 374322684..3d3c1f4c9 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -894,7 +894,7 @@ void UDPStandardImplementation::setupFifoStructure(){ mem0[i]=(char*)malloc((whatperbuffer * numJobsPerThread + HEADER_SIZE_NUM_TOT_PACKETS)*fifosize); /** shud let the client know about this */ if (mem0[i]==NULL){ - cout<<"++++++++++++++++++++++ COULD NOT ALLOCATE MEMORY FOR LISTENING !!!!!!!+++++++++++++++++++++" << endl; + cprintf(BG_RED,"++++++++++++++++++++++ COULD NOT ALLOCATE MEMORY FOR LISTENING !!!!!!!+++++++++++++++++++++\n"); exit(-1); } @@ -1720,8 +1720,6 @@ int UDPStandardImplementation::startListening(){ else maxBufferSize = 0; - prenum=0; - while((1<ReceiveDataOnly(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS, maxBufferSize); - if(rc == 1040){ - cprintf(YELLOW,"tempframenum[%d]:%d\n",ithread,((*(uint32_t*)(((eiger_packet_header *)((char*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS)))->num1)))); - cprintf(YELLOW,"packetnum[%d]:%d\n",ithread,((*(uint8_t*)(((eiger_packet_header *)((char*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS)))->num4)))); - - if(((*(uint32_t*)(((eiger_packet_header *)((char*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS)))->num1)))< prenum){ - cprintf(BG_RED, "framenumber weird:previous:%d\n",prenum); - exit(-1); - } - prenum = ((*(uint32_t*)(((eiger_packet_header *)((char*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS)))->num1))); - + if(rc == EIGER_HEADER_LENGTH && myDetectorType == EIGER) { + while(rc == EIGER_HEADER_LENGTH) + rc = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS, maxBufferSize); } expected = maxBufferSize; #ifdef SOCKET_DEBUG @@ -1947,7 +1938,8 @@ int UDPStandardImplementation::startWriting(){ int numpackets[numListeningThreads], nf; bool fullframe[numListeningThreads],popready[numListeningThreads]; uint32_t tempframenum[numListeningThreads]; - int lastpacketheader[numListeningThreads], currentpacketheader[numListeningThreads]; + uint32_t presentframenum; + uint32_t lastpacketheader[numListeningThreads], currentpacketheader[numListeningThreads]; int numberofmissingpackets[numListeningThreads]; int MAX_VALUE = 1024; @@ -2033,7 +2025,7 @@ int UDPStandardImplementation::startWriting(){ tempframenum[i] = 0; } endofacquisition = false; - + presentframenum = 0; while((1<pop(wbuf[i]); #ifdef FIFO_DEBUG cprintf(GREEN,"%d writer poped 0x%x from fifo %d\n", ithread, (void*)(wbuf[i]), i); @@ -2055,8 +2044,12 @@ int UDPStandardImplementation::startWriting(){ #ifdef VERYDEBUG cprintf(GREEN,"%d numpackets: %d for fifo :%d\n", ithread, numpackets[i], i); #endif + if(numpackets < 0){ + cprintf(BG_RED,"negative numpackets[%d]%d\n",i,numpackets[i]); + exit(-1); + } //dont pop again if dummy packet - if(!numpackets[i]){ + else if(numpackets[i] == 0){ popready[i] = false; //#ifdef EIGER_DEBUG3 cprintf(GREEN,"%d Dummy frame popped out of fifo %d",ithread, i); @@ -2066,9 +2059,12 @@ int UDPStandardImplementation::startWriting(){ if(numpackets[i] == 1040){ cprintf(BLUE,"tempframenum[%d]:%d\n",i,((*(uint32_t*)(((eiger_packet_header *)((char*)(wbuf[i] + HEADER_SIZE_NUM_TOT_PACKETS)))->num1)))); cprintf(BLUE,"packetnum[%d]:%d\n",i,((*(uint8_t*)(((eiger_packet_header *)((char*)(wbuf[i] + HEADER_SIZE_NUM_TOT_PACKETS)))->num4)))); + }else if(numpackets[i] == EIGER_HEADER_LENGTH){ + cprintf(BG_RED, "got header in writer, weirdd packetsize:%d\n",numpackets[i]); + exit(-1); + } - - }if(myDetectorType == EIGER){ + if(myDetectorType == EIGER){ tofree[tofreeoffset[i]] = wbuf[i]; tofreeoffset[i]++; } @@ -2107,7 +2103,7 @@ int UDPStandardImplementation::startWriting(){ //anything that is not a data packet of right size if(numpackets[i] != onePacketSize){ //header packet - if(numpackets[i] == EIGER_HEADER_LENGTH) continue; + if(numpackets[i] == EIGER_HEADER_LENGTH) {cprintf(BG_RED,"weird, frame packet recieved\n"); exit(-1);} //dummy packet else if(!numpackets[i]){ //#ifdef VERYDEBUG @@ -2130,7 +2126,7 @@ int UDPStandardImplementation::startWriting(){ else cprintf(RED, "1 fifo:%d Weird at pnum:%d\n",i,tempoffset[i]); #endif if ((*(uint8_t*)(((eiger_packet_header *)((char*)(tempbuffer[tempoffset[i]])))->num3)) != 0xFF){ - cprintf(BG_RED, "pnum mismatch num4 earlier2! i:%d pnum:%d fnum:%d num3:0x%x actual num3:0x%x\n", + cprintf(BG_RED, "dummy blank mismatch num4 earlier2! i:%d pnum:%d fnum:%d num3:0x%x actual num3:0x%x\n", i,tempoffset[i],tempframenum[i], (*(uint8_t*)(((eiger_packet_header *)((char*)(tempbuffer[tempoffset[i]])))->num3)), (*(uint8_t*)(((eiger_packet_header *)((char*)(blankframe[blankoffset])))->num3))); @@ -2171,15 +2167,15 @@ int UDPStandardImplementation::startWriting(){ tempframenum[i] += (startFrameIndex-1); - //WRONG FRAME - leave (also includes exception of tempnum 0 and currfnum 0) - if((tempframenum[i] != (currframenum+1))&&(tempframenum[i] || currframenum)){cout<<"wrong packet"<num1))), ((*(uint8_t*)(((eiger_packet_header *)((char*)(wbuf[i] + HEADER_SIZE_NUM_TOT_PACKETS)))->num4)))); //#endif - tempframenum[i] = currframenum+1; + tempframenum[i] = presentframenum; //add missing packets numberofmissingpackets[i] = (LAST_PACKET_VALUE - lastpacketheader[i]); #ifdef VERYDEBUG @@ -2195,7 +2191,7 @@ int UDPStandardImplementation::startWriting(){ else cprintf(RED, "5 fifo:%d WEird at pnum:%d\n",i,tempoffset[i]); #endif if ((*(uint8_t*)(((eiger_packet_header *)((char*)(tempbuffer[tempoffset[i]])))->num3)) != 0xFF){ - cprintf(BG_RED, "pnum mismatch num4 earlier2! i:%d pnum:%d fnum:%d num3:0x%x actual num3:0x%x\n", + cprintf(BG_RED, "wrong blank mismatch num4 earlier2! i:%d pnum:%d fnum:%d num3:0x%x actual num3:0x%x\n", i,tempoffset[i],tempframenum[i], (*(uint8_t*)(((eiger_packet_header *)((char*)(tempbuffer[tempoffset[i]])))->num3)), (*(uint8_t*)(((eiger_packet_header *)((char*)(blankframe[blankoffset])))->num3))); @@ -2237,7 +2233,7 @@ int UDPStandardImplementation::startWriting(){ else cprintf(RED, "4 fifo:%d WEird at pnum:%d\n",i,tempoffset[i]); #endif if ((*(uint8_t*)(((eiger_packet_header *)((char*)(tempbuffer[tempoffset[i]])))->num3)) != 0xFF){ - cprintf(BG_RED, "pnum mismatch num4 earlier2! i:%d pnum:%d fnum:%d num3:0x%x actual num3:0x%x\n", + cprintf(BG_RED, "correct blank mismatch num4 earlier2! i:%d pnum:%d fnum:%d num3:0x%x actual num3:0x%x\n", i,tempoffset[i],tempframenum[i], (*(uint8_t*)(((eiger_packet_header *)((char*)(tempbuffer[tempoffset[i]])))->num3)), (*(uint8_t*)(((eiger_packet_header *)((char*)(blankframe[blankoffset])))->num3))); @@ -2250,7 +2246,7 @@ int UDPStandardImplementation::startWriting(){ //add current packet if(currentpacketheader[i] != (tempoffset[i]-(i*packetsPerFrame/numListeningThreads))){ - cprintf(BG_RED, "pnum mismatch earlier! tempoffset[%d]:%d pnum:%d fnum:%d\n",i,tempoffset[i],currentpacketheader[i],tempframenum[i]); + cprintf(BG_RED, "correct pnum mismatch earlier! tempoffset[%d]:%d pnum:%d fnum:%d rfnum:%d\n",i,tempoffset[i],currentpacketheader[i],tempframenum[i],(*(uint32_t*)(((eiger_packet_header *)((char*)(wbuf[i])))->num1))); exit(-1); } tempbuffer[tempoffset[i]] = wbuf[i] + HEADER_SIZE_NUM_TOT_PACKETS; @@ -2288,9 +2284,9 @@ int UDPStandardImplementation::startWriting(){ if(tempframenum[0] != tempframenum[1]) cprintf(RED,"Frame numbers mismatch!!! %d %d\n",tempframenum[0],tempframenum[1]); currframenum = tempframenum[0]; - //to resolve for missing frame packets + /*//to resolve for missing frame packets tempframenum[0]++; - tempframenum[1]++; + tempframenum[1]++;*/ numMissingPackets += (numberofmissingpackets[0]+numberofmissingpackets[1]); numTotMissingPacketsInFile += numMissingPackets; numTotMissingPackets += numMissingPackets; @@ -2335,10 +2331,11 @@ int UDPStandardImplementation::startWriting(){ //reset a few stuff + presentframenum = tempframenum[0]+1; for(int i=0;inum4)) != (i-(port*packetsPerFrame/numListeningThreads))){ cprintf(BG_RED, "pnum mismatch num4! i:%d pnum:%d fnum:%d\n",i,(*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num4)),currframenum); - exit(-1); + /* exit(-1);*/ } @@ -2909,7 +2906,7 @@ void UDPStandardImplementation::handleWithoutDataCompression(int ithread, char* cprintf(BG_RED, "pnum mismatch! i:%d pnum:%d fnum:%d\n",i,(*(uint16_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num2)),currframenum); if ((*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num3)) == 0xFF) cprintf(BG_RED,"missing packet though\n"); - exit(-1); + /*exit(-1);*/ } //overwriting port number and dynamic range From e8a5f8108347081449eaf3231a7cba73ccd685ec Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Wed, 19 Aug 2015 14:32:08 +0200 Subject: [PATCH 121/474] moving to fix another branch --- .../src/UDPStandardImplementation.cpp | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 3d3c1f4c9..0d4eab84b 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1751,7 +1751,11 @@ int UDPStandardImplementation::startListening(){ if(rc == EIGER_HEADER_LENGTH && myDetectorType == EIGER) { while(rc == EIGER_HEADER_LENGTH) rc = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS, maxBufferSize); - } + }/* + if(rc == 1040){ + cprintf(YELLOW,"tempframenum[%d]:%d\n",ithread,((*(uint32_t*)(((eiger_packet_header *)((char*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS)))->num1)))); + cprintf(YELLOW,"packetnum[%d]:%d\n",ithread,((*(uint8_t*)(((eiger_packet_header *)((char*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS)))->num4)))); + }*/ expected = maxBufferSize; #ifdef SOCKET_DEBUG }else{ @@ -2768,17 +2772,17 @@ void UDPStandardImplementation::writeToFile_withoutCompression(char* buf[],int n }else fwrite(buf[0]+offset, 1, packetsToSave * onePacketSize, sfilefd); packetsInFile += packetsToSave; -#ifdef EIGER_DEBUG3 +//#ifdef EIGER_DEBUG3 cprintf(GREEN,"packetscaught earlier:%d packetstosave:%d numMissingPackets:%d addingon:%d\n", packetsCaught,packetsToSave,numMissingPackets,(packetsToSave - numMissingPackets)); -#endif +//#endif packetsCaught += (packetsToSave - numMissingPackets); totalPacketsCaught += (packetsToSave - numMissingPackets); numMissingPackets = 0; -#ifdef EIGER_DEBUG3 +//#ifdef EIGER_DEBUG3 cprintf(GREEN,"packetscaught:%d\n", packetsCaught); cprintf(GREEN,"totalPacketsCaught:%d\n", totalPacketsCaught); -#endif +//#endif //new file if(packetsInFile >= maxPacketsPerFile){ @@ -2867,12 +2871,13 @@ void UDPStandardImplementation::handleWithoutDataCompression(int ithread, char* missingpacket = 1; //add packet numbers (*(uint16_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num2)) = (i+1); + (*(uint32_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num1)) = currframenum; }else{ missingpacket = 0; if((*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num4)) != (i-(port*packetsPerFrame/numListeningThreads))){ cprintf(BG_RED, "pnum mismatch num4! i:%d pnum:%d fnum:%d\n",i,(*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num4)),currframenum); - /* exit(-1);*/ + exit(-1); } @@ -2906,7 +2911,7 @@ void UDPStandardImplementation::handleWithoutDataCompression(int ithread, char* cprintf(BG_RED, "pnum mismatch! i:%d pnum:%d fnum:%d\n",i,(*(uint16_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num2)),currframenum); if ((*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num3)) == 0xFF) cprintf(BG_RED,"missing packet though\n"); - /*exit(-1);*/ + exit(-1); } //overwriting port number and dynamic range @@ -2938,9 +2943,9 @@ void UDPStandardImplementation::handleWithoutDataCompression(int ithread, char* writeToFile_withoutCompression(wbuffer, npackets,currframenum); } -#ifdef VERYDEBUG +//#ifdef VERYDEBUG cprintf(GREEN,"written everyting\n"); -#endif +//#endif } From 5dd5c250f3c30593706dd67f3ed8c80a6440443d Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Wed, 19 Aug 2015 14:55:15 +0200 Subject: [PATCH 122/474] removing unnecessary prints --- slsReceiverSoftware/include/genericSocket.h | 30 +++---------------- .../src/UDPBaseImplementation.cpp | 2 -- .../src/UDPStandardImplementation.cpp | 19 ++++++------ 3 files changed, 13 insertions(+), 38 deletions(-) diff --git a/slsReceiverSoftware/include/genericSocket.h b/slsReceiverSoftware/include/genericSocket.h index 3bb4adcff..aa79f3233 100644 --- a/slsReceiverSoftware/include/genericSocket.h +++ b/slsReceiverSoftware/include/genericSocket.h @@ -60,7 +60,6 @@ class sockaddr_in; #include #endif -#include "ansi.h" #include /******exit */ #include @@ -71,7 +70,6 @@ class sockaddr_in; #include #include -#include //SIGINT using namespace std; @@ -127,7 +125,6 @@ typedef struct struct hostent *hostInfo = gethostbyname(host_ip_or_name); if (hostInfo == NULL){ cerr << "Exiting: Problem interpreting host: " << host_ip_or_name << "\n"; - cprintf(RED,"Exiting: Problem interpreting host:%s\n",host_ip_or_name); } else { // Set some fields in the serverAddress structure. serverAddress.sin_family = hostInfo->h_addrtype; @@ -137,7 +134,6 @@ typedef struct socketDescriptor=0; //You can use send and recv, //would it work????? } clientAddress_length=sizeof(clientAddress); - cprintf(MAGENTA, "client socket created %d \n",socketDescriptor,protocol); } @@ -180,7 +176,6 @@ typedef struct nsent(0), total_sent(0) { - signal(SIGCHLD,SIG_IGN); //memset(&serverAddress, 0, sizeof(sockaddr_in)); // memset(&clientAddress, 0, sizeof(sockaddr_in)); // serverAddress = {0}; @@ -210,12 +205,10 @@ typedef struct socketDescriptor = socket(AF_INET, getProtocol(),0); //tcp - cprintf(MAGENTA, "socket created %d protocol:%d\n",socketDescriptor,protocol); if (socketDescriptor < 0) { cerr << "Can not create socket "<0) { if ((file_des = accept(socketDescriptor,(struct sockaddr *) &clientAddress, &clientAddress_length)) < 0) { cerr << "Error: with server accept, connection refused"<=0){ @@ -459,16 +443,10 @@ typedef struct if(file_des>=0){ //then was open if(is_a_server){ - // cprintf(MAGENTA, "file_des disconnected %d \n",file_des); - if(close(file_des)) - cprintf(RED,"file_des not disconnected %d\n", file_des); - // cprintf(MAGENTA, "file_des disconnected %d \n",file_des); + close(file_des); } else { - //cprintf(MAGENTA, "socketDescriptor disconnected %d \n",socketDescriptor); - if(close(socketDescriptor)) - cprintf(RED,"socketDescriptor not disconnected %d\n", file_des); - // cprintf(MAGENTA, "socketDescriptor disconnected %d \n",socketDescriptor); + close(socketDescriptor); socketDescriptor=-1; } file_des=-1; diff --git a/slsReceiverSoftware/src/UDPBaseImplementation.cpp b/slsReceiverSoftware/src/UDPBaseImplementation.cpp index 80ce6b2c7..670805a46 100644 --- a/slsReceiverSoftware/src/UDPBaseImplementation.cpp +++ b/slsReceiverSoftware/src/UDPBaseImplementation.cpp @@ -746,7 +746,6 @@ int UDPBaseImplementation::createUDPSockets(){ FILE_LOG(logDEBUG) << __AT__ << " cout<<"warning:eth is empty.listening to all"<getErrorStatus(); if(!iret){ cout << "UDP port opened at port " << port[i] << endl; - cprintf(YELLOW, "socket of port %d descriptor:%d\n",i,udpSocket[i]->getsocketDescriptor()); + //cprintf(YELLOW, "socket of port %d descriptor:%d\n",i,udpSocket[i]->getsocketDescriptor()); }else{ #ifdef VERBOSE cprintf(BG_RED,"Could not create UDP socket on port %d error: %d\n", port[i], iret); @@ -1411,7 +1411,7 @@ int UDPStandardImplementation::createNewFile(){ //close if(sfilefd){ if(fclose(sfilefd)){ - cprintf(YELLOW, "file clsoe problem %d\n",fileno(sfilefd)); + cprintf(RED, "file close problem %d\n",fileno(sfilefd)); fclose(sfilefd); } sfilefd = NULL; @@ -1430,9 +1430,8 @@ int UDPStandardImplementation::createNewFile(){ //setting buffer setvbuf(sfilefd,NULL,_IOFBF,BUF_SIZE); - cprintf(YELLOW, "file value:%d\n",fileno(sfilefd)); + //cprintf(YELLOW, "file value:%d\n",fileno(sfilefd)); - //cprintf(YELLOW, "file valuex:%d",(int)sfilefd); //printing packet losses and file names if(!packetsCaught) cout << savefilename << endl; @@ -1474,12 +1473,12 @@ void UDPStandardImplementation::closeFile(int ithr){ if(!dataCompression){ if(sfilefd){ -//#ifdef VERBOSE +#ifdef VERBOSE cprintf(YELLOW, "gonna close file:%d\n",fileno(sfilefd)); -//#endif +#endif if(fclose(sfilefd)) - perror("close ERRROR"); - cprintf(YELLOW, "check close file:%d\n",fileno(sfilefd)); + perror("file close ERROR"); + //cprintf(YELLOW, "check close file:%d\n",fileno(sfilefd)); sfilefd = NULL; } } From 587d357f3ee94ae5c75c0577b8f6826b2805d286 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Wed, 19 Aug 2015 15:47:24 +0200 Subject: [PATCH 123/474] resetting frame index for scans for eiger --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index bb7241665..bebb7ad5e 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -2187,11 +2187,8 @@ void UDPStandardImplementation::startFrameIndices(int ithread){ FILE_LOG(logDEBUG) << __AT__ << " called"; if (myDetectorType == EIGER){ - //add currframenum later in this method for scans - /*if(dynamicRange == 32) - startFrameIndex = htonl(*(unsigned int*)((eiger_image_header32 *)((char*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS)))->fnum); - else*/ - startFrameIndex = htonl(*(unsigned int*)((eiger_image_header *)((char*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS)))->fnum); + startFrameIndex = 0; + /*startFrameIndex = htonl(*(unsigned int*)((eiger_image_header *)((char*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS)))->fnum);*/ } //gotthard has +1 for frame number and not a short frame else if ((myDetectorType == PROPIX) || ((myDetectorType == GOTTHARD) && (shortFrame == -1))) @@ -2209,6 +2206,7 @@ void UDPStandardImplementation::startFrameIndices(int ithread){ acqStarted = true; cout << "startAcquisitionIndex:" << hex << startAcquisitionIndex< Date: Thu, 20 Aug 2015 10:17:36 +0200 Subject: [PATCH 124/474] changed startframeindex to 1 as thats whats written to file in eiger --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index bebb7ad5e..683b6a9f9 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -2187,7 +2187,7 @@ void UDPStandardImplementation::startFrameIndices(int ithread){ FILE_LOG(logDEBUG) << __AT__ << " called"; if (myDetectorType == EIGER){ - startFrameIndex = 0; + startFrameIndex = 1; /*startFrameIndex = htonl(*(unsigned int*)((eiger_image_header *)((char*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS)))->fnum);*/ } //gotthard has +1 for frame number and not a short frame From a29da27a42e83bb98090f5ada84cebc2d13812c7 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Thu, 20 Aug 2015 17:36:41 +0200 Subject: [PATCH 125/474] works without problems except bottom doesnt get much for acquire --- .../include/UDPBaseImplementation.h | 2 +- .../src/UDPStandardImplementation.cpp | 129 +++++++++++------- 2 files changed, 82 insertions(+), 49 deletions(-) diff --git a/slsReceiverSoftware/include/UDPBaseImplementation.h b/slsReceiverSoftware/include/UDPBaseImplementation.h index 05b992975..38adefe90 100644 --- a/slsReceiverSoftware/include/UDPBaseImplementation.h +++ b/slsReceiverSoftware/include/UDPBaseImplementation.h @@ -618,7 +618,7 @@ protected: uint32_t currframenum; /** Previous Frame number from buffer */ - uint32_t prevframenum; + int prevframenum; /** size of one frame */ int frameSize; diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 0d4eab84b..5f68876a9 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1749,12 +1749,16 @@ int UDPStandardImplementation::startListening(){ #endif rc = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS, maxBufferSize); if(rc == EIGER_HEADER_LENGTH && myDetectorType == EIGER) { - while(rc == EIGER_HEADER_LENGTH) + while(rc == EIGER_HEADER_LENGTH){ rc = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS, maxBufferSize); - }/* - if(rc == 1040){ - cprintf(YELLOW,"tempframenum[%d]:%d\n",ithread,((*(uint32_t*)(((eiger_packet_header *)((char*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS)))->num1)))); - cprintf(YELLOW,"packetnum[%d]:%d\n",ithread,((*(uint8_t*)(((eiger_packet_header *)((char*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS)))->num4)))); + /*cprintf(MAGENTA,"%d got a header*****************************\n",ithread); + cprintf(MAGENTA,"tempframenum[%d]:%d\n",ithread,(htonl(*(uint32_t*)(((eiger_image_header *)((char*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS)))->fnum)))); + */} + } + /* if(rc == 1040){ + cprintf(CYAN,"tempframenum[%d]:%d\n",ithread,((*(uint32_t*)(((eiger_packet_header *)((char*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS)))->num1)))); + cprintf(CYAN,"packetnum[%d]:%d\n",ithread,((*(uint8_t*)(((eiger_packet_header *)((char*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS)))->num4)))); + cprintf(CYAN,"add[%d]:0x%x\n",ithread,(void*)(buffer[ithread])); }*/ expected = maxBufferSize; #ifdef SOCKET_DEBUG @@ -1888,6 +1892,9 @@ int UDPStandardImplementation::startListening(){ cprintf(BLUE,"%d listener going to push fifo: 0x%x\n", ithread,(void*)(buffer[ithread])); #endif while(!fifo[ithread]->push(buffer[ithread])); + /*cprintf(YELLOW,"tempframenum[%d]:%d\n",ithread,((*(uint32_t*)(((eiger_packet_header *)((char*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS)))->num1)))); + cprintf(YELLOW,"packetnum[%d]:%d\n",ithread,((*(uint8_t*)(((eiger_packet_header *)((char*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS)))->num4)))); + cprintf(YELLOW,"add[%d]:0x%x\n",ithread,(void*)(buffer[ithread]));*/ #ifdef FIFO_DEBUG cprintf(BLUE, "%d listener pushed into fifo %x\n",ithread, (void*)(buffer[ithread])); #endif @@ -2007,9 +2014,9 @@ int UDPStandardImplementation::startWriting(){ cprintf(RED,"blank frame not detected at %d: 0x%x\n",i,(*(uint8_t*)(((eiger_packet_header *)((char*)(blankframe[i])))->num3)) ); exit(-1); } - #ifdef FIFO_DEBUG + //#ifdef FIFO_DEBUG cprintf(GREEN,"packet %d blank frame 0x%x\n",i,(void*)(blankframe[i])); - #endif + //#endif } } @@ -2061,9 +2068,9 @@ int UDPStandardImplementation::startWriting(){ }else{ endofacquisition = false; if(numpackets[i] == 1040){ - cprintf(BLUE,"tempframenum[%d]:%d\n",i,((*(uint32_t*)(((eiger_packet_header *)((char*)(wbuf[i] + HEADER_SIZE_NUM_TOT_PACKETS)))->num1)))); + /* cprintf(BLUE,"tempframenum[%d]:%d\n",i,((*(uint32_t*)(((eiger_packet_header *)((char*)(wbuf[i] + HEADER_SIZE_NUM_TOT_PACKETS)))->num1)))); cprintf(BLUE,"packetnum[%d]:%d\n",i,((*(uint8_t*)(((eiger_packet_header *)((char*)(wbuf[i] + HEADER_SIZE_NUM_TOT_PACKETS)))->num4)))); - }else if(numpackets[i] == EIGER_HEADER_LENGTH){ + */}else if(numpackets[i] == EIGER_HEADER_LENGTH){ cprintf(BG_RED, "got header in writer, weirdd packetsize:%d\n",numpackets[i]); exit(-1); } @@ -2125,19 +2132,19 @@ int UDPStandardImplementation::startWriting(){ for(j=0;jnum3)) == 0xFF) + if ((*(uint8_t*)(((eiger_packet_header *)((char*)(tempbuffer[tempoffset[i]])))->num3))&0x2) cprintf(RED,"1 fifo:%d missing packet added at pnum:%d\n",i,tempoffset[i]); else cprintf(RED, "1 fifo:%d Weird at pnum:%d\n",i,tempoffset[i]); #endif - if ((*(uint8_t*)(((eiger_packet_header *)((char*)(tempbuffer[tempoffset[i]])))->num3)) != 0xFF){ + if (!((*(uint8_t*)(((eiger_packet_header *)((char*)(tempbuffer[tempoffset[i]])))->num3))&0x2)){ cprintf(BG_RED, "dummy blank mismatch num4 earlier2! i:%d pnum:%d fnum:%d num3:0x%x actual num3:0x%x\n", i,tempoffset[i],tempframenum[i], (*(uint8_t*)(((eiger_packet_header *)((char*)(tempbuffer[tempoffset[i]])))->num3)), (*(uint8_t*)(((eiger_packet_header *)((char*)(blankframe[blankoffset])))->num3))); exit(-1); }else - cprintf(GREEN, "blank packet i:%d pnum:%d fnum:%d num3:0x%x\n",i,tempoffset[i],tempframenum[i],(*(uint8_t*)(((eiger_packet_header *)((char*)(tempbuffer[tempoffset[i]])))->num3))); - + /*cprintf(GREEN, "blank packet i:%d pnum:%d fnum:%d num3:0x%x\n",i,tempoffset[i],tempframenum[i],(*(uint8_t*)(((eiger_packet_header *)((char*)(tempbuffer[tempoffset[i]])))->num3))); +*/ tempoffset[i] ++; blankoffset ++; } @@ -2172,13 +2179,13 @@ int UDPStandardImplementation::startWriting(){ //WRONG FRAME - leave - if(tempframenum[i] != presentframenum){cout<<"wrong packet"<num1))), ((*(uint8_t*)(((eiger_packet_header *)((char*)(wbuf[i] + HEADER_SIZE_NUM_TOT_PACKETS)))->num4)))); -//#endif +#endif tempframenum[i] = presentframenum; //add missing packets numberofmissingpackets[i] = (LAST_PACKET_VALUE - lastpacketheader[i]); @@ -2190,18 +2197,23 @@ int UDPStandardImplementation::startWriting(){ for(j=0;jnum3)) == 0xFF) + if ((*(uint8_t*)(((eiger_packet_header *)((char*)(tempbuffer[tempoffset[i]])))->num3))&0x2) cprintf(RED,"5 fifo:%d missing packet added at pnum:%d\n",i,tempoffset[i]); else cprintf(RED, "5 fifo:%d WEird at pnum:%d\n",i,tempoffset[i]); #endif - if ((*(uint8_t*)(((eiger_packet_header *)((char*)(tempbuffer[tempoffset[i]])))->num3)) != 0xFF){ - cprintf(BG_RED, "wrong blank mismatch num4 earlier2! i:%d pnum:%d fnum:%d num3:0x%x actual num3:0x%x\n", + if (!((*(uint8_t*)(((eiger_packet_header *)((char*)(tempbuffer[tempoffset[i]])))->num3))&0x2)){ + cprintf(BG_RED, "wrong blank mismatch num4 earlier2! " + "i:%d pnum:%d fnum:%d num3:0x%x actual num3:0x%x add:0x%x\n", i,tempoffset[i],tempframenum[i], (*(uint8_t*)(((eiger_packet_header *)((char*)(tempbuffer[tempoffset[i]])))->num3)), - (*(uint8_t*)(((eiger_packet_header *)((char*)(blankframe[blankoffset])))->num3))); + (*(uint8_t*)(((eiger_packet_header *)((char*)(blankframe[blankoffset])))->num3)), + (void*)(tempbuffer[tempoffset[i]])); exit(-1); }else - cprintf(GREEN, "blank packet i:%d pnum:%d fnum:%d num3:0x%x\n",i,tempoffset[i],tempframenum[i],(*(uint8_t*)(((eiger_packet_header *)((char*)(tempbuffer[tempoffset[i]])))->num3))); + /*cprintf(GREEN, "blank packet i:%d pnum:%d fnum:%d num3:0x%x add:0x%x\n", + i,tempoffset[i],tempframenum[i], + (*(uint8_t*)(((eiger_packet_header *)((char*)(tempbuffer[tempoffset[i]])))->num3)), + (void*)(tempbuffer[tempoffset[i]]));*/ tempoffset[i] ++; blankoffset ++; @@ -2213,15 +2225,15 @@ int UDPStandardImplementation::startWriting(){ //CORRECT FRAME - continue building frame - else {cout<<"correct packet"<num4))); -//#ifdef VERYVERBOSE +#ifdef VERYVERBOSE cprintf(GREEN,"**fifo:%d currentpacketheader: %d lastpacketheader %d tempoffset:%d\n",i,currentpacketheader[i],lastpacketheader[i], tempoffset[i]); -//#endif +#endif //add missing packets numberofmissingpackets[i] = (currentpacketheader[i] - lastpacketheader[i] -1); #ifdef VERYDEBUG @@ -2232,25 +2244,32 @@ int UDPStandardImplementation::startWriting(){ for(j=0;jnum3)) == 0xFF) + if ((*(uint8_t*)(((eiger_packet_header *)((char*)(tempbuffer[tempoffset[i]])))->num3))&0x2) cprintf(RED,"4 fifo:%d missing packet added at pnum:%d\n",i,tempoffset[i]); else cprintf(RED, "4 fifo:%d WEird at pnum:%d\n",i,tempoffset[i]); #endif - if ((*(uint8_t*)(((eiger_packet_header *)((char*)(tempbuffer[tempoffset[i]])))->num3)) != 0xFF){ - cprintf(BG_RED, "correct blank mismatch num4 earlier2! i:%d pnum:%d fnum:%d num3:0x%x actual num3:0x%x\n", + if (!((*(uint8_t*)(((eiger_packet_header *)((char*)(tempbuffer[tempoffset[i]])))->num3))&0x2)){ + cprintf(BG_RED, "correct blank mismatch num4 earlier2! " + "i:%d pnum:%d fnum:%d num3:0x%x actual num3:0x%x add:0x%x\n", i,tempoffset[i],tempframenum[i], (*(uint8_t*)(((eiger_packet_header *)((char*)(tempbuffer[tempoffset[i]])))->num3)), - (*(uint8_t*)(((eiger_packet_header *)((char*)(blankframe[blankoffset])))->num3))); + (*(uint8_t*)(((eiger_packet_header *)((char*)(blankframe[blankoffset])))->num3)), + (void*)(tempbuffer[tempoffset[i]])); exit(-1); }else - cprintf(GREEN, "blank packet i:%d pnum:%d fnum:%d num3:0x%x\n",i,tempoffset[i],tempframenum[i],(*(uint8_t*)(((eiger_packet_header *)((char*)(tempbuffer[tempoffset[i]])))->num3))); + /* cprintf(GREEN, "blank packet i:%d pnum:%d fnum:%d num3:0x%x add:0x%x\n", + i,tempoffset[i],tempframenum[i], + (*(uint8_t*)(((eiger_packet_header *)((char*)(tempbuffer[tempoffset[i]])))->num3)), + (void*)(tempbuffer[tempoffset[i]]));*/ tempoffset[i] ++; blankoffset ++; } //add current packet if(currentpacketheader[i] != (tempoffset[i]-(i*packetsPerFrame/numListeningThreads))){ - cprintf(BG_RED, "correct pnum mismatch earlier! tempoffset[%d]:%d pnum:%d fnum:%d rfnum:%d\n",i,tempoffset[i],currentpacketheader[i],tempframenum[i],(*(uint32_t*)(((eiger_packet_header *)((char*)(wbuf[i])))->num1))); + cprintf(BG_RED, "correct pnum mismatch earlier! tempoffset[%d]:%d pnum:%d fnum:%d rfnum:%d\n", + i,tempoffset[i],currentpacketheader[i], + tempframenum[i],(*(uint32_t*)(((eiger_packet_header *)((char*)(wbuf[i]+ HEADER_SIZE_NUM_TOT_PACKETS)))->num1))); exit(-1); } tempbuffer[tempoffset[i]] = wbuf[i] + HEADER_SIZE_NUM_TOT_PACKETS; @@ -2258,10 +2277,15 @@ int UDPStandardImplementation::startWriting(){ cprintf(GREEN,"**fifo:%d currentpacketheader: %d tempoffset:%d\n",i,(*(uint8_t*)(((eiger_packet_header *)((char*)(tempbuffer[tempoffset[i]])))->num4)),tempoffset[i]); #endif if((*(uint8_t*)(((eiger_packet_header *)((char*)(tempbuffer[tempoffset[i]])))->num4)) != (tempoffset[i]-(i*packetsPerFrame/numListeningThreads))){ - cprintf(BG_RED, "pnum mismatch num4 earlier! i:%d pnum:%d fnum:%d\n",i,(*(uint8_t*)(((eiger_packet_header *)((char*)(tempbuffer[tempoffset[i]])))->num4)),tempframenum[i]); + cprintf(BG_RED, "pnum mismatch num4 earlier! i:%d pnum:%d fnum:%d add:0x%x\n", + i,(*(uint8_t*)(((eiger_packet_header *)((char*)(tempbuffer[tempoffset[i]])))->num4)), + tempframenum[i],(void*)(tempbuffer[tempoffset[i]])); exit(-1); } - cprintf(GREEN, "normal packet i:%d pnum:%d fnum:%d num3:0x%x\n",i,tempoffset[i],tempframenum[i],(*(uint8_t*)(((eiger_packet_header *)((char*)(tempbuffer[tempoffset[i]])))->num3))); + /*cprintf(GREEN, "normal packet i:%d pnum:%d fnum:%d num3:0x%x add:0x%x\n", + i,tempoffset[i],tempframenum[i], + (*(uint8_t*)(((eiger_packet_header *)((char*)(tempbuffer[tempoffset[i]])))->num3)), + (void*)(tempbuffer[tempoffset[i]]));*/ tempoffset[i] ++; //update last packet lastpacketheader[i] = currentpacketheader[i]; @@ -2306,7 +2330,7 @@ int UDPStandardImplementation::startWriting(){ cprintf(RED, "numMissingPackets:%d fnum:%d\n",numMissingPackets,currframenum); for (j=0;jnum3)) == 0xFF) + if ((*(uint8_t*)(((eiger_packet_header *)((char*)(tempbuffer[j])))->num3))&0x2) cprintf(RED,"found the missing packet at pnum:%d\n",j); } #endif @@ -2329,9 +2353,9 @@ int UDPStandardImplementation::startWriting(){ cprintf(GREEN,"%d writer freed pushed into fifofree %x for listener %d\n",ithread, (void*)(tofree[j]),1); #endif } -//#ifdef VERYDEBUG +#ifdef VERYDEBUG cprintf(GREEN,"finished freeing\n"); -//#endif +#endif //reset a few stuff @@ -2341,6 +2365,7 @@ int UDPStandardImplementation::startWriting(){ //no dummy packet and is the last packet (if not last packet, next frame, dont pop over it) if((numpackets[i]) && (currentpacketheader[i] == LAST_PACKET_VALUE)) popready[i] = true; + /*cprintf(GREEN,"popready[%d]:%d\n",i,popready[i]);*/ tempoffset[i] = (i*packetsPerFrame/numListeningThreads); tofreeoffset[i] = (i*packetsPerFrame/numListeningThreads); blankoffset = 0; @@ -2350,6 +2375,11 @@ int UDPStandardImplementation::startWriting(){ } } + /* for(int i=0;inum1)))); + cprintf(GREEN,"packetnum[%d]:%d\n",i,((*(uint8_t*)(((eiger_packet_header *)((char*)(wbuf[i] + HEADER_SIZE_NUM_TOT_PACKETS)))->num4)))); + }*/ } @@ -2772,17 +2802,17 @@ void UDPStandardImplementation::writeToFile_withoutCompression(char* buf[],int n }else fwrite(buf[0]+offset, 1, packetsToSave * onePacketSize, sfilefd); packetsInFile += packetsToSave; -//#ifdef EIGER_DEBUG3 +#ifdef EIGER_DEBUG3 cprintf(GREEN,"packetscaught earlier:%d packetstosave:%d numMissingPackets:%d addingon:%d\n", packetsCaught,packetsToSave,numMissingPackets,(packetsToSave - numMissingPackets)); -//#endif +#endif packetsCaught += (packetsToSave - numMissingPackets); totalPacketsCaught += (packetsToSave - numMissingPackets); numMissingPackets = 0; -//#ifdef EIGER_DEBUG3 +#ifdef EIGER_DEBUG3 cprintf(GREEN,"packetscaught:%d\n", packetsCaught); cprintf(GREEN,"totalPacketsCaught:%d\n", totalPacketsCaught); -//#endif +#endif //new file if(packetsInFile >= maxPacketsPerFile){ @@ -2867,11 +2897,11 @@ void UDPStandardImplementation::handleWithoutDataCompression(int ithread, char* //missing packet - if ((*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num3)) == 0xFF){ + if ((*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num3))&0x2){ missingpacket = 1; //add packet numbers (*(uint16_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num2)) = (i+1); - (*(uint32_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num1)) = currframenum; + (*(uint32_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num1)) = currframenum+1; }else{ missingpacket = 0; @@ -2909,7 +2939,7 @@ void UDPStandardImplementation::handleWithoutDataCompression(int ithread, char* if((*(uint16_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num2)) != (i+1)){ cprintf(BG_RED, "pnum mismatch! i:%d pnum:%d fnum:%d\n",i,(*(uint16_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num2)),currframenum); - if ((*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num3)) == 0xFF) + if ((*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num3))&0x2) cprintf(BG_RED,"missing packet though\n"); exit(-1); } @@ -2933,8 +2963,11 @@ void UDPStandardImplementation::handleWithoutDataCompression(int ithread, char* (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num4)), (*(uint16_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num2))); #endif - - +/* + cprintf(GREEN,"at writing, fnum:%d, pnum:%d,num3:0x%x add:0x%x\n", + currframenum, i, (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num3)), + (void*)(wbuffer[i])); +*/ } } @@ -2943,9 +2976,9 @@ void UDPStandardImplementation::handleWithoutDataCompression(int ithread, char* writeToFile_withoutCompression(wbuffer, npackets,currframenum); } -//#ifdef VERYDEBUG +#ifdef VERYDEBUG cprintf(GREEN,"written everyting\n"); -//#endif +#endif } From 4813d7b59830393b0e713ad695706009c508c025 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Fri, 21 Aug 2015 10:04:55 +0200 Subject: [PATCH 126/474] should work properly --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 5f68876a9..769269721 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1654,7 +1654,12 @@ void UDPStandardImplementation::startReadout(){ /********************************************/ //usleep(10000000); //usleep(2000000); - + int prev = totalPacketsCaught; + usleep(50000); + while(prev!=totalPacketsCaught){ + prev=totalPacketsCaught; + usleep(50000); + } pthread_mutex_lock(&status_mutex); status = TRANSMITTING; pthread_mutex_unlock(&status_mutex); @@ -2014,9 +2019,9 @@ int UDPStandardImplementation::startWriting(){ cprintf(RED,"blank frame not detected at %d: 0x%x\n",i,(*(uint8_t*)(((eiger_packet_header *)((char*)(blankframe[i])))->num3)) ); exit(-1); } - //#ifdef FIFO_DEBUG +#ifdef FIFO_DEBUG cprintf(GREEN,"packet %d blank frame 0x%x\n",i,(void*)(blankframe[i])); - //#endif +#endif } } From 8f6b8a847404262ab58f7cee2a3625f55188c818 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Fri, 21 Aug 2015 10:54:14 +0200 Subject: [PATCH 127/474] forgot to commit earlier --- .../src/UDPStandardImplementation.cpp | 31 +++++++++---------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 769269721..de95765a2 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -2067,9 +2067,9 @@ int UDPStandardImplementation::startWriting(){ //dont pop again if dummy packet else if(numpackets[i] == 0){ popready[i] = false; -//#ifdef EIGER_DEBUG3 +#ifdef EIGER_DEBUG3 cprintf(GREEN,"%d Dummy frame popped out of fifo %d",ithread, i); -//#endif +#endif }else{ endofacquisition = false; if(numpackets[i] == 1040){ @@ -2093,9 +2093,9 @@ int UDPStandardImplementation::startWriting(){ //END OF ACQUISITION if(endofacquisition){ -//#ifdef VERYDEBUG +#ifdef VERYDEBUG cprintf(GREEN,"%d Both dummy frames\n", ithread); -//#endif +#endif //remaining packets to be written if((myDetectorType == EIGER) && ((tempoffset[0]!=0) || (tempoffset[1]!=(packetsPerFrame/numListeningThreads)))); @@ -2122,15 +2122,15 @@ int UDPStandardImplementation::startWriting(){ if(numpackets[i] == EIGER_HEADER_LENGTH) {cprintf(BG_RED,"weird, frame packet recieved\n"); exit(-1);} //dummy packet else if(!numpackets[i]){ -//#ifdef VERYDEBUG +#ifdef VERYDEBUG cprintf(RED, "Dummy packet: %d from fifo %d\n", numpackets[i],i); -//#endif +#endif cout<<"tempoffset["<num3))); */ - tempoffset[i] ++; - blankoffset ++; + tempoffset[i]++; + blankoffset++; } //set fullframe and dont let fifo pop over it until written fullframe[i] = true; popready[i] = false; } } -//#ifdef EIGER_DEBUG3 +#ifdef EIGER_DEBUG3 else{ cprintf(RED, "WARNING: Got a weird packet size: %d from fifo %d\n", numpackets[i],i); continue; } -//#endif +#endif } @@ -2317,15 +2317,12 @@ int UDPStandardImplementation::startWriting(){ if(tempframenum[0] != tempframenum[1]) cprintf(RED,"Frame numbers mismatch!!! %d %d\n",tempframenum[0],tempframenum[1]); currframenum = tempframenum[0]; - /*//to resolve for missing frame packets - tempframenum[0]++; - tempframenum[1]++;*/ numMissingPackets += (numberofmissingpackets[0]+numberofmissingpackets[1]); numTotMissingPacketsInFile += numMissingPackets; numTotMissingPackets += numMissingPackets; -//#ifdef EIGER_DEBUG2 +#ifdef EIGER_DEBUG2 cprintf(GREEN,"**fnum:%d**\n",currframenum); -//#endif +#endif #ifdef EIGER_DEBUG3 if(numberofmissingpackets[0]) cprintf(RED, "fifo 0 missing packets:%d fnum:%d\n",numberofmissingpackets[0],currframenum); From 0a0dfb2dc6765e0a8c3931ec92b47bfd78fc2939 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Fri, 21 Aug 2015 14:11:38 +0200 Subject: [PATCH 128/474] fixed problem with increasing file descriptor when connecting to receiver --- slsReceiverSoftware/include/genericSocket.h | 40 ++++++++++--------- .../src/slsReceiverTCPIPInterface.cpp | 11 +++++ 2 files changed, 33 insertions(+), 18 deletions(-) diff --git a/slsReceiverSoftware/include/genericSocket.h b/slsReceiverSoftware/include/genericSocket.h index aa79f3233..fe49df0d2 100644 --- a/slsReceiverSoftware/include/genericSocket.h +++ b/slsReceiverSoftware/include/genericSocket.h @@ -71,6 +71,7 @@ class sockaddr_in; #include + using namespace std; #define DEFAULT_PACKET_SIZE 1286 @@ -206,7 +207,6 @@ typedef struct socketDescriptor = socket(AF_INET, getProtocol(),0); //tcp - if (socketDescriptor < 0) { cerr << "Can not create socket "<= 0){ \ close(socketDescriptor); \ } \ - file_des=-1; \ + if(is_a_server and getProtocol() == TCP){\ + if(file_des>0)\ + close(file_des);\ + } + file_des=-1; \ serverAddress.sin_port=-1; \ }; @@ -401,7 +405,6 @@ typedef struct cerr << "Can not create socket "<=0){ + close(socketDescriptor); + socketDescriptor = -1; + } + } + } + /** @short free connection */ void Disconnect(){ if (protocol==UDP){ @@ -429,18 +442,6 @@ typedef struct socketDescriptor=-1; } else{ - - /* close(socketDescriptor); - socketDescriptor=-1; - if(is_a_server){ - if(file_des>=0){ - close(file_des); - file_des=-1; - } - } -*/ - - if(file_des>=0){ //then was open if(is_a_server){ close(file_des); @@ -451,9 +452,6 @@ typedef struct } file_des=-1; } - - - } }; @@ -536,6 +534,9 @@ typedef struct } mac[sizeof(mac)-1]='\0'; + if(sock!=1){ + close(sock); + } return string(mac); }; @@ -557,6 +558,9 @@ typedef struct strncpy(addr,p,sizeof(addr)-1); addr[sizeof(addr)-1]='\0'; + if(sock!=1){ + close(sock); + } return string(addr); }; diff --git a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp index dfa01e6e3..65dbd890c 100644 --- a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp +++ b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp @@ -145,8 +145,18 @@ void slsReceiverTCPIPInterface::stop(){ cout<<"Shutting down TCP Socket and TCP thread"<shutDownUDPSockets(); + + cout << "Closing Files... " << endl; + receiverBase->closeFile(); + } + + killTCPServerThread = 1; socket->ShutDownSocket(); + socket->exitServer(); cout<<"Socket closed"<closeFile(); } + socket->exitServer(); pthread_exit(NULL); } From 41a4a9b611f45198f227d1158e69e1e11680d534 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Wed, 26 Aug 2015 10:28:39 +0200 Subject: [PATCH 129/474] some changes for 8 and 16 bit --- .../src/UDPStandardImplementation.cpp | 99 +++++++++++-------- 1 file changed, 59 insertions(+), 40 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 7b56daa04..b654be331 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1987,8 +1987,8 @@ int UDPStandardImplementation::startWriting(){ //last packet numbers for different dynamic ranges if(myDetectorType == EIGER){ switch(dynamicRange){ - case 4: LAST_PACKET_VALUE = 0x40; break; - case 8: LAST_PACKET_VALUE = 0x80; break; + case 4: LAST_PACKET_VALUE = 0x3f; break; + case 8: LAST_PACKET_VALUE = 0x7f; break; case 16: LAST_PACKET_VALUE = 0xff; break; case 32: LAST_PACKET_VALUE = 0xff; break; default: break; @@ -2084,11 +2084,14 @@ int UDPStandardImplementation::startWriting(){ }else{ endofacquisition = false; if(numpackets[i] == 1040){ - /* cprintf(BLUE,"tempframenum[%d]:%d\n",i,((*(uint32_t*)(((eiger_packet_header *)((char*)(wbuf[i] + HEADER_SIZE_NUM_TOT_PACKETS)))->num1)))); + cprintf(BLUE,"tempframenum[%d]:%d\n",i,((*(uint32_t*)(((eiger_packet_header *)((char*)(wbuf[i] + HEADER_SIZE_NUM_TOT_PACKETS)))->num1)))); cprintf(BLUE,"packetnum[%d]:%d\n",i,((*(uint8_t*)(((eiger_packet_header *)((char*)(wbuf[i] + HEADER_SIZE_NUM_TOT_PACKETS)))->num4)))); - */}else if(numpackets[i] == EIGER_HEADER_LENGTH){ + }else if(numpackets[i] == EIGER_HEADER_LENGTH){ cprintf(BG_RED, "got header in writer, weirdd packetsize:%d\n",numpackets[i]); exit(-1); + }else { + cprintf(BG_RED, "got weird in writer, weirdd packetsize:%d\n",numpackets[i]); + } if(myDetectorType == EIGER){ @@ -2104,9 +2107,9 @@ int UDPStandardImplementation::startWriting(){ //END OF ACQUISITION if(endofacquisition){ -#ifdef VERYDEBUG +//#ifdef VERYDEBUG cprintf(GREEN,"%d Both dummy frames\n", ithread); -#endif +//#endif //remaining packets to be written if((myDetectorType == EIGER) && ((tempoffset[0]!=0) || (tempoffset[1]!=(packetsPerFrame/numListeningThreads)))); @@ -2133,15 +2136,15 @@ int UDPStandardImplementation::startWriting(){ if(numpackets[i] == EIGER_HEADER_LENGTH) {cprintf(BG_RED,"weird, frame packet recieved\n"); exit(-1);} //dummy packet else if(!numpackets[i]){ -#ifdef VERYDEBUG +//#ifdef VERYDEBUG cprintf(RED, "Dummy packet: %d from fifo %d\n", numpackets[i],i); -#endif - cout<<"tempoffset["<num3))); exit(-1); }else - /*cprintf(GREEN, "blank packet i:%d pnum:%d fnum:%d num3:0x%x\n",i,tempoffset[i],tempframenum[i],(*(uint8_t*)(((eiger_packet_header *)((char*)(tempbuffer[tempoffset[i]])))->num3))); -*/ +//#ifdef PADDING + cprintf(GREEN, "blank packet i:%d pnum:%d fnum:%d num3:0x%x\n",i,tempoffset[i],tempframenum[i],(*(uint8_t*)(((eiger_packet_header *)((char*)(tempbuffer[tempoffset[i]])))->num3))); +//#endif tempoffset[i]++; blankoffset++; } @@ -2169,12 +2173,12 @@ int UDPStandardImplementation::startWriting(){ popready[i] = false; } } -#ifdef EIGER_DEBUG3 +//#ifdef EIGER_DEBUG3 else{ cprintf(RED, "WARNING: Got a weird packet size: %d from fifo %d\n", numpackets[i],i); continue; } -#endif +//#endif } @@ -2195,13 +2199,17 @@ int UDPStandardImplementation::startWriting(){ //WRONG FRAME - leave - if(tempframenum[i] != presentframenum){/*cout<<"wrong packet"<num1))), ((*(uint8_t*)(((eiger_packet_header *)((char*)(wbuf[i] + HEADER_SIZE_NUM_TOT_PACKETS)))->num4)))); -#endif +//#endif tempframenum[i] = presentframenum; //add missing packets numberofmissingpackets[i] = (LAST_PACKET_VALUE - lastpacketheader[i]); @@ -2226,11 +2234,12 @@ int UDPStandardImplementation::startWriting(){ (void*)(tempbuffer[tempoffset[i]])); exit(-1); }else - /*cprintf(GREEN, "blank packet i:%d pnum:%d fnum:%d num3:0x%x add:0x%x\n", +//#ifdef PADDING + cprintf(GREEN, "blank packet i:%d pnum:%d fnum:%d num3:0x%x add:0x%x\n", i,tempoffset[i],tempframenum[i], (*(uint8_t*)(((eiger_packet_header *)((char*)(tempbuffer[tempoffset[i]])))->num3)), - (void*)(tempbuffer[tempoffset[i]]));*/ - + (void*)(tempbuffer[tempoffset[i]])); +//#endif tempoffset[i] ++; blankoffset ++; } @@ -2241,10 +2250,13 @@ int UDPStandardImplementation::startWriting(){ //CORRECT FRAME - continue building frame - else {/*cout<<"correct packet"<num4))); #ifdef VERYVERBOSE @@ -2273,10 +2285,12 @@ int UDPStandardImplementation::startWriting(){ (void*)(tempbuffer[tempoffset[i]])); exit(-1); }else - /* cprintf(GREEN, "blank packet i:%d pnum:%d fnum:%d num3:0x%x add:0x%x\n", +//#ifdef PADDING + cprintf(GREEN, "blank packet i:%d pnum:%d fnum:%d num3:0x%x add:0x%x\n", i,tempoffset[i],tempframenum[i], (*(uint8_t*)(((eiger_packet_header *)((char*)(tempbuffer[tempoffset[i]])))->num3)), - (void*)(tempbuffer[tempoffset[i]]));*/ + (void*)(tempbuffer[tempoffset[i]])); +//#endif tempoffset[i] ++; blankoffset ++; } @@ -2298,10 +2312,12 @@ int UDPStandardImplementation::startWriting(){ tempframenum[i],(void*)(tempbuffer[tempoffset[i]])); exit(-1); } - /*cprintf(GREEN, "normal packet i:%d pnum:%d fnum:%d num3:0x%x add:0x%x\n", +//#ifdef PADDING + cprintf(GREEN, "normal packet i:%d pnum:%d fnum:%d num3:0x%x add:0x%x\n", i,tempoffset[i],tempframenum[i], (*(uint8_t*)(((eiger_packet_header *)((char*)(tempbuffer[tempoffset[i]])))->num3)), - (void*)(tempbuffer[tempoffset[i]]));*/ + (void*)(tempbuffer[tempoffset[i]])); +//#endif tempoffset[i] ++; //update last packet lastpacketheader[i] = currentpacketheader[i]; @@ -2331,10 +2347,10 @@ int UDPStandardImplementation::startWriting(){ numMissingPackets += (numberofmissingpackets[0]+numberofmissingpackets[1]); numTotMissingPacketsInFile += numMissingPackets; numTotMissingPackets += numMissingPackets; -#ifdef EIGER_DEBUG2 +//#ifdef EIGER_DEBUG2 cprintf(GREEN,"**fnum:%d**\n",currframenum); -#endif -#ifdef EIGER_DEBUG3 +//#endif +//#ifdef EIGER_DEBUG3 if(numberofmissingpackets[0]) cprintf(RED, "fifo 0 missing packets:%d fnum:%d\n",numberofmissingpackets[0],currframenum); if(numberofmissingpackets[1]) @@ -2346,7 +2362,7 @@ int UDPStandardImplementation::startWriting(){ if ((*(uint8_t*)(((eiger_packet_header *)((char*)(tempbuffer[j])))->num3))&0x2) cprintf(RED,"found the missing packet at pnum:%d\n",j); } -#endif +//#endif //write and copy to gui @@ -2366,9 +2382,9 @@ int UDPStandardImplementation::startWriting(){ cprintf(GREEN,"%d writer freed pushed into fifofree %x for listener %d\n",ithread, (void*)(tofree[j]),1); #endif } -#ifdef VERYDEBUG +//#ifdef VERYDEBUG cprintf(GREEN,"finished freeing\n"); -#endif +//#endif //reset a few stuff @@ -2388,11 +2404,13 @@ int UDPStandardImplementation::startWriting(){ } } - /* for(int i=0;inum1)))); cprintf(GREEN,"packetnum[%d]:%d\n",i,((*(uint8_t*)(((eiger_packet_header *)((char*)(wbuf[i] + HEADER_SIZE_NUM_TOT_PACKETS)))->num4)))); - }*/ + } +//#endif } @@ -2955,11 +2973,12 @@ void UDPStandardImplementation::handleWithoutDataCompression(int ithread, char* cprintf(GREEN, "%d packet header:0x%016llx num3:0x%x\n",i, ((uint64_t)(*((uint64_t*)(wbuffer[i])))), (uint8_t)(*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num3))); + + cprintf(GREEN, "%d - 0x%x - %d - %d\n", i, + (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num3)), + (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num4)), + (*(uint16_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num2))); } - cprintf(GREEN, "%d - 0x%x - %d - %d\n", i, - (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num3)), - (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num4)), - (*(uint16_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num2))); #endif /* cprintf(GREEN,"at writing, fnum:%d, pnum:%d,num3:0x%x add:0x%x\n", From ed1dc77bb31178074fcfaf53d4370701557d31e5 Mon Sep 17 00:00:00 2001 From: Anna Bergamaschi Date: Fri, 28 Aug 2015 10:56:24 +0200 Subject: [PATCH 130/474] some changes to receiver defs --- .../include/dummyUDPInterface.h | 21 ++++++++++++-- slsReceiverSoftware/include/receiver_defs.h | 14 +++++----- slsReceiverSoftware/src/dummyMain.cpp | 28 ++++++++++--------- 3 files changed, 41 insertions(+), 22 deletions(-) diff --git a/slsReceiverSoftware/include/dummyUDPInterface.h b/slsReceiverSoftware/include/dummyUDPInterface.h index 479de4584..5cba675cc 100644 --- a/slsReceiverSoftware/include/dummyUDPInterface.h +++ b/slsReceiverSoftware/include/dummyUDPInterface.h @@ -15,6 +15,7 @@ #include "UDPInterface.h" #include "sls_receiver_defs.h" +#include "genericSocket.h" class dummyUDPInterface : public UDPInterface { @@ -58,7 +59,12 @@ class dummyUDPInterface : public UDPInterface { /** * Destructor */ - dummyUDPInterface() : UDPInterface(), dynamicRange(16), scanTag(1000), nFrames(100), fWrite(1), fOverwrite(1), fIndex(0), fCaught(0), totfCaught(0), startAcqIndex(0), startFrameIndex(0), acqIndex(0), dataCompression(false), period(0), type(slsReceiverDefs::GENERIC), framesNeeded(100), udpPort1(1900), udpPort2(1901), shortFrame(0), nFramesToGui(0), e10G(0) {strcpy(detHostname,"none"); strcpy(fName,"run"); strcpy(fPath,"/scratch/"); strcpy(eth,"eth0"); cout << "New dummy UDP Interface" << endl;}; + dummyUDPInterface() : UDPInterface(), dynamicRange(16), scanTag(1000), nFrames(100), fWrite(1), fOverwrite(1), fIndex(0), fCaught(0), totfCaught(0), startAcqIndex(0), startFrameIndex(0), acqIndex(0), dataCompression(false), period(0), type(slsReceiverDefs::GENERIC), framesNeeded(100), udpPort1(1900), udpPort2(1901), shortFrame(0), nFramesToGui(0), e10G(0) {strcpy(detHostname,"none"); strcpy(fName,"run"); strcpy(fPath,"/scratch/"); strcpy(eth,"eth0"); cout << "New dummy UDP Interface" << endl; + + + + +}; ~dummyUDPInterface() {cout << "Destroying dummy UDP Interface" << endl;}; @@ -198,7 +204,18 @@ class dummyUDPInterface : public UDPInterface { /returns 0 on success or -1 on failure */ //FIXME: success == 0 or success == 1? - virtual int startReceiver(char *message=NULL) {cout << "dummy start receiver" << endl; return 0;}; + virtual int startReceiver(char *message=NULL) {cout << "dummy start receiver" << endl; + char buff[8225]; + buff[8224]='\0'; + int ip=0; + int ib; + genericSocket *udpSocket= new genericSocket(50004,genericSocket::UDP,8224); + while((ib=udpSocket->ReceiveDataOnly(buff,8224))>0) { + cout << "*** "<< ib <<" ************************** " << ip++ << endl; + cout << buff << endl; + cout << "*****************************" << endl << endl<< endl ; + } +return 0;}; /** * Stops Receiver - stops listening for packets diff --git a/slsReceiverSoftware/include/receiver_defs.h b/slsReceiverSoftware/include/receiver_defs.h index 6f3b1acd3..f208d93c7 100755 --- a/slsReceiverSoftware/include/receiver_defs.h +++ b/slsReceiverSoftware/include/receiver_defs.h @@ -70,14 +70,14 @@ #define JCTB_FIFO_SIZE 2500 //cannot be less than max jobs per thread = 1000 /*#define MOENCH_ALIGNED_FRAME_SIZE 65536*/ -#define JCTB_PACKETS_PER_FRAME 50 -#define JCTB_ONE_PACKET_SIZE 8214 -#define JCTB_BUFFER_SIZE (MOENCH_ONE_PACKET_SIZE*MOENCH_PACKETS_PER_FRAME) -#define JCTB_DATA_BYTES (JCTB_BUFFER_PER_FRAME) +#define JCTB_PACKETS_PER_FRAME 1 +#define JCTB_ONE_PACKET_SIZE 8224 +#define JCTB_BUFFER_SIZE (JCTB_ONE_PACKET_SIZE*40) +#define JCTB_DATA_BYTES (8192*JCTB_PACKETS_PER_FRAME) -#define JCTB_FRAME_INDEX_MASK 0xFFFFFF00 -#define JCTB_FRAME_INDEX_OFFSET 8 -#define JCTB_PACKET_INDEX_MASK 0xFF +#define JCTB_FRAME_INDEX_MASK 0xFFFFFFFF +#define JCTB_FRAME_INDEX_OFFSET 6+8 +#define JCTB_PACKET_INDEX_MASK 0xFFFFFFFF #define JCTB_BYTES_PER_ADC (2) #define JCTB_PIXELS_IN_ONE_ROW 32 diff --git a/slsReceiverSoftware/src/dummyMain.cpp b/slsReceiverSoftware/src/dummyMain.cpp index 41494fd99..3f4e9bb2d 100644 --- a/slsReceiverSoftware/src/dummyMain.cpp +++ b/slsReceiverSoftware/src/dummyMain.cpp @@ -18,24 +18,26 @@ int main(int argc, char *argv[]) { bool bottom = false; cout << "CCCCCC" << endl; dummyUDPInterface *udp=new dummyUDPInterface(); - slsReceiverTCPIPInterface *tcpipInterface = new slsReceiverTCPIPInterface(success, udp, tcpip_port_no, bottom); +// slsReceiverTCPIPInterface *tcpipInterface = new slsReceiverTCPIPInterface(success, udp, tcpip_port_no, bottom); - if(tcpipInterface->start() == slsReceiverDefs::OK){ - cout << "DONE!" << endl; - string str; - cin>>str; - //wait and look for an exit keyword - while(str.find("exit") == string::npos) - cin>>str; - //stop tcp server thread, stop udp socket - tcpipInterface->stop(); - } +// if(tcpipInterface->start() == slsReceiverDefs::OK){ +// cout << "DONE!" << endl; +// string str; +// cin>>str; +// //wait and look for an exit keyword +// while(str.find("exit") == string::npos) +// cin>>str; +// //stop tcp server thread, stop udp socket +// tcpipInterface->stop(); +// } - if (tcpipInterface) - delete tcpipInterface; +// if (tcpipInterface) +// delete tcpipInterface; + + udp->startReceiver(); if(udp) delete udp; return 0; From 74366b3cfe326684a88dce83f3df813153838878 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Thu, 3 Sep 2015 12:00:37 +0200 Subject: [PATCH 131/474] halfway into new server --- .../include/UDPBaseImplementation.h | 33 +-- .../include/UDPStandardImplementation.h | 2 - .../src/UDPBaseImplementation.cpp | 91 ------- .../src/UDPStandardImplementation.cpp | 225 +++++++----------- .../src/slsReceiverTCPIPInterface.cpp | 1 - 5 files changed, 105 insertions(+), 247 deletions(-) diff --git a/slsReceiverSoftware/include/UDPBaseImplementation.h b/slsReceiverSoftware/include/UDPBaseImplementation.h index 38adefe90..3dd655f54 100644 --- a/slsReceiverSoftware/include/UDPBaseImplementation.h +++ b/slsReceiverSoftware/include/UDPBaseImplementation.h @@ -483,25 +483,25 @@ protected: //// Could be done more fine-grained... TODO // private: protected: - /** structure of an eiger image header*/ + /** structure of an eiger packet*/ typedef struct { - unsigned char header_before1[5]; - unsigned char header_confirm[1]; - unsigned char header_before2[14]; - //unsigned char header_before[20]; - unsigned char fnum[4]; - unsigned char header_after[24]; - } eiger_image_header; + unsigned char subframenum[4]; + unsigned char missingpacket[2]; + unsigned char portnum[1]; + unsigned char dynamicrange[1]; + } eiger_packet_header_t; - /** structure of an eiger image header*/ typedef struct { - unsigned char num1[4]; - unsigned char num2[2]; - unsigned char num3[1]; - unsigned char num4[1]; - } eiger_packet_header; + unsigned char framenum[6]; + unsigned char packetnum[2]; + } eiger_packet_footer_t; + + eiger_packet_header_t* eiger_packet_header; + unsigned char* eiger_packet_data; + eiger_packet_footer_t* eiger_packet_footer; + /** max number of listening threads */ const static int MAX_NUM_LISTENING_THREADS = EIGER_MAX_PORTS; @@ -626,9 +626,12 @@ protected: /** buffer size. different from framesize as we wait for one packet instead of frame for eiger */ int bufferSize; - /** oen buffer size */ + /** one buffer size */ int onePacketSize; + /** one buffer size */ + int oneDataSize; + /** latest data */ char* latestData; diff --git a/slsReceiverSoftware/include/UDPStandardImplementation.h b/slsReceiverSoftware/include/UDPStandardImplementation.h index 67443f21c..92092bead 100644 --- a/slsReceiverSoftware/include/UDPStandardImplementation.h +++ b/slsReceiverSoftware/include/UDPStandardImplementation.h @@ -485,8 +485,6 @@ private: void handleDataCompression(int ithread, char* wbuffer[], char* data, int xmax, int ymax, int &nf); - - public: diff --git a/slsReceiverSoftware/src/UDPBaseImplementation.cpp b/slsReceiverSoftware/src/UDPBaseImplementation.cpp index 40152f581..c59932b9d 100644 --- a/slsReceiverSoftware/src/UDPBaseImplementation.cpp +++ b/slsReceiverSoftware/src/UDPBaseImplementation.cpp @@ -1561,97 +1561,6 @@ int UDPBaseImplementation::startWriting(){ FILE_LOG(logDEBUG) << __AT__ << " sta while((1<pop(wbuf[i]); - numpackets = (uint16_t)(*((uint16_t*)wbuf[i])); -#ifdef VERYDEBUG - cout << ithread << " numpackets:" << dec << numpackets << endl; -#endif - } - -#ifdef VERYDEBUG - cout << ithread << " numpackets:" << dec << numpackets << endl; - cout << ithread << " *** writer popped from fifo " << (void*) wbuf[0]<< endl; - cout << ithread << " *** writer popped from fifo " << (void*) wbuf[1]<< endl; -#endif - - - //last dummy packet - if(numpackets == 0xFFFF){ - stopWriting(ithread,wbuf); - continue; - } - - - - - //for progress - if(myDetectorType == EIGER){ - tempframenum = htonl(*(unsigned int*)((eiger_image_header *)((char*)(wbuf[ithread] + HEADER_SIZE_NUM_TOT_PACKETS)))->fnum); - tempframenum += (startFrameIndex-1); //eiger frame numbers start at 1, so need to -1 - }else if ((myDetectorType == GOTTHARD) && (shortFrame == -1)) - tempframenum = (((((uint32_t)(*((uint32_t*)(wbuf[ithread] + HEADER_SIZE_NUM_TOT_PACKETS))))+1)& (frameIndexMask)) >> frameIndexOffset); - else - tempframenum = ((((uint32_t)(*((uint32_t*)(wbuf[ithread] + HEADER_SIZE_NUM_TOT_PACKETS))))& (frameIndexMask)) >> frameIndexOffset); - - if(numWriterThreads == 1) - currframenum = tempframenum; - else{ - pthread_mutex_lock(&progress_mutex); - if(tempframenum > currframenum) - currframenum = tempframenum; - pthread_mutex_unlock(&progress_mutex); - } -//#ifdef VERYDEBUG - if(myDetectorType == EIGER) - cout << endl < 0){ - for(i=0;ipush(wbuf[i])); -#ifdef VERYDEBUG - cout << ithread << ":" << i+j << " fifo freed:" << (void*)wbuf[i] << endl; -#endif - } - - - } - else{ - //copy to gui - copyFrameToGui(NULL,-1,wbuf[0]+HEADER_SIZE_NUM_TOT_PACKETS); -#ifdef VERYVERBOSE - cout << ithread << " finished copying" << endl; -#endif - while(!fifoFree[0]->push(wbuf[0])); -#ifdef VERYVERBOSE - cout<<"buf freed:"<<(void*)wbuf[0]< #include - +#include using namespace std; @@ -39,7 +39,6 @@ UDPStandardImplementation::UDPStandardImplementation() //guiFrameNumber(0), //tengigaEnable(0) { - thread_started = 0; eth = NULL; latestData = NULL; @@ -141,6 +140,7 @@ void UDPStandardImplementation::initializeMembers(){ frameSize = 0; bufferSize = 0; onePacketSize = 0; + oneDataSize = 0; guiDataReady = 0; nFrameToGui = 0; fifosize = 0; @@ -200,6 +200,7 @@ void UDPStandardImplementation::initializeMembers(){ //strcpy(fileName,"run"); + //status pthread_mutex_lock(&status_mutex); status = IDLE; @@ -246,6 +247,7 @@ void UDPStandardImplementation::deleteMembers(){ FILE_LOG(logDEBUG) << __AT__ < if(fifo[i]) {delete fifo[i]; fifo[i] = NULL;} if(fifoFree[i]) {delete fifoFree[i]; fifoFree[i] = NULL;} } + } @@ -323,6 +325,7 @@ int UDPStandardImplementation::setDetectorType(detectorType det){ FILE_LOG(logD fifosize = EIGER_FIFO_SIZE; packetsPerFrame = EIGER_ONE_GIGA_CONSTANT * dynamicRange * EIGER_MAX_PORTS; onePacketSize = EIGER_ONE_GIGA_ONE_PACKET_SIZE; + oneDataSize = EIGER_ONE_GIGA_ONE_DATA_SIZE; frameSize = onePacketSize * packetsPerFrame; bufferSize = (frameSize/EIGER_MAX_PORTS) + EIGER_HEADER_LENGTH;//everything one port gets (img header plus packets) maxPacketsPerFile = EIGER_MAX_FRAMES_PER_FILE * packetsPerFrame; @@ -337,6 +340,8 @@ int UDPStandardImplementation::setDetectorType(detectorType det){ FILE_LOG(logD createListeningThreads(true); numListeningThreads = MAX_NUM_LISTENING_THREADS; + + } else if(myDetectorType == JUNGFRAUCTB || myDetectorType == JUNGFRAU ){ fifosize = JCTB_FIFO_SIZE; packetsPerFrame = JCTB_PACKETS_PER_FRAME; @@ -1004,13 +1009,6 @@ cout << "copyframe" << endl; for(int j=0;jReceiveDataOnly(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS, maxBufferSize); - /*cprintf(MAGENTA,"%d got a header*****************************\n",ithread); - cprintf(MAGENTA,"tempframenum[%d]:%d\n",ithread,(htonl(*(uint32_t*)(((eiger_image_header *)((char*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS)))->fnum)))); - */} + } } - /* if(rc == 1040){ - cprintf(CYAN,"tempframenum[%d]:%d\n",ithread,((*(uint32_t*)(((eiger_packet_header *)((char*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS)))->num1)))); - cprintf(CYAN,"packetnum[%d]:%d\n",ithread,((*(uint8_t*)(((eiger_packet_header *)((char*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS)))->num4)))); - cprintf(CYAN,"add[%d]:0x%x\n",ithread,(void*)(buffer[ithread])); - }*/ expected = maxBufferSize; #ifdef SOCKET_DEBUG }else{ @@ -1908,9 +1899,6 @@ int UDPStandardImplementation::startListening(){ cprintf(BLUE,"%d listener going to push fifo: 0x%x\n", ithread,(void*)(buffer[ithread])); #endif while(!fifo[ithread]->push(buffer[ithread])); - /*cprintf(YELLOW,"tempframenum[%d]:%d\n",ithread,((*(uint32_t*)(((eiger_packet_header *)((char*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS)))->num1)))); - cprintf(YELLOW,"packetnum[%d]:%d\n",ithread,((*(uint8_t*)(((eiger_packet_header *)((char*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS)))->num4)))); - cprintf(YELLOW,"add[%d]:0x%x\n",ithread,(void*)(buffer[ithread]));*/ #ifdef FIFO_DEBUG cprintf(BLUE, "%d listener pushed into fifo %x\n",ithread, (void*)(buffer[ithread])); #endif @@ -2019,15 +2007,24 @@ int UDPStandardImplementation::startWriting(){ //blank frame if(myDetectorType == EIGER){ + for(i=0;inum3)) = 0xFF; - for(j=0;j<(onePacketSize-16);++j) - (*((uint8_t*)((char*)(blankframe[i])+8+j))) = 0xFF; - if ((*(uint8_t*)(((eiger_packet_header *)((char*)(blankframe[i])))->num3)) != 0xFF){ - cprintf(RED,"blank frame not detected at %d: 0x%x\n",i,(*(uint8_t*)(((eiger_packet_header *)((char*)(blankframe[i])))->num3)) ); + //blank frame for each packet + blankframe[i] = new char[onePacketSize]; + eiger_packet_header = (eiger_packet_header_t*) blankframe[i]; + //set missing packet to 0xff + *( (uint16_t*) eiger_packet_header->missingpacket) = 0xFF; + + //set each value inside blank frame to 0xff + for(j=0;j<(oneDataSize);++j){ + eiger_packet_data = blankframe[i] + sizeof(eiger_packet_header_t) + j; + *(eiger_packet_data) = 0xFF; + } + //verify + if (*( (uint16_t*) eiger_packet_header->missingpacket) != 0xFF){ + cprintf(RED,"blank frame not detected at %d: 0x%x\n",i,*( (uint16_t*) eiger_packet_header->missingpacket) ); exit(-1); } #ifdef FIFO_DEBUG @@ -2084,8 +2081,8 @@ int UDPStandardImplementation::startWriting(){ }else{ endofacquisition = false; if(numpackets[i] == 1040){ - cprintf(BLUE,"tempframenum[%d]:%d\n",i,((*(uint32_t*)(((eiger_packet_header *)((char*)(wbuf[i] + HEADER_SIZE_NUM_TOT_PACKETS)))->num1)))); - cprintf(BLUE,"packetnum[%d]:%d\n",i,((*(uint8_t*)(((eiger_packet_header *)((char*)(wbuf[i] + HEADER_SIZE_NUM_TOT_PACKETS)))->num4)))); + cprintf(BLUE,"tempframenum[%d]:%d\n",i,((*(uint32_t*)(((eiger_packet_1g *)((char*)(wbuf[i] + HEADER_SIZE_NUM_TOT_PACKETS)))->framenum)))); + cprintf(BLUE,"packetnum[%d]:%d\n",i,((*(uint16_t*)(((eiger_packet_1g *)((char*)(wbuf[i] + HEADER_SIZE_NUM_TOT_PACKETS)))->packetnum)))); }else if(numpackets[i] == EIGER_HEADER_LENGTH){ cprintf(BG_RED, "got header in writer, weirdd packetsize:%d\n",numpackets[i]); exit(-1); @@ -2151,19 +2148,19 @@ int UDPStandardImplementation::startWriting(){ for(j=0;jnum3))&0x2) + if (*(uint8_t*)(((eiger_packet_1g *)((char*)(tempbuffer[tempoffset[i]])))->missingpacket)) cprintf(RED,"1 fifo:%d missing packet added at pnum:%d\n",i,tempoffset[i]); else cprintf(RED, "1 fifo:%d Weird at pnum:%d\n",i,tempoffset[i]); #endif - if (!((*(uint8_t*)(((eiger_packet_header *)((char*)(tempbuffer[tempoffset[i]])))->num3))&0x2)){ - cprintf(BG_RED, "dummy blank mismatch num4 earlier2! i:%d pnum:%d fnum:%d num3:0x%x actual num3:0x%x\n", + if ((*(uint8_t*)(((eiger_packet_1g *)((char*)(tempbuffer[tempoffset[i]])))->missingpacket))!= 0xFF){ + cprintf(BG_RED, "dummy blank mismatch num4 earlier2! i:%d pnum:%d fnum:%d missingpacket:0x%x actual missingpacket:0x%x\n", i,tempoffset[i],tempframenum[i], - (*(uint8_t*)(((eiger_packet_header *)((char*)(tempbuffer[tempoffset[i]])))->num3)), - (*(uint8_t*)(((eiger_packet_header *)((char*)(blankframe[blankoffset])))->num3))); + (*(uint8_t*)(((eiger_packet_1g *)((char*)(tempbuffer[tempoffset[i]])))->missingpacket)), + (*(uint8_t*)(((eiger_packet_1g *)((char*)(blankframe[blankoffset])))->missingpacket))); exit(-1); }else //#ifdef PADDING - cprintf(GREEN, "blank packet i:%d pnum:%d fnum:%d num3:0x%x\n",i,tempoffset[i],tempframenum[i],(*(uint8_t*)(((eiger_packet_header *)((char*)(tempbuffer[tempoffset[i]])))->num3))); + cprintf(GREEN, "blank packet i:%d pnum:%d fnum:%d missingpacket:0x%x\n",i,tempoffset[i],tempframenum[i],(*(uint8_t*)(((eiger_packet_1g *)((char*)(tempbuffer[tempoffset[i]])))->missingpacket))); //#endif tempoffset[i]++; blankoffset++; @@ -2189,8 +2186,7 @@ int UDPStandardImplementation::startWriting(){ if(!fullframe[i]){ //update frame number - //tempframenum[i] = (htonl(*(uint32_t*)(((eiger_packet_header *)((char*)(wbuf[i] + HEADER_SIZE_NUM_TOT_PACKETS)))->num1))); - tempframenum[i] = ((*(uint32_t*)(((eiger_packet_header *)((char*)(wbuf[i] + HEADER_SIZE_NUM_TOT_PACKETS)))->num1))); + tempframenum[i] = ((*(uint32_t*)(((eiger_packet_1g *)((char*)(wbuf[i] + HEADER_SIZE_NUM_TOT_PACKETS)))->framenum))); if(!tempframenum[i]) @@ -2207,8 +2203,8 @@ int UDPStandardImplementation::startWriting(){ //#ifdef EIGER_DEBUG3 cprintf(RED,"fifo:%d packet from next frame %d, add missing packets to the right one %d\n",i,tempframenum[i],presentframenum ); cprintf(RED,"current wrong frame:%d wrong frame packet number:%d\n", - ((*(uint32_t*)(((eiger_packet_header *)((char*)(wbuf[i] + HEADER_SIZE_NUM_TOT_PACKETS)))->num1))), - ((*(uint8_t*)(((eiger_packet_header *)((char*)(wbuf[i] + HEADER_SIZE_NUM_TOT_PACKETS)))->num4)))); + ((*(uint32_t*)(((eiger_packet_1g *)((char*)(wbuf[i] + HEADER_SIZE_NUM_TOT_PACKETS)))->framenum))), + ((*(uint16_t*)(((eiger_packet_1g *)((char*)(wbuf[i] + HEADER_SIZE_NUM_TOT_PACKETS)))->packetnum)))); //#endif tempframenum[i] = presentframenum; //add missing packets @@ -2221,23 +2217,23 @@ int UDPStandardImplementation::startWriting(){ for(j=0;jnum3))&0x2) + if ((*(uint8_t*)(((eiger_packet_1g *)((char*)(tempbuffer[tempoffset[i]])))->missingpacket))== 0xFF) cprintf(RED,"5 fifo:%d missing packet added at pnum:%d\n",i,tempoffset[i]); else cprintf(RED, "5 fifo:%d WEird at pnum:%d\n",i,tempoffset[i]); #endif - if (!((*(uint8_t*)(((eiger_packet_header *)((char*)(tempbuffer[tempoffset[i]])))->num3))&0x2)){ + if ((*(uint8_t*)(((eiger_packet_1g *)((char*)(tempbuffer[tempoffset[i]])))->missingpacket))!= 0xFF){ cprintf(BG_RED, "wrong blank mismatch num4 earlier2! " - "i:%d pnum:%d fnum:%d num3:0x%x actual num3:0x%x add:0x%x\n", + "i:%d pnum:%d fnum:%d missingpacket:0x%x actual missingpacket:0x%x add:0x%x\n", i,tempoffset[i],tempframenum[i], - (*(uint8_t*)(((eiger_packet_header *)((char*)(tempbuffer[tempoffset[i]])))->num3)), - (*(uint8_t*)(((eiger_packet_header *)((char*)(blankframe[blankoffset])))->num3)), + (*(uint8_t*)(((eiger_packet_1g *)((char*)(tempbuffer[tempoffset[i]])))->missingpacket)), + (*(uint8_t*)(((eiger_packet_1g *)((char*)(blankframe[blankoffset])))->missingpacket)), (void*)(tempbuffer[tempoffset[i]])); exit(-1); }else //#ifdef PADDING - cprintf(GREEN, "blank packet i:%d pnum:%d fnum:%d num3:0x%x add:0x%x\n", + cprintf(GREEN, "blank packet i:%d pnum:%d fnum:%d missingpacket:0x%x add:0x%x\n", i,tempoffset[i],tempframenum[i], - (*(uint8_t*)(((eiger_packet_header *)((char*)(tempbuffer[tempoffset[i]])))->num3)), + (*(uint8_t*)(((eiger_packet_1g *)((char*)(tempbuffer[tempoffset[i]])))->missingpacket)), (void*)(tempbuffer[tempoffset[i]])); //#endif tempoffset[i] ++; @@ -2258,7 +2254,7 @@ int UDPStandardImplementation::startWriting(){ cprintf(GREEN,"**tempfraemnum of %d: %d\n",i,tempframenum[i]); //#endif //update current packet - currentpacketheader[i] = ((*(uint8_t*)(((eiger_packet_header *)((char*)(wbuf[i] + HEADER_SIZE_NUM_TOT_PACKETS)))->num4))); + currentpacketheader[i] = ((*(uint16_t*)(((eiger_packet_1g *)((char*)(wbuf[i] + HEADER_SIZE_NUM_TOT_PACKETS)))->packetnum))); #ifdef VERYVERBOSE cprintf(GREEN,"**fifo:%d currentpacketheader: %d lastpacketheader %d tempoffset:%d\n",i,currentpacketheader[i],lastpacketheader[i], tempoffset[i]); #endif @@ -2272,23 +2268,23 @@ int UDPStandardImplementation::startWriting(){ for(j=0;jnum3))&0x2) + if ((*(uint8_t*)(((eiger_packet_1g *)((char*)(tempbuffer[tempoffset[i]])))->missingpacket)) ==0xFF) cprintf(RED,"4 fifo:%d missing packet added at pnum:%d\n",i,tempoffset[i]); else cprintf(RED, "4 fifo:%d WEird at pnum:%d\n",i,tempoffset[i]); #endif - if (!((*(uint8_t*)(((eiger_packet_header *)((char*)(tempbuffer[tempoffset[i]])))->num3))&0x2)){ + if ((*(uint8_t*)(((eiger_packet_1g *)((char*)(tempbuffer[tempoffset[i]])))->missingpacket))!= 0xFF){ cprintf(BG_RED, "correct blank mismatch num4 earlier2! " - "i:%d pnum:%d fnum:%d num3:0x%x actual num3:0x%x add:0x%x\n", + "i:%d pnum:%d fnum:%d missingpacket:0x%x actual missingpacket:0x%x add:0x%x\n", i,tempoffset[i],tempframenum[i], - (*(uint8_t*)(((eiger_packet_header *)((char*)(tempbuffer[tempoffset[i]])))->num3)), - (*(uint8_t*)(((eiger_packet_header *)((char*)(blankframe[blankoffset])))->num3)), + (*(uint8_t*)(((eiger_packet_1g *)((char*)(tempbuffer[tempoffset[i]])))->missingpacket)), + (*(uint8_t*)(((eiger_packet_1g *)((char*)(blankframe[blankoffset])))->missingpacket)), (void*)(tempbuffer[tempoffset[i]])); exit(-1); }else //#ifdef PADDING - cprintf(GREEN, "blank packet i:%d pnum:%d fnum:%d num3:0x%x add:0x%x\n", + cprintf(GREEN, "blank packet i:%d pnum:%d fnum:%d missingpacket:0x%x add:0x%x\n", i,tempoffset[i],tempframenum[i], - (*(uint8_t*)(((eiger_packet_header *)((char*)(tempbuffer[tempoffset[i]])))->num3)), + (*(uint8_t*)(((eiger_packet_1g *)((char*)(tempbuffer[tempoffset[i]])))->missingpacket)), (void*)(tempbuffer[tempoffset[i]])); //#endif tempoffset[i] ++; @@ -2299,23 +2295,23 @@ int UDPStandardImplementation::startWriting(){ if(currentpacketheader[i] != (tempoffset[i]-(i*packetsPerFrame/numListeningThreads))){ cprintf(BG_RED, "correct pnum mismatch earlier! tempoffset[%d]:%d pnum:%d fnum:%d rfnum:%d\n", i,tempoffset[i],currentpacketheader[i], - tempframenum[i],(*(uint32_t*)(((eiger_packet_header *)((char*)(wbuf[i]+ HEADER_SIZE_NUM_TOT_PACKETS)))->num1))); + tempframenum[i],(*(uint32_t*)(((eiger_packet_1g *)((char*)(wbuf[i]+ HEADER_SIZE_NUM_TOT_PACKETS)))->framenum))); exit(-1); } tempbuffer[tempoffset[i]] = wbuf[i] + HEADER_SIZE_NUM_TOT_PACKETS; #ifdef EIGER_DEBUG3 - cprintf(GREEN,"**fifo:%d currentpacketheader: %d tempoffset:%d\n",i,(*(uint8_t*)(((eiger_packet_header *)((char*)(tempbuffer[tempoffset[i]])))->num4)),tempoffset[i]); + cprintf(GREEN,"**fifo:%d currentpacketheader: %d tempoffset:%d\n",i,(*(uint16_t*)(((eiger_packet_1g *)((char*)(tempbuffer[tempoffset[i]])))->packetnum)),tempoffset[i]); #endif - if((*(uint8_t*)(((eiger_packet_header *)((char*)(tempbuffer[tempoffset[i]])))->num4)) != (tempoffset[i]-(i*packetsPerFrame/numListeningThreads))){ + if((*(uint16_t*)(((eiger_packet_1g *)((char*)(tempbuffer[tempoffset[i]])))->packetnum)) != (tempoffset[i]-(i*packetsPerFrame/numListeningThreads))){ cprintf(BG_RED, "pnum mismatch num4 earlier! i:%d pnum:%d fnum:%d add:0x%x\n", - i,(*(uint8_t*)(((eiger_packet_header *)((char*)(tempbuffer[tempoffset[i]])))->num4)), + i,(*(uint16_t*)(((eiger_packet_1g *)((char*)(tempbuffer[tempoffset[i]])))->packetnum)), tempframenum[i],(void*)(tempbuffer[tempoffset[i]])); exit(-1); } //#ifdef PADDING - cprintf(GREEN, "normal packet i:%d pnum:%d fnum:%d num3:0x%x add:0x%x\n", + cprintf(GREEN, "normal packet i:%d pnum:%d fnum:%d missingpacket:0x%x add:0x%x\n", i,tempoffset[i],tempframenum[i], - (*(uint8_t*)(((eiger_packet_header *)((char*)(tempbuffer[tempoffset[i]])))->num3)), + (*(uint8_t*)(((eiger_packet_1g *)((char*)(tempbuffer[tempoffset[i]])))->missingpacket)), (void*)(tempbuffer[tempoffset[i]])); //#endif tempoffset[i] ++; @@ -2359,7 +2355,7 @@ int UDPStandardImplementation::startWriting(){ cprintf(RED, "numMissingPackets:%d fnum:%d\n",numMissingPackets,currframenum); for (j=0;jnum3))&0x2) + if ((*(uint8_t*)(((eiger_packet_1g *)((char*)(tempbuffer[j])))->missingpacket))==0xFF) cprintf(RED,"found the missing packet at pnum:%d\n",j); } //#endif @@ -2407,8 +2403,8 @@ int UDPStandardImplementation::startWriting(){ //#ifdef VERYDEBUG for(int i=0;inum1)))); - cprintf(GREEN,"packetnum[%d]:%d\n",i,((*(uint8_t*)(((eiger_packet_header *)((char*)(wbuf[i] + HEADER_SIZE_NUM_TOT_PACKETS)))->num4)))); + cprintf(GREEN,"tempframenum[%d]:%d\n",i,((*(uint32_t*)(((eiger_packet_1g *)((char*)(wbuf[i] + HEADER_SIZE_NUM_TOT_PACKETS)))->framenum)))); + cprintf(GREEN,"packetnum[%d]:%d\n",i,((*(uint16_t*)(((eiger_packet_1g *)((char*)(wbuf[i] + HEADER_SIZE_NUM_TOT_PACKETS)))->packetnum)))); } //#endif } @@ -2735,53 +2731,7 @@ void UDPStandardImplementation::writeToFile_withoutCompression(char* buf[],int n if((enableFileWrite) && (sfilefd)){ offset = HEADER_SIZE_NUM_TOT_PACKETS; - if(myDetectorType == EIGER){ -#ifdef WRITE_HEADERS -#ifdef VERY_DEBUG - if(myDetectorType == EIGER){ - int k = 0; - if(dynamicRange != 32){ - cprintf(RED, "\np1 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf[k])))->num1))); - cprintf(RED, "p1:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf[k])))->num3))); - cprintf(RED, "p0 num:%d - %d\n", k, (*(uint8_t*)(((eiger_packet_header *)((char*)(buf[k])))->num4))); - k = 1; - cprintf(RED, "p2 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf[k])))->num1))); - cprintf(RED, "p2:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf[k])))->num3))); - cprintf(RED, "p1 num:%d - %d\n", k,(*(uint8_t*)(((eiger_packet_header *)((char*)(buf[k])))->num4))); - k = 2; - cprintf(RED, "p3 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf[k])))->num1))); - cprintf(RED, "p3:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf[k])))->num3))); - cprintf(RED, "p2 num:%d - %d\n", k,(*(uint8_t*)(((eiger_packet_header *)((char*)(buf[k])))->num4))); - }else{ - k = 0; - cprintf(RED, "\np1 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf[k])))->num1))); - cprintf(RED, "p1:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf[k])))->num3))); - cprintf(RED, "p0 num:%d - %d\n", k, (*(uint16_t*)(((eiger_packet_header *)((char*)(buf[k])))->num2))); - k = 1; - cprintf(RED, "p2 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf[k])))->num1))); - cprintf(RED, "p2:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf[k])))->num3))); - cprintf(RED, "p1 num:%d - %d\n", k, (*(uint16_t*)(((eiger_packet_header *)((char*)(buf[k])))->num2))); - k = 2; - cprintf(RED, "p3 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf[k])))->num1))); - cprintf(RED, "p3:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf[k])))->num3))); - cprintf(RED, "p2 num:%d - %d\n", k, (*(uint16_t*)(((eiger_packet_header *)((char*)(buf[k])))->num2))); - k = 256; - cprintf(RED, "p257 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf[k])))->num1))); - cprintf(RED, "p257:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf[k])))->num3))); - cprintf(RED, "p256 num:%d - %d\n", k, (*(uint16_t*)(((eiger_packet_header *)((char*)(buf[k])))->num2))); - k = 512; - cprintf(RED, "p513 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf[k])))->num1))); - cprintf(RED, "p513:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf[k])))->num3))); - cprintf(RED, "p512 num:%d - %d\n", k, (*(uint16_t*)(((eiger_packet_header *)((char*)(buf[k])))->num2))); - k = 768; - cprintf(RED, "p769 fnum:0x%x\n", (*(unsigned int*)(((eiger_packet_header *)((char*)(buf[k])))->num1))); - cprintf(RED, "p769:0x%x\n", (*(uint8_t*)(((eiger_packet_header *)((char*)(buf[k])))->num3))); - cprintf(RED, "p768 num:%d - %d\n", k,(*(uint16_t*)(((eiger_packet_header *)((char*)(buf[k])))->num2))); - } - } -#endif -#endif - } + while(numpackets > 0){ //for progress and packet loss calculation(new files) @@ -2913,29 +2863,29 @@ void UDPStandardImplementation::handleWithoutDataCompression(int ithread, char* //missing packet - if ((*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num3))&0x2){ + if ((*(uint8_t*)(((eiger_packet_1g *)((char*)(wbuffer[i])))->missingpacket))==0xFF){ missingpacket = 1; //add packet numbers - (*(uint16_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num2)) = (i+1); - (*(uint32_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num1)) = currframenum+1; + (*(uint16_t*)(((eiger_packet_1g *)((char*)(wbuffer[i])))->packetnum)) = (i+1); + (*(uint32_t*)(((eiger_packet_1g *)((char*)(wbuffer[i])))->framenum)) = currframenum+1; }else{ missingpacket = 0; - if((*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num4)) != (i-(port*packetsPerFrame/numListeningThreads))){ - cprintf(BG_RED, "pnum mismatch num4! i:%d pnum:%d fnum:%d\n",i,(*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num4)),currframenum); + if((*(uint16_t*)(((eiger_packet_1g *)((char*)(wbuffer[i])))->packetnum)) != (i-(port*packetsPerFrame/numListeningThreads))){ + cprintf(BG_RED, "pnum mismatch num4! i:%d pnum:%d fnum:%d\n",i,(*(uint16_t*)(((eiger_packet_1g *)((char*)(wbuffer[i])))->packetnum)),currframenum); exit(-1); } - if(dynamicRange != 32){ + /* if(dynamicRange != 32){*/ //move packet numbers to num2, and compensate for port1 starting pnum from 0 if(!port) - (*(uint16_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num2)) = - ((*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num4))+1); + (*(uint16_t*)(((eiger_packet_1g *)((char*)(wbuffer[i])))->packetnum)) = + ((*(uint16_t*)(((eiger_packet_1g *)((char*)(wbuffer[i])))->packetnum))+1); else - (*(uint16_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num2)) = - ((*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num4))+(packetsPerFrame/2) +1); - } + (*(uint16_t*)(((eiger_packet_1g *)((char*)(wbuffer[i])))->packetnum)) = + ((*(uint16_t*)(((eiger_packet_1g *)((char*)(wbuffer[i])))->packetnum))+(packetsPerFrame/2) +1); + /*} //dr == 32 else{ if(i == 0) @@ -2946,43 +2896,42 @@ void UDPStandardImplementation::handleWithoutDataCompression(int ithread, char* pnuminc = (packetsPerFrame/2); else if(i == (3*packetsPerFrame/4)) pnuminc = (3*packetsPerFrame/4); - (*(uint16_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num2)) - = ((*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num4))+pnuminc+1); + (*(uint16_t*)(((eiger_packet_1g *)((char*)(wbuffer[i])))->packetnum)) + = ((*(uint8_t*)(((eiger_packet_1g *)((char*)(wbuffer[i])))->packetnum,))+pnuminc+1); - } + }*/ } - if((*(uint16_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num2)) != (i+1)){ - cprintf(BG_RED, "pnum mismatch! i:%d pnum:%d fnum:%d\n",i,(*(uint16_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num2)),currframenum); - if ((*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num3))&0x2) + if((*(uint16_t*)(((eiger_packet_1g *)((char*)(wbuffer[i])))->packetnum)) != (i+1)){ + cprintf(BG_RED, "pnum mismatch! i:%d pnum:%d fnum:%d\n",i,(*(uint16_t*)(((eiger_packet_1g *)((char*)(wbuffer[i])))->packetnum)),currframenum); + if ((*(uint8_t*)(((eiger_packet_1g *)((char*)(wbuffer[i])))->missingpacket))==0xFF) cprintf(BG_RED,"missing packet though\n"); exit(-1); } //overwriting port number and dynamic range - (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num3)) = + (*(uint8_t*)(((eiger_packet_1g *)((char*)(wbuffer[i])))->missingpacket)) = ((dynamicRange<<2)|(missingpacket<<1)|(port)); //frame number - //(*(uint32_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num1)) = currframenum; + //(*(uint32_t*)(((eiger_packet_1g *)((char*)(wbuffer[i])))->framenum)) = currframenum; #ifdef VERYDEBUG if((i==0)||(i==1)){ - cprintf(GREEN, "%d packet header:0x%016llx num3:0x%x\n",i, + cprintf(GREEN, "%d packet header:0x%016llx missingpacket:0x%x\n",i, ((uint64_t)(*((uint64_t*)(wbuffer[i])))), - (uint8_t)(*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num3))); + (uint8_t)(*(uint8_t*)(((eiger_packet_1g *)((char*)(wbuffer[i])))->missingpacket))); - cprintf(GREEN, "%d - 0x%x - %d - %d\n", i, - (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num3)), - (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num4)), - (*(uint16_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num2))); + cprintf(GREEN, "%d - 0x%x - %d\n", i, + (*(uint8_t*)(((eiger_packet_1g *)((char*)(wbuffer[i])))->missingpacket)), + (*(uint16_t*)(((eiger_packet_1g *)((char*)(wbuffer[i])))->packetnum))); } #endif /* - cprintf(GREEN,"at writing, fnum:%d, pnum:%d,num3:0x%x add:0x%x\n", - currframenum, i, (*(uint8_t*)(((eiger_packet_header *)((char*)(wbuffer[i])))->num3)), + cprintf(GREEN,"at writing, fnum:%d, pnum:%d,missingpacket:0x%x add:0x%x\n", + currframenum, i, (*(uint8_t*)(((eiger_packet_1g *)((char*)(wbuffer[i])))->missingpacket)), (void*)(wbuffer[i])); */ @@ -3148,9 +3097,11 @@ int UDPStandardImplementation::enableTenGiga(int enable){ if(!tengigaEnable){ packetsPerFrame = EIGER_ONE_GIGA_CONSTANT * dynamicRange * EIGER_MAX_PORTS; onePacketSize = EIGER_ONE_GIGA_ONE_PACKET_SIZE; + oneDataSize = EIGER_ONE_GIGA_ONE_DATA_SIZE; }else{ packetsPerFrame = EIGER_TEN_GIGA_CONSTANT * dynamicRange * EIGER_MAX_PORTS; onePacketSize = EIGER_TEN_GIGA_ONE_PACKET_SIZE; + oneDataSize = EIGER_TEN_GIGA_ONE_DATA_SIZE; } frameSize = onePacketSize * packetsPerFrame; bufferSize = (frameSize/EIGER_MAX_PORTS) + EIGER_HEADER_LENGTH;//everything one port gets (img header plus packets) @@ -3202,5 +3153,3 @@ int UDPStandardImplementation::enableTenGiga(int enable){ return tengigaEnable; } - - diff --git a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp index 3d16a3c4f..ea0336895 100644 --- a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp +++ b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp @@ -1570,7 +1570,6 @@ int slsReceiverTCPIPInterface::eiger_read_frame(){ char fName[MAX_STR_LENGTH]=""; int acquisitionIndex = -1; int frameIndex= -1; - int i; uint32_t index=0; int frameSize = EIGER_ONE_GIGA_ONE_PACKET_SIZE * packetsPerFrame; From 04578f7c69217b9d4d159732554acf17775f19fe Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Thu, 3 Sep 2015 15:17:31 +0200 Subject: [PATCH 132/474] added subframe exposure time settable --- slsReceiverSoftware/include/sls_receiver_defs.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/slsReceiverSoftware/include/sls_receiver_defs.h b/slsReceiverSoftware/include/sls_receiver_defs.h index 6abb30887..49cc8fb64 100755 --- a/slsReceiverSoftware/include/sls_receiver_defs.h +++ b/slsReceiverSoftware/include/sls_receiver_defs.h @@ -92,7 +92,9 @@ public: MEASUREMENTS_NUMBER, FRAMES_FROM_START, FRAMES_FROM_START_PG, - SAMPLES_JCTB + SAMPLES_JCTB, + SUBFRAME_ACQUISITION_TIME, /**< subframe exposure time */ + MAX_TIMERS }; From 572b6fe29f9422bbd46ecab4bd37c6539f216520 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Thu, 10 Sep 2015 14:05:10 +0200 Subject: [PATCH 133/474] f --- slsReceiverSoftware/include/UDPBaseImplementation.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/slsReceiverSoftware/include/UDPBaseImplementation.h b/slsReceiverSoftware/include/UDPBaseImplementation.h index 3dd655f54..d68f1c6d4 100644 --- a/slsReceiverSoftware/include/UDPBaseImplementation.h +++ b/slsReceiverSoftware/include/UDPBaseImplementation.h @@ -498,10 +498,6 @@ protected: unsigned char packetnum[2]; } eiger_packet_footer_t; - eiger_packet_header_t* eiger_packet_header; - unsigned char* eiger_packet_data; - eiger_packet_footer_t* eiger_packet_footer; - /** max number of listening threads */ const static int MAX_NUM_LISTENING_THREADS = EIGER_MAX_PORTS; From fe76ce96504d31f03ba89c5b9465ffdd338c65c6 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 15 Sep 2015 15:31:29 +0200 Subject: [PATCH 134/474] seems to run fine, only 16gb checked for fimware v 10 and software version v1.10.2 --- .../include/UDPBaseImplementation.h | 6 + slsReceiverSoftware/include/receiver_defs.h | 3 +- .../src/UDPBaseImplementation.cpp | 190 ----------- .../src/UDPStandardImplementation.cpp | 313 +++++++++--------- 4 files changed, 171 insertions(+), 341 deletions(-) diff --git a/slsReceiverSoftware/include/UDPBaseImplementation.h b/slsReceiverSoftware/include/UDPBaseImplementation.h index d68f1c6d4..d69e00b93 100644 --- a/slsReceiverSoftware/include/UDPBaseImplementation.h +++ b/slsReceiverSoftware/include/UDPBaseImplementation.h @@ -505,6 +505,9 @@ protected: /** max number of writer threads */ const static int MAX_NUM_WRITER_THREADS = 15; + /** missing packet identifier value */ + const static uint16_t missingPacketValue = 0xFFFF; + /** detector type */ detectorType myDetectorType; @@ -712,6 +715,9 @@ protected: /** 10Gbe enable*/ int tengigaEnable; + /** footer offset is different for 1g and 10g*/ + int footer_offset; + // TODO: not properly sure where to put these... /** structure of an eiger image header*/ diff --git a/slsReceiverSoftware/include/receiver_defs.h b/slsReceiverSoftware/include/receiver_defs.h index 701b4e382..206c8b92b 100755 --- a/slsReceiverSoftware/include/receiver_defs.h +++ b/slsReceiverSoftware/include/receiver_defs.h @@ -118,10 +118,11 @@ #define EIGER_ONE_GIGA_ONE_DATA_SIZE 1024 #define EIGER_TEN_GIGA_ONE_PACKET_SIZE 4112 #define EIGER_TEN_GIGA_ONE_DATA_SIZE 4096 +#define EIGER_PACKET_HEADER_SIZE 8 //#define EIGER_BUFFER_SIZE_CONSTANT (EIGER_ONE_PACKET_SIZE*EIGER_PACKETS_PER_FRAME_COSTANT)//1040*16*2//*bit mode //#define EIGER_DATA_BYTES_CONSTANT (EIGER_ONE_DATA_SIZE*EIGER_PACKETS_PER_FRAME_COSTANT) //1024*16*2//*bit mode -#define EIGER_FRAME_INDEX_MASK 0xFFFF +#define EIGER_FRAME_INDEX_MASK 0xFFFFFFFF //32 bit for now #define EIGER_FRAME_INDEX_OFFSET 0 #define EIGER_PACKET_INDEX_MASK 0x0 diff --git a/slsReceiverSoftware/src/UDPBaseImplementation.cpp b/slsReceiverSoftware/src/UDPBaseImplementation.cpp index c59932b9d..fb10ae106 100644 --- a/slsReceiverSoftware/src/UDPBaseImplementation.cpp +++ b/slsReceiverSoftware/src/UDPBaseImplementation.cpp @@ -558,83 +558,6 @@ void UDPBaseImplementation::setupFilter(){ FILE_LOG(logDEBUG) << __AT__ << " sta //LEO: it is not clear to me.. void UDPBaseImplementation::setupFifoStructure(){ FILE_LOG(logDEBUG) << __AT__ << " starting"; - int64_t i; - int oldn = numJobsPerThread; - - //if every nth frame mode - if(nFrameToGui) - numJobsPerThread = nFrameToGui; - - //random nth frame mode - else{ - if(!acquisitionPeriod) - i = SAMPLE_TIME_IN_NS; - else - i = SAMPLE_TIME_IN_NS/acquisitionPeriod; - if (i > MAX_JOBS_PER_THREAD) - numJobsPerThread = MAX_JOBS_PER_THREAD; - else if (i < 1) - numJobsPerThread = 1; - else - numJobsPerThread = i; - } - - //if same, return - if(oldn == numJobsPerThread) - return; - - if(myDetectorType == EIGER) - numJobsPerThread = 1; - - //otherwise memory too much if numjobsperthread is at max = 1000 - fifosize = GOTTHARD_FIFO_SIZE; - if(myDetectorType == MOENCH) - fifosize = MOENCH_FIFO_SIZE; - else if(myDetectorType == EIGER) - fifosize = EIGER_FIFO_SIZE; - - if(fifosize % numJobsPerThread) - fifosize = (fifosize/numJobsPerThread)+1; - else - fifosize = fifosize/numJobsPerThread; - - - cout << "Number of Frames per buffer:" << numJobsPerThread << endl; - cout << "Fifo Size:" << fifosize << endl; - - /* - //for testing - numJobsPerThread = 3; fifosize = 11; - */ - - for(int i=0;iisEmpty()) - fifoFree[i]->pop(buffer[i]); - delete fifoFree[i]; - } - if(fifo[i]) delete fifo[i]; - if(mem0[i]) free(mem0[i]); - fifoFree[i] = new CircularFifo(fifosize); - fifo[i] = new CircularFifo(fifosize); - - - //allocate memory - mem0[i]=(char*)malloc((bufferSize * numJobsPerThread + HEADER_SIZE_NUM_TOT_PACKETS)*fifosize); - /** shud let the client know about this */ - if (mem0[i]==NULL){ - cprintf(BG_RED,"++++++++++++++++++++++ COULD NOT ALLOCATE MEMORY FOR LISTENING !!!!!!!+++++++++++++++++++++\n"); - exit(-1); - } - buffer[i]=mem0[i]; - //push the addresses into freed fifoFree and writingFifoFree - while (buffer[i]<(mem0[i]+(bufferSize * numJobsPerThread + HEADER_SIZE_NUM_TOT_PACKETS)*(fifosize-1))) { - fifoFree[i]->push(buffer[i]); - buffer[i]+=(bufferSize * numJobsPerThread + HEADER_SIZE_NUM_TOT_PACKETS); - } - } - cout << "Fifo structure(s) reconstructed" << endl; } @@ -1529,93 +1452,6 @@ int UDPBaseImplementation::startWriting(){ FILE_LOG(logDEBUG) << __AT__ << " sta cout << ithread << "In startWriting()" <fnum); - //gotthard has +1 for frame number and not a short frame - else if ((myDetectorType == GOTTHARD) && (shortFrame == -1)) - startFrameIndex = (((((uint32_t)(*((uint32_t*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS))))+1) - & (frameIndexMask)) >> frameIndexOffset); - else - startFrameIndex = ((((uint32_t)(*((uint32_t*)(buffer[ithread]+HEADER_SIZE_NUM_TOT_PACKETS)))) - & (frameIndexMask)) >> frameIndexOffset); - //start of acquisition - if(!acqStarted){ - startAcquisitionIndex=startFrameIndex; - currframenum = startAcquisitionIndex; - acqStarted = true; - cout << "startAcquisitionIndex:" << startAcquisitionIndex<missingpacket) = 0xFF; + *( (uint16_t*) blankframe_header->missingpacket) = missingPacketValue; //set each value inside blank frame to 0xff for(j=0;j<(oneDataSize);++j){ - eiger_packet_data = blankframe[i] + sizeof(eiger_packet_header_t) + j; - *(eiger_packet_data) = 0xFF; + blankframe_data = (unsigned char*)blankframe[i] + sizeof(eiger_packet_header_t) + j; + *(blankframe_data) = 0xFF; } //verify - if (*( (uint16_t*) eiger_packet_header->missingpacket) != 0xFF){ - cprintf(RED,"blank frame not detected at %d: 0x%x\n",i,*( (uint16_t*) eiger_packet_header->missingpacket) ); + if (*( (uint16_t*) blankframe_header->missingpacket) != missingPacketValue){ + cprintf(RED,"blank frame not detected at %d: 0x%x\n",i,*( (uint16_t*) blankframe_header->missingpacket) ); exit(-1); } #ifdef FIFO_DEBUG @@ -2041,8 +2057,8 @@ int UDPStandardImplementation::startWriting(){ tempoffset[i] = (i*packetsPerFrame/numListeningThreads); tofreeoffset[i] = (i*packetsPerFrame/numListeningThreads); blankoffset = 0; - lastpacketheader[i] = -1; - currentpacketheader[i] = -1; + lastpacketheader[i] = 0; + currentpacketheader[i] = 0; numberofmissingpackets[i] = 0; numpackets[i] = 0; @@ -2065,6 +2081,7 @@ int UDPStandardImplementation::startWriting(){ cprintf(GREEN,"%d writer poped 0x%x from fifo %d\n", ithread, (void*)(wbuf[i]), i); #endif numpackets[i] = (uint32_t)(*((uint32_t*)wbuf[i])); + #ifdef VERYDEBUG cprintf(GREEN,"%d numpackets: %d for fifo :%d\n", ithread, numpackets[i], i); #endif @@ -2080,17 +2097,22 @@ int UDPStandardImplementation::startWriting(){ #endif }else{ endofacquisition = false; - if(numpackets[i] == 1040){ - cprintf(BLUE,"tempframenum[%d]:%d\n",i,((*(uint32_t*)(((eiger_packet_1g *)((char*)(wbuf[i] + HEADER_SIZE_NUM_TOT_PACKETS)))->framenum)))); - cprintf(BLUE,"packetnum[%d]:%d\n",i,((*(uint16_t*)(((eiger_packet_1g *)((char*)(wbuf[i] + HEADER_SIZE_NUM_TOT_PACKETS)))->packetnum)))); + if(numpackets[i] == 1040){; +#ifdef EIGER_DEBUG3 + wbuf_footer = (eiger_packet_footer_t*)(wbuf[i] + footer_offset + HEADER_SIZE_NUM_TOT_PACKETS); + //cprintf(BLUE,"footer value:0x%x\n",i,(uint64_t)(*( (uint64_t*) wbuf_footer))); + cprintf(BLUE,"tempframenum[%d]:%d\n",i,(uint32_t)(*( (uint64_t*) wbuf_footer))); + cprintf(BLUE,"packetnum[%d]:%d\n",i,*( (uint16_t*) wbuf_footer->packetnum)); +#endif }else if(numpackets[i] == EIGER_HEADER_LENGTH){ cprintf(BG_RED, "got header in writer, weirdd packetsize:%d\n",numpackets[i]); exit(-1); - }else { - cprintf(BG_RED, "got weird in writer, weirdd packetsize:%d\n",numpackets[i]); - } - +//#ifdef EIGER_DEBUG3 + else { + cprintf(BG_RED, "got weird in writer, weirdd packetsize:%d\n",numpackets[i]); + } +//#endif if(myDetectorType == EIGER){ tofree[tofreeoffset[i]] = wbuf[i]; tofreeoffset[i]++; @@ -2104,9 +2126,9 @@ int UDPStandardImplementation::startWriting(){ //END OF ACQUISITION if(endofacquisition){ -//#ifdef VERYDEBUG +#ifdef EIGER_DEBUG3 cprintf(GREEN,"%d Both dummy frames\n", ithread); -//#endif +#endif //remaining packets to be written if((myDetectorType == EIGER) && ((tempoffset[0]!=0) || (tempoffset[1]!=(packetsPerFrame/numListeningThreads)))); @@ -2121,6 +2143,8 @@ int UDPStandardImplementation::startWriting(){ if(myDetectorType == EIGER){ + + //NOT FULL FRAME if(!fullframe[0] || !fullframe[1]){ for(i=0;imissingpacket)) - cprintf(RED,"1 fifo:%d missing packet added at pnum:%d\n",i,tempoffset[i]); - else cprintf(RED, "1 fifo:%d Weird at pnum:%d\n",i,tempoffset[i]); -#endif - if ((*(uint8_t*)(((eiger_packet_1g *)((char*)(tempbuffer[tempoffset[i]])))->missingpacket))!= 0xFF){ - cprintf(BG_RED, "dummy blank mismatch num4 earlier2! i:%d pnum:%d fnum:%d missingpacket:0x%x actual missingpacket:0x%x\n", + + tempframe_header = (eiger_packet_header_t*) tempbuffer[tempoffset[i]]; + blankframe_header = (eiger_packet_header_t*) blankframe[blankoffset]; + if (*( (uint16_t*) tempframe_header->missingpacket)!= missingPacketValue){ + cprintf(BG_RED, "dummy blank mismatch num4 earlier2! " + "i:%d pnum:%d fnum:%d missingpacket:0x%x actual missingpacket:0x%x\n", i,tempoffset[i],tempframenum[i], - (*(uint8_t*)(((eiger_packet_1g *)((char*)(tempbuffer[tempoffset[i]])))->missingpacket)), - (*(uint8_t*)(((eiger_packet_1g *)((char*)(blankframe[blankoffset])))->missingpacket))); + *( (uint16_t*) tempframe_header->missingpacket), + *( (uint16_t*) blankframe_header->missingpacket)); exit(-1); }else -//#ifdef PADDING - cprintf(GREEN, "blank packet i:%d pnum:%d fnum:%d missingpacket:0x%x\n",i,tempoffset[i],tempframenum[i],(*(uint8_t*)(((eiger_packet_1g *)((char*)(tempbuffer[tempoffset[i]])))->missingpacket))); -//#endif +#ifdef PADDING + cprintf(GREEN, "blank packet i:%d pnum:%d fnum:%d missingpacket:0x%x\n",i, + tempoffset[i],tempframenum[i],*( (uint16_t*) tempframe_header->missingpacket)); +#endif tempoffset[i]++; blankoffset++; } @@ -2184,9 +2208,12 @@ int UDPStandardImplementation::startWriting(){ //not a full frame if(!fullframe[i]){ - + wbuf_footer = (eiger_packet_footer_t*)(wbuf[i] + footer_offset + HEADER_SIZE_NUM_TOT_PACKETS); +#ifdef EIGER_DEBUG3 + cprintf(GREEN,"**pnum of %d: %d\n",i,(*( (uint16_t*) wbuf_footer->packetnum))); +#endif //update frame number - tempframenum[i] = ((*(uint32_t*)(((eiger_packet_1g *)((char*)(wbuf[i] + HEADER_SIZE_NUM_TOT_PACKETS)))->framenum))); + tempframenum[i] =(uint32_t)(*( (uint64_t*) wbuf_footer)); if(!tempframenum[i]) @@ -2196,16 +2223,18 @@ int UDPStandardImplementation::startWriting(){ //WRONG FRAME - leave if(tempframenum[i] != presentframenum){ -//#ifdef PADDING +#ifdef PADDING cout<<"wrong packet"<framenum))), - ((*(uint16_t*)(((eiger_packet_1g *)((char*)(wbuf[i] + HEADER_SIZE_NUM_TOT_PACKETS)))->packetnum)))); -//#endif + (uint32_t)(*( (uint64_t*) wbuf_footer)), + *( (uint16_t*) wbuf_footer->packetnum)); + +#endif tempframenum[i] = presentframenum; //add missing packets numberofmissingpackets[i] = (LAST_PACKET_VALUE - lastpacketheader[i]); @@ -2216,26 +2245,24 @@ int UDPStandardImplementation::startWriting(){ //to decrement from packetsInFile to calculate packet loss for(j=0;jmissingpacket))== 0xFF) - cprintf(RED,"5 fifo:%d missing packet added at pnum:%d\n",i,tempoffset[i]); - else cprintf(RED, "5 fifo:%d WEird at pnum:%d\n",i,tempoffset[i]); -#endif - if ((*(uint8_t*)(((eiger_packet_1g *)((char*)(tempbuffer[tempoffset[i]])))->missingpacket))!= 0xFF){ + + tempframe_header = (eiger_packet_header_t*) tempbuffer[tempoffset[i]]; + blankframe_header = (eiger_packet_header_t*) blankframe[blankoffset]; + if (*( (uint16_t*) tempframe_header->missingpacket)!= missingPacketValue){ cprintf(BG_RED, "wrong blank mismatch num4 earlier2! " "i:%d pnum:%d fnum:%d missingpacket:0x%x actual missingpacket:0x%x add:0x%x\n", i,tempoffset[i],tempframenum[i], - (*(uint8_t*)(((eiger_packet_1g *)((char*)(tempbuffer[tempoffset[i]])))->missingpacket)), - (*(uint8_t*)(((eiger_packet_1g *)((char*)(blankframe[blankoffset])))->missingpacket)), + *( (uint16_t*) tempframe_header->missingpacket), + *( (uint16_t*) blankframe_header->missingpacket), (void*)(tempbuffer[tempoffset[i]])); exit(-1); }else -//#ifdef PADDING +#ifdef PADDING cprintf(GREEN, "blank packet i:%d pnum:%d fnum:%d missingpacket:0x%x add:0x%x\n", i,tempoffset[i],tempframenum[i], - (*(uint8_t*)(((eiger_packet_1g *)((char*)(tempbuffer[tempoffset[i]])))->missingpacket)), + *( (uint16_t*) tempframe_header->missingpacket), (void*)(tempbuffer[tempoffset[i]])); -//#endif +#endif tempoffset[i] ++; blankoffset ++; } @@ -2247,73 +2274,75 @@ int UDPStandardImplementation::startWriting(){ //CORRECT FRAME - continue building frame else { -//#ifdef PADDING +#ifdef PADDING cout<<"correct packet"<packetnum))); + currentpacketheader[i] = *( (uint16_t*) wbuf_footer->packetnum); #ifdef VERYVERBOSE - cprintf(GREEN,"**fifo:%d currentpacketheader: %d lastpacketheader %d tempoffset:%d\n",i,currentpacketheader[i],lastpacketheader[i], tempoffset[i]); + cprintf(GREEN,"**fifo:%d currentpacketheader: %d lastpacketheader %d tempoffset:%d\n", + i,currentpacketheader[i],lastpacketheader[i], tempoffset[i]); #endif //add missing packets numberofmissingpackets[i] = (currentpacketheader[i] - lastpacketheader[i] -1); #ifdef VERYDEBUG if(numberofmissingpackets[i]>0) - cprintf(BG_RED,"fifo:%d missing packet from: %d now at :%d tempoffset:%d\n",i,lastpacketheader[i],currentpacketheader[i],tempoffset[i]); + cprintf(BG_RED,"fifo:%d missing packet from: %d now at :%d tempoffset:%d\n", + i,lastpacketheader[i],currentpacketheader[i],tempoffset[i]); #endif //to decrement from packetsInFile to calculate packet loss for(j=0;jmissingpacket)) ==0xFF) - cprintf(RED,"4 fifo:%d missing packet added at pnum:%d\n",i,tempoffset[i]); - else cprintf(RED, "4 fifo:%d WEird at pnum:%d\n",i,tempoffset[i]); -#endif - if ((*(uint8_t*)(((eiger_packet_1g *)((char*)(tempbuffer[tempoffset[i]])))->missingpacket))!= 0xFF){ + + tempframe_header = (eiger_packet_header_t*) tempbuffer[tempoffset[i]]; + blankframe_header = (eiger_packet_header_t*) blankframe[blankoffset]; + if (*( (uint16_t*) tempframe_header->missingpacket)!= missingPacketValue){ cprintf(BG_RED, "correct blank mismatch num4 earlier2! " "i:%d pnum:%d fnum:%d missingpacket:0x%x actual missingpacket:0x%x add:0x%x\n", i,tempoffset[i],tempframenum[i], - (*(uint8_t*)(((eiger_packet_1g *)((char*)(tempbuffer[tempoffset[i]])))->missingpacket)), - (*(uint8_t*)(((eiger_packet_1g *)((char*)(blankframe[blankoffset])))->missingpacket)), + *( (uint16_t*) tempframe_header->missingpacket), + *( (uint16_t*) blankframe_header->missingpacket), (void*)(tempbuffer[tempoffset[i]])); exit(-1); }else -//#ifdef PADDING +#ifdef PADDING cprintf(GREEN, "blank packet i:%d pnum:%d fnum:%d missingpacket:0x%x add:0x%x\n", i,tempoffset[i],tempframenum[i], - (*(uint8_t*)(((eiger_packet_1g *)((char*)(tempbuffer[tempoffset[i]])))->missingpacket)), + *( (uint16_t*) tempframe_header->missingpacket), (void*)(tempbuffer[tempoffset[i]])); -//#endif +#endif tempoffset[i] ++; blankoffset ++; } //add current packet - - if(currentpacketheader[i] != (tempoffset[i]-(i*packetsPerFrame/numListeningThreads))){ + if(currentpacketheader[i] != (tempoffset[i]-(i*packetsPerFrame/numListeningThreads))+1){ cprintf(BG_RED, "correct pnum mismatch earlier! tempoffset[%d]:%d pnum:%d fnum:%d rfnum:%d\n", i,tempoffset[i],currentpacketheader[i], - tempframenum[i],(*(uint32_t*)(((eiger_packet_1g *)((char*)(wbuf[i]+ HEADER_SIZE_NUM_TOT_PACKETS)))->framenum))); + tempframenum[i],(uint32_t)(*( (uint64_t*) wbuf_footer))); exit(-1); } + tempbuffer[tempoffset[i]] = wbuf[i] + HEADER_SIZE_NUM_TOT_PACKETS; + tempframe_footer = (eiger_packet_footer_t*) (tempbuffer[tempoffset[i]] + footer_offset); #ifdef EIGER_DEBUG3 - cprintf(GREEN,"**fifo:%d currentpacketheader: %d tempoffset:%d\n",i,(*(uint16_t*)(((eiger_packet_1g *)((char*)(tempbuffer[tempoffset[i]])))->packetnum)),tempoffset[i]); + cprintf(GREEN,"**fifo:%d currentpacketheader: %d tempoffset:%d\n", + i,*( (uint16_t*) tempframe_footer->packetnum),tempoffset[i]); #endif - if((*(uint16_t*)(((eiger_packet_1g *)((char*)(tempbuffer[tempoffset[i]])))->packetnum)) != (tempoffset[i]-(i*packetsPerFrame/numListeningThreads))){ - cprintf(BG_RED, "pnum mismatch num4 earlier! i:%d pnum:%d fnum:%d add:0x%x\n", - i,(*(uint16_t*)(((eiger_packet_1g *)((char*)(tempbuffer[tempoffset[i]])))->packetnum)), + if(*( (uint16_t*) tempframe_footer->packetnum)!= (tempoffset[i]-(i*packetsPerFrame/numListeningThreads))+1){ + cprintf(BG_RED, "pnum mismatch num4 earlier! i:%d pnum:%d pnum orig:%d fnum:%d add:0x%x\n", + i,*( (uint16_t*) tempframe_footer->packetnum),*( (uint16_t*) wbuf_footer->packetnum), tempframenum[i],(void*)(tempbuffer[tempoffset[i]])); exit(-1); } -//#ifdef PADDING +#ifdef PADDING cprintf(GREEN, "normal packet i:%d pnum:%d fnum:%d missingpacket:0x%x add:0x%x\n", i,tempoffset[i],tempframenum[i], - (*(uint8_t*)(((eiger_packet_1g *)((char*)(tempbuffer[tempoffset[i]])))->missingpacket)), + *( (uint16_t*) tempframe_footer->packetnum), (void*)(tempbuffer[tempoffset[i]])); -//#endif +#endif tempoffset[i] ++; //update last packet lastpacketheader[i] = currentpacketheader[i]; @@ -2343,10 +2372,10 @@ int UDPStandardImplementation::startWriting(){ numMissingPackets += (numberofmissingpackets[0]+numberofmissingpackets[1]); numTotMissingPacketsInFile += numMissingPackets; numTotMissingPackets += numMissingPackets; -//#ifdef EIGER_DEBUG2 +#ifdef EIGER_DEBUG2 cprintf(GREEN,"**fnum:%d**\n",currframenum); -//#endif -//#ifdef EIGER_DEBUG3 +#endif +#ifdef EIGER_DEBUG3 if(numberofmissingpackets[0]) cprintf(RED, "fifo 0 missing packets:%d fnum:%d\n",numberofmissingpackets[0],currframenum); if(numberofmissingpackets[1]) @@ -2354,11 +2383,13 @@ int UDPStandardImplementation::startWriting(){ if(numMissingPackets){ cprintf(RED, "numMissingPackets:%d fnum:%d\n",numMissingPackets,currframenum); - for (j=0;jmissingpacket))==0xFF) + for (j=0;jmissingpacket)==missingPacketValue) cprintf(RED,"found the missing packet at pnum:%d\n",j); + } } -//#endif +#endif //write and copy to gui @@ -2378,9 +2409,9 @@ int UDPStandardImplementation::startWriting(){ cprintf(GREEN,"%d writer freed pushed into fifofree %x for listener %d\n",ithread, (void*)(tofree[j]),1); #endif } -//#ifdef VERYDEBUG +#ifdef VERYDEBUG cprintf(GREEN,"finished freeing\n"); -//#endif +#endif //reset a few stuff @@ -2394,19 +2425,20 @@ int UDPStandardImplementation::startWriting(){ tempoffset[i] = (i*packetsPerFrame/numListeningThreads); tofreeoffset[i] = (i*packetsPerFrame/numListeningThreads); blankoffset = 0; - lastpacketheader[i] = -1; - currentpacketheader[i] = -1; + lastpacketheader[i] = 0; + currentpacketheader[i] = 0; numberofmissingpackets[i] = 0; } } -//#ifdef VERYDEBUG +#ifdef VERYDEBUG for(int i=0;iframenum)))); - cprintf(GREEN,"packetnum[%d]:%d\n",i,((*(uint16_t*)(((eiger_packet_1g *)((char*)(wbuf[i] + HEADER_SIZE_NUM_TOT_PACKETS)))->packetnum)))); + cprintf(GREEN,"tempframenum[%d]:%d\n",i,(uint32_t)(*( (uint64_t*) wbuf_footer))); + cprintf(GREEN,"packetnum[%d]:%d\n",i,*( (uint16_t*) wbuf_footer->packetnum)); } -//#endif +#endif } @@ -2838,8 +2870,6 @@ void UDPStandardImplementation::handleWithoutDataCompression(int ithread, char* int i,j, missingpacket,port = 0, pnuminc; - - if (cbAction < DO_EVERYTHING){ if (myDetectorType == EIGER){ for(i=0;ipacketnum)); +#endif //which port if (i ==(packetsPerFrame/2)) port = 1; @@ -2863,77 +2902,51 @@ void UDPStandardImplementation::handleWithoutDataCompression(int ithread, char* //missing packet - if ((*(uint8_t*)(((eiger_packet_1g *)((char*)(wbuffer[i])))->missingpacket))==0xFF){ + if (*( (uint16_t*) wbuf_header->missingpacket)== missingPacketValue){ +#ifdef VERY_VERBOSE + cprintf(GREEN,"missing packet at %d\n", i+1); +#endif missingpacket = 1; - //add packet numbers - (*(uint16_t*)(((eiger_packet_1g *)((char*)(wbuffer[i])))->packetnum)) = (i+1); - (*(uint32_t*)(((eiger_packet_1g *)((char*)(wbuffer[i])))->framenum)) = currframenum+1; + //add frame and packet numbers + *( (uint64_t*) wbuf_footer) = (uint64_t)((currframenum+1)); + *( (uint16_t*) wbuf_footer->packetnum) = (i+1); }else{ missingpacket = 0; - if((*(uint16_t*)(((eiger_packet_1g *)((char*)(wbuffer[i])))->packetnum)) != (i-(port*packetsPerFrame/numListeningThreads))){ - cprintf(BG_RED, "pnum mismatch num4! i:%d pnum:%d fnum:%d\n",i,(*(uint16_t*)(((eiger_packet_1g *)((char*)(wbuffer[i])))->packetnum)),currframenum); + if(*( (uint16_t*) wbuf_footer->packetnum)!= (i-(port*packetsPerFrame/numListeningThreads))+1){ + cprintf(BG_RED, "pnum mismatch num4! i:%d pnum:%d fnum:%d\n", + i,*( (uint16_t*) wbuf_footer->packetnum),currframenum); exit(-1); } - - /* if(dynamicRange != 32){*/ //move packet numbers to num2, and compensate for port1 starting pnum from 0 - if(!port) - (*(uint16_t*)(((eiger_packet_1g *)((char*)(wbuffer[i])))->packetnum)) = - ((*(uint16_t*)(((eiger_packet_1g *)((char*)(wbuffer[i])))->packetnum))+1); - else - (*(uint16_t*)(((eiger_packet_1g *)((char*)(wbuffer[i])))->packetnum)) = - ((*(uint16_t*)(((eiger_packet_1g *)((char*)(wbuffer[i])))->packetnum))+(packetsPerFrame/2) +1); - /*} - //dr == 32 - else{ - if(i == 0) - pnuminc = 0; - else if(i == (packetsPerFrame/4)) - pnuminc = (packetsPerFrame/4); - else if(i == (packetsPerFrame/2)) - pnuminc = (packetsPerFrame/2); - else if(i == (3*packetsPerFrame/4)) - pnuminc = (3*packetsPerFrame/4); - (*(uint16_t*)(((eiger_packet_1g *)((char*)(wbuffer[i])))->packetnum)) - = ((*(uint8_t*)(((eiger_packet_1g *)((char*)(wbuffer[i])))->packetnum,))+pnuminc+1); - - }*/ + if(port) + *( (uint16_t*) wbuf_footer->packetnum) = (*( (uint16_t*) wbuf_footer->packetnum))+(packetsPerFrame/2); } - - if((*(uint16_t*)(((eiger_packet_1g *)((char*)(wbuffer[i])))->packetnum)) != (i+1)){ - cprintf(BG_RED, "pnum mismatch! i:%d pnum:%d fnum:%d\n",i,(*(uint16_t*)(((eiger_packet_1g *)((char*)(wbuffer[i])))->packetnum)),currframenum); - if ((*(uint8_t*)(((eiger_packet_1g *)((char*)(wbuffer[i])))->missingpacket))==0xFF) + if(*( (uint16_t*) wbuf_footer->packetnum) != (i+1)){ + cprintf(BG_RED, "pnum mismatch! i:%d pnum:%d fnum:%d\n", + i,*( (uint16_t*) wbuf_footer->packetnum),currframenum); + if (*( (uint16_t*) wbuf_header->missingpacket) == missingPacketValue) cprintf(BG_RED,"missing packet though\n"); exit(-1); } //overwriting port number and dynamic range - (*(uint8_t*)(((eiger_packet_1g *)((char*)(wbuffer[i])))->missingpacket)) = - ((dynamicRange<<2)|(missingpacket<<1)|(port)); + *( (uint8_t*) wbuf_header->portnum) = port; + *( (uint8_t*) wbuf_header->dynamicrange) = dynamicRange; - //frame number - //(*(uint32_t*)(((eiger_packet_1g *)((char*)(wbuffer[i])))->framenum)) = currframenum; #ifdef VERYDEBUG if((i==0)||(i==1)){ cprintf(GREEN, "%d packet header:0x%016llx missingpacket:0x%x\n",i, - ((uint64_t)(*((uint64_t*)(wbuffer[i])))), - (uint8_t)(*(uint8_t*)(((eiger_packet_1g *)((char*)(wbuffer[i])))->missingpacket))); + (uint64_t)()*( (uint64_t*) wbuf_header)), *( (uint16_t*) wbuf_header->missingpacket)); cprintf(GREEN, "%d - 0x%x - %d\n", i, - (*(uint8_t*)(((eiger_packet_1g *)((char*)(wbuffer[i])))->missingpacket)), - (*(uint16_t*)(((eiger_packet_1g *)((char*)(wbuffer[i])))->packetnum))); + *( (uint16_t*) wbuf_header->missingpacket), *( (uint16_t*) wbuf_footer->packetnum)); } #endif -/* - cprintf(GREEN,"at writing, fnum:%d, pnum:%d,missingpacket:0x%x add:0x%x\n", - currframenum, i, (*(uint8_t*)(((eiger_packet_1g *)((char*)(wbuffer[i])))->missingpacket)), - (void*)(wbuffer[i])); -*/ } } From 5368103efa36c625ea36b81a6af41389bb07dc46 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 15 Sep 2015 15:40:54 +0200 Subject: [PATCH 135/474] 10g gui bottom offset bug fix --- slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp index 65dbd890c..aa799d380 100644 --- a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp +++ b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp @@ -1629,11 +1629,12 @@ int slsReceiverTCPIPInterface::eiger_read_frame(){ int linesperpacket = (16*1/dynamicrange);// 16:1 line, 8:2 lines, 4:4 lines, 32: 0.5 int numbytesperlineperport=(EIGER_PIXELS_IN_ONE_ROW/EIGER_MAX_PORTS)*dynamicrange/8;//16:1024,8:512,4:256,32:2048 int datapacketlength = EIGER_ONE_GIGA_ONE_DATA_SIZE; - int total_num_bytes = 1040*(16*dynamicrange)*2; + int total_num_bytes = EIGER_ONE_GIGA_ONE_PACKET_SIZE *(EIGER_ONE_GIGA_CONSTANT *dynamicrange)*2; if(tenGigaEnable){ linesperpacket = (16*4/dynamicrange);// 16:4 line, 8:8 lines, 4:16 lines, 32: 2 datapacketlength = EIGER_TEN_GIGA_ONE_DATA_SIZE; + total_num_bytes = EIGER_TEN_GIGA_ONE_PACKET_SIZE*(EIGER_TEN_GIGA_CONSTANT*dynamicrange)*2; } //if 1GbE, one line is split into two packets for 32 bit mode, so its special else if(dynamicrange == 32){ From c7017eef5b720f67723c00cfa6308f19a88b35d5 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 15 Sep 2015 15:41:58 +0200 Subject: [PATCH 136/474] 10g gui bottom offset bug fix --- slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp index ea0336895..17ff75764 100644 --- a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp +++ b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp @@ -1630,11 +1630,12 @@ int slsReceiverTCPIPInterface::eiger_read_frame(){ int linesperpacket = (16*1/dynamicrange);// 16:1 line, 8:2 lines, 4:4 lines, 32: 0.5 int numbytesperlineperport=(EIGER_PIXELS_IN_ONE_ROW/EIGER_MAX_PORTS)*dynamicrange/8;//16:1024,8:512,4:256,32:2048 int datapacketlength = EIGER_ONE_GIGA_ONE_DATA_SIZE; - int total_num_bytes = 1040*(16*dynamicrange)*2; + int total_num_bytes = EIGER_ONE_GIGA_ONE_PACKET_SIZE *(EIGER_ONE_GIGA_CONSTANT *dynamicrange)*2; if(tenGigaEnable){ linesperpacket = (16*4/dynamicrange);// 16:4 line, 8:8 lines, 4:16 lines, 32: 2 datapacketlength = EIGER_TEN_GIGA_ONE_DATA_SIZE; + total_num_bytes = EIGER_TEN_GIGA_ONE_PACKET_SIZE*(EIGER_TEN_GIGA_CONSTANT*dynamicrange)*2; } //if 1GbE, one line is split into two packets for 32 bit mode, so its special else if(dynamicrange == 32){ From 1b471bc6759d6e9c49a32e627dbf843d7b5a7ee6 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Thu, 17 Sep 2015 09:14:00 +0200 Subject: [PATCH 137/474] partial_frames for 10g bug fixed specifzing literal 1024 for allowed packet size in startwritign --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index d55a1f1fc..8c68403b6 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1962,7 +1962,7 @@ int UDPStandardImplementation::startWriting(){ uint32_t lastpacketheader[numListeningThreads], currentpacketheader[numListeningThreads]; int numberofmissingpackets[numListeningThreads]; - int MAX_VALUE = 1024; + int MAX_VALUE = 1024;//32 bit number of packets char* tofree[MAX_VALUE]; char* tempbuffer[MAX_VALUE]; char* blankframe[MAX_VALUE]; @@ -2097,7 +2097,7 @@ int UDPStandardImplementation::startWriting(){ #endif }else{ endofacquisition = false; - if(numpackets[i] == 1040){; + if(numpackets[i] == bufferSize){; #ifdef EIGER_DEBUG3 wbuf_footer = (eiger_packet_footer_t*)(wbuf[i] + footer_offset + HEADER_SIZE_NUM_TOT_PACKETS); //cprintf(BLUE,"footer value:0x%x\n",i,(uint64_t)(*( (uint64_t*) wbuf_footer))); From b3012acea2a1e26d23ae9a32cc0833f844fbc907 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Thu, 17 Sep 2015 12:03:11 +0200 Subject: [PATCH 138/474] bug fixxed for 10g writing filter, still debug mode --- .../src/UDPStandardImplementation.cpp | 81 ++++++++++--------- 1 file changed, 41 insertions(+), 40 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 8c68403b6..10ed49463 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -2092,18 +2092,18 @@ int UDPStandardImplementation::startWriting(){ //dont pop again if dummy packet else if(numpackets[i] == 0){ popready[i] = false; -#ifdef EIGER_DEBUG3 +//#ifdef EIGER_DEBUG3 cprintf(GREEN,"%d Dummy frame popped out of fifo %d",ithread, i); -#endif +//#endif }else{ endofacquisition = false; - if(numpackets[i] == bufferSize){; -#ifdef EIGER_DEBUG3 + if(numpackets[i] == onePacketSize){; +//#ifdef EIGER_DEBUG3 wbuf_footer = (eiger_packet_footer_t*)(wbuf[i] + footer_offset + HEADER_SIZE_NUM_TOT_PACKETS); //cprintf(BLUE,"footer value:0x%x\n",i,(uint64_t)(*( (uint64_t*) wbuf_footer))); cprintf(BLUE,"tempframenum[%d]:%d\n",i,(uint32_t)(*( (uint64_t*) wbuf_footer))); cprintf(BLUE,"packetnum[%d]:%d\n",i,*( (uint16_t*) wbuf_footer->packetnum)); -#endif +//#endif }else if(numpackets[i] == EIGER_HEADER_LENGTH){ cprintf(BG_RED, "got header in writer, weirdd packetsize:%d\n",numpackets[i]); exit(-1); @@ -2126,9 +2126,9 @@ int UDPStandardImplementation::startWriting(){ //END OF ACQUISITION if(endofacquisition){ -#ifdef EIGER_DEBUG3 +//#ifdef EIGER_DEBUG3 cprintf(GREEN,"%d Both dummy frames\n", ithread); -#endif +//#endif //remaining packets to be written if((myDetectorType == EIGER) && ((tempoffset[0]!=0) || (tempoffset[1]!=(packetsPerFrame/numListeningThreads)))); @@ -2157,15 +2157,15 @@ int UDPStandardImplementation::startWriting(){ if(numpackets[i] == EIGER_HEADER_LENGTH) {cprintf(BG_RED,"weird, frame packet recieved\n"); exit(-1);} //dummy packet else if(!numpackets[i]){ -#ifdef EIGER_DEBUG3 +//#ifdef EIGER_DEBUG3 cprintf(RED, "Dummy packet: %d from fifo %d\n", numpackets[i],i); -#endif +//#endif cout<<"tempoffset["<missingpacket)); exit(-1); }else -#ifdef PADDING +//#ifdef PADDING cprintf(GREEN, "blank packet i:%d pnum:%d fnum:%d missingpacket:0x%x\n",i, tempoffset[i],tempframenum[i],*( (uint16_t*) tempframe_header->missingpacket)); -#endif +//#endif tempoffset[i]++; blankoffset++; } @@ -2209,9 +2209,9 @@ int UDPStandardImplementation::startWriting(){ //not a full frame if(!fullframe[i]){ wbuf_footer = (eiger_packet_footer_t*)(wbuf[i] + footer_offset + HEADER_SIZE_NUM_TOT_PACKETS); -#ifdef EIGER_DEBUG3 +//#ifdef EIGER_DEBUG3 cprintf(GREEN,"**pnum of %d: %d\n",i,(*( (uint16_t*) wbuf_footer->packetnum))); -#endif +//#endif //update frame number tempframenum[i] =(uint32_t)(*( (uint64_t*) wbuf_footer)); @@ -2223,18 +2223,18 @@ int UDPStandardImplementation::startWriting(){ //WRONG FRAME - leave if(tempframenum[i] != presentframenum){ -#ifdef PADDING +//#ifdef PADDING cout<<"wrong packet"<packetnum)); -#endif +//#endif tempframenum[i] = presentframenum; //add missing packets numberofmissingpackets[i] = (LAST_PACKET_VALUE - lastpacketheader[i]); @@ -2257,12 +2257,12 @@ int UDPStandardImplementation::startWriting(){ (void*)(tempbuffer[tempoffset[i]])); exit(-1); }else -#ifdef PADDING +//#ifdef PADDING cprintf(GREEN, "blank packet i:%d pnum:%d fnum:%d missingpacket:0x%x add:0x%x\n", i,tempoffset[i],tempframenum[i], *( (uint16_t*) tempframe_header->missingpacket), (void*)(tempbuffer[tempoffset[i]])); -#endif +//#endif tempoffset[i] ++; blankoffset ++; } @@ -2274,12 +2274,12 @@ int UDPStandardImplementation::startWriting(){ //CORRECT FRAME - continue building frame else { -#ifdef PADDING +//#ifdef PADDING cout<<"correct packet"<packetnum); #ifdef VERYVERBOSE @@ -2308,12 +2308,12 @@ int UDPStandardImplementation::startWriting(){ (void*)(tempbuffer[tempoffset[i]])); exit(-1); }else -#ifdef PADDING +//#ifdef PADDING cprintf(GREEN, "blank packet i:%d pnum:%d fnum:%d missingpacket:0x%x add:0x%x\n", i,tempoffset[i],tempframenum[i], *( (uint16_t*) tempframe_header->missingpacket), (void*)(tempbuffer[tempoffset[i]])); -#endif +//#endif tempoffset[i] ++; blankoffset ++; } @@ -2326,32 +2326,33 @@ int UDPStandardImplementation::startWriting(){ } tempbuffer[tempoffset[i]] = wbuf[i] + HEADER_SIZE_NUM_TOT_PACKETS; + tempframe_header = (eiger_packet_header_t*) tempbuffer[tempoffset[i]]; tempframe_footer = (eiger_packet_footer_t*) (tempbuffer[tempoffset[i]] + footer_offset); -#ifdef EIGER_DEBUG3 +//#ifdef EIGER_DEBUG3 cprintf(GREEN,"**fifo:%d currentpacketheader: %d tempoffset:%d\n", i,*( (uint16_t*) tempframe_footer->packetnum),tempoffset[i]); -#endif +//#endif if(*( (uint16_t*) tempframe_footer->packetnum)!= (tempoffset[i]-(i*packetsPerFrame/numListeningThreads))+1){ cprintf(BG_RED, "pnum mismatch num4 earlier! i:%d pnum:%d pnum orig:%d fnum:%d add:0x%x\n", i,*( (uint16_t*) tempframe_footer->packetnum),*( (uint16_t*) wbuf_footer->packetnum), tempframenum[i],(void*)(tempbuffer[tempoffset[i]])); exit(-1); } -#ifdef PADDING +//#ifdef PADDING cprintf(GREEN, "normal packet i:%d pnum:%d fnum:%d missingpacket:0x%x add:0x%x\n", i,tempoffset[i],tempframenum[i], - *( (uint16_t*) tempframe_footer->packetnum), + *( (uint16_t*) tempframe_header->missingpacket), (void*)(tempbuffer[tempoffset[i]])); -#endif +//#endif tempoffset[i] ++; //update last packet lastpacketheader[i] = currentpacketheader[i]; popready[i] = true; //last frame got, this will save time and also for last frames, it doesnt wait for stop receiver if(currentpacketheader[i] == LAST_PACKET_VALUE){ -#ifdef EIGER_DEBUG3 +//#ifdef EIGER_DEBUG3 cprintf(GREEN, "Got last packet\n"); -#endif +//#endif fullframe[i] = true; popready[i] = false; } @@ -2372,10 +2373,10 @@ int UDPStandardImplementation::startWriting(){ numMissingPackets += (numberofmissingpackets[0]+numberofmissingpackets[1]); numTotMissingPacketsInFile += numMissingPackets; numTotMissingPackets += numMissingPackets; -#ifdef EIGER_DEBUG2 +//#ifdef EIGER_DEBUG2 cprintf(GREEN,"**fnum:%d**\n",currframenum); -#endif -#ifdef EIGER_DEBUG3 +//#endif +//#ifdef EIGER_DEBUG3 if(numberofmissingpackets[0]) cprintf(RED, "fifo 0 missing packets:%d fnum:%d\n",numberofmissingpackets[0],currframenum); if(numberofmissingpackets[1]) @@ -2389,7 +2390,7 @@ int UDPStandardImplementation::startWriting(){ cprintf(RED,"found the missing packet at pnum:%d\n",j); } } -#endif +//#endif //write and copy to gui @@ -2431,14 +2432,14 @@ int UDPStandardImplementation::startWriting(){ } } -#ifdef VERYDEBUG +//#ifdef EIGER_DEBUG3 for(int i=0;ipacketnum)); } -#endif +//#endif } From 5a4dfd128d9dbe58c106fc39d4ddf8cd3dda03d0 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Thu, 17 Sep 2015 12:29:16 +0200 Subject: [PATCH 139/474] 10g partial_frames should also work now --- .../src/UDPStandardImplementation.cpp | 97 +++++++++++-------- 1 file changed, 55 insertions(+), 42 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 10ed49463..b0a24ebc0 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -2047,9 +2047,21 @@ int UDPStandardImplementation::startWriting(){ cprintf(GREEN,"packet %d blank frame 0x%x\n",i,(void*)(blankframe[i])); #endif } + + if(tengigaEnable){ + switch(dynamicRange){ + case 4: LAST_PACKET_VALUE = 0x10; break; + case 8: LAST_PACKET_VALUE = 0x20; break; + case 16: LAST_PACKET_VALUE = 0x40; break; + case 32: LAST_PACKET_VALUE = 0x80; break; + default: break; + } + } } + + //allow them all to be popped initially for(i=0;ipacketnum)); -//#endif +#endif }else if(numpackets[i] == EIGER_HEADER_LENGTH){ cprintf(BG_RED, "got header in writer, weirdd packetsize:%d\n",numpackets[i]); exit(-1); } -//#ifdef EIGER_DEBUG3 +#ifdef EIGER_DEBUG3 else { cprintf(BG_RED, "got weird in writer, weirdd packetsize:%d\n",numpackets[i]); } -//#endif +#endif if(myDetectorType == EIGER){ tofree[tofreeoffset[i]] = wbuf[i]; tofreeoffset[i]++; @@ -2126,9 +2138,9 @@ int UDPStandardImplementation::startWriting(){ //END OF ACQUISITION if(endofacquisition){ -//#ifdef EIGER_DEBUG3 +#ifdef EIGER_DEBUG3 cprintf(GREEN,"%d Both dummy frames\n", ithread); -//#endif +#endif //remaining packets to be written if((myDetectorType == EIGER) && ((tempoffset[0]!=0) || (tempoffset[1]!=(packetsPerFrame/numListeningThreads)))); @@ -2157,15 +2169,16 @@ int UDPStandardImplementation::startWriting(){ if(numpackets[i] == EIGER_HEADER_LENGTH) {cprintf(BG_RED,"weird, frame packet recieved\n"); exit(-1);} //dummy packet else if(!numpackets[i]){ -//#ifdef EIGER_DEBUG3 +#ifdef EIGER_DEBUG3 cprintf(RED, "Dummy packet: %d from fifo %d\n", numpackets[i],i); -//#endif +#endif + cout<<"packetsperframe:"<missingpacket)); exit(-1); }else -//#ifdef PADDING +#ifdef PADDING cprintf(GREEN, "blank packet i:%d pnum:%d fnum:%d missingpacket:0x%x\n",i, tempoffset[i],tempframenum[i],*( (uint16_t*) tempframe_header->missingpacket)); -//#endif +#endif tempoffset[i]++; blankoffset++; } @@ -2194,12 +2207,12 @@ int UDPStandardImplementation::startWriting(){ popready[i] = false; } } -//#ifdef EIGER_DEBUG3 +#ifdef EIGER_DEBUG3 else{ cprintf(RED, "WARNING: Got a weird packet size: %d from fifo %d\n", numpackets[i],i); continue; } -//#endif +#endif } @@ -2209,9 +2222,9 @@ int UDPStandardImplementation::startWriting(){ //not a full frame if(!fullframe[i]){ wbuf_footer = (eiger_packet_footer_t*)(wbuf[i] + footer_offset + HEADER_SIZE_NUM_TOT_PACKETS); -//#ifdef EIGER_DEBUG3 +#ifdef EIGER_DEBUG3 cprintf(GREEN,"**pnum of %d: %d\n",i,(*( (uint16_t*) wbuf_footer->packetnum))); -//#endif +#endif //update frame number tempframenum[i] =(uint32_t)(*( (uint64_t*) wbuf_footer)); @@ -2223,18 +2236,18 @@ int UDPStandardImplementation::startWriting(){ //WRONG FRAME - leave if(tempframenum[i] != presentframenum){ -//#ifdef PADDING +#ifdef PADDING cout<<"wrong packet"<packetnum)); -//#endif +#endif tempframenum[i] = presentframenum; //add missing packets numberofmissingpackets[i] = (LAST_PACKET_VALUE - lastpacketheader[i]); @@ -2257,12 +2270,12 @@ int UDPStandardImplementation::startWriting(){ (void*)(tempbuffer[tempoffset[i]])); exit(-1); }else -//#ifdef PADDING +#ifdef PADDING cprintf(GREEN, "blank packet i:%d pnum:%d fnum:%d missingpacket:0x%x add:0x%x\n", i,tempoffset[i],tempframenum[i], *( (uint16_t*) tempframe_header->missingpacket), (void*)(tempbuffer[tempoffset[i]])); -//#endif +#endif tempoffset[i] ++; blankoffset ++; } @@ -2274,12 +2287,12 @@ int UDPStandardImplementation::startWriting(){ //CORRECT FRAME - continue building frame else { -//#ifdef PADDING +#ifdef PADDING cout<<"correct packet"<packetnum); #ifdef VERYVERBOSE @@ -2308,12 +2321,12 @@ int UDPStandardImplementation::startWriting(){ (void*)(tempbuffer[tempoffset[i]])); exit(-1); }else -//#ifdef PADDING +#ifdef PADDING cprintf(GREEN, "blank packet i:%d pnum:%d fnum:%d missingpacket:0x%x add:0x%x\n", i,tempoffset[i],tempframenum[i], *( (uint16_t*) tempframe_header->missingpacket), (void*)(tempbuffer[tempoffset[i]])); -//#endif +#endif tempoffset[i] ++; blankoffset ++; } @@ -2328,31 +2341,31 @@ int UDPStandardImplementation::startWriting(){ tempbuffer[tempoffset[i]] = wbuf[i] + HEADER_SIZE_NUM_TOT_PACKETS; tempframe_header = (eiger_packet_header_t*) tempbuffer[tempoffset[i]]; tempframe_footer = (eiger_packet_footer_t*) (tempbuffer[tempoffset[i]] + footer_offset); -//#ifdef EIGER_DEBUG3 +#ifdef EIGER_DEBUG3 cprintf(GREEN,"**fifo:%d currentpacketheader: %d tempoffset:%d\n", i,*( (uint16_t*) tempframe_footer->packetnum),tempoffset[i]); -//#endif +#endif if(*( (uint16_t*) tempframe_footer->packetnum)!= (tempoffset[i]-(i*packetsPerFrame/numListeningThreads))+1){ cprintf(BG_RED, "pnum mismatch num4 earlier! i:%d pnum:%d pnum orig:%d fnum:%d add:0x%x\n", i,*( (uint16_t*) tempframe_footer->packetnum),*( (uint16_t*) wbuf_footer->packetnum), tempframenum[i],(void*)(tempbuffer[tempoffset[i]])); exit(-1); } -//#ifdef PADDING +#ifdef PADDING cprintf(GREEN, "normal packet i:%d pnum:%d fnum:%d missingpacket:0x%x add:0x%x\n", i,tempoffset[i],tempframenum[i], *( (uint16_t*) tempframe_header->missingpacket), (void*)(tempbuffer[tempoffset[i]])); -//#endif +#endif tempoffset[i] ++; //update last packet lastpacketheader[i] = currentpacketheader[i]; popready[i] = true; //last frame got, this will save time and also for last frames, it doesnt wait for stop receiver if(currentpacketheader[i] == LAST_PACKET_VALUE){ -//#ifdef EIGER_DEBUG3 +#ifdef EIGER_DEBUG3 cprintf(GREEN, "Got last packet\n"); -//#endif +#endif fullframe[i] = true; popready[i] = false; } @@ -2373,10 +2386,10 @@ int UDPStandardImplementation::startWriting(){ numMissingPackets += (numberofmissingpackets[0]+numberofmissingpackets[1]); numTotMissingPacketsInFile += numMissingPackets; numTotMissingPackets += numMissingPackets; -//#ifdef EIGER_DEBUG2 +#ifdef EIGER_DEBUG2 cprintf(GREEN,"**fnum:%d**\n",currframenum); -//#endif -//#ifdef EIGER_DEBUG3 +#endif +#ifdef EIGER_DEBUG3 if(numberofmissingpackets[0]) cprintf(RED, "fifo 0 missing packets:%d fnum:%d\n",numberofmissingpackets[0],currframenum); if(numberofmissingpackets[1]) @@ -2390,7 +2403,7 @@ int UDPStandardImplementation::startWriting(){ cprintf(RED,"found the missing packet at pnum:%d\n",j); } } -//#endif +#endif //write and copy to gui @@ -2432,14 +2445,14 @@ int UDPStandardImplementation::startWriting(){ } } -//#ifdef EIGER_DEBUG3 +#ifdef EIGER_DEBUG3 for(int i=0;ipacketnum)); } -//#endif +#endif } From 30b83861a427b11b89e8008de79e59461d408738 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Thu, 17 Sep 2015 12:34:17 +0200 Subject: [PATCH 140/474] 10g partial_frames should also work now --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index b0a24ebc0..23bbe0b7a 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -2172,8 +2172,7 @@ int UDPStandardImplementation::startWriting(){ #ifdef EIGER_DEBUG3 cprintf(RED, "Dummy packet: %d from fifo %d\n", numpackets[i],i); #endif - cout<<"packetsperframe:"< Date: Tue, 22 Sep 2015 11:56:37 +0200 Subject: [PATCH 141/474] doesnt crash at frame number 0 --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 23bbe0b7a..6f86b2416 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -2166,7 +2166,7 @@ int UDPStandardImplementation::startWriting(){ //anything that is not a data packet of right size if(numpackets[i] != onePacketSize){ //header packet - if(numpackets[i] == EIGER_HEADER_LENGTH) {cprintf(BG_RED,"weird, frame packet recieved\n"); exit(-1);} + if(numpackets[i] == EIGER_HEADER_LENGTH) {cprintf(BG_RED,"weird, header frame packet recieved. shouldnt\n"); exit(-1);} //dummy packet else if(!numpackets[i]){ #ifdef EIGER_DEBUG3 @@ -2225,11 +2225,11 @@ int UDPStandardImplementation::startWriting(){ cprintf(GREEN,"**pnum of %d: %d\n",i,(*( (uint16_t*) wbuf_footer->packetnum))); #endif //update frame number + if(!((uint32_t)(*( (uint64_t*) wbuf_footer)))){ + cprintf(BG_RED,"**VERY WEIRD frame numbers for fifo %d: %d\n",i,(uint32_t)(*( (uint64_t*) wbuf_footer))); + continue; + } tempframenum[i] =(uint32_t)(*( (uint64_t*) wbuf_footer)); - - - if(!tempframenum[i]) - cprintf(RED,"**VERY WEIRD frame numbers for fifo %d: %d\n",i,tempframenum[i]); tempframenum[i] += (startFrameIndex-1); From 71cd046bed1ea7b449b17fa673a1acf1c53532b4 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 22 Sep 2015 12:16:42 +0200 Subject: [PATCH 142/474] small change to ensure no crash at wrong frame read --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 6f86b2416..5abb79fcc 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -2226,7 +2226,9 @@ int UDPStandardImplementation::startWriting(){ #endif //update frame number if(!((uint32_t)(*( (uint64_t*) wbuf_footer)))){ - cprintf(BG_RED,"**VERY WEIRD frame numbers for fifo %d: %d\n",i,(uint32_t)(*( (uint64_t*) wbuf_footer))); + cprintf(BG_RED,"%d VERY WEIRD frame number=%d and popready:%d\n", + i,(uint32_t)(*( (uint64_t*) wbuf_footer)),popready[i]); + popready[i]=true; continue; } tempframenum[i] =(uint32_t)(*( (uint64_t*) wbuf_footer)); From 7c0430572b731e8476f26fab2e7ebbdc2e8fa535 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 22 Sep 2015 16:21:41 +0200 Subject: [PATCH 143/474] included subframe into receiver and sends to gui --- .../include/UDPBaseImplementation.h | 9 +-- slsReceiverSoftware/include/UDPInterface.h | 3 +- .../include/UDPStandardImplementation.h | 5 +- .../src/UDPBaseImplementation.cpp | 56 ++----------------- .../src/UDPStandardImplementation.cpp | 26 +++------ .../src/slsReceiverTCPIPInterface.cpp | 56 +++++++++++++++---- 6 files changed, 63 insertions(+), 92 deletions(-) diff --git a/slsReceiverSoftware/include/UDPBaseImplementation.h b/slsReceiverSoftware/include/UDPBaseImplementation.h index d69e00b93..cbc4f386c 100644 --- a/slsReceiverSoftware/include/UDPBaseImplementation.h +++ b/slsReceiverSoftware/include/UDPBaseImplementation.h @@ -297,11 +297,10 @@ class UDPBaseImplementation : protected virtual slsReceiverDefs, public UDPInter * Returns the buffer-current frame read by receiver * @param c pointer to current file name * @param raw address of pointer, pointing to current frame to send to gui - * @param fnum frame number for eiger as it is not in the packet * @param startAcquisitionIndex is the start index of the acquisition * @param startFrameIndex is the start index of the scan */ - void readFrame(char* c,char** raw, uint32_t &fnum, uint32_t &startAcquisitionIndex, uint32_t &startFrameIndex); + void readFrame(char* c,char** raw, uint32_t &startAcquisitionIndex, uint32_t &startFrameIndex); /** * Closes all files @@ -359,7 +358,7 @@ protected: * Copy frames to gui * uses semaphore for nth frame mode */ - void copyFrameToGui(char* startbuf[], uint32_t fnum=-1, char* buf=NULL); + void copyFrameToGui(char* startbuf[], char* buf=NULL); /** * creates udp sockets @@ -483,6 +482,7 @@ protected: //// Could be done more fine-grained... TODO // private: protected: + /** structure of an eiger packet*/ typedef struct { @@ -643,9 +643,6 @@ protected: /** points to the filename to send to gui */ char* guiFileName; - /** temporary number for eiger frame number as its not included in the packet */ - uint32_t guiFrameNumber; - /** send every nth frame to gui or only upon gui request*/ int nFrameToGui; diff --git a/slsReceiverSoftware/include/UDPInterface.h b/slsReceiverSoftware/include/UDPInterface.h index 8952396f3..c1d30ec0b 100644 --- a/slsReceiverSoftware/include/UDPInterface.h +++ b/slsReceiverSoftware/include/UDPInterface.h @@ -338,11 +338,10 @@ class UDPInterface { * Returns the buffer-current frame read by receiver * @param c pointer to current file name * @param raw address of pointer, pointing to current frame to send to gui - * @param fnum frame number for eiger as it is not in the packet * @param startAcquisitionIndex is the start index of the acquisition * @param startFrameIndex is the start index of the scan */ - virtual void readFrame(char* c,char** raw, uint32_t &fnum, uint32_t &startAcquisitionIndex, uint32_t &startFrameIndex)=0; + virtual void readFrame(char* c,char** raw, uint32_t &startAcquisitionIndex, uint32_t &startFrameIndex)=0; /** set status to transmitting and * when fifo is empty later, sets status to run_finished diff --git a/slsReceiverSoftware/include/UDPStandardImplementation.h b/slsReceiverSoftware/include/UDPStandardImplementation.h index 92092bead..2916ee6b9 100644 --- a/slsReceiverSoftware/include/UDPStandardImplementation.h +++ b/slsReceiverSoftware/include/UDPStandardImplementation.h @@ -294,11 +294,10 @@ class UDPStandardImplementation: private virtual slsReceiverDefs, public UDPBase * Returns the buffer-current frame read by receiver * @param c pointer to current file name * @param raw address of pointer, pointing to current frame to send to gui - * @param fnum frame number for eiger as it is not in the packet * @param startAcquisitionIndex is the start index of the acquisition * @param startFrameIndex is the start index of the scan */ - void readFrame(char* c,char** raw, uint32_t &fnum, uint32_t &startAcquisitionIndex, uint32_t &startFrameIndex); + void readFrame(char* c,char** raw, uint32_t &startAcquisitionIndex, uint32_t &startFrameIndex); /** * Closes all files @@ -356,7 +355,7 @@ private: * Copy frames to gui * uses semaphore for nth frame mode */ - void copyFrameToGui(char* startbuf[], uint32_t fnum=-1, char* buf=NULL); + void copyFrameToGui(char* startbuf[], char* buf=NULL); /** * creates udp sockets diff --git a/slsReceiverSoftware/src/UDPBaseImplementation.cpp b/slsReceiverSoftware/src/UDPBaseImplementation.cpp index fb10ae106..20326bafd 100644 --- a/slsReceiverSoftware/src/UDPBaseImplementation.cpp +++ b/slsReceiverSoftware/src/UDPBaseImplementation.cpp @@ -567,7 +567,7 @@ void UDPBaseImplementation::setupFifoStructure(){ FILE_LOG(logDEBUG) << __AT__ < /** acquisition functions */ -void UDPBaseImplementation::readFrame(char* c,char** raw, uint32_t &fnum, uint32_t &startAcquisitionIndex, uint32_t &startFrameIndex){ +void UDPBaseImplementation::readFrame(char* c,char** raw,uint32_t &startAcquisitionIndex, uint32_t &startFrameIndex){ FILE_LOG(logDEBUG) << __AT__ << " called"; //point to gui data if (guiData == NULL){ @@ -576,7 +576,6 @@ void UDPBaseImplementation::readFrame(char* c,char** raw, uint32_t &fnum, uint32 //copy data and filename strcpy(c,guiFileName); - fnum = guiFrameNumber; startAcquisitionIndex = getStartAcquisitionIndex(); startFrameIndex = getStartFrameIndex(); @@ -601,55 +600,8 @@ void UDPBaseImplementation::readFrame(char* c,char** raw, uint32_t &fnum, uint32 -void UDPBaseImplementation::copyFrameToGui(char* startbuf[], uint32_t fnum, char* buf){ FILE_LOG(logDEBUG) << __AT__ << " starting"; +void UDPBaseImplementation::copyFrameToGui(char* startbuf[], char* buf){ FILE_LOG(logDEBUG) << __AT__ << " starting"; - //random read when gui not ready - if((!nFrameToGui) && (!guiData)){ - pthread_mutex_lock(&dataReadyMutex); - guiDataReady=0; - pthread_mutex_unlock(&dataReadyMutex); - } - - //random read or nth frame read, gui needs data now or it is the first frame - else{ - /* - //nth frame read, block current process if the guireader hasnt read it yet - if(nFrameToGui) - sem_wait(&smp); -*/ - pthread_mutex_lock(&dataReadyMutex); - guiDataReady=0; - //eiger - if(startbuf != NULL){ - int offset = 0; - int size = frameSize/EIGER_MAX_PORTS; - for(int j=0;j= packetsPerFrame){//min 1 frame, but neednt be //if(npackets == packetsPerFrame * numJobsPerThread){ //only full frames - copyFrameToGui(NULL,-1,wbuffer[0]+HEADER_SIZE_NUM_TOT_PACKETS); + copyFrameToGui(NULL,wbuffer[0]+HEADER_SIZE_NUM_TOT_PACKETS); #ifdef VERYVERBOSE cout << ithread << " finished copying" << endl; #endif @@ -3087,7 +3075,7 @@ void UDPStandardImplementation::handleDataCompression(int ithread, char* wbuffer #endif if(!once){ - copyFrameToGui(NULL,-1,buff); + copyFrameToGui(NULL,buff); once = 1; } } diff --git a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp index 17ff75764..ffa3f5d8c 100644 --- a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp +++ b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp @@ -1068,7 +1068,7 @@ int slsReceiverTCPIPInterface::moench_read_frame(){ uint32_t startAcquisitionIndex=0; uint32_t startFrameIndex=0; - uint32_t index = 0,bindex = 0, offset=0; + uint32_t index = -1,bindex = 0, offset=0; strcpy(mess,"Could not read frame\n"); @@ -1088,7 +1088,7 @@ int slsReceiverTCPIPInterface::moench_read_frame(){ else{ ret = OK; /*startIndex=receiverBase->getStartFrameIndex();*/ - receiverBase->readFrame(fName,&raw,index,startAcquisitionIndex,startFrameIndex); + receiverBase->readFrame(fName,&raw,startAcquisitionIndex,startFrameIndex); /**send garbage with -1 index to try again*/ if (raw == NULL){ @@ -1253,7 +1253,7 @@ int slsReceiverTCPIPInterface::gotthard_read_frame(){ char* raw = new char[bufferSize]; - uint32_t index=0,index2=0; + uint32_t index=-1,index2=0; uint32_t pindex=0,pindex2=0; uint32_t bindex=0,bindex2=0; uint32_t startAcquisitionIndex=0; @@ -1277,7 +1277,7 @@ int slsReceiverTCPIPInterface::gotthard_read_frame(){ }else{ ret = OK; /*startIndex=receiverBase->getStartFrameIndex();*/ - receiverBase->readFrame(fName,&raw,index,startAcquisitionIndex,startFrameIndex); + receiverBase->readFrame(fName,&raw,startAcquisitionIndex,startFrameIndex); /**send garbage with -1 index to try again*/ if (raw == NULL){ @@ -1429,7 +1429,7 @@ int slsReceiverTCPIPInterface::propix_read_frame(){ for(i=0;igetStartFrameIndex();*/ - receiverBase->readFrame(fName,&raw,index,startAcquisitionIndex,startFrameIndex); + receiverBase->readFrame(fName,&raw,startAcquisitionIndex,startFrameIndex); /**send garbage with -1 index to try again*/ if (raw == NULL){ @@ -1567,16 +1567,36 @@ int slsReceiverTCPIPInterface::propix_read_frame(){ int slsReceiverTCPIPInterface::eiger_read_frame(){ ret=OK; + + /** structure of an eiger packet*/ + typedef struct + { + unsigned char subframenum[4]; + unsigned char missingpacket[2]; + unsigned char portnum[1]; + unsigned char dynamicrange[1]; + } eiger_packet_header_t; + + typedef struct + { + unsigned char framenum[6]; + unsigned char packetnum[2]; + } eiger_packet_footer_t; + + char fName[MAX_STR_LENGTH]=""; int acquisitionIndex = -1; int frameIndex= -1; uint32_t index=0; + uint32_t subframenumber=-1; int frameSize = EIGER_ONE_GIGA_ONE_PACKET_SIZE * packetsPerFrame; int dataSize = EIGER_ONE_GIGA_ONE_DATA_SIZE * packetsPerFrame; + int oneDataSize = EIGER_ONE_GIGA_ONE_DATA_SIZE; if(tenGigaEnable){ frameSize = EIGER_TEN_GIGA_ONE_PACKET_SIZE * packetsPerFrame; dataSize = EIGER_TEN_GIGA_ONE_DATA_SIZE * packetsPerFrame; + oneDataSize = EIGER_TEN_GIGA_ONE_DATA_SIZE; } char* raw = new char[frameSize]; char* origVal = new char[frameSize]; @@ -1605,10 +1625,8 @@ int slsReceiverTCPIPInterface::eiger_read_frame(){ else{ ret = OK; /** read a frame */ - receiverBase->readFrame(fName,&raw,index,startAcquisitionIndex,startFrameIndex); -#ifdef VERBOSE - cout << "index:" << dec << index << endl; -#endif + receiverBase->readFrame(fName,&raw,startAcquisitionIndex,startFrameIndex); + /**send garbage with -1 index to try again*/ if (raw == NULL){ startAcquisitionIndex = -1; @@ -1620,6 +1638,21 @@ int slsReceiverTCPIPInterface::eiger_read_frame(){ /**proper frame*/ else{//cout<<"**** got proper frame ******"<subframenum); + } + +#ifdef VERBOSE + cout << "index:" << dec << index << endl; + cout << "subframenumber:" << dec << subframenumber << endl; +#endif + memcpy(origVal,raw,frameSize); raw=NULL; @@ -1740,6 +1773,7 @@ int slsReceiverTCPIPInterface::eiger_read_frame(){ cout << "index:" << index << endl; cout << "startAcquisitionIndex:" << startAcquisitionIndex << endl; cout << "startFrameIndex:" << startFrameIndex << endl; + cout << "subframenumber:" << subframenumber << endl; #endif } } @@ -1751,6 +1785,7 @@ int slsReceiverTCPIPInterface::eiger_read_frame(){ cout << "frameIndex:" << frameIndex << endl; cout << "startAcquisitionIndex:" << startAcquisitionIndex << endl; cout << "startFrameIndex:" << startFrameIndex << endl; + cout << "subframenumber:" << subframenumber << endl; } #endif @@ -1773,6 +1808,7 @@ int slsReceiverTCPIPInterface::eiger_read_frame(){ socket->SendDataOnly(fName,MAX_STR_LENGTH); socket->SendDataOnly(&acquisitionIndex,sizeof(acquisitionIndex)); socket->SendDataOnly(&frameIndex,sizeof(frameIndex)); + socket->SendDataOnly(&subframenumber,sizeof(subframenumber)); socket->SendDataOnly(retval,dataSize); } From 102162ac1a883a4e9d729b6249b066326555555b Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 22 Sep 2015 16:41:00 +0200 Subject: [PATCH 144/474] made compatible to subframe in gui for partial_frame --- slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp index aa799d380..8e07ceafe 100644 --- a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp +++ b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp @@ -1570,7 +1570,7 @@ int slsReceiverTCPIPInterface::eiger_read_frame(){ int frameIndex= -1; int i; uint32_t index=0; - + uint32_t subindex=-1; int frameSize = EIGER_ONE_GIGA_ONE_PACKET_SIZE * packetsPerFrame; int dataSize = EIGER_ONE_GIGA_ONE_DATA_SIZE * packetsPerFrame; if(tenGigaEnable){ @@ -1750,6 +1750,7 @@ int slsReceiverTCPIPInterface::eiger_read_frame(){ cout << "frameIndex:" << frameIndex << endl; cout << "startAcquisitionIndex:" << startAcquisitionIndex << endl; cout << "startFrameIndex:" << startFrameIndex << endl; + } #endif @@ -1772,6 +1773,7 @@ int slsReceiverTCPIPInterface::eiger_read_frame(){ socket->SendDataOnly(fName,MAX_STR_LENGTH); socket->SendDataOnly(&acquisitionIndex,sizeof(acquisitionIndex)); socket->SendDataOnly(&frameIndex,sizeof(frameIndex)); + socket->SendDataOnly(&subindex,sizeof(subindex)); socket->SendDataOnly(retval,dataSize); } From 06b38e591ced7837b36c64b56142781c6a40b573 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Wed, 23 Sep 2015 12:34:21 +0200 Subject: [PATCH 145/474] got rid of warnings --- slsReceiverSoftware/include/circularFifo.h | 2 +- .../src/UDPBaseImplementation.cpp | 185 ------------------ .../src/UDPStandardImplementation.cpp | 24 +-- .../src/slsReceiverTCPIPInterface.cpp | 7 +- 4 files changed, 14 insertions(+), 204 deletions(-) diff --git a/slsReceiverSoftware/include/circularFifo.h b/slsReceiverSoftware/include/circularFifo.h index 6f779aafc..1ba584cc4 100644 --- a/slsReceiverSoftware/include/circularFifo.h +++ b/slsReceiverSoftware/include/circularFifo.h @@ -79,7 +79,7 @@ template bool CircularFifo::push(Element*& item_) { - int nextTail = increment(tail); + unsigned int nextTail = increment(tail); if(nextTail != head) { array[tail] = item_; diff --git a/slsReceiverSoftware/src/UDPBaseImplementation.cpp b/slsReceiverSoftware/src/UDPBaseImplementation.cpp index 20326bafd..682c52980 100644 --- a/slsReceiverSoftware/src/UDPBaseImplementation.cpp +++ b/slsReceiverSoftware/src/UDPBaseImplementation.cpp @@ -1399,12 +1399,6 @@ int UDPBaseImplementation::startListening(){ FILE_LOG(logDEBUG) << __AT__ << " s int UDPBaseImplementation::startWriting(){ FILE_LOG(logDEBUG) << __AT__ << " starting"; - int ithread = currentWriterThreadIndex; -#ifdef VERYVERBOSE - cout << ithread << "In startWriting()" < 0){ - - //for progress and packet loss calculation(new files) - if(myDetectorType == EIGER); - else if ((myDetectorType == GOTTHARD) && (shortFrame == -1)) - tempframenum = (((((uint32_t)(*((uint32_t*)(buf + HEADER_SIZE_NUM_TOT_PACKETS))))+1)& (frameIndexMask)) >> frameIndexOffset); - else - tempframenum = ((((uint32_t)(*((uint32_t*)(buf + HEADER_SIZE_NUM_TOT_PACKETS))))& (frameIndexMask)) >> frameIndexOffset); - - if(numWriterThreads == 1) - currframenum = tempframenum; - else{ - if(tempframenum > currframenum) - currframenum = tempframenum; - } -#ifdef VERYDEBUG - cout << "tempframenum:" << dec << tempframenum << " curframenum:" << currframenum << endl; -#endif - - //lock - if(numWriterThreads > 1) - pthread_mutex_lock(&write_mutex); - - - //to create new file when max reached - packetsToSave = maxPacketsPerFile - packetsInFile; - if(packetsToSave > numpackets) - packetsToSave = numpackets; -/**next time offset is still plus header length*/ - fwrite(buf+offset, 1, packetsToSave * onePacketSize, sfilefd); - packetsInFile += packetsToSave; - packetsCaught += packetsToSave; - totalPacketsCaught += packetsToSave; - - - //new file - if(packetsInFile >= maxPacketsPerFile){ - //for packet loss - lastpacket = (((packetsToSave - 1) * onePacketSize) + offset); - if(myDetectorType == EIGER); - else if ((myDetectorType == GOTTHARD) && (shortFrame == -1)) - tempframenum = (((((uint32_t)(*((uint32_t*)(buf + lastpacket))))+1)& (frameIndexMask)) >> frameIndexOffset); - else - tempframenum = ((((uint32_t)(*((uint32_t*)(buf + lastpacket))))& (frameIndexMask)) >> frameIndexOffset); - - if(numWriterThreads == 1) - currframenum = tempframenum; - else{ - if(tempframenum > currframenum) - currframenum = tempframenum; - } -#ifdef VERYDEBUG - cout << "tempframenum:" << dec << tempframenum << " curframenum:" << currframenum << endl; -#endif - //create - createNewFile(); - } - - //unlock - if(numWriterThreads > 1) - pthread_mutex_unlock(&write_mutex); - - - offset += (packetsToSave * onePacketSize); - numpackets -= packetsToSave; - } - - } - else{ - if(numWriterThreads > 1) - pthread_mutex_lock(&write_mutex); - packetsInFile += numpackets; - packetsCaught += numpackets; - totalPacketsCaught += numpackets; - if(numWriterThreads > 1) - pthread_mutex_unlock(&write_mutex); - } } @@ -1675,97 +1581,6 @@ void UDPBaseImplementation::handleDataCompression(int ithread, char* wbuffer[], FILE_LOG(logDEBUG) << __FILE__ << "::" << __func__ << " starting"; -#if defined(MYROOT1) && defined(ALLFILE_DEBUG) - writeToFile_withoutCompression(wbuf[0], numpackets,currframenum); -#endif - - eventType thisEvent = PEDESTAL; - int ndata; - char* buff = 0; - int npackets = (uint16_t)(*((uint16_t*)wbuffer[0])); - data = wbuffer[0]+ HEADER_SIZE_NUM_TOT_PACKETS; - int remainingsize = npackets * onePacketSize; - int np; - int once = 0; - double tot, tl, tr, bl, br; - int xmin = 1, ymin = 1, ix, iy; - - - while(buff = receiverdata[ithread]->findNextFrame(data,ndata,remainingsize)){ - np = ndata/onePacketSize; - - //cout<<"buff framnum:"<> frameIndexOffset)<newFrame(); - - //only for moench - if(commonModeSubtractionEnable){ - for(ix = xmin - 1; ix < xmax+1; ix++){ - for(iy = ymin - 1; iy < ymax+1; iy++){ - thisEvent = singlePhotonDet[ithread]->getEventType(buff, ix, iy, 0); - } - } - } - - - for(ix = xmin - 1; ix < xmax+1; ix++) - for(iy = ymin - 1; iy < ymax+1; iy++){ - thisEvent=singlePhotonDet[ithread]->getEventType(buff, ix, iy, commonModeSubtractionEnable); - if (nf>1000) { - tot=0; - tl=0; - tr=0; - bl=0; - br=0; - if (thisEvent==PHOTON_MAX) { - receiverdata[ithread]->getFrameNumber(buff); - //iFrame=receiverdata[ithread]->getFrameNumber(buff); -#ifdef MYROOT1 - myTree[ithread]->Fill(); - //cout << "Fill in event: frmNr: " << iFrame << " ix " << ix << " iy " << iy << " type " << thisEvent << endl; -#else - pthread_mutex_lock(&write_mutex); - if((enableFileWrite) && (sfilefd)) - singlePhotonDet[ithread]->writeCluster(sfilefd); - pthread_mutex_unlock(&write_mutex); -#endif - } - } - } - - nf++; -#ifndef ALLFILE - pthread_mutex_lock(&progress_mutex); - packetsInFile += packetsPerFrame; - packetsCaught += packetsPerFrame; - totalPacketsCaught += packetsPerFrame; - if(packetsInFile >= maxPacketsPerFile) - createNewFile(); - pthread_mutex_unlock(&progress_mutex); - -#endif - if(!once){ - copyFrameToGui(NULL,buff); - once = 1; - } - } - - remainingsize -= ((buff + ndata) - data); - data = buff + ndata; - if(data > (wbuffer[0] + HEADER_SIZE_NUM_TOT_PACKETS + npackets * onePacketSize) ) - cout <<" **************ERROR SHOULD NOT COME HERE, Error 142536!"<push(wbuffer[0])); -#ifdef VERYVERBOSE - cout<<"buf freed:"<<(void*)wbuffer[0]<missingpacket)!= missingPacketValue){ cprintf(BG_RED, "wrong blank mismatch num4 earlier2! " - "i:%d pnum:%d fnum:%d missingpacket:0x%x actual missingpacket:0x%x add:0x%x\n", + "i:%d pnum:%d fnum:%d missingpacket:0x%x actual missingpacket:0x%x add:0x%p\n", i,tempoffset[i],tempframenum[i], *( (uint16_t*) tempframe_header->missingpacket), *( (uint16_t*) blankframe_header->missingpacket), @@ -2303,7 +2297,7 @@ int UDPStandardImplementation::startWriting(){ blankframe_header = (eiger_packet_header_t*) blankframe[blankoffset]; if (*( (uint16_t*) tempframe_header->missingpacket)!= missingPacketValue){ cprintf(BG_RED, "correct blank mismatch num4 earlier2! " - "i:%d pnum:%d fnum:%d missingpacket:0x%x actual missingpacket:0x%x add:0x%x\n", + "i:%d pnum:%d fnum:%d missingpacket:0x%x actual missingpacket:0x%x add:0x%p\n", i,tempoffset[i],tempframenum[i], *( (uint16_t*) tempframe_header->missingpacket), *( (uint16_t*) blankframe_header->missingpacket), @@ -2320,7 +2314,7 @@ int UDPStandardImplementation::startWriting(){ blankoffset ++; } //add current packet - if(currentpacketheader[i] != (tempoffset[i]-(i*packetsPerFrame/numListeningThreads))+1){ + if(currentpacketheader[i] != (uint32_t)(tempoffset[i]-(i*packetsPerFrame/numListeningThreads))+1){ cprintf(BG_RED, "correct pnum mismatch earlier! tempoffset[%d]:%d pnum:%d fnum:%d rfnum:%d\n", i,tempoffset[i],currentpacketheader[i], tempframenum[i],(uint32_t)(*( (uint64_t*) wbuf_footer))); @@ -2335,7 +2329,7 @@ int UDPStandardImplementation::startWriting(){ i,*( (uint16_t*) tempframe_footer->packetnum),tempoffset[i]); #endif if(*( (uint16_t*) tempframe_footer->packetnum)!= (tempoffset[i]-(i*packetsPerFrame/numListeningThreads))+1){ - cprintf(BG_RED, "pnum mismatch num4 earlier! i:%d pnum:%d pnum orig:%d fnum:%d add:0x%x\n", + cprintf(BG_RED, "pnum mismatch num4 earlier! i:%d pnum:%d pnum orig:%d fnum:%d add:0x%p\n", i,*( (uint16_t*) tempframe_footer->packetnum),*( (uint16_t*) wbuf_footer->packetnum), tempframenum[i],(void*)(tempbuffer[tempoffset[i]])); exit(-1); @@ -2815,7 +2809,7 @@ void UDPStandardImplementation::writeToFile_withoutCompression(char* buf[],int n cprintf(GREEN,"totalPacketsCaught:%d\n", totalPacketsCaught); #endif //new file - if(packetsInFile >= maxPacketsPerFile){ + if(packetsInFile >= (uint32_t)maxPacketsPerFile){ //for packet loss, because currframenum is the latest one for eiger if(myDetectorType != EIGER){ @@ -2870,7 +2864,7 @@ void UDPStandardImplementation::writeToFile_withoutCompression(char* buf[],int n void UDPStandardImplementation::handleWithoutDataCompression(int ithread, char* wbuffer[],int npackets){ - int i,j, missingpacket,port = 0, pnuminc; + int i, missingpacket,port = 0; if (cbAction < DO_EVERYTHING){ @@ -3069,7 +3063,7 @@ void UDPStandardImplementation::handleDataCompression(int ithread, char* wbuffer packetsInFile += packetsPerFrame; packetsCaught += packetsPerFrame; totalPacketsCaught += packetsPerFrame; - if(packetsInFile >= maxPacketsPerFile) + if(packetsInFile >= (uint32_t)maxPacketsPerFile) createNewFile(); pthread_mutex_unlock(&progress_mutex); diff --git a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp index ffa3f5d8c..24e475c50 100644 --- a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp +++ b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp @@ -39,10 +39,11 @@ slsReceiverTCPIPInterface::slsReceiverTCPIPInterface(int &success, UDPInterface* shortFrame(-1), packetsPerFrame(GOTTHARD_PACKETS_PER_FRAME), dynamicrange(16), - socket(NULL), killTCPServerThread(0), - tenGigaEnable(0), portNumber(DEFAULT_PORTNO+2), - bottom(bot){ + tenGigaEnable(0), + portNumber(DEFAULT_PORTNO+2), + bottom(bot), + socket(NULL){ int port_no=portNumber; if(receiverBase == NULL) receiverBase = 0; From c392348def93499c7b67cd040343c9c3c0e5799e Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Wed, 30 Sep 2015 11:40:39 +0200 Subject: [PATCH 146/474] big change half done --- .../include/UDPBaseImplementation.h | 1091 ++++------ slsReceiverSoftware/include/UDPInterface.h | 602 +++--- .../include/UDPStandardImplementation.h | 221 +- .../src/UDPBaseImplementation.cpp | 1915 +++-------------- slsReceiverSoftware/src/UDPInterface.cpp | 1 - .../src/UDPStandardImplementation.cpp | 4 +- .../src/slsReceiverTCPIPInterface.cpp | 360 +++- 7 files changed, 1560 insertions(+), 2634 deletions(-) diff --git a/slsReceiverSoftware/include/UDPBaseImplementation.h b/slsReceiverSoftware/include/UDPBaseImplementation.h index cbc4f386c..29d9dd009 100644 --- a/slsReceiverSoftware/include/UDPBaseImplementation.h +++ b/slsReceiverSoftware/include/UDPBaseImplementation.h @@ -8,25 +8,9 @@ #include "sls_receiver_defs.h" -#include "receiver_defs.h" -#include "genericSocket.h" -#include "circularFifo.h" -#include "singlePhotonDetector.h" -#include "slsReceiverData.h" -#include "moenchCommonMode.h" - #include "UDPInterface.h" - -#ifdef MYROOT1 -#include -#include -#endif - - #include -#include #include -#include /** * @short does all the functions for a receiver, set/get parameters, start/stop etc. @@ -35,6 +19,11 @@ class UDPBaseImplementation : protected virtual slsReceiverDefs, public UDPInterface { public: + + /************************************************************************* + * Constructor & Destructor ********************************************** + * They access local cache of configuration or detector parameters ******* + *************************************************************************/ /** * Constructor */ @@ -45,800 +34,538 @@ class UDPBaseImplementation : protected virtual slsReceiverDefs, public UDPInter */ virtual ~UDPBaseImplementation(); - void configure(map config_map); + /************************************************************************* + * Getters *************************************************************** + * They access local cache of configuration or detector parameters ******* + *************************************************************************/ - /** - * delete and free member parameters - */ - void deleteMembers(); - - /** - * initialize member parameters - */ - void initializeMembers(); - - /** - * Set receiver type - * @param det detector type - * Returns success or FAIL - */ - int setDetectorType(detectorType det); - - /** - * Set bottom to bot - * @param bot = 1 if bottom - */ - void setBottom(int bot); - - //Frame indices and numbers caught - /** - * Returns the frame index at start of entire acquisition (including all scans) - */ - uint32_t getStartAcquisitionIndex(); - - /** - * Returns current Frame Index Caught for an entire acquisition (including all scans) - */ - uint32_t getAcquisitionIndex(); - - /** - * Returns if acquisition started - */ - bool getAcquistionStarted(); - - /** - * Returns Frames Caught for each real time acquisition (eg. for each scan) - */ - int getFramesCaught(); - - /** - * Returns Total Frames Caught for an entire acquisition (including all scans) - */ - int getTotalFramesCaught(); - - /** - * Returns the frame index at start of each real time acquisition (eg. for each scan) - */ - uint32_t getStartFrameIndex(); - - /** - * Returns current Frame Index for each real time acquisition (eg. for each scan) - */ - uint32_t getFrameIndex(); - - /** - * Returns if measurement started - */ - bool getMeasurementStarted(); - - /** - * Resets the Total Frames Caught - * This is how the receiver differentiates between entire acquisitions - * Returns 0 - */ - void resetTotalFramesCaught(); - - - - - //file parameters - /** - * Returns File Path - */ - char* getFilePath() const; - - /** - * Set File Path - * @param c file path - */ - char* setFilePath(const char c[]); - - /** - * Returns File Name - */ - char* getFileName() const; - - /** - * Set File Name (without frame index, file index and extension) - * @param c file name - */ - char* setFileName(const char c[]); - - /** - * Returns File Index - */ - int getFileIndex(); - - /** - * Set File Index - * @param i file index - */ - int setFileIndex(int i); - - /** - * Set Frame Index Needed - * @param i frame index needed - */ - int setFrameIndexNeeded(int i); - - /** - * Set enable file write - * @param i file write enable - * Returns file write enable - */ - int setEnableFileWrite(int i); - - /** - * Enable/disable overwrite - * @param i enable - * Returns enable over write - */ - int setEnableOverwrite(int i); - - /** - * Returns file write enable - * 1: YES 0: NO - */ - int getEnableFileWrite() const; - - /** - * Returns file over write enable - * 1: YES 0: NO - */ - int getEnableOverwrite() const; - -//other parameters - - /** - * abort acquisition with minimum damage: close open files, cleanup. - * does nothing if state already is 'idle' - */ - void abort() {}; - - /** - * Returns status of receiver: idle, running or error - */ - runStatus getStatus() const; - - /** - * Set detector hostname - * @param c hostname - */ - void initialize(const char *detectorHostName); - - /* Returns detector hostname - /returns hostname - * caller needs to deallocate the returned char array. - * if uninitialized, it must return NULL + //**initial parameters*** + /* + * Get detector hostname + * @return NULL or hostname or NULL if uninitialized (max of 1000 characters) */ char *getDetectorHostname() const; + + //***file parameters*** /** - * Set Ethernet Interface or IP to listen to + * Get File Name Prefix (without frame index, file index and extension (_d0_f000000000000_8.raw)) + * @return NULL or file name prefix (max of 1000 characters) */ - void setEthernetInterface(char* c); + char *getFileName() const; /** - * Set UDP Port Number + * Get File Path + * @return NULL or file path (max of 1000 characters) */ - void setUDPPortNo(int p); - void setUDPPortNo2(int p); - - /* - * Returns number of frames to receive - * This is the number of frames to expect to receiver from the detector. - * The data receiver will change from running to idle when it got this number of frames - */ - int getNumberOfFrames() const; + char *getFilePath() const; /** - * set frame number if a positive number + * Get File Index + * @return file index of acquisition */ - int32_t setNumberOfFrames(int32_t fnum); + uint64_t getFileIndex() const; /** - * Returns scan tag + * Get Scan Tag + * @return scan tag //FIXME: needed? (unsigned integer?) */ int getScanTag() const; /** - * set scan tag if its is a positive number + * Get if Frame Index is enabled (acquisition of more than 1 frame adds '_f000000000000' to file name ) + * @return true if frame index needed, else false */ - int32_t setScanTag(int32_t stag); + bool getFrameIndexEnable() const; /** - * Returns the number of bits per pixel + * Get File Write Enable + * @return true if file write enabled, else false */ - int getDynamicRange() const; + bool getFileWriteEnable() const; /** - * set dynamic range if its is a positive number + * Get File Over Write Enable + * @return true if file over write enabled, else false */ - int32_t setDynamicRange(int32_t dr); + bool getOverwriteEnable() const; /** - * Set short frame - * @param i if shortframe i=1 + * Get data compression, by saving only hits (so far implemented only for Moench and Gotthard) + * @return true if data compression enabled, else false */ - int setShortFrame(int i); + bool getDataCompressionEnable() const; + + + //***acquisition count parameters*** + /** + * Get Total Frames Caught for an entire acquisition (including all scans) + * @return total number of frames caught for entire acquisition + */ + uint64_t getTotalFramesCaught() const; /** - * Set the variable to send every nth frame to gui - * or if 0,send frame only upon gui request + * Get Frames Caught for each real time acquisition (eg. for each scan) + * @return number of frames caught for each scan */ - int setNFrameToGui(int i); - - /** set acquisition period if a positive number - */ - int64_t setAcquisitionPeriod(int64_t index); - - /** get data compression, by saving only hits - */ - bool getDataCompression(); - - /** enabl data compression, by saving only hits - /returns if failed - */ - int enableDataCompression(bool enable); + uint64_t getFramesCaught() const; /** - * enable 10Gbe - @param enable 1 for 10Gbe or 0 for 1 Gbe, -1 to read out - \returns enable for 10Gbe + * Get Current Frame Index Caught for an entire acquisition (including all scans) + * @return current frame index (represents all scans too) */ - int enableTenGiga(int enable = -1); + int64_t getAcquisitionIndex() const; - -//other functions + //***connection parameters*** + /** + * Get UDP Port Number + * @return udp port number + */ + uint32_t getUDPPortNo() const; /** - * Returns the buffer-current frame read by receiver - * @param c pointer to current file name - * @param raw address of pointer, pointing to current frame to send to gui - * @param startAcquisitionIndex is the start index of the acquisition - * @param startFrameIndex is the start index of the scan + * Get Second UDP Port Number (eiger specific) + * @return second udp port number */ - void readFrame(char* c,char** raw, uint32_t &startAcquisitionIndex, uint32_t &startFrameIndex); + uint32_t getUDPPortNo2() const; /** - * Closes all files - * @param ithr thread index + * Get Ehernet Interface + * @ethernet interface. eg. eth0 or "" if listening to all (max of 1000 characters) */ - void closeFile(int ithr = -1); + char *getEthernetInterface() const; + + + //***acquisition parameters*** + /** + * Get Short Frame Enabled, later will be moved to getROI (so far only for gotthard) + * @return index of adc enabled, else -1 if all enabled + */ + int getShortFrameEnable() const; /** - * Starts Receiver - starts to listen for packets - * @param message is the error message if there is an error - * Returns success + * Get the Frequency of Frames Sent to GUI + * @return 0 for random frame requests, n for nth frame frequency */ - int startReceiver(char message[]); + uint32_t getFrameToGuiFrequency() const; /** - * Stops Receiver - stops listening for packets - * Returns success + * Get Acquisition Period + * @return acquisition period */ - int stopReceiver(); + uint64_t getAcquisitionPeriod() const; - /** set status to transmitting and - * when fifo is empty later, sets status to run_finished + /* + * Get Number of Frames expected by receiver from detector + * The data receiver status will change from running to idle when it gets this number of frames FIXME: (Not implemented) + * @return number of frames expected + */ + uint64_t getNumberOfFrames() const; + + /** + * Get Dynamic Range or Number of Bits Per Pixel + * @return dynamic range that is 4, 8, 16 or 32 + */ + uint32_t getDynamicRange() const; + + /** + * Get Ten Giga Enable + * @return true if 10Giga enabled, else false (1G enabled) + */ + bool getTenGigaEnable() const; + + //***receiver status*** + /** + * Get Listening Status of Receiver + * @return can be idle, listening or error depending on if the receiver is listening or not + */ + slsReceiverDefs::runStatus getStatus() const; + + + + + /************************************************************************* + * Setters *************************************************************** + * They modify the local cache of configuration or detector parameters *** + *************************************************************************/ + + //**initial parameters*** + /** + * Configure command line parameters + * @param config_map mapping of config parameters passed from command line arguments + */ + void configure(map config_map); + + /** + * Set Bottom Enable (eiger specific, should be moved to configure, and later from client via TCPIP) + * @param b is true for bottom enabled or false for bottom disabled + */ + void setBottomEnable(const bool b); + + + //***file parameters*** + /** + * Set File Name Prefix (without frame index, file index and extension (_d0_f000000000000_8.raw)) + * Does not check for file existence since it is created only at startReceiver + * @param c file name (max of 1000 characters) + */ + void setFileName(const char c[]); + + /** + * Set File Path + * Checks for file directory existence before setting file path, + * If it doesn't exist, it will set it blank + * @param c file path (max of 1000 characters) + */ + void setFilePath(const char c[]); + + /** + * Set File Index of acquisition + * @param i file index of acquisition + */ + void setFileIndex(const uint64_t i); + + /** + * Set Scan Tag + * @param i scan tag //FIXME: needed? (unsigned integer?) + */ + void setScanTag(const int i); + + /** + * Set Frame Index Enable (acquisition of more than 1 frame adds '_f000000000000' to file name ) + * @param b true for frame index enable, else false + */ + void setFrameIndexEnable(const bool b); + + /** + * Set File Write Enable + * @param b true for file write enable, else false + */ + void setFileWriteEnable(const bool b); + + /** + * Set File Overwrite Enable + * @param b true for file overwrite enable, else false + */ + void setOverwriteEnable(const bool b); + + /** + * Set data compression, by saving only hits (so far implemented only for Moench and Gotthard) + * @param b true for data compression enable, else false + */ + void setDataCompressionEnable(const bool b); + + + + //***connection parameters*** + /** + * Set UDP Port Number + * @param i udp port number + */ + void setUDPPortNo(const uint32_t i); + + /** + * Set Second UDP Port Number (eiger specific) + * @return second udp port number + */ + void setUDPPortNo2(const uint32_t i); + + /** + * Set Ethernet Interface to listen to + * @param c ethernet inerface eg. eth0 (max of 1000 characters) + */ + void setEthernetInterface(const char* c); + + + //***connection parameters*** + /** + * Set Short Frame Enabled, later will be moved to getROI (so far only for gotthard) + * @param i index of adc enabled, else -1 if all enabled + */ + void setShortFrameEnable(const int i); + + /** + * Set the Frequency of Frames Sent to GUI + * @param i 0 for random frame requests, n for nth frame frequency + */ + void setFrameToGuiFrequency(const uint32_t i); + + /** + * Set Acquisition Period + * @param i acquisition period + */ + void setAcquisitionPeriod(const uint64_t i); + + /** + * Set Number of Frames expected by receiver from detector + * The data receiver status will change from running to idle when it gets this number of frames FIXME: (Not implemented) + * @param i number of frames expected + */ + void setNumberOfFrames(const uint64_t i); + + /** + * Set Dynamic Range or Number of Bits Per Pixel + * @param i dynamic range that is 4, 8, 16 or 32 + */ + void setDynamicRange(const uint32_t i); + + /** + * Set Ten Giga Enable + * @param b true if 10Giga enabled, else false (1G enabled) + */ + void setTenGigaEnable(const bool b); + + + + /************************************************************************* + * Behavioral functions*************************************************** + * They may modify the status of the receiver **************************** + *************************************************************************/ + + //***initial functions*** + /** + * Set receiver type (and corresponding detector variables in derived STANDARD class) + * It is the first function called by the client when connecting to receiver + * @param d detector type + * @return OK or FAIL + */ + int setDetectorType(const slsReceiverDefs::detectorType d); + + /** + * Sets detector hostname (and corresponding detector variables in derived REST class) + * It is second function called by the client when connecting to receiver. + * you can call this function only once. //FIXME: is this still valid, this implemented in derived REST class? + * @param c detector hostname + */ + void initialize(const char *c); + + + //***acquisition functions*** + /** + * Reset acquisition parameters such as total frames caught for an entire acquisition (including all scans) + */ + void resetAcquisitionCount(); + + /** + * Start Listening for Packets by activating all configuration settings to receiver + * @param c error message if FAIL + * @return OK or FAIL + */ + int startReceiver(char *c=NULL); + + /** + * Stop Listening for Packets + * Calls startReadout(), which stops listening and sets status to Transmitting + * When it has read every frame in buffer,it returns with the status Run_Finished + */ + void stopReceiver(); + + /** + * Stop Listening to Packets + * and sets status to Transmitting */ void startReadout(); /** * shuts down the udp sockets - * \returns if success or fail + * \returns OK or FAIL */ int shutDownUDPSockets(); -protected: - - /* - void not_implemented(string method_name){ - std::cout << "[WARNING] Method " << method_name << " not implemented!" << std::endl; - }; - */ /** - * Deletes all the filter objects for single photon data + * Get the buffer-current frame read by receiver + * @param c pointer to current file name + * @param raw address of pointer, pointing to current frame to send to gui + * @param startAcquisitionIndex start index of the acquisition + * @param startFrameIndex start index of the scan */ - void deleteFilter(); + void readFrame(char* c,char** raw, uint64_t &startAcquisitionIndex, uint64_t &startFrameIndex); /** - * Constructs the filter for single photon data + * abort acquisition with minimum damage: close open files, cleanup. + * does nothing if state already is 'idle' */ - void setupFilter(); + void abort(); //FIXME: needed, isnt stopReceiver enough? /** - * set up fifo according to the new numjobsperthread + * Closes all files + * @param i thread index, -1 for all threads */ - void setupFifoStructure (); + void closeFile(int i = -1); - /** - * Copy frames to gui - * uses semaphore for nth frame mode - */ - void copyFrameToGui(char* startbuf[], char* buf=NULL); + //***callback functions*** /** - * creates udp sockets - * \returns if success or fail - */ - int createUDPSockets(); - - /** - * create listening thread - * @param destroy is true to kill all threads and start again - */ - int createListeningThreads(bool destroy = false); - - /** - * create writer threads - * @param destroy is true to kill all threads and start again - */ - int createWriterThreads(bool destroy = false); - - /** - * set thread priorities - */ - void setThreadPriorities(); - - /** - * initializes variables and creates the first file - * also does the startAcquisitionCallBack - * \returns FAIL or OK - */ - int setupWriter(); - - /** - * Creates new tree and file for compression - * @param ithr thread number - * @param iframe frame number - *\returns OK for succces or FAIL for failure - */ - int createCompressionFile(int ithr, int iframe); - - /** - * Creates new file - *\returns OK for succces or FAIL for failure - */ - int createNewFile(); - - /** - * Static function - Thread started which listens to packets. - * Called by startReceiver() - * @param this_pointer pointer to this object - */ - static void* startListeningThread(void *this_pointer); - - /** - * Static function - Thread started which writes packets to file. - * Called by startReceiver() - * @param this_pointer pointer to this object - */ - static void* startWritingThread(void *this_pointer); - - /** - * Thread started which listens to packets. - * Called by startReceiver() + * Call back for start acquisition + * callback arguments are + * filepath + * filename + * fileindex + * datasize * + * return value is the action which decides what the user and default responsibilities to save data are + * 0 callback takes care of open,close,wrie file + * 1 callback writes file, we have to open, close it + * 2 we open, close, write file, callback does not do anything */ - int startListening(); + void registerCallBackStartAcquisition(int (*func)(char*, char*,uint64_t, uint32_t, void*),void *arg); /** - * Thread started which writes packets to file. - * Called by startReceiver() - * + * Call back for acquisition finished + * callback argument is + * total frames caught */ - int startWriting(); + void registerCallBackAcquisitionFinished(void (*func)(uint64_t, void*),void *arg); /** - * Writing to file without compression - * @param buf is the address of buffer popped out of fifo - * @param numpackets is the number of packets - * @param framenum current frame number + * Call back for raw data + * args to raw data ready callback are + * framenum + * datapointer + * datasize in bytes + * file descriptor + * guidatapointer (NULL, no data required) */ - void writeToFile_withoutCompression(char* buf,int numpackets, uint32_t framenum); - - /** - * Its called for the first packet of a scan or acquistion - * Sets the startframeindices and the variables to know if acquisition started - * @param ithread listening thread number - */ - void startFrameIndices(int ithread); - - /** - * This is called when udp socket is shut down - * It pops ffff instead of packet number into fifo - * to inform writers about the end of listening session - * @param ithread listening thread number - * @param rc number of bytes received - * @param pc packet count - * @param t total packets listened to - */ - void stopListening(int ithread, int rc, int &pc, int &t); - - /** - * When acquisition is over, this is called - * @param ithread listening thread number - * @param wbuffer writer buffer - */ - void stopWriting(int ithread, char* wbuffer[]); - - - /** - * data compression for each fifo output - * @param ithread listening thread number - * @param wbuffer writer buffer - * @param data pointer to the next packet start - * @param xmax max pixels in x direction - * @param ymax max pixels in y direction - * @param nf nf - */ - void handleDataCompression(int ithread, char* wbuffer[], char* data, int xmax, int ymax, int &nf); + void registerCallBackRawDataReady(void (*func)(uint64_t, char*, uint32_t, FILE*, char*, void*),void *arg); + - //// Could be done more fine-grained... TODO - // private: protected: - /** structure of an eiger packet*/ - typedef struct - { + //**detector parameters*** + /** + * structure of an eiger packet header + * subframenum subframe number for 32 bit mode (already written by firmware) + * missingpacket explicitly put to 0xFF to recognize it in file read (written by software) + * portnum 0 for the first port and 1 for the second port (written by software to file) + * dynamicrange dynamic range or bits per pixel (written by software to file) + */ + typedef struct { unsigned char subframenum[4]; unsigned char missingpacket[2]; unsigned char portnum[1]; unsigned char dynamicrange[1]; } eiger_packet_header_t; - - typedef struct - { + /** + * structure of an eiger packet footer + * framenum 48 bit frame number (already written by firmware) + * packetnum packet number (already written by firmware) + */ + typedef struct { unsigned char framenum[6]; unsigned char packetnum[2]; } eiger_packet_footer_t; - /** max number of listening threads */ - const static int MAX_NUM_LISTENING_THREADS = EIGER_MAX_PORTS; - - /** max number of writer threads */ - const static int MAX_NUM_WRITER_THREADS = 15; - - /** missing packet identifier value */ - const static uint16_t missingPacketValue = 0xFFFF; - /** detector type */ detectorType myDetectorType; - /** detector hostname */ char detHostname[MAX_STR_LENGTH]; + /** Number of Packets per Frame*/ + uint64_t packetsPerFrame; + /** Acquisition Period */ + int64_t acquisitionPeriod; + /** Frame Number */ + int64_t numberOfFrames; + /** Dynamic Range */ + uint32_t dynamicRange; + /** Ten Giga Enable*/ + bool tengigaEnable; + /** Bottom Half Module Enable */ + bool bottomEnable; - /** status of receiver */ + //***receiver parameters*** + /** Maximum Number of Listening Threads/ UDP Ports */ + const static int MAX_NUM_LISTENING_THREADS = 2; + /** Receiver Status */ runStatus status; - /** UDP Socket between Receiver and Detector */ - genericSocket* udpSocket[MAX_NUM_LISTENING_THREADS]; + //***connection parameters*** + /** Ethernet Interface */ + char eth[MAX_STR_LENGTH]; + /** Server UDP Port Number*/ + uint32_t udpPortNum[MAX_NUM_LISTENING_THREADS]; - /** Server UDP Port*/ - int server_port[MAX_NUM_LISTENING_THREADS]; - - /** ethernet interface or IP to listen to */ - char *eth; - - /** max packets per file **/ - int maxPacketsPerFile; - - /** File write enable */ - int enableFileWrite; - - /** File over write enable */ - int overwrite; - - /** Complete File name */ - char savefilename[MAX_STR_LENGTH]; - - /** File Name without frame index, file index and extension*/ + //***file parameters*** + /** File Name without frame index, file index and extension (_d0_f000000000000_8.raw)*/ char fileName[MAX_STR_LENGTH]; - /** File Path */ char filePath[MAX_STR_LENGTH]; - /** File Index */ - int fileIndex; - - /** scan tag */ + uint64_t fileIndex; + /** Scan Tag */ int scanTag; + /** Frame Index Enable */ + bool frameIndexEnable; + /** File Write enable */ + bool fileWriteEnable; + /** Overwrite enable */ + bool overwriteEnable; + /** Data Compression Enable - save only hits */ + bool dataCompressionEnable; - /** if frame index required in file name */ - int frameIndexNeeded; - - /* Acquisition started */ - bool acqStarted; - - /* Measurement started */ - bool measurementStarted; - - /** Frame index at start of each real time acquisition (eg. for each scan) */ - uint32_t startFrameIndex; - - /** Actual current frame index of each time acquisition (eg. for each scan) */ - uint32_t frameIndex; - - /** Frames Caught for each real time acquisition (eg. for each scan) */ - uint32_t packetsCaught; - + //***acquisition count parameters*** /** Total packets caught for an entire acquisition (including all scans) */ - uint32_t totalPacketsCaught; - - /** Pckets currently in current file, starts new file when it reaches max */ - uint32_t packetsInFile; - - /** Number of missing packets in acquisition*/ - uint32_t numTotMissingPackets; - - /** Number of missing packets in file (sometimes packetsinFile is incorrect due to padded packets for eiger)*/ - uint32_t numTotMissingPacketsInFile; - - /** Number of missing packets per buffer*/ - uint32_t numMissingPackets; - - /** Frame index at start of an entire acquisition (including all scans) */ - uint32_t startAcquisitionIndex; + uint64_t totalPacketsCaught; + /** Frames Caught for each real time acquisition (eg. for each scan) */ + uint64_t packetsCaught; + //***acquisition indices parameters*** /** Actual current frame index of an entire acquisition (including all scans) */ - uint32_t acquisitionIndex; + uint64_t acquisitionIndex; - /** number of packets per frame*/ - int packetsPerFrame; - - /** frame index mask */ - uint32_t frameIndexMask; - - /** packet index mask */ - uint32_t packetIndexMask; - - /** frame index offset */ - int frameIndexOffset; - - /** acquisition period */ - int64_t acquisitionPeriod; - - /** frame number */ - int32_t numberOfFrames; - - /** dynamic range */ - int dynamicRange; - - /** short frames */ - int shortFrame; - - /** current frame number */ - uint32_t currframenum; - - /** Previous Frame number from buffer */ - int prevframenum; - - /** size of one frame */ - int frameSize; - - /** buffer size. different from framesize as we wait for one packet instead of frame for eiger */ - int bufferSize; - - /** one buffer size */ - int onePacketSize; - - /** one buffer size */ - int oneDataSize; - - /** latest data */ - char* latestData; - - /** gui data ready */ - int guiDataReady; - - /** points to the data to send to gui */ - char* guiData; - - /** points to the filename to send to gui */ - char* guiFileName; - - /** send every nth frame to gui or only upon gui request*/ - int nFrameToGui; - - /** fifo size */ - unsigned int fifosize; - - /** number of jobs per thread for data compression */ - int numJobsPerThread; - - /** datacompression - save only hits */ - bool dataCompression; - - /** memory allocated for the buffer */ - char *mem0[MAX_NUM_LISTENING_THREADS]; - - /** circular fifo to store addresses of data read */ - CircularFifo* fifo[MAX_NUM_LISTENING_THREADS]; - - /** circular fifo to store addresses of data already written and ready to be resued*/ - CircularFifo* fifoFree[MAX_NUM_LISTENING_THREADS]; - - /** Receiver buffer */ - char *buffer[MAX_NUM_LISTENING_THREADS]; - - /** number of writer threads */ - int numListeningThreads; - - /** number of writer threads */ - int numWriterThreads; - - /** to know if listening and writer threads created properly */ - int thread_started; - - /** current listening thread index*/ - int currentListeningThreadIndex; - - /** current writer thread index*/ - int currentWriterThreadIndex; - - /** thread listening to packets */ - pthread_t listening_thread[MAX_NUM_LISTENING_THREADS]; - - /** thread writing packets */ - pthread_t writing_thread[MAX_NUM_WRITER_THREADS]; - - /** total frame count the listening thread has listened to */ - int totalListeningFrameCount[MAX_NUM_LISTENING_THREADS]; - - /** mask showing which listening threads are running */ - volatile uint32_t listeningthreads_mask; - - /** mask showing which writer threads are running */ - volatile uint32_t writerthreads_mask; - - /** mask showing which threads have created files*/ - volatile uint32_t createfile_mask; - - /** OK if file created was successful */ - int ret_createfile; - - /** variable used to self terminate threads waiting for semaphores */ - int killAllListeningThreads; - - /** variable used to self terminate threads waiting for semaphores */ - int killAllWritingThreads; - - /** 10Gbe enable*/ - int tengigaEnable; - - /** footer offset is different for 1g and 10g*/ - int footer_offset; - - // TODO: not properly sure where to put these... - /** structure of an eiger image header*/ - - - - -//semaphores - /** semaphore to synchronize writer and guireader threads */ - sem_t smp; - /** semaphore to synchronize listener threads */ - sem_t listensmp[MAX_NUM_LISTENING_THREADS]; - /** semaphore to synchronize writer threads */ - sem_t writersmp[MAX_NUM_WRITER_THREADS]; - - -//mutex - /** guiDataReady mutex */ - pthread_mutex_t dataReadyMutex; - - /** mutex for status */ - pthread_mutex_t status_mutex; - - /** mutex for progress variable currframenum */ - pthread_mutex_t progress_mutex; - - /** mutex for writing data to file */ - pthread_mutex_t write_mutex; - - /** File Descriptor */ - FILE *sfilefd; - - //filter - singlePhotonDetector *singlePhotonDet[MAX_NUM_WRITER_THREADS]; - slsReceiverData *receiverdata[MAX_NUM_WRITER_THREADS]; - moenchCommonMode *cmSub; - bool commonModeSubtractionEnable; - -#ifdef MYROOT1 - /** Tree where the hits are stored */ - TTree *myTree[MAX_NUM_WRITER_THREADS]; - - /** File where the tree is saved */ - TFile *myFile[MAX_NUM_WRITER_THREADS]; -#endif + //***acquisition parameters*** + /* Short Frame Enable or index of adc enabled, else -1 if all enabled (gotthard specific) TODO: move to setROI */ + int shortFrameEnable; + /** Frequency of Frames sent to GUI */ + uint32_t FrameToGuiFrequency; + //***callback parameters*** /** - callback arguments are - filepath - filename - fileindex - data size - - return value is - 0 callback takes care of open,close,write file - 1 callback writes file, we have to open, close it - 2 we open, close, write file, callback does not do anything - - */ + * function being called back for start acquisition + * callback arguments are + * filepath + * filename + * fileindex + * datasize + * + * return value is + * 0 callback takes care of open,close,wrie file + * 1 callback writes file, we have to open, close it + * 2 we open, close, write file, callback does not do anything + */ int (*startAcquisitionCallBack)(char*, char*,int, int, void*); void *pStartAcquisition; /** - args to acquisition finished callback - total frames caught - - */ + * function being called back for acquisition finished + * callback argument is + * total frames caught + */ void (*acquisitionFinishedCallBack)(int, void*); void *pAcquisitionFinished; /** - args to raw data ready callback are - framenum - datapointer - datasize in bytes - file descriptor - guidatapointer (NULL, no data required) - */ + * function being called back for raw data + * args to raw data ready callback are + * framenum + * datapointer + * datasize in bytes + * file descriptor + * guidatapointer (NULL, no data required) + */ void (*rawDataReadyCallBack)(int, char*, int, FILE*, char*, void*); void *pRawDataReady; - /** The action which decides what the user and default responsibilites to save data are - * 0 raw data ready callback takes care of open,close,write file - * 1 callback writes file, we have to open, close it - * 2 we open, close, write file, callback does not do anything */ - int cbAction; - /** true if bottom half module for eiger */ - bool bottom; +private: -public: - - - /** - callback arguments are - filepath - filename - fileindex - datasize - - return value is - 0 callback takes care of open,close,wrie file - 1 callback writes file, we have to open, close it - 2 we open, close, write file, callback does not do anything - */ - void registerCallBackStartAcquisition(int (*func)(char*, char*,int, int, void*),void *arg){startAcquisitionCallBack=func; pStartAcquisition=arg;}; - - /** - callback argument is - toatal frames caught - */ - void registerCallBackAcquisitionFinished(void (*func)(int, void*),void *arg){acquisitionFinishedCallBack=func; pAcquisitionFinished=arg;}; - - /** - args to raw data ready callback are - framenum - datapointer - datasize in bytes - file descriptor - guidatapointer (NULL, no data required) - */ - void registerCallBackRawDataReady(void (*func)(int, char*, int, FILE*, char*, void*),void *arg){rawDataReadyCallBack=func; pRawDataReady=arg;}; }; diff --git a/slsReceiverSoftware/include/UDPInterface.h b/slsReceiverSoftware/include/UDPInterface.h index c1d30ec0b..2e89b59be 100644 --- a/slsReceiverSoftware/include/UDPInterface.h +++ b/slsReceiverSoftware/include/UDPInterface.h @@ -26,375 +26,471 @@ class UDPInterface { - /* abstract class that defines the UDP interface of an sls detector data receiver. + /* abstract class that defines the UDP interface of an sls detector data receiver. * - * Use the factory method UDPInterface::create() to get an instance: + * Use the factory method UDPInterface::create() to get an instance: + * + * UDPInterface *udp_interface = UDPInterface::create() * - * UDPInterface *udp_interface = UDPInterface::create() * * supported sequence of method-calls: * - * initialize() : once and only once after create() + * initialize() : once and only once after create() //FIXME: only once functionality implemented in the derived REST class, so not mention here? + * + * get*() : anytime after initialize(), multiples times * - * get*() : anytime after initialize(), multiples times * set*() : anytime after initialize(), multiple times * - * startReceiver(): anytime after initialize(). Will fail if state already is 'running' - * - * abort(), - * stopReceiver() : anytime after initialize(). Will do nothing if state already is idle. - * - * getStatus() returns the actual state of the data receiver - running or idle. All other - * get*() and set*() methods access the local cache of configuration values only and *do not* modify the data receiver settings. + * startReceiver(): anytime after initialize(). Will fail if state already is 'running': * * Only startReceiver() does change the data receiver configuration, it does pass the whole configuration cache to the data receiver. * - * get- and set-methods that return a char array (char *) allocate a new array at each call. The caller is responsible to free the allocated space: + * abort(), //FIXME: needed? + * + * stopReceiver() : anytime after initialize(). Will do nothing if state already is idle. + * + * getStatus() returns the actual state of the data receiver - idle, running or error, enum defined in include/sls_receiver_defs.h + * + * + * + * get*() and set*() methods access the local cache of configuration values only and *do not* modify the data receiver settings. + * + * set methods return nothing, use get methods to validate a set method success + * + * get-methods that return a char array (char *) allocate a new array at each call. The caller is responsible to free the allocated space: * * char *c = receiver->getFileName(); - * .... + * Or + * FIXME: so that the pointers are not shared external to the class, do the following way in the calling method? + * char *c = new char[MAX_STR_LENGTH]; + * strcpy(c,receiver->getFileName()); + * .... + * * delete[] c; * - * always: 1:YES 0:NO for int as bool-like arguments + * All pointers passed in externally will be allocated and freed by the calling function + * + * OK and FAIL are defined in include/sls_receiver_defs.h for functions implementing behavior * */ public: + /************************************************************************* + * Constructor & Destructor ********************************************** + * They access local cache of configuration or detector parameters ******* + *************************************************************************/ + /** + * Constructor + * Only non virtual function implemented in this class + * Factory create method to create a standard or REST object + * @param [in] receiver_type type can be standard or REST + * @return a UDPInterface reference to object depending on receiver type + */ + static UDPInterface *create(string receiver_type = "standard"); + /** * Destructor */ virtual ~UDPInterface() {}; - /** - * Factory create method + + + /************************************************************************* + * Getters *************************************************************** + * They access local cache of configuration or detector parameters ******* + *************************************************************************/ + + //**initial parameters*** + /* + * Get detector hostname + * @return hostname or NULL if uninitialized, must be released by calling function (max of 1000 characters) */ - static UDPInterface *create(string receiver_type = "standard"); + virtual char *getDetectorHostname() const = 0; - virtual void configure(map config_map) = 0; - - public: - + //***file parameters*** /** - * Initialize the Receiver - @param detectorHostName detector hostname - * you can call this function only once. You must call it before you call startReceiver() for the first time. - */ - virtual void initialize(const char *detectorHostName) = 0; - - - /* Returns detector hostname - /returns hostname - * caller needs to deallocate the returned char array. - * if uninitialized, it must return NULL - */ - virtual char *getDetectorHostname() const = 0; - - /** - * Returns status of receiver: idle, running or error - */ - virtual slsReceiverDefs::runStatus getStatus() const = 0; - - /** - * Returns File Name - * caller is responsible to deallocate the returned char array. + * Get File Name Prefix (without frame index, file index and extension (_d0_f000000000000_8.raw)) + * @return NULL or pointer to file name prefix, must be released by calling function (max of 1000 characters) */ virtual char *getFileName() const = 0; - /** - * Returns File Path - * caller is responsible to deallocate the returned char array + * Get File Path + * @return NULL or pointer to file path, must be released by calling function (max of 1000 characters) */ - virtual char *getFilePath() const = 0; //FIXME: Does the caller need to free() the returned pointer? - + virtual char *getFilePath() const = 0; /** - * Returns the number of bits per pixel + * Get File Index + * @return NULL or file index of acquisition */ - virtual int getDynamicRange() const = 0; + virtual uint64_t getFileIndex() const = 0; /** - * Returns scan tag + * Get Scan Tag + * @return scan tag //FIXME: needed? (unsigned integer?) */ virtual int getScanTag() const = 0; + /** + * Get if Frame Index is enabled (acquisition of more than 1 frame adds '_f000000000000' to file name ) + * @return true if frame index needed, else false + */ + virtual bool getFrameIndexEnable() const = 0; + + /** + * Get File Write Enable + * @return true if file write enabled, else false + */ + virtual bool getFileWriteEnable() const = 0; + + /** + * Get File Over Write Enable + * @return true if file over write enabled, else false + */ + virtual bool getOverwriteEnable() const = 0; + + /** + * Get data compression, by saving only hits (so far implemented only for Moench and Gotthard) + * @return true if data compression enabled, else false + */ + virtual bool getDataCompressionEnable() const = 0; + + + //***acquisition count parameters*** + /** + * Get Total Frames Caught for an entire acquisition (including all scans) + * @return total number of frames caught for entire acquisition + */ + virtual uint64_t getTotalFramesCaught() const = 0; + + /** + * Get Frames Caught for each real time acquisition (eg. for each scan) + * @return number of frames caught for each scan + */ + virtual uint64_t getFramesCaught() const = 0; + + /** + * Get Current Frame Index Caught for an entire acquisition (including all scans) + * @return current frame index (represents all scans too) or -1 if no packets caught + */ + virtual int64_t getAcquisitionIndex() const = 0; + + + //***connection parameters*** + /** + * Get UDP Port Number + * @return udp port number + */ + virtual uint32_t getUDPPortNo() const = 0; + + /** + * Get Second UDP Port Number (eiger specific) + * @return second udp port number + */ + virtual uint32_t getUDPPortNo2() const = 0; + + /** + * Get Ehernet Interface + * @return ethernet interface. eg. eth0 (max of 1000 characters) + */ + virtual char *getEthernetInterface() const = 0; + + + //***acquisition parameters*** + /** + * Get Short Frame Enabled, later will be moved to getROI (so far only for gotthard) + * @return index of adc enabled, else -1 if all enabled + */ + virtual int getShortFrameEnable() const = 0; + + /** + * Get the Frequency of Frames Sent to GUI + * @return 0 for random frame requests, n for nth frame frequency + */ + virtual uint32_t getFrameToGuiFrequency() const = 0; + + /** + * Get Acquisition Period + * @return acquisition period + */ + virtual uint64_t getAcquisitionPeriod() const = 0; + /* - * Returns number of frames to receive - * This is the number of frames to expect to receiver from the detector. - * The data receiver will change from running to idle when it got this number of frames + * Get Number of Frames expected by receiver from detector + * The data receiver status will change from running to idle when it gets this number of frames FIXME: (Not implemented) + * @return number of frames expected */ - virtual int getNumberOfFrames() const = 0; + virtual uint64_t getNumberOfFrames() const = 0; /** - * Returns file write enable - * 1: YES 0: NO - */ - virtual int getEnableFileWrite() const = 0; - - /** - * Returns file over write enable - * 1: YES 0: NO - */ - virtual int getEnableOverwrite() const = 0; - - /** - * Set File Name (without frame index, file index and extension) - @param c file name - /returns file name - * returns NULL on failure (like bad file name) - * does not check the existence of the file - we don't know which path we'll finally use, so no point to check. - * caller is responsible to deallocate the returned char array. + * Get Dynamic Range or Number of Bits Per Pixel + * @return dynamic range that is 4, 8, 16 or 32 */ - virtual char* setFileName(const char c[]) = 0; + virtual uint32_t getDynamicRange() const = 0; + + /** + * Get Ten Giga Enable + * @return true if 10Giga enabled, else false (1G enabled) + */ + virtual bool getTenGigaEnable() const = 0; + + //***receiver status*** + /** + * Get Listening Status of Receiver + * @return can be idle, listening or error depending on if the receiver is listening or not + */ + virtual slsReceiverDefs::runStatus getStatus() const = 0; + + + + + /************************************************************************* + * Setters *************************************************************** + * They modify the local cache of configuration or detector parameters *** + *************************************************************************/ + + //**initial parameters*** + /** + * Configure command line parameters + * @param config_map mapping of config parameters passed from command line arguments + */ + virtual void configure(map config_map) = 0; + + /** + * Set Bottom Enable (eiger specific, should be moved to configure, and later from client via TCPIP) + * @param b is true for bottom enabled or false for bottom disabled + */ + virtual void setBottomEnable(const bool b)= 0; + + + //***file parameters*** + /** + * Set File Name Prefix (without frame index, file index and extension (_d0_f000000000000_8.raw)) + * Does not check for file existence since it is created only at startReceiver + * @param c file name (max of 1000 characters) + */ + virtual void setFileName(const char c[]) = 0; /** * Set File Path - @param c file path - /returns file path - * checks the existence of the directory. returns NULL if directory does not exist or is not readable. - * caller is responsible to deallocate the returned char array. + * Checks for file directory existence before setting file path + * @param c file path (max of 1000 characters) */ - virtual char* setFilePath(const char c[]) = 0; + virtual void setFilePath(const char c[]) = 0; /** - * Returns the number of bits per pixel - @param dr sets dynamic range - /returns dynamic range - * returns -1 on failure - * FIXME: what are the allowd values - should we use an enum as argument? + * Set File Index of acquisition + * @param i file index of acquisition */ - virtual int setDynamicRange(const int dr) = 0; - + virtual void setFileIndex(const uint64_t i) = 0; /** - * Set scan tag - @param tag scan tag - /returns scan tag (always non-negative) - * FIXME: valid range - only positive? 16bit ore 32bit? - * returns -1 on failure + * Set Scan Tag + * @param i scan tag //FIXME: needed? (unsigned integer?) */ - virtual int setScanTag(const int tag) = 0; + virtual void setScanTag(const int i) = 0; /** - * Sets number of frames - @param fnum number of frames - /returns number of frames + * Set Frame Index Enable (acquisition of more than 1 frame adds '_f000000000000' to file name ) + * @param b true for frame index enable, else false */ - virtual int setNumberOfFrames(const int fnum) = 0; + virtual void setFrameIndexEnable(const bool b) = 0; /** - * Set enable file write - * @param i file write enable - /returns file write enable + * Set File Write Enable + * @param b true for file write enable, else false */ - virtual int setEnableFileWrite(const int i) = 0; + virtual void setFileWriteEnable(const bool b) = 0; /** - * Set enable file overwrite - * @param i file overwrite enable - /returns file overwrite enable + * Set File Overwrite Enable + * @param b true for file overwrite enable, else false */ - virtual int setEnableOverwrite(const int i) = 0; + virtual void setOverwriteEnable(const bool b) = 0; /** - * Starts Receiver - activate all configuration settings to the eiger receiver and start to listen for packets - @param message is the error message if there is an error - /returns 0 on success or -1 on failure + * Set data compression, by saving only hits (so far implemented only for Moench and Gotthard) + * @param b true for data compression enable, else false */ - //FIXME: success == 0 or success == 1? - virtual int startReceiver(char *message=NULL) = 0; //FIXME: who allocates message[]? - - /** - * Stops Receiver - stops listening for packets - /returns success - * same as abort(). Always returns 0. - */ - virtual int stopReceiver() = 0; - - /** - * abort acquisition with minimum damage: close open files, cleanup. - * does nothing if state already is 'idle' - */ - virtual void abort() = 0; + virtual void setDataCompressionEnable(const bool b) = 0; - -/******************************************************************************************************************* - **************************************** Added by Dhanya ********************************************************* - *******************************************************************************************************************/ - - /** - * Set bottom to bot - * @param bot = 1 if bottom - */ - virtual void setBottom(int bot)= 0; - - /** - * Returns File Index - */ - virtual int getFileIndex() = 0; - - /** - * Returns Total Frames Caught for an entire acquisition (including all scans) - */ - virtual int getTotalFramesCaught() = 0; - - /** - * Returns Frames Caught for each real time acquisition (eg. for each scan) - */ - virtual int getFramesCaught() = 0; - - /** - * Returns the frame index at start of entire acquisition (including all scans) - */ - virtual uint32_t getStartAcquisitionIndex()=0; - - /** - * Returns current Frame Index Caught for an entire acquisition (including all scans) - */ - virtual uint32_t getAcquisitionIndex() = 0; - - /** - * Returns the frame index at start of each real time acquisition (eg. for each scan) - */ - virtual uint32_t getStartFrameIndex() = 0; - - /** get data compression, by saving only hits - */ - virtual bool getDataCompression() = 0; - - /** - * Set receiver type - * @param det detector type - * Returns success or FAIL - */ - virtual int setDetectorType(slsReceiverDefs::detectorType det) = 0; - - /** - * Set File Index - * @param i file index - */ - virtual int setFileIndex(int i) = 0; - - /** set acquisition period if a positive number - */ - virtual int64_t setAcquisitionPeriod(int64_t index) = 0; - - /** - * Set Frame Index Needed - * @param i frame index needed - */ - virtual int setFrameIndexNeeded(int i) = 0; - + //***connection parameters*** /** * Set UDP Port Number + * @param i udp port number */ - virtual void setUDPPortNo(int p) = 0; + virtual void setUDPPortNo(const uint32_t i) = 0; /** - * Set UDP Port Number + * Set Second UDP Port Number (eiger specific) + * @return second udp port number */ - virtual void setUDPPortNo2(int p) = 0; + virtual void setUDPPortNo2(const uint32_t i) = 0; /** - * Set Ethernet Interface or IP to listen to + * Set Ethernet Interface to listen to + * @param c ethernet inerface eg. eth0 (max of 1000 characters) */ - virtual void setEthernetInterface(char* c) = 0; + virtual void setEthernetInterface(const char* c) = 0; + + + //***connection parameters*** + /** + * Set Short Frame Enabled, later will be moved to getROI (so far only for gotthard) + * @param i index of adc enabled, else -1 if all enabled + */ + virtual void setShortFrameEnable(const int i) = 0; /** - * Set short frame - * @param i if shortframe i=1 + * Set the Frequency of Frames Sent to GUI + * @param i 0 for random frame requests, n for nth frame frequency */ - virtual int setShortFrame(int i) = 0; + virtual void setFrameToGuiFrequency(const uint32_t i) = 0; /** - * Set the variable to send every nth frame to gui - * or if 0,send frame only upon gui request + * Set Acquisition Period + * @param i acquisition period */ - virtual int setNFrameToGui(int i) = 0; + virtual void setAcquisitionPeriod(const uint64_t i) = 0; /** - * Resets the Total Frames Caught - * This is how the receiver differentiates between entire acquisitions - * Returns 0 + * Set Number of Frames expected by receiver from detector + * The data receiver status will change from running to idle when it gets this number of frames FIXME: (Not implemented) + * @param i number of frames expected */ - virtual void resetTotalFramesCaught() = 0; - - /** enabl data compression, by saving only hits - /returns if failed - */ - virtual int enableDataCompression(bool enable) = 0; + virtual void setNumberOfFrames(const uint64_t i) = 0; /** - * enable 10Gbe - @param enable 1 for 10Gbe or 0 for 1 Gbe, -1 to read out - \returns enable for 10Gbe + * Set Dynamic Range or Number of Bits Per Pixel + * @param i dynamic range that is 4, 8, 16 or 32 */ - virtual int enableTenGiga(int enable = -1) = 0; + virtual void setDynamicRange(const uint32_t i) = 0; /** - * Returns the buffer-current frame read by receiver - * @param c pointer to current file name - * @param raw address of pointer, pointing to current frame to send to gui - * @param startAcquisitionIndex is the start index of the acquisition - * @param startFrameIndex is the start index of the scan + * Set Ten Giga Enable + * @param b true if 10Giga enabled, else false (1G enabled) */ - virtual void readFrame(char* c,char** raw, uint32_t &startAcquisitionIndex, uint32_t &startFrameIndex)=0; + virtual void setTenGigaEnable(const bool b) = 0; - /** set status to transmitting and - * when fifo is empty later, sets status to run_finished + + + /************************************************************************* + * Behavioral functions*************************************************** + * They may modify the status of the receiver **************************** + *************************************************************************/ + + //***initial functions*** + /** + * Set receiver type (and corresponding detector variables in derived STANDARD class) + * It is the first function called by the client when connecting to receiver + * @param d detector type + * @return OK or FAIL + */ + virtual int setDetectorType(const slsReceiverDefs::detectorType d) = 0; + + /** + * Sets detector hostname (and corresponding detector variables in derived REST class) + * It is second function called by the client when connecting to receiver. + * you can call this function only once. //FIXME: is this still valid, this implemented in derived REST class? + * @param c detector hostname + */ + virtual void initialize(const char *c) = 0; + + + //***acquisition functions*** + /** + * Reset acquisition parameters such as total frames caught for an entire acquisition (including all scans) + */ + void resetAcquisitionCount(); + + /** + * Start Listening for Packets by activating all configuration settings to receiver + * @param c error message if FAIL + * @return OK or FAIL + */ + virtual int startReceiver(char *c=NULL) = 0; + + /** + * Stop Listening for Packets + * Calls startReadout(), which stops listening and sets status to Transmitting + * When it has read every frame in buffer,it returns with the status Run_Finished + */ + virtual void stopReceiver() = 0; + + /** + * Stop Listening to Packets + * and sets status to Transmitting */ virtual void startReadout() = 0; /** * shuts down the udp sockets - * \returns if success or fail + * \returns OK or FAIL */ virtual int shutDownUDPSockets() = 0; /** - * Closes all files - * @param ithr thread index, -1 for all threads + * Get the buffer-current frame read by receiver + * @param c pointer to current file name + * @param raw address of pointer, pointing to current frame to send to gui + * @param startAcquisitionIndex start index of the acquisition + * @param startFrameIndex start index of the scan */ - virtual void closeFile(int ithr = -1) = 0; + virtual void readFrame(char* c,char** raw, uint64_t &startAcquisitionIndex, uint64_t &startFrameIndex)=0; /** - * Call back for start acquisition - callback arguments are - filepath - filename - fileindex - datasize + * abort acquisition with minimum damage: close open files, cleanup. + * does nothing if state already is 'idle' + */ + virtual void abort() = 0; //FIXME: needed, isnt stopReceiver enough? - return value is - 0 callback takes care of open,close,wrie file - 1 callback writes file, we have to open, close it - 2 we open, close, write file, callback does not do anything - */ - virtual void registerCallBackStartAcquisition(int (*func)(char*, char*,int, int, void*),void *arg) = 0; + /** + * Closes all files + * @param i thread index, -1 for all threads + */ + virtual void closeFile(int i = -1) = 0; + + + //***callback functions*** + /** + * Call back for start acquisition + * callback arguments are + * filepath + * filename + * fileindex + * datasize + * + * return value is + * 0 callback takes care of open,close,wrie file + * 1 callback writes file, we have to open, close it + * 2 we open, close, write file, callback does not do anything + */ + virtual void registerCallBackStartAcquisition(int (*func)(char*, char*,uint64_t, uint32_t, void*),void *arg) = 0; /** * Call back for acquisition finished - callback argument is - total frames caught - */ - virtual void registerCallBackAcquisitionFinished(void (*func)(int, void*),void *arg) = 0; + * callback argument is + * total frames caught + */ + virtual void registerCallBackAcquisitionFinished(void (*func)(uint64_t, void*),void *arg) = 0; /** * Call back for raw data - args to raw data ready callback are - framenum - datapointer - datasize in bytes - file descriptor - guidatapointer (NULL, no data required) - */ - virtual void registerCallBackRawDataReady(void (*func)(int, char*, int, FILE*, char*, void*),void *arg) = 0; - + * args to raw data ready callback are + * framenum + * datapointer + * datasize in bytes + * file descriptor + * guidatapointer (NULL, no data required) + */ + virtual void registerCallBackRawDataReady(void (*func)(uint64_t, char*, uint32_t, FILE*, char*, void*),void *arg) = 0; + + protected: - private: }; diff --git a/slsReceiverSoftware/include/UDPStandardImplementation.h b/slsReceiverSoftware/include/UDPStandardImplementation.h index 2916ee6b9..04bd7000e 100644 --- a/slsReceiverSoftware/include/UDPStandardImplementation.h +++ b/slsReceiverSoftware/include/UDPStandardImplementation.h @@ -24,6 +24,7 @@ #endif + #include #include #include @@ -199,7 +200,7 @@ class UDPStandardImplementation: private virtual slsReceiverDefs, public UDPBase * Set detector hostname * @param c hostname */ - void initialize(const char *detectorHostName); + void setDetectorHostname(const char *detectorHostName); /* Returns detector hostname /returns hostname @@ -484,6 +485,224 @@ private: void handleDataCompression(int ithread, char* wbuffer[], char* data, int xmax, int ymax, int &nf); + + + + + + + + + + + + + + + + + + + + + + + /** max number of writer threads */ + const static int MAX_NUM_WRITER_THREADS = 15; + + /** missing packet identifier value */ + const static uint16_t missingPacketValue = 0xFFFF; + + + /** UDP Socket between Receiver and Detector */ + genericSocket* udpSocket[MAX_NUM_LISTENING_THREADS]; + + /** max packets per file **/ + int maxPacketsPerFile; + + /** Frame Index at start of an entire acquisition (including all scans) */ + uint64_t startAcquisitionIndex; + /** Complete File name */ + char savefilename[MAX_STR_LENGTH]; + + /* Measurement started */ + bool measurementStarted; + /* Acquisition started */ + bool acqStarted; + /** Frame index at start of each real time acquisition (eg. for each scan) */ + uint32_t startFrameIndex; + + /** Actual current frame index of each time acquisition (eg. for each scan) */ + uint32_t frameIndex; + + /** Pckets currently in current file, starts new file when it reaches max */ + uint32_t packetsInFile; + + /** Number of missing packets in acquisition*/ + uint32_t numTotMissingPackets; + + /** Number of missing packets in file (sometimes packetsinFile is incorrect due to padded packets for eiger)*/ + uint32_t numTotMissingPacketsInFile; + + /** Number of missing packets per buffer*/ + uint32_t numMissingPackets; + + /** frame index mask */ + uint32_t frameIndexMask; + + /** packet index mask */ + uint32_t packetIndexMask; + + /** frame index offset */ + int frameIndexOffset; + /** Current Frame Number */ + uint64_t currframenum; + + /** Previous Frame number from buffer */ + int prevframenum; + + /** size of one frame */ + int frameSize; + + /** buffer size. different from framesize as we wait for one packet instead of frame for eiger */ + int bufferSize; + + /** one buffer size */ + int onePacketSize; + + /** one buffer size */ + int oneDataSize; + + /** latest data */ + char* latestData; + + /** gui data ready */ + int guiDataReady; + + /** points to the data to send to gui */ + char* guiData; + + /** points to the filename to send to gui */ + char* guiFileName; + + /** fifo size */ + unsigned int fifosize; + + /** number of jobs per thread for data compression */ + int numJobsPerThread; + + /** memory allocated for the buffer */ + char *mem0[MAX_NUM_LISTENING_THREADS]; + + /** circular fifo to store addresses of data read */ + CircularFifo* fifo[MAX_NUM_LISTENING_THREADS]; + + /** circular fifo to store addresses of data already written and ready to be resued*/ + CircularFifo* fifoFree[MAX_NUM_LISTENING_THREADS]; + + /** Receiver buffer */ + char *buffer[MAX_NUM_LISTENING_THREADS]; + + /** number of writer threads */ + int numListeningThreads; + + /** number of writer threads */ + int numWriterThreads; + + /** to know if listening and writer threads created properly */ + int thread_started; + + /** current listening thread index*/ + int currentListeningThreadIndex; + + /** current writer thread index*/ + int currentWriterThreadIndex; + + /** thread listening to packets */ + pthread_t listening_thread[MAX_NUM_LISTENING_THREADS]; + + /** thread writing packets */ + pthread_t writing_thread[MAX_NUM_WRITER_THREADS]; + + /** total frame count the listening thread has listened to */ + int totalListeningFrameCount[MAX_NUM_LISTENING_THREADS]; + + /** mask showing which listening threads are running */ + volatile uint32_t listeningthreads_mask; + + /** mask showing which writer threads are running */ + volatile uint32_t writerthreads_mask; + + /** mask showing which threads have created files*/ + volatile uint32_t createfile_mask; + + /** OK if file created was successful */ + int ret_createfile; + + /** variable used to self terminate threads waiting for semaphores */ + int killAllListeningThreads; + + /** variable used to self terminate threads waiting for semaphores */ + int killAllWritingThreads; + + + + /** footer offset is different for 1g and 10g*/ + int footer_offset; + + // TODO: not properly sure where to put these... + /** structure of an eiger image header*/ + + + + +//semaphores + /** semaphore to synchronize writer and guireader threads */ + sem_t smp; + /** semaphore to synchronize listener threads */ + sem_t listensmp[MAX_NUM_LISTENING_THREADS]; + /** semaphore to synchronize writer threads */ + sem_t writersmp[MAX_NUM_WRITER_THREADS]; + + +//mutex + /** guiDataReady mutex */ + pthread_mutex_t dataReadyMutex; + + /** mutex for status */ + pthread_mutex_t status_mutex; + + /** mutex for progress variable currframenum */ + pthread_mutex_t progress_mutex; + + /** mutex for writing data to file */ + pthread_mutex_t write_mutex; + + /** File Descriptor */ + FILE *sfilefd; + + //filter + singlePhotonDetector *singlePhotonDet[MAX_NUM_WRITER_THREADS]; + slsReceiverData *receiverdata[MAX_NUM_WRITER_THREADS]; + moenchCommonMode *cmSub; + bool commonModeSubtractionEnable; + +#ifdef MYROOT1 + /** Tree where the hits are stored */ + TTree *myTree[MAX_NUM_WRITER_THREADS]; + + /** File where the tree is saved */ + TFile *myFile[MAX_NUM_WRITER_THREADS]; +#endif + + + /** The action which decides what the user and default responsibilites to save data are + * 0 raw data ready callback takes care of open,close,write file + * 1 callback writes file, we have to open, close it + * 2 we open, close, write file, callback does not do anything */ + int cbAction; + + public: diff --git a/slsReceiverSoftware/src/UDPBaseImplementation.cpp b/slsReceiverSoftware/src/UDPBaseImplementation.cpp index 682c52980..e16060865 100644 --- a/slsReceiverSoftware/src/UDPBaseImplementation.cpp +++ b/slsReceiverSoftware/src/UDPBaseImplementation.cpp @@ -1,4 +1,4 @@ -#ifdef SLS_RECEIVER_UDP_FUNCTIONS +//#ifdef SLS_RECEIVER_UDP_FUNCTIONS /********************************************//** * @file UDPBaseImplementation.cpp * @short does all the functions for a receiver, set/get parameters, start/stop etc. @@ -23,178 +23,204 @@ #include #include -//#include "utilities.h" - using namespace std; +/************************************************************************* + * Constructor & Destructor ********************************************** + * They access local cache of configuration or detector parameters ******* + *************************************************************************/ UDPBaseImplementation::UDPBaseImplementation(){ -} + //**detector parameters*** + strcpy(detHostname,""); + packetsPerFrame = 0; + acquisitionPeriod = 0; + numberOfFrames = 0; + dynamicRange = 16; + tengigaEnable = false; + bottomEnable = false; + //***receiver parameters*** + status = IDLE; -UDPBaseImplementation::~UDPBaseImplementation(){} + //***connection parameters*** + strcpy(eth,""); + for(int i=0;i config_map){ - FILE_LOG(logWARNING) << __AT__ << "doing nothing..."; + //***acquisition count parameters*** + totalPacketsCaught = 0; + packetsCaught = 0; + + //***acquisition indices parameters*** + acquisitionIndex = 0; + + //***acquisition parameters*** + shortFrameEnable = -1; + FrameToGuiFrequency = 0; + + //***callback parameters*** + startAcquisitionCallBack = NULL; + pStartAcquisition = NULL; + acquisitionFinishedCallBack = NULL; + pAcquisitionFinished = NULL; + rawDataReadyCallBack = NULL; + pRawDataReady = NULL; }; +UDPBaseImplementation::~UDPBaseImplementation(){}; -void UDPBaseImplementation::deleteMembers(){ - FILE_LOG(logWARNING) << "[WARNING] This is a base implementation, " << __func__ << " could have no effects."; + +/************************************************************************* + * Getters *************************************************************** + * They access local cache of configuration or detector parameters ******* + *************************************************************************/ + +/**initial parameters***/ +char *UDPBaseImplementation::getDetectorHostname() const{ + FILE_LOG(logDEBUG) << __AT__ << " starting"; + + //not initialized + if(!strlen(detHostname)) + return NULL; + + char* output = new char[MAX_STR_LENGTH]; + strcpy(output,detHostname); + //freed by calling function + return output; } -void UDPBaseImplementation::initializeMembers(){ - FILE_LOG(logWARNING) << "[WARNING] This is a base implementation, " << __func__ << " could have no effects."; +/***file parameters***/ +char *UDPBaseImplementation::getFileName() const{ + FILE_LOG(logDEBUG) << __AT__ << " starting"; + + //not initialized + if(!strlen(fileName)) + return NULL; + + char* output = new char[MAX_STR_LENGTH]; + strcpy(output,fileName); + //freed by calling function + return output; } +char *UDPBaseImplementation::getFilePath() const{ + FILE_LOG(logDEBUG) << __AT__ << " starting"; -int UDPBaseImplementation::setDetectorType(detectorType det){ - cout << "[WARNING] This is a base implementation, " << __func__ << " not correctly implemented" << endl; - cout << "Setting Receiver Type " << endl; + //not initialized + if(!strlen(filePath)) + return NULL; - deleteMembers(); - initializeMembers(); - - myDetectorType = det; - - switch(myDetectorType){ - case GOTTHARD: - cout << endl << "***** This is a GOTTHARD Receiver *****" << endl << endl; - break; - case MOENCH: - cout << endl << "***** This is a MOENCH Receiver *****" << endl << endl; - break; - case EIGER: - cout << endl << "***** This is a EIGER Receiver *****" << endl << endl; - break; - default: - cout << endl << "***** Unknown Receiver *****" << endl << endl; - return FAIL; - break; - } - /* - //moench variables - if(myDetectorType == GOTTHARD){ - fifosize = GOTTHARD_FIFO_SIZE; - packetsPerFrame = GOTTHARD_PACKETS_PER_FRAME; - onePacketSize = GOTTHARD_ONE_PACKET_SIZE; - frameSize = GOTTHARD_BUFFER_SIZE; - bufferSize = GOTTHARD_BUFFER_SIZE; - maxPacketsPerFile = MAX_FRAMES_PER_FILE * GOTTHARD_PACKETS_PER_FRAME; - frameIndexMask = GOTTHARD_FRAME_INDEX_MASK; - frameIndexOffset = GOTTHARD_FRAME_INDEX_OFFSET; - packetIndexMask = GOTTHARD_PACKET_INDEX_MASK; - }else if(myDetectorType == MOENCH){ - fifosize = MOENCH_FIFO_SIZE; - packetsPerFrame = MOENCH_PACKETS_PER_FRAME; - onePacketSize = MOENCH_ONE_PACKET_SIZE; - frameSize = MOENCH_BUFFER_SIZE; - bufferSize = MOENCH_BUFFER_SIZE; - maxPacketsPerFile = MOENCH_MAX_FRAMES_PER_FILE * MOENCH_PACKETS_PER_FRAME; - frameIndexMask = MOENCH_FRAME_INDEX_MASK; - frameIndexOffset = MOENCH_FRAME_INDEX_OFFSET; - packetIndexMask = MOENCH_PACKET_INDEX_MASK; - } - else if(myDetectorType == EIGER){ - fifosize = EIGER_FIFO_SIZE; - packetsPerFrame = EIGER_ONE_GIGA_CONSTANT * dynamicRange * EIGER_MAX_PORTS; - onePacketSize = EIGER_ONE_GIGA_ONE_PACKET_SIZE; - frameSize = onePacketSize * packetsPerFrame; - bufferSize = (frameSize/EIGER_MAX_PORTS) + EIGER_HEADER_LENGTH;//everything one port gets (img header plus packets) - maxPacketsPerFile = EIGER_MAX_FRAMES_PER_FILE * packetsPerFrame; - frameIndexMask = EIGER_FRAME_INDEX_MASK; - frameIndexOffset = EIGER_FRAME_INDEX_OFFSET; - packetIndexMask = EIGER_PACKET_INDEX_MASK; - - pthread_mutex_lock(&status_mutex); - listeningthreads_mask = 0x0; - pthread_mutex_unlock(&(status_mutex)); - if(thread_started) - createListeningThreads(true); - - numListeningThreads = MAX_NUM_LISTENING_THREADS; - } - latestData = new char[frameSize]; - - - setupFifoStructure(); - - if(createListeningThreads() == FAIL){ - cout << "ERROR: Could not create listening thread" << endl; - exit (-1); - } - - if(createWriterThreads() == FAIL){ - cout << "ERROR: Could not create writer threads" << endl; - exit (-1); - } - - setThreadPriorities(); - - cout << "Ready..." << endl; - - return OK; - */ - return OK; + char* output = new char[MAX_STR_LENGTH]; + strcpy(output,filePath); + //freed by calling function + return output; } +uint32_t UDPBaseImplementation::getFileIndex() const{ FILE_LOG(logDEBUG) << __AT__ << " starting"; return fileIndex;} +int UDPBaseImplementation::getScanTag() const{ FILE_LOG(logDEBUG) << __AT__ << " starting"; return scanTag;} -void UDPBaseImplementation::setBottom(int bot){bottom=bot;}; +bool UDPBaseImplementation::getFrameIndexEnable() const{ FILE_LOG(logDEBUG) << __AT__ << " starting"; return frameIndexEnable;} -/*Frame indices and numbers caught*/ +bool UDPBaseImplementation::getFileWriteEnable() const{ FILE_LOG(logDEBUG) << __AT__ << " starting"; return fileWriteEnable;} -bool UDPBaseImplementation::getAcquistionStarted(){ FILE_LOG(logDEBUG) << __AT__ << " starting";return acqStarted;}; +bool UDPBaseImplementation::getOverwriteEnable() const{ FILE_LOG(logDEBUG) << __AT__ << " starting"; return overwriteEnable;} -bool UDPBaseImplementation::getMeasurementStarted(){ FILE_LOG(logDEBUG) << __AT__ << " starting";return measurementStarted;}; +bool UDPBaseImplementation::getDataCompressionEnable() const{ FILE_LOG(logDEBUG) << __AT__ << " starting"; return dataCompressionEnable;} -int UDPBaseImplementation::getFramesCaught(){ FILE_LOG(logDEBUG) << __AT__ << " starting";return (packetsCaught/packetsPerFrame);} +/***acquisition count parameters***/ +uint64_t UDPBaseImplementation::getTotalFramesCaught() const{ FILE_LOG(logDEBUG) << __AT__ << " starting"; return (totalPacketsCaught/packetsPerFrame);} -int UDPBaseImplementation::getTotalFramesCaught(){ FILE_LOG(logDEBUG) << __AT__ << " starting";return (totalPacketsCaught/packetsPerFrame);} +uint64_t UDPBaseImplementation::getFramesCaught() const{ FILE_LOG(logDEBUG) << __AT__ << " starting"; return (packetsCaught/packetsPerFrame);} -uint32_t UDPBaseImplementation::getStartAcquisitionIndex(){ FILE_LOG(logDEBUG) << __AT__ << " starting";return startAcquisitionIndex;} +int64_t UDPBaseImplementation::getAcquisitionIndex() const{ + FILE_LOG(logDEBUG) << __AT__ << " starting"; -uint32_t UDPBaseImplementation::getStartFrameIndex(){ FILE_LOG(logDEBUG) << __AT__ << " starting";return startFrameIndex;} - -uint32_t UDPBaseImplementation::getFrameIndex(){ FILE_LOG(logDEBUG) << __AT__ << " starting"; - if(!packetsCaught) - frameIndex=-1; - else - frameIndex = currframenum - startFrameIndex; - return frameIndex; -} - - -uint32_t UDPBaseImplementation::getAcquisitionIndex(){ FILE_LOG(logDEBUG) << __AT__ << " starting"; if(!totalPacketsCaught) - acquisitionIndex=-1; - else - acquisitionIndex = currframenum - startAcquisitionIndex; - //cout<<"acquisitionIndex:"< config_map){ + FILE_LOG(logWARNING) << __AT__ << " doing nothing..."; + FILE_LOG(logERROR) << __AT__ << " must be overridden by child classes"; } -inline char* UDPBaseImplementation::setFilePath(const char c[]){ FILE_LOG(logDEBUG) << __AT__ << " starting"; - FILE_LOG(logDEBUG) << __AT__ << "called"; +void UDPBaseImplementation::setBottomEnable(const bool b){ + FILE_LOG(logDEBUG) << __AT__ << " starting"; + + bottomEnable = b; + FILE_LOG(logINFO) << "Bottom Enable:" << bottomEnable; +} + + +/***file parameters***/ +void UDPBaseImplementation::setFileName(const char c[]){ + FILE_LOG(logDEBUG) << __AT__ << " starting"; + + if(strlen(c)) + strcpy(fileName, c); + FILE_LOG(logINFO) << "File name:" << fileName; +} + +void UDPBaseImplementation::setFilePath(const char c[]){ + FILE_LOG(logDEBUG) << __AT__ << " starting"; + if(strlen(c)){ //check if filepath exists struct stat st; @@ -204,1484 +230,209 @@ inline char* UDPBaseImplementation::setFilePath(const char c[]){ FILE_LOG(logDEB strcpy(filePath,""); FILE_LOG(logWARNING) << "FilePath does not exist:" << filePath; } + strcpy(filePath, c); } - FILE_LOG(logDEBUG) << __AT__ << getFilePath(); -#ifdef VERBOSE - cout << getFilePath() << " " << filePath << endl; -#endif - return getFilePath(); + FILE_LOG(logINFO) << "File path:" << filePath; +} + +void UDPBaseImplementation::setFileIndex(const uint32_t i){ + FILE_LOG(logDEBUG) << __AT__ << " starting"; + + fileIndex = i; + FILE_LOG(logINFO) << "File Index:" << fileIndex; +} + +//FIXME: needed? +void UDPBaseImplementation::setScanTag(const int i){ + FILE_LOG(logDEBUG) << __AT__ << " starting"; + + scanTag = i; + FILE_LOG(logINFO) << "Scan Tag:" << scanTag; + +} + +void UDPBaseImplementation::setFrameIndexEnable(const bool b){ + FILE_LOG(logDEBUG) << __AT__ << " starting"; + + frameIndexEnable = b; + FILE_LOG(logINFO) << "Frame Index Enable:" << frameIndexEnable; +} + +void UDPBaseImplementation::setFileWriteEnable(const bool b){ + FILE_LOG(logDEBUG) << __AT__ << " starting"; + + fileWriteEnable = b; + FILE_LOG(logINFO) << "File Write Enable:" << fileWriteEnable; +} + +void UDPBaseImplementation::setOverwriteEnable(const bool b){ + FILE_LOG(logDEBUG) << __AT__ << " starting"; + + overwriteEnable = b; + FILE_LOG(logINFO) << "Overwrite Enable:" << overwriteEnable; +} + +void UDPBaseImplementation::setDataCompressionEnable(const bool b){ + FILE_LOG(logDEBUG) << __AT__ << " starting"; + + dataCompressionEnable = b; + FILE_LOG(logINFO) << "Data Compression Enable:" << dataCompressionEnable; } -char* UDPBaseImplementation::getFileName() const{ - FILE_LOG(logDEBUG) << __FILE__ << "::" << __func__ << " starting"; - return (char*)fileName; +/***connection parameters***/ +void UDPBaseImplementation::setUDPPortNo(const uint32_t i){ + FILE_LOG(logDEBUG) << __AT__ << " starting"; + + udpPortNum[0] = i; + FILE_LOG(logINFO) << "udpPortNum[0]:" << udpPortNum[0]; } -inline char* UDPBaseImplementation::setFileName(const char c[]){ FILE_LOG(logDEBUG) << __AT__ << " starting"; - //cout << "[WARNING] This is a base implementation, " << __func__ << " could have no effects." << endl; - +void UDPBaseImplementation::setUDPPortNo2(const uint32_t i){ + FILE_LOG(logDEBUG) << __AT__ << " starting"; + + udpPortNum[1] = i; + FILE_LOG(logINFO) << "udpPortNum[1]:" << udpPortNum[1]; +} + +void UDPBaseImplementation::setEthernetInterface(const char* c){ + FILE_LOG(logDEBUG) << __AT__ << " starting"; + + strcpy(eth, c); + FILE_LOG(logINFO) << "Ethernet Interface:" << eth; +} + + +/***connection parameters***/ +void UDPBaseImplementation::setShortFrameEnable(const int i){ + FILE_LOG(logDEBUG) << __AT__ << " starting"; + + shortFrameEnable = i; + FILE_LOG(logINFO) << "Short Frame Enable:" << shortFrameEnable; +} + +void UDPBaseImplementation::setFrameToGuiFrequency(const uint32_t i){ + FILE_LOG(logDEBUG) << __AT__ << " starting"; + + FrameToGuiFrequency = i; + FILE_LOG(logINFO) << "Frame To Gui Frequency:" << FrameToGuiFrequency; +} + +void UDPBaseImplementation::setAcquisitionPeriod(const uint64_t i){ + FILE_LOG(logDEBUG) << __AT__ << " starting"; + + acquisitionPeriod = i; + FILE_LOG(logINFO) << "Acquisition Period:" << acquisitionPeriod; +} + +void UDPBaseImplementation::setNumberOfFrames(const uint64_t i){ + FILE_LOG(logDEBUG) << __AT__ << " starting"; + + numberOfFrames = i; + FILE_LOG(logINFO) << "Number of Frames:" << numberOfFrames; +} + +void UDPBaseImplementation::setDynamicRange(const uint32_t i){ + FILE_LOG(logDEBUG) << __AT__ << " starting"; + + dynamicRange = i; + FILE_LOG(logINFO) << "Dynamic Range:" << dynamicRange; +} + +void UDPBaseImplementation::setTenGigaEnable(const bool b){ + FILE_LOG(logDEBUG) << __AT__ << " starting"; + + tengigaEnable = b; + FILE_LOG(logINFO) << "Ten Giga Enable:" << tengigaEnable; +} + + + +/************************************************************************* + * Behavioral functions*************************************************** + * They may modify the status of the receiver **************************** + *************************************************************************/ + +/***initial functions***/ +int UDPBaseImplementation::setDetectorType(const slsReceiverDefs::detectorType d){ + FILE_LOG(logDEBUG) << __AT__ << " starting"; + + myDetectorType = d; + FILE_LOG(logINFO) << "Detector Type:" << slsDetectorBase::getDetectorType(d); + return OK; +} + +void UDPBaseImplementation::initialize(const char *c){ + FILE_LOG(logDEBUG) << __AT__ << " starting"; + if(strlen(c)) - strcpy(fileName,c); - - return getFileName(); + strcpy(detHostname, c); + FILE_LOG(logINFO) << "Detector Hostname:" << detHostname; } -int UDPBaseImplementation::getFileIndex(){ FILE_LOG(logDEBUG) << __AT__ << " starting"; - return fileIndex; +/***acquisition functions***/ +void UDPBaseImplementation::resetAcquisitionCount(){ + FILE_LOG(logDEBUG) << __AT__ << " starting"; + + totalPacketsCaught = 0; + FILE_LOG(logINFO) << "totalPacketsCaught:" << totalPacketsCaught << endl; } -int UDPBaseImplementation::setFileIndex(int i){ FILE_LOG(logDEBUG) << __AT__ << " starting"; - //cout << "[WARNING] This is a base implementation, " << __func__ << " could have no effects." << endl; - if(i>=0) - fileIndex = i; - return getFileIndex(); -} - - -int UDPBaseImplementation::setFrameIndexNeeded(int i){ FILE_LOG(logDEBUG) << __AT__ << " starting"; - //cout << "[WARNING] This is a base implementation, " << __func__ << " could have no effects." << endl; - frameIndexNeeded = i; - return frameIndexNeeded; -} - - -int UDPBaseImplementation::getEnableFileWrite() const{ - FILE_LOG(logDEBUG) << __FILE__ << "::" << __func__ << " starting"; - -return enableFileWrite; -} - -int UDPBaseImplementation::setEnableFileWrite(int i){ FILE_LOG(logDEBUG) << __AT__ << " starting"; - enableFileWrite=i; - return getEnableFileWrite(); -} - -int UDPBaseImplementation::getEnableOverwrite() const{ - FILE_LOG(logDEBUG) << __FILE__ << "::" << __func__ << " starting"; - - return overwrite; -} - -int UDPBaseImplementation::setEnableOverwrite(int i){ FILE_LOG(logDEBUG) << __AT__ << " starting"; - overwrite=i; - return getEnableOverwrite(); -} - - - - - -/*other parameters*/ - -slsReceiverDefs::runStatus UDPBaseImplementation::getStatus() const{ - return status; -} - - -void UDPBaseImplementation::initialize(const char *detectorHostName){ FILE_LOG(logDEBUG) << __AT__ << " starting"; - if(strlen(detectorHostName)) - strcpy(detHostname,detectorHostName); -} - - -char *UDPBaseImplementation::getDetectorHostname() const{ - return (char*)detHostname; -} - -void UDPBaseImplementation::setEthernetInterface(char* c){ FILE_LOG(logDEBUG) << __AT__ << " starting"; - strcpy(eth,c); -} - - -void UDPBaseImplementation::setUDPPortNo(int p){ - server_port[0] = p; -} - - -void UDPBaseImplementation::setUDPPortNo2(int p){ - server_port[1] = p; -} - - -int UDPBaseImplementation::getNumberOfFrames() const { - return numberOfFrames; -} - - -int32_t UDPBaseImplementation::setNumberOfFrames(int32_t fnum){ FILE_LOG(logDEBUG) << __AT__ << " starting"; - if(fnum >= 0) - numberOfFrames = fnum; - - return getNumberOfFrames(); -} - - -int UDPBaseImplementation::getScanTag() const{ - return scanTag; -} - - -int32_t UDPBaseImplementation::setScanTag(int32_t stag){ FILE_LOG(logDEBUG) << __AT__ << " starting"; - if(stag >= 0) - scanTag = stag; - - return getScanTag(); -} - - -int UDPBaseImplementation::getDynamicRange() const{ - return dynamicRange; -} - -int32_t UDPBaseImplementation::setDynamicRange(int32_t dr){ FILE_LOG(logDEBUG) << __AT__ << " starting"; - cout << "Setting Dynamic Range" << endl; - - int olddr = dynamicRange; - if(dr >= 0){ - dynamicRange = dr; - - if(myDetectorType == EIGER){ - - - if(!tengigaEnable) - packetsPerFrame = EIGER_ONE_GIGA_CONSTANT * dynamicRange * EIGER_MAX_PORTS; - else - packetsPerFrame = EIGER_TEN_GIGA_CONSTANT * dynamicRange * EIGER_MAX_PORTS; - frameSize = onePacketSize * packetsPerFrame; - bufferSize = (frameSize/EIGER_MAX_PORTS) + EIGER_HEADER_LENGTH;//everything one port gets (img header plus packets) - maxPacketsPerFile = EIGER_MAX_FRAMES_PER_FILE * packetsPerFrame; - - - - if(olddr != dr){ - - //del - if(thread_started){ - createListeningThreads(true); - createWriterThreads(true); - } - for(int i=0;i=0){ - nFrameToGui = i; - setupFifoStructure(); - } - return nFrameToGui; -} - - - -int64_t UDPBaseImplementation::setAcquisitionPeriod(int64_t index){ FILE_LOG(logDEBUG) << __AT__ << " starting"; - - if(index >= 0){ - if(index != acquisitionPeriod){ - acquisitionPeriod = index; - setupFifoStructure(); - } - } - return acquisitionPeriod; -} - - -bool UDPBaseImplementation::getDataCompression(){ FILE_LOG(logDEBUG) << __AT__ << " starting";return dataCompression;} - -int UDPBaseImplementation::enableDataCompression(bool enable){ FILE_LOG(logDEBUG) << __AT__ << " starting"; - cout << "Data compression "; - if(enable) - cout << "enabled" << endl; - else - cout << "disabled" << endl; -#ifdef MYROOT1 - cout << " WITH ROOT" << endl; -#else - cout << " WITHOUT ROOT" << endl; -#endif - //delete filter for the current number of threads - deleteFilter(); - - dataCompression = enable; - pthread_mutex_lock(&status_mutex); - writerthreads_mask = 0x0; - pthread_mutex_unlock(&(status_mutex)); - - createWriterThreads(true); - - if(enable) - numWriterThreads = MAX_NUM_WRITER_THREADS; - else - numWriterThreads = 1; - - if(createWriterThreads() == FAIL){ - cprintf(BG_RED,"ERROR: Could not create writer threads\n"); - return FAIL; - } - setThreadPriorities(); - - - if(enable) - setupFilter(); - +int UDPBaseImplementation::startReceiver(char *c=NULL){ + FILE_LOG(logWARNING) << __AT__ << " doing nothing..."; + FILE_LOG(logERROR) << __AT__ << " must be overridden by child classes"; return OK; } +void UDPBaseImplementation::stopReceiver(){ + FILE_LOG(logWARNING) << __AT__ << " doing nothing..."; + FILE_LOG(logERROR) << __AT__ << " must be overridden by child classes"; +} +void UDPBaseImplementation::startReadout(){ + FILE_LOG(logWARNING) << __AT__ << " doing nothing..."; + FILE_LOG(logERROR) << __AT__ << " must be overridden by child classes"; +} +int UDPBaseImplementation::shutDownUDPSockets(){ + FILE_LOG(logWARNING) << __AT__ << " doing nothing..."; + FILE_LOG(logERROR) << __AT__ << " must be overridden by child classes"; +} +void UDPBaseImplementation::readFrame(char* c,char** raw, uint64_t &startAcquisitionIndex, uint64_t &startFrameIndex){ + FILE_LOG(logWARNING) << __AT__ << " doing nothing..."; + FILE_LOG(logERROR) << __AT__ << " must be overridden by child classes"; +} +//FIXME: needed, isnt stopReceiver enough? +void UDPBaseImplementation::abort(){ + FILE_LOG(logWARNING) << __AT__ << " doing nothing..."; + FILE_LOG(logERROR) << __AT__ << " must be overridden by child classes"; +} - - - - - - -/*other functions*/ - - -void UDPBaseImplementation::deleteFilter(){ FILE_LOG(logDEBUG) << __AT__ << " starting"; - int i; - cmSub=NULL; - - for(i=0;i(receiverdata[i], csize, sigma, sign, cmSub); +void UDPBaseImplementation::registerCallBackAcquisitionFinished(void (*func)(int, void*),void *arg){ + acquisitionFinishedCallBack=func; + pAcquisitionFinished=arg; +} +void UDPBaseImplementation::registerCallBackRawDataReady(void (*func)(int, char*, int, FILE*, char*, void*),void *arg){ + rawDataReadyCallBack=func; + pRawDataReady=arg; } - -//LEO: it is not clear to me.. -void UDPBaseImplementation::setupFifoStructure(){ FILE_LOG(logDEBUG) << __AT__ << " starting"; - -} - - - - - - - -/** acquisition functions */ -void UDPBaseImplementation::readFrame(char* c,char** raw,uint32_t &startAcquisitionIndex, uint32_t &startFrameIndex){ - FILE_LOG(logDEBUG) << __AT__ << " called"; - //point to gui data - if (guiData == NULL){ - guiData = latestData; - } - - //copy data and filename - strcpy(c,guiFileName); - startAcquisitionIndex = getStartAcquisitionIndex(); - startFrameIndex = getStartFrameIndex(); - - - //could not get gui data - if(!guiDataReady){ - *raw = NULL; - } - //data ready, set guidata to receive new data - else{ - *raw = guiData; - guiData = NULL; - if((nFrameToGui) && (writerthreads_mask)){ - //release after getting data - sem_post(&smp); - } - } -} - - - - - - -void UDPBaseImplementation::copyFrameToGui(char* startbuf[], char* buf){ FILE_LOG(logDEBUG) << __AT__ << " starting"; - -} - - - - - -int UDPBaseImplementation::createUDPSockets(){ FILE_LOG(logDEBUG) << __AT__ << " starting"; - - //if eth is mistaken with ip address - if (strchr(eth,'.')!=NULL) - strcpy(eth,""); - - shutDownUDPSockets(); - - //if no eth, listen to all - if(!strlen(eth)){ - cout<<"warning:eth is empty.listening to all"<getErrorStatus(); - if(iret){ -#ifdef VERBOSE - cprintf(BG_RED,"Could not create UDP socket on port %d error: %d\n",server_port[i], iret); -#endif - return FAIL; - } - } - - return OK; -} - - - - - - - -int UDPBaseImplementation::shutDownUDPSockets(){ FILE_LOG(logDEBUG) << __AT__ << " starting"; - for(int i=0;iShutDownSocket(); - delete udpSocket[i]; - udpSocket[i] = NULL; - } - } - return OK; -} - - - - - -int UDPBaseImplementation::createListeningThreads(bool destroy){ FILE_LOG(logDEBUG) << __AT__ << " starting"; - int i; - void* status; - - killAllListeningThreads = 0; - - pthread_mutex_lock(&status_mutex); - listeningthreads_mask = 0x0; - pthread_mutex_unlock(&(status_mutex)); - - if(!destroy){ - - //start listening threads - cout << "Creating Listening Threads(s)"; - - currentListeningThreadIndex = -1; - - for(i = 0; i < numListeningThreads; ++i){ - sem_init(&listensmp[i],1,0); - thread_started = 0; - currentListeningThreadIndex = i; - if(pthread_create(&listening_thread[i], NULL,startListeningThread, (void*) this)){ - cout << "Could not create listening thread with index " << i << endl; - return FAIL; - } - while(!thread_started); - cout << "."; - cout << flush; - } -#ifdef VERBOSE - cout << "Listening thread(s) created successfully." << endl; -#else - cout << endl; -#endif - }else{ - cout<<"Destroying Listening Thread(s)"<initEventTree(temp, &iframe); - //resets the pedestalSubtraction array and the commonModeSubtraction - singlePhotonDet[ithr]->newDataSet(); - if(myFile[ithr]==NULL){ - cout<<"file null"<IsOpen()){ - cout<<"file not open"< DO_NOTHING){ - //close - if(sfilefd){ - fclose(sfilefd); - sfilefd = NULL; - } - //open file - if(!overwrite){ - if (NULL == (sfilefd = fopen((const char *) (savefilename), "wx"))){ - cout << "Error: Could not create new file " << savefilename << endl; - return FAIL; - } - }else if (NULL == (sfilefd = fopen((const char *) (savefilename), "w"))){ - cout << "Error: Could not creat dsdasdserwe file " << savefilename << endl; - return FAIL; - } - //setting buffer - setvbuf(sfilefd,NULL,_IOFBF,BUF_SIZE); - - //printing packet losses and file names - if(!packetsCaught) - cout << savefilename << endl; - else{ - cout << savefilename - << "\tpacket loss " - << setw(4)<GetCurrentFile(); - - if(myFile[ithr]->Write()) - //->Write(tall->GetName(),TObject::kOverwrite); - cout << "Thread " << ithr <<": wrote frames to file" << endl; - else - cout << "Thread " << ithr << ": could not write frames to file" << endl; - - }else - cout << "Thread " << ithr << ": could not write frames to file: No file or No Tree" << endl; - //close file - if(myTree[ithr] && myFile[ithr]) - myFile[ithr] = myTree[ithr]->GetCurrentFile(); - if(myFile[ithr] != NULL) - myFile[ithr]->Close(); - myFile[ithr] = NULL; - myTree[ithr] = NULL; - pthread_mutex_unlock(&write_mutex); - -#endif - } - */ - FILE_LOG(logDEBUG) << __AT__ << "exited"; - -} - - - - - -int UDPBaseImplementation::startReceiver(char message[]){ FILE_LOG(logDEBUG) << __AT__ << " starting"; - int i; - - -// #ifdef VERBOSE - cout << "Starting Receiver" << endl; //#endif - - - //reset listening thread variables - measurementStarted = false; - //should be set to zero as its added to get next start frame indices for scans for eiger - if(!acqStarted) currframenum = 0; - startFrameIndex = 0; - - for(int i = 0; i < numListeningThreads; ++i) - totalListeningFrameCount[i] = 0; - - //udp socket - if(createUDPSockets() == FAIL){ - strcpy(message,"Could not create UDP Socket(s).\n"); - cout << endl << message << endl; - return FAIL; - } - cout << "UDP socket(s) created successfully. 1st port " << server_port[0] << endl; - - - if(setupWriter() == FAIL){ - //stop udp socket - shutDownUDPSockets(); - - sprintf(message,"Could not create file %s.\n",savefilename); - return FAIL; - } - cout << "Successfully created file(s)" << endl; - - //done to give the gui some proper name instead of always the last file name - if(dataCompression) - sprintf(savefilename, "%s/%s_fxxx_%d_xx.root", filePath,fileName,fileIndex); - - //initialize semaphore - sem_init(&smp,1,0); - - //status - pthread_mutex_lock(&status_mutex); - status = RUNNING; - for(i=0;istartListening(); - - return this_pointer; -} - - - -void* UDPBaseImplementation::startWritingThread(void* this_pointer){ FILE_LOG(logDEBUG) << __AT__ << " starting"; - ((UDPBaseImplementation*)this_pointer)->startWriting(); - return this_pointer; -} - - - - - - -int UDPBaseImplementation::startListening(){ FILE_LOG(logDEBUG) << __AT__ << " starting"; - int ithread = currentListeningThreadIndex; -#ifdef VERYVERBOSE - cout << "In startListening() " << endl; -#endif - - thread_started = 1; - - int total; - int lastpacketoffset, expected, rc,packetcount, maxBufferSize, carryonBufferSize; - uint32_t lastframeheader;// for moench to check for all the packets in last frame - char* tempchar = NULL; - int imageheader = 0; - if(myDetectorType==EIGER) - imageheader = EIGER_IMAGE_HEADER_SIZE; - - - while(1){ - //variables that need to be checked/set before each acquisition - carryonBufferSize = 0; - //if more than 1 listening thread, listen one packet at a time, else need to interleaved frame later - maxBufferSize = bufferSize * numJobsPerThread; -#ifdef VERYDEBUG - cout << " maxBufferSize:" << maxBufferSize << ",carryonBufferSize:" << carryonBufferSize << endl; -#endif - - if(tempchar) {delete [] tempchar;tempchar = NULL;} - if(myDetectorType != EIGER) - tempchar = new char[onePacketSize * ((packetsPerFrame/numListeningThreads) - 1)]; //gotthard: 1packet size, moench:39 packet size - - - while((1<pop(buffer[ithread]); -#ifdef VERYDEBUG - cout << ithread << " *** popped from fifo free" << (void*)buffer[ithread] << endl; -#endif - - - //receive - if(udpSocket[ithread] == NULL){ - rc = 0; - cout << ithread << "UDP Socket is NULL" << endl; - } - //normal listening - else if(!carryonBufferSize){ - - rc = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS, maxBufferSize); - expected = maxBufferSize; - - } - //the remaining packets from previous buffer - else{ -#ifdef VERYDEBUG - cout << ithread << " ***carry on buffer" << carryonBufferSize << endl; - cout << ithread << " framennum in temochar:"<<((((uint32_t)(*((uint32_t*)tempchar))) - & (frameIndexMask)) >> frameIndexOffset)<ReceiveDataOnly((buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS + carryonBufferSize),maxBufferSize - carryonBufferSize); - expected = maxBufferSize - carryonBufferSize; - } - -#ifdef VERYDEBUG - cout << ithread << " *** rc:" << dec << rc << ". expected:" << dec << expected << endl; -#endif - - - - - //start indices for each start of scan/acquisition - eiger does it before - if((!measurementStarted) && (rc > 0) && (!ithread)) - startFrameIndices(ithread); - - //problem in receiving or end of acquisition - if((rc < expected)||(rc <= 0)){ - stopListening(ithread,rc,packetcount,total); - continue; - } - - - - //reset - packetcount = (packetsPerFrame/numListeningThreads) * numJobsPerThread; - carryonBufferSize = 0; - - - - //check if last packet valid and calculate packet count - switch(myDetectorType){ - - case MOENCH: - lastpacketoffset = (((numJobsPerThread * packetsPerFrame - 1) * onePacketSize) + HEADER_SIZE_NUM_TOT_PACKETS); -#ifdef VERYDEBUG - cout <<"first packet:"<< ((((uint32_t)(*((uint32_t*)(buffer[ithread]+HEADER_SIZE_NUM_TOT_PACKETS))))) & (packetIndexMask)) << endl; - cout <<"first header:"<< (((((uint32_t)(*((uint32_t*)(buffer[ithread]+HEADER_SIZE_NUM_TOT_PACKETS))))) & (frameIndexMask)) >> frameIndexOffset) << endl; - cout << "last packet offset:" << lastpacketoffset << endl; - cout <<"last packet:"<< ((((uint32_t)(*((uint32_t*)(buffer[ithread]+lastpacketoffset))))) & (packetIndexMask)) << endl; - cout <<"last header:"<< (((((uint32_t)(*((uint32_t*)(buffer[ithread]+lastpacketoffset))))) & (frameIndexMask)) >> frameIndexOffset) << endl; -#endif - //moench last packet value is 0 - if( ((((uint32_t)(*((uint32_t*)(buffer[ithread]+lastpacketoffset))))) & (packetIndexMask))){ - lastframeheader = ((((uint32_t)(*((uint32_t*)(buffer[ithread]+lastpacketoffset))))) & (frameIndexMask)) >> frameIndexOffset; - carryonBufferSize += onePacketSize; - lastpacketoffset -= onePacketSize; - --packetcount; - while (lastframeheader == (((((uint32_t)(*((uint32_t*)(buffer[ithread]+lastpacketoffset))))) & (frameIndexMask)) >> frameIndexOffset)){ - carryonBufferSize += onePacketSize; - lastpacketoffset -= onePacketSize; - --packetcount; - } - memcpy(tempchar, buffer[ithread]+(lastpacketoffset+onePacketSize), carryonBufferSize); -#ifdef VERYDEBUG - cout << "tempchar header:" << (((((uint32_t)(*((uint32_t*)(tempchar))))) - & (frameIndexMask)) >> frameIndexOffset) << endl; - cout <<"tempchar packet:"<< ((((uint32_t)(*((uint32_t*)(tempchar))))) - & (packetIndexMask)) << endl; -#endif - } - break; - - case GOTTHARD: - if(shortFrame == -1){ - lastpacketoffset = (((numJobsPerThread * packetsPerFrame - 1) * onePacketSize) + HEADER_SIZE_NUM_TOT_PACKETS); -#ifdef VERYDEBUG - cout << "last packet offset:" << lastpacketoffset << endl; -#endif - - if((unsigned int)(packetsPerFrame -1) != ((((uint32_t)(*((uint32_t*)(buffer[ithread]+lastpacketoffset))))+1) & (packetIndexMask))){ - memcpy(tempchar,buffer[ithread]+lastpacketoffset, onePacketSize); -#ifdef VERYDEBUG - cout << "tempchar header:" << (((((uint32_t)(*((uint32_t*)(tempchar))))+1) - & (frameIndexMask)) >> frameIndexOffset) << endl; -#endif - carryonBufferSize = onePacketSize; - --packetcount; - } - } -#ifdef VERYDEBUG - cout << "header:" << (((((uint32_t)(*((uint32_t*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS))))+1) - & (frameIndexMask)) >> frameIndexOffset) << endl; -#endif - break; - default: - - break; - - } - - - // cout<<"*********** "<fnum)<push(buffer[ithread])); -#ifdef VERYDEBUG - if(!ithread) cout << ithread << " *** pushed into listening fifo" << endl; -#endif - } - - sem_wait(&listensmp[ithread]); - - //make sure its not exiting thread - if(killAllListeningThreads){ - cout << ithread << " good bye listening thread" << endl; - if(tempchar) {delete [] tempchar;tempchar = NULL;} - pthread_exit(NULL); - } - } - - return OK; -} - - - - - - - - - - - - - -int UDPBaseImplementation::startWriting(){ FILE_LOG(logDEBUG) << __AT__ << " starting"; - - return OK; -} - - - - -void UDPBaseImplementation::startFrameIndices(int ithread){ FILE_LOG(logDEBUG) << __AT__ << " starting"; - - - -} - - - -void UDPBaseImplementation::stopListening(int ithread, int rc, int &pc, int &t){ FILE_LOG(logDEBUG) << __AT__ << " starting"; -int i; - -#ifdef VERYVERBOSE - cerr << ithread << " recvfrom() failed:"<push(buffer[ithread]); - exit(-1); - } - //push the last buffer into fifo - if(rc > 0){ - pc = (rc/onePacketSize); -#ifdef VERYDEBUG - cout << ithread << " *** last packetcount:" << pc << endl; -#endif - (*((uint16_t*)(buffer[ithread]))) = pc; - totalListeningFrameCount[ithread] += pc; - while(!fifo[ithread]->push(buffer[ithread])); -#ifdef VERYDEBUG - cout << ithread << " *** last lbuf1:" << (void*)buffer[ithread] << endl; -#endif - } - - - //push dummy buffer to all writer threads - for(i=0;ipop(buffer[ithread]); - (*((uint16_t*)(buffer[ithread]))) = 0xFFFF; -#ifdef VERYDEBUG - cout << ithread << " going to push in dummy buffer:" << (void*)buffer[ithread] << " with num packets:"<< (*((uint16_t*)(buffer[ithread]))) << endl; -#endif - while(!fifo[ithread]->push(buffer[ithread])); -#ifdef VERYDEBUG - cout << ithread << " pushed in dummy buffer:" << (void*)buffer[ithread] << endl; -#endif - } - - //reset mask and exit loop - pthread_mutex_lock(&status_mutex); - listeningthreads_mask^=(1< 1) - cout << "Waiting for listening to be done.. current mask:" << hex << listeningthreads_mask << endl; -#endif - while(listeningthreads_mask) - usleep(5000); -#ifdef VERYDEBUG - t = 0; - for(i=0;ipush(wbuffer[i])); -#ifdef VERYDEBUG - cout << ithread << ":" << i<< " fifo freed:" << (void*)wbuffer[i] << endl; -#endif - } - - - - //all threads need to close file, reset mask and exit loop - closeFile(ithread); - pthread_mutex_lock(&status_mutex); - writerthreads_mask^=(1<= 0){ - - tengigaEnable = enable; - - if(myDetectorType == EIGER){ - - if(!tengigaEnable){ - packetsPerFrame = EIGER_ONE_GIGA_CONSTANT * dynamicRange * EIGER_MAX_PORTS; - onePacketSize = EIGER_ONE_GIGA_ONE_PACKET_SIZE; - maxPacketsPerFile = EIGER_MAX_FRAMES_PER_FILE * packetsPerFrame; - }else{ - packetsPerFrame = EIGER_TEN_GIGA_CONSTANT * dynamicRange * EIGER_MAX_PORTS; - onePacketSize = EIGER_TEN_GIGA_ONE_PACKET_SIZE; - maxPacketsPerFile = EIGER_MAX_FRAMES_PER_FILE * packetsPerFrame*4; - } - frameSize = onePacketSize * packetsPerFrame; - bufferSize = (frameSize/EIGER_MAX_PORTS) + EIGER_HEADER_LENGTH;//everything one port gets (img header plus packets) - //maxPacketsPerFile = EIGER_MAX_FRAMES_PER_FILE * packetsPerFrame; - - - cout<<"packetsPerFrame:"<*flist[fnum])(); if (ret==FAIL) - cout << "Error executing the function = " << fnum << endl; + cprintf(RED, "Error executing the function = %d\n",fnum); return ret; } @@ -358,7 +358,7 @@ void slsReceiverTCPIPInterface::staticCloseFile(int p){ int slsReceiverTCPIPInterface::set_detector_type(){ ret=OK; - int retval=FAIL; + detectorType retval=GENERIC; detectorType dr; strcpy(mess,"Could not set detector type range\n"); @@ -377,20 +377,35 @@ int slsReceiverTCPIPInterface::set_detector_type(){ ret=FAIL; } else{ - myDetectorType = dr; + + switch(dr){ + case GOTTHARD: + case PROPIX: + case MOENCH: + case EIGER: + case JUNGFRAUCTB: + case JUNGFRAU: + break; + default: + sprintf(mess,"Unknown detector type: %d\n", dr); + ret = FAIL; + break; + if(ret != FAIL){ #ifndef REST - receiverBase = UDPInterface::create("standard"); - receiverBase->setBottom(bottom); + receiverBase = UDPInterface::create("standard"); + receiverBase->setBottomEnable(bottom); #endif - ret=receiverBase->setDetectorType(dr); - retval = myDetectorType; + myDetectorType = dr; + ret=receiverBase->setDetectorType(myDetectorType); + retval = myDetectorType; + } + } } - } //#ifdef VERBOSE if(ret!=FAIL) cout << "detector type" << dr << endl; else - cout << mess << endl; + cprintf(RED, "%s\n", mess); //#endif #endif @@ -417,7 +432,8 @@ int slsReceiverTCPIPInterface::set_detector_type(){ int slsReceiverTCPIPInterface::set_file_name() { ret=OK; - char retval[MAX_STR_LENGTH]=""; + char* retval[MAX_STR_LENGTH] = NULL; + char defaultVal[MAX_STR_LENGTH] = ""; char fName[MAX_STR_LENGTH]; strcpy(mess,"Could not set file name"); @@ -439,8 +455,12 @@ int slsReceiverTCPIPInterface::set_file_name() { strcpy(mess,"Receiver not set up\n"); ret=FAIL; } - else - strcpy(retval,receiverBase->setFileName(fName)); + else{ + receiverBase->setFileName(fName); + retval = receiveBase->getFileName(); + if(retval == NULL) + ret = FAIL; + } } #ifdef VERBOSE if(ret!=FAIL) @@ -457,9 +477,15 @@ int slsReceiverTCPIPInterface::set_file_name() { // send answer socket->SendDataOnly(&ret,sizeof(ret)); - if(ret==FAIL) + if(ret==FAIL){ + cprintf(RED, "%s\n", mess); socket->SendDataOnly(mess,sizeof(mess)); - socket->SendDataOnly(retval,MAX_STR_LENGTH); + socket->SendDataOnly(defaultVal,MAX_STR_LENGTH); + }else + socket->SendDataOnly(retval,MAX_STR_LENGTH); + + //free + if(retval != NULL) delete[] retval; //return ok/fail return ret; @@ -472,7 +498,8 @@ int slsReceiverTCPIPInterface::set_file_name() { int slsReceiverTCPIPInterface::set_file_dir() { ret=OK; - char retval[MAX_STR_LENGTH]=""; + char* retval=NULL; + char defaultVal[MAX_STR_LENGTH] = ""; char fPath[MAX_STR_LENGTH]; strcpy(mess,"Could not set file path\n"); @@ -498,13 +525,12 @@ int slsReceiverTCPIPInterface::set_file_dir() { ret=FAIL; } else{ - strcpy(retval,receiverBase->setFilePath(fPath)); - // if file path doesnt exist - if(strlen(fPath)) - if (strcmp(retval,fPath)){ - strcpy(mess,"receiver file path does not exist\n"); - ret=FAIL; - } + receiverBase->setFilePath(fPath); + retval = receiveBase->getFilePath(); + if(reval == NULL){ + ret = FAIL; + strcpy(mess,"receiver file path does not exist\n"); + } } } @@ -523,9 +549,15 @@ int slsReceiverTCPIPInterface::set_file_dir() { // send answer socket->SendDataOnly(&ret,sizeof(ret)); - if(ret==FAIL) + if(ret==FAIL){ + cprintf(RED, "%s\n", mess); socket->SendDataOnly(mess,sizeof(mess)); - socket->SendDataOnly(retval,MAX_STR_LENGTH); + socket->SendDataOnly(defaultVal,MAX_STR_LENGTH); + }else + socket->SendDataOnly(retval,MAX_STR_LENGTH); + + //free + if(retval != NULL) delete[] retval; //return ok/fail return ret; @@ -560,8 +592,13 @@ int slsReceiverTCPIPInterface::set_file_index() { strcpy(mess,"Receiver not set up\n"); ret=FAIL; } - else - retval=receiverBase->setFileIndex(index); + else{ + if(index >= 0) + receiverBase->setFileIndex(index); + retval=receiverBase->getFileIndex(); + if(index>=0 && retval!=index) + ret = FAIL; + } } #ifdef VERBOSE if(ret!=FAIL) @@ -578,8 +615,10 @@ int slsReceiverTCPIPInterface::set_file_index() { // send answer socket->SendDataOnly(&ret,sizeof(ret)); - if(ret==FAIL) + if(ret==FAIL){ + cprintf(RED, "%s\n", mess); socket->SendDataOnly(mess,sizeof(mess)); + } socket->SendDataOnly(&retval,sizeof(retval)); //return ok/fail @@ -617,8 +656,22 @@ int slsReceiverTCPIPInterface::set_frame_index() { strcpy(mess,"Receiver not set up\n"); ret=FAIL; } - else - retval=receiverBase->setFrameIndexNeeded(index); + else{ + //client sets to 0, but for receiver it is just an enable + //client uses this value for other detectors not using receiver, + //so implement the interface here + + switch(index){ + case -1: index=0; break; + default: index=1; break; //value is 0 + } + receiverBase->setFrameIndexEnable(index); + retval=receiverBase->getFrameIndexEnable(); + switch(retval){ + case 0: retval=-1; break; + case 1: retval=0; break; + } + } } #ifdef VERBOSE if(ret!=FAIL) @@ -635,8 +688,10 @@ int slsReceiverTCPIPInterface::set_frame_index() { // send answer socket->SendDataOnly(&ret,sizeof(ret)); - if(ret==FAIL) + if(ret==FAIL){ + cprintf(RED, "%s\n", mess); socket->SendDataOnly(mess,sizeof(mess)); + } socket->SendDataOnly(&retval,sizeof(retval)); //return ok/fail @@ -652,7 +707,7 @@ int slsReceiverTCPIPInterface::set_frame_index() { int slsReceiverTCPIPInterface::setup_udp(){ ret=OK; strcpy(mess,"could not set up udp connection"); - char retval[MAX_STR_LENGTH]=""; + char retval[MAX_STR_LENGTH] = ""; char args[3][MAX_STR_LENGTH]; string temp; @@ -705,8 +760,8 @@ int slsReceiverTCPIPInterface::setup_udp(){ } FILE_LOG(logDEBUG) << __FILE__ << "::" << __func__ << " " << eth; receiverBase->setEthernetInterface(eth); - cout << eth << endl; + //get mac address from ethernet interface if (ret != FAIL) temp = genericSocket::nameToMac(eth); @@ -715,7 +770,7 @@ int slsReceiverTCPIPInterface::setup_udp(){ if ((temp=="00:00:00:00:00:00") || (ret == FAIL)){ ret = FAIL; strcpy(mess,"failed to get mac adddress to listen to\n"); - cout << "mess:" << mess << endl; + cprintf(RED,"%s\n",mess); } else{ strcpy(retval,temp.c_str()); @@ -733,8 +788,10 @@ int slsReceiverTCPIPInterface::setup_udp(){ // send answer socket->SendDataOnly(&ret,sizeof(ret)); - if(ret==FAIL) + if(ret==FAIL){ + cprintf(RED, "%s\n", mess); socket->SendDataOnly(mess,sizeof(mess)); + } socket->SendDataOnly(retval,MAX_STR_LENGTH); //return ok/fail @@ -749,8 +806,7 @@ int slsReceiverTCPIPInterface::setup_udp(){ int slsReceiverTCPIPInterface::start_receiver(){ ret=OK; ret=OK; - enum runStatus s; - char cstatus[15]; + enum runStatus s = ERROR; strcpy(mess,"Could not start receiver\n"); // execute action if the arguments correctly arrived @@ -771,22 +827,13 @@ int slsReceiverTCPIPInterface::start_receiver(){ } else { s = receiverBase->getStatus(); - switch (s) { - case ERROR: strcpy(cstatus,"error"); break; - case WAITING: strcpy(cstatus,"waiting"); break; - case RUNNING: strcpy(cstatus,"running"); break; - case TRANSMITTING: strcpy(cstatus,"data"); break; - case RUN_FINISHED: strcpy(cstatus,"finished"); break; - default: strcpy(cstatus,"idle"); break; - } if(s == IDLE) ret=receiverBase->startReceiver(mess); else{ - sprintf(mess,"Cannot start Receiver as it is in %s state\n",cstatus); + sprintf(mess,"Cannot start Receiver as it is in %s state\n",slsDetectorBase::runStatusType(s).c_str()); ret=FAIL; } } - #endif if(ret==OK && socket->differentClients){ @@ -797,6 +844,7 @@ int slsReceiverTCPIPInterface::start_receiver(){ // send answer socket->SendDataOnly(&ret,sizeof(ret)); if(ret==FAIL){ + cprintf(RED, "%s\n", mess); socket->SendDataOnly(mess,sizeof(mess)); } //return ok/fail @@ -808,7 +856,7 @@ int slsReceiverTCPIPInterface::start_receiver(){ int slsReceiverTCPIPInterface::stop_receiver(){ ret=OK; - + enum runStatus s = ERROR; strcpy(mess,"Could not stop receiver\n"); // execute action if the arguments correctly arrived @@ -821,8 +869,17 @@ int slsReceiverTCPIPInterface::stop_receiver(){ strcpy(mess,"Receiver not set up\n"); ret=FAIL; } - else if(receiverBase->getStatus()!=IDLE) - ret=receiverBase->stopReceiver(); + else{ + if(receiverBase->getStatus()!=IDLE) + receiverBase->stopReceiver(); + s = receiverBase->getStatus(); + if(s==IDLE) + ret = OK; + else{ + sprintf(mess,"Could not stop receiver. It is in %s state\n",slsDetectorBase::runStatusType(s).c_str()); + ret = FAIL; + } + } #endif if(ret==OK && socket->differentClients){ @@ -832,8 +889,10 @@ int slsReceiverTCPIPInterface::stop_receiver(){ // send answer socket->SendDataOnly(&ret,sizeof(ret)); - if(ret==FAIL) + if(ret==FAIL){ + cprintf(RED, "%s\n", mess); socket->SendDataOnly(mess,sizeof(mess)); + } //return ok/fail return ret; @@ -860,8 +919,10 @@ int slsReceiverTCPIPInterface::get_status(){ // send answer socket->SendDataOnly(&ret,sizeof(ret)); - if(ret==FAIL) + if(ret==FAIL){ + cprintf(RED, "%s\n", mess); socket->SendDataOnly(mess,sizeof(mess)); + } socket->SendDataOnly(&retval,sizeof(retval)); //return ok/fail return ret; @@ -888,8 +949,10 @@ int slsReceiverTCPIPInterface::get_frames_caught(){ // send answer socket->SendDataOnly(&ret,sizeof(ret)); - if(ret==FAIL) + if(ret==FAIL){ + cprintf(RED, "%s\n", mess); socket->SendDataOnly(mess,sizeof(mess)); + } socket->SendDataOnly(&retval,sizeof(retval)); //return ok/fail return ret; @@ -918,8 +981,10 @@ int slsReceiverTCPIPInterface::get_frame_index(){ // send answer socket->SendDataOnly(&ret,sizeof(ret)); - if(ret==FAIL) + if(ret==FAIL){ + cprintf(RED, "%s\n", mess); socket->SendDataOnly(mess,sizeof(mess)); + } socket->SendDataOnly(&retval,sizeof(retval)); //return ok/fail return ret; @@ -946,7 +1011,7 @@ int slsReceiverTCPIPInterface::reset_frames_caught(){ ret=FAIL; } else - receiverBase->resetTotalFramesCaught(); + receiverBase->resetAcquisitionCount(); } #endif @@ -957,9 +1022,10 @@ int slsReceiverTCPIPInterface::reset_frames_caught(){ // send answer socket->SendDataOnly(&ret,sizeof(ret)); - if(ret==FAIL) + if(ret==FAIL){ + cprintf(RED, "%s\n", mess); socket->SendDataOnly(mess,sizeof(mess)); - + } //return ok/fail return ret; @@ -1006,7 +1072,8 @@ int slsReceiverTCPIPInterface::set_short_frame() { ret=FAIL; } else{ - retval=receiverBase->setShortFrame(index); + receiverBase->setShortFrameEnable(index); + retval = receiverBase->getShortFrameEnable(); shortFrame = retval; if(shortFrame==-1) packetsPerFrame=GOTTHARD_PACKETS_PER_FRAME; @@ -1023,8 +1090,10 @@ int slsReceiverTCPIPInterface::set_short_frame() { // send answer socket->SendDataOnly(&ret,sizeof(ret)); - if(ret==FAIL) + if(ret==FAIL){ + cprintf(RED, "%s\n", mess); socket->SendDataOnly(mess,sizeof(mess)); + } socket->SendDataOnly(&retval,sizeof(retval)); //return ok/fail @@ -1088,7 +1157,6 @@ int slsReceiverTCPIPInterface::moench_read_frame(){ else{ ret = OK; - /*startIndex=receiverBase->getStartFrameIndex();*/ receiverBase->readFrame(fName,&raw,startAcquisitionIndex,startFrameIndex); /**send garbage with -1 index to try again*/ @@ -1203,7 +1271,7 @@ int slsReceiverTCPIPInterface::moench_read_frame(){ // send answer socket->SendDataOnly(&ret,sizeof(ret)); if(ret==FAIL){ - cout << "mess:" << mess << endl; + cprintf(RED,"%s\n",mess); socket->SendDataOnly(mess,sizeof(mess)); } else{ @@ -1277,7 +1345,6 @@ int slsReceiverTCPIPInterface::gotthard_read_frame(){ cout<<"haven't caught any frame yet"<getStartFrameIndex();*/ receiverBase->readFrame(fName,&raw,startAcquisitionIndex,startFrameIndex); /**send garbage with -1 index to try again*/ @@ -1385,7 +1452,7 @@ int slsReceiverTCPIPInterface::gotthard_read_frame(){ // send answer socket->SendDataOnly(&ret,sizeof(ret)); if(ret==FAIL){ - cout << "mess:" << mess << endl; + cprintf(RED,"%s\n",mess); socket->SendDataOnly(mess,sizeof(mess)); } else{ @@ -1453,7 +1520,6 @@ int slsReceiverTCPIPInterface::propix_read_frame(){ cout<<"haven't caught any frame yet"<getStartFrameIndex();*/ receiverBase->readFrame(fName,&raw,startAcquisitionIndex,startFrameIndex); /**send garbage with -1 index to try again*/ @@ -1540,7 +1606,7 @@ int slsReceiverTCPIPInterface::propix_read_frame(){ // send answer socket->SendDataOnly(&ret,sizeof(ret)); if(ret==FAIL){ - cout << "mess:" << mess << endl; + cprintf(RED,"%s\n",mess); socket->SendDataOnly(mess,sizeof(mess)); } else{ @@ -1802,7 +1868,7 @@ int slsReceiverTCPIPInterface::eiger_read_frame(){ // send answer socket->SendDataOnly(&ret,sizeof(ret)); if(ret==FAIL){ - cout << "mess:" << mess << endl; + cprintf(RED,"%s\n",mess); socket->SendDataOnly(mess,sizeof(mess)); } else{ @@ -1855,8 +1921,13 @@ int slsReceiverTCPIPInterface::set_read_frequency(){ ret = FAIL; strcpy(mess,"cannot set up receiver mode when receiver is running\n"); }*/ - else - retval=receiverBase->setNFrameToGui(index); + else{ + if(index >= 0) + receiverBase->setFrameToGuiFrequency(index); + retval=receiverBase->getFrameToGuiFrequency(); + if(index>=0 && retval!=index) + ret = FAIL; + } } #endif @@ -1868,8 +1939,10 @@ int slsReceiverTCPIPInterface::set_read_frequency(){ // send answer socket->SendDataOnly(&ret,sizeof(ret)); - if(ret==FAIL) + if(ret==FAIL){ + cprintf(RED,"%s\n",mess); socket->SendDataOnly(mess,sizeof(mess)); + } socket->SendDataOnly(&retval,sizeof(retval)); //return ok/fail @@ -1907,9 +1980,9 @@ int slsReceiverTCPIPInterface::enable_file_write(){ } else{ if(enable >= 0) - receiverBase->setEnableFileWrite(enable); - retval=receiverBase->getEnableFileWrite(); - if((enable!=-1)&&(enable!=retval)) + receiverBase->setFileWriteEnable(enable); + retval=receiverBase->getFileWriteEnable(); + if(enable>=0 && enable!=retval) ret=FAIL; } } @@ -1922,8 +1995,10 @@ int slsReceiverTCPIPInterface::enable_file_write(){ // send answer socket->SendDataOnly(&ret,sizeof(ret)); - if(ret==FAIL) + if(ret==FAIL){ + cprintf(RED,"%s\n",mess); socket->SendDataOnly(mess,sizeof(mess)); + } socket->SendDataOnly(&retval,sizeof(retval)); //return ok/fail @@ -1991,8 +2066,10 @@ int slsReceiverTCPIPInterface::start_readout(){ // send answer socket->SendDataOnly(&ret,sizeof(ret)); - if(ret==FAIL) + if(ret==FAIL){ + cprintf(RED,"%s\n",mess); socket->SendDataOnly(mess,sizeof(mess)); + } socket->SendDataOnly(&retval,sizeof(retval)); //return ok/fail return ret; @@ -2029,10 +2106,17 @@ int slsReceiverTCPIPInterface::set_timer() { ret=FAIL; } else{ - if(index[0] == slsReceiverDefs::FRAME_PERIOD) - retval=receiverBase->setAcquisitionPeriod(index[1]); - else - retval=receiverBase->setNumberOfFrames(index[1]); + if(index[0] == slsReceiverDefs::FRAME_PERIOD){ + if(index[1]>=0) + receiverBase->setAcquisitionPeriod(index[1]); + retval=receiverBase->getAcquisitionPeriod(); + }else{ + if(index[1]>=0) + receiverBase->setNumberOfFrames(index[1]); + retval=receiverBase->getNumberOfFrames(); + } + if(index[1]>=0 && retval!=index[1]) + ret = FAIL; } } #ifdef VERBOSE @@ -2053,8 +2137,10 @@ int slsReceiverTCPIPInterface::set_timer() { // send answer socket->SendDataOnly(&ret,sizeof(ret)); - if(ret==FAIL) + if(ret==FAIL){ + cprintf(RED,"%s\n",mess); socket->SendDataOnly(mess,sizeof(mess)); + } socket->SendDataOnly(&retval,sizeof(retval)); //return ok/fail @@ -2095,15 +2181,21 @@ int slsReceiverTCPIPInterface::enable_compression() { strcpy(mess,"Cannot enable/disable compression while status is running\n"); ret=FAIL; } - else - ret = receiverBase->enableDataCompression(enable); + else{ + if(enable >= 0) + receiverBase->setDataCompressionEnable(enable); + } } if (receiverBase == NULL){ strcpy(mess,"Receiver not set up\n"); ret=FAIL; - }else - retval=receiverBase->getDataCompression(); + }else{ + retval = receiverBase->getDataCompressionEnable(); + if(enable >= 0 && retval != enable) + ret = FAIL; + } + } #endif @@ -2114,8 +2206,10 @@ int slsReceiverTCPIPInterface::enable_compression() { // send answer socket->SendDataOnly(&ret,sizeof(ret)); - if(ret==FAIL) + if(ret==FAIL){ + cprintf(RED,"%s\n",mess); socket->SendDataOnly(mess,sizeof(mess)); + } socket->SendDataOnly(&retval,sizeof(retval)); //return ok/fail @@ -2127,7 +2221,8 @@ int slsReceiverTCPIPInterface::enable_compression() { int slsReceiverTCPIPInterface::set_detector_hostname() { ret=OK; - char retval[MAX_STR_LENGTH]=""; + char* retval = NULL; + char defaultVal[MAX_STR_LENGTH] = ""; char hostname[MAX_STR_LENGTH]=""; strcpy(mess,"Could not set detector hostname"); @@ -2151,7 +2246,10 @@ int slsReceiverTCPIPInterface::set_detector_hostname() { } else{ receiverBase->initialize(hostname); - strcpy(retval,receiverBase->getDetectorHostname()); + retval = receiverBase->getDetectorHostname(); + if(retval == NULL){ + ret = FAIL; + } } } #ifdef VERBOSE @@ -2169,9 +2267,14 @@ int slsReceiverTCPIPInterface::set_detector_hostname() { // send answer socket->SendDataOnly(&ret,sizeof(ret)); - if(ret==FAIL) + if(ret==FAIL){ + cprintf(RED,"%s\n",mess); socket->SendDataOnly(mess,sizeof(mess)); - socket->SendDataOnly(retval,MAX_STR_LENGTH); + socket->SendDataOnly(defaultVal,MAX_STR_LENGTH); + }else socket->SendDataOnly(retval,MAX_STR_LENGTH); + + //free + if(retval!=NULL) delete[] retval; //return ok/fail return ret; @@ -2203,14 +2306,14 @@ int slsReceiverTCPIPInterface::set_dynamic_range() { sprintf(mess,"Receiver locked by %s\n", socket->lastClientIP); ret=FAIL; } - else if ((dr>0) && (myDetectorType == EIGER)){ + else if (dr>0) { switch(dr){ case 4: case 8: case 16: case 32:break; default: - sprintf(mess,"This dynamic range does not exist for eiger: %d\n",dr); + sprintf(mess,"This dynamic range does not exist: %d\n",dr); cprintf(RED,"%s", mess); ret=FAIL; break; @@ -2221,14 +2324,19 @@ int slsReceiverTCPIPInterface::set_dynamic_range() { strcpy(mess,"Receiver not set up\n"); ret=FAIL; }else{ - if(dr > 0) receiverBase->setDynamicRange(dr); + if(dr > 0) + receiverBase->setDynamicRange(dr); retval = receiverBase->getDynamicRange(); - dynamicrange = retval; - if(myDetectorType == EIGER){ - if(!tenGigaEnable) - packetsPerFrame = EIGER_ONE_GIGA_CONSTANT * dynamicrange * EIGER_MAX_PORTS; - else - packetsPerFrame = EIGER_TEN_GIGA_CONSTANT * dynamicrange * EIGER_MAX_PORTS; + if(dr > 0 && retval != dr) + ret = FAIL; + else{ + dynamicrange = retval; + if(myDetectorType == EIGER){ + if(!tenGigaEnable) + packetsPerFrame = EIGER_ONE_GIGA_CONSTANT * dynamicrange * EIGER_MAX_PORTS; + else + packetsPerFrame = EIGER_TEN_GIGA_CONSTANT * dynamicrange * EIGER_MAX_PORTS; + } } } } @@ -2248,8 +2356,10 @@ int slsReceiverTCPIPInterface::set_dynamic_range() { // send answer socket->SendDataOnly(&ret,sizeof(ret)); - if(ret==FAIL) + if(ret==FAIL){ + cprintf(RED,"%s\n",mess); socket->SendDataOnly(mess,sizeof(mess)); + } socket->SendDataOnly(&retval,sizeof(retval)); //return ok/fail @@ -2288,8 +2398,10 @@ int slsReceiverTCPIPInterface::enable_overwrite() { } else{ if(index >= 0) - receiverBase->setEnableOverwrite(index); - retval=receiverBase->getEnableOverwrite(); + receiverBase->setOverwriteEnable(index); + retval=receiverBase->getOverwriteEnable(); + if(index >=0 && retval != index) + ret = FAIL; } } #ifdef VERBOSE @@ -2307,8 +2419,10 @@ int slsReceiverTCPIPInterface::enable_overwrite() { // send answer socket->SendDataOnly(&ret,sizeof(ret)); - if(ret==FAIL) + if(ret==FAIL){ + cprintf(RED,"%s\n",mess); socket->SendDataOnly(mess,sizeof(mess)); + } socket->SendDataOnly(&retval,sizeof(retval)); //return ok/fail @@ -2346,8 +2460,10 @@ int slsReceiverTCPIPInterface::enable_tengiga() { ret=FAIL; } else{ - retval=receiverBase->enableTenGiga(val); - if((val!=-1) && (val != retval)) + if(val >= 0) + receiverBase->setDataCompressionEnable(val); + retval=receiverBase->getDataCompressionEnable(); + if((val >= 0) && (val != retval)) ret = FAIL; else tenGigaEnable = retval; @@ -2368,8 +2484,10 @@ int slsReceiverTCPIPInterface::enable_tengiga() { // send answer socket->SendDataOnly(&ret,sizeof(ret)); - if(ret==FAIL) + if(ret==FAIL){ + cprintf(RED,"%s\n",mess); socket->SendDataOnly(mess,sizeof(mess)); + } socket->SendDataOnly(&retval,sizeof(retval)); //return ok/fail @@ -2436,8 +2554,10 @@ int slsReceiverTCPIPInterface::lock_receiver() { // send answer socket->SendDataOnly(&ret,sizeof(ret)); - if (ret==FAIL) + if(ret==FAIL){ + cprintf(RED,"%s\n",mess); socket->SendDataOnly(mess,sizeof(mess)); + } else socket->SendDataOnly(&lockStatus,sizeof(lockStatus)); @@ -2509,9 +2629,10 @@ int slsReceiverTCPIPInterface::set_port() { // send answer socket->SendDataOnly(&ret,sizeof(ret)); - if (ret==FAIL) { + if(ret==FAIL){ + cprintf(RED,"%s\n",mess); socket->SendDataOnly(mess,sizeof(mess)); - } else { + }else { socket->SendDataOnly(&p_number,sizeof(p_number)); if(sd>=0){ socket->Disconnect(); @@ -2550,7 +2671,8 @@ int slsReceiverTCPIPInterface::get_last_client_ip() { int slsReceiverTCPIPInterface::send_update() { ret=OK; int ind; - char path[MAX_STR_LENGTH]; + char defaultVal[MAX_STR_LENGTH]=""; + char* path = NULL; socket->SendDataOnly(socket->lastClientIP,sizeof(socket->lastClientIP)); @@ -2564,17 +2686,26 @@ int slsReceiverTCPIPInterface::send_update() { //filepath #ifdef SLS_RECEIVER_UDP_FUNCTIONS - strcpy(path,receiverBase->getFilePath()); + path = receiverBase->getFilePath(); #endif - socket->SendDataOnly(path,MAX_STR_LENGTH); + if(path == NULL) + socket->SendDataOnly(defaultVal,MAX_STR_LENGTH); + else{ + socket->SendDataOnly(path,MAX_STR_LENGTH); + delete[] path; + } //filename #ifdef SLS_RECEIVER_UDP_FUNCTIONS - strcpy(path,receiverBase->getFileName()); + path = receiverBase->getFileName(); #endif - socket->SendDataOnly(path,MAX_STR_LENGTH); - + if(path == NULL) + socket->SendDataOnly(defaultVal,MAX_STR_LENGTH); + else{ + socket->SendDataOnly(path,MAX_STR_LENGTH); + delete[] path; + } if (lockStatus==0) { strcpy(socket->lastClientIP,socket->thisClientIP); @@ -2597,7 +2728,8 @@ int slsReceiverTCPIPInterface::update_client() { ret=FAIL; } socket->SendDataOnly(&ret,sizeof(ret)); - if(ret == FAIL){ + if(ret==FAIL){ + cprintf(RED,"%s\n",mess); socket->SendDataOnly(mess,sizeof(mess)); return ret; } @@ -2616,7 +2748,7 @@ int slsReceiverTCPIPInterface::exit_server() { socket->SendDataOnly(&ret,sizeof(ret)); strcpy(mess,"closing server"); socket->SendDataOnly(mess,sizeof(mess)); - cout << mess << endl; + cprintf(RED,"%s\n",mess); return ret; } From 9148f6365ece80e42b83ed66f130686af13883cf Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Fri, 2 Oct 2015 12:05:16 +0200 Subject: [PATCH 147/474] changed last packet value literal to expression, not big in functionality --- .../src/UDPStandardImplementation.cpp | 24 ++----------------- 1 file changed, 2 insertions(+), 22 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 609f4fea7..84a5fedba 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1970,19 +1970,6 @@ int UDPStandardImplementation::startWriting(){ eiger_packet_header_t* blankframe_header=0; unsigned char* blankframe_data=0; - //last packet numbers for different dynamic ranges - if(myDetectorType == EIGER){ - switch(dynamicRange){ - case 4: LAST_PACKET_VALUE = 0x40; break; - case 8: LAST_PACKET_VALUE = 0x80; break; - case 16: LAST_PACKET_VALUE = 0x100; break; - case 32: LAST_PACKET_VALUE = 0x200; break; - default: break; - } - - } - - while(1){ @@ -2030,15 +2017,8 @@ int UDPStandardImplementation::startWriting(){ #endif } - if(tengigaEnable){ - switch(dynamicRange){ - case 4: LAST_PACKET_VALUE = 0x10; break; - case 8: LAST_PACKET_VALUE = 0x20; break; - case 16: LAST_PACKET_VALUE = 0x40; break; - case 32: LAST_PACKET_VALUE = 0x80; break; - default: break; - } - } + //last packet numbers for different dynamic ranges + LAST_PACKET_VALUE = (packetsPerFrame/numListeningThreads); } From a3e88f96d6d1cfd2ad050006dc632c88437c8715 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Thu, 8 Oct 2015 12:19:07 +0200 Subject: [PATCH 148/474] some more changes --- .../include/UDPBaseImplementation.h | 67 +- slsReceiverSoftware/include/UDPInterface.h | 30 +- .../include/UDPStandardImplementation.h | 694 ++++--- slsReceiverSoftware/include/receiver_defs.h | 8 +- slsReceiverSoftware/include/slsReceiver.h | 1 - .../include/sls_receiver_defs.h | 10 + .../src/UDPBaseImplementation.cpp | 91 +- slsReceiverSoftware/src/UDPInterface.cpp | 4 +- .../src/UDPStandardImplementation.cpp | 1838 ++++++++--------- .../src/slsReceiverTCPIPInterface.cpp | 43 +- 10 files changed, 1436 insertions(+), 1350 deletions(-) diff --git a/slsReceiverSoftware/include/UDPBaseImplementation.h b/slsReceiverSoftware/include/UDPBaseImplementation.h index 29d9dd009..293ac6763 100644 --- a/slsReceiverSoftware/include/UDPBaseImplementation.h +++ b/slsReceiverSoftware/include/UDPBaseImplementation.h @@ -7,13 +7,12 @@ ***********************************************/ -#include "sls_receiver_defs.h" +//#include "sls_receiver_defs.h" #include "UDPInterface.h" -#include -#include +//#include /** - * @short does all the functions for a receiver, set/get parameters, start/stop etc. + * @short does all the base functions for a receiver, set/get parameters, start/stop etc. */ class UDPBaseImplementation : protected virtual slsReceiverDefs, public UDPInterface { @@ -123,13 +122,13 @@ class UDPBaseImplementation : protected virtual slsReceiverDefs, public UDPInter * Get UDP Port Number * @return udp port number */ - uint32_t getUDPPortNo() const; + uint32_t getUDPPortNumber() const; /** * Get Second UDP Port Number (eiger specific) * @return second udp port number */ - uint32_t getUDPPortNo2() const; + uint32_t getUDPPortNumber2() const; /** * Get Ehernet Interface @@ -254,9 +253,9 @@ class UDPBaseImplementation : protected virtual slsReceiverDefs, public UDPInter /** * Set data compression, by saving only hits (so far implemented only for Moench and Gotthard) * @param b true for data compression enable, else false + * @return OK or FAIL */ - void setDataCompressionEnable(const bool b); - + int setDataCompressionEnable(const bool b); //***connection parameters*** @@ -264,13 +263,13 @@ class UDPBaseImplementation : protected virtual slsReceiverDefs, public UDPInter * Set UDP Port Number * @param i udp port number */ - void setUDPPortNo(const uint32_t i); + void setUDPPortNumber(const uint32_t i); /** * Set Second UDP Port Number (eiger specific) * @return second udp port number */ - void setUDPPortNo2(const uint32_t i); + void setUDPPortNumber2(const uint32_t i); /** * Set Ethernet Interface to listen to @@ -279,7 +278,7 @@ class UDPBaseImplementation : protected virtual slsReceiverDefs, public UDPInter void setEthernetInterface(const char* c); - //***connection parameters*** + //***acquisition parameters*** /** * Set Short Frame Enabled, later will be moved to getROI (so far only for gotthard) * @param i index of adc enabled, else -1 if all enabled @@ -289,14 +288,16 @@ class UDPBaseImplementation : protected virtual slsReceiverDefs, public UDPInter /** * Set the Frequency of Frames Sent to GUI * @param i 0 for random frame requests, n for nth frame frequency + * @return OK or FAIL */ - void setFrameToGuiFrequency(const uint32_t i); + int setFrameToGuiFrequency(const uint32_t i); /** * Set Acquisition Period * @param i acquisition period + * @return OK or FAIL */ - void setAcquisitionPeriod(const uint64_t i); + int setAcquisitionPeriod(const uint64_t i); /** * Set Number of Frames expected by receiver from detector @@ -308,15 +309,16 @@ class UDPBaseImplementation : protected virtual slsReceiverDefs, public UDPInter /** * Set Dynamic Range or Number of Bits Per Pixel * @param i dynamic range that is 4, 8, 16 or 32 + * @return OK or FAIL */ - void setDynamicRange(const uint32_t i); + int setDynamicRange(const uint32_t i); /** * Set Ten Giga Enable * @param b true if 10Giga enabled, else false (1G enabled) + * @return OK or FAIL */ - void setTenGigaEnable(const bool b); - + int setTenGigaEnable(const bool b); /************************************************************************* @@ -324,6 +326,7 @@ class UDPBaseImplementation : protected virtual slsReceiverDefs, public UDPInter * They may modify the status of the receiver **************************** *************************************************************************/ + //***initial functions*** /** * Set receiver type (and corresponding detector variables in derived STANDARD class) @@ -387,7 +390,7 @@ class UDPBaseImplementation : protected virtual slsReceiverDefs, public UDPInter * abort acquisition with minimum damage: close open files, cleanup. * does nothing if state already is 'idle' */ - void abort(); //FIXME: needed, isnt stopReceiver enough? + void abort(); //FIXME: needed, isn't stopReceiver enough? /** * Closes all files @@ -436,36 +439,12 @@ class UDPBaseImplementation : protected virtual slsReceiverDefs, public UDPInter protected: //**detector parameters*** - /** - * structure of an eiger packet header - * subframenum subframe number for 32 bit mode (already written by firmware) - * missingpacket explicitly put to 0xFF to recognize it in file read (written by software) - * portnum 0 for the first port and 1 for the second port (written by software to file) - * dynamicrange dynamic range or bits per pixel (written by software to file) - */ - typedef struct { - unsigned char subframenum[4]; - unsigned char missingpacket[2]; - unsigned char portnum[1]; - unsigned char dynamicrange[1]; - } eiger_packet_header_t; - /** - * structure of an eiger packet footer - * framenum 48 bit frame number (already written by firmware) - * packetnum packet number (already written by firmware) - */ - typedef struct { - unsigned char framenum[6]; - unsigned char packetnum[2]; - } eiger_packet_footer_t; - - /** detector type */ detectorType myDetectorType; /** detector hostname */ char detHostname[MAX_STR_LENGTH]; /** Number of Packets per Frame*/ - uint64_t packetsPerFrame; + uint32_t packetsPerFrame; /** Acquisition Period */ int64_t acquisitionPeriod; /** Frame Number */ @@ -479,7 +458,7 @@ class UDPBaseImplementation : protected virtual slsReceiverDefs, public UDPInter //***receiver parameters*** /** Maximum Number of Listening Threads/ UDP Ports */ - const static int MAX_NUM_LISTENING_THREADS = 2; + const static int MAX_NUMBER_OF_LISTENING_THREADS = 2; /** Receiver Status */ runStatus status; @@ -487,7 +466,7 @@ class UDPBaseImplementation : protected virtual slsReceiverDefs, public UDPInter /** Ethernet Interface */ char eth[MAX_STR_LENGTH]; /** Server UDP Port Number*/ - uint32_t udpPortNum[MAX_NUM_LISTENING_THREADS]; + uint32_t udpPortNum[MAX_NUMBER_OF_LISTENING_THREADS]; //***file parameters*** /** File Name without frame index, file index and extension (_d0_f000000000000_8.raw)*/ diff --git a/slsReceiverSoftware/include/UDPInterface.h b/slsReceiverSoftware/include/UDPInterface.h index 2e89b59be..65c275a29 100644 --- a/slsReceiverSoftware/include/UDPInterface.h +++ b/slsReceiverSoftware/include/UDPInterface.h @@ -17,8 +17,6 @@ #include "sls_receiver_defs.h" #include "receiver_defs.h" -#include "MySocketTCP.h" - #include "utilities.h" #include "logger.h" @@ -184,13 +182,13 @@ class UDPInterface { * Get UDP Port Number * @return udp port number */ - virtual uint32_t getUDPPortNo() const = 0; + virtual uint32_t getUDPPortNumber() const = 0; /** * Get Second UDP Port Number (eiger specific) * @return second udp port number */ - virtual uint32_t getUDPPortNo2() const = 0; + virtual uint32_t getUDPPortNumber2() const = 0; /** * Get Ehernet Interface @@ -314,22 +312,22 @@ class UDPInterface { /** * Set data compression, by saving only hits (so far implemented only for Moench and Gotthard) * @param b true for data compression enable, else false + * @return OK or FAIL */ - virtual void setDataCompressionEnable(const bool b) = 0; - + virtual int setDataCompressionEnable(const bool b) = 0; //***connection parameters*** /** * Set UDP Port Number * @param i udp port number */ - virtual void setUDPPortNo(const uint32_t i) = 0; + virtual void setUDPPortNumber(const uint32_t i) = 0; /** * Set Second UDP Port Number (eiger specific) * @return second udp port number */ - virtual void setUDPPortNo2(const uint32_t i) = 0; + virtual void setUDPPortNumber2(const uint32_t i) = 0; /** * Set Ethernet Interface to listen to @@ -338,7 +336,7 @@ class UDPInterface { virtual void setEthernetInterface(const char* c) = 0; - //***connection parameters*** + //***acquisition parameters*** /** * Set Short Frame Enabled, later will be moved to getROI (so far only for gotthard) * @param i index of adc enabled, else -1 if all enabled @@ -348,14 +346,16 @@ class UDPInterface { /** * Set the Frequency of Frames Sent to GUI * @param i 0 for random frame requests, n for nth frame frequency + * @return OK or FAIL */ - virtual void setFrameToGuiFrequency(const uint32_t i) = 0; + virtual int setFrameToGuiFrequency(const uint32_t i) = 0; /** * Set Acquisition Period * @param i acquisition period + * @return OK or FAIL */ - virtual void setAcquisitionPeriod(const uint64_t i) = 0; + virtual int setAcquisitionPeriod(const uint64_t i) = 0; /** * Set Number of Frames expected by receiver from detector @@ -367,15 +367,16 @@ class UDPInterface { /** * Set Dynamic Range or Number of Bits Per Pixel * @param i dynamic range that is 4, 8, 16 or 32 + * @return OK or FAIL */ - virtual void setDynamicRange(const uint32_t i) = 0; + virtual int setDynamicRange(const uint32_t i) = 0; /** * Set Ten Giga Enable * @param b true if 10Giga enabled, else false (1G enabled) + * @return OK or FAIL */ - virtual void setTenGigaEnable(const bool b) = 0; - + virtual int setTenGigaEnable(const bool b) = 0; /************************************************************************* @@ -383,6 +384,7 @@ class UDPInterface { * They may modify the status of the receiver **************************** *************************************************************************/ + //***initial functions*** /** * Set receiver type (and corresponding detector variables in derived STANDARD class) diff --git a/slsReceiverSoftware/include/UDPStandardImplementation.h b/slsReceiverSoftware/include/UDPStandardImplementation.h index 04bd7000e..747eaad34 100644 --- a/slsReceiverSoftware/include/UDPStandardImplementation.h +++ b/slsReceiverSoftware/include/UDPStandardImplementation.h @@ -6,25 +6,22 @@ * @short does all the functions for a receiver, set/get parameters, start/stop etc. ***********************************************/ +#include "UDPBaseImplementation.h" -#include "sls_receiver_defs.h" -#include "receiver_defs.h" +//#include "sls_receiver_defs.h" +//#include "receiver_defs.h" #include "genericSocket.h" #include "circularFifo.h" #include "singlePhotonDetector.h" #include "slsReceiverData.h" #include "moenchCommonMode.h" -//#include "UDPInterface.h" -#include "UDPBaseImplementation.h" #ifdef MYROOT1 #include #include #endif - - #include #include #include @@ -38,7 +35,13 @@ class UDPStandardImplementation: private virtual slsReceiverDefs, public UDPBaseImplementation { public: - /** + + + /************************************************************************* + * Constructor & Destructor ********************************************** + * They access local cache of configuration or detector parameters ******* + *************************************************************************/ + /** * Constructor */ UDPStandardImplementation(); @@ -48,17 +51,382 @@ class UDPStandardImplementation: private virtual slsReceiverDefs, public UDPBase */ virtual ~UDPStandardImplementation(); + + /************************************************************************* + * Getters *************************************************************** + * They access local cache of configuration or detector parameters ******* + *************************************************************************/ + + //***acquisition count parameters*** + + + /************************************************************************* + * Setters *************************************************************** + * They modify the local cache of configuration or detector parameters *** + *************************************************************************/ + + //**initial parameters*** + + /** + * Overridden method + * Configure command line parameters + * @param config_map mapping of config parameters passed from command line arguments + */ void configure(map config_map); + //*** file parameters*** /** - * delete and free member parameters + * Overridden method + * Set data compression, by saving only hits (so far implemented only for Moench and Gotthard) + * @param b true for data compression enable, else false */ - void deleteMembers(); + void setDataCompressionEnable(const bool b); + + //***acquisition parameters*** + /** + * Overridden method + * Set Short Frame Enabled, later will be moved to getROI (so far only for gotthard) + * @param i index of adc enabled, else -1 if all enabled + */ + void setShortFrameEnable(const int i); /** - * initialize member parameters + * Overridden method + * Set the Frequency of Frames Sent to GUI + * @param i 0 for random frame requests, n for nth frame frequency + * @return OK or FAIL + */ + int setFrameToGuiFrequency(const uint32_t i); + + /** + * Overridden method + * Set Acquisition Period + * @param i acquisition period + * @return OK or FAIL + */ + int setAcquisitionPeriod(const uint64_t i); + + /** + * Overridden method + * Set Dynamic Range or Number of Bits Per Pixel + * @param i dynamic range that is 4, 8, 16 or 32 + * @return OK or FAIL + */ + int setDynamicRange(const uint32_t i); + + /** + * Overridden method + * Set Ten Giga Enable + * @param b true if 10Giga enabled, else false (1G enabled) + * @return OK or FAIL + */ + int setTenGigaEnable(const bool b); + + + + /************************************************************************* + * Behavioral functions*************************************************** + * They may modify the status of the receiver **************************** + *************************************************************************/ + + //***initial functions*** + /** + * Overridden method + * Set receiver type (and corresponding detector variables in derived STANDARD class) + * It is the first function called by the client when connecting to receiver + * @param d detector type + * @return OK or FAIL + */ + int setDetectorType(const slsReceiverDefs::detectorType d); + + //***acquisition functions*** + /** + * Overridden method + * Reset acquisition parameters such as total frames caught for an entire acquisition (including all scans) + */ + void resetAcquisitionCount(); + + /** + * Overridden method + * Start Listening for Packets by activating all configuration settings to receiver + * @param c error message if FAIL + * @return OK or FAIL + */ + int startReceiver(char *c=NULL); + + + +private: + + /************************************************************************* + * Setters *************************************************************** + * They modify the local cache of configuration or detector parameters *** + *************************************************************************/ + //**initial parameters*** + + /** + * Delete and free base member parameters + */ + void deleteBaseMembers(); + + /** + * Delete and free member parameters + */ + void deleteMembers(); + + /** + * Deletes all the filter objects for single photon data + * Deals with data compression + */ + void deleteFilter(); + + /** + * Initialize base member parameters + */ + void initializeBaseMembers(); + + /** + * Initialize member parameters */ void initializeMembers(); + + /** + * Sets up all the filter objects for single photon data + * Deals with data compression + */ + void initializeFilter(); + + /** + * Create Listening Threads + * @param destroy is true to destroy all the threads + */ + int createListeningThreads(bool destroy = false); + + /** + * Create Writer Threads + * @param destroy is true to destroy all the threads + * @return OK or FAIL + */ + int createWriterThreads(bool destroy = false); + + /** + * Set Thread Priorities + */ + void setThreadPriorities(); + + /** + * Set up the Fifo Structure for processing buffers + * between listening and writer threads + * @return OK or FAIL + */ + int setupFifoStructure(); + + /** + * Creates UDP Sockets + * @return OK or FAIL + */ + int createUDPSockets(); + + + + //**detector parameters*** + /** + * structure of an eiger packet header + * subframenum subframe number for 32 bit mode (already written by firmware) + * missingpacket explicitly put to 0xFF to recognize it in file read (written by software) + * portnum 0 for the first port and 1 for the second port (written by software to file) + * dynamicrange dynamic range or bits per pixel (written by software to file) + */ + typedef struct { + unsigned char subFameNumber[4]; + unsigned char missingPacket[2]; + unsigned char portIndex[1]; + unsigned char dynamicRange[1]; + } eiger_packet_header_t; + /** + * structure of an eiger packet footer + * framenum 48 bit frame number (already written by firmware) + * packetnum packet number (already written by firmware) + */ + typedef struct { + unsigned char frameNumber[6]; + unsigned char packetNumber[2]; + } eiger_packet_footer_t; + + /** Size of 1 Frame including headers */ + int frameSize; + + /** Size of 1 buffer processed at a time */ + int bufferSize; + + /** One Packet Size including headers */ + int onePacketSize; + + /** One Packet Size without headers */ + int oneDataSize; + + /** Frame Index Mask */ + uint64_t frameIndexMask; + + /** Frame Index Offset */ + int frameIndexOffset; + + /** Packet Index Mask */ + uint64_t packetIndexMask; + + /** Footer offset from start of Packet*/ + int footerOffset; + + //***File parameters*** + /** Maximum Packets Per File **/ + int maxPacketsPerFile; + + + + //***acquisition indices parameters*** + /** Frame Number of First Frame of an Acquisition */ + uint64_t startAcquisitionIndex; + + /** Frame index at start of each real time acquisition (eg. for each scan) */ + uint64_t startFrameIndex; + + /** Current Frame Number */ + uint64_t currentFrameNumber; + + /* Acquisition started */ + bool acqStarted; + + /* Measurement started */ + bool measurementStarted; + + /** Total Frame Count listened to by listening threads */ + int totalListeningFrameCount[MAX_NUMBER_OF_LISTENING_THREADS]; + + + + + //***receiver parameters*** + /** Receiver Buffer */ + char *buffer[MAX_NUMBER_OF_LISTENING_THREADS]; + + /** Memory allocated */ + char *mem0[MAX_NUMBER_OF_LISTENING_THREADS]; + + /** Circular fifo to point to addresses of data listened to */ + CircularFifo* fifo[MAX_NUMBER_OF_LISTENING_THREADS]; + + /** Circular fifo to point to address already written and freed, to be reused */ + CircularFifo* fifoFree[MAX_NUMBER_OF_LISTENING_THREADS]; + + /** Number of Jobs Per Buffer */ + int numberofJobsPerBuffer; + + /** Fifo Depth */ + uint32_t fifoSize; + + /** Current Frame copied for Gui */ + char* latestData; + + + + //***general and listening thread parameters*** + /** Ensures if threads created successfully */ + bool threadStarted; + + /** Number of Listening Threads */ + int numberofListeningThreads; + + /** Listening Threads */ + pthread_t listeningThreads[MAX_NUMBER_OF_LISTENING_THREADS]; + + /** Semaphores Synchronizing Listening Threads */ + sem_t listenSemaphore[MAX_NUMBER_OF_LISTENING_THREADS]; + + /** Current Listening Thread Index*/ + int currentListeningThreadIndex; + + /** Mask with each bit indicating status of each listening thread */ + volatile uint32_t listeningThreadsMask; + + /** Set to self-terminate listening threads waiting for semaphores */ + bool killAllListeningThreads; + + + + //***writer thread parameters*** + /** Maximum Number of Writer Threads */ + const static int MAX_NUMBER_OF_WRITER_THREADS = 15; + + /** Number of Writer Threads */ + int numberofWriterThreads; + + /** Writer Threads */ + pthread_t writingThreads[MAX_NUMBER_OF_WRITER_THREADS]; + + /** Semaphores Synchronizing Writer Threads */ + sem_t writerSemaphore[MAX_NUMBER_OF_WRITER_THREADS]; + + /** Current Writer Thread Index*/ + int currentWriterThreadIndex; + + /** Mask with each bit indicating status of each writer thread */ + volatile uint32_t writerThreadsMask; + + /** Mask with each bit indicating file created for each writer thread*/ + volatile uint32_t createFileMask; + + /** Set to self-terminate writer threads waiting for semaphores */ + bool killAllWritingThreads; + + + + + + + //***filter parameters*** + /** Common Mode Subtraction Enable FIXME: Always false, only moench uses, Ask Anna */ + bool commonModeSubtractionEnable; + + /** Moench Common Mode Subtraction */ + moenchCommonMode *moenchCommonModeSubtraction; + + /** Single Photon Detector Object for each writer thread */ + singlePhotonDetector *singlePhotonDetectorObject[MAX_NUMBER_OF_WRITER_THREADS]; + + /** Receiver Data Object for each writer thread */ + slsReceiverData *receiverData[MAX_NUMBER_OF_WRITER_THREADS]; + + + + + //***mutex*** + /** mutex for status */ + pthread_mutex_t status_mutex; + + + + + + + + + + + + + + + + + + + + + + + + + /** * Set receiver type @@ -74,26 +442,11 @@ class UDPStandardImplementation: private virtual slsReceiverDefs, public UDPBase */ //uint32_t getStartAcquisitionIndex(); - /** - * Returns current Frame Index Caught for an entire acquisition (including all scans) - */ - //uint32_t getAcquisitionIndex(); - /** * Returns if acquisition started */ //bool getAcquistionStarted(); - /** - * Returns Frames Caught for each real time acquisition (eg. for each scan) - */ - //int getFramesCaught(); - - /** - * Returns Total Frames Caught for an entire acquisition (including all scans) - */ - //int getTotalFramesCaught(); - /** * Returns the frame index at start of each real time acquisition (eg. for each scan) */ @@ -117,71 +470,8 @@ class UDPStandardImplementation: private virtual slsReceiverDefs, public UDPBase //void resetTotalFramesCaught(); - //file parameters - /** - * Returns File Path - */ - //char* getFilePath() const; - /** - * Set File Path - * @param c file path - */ - //char* setFilePath(const char c[]); - /** - * Returns File Name - */ - //char* getFileName() const; - - /** - * Set File Name (without frame index, file index and extension) - * @param c file name - */ - //char* setFileName(const char c[]); - - /** - * Returns File Index - */ - //int getFileIndex(); - - /** - * Set File Index - * @param i file index - */ - //int setFileIndex(int i); - - /** - * Set Frame Index Needed - * @param i frame index needed - */ - //int setFrameIndexNeeded(int i); - - /** - * Set enable file write - * @param i file write enable - * Returns file write enable - */ - //int setEnableFileWrite(int i); - - /** - * Enable/disable overwrite - * @param i enable - * Returns enable over write - */ - //int setEnableOverwrite(int i); - - /** - * Returns file write enable - * 1: YES 0: NO - */ - //int getEnableFileWrite() const; - - /** - * Returns file over write enable - * 1: YES 0: NO - */ - //int getEnableOverwrite() const; //other parameters @@ -202,83 +492,7 @@ class UDPStandardImplementation: private virtual slsReceiverDefs, public UDPBase */ void setDetectorHostname(const char *detectorHostName); - /* Returns detector hostname - /returns hostname - * caller needs to deallocate the returned char array. - * if uninitialized, it must return NULL - */ - char *getDetectorHostname() const; - /** - * Set Ethernet Interface or IP to listen to - */ - void setEthernetInterface(char* c); - - /** - * Set UDP Port Number - */ - void setUDPPortNo(int p); - /** - * Set UDP Port Number - */ - void setUDPPortNo2(int p); - - /* - * Returns number of frames to receive - * This is the number of frames to expect to receiver from the detector. - * The data receiver will change from running to idle when it got this number of frames - */ - int getNumberOfFrames() const; - - /** - * set frame number if a positive number - */ - int32_t setNumberOfFrames(int32_t fnum); - - /** - * Returns scan tag - */ - int getScanTag() const; - - /** - * set scan tag if its is a positive number - */ - int32_t setScanTag(int32_t stag); - - /** - * Returns the number of bits per pixel - */ - int getDynamicRange() const; - - /** - * set dynamic range if its is a positive number - */ - int32_t setDynamicRange(int32_t dr); - - /** - * Set short frame - * @param i if shortframe i=1 - */ - int setShortFrame(int i); - - /** - * Set the variable to send every nth frame to gui - * or if 0,send frame only upon gui request - */ - int setNFrameToGui(int i); - - /** set acquisition period if a positive number - */ - int64_t setAcquisitionPeriod(int64_t index); - - /** get data compression, by saving only hits - */ - bool getDataCompression(); - - /** enabl data compression, by saving only hits - /returns if failed - */ - int enableDataCompression(bool enable); /** * enable 10Gbe @@ -337,20 +551,9 @@ private: std::cout << "[WARNING] Method " << method_name << " not implemented!" << std::endl; }; */ - /** - * Deletes all the filter objects for single photon data - */ - void deleteFilter(); - /** - * Constructs the filter for single photon data - */ - void setupFilter(); - /** - * set up fifo according to the new numjobsperthread - */ - void setupFifoStructure (); + /** * Copy frames to gui @@ -358,28 +561,6 @@ private: */ void copyFrameToGui(char* startbuf[], char* buf=NULL); - /** - * creates udp sockets - * \returns if success or fail - */ - int createUDPSockets(); - - /** - * create listening thread - * @param destroy is true to kill all threads and start again - */ - int createListeningThreads(bool destroy = false); - - /** - * create writer threads - * @param destroy is true to kill all threads and start again - */ - int createWriterThreads(bool destroy = false); - - /** - * set thread priorities - */ - void setThreadPriorities(); /** * initializes variables and creates the first file @@ -507,8 +688,7 @@ private: - /** max number of writer threads */ - const static int MAX_NUM_WRITER_THREADS = 15; + /** missing packet identifier value */ const static uint16_t missingPacketValue = 0xFFFF; @@ -517,21 +697,9 @@ private: /** UDP Socket between Receiver and Detector */ genericSocket* udpSocket[MAX_NUM_LISTENING_THREADS]; - /** max packets per file **/ - int maxPacketsPerFile; - - /** Frame Index at start of an entire acquisition (including all scans) */ - uint64_t startAcquisitionIndex; /** Complete File name */ char savefilename[MAX_STR_LENGTH]; - /* Measurement started */ - bool measurementStarted; - /* Acquisition started */ - bool acqStarted; - /** Frame index at start of each real time acquisition (eg. for each scan) */ - uint32_t startFrameIndex; - /** Actual current frame index of each time acquisition (eg. for each scan) */ uint32_t frameIndex; @@ -547,34 +715,9 @@ private: /** Number of missing packets per buffer*/ uint32_t numMissingPackets; - /** frame index mask */ - uint32_t frameIndexMask; - - /** packet index mask */ - uint32_t packetIndexMask; - - /** frame index offset */ - int frameIndexOffset; - /** Current Frame Number */ - uint64_t currframenum; - /** Previous Frame number from buffer */ int prevframenum; - /** size of one frame */ - int frameSize; - - /** buffer size. different from framesize as we wait for one packet instead of frame for eiger */ - int bufferSize; - - /** one buffer size */ - int onePacketSize; - - /** one buffer size */ - int oneDataSize; - - /** latest data */ - char* latestData; /** gui data ready */ int guiDataReady; @@ -585,71 +728,9 @@ private: /** points to the filename to send to gui */ char* guiFileName; - /** fifo size */ - unsigned int fifosize; - - /** number of jobs per thread for data compression */ - int numJobsPerThread; - - /** memory allocated for the buffer */ - char *mem0[MAX_NUM_LISTENING_THREADS]; - - /** circular fifo to store addresses of data read */ - CircularFifo* fifo[MAX_NUM_LISTENING_THREADS]; - - /** circular fifo to store addresses of data already written and ready to be resued*/ - CircularFifo* fifoFree[MAX_NUM_LISTENING_THREADS]; - - /** Receiver buffer */ - char *buffer[MAX_NUM_LISTENING_THREADS]; - - /** number of writer threads */ - int numListeningThreads; - - /** number of writer threads */ - int numWriterThreads; - - /** to know if listening and writer threads created properly */ - int thread_started; - - /** current listening thread index*/ - int currentListeningThreadIndex; - - /** current writer thread index*/ - int currentWriterThreadIndex; - - /** thread listening to packets */ - pthread_t listening_thread[MAX_NUM_LISTENING_THREADS]; - - /** thread writing packets */ - pthread_t writing_thread[MAX_NUM_WRITER_THREADS]; - - /** total frame count the listening thread has listened to */ - int totalListeningFrameCount[MAX_NUM_LISTENING_THREADS]; - - /** mask showing which listening threads are running */ - volatile uint32_t listeningthreads_mask; - - /** mask showing which writer threads are running */ - volatile uint32_t writerthreads_mask; - - /** mask showing which threads have created files*/ - volatile uint32_t createfile_mask; - - /** OK if file created was successful */ +/** OK if file created was successful */ int ret_createfile; - /** variable used to self terminate threads waiting for semaphores */ - int killAllListeningThreads; - - /** variable used to self terminate threads waiting for semaphores */ - int killAllWritingThreads; - - - - /** footer offset is different for 1g and 10g*/ - int footer_offset; - // TODO: not properly sure where to put these... /** structure of an eiger image header*/ @@ -659,19 +740,11 @@ private: //semaphores /** semaphore to synchronize writer and guireader threads */ sem_t smp; - /** semaphore to synchronize listener threads */ - sem_t listensmp[MAX_NUM_LISTENING_THREADS]; - /** semaphore to synchronize writer threads */ - sem_t writersmp[MAX_NUM_WRITER_THREADS]; - //mutex /** guiDataReady mutex */ pthread_mutex_t dataReadyMutex; - /** mutex for status */ - pthread_mutex_t status_mutex; - /** mutex for progress variable currframenum */ pthread_mutex_t progress_mutex; @@ -682,10 +755,7 @@ private: FILE *sfilefd; //filter - singlePhotonDetector *singlePhotonDet[MAX_NUM_WRITER_THREADS]; - slsReceiverData *receiverdata[MAX_NUM_WRITER_THREADS]; - moenchCommonMode *cmSub; - bool commonModeSubtractionEnable; + #ifdef MYROOT1 /** Tree where the hits are stored */ diff --git a/slsReceiverSoftware/include/receiver_defs.h b/slsReceiverSoftware/include/receiver_defs.h index 206c8b92b..bac0df2d6 100755 --- a/slsReceiverSoftware/include/receiver_defs.h +++ b/slsReceiverSoftware/include/receiver_defs.h @@ -27,8 +27,9 @@ /*#define GOTTHARD_ALIGNED_FRAME_SIZE 4096*/ #define GOTTHARD_PACKETS_PER_FRAME 2 #define GOTTHARD_ONE_PACKET_SIZE 1286 +#define GOTTHARD_ONE_DATA_SIZE 1280 #define GOTTHARD_BUFFER_SIZE (GOTTHARD_ONE_PACKET_SIZE*GOTTHARD_PACKETS_PER_FRAME) //1286*2 -#define GOTTHARD_DATA_BYTES (1280*GOTTHARD_PACKETS_PER_FRAME) //1280*2 +#define GOTTHARD_DATA_BYTES (GOTTHARD_ONE_DATA_SIZE*GOTTHARD_PACKETS_PER_FRAME) //1280*2 #define GOTTHARD_FRAME_INDEX_MASK 0xFFFFFFFE #define GOTTHARD_FRAME_INDEX_OFFSET 1 @@ -39,7 +40,7 @@ #define GOTTHARD_SHORT_PACKETS_PER_FRAME 1 -#define GOTTHARD_SHORT_ONE_PACKET_SIZE 518 +#define GOTTHARD_SHORT_ONE_PACKET_SIZE 518 #define GOTTHARD_SHORT_BUFFER_SIZE 518 #define GOTTHARD_SHORT_DATABYTES 512 #define GOTTHARD_SHORT_FRAME_INDEX_MASK 0xFFFFFFFF @@ -75,8 +76,9 @@ /*#define MOENCH_ALIGNED_FRAME_SIZE 65536*/ #define MOENCH_PACKETS_PER_FRAME 40 #define MOENCH_ONE_PACKET_SIZE 1286 +#define MOENCH_ONE_DATA_SIZE 1280 #define MOENCH_BUFFER_SIZE (MOENCH_ONE_PACKET_SIZE*MOENCH_PACKETS_PER_FRAME) //1286*40 -#define MOENCH_DATA_BYTES (1280*MOENCH_PACKETS_PER_FRAME) //1280*40 +#define MOENCH_DATA_BYTES (MOENCH_ONE_DATA_SIZE*MOENCH_PACKETS_PER_FRAME) //1280*40 #define MOENCH_FRAME_INDEX_MASK 0xFFFFFF00 #define MOENCH_FRAME_INDEX_OFFSET 8 diff --git a/slsReceiverSoftware/include/slsReceiver.h b/slsReceiverSoftware/include/slsReceiver.h index 4eb024776..e76ea7d1b 100644 --- a/slsReceiverSoftware/include/slsReceiver.h +++ b/slsReceiverSoftware/include/slsReceiver.h @@ -8,7 +8,6 @@ #include "slsReceiverTCPIPInterface.h" #include "UDPInterface.h" -//#include "UDPBaseImplementation.h" #include "receiver_defs.h" #include "MySocketTCP.h" diff --git a/slsReceiverSoftware/include/sls_receiver_defs.h b/slsReceiverSoftware/include/sls_receiver_defs.h index 11641334a..04b8b19fb 100755 --- a/slsReceiverSoftware/include/sls_receiver_defs.h +++ b/slsReceiverSoftware/include/sls_receiver_defs.h @@ -111,6 +111,16 @@ public: }; + /** returns string from enabled/disabled + \param b true or false + \returns string enabled, disabled + */ + static string stringEnable(bool b){\ + if(b) return string("enabled"); \ + else return string("disabled"); \ + }; + + #ifdef __cplusplus protected: diff --git a/slsReceiverSoftware/src/UDPBaseImplementation.cpp b/slsReceiverSoftware/src/UDPBaseImplementation.cpp index e16060865..0c1c30248 100644 --- a/slsReceiverSoftware/src/UDPBaseImplementation.cpp +++ b/slsReceiverSoftware/src/UDPBaseImplementation.cpp @@ -4,25 +4,12 @@ * @short does all the functions for a receiver, set/get parameters, start/stop etc. ***********************************************/ - #include "UDPBaseImplementation.h" -#include "moench02ModuleData.h" -#include "gotthardModuleData.h" -#include "gotthardShortModuleData.h" - - -#include // SIGINT #include // stat -#include // socket(), bind(), listen(), accept(), shut down -#include // sock_addr_in, htonl, INADDR_ANY -#include // exit() -#include //set precision -#include //munmap -#include #include - +#include using namespace std; @@ -32,7 +19,11 @@ using namespace std; * They access local cache of configuration or detector parameters ******* *************************************************************************/ UDPBaseImplementation::UDPBaseImplementation(){ + FILE_LOG(logDEBUG) << __AT__ << " starting"; + + cout << "Info: Initializing base members" << endl; //**detector parameters*** + myDetectorType = GENERIC; strcpy(detHostname,""); packetsPerFrame = 0; acquisitionPeriod = 0; @@ -51,7 +42,7 @@ UDPBaseImplementation::UDPBaseImplementation(){ } //***file parameters*** - strcpy(fileName,""); + strcpy(fileName,"run"); strcpy(filePath,""); fileIndex = 0; scanTag = 0; @@ -78,9 +69,17 @@ UDPBaseImplementation::UDPBaseImplementation(){ pAcquisitionFinished = NULL; rawDataReadyCallBack = NULL; pRawDataReady = NULL; -}; +} -UDPBaseImplementation::~UDPBaseImplementation(){}; +UDPBaseImplementation::~UDPBaseImplementation(){ + FILE_LOG(logDEBUG) << __AT__ << " starting"; + + cout << "Info: Deleting base member pointers" << endl; + if(detHostname) {delete [] detHostname; detHostname = NULL;} + if(eth) {delete [] eth; eth = NULL;} + if(fileName) {delete [] fileName; fileName = NULL;} + if(filePath) {delete [] filePath; filePath = NULL;} +} /************************************************************************* @@ -157,9 +156,9 @@ int64_t UDPBaseImplementation::getAcquisitionIndex() const{ /***connection parameters***/ -uint32_t UDPBaseImplementation::getUDPPortNo() const{ FILE_LOG(logDEBUG) << __AT__ << " starting"; return udpPortNum[0];} +uint32_t UDPBaseImplementation::getUDPPortNumber() const{ FILE_LOG(logDEBUG) << __AT__ << " starting"; return udpPortNum[0];} -uint32_t UDPBaseImplementation::getUDPPortNo2() const{ FILE_LOG(logDEBUG) << __AT__ << " starting"; return udpPortNum[1];} +uint32_t UDPBaseImplementation::getUDPPortNumber2() const{ FILE_LOG(logDEBUG) << __AT__ << " starting"; return udpPortNum[1];} char *UDPBaseImplementation::getEthernetInterface() const{ FILE_LOG(logDEBUG) << __AT__ << " starting"; @@ -205,7 +204,7 @@ void UDPBaseImplementation::setBottomEnable(const bool b){ FILE_LOG(logDEBUG) << __AT__ << " starting"; bottomEnable = b; - FILE_LOG(logINFO) << "Bottom Enable:" << bottomEnable; + FILE_LOG(logINFO) << "Bottom Enable: " << stringEnable(bottomEnable); } @@ -255,41 +254,46 @@ void UDPBaseImplementation::setFrameIndexEnable(const bool b){ FILE_LOG(logDEBUG) << __AT__ << " starting"; frameIndexEnable = b; - FILE_LOG(logINFO) << "Frame Index Enable:" << frameIndexEnable; + FILE_LOG(logINFO) << "Frame Index Enable: " << stringEnable(frameIndexEnable); } void UDPBaseImplementation::setFileWriteEnable(const bool b){ FILE_LOG(logDEBUG) << __AT__ << " starting"; fileWriteEnable = b; - FILE_LOG(logINFO) << "File Write Enable:" << fileWriteEnable; + FILE_LOG(logINFO) << "File Write Enable: " << stringEnable(fileWriteEnable); } void UDPBaseImplementation::setOverwriteEnable(const bool b){ FILE_LOG(logDEBUG) << __AT__ << " starting"; overwriteEnable = b; - FILE_LOG(logINFO) << "Overwrite Enable:" << overwriteEnable; + FILE_LOG(logINFO) << "Overwrite Enable: " << stringEnable(overwriteEnable); } -void UDPBaseImplementation::setDataCompressionEnable(const bool b){ +int UDPBaseImplementation::setDataCompressionEnable(const bool b){ FILE_LOG(logDEBUG) << __AT__ << " starting"; dataCompressionEnable = b; - FILE_LOG(logINFO) << "Data Compression Enable:" << dataCompressionEnable; -} + FILE_LOG(logINFO) << "Data Compression Enable: " << stringEnable(dataCompressionEnable); + //overridden methods might return FAIL + return OK; +} /***connection parameters***/ -void UDPBaseImplementation::setUDPPortNo(const uint32_t i){ +void UDPBaseImplementation::setUDPPortNumber(const uint32_t i){ FILE_LOG(logDEBUG) << __AT__ << " starting"; - udpPortNum[0] = i; + if(bottomEnable) + udpPortNum[1] = i; + else + udpPortNum[0] = i; FILE_LOG(logINFO) << "udpPortNum[0]:" << udpPortNum[0]; } -void UDPBaseImplementation::setUDPPortNo2(const uint32_t i){ +void UDPBaseImplementation::setUDPPortNumber2(const uint32_t i){ FILE_LOG(logDEBUG) << __AT__ << " starting"; udpPortNum[1] = i; @@ -304,26 +308,32 @@ void UDPBaseImplementation::setEthernetInterface(const char* c){ } -/***connection parameters***/ +/***acquisition parameters***/ void UDPBaseImplementation::setShortFrameEnable(const int i){ FILE_LOG(logDEBUG) << __AT__ << " starting"; shortFrameEnable = i; - FILE_LOG(logINFO) << "Short Frame Enable:" << shortFrameEnable; + FILE_LOG(logINFO) << "Short Frame Enable: " << stringEnable(shortFrameEnable); } -void UDPBaseImplementation::setFrameToGuiFrequency(const uint32_t i){ +int UDPBaseImplementation::setFrameToGuiFrequency(const uint32_t i){ FILE_LOG(logDEBUG) << __AT__ << " starting"; FrameToGuiFrequency = i; FILE_LOG(logINFO) << "Frame To Gui Frequency:" << FrameToGuiFrequency; + + //overrridden child classes might return FAIL + return OK; } -void UDPBaseImplementation::setAcquisitionPeriod(const uint64_t i){ +int UDPBaseImplementation::setAcquisitionPeriod(const uint64_t i){ FILE_LOG(logDEBUG) << __AT__ << " starting"; acquisitionPeriod = i; FILE_LOG(logINFO) << "Acquisition Period:" << acquisitionPeriod; + + //overrridden child classes might return FAIL + return OK; } void UDPBaseImplementation::setNumberOfFrames(const uint64_t i){ @@ -333,20 +343,25 @@ void UDPBaseImplementation::setNumberOfFrames(const uint64_t i){ FILE_LOG(logINFO) << "Number of Frames:" << numberOfFrames; } -void UDPBaseImplementation::setDynamicRange(const uint32_t i){ +int UDPBaseImplementation::setDynamicRange(const uint32_t i){ FILE_LOG(logDEBUG) << __AT__ << " starting"; dynamicRange = i; FILE_LOG(logINFO) << "Dynamic Range:" << dynamicRange; + + //overrridden child classes might return FAIL + return OK; } -void UDPBaseImplementation::setTenGigaEnable(const bool b){ +int UDPBaseImplementation::setTenGigaEnable(const bool b){ FILE_LOG(logDEBUG) << __AT__ << " starting"; tengigaEnable = b; - FILE_LOG(logINFO) << "Ten Giga Enable:" << tengigaEnable; -} + FILE_LOG(logINFO) << "Ten Giga Enable: " << stringEnable(tengigaEnable); + //overridden functions might return FAIL + return OK; +} /************************************************************************* @@ -354,11 +369,13 @@ void UDPBaseImplementation::setTenGigaEnable(const bool b){ * They may modify the status of the receiver **************************** *************************************************************************/ + /***initial functions***/ int UDPBaseImplementation::setDetectorType(const slsReceiverDefs::detectorType d){ FILE_LOG(logDEBUG) << __AT__ << " starting"; myDetectorType = d; + //if eiger, set numberofListeningThreads = 2; FILE_LOG(logINFO) << "Detector Type:" << slsDetectorBase::getDetectorType(d); return OK; } diff --git a/slsReceiverSoftware/src/UDPInterface.cpp b/slsReceiverSoftware/src/UDPInterface.cpp index 952098811..937035845 100644 --- a/slsReceiverSoftware/src/UDPInterface.cpp +++ b/slsReceiverSoftware/src/UDPInterface.cpp @@ -5,11 +5,11 @@ ***********************************************/ - -#include #include +#include using namespace std; + #include "UDPInterface.h" #include "UDPBaseImplementation.h" #include "UDPStandardImplementation.h" diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index dfbe51493..0f4290c9c 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -10,24 +10,920 @@ #include "gotthardModuleData.h" #include "gotthardShortModuleData.h" - -#include // SIGINT -#include // stat -#include // socket(), bind(), listen(), accept(), shut down -#include // sock_addr_in, htonl, INADDR_ANY +//#include // socket(), bind(), listen(), accept(), shut down +//#include // sock_addr_in, htonl, INADDR_ANY #include // exit() -#include //set precision -#include //munmap +#include //set precision for printing parameters for create new file +#include //map +//#include //munmap - - -#include #include +#include #include using namespace std; - #define WRITE_HEADERS + +/************************************************************************* + * Constructor & Destructor ********************************************** + * They access local cache of configuration or detector parameters ******* + *************************************************************************/ + +UDPStandardImplementation::UDPStandardImplementation(){ + FILE_LOG(logDEBUG) << __AT__ << " called"; + + initializeMembers(); +} + +UDPStandardImplementation::~UDPStandardImplementation(){ + FILE_LOG(logDEBUG) << __AT__ << " called"; + + deleteMembers(); +} + + +/************************************************************************* + * Setters *************************************************************** + * They modify the local cache of configuration or detector parameters *** + *************************************************************************/ + +/***initial parameters***/ +void UDPStandardImplementation::deleteBaseMembers(){ + FILE_LOG(logDEBUG) << __AT__ << " starting"; + + UDPBaseImplementation::~UDPBaseImplementation(); +} + +void UDPStandardImplementation::deleteMembers(){ + FILE_LOG(logDEBUG) << __AT__ << " starting"; + + cout << "Info: Deleting member pointers" << endl; + //filter + deleteFilter(); + //kill threads + if(threadStarted){ + createListeningThreads(true); + createWriterThreads(true); + } + //shutdownudpsockets + //close file + if(latestData) {delete[] latestData; latestData = NULL;} +} + +void UDPStandardImplementation::deleteFilter(){ + FILE_LOG(logDEBUG) << __AT__ << " starting"; + + moenchCommonModeSubtraction = NULL; + for(int i=0; i(receiverData[i], csize, sigma, sign, commonModeSubtractionEnable); +} + + + +int UDPStandardImplementation::createListeningThreads(bool destroy){ + FILE_LOG(logDEBUG) << __AT__ << " starting"; + + //reset masks + killAllListeningThreads = false; + pthread_mutex_lock(&status_mutex); + listeningThreadsMask = 0x0; + pthread_mutex_unlock(&(status_mutex)); + + //destroy + if(destroy){ + cout << "Info: Destroying Listening Thread(s)" << endl; + + killAllListeningThreads = true; + for(int i = 0; i < numberofListeningThreads; ++i){ + sem_post(&listenSemaphore[i]); + pthread_join(listeningThreads[i],NULL); + cout <<"."< MAX_JOBS_PER_THREAD) + numberofJobsPerBuffer = MAX_JOBS_PER_THREAD; + else if (i < 1) + numberofJobsPerBuffer = 1; + else + numberofJobsPerBuffer = i; + + } + cout << "Info: Number of Frames per buffer:" << numberofJobsPerBuffer << endl; + } + + //set fifo depth + //eiger listens to 1 packet at a time and size changes depending on packets per frame + if(myDetectorType == EIGER) + fifoSize = EIGER_FIFO_SIZE * packetsPerFrame; + else{ + fifoSize = GOTTHARD_FIFO_SIZE; + if(myDetectorType == MOENCH) + fifoSize = MOENCH_FIFO_SIZE; + else if(myDetectorType == PROPIX) + fifoSize = PROPIX_FIFO_SIZE; + //reduce fifo depth if more frames listened to at a time + if(fifoSize % numberofJobsPerBuffer) + fifoSize = (fifoSize/numberofJobsPerBuffer)+1; + else + fifoSize = fifoSize/numberofJobsPerBuffer; + } +#ifdef VERBOSE + cout << "Info: Fifo Depth:" << fifoSize << endl; +#endif + + + //do not rebuild fifo structure if it is the same + if((oldNumberofJobsPerBuffer == numberofJobsPerBuffer) && (oldFifoSize == fifoSize)) + return OK; + + + //set up fifo structure + for(int i=0;iisEmpty()) + fifoFree[i]->pop(buffer[i]); +#ifdef FIFO_DEBUG + cprintf(GREEN,"%d fifostructure popped from fifofree %p\n", i, (void*)(buffer[i])); +#endif + delete fifoFree[i]; + } + if(fifo[i]) delete fifo[i]; + if(mem0[i]) free(mem0[i]); + + //creating + fifoFree[i] = new CircularFifo(fifoSize); + fifo[i] = new CircularFifo(fifoSize); + + //allocate memory + mem0[i] = (char*)malloc((bufferSize * numberofJobsPerBuffer + HEADER_SIZE_NUM_TOT_PACKETS) * fifoSize); + if (mem0[i] == NULL){ + cprintf(BG_RED,"Error: Could not allocate memory for listening \n"); + return FAIL; + } + + //push free address into fifoFree + buffer[i]=mem0[i]; + while (buffer[i] < (mem0[i]+(bufferSize * numberofJobsPerBuffer + HEADER_SIZE_NUM_TOT_PACKETS) * (fifoSize-1))) { + fifoFree[i]->push(buffer[i]); +#ifdef FIFO_DEBUG + cprintf(BLUE,"%d fifostructure free pushed into fifofree %p\n", i, (void*)(buffer[i])); +#endif + buffer[i] += (bufferSize * numberofJobsPerBuffer + HEADER_SIZE_NUM_TOT_PACKETS); + } + } + cout << "Info: Fifo structure(s) reconstructed" << endl; +} + + + + +int UDPStandardImplementation::createUDPSockets(){ + FILE_LOG(logDEBUG) << __AT__ << " called"; + + + + + return OK; +} + + + + +void UDPStandardImplementation::configure(map config_map){ + FILE_LOG(logDEBUG) << __AT__ << " starting"; + + map::const_iterator pos; + pos = config_map.find("mode"); + if (pos != config_map.end() ){ + int b; + if(!sscanf(pos->second.c_str(), "%d", &b)){ + cout << "Warning: Could not parse mode. Assuming top mode." << endl; + b = 0; + } + bottomEnable = b!= 0; + cout << "Info: Bottom Enable: " << stringEnable(bottomEnable) << endl; + } + +} + + +/***file parameters***/ +int UDPStandardImplementation::setDataCompressionEnable(const bool b){ + FILE_LOG(logDEBUG) << __AT__ << " starting"; + + cout << "Info: Setting up Data Compression Enable to " << stringEnable(b); +#ifdef MYROOT1 + cout << " WITH ROOT" << endl; +#else + cout << " WITHOUT ROOT" << endl; +#endif + + //set data compression enable + dataCompressionEnable = b; + + //-- create writer threads depending on enable + pthread_mutex_lock(&status_mutex); + writerThreadsMask = 0x0; + pthread_mutex_unlock(&(status_mutex)); + + createWriterThreads(true); + if(b) + numberofWriterThreads = MAX_NUMBER_OF_WRITER_THREADS; + else + numberofWriterThreads = 1; + if(createWriterThreads() == FAIL){ + cprintf(BG_RED,"Error: Could not create writer threads\n"); + return FAIL; + } + //-- end of create writer threads + setThreadPriorities(); + + //filter + deleteFilter(); + if(b) + initializeFilter(); + + cout << "Info: Data Compression " << stringEnable(dataCompressionEnable) << endl; + + return OK; +} + + +/***acquisition parameters***/ +void UDPStandardImplementation::setShortFrameEnable(const int i){ + FILE_LOG(logDEBUG) << __AT__ << " called"; + + shortFrameEnable = i; + + if(shortFrameEnable!=-1){ + frameSize = GOTTHARD_SHORT_BUFFER_SIZE; + bufferSize = GOTTHARD_SHORT_BUFFER_SIZE; + onePacketSize = GOTTHARD_SHORT_BUFFER_SIZE; + oneDataSize = GOTTHARD_SHORT_DATABYTES; + maxPacketsPerFile = SHORT_MAX_FRAMES_PER_FILE * GOTTHARD_SHORT_PACKETS_PER_FRAME; + packetsPerFrame = GOTTHARD_SHORT_PACKETS_PER_FRAME; + frameIndexMask = GOTTHARD_SHORT_FRAME_INDEX_MASK; + frameIndexOffset = GOTTHARD_SHORT_FRAME_INDEX_OFFSET; + packetIndexMask = GOTTHARD_SHORT_PACKET_INDEX_MASK; + + }else{ + frameSize = GOTTHARD_BUFFER_SIZE; + bufferSize = GOTTHARD_BUFFER_SIZE; + onePacketSize = GOTTHARD_ONE_PACKET_SIZE; + oneDataSize = GOTTHARD_ONE_DATA_SIZE; + maxPacketsPerFile = MAX_FRAMES_PER_FILE * GOTTHARD_PACKETS_PER_FRAME; + packetsPerFrame = GOTTHARD_PACKETS_PER_FRAME; + frameIndexMask = GOTTHARD_FRAME_INDEX_MASK; + frameIndexOffset = GOTTHARD_FRAME_INDEX_OFFSET; + packetIndexMask = GOTTHARD_PACKET_INDEX_MASK; + } + + //filter + deleteFilter(); + if(dataCompressionEnable) + initializeFilter(); + + cout << "Info: Short Frame Enable set to " << shortFrameEnable << endl; +} + + +int UDPStandardImplementation::setFrameToGuiFrequency(const uint32_t i){ + FILE_LOG(logDEBUG) << __AT__ << " called"; + + if(i >= 0){ + FrameToGuiFrequency = i; + if(setupFifoStructure() == FAIL) + return FAIL; + } + + cout << "Info: Frame to Gui Frequency set to " << FrameToGuiFrequency << endl; + + return OK; +} + + +int UDPStandardImplementation::setAcquisitionPeriod(int64_t i){ + FILE_LOG(logDEBUG) << __AT__ << " called"; + + if(i >= 0){ + acquisitionPeriod = i; + if(setupFifoStructure() == FAIL) + return FAIL; + } + + cout << "Info: Acquisition Period set to " << acquisitionPeriod << endl; + + + return OK; +} + +int UDPStandardImplementation::setDynamicRange(const uint32_t i){ + FILE_LOG(logDEBUG) << __AT__ << " called"; + + int oldDynamicRange = dynamicRange; + + cout << "Info: Setting Dynamic Range to " << i << endl; + dynamicRange = i; + + if(myDetectorType == EIGER){ + + //set parameters depending on new dynamic range. + packetsPerFrame = (tengigaEnable ? EIGER_TEN_GIGA_CONSTANT : EIGER_ONE_GIGA_CONSTANT) + * dynamicRange * EIGER_MAX_PORTS; + frameSize = onePacketSize * packetsPerFrame; + maxPacketsPerFile = EIGER_MAX_FRAMES_PER_FILE * packetsPerFrame; + + //new dynamic range, then restart threads and resetup fifo structure + if(oldDynamicRange != dynamicRange){ + + //delete threads + if(threadStarted){ + createListeningThreads(true); + createWriterThreads(true); + } + + //gui buffer + if(latestData){delete[] latestData; latestData = NULL;} + latestData = new char[frameSize]; + + //restructure fifo + if(setupFifoStructure() == FAIL) + return FAIL; + + //create threads + if(createListeningThreads() == FAIL){ + cprintf(BG_RED,"Error: Could not create listening thread\n"); + return FAIL; + } + if(createWriterThreads() == FAIL){ + cprintf(BG_RED,"Error: Could not create writer threads\n"); + return FAIL; + } + setThreadPriorities(); + } + + } + + cout << "Info: Dynamic Range set to " << dynamicRange << endl; + + return OK; +} + + + +int UDPStandardImplementation::setTenGigaEnable(const bool b){ + FILE_LOG(logDEBUG) << __AT__ << " called"; + + cout << "Info: Setting Ten Giga to " << string(b) << endl; + bool oldTenGigaEnable = tengigaEnable; + tengigaEnable = b; + + if(myDetectorType == EIGER){ + + //set parameters depending on 10g + if(tengigaEnable){ + packetsPerFrame = EIGER_TEN_GIGA_CONSTANT * dynamicRange * EIGER_MAX_PORTS; + onePacketSize = EIGER_TEN_GIGA_ONE_PACKET_SIZE; + oneDataSize = EIGER_TEN_GIGA_ONE_DATA_SIZE; + }else{ + packetsPerFrame = EIGER_ONE_GIGA_CONSTANT * dynamicRange * EIGER_MAX_PORTS; + onePacketSize = EIGER_ONE_GIGA_ONE_PACKET_SIZE; + oneDataSize = EIGER_ONE_GIGA_ONE_DATA_SIZE; + } + frameSize = onePacketSize * packetsPerFrame; + bufferSize = onePacketSize; + maxPacketsPerFile = EIGER_MAX_FRAMES_PER_FILE * packetsPerFrame; + + FILE_LOG(logDEBUG1) << dec << + "packetsPerFrame:" << packetsPerFrame << + "\nonePacketSize:" << onePacketSize << + "\noneDataSize:" << oneDataSize << + "\nframesize:" << frameSize << + "\nbufferSize:" << bufferSize << + "\nmaxPacketsPerFile:" << maxPacketsPerFile << endl; + + + + //new enable, then restart threads and resetup fifo structure + if(oldTenGigaEnable != tengigaEnable){ + + //delete threads + if(threadStarted){ + createListeningThreads(true); + createWriterThreads(true); + } + + //gui buffer + if(latestData){delete[] latestData; latestData = NULL;} + latestData = new char[frameSize]; + + //restructure fifo + if(setupFifoStructure() == FAIL) + return FAIL; + + //create threads + if(createListeningThreads() == FAIL){ + cprintf(BG_RED,"Error: Could not create listening thread\n"); + return FAIL; + } + if(createWriterThreads() == FAIL){ + cprintf(BG_RED,"Error: Could not create writer threads\n"); + return FAIL; + } + setThreadPriorities(); + } + + } + + cout << "Info: Ten Giga " << string(tengigaEnable) << endl; + + return OK; +} + + + +/************************************************************************* + * Behavioral functions*************************************************** + * They may modify the status of the receiver **************************** + *************************************************************************/ + + +/***initial functions***/ +int UDPStandardImplementation::setDetectorType(const slsReceiverDefs::detectorType d){ + FILE_LOG(logDEBUG) << __AT__ << " called"; + + cout << "Setting receiver type ..." << endl; + + deleteBaseMembers(); + deleteMembers(); + initializeBaseMembers(); + initializeMembers(); + + myDetectorType = d; + switch(myDetectorType){ + case GOTTHARD: + case PROPIX: + case MOENCH: + case EIGER: + case JUNGFRAUCTB: + case JUNGFRAU: + cout << "Info: ***** This is a " << slsDetectorBase::getDetectorType(d) << " Receiver *****" << endl; + break; + default: + cout << "Error: This is an unknown receiver type " << (int)d << endl; + return FAIL; + } + + //set detector specific variables + switch(myDetectorType){ + case GOTTHARD: + packetsPerFrame = GOTTHARD_PACKETS_PER_FRAME; + onePacketSize = GOTTHARD_ONE_PACKET_SIZE; + oneDataSize = GOTTHARD_ONE_DATA_SIZE; + frameSize = GOTTHARD_BUFFER_SIZE; + bufferSize = GOTTHARD_BUFFER_SIZE; + frameIndexMask = GOTTHARD_FRAME_INDEX_MASK; + frameIndexOffset = GOTTHARD_FRAME_INDEX_OFFSET; + packetIndexMask = GOTTHARD_PACKET_INDEX_MASK; + maxPacketsPerFile = MAX_FRAMES_PER_FILE * GOTTHARD_PACKETS_PER_FRAME; + fifoSize = GOTTHARD_FIFO_SIZE; + //footerOffset = Not applicable; + break; + case PROPIX: + packetsPerFrame = PROPIX_PACKETS_PER_FRAME; + onePacketSize = PROPIX_ONE_PACKET_SIZE; + //oneDataSize = Not applicable; + frameSize = PROPIX_BUFFER_SIZE; + bufferSize = PROPIX_BUFFER_SIZE; + frameIndexMask = PROPIX_FRAME_INDEX_MASK; + frameIndexOffset = PROPIX_FRAME_INDEX_OFFSET; + packetIndexMask = PROPIX_PACKET_INDEX_MASK; + maxPacketsPerFile = MAX_FRAMES_PER_FILE * PROPIX_PACKETS_PER_FRAME; + fifoSize = PROPIX_FIFO_SIZE; + //footerOffset = Not applicable; + break; + case MOENCH: + packetsPerFrame = MOENCH_PACKETS_PER_FRAME; + onePacketSize = MOENCH_ONE_PACKET_SIZE; + oneDataSize = MOENCH_ONE_DATA_SIZE; + frameSize = MOENCH_BUFFER_SIZE; + bufferSize = MOENCH_BUFFER_SIZE; + frameIndexMask = MOENCH_FRAME_INDEX_MASK; + frameIndexOffset = MOENCH_FRAME_INDEX_OFFSET; + packetIndexMask = MOENCH_PACKET_INDEX_MASK; + maxPacketsPerFile = MOENCH_MAX_FRAMES_PER_FILE * MOENCH_PACKETS_PER_FRAME; + fifoSize = MOENCH_FIFO_SIZE; + //footerOffset = Not applicable; + break; + case EIGER: + //assuming 1G in the beginning + packetsPerFrame = EIGER_ONE_GIGA_CONSTANT * dynamicRange * EIGER_MAX_PORTS; + onePacketSize = EIGER_ONE_GIGA_ONE_PACKET_SIZE; + oneDataSize = EIGER_ONE_GIGA_ONE_DATA_SIZE; + frameSize = onePacketSize * packetsPerFrame; + bufferSize = onePacketSize; + frameIndexMask = EIGER_FRAME_INDEX_MASK; + frameIndexOffset = EIGER_FRAME_INDEX_OFFSET; + packetIndexMask = EIGER_PACKET_INDEX_MASK; + maxPacketsPerFile = EIGER_MAX_FRAMES_PER_FILE * packetsPerFrame; + fifoSize = EIGER_FIFO_SIZE; + footerOffset = EIGER_PACKET_HEADER_SIZE + oneDataSize; + break; + case JUNGFRAUCTB: + case JUNGFRAU: + packetsPerFrame = JCTB_PACKETS_PER_FRAME; + onePacketSize = JCTB_ONE_PACKET_SIZE; + //oneDataSize = Not applicable; + frameSize = JCTB_BUFFER_SIZE; + bufferSize = JCTB_BUFFER_SIZE; + frameIndexMask = JCTB_FRAME_INDEX_MASK; + frameIndexOffset = JCTB_FRAME_INDEX_OFFSET; + packetIndexMask = JCTB_PACKET_INDEX_MASK; + maxPacketsPerFile = JFCTB_MAX_FRAMES_PER_FILE * JCTB_PACKETS_PER_FRAME; + fifoSize = JCTB_FIFO_SIZE; + //footerOffset = Not applicable; + break; + } + + //delete threads and set number of listening threads + if(myDetectorType == EIGER){ + pthread_mutex_lock(&status_mutex); + listeningThreadsMask = 0x0; + pthread_mutex_unlock(&(status_mutex)); + if(threadStarted) + createListeningThreads(true); + numberofListeningThreads = MAX_NUMBER_OF_LISTENING_THREADS; + } + + //set up fifo structure -1 for numberofJobsPerBuffer ensure it is done + numberofJobsPerBuffer = -1; + setupFifoStructure(); + + //create threads + if(createListeningThreads() == FAIL){ + cprintf(BG_RED,"Error: Could not create listening thread\n"); + exit (-1); + } + if(createWriterThreads() == FAIL){ + cprintf(BG_RED,"Error: Could not create writer threads\n"); + exit (-1); + } + setThreadPriorities(); + + //allocate for latest data (frame copy for gui) + latestData = new char[frameSize]; + + cout << " Detector type set to " << slsDetectorBase::getDetectorType(d) << endl; + cout << "Ready..." << endl; + + return OK; +} + + +/***acquisition functions***/ +void UDPStandardImplementation::resetAcquisitionCount(){ + FILE_LOG(logDEBUG) << __AT__ << " starting"; + + totalPacketsCaught = 0; + acqStarted = false; + startAcquisitionIndex = 0; + + cout << "Info: Acquisition Count has been reset" << endl; +} + + +int UDPStandardImplementation::startReceiver(char *c=NULL){ + FILE_LOG(logDEBUG) << __AT__ << " called"; + + cout << "Info: Starting Receiver" << endl; + + //reset measurement variables + measurementStarted = false; + startFrameIndex = 0; + if(!acqStarted) + currentFrameNumber = 0; //has to be zero to add to startframeindex for each scan + for(int i = 0; i < numberofListeningThreads; ++i) + totalListeningFrameCount[i] = 0; + + //create UDP sockets + if(createUDPSockets() == FAIL){ + + } + + return OK; +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + UDPStandardImplementation::UDPStandardImplementation(){ @@ -36,7 +932,7 @@ UDPStandardImplementation::UDPStandardImplementation(){ latestData = NULL; guiFileName = NULL; tengigaEnable = 0; - footer_offset = 0; + for(int i=0;i config_map){ - FILE_LOG(logWARNING) << __AT__ << " called"; - - map::const_iterator pos; - pos = config_map.find("mode"); - if (pos != config_map.end() ){ - int b; - if(!sscanf(pos->second.c_str(), "%d", &b)){ - cout << "Warning: Could not parse mode. Assuming top mode." << endl; - b = 0; - } - bottom = b!= 0; - cout << "bottom:"<< bottom << endl; - } -}; void UDPStandardImplementation::initializeMembers(){ myDetectorType = GENERIC; - maxPacketsPerFile = 0; enableFileWrite = 1; overwrite = 1; fileIndex = 0; scanTag = 0; frameIndexNeeded = 0; - acqStarted = false; - measurementStarted = false; - startFrameIndex = 0; + + frameIndex = 0; packetsCaught = 0; totalPacketsCaught = 0; @@ -119,7 +998,7 @@ void UDPStandardImplementation::initializeMembers(){ numMissingPackets = 0; startAcquisitionIndex = 0; acquisitionIndex = 0; - packetsPerFrame = 0; + frameIndexMask = 0; packetIndexMask = 0; frameIndexOffset = 0; @@ -129,39 +1008,24 @@ void UDPStandardImplementation::initializeMembers(){ shortFrame = -1; currframenum = 0; prevframenum = 0; - frameSize = 0; - bufferSize = 0; - onePacketSize = 0; - oneDataSize = 0; + guiDataReady = 0; nFrameToGui = 0; - fifosize = 0; - numJobsPerThread = -1; dataCompression = false; numListeningThreads = 1; numWriterThreads = 1; thread_started = 0; - currentListeningThreadIndex = -1; - currentWriterThreadIndex = -1; - for(int i=0;i=0) - fileIndex = i; - return getFileIndex(); -} -*/ -/* -int UDPStandardImplementation::setFrameIndexNeeded(int i){ - frameIndexNeeded = i; - return frameIndexNeeded; -} -*/ -/* -int UDPStandardImplementation::getEnableFileWrite() const{ - return enableFileWrite; -} -*/ - -/* -int UDPStandardImplementation::setEnableFileWrite(int i){ - enableFileWrite=i; - return getEnableFileWrite(); -} -*/ - -/* -int UDPStandardImplementation::getEnableOverwrite() const{ - return overwrite; -} -*/ - -/* -int UDPStandardImplementation::setEnableOverwrite(int i){ - overwrite=i; - return getEnableOverwrite(); -} -*/ /*other parameters*/ -slsReceiverDefs::runStatus UDPStandardImplementation::getStatus() const{ - FILE_LOG(logDEBUG) << __AT__ << " called, status: " << status; - - - return status; -} - - -void UDPStandardImplementation::setDetectorHostname(const char *detectorHostName){ - if(strlen(detectorHostName)) - strcpy(detHostname,detectorHostName); -} - - -char *UDPStandardImplementation::getDetectorHostname() const{ - if(!strlen(detHostname)) - return NULL; - return (char*)detHostname; -} - -void UDPStandardImplementation::setEthernetInterface(char* c){ FILE_LOG(logDEBUG) << __AT__ << " called"; - - strcpy(eth,c); -} - - -void UDPStandardImplementation::setUDPPortNo(int p){ -FILE_LOG(logDEBUG) << __AT__ << " called"; - server_port[0] = p; -} - - -void UDPStandardImplementation::setUDPPortNo2(int p){ -FILE_LOG(logDEBUG) << __AT__ << " called"; - server_port[1] = p; -} - - -int UDPStandardImplementation::getNumberOfFrames() const { - return numberOfFrames; -} - - -int32_t UDPStandardImplementation::setNumberOfFrames(int32_t fnum){ FILE_LOG(logDEBUG) << __AT__ << " called"; - - if(fnum >= 0) - numberOfFrames = fnum; - - return getNumberOfFrames(); -} - -int UDPStandardImplementation::getScanTag() const{ - return scanTag; -} - - -int32_t UDPStandardImplementation::setScanTag(int32_t stag){ FILE_LOG(logDEBUG) << __AT__ << " called"; - - if(stag >= 0) - scanTag = stag; - - return getScanTag(); -} - - -int UDPStandardImplementation::getDynamicRange() const{ - return dynamicRange; -} - -int32_t UDPStandardImplementation::setDynamicRange(int32_t dr){ FILE_LOG(logDEBUG) << __AT__ << " called"; - - int olddr = dynamicRange; - - if(dr >= 0){ - cout << "Setting Dynamic Range to " << dr << endl; - - dynamicRange = dr; - - if(myDetectorType == EIGER){ - - - if(!tengigaEnable){ - packetsPerFrame = EIGER_ONE_GIGA_CONSTANT * dynamicRange * EIGER_MAX_PORTS; - onePacketSize = EIGER_ONE_GIGA_ONE_PACKET_SIZE; - oneDataSize = EIGER_ONE_GIGA_ONE_DATA_SIZE; - }else{ - packetsPerFrame = EIGER_TEN_GIGA_CONSTANT * dynamicRange * EIGER_MAX_PORTS; - onePacketSize = EIGER_TEN_GIGA_ONE_PACKET_SIZE; - oneDataSize = EIGER_TEN_GIGA_ONE_DATA_SIZE; - } - - footer_offset = EIGER_PACKET_HEADER_SIZE + oneDataSize; - frameSize = onePacketSize * packetsPerFrame; - bufferSize = (frameSize/EIGER_MAX_PORTS) + EIGER_HEADER_LENGTH;//everything one port gets (img header plus packets) - maxPacketsPerFile = EIGER_MAX_FRAMES_PER_FILE * packetsPerFrame; - - - - if(olddr != dr){ - - //del - if(thread_started){ - createListeningThreads(true); - createWriterThreads(true); - } - for(int i=0;i=0){ - nFrameToGui = i; - setupFifoStructure(); - } - return nFrameToGui; -} - - - -int64_t UDPStandardImplementation::setAcquisitionPeriod(int64_t index){ FILE_LOG(logDEBUG) << __AT__ << " called"; - - - if(index >= 0){ - if(index != acquisitionPeriod){ - acquisitionPeriod = index; - setupFifoStructure(); - } - } - return acquisitionPeriod; -} - - -bool UDPStandardImplementation::getDataCompression(){ FILE_LOG(logDEBUG) << __AT__ << " called"; -return dataCompression;} - -int UDPStandardImplementation::enableDataCompression(bool enable){ FILE_LOG(logDEBUG) << __AT__ << " called"; - - cout << "Data compression "; - if(enable) - cout << "enabled" << endl; - else - cout << "disabled" << endl; -#ifdef MYROOT1 - cout << " WITH ROOT" << endl; -#else - cout << " WITHOUT ROOT" << endl; -#endif - //delete filter for the current number of threads - deleteFilter(); - - dataCompression = enable; - pthread_mutex_lock(&status_mutex); - writerthreads_mask = 0x0; - pthread_mutex_unlock(&(status_mutex)); - - createWriterThreads(true); - - if(enable) - numWriterThreads = MAX_NUM_WRITER_THREADS; - else - numWriterThreads = 1; - - if(createWriterThreads() == FAIL){ - cprintf(BG_RED,"ERROR: Could not create writer threads\n"); - return FAIL; - } - setThreadPriorities(); - - - if(enable) - setupFilter(); - - return OK; -} - - - - - - - - - - - - -/*other functions*/ - - -void UDPStandardImplementation::deleteFilter(){ FILE_LOG(logDEBUG) << __AT__ << " called"; - - int i; - cmSub=NULL; - - for(i=0;i(receiverdata[i], csize, sigma, sign, cmSub); - -} - - - -//LEO: it is not clear to me.. -void UDPStandardImplementation::setupFifoStructure(){ - FILE_LOG(logDEBUG) << __AT__ << " called"; - - int64_t i; - int oldn = numJobsPerThread; - - //if every nth frame mode - if(nFrameToGui) - numJobsPerThread = nFrameToGui; - - //random nth frame mode - else{ - if(!acquisitionPeriod) - i = SAMPLE_TIME_IN_NS; - else - i = SAMPLE_TIME_IN_NS/acquisitionPeriod; - if (i > MAX_JOBS_PER_THREAD) - numJobsPerThread = MAX_JOBS_PER_THREAD; - else if (i < 1) - numJobsPerThread = 1; - else - numJobsPerThread = i; - } - - //if same, return - if(oldn == numJobsPerThread) - return; - - if(myDetectorType == EIGER) - numJobsPerThread = 1; - - //otherwise memory too much if numjobsperthread is at max = 1000 - fifosize = GOTTHARD_FIFO_SIZE; - if(myDetectorType == MOENCH) - fifosize = MOENCH_FIFO_SIZE; - if(myDetectorType == PROPIX) - fifosize = PROPIX_FIFO_SIZE; - else if(myDetectorType == EIGER) - fifosize = EIGER_FIFO_SIZE * packetsPerFrame; - - if(fifosize % numJobsPerThread) - fifosize = (fifosize/numJobsPerThread)+1; - else - fifosize = fifosize/numJobsPerThread; - - if(myDetectorType == EIGER) - cout << "1 packet per buffer" << endl; - else - cout << "Number of Frames per buffer:" << numJobsPerThread << endl; -#ifdef VERBOSE - cout << "Fifo Size:" << fifosize << endl; -#endif - /* - //for testing - numJobsPerThread = 3; fifosize = 11; - */ - - for(int i=0;iisEmpty()) - fifoFree[i]->pop(buffer[i]); -#ifdef FIFO_DEBUG - //cprintf(GREEN,"%d fifostructure popped from fifofree %x\n", i, (void*)(buffer[i])); -#endif - delete fifoFree[i]; - } - if(fifo[i]) delete fifo[i]; - if(mem0[i]) free(mem0[i]); - fifoFree[i] = new CircularFifo(fifosize); - fifo[i] = new CircularFifo(fifosize); - - - int whatperbuffer = bufferSize; - if(myDetectorType == EIGER) - whatperbuffer = onePacketSize; - - //allocate memory - mem0[i]=(char*)malloc((whatperbuffer * numJobsPerThread + HEADER_SIZE_NUM_TOT_PACKETS)*fifosize); - /** shud let the client know about this */ - if (mem0[i]==NULL){ - cprintf(BG_RED,"++++++++++++++++++++++ COULD NOT ALLOCATE MEMORY FOR LISTENING !!!!!!!+++++++++++++++++++++\n"); - exit(-1); - } - - buffer[i]=mem0[i]; - //push the addresses into freed fifoFree and writingFifoFree - while (buffer[i]<(mem0[i]+(whatperbuffer * numJobsPerThread + HEADER_SIZE_NUM_TOT_PACKETS)*(fifosize-1))) { - fifoFree[i]->push(buffer[i]); -#ifdef FIFO_DEBUG - cprintf(BLUE,"%d fifostructure free pushed into fifofree %x\n", i, (void*)(buffer[i])); -#endif - buffer[i]+=(whatperbuffer * numJobsPerThread + HEADER_SIZE_NUM_TOT_PACKETS); - } - } - cout << "Fifo structure(s) reconstructed" << endl; -} - - - - @@ -1113,164 +1342,6 @@ int UDPStandardImplementation::shutDownUDPSockets(){ -int UDPStandardImplementation::createListeningThreads(bool destroy){ - FILE_LOG(logDEBUG) << __AT__ << " called"; - - int i; - void* status; - - killAllListeningThreads = 0; - - pthread_mutex_lock(&status_mutex); - listeningthreads_mask = 0x0; - pthread_mutex_unlock(&(status_mutex)); - - FILE_LOG(logDEBUG) << "Starting " << __func__ << endl; - - if(!destroy){ - - //start listening threads - cout << "Creating Listening Threads(s)"; - - currentListeningThreadIndex = -1; - - for(i = 0; i < numListeningThreads; ++i){ - sem_init(&listensmp[i],1,0); - thread_started = 0; - currentListeningThreadIndex = i; - if(pthread_create(&listening_thread[i], NULL,startListeningThread, (void*) this)){ - cout << "Could not create listening thread with index " << i << endl; - return FAIL; - } - while(!thread_started); - cout << "."; - cout << flush; - } -#ifdef VERBOSE - cout << "Listening thread(s) created successfully." << endl; -#else - cout << endl; -#endif - }else{ - cout<<"Destroying Listening Thread(s)"<= 0){ - - tengigaEnable = enable; - - if(myDetectorType == EIGER){ - - if(!tengigaEnable){ - packetsPerFrame = EIGER_ONE_GIGA_CONSTANT * dynamicRange * EIGER_MAX_PORTS; - onePacketSize = EIGER_ONE_GIGA_ONE_PACKET_SIZE; - oneDataSize = EIGER_ONE_GIGA_ONE_DATA_SIZE; - }else{ - packetsPerFrame = EIGER_TEN_GIGA_CONSTANT * dynamicRange * EIGER_MAX_PORTS; - onePacketSize = EIGER_TEN_GIGA_ONE_PACKET_SIZE; - oneDataSize = EIGER_TEN_GIGA_ONE_DATA_SIZE; - } - frameSize = onePacketSize * packetsPerFrame; - bufferSize = (frameSize/EIGER_MAX_PORTS) + EIGER_HEADER_LENGTH;//everything one port gets (img header plus packets) - maxPacketsPerFile = EIGER_MAX_FRAMES_PER_FILE * packetsPerFrame; - -#ifdef VERBOSE - cout<<"packetsPerFrame:"<= 0) - receiverBase->setFrameToGuiFrequency(index); + if(index >= 0){ + ret = receiverBase->setFrameToGuiFrequency(index); + if(ret == FAIL) + strcpy(mess, "Could not allocate memory for listening fifo\n"); + } retval=receiverBase->getFrameToGuiFrequency(); if(index>=0 && retval!=index) ret = FAIL; @@ -2107,8 +2110,11 @@ int slsReceiverTCPIPInterface::set_timer() { } else{ if(index[0] == slsReceiverDefs::FRAME_PERIOD){ - if(index[1]>=0) - receiverBase->setAcquisitionPeriod(index[1]); + if(index[1]>=0){ + ret = receiverBase->setAcquisitionPeriod(index[1]); + if(ret == FAIL) + strcpy(mess,"Could not allocate memory for listening fifo\n") + } retval=receiverBase->getAcquisitionPeriod(); }else{ if(index[1]>=0) @@ -2183,17 +2189,19 @@ int slsReceiverTCPIPInterface::enable_compression() { } else{ if(enable >= 0) - receiverBase->setDataCompressionEnable(enable); + ret = receiverBase->setDataCompressionEnable(enable); } } - if (receiverBase == NULL){ - strcpy(mess,"Receiver not set up\n"); - ret=FAIL; - }else{ - retval = receiverBase->getDataCompressionEnable(); - if(enable >= 0 && retval != enable) - ret = FAIL; + if(ret != FAIL){ + if (receiverBase == NULL){ + strcpy(mess,"Receiver not set up\n"); + ret=FAIL; + }else{ + retval = receiverBase->getDataCompressionEnable(); + if(enable >= 0 && retval != enable) + ret = FAIL; + } } } @@ -2324,8 +2332,11 @@ int slsReceiverTCPIPInterface::set_dynamic_range() { strcpy(mess,"Receiver not set up\n"); ret=FAIL; }else{ - if(dr > 0) - receiverBase->setDynamicRange(dr); + if(dr > 0){ + ret = receiverBase->setDynamicRange(dr); + if(ret == FAIL) + strcpy(mess, "Could not allocate memory for fifo or could not start listening/writing threads\n"); + } retval = receiverBase->getDynamicRange(); if(dr > 0 && retval != dr) ret = FAIL; @@ -2461,8 +2472,8 @@ int slsReceiverTCPIPInterface::enable_tengiga() { } else{ if(val >= 0) - receiverBase->setDataCompressionEnable(val); - retval=receiverBase->getDataCompressionEnable(); + ret = receiverBase->setTenGigaEnable(val); + retval=receiverBase->getTenGigaEnable(); if((val >= 0) && (val != retval)) ret = FAIL; else From e915245c104c9cb66c002ab89cb3fb1de11b0f12 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Thu, 8 Oct 2015 17:09:43 +0200 Subject: [PATCH 149/474] additional change --- .../include/UDPBaseImplementation.h | 6 +- slsReceiverSoftware/include/UDPInterface.h | 6 +- .../include/UDPStandardImplementation.h | 220 +++----- .../src/UDPBaseImplementation.cpp | 5 +- .../src/UDPStandardImplementation.cpp | 497 ++++++++---------- 5 files changed, 297 insertions(+), 437 deletions(-) diff --git a/slsReceiverSoftware/include/UDPBaseImplementation.h b/slsReceiverSoftware/include/UDPBaseImplementation.h index 293ac6763..c1de8fa6f 100644 --- a/slsReceiverSoftware/include/UDPBaseImplementation.h +++ b/slsReceiverSoftware/include/UDPBaseImplementation.h @@ -111,7 +111,7 @@ class UDPBaseImplementation : protected virtual slsReceiverDefs, public UDPInter uint64_t getFramesCaught() const; /** - * Get Current Frame Index Caught for an entire acquisition (including all scans) + * Get Current Frame Index for an entire acquisition (including all scans) * @return current frame index (represents all scans too) */ int64_t getAcquisitionIndex() const; @@ -372,8 +372,8 @@ class UDPBaseImplementation : protected virtual slsReceiverDefs, public UDPInter void startReadout(); /** - * shuts down the udp sockets - * \returns OK or FAIL + * Shuts down and deletes UDP Sockets + * @return OK or FAIL */ int shutDownUDPSockets(); diff --git a/slsReceiverSoftware/include/UDPInterface.h b/slsReceiverSoftware/include/UDPInterface.h index 65c275a29..a3766b847 100644 --- a/slsReceiverSoftware/include/UDPInterface.h +++ b/slsReceiverSoftware/include/UDPInterface.h @@ -171,7 +171,7 @@ class UDPInterface { virtual uint64_t getFramesCaught() const = 0; /** - * Get Current Frame Index Caught for an entire acquisition (including all scans) + * Get Current Frame Index for an entire acquisition (including all scans) * @return current frame index (represents all scans too) or -1 if no packets caught */ virtual int64_t getAcquisitionIndex() const = 0; @@ -430,8 +430,8 @@ class UDPInterface { virtual void startReadout() = 0; /** - * shuts down the udp sockets - * \returns OK or FAIL + * Shuts down and deletes UDP Sockets + * @return OK or FAIL */ virtual int shutDownUDPSockets() = 0; diff --git a/slsReceiverSoftware/include/UDPStandardImplementation.h b/slsReceiverSoftware/include/UDPStandardImplementation.h index 747eaad34..825806e83 100644 --- a/slsReceiverSoftware/include/UDPStandardImplementation.h +++ b/slsReceiverSoftware/include/UDPStandardImplementation.h @@ -57,8 +57,6 @@ class UDPStandardImplementation: private virtual slsReceiverDefs, public UDPBase * They access local cache of configuration or detector parameters ******* *************************************************************************/ - //***acquisition count parameters*** - /************************************************************************* * Setters *************************************************************** @@ -154,14 +152,14 @@ class UDPStandardImplementation: private virtual slsReceiverDefs, public UDPBase */ int startReceiver(char *c=NULL); - + /** + * Shuts down and deletes UDP Sockets + * @return OK or FAIL + */ + int shutDownUDPSockets(); private: - /************************************************************************* - * Setters *************************************************************** - * They modify the local cache of configuration or detector parameters *** - *************************************************************************/ //**initial parameters*** /** @@ -227,6 +225,13 @@ private: */ int createUDPSockets(); + /** + * Initializes writer variables and creates the first file + * also does the startAcquisitionCallBack + * @return OK or FAIL + */ + int setupWriter(); + //**detector parameters*** @@ -277,19 +282,27 @@ private: /** Footer offset from start of Packet*/ int footerOffset; + //***File parameters*** /** Maximum Packets Per File **/ int maxPacketsPerFile; + /** If file created successfully for all Writer Threads */ + bool fileCreateSuccess; - //***acquisition indices parameters*** - /** Frame Number of First Frame of an Acquisition */ + + + //***acquisition indices/count parameters*** + /** Frame Number of First Frame of an entire Acquisition (including all scans) */ uint64_t startAcquisitionIndex; /** Frame index at start of each real time acquisition (eg. for each scan) */ uint64_t startFrameIndex; + /** Actual current frame index of each time acquisition (eg. for each scan) */ + uint64_t frameIndex; + /** Current Frame Number */ uint64_t currentFrameNumber; @@ -302,6 +315,19 @@ private: /** Total Frame Count listened to by listening threads */ int totalListeningFrameCount[MAX_NUMBER_OF_LISTENING_THREADS]; + /** Pckets currently in current file, starts new file when it reaches max */ + uint32_t packetsInFile; + + /** Number of Missing Packets per buffer*/ + uint32_t numMissingPackets; + + /** Total Number of Missing Packets in acquisition*/ + uint32_t numTotMissingPackets; + + /** Number of Missing Packets in file */ + uint32_t numTotMissingPacketsInFile; + + @@ -318,15 +344,37 @@ private: /** Circular fifo to point to address already written and freed, to be reused */ CircularFifo* fifoFree[MAX_NUMBER_OF_LISTENING_THREADS]; + /** UDP Sockets - Detector to Receiver */ + genericSocket* udpSocket[MAX_NUMBER_OF_LISTENING_THREADS]; + + /** File Descriptor */ + FILE *sfilefd; + /** Number of Jobs Per Buffer */ int numberofJobsPerBuffer; /** Fifo Depth */ uint32_t fifoSize; - /** Current Frame copied for Gui */ + + //***receiver to GUI parameters*** + /** Current Frame copied for GUI */ char* latestData; + /** If Data to be sent to GUI is ready */ + bool guiDataReady; + + /** Pointer to data to be sent to GUI */ + char* guiData; + + /** Pointer to file name to be sent to GUI */ + char guiFileName[MAX_STR_LENGTH]; + + /** Semaphore to synchronize Writer and GuiReader threads*/ + sem_t writerGuiSemaphore; + + + //***general and listening thread parameters*** @@ -382,7 +430,6 @@ private: - //***filter parameters*** /** Common Mode Subtraction Enable FIXME: Always false, only moench uses, Ask Anna */ bool commonModeSubtractionEnable; @@ -404,6 +451,12 @@ private: pthread_mutex_t status_mutex; + //***callback*** + /** The action which decides what the user and default responsibilities to save data are + * 0 raw data ready callback takes care of open,close,write file + * 1 callback writes file, we have to open, close it + * 2 we open, close, write file, callback does not do anything */ + int cbAction; @@ -422,89 +475,6 @@ private: - - - - - - - /** - * Set receiver type - * @param det detector type - * Returns success or FAIL - */ - int setDetectorType(detectorType det); - - - //Frame indices and numbers caught - /** - * Returns the frame index at start of entire acquisition (including all scans) - */ - //uint32_t getStartAcquisitionIndex(); - - /** - * Returns if acquisition started - */ - //bool getAcquistionStarted(); - - /** - * Returns the frame index at start of each real time acquisition (eg. for each scan) - */ - //uint32_t getStartFrameIndex(); - - /** - * Returns current Frame Index for each real time acquisition (eg. for each scan) - */ - //uint32_t getFrameIndex(); - - /** - * Returns if measurement started - */ - //bool getMeasurementStarted(); - - /** - * Resets the Total Frames Caught - * This is how the receiver differentiates between entire acquisitions - * Returns 0 - */ - //void resetTotalFramesCaught(); - - - - - -//other parameters - - /** - * abort acquisition with minimum damage: close open files, cleanup. - * does nothing if state already is 'idle' - */ - void abort() {}; - - /** - * Returns status of receiver: idle, running or error - */ - runStatus getStatus() const; - - /** - * Set detector hostname - * @param c hostname - */ - void setDetectorHostname(const char *detectorHostName); - - - - /** - * enable 10Gbe - @param enable 1 for 10Gbe or 0 for 1 Gbe, -1 to read out - \returns enable for 10Gbe - */ - int enableTenGiga(int enable = -1); - - - -//other functions - /** * Returns the buffer-current frame read by receiver * @param c pointer to current file name @@ -520,12 +490,6 @@ private: */ void closeFile(int ithr = -1); - /** - * Starts Receiver - starts to listen for packets - * @param message is the error message if there is an error - * Returns success - */ - int startReceiver(char message[]); /** * Stops Receiver - stops listening for packets @@ -538,21 +502,9 @@ private: */ void startReadout(); - /** - * shuts down the udp sockets - * \returns if success or fail - */ - int shutDownUDPSockets(); + private: - - /* - void not_implemented(string method_name){ - std::cout << "[WARNING] Method " << method_name << " not implemented!" << std::endl; - }; - */ - - /** @@ -562,12 +514,6 @@ private: void copyFrameToGui(char* startbuf[], char* buf=NULL); - /** - * initializes variables and creates the first file - * also does the startAcquisitionCallBack - * \returns FAIL or OK - */ - int setupWriter(); /** * Creates new tree and file for compression @@ -694,42 +640,18 @@ private: const static uint16_t missingPacketValue = 0xFFFF; - /** UDP Socket between Receiver and Detector */ - genericSocket* udpSocket[MAX_NUM_LISTENING_THREADS]; - - /** Complete File name */ +/** Complete File name */ char savefilename[MAX_STR_LENGTH]; - /** Actual current frame index of each time acquisition (eg. for each scan) */ - uint32_t frameIndex; - /** Pckets currently in current file, starts new file when it reaches max */ - uint32_t packetsInFile; - - /** Number of missing packets in acquisition*/ - uint32_t numTotMissingPackets; - - /** Number of missing packets in file (sometimes packetsinFile is incorrect due to padded packets for eiger)*/ - uint32_t numTotMissingPacketsInFile; - - /** Number of missing packets per buffer*/ - uint32_t numMissingPackets; /** Previous Frame number from buffer */ int prevframenum; - /** gui data ready */ - int guiDataReady; - /** points to the data to send to gui */ - char* guiData; - /** points to the filename to send to gui */ - char* guiFileName; -/** OK if file created was successful */ - int ret_createfile; // TODO: not properly sure where to put these... /** structure of an eiger image header*/ @@ -738,8 +660,7 @@ private: //semaphores - /** semaphore to synchronize writer and guireader threads */ - sem_t smp; + //mutex /** guiDataReady mutex */ @@ -751,8 +672,6 @@ private: /** mutex for writing data to file */ pthread_mutex_t write_mutex; - /** File Descriptor */ - FILE *sfilefd; //filter @@ -766,11 +685,6 @@ private: #endif - /** The action which decides what the user and default responsibilites to save data are - * 0 raw data ready callback takes care of open,close,write file - * 1 callback writes file, we have to open, close it - * 2 we open, close, write file, callback does not do anything */ - int cbAction; public: diff --git a/slsReceiverSoftware/src/UDPBaseImplementation.cpp b/slsReceiverSoftware/src/UDPBaseImplementation.cpp index 0c1c30248..ec5c27ad5 100644 --- a/slsReceiverSoftware/src/UDPBaseImplementation.cpp +++ b/slsReceiverSoftware/src/UDPBaseImplementation.cpp @@ -286,10 +286,7 @@ int UDPBaseImplementation::setDataCompressionEnable(const bool b){ void UDPBaseImplementation::setUDPPortNumber(const uint32_t i){ FILE_LOG(logDEBUG) << __AT__ << " starting"; - if(bottomEnable) - udpPortNum[1] = i; - else - udpPortNum[0] = i; + udpPortNum[0] = i; FILE_LOG(logINFO) << "udpPortNum[0]:" << udpPortNum[0]; } diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 0f4290c9c..5901e96a3 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -58,16 +58,22 @@ void UDPStandardImplementation::deleteMembers(){ FILE_LOG(logDEBUG) << __AT__ << " starting"; cout << "Info: Deleting member pointers" << endl; + shutDownUDPSockets(); + closeFile(); //filter deleteFilter(); + for(int i=0; igetErrorStatus(); + if(!iret){ + cout << "Info: UDP port opened at port " << port[i] << endl; + }else{ +#ifdef VERBOSE + cprintf(BG_RED,"Error: Could not create UDP socket on port %d error: %d\n", port[i], iret); +#endif + shutDownUDPSockets(); + return FAIL; + } + } + + cout << "Info: UDP socket(s) created successfully." << endl; + cout << "Info: Listener Ready ..." << endl; return OK; } +int UDPStandardImplementation::setupWriter(){ + FILE_LOG(logDEBUG) << __AT__ << " starting"; + + //acquisition start call back returns enable write + cbAction = DO_EVERYTHING; + if (startAcquisitionCallBack) + cbAction=startAcquisitionCallBack(filePath,fileName,fileIndex,bufferSize,pStartAcquisition); + + if(cbAction < DO_EVERYTHING){ + cout << "Info: Call back activated. Data saving must be taken care of by user in call back." << endl; + if (rawDataReadyCallBack) + cout << "Info: Data Write has been defined externally" << endl; + }else if(!fileWriteEnable) + cout << "Info: Data will not be saved" << endl; + + + + //creating first file + //setting all value to 1 + pthread_mutex_lock(&status_mutex); + for(int i=0; i config_map){ FILE_LOG(logDEBUG) << __AT__ << " starting"; @@ -869,25 +984,113 @@ int UDPStandardImplementation::startReceiver(char *c=NULL){ cout << "Info: Starting Receiver" << endl; + + //RESET //reset measurement variables measurementStarted = false; startFrameIndex = 0; + frameIndex = 0; if(!acqStarted) currentFrameNumber = 0; //has to be zero to add to startframeindex for each scan for(int i = 0; i < numberofListeningThreads; ++i) totalListeningFrameCount[i] = 0; + packetsCaught = 0; + numMissingPackets = 0; + numTotMissingPackets = 0; + numTotMissingPacketsInFile = 0; + //reset file parameters + packetsInFile = 0; + if(sfilefd){ + fclose(sfilefd); + sfilefd = NULL; + } + //reset gui variables + guiData = NULL; + guiDataReady=0; + strcpy(guiFileName,""); + //reset masks + pthread_mutex_lock(&status_mutex); + writerThreadsMask = 0x0; + createFileMask = 0x0; + fileCreateSuccess = false; + pthread_mutex_unlock(&status_mutex); + + + //Print Receiver Configuration + cout << "Info: ***Receiver Configuration***" << endl; + cout << "Info: Max Packets Per File:" << maxPacketsPerFile << endl; + cout << "Info: Data Compression has been " << stringEnable(dataCompressionEnable) << endl; + if(myDetectorType != EIGER) + cout << "Info: Number of Jobs Per Buffer: " << numberofJobsPerBuffer << endl; + if(FrameToGuiFrequency) + cout << "Info: Frequency of frames sent to gui" << FrameToGuiFrequency << endl; + + //create UDP sockets if(createUDPSockets() == FAIL){ - + strcpy(c,"Could not create UDP Socket(s).\n"); + cout << endl; + cout << "Error: "<< c << endl; + return FAIL; } + if(setupWriter() == FAIL){ + //stop udp socket + shutDownUDPSockets(); + sprintf(c,"Could not create file %s.\n",savefilename); + cout << endl; + cout << "Error: "<< c << endl; + return FAIL; + } + + + //For compression, done to give the gui some proper name instead of always the last file name + if(dataCompressionEnable) + sprintf(savefilename, "%s/%s_fxxx_%d_xx.root", filePath,fileName,fileIndex); + + //initialize semaphore to synchronize between writer and gui reader threads + sem_init(&writerGuiSemaphore,1,0); + + //status and thread masks + pthread_mutex_lock(&status_mutex); + status = RUNNING; + for(int i=0;iShutDownSocket(); + delete udpSocket[i]; + udpSocket[i] = NULL; + } + } + return OK; +} @@ -929,16 +1132,13 @@ int UDPStandardImplementation::startReceiver(char *c=NULL){ UDPStandardImplementation::UDPStandardImplementation(){ thread_started = 0; eth = NULL; - latestData = NULL; - guiFileName = NULL; + tengigaEnable = 0; for(int i=0;igetErrorStatus(); - if(!iret){ - cout << "UDP port opened at port " << port[i] << endl; - }else{ -#ifdef VERBOSE - cprintf(BG_RED,"Could not create UDP socket on port %d error: %d\n", port[i], iret); -#endif - shutDownUDPSockets(); - return FAIL; - } - } - - - - return OK; -} - - - - - - - -int UDPStandardImplementation::shutDownUDPSockets(){ - FILE_LOG(logDEBUG) << __AT__ << " called"; - - for(int i=0;iShutDownSocket(); - delete udpSocket[i]; - udpSocket[i] = NULL; - } - } - return OK; -} - - - - - - - -int UDPStandardImplementation::setupWriter(){ - FILE_LOG(logDEBUG) << __AT__ << " called"; - - //reset writing thread variables - packetsInFile=0; - numTotMissingPackets = 0; - numTotMissingPacketsInFile = 0; - numMissingPackets = 0; - packetsCaught=0; - frameIndex=0; - if(sfilefd) {cprintf(RED,"**FILE not closed!\n");fclose(sfilefd);sfilefd=NULL;} - guiData = NULL; - guiDataReady=0; - strcpy(guiFileName,""); - cbAction = DO_EVERYTHING; - - pthread_mutex_lock(&status_mutex); - writerthreads_mask = 0x0; - createfile_mask = 0x0; - ret_createfile = OK; - pthread_mutex_unlock(&status_mutex); - - //printouts - cout << "Max Packets Per File:" << maxPacketsPerFile << endl; - if (rawDataReadyCallBack) - cout << "Note: Data Write has been defined exernally" << endl; - if (dataCompression) - cout << "Data Compression is enabled with " << numJobsPerThread << " number of jobs per thread" << endl; - if(nFrameToGui) - cout << "Sending every " << nFrameToGui << "th frame to gui" << endl; - - - - //acquisition start call back returns enable write - if (startAcquisitionCallBack) - cbAction=startAcquisitionCallBack(filePath,fileName,fileIndex,bufferSize,pStartAcquisition); - - if(cbAction < DO_EVERYTHING) - cout << endl << "Note: Call back activated. Data saving must be taken care of by user in call back." << endl; - else if(enableFileWrite==0) - cout << endl << "Note: Data will not be saved" << endl; - - - - //creating first file - - //mask - pthread_mutex_lock(&status_mutex); - for(int i=0;i Date: Tue, 13 Oct 2015 15:22:30 +0200 Subject: [PATCH 150/474] some more --- .../include/UDPBaseImplementation.h | 13 +- slsReceiverSoftware/include/UDPInterface.h | 10 +- .../include/UDPStandardImplementation.h | 371 ++- slsReceiverSoftware/include/logger.h | 6 + .../src/UDPBaseImplementation.cpp | 2 +- .../src/UDPStandardImplementation.cpp | 2256 ++++++++--------- 6 files changed, 1241 insertions(+), 1417 deletions(-) diff --git a/slsReceiverSoftware/include/UDPBaseImplementation.h b/slsReceiverSoftware/include/UDPBaseImplementation.h index c1de8fa6f..43f98b511 100644 --- a/slsReceiverSoftware/include/UDPBaseImplementation.h +++ b/slsReceiverSoftware/include/UDPBaseImplementation.h @@ -381,10 +381,10 @@ class UDPBaseImplementation : protected virtual slsReceiverDefs, public UDPInter * Get the buffer-current frame read by receiver * @param c pointer to current file name * @param raw address of pointer, pointing to current frame to send to gui - * @param startAcquisitionIndex start index of the acquisition - * @param startFrameIndex start index of the scan + * @param startAcq start index of the acquisition + * @param startFrame start index of the scan */ - void readFrame(char* c,char** raw, uint64_t &startAcquisitionIndex, uint64_t &startFrameIndex); + void readFrame(char* c,char** raw, uint64_t &startAcq, uint64_t &startFrame); /** * abort acquisition with minimum damage: close open files, cleanup. @@ -393,8 +393,8 @@ class UDPBaseImplementation : protected virtual slsReceiverDefs, public UDPInter void abort(); //FIXME: needed, isn't stopReceiver enough? /** - * Closes all files - * @param i thread index, -1 for all threads + * Closes file / all files(if multiple files) + * @param i thread index (if multiple files used eg. root files) -1 for all threads */ void closeFile(int i = -1); @@ -438,6 +438,9 @@ class UDPBaseImplementation : protected virtual slsReceiverDefs, public UDPInter protected: + /************************************************************************* + * Class Members ********************************************************* + *************************************************************************/ //**detector parameters*** /** detector type */ detectorType myDetectorType; diff --git a/slsReceiverSoftware/include/UDPInterface.h b/slsReceiverSoftware/include/UDPInterface.h index a3766b847..b62ad2eb0 100644 --- a/slsReceiverSoftware/include/UDPInterface.h +++ b/slsReceiverSoftware/include/UDPInterface.h @@ -439,10 +439,10 @@ class UDPInterface { * Get the buffer-current frame read by receiver * @param c pointer to current file name * @param raw address of pointer, pointing to current frame to send to gui - * @param startAcquisitionIndex start index of the acquisition - * @param startFrameIndex start index of the scan + * @param startAcq start index of the acquisition + * @param startFrame start index of the scan */ - virtual void readFrame(char* c,char** raw, uint64_t &startAcquisitionIndex, uint64_t &startFrameIndex)=0; + virtual void readFrame(char* c,char** raw, uint64_t &startAcq, uint64_t &startFrame)=0; /** * abort acquisition with minimum damage: close open files, cleanup. @@ -451,8 +451,8 @@ class UDPInterface { virtual void abort() = 0; //FIXME: needed, isnt stopReceiver enough? /** - * Closes all files - * @param i thread index, -1 for all threads + * Closes file / all files(if multiple files) + * @param i thread index (if multiple files used eg. root files) -1 for all threads */ virtual void closeFile(int i = -1) = 0; diff --git a/slsReceiverSoftware/include/UDPStandardImplementation.h b/slsReceiverSoftware/include/UDPStandardImplementation.h index 825806e83..cbd46d433 100644 --- a/slsReceiverSoftware/include/UDPStandardImplementation.h +++ b/slsReceiverSoftware/include/UDPStandardImplementation.h @@ -153,12 +153,63 @@ class UDPStandardImplementation: private virtual slsReceiverDefs, public UDPBase int startReceiver(char *c=NULL); /** + * Overridden method + * Stop Listening for Packets + * Calls startReadout(), which stops listening and sets status to Transmitting + * When it has read every frame in buffer,it returns with the status Run_Finished + * Pre: status is running, semaphores have been instantiated, + * Post: udp sockets shut down, status is idle, semaphores destroyed + */ + void stopReceiver(); + + /** + * Overridden method + * Stop Listening to Packets + * and sets status to Transmitting + * Pre: status is running, udp sockets have been initialized, stop receiver initiated + * Post:udp sockets closed, status is transmitting + */ + void startReadout(); + + /** + * Overridden method * Shuts down and deletes UDP Sockets * @return OK or FAIL */ int shutDownUDPSockets(); + /** + * Overridden method + * Get the buffer-current frame read by receiver + * @param c pointer to current file name + * @param raw address of pointer, pointing to current frame to send to gui + * @param startAcq start index of the acquisition + * @param startFrame start index of the scan + */ + void readFrame(char* c,char** raw, uint64_t &startAcq, uint64_t &startFrame); + + /** + * Overridden method + * Closes file / all files(data compression involves multiple files) + * @param i thread index valid for datacompression using root files, -1 for all threads + */ + void closeFile(int i = -1); + private: + /************************************************************************* + * Getters *************************************************************** + * They access local cache of configuration or detector parameters ******* + *************************************************************************/ + +/* + uint64_t (*getFrameNumber)(); + uint64_t eigerGetFrameNumber(); + uint64_t generalGetFrameNumber(); + getframenumber = &generalgetframenumber; + if(dettpe == eiger) getframenumber = &eigerGerFramenumber; + + call using getframenumber(); +*/ //**initial parameters*** @@ -194,6 +245,19 @@ private: */ void initializeFilter(); + /** + * Set up the Fifo Structure for processing buffers + * between listening and writer threads + * @return OK or FAIL + */ + int setupFifoStructure(); + + + + /************************************************************************* + * Listening and Writing Threads ***************************************** + *************************************************************************/ + /** * Create Listening Threads * @param destroy is true to destroy all the threads @@ -212,13 +276,6 @@ private: */ void setThreadPriorities(); - /** - * Set up the Fifo Structure for processing buffers - * between listening and writer threads - * @return OK or FAIL - */ - int setupFifoStructure(); - /** * Creates UDP Sockets * @return OK or FAIL @@ -232,7 +289,87 @@ private: */ int setupWriter(); + /** + * Creates new file + * @return OK or FAIL + */ + int createNewFile(); + /** + * Static function - Starts Listening Thread of this object + * @param this_pointer pointer to this object + */ + static void* startListeningThread(void *this_pointer); + + /** + * Static function - Starts Writing Thread of this object + * @param this_pointer pointer to this object + */ + static void* startWritingThread(void *this_pointer); + + /** + * Thread that listens to packets + * It pops the fifofree for free addresses, listens to packets and pushes them into the fifo + * This is continuously looped for each buffer in a nested loop, which is again looped for each acquisition + * Exits only for changing dynamic range, 10G parameters etc and recreated + * + */ + void startListening(); + + /** + * Thread started which writes packets to file. + * It pops the fifo, processes and writes packets to file and pushes the addresses into the fifoFree + * This is continuously looped for each buffer in a nested loop, which is again looped for each acquisition + * Exits only for changing dynamic range, 10G parameters etc and recreated + * + */ + void startWriting(); + + /** + * Called by startListening + * Listens to buffer, until packet(s) received or shutdownUDPsocket called by client + * Also copies carryovers from previous frame in front of buffer (gotthard and moench) + * For eiger, it ignores packets less than onePacketSize + * @param ithread listening thread index + * @param lSize number of bytes to listen to + * @param cSize number of bytes carried on from previous buffer + * @param temp temporary storage of previous buffer + * @return the number of bytes actually received + */ + int prepareAndListenBuffer(int ithread, int lSize, int cSize, char* temp); + + /** + * Called by startListening + * Its called for the first packet of a scan or acquistion + * Sets the startframeindices and the variables to know if acquisition started + * @param ithread listening thread number + */ + void startFrameIndices(int ithread); + + /** + * Called by prepareAndListenBuffer + * This is called when udp socket is shut down by client + * It pushes ffff instead of packet number into fifo + * to inform writers about the end of listening session + * Then sets the listening mask so that it stops listening and wait for next acquisition trigger + * @param ithread listening thread number + * @param numbytes number of bytes received + */ + void stopListening(int ithread, int numbytes); + + /* + * Called by startListening for gotthard and moench to handle split frames + * It processes listening thread buffers by ensuring split frames are in the same buffer + * @param ithread listening thread index + * @param cSize number of bytes carried over to the next buffer to reunite with split frame + * @param temp temporary buffer to store the split frame + * @return packet count + */ + uint32_t processListeningBuffer(int ithread, int cSize,char* temp); + + /************************************************************************* + * Class Members ********************************************************* + *************************************************************************/ //**detector parameters*** /** @@ -284,7 +421,18 @@ private: //***File parameters*** - /** Maximum Packets Per File **/ +#ifdef MYROOT1 + /** Tree where the hits are stored */ + TTree *myTree[MAX_NUMBER_OF_WRITER_THREADS]; + + /** File where the tree is saved */ + TFile *myFile[MAX_NUMBER_OF_WRITER_THREADS]; +#endif + + /** Complete File name */ + char completeFileName[MAX_STR_LENGTH]; + + /** Maximum Packets Per File **/ int maxPacketsPerFile; /** If file created successfully for all Writer Threads */ @@ -306,6 +454,9 @@ private: /** Current Frame Number */ uint64_t currentFrameNumber; + /** Previous Frame number from buffer to calculate loss */ + uint64_t previousFrameNumber; + /* Acquisition started */ bool acqStarted; @@ -356,6 +507,11 @@ private: /** Fifo Depth */ uint32_t fifoSize; + /** Missing Packet identifier value */ + const static uint16_t missingPacketValue = 0xFFFF; + + /** Dummy Packet identifier value */ + const static uint32_t dummyPacketValue = 0xFFFFFFFF; //***receiver to GUI parameters*** /** Current Frame copied for GUI */ @@ -381,6 +537,9 @@ private: /** Ensures if threads created successfully */ bool threadStarted; + /** Current Thread Index*/ + int currentThreadIndex; + /** Number of Listening Threads */ int numberofListeningThreads; @@ -414,9 +573,6 @@ private: /** Semaphores Synchronizing Writer Threads */ sem_t writerSemaphore[MAX_NUMBER_OF_WRITER_THREADS]; - /** Current Writer Thread Index*/ - int currentWriterThreadIndex; - /** Mask with each bit indicating status of each writer thread */ volatile uint32_t writerThreadsMask; @@ -447,9 +603,17 @@ private: //***mutex*** - /** mutex for status */ - pthread_mutex_t status_mutex; + /** Status mutex */ + pthread_mutex_t statusMutex; + /** Writing mutex */ + pthread_mutex_t writeMutex; + + /** GuiDataReady Mutex */ + pthread_mutex_t dataReadyMutex; + + /** Progress (currentFrameNumber) Mutex */ + pthread_mutex_t progressMutex; //***callback*** /** The action which decides what the user and default responsibilities to save data are @@ -475,32 +639,6 @@ private: - /** - * Returns the buffer-current frame read by receiver - * @param c pointer to current file name - * @param raw address of pointer, pointing to current frame to send to gui - * @param startAcquisitionIndex is the start index of the acquisition - * @param startFrameIndex is the start index of the scan - */ - void readFrame(char* c,char** raw, uint32_t &startAcquisitionIndex, uint32_t &startFrameIndex); - - /** - * Closes all files - * @param ithr thread index - */ - void closeFile(int ithr = -1); - - - /** - * Stops Receiver - stops listening for packets - * Returns success - */ - int stopReceiver(); - - /** set status to transmitting and - * when fifo is empty later, sets status to run_finished - */ - void startReadout(); @@ -513,8 +651,6 @@ private: */ void copyFrameToGui(char* startbuf[], char* buf=NULL); - - /** * Creates new tree and file for compression * @param ithr thread number @@ -523,40 +659,6 @@ private: */ int createCompressionFile(int ithr, int iframe); - /** - * Creates new file - *\returns OK for succces or FAIL for failure - */ - int createNewFile(); - - /** - * Static function - Thread started which listens to packets. - * Called by startReceiver() - * @param this_pointer pointer to this object - */ - static void* startListeningThread(void *this_pointer); - - /** - * Static function - Thread started which writes packets to file. - * Called by startReceiver() - * @param this_pointer pointer to this object - */ - static void* startWritingThread(void *this_pointer); - - /** - * Thread started which listens to packets. - * Called by startReceiver() - * - */ - int startListening(); - - /** - * Thread started which writes packets to file. - * Called by startReceiver() - * - */ - int startWriting(); - /** * Writing to file without compression * @param buf is the address of buffer popped out of fifo @@ -565,25 +667,6 @@ private: */ void writeToFile_withoutCompression(char* buf[],int numpackets, uint32_t framenum); - /** - * Its called for the first packet of a scan or acquistion - * Sets the startframeindices and the variables to know if acquisition started - * @param ithread listening thread number - * @param numbytes number of bytes it listened to - */ - void startFrameIndices(int ithread, int numbytes); - - /** - * This is called when udp socket is shut down - * It pops ffff instead of packet number into fifo - * to inform writers about the end of listening session - * @param ithread listening thread number - * @param rc number of bytes received - * @param pc packet count - * @param t total packets listened to - */ - void stopListening(int ithread, int rc, int &pc, int &t); - /** * When acquisition is over, this is called * @param ithread listening thread number @@ -615,110 +698,10 @@ private: - - - - - - - - - - - - - - - - - - - - - - /** missing packet identifier value */ - const static uint16_t missingPacketValue = 0xFFFF; - - -/** Complete File name */ - char savefilename[MAX_STR_LENGTH]; - - - - /** Previous Frame number from buffer */ - int prevframenum; - - - - - - - // TODO: not properly sure where to put these... - /** structure of an eiger image header*/ - - - - -//semaphores - - -//mutex - /** guiDataReady mutex */ - pthread_mutex_t dataReadyMutex; - - /** mutex for progress variable currframenum */ - pthread_mutex_t progress_mutex; - - /** mutex for writing data to file */ - pthread_mutex_t write_mutex; - //filter -#ifdef MYROOT1 - /** Tree where the hits are stored */ - TTree *myTree[MAX_NUM_WRITER_THREADS]; - - /** File where the tree is saved */ - TFile *myFile[MAX_NUM_WRITER_THREADS]; -#endif - - - - -public: - - - /** - callback arguments are - filepath - filename - fileindex - datasize - - return value is - 0 callback takes care of open,close,wrie file - 1 callback writes file, we have to open, close it - 2 we open, close, write file, callback does not do anything - */ - void registerCallBackStartAcquisition(int (*func)(char*, char*,int, int, void*),void *arg){startAcquisitionCallBack=func; pStartAcquisition=arg;}; - - /** - callback argument is - toatal frames caught - */ - void registerCallBackAcquisitionFinished(void (*func)(int, void*),void *arg){acquisitionFinishedCallBack=func; pAcquisitionFinished=arg;}; - - /** - args to raw data ready callback are - framenum - datapointer - datasize in bytes - file descriptor - guidatapointer (NULL, no data required) - */ - void registerCallBackRawDataReady(void (*func)(int, char*, int, FILE*, char*, void*),void *arg){rawDataReadyCallBack=func; pRawDataReady=arg;}; }; diff --git a/slsReceiverSoftware/include/logger.h b/slsReceiverSoftware/include/logger.h index cba284fb1..5e964da27 100644 --- a/slsReceiverSoftware/include/logger.h +++ b/slsReceiverSoftware/include/logger.h @@ -23,6 +23,12 @@ #define TOSTRING(x) STRINGIFY(x) #define MYCONCAT(x,y) #define __AT__ string(__FILE__) + string("::") + string(__func__) + string("(): ") +#define __SHORT_FORM_OF_FILE__ \ +(strrchr(__FILE__,'/') \ +? strrchr(__FILE__,'/')+1 \ +: __FILE__ \ +) +#define __SHORT_AT__ string(__SHORT_FORM_OF_FILE__) + string("::") + string(__func__) + string("(): ") //":" TOSTRING(__LINE__) diff --git a/slsReceiverSoftware/src/UDPBaseImplementation.cpp b/slsReceiverSoftware/src/UDPBaseImplementation.cpp index ec5c27ad5..75f7fa244 100644 --- a/slsReceiverSoftware/src/UDPBaseImplementation.cpp +++ b/slsReceiverSoftware/src/UDPBaseImplementation.cpp @@ -37,7 +37,7 @@ UDPBaseImplementation::UDPBaseImplementation(){ //***connection parameters*** strcpy(eth,""); - for(int i=0;i /proc/sys/net/core/rmem_max")) + cout << "Warning: No root permission to change socket receiver buffer size in file /proc/sys/net/core/rmem_max" << endl; + else if(system("echo 250000 > /proc/sys/net/core/netdev_max_backlog")) + cout << "Warning: No root permission to change max length of input queue in file /proc/sys/net/core/netdev_max_backlog" << endl; + /** permanent setting by heiner + net.core.rmem_max = 104857600 # 100MiB + net.core.netdev_max_backlog = 250000 + sysctl -p + // from the manual + sysctl -w net.core.rmem_max=16777216 + sysctl -w net.core.netdev_max_backlog=250000 + */ } UDPStandardImplementation::~UDPStandardImplementation(){ - FILE_LOG(logDEBUG) << __AT__ << " called"; + FILE_LOG(logDEBUG1) << __AT__ << " called"; deleteMembers(); } @@ -49,13 +69,13 @@ UDPStandardImplementation::~UDPStandardImplementation(){ /***initial parameters***/ void UDPStandardImplementation::deleteBaseMembers(){ - FILE_LOG(logDEBUG) << __AT__ << " starting"; + FILE_LOG(logDEBUG1) << __AT__ << " starting"; UDPBaseImplementation::~UDPBaseImplementation(); } void UDPStandardImplementation::deleteMembers(){ - FILE_LOG(logDEBUG) << __AT__ << " starting"; + FILE_LOG(logDEBUG1) << __AT__ << " starting"; cout << "Info: Deleting member pointers" << endl; shutDownUDPSockets(); @@ -77,7 +97,7 @@ void UDPStandardImplementation::deleteMembers(){ } void UDPStandardImplementation::deleteFilter(){ - FILE_LOG(logDEBUG) << __AT__ << " starting"; + FILE_LOG(logDEBUG1) << __AT__ << " starting"; moenchCommonModeSubtraction = NULL; for(int i=0; igetErrorStatus(); - if(!iret){ - cout << "Info: UDP port opened at port " << port[i] << endl; - }else{ -#ifdef VERBOSE - cprintf(BG_RED,"Error: Could not create UDP socket on port %d error: %d\n", port[i], iret); -#endif - shutDownUDPSockets(); - return FAIL; - } - } - - cout << "Info: UDP socket(s) created successfully." << endl; - cout << "Info: Listener Ready ..." << endl; - - return OK; -} - - - -int UDPStandardImplementation::setupWriter(){ - FILE_LOG(logDEBUG) << __AT__ << " starting"; - - //acquisition start call back returns enable write - cbAction = DO_EVERYTHING; - if (startAcquisitionCallBack) - cbAction=startAcquisitionCallBack(filePath,fileName,fileIndex,bufferSize,pStartAcquisition); - - if(cbAction < DO_EVERYTHING){ - cout << "Info: Call back activated. Data saving must be taken care of by user in call back." << endl; - if (rawDataReadyCallBack) - cout << "Info: Data Write has been defined externally" << endl; - }else if(!fileWriteEnable) - cout << "Info: Data will not be saved" << endl; - - - - //creating first file - //setting all value to 1 - pthread_mutex_lock(&status_mutex); - for(int i=0; i config_map){ - FILE_LOG(logDEBUG) << __AT__ << " starting"; + FILE_LOG(logDEBUG1) << __AT__ << " starting"; map::const_iterator pos; pos = config_map.find("mode"); @@ -596,7 +376,7 @@ void UDPStandardImplementation::configure(map config_map){ /***file parameters***/ int UDPStandardImplementation::setDataCompressionEnable(const bool b){ - FILE_LOG(logDEBUG) << __AT__ << " starting"; + FILE_LOG(logDEBUG1) << __AT__ << " starting"; cout << "Info: Setting up Data Compression Enable to " << stringEnable(b); #ifdef MYROOT1 @@ -609,9 +389,9 @@ int UDPStandardImplementation::setDataCompressionEnable(const bool b){ dataCompressionEnable = b; //-- create writer threads depending on enable - pthread_mutex_lock(&status_mutex); + pthread_mutex_lock(&statusMutex); writerThreadsMask = 0x0; - pthread_mutex_unlock(&(status_mutex)); + pthread_mutex_unlock(&(statusMutex)); createWriterThreads(true); if(b) @@ -638,7 +418,7 @@ int UDPStandardImplementation::setDataCompressionEnable(const bool b){ /***acquisition parameters***/ void UDPStandardImplementation::setShortFrameEnable(const int i){ - FILE_LOG(logDEBUG) << __AT__ << " called"; + FILE_LOG(logDEBUG1) << __AT__ << " called"; shortFrameEnable = i; @@ -675,7 +455,7 @@ void UDPStandardImplementation::setShortFrameEnable(const int i){ int UDPStandardImplementation::setFrameToGuiFrequency(const uint32_t i){ - FILE_LOG(logDEBUG) << __AT__ << " called"; + FILE_LOG(logDEBUG1) << __AT__ << " called"; if(i >= 0){ FrameToGuiFrequency = i; @@ -690,7 +470,7 @@ int UDPStandardImplementation::setFrameToGuiFrequency(const uint32_t i){ int UDPStandardImplementation::setAcquisitionPeriod(int64_t i){ - FILE_LOG(logDEBUG) << __AT__ << " called"; + FILE_LOG(logDEBUG1) << __AT__ << " called"; if(i >= 0){ acquisitionPeriod = i; @@ -705,7 +485,7 @@ int UDPStandardImplementation::setAcquisitionPeriod(int64_t i){ } int UDPStandardImplementation::setDynamicRange(const uint32_t i){ - FILE_LOG(logDEBUG) << __AT__ << " called"; + FILE_LOG(logDEBUG1) << __AT__ << " called"; int oldDynamicRange = dynamicRange; @@ -759,7 +539,7 @@ int UDPStandardImplementation::setDynamicRange(const uint32_t i){ int UDPStandardImplementation::setTenGigaEnable(const bool b){ - FILE_LOG(logDEBUG) << __AT__ << " called"; + FILE_LOG(logDEBUG1) << __AT__ << " called"; cout << "Info: Setting Ten Giga to " << string(b) << endl; bool oldTenGigaEnable = tengigaEnable; @@ -829,6 +609,10 @@ int UDPStandardImplementation::setTenGigaEnable(const bool b){ + + + + /************************************************************************* * Behavioral functions*************************************************** * They may modify the status of the receiver **************************** @@ -837,7 +621,7 @@ int UDPStandardImplementation::setTenGigaEnable(const bool b){ /***initial functions***/ int UDPStandardImplementation::setDetectorType(const slsReceiverDefs::detectorType d){ - FILE_LOG(logDEBUG) << __AT__ << " called"; + FILE_LOG(logDEBUG1) << __AT__ << " called"; cout << "Setting receiver type ..." << endl; @@ -857,7 +641,7 @@ int UDPStandardImplementation::setDetectorType(const slsReceiverDefs::detectorTy cout << "Info: ***** This is a " << slsDetectorBase::getDetectorType(d) << " Receiver *****" << endl; break; default: - cout << "Error: This is an unknown receiver type " << (int)d << endl; + cprintf(BG_RED, "Error: This is an unknown receiver type %d\n", (int)d); return FAIL; } @@ -934,9 +718,9 @@ int UDPStandardImplementation::setDetectorType(const slsReceiverDefs::detectorTy //delete threads and set number of listening threads if(myDetectorType == EIGER){ - pthread_mutex_lock(&status_mutex); + pthread_mutex_lock(&statusMutex); listeningThreadsMask = 0x0; - pthread_mutex_unlock(&(status_mutex)); + pthread_mutex_unlock(&(statusMutex)); if(threadStarted) createListeningThreads(true); numberofListeningThreads = MAX_NUMBER_OF_LISTENING_THREADS; @@ -949,11 +733,11 @@ int UDPStandardImplementation::setDetectorType(const slsReceiverDefs::detectorTy //create threads if(createListeningThreads() == FAIL){ cprintf(BG_RED,"Error: Could not create listening thread\n"); - exit (-1); + return FAIL; } if(createWriterThreads() == FAIL){ cprintf(BG_RED,"Error: Could not create writer threads\n"); - exit (-1); + return FAIL; } setThreadPriorities(); @@ -969,7 +753,7 @@ int UDPStandardImplementation::setDetectorType(const slsReceiverDefs::detectorTy /***acquisition functions***/ void UDPStandardImplementation::resetAcquisitionCount(){ - FILE_LOG(logDEBUG) << __AT__ << " starting"; + FILE_LOG(logDEBUG1) << __AT__ << " starting"; totalPacketsCaught = 0; acqStarted = false; @@ -980,7 +764,7 @@ void UDPStandardImplementation::resetAcquisitionCount(){ int UDPStandardImplementation::startReceiver(char *c=NULL){ - FILE_LOG(logDEBUG) << __AT__ << " called"; + FILE_LOG(logDEBUG1) << __AT__ << " called"; cout << "Info: Starting Receiver" << endl; @@ -1009,11 +793,11 @@ int UDPStandardImplementation::startReceiver(char *c=NULL){ guiDataReady=0; strcpy(guiFileName,""); //reset masks - pthread_mutex_lock(&status_mutex); + pthread_mutex_lock(&statusMutex); writerThreadsMask = 0x0; createFileMask = 0x0; fileCreateSuccess = false; - pthread_mutex_unlock(&status_mutex); + pthread_mutex_unlock(&statusMutex); //Print Receiver Configuration @@ -1024,6 +808,8 @@ int UDPStandardImplementation::startReceiver(char *c=NULL){ cout << "Info: Number of Jobs Per Buffer: " << numberofJobsPerBuffer << endl; if(FrameToGuiFrequency) cout << "Info: Frequency of frames sent to gui" << FrameToGuiFrequency << endl; + else + cout << "Info: Random frames sent to gui" << endl; @@ -1031,54 +817,84 @@ int UDPStandardImplementation::startReceiver(char *c=NULL){ if(createUDPSockets() == FAIL){ strcpy(c,"Could not create UDP Socket(s).\n"); cout << endl; - cout << "Error: "<< c << endl; + cprintf(BG_RED, "Error: %s\n",c); return FAIL; } if(setupWriter() == FAIL){ //stop udp socket shutDownUDPSockets(); - sprintf(c,"Could not create file %s.\n",savefilename); + sprintf(c,"Could not create file %s.\n",completeFileName); cout << endl; - cout << "Error: "<< c << endl; + cprintf(BG_RED, "Error: %s\n",c); return FAIL; } - //For compression, done to give the gui some proper name instead of always the last file name + //For compression, just for gui purposes if(dataCompressionEnable) - sprintf(savefilename, "%s/%s_fxxx_%d_xx.root", filePath,fileName,fileIndex); + sprintf(completeFileName, "%s/%s_fxxx_%d_xx.root", filePath,fileName,fileIndex); //initialize semaphore to synchronize between writer and gui reader threads sem_init(&writerGuiSemaphore,1,0); //status and thread masks - pthread_mutex_lock(&status_mutex); + pthread_mutex_lock(&statusMutex); status = RUNNING; - for(int i=0;i /proc/sys/net/core/rmem_max")) - cout << "\nWARNING: Could not change socket receiver buffer size in file /proc/sys/net/core/rmem_max" << endl; - else if(system("echo 250000 > /proc/sys/net/core/netdev_max_backlog")) - cout << "\nWARNING: Could not change max length of input queue in file /proc/sys/net/core/netdev_max_backlog" << endl; - - /** permanent setting heiner - net.core.rmem_max = 104857600 # 100MiB - net.core.netdev_max_backlog = 250000 - sysctl -p - // from the manual - sysctl -w net.core.rmem_max=16777216 - sysctl -w net.core.netdev_max_backlog=250000 - */ + if(status == RUNNING){ + //wait for all packets + uint64_t prev = totalPacketsCaught; + usleep(50000); + while(prev!=totalPacketsCaught){ + prev=totalPacketsCaught; + usleep(50000); } + //set status + pthread_mutex_lock(&statusMutex); + status = TRANSMITTING; + pthread_mutex_unlock(&statusMutex); + cout << "Info: Status: Transmitting" << endl; + } - -void UDPStandardImplementation::initializeMembers(){ - myDetectorType = GENERIC; - enableFileWrite = 1; - overwrite = 1; - fileIndex = 0; - scanTag = 0; - frameIndexNeeded = 0; + //shut down udp sockets and make listeners push dummy (end) packets for writers + shutDownUDPSockets(); +} - packetsCaught = 0; - totalPacketsCaught = 0; - startAcquisitionIndex = 0; - acquisitionIndex = 0; +void UDPStandardImplementation::readFrame(char* c,char** raw, uint64_t &startAcq, uint64_t &startFrame){ + FILE_LOG(logDEBUG1) << __AT__ << " called"; - frameIndexMask = 0; - packetIndexMask = 0; - frameIndexOffset = 0; - acquisitionPeriod = SAMPLE_TIME_IN_NS; - numberOfFrames = 0; - dynamicRange = 16; - shortFrame = -1; - currframenum = 0; - prevframenum = 0; + //point to gui data, to let writer thread know that gui is back for data + if (guiData == NULL){ + guiData = latestData; +#ifdef DEBUG4 + cprintf(CYAN,"Info: gui data not null anymore - ready to get data\n"); +#endif + } + + //copy data and filename + strcpy(c,guiFileName); + startAcq = startAcquisitionIndex; + startFrame = startFrameIndex; - nFrameToGui = 0; - dataCompression = false; - numListeningThreads = 1; - numWriterThreads = 1; - thread_started = 0; + //gui data not copied yet + if(!guiDataReady){ +#ifdef DEBUG4 + cprintf(CYAN,"Info: gui data not ready\n"); +#endif + *raw = NULL; + } + + //gui data ready, pass address to gui to copy the data + else{ +#ifdef DEBUG4 + cprintf(CYAN,"Info: gui data ready\n"); +#endif + *raw = guiData; + guiData = NULL; + + //for nth frame to gui, post semaphore so writer stops waiting + if((FrameToGuiFrequency) && (writerThreadsMask)){ +#ifdef DEBUG4 + cprintf(CYAN,"Info: gonna post\n"); +#endif + //release after getting data + sem_post(&smp); + } +#ifdef DEBUG4 + cprintf(CYAN,"Info: done post\n"); +#endif + + } +} - tengigaEnable = 0; +void UDPStandardImplementation::closeFile(int i){ + FILE_LOG(logDEBUG1) << __AT__ << " called for " << i ; + //normal + if(!dataCompressionEnable){ + if(sfilefd){ +#ifdef DEBUG4 + cprintf(YELLOW, "Going to close file:%d\n",fileno(sfilefd)); +#endif + fclose(sfilefd); + sfilefd = NULL; + } + } + //compression + else{ +#if (defined(MYROOT1) && defined(ALLFILE_DEBUG)) || !defined(MYROOT1) + if(sfilefd){ +#ifdef DEBUG4 + cout << "sfield:" << (int)sfilefd << endl; +#endif + fclose(sfilefd); + sfilefd = NULL; + } +#endif - eth = NULL; - - - - cmSub = NULL; - - - //diff threads - for(int i=0;iGetCurrentFile(); + + if(myFile[i]->Write()) + //->Write(tall->GetName(),TObject::kOverwrite); + cout << "Info: Thread " << i <<": wrote frames to file" << endl; + else + cout << "Info: Thread " << i << ": could not write frames to file" << endl; + + }else + cout << "Info: Thread " << i << ": could not write frames to file: No file or No Tree" << endl; + //close file + if(myTree[i] && myFile[i]) + myFile[i] = myTree[i]->GetCurrentFile(); + if(myFile[i] != NULL) + myFile[i]->Close(); + myFile[i] = NULL; + myTree[i] = NULL; + pthread_mutex_unlock(&writeMutex); + +#endif + } +} + + + + +/************************************************************************* + * Listening and Writing Threads ***************************************** + *************************************************************************/ + + +int UDPStandardImplementation::createListeningThreads(bool destroy){ + FILE_LOG(logDEBUG1) << __AT__ << " starting"; + + //reset masks + killAllListeningThreads = false; + pthread_mutex_lock(&statusMutex); + listeningThreadsMask = 0x0; + pthread_mutex_unlock(&(statusMutex)); + + //destroy + if(destroy){ + cout << "Info: Destroying Listening Thread(s)" << endl; + + killAllListeningThreads = true; + for(int i = 0; i < numberofListeningThreads; ++i){ + sem_post(&listenSemaphore[i]); + pthread_join(listeningThreads[i],NULL); + cout <<"."<getErrorStatus(); + if(!iret){ + cout << "Info: UDP port opened at port " << port[i] << endl; + }else{ +#ifdef VERBOSE + cprintf(BG_RED,"Error: Could not create UDP socket on port %d error: %d\n", port[i], iret); +#endif + shutDownUDPSockets(); + return FAIL; + } + } + + cout << "Info: UDP socket(s) created successfully." << endl; + cout << "Info: Listener Ready ..." << endl; + + return OK; +} + + + +int UDPStandardImplementation::setupWriter(){ + FILE_LOG(logDEBUG1) << __AT__ << " starting"; + + //acquisition start call back returns enable write + cbAction = DO_EVERYTHING; + if (startAcquisitionCallBack) + cbAction=startAcquisitionCallBack(filePath,fileName,fileIndex,bufferSize,pStartAcquisition); + + if(cbAction < DO_EVERYTHING){ + cout << "Info: Call back activated. Data saving must be taken care of by user in call back." << endl; + if (rawDataReadyCallBack) + cout << "Info: Data Write has been defined externally" << endl; + }else if(!fileWriteEnable) + cout << "Info: Data will not be saved" << endl; + + + + //creating first file + //setting all value to 1 + pthread_mutex_lock(&statusMutex); + for(int i=0; i DO_NOTHING){ + + //close file pointers + if(sfilefd){ + fclose(sfilefd); + sfilefd = NULL; + } + + //create file + if(!overwriteEnable){ + if (NULL == (sfilefd = fopen((const char *) (completeFileName), "wx"))){ + cprintf(BG_RED,"Error: Could not create/overwrite file %s\n",completeFileName); + return FAIL; + } + }else if (NULL == (sfilefd = fopen((const char *) (completeFileName), "w"))){ + cprintf(BG_RED,"Error: Could not create file %s\n",completeFileName); + return FAIL; + } + //setting file buffer size to 16mb + setvbuf(sfilefd,NULL,_IOFBF,BUF_SIZE); + + //Print packet loss and filenames + if(!packetsCaught){ + previousFrameNumber = -1; + cout << "Info: " << completeFileName << endl; + }else{ + cout << "Info:" << completeFileName + << "\tPacket Loss: " << setw(4)<startListening(); + return this_pointer; +} + + + +void* UDPStandardImplementation::startWritingThread(void* this_pointer){ + FILE_LOG(logDEBUG1) << __AT__ << " called"; + ((UDPStandardImplementation*)this_pointer)->startWriting(); + return this_pointer; +} + + + + +void UDPStandardImplementation::startListening(){ + FILE_LOG(logDEBUG1) << __AT__ << " called"; + + //set current thread value index + int ithread = currentThreadIndex; + //let calling function know thread started and obtained current + threadStarted = 1; + + + //variable definitions + int listenSize = 0; //listen to only 1 packet + uint32_t rc; //size of buffer received in bytes + //split frames + int carryonBufferSize; //from previous buffer to keep frames together in a buffer + char* tempBuffer = NULL; //temporary buffer to store split frames + if(myDetectorType != EIGER){ + listenSize = bufferSize * numberofJobsPerBuffer; //listen to more than 1 packet + tempBuffer = new char[onePacketSize * (packetsPerFrame - 1)]; //store maximum of 1 packets less in a frame + } + /* outer loop - loops once for each acquisition */ + //infinite loop, exited only to change dynamic range, 10G parameters etc (then recreated again) + while(true){ + + //reset parameters before acquisition + carryonBufferSize = 0; + + /* inner loop - loop for each buffer */ + //until mask unset (udp sockets shut down by client) + while((1 << ithread) & listeningThreadsMask){ + + //pop from fifo + fifoFree[ithread]->pop(buffer[ithread]); +#ifdef FIFODEBUG + cprintf(BLUE,"%d :Listener popped from fifofree %p\n", ithread, (void*)(buffer[ithread])); +#endif + + //udpsocket doesnt exist + if(udpSocket[ithread] == NULL){ + cprintf(RED, "Error: Thread %d :UDP Socket not created\n",ithread); + stopListening(ithread,0); + continue; + } + + rc = prepareAndListenBuffer(ithread, listenSize, carryonBufferSize, tempBuffer); + + //start indices for each start of scan/acquisition + if((!measurementStarted) && (rc > 0)){ + pthread_mutex_lock(&progressMutex); + if(!measurementStarted) + startFrameIndices(ithread); + pthread_mutex_unlock(&progressMutex); + } + + //problem in receiving or end of acquisition + if (status == TRANSMITTING){ + stopListening(ithread,rc); + continue; + } + + //write packet count to buffer + if(myDetectorType == EIGER) + (*((uint32_t*)(buffer[ithread]))) = 1; + //handling split frames and writing packet Count to buffer + else + (*((uint32_t*)(buffer[ithread]))) = processListeningBuffer(ithread, carryonBufferSize, tempBuffer); + + + //push buffer to FIFO + while(!fifo[ithread]->push(buffer[ithread])); +#ifdef FIFODEBUG + cprintf(BLUE,"Listening_Thread %d: Listener pushed into fifo %p\n",ithread, (void*)(buffer[ithread])); +#endif + + }/*--end of loop for each buffer (inner loop)*/ + + //end of acquisition, wait for next acquisition/change of parameters + sem_wait(&listenSemaphore[ithread]); + + //check to exit thread (for change of parameters) - only EXIT possibility + if(killAllListeningThreads){ + cprintf(GREEN,"Listening_Thread %d:Goodbye!\n",ithread); + //free resources at exit + if(tempBuffer) delete[] tempBuffer; + pthread_exit(NULL); + } + + }/*--end of loop for each acquisition (outer loop) */ +} + + + + + +int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int lSize, int cSize, char* temp){ + FILE_LOG(logDEBUG1) << __AT__ << " called"; + + //listen to UDP packets + memcpy(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS, temp, cSize); + int receivedSize = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS + cSize, lSize + cSize); + + //throw away packets that is not one packet size, need to check status if socket is shut down + while(status != TRANSMITTING && myDetectorType == EIGER && receivedSize != onePacketSize) { + if(receivedSize != EIGER_HEADER_LENGTH) + cprintf(RED,"Listening_Thread %d: Listened to a weird packet size %d\n",receivedSize); +#ifdef DEBUG + else + cprintf(BLUE,"Listening_Thread %d: Listened to a header packet\n",ithread); +#endif + receivedSize = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS); + } + +#ifdef DEBUG + cprintf(BLUE, "Listening_Thread %d : Received bytes: %d. Expected bytes: %d\n", ithread, receivedSize, expected-cSize); +#endif + return receivedSize; +} + + +void UDPStandardImplementation::startFrameIndices(int ithread){ + FILE_LOG(logDEBUG1) << __AT__ << " called"; + + //determine startFrameIndex + switch(myDetectorType){ + case EIGER: + startFrameIndex = 0; //frame number always resets + break; + default: + if(shortFrameEnable < 0){ + startFrameIndex = (((((uint32_t)(*((uint32_t*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS))))+1) + & (frameIndexMask)) >> frameIndexOffset); + }else{ + startFrameIndex = ((((uint32_t)(*((uint32_t*)(buffer[ithread]+HEADER_SIZE_NUM_TOT_PACKETS)))) + & (frameIndexMask)) >> frameIndexOffset); + } + break; + } + + //start of entire acquisition + if(!acqStarted){ + startAcquisitionIndex = startFrameIndex; + acqStarted = true; + cprintf(BLUE,"Info: Thread %d: startAcquisitionIndex:%d\n",ithread,startAcquisitionIndex); + } + + //set start of scan/real time measurement + cprintf(BLUE,"Info: Thread %d: startFrameIndex: %d\n", ithread,startFrameIndex); + measurementStarted = true; +} + + + + + +void UDPStandardImplementation::stopListening(int ithread, int numbytes){ + FILE_LOG(logDEBUG1) << __AT__ << " called"; + + cout << "Info: Stop Listening. Status:" << slsDetectorBase::runStatusType(status) << endl; + + + //less than 1 packet size (especially for eiger), ignore the buffer (so that 2 dummy buffers are not sent with pc=0) + if(numbytes < onePacketSize) + numbytes = 0; + + + //free empty buffer + if(numbytes <= 0){ + cprintf(BLUE,"Info: Thread %d :End of Acquisition for Listening Thread\n", ithread); + while(!fifoFree[ithread]->push(buffer[ithread])); +#ifdef FIFODEBUG + cprintf(BLUE,"Listening_Thread %d :Listener push empty buffer into fifofree %p\n", ithread, (void*)(buffer[ithread])); #endif } - - - strcpy(savefilename,""); - - - //strcpy(filePath,""); - //strcpy(fileName,"run"); - - - - //status - pthread_mutex_lock(&status_mutex); - status = IDLE; - pthread_mutex_unlock(&(status_mutex)); - -} - - - -UDPStandardImplementation::~UDPStandardImplementation(){ FILE_LOG(logDEBUG) << __AT__ << " called"; - - createListeningThreads(true); - createWriterThreads(true); - deleteMembers(); -} - - - - -void UDPStandardImplementation::deleteMembers(){ FILE_LOG(logDEBUG) << __AT__ << " called"; - - //kill threads - if(thread_started){ - createListeningThreads(true); - createWriterThreads(true); + //push last non empty buffer into fifo + else{ + (*((uint32_t*)(buffer[ithread]))) = numbytes/onePacketSize; + totalListeningFrameCount[ithread] += (numbytes/onePacketSize); +#ifdef DEBUG + cprintf(BLUE,"Listening_Thread %d: Last Buffer numBytes:%d\n",ithread, numbytes); + cprintf(BLUE,"Listening_Thread %d: Last Buffer packet count:%d\n",ithread, numbytes/onePacketSize); +#endif + while(!fifo[ithread]->push(buffer[ithread])); +#ifdef FIFODEBUG + cprintf(BLUE,"Listening_Thread %d: Listener Last Buffer pushed into fifo %p\n", ithread,(void*)(buffer[ithread])); +#endif } - for(int i=0;ipop(buffer[ithread]); + //creating dummy-end buffer with pc=0xFFFF + (*((uint32_t*)(buffer[ithread]))) = dummyPacketValue; + while(!fifo[ithread]->push(buffer[ithread])); +#ifdef FIFODEBUG + cprintf(BLUE,"Listening_Thread %d: Listener pushed dummy-end buffer into fifo %p\n", ithread,(void*)(buffer[ithread])); +#endif + } + + + //reset mask and exit loop + pthread_mutex_lock(&statusMutex); + listeningThreadsMask^=(1< 1) + cprintf(BLUE,"Listening_Thread %d: Waiting for other listening threads to be done.. current mask:0x%x\n", ithread, listeningThreadsMask); +#endif + while(listeningThreadsMask) + usleep(5000); +#ifdef DEBUG4 + int t=0; + for(i=0;i> frameIndexOffset)); +#endif + cSize = onePacketSize; + --packetCount; + } } - if(receiverdata[i]){ - delete receiverdata[i]; - receiverdata[i] = NULL; - } - } - shutDownUDPSockets(); - if(eth) {delete [] eth; eth = NULL;} - if(latestData) {delete [] latestData; latestData = NULL;} +#ifdef DEBUG4 + cprintf(BLUE, "Listening_Thread %d: First Header:%d\n", (((((uint32_t)(*((uint32_t*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS))))+1) + & (frameIndexMask)) >> frameIndexOffset)); +#endif + break; - for(int i=0;i> frameIndexOffset), + ((((uint32_t)(*((uint32_t*)(buffer[ithread]+HEADER_SIZE_NUM_TOT_PACKETS))))) & (packetIndexMask)), + (((((uint32_t)(*((uint32_t*)(buffer[ithread]+lastpacketoffset))))) & (frameIndexMask)) >> frameIndexOffset), + ((((uint32_t)(*((uint32_t*)(buffer[ithread]+lastpacketoffset))))) & (packetIndexMask)), + lastPacketOffset); +#endif + //moench last packet value is 0, so find the last packet and store the others in a temp storage + if( ((((uint32_t)(*((uint32_t*)(buffer[ithread]+lastPacketOffset))))) & (packetIndexMask))){ + lastFrameHeader = ((((uint32_t)(*((uint32_t*)(buffer[ithread]+lastPacketOffset))))) + & (frameIndexMask)) >> frameIndexOffset; + cSize += onePacketSize; + lastPacketOffset -= onePacketSize; + --packetCount; + while (lastFrameHeader == (((((uint32_t)(*((uint32_t*)(buffer[ithread]+lastPacketOffset))))) & (frameIndexMask)) >> frameIndexOffset)){ + cSize += onePacketSize; + lastPacketOffset -= onePacketSize; + --packetCount; + } + memcpy(temp, buffer[ithread]+(lastPacketOffset+onePacketSize), cSize); +#ifdef DEBUG4 + cprintf(BLUE, "Listening_Thread %d: temp Header:%d\t temp Packet:%d\n", + (((((uint32_t)(*((uint32_t*)(temp)))))& (frameIndexMask)) >> frameIndexOffset), + ((((uint32_t)(*((uint32_t*)(temp))))) & (packetIndexMask))); +#endif + } + break; + + default: + cprintf(RED,"Listening_Thread %d: Error: This detector is not implemented in the receiver" + + slsDetectorBase::getDetectorType(myDetectorType).c_str() + "\n"); + break; } +#ifdef DEBUG4 + cprintf(BLUE,"Listening_Thread %d: PacketCount:%d CarryonBufferSize:%d\n",ithread, packetCount, cSize); +#endif + + return packetCount; +} + + + + + + +void UDPStandardImplementation::startWriting(){ + FILE_LOG(logDEBUG1) << __AT__ << " called"; + + //set current thread value index + int ithread = currentThreadIndex; + //let calling function know thread started and obtained current + threadStarted = 1; + + //variable definitions + char* wbuf[MAX_NUMBER_OF_LISTENING_THREADS] = NULL; + sfilefd = NULL; + + + /* outer loop - loops once for each acquisition */ + //infinite loop, exited only to change dynamic range, 10G parameters etc (then recreated again) + while(true){ + + //--reset parameters before acquisition + //--end of reset parameters before acquisition + + /* inner loop - loop for each buffer */ + //until mask unset (udp sockets shut down by client) + while((1 << ithread) & writerThreadsMask){ + + + + }/*--end of loop for each buffer (inner loop)*/ + + + //in case they are not closed already + closeFile(); +#ifdef DEBUG4 + cprintf(GREEN,"Writing_Thread %d: Done with acquisition. Waiting for 1st sem to create new file/change of parameters\n", ithread); +#endif + //end of acquisition, wait for file create/change of parameters + sem_wait(&writerSemaphore[ithread]); + //check to exit thread (for change of parameters) - only EXIT possibility + if(killAllWritingThreads){ + cprintf(GREEN,"Writing_Thread %d:Goodbye!\n",ithread); + //free resources at exit + for(int i=0; i DO_NOTHING){ - //close - if(sfilefd){ - if(fclose(sfilefd)){ - cprintf(RED, "file close problem %d\n",fileno(sfilefd)); - fclose(sfilefd); - } - sfilefd = NULL; - } - - //open file - if(!overwrite){ - if (NULL == (sfilefd = fopen((const char *) (savefilename), "wx"))){ - cprintf(BG_RED,"Error: Could not create new file %s\n",savefilename); - return FAIL; - } - }else if (NULL == (sfilefd = fopen((const char *) (savefilename), "w"))){ - cprintf(BG_RED,"Error: Could not create file %s\n",savefilename); - return FAIL; - } - //setting buffer - setvbuf(sfilefd,NULL,_IOFBF,BUF_SIZE); - - - //printing packet losses and file names - if(!packetsCaught) - cout << savefilename << endl; - else{ - cout << savefilename - << "\tpacket loss " - << setw(4)<GetCurrentFile(); - - if(myFile[ithr]->Write()) - //->Write(tall->GetName(),TObject::kOverwrite); - cout << "Thread " << ithr <<": wrote frames to file" << endl; - else - cout << "Thread " << ithr << ": could not write frames to file" << endl; - - }else - cout << "Thread " << ithr << ": could not write frames to file: No file or No Tree" << endl; - //close file - if(myTree[ithr] && myFile[ithr]) - myFile[ithr] = myTree[ithr]->GetCurrentFile(); - if(myFile[ithr] != NULL) - myFile[ithr]->Close(); - myFile[ithr] = NULL; - myTree[ithr] = NULL; - pthread_mutex_unlock(&write_mutex); - -#endif - } -} - - - - -/** - * Pre: status is running, semaphores have been instantiated, - * Post: udp sockets shut down, status is idle, sempahores destroyed - * */ - -int UDPStandardImplementation::stopReceiver(){ - FILE_LOG(logDEBUG) << __AT__ << " called"; - - if(status != IDLE){ - //#ifdef VERBOSE - cout << "Stopping Receiver" << endl; - //#endif - - startReadout(); - - while(status == TRANSMITTING){ - sem_post(&smp); - usleep(5000); - } - - //semaphore destroy - sem_destroy(&smp); - - //change status - pthread_mutex_lock(&status_mutex); - status = IDLE; - pthread_mutex_unlock(&(status_mutex)); - - cout << "Receiver Stopped.\nStatus:" << status << endl << endl; - }else cout <<" Not idle to stop receiver" << endl; - - - //sem_post(&smp); - - return OK; -} - - - - -/** - * Pre: status is running, udp sockets have been initialized, - * stop receiver initiated - * Post:udp sockets closed, status is transmitting - * */ -void UDPStandardImplementation::startReadout(){ - FILE_LOG(logDEBUG) << __AT__ << " called"; - - //#ifdef VERBOSE - cout << "Start Receiver Readout" << endl; - //#endif - - if(status == RUNNING){ - - //wait so that all packets which take time has arrived - usleep(5000); - - /********************************************/ - //usleep(10000000); - //usleep(2000000); - uint32_t prev = totalPacketsCaught; - usleep(50000); - while(prev!=totalPacketsCaught){ - prev=totalPacketsCaught; - usleep(50000); - } - pthread_mutex_lock(&status_mutex); - status = TRANSMITTING; - pthread_mutex_unlock(&status_mutex); - cout << "Status: Transmitting" << endl; - } - - //kill udp socket to tell the listening thread to push last packet - shutDownUDPSockets(); - -} - - - -void* UDPStandardImplementation::startListeningThread(void* this_pointer){ - FILE_LOG(logDEBUG) << __AT__ << " called"; - ((UDPStandardImplementation*)this_pointer)->startListening(); - - return this_pointer; -} - - - -void* UDPStandardImplementation::startWritingThread(void* this_pointer){ - FILE_LOG(logDEBUG) << __AT__ << " called"; - ((UDPStandardImplementation*)this_pointer)->startWriting(); - return this_pointer; -} - - - - - - -int UDPStandardImplementation::startListening(){ - FILE_LOG(logDEBUG) << __AT__ << " called"; - int ithread = currentListeningThreadIndex; -#ifdef VERYVERBOSE - cprintf(BLUE, "In startListening()\n "); -#endif - - thread_started = 1; - - int total; - int lastpacketoffset, expected, rc,packetcount, maxBufferSize, carryonBufferSize; - uint32_t lastframeheader;// for moench to check for all the packets in last frame - char* tempchar = NULL; - - while(1){ - //variables that need to be checked/set before each acquisition - carryonBufferSize = 0; - maxBufferSize = bufferSize * numJobsPerThread; -#ifdef VERYDEBUG - cprintf(BLUE, "%d maxBufferSize:%d carryonBufferSize:%d\n", ithread,maxBufferSize,carryonBufferSize); -#endif - - //missing packets compensation in listening thread - if(tempchar) {delete [] tempchar;tempchar = NULL;} - if(myDetectorType != EIGER) - tempchar = new char[onePacketSize * ((packetsPerFrame/numListeningThreads) - 1)]; //gotthard: 1packet size, moench:39 packet size - else - maxBufferSize = 0; - - - while((1<pop(buffer[ithread]); -#ifdef FIFO_DEBUG - cprintf(BLUE,"%d listener popped from fifofree %x\n", ithread, (void*)(buffer[ithread])); -#endif - - - - //ensure udpsocket exists - if(udpSocket[ithread] == NULL){ - rc = 0; - cprintf(BLUE, "%d UDP Socket is NULL\n",ithread); - } - - - //normal listening - else if(!carryonBufferSize){ -#ifdef SOCKET_DEBUG - if(!ithread){ -#endif - rc = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS, maxBufferSize); - if(rc == EIGER_HEADER_LENGTH && myDetectorType == EIGER) { - while(rc == EIGER_HEADER_LENGTH){ - rc = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS, maxBufferSize); - } - } - expected = maxBufferSize; -#ifdef SOCKET_DEBUG - }else{ - while(1) usleep(100000000); - } -#endif - } - - - //the remaining packets from previous buffer, copy it and listen to n less frame - else{ -#ifdef VERYDEBUG - cprintf(BLUE, "%d carry on buffer size:%d\n",ithread,carryonBufferSize); - cprintf(BLUE, "%d framennum in tempchar:%d\n",((((uint32_t)(*((uint32_t*)tempchar))) - & (frameIndexMask)) >> frameIndexOffset)); - cprintf(BLUE, "%d tempchar packet:%d\n", ((((uint32_t)(*((uint32_t*)(tempchar))))) - & (packetIndexMask))); -#endif - memcpy(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS, tempchar, carryonBufferSize); - rc = udpSocket[ithread]->ReceiveDataOnly((buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS + carryonBufferSize),maxBufferSize - carryonBufferSize); - expected = maxBufferSize - carryonBufferSize; - } - - -#ifdef EIGER_DEBUG - cprintf(BLUE, "%d rc: %d. expected: %d\n", ithread, rc, expected); -#endif - - - //start indices for each start of scan/acquisition - if((!measurementStarted) && (rc > 0)){ - pthread_mutex_lock(&progress_mutex); - if(!measurementStarted) - startFrameIndices(ithread, rc); - pthread_mutex_unlock(&progress_mutex); - } - - - //problem in receiving or end of acquisition - if (status == TRANSMITTING){ - stopListening(ithread,rc,packetcount,total); - continue; - } - - - //reset - packetcount = (packetsPerFrame/numListeningThreads) * numJobsPerThread; - carryonBufferSize = 0; - - - - //check if last packet valid and calculate packet count - switch(myDetectorType){ - case MOENCH: - lastpacketoffset = (((numJobsPerThread * packetsPerFrame - 1) * onePacketSize) + HEADER_SIZE_NUM_TOT_PACKETS); -#ifdef VERYDEBUG - cout <<"first packet:"<< ((((uint32_t)(*((uint32_t*)(buffer[ithread]+HEADER_SIZE_NUM_TOT_PACKETS))))) & (packetIndexMask)) << endl; - cout <<"first header:"<< (((((uint32_t)(*((uint32_t*)(buffer[ithread]+HEADER_SIZE_NUM_TOT_PACKETS))))) & (frameIndexMask)) >> frameIndexOffset) << endl; - cout << "last packet offset:" << lastpacketoffset << endl; - cout <<"last packet:"<< ((((uint32_t)(*((uint32_t*)(buffer[ithread]+lastpacketoffset))))) & (packetIndexMask)) << endl; - cout <<"last header:"<< (((((uint32_t)(*((uint32_t*)(buffer[ithread]+lastpacketoffset))))) & (frameIndexMask)) >> frameIndexOffset) << endl; -#endif - //moench last packet value is 0 - if( ((((uint32_t)(*((uint32_t*)(buffer[ithread]+lastpacketoffset))))) & (packetIndexMask))){ - lastframeheader = ((((uint32_t)(*((uint32_t*)(buffer[ithread]+lastpacketoffset))))) & (frameIndexMask)) >> frameIndexOffset; - carryonBufferSize += onePacketSize; - lastpacketoffset -= onePacketSize; - --packetcount; - while (lastframeheader == (((((uint32_t)(*((uint32_t*)(buffer[ithread]+lastpacketoffset))))) & (frameIndexMask)) >> frameIndexOffset)){ - carryonBufferSize += onePacketSize; - lastpacketoffset -= onePacketSize; - --packetcount; - } - memcpy(tempchar, buffer[ithread]+(lastpacketoffset+onePacketSize), carryonBufferSize); -#ifdef VERYDEBUG - cout << "tempchar header:" << (((((uint32_t)(*((uint32_t*)(tempchar))))) - & (frameIndexMask)) >> frameIndexOffset) << endl; - cout <<"tempchar packet:"<< ((((uint32_t)(*((uint32_t*)(tempchar))))) - & (packetIndexMask)) << endl; -#endif - } - break; - - case GOTTHARD: - case PROPIX: - if(shortFrame == -1){ - lastpacketoffset = (((numJobsPerThread * packetsPerFrame - 1) * onePacketSize) + HEADER_SIZE_NUM_TOT_PACKETS); -#ifdef VERYDEBUG - cprintf(BLUE, "%d last packet offset:%d\n",ithread, lastpacketoffset); -#endif - //if not last packet - if((unsigned int)(packetsPerFrame -1) != ((((uint32_t)(*((uint32_t*)(buffer[ithread]+lastpacketoffset))))+1) & (packetIndexMask))){ - memcpy(tempchar,buffer[ithread]+lastpacketoffset, onePacketSize); -#ifdef VERYDEBUG - cprintf(BLUE, "%d tempchar header:%d\n",ithread,(((((uint32_t)(*((uint32_t*)(tempchar))))+1) - & (frameIndexMask)) >> frameIndexOffset)); -#endif - carryonBufferSize = onePacketSize; - --packetcount; - } - } -#ifdef VERYDEBUG - cprintf(BLUE, "%d header:%d\n", (((((uint32_t)(*((uint32_t*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS))))+1) - & (frameIndexMask)) >> frameIndexOffset)); -#endif - break; - - - - case EIGER: - //because even headers might be included, so not packet count - (*((uint32_t*)(buffer[ithread]))) = rc; - packetcount = 1; - break; - - default: - break; - } - - - - //write packet count and push -#ifdef VERYDEBUG - cprintf(BLUE, "%d packetcount:%d carryonbuffer:%d\n", ithread, packetcount, carryonBufferSize); -#endif - if(myDetectorType != EIGER) - (*((uint32_t*)(buffer[ithread]))) = packetcount; - totalListeningFrameCount[ithread] += packetcount; -#ifdef VERYDEBUG - cprintf(BLUE,"%d listener going to push fifo: 0x%x\n", ithread,(void*)(buffer[ithread])); -#endif - while(!fifo[ithread]->push(buffer[ithread])); -#ifdef FIFO_DEBUG - cprintf(BLUE, "%d listener pushed into fifo %x\n",ithread, (void*)(buffer[ithread])); -#endif - - - - } - - sem_wait(&listensmp[ithread]); - - //make sure its not exiting thread - if(killAllListeningThreads){ - cout << ithread << " good bye listening thread" << endl; - if(tempchar) {delete [] tempchar;tempchar = NULL;} - pthread_exit(NULL); - } - - if(tempchar) {delete [] tempchar;tempchar = NULL;} - } - - return OK; -} - - - - - - - @@ -1946,16 +1978,10 @@ int UDPStandardImplementation::startListening(){ int UDPStandardImplementation::startWriting(){ - FILE_LOG(logDEBUG) << __AT__ << " called"; + FILE_LOG(logDEBUG1) << __AT__ << " called"; - int ithread = currentWriterThreadIndex; -#ifdef VERYVERBOSE - cprintf(GREEN,"%d In startWriting()\n", ithread); -#endif - thread_started = 1; - char* wbuf[numListeningThreads];//interleaved char *d=new char[bufferSize*numListeningThreads]; int xmax=0,ymax=0; int ret,i,j; @@ -2468,66 +2494,9 @@ int UDPStandardImplementation::startWriting(){ } } -#ifdef VERYVERBOSE - cprintf(GREEN,"%d gonna wait for 1st sem\n", ithread); -#endif - //wait - sem_wait(&writersmp[ithread]); - if(killAllWritingThreads){ - for(i=0;i> frameIndexOffset); - else - startFrameIndex = ((((uint32_t)(*((uint32_t*)(buffer[ithread]+HEADER_SIZE_NUM_TOT_PACKETS)))) - & (frameIndexMask)) >> frameIndexOffset); - - - //start of acquisition - if(!acqStarted){ - startAcquisitionIndex=startFrameIndex; - //currframenum = startAcquisitionIndex; - acqStarted = true; - cprintf(BLUE,"%d startAcquisitionIndex:%d\n", ithread, startAcquisitionIndex); - } - - cprintf(BLUE,"%d startFrameIndex: %d\n", ithread,startFrameIndex); - prevframenum=startFrameIndex-1; //so that there is no packet loss, when currframenum(max,20) - prevframenum(1) - measurementStarted = true; - -} - - - -void UDPStandardImplementation::stopListening(int ithread, int rc, int &pc, int &t){ - FILE_LOG(logDEBUG) << __AT__ << " called"; - - - int i; - -#ifdef VERYVERBOSE - cprintf(BLUE, "%d Stop Listening\n", ithread); -#endif - - - if(status != TRANSMITTING){ - cprintf(BG_RED,"%d *** udp socket not shut down from client ***********************\n", ithread); - while(!fifoFree[ithread]->push(buffer[ithread])); - exit(-1); - } - - - //free buffer - if(rc <= 0){ - cprintf(BLUE,"%d End of acquisition for Listening Thread\n", ithread); - while(!fifoFree[ithread]->push(buffer[ithread])); -#ifdef FIFO_DEBUG - cprintf(BLUE,"%d listener empty buffer pushed into fifofree %x\n", ithread, (void*)(buffer[ithread])); -#endif - } - - - //push the last buffer into fifo - else{ - if(myDetectorType == EIGER){ - (*((uint32_t*)(buffer[ithread]))) = rc; - pc = 1; - }else{ - pc = (rc/onePacketSize); - (*((uint32_t*)(buffer[ithread]))) = pc; - } -#ifdef VERYDEBUG - cprintf(BLUE,"%d last rc:%d\n",ithread, rc); - cprintf(BLUE,"%d last packetcount:%d\n", ithread, pc); -#endif - - totalListeningFrameCount[ithread] += pc; - while(!fifo[ithread]->push(buffer[ithread])); -#ifdef FIFO_DEBUG - cprintf(BLUE,"%d listener last buffer pushed into fifo %x\n", ithread,(void*)(buffer[ithread])); -#endif - } - - - - - //push dummy buffer to all writer threads - for(i=0;ipop(buffer[ithread]); -#ifdef FIFO_DEBUG - cprintf(BLUE,"%d listener popped dummy buffer from fifofree %x\n", ithread,(void*)(buffer[ithread])); -#endif - (*((uint32_t*)(buffer[ithread]))) = 0x0; -#ifdef VERYDEBUG - cprintf(BLUE,"%d dummy buffer num packets:%d\n", ithread(*((uint16_t*)(buffer[ithread])))); -#endif - while(!fifo[ithread]->push(buffer[ithread])); -#ifdef FIFO_DEBUG - cprintf(BLUE,"%d listener pushed dummy buffer into fifo %x\n", ithread,(void*)(buffer[ithread])); -#endif - } - - - - //reset mask and exit loop - pthread_mutex_lock(&status_mutex); - listeningthreads_mask^=(1< 1) - cprintf(BLUE,"%d Waiting for listening to be done.. current mask:0x%x\n", ithread, listeningthreads_mask); -#endif - while(listeningthreads_mask) - usleep(5000); -#ifdef VERYDEBUG - t = 0; - for(i=0;i Date: Wed, 14 Oct 2015 09:11:40 +0200 Subject: [PATCH 151/474] again --- .../include/UDPStandardImplementation.h | 2 + .../src/UDPStandardImplementation.cpp | 110 +++++++++++++++--- 2 files changed, 93 insertions(+), 19 deletions(-) diff --git a/slsReceiverSoftware/include/UDPStandardImplementation.h b/slsReceiverSoftware/include/UDPStandardImplementation.h index cbd46d433..bbe526c40 100644 --- a/slsReceiverSoftware/include/UDPStandardImplementation.h +++ b/slsReceiverSoftware/include/UDPStandardImplementation.h @@ -367,6 +367,8 @@ private: */ uint32_t processListeningBuffer(int ithread, int cSize,char* temp); + bool popAndCheckEndofAcquisition(char* wbuffer[], bool ready[], uint32_t nP[],char* toFree[],int toFreeOffset[]); + /************************************************************************* * Class Members ********************************************************* *************************************************************************/ diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 7fa6310df..f4d2d968f 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -20,6 +20,7 @@ #include #include #include +#include using namespace std; #define WRITE_HEADERS @@ -1718,8 +1719,15 @@ void UDPStandardImplementation::startWriting(){ threadStarted = 1; //variable definitions - char* wbuf[MAX_NUMBER_OF_LISTENING_THREADS] = NULL; - sfilefd = NULL; + char* wbuf[numberofListeningThreads]; //buffer popped from FIFO + sfilefd = NULL; //file pointer + bool popReady[numberofListeningThreads]; //if the FIFO can be popped + uint32_t numPackets[numberofListeningThreads]; //number of packets popped from the FIFO + //eiger specific + int MAX_NUM_PACKETS = 1024; //highest 32 bit has 1024 number of packets + char* toFreePointers[MAX_NUM_PACKETS]; //pointers to free for each frame + int toFreePointersOffset[numberofListeningThreads]; //offset of pointers to free added for each thread + /* outer loop - loops once for each acquisition */ @@ -1727,6 +1735,15 @@ void UDPStandardImplementation::startWriting(){ while(true){ //--reset parameters before acquisition + for(int i=0; ipop(wbuffer[i]); +#ifdef FIFODEBUG + cprintf(GREEN,"Writing_Thread %d: Popped %p from FIFO %d\n", ithread, (void*)(wbuffer[i]),i); +#endif + val = (uint32_t)(*((uint32_t*)wbuffer[i])); + if(val < 0) + cprintf(BG_RED,"Error: Negative packet numbers: %d for FIFO %d\n",val,i); + nP[i] = abs(val); +#ifdef DEBUG4 + cprintf(GREEN,"Writing_Thread %d: Number of Packets: %d for FIFO %d\n", ithread, nP[i], i); +#endif + //dummy-end buffer + if(nP[i] == dummyPacketValue){ + ready[i] = false; +#ifdef DEBUG3 + cprintf(GREEN,"Writing_Thread %d: Dummy frame popped out of FIFO %d",ithread, i); +#endif + } + //normal buffer popped out + else{ + endofAcquisition = false; +#ifdef DEBUG4 + switch(myDetectorType){ + case EIGER: + wbuf_footer = (eiger_packet_footer_t*)(wbuffer[i] + footerOffset + HEADER_SIZE_NUM_TOT_PACKETS); + //cprintf(BLUE,"footer value:0x%x\n",i,(uint64_t)(*( (uint64_t*) wbuf_footer))); + cprintf(BLUE,"Fnum[%d]:%d\n",i,(uint32_t)(*( (uint64_t*) wbuf_footer))); + cprintf(BLUE,"Pnum[%d]:%d\n",i,*( (uint16_t*) wbuf_footer->packetNumber)); + break; + default: break; + } +#endif + if(myDetectorType == EIGER){ + toFree[toFreeOffset[i]] = wbuffer[i]; + toFreeOffset[i]++; + } + } + } + } + + return endofAcquisition; +} @@ -1987,23 +2070,21 @@ int UDPStandardImplementation::startWriting(){ int ret,i,j; bool endofacquisition; - int numpackets[numListeningThreads], nf; - bool fullframe[numListeningThreads],popready[numListeningThreads]; + int nf; + bool fullframe[numListeningThreads]; volatile uint32_t tempframenum[numListeningThreads]; uint32_t presentframenum; uint32_t lastpacketheader[numListeningThreads], currentpacketheader[numListeningThreads]; int numberofmissingpackets[numListeningThreads]; - int MAX_VALUE = 1024;//32 bit number of packets - char* tofree[MAX_VALUE]; + + char* tempbuffer[MAX_VALUE]; char* blankframe[MAX_VALUE]; - int tofreeoffset[numListeningThreads]; int tempoffset[numListeningThreads]; int blankoffset; for(i=0;ipacketnum)); #endif - }else if(numpackets[i] == EIGER_HEADER_LENGTH){ - cprintf(BG_RED, "got header in writer, weirdd packetsize:%d\n",numpackets[i]); - exit(-1); } -#ifdef EIGER_DEBUG3 - else { - cprintf(BG_RED, "got weird in writer, weirdd packetsize:%d\n",numpackets[i]); - } -#endif + if(myDetectorType == EIGER){ tofree[tofreeoffset[i]] = wbuf[i]; tofreeoffset[i]++; From a3e12e795526213c352443734d67d64e7fb14b9b Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Thu, 15 Oct 2015 12:11:06 +0200 Subject: [PATCH 152/474] somewhere --- .../include/UDPStandardImplementation.h | 37 ++++- .../include/sls_receiver_defs.h | 8 +- .../src/UDPBaseImplementation.cpp | 18 +- .../src/UDPStandardImplementation.cpp | 155 ++++++++---------- 4 files changed, 106 insertions(+), 112 deletions(-) diff --git a/slsReceiverSoftware/include/UDPStandardImplementation.h b/slsReceiverSoftware/include/UDPStandardImplementation.h index bbe526c40..0c1d4ac43 100644 --- a/slsReceiverSoftware/include/UDPStandardImplementation.h +++ b/slsReceiverSoftware/include/UDPStandardImplementation.h @@ -77,8 +77,9 @@ class UDPStandardImplementation: private virtual slsReceiverDefs, public UDPBase * Overridden method * Set data compression, by saving only hits (so far implemented only for Moench and Gotthard) * @param b true for data compression enable, else false + * @return OK or FAIL */ - void setDataCompressionEnable(const bool b); + int setDataCompressionEnable(const bool b); //***acquisition parameters*** /** @@ -367,7 +368,33 @@ private: */ uint32_t processListeningBuffer(int ithread, int cSize,char* temp); - bool popAndCheckEndofAcquisition(char* wbuffer[], bool ready[], uint32_t nP[],char* toFree[],int toFreeOffset[]); + /** + * Called by StartWriting + * Pops buffer from all the FIFOs and checks for dummy frames and end of acquisition + * @param ithread current thread index + * @param wbuffer the buffer array that is popped from all the FIFOs + * @param ready if that FIFO is allowed to pop (depends on if dummy buffer already popped/ waiting for other FIFO to finish a frame(eiger)) + * @param nP number of packets in the buffer popped out + * @param toFree array of addresses to pop into fifoFree (eiger specific) + * @param toFreeOffset the number of addresses to free for each FIFO (eiger specific) + * @return true if end of acquisition else false + */ + bool popAndCheckEndofAcquisition(int ithread, char* wbuffer[], bool ready[], uint32_t nP[],char* toFree[],int toFreeOffset[]); + + /** + * Called by StartWriting + * When dummy-end buffers are popped from all FIFOs (acquisition over), this is called + * It frees the FIFO addresses, closes all files + * For data compression, it waits for all threads to be done + * Changes the status to RUN_FINISHED and prints statistics + * @param ithread writing thread index + * @param wbuffer writing buffer popped out from FIFO + */ + void stopWriting(int ithread, char* wbuffer[]); + + void processWritingBuffer(int ithread, char* wbuffer[], uint32_t nP[]); + void processWritingBufferPacketByPacket(); + /************************************************************************* * Class Members ********************************************************* @@ -669,11 +696,7 @@ private: */ void writeToFile_withoutCompression(char* buf[],int numpackets, uint32_t framenum); - /** - * When acquisition is over, this is called - * @param ithread listening thread number - */ - void stopWriting(int ithread, char* wbuffer[]); + /** * updates parameters and writes to file when not a dummy frame diff --git a/slsReceiverSoftware/include/sls_receiver_defs.h b/slsReceiverSoftware/include/sls_receiver_defs.h index 04b8b19fb..fe0c715b1 100755 --- a/slsReceiverSoftware/include/sls_receiver_defs.h +++ b/slsReceiverSoftware/include/sls_receiver_defs.h @@ -8,8 +8,10 @@ #endif #include +#include #include "ansi.h" + typedef double double32_t; typedef float float32_t; typedef int int32_t; @@ -115,9 +117,9 @@ public: \param b true or false \returns string enabled, disabled */ - static string stringEnable(bool b){\ - if(b) return string("enabled"); \ - else return string("disabled"); \ + static std::string stringEnable(bool b){\ + if(b) return std::string("enabled"); \ + else return std::string("disabled"); \ }; diff --git a/slsReceiverSoftware/src/UDPBaseImplementation.cpp b/slsReceiverSoftware/src/UDPBaseImplementation.cpp index 75f7fa244..18e43edb5 100644 --- a/slsReceiverSoftware/src/UDPBaseImplementation.cpp +++ b/slsReceiverSoftware/src/UDPBaseImplementation.cpp @@ -5,9 +5,9 @@ ***********************************************/ #include "UDPBaseImplementation.h" +#include "genericSocket.h" #include // stat - #include #include using namespace std; @@ -75,10 +75,6 @@ UDPBaseImplementation::~UDPBaseImplementation(){ FILE_LOG(logDEBUG) << __AT__ << " starting"; cout << "Info: Deleting base member pointers" << endl; - if(detHostname) {delete [] detHostname; detHostname = NULL;} - if(eth) {delete [] eth; eth = NULL;} - if(fileName) {delete [] fileName; fileName = NULL;} - if(filePath) {delete [] filePath; filePath = NULL;} } @@ -129,7 +125,7 @@ char *UDPBaseImplementation::getFilePath() const{ return output; } -uint32_t UDPBaseImplementation::getFileIndex() const{ FILE_LOG(logDEBUG) << __AT__ << " starting"; return fileIndex;} +uint64_t UDPBaseImplementation::getFileIndex() const{ FILE_LOG(logDEBUG) << __AT__ << " starting"; return fileIndex;} int UDPBaseImplementation::getScanTag() const{ FILE_LOG(logDEBUG) << __AT__ << " starting"; return scanTag;} @@ -234,7 +230,7 @@ void UDPBaseImplementation::setFilePath(const char c[]){ FILE_LOG(logINFO) << "File path:" << filePath; } -void UDPBaseImplementation::setFileIndex(const uint32_t i){ +void UDPBaseImplementation::setFileIndex(const uint64_t i){ FILE_LOG(logDEBUG) << __AT__ << " starting"; fileIndex = i; @@ -394,7 +390,7 @@ void UDPBaseImplementation::resetAcquisitionCount(){ FILE_LOG(logINFO) << "totalPacketsCaught:" << totalPacketsCaught << endl; } -int UDPBaseImplementation::startReceiver(char *c=NULL){ +int UDPBaseImplementation::startReceiver(char *c){ FILE_LOG(logWARNING) << __AT__ << " doing nothing..."; FILE_LOG(logERROR) << __AT__ << " must be overridden by child classes"; return OK; @@ -433,17 +429,17 @@ void UDPBaseImplementation::closeFile(int i){ /***callback functions***/ -void UDPBaseImplementation::registerCallBackStartAcquisition(int (*func)(char*, char*,int, int, void*),void *arg){ +void UDPBaseImplementation::registerCallBackStartAcquisition(int (*func)(char*, char*,uint64_t, uint32_t, void*),void *arg){ startAcquisitionCallBack=func; pStartAcquisition=arg; } -void UDPBaseImplementation::registerCallBackAcquisitionFinished(void (*func)(int, void*),void *arg){ +void UDPBaseImplementation::registerCallBackAcquisitionFinished(void (*func)(uint64_t, void*),void *arg){ acquisitionFinishedCallBack=func; pAcquisitionFinished=arg; } -void UDPBaseImplementation::registerCallBackRawDataReady(void (*func)(int, char*, int, FILE*, char*, void*),void *arg){ +void UDPBaseImplementation::registerCallBackRawDataReady(void (*func)(uint64_t, char*, uint32_t, FILE*, char*, void*),void *arg){ rawDataReadyCallBack=func; pRawDataReady=arg; } diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index f4d2d968f..1d6a1eb23 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -764,7 +764,7 @@ void UDPStandardImplementation::resetAcquisitionCount(){ } -int UDPStandardImplementation::startReceiver(char *c=NULL){ +int UDPStandardImplementation::startReceiver(char *c){ FILE_LOG(logDEBUG1) << __AT__ << " called"; cout << "Info: Starting Receiver" << endl; @@ -1752,23 +1752,28 @@ void UDPStandardImplementation::startWriting(){ //pop fifo and if end of acquisition - if(popAndCheckEndofAcquisition(wbuf, popReady, numPackets,toFreePointers,toFreePointersOffset)){ + if(popAndCheckEndofAcquisition(ithread, wbuf, popReady, numPackets,toFreePointers,toFreePointersOffset)){ #ifdef DEBUG4 cprintf(GREEN,"Writing_Thread %d: All dummy-end buffers popped\n", ithread); #endif //finish missing packets - if(myDetectorType == EIGER - && ((tempoffset[0]!=0) || (tempoffset[1]!=(packetsPerFrame/numListeningThreads)))); + + if(myDetectorType == EIGER && + ((tempoffset[0]!=0) || (tempoffset[1]!=(packetsPerFrame/numberofListeningThreads)))); else{ stopWriting(ithread,wbuf); continue; } } - //eiger-processWritingPackets(); - //others-processWritingBuffer(); - - + switch(myDetectorType){ + case EIGER: + processWritingBufferPacketByPacket(); + break; + default: + processWritingBuffer(ithread, wbuf, numPackets); + break; + } }/*--end of loop for each buffer (inner loop)*/ @@ -1835,7 +1840,8 @@ void UDPStandardImplementation::startWriting(){ -bool UDPStandardImplementation::popAndCheckEndofAcquisition(char* wbuffer[], bool ready[], uint32_t nP[],char* toFree[],int toFreeOffset[]){ +bool UDPStandardImplementation::popAndCheckEndofAcquisition(int ithread, char* wbuffer[], bool ready[], uint32_t nP[],char* toFree[],int toFreeOffset[]){ + FILE_LOG(logDEBUG1) << __AT__ << " called"; bool endofAcquisition = true; int val; @@ -1866,7 +1872,7 @@ bool UDPStandardImplementation::popAndCheckEndofAcquisition(char* wbuffer[], boo #ifdef DEBUG4 switch(myDetectorType){ case EIGER: - wbuf_footer = (eiger_packet_footer_t*)(wbuffer[i] + footerOffset + HEADER_SIZE_NUM_TOT_PACKETS); + eiger_packet_footer_t* wbuf_footer = (eiger_packet_footer_t*)(wbuffer[i] + footerOffset + HEADER_SIZE_NUM_TOT_PACKETS); //cprintf(BLUE,"footer value:0x%x\n",i,(uint64_t)(*( (uint64_t*) wbuf_footer))); cprintf(BLUE,"Fnum[%d]:%d\n",i,(uint32_t)(*( (uint64_t*) wbuf_footer))); cprintf(BLUE,"Pnum[%d]:%d\n",i,*( (uint16_t*) wbuf_footer->packetNumber)); @@ -1887,6 +1893,54 @@ bool UDPStandardImplementation::popAndCheckEndofAcquisition(char* wbuffer[], boo +void UDPStandardImplementation::stopWriting(int ithread, char* wbuffer[]){ + FILE_LOG(logDEBUG1) << __AT__ << " called"; + + cprintf(GREEN,"Info: Writing_Thread %d: End of Acquisition\n",ithread); + + //free fifo + for(int i=0; ipush(wbuffer[i])); +#ifdef +} + +void UDPStandardImplementation::processWritingBuffer(int ithread, char* wbuffer[], uint32_t nP[]){ + FILE_LOG(logDEBUG1) << __AT__ << " called"; + + +} + + +void UDPStandardImplementation::processWritingBufferPacketByPacket(int ithread, char* wbuffer[], uint32_t nP[]){ + FILE_LOG(logDEBUG1) << __AT__ << " called"; + + uint64_t tempframenumber = ((uint32_t)(*((uint32_t*)(wbuffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS)))); + + //for gotthard and normal frame, increment frame number to separate fnum and pnum + if (myDetectorType == PROPIX ||(myDetectorType == GOTTHARD && shortFrameEnable == -1)) + tempframenumber++; + + //get frame number + tempframenumber = (tempframenumber & frameIndexMask) >> frameIndexOffset; + + //single thread, just assign and process without compression + if(!dataCompressionEnable){ + currentFrameNumber = tempframenumber; + handleWithoutDataCompression(ithread, wbuffer, nP[0]); + } + + //handling multiple threads + else{ + pthread_mutex_lock(&progressMutex); + if(tempframenumber > currentFrameNumber) + currentFrameNumber = tempframenumber; + pthread_mutex_unlock(&progressMutex); + handleDataCompression(ithread,wbuffer,d, xmax, ymax, nf); + } + + + +} @@ -2173,66 +2227,9 @@ int UDPStandardImplementation::startWriting(){ - //pop - endofacquisition = true; - for(i=0;ipop(wbuf[i]); -#ifdef FIFO_DEBUG - cprintf(GREEN,"%d writer poped 0x%x from fifo %d\n", ithread, (void*)(wbuf[i]), i); -#endif - numpackets[i] = (uint32_t)(*((uint32_t*)wbuf[i])); - -#ifdef VERYDEBUG - cprintf(GREEN,"%d numpackets: %d for fifo :%d\n", ithread, numpackets[i], i); -#endif - if(numpackets < 0){ - cprintf(BG_RED,"negative numpackets[%d]%d\n",i,numpackets[i]); - exit(-1); - } - //dont pop again if dummy packet - else if(numpackets[i] == 0){ - popready[i] = false; -#ifdef EIGER_DEBUG3 - cprintf(GREEN,"%d Dummy frame popped out of fifo %d",ithread, i); -#endif - }else{ - endofacquisition = false; - if(numpackets[i] == onePacketSize){ -#ifdef EIGER_DEBUG3 - wbuf_footer = (eiger_packet_footer_t*)(wbuf[i] + footer_offset + HEADER_SIZE_NUM_TOT_PACKETS); - //cprintf(BLUE,"footer value:0x%x\n",i,(uint64_t)(*( (uint64_t*) wbuf_footer))); - cprintf(BLUE,"tempframenum[%d]:%d\n",i,(uint32_t)(*( (uint64_t*) wbuf_footer))); - cprintf(BLUE,"packetnum[%d]:%d\n",i,*( (uint16_t*) wbuf_footer->packetnum)); -#endif - } - - if(myDetectorType == EIGER){ - tofree[tofreeoffset[i]] = wbuf[i]; - tofreeoffset[i]++; - } - } - - } - } - //END OF ACQUISITION - if(endofacquisition){ -#ifdef EIGER_DEBUG3 - cprintf(GREEN,"%d Both dummy frames\n", ithread); -#endif - //remaining packets to be written - if((myDetectorType == EIGER) && - ((tempoffset[0]!=0) || (tempoffset[1]!=(packetsPerFrame/numListeningThreads)))); - else{ - - stopWriting(ithread,wbuf); - continue; - } - } - if(myDetectorType == EIGER){ @@ -2539,31 +2536,7 @@ int UDPStandardImplementation::startWriting(){ } - //other detectors other than eiger - else{ - //frame number for progress - if ((myDetectorType == PROPIX) ||((myDetectorType == GOTTHARD) && (shortFrame == -1))) - tempframenum[0] = (((((uint32_t)(*((uint32_t*)(wbuf[ithread] + HEADER_SIZE_NUM_TOT_PACKETS))))+1)& (frameIndexMask)) >> frameIndexOffset); - else - tempframenum[0] = ((((uint32_t)(*((uint32_t*)(wbuf[ithread] + HEADER_SIZE_NUM_TOT_PACKETS))))& (frameIndexMask)) >> frameIndexOffset); - - if(numWriterThreads == 1) - currframenum = tempframenum[0]; - else{ - pthread_mutex_lock(&progress_mutex); - if(tempframenum[0] > currframenum) - currframenum = tempframenum[0]; - pthread_mutex_unlock(&progress_mutex); - } - - - //without datacompression: write datacall back, or write data, free fifo - if(!dataCompression) handleWithoutDataCompression(ithread,wbuf, numpackets[0]); - //data compression - else handleDataCompression(ithread,wbuf,d, xmax, ymax, nf); - - } } From 169a91b6aceb7b952815e08d73d5d63408d8a602 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Fri, 16 Oct 2015 10:47:21 +0200 Subject: [PATCH 153/474] some --- .../include/UDPStandardImplementation.h | 80 +- .../src/UDPStandardImplementation.cpp | 817 ++++++++---------- 2 files changed, 405 insertions(+), 492 deletions(-) diff --git a/slsReceiverSoftware/include/UDPStandardImplementation.h b/slsReceiverSoftware/include/UDPStandardImplementation.h index 0c1d4ac43..6b08fab2b 100644 --- a/slsReceiverSoftware/include/UDPStandardImplementation.h +++ b/slsReceiverSoftware/include/UDPStandardImplementation.h @@ -317,15 +317,6 @@ private: */ void startListening(); - /** - * Thread started which writes packets to file. - * It pops the fifo, processes and writes packets to file and pushes the addresses into the fifoFree - * This is continuously looped for each buffer in a nested loop, which is again looped for each acquisition - * Exits only for changing dynamic range, 10G parameters etc and recreated - * - */ - void startWriting(); - /** * Called by startListening * Listens to buffer, until packet(s) received or shutdownUDPsocket called by client @@ -368,6 +359,16 @@ private: */ uint32_t processListeningBuffer(int ithread, int cSize,char* temp); + /** + * Thread started which writes packets to file. + * It calls popAndCheckEndofAcquisition to pop fifo and check if it is a dummy end buffer + * It then calls a function to process and write packets to file and pushes the addresses into the fifoFree + * This is continuously looped for each buffer in a nested loop, which is again looped for each acquisition + * Exits only for changing dynamic range, 10G parameters etc and recreated + * + */ + void startWriting(); + /** * Called by StartWriting * Pops buffer from all the FIFOs and checks for dummy frames and end of acquisition @@ -392,9 +393,40 @@ private: */ void stopWriting(int ithread, char* wbuffer[]); - void processWritingBuffer(int ithread, char* wbuffer[], uint32_t nP[]); - void processWritingBufferPacketByPacket(); + /** + * Called by startWriting or processWritingBufferPacketByPacket upon reading a frame (for eiger) + * Updates parameters, (writes headers for eiger) and writes to file when not a dummy frame + * Copies data for gui display and frees addresses popped from FIFOs + * @param ithread writing thread index + * @param wbuffer writing buffer popped out from FIFO + * @param npackets number of packets + */ + void handleWithoutDataCompression(int ithread, char* wbuffer[],int npackets); + /** + * Calle by handleWithoutDataCompression + * Creating headers Writing to file without compression + * @param wbuffer is the address of buffer popped out of FIFO + * @param numpackets is the number of packets + */ + void writeFileWithoutCompression(char* wbuffer[],int numpackets); + + /** + * Called by writeToFileWithoutCompression() + * Create headers for file writing (at the moment, this is eiger specific) + * @param wbuffer writing buffer popped from FIFOs + */ + void createHeaders(char* wbuffer[]); + + /** + * Called by handleWithoutDataCompression and handleWithCompression after writing to file + * Copy frames for GUI and updates appropriate parameters for frequency frames to gui + * Uses semaphore for nth frame mode + * @param buffer buffer to copy + */ + void copyFrameToGui(char* buffer[]); + + void processWritingBufferPacketByPacket(); /************************************************************************* * Class Members ********************************************************* @@ -674,11 +706,7 @@ private: private: - /** - * Copy frames to gui - * uses semaphore for nth frame mode - */ - void copyFrameToGui(char* startbuf[], char* buf=NULL); + /** * Creates new tree and file for compression @@ -688,26 +716,6 @@ private: */ int createCompressionFile(int ithr, int iframe); - /** - * Writing to file without compression - * @param buf is the address of buffer popped out of fifo - * @param numpackets is the number of packets - * @param framenum current frame number - */ - void writeToFile_withoutCompression(char* buf[],int numpackets, uint32_t framenum); - - - - /** - * updates parameters and writes to file when not a dummy frame - * Also calls writeToFile_withoutCompression or handleDataCompression - * Called by startWriting() - * @param ithread writing thread number - * @param wbuffer writer buffer - * @param npackets number of packets - */ - void handleWithoutDataCompression(int ithread, char* wbuffer[],int npackets); - /** * data compression for each fifo output * @param ithread writing thread number diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 1d6a1eb23..f01997cf8 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -775,8 +775,11 @@ int UDPStandardImplementation::startReceiver(char *c){ measurementStarted = false; startFrameIndex = 0; frameIndex = 0; - if(!acqStarted) + if(!acqStarted){ currentFrameNumber = 0; //has to be zero to add to startframeindex for each scan + acquisitionIndex = 0; + frameIndex = 0; + } for(int i = 0; i < numberofListeningThreads; ++i) totalListeningFrameCount[i] = 0; packetsCaught = 0; @@ -983,7 +986,7 @@ void UDPStandardImplementation::readFrame(char* c,char** raw, uint64_t &startAcq cprintf(CYAN,"Info: gonna post\n"); #endif //release after getting data - sem_post(&smp); + sem_post(&writerGuiSemaphore); } #ifdef DEBUG4 cprintf(CYAN,"Info: done post\n"); @@ -1771,7 +1774,10 @@ void UDPStandardImplementation::startWriting(){ processWritingBufferPacketByPacket(); break; default: - processWritingBuffer(ithread, wbuf, numPackets); + if(!dataCompressionEnable) + handleWithoutDataCompression(ithread, wbuf, numPackets[0]); + else + handleDataCompression(ithread,wbuf,d, xmax, ymax, nf); break; } @@ -1899,180 +1905,372 @@ void UDPStandardImplementation::stopWriting(int ithread, char* wbuffer[]){ cprintf(GREEN,"Info: Writing_Thread %d: End of Acquisition\n",ithread); //free fifo - for(int i=0; ipush(wbuffer[i])); -#ifdef -} - -void UDPStandardImplementation::processWritingBuffer(int ithread, char* wbuffer[], uint32_t nP[]){ - FILE_LOG(logDEBUG1) << __AT__ << " called"; - - -} - - -void UDPStandardImplementation::processWritingBufferPacketByPacket(int ithread, char* wbuffer[], uint32_t nP[]){ - FILE_LOG(logDEBUG1) << __AT__ << " called"; - - uint64_t tempframenumber = ((uint32_t)(*((uint32_t*)(wbuffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS)))); - - //for gotthard and normal frame, increment frame number to separate fnum and pnum - if (myDetectorType == PROPIX ||(myDetectorType == GOTTHARD && shortFrameEnable == -1)) - tempframenumber++; - - //get frame number - tempframenumber = (tempframenumber & frameIndexMask) >> frameIndexOffset; - - //single thread, just assign and process without compression - if(!dataCompressionEnable){ - currentFrameNumber = tempframenumber; - handleWithoutDataCompression(ithread, wbuffer, nP[0]); +#ifdef FIFODEBUG + cprintf(GREEN,"Writing_Thread %d: Freeing dummy-end buffer. Pushed into fifofree %p for listener %d\n", ithread,(void*)(wbuffer[i]),i); +#endif } - //handling multiple threads - else{ - pthread_mutex_lock(&progressMutex); - if(tempframenumber > currentFrameNumber) - currentFrameNumber = tempframenumber; - pthread_mutex_unlock(&progressMutex); - handleDataCompression(ithread,wbuffer,d, xmax, ymax, nf); + //all threads need to close file, reset mask and exit loop + closeFile(ithread); + pthread_mutex_lock(&statusMutex); + writerThreadsMask^=(1<> frameIndexOffset; + //set indices + acquisitionIndex = currentFrameNumber - startAcquisitionIndex; + frameIndex = currentFrameNumber - startFrameIndex; } - -} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -/* - acquisitionIndex = currframenum - startAcquisitionIndex - frameIndex = currframenum - startFrameIndex; - -} -*/ - - - - -void UDPStandardImplementation::copyFrameToGui(char* startbuf[], char* buf){ - FILE_LOG(logDEBUG1) << __AT__ << " called"; -#ifdef VERY_VERY_DEBUG -cout << "copyframe" << endl; + //callback to write data + if (cbAction < DO_EVERYTHING){ + switch(myDetectorType){ + case EIGER: + for(i=0;i 0) + writeFileWithoutCompression(wbuffer, npackets); +#ifdef DEBUG4 + cprintf(GREEN,"Writing_Thread: Writing done\nGoing to copy frame\n"); #endif - //random read when gui not ready , also command line doesnt have nthframetogui - //else guidata always null as guidataready is always 1 after 1st frame, and seccond data never gets copied - if((!nFrameToGui) && (!guiData)){ -#ifdef VERY_VERY_DEBUG - cprintf(GREEN,"doing nothing\n"); + + //copy frame for gui + if(npackets >= packetsPerFrame) + copyFrameToGui(wbuffer); +#ifdef DEBUG4 + cprintf(GREEN,"Writing_Thread: Copied frame\n"); +#endif + + + //free fifo addresses (eiger frees for each packet later) + if(myDetectorType != EIGER){ + while(!fifoFree[0]->push(wbuffer[0])); +#ifdef FIFODEBUG + cprintf(GREEN,"Writing_Thread %d: Freed buffer, pushed into fifofree %p for listener 0\n",ithread, (void*)(wbuffer[0])); +#endif + } +} + + + + +void UDPStandardImplementation::writeFileWithoutCompression(char* wbuffer[],int numpackets){ + FILE_LOG(logDEBUG1) << __AT__ << " called"; + + int i; + + //create headers for eiger +#ifdef WRITE_HEADERS + if (myDetectorType == EIGER && cbAction == DO_EVERYTHING) + createHeaders(wbuffer); +#endif + + //if write enabled + if((fileWriteEnable) && (sfilefd)){ + int offset = HEADER_SIZE_NUM_TOT_PACKETS; //offset (not eiger) to keep track of how many packets saved + int packetsToSave; //how many packets to save at a time + volatile uint64_t tempframenumber; + int lastpacket; + + //loop to take care of creating new files when it reaches max packets per file + while(numpackets > 0){ + + //to create new file when max reached + packetsToSave = maxPacketsPerFile - packetsInFile; + if(packetsToSave > numpackets) + packetsToSave = numpackets; + + //write to file + if(cbAction == DO_EVERYTHING){ + switch(myDetectorType){ + case EIGER: + for(i=0; i= (uint32_t)maxPacketsPerFile){ + //for packet loss, because currframenum is the latest one for eiger + if(myDetectorType != EIGER){ + lastpacket = (((packetsToSave - 1) * onePacketSize) + offset); + + //get frame number (eiger already gets it when it does packet to packet processing) + tempframenumber = ((uint32_t)(*((uint32_t*)(wbuffer[0] + lastpacket)))); + //for gotthard and normal frame, increment frame number to separate fnum and pnum + if (myDetectorType == PROPIX ||(myDetectorType == GOTTHARD && shortFrameEnable == -1)) + tempframenumber++; + //get frame number + currentFrameNumber = (tempframenumber & frameIndexMask) >> frameIndexOffset; + //set indices + acquisitionIndex = currentFrameNumber - startAcquisitionIndex; + frameIndex = currentFrameNumber - startFrameIndex; + } +#ifdef DEBUG3 + cprintf(GREEN,"Writing_Thread: Current Frame Number:%d\n",currentFrameNumber); +#endif + createNewFile(); + } + + //increase offset + if(myDetectorType != EIGER) + offset += (packetsToSave * onePacketSize); + numpackets -= packetsToSave; + } + } + + //only update parameters + else{ + if(numberofWriterThreads > 1) pthread_mutex_lock(&writeMutex); + packetsInFile += numpackets; + packetsCaught += (numpackets - numMissingPackets); + totalPacketsCaught += (numpackets - numMissingPackets); + numMissingPackets = 0; + if(numberofWriterThreads > 1) pthread_mutex_unlock(&writeMutex); + } + +} + + + + + +void UDPStandardImplementation::createHeaders(char* wbuffer[]){ + + eiger_packet_header_t* wbuf_header=0; + eiger_packet_footer_t* wbuf_footer=0; + int port = 0, missingPacket; + + for (int i = 0; i < packetsPerFrame; i++){ + + wbuf_header = (eiger_packet_header_t*) wbuffer[i]; + wbuf_footer = (eiger_packet_footer_t*)(wbuffer[i] + footerOffset); +#ifdef DEBUG4 + cprintf(GREEN, "Loop index:%d Pnum:%d\n",i,*( (uint16_t*) wbuf_footer->packetNumber)); +#endif + //which port + if (i ==(packetsPerFrame/2)) port = 1; + + //missing packet + if (*( (uint16_t*) wbuf_header->missingPacket)== missingPacketValue){ +#ifdef DEBUG4 + cprintf(GREEN,"Missing packet at %d\n", i+1); +#endif + missingPacket = 1; + //add frame and packet numbers + *( (uint64_t*) wbuf_footer) = (uint64_t)((currentFrameNumber+1)); + *( (uint16_t*) wbuf_footer->packetNumber) = (i+1); + } + //normal packet + else{ + missingPacket = 0; + //correct the packet numbers of port2 so that port1 and 2 are not the same + if(port) *( (uint16_t*) wbuf_footer->packetNumber) = (*( (uint16_t*) wbuf_footer->packetNumber))+(packetsPerFrame/2); + } + //DEBUGGING + if(*( (uint16_t*) wbuf_footer->packetNumber) != (i+1)){ + cprintf(BG_RED, "Packet Number Mismatch! i:%d pnum:%d fnum:%d missingPacket:%d\n", + i,*( (uint16_t*) wbuf_footer->packetNumber),currentFrameNumber,*( (uint16_t*) wbuf_header->missingPacket)); + exit(-1); + } + //overwriting port number and dynamic range + *( (uint8_t*) wbuf_header->portIndex) = port; + *( (uint8_t*) wbuf_header->dynamicRange) = dynamicRange; + } +} + + +void UDPStandardImplementation::copyFrameToGui(char* buffer[]){ + FILE_LOG(logDEBUG1) << __AT__ << " called"; + + int i; + + //random read (gui not ready) + //need to toggle guiDataReady or the second frame wont be copied + if((!FrameToGuiFrequency) && (!guiData)){ +#ifdef DEBUG4 + cprintf(GREEN,"Writing_Thread: CopyingFrame: Resetting guiDataReady\n"); #endif pthread_mutex_lock(&dataReadyMutex); guiDataReady=0; pthread_mutex_unlock(&dataReadyMutex); } - //random read or nth frame read, gui needs data now or it is the first frame + //random read (gui ready) or nth frame read: gui needs data now or it is the first frame else{ -#ifdef VERY_VERY_DEBUG - cprintf(GREEN,"gui needs data now or 1st frame\n"); +#ifdef DEBUG4 + cprintf(GREEN,"Writing_Thread: CopyingFrame: Gui needs data now OR 1st frame\n"); #endif pthread_mutex_lock(&dataReadyMutex); guiDataReady=0; -#ifdef VERY_VERY_DEBUG - cprintf(GREEN,"guidataready is 0, copying data\n"); +#ifdef DEBUG4 + cprintf(GREEN,"Writing_Thread: CopyingFrame: guidataready is 0, Copying data\n"); #endif - //eiger - if(startbuf != NULL){ + switch(myDetectorType){ + case EIGER: + for(int i=0; ipush(wbuffer[i])); -#ifdef FIFO_DEBUG - cprintf(GREEN,"%d writer free dummy pushed into fifofree %x for listener %d\n", ithread,(void*)(wbuffer[i]),i); -#endif - } - - - - //all threads need to close file, reset mask and exit loop - closeFile(ithread); - pthread_mutex_lock(&statusMutex); - writerthreads_mask^=(1< 0){ - - //for progress and packet loss calculation(new files) - if(myDetectorType == EIGER); - else if ((myDetectorType == PROPIX)||((myDetectorType == GOTTHARD) && (shortFrame == -1))) - tempframenum = (((((uint32_t)(*((uint32_t*)(buf[0] + HEADER_SIZE_NUM_TOT_PACKETS))))+1)& (frameIndexMask)) >> frameIndexOffset); - else - tempframenum = ((((uint32_t)(*((uint32_t*)(buf[0] + HEADER_SIZE_NUM_TOT_PACKETS))))& (frameIndexMask)) >> frameIndexOffset); - - if(numWriterThreads == 1) - currframenum = tempframenum; - else{ - if(tempframenum > currframenum) - currframenum = tempframenum; - } -#ifdef VERYDEBUG - cout << "tempframenum:" << dec << tempframenum << " curframenum:" << currframenum << endl; -#endif - - //lock - if(numWriterThreads > 1) - pthread_mutex_lock(&write_mutex); - - - //to create new file when max reached - packetsToSave = maxPacketsPerFile - packetsInFile; - if(packetsToSave > numpackets) - packetsToSave = numpackets; -/**next time offset is still plus header length*/ - if(myDetectorType == EIGER){ - for(i=0;i= (uint32_t)maxPacketsPerFile){ - - //for packet loss, because currframenum is the latest one for eiger - if(myDetectorType != EIGER){ - lastpacket = (((packetsToSave - 1) * onePacketSize) + offset); - - if ((myDetectorType == PROPIX)||((myDetectorType == GOTTHARD) && (shortFrame == -1))) - - tempframenum = (((((uint32_t)(*((uint32_t*)(buf[0] + lastpacket))))+1)& (frameIndexMask)) >> frameIndexOffset); - else - tempframenum = ((((uint32_t)(*((uint32_t*)(buf[0] + lastpacket))))& (frameIndexMask)) >> frameIndexOffset); - } - if(numWriterThreads == 1) - currframenum = tempframenum; - else{ - if(tempframenum > currframenum) - currframenum = tempframenum; - } -#ifdef VERYDEBUG - cout << "tempframenum:" << dec << tempframenum << " curframenum:" << currframenum << endl; -#endif - //create - createNewFile(); - } - - //unlock - if(numWriterThreads > 1) - pthread_mutex_unlock(&write_mutex); - - if(myDetectorType != EIGER) - offset += (packetsToSave * onePacketSize); - numpackets -= packetsToSave; - } - - } - else{ - if(numWriterThreads > 1) - pthread_mutex_lock(&write_mutex); - packetsInFile += numpackets; - packetsCaught += (numpackets - numMissingPackets); - totalPacketsCaught += (numpackets - numMissingPackets); - numMissingPackets = 0; - if(numWriterThreads > 1) - pthread_mutex_unlock(&write_mutex); - } -} - - - - - - - - -void UDPStandardImplementation::handleWithoutDataCompression(int ithread, char* wbuffer[],int npackets){ - int i, missingpacket,port = 0; - - - if (cbAction < DO_EVERYTHING){ - if (myDetectorType == EIGER){ - for(i=0;i 0){ - -#ifdef WRITE_HEADERS - if (myDetectorType == EIGER){ - - eiger_packet_header_t* wbuf_header=0; - eiger_packet_footer_t* wbuf_footer=0; - - - for (i = 0; i < packetsPerFrame; i++){ - - wbuf_header = (eiger_packet_header_t*) wbuffer[i]; - wbuf_footer = (eiger_packet_footer_t*)(wbuffer[i] + footer_offset); -#ifdef EIGER_DEBUG3 - cprintf(GREEN, "i:%d pnum:%d \n",i,*( (uint16_t*) wbuf_footer->packetnum)); -#endif - //which port - if (i ==(packetsPerFrame/2)) - port = 1; - - - - //missing packet - if (*( (uint16_t*) wbuf_header->missingpacket)== missingPacketValue){ -#ifdef VERY_VERBOSE - cprintf(GREEN,"missing packet at %d\n", i+1); -#endif - missingpacket = 1; - //add frame and packet numbers - *( (uint64_t*) wbuf_footer) = (uint64_t)((currframenum+1)); - *( (uint16_t*) wbuf_footer->packetnum) = (i+1); - }else{ - missingpacket = 0; - - if(*( (uint16_t*) wbuf_footer->packetnum)!= (i-(port*packetsPerFrame/numListeningThreads))+1){ - cprintf(BG_RED, "pnum mismatch num4! i:%d pnum:%d fnum:%d\n", - i,*( (uint16_t*) wbuf_footer->packetnum),currframenum); - exit(-1); - } - - //move packet numbers to num2, and compensate for port1 starting pnum from 0 - if(port) - *( (uint16_t*) wbuf_footer->packetnum) = (*( (uint16_t*) wbuf_footer->packetnum))+(packetsPerFrame/2); - } - - if(*( (uint16_t*) wbuf_footer->packetnum) != (i+1)){ - cprintf(BG_RED, "pnum mismatch! i:%d pnum:%d fnum:%d\n", - i,*( (uint16_t*) wbuf_footer->packetnum),currframenum); - if (*( (uint16_t*) wbuf_header->missingpacket) == missingPacketValue) - cprintf(BG_RED,"missing packet though\n"); - exit(-1); - } - - //overwriting port number and dynamic range - *( (uint8_t*) wbuf_header->portnum) = port; - *( (uint8_t*) wbuf_header->dynamicrange) = dynamicRange; - - - -#ifdef VERYDEBUG - if((i==0)||(i==1)){ - cprintf(GREEN, "%d packet header:0x%016llx missingpacket:0x%x\n",i, - (uint64_t)()*( (uint64_t*) wbuf_header)), *( (uint16_t*) wbuf_header->missingpacket)); - - cprintf(GREEN, "%d - 0x%x - %d\n", i, - *( (uint16_t*) wbuf_header->missingpacket), *( (uint16_t*) wbuf_footer->packetnum)); - } -#endif - - } - } -#endif - - writeToFile_withoutCompression(wbuffer, npackets,currframenum); - } - -#ifdef VERYDEBUG - cprintf(GREEN,"written everyting\n"); -#endif - } - - - if(myDetectorType == EIGER) { - -#ifdef VERYDEBUG - cprintf(GREEN,"gonna copy frame\n"); -#endif - copyFrameToGui(wbuffer); -#ifdef VERYDEBUG - cprintf(GREEN,"copied frame\n"); -#endif - }else{ - //copy to gui - if(npackets >= packetsPerFrame){//min 1 frame, but neednt be - //if(npackets == packetsPerFrame * numJobsPerThread){ //only full frames - copyFrameToGui(NULL,wbuffer[0]+HEADER_SIZE_NUM_TOT_PACKETS); -#ifdef VERYVERBOSE - cout << ithread << " finished copying" << endl; -#endif - } - - //else cout << "unfinished buffersize" << endl; - while(!fifoFree[0]->push(wbuffer[0])); -#ifdef FIFO_DEBUG - cprintf(GREEN,"%d writer freed pushed into fifofree %x for listener 0\n",ithread, (void*)(wbuffer[0])); -#endif - - } -} @@ -2875,6 +2764,22 @@ void UDPStandardImplementation::handleWithoutDataCompression(int ithread, char* void UDPStandardImplementation::handleDataCompression(int ithread, char* wbuffer[], char* data, int xmax, int ymax, int &nf){ FILE_LOG(logDEBUG1) << __AT__ << " called"; + uint64_t tempframenumber = ((uint32_t)(*((uint32_t*)(wbuffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS)))); + //for gotthard and normal frame, increment frame number to separate fnum and pnum + if (myDetectorType == PROPIX ||(myDetectorType == GOTTHARD && shortFrameEnable == -1)) + tempframenumber++; + //get frame number + tempframenumber = (tempframenumber & frameIndexMask) >> frameIndexOffset; + + + pthread_mutex_lock(&progressMutex); + if(tempframenumber > currentFrameNumber) + currentFrameNumber = tempframenumber; + pthread_mutex_unlock(&progressMutex); + //set indices + acquisitionIndex = currentFrameNumber - startAcquisitionIndex; + frameIndex = currentFrameNumber - startFrameIndex; + #if defined(MYROOT1) && defined(ALLFILE_DEBUG) writeToFile_withoutCompression(wbuf[0], numpackets,currframenum); #endif From 253383331fe66ff38a1cbde12f5c3602b4e21dab Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Mon, 19 Oct 2015 16:06:54 +0200 Subject: [PATCH 154/474] vg --- .../include/UDPStandardImplementation.h | 89 +-- .../src/UDPStandardImplementation.cpp | 632 ++++++++++-------- 2 files changed, 386 insertions(+), 335 deletions(-) diff --git a/slsReceiverSoftware/include/UDPStandardImplementation.h b/slsReceiverSoftware/include/UDPStandardImplementation.h index 6b08fab2b..430b5c5d1 100644 --- a/slsReceiverSoftware/include/UDPStandardImplementation.h +++ b/slsReceiverSoftware/include/UDPStandardImplementation.h @@ -291,11 +291,19 @@ private: int setupWriter(); /** - * Creates new file + * Creates new file and reset some parameters * @return OK or FAIL */ int createNewFile(); + /** + * Creates new tree and file for compression + * @param ithread thread number + * @param iframe frame number + * @return OK or FAIL + */ + int createCompressionFile(int ithread, int iframe); + /** * Static function - Starts Listening Thread of this object * @param this_pointer pointer to this object @@ -370,7 +378,7 @@ private: void startWriting(); /** - * Called by StartWriting + * Called by processWritingBuffer and processWritingBufferPacketByPacket * Pops buffer from all the FIFOs and checks for dummy frames and end of acquisition * @param ithread current thread index * @param wbuffer the buffer array that is popped from all the FIFOs @@ -383,7 +391,7 @@ private: bool popAndCheckEndofAcquisition(int ithread, char* wbuffer[], bool ready[], uint32_t nP[],char* toFree[],int toFreeOffset[]); /** - * Called by StartWriting + * Called by processWritingBuffer and processWritingBufferPacketByPacket * When dummy-end buffers are popped from all FIFOs (acquisition over), this is called * It frees the FIFO addresses, closes all files * For data compression, it waits for all threads to be done @@ -394,7 +402,7 @@ private: void stopWriting(int ithread, char* wbuffer[]); /** - * Called by startWriting or processWritingBufferPacketByPacket upon reading a frame (for eiger) + * Called by processWritingBuffer and processWritingBufferPacketByPacket * Updates parameters, (writes headers for eiger) and writes to file when not a dummy frame * Copies data for gui display and frees addresses popped from FIFOs * @param ithread writing thread index @@ -412,7 +420,7 @@ private: void writeFileWithoutCompression(char* wbuffer[],int numpackets); /** - * Called by writeToFileWithoutCompression() + * Called by writeToFileWithoutCompression * Create headers for file writing (at the moment, this is eiger specific) * @param wbuffer writing buffer popped from FIFOs */ @@ -426,7 +434,24 @@ private: */ void copyFrameToGui(char* buffer[]); - void processWritingBufferPacketByPacket(); + void processWritingBuffer(int ithread); + + void processWritingBufferPacketByPacket(int ithread); + + void waitWritingBufferForNextAcquisition(int ithread); + + /** + * Called by processWritingBuffer + * Processing fifo popped buffers for data compression + * Updates parameters and writes to file + * Copies data for gui display and frees addresses popped from FIFOs + * @param ithread writing thread number + * @param wbuffer writer buffer + * @param nf number of frames + */ + void handleDataCompression(int ithread, char* wbuffer[], int &nf); + + /************************************************************************* * Class Members ********************************************************* @@ -683,58 +708,6 @@ private: * 2 we open, close, write file, callback does not do anything */ int cbAction; - - - - - - - - - - - - - - - - - - - - -private: - - - - - /** - * Creates new tree and file for compression - * @param ithr thread number - * @param iframe frame number - *\returns OK for succces or FAIL for failure - */ - int createCompressionFile(int ithr, int iframe); - - /** - * data compression for each fifo output - * @param ithread writing thread number - * @param wbuffer writer buffer - * @param data pointer to the next packet start - * @param xmax max pixels in x direction - * @param ymax max pixels in y direction - * @param nf nf - */ - void handleDataCompression(int ithread, char* wbuffer[], char* data, int xmax, int ymax, int &nf); - - - - - - - //filter - - }; diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index f01997cf8..4b253966b 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1382,6 +1382,36 @@ int UDPStandardImplementation::createNewFile(){ +int UDPStandardImplementation::createCompressionFile(int ithread, int iframe){ + FILE_LOG(logDEBUG1) << __AT__ << " called"; + +#ifdef MYROOT1 + char temp[MAX_STR_LENGTH]; + //create file name for gui purposes, and set up acquistion parameters + sprintf(temp, "%s/%s_fxxx_%d_%d.root", filePath,fileName,fileIndex,ithread); + //file + myFile[ithread] = new TFile(temp,"RECREATE");/** later return error if it exists */ + cprintf(GREEN,"Writing_Thread %d: Created Compression File: %s\n",ithread, temp); + //tree + sprintf(temp, "%s_fxxx_%d_%d",fileName,fileIndex,ithread); + myTree[ithread]=singlePhotonDetectorObject[ithread]->initEventTree(temp, &iframe); + //resets the pedestalSubtraction array and the commonModeSubtraction + singlePhotonDetectorObject[ithread]->newDataSet(); + if(myFile[ithread]==NULL){ + cprintf(BG_RED,"Error: File Null\n"); + return FAIL; + } + if(!myFile[ithread]->IsOpen()){ + cprintf(BG_RED,"Error: File Not Open\n") + return FAIL; + } + return OK; +#endif + return FAIL; +} + + + void* UDPStandardImplementation::startListeningThread(void* this_pointer){ FILE_LOG(logDEBUG1) << __AT__ << " called"; ((UDPStandardImplementation*)this_pointer)->startListening(); @@ -1399,6 +1429,8 @@ void* UDPStandardImplementation::startWritingThread(void* this_pointer){ + + void UDPStandardImplementation::startListening(){ FILE_LOG(logDEBUG1) << __AT__ << " called"; @@ -1517,6 +1549,10 @@ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int lSize, in } + + + + void UDPStandardImplementation::startFrameIndices(int ithread){ FILE_LOG(logDEBUG1) << __AT__ << " called"; @@ -1552,6 +1588,8 @@ void UDPStandardImplementation::startFrameIndices(int ithread){ + + void UDPStandardImplementation::stopListening(int ithread, int numbytes){ FILE_LOG(logDEBUG1) << __AT__ << " called"; @@ -1629,6 +1667,7 @@ void UDPStandardImplementation::stopListening(int ithread, int numbytes){ + uint32_t UDPStandardImplementation::processListeningBuffer(int ithread, int cSize, char* temp){ FILE_LOG(logDEBUG1) << __AT__ << " called"; @@ -1721,17 +1760,99 @@ void UDPStandardImplementation::startWriting(){ //let calling function know thread started and obtained current threadStarted = 1; + switch(myDetectorType){ + case EIGER: + processWritingBufferPacketByPacket(ithread); + break; + default: + processWritingBuffer(ithread); + break; + } + +} + + + +void UDPStandardImplementation::processWritingBuffer(int ithread, int &nf){ + FILE_LOG(logDEBUG1) << __AT__ << " called"; + + //variable definitions + char* wbuf[numberofListeningThreads]; //buffer popped from FIFO + sfilefd = NULL; //file pointer + + /* outer loop - loops once for each acquisition */ + //infinite loop, exited only to change dynamic range, 10G parameters etc (then recreated again) + while(true){ + + //--reset parameters before acquisition + nf = 0; + + /* inner loop - loop for each buffer */ + //until mask unset (udp sockets shut down by client) + while((1 << ithread) & writerThreadsMask){ + //pop + fifo[0]->pop(wbuf[0]); +#ifdef FIFODEBUG + cprintf(GREEN,"Writing_Thread %d: Popped %p from FIFO %d\n", ithread, (void*)(wbuf[0]),0); +#endif + int numPackets = (uint32_t)(*((uint32_t*)wbuf[0])); + if(numPackets < 0) + cprintf(BG_RED,"Error: Negative packet numbers: %d for FIFO %d\n",numPackets,0); +#ifdef DEBUG4 + cprintf(GREEN,"Writing_Thread %d: Number of Packets: %d for FIFO %d\n", ithread, numPackets, 0); +#endif + + + //dummy packet + if(numPackets == dummyPacketValue){ +#ifdef DEBUG3 + cprintf(GREEN,"Writing_Thread %d: Dummy frame popped out of FIFO %d",ithread, 0); +#endif + stopWriting(ithread,wbuf); + continue; + } + + + + //process + if(!dataCompressionEnable) + handleWithoutDataCompression(ithread, wbuf, numPackets); + else{ +#if defined(MYROOT1) && defined(ALLFILE_DEBUG) + if(npackets > 0) + writeFileWithoutCompression(wbuf, numPackets); +#endif + handleDataCompression(ithread,wbuf,nf); + } + }/*--end of loop for each buffer (inner loop)*/ + + waitWritingBufferForNextAcquisition(ithread); + + }/*--end of loop for each acquisition (outer loop) */ + + +} + + + + + + + + +void UDPStandardImplementation::processWritingBufferPacketByPacket(int ithread){ + FILE_LOG(logDEBUG1) << __AT__ << " called"; + + //variable definitions char* wbuf[numberofListeningThreads]; //buffer popped from FIFO sfilefd = NULL; //file pointer bool popReady[numberofListeningThreads]; //if the FIFO can be popped - uint32_t numPackets[numberofListeningThreads]; //number of packets popped from the FIFO - //eiger specific - int MAX_NUM_PACKETS = 1024; //highest 32 bit has 1024 number of packets - char* toFreePointers[MAX_NUM_PACKETS]; //pointers to free for each frame - int toFreePointersOffset[numberofListeningThreads]; //offset of pointers to free added for each thread - - + uint32_t numPackets[numberofListeningThreads]; //number of packets popped from the FIFO + //eiger specific + int MAX_NUM_PACKETS = 1024; //highest 32 bit has 1024 number of packets + char* toFreePointers[MAX_NUM_PACKETS]; //pointers to free for each frame + int toFreePointersOffset[numberofListeningThreads]; //offset of pointers to free added for each thread /* outer loop - loops once for each acquisition */ //infinite loop, exited only to change dynamic range, 10G parameters etc (then recreated again) @@ -1745,10 +1866,11 @@ void UDPStandardImplementation::startWriting(){ toFreePointersOffset[i] = (i*packetsPerFrame/numberofListeningThreads); } for(int i=0; i> frameIndexOffset; + //handle multi threads + pthread_mutex_lock(&progressMutex); + if(tempframenumber > currentFrameNumber) + currentFrameNumber = tempframenumber; + pthread_mutex_unlock(&progressMutex); + //set indices + acquisitionIndex = currentFrameNumber - startAcquisitionIndex; + frameIndex = currentFrameNumber - startFrameIndex; -} + //variable definitions + char* buff[2] = 0; //an array just to be compatible with copyframetogui + char* data = wbuffer[0]+ HEADER_SIZE_NUM_TOT_PACKETS; //data pointer to the next memory to be analysed + int ndata; //size of data returned + int np; //remaining number of packets returned + int npackets = (uint32_t)(*((uint32_t*)wbuffer[0])); //number of total packets + int remainingsize = npackets * onePacketSize; //size of the memory slot to be analyzed + + eventType thisEvent = PEDESTAL; + int once = 0; + int xmax = 0, ymax = 0; //max pixels in x and y direction + int xmin = 1, ymin = 1; //min pixels in x and y direction + double tot, tl, tr, bl, br; + + //determining xmax and ymax + switch(myDetectorType){ + case MOENCH: + xmax = MOENCH_PIXELS_IN_ONE_ROW-1; + ymax = MOENCH_PIXELS_IN_ONE_ROW-1; + break; + case GOTTHARD: + if(shortFrameEnable == -1){ + xmax = GOTTHARD_PIXELS_IN_ROW-1; + ymax = GOTTHARD_PIXELS_IN_COL-1; + }else{ + xmax = GOTTHARD_SHORT_PIXELS_IN_ROW-1; + ymax = GOTTHARD_SHORT_PIXELS_IN_COL-1; + } + break; + } + + while(buff[0] = receiverData[ithread]->findNextFrame(data,ndata,remainingsize)){ + + //remaining number of packets + np = ndata/onePacketSize; + + if ((np == packetsPerFrame) && (buff[0]!=NULL)){ + if(nf == 1000) + cprintf(GREEN, "Writing_Thread %d: pedestal done\n", ithread); + + singlePhotonDetectorObject[ithread]->newFrame(); + + //only for moench + if(commonModeSubtractionEnable){ + for(int ix = xmin - 1; ix < xmax+1; ix++){ + for(int iy = ymin - 1; iy < ymax+1; iy++){ + thisEvent = singlePhotonDetectorObject[ithread]->getEventType(buff[0], ix, iy, 0); + } + } + } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -int UDPStandardImplementation::createCompressionFile(int ithr, int iframe){ - FILE_LOG(logDEBUG1) << __AT__ << " called"; - + for(int ix = xmin - 1; ix < xmax+1; ix++) + for(int iy = ymin - 1; iy < ymax+1; iy++){ + thisEvent=singlePhotonDetectorObject[ithread]->getEventType(buff[0], ix, iy, commonModeSubtractionEnable); + if (nf>1000) { + tot=0; + tl=0; + tr=0; + bl=0; + br=0; + if (thisEvent==PHOTON_MAX) { + receiverData[ithread]->getFrameNumber(buff[0]); + //iFrame=receiverdata[ithread]->getFrameNumber(buff); #ifdef MYROOT1 - char temp[MAX_STR_LENGTH]; - //create file name for gui purposes, and set up acquistion parameters - sprintf(temp, "%s/%s_fxxx_%d_%d.root", filePath,fileName,fileIndex,ithr); - //file - myFile[ithr] = new TFile(temp,"RECREATE");/** later return error if it exists */ - cout << "Thread " << ithr << ": created File: "<< temp << endl; - //tree - sprintf(temp, "%s_fxxx_%d_%d",fileName,fileIndex,ithr); - myTree[ithr]=singlePhotonDet[ithr]->initEventTree(temp, &iframe); - //resets the pedestalSubtraction array and the commonModeSubtraction - singlePhotonDet[ithr]->newDataSet(); - if(myFile[ithr]==NULL){ - cout<<"file null"<IsOpen()){ - cout<<"file not open"<Fill(); + //cout << "Fill in event: frmNr: " << iFrame << " ix " << ix << " iy " << iy << " type " << thisEvent << endl; +#else + pthread_mutex_lock(&writeMutex); + if((fileWriteEnable) && (sfilefd)) + singlePhotonDetectorObject[ithread]->writeCluster(sfilefd); + pthread_mutex_unlock(&writeMutex); +#endif + } + } + } + + nf++; +#ifndef ALLFILE + pthread_mutex_lock(&progressMutex); + packetsInFile += packetsPerFrame; + packetsCaught += packetsPerFrame; + totalPacketsCaught += packetsPerFrame; + if(packetsInFile >= (uint32_t)maxPacketsPerFile) + createNewFile(); + pthread_mutex_unlock(&progressMutex); + +#endif + if(!once){ + copyFrameToGui(buff); + once = 1; + } + } + + remainingsize -= ((buff[0] + ndata) - data); + data = buff[0] + ndata; + if(data > (wbuffer[0] + HEADER_SIZE_NUM_TOT_PACKETS + npackets * onePacketSize) ) + cprintf(BG_RED,"Writing_Thread %d: Error: Compression data goes out of bounds!\n", ithread); + } + + + while(!fifoFree[0]->push(wbuffer[0])); +#ifdef FIFODEBUG + cprintf(GREEN,"Writing_Thread %d: Compression free pushed into fifofree %p for listerner 0\n", ithread, (void*)(wbuffer[0])); #endif - return OK; } @@ -2312,13 +2481,49 @@ int UDPStandardImplementation::createCompressionFile(int ithr, int iframe){ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + int UDPStandardImplementation::startWriting(){ FILE_LOG(logDEBUG1) << __AT__ << " called"; - char *d=new char[bufferSize*numListeningThreads]; - int xmax=0,ymax=0; + int ret,i,j; bool endofacquisition; @@ -2355,19 +2560,7 @@ int UDPStandardImplementation::startWriting(){ while(1){ - nf = 0; - if(myDetectorType == MOENCH){ - xmax = MOENCH_PIXELS_IN_ONE_ROW-1; - ymax = MOENCH_PIXELS_IN_ONE_ROW-1; - }else{ - if(shortFrame == -1){ - xmax = GOTTHARD_PIXELS_IN_ROW-1; - ymax = GOTTHARD_PIXELS_IN_COL-1; - }else{ - xmax = GOTTHARD_SHORT_PIXELS_IN_ROW-1; - ymax = GOTTHARD_SHORT_PIXELS_IN_COL-1; - } - } + //so that the first frame is always copied guiData = latestData; @@ -2757,118 +2950,3 @@ int UDPStandardImplementation::startWriting(){ - - - - -void UDPStandardImplementation::handleDataCompression(int ithread, char* wbuffer[], char* data, int xmax, int ymax, int &nf){ - FILE_LOG(logDEBUG1) << __AT__ << " called"; - - uint64_t tempframenumber = ((uint32_t)(*((uint32_t*)(wbuffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS)))); - //for gotthard and normal frame, increment frame number to separate fnum and pnum - if (myDetectorType == PROPIX ||(myDetectorType == GOTTHARD && shortFrameEnable == -1)) - tempframenumber++; - //get frame number - tempframenumber = (tempframenumber & frameIndexMask) >> frameIndexOffset; - - - pthread_mutex_lock(&progressMutex); - if(tempframenumber > currentFrameNumber) - currentFrameNumber = tempframenumber; - pthread_mutex_unlock(&progressMutex); - //set indices - acquisitionIndex = currentFrameNumber - startAcquisitionIndex; - frameIndex = currentFrameNumber - startFrameIndex; - -#if defined(MYROOT1) && defined(ALLFILE_DEBUG) - writeToFile_withoutCompression(wbuf[0], numpackets,currframenum); -#endif - int npackets = (uint32_t)(*((uint32_t*)wbuffer[0])); - eventType thisEvent = PEDESTAL; - int ndata; - char* buff = 0; - data = wbuffer[0]+ HEADER_SIZE_NUM_TOT_PACKETS; - int remainingsize = npackets * onePacketSize; - int np; - int once = 0; - double tot, tl, tr, bl, br; - int xmin = 1, ymin = 1, ix, iy; - - - while(buff = receiverdata[ithread]->findNextFrame(data,ndata,remainingsize)){ - np = ndata/onePacketSize; - - //cout<<"buff framnum:"<> frameIndexOffset)<newFrame(); - - //only for moench - if(commonModeSubtractionEnable){ - for(ix = xmin - 1; ix < xmax+1; ix++){ - for(iy = ymin - 1; iy < ymax+1; iy++){ - thisEvent = singlePhotonDet[ithread]->getEventType(buff, ix, iy, 0); - } - } - } - - - for(ix = xmin - 1; ix < xmax+1; ix++) - for(iy = ymin - 1; iy < ymax+1; iy++){ - thisEvent=singlePhotonDet[ithread]->getEventType(buff, ix, iy, commonModeSubtractionEnable); - if (nf>1000) { - tot=0; - tl=0; - tr=0; - bl=0; - br=0; - if (thisEvent==PHOTON_MAX) { - receiverdata[ithread]->getFrameNumber(buff); - //iFrame=receiverdata[ithread]->getFrameNumber(buff); -#ifdef MYROOT1 - myTree[ithread]->Fill(); - //cout << "Fill in event: frmNr: " << iFrame << " ix " << ix << " iy " << iy << " type " << thisEvent << endl; -#else - pthread_mutex_lock(&write_mutex); - if((enableFileWrite) && (sfilefd)) - singlePhotonDet[ithread]->writeCluster(sfilefd); - pthread_mutex_unlock(&write_mutex); -#endif - } - } - } - - nf++; -#ifndef ALLFILE - pthread_mutex_lock(&progress_mutex); - packetsInFile += packetsPerFrame; - packetsCaught += packetsPerFrame; - totalPacketsCaught += packetsPerFrame; - if(packetsInFile >= (uint32_t)maxPacketsPerFile) - createNewFile(); - pthread_mutex_unlock(&progress_mutex); - -#endif - if(!once){ - copyFrameToGui(NULL,buff); - once = 1; - } - } - - remainingsize -= ((buff + ndata) - data); - data = buff + ndata; - if(data > (wbuffer[0] + HEADER_SIZE_NUM_TOT_PACKETS + npackets * onePacketSize) ) - cprintf(BG_RED,"ERROR SHOULD NOT COME HERE, Error 142536!\n"); - - } - - while(!fifoFree[0]->push(wbuffer[0])); -#ifdef FIFO_DEBUG - cprintf(BLUE,"%d writer compression free pushed into fifofree %x for listerner 0\n", ithread, (void*)(wbuffer[0])); -#endif - -} - From 6d6725c4e8d452830e227e40c62939bedb92d88a Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Wed, 21 Oct 2015 11:03:57 +0200 Subject: [PATCH 155/474] df --- .../src/UDPStandardImplementation.cpp | 462 ++++++++---------- 1 file changed, 197 insertions(+), 265 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 4b253966b..34ee816cb 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1773,12 +1773,14 @@ void UDPStandardImplementation::startWriting(){ -void UDPStandardImplementation::processWritingBuffer(int ithread, int &nf){ +void UDPStandardImplementation::processWritingBuffer(int ithread){ FILE_LOG(logDEBUG1) << __AT__ << " called"; //variable definitions char* wbuf[numberofListeningThreads]; //buffer popped from FIFO sfilefd = NULL; //file pointer + int nf; //for compression, number of frames + /* outer loop - loops once for each acquisition */ //infinite loop, exited only to change dynamic range, 10G parameters etc (then recreated again) @@ -1786,6 +1788,8 @@ void UDPStandardImplementation::processWritingBuffer(int ithread, int &nf){ //--reset parameters before acquisition nf = 0; + guiData = latestData; //so that the first frame is always copied + /* inner loop - loop for each buffer */ //until mask unset (udp sockets shut down by client) @@ -1803,7 +1807,7 @@ void UDPStandardImplementation::processWritingBuffer(int ithread, int &nf){ #endif - //dummy packet + //end of acquisition if(numPackets == dummyPacketValue){ #ifdef DEBUG3 cprintf(GREEN,"Writing_Thread %d: Dummy frame popped out of FIFO %d",ithread, 0); @@ -1829,8 +1833,6 @@ void UDPStandardImplementation::processWritingBuffer(int ithread, int &nf){ waitWritingBufferForNextAcquisition(ithread); }/*--end of loop for each acquisition (outer loop) */ - - } @@ -1843,32 +1845,72 @@ void UDPStandardImplementation::processWritingBuffer(int ithread, int &nf){ void UDPStandardImplementation::processWritingBufferPacketByPacket(int ithread){ FILE_LOG(logDEBUG1) << __AT__ << " called"; - //variable definitions - char* wbuf[numberofListeningThreads]; //buffer popped from FIFO + char* packetBuffer[numberofListeningThreads]; //buffer popped from FIFO sfilefd = NULL; //file pointer bool popReady[numberofListeningThreads]; //if the FIFO can be popped - uint32_t numPackets[numberofListeningThreads]; //number of packets popped from the FIFO - //eiger specific - int MAX_NUM_PACKETS = 1024; //highest 32 bit has 1024 number of packets - char* toFreePointers[MAX_NUM_PACKETS]; //pointers to free for each frame - int toFreePointersOffset[numberofListeningThreads]; //offset of pointers to free added for each thread + uint32_t numPackets[numberofListeningThreads]; //number of packets popped from the FIFO + + int MAX_NUM_PACKETS = 1024; //highest 32 bit has 1024 number of packets + uint32_t LAST_PACKET_VALUE; //last packet number + char* toFreePointers[MAX_NUM_PACKETS]; //pointers to free for each frame + int toFreePointersOffset[numberofListeningThreads]; //offset of pointers to free added for each thread + + char* frameBuffer[MAX_NUM_PACKETS]; //buffer offset created for a whole frame + int frameBufferoffset[numberofListeningThreads]; //buffer offset created for a whole frame for both listening threads + char* blankframe[MAX_NUM_PACKETS]; //blank buffer for a whole frame with missing packets + int blankoffset; //blank buffer offset + + bool fullframe[numberofListeningThreads]; //if full frame processed for each listening thread + volatile uint32_t threadFrameNumber[numberofListeningThreads]; //thread frame number for each listening thread buffer popped out + volatile uint32_t presentFrameNumber; //the current frame number aiming to be built + volatile uint32_t lastPacketNumber[numberofListeningThreads]; //last packet number got + volatile uint32_t currentPacketNumber[numberofListeningThreads];//current packet number + volatile int numberofMissingPackets[numberofListeningThreads]; // number of missing packets in this buffer + + eiger_packet_header_t* blankframe_header; + + for(int i=0; imissingPacket) = missingPacketValue; + //set each value inside blank frame to 0xff + for(int j=0;j<(oneDataSize);++j){ + blankframe_data = (unsigned char*)blankframe[i] + sizeof(eiger_packet_header_t) + j; + *(blankframe_data) = 0xFF; + } } - //--end of reset parameters before acquisition + guiData = latestData; //so that the first frame is always copied + LAST_PACKET_VALUE = (packetsPerFrame/numberofListeningThreads); + /* inner loop - loop for each buffer */ @@ -1877,22 +1919,147 @@ void UDPStandardImplementation::processWritingBufferPacketByPacket(int ithread){ //pop fifo and if end of acquisition - if(popAndCheckEndofAcquisition(ithread, wbuf, popReady, numPackets,toFreePointers,toFreePointersOffset)){ + if(popAndCheckEndofAcquisition(ithread, packetBuffer, popReady, numPackets,toFreePointers,toFreePointersOffset)){ #ifdef DEBUG4 - cprintf(GREEN,"Writing_Thread %d: All dummy-end buffers popped\n", ithread); + cprintf(GREEN,"All dummy-end buffers popped\n", ithread); #endif //finish missing packets - - if(myDetectorType == EIGER && - ((tempoffset[0]!=0) || (tempoffset[1]!=(packetsPerFrame/numberofListeningThreads)))); + if(((frameBufferoffset[0]!=0) || (frameBufferoffset[1]!=(packetsPerFrame/numberofListeningThreads)))); else{ - stopWriting(ithread,wbuf); + stopWriting(ithread,packetBuffer); continue; } } + for(int i=0;ipacketNumber),lastPacketNumber[i],frameBufferoffset[i] ); + cprintf(RED,"Fifo %d: Add missing packets to the right fnum %d\n", + i,presentFrameNumber); +#endif + numberofMissingPackets[i] = (LAST_PACKET_VALUE - lastPacketNumber[i]); + } + //correct packet (but never dummy frame)------------------------------------------- + else{ + //update current packet + eiger_packet_footer_t* packetBuffer_footer = (eiger_packet_footer_t*)(packetBuffer[i] + footerOffset + HEADER_SIZE_NUM_TOT_PACKETS); + currentPacketNumber[i] = *( (uint16_t*) packetBuffer_footer->packetNumber); +#ifdef DEBUG4 + cprintf(GREEN,"Fifo %d: Correct Packet has fnum %d, pnum %d, last_packet %d, pnum_offset\n", + i,threadFrameNumber[i],currentPacketNumber[i],lastPacketNumber[i],frameBufferoffset[i]); +#endif + numberofMissingPackets[i] = (currentPacketNumber[i] - lastPacketNumber[i] - 1); + + } + + + //add missing packets + for(int j=0;jmissingPacket)!= missingPacketValue){ + blankframe_header = (eiger_packet_header_t*) blankframe[blankoffset]; + cprintf(BG_RED, "Fifo %d: Missing Packet Error: Adding blank packets mismatch " + "pnum_offset %d, fnum_thread %d, missingpacket_buffer 0x%x, missingpacket_blank 0x%x\n", + i,frameBufferoffset[i],threadFrameNumber[i], + *( (uint16_t*) frameBuffer_header->missingPacket), + *( (uint16_t*) blankframe_header->missingPacket)); + exit(-1); + }else{ +#ifdef DEBUG4 + cprintf(GREEN, "Fifo %d: Missing Packet Adding blank packets success " + "pnum_offset %d, fnum_thread %d, missingpacket_buffer 0x%x\n", + i,frameBufferoffset[i],threadFrameNumber[i], + *( (uint16_t*) frameBuffer_header->missingPacket)); +#endif + frameBufferoffset[i]++; + blankoffset++; + } + if(threadFrameNumber[i] != presentFrameNumber){ + //set fullframe and dont let fifo pop over it + fullframe[i] = true; + popReady[i] = false; + } + } + + //add current packet + if(threadFrameNumber[i] == presentFrameNumber){ + if(currentPacketNumber[i] != (uint32_t)(frameBufferoffset[i]-(i*packetsPerFrame/numberofListeningThreads))+1){ + cprintf(BG_RED, "Fifo %d: Correct Packet Error:Adding current packet mismatch " + "pnum_offset %d,pnum %d fnum %d, (firmware fnum %d)\n", + i,frameBufferoffset[i],currentPacketNumber[i], + threadFrameNumber[i],(uint32_t)(*( (uint64_t*) packetBuffer_footer))); + exit(-1); + } + + frameBuffer[frameBufferoffset[i]] = packetBuffer[i] + HEADER_SIZE_NUM_TOT_PACKETS; + tempframe_header = (eiger_packet_header_t*) tempbuffer[tempoffset[i]]; + tempframe_footer = (eiger_packet_footer_t*) (tempbuffer[tempoffset[i]] + footer_offset); + } + + + + if(threadFrameNumber[i] != presentFrameNumber) + threadFrameNumber[i] = presentFrameNumber; + + + + + + + + + + } + + } + + + } + + @@ -1904,10 +2071,11 @@ void UDPStandardImplementation::processWritingBufferPacketByPacket(int ithread){ waitWritingBufferForNextAcquisition(ithread); }/*--end of loop for each acquisition (outer loop) */ - } + + void UDPStandardImplementation::waitWritingBufferForNextAcquisition(int ithread){ FILE_LOG(logDEBUG1) << __AT__ << " called"; @@ -2428,7 +2596,7 @@ void UDPStandardImplementation::handleDataCompression(int ithread, char* wbuffer br=0; if (thisEvent==PHOTON_MAX) { receiverData[ithread]->getFrameNumber(buff[0]); - //iFrame=receiverdata[ithread]->getFrameNumber(buff); + //iFrame=receiverData[ithread]->getFrameNumber(buff); #ifdef MYROOT1 myTree[ithread]->Fill(); //cout << "Fill in event: frmNr: " << iFrame << " ix " << ix << " iy " << iy << " type " << thisEvent << endl; @@ -2524,37 +2692,13 @@ int UDPStandardImplementation::startWriting(){ - int ret,i,j; - bool endofacquisition; - int nf; - bool fullframe[numListeningThreads]; - volatile uint32_t tempframenum[numListeningThreads]; - uint32_t presentframenum; - uint32_t lastpacketheader[numListeningThreads], currentpacketheader[numListeningThreads]; - int numberofmissingpackets[numListeningThreads]; - - - - char* tempbuffer[MAX_VALUE]; - char* blankframe[MAX_VALUE]; - int tempoffset[numListeningThreads]; - int blankoffset; - for(i=0;imissingpacket) = missingPacketValue; - - //set each value inside blank frame to 0xff - for(j=0;j<(oneDataSize);++j){ - blankframe_data = (unsigned char*)blankframe[i] + sizeof(eiger_packet_header_t) + j; - *(blankframe_data) = 0xFF; - } - //verify - if (*( (uint16_t*) blankframe_header->missingpacket) != missingPacketValue){ - cprintf(RED,"blank frame not detected at %d: 0x%x\n",i,*( (uint16_t*) blankframe_header->missingpacket) ); - exit(-1); - } -#ifdef FIFO_DEBUG - cprintf(GREEN,"packet %d blank frame 0x%x\n",i,(void*)(blankframe[i])); -#endif - } - - //last packet numbers for different dynamic ranges - LAST_PACKET_VALUE = (packetsPerFrame/numListeningThreads); - } - - - //allow them all to be popped initially - for(i=0;imissingpacket)!= missingPacketValue){ - cprintf(BG_RED, "dummy blank mismatch num4 earlier2! " - "i:%d pnum:%d fnum:%d missingpacket:0x%x actual missingpacket:0x%x\n", - i,tempoffset[i],tempframenum[i], - *( (uint16_t*) tempframe_header->missingpacket), - *( (uint16_t*) blankframe_header->missingpacket)); - exit(-1); - }else -#ifdef PADDING - cprintf(GREEN, "blank packet i:%d pnum:%d fnum:%d missingpacket:0x%x\n",i, - tempoffset[i],tempframenum[i],*( (uint16_t*) tempframe_header->missingpacket)); -#endif - tempoffset[i]++; - blankoffset++; - } - //set fullframe and dont let fifo pop over it until written - fullframe[i] = true; - popready[i] = false; - } - } -#ifdef EIGER_DEBUG3 - else{ - cprintf(RED, "WARNING: Got a weird packet size: %d from fifo %d\n", numpackets[i],i); - continue; - } -#endif - } - - - //not a full frame if(!fullframe[i]){ - wbuf_footer = (eiger_packet_footer_t*)(wbuf[i] + footer_offset + HEADER_SIZE_NUM_TOT_PACKETS); -#ifdef EIGER_DEBUG3 - cprintf(GREEN,"**pnum of %d: %d\n",i,(*( (uint16_t*) wbuf_footer->packetnum))); -#endif - //update frame number - if(!((uint32_t)(*( (uint64_t*) wbuf_footer)))){ - cprintf(BG_RED,"%d VERY WEIRD frame number=%d and popready:%d\n", - i,(uint32_t)(*( (uint64_t*) wbuf_footer)),popready[i]); - popready[i]=true; - continue; - } - tempframenum[i] =(uint32_t)(*( (uint64_t*) wbuf_footer)); - tempframenum[i] += (startFrameIndex-1); - //WRONG FRAME - leave - if(tempframenum[i] != presentframenum){ -#ifdef PADDING - cout<<"wrong packet"<packetnum)); - -#endif - tempframenum[i] = presentframenum; - //add missing packets - numberofmissingpackets[i] = (LAST_PACKET_VALUE - lastpacketheader[i]); -#ifdef VERYDEBUG - if(numberofmissingpackets[i]>0) - cprintf(BG_RED,"fifo:%d missing packet from: %d now\n",i,lastpacketheader[i]); -#endif - //to decrement from packetsInFile to calculate packet loss - for(j=0;jmissingpacket)!= missingPacketValue){ - cprintf(BG_RED, "wrong blank mismatch num4 earlier2! " - "i:%d pnum:%d fnum:%d missingpacket:0x%x actual missingpacket:0x%x add:0x%p\n", - i,tempoffset[i],tempframenum[i], - *( (uint16_t*) tempframe_header->missingpacket), - *( (uint16_t*) blankframe_header->missingpacket), - (void*)(tempbuffer[tempoffset[i]])); - exit(-1); - }else -#ifdef PADDING - cprintf(GREEN, "blank packet i:%d pnum:%d fnum:%d missingpacket:0x%x add:0x%x\n", - i,tempoffset[i],tempframenum[i], - *( (uint16_t*) tempframe_header->missingpacket), - (void*)(tempbuffer[tempoffset[i]])); -#endif - tempoffset[i] ++; - blankoffset ++; - } - //set fullframe and dont let fifo pop over it until written - fullframe[i] = true; - popready[i] = false; - } //CORRECT FRAME - continue building frame - else { -#ifdef PADDING - cout<<"correct packet"<packetnum); -#ifdef VERYVERBOSE - cprintf(GREEN,"**fifo:%d currentpacketheader: %d lastpacketheader %d tempoffset:%d\n", - i,currentpacketheader[i],lastpacketheader[i], tempoffset[i]); -#endif - //add missing packets - numberofmissingpackets[i] = (currentpacketheader[i] - lastpacketheader[i] -1); -#ifdef VERYDEBUG - if(numberofmissingpackets[i]>0) - cprintf(BG_RED,"fifo:%d missing packet from: %d now at :%d tempoffset:%d\n", - i,lastpacketheader[i],currentpacketheader[i],tempoffset[i]); -#endif - //to decrement from packetsInFile to calculate packet loss - for(j=0;jmissingpacket)!= missingPacketValue){ - cprintf(BG_RED, "correct blank mismatch num4 earlier2! " - "i:%d pnum:%d fnum:%d missingpacket:0x%x actual missingpacket:0x%x add:0x%p\n", - i,tempoffset[i],tempframenum[i], - *( (uint16_t*) tempframe_header->missingpacket), - *( (uint16_t*) blankframe_header->missingpacket), - (void*)(tempbuffer[tempoffset[i]])); - exit(-1); - }else -#ifdef PADDING - cprintf(GREEN, "blank packet i:%d pnum:%d fnum:%d missingpacket:0x%x add:0x%x\n", - i,tempoffset[i],tempframenum[i], - *( (uint16_t*) tempframe_header->missingpacket), - (void*)(tempbuffer[tempoffset[i]])); -#endif - tempoffset[i] ++; - blankoffset ++; - } - //add current packet - if(currentpacketheader[i] != (uint32_t)(tempoffset[i]-(i*packetsPerFrame/numListeningThreads))+1){ - cprintf(BG_RED, "correct pnum mismatch earlier! tempoffset[%d]:%d pnum:%d fnum:%d rfnum:%d\n", - i,tempoffset[i],currentpacketheader[i], - tempframenum[i],(uint32_t)(*( (uint64_t*) wbuf_footer))); - exit(-1); - } tempbuffer[tempoffset[i]] = wbuf[i] + HEADER_SIZE_NUM_TOT_PACKETS; tempframe_header = (eiger_packet_header_t*) tempbuffer[tempoffset[i]]; From 837d0dce03f184d5a8040fb92a0e9a415362f18e Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 27 Oct 2015 09:31:08 +0100 Subject: [PATCH 156/474] dsg --- .../src/UDPStandardImplementation.cpp | 47 ++++++++++--------- 1 file changed, 26 insertions(+), 21 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 34ee816cb..a6833e57d 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1935,7 +1935,9 @@ void UDPStandardImplementation::processWritingBufferPacketByPacket(int ithread){ for(int i=0;ipacketNumber); +#ifdef DEBUG4 + cprintf(GREEN,"Fifo %d: Packet has fnum %d, pnum %d, last_packet %d, pnum_offset\n", + i,threadFrameNumber[i],currentPacketNumber[i],lastPacketNumber[i],frameBufferoffset[i]); +#endif } @@ -1970,8 +1980,9 @@ void UDPStandardImplementation::processWritingBufferPacketByPacket(int ithread){ threadFrameNumber[i] = dummyPacketValue; } - //wrong packet (dummy (not full) or from next frame))-------------------------------- - else if (threadFrameNumber[i] != presentFrameNumber){ + /**check if next frame lastpacket number is actually +1*/ + //wrong packet & correct (dummy (not full) or from future packet))-------------------------------- + else{// if ((threadFrameNumber[i] != presentFrameNumber) ||(currentPacketNumber[i] != lastPacketNumber[i] + 1)){ #ifdef DEBUG4 cprintf(GREEN,"Fifo %d: Wrong Packet has fnum %d, (firmware fnum %d), pnum %d, last_packet %d, pnum_offset %d\n", i,presentFrameNumber[i],(uint32_t)(*( (uint64_t*) packetBuffer_footer)), @@ -1979,20 +1990,12 @@ void UDPStandardImplementation::processWritingBufferPacketByPacket(int ithread){ cprintf(RED,"Fifo %d: Add missing packets to the right fnum %d\n", i,presentFrameNumber); #endif - numberofMissingPackets[i] = (LAST_PACKET_VALUE - lastPacketNumber[i]); + if(threadFrameNumber[i] != presentFrameNumber) + numberofMissingPackets[i] = (LAST_PACKET_VALUE - lastPacketNumber[i]); + else + numberofMissingPackets[i] = (currentPacketNumber[i] - lastPacketNumber[i] - 1); } - //correct packet (but never dummy frame)------------------------------------------- - else{ - //update current packet - eiger_packet_footer_t* packetBuffer_footer = (eiger_packet_footer_t*)(packetBuffer[i] + footerOffset + HEADER_SIZE_NUM_TOT_PACKETS); - currentPacketNumber[i] = *( (uint16_t*) packetBuffer_footer->packetNumber); -#ifdef DEBUG4 - cprintf(GREEN,"Fifo %d: Correct Packet has fnum %d, pnum %d, last_packet %d, pnum_offset\n", - i,threadFrameNumber[i],currentPacketNumber[i],lastPacketNumber[i],frameBufferoffset[i]); -#endif - numberofMissingPackets[i] = (currentPacketNumber[i] - lastPacketNumber[i] - 1); - } //add missing packets @@ -2017,13 +2020,13 @@ void UDPStandardImplementation::processWritingBufferPacketByPacket(int ithread){ frameBufferoffset[i]++; blankoffset++; } - if(threadFrameNumber[i] != presentFrameNumber){ - //set fullframe and dont let fifo pop over it - fullframe[i] = true; - popReady[i] = false; - } - } + } + if((numPackets[i] == dummyPacketValue) ||(threadFrameNumber[i] != presentFrameNumber)){ + //set fullframe and dont let fifo pop over it + fullframe[i] = true; + popReady[i] = false; + } //add current packet if(threadFrameNumber[i] == presentFrameNumber){ if(currentPacketNumber[i] != (uint32_t)(frameBufferoffset[i]-(i*packetsPerFrame/numberofListeningThreads))+1){ @@ -2054,6 +2057,8 @@ void UDPStandardImplementation::processWritingBufferPacketByPacket(int ithread){ } + numMissingPackets += numberofMissingPackets[i]; + } From 5f3de2057cd718caa3b26d0b0fe787b750f760c2 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 27 Oct 2015 14:33:26 +0100 Subject: [PATCH 157/474] df --- slsReceiverSoftware/include/slsReceiver.h | 6 +- .../include/slsReceiverUsers.h | 6 +- .../src/UDPStandardImplementation.cpp | 441 ++++++------------ slsReceiverSoftware/src/slsReceiver.cpp | 6 +- .../src/slsReceiverTCPIPInterface.cpp | 14 +- slsReceiverSoftware/src/slsReceiverUsers.cpp | 6 +- 6 files changed, 153 insertions(+), 326 deletions(-) diff --git a/slsReceiverSoftware/include/slsReceiver.h b/slsReceiverSoftware/include/slsReceiver.h index e76ea7d1b..94548caed 100644 --- a/slsReceiverSoftware/include/slsReceiver.h +++ b/slsReceiverSoftware/include/slsReceiver.h @@ -62,14 +62,14 @@ class slsReceiver : private virtual slsReceiverDefs { @param func callback to be called when starting the acquisition. Its arguments are filepath filename fileindex data size \returns 0 callback takes care of open,close,write file; 1 callback writes file, we have to open, close it; 2 we open, close, write file, callback does not do anything */ - void registerCallBackStartAcquisition(int (*func)(char*, char*,int, int, void*),void *arg); + void registerCallBackStartAcquisition(int (*func)(char*, char*,uint64_t, uint32_t, void*),void *arg); /** callback argument is toatal farmes caught */ - void registerCallBackAcquisitionFinished(void (*func)(int, void*),void *arg); + void registerCallBackAcquisitionFinished(void (*func)(uint64_t, void*),void *arg); /** args to raw data ready callback are @@ -79,7 +79,7 @@ class slsReceiver : private virtual slsReceiverDefs { file descriptor guidatapointer (NULL, no data required) */ - void registerCallBackRawDataReady(void (*func)(int, char*, int, FILE*, char*, void*),void *arg); + void registerCallBackRawDataReady(void (*func)(uint64_t, char*, uint32_t, FILE*, char*, void*),void *arg); private: diff --git a/slsReceiverSoftware/include/slsReceiverUsers.h b/slsReceiverSoftware/include/slsReceiverUsers.h index 50d6f38fe..0d242d372 100644 --- a/slsReceiverSoftware/include/slsReceiverUsers.h +++ b/slsReceiverSoftware/include/slsReceiverUsers.h @@ -61,7 +61,7 @@ public: */ - void registerCallBackStartAcquisition(int (*func)(char* filepath, char* filename,int fileindex, int datasize, void*),void *arg); + void registerCallBackStartAcquisition(int (*func)(char* filepath, char* filename,uint64_t fileindex, uint32_t datasize, void*),void *arg); /** @@ -71,7 +71,7 @@ public: */ - void registerCallBackAcquisitionFinished(void (*func)(int nf, void*),void *arg); + void registerCallBackAcquisitionFinished(void (*func)(uint64_t nf, void*),void *arg); @@ -81,7 +81,7 @@ public: \returns nothing */ - void registerCallBackRawDataReady(void (*func)(int framenumber, char* datapointer, int datasize, FILE* filedescriptor, char* guidatapointer, void*),void *arg); + void registerCallBackRawDataReady(void (*func)(uint64_t framenumber, char* datapointer, uint32_t datasize, FILE* filedescriptor, char* guidatapointer, void*),void *arg); // made static to close thread files with ctrl+c static slsReceiver* receiver; diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index a6833e57d..b15a48cc4 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1921,7 +1921,7 @@ void UDPStandardImplementation::processWritingBufferPacketByPacket(int ithread){ //pop fifo and if end of acquisition if(popAndCheckEndofAcquisition(ithread, packetBuffer, popReady, numPackets,toFreePointers,toFreePointersOffset)){ #ifdef DEBUG4 - cprintf(GREEN,"All dummy-end buffers popped\n", ithread); + cprintf(GREEN,"Writing_Thread All dummy-end buffers popped\n", ithread); #endif //finish missing packets if(((frameBufferoffset[0]!=0) || (frameBufferoffset[1]!=(packetsPerFrame/numberofListeningThreads)))); @@ -1932,22 +1932,25 @@ void UDPStandardImplementation::processWritingBufferPacketByPacket(int ithread){ } - + //get a full frame------------------------------------------------------------------------------------------------------- for(int i=0;ipacketNumber); -#ifdef DEBUG4 - cprintf(GREEN,"Fifo %d: Packet has fnum %d, pnum %d, last_packet %d, pnum_offset\n", - i,threadFrameNumber[i],currentPacketNumber[i],lastPacketNumber[i],frameBufferoffset[i]); -#endif } - - - //dummy not done ----------------------------- - if(numPackets[i] == dummyPacketValue){ + //calculate number of missing packets----------------------------------------------------- + numberofMissingPackets[i] = 0; #ifdef DEBUG4 - cprintf(RED, "Fifo %d: Dummy packet: Adding missing packets to the last frame\n", i); -#endif - numberofMissingPackets[i] = (LAST_PACKET_VALUE - lastPacketNumber[i]); - threadFrameNumber[i] = dummyPacketValue; - } - - /**check if next frame lastpacket number is actually +1*/ - //wrong packet & correct (dummy (not full) or from future packet))-------------------------------- - else{// if ((threadFrameNumber[i] != presentFrameNumber) ||(currentPacketNumber[i] != lastPacketNumber[i] + 1)){ -#ifdef DEBUG4 - cprintf(GREEN,"Fifo %d: Wrong Packet has fnum %d, (firmware fnum %d), pnum %d, last_packet %d, pnum_offset %d\n", + if(numPackets[i] == dummyPacketValue) + cprintf(GREEN, "Fifo %d: Dummy packet: Adding missing packets to the last frame\n", i); + else{ + cprintf(GREEN,"Fifo %d: fnum %d, (FW_fnum %d), pnum %d, last_pnum %d, pnum_offset %d\n" + "Fifo %d: Add missing packets to the right fnum %d\n", i,presentFrameNumber[i],(uint32_t)(*( (uint64_t*) packetBuffer_footer)), - *( (uint16_t*) packetBuffer_footer->packetNumber),lastPacketNumber[i],frameBufferoffset[i] ); - cprintf(RED,"Fifo %d: Add missing packets to the right fnum %d\n", + *( (uint16_t*) packetBuffer_footer->packetNumber),lastPacketNumber[i],frameBufferoffset[i], i,presentFrameNumber); -#endif - if(threadFrameNumber[i] != presentFrameNumber) - numberofMissingPackets[i] = (LAST_PACKET_VALUE - lastPacketNumber[i]); - else - numberofMissingPackets[i] = (currentPacketNumber[i] - lastPacketNumber[i] - 1); } +#endif + if((numPackets[i] == dummyPacketValue) || (threadFrameNumber[i] != presentFrameNumber)) + numberofMissingPackets[i] = (LAST_PACKET_VALUE - lastPacketNumber[i]); + else + numberofMissingPackets[i] = (currentPacketNumber[i] - lastPacketNumber[i] - 1); - //add missing packets + //add missing packets--------------------------------------------------------------------- for(int j=0;jmissingPacket)!= missingPacketValue){ blankframe_header = (eiger_packet_header_t*) blankframe[blankoffset]; cprintf(BG_RED, "Fifo %d: Missing Packet Error: Adding blank packets mismatch " - "pnum_offset %d, fnum_thread %d, missingpacket_buffer 0x%x, missingpacket_blank 0x%x\n", - i,frameBufferoffset[i],threadFrameNumber[i], + "pnum_offset %d, pnum %d, fnum_thread %d, missingpacket_buffer 0x%x, missingpacket_blank 0x%x\n", + i,frameBufferoffset[i],currentPacketNumber[i],threadFrameNumber[i], *( (uint16_t*) frameBuffer_header->missingPacket), *( (uint16_t*) blankframe_header->missingPacket)); exit(-1); }else{ #ifdef DEBUG4 - cprintf(GREEN, "Fifo %d: Missing Packet Adding blank packets success " - "pnum_offset %d, fnum_thread %d, missingpacket_buffer 0x%x\n", - i,frameBufferoffset[i],threadFrameNumber[i], + cprintf(RED, "Fifo %d: Missing Packet: Adding blank packets success " + "pnum_offset %d, pnum %d, fnum_thread %d, missingpacket_buffer 0x%x\n", + i,frameBufferoffset[i],currentPacketNumber[i],threadFrameNumber[i], *( (uint16_t*) frameBuffer_header->missingPacket)); #endif frameBufferoffset[i]++; blankoffset++; } + } - } - if((numPackets[i] == dummyPacketValue) ||(threadFrameNumber[i] != presentFrameNumber)){ - //set fullframe and dont let fifo pop over it - fullframe[i] = true; + //missed packets/future packet: do not pop over and determine fullframe-------------------- + if(numberofMissingPackets[i]){ popReady[i] = false; + if((numPackets[i] == dummyPacketValue) ||(threadFrameNumber[i] != presentFrameNumber)) + fullframe[i] = true; + else{ + fullframe[i] = false; + //update last packet + lastPacketNumber[i] = currentPacketNumber[i] - 1; + } + if(threadFrameNumber[i] != presentFrameNumber) + threadFrameNumber[i] = presentFrameNumber; + numMissingPackets += numberofMissingPackets[i]; } - //add current packet - if(threadFrameNumber[i] == presentFrameNumber){ + + //no missed packet: add current packet-------------------------------------------------------------- + else{ if(currentPacketNumber[i] != (uint32_t)(frameBufferoffset[i]-(i*packetsPerFrame/numberofListeningThreads))+1){ - cprintf(BG_RED, "Fifo %d: Correct Packet Error:Adding current packet mismatch " - "pnum_offset %d,pnum %d fnum %d, (firmware fnum %d)\n", + cprintf(BG_RED, "Fifo %d: Correct Packet Offset Error:Adding current packet mismatch " + "pnum_offset %d,pnum %d fnum_thread %d, (FW_fnum %d)\n", i,frameBufferoffset[i],currentPacketNumber[i], threadFrameNumber[i],(uint32_t)(*( (uint64_t*) packetBuffer_footer))); exit(-1); } frameBuffer[frameBufferoffset[i]] = packetBuffer[i] + HEADER_SIZE_NUM_TOT_PACKETS; - tempframe_header = (eiger_packet_header_t*) tempbuffer[tempoffset[i]]; - tempframe_footer = (eiger_packet_footer_t*) (tempbuffer[tempoffset[i]] + footer_offset); +#ifdef DEBUG4 + eiger_packet_header_t* frameBuffer_header = (eiger_packet_header_t*) frameBuffer[frameBufferoffset[i]]; + eiger_packet_footer_t* frameBuffer_footer = (eiger_packet_footer_t*) (frameBuffer[frameBufferoffset[i]] + footer_offset); + cprintf(GREEN, "Fifo %d: Current Packet added success:" + "pnum_offset %d, pnum %d, fnum_thread %d, missingpacket_buffer 0x%x\n", + i,frameBufferoffset[i],currentPacketNumber[i],threadFrameNumber[i], + *( (uint16_t*) frameBuffer_header->missingPacket)); +#endif + frameBufferoffset[i]++; + //update last packet + lastPacketNumber[i] = currentPacketNumber[i]; + popReady[i] = true; + fullframe[i] = false; + if(currentPacketNumber[i] == LAST_PACKET_VALUE){ +#ifdef DEBUG4 + cprintf(GREEN, "Fifo %d: Got last packet\n",i); +#endif + popReady[i] = false; + fullframe[i] = true; + } } + } + } + //full frame + if(fullframe[0] && fullframe[1]){ + currentPacketNumber = presentFrameNumber; + numTotMissingPacketsInFile += numMissingPackets; + numTotMissingPackets += numMissingPackets; +#ifdef FNUM_DEBUG + cprintf(GREEN,"**fnum:%d**\n",currframenum); +#endif +#ifdef MISSINGP_DEBUG + if(numberofMissingPackets[0]) + cprintf(RED, "Fifo 0 missing packets %d for fnum %d\n",numberofMissingPackets[0],currentPacketNumber); + if(numberofMissingPackets[1]) + cprintf(RED, "Fifo 1 missing packets%d for fnum %d\n",numberofMissingPackets[1],currentPacketNumber); + if(numMissingPackets){ + cprintf(RED, "Total missing packets %d for fnum %d\n",numMissingPackets,currentPacketNumber); + for (int j=0;jmissingPacket)==missingPacketValue) + cprintf(RED,"Found missing packet at pnum %d\n",j); + } + } +#endif - if(threadFrameNumber[i] != presentFrameNumber) - threadFrameNumber[i] = presentFrameNumber; - - - - - - - + //write and copy to gui + handleWithoutDataCompression(ithread,frameBuffer,packetsPerFrame); + + //freeing + for(int j=0;jpush(toFreePointers[j])); +#ifdef FIFODEBUG + cprintf(GREEN,"Fifo 0: Writing_Thread freed: pushed into fifofree %p\n",ithread, (void*)(toFreePointers[j])); +#endif + } + for(int j=(packetsPerFrame/numberofListeningThreads);jpush(toFreePointers[j])); +#ifdef FIFODEBUG + cprintf(GREEN,"Fifo 1: Writing_Thread freed: pushed into fifofree %p\n",ithread, (void*)(toFreePointers[j])); +#endif + } +#ifdef DEBUG4 + cprintf(GREEN,"Writing_Thread: finished freeing\n"); +#endif + //reset a few stuff + presentFrameNumber++; + for(int i=0; ipacketNumber), (void*)(packetBuffer[i])); + } +#endif @@ -2646,244 +2712,3 @@ void UDPStandardImplementation::handleDataCompression(int ithread, char* wbuffer } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -int UDPStandardImplementation::startWriting(){ - FILE_LOG(logDEBUG1) << __AT__ << " called"; - - - - - - - eiger_packet_footer_t* wbuf_footer=0; - eiger_packet_header_t* tempframe_header=0; - eiger_packet_footer_t* tempframe_footer=0; - - - - - while(1){ - - - - - - - while((1<packetnum),tempoffset[i]); -#endif - if(*( (uint16_t*) tempframe_footer->packetnum)!= (tempoffset[i]-(i*packetsPerFrame/numListeningThreads))+1){ - cprintf(BG_RED, "pnum mismatch num4 earlier! i:%d pnum:%d pnum orig:%d fnum:%d add:0x%p\n", - i,*( (uint16_t*) tempframe_footer->packetnum),*( (uint16_t*) wbuf_footer->packetnum), - tempframenum[i],(void*)(tempbuffer[tempoffset[i]])); - exit(-1); - } -#ifdef PADDING - cprintf(GREEN, "normal packet i:%d pnum:%d fnum:%d missingpacket:0x%x add:0x%x\n", - i,tempoffset[i],tempframenum[i], - *( (uint16_t*) tempframe_header->missingpacket), - (void*)(tempbuffer[tempoffset[i]])); -#endif - tempoffset[i] ++; - //update last packet - lastpacketheader[i] = currentpacketheader[i]; - popready[i] = true; - //last frame got, this will save time and also for last frames, it doesnt wait for stop receiver - if(currentpacketheader[i] == LAST_PACKET_VALUE){ -#ifdef EIGER_DEBUG3 - cprintf(GREEN, "Got last packet\n"); -#endif - fullframe[i] = true; - popready[i] = false; - } - } - } - } - } - - - - //FULL FRAME - if(fullframe[0] && fullframe[1]){ - - //determine frame number - if(tempframenum[0] != tempframenum[1]) - cprintf(RED,"Frame numbers mismatch!!! %d %d\n",tempframenum[0],tempframenum[1]); - currframenum = tempframenum[0]; - numMissingPackets += (numberofmissingpackets[0]+numberofmissingpackets[1]); - numTotMissingPacketsInFile += numMissingPackets; - numTotMissingPackets += numMissingPackets; -#ifdef EIGER_DEBUG2 - cprintf(GREEN,"**fnum:%d**\n",currframenum); -#endif -#ifdef EIGER_DEBUG3 - if(numberofmissingpackets[0]) - cprintf(RED, "fifo 0 missing packets:%d fnum:%d\n",numberofmissingpackets[0],currframenum); - if(numberofmissingpackets[1]) - cprintf(RED, "fifo 1 missing packets:%d fnum:%d\n",numberofmissingpackets[1],currframenum); - if(numMissingPackets){ - cprintf(RED, "numMissingPackets:%d fnum:%d\n",numMissingPackets,currframenum); - - for (j=0;jmissingpacket)==missingPacketValue) - cprintf(RED,"found the missing packet at pnum:%d\n",j); - } - } -#endif - - - //write and copy to gui - handleWithoutDataCompression(ithread,tempbuffer,packetsPerFrame); - - - //freeing - for(j=0;jpush(tofree[j])); -#ifdef FIFO_DEBUG - cprintf(GREEN,"%d writer freed pushed into fifofree %x for listener %d\n",ithread, (void*)(tofree[j]),0); -#endif - } - for(j=(packetsPerFrame/numListeningThreads);jpush(tofree[j])); -#ifdef FIFO_DEBUG - cprintf(GREEN,"%d writer freed pushed into fifofree %x for listener %d\n",ithread, (void*)(tofree[j]),1); -#endif - } -#ifdef VERYDEBUG - cprintf(GREEN,"finished freeing\n"); -#endif - - - //reset a few stuff - presentframenum = tempframenum[0]+1; - for(int i=0;ipacketnum)); - } -#endif - } - - - - - } - - } - - - return OK; -} - - - - - - - - - - - - - - diff --git a/slsReceiverSoftware/src/slsReceiver.cpp b/slsReceiverSoftware/src/slsReceiver.cpp index 5783e601c..15149dde0 100644 --- a/slsReceiverSoftware/src/slsReceiver.cpp +++ b/slsReceiverSoftware/src/slsReceiver.cpp @@ -166,20 +166,20 @@ int64_t slsReceiver::getReceiverVersion(){ } -void slsReceiver::registerCallBackStartAcquisition(int (*func)(char*, char*,int, int, void*),void *arg){ +void slsReceiver::registerCallBackStartAcquisition(int (*func)(char*, char*,uint64_t, uint32_t, void*),void *arg){ //tcpipInterface udp_interface->registerCallBackStartAcquisition(func,arg); } -void slsReceiver::registerCallBackAcquisitionFinished(void (*func)(int, void*),void *arg){ +void slsReceiver::registerCallBackAcquisitionFinished(void (*func)(uint64_t, void*),void *arg){ //tcpipInterface udp_interface->registerCallBackAcquisitionFinished(func,arg); } -void slsReceiver::registerCallBackRawDataReady(void (*func)(int, char*, int, FILE*, char*, void*),void *arg){ +void slsReceiver::registerCallBackRawDataReady(void (*func)(uint64_t, char*, uint32_t, FILE*, char*, void*),void *arg){ //tcpipInterface udp_interface->registerCallBackRawDataReady(func,arg); } diff --git a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp index cfab3e75d..5b4664e55 100644 --- a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp +++ b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp @@ -9,6 +9,7 @@ #include "slsReceiverUsers.h" #include "slsReceiver.h" + #include //SIGINT #include //EXIT @@ -401,6 +402,7 @@ int slsReceiverTCPIPInterface::set_detector_type(){ } } } + } //#ifdef VERBOSE if(ret!=FAIL) cout << "detector type" << dr << endl; @@ -432,7 +434,7 @@ int slsReceiverTCPIPInterface::set_detector_type(){ int slsReceiverTCPIPInterface::set_file_name() { ret=OK; - char* retval[MAX_STR_LENGTH] = NULL; + char* retval = NULL; char defaultVal[MAX_STR_LENGTH] = ""; char fName[MAX_STR_LENGTH]; strcpy(mess,"Could not set file name"); @@ -457,7 +459,7 @@ int slsReceiverTCPIPInterface::set_file_name() { } else{ receiverBase->setFileName(fName); - retval = receiveBase->getFileName(); + retval = receiverBase->getFileName(); if(retval == NULL) ret = FAIL; } @@ -526,8 +528,8 @@ int slsReceiverTCPIPInterface::set_file_dir() { } else{ receiverBase->setFilePath(fPath); - retval = receiveBase->getFilePath(); - if(reval == NULL){ + retval = receiverBase->getFilePath(); + if(retval == NULL){ ret = FAIL; strcpy(mess,"receiver file path does not exist\n"); } @@ -741,8 +743,8 @@ int slsReceiverTCPIPInterface::setup_udp(){ //set up udp port sscanf(args[1],"%d",&udpport); sscanf(args[2],"%d",&udpport2); - receiverBase->setUDPPortNo(udpport); - receiverBase->setUDPPortNo2(udpport2); + receiverBase->setUDPPortNumber(udpport); + receiverBase->setUDPPortNumber2(udpport2); //setup udpip //get ethernet interface or IP to listen to cout << "Ethernet interface is " << args[0] << endl; diff --git a/slsReceiverSoftware/src/slsReceiverUsers.cpp b/slsReceiverSoftware/src/slsReceiverUsers.cpp index c27f1efc2..1df35558c 100644 --- a/slsReceiverSoftware/src/slsReceiverUsers.cpp +++ b/slsReceiverSoftware/src/slsReceiverUsers.cpp @@ -29,18 +29,18 @@ int64_t slsReceiverUsers::getReceiverVersion(){ } -void slsReceiverUsers::registerCallBackStartAcquisition(int (*func)(char*, char*,int, int, void*),void *arg){ +void slsReceiverUsers::registerCallBackStartAcquisition(int (*func)(char*, char*,uint64_t, uint32_t, void*),void *arg){ slsReceiverUsers::receiver->registerCallBackStartAcquisition(func,arg); } -void slsReceiverUsers::registerCallBackAcquisitionFinished(void (*func)(int, void*),void *arg){ +void slsReceiverUsers::registerCallBackAcquisitionFinished(void (*func)(uint64_t, void*),void *arg){ slsReceiverUsers::receiver->registerCallBackAcquisitionFinished(func,arg); } -void slsReceiverUsers::registerCallBackRawDataReady(void (*func)(int, char*, int, FILE*, char*, void*),void *arg){ +void slsReceiverUsers::registerCallBackRawDataReady(void (*func)(uint64_t, char*, uint32_t, FILE*, char*, void*),void *arg){ slsReceiverUsers::receiver->registerCallBackRawDataReady(func,arg); } From 58bfa296beca9d19933de635caf5e622bd5721c1 Mon Sep 17 00:00:00 2001 From: l_msdetect Date: Wed, 28 Oct 2015 17:40:55 +0100 Subject: [PATCH 158/474] done --- .../include/UDPBaseImplementation.h | 14 +- slsReceiverSoftware/include/UDPInterface.h | 8 +- .../include/UDPStandardImplementation.h | 13 +- slsReceiverSoftware/include/slsReceiver.h | 6 +- .../include/slsReceiverUsers.h | 6 +- .../include/sls_receiver_defs.h | 49 +++++++ .../src/UDPBaseImplementation.cpp | 41 +++--- .../src/UDPStandardImplementation.cpp | 138 +++++++++--------- slsReceiverSoftware/src/slsReceiver.cpp | 6 +- .../src/slsReceiverTCPIPInterface.cpp | 28 ++-- slsReceiverSoftware/src/slsReceiverUsers.cpp | 6 +- 11 files changed, 182 insertions(+), 133 deletions(-) diff --git a/slsReceiverSoftware/include/UDPBaseImplementation.h b/slsReceiverSoftware/include/UDPBaseImplementation.h index 43f98b511..dfb7b0429 100644 --- a/slsReceiverSoftware/include/UDPBaseImplementation.h +++ b/slsReceiverSoftware/include/UDPBaseImplementation.h @@ -33,6 +33,10 @@ class UDPBaseImplementation : protected virtual slsReceiverDefs, public UDPInter */ virtual ~UDPBaseImplementation(); + /* + * Initialize class members + */ + void initializeMembers(); /************************************************************************* * Getters *************************************************************** @@ -180,7 +184,7 @@ class UDPBaseImplementation : protected virtual slsReceiverDefs, public UDPInter * Get Listening Status of Receiver * @return can be idle, listening or error depending on if the receiver is listening or not */ - slsReceiverDefs::runStatus getStatus() const; + runStatus getStatus() const; @@ -334,7 +338,7 @@ class UDPBaseImplementation : protected virtual slsReceiverDefs, public UDPInter * @param d detector type * @return OK or FAIL */ - int setDetectorType(const slsReceiverDefs::detectorType d); + int setDetectorType(const detectorType d); /** * Sets detector hostname (and corresponding detector variables in derived REST class) @@ -413,14 +417,14 @@ class UDPBaseImplementation : protected virtual slsReceiverDefs, public UDPInter * 1 callback writes file, we have to open, close it * 2 we open, close, write file, callback does not do anything */ - void registerCallBackStartAcquisition(int (*func)(char*, char*,uint64_t, uint32_t, void*),void *arg); + void registerCallBackStartAcquisition(int (*func)(char*, char*,int, int, void*),void *arg); /** * Call back for acquisition finished * callback argument is * total frames caught */ - void registerCallBackAcquisitionFinished(void (*func)(uint64_t, void*),void *arg); + void registerCallBackAcquisitionFinished(void (*func)(int, void*),void *arg); /** * Call back for raw data @@ -431,7 +435,7 @@ class UDPBaseImplementation : protected virtual slsReceiverDefs, public UDPInter * file descriptor * guidatapointer (NULL, no data required) */ - void registerCallBackRawDataReady(void (*func)(uint64_t, char*, uint32_t, FILE*, char*, void*),void *arg); + void registerCallBackRawDataReady(void (*func)(int, char*, int, FILE*, char*, void*),void *arg); diff --git a/slsReceiverSoftware/include/UDPInterface.h b/slsReceiverSoftware/include/UDPInterface.h index b62ad2eb0..1a6377653 100644 --- a/slsReceiverSoftware/include/UDPInterface.h +++ b/slsReceiverSoftware/include/UDPInterface.h @@ -407,7 +407,7 @@ class UDPInterface { /** * Reset acquisition parameters such as total frames caught for an entire acquisition (including all scans) */ - void resetAcquisitionCount(); + virtual void resetAcquisitionCount() = 0; /** * Start Listening for Packets by activating all configuration settings to receiver @@ -471,14 +471,14 @@ class UDPInterface { * 1 callback writes file, we have to open, close it * 2 we open, close, write file, callback does not do anything */ - virtual void registerCallBackStartAcquisition(int (*func)(char*, char*,uint64_t, uint32_t, void*),void *arg) = 0; + virtual void registerCallBackStartAcquisition(int (*func)(char*, char*,int, int, void*),void *arg) = 0; /** * Call back for acquisition finished * callback argument is * total frames caught */ - virtual void registerCallBackAcquisitionFinished(void (*func)(uint64_t, void*),void *arg) = 0; + virtual void registerCallBackAcquisitionFinished(void (*func)(int, void*),void *arg) = 0; /** * Call back for raw data @@ -489,7 +489,7 @@ class UDPInterface { * file descriptor * guidatapointer (NULL, no data required) */ - virtual void registerCallBackRawDataReady(void (*func)(uint64_t, char*, uint32_t, FILE*, char*, void*),void *arg) = 0; + virtual void registerCallBackRawDataReady(void (*func)(int, char*, int, FILE*, char*, void*),void *arg) = 0; protected: diff --git a/slsReceiverSoftware/include/UDPStandardImplementation.h b/slsReceiverSoftware/include/UDPStandardImplementation.h index 430b5c5d1..d478f0e7a 100644 --- a/slsReceiverSoftware/include/UDPStandardImplementation.h +++ b/slsReceiverSoftware/include/UDPStandardImplementation.h @@ -136,7 +136,7 @@ class UDPStandardImplementation: private virtual slsReceiverDefs, public UDPBase * @param d detector type * @return OK or FAIL */ - int setDetectorType(const slsReceiverDefs::detectorType d); + int setDetectorType(const detectorType d); //***acquisition functions*** /** @@ -214,11 +214,6 @@ private: //**initial parameters*** - /** - * Delete and free base member parameters - */ - void deleteBaseMembers(); - /** * Delete and free member parameters */ @@ -409,7 +404,7 @@ private: * @param wbuffer writing buffer popped out from FIFO * @param npackets number of packets */ - void handleWithoutDataCompression(int ithread, char* wbuffer[],int npackets); + void handleWithoutDataCompression(int ithread, char* wbuffer[],uint32_t npackets); /** * Calle by handleWithoutDataCompression @@ -417,7 +412,7 @@ private: * @param wbuffer is the address of buffer popped out of FIFO * @param numpackets is the number of packets */ - void writeFileWithoutCompression(char* wbuffer[],int numpackets); + void writeFileWithoutCompression(char* wbuffer[],uint32_t numpackets); /** * Called by writeToFileWithoutCompression @@ -449,7 +444,7 @@ private: * @param wbuffer writer buffer * @param nf number of frames */ - void handleDataCompression(int ithread, char* wbuffer[], int &nf); + void handleDataCompression(int ithread, char* wbuffer[], uint64_t &nf); diff --git a/slsReceiverSoftware/include/slsReceiver.h b/slsReceiverSoftware/include/slsReceiver.h index 94548caed..e76ea7d1b 100644 --- a/slsReceiverSoftware/include/slsReceiver.h +++ b/slsReceiverSoftware/include/slsReceiver.h @@ -62,14 +62,14 @@ class slsReceiver : private virtual slsReceiverDefs { @param func callback to be called when starting the acquisition. Its arguments are filepath filename fileindex data size \returns 0 callback takes care of open,close,write file; 1 callback writes file, we have to open, close it; 2 we open, close, write file, callback does not do anything */ - void registerCallBackStartAcquisition(int (*func)(char*, char*,uint64_t, uint32_t, void*),void *arg); + void registerCallBackStartAcquisition(int (*func)(char*, char*,int, int, void*),void *arg); /** callback argument is toatal farmes caught */ - void registerCallBackAcquisitionFinished(void (*func)(uint64_t, void*),void *arg); + void registerCallBackAcquisitionFinished(void (*func)(int, void*),void *arg); /** args to raw data ready callback are @@ -79,7 +79,7 @@ class slsReceiver : private virtual slsReceiverDefs { file descriptor guidatapointer (NULL, no data required) */ - void registerCallBackRawDataReady(void (*func)(uint64_t, char*, uint32_t, FILE*, char*, void*),void *arg); + void registerCallBackRawDataReady(void (*func)(int, char*, int, FILE*, char*, void*),void *arg); private: diff --git a/slsReceiverSoftware/include/slsReceiverUsers.h b/slsReceiverSoftware/include/slsReceiverUsers.h index 0d242d372..50d6f38fe 100644 --- a/slsReceiverSoftware/include/slsReceiverUsers.h +++ b/slsReceiverSoftware/include/slsReceiverUsers.h @@ -61,7 +61,7 @@ public: */ - void registerCallBackStartAcquisition(int (*func)(char* filepath, char* filename,uint64_t fileindex, uint32_t datasize, void*),void *arg); + void registerCallBackStartAcquisition(int (*func)(char* filepath, char* filename,int fileindex, int datasize, void*),void *arg); /** @@ -71,7 +71,7 @@ public: */ - void registerCallBackAcquisitionFinished(void (*func)(uint64_t nf, void*),void *arg); + void registerCallBackAcquisitionFinished(void (*func)(int nf, void*),void *arg); @@ -81,7 +81,7 @@ public: \returns nothing */ - void registerCallBackRawDataReady(void (*func)(uint64_t framenumber, char* datapointer, uint32_t datasize, FILE* filedescriptor, char* guidatapointer, void*),void *arg); + void registerCallBackRawDataReady(void (*func)(int framenumber, char* datapointer, int datasize, FILE* filedescriptor, char* guidatapointer, void*),void *arg); // made static to close thread files with ctrl+c static slsReceiver* receiver; diff --git a/slsReceiverSoftware/include/sls_receiver_defs.h b/slsReceiverSoftware/include/sls_receiver_defs.h index fe0c715b1..04f647f0a 100755 --- a/slsReceiverSoftware/include/sls_receiver_defs.h +++ b/slsReceiverSoftware/include/sls_receiver_defs.h @@ -122,6 +122,55 @@ public: else return std::string("disabled"); \ }; + /** returns detector type string from detector type index + \param t string can be Mythen, Pilatus, Eiger, Gotthard, Agipd, Unknown + \returns MYTHEN, PILATUS, EIGER, GOTTHARD, AGIPD, MÖNCH, GENERIC + */ + static std::string getDetectorType(detectorType t){ \ + switch (t) { \ + case MYTHEN: return std::string("Mythen"); \ + case PILATUS: return std::string("Pilatus"); \ + case EIGER: return std::string("Eiger"); \ + case GOTTHARD: return std::string("Gotthard"); \ + case AGIPD: return std::string("Agipd"); \ + case MOENCH: return std::string("Moench"); \ + case JUNGFRAU: return std::string("Jungfrau"); \ + case JUNGFRAUCTB: return std::string("JungfrauCTB"); \ + case PROPIX: return std::string("Propix"); \ + default: return std::string("Unknown"); \ + }}; + + /** returns detector type index from detector type string + \param type can be MYTHEN, PILATUS, EIGER, GOTTHARD, AGIPD, GENERIC + \returns Mythen, Pilatus, Eiger, Gotthard, Agipd, Mönch, Unknown + */ + static detectorType getDetectorType(std::string const type){\ + if (type=="Mythen") return MYTHEN; \ + if (type=="Pilatus") return PILATUS; \ + if (type=="Eiger") return EIGER; \ + if (type=="Gotthard") return GOTTHARD; \ + if (type=="Agipd") return AGIPD; \ + if (type=="Moench") return MOENCH; \ + if (type=="Jungfrau") return JUNGFRAU; \ + if (type=="JungfrauCTB") return JUNGFRAUCTB; \ + if (type=="Propix") return PROPIX; \ + return GENERIC; \ + }; + + + /** returns string from run status index + \param s can be ERROR, WAITING, RUNNING, TRANSMITTING, RUN_FINISHED + \returns string error, waiting, running, data, finished + */ + static std::string runStatusType(runStatus s){\ + switch (s) { \ + case ERROR: return std::string("error"); \ + case WAITING: return std::string("waiting"); \ + case RUNNING: return std::string("running"); \ + case TRANSMITTING: return std::string("data"); \ + case RUN_FINISHED: return std::string("finished"); \ + default: return std::string("idle"); \ + }}; #ifdef __cplusplus diff --git a/slsReceiverSoftware/src/UDPBaseImplementation.cpp b/slsReceiverSoftware/src/UDPBaseImplementation.cpp index 18e43edb5..0bfef5d71 100644 --- a/slsReceiverSoftware/src/UDPBaseImplementation.cpp +++ b/slsReceiverSoftware/src/UDPBaseImplementation.cpp @@ -21,6 +21,20 @@ using namespace std; UDPBaseImplementation::UDPBaseImplementation(){ FILE_LOG(logDEBUG) << __AT__ << " starting"; + initializeMembers(); + + //***callback parameters*** + startAcquisitionCallBack = NULL; + pStartAcquisition = NULL; + acquisitionFinishedCallBack = NULL; + pAcquisitionFinished = NULL; + rawDataReadyCallBack = NULL; + pRawDataReady = NULL; +} + +void UDPBaseImplementation::initializeMembers(){ + FILE_LOG(logDEBUG) << __AT__ << " starting"; + cout << "Info: Initializing base members" << endl; //**detector parameters*** myDetectorType = GENERIC; @@ -61,21 +75,9 @@ UDPBaseImplementation::UDPBaseImplementation(){ //***acquisition parameters*** shortFrameEnable = -1; FrameToGuiFrequency = 0; - - //***callback parameters*** - startAcquisitionCallBack = NULL; - pStartAcquisition = NULL; - acquisitionFinishedCallBack = NULL; - pAcquisitionFinished = NULL; - rawDataReadyCallBack = NULL; - pRawDataReady = NULL; } -UDPBaseImplementation::~UDPBaseImplementation(){ - FILE_LOG(logDEBUG) << __AT__ << " starting"; - - cout << "Info: Deleting base member pointers" << endl; -} +UDPBaseImplementation::~UDPBaseImplementation(){} /************************************************************************* @@ -364,12 +366,12 @@ int UDPBaseImplementation::setTenGigaEnable(const bool b){ /***initial functions***/ -int UDPBaseImplementation::setDetectorType(const slsReceiverDefs::detectorType d){ +int UDPBaseImplementation::setDetectorType(const detectorType d){ FILE_LOG(logDEBUG) << __AT__ << " starting"; myDetectorType = d; //if eiger, set numberofListeningThreads = 2; - FILE_LOG(logINFO) << "Detector Type:" << slsDetectorBase::getDetectorType(d); + FILE_LOG(logINFO) << "Detector Type:" << getDetectorType(d); return OK; } @@ -409,6 +411,9 @@ void UDPBaseImplementation::startReadout(){ int UDPBaseImplementation::shutDownUDPSockets(){ FILE_LOG(logWARNING) << __AT__ << " doing nothing..."; FILE_LOG(logERROR) << __AT__ << " must be overridden by child classes"; + + //overridden functions might return FAIL + return OK; } void UDPBaseImplementation::readFrame(char* c,char** raw, uint64_t &startAcquisitionIndex, uint64_t &startFrameIndex){ @@ -429,17 +434,17 @@ void UDPBaseImplementation::closeFile(int i){ /***callback functions***/ -void UDPBaseImplementation::registerCallBackStartAcquisition(int (*func)(char*, char*,uint64_t, uint32_t, void*),void *arg){ +void UDPBaseImplementation::registerCallBackStartAcquisition(int (*func)(char*, char*,int, int, void*),void *arg){ startAcquisitionCallBack=func; pStartAcquisition=arg; } -void UDPBaseImplementation::registerCallBackAcquisitionFinished(void (*func)(uint64_t, void*),void *arg){ +void UDPBaseImplementation::registerCallBackAcquisitionFinished(void (*func)(int, void*),void *arg){ acquisitionFinishedCallBack=func; pAcquisitionFinished=arg; } -void UDPBaseImplementation::registerCallBackRawDataReady(void (*func)(uint64_t, char*, uint32_t, FILE*, char*, void*),void *arg){ +void UDPBaseImplementation::registerCallBackRawDataReady(void (*func)(int, char*, int, FILE*, char*, void*),void *arg){ rawDataReadyCallBack=func; pRawDataReady=arg; } diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index b15a48cc4..e144585be 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -69,11 +69,6 @@ UDPStandardImplementation::~UDPStandardImplementation(){ *************************************************************************/ /***initial parameters***/ -void UDPStandardImplementation::deleteBaseMembers(){ - FILE_LOG(logDEBUG1) << __AT__ << " starting"; - - UDPBaseImplementation::~UDPBaseImplementation(); -} void UDPStandardImplementation::deleteMembers(){ FILE_LOG(logDEBUG1) << __AT__ << " starting"; @@ -116,7 +111,7 @@ void UDPStandardImplementation::deleteFilter(){ void UDPStandardImplementation::initializeBaseMembers(){ FILE_LOG(logDEBUG1) << __AT__ << " starting"; - UDPBaseImplementation::UDPBaseImplementation(); + UDPBaseImplementation::initializeMembers(); acquisitionPeriod = SAMPLE_TIME_IN_NS; } @@ -216,6 +211,7 @@ void UDPStandardImplementation::initializeFilter(){ int sign = 1, csize, i; //common mode initialization + moenchCommonModeSubtraction = NULL; if (commonModeSubtractionEnable){ if(myDetectorType == MOENCH) moenchCommonModeSubtraction=new moenchCommonMode(); @@ -244,7 +240,7 @@ void UDPStandardImplementation::initializeFilter(){ //single photon detector initialization for(i=0; i(receiverData[i], csize, sigma, sign, commonModeSubtractionEnable); + singlePhotonDetectorObject[i]=new singlePhotonDetector(receiverData[i], csize, sigma, sign, moenchCommonModeSubtraction); } @@ -255,7 +251,7 @@ int UDPStandardImplementation::setupFifoStructure(){ int64_t i; int oldNumberofJobsPerBuffer = numberofJobsPerBuffer; - int oldFifoSize = fifoSize; + uint32_t oldFifoSize = fifoSize; //eiger always listens to 1 packet at a time if(myDetectorType == EIGER){ @@ -349,6 +345,7 @@ int UDPStandardImplementation::setupFifoStructure(){ } } cout << "Info: Fifo structure(s) reconstructed" << endl; + return OK; } @@ -458,11 +455,9 @@ void UDPStandardImplementation::setShortFrameEnable(const int i){ int UDPStandardImplementation::setFrameToGuiFrequency(const uint32_t i){ FILE_LOG(logDEBUG1) << __AT__ << " called"; - if(i >= 0){ - FrameToGuiFrequency = i; - if(setupFifoStructure() == FAIL) - return FAIL; - } + FrameToGuiFrequency = i; + if(setupFifoStructure() == FAIL) + return FAIL; cout << "Info: Frame to Gui Frequency set to " << FrameToGuiFrequency << endl; @@ -470,14 +465,12 @@ int UDPStandardImplementation::setFrameToGuiFrequency(const uint32_t i){ } -int UDPStandardImplementation::setAcquisitionPeriod(int64_t i){ +int UDPStandardImplementation::setAcquisitionPeriod(const uint64_t i){ FILE_LOG(logDEBUG1) << __AT__ << " called"; - if(i >= 0){ - acquisitionPeriod = i; - if(setupFifoStructure() == FAIL) - return FAIL; - } + acquisitionPeriod = i; + if(setupFifoStructure() == FAIL) + return FAIL; cout << "Info: Acquisition Period set to " << acquisitionPeriod << endl; @@ -488,7 +481,7 @@ int UDPStandardImplementation::setAcquisitionPeriod(int64_t i){ int UDPStandardImplementation::setDynamicRange(const uint32_t i){ FILE_LOG(logDEBUG1) << __AT__ << " called"; - int oldDynamicRange = dynamicRange; + uint32_t oldDynamicRange = dynamicRange; cout << "Info: Setting Dynamic Range to " << i << endl; dynamicRange = i; @@ -542,7 +535,7 @@ int UDPStandardImplementation::setDynamicRange(const uint32_t i){ int UDPStandardImplementation::setTenGigaEnable(const bool b){ FILE_LOG(logDEBUG1) << __AT__ << " called"; - cout << "Info: Setting Ten Giga to " << string(b) << endl; + cout << "Info: Setting Ten Giga to " << stringEnable(b) << endl; bool oldTenGigaEnable = tengigaEnable; tengigaEnable = b; @@ -603,7 +596,7 @@ int UDPStandardImplementation::setTenGigaEnable(const bool b){ } - cout << "Info: Ten Giga " << string(tengigaEnable) << endl; + cout << "Info: Ten Giga " << stringEnable(tengigaEnable) << endl; return OK; } @@ -621,12 +614,11 @@ int UDPStandardImplementation::setTenGigaEnable(const bool b){ /***initial functions***/ -int UDPStandardImplementation::setDetectorType(const slsReceiverDefs::detectorType d){ +int UDPStandardImplementation::setDetectorType(const detectorType d){ FILE_LOG(logDEBUG1) << __AT__ << " called"; cout << "Setting receiver type ..." << endl; - deleteBaseMembers(); deleteMembers(); initializeBaseMembers(); initializeMembers(); @@ -639,7 +631,7 @@ int UDPStandardImplementation::setDetectorType(const slsReceiverDefs::detectorTy case EIGER: case JUNGFRAUCTB: case JUNGFRAU: - cout << "Info: ***** This is a " << slsDetectorBase::getDetectorType(d) << " Receiver *****" << endl; + cout << "Info: ***** This is a " << getDetectorType(d) << " Receiver *****" << endl; break; default: cprintf(BG_RED, "Error: This is an unknown receiver type %d\n", (int)d); @@ -715,6 +707,9 @@ int UDPStandardImplementation::setDetectorType(const slsReceiverDefs::detectorTy fifoSize = JCTB_FIFO_SIZE; //footerOffset = Not applicable; break; + default: + cprintf(BG_RED, "Error: This is an unknown receiver type %d\n", (int)d); + return FAIL; } //delete threads and set number of listening threads @@ -745,7 +740,7 @@ int UDPStandardImplementation::setDetectorType(const slsReceiverDefs::detectorTy //allocate for latest data (frame copy for gui) latestData = new char[frameSize]; - cout << " Detector type set to " << slsDetectorBase::getDetectorType(d) << endl; + cout << " Detector type set to " << getDetectorType(d) << endl; cout << "Ready..." << endl; return OK; @@ -837,7 +832,7 @@ int UDPStandardImplementation::startReceiver(char *c){ //For compression, just for gui purposes if(dataCompressionEnable) - sprintf(completeFileName, "%s/%s_fxxx_%d_xx.root", filePath,fileName,fileIndex); + sprintf(completeFileName, "%s/%s_fxxx_%lld_xx.root", filePath,fileName,(long long int)fileIndex); //initialize semaphore to synchronize between writer and gui reader threads sem_init(&writerGuiSemaphore,1,0); @@ -856,7 +851,7 @@ int UDPStandardImplementation::startReceiver(char *c){ //usleep(5000000); cout << "Info: Receiver Started." << endl; - cout << "Info: Status:" << slsDetectorBase::runStatusType(status) << endl; + cout << "Info: Status:" << runStatusType(status) << endl; return OK; } @@ -889,7 +884,7 @@ void UDPStandardImplementation::stopReceiver(){ pthread_mutex_unlock(&(statusMutex)); cout << "Info: Receiver Stopped" << endl; - cout << "Info: Status:" << slsDetectorBase::runStatusType(status) << endl; + cout << "Info: Status:" << runStatusType(status) << endl; cout << endl; } @@ -1210,8 +1205,10 @@ int UDPStandardImplementation::createUDPSockets(){ FILE_LOG(logDEBUG1) << __AT__ << " called"; //switching ports if bottom enabled - int port[2]; - port = udpPortNum; + uint32_t port[2]; + port[0]= udpPortNum[0]; + port[1]= udpPortNum[1]; + //port = udpPortNum; if(bottomEnable){ port[0] = udpPortNum[1]; port[1] = udpPortNum[0]; @@ -1266,7 +1263,7 @@ int UDPStandardImplementation::setupWriter(){ //acquisition start call back returns enable write cbAction = DO_EVERYTHING; if (startAcquisitionCallBack) - cbAction=startAcquisitionCallBack(filePath,fileName,fileIndex,bufferSize,pStartAcquisition); + cbAction=startAcquisitionCallBack(filePath,fileName,(int)fileIndex,bufferSize,pStartAcquisition); if(cbAction < DO_EVERYTHING){ cout << "Info: Call back activated. Data saving must be taken care of by user in call back." << endl; @@ -1318,11 +1315,11 @@ int UDPStandardImplementation::createNewFile(){ //create file name if(!frameIndexEnable) - sprintf(completeFileName, "%s/%s_%d.raw", filePath,fileName,fileIndex); + sprintf(completeFileName, "%s/%s_%lld.raw", filePath,fileName,(long long int)fileIndex); else if (myDetectorType == EIGER) - sprintf(completeFileName, "%s/%s_f%012d_%d.raw", filePath,fileName,currentFrameNumber,fileIndex); + sprintf(completeFileName, "%s/%s_f%012lld_%lld.raw", filePath,fileName,(long long int)currentFrameNumber,(long long int)fileIndex); else - sprintf(completeFileName, "%s/%s_f%012d_%d.raw", filePath,fileName,(packetsCaught/packetsPerFrame),fileIndex); + sprintf(completeFileName, "%s/%s_f%012lld_%lld.raw", filePath,fileName,(long long int)(packetsCaught/packetsPerFrame),(long long int)fileIndex); #ifdef DEBUG4 cout << "Info: " << completefileName << endl; @@ -1534,7 +1531,7 @@ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int lSize, in //throw away packets that is not one packet size, need to check status if socket is shut down while(status != TRANSMITTING && myDetectorType == EIGER && receivedSize != onePacketSize) { if(receivedSize != EIGER_HEADER_LENGTH) - cprintf(RED,"Listening_Thread %d: Listened to a weird packet size %d\n",receivedSize); + cprintf(RED,"Listening_Thread %d: Listened to a weird packet size %d\n",ithread, receivedSize); #ifdef DEBUG else cprintf(BLUE,"Listening_Thread %d: Listened to a header packet\n",ithread); @@ -1576,11 +1573,11 @@ void UDPStandardImplementation::startFrameIndices(int ithread){ if(!acqStarted){ startAcquisitionIndex = startFrameIndex; acqStarted = true; - cprintf(BLUE,"Info: Thread %d: startAcquisitionIndex:%d\n",ithread,startAcquisitionIndex); + cprintf(BLUE,"Info: Thread %d: startAcquisitionIndex:%lld\n",ithread,(long long int)startAcquisitionIndex); } //set start of scan/real time measurement - cprintf(BLUE,"Info: Thread %d: startFrameIndex: %d\n", ithread,startFrameIndex); + cprintf(BLUE,"Info: Thread %d: startFrameIndex: %lld\n", ithread,(long long int)startFrameIndex); measurementStarted = true; } @@ -1593,7 +1590,7 @@ void UDPStandardImplementation::startFrameIndices(int ithread){ void UDPStandardImplementation::stopListening(int ithread, int numbytes){ FILE_LOG(logDEBUG1) << __AT__ << " called"; - cout << "Info: Stop Listening. Status:" << slsDetectorBase::runStatusType(status) << endl; + cout << "Info: Stop Listening. Status:" << runStatusType(status) << endl; //less than 1 packet size (especially for eiger), ignore the buffer (so that 2 dummy buffers are not sent with pc=0) @@ -1672,7 +1669,7 @@ uint32_t UDPStandardImplementation::processListeningBuffer(int ithread, int cSiz FILE_LOG(logDEBUG1) << __AT__ << " called"; int lastPacketOffset; //the offset of the last packet - int lastFrameHeader; //frame number of last packet in buffer + uint32_t lastFrameHeader; //frame number of last packet in buffer uint32_t packetCount = (packetsPerFrame/numberofListeningThreads) * numberofJobsPerBuffer; //packets received cSize = 0; //reset size @@ -1735,8 +1732,8 @@ uint32_t UDPStandardImplementation::processListeningBuffer(int ithread, int cSiz break; default: - cprintf(RED,"Listening_Thread %d: Error: This detector is not implemented in the receiver" + - slsDetectorBase::getDetectorType(myDetectorType).c_str() + "\n"); + cprintf(RED,"Listening_Thread %d: Error: This detector %s is not implemented in the receiver\n", + ithread, getDetectorType(myDetectorType).c_str()); break; } @@ -1779,7 +1776,7 @@ void UDPStandardImplementation::processWritingBuffer(int ithread){ //variable definitions char* wbuf[numberofListeningThreads]; //buffer popped from FIFO sfilefd = NULL; //file pointer - int nf; //for compression, number of frames + uint64_t nf; //for compression, number of frames /* outer loop - loops once for each acquisition */ @@ -1799,7 +1796,7 @@ void UDPStandardImplementation::processWritingBuffer(int ithread){ #ifdef FIFODEBUG cprintf(GREEN,"Writing_Thread %d: Popped %p from FIFO %d\n", ithread, (void*)(wbuf[0]),0); #endif - int numPackets = (uint32_t)(*((uint32_t*)wbuf[0])); + uint32_t numPackets = (uint32_t)(*((uint32_t*)wbuf[0])); if(numPackets < 0) cprintf(BG_RED,"Error: Negative packet numbers: %d for FIFO %d\n",numPackets,0); #ifdef DEBUG4 @@ -1896,7 +1893,7 @@ void UDPStandardImplementation::processWritingBufferPacketByPacket(int ithread){ //blank frame - initializing with missing packet values blankoffset = 0; unsigned char* blankframe_data=0; - for(int i=0; ipacketNumber) != (i+1)){ - cprintf(BG_RED, "Packet Number Mismatch! i:%d pnum:%d fnum:%d missingPacket:%d\n", - i,*( (uint16_t*) wbuf_footer->packetNumber),currentFrameNumber,*( (uint16_t*) wbuf_header->missingPacket)); + cprintf(BG_RED, "Writing_Thread: Packet Number Mismatch! " + "i %d, pnum %d, fnum %lld, missingPacket 0x%x\n", + i,*( (uint16_t*) wbuf_footer->packetNumber),(long long int)currentFrameNumber,*( (uint16_t*) wbuf_header->missingPacket)); exit(-1); } //overwriting port number and dynamic range @@ -2526,7 +2521,6 @@ void UDPStandardImplementation::createHeaders(char* wbuffer[]){ void UDPStandardImplementation::copyFrameToGui(char* buffer[]){ FILE_LOG(logDEBUG1) << __AT__ << " called"; - int i; //random read (gui not ready) //need to toggle guiDataReady or the second frame wont be copied @@ -2551,7 +2545,7 @@ void UDPStandardImplementation::copyFrameToGui(char* buffer[]){ #endif switch(myDetectorType){ case EIGER: - for(int i=0; ifindNextFrame(data,ndata,remainingsize)){ diff --git a/slsReceiverSoftware/src/slsReceiver.cpp b/slsReceiverSoftware/src/slsReceiver.cpp index 15149dde0..5783e601c 100644 --- a/slsReceiverSoftware/src/slsReceiver.cpp +++ b/slsReceiverSoftware/src/slsReceiver.cpp @@ -166,20 +166,20 @@ int64_t slsReceiver::getReceiverVersion(){ } -void slsReceiver::registerCallBackStartAcquisition(int (*func)(char*, char*,uint64_t, uint32_t, void*),void *arg){ +void slsReceiver::registerCallBackStartAcquisition(int (*func)(char*, char*,int, int, void*),void *arg){ //tcpipInterface udp_interface->registerCallBackStartAcquisition(func,arg); } -void slsReceiver::registerCallBackAcquisitionFinished(void (*func)(uint64_t, void*),void *arg){ +void slsReceiver::registerCallBackAcquisitionFinished(void (*func)(int, void*),void *arg){ //tcpipInterface udp_interface->registerCallBackAcquisitionFinished(func,arg); } -void slsReceiver::registerCallBackRawDataReady(void (*func)(uint64_t, char*, uint32_t, FILE*, char*, void*),void *arg){ +void slsReceiver::registerCallBackRawDataReady(void (*func)(int, char*, int, FILE*, char*, void*),void *arg){ //tcpipInterface udp_interface->registerCallBackRawDataReady(func,arg); } diff --git a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp index 5b4664e55..f94b47a01 100644 --- a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp +++ b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp @@ -185,7 +185,7 @@ void slsReceiverTCPIPInterface::startTCPServer(){ #ifdef VERYVERBOSE cout << "Starting Receiver TCP Server" << endl; #endif - int v=slsReceiverDefs::OK; + int v=OK; while(1) { #ifdef VERBOSE @@ -832,7 +832,7 @@ int slsReceiverTCPIPInterface::start_receiver(){ if(s == IDLE) ret=receiverBase->startReceiver(mess); else{ - sprintf(mess,"Cannot start Receiver as it is in %s state\n",slsDetectorBase::runStatusType(s).c_str()); + sprintf(mess,"Cannot start Receiver as it is in %s state\n",runStatusType(s).c_str()); ret=FAIL; } } @@ -878,7 +878,7 @@ int slsReceiverTCPIPInterface::stop_receiver(){ if(s==IDLE) ret = OK; else{ - sprintf(mess,"Could not stop receiver. It is in %s state\n",slsDetectorBase::runStatusType(s).c_str()); + sprintf(mess,"Could not stop receiver. It is in %s state\n",runStatusType(s).c_str()); ret = FAIL; } } @@ -1138,8 +1138,8 @@ int slsReceiverTCPIPInterface::moench_read_frame(){ char* raw = new char[bufferSize]; - uint32_t startAcquisitionIndex=0; - uint32_t startFrameIndex=0; + uint64_t startAcquisitionIndex=0; + uint64_t startFrameIndex=0; uint32_t index = -1,bindex = 0, offset=0; strcpy(mess,"Could not read frame\n"); @@ -1327,8 +1327,8 @@ int slsReceiverTCPIPInterface::gotthard_read_frame(){ uint32_t index=-1,index2=0; uint32_t pindex=0,pindex2=0; uint32_t bindex=0,bindex2=0; - uint32_t startAcquisitionIndex=0; - uint32_t startFrameIndex=0; + uint64_t startAcquisitionIndex=0; + uint64_t startFrameIndex=0; strcpy(mess,"Could not read frame\n"); @@ -1502,8 +1502,8 @@ int slsReceiverTCPIPInterface::propix_read_frame(){ uint32_t index=-1,index2=0; uint32_t pindex=0,pindex2=0; uint32_t bindex=0,bindex2=0; - uint32_t startAcquisitionIndex=0; - uint32_t startFrameIndex=0; + uint64_t startAcquisitionIndex=0; + uint64_t startFrameIndex=0; strcpy(mess,"Could not read frame\n"); @@ -1670,8 +1670,8 @@ int slsReceiverTCPIPInterface::eiger_read_frame(){ char* raw = new char[frameSize]; char* origVal = new char[frameSize]; char* retval = new char[dataSize]; - uint32_t startAcquisitionIndex=0; - uint32_t startFrameIndex=0; + uint64_t startAcquisitionIndex=0; + uint64_t startFrameIndex=0; strcpy(mess,"Could not read frame\n"); @@ -2111,11 +2111,11 @@ int slsReceiverTCPIPInterface::set_timer() { ret=FAIL; } else{ - if(index[0] == slsReceiverDefs::FRAME_PERIOD){ + if(index[0] == FRAME_PERIOD){ if(index[1]>=0){ ret = receiverBase->setAcquisitionPeriod(index[1]); if(ret == FAIL) - strcpy(mess,"Could not allocate memory for listening fifo\n") + strcpy(mess,"Could not allocate memory for listening fifo\n"); } retval=receiverBase->getAcquisitionPeriod(); }else{ @@ -2129,7 +2129,7 @@ int slsReceiverTCPIPInterface::set_timer() { } #ifdef VERBOSE if(ret!=FAIL){ - if(index[0] == slsReceiverDefs::FRAME_PERIOD) + if(index[0] == FRAME_PERIOD) cout << "acquisition period:" << retval << endl; else cout << "frame number:" << retval << endl; diff --git a/slsReceiverSoftware/src/slsReceiverUsers.cpp b/slsReceiverSoftware/src/slsReceiverUsers.cpp index 1df35558c..c27f1efc2 100644 --- a/slsReceiverSoftware/src/slsReceiverUsers.cpp +++ b/slsReceiverSoftware/src/slsReceiverUsers.cpp @@ -29,18 +29,18 @@ int64_t slsReceiverUsers::getReceiverVersion(){ } -void slsReceiverUsers::registerCallBackStartAcquisition(int (*func)(char*, char*,uint64_t, uint32_t, void*),void *arg){ +void slsReceiverUsers::registerCallBackStartAcquisition(int (*func)(char*, char*,int, int, void*),void *arg){ slsReceiverUsers::receiver->registerCallBackStartAcquisition(func,arg); } -void slsReceiverUsers::registerCallBackAcquisitionFinished(void (*func)(uint64_t, void*),void *arg){ +void slsReceiverUsers::registerCallBackAcquisitionFinished(void (*func)(int, void*),void *arg){ slsReceiverUsers::receiver->registerCallBackAcquisitionFinished(func,arg); } -void slsReceiverUsers::registerCallBackRawDataReady(void (*func)(uint64_t, char*, uint32_t, FILE*, char*, void*),void *arg){ +void slsReceiverUsers::registerCallBackRawDataReady(void (*func)(int, char*, int, FILE*, char*, void*),void *arg){ slsReceiverUsers::receiver->registerCallBackRawDataReady(func,arg); } From db54fbddde14443b4b64ef321bfb57a5e23c8ae6 Mon Sep 17 00:00:00 2001 From: Anna Bergamaschi Date: Thu, 29 Oct 2015 11:20:08 +0100 Subject: [PATCH 159/474] detector type bug fix --- .../src/slsReceiverTCPIPInterface.cpp | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp index f94b47a01..be3242cd9 100644 --- a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp +++ b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp @@ -391,21 +391,22 @@ int slsReceiverTCPIPInterface::set_detector_type(){ sprintf(mess,"Unknown detector type: %d\n", dr); ret = FAIL; break; - if(ret != FAIL){ -#ifndef REST - receiverBase = UDPInterface::create("standard"); - receiverBase->setBottomEnable(bottom); -#endif - myDetectorType = dr; - ret=receiverBase->setDetectorType(myDetectorType); - retval = myDetectorType; - } } + if(ret != FAIL){ +#ifndef REST + receiverBase = UDPInterface::create("standard"); + receiverBase->setBottomEnable(bottom); +#endif + myDetectorType = dr; + ret=receiverBase->setDetectorType(myDetectorType); + retval = myDetectorType; + } + } } //#ifdef VERBOSE if(ret!=FAIL) - cout << "detector type" << dr << endl; + cout << "detector type " << dr << endl; else cprintf(RED, "%s\n", mess); //#endif From eb5f481faaf2b90891c45532a9b5f3a7093e49c9 Mon Sep 17 00:00:00 2001 From: Anna Bergamaschi Date: Thu, 29 Oct 2015 11:21:57 +0100 Subject: [PATCH 160/474] detector type bug fix --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index e144585be..fd4ab0c0c 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1797,8 +1797,10 @@ void UDPStandardImplementation::processWritingBuffer(int ithread){ cprintf(GREEN,"Writing_Thread %d: Popped %p from FIFO %d\n", ithread, (void*)(wbuf[0]),0); #endif uint32_t numPackets = (uint32_t)(*((uint32_t*)wbuf[0])); - if(numPackets < 0) - cprintf(BG_RED,"Error: Negative packet numbers: %d for FIFO %d\n",numPackets,0); + cout<<"numpackets:"< Date: Thu, 29 Oct 2015 13:33:24 +0100 Subject: [PATCH 161/474] log --- .../src/UDPBaseImplementation.cpp | 10 +-- .../src/UDPStandardImplementation.cpp | 79 +++++++++---------- slsReceiverSoftware/src/main.cpp | 2 +- .../src/slsReceiverTCPIPInterface.cpp | 4 +- 4 files changed, 46 insertions(+), 49 deletions(-) diff --git a/slsReceiverSoftware/src/UDPBaseImplementation.cpp b/slsReceiverSoftware/src/UDPBaseImplementation.cpp index 0bfef5d71..94a39d07d 100644 --- a/slsReceiverSoftware/src/UDPBaseImplementation.cpp +++ b/slsReceiverSoftware/src/UDPBaseImplementation.cpp @@ -35,7 +35,7 @@ UDPBaseImplementation::UDPBaseImplementation(){ void UDPBaseImplementation::initializeMembers(){ FILE_LOG(logDEBUG) << __AT__ << " starting"; - cout << "Info: Initializing base members" << endl; + FILE_LOG(logDEBUG1) << "Info: Initializing base members" << endl; //**detector parameters*** myDetectorType = GENERIC; strcpy(detHostname,""); @@ -202,7 +202,7 @@ void UDPBaseImplementation::setBottomEnable(const bool b){ FILE_LOG(logDEBUG) << __AT__ << " starting"; bottomEnable = b; - FILE_LOG(logINFO) << "Bottom Enable: " << stringEnable(bottomEnable); + FILE_LOG(logINFO) << "Bottom - " << stringEnable(bottomEnable) << endl; } @@ -216,7 +216,7 @@ void UDPBaseImplementation::setFileName(const char c[]){ } void UDPBaseImplementation::setFilePath(const char c[]){ - FILE_LOG(logDEBUG) << __AT__ << " starting"; + FILE_LOG(logINFO) << __AT__ << " starting"; if(strlen(c)){ //check if filepath exists @@ -229,7 +229,7 @@ void UDPBaseImplementation::setFilePath(const char c[]){ } strcpy(filePath, c); } - FILE_LOG(logINFO) << "File path:" << filePath; + FILE_LOG(logDEBUG1) << "Info: File path:" << filePath; } void UDPBaseImplementation::setFileIndex(const uint64_t i){ @@ -273,7 +273,7 @@ int UDPBaseImplementation::setDataCompressionEnable(const bool b){ FILE_LOG(logDEBUG) << __AT__ << " starting"; dataCompressionEnable = b; - FILE_LOG(logINFO) << "Data Compression Enable: " << stringEnable(dataCompressionEnable); + FILE_LOG(logINFO) << "Data Compression : " << stringEnable(dataCompressionEnable); //overridden methods might return FAIL return OK; diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index fd4ab0c0c..bfe8c9eb7 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -42,10 +42,10 @@ UDPStandardImplementation::UDPStandardImplementation(){ pthread_mutex_init(&progressMutex,NULL); //to increase socket receiver buffer size and max length of input queue by changing kernel settings - if(system("echo $((100*1024*1024)) > /proc/sys/net/core/rmem_max")) - cout << "Warning: No root permission to change socket receiver buffer size in file /proc/sys/net/core/rmem_max" << endl; + if(system("echo $((100*1024*1024)) > /proc/sys/net/core/rmem_max")) + FILE_LOG(logDEBUG1) << "Warning: No root permission to change socket receiver buffer size in file /proc/sys/net/core/rmem_max" << endl; else if(system("echo 250000 > /proc/sys/net/core/netdev_max_backlog")) - cout << "Warning: No root permission to change max length of input queue in file /proc/sys/net/core/netdev_max_backlog" << endl; + FILE_LOG(logDEBUG1) << "Warning: No root permission to change max length of input queue in file /proc/sys/net/core/netdev_max_backlog" << endl; /** permanent setting by heiner net.core.rmem_max = 104857600 # 100MiB net.core.netdev_max_backlog = 250000 @@ -54,6 +54,7 @@ UDPStandardImplementation::UDPStandardImplementation(){ sysctl -w net.core.rmem_max=16777216 sysctl -w net.core.netdev_max_backlog=250000 */ + cout << endl; } UDPStandardImplementation::~UDPStandardImplementation(){ @@ -73,7 +74,7 @@ UDPStandardImplementation::~UDPStandardImplementation(){ void UDPStandardImplementation::deleteMembers(){ FILE_LOG(logDEBUG1) << __AT__ << " starting"; - cout << "Info: Deleting member pointers" << endl; + FILE_LOG(logDEBUG1) << "Info: Deleting member pointers" << endl; shutDownUDPSockets(); closeFile(); //filter @@ -119,7 +120,7 @@ void UDPStandardImplementation::initializeBaseMembers(){ void UDPStandardImplementation::initializeMembers(){ FILE_LOG(logDEBUG1) << __AT__ << " starting"; - cout << "Info: Initializing members" << endl; + FILE_LOG(logDEBUG1) << "Info: Initializing members" << endl; //***detector parameters*** frameSize = 0; @@ -256,7 +257,7 @@ int UDPStandardImplementation::setupFifoStructure(){ //eiger always listens to 1 packet at a time if(myDetectorType == EIGER){ numberofJobsPerBuffer = 1; - cout << "Info: 1 packet per buffer" << endl; + FILE_LOG(logDEBUG1) << "Info: 1 packet per buffer" << endl; } //else calculate best possible number of frames to listen to at a time (for fast readouts like gotthard) @@ -298,9 +299,8 @@ int UDPStandardImplementation::setupFifoStructure(){ else fifoSize = fifoSize/numberofJobsPerBuffer; } -#ifdef VERBOSE - cout << "Info: Fifo Depth:" << fifoSize << endl; -#endif + FILE_LOG(logDEBUG1) << "Info: Fifo Depth:" << fifoSize << endl; + //do not rebuild fifo structure if it is the same @@ -315,8 +315,8 @@ int UDPStandardImplementation::setupFifoStructure(){ if(fifoFree[i]){ while(!fifoFree[i]->isEmpty()) fifoFree[i]->pop(buffer[i]); -#ifdef FIFO_DEBUG - cprintf(GREEN,"%d fifostructure popped from fifofree %p\n", i, (void*)(buffer[i])); +#ifdef FIFODEBUG + cprintf(GREEN,"Info: %d fifostructure popped from fifofree %p\n", i, (void*)(buffer[i])); #endif delete fifoFree[i]; } @@ -338,13 +338,13 @@ int UDPStandardImplementation::setupFifoStructure(){ buffer[i]=mem0[i]; while (buffer[i] < (mem0[i]+(bufferSize * numberofJobsPerBuffer + HEADER_SIZE_NUM_TOT_PACKETS) * (fifoSize-1))) { fifoFree[i]->push(buffer[i]); -#ifdef FIFO_DEBUG - cprintf(BLUE,"%d fifostructure free pushed into fifofree %p\n", i, (void*)(buffer[i])); +#ifdef FIFODEBUG + cprintf(BLUE,"Info: %d fifostructure free pushed into fifofree %p\n", i, (void*)(buffer[i])); #endif buffer[i] += (bufferSize * numberofJobsPerBuffer + HEADER_SIZE_NUM_TOT_PACKETS); } } - cout << "Info: Fifo structure(s) reconstructed" << endl; + FILE_LOG(logDEBUG1) << "Info: Fifo structure(s) reconstructed" << endl; return OK; } @@ -366,7 +366,7 @@ void UDPStandardImplementation::configure(map config_map){ b = 0; } bottomEnable = b!= 0; - cout << "Info: Bottom Enable: " << stringEnable(bottomEnable) << endl; + cout << "Info: Bottom - " << stringEnable(bottomEnable) << endl; } } @@ -376,12 +376,14 @@ void UDPStandardImplementation::configure(map config_map){ int UDPStandardImplementation::setDataCompressionEnable(const bool b){ FILE_LOG(logDEBUG1) << __AT__ << " starting"; - cout << "Info: Setting up Data Compression Enable to " << stringEnable(b); + if(myDetectorType != EIGER){ + cout << "Info: Setting up Data Compression Enable to " << stringEnable(b); #ifdef MYROOT1 - cout << " WITH ROOT" << endl; + cout << " WITH ROOT" << endl; #else - cout << " WITHOUT ROOT" << endl; + cout << " WITHOUT ROOT" << endl; #endif + } //set data compression enable dataCompressionEnable = b; @@ -617,7 +619,7 @@ int UDPStandardImplementation::setTenGigaEnable(const bool b){ int UDPStandardImplementation::setDetectorType(const detectorType d){ FILE_LOG(logDEBUG1) << __AT__ << " called"; - cout << "Setting receiver type ..." << endl; + cout << "Info: Setting receiver type ..." << endl; deleteMembers(); initializeBaseMembers(); @@ -631,7 +633,7 @@ int UDPStandardImplementation::setDetectorType(const detectorType d){ case EIGER: case JUNGFRAUCTB: case JUNGFRAU: - cout << "Info: ***** This is a " << getDetectorType(d) << " Receiver *****" << endl; + FILE_LOG(logINFO) << " ***** This is a " << getDetectorType(d) << " Receiver *****" << endl; break; default: cprintf(BG_RED, "Error: This is an unknown receiver type %d\n", (int)d); @@ -761,7 +763,8 @@ void UDPStandardImplementation::resetAcquisitionCount(){ int UDPStandardImplementation::startReceiver(char *c){ FILE_LOG(logDEBUG1) << __AT__ << " called"; - + + cout << endl; cout << "Info: Starting Receiver" << endl; @@ -800,15 +803,16 @@ int UDPStandardImplementation::startReceiver(char *c){ //Print Receiver Configuration - cout << "Info: ***Receiver Configuration***" << endl; - cout << "Info: Max Packets Per File:" << maxPacketsPerFile << endl; - cout << "Info: Data Compression has been " << stringEnable(dataCompressionEnable) << endl; - if(myDetectorType != EIGER) + if(myDetectorType != EIGER){ + + cout << "Info: Data Compression has been " << stringEnable(dataCompressionEnable) << endl; cout << "Info: Number of Jobs Per Buffer: " << numberofJobsPerBuffer << endl; + cout << "Info: Max Packets Per File:" << maxPacketsPerFile << endl; + } if(FrameToGuiFrequency) - cout << "Info: Frequency of frames sent to gui" << FrameToGuiFrequency << endl; + cout << "Info: requency of frames sent to gui: " << FrameToGuiFrequency << endl; else - cout << "Info: Random frames sent to gui" << endl; + cout << "Info: Frequency of frames sent to gui: Random" << endl; @@ -895,7 +899,7 @@ void UDPStandardImplementation::stopReceiver(){ int UDPStandardImplementation::shutDownUDPSockets(){ FILE_LOG(logDEBUG1) << __AT__ << " called"; - cout << "Info: Shutting down UDP Socket(s)" << endl; + FILE_LOG(logDEBUG1) << "Info: Shutting down UDP Socket(s)" << endl; for(int i=0;istart() == slsReceiverDefs::OK){ - cout << "DONE!" << endl; + FILE_LOG(logDEBUG1) << "DONE!" << endl; string str; cin>>str; //wait and look for an exit keyword diff --git a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp index be3242cd9..e0835df55 100644 --- a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp +++ b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp @@ -125,14 +125,14 @@ int slsReceiverTCPIPInterface::setPortNumber(int pn){ int slsReceiverTCPIPInterface::start(){ - cout << "Creating TCP Server Thread" << endl; + FILE_LOG(logDEBUG1) << "Creating TCP Server Thread" << endl; killTCPServerThread = 0; if(pthread_create(&TCPServer_thread, NULL,startTCPServerThread, (void*) this)){ cout << "Could not create TCP Server thread" << endl; return FAIL; } //#ifdef VERBOSE - cout << "TCP Server thread created successfully." << endl; + FILE_LOG(logDEBUG1) << "TCP Server thread created successfully." << endl; //#endif return OK; } From 963717215f346e7f06b4161b5ba3a88fec6e790f Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Thu, 29 Oct 2015 17:23:39 +0100 Subject: [PATCH 162/474] done --- slsReceiverSoftware/include/ansi.h | 29 +- slsReceiverSoftware/include/logger.h | 43 ++- .../src/UDPBaseImplementation.cpp | 16 +- slsReceiverSoftware/src/UDPInterface.cpp | 2 +- .../src/UDPStandardImplementation.cpp | 257 ++++++++---------- .../src/slsReceiverTCPIPInterface.cpp | 77 +++--- 6 files changed, 221 insertions(+), 203 deletions(-) diff --git a/slsReceiverSoftware/include/ansi.h b/slsReceiverSoftware/include/ansi.h index 1a24d403e..210491373 100644 --- a/slsReceiverSoftware/include/ansi.h +++ b/slsReceiverSoftware/include/ansi.h @@ -1,17 +1,18 @@ -#define RED "\x1b[31m" -#define GREEN "\x1b[32m" -#define YELLOW "\x1b[33m" -#define BLUE "\x1b[34m" -#define MAGENTA "\x1b[35m" -#define CYAN "\x1b[36m" -#define BG_RED "\x1b[41m" -#define BG_GREEN "\x1b[42m" -#define BG_YELLOW "\x1b[43m" -#define BG_BLUE "\x1b[44m" -#define BG_MAGENTA "\x1b[45m" -#define BG_CYAN "\x1b[46m" -#define RESET "\x1b[0m" -#define BOLD "\x1b[1m" +#define RED "\x1b[31m" +#define GREEN "\x1b[32m" +#define YELLOW "\x1b[33m" +#define BLUE "\x1b[34m" +#define MAGENTA "\x1b[35m" +#define CYAN "\x1b[36m" +#define GRAY "\x1b[37m" +#define BG_RED "\x1b[41m" +#define BG_GREEN "\x1b[42m" +#define BG_YELLOW "\x1b[43m" +#define BG_BLUE "\x1b[44m" +#define BG_MAGENTA "\x1b[45m" +#define BG_CYAN "\x1b[46m" +#define RESET "\x1b[0m" +#define BOLD "\x1b[1m" #define cprintf(code, format, ...) printf(code format RESET, ##__VA_ARGS__) diff --git a/slsReceiverSoftware/include/logger.h b/slsReceiverSoftware/include/logger.h index 5e964da27..7732abffc 100644 --- a/slsReceiverSoftware/include/logger.h +++ b/slsReceiverSoftware/include/logger.h @@ -5,6 +5,7 @@ #include #include #include +#include #ifdef VERBOSE #define FILELOG_MAX_LEVEL logDEBUG @@ -14,6 +15,10 @@ #define FILELOG_MAX_LEVEL logDEBUG4 #endif +#ifdef FIFODEBUG +#define FILELOG_MAX_LEVEL logDEBUG5 +#endif + #ifndef FILELOG_MAX_LEVEL #define FILELOG_MAX_LEVEL logINFO #endif @@ -40,7 +45,7 @@ void error(const char *location, const char *msg){ inline std::string NowTime(); -enum TLogLevel {logERROR, logWARNING, logINFO, logDEBUG, logDEBUG1, logDEBUG2, logDEBUG3, logDEBUG4}; +enum TLogLevel {logERROR, logWARNING, logINFO, logDEBUG, logDEBUG1, logDEBUG2, logDEBUG3, logDEBUG4, logDEBUG5}; template class Log{ public: @@ -52,6 +57,7 @@ template class Log{ static TLogLevel FromString(const std::string& level); protected: std::ostringstream os; + TLogLevel lev; private: Log(const Log&); Log& operator =(const Log&); @@ -62,6 +68,7 @@ class Output2FILE { public: static FILE*& Stream(); static void Output(const std::string& msg); + static void Output(const std::string& msg, TLogLevel level); }; #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) @@ -79,10 +86,17 @@ public: class FILELOG_DECLSPEC FILELog : public Log {}; //typedef Log FILELog; +#ifdef REST #define FILE_LOG(level) \ if (level > FILELOG_MAX_LEVEL) ; \ else if (level > FILELog::ReportingLevel() || !Output2FILE::Stream()) ; \ else FILELog().Get(level) +#else + #define FILE_LOG(level) \ + if (level > FILELOG_MAX_LEVEL) ; \ + else if (level > FILELog::ReportingLevel() || !Output2FILE::Stream()) ; \ + else FILELog().Get(level) +#endif #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) @@ -126,10 +140,11 @@ inline std::string NowTime() #endif //WIN32 -template Log::Log(){} +template Log::Log():lev(logDEBUG){} template std::ostringstream& Log::Get(TLogLevel level) { + lev = level; os << "- " << NowTime(); os << " " << ToString(level) << ": "; os << std::string(level > logDEBUG ? level - logDEBUG : 0, '\t'); @@ -139,24 +154,30 @@ template std::ostringstream& Log::Get(TLogLevel level) template Log::~Log() { os << std::endl; +#ifdef REST T::Output( os.str()); +#else + T::Output( os.str(),lev); +#endif } template TLogLevel& Log::ReportingLevel() { - static TLogLevel reportingLevel = logDEBUG4; + static TLogLevel reportingLevel = logDEBUG5; return reportingLevel; } template std::string Log::ToString(TLogLevel level) { - static const char* const buffer[] = {"ERROR", "WARNING", "INFO", "DEBUG", "DEBUG1", "DEBUG2", "DEBUG3", "DEBUG4"}; + static const char* const buffer[] = {"ERROR", "WARNING", "INFO", "DEBUG", "DEBUG1", "DEBUG2", "DEBUG3", "DEBUG4","DEBUG5"}; return buffer[level]; } template TLogLevel Log::FromString(const std::string& level) { + if (level == "DEBUG5") + return logDEBUG5; if (level == "DEBUG4") return logDEBUG4; if (level == "DEBUG3") @@ -193,6 +214,20 @@ inline void Output2FILE::Output(const std::string& msg) fflush(pStream); } +inline void Output2FILE::Output(const std::string& msg, TLogLevel level) +{ + FILE* pStream = Stream(); + if (!pStream) + return; + switch(level){ + case logERROR: cprintf(RED BOLD,"%s",msg.c_str()); break; + case logWARNING: cprintf(YELLOW BOLD,"%s",msg.c_str()); break; + case logINFO: cprintf(GRAY,"%s",msg.c_str()); break; + default: fprintf(pStream,"%s",msg.c_str()); break; + } + fflush(pStream); +} + #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) # if defined (BUILDING_FILELOG_DLL) # define FILELOG_DECLSPEC __declspec (dllexport) diff --git a/slsReceiverSoftware/src/UDPBaseImplementation.cpp b/slsReceiverSoftware/src/UDPBaseImplementation.cpp index 94a39d07d..eaac8c8e9 100644 --- a/slsReceiverSoftware/src/UDPBaseImplementation.cpp +++ b/slsReceiverSoftware/src/UDPBaseImplementation.cpp @@ -35,7 +35,7 @@ UDPBaseImplementation::UDPBaseImplementation(){ void UDPBaseImplementation::initializeMembers(){ FILE_LOG(logDEBUG) << __AT__ << " starting"; - FILE_LOG(logDEBUG1) << "Info: Initializing base members" << endl; + FILE_LOG(logDEBUG) << "Info: Initializing base members"; //**detector parameters*** myDetectorType = GENERIC; strcpy(detHostname,""); @@ -202,7 +202,7 @@ void UDPBaseImplementation::setBottomEnable(const bool b){ FILE_LOG(logDEBUG) << __AT__ << " starting"; bottomEnable = b; - FILE_LOG(logINFO) << "Bottom - " << stringEnable(bottomEnable) << endl; + FILE_LOG(logINFO) << "Bottom - " << stringEnable(bottomEnable); } @@ -216,7 +216,7 @@ void UDPBaseImplementation::setFileName(const char c[]){ } void UDPBaseImplementation::setFilePath(const char c[]){ - FILE_LOG(logINFO) << __AT__ << " starting"; + FILE_LOG(logDEBUG) << __AT__ << " starting"; if(strlen(c)){ //check if filepath exists @@ -229,7 +229,7 @@ void UDPBaseImplementation::setFilePath(const char c[]){ } strcpy(filePath, c); } - FILE_LOG(logDEBUG1) << "Info: File path:" << filePath; + FILE_LOG(logDEBUG) << "Info: File path:" << filePath; } void UDPBaseImplementation::setFileIndex(const uint64_t i){ @@ -285,14 +285,14 @@ void UDPBaseImplementation::setUDPPortNumber(const uint32_t i){ FILE_LOG(logDEBUG) << __AT__ << " starting"; udpPortNum[0] = i; - FILE_LOG(logINFO) << "udpPortNum[0]:" << udpPortNum[0]; + FILE_LOG(logINFO) << "UDP Port Number[0]:" << udpPortNum[0]; } void UDPBaseImplementation::setUDPPortNumber2(const uint32_t i){ FILE_LOG(logDEBUG) << __AT__ << " starting"; udpPortNum[1] = i; - FILE_LOG(logINFO) << "udpPortNum[1]:" << udpPortNum[1]; + FILE_LOG(logINFO) << "UDP Port Number[1]:" << udpPortNum[1]; } void UDPBaseImplementation::setEthernetInterface(const char* c){ @@ -325,7 +325,7 @@ int UDPBaseImplementation::setAcquisitionPeriod(const uint64_t i){ FILE_LOG(logDEBUG) << __AT__ << " starting"; acquisitionPeriod = i; - FILE_LOG(logINFO) << "Acquisition Period:" << acquisitionPeriod; + FILE_LOG(logINFO) << "Acquisition Period:" << (double)acquisitionPeriod/(1E9) << "s"; //overrridden child classes might return FAIL return OK; @@ -389,7 +389,7 @@ void UDPBaseImplementation::resetAcquisitionCount(){ FILE_LOG(logDEBUG) << __AT__ << " starting"; totalPacketsCaught = 0; - FILE_LOG(logINFO) << "totalPacketsCaught:" << totalPacketsCaught << endl; + FILE_LOG(logINFO) << "totalPacketsCaught:" << totalPacketsCaught; } int UDPBaseImplementation::startReceiver(char *c){ diff --git a/slsReceiverSoftware/src/UDPInterface.cpp b/slsReceiverSoftware/src/UDPInterface.cpp index 937035845..17491bc3a 100644 --- a/slsReceiverSoftware/src/UDPInterface.cpp +++ b/slsReceiverSoftware/src/UDPInterface.cpp @@ -23,7 +23,7 @@ using namespace std; UDPInterface * UDPInterface::create(string receiver_type){ if (receiver_type == "standard"){ - cout << "Starting " << receiver_type << endl; + FILE_LOG(logINFO) << "Starting " << receiver_type; return new UDPStandardImplementation(); } #ifdef REST diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index bfe8c9eb7..346d6db9f 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -42,10 +42,11 @@ UDPStandardImplementation::UDPStandardImplementation(){ pthread_mutex_init(&progressMutex,NULL); //to increase socket receiver buffer size and max length of input queue by changing kernel settings - if(system("echo $((100*1024*1024)) > /proc/sys/net/core/rmem_max")) - FILE_LOG(logDEBUG1) << "Warning: No root permission to change socket receiver buffer size in file /proc/sys/net/core/rmem_max" << endl; + if(myDetectorType == EIGER); + else if(system("echo $((100*1024*1024)) > /proc/sys/net/core/rmem_max")) + FILE_LOG(logDEBUG) << "Warning: No root permission to change socket receiver buffer size in file /proc/sys/net/core/rmem_max"; else if(system("echo 250000 > /proc/sys/net/core/netdev_max_backlog")) - FILE_LOG(logDEBUG1) << "Warning: No root permission to change max length of input queue in file /proc/sys/net/core/netdev_max_backlog" << endl; + FILE_LOG(logDEBUG) << "Warning: No root permission to change max length of input queue in file /proc/sys/net/core/netdev_max_backlog"; /** permanent setting by heiner net.core.rmem_max = 104857600 # 100MiB net.core.netdev_max_backlog = 250000 @@ -53,8 +54,7 @@ UDPStandardImplementation::UDPStandardImplementation(){ // from the manual sysctl -w net.core.rmem_max=16777216 sysctl -w net.core.netdev_max_backlog=250000 - */ - cout << endl; + */ } UDPStandardImplementation::~UDPStandardImplementation(){ @@ -74,7 +74,7 @@ UDPStandardImplementation::~UDPStandardImplementation(){ void UDPStandardImplementation::deleteMembers(){ FILE_LOG(logDEBUG1) << __AT__ << " starting"; - FILE_LOG(logDEBUG1) << "Info: Deleting member pointers" << endl; + FILE_LOG(logDEBUG) << "Info: Deleting member pointers"; shutDownUDPSockets(); closeFile(); //filter @@ -120,7 +120,7 @@ void UDPStandardImplementation::initializeBaseMembers(){ void UDPStandardImplementation::initializeMembers(){ FILE_LOG(logDEBUG1) << __AT__ << " starting"; - FILE_LOG(logDEBUG1) << "Info: Initializing members" << endl; + FILE_LOG(logDEBUG) << "Info: Initializing members"; //***detector parameters*** frameSize = 0; @@ -257,7 +257,7 @@ int UDPStandardImplementation::setupFifoStructure(){ //eiger always listens to 1 packet at a time if(myDetectorType == EIGER){ numberofJobsPerBuffer = 1; - FILE_LOG(logDEBUG1) << "Info: 1 packet per buffer" << endl; + FILE_LOG(logDEBUG) << "Info: 1 packet per buffer"; } //else calculate best possible number of frames to listen to at a time (for fast readouts like gotthard) @@ -280,7 +280,7 @@ int UDPStandardImplementation::setupFifoStructure(){ numberofJobsPerBuffer = i; } - cout << "Info: Number of Frames per buffer:" << numberofJobsPerBuffer << endl; + FILE_LOG(logINFO) << "Number of Frames per buffer:" << numberofJobsPerBuffer << endl; } //set fifo depth @@ -299,7 +299,7 @@ int UDPStandardImplementation::setupFifoStructure(){ else fifoSize = fifoSize/numberofJobsPerBuffer; } - FILE_LOG(logDEBUG1) << "Info: Fifo Depth:" << fifoSize << endl; + FILE_LOG(logDEBUG) << "Info: Fifo Depth:" << fifoSize; @@ -315,8 +315,8 @@ int UDPStandardImplementation::setupFifoStructure(){ if(fifoFree[i]){ while(!fifoFree[i]->isEmpty()) fifoFree[i]->pop(buffer[i]); -#ifdef FIFODEBUG - cprintf(GREEN,"Info: %d fifostructure popped from fifofree %p\n", i, (void*)(buffer[i])); +#ifdef DEBUG5 + cprintf(BLUE,"Info: %d fifostructure popped from fifofree %p\n", i, (void*)(buffer[i])); #endif delete fifoFree[i]; } @@ -338,13 +338,13 @@ int UDPStandardImplementation::setupFifoStructure(){ buffer[i]=mem0[i]; while (buffer[i] < (mem0[i]+(bufferSize * numberofJobsPerBuffer + HEADER_SIZE_NUM_TOT_PACKETS) * (fifoSize-1))) { fifoFree[i]->push(buffer[i]); -#ifdef FIFODEBUG +#ifdef DEBUG5 cprintf(BLUE,"Info: %d fifostructure free pushed into fifofree %p\n", i, (void*)(buffer[i])); #endif buffer[i] += (bufferSize * numberofJobsPerBuffer + HEADER_SIZE_NUM_TOT_PACKETS); } } - FILE_LOG(logDEBUG1) << "Info: Fifo structure(s) reconstructed" << endl; + FILE_LOG(logDEBUG) << "Info: Fifo structure(s) reconstructed"; return OK; } @@ -366,7 +366,7 @@ void UDPStandardImplementation::configure(map config_map){ b = 0; } bottomEnable = b!= 0; - cout << "Info: Bottom - " << stringEnable(bottomEnable) << endl; + FILE_LOG(logINFO) << "Bottom: " << stringEnable(bottomEnable); } } @@ -410,7 +410,7 @@ int UDPStandardImplementation::setDataCompressionEnable(const bool b){ if(b) initializeFilter(); - cout << "Info: Data Compression " << stringEnable(dataCompressionEnable) << endl; + FILE_LOG(logINFO) << "Data Compression: " << stringEnable(dataCompressionEnable); return OK; } @@ -450,7 +450,7 @@ void UDPStandardImplementation::setShortFrameEnable(const int i){ if(dataCompressionEnable) initializeFilter(); - cout << "Info: Short Frame Enable set to " << shortFrameEnable << endl; + FILE_LOG(logINFO) << "Short Frame Enable: " << shortFrameEnable; } @@ -461,7 +461,7 @@ int UDPStandardImplementation::setFrameToGuiFrequency(const uint32_t i){ if(setupFifoStructure() == FAIL) return FAIL; - cout << "Info: Frame to Gui Frequency set to " << FrameToGuiFrequency << endl; + FILE_LOG(logINFO) << "Frame to Gui Frequency: " << FrameToGuiFrequency; return OK; } @@ -474,7 +474,7 @@ int UDPStandardImplementation::setAcquisitionPeriod(const uint64_t i){ if(setupFifoStructure() == FAIL) return FAIL; - cout << "Info: Acquisition Period set to " << acquisitionPeriod << endl; + FILE_LOG(logINFO) << "Acquisition Period: " << (double)acquisitionPeriod/(1E9) << "s"; return OK; @@ -485,7 +485,7 @@ int UDPStandardImplementation::setDynamicRange(const uint32_t i){ uint32_t oldDynamicRange = dynamicRange; - cout << "Info: Setting Dynamic Range to " << i << endl; + FILE_LOG(logDEBUG) << "Info: Setting Dynamic Range to " << i; dynamicRange = i; if(myDetectorType == EIGER){ @@ -515,11 +515,11 @@ int UDPStandardImplementation::setDynamicRange(const uint32_t i){ //create threads if(createListeningThreads() == FAIL){ - cprintf(BG_RED,"Error: Could not create listening thread\n"); + FILE_LOG(logERROR) << "Could not create listening thread"; return FAIL; } if(createWriterThreads() == FAIL){ - cprintf(BG_RED,"Error: Could not create writer threads\n"); + FILE_LOG(logERROR) << "Could not create writer threads"; return FAIL; } setThreadPriorities(); @@ -527,7 +527,7 @@ int UDPStandardImplementation::setDynamicRange(const uint32_t i){ } - cout << "Info: Dynamic Range set to " << dynamicRange << endl; + FILE_LOG(logINFO) << "Dynamic Range: " << dynamicRange; return OK; } @@ -537,7 +537,7 @@ int UDPStandardImplementation::setDynamicRange(const uint32_t i){ int UDPStandardImplementation::setTenGigaEnable(const bool b){ FILE_LOG(logDEBUG1) << __AT__ << " called"; - cout << "Info: Setting Ten Giga to " << stringEnable(b) << endl; + FILE_LOG(logDEBUG) << "Info: Setting Ten Giga to " << stringEnable(b); bool oldTenGigaEnable = tengigaEnable; tengigaEnable = b; @@ -557,13 +557,13 @@ int UDPStandardImplementation::setTenGigaEnable(const bool b){ bufferSize = onePacketSize; maxPacketsPerFile = EIGER_MAX_FRAMES_PER_FILE * packetsPerFrame; - FILE_LOG(logDEBUG1) << dec << + FILE_LOG(logDEBUG) << dec << "packetsPerFrame:" << packetsPerFrame << "\nonePacketSize:" << onePacketSize << "\noneDataSize:" << oneDataSize << "\nframesize:" << frameSize << "\nbufferSize:" << bufferSize << - "\nmaxPacketsPerFile:" << maxPacketsPerFile << endl; + "\nmaxPacketsPerFile:" << maxPacketsPerFile; @@ -586,11 +586,11 @@ int UDPStandardImplementation::setTenGigaEnable(const bool b){ //create threads if(createListeningThreads() == FAIL){ - cprintf(BG_RED,"Error: Could not create listening thread\n"); + FILE_LOG(logERROR) << "Could not create listening thread"; return FAIL; } if(createWriterThreads() == FAIL){ - cprintf(BG_RED,"Error: Could not create writer threads\n"); + FILE_LOG(logERROR) << "Could not create writer threads"; return FAIL; } setThreadPriorities(); @@ -598,7 +598,7 @@ int UDPStandardImplementation::setTenGigaEnable(const bool b){ } - cout << "Info: Ten Giga " << stringEnable(tengigaEnable) << endl; + FILE_LOG(logINFO) << "Ten Giga: " << stringEnable(tengigaEnable); return OK; } @@ -619,7 +619,7 @@ int UDPStandardImplementation::setTenGigaEnable(const bool b){ int UDPStandardImplementation::setDetectorType(const detectorType d){ FILE_LOG(logDEBUG1) << __AT__ << " called"; - cout << "Info: Setting receiver type ..." << endl; + FILE_LOG(logDEBUG) << "Setting receiver type"; deleteMembers(); initializeBaseMembers(); @@ -633,10 +633,10 @@ int UDPStandardImplementation::setDetectorType(const detectorType d){ case EIGER: case JUNGFRAUCTB: case JUNGFRAU: - FILE_LOG(logINFO) << " ***** This is a " << getDetectorType(d) << " Receiver *****" << endl; + FILE_LOG(logINFO) << " ***** This is a " << getDetectorType(d) << " Receiver *****"; break; default: - cprintf(BG_RED, "Error: This is an unknown receiver type %d\n", (int)d); + FILE_LOG(logERROR) << "This is an unknown receiver type " << (int)d; return FAIL; } @@ -710,7 +710,7 @@ int UDPStandardImplementation::setDetectorType(const detectorType d){ //footerOffset = Not applicable; break; default: - cprintf(BG_RED, "Error: This is an unknown receiver type %d\n", (int)d); + FILE_LOG(logERROR) << "This is an unknown receiver type " << (int)d; return FAIL; } @@ -730,11 +730,11 @@ int UDPStandardImplementation::setDetectorType(const detectorType d){ //create threads if(createListeningThreads() == FAIL){ - cprintf(BG_RED,"Error: Could not create listening thread\n"); + FILE_LOG(logERROR) << "Could not create listening thread"; return FAIL; } if(createWriterThreads() == FAIL){ - cprintf(BG_RED,"Error: Could not create writer threads\n"); + FILE_LOG(logERROR) << "Could not create writer threads"; return FAIL; } setThreadPriorities(); @@ -742,8 +742,7 @@ int UDPStandardImplementation::setDetectorType(const detectorType d){ //allocate for latest data (frame copy for gui) latestData = new char[frameSize]; - cout << " Detector type set to " << getDetectorType(d) << endl; - cout << "Ready..." << endl; + FILE_LOG(logDEBUG) << " Detector type set to " << getDetectorType(d); return OK; } @@ -757,15 +756,14 @@ void UDPStandardImplementation::resetAcquisitionCount(){ acqStarted = false; startAcquisitionIndex = 0; - cout << "Info: Acquisition Count has been reset" << endl; + FILE_LOG(logINFO) << "Acquisition Count has been reset"; } int UDPStandardImplementation::startReceiver(char *c){ FILE_LOG(logDEBUG1) << __AT__ << " called"; - cout << endl; - cout << "Info: Starting Receiver" << endl; + FILE_LOG(logINFO) << "Starting Receiver"; //RESET @@ -804,32 +802,29 @@ int UDPStandardImplementation::startReceiver(char *c){ //Print Receiver Configuration if(myDetectorType != EIGER){ - - cout << "Info: Data Compression has been " << stringEnable(dataCompressionEnable) << endl; - cout << "Info: Number of Jobs Per Buffer: " << numberofJobsPerBuffer << endl; - cout << "Info: Max Packets Per File:" << maxPacketsPerFile << endl; + FILE_LOG(logINFO) << "Data Compression has been " << stringEnable(dataCompressionEnable); + FILE_LOG(logINFO) << "Number of Jobs Per Buffer: " << numberofJobsPerBuffer; + FILE_LOG(logINFO) << "Max Packets Per File:" << maxPacketsPerFile; } if(FrameToGuiFrequency) - cout << "Info: requency of frames sent to gui: " << FrameToGuiFrequency << endl; + FILE_LOG(logINFO) << "Frequency of frames sent to gui: " << FrameToGuiFrequency; else - cout << "Info: Frequency of frames sent to gui: Random" << endl; + FILE_LOG(logINFO) << "Frequency of frames sent to gui: Random"; //create UDP sockets if(createUDPSockets() == FAIL){ - strcpy(c,"Could not create UDP Socket(s).\n"); - cout << endl; - cprintf(BG_RED, "Error: %s\n",c); + strcpy(c,"Could not create UDP Socket(s)."); + FILE_LOG(logERROR) << c; return FAIL; } if(setupWriter() == FAIL){ //stop udp socket shutDownUDPSockets(); - sprintf(c,"Could not create file %s.\n",completeFileName); - cout << endl; - cprintf(BG_RED, "Error: %s\n",c); + sprintf(c,"Could not create file %s.",completeFileName); + FILE_LOG(logERROR) << c; return FAIL; } @@ -854,8 +849,8 @@ int UDPStandardImplementation::startReceiver(char *c){ for(int i=0; i < numberofWriterThreads; i++) sem_post(&writerSemaphore[i]); //usleep(5000000); - cout << "Info: Receiver Started." << endl; - cout << "Info: Status:" << runStatusType(status) << endl; + FILE_LOG(logINFO) << "Receiver Started"; + FILE_LOG(logINFO) << "Status:" << runStatusType(status); return OK; } @@ -868,7 +863,7 @@ int UDPStandardImplementation::startReceiver(char *c){ void UDPStandardImplementation::stopReceiver(){ FILE_LOG(logDEBUG1) << __AT__ << " called"; - cout << "Info: Stopping Receiver" << endl; + FILE_LOG(logINFO) << "Stopping Receiver"; //set status to transmitting startReadout(); @@ -887,8 +882,8 @@ void UDPStandardImplementation::stopReceiver(){ status = IDLE; pthread_mutex_unlock(&(statusMutex)); - cout << "Info: Receiver Stopped" << endl; - cout << "Info: Status:" << runStatusType(status) << endl; + FILE_LOG(logINFO) << "Receiver Stopped"; + FILE_LOG(logINFO) << "Status:" << runStatusType(status); cout << endl; } @@ -899,7 +894,7 @@ void UDPStandardImplementation::stopReceiver(){ int UDPStandardImplementation::shutDownUDPSockets(){ FILE_LOG(logDEBUG1) << __AT__ << " called"; - FILE_LOG(logDEBUG1) << "Info: Shutting down UDP Socket(s)" << endl; + FILE_LOG(logDEBUG) << "Info: Shutting down UDP Socket(s)"; for(int i=0;iWrite()) //->Write(tall->GetName(),TObject::kOverwrite); - cout << "Info: Thread " << i <<": wrote frames to file" << endl; + FILE_LOG(logINFO) << "Thread " << i <<": wrote frames to file"; else - cout << "Info: Thread " << i << ": could not write frames to file" << endl; + FILE_LOG(logINFO) << "Thread " << i << ": could not write frames to file"; }else - cout << "Info: Thread " << i << ": could not write frames to file: No file or No Tree" << endl; + FILE_LOG(logINFO) << "Thread " << i << ": could not write frames to file: No file or No Tree"; //close file if(myTree[i] && myFile[i]) myFile[i] = myTree[i]->GetCurrentFile(); @@ -1068,23 +1063,22 @@ int UDPStandardImplementation::createListeningThreads(bool destroy){ //destroy if(destroy){ - FILE_LOG(logDEBUG) << "Info: Destroying Listening Thread(s)" << endl; + FILE_LOG(logDEBUG) << "Info: Destroying Listening Thread(s)"; killAllListeningThreads = true; for(int i = 0; i < numberofListeningThreads; ++i){ sem_post(&listenSemaphore[i]); pthread_join(listeningThreads[i],NULL); - cout <<"."<getErrorStatus(); if(!iret){ - cout << "Info: UDP port opened at port " << port[i] << endl; + FILE_LOG(logINFO) << "UDP port opened at port " << port[i]; }else{ -#ifdef VERBOSE - cprintf(BG_RED,"Error: Could not create UDP socket on port %d error: %d\n", port[i], iret); -#endif + FILE_LOG(logERROR) << "Could not create UDP socket on port " << port[i] << " error: " << iret; shutDownUDPSockets(); return FAIL; } } - cout << "Info: UDP socket(s) created successfully." << endl; - cout << "Info: Listener Ready ..." << endl; + FILE_LOG(logDEBUG) << "UDP socket(s) created successfully."; + FILE_LOG(logINFO) << "Listener Ready ..."; return OK; } @@ -1270,11 +1254,11 @@ int UDPStandardImplementation::setupWriter(){ cbAction=startAcquisitionCallBack(filePath,fileName,(int)fileIndex,bufferSize,pStartAcquisition); if(cbAction < DO_EVERYTHING){ - cout << "Info: Call back activated. Data saving must be taken care of by user in call back." << endl; + FILE_LOG(logINFO) << "Call back activated. Data saving must be taken care of by user in call back."; if (rawDataReadyCallBack) - cout << "Info: Data Write has been defined externally" << endl; + FILE_LOG(logINFO) << "Data Write has been defined externally"; }else if(!fileWriteEnable) - cout << "Info: Data will not be saved" << endl; + FILE_LOG(logINFO) << "Data will not be saved"; @@ -1285,7 +1269,7 @@ int UDPStandardImplementation::setupWriter(){ pthread_mutex_unlock(&statusMutex); for(int i=0; inewDataSet(); if(myFile[ithread]==NULL){ - cprintf(BG_RED,"Error: File Null\n"); + FILE_LOG(logERROR) << "File Null"; return FAIL; } if(!myFile[ithread]->IsOpen()){ - cprintf(BG_RED,"Error: File Not Open\n") + FILE_LOG(logERROR) << "File Not Open"; return FAIL; } return OK; @@ -1464,13 +1448,13 @@ void UDPStandardImplementation::startListening(){ //pop from fifo fifoFree[ithread]->pop(buffer[ithread]); -#ifdef FIFODEBUG - cprintf(BLUE,"%d :Listener popped from fifofree %p\n", ithread, (void*)(buffer[ithread])); +#ifdef DEBUG5 + cprintf(BLUE,"Listening_Thread %d :Listener popped from fifofree %p\n", ithread, (void*)(buffer[ithread])); #endif //udpsocket doesnt exist if(udpSocket[ithread] == NULL){ - cprintf(RED, "Error: Thread %d :UDP Socket not created\n",ithread); + FILE_LOG(logERROR) << "Listening_Thread " << ithread << ": UDP Socket not created"; stopListening(ithread,0); continue; } @@ -1501,7 +1485,7 @@ void UDPStandardImplementation::startListening(){ //push buffer to FIFO while(!fifo[ithread]->push(buffer[ithread])); -#ifdef FIFODEBUG +#ifdef DEBUG5 cprintf(BLUE,"Listening_Thread %d: Listener pushed into fifo %p\n",ithread, (void*)(buffer[ithread])); #endif @@ -1512,7 +1496,7 @@ void UDPStandardImplementation::startListening(){ //check to exit thread (for change of parameters) - only EXIT possibility if(killAllListeningThreads){ - cprintf(GREEN,"Listening_Thread %d:Goodbye!\n",ithread); + cprintf(BLUE,"Listening_Thread %d:Goodbye!\n",ithread); //free resources at exit if(tempBuffer) delete[] tempBuffer; pthread_exit(NULL); @@ -1544,7 +1528,7 @@ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int lSize, in } #ifdef DEBUG - cprintf(BLUE, "Listening_Thread %d : Received bytes: %d. Expected bytes: %d\n", ithread, receivedSize, expected-cSize); + cprintf(BLUE, "Listening_Thread %d : Received bytes: %d. Expected bytes: %d\n", ithread, receivedSize, bufferSize * numberofJobsPerBuffer-cSize); #endif return receivedSize; } @@ -1577,11 +1561,11 @@ void UDPStandardImplementation::startFrameIndices(int ithread){ if(!acqStarted){ startAcquisitionIndex = startFrameIndex; acqStarted = true; - cprintf(BLUE,"Info: Thread %d: startAcquisitionIndex:%lld\n",ithread,(long long int)startAcquisitionIndex); + cprintf(BLUE,"Listening_Thread %d: startAcquisitionIndex:%lld\n",ithread,(long long int)startAcquisitionIndex); } //set start of scan/real time measurement - cprintf(BLUE,"Info: Thread %d: startFrameIndex: %lld\n", ithread,(long long int)startFrameIndex); + cprintf(BLUE,"Listening_Thread %d: startFrameIndex: %lld\n", ithread,(long long int)startFrameIndex); measurementStarted = true; } @@ -1594,8 +1578,7 @@ void UDPStandardImplementation::startFrameIndices(int ithread){ void UDPStandardImplementation::stopListening(int ithread, int numbytes){ FILE_LOG(logDEBUG1) << __AT__ << " called"; - cout << "Info: Thread " << ithread << ": Stop Listening.\nStatus:" << runStatusType(status) << endl; - + cprintf(BLUE,"Listening_Thread %d: Stop Listening.\nStatus:%s\n", ithread, runStatusType(status).c_str()); //less than 1 packet size (especially for eiger), ignore the buffer (so that 2 dummy buffers are not sent with pc=0) if(numbytes < onePacketSize) @@ -1604,9 +1587,9 @@ void UDPStandardImplementation::stopListening(int ithread, int numbytes){ //free empty buffer if(numbytes <= 0){ - cprintf(BLUE,"Info: Thread %d :End of Acquisition for Listening Thread\n", ithread); + cprintf(BLUE,"Listening_Thread %d :End of Acquisition\n", ithread); while(!fifoFree[ithread]->push(buffer[ithread])); -#ifdef FIFODEBUG +#ifdef DEBUG5 cprintf(BLUE,"Listening_Thread %d :Listener push empty buffer into fifofree %p\n", ithread, (void*)(buffer[ithread])); #endif } @@ -1621,7 +1604,7 @@ void UDPStandardImplementation::stopListening(int ithread, int numbytes){ cprintf(BLUE,"Listening_Thread %d: Last Buffer packet count:%d\n",ithread, numbytes/onePacketSize); #endif while(!fifo[ithread]->push(buffer[ithread])); -#ifdef FIFODEBUG +#ifdef DEBUG5 cprintf(BLUE,"Listening_Thread %d: Listener Last Buffer pushed into fifo %p\n", ithread,(void*)(buffer[ithread])); #endif } @@ -1632,7 +1615,7 @@ void UDPStandardImplementation::stopListening(int ithread, int numbytes){ //creating dummy-end buffer with pc=0xFFFF (*((uint32_t*)(buffer[ithread]))) = dummyPacketValue; while(!fifo[ithread]->push(buffer[ithread])); -#ifdef FIFODEBUG +#ifdef DEBUG5 cprintf(BLUE,"Listening_Thread %d: Listener pushed dummy-end buffer into fifo %p\n", ithread,(void*)(buffer[ithread])); #endif } @@ -1797,7 +1780,7 @@ void UDPStandardImplementation::processWritingBuffer(int ithread){ while((1 << ithread) & writerThreadsMask){ //pop fifo[0]->pop(wbuf[0]); -#ifdef FIFODEBUG +#ifdef DEBUG5 cprintf(GREEN,"Writing_Thread %d: Popped %p from FIFO %d\n", ithread, (void*)(wbuf[0]),0); #endif uint32_t numPackets = (uint32_t)(*((uint32_t*)wbuf[0])); @@ -1952,7 +1935,7 @@ void UDPStandardImplementation::processWritingBufferPacketByPacket(int ithread){ //update frame number and packet number if(numPackets[i] != dummyPacketValue){ if(!((uint32_t)(*( (uint64_t*) packetBuffer_footer)))){ - cprintf(BG_RED,"Fifo %d: Error: Frame Number is zero from firmware. popready[%d]:%d\n",i,i,popReady[i]); + FILE_LOG(logERROR) << "Fifo "<< i << ": Frame Number is zero from firmware. popready[" << i << "]:" << popReady[i]; popReady[i]=true; continue; } @@ -2090,13 +2073,13 @@ void UDPStandardImplementation::processWritingBufferPacketByPacket(int ithread){ //freeing for(int j=0;jpush(toFreePointers[j])); -#ifdef FIFODEBUG +#ifdef DEBUG5 cprintf(GREEN,"Fifo 0: Writing_Thread freed: pushed into fifofree %p\n",ithread, (void*)(toFreePointers[j])); #endif } for(int j=(packetsPerFrame/numberofListeningThreads);jpush(toFreePointers[j])); -#ifdef FIFODEBUG +#ifdef DEBUG5 cprintf(GREEN,"Fifo 1: Writing_Thread freed: pushed into fifofree %p\n",ithread, (void*)(toFreePointers[j])); #endif } @@ -2210,7 +2193,7 @@ bool UDPStandardImplementation::popAndCheckEndofAcquisition(int ithread, char* w //pop if ready if(ready[i]){ fifo[i]->pop(wbuffer[i]); -#ifdef FIFODEBUG +#ifdef DEBUG5 cprintf(GREEN,"Writing_Thread %d: Popped %p from FIFO %d\n", ithread, (void*)(wbuffer[i]),i); #endif nP[i] = (uint32_t)(*((uint32_t*)wbuffer[i])); @@ -2259,7 +2242,7 @@ void UDPStandardImplementation::stopWriting(int ithread, char* wbuffer[]){ //free fifo for(int i=0; ipush(wbuffer[i])); -#ifdef FIFODEBUG +#ifdef DEBUG5 cprintf(GREEN,"Writing_Thread %d: Freeing dummy-end buffer. Pushed into fifofree %p for listener %d\n", ithread,(void*)(wbuffer[i]),i); #endif } @@ -2296,12 +2279,12 @@ void UDPStandardImplementation::stopWriting(int ithread, char* wbuffer[]){ //statistics cprintf(GREEN, "Status: Run Finished\n"); - if(!totalPacketsCaught){ - cprintf(RED, "Total Missing Packets padded:%d\n",numTotMissingPackets); - cprintf(RED, "Total Packets Caught: 0\n"); + if((long long int)(totalPacketsCaught/packetsPerFrame) == 0){ + cprintf(RED, "Total Missing Packets padded: %d\n",numTotMissingPackets); + cprintf(RED, "Total Packets Caught: %lld\n",(long long int)totalPacketsCaught); cprintf(RED, "Total Frames Caught: 0\n"); }else{ - cprintf(GREEN, "Total Missing Packets padded:%d\n",numTotMissingPackets); + cprintf(GREEN, "Total Missing Packets padded: %d\n",numTotMissingPackets); cprintf(GREEN, "Total Packets Caught:%lld\n", (long long int)totalPacketsCaught); cprintf(GREEN, "Total Frames Caught:%lld\n",(long long int)(totalPacketsCaught/packetsPerFrame)); } @@ -2365,7 +2348,7 @@ void UDPStandardImplementation::handleWithoutDataCompression(int ithread, char* //free fifo addresses (eiger frees for each packet later) if(myDetectorType != EIGER){ while(!fifoFree[0]->push(wbuffer[0])); -#ifdef FIFODEBUG +#ifdef DEBUG5 cprintf(GREEN,"Writing_Thread %d: Freed buffer, pushed into fifofree %p for listener 0\n",ithread, (void*)(wbuffer[0])); #endif } @@ -2701,7 +2684,7 @@ void UDPStandardImplementation::handleDataCompression(int ithread, char* wbuffer while(!fifoFree[0]->push(wbuffer[0])); -#ifdef FIFODEBUG +#ifdef DEBUG5 cprintf(GREEN,"Writing_Thread %d: Compression free pushed into fifofree %p for listerner 0\n", ithread, (void*)(wbuffer[0])); #endif } diff --git a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp index e0835df55..d7e562f76 100644 --- a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp +++ b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp @@ -125,14 +125,14 @@ int slsReceiverTCPIPInterface::setPortNumber(int pn){ int slsReceiverTCPIPInterface::start(){ - FILE_LOG(logDEBUG1) << "Creating TCP Server Thread" << endl; + FILE_LOG(logDEBUG) << "Creating TCP Server Thread" << endl; killTCPServerThread = 0; if(pthread_create(&TCPServer_thread, NULL,startTCPServerThread, (void*) this)){ cout << "Could not create TCP Server thread" << endl; return FAIL; } //#ifdef VERBOSE - FILE_LOG(logDEBUG1) << "TCP Server thread created successfully." << endl; + FILE_LOG(logDEBUG) << "TCP Server thread created successfully." << endl; //#endif return OK; } @@ -395,25 +395,27 @@ int slsReceiverTCPIPInterface::set_detector_type(){ if(ret != FAIL){ #ifndef REST receiverBase = UDPInterface::create("standard"); - receiverBase->setBottomEnable(bottom); #endif myDetectorType = dr; ret=receiverBase->setDetectorType(myDetectorType); retval = myDetectorType; +#ifndef REST + receiverBase->setBottomEnable(bottom); +#endif } } } //#ifdef VERBOSE if(ret!=FAIL) - cout << "detector type " << dr << endl; + FILE_LOG(logDEBUG) << "detector type " << dr; else cprintf(RED, "%s\n", mess); //#endif #endif if(ret==OK && socket->differentClients){ - cout << "Force update" << endl; + FILE_LOG(logDEBUG) << "Force update"; ret=FORCE_UPDATE; } @@ -474,7 +476,7 @@ int slsReceiverTCPIPInterface::set_file_name() { #endif if(ret==OK && socket->differentClients){ - cout << "Force update" << endl; + FILE_LOG(logDEBUG) << "Force update"; ret=FORCE_UPDATE; } @@ -546,7 +548,7 @@ int slsReceiverTCPIPInterface::set_file_dir() { #endif if(ret==OK && socket->differentClients){ - cout << "Force update" << endl; + FILE_LOG(logDEBUG) << "Force update"; ret=FORCE_UPDATE; } @@ -612,7 +614,7 @@ int slsReceiverTCPIPInterface::set_file_index() { #endif if(ret==OK && socket->differentClients){ - cout << "Force update" << endl; + FILE_LOG(logDEBUG) << "Force update"; ret=FORCE_UPDATE; } @@ -685,7 +687,7 @@ int slsReceiverTCPIPInterface::set_frame_index() { #endif if(ret==OK && socket->differentClients){ - cout << "Force update" << endl; + FILE_LOG(logDEBUG) << "Force update"; ret=FORCE_UPDATE; } @@ -748,12 +750,12 @@ int slsReceiverTCPIPInterface::setup_udp(){ receiverBase->setUDPPortNumber2(udpport2); //setup udpip //get ethernet interface or IP to listen to - cout << "Ethernet interface is " << args[0] << endl; + FILE_LOG(logINFO) << "Receiver UDP IP: " << args[0]; temp = genericSocket::ipToName(args[0]); - cout << temp << endl; if(temp=="none"){ ret = FAIL; - strcpy(mess, "failed to get ethernet interface or IP to listen to\n"); + strcpy(mess, "Failed to get ethernet interface or IP\n"); + FILE_LOG(logERROR) << mess; } else{ strcpy(eth,temp.c_str()); @@ -761,9 +763,7 @@ int slsReceiverTCPIPInterface::setup_udp(){ strcpy(eth,""); ret = FAIL; } - FILE_LOG(logDEBUG) << __FILE__ << "::" << __func__ << " " << eth; receiverBase->setEthernetInterface(eth); - cout << eth << endl; //get mac address from ethernet interface if (ret != FAIL) @@ -773,11 +773,10 @@ int slsReceiverTCPIPInterface::setup_udp(){ if ((temp=="00:00:00:00:00:00") || (ret == FAIL)){ ret = FAIL; strcpy(mess,"failed to get mac adddress to listen to\n"); - cprintf(RED,"%s\n",mess); } else{ strcpy(retval,temp.c_str()); - cout<<"mac:"<differentClients){ - cout << "Force update" << endl; + FILE_LOG(logDEBUG) << "Force update"; ret=FORCE_UPDATE; } // send answer socket->SendDataOnly(&ret,sizeof(ret)); if(ret==FAIL){ - cprintf(RED, "%s\n", mess); + FILE_LOG(logERROR) << mess; socket->SendDataOnly(mess,sizeof(mess)); } socket->SendDataOnly(retval,MAX_STR_LENGTH); @@ -840,7 +839,7 @@ int slsReceiverTCPIPInterface::start_receiver(){ #endif if(ret==OK && socket->differentClients){ - cout << "Force update" << endl; + FILE_LOG(logDEBUG) << "Force update"; ret=FORCE_UPDATE; } @@ -886,7 +885,7 @@ int slsReceiverTCPIPInterface::stop_receiver(){ #endif if(ret==OK && socket->differentClients){ - cout << "Force update" << endl; + FILE_LOG(logDEBUG) << "Force update"; ret=FORCE_UPDATE; } @@ -916,7 +915,7 @@ int slsReceiverTCPIPInterface::get_status(){ #endif if(ret==OK && socket->differentClients){ - cout << "Force update" << endl; + FILE_LOG(logDEBUG) << "Force update"; ret=FORCE_UPDATE; } @@ -946,7 +945,7 @@ int slsReceiverTCPIPInterface::get_frames_caught(){ }else retval=receiverBase->getTotalFramesCaught(); #endif if(ret==OK && socket->differentClients){ - cout << "Force update" << endl; + FILE_LOG(logDEBUG) << "Force update"; ret=FORCE_UPDATE; } @@ -978,7 +977,7 @@ int slsReceiverTCPIPInterface::get_frame_index(){ #endif if(ret==OK && socket->differentClients){ - cout << "Force update" << endl; + FILE_LOG(logDEBUG) << "Force update"; ret=FORCE_UPDATE; } @@ -1019,7 +1018,7 @@ int slsReceiverTCPIPInterface::reset_frames_caught(){ #endif if(ret==OK && socket->differentClients){ - cout << "Force update" << endl; + FILE_LOG(logDEBUG) << "Force update"; ret=FORCE_UPDATE; } @@ -1087,7 +1086,7 @@ int slsReceiverTCPIPInterface::set_short_frame() { #endif if(ret==OK && socket->differentClients){ - cout << "Force update" << endl; + FILE_LOG(logDEBUG) << "Force update"; ret=FORCE_UPDATE; } @@ -1267,7 +1266,7 @@ int slsReceiverTCPIPInterface::moench_read_frame(){ #endif if(ret==OK && socket->differentClients){ - cout << "Force update" << endl; + FILE_LOG(logDEBUG) << "Force update"; ret=FORCE_UPDATE; } @@ -1448,7 +1447,7 @@ int slsReceiverTCPIPInterface::gotthard_read_frame(){ #endif if(ret==OK && socket->differentClients){ - cout << "Force update" << endl; + FILE_LOG(logDEBUG) << "Force update"; ret=FORCE_UPDATE; } @@ -1602,7 +1601,7 @@ int slsReceiverTCPIPInterface::propix_read_frame(){ #endif if(ret==OK && socket->differentClients){ - cout << "Force update" << endl; + FILE_LOG(logDEBUG) << "Force update"; ret=FORCE_UPDATE; } @@ -1864,7 +1863,7 @@ int slsReceiverTCPIPInterface::eiger_read_frame(){ #endif if(ret==OK && socket->differentClients){ - cout << "Force update" << endl; + FILE_LOG(logDEBUG) << "Force update"; ret=FORCE_UPDATE; } @@ -1939,7 +1938,7 @@ int slsReceiverTCPIPInterface::set_read_frequency(){ #endif if(ret==OK && socket->differentClients){ - cout << "Force update" << endl; + FILE_LOG(logDEBUG) << "Force update"; ret=FORCE_UPDATE; } @@ -1995,7 +1994,7 @@ int slsReceiverTCPIPInterface::enable_file_write(){ #endif if(ret==OK && socket->differentClients){ - cout << "Force update" << endl; + FILE_LOG(logDEBUG) << "Force update"; ret=FORCE_UPDATE; } @@ -2023,7 +2022,7 @@ int slsReceiverTCPIPInterface::get_id(){ #endif if(socket->differentClients){ - cout << "Force update" << endl; + FILE_LOG(logDEBUG) << "Force update"; ret=FORCE_UPDATE; } @@ -2066,7 +2065,7 @@ int slsReceiverTCPIPInterface::start_readout(){ #endif if(ret==OK && socket->differentClients){ - cout << "Force update" << endl; + FILE_LOG(logDEBUG) << "Force update"; ret=FORCE_UPDATE; } @@ -2140,7 +2139,7 @@ int slsReceiverTCPIPInterface::set_timer() { #endif if(ret==OK && socket->differentClients){ - cout << "Force update" << endl; + FILE_LOG(logDEBUG) << "Force update"; ret=FORCE_UPDATE; } @@ -2211,7 +2210,7 @@ int slsReceiverTCPIPInterface::enable_compression() { #endif if(ret==OK && socket->differentClients){ - cout << "Force update" << endl; + FILE_LOG(logDEBUG) << "Force update"; ret=FORCE_UPDATE; } @@ -2272,7 +2271,7 @@ int slsReceiverTCPIPInterface::set_detector_hostname() { #endif if(ret==OK && socket->differentClients){ - cout << "Force update" << endl; + FILE_LOG(logDEBUG) << "Force update"; ret=FORCE_UPDATE; } @@ -2364,7 +2363,7 @@ int slsReceiverTCPIPInterface::set_dynamic_range() { #endif if(ret==OK && socket->differentClients){ - cout << "Force update" << endl; + FILE_LOG(logDEBUG) << "Force update"; ret=FORCE_UPDATE; } @@ -2427,7 +2426,7 @@ int slsReceiverTCPIPInterface::enable_overwrite() { #endif if(ret==OK && socket->differentClients){ - cout << "Force update" << endl; + FILE_LOG(logDEBUG) << "Force update"; ret=FORCE_UPDATE; } @@ -2492,7 +2491,7 @@ int slsReceiverTCPIPInterface::enable_tengiga() { #endif if(ret==OK && socket->differentClients){ - cout << "Force update" << endl; + FILE_LOG(logDEBUG) << "Force update"; ret=FORCE_UPDATE; } From 4c85a27f10a207a21cfd5fdb04d468c4170882eb Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Thu, 29 Oct 2015 17:34:19 +0100 Subject: [PATCH 163/474] done --- .../src/UDPBaseImplementation.cpp | 2 +- .../src/UDPStandardImplementation.cpp | 42 ++++++++++--------- 2 files changed, 23 insertions(+), 21 deletions(-) diff --git a/slsReceiverSoftware/src/UDPBaseImplementation.cpp b/slsReceiverSoftware/src/UDPBaseImplementation.cpp index eaac8c8e9..606208521 100644 --- a/slsReceiverSoftware/src/UDPBaseImplementation.cpp +++ b/slsReceiverSoftware/src/UDPBaseImplementation.cpp @@ -299,7 +299,7 @@ void UDPBaseImplementation::setEthernetInterface(const char* c){ FILE_LOG(logDEBUG) << __AT__ << " starting"; strcpy(eth, c); - FILE_LOG(logINFO) << "Ethernet Interface:" << eth; + FILE_LOG(logINFO) << "Ethernet Interface: " << eth; } diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 346d6db9f..cf8779e75 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -763,7 +763,7 @@ void UDPStandardImplementation::resetAcquisitionCount(){ int UDPStandardImplementation::startReceiver(char *c){ FILE_LOG(logDEBUG1) << __AT__ << " called"; - FILE_LOG(logINFO) << "Starting Receiver"; + cout << "Starting Receiver" << endl; //RESET @@ -849,8 +849,8 @@ int UDPStandardImplementation::startReceiver(char *c){ for(int i=0; i < numberofWriterThreads; i++) sem_post(&writerSemaphore[i]); //usleep(5000000); - FILE_LOG(logINFO) << "Receiver Started"; - FILE_LOG(logINFO) << "Status:" << runStatusType(status); + cout << "Receiver Started" << endl; + cout << "Status:" << runStatusType(status) << endl; return OK; } @@ -863,7 +863,7 @@ int UDPStandardImplementation::startReceiver(char *c){ void UDPStandardImplementation::stopReceiver(){ FILE_LOG(logDEBUG1) << __AT__ << " called"; - FILE_LOG(logINFO) << "Stopping Receiver"; + cout << "Stopping Receiver" << endl; //set status to transmitting startReadout(); @@ -882,8 +882,8 @@ void UDPStandardImplementation::stopReceiver(){ status = IDLE; pthread_mutex_unlock(&(statusMutex)); - FILE_LOG(logINFO) << "Receiver Stopped"; - FILE_LOG(logINFO) << "Status:" << runStatusType(status); + cout << "Receiver Stopped" << endl; + cout << "Status:" << runStatusType(status) << endl; cout << endl; } @@ -931,7 +931,7 @@ void UDPStandardImplementation::startReadout(){ pthread_mutex_lock(&statusMutex); status = TRANSMITTING; pthread_mutex_unlock(&statusMutex); - FILE_LOG(logINFO) << "Status: Transmitting"; + cout << "Status: Transmitting" << endl; } //shut down udp sockets and make listeners push dummy (end) packets for writers @@ -1025,12 +1025,12 @@ void UDPStandardImplementation::closeFile(int i){ if(myFile[i]->Write()) //->Write(tall->GetName(),TObject::kOverwrite); - FILE_LOG(logINFO) << "Thread " << i <<": wrote frames to file"; + cout << "Thread " << i <<": wrote frames to file" << endl; else - FILE_LOG(logINFO) << "Thread " << i << ": could not write frames to file"; + cout << "Thread " << i << ": could not write frames to file" << endl; }else - FILE_LOG(logINFO) << "Thread " << i << ": could not write frames to file: No file or No Tree"; + cout << "Thread " << i << ": could not write frames to file: No file or No Tree" << endl; //close file if(myTree[i] && myFile[i]) myFile[i] = myTree[i]->GetCurrentFile(); @@ -1145,8 +1145,8 @@ int UDPStandardImplementation::createWriterThreads(bool destroy){ while(!threadStarted); FILE_LOG(logDEBUG) << "." << flush; } -#ifdef VERBOSE - FILE_LOG(logINFO) << "\nWriter thread(s) created successfully."; +#ifdef DEBUG + cout << "\nWriter thread(s) created successfully" << endl; #endif } @@ -1219,7 +1219,7 @@ int UDPStandardImplementation::createUDPSockets(){ } //normal socket else{ - FILE_LOG(logINFO) << "eth:" << eth << endl; + FILE_LOG(logINFO) << "Ethernet Interface:" << eth; for(int i=0;igetErrorStatus(); if(!iret){ - FILE_LOG(logINFO) << "UDP port opened at port " << port[i]; + cout << "UDP port opened at port " << port[i] << endl; }else{ FILE_LOG(logERROR) << "Could not create UDP socket on port " << port[i] << " error: " << iret; shutDownUDPSockets(); @@ -1238,7 +1238,7 @@ int UDPStandardImplementation::createUDPSockets(){ } FILE_LOG(logDEBUG) << "UDP socket(s) created successfully."; - FILE_LOG(logINFO) << "Listener Ready ..."; + cout << "Listener Ready ..." << endl; return OK; } @@ -1287,7 +1287,7 @@ int UDPStandardImplementation::setupWriter(){ } FILE_LOG(logDEBUG) << "Successfully created file(s)"; - FILE_LOG(logINFO) << "Writer Ready ..."; + cout << "Writer Ready ..." << endl; return fileCreateSuccess; } @@ -1338,9 +1338,9 @@ int UDPStandardImplementation::createNewFile(){ //Print packet loss and filenames if(!packetsCaught){ previousFrameNumber = -1; - FILE_LOG(logINFO) << "File: " << completeFileName; + cout << "File: " << completeFileName << endl; }else{ - FILE_LOG(logINFO) << completeFileName + cout << completeFileName << "\tPacket Loss: " << setw(4)< Date: Thu, 29 Oct 2015 17:38:31 +0100 Subject: [PATCH 164/474] done --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index cf8779e75..a55c3098a 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -850,7 +850,7 @@ int UDPStandardImplementation::startReceiver(char *c){ //usleep(5000000); cout << "Receiver Started" << endl; - cout << "Status:" << runStatusType(status) << endl; + cout << "Status: " << runStatusType(status) << endl; return OK; } @@ -883,7 +883,7 @@ void UDPStandardImplementation::stopReceiver(){ pthread_mutex_unlock(&(statusMutex)); cout << "Receiver Stopped" << endl; - cout << "Status:" << runStatusType(status) << endl; + cout << "Status: " << runStatusType(status) << endl; cout << endl; } @@ -1579,7 +1579,7 @@ void UDPStandardImplementation::stopListening(int ithread, int numbytes){ FILE_LOG(logDEBUG1) << __AT__ << " called"; #ifdef DEBUG4 - cprintf(BLUE,"Listening_Thread %d: Stop Listening\nStatus:%s\n", ithread, runStatusType(status).c_str()); + cprintf(BLUE,"Listening_Thread %d: Stop Listening\nStatus: %s\n", ithread, runStatusType(status).c_str()); #endif //less than 1 packet size (especially for eiger), ignore the buffer (so that 2 dummy buffers are not sent with pc=0) From 1c9d01ea1c01a72ee7b6e399d0bdb3f0203eb2e1 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Thu, 29 Oct 2015 17:39:47 +0100 Subject: [PATCH 165/474] done --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index a55c3098a..fffb38e87 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -884,7 +884,7 @@ void UDPStandardImplementation::stopReceiver(){ cout << "Receiver Stopped" << endl; cout << "Status: " << runStatusType(status) << endl; - cout << endl; + cout << endl << endl; } From 5c5e2edbf96d814d5740d441e73399aee8729260 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Thu, 29 Oct 2015 17:45:24 +0100 Subject: [PATCH 166/474] done --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index fffb38e87..fee4a16c0 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -2281,10 +2281,10 @@ void UDPStandardImplementation::stopWriting(int ithread, char* wbuffer[]){ //statistics cprintf(GREEN, "Status: Run Finished\n"); - if((long long int)(totalPacketsCaught/packetsPerFrame) == 0){ + if(numTotMissingPackets){ cprintf(RED, "Total Missing Packets padded: %d\n",numTotMissingPackets); cprintf(RED, "Total Packets Caught: %lld\n",(long long int)totalPacketsCaught); - cprintf(RED, "Total Frames Caught: 0\n"); + cprintf(RED, "Total Frames Caught: %lld\n",(long long int)(totalPacketsCaught/packetsPerFrame)); }else{ cprintf(GREEN, "Total Missing Packets padded: %d\n",numTotMissingPackets); cprintf(GREEN, "Total Packets Caught:%lld\n", (long long int)totalPacketsCaught); From f77b78b5c6a3c8615781641978ee75a9df7057cf Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Mon, 2 Nov 2015 15:55:15 +0100 Subject: [PATCH 167/474] changes to compile server in defs file --- slsReceiverSoftware/include/sls_receiver_defs.h | 5 ++++- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 5 +++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/slsReceiverSoftware/include/sls_receiver_defs.h b/slsReceiverSoftware/include/sls_receiver_defs.h index 04f647f0a..07566ab84 100755 --- a/slsReceiverSoftware/include/sls_receiver_defs.h +++ b/slsReceiverSoftware/include/sls_receiver_defs.h @@ -8,7 +8,9 @@ #endif #include +#ifdef __cplusplus #include +#endif #include "ansi.h" @@ -112,7 +114,7 @@ public: RUNNING /**< acquisition running, no data in memory */ }; - +#ifdef __cplusplus /** returns string from enabled/disabled \param b true or false \returns string enabled, disabled @@ -172,6 +174,7 @@ public: default: return std::string("idle"); \ }}; +#endif #ifdef __cplusplus protected: diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index fee4a16c0..2bafb96b1 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -43,10 +43,11 @@ UDPStandardImplementation::UDPStandardImplementation(){ //to increase socket receiver buffer size and max length of input queue by changing kernel settings if(myDetectorType == EIGER); - else if(system("echo $((100*1024*1024)) > /proc/sys/net/core/rmem_max")) + else if(system("echo $((100*1024*1024)) > /proc/sys/net/core/rmem_max")){ FILE_LOG(logDEBUG) << "Warning: No root permission to change socket receiver buffer size in file /proc/sys/net/core/rmem_max"; - else if(system("echo 250000 > /proc/sys/net/core/netdev_max_backlog")) + }else if(system("echo 250000 > /proc/sys/net/core/netdev_max_backlog")){ FILE_LOG(logDEBUG) << "Warning: No root permission to change max length of input queue in file /proc/sys/net/core/netdev_max_backlog"; + } /** permanent setting by heiner net.core.rmem_max = 104857600 # 100MiB net.core.netdev_max_backlog = 250000 From e9f51e2ef59dd2b231c0a38952c4b30adf0c6349 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Mon, 2 Nov 2015 17:33:10 +0100 Subject: [PATCH 168/474] put in the changes by Andrea to make it as static and remove as many destructors bugs --- .../include/slsReceiverTCPIPInterface.h | 3 -- .../include/slsReceiverUsers.h | 4 +- .../src/UDPStandardImplementation.cpp | 9 ++-- slsReceiverSoftware/src/main.cpp | 38 +++++++++-------- slsReceiverSoftware/src/slsReceiver.cpp | 6 ++- .../src/slsReceiverTCPIPInterface.cpp | 42 ++----------------- slsReceiverSoftware/src/slsReceiverUsers.cpp | 20 ++++----- 7 files changed, 46 insertions(+), 76 deletions(-) diff --git a/slsReceiverSoftware/include/slsReceiverTCPIPInterface.h b/slsReceiverSoftware/include/slsReceiverTCPIPInterface.h index 83d9416aa..49e5134f1 100644 --- a/slsReceiverSoftware/include/slsReceiverTCPIPInterface.h +++ b/slsReceiverSoftware/include/slsReceiverTCPIPInterface.h @@ -54,9 +54,6 @@ class slsReceiverTCPIPInterface : private virtual slsReceiverDefs { /** Close all threaded Files and exit */ void closeFile(int p); - /** Static function to call closeFile */ - static void staticCloseFile(int p); - /** gets version */ int64_t getReceiverVersion(); diff --git a/slsReceiverSoftware/include/slsReceiverUsers.h b/slsReceiverSoftware/include/slsReceiverUsers.h index 50d6f38fe..eea403560 100644 --- a/slsReceiverSoftware/include/slsReceiverUsers.h +++ b/slsReceiverSoftware/include/slsReceiverUsers.h @@ -83,8 +83,8 @@ public: void registerCallBackRawDataReady(void (*func)(int framenumber, char* datapointer, int datasize, FILE* filedescriptor, char* guidatapointer, void*),void *arg); - // made static to close thread files with ctrl+c - static slsReceiver* receiver; + //receiver object + slsReceiver* receiver; }; diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 2bafb96b1..6149f0c10 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -60,7 +60,7 @@ UDPStandardImplementation::UDPStandardImplementation(){ UDPStandardImplementation::~UDPStandardImplementation(){ FILE_LOG(logDEBUG1) << __AT__ << " called"; - + closeFile(); deleteMembers(); } @@ -1184,9 +1184,9 @@ void UDPStandardImplementation::setThreadPriorities(){ if (pthread_setschedparam(pthread_self(),5 , &tcp_param) == EPERM) rights = false; - if(!rights) + if(!rights){ FILE_LOG(logWARNING) << "No root permission to prioritize threads."; - + } } @@ -1256,8 +1256,9 @@ int UDPStandardImplementation::setupWriter(){ if(cbAction < DO_EVERYTHING){ FILE_LOG(logINFO) << "Call back activated. Data saving must be taken care of by user in call back."; - if (rawDataReadyCallBack) + if (rawDataReadyCallBack){ FILE_LOG(logINFO) << "Data Write has been defined externally"; + } }else if(!fileWriteEnable) FILE_LOG(logINFO) << "Data will not be saved"; diff --git a/slsReceiverSoftware/src/main.cpp b/slsReceiverSoftware/src/main.cpp index 53a8bd110..1dc9a65c6 100644 --- a/slsReceiverSoftware/src/main.cpp +++ b/slsReceiverSoftware/src/main.cpp @@ -6,25 +6,38 @@ #include #include +#include //SIGINT #include "utilities.h" #include "logger.h" - using namespace std; +slsReceiverUsers *receiver; + +void deleteReceiver(slsReceiverUsers* r){ + if(r){delete r;r=0;} +} + +void closeFile(int p){ + deleteReceiver(receiver); +} int main(int argc, char *argv[]) { + + //Catch signal SIGINT to close files properly + signal(SIGINT,closeFile); + int ret = slsReceiverDefs::OK; + receiver = new slsReceiverUsers(argc, argv, ret); - slsReceiverUsers *user = new slsReceiverUsers(argc, argv, ret); - - if(ret==slsReceiverDefs::FAIL) + if(ret==slsReceiverDefs::FAIL){ + deleteReceiver(receiver); return -1; + } //register callbacks - /** callback arguments are filepath @@ -37,10 +50,8 @@ int main(int argc, char *argv[]) { 1 callback writes file, we have to open, close it 2 we open, close, write file, callback does not do anything - registerCallBackStartAcquisition(int (*func)(char*, char*,int, int, void*),void *arg); */ - //receiver->registerCallBackStartAcquisition(func,arg); @@ -49,32 +60,25 @@ int main(int argc, char *argv[]) { total farmes caught registerCallBackAcquisitionFinished(void (*func)(int, void*),void *arg); */ - - //receiver->registerCallBackAcquisitionFinished(func,arg); - /** args to raw data ready callback are framenum datapointer file descriptor guidatapointer (NULL, no data required) - NEVER DELETE THE DATA POINTER REMEMBER THAT THE CALLBACK IS BLOCKING - registerCallBackRawDataReady(void (*func)(int, char*, FILE*, char*, void*),void *arg); - */ - //receiver->registerCallBackRawDataReady(func,arg); //start tcp server thread - if(user->start() == slsReceiverDefs::OK){ + if(receiver->start() == slsReceiverDefs::OK){ FILE_LOG(logDEBUG1) << "DONE!" << endl; string str; cin>>str; @@ -82,10 +86,10 @@ int main(int argc, char *argv[]) { while(str.find("exit") == string::npos) cin>>str; //stop tcp server thread, stop udp socket - user->stop(); + receiver->stop(); } - delete user; + deleteReceiver(receiver); cout << "Goodbye!" << endl; return 0; } diff --git a/slsReceiverSoftware/src/slsReceiver.cpp b/slsReceiverSoftware/src/slsReceiver.cpp index 5783e601c..f23da65c5 100644 --- a/slsReceiverSoftware/src/slsReceiver.cpp +++ b/slsReceiverSoftware/src/slsReceiver.cpp @@ -29,6 +29,9 @@ slsReceiver::slsReceiver(int argc, char *argv[], int &success){ * @return */ + udp_interface = NULL; + tcpipInterface = NULL; + //creating base receiver map configuration_map; int tcpip_port_no = 1954; @@ -55,7 +58,8 @@ slsReceiver::slsReceiver(int argc, char *argv[], int &success){ }; /* getopt_long stores the option index here. */ int option_index = 0; - int c; + int c=0; + optind = 1; while ( c != -1 ){ c = getopt_long (argc, argv, "mbfhtr", long_options, &option_index); diff --git a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp index d7e562f76..24ba62d99 100644 --- a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp +++ b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp @@ -9,10 +9,7 @@ #include "slsReceiverUsers.h" #include "slsReceiver.h" - -#include //SIGINT #include //EXIT - #include #include #include @@ -27,9 +24,8 @@ using namespace std; slsReceiverTCPIPInterface::~slsReceiverTCPIPInterface() { - closeFile(0); + stop(); if(socket) {delete socket; socket=NULL;} - if(receiverBase) {delete receiverBase; receiverBase=NULL;} } slsReceiverTCPIPInterface::slsReceiverTCPIPInterface(int &success, UDPInterface* rbase, int pn, bool bot): @@ -71,9 +67,6 @@ slsReceiverTCPIPInterface::slsReceiverTCPIPInterface(int &success, UDPInterface* #ifdef VERBOSE cout << "Function table assigned." << endl; #endif - - //Catch signal SIGINT to close files properly - signal(SIGINT,staticCloseFile); } } @@ -139,34 +132,13 @@ int slsReceiverTCPIPInterface::start(){ void slsReceiverTCPIPInterface::stop(){ - cout << "Shutting down UDP Socket" << endl; - if(receiverBase) - receiverBase->shutDownUDPSockets(); - - cout << "Closing Files... " << endl; - receiverBase->closeFile(); - - - cout<<"Shutting down TCP Socket and TCP thread"<shutDownUDPSockets(); - - cout << "Closing Files... " << endl; - receiverBase->closeFile(); - } - - killTCPServerThread = 1; - socket->ShutDownSocket(); - socket->exitServer(); + if(socket) socket->ShutDownSocket(); cout<<"Socket closed"<closeFile(p); + receiverBase->closeFile(); } diff --git a/slsReceiverSoftware/src/slsReceiverUsers.cpp b/slsReceiverSoftware/src/slsReceiverUsers.cpp index c27f1efc2..8a1d17f43 100644 --- a/slsReceiverSoftware/src/slsReceiverUsers.cpp +++ b/slsReceiverSoftware/src/slsReceiverUsers.cpp @@ -1,47 +1,45 @@ #include "slsReceiverUsers.h" #include "slsReceiver.h" -slsReceiver* slsReceiverUsers::receiver(NULL); - slsReceiverUsers::slsReceiverUsers(int argc, char *argv[], int &success) { - slsReceiverUsers::receiver=new slsReceiver(argc, argv, success); + receiver=new slsReceiver(argc, argv, success); } slsReceiverUsers::~slsReceiverUsers() { - delete slsReceiverUsers::receiver; + delete receiver; } int slsReceiverUsers::start() { - return slsReceiverUsers::receiver->start(); + return receiver->start(); } void slsReceiverUsers::stop() { - slsReceiverUsers::receiver->stop(); + receiver->stop(); } void slsReceiverUsers::closeFile(int p) { - slsReceiverUsers::receiver->closeFile(p); + receiver->closeFile(p); } int64_t slsReceiverUsers::getReceiverVersion(){ - return slsReceiverUsers::receiver->getReceiverVersion(); + return receiver->getReceiverVersion(); } void slsReceiverUsers::registerCallBackStartAcquisition(int (*func)(char*, char*,int, int, void*),void *arg){ - slsReceiverUsers::receiver->registerCallBackStartAcquisition(func,arg); + receiver->registerCallBackStartAcquisition(func,arg); } void slsReceiverUsers::registerCallBackAcquisitionFinished(void (*func)(int, void*),void *arg){ - slsReceiverUsers::receiver->registerCallBackAcquisitionFinished(func,arg); + receiver->registerCallBackAcquisitionFinished(func,arg); } void slsReceiverUsers::registerCallBackRawDataReady(void (*func)(int, char*, int, FILE*, char*, void*),void *arg){ - slsReceiverUsers::receiver->registerCallBackRawDataReady(func,arg); + receiver->registerCallBackRawDataReady(func,arg); } From 667c1c0304aa284f432274405e8470ac2eb2bb9a Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Thu, 5 Nov 2015 12:05:31 +0100 Subject: [PATCH 169/474] some small changes --- .../src/UDPStandardImplementation.cpp | 115 ++++++++++-------- .../src/slsReceiverTCPIPInterface.cpp | 68 +++++------ 2 files changed, 98 insertions(+), 85 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 6149f0c10..86e533efa 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -31,7 +31,7 @@ using namespace std; *************************************************************************/ UDPStandardImplementation::UDPStandardImplementation(){ - FILE_LOG(logDEBUG1) << __AT__ << " called"; + FILE_LOG(logDEBUG) << __AT__ << " called"; initializeMembers(); @@ -59,7 +59,7 @@ UDPStandardImplementation::UDPStandardImplementation(){ } UDPStandardImplementation::~UDPStandardImplementation(){ - FILE_LOG(logDEBUG1) << __AT__ << " called"; + FILE_LOG(logDEBUG) << __AT__ << " called"; closeFile(); deleteMembers(); } @@ -73,7 +73,7 @@ UDPStandardImplementation::~UDPStandardImplementation(){ /***initial parameters***/ void UDPStandardImplementation::deleteMembers(){ - FILE_LOG(logDEBUG1) << __AT__ << " starting"; + FILE_LOG(logDEBUG) << __AT__ << " starting"; FILE_LOG(logDEBUG) << "Info: Deleting member pointers"; shutDownUDPSockets(); @@ -95,7 +95,7 @@ void UDPStandardImplementation::deleteMembers(){ } void UDPStandardImplementation::deleteFilter(){ - FILE_LOG(logDEBUG1) << __AT__ << " starting"; + FILE_LOG(logDEBUG) << __AT__ << " starting"; moenchCommonModeSubtraction = NULL; for(int i=0; i config_map){ - FILE_LOG(logDEBUG1) << __AT__ << " starting"; + FILE_LOG(logDEBUG) << __AT__ << " starting"; map::const_iterator pos; pos = config_map.find("mode"); @@ -375,7 +375,7 @@ void UDPStandardImplementation::configure(map config_map){ /***file parameters***/ int UDPStandardImplementation::setDataCompressionEnable(const bool b){ - FILE_LOG(logDEBUG1) << __AT__ << " starting"; + FILE_LOG(logDEBUG) << __AT__ << " starting"; if(myDetectorType != EIGER){ cout << "Info: Setting up Data Compression Enable to " << stringEnable(b); @@ -419,7 +419,7 @@ int UDPStandardImplementation::setDataCompressionEnable(const bool b){ /***acquisition parameters***/ void UDPStandardImplementation::setShortFrameEnable(const int i){ - FILE_LOG(logDEBUG1) << __AT__ << " called"; + FILE_LOG(logDEBUG) << __AT__ << " called"; shortFrameEnable = i; @@ -456,7 +456,7 @@ void UDPStandardImplementation::setShortFrameEnable(const int i){ int UDPStandardImplementation::setFrameToGuiFrequency(const uint32_t i){ - FILE_LOG(logDEBUG1) << __AT__ << " called"; + FILE_LOG(logDEBUG) << __AT__ << " called"; FrameToGuiFrequency = i; if(setupFifoStructure() == FAIL) @@ -469,7 +469,7 @@ int UDPStandardImplementation::setFrameToGuiFrequency(const uint32_t i){ int UDPStandardImplementation::setAcquisitionPeriod(const uint64_t i){ - FILE_LOG(logDEBUG1) << __AT__ << " called"; + FILE_LOG(logDEBUG) << __AT__ << " called"; acquisitionPeriod = i; if(setupFifoStructure() == FAIL) @@ -482,7 +482,7 @@ int UDPStandardImplementation::setAcquisitionPeriod(const uint64_t i){ } int UDPStandardImplementation::setDynamicRange(const uint32_t i){ - FILE_LOG(logDEBUG1) << __AT__ << " called"; + FILE_LOG(logDEBUG) << __AT__ << " called"; uint32_t oldDynamicRange = dynamicRange; @@ -536,7 +536,7 @@ int UDPStandardImplementation::setDynamicRange(const uint32_t i){ int UDPStandardImplementation::setTenGigaEnable(const bool b){ - FILE_LOG(logDEBUG1) << __AT__ << " called"; + FILE_LOG(logDEBUG) << __AT__ << " called"; FILE_LOG(logDEBUG) << "Info: Setting Ten Giga to " << stringEnable(b); bool oldTenGigaEnable = tengigaEnable; @@ -618,7 +618,7 @@ int UDPStandardImplementation::setTenGigaEnable(const bool b){ /***initial functions***/ int UDPStandardImplementation::setDetectorType(const detectorType d){ - FILE_LOG(logDEBUG1) << __AT__ << " called"; + FILE_LOG(logDEBUG) << __AT__ << " called"; FILE_LOG(logDEBUG) << "Setting receiver type"; @@ -751,7 +751,7 @@ int UDPStandardImplementation::setDetectorType(const detectorType d){ /***acquisition functions***/ void UDPStandardImplementation::resetAcquisitionCount(){ - FILE_LOG(logDEBUG1) << __AT__ << " starting"; + FILE_LOG(logDEBUG) << __AT__ << " starting"; totalPacketsCaught = 0; acqStarted = false; @@ -762,7 +762,7 @@ void UDPStandardImplementation::resetAcquisitionCount(){ int UDPStandardImplementation::startReceiver(char *c){ - FILE_LOG(logDEBUG1) << __AT__ << " called"; + FILE_LOG(logDEBUG) << __AT__ << " called"; cout << "Starting Receiver" << endl; @@ -862,7 +862,7 @@ int UDPStandardImplementation::startReceiver(char *c){ * Post: udp sockets shut down, status is idle, semaphores destroyed * */ void UDPStandardImplementation::stopReceiver(){ - FILE_LOG(logDEBUG1) << __AT__ << " called"; + FILE_LOG(logDEBUG) << __AT__ << " called"; cout << "Stopping Receiver" << endl; @@ -893,7 +893,7 @@ void UDPStandardImplementation::stopReceiver(){ int UDPStandardImplementation::shutDownUDPSockets(){ - FILE_LOG(logDEBUG1) << __AT__ << " called"; + FILE_LOG(logDEBUG) << __AT__ << " called"; FILE_LOG(logDEBUG) << "Info: Shutting down UDP Socket(s)"; @@ -915,7 +915,7 @@ int UDPStandardImplementation::shutDownUDPSockets(){ * Post:udp sockets closed, status is transmitting * */ void UDPStandardImplementation::startReadout(){ - FILE_LOG(logDEBUG1) << __AT__ << " called"; + FILE_LOG(logDEBUG) << __AT__ << " called"; FILE_LOG(logDEBUG) << "Info: Transmitting last data"; @@ -943,7 +943,7 @@ void UDPStandardImplementation::startReadout(){ void UDPStandardImplementation::readFrame(char* c,char** raw, uint64_t &startAcq, uint64_t &startFrame){ - FILE_LOG(logDEBUG1) << __AT__ << " called"; + FILE_LOG(logDEBUG) << __AT__ << " called"; //point to gui data, to let writer thread know that gui is back for data if (guiData == NULL){ @@ -993,7 +993,7 @@ void UDPStandardImplementation::readFrame(char* c,char** raw, uint64_t &startAcq void UDPStandardImplementation::closeFile(int i){ - FILE_LOG(logDEBUG1) << __AT__ << " called for " << i ; + FILE_LOG(logDEBUG) << __AT__ << " called for " << i ; //normal if(!dataCompressionEnable){ @@ -1054,7 +1054,7 @@ void UDPStandardImplementation::closeFile(int i){ int UDPStandardImplementation::createListeningThreads(bool destroy){ - FILE_LOG(logDEBUG1) << __AT__ << " starting"; + FILE_LOG(logDEBUG) << __AT__ << " starting"; //reset masks killAllListeningThreads = false; @@ -1104,7 +1104,7 @@ int UDPStandardImplementation::createListeningThreads(bool destroy){ int UDPStandardImplementation::createWriterThreads(bool destroy){ - FILE_LOG(logDEBUG1) << __AT__ << " starting"; + FILE_LOG(logDEBUG) << __AT__ << " starting"; //reset masks killAllWritingThreads = false; @@ -1157,7 +1157,7 @@ int UDPStandardImplementation::createWriterThreads(bool destroy){ void UDPStandardImplementation::setThreadPriorities(){ - FILE_LOG(logDEBUG1) << __AT__ << " called"; + FILE_LOG(logDEBUG) << __AT__ << " called"; struct sched_param tcp_param, listen_param, write_param; bool rights = true; @@ -1193,7 +1193,7 @@ void UDPStandardImplementation::setThreadPriorities(){ int UDPStandardImplementation::createUDPSockets(){ - FILE_LOG(logDEBUG1) << __AT__ << " called"; + FILE_LOG(logDEBUG) << __AT__ << " called"; //switching ports if bottom enabled uint32_t port[2]; @@ -1247,7 +1247,7 @@ int UDPStandardImplementation::createUDPSockets(){ int UDPStandardImplementation::setupWriter(){ - FILE_LOG(logDEBUG1) << __AT__ << " starting"; + FILE_LOG(logDEBUG) << __AT__ << " starting"; //acquisition start call back returns enable write cbAction = DO_EVERYTHING; @@ -1297,7 +1297,7 @@ int UDPStandardImplementation::setupWriter(){ int UDPStandardImplementation::createNewFile(){ - FILE_LOG(logDEBUG1) << __AT__ << " called"; + FILE_LOG(logDEBUG) << __AT__ << " called"; int index = 0; if(packetsCaught) @@ -1370,7 +1370,7 @@ int UDPStandardImplementation::createNewFile(){ int UDPStandardImplementation::createCompressionFile(int ithread, int iframe){ - FILE_LOG(logDEBUG1) << __AT__ << " called"; + FILE_LOG(logDEBUG) << __AT__ << " called"; #ifdef MYROOT1 char temp[MAX_STR_LENGTH]; @@ -1400,7 +1400,7 @@ int UDPStandardImplementation::createCompressionFile(int ithread, int iframe){ void* UDPStandardImplementation::startListeningThread(void* this_pointer){ - FILE_LOG(logDEBUG1) << __AT__ << " called"; + FILE_LOG(logDEBUG) << __AT__ << " called"; ((UDPStandardImplementation*)this_pointer)->startListening(); return this_pointer; } @@ -1408,7 +1408,7 @@ void* UDPStandardImplementation::startListeningThread(void* this_pointer){ void* UDPStandardImplementation::startWritingThread(void* this_pointer){ - FILE_LOG(logDEBUG1) << __AT__ << " called"; + FILE_LOG(logDEBUG) << __AT__ << " called"; ((UDPStandardImplementation*)this_pointer)->startWriting(); return this_pointer; } @@ -1419,7 +1419,7 @@ void* UDPStandardImplementation::startWritingThread(void* this_pointer){ void UDPStandardImplementation::startListening(){ - FILE_LOG(logDEBUG1) << __AT__ << " called"; + FILE_LOG(logDEBUG) << __AT__ << " called"; //set current thread value index int ithread = currentThreadIndex; @@ -1433,16 +1433,18 @@ void UDPStandardImplementation::startListening(){ //split frames int carryonBufferSize; //from previous buffer to keep frames together in a buffer char* tempBuffer = NULL; //temporary buffer to store split frames - if(myDetectorType != EIGER){ - listenSize = bufferSize * numberofJobsPerBuffer; //listen to more than 1 packet - tempBuffer = new char[onePacketSize * (packetsPerFrame - 1)]; //store maximum of 1 packets less in a frame - } + /* outer loop - loops once for each acquisition */ //infinite loop, exited only to change dynamic range, 10G parameters etc (then recreated again) while(true){ //reset parameters before acquisition carryonBufferSize = 0; + if(myDetectorType != EIGER){ + listenSize = bufferSize * numberofJobsPerBuffer; //listen to more than 1 packet + if(tempBuffer!=NULL){delete []tempBuffer;tempBuffer=NULL;} + tempBuffer = new char[onePacketSize * (packetsPerFrame - 1)]; //store maximum of 1 packets less in a frame + } /* inner loop - loop for each buffer */ //until mask unset (udp sockets shut down by client) @@ -1512,7 +1514,7 @@ void UDPStandardImplementation::startListening(){ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int lSize, int cSize, char* temp){ - FILE_LOG(logDEBUG1) << __AT__ << " called"; + FILE_LOG(logDEBUG) << __AT__ << " called"; //listen to UDP packets memcpy(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS, temp, cSize); @@ -1529,6 +1531,17 @@ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int lSize, in receivedSize = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS); } +#ifdef MANUALDEBUG + eiger_packet_header_t* header = (eiger_packet_header_t*) (buffer[ithread]+HEADER_SIZE_NUM_TOT_PACKETS); + eiger_packet_footer_t* footer = (eiger_packet_footer_t*)(buffer[ithread] + footerOffset + HEADER_SIZE_NUM_TOT_PACKETS); + cprintf(GREEN,"thread:%d subframenum:%d oldpacketnum:%d new pnum:%d\n", + ithread, + (*( (unsigned int*) header->subFameNumber)), + (*( (uint8_t*) header->dynamicRange)), + (*( (uint16_t*) footer->packetNumber))); +#endif + + #ifdef DEBUG cprintf(BLUE, "Listening_Thread %d : Received bytes: %d. Expected bytes: %d\n", ithread, receivedSize, bufferSize * numberofJobsPerBuffer-cSize); #endif @@ -1541,7 +1554,7 @@ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int lSize, in void UDPStandardImplementation::startFrameIndices(int ithread){ - FILE_LOG(logDEBUG1) << __AT__ << " called"; + FILE_LOG(logDEBUG) << __AT__ << " called"; //determine startFrameIndex switch(myDetectorType){ @@ -1578,7 +1591,7 @@ void UDPStandardImplementation::startFrameIndices(int ithread){ void UDPStandardImplementation::stopListening(int ithread, int numbytes){ - FILE_LOG(logDEBUG1) << __AT__ << " called"; + FILE_LOG(logDEBUG) << __AT__ << " called"; #ifdef DEBUG4 cprintf(BLUE,"Listening_Thread %d: Stop Listening\nStatus: %s\n", ithread, runStatusType(status).c_str()); @@ -1657,7 +1670,7 @@ void UDPStandardImplementation::stopListening(int ithread, int numbytes){ uint32_t UDPStandardImplementation::processListeningBuffer(int ithread, int cSize, char* temp){ - FILE_LOG(logDEBUG1) << __AT__ << " called"; + FILE_LOG(logDEBUG) << __AT__ << " called"; int lastPacketOffset; //the offset of the last packet uint32_t lastFrameHeader; //frame number of last packet in buffer @@ -1741,7 +1754,7 @@ uint32_t UDPStandardImplementation::processListeningBuffer(int ithread, int cSiz void UDPStandardImplementation::startWriting(){ - FILE_LOG(logDEBUG1) << __AT__ << " called"; + FILE_LOG(logDEBUG) << __AT__ << " called"; //set current thread value index int ithread = currentThreadIndex; @@ -1762,7 +1775,7 @@ void UDPStandardImplementation::startWriting(){ void UDPStandardImplementation::processWritingBuffer(int ithread){ - FILE_LOG(logDEBUG1) << __AT__ << " called"; + FILE_LOG(logDEBUG) << __AT__ << " called"; //variable definitions char* wbuf[numberofListeningThreads]; //buffer popped from FIFO @@ -1829,7 +1842,7 @@ void UDPStandardImplementation::processWritingBuffer(int ithread){ void UDPStandardImplementation::processWritingBufferPacketByPacket(int ithread){ - FILE_LOG(logDEBUG1) << __AT__ << " called"; + FILE_LOG(logDEBUG) << __AT__ << " called"; //variable definitions char* packetBuffer[numberofListeningThreads]; //buffer popped from FIFO @@ -2133,7 +2146,7 @@ void UDPStandardImplementation::processWritingBufferPacketByPacket(int ithread){ void UDPStandardImplementation::waitWritingBufferForNextAcquisition(int ithread){ - FILE_LOG(logDEBUG1) << __AT__ << " called"; + FILE_LOG(logDEBUG) << __AT__ << " called"; //in case they are not closed already closeFile(); @@ -2190,7 +2203,7 @@ void UDPStandardImplementation::waitWritingBufferForNextAcquisition(int ithread) bool UDPStandardImplementation::popAndCheckEndofAcquisition(int ithread, char* wbuffer[], bool ready[], uint32_t nP[],char* toFree[],int toFreeOffset[]){ - FILE_LOG(logDEBUG1) << __AT__ << " called"; + FILE_LOG(logDEBUG) << __AT__ << " called"; bool endofAcquisition = true; for(int i=0; ithisClientIP,"none1"); strcpy(mess,"dummy message"); function_table(); -#ifdef VERBOSE +#ifdef VERYVERBOSE cout << "Function table assigned." << endl; #endif } @@ -124,7 +124,7 @@ int slsReceiverTCPIPInterface::start(){ cout << "Could not create TCP Server thread" << endl; return FAIL; } - //#ifdef VERBOSE + //#ifdef VERYVERBOSE FILE_LOG(logDEBUG) << "TCP Server thread created successfully." << endl; //#endif return OK; @@ -160,7 +160,7 @@ void slsReceiverTCPIPInterface::startTCPServer(){ int v=OK; while(1) { -#ifdef VERBOSE +#ifdef VERYVERBOSE cout<< endl; #endif #ifdef VERY_VERBOSE @@ -254,7 +254,7 @@ int slsReceiverTCPIPInterface::function_table(){ flist[F_ENABLE_RECEIVER_TEN_GIGA] = &slsReceiverTCPIPInterface::enable_tengiga; -#ifdef VERBOSE +#ifdef VERYVERBOSE for (int i=0;iReceiveDataOnly(&fnum,sizeof(fnum)); if (n <= 0) { -#ifdef VERBOSE +#ifdef VERYVERBOSE cout << "ERROR reading from socket " << n << ", " << fnum << endl; #endif return FAIL; } -#ifdef VERBOSE +#ifdef VERYVERBOSE else cout << "size of data received " << n <> GOTTHARD_SHORT_FRAME_INDEX_OFFSET); -#ifdef VERBOSE +#ifdef VERYVERBOSE cout << "index:" << hex << index << endl; #endif }else{ @@ -1336,7 +1336,7 @@ int slsReceiverTCPIPInterface::gotthard_read_frame(){ bindex2 = ((uint32_t)(*((uint32_t*)((char*)(raw+onebuffersize)))))+1; pindex2 =(bindex2 & GOTTHARD_PACKET_INDEX_MASK); index2 =((bindex2 & GOTTHARD_FRAME_INDEX_MASK) >> GOTTHARD_FRAME_INDEX_OFFSET); -#ifdef VERBOSE +#ifdef VERYVERBOSE cout << "index1:" << hex << index << endl; cout << "index2:" << hex << index << endl; #endif @@ -1398,7 +1398,7 @@ int slsReceiverTCPIPInterface::gotthard_read_frame(){ } } -#ifdef VERBOSE +#ifdef VERYVERBOSE if(frameIndex!=-1){ cout << "fName:" << fName << endl; cout << "acquisitionIndex:" << acquisitionIndex << endl; @@ -1493,7 +1493,7 @@ int slsReceiverTCPIPInterface::propix_read_frame(){ /**send garbage with -1 index to try again*/ if (raw == NULL){ startAcquisitionIndex = -1; -#ifdef VERBOSE +#ifdef VERYVERBOSE cout<<"data not ready for gui yet"<> PROPIX_FRAME_INDEX_OFFSET); -#ifdef VERBOSE +#ifdef VERYVERBOSE cout << "index1:" << hex << index << endl; cout << "index2:" << hex << index << endl; #endif @@ -1552,7 +1552,7 @@ int slsReceiverTCPIPInterface::propix_read_frame(){ } } -#ifdef VERBOSE +#ifdef VERYVERBOSE if(frameIndex!=-1){ cout << "fName:" << fName << endl; cout << "acquisitionIndex:" << acquisitionIndex << endl; @@ -1652,7 +1652,7 @@ int slsReceiverTCPIPInterface::eiger_read_frame(){ /**send garbage with -1 index to try again*/ else if(!receiverBase->getFramesCaught()){ startAcquisitionIndex=-1; -#ifdef VERBOSE +#ifdef VERYVERBOSE cout<<"haven't caught any frame yet"<subframenum); } -#ifdef VERBOSE +#ifdef VERYVERBOSE cout << "index:" << dec << index << endl; cout << "subframenumber:" << dec << subframenumber << endl; #endif @@ -1813,7 +1813,7 @@ int slsReceiverTCPIPInterface::eiger_read_frame(){ } } -#ifdef VERBOSE +#ifdef VERYVERBOSE if(frameIndex!=-1){ cout << "fName:" << fName << endl; cout << "acquisitionIndex:" << acquisitionIndex << endl; @@ -2093,7 +2093,7 @@ int slsReceiverTCPIPInterface::set_timer() { ret = FAIL; } } -#ifdef VERBOSE +#ifdef VERYVERBOSE if(ret!=FAIL){ if(index[0] == FRAME_PERIOD) cout << "acquisition period:" << retval << endl; @@ -2228,7 +2228,7 @@ int slsReceiverTCPIPInterface::set_detector_hostname() { } } } -#ifdef VERBOSE +#ifdef VERYVERBOSE if(ret!=FAIL) cout << "hostname:" << retval << endl; else @@ -2320,7 +2320,7 @@ int slsReceiverTCPIPInterface::set_dynamic_range() { } } } -#ifdef VERBOSE +#ifdef VERYVERBOSE if(ret!=FAIL) cout << "dynamic range" << dr << endl; else @@ -2383,7 +2383,7 @@ int slsReceiverTCPIPInterface::enable_overwrite() { ret = FAIL; } } -#ifdef VERBOSE +#ifdef VERYVERBOSE if(ret!=FAIL) cout << "overwrite:" << retval << endl; else @@ -2448,7 +2448,7 @@ int slsReceiverTCPIPInterface::enable_tengiga() { tenGigaEnable = retval; } } -#ifdef VERBOSE +#ifdef VERYVERBOSE if(ret!=FAIL) cout << "10Gbe:" << val << endl; else @@ -2749,7 +2749,7 @@ int slsReceiverTCPIPInterface::exec_command() { // execute action if the arguments correctly arrived if (ret==OK) { -#ifdef VERBOSE +#ifdef VERYVERBOSE cout << "executing command " << cmd << endl; #endif if (lockStatus==0 || socket->differentClients==0) From 98ab99c53f744a44c7a6417c6f7c5f1f073ef441 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Fri, 6 Nov 2015 11:23:50 +0100 Subject: [PATCH 170/474] fixed a bug of both threads not popping out(due to wrong frame packet) and end of acquisition wrongly inferred --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 86e533efa..12a176777 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -2244,6 +2244,11 @@ bool UDPStandardImplementation::popAndCheckEndofAcquisition(int ithread, char* w } } } + //when both are not popped but curretn frame number is being processed + else{ + if(nP[i] != dummyPacketValue) + endofAcquisition = false; + } } return endofAcquisition; From 455c9c5c8084a5159bfdeac345bd8262d7ef5a50 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Mon, 9 Nov 2015 17:16:24 +0100 Subject: [PATCH 171/474] some changes for memory leak --- .../src/UDPStandardImplementation.cpp | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 12a176777..b12826f16 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1867,8 +1867,6 @@ void UDPStandardImplementation::processWritingBufferPacketByPacket(int ithread){ volatile uint32_t currentPacketNumber[numberofListeningThreads];//current packet number volatile int numberofMissingPackets[numberofListeningThreads]; // number of missing packets in this buffer - eiger_packet_header_t* blankframe_header; - for(int i=0; imissingPacket) = missingPacketValue; //set each value inside blank frame to 0xff for(int j=0;j<(oneDataSize);++j){ - blankframe_data = (unsigned char*)blankframe[i] + sizeof(eiger_packet_header_t) + j; + unsigned char* blankframe_data = (unsigned char*)blankframe[i] + sizeof(eiger_packet_header_t) + j; *(blankframe_data) = 0xFF; } } @@ -1945,12 +1947,11 @@ void UDPStandardImplementation::processWritingBufferPacketByPacket(int ithread){ //not full frame else if(!fullframe[i]){ - eiger_packet_footer_t* packetBuffer_footer = (eiger_packet_footer_t*)(packetBuffer[i] + footerOffset + HEADER_SIZE_NUM_TOT_PACKETS); - - //update frame number and packet number if(numPackets[i] != dummyPacketValue){ + eiger_packet_footer_t* packetBuffer_footer = (eiger_packet_footer_t*)(packetBuffer[i] + footerOffset + HEADER_SIZE_NUM_TOT_PACKETS); + if(!((uint32_t)(*( (uint64_t*) packetBuffer_footer)))){ FILE_LOG(logERROR) << "Fifo "<< i << ": Frame Number is zero from firmware. popready[" << i << "]:" << popReady[i]; popReady[i]=true; @@ -1972,10 +1973,10 @@ void UDPStandardImplementation::processWritingBufferPacketByPacket(int ithread){ if(numPackets[i] == dummyPacketValue) cprintf(GREEN, "Fifo %d: Dummy packet: Adding missing packets to the last frame\n", i); else{ - cprintf(GREEN,"Fifo %d: fnum %d, (FW_fnum %d), pnum %d, last_pnum %d, pnum_offset %d\n" + cprintf(GREEN,"Fifo %d: fnum %d, fnum_thread %d, pnum %d, last_pnum %d, pnum_offset %d\n" "Fifo %d: Add missing packets to the right fnum %d\n", - i,presentFrameNumber[i],(uint32_t)(*( (uint64_t*) packetBuffer_footer)), - *( (uint16_t*) packetBuffer_footer->packetNumber),lastPacketNumber[i],frameBufferoffset[i], + i,presentFrameNumber[i],threadFrameNumber[i], + currentPacketNumber[i],lastPacketNumber[i],frameBufferoffset[i], i,presentFrameNumber); } #endif @@ -1991,7 +1992,7 @@ void UDPStandardImplementation::processWritingBufferPacketByPacket(int ithread){ frameBuffer[frameBufferoffset[i]] = blankframe[blankoffset]; eiger_packet_header_t* frameBuffer_header = (eiger_packet_header_t*) frameBuffer[frameBufferoffset[i]]; if (*( (uint16_t*) frameBuffer_header->missingPacket)!= missingPacketValue){ - blankframe_header = (eiger_packet_header_t*) blankframe[blankoffset]; + eiger_packet_header_t* blankframe_header = (eiger_packet_header_t*) blankframe[blankoffset]; cprintf(BG_RED, "Fifo %d: Missing Packet Error: Adding blank packets mismatch " "pnum_offset %d, pnum %d, fnum_thread %d, missingpacket_buffer 0x%x, missingpacket_blank 0x%x\n", i,frameBufferoffset[i],currentPacketNumber[i],threadFrameNumber[i], @@ -2029,9 +2030,8 @@ void UDPStandardImplementation::processWritingBufferPacketByPacket(int ithread){ else{ if(currentPacketNumber[i] != (uint32_t)(frameBufferoffset[i]-(i*packetsPerFrame/numberofListeningThreads))+1){ cprintf(BG_RED, "Fifo %d: Correct Packet Offset Error:Adding current packet mismatch " - "pnum_offset %d,pnum %d fnum_thread %d, (FW_fnum %d)\n", - i,frameBufferoffset[i],currentPacketNumber[i], - threadFrameNumber[i],(uint32_t)(*( (uint64_t*) packetBuffer_footer))); + "pnum_offset %d,pnum %d fnum_thread %d\n", + i,frameBufferoffset[i],currentPacketNumber[i],threadFrameNumber[i]); exit(-1); } @@ -2066,9 +2066,9 @@ void UDPStandardImplementation::processWritingBufferPacketByPacket(int ithread){ currentFrameNumber = presentFrameNumber; numTotMissingPacketsInFile += numMissingPackets; numTotMissingPackets += numMissingPackets; -#ifdef FNUM_DEBUG - cprintf(GREEN,"**fnum:%d**\n",currframenum); -#endif +//#ifdef FNUM_DEBUG + cprintf(GREEN,"**fnum:%d**\n",currentFrameNumber); +//#endif #ifdef MISSINGP_DEBUG if(numberofMissingPackets[0]) cprintf(RED, "Fifo 0 missing packets %d for fnum %d\n",numberofMissingPackets[0],currentPacketNumber); From 0627668090724e368ddc1889d4fd2f111df8c774 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Wed, 11 Nov 2015 15:08:50 +0100 Subject: [PATCH 172/474] some changes for memory leak --- .../include/UDPStandardImplementation.h | 5 +- slsReceiverSoftware/include/genericSocket.h | 32 ++-- .../src/UDPStandardImplementation.cpp | 163 ++++++++++++------ .../src/slsReceiverTCPIPInterface.cpp | 30 ++-- 4 files changed, 146 insertions(+), 84 deletions(-) diff --git a/slsReceiverSoftware/include/UDPStandardImplementation.h b/slsReceiverSoftware/include/UDPStandardImplementation.h index d478f0e7a..a1cad30e9 100644 --- a/slsReceiverSoftware/include/UDPStandardImplementation.h +++ b/slsReceiverSoftware/include/UDPStandardImplementation.h @@ -379,11 +379,10 @@ private: * @param wbuffer the buffer array that is popped from all the FIFOs * @param ready if that FIFO is allowed to pop (depends on if dummy buffer already popped/ waiting for other FIFO to finish a frame(eiger)) * @param nP number of packets in the buffer popped out - * @param toFree array of addresses to pop into fifoFree (eiger specific) - * @param toFreeOffset the number of addresses to free for each FIFO (eiger specific) + * @param fifoTempFree circular fifo to save addresses of packets adding upto a frame before pushing into fifofree (eiger specific) * @return true if end of acquisition else false */ - bool popAndCheckEndofAcquisition(int ithread, char* wbuffer[], bool ready[], uint32_t nP[],char* toFree[],int toFreeOffset[]); + bool popAndCheckEndofAcquisition(int ithread, char* wbuffer[], bool ready[], uint32_t nP[],CircularFifo* fifoTempFree[]); /** * Called by processWritingBuffer and processWritingBufferPacketByPacket diff --git a/slsReceiverSoftware/include/genericSocket.h b/slsReceiverSoftware/include/genericSocket.h index de49d7860..b1b5e8f62 100644 --- a/slsReceiverSoftware/include/genericSocket.h +++ b/slsReceiverSoftware/include/genericSocket.h @@ -116,6 +116,11 @@ typedef struct // serverAddress = {0}; // clientAddress = {0}; // strcpy(hostname,host_ip_or_name); + + strcpy(lastClientIP,"none"); + strcpy(thisClientIP,"none1"); + strcpy(dummyClientIP,"dummy"); + struct hostent *hostInfo = gethostbyname(host_ip_or_name); if (hostInfo == NULL){ cerr << "Exiting: Problem interpreting host: " << host_ip_or_name << "\n"; @@ -170,16 +175,16 @@ typedef struct nsent(0), total_sent(0) { - //memset(&serverAddress, 0, sizeof(sockaddr_in)); - // memset(&clientAddress, 0, sizeof(sockaddr_in)); - // serverAddress = {0}; - // clientAddress = {0}; -/* // you can specify an IP address: */ -/* */ +/* // you can specify an IP address: */ /* // or you can let it automatically select one: */ /* myaddr.sin_addr.s_addr = INADDR_ANY; */ + + strcpy(lastClientIP,"none"); + strcpy(thisClientIP,"none1"); + strcpy(dummyClientIP,"dummy"); + if(serverAddress.sin_port == htons(port_number)){ socketDescriptor = -10; return; @@ -592,6 +597,15 @@ typedef struct length-=nsent; total_sent+=nsent; } + + if (total_sent>0) + strcpy(thisClientIP,dummyClientIP); + + if (strcmp(lastClientIP,thisClientIP)) + differentClients=1; + else + differentClients=0; + break; case UDP: if (socketDescriptor<0) return -1; @@ -641,13 +655,7 @@ typedef struct #ifdef VERY_VERBOSE cout << "sent "<< total_sent << " Bytes" << endl; #endif - if (total_sent>0) - strcpy(thisClientIP,dummyClientIP); - if (strcmp(lastClientIP,thisClientIP)) - differentClients=1; - else - differentClients=0; return total_sent; diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index b12826f16..266f3e38c 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -152,7 +152,7 @@ void UDPStandardImplementation::initializeMembers(){ previousFrameNumber = -1; acqStarted = false; measurementStarted = false; - for(int i = 0; i < numberofListeningThreads; ++i) + for(int i = 0; i < MAX_NUMBER_OF_LISTENING_THREADS; ++i) totalListeningFrameCount[i] = 0; packetsInFile = 0; numMissingPackets = 0; @@ -309,6 +309,7 @@ int UDPStandardImplementation::setupFifoStructure(){ return OK; + int count = 0; //set up fifo structure for(int i=0;iisEmpty()) + fifo[i]->pop(buffer[i]); + delete fifo[i]; + } if(mem0[i]) free(mem0[i]); //creating fifoFree[i] = new CircularFifo(fifoSize); fifo[i] = new CircularFifo(fifoSize); + //cout<<"buffersize:"<push(buffer[i]); -#ifdef DEBUG5 +//#ifdef DEBUG5 + + if(count==0 || count == 127998) cprintf(BLUE,"Info: %d fifostructure free pushed into fifofree %p\n", i, (void*)(buffer[i])); -#endif +//#endif buffer[i] += (bufferSize * numberofJobsPerBuffer + HEADER_SIZE_NUM_TOT_PACKETS); + count++; } + cout<pop(buffer[ithread]); -#ifdef DEBUG5 - cprintf(BLUE,"Listening_Thread %d :Listener popped from fifofree %p\n", ithread, (void*)(buffer[ithread])); +#ifdef CFIFODEBUG + if(ithread == 0) + cprintf(CYAN,"Listening_Thread %d :Listener popped from fifofree %p\n", ithread, (void*)(buffer[ithread])); + else + cprintf(YELLOW,"Listening_Thread %d :Listener popped from fifofree %p\n", ithread, (void*)(buffer[ithread])); #endif //udpsocket doesnt exist @@ -1489,8 +1504,12 @@ void UDPStandardImplementation::startListening(){ //push buffer to FIFO while(!fifo[ithread]->push(buffer[ithread])); -#ifdef DEBUG5 - cprintf(BLUE,"Listening_Thread %d: Listener pushed into fifo %p\n",ithread, (void*)(buffer[ithread])); +#ifdef CFIFODEBUG + if(ithread == 0) + cprintf(CYAN,"Listening_Thread %d: Listener pushed into fifo %p\n",ithread, (void*)(buffer[ithread])); + else + cprintf(YELLOW,"Listening_Thread %d: Listener pushed into fifo %p\n",ithread, (void*)(buffer[ithread])); + #endif }/*--end of loop for each buffer (inner loop)*/ @@ -1517,7 +1536,8 @@ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int lSize, in FILE_LOG(logDEBUG) << __AT__ << " called"; //listen to UDP packets - memcpy(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS, temp, cSize); + if(cSize) + memcpy(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS, temp, cSize); int receivedSize = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS + cSize, lSize + cSize); //throw away packets that is not one packet size, need to check status if socket is shut down @@ -1606,8 +1626,11 @@ void UDPStandardImplementation::stopListening(int ithread, int numbytes){ if(numbytes <= 0){ cprintf(BLUE,"Listening_Thread %d :End of Acquisition\n", ithread); while(!fifoFree[ithread]->push(buffer[ithread])); -#ifdef DEBUG5 - cprintf(BLUE,"Listening_Thread %d :Listener push empty buffer into fifofree %p\n", ithread, (void*)(buffer[ithread])); +#ifdef CFIFODEBUG + if(ithread == 0) + cprintf(CYAN,"Listening_Thread %d :Listener push empty buffer into fifofree %p\n", ithread, (void*)(buffer[ithread])); + else + cprintf(YELLOW,"Listening_Thread %d :Listener push empty buffer into fifofree %p\n", ithread, (void*)(buffer[ithread])); #endif } @@ -1621,19 +1644,31 @@ void UDPStandardImplementation::stopListening(int ithread, int numbytes){ cprintf(BLUE,"Listening_Thread %d: Last Buffer packet count:%d\n",ithread, numbytes/onePacketSize); #endif while(!fifo[ithread]->push(buffer[ithread])); -#ifdef DEBUG5 - cprintf(BLUE,"Listening_Thread %d: Listener Last Buffer pushed into fifo %p\n", ithread,(void*)(buffer[ithread])); +#ifdef CFIFODEBUG + if(ithread == 0) + cprintf(CYAN,"Listening_Thread %d: Listener Last Buffer pushed into fifo %p\n", ithread,(void*)(buffer[ithread])); + else + cprintf(YELLOW,"Listening_Thread %d: Listener Last Buffer pushed into fifo %p\n", ithread,(void*)(buffer[ithread])); #endif } //push dummy-end buffer into fifo for all writer threads for(int i=0; ipop(buffer[ithread]); +#ifdef CFIFODEBUG + if(ithread == 0) + cprintf(CYAN,"Listening_Thread %d: Popped Dummy from fifoFree %p\n", ithread,(void*)(buffer[ithread])); + else + cprintf(YELLOW,"Listening_Thread %d: Popped Dummy from fifoFree %p\n", ithread,(void*)(buffer[ithread])); +#endif //creating dummy-end buffer with pc=0xFFFF (*((uint32_t*)(buffer[ithread]))) = dummyPacketValue; while(!fifo[ithread]->push(buffer[ithread])); -#ifdef DEBUG5 - cprintf(BLUE,"Listening_Thread %d: Listener pushed dummy-end buffer into fifo %p\n", ithread,(void*)(buffer[ithread])); +#ifdef CFIFODEBUG + if(ithread == 0) + cprintf(CYAN,"Listening_Thread %d: Listener pushed dummy-end buffer into fifo %p\n", ithread,(void*)(buffer[ithread])); + else + cprintf(YELLOW,"Listening_Thread %d: Listener pushed dummy-end buffer into fifo %p\n", ithread,(void*)(buffer[ithread])); #endif } @@ -1852,8 +1887,9 @@ void UDPStandardImplementation::processWritingBufferPacketByPacket(int ithread){ int MAX_NUM_PACKETS = 1024; //highest 32 bit has 1024 number of packets uint32_t LAST_PACKET_VALUE; //last packet number - char* toFreePointers[MAX_NUM_PACKETS]; //pointers to free for each frame - int toFreePointersOffset[numberofListeningThreads]; //offset of pointers to free added for each thread + + CircularFifo* fifoTempFree[numberofListeningThreads];//ciruclar fifo to keep track of one frame packets to be freed and reused later + char* temp = NULL; char* frameBuffer[MAX_NUM_PACKETS]; //buffer offset created for a whole frame int frameBufferoffset[numberofListeningThreads]; //buffer offset created for a whole frame for both listening threads @@ -1868,34 +1904,42 @@ void UDPStandardImplementation::processWritingBufferPacketByPacket(int ithread){ volatile int numberofMissingPackets[numberofListeningThreads]; // number of missing packets in this buffer for(int i=0; iisEmpty()) + fifoTempFree[i]->pop(temp); + delete fifoTempFree[i]; + } + fifoTempFree[i] = new CircularFifo(MAX_NUM_PACKETS); } - presentFrameNumber = 0; - //blank frame - initializing with missing packet values - blankoffset = 0; for(uint32_t i=0; imissingPacket)==missingPacketValue) cprintf(RED,"Found missing packet at pnum %d\n",j); } } -#endif +//#endif //write and copy to gui handleWithoutDataCompression(ithread,frameBuffer,packetsPerFrame); //freeing - for(int j=0;jpush(toFreePointers[j])); -#ifdef DEBUG5 - cprintf(GREEN,"Fifo 0: Writing_Thread freed: pushed into fifofree %p\n",ithread, (void*)(toFreePointers[j])); -#endif - } - for(int j=(packetsPerFrame/numberofListeningThreads);jpush(toFreePointers[j])); -#ifdef DEBUG5 - cprintf(GREEN,"Fifo 1: Writing_Thread freed: pushed into fifofree %p\n",ithread, (void*)(toFreePointers[j])); + for(int i=0; iisEmpty()){ + fifoTempFree[i]->pop(temp); + fifoFree[i]->push(temp); + count++; +#ifdef CFIFODEBUG + if(i==0) + cprintf(CYAN,"Fifo %d: %d Writing_Thread freed: pushed into fifofree %p\n",i,count, (void*)(temp)); + else + cprintf(YELLOW,"Fifo %d: %d Writing_Thread freed: pushed into fifofree %p\n",i, count,(void*)(temp)); #endif + } } + + + #ifdef DEBUG4 cprintf(GREEN,"Writing_Thread: finished freeing\n"); #endif @@ -2113,7 +2158,6 @@ void UDPStandardImplementation::processWritingBufferPacketByPacket(int ithread){ if((numPackets[i] != dummyPacketValue) && (currentPacketNumber[i] == LAST_PACKET_VALUE)) popReady[i] = true; frameBufferoffset[i] = (i*packetsPerFrame/numberofListeningThreads); - toFreePointersOffset[i] = (i*packetsPerFrame/numberofListeningThreads); blankoffset = 0; lastPacketNumber[i] = 0; currentPacketNumber[i] = 0; @@ -2202,7 +2246,7 @@ void UDPStandardImplementation::waitWritingBufferForNextAcquisition(int ithread) } -bool UDPStandardImplementation::popAndCheckEndofAcquisition(int ithread, char* wbuffer[], bool ready[], uint32_t nP[],char* toFree[],int toFreeOffset[]){ +bool UDPStandardImplementation::popAndCheckEndofAcquisition(int ithread, char* wbuffer[], bool ready[], uint32_t nP[],CircularFifo* fifoTempFree[]){ FILE_LOG(logDEBUG) << __AT__ << " called"; bool endofAcquisition = true; @@ -2210,8 +2254,11 @@ bool UDPStandardImplementation::popAndCheckEndofAcquisition(int ithread, char* w //pop if ready if(ready[i]){ fifo[i]->pop(wbuffer[i]); -#ifdef DEBUG5 - cprintf(GREEN,"Writing_Thread %d: Popped %p from FIFO %d\n", ithread, (void*)(wbuffer[i]),i); +#ifdef CFIFODEBUG + if(i == 0) + cprintf(CYAN,"Writing_Thread %d: Popped %p from FIFO %d\n", ithread, (void*)(wbuffer[i]),i); + else + cprintf(YELLOW,"Writing_Thread %d: Popped %p from FIFO %d\n", ithread, (void*)(wbuffer[i]),i); #endif nP[i] = (uint32_t)(*((uint32_t*)wbuffer[i])); #ifdef DEBUG4 @@ -2239,8 +2286,7 @@ bool UDPStandardImplementation::popAndCheckEndofAcquisition(int ithread, char* w } #endif if(myDetectorType == EIGER){ - toFree[toFreeOffset[i]] = wbuffer[i]; - toFreeOffset[i]++; + while(!fifoTempFree[i]->push(wbuffer[i])); } } } @@ -2264,8 +2310,11 @@ void UDPStandardImplementation::stopWriting(int ithread, char* wbuffer[]){ //free fifo for(int i=0; ipush(wbuffer[i])); -#ifdef DEBUG5 - cprintf(GREEN,"Writing_Thread %d: Freeing dummy-end buffer. Pushed into fifofree %p for listener %d\n", ithread,(void*)(wbuffer[i]),i); +#ifdef CFIFODEBUG + if(i==0) + cprintf(CYAN,"Writing_Thread %d: Freeing dummy-end buffer. Pushed into fifofree %p for listener %d\n", ithread,(void*)(wbuffer[i]),i); + else + cprintf(YELLOW,"Writing_Thread %d: Freeing dummy-end buffer. Pushed into fifofree %p for listener %d\n", ithread,(void*)(wbuffer[i]),i); #endif } @@ -2478,14 +2527,14 @@ void UDPStandardImplementation::writeFileWithoutCompression(char* wbuffer[],uint void UDPStandardImplementation::createHeaders(char* wbuffer[]){ - eiger_packet_header_t* wbuf_header=0; - eiger_packet_footer_t* wbuf_footer=0; + int port = 0, missingPacket; for (uint32_t i = 0; i < packetsPerFrame; i++){ - wbuf_header = (eiger_packet_header_t*) wbuffer[i]; - wbuf_footer = (eiger_packet_footer_t*)(wbuffer[i] + footerOffset); + + eiger_packet_header_t* wbuf_header = (eiger_packet_header_t*) wbuffer[i]; + eiger_packet_footer_t* wbuf_footer = (eiger_packet_footer_t*)(wbuffer[i] + footerOffset); #ifdef DEBUG4 cprintf(GREEN, "Loop index:%d Pnum:%d\n",i,*( (uint16_t*) wbuf_footer->packetNumber)); #endif diff --git a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp index 1a6f9860c..4e32516fa 100644 --- a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp +++ b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp @@ -441,6 +441,7 @@ int slsReceiverTCPIPInterface::set_file_name() { #endif #endif + if(ret==OK && socket->differentClients){ FILE_LOG(logDEBUG) << "Force update"; ret=FORCE_UPDATE; @@ -451,12 +452,14 @@ int slsReceiverTCPIPInterface::set_file_name() { if(ret==FAIL){ cprintf(RED, "%s\n", mess); socket->SendDataOnly(mess,sizeof(mess)); + } + if(retval == NULL) socket->SendDataOnly(defaultVal,MAX_STR_LENGTH); - }else + else{ socket->SendDataOnly(retval,MAX_STR_LENGTH); + delete[] retval; + } - //free - if(retval != NULL) delete[] retval; //return ok/fail return ret; @@ -523,12 +526,13 @@ int slsReceiverTCPIPInterface::set_file_dir() { if(ret==FAIL){ cprintf(RED, "%s\n", mess); socket->SendDataOnly(mess,sizeof(mess)); + } + if(retval == NULL) socket->SendDataOnly(defaultVal,MAX_STR_LENGTH); - }else + else{ socket->SendDataOnly(retval,MAX_STR_LENGTH); - - //free - if(retval != NULL) delete[] retval; + delete[] retval; + } //return ok/fail return ret; @@ -2244,13 +2248,15 @@ int slsReceiverTCPIPInterface::set_detector_hostname() { // send answer socket->SendDataOnly(&ret,sizeof(ret)); if(ret==FAIL){ - cprintf(RED,"%s\n",mess); + cprintf(RED, "%s\n", mess); socket->SendDataOnly(mess,sizeof(mess)); + } + if(retval == NULL) socket->SendDataOnly(defaultVal,MAX_STR_LENGTH); - }else socket->SendDataOnly(retval,MAX_STR_LENGTH); - - //free - if(retval!=NULL) delete[] retval; + else{ + socket->SendDataOnly(retval,MAX_STR_LENGTH); + delete[] retval; + } //return ok/fail return ret; From 24438419d55483768d36ab395f4a8c6411c5ddec Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Wed, 11 Nov 2015 15:09:37 +0100 Subject: [PATCH 173/474] some changes for memory leak --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 266f3e38c..8d74dfa90 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -355,7 +355,6 @@ int UDPStandardImplementation::setupFifoStructure(){ buffer[i] += (bufferSize * numberofJobsPerBuffer + HEADER_SIZE_NUM_TOT_PACKETS); count++; } - cout< Date: Thu, 12 Nov 2015 13:49:09 +0100 Subject: [PATCH 174/474] memory leak fixed --- slsReceiverSoftware/include/circularFifo.h | 11 +- slsReceiverSoftware/include/genericSocket.h | 114 ++++++++---------- slsReceiverSoftware/include/receiver_defs.h | 2 +- .../src/UDPStandardImplementation.cpp | 33 +++-- 4 files changed, 77 insertions(+), 83 deletions(-) diff --git a/slsReceiverSoftware/include/circularFifo.h b/slsReceiverSoftware/include/circularFifo.h index 1ba584cc4..4234a4d5d 100644 --- a/slsReceiverSoftware/include/circularFifo.h +++ b/slsReceiverSoftware/include/circularFifo.h @@ -78,8 +78,10 @@ int CircularFifo::getSemValue() template bool CircularFifo::push(Element*& item_) { - + //cout<<"*head:"<::push(Element*& item_) template bool CircularFifo::pop(Element*& item_) { - // if(head == tail) - // return false; // empty queue + //cout<<"-tail:"<0){ - nsending = (length>packet_size) ? packet_size:length; - nsent = read(file_des,(char*)buf+total_sent,nsending); - if(!nsent) break; - length-=nsent; - total_sent+=nsent; - } + if (buf==NULL) return -1; - if (total_sent>0) - strcpy(thisClientIP,dummyClientIP); - if (strcmp(lastClientIP,thisClientIP)) - differentClients=1; - else - differentClients=0; + total_sent=0; - break; - case UDP: - if (socketDescriptor<0) return -1; + switch(protocol) { + case TCP: + if (file_des<0) return -1; + while(length>0){ + nsending = (length>packet_size) ? packet_size:length; + nsent = read(file_des,(char*)buf+total_sent,nsending); + if(!nsent) break; + length-=nsent; + total_sent+=nsent; + } - //if length given, listens to length, else listens for packetsize till length is reached - if(length){ -/*int k = 0;*/ + if (total_sent>0) + strcpy(thisClientIP,dummyClientIP); - while(length>0){ - nsending = (length>packet_size) ? packet_size:length; -/* + if (strcmp(lastClientIP,thisClientIP)) + differentClients=1; + else + differentClients=0; + + break; + case UDP: + if (socketDescriptor<0) return -1; + + //if length given, listens to length, else listens for packetsize till length is reached + if(length){ + /*int k = 0;*/ + + while(length>0){ + nsending = (length>packet_size) ? packet_size:length; + /* //created for debugging on 11.05.2015 nsending=5000; nsent = recvfrom(socketDescriptor,(char*)buf,nsending, 0, (struct sockaddr *) &clientAddress, &clientAddress_length); @@ -632,33 +632,32 @@ typedef struct } else k++; - */ - - - nsent = recvfrom(socketDescriptor,(char*)buf+total_sent,nsending, 0, (struct sockaddr *) &clientAddress, &clientAddress_length); - if(!nsent) break; - length-=nsent; - total_sent+=nsent; - } - } - //listens to only 1 packet - else{ - //normal - nsending=packet_size; - nsent = recvfrom(socketDescriptor,(char*)buf+total_sent,nsending, 0, (struct sockaddr *) &clientAddress, &clientAddress_length); - total_sent+=nsent; - } - break; - default: - ; - } + */ + nsent = recvfrom(socketDescriptor,(char*)buf+total_sent,nsending, 0, (struct sockaddr *) &clientAddress, &clientAddress_length); + if(!nsent) break; + length-=nsent; + total_sent+=nsent; + } + } + //listens to only 1 packet + else{ + //normal + nsending=packet_size; + nsent = recvfrom(socketDescriptor,(char*)buf+total_sent,nsending, 0, (struct sockaddr *) &clientAddress, &clientAddress_length); + //nsent = 1040; + total_sent+=nsent; + } + break; + default: + ; + } #ifdef VERY_VERBOSE - cout << "sent "<< total_sent << " Bytes" << endl; + cout << "sent "<< total_sent << " Bytes" << endl; #endif - return total_sent; - + return total_sent; + } @@ -714,21 +713,12 @@ typedef struct protected: communicationProtocol protocol; - - - int is_a_server; - - int socketDescriptor; int file_des; - int packet_size; - struct sockaddr_in clientAddress, serverAddress; socklen_t clientAddress_length; - - char dummyClientIP[INET_ADDRSTRLEN]; diff --git a/slsReceiverSoftware/include/receiver_defs.h b/slsReceiverSoftware/include/receiver_defs.h index bac0df2d6..c11fe876d 100755 --- a/slsReceiverSoftware/include/receiver_defs.h +++ b/slsReceiverSoftware/include/receiver_defs.h @@ -111,7 +111,7 @@ #define EIGER_MAX_PORTS 2 #define EIGER_HEADER_LENGTH 48 -#define EIGER_FIFO_SIZE 250 //cannot be less than max jobs per thread = 1000 +#define EIGER_FIFO_SIZE 100 /*#define EIGER_ALIGNED_FRAME_SIZE 65536*/ #define EIGER_ONE_GIGA_CONSTANT 16 #define EIGER_TEN_GIGA_CONSTANT 4 diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 8d74dfa90..68ba62a68 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -309,7 +309,6 @@ int UDPStandardImplementation::setupFifoStructure(){ return OK; - int count = 0; //set up fifo structure for(int i=0;ipush(buffer[i]); -//#ifdef DEBUG5 - - if(count==0 || count == 127998) + sprintf(buffer[i],"mem%d",i); +#ifdef DEBUG5 cprintf(BLUE,"Info: %d fifostructure free pushed into fifofree %p\n", i, (void*)(buffer[i])); -//#endif +#endif buffer[i] += (bufferSize * numberofJobsPerBuffer + HEADER_SIZE_NUM_TOT_PACKETS); - count++; } } FILE_LOG(logDEBUG) << "Info: Fifo structure(s) reconstructed"; @@ -1461,6 +1457,7 @@ void UDPStandardImplementation::startListening(){ //until mask unset (udp sockets shut down by client) while((1 << ithread) & listeningThreadsMask){ + //pop from fifo fifoFree[ithread]->pop(buffer[ithread]); #ifdef CFIFODEBUG @@ -1479,6 +1476,7 @@ void UDPStandardImplementation::startListening(){ rc = prepareAndListenBuffer(ithread, listenSize, carryonBufferSize, tempBuffer); + //start indices for each start of scan/acquisition if((!measurementStarted) && (rc > 0)){ pthread_mutex_lock(&progressMutex); @@ -1487,12 +1485,12 @@ void UDPStandardImplementation::startListening(){ pthread_mutex_unlock(&progressMutex); } + //problem in receiving or end of acquisition if (status == TRANSMITTING){ stopListening(ithread,rc); continue; } - //write packet count to buffer if(myDetectorType == EIGER) (*((uint32_t*)(buffer[ithread]))) = 1; @@ -1503,6 +1501,7 @@ void UDPStandardImplementation::startListening(){ //push buffer to FIFO while(!fifo[ithread]->push(buffer[ithread])); + #ifdef CFIFODEBUG if(ithread == 0) cprintf(CYAN,"Listening_Thread %d: Listener pushed into fifo %p\n",ithread, (void*)(buffer[ithread])); @@ -1511,6 +1510,7 @@ void UDPStandardImplementation::startListening(){ #endif + }/*--end of loop for each buffer (inner loop)*/ //end of acquisition, wait for next acquisition/change of parameters @@ -1537,6 +1537,7 @@ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int lSize, in //listen to UDP packets if(cSize) memcpy(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS, temp, cSize); + int receivedSize = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS + cSize, lSize + cSize); //throw away packets that is not one packet size, need to check status if socket is shut down @@ -1550,6 +1551,7 @@ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int lSize, in receivedSize = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS); } + #ifdef MANUALDEBUG eiger_packet_header_t* header = (eiger_packet_header_t*) (buffer[ithread]+HEADER_SIZE_NUM_TOT_PACKETS); eiger_packet_footer_t* footer = (eiger_packet_footer_t*)(buffer[ithread] + footerOffset + HEADER_SIZE_NUM_TOT_PACKETS); @@ -1961,7 +1963,6 @@ void UDPStandardImplementation::processWritingBufferPacketByPacket(int ithread){ //until mask unset (udp sockets shut down by client) while((1 << ithread) & writerThreadsMask){ - //pop fifo and if end of acquisition if(popAndCheckEndofAcquisition(ithread, packetBuffer, popReady, numPackets,fifoTempFree)){ #ifdef DEBUG4 @@ -2109,10 +2110,10 @@ void UDPStandardImplementation::processWritingBufferPacketByPacket(int ithread){ currentFrameNumber = presentFrameNumber; numTotMissingPacketsInFile += numMissingPackets; numTotMissingPackets += numMissingPackets; -//#ifdef FNUM_DEBUG +#ifdef FNUM_DEBUG cprintf(GREEN,"**fnum:%d**\n",currentFrameNumber); -//#endif -//#ifdef MISSINGP_DEBUG +#endif +#ifdef MISSINGP_DEBUG if(numMissingPackets){ cprintf(RED, "Total missing packets %d for fnum %d\n",numMissingPackets,currentFrameNumber); for (int j=0;jisEmpty()){ fifoTempFree[i]->pop(temp); fifoFree[i]->push(temp); - count++; #ifdef CFIFODEBUG if(i==0) - cprintf(CYAN,"Fifo %d: %d Writing_Thread freed: pushed into fifofree %p\n",i,count, (void*)(temp)); + cprintf(CYAN,"Fifo %d: Writing_Thread freed: pushed into fifofree %p\n",i, (void*)(temp)); else - cprintf(YELLOW,"Fifo %d: %d Writing_Thread freed: pushed into fifofree %p\n",i, count,(void*)(temp)); + cprintf(YELLOW,"Fifo %d: Writing_Thread freed: pushed into fifofree %p\n",i, (void*)(temp)); #endif } } From 113e5223990bbd22f5639409790f4b254314aa05 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Fri, 13 Nov 2015 17:55:11 +0100 Subject: [PATCH 175/474] refactoring and reducing overhead --- .../src/UDPStandardImplementation.cpp | 28 ++++++++++++++----- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 68ba62a68..2b3068e08 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -856,7 +856,6 @@ int UDPStandardImplementation::startReceiver(char *c){ for(int i=0;i Date: Mon, 16 Nov 2015 11:48:50 +0100 Subject: [PATCH 176/474] fifodepth def change, and listening packets count right --- .../include/UDPStandardImplementation.h | 2 +- .../src/UDPStandardImplementation.cpp | 49 ++++++++++--------- 2 files changed, 26 insertions(+), 25 deletions(-) diff --git a/slsReceiverSoftware/include/UDPStandardImplementation.h b/slsReceiverSoftware/include/UDPStandardImplementation.h index a1cad30e9..605afc155 100644 --- a/slsReceiverSoftware/include/UDPStandardImplementation.h +++ b/slsReceiverSoftware/include/UDPStandardImplementation.h @@ -585,7 +585,7 @@ private: int numberofJobsPerBuffer; /** Fifo Depth */ - uint32_t fifoSize; + uint32_t fifoDepth; /** Missing Packet identifier value */ const static uint16_t missingPacketValue = 0xFFFF; diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 2b3068e08..4c2574234 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -170,7 +170,7 @@ void UDPStandardImplementation::initializeMembers(){ } sfilefd = NULL; numberofJobsPerBuffer = -1; - fifoSize = 0; + fifoDepth = 0; //***receiver to GUI parameters*** latestData = NULL; @@ -253,7 +253,7 @@ int UDPStandardImplementation::setupFifoStructure(){ int64_t i; int oldNumberofJobsPerBuffer = numberofJobsPerBuffer; - uint32_t oldFifoSize = fifoSize; + uint32_t oldFifoSize = fifoDepth; //eiger always listens to 1 packet at a time if(myDetectorType == EIGER){ @@ -287,25 +287,25 @@ int UDPStandardImplementation::setupFifoStructure(){ //set fifo depth //eiger listens to 1 packet at a time and size changes depending on packets per frame if(myDetectorType == EIGER) - fifoSize = EIGER_FIFO_SIZE * packetsPerFrame; + fifoDepth = EIGER_FIFO_SIZE * packetsPerFrame; else{ - fifoSize = GOTTHARD_FIFO_SIZE; + fifoDepth = GOTTHARD_FIFO_SIZE; if(myDetectorType == MOENCH) - fifoSize = MOENCH_FIFO_SIZE; + fifoDepth = MOENCH_FIFO_SIZE; else if(myDetectorType == PROPIX) - fifoSize = PROPIX_FIFO_SIZE; + fifoDepth = PROPIX_FIFO_SIZE; //reduce fifo depth if more frames listened to at a time - if(fifoSize % numberofJobsPerBuffer) - fifoSize = (fifoSize/numberofJobsPerBuffer)+1; + if(fifoDepth % numberofJobsPerBuffer) + fifoDepth = (fifoDepth/numberofJobsPerBuffer)+1; else - fifoSize = fifoSize/numberofJobsPerBuffer; + fifoDepth = fifoDepth/numberofJobsPerBuffer; } - FILE_LOG(logDEBUG) << "Info: Fifo Depth:" << fifoSize; + FILE_LOG(logDEBUG) << "Info: Fifo Depth:" << fifoDepth; //do not rebuild fifo structure if it is the same - if((oldNumberofJobsPerBuffer == numberofJobsPerBuffer) && (oldFifoSize == fifoSize)) + if((oldNumberofJobsPerBuffer == numberofJobsPerBuffer) && (oldFifoSize == fifoDepth)) return OK; @@ -329,13 +329,13 @@ int UDPStandardImplementation::setupFifoStructure(){ if(mem0[i]) free(mem0[i]); //creating - fifoFree[i] = new CircularFifo(fifoSize); - fifo[i] = new CircularFifo(fifoSize); + fifoFree[i] = new CircularFifo(fifoDepth); + fifo[i] = new CircularFifo(fifoDepth); //cout<<"buffersize:"<push(buffer[i]); sprintf(buffer[i],"mem%d",i); #ifdef DEBUG5 @@ -660,7 +660,7 @@ int UDPStandardImplementation::setDetectorType(const detectorType d){ frameIndexOffset = GOTTHARD_FRAME_INDEX_OFFSET; packetIndexMask = GOTTHARD_PACKET_INDEX_MASK; maxPacketsPerFile = MAX_FRAMES_PER_FILE * GOTTHARD_PACKETS_PER_FRAME; - fifoSize = GOTTHARD_FIFO_SIZE; + fifoDepth = GOTTHARD_FIFO_SIZE; //footerOffset = Not applicable; break; case PROPIX: @@ -673,7 +673,7 @@ int UDPStandardImplementation::setDetectorType(const detectorType d){ frameIndexOffset = PROPIX_FRAME_INDEX_OFFSET; packetIndexMask = PROPIX_PACKET_INDEX_MASK; maxPacketsPerFile = MAX_FRAMES_PER_FILE * PROPIX_PACKETS_PER_FRAME; - fifoSize = PROPIX_FIFO_SIZE; + fifoDepth = PROPIX_FIFO_SIZE; //footerOffset = Not applicable; break; case MOENCH: @@ -686,7 +686,7 @@ int UDPStandardImplementation::setDetectorType(const detectorType d){ frameIndexOffset = MOENCH_FRAME_INDEX_OFFSET; packetIndexMask = MOENCH_PACKET_INDEX_MASK; maxPacketsPerFile = MOENCH_MAX_FRAMES_PER_FILE * MOENCH_PACKETS_PER_FRAME; - fifoSize = MOENCH_FIFO_SIZE; + fifoDepth = MOENCH_FIFO_SIZE; //footerOffset = Not applicable; break; case EIGER: @@ -700,7 +700,7 @@ int UDPStandardImplementation::setDetectorType(const detectorType d){ frameIndexOffset = EIGER_FRAME_INDEX_OFFSET; packetIndexMask = EIGER_PACKET_INDEX_MASK; maxPacketsPerFile = EIGER_MAX_FRAMES_PER_FILE * packetsPerFrame; - fifoSize = EIGER_FIFO_SIZE; + fifoDepth = EIGER_FIFO_SIZE; footerOffset = EIGER_PACKET_HEADER_SIZE + oneDataSize; break; case JUNGFRAUCTB: @@ -714,7 +714,7 @@ int UDPStandardImplementation::setDetectorType(const detectorType d){ frameIndexOffset = JCTB_FRAME_INDEX_OFFSET; packetIndexMask = JCTB_PACKET_INDEX_MASK; maxPacketsPerFile = JFCTB_MAX_FRAMES_PER_FILE * JCTB_PACKETS_PER_FRAME; - fifoSize = JCTB_FIFO_SIZE; + fifoDepth = JCTB_FIFO_SIZE; //footerOffset = Not applicable; break; default: @@ -934,18 +934,19 @@ void UDPStandardImplementation::startReadout(){ } //wait for all packets if(totalP!=numberOfFrames*packetsPerFrame){ + prev = -1; //wait as long as there is change from prev totalP while(prev != totalP){ - cprintf(MAGENTA,"waiting for all packets\n"); - usleep(1000);/* Need to find optimal time (exposure time and acquisition period) **/ + cprintf(MAGENTA,"waiting for all packets totalP:%d\n",totalP); + usleep(5000);/* Need to find optimal time (exposure time and acquisition period) **/ prev = totalP; totalP=0; for(i=0; iReceiveDataOnly(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS); } - + totalListeningFrameCount[ithread] += (receivedSize/onePacketSize); #ifdef MANUALDEBUG eiger_packet_header_t* header = (eiger_packet_header_t*) (buffer[ithread]+HEADER_SIZE_NUM_TOT_PACKETS); From 777f04331d28c06f0e5d6f6806b4e7ebd6929edf Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 17 Nov 2015 10:31:09 +0100 Subject: [PATCH 177/474] implemented fifo depth configurable from client --- .../include/UDPBaseImplementation.h | 16 ++++ slsReceiverSoftware/include/UDPInterface.h | 13 +++ .../include/UDPStandardImplementation.h | 11 ++- .../include/slsReceiverTCPIPInterface.h | 3 + .../include/sls_receiver_funcs.h | 3 +- .../src/UDPBaseImplementation.cpp | 12 +++ .../src/UDPStandardImplementation.cpp | 88 +++++++++++-------- .../src/slsReceiverTCPIPInterface.cpp | 76 ++++++++++++++++ 8 files changed, 184 insertions(+), 38 deletions(-) diff --git a/slsReceiverSoftware/include/UDPBaseImplementation.h b/slsReceiverSoftware/include/UDPBaseImplementation.h index dfb7b0429..2c544759b 100644 --- a/slsReceiverSoftware/include/UDPBaseImplementation.h +++ b/slsReceiverSoftware/include/UDPBaseImplementation.h @@ -179,6 +179,13 @@ class UDPBaseImplementation : protected virtual slsReceiverDefs, public UDPInter */ bool getTenGigaEnable() const; + /** + * Get Fifo Depth + * @return fifo depth + */ + uint32_t getFifoDepth() const; + + //***receiver status*** /** * Get Listening Status of Receiver @@ -324,6 +331,13 @@ class UDPBaseImplementation : protected virtual slsReceiverDefs, public UDPInter */ int setTenGigaEnable(const bool b); + /** + * Set Fifo Depth + * @param i fifo depth value + * @return OK or FAIL + */ + int setFifoDepth(const uint32_t i); + /************************************************************************* * Behavioral functions*************************************************** @@ -460,6 +474,8 @@ class UDPBaseImplementation : protected virtual slsReceiverDefs, public UDPInter uint32_t dynamicRange; /** Ten Giga Enable*/ bool tengigaEnable; + /** Fifo Depth */ + uint32_t fifoDepth; /** Bottom Half Module Enable */ bool bottomEnable; diff --git a/slsReceiverSoftware/include/UDPInterface.h b/slsReceiverSoftware/include/UDPInterface.h index 1a6377653..798c45f6c 100644 --- a/slsReceiverSoftware/include/UDPInterface.h +++ b/slsReceiverSoftware/include/UDPInterface.h @@ -235,6 +235,12 @@ class UDPInterface { */ virtual bool getTenGigaEnable() const = 0; + /** + * Get Fifo Depth + * @return fifo depth + */ + virtual uint32_t getFifoDepth() const = 0; + //***receiver status*** /** * Get Listening Status of Receiver @@ -378,6 +384,13 @@ class UDPInterface { */ virtual int setTenGigaEnable(const bool b) = 0; + /** + * Set Fifo Depth + * @param i fifo depth value + * @return OK or FAIL + */ + virtual int setFifoDepth(const uint32_t i) = 0; + /************************************************************************* * Behavioral functions*************************************************** diff --git a/slsReceiverSoftware/include/UDPStandardImplementation.h b/slsReceiverSoftware/include/UDPStandardImplementation.h index 605afc155..3c256450a 100644 --- a/slsReceiverSoftware/include/UDPStandardImplementation.h +++ b/slsReceiverSoftware/include/UDPStandardImplementation.h @@ -122,6 +122,13 @@ class UDPStandardImplementation: private virtual slsReceiverDefs, public UDPBase int setTenGigaEnable(const bool b); + /** + * Overridden method + * Set Fifo Depth + * @param i fifo depth value + * @return OK or FAIL + */ + int setFifoDepth(const uint32_t i); /************************************************************************* * Behavioral functions*************************************************** @@ -584,8 +591,8 @@ private: /** Number of Jobs Per Buffer */ int numberofJobsPerBuffer; - /** Fifo Depth */ - uint32_t fifoDepth; + /** Total fifo size */ + uint32_t fifoSize; /** Missing Packet identifier value */ const static uint16_t missingPacketValue = 0xFFFF; diff --git a/slsReceiverSoftware/include/slsReceiverTCPIPInterface.h b/slsReceiverSoftware/include/slsReceiverTCPIPInterface.h index 49e5134f1..b71b705f6 100644 --- a/slsReceiverSoftware/include/slsReceiverTCPIPInterface.h +++ b/slsReceiverSoftware/include/slsReceiverTCPIPInterface.h @@ -207,6 +207,9 @@ private: /** enable 10Gbe */ int enable_tengiga(); + /** set fifo depth */ + int set_fifo_depth(); + //General Functions /** Locks Receiver */ int lock_receiver(); diff --git a/slsReceiverSoftware/include/sls_receiver_funcs.h b/slsReceiverSoftware/include/sls_receiver_funcs.h index 7f3842576..e1ef93040 100644 --- a/slsReceiverSoftware/include/sls_receiver_funcs.h +++ b/slsReceiverSoftware/include/sls_receiver_funcs.h @@ -48,7 +48,8 @@ enum { F_ENABLE_RECEIVER_COMPRESSION, /**< enable compression in receiver */ F_ENABLE_RECEIVER_OVERWRITE, /**< set overwrite flag in receiver */ - F_ENABLE_RECEIVER_TEN_GIGA /**< enable 10Gbe in receiver */ + F_ENABLE_RECEIVER_TEN_GIGA, /**< enable 10Gbe in receiver */ + F_SET_RECEIVER_FIFO_DEPTH /**< set receiver fifo depth */ /* Always append functions hereafter!!! */ }; diff --git a/slsReceiverSoftware/src/UDPBaseImplementation.cpp b/slsReceiverSoftware/src/UDPBaseImplementation.cpp index 606208521..9a9b1723a 100644 --- a/slsReceiverSoftware/src/UDPBaseImplementation.cpp +++ b/slsReceiverSoftware/src/UDPBaseImplementation.cpp @@ -44,6 +44,7 @@ void UDPBaseImplementation::initializeMembers(){ numberOfFrames = 0; dynamicRange = 16; tengigaEnable = false; + fifoDepth = 0; bottomEnable = false; //***receiver parameters*** @@ -181,6 +182,8 @@ uint32_t UDPBaseImplementation::getDynamicRange() const{ FILE_LOG(logDEBUG) << _ bool UDPBaseImplementation::getTenGigaEnable() const{ FILE_LOG(logDEBUG) << __AT__ << " starting"; return tengigaEnable;} +uint32_t UDPBaseImplementation::getFifoDepth() const{ FILE_LOG(logDEBUG) << __AT__ << " starting"; return fifoDepth;} + /***receiver status***/ slsReceiverDefs::runStatus UDPBaseImplementation::getStatus() const{ FILE_LOG(logDEBUG) << __AT__ << " starting"; return status;} @@ -358,6 +361,15 @@ int UDPBaseImplementation::setTenGigaEnable(const bool b){ return OK; } +int UDPBaseImplementation::setFifoDepth(const uint32_t i){ + FILE_LOG(logDEBUG) << __AT__ << " starting"; + + fifoDepth = i; + FILE_LOG(logINFO) << "Fifo Depth: " << i; + + //overridden functions might return FAIL + return OK; +} /************************************************************************* * Behavioral functions*************************************************** diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 4c2574234..3a6a346e1 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -170,7 +170,7 @@ void UDPStandardImplementation::initializeMembers(){ } sfilefd = NULL; numberofJobsPerBuffer = -1; - fifoDepth = 0; + fifoSize = 0; //***receiver to GUI parameters*** latestData = NULL; @@ -251,16 +251,15 @@ void UDPStandardImplementation::initializeFilter(){ int UDPStandardImplementation::setupFifoStructure(){ FILE_LOG(logDEBUG) << __AT__ << " called"; + + //number of jobs per buffer int64_t i; int oldNumberofJobsPerBuffer = numberofJobsPerBuffer; - uint32_t oldFifoSize = fifoDepth; - //eiger always listens to 1 packet at a time if(myDetectorType == EIGER){ numberofJobsPerBuffer = 1; FILE_LOG(logDEBUG) << "Info: 1 packet per buffer"; } - //else calculate best possible number of frames to listen to at a time (for fast readouts like gotthard) else{ //if frequency to gui is not random (every nth frame), then listen to only n frames per buffer @@ -284,29 +283,41 @@ int UDPStandardImplementation::setupFifoStructure(){ FILE_LOG(logINFO) << "Number of Frames per buffer:" << numberofJobsPerBuffer << endl; } - //set fifo depth - //eiger listens to 1 packet at a time and size changes depending on packets per frame - if(myDetectorType == EIGER) - fifoDepth = EIGER_FIFO_SIZE * packetsPerFrame; - else{ - fifoDepth = GOTTHARD_FIFO_SIZE; - if(myDetectorType == MOENCH) - fifoDepth = MOENCH_FIFO_SIZE; - else if(myDetectorType == PROPIX) - fifoDepth = PROPIX_FIFO_SIZE; - //reduce fifo depth if more frames listened to at a time - if(fifoDepth % numberofJobsPerBuffer) - fifoDepth = (fifoDepth/numberofJobsPerBuffer)+1; - else - fifoDepth = fifoDepth/numberofJobsPerBuffer; + + + // fifo depth + uint32_t oldFifoSize = fifoSize; + //default + if(!fifoDepth){ + switch(myDetectorType){ + case GOTTHARD: fifoSize = GOTTHARD_FIFO_SIZE; break; + case MOENCH: fifoSize = MOENCH_FIFO_SIZE; break; + case PROPIX: fifoSize = PROPIX_FIFO_SIZE; break; + case EIGER: fifoSize = EIGER_FIFO_SIZE * packetsPerFrame; break;//listens to 1 packet at a time and size depends on packetsperframe + default: break; + } } - FILE_LOG(logDEBUG) << "Info: Fifo Depth:" << fifoDepth; + //change by user + else{ + if(myDetectorType == EIGER) + fifoSize = fifoDepth * packetsPerFrame; + else fifoSize = fifoDepth; + } + //reduce fifo depth if > 1 numberofJobsPerBuffer + if(fifoSize % numberofJobsPerBuffer) + fifoSize = (fifoSize/numberofJobsPerBuffer)+1; + else + fifoSize = fifoSize/numberofJobsPerBuffer; - //do not rebuild fifo structure if it is the same - if((oldNumberofJobsPerBuffer == numberofJobsPerBuffer) && (oldFifoSize == fifoDepth)) + //do not rebuild fifo structure if it is the same (oldfifosize differs only for different packetsperframe) + if((oldNumberofJobsPerBuffer == numberofJobsPerBuffer) && (oldFifoSize == fifoSize)) return OK; + FILE_LOG(logINFO) << "Info: Total Fifo Size:" << fifoSize; + + + //set up fifo structure @@ -329,13 +340,11 @@ int UDPStandardImplementation::setupFifoStructure(){ if(mem0[i]) free(mem0[i]); //creating - fifoFree[i] = new CircularFifo(fifoDepth); - fifo[i] = new CircularFifo(fifoDepth); - - //cout<<"buffersize:"<(fifoSize); + fifo[i] = new CircularFifo(fifoSize); //allocate memory - mem0[i] = (char*)malloc((bufferSize * numberofJobsPerBuffer + HEADER_SIZE_NUM_TOT_PACKETS) * fifoDepth); + mem0[i] = (char*)malloc((bufferSize * numberofJobsPerBuffer + HEADER_SIZE_NUM_TOT_PACKETS) * fifoSize); if (mem0[i] == NULL){ cprintf(BG_RED,"Error: Could not allocate memory for listening \n"); return FAIL; @@ -343,7 +352,7 @@ int UDPStandardImplementation::setupFifoStructure(){ //push free address into fifoFree buffer[i]=mem0[i]; - while (buffer[i] < (mem0[i]+(bufferSize * numberofJobsPerBuffer + HEADER_SIZE_NUM_TOT_PACKETS) * (fifoDepth-1))) { + while (buffer[i] < (mem0[i]+(bufferSize * numberofJobsPerBuffer + HEADER_SIZE_NUM_TOT_PACKETS) * (fifoSize-1))) { fifoFree[i]->push(buffer[i]); sprintf(buffer[i],"mem%d",i); #ifdef DEBUG5 @@ -352,7 +361,7 @@ int UDPStandardImplementation::setupFifoStructure(){ buffer[i] += (bufferSize * numberofJobsPerBuffer + HEADER_SIZE_NUM_TOT_PACKETS); } } - FILE_LOG(logDEBUG) << "Info: Fifo structure(s) reconstructed"; + cout << "Fifo structure(s) reconstructed" << endl; return OK; } @@ -612,7 +621,16 @@ int UDPStandardImplementation::setTenGigaEnable(const bool b){ } +int UDPStandardImplementation::setFifoDepth(const uint32_t i){ + FILE_LOG(logDEBUG) << __AT__ << " called"; + if(i != fifoDepth){ + FILE_LOG(logINFO) << "Fifo Depth: " << i << endl; + fifoDepth = i; + return setupFifoStructure(); + } + return OK; +} @@ -641,7 +659,7 @@ int UDPStandardImplementation::setDetectorType(const detectorType d){ case EIGER: case JUNGFRAUCTB: case JUNGFRAU: - FILE_LOG(logINFO) << " ***** This is a " << getDetectorType(d) << " Receiver *****"; + FILE_LOG(logINFO) << " ***** " << getDetectorType(d) << " Receiver *****"; break; default: FILE_LOG(logERROR) << "This is an unknown receiver type " << (int)d; @@ -660,7 +678,7 @@ int UDPStandardImplementation::setDetectorType(const detectorType d){ frameIndexOffset = GOTTHARD_FRAME_INDEX_OFFSET; packetIndexMask = GOTTHARD_PACKET_INDEX_MASK; maxPacketsPerFile = MAX_FRAMES_PER_FILE * GOTTHARD_PACKETS_PER_FRAME; - fifoDepth = GOTTHARD_FIFO_SIZE; + fifoSize = GOTTHARD_FIFO_SIZE; //footerOffset = Not applicable; break; case PROPIX: @@ -673,7 +691,7 @@ int UDPStandardImplementation::setDetectorType(const detectorType d){ frameIndexOffset = PROPIX_FRAME_INDEX_OFFSET; packetIndexMask = PROPIX_PACKET_INDEX_MASK; maxPacketsPerFile = MAX_FRAMES_PER_FILE * PROPIX_PACKETS_PER_FRAME; - fifoDepth = PROPIX_FIFO_SIZE; + fifoSize = PROPIX_FIFO_SIZE; //footerOffset = Not applicable; break; case MOENCH: @@ -686,7 +704,7 @@ int UDPStandardImplementation::setDetectorType(const detectorType d){ frameIndexOffset = MOENCH_FRAME_INDEX_OFFSET; packetIndexMask = MOENCH_PACKET_INDEX_MASK; maxPacketsPerFile = MOENCH_MAX_FRAMES_PER_FILE * MOENCH_PACKETS_PER_FRAME; - fifoDepth = MOENCH_FIFO_SIZE; + fifoSize = MOENCH_FIFO_SIZE; //footerOffset = Not applicable; break; case EIGER: @@ -700,7 +718,7 @@ int UDPStandardImplementation::setDetectorType(const detectorType d){ frameIndexOffset = EIGER_FRAME_INDEX_OFFSET; packetIndexMask = EIGER_PACKET_INDEX_MASK; maxPacketsPerFile = EIGER_MAX_FRAMES_PER_FILE * packetsPerFrame; - fifoDepth = EIGER_FIFO_SIZE; + fifoSize = EIGER_FIFO_SIZE; footerOffset = EIGER_PACKET_HEADER_SIZE + oneDataSize; break; case JUNGFRAUCTB: @@ -714,7 +732,7 @@ int UDPStandardImplementation::setDetectorType(const detectorType d){ frameIndexOffset = JCTB_FRAME_INDEX_OFFSET; packetIndexMask = JCTB_PACKET_INDEX_MASK; maxPacketsPerFile = JFCTB_MAX_FRAMES_PER_FILE * JCTB_PACKETS_PER_FRAME; - fifoDepth = JCTB_FIFO_SIZE; + fifoSize = JCTB_FIFO_SIZE; //footerOffset = Not applicable; break; default: diff --git a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp index 4e32516fa..403aa7309 100644 --- a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp +++ b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp @@ -252,6 +252,7 @@ int slsReceiverTCPIPInterface::function_table(){ flist[F_ENABLE_RECEIVER_OVERWRITE] = &slsReceiverTCPIPInterface::enable_overwrite; flist[F_ENABLE_RECEIVER_TEN_GIGA] = &slsReceiverTCPIPInterface::enable_tengiga; + flist[F_SET_RECEIVER_FIFO_DEPTH] = &slsReceiverTCPIPInterface::set_fifo_depth; #ifdef VERYVERBOSE @@ -2484,6 +2485,81 @@ int slsReceiverTCPIPInterface::enable_tengiga() { +int slsReceiverTCPIPInterface::set_fifo_depth() { + ret=OK; + int value=-1; + int retval=-100; + strcpy(mess,"Could not set/get fifo depth for receiver\n"); + + // receive arguments + if(socket->ReceiveDataOnly(&value,sizeof(value)) < 0 ){ + strcpy(mess,"Error reading from socket\n"); + ret = FAIL; + } + + + // execute action if the arguments correctly arrived +#ifdef SLS_RECEIVER_UDP_FUNCTIONS + if (ret==OK) { + if(value >= 0){ + if (lockStatus==1 && socket->differentClients==1){ + sprintf(mess,"Receiver locked by %s\n", socket->lastClientIP); + ret=FAIL; + } + else if (receiverBase == NULL){ + strcpy(mess,"Receiver not set up\n"); + ret=FAIL; + } + else if(receiverBase->getStatus()==RUNNING){ + strcpy(mess,"Cannot set/get fifo depth while status is running\n"); + ret=FAIL; + } + else{ + if(value >= 0){ + ret = receiverBase->setFifoDepth(value); + } + } + } + + + if (receiverBase == NULL){ + strcpy(mess,"Receiver not set up\n"); + ret=FAIL; + }else{ + retval = receiverBase->getFifoDepth(); + if(value >= 0 && retval != value) + ret = FAIL; + } + + } +#endif + + if(ret==OK && socket->differentClients){ + FILE_LOG(logDEBUG) << "Force update"; + ret=FORCE_UPDATE; + } + + // send answer + socket->SendDataOnly(&ret,sizeof(ret)); + if(ret==FAIL){ + cprintf(RED,"%s\n",mess); + socket->SendDataOnly(mess,sizeof(mess)); + } + socket->SendDataOnly(&retval,sizeof(retval)); + + //return ok/fail + return ret; +} + + + + + + + + + + From 73f8d065b3cbd10e9d4f6471e4703be752e53348 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 17 Nov 2015 12:27:18 +0100 Subject: [PATCH 178/474] empty fifo at receiver start and comment waiting for packet --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 3a6a346e1..cda3bebad 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -956,7 +956,9 @@ void UDPStandardImplementation::startReadout(){ prev = -1; //wait as long as there is change from prev totalP while(prev != totalP){ +#ifdef DEBUG5 cprintf(MAGENTA,"waiting for all packets totalP:%d\n",totalP); +#endif usleep(5000);/* Need to find optimal time (exposure time and acquisition period) **/ prev = totalP; totalP=0; @@ -2240,6 +2242,13 @@ void UDPStandardImplementation::waitWritingBufferForNextAcquisition(int ithread) #endif + //pop fifo so that its empty + char* temp; + while(!fifo[ithread]->isEmpty()){ + cout << ithread << ":emptied buffer in fifo" << endl; + fifo[ithread]->pop(temp); + } + //create file if((1< Date: Tue, 17 Nov 2015 15:27:52 +0100 Subject: [PATCH 179/474] just minor edit changes --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index cda3bebad..00b1283e2 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -959,6 +959,7 @@ void UDPStandardImplementation::startReadout(){ #ifdef DEBUG5 cprintf(MAGENTA,"waiting for all packets totalP:%d\n",totalP); #endif + usleep(5000);/* Need to find optimal time (exposure time and acquisition period) **/ prev = totalP; totalP=0; @@ -2315,14 +2316,11 @@ bool UDPStandardImplementation::popAndCheckEndofAcquisition(int ithread, char* w else{ endofAcquisition = false; #ifdef DEBUG4 - switch(myDetectorType){ - case EIGER: + if(myDetectorType == EIGER){ eiger_packet_footer_t* wbuf_footer = (eiger_packet_footer_t*)(wbuffer[i] + footerOffset + HEADER_SIZE_NUM_TOT_PACKETS); //cprintf(BLUE,"footer value:0x%x\n",i,(uint64_t)(*( (uint64_t*) wbuf_footer))); cprintf(BLUE,"Fnum[%d]:%d\n",i,(uint32_t)(*( (uint64_t*) wbuf_footer))); cprintf(BLUE,"Pnum[%d]:%d\n",i,*( (uint16_t*) wbuf_footer->packetNumber)); - break; - default: break; } #endif if(myDetectorType == EIGER){ From 6600d82fc7f3700d77a6c13ceeb5c4dd1a1d46e1 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Thu, 19 Nov 2015 11:18:35 +0100 Subject: [PATCH 180/474] some small unimportant changes such as removign eiger header structure form generic socket and initializign differentlclients --- slsReceiverSoftware/include/genericSocket.h | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/slsReceiverSoftware/include/genericSocket.h b/slsReceiverSoftware/include/genericSocket.h index aebdd8066..97cd3223e 100644 --- a/slsReceiverSoftware/include/genericSocket.h +++ b/slsReceiverSoftware/include/genericSocket.h @@ -93,12 +93,7 @@ enum communicationProtocol{ UDP /**< UDP */ }; -typedef struct -{ - unsigned char header_before[20]; - unsigned char fnum[4]; - unsigned char header_after[24]; -} eiger_image_header; + genericSocket(const char* const host_ip_or_name, unsigned short int const port_number, communicationProtocol p, int ps = DEFAULT_PACKET_SIZE) : // portno(port_number), @@ -120,6 +115,7 @@ typedef struct strcpy(lastClientIP,"none"); strcpy(thisClientIP,"none1"); strcpy(dummyClientIP,"dummy"); + differentClients = 0; struct hostent *hostInfo = gethostbyname(host_ip_or_name); if (hostInfo == NULL){ @@ -184,6 +180,7 @@ typedef struct strcpy(lastClientIP,"none"); strcpy(thisClientIP,"none1"); strcpy(dummyClientIP,"dummy"); + differentClients = 0; if(serverAddress.sin_port == htons(port_number)){ socketDescriptor = -10; From 8b0772abaec30e3d44482bf2479c947d1b7f4da0 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Thu, 19 Nov 2015 14:21:04 +0100 Subject: [PATCH 181/474] got rid of memory leak when using gui --- .../src/slsReceiverTCPIPInterface.cpp | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp index 403aa7309..4af5e0424 100644 --- a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp +++ b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp @@ -1107,7 +1107,7 @@ int slsReceiverTCPIPInterface::moench_read_frame(){ for(i=0;igetFramesCaught()){ startAcquisitionIndex=-1; #ifdef VERYVERBOSE cout<<"haven't caught any frame yet"<readFrame(fName,&raw,startAcquisitionIndex,startFrameIndex); - - /**send garbage with -1 index to try again*/ + //send garbage with -1 index to try again if (raw == NULL){ startAcquisitionIndex = -1; #ifdef VERYVERBOSE @@ -1675,7 +1676,7 @@ int slsReceiverTCPIPInterface::eiger_read_frame(){ #endif } - /**proper frame*/ + //proper frame else{//cout<<"**** got proper frame ******"< Date: Mon, 23 Nov 2015 11:54:55 +0100 Subject: [PATCH 182/474] some cleanup for rest --- slsReceiverSoftware/include/UDPInterface.h | 6 +- .../include/UDPRESTImplementation.h | 864 +------ .../include/UDPStandardImplementation.h | 10 +- .../src/UDPRESTImplementation.cpp | 2104 +---------------- .../src/UDPStandardImplementation.cpp | 9 +- 5 files changed, 205 insertions(+), 2788 deletions(-) diff --git a/slsReceiverSoftware/include/UDPInterface.h b/slsReceiverSoftware/include/UDPInterface.h index 798c45f6c..b00f038cb 100644 --- a/slsReceiverSoftware/include/UDPInterface.h +++ b/slsReceiverSoftware/include/UDPInterface.h @@ -39,13 +39,17 @@ class UDPInterface { * * set*() : anytime after initialize(), multiple times * - * startReceiver(): anytime after initialize(). Will fail if state already is 'running': + * startReceiver(): anytime after initialize(). Will fail in TCPIP itself if state already is 'running': * * Only startReceiver() does change the data receiver configuration, it does pass the whole configuration cache to the data receiver. * * abort(), //FIXME: needed? * * stopReceiver() : anytime after initialize(). Will do nothing if state already is idle. + * Otherwise, sets status to transmitting when shutting down sockets + * then to run_finished when all data obtained + * then to idle when returning from this function + * * * getStatus() returns the actual state of the data receiver - idle, running or error, enum defined in include/sls_receiver_defs.h * diff --git a/slsReceiverSoftware/include/UDPRESTImplementation.h b/slsReceiverSoftware/include/UDPRESTImplementation.h index f335ba9d2..374199721 100644 --- a/slsReceiverSoftware/include/UDPRESTImplementation.h +++ b/slsReceiverSoftware/include/UDPRESTImplementation.h @@ -7,36 +7,21 @@ ***********************************************/ -#include "sls_receiver_defs.h" -#include "receiver_defs.h" -#include "genericSocket.h" -#include "circularFifo.h" -#include "singlePhotonDetector.h" -#include "slsReceiverData.h" -#include "moenchCommonMode.h" - #include "UDPBaseImplementation.h" - -#ifdef MYROOT1 -#include -#include -#endif - #include "RestHelper.h" - #include -#include #include -#include /** * @short does all the functions for a receiver, set/get parameters, start/stop etc. */ class UDPRESTImplementation : protected virtual slsReceiverDefs, public UDPBaseImplementation { - - public: +public: + /************************************************************************* + * Constructor & Destructor ********************************************** + *************************************************************************/ /** * Constructor */ @@ -49,787 +34,116 @@ class UDPRESTImplementation : protected virtual slsReceiverDefs, public UDPBaseI protected: - void initialize_REST(); + + /************************************************************************* + * Getters *************************************************************** + * They access local cache of configuration or detector parameters ******* + *************************************************************************/ + /** + * Get Rest State + */ int get_rest_state(RestHelper * rest, string *rest_state); + /************************************************************************* + * Setters *************************************************************** + * They modify the local cache of configuration or detector parameters *** + *************************************************************************/ + /** + * Initialize REST + */ + void initialize_REST(); + + + + public: + /************************************************************************* + * Getters *************************************************************** + * They access local cache of configuration or detector parameters ******* + *************************************************************************/ + + + /************************************************************************* + * Setters *************************************************************** + * They modify the local cache of configuration or detector parameters *** + *************************************************************************/ + + /** + * Overridden method + * Configure command line parameters + * @param config_map mapping of config parameters passed from command line arguments + */ void configure(map config_map); - /** - * delete and free member parameters - */ - void deleteMembers(); + + /************************************************************************* + * Behavioral functions*************************************************** + * They may modify the status of the receiver **************************** + *************************************************************************/ /** - * initialize member parameters + * Overridden method + * Start Listening for Packets by activating all configuration settings to receiver + * When this function returns, it has status RUNNING(upon SUCCESS) or IDLE (upon failure) + * @param c error message if FAIL + * @return OK or FAIL */ - //void initializeMembers(); + int startReceiver(char *c=NULL); /** - * Set detector hostname - * @param c hostname + * Overridden method + * Stop Listening for Packets + * Calls startReadout(), which stops listening and sets status to Transmitting + * When it has read every frame in buffer, the status changes to Run_Finished + * When this function returns, receiver has status IDLE + * Pre: status is running, semaphores have been instantiated, + * Post: udp sockets shut down, status is idle, semaphores destroyed */ - //void initialize(const char *detectorHostName); - - /* Returns detector hostname - /returns hostname - * caller needs to deallocate the returned char array. - * if uninitialized, it must return NULL - */ - //char *getDetectorHostname() const; - + void stopReceiver(); /** - * Set receiver type - * @param det detector type - * Returns success or FAIL - */ - //int setDetectorType(detectorType det); - - - //Frame indices and numbers caught - /** - * Returns the frame index at start of entire acquisition (including all scans) - */ - uint32_t getStartAcquisitionIndex(); - - /** - * Returns current Frame Index Caught for an entire acquisition (including all scans) - */ - uint32_t getAcquisitionIndex(); - - /** - * Returns if acquisition started - */ - bool getAcquistionStarted(); - - /** - * Returns Frames Caught for each real time acquisition (eg. for each scan) - */ - int getFramesCaught(); - - /** - * Returns Total Frames Caught for an entire acquisition (including all scans) - */ - int getTotalFramesCaught(); - - /** - * Returns the frame index at start of each real time acquisition (eg. for each scan) - */ - uint32_t getStartFrameIndex(); - - /** - * Returns current Frame Index for each real time acquisition (eg. for each scan) - */ - uint32_t getFrameIndex(); - - /** - * Returns if measurement started - */ - bool getMeasurementStarted(); - - /** - * Resets the Total Frames Caught - * This is how the receiver differentiates between entire acquisitions - * Returns 0 - */ - void resetTotalFramesCaught(); - - - - - //file parameters - /** - * Returns File Path - */ - //char* getFilePath() const; - - /** - * Set File Path - * @param c file path - */ - //char* setFilePath(const char c[]); - - /** - * Returns File Name - */ - //char* getFileName() const; - - /** - * Set File Name (without frame index, file index and extension) - * @param c file name - */ - //char* setFileName(const char c[]); - - /** - * Returns File Index - */ - int getFileIndex(); - - /** - * Set File Index - * @param i file index - */ - int setFileIndex(int i); - - /** - * Set Frame Index Needed - * @param i frame index needed - */ - int setFrameIndexNeeded(int i); - - /** - * Set enable file write - * @param i file write enable - * Returns file write enable - */ - //int setEnableFileWrite(int i); - - /** - * Enable/disable overwrite - * @param i enable - * Returns enable over write - */ - //int setEnableOverwrite(int i); - - /** - * Returns file write enable - * 1: YES 0: NO - */ - //int getEnableFileWrite() const; - - /** - * Returns file over write enable - * 1: YES 0: NO - */ - //int getEnableOverwrite() const; - -//other parameters - - /** - * abort acquisition with minimum damage: close open files, cleanup. - * does nothing if state already is 'idle' - */ - void abort() {}; - - /** - * Returns status of receiver: idle, running or error - */ - runStatus getStatus() const; - - - /** - * Set Ethernet Interface or IP to listen to - */ - void setEthernetInterface(char* c); - - /** - * Set UDP Port Number - */ - void setUDPPortNo(int p); - void setUDPPortNo2(int p); - - /* - * Returns number of frames to receive - * This is the number of frames to expect to receiver from the detector. - * The data receiver will change from running to idle when it got this number of frames - */ - - //int getNumberOfFrames() const; - - /** - * set frame number if a positive number - */ - //int32_t setNumberOfFrames(int32_t fnum); - - - /** - * Returns scan tag - */ - //int getScanTag() const; - - /** - * set scan tag if its is a positive number - */ - //int32_t setScanTag(int32_t stag); - - /** - * Returns the number of bits per pixel - */ - //int getDynamicRange() const; - - /** - * set dynamic range if its is a positive number - */ - int32_t setDynamicRange(int32_t dr); - - /** - * Set short frame - * @param i if shortframe i=1 - */ - int setShortFrame(int i); - - /** - * Set the variable to send every nth frame to gui - * or if 0,send frame only upon gui request - */ - int setNFrameToGui(int i); - - /** set acquisition period if a positive number - */ - int64_t setAcquisitionPeriod(int64_t index); - - /** get data compression, by saving only hits - */ - bool getDataCompression(); - - /** enabl data compression, by saving only hits - /returns if failed - */ - int enableDataCompression(bool enable); - - /** - * enable 10Gbe - @param enable 1 for 10Gbe or 0 for 1 Gbe, -1 to read out - \returns enable for 10Gbe - */ - int enableTenGiga(int enable = -1); - - - -//other functions - - /** - * Returns the buffer-current frame read by receiver - * @param c pointer to current file name - * @param raw address of pointer, pointing to current frame to send to gui - * @param fnum frame number for eiger as it is not in the packet - * @param startAcquisitionIndex is the start index of the acquisition - * @param startFrameIndex is the start index of the scan - */ - void readFrame(char* c,char** raw, uint32_t &fnum, uint32_t &startAcquisitionIndex, uint32_t &startFrameIndex); - - /** - * Closes all files - * @param ithr thread index - */ - void closeFile(int ithr = -1); - - /** - * Starts Receiver - starts to listen for packets - * @param message is the error message if there is an error - * Returns success - */ - int startReceiver(char message[]); - - /** - * Stops Receiver - stops listening for packets - * Returns success - */ - int stopReceiver(); - - /** set status to transmitting and - * when fifo is empty later, sets status to run_finished + * Overridden method + * Stop Listening to Packets + * and sets status to Transmitting + * Next step would be to get all data and stop receiver completely and return with idle state + * Pre: status is running, udp sockets have been initialized, stop receiver initiated + * Post:udp sockets closed, status is transmitting, */ void startReadout(); /** - * shuts down the udp sockets - * \returns if success or fail + * Overridden method + * Shuts down and deletes UDP Sockets + * TCPIPInterface can also call this in case of illegal shutdown of receiver + * @return OK or FAIL */ int shutDownUDPSockets(); + /** + * Overridden method + * Get the buffer-current frame read by receiver + * @param c pointer to current file name + * @param raw address of pointer, pointing to current frame to send to gui + * @param startAcq start index of the acquisition + * @param startFrame start index of the scan + */ + void readFrame(char* c,char** raw, uint64_t &startAcq, uint64_t &startFrame); + + /** + * Overridden method + * Closes file / all files(data compression involves multiple files) + * TCPIPInterface can also call this in case of illegal shutdown of receiver + * @param i thread index valid for datacompression using root files, -1 for all threads + */ + void closeFile(int i = -1); + private: - /* - void not_implemented(string method_name){ - std::cout << "[WARNING] Method " << method_name << " not implemented!" << std::endl; - }; - */ - /** - * Deletes all the filter objects for single photon data - */ - void deleteFilter(); - - /** - * Constructs the filter for single photon data - */ - void setupFilter(); - - /** - * set up fifo according to the new numjobsperthread - */ - void setupFifoStructure (); - - /** - * Copy frames to gui - * uses semaphore for nth frame mode - */ - void copyFrameToGui(char* startbuf[], uint32_t fnum=-1, char* buf=NULL); - - /** - * creates udp sockets - * \returns if success or fail - */ - int createUDPSockets(); - - /** - * create listening thread - * @param destroy is true to kill all threads and start again - */ - int createListeningThreads(bool destroy = false); - - /** - * create writer threads - * @param destroy is true to kill all threads and start again - */ - int createWriterThreads(bool destroy = false); - - /** - * set thread priorities - */ - void setThreadPriorities(); - - /** - * initializes variables and creates the first file - * also does the startAcquisitionCallBack - * \returns FAIL or OK - */ - int setupWriter(); - - /** - * Creates new tree and file for compression - * @param ithr thread number - * @param iframe frame number - *\returns OK for succces or FAIL for failure - */ - int createCompressionFile(int ithr, int iframe); - - /** - * Creates new file - *\returns OK for succces or FAIL for failure - */ - int createNewFile(); - - /** - * Static function - Thread started which listens to packets. - * Called by startReceiver() - * @param this_pointer pointer to this object - */ - static void* startListeningThread(void *this_pointer); - - /** - * Static function - Thread started which writes packets to file. - * Called by startReceiver() - * @param this_pointer pointer to this object - */ - static void* startWritingThread(void *this_pointer); - - /** - * Thread started which listens to packets. - * Called by startReceiver() - * - */ - int startListening(); - - /** - * Thread started which writes packets to file. - * Called by startReceiver() - * - */ - int startWriting(); - - /** - * Writing to file without compression - * @param buf is the address of buffer popped out of fifo - * @param numpackets is the number of packets - * @param framenum current frame number - */ - void writeToFile_withoutCompression(char* buf,int numpackets, uint32_t framenum); - - /** - * Its called for the first packet of a scan or acquistion - * Sets the startframeindices and the variables to know if acquisition started - * @param ithread listening thread number - */ - void startFrameIndices(int ithread); - - /** - * This is called when udp socket is shut down - * It pops ffff instead of packet number into fifo - * to inform writers about the end of listening session - * @param ithread listening thread number - * @param rc number of bytes received - * @param pc packet count - * @param t total packets listened to - */ - void stopListening(int ithread, int rc, int &pc, int &t); - - /** - * When acquisition is over, this is called - * @param ithread listening thread number - * @param wbuffer writer buffer - */ - void stopWriting(int ithread, char* wbuffer[]); - - - /** - * data compression for each fifo output - * @param ithread listening thread number - * @param wbuffer writer buffer - * @param npackets number of packets from the fifo - * @param data pointer to the next packet start - * @param xmax max pixels in x direction - * @param ymax max pixels in y direction - * @param nf nf - */ - void handleDataCompression(int ithread, char* wbuffer[], int &npackets, char* data, int xmax, int ymax, int &nf); - - - /** structure of an eiger image header*/ - typedef struct - { - unsigned char header_before[20]; - unsigned char fnum[4]; - unsigned char header_after[24]; - } eiger_image_header; - - - /** structure of an eiger image header*/ - typedef struct - { - unsigned char num1[4]; - unsigned char num2[4]; - } eiger_packet_header; - - /** max number of listening threads */ - const static int MAX_NUM_LISTENING_THREADS = EIGER_MAX_PORTS; - - /** max number of writer threads */ - const static int MAX_NUM_WRITER_THREADS = 15; - - /** detector type */ - //detectorType myDetectorType; - - /** detector hostname */ - //char detHostname[MAX_STR_LENGTH]; - - /** status of receiver */ - //runStatus status; - - /** UDP Socket between Receiver and Detector */ - //genericSocket* udpSocket[MAX_NUM_LISTENING_THREADS]; - - /** Server UDP Port*/ - //int server_port[MAX_NUM_LISTENING_THREADS]; - - /** ethernet interface or IP to listen to */ - //char *eth; - - /** max packets per file **/ - //int maxPacketsPerFile; - - /** File write enable */ - //int enableFileWrite; - - /** File over write enable */ - //int overwrite; - - /** Complete File name */ - //char savefilename[MAX_STR_LENGTH]; - - /** File Name without frame index, file index and extension*/ - //char fileName[MAX_STR_LENGTH]; - - /** File Path */ - //char filePath[MAX_STR_LENGTH]; - - /** File Index */ - //int fileIndex; - - /** scan tag */ - //int scanTag; - - /** if frame index required in file name */ - //int frameIndexNeeded; - - /* Acquisition started */ - //bool acqStarted; - - /* Measurement started */ - //bool measurementStarted; - - /** Frame index at start of each real time acquisition (eg. for each scan) */ - //uint32_t startFrameIndex; - - /** Actual current frame index of each time acquisition (eg. for each scan) */ - //uint32_t frameIndex; - - /** Frames Caught for each real time acquisition (eg. for each scan) */ - //int packetsCaught; - - /** Total packets caught for an entire acquisition (including all scans) */ - //int totalPacketsCaught; - - /** Pckets currently in current file, starts new file when it reaches max */ - //int packetsInFile; - - /** Frame index at start of an entire acquisition (including all scans) */ - //uint32_t startAcquisitionIndex; - - /** Actual current frame index of an entire acquisition (including all scans) */ - //uint32_t acquisitionIndex; - - /** number of packets per frame*/ - //int packetsPerFrame; - - /** frame index mask */ - //uint32_t frameIndexMask; - - /** packet index mask */ - //uint32_t packetIndexMask; - - /** frame index offset */ - //int frameIndexOffset; - - /** acquisition period */ - //int64_t acquisitionPeriod; - - /** frame number */ - //int32_t numberOfFrames; - - /** dynamic range */ - //int dynamicRange; - - /** short frames */ - //int shortFrame; - - /** current frame number */ - //uint32_t currframenum; - - /** Previous Frame number from buffer */ - //uint32_t prevframenum; - - /** size of one frame */ - //int frameSize; - - /** buffer size. different from framesize as we wait for one packet instead of frame for eiger */ - //int bufferSize; - - /** oen buffer size */ - //int onePacketSize; - - /** latest data */ - //char* latestData; - - /** gui data ready */ - //int guiDataReady; - - /** points to the data to send to gui */ - //char* guiData; - - /** points to the filename to send to gui */ - //char* guiFileName; - - /** temporary number for eiger frame number as its not included in the packet */ - //uint32_t guiFrameNumber; - - /** send every nth frame to gui or only upon gui request*/ - //int nFrameToGui; - - /** fifo size */ - //unsigned int fifosize; - - /** number of jobs per thread for data compression */ - //int numJobsPerThread; - - /** datacompression - save only hits */ - //bool dataCompression; - - /** memory allocated for the buffer */ - //char *mem0[MAX_NUM_LISTENING_THREADS]; - - /** circular fifo to store addresses of data read */ - //CircularFifo* fifo[MAX_NUM_LISTENING_THREADS]; - - /** circular fifo to store addresses of data already written and ready to be resued*/ - //CircularFifo* fifoFree[MAX_NUM_LISTENING_THREADS]; - - /** Receiver buffer */ - //char *buffer[MAX_NUM_LISTENING_THREADS]; - - /** number of writer threads */ - //intt numListeningThreads; - - /** number of writer threads */ - //int numWriterThreads; - - /** to know if listening and writer threads created properly */ - //int thread_started; - - /** current listening thread index*/ - //int currentListeningThreadIndex; - - /** current writer thread index*/ - //int currentWriterThreadIndex; - - /** thread listening to packets */ - //pthread_t listening_thread[MAX_NUM_LISTENING_THREADS]; - - /** thread writing packets */ - //pthread_t writing_thread[MAX_NUM_WRITER_THREADS]; - - /** total frame count the listening thread has listened to */ - //int totalListeningFrameCount[MAX_NUM_LISTENING_THREADS]; - - /** mask showing which listening threads are running */ - //volatile uint32_t listeningthreads_mask; - - /** mask showing which writer threads are running */ - //volatile uint32_t writerthreads_mask; - - /** mask showing which threads have created files*/ - //volatile uint32_t createfile_mask; - - /** OK if file created was successful */ - //int ret_createfile; - - /** variable used to self terminate threads waiting for semaphores */ - //int killAllListeningThreads; - - /** variable used to self terminate threads waiting for semaphores */ - //int killAllWritingThreads; - - /** 10Gbe enable*/ - //int tengigaEnable; - - - - -//semaphores - /** semaphore to synchronize writer and guireader threads */ - //sem_t smp; - /** semaphore to synchronize listener threads */ - //sem_t listensmp[MAX_NUM_LISTENING_THREADS]; - /** semaphore to synchronize writer threads */ - //sem_t writersmp[MAX_NUM_WRITER_THREADS]; - - -//mutex - /** guiDataReady mutex */ - //pthread_mutex_t dataReadyMutex; - - /** mutex for status */ - //pthread_mutex_t status_mutex; - - /** mutex for progress variable currframenum */ - //pthread_mutex_t progress_mutex; - - /** mutex for writing data to file */ - //pthread_mutex_t write_mutex; - - /** File Descriptor */ - //FILE *sfilefd; - - //filter - //singlePhotonDetector *singlePhotonDet[MAX_NUM_WRITER_THREADS]; - //slsReceiverData *receiverdata[MAX_NUM_WRITER_THREADS]; - //moenchCommonMode *cmSub; - //bool commonModeSubtractionEnable; - -#ifdef MYROOT1 - /** Tree where the hits are stored */ - TTree *myTree[MAX_NUM_WRITER_THREADS]; - - /** File where the tree is saved */ - TFile *myFile[MAX_NUM_WRITER_THREADS]; -#endif - - - - /** - callback arguments are - filepath - filename - fileindex - data size - - return value is - 0 callback takes care of open,close,write file - 1 callback writes file, we have to open, close it - 2 we open, close, write file, callback does not do anything - - */ - int (*startAcquisitionCallBack)(char*, char*,int, int, void*); - void *pStartAcquisition; - - /** - args to acquisition finished callback - total frames caught - - */ - void (*acquisitionFinishedCallBack)(int, void*); - void *pAcquisitionFinished; - - - /** - args to raw data ready callback are - framenum - datapointer - datasize in bytes - file descriptor - guidatapointer (NULL, no data required) - */ - void (*rawDataReadyCallBack)(int, char*, int, FILE*, char*, void*); - void *pRawDataReady; - - /** The action which decides what the user and default responsibilites to save data are - * 0 raw data ready callback takes care of open,close,write file - * 1 callback writes file, we have to open, close it - * 2 we open, close, write file, callback does not do anything */ - int cbAction; - - -public: - - - /** - callback arguments are - filepath - filename - fileindex - datasize - - return value is - 0 callback takes care of open,close,wrie file - 1 callback writes file, we have to open, close it - 2 we open, close, write file, callback does not do anything - */ - void registerCallBackStartAcquisition(int (*func)(char*, char*,int, int, void*),void *arg){startAcquisitionCallBack=func; pStartAcquisition=arg;}; - - /** - callback argument is - toatal frames caught - */ - void registerCallBackAcquisitionFinished(void (*func)(int, void*),void *arg){acquisitionFinishedCallBack=func; pAcquisitionFinished=arg;}; - - /** - args to raw data ready callback are - framenum - datapointer - datasize in bytes - file descriptor - guidatapointer (NULL, no data required) - */ - void registerCallBackRawDataReady(void (*func)(int, char*, int, FILE*, char*, void*),void *arg){rawDataReadyCallBack=func; pRawDataReady=arg;}; - - - //REST specific bool isInitialized; RestHelper * rest ; - int rest_port; // receiver backend port - string rest_hostname; // receiver hostname + int rest_port; // receiver backend port + string rest_hostname; // receiver hostname }; diff --git a/slsReceiverSoftware/include/UDPStandardImplementation.h b/slsReceiverSoftware/include/UDPStandardImplementation.h index 3c256450a..7ec6672aa 100644 --- a/slsReceiverSoftware/include/UDPStandardImplementation.h +++ b/slsReceiverSoftware/include/UDPStandardImplementation.h @@ -8,8 +8,6 @@ #include "UDPBaseImplementation.h" -//#include "sls_receiver_defs.h" -//#include "receiver_defs.h" #include "genericSocket.h" #include "circularFifo.h" #include "singlePhotonDetector.h" @@ -39,7 +37,6 @@ class UDPStandardImplementation: private virtual slsReceiverDefs, public UDPBase /************************************************************************* * Constructor & Destructor ********************************************** - * They access local cache of configuration or detector parameters ******* *************************************************************************/ /** * Constructor @@ -155,6 +152,7 @@ class UDPStandardImplementation: private virtual slsReceiverDefs, public UDPBase /** * Overridden method * Start Listening for Packets by activating all configuration settings to receiver + * When this function returns, it has status RUNNING(upon SUCCESS) or IDLE (upon failure) * @param c error message if FAIL * @return OK or FAIL */ @@ -164,7 +162,8 @@ class UDPStandardImplementation: private virtual slsReceiverDefs, public UDPBase * Overridden method * Stop Listening for Packets * Calls startReadout(), which stops listening and sets status to Transmitting - * When it has read every frame in buffer,it returns with the status Run_Finished + * When it has read every frame in buffer, the status changes to Run_Finished + * When this function returns, receiver has status IDLE * Pre: status is running, semaphores have been instantiated, * Post: udp sockets shut down, status is idle, semaphores destroyed */ @@ -174,6 +173,7 @@ class UDPStandardImplementation: private virtual slsReceiverDefs, public UDPBase * Overridden method * Stop Listening to Packets * and sets status to Transmitting + * Next step would be to get all data and stop receiver completely and return with idle state * Pre: status is running, udp sockets have been initialized, stop receiver initiated * Post:udp sockets closed, status is transmitting */ @@ -182,6 +182,7 @@ class UDPStandardImplementation: private virtual slsReceiverDefs, public UDPBase /** * Overridden method * Shuts down and deletes UDP Sockets + * TCPIPInterface can also call this in case of illegal shutdown of receiver * @return OK or FAIL */ int shutDownUDPSockets(); @@ -199,6 +200,7 @@ class UDPStandardImplementation: private virtual slsReceiverDefs, public UDPBase /** * Overridden method * Closes file / all files(data compression involves multiple files) + * TCPIPInterface can also call this in case of illegal shutdown of receiver * @param i thread index valid for datacompression using root files, -1 for all threads */ void closeFile(int i = -1); diff --git a/slsReceiverSoftware/src/UDPRESTImplementation.cpp b/slsReceiverSoftware/src/UDPRESTImplementation.cpp index 4b2b67e4b..ab650257f 100644 --- a/slsReceiverSoftware/src/UDPRESTImplementation.cpp +++ b/slsReceiverSoftware/src/UDPRESTImplementation.cpp @@ -7,32 +7,21 @@ #include "UDPRESTImplementation.h" -#include "moench02ModuleData.h" -#include "gotthardModuleData.h" -#include "gotthardShortModuleData.h" - - -#include // SIGINT -#include // stat -#include // socket(), bind(), listen(), accept(), shut down -#include // sock_addr_in, htonl, INADDR_ANY #include // exit() #include // set precision -#include // munmap - -#include +#include // map #include +#include +#include #include - //#include "utilities.h" - using namespace std; /* TODO + filePath != getFilePath + better state handling. Now it is only IDLE - RUNNING - IDLE -*/ + */ UDPRESTImplementation::UDPRESTImplementation(){ @@ -40,6 +29,8 @@ UDPRESTImplementation::UDPRESTImplementation(){ //TODO I do not really know what to do with bottom... // Default values + isInitialized = false; + rest = NULL; rest_hostname = "localhost"; rest_port = 8081; } @@ -69,9 +60,9 @@ void UDPRESTImplementation::configure(map config_map){ for(map::const_iterator i=config_map.begin(); i != config_map.end(); i++){ std::cout << i->first << " " << i->second<< std::endl; } - */ + */ -}; +} int UDPRESTImplementation::get_rest_state(RestHelper * rest, string *rest_state){ @@ -84,13 +75,14 @@ int UDPRESTImplementation::get_rest_state(RestHelper * rest, string *rest_state) } return code; -}; +} + void UDPRESTImplementation::initialize_REST(){ - + FILE_LOG(logDEBUG) << __AT__ << " called"; FILE_LOG(logDEBUG) << __AT__ << " REST status is initialized: " << isInitialized; - + if (rest_hostname.empty()) { FILE_LOG(logDEBUG) << __AT__ <<"can't initialize with empty string or NULL for detectorHostname"; } @@ -99,7 +91,7 @@ void UDPRESTImplementation::initialize_REST(){ } else { FILE_LOG(logDEBUG) << __AT__ << "with receiverHostName=" << rest_hostname << ":" << rest_port; - + rest = new RestHelper() ; std::string answer; int code; @@ -107,7 +99,7 @@ void UDPRESTImplementation::initialize_REST(){ rest->init(rest_hostname, rest_port); code = get_rest_state(rest, &answer); std::cout << "AAAAAAAa " << answer << std::endl; - + if (code != 0){ FILE_LOG(logERROR) << __AT__ << " REST state returned: " << answer; @@ -123,21 +115,21 @@ void UDPRESTImplementation::initialize_REST(){ FILE_LOG(logERROR) << __func__ << ": " << e; throw; } - + //JsonBox::Object json_object; //json_object["configfile"] = JsonBox::Value("FILENAME"); JsonBox::Value json_request; //json_request["configfile"] = "config.py"; json_request["path"] = filePath; - + stringstream ss; string test; //std::cout << "GetSTring: " << json_request << std::endl; json_request.writeToStream(ss, false); //ss << json_request; ss >> test; - - + + code = rest->get_json("state", &answer); FILE_LOG(logDEBUG) << __AT__ << " state got " << code << " " << answer << "\n"; if (answer != "INITIALIZED"){ @@ -151,8 +143,8 @@ void UDPRESTImplementation::initialize_REST(){ FILE_LOG(logDEBUG) << __AT__ << " state/configure got " << code; code = rest->get_json("state", &answer); FILE_LOG(logDEBUG) << __AT__ << " state got " << code << " " << answer << "\n"; - - + + /* std::std::cout << string << std::endl; << "---- REST test 3: true, json object "<< std::endl; JsonBox::Value json_value; @@ -160,566 +152,53 @@ void UDPRESTImplementation::initialize_REST(){ std::cout << "JSON " << json_value["status"] << std::endl; */ } - + FILE_LOG(logDEBUG) << __func__ << ": initialize() done"; } -/* -int UDPRESTImplementation::setDetectorType(detectorType det){ - cout << "[WARNING] This is a base implementation, " << __func__ << " not correctly implemented" << endl; - return OK; -} -*/ - - -/*Frame indices and numbers caught*/ - -bool UDPRESTImplementation::getAcquistionStarted(){ - FILE_LOG(logDEBUG) << __AT__ << " called"; - return acqStarted; -}; - -bool UDPRESTImplementation::getMeasurementStarted(){ - FILE_LOG(logDEBUG) << __AT__ << " called"; - return measurementStarted; -}; - -int UDPRESTImplementation::getFramesCaught(){ - FILE_LOG(logDEBUG) << __AT__ << " called"; - return (packetsCaught/packetsPerFrame); -} - -int UDPRESTImplementation::getTotalFramesCaught(){ - FILE_LOG(logDEBUG) << __AT__ << " called"; - if (packetsPerFrame == 0){ - FILE_LOG(logWARNING) << __AT__ << " packetsPerFrame is 0!!!"; - return 0; - } - return (totalPacketsCaught/packetsPerFrame); -} - -uint32_t UDPRESTImplementation::getStartAcquisitionIndex(){ - FILE_LOG(logDEBUG) << __AT__ << " called"; - return startAcquisitionIndex; -} - -uint32_t UDPRESTImplementation::getStartFrameIndex(){ - FILE_LOG(logDEBUG) << __AT__ << " called"; - return startFrameIndex; -} - -uint32_t UDPRESTImplementation::getFrameIndex(){ - FILE_LOG(logDEBUG) << __AT__ << " called"; - - if(!packetsCaught) - frameIndex=-1; - else - frameIndex = currframenum - startFrameIndex; - return frameIndex; -} - - -uint32_t UDPRESTImplementation::getAcquisitionIndex(){ - //FILE_LOG(logDEBUG) << __AT__ << " called, idx: " << acquisitionIndex; - if(!totalPacketsCaught) - acquisitionIndex = -1; - else - acquisitionIndex = currframenum - startAcquisitionIndex; - - //FILE_LOG(logDEBUG) << __AT__ << " idx: " << acquisitionIndex - // << " currframenum: " << currframenum - // << " startAcqIdx: " << startAcquisitionIndex; - - return acquisitionIndex; -} - - -void UDPRESTImplementation::resetTotalFramesCaught(){ - FILE_LOG(logDEBUG) << __AT__ << " called"; - acqStarted = false; - startAcquisitionIndex = 0; - totalPacketsCaught = 0; -} - - -/*file parameters*/ -int UDPRESTImplementation::getFileIndex(){ - FILE_LOG(logDEBUG) << __AT__ << " called"; - return fileIndex; -} - -int UDPRESTImplementation::setFileIndex(int i){ - FILE_LOG(logDEBUG) << __AT__ << " called"; - - if(i>=0) - fileIndex = i; - - return getFileIndex(); -} - - -int UDPRESTImplementation::setFrameIndexNeeded(int i){ - FILE_LOG(logDEBUG) << __AT__ << " called"; - frameIndexNeeded = i; - return frameIndexNeeded; -} - - -/* -int UDPRESTImplementation::getEnableFileWrite() const{ - return enableFileWrite; -} - -int UDPRESTImplementation::setEnableFileWrite(int i){ - enableFileWrite=i; - return getEnableFileWrite(); -} - -int UDPRESTImplementation::getEnableOverwrite() const{ - return overwrite; -} - -int UDPRESTImplementation::setEnableOverwrite(int i){ - overwrite=i; - return getEnableOverwrite(); -} -*/ - - - - -/*other parameters*/ - -slsReceiverDefs::runStatus UDPRESTImplementation::getStatus() const{ - FILE_LOG(logDEBUG) << __AT__ << " called, status: " << status; - return status; -} - - - -/* -char *UDPRESTImplementation::getDetectorHostname() const{ - return (char*)detHostname; -} -*/ - -void UDPRESTImplementation::setEthernetInterface(char* c){ - FILE_LOG(logDEBUG) << __FILE__ << "::" << __func__ << " starting"; - - // TODO: this segfaults - //strcpy(eth,c); - //FILE_LOG(logDEBUG) << __FILE__ << "::" << __func__ << " done"; -} - -/* -void UDPRESTImplementation::setUDPPortNo(int p){ - FILE_LOG(logDEBUG) << __AT__ << " called"; - for(int i=0;i= 0) - numberOfFrames = fnum; - - return getNumberOfFrames(); -} -*/ -/* -int UDPRESTImplementation::getScanTag() const{ - return scanTag; -} -*/ - -/* -int32_t UDPRESTImplementation::setScanTag(int32_t stag){ - if(stag >= 0) - scanTag = stag; - - return getScanTag(); -} -*/ - -int32_t UDPRESTImplementation::setDynamicRange(int32_t dr){ - FILE_LOG(logDEBUG) << __FILE__ << "::" << __func__ << " starting"; - - int olddr = dynamicRange; - if(dr >= 0){ - dynamicRange = dr; - } - - FILE_LOG(logDEBUG) << __FILE__ << "::" << __func__ << " " << getDynamicRange(); - return getDynamicRange(); - - -} - -/* -int32_t UDPRESTImplementation::getDynamicRange() const{ - FILE_LOG(logDEBUG) << __FILE__ << "::" << __func__ << " starting"; - - return dynamicRange; -} -*/ - -int UDPRESTImplementation::setShortFrame(int i){ - FILE_LOG(logDEBUG) << __AT__ << " called"; - shortFrame=i; - - if(shortFrame!=-1){ - bufferSize = GOTTHARD_SHORT_ONE_PACKET_SIZE; - frameSize = GOTTHARD_SHORT_BUFFER_SIZE; - maxPacketsPerFile = SHORT_MAX_FRAMES_PER_FILE * GOTTHARD_SHORT_PACKETS_PER_FRAME; - packetsPerFrame = GOTTHARD_SHORT_PACKETS_PER_FRAME; - frameIndexMask = GOTTHARD_SHORT_FRAME_INDEX_MASK; - frameIndexOffset = GOTTHARD_SHORT_FRAME_INDEX_OFFSET; - - }else{ - onePacketSize = GOTTHARD_ONE_PACKET_SIZE; - bufferSize = GOTTHARD_BUFFER_SIZE; - frameSize = GOTTHARD_BUFFER_SIZE; - maxPacketsPerFile = MAX_FRAMES_PER_FILE * GOTTHARD_PACKETS_PER_FRAME; - packetsPerFrame = GOTTHARD_PACKETS_PER_FRAME; - frameIndexMask = GOTTHARD_FRAME_INDEX_MASK; - frameIndexOffset = GOTTHARD_FRAME_INDEX_OFFSET; - } - - - deleteFilter(); - if(dataCompression) - setupFilter(); - - return shortFrame; -} - - -int UDPRESTImplementation::setNFrameToGui(int i){ - FILE_LOG(logDEBUG) << __AT__ << " called"; - if(i>=0){ - nFrameToGui = i; - setupFifoStructure(); - } - return nFrameToGui; -} - - - -int64_t UDPRESTImplementation::setAcquisitionPeriod(int64_t index){ - FILE_LOG(logDEBUG) << __AT__ << " called"; - if(index >= 0){ - if(index != acquisitionPeriod){ - acquisitionPeriod = index; - setupFifoStructure(); - } - } - return acquisitionPeriod; -} - - -bool UDPRESTImplementation::getDataCompression(){ - FILE_LOG(logDEBUG) << __AT__ << " called"; - return dataCompression; -} - -int UDPRESTImplementation::enableDataCompression(bool enable){ - FILE_LOG(logDEBUG) << __AT__ << " called, doing nothing"; - return OK; -} - - - -/*other functions*/ - - -void UDPRESTImplementation::deleteFilter(){ - FILE_LOG(logDEBUG) << __AT__ << " called"; - int i; - cmSub=NULL; - - for(i=0;i(receiverdata[i], csize, sigma, sign, cmSub); - -} - - - -//LEO: it is not clear to me.. -void UDPRESTImplementation::setupFifoStructure(){ - FILE_LOG(logDEBUG) << __AT__ << " called, doing nothing"; -} -/* -void UDPRESTImplementation::setupFifoStructure(){ - FILE_LOG(logDEBUG) << __AT__ << " called"; - - int64_t i; - int oldn = numJobsPerThread; - - //if every nth frame mode - if(nFrameToGui) - numJobsPerThread = nFrameToGui; - - //random nth frame mode - else{ - if(!acquisitionPeriod) - i = SAMPLE_TIME_IN_NS; - else - i = SAMPLE_TIME_IN_NS/acquisitionPeriod; - if (i > MAX_JOBS_PER_THREAD) - numJobsPerThread = MAX_JOBS_PER_THREAD; - else if (i < 1) - numJobsPerThread = 1; - else - numJobsPerThread = i; - } - - //if same, return - if(oldn == numJobsPerThread) - return; - - if(myDetectorType == EIGER) - numJobsPerThread = 1; - - //otherwise memory too much if numjobsperthread is at max = 1000 - fifosize = GOTTHARD_FIFO_SIZE; - if(myDetectorType == MOENCH) - fifosize = MOENCH_FIFO_SIZE; - else if(myDetectorType == EIGER) - fifosize = EIGER_FIFO_SIZE; - - if(fifosize % numJobsPerThread) - fifosize = (fifosize/numJobsPerThread)+1; - else - fifosize = fifosize/numJobsPerThread; - - - cout << "Number of Frames per buffer:" << numJobsPerThread << endl; - cout << "Fifo Size:" << fifosize << endl; - - - for(int i=0;iisEmpty()) - fifoFree[i]->pop(buffer[i]); - delete fifoFree[i]; - } - if(fifo[i]) delete fifo[i]; - if(mem0[i]) free(mem0[i]); - fifoFree[i] = new CircularFifo(fifosize); - fifo[i] = new CircularFifo(fifosize); - - - //allocate memory - mem0[i]=(char*)malloc((bufferSize * numJobsPerThread + HEADER_SIZE_NUM_TOT_PACKETS)*fifosize); - // shud let the client know about this - if (mem0[i]==NULL){ - cout<<"++++++++++++++++++++++ COULD NOT ALLOCATE MEMORY FOR LISTENING !!!!!!!+++++++++++++++++++++" << endl; - exit(-1); - } - buffer[i]=mem0[i]; - //push the addresses into freed fifoFree and writingFifoFree - while (buffer[i]<(mem0[i]+(bufferSize * numJobsPerThread + HEADER_SIZE_NUM_TOT_PACKETS)*(fifosize-1))) { - fifoFree[i]->push(buffer[i]); - buffer[i]+=(bufferSize * numJobsPerThread + HEADER_SIZE_NUM_TOT_PACKETS); - } - } - cout << "Fifo structure(s) reconstructed" << endl; -} -*/ - - - /** acquisition functions */ -void UDPRESTImplementation::readFrame(char* c,char** raw, uint32_t &fnum, uint32_t &startAcquisitionIndex, uint32_t &startFrameIndex){ - FILE_LOG(logDEBUG) << __AT__ << " called"; - //point to gui data - if (guiData == NULL){ - guiData = latestData; - } - - //copy data and filename - strcpy(c,guiFileName); - fnum = guiFrameNumber; - startAcquisitionIndex = getStartAcquisitionIndex(); - startFrameIndex = getStartFrameIndex(); - //could not get gui data - if(!guiDataReady){ - *raw = NULL; - } - //data ready, set guidata to receive new data - else{ - *raw = guiData; - guiData = NULL; - if((nFrameToGui) && (writerthreads_mask)){ - //release after getting data - sem_post(&smp); - } - } -} - - - - - -void UDPRESTImplementation::copyFrameToGui(char* startbuf[], uint32_t fnum, char* buf){ - FILE_LOG(logDEBUG) << __AT__ << " called"; - - //random read when gui not ready - if((!nFrameToGui) && (!guiData)){ - pthread_mutex_lock(&dataReadyMutex); - guiDataReady=0; - pthread_mutex_unlock(&dataReadyMutex); - } - - //random read or nth frame read, gui needs data now - else{ - /* - //nth frame read, block current process if the guireader hasnt read it yet - if(nFrameToGui) - sem_wait(&smp); -*/ - pthread_mutex_lock(&dataReadyMutex); - guiDataReady=0; - //eiger - if(startbuf != NULL){ - int offset = 0; - int size = frameSize/EIGER_MAX_PORTS; - for(int j=0;jpost_json("state/configure", &answer, request_body); + code = rest->get_json("state", &answer); + FILE_LOG(logDEBUG) << __FILE__ << "::" << " got: " << answer; - //error - int iret; - for(int i=0;igetErrorStatus(); - if(iret){ -#ifdef VERBOSE - cout << "Could not create UDP socket on port " << server_port[i] << " error:" << iret << endl; -#endif - return FAIL; - } - } + //code = rest->post_json("state/open", &answer); + //code = rest->get_json("state", &answer); + + status = RUNNING; return OK; } @@ -727,9 +206,46 @@ int UDPRESTImplementation::createUDPSockets(){ +void UDPRESTImplementation::stopReceiver(){ + + FILE_LOG(logDEBUG) << __AT__ << "called"; + + if(status == RUNNING) + startReadout(); + + while(status == TRANSMITTING) + usleep(5000); + + //change status + status = IDLE; + + FILE_LOG(logDEBUG) << __AT__ << "exited, status " << endl; + +} + + +void UDPRESTImplementation::startReadout(){ + FILE_LOG(logDEBUG) << __AT__ << " starting"; + + status = TRANSMITTING; + + //kill udp socket to tell the listening thread to push last packet + shutDownUDPSockets(); + FILE_LOG(logDEBUG) << __FILE__ << "::" << __func__ << " done"; + +} + + + + + +/* FIXME + * Its also called by TCP in case of illegal shut down such as Ctrl + c. + * Upto you what you want to do with it. + */ int UDPRESTImplementation::shutDownUDPSockets(){ FILE_LOG(logDEBUG) << __AT__ << "called"; @@ -755,19 +271,19 @@ int UDPRESTImplementation::shutDownUDPSockets(){ } // getting the state - FILE_LOG(logWARNING) << "PLEASE WAIT WHILE CHECKING AND SHUTTING DOWN ALL CONNECTIONS!"; + FILE_LOG(logWARNING) << "PLEASE WAIT WHILE CHECKING AND SHUTTING DOWN ALL CONNECTIONS!"; code = rest->get_json("state", &answer); be_state = answer["state"].getString(); // LEO: this is probably wrong if (be_state == "OPEN"){ while (be_state != "TRANSIENT"){ - code = rest->get_json("state", &answer); - be_state = answer["state"].getString(); - cout << "be_State: " << be_state << endl; - usleep(10000); + code = rest->get_json("state", &answer); + be_state = answer["state"].getString(); + cout << "be_State: " << be_state << endl; + usleep(10000); } - + code = rest->post_json("state/close", &answer); std::cout <post_json("state/reset", &answer); @@ -787,1443 +303,29 @@ int UDPRESTImplementation::shutDownUDPSockets(){ - - -int UDPRESTImplementation::createListeningThreads(bool destroy){ - +/* FIXME + * do you really need this, this is called if registerDataCallback() is activated + * in your gui to get data from receiver. you probably have a different way + * of reconstructing complete data set from all receivers + */ +void UDPRESTImplementation::readFramee(char* c,char** raw, uint64_t &startAcq, uint64_t &startFrame){ FILE_LOG(logDEBUG) << __AT__ << " called"; - int i; - void* status; - - killAllListeningThreads = 0; - - pthread_mutex_lock(&status_mutex); - listeningthreads_mask = 0x0; - pthread_mutex_unlock(&(status_mutex)); - - if(!destroy){ - - //start listening threads - cout << "Creating Listening Threads(s)"; - - currentListeningThreadIndex = -1; - - for(i = 0; i < numListeningThreads; ++i){ - sem_init(&listensmp[i],1,0); - thread_started = 0; - currentListeningThreadIndex = i; - if(pthread_create(&listening_thread[i], NULL,startListeningThread, (void*) this)){ - cout << "Could not create listening thread with index " << i << endl; - return FAIL; - } - while(!thread_started); - cout << "."; - cout << flush; - } -#ifdef VERBOSE - cout << "Listening thread(s) created successfully." << endl; -#else - cout << endl; -#endif - }else{ - cout<<"Destroying Listening Thread(s)"<initEventTree(temp, &iframe); - //resets the pedestalSubtraction array and the commonModeSubtraction - singlePhotonDet[ithr]->newDataSet(); - if(myFile[ithr]==NULL){ - cout<<"file null"<IsOpen()){ - cout<<"file not open"< DO_NOTHING){ - //close - if(sfilefd){ - fclose(sfilefd); - sfilefd = NULL; - } - //open file - if(!overwrite){ - if (NULL == (sfilefd = fopen((const char *) (savefilename), "wx"))){ - cout << "Error: Could not create new file " << savefilename << endl; - return FAIL; - } - }else if (NULL == (sfilefd = fopen((const char *) (savefilename), "w"))){ - cout << "Error: Could not create file " << savefilename << endl; - return FAIL; - } - //setting buffer - setvbuf(sfilefd,NULL,_IOFBF,BUF_SIZE); - - //printing packet losses and file names - if(!packetsCaught) - cout << savefilename << endl; - else{ - cout << savefilename - << "\tpacket loss " - << setw(4)<GetCurrentFile(); - - if(myFile[ithr]->Write()) - //->Write(tall->GetName(),TObject::kOverwrite); - cout << "Thread " << ithr <<": wrote frames to file" << endl; - else - cout << "Thread " << ithr << ": could not write frames to file" << endl; - - }else - cout << "Thread " << ithr << ": could not write frames to file: No file or No Tree" << endl; - //close file - if(myTree[ithr] && myFile[ithr]) - myFile[ithr] = myTree[ithr]->GetCurrentFile(); - if(myFile[ithr] != NULL) - myFile[ithr]->Close(); - myFile[ithr] = NULL; - myTree[ithr] = NULL; - pthread_mutex_unlock(&write_mutex); - -#endif - } - FILE_LOG(logDEBUG) << __AT__ << "exited for thread " << ithr; } - - -int UDPRESTImplementation::startReceiver(char message[]){ - int i; - - FILE_LOG(logDEBUG) << __FILE__ << "::" << __func__ << " starting"; - initialize_REST(); - FILE_LOG(logDEBUG) << __FILE__ << "::" << __func__ << " initialized"; - - cout << "Starting Receiver" << endl; - - std::string answer; - int code; - //char *intStr = itoa(a); - //string str = string(intStr); - // TODO: remove hardcode!!! - stringstream ss; - ss << getDynamicRange(); - string str_dr = ss.str(); - stringstream ss2; - ss2 << getNumberOfFrames(); - string str_n = ss2.str(); - - - cout << "Starting Receiver" << endl; - - std::string request_body = "{\"settings\": {\"bit_depth\": " + str_dr + ", \"nimages\": " + str_n + "}}"; - //std::string request_body = "{\"settings\": {\"nimages\":1, \"scanid\":999, \"bit_depth\":16}}"; - FILE_LOG(logDEBUG) << __FILE__ << "::" << " sending this configuration body: " << request_body; - code = rest->post_json("state/configure", &answer, request_body); - code = rest->get_json("state", &answer); - FILE_LOG(logDEBUG) << __FILE__ << "::" << " got: " << answer; - - //code = rest->post_json("state/open", &answer); - //code = rest->get_json("state", &answer); - - status = RUNNING; - - //reset listening thread variables - /* - measurementStarted = false; - //should be set to zero as its added to get next start frame indices for scans for eiger - if(!acqStarted) currframenum = 0; - startFrameIndex = 0; - - for(int i = 0; i < numListeningThreads; ++i) - totalListeningFrameCount[i] = 0; - */ - //udp socket - /* - if(createUDPSockets() == FAIL){ - strcpy(message,"Could not create UDP Socket(s).\n"); - cout << endl << message << endl; - return FAIL; - } - cout << "UDP socket(s) created successfully. 1st port " << server_port[0] << endl; - - */ - /* - if(setupWriter() == FAIL){ - //stop udp socket - shutDownUDPSockets(); - - sprintf(message,"Could not create file %s.\n",savefilename); - return FAIL; - } - cout << "Successfully created file(s)" << endl; - - //done to give the gui some proper name instead of always the last file name - if(dataCompression) - sprintf(savefilename, "%s/%s_fxxx_%d_xx.root", filePath,fileName,fileIndex); - - //initialize semaphore - sem_init(&smp,1,0); - - //status - pthread_mutex_lock(&status_mutex); - status = RUNNING; - for(i=0;istartListening(); - - return this_pointer; -} - - - -void* UDPRESTImplementation::startWritingThread(void* this_pointer){ - FILE_LOG(logDEBUG) << __AT__ << " called"; - FILE_LOG(logDEBUG) << __AT__ << " doing a big bunch of nothing"; - - //((UDPRESTImplementation*)this_pointer)->startWriting(); - return this_pointer; -} - - - - - - -int UDPRESTImplementation::startListening(){ - FILE_LOG(logDEBUG) << __AT__ << " called"; - FILE_LOG(logDEBUG) << __AT__ << " doing a big bunch of nothing"; - - /* - int ithread = currentListeningThreadIndex; -#ifdef VERYVERBOSE - cout << "In startListening() " << endl; -#endif - - thread_started = 1; - - int i,total; - int lastpacketoffset, expected, rc, rc1,packetcount, maxBufferSize, carryonBufferSize; - uint32_t lastframeheader;// for moench to check for all the packets in last frame - char* tempchar = NULL; - int imageheader = 0; - if(myDetectorType==EIGER) - imageheader = EIGER_IMAGE_HEADER_SIZE; - - - while(1){ - //variables that need to be checked/set before each acquisition - carryonBufferSize = 0; - //if more than 1 listening thread, listen one packet at a time, else need to interleaved frame later - maxBufferSize = bufferSize * numJobsPerThread; -#ifdef VERYDEBUG - cout << " maxBufferSize:" << maxBufferSize << ",carryonBufferSize:" << carryonBufferSize << endl; -#endif - - if(tempchar) {delete [] tempchar;tempchar = NULL;} - if(myDetectorType != EIGER) - tempchar = new char[onePacketSize * ((packetsPerFrame/numListeningThreads) - 1)]; //gotthard: 1packet size, moench:39 packet size - - - while((1<pop(buffer[ithread]); -#ifdef VERYDEBUG - cout << ithread << " *** popped from fifo free" << (void*)buffer[ithread] << endl; -#endif - - - //receive - if(udpSocket[ithread] == NULL){ - rc = 0; - cout << ithread << "UDP Socket is NULL" << endl; - } - //normal listening - else if(!carryonBufferSize){ - - rc = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS, maxBufferSize); - expected = maxBufferSize; - - } - //the remaining packets from previous buffer - else{ -#ifdef VERYDEBUG - cout << ithread << " ***carry on buffer" << carryonBufferSize << endl; - cout << ithread << " framennum in temochar:"<<((((uint32_t)(*((uint32_t*)tempchar))) - & (frameIndexMask)) >> frameIndexOffset)<ReceiveDataOnly((buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS + carryonBufferSize),maxBufferSize - carryonBufferSize); - expected = maxBufferSize - carryonBufferSize; - } - -#ifdef VERYDEBUG - cout << ithread << " *** rc:" << dec << rc << ". expected:" << dec << expected << endl; -#endif - - - - - //start indices for each start of scan/acquisition - eiger does it before - if((!measurementStarted) && (rc > 0) && (!ithread)) - startFrameIndices(ithread); - - //problem in receiving or end of acquisition - if((rc < expected)||(rc <= 0)){ - stopListening(ithread,rc,packetcount,total); - continue; - } - - - - //reset - packetcount = (packetsPerFrame/numListeningThreads) * numJobsPerThread; - carryonBufferSize = 0; - - - - //check if last packet valid and calculate packet count - switch(myDetectorType){ - - case MOENCH: - lastpacketoffset = (((numJobsPerThread * packetsPerFrame - 1) * onePacketSize) + HEADER_SIZE_NUM_TOT_PACKETS); -#ifdef VERYDEBUG - cout <<"first packet:"<< ((((uint32_t)(*((uint32_t*)(buffer[ithread]+HEADER_SIZE_NUM_TOT_PACKETS))))) & (packetIndexMask)) << endl; - cout <<"first header:"<< (((((uint32_t)(*((uint32_t*)(buffer[ithread]+HEADER_SIZE_NUM_TOT_PACKETS))))) & (frameIndexMask)) >> frameIndexOffset) << endl; - cout << "last packet offset:" << lastpacketoffset << endl; - cout <<"last packet:"<< ((((uint32_t)(*((uint32_t*)(buffer[ithread]+lastpacketoffset))))) & (packetIndexMask)) << endl; - cout <<"last header:"<< (((((uint32_t)(*((uint32_t*)(buffer[ithread]+lastpacketoffset))))) & (frameIndexMask)) >> frameIndexOffset) << endl; -#endif - //moench last packet value is 0 - if( ((((uint32_t)(*((uint32_t*)(buffer[ithread]+lastpacketoffset))))) & (packetIndexMask))){ - lastframeheader = ((((uint32_t)(*((uint32_t*)(buffer[ithread]+lastpacketoffset))))) & (frameIndexMask)) >> frameIndexOffset; - carryonBufferSize += onePacketSize; - lastpacketoffset -= onePacketSize; - --packetcount; - while (lastframeheader == (((((uint32_t)(*((uint32_t*)(buffer[ithread]+lastpacketoffset))))) & (frameIndexMask)) >> frameIndexOffset)){ - carryonBufferSize += onePacketSize; - lastpacketoffset -= onePacketSize; - --packetcount; - } - memcpy(tempchar, buffer[ithread]+(lastpacketoffset+onePacketSize), carryonBufferSize); -#ifdef VERYDEBUG - cout << "tempchar header:" << (((((uint32_t)(*((uint32_t*)(tempchar))))) - & (frameIndexMask)) >> frameIndexOffset) << endl; - cout <<"tempchar packet:"<< ((((uint32_t)(*((uint32_t*)(tempchar))))) - & (packetIndexMask)) << endl; -#endif - } - break; - - case GOTTHARD: - if(shortFrame == -1){ - lastpacketoffset = (((numJobsPerThread * packetsPerFrame - 1) * onePacketSize) + HEADER_SIZE_NUM_TOT_PACKETS); -#ifdef VERYDEBUG - cout << "last packet offset:" << lastpacketoffset << endl; -#endif - - if((unsigned int)(packetsPerFrame -1) != ((((uint32_t)(*((uint32_t*)(buffer[ithread]+lastpacketoffset))))+1) & (packetIndexMask))){ - memcpy(tempchar,buffer[ithread]+lastpacketoffset, onePacketSize); -#ifdef VERYDEBUG - cout << "tempchar header:" << (((((uint32_t)(*((uint32_t*)(tempchar))))+1) - & (frameIndexMask)) >> frameIndexOffset) << endl; -#endif - carryonBufferSize = onePacketSize; - --packetcount; - } - } -#ifdef VERYDEBUG - cout << "header:" << (((((uint32_t)(*((uint32_t*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS))))+1) - & (frameIndexMask)) >> frameIndexOffset) << endl; -#endif - break; - default: - - break; - - } - - - // cout<<"*********** "<fnum)<push(buffer[ithread])); -#ifdef VERYDEBUG - if(!ithread) cout << ithread << " *** pushed into listening fifo" << endl; -#endif - } - - sem_wait(&listensmp[ithread]); - - //make sure its not exiting thread - if(killAllListeningThreads){ - cout << ithread << " good bye listening thread" << endl; - if(tempchar) {delete [] tempchar;tempchar = NULL;} - pthread_exit(NULL); - } - } - */ - return OK; -} - - - - - - - - - - - - - -int UDPRESTImplementation::startWriting(){ - FILE_LOG(logDEBUG) << __AT__ << " called"; - FILE_LOG(logDEBUG) << __AT__ << " doing a big bunch of nothing"; - /* - int ithread = currentWriterThreadIndex; -#ifdef VERYVERBOSE - cout << ithread << "In startWriting()" <pop(wbuf[i]); - numpackets = (uint16_t)(*((uint16_t*)wbuf[i])); -#ifdef VERYDEBUG - cout << ithread << " numpackets:" << dec << numpackets << endl; -#endif - } - -#ifdef VERYDEBUG - cout << ithread << " numpackets:" << dec << numpackets << endl; - cout << ithread << " *** writer popped from fifo " << (void*) wbuf[0]<< endl; - cout << ithread << " *** writer popped from fifo " << (void*) wbuf[1]<< endl; -#endif - - - //last dummy packet - if(numpackets == 0xFFFF){ - stopWriting(ithread,wbuf); - continue; - } - - - - - //for progress - if(myDetectorType == EIGER){ - tempframenum = htonl(*(unsigned int*)((eiger_image_header *)((char*)(wbuf[ithread] + HEADER_SIZE_NUM_TOT_PACKETS)))->fnum); - tempframenum += (startFrameIndex-1); //eiger frame numbers start at 1, so need to -1 - }else if ((myDetectorType == GOTTHARD) && (shortFrame == -1)) - tempframenum = (((((uint32_t)(*((uint32_t*)(wbuf[ithread] + HEADER_SIZE_NUM_TOT_PACKETS))))+1)& (frameIndexMask)) >> frameIndexOffset); - else - tempframenum = ((((uint32_t)(*((uint32_t*)(wbuf[ithread] + HEADER_SIZE_NUM_TOT_PACKETS))))& (frameIndexMask)) >> frameIndexOffset); - - if(numWriterThreads == 1) - currframenum = tempframenum; - else{ - pthread_mutex_lock(&progress_mutex); - if(tempframenum > currframenum) - currframenum = tempframenum; - pthread_mutex_unlock(&progress_mutex); - } -//#ifdef VERYDEBUG - if(myDetectorType == EIGER) - cout << endl < 0){ - for(i=0;ipush(wbuf[i])); -#ifdef VERYDEBUG - cout << ithread << ":" << i+j << " fifo freed:" << (void*)wbuf[i] << endl; -#endif - } - - - } - else{ - //copy to gui - copyFrameToGui(NULL,-1,wbuf[0]+HEADER_SIZE_NUM_TOT_PACKETS); -#ifdef VERYVERBOSE - cout << ithread << " finished copying" << endl; -#endif - while(!fifoFree[0]->push(wbuf[0])); -#ifdef VERYVERBOSE - cout<<"buf freed:"<<(void*)wbuf[0]<fnum); - //gotthard has +1 for frame number and not a short frame - else if ((myDetectorType == GOTTHARD) && (shortFrame == -1)) - startFrameIndex = (((((uint32_t)(*((uint32_t*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS))))+1) - & (frameIndexMask)) >> frameIndexOffset); - else - startFrameIndex = ((((uint32_t)(*((uint32_t*)(buffer[ithread]+HEADER_SIZE_NUM_TOT_PACKETS)))) - & (frameIndexMask)) >> frameIndexOffset); - - - //start of acquisition - if(!acqStarted){ - startAcquisitionIndex=startFrameIndex; - currframenum = startAcquisitionIndex; - acqStarted = true; - cout << "startAcquisitionIndex:" << startAcquisitionIndex<push(buffer[ithread]); - exit(-1); - } - //push the last buffer into fifo - if(rc > 0){ - pc = (rc/onePacketSize); -#ifdef VERYDEBUG - cout << ithread << " *** last packetcount:" << pc << endl; -#endif - (*((uint16_t*)(buffer[ithread]))) = pc; - totalListeningFrameCount[ithread] += pc; - while(!fifo[ithread]->push(buffer[ithread])); -#ifdef VERYDEBUG - cout << ithread << " *** last lbuf1:" << (void*)buffer[ithread] << endl; -#endif - } - - - //push dummy buffer to all writer threads - for(i=0;ipop(buffer[ithread]); - (*((uint16_t*)(buffer[ithread]))) = 0xFFFF; -#ifdef VERYDEBUG - cout << ithread << " going to push in dummy buffer:" << (void*)buffer[ithread] << " with num packets:"<< (*((uint16_t*)(buffer[ithread]))) << endl; -#endif - while(!fifo[ithread]->push(buffer[ithread])); -#ifdef VERYDEBUG - cout << ithread << " pushed in dummy buffer:" << (void*)buffer[ithread] << endl; -#endif - } - - //reset mask and exit loop - pthread_mutex_lock(&status_mutex); - listeningthreads_mask^=(1< 1) - cout << "Waiting for listening to be done.. current mask:" << hex << listeningthreads_mask << endl; -#endif - while(listeningthreads_mask) - usleep(5000); -#ifdef VERYDEBUG - t = 0; - for(i=0;ipush(wbuffer[i])); -#ifdef VERYDEBUG - cout << ithread << ":" << i<< " fifo freed:" << (void*)wbuffer[i] << endl; -#endif - } - - - - //all threads need to close file, reset mask and exit loop - closeFile(ithread); - pthread_mutex_lock(&status_mutex); - writerthreads_mask^=(1< 0){ - - //for progress and packet loss calculation(new files) - if(myDetectorType == EIGER); - else if ((myDetectorType == GOTTHARD) && (shortFrame == -1)) - tempframenum = (((((uint32_t)(*((uint32_t*)(buf + HEADER_SIZE_NUM_TOT_PACKETS))))+1)& (frameIndexMask)) >> frameIndexOffset); - else - tempframenum = ((((uint32_t)(*((uint32_t*)(buf + HEADER_SIZE_NUM_TOT_PACKETS))))& (frameIndexMask)) >> frameIndexOffset); - - if(numWriterThreads == 1) - currframenum = tempframenum; - else{ - if(tempframenum > currframenum) - currframenum = tempframenum; - } -#ifdef VERYDEBUG - cout << "tempframenum:" << dec << tempframenum << " curframenum:" << currframenum << endl; -#endif - - //lock - if(numWriterThreads > 1) - pthread_mutex_lock(&write_mutex); - - - //to create new file when max reached - packetsToSave = maxPacketsPerFile - packetsInFile; - if(packetsToSave > numpackets) - packetsToSave = numpackets; -/**next time offset is still plus header length*/ - fwrite(buf+offset, 1, packetsToSave * onePacketSize, sfilefd); - packetsInFile += packetsToSave; - packetsCaught += packetsToSave; - totalPacketsCaught += packetsToSave; - - - //new file - if(packetsInFile >= maxPacketsPerFile){ - //for packet loss - lastpacket = (((packetsToSave - 1) * onePacketSize) + offset); - if(myDetectorType == EIGER); - else if ((myDetectorType == GOTTHARD) && (shortFrame == -1)) - tempframenum = (((((uint32_t)(*((uint32_t*)(buf + lastpacket))))+1)& (frameIndexMask)) >> frameIndexOffset); - else - tempframenum = ((((uint32_t)(*((uint32_t*)(buf + lastpacket))))& (frameIndexMask)) >> frameIndexOffset); - - if(numWriterThreads == 1) - currframenum = tempframenum; - else{ - if(tempframenum > currframenum) - currframenum = tempframenum; - } -#ifdef VERYDEBUG - cout << "tempframenum:" << dec << tempframenum << " curframenum:" << currframenum << endl; -#endif - //create - createNewFile(); - } - - //unlock - if(numWriterThreads > 1) - pthread_mutex_unlock(&write_mutex); - - - offset += (packetsToSave * onePacketSize); - numpackets -= packetsToSave; - } - - } - else{ - if(numWriterThreads > 1) - pthread_mutex_lock(&write_mutex); - packetsInFile += numpackets; - packetsCaught += numpackets; - totalPacketsCaught += numpackets; - if(numWriterThreads > 1) - pthread_mutex_unlock(&write_mutex); - } -} - - - - - - - - - - - - - - -void UDPRESTImplementation::handleDataCompression(int ithread, char* wbuffer[], int &npackets, char* data, int xmax, int ymax, int &nf){ - - FILE_LOG(logDEBUG) << __AT__ << " called"; - -#if defined(MYROOT1) && defined(ALLFILE_DEBUG) - writeToFile_withoutCompression(wbuf[0], numpackets,currframenum); -#endif - - eventType thisEvent = PEDESTAL; - int ndata; - char* buff = 0; - data = wbuffer[0]+ HEADER_SIZE_NUM_TOT_PACKETS; - int remainingsize = npackets * onePacketSize; - int np; - int once = 0; - double tot, tl, tr, bl, br; - int xmin = 1, ymin = 1, ix, iy; - - - while(buff = receiverdata[ithread]->findNextFrame(data,ndata,remainingsize)){ - np = ndata/onePacketSize; - - //cout<<"buff framnum:"<> frameIndexOffset)<newFrame(); - - //only for moench - if(commonModeSubtractionEnable){ - for(ix = xmin - 1; ix < xmax+1; ix++){ - for(iy = ymin - 1; iy < ymax+1; iy++){ - thisEvent = singlePhotonDet[ithread]->getEventType(buff, ix, iy, 0); - } - } - } - - - for(ix = xmin - 1; ix < xmax+1; ix++) - for(iy = ymin - 1; iy < ymax+1; iy++){ - thisEvent=singlePhotonDet[ithread]->getEventType(buff, ix, iy, commonModeSubtractionEnable); - if (nf>1000) { - tot=0; - tl=0; - tr=0; - bl=0; - br=0; - if (thisEvent==PHOTON_MAX) { - receiverdata[ithread]->getFrameNumber(buff); - //iFrame=receiverdata[ithread]->getFrameNumber(buff); -#ifdef MYROOT1 - myTree[ithread]->Fill(); - //cout << "Fill in event: frmNr: " << iFrame << " ix " << ix << " iy " << iy << " type " << thisEvent << endl; -#else - pthread_mutex_lock(&write_mutex); - if((enableFileWrite) && (sfilefd)) - singlePhotonDet[ithread]->writeCluster(sfilefd); - pthread_mutex_unlock(&write_mutex); -#endif - } - } - } - - nf++; -#ifndef ALLFILE - pthread_mutex_lock(&progress_mutex); - packetsInFile += packetsPerFrame; - packetsCaught += packetsPerFrame; - totalPacketsCaught += packetsPerFrame; - if(packetsInFile >= maxPacketsPerFile) - createNewFile(); - pthread_mutex_unlock(&progress_mutex); - -#endif - if(!once){ - copyFrameToGui(NULL,-1,buff); - once = 1; - } - } - - remainingsize -= ((buff + ndata) - data); - data = buff + ndata; - if(data > (wbuffer[0] + HEADER_SIZE_NUM_TOT_PACKETS + npackets * onePacketSize) ) - cout <<" **************ERROR SHOULD NOT COME HERE, Error 142536!"<push(wbuffer[0])); -#ifdef VERYVERBOSE - cout<<"buf freed:"<<(void*)wbuffer[0]<= 0){ - - tengigaEnable = enable; - - if(myDetectorType == EIGER){ - - if(!tengigaEnable){ - packetsPerFrame = EIGER_ONE_GIGA_CONSTANT * dynamicRange * EIGER_MAX_PORTS; - onePacketSize = EIGER_ONE_GIGA_ONE_PACKET_SIZE; - maxPacketsPerFile = EIGER_MAX_FRAMES_PER_FILE * packetsPerFrame; - }else{ - packetsPerFrame = EIGER_TEN_GIGA_CONSTANT * dynamicRange * EIGER_MAX_PORTS; - onePacketSize = EIGER_TEN_GIGA_ONE_PACKET_SIZE; - maxPacketsPerFile = EIGER_MAX_FRAMES_PER_FILE * packetsPerFrame*4; - } - frameSize = onePacketSize * packetsPerFrame; - bufferSize = (frameSize/EIGER_MAX_PORTS) + EIGER_HEADER_LENGTH;//everything one port gets (img header plus packets) - //maxPacketsPerFile = EIGER_MAX_FRAMES_PER_FILE * packetsPerFrame; - - - cout<<"packetsPerFrame:"< // socket(), bind(), listen(), accept(), shut down -//#include // sock_addr_in, htonl, INADDR_ANY #include // exit() #include //set precision for printing parameters for create new file #include //map -//#include //munmap - #include #include #include -#include using namespace std; #define WRITE_HEADERS @@ -789,7 +784,7 @@ void UDPStandardImplementation::resetAcquisitionCount(){ int UDPStandardImplementation::startReceiver(char *c){ FILE_LOG(logDEBUG) << __AT__ << " called"; - cout << "Starting Receiver" << endl; + FILE_LOG(logINFO) << "Stopping Receiver"; //RESET @@ -888,7 +883,7 @@ int UDPStandardImplementation::startReceiver(char *c){ void UDPStandardImplementation::stopReceiver(){ FILE_LOG(logDEBUG) << __AT__ << " called"; - cout << "Stopping Receiver" << endl; + FILE_LOG(logINFO) << "Stopping Receiver"; //set status to transmitting startReadout(); From 3b0e2e611c3733003d327d188de0307d6483a2b6 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Fri, 27 Nov 2015 15:57:19 +0100 Subject: [PATCH 183/474] jungfrau works --- .../include/UDPStandardImplementation.h | 23 --- slsReceiverSoftware/include/genericSocket.h | 4 +- slsReceiverSoftware/include/receiver_defs.h | 57 ++++++ .../include/slsReceiverTCPIPInterface.h | 3 + .../include/sls_receiver_defs.h | 1 + .../src/UDPStandardImplementation.cpp | 108 ++++++++-- .../src/slsReceiverTCPIPInterface.cpp | 186 ++++++++++++++++-- 7 files changed, 320 insertions(+), 62 deletions(-) diff --git a/slsReceiverSoftware/include/UDPStandardImplementation.h b/slsReceiverSoftware/include/UDPStandardImplementation.h index 7ec6672aa..0921ad934 100644 --- a/slsReceiverSoftware/include/UDPStandardImplementation.h +++ b/slsReceiverSoftware/include/UDPStandardImplementation.h @@ -461,29 +461,6 @@ private: *************************************************************************/ //**detector parameters*** - /** - * structure of an eiger packet header - * subframenum subframe number for 32 bit mode (already written by firmware) - * missingpacket explicitly put to 0xFF to recognize it in file read (written by software) - * portnum 0 for the first port and 1 for the second port (written by software to file) - * dynamicrange dynamic range or bits per pixel (written by software to file) - */ - typedef struct { - unsigned char subFameNumber[4]; - unsigned char missingPacket[2]; - unsigned char portIndex[1]; - unsigned char dynamicRange[1]; - } eiger_packet_header_t; - /** - * structure of an eiger packet footer - * framenum 48 bit frame number (already written by firmware) - * packetnum packet number (already written by firmware) - */ - typedef struct { - unsigned char frameNumber[6]; - unsigned char packetNumber[2]; - } eiger_packet_footer_t; - /** Size of 1 Frame including headers */ int frameSize; diff --git a/slsReceiverSoftware/include/genericSocket.h b/slsReceiverSoftware/include/genericSocket.h index 97cd3223e..3facb0a2b 100644 --- a/slsReceiverSoftware/include/genericSocket.h +++ b/slsReceiverSoftware/include/genericSocket.h @@ -75,7 +75,8 @@ class sockaddr_in; using namespace std; #define DEFAULT_PACKET_SIZE 1286 -#define SOCKET_BUFFER_SIZE (100*1024*1024) //100MB +/*#define SOCKET_BUFFER_SIZE (100*1024*1024) //100MB*/ +#define SOCKET_BUFFER_SIZE (2000*1024*1024) //100MB #define DEFAULT_PORTNO 1952 #define DEFAULT_BACKLOG 5 #define DEFAULT_UDP_PORTNO 50001 @@ -578,7 +579,6 @@ enum communicationProtocol{ int ReceiveDataOnly(void* buf,int length=0){ - if (buf==NULL) return -1; diff --git a/slsReceiverSoftware/include/receiver_defs.h b/slsReceiverSoftware/include/receiver_defs.h index c11fe876d..3cc5e8091 100755 --- a/slsReceiverSoftware/include/receiver_defs.h +++ b/slsReceiverSoftware/include/receiver_defs.h @@ -5,6 +5,43 @@ #include + +/** + * structure of an eiger packet header + * subframenum subframe number for 32 bit mode (already written by firmware) + * missingpacket explicitly put to 0xFF to recognize it in file read (written by software) + * portnum 0 for the first port and 1 for the second port (written by software to file) + * dynamicrange dynamic range or bits per pixel (written by software to file) + */ +typedef struct { + unsigned char subFrameNumber[4]; + unsigned char missingPacket[2]; + unsigned char portIndex[1]; + unsigned char dynamicRange[1]; +} eiger_packet_header_t; +/** + * structure of an eiger packet footer + * framenum 48 bit frame number (already written by firmware) + * packetnum packet number (already written by firmware) + */ +typedef struct { + unsigned char frameNumber[6]; + unsigned char packetNumber[2]; +} eiger_packet_footer_t; + +/** + * structure of an jungfrau packet header + * empty header + * framenumber + * packetnumber + */ +typedef struct { + unsigned char emptyHeader[6]; + unsigned char frameNumber[8]; + unsigned char packetNumber[8]; +} jfrau_packet_header_t; + + #define GOODBYE -200 #define DO_NOTHING 0 @@ -90,6 +127,26 @@ + +#define JFRAU_FIFO_SIZE 2500 //cannot be less than max jobs per thread = 1000 +#define JFRAU_PACKETS_PER_FRAME 128 +#define JFRAU_HEADER_LENGTH 22 +#define JFRAU_ONE_DATA_SIZE 8192 +#define JFRAU_ONE_PACKET_SIZE (JFRAU_HEADER_LENGTH+JFRAU_ONE_DATA_SIZE) //8214 +#define JFRAU_DATA_BYTES (JFRAU_ONE_DATA_SIZE*JFRAU_PACKETS_PER_FRAME) //8192*128 +#define JFRAU_BUFFER_SIZE (JFRAU_ONE_PACKET_SIZE*JFRAU_PACKETS_PER_FRAME) //8214*128 + + +#define JFRAU_FRAME_INDEX_MASK 0x0 //Not Applicable, use struct +#define JFRAU_FRAME_INDEX_OFFSET 0x0 //Not Applicable, use struct +#define JFRAU_PACKET_INDEX_MASK 0x0//Not Applicable, use struct + +#define JFRAU_PIXELS_IN_ONE_ROW (256*4) +#define JFRAU_PIXELS_IN_ONE_COL (256*2) +#define JFRAU_BYTES_IN_ONE_ROW (JFRAU_PIXELS_IN_ONE_ROW*2) + + + #define JCTB_FIFO_SIZE 2500 //cannot be less than max jobs per thread = 1000 /*#define MOENCH_ALIGNED_FRAME_SIZE 65536*/ #define JCTB_PACKETS_PER_FRAME 50 diff --git a/slsReceiverSoftware/include/slsReceiverTCPIPInterface.h b/slsReceiverSoftware/include/slsReceiverTCPIPInterface.h index b71b705f6..237f240e6 100644 --- a/slsReceiverSoftware/include/slsReceiverTCPIPInterface.h +++ b/slsReceiverSoftware/include/slsReceiverTCPIPInterface.h @@ -176,6 +176,9 @@ private: /** eiger specific read frame */ int eiger_read_frame(); + /** jungfrau specific read frame */ + int jungfrau_read_frame(); + /** Sets the receiver to send every nth frame to gui, or only upon gui request */ int set_read_frequency(); diff --git a/slsReceiverSoftware/include/sls_receiver_defs.h b/slsReceiverSoftware/include/sls_receiver_defs.h index 07566ab84..c11f6f8c0 100755 --- a/slsReceiverSoftware/include/sls_receiver_defs.h +++ b/slsReceiverSoftware/include/sls_receiver_defs.h @@ -24,6 +24,7 @@ typedef int int32_t; #define SHORT_MAX_FRAMES_PER_FILE 100000 #define MOENCH_MAX_FRAMES_PER_FILE 1000 #define EIGER_MAX_FRAMES_PER_FILE 2000 +#define JFRAU_MAX_FRAMES_PER_FILE 2000 #define JFCTB_MAX_FRAMES_PER_FILE 100000 diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index ec0f964cb..fe86efd51 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -251,7 +251,7 @@ int UDPStandardImplementation::setupFifoStructure(){ int64_t i; int oldNumberofJobsPerBuffer = numberofJobsPerBuffer; //eiger always listens to 1 packet at a time - if(myDetectorType == EIGER){ + if((myDetectorType == EIGER) || (myDetectorType = JUNGFRAU)){ numberofJobsPerBuffer = 1; FILE_LOG(logDEBUG) << "Info: 1 packet per buffer"; } @@ -288,6 +288,7 @@ int UDPStandardImplementation::setupFifoStructure(){ case GOTTHARD: fifoSize = GOTTHARD_FIFO_SIZE; break; case MOENCH: fifoSize = MOENCH_FIFO_SIZE; break; case PROPIX: fifoSize = PROPIX_FIFO_SIZE; break; + case JUNGFRAU: fifoSize = JFRAU_FIFO_SIZE; break; case EIGER: fifoSize = EIGER_FIFO_SIZE * packetsPerFrame; break;//listens to 1 packet at a time and size depends on packetsperframe default: break; } @@ -717,7 +718,6 @@ int UDPStandardImplementation::setDetectorType(const detectorType d){ footerOffset = EIGER_PACKET_HEADER_SIZE + oneDataSize; break; case JUNGFRAUCTB: - case JUNGFRAU: packetsPerFrame = JCTB_PACKETS_PER_FRAME; onePacketSize = JCTB_ONE_PACKET_SIZE; //oneDataSize = Not applicable; @@ -730,6 +730,19 @@ int UDPStandardImplementation::setDetectorType(const detectorType d){ fifoSize = JCTB_FIFO_SIZE; //footerOffset = Not applicable; break; + case JUNGFRAU: + packetsPerFrame = JFRAU_PACKETS_PER_FRAME; + onePacketSize = JFRAU_ONE_PACKET_SIZE; + oneDataSize = JFRAU_DATA_BYTES; + frameSize = JFRAU_BUFFER_SIZE; + bufferSize = JFRAU_BUFFER_SIZE; + frameIndexMask = JFRAU_FRAME_INDEX_MASK; + frameIndexOffset = JFRAU_FRAME_INDEX_OFFSET; + packetIndexMask = JFRAU_PACKET_INDEX_MASK; + maxPacketsPerFile = JFRAU_MAX_FRAMES_PER_FILE * JFRAU_PACKETS_PER_FRAME; + fifoSize = JFRAU_FIFO_SIZE; + //footerOffset = Not applicable; + break; default: FILE_LOG(logERROR) << "This is an unknown receiver type " << (int)d; return FAIL; @@ -1297,9 +1310,9 @@ int UDPStandardImplementation::setupWriter(){ if (rawDataReadyCallBack){ FILE_LOG(logINFO) << "Data Write has been defined externally"; } - }else if(!fileWriteEnable) + }else if(!fileWriteEnable){ FILE_LOG(logINFO) << "Data will not be saved"; - + } //creating first file @@ -1571,6 +1584,7 @@ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int lSize, in int receivedSize = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS + cSize, lSize + cSize); + //throw away packets that is not one packet size, need to check status if socket is shut down while(status != TRANSMITTING && myDetectorType == EIGER && receivedSize != onePacketSize) { if(receivedSize != EIGER_HEADER_LENGTH) @@ -1584,13 +1598,19 @@ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int lSize, in totalListeningFrameCount[ithread] += (receivedSize/onePacketSize); #ifdef MANUALDEBUG - eiger_packet_header_t* header = (eiger_packet_header_t*) (buffer[ithread]+HEADER_SIZE_NUM_TOT_PACKETS); - eiger_packet_footer_t* footer = (eiger_packet_footer_t*)(buffer[ithread] + footerOffset + HEADER_SIZE_NUM_TOT_PACKETS); - cprintf(GREEN,"thread:%d subframenum:%d oldpacketnum:%d new pnum:%d\n", - ithread, - (*( (unsigned int*) header->subFameNumber)), - (*( (uint8_t*) header->dynamicRange)), - (*( (uint16_t*) footer->packetNumber))); + if(myDetectorType == JUNGFRAU){ + jfrau_packet_header_t* header = (jfrau_packet_header_t*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS); + cprintf(RED,"framenumber:%llu\n",(long long unsigned int)(*( (uint64_t*) header->frameNumber))); + cprintf(RED,"packetnumber:%llu\n",(long long unsigned int)(*( (uint64_t*) header->packetNumber))); + }else if(myDetectorType == EIGER){ + eiger_packet_header_t* header = (eiger_packet_header_t*) (buffer[ithread]+HEADER_SIZE_NUM_TOT_PACKETS); + eiger_packet_footer_t* footer = (eiger_packet_footer_t*)(buffer[ithread] + footerOffset + HEADER_SIZE_NUM_TOT_PACKETS); + cprintf(GREEN,"thread:%d subframenum:%d oldpacketnum:%d new pnum:%d\n", + ithread, + (*( (unsigned int*) header->subFrameNumber)), + (*( (uint8_t*) header->dynamicRange)), + (*( (uint16_t*) footer->packetNumber))); + } #endif @@ -1609,10 +1629,15 @@ void UDPStandardImplementation::startFrameIndices(int ithread){ FILE_LOG(logDEBUG) << __AT__ << " called"; //determine startFrameIndex + jfrau_packet_header_t* header=0; switch(myDetectorType){ case EIGER: startFrameIndex = 0; //frame number always resets break; + case JUNGFRAU: + header = (jfrau_packet_header_t*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS); + startFrameIndex = (*( (uint64_t*) header->frameNumber)); + break; default: if(shortFrameEnable < 0){ startFrameIndex = (((((uint32_t)(*((uint32_t*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS))))+1) @@ -1741,8 +1766,10 @@ uint32_t UDPStandardImplementation::processListeningBuffer(int ithread, int cSiz int lastPacketOffset; //the offset of the last packet uint32_t lastFrameHeader; //frame number of last packet in buffer + uint64_t lastFrameHeader64; //frame number of last packet in buffer uint32_t packetCount = (packetsPerFrame/numberofListeningThreads) * numberofJobsPerBuffer; //packets received cSize = 0; //reset size + jfrau_packet_header_t* header; switch(myDetectorType){ case GOTTHARD: @@ -1802,6 +1829,44 @@ uint32_t UDPStandardImplementation::processListeningBuffer(int ithread, int cSiz } break; + + case JUNGFRAU: + lastPacketOffset = (((numberofJobsPerBuffer * packetsPerFrame - 1) * onePacketSize) + HEADER_SIZE_NUM_TOT_PACKETS); +#ifdef DEBUG4 + header = (jfrau_packet_header_t*) (buffer[ithread]+HEADER_SIZE_NUM_TOT_PACKETS); + cprintf(BLUE, "Listening_Thread: First Header:%llu\t First Packet:%llu\n", + (long long unsigned int)(*( (uint64_t*) header->frameNumber)), + (long long unsigned int)(*( (uint64_t*) header->packetNumber))); +#endif + header = (jfrau_packet_header_t*) (buffer[ithread]+lastPacketOffset); +#ifdef DEBUG4 + cprintf(BLUE, "Listening_Thread: Last Header:%llu\t Last Packet:%llu\n", + (long long unsigned int)(*( (uint64_t*) header->frameNumber)), + (long long unsigned int)(*( (uint64_t*) header->packetNumber))); +#endif + //jungfrau last packet value is 0, so find the last packet and store the others in a temp storage + if(*( (uint64_t*) header->packetNumber)){ + cprintf(RED,"entering missing packet zone\n"); + lastFrameHeader64 = (*( (uint64_t*) header->frameNumber)); + cSize += onePacketSize; + lastPacketOffset -= onePacketSize; + --packetCount; + while (lastFrameHeader64 == (*( (uint64_t*) header->frameNumber))){ + cSize += onePacketSize; + lastPacketOffset -= onePacketSize; + header = (jfrau_packet_header_t*) (buffer[ithread]+lastPacketOffset); +#ifdef DEBUG4 + cprintf(RED,"new header:%llu new packet:%llu\n", + (long long unsigned int)(*( (uint64_t*) header->frameNumber)), + (long long unsigned int)(*( (uint64_t*) header->packetNumber))); +#endif + --packetCount; + } + memcpy(temp, buffer[ithread]+(lastPacketOffset+onePacketSize), cSize); + } + + break; + default: cprintf(RED,"Listening_Thread %d: Error: This detector %s is not implemented in the receiver\n", ithread, getDetectorType(myDetectorType).c_str()); @@ -2406,19 +2471,26 @@ void UDPStandardImplementation::handleWithoutDataCompression(int ithread, char* //get frame number (eiger already gets it when it does packet to packet processing) - if (myDetectorType != EIGER){ - uint64_t tempframenumber = ((uint32_t)(*((uint32_t*)(wbuffer[0] + HEADER_SIZE_NUM_TOT_PACKETS)))); - //for gotthard and normal frame, increment frame number to separate fnum and pnum - if (myDetectorType == PROPIX ||(myDetectorType == GOTTHARD && shortFrameEnable == -1)) - tempframenumber++; - //get frame number - currentFrameNumber = (tempframenumber & frameIndexMask) >> frameIndexOffset; + if(myDetectorType != EIGER){ + if(myDetectorType == JUNGFRAU){ + jfrau_packet_header_t* header = (jfrau_packet_header_t*)(wbuffer[0] + HEADER_SIZE_NUM_TOT_PACKETS); + currentFrameNumber = (*( (uint64_t*) header->frameNumber)); + }else{ + uint64_t tempframenumber = ((uint32_t)(*((uint32_t*)(wbuffer[0] + HEADER_SIZE_NUM_TOT_PACKETS)))); + //for gotthard and normal frame, increment frame number to separate fnum and pnum + if (myDetectorType == PROPIX ||(myDetectorType == GOTTHARD && shortFrameEnable == -1)) + tempframenumber++; + //get frame number + currentFrameNumber = (tempframenumber & frameIndexMask) >> frameIndexOffset; + } //set indices acquisitionIndex = currentFrameNumber - startAcquisitionIndex; frameIndex = currentFrameNumber - startFrameIndex; } + + //callback to write data if (cbAction < DO_EVERYTHING){ switch(myDetectorType){ diff --git a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp index 4af5e0424..3cb511b87 100644 --- a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp +++ b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp @@ -817,7 +817,7 @@ int slsReceiverTCPIPInterface::start_receiver(){ // send answer socket->SendDataOnly(&ret,sizeof(ret)); if(ret==FAIL){ - cprintf(RED, "%s\n", mess); + cprintf(RED, "Error:%s\n", mess); socket->SendDataOnly(mess,sizeof(mess)); } //return ok/fail @@ -1084,6 +1084,8 @@ int slsReceiverTCPIPInterface::read_frame(){ return eiger_read_frame(); case PROPIX: return propix_read_frame(); + case JUNGFRAU: + return jungfrau_read_frame(); default: return gotthard_read_frame(); } @@ -1608,22 +1610,6 @@ int slsReceiverTCPIPInterface::propix_read_frame(){ int slsReceiverTCPIPInterface::eiger_read_frame(){ ret=OK; - /** structure of an eiger packet*/ - typedef struct - { - unsigned char subframenum[4]; - unsigned char missingpacket[2]; - unsigned char portnum[1]; - unsigned char dynamicrange[1]; - } eiger_packet_header_t; - - typedef struct - { - unsigned char framenum[6]; - unsigned char packetnum[2]; - } eiger_packet_footer_t; - - char fName[MAX_STR_LENGTH]=""; int acquisitionIndex = -1; int frameIndex= -1; @@ -1686,7 +1672,7 @@ int slsReceiverTCPIPInterface::eiger_read_frame(){ if(dynamicrange == 32){ eiger_packet_header_t* wbuf_header; wbuf_header = (eiger_packet_header_t*) raw; - subframenumber = *( (uint32_t*) wbuf_header->subframenum); + subframenumber = *( (uint32_t*) wbuf_header->subFrameNumber); } #ifdef VERYVERBOSE @@ -1866,6 +1852,167 @@ int slsReceiverTCPIPInterface::eiger_read_frame(){ +int slsReceiverTCPIPInterface::jungfrau_read_frame(){ + ret=OK; + + char fName[MAX_STR_LENGTH]=""; + int acquisitionIndex = -1; + int frameIndex= -1; + uint64_t currentIndex=0; + uint64_t startAcquisitionIndex=0; + uint64_t startFrameIndex=0; + strcpy(mess,"Could not read frame\n"); + + + int frameSize = JFRAU_ONE_PACKET_SIZE * packetsPerFrame; + int dataSize = JFRAU_ONE_DATA_SIZE * packetsPerFrame; + int oneDataSize = JFRAU_ONE_DATA_SIZE; + + char* raw; + char* origVal = new char[frameSize]; + char* retval = new char[dataSize]; + char* blackpacket = new char[oneDataSize]; + + for(int i=0;igetFramesCaught()){ + startAcquisitionIndex=-1; +#ifdef VERYVERBOSE + cout<<"haven't caught any frame yet"<readFrame(fName,&raw,startAcquisitionIndex,startFrameIndex); + //send garbage with -1 index to try again + if (raw == NULL){ + startAcquisitionIndex = -1; +#ifdef VERYVERBOSE + cout<<"data not ready for gui yet"<frameNumber)); +#ifdef VERYVERBOSE + cout << "currentIndex:" << dec << currentIndex << endl; +#endif + + int64_t currentPacket = packetsPerFrame-1; + int offsetsrc = 0; + int offsetdest = 0; + uint64_t ifnum=-1; + uint64_t ipnum=-1; + + while(currentPacket >= 0){ + header = (jfrau_packet_header_t*) (origVal + offsetsrc); + ifnum = (*( (uint64_t*) header->frameNumber)); + ipnum = (*( (uint64_t*) header->packetNumber)); + if(ifnum != currentIndex) { + cout << "current packet " << currentPacket << " Wrong Frame number " << ifnum << ", copying blank packet" << endl; + memcpy(retval+offsetdest,blackpacket,oneDataSize); + offsetdest += oneDataSize; + //no need to increase offsetsrc as all packets will be wrong + currentPacket--; + continue; + } + if(ipnum!= currentPacket){ + cout << "current packet " << currentPacket << " Wrong packet number " << ipnum << ", copying blank packet" << endl; + memcpy(retval+offsetdest,blackpacket,oneDataSize); + offsetdest += oneDataSize; + //no need to increase offsetsrc until we get the right packet + currentPacket--; + continue; + } + offsetsrc+=JFRAU_HEADER_LENGTH; + memcpy(retval+offsetdest,origVal+offsetsrc,oneDataSize); + offsetdest += oneDataSize; + offsetsrc += oneDataSize; + currentPacket--; + } + + + acquisitionIndex = (int)(currentIndex-startAcquisitionIndex); + if(acquisitionIndex == -1) + startFrameIndex = -1; + else + frameIndex = (int)(currentIndex-startFrameIndex); +#ifdef VERY_VERY_DEBUG + cout << "acquisitionIndex calculated is:" << acquisitionIndex << endl; + cout << "frameIndex calculated is:" << frameIndex << endl; + cout << "currentIndex:" << currentIndex << endl; + cout << "startAcquisitionIndex:" << startAcquisitionIndex << endl; + cout << "startFrameIndex:" << startFrameIndex << endl; +#endif + } + } + +#ifdef VERYVERBOSE + if(frameIndex!=-1){ + cout << "fName:" << fName << endl; + cout << "acquisitionIndex:" << acquisitionIndex << endl; + cout << "frameIndex:" << frameIndex << endl; + cout << "startAcquisitionIndex:" << startAcquisitionIndex << endl; + cout << "startFrameIndex:" << startFrameIndex << endl; + } +#endif + + + +#endif + + if(ret==OK && socket->differentClients){ + FILE_LOG(logDEBUG) << "Force update"; + ret=FORCE_UPDATE; + } + + // send answer + socket->SendDataOnly(&ret,sizeof(ret)); + if(ret==FAIL){ + cprintf(RED,"%s\n",mess); + socket->SendDataOnly(mess,sizeof(mess)); + } + else{ + socket->SendDataOnly(fName,MAX_STR_LENGTH); + socket->SendDataOnly(&acquisitionIndex,sizeof(acquisitionIndex)); + socket->SendDataOnly(&frameIndex,sizeof(frameIndex)); + socket->SendDataOnly(retval,dataSize); + } + + delete [] retval; + delete [] origVal; + delete [] raw; + + return ret; +} + + + + + + int slsReceiverTCPIPInterface::set_read_frequency(){ ret=OK; int retval=-1; @@ -2323,7 +2470,8 @@ int slsReceiverTCPIPInterface::set_dynamic_range() { packetsPerFrame = EIGER_ONE_GIGA_CONSTANT * dynamicrange * EIGER_MAX_PORTS; else packetsPerFrame = EIGER_TEN_GIGA_CONSTANT * dynamicrange * EIGER_MAX_PORTS; - } + }else if (myDetectorType == JUNGFRAU) + packetsPerFrame = JFRAU_PACKETS_PER_FRAME; } } } From 74b1baa9d84eace60a6dde85138a8e1b8e5778db Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Fri, 27 Nov 2015 17:07:57 +0100 Subject: [PATCH 184/474] solved packet loss problem --- .../include/sls_receiver_defs.h | 2 +- .../src/UDPStandardImplementation.cpp | 26 +++++++++++++------ 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/slsReceiverSoftware/include/sls_receiver_defs.h b/slsReceiverSoftware/include/sls_receiver_defs.h index c11f6f8c0..7c500ece1 100755 --- a/slsReceiverSoftware/include/sls_receiver_defs.h +++ b/slsReceiverSoftware/include/sls_receiver_defs.h @@ -24,7 +24,7 @@ typedef int int32_t; #define SHORT_MAX_FRAMES_PER_FILE 100000 #define MOENCH_MAX_FRAMES_PER_FILE 1000 #define EIGER_MAX_FRAMES_PER_FILE 2000 -#define JFRAU_MAX_FRAMES_PER_FILE 2000 +#define JFRAU_MAX_FRAMES_PER_FILE 5 #define JFCTB_MAX_FRAMES_PER_FILE 100000 diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index fe86efd51..cd94e2e52 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1393,12 +1393,15 @@ int UDPStandardImplementation::createNewFile(){ previousFrameNumber = -1; cout << "File: " << completeFileName << endl; }else{ + if (previousFrameNumber == -1) + previousFrameNumber = startFrameIndex-1; + cout << completeFileName << "\tPacket Loss: " << setw(4)<= (uint32_t)maxPacketsPerFile){ //for packet loss, because currframenum is the latest one for eiger + //get frame number (eiger already gets it when it does packet to packet processing) if(myDetectorType != EIGER){ lastpacket = (((packetsToSave - 1) * onePacketSize) + offset); + if(myDetectorType == JUNGFRAU){ + jfrau_packet_header_t* header = (jfrau_packet_header_t*) (wbuffer[0] + lastpacket); + currentFrameNumber = (*( (uint64_t*) header->frameNumber)); + }else{ + tempframenumber = ((uint32_t)(*((uint32_t*)(wbuffer[0] + lastpacket)))); + //for gotthard and normal frame, increment frame number to separate fnum and pnum + if (myDetectorType == PROPIX ||(myDetectorType == GOTTHARD && shortFrameEnable == -1)) + tempframenumber++; + //get frame number + currentFrameNumber = (tempframenumber & frameIndexMask) >> frameIndexOffset; + } + + - //get frame number (eiger already gets it when it does packet to packet processing) - tempframenumber = ((uint32_t)(*((uint32_t*)(wbuffer[0] + lastpacket)))); - //for gotthard and normal frame, increment frame number to separate fnum and pnum - if (myDetectorType == PROPIX ||(myDetectorType == GOTTHARD && shortFrameEnable == -1)) - tempframenumber++; - //get frame number - currentFrameNumber = (tempframenumber & frameIndexMask) >> frameIndexOffset; //set indices acquisitionIndex = currentFrameNumber - startAcquisitionIndex; frameIndex = currentFrameNumber - startFrameIndex; From 6498292ee479ab7ebeb16c0f7de717af9f6d0f4f Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Fri, 27 Nov 2015 17:09:33 +0100 Subject: [PATCH 185/474] max packets per file forgotten at 5 --- slsReceiverSoftware/include/sls_receiver_defs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/slsReceiverSoftware/include/sls_receiver_defs.h b/slsReceiverSoftware/include/sls_receiver_defs.h index 7c500ece1..c11f6f8c0 100755 --- a/slsReceiverSoftware/include/sls_receiver_defs.h +++ b/slsReceiverSoftware/include/sls_receiver_defs.h @@ -24,7 +24,7 @@ typedef int int32_t; #define SHORT_MAX_FRAMES_PER_FILE 100000 #define MOENCH_MAX_FRAMES_PER_FILE 1000 #define EIGER_MAX_FRAMES_PER_FILE 2000 -#define JFRAU_MAX_FRAMES_PER_FILE 5 +#define JFRAU_MAX_FRAMES_PER_FILE 2000 #define JFCTB_MAX_FRAMES_PER_FILE 100000 From 34508012a8d3ed1f42f98a5de6aa4a8c71be5b46 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 1 Dec 2015 16:39:01 +0100 Subject: [PATCH 186/474] prevnumber is unsigned before bug --- slsReceiverSoftware/include/UDPStandardImplementation.h | 2 +- slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/slsReceiverSoftware/include/UDPStandardImplementation.h b/slsReceiverSoftware/include/UDPStandardImplementation.h index 0921ad934..e25594f8f 100644 --- a/slsReceiverSoftware/include/UDPStandardImplementation.h +++ b/slsReceiverSoftware/include/UDPStandardImplementation.h @@ -521,7 +521,7 @@ private: uint64_t currentFrameNumber; /** Previous Frame number from buffer to calculate loss */ - uint64_t previousFrameNumber; + int64_t previousFrameNumber; /* Acquisition started */ bool acqStarted; diff --git a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp index 3cb511b87..87d920440 100644 --- a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp +++ b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp @@ -1938,7 +1938,7 @@ int slsReceiverTCPIPInterface::jungfrau_read_frame(){ currentPacket--; continue; } - if(ipnum!= currentPacket){ + if((int64_t)ipnum!= currentPacket){ cout << "current packet " << currentPacket << " Wrong packet number " << ipnum << ", copying blank packet" << endl; memcpy(retval+offsetdest,blackpacket,oneDataSize); offsetdest += oneDataSize; From f16db2e6ca6ee7e2ba448b67ab255edb7fec939e Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Wed, 2 Dec 2015 09:39:16 +0100 Subject: [PATCH 187/474] 10giga offset corrected --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index ec0f964cb..d7e6989a3 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -568,7 +568,7 @@ int UDPStandardImplementation::setTenGigaEnable(const bool b){ frameSize = onePacketSize * packetsPerFrame; bufferSize = onePacketSize; maxPacketsPerFile = EIGER_MAX_FRAMES_PER_FILE * packetsPerFrame; - + footerOffset = EIGER_PACKET_HEADER_SIZE + oneDataSize; FILE_LOG(logDEBUG) << dec << "packetsPerFrame:" << packetsPerFrame << "\nonePacketSize:" << onePacketSize << @@ -1586,11 +1586,12 @@ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int lSize, in #ifdef MANUALDEBUG eiger_packet_header_t* header = (eiger_packet_header_t*) (buffer[ithread]+HEADER_SIZE_NUM_TOT_PACKETS); eiger_packet_footer_t* footer = (eiger_packet_footer_t*)(buffer[ithread] + footerOffset + HEADER_SIZE_NUM_TOT_PACKETS); - cprintf(GREEN,"thread:%d subframenum:%d oldpacketnum:%d new pnum:%d\n", - ithread, + cprintf(GREEN,"thread:%d footeroffset:%dsubframenum:%d oldpacketnum:%d new pnum:%d new fnum:%d\n", + ithread,footerOffset, (*( (unsigned int*) header->subFameNumber)), (*( (uint8_t*) header->dynamicRange)), - (*( (uint16_t*) footer->packetNumber))); + (*( (uint16_t*) footer->packetNumber)), + (uint32_t)(*( (uint64_t*) footer))); #endif From 18eb1274c5a7151abfa77332616b2451902776ce Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 15 Dec 2015 11:04:49 +0100 Subject: [PATCH 188/474] fixed fifodepth to return defualt size, also moved destroying and creating threads to fifostructure, had forgotten to override setnumberofframes calling fifostructure which is important for gotthard --- .../include/UDPBaseImplementation.h | 5 +- slsReceiverSoftware/include/UDPInterface.h | 3 +- .../include/UDPStandardImplementation.h | 11 ++ .../src/UDPBaseImplementation.cpp | 5 +- .../src/UDPStandardImplementation.cpp | 104 ++++++++---------- 5 files changed, 63 insertions(+), 65 deletions(-) diff --git a/slsReceiverSoftware/include/UDPBaseImplementation.h b/slsReceiverSoftware/include/UDPBaseImplementation.h index 2c544759b..568183e42 100644 --- a/slsReceiverSoftware/include/UDPBaseImplementation.h +++ b/slsReceiverSoftware/include/UDPBaseImplementation.h @@ -312,10 +312,11 @@ class UDPBaseImplementation : protected virtual slsReceiverDefs, public UDPInter /** * Set Number of Frames expected by receiver from detector - * The data receiver status will change from running to idle when it gets this number of frames FIXME: (Not implemented) + * The data receiver status will change from running to idle when it gets this number of frames * @param i number of frames expected + * @return OK or FAIL */ - void setNumberOfFrames(const uint64_t i); + int setNumberOfFrames(const uint64_t i); /** * Set Dynamic Range or Number of Bits Per Pixel diff --git a/slsReceiverSoftware/include/UDPInterface.h b/slsReceiverSoftware/include/UDPInterface.h index b00f038cb..9ad5a7e6a 100644 --- a/slsReceiverSoftware/include/UDPInterface.h +++ b/slsReceiverSoftware/include/UDPInterface.h @@ -371,8 +371,9 @@ class UDPInterface { * Set Number of Frames expected by receiver from detector * The data receiver status will change from running to idle when it gets this number of frames FIXME: (Not implemented) * @param i number of frames expected + * @return OK or FAIL */ - virtual void setNumberOfFrames(const uint64_t i) = 0; + virtual int setNumberOfFrames(const uint64_t i) = 0; /** * Set Dynamic Range or Number of Bits Per Pixel diff --git a/slsReceiverSoftware/include/UDPStandardImplementation.h b/slsReceiverSoftware/include/UDPStandardImplementation.h index 7ec6672aa..9a34f25d3 100644 --- a/slsReceiverSoftware/include/UDPStandardImplementation.h +++ b/slsReceiverSoftware/include/UDPStandardImplementation.h @@ -102,6 +102,15 @@ class UDPStandardImplementation: private virtual slsReceiverDefs, public UDPBase */ int setAcquisitionPeriod(const uint64_t i); + /** + * Overridden method + * Set Number of Frames expected by receiver from detector + * The data receiver status will change from running to idle when it gets this number of frames + * @param i number of frames expected + * @return OK or FAIL + */ + int setNumberOfFrames(const uint64_t i); + /** * Overridden method * Set Dynamic Range or Number of Bits Per Pixel @@ -253,6 +262,8 @@ private: /** * Set up the Fifo Structure for processing buffers * between listening and writer threads + * When the parameters ahve been determined and if fifostructure needs to be changes, + * the listerning and writing threads are also destroyed together with this * @return OK or FAIL */ int setupFifoStructure(); diff --git a/slsReceiverSoftware/src/UDPBaseImplementation.cpp b/slsReceiverSoftware/src/UDPBaseImplementation.cpp index 9a9b1723a..a76cf0e9f 100644 --- a/slsReceiverSoftware/src/UDPBaseImplementation.cpp +++ b/slsReceiverSoftware/src/UDPBaseImplementation.cpp @@ -334,11 +334,14 @@ int UDPBaseImplementation::setAcquisitionPeriod(const uint64_t i){ return OK; } -void UDPBaseImplementation::setNumberOfFrames(const uint64_t i){ +int UDPBaseImplementation::setNumberOfFrames(const uint64_t i){ FILE_LOG(logDEBUG) << __AT__ << " starting"; numberOfFrames = i; FILE_LOG(logINFO) << "Number of Frames:" << numberOfFrames; + + //overrridden child classes might return FAIL + return OK; } int UDPBaseImplementation::setDynamicRange(const uint32_t i){ diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index d7e6989a3..36f8aa436 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -282,23 +282,11 @@ int UDPStandardImplementation::setupFifoStructure(){ // fifo depth uint32_t oldFifoSize = fifoSize; - //default - if(!fifoDepth){ - switch(myDetectorType){ - case GOTTHARD: fifoSize = GOTTHARD_FIFO_SIZE; break; - case MOENCH: fifoSize = MOENCH_FIFO_SIZE; break; - case PROPIX: fifoSize = PROPIX_FIFO_SIZE; break; - case EIGER: fifoSize = EIGER_FIFO_SIZE * packetsPerFrame; break;//listens to 1 packet at a time and size depends on packetsperframe - default: break; - } - } - //change by user - else{ - if(myDetectorType == EIGER) - fifoSize = fifoDepth * packetsPerFrame; - else fifoSize = fifoDepth; - } + if(myDetectorType == EIGER) + fifoSize = fifoDepth * packetsPerFrame;//listens to 1 packet at a time and size depends on packetsperframe + else + fifoSize = fifoDepth; //reduce fifo depth if > 1 numberofJobsPerBuffer if(fifoSize % numberofJobsPerBuffer) @@ -313,6 +301,11 @@ int UDPStandardImplementation::setupFifoStructure(){ + //delete threads + if(threadStarted){ + createListeningThreads(true); + createWriterThreads(true); + } //set up fifo structure @@ -357,6 +350,18 @@ int UDPStandardImplementation::setupFifoStructure(){ } } cout << "Fifo structure(s) reconstructed" << endl; + + //create threads + if(createListeningThreads() == FAIL){ + FILE_LOG(logERROR) << "Could not create listening thread"; + return FAIL; + } + if(createWriterThreads() == FAIL){ + FILE_LOG(logERROR) << "Could not create writer threads"; + return FAIL; + } + setThreadPriorities(); + return OK; } @@ -483,11 +488,25 @@ int UDPStandardImplementation::setAcquisitionPeriod(const uint64_t i){ FILE_LOG(logDEBUG) << __AT__ << " called"; acquisitionPeriod = i; - if(setupFifoStructure() == FAIL) - return FAIL; + if((myDetectorType == GOTTHARD) && (myDetectorType == MOENCH)) + if(setupFifoStructure() == FAIL) + return FAIL; FILE_LOG(logINFO) << "Acquisition Period: " << (double)acquisitionPeriod/(1E9) << "s"; + return OK; +} + + +int UDPStandardImplementation::setNumberOfFrames(const uint64_t i){ + FILE_LOG(logDEBUG) << __AT__ << " called"; + + numberOfFrames = i; + if((myDetectorType == GOTTHARD) && (myDetectorType == MOENCH)) + if(setupFifoStructure() == FAIL) + return FAIL; + + FILE_LOG(logINFO) << "Number of Frames:" << numberOfFrames; return OK; } @@ -511,30 +530,15 @@ int UDPStandardImplementation::setDynamicRange(const uint32_t i){ //new dynamic range, then restart threads and resetup fifo structure if(oldDynamicRange != dynamicRange){ - //delete threads - if(threadStarted){ - createListeningThreads(true); - createWriterThreads(true); - } - //gui buffer if(latestData){delete[] latestData; latestData = NULL;} latestData = new char[frameSize]; //restructure fifo + numberofJobsPerBuffer = -1; if(setupFifoStructure() == FAIL) return FAIL; - //create threads - if(createListeningThreads() == FAIL){ - FILE_LOG(logERROR) << "Could not create listening thread"; - return FAIL; - } - if(createWriterThreads() == FAIL){ - FILE_LOG(logERROR) << "Could not create writer threads"; - return FAIL; - } - setThreadPriorities(); } } @@ -582,12 +586,6 @@ int UDPStandardImplementation::setTenGigaEnable(const bool b){ //new enable, then restart threads and resetup fifo structure if(oldTenGigaEnable != tengigaEnable){ - //delete threads - if(threadStarted){ - createListeningThreads(true); - createWriterThreads(true); - } - //gui buffer if(latestData){delete[] latestData; latestData = NULL;} latestData = new char[frameSize]; @@ -596,16 +594,6 @@ int UDPStandardImplementation::setTenGigaEnable(const bool b){ if(setupFifoStructure() == FAIL) return FAIL; - //create threads - if(createListeningThreads() == FAIL){ - FILE_LOG(logERROR) << "Could not create listening thread"; - return FAIL; - } - if(createWriterThreads() == FAIL){ - FILE_LOG(logERROR) << "Could not create writer threads"; - return FAIL; - } - setThreadPriorities(); } } @@ -674,6 +662,7 @@ int UDPStandardImplementation::setDetectorType(const detectorType d){ packetIndexMask = GOTTHARD_PACKET_INDEX_MASK; maxPacketsPerFile = MAX_FRAMES_PER_FILE * GOTTHARD_PACKETS_PER_FRAME; fifoSize = GOTTHARD_FIFO_SIZE; + fifoDepth = GOTTHARD_FIFO_SIZE; //footerOffset = Not applicable; break; case PROPIX: @@ -687,6 +676,7 @@ int UDPStandardImplementation::setDetectorType(const detectorType d){ packetIndexMask = PROPIX_PACKET_INDEX_MASK; maxPacketsPerFile = MAX_FRAMES_PER_FILE * PROPIX_PACKETS_PER_FRAME; fifoSize = PROPIX_FIFO_SIZE; + fifoDepth = PROPIX_FIFO_SIZE; //footerOffset = Not applicable; break; case MOENCH: @@ -700,6 +690,7 @@ int UDPStandardImplementation::setDetectorType(const detectorType d){ packetIndexMask = MOENCH_PACKET_INDEX_MASK; maxPacketsPerFile = MOENCH_MAX_FRAMES_PER_FILE * MOENCH_PACKETS_PER_FRAME; fifoSize = MOENCH_FIFO_SIZE; + fifoDepth = MOENCH_FIFO_SIZE; //footerOffset = Not applicable; break; case EIGER: @@ -714,6 +705,7 @@ int UDPStandardImplementation::setDetectorType(const detectorType d){ packetIndexMask = EIGER_PACKET_INDEX_MASK; maxPacketsPerFile = EIGER_MAX_FRAMES_PER_FILE * packetsPerFrame; fifoSize = EIGER_FIFO_SIZE; + fifoDepth = EIGER_FIFO_SIZE; footerOffset = EIGER_PACKET_HEADER_SIZE + oneDataSize; break; case JUNGFRAUCTB: @@ -728,6 +720,7 @@ int UDPStandardImplementation::setDetectorType(const detectorType d){ packetIndexMask = JCTB_PACKET_INDEX_MASK; maxPacketsPerFile = JFCTB_MAX_FRAMES_PER_FILE * JCTB_PACKETS_PER_FRAME; fifoSize = JCTB_FIFO_SIZE; + fifoDepth = JCTB_FIFO_SIZE; //footerOffset = Not applicable; break; default: @@ -749,17 +742,6 @@ int UDPStandardImplementation::setDetectorType(const detectorType d){ numberofJobsPerBuffer = -1; setupFifoStructure(); - //create threads - if(createListeningThreads() == FAIL){ - FILE_LOG(logERROR) << "Could not create listening thread"; - return FAIL; - } - if(createWriterThreads() == FAIL){ - FILE_LOG(logERROR) << "Could not create writer threads"; - return FAIL; - } - setThreadPriorities(); - //allocate for latest data (frame copy for gui) latestData = new char[frameSize]; From bb78d1af738dc4d9b646f3679397bbf0ed43947a Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 15 Dec 2015 11:59:17 +0100 Subject: [PATCH 189/474] solved recover from root permission error --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 36f8aa436..39d25e1ef 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -827,7 +827,8 @@ int UDPStandardImplementation::startReceiver(char *c){ //stop udp socket shutDownUDPSockets(); sprintf(c,"Could not create file %s.",completeFileName); - FILE_LOG(logERROR) << c; + //FILE_LOG(logERROR) << c; + for(int i=0; i < numberofWriterThreads; i++) sem_post(&writerSemaphore[i]); return FAIL; } @@ -1308,8 +1309,10 @@ int UDPStandardImplementation::setupWriter(){ #endif } - FILE_LOG(logDEBUG) << "Successfully created file(s)"; - cout << "Writer Ready ..." << endl; + if(fileCreateSuccess == OK){ + FILE_LOG(logDEBUG) << "Successfully created file(s)"; + cout << "Writer Ready ..." << endl; + } return fileCreateSuccess; } From deb72feb912fcc62a49acf719e45e949e0ee499d Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 19 Jan 2016 14:39:58 +0100 Subject: [PATCH 190/474] still not resolved altho some changes --- .../src/UDPStandardImplementation.cpp | 347 ++++++++++++++---- 1 file changed, 285 insertions(+), 62 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 39d25e1ef..682d82e19 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1964,7 +1964,10 @@ void UDPStandardImplementation::processWritingBufferPacketByPacket(int ithread){ blankframe[i] = new char[onePacketSize]; //set missing packet to 0xff eiger_packet_header_t* blankframe_header = (eiger_packet_header_t*) blankframe[i]; + eiger_packet_footer_t* blankframe_footer = (eiger_packet_footer_t*)(blankframe[i] + footerOffset); *( (uint16_t*) blankframe_header->missingPacket) = missingPacketValue; + *( (uint16_t*) blankframe_footer->packetNumber) = i+1; + //set each value inside blank frame to 0xff for(int j=0;j<(oneDataSize);++j){ unsigned char* blankframe_data = (unsigned char*)blankframe[i] + sizeof(eiger_packet_header_t) + j; @@ -1980,11 +1983,29 @@ void UDPStandardImplementation::processWritingBufferPacketByPacket(int ithread){ //until mask unset (udp sockets shut down by client) while((1 << ithread) & writerThreadsMask){ + /* for(int iloop=0;ilooppacketNumber), + (uint32_t)(*( (uint64_t*) wbuf_footer)), + *( (uint16_t*) wbuf_header->missingPacket)); + cout<packetNumber), + (uint32_t)(*( (uint64_t*) wbuf_footer)), + *( (uint16_t*) wbuf_header->missingPacket)); + cout<packetNumber), + (uint32_t)(*( (uint64_t*) wbuf_footer)), + *( (uint16_t*) wbuf_header->missingPacket)); + cout<packetNumber), + (uint32_t)(*( (uint64_t*) wbuf_footer)), + *( (uint16_t*) wbuf_header->missingPacket)); + cout<packetNumber); + cprintf(MAGENTA,"Fifo %d: threadframenumber original-1:%d currentpacketnumber real:%d\n", + i,threadFrameNumber[i],currentPacketNumber[i]); } - + /* for(int iloop=0;ilooppacketNumber), + (uint32_t)(*( (uint64_t*) wbuf_footer)), + *( (uint16_t*) wbuf_header->missingPacket)); + cout<packetNumber), + (uint32_t)(*( (uint64_t*) wbuf_footer)), + *( (uint16_t*) wbuf_header->missingPacket)); + cout<packetNumber), + (uint32_t)(*( (uint64_t*) wbuf_footer)), + *( (uint16_t*) wbuf_header->missingPacket)); + cout<packetNumber), + (uint32_t)(*( (uint64_t*) wbuf_footer)), + *( (uint16_t*) wbuf_header->missingPacket)); + cout<packetNumber), + (uint32_t)(*( (uint64_t*) wbuf_footer)), + *( (uint16_t*) wbuf_header->missingPacket)); + cout<packetNumber), + (uint32_t)(*( (uint64_t*) wbuf_footer)), + *( (uint16_t*) wbuf_header->missingPacket)); + cout<missingPacket)!= missingPacketValue){ eiger_packet_header_t* blankframe_header = (eiger_packet_header_t*) blankframe[blankoffset]; - cprintf(BG_RED, "Fifo %d: Missing Packet Error: Adding blank packets mismatch " + cprintf(BG_RED, "Fifo %d: Add Missing Packet Error: " "pnum_offset %d, pnum %d, fnum_thread %d, missingpacket_buffer 0x%x, missingpacket_blank 0x%x\n", i,frameBufferoffset[i],currentPacketNumber[i],threadFrameNumber[i], *( (uint16_t*) frameBuffer_header->missingPacket), *( (uint16_t*) blankframe_header->missingPacket)); exit(-1); }else{ -#ifdef DEBUG4 - cprintf(RED, "Fifo %d: Missing Packet: Adding blank packets success " - "pnum_offset %d, pnum %d, fnum_thread %d, missingpacket_buffer 0x%x\n", +//#ifdef DEBUG4 + cprintf(RED, "Fifo %d: Add Missing Packet success: " + "pnum_offset %d, pnum_got %d, fnum_thread %d, missingpacket_buffer 0x%x\n", i,frameBufferoffset[i],currentPacketNumber[i],threadFrameNumber[i], *( (uint16_t*) frameBuffer_header->missingPacket)); -#endif - frameBufferoffset[i]++; - blankoffset++; +//#endif + frameBufferoffset[i]=frameBufferoffset[i]+1; + //blankoffset++; } } + popReady[i] = false; + if((numPackets[i] == dummyPacketValue) ||(threadFrameNumber[i] != presentFrameNumber)) + fullframe[i] = true; + else + fullframe[i] = false; + if(threadFrameNumber[i] != presentFrameNumber) + threadFrameNumber[i] = presentFrameNumber; + //missed packets/future packet: do not pop over and determine fullframe-------------------- if(numberofMissingPackets[i]){ - popReady[i] = false; - if((numPackets[i] == dummyPacketValue) ||(threadFrameNumber[i] != presentFrameNumber)) - fullframe[i] = true; - else{ - fullframe[i] = false; + //popReady[i] = false; + //if((numPackets[i] == dummyPacketValue) ||(threadFrameNumber[i] != presentFrameNumber)) + // fullframe[i] = true; + //else{ + // fullframe[i] = false; //update last packet - lastPacketNumber[i] = currentPacketNumber[i] - 1; - } - if(threadFrameNumber[i] != presentFrameNumber) - threadFrameNumber[i] = presentFrameNumber; + //lastPacketNumber[i] = currentPacketNumber[i] - 1; + //} + //if(threadFrameNumber[i] != presentFrameNumber) + // threadFrameNumber[i] = presentFrameNumber; numMissingPackets += numberofMissingPackets[i]; } - //no missed packet: add current packet-------------------------------------------------------------- - else{ + /*for(int iloop=0;ilooppacketNumber), + (uint32_t)(*( (uint64_t*) wbuf_footer)), + *( (uint16_t*) wbuf_header->missingPacket)); + cout<packetNumber), + (uint32_t)(*( (uint64_t*) wbuf_footer)), + *( (uint16_t*) wbuf_header->missingPacket)); + cout<packetNumber),threadFrameNumber[i], *( (uint16_t*) frameBuffer_header->missingPacket)); -#endif - frameBufferoffset[i]++; +//#endif + frameBufferoffset[i]=frameBufferoffset[i]+1; //update last packet lastPacketNumber[i] = currentPacketNumber[i]; popReady[i] = true; fullframe[i] = false; if(currentPacketNumber[i] == LAST_PACKET_VALUE){ -#ifdef DEBUG4 +//#ifdef DEBUG4 cprintf(GREEN, "Fifo %d: Got last packet\n",i); -#endif +//#endif popReady[i] = false; fullframe[i] = true; } @@ -2121,15 +2243,31 @@ void UDPStandardImplementation::processWritingBufferPacketByPacket(int ithread){ } } + /* for(int iloop=0;ilooppacketNumber), + (uint32_t)(*( (uint64_t*) wbuf_footer)), + *( (uint16_t*) wbuf_header->missingPacket)); + cout<packetNumber), + (uint32_t)(*( (uint64_t*) wbuf_footer)), + *( (uint16_t*) wbuf_header->missingPacket)); + cout<packetNumber), + (uint32_t)(*( (uint64_t*) wbuf_footer)), + *( (uint16_t*) wbuf_header->missingPacket)); + cout<packetNumber), + (uint32_t)(*( (uint64_t*) wbuf_footer)), + *( (uint16_t*) wbuf_header->missingPacket)); + cout<packetNumber), + (uint32_t)(*( (uint64_t*) wbuf_footer)), + *( (uint16_t*) wbuf_header->missingPacket)); + cout<packetNumber), + (uint32_t)(*( (uint64_t*) wbuf_footer)), + *( (uint16_t*) wbuf_header->missingPacket)); + cout<isEmpty()){ @@ -2173,24 +2345,57 @@ void UDPStandardImplementation::processWritingBufferPacketByPacket(int ithread){ if((numPackets[i] != dummyPacketValue) && (currentPacketNumber[i] == LAST_PACKET_VALUE)) popReady[i] = true; frameBufferoffset[i] = (i*packetsPerFrame/numberofListeningThreads); - blankoffset = 0; + //blankoffset = 0; lastPacketNumber[i] = 0; currentPacketNumber[i] = 0; numberofMissingPackets[i] = 0; } + } + /* for(int iloop=0;ilooppacketNumber), + (uint32_t)(*( (uint64_t*) wbuf_footer)), + *( (uint16_t*) wbuf_header->missingPacket)); + cout<packetNumber), + (uint32_t)(*( (uint64_t*) wbuf_footer)), + *( (uint16_t*) wbuf_header->missingPacket)); + cout<packetNumber), (void*)(packetBuffer[i])); + i,popReady[i],(uint32_t)(*( (uint64_t*) wbuf_footer1)), + *( (uint16_t*) wbuf_footer1->packetNumber), (void*)(packetBuffer[i])); } #endif + /*for(int iloop=0;ilooppacketNumber), + (uint32_t)(*( (uint64_t*) wbuf_footer)), + *( (uint16_t*) wbuf_header->missingPacket)); + cout<packetNumber), + (uint32_t)(*( (uint64_t*) wbuf_footer)), + *( (uint16_t*) wbuf_header->missingPacket)); + cout<packetNumber)); } -#endif +//#endif if(myDetectorType == EIGER){ while(!fifoTempFree[i]->push(wbuffer[i])); } @@ -2548,14 +2753,21 @@ void UDPStandardImplementation::createHeaders(char* wbuffer[]){ int port = 0, missingPacket; + bool exitVal = 0; + cprintf(GREEN,"packetsperframe:%d\n",packetsPerFrame); for (uint32_t i = 0; i < packetsPerFrame; i++){ eiger_packet_header_t* wbuf_header = (eiger_packet_header_t*) wbuffer[i]; eiger_packet_footer_t* wbuf_footer = (eiger_packet_footer_t*)(wbuffer[i] + footerOffset); #ifdef DEBUG4 - cprintf(GREEN, "Loop index:%d Pnum:%d\n",i,*( (uint16_t*) wbuf_footer->packetNumber)); + cprintf(GREEN, "Loop index:%d Pnum:%d real fnum %d,missingPacket 0x%x\n", + i, + *( (uint16_t*) wbuf_footer->packetNumber), + (uint32_t)(*( (uint64_t*) wbuf_footer)), + *( (uint16_t*) wbuf_header->missingPacket) + ); cout <missingPacket)== missingPacketValue){ #ifdef DEBUG4 - cprintf(GREEN,"Missing packet at %d\n", i+1); + cprintf(RED,"-Missing packet at Loop Index %d\n", i); #endif missingPacket = 1; - //add frame and packet numbers - *( (uint64_t*) wbuf_footer) = (uint64_t)((currentFrameNumber+1)); - *( (uint16_t*) wbuf_footer->packetNumber) = (i+1); + //add frame number + *( (uint64_t*) wbuf_footer) = (currentFrameNumber+1) | (((uint64_t)(*( (uint16_t*) wbuf_footer->packetNumber)))<<0x30); + //*( (uint16_t*) wbuf_footer->packetNumber) = (i+1); +#ifdef DEBUG4 + cprintf(RED, "Missing Packet Loop index:%d fnum:%d Pnum:%d\n",i, + (uint32_t)(*( (uint64_t*) wbuf_footer)), + *( (uint16_t*) wbuf_footer->packetNumber)); +#endif } //normal packet else{ @@ -2579,14 +2796,20 @@ void UDPStandardImplementation::createHeaders(char* wbuffer[]){ //DEBUGGING if(*( (uint16_t*) wbuf_footer->packetNumber) != (i+1)){ cprintf(BG_RED, "Writing_Thread: Packet Number Mismatch! " - "i %d, pnum %d, fnum %lld, missingPacket 0x%x\n", - i,*( (uint16_t*) wbuf_footer->packetNumber),(long long int)currentFrameNumber,*( (uint16_t*) wbuf_header->missingPacket)); - exit(-1); + "i %d, real pnum %d, real fnum %d, missingPacket 0x%x\n", + i, + *( (uint16_t*) wbuf_footer->packetNumber), + (uint32_t)(*( (uint64_t*) wbuf_footer)), + *( (uint16_t*) wbuf_header->missingPacket)); + exitVal =1; } //overwriting port number and dynamic range *( (uint8_t*) wbuf_header->portIndex) = port; *( (uint8_t*) wbuf_header->dynamicRange) = dynamicRange; } + + if(exitVal){exit(-1);} + } From 39c3a712e1e1750b3e8af7535bbbaecfcd4c16d1 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Mon, 1 Feb 2016 17:57:43 +0100 Subject: [PATCH 191/474] solved a bit, but not the create fiel problem --- .../src/UDPStandardImplementation.cpp | 379 ++++++++++++------ 1 file changed, 262 insertions(+), 117 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 682d82e19..b814d4c06 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -313,16 +313,20 @@ int UDPStandardImplementation::setupFifoStructure(){ //deleting if(fifoFree[i]){ - while(!fifoFree[i]->isEmpty()) + while(!fifoFree[i]->isEmpty()){ fifoFree[i]->pop(buffer[i]); + //cprintf(BLUE,"FifoFree[%d]: value:%d, pop 0x%x\n",i,fifoFree[i]->getSemValue(),(void*)(buffer[i])); + } #ifdef DEBUG5 cprintf(BLUE,"Info: %d fifostructure popped from fifofree %p\n", i, (void*)(buffer[i])); #endif delete fifoFree[i]; } if(fifo[i]){ - while(!fifo[i]->isEmpty()) + while(!fifo[i]->isEmpty()){ fifo[i]->pop(buffer[i]); + //cprintf(CYAN,"Fifo[%d]: value:%d, pop 0x%x\n",i,fifo[i]->getSemValue(),(void*)(buffer[i])); + } delete fifo[i]; } if(mem0[i]) free(mem0[i]); @@ -341,8 +345,13 @@ int UDPStandardImplementation::setupFifoStructure(){ //push free address into fifoFree buffer[i]=mem0[i]; while (buffer[i] < (mem0[i]+(bufferSize * numberofJobsPerBuffer + HEADER_SIZE_NUM_TOT_PACKETS) * (fifoSize-1))) { - fifoFree[i]->push(buffer[i]); + //cprintf(BLUE,"fifofree %d: push 0x%p\n",i,(void*)buffer[i]); + /*for(int k=0;kpush(buffer[i])); + //cprintf(GREEN,"Fifofree[%d]: value:%d, push 0x%x\n",i,fifoFree[i]->getSemValue(),(void*)(buffer[i])); #ifdef DEBUG5 cprintf(BLUE,"Info: %d fifostructure free pushed into fifofree %p\n", i, (void*)(buffer[i])); #endif @@ -897,11 +906,12 @@ void UDPStandardImplementation::stopReceiver(){ int UDPStandardImplementation::shutDownUDPSockets(){ FILE_LOG(logDEBUG) << __AT__ << " called"; - FILE_LOG(logDEBUG) << "Info: Shutting down UDP Socket(s)"; + for(int i=0;iShutDownSocket(); + FILE_LOG(logINFO) << "Info: Shut down UDP Socket " << i << endl; delete udpSocket[i]; udpSocket[i] = NULL; } @@ -934,9 +944,9 @@ void UDPStandardImplementation::startReadout(){ prev = -1; //wait as long as there is change from prev totalP while(prev != totalP){ -#ifdef DEBUG5 +//#ifdef DEBUG5 cprintf(MAGENTA,"waiting for all packets totalP:%d\n",totalP); -#endif +//#endif usleep(5000);/* Need to find optimal time (exposure time and acquisition period) **/ prev = totalP; @@ -1476,6 +1486,11 @@ void UDPStandardImplementation::startListening(){ //pop from fifo fifoFree[ithread]->pop(buffer[ithread]); + +#ifdef EVERYFIFODEBUG + if(fifoFree[ithread]->getSemValue()<100) + cprintf(BLUE,"FifoFree[%d]: value:%d, pop 0x%x\n",ithread,fifoFree[ithread]->getSemValue(),(void*)(buffer[ithread])); +#endif #ifdef CFIFODEBUG if(ithread == 0) cprintf(CYAN,"Listening_Thread %d :Listener popped from fifofree %p\n", ithread, (void*)(buffer[ithread])); @@ -1492,7 +1507,6 @@ void UDPStandardImplementation::startListening(){ rc = prepareAndListenBuffer(ithread, listenSize, carryonBufferSize, tempBuffer); - //start indices for each start of scan/acquisition if((!measurementStarted) && (rc > 0)){ pthread_mutex_lock(&progressMutex); @@ -1518,6 +1532,10 @@ void UDPStandardImplementation::startListening(){ //push buffer to FIFO while(!fifo[ithread]->push(buffer[ithread])); +#ifdef EVERYFIFODEBUG + if(fifo[ithread]->getSemValue()>(fifoSize-100)) + cprintf(MAGENTA,"Fifo[%d]: value:%d, push 0x%x\n",ithread,fifo[ithread]->getSemValue(),(void*)(buffer[ithread])); +#endif #ifdef CFIFODEBUG if(ithread == 0) cprintf(CYAN,"Listening_Thread %d: Listener pushed into fifo %p\n",ithread, (void*)(buffer[ithread])); @@ -1549,6 +1567,7 @@ void UDPStandardImplementation::startListening(){ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int lSize, int cSize, char* temp){ FILE_LOG(logDEBUG) << __AT__ << " called"; + int testbit = 0; //listen to UDP packets if(cSize) @@ -1558,8 +1577,11 @@ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int lSize, in //throw away packets that is not one packet size, need to check status if socket is shut down while(status != TRANSMITTING && myDetectorType == EIGER && receivedSize != onePacketSize) { - if(receivedSize != EIGER_HEADER_LENGTH) + if(receivedSize != EIGER_HEADER_LENGTH){ cprintf(RED,"Listening_Thread %d: Listened to a weird packet size %d\n",ithread, receivedSize); + }/*else{ + testbit = 1; + }*/ #ifdef DEBUG else cprintf(BLUE,"Listening_Thread %d: Listened to a header packet\n",ithread); @@ -1567,6 +1589,11 @@ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int lSize, in receivedSize = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS); } totalListeningFrameCount[ithread] += (receivedSize/onePacketSize); + /*if(testbit == 1){ + testbit = 0; + eiger_packet_footer_t* footer = (eiger_packet_footer_t*)(buffer[ithread] + footerOffset + HEADER_SIZE_NUM_TOT_PACKETS); + cprintf(CYAN,"Listening_Thread %d: fnum:%d\n",ithread,(uint32_t)(*( (uint64_t*) footer))); + }*/ #ifdef MANUALDEBUG eiger_packet_header_t* header = (eiger_packet_header_t*) (buffer[ithread]+HEADER_SIZE_NUM_TOT_PACKETS); @@ -1631,9 +1658,9 @@ void UDPStandardImplementation::startFrameIndices(int ithread){ void UDPStandardImplementation::stopListening(int ithread, int numbytes){ FILE_LOG(logDEBUG) << __AT__ << " called"; -#ifdef DEBUG4 - cprintf(BLUE,"Listening_Thread %d: Stop Listening\nStatus: %s\n", ithread, runStatusType(status).c_str()); -#endif +//#ifdef DEBUG4 + cprintf(BG_RED,"Listening_Thread %d: Stop Listening\nStatus: %s numbytes:%d\n", ithread, runStatusType(status).c_str(),numbytes); +//#endif //less than 1 packet size (especially for eiger), ignore the buffer (so that 2 dummy buffers are not sent with pc=0) if(numbytes < onePacketSize) @@ -1644,6 +1671,10 @@ void UDPStandardImplementation::stopListening(int ithread, int numbytes){ if(numbytes <= 0){ cprintf(BLUE,"Listening_Thread %d :End of Acquisition\n", ithread); while(!fifoFree[ithread]->push(buffer[ithread])); +#ifdef EVERYFIFODEBUG + if(fifoFree[ithread]->getSemValue()<100) + cprintf(GREEN,"Fifofree[%d]: value:%d, push 0x%x\n",ithread,fifoFree[ithread]->getSemValue(),(void*)(buffer[ithread])); +#endif #ifdef CFIFODEBUG if(ithread == 0) cprintf(CYAN,"Listening_Thread %d :Listener push empty buffer into fifofree %p\n", ithread, (void*)(buffer[ithread])); @@ -1657,11 +1688,15 @@ void UDPStandardImplementation::stopListening(int ithread, int numbytes){ else{ (*((uint32_t*)(buffer[ithread]))) = numbytes/onePacketSize; totalListeningFrameCount[ithread] += (numbytes/onePacketSize); -#ifdef DEBUG +//#ifdef DEBUG cprintf(BLUE,"Listening_Thread %d: Last Buffer numBytes:%d\n",ithread, numbytes); cprintf(BLUE,"Listening_Thread %d: Last Buffer packet count:%d\n",ithread, numbytes/onePacketSize); -#endif +//#endif while(!fifo[ithread]->push(buffer[ithread])); +#ifdef EVERYFIFODEBUG + if(fifo[ithread]->getSemValue()>(fifoSize-100)) + cprintf(MAGENTA,"Fifo[%d]: value:%d, push 0x%x\n",ithread,fifo[ithread]->getSemValue(),(void*)(buffer[ithread])); +#endif #ifdef CFIFODEBUG if(ithread == 0) cprintf(CYAN,"Listening_Thread %d: Listener Last Buffer pushed into fifo %p\n", ithread,(void*)(buffer[ithread])); @@ -1673,6 +1708,10 @@ void UDPStandardImplementation::stopListening(int ithread, int numbytes){ //push dummy-end buffer into fifo for all writer threads for(int i=0; ipop(buffer[ithread]); +#ifdef EVERYFIFODEBUG + if(fifoFree[ithread]->getSemValue()<100) + cprintf(BLUE,"FifoFree[%d]: value:%d, pop 0x%x\n",ithread,fifoFree[ithread]->getSemValue(),(void*)(buffer[ithread])); +#endif #ifdef CFIFODEBUG if(ithread == 0) cprintf(CYAN,"Listening_Thread %d: Popped Dummy from fifoFree %p\n", ithread,(void*)(buffer[ithread])); @@ -1682,6 +1721,10 @@ void UDPStandardImplementation::stopListening(int ithread, int numbytes){ //creating dummy-end buffer with pc=0xFFFF (*((uint32_t*)(buffer[ithread]))) = dummyPacketValue; while(!fifo[ithread]->push(buffer[ithread])); +#ifdef EVERYFIFODEBUG + if(fifo[ithread]->getSemValue()>(fifoSize-100)) + cprintf(MAGENTA,"Fifo[%d]: value:%d, push 0x%x\n",ithread,fifo[ithread]->getSemValue(),(void*)(buffer[ithread])); +#endif #ifdef CFIFODEBUG if(ithread == 0) cprintf(CYAN,"Listening_Thread %d: Listener pushed dummy-end buffer into fifo %p\n", ithread,(void*)(buffer[ithread])); @@ -1850,6 +1893,10 @@ void UDPStandardImplementation::processWritingBuffer(int ithread){ while((1 << ithread) & writerThreadsMask){ //pop fifo[0]->pop(wbuf[0]); +#ifdef EVERYFIFODEBUG + if(fifo[0]->getSemValue()>(fifoSize-100)) + cprintf(CYAN,"Fifo[%d]: value:%d, pop 0x%x\n",0,fifo[0]->getSemValue(),(void*)(wbuf[0])); +#endif #ifdef DEBUG5 cprintf(GREEN,"Writing_Thread %d: Popped %p from FIFO %d\n", ithread, (void*)(wbuf[0]),0); #endif @@ -1952,8 +1999,13 @@ void UDPStandardImplementation::processWritingBufferPacketByPacket(int ithread){ //circular temp fifo between getting a whole frame and freeing them if(fifoTempFree[i]){ - while(!fifoTempFree[i]->isEmpty()) + while(!fifoTempFree[i]->isEmpty()){ fifoTempFree[i]->pop(temp); +#ifdef EVERYFIFODEBUG + if(fifoTempFree[i]->getSemValue()>((packetsPerFrame/numberofListeningThreads)-3)) + cprintf(RED,"FifoTempFree[%d]: value:%d, pop 0x%x\n",i,fifoTempFree[i]->getSemValue(),(void*)(temp)); +#endif + } delete fifoTempFree[i]; } fifoTempFree[i] = new CircularFifo(MAX_NUM_PACKETS); @@ -1983,29 +2035,34 @@ void UDPStandardImplementation::processWritingBufferPacketByPacket(int ithread){ //until mask unset (udp sockets shut down by client) while((1 << ithread) & writerThreadsMask){ - /* for(int iloop=0;ilooppacketNumber), (uint32_t)(*( (uint64_t*) wbuf_footer)), - *( (uint16_t*) wbuf_header->missingPacket)); + *( (uint16_t*) wbuf_header->missingPacket), + (void*)frameBuffer[iloop]); cout<packetNumber), (uint32_t)(*( (uint64_t*) wbuf_footer)), - *( (uint16_t*) wbuf_header->missingPacket)); + *( (uint16_t*) wbuf_header->missingPacket), + (void*)frameBuffer[iloop]); cout<packetNumber), (uint32_t)(*( (uint64_t*) wbuf_footer)), *( (uint16_t*) wbuf_header->missingPacket)); @@ -2023,13 +2084,13 @@ void UDPStandardImplementation::processWritingBufferPacketByPacket(int ithread){ } for(int iloop=64;ilooppacketNumber), (uint32_t)(*( (uint64_t*) wbuf_footer)), *( (uint16_t*) wbuf_header->missingPacket)); cout<packetNumber); - cprintf(MAGENTA,"Fifo %d: threadframenumber original-1:%d currentpacketnumber real:%d\n", +#ifdef DEBUG4 + cprintf(MAGENTA,"Fifo %d: threadframenumber original:%d currentpacketnumber real:%d\n", i,threadFrameNumber[i],currentPacketNumber[i]); +#endif } - /* for(int iloop=0;ilooppacketNumber), - (uint32_t)(*( (uint64_t*) wbuf_footer)), - *( (uint16_t*) wbuf_header->missingPacket)); - cout<packetNumber), - (uint32_t)(*( (uint64_t*) wbuf_footer)), - *( (uint16_t*) wbuf_header->missingPacket)); - cout<packetNumber), (uint32_t)(*( (uint64_t*) wbuf_footer)), *( (uint16_t*) wbuf_header->missingPacket)); cout<packetNumber), (uint32_t)(*( (uint64_t*) wbuf_footer)), *( (uint16_t*) wbuf_header->missingPacket)); cout<packetNumber), (uint32_t)(*( (uint64_t*) wbuf_footer)), *( (uint16_t*) wbuf_header->missingPacket)); cout<packetNumber), (uint32_t)(*( (uint64_t*) wbuf_footer)), *( (uint16_t*) wbuf_header->missingPacket)); cout<missingPacket)!= missingPacketValue){ @@ -2156,12 +2206,12 @@ void UDPStandardImplementation::processWritingBufferPacketByPacket(int ithread){ *( (uint16_t*) blankframe_header->missingPacket)); exit(-1); }else{ -//#ifdef DEBUG4 +#ifdef DEBUG4 cprintf(RED, "Fifo %d: Add Missing Packet success: " "pnum_offset %d, pnum_got %d, fnum_thread %d, missingpacket_buffer 0x%x\n", i,frameBufferoffset[i],currentPacketNumber[i],threadFrameNumber[i], *( (uint16_t*) frameBuffer_header->missingPacket)); -//#endif +#endif frameBufferoffset[i]=frameBufferoffset[i]+1; //blankoffset++; } @@ -2189,25 +2239,26 @@ void UDPStandardImplementation::processWritingBufferPacketByPacket(int ithread){ // threadFrameNumber[i] = presentFrameNumber; numMissingPackets += numberofMissingPackets[i]; } - - /*for(int iloop=0;ilooppacketNumber), (uint32_t)(*( (uint64_t*) wbuf_footer)), *( (uint16_t*) wbuf_header->missingPacket)); cout<packetNumber), (uint32_t)(*( (uint64_t*) wbuf_footer)), *( (uint16_t*) wbuf_header->missingPacket)); cout<push(packetBuffer[i])); +#ifdef EVERYFIFODEBUG + if(fifoTempFree[i]->getSemValue()>((packetsPerFrame/numberofListeningThreads)-3)) + cprintf(YELLOW,"FifoTempfree[%d]: value:%d, push 0x%x\n",i,fifoTempFree[i]->getSemValue(),(void*)(wbuffer[i])); +#endif + + + + //cprintf(RED,"Current Packet frameBufferoffset[i]:%d\n",frameBufferoffset[i]); + frameBuffer[frameBufferoffset[i]] = (packetBuffer[i] + HEADER_SIZE_NUM_TOT_PACKETS); +#ifdef DEBUG4 eiger_packet_header_t* frameBuffer_header = (eiger_packet_header_t*) frameBuffer[frameBufferoffset[i]]; eiger_packet_footer_t* frameBuffer_footer = (eiger_packet_footer_t*) (frameBuffer[frameBufferoffset[i]] + footerOffset); cprintf(GREEN, "Fifo %d: Current Packet added success:" "pnum_offset %d, pnum %d, real pnum %d fnum_thread %d, missingpacket_buffer 0x%x\n", i,frameBufferoffset[i],currentPacketNumber[i],*( (uint16_t*) frameBuffer_footer->packetNumber),threadFrameNumber[i], *( (uint16_t*) frameBuffer_header->missingPacket)); -//#endif +#endif frameBufferoffset[i]=frameBufferoffset[i]+1; //update last packet lastPacketNumber[i] = currentPacketNumber[i]; popReady[i] = true; fullframe[i] = false; if(currentPacketNumber[i] == LAST_PACKET_VALUE){ -//#ifdef DEBUG4 +#ifdef DEBUG4 cprintf(GREEN, "Fifo %d: Got last packet\n",i); -//#endif +#endif popReady[i] = false; fullframe[i] = true; - } - } - } - } + } //end of last packet + }//end of add current packet + }//end of if(!fullframe) + }//end of for listening threads - /* for(int iloop=0;ilooppacketNumber), (uint32_t)(*( (uint64_t*) wbuf_footer)), *( (uint16_t*) wbuf_header->missingPacket)); @@ -2253,7 +2314,7 @@ void UDPStandardImplementation::processWritingBufferPacketByPacket(int ithread){ } for(int iloop=64;ilooppacketNumber), (uint32_t)(*( (uint64_t*) wbuf_footer)), *( (uint16_t*) wbuf_header->missingPacket)); @@ -2265,9 +2326,21 @@ void UDPStandardImplementation::processWritingBufferPacketByPacket(int ithread){ currentFrameNumber = presentFrameNumber; numTotMissingPacketsInFile += numMissingPackets; numTotMissingPackets += numMissingPackets; -//#ifdef FNUM_DEBUG + + + cprintf(GREEN,"**framenum:%lld\n ",(long long int)currentFrameNumber); + for(int i=0;ipacketNumber), (void*)(packetBuffer[i])); + } +#ifdef DEBUG4 + cprintf(BLUE," nummissingpackets:%d\n",numMissingPackets); +#endif +#ifdef FNUM_DEBUG cprintf(GREEN,"**fnum:%lld**\n",(long long int)currentFrameNumber); -//#endif +#endif #ifdef MISSINGP_DEBUG if(numMissingPackets){ cprintf(RED, "Total missing packets %d for fnum %d\n",numMissingPackets,currentFrameNumber); @@ -2280,7 +2353,7 @@ void UDPStandardImplementation::processWritingBufferPacketByPacket(int ithread){ #endif /* for(int iloop=0;ilooppacketNumber), (uint32_t)(*( (uint64_t*) wbuf_footer)), *( (uint16_t*) wbuf_header->missingPacket)); @@ -2288,19 +2361,20 @@ void UDPStandardImplementation::processWritingBufferPacketByPacket(int ithread){ } for(int iloop=64;ilooppacketNumber), (uint32_t)(*( (uint64_t*) wbuf_footer)), *( (uint16_t*) wbuf_header->missingPacket)); cout<packetNumber), (uint32_t)(*( (uint64_t*) wbuf_footer)), *( (uint16_t*) wbuf_header->missingPacket)); @@ -2308,7 +2382,7 @@ void UDPStandardImplementation::processWritingBufferPacketByPacket(int ithread){ } for(int iloop=64;ilooppacketNumber), (uint32_t)(*( (uint64_t*) wbuf_footer)), *( (uint16_t*) wbuf_header->missingPacket)); @@ -2320,7 +2394,15 @@ void UDPStandardImplementation::processWritingBufferPacketByPacket(int ithread){ for(int i=0; iisEmpty()){ fifoTempFree[i]->pop(temp); - fifoFree[i]->push(temp); +#ifdef EVERYFIFODEBUG + if(fifoTempFree[i]->getSemValue()>((packetsPerFrame/numberofListeningThreads)-3)) + cprintf(GRAY,"FifoTempFree[%d]: value:%d, pop 0x%x\n",i,fifoTempFree[i]->getSemValue(),(void*)(temp)); +#endif + while(!fifoFree[i]->push(temp)); +#ifdef EVERYFIFODEBUG + if(fifoFree[i]->getSemValue()<100) + cprintf(GREEN,"FifoFree[%d]: value:%d, push 0x%x\n",i,fifoFree[i]->getSemValue(),(void*)(temp)); +#endif #ifdef CFIFODEBUG if(i==0) cprintf(CYAN,"Fifo %d: Writing_Thread freed: pushed into fifofree %p\n",i, (void*)(temp)); @@ -2341,8 +2423,13 @@ void UDPStandardImplementation::processWritingBufferPacketByPacket(int ithread){ presentFrameNumber++; for(int i=0; ipacketNumber), (uint32_t)(*( (uint64_t*) wbuf_footer)), *( (uint16_t*) wbuf_header->missingPacket)); @@ -2365,7 +2452,7 @@ void UDPStandardImplementation::processWritingBufferPacketByPacket(int ithread){ } for(int iloop=64;ilooppacketNumber), (uint32_t)(*( (uint64_t*) wbuf_footer)), *( (uint16_t*) wbuf_header->missingPacket)); @@ -2382,18 +2469,20 @@ void UDPStandardImplementation::processWritingBufferPacketByPacket(int ithread){ #endif /*for(int iloop=0;ilooppacketNumber), (uint32_t)(*( (uint64_t*) wbuf_footer)), - *( (uint16_t*) wbuf_header->missingPacket)); + *( (uint16_t*) wbuf_header->missingPacket), + (void*)frameBuffer[iloop]); cout<packetNumber), (uint32_t)(*( (uint64_t*) wbuf_footer)), - *( (uint16_t*) wbuf_header->missingPacket)); + *( (uint16_t*) wbuf_header->missingPacket), + (void*)frameBuffer[iloop]); cout<isEmpty()){ - cout << ithread << ":emptied buffer in fifo" << endl; + cprintf(RED,"%d:emptied buffer in fifo\n", ithread); fifo[ithread]->pop(temp); +#ifdef EVERYFIFODEBUG + if(fifo[ithread]->getSemValue()>(fifoSize-100)) + cprintf(CYAN,"Fifo[%d]: value:%d, pop 0x%x\n",ithread,fifo[ithread]->getSemValue(),(void*)(temp)); +#endif } //create file @@ -2481,6 +2574,10 @@ bool UDPStandardImplementation::popAndCheckEndofAcquisition(int ithread, char* w //pop if ready if(ready[i]){ fifo[i]->pop(wbuffer[i]); +#ifdef EVERYFIFODEBUG + if(fifo[i]->getSemValue()>(fifoSize-100)) + cprintf(CYAN,"Fifo[%d]: value:%d, pop 0x%x\n",i,fifo[i]->getSemValue(),(void*)(wbuffer[i])); +#endif #ifdef CFIFODEBUG if(i == 0) cprintf(CYAN,"Writing_Thread %d: Popped %p from FIFO %d\n", ithread, (void*)(wbuffer[i]),i); @@ -2494,24 +2591,31 @@ bool UDPStandardImplementation::popAndCheckEndofAcquisition(int ithread, char* w //dummy-end buffer if(nP[i] == dummyPacketValue){ ready[i] = false; -#ifdef DEBUG3 +//#ifdef DEBUG3 cprintf(GREEN,"Writing_Thread %d: Dummy frame popped out of FIFO %d",ithread, i); -#endif +//#endif } //normal buffer popped out else{ endofAcquisition = false; -//#ifdef DEBUG4 +#ifdef DEBUG4 if(myDetectorType == EIGER){ eiger_packet_footer_t* wbuf_footer = (eiger_packet_footer_t*)(wbuffer[i] + footerOffset + HEADER_SIZE_NUM_TOT_PACKETS); //cprintf(BLUE,"footer value:0x%x\n",i,(uint64_t)(*( (uint64_t*) wbuf_footer))); + //if(*( (uint16_t*) wbuf_footer->packetNumber) == 1){ cprintf(BLUE,"Fnum[%d]:%d\n",i,(uint32_t)(*( (uint64_t*) wbuf_footer))); cprintf(BLUE,"Pnum[%d]:%d\n",i,*( (uint16_t*) wbuf_footer->packetNumber)); + //} } -//#endif - if(myDetectorType == EIGER){ +#endif + /*moved to current packet addition + * if(myDetectorType == EIGER){ while(!fifoTempFree[i]->push(wbuffer[i])); - } +#ifdef EVERYFIFODEBUG + if(fifoTempFree[i]->getSemValue()>((packetsPerFrame/numberofListeningThreads)-3)) + cprintf(YELLOW,"FifoTempfree[%d]: value:%d, push 0x%x\n",i,fifoTempFree[i]->getSemValue(),(void*)(wbuffer[i])); +#endif + }*/ } } //when both are not popped but curretn frame number is being processed @@ -2534,6 +2638,10 @@ void UDPStandardImplementation::stopWriting(int ithread, char* wbuffer[]){ //free fifo for(int i=0; ipush(wbuffer[i])); +#ifdef EVERYFIFODEBUG + if(fifoFree[i]->getSemValue()<100) + cprintf(GREEN,"FifoFree[%d]: value:%d, push 0x%x\n",i,fifoFree[i]->getSemValue(),(void*)(wbuffer[i])); +#endif #ifdef CFIFODEBUG if(i==0) cprintf(CYAN,"Writing_Thread %d: Freeing dummy-end buffer. Pushed into fifofree %p for listener %d\n", ithread,(void*)(wbuffer[i]),i); @@ -2633,16 +2741,20 @@ void UDPStandardImplementation::handleWithoutDataCompression(int ithread, char* //copy frame for gui - if(npackets >= packetsPerFrame) + /*if(npackets >= packetsPerFrame) copyFrameToGui(wbuffer); #ifdef DEBUG4 cprintf(GREEN,"Writing_Thread: Copied frame\n"); -#endif +#endif*/ //free fifo addresses (eiger frees for each packet later) if(myDetectorType != EIGER){ while(!fifoFree[0]->push(wbuffer[0])); +#ifdef EVERYFIFODEBUG + if(fifoFree[0]->getSemValue()<100) + cprintf(GREEN,"FifoFree[%d]: value:%d, push 0x%x\n",0,fifoFree[0]->getSemValue(),(void*)(wbuffer[0])); +#endif #ifdef DEBUG5 cprintf(GREEN,"Writing_Thread %d: Freed buffer, pushed into fifofree %p for listener 0\n",ithread, (void*)(wbuffer[0])); #endif @@ -2723,6 +2835,7 @@ void UDPStandardImplementation::writeFileWithoutCompression(char* wbuffer[],uint #ifdef DEBUG3 cprintf(GREEN,"Writing_Thread: Current Frame Number:%d\n",currentFrameNumber); #endif + cprintf(BG_RED,"CREATE NEW FILE %lld \n",(long long int)currentFrameNumber );exit(-1); createNewFile(); } @@ -2754,13 +2867,14 @@ void UDPStandardImplementation::createHeaders(char* wbuffer[]){ int port = 0, missingPacket; bool exitVal = 0; + eiger_packet_header_t* wbuf_header; + eiger_packet_footer_t* wbuf_footer; - cprintf(GREEN,"packetsperframe:%d\n",packetsPerFrame); for (uint32_t i = 0; i < packetsPerFrame; i++){ - eiger_packet_header_t* wbuf_header = (eiger_packet_header_t*) wbuffer[i]; - eiger_packet_footer_t* wbuf_footer = (eiger_packet_footer_t*)(wbuffer[i] + footerOffset); + wbuf_header = (eiger_packet_header_t*) wbuffer[i]; + wbuf_footer = (eiger_packet_footer_t*)(wbuffer[i] + footerOffset); #ifdef DEBUG4 cprintf(GREEN, "Loop index:%d Pnum:%d real fnum %d,missingPacket 0x%x\n", i, @@ -2778,8 +2892,20 @@ void UDPStandardImplementation::createHeaders(char* wbuffer[]){ cprintf(RED,"-Missing packet at Loop Index %d\n", i); #endif missingPacket = 1; + + //DEBUGGING + if(*( (uint16_t*) wbuf_footer->packetNumber) != (i+1)){ + cprintf(BG_RED, "Writing_Thread: Packet Number Mismatch (missing p)! " + "i %d, real pnum %d, real fnum %d, missingPacket 0x%x\n", + i, + *( (uint16_t*) wbuf_footer->packetNumber), + (uint32_t)(*( (uint64_t*) wbuf_footer)), + *( (uint16_t*) wbuf_header->missingPacket)); + exitVal =1; + } + //add frame number - *( (uint64_t*) wbuf_footer) = (currentFrameNumber+1) | (((uint64_t)(*( (uint16_t*) wbuf_footer->packetNumber)))<<0x30); + /**( (uint64_t*) wbuf_footer) = (currentFrameNumber+1) | (((uint64_t)(*( (uint16_t*) wbuf_footer->packetNumber)))<<0x30);*/ //*( (uint16_t*) wbuf_footer->packetNumber) = (i+1); #ifdef DEBUG4 cprintf(RED, "Missing Packet Loop index:%d fnum:%d Pnum:%d\n",i, @@ -2790,10 +2916,25 @@ void UDPStandardImplementation::createHeaders(char* wbuffer[]){ //normal packet else{ missingPacket = 0; + + //DEBUGGING + if(*( (uint16_t*) wbuf_footer->packetNumber) != ( (i>((packetsPerFrame/2)-1)?(i-(packetsPerFrame/2)+1):i+1) )){ + cprintf(BG_RED, "Writing_Thread: Packet Number Mismatch! " + "i %d, real pnum %d, real fnum %d, missingPacket 0x%x\n", + i, + *( (uint16_t*) wbuf_footer->packetNumber), + (uint32_t)(*( (uint64_t*) wbuf_footer)), + *( (uint16_t*) wbuf_header->missingPacket)); + exitVal =1; + } + + /*uint16_t p = *( (uint16_t*) wbuf_footer->packetNumber); //correct the packet numbers of port2 so that port1 and 2 are not the same - if(port) *( (uint16_t*) wbuf_footer->packetNumber) = (*( (uint16_t*) wbuf_footer->packetNumber))+(packetsPerFrame/2); + if(port) *( (uint16_t*) wbuf_footer->packetNumber) = (p +(packetsPerFrame/2));*/ + } - //DEBUGGING + + /*//DEBUGGING if(*( (uint16_t*) wbuf_footer->packetNumber) != (i+1)){ cprintf(BG_RED, "Writing_Thread: Packet Number Mismatch! " "i %d, real pnum %d, real fnum %d, missingPacket 0x%x\n", @@ -2802,10 +2943,10 @@ void UDPStandardImplementation::createHeaders(char* wbuffer[]){ (uint32_t)(*( (uint64_t*) wbuf_footer)), *( (uint16_t*) wbuf_header->missingPacket)); exitVal =1; - } + }*/ //overwriting port number and dynamic range - *( (uint8_t*) wbuf_header->portIndex) = port; - *( (uint8_t*) wbuf_header->dynamicRange) = dynamicRange; + /**( (uint8_t*) wbuf_header->portIndex) = (uint8_t)port; + *( (uint8_t*) wbuf_header->dynamicRange) = (uint8_t)dynamicRange;*/ } if(exitVal){exit(-1);} @@ -2997,6 +3138,10 @@ void UDPStandardImplementation::handleDataCompression(int ithread, char* wbuffer while(!fifoFree[0]->push(wbuffer[0])); +#ifdef EVERYFIFODEBUG + if(fifoFree[0]->getSemValue()<100) + cprintf(GREEN,"FifoFree[%d]: value:%d, push 0x%x\n",0,fifoFree[0]->getSemValue(),(void*)(wbuffer[0])); +#endif #ifdef DEBUG5 cprintf(GREEN,"Writing_Thread %d: Compression free pushed into fifofree %p for listerner 0\n", ithread, (void*)(wbuffer[0])); #endif From 3045876a86e4deb7551f3bade9f06a89f8d9efa8 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 2 Feb 2016 17:33:57 +0100 Subject: [PATCH 192/474] solved bug problem --- .../src/UDPStandardImplementation.cpp | 295 +++--------------- 1 file changed, 49 insertions(+), 246 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index b814d4c06..899e69e25 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -861,8 +861,8 @@ int UDPStandardImplementation::startReceiver(char *c){ for(int i=0;iShutDownSocket(); - FILE_LOG(logINFO) << "Info: Shut down UDP Socket " << i << endl; + FILE_LOG(logINFO) << "Shut down UDP Socket " << i; delete udpSocket[i]; udpSocket[i] = NULL; } @@ -929,7 +929,7 @@ int UDPStandardImplementation::shutDownUDPSockets(){ void UDPStandardImplementation::startReadout(){ FILE_LOG(logDEBUG) << __AT__ << " called"; - FILE_LOG(logDEBUG) << "Info: Transmitting last data"; + FILE_LOG(logDEBUG) << "Transmitting last data"; if(status == RUNNING){ @@ -944,9 +944,9 @@ void UDPStandardImplementation::startReadout(){ prev = -1; //wait as long as there is change from prev totalP while(prev != totalP){ -//#ifdef DEBUG5 +#ifdef DEBUG5 cprintf(MAGENTA,"waiting for all packets totalP:%d\n",totalP); -//#endif +#endif usleep(5000);/* Need to find optimal time (exposure time and acquisition period) **/ prev = totalP; @@ -963,7 +963,8 @@ void UDPStandardImplementation::startReadout(){ pthread_mutex_lock(&statusMutex); status = TRANSMITTING; pthread_mutex_unlock(&statusMutex); - cout << "Status: Transmitting" << endl; + + FILE_LOG(logINFO) << "Status: Transmitting"; } //shut down udp sockets and make listeners push dummy (end) packets for writers @@ -1658,9 +1659,9 @@ void UDPStandardImplementation::startFrameIndices(int ithread){ void UDPStandardImplementation::stopListening(int ithread, int numbytes){ FILE_LOG(logDEBUG) << __AT__ << " called"; -//#ifdef DEBUG4 - cprintf(BG_RED,"Listening_Thread %d: Stop Listening\nStatus: %s numbytes:%d\n", ithread, runStatusType(status).c_str(),numbytes); -//#endif +#ifdef DEBUG4 + cprintf(BLUE,"Listening_Thread %d: Stop Listening\nStatus: %s numbytes:%d\n", ithread, runStatusType(status).c_str(),numbytes); +#endif //less than 1 packet size (especially for eiger), ignore the buffer (so that 2 dummy buffers are not sent with pc=0) if(numbytes < onePacketSize) @@ -1669,7 +1670,7 @@ void UDPStandardImplementation::stopListening(int ithread, int numbytes){ //free empty buffer if(numbytes <= 0){ - cprintf(BLUE,"Listening_Thread %d :End of Acquisition\n", ithread); + FILE_LOG(logINFO) << "Listening "<< ithread << ": End of Acquisition"; while(!fifoFree[ithread]->push(buffer[ithread])); #ifdef EVERYFIFODEBUG if(fifoFree[ithread]->getSemValue()<100) @@ -1688,10 +1689,10 @@ void UDPStandardImplementation::stopListening(int ithread, int numbytes){ else{ (*((uint32_t*)(buffer[ithread]))) = numbytes/onePacketSize; totalListeningFrameCount[ithread] += (numbytes/onePacketSize); -//#ifdef DEBUG +#ifdef DEBUG cprintf(BLUE,"Listening_Thread %d: Last Buffer numBytes:%d\n",ithread, numbytes); cprintf(BLUE,"Listening_Thread %d: Last Buffer packet count:%d\n",ithread, numbytes/onePacketSize); -//#endif +#endif while(!fifo[ithread]->push(buffer[ithread])); #ifdef EVERYFIFODEBUG if(fifo[ithread]->getSemValue()>(fifoSize-100)) @@ -2035,27 +2036,6 @@ void UDPStandardImplementation::processWritingBufferPacketByPacket(int ithread){ //until mask unset (udp sockets shut down by client) while((1 << ithread) & writerThreadsMask){ - /* - for(int iloop=0;ilooppacketNumber), - (uint32_t)(*( (uint64_t*) wbuf_footer)), - *( (uint16_t*) wbuf_header->missingPacket), - (void*)frameBuffer[iloop]); - cout<packetNumber), - (uint32_t)(*( (uint64_t*) wbuf_footer)), - *( (uint16_t*) wbuf_header->missingPacket), - (void*)frameBuffer[iloop]); - cout<packetNumber), - (uint32_t)(*( (uint64_t*) wbuf_footer)), - *( (uint16_t*) wbuf_header->missingPacket)); - cout<packetNumber), - (uint32_t)(*( (uint64_t*) wbuf_footer)), - *( (uint16_t*) wbuf_header->missingPacket)); - cout<packetNumber), - (uint32_t)(*( (uint64_t*) wbuf_footer)), - *( (uint16_t*) wbuf_header->missingPacket)); - cout<packetNumber), - (uint32_t)(*( (uint64_t*) wbuf_footer)), - *( (uint16_t*) wbuf_header->missingPacket)); - cout<packetNumber), - (uint32_t)(*( (uint64_t*) wbuf_footer)), - *( (uint16_t*) wbuf_header->missingPacket)); - cout<packetNumber), - (uint32_t)(*( (uint64_t*) wbuf_footer)), - *( (uint16_t*) wbuf_header->missingPacket)); - cout<packetNumber), - (uint32_t)(*( (uint64_t*) wbuf_footer)), - *( (uint16_t*) wbuf_header->missingPacket)); - cout<packetNumber), - (uint32_t)(*( (uint64_t*) wbuf_footer)), - *( (uint16_t*) wbuf_header->missingPacket)); - cout<packetNumber), - (uint32_t)(*( (uint64_t*) wbuf_footer)), - *( (uint16_t*) wbuf_header->missingPacket)); - cout<packetNumber), - (uint32_t)(*( (uint64_t*) wbuf_footer)), - *( (uint16_t*) wbuf_header->missingPacket)); - cout<500){ + cprintf(BG_RED,"too high frame number %lld \n",(long long int)currentFrameNumber ); + exit(-1); + } for(int i=0;ipacketNumber), (void*)(packetBuffer[i])); - } + }*/ #ifdef DEBUG4 cprintf(BLUE," nummissingpackets:%d\n",numMissingPackets); #endif @@ -2351,43 +2245,31 @@ void UDPStandardImplementation::processWritingBufferPacketByPacket(int ithread){ } } #endif - /* for(int iloop=0;ilooppacketNumber), - (uint32_t)(*( (uint64_t*) wbuf_footer)), - *( (uint16_t*) wbuf_header->missingPacket)); - cout<packetNumber), - (uint32_t)(*( (uint64_t*) wbuf_footer)), - *( (uint16_t*) wbuf_header->missingPacket)); - cout<packetNumber), - (uint32_t)(*( (uint64_t*) wbuf_footer)), - *( (uint16_t*) wbuf_header->missingPacket)); - cout<packetNumber), - (uint32_t)(*( (uint64_t*) wbuf_footer)), - *( (uint16_t*) wbuf_header->missingPacket)); - cout<packetNumber), - (uint32_t)(*( (uint64_t*) wbuf_footer)), - *( (uint16_t*) wbuf_header->missingPacket)); - cout<packetNumber), - (uint32_t)(*( (uint64_t*) wbuf_footer)), - *( (uint16_t*) wbuf_header->missingPacket)); - cout<packetNumber), (void*)(packetBuffer[i])); - } -#endif - /*for(int iloop=0;ilooppacketNumber), - (uint32_t)(*( (uint64_t*) wbuf_footer)), - *( (uint16_t*) wbuf_header->missingPacket), - (void*)frameBuffer[iloop]); - cout<packetNumber), - (uint32_t)(*( (uint64_t*) wbuf_footer)), - *( (uint16_t*) wbuf_header->missingPacket), - (void*)frameBuffer[iloop]); - cout<push(wbuffer[i])); -#ifdef EVERYFIFODEBUG - if(fifoTempFree[i]->getSemValue()>((packetsPerFrame/numberofListeningThreads)-3)) - cprintf(YELLOW,"FifoTempfree[%d]: value:%d, push 0x%x\n",i,fifoTempFree[i]->getSemValue(),(void*)(wbuffer[i])); -#endif - }*/ } } //when both are not popped but curretn frame number is being processed @@ -2633,7 +2437,7 @@ bool UDPStandardImplementation::popAndCheckEndofAcquisition(int ithread, char* w void UDPStandardImplementation::stopWriting(int ithread, char* wbuffer[]){ FILE_LOG(logDEBUG) << __AT__ << " called"; - cprintf(GREEN,"Info: Writing_Thread %d: End of Acquisition\n",ithread); + FILE_LOG(logINFO) << "Writing "<< ithread << ": End of Acquisition"; //free fifo for(int i=0; i Date: Tue, 2 Feb 2016 18:52:24 +0100 Subject: [PATCH 193/474] all changes done --- .../src/UDPStandardImplementation.cpp | 54 ++++++------------- 1 file changed, 15 insertions(+), 39 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 899e69e25..3c0252008 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1568,7 +1568,6 @@ void UDPStandardImplementation::startListening(){ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int lSize, int cSize, char* temp){ FILE_LOG(logDEBUG) << __AT__ << " called"; - int testbit = 0; //listen to UDP packets if(cSize) @@ -1580,9 +1579,7 @@ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int lSize, in while(status != TRANSMITTING && myDetectorType == EIGER && receivedSize != onePacketSize) { if(receivedSize != EIGER_HEADER_LENGTH){ cprintf(RED,"Listening_Thread %d: Listened to a weird packet size %d\n",ithread, receivedSize); - }/*else{ - testbit = 1; - }*/ + } #ifdef DEBUG else cprintf(BLUE,"Listening_Thread %d: Listened to a header packet\n",ithread); @@ -1590,11 +1587,6 @@ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int lSize, in receivedSize = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS); } totalListeningFrameCount[ithread] += (receivedSize/onePacketSize); - /*if(testbit == 1){ - testbit = 0; - eiger_packet_footer_t* footer = (eiger_packet_footer_t*)(buffer[ithread] + footerOffset + HEADER_SIZE_NUM_TOT_PACKETS); - cprintf(CYAN,"Listening_Thread %d: fnum:%d\n",ithread,(uint32_t)(*( (uint64_t*) footer))); - }*/ #ifdef MANUALDEBUG eiger_packet_header_t* header = (eiger_packet_header_t*) (buffer[ithread]+HEADER_SIZE_NUM_TOT_PACKETS); @@ -2099,7 +2091,7 @@ void UDPStandardImplementation::processWritingBufferPacketByPacket(int ithread){ numberofMissingPackets[i] = (LAST_PACKET_VALUE - lastPacketNumber[i]); else numberofMissingPackets[i] = (currentPacketNumber[i] - lastPacketNumber[i] - 1); - + numMissingPackets += numberofMissingPackets[i]; #ifdef DEBUG4 if(numPackets[i] == dummyPacketValue) @@ -2118,7 +2110,6 @@ void UDPStandardImplementation::processWritingBufferPacketByPacket(int ithread){ for(int j=0;jmissingPacket)!= missingPacketValue){ @@ -2137,10 +2128,10 @@ void UDPStandardImplementation::processWritingBufferPacketByPacket(int ithread){ *( (uint16_t*) frameBuffer_header->missingPacket)); #endif frameBufferoffset[i]=frameBufferoffset[i]+1; - //blankoffset++; } } + //missed packets/future packet: do not pop over and determine fullframe-------------------- popReady[i] = false; if((numPackets[i] == dummyPacketValue) ||(threadFrameNumber[i] != presentFrameNumber)) fullframe[i] = true; @@ -2149,24 +2140,8 @@ void UDPStandardImplementation::processWritingBufferPacketByPacket(int ithread){ if(threadFrameNumber[i] != presentFrameNumber) threadFrameNumber[i] = presentFrameNumber; - //missed packets/future packet: do not pop over and determine fullframe-------------------- - if(numberofMissingPackets[i]){ - //popReady[i] = false; - //if((numPackets[i] == dummyPacketValue) ||(threadFrameNumber[i] != presentFrameNumber)) - // fullframe[i] = true; - //else{ - // fullframe[i] = false; - //update last packet - //lastPacketNumber[i] = currentPacketNumber[i] - 1; - //} - //if(threadFrameNumber[i] != presentFrameNumber) - // threadFrameNumber[i] = presentFrameNumber; - numMissingPackets += numberofMissingPackets[i]; - } - //add current packet-------------------------------------------------------------- - if(fullframe[i] == false){ if(currentPacketNumber[i] != (uint32_t)(frameBufferoffset[i]-(i*packetsPerFrame/numberofListeningThreads))+1){ cprintf(BG_RED, "Fifo %d: Correct Packet Offset Error: " @@ -2545,11 +2520,11 @@ void UDPStandardImplementation::handleWithoutDataCompression(int ithread, char* //copy frame for gui - /*if(npackets >= packetsPerFrame) + if(npackets >= packetsPerFrame) copyFrameToGui(wbuffer); #ifdef DEBUG4 cprintf(GREEN,"Writing_Thread: Copied frame\n"); -#endif*/ +#endif //free fifo addresses (eiger frees for each packet later) @@ -2708,8 +2683,8 @@ void UDPStandardImplementation::createHeaders(char* wbuffer[]){ } //add frame number - /**( (uint64_t*) wbuf_footer) = (currentFrameNumber+1) | (((uint64_t)(*( (uint16_t*) wbuf_footer->packetNumber)))<<0x30);*/ - //*( (uint16_t*) wbuf_footer->packetNumber) = (i+1); + ( (uint64_t*) wbuf_footer) = (currentFrameNumber+1) | (((uint64_t)(*( (uint16_t*) wbuf_footer->packetNumber)))<<0x30); + //*( (uint16_t*) wbuf_footer->packetNumber) = (i+1); // missing frames already have the right packet number #ifdef DEBUG4 cprintf(RED, "Missing Packet Loop index:%d fnum:%d Pnum:%d\n",i, (uint32_t)(*( (uint64_t*) wbuf_footer)), @@ -2731,13 +2706,17 @@ void UDPStandardImplementation::createHeaders(char* wbuffer[]){ exitVal =1; } - /*uint16_t p = *( (uint16_t*) wbuf_footer->packetNumber); + uint16_t p = *( (uint16_t*) wbuf_footer->packetNumber); //correct the packet numbers of port2 so that port1 and 2 are not the same - if(port) *( (uint16_t*) wbuf_footer->packetNumber) = (p +(packetsPerFrame/2));*/ + if(port) *( (uint16_t*) wbuf_footer->packetNumber) = (p +(packetsPerFrame/2)); } - /*//DEBUGGING + //overwriting port number and dynamic range + ( (uint8_t*) wbuf_header->portIndex) = (uint8_t)port; + *( (uint8_t*) wbuf_header->dynamicRange) = (uint8_t)dynamicRange; + + //DEBUGGING if(*( (uint16_t*) wbuf_footer->packetNumber) != (i+1)){ cprintf(BG_RED, "Writing_Thread: Packet Number Mismatch! " "i %d, real pnum %d, real fnum %d, missingPacket 0x%x\n", @@ -2746,10 +2725,7 @@ void UDPStandardImplementation::createHeaders(char* wbuffer[]){ (uint32_t)(*( (uint64_t*) wbuf_footer)), *( (uint16_t*) wbuf_header->missingPacket)); exitVal =1; - }*/ - //overwriting port number and dynamic range - /**( (uint8_t*) wbuf_header->portIndex) = (uint8_t)port; - *( (uint8_t*) wbuf_header->dynamicRange) = (uint8_t)dynamicRange;*/ + } } if(exitVal){exit(-1);} From 72cfd7a1d747b78805d29aacb51dbccd2c4a869b Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 2 Feb 2016 18:57:20 +0100 Subject: [PATCH 194/474] all changes done with bugs solved. need to test with image reconstruction --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 3c0252008..89bff743b 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -2683,7 +2683,7 @@ void UDPStandardImplementation::createHeaders(char* wbuffer[]){ } //add frame number - ( (uint64_t*) wbuf_footer) = (currentFrameNumber+1) | (((uint64_t)(*( (uint16_t*) wbuf_footer->packetNumber)))<<0x30); + *( (uint64_t*) wbuf_footer) = (currentFrameNumber+1) | (((uint64_t)(*( (uint16_t*) wbuf_footer->packetNumber)))<<0x30); //*( (uint16_t*) wbuf_footer->packetNumber) = (i+1); // missing frames already have the right packet number #ifdef DEBUG4 cprintf(RED, "Missing Packet Loop index:%d fnum:%d Pnum:%d\n",i, @@ -2713,7 +2713,7 @@ void UDPStandardImplementation::createHeaders(char* wbuffer[]){ } //overwriting port number and dynamic range - ( (uint8_t*) wbuf_header->portIndex) = (uint8_t)port; + *( (uint8_t*) wbuf_header->portIndex) = (uint8_t)port; *( (uint8_t*) wbuf_header->dynamicRange) = (uint8_t)dynamicRange; //DEBUGGING From fed17eb8ebc54d3fe521258d2b60d9cb24934889 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Wed, 3 Feb 2016 11:26:18 +0100 Subject: [PATCH 195/474] modified color of printout --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 89bff743b..60893deea 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1501,7 +1501,7 @@ void UDPStandardImplementation::startListening(){ //udpsocket doesnt exist if(udpSocket[ithread] == NULL){ - FILE_LOG(logERROR) << "Listening_Thread " << ithread << ": UDP Socket not created"; + FILE_LOG(logERROR) << "Listening_Thread " << ithread << ": UDP Socket not created or shut down earlier"; stopListening(ithread,0); continue; } @@ -2461,7 +2461,7 @@ void UDPStandardImplementation::stopWriting(int ithread, char* wbuffer[]){ //statistics FILE_LOG(logINFO) << "Status: Run Finished"; - if(numTotMissingPackets){ + if(totalPacketsCaught != (numberOfFrames*packetsPerFrame)){ cprintf(RED, "Total Missing Packets padded: %d\n",numTotMissingPackets); cprintf(RED, "Total Packets Caught: %lld\n",(long long int)totalPacketsCaught); cprintf(RED, "Total Frames Caught: %lld\n",(long long int)(totalPacketsCaught/packetsPerFrame)); From ef8fbab1f4aa08f0c069fd4390ad20ebc59f0f08 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Wed, 3 Feb 2016 11:34:47 +0100 Subject: [PATCH 196/474] 10g bug fixed in previous branch merge --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 60893deea..c5fee8065 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -955,7 +955,7 @@ void UDPStandardImplementation::startReadout(){ totalP += totalListeningFrameCount[i]; } } - }//else cprintf(MAGENTA,"***Got all packets without waiting****\n"); + } From 41f7743af932bb551950705be539bba4c8fca94b Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Wed, 3 Feb 2016 16:27:23 +0100 Subject: [PATCH 197/474] included fifodepth for jungfrau. Needed else its stuck --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 849a477bd..8368fceb2 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -741,6 +741,7 @@ int UDPStandardImplementation::setDetectorType(const detectorType d){ frameIndexOffset = JFRAU_FRAME_INDEX_OFFSET; packetIndexMask = JFRAU_PACKET_INDEX_MASK; maxPacketsPerFile = JFRAU_MAX_FRAMES_PER_FILE * JFRAU_PACKETS_PER_FRAME; + fifoDepth = JFRAU_FIFO_SIZE; fifoSize = JFRAU_FIFO_SIZE; //footerOffset = Not applicable; break; From 0c9806e17f1b89a02c5b952f86f43fe79ba7372f Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Thu, 4 Feb 2016 12:39:05 +0100 Subject: [PATCH 198/474] jungfrau header changed --- slsReceiverSoftware/include/receiver_defs.h | 6 +- .../src/UDPStandardImplementation.cpp | 65 ++++++++++--------- .../src/slsReceiverTCPIPInterface.cpp | 14 ++-- 3 files changed, 46 insertions(+), 39 deletions(-) diff --git a/slsReceiverSoftware/include/receiver_defs.h b/slsReceiverSoftware/include/receiver_defs.h index 3cc5e8091..49522334d 100755 --- a/slsReceiverSoftware/include/receiver_defs.h +++ b/slsReceiverSoftware/include/receiver_defs.h @@ -37,8 +37,10 @@ typedef struct { */ typedef struct { unsigned char emptyHeader[6]; - unsigned char frameNumber[8]; - unsigned char packetNumber[8]; + unsigned char reserved[4]; + unsigned char packetNumber[1]; + unsigned char frameNumber[3]; + unsigned char bunchid[8]; } jfrau_packet_header_t; diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 8368fceb2..8a6a57aab 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1591,7 +1591,6 @@ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int lSize, in int receivedSize = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS + cSize, lSize + cSize); - //throw away packets that is not one packet size, need to check status if socket is shut down while(status != TRANSMITTING && myDetectorType == EIGER && receivedSize != onePacketSize) { if(receivedSize != EIGER_HEADER_LENGTH){ @@ -1606,19 +1605,25 @@ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int lSize, in totalListeningFrameCount[ithread] += (receivedSize/onePacketSize); #ifdef MANUALDEBUG - if(myDetectorType == JUNGFRAU){ - jfrau_packet_header_t* header = (jfrau_packet_header_t*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS); - cprintf(RED,"framenumber:%llu\n",(long long unsigned int)(*( (uint64_t*) header->frameNumber))); - cprintf(RED,"packetnumber:%llu\n",(long long unsigned int)(*( (uint64_t*) header->packetNumber))); - }else if(myDetectorType == EIGER){ - eiger_packet_header_t* header = (eiger_packet_header_t*) (buffer[ithread]+HEADER_SIZE_NUM_TOT_PACKETS); - eiger_packet_footer_t* footer = (eiger_packet_footer_t*)(buffer[ithread] + footerOffset + HEADER_SIZE_NUM_TOT_PACKETS); - cprintf(GREEN,"thread:%d footeroffset:%dsubframenum:%d oldpacketnum:%d new pnum:%d new fnum:%d\n", - ithread,footerOffset, - (*( (unsigned int*) header->subFameNumber)), - (*( (uint8_t*) header->dynamicRange)), - (*( (uint16_t*) footer->packetNumber)), - (uint32_t)(*( (uint64_t*) footer))); + if(receivedSize>0){ + if(myDetectorType == JUNGFRAU){ + jfrau_packet_header_t* header; + + for(int iloop=0;iloop<2;iloop++){ + header = (jfrau_packet_header_t*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS + iloop * (JFRAU_HEADER_LENGTH+JFRAU_ONE_DATA_SIZE)); + cprintf(RED,"[%d]: packetnumber:%x\n",iloop, (*( (uint8_t*) header->packetNumber))); + cprintf(RED," : framenumber :%x\n", (*( (uint32_t*) header->frameNumber))&0xffffff); + } + }else if(myDetectorType == EIGER){ + eiger_packet_header_t* header = (eiger_packet_header_t*) (buffer[ithread]+HEADER_SIZE_NUM_TOT_PACKETS); + eiger_packet_footer_t* footer = (eiger_packet_footer_t*)(buffer[ithread] + footerOffset + HEADER_SIZE_NUM_TOT_PACKETS); + cprintf(GREEN,"thread:%d footeroffset:%dsubframenum:%d oldpacketnum:%d new pnum:%d new fnum:%d\n", + ithread,footerOffset, + (*( (unsigned int*) header->subFrameNumber)), + (*( (uint8_t*) header->dynamicRange)), + (*( (uint16_t*) footer->packetNumber)), + (uint32_t)(*( (uint64_t*) footer))); + } } #endif @@ -1645,7 +1650,7 @@ void UDPStandardImplementation::startFrameIndices(int ithread){ break; case JUNGFRAU: header = (jfrau_packet_header_t*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS); - startFrameIndex = (*( (uint64_t*) header->frameNumber)); + startFrameIndex = (*( (uint32_t*) header->frameNumber))&0xffffff; break; default: if(shortFrameEnable < 0){ @@ -1859,31 +1864,31 @@ uint32_t UDPStandardImplementation::processListeningBuffer(int ithread, int cSiz lastPacketOffset = (((numberofJobsPerBuffer * packetsPerFrame - 1) * onePacketSize) + HEADER_SIZE_NUM_TOT_PACKETS); #ifdef DEBUG4 header = (jfrau_packet_header_t*) (buffer[ithread]+HEADER_SIZE_NUM_TOT_PACKETS); - cprintf(BLUE, "Listening_Thread: First Header:%llu\t First Packet:%llu\n", - (long long unsigned int)(*( (uint64_t*) header->frameNumber)), - (long long unsigned int)(*( (uint64_t*) header->packetNumber))); + cprintf(BLUE, "Listening_Thread: First Header:%d\t First Packet:%d\n", + (*( (uint32_t*) header->frameNumber))&0xffffff, + (*( (uint8_t*) header->packetNumber))); #endif header = (jfrau_packet_header_t*) (buffer[ithread]+lastPacketOffset); #ifdef DEBUG4 - cprintf(BLUE, "Listening_Thread: Last Header:%llu\t Last Packet:%llu\n", - (long long unsigned int)(*( (uint64_t*) header->frameNumber)), - (long long unsigned int)(*( (uint64_t*) header->packetNumber))); + cprintf(BLUE, "Listening_Thread: Last Header:%du\t Last Packet:%d\n", + (*( (uint32_t*) header->frameNumber))&0xffffff, + (*( (uint8_t*) header->packetNumber))); #endif //jungfrau last packet value is 0, so find the last packet and store the others in a temp storage - if(*( (uint64_t*) header->packetNumber)){ + if((*( (uint8_t*) header->packetNumber))){ cprintf(RED,"entering missing packet zone\n"); - lastFrameHeader64 = (*( (uint64_t*) header->frameNumber)); + lastFrameHeader64 = (*( (uint32_t*) header->frameNumber))&0xffffff; cSize += onePacketSize; lastPacketOffset -= onePacketSize; --packetCount; - while (lastFrameHeader64 == (*( (uint64_t*) header->frameNumber))){ + while (lastFrameHeader64 == (*( (uint32_t*) header->frameNumber))&0xffffff){ cSize += onePacketSize; lastPacketOffset -= onePacketSize; header = (jfrau_packet_header_t*) (buffer[ithread]+lastPacketOffset); #ifdef DEBUG4 - cprintf(RED,"new header:%llu new packet:%llu\n", - (long long unsigned int)(*( (uint64_t*) header->frameNumber)), - (long long unsigned int)(*( (uint64_t*) header->packetNumber))); + cprintf(RED,"new header:%d new packet:%d\n", + (*( (uint32_t*) header->frameNumber))&0xffffff, + (*( (uint8_t*) header->packetNumber))); #endif --packetCount; } @@ -2529,7 +2534,7 @@ void UDPStandardImplementation::stopWriting(int ithread, char* wbuffer[]){ //statistics FILE_LOG(logINFO) << "Status: Run Finished"; - if(totalPacketsCaught != (numberOfFrames*packetsPerFrame)){ + if(totalPacketsCaught != ((uint64_t)numberOfFrames*packetsPerFrame)){ cprintf(RED, "Total Missing Packets padded: %d\n",numTotMissingPackets); cprintf(RED, "Total Packets Caught: %lld\n",(long long int)totalPacketsCaught); cprintf(RED, "Total Frames Caught: %lld\n",(long long int)(totalPacketsCaught/packetsPerFrame)); @@ -2555,7 +2560,7 @@ void UDPStandardImplementation::handleWithoutDataCompression(int ithread, char* if(myDetectorType != EIGER){ if(myDetectorType == JUNGFRAU){ jfrau_packet_header_t* header = (jfrau_packet_header_t*)(wbuffer[0] + HEADER_SIZE_NUM_TOT_PACKETS); - currentFrameNumber = (*( (uint64_t*) header->frameNumber)); + currentFrameNumber = (*( (uint32_t*) header->frameNumber))&0xffffff; }else{ uint64_t tempframenumber = ((uint32_t)(*((uint32_t*)(wbuffer[0] + HEADER_SIZE_NUM_TOT_PACKETS)))); //for gotthard and normal frame, increment frame number to separate fnum and pnum @@ -2677,7 +2682,7 @@ void UDPStandardImplementation::writeFileWithoutCompression(char* wbuffer[],uint lastpacket = (((packetsToSave - 1) * onePacketSize) + offset); if(myDetectorType == JUNGFRAU){ jfrau_packet_header_t* header = (jfrau_packet_header_t*) (wbuffer[0] + lastpacket); - currentFrameNumber = (*( (uint64_t*) header->frameNumber)); + currentFrameNumber = (*( (uint32_t*) header->frameNumber))&0xffffff; }else{ tempframenumber = ((uint32_t)(*((uint32_t*)(wbuffer[0] + lastpacket)))); //for gotthard and normal frame, increment frame number to separate fnum and pnum diff --git a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp index 87d920440..a79fb6ebd 100644 --- a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp +++ b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp @@ -1858,7 +1858,7 @@ int slsReceiverTCPIPInterface::jungfrau_read_frame(){ char fName[MAX_STR_LENGTH]=""; int acquisitionIndex = -1; int frameIndex= -1; - uint64_t currentIndex=0; + int64_t currentIndex=0; uint64_t startAcquisitionIndex=0; uint64_t startFrameIndex=0; strcpy(mess,"Could not read frame\n"); @@ -1915,7 +1915,7 @@ int slsReceiverTCPIPInterface::jungfrau_read_frame(){ //fixed frame number jfrau_packet_header_t* header = (jfrau_packet_header_t*) origVal; - currentIndex = (*( (uint64_t*) header->frameNumber)); + currentIndex = (*( (uint32_t*) header->frameNumber))&0xffffff; #ifdef VERYVERBOSE cout << "currentIndex:" << dec << currentIndex << endl; #endif @@ -1923,13 +1923,13 @@ int slsReceiverTCPIPInterface::jungfrau_read_frame(){ int64_t currentPacket = packetsPerFrame-1; int offsetsrc = 0; int offsetdest = 0; - uint64_t ifnum=-1; - uint64_t ipnum=-1; + int64_t ifnum=-1; + int64_t ipnum=-1; while(currentPacket >= 0){ header = (jfrau_packet_header_t*) (origVal + offsetsrc); - ifnum = (*( (uint64_t*) header->frameNumber)); - ipnum = (*( (uint64_t*) header->packetNumber)); + ifnum = (*( (uint32_t*) header->frameNumber))&0xffffff; + ipnum = (*( (uint8_t*) header->packetNumber)); if(ifnum != currentIndex) { cout << "current packet " << currentPacket << " Wrong Frame number " << ifnum << ", copying blank packet" << endl; memcpy(retval+offsetdest,blackpacket,oneDataSize); @@ -1938,7 +1938,7 @@ int slsReceiverTCPIPInterface::jungfrau_read_frame(){ currentPacket--; continue; } - if((int64_t)ipnum!= currentPacket){ + if(ipnum!= currentPacket){ cout << "current packet " << currentPacket << " Wrong packet number " << ipnum << ", copying blank packet" << endl; memcpy(retval+offsetdest,blackpacket,oneDataSize); offsetdest += oneDataSize; From 5afb38c1ecd0f6564a38e54a732126e9c9727b7c Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Mon, 8 Feb 2016 10:40:33 +0100 Subject: [PATCH 199/474] changing the print outs --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 8a6a57aab..2dc67234a 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -2534,7 +2534,7 @@ void UDPStandardImplementation::stopWriting(int ithread, char* wbuffer[]){ //statistics FILE_LOG(logINFO) << "Status: Run Finished"; - if(totalPacketsCaught != ((uint64_t)numberOfFrames*packetsPerFrame)){ + if(totalPacketsCaught < ((uint64_t)numberOfFrames*packetsPerFrame)){ cprintf(RED, "Total Missing Packets padded: %d\n",numTotMissingPackets); cprintf(RED, "Total Packets Caught: %lld\n",(long long int)totalPacketsCaught); cprintf(RED, "Total Frames Caught: %lld\n",(long long int)(totalPacketsCaught/packetsPerFrame)); From bd91aea7136fbed1835bb51fe7c4eb2aa447061f Mon Sep 17 00:00:00 2001 From: Anna Bergamaschi Date: Thu, 11 Feb 2016 17:09:54 +0100 Subject: [PATCH 200/474] Some defs for JCTB receiver --- slsReceiverSoftware/include/circularFifo.h | 2 -- slsReceiverSoftware/include/receiver_defs.h | 6 +++--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/slsReceiverSoftware/include/circularFifo.h b/slsReceiverSoftware/include/circularFifo.h index 6f779aafc..733b0800d 100644 --- a/slsReceiverSoftware/include/circularFifo.h +++ b/slsReceiverSoftware/include/circularFifo.h @@ -78,7 +78,6 @@ int CircularFifo::getSemValue() template bool CircularFifo::push(Element*& item_) { - int nextTail = increment(tail); if(nextTail != head) { @@ -87,7 +86,6 @@ bool CircularFifo::push(Element*& item_) sem_post(&free_mutex); return true; } - // queue was full return false; } diff --git a/slsReceiverSoftware/include/receiver_defs.h b/slsReceiverSoftware/include/receiver_defs.h index 0a4bda66b..32aa52712 100755 --- a/slsReceiverSoftware/include/receiver_defs.h +++ b/slsReceiverSoftware/include/receiver_defs.h @@ -90,7 +90,7 @@ #define JCTB_FIFO_SIZE 2500 //cannot be less than max jobs per thread = 1000 /*#define MOENCH_ALIGNED_FRAME_SIZE 65536*/ -<<<<<<< HEAD +//<<<<<<< HEAD #define JCTB_PACKETS_PER_FRAME 1 #define JCTB_ONE_PACKET_SIZE 8224 #define JCTB_BUFFER_SIZE (JCTB_ONE_PACKET_SIZE*40) @@ -99,7 +99,7 @@ #define JCTB_FRAME_INDEX_MASK 0xFFFFFFFF #define JCTB_FRAME_INDEX_OFFSET 6+8 #define JCTB_PACKET_INDEX_MASK 0xFFFFFFFF -======= +//======= #define JCTB_PACKETS_PER_FRAME 50 #define JCTB_ONE_PACKET_SIZE 8214 #define JCTB_BUFFER_SIZE (MOENCH_ONE_PACKET_SIZE*MOENCH_PACKETS_PER_FRAME) @@ -108,7 +108,7 @@ #define JCTB_FRAME_INDEX_MASK 0xFFFFFF00 #define JCTB_FRAME_INDEX_OFFSET 8 #define JCTB_PACKET_INDEX_MASK 0xFF ->>>>>>> 8bad1d33fcf4601752bb6722a9eca00aa2cd4ed2 +//>>>>>>> 8bad1d33fcf4601752bb6722a9eca00aa2cd4ed2 #define JCTB_BYTES_PER_ADC (2) #define JCTB_PIXELS_IN_ONE_ROW 32 From 66eddb1afed3ddc7c88bcebcaa997fb88b0e4e11 Mon Sep 17 00:00:00 2001 From: Anna Bergamaschi Date: Mon, 22 Feb 2016 14:00:22 +0100 Subject: [PATCH 201/474] Added stopped status --- slsReceiverSoftware/include/sls_receiver_defs.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/slsReceiverSoftware/include/sls_receiver_defs.h b/slsReceiverSoftware/include/sls_receiver_defs.h index 07566ab84..a2dfe6ab4 100755 --- a/slsReceiverSoftware/include/sls_receiver_defs.h +++ b/slsReceiverSoftware/include/sls_receiver_defs.h @@ -111,7 +111,8 @@ public: WAITING, /**< waiting for trigger or gate signal */ RUN_FINISHED, /**< acquisition not running but data in memory */ TRANSMITTING, /**< acquisition running and data in memory */ - RUNNING /**< acquisition running, no data in memory */ + RUNNING, /**< acquisition running, no data in memory */ + STOPPED /**< received external stop */ }; #ifdef __cplusplus From f113b1afbbb6ee257e0d7f25c31ec7ad70f3fb90 Mon Sep 17 00:00:00 2001 From: Anna Bergamaschi Date: Mon, 22 Feb 2016 15:07:05 +0100 Subject: [PATCH 202/474] Added status stopped --- slsReceiverSoftware/include/sls_receiver_defs.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/slsReceiverSoftware/include/sls_receiver_defs.h b/slsReceiverSoftware/include/sls_receiver_defs.h index c11f6f8c0..e37639b07 100755 --- a/slsReceiverSoftware/include/sls_receiver_defs.h +++ b/slsReceiverSoftware/include/sls_receiver_defs.h @@ -112,7 +112,8 @@ public: WAITING, /**< waiting for trigger or gate signal */ RUN_FINISHED, /**< acquisition not running but data in memory */ TRANSMITTING, /**< acquisition running and data in memory */ - RUNNING /**< acquisition running, no data in memory */ + RUNNING, /**< acquisition running, no data in memory */ + STOPPED /**< acquisition stopped externally */ }; #ifdef __cplusplus @@ -172,6 +173,7 @@ public: case RUNNING: return std::string("running"); \ case TRANSMITTING: return std::string("data"); \ case RUN_FINISHED: return std::string("finished"); \ + case STOPPED: return std::string("stopped"); \ default: return std::string("idle"); \ }}; From e508050be85b5b0384e890e14b6f9aea872e7ac1 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Thu, 25 Feb 2016 12:11:05 +0100 Subject: [PATCH 203/474] bug fix: converts any receiver other than eiger into a jungfrau receiver --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 2dc67234a..ccbdaf148 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -251,7 +251,7 @@ int UDPStandardImplementation::setupFifoStructure(){ int64_t i; int oldNumberofJobsPerBuffer = numberofJobsPerBuffer; //eiger always listens to 1 packet at a time - if((myDetectorType == EIGER) || (myDetectorType = JUNGFRAU)){ + if((myDetectorType == EIGER) || (myDetectorType == JUNGFRAU)){ numberofJobsPerBuffer = 1; FILE_LOG(logDEBUG) << "Info: 1 packet per buffer"; } From 683ea31963d7ff6064ff5591255deb55af586b0a Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Thu, 25 Feb 2016 13:56:23 +0100 Subject: [PATCH 204/474] removed comment entering missing zone --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index ccbdaf148..9c18ad243 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1876,7 +1876,7 @@ uint32_t UDPStandardImplementation::processListeningBuffer(int ithread, int cSiz #endif //jungfrau last packet value is 0, so find the last packet and store the others in a temp storage if((*( (uint8_t*) header->packetNumber))){ - cprintf(RED,"entering missing packet zone\n"); + //cprintf(RED,"entering missing packet zone\n"); lastFrameHeader64 = (*( (uint32_t*) header->frameNumber))&0xffffff; cSize += onePacketSize; lastPacketOffset -= onePacketSize; From d4b388f434c5fc54091dd434cb86dc6472e836fc Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Thu, 25 Feb 2016 14:13:42 +0100 Subject: [PATCH 205/474] unresolved conflict --- slsReceiverSoftware/include/receiver_defs.h | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/slsReceiverSoftware/include/receiver_defs.h b/slsReceiverSoftware/include/receiver_defs.h index d9e6a7009..4c621a67f 100755 --- a/slsReceiverSoftware/include/receiver_defs.h +++ b/slsReceiverSoftware/include/receiver_defs.h @@ -151,7 +151,6 @@ typedef struct { #define JCTB_FIFO_SIZE 2500 //cannot be less than max jobs per thread = 1000 /*#define MOENCH_ALIGNED_FRAME_SIZE 65536*/ -//<<<<<<< HEAD #define JCTB_PACKETS_PER_FRAME 1 #define JCTB_ONE_PACKET_SIZE 8224 #define JCTB_BUFFER_SIZE (JCTB_ONE_PACKET_SIZE*40) @@ -160,16 +159,7 @@ typedef struct { #define JCTB_FRAME_INDEX_MASK 0xFFFFFFFF #define JCTB_FRAME_INDEX_OFFSET 6+8 #define JCTB_PACKET_INDEX_MASK 0xFFFFFFFF -//======= -#define JCTB_PACKETS_PER_FRAME 50 -#define JCTB_ONE_PACKET_SIZE 8214 -#define JCTB_BUFFER_SIZE (MOENCH_ONE_PACKET_SIZE*MOENCH_PACKETS_PER_FRAME) -#define JCTB_DATA_BYTES (JCTB_BUFFER_PER_FRAME) -#define JCTB_FRAME_INDEX_MASK 0xFFFFFF00 -#define JCTB_FRAME_INDEX_OFFSET 8 -#define JCTB_PACKET_INDEX_MASK 0xFF -//>>>>>>> 8bad1d33fcf4601752bb6722a9eca00aa2cd4ed2 #define JCTB_BYTES_PER_ADC (2) #define JCTB_PIXELS_IN_ONE_ROW 32 From d88b104aa872dfd91d43b7cf9580be04a22278d8 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 15 Mar 2016 15:28:50 +0100 Subject: [PATCH 206/474] bug fix for receiver call back --- .../include/slsReceiverTCPIPInterface.h | 107 ++++++++++++------ slsReceiverSoftware/src/main.cpp | 28 ++++- slsReceiverSoftware/src/slsReceiver.cpp | 15 ++- .../src/slsReceiverTCPIPInterface.cpp | 32 ++++++ 4 files changed, 139 insertions(+), 43 deletions(-) diff --git a/slsReceiverSoftware/include/slsReceiverTCPIPInterface.h b/slsReceiverSoftware/include/slsReceiverTCPIPInterface.h index 237f240e6..a2f358aca 100644 --- a/slsReceiverSoftware/include/slsReceiverTCPIPInterface.h +++ b/slsReceiverSoftware/include/slsReceiverTCPIPInterface.h @@ -57,45 +57,39 @@ class slsReceiverTCPIPInterface : private virtual slsReceiverDefs { /** gets version */ int64_t getReceiverVersion(); -/* /\** */ -/* callback arguments are */ -/* filepath */ -/* filename */ -/* fileindex */ -/* data size */ + //***callback functions*** + /** + * Call back for start acquisition + * callback arguments are + * filepath + * filename + * fileindex + * datasize + * + * return value is the action which decides what the user and default responsibilities to save data are + * 0 callback takes care of open,close,wrie file + * 1 callback writes file, we have to open, close it + * 2 we open, close, write file, callback does not do anything + */ + void registerCallBackStartAcquisition(int (*func)(char*, char*,int, int, void*),void *arg); -/* return value is */ -/* 0 callback takes care of open,close,wrie file */ -/* 1 callback writes file, we have to open, close it */ -/* 2 we open, close, write file, callback does not do anything */ - -/* *\/ */ - -/* void registerCallBackStartAcquisition(int (*func)(char*, char*,int, int, void*),void *arg){receiverBase->registerCallBackStartAcquisition(func,arg);};; */ - - -/* /\** */ -/* callback argument is */ -/* toatal farmes caught */ - -/* *\/ */ - - -/* void registerCallBackAcquisitionFinished(void (*func)(int, void*),void *arg){receiverBase->registerCallBackAcquisitionFinished(func,arg);}; */ - - - -/* /\** */ -/* args to raw data ready callback are */ -/* framenum */ -/* datapointer */ -/* datasize in bytes */ -/* file descriptor */ -/* guidatapointer (NULL, no data required) */ -/* *\/ */ - -/* void registerCallBackRawDataReady(void (*func)(int, char*, int, FILE*, char*, void*),void *arg){receiverBase->registerCallBackRawDataReady(func,arg);}; */ + /** + * Call back for acquisition finished + * callback argument is + * total frames caught + */ + void registerCallBackAcquisitionFinished(void (*func)(int, void*),void *arg); + /** + * Call back for raw data + * args to raw data ready callback are + * framenum + * datapointer + * datasize in bytes + * file descriptor + * guidatapointer (NULL, no data required) + */ + void registerCallBackRawDataReady(void (*func)(int, char*, int, FILE*, char*, void*),void *arg); private: @@ -284,6 +278,45 @@ private: bool bottom; + //***callback parameters*** + /** + * function being called back for start acquisition + * callback arguments are + * filepath + * filename + * fileindex + * datasize + * + * return value is + * 0 callback takes care of open,close,wrie file + * 1 callback writes file, we have to open, close it + * 2 we open, close, write file, callback does not do anything + */ + int (*startAcquisitionCallBack)(char*, char*,int, int, void*); + void *pStartAcquisition; + + /** + * function being called back for acquisition finished + * callback argument is + * total frames caught + */ + void (*acquisitionFinishedCallBack)(int, void*); + void *pAcquisitionFinished; + + + /** + * function being called back for raw data + * args to raw data ready callback are + * framenum + * datapointer + * datasize in bytes + * file descriptor + * guidatapointer (NULL, no data required) + */ + void (*rawDataReadyCallBack)(int, char*, int, FILE*, char*, void*); + void *pRawDataReady; + + protected: /** Socket */ MySocketTCP* socket; diff --git a/slsReceiverSoftware/src/main.cpp b/slsReceiverSoftware/src/main.cpp index 1dc9a65c6..a005f569d 100644 --- a/slsReceiverSoftware/src/main.cpp +++ b/slsReceiverSoftware/src/main.cpp @@ -22,6 +22,28 @@ void closeFile(int p){ deleteReceiver(receiver); } +/* +int startAcquisitionCallBack(char* filePath, char* fileName, int fileIndex, int bufferSize, void* context) { + cout << "#### startAcquisitionCallBack ####" << endl; + cout << "* filePath: " << filePath << endl; + cout << "* fileName: " << fileName << endl; + cout << "* fileIndex: " << fileIndex << endl; + cout << "* bufferSize: " << bufferSize << endl; + return 1; +} + +void acquisitionFinishedCallBack(int totalFramesCaught, void* context) { + cout << "#### acquisitionFinishedCallBack ####" << endl; + cout << "* totalFramesCaught: " << totalFramesCaught << endl; +} + +void rawDataReadyCallBack(int currFrameNum, char* dataPointer, int dataSize, FILE* file, char* guiDataPointer, void* context) { + cout << "#### rawDataReadyCallBack ####" << endl; + cout << "* currFrameNum: " << currFrameNum << endl; + cout << "* dataSize: " << dataSize << endl; +} +*/ + int main(int argc, char *argv[]) { //Catch signal SIGINT to close files properly @@ -52,7 +74,7 @@ int main(int argc, char *argv[]) { registerCallBackStartAcquisition(int (*func)(char*, char*,int, int, void*),void *arg); */ - //receiver->registerCallBackStartAcquisition(func,arg); + //receiver->registerCallBackStartAcquisition(startAcquisitionCallBack,NULL); /** @@ -60,7 +82,7 @@ int main(int argc, char *argv[]) { total farmes caught registerCallBackAcquisitionFinished(void (*func)(int, void*),void *arg); */ - //receiver->registerCallBackAcquisitionFinished(func,arg); + //receiver->registerCallBackAcquisitionFinished(acquisitionFinishedCallBack,NULL); /** @@ -73,7 +95,7 @@ int main(int argc, char *argv[]) { REMEMBER THAT THE CALLBACK IS BLOCKING registerCallBackRawDataReady(void (*func)(int, char*, FILE*, char*, void*),void *arg); */ - //receiver->registerCallBackRawDataReady(func,arg); + //receiver->registerCallBackRawDataReady(rawDataReadyCallBack,NULL); diff --git a/slsReceiverSoftware/src/slsReceiver.cpp b/slsReceiverSoftware/src/slsReceiver.cpp index f23da65c5..a6c231a3e 100644 --- a/slsReceiverSoftware/src/slsReceiver.cpp +++ b/slsReceiverSoftware/src/slsReceiver.cpp @@ -172,20 +172,29 @@ int64_t slsReceiver::getReceiverVersion(){ void slsReceiver::registerCallBackStartAcquisition(int (*func)(char*, char*,int, int, void*),void *arg){ //tcpipInterface - udp_interface->registerCallBackStartAcquisition(func,arg); + if(udp_interface) + udp_interface->registerCallBackStartAcquisition(func,arg); + else + tcpipInterface->registerCallBackStartAcquisition(func,arg); } void slsReceiver::registerCallBackAcquisitionFinished(void (*func)(int, void*),void *arg){ //tcpipInterface - udp_interface->registerCallBackAcquisitionFinished(func,arg); + if(udp_interface) + udp_interface->registerCallBackAcquisitionFinished(func,arg); + else + tcpipInterface->registerCallBackAcquisitionFinished(func,arg); } void slsReceiver::registerCallBackRawDataReady(void (*func)(int, char*, int, FILE*, char*, void*),void *arg){ //tcpipInterface - udp_interface->registerCallBackRawDataReady(func,arg); + if(udp_interface) + udp_interface->registerCallBackRawDataReady(func,arg); + else + tcpipInterface->registerCallBackRawDataReady(func,arg); } diff --git a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp index a79fb6ebd..9b7a91a8e 100644 --- a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp +++ b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp @@ -42,6 +42,14 @@ slsReceiverTCPIPInterface::slsReceiverTCPIPInterface(int &success, UDPInterface* bottom(bot), socket(NULL){ + //***callback parameters*** + startAcquisitionCallBack = NULL; + pStartAcquisition = NULL; + acquisitionFinishedCallBack = NULL; + pAcquisitionFinished = NULL; + rawDataReadyCallBack = NULL; + pRawDataReady = NULL; + int port_no=portNumber; if(receiverBase == NULL) receiverBase = 0; @@ -362,6 +370,12 @@ int slsReceiverTCPIPInterface::set_detector_type(){ if(ret != FAIL){ #ifndef REST receiverBase = UDPInterface::create("standard"); + if(startAcquisitionCallBack) + receiverBase->registerCallBackStartAcquisition(startAcquisitionCallBack,pStartAcquisition); + if(acquisitionFinishedCallBack) + receiverBase->registerCallBackAcquisitionFinished(acquisitionFinishedCallBack,pAcquisitionFinished); + if(rawDataReadyCallBack) + receiverBase->registerCallBackRawDataReady(rawDataReadyCallBack,pRawDataReady); #endif myDetectorType = dr; ret=receiverBase->setDetectorType(myDetectorType); @@ -3012,5 +3026,23 @@ int slsReceiverTCPIPInterface::exec_command() { +/***callback functions***/ +void slsReceiverTCPIPInterface::registerCallBackStartAcquisition(int (*func)(char*, char*,int, int, void*),void *arg){ + startAcquisitionCallBack=func; + pStartAcquisition=arg; +} + +void slsReceiverTCPIPInterface::registerCallBackAcquisitionFinished(void (*func)(int, void*),void *arg){ + acquisitionFinishedCallBack=func; + pAcquisitionFinished=arg; +} + +void slsReceiverTCPIPInterface::registerCallBackRawDataReady(void (*func)(int, char*, int, FILE*, char*, void*),void *arg){ + rawDataReadyCallBack=func; + pRawDataReady=arg; +} + + + From 75a50a7ae0bb6b797a12e9d18bc460e7cf7a5e22 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 10 May 2016 17:13:27 +0200 Subject: [PATCH 207/474] receiver udp parameters should be sent to receiver everytime if rx_hostname is set --- .../include/slsReceiverTCPIPInterface.h | 3 + .../src/slsReceiverTCPIPInterface.cpp | 65 ++++++++++--------- 2 files changed, 36 insertions(+), 32 deletions(-) diff --git a/slsReceiverSoftware/include/slsReceiverTCPIPInterface.h b/slsReceiverSoftware/include/slsReceiverTCPIPInterface.h index a2f358aca..8b5c4527f 100644 --- a/slsReceiverSoftware/include/slsReceiverTCPIPInterface.h +++ b/slsReceiverSoftware/include/slsReceiverTCPIPInterface.h @@ -277,6 +277,9 @@ private: /** true if bottom half module for eiger */ bool bottom; + /** Receiver not setup error message */ + char SET_RECEIVER_ERR_MESSAGE[MAX_STR_LENGTH]; + //***callback parameters*** /** diff --git a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp index 9b7a91a8e..1e2b5c49e 100644 --- a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp +++ b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp @@ -22,7 +22,6 @@ using namespace std; - slsReceiverTCPIPInterface::~slsReceiverTCPIPInterface() { stop(); if(socket) {delete socket; socket=NULL;} @@ -42,6 +41,8 @@ slsReceiverTCPIPInterface::slsReceiverTCPIPInterface(int &success, UDPInterface* bottom(bot), socket(NULL){ + strcpy(SET_RECEIVER_ERR_MESSAGE,"Receiver not set up. Please use rx_hostname first.\n"); + //***callback parameters*** startAcquisitionCallBack = NULL; pStartAcquisition = NULL; @@ -438,7 +439,7 @@ int slsReceiverTCPIPInterface::set_file_name() { ret=FAIL; } else if (receiverBase == NULL){ - strcpy(mess,"Receiver not set up\n"); + strcpy(mess,SET_RECEIVER_ERR_MESSAGE); ret=FAIL; } else{ @@ -510,7 +511,7 @@ int slsReceiverTCPIPInterface::set_file_dir() { ret = FAIL; }*/ else if (receiverBase == NULL){ - strcpy(mess,"Receiver not set up\n"); + strcpy(mess,SET_RECEIVER_ERR_MESSAGE); ret=FAIL; } else{ @@ -579,7 +580,7 @@ int slsReceiverTCPIPInterface::set_file_index() { ret=FAIL; } else if (receiverBase == NULL){ - strcpy(mess,"Receiver not set up\n"); + strcpy(mess,SET_RECEIVER_ERR_MESSAGE); ret=FAIL; } else{ @@ -643,7 +644,7 @@ int slsReceiverTCPIPInterface::set_frame_index() { ret=FAIL; } else if (receiverBase == NULL){ - strcpy(mess,"Receiver not set up\n"); + strcpy(mess,SET_RECEIVER_ERR_MESSAGE); ret=FAIL; } else{ @@ -720,7 +721,7 @@ int slsReceiverTCPIPInterface::setup_udp(){ ret=FAIL; } else if (receiverBase == NULL){ - strcpy(mess,"Receiver not set up\n"); + strcpy(mess,SET_RECEIVER_ERR_MESSAGE); ret=FAIL; } else if(receiverBase->getStatus()==RUNNING){ @@ -804,12 +805,12 @@ int slsReceiverTCPIPInterface::start_receiver(){ } /* else if(!strlen(receiverBase->getFilePath())){ - strcpy(mess,"receiver not set up. set receiver ip again.\n"); + strcpy(mess,SET_RECEIVER_ERR_MESSAGE"); ret = FAIL; } */ else if (receiverBase == NULL){ - strcpy(mess,"Receiver not set up\n"); + strcpy(mess,SET_RECEIVER_ERR_MESSAGE); ret=FAIL; } else { @@ -853,7 +854,7 @@ int slsReceiverTCPIPInterface::stop_receiver(){ ret=FAIL; } else if (receiverBase == NULL){ - strcpy(mess,"Receiver not set up\n"); + strcpy(mess,SET_RECEIVER_ERR_MESSAGE); ret=FAIL; } else{ @@ -894,7 +895,7 @@ int slsReceiverTCPIPInterface::get_status(){ // execute action if the arguments correctly arrived #ifdef SLS_RECEIVER_UDP_FUNCTIONS if (receiverBase == NULL){ - strcpy(mess,"Receiver not set up\n"); + strcpy(mess,SET_RECEIVER_ERR_MESSAGE); ret=FAIL; }else retval=receiverBase->getStatus(); #endif @@ -925,7 +926,7 @@ int slsReceiverTCPIPInterface::get_frames_caught(){ // execute action if the arguments correctly arrived #ifdef SLS_RECEIVER_UDP_FUNCTIONS if (receiverBase == NULL){ - strcpy(mess,"Receiver not set up\n"); + strcpy(mess,SET_RECEIVER_ERR_MESSAGE); ret=FAIL; }else retval=receiverBase->getTotalFramesCaught(); #endif @@ -955,7 +956,7 @@ int slsReceiverTCPIPInterface::get_frame_index(){ // execute action if the arguments correctly arrived #ifdef SLS_RECEIVER_UDP_FUNCTIONS if (receiverBase == NULL){ - strcpy(mess,"Receiver not set up\n"); + strcpy(mess,SET_RECEIVER_ERR_MESSAGE); ret=FAIL; }else retval=receiverBase->getAcquisitionIndex(); @@ -994,7 +995,7 @@ int slsReceiverTCPIPInterface::reset_frames_caught(){ ret=FAIL; } else if (receiverBase == NULL){ - strcpy(mess,"Receiver not set up\n"); + strcpy(mess,SET_RECEIVER_ERR_MESSAGE); ret=FAIL; } else @@ -1051,7 +1052,7 @@ int slsReceiverTCPIPInterface::set_short_frame() { ret=FAIL; } else if (receiverBase == NULL){ - strcpy(mess,"Receiver not set up\n"); + strcpy(mess,SET_RECEIVER_ERR_MESSAGE); ret=FAIL; } else if(receiverBase->getStatus()==RUNNING){ @@ -1135,7 +1136,7 @@ int slsReceiverTCPIPInterface::moench_read_frame(){ // execute action if the arguments correctly arrived #ifdef SLS_RECEIVER_UDP_FUNCTIONS if (receiverBase == NULL){ - strcpy(mess,"Receiver not set up\n"); + strcpy(mess,SET_RECEIVER_ERR_MESSAGE); ret=FAIL; } /**send garbage with -1 index to try again*/ @@ -1324,7 +1325,7 @@ int slsReceiverTCPIPInterface::gotthard_read_frame(){ #ifdef SLS_RECEIVER_UDP_FUNCTIONS if (receiverBase == NULL){ - strcpy(mess,"Receiver not set up\n"); + strcpy(mess,SET_RECEIVER_ERR_MESSAGE); ret=FAIL; } @@ -1499,7 +1500,7 @@ int slsReceiverTCPIPInterface::propix_read_frame(){ #ifdef SLS_RECEIVER_UDP_FUNCTIONS if (receiverBase == NULL){ - strcpy(mess,"Receiver not set up\n"); + strcpy(mess,SET_RECEIVER_ERR_MESSAGE); ret=FAIL; } @@ -1650,7 +1651,7 @@ int slsReceiverTCPIPInterface::eiger_read_frame(){ #ifdef SLS_RECEIVER_UDP_FUNCTIONS if (receiverBase == NULL){ - strcpy(mess,"Receiver not set up\n"); + strcpy(mess,SET_RECEIVER_ERR_MESSAGE); ret=FAIL; } @@ -1895,7 +1896,7 @@ int slsReceiverTCPIPInterface::jungfrau_read_frame(){ #ifdef SLS_RECEIVER_UDP_FUNCTIONS if (receiverBase == NULL){ - strcpy(mess,"Receiver not set up\n"); + strcpy(mess,SET_RECEIVER_ERR_MESSAGE); ret=FAIL; } @@ -2048,7 +2049,7 @@ int slsReceiverTCPIPInterface::set_read_frequency(){ ret=FAIL; } else if (receiverBase == NULL){ - strcpy(mess,"Receiver not set up\n"); + strcpy(mess,SET_RECEIVER_ERR_MESSAGE); ret=FAIL; } /* @@ -2113,7 +2114,7 @@ int slsReceiverTCPIPInterface::enable_file_write(){ ret=FAIL; } else if (receiverBase == NULL){ - strcpy(mess,"Receiver not set up\n"); + strcpy(mess,SET_RECEIVER_ERR_MESSAGE); ret=FAIL; } else{ @@ -2185,7 +2186,7 @@ int slsReceiverTCPIPInterface::start_readout(){ // execute action if the arguments correctly arrived #ifdef SLS_RECEIVER_UDP_FUNCTIONS if (receiverBase == NULL){ - strcpy(mess,"Receiver not set up\n"); + strcpy(mess,SET_RECEIVER_ERR_MESSAGE); ret=FAIL; }else{ receiverBase->startReadout(); @@ -2240,7 +2241,7 @@ int slsReceiverTCPIPInterface::set_timer() { ret=FAIL; } else if (receiverBase == NULL){ - strcpy(mess,"Receiver not set up\n"); + strcpy(mess,SET_RECEIVER_ERR_MESSAGE); ret=FAIL; } else{ @@ -2315,7 +2316,7 @@ int slsReceiverTCPIPInterface::enable_compression() { ret=FAIL; } else if (receiverBase == NULL){ - strcpy(mess,"Receiver not set up\n"); + strcpy(mess,SET_RECEIVER_ERR_MESSAGE); ret=FAIL; } else if(receiverBase->getStatus()==RUNNING){ @@ -2330,7 +2331,7 @@ int slsReceiverTCPIPInterface::enable_compression() { if(ret != FAIL){ if (receiverBase == NULL){ - strcpy(mess,"Receiver not set up\n"); + strcpy(mess,SET_RECEIVER_ERR_MESSAGE); ret=FAIL; }else{ retval = receiverBase->getDataCompressionEnable(); @@ -2384,7 +2385,7 @@ int slsReceiverTCPIPInterface::set_detector_hostname() { ret=FAIL; } else if (receiverBase == NULL){ - strcpy(mess,"Receiver not set up\n"); + strcpy(mess,SET_RECEIVER_ERR_MESSAGE); ret=FAIL; } else{ @@ -2466,7 +2467,7 @@ int slsReceiverTCPIPInterface::set_dynamic_range() { } if(ret!=FAIL){ if (receiverBase == NULL){ - strcpy(mess,"Receiver not set up\n"); + strcpy(mess,SET_RECEIVER_ERR_MESSAGE); ret=FAIL; }else{ if(dr > 0){ @@ -2542,7 +2543,7 @@ int slsReceiverTCPIPInterface::enable_overwrite() { ret=FAIL; } else if (receiverBase == NULL){ - strcpy(mess,"Receiver not set up\n"); + strcpy(mess,SET_RECEIVER_ERR_MESSAGE); ret=FAIL; } else{ @@ -2605,7 +2606,7 @@ int slsReceiverTCPIPInterface::enable_tengiga() { ret=FAIL; } else if (receiverBase == NULL){ - strcpy(mess,"Receiver not set up\n"); + strcpy(mess,SET_RECEIVER_ERR_MESSAGE); ret=FAIL; } else{ @@ -2670,7 +2671,7 @@ int slsReceiverTCPIPInterface::set_fifo_depth() { ret=FAIL; } else if (receiverBase == NULL){ - strcpy(mess,"Receiver not set up\n"); + strcpy(mess,SET_RECEIVER_ERR_MESSAGE); ret=FAIL; } else if(receiverBase->getStatus()==RUNNING){ @@ -2686,7 +2687,7 @@ int slsReceiverTCPIPInterface::set_fifo_depth() { if (receiverBase == NULL){ - strcpy(mess,"Receiver not set up\n"); + strcpy(mess,SET_RECEIVER_ERR_MESSAGE); ret=FAIL; }else{ retval = receiverBase->getFifoDepth(); @@ -2948,7 +2949,7 @@ int slsReceiverTCPIPInterface::send_update() { int slsReceiverTCPIPInterface::update_client() { ret=OK; if (receiverBase == NULL){ - strcpy(mess,"Receiver not set up\n"); + strcpy(mess,SET_RECEIVER_ERR_MESSAGE); ret=FAIL; } socket->SendDataOnly(&ret,sizeof(ret)); From d88253f643e405fa699b101dbda817512d516105 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Mon, 13 Jun 2016 19:10:14 +0200 Subject: [PATCH 208/474] versions update --- slsReceiverSoftware/gitInfo.txt | 14 +++++++------- slsReceiverSoftware/include/gitInfoReceiver.h | 10 +++++----- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/slsReceiverSoftware/gitInfo.txt b/slsReceiverSoftware/gitInfo.txt index 71d112f95..04de2ab36 100644 --- a/slsReceiverSoftware/gitInfo.txt +++ b/slsReceiverSoftware/gitInfo.txt @@ -1,9 +1,9 @@ Path: slsDetectorsPackage/slsReceiverSoftware -URL: origin maliakal_d@gitorious.psi.ch:sls_det_software/sls_receiver_software.git -Repository Root: origin maliakal_d@gitorious.psi.ch:sls_det_software/sls_receiver_software.git -Repsitory UUID: 750a0a06945a748a18d0b8b19b7cf94ecf2fec23 -Revision: 112 -Branch: master +URL: origin git@git.psi.ch:sls_detectors_software/sls_receiver_software.git +Repository Root: origin git@git.psi.ch:sls_detectors_software/sls_receiver_software.git +Repsitory UUID: a29f65210a2391bba59fe237d3735db29a83c88a +Revision: 235 +Branch: developer Last Changed Author: Dhanya_Maliakal -Last Changed Rev: 112 -Last Changed Date: 2015-06-26 15:57:28 +0200 +Last Changed Rev: 235 +Last Changed Date: 2016-05-10 17:13:27 +0200 diff --git a/slsReceiverSoftware/include/gitInfoReceiver.h b/slsReceiverSoftware/include/gitInfoReceiver.h index 19ffa6835..8c879eb5a 100644 --- a/slsReceiverSoftware/include/gitInfoReceiver.h +++ b/slsReceiverSoftware/include/gitInfoReceiver.h @@ -1,11 +1,11 @@ //#define SVNPATH "" -#define SVNURL "maliakal_d@gitorious.psi.ch:sls_det_software/sls_receiver_software.git" +#define SVNURL "git@git.psi.ch:sls_detectors_software/sls_receiver_software.git" //#define SVNREPPATH "" -#define SVNREPUUID "750a0a06945a748a18d0b8b19b7cf94ecf2fec23" -//#define SVNREV 0x112 +#define SVNREPUUID "a29f65210a2391bba59fe237d3735db29a83c88a" +//#define SVNREV 0x235 //#define SVNKIND "" //#define SVNSCHED "" #define SVNAUTH "Dhanya_Maliakal" -#define SVNREV 0x112 -#define SVNDATE 0x20150626 +#define SVNREV 0x235 +#define SVNDATE 0x20160510 // From df04d9fb07fb7b6222c595d459e57d3949787509 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Mon, 4 Jul 2016 15:51:18 +0200 Subject: [PATCH 209/474] updating versions --- slsReceiverSoftware/gitInfo.txt | 8 ++++---- slsReceiverSoftware/include/gitInfoReceiver.h | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/slsReceiverSoftware/gitInfo.txt b/slsReceiverSoftware/gitInfo.txt index 04de2ab36..ebfc43e78 100644 --- a/slsReceiverSoftware/gitInfo.txt +++ b/slsReceiverSoftware/gitInfo.txt @@ -1,9 +1,9 @@ Path: slsDetectorsPackage/slsReceiverSoftware URL: origin git@git.psi.ch:sls_detectors_software/sls_receiver_software.git Repository Root: origin git@git.psi.ch:sls_detectors_software/sls_receiver_software.git -Repsitory UUID: a29f65210a2391bba59fe237d3735db29a83c88a -Revision: 235 +Repsitory UUID: e961e6a2236cdebed98bc5e51fe862ba0c3bb2f2 +Revision: 236 Branch: developer Last Changed Author: Dhanya_Maliakal -Last Changed Rev: 235 -Last Changed Date: 2016-05-10 17:13:27 +0200 +Last Changed Rev: 236 +Last Changed Date: 2016-06-13 19:10:14 +0200 diff --git a/slsReceiverSoftware/include/gitInfoReceiver.h b/slsReceiverSoftware/include/gitInfoReceiver.h index 8c879eb5a..77d90c49e 100644 --- a/slsReceiverSoftware/include/gitInfoReceiver.h +++ b/slsReceiverSoftware/include/gitInfoReceiver.h @@ -1,11 +1,11 @@ //#define SVNPATH "" #define SVNURL "git@git.psi.ch:sls_detectors_software/sls_receiver_software.git" //#define SVNREPPATH "" -#define SVNREPUUID "a29f65210a2391bba59fe237d3735db29a83c88a" -//#define SVNREV 0x235 +#define SVNREPUUID "e961e6a2236cdebed98bc5e51fe862ba0c3bb2f2" +//#define SVNREV 0x236 //#define SVNKIND "" //#define SVNSCHED "" #define SVNAUTH "Dhanya_Maliakal" -#define SVNREV 0x235 -#define SVNDATE 0x20160510 +#define SVNREV 0x236 +#define SVNDATE 0x20160613 // From a65920377c522b1e862e9b7c73a1e69f0fe96b70 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 5 Jul 2016 17:17:34 +0200 Subject: [PATCH 210/474] feature with header in file --- .../include/UDPStandardImplementation.h | 8 +++ .../src/UDPStandardImplementation.cpp | 56 ++++++++++++++++++- 2 files changed, 63 insertions(+), 1 deletion(-) diff --git a/slsReceiverSoftware/include/UDPStandardImplementation.h b/slsReceiverSoftware/include/UDPStandardImplementation.h index 521d6079b..8ab54a300 100644 --- a/slsReceiverSoftware/include/UDPStandardImplementation.h +++ b/slsReceiverSoftware/include/UDPStandardImplementation.h @@ -440,6 +440,11 @@ private: */ void createHeaders(char* wbuffer[]); + /** + * Updates the file header char aray, each time the corresp parameter is changed + */ + void updateFileHeader(); + /** * Called by handleWithoutDataCompression and handleWithCompression after writing to file * Copy frames for GUI and updates appropriate parameters for frequency frames to gui @@ -467,6 +472,7 @@ private: + /************************************************************************* * Class Members ********************************************************* *************************************************************************/ @@ -515,6 +521,8 @@ private: /** If file created successfully for all Writer Threads */ bool fileCreateSuccess; + char fileHeader[1000]; + diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 9c18ad243..614cfc8c7 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -138,6 +138,7 @@ void UDPStandardImplementation::initializeMembers(){ strcpy(completeFileName,""); maxPacketsPerFile = 0; fileCreateSuccess = false; + strcpy(fileHeader,""); //***acquisition indices parameters*** startAcquisitionIndex = 0; @@ -536,6 +537,8 @@ int UDPStandardImplementation::setDynamicRange(const uint32_t i){ frameSize = onePacketSize * packetsPerFrame; maxPacketsPerFile = EIGER_MAX_FRAMES_PER_FILE * packetsPerFrame; + updateFileHeader(); + //new dynamic range, then restart threads and resetup fifo structure if(oldDynamicRange != dynamicRange){ @@ -591,6 +594,7 @@ int UDPStandardImplementation::setTenGigaEnable(const bool b){ "\nmaxPacketsPerFile:" << maxPacketsPerFile; + updateFileHeader(); //new enable, then restart threads and resetup fifo structure if(oldTenGigaEnable != tengigaEnable){ @@ -767,6 +771,10 @@ int UDPStandardImplementation::setDetectorType(const detectorType d){ //allocate for latest data (frame copy for gui) latestData = new char[frameSize]; + //updates File Header + if(myDetectorType == EIGER) + updateFileHeader(); + FILE_LOG(logDEBUG) << " Detector type set to " << getDetectorType(d); return OK; @@ -1413,6 +1421,10 @@ int UDPStandardImplementation::createNewFile(){ numTotMissingPacketsInFile = 0; } + //write file header + if(myDetectorType == EIGER) + fwrite((void*)fileHeader, 1, strlen(fileHeader), sfilefd); + return OK; } @@ -2801,7 +2813,7 @@ void UDPStandardImplementation::createHeaders(char* wbuffer[]){ //overwriting port number and dynamic range *( (uint8_t*) wbuf_header->portIndex) = (uint8_t)port; - *( (uint8_t*) wbuf_header->dynamicRange) = (uint8_t)dynamicRange; + //*( (uint8_t*) wbuf_header->dynamicRange) = (uint8_t)dynamicRange; //DEBUGGING if(*( (uint16_t*) wbuf_footer->packetNumber) != (i+1)){ @@ -2820,6 +2832,48 @@ void UDPStandardImplementation::createHeaders(char* wbuffer[]){ } +void UDPStandardImplementation::updateFileHeader(){ + int xpix=-1,ypix=-1; + + //create detector specific packet header + char packetheader[1000]; + strcpy(packetheader,""); + + //only for eiger right now + /*switch(myDetectorType){ + case EIGER: + */ sprintf(packetheader,"#Packet Header\n" + "Sub Frame Number 4 bytes\n" + "Missing Packet\t 2 bytes\n" + "Port Number\t 1 byte\n" + "Unused\t\t 1 byte\n\n" + "#Packet Footer\n" + "Frame Number\t 6 bytes\n" + "Packet Number\t 2 bytes\n"); + xpix = EIGER_PIXELS_IN_ONE_ROW; + ypix = EIGER_PIXELS_IN_ONE_COL; + /* break; + default: + break; + } +*/ + + //update file header + int length = sizeof(fileHeader); + while(length!=strlen(fileHeader)){ + length = strlen(fileHeader); + sprintf(fileHeader,"Header\t\t %d bytes\n" + "Dynamic Range\t %d\n" + "Packet\t\t %d bytes\n" + "x\t\t %d pixels\n" + "y\t\t %d pixels\n\n" + "%s", + length,dynamicRange,onePacketSize,xpix,ypix,packetheader); + } + +} + + void UDPStandardImplementation::copyFrameToGui(char* buffer[]){ FILE_LOG(logDEBUG) << __AT__ << " called"; From 980c1c02e601a9a50a1b99df27abd1f0d24bd9a7 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 5 Jul 2016 17:23:05 +0200 Subject: [PATCH 211/474] updating versions --- slsReceiverSoftware/gitInfo.txt | 8 ++++---- slsReceiverSoftware/include/gitInfoReceiver.h | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/slsReceiverSoftware/gitInfo.txt b/slsReceiverSoftware/gitInfo.txt index ebfc43e78..99bdd785a 100644 --- a/slsReceiverSoftware/gitInfo.txt +++ b/slsReceiverSoftware/gitInfo.txt @@ -1,9 +1,9 @@ Path: slsDetectorsPackage/slsReceiverSoftware URL: origin git@git.psi.ch:sls_detectors_software/sls_receiver_software.git Repository Root: origin git@git.psi.ch:sls_detectors_software/sls_receiver_software.git -Repsitory UUID: e961e6a2236cdebed98bc5e51fe862ba0c3bb2f2 -Revision: 236 +Repsitory UUID: 1f6fd4bdf369baca329b1cdc186d3aaf258c364c +Revision: 238 Branch: developer Last Changed Author: Dhanya_Maliakal -Last Changed Rev: 236 -Last Changed Date: 2016-06-13 19:10:14 +0200 +Last Changed Rev: 238 +Last Changed Date: 2016-07-05 17:17:34 +0200 diff --git a/slsReceiverSoftware/include/gitInfoReceiver.h b/slsReceiverSoftware/include/gitInfoReceiver.h index 77d90c49e..3df81898b 100644 --- a/slsReceiverSoftware/include/gitInfoReceiver.h +++ b/slsReceiverSoftware/include/gitInfoReceiver.h @@ -1,11 +1,11 @@ //#define SVNPATH "" #define SVNURL "git@git.psi.ch:sls_detectors_software/sls_receiver_software.git" //#define SVNREPPATH "" -#define SVNREPUUID "e961e6a2236cdebed98bc5e51fe862ba0c3bb2f2" -//#define SVNREV 0x236 +#define SVNREPUUID "1f6fd4bdf369baca329b1cdc186d3aaf258c364c" +//#define SVNREV 0x238 //#define SVNKIND "" //#define SVNSCHED "" #define SVNAUTH "Dhanya_Maliakal" -#define SVNREV 0x236 -#define SVNDATE 0x20160613 +#define SVNREV 0x238 +#define SVNDATE 0x20160705 // From 347ecb9bb5b6bed47e887796263dcc3d49635cc5 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 5 Jul 2016 17:24:45 +0200 Subject: [PATCH 212/474] updating versions --- slsReceiverSoftware/gitInfo.txt | 8 ++++---- slsReceiverSoftware/include/gitInfoReceiver.h | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/slsReceiverSoftware/gitInfo.txt b/slsReceiverSoftware/gitInfo.txt index 99bdd785a..67fc9b596 100644 --- a/slsReceiverSoftware/gitInfo.txt +++ b/slsReceiverSoftware/gitInfo.txt @@ -1,9 +1,9 @@ Path: slsDetectorsPackage/slsReceiverSoftware URL: origin git@git.psi.ch:sls_detectors_software/sls_receiver_software.git Repository Root: origin git@git.psi.ch:sls_detectors_software/sls_receiver_software.git -Repsitory UUID: 1f6fd4bdf369baca329b1cdc186d3aaf258c364c -Revision: 238 +Repsitory UUID: a6e547d12d512ad5cd177f32cd6a38439c66fa49 +Revision: 239 Branch: developer Last Changed Author: Dhanya_Maliakal -Last Changed Rev: 238 -Last Changed Date: 2016-07-05 17:17:34 +0200 +Last Changed Rev: 239 +Last Changed Date: 2016-07-05 17:23:05 +0200 diff --git a/slsReceiverSoftware/include/gitInfoReceiver.h b/slsReceiverSoftware/include/gitInfoReceiver.h index 3df81898b..2763cd87a 100644 --- a/slsReceiverSoftware/include/gitInfoReceiver.h +++ b/slsReceiverSoftware/include/gitInfoReceiver.h @@ -1,11 +1,11 @@ //#define SVNPATH "" #define SVNURL "git@git.psi.ch:sls_detectors_software/sls_receiver_software.git" //#define SVNREPPATH "" -#define SVNREPUUID "1f6fd4bdf369baca329b1cdc186d3aaf258c364c" -//#define SVNREV 0x238 +#define SVNREPUUID "a6e547d12d512ad5cd177f32cd6a38439c66fa49" +//#define SVNREV 0x239 //#define SVNKIND "" //#define SVNSCHED "" #define SVNAUTH "Dhanya_Maliakal" -#define SVNREV 0x238 +#define SVNREV 0x239 #define SVNDATE 0x20160705 // From 96a88f9de2c6df1dafcd7fae81f6e85d48b878d6 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Wed, 6 Jul 2016 10:31:30 +0200 Subject: [PATCH 213/474] added timestamp --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 614cfc8c7..03eabbd69 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -16,6 +16,7 @@ #include #include #include +#include using namespace std; #define WRITE_HEADERS @@ -2859,16 +2860,19 @@ void UDPStandardImplementation::updateFileHeader(){ */ //update file header + time_t t = time(0); int length = sizeof(fileHeader); while(length!=strlen(fileHeader)){ length = strlen(fileHeader); - sprintf(fileHeader,"Header\t\t %d bytes\n" + sprintf(fileHeader,"\nHeader\t\t %d bytes\n" "Dynamic Range\t %d\n" "Packet\t\t %d bytes\n" "x\t\t %d pixels\n" - "y\t\t %d pixels\n\n" + "y\t\t %d pixels\n" + "Timestamp\t %s\n\n" "%s", - length,dynamicRange,onePacketSize,xpix,ypix,packetheader); + length,dynamicRange,onePacketSize,xpix,ypix,ctime(&t), + packetheader); } } From 779d8d109498d27201c48c19f258ddb8a6cd3568 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Wed, 6 Jul 2016 10:32:58 +0200 Subject: [PATCH 214/474] updating versions --- slsReceiverSoftware/gitInfo.txt | 8 ++++---- slsReceiverSoftware/include/gitInfoReceiver.h | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/slsReceiverSoftware/gitInfo.txt b/slsReceiverSoftware/gitInfo.txt index 67fc9b596..d950be936 100644 --- a/slsReceiverSoftware/gitInfo.txt +++ b/slsReceiverSoftware/gitInfo.txt @@ -1,9 +1,9 @@ Path: slsDetectorsPackage/slsReceiverSoftware URL: origin git@git.psi.ch:sls_detectors_software/sls_receiver_software.git Repository Root: origin git@git.psi.ch:sls_detectors_software/sls_receiver_software.git -Repsitory UUID: a6e547d12d512ad5cd177f32cd6a38439c66fa49 -Revision: 239 +Repsitory UUID: 041be3f69f7d6a3b33dd270fe5175839962cc23f +Revision: 241 Branch: developer Last Changed Author: Dhanya_Maliakal -Last Changed Rev: 239 -Last Changed Date: 2016-07-05 17:23:05 +0200 +Last Changed Rev: 241 +Last Changed Date: 2016-07-06 10:31:30 +0200 diff --git a/slsReceiverSoftware/include/gitInfoReceiver.h b/slsReceiverSoftware/include/gitInfoReceiver.h index 2763cd87a..939ac3864 100644 --- a/slsReceiverSoftware/include/gitInfoReceiver.h +++ b/slsReceiverSoftware/include/gitInfoReceiver.h @@ -1,11 +1,11 @@ //#define SVNPATH "" #define SVNURL "git@git.psi.ch:sls_detectors_software/sls_receiver_software.git" //#define SVNREPPATH "" -#define SVNREPUUID "a6e547d12d512ad5cd177f32cd6a38439c66fa49" -//#define SVNREV 0x239 +#define SVNREPUUID "041be3f69f7d6a3b33dd270fe5175839962cc23f" +//#define SVNREV 0x241 //#define SVNKIND "" //#define SVNSCHED "" #define SVNAUTH "Dhanya_Maliakal" -#define SVNREV 0x239 -#define SVNDATE 0x20160705 +#define SVNREV 0x241 +#define SVNDATE 0x20160706 // From 79e3cdd183edd24d0427568ebc06e325178c4b6b Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 12 Jul 2016 16:02:23 +0200 Subject: [PATCH 215/474] receiver crashing at file write disabled taking acquistion --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 03eabbd69..210e3b95c 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1413,6 +1413,9 @@ int UDPStandardImplementation::createNewFile(){ } + //write file header + if(myDetectorType == EIGER) + fwrite((void*)fileHeader, 1, strlen(fileHeader), sfilefd); } //reset counters for each new file @@ -1422,9 +1425,7 @@ int UDPStandardImplementation::createNewFile(){ numTotMissingPacketsInFile = 0; } - //write file header - if(myDetectorType == EIGER) - fwrite((void*)fileHeader, 1, strlen(fileHeader), sfilefd); + return OK; } From 3fd3a5dc105eedda3a954fbda11ed66c12bf8cd6 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 12 Jul 2016 16:21:50 +0200 Subject: [PATCH 216/474] last frame number caught added to log --- .../include/UDPStandardImplementation.h | 3 +++ slsReceiverSoftware/src/UDPStandardImplementation.cpp | 10 ++++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/slsReceiverSoftware/include/UDPStandardImplementation.h b/slsReceiverSoftware/include/UDPStandardImplementation.h index 8ab54a300..26f63ddc0 100644 --- a/slsReceiverSoftware/include/UDPStandardImplementation.h +++ b/slsReceiverSoftware/include/UDPStandardImplementation.h @@ -542,6 +542,9 @@ private: /** Previous Frame number from buffer to calculate loss */ int64_t previousFrameNumber; + /** Last Frame Index Listened To */ + int32_t lastFrameIndex; + /* Acquisition started */ bool acqStarted; diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 210e3b95c..0d7f30aea 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -147,10 +147,12 @@ void UDPStandardImplementation::initializeMembers(){ frameIndex = 0; currentFrameNumber = 0; previousFrameNumber = -1; + lastFrameIndex = 0; acqStarted = false; measurementStarted = false; - for(int i = 0; i < MAX_NUMBER_OF_LISTENING_THREADS; ++i) + for(int i = 0; i < MAX_NUMBER_OF_LISTENING_THREADS; ++i){ totalListeningFrameCount[i] = 0; + } packetsInFile = 0; numMissingPackets = 0; numTotMissingPackets = 0; @@ -2106,7 +2108,8 @@ void UDPStandardImplementation::processWritingBufferPacketByPacket(int ithread){ *(blankframe_data) = 0xFF; } } - + //last frame read out + lastFrameIndex = -1; @@ -2162,6 +2165,8 @@ void UDPStandardImplementation::processWritingBufferPacketByPacket(int ithread){ } //frame number threadFrameNumber[i] = (uint32_t)(*( (uint64_t*) packetBuffer_footer)); + //last frame read out + lastFrameIndex = threadFrameNumber[i]; threadFrameNumber[i] += (startFrameIndex - 1); //packet number @@ -2548,6 +2553,7 @@ void UDPStandardImplementation::stopWriting(int ithread, char* wbuffer[]){ //statistics FILE_LOG(logINFO) << "Status: Run Finished"; + FILE_LOG(logINFO) << "Last Frame Number Caught:" << lastFrameIndex; if(totalPacketsCaught < ((uint64_t)numberOfFrames*packetsPerFrame)){ cprintf(RED, "Total Missing Packets padded: %d\n",numTotMissingPackets); cprintf(RED, "Total Packets Caught: %lld\n",(long long int)totalPacketsCaught); From eda342911f09ced8ea3eea11000c2ace6476802d Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Thu, 14 Jul 2016 16:23:29 +0200 Subject: [PATCH 217/474] update versions --- slsReceiverSoftware/gitInfo.txt | 8 ++++---- slsReceiverSoftware/include/gitInfoReceiver.h | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/slsReceiverSoftware/gitInfo.txt b/slsReceiverSoftware/gitInfo.txt index d950be936..5460959f8 100644 --- a/slsReceiverSoftware/gitInfo.txt +++ b/slsReceiverSoftware/gitInfo.txt @@ -1,9 +1,9 @@ Path: slsDetectorsPackage/slsReceiverSoftware URL: origin git@git.psi.ch:sls_detectors_software/sls_receiver_software.git Repository Root: origin git@git.psi.ch:sls_detectors_software/sls_receiver_software.git -Repsitory UUID: 041be3f69f7d6a3b33dd270fe5175839962cc23f -Revision: 241 +Repsitory UUID: 8e0c6a761b1b7370aaf6ab16fd14d394606538c1 +Revision: 244 Branch: developer Last Changed Author: Dhanya_Maliakal -Last Changed Rev: 241 -Last Changed Date: 2016-07-06 10:31:30 +0200 +Last Changed Rev: 244 +Last Changed Date: 2016-07-12 16:21:50 +0200 diff --git a/slsReceiverSoftware/include/gitInfoReceiver.h b/slsReceiverSoftware/include/gitInfoReceiver.h index 939ac3864..d768a3094 100644 --- a/slsReceiverSoftware/include/gitInfoReceiver.h +++ b/slsReceiverSoftware/include/gitInfoReceiver.h @@ -1,11 +1,11 @@ //#define SVNPATH "" #define SVNURL "git@git.psi.ch:sls_detectors_software/sls_receiver_software.git" //#define SVNREPPATH "" -#define SVNREPUUID "041be3f69f7d6a3b33dd270fe5175839962cc23f" -//#define SVNREV 0x241 +#define SVNREPUUID "8e0c6a761b1b7370aaf6ab16fd14d394606538c1" +//#define SVNREV 0x244 //#define SVNKIND "" //#define SVNSCHED "" #define SVNAUTH "Dhanya_Maliakal" -#define SVNREV 0x241 -#define SVNDATE 0x20160706 +#define SVNREV 0x244 +#define SVNDATE 0x20160712 // From 56a0bbfcc197bad5920a22e3b9dba4ec421d34f2 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Thu, 14 Jul 2016 17:10:28 +0200 Subject: [PATCH 218/474] bug filename with respect to frame number --- .../src/UDPStandardImplementation.cpp | 57 +++++++++---------- 1 file changed, 27 insertions(+), 30 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 0d7f30aea..06db3368c 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -2663,6 +2663,33 @@ void UDPStandardImplementation::writeFileWithoutCompression(char* wbuffer[],uint //loop to take care of creating new files when it reaches max packets per file while(numpackets > 0){ + //new file + if(packetsInFile >= (uint32_t)maxPacketsPerFile){ + //for packet loss, because currframenum is the latest one for eiger + //get frame number (eiger already gets it when it does packet to packet processing) + if(myDetectorType != EIGER){ + lastpacket = (((packetsToSave - 1) * onePacketSize) + offset); + if(myDetectorType == JUNGFRAU){ + jfrau_packet_header_t* header = (jfrau_packet_header_t*) (wbuffer[0] + lastpacket); + currentFrameNumber = (*( (uint32_t*) header->frameNumber))&0xffffff; + }else{ + tempframenumber = ((uint32_t)(*((uint32_t*)(wbuffer[0] + lastpacket)))); + //for gotthard and normal frame, increment frame number to separate fnum and pnum + if (myDetectorType == PROPIX ||(myDetectorType == GOTTHARD && shortFrameEnable == -1)) + tempframenumber++; + //get frame number + currentFrameNumber = (tempframenumber & frameIndexMask) >> frameIndexOffset; + } + + //set indices + acquisitionIndex = currentFrameNumber - startAcquisitionIndex; + frameIndex = currentFrameNumber - startFrameIndex; + } +#ifdef DEBUG3 + cprintf(GREEN,"Writing_Thread: Current Frame Number:%d\n",currentFrameNumber); +#endif + createNewFile(); + } //to create new file when max reached packetsToSave = maxPacketsPerFile - packetsInFile; if(packetsToSave > numpackets) @@ -2694,36 +2721,6 @@ void UDPStandardImplementation::writeFileWithoutCompression(char* wbuffer[],uint cprintf(GREEN,"Writing Thread: packetscaught:%d totalPacketsCaught:%d\n", packetsCaught,totalPacketsCaught); #endif - //new file - if(packetsInFile >= (uint32_t)maxPacketsPerFile){ - //for packet loss, because currframenum is the latest one for eiger - //get frame number (eiger already gets it when it does packet to packet processing) - if(myDetectorType != EIGER){ - lastpacket = (((packetsToSave - 1) * onePacketSize) + offset); - if(myDetectorType == JUNGFRAU){ - jfrau_packet_header_t* header = (jfrau_packet_header_t*) (wbuffer[0] + lastpacket); - currentFrameNumber = (*( (uint32_t*) header->frameNumber))&0xffffff; - }else{ - tempframenumber = ((uint32_t)(*((uint32_t*)(wbuffer[0] + lastpacket)))); - //for gotthard and normal frame, increment frame number to separate fnum and pnum - if (myDetectorType == PROPIX ||(myDetectorType == GOTTHARD && shortFrameEnable == -1)) - tempframenumber++; - //get frame number - currentFrameNumber = (tempframenumber & frameIndexMask) >> frameIndexOffset; - } - - - - //set indices - acquisitionIndex = currentFrameNumber - startAcquisitionIndex; - frameIndex = currentFrameNumber - startFrameIndex; - } -#ifdef DEBUG3 - cprintf(GREEN,"Writing_Thread: Current Frame Number:%d\n",currentFrameNumber); -#endif - createNewFile(); - } - //increase offset if(myDetectorType != EIGER) offset += (packetsToSave * onePacketSize); From c852463de10b8311167be8008ad70f28d528be84 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Mon, 18 Jul 2016 18:18:08 +0200 Subject: [PATCH 219/474] updaterev --- slsReceiverSoftware/gitInfo.txt | 8 ++++---- slsReceiverSoftware/include/gitInfoReceiver.h | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/slsReceiverSoftware/gitInfo.txt b/slsReceiverSoftware/gitInfo.txt index 5460959f8..6094ae5bc 100644 --- a/slsReceiverSoftware/gitInfo.txt +++ b/slsReceiverSoftware/gitInfo.txt @@ -1,9 +1,9 @@ Path: slsDetectorsPackage/slsReceiverSoftware URL: origin git@git.psi.ch:sls_detectors_software/sls_receiver_software.git Repository Root: origin git@git.psi.ch:sls_detectors_software/sls_receiver_software.git -Repsitory UUID: 8e0c6a761b1b7370aaf6ab16fd14d394606538c1 -Revision: 244 +Repsitory UUID: 6de08693c4ded931234c93824d36bb17ca1308cd +Revision: 246 Branch: developer Last Changed Author: Dhanya_Maliakal -Last Changed Rev: 244 -Last Changed Date: 2016-07-12 16:21:50 +0200 +Last Changed Rev: 246 +Last Changed Date: 2016-07-14 17:10:28 +0200 diff --git a/slsReceiverSoftware/include/gitInfoReceiver.h b/slsReceiverSoftware/include/gitInfoReceiver.h index d768a3094..a90b621c7 100644 --- a/slsReceiverSoftware/include/gitInfoReceiver.h +++ b/slsReceiverSoftware/include/gitInfoReceiver.h @@ -1,11 +1,11 @@ //#define SVNPATH "" #define SVNURL "git@git.psi.ch:sls_detectors_software/sls_receiver_software.git" //#define SVNREPPATH "" -#define SVNREPUUID "8e0c6a761b1b7370aaf6ab16fd14d394606538c1" -//#define SVNREV 0x244 +#define SVNREPUUID "6de08693c4ded931234c93824d36bb17ca1308cd" +//#define SVNREV 0x246 //#define SVNKIND "" //#define SVNSCHED "" #define SVNAUTH "Dhanya_Maliakal" -#define SVNREV 0x244 -#define SVNDATE 0x20160712 +#define SVNREV 0x246 +#define SVNDATE 0x20160714 // From 658f3459ca0aee01a3ca38aa0e303631cb3813a7 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Wed, 3 Aug 2016 17:02:40 +0200 Subject: [PATCH 220/474] changes to get rid of warnings --- slsReceiverSoftware/include/sls_receiver_funcs.h | 4 +++- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/slsReceiverSoftware/include/sls_receiver_funcs.h b/slsReceiverSoftware/include/sls_receiver_funcs.h index e1ef93040..040beae44 100644 --- a/slsReceiverSoftware/include/sls_receiver_funcs.h +++ b/slsReceiverSoftware/include/sls_receiver_funcs.h @@ -49,7 +49,9 @@ enum { F_ENABLE_RECEIVER_OVERWRITE, /**< set overwrite flag in receiver */ F_ENABLE_RECEIVER_TEN_GIGA, /**< enable 10Gbe in receiver */ - F_SET_RECEIVER_FIFO_DEPTH /**< set receiver fifo depth */ + F_SET_RECEIVER_FIFO_DEPTH, /**< set receiver fifo depth */ + + F_SET_TRANSMISSION_DELAY /**< set transmission delay */ /* Always append functions hereafter!!! */ }; diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 06db3368c..6ab655ac0 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1897,7 +1897,7 @@ uint32_t UDPStandardImplementation::processListeningBuffer(int ithread, int cSiz cSize += onePacketSize; lastPacketOffset -= onePacketSize; --packetCount; - while (lastFrameHeader64 == (*( (uint32_t*) header->frameNumber))&0xffffff){ + while (lastFrameHeader64 == ((*( (uint32_t*) header->frameNumber))&0xffffff)){ cSize += onePacketSize; lastPacketOffset -= onePacketSize; header = (jfrau_packet_header_t*) (buffer[ithread]+lastPacketOffset); @@ -2866,7 +2866,7 @@ void UDPStandardImplementation::updateFileHeader(){ //update file header time_t t = time(0); int length = sizeof(fileHeader); - while(length!=strlen(fileHeader)){ + while((unsigned int)length!=strlen(fileHeader)){ length = strlen(fileHeader); sprintf(fileHeader,"\nHeader\t\t %d bytes\n" "Dynamic Range\t %d\n" From b3ad45b1c941eafac18b65e60cc613fe4982a6f0 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Thu, 4 Aug 2016 17:19:31 +0200 Subject: [PATCH 221/474] wrongly put func def in receiver_funcs --- slsReceiverSoftware/include/sls_receiver_funcs.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/slsReceiverSoftware/include/sls_receiver_funcs.h b/slsReceiverSoftware/include/sls_receiver_funcs.h index 040beae44..e1ef93040 100644 --- a/slsReceiverSoftware/include/sls_receiver_funcs.h +++ b/slsReceiverSoftware/include/sls_receiver_funcs.h @@ -49,9 +49,7 @@ enum { F_ENABLE_RECEIVER_OVERWRITE, /**< set overwrite flag in receiver */ F_ENABLE_RECEIVER_TEN_GIGA, /**< enable 10Gbe in receiver */ - F_SET_RECEIVER_FIFO_DEPTH, /**< set receiver fifo depth */ - - F_SET_TRANSMISSION_DELAY /**< set transmission delay */ + F_SET_RECEIVER_FIFO_DEPTH /**< set receiver fifo depth */ /* Always append functions hereafter!!! */ }; From e452bccea2d97bdd852a51476b57cb57fef65823 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Fri, 12 Aug 2016 11:18:11 +0200 Subject: [PATCH 222/474] updaterev --- slsReceiverSoftware/gitInfo.txt | 10 +++++----- slsReceiverSoftware/include/gitInfoReceiver.h | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/slsReceiverSoftware/gitInfo.txt b/slsReceiverSoftware/gitInfo.txt index 6094ae5bc..4d39e4314 100644 --- a/slsReceiverSoftware/gitInfo.txt +++ b/slsReceiverSoftware/gitInfo.txt @@ -1,9 +1,9 @@ Path: slsDetectorsPackage/slsReceiverSoftware URL: origin git@git.psi.ch:sls_detectors_software/sls_receiver_software.git Repository Root: origin git@git.psi.ch:sls_detectors_software/sls_receiver_software.git -Repsitory UUID: 6de08693c4ded931234c93824d36bb17ca1308cd -Revision: 246 -Branch: developer +Repsitory UUID: a10bf5ae88d113a482dca646085abcb7a45dc52e +Revision: 249 +Branch: master Last Changed Author: Dhanya_Maliakal -Last Changed Rev: 246 -Last Changed Date: 2016-07-14 17:10:28 +0200 +Last Changed Rev: 249 +Last Changed Date: 2016-08-04 17:19:31 +0200 diff --git a/slsReceiverSoftware/include/gitInfoReceiver.h b/slsReceiverSoftware/include/gitInfoReceiver.h index a90b621c7..b3eb26e83 100644 --- a/slsReceiverSoftware/include/gitInfoReceiver.h +++ b/slsReceiverSoftware/include/gitInfoReceiver.h @@ -1,11 +1,11 @@ //#define SVNPATH "" #define SVNURL "git@git.psi.ch:sls_detectors_software/sls_receiver_software.git" //#define SVNREPPATH "" -#define SVNREPUUID "6de08693c4ded931234c93824d36bb17ca1308cd" -//#define SVNREV 0x246 +#define SVNREPUUID "a10bf5ae88d113a482dca646085abcb7a45dc52e" +//#define SVNREV 0x249 //#define SVNKIND "" //#define SVNSCHED "" #define SVNAUTH "Dhanya_Maliakal" -#define SVNREV 0x246 -#define SVNDATE 0x20160714 +#define SVNREV 0x249 +#define SVNDATE 0x20160804 // From 882202c2bcd1e286cf83874e2623c5dc5d002f82 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Fri, 12 Aug 2016 13:48:30 +0200 Subject: [PATCH 223/474] fixed bug show nth frame as in 2nd, 4th etc. --- .../include/UDPStandardImplementation.h | 4 ++++ slsReceiverSoftware/src/UDPStandardImplementation.cpp | 11 +++++++++++ 2 files changed, 15 insertions(+) diff --git a/slsReceiverSoftware/include/UDPStandardImplementation.h b/slsReceiverSoftware/include/UDPStandardImplementation.h index 26f63ddc0..a3af9ab03 100644 --- a/slsReceiverSoftware/include/UDPStandardImplementation.h +++ b/slsReceiverSoftware/include/UDPStandardImplementation.h @@ -601,6 +601,8 @@ private: /** Dummy Packet identifier value */ const static uint32_t dummyPacketValue = 0xFFFFFFFF; + + //***receiver to GUI parameters*** /** Current Frame copied for GUI */ char* latestData; @@ -617,6 +619,8 @@ private: /** Semaphore to synchronize Writer and GuiReader threads*/ sem_t writerGuiSemaphore; + /** counter for nth frame to gui */ + int frametoGuiCounter; diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 6ab655ac0..d64692b65 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -176,6 +176,7 @@ void UDPStandardImplementation::initializeMembers(){ guiDataReady = false; guiData = NULL; strcpy(guiFileName,""); + frametoGuiCounter = 0; //***general and listening thread parameters*** threadStarted = false; @@ -804,6 +805,7 @@ int UDPStandardImplementation::startReceiver(char *c){ //RESET //reset measurement variables + frametoGuiCounter = 0; measurementStarted = false; startFrameIndex = 0; frameIndex = 0; @@ -2897,6 +2899,9 @@ void UDPStandardImplementation::copyFrameToGui(char* buffer[]){ pthread_mutex_unlock(&dataReadyMutex); } + //if nthe frame, wait for your turn (1st frame always shown as its zero) + else if(FrameToGuiFrequency && ((frametoGuiCounter)%FrameToGuiFrequency)); + //random read (gui ready) or nth frame read: gui needs data now or it is the first frame else{ #ifdef DEBUG4 @@ -2936,6 +2941,12 @@ void UDPStandardImplementation::copyFrameToGui(char* buffer[]){ } } + + //update the counter for nth frame + if(FrameToGuiFrequency) + frametoGuiCounter++; + + } From b64af8dc8d65a28435031cbd61a5e0789fa26d98 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Mon, 15 Aug 2016 12:10:16 +0200 Subject: [PATCH 224/474] starting --- .../include/UDPStandardImplementation.h | 50 +++++++++++-------- .../src/UDPStandardImplementation.cpp | 17 ++++--- 2 files changed, 40 insertions(+), 27 deletions(-) diff --git a/slsReceiverSoftware/include/UDPStandardImplementation.h b/slsReceiverSoftware/include/UDPStandardImplementation.h index a3af9ab03..b4e85373d 100644 --- a/slsReceiverSoftware/include/UDPStandardImplementation.h +++ b/slsReceiverSoftware/include/UDPStandardImplementation.h @@ -477,6 +477,15 @@ private: * Class Members ********************************************************* *************************************************************************/ + /** Maximum Number of Writer Threads */ + +#ifdef DCOMPRESS + /**** most likely not used ***/ + const static int MAX_NUMBER_OF_WRITER_THREADS = 15; +#else + const static int MAX_NUMBER_OF_WRITER_THREADS = 2; +#endif + //**detector parameters*** /** Size of 1 Frame including headers */ int frameSize; @@ -513,7 +522,7 @@ private: #endif /** Complete File name */ - char completeFileName[MAX_STR_LENGTH]; + char completeFileName[MAX_NUMBER_OF_WRITER_THREADS][MAX_STR_LENGTH]; /** Maximum Packets Per File **/ int maxPacketsPerFile; @@ -521,23 +530,24 @@ private: /** If file created successfully for all Writer Threads */ bool fileCreateSuccess; - char fileHeader[1000]; + char fileHeader[MAX_NUMBER_OF_WRITER_THREADS][MAX_STR_LENGTH]; //***acquisition indices/count parameters*** /** Frame Number of First Frame of an entire Acquisition (including all scans) */ - uint64_t startAcquisitionIndex; + uint64_t startAcquisitionIndex[MAX_NUMBER_OF_LISTENING_THREADS]; /** Frame index at start of each real time acquisition (eg. for each scan) */ - uint64_t startFrameIndex; + uint64_t startFrameIndex[MAX_NUMBER_OF_LISTENING_THREADS]; /** Actual current frame index of each time acquisition (eg. for each scan) */ - uint64_t frameIndex; + uint64_t frameIndex[MAX_NUMBER_OF_WRITER_THREADS]; /** Current Frame Number */ - uint64_t currentFrameNumber; + uint64_t currentFrameNumber[MAX_NUMBER_OF_WRITER_THREADS]; + /** Previous Frame number from buffer to calculate loss */ int64_t previousFrameNumber; @@ -545,26 +555,27 @@ private: /** Last Frame Index Listened To */ int32_t lastFrameIndex; + /* Acquisition started */ - bool acqStarted; + bool acqStarted[MAX_NUMBER_OF_LISTENING_THREADS]; /* Measurement started */ - bool measurementStarted; + bool measurementStarted[MAX_NUMBER_OF_LISTENING_THREADS]; /** Total Frame Count listened to by listening threads */ int totalListeningFrameCount[MAX_NUMBER_OF_LISTENING_THREADS]; /** Pckets currently in current file, starts new file when it reaches max */ - uint32_t packetsInFile; + uint32_t packetsInFile[MAX_NUMBER_OF_WRITER_THREADS]; /** Number of Missing Packets per buffer*/ - uint32_t numMissingPackets; + uint32_t numMissingPackets[MAX_NUMBER_OF_WRITER_THREADS]; /** Total Number of Missing Packets in acquisition*/ - uint32_t numTotMissingPackets; + uint32_t numTotMissingPackets[MAX_NUMBER_OF_WRITER_THREADS]; /** Number of Missing Packets in file */ - uint32_t numTotMissingPacketsInFile; + uint32_t numTotMissingPacketsInFile[MAX_NUMBER_OF_WRITER_THREADS]; @@ -587,7 +598,7 @@ private: genericSocket* udpSocket[MAX_NUMBER_OF_LISTENING_THREADS]; /** File Descriptor */ - FILE *sfilefd; + FILE *sfilefd[MAX_NUMBER_OF_WRITER_THREADS]; /** Number of Jobs Per Buffer */ int numberofJobsPerBuffer; @@ -605,22 +616,22 @@ private: //***receiver to GUI parameters*** /** Current Frame copied for GUI */ - char* latestData; + char* latestData[MAX_NUMBER_OF_WRITER_THREADS]; /** If Data to be sent to GUI is ready */ - bool guiDataReady; + bool guiDataReady[MAX_NUMBER_OF_WRITER_THREADS]; /** Pointer to data to be sent to GUI */ - char* guiData; + char* guiData[MAX_NUMBER_OF_WRITER_THREADS]; /** Pointer to file name to be sent to GUI */ char guiFileName[MAX_STR_LENGTH]; /** Semaphore to synchronize Writer and GuiReader threads*/ - sem_t writerGuiSemaphore; + sem_t writerGuiSemaphore[MAX_NUMBER_OF_WRITER_THREADS]; /** counter for nth frame to gui */ - int frametoGuiCounter; + int frametoGuiCounter[MAX_NUMBER_OF_WRITER_THREADS]; @@ -653,9 +664,6 @@ private: //***writer thread parameters*** - /** Maximum Number of Writer Threads */ - const static int MAX_NUMBER_OF_WRITER_THREADS = 15; - /** Number of Writer Threads */ int numberofWriterThreads; diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index d64692b65..c29177143 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -56,7 +56,8 @@ UDPStandardImplementation::UDPStandardImplementation(){ UDPStandardImplementation::~UDPStandardImplementation(){ FILE_LOG(logDEBUG) << __AT__ << " called"; - closeFile(); + for(int i=0;i Date: Mon, 15 Aug 2016 15:11:46 +0200 Subject: [PATCH 225/474] in between --- .../include/UDPStandardImplementation.h | 6 +- .../src/UDPStandardImplementation.cpp | 66 +++++++++++-------- 2 files changed, 43 insertions(+), 29 deletions(-) diff --git a/slsReceiverSoftware/include/UDPStandardImplementation.h b/slsReceiverSoftware/include/UDPStandardImplementation.h index b4e85373d..d0a52ccb2 100644 --- a/slsReceiverSoftware/include/UDPStandardImplementation.h +++ b/slsReceiverSoftware/include/UDPStandardImplementation.h @@ -550,10 +550,10 @@ private: /** Previous Frame number from buffer to calculate loss */ - int64_t previousFrameNumber; + int64_t previousFrameNumber[MAX_NUMBER_OF_WRITER_THREADS]; /** Last Frame Index Listened To */ - int32_t lastFrameIndex; + int32_t lastFrameIndex[MAX_NUMBER_OF_WRITER_THREADS]; /* Acquisition started */ @@ -625,7 +625,7 @@ private: char* guiData[MAX_NUMBER_OF_WRITER_THREADS]; /** Pointer to file name to be sent to GUI */ - char guiFileName[MAX_STR_LENGTH]; + char guiFileName[MAX_NUMBER_OF_WRITER_THREADS][MAX_STR_LENGTH]; /** Semaphore to synchronize Writer and GuiReader threads*/ sem_t writerGuiSemaphore[MAX_NUMBER_OF_WRITER_THREADS]; diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index c29177143..b6e855d11 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -140,28 +140,31 @@ void UDPStandardImplementation::initializeMembers(){ } #endif for(int i=0; i Date: Mon, 15 Aug 2016 16:59:30 +0200 Subject: [PATCH 226/474] in between --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index b6e855d11..5b88c0cf7 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -791,7 +791,11 @@ int UDPStandardImplementation::setDetectorType(const detectorType d){ numberofJobsPerBuffer = -1; setupFifoStructure(); - //allocate for latest data (frame copy for gui) + //allocate for latest data (frame copy for gui), free variables + for(int i=0; i Date: Mon, 15 Aug 2016 17:32:27 +0200 Subject: [PATCH 227/474] in between --- slsReceiverSoftware/include/UDPStandardImplementation.h | 4 ++-- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 7 ++++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/slsReceiverSoftware/include/UDPStandardImplementation.h b/slsReceiverSoftware/include/UDPStandardImplementation.h index d0a52ccb2..26c01262d 100644 --- a/slsReceiverSoftware/include/UDPStandardImplementation.h +++ b/slsReceiverSoftware/include/UDPStandardImplementation.h @@ -557,10 +557,10 @@ private: /* Acquisition started */ - bool acqStarted[MAX_NUMBER_OF_LISTENING_THREADS]; + bool acqStarted; /* Measurement started */ - bool measurementStarted[MAX_NUMBER_OF_LISTENING_THREADS]; + bool measurementStarted; /** Total Frame Count listened to by listening threads */ int totalListeningFrameCount[MAX_NUMBER_OF_LISTENING_THREADS]; diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 5b88c0cf7..645605409 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -150,10 +150,10 @@ void UDPStandardImplementation::initializeMembers(){ for(int i = 0; i < MAX_NUMBER_OF_LISTENING_THREADS; ++i){ startAcquisitionIndex[i] = 0; startFrameIndex[i] = 0; - acqStarted[i] = false; - measurementStarted[i] = false; totalListeningFrameCount[i] = 0; } + acqStarted = false; + measurementStarted = false; for(int i=0; i Date: Tue, 16 Aug 2016 11:44:20 +0200 Subject: [PATCH 228/474] in between --- .../src/UDPStandardImplementation.cpp | 32 +++++++++++++++---- 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 645605409..bc6c6ab28 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -813,9 +813,16 @@ int UDPStandardImplementation::setDetectorType(const detectorType d){ void UDPStandardImplementation::resetAcquisitionCount(){ FILE_LOG(logDEBUG) << __AT__ << " starting"; - totalPacketsCaught = 0; + for(int i=0;i Date: Tue, 16 Aug 2016 13:42:29 +0200 Subject: [PATCH 229/474] in between --- .../src/UDPStandardImplementation.cpp | 80 ++++++++++--------- 1 file changed, 43 insertions(+), 37 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index bc6c6ab28..3907f7834 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -833,47 +833,46 @@ int UDPStandardImplementation::startReceiver(char *c){ FILE_LOG(logINFO) << "Stopping Receiver"; + //reseting variables - //RESET - //reset measurement variables pthread_mutex_lock(&progressMutex); measurementStarted = false; pthread_mutex_unlock(&progressMutex); - - for(int i=0;i Date: Wed, 17 Aug 2016 09:33:59 +0200 Subject: [PATCH 230/474] in between --- .../include/UDPBaseImplementation.h | 4 +- slsReceiverSoftware/include/UDPInterface.h | 4 +- .../include/UDPStandardImplementation.h | 13 ++- .../src/UDPStandardImplementation.cpp | 109 ++++++++++-------- 4 files changed, 76 insertions(+), 54 deletions(-) diff --git a/slsReceiverSoftware/include/UDPBaseImplementation.h b/slsReceiverSoftware/include/UDPBaseImplementation.h index 568183e42..7562b0056 100644 --- a/slsReceiverSoftware/include/UDPBaseImplementation.h +++ b/slsReceiverSoftware/include/UDPBaseImplementation.h @@ -413,9 +413,9 @@ class UDPBaseImplementation : protected virtual slsReceiverDefs, public UDPInter /** * Closes file / all files(if multiple files) - * @param i thread index (if multiple files used eg. root files) -1 for all threads + * @param i writer thread index */ - void closeFile(int i = -1); + void closeFile(int i = 0); //***callback functions*** diff --git a/slsReceiverSoftware/include/UDPInterface.h b/slsReceiverSoftware/include/UDPInterface.h index 9ad5a7e6a..2b3a3baba 100644 --- a/slsReceiverSoftware/include/UDPInterface.h +++ b/slsReceiverSoftware/include/UDPInterface.h @@ -470,9 +470,9 @@ class UDPInterface { /** * Closes file / all files(if multiple files) - * @param i thread index (if multiple files used eg. root files) -1 for all threads + * @param i writer thread index */ - virtual void closeFile(int i = -1) = 0; + virtual void closeFile(int i = 0) = 0; //***callback functions*** diff --git a/slsReceiverSoftware/include/UDPStandardImplementation.h b/slsReceiverSoftware/include/UDPStandardImplementation.h index 26c01262d..0f2c98bad 100644 --- a/slsReceiverSoftware/include/UDPStandardImplementation.h +++ b/slsReceiverSoftware/include/UDPStandardImplementation.h @@ -210,9 +210,9 @@ class UDPStandardImplementation: private virtual slsReceiverDefs, public UDPBase * Overridden method * Closes file / all files(data compression involves multiple files) * TCPIPInterface can also call this in case of illegal shutdown of receiver - * @param i thread index valid for datacompression using root files, -1 for all threads + * @param i writer thread index */ - void closeFile(int i = -1); + void closeFile(int i = 0); private: /************************************************************************* @@ -307,9 +307,10 @@ private: /** * Creates new file and reset some parameters + * @param ithread writer thread index * @return OK or FAIL */ - int createNewFile(); + int createNewFile(int ithread); /** * Creates new tree and file for compression @@ -428,10 +429,11 @@ private: /** * Calle by handleWithoutDataCompression * Creating headers Writing to file without compression + * @param ithread writer thread index * @param wbuffer is the address of buffer popped out of FIFO * @param numpackets is the number of packets */ - void writeFileWithoutCompression(char* wbuffer[],uint32_t numpackets); + void writeFileWithoutCompression(int ithread, char* wbuffer[],uint32_t numpackets); /** * Called by writeToFileWithoutCompression @@ -524,6 +526,9 @@ private: /** Complete File name */ char completeFileName[MAX_NUMBER_OF_WRITER_THREADS][MAX_STR_LENGTH]; + /** File Prefix with detector index */ + char receiverFilePrefix[MAX_NUMBER_OF_WRITER_THREADS][MAX_STR_LENGTH]; + /** Maximum Packets Per File **/ int maxPacketsPerFile; diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 3907f7834..92e4e9636 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -10,6 +10,8 @@ #include "gotthardModuleData.h" #include "gotthardShortModuleData.h" +#include "fileIOStatic.h" + #include // exit() #include //set precision for printing parameters for create new file #include //map @@ -74,7 +76,8 @@ void UDPStandardImplementation::deleteMembers(){ FILE_LOG(logDEBUG) << "Info: Deleting member pointers"; shutDownUDPSockets(); - closeFile(); + for(int i=0;i config_map){ } -/***file parameters***/ int UDPStandardImplementation::setDataCompressionEnable(const bool b){ FILE_LOG(logDEBUG) << __AT__ << " starting"; @@ -958,12 +961,14 @@ void UDPStandardImplementation::stopReceiver(){ //wait until status is run_finished while(status == TRANSMITTING){ - sem_post(&writerGuiSemaphore); + for(int i=0; i < numberofWriterThreads; i++) + sem_post(&writerGuiSemaphore[i]); usleep(5000); } //semaphore destroy - sem_destroy(&writerGuiSemaphore); + for(int i=0; i < numberofWriterThreads; i++) + sem_destroy(&writerGuiSemaphore[i]); //change status pthread_mutex_lock(&statusMutex); @@ -982,8 +987,6 @@ void UDPStandardImplementation::stopReceiver(){ int UDPStandardImplementation::shutDownUDPSockets(){ FILE_LOG(logDEBUG) << __AT__ << " called"; - - for(int i=0;iShutDownSocket(); @@ -1033,8 +1036,6 @@ void UDPStandardImplementation::startReadout(){ } } - - //set status pthread_mutex_lock(&statusMutex); status = TRANSMITTING; @@ -1049,26 +1050,26 @@ void UDPStandardImplementation::startReadout(){ - -void UDPStandardImplementation::readFrame(char* c,char** raw, uint64_t &startAcq, uint64_t &startFrame){ +/**make this better by asking all of it at once*/ +void UDPStandardImplementation::readFrame(int wThread, char* c,char** raw, uint64_t &startAcq, uint64_t &startFrame){ FILE_LOG(logDEBUG) << __AT__ << " called"; //point to gui data, to let writer thread know that gui is back for data - if (guiData == NULL){ - guiData = latestData; + if (guiData[wThread] == NULL){ + guiData[wThread] = latestData[wThread]; #ifdef DEBUG4 cprintf(CYAN,"Info: gui data not null anymore - ready to get data\n"); #endif } //copy data and filename - strcpy(c,guiFileName); - startAcq = startAcquisitionIndex; - startFrame = startFrameIndex; + strcpy(c,guiFileName[wThread]); + startAcq = startAcquisitionIndex[wThread]; + startFrame = startFrameIndex[wThread]; //gui data not copied yet - if(!guiDataReady){ + if(!guiDataReady[wThread]){ #ifdef DEBUG4 cprintf(CYAN,"Info: gui data not ready\n"); #endif @@ -1080,8 +1081,8 @@ void UDPStandardImplementation::readFrame(char* c,char** raw, uint64_t &startAcq #ifdef DEBUG4 cprintf(CYAN,"Info: gui data ready\n"); #endif - *raw = guiData; - guiData = NULL; + *raw = guiData[wThread]; + guiData[wThread] = NULL; //for nth frame to gui, post semaphore so writer stops waiting if((FrameToGuiFrequency) && (writerThreadsMask)){ @@ -1089,7 +1090,7 @@ void UDPStandardImplementation::readFrame(char* c,char** raw, uint64_t &startAcq cprintf(CYAN,"Info: gonna post\n"); #endif //release after getting data - sem_post(&writerGuiSemaphore); + sem_post(&writerGuiSemaphore[wThread]); } #ifdef DEBUG4 cprintf(CYAN,"Info: done post\n"); @@ -1105,24 +1106,24 @@ void UDPStandardImplementation::closeFile(int i){ //normal if(!dataCompressionEnable){ - if(sfilefd){ + if(sfilefd[i]){ #ifdef DEBUG4 FILE_LOG(logDEBUG4) << "Going to close file: " << fileno(sfilefd)); #endif - fclose(sfilefd); - sfilefd = NULL; + fclose(sfilefd[i]); + sfilefd[i] = NULL; } } //compression else{ #if (defined(MYROOT1) && defined(ALLFILE_DEBUG)) || !defined(MYROOT1) - if(sfilefd){ + if(sfilefd[i]){ #ifdef DEBUG4 - FILE_LOG(logDEBUG4) << "sfield: " << (int)sfilefd; + FILE_LOG(logDEBUG4) << "sfield: " << (int)sfilefd[i]; #endif - fclose(sfilefd); - sfilefd = NULL; + fclose(sfilefd[i]); + sfilefd[i] = NULL; } #endif @@ -1293,7 +1294,9 @@ void UDPStandardImplementation::setThreadPriorities(){ rights = false; if(!rights){ - FILE_LOG(logWARNING) << "No root permission to prioritize threads."; + FILE_LOG(logWARNING) << "Unable to prioritize threads. Root privileges required for this option."; + }else{ + FILE_LOG(logINFO) << "Priorities set - TCP:50, Listening:99, Writing:90"; } } @@ -1375,7 +1378,8 @@ int UDPStandardImplementation::setupWriter(){ //creating first file //setting all value to 1 pthread_mutex_lock(&statusMutex); - for(int i=0; i= (uint32_t)maxPacketsPerFile) - createNewFile(); + createNewFile(0); pthread_mutex_unlock(&progressMutex); #endif From f17a2ba2b8e6e408830b7794259b8b42906d7e23 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Wed, 24 Aug 2016 11:54:15 +0200 Subject: [PATCH 231/474] in between --- .../include/UDPBaseImplementation.h | 4 +- slsReceiverSoftware/include/UDPInterface.h | 4 +- .../include/UDPStandardImplementation.h | 31 +- .../src/UDPBaseImplementation.cpp | 2 +- .../src/UDPStandardImplementation.cpp | 265 ++++++++++-------- .../src/slsReceiverTCPIPInterface.cpp | 5 + 6 files changed, 176 insertions(+), 135 deletions(-) diff --git a/slsReceiverSoftware/include/UDPBaseImplementation.h b/slsReceiverSoftware/include/UDPBaseImplementation.h index 7562b0056..f9c5e9273 100644 --- a/slsReceiverSoftware/include/UDPBaseImplementation.h +++ b/slsReceiverSoftware/include/UDPBaseImplementation.h @@ -413,9 +413,9 @@ class UDPBaseImplementation : protected virtual slsReceiverDefs, public UDPInter /** * Closes file / all files(if multiple files) - * @param i writer thread index + * @param ithread writer thread index */ - void closeFile(int i = 0); + void closeFile(int ithread = 0); //***callback functions*** diff --git a/slsReceiverSoftware/include/UDPInterface.h b/slsReceiverSoftware/include/UDPInterface.h index 2b3a3baba..dba7acf52 100644 --- a/slsReceiverSoftware/include/UDPInterface.h +++ b/slsReceiverSoftware/include/UDPInterface.h @@ -470,9 +470,9 @@ class UDPInterface { /** * Closes file / all files(if multiple files) - * @param i writer thread index + * @param ithread writer thread index */ - virtual void closeFile(int i = 0) = 0; + virtual void closeFile(int ithread = 0) = 0; //***callback functions*** diff --git a/slsReceiverSoftware/include/UDPStandardImplementation.h b/slsReceiverSoftware/include/UDPStandardImplementation.h index 0f2c98bad..4be649189 100644 --- a/slsReceiverSoftware/include/UDPStandardImplementation.h +++ b/slsReceiverSoftware/include/UDPStandardImplementation.h @@ -199,20 +199,21 @@ class UDPStandardImplementation: private virtual slsReceiverDefs, public UDPBase /** * Overridden method * Get the buffer-current frame read by receiver + * @param ithread writer thread * @param c pointer to current file name * @param raw address of pointer, pointing to current frame to send to gui * @param startAcq start index of the acquisition * @param startFrame start index of the scan */ - void readFrame(char* c,char** raw, uint64_t &startAcq, uint64_t &startFrame); + void readFrame(int ithread, char* c,char** raw, uint64_t &startAcq, uint64_t &startFrame); /** * Overridden method * Closes file / all files(data compression involves multiple files) * TCPIPInterface can also call this in case of illegal shutdown of receiver - * @param i writer thread index + * @param ithread writer thread index */ - void closeFile(int i = 0); + void closeFile(int ithread = 0); private: /************************************************************************* @@ -444,16 +445,18 @@ private: /** * Updates the file header char aray, each time the corresp parameter is changed + * @param ithread writer thread index */ - void updateFileHeader(); + void updateFileHeader(int ithread); /** * Called by handleWithoutDataCompression and handleWithCompression after writing to file * Copy frames for GUI and updates appropriate parameters for frequency frames to gui * Uses semaphore for nth frame mode + * @param ithread writer thread index * @param buffer buffer to copy */ - void copyFrameToGui(char* buffer[]); + void copyFrameToGui(int ithread, char* buffer[]); void processWritingBuffer(int ithread); @@ -526,9 +529,6 @@ private: /** Complete File name */ char completeFileName[MAX_NUMBER_OF_WRITER_THREADS][MAX_STR_LENGTH]; - /** File Prefix with detector index */ - char receiverFilePrefix[MAX_NUMBER_OF_WRITER_THREADS][MAX_STR_LENGTH]; - /** Maximum Packets Per File **/ int maxPacketsPerFile; @@ -542,10 +542,10 @@ private: //***acquisition indices/count parameters*** /** Frame Number of First Frame of an entire Acquisition (including all scans) */ - uint64_t startAcquisitionIndex[MAX_NUMBER_OF_LISTENING_THREADS]; + uint64_t startAcquisitionIndex; /** Frame index at start of each real time acquisition (eg. for each scan) */ - uint64_t startFrameIndex[MAX_NUMBER_OF_LISTENING_THREADS]; + uint64_t startFrameIndex[MAX_NUMBER_OF_WRITER_THREADS]; /** Actual current frame index of each time acquisition (eg. for each scan) */ uint64_t frameIndex[MAX_NUMBER_OF_WRITER_THREADS]; @@ -564,8 +564,8 @@ private: /* Acquisition started */ bool acqStarted; - /* Measurement started */ - bool measurementStarted; + /* Measurement started - for each thread to get progress print outs*/ + bool measurementStarted[MAX_NUMBER_OF_LISTENING_THREADS]; /** Total Frame Count listened to by listening threads */ int totalListeningFrameCount[MAX_NUMBER_OF_LISTENING_THREADS]; @@ -582,6 +582,10 @@ private: /** Number of Missing Packets in file */ uint32_t numTotMissingPacketsInFile[MAX_NUMBER_OF_WRITER_THREADS]; + /** packets caught per thread */ + uint64_t packetsCaughtPerThread[MAX_NUMBER_OF_WRITER_THREADS]; + + @@ -720,6 +724,9 @@ private: /** Progress (currentFrameNumber) Mutex */ pthread_mutex_t progressMutex; + /** Progress (currentFrameNumber) Mutex */ + pthread_mutex_t udpSocketMutex[MAX_NUMBER_OF_LISTENING_THREADS]; + //***callback*** /** The action which decides what the user and default responsibilities to save data are * 0 raw data ready callback takes care of open,close,write file diff --git a/slsReceiverSoftware/src/UDPBaseImplementation.cpp b/slsReceiverSoftware/src/UDPBaseImplementation.cpp index a76cf0e9f..8168affa4 100644 --- a/slsReceiverSoftware/src/UDPBaseImplementation.cpp +++ b/slsReceiverSoftware/src/UDPBaseImplementation.cpp @@ -442,7 +442,7 @@ void UDPBaseImplementation::abort(){ FILE_LOG(logERROR) << __AT__ << " must be overridden by child classes"; } -void UDPBaseImplementation::closeFile(int i){ +void UDPBaseImplementation::closeFile(int ithread){ FILE_LOG(logWARNING) << __AT__ << " doing nothing..."; FILE_LOG(logERROR) << __AT__ << " must be overridden by child classes"; } diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 92e4e9636..96c81f465 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -38,6 +38,8 @@ UDPStandardImplementation::UDPStandardImplementation(){ pthread_mutex_init(&writeMutex,NULL); pthread_mutex_init(&dataReadyMutex,NULL); pthread_mutex_init(&progressMutex,NULL); + for(int i=0;iShutDownSocket(); FILE_LOG(logINFO) << "Shut down UDP Socket " << i; delete udpSocket[i]; udpSocket[i] = NULL; + pthread_mutex_unlock(&udpSocketMutex[i]); } } return OK; @@ -1051,25 +1052,25 @@ void UDPStandardImplementation::startReadout(){ /**make this better by asking all of it at once*/ -void UDPStandardImplementation::readFrame(int wThread, char* c,char** raw, uint64_t &startAcq, uint64_t &startFrame){ +void UDPStandardImplementation::readFrame(int ithread, char* c,char** raw, uint64_t &startAcq, uint64_t &startFrame){ FILE_LOG(logDEBUG) << __AT__ << " called"; //point to gui data, to let writer thread know that gui is back for data - if (guiData[wThread] == NULL){ - guiData[wThread] = latestData[wThread]; + if (guiData[ithread] == NULL){ + guiData[ithread] = latestData[ithread]; #ifdef DEBUG4 cprintf(CYAN,"Info: gui data not null anymore - ready to get data\n"); #endif } //copy data and filename - strcpy(c,guiFileName[wThread]); - startAcq = startAcquisitionIndex[wThread]; - startFrame = startFrameIndex[wThread]; + strcpy(c,guiFileName[ithread]); + startAcq = startAcquisitionIndex; + startFrame = startFrameIndex[ithread]; //gui data not copied yet - if(!guiDataReady[wThread]){ + if(!guiDataReady[ithread]){ #ifdef DEBUG4 cprintf(CYAN,"Info: gui data not ready\n"); #endif @@ -1081,8 +1082,8 @@ void UDPStandardImplementation::readFrame(int wThread, char* c,char** raw, uint6 #ifdef DEBUG4 cprintf(CYAN,"Info: gui data ready\n"); #endif - *raw = guiData[wThread]; - guiData[wThread] = NULL; + *raw = guiData[ithread]; + guiData[ithread] = NULL; //for nth frame to gui, post semaphore so writer stops waiting if((FrameToGuiFrequency) && (writerThreadsMask)){ @@ -1090,7 +1091,7 @@ void UDPStandardImplementation::readFrame(int wThread, char* c,char** raw, uint6 cprintf(CYAN,"Info: gonna post\n"); #endif //release after getting data - sem_post(&writerGuiSemaphore[wThread]); + sem_post(&writerGuiSemaphore[ithread]); } #ifdef DEBUG4 cprintf(CYAN,"Info: done post\n"); @@ -1101,53 +1102,53 @@ void UDPStandardImplementation::readFrame(int wThread, char* c,char** raw, uint6 -void UDPStandardImplementation::closeFile(int i){ - FILE_LOG(logDEBUG) << __AT__ << " called for " << i ; +void UDPStandardImplementation::closeFile(int ithread){ + FILE_LOG(logDEBUG) << __AT__ << " called for " << ithread ; //normal if(!dataCompressionEnable){ - if(sfilefd[i]){ + if(sfilefd[ithread]){ #ifdef DEBUG4 FILE_LOG(logDEBUG4) << "Going to close file: " << fileno(sfilefd)); #endif - fclose(sfilefd[i]); - sfilefd[i] = NULL; + fclose(sfilefd[ithread]); + sfilefd[ithread] = NULL; } } //compression else{ #if (defined(MYROOT1) && defined(ALLFILE_DEBUG)) || !defined(MYROOT1) - if(sfilefd[i]){ + if(sfilefd[0]){ #ifdef DEBUG4 FILE_LOG(logDEBUG4) << "sfield: " << (int)sfilefd[i]; #endif - fclose(sfilefd[i]); - sfilefd[i] = NULL; + fclose(sfilefd[0]); + sfilefd[0] = NULL; } #endif #ifdef MYROOT1 pthread_mutex_lock(&writeMutex); //write to file - if(myTree[i] && myFile[i]){ - myFile[i] = myTree[i]->GetCurrentFile(); + if(myTree[ithread] && myFile[ithread]){ + myFile[ithread] = myTree[ithread]->GetCurrentFile(); - if(myFile[i]->Write()) + if(myFile[ithread]->Write()) //->Write(tall->GetName(),TObject::kOverwrite); - cout << "Thread " << i <<": wrote frames to file" << endl; + cout << "Thread " << ithread <<": wrote frames to file" << endl; else - cout << "Thread " << i << ": could not write frames to file" << endl; + cout << "Thread " << ithread << ": could not write frames to file" << endl; }else - cout << "Thread " << i << ": could not write frames to file: No file or No Tree" << endl; + cout << "Thread " << ithread << ": could not write frames to file: No file or No Tree" << endl; //close file - if(myTree[i] && myFile[i]) - myFile[i] = myTree[i]->GetCurrentFile(); - if(myFile[i] != NULL) - myFile[i]->Close(); - myFile[i] = NULL; - myTree[i] = NULL; + if(myTree[ithread] && myFile[ithread]) + myFile[ithread] = myTree[ithread]->GetCurrentFile(); + if(myFile[ithread] != NULL) + myFile[ithread]->Close(); + myFile[ithread] = NULL; + myTree[ithread] = NULL; pthread_mutex_unlock(&writeMutex); #endif @@ -1363,7 +1364,8 @@ int UDPStandardImplementation::setupWriter(){ //acquisition start call back returns enable write cbAction = DO_EVERYTHING; if (startAcquisitionCallBack) - cbAction=startAcquisitionCallBack(filePath,fileName,(int)fileIndex,bufferSize,pStartAcquisition); + cbAction=startAcquisitionCallBack(filePath,fileName[0],(int)fileIndex,bufferSize,pStartAcquisition); + if(cbAction < DO_EVERYTHING){ FILE_LOG(logINFO) << "Call back activated. Data saving must be taken care of by user in call back."; @@ -1406,16 +1408,16 @@ int UDPStandardImplementation::createNewFile(int ithread){ FILE_LOG(logDEBUG) << __AT__ << " called"; int index = 0; - if(packetsCaught) + if(packetsCaughtPerThread[ithread]) index = frameIndex[ithread]; //create file name if(!frameIndexEnable) - sprintf(completeFileName[ithread], "%s/%s_%lld.raw", filePath,fileName,(long long int)fileIndex); + sprintf(completeFileName[ithread], "%s/%s_%lld.raw", filePath,fileName[ithread],(long long int)fileIndex); else if (myDetectorType == EIGER) - sprintf(completeFileName[ithread], "%s/%s_f%012lld_%lld.raw", filePath,fileName,(long long int)currentFrameNumber,(long long int)fileIndex); + sprintf(completeFileName[ithread], "%s/%s_f%012lld_%lld.raw", filePath,fileName[ithread],(long long int)currentFrameNumber[ithread],(long long int)fileIndex); else - sprintf(completeFileName[ithread], "%s/%s_f%012lld_%lld.raw", filePath,fileName,(long long int)(packetsCaught/packetsPerFrame),(long long int)fileIndex); + sprintf(completeFileName[ithread], "%s/%s_f%012lld_%lld.raw", filePath,fileName[ithread],(long long int)(packetsCaught[ithread]/packetsPerFrame),(long long int)fileIndex); #ifdef DEBUG4 FILE_LOG(logINFO) << completefileName; @@ -1425,54 +1427,56 @@ int UDPStandardImplementation::createNewFile(int ithread){ if(fileWriteEnable && cbAction > DO_NOTHING){ //close file pointers - if(sfilefd){ - fclose(sfilefd); - sfilefd = NULL; + if(sfilefd[ithread]){ + fclose(sfilefd[ithread]); + sfilefd[ithread] = NULL; } //create file if(!overwriteEnable){ - if (NULL == (sfilefd = fopen((const char *) (completeFileName), "wx"))){ - FILE_LOG(logERROR) << "Could not create/overwrite file" << completeFileName; + if (NULL == (sfilefd[ithread] = fopen((const char *) (completeFileName[ithread]), "wx"))){ + FILE_LOG(logERROR) << "Could not create/overwrite file" << completeFileName[ithread]; return FAIL; } - }else if (NULL == (sfilefd = fopen((const char *) (completeFileName), "w"))){ - FILE_LOG(logERROR) << "Could not create file" << completeFileName; + }else if (NULL == (sfilefd[ithread] = fopen((const char *) (completeFileName[ithread]), "w"))){ + FILE_LOG(logERROR) << "Could not create file" << completeFileName[ithread]; return FAIL; } //setting file buffer size to 16mb - setvbuf(sfilefd,NULL,_IOFBF,BUF_SIZE); + setvbuf(sfilefd[ithread],NULL,_IOFBF,BUF_SIZE); + //Print packet loss and filenames - if(!packetsCaught){ - previousFrameNumber = -1; - cout << "File: " << completeFileName << endl; + if(!packetsCaughtPerThread[ithread]){ + previousFrameNumber[ithread] = -1; + cout << "File: " << completeFileName[ithread] << endl; }else{ - if (previousFrameNumber == -1) - previousFrameNumber = startFrameIndex-1; + //Assumption for startFrameindex usign ithread: datacompression never enters here and therefore is always same number of listening and writing threads to use ithread + if (previousFrameNumber[ithread] == -1) + previousFrameNumber[ithread] = startFrameIndex[ithread]-1; - cout << completeFileName + cout << completeFileName[ithread] << "\tPacket Loss: " << setw(4)<initEventTree(temp, &iframe); //resets the pedestalSubtraction array and the commonModeSubtraction singlePhotonDetectorObject[ithread]->newDataSet(); @@ -1589,19 +1593,14 @@ void UDPStandardImplementation::startListening(){ rc = prepareAndListenBuffer(ithread, listenSize, carryonBufferSize, tempBuffer); //start indices for each start of scan/acquisition - if((!measurementStarted) && (rc > 0)){ - pthread_mutex_lock(&progressMutex); - if(!measurementStarted) - startFrameIndices(ithread); - pthread_mutex_unlock(&progressMutex); - } - - + if((!measurementStarted) && (rc > 0)) + startFrameIndices(ithread); //problem in receiving or end of acquisition if (status == TRANSMITTING){ stopListening(ithread,rc); continue; } + //write packet count to buffer if(myDetectorType == EIGER) (*((uint32_t*)(buffer[ithread]))) = 1; @@ -1653,10 +1652,14 @@ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int lSize, in if(cSize) memcpy(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS, temp, cSize); + pthread_mutex_lock(&udpSocketMutex[ithread]); int receivedSize = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS + cSize, lSize + cSize); - - //throw away packets that is not one packet size, need to check status if socket is shut down - while(status != TRANSMITTING && myDetectorType == EIGER && receivedSize != onePacketSize) { + //throw away packets that is not one packet size + while(myDetectorType == EIGER && receivedSize != onePacketSize) { + //need to check status if socket is shut down + if(status == TRANSMITTING) + break; + //print if(receivedSize != EIGER_HEADER_LENGTH){ cprintf(RED,"Listening_Thread %d: Listened to a weird packet size %d\n",ithread, receivedSize); } @@ -1664,8 +1667,11 @@ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int lSize, in else cprintf(BLUE,"Listening_Thread %d: Listened to a header packet\n",ithread); #endif + //listen again receivedSize = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS); } + pthread_mutex_unlock(&udpSocketMutex[ithread]); + totalListeningFrameCount[ithread] += (receivedSize/onePacketSize); #ifdef MANUALDEBUG @@ -1710,18 +1716,18 @@ void UDPStandardImplementation::startFrameIndices(int ithread){ jfrau_packet_header_t* header=0; switch(myDetectorType){ case EIGER: - startFrameIndex = 0; //frame number always resets + startFrameIndex[ithread] = 0; //frame number always resets break; case JUNGFRAU: header = (jfrau_packet_header_t*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS); - startFrameIndex = (*( (uint32_t*) header->frameNumber))&0xffffff; + startFrameIndex[ithread] = (*( (uint32_t*) header->frameNumber))&0xffffff; break; default: if(shortFrameEnable < 0){ - startFrameIndex = (((((uint32_t)(*((uint32_t*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS))))+1) + startFrameIndex[ithread] = (((((uint32_t)(*((uint32_t*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS))))+1) & (frameIndexMask)) >> frameIndexOffset); }else{ - startFrameIndex = ((((uint32_t)(*((uint32_t*)(buffer[ithread]+HEADER_SIZE_NUM_TOT_PACKETS)))) + startFrameIndex[ithread] = ((((uint32_t)(*((uint32_t*)(buffer[ithread]+HEADER_SIZE_NUM_TOT_PACKETS)))) & (frameIndexMask)) >> frameIndexOffset); } break; @@ -1729,14 +1735,16 @@ void UDPStandardImplementation::startFrameIndices(int ithread){ //start of entire acquisition if(!acqStarted){ - startAcquisitionIndex = startFrameIndex; + pthread_mutex_lock(&progressMutex); + startAcquisitionIndex = startFrameIndex[ithread]; acqStarted = true; + pthread_mutex_unlock(&progressMutex); cprintf(BLUE,"Listening_Thread %d: startAcquisitionIndex:%lld\n",ithread,(long long int)startAcquisitionIndex); } //set start of scan/real time measurement - cprintf(BLUE,"Listening_Thread %d: startFrameIndex: %lld\n", ithread,(long long int)startFrameIndex); - measurementStarted = true; + cprintf(BLUE,"Listening_Thread %d: startFrameIndex: %lld\n", ithread,(long long int)startFrameIndex[ithread]); + measurementStarted[ithread] = true; } @@ -2215,7 +2223,7 @@ void UDPStandardImplementation::processWritingBufferPacketByPacket(int ithread){ threadFrameNumber[i] = (uint32_t)(*( (uint64_t*) packetBuffer_footer)); //last frame read out lastFrameIndex = threadFrameNumber[i]; - threadFrameNumber[i] += (startFrameIndex - 1); + threadFrameNumber[i] += (startFrameIndex[ithread] - 1); //packet number currentPacketNumber[i] = *( (uint16_t*) packetBuffer_footer->packetNumber); @@ -2371,7 +2379,7 @@ void UDPStandardImplementation::processWritingBufferPacketByPacket(int ithread){ //ensuring last packet got is not of some other future frame but of the current one eiger_packet_footer_t* wbuf_footer1 = (eiger_packet_footer_t*)(packetBuffer[i] + footerOffset + HEADER_SIZE_NUM_TOT_PACKETS); - uint64_t packfnum = (((uint32_t)(*( (uint64_t*) wbuf_footer1)))+(startFrameIndex - 1)); + uint64_t packfnum = (((uint32_t)(*( (uint64_t*) wbuf_footer1)))+(startFrameIndex[ithread] - 1)); //to reset to get new frame: not dummy and the last packet if((numPackets[i] != dummyPacketValue) && (currentPacketNumber[i] == LAST_PACKET_VALUE) && (packfnum == currentFrameNumber) ) @@ -2460,13 +2468,27 @@ void UDPStandardImplementation::waitWritingBufferForNextAcquisition(int ithread) if((1< 1) pthread_mutex_lock(&writeMutex); packetsInFile += numpackets; + packetsCaughtPerThread[ithread] += (numpackets - numMissingPackets); + pthread_mutex_lock(&progressMutex); packetsCaught += (numpackets - numMissingPackets); + pthread_mutex_unlock(&progressMutex); totalPacketsCaught += (numpackets - numMissingPackets); numMissingPackets = 0; if(numberofWriterThreads > 1) pthread_mutex_unlock(&writeMutex); @@ -2906,7 +2934,7 @@ void UDPStandardImplementation::createHeaders(char* wbuffer[]){ } -void UDPStandardImplementation::updateFileHeader(){ +void UDPStandardImplementation::updateFileHeader(int ithread){ int xpix=-1,ypix=-1; //create detector specific packet header @@ -2934,10 +2962,10 @@ void UDPStandardImplementation::updateFileHeader(){ //update file header time_t t = time(0); - int length = sizeof(fileHeader); - while((unsigned int)length!=strlen(fileHeader)){ - length = strlen(fileHeader); - sprintf(fileHeader,"\nHeader\t\t %d bytes\n" + int length = sizeof(fileHeader[ithread]); + while((unsigned int)length!=strlen(fileHeader[ithread])){ + length = strlen(fileHeader[ithread]); + sprintf(fileHeader[ithread],"\nHeader\t\t %d bytes\n" "Dynamic Range\t %d\n" "Packet\t\t %d bytes\n" "x\t\t %d pixels\n" @@ -3037,7 +3065,7 @@ void UDPStandardImplementation::handleDataCompression(int ithread, char* wbuffer pthread_mutex_unlock(&progressMutex); //set indices acquisitionIndex = currentFrameNumber - startAcquisitionIndex; - frameIndex = currentFrameNumber - startFrameIndex; + frameIndex = currentFrameNumber - startFrameIndex[0]; //variable definitions @@ -3123,6 +3151,7 @@ void UDPStandardImplementation::handleDataCompression(int ithread, char* wbuffer #ifndef ALLFILE pthread_mutex_lock(&progressMutex); packetsInFile += packetsPerFrame; + packetsCaughtPerThread[0] += packetsPerFrame; packetsCaught += packetsPerFrame; totalPacketsCaught += packetsPerFrame; if(packetsInFile >= (uint32_t)maxPacketsPerFile) diff --git a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp index 1e2b5c49e..a07c4c284 100644 --- a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp +++ b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp @@ -370,6 +370,7 @@ int slsReceiverTCPIPInterface::set_detector_type(){ } if(ret != FAIL){ #ifndef REST + if(receiverBase) delete receiverBase; receiverBase = UDPInterface::create("standard"); if(startAcquisitionCallBack) receiverBase->registerCallBackStartAcquisition(startAcquisitionCallBack,pStartAcquisition); @@ -998,6 +999,10 @@ int slsReceiverTCPIPInterface::reset_frames_caught(){ strcpy(mess,SET_RECEIVER_ERR_MESSAGE); ret=FAIL; } + else if(receiverBase->getStatus()==RUNNING){ + strcpy(mess,"Cannot reset frames caught while status is running\n"); + ret=FAIL; + } else receiverBase->resetAcquisitionCount(); } From e9b7a11cf6ff3f0261ffa04818128b6110cbe655 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Wed, 24 Aug 2016 16:23:43 +0200 Subject: [PATCH 232/474] in between --- .../include/UDPStandardImplementation.h | 21 +- .../src/UDPStandardImplementation.cpp | 245 ++++++++---------- 2 files changed, 122 insertions(+), 144 deletions(-) diff --git a/slsReceiverSoftware/include/UDPStandardImplementation.h b/slsReceiverSoftware/include/UDPStandardImplementation.h index 4be649189..587b88dbd 100644 --- a/slsReceiverSoftware/include/UDPStandardImplementation.h +++ b/slsReceiverSoftware/include/UDPStandardImplementation.h @@ -348,12 +348,11 @@ private: * Also copies carryovers from previous frame in front of buffer (gotthard and moench) * For eiger, it ignores packets less than onePacketSize * @param ithread listening thread index - * @param lSize number of bytes to listen to * @param cSize number of bytes carried on from previous buffer * @param temp temporary storage of previous buffer * @return the number of bytes actually received */ - int prepareAndListenBuffer(int ithread, int lSize, int cSize, char* temp); + int prepareAndListenBuffer(int ithread, int cSize, char* temp); /** * Called by startListening @@ -380,9 +379,10 @@ private: * @param ithread listening thread index * @param cSize number of bytes carried over to the next buffer to reunite with split frame * @param temp temporary buffer to store the split frame + * @param rc number of bytes received * @return packet count */ - uint32_t processListeningBuffer(int ithread, int cSize,char* temp); + uint32_t processListeningBuffer(int ithread, int &cSize,char* temp, int rc); /** * Thread started which writes packets to file. @@ -415,7 +415,7 @@ private: * @param ithread writing thread index * @param wbuffer writing buffer popped out from FIFO */ - void stopWriting(int ithread, char* wbuffer[]); + void stopWriting(int ithread, char* wbuffer); /** * Called by processWritingBuffer and processWritingBufferPacketByPacket @@ -425,7 +425,7 @@ private: * @param wbuffer writing buffer popped out from FIFO * @param npackets number of packets */ - void handleWithoutDataCompression(int ithread, char* wbuffer[],uint32_t npackets); + void handleWithoutDataCompression(int ithread, char* wbuffer,uint32_t npackets); /** * Calle by handleWithoutDataCompression @@ -492,9 +492,6 @@ private: #endif //**detector parameters*** - /** Size of 1 Frame including headers */ - int frameSize; - /** Size of 1 buffer processed at a time */ int bufferSize; @@ -529,8 +526,8 @@ private: /** Complete File name */ char completeFileName[MAX_NUMBER_OF_WRITER_THREADS][MAX_STR_LENGTH]; - /** Maximum Packets Per File **/ - int maxPacketsPerFile; + /** Maximum Frames Per File **/ + int maxFramesPerFile; /** If file created successfully for all Writer Threads */ bool fileCreateSuccess; @@ -545,7 +542,7 @@ private: uint64_t startAcquisitionIndex; /** Frame index at start of each real time acquisition (eg. for each scan) */ - uint64_t startFrameIndex[MAX_NUMBER_OF_WRITER_THREADS]; + uint64_t startFrameIndex; /** Actual current frame index of each time acquisition (eg. for each scan) */ uint64_t frameIndex[MAX_NUMBER_OF_WRITER_THREADS]; @@ -577,7 +574,7 @@ private: uint32_t numMissingPackets[MAX_NUMBER_OF_WRITER_THREADS]; /** Total Number of Missing Packets in acquisition*/ - uint32_t numTotMissingPackets[MAX_NUMBER_OF_WRITER_THREADS]; + uint32_t numTotMissingPackets; /** Number of Missing Packets in file */ uint32_t numTotMissingPacketsInFile[MAX_NUMBER_OF_WRITER_THREADS]; diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 96c81f465..62da115d3 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -128,7 +128,6 @@ void UDPStandardImplementation::initializeMembers(){ FILE_LOG(logDEBUG) << "Info: Initializing members"; //***detector parameters*** - frameSize = 0; bufferSize = 0; onePacketSize = 0; oneDataSize = 0; @@ -149,18 +148,18 @@ void UDPStandardImplementation::initializeMembers(){ strcpy(fileHeader[i],""); sfilefd[i] = NULL; } - maxPacketsPerFile = 0; + maxFramesPerFile = 0; fileCreateSuccess = false; //***acquisition indices parameters*** startAcquisitionIndex = 0; acqStarted = false; + startFrameIndex = 0; for(int i = 0; i < MAX_NUMBER_OF_LISTENING_THREADS; ++i){ - startFrameIndex[i] = 0; measurementStarted[i] = false; totalListeningFrameCount[i] = 0; } - + numTotMissingPackets = 0; for(int i=0; i 1 numberofJobsPerBuffer if(fifoSize % numberofJobsPerBuffer) @@ -338,10 +333,8 @@ int UDPStandardImplementation::setupFifoStructure(){ fifoFree[i]->pop(buffer[i]); //cprintf(BLUE,"FifoFree[%d]: value:%d, pop 0x%x\n",i,fifoFree[i]->getSemValue(),(void*)(buffer[i])); } -#ifdef DEBUG5 - cprintf(BLUE,"Info: %d fifostructure popped from fifofree %p\n", i, (void*)(buffer[i])); -#endif delete fifoFree[i]; + fifoFree[i] = NULL; } if(fifo[i]){ while(!fifo[i]->isEmpty()){ @@ -349,8 +342,12 @@ int UDPStandardImplementation::setupFifoStructure(){ //cprintf(CYAN,"Fifo[%d]: value:%d, pop 0x%x\n",i,fifo[i]->getSemValue(),(void*)(buffer[i])); } delete fifo[i]; + fifo[i] = NULL; + } + if(mem0[i]){ + free(mem0[i]); + mem0[i] = NULL; } - if(mem0[i]) free(mem0[i]); //creating fifoFree[i] = new CircularFifo(fifoSize); @@ -469,22 +466,20 @@ void UDPStandardImplementation::setShortFrameEnable(const int i){ shortFrameEnable = i; if(shortFrameEnable!=-1){ - frameSize = GOTTHARD_SHORT_BUFFER_SIZE; bufferSize = GOTTHARD_SHORT_BUFFER_SIZE; onePacketSize = GOTTHARD_SHORT_BUFFER_SIZE; oneDataSize = GOTTHARD_SHORT_DATABYTES; - maxPacketsPerFile = SHORT_MAX_FRAMES_PER_FILE * GOTTHARD_SHORT_PACKETS_PER_FRAME; + maxFramesPerFile = SHORT_MAX_FRAMES_PER_FILE; packetsPerFrame = GOTTHARD_SHORT_PACKETS_PER_FRAME; frameIndexMask = GOTTHARD_SHORT_FRAME_INDEX_MASK; frameIndexOffset = GOTTHARD_SHORT_FRAME_INDEX_OFFSET; packetIndexMask = GOTTHARD_SHORT_PACKET_INDEX_MASK; }else{ - frameSize = GOTTHARD_BUFFER_SIZE; bufferSize = GOTTHARD_BUFFER_SIZE; onePacketSize = GOTTHARD_ONE_PACKET_SIZE; oneDataSize = GOTTHARD_ONE_DATA_SIZE; - maxPacketsPerFile = MAX_FRAMES_PER_FILE * GOTTHARD_PACKETS_PER_FRAME; + maxFramesPerFile = MAX_FRAMES_PER_FILE; packetsPerFrame = GOTTHARD_PACKETS_PER_FRAME; frameIndexMask = GOTTHARD_FRAME_INDEX_MASK; frameIndexOffset = GOTTHARD_FRAME_INDEX_OFFSET; @@ -517,9 +512,8 @@ int UDPStandardImplementation::setAcquisitionPeriod(const uint64_t i){ FILE_LOG(logDEBUG) << __AT__ << " called"; acquisitionPeriod = i; - if((myDetectorType == GOTTHARD) && (myDetectorType == MOENCH)) - if(setupFifoStructure() == FAIL) - return FAIL; + if(setupFifoStructure() == FAIL) + return FAIL; FILE_LOG(logINFO) << "Acquisition Period: " << (double)acquisitionPeriod/(1E9) << "s"; @@ -531,9 +525,8 @@ int UDPStandardImplementation::setNumberOfFrames(const uint64_t i){ FILE_LOG(logDEBUG) << __AT__ << " called"; numberOfFrames = i; - if((myDetectorType == GOTTHARD) && (myDetectorType == MOENCH)) - if(setupFifoStructure() == FAIL) - return FAIL; + if(setupFifoStructure() == FAIL) + return FAIL; FILE_LOG(logINFO) << "Number of Frames:" << numberOfFrames; @@ -551,12 +544,11 @@ int UDPStandardImplementation::setDynamicRange(const uint32_t i){ if(myDetectorType == EIGER){ //set parameters depending on new dynamic range. - packetsPerFrame = (tengigaEnable ? EIGER_TEN_GIGA_CONSTANT : EIGER_ONE_GIGA_CONSTANT) - * dynamicRange * EIGER_MAX_PORTS; - frameSize = onePacketSize * packetsPerFrame; - maxPacketsPerFile = EIGER_MAX_FRAMES_PER_FILE * packetsPerFrame; + packetsPerFrame = (tengigaEnable ? EIGER_TEN_GIGA_CONSTANT : EIGER_ONE_GIGA_CONSTANT) * dynamicRange; + bufferSize = onePacketSize * packetsPerFrame; - updateFileHeader(); + for(int i=0; i 0)) @@ -1603,10 +1589,10 @@ void UDPStandardImplementation::startListening(){ //write packet count to buffer if(myDetectorType == EIGER) - (*((uint32_t*)(buffer[ithread]))) = 1; - //handling split frames and writing packet Count to buffer - else - (*((uint32_t*)(buffer[ithread]))) = processListeningBuffer(ithread, carryonBufferSize, tempBuffer); + (*((uint32_t*)(buffer[ithread]))) = rc/onePacketSize; + + if(dataCompressionEnable) + (*((uint32_t*)(buffer[ithread]))) = processListeningBuffer(ithread, carryonBufferSize, tempBuffer, rc); //push buffer to FIFO @@ -1645,24 +1631,17 @@ void UDPStandardImplementation::startListening(){ -int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int lSize, int cSize, char* temp){ +int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int cSize, char* temp){ FILE_LOG(logDEBUG) << __AT__ << " called"; - //listen to UDP packets - if(cSize) - memcpy(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS, temp, cSize); + //carry over from previous buffer + if(cSize) memcpy(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS, temp, cSize); - pthread_mutex_lock(&udpSocketMutex[ithread]); - int receivedSize = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS + cSize, lSize + cSize); + int receivedSize = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS + cSize, (bufferSize * numberofJobsPerBuffer) - cSize); //throw away packets that is not one packet size while(myDetectorType == EIGER && receivedSize != onePacketSize) { - //need to check status if socket is shut down - if(status == TRANSMITTING) - break; - //print - if(receivedSize != EIGER_HEADER_LENGTH){ + if(receivedSize != EIGER_HEADER_LENGTH) cprintf(RED,"Listening_Thread %d: Listened to a weird packet size %d\n",ithread, receivedSize); - } #ifdef DEBUG else cprintf(BLUE,"Listening_Thread %d: Listened to a header packet\n",ithread); @@ -1670,7 +1649,6 @@ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int lSize, in //listen again receivedSize = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS); } - pthread_mutex_unlock(&udpSocketMutex[ithread]); totalListeningFrameCount[ithread] += (receivedSize/onePacketSize); @@ -1696,8 +1674,6 @@ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int lSize, in } } #endif - - #ifdef DEBUG cprintf(BLUE, "Listening_Thread %d : Received bytes: %d. Expected bytes: %d\n", ithread, receivedSize, bufferSize * numberofJobsPerBuffer-cSize); #endif @@ -1716,18 +1692,18 @@ void UDPStandardImplementation::startFrameIndices(int ithread){ jfrau_packet_header_t* header=0; switch(myDetectorType){ case EIGER: - startFrameIndex[ithread] = 0; //frame number always resets + startFrameIndex = 0; //frame number always resets break; case JUNGFRAU: header = (jfrau_packet_header_t*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS); - startFrameIndex[ithread] = (*( (uint32_t*) header->frameNumber))&0xffffff; + startFrameIndex = (*( (uint32_t*) header->frameNumber))&0xffffff; break; default: if(shortFrameEnable < 0){ - startFrameIndex[ithread] = (((((uint32_t)(*((uint32_t*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS))))+1) + startFrameIndex = (((((uint32_t)(*((uint32_t*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS))))+1) & (frameIndexMask)) >> frameIndexOffset); }else{ - startFrameIndex[ithread] = ((((uint32_t)(*((uint32_t*)(buffer[ithread]+HEADER_SIZE_NUM_TOT_PACKETS)))) + startFrameIndex = ((((uint32_t)(*((uint32_t*)(buffer[ithread]+HEADER_SIZE_NUM_TOT_PACKETS)))) & (frameIndexMask)) >> frameIndexOffset); } break; @@ -1736,14 +1712,14 @@ void UDPStandardImplementation::startFrameIndices(int ithread){ //start of entire acquisition if(!acqStarted){ pthread_mutex_lock(&progressMutex); - startAcquisitionIndex = startFrameIndex[ithread]; + startAcquisitionIndex = startFrameIndex; acqStarted = true; pthread_mutex_unlock(&progressMutex); cprintf(BLUE,"Listening_Thread %d: startAcquisitionIndex:%lld\n",ithread,(long long int)startAcquisitionIndex); } //set start of scan/real time measurement - cprintf(BLUE,"Listening_Thread %d: startFrameIndex: %lld\n", ithread,(long long int)startFrameIndex[ithread]); + cprintf(BLUE,"Listening_Thread %d: startFrameIndex: %lld\n", ithread,(long long int)startFrameIndex); measurementStarted[ithread] = true; } @@ -1863,13 +1839,13 @@ void UDPStandardImplementation::stopListening(int ithread, int numbytes){ -uint32_t UDPStandardImplementation::processListeningBuffer(int ithread, int cSize, char* temp){ +uint32_t UDPStandardImplementation::processListeningBuffer(int ithread, int &cSize, char* temp, int rc){ FILE_LOG(logDEBUG) << __AT__ << " called"; int lastPacketOffset; //the offset of the last packet uint32_t lastFrameHeader; //frame number of last packet in buffer uint64_t lastFrameHeader64; //frame number of last packet in buffer - uint32_t packetCount = (packetsPerFrame/numberofListeningThreads) * numberofJobsPerBuffer; //packets received + uint32_t packetCount = rc;//(packetsPerFrame/numberofListeningThreads) * numberofJobsPerBuffer; //packets received cSize = 0; //reset size jfrau_packet_header_t* header; @@ -2012,9 +1988,10 @@ void UDPStandardImplementation::processWritingBuffer(int ithread){ FILE_LOG(logDEBUG) << __AT__ << " called"; //variable definitions - char* wbuf[numberofListeningThreads]; //buffer popped from FIFO - sfilefd = NULL; //file pointer - uint64_t nf; //for compression, number of frames + char* wbuf; //buffer popped from FIFO + sfilefd[ithread] = NULL; //file pointer + uint64_t nf; //for compression, number of frames + int listenfifoIndex = ithread; /* outer loop - loops once for each acquisition */ @@ -2023,31 +2000,33 @@ void UDPStandardImplementation::processWritingBuffer(int ithread){ //--reset parameters before acquisition nf = 0; - guiData = latestData; //so that the first frame is always copied + guiData[ithread] = latestData[ithread]; //so that the first frame is always copied + if(dataCompressionEnable) + listenfifoIndex = 0; //compression has only one listening thread /* inner loop - loop for each buffer */ //until mask unset (udp sockets shut down by client) while((1 << ithread) & writerThreadsMask){ //pop - fifo[0]->pop(wbuf[0]); + fifo[listenfifoIndex]->pop(wbuf); #ifdef EVERYFIFODEBUG - if(fifo[0]->getSemValue()>(fifoSize-100)) - cprintf(CYAN,"Fifo[%d]: value:%d, pop 0x%x\n",0,fifo[0]->getSemValue(),(void*)(wbuf[0])); + if(fifo[listenfifoIndex]->getSemValue()>(fifoSize-100)) + cprintf(CYAN,"Fifo[%d]: value:%d, pop 0x%x\n",listenfifoIndex,fifo[listenfifoIndex]->getSemValue(),(void*)(wbuf)); #endif -#ifdef DEBUG5 - cprintf(GREEN,"Writing_Thread %d: Popped %p from FIFO %d\n", ithread, (void*)(wbuf[0]),0); -#endif - uint32_t numPackets = (uint32_t)(*((uint32_t*)wbuf[0])); #ifdef DEBUG4 - cprintf(GREEN,"Writing_Thread %d: Number of Packets: %d for FIFO %d\n", ithread, numPackets, 0); + cprintf(GREEN,"Writing_Thread %d: Popped %p from FIFO %d\n", ithread, (void*)(wbuf),listenfifoIndex); +#endif + uint32_t numPackets = (uint32_t)(*((uint32_t*)wbuf)); +#ifdef DEBUG4 + cprintf(GREEN,"Writing_Thread %d: Number of Packets: %d for FIFO %d\n", ithread, numPackets, listenfifoIndex); #endif //end of acquisition if(numPackets == dummyPacketValue){ -#ifdef DEBUG3 - cprintf(GREEN,"Writing_Thread %d: Dummy frame popped out of FIFO %d",ithread, 0); +#ifdef DEBUG4 + cprintf(GREEN,"Writing_Thread %d: Dummy frame popped out of FIFO %d",ithread, listenfifoIndex); #endif stopWriting(ithread,wbuf); continue; @@ -2055,9 +2034,11 @@ void UDPStandardImplementation::processWritingBuffer(int ithread){ - //process + //normal if(!dataCompressionEnable) handleWithoutDataCompression(ithread, wbuf, numPackets); + + //compression else{ #if defined(MYROOT1) && defined(ALLFILE_DEBUG) if(npackets > 0) @@ -2145,12 +2126,13 @@ void UDPStandardImplementation::processWritingBufferPacketByPacket(int ithread){ #endif } delete fifoTempFree[i]; + fifoTempFree[i] = NULL; } fifoTempFree[i] = new CircularFifo(MAX_NUM_PACKETS); } for(uint32_t i=0; ipacketNumber); @@ -2338,7 +2320,7 @@ void UDPStandardImplementation::processWritingBufferPacketByPacket(int ithread){ if(fullframe[0] && fullframe[1]){ currentFrameNumber = presentFrameNumber; numTotMissingPacketsInFile += numMissingPackets; - numTotMissingPackets += numMissingPackets; + numTotMissingPackets += numMissingPackets;/**requires a lock*/ /* cprintf(CYAN,"**framenum:%lld\n ",(long long int)currentFrameNumber); @@ -2379,7 +2361,7 @@ void UDPStandardImplementation::processWritingBufferPacketByPacket(int ithread){ //ensuring last packet got is not of some other future frame but of the current one eiger_packet_footer_t* wbuf_footer1 = (eiger_packet_footer_t*)(packetBuffer[i] + footerOffset + HEADER_SIZE_NUM_TOT_PACKETS); - uint64_t packfnum = (((uint32_t)(*( (uint64_t*) wbuf_footer1)))+(startFrameIndex[ithread] - 1)); + uint64_t packfnum = (((uint32_t)(*( (uint64_t*) wbuf_footer1)))+(startFrameIndex - 1)); //to reset to get new frame: not dummy and the last packet if((numPackets[i] != dummyPacketValue) && (currentPacketNumber[i] == LAST_PACKET_VALUE) && (packfnum == currentFrameNumber) ) @@ -2592,25 +2574,24 @@ bool UDPStandardImplementation::popAndCheckEndofAcquisition(int ithread, char* w -void UDPStandardImplementation::stopWriting(int ithread, char* wbuffer[]){ +void UDPStandardImplementation::stopWriting(int ithread, char* wbuffer){ FILE_LOG(logDEBUG) << __AT__ << " called"; FILE_LOG(logINFO) << "Writing "<< ithread << ": End of Acquisition"; //free fifo - for(int i=0; ipush(wbuffer[i])); + while(!fifoFree[ithread]->push(wbuffer)); #ifdef EVERYFIFODEBUG - if(fifoFree[i]->getSemValue()<100) - cprintf(GREEN,"FifoFree[%d]: value:%d, push 0x%x\n",i,fifoFree[i]->getSemValue(),(void*)(wbuffer[i])); + if(fifoFree[ithread]->getSemValue()<100) + cprintf(GREEN,"FifoFree[%d]: value:%d, push 0x%x\n",ithread,fifoFree[ithread]->getSemValue(),(void*)(wbuffer)); #endif #ifdef CFIFODEBUG - if(i==0) - cprintf(CYAN,"Writing_Thread %d: Freeing dummy-end buffer. Pushed into fifofree %p for listener %d\n", ithread,(void*)(wbuffer[i]),i); - else - cprintf(YELLOW,"Writing_Thread %d: Freeing dummy-end buffer. Pushed into fifofree %p for listener %d\n", ithread,(void*)(wbuffer[i]),i); + if(ithread==0) + cprintf(CYAN,"Writing_Thread %d: Freeing dummy-end buffer. Pushed into fifofree %p for listener %d\n", ithread,(void*)(wbuffer),ithread); + else + cprintf(YELLOW,"Writing_Thread %d: Freeing dummy-end buffer. Pushed into fifofree %p for listener %d\n", ithread,(void*)(wbuffer),ithread); #endif - } + //all threads need to close file, reset mask and exit loop closeFile(ithread); @@ -2644,7 +2625,7 @@ void UDPStandardImplementation::stopWriting(int ithread, char* wbuffer[]){ //statistics FILE_LOG(logINFO) << "Status: Run Finished"; - FILE_LOG(logINFO) << "Last Frame Number Caught:" << lastFrameIndex; + FILE_LOG(logINFO) << "Last Frame Number Caught:" << lastFrameIndex[ithread]; if(totalPacketsCaught < ((uint64_t)numberOfFrames*packetsPerFrame)){ cprintf(RED, "Total Missing Packets padded: %d\n",numTotMissingPackets); cprintf(RED, "Total Packets Caught: %lld\n",(long long int)totalPacketsCaught); @@ -2663,7 +2644,7 @@ void UDPStandardImplementation::stopWriting(int ithread, char* wbuffer[]){ -void UDPStandardImplementation::handleWithoutDataCompression(int ithread, char* wbuffer[],uint32_t npackets){ +void UDPStandardImplementation::handleWithoutDataCompression(int ithread, char* wbuffer,uint32_t npackets){ FILE_LOG(logDEBUG) << __AT__ << " called"; @@ -2682,7 +2663,7 @@ void UDPStandardImplementation::handleWithoutDataCompression(int ithread, char* } //set indices acquisitionIndex = currentFrameNumber - startAcquisitionIndex; - frameIndex = currentFrameNumber - startFrameIndex[ithread]; + frameIndex = currentFrameNumber - startFrameIndex; } @@ -2774,7 +2755,7 @@ void UDPStandardImplementation::writeFileWithoutCompression(int ithread, char* w //set indices acquisitionIndex = currentFrameNumber - startAcquisitionIndex; - frameIndex = currentFrameNumber - startFrameIndex[ithread]; + frameIndex = currentFrameNumber - startFrameIndex; } #ifdef DEBUG3 cprintf(GREEN,"Writing_Thread: Current Frame Number:%d\n",currentFrameNumber); @@ -3065,7 +3046,7 @@ void UDPStandardImplementation::handleDataCompression(int ithread, char* wbuffer pthread_mutex_unlock(&progressMutex); //set indices acquisitionIndex = currentFrameNumber - startAcquisitionIndex; - frameIndex = currentFrameNumber - startFrameIndex[0]; + frameIndex = currentFrameNumber - startFrameIndex; //variable definitions From be2bc15ab5c5e26adb72275610900e206e9cba5b Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 30 Aug 2016 16:10:46 +0200 Subject: [PATCH 233/474] not done --- .../include/UDPBaseImplementation.h | 2 +- .../include/UDPStandardImplementation.h | 89 +- slsReceiverSoftware/include/genericSocket.h | 24 +- slsReceiverSoftware/include/receiver_defs.h | 2 +- .../src/UDPStandardImplementation.cpp | 1224 ++++++----------- .../src/slsReceiverTCPIPInterface.cpp | 5 +- 6 files changed, 505 insertions(+), 841 deletions(-) diff --git a/slsReceiverSoftware/include/UDPBaseImplementation.h b/slsReceiverSoftware/include/UDPBaseImplementation.h index f9c5e9273..6083b0723 100644 --- a/slsReceiverSoftware/include/UDPBaseImplementation.h +++ b/slsReceiverSoftware/include/UDPBaseImplementation.h @@ -513,7 +513,7 @@ class UDPBaseImplementation : protected virtual slsReceiverDefs, public UDPInter //***acquisition count parameters*** /** Total packets caught for an entire acquisition (including all scans) */ uint64_t totalPacketsCaught; - /** Frames Caught for each real time acquisition (eg. for each scan) */ + /** Packets Caught for each real time acquisition (eg. for each scan) */ uint64_t packetsCaught; //***acquisition indices parameters*** diff --git a/slsReceiverSoftware/include/UDPStandardImplementation.h b/slsReceiverSoftware/include/UDPStandardImplementation.h index 587b88dbd..fcec7fc0d 100644 --- a/slsReceiverSoftware/include/UDPStandardImplementation.h +++ b/slsReceiverSoftware/include/UDPStandardImplementation.h @@ -78,6 +78,19 @@ class UDPStandardImplementation: private virtual slsReceiverDefs, public UDPBase */ int setDataCompressionEnable(const bool b); + //***acquisition count parameters*** + /** + * Get Total Frames Caught for an entire acquisition (including all scans) + * @return total number of frames caught for entire acquisition + */ + uint64_t getTotalFramesCaught() const; + + /** + * Get Frames Caught for each real time acquisition (eg. for each scan) + * @return number of frames caught for each scan + */ + uint64_t getFramesCaught() const; + //***acquisition parameters*** /** * Overridden method @@ -394,18 +407,6 @@ private: */ void startWriting(); - /** - * Called by processWritingBuffer and processWritingBufferPacketByPacket - * Pops buffer from all the FIFOs and checks for dummy frames and end of acquisition - * @param ithread current thread index - * @param wbuffer the buffer array that is popped from all the FIFOs - * @param ready if that FIFO is allowed to pop (depends on if dummy buffer already popped/ waiting for other FIFO to finish a frame(eiger)) - * @param nP number of packets in the buffer popped out - * @param fifoTempFree circular fifo to save addresses of packets adding upto a frame before pushing into fifofree (eiger specific) - * @return true if end of acquisition else false - */ - bool popAndCheckEndofAcquisition(int ithread, char* wbuffer[], bool ready[], uint32_t nP[],CircularFifo* fifoTempFree[]); - /** * Called by processWritingBuffer and processWritingBufferPacketByPacket * When dummy-end buffers are popped from all FIFOs (acquisition over), this is called @@ -434,14 +435,14 @@ private: * @param wbuffer is the address of buffer popped out of FIFO * @param numpackets is the number of packets */ - void writeFileWithoutCompression(int ithread, char* wbuffer[],uint32_t numpackets); + void writeFileWithoutCompression(int ithread, char* wbuffer,uint32_t numpackets); /** * Called by writeToFileWithoutCompression * Create headers for file writing (at the moment, this is eiger specific) * @param wbuffer writing buffer popped from FIFOs */ - void createHeaders(char* wbuffer[]); + void createHeaders(char* wbuffer); /** * Updates the file header char aray, each time the corresp parameter is changed @@ -456,11 +457,7 @@ private: * @param ithread writer thread index * @param buffer buffer to copy */ - void copyFrameToGui(int ithread, char* buffer[]); - - void processWritingBuffer(int ithread); - - void processWritingBufferPacketByPacket(int ithread); + void copyFrameToGui(int ithread, char* buffer); void waitWritingBufferForNextAcquisition(int ithread); @@ -473,10 +470,28 @@ private: * @param wbuffer writer buffer * @param nf number of frames */ - void handleDataCompression(int ithread, char* wbuffer[], uint64_t &nf); + void handleDataCompression(int ithread, char* wbuffer, uint64_t &nf); + /** + * Get Frame Number + * @param ithread writer thread index + * @param wbuffer writer buffer + * @param tempframenumber reference to the frame number + * @return OK or FAIL + */ + int getFrameNumber(int ithread, char* wbuffer, uint64_t &tempframenumber); + /** + * Find offset upto this frame number and write it to file + * @param ithread writer thread index + * @param wbuffer writer buffer + * @param offset reference of offset to look from and replaces offset to starting of nextframenumber + * @param nextFrameNumber frame number up to which data written + * @param numpackets number of packets in buffer + * @param numPacketsWritten number of packets written to file + */ + int writeUptoFrameNumber(int ithread, char* wbuffer, int &offset, uint64_t nextFrameNumber, uint32_t numpackets, int &numPacketsWritten); /************************************************************************* * Class Members ********************************************************* @@ -526,8 +541,11 @@ private: /** Complete File name */ char completeFileName[MAX_NUMBER_OF_WRITER_THREADS][MAX_STR_LENGTH]; + /** File Name without frame index, file index and extension (_d0_f000000000000_8.raw)*/ + char fileNamePerThread[MAX_NUMBER_OF_WRITER_THREADS][MAX_STR_LENGTH]; + /** Maximum Frames Per File **/ - int maxFramesPerFile; + uint64_t maxFramesPerFile; /** If file created successfully for all Writer Threads */ bool fileCreateSuccess; @@ -550,12 +568,12 @@ private: /** Current Frame Number */ uint64_t currentFrameNumber[MAX_NUMBER_OF_WRITER_THREADS]; - /** Previous Frame number from buffer to calculate loss */ - int64_t previousFrameNumber[MAX_NUMBER_OF_WRITER_THREADS]; + int64_t frameNumberInPreviousFile[MAX_NUMBER_OF_WRITER_THREADS]; /** Last Frame Index Listened To */ - int32_t lastFrameIndex[MAX_NUMBER_OF_WRITER_THREADS]; + int64_t lastFrameIndex[MAX_NUMBER_OF_WRITER_THREADS]; + /* Acquisition started */ @@ -564,25 +582,14 @@ private: /* Measurement started - for each thread to get progress print outs*/ bool measurementStarted[MAX_NUMBER_OF_LISTENING_THREADS]; - /** Total Frame Count listened to by listening threads */ - int totalListeningFrameCount[MAX_NUMBER_OF_LISTENING_THREADS]; + /** Total packet Count listened to by listening threads */ + int totalListeningPacketCount[MAX_NUMBER_OF_LISTENING_THREADS]; /** Pckets currently in current file, starts new file when it reaches max */ - uint32_t packetsInFile[MAX_NUMBER_OF_WRITER_THREADS]; - - /** Number of Missing Packets per buffer*/ - uint32_t numMissingPackets[MAX_NUMBER_OF_WRITER_THREADS]; - - /** Total Number of Missing Packets in acquisition*/ - uint32_t numTotMissingPackets; - - /** Number of Missing Packets in file */ - uint32_t numTotMissingPacketsInFile[MAX_NUMBER_OF_WRITER_THREADS]; - - /** packets caught per thread */ - uint64_t packetsCaughtPerThread[MAX_NUMBER_OF_WRITER_THREADS]; - + uint64_t lastFrameNumberInFile[MAX_NUMBER_OF_WRITER_THREADS]; + /** packets in current file */ + uint64_t totalPacketsInFile[MAX_NUMBER_OF_WRITER_THREADS]; @@ -721,8 +728,6 @@ private: /** Progress (currentFrameNumber) Mutex */ pthread_mutex_t progressMutex; - /** Progress (currentFrameNumber) Mutex */ - pthread_mutex_t udpSocketMutex[MAX_NUMBER_OF_LISTENING_THREADS]; //***callback*** /** The action which decides what the user and default responsibilities to save data are diff --git a/slsReceiverSoftware/include/genericSocket.h b/slsReceiverSoftware/include/genericSocket.h index 3facb0a2b..0f52c0413 100644 --- a/slsReceiverSoftware/include/genericSocket.h +++ b/slsReceiverSoftware/include/genericSocket.h @@ -613,25 +613,13 @@ enum communicationProtocol{ while(length>0){ nsending = (length>packet_size) ? packet_size:length; - /* - //created for debugging on 11.05.2015 - nsending=5000; - nsent = recvfrom(socketDescriptor,(char*)buf,nsending, 0, (struct sockaddr *) &clientAddress, &clientAddress_length); - if(nsent <1000){ - if(nsent < 48){ - cout << " "<fnum)<< "\t"; - cout << k <<" packets" << endl; - k = 0; - } - } - else - k++; - */ nsent = recvfrom(socketDescriptor,(char*)buf+total_sent,nsending, 0, (struct sockaddr *) &clientAddress, &clientAddress_length); - if(!nsent) break; + if(nsent < packet_size) { + if(nsent){ + cout << "Incomplete Packet size " << nsent << endl; + } + break; + } length-=nsent; total_sent+=nsent; } diff --git a/slsReceiverSoftware/include/receiver_defs.h b/slsReceiverSoftware/include/receiver_defs.h index 4c621a67f..0c60b892c 100755 --- a/slsReceiverSoftware/include/receiver_defs.h +++ b/slsReceiverSoftware/include/receiver_defs.h @@ -139,7 +139,7 @@ typedef struct { #define JFRAU_BUFFER_SIZE (JFRAU_ONE_PACKET_SIZE*JFRAU_PACKETS_PER_FRAME) //8214*128 -#define JFRAU_FRAME_INDEX_MASK 0x0 //Not Applicable, use struct +#define JFRAU_FRAME_INDEX_MASK 0xffffff //mask after using struct (48 bit) #define JFRAU_FRAME_INDEX_OFFSET 0x0 //Not Applicable, use struct #define JFRAU_PACKET_INDEX_MASK 0x0//Not Applicable, use struct diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 62da115d3..887b827a4 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -10,8 +10,6 @@ #include "gotthardModuleData.h" #include "gotthardShortModuleData.h" -#include "fileIOStatic.h" - #include // exit() #include //set precision for printing parameters for create new file #include //map @@ -38,8 +36,6 @@ UDPStandardImplementation::UDPStandardImplementation(){ pthread_mutex_init(&writeMutex,NULL); pthread_mutex_init(&dataReadyMutex,NULL); pthread_mutex_init(&progressMutex,NULL); - for(int i=0;iShutDownSocket(); FILE_LOG(logINFO) << "Shut down UDP Socket " << i; delete udpSocket[i]; udpSocket[i] = NULL; - pthread_mutex_unlock(&udpSocketMutex[i]); } } return OK; @@ -998,10 +1005,10 @@ void UDPStandardImplementation::startReadout(){ //check if all packets got int totalP = 0,prev,i; for(i=0; iinitEventTree(temp, &iframe); //resets the pedestalSubtraction array and the commonModeSubtraction singlePhotonDetectorObject[ithread]->newDataSet(); @@ -1564,20 +1570,16 @@ void UDPStandardImplementation::startListening(){ #endif - pthread_mutex_lock(&udpSocketMutex[ithread]); //udpsocket doesnt exist - if(udpSocket[ithread] == NULL){ + if(status == TRANSMITTING){ FILE_LOG(logERROR) << "Listening_Thread " << ithread << ": UDP Socket not created or shut down earlier"; stopListening(ithread,0); - pthread_mutex_unlock(&udpSocketMutex[ithread]); continue; } rc = prepareAndListenBuffer(ithread, carryonBufferSize, tempBuffer); carryonBufferSize = 0; - pthread_mutex_unlock(&udpSocketMutex[ithread]); - //start indices for each start of scan/acquisition if((!measurementStarted) && (rc > 0)) startFrameIndices(ithread); @@ -1589,7 +1591,7 @@ void UDPStandardImplementation::startListening(){ //write packet count to buffer if(myDetectorType == EIGER) - (*((uint32_t*)(buffer[ithread]))) = rc/onePacketSize; + (*((uint32_t*)(buffer[ithread]))) = (rc/onePacketSize); if(dataCompressionEnable) (*((uint32_t*)(buffer[ithread]))) = processListeningBuffer(ithread, carryonBufferSize, tempBuffer, rc); @@ -1634,12 +1636,18 @@ void UDPStandardImplementation::startListening(){ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int cSize, char* temp){ FILE_LOG(logDEBUG) << __AT__ << " called"; + int receivedSize = 0; + //carry over from previous buffer if(cSize) memcpy(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS, temp, cSize); - int receivedSize = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS + cSize, (bufferSize * numberofJobsPerBuffer) - cSize); + if(status != TRANSMITTING) + receivedSize = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS + cSize, (bufferSize * numberofJobsPerBuffer) - cSize); + //throw away packets that is not one packet size - while(myDetectorType == EIGER && receivedSize != onePacketSize) { + while((myDetectorType == EIGER) && + (receivedSize != ((bufferSize * numberofJobsPerBuffer) - cSize)) && + (status != TRANSMITTING)) { if(receivedSize != EIGER_HEADER_LENGTH) cprintf(RED,"Listening_Thread %d: Listened to a weird packet size %d\n",ithread, receivedSize); #ifdef DEBUG @@ -1647,10 +1655,12 @@ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int cSize, ch cprintf(BLUE,"Listening_Thread %d: Listened to a header packet\n",ithread); #endif //listen again - receivedSize = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS); + if(status != TRANSMITTING) + receivedSize = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS + cSize, (bufferSize * numberofJobsPerBuffer) - cSize); + //cout<0){ @@ -1761,7 +1771,7 @@ void UDPStandardImplementation::stopListening(int ithread, int numbytes){ //push last non empty buffer into fifo else{ (*((uint32_t*)(buffer[ithread]))) = numbytes/onePacketSize; - totalListeningFrameCount[ithread] += (numbytes/onePacketSize); + totalListeningPacketCount[ithread] += (numbytes/onePacketSize); #ifdef DEBUG cprintf(BLUE,"Listening_Thread %d: Last Buffer numBytes:%d\n",ithread, numbytes); cprintf(BLUE,"Listening_Thread %d: Last Buffer packet count:%d\n",ithread, numbytes/onePacketSize); @@ -1813,7 +1823,7 @@ void UDPStandardImplementation::stopListening(int ithread, int numbytes){ listeningThreadsMask^=(1<> frameIndexOffset), @@ -1909,7 +1919,7 @@ uint32_t UDPStandardImplementation::processListeningBuffer(int ithread, int &cSi case JUNGFRAU: - lastPacketOffset = (((numberofJobsPerBuffer * packetsPerFrame - 1) * onePacketSize) + HEADER_SIZE_NUM_TOT_PACKETS); + lastPacketOffset = (((packetCount - 1) * onePacketSize) + HEADER_SIZE_NUM_TOT_PACKETS); #ifdef DEBUG4 header = (jfrau_packet_header_t*) (buffer[ithread]+HEADER_SIZE_NUM_TOT_PACKETS); cprintf(BLUE, "Listening_Thread: First Header:%d\t First Packet:%d\n", @@ -1971,22 +1981,6 @@ void UDPStandardImplementation::startWriting(){ //let calling function know thread started and obtained current threadStarted = 1; - switch(myDetectorType){ - case EIGER: - processWritingBufferPacketByPacket(ithread); - break; - default: - processWritingBuffer(ithread); - break; - } - -} - - - -void UDPStandardImplementation::processWritingBuffer(int ithread){ - FILE_LOG(logDEBUG) << __AT__ << " called"; - //variable definitions char* wbuf; //buffer popped from FIFO sfilefd[ithread] = NULL; //file pointer @@ -2000,7 +1994,7 @@ void UDPStandardImplementation::processWritingBuffer(int ithread){ //--reset parameters before acquisition nf = 0; - guiData[ithread] = latestData[ithread]; //so that the first frame is always copied + guiData[ithread] = latestData[ithread]; //so that the first frame is always copied if(dataCompressionEnable) listenfifoIndex = 0; //compression has only one listening thread @@ -2060,361 +2054,6 @@ void UDPStandardImplementation::processWritingBuffer(int ithread){ -void UDPStandardImplementation::processWritingBufferPacketByPacket(int ithread){ - FILE_LOG(logDEBUG) << __AT__ << " called"; - - //variable definitions - char* packetBuffer[numberofListeningThreads]; //buffer popped from FIFO - sfilefd = NULL; //file pointer - bool popReady[numberofListeningThreads]; //if the FIFO can be popped - uint32_t numPackets[numberofListeningThreads]; //number of packets popped from the FIFO - - int MAX_NUM_PACKETS = 1024; //highest 32 bit has 1024 number of packets - uint32_t LAST_PACKET_VALUE; //last packet number - - CircularFifo* fifoTempFree[numberofListeningThreads];//ciruclar fifo to keep track of one frame packets to be freed and reused later - char* temp = NULL; - - char* frameBuffer[MAX_NUM_PACKETS]; //buffer offset created for a whole frame - int frameBufferoffset[numberofListeningThreads]; //buffer offset created for a whole frame for both listening threads - char* blankframe[MAX_NUM_PACKETS]; //blank buffer for a whole frame with missing packets - int blankoffset; //blank buffer offset - - bool fullframe[numberofListeningThreads]; //if full frame processed for each listening thread - volatile uint32_t threadFrameNumber[numberofListeningThreads]; //thread frame number for each listening thread buffer popped out - volatile uint32_t presentFrameNumber; //the current frame number aiming to be built - volatile uint32_t lastPacketNumber[numberofListeningThreads]; //last packet number got - volatile uint32_t currentPacketNumber[numberofListeningThreads];//current packet number - volatile int numberofMissingPackets[numberofListeningThreads]; // number of missing packets in this buffer - - for(int i=0; iisEmpty()){ - fifoTempFree[i]->pop(temp); -#ifdef EVERYFIFODEBUG - if(fifoTempFree[i]->getSemValue()>((packetsPerFrame/numberofListeningThreads)-3)) - cprintf(RED,"FifoTempFree[%d]: value:%d, pop 0x%x\n",i,fifoTempFree[i]->getSemValue(),(void*)(temp)); -#endif - } - delete fifoTempFree[i]; - fifoTempFree[i] = NULL; - } - fifoTempFree[i] = new CircularFifo(MAX_NUM_PACKETS); - } - - for(uint32_t i=0; imissingPacket) = missingPacketValue; - *( (uint16_t*) blankframe_footer->packetNumber) = i+1; - - //set each value inside blank frame to 0xff - for(int j=0;j<(oneDataSize);++j){ - unsigned char* blankframe_data = (unsigned char*)blankframe[i] + sizeof(eiger_packet_header_t) + j; - *(blankframe_data) = 0xFF; - } - } - //last frame read out - lastFrameIndex = -1; - - - - - /* inner loop - loop for each buffer */ - //until mask unset (udp sockets shut down by client) - while((1 << ithread) & writerThreadsMask){ - - - //pop fifo and if end of acquisition - //cprintf(BLUE,"popready[0]:%d popready[1]:%d\n",popReady[0],popReady[1]); - if(popAndCheckEndofAcquisition(ithread, packetBuffer, popReady, numPackets,fifoTempFree)){ -#ifdef DEBUG4 - cprintf(GREEN,"Writing_Thread All dummy-end buffers popped\n"); -#endif - //finish missing packets - if(((frameBufferoffset[0]!=0) || (frameBufferoffset[1]!=((int)packetsPerFrame/numberofListeningThreads)))); - else{ - stopWriting(ithread,packetBuffer); - continue; - } - } -#ifdef DEBUG4 - else{cprintf(BLUE,"POPped but i see?\n");} -#endif - - //get a full frame------------------------------------------------------------------------------------------------------- - for(int i=0;ipacketNumber); -#ifdef DEBUG4 - cprintf(MAGENTA,"Fifo %d: threadframenumber original:%d currentpacketnumber real:%d\n", - i,threadFrameNumber[i],currentPacketNumber[i]); -#endif - } - - //calculate number of missing packets----------------------------------------------------- - numberofMissingPackets[i] = 0; - if((numPackets[i] == dummyPacketValue) || (threadFrameNumber[i] != presentFrameNumber)) - numberofMissingPackets[i] = (LAST_PACKET_VALUE - lastPacketNumber[i]); - else - numberofMissingPackets[i] = (currentPacketNumber[i] - lastPacketNumber[i] - 1); - numMissingPackets += numberofMissingPackets[i]; - -#ifdef DEBUG4 - if(numPackets[i] == dummyPacketValue) - cprintf(GREEN, "Fifo %d: Calc missing packets (Dummy): Adding missing packets %d to the last frame\n", - i, numberofMissingPackets[i]); - else{ - cprintf(GREEN,"Fifo %d: Calc missing packets: fnum %d, fnum_thread %d, " - "pnum %d, last_pnum %d, pnum_offset %d missing_packets %d\n", - i,presentFrameNumber,threadFrameNumber[i], - currentPacketNumber[i],lastPacketNumber[i],frameBufferoffset[i],numberofMissingPackets[i]); - } -#endif - - - //add missing packets--------------------------------------------------------------------- - for(int j=0;jmissingPacket)!= missingPacketValue){ - eiger_packet_header_t* blankframe_header = (eiger_packet_header_t*) blankframe[blankoffset]; - cprintf(BG_RED, "Fifo %d: Add Missing Packet Error: " - "pnum_offset %d, pnum %d, fnum_thread %d, missingpacket_buffer 0x%x, missingpacket_blank 0x%x\n", - i,frameBufferoffset[i],currentPacketNumber[i],threadFrameNumber[i], - *( (uint16_t*) frameBuffer_header->missingPacket), - *( (uint16_t*) blankframe_header->missingPacket)); - exit(-1); - }else{ -#ifdef DEBUG4 - cprintf(RED, "Fifo %d: Add Missing Packet success: " - "pnum_offset %d, pnum_got %d, fnum_thread %d, missingpacket_buffer 0x%x\n", - i,frameBufferoffset[i],currentPacketNumber[i],threadFrameNumber[i], - *( (uint16_t*) frameBuffer_header->missingPacket)); -#endif - frameBufferoffset[i]=frameBufferoffset[i]+1; - } - } - - //missed packets/future packet: do not pop over and determine fullframe-------------------- - popReady[i] = false; - if((numPackets[i] == dummyPacketValue) ||(threadFrameNumber[i] != presentFrameNumber)) - fullframe[i] = true; - else - fullframe[i] = false; - if(threadFrameNumber[i] != presentFrameNumber) - threadFrameNumber[i] = presentFrameNumber; - - - //add current packet-------------------------------------------------------------- - if(fullframe[i] == false){ - if(currentPacketNumber[i] != (uint32_t)(frameBufferoffset[i]-(i*packetsPerFrame/numberofListeningThreads))+1){ - cprintf(BG_RED, "Fifo %d: Correct Packet Offset Error: " - "pnum_offset %d,pnum %d fnum_thread %d\n", - i,frameBufferoffset[i],currentPacketNumber[i],threadFrameNumber[i]); - exit(-1); - } - - - while(!fifoTempFree[i]->push(packetBuffer[i])); -#ifdef EVERYFIFODEBUG - if(fifoTempFree[i]->getSemValue()>((packetsPerFrame/numberofListeningThreads)-3)) - cprintf(YELLOW,"FifoTempfree[%d]: value:%d, push 0x%x\n",i,fifoTempFree[i]->getSemValue(),(void*)(wbuffer[i])); -#endif - - - - //cprintf(RED,"Current Packet frameBufferoffset[i]:%d\n",frameBufferoffset[i]); - frameBuffer[frameBufferoffset[i]] = (packetBuffer[i] + HEADER_SIZE_NUM_TOT_PACKETS); -#ifdef DEBUG4 - eiger_packet_header_t* frameBuffer_header = (eiger_packet_header_t*) frameBuffer[frameBufferoffset[i]]; - eiger_packet_footer_t* frameBuffer_footer = (eiger_packet_footer_t*) (frameBuffer[frameBufferoffset[i]] + footerOffset); - cprintf(GREEN, "Fifo %d: Current Packet added success:" - "pnum_offset %d, pnum %d, real pnum %d fnum_thread %d, missingpacket_buffer 0x%x\n", - i,frameBufferoffset[i],currentPacketNumber[i],*( (uint16_t*) frameBuffer_footer->packetNumber),threadFrameNumber[i], - *( (uint16_t*) frameBuffer_header->missingPacket)); -#endif - frameBufferoffset[i]=frameBufferoffset[i]+1; - //update last packet - lastPacketNumber[i] = currentPacketNumber[i]; - popReady[i] = true; - fullframe[i] = false; - if(currentPacketNumber[i] == LAST_PACKET_VALUE){ -#ifdef DEBUG4 - cprintf(GREEN, "Fifo %d: Got last packet\n",i); -#endif - popReady[i] = false; - fullframe[i] = true; - } //end of last packet - }//end of add current packet - }//end of if(!fullframe) - }//end of for listening threads - - - //full frame - if(fullframe[0] && fullframe[1]){ - currentFrameNumber = presentFrameNumber; - numTotMissingPacketsInFile += numMissingPackets; - numTotMissingPackets += numMissingPackets;/**requires a lock*/ - -/* - cprintf(CYAN,"**framenum:%lld\n ",(long long int)currentFrameNumber); - if(currentFrameNumber>500){ - cprintf(BG_RED,"too high frame number %lld \n",(long long int)currentFrameNumber ); - exit(-1); - } - for(int i=0;ipacketNumber), (void*)(packetBuffer[i])); - }*/ -#ifdef DEBUG4 - cprintf(BLUE," nummissingpackets:%d\n",numMissingPackets); -#endif -#ifdef FNUM_DEBUG - cprintf(GREEN,"**fnum:%lld**\n",(long long int)currentFrameNumber); -#endif -#ifdef MISSINGP_DEBUG - if(numMissingPackets){ - cprintf(RED, "Total missing packets %d for fnum %d\n",numMissingPackets,currentFrameNumber); - for (int j=0;jmissingPacket)==missingPacketValue) - cprintf(RED,"Found missing packet at pnum %d\n",j); - } - } -#endif - - //write and copy to gui - handleWithoutDataCompression(ithread,frameBuffer,packetsPerFrame); - - //reset a few stuff - presentFrameNumber++; - for(int i=0; iisEmpty()){ - fifoTempFree[i]->pop(temp); -#ifdef EVERYFIFODEBUG - if(fifoTempFree[i]->getSemValue()>((packetsPerFrame/numberofListeningThreads)-3)) - cprintf(GRAY,"FifoTempFree[%d]: value:%d, pop 0x%x\n",i,fifoTempFree[i]->getSemValue(),(void*)(temp)); -#endif - while(!fifoFree[i]->push(temp)); -#ifdef EVERYFIFODEBUG - if(fifoFree[i]->getSemValue()<100) - cprintf(GREEN,"FifoFree[%d]: value:%d, push 0x%x\n",i,fifoFree[i]->getSemValue(),(void*)(temp)); -#endif -#ifdef CFIFODEBUG - if(i==0) - cprintf(CYAN,"Fifo %d: Writing_Thread freed: pushed into fifofree %p\n",i, (void*)(temp)); - else - cprintf(YELLOW,"Fifo %d: Writing_Thread freed: pushed into fifofree %p\n",i, (void*)(temp)); -#endif - } - } -#ifdef DEBUG4 - cprintf(GREEN,"Writing_Thread: finished freeing\n"); -#endif - - - }//end of full frame - - }/*--end of loop for each buffer (inner loop)*/ - - waitWritingBufferForNextAcquisition(ithread); - - }/*--end of loop for each acquisition (outer loop) */ -} - - - - void UDPStandardImplementation::waitWritingBufferForNextAcquisition(int ithread){ FILE_LOG(logDEBUG) << __AT__ << " called"; @@ -2451,24 +2090,20 @@ void UDPStandardImplementation::waitWritingBufferForNextAcquisition(int ithread) //change the detector index in the file names if(myDetectorType == EIGER){ int detindex = -1; - string tempname(fileName[ithread]); - cout<<"tempname:"<* fifoTempFree[]){ - FILE_LOG(logDEBUG) << __AT__ << " called"; - - bool endofAcquisition = true; - for(int i=0; ipop(wbuffer[i]); -#ifdef EVERYFIFODEBUG - if(fifo[i]->getSemValue()>(fifoSize-100)) - cprintf(CYAN,"Fifo[%d]: value:%d, pop 0x%x\n",i,fifo[i]->getSemValue(),(void*)(wbuffer[i])); -#endif -#ifdef CFIFODEBUG - if(i == 0) - cprintf(CYAN,"Writing_Thread %d: Popped %p from FIFO %d\n", ithread, (void*)(wbuffer[i]),i); - else - cprintf(YELLOW,"Writing_Thread %d: Popped %p from FIFO %d\n", ithread, (void*)(wbuffer[i]),i); -#endif - nP[i] = (uint32_t)(*((uint32_t*)wbuffer[i])); -#ifdef DEBUG4 - cprintf(GREEN,"Writing_Thread %d: Number of Packets: %d for FIFO %d\n", ithread, nP[i], i); -#endif - //dummy-end buffer - if(nP[i] == dummyPacketValue){ - ready[i] = false; -#ifdef DEBUG3 - cprintf(GREEN,"Writing_Thread %d: Dummy frame popped out of FIFO %d",ithread, i); -#endif - } - //normal buffer popped out - else{ - endofAcquisition = false; -#ifdef DEBUG4 - if(myDetectorType == EIGER){ - eiger_packet_footer_t* wbuf_footer = (eiger_packet_footer_t*)(wbuffer[i] + footerOffset + HEADER_SIZE_NUM_TOT_PACKETS); - //cprintf(BLUE,"footer value:0x%x\n",i,(uint64_t)(*( (uint64_t*) wbuf_footer))); - //if(*( (uint16_t*) wbuf_footer->packetNumber) == 1){ - cprintf(BLUE,"Fnum[%d]:%d\n",i,(uint32_t)(*( (uint64_t*) wbuf_footer))); - cprintf(BLUE,"Pnum[%d]:%d\n",i,*( (uint16_t*) wbuf_footer->packetNumber)); - //} - } -#endif - } - } - //when both are not popped but curretn frame number is being processed - else{ - if(nP[i] != dummyPacketValue) - endofAcquisition = false; - } - } - - return endofAcquisition; -} - - void UDPStandardImplementation::stopWriting(int ithread, char* wbuffer){ FILE_LOG(logDEBUG) << __AT__ << " called"; @@ -2626,294 +2206,200 @@ void UDPStandardImplementation::stopWriting(int ithread, char* wbuffer){ //statistics FILE_LOG(logINFO) << "Status: Run Finished"; FILE_LOG(logINFO) << "Last Frame Number Caught:" << lastFrameIndex[ithread]; - if(totalPacketsCaught < ((uint64_t)numberOfFrames*packetsPerFrame)){ - cprintf(RED, "Total Missing Packets padded: %d\n",numTotMissingPackets); + if(totalPacketsCaught < ((uint64_t)numberOfFrames*packetsPerFrame*numberofListeningThreads)){ + cprintf(RED, "Total Missing Packets: %lld\n",(long long int)numberOfFrames*packetsPerFrame*numberofListeningThreads-totalPacketsCaught); cprintf(RED, "Total Packets Caught: %lld\n",(long long int)totalPacketsCaught); - cprintf(RED, "Total Frames Caught: %lld\n",(long long int)(totalPacketsCaught/packetsPerFrame)); + cprintf(RED, "Total Frames Caught: %lld\n",(long long int)(totalPacketsCaught/(packetsPerFrame*numberofListeningThreads))); }else{ - cprintf(GREEN, "Total Missing Packets padded: %d\n",numTotMissingPackets); - cprintf(GREEN, "Total Packets Caught:%lld\n", (long long int)totalPacketsCaught); - cprintf(GREEN, "Total Frames Caught:%lld\n",(long long int)(totalPacketsCaught/packetsPerFrame)); + cprintf(GREEN, "Total Missing Packets: %lld\n",(long long int)numberOfFrames*packetsPerFrame*numberofListeningThreads-totalPacketsCaught); + cprintf(GREEN, "Total Packets Caught: %lld\n",(long long int)totalPacketsCaught); + cprintf(GREEN, "Total Frames Caught: %lld\n",(long long int)(totalPacketsCaught/(packetsPerFrame*numberofListeningThreads))); } //acquisition end if (acquisitionFinishedCallBack) - acquisitionFinishedCallBack((int)(totalPacketsCaught/packetsPerFrame), pAcquisitionFinished); + acquisitionFinishedCallBack((int)totalPacketsCaught, pAcquisitionFinished); } } -void UDPStandardImplementation::handleWithoutDataCompression(int ithread, char* wbuffer,uint32_t npackets){ +void UDPStandardImplementation::handleWithoutDataCompression(int ithread, char* wbuffer, uint32_t npackets){ FILE_LOG(logDEBUG) << __AT__ << " called"; - //get frame number (eiger already gets it when it does packet to packet processing) - if(myDetectorType != EIGER){ - if(myDetectorType == JUNGFRAU){ - jfrau_packet_header_t* header = (jfrau_packet_header_t*)(wbuffer[0] + HEADER_SIZE_NUM_TOT_PACKETS); - currentFrameNumber = (*( (uint32_t*) header->frameNumber))&0xffffff; - }else{ - uint64_t tempframenumber = ((uint32_t)(*((uint32_t*)(wbuffer[0] + HEADER_SIZE_NUM_TOT_PACKETS)))); - //for gotthard and normal frame, increment frame number to separate fnum and pnum - if (myDetectorType == PROPIX ||(myDetectorType == GOTTHARD && shortFrameEnable == -1)) - tempframenumber++; - //get frame number - currentFrameNumber = (tempframenumber & frameIndexMask) >> frameIndexOffset; - } - //set indices - acquisitionIndex = currentFrameNumber - startAcquisitionIndex; - frameIndex = currentFrameNumber - startFrameIndex; + //get current frame number + uint64_t tempframenumber; + if(getFrameNumber(ithread, wbuffer + HEADER_SIZE_NUM_TOT_PACKETS,tempframenumber) == FAIL){ + //error in frame number sent by fpga + while(!fifoFree[ithread]->push(wbuffer)); + + return; } + //update current frame number + lastFrameIndex[ithread] = tempframenumber; + if(myDetectorType == EIGER) + currentFrameNumber[ithread] = tempframenumber + (startFrameIndex - 1); + else + currentFrameNumber[ithread] = tempframenumber-startFrameIndex; - + //set indices + pthread_mutex_lock(&progressMutex); + if((currentFrameNumber[ithread] - startAcquisitionIndex) > acquisitionIndex) + acquisitionIndex = currentFrameNumber[ithread] - startAcquisitionIndex; + if((currentFrameNumber[ithread] - startFrameIndex) > frameIndex[ithread]) + frameIndex[ithread] = currentFrameNumber[ithread] - startFrameIndex; + pthread_mutex_unlock(&progressMutex); //callback to write data - if (cbAction < DO_EVERYTHING){ - switch(myDetectorType){ - case EIGER: - for(uint32_t i=0;i 0) - writeFileWithoutCompression(wbuffer, npackets); + writeFileWithoutCompression(ithread, wbuffer, npackets); #ifdef DEBUG4 cprintf(GREEN,"Writing_Thread: Writing done\nGoing to copy frame\n"); #endif //copy frame for gui - if(npackets >= packetsPerFrame) - copyFrameToGui(wbuffer); + if(npackets >= packetsPerFrame)/**needs to be reworked*/ + copyFrameToGui(ithread, wbuffer); #ifdef DEBUG4 cprintf(GREEN,"Writing_Thread: Copied frame\n"); #endif - //free fifo addresses (eiger frees for each packet later) - if(myDetectorType != EIGER){ - while(!fifoFree[0]->push(wbuffer[0])); + //free fifo addresses + int listenfifoThread = ithread; + if(dataCompressionEnable) + listenfifoThread = 0; + while(!fifoFree[listenfifoThread]->push(wbuffer)); #ifdef EVERYFIFODEBUG - if(fifoFree[0]->getSemValue()<100) - cprintf(GREEN,"FifoFree[%d]: value:%d, push 0x%x\n",0,fifoFree[0]->getSemValue(),(void*)(wbuffer[0])); + if(fifoFree[listenfifoThread]->getSemValue()<100) + cprintf(GREEN,"FifoFree[%d]: value:%d, push 0x%x\n",listenfifoThread,fifoFree[listenfifoThread]->getSemValue(),(void*)(wbuffer)); #endif #ifdef DEBUG5 - cprintf(GREEN,"Writing_Thread %d: Freed buffer, pushed into fifofree %p for listener 0\n",ithread, (void*)(wbuffer[0])); + cprintf(GREEN,"Writing_Thread %d: Freed buffer, pushed into fifofree %p for listener %d \n",listenfifoThread, (void*)(wbuffer), listenfifoThread); #endif - } + } -void UDPStandardImplementation::writeFileWithoutCompression(int ithread, char* wbuffer[],uint32_t numpackets){ +void UDPStandardImplementation::writeFileWithoutCompression(int ithread, char* wbuffer,uint32_t numpackets){ FILE_LOG(logDEBUG) << __AT__ << " called"; - - //create headers for eiger -#ifdef WRITE_HEADERS - if (myDetectorType == EIGER && cbAction == DO_EVERYTHING) - createHeaders(wbuffer); -#endif - //if write enabled - if((fileWriteEnable) && (sfilefd)){ - int offset = HEADER_SIZE_NUM_TOT_PACKETS; //offset (not eiger) to keep track of how many packets saved - uint32_t packetsToSave; //how many packets to save at a time - volatile uint64_t tempframenumber; - int lastpacket; + if((fileWriteEnable) && (sfilefd[ithread])){ +cout< 0){ - //new file - if(packetsInFile >= (uint32_t)maxPacketsPerFile){ - //for packet loss, because currframenum is the latest one for eiger - //get frame number (eiger already gets it when it does packet to packet processing) - if(myDetectorType != EIGER){ - lastpacket = (((packetsToSave - 1) * onePacketSize) + offset); - if(myDetectorType == JUNGFRAU){ - jfrau_packet_header_t* header = (jfrau_packet_header_t*) (wbuffer[0] + lastpacket); - currentFrameNumber = (*( (uint32_t*) header->frameNumber))&0xffffff; - }else{ - tempframenumber = ((uint32_t)(*((uint32_t*)(wbuffer[0] + lastpacket)))); - //for gotthard and normal frame, increment frame number to separate fnum and pnum - if (myDetectorType == PROPIX ||(myDetectorType == GOTTHARD && shortFrameEnable == -1)) - tempframenumber++; - //get frame number - currentFrameNumber = (tempframenumber & frameIndexMask) >> frameIndexOffset; - } - - //set indices - acquisitionIndex = currentFrameNumber - startAcquisitionIndex; - frameIndex = currentFrameNumber - startFrameIndex; + //handle half frames from previous buffer + //second part to not check when there has been something written previously + if(numpackets &&(lastFrameNumberInFile[ithread])){ + //get start frame (required to create new file at the right juncture) + uint64_t startframe =-1; + if(getFrameNumber(ithread, wbuffer + offset, startframe) == FAIL){ + //error in frame number sent by fpga + while(!fifoFree[ithread]->push(wbuffer)); + return; } -#ifdef DEBUG3 - cprintf(GREEN,"Writing_Thread: Current Frame Number:%d\n",currentFrameNumber); -#endif - createNewFile(ithread); - } - //to create new file when max reached - packetsToSave = maxPacketsPerFile - packetsInFile; - if(packetsToSave > numpackets) - packetsToSave = numpackets; + cout<<"222"<push(wbuffer)); + return; + } + totalPacketsInFile[ithread] += numpackets; + lastFrameNumberInFile[ithread] = finalLastFrameNumberToSave+1; + currentFrameNumber[ithread] = finalLastFrameNumberToSave; + } + if(numberofWriterThreads > 1) pthread_mutex_lock(&writeMutex); - packetsInFile += numpackets; - packetsCaughtPerThread[ithread] += (numpackets - numMissingPackets); - pthread_mutex_lock(&progressMutex); - packetsCaught += (numpackets - numMissingPackets); - pthread_mutex_unlock(&progressMutex); - totalPacketsCaught += (numpackets - numMissingPackets); - numMissingPackets = 0; + packetsCaught += numpackets; + totalPacketsCaught += numpackets; if(numberofWriterThreads > 1) pthread_mutex_unlock(&writeMutex); } + //set indices + pthread_mutex_lock(&progressMutex); + if((currentFrameNumber[ithread] - startAcquisitionIndex) > acquisitionIndex) + acquisitionIndex = currentFrameNumber[ithread] - startAcquisitionIndex; + if((currentFrameNumber[ithread] - startFrameIndex) > frameIndex[ithread]) + frameIndex[ithread] = currentFrameNumber[ithread] - startFrameIndex; + pthread_mutex_unlock(&progressMutex); } -void UDPStandardImplementation::createHeaders(char* wbuffer[]){ - - - int port = 0, missingPacket; - bool exitVal = 0; - eiger_packet_header_t* wbuf_header; - eiger_packet_footer_t* wbuf_footer; - - for (uint32_t i = 0; i < packetsPerFrame; i++){ - - - wbuf_header = (eiger_packet_header_t*) wbuffer[i]; - wbuf_footer = (eiger_packet_footer_t*)(wbuffer[i] + footerOffset); -#ifdef DEBUG4 - cprintf(GREEN, "Loop index:%d Pnum:%d real fnum %d,missingPacket 0x%x\n", - i, - *( (uint16_t*) wbuf_footer->packetNumber), - (uint32_t)(*( (uint64_t*) wbuf_footer)), - *( (uint16_t*) wbuf_header->missingPacket) - ); cout <missingPacket)== missingPacketValue){ -#ifdef DEBUG4 - cprintf(RED,"-Missing packet at Loop Index %d\n", i); -#endif - missingPacket = 1; - - //DEBUGGING - if(*( (uint16_t*) wbuf_footer->packetNumber) != (i+1)){ - cprintf(BG_RED, "Writing_Thread: Packet Number Mismatch (missing p)! " - "i %d, real pnum %d, real fnum %d, missingPacket 0x%x\n", - i, - *( (uint16_t*) wbuf_footer->packetNumber), - (uint32_t)(*( (uint64_t*) wbuf_footer)), - *( (uint16_t*) wbuf_header->missingPacket)); - exitVal =1; - } - - //add frame number - *( (uint64_t*) wbuf_footer) = (currentFrameNumber+1) | (((uint64_t)(*( (uint16_t*) wbuf_footer->packetNumber)))<<0x30); - //*( (uint16_t*) wbuf_footer->packetNumber) = (i+1); // missing frames already have the right packet number -#ifdef DEBUG4 - cprintf(RED, "Missing Packet Loop index:%d fnum:%d Pnum:%d\n",i, - (uint32_t)(*( (uint64_t*) wbuf_footer)), - *( (uint16_t*) wbuf_footer->packetNumber)); -#endif - } - //normal packet - else{ - missingPacket = 0; - - //DEBUGGING - if(*( (uint16_t*) wbuf_footer->packetNumber) != ( (i>((packetsPerFrame/2)-1)?(i-(packetsPerFrame/2)+1):i+1) )){ - cprintf(BG_RED, "Writing_Thread: Packet Number Mismatch! " - "i %d, real pnum %d, real fnum %d, missingPacket 0x%x\n", - i, - *( (uint16_t*) wbuf_footer->packetNumber), - (uint32_t)(*( (uint64_t*) wbuf_footer)), - *( (uint16_t*) wbuf_header->missingPacket)); - exitVal =1; - } - - uint16_t p = *( (uint16_t*) wbuf_footer->packetNumber); - //correct the packet numbers of port2 so that port1 and 2 are not the same - if(port) *( (uint16_t*) wbuf_footer->packetNumber) = (p +(packetsPerFrame/2)); - - } - - //overwriting port number and dynamic range - *( (uint8_t*) wbuf_header->portIndex) = (uint8_t)port; - //*( (uint8_t*) wbuf_header->dynamicRange) = (uint8_t)dynamicRange; - - //DEBUGGING - if(*( (uint16_t*) wbuf_footer->packetNumber) != (i+1)){ - cprintf(BG_RED, "Writing_Thread: Packet Number Mismatch! " - "i %d, real pnum %d, real fnum %d, missingPacket 0x%x\n", - i, - *( (uint16_t*) wbuf_footer->packetNumber), - (uint32_t)(*( (uint64_t*) wbuf_footer)), - *( (uint16_t*) wbuf_header->missingPacket)); - exitVal =1; - } - } - - if(exitVal){exit(-1);} - -} - void UDPStandardImplementation::updateFileHeader(int ithread){ int xpix=-1,ypix=-1; @@ -2960,23 +2446,23 @@ void UDPStandardImplementation::updateFileHeader(int ithread){ } -void UDPStandardImplementation::copyFrameToGui(char* buffer[]){ +void UDPStandardImplementation::copyFrameToGui(int ithread, char* buffer){ FILE_LOG(logDEBUG) << __AT__ << " called"; //random read (gui not ready) //need to toggle guiDataReady or the second frame wont be copied - if((!FrameToGuiFrequency) && (!guiData)){ + if((!FrameToGuiFrequency) && (!guiData[ithread])){ #ifdef DEBUG4 cprintf(GREEN,"Writing_Thread: CopyingFrame: Resetting guiDataReady\n"); #endif pthread_mutex_lock(&dataReadyMutex); - guiDataReady=0; + guiDataReady[ithread]=0; pthread_mutex_unlock(&dataReadyMutex); } //if nthe frame, wait for your turn (1st frame always shown as its zero) - else if(FrameToGuiFrequency && ((frametoGuiCounter)%FrameToGuiFrequency)); + else if(FrameToGuiFrequency && ((frametoGuiCounter[ithread])%FrameToGuiFrequency)); //random read (gui ready) or nth frame read: gui needs data now or it is the first frame else{ @@ -2984,22 +2470,15 @@ void UDPStandardImplementation::copyFrameToGui(char* buffer[]){ cprintf(GREEN,"Writing_Thread: CopyingFrame: Gui needs data now OR 1st frame\n"); #endif pthread_mutex_lock(&dataReadyMutex); - guiDataReady=0; + guiDataReady[ithread]=0; #ifdef DEBUG4 cprintf(GREEN,"Writing_Thread: CopyingFrame: guidataready is 0, Copying data\n"); #endif - switch(myDetectorType){ - case EIGER: - for(uint32_t i=0; i> frameIndexOffset; - //handle multi threads - pthread_mutex_lock(&progressMutex); - if(tempframenumber > currentFrameNumber) - currentFrameNumber = tempframenumber; - pthread_mutex_unlock(&progressMutex); - //set indices - acquisitionIndex = currentFrameNumber - startAcquisitionIndex; - frameIndex = currentFrameNumber - startFrameIndex; + uint64_t tempframenumber=-1; + if(getFrameNumber(ithread, wbuffer + HEADER_SIZE_NUM_TOT_PACKETS, tempframenumber) == FAIL){ + //error in frame number sent by fpga + while(!fifoFree[ithread]->push(wbuffer)); + return; + } + currentFrameNumber[ithread] = tempframenumber; + //set indices + pthread_mutex_lock(&progressMutex); + if((currentFrameNumber[ithread] - startAcquisitionIndex) > acquisitionIndex) + acquisitionIndex = currentFrameNumber[ithread] - startAcquisitionIndex; + if((currentFrameNumber[ithread] - startFrameIndex) > frameIndex[ithread]) + frameIndex[ithread] = currentFrameNumber[ithread] - startFrameIndex; + pthread_mutex_unlock(&progressMutex); //variable definitions char* buff[2]={0,0}; //an array just to be compatible with copyframetogui - char* data = wbuffer[0]+ HEADER_SIZE_NUM_TOT_PACKETS; //data pointer to the next memory to be analysed + char* data = wbuffer+ HEADER_SIZE_NUM_TOT_PACKETS; //data pointer to the next memory to be analysed int ndata; //size of data returned uint32_t np; //remaining number of packets returned - uint32_t npackets = (uint32_t)(*((uint32_t*)wbuffer[0])); //number of total packets + uint32_t npackets = (uint32_t)(*((uint32_t*)wbuffer)); //number of total packets int remainingsize = npackets * onePacketSize; //size of the memory slot to be analyzed eventType thisEvent = PEDESTAL; @@ -3120,8 +2599,8 @@ void UDPStandardImplementation::handleDataCompression(int ithread, char* wbuffer //cout << "Fill in event: frmNr: " << iFrame << " ix " << ix << " iy " << iy << " type " << thisEvent << endl; #else pthread_mutex_lock(&writeMutex); - if((fileWriteEnable) && (sfilefd)) - singlePhotonDetectorObject[ithread]->writeCluster(sfilefd); + if((fileWriteEnable) && (sfilefd[0])) + singlePhotonDetectorObject[ithread]->writeCluster(sfilefd[0]); pthread_mutex_unlock(&writeMutex); #endif } @@ -3129,38 +2608,229 @@ void UDPStandardImplementation::handleDataCompression(int ithread, char* wbuffer } nf++; + + #ifndef ALLFILE - pthread_mutex_lock(&progressMutex); - packetsInFile += packetsPerFrame; - packetsCaughtPerThread[0] += packetsPerFrame; - packetsCaught += packetsPerFrame; - totalPacketsCaught += packetsPerFrame; - if(packetsInFile >= (uint32_t)maxPacketsPerFile) - createNewFile(0); - pthread_mutex_unlock(&progressMutex); + totalPacketsInFile[ithread] += (bufferSize/packetsPerFrame); + pthread_mutex_lock(&writeMutex); + if((packetsCaught%packetsPerFrame) >= (uint32_t)maxFramesPerFile) + createNewFile(ithread); + packetsCaught += (bufferSize/packetsPerFrame); + totalPacketsCaught += (bufferSize/packetsPerFrame); + pthread_mutex_unlock(&writeMutex); + #endif if(!once){ - copyFrameToGui(buff); + copyFrameToGui(ithread, buff[0]); once = 1; } } remainingsize -= ((buff[0] + ndata) - data); data = buff[0] + ndata; - if(data > (wbuffer[0] + HEADER_SIZE_NUM_TOT_PACKETS + npackets * onePacketSize) ) + if(data > (wbuffer + HEADER_SIZE_NUM_TOT_PACKETS + npackets * onePacketSize) ) cprintf(BG_RED,"Writing_Thread %d: Error: Compression data goes out of bounds!\n", ithread); } - while(!fifoFree[0]->push(wbuffer[0])); + while(!fifoFree[0]->push(wbuffer)); #ifdef EVERYFIFODEBUG if(fifoFree[0]->getSemValue()<100) - cprintf(GREEN,"FifoFree[%d]: value:%d, push 0x%x\n",0,fifoFree[0]->getSemValue(),(void*)(wbuffer[0])); + cprintf(GREEN,"FifoFree[%d]: value:%d, push 0x%x\n",0,fifoFree[0]->getSemValue(),(void*)(wbuffer)); #endif #ifdef DEBUG5 - cprintf(GREEN,"Writing_Thread %d: Compression free pushed into fifofree %p for listerner 0\n", ithread, (void*)(wbuffer[0])); + cprintf(GREEN,"Writing_Thread %d: Compression free pushed into fifofree %p for listerner 0\n", ithread, (void*)(wbuffer)); #endif } + +int UDPStandardImplementation::getFrameNumber(int ithread, char* wbuffer, uint64_t &tempframenumber){ + FILE_LOG(logDEBUG) << __AT__ << " called"; + + eiger_packet_footer_t* footer=0; + jfrau_packet_header_t* header=0; + int pnum=-1; + + switch(myDetectorType){ + + case EIGER: + footer = (eiger_packet_footer_t*)(wbuffer + footerOffset); + tempframenumber = (uint32_t)(*( (uint64_t*) footer)); + //error in frame number sent by fpga + if(!((uint32_t)(*( (uint64_t*) footer)))){ + tempframenumber = -1; + FILE_LOG(logERROR) << "Fifo "<< ithread << ": Frame Number is zero from firmware."; + return FAIL; + } +//#ifdef DEBUG4 + if(!ithread) cprintf(GREEN,"Writing_Thread %d: fnum:%lld pnum:%d FPGA_fnum:%d footeroffset:%d\n", + ithread, + (long long int)tempframenumber, + (*( (uint16_t*) footer->packetNumber)), + (uint32_t)(*( (uint64_t*) footer)), + footerOffset); +//#endif + break; + + case JUNGFRAU: + header = (jfrau_packet_header_t*)(wbuffer); + tempframenumber = (*( (uint32_t*) header->frameNumber))&frameIndexMask; +#ifdef DEBUG4 + cprintf(GREEN, "Writing_Thread %d: fnum:%lld\t pnum:%d\n", + (long long int)tempframenumber, + (*( (uint8_t*) header->packetNumber))); +#endif + break; + + default: + tempframenumber = ((uint32_t)(*((uint32_t*)(wbuffer)))); + //for gotthard and normal frame, increment frame number to separate fnum and pnum + if (myDetectorType == PROPIX ||(myDetectorType == GOTTHARD && shortFrameEnable == -1)) + tempframenumber++; + pnum = tempframenumber&packetIndexMask; + tempframenumber = (tempframenumber & frameIndexMask) >> frameIndexOffset; +#ifdef DEBUG4 + cprintf(GREEN, "Writing_Thread %d: fnum:%lld\t pnum:%d\n", + (long long int)tempframenumber, + pnum); +#endif + + break; + } + return OK; +} + + + + + +int UDPStandardImplementation::writeUptoFrameNumber(int ithread, char* wbuffer, int &offset, uint64_t nextFrameNumber, uint32_t numpackets, int &numPacketsWritten){ + FILE_LOG(logDEBUG) << __AT__ << " called"; + + + bool expectedoffsetATlastpacket = false; + int startoffset = offset; + if(!ithread) cout<= endoffset){ + expectedoffset = startoffset + ((numpackets -1) * onePacketSize); + expectedoffsetATlastpacket = true; + } + offset = expectedoffset; + if(!ithread) cout<push(wbuffer)); + return FAIL; + } + if(!ithread) cout<=nextFrameNumber){ + if(!ithread) cout<=nextFrameNumber){ + offset -= (onePacketSize*packetsPerFrame);/** its ok..if jonbsperthread is 1, go packet by packet*/ + if(!ithread) cout<push(wbuffer)); + return FAIL; + } + if(!ithread) cout<push(wbuffer)); + return FAIL; + } + if(!ithread) cout<endoffset){if(!ithread) cout<push(wbuffer)); + return FAIL; + } + if(!ithread) cout<endoffset){ + offset = endoffset; + if(!ithread) cout< end offset so offset now:"<nextFrameNumber){ + offset -= onePacketSize; + if(!ithread) cout<push(wbuffer)); + return FAIL; + } + if(!ithread) cout<getTotalFramesCaught(); + cout<<"frames caught sent:"<differentClients){ FILE_LOG(logDEBUG) << "Force update"; @@ -2487,9 +2488,9 @@ int slsReceiverTCPIPInterface::set_dynamic_range() { dynamicrange = retval; if(myDetectorType == EIGER){ if(!tenGigaEnable) - packetsPerFrame = EIGER_ONE_GIGA_CONSTANT * dynamicrange * EIGER_MAX_PORTS; + packetsPerFrame = EIGER_ONE_GIGA_CONSTANT * dynamicrange; else - packetsPerFrame = EIGER_TEN_GIGA_CONSTANT * dynamicrange * EIGER_MAX_PORTS; + packetsPerFrame = EIGER_TEN_GIGA_CONSTANT * dynamicrange; }else if (myDetectorType == JUNGFRAU) packetsPerFrame = JFRAU_PACKETS_PER_FRAME; } From 8eea853a9a8fca03bd06c9f4d7a5d20413f6ce75 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 30 Aug 2016 16:13:24 +0200 Subject: [PATCH 234/474] updaterev --- slsReceiverSoftware/gitInfo.txt | 10 +++++----- slsReceiverSoftware/include/gitInfoReceiver.h | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/slsReceiverSoftware/gitInfo.txt b/slsReceiverSoftware/gitInfo.txt index 4d39e4314..82c68fc0a 100644 --- a/slsReceiverSoftware/gitInfo.txt +++ b/slsReceiverSoftware/gitInfo.txt @@ -1,9 +1,9 @@ Path: slsDetectorsPackage/slsReceiverSoftware URL: origin git@git.psi.ch:sls_detectors_software/sls_receiver_software.git Repository Root: origin git@git.psi.ch:sls_detectors_software/sls_receiver_software.git -Repsitory UUID: a10bf5ae88d113a482dca646085abcb7a45dc52e -Revision: 249 -Branch: master +Repsitory UUID: 10000196185a0991cd13457cd69966d79f860134 +Revision: 251 +Branch: developer Last Changed Author: Dhanya_Maliakal -Last Changed Rev: 249 -Last Changed Date: 2016-08-04 17:19:31 +0200 +Last Changed Rev: 251 +Last Changed Date: 2016-08-12 13:48:30 +0200 diff --git a/slsReceiverSoftware/include/gitInfoReceiver.h b/slsReceiverSoftware/include/gitInfoReceiver.h index b3eb26e83..10c4e9caa 100644 --- a/slsReceiverSoftware/include/gitInfoReceiver.h +++ b/slsReceiverSoftware/include/gitInfoReceiver.h @@ -1,11 +1,11 @@ //#define SVNPATH "" #define SVNURL "git@git.psi.ch:sls_detectors_software/sls_receiver_software.git" //#define SVNREPPATH "" -#define SVNREPUUID "a10bf5ae88d113a482dca646085abcb7a45dc52e" -//#define SVNREV 0x249 +#define SVNREPUUID "10000196185a0991cd13457cd69966d79f860134" +//#define SVNREV 0x251 //#define SVNKIND "" //#define SVNSCHED "" #define SVNAUTH "Dhanya_Maliakal" -#define SVNREV 0x249 -#define SVNDATE 0x20160804 +#define SVNREV 0x251 +#define SVNDATE 0x20160812 // From fbf6e2bff1695c199e1c31e053dc094ac3097d01 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Wed, 31 Aug 2016 10:23:58 +0200 Subject: [PATCH 235/474] not done --- .../src/UDPStandardImplementation.cpp | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 887b827a4..0e9dc9015 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1643,23 +1643,7 @@ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int cSize, ch if(status != TRANSMITTING) receivedSize = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS + cSize, (bufferSize * numberofJobsPerBuffer) - cSize); - - //throw away packets that is not one packet size - while((myDetectorType == EIGER) && - (receivedSize != ((bufferSize * numberofJobsPerBuffer) - cSize)) && - (status != TRANSMITTING)) { - if(receivedSize != EIGER_HEADER_LENGTH) - cprintf(RED,"Listening_Thread %d: Listened to a weird packet size %d\n",ithread, receivedSize); -#ifdef DEBUG - else - cprintf(BLUE,"Listening_Thread %d: Listened to a header packet\n",ithread); -#endif - //listen again - if(status != TRANSMITTING) - receivedSize = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS + cSize, (bufferSize * numberofJobsPerBuffer) - cSize); - //cout< Date: Wed, 31 Aug 2016 17:23:44 +0200 Subject: [PATCH 236/474] separated --- .../include/UDPBaseImplementation.h | 3 +- slsReceiverSoftware/include/UDPInterface.h | 3 +- .../include/UDPStandardImplementation.h | 6 +- slsReceiverSoftware/include/genericSocket.h | 20 +- .../src/UDPBaseImplementation.cpp | 2 +- .../src/UDPStandardImplementation.cpp | 267 +++++++++--------- .../src/slsReceiverTCPIPInterface.cpp | 85 +++--- 7 files changed, 205 insertions(+), 181 deletions(-) diff --git a/slsReceiverSoftware/include/UDPBaseImplementation.h b/slsReceiverSoftware/include/UDPBaseImplementation.h index 6083b0723..60e07ef64 100644 --- a/slsReceiverSoftware/include/UDPBaseImplementation.h +++ b/slsReceiverSoftware/include/UDPBaseImplementation.h @@ -398,12 +398,13 @@ class UDPBaseImplementation : protected virtual slsReceiverDefs, public UDPInter /** * Get the buffer-current frame read by receiver + * @param ithread port thread index * @param c pointer to current file name * @param raw address of pointer, pointing to current frame to send to gui * @param startAcq start index of the acquisition * @param startFrame start index of the scan */ - void readFrame(char* c,char** raw, uint64_t &startAcq, uint64_t &startFrame); + void readFrame(int ithread, char* c,char** raw, int64_t &startAcq, int64_t &startFrame); /** * abort acquisition with minimum damage: close open files, cleanup. diff --git a/slsReceiverSoftware/include/UDPInterface.h b/slsReceiverSoftware/include/UDPInterface.h index dba7acf52..754aa5bd7 100644 --- a/slsReceiverSoftware/include/UDPInterface.h +++ b/slsReceiverSoftware/include/UDPInterface.h @@ -455,12 +455,13 @@ class UDPInterface { /** * Get the buffer-current frame read by receiver + * @param ithread port thread index * @param c pointer to current file name * @param raw address of pointer, pointing to current frame to send to gui * @param startAcq start index of the acquisition * @param startFrame start index of the scan */ - virtual void readFrame(char* c,char** raw, uint64_t &startAcq, uint64_t &startFrame)=0; + virtual void readFrame(int ithread, char* c,char** raw, int64_t &startAcq, int64_t &startFrame)=0; /** * abort acquisition with minimum damage: close open files, cleanup. diff --git a/slsReceiverSoftware/include/UDPStandardImplementation.h b/slsReceiverSoftware/include/UDPStandardImplementation.h index fcec7fc0d..b17882baa 100644 --- a/slsReceiverSoftware/include/UDPStandardImplementation.h +++ b/slsReceiverSoftware/include/UDPStandardImplementation.h @@ -218,7 +218,7 @@ class UDPStandardImplementation: private virtual slsReceiverDefs, public UDPBase * @param startAcq start index of the acquisition * @param startFrame start index of the scan */ - void readFrame(int ithread, char* c,char** raw, uint64_t &startAcq, uint64_t &startFrame); + void readFrame(int ithread, char* c,char** raw, int64_t &startAcq, int64_t &startFrame); /** * Overridden method @@ -571,8 +571,6 @@ private: /** Previous Frame number from buffer to calculate loss */ int64_t frameNumberInPreviousFile[MAX_NUMBER_OF_WRITER_THREADS]; - /** Last Frame Index Listened To */ - int64_t lastFrameIndex[MAX_NUMBER_OF_WRITER_THREADS]; @@ -586,7 +584,7 @@ private: int totalListeningPacketCount[MAX_NUMBER_OF_LISTENING_THREADS]; /** Pckets currently in current file, starts new file when it reaches max */ - uint64_t lastFrameNumberInFile[MAX_NUMBER_OF_WRITER_THREADS]; + int64_t lastFrameNumberInFile[MAX_NUMBER_OF_WRITER_THREADS]; /** packets in current file */ uint64_t totalPacketsInFile[MAX_NUMBER_OF_WRITER_THREADS]; diff --git a/slsReceiverSoftware/include/genericSocket.h b/slsReceiverSoftware/include/genericSocket.h index 0f52c0413..6cb9a8693 100644 --- a/slsReceiverSoftware/include/genericSocket.h +++ b/slsReceiverSoftware/include/genericSocket.h @@ -3,7 +3,7 @@ #define GENERIC_SOCKET_H - +#include "ansi.h" /** @@ -105,7 +105,8 @@ enum communicationProtocol{ packet_size(ps), nsending(0), nsent(0), - total_sent(0)// sender (client): where to? ip + total_sent(0),// sender (client): where to? ip + header_packet_size(0) { //memset(&serverAddress, 0, sizeof(sockaddr_in)); //memset(&clientAddress, 0, sizeof(sockaddr_in)); @@ -161,7 +162,7 @@ enum communicationProtocol{ */ - genericSocket(unsigned short int const port_number, communicationProtocol p, int ps = DEFAULT_PACKET_SIZE, const char *eth=NULL): + genericSocket(unsigned short int const port_number, communicationProtocol p, int ps = DEFAULT_PACKET_SIZE, const char *eth=NULL, int hsize=0): //portno(port_number), protocol(p), is_a_server(1), @@ -170,7 +171,8 @@ enum communicationProtocol{ packet_size(ps), nsending(0), nsent(0), - total_sent(0) + total_sent(0), + header_packet_size(hsize) { /* // you can specify an IP address: */ @@ -616,7 +618,8 @@ enum communicationProtocol{ nsent = recvfrom(socketDescriptor,(char*)buf+total_sent,nsending, 0, (struct sockaddr *) &clientAddress, &clientAddress_length); if(nsent < packet_size) { if(nsent){ - cout << "Incomplete Packet size " << nsent << endl; + if(nsent != header_packet_size) + cprintf(RED,"Incomplete Packet size %d\n",nsent); } break; } @@ -690,6 +693,11 @@ enum communicationProtocol{ } + + int getCurrentTotalReceived(){ + return total_sent; + } + char lastClientIP[INET_ADDRSTRLEN]; char thisClientIP[INET_ADDRSTRLEN]; int differentClients; @@ -712,7 +720,7 @@ enum communicationProtocol{ int nsending; int nsent; int total_sent; - + int header_packet_size; // pthread_mutex_t mp; diff --git a/slsReceiverSoftware/src/UDPBaseImplementation.cpp b/slsReceiverSoftware/src/UDPBaseImplementation.cpp index 8168affa4..858e968c2 100644 --- a/slsReceiverSoftware/src/UDPBaseImplementation.cpp +++ b/slsReceiverSoftware/src/UDPBaseImplementation.cpp @@ -431,7 +431,7 @@ int UDPBaseImplementation::shutDownUDPSockets(){ return OK; } -void UDPBaseImplementation::readFrame(char* c,char** raw, uint64_t &startAcquisitionIndex, uint64_t &startFrameIndex){ +void UDPBaseImplementation::readFrame(int ithread, char* c,char** raw, int64_t &startAcquisitionIndex, int64_t &startFrameIndex){ FILE_LOG(logWARNING) << __AT__ << " doing nothing..."; FILE_LOG(logERROR) << __AT__ << " must be overridden by child classes"; } diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 0e9dc9015..db81cbd61 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -159,8 +159,7 @@ void UDPStandardImplementation::initializeMembers(){ frameIndex[i] = 0; currentFrameNumber[i] = 0; frameNumberInPreviousFile[i] = -1; - lastFrameIndex[i] = 0; - lastFrameNumberInFile[i] = 0; + lastFrameNumberInFile[i] = -1; totalPacketsInFile[i] = 0; } @@ -551,7 +550,6 @@ int UDPStandardImplementation::setDynamicRange(const uint32_t i){ //set parameters depending on new dynamic range. packetsPerFrame = (tengigaEnable ? EIGER_TEN_GIGA_CONSTANT : EIGER_ONE_GIGA_CONSTANT) * dynamicRange; bufferSize = onePacketSize * packetsPerFrame; - cout<<"packetsPerFrame:"<getCurrentTotalReceived(); + //wait for all packets if(totalP!=numberOfFrames*packetsPerFrame*numberofListeningThreads){ - prev = -1; - //wait as long as there is change from prev totalP - while(prev != totalP){ + //wait as long as there is change from prev totalP, + //and also change from received in buffer to previous value + //(as one listens to many at a time, shouldnt cut off in between) + while((prev != totalP) && (prevReceivedInBuffer!= currentReceivedInBuffer)){ #ifdef DEBUG5 - cprintf(MAGENTA,"waiting for all packets totalP:%d\n",totalP); + cprintf(MAGENTA,"waiting for all packets totalP:%d currently in buffer:%d\n",totalP,currentReceivedInBuffer); + #endif usleep(5000);/* Need to find optimal time (exposure time and acquisition period) **/ prev = totalP; - totalP=0; - for(i=0; igetCurrentTotalReceived(); } } @@ -1041,7 +1049,7 @@ void UDPStandardImplementation::startReadout(){ /**make this better by asking all of it at once*/ -void UDPStandardImplementation::readFrame(int ithread, char* c,char** raw, uint64_t &startAcq, uint64_t &startFrame){ +void UDPStandardImplementation::readFrame(int ithread, char* c,char** raw, int64_t &startAcq, int64_t &startFrame){ FILE_LOG(logDEBUG) << __AT__ << " called"; //point to gui data, to let writer thread know that gui is back for data @@ -1311,20 +1319,23 @@ int UDPStandardImplementation::createUDPSockets(){ strcpy(eth,""); shutDownUDPSockets(); + int headerpacketsize = 0; + if(myDetectorType == EIGER) + headerpacketsize = EIGER_HEADER_LENGTH; //if no eth, listen to all if(!strlen(eth)){ FILE_LOG(logWARNING) << "eth is empty. Listening to all"; for(int i=0;iReceiveDataOnly(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS + cSize, (bufferSize * numberofJobsPerBuffer) - cSize); - cout<ReceiveDataOnly(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS + cSize, (bufferSize * numberofJobsPerBuffer) - cSize); + totalListeningPacketCount[ithread] += (receivedSize/onePacketSize); #ifdef MANUALDEBUG @@ -1774,32 +1788,31 @@ void UDPStandardImplementation::stopListening(int ithread, int numbytes){ } //push dummy-end buffer into fifo for all writer threads - for(int i=0; ipop(buffer[ithread]); + fifoFree[ithread]->pop(buffer[ithread]); #ifdef EVERYFIFODEBUG - if(fifoFree[ithread]->getSemValue()<100) + if(fifoFree[ithread]->getSemValue()<100) cprintf(BLUE,"FifoFree[%d]: value:%d, pop 0x%x\n",ithread,fifoFree[ithread]->getSemValue(),(void*)(buffer[ithread])); #endif #ifdef CFIFODEBUG - if(ithread == 0) - cprintf(CYAN,"Listening_Thread %d: Popped Dummy from fifoFree %p\n", ithread,(void*)(buffer[ithread])); - else - cprintf(YELLOW,"Listening_Thread %d: Popped Dummy from fifoFree %p\n", ithread,(void*)(buffer[ithread])); + if(ithread == 0) + cprintf(CYAN,"Listening_Thread %d: Popped Dummy from fifoFree %p\n", ithread,(void*)(buffer[ithread])); + else + cprintf(YELLOW,"Listening_Thread %d: Popped Dummy from fifoFree %p\n", ithread,(void*)(buffer[ithread])); #endif - //creating dummy-end buffer with pc=0xFFFF - (*((uint32_t*)(buffer[ithread]))) = dummyPacketValue; - while(!fifo[ithread]->push(buffer[ithread])); + //creating dummy-end buffer with pc=0xFFFF + (*((uint32_t*)(buffer[ithread]))) = dummyPacketValue; + while(!fifo[ithread]->push(buffer[ithread])); #ifdef EVERYFIFODEBUG - if(fifo[ithread]->getSemValue()>(fifoSize-100)) + if(fifo[ithread]->getSemValue()>(fifoSize-100)) cprintf(MAGENTA,"Fifo[%d]: value:%d, push 0x%x\n",ithread,fifo[ithread]->getSemValue(),(void*)(buffer[ithread])); #endif #ifdef CFIFODEBUG - if(ithread == 0) - cprintf(CYAN,"Listening_Thread %d: Listener pushed dummy-end buffer into fifo %p\n", ithread,(void*)(buffer[ithread])); - else - cprintf(YELLOW,"Listening_Thread %d: Listener pushed dummy-end buffer into fifo %p\n", ithread,(void*)(buffer[ithread])); + if(ithread == 0) + cprintf(CYAN,"Listening_Thread %d: Listener pushed dummy-end buffer into fifo %p\n", ithread,(void*)(buffer[ithread])); + else + cprintf(YELLOW,"Listening_Thread %d: Listener pushed dummy-end buffer into fifo %p\n", ithread,(void*)(buffer[ithread])); #endif - } + //reset mask and exit loop @@ -2061,8 +2074,9 @@ void UDPStandardImplementation::waitWritingBufferForNextAcquisition(int ithread) //pop fifo so that its empty char* temp; while(!fifo[ithread]->isEmpty()){ - cprintf(RED,"%d:emptied buffer in fifo\n", ithread); + cprintf(RED,"%d:fifo emptied\n", ithread); fifo[ithread]->pop(temp); + fifoFree[ithread]->push(temp); #ifdef EVERYFIFODEBUG if(fifo[ithread]->getSemValue()>(fifoSize-100)) cprintf(CYAN,"Fifo[%d]: value:%d, pop 0x%x\n",ithread,fifo[ithread]->getSemValue(),(void*)(temp)); @@ -2087,7 +2101,6 @@ void UDPStandardImplementation::waitWritingBufferForNextAcquisition(int ithread) if(detindex == -1) sprintf(fileNamePerThread[ithread],"%s_d%d",fileName,ithread); - cout << "file name changed to include det Id:" << fileNamePerThread[ithread] << endl; } if(dataCompressionEnable){ @@ -2189,15 +2202,34 @@ void UDPStandardImplementation::stopWriting(int ithread, char* wbuffer){ //statistics FILE_LOG(logINFO) << "Status: Run Finished"; - FILE_LOG(logINFO) << "Last Frame Number Caught:" << lastFrameIndex[ithread]; if(totalPacketsCaught < ((uint64_t)numberOfFrames*packetsPerFrame*numberofListeningThreads)){ cprintf(RED, "Total Missing Packets: %lld\n",(long long int)numberOfFrames*packetsPerFrame*numberofListeningThreads-totalPacketsCaught); cprintf(RED, "Total Packets Caught: %lld\n",(long long int)totalPacketsCaught); cprintf(RED, "Total Frames Caught: %lld\n",(long long int)(totalPacketsCaught/(packetsPerFrame*numberofListeningThreads))); + cprintf(RED, "Last Frame Number Caught: "); + int64_t lastFrameNumber = 0; + for(int i=0;i=0)){ //get start frame (required to create new file at the right juncture) uint64_t startframe =-1; if(getFrameNumber(ithread, wbuffer + offset, startframe) == FAIL){ @@ -2299,8 +2325,8 @@ cout<push(wbuffer)); return; } - cout<<"222"<=0) &&(!((lastFrameNumberInFile[ithread]+1) % maxFramesPerFile))){ createNewFile(ithread); } //frames to save in one file - nextFileFrameNumber = lastFrameNumberInFile[ithread] + - (maxFramesPerFile - (lastFrameNumberInFile[ithread]%maxFramesPerFile)); - if(!ithread) cout<push(wbuffer)); return; } - currentFrameNumber[ithread] = tempframenumber; + currentFrameNumber[ithread] = tempframenumber; + //set indices pthread_mutex_lock(&progressMutex); @@ -2648,14 +2669,15 @@ int UDPStandardImplementation::getFrameNumber(int ithread, char* wbuffer, uint64 FILE_LOG(logERROR) << "Fifo "<< ithread << ": Frame Number is zero from firmware."; return FAIL; } -//#ifdef DEBUG4 +#ifdef DEBUG4 if(!ithread) cprintf(GREEN,"Writing_Thread %d: fnum:%lld pnum:%d FPGA_fnum:%d footeroffset:%d\n", ithread, (long long int)tempframenumber, (*( (uint16_t*) footer->packetNumber)), (uint32_t)(*( (uint64_t*) footer)), footerOffset); -//#endif +#endif + tempframenumber += (startFrameIndex - 1); break; case JUNGFRAU: @@ -2666,6 +2688,7 @@ int UDPStandardImplementation::getFrameNumber(int ithread, char* wbuffer, uint64 (long long int)tempframenumber, (*( (uint8_t*) header->packetNumber))); #endif + tempframenumber += startFrameIndex; break; default: @@ -2680,7 +2703,7 @@ int UDPStandardImplementation::getFrameNumber(int ithread, char* wbuffer, uint64 (long long int)tempframenumber, pnum); #endif - + tempframenumber += startFrameIndex; break; } return OK; @@ -2694,119 +2717,103 @@ int UDPStandardImplementation::writeUptoFrameNumber(int ithread, char* wbuffer, FILE_LOG(logDEBUG) << __AT__ << " called"; - bool expectedoffsetATlastpacket = false; + int bigIncrements = onePacketSize * packetsPerFrame; //a frame at a time + if(numberofJobsPerBuffer == 1) bigIncrements = onePacketSize; //a packet at a time as we listen to only one frame in a buffer + int startoffset = offset; - if(!ithread) cout<= endoffset){ expectedoffset = startoffset + ((numpackets -1) * onePacketSize); expectedoffsetATlastpacket = true; } offset = expectedoffset; - if(!ithread) cout<push(wbuffer)); return FAIL; } - if(!ithread) cout<=nextFrameNumber){ - if(!ithread) cout<=nextFrameNumber){ - offset -= (onePacketSize*packetsPerFrame);/** its ok..if jonbsperthread is 1, go packet by packet*/ - if(!ithread) cout<push(wbuffer)); - return FAIL; - } - if(!ithread) cout<push(wbuffer)); return FAIL; } - if(!ithread) cout<push(wbuffer)); + return FAIL; + } + } + while(tempframenumberpush(wbuffer)); + return FAIL; + } + } } //if tempframenumber is too low, go forwards fast (by frame) and then slowly (by each packet) backwards else{ - if(!ithread) cout<endoffset){if(!ithread) cout<endoffset) + break; if(getFrameNumber(ithread, wbuffer + offset, tempframenumber) == FAIL){ //error in frame number sent by fpga while(!fifoFree[ithread]->push(wbuffer)); return FAIL; } - if(!ithread) cout<endoffset){ offset = endoffset; - if(!ithread) cout< end offset so offset now:"<nextFrameNumber){ - offset -= onePacketSize; - if(!ithread) cout<push(wbuffer)); return FAIL; } - if(!ithread) cout<nextFrameNumber){ + offset -= onePacketSize; + if(getFrameNumber(ithread, wbuffer + offset, tempframenumber) == FAIL){ + //error in frame number sent by fpga + while(!fifoFree[ithread]->push(wbuffer)); + return FAIL; + } } offset += onePacketSize; - if(!ithread) cout<getTotalFramesCaught(); - cout<<"frames caught sent:"<differentClients){ FILE_LOG(logDEBUG) << "Force update"; @@ -1132,8 +1131,8 @@ int slsReceiverTCPIPInterface::moench_read_frame(){ char* raw; - uint64_t startAcquisitionIndex=0; - uint64_t startFrameIndex=0; + int64_t startAcquisitionIndex=0; + int64_t startFrameIndex=0; uint32_t index = -1,bindex = 0, offset=0; strcpy(mess,"Could not read frame\n"); @@ -1153,7 +1152,7 @@ int slsReceiverTCPIPInterface::moench_read_frame(){ else{ ret = OK; - receiverBase->readFrame(fName,&raw,startAcquisitionIndex,startFrameIndex); + receiverBase->readFrame(0,fName,&raw,startAcquisitionIndex,startFrameIndex); /**send garbage with -1 index to try again*/ if (raw == NULL){ @@ -1321,8 +1320,8 @@ int slsReceiverTCPIPInterface::gotthard_read_frame(){ uint32_t index=-1,index2=0; uint32_t pindex=0,pindex2=0; uint32_t bindex=0,bindex2=0; - uint64_t startAcquisitionIndex=0; - uint64_t startFrameIndex=0; + int64_t startAcquisitionIndex=0; + int64_t startFrameIndex=0; strcpy(mess,"Could not read frame\n"); @@ -1341,7 +1340,7 @@ int slsReceiverTCPIPInterface::gotthard_read_frame(){ cout<<"haven't caught any frame yet"<readFrame(fName,&raw,startAcquisitionIndex,startFrameIndex); + receiverBase->readFrame(0,fName,&raw,startAcquisitionIndex,startFrameIndex); /**send garbage with -1 index to try again*/ if (raw == NULL){ @@ -1496,8 +1495,8 @@ int slsReceiverTCPIPInterface::propix_read_frame(){ uint32_t index=-1,index2=0; uint32_t pindex=0,pindex2=0; uint32_t bindex=0,bindex2=0; - uint64_t startAcquisitionIndex=0; - uint64_t startFrameIndex=0; + int64_t startAcquisitionIndex=0; + int64_t startFrameIndex=0; strcpy(mess,"Could not read frame\n"); @@ -1516,7 +1515,7 @@ int slsReceiverTCPIPInterface::propix_read_frame(){ cout<<"haven't caught any frame yet"<readFrame(fName,&raw,startAcquisitionIndex,startFrameIndex); + receiverBase->readFrame(0,fName,&raw,startAcquisitionIndex,startFrameIndex); /**send garbage with -1 index to try again*/ if (raw == NULL){ @@ -1634,22 +1633,27 @@ int slsReceiverTCPIPInterface::eiger_read_frame(){ char fName[MAX_STR_LENGTH]=""; int acquisitionIndex = -1; int frameIndex= -1; - uint32_t index=0; - uint32_t subframenumber=-1; + int index=0; + int subframenumber=-1; - int frameSize = EIGER_ONE_GIGA_ONE_PACKET_SIZE * packetsPerFrame; - int dataSize = EIGER_ONE_GIGA_ONE_DATA_SIZE * packetsPerFrame; + int frameSize = EIGER_ONE_GIGA_ONE_PACKET_SIZE * packetsPerFrame * EIGER_MAX_PORTS; + int dataSize = EIGER_ONE_GIGA_ONE_DATA_SIZE * packetsPerFrame * EIGER_MAX_PORTS; int oneDataSize = EIGER_ONE_GIGA_ONE_DATA_SIZE; + int onePacketSize = EIGER_ONE_GIGA_ONE_PACKET_SIZE; if(tenGigaEnable){ - frameSize = EIGER_TEN_GIGA_ONE_PACKET_SIZE * packetsPerFrame; - dataSize = EIGER_TEN_GIGA_ONE_DATA_SIZE * packetsPerFrame; + frameSize = EIGER_TEN_GIGA_ONE_PACKET_SIZE * packetsPerFrame * EIGER_MAX_PORTS; + dataSize = EIGER_TEN_GIGA_ONE_DATA_SIZE * packetsPerFrame * EIGER_MAX_PORTS; oneDataSize = EIGER_TEN_GIGA_ONE_DATA_SIZE; + onePacketSize = EIGER_TEN_GIGA_ONE_PACKET_SIZE; } char* raw; char* origVal = new char[frameSize]; char* retval = new char[dataSize]; - uint64_t startAcquisitionIndex=0; - uint64_t startFrameIndex=0; + memset(origVal,0xF,frameSize); + memset(retval,0xF,dataSize); + + int64_t startAcquisitionIndex=0; + int64_t startFrameIndex=0; strcpy(mess,"Could not read frame\n"); @@ -1674,35 +1678,40 @@ int slsReceiverTCPIPInterface::eiger_read_frame(){ else{ ret = OK; //read a frame - receiverBase->readFrame(fName,&raw,startAcquisitionIndex,startFrameIndex); - //send garbage with -1 index to try again - if (raw == NULL){ - startAcquisitionIndex = -1; + for(int i=0;ireadFrame(i,fName,&raw,startAcquisitionIndex,startFrameIndex); + //send garbage with -1 index to try again + if (raw == NULL){ + startAcquisitionIndex = -1; #ifdef VERYVERBOSE - cout<<"data not ready for gui yet"<subFrameNumber); } -#ifdef VERYVERBOSE +//#ifdef VERYVERBOSE cout << "index:" << dec << index << endl; cout << "subframenumber:" << dec << subframenumber << endl; -#endif +//#endif + - memcpy(origVal,raw,frameSize); - raw=NULL; int c1=8;//first port int c2=(frameSize/2) + 8; //second port @@ -1815,18 +1824,18 @@ int slsReceiverTCPIPInterface::eiger_read_frame(){ startFrameIndex = -1; else frameIndex = index-startFrameIndex; -#ifdef VERY_VERY_DEBUG +//#ifdef VERY_VERY_DEBUG cout << "acquisitionIndex calculated is:" << acquisitionIndex << endl; cout << "frameIndex calculated is:" << frameIndex << endl; cout << "index:" << index << endl; cout << "startAcquisitionIndex:" << startAcquisitionIndex << endl; cout << "startFrameIndex:" << startFrameIndex << endl; cout << "subframenumber:" << subframenumber << endl; -#endif +//#endif } } -#ifdef VERYVERBOSE +//#ifdef VERYVERBOSE if(frameIndex!=-1){ cout << "fName:" << fName << endl; cout << "acquisitionIndex:" << acquisitionIndex << endl; @@ -1835,7 +1844,7 @@ int slsReceiverTCPIPInterface::eiger_read_frame(){ cout << "startFrameIndex:" << startFrameIndex << endl; cout << "subframenumber:" << subframenumber << endl; } -#endif +//#endif @@ -1880,8 +1889,8 @@ int slsReceiverTCPIPInterface::jungfrau_read_frame(){ int acquisitionIndex = -1; int frameIndex= -1; int64_t currentIndex=0; - uint64_t startAcquisitionIndex=0; - uint64_t startFrameIndex=0; + int64_t startAcquisitionIndex=0; + int64_t startFrameIndex=0; strcpy(mess,"Could not read frame\n"); @@ -1919,7 +1928,7 @@ int slsReceiverTCPIPInterface::jungfrau_read_frame(){ else{ ret = OK; //read a frame - receiverBase->readFrame(fName,&raw,startAcquisitionIndex,startFrameIndex); + receiverBase->readFrame(0,fName,&raw,startAcquisitionIndex,startFrameIndex); //send garbage with -1 index to try again if (raw == NULL){ startAcquisitionIndex = -1; From 6152ca66b469703d0fa19abd6867e7efefb91e34 Mon Sep 17 00:00:00 2001 From: wang_x1 Date: Wed, 31 Aug 2016 20:55:00 +0200 Subject: [PATCH 237/474] add cmake configuration --- slsReceiverSoftware/CMakeLists.txt | 44 ++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 slsReceiverSoftware/CMakeLists.txt diff --git a/slsReceiverSoftware/CMakeLists.txt b/slsReceiverSoftware/CMakeLists.txt new file mode 100644 index 000000000..f84b0d2bc --- /dev/null +++ b/slsReceiverSoftware/CMakeLists.txt @@ -0,0 +1,44 @@ +set(SOURCES + src/MySocketTCP.cpp + src/UDPInterface.cpp + src/UDPBaseImplementation.cpp + src/UDPStandardImplementation.cpp + src/slsReceiverTCPIPInterface.cpp + src/slsReceiver.cpp + src/slsReceiverUsers.cpp + src/utilities.cpp +) + +include_directories( + include + ../slsDetectorCalibration +) + +add_library(slsReceiverStatic STATIC + ${SOURCES} + ${HEADERS} +) +set_target_properties(slsReceiverStatic PROPERTIES + ARCHIVE_OUTPUT_NAME SlsReceiver + ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin +) + +add_library(slsReceiverShared SHARED + ${SOURCES} + ${HEADERS} +) +set_target_properties(slsReceiverShared PROPERTIES + LIBRARY_OUTPUT_NAME SlsReceiver + LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin +) + +add_executable(slsReceiver + src/main.cpp +) +set_target_properties(slsReceiver PROPERTIES + RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin +) +target_link_libraries(slsReceiver + slsReceiverShared + pthread +) From eea2809136e1c1e5c0d9fdc9d06a1b86d5a89a89 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Thu, 1 Sep 2016 11:22:28 +0200 Subject: [PATCH 238/474] in between --- .../src/UDPStandardImplementation.cpp | 36 ++++++++---------- .../src/slsReceiverTCPIPInterface.cpp | 38 ++++++++++--------- 2 files changed, 36 insertions(+), 38 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index db81cbd61..df0b7ccf9 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -727,7 +727,7 @@ int UDPStandardImplementation::setDetectorType(const detectorType d){ frameIndexMask = EIGER_FRAME_INDEX_MASK; frameIndexOffset = EIGER_FRAME_INDEX_OFFSET; packetIndexMask = EIGER_PACKET_INDEX_MASK; - maxFramesPerFile = 5;//EIGER_MAX_FRAMES_PER_FILE; + maxFramesPerFile = EIGER_MAX_FRAMES_PER_FILE; fifoSize = EIGER_FIFO_SIZE; fifoDepth = EIGER_FIFO_SIZE; footerOffset = EIGER_PACKET_HEADER_SIZE + oneDataSize; @@ -1655,7 +1655,7 @@ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int cSize, ch if(status != TRANSMITTING) receivedSize = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS + cSize, (bufferSize * numberofJobsPerBuffer) - cSize); //eiger returns 0 when header packet caught - if(!receivedSize && status != TRANSMITTING) + while(receivedSize < onePacketSize && status != TRANSMITTING) receivedSize = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS + cSize, (bufferSize * numberofJobsPerBuffer) - cSize); totalListeningPacketCount[ithread] += (receivedSize/onePacketSize); @@ -2206,28 +2206,24 @@ void UDPStandardImplementation::stopWriting(int ithread, char* wbuffer){ cprintf(RED, "Total Missing Packets: %lld\n",(long long int)numberOfFrames*packetsPerFrame*numberofListeningThreads-totalPacketsCaught); cprintf(RED, "Total Packets Caught: %lld\n",(long long int)totalPacketsCaught); cprintf(RED, "Total Frames Caught: %lld\n",(long long int)(totalPacketsCaught/(packetsPerFrame*numberofListeningThreads))); - cprintf(RED, "Last Frame Number Caught: "); int64_t lastFrameNumber = 0; for(int i=0;i=0)){ //get start frame (required to create new file at the right juncture) uint64_t startframe =-1; + //cout<<"getting start frame number"<push(wbuffer)); return; } - + //cout<<"done getting start frame number"<push(wbuffer)); @@ -2752,7 +2748,7 @@ int UDPStandardImplementation::writeUptoFrameNumber(int ithread, char* wbuffer, while(tempframenumber>=nextFrameNumber){ offset -= bigIncrements; if(offsetpush(wbuffer)); @@ -2760,7 +2756,7 @@ int UDPStandardImplementation::writeUptoFrameNumber(int ithread, char* wbuffer, } } if(offsetpush(wbuffer)); @@ -2768,7 +2764,7 @@ int UDPStandardImplementation::writeUptoFrameNumber(int ithread, char* wbuffer, } } while(tempframenumberpush(wbuffer)); @@ -2782,7 +2778,7 @@ int UDPStandardImplementation::writeUptoFrameNumber(int ithread, char* wbuffer, while(tempframenumberendoffset) - break; + break;//cout<<"frame number at going forwards fast"<push(wbuffer)); @@ -2790,7 +2786,7 @@ int UDPStandardImplementation::writeUptoFrameNumber(int ithread, char* wbuffer, } } if(offset>endoffset){ - offset = endoffset; + offset = endoffset;//cout<<"frame number at offset>endoffset"<push(wbuffer)); @@ -2798,7 +2794,7 @@ int UDPStandardImplementation::writeUptoFrameNumber(int ithread, char* wbuffer, } } while(tempframenumber>nextFrameNumber){ - offset -= onePacketSize; + offset -= onePacketSize;//cout<<"frame number at going bacckwards slow"<push(wbuffer)); @@ -2814,7 +2810,7 @@ int UDPStandardImplementation::writeUptoFrameNumber(int ithread, char* wbuffer, fwrite(wbuffer + startoffset, 1, offset-startoffset, sfilefd[ithread]); numPacketsWritten += ((offset-startoffset)/onePacketSize); lastFrameNumberInFile[ithread] = frameNumberWritten; - + //cout<<"done with writeUptoFrameNumber" << endl; return OK; } diff --git a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp index 6c8092c4c..abb1308e8 100644 --- a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp +++ b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp @@ -1685,9 +1685,25 @@ int slsReceiverTCPIPInterface::eiger_read_frame(){ startAcquisitionIndex = -1; #ifdef VERYVERBOSE cout<<"data not ready for gui yet"<subFrameNumber); + } +#ifdef VERYVERBOSE + cout << "index:" << dec << index << endl; + if(index>10000) exit(-1); + cout << "subframenumber:" << dec << subframenumber << endl; +#endif + memcpy(((char*)origVal)+(i*onePacketSize*packetsPerFrame),raw,(frameSize/EIGER_MAX_PORTS)); raw=NULL; } @@ -1696,20 +1712,6 @@ int slsReceiverTCPIPInterface::eiger_read_frame(){ if(startAcquisitionIndex != -1){ //cout<<"**** got proper frame ******"<subFrameNumber); - } - -//#ifdef VERYVERBOSE - cout << "index:" << dec << index << endl; - cout << "subframenumber:" << dec << subframenumber << endl; -//#endif @@ -1824,18 +1826,18 @@ int slsReceiverTCPIPInterface::eiger_read_frame(){ startFrameIndex = -1; else frameIndex = index-startFrameIndex; -//#ifdef VERY_VERY_DEBUG +#ifdef VERY_VERY_DEBUG cout << "acquisitionIndex calculated is:" << acquisitionIndex << endl; cout << "frameIndex calculated is:" << frameIndex << endl; cout << "index:" << index << endl; cout << "startAcquisitionIndex:" << startAcquisitionIndex << endl; cout << "startFrameIndex:" << startFrameIndex << endl; cout << "subframenumber:" << subframenumber << endl; -//#endif +#endif } } -//#ifdef VERYVERBOSE +#ifdef VERYVERBOSE if(frameIndex!=-1){ cout << "fName:" << fName << endl; cout << "acquisitionIndex:" << acquisitionIndex << endl; @@ -1844,7 +1846,7 @@ int slsReceiverTCPIPInterface::eiger_read_frame(){ cout << "startFrameIndex:" << startFrameIndex << endl; cout << "subframenumber:" << subframenumber << endl; } -//#endif +#endif From 5b3ab9a2b4e3ab8c8d6889862d4a2271c5396bd2 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Thu, 1 Sep 2016 13:34:02 +0200 Subject: [PATCH 239/474] soewhere --- .../src/UDPStandardImplementation.cpp | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index df0b7ccf9..4ba857b2c 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1660,7 +1660,7 @@ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int cSize, ch totalListeningPacketCount[ithread] += (receivedSize/onePacketSize); -#ifdef MANUALDEBUG +//#ifdef MANUALDEBUG if(receivedSize>0){ if(myDetectorType == JUNGFRAU){ jfrau_packet_header_t* header; @@ -1681,7 +1681,7 @@ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int cSize, ch (uint32_t)(*( (uint64_t*) footer))); } } -#endif +//#endif #ifdef DEBUG cprintf(BLUE, "Listening_Thread %d : Received bytes: %d. Expected bytes: %d\n", ithread, receivedSize, bufferSize * numberofJobsPerBuffer-cSize); #endif @@ -2309,20 +2309,20 @@ void UDPStandardImplementation::writeFileWithoutCompression(int ithread, char* w int offset = HEADER_SIZE_NUM_TOT_PACKETS; uint64_t nextFileFrameNumber; int packetsWritten = 0; - + //if(ithread) cout<<"numpackets:"<=0)){ //get start frame (required to create new file at the right juncture) uint64_t startframe =-1; - //cout<<"getting start frame number"<push(wbuffer)); return; } - //cout<<"done getting start frame number"<push(wbuffer)); @@ -2748,7 +2748,7 @@ int UDPStandardImplementation::writeUptoFrameNumber(int ithread, char* wbuffer, while(tempframenumber>=nextFrameNumber){ offset -= bigIncrements; if(offsetpush(wbuffer)); @@ -2756,7 +2756,7 @@ int UDPStandardImplementation::writeUptoFrameNumber(int ithread, char* wbuffer, } } if(offsetpush(wbuffer)); @@ -2764,7 +2764,7 @@ int UDPStandardImplementation::writeUptoFrameNumber(int ithread, char* wbuffer, } } while(tempframenumberpush(wbuffer)); @@ -2778,7 +2778,7 @@ int UDPStandardImplementation::writeUptoFrameNumber(int ithread, char* wbuffer, while(tempframenumberendoffset) - break;//cout<<"frame number at going forwards fast"<push(wbuffer)); @@ -2786,7 +2786,7 @@ int UDPStandardImplementation::writeUptoFrameNumber(int ithread, char* wbuffer, } } if(offset>endoffset){ - offset = endoffset;//cout<<"frame number at offset>endoffset"<endoffset f#:"<push(wbuffer)); @@ -2794,7 +2794,7 @@ int UDPStandardImplementation::writeUptoFrameNumber(int ithread, char* wbuffer, } } while(tempframenumber>nextFrameNumber){ - offset -= onePacketSize;//cout<<"frame number at going bacckwards slow"<push(wbuffer)); @@ -2810,7 +2810,7 @@ int UDPStandardImplementation::writeUptoFrameNumber(int ithread, char* wbuffer, fwrite(wbuffer + startoffset, 1, offset-startoffset, sfilefd[ithread]); numPacketsWritten += ((offset-startoffset)/onePacketSize); lastFrameNumberInFile[ithread] = frameNumberWritten; - //cout<<"done with writeUptoFrameNumber" << endl; + //if(ithread) cout<<"done with writeUptoFrameNumber" << endl; return OK; } From 4eceb3b5f76ec26140d22a831c375822cf32d240 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Fri, 2 Sep 2016 15:47:28 +0200 Subject: [PATCH 240/474] kinda --- .../include/UDPStandardImplementation.h | 8 +- .../src/UDPBaseImplementation.cpp | 1 + .../src/UDPStandardImplementation.cpp | 221 +++++++++--------- .../src/slsReceiverTCPIPInterface.cpp | 36 +-- 4 files changed, 139 insertions(+), 127 deletions(-) diff --git a/slsReceiverSoftware/include/UDPStandardImplementation.h b/slsReceiverSoftware/include/UDPStandardImplementation.h index b17882baa..b043eeedf 100644 --- a/slsReceiverSoftware/include/UDPStandardImplementation.h +++ b/slsReceiverSoftware/include/UDPStandardImplementation.h @@ -220,6 +220,8 @@ class UDPStandardImplementation: private virtual slsReceiverDefs, public UDPBase */ void readFrame(int ithread, char* c,char** raw, int64_t &startAcq, int64_t &startFrame); + + void resetGuiPointer(int ithread); /** * Overridden method * Closes file / all files(data compression involves multiple files) @@ -456,8 +458,9 @@ private: * Uses semaphore for nth frame mode * @param ithread writer thread index * @param buffer buffer to copy + * @param numpackets number of packets to copy */ - void copyFrameToGui(int ithread, char* buffer); + void copyFrameToGui(int ithread, char* buffer, uint32_t numpackets); void waitWritingBufferForNextAcquisition(int ithread); @@ -589,6 +592,9 @@ private: /** packets in current file */ uint64_t totalPacketsInFile[MAX_NUMBER_OF_WRITER_THREADS]; + /**Total packet count written by each writing thread */ + uint64_t totalWritingPacketCount[MAX_NUMBER_OF_LISTENING_THREADS]; + diff --git a/slsReceiverSoftware/src/UDPBaseImplementation.cpp b/slsReceiverSoftware/src/UDPBaseImplementation.cpp index 858e968c2..d4bbbcfbd 100644 --- a/slsReceiverSoftware/src/UDPBaseImplementation.cpp +++ b/slsReceiverSoftware/src/UDPBaseImplementation.cpp @@ -436,6 +436,7 @@ void UDPBaseImplementation::readFrame(int ithread, char* c,char** raw, int64_t & FILE_LOG(logERROR) << __AT__ << " must be overridden by child classes"; } + //FIXME: needed, isnt stopReceiver enough? void UDPBaseImplementation::abort(){ FILE_LOG(logWARNING) << __AT__ << " doing nothing..."; diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 4ba857b2c..7f649d5c3 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -161,6 +161,7 @@ void UDPStandardImplementation::initializeMembers(){ frameNumberInPreviousFile[i] = -1; lastFrameNumberInFile[i] = -1; totalPacketsInFile[i] = 0; + totalWritingPacketCount[i] = 0; } @@ -849,6 +850,7 @@ int UDPStandardImplementation::startReceiver(char *c){ //reset file parameters lastFrameNumberInFile[i] = -1; totalPacketsInFile[i] = 0; + totalWritingPacketCount[i] = 0; if(sfilefd[i]){ fclose(sfilefd[i]); sfilefd[i] = NULL; @@ -1015,7 +1017,7 @@ void UDPStandardImplementation::startReadout(){ //wait as long as there is change from prev totalP, //and also change from received in buffer to previous value //(as one listens to many at a time, shouldnt cut off in between) - while((prev != totalP) && (prevReceivedInBuffer!= currentReceivedInBuffer)){ + while((prev != totalP) || (prevReceivedInBuffer!= currentReceivedInBuffer)){ #ifdef DEBUG5 cprintf(MAGENTA,"waiting for all packets totalP:%d currently in buffer:%d\n",totalP,currentReceivedInBuffer); @@ -1031,7 +1033,12 @@ void UDPStandardImplementation::startReadout(){ currentReceivedInBuffer = 0; for(i=0; igetCurrentTotalReceived(); +#ifdef DEBUG5 + cprintf(MAGENTA,"\tupdated: totalP:%d currently in buffer:%d\n",totalP,currentReceivedInBuffer); + +#endif } + } //set status @@ -1080,6 +1087,7 @@ void UDPStandardImplementation::readFrame(int ithread, char* c,char** raw, int64 cprintf(CYAN,"Info: gui data ready\n"); #endif *raw = guiData[ithread]; + guiData[ithread] = NULL; //for nth frame to gui, post semaphore so writer stops waiting @@ -1097,7 +1105,25 @@ void UDPStandardImplementation::readFrame(int ithread, char* c,char** raw, int64 } } +/* +void UDPStandardImplementation::resetGuiPointer(int ithread){ + FILE_LOG(logDEBUG) << __AT__ << " called"; + guiData[ithread] = NULL; + + //for nth frame to gui, post semaphore so writer stops waiting + if((FrameToGuiFrequency) && (writerThreadsMask)){ +#ifdef DEBUG4 + cprintf(CYAN,"Info: gonna post\n"); +#endif + //release after getting data + sem_post(&writerGuiSemaphore[ithread]); + } +#ifdef DEBUG4 + cprintf(CYAN,"Info: done post\n"); +#endif +} +*/ void UDPStandardImplementation::closeFile(int ithread){ FILE_LOG(logDEBUG) << __AT__ << " called for " << ithread ; @@ -1408,7 +1434,7 @@ int UDPStandardImplementation::createNewFile(int ithread){ FILE_LOG(logDEBUG) << __AT__ << " called"; int index = 0; - if(packetsCaught) + if(totalWritingPacketCount[ithread]) index = frameIndex[ithread]; //create file name @@ -1445,7 +1471,7 @@ int UDPStandardImplementation::createNewFile(int ithread){ //Print packet loss and filenames - if(!packetsCaught){ + if(!totalWritingPacketCount[ithread]){ frameNumberInPreviousFile[ithread] = -1; cout << "Thread " << ithread << " File:" << completeFileName[ithread] << endl; }else{ @@ -1458,7 +1484,8 @@ int UDPStandardImplementation::createNewFile(int ithread){ << "\tPacket Loss: " << setw(4)<0){ if(myDetectorType == JUNGFRAU){ jfrau_packet_header_t* header; @@ -1681,7 +1708,7 @@ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int cSize, ch (uint32_t)(*( (uint64_t*) footer))); } } -//#endif +#endif #ifdef DEBUG cprintf(BLUE, "Listening_Thread %d : Received bytes: %d. Expected bytes: %d\n", ithread, receivedSize, bufferSize * numberofJobsPerBuffer-cSize); #endif @@ -2202,31 +2229,33 @@ void UDPStandardImplementation::stopWriting(int ithread, char* wbuffer){ //statistics FILE_LOG(logINFO) << "Status: Run Finished"; - if(totalPacketsCaught < ((uint64_t)numberOfFrames*packetsPerFrame*numberofListeningThreads)){ - cprintf(RED, "Total Missing Packets: %lld\n",(long long int)numberOfFrames*packetsPerFrame*numberofListeningThreads-totalPacketsCaught); - cprintf(RED, "Total Packets Caught: %lld\n",(long long int)totalPacketsCaught); - cprintf(RED, "Total Frames Caught: %lld\n",(long long int)(totalPacketsCaught/(packetsPerFrame*numberofListeningThreads))); - int64_t lastFrameNumber = 0; - for(int i=0;i= packetsPerFrame)/**needs to be reworked*/ - copyFrameToGui(ithread, wbuffer); + //if(npackets >= (packetsPerFrame/numberofListeningThreads)) + if(npackets) + copyFrameToGui(ithread, wbuffer,npackets); #ifdef DEBUG4 cprintf(GREEN,"Writing_Thread: Copied frame\n"); #endif @@ -2331,6 +2361,7 @@ void UDPStandardImplementation::writeFileWithoutCompression(int ithread, char* w //update stats numpackets -= packetsWritten; totalPacketsInFile[ithread] += packetsWritten; + totalWritingPacketCount[ithread] += packetsWritten; pthread_mutex_lock(&writeMutex); packetsCaught += packetsWritten; totalPacketsCaught += packetsWritten; @@ -2342,9 +2373,9 @@ void UDPStandardImplementation::writeFileWithoutCompression(int ithread, char* w while(numpackets){ //new file //create new file only if something has been written and modulus works - if((lastFrameNumberInFile[ithread]>=0) &&(!((lastFrameNumberInFile[ithread]+1) % maxFramesPerFile))){ + if((lastFrameNumberInFile[ithread]>=0) &&(!((lastFrameNumberInFile[ithread]+1) % maxFramesPerFile))) createNewFile(ithread); - } + //frames to save in one file nextFileFrameNumber = (lastFrameNumberInFile[ithread]+1) + @@ -2357,6 +2388,7 @@ void UDPStandardImplementation::writeFileWithoutCompression(int ithread, char* w //update stats numpackets -= packetsWritten; totalPacketsInFile[ithread] += packetsWritten; + totalWritingPacketCount[ithread] += packetsWritten; pthread_mutex_lock(&writeMutex); packetsCaught += packetsWritten; totalPacketsCaught += packetsWritten; @@ -2378,8 +2410,10 @@ void UDPStandardImplementation::writeFileWithoutCompression(int ithread, char* w return; } totalPacketsInFile[ithread] += numpackets; + totalWritingPacketCount[ithread] += numpackets; lastFrameNumberInFile[ithread] = finalLastFrameNumberToSave; currentFrameNumber[ithread] = finalLastFrameNumberToSave; + } if(numberofWriterThreads > 1) pthread_mutex_lock(&writeMutex); @@ -2447,7 +2481,7 @@ void UDPStandardImplementation::updateFileHeader(int ithread){ } -void UDPStandardImplementation::copyFrameToGui(int ithread, char* buffer){ +void UDPStandardImplementation::copyFrameToGui(int ithread, char* buffer, uint32_t numpackets){ FILE_LOG(logDEBUG) << __AT__ << " called"; @@ -2475,7 +2509,7 @@ void UDPStandardImplementation::copyFrameToGui(int ithread, char* buffer){ #ifdef DEBUG4 cprintf(GREEN,"Writing_Thread: CopyingFrame: guidataready is 0, Copying data\n"); #endif - memcpy(latestData[ithread],buffer + HEADER_SIZE_NUM_TOT_PACKETS,bufferSize); + memcpy(latestData[ithread],buffer , numpackets*onePacketSize); strcpy(guiFileName[ithread],completeFileName[ithread]); guiDataReady[ithread]=1; pthread_mutex_unlock(&dataReadyMutex); @@ -2612,6 +2646,7 @@ void UDPStandardImplementation::handleDataCompression(int ithread, char* wbuffer #ifndef ALLFILE totalPacketsInFile[ithread] += (bufferSize/packetsPerFrame); + totalWritingPacketCount[ithread] += (bufferSize/packetsPerFrame); pthread_mutex_lock(&writeMutex); if((packetsCaught%packetsPerFrame) >= (uint32_t)maxFramesPerFile) createNewFile(ithread); @@ -2622,7 +2657,7 @@ void UDPStandardImplementation::handleDataCompression(int ithread, char* wbuffer #endif if(!once){ - copyFrameToGui(ithread, buff[0]); + copyFrameToGui(ithread, buff[0],(uint32_t)packetsPerFrame); once = 1; } } @@ -2662,7 +2697,6 @@ int UDPStandardImplementation::getFrameNumber(int ithread, char* wbuffer, uint64 if(!((uint32_t)(*( (uint64_t*) footer)))){ tempframenumber = -1; FILE_LOG(logERROR) << "Fifo "<< ithread << ": Frame Number is zero from firmware."; - exit(-1); return FAIL; } #ifdef DEBUG4 @@ -2713,103 +2747,66 @@ int UDPStandardImplementation::writeUptoFrameNumber(int ithread, char* wbuffer, FILE_LOG(logDEBUG) << __AT__ << " called"; //if(ithread) cout<<"at writeUptoFrameNumber " << nextFrameNumber<< endl; - int bigIncrements = onePacketSize * packetsPerFrame; //a frame at a time - if(numberofJobsPerBuffer == 1) bigIncrements = onePacketSize; //a packet at a time as we listen to only one frame in a buffer int startoffset = offset; int endoffset = startoffset + numpackets * onePacketSize; - - int expectedoffset = startoffset + ((nextFrameNumber - (lastFrameNumberInFile[ithread]+1)) * onePacketSize * packetsPerFrame); - bool expectedoffsetATlastpacket = false; - if(expectedoffset >= endoffset){ - expectedoffset = startoffset + ((numpackets -1) * onePacketSize); - expectedoffsetATlastpacket = true; - } - offset = expectedoffset; - - - //get frame number at expected offset uint64_t tempframenumber=-1; - uint64_t frameNumberWritten=-1;//if(ithread) cout<<"frame number at expected ofset"<push(wbuffer)); return FAIL; } + //last packet's frame number < nextframenumber + if(tempframenumber=nextFrameNumber){ - while(tempframenumber>=nextFrameNumber){ - offset -= bigIncrements; - if(offsetpush(wbuffer)); - return FAIL; - } - } - if(offsetpush(wbuffer)); - return FAIL; - } - } - while(tempframenumberpush(wbuffer)); - return FAIL; - } - } + + //somewhere in between + int bigIncrements = onePacketSize * packetsPerFrame * 10; //10 frames at a time + if(numberofJobsPerBuffer == 1) bigIncrements = onePacketSize; //a packet at a time as we listen to only one frame in a buffer + + cout<=nextFrameNumber){ + offset -= bigIncrements; + if(offsetpush(wbuffer)); + return FAIL; } - - //if tempframenumber is too low, go forwards fast (by frame) and then slowly (by each packet) backwards - else{ - while(tempframenumberendoffset) - break;//if(ithread) cout<<"frame number at going forwards fast f#:"<push(wbuffer)); - return FAIL; - } - } - if(offset>endoffset){ - offset = endoffset;//if(ithread) cout<<"frame number at offset>endoffset f#:"<push(wbuffer)); - return FAIL; - } - } - while(tempframenumber>nextFrameNumber){ - offset -= onePacketSize;//if(ithread) cout<<"frame number at going bacckwards slow f#:"<push(wbuffer)); - return FAIL; - } - } - offset += onePacketSize; + } + if(offsetpush(wbuffer)); + return FAIL; + } + } + while(tempframenumberpush(wbuffer)); + return FAIL; } - frameNumberWritten = nextFrameNumber-1; } fwrite(wbuffer + startoffset, 1, offset-startoffset, sfilefd[ithread]); numPacketsWritten += ((offset-startoffset)/onePacketSize); - lastFrameNumberInFile[ithread] = frameNumberWritten; + lastFrameNumberInFile[ithread] = (nextFrameNumber-1); //if(ithread) cout<<"done with writeUptoFrameNumber" << endl; return OK; } diff --git a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp index abb1308e8..500db2988 100644 --- a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp +++ b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp @@ -1164,7 +1164,7 @@ int slsReceiverTCPIPInterface::moench_read_frame(){ else{ bindex = ((uint32_t)(*((uint32_t*)raw))); - memcpy(origVal,raw,bufferSize); + memcpy(origVal,raw + HEADER_SIZE_NUM_TOT_PACKETS,bufferSize); raw=NULL; //************** packet number order********************** @@ -1369,7 +1369,7 @@ int slsReceiverTCPIPInterface::gotthard_read_frame(){ #endif } - memcpy(origVal,raw,bufferSize); + memcpy(origVal,raw + HEADER_SIZE_NUM_TOT_PACKETS,bufferSize); raw=NULL; @@ -1535,7 +1535,7 @@ int slsReceiverTCPIPInterface::propix_read_frame(){ cout << "index2:" << hex << index << endl; #endif - memcpy(origVal,raw,bufferSize); + memcpy(origVal,raw + HEADER_SIZE_NUM_TOT_PACKETS,bufferSize); raw=NULL; /*//ignore if half frame is missing @@ -1649,8 +1649,8 @@ int slsReceiverTCPIPInterface::eiger_read_frame(){ char* raw; char* origVal = new char[frameSize]; char* retval = new char[dataSize]; - memset(origVal,0xF,frameSize); - memset(retval,0xF,dataSize); + memset(origVal,0xFF,frameSize); + memset(retval,0xFF,dataSize); int64_t startAcquisitionIndex=0; int64_t startFrameIndex=0; @@ -1677,6 +1677,9 @@ int slsReceiverTCPIPInterface::eiger_read_frame(){ // acq started else{ ret = OK; + int fnum[EIGER_MAX_PORTS]; + for(int i=0;ireadFrame(i,fName,&raw,startAcquisitionIndex,startFrameIndex); @@ -1684,27 +1687,28 @@ int slsReceiverTCPIPInterface::eiger_read_frame(){ if (raw == NULL){ startAcquisitionIndex = -1; #ifdef VERYVERBOSE - cout<<"data not ready for gui yet"<subFrameNumber); } #ifdef VERYVERBOSE cout << "index:" << dec << index << endl; - if(index>10000) exit(-1); cout << "subframenumber:" << dec << subframenumber << endl; #endif - - memcpy(((char*)origVal)+(i*onePacketSize*packetsPerFrame),raw,(frameSize/EIGER_MAX_PORTS)); + int numpackets = (uint32_t)(*( (uint32_t*) raw)); + memcpy(((char*)origVal)+(i*onePacketSize*packetsPerFrame),raw + HEADER_SIZE_NUM_TOT_PACKETS,numpackets*onePacketSize); raw=NULL; } } @@ -1712,8 +1716,12 @@ int slsReceiverTCPIPInterface::eiger_read_frame(){ if(startAcquisitionIndex != -1){ //cout<<"**** got proper frame ******"<resetGuiPointer(i); - + if(fnum[0]!=fnum[1]) + cprintf(BG_RED,"Fnums differ %d and %d\n",fnum[0],fnum[1]); int c1=8;//first port int c2=(frameSize/2) + 8; //second port @@ -1942,7 +1950,7 @@ int slsReceiverTCPIPInterface::jungfrau_read_frame(){ //proper frame else{ //cout<<"**** got proper frame ******"< Date: Mon, 5 Sep 2016 10:09:49 +0200 Subject: [PATCH 241/474] in between --- .../include/UDPStandardImplementation.h | 41 ++++- .../src/UDPStandardImplementation.cpp | 166 ++++++++++++++++-- 2 files changed, 190 insertions(+), 17 deletions(-) diff --git a/slsReceiverSoftware/include/UDPStandardImplementation.h b/slsReceiverSoftware/include/UDPStandardImplementation.h index b043eeedf..6674c62d9 100644 --- a/slsReceiverSoftware/include/UDPStandardImplementation.h +++ b/slsReceiverSoftware/include/UDPStandardImplementation.h @@ -289,6 +289,12 @@ private: /************************************************************************* * Listening and Writing Threads ***************************************** *************************************************************************/ + /** + * Create Data Call Back Threads + * @param destroy is true to destroy all the threads + * @return OK or FAIL + */ + int createDataCallbackThreads(bool destroy = false); /** * Create Listening Threads @@ -303,6 +309,9 @@ private: */ int createWriterThreads(bool destroy = false); + + + /** * Set Thread Priorities */ @@ -336,6 +345,12 @@ private: */ int createCompressionFile(int ithread, int iframe); + /** + * Static function - Starts Data Callback Thread of this object + * @param this_pointer pointer to this object + */ + static void* startDataCallbackThread(void *this_pointer); + /** * Static function - Starts Listening Thread of this object * @param this_pointer pointer to this object @@ -348,6 +363,11 @@ private: */ static void* startWritingThread(void *this_pointer); + /** + * Thread that sends data packets to client + */ + void startDataCallback(); + /** * Thread that listens to packets * It pops the fifofree for free addresses, listens to packets and pushes them into the fifo @@ -652,6 +672,24 @@ private: + //***data call back thread parameters*** + /** Number of data callback Threads */ + int numberofDataCallbackThreads; + + /** Data Callback Threads */ + pthread_t dataCallbackThreads[MAX_NUMBER_OF_LISTENING_THREADS]; + + /** Semaphores Synchronizing DataCallback Threads */ + sem_t dataCallbackSemaphore[MAX_NUMBER_OF_LISTENING_THREADS]; + + /** Mask with each bit indicating status of each data callback thread */ + volatile uint32_t dataCallbackThreadsMask; + + /** Set to self-terminate data callback threads waiting for semaphores */ + bool killAllDataCallbackThreads; + + bool dataCallbackEnabled; + //***general and listening thread parameters*** /** Ensures if threads created successfully */ @@ -669,9 +707,6 @@ private: /** Semaphores Synchronizing Listening Threads */ sem_t listenSemaphore[MAX_NUMBER_OF_LISTENING_THREADS]; - /** Current Listening Thread Index*/ - int currentListeningThreadIndex; - /** Mask with each bit indicating status of each listening thread */ volatile uint32_t listeningThreadsMask; diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 7f649d5c3..983fd1fb8 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -186,6 +186,12 @@ void UDPStandardImplementation::initializeMembers(){ frametoGuiCounter[i] = 0; } + //***data callback thread parameters*** + numberofDataCallbackThreads = 1; + dataCallbackThreadsMask = 0x0; + killAllDataCallbackThreads = false; + dataCallbackEnabled = true; /**false*/ + //***general and listening thread parameters*** threadStarted = false; currentThreadIndex = -1; @@ -767,14 +773,17 @@ int UDPStandardImplementation::setDetectorType(const detectorType d){ //delete threads and set number of listening threads if(myDetectorType == EIGER){ pthread_mutex_lock(&statusMutex); + dataCallbackThreadsMask = 0x0; listeningThreadsMask = 0x0; writerThreadsMask = 0x0; pthread_mutex_unlock(&(statusMutex)); if(threadStarted){ createListeningThreads(true); + createDataCallbackThreads(true); createWriterThreads(true); } numberofListeningThreads = MAX_NUMBER_OF_LISTENING_THREADS; + numberofDataCallbackThreads = MAX_NUMBER_OF_LISTENING_THREADS; numberofWriterThreads = MAX_NUMBER_OF_WRITER_THREADS; } @@ -793,7 +802,8 @@ int UDPStandardImplementation::setDetectorType(const detectorType d){ //updates File Header if(myDetectorType == EIGER){ for(int i=0; istartDataCallback(); + return this_pointer; +} + + + void* UDPStandardImplementation::startListeningThread(void* this_pointer){ FILE_LOG(logDEBUG) << __AT__ << " called"; ((UDPStandardImplementation*)this_pointer)->startListening(); @@ -1560,6 +1643,62 @@ void* UDPStandardImplementation::startWritingThread(void* this_pointer){ +void UDPStandardImplementation::startDataCallback(){ + FILE_LOG(logDEBUG) << __AT__ << " called"; + + //set current thread value index + int ithread = currentThreadIndex; + //let calling function know thread started and obtained current + threadStarted = 1; + char* buffer; + // server address to bind + const char *hostName = "tcp://127.0.0.1:70001";/**increment this by ithread and detid*/ + + /* outer loop - loops once for each acquisition */ + //infinite loop, exited only to change dynamic range, 10G parameters etc (then recreated again) + while(true){ + + void *context = zmq_ctx_new(); + // create a publisher + socket = zmq_socket(context, ZMQ_PUB); + // bind + zmq_bind(socket,hostName);/**increment this by 1*/ + + /* inner loop - loop for each buffer */ + //until mask reset (udp sockets shut down by client) + while((1 << ithread) & dataCallbackThreadsMask){ + + //wait for data + sem_wait(&dataCallbackSemaphore[ithread]); + if(status == TRANSMITTING) + continue; + int numpackets = (uint32_t)(*( (uint32_t*) latestData)); /*latestdata should be size of one buffer*/ + memcpy(buffer, latestData, numpackets*onePacketSize);/**read first bytes to get numpackets*/ + + /*check if it should be added to previous (processlistening buffer for datacompression)*/ + + zmq_send(socket, buffer.data(), buffer.size(), 0); + + }/*--end of loop for each buffer (inner loop)*/ + + //end of acquisition, wait for next acquisition/change of parameters + sem_wait(&dataCallbackSemaphore[ithread]); + + //check to exit thread (for change of parameters) - only EXIT possibility + if(killAllDataCallbackThreads){ + cprintf(BLUE,"DataCallback_Thread %d:Goodbye!\n",ithread); + //free resources at exit + zmq_unbind(socket, hostName); + zmq_close(socket); + zmq_ctx_destroy(context); + pthread_exit(NULL); + } + + }/*--end of loop for each acquisition (outer loop) */ + +} + + void UDPStandardImplementation::startListening(){ @@ -2222,6 +2361,8 @@ void UDPStandardImplementation::stopWriting(int ithread, char* wbuffer){ //ensure listening threads done before updating status as it returns to client (from stopReceiver) while(listeningThreadsMask) usleep(5000); + while(dataCallbackThreadsMask) + usleep(5000); //update status pthread_mutex_lock(&statusMutex); status = RUN_FINISHED; @@ -2485,22 +2626,19 @@ void UDPStandardImplementation::copyFrameToGui(int ithread, char* buffer, uint32 FILE_LOG(logDEBUG) << __AT__ << " called"; - //random read (gui not ready) - //need to toggle guiDataReady or the second frame wont be copied - if((!FrameToGuiFrequency) && (!guiData[ithread])){ -#ifdef DEBUG4 - cprintf(GREEN,"Writing_Thread: CopyingFrame: Resetting guiDataReady\n"); -#endif - pthread_mutex_lock(&dataReadyMutex); - guiDataReady[ithread]=0; - pthread_mutex_unlock(&dataReadyMutex); - } //if nthe frame, wait for your turn (1st frame always shown as its zero) - else if(FrameToGuiFrequency && ((frametoGuiCounter[ithread])%FrameToGuiFrequency)); + if(FrameToGuiFrequency && ((frametoGuiCounter[ithread])%FrameToGuiFrequency)); //random read (gui ready) or nth frame read: gui needs data now or it is the first frame else{ + + //tell datacallback to pick up data + sem_post(&dataCallbackSemaphore[ithread]); + + + memcpy(latestData[ithread],buffer , numpackets*onePacketSize); + #ifdef DEBUG4 cprintf(GREEN,"Writing_Thread: CopyingFrame: Gui needs data now OR 1st frame\n"); #endif From 3ed738b9491d6864fe6c095ffcde76e0389cb1a5 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Fri, 9 Sep 2016 17:52:07 +0200 Subject: [PATCH 242/474] almost done --- slsReceiverSoftware/Makefile | 15 +- .../include/UDPStandardImplementation.h | 32 +- slsReceiverSoftware/include/genericSocket.h | 1 + slsReceiverSoftware/include/libzmq.a | Bin 0 -> 2389564 bytes slsReceiverSoftware/include/zmq.h | 416 ++++++++++++++++++ .../src/UDPStandardImplementation.cpp | 402 +++++++++-------- .../src/slsReceiverTCPIPInterface.cpp | 79 +++- 7 files changed, 743 insertions(+), 202 deletions(-) create mode 100644 slsReceiverSoftware/include/libzmq.a create mode 100644 slsReceiverSoftware/include/zmq.h diff --git a/slsReceiverSoftware/Makefile b/slsReceiverSoftware/Makefile index b7d1c10a9..d94ac77a0 100644 --- a/slsReceiverSoftware/Makefile +++ b/slsReceiverSoftware/Makefile @@ -12,10 +12,13 @@ PROGS = $(DESTDIR)/slsReceiver CFLAGS= -g -DC_ONLY -fPIC #FLAGS+= #-DVERBOSE -DVERYVERBOSE -DFLAGS= -g -DDACS_INT -DSLS_RECEIVER_UDP_FUNCTIONS +DFLAGS= -g -DDACS_INT -DSLS_RECEIVER_UDP_FUNCTIONS #-DVERBOSE INCLUDES?= $(INCLUDESRXR) -I include/ -I ../slsDetectorCalibration +LIBZMQDIR = include +LIBZMQ = -L$(LIBZMQDIR) -Wl,-rpath=$(LIBZMQDIR) -lzmq + #-Iinclude -I../slsDetectorCalibration -I$(ASM) SRC_CLNT = MySocketTCP.cpp UDPInterface.cpp UDPBaseImplementation.cpp UDPStandardImplementation.cpp slsReceiverTCPIPInterface.cpp slsReceiver.cpp slsReceiverUsers.cpp utilities.cpp @@ -49,9 +52,9 @@ intdoc: $(SRC_H) $(SRC_CLNT) $(BUILDDIR)/%.o : $(SRCDIR)/%.cpp Makefile ifeq ($(ROOTSLS),yes) - $(CXX) -DROOTSLS -o $@ -c $< $(INCLUDES) $(DFLAGS) $(ROOTFLAGS) -fPIC $(EPICSFLAGS) $(LDFLAGRXR) -L/usr/lib64/ $(FLAGS) + $(CXX) -DROOTSLS -o $@ -c $< $(INCLUDES) $(DFLAGS) $(ROOTFLAGS) -fPIC $(EPICSFLAGS) $(LDFLAGRXR) -L/usr/lib64/ $(FLAGS) else - $(CXX) -o $@ -c $< $(INCLUDES) $(DFLAGS) -fPIC $(EPICSFLAGS) $(LDFLAGRXR) -lpthread $(FLAGS) + $(CXX) -o $@ -c $< $(INCLUDES) $(DFLAGS) -fPIC $(EPICSFLAGS) $(LDFLAGRXR) -lpthread $(FLAGS) $(LIBZMQ) -lrt endif lib: $(OBJS) $(DESTDIR)/libSlsReceiver.so $(DESTDIR)/libSlsReceiver.a @@ -60,7 +63,7 @@ receiver: $(DESTDIR)/slsReceiver $(DESTDIR)/libSlsReceiver.so: $(OBJS) - $(CXX) -shared -Wl,-soname,libSlsReceiver.so -o libSlsReceiver.so $(OBJS) -lc $(INCLUDES) $(DFLAGS) $(FLAGS) $(EPICSFLAGS) -L/usr/lib64 -lpthread + $(CXX) -shared -Wl,-soname,libSlsReceiver.so -o libSlsReceiver.so $(OBJS) -lc $(INCLUDES) $(DFLAGS) $(FLAGS) $(EPICSFLAGS) -L/usr/lib64 -lpthread $(LIBZMQ) -lrt $(shell test -d $(DESTDIR) || mkdir -p $(DESTDIR)) mv libSlsReceiver.so $(DESTDIR) @@ -70,12 +73,12 @@ $(DESTDIR)/libSlsReceiver.a: $(OBJS) $(DESTDIR)/slsReceiver: lib - $(CXX) -o $@ $(SRCDIR)/$(MAIN_SRC) $(FLAGS) $(INCLUDES) $(CLAGS) $(LIBS) $(LDFLAGRXR) -fPIC + $(CXX) -o $@ $(SRCDIR)/$(MAIN_SRC) $(FLAGS) $(INCLUDES) $(CLAGS) $(LIBS) $(LDFLAGRXR) -fPIC $(LIBZMQ) -lrt #$(EIGERFLAGS) $(DESTDIR)/dummyReceiver: lib - $(CXX) -o $@ $(SRCDIR)/$(DUMMY_MAIN_SRC) $(FLAGS) $(INCLUDES) $(CLAGS) $(LIBS) $(LDFLAGRXR) -fPIC + $(CXX) -o $@ $(SRCDIR)/$(DUMMY_MAIN_SRC) $(FLAGS) $(INCLUDES) $(CLAGS) $(LIBS) $(LDFLAGRXR) -fPIC $(LIBZMQ) -lrt #$(EIGERFLAGS) diff --git a/slsReceiverSoftware/include/UDPStandardImplementation.h b/slsReceiverSoftware/include/UDPStandardImplementation.h index 6674c62d9..15efda79f 100644 --- a/slsReceiverSoftware/include/UDPStandardImplementation.h +++ b/slsReceiverSoftware/include/UDPStandardImplementation.h @@ -70,6 +70,13 @@ class UDPStandardImplementation: private virtual slsReceiverDefs, public UDPBase void configure(map config_map); //*** file parameters*** + /** + * Set File Name Prefix (without frame index, file index and extension (_d0_f000000000000_8.raw)) + * Does not check for file existence since it is created only at startReceiver + * @param c file name (max of 1000 characters) + */ + void setFileName(const char c[]); + /** * Overridden method * Set data compression, by saving only hits (so far implemented only for Moench and Gotthard) @@ -500,10 +507,11 @@ private: * Get Frame Number * @param ithread writer thread index * @param wbuffer writer buffer - * @param tempframenumber reference to the frame number + * @param framenumber reference to the frame number + * @param packetnumber reference to the packet number * @return OK or FAIL */ - int getFrameNumber(int ithread, char* wbuffer, uint64_t &tempframenumber); + int getFrameandPacketNumber(int ithread, char* wbuffer, uint64_t &framenumber, uint32_t &packetnumber); /** * Find offset upto this frame number and write it to file @@ -530,6 +538,9 @@ private: #endif //**detector parameters*** + /*Detector Readout ID*/ + int detID; + /** Size of 1 buffer processed at a time */ int bufferSize; @@ -655,17 +666,17 @@ private: /** Current Frame copied for GUI */ char* latestData[MAX_NUMBER_OF_WRITER_THREADS]; - /** If Data to be sent to GUI is ready */ - bool guiDataReady[MAX_NUMBER_OF_WRITER_THREADS]; - - /** Pointer to data to be sent to GUI */ - char* guiData[MAX_NUMBER_OF_WRITER_THREADS]; - /** Pointer to file name to be sent to GUI */ char guiFileName[MAX_NUMBER_OF_WRITER_THREADS][MAX_STR_LENGTH]; + /** Number of packets copied to be sent to gui (others padded) */ + int guiNumPackets[MAX_NUMBER_OF_WRITER_THREADS]; + /** Semaphore to synchronize Writer and GuiReader threads*/ - sem_t writerGuiSemaphore[MAX_NUMBER_OF_WRITER_THREADS]; + sem_t writerGuiSemaphore[MAX_NUMBER_OF_WRITER_THREADS]; //datacompression, only first thread sends to gui + + /** Semaphore to synchronize Writer and GuiReader threads*/ + sem_t dataCallbackWriterSemaphore[MAX_NUMBER_OF_WRITER_THREADS]; //datacompression, only first thread sends to gui /** counter for nth frame to gui */ int frametoGuiCounter[MAX_NUMBER_OF_WRITER_THREADS]; @@ -673,6 +684,9 @@ private: //***data call back thread parameters*** + /** Ensures if zmq threads created successfully */ + bool zmqThreadStarted; + /** Number of data callback Threads */ int numberofDataCallbackThreads; diff --git a/slsReceiverSoftware/include/genericSocket.h b/slsReceiverSoftware/include/genericSocket.h index 6cb9a8693..11828c8a7 100644 --- a/slsReceiverSoftware/include/genericSocket.h +++ b/slsReceiverSoftware/include/genericSocket.h @@ -81,6 +81,7 @@ using namespace std; #define DEFAULT_BACKLOG 5 #define DEFAULT_UDP_PORTNO 50001 #define DEFAULT_GUI_PORTNO 65000 +#define DEFAULT_ZMQ_PORTNO 70001 class genericSocket{ diff --git a/slsReceiverSoftware/include/libzmq.a b/slsReceiverSoftware/include/libzmq.a new file mode 100644 index 0000000000000000000000000000000000000000..0801ef205f2d87512924c08624ee43ee1885c2a4 GIT binary patch literal 2389564 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 my@Z13 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%0D23Bee|NhW{ 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. + + ************************************************************************* + NOTE to contributors. This file comprises the principal public contract + for ZeroMQ API users (along with zmq_utils.h). Any change to this file + supplied in a stable release SHOULD not break existing applications. + In practice this means that the value of constants must not change, and + that old values may not be reused for new constants. + ************************************************************************* +*/ + +#ifndef __ZMQ_H_INCLUDED__ +#define __ZMQ_H_INCLUDED__ + +/* Version macros for compile-time API version detection */ +#define ZMQ_VERSION_MAJOR 4 +#define ZMQ_VERSION_MINOR 0 +#define ZMQ_VERSION_PATCH 4 + +#define ZMQ_MAKE_VERSION(major, minor, patch) \ + ((major) * 10000 + (minor) * 100 + (patch)) +#define ZMQ_VERSION \ + ZMQ_MAKE_VERSION(ZMQ_VERSION_MAJOR, ZMQ_VERSION_MINOR, ZMQ_VERSION_PATCH) + +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined _WIN32_WCE +#include +#endif +#include +#include +#if defined _WIN32 +#include +#endif + +/* Handle DSO symbol visibility */ +#if defined _WIN32 +# if defined ZMQ_STATIC +# define ZMQ_EXPORT +# elif defined DLL_EXPORT +# define ZMQ_EXPORT __declspec(dllexport) +# else +# define ZMQ_EXPORT __declspec(dllimport) +# endif +#else +# if defined __SUNPRO_C || defined __SUNPRO_CC +# define ZMQ_EXPORT __global +# elif (defined __GNUC__ && __GNUC__ >= 4) || defined __INTEL_COMPILER +# define ZMQ_EXPORT __attribute__ ((visibility("default"))) +# else +# define ZMQ_EXPORT +# endif +#endif + +/* Define integer types needed for event interface */ +#if defined ZMQ_HAVE_SOLARIS || defined ZMQ_HAVE_OPENVMS +# include +#elif defined _MSC_VER && _MSC_VER < 1600 +# ifndef int32_t +typedef __int32 int32_t; +# endif +# ifndef uint16_t +typedef unsigned __int16 uint16_t; +# endif +# ifndef uint8_t +typedef unsigned __int8 uint8_t; +# endif +#else +# include +#endif + + +/******************************************************************************/ +/* 0MQ errors. */ +/******************************************************************************/ + +/* A number random enough not to collide with different errno ranges on */ +/* different OSes. The assumption is that error_t is at least 32-bit type. */ +#define ZMQ_HAUSNUMERO 156384712 + +/* On Windows platform some of the standard POSIX errnos are not defined. */ +#ifndef ENOTSUP +#define ENOTSUP (ZMQ_HAUSNUMERO + 1) +#endif +#ifndef EPROTONOSUPPORT +#define EPROTONOSUPPORT (ZMQ_HAUSNUMERO + 2) +#endif +#ifndef ENOBUFS +#define ENOBUFS (ZMQ_HAUSNUMERO + 3) +#endif +#ifndef ENETDOWN +#define ENETDOWN (ZMQ_HAUSNUMERO + 4) +#endif +#ifndef EADDRINUSE +#define EADDRINUSE (ZMQ_HAUSNUMERO + 5) +#endif +#ifndef EADDRNOTAVAIL +#define EADDRNOTAVAIL (ZMQ_HAUSNUMERO + 6) +#endif +#ifndef ECONNREFUSED +#define ECONNREFUSED (ZMQ_HAUSNUMERO + 7) +#endif +#ifndef EINPROGRESS +#define EINPROGRESS (ZMQ_HAUSNUMERO + 8) +#endif +#ifndef ENOTSOCK +#define ENOTSOCK (ZMQ_HAUSNUMERO + 9) +#endif +#ifndef EMSGSIZE +#define EMSGSIZE (ZMQ_HAUSNUMERO + 10) +#endif +#ifndef EAFNOSUPPORT +#define EAFNOSUPPORT (ZMQ_HAUSNUMERO + 11) +#endif +#ifndef ENETUNREACH +#define ENETUNREACH (ZMQ_HAUSNUMERO + 12) +#endif +#ifndef ECONNABORTED +#define ECONNABORTED (ZMQ_HAUSNUMERO + 13) +#endif +#ifndef ECONNRESET +#define ECONNRESET (ZMQ_HAUSNUMERO + 14) +#endif +#ifndef ENOTCONN +#define ENOTCONN (ZMQ_HAUSNUMERO + 15) +#endif +#ifndef ETIMEDOUT +#define ETIMEDOUT (ZMQ_HAUSNUMERO + 16) +#endif +#ifndef EHOSTUNREACH +#define EHOSTUNREACH (ZMQ_HAUSNUMERO + 17) +#endif +#ifndef ENETRESET +#define ENETRESET (ZMQ_HAUSNUMERO + 18) +#endif + +/* Native 0MQ error codes. */ +#define EFSM (ZMQ_HAUSNUMERO + 51) +#define ENOCOMPATPROTO (ZMQ_HAUSNUMERO + 52) +#define ETERM (ZMQ_HAUSNUMERO + 53) +#define EMTHREAD (ZMQ_HAUSNUMERO + 54) + +/* Run-time API version detection */ +ZMQ_EXPORT void zmq_version (int *major, int *minor, int *patch); + +/* This function retrieves the errno as it is known to 0MQ library. The goal */ +/* of this function is to make the code 100% portable, including where 0MQ */ +/* compiled with certain CRT library (on Windows) is linked to an */ +/* application that uses different CRT library. */ +ZMQ_EXPORT int zmq_errno (void); + +/* Resolves system errors and 0MQ errors to human-readable string. */ +ZMQ_EXPORT const char *zmq_strerror (int errnum); + +/******************************************************************************/ +/* 0MQ infrastructure (a.k.a. context) initialisation & termination. */ +/******************************************************************************/ + +/* New API */ +/* Context options */ +#define ZMQ_IO_THREADS 1 +#define ZMQ_MAX_SOCKETS 2 + +/* Default for new contexts */ +#define ZMQ_IO_THREADS_DFLT 1 +#define ZMQ_MAX_SOCKETS_DFLT 1023 + +ZMQ_EXPORT void *zmq_ctx_new (void); +ZMQ_EXPORT int zmq_ctx_term (void *context); +ZMQ_EXPORT int zmq_ctx_shutdown (void *ctx_); +ZMQ_EXPORT int zmq_ctx_set (void *context, int option, int optval); +ZMQ_EXPORT int zmq_ctx_get (void *context, int option); + +/* Old (legacy) API */ +ZMQ_EXPORT void *zmq_init (int io_threads); +ZMQ_EXPORT int zmq_term (void *context); +ZMQ_EXPORT int zmq_ctx_destroy (void *context); + + +/******************************************************************************/ +/* 0MQ message definition. */ +/******************************************************************************/ + +typedef struct zmq_msg_t {unsigned char _ [32];} zmq_msg_t; + +typedef void (zmq_free_fn) (void *data, void *hint); + +ZMQ_EXPORT int zmq_msg_init (zmq_msg_t *msg); +ZMQ_EXPORT int zmq_msg_init_size (zmq_msg_t *msg, size_t size); +ZMQ_EXPORT int zmq_msg_init_data (zmq_msg_t *msg, void *data, + size_t size, zmq_free_fn *ffn, void *hint); +ZMQ_EXPORT int zmq_msg_send (zmq_msg_t *msg, void *s, int flags); +ZMQ_EXPORT int zmq_msg_recv (zmq_msg_t *msg, void *s, int flags); +ZMQ_EXPORT int zmq_msg_close (zmq_msg_t *msg); +ZMQ_EXPORT int zmq_msg_move (zmq_msg_t *dest, zmq_msg_t *src); +ZMQ_EXPORT int zmq_msg_copy (zmq_msg_t *dest, zmq_msg_t *src); +ZMQ_EXPORT void *zmq_msg_data (zmq_msg_t *msg); +ZMQ_EXPORT size_t zmq_msg_size (zmq_msg_t *msg); +ZMQ_EXPORT int zmq_msg_more (zmq_msg_t *msg); +ZMQ_EXPORT int zmq_msg_get (zmq_msg_t *msg, int option); +ZMQ_EXPORT int zmq_msg_set (zmq_msg_t *msg, int option, int optval); + + +/******************************************************************************/ +/* 0MQ socket definition. */ +/******************************************************************************/ + +/* Socket types. */ +#define ZMQ_PAIR 0 +#define ZMQ_PUB 1 +#define ZMQ_SUB 2 +#define ZMQ_REQ 3 +#define ZMQ_REP 4 +#define ZMQ_DEALER 5 +#define ZMQ_ROUTER 6 +#define ZMQ_PULL 7 +#define ZMQ_PUSH 8 +#define ZMQ_XPUB 9 +#define ZMQ_XSUB 10 +#define ZMQ_STREAM 11 + +/* Deprecated aliases */ +#define ZMQ_XREQ ZMQ_DEALER +#define ZMQ_XREP ZMQ_ROUTER + +/* Socket options. */ +#define ZMQ_AFFINITY 4 +#define ZMQ_IDENTITY 5 +#define ZMQ_SUBSCRIBE 6 +#define ZMQ_UNSUBSCRIBE 7 +#define ZMQ_RATE 8 +#define ZMQ_RECOVERY_IVL 9 +#define ZMQ_SNDBUF 11 +#define ZMQ_RCVBUF 12 +#define ZMQ_RCVMORE 13 +#define ZMQ_FD 14 +#define ZMQ_EVENTS 15 +#define ZMQ_TYPE 16 +#define ZMQ_LINGER 17 +#define ZMQ_RECONNECT_IVL 18 +#define ZMQ_BACKLOG 19 +#define ZMQ_RECONNECT_IVL_MAX 21 +#define ZMQ_MAXMSGSIZE 22 +#define ZMQ_SNDHWM 23 +#define ZMQ_RCVHWM 24 +#define ZMQ_MULTICAST_HOPS 25 +#define ZMQ_RCVTIMEO 27 +#define ZMQ_SNDTIMEO 28 +#define ZMQ_LAST_ENDPOINT 32 +#define ZMQ_ROUTER_MANDATORY 33 +#define ZMQ_TCP_KEEPALIVE 34 +#define ZMQ_TCP_KEEPALIVE_CNT 35 +#define ZMQ_TCP_KEEPALIVE_IDLE 36 +#define ZMQ_TCP_KEEPALIVE_INTVL 37 +#define ZMQ_TCP_ACCEPT_FILTER 38 +#define ZMQ_IMMEDIATE 39 +#define ZMQ_XPUB_VERBOSE 40 +#define ZMQ_ROUTER_RAW 41 +#define ZMQ_IPV6 42 +#define ZMQ_MECHANISM 43 +#define ZMQ_PLAIN_SERVER 44 +#define ZMQ_PLAIN_USERNAME 45 +#define ZMQ_PLAIN_PASSWORD 46 +#define ZMQ_CURVE_SERVER 47 +#define ZMQ_CURVE_PUBLICKEY 48 +#define ZMQ_CURVE_SECRETKEY 49 +#define ZMQ_CURVE_SERVERKEY 50 +#define ZMQ_PROBE_ROUTER 51 +#define ZMQ_REQ_CORRELATE 52 +#define ZMQ_REQ_RELAXED 53 +#define ZMQ_CONFLATE 54 +#define ZMQ_ZAP_DOMAIN 55 + +/* Message options */ +#define ZMQ_MORE 1 + +/* Send/recv options. */ +#define ZMQ_DONTWAIT 1 +#define ZMQ_SNDMORE 2 + +/* Security mechanisms */ +#define ZMQ_NULL 0 +#define ZMQ_PLAIN 1 +#define ZMQ_CURVE 2 + +/* Deprecated options and aliases */ +#define ZMQ_IPV4ONLY 31 +#define ZMQ_DELAY_ATTACH_ON_CONNECT ZMQ_IMMEDIATE +#define ZMQ_NOBLOCK ZMQ_DONTWAIT +#define ZMQ_FAIL_UNROUTABLE ZMQ_ROUTER_MANDATORY +#define ZMQ_ROUTER_BEHAVIOR ZMQ_ROUTER_MANDATORY + +/******************************************************************************/ +/* 0MQ socket events and monitoring */ +/******************************************************************************/ + +/* Socket transport events (tcp and ipc only) */ +#define ZMQ_EVENT_CONNECTED 1 +#define ZMQ_EVENT_CONNECT_DELAYED 2 +#define ZMQ_EVENT_CONNECT_RETRIED 4 + +#define ZMQ_EVENT_LISTENING 8 +#define ZMQ_EVENT_BIND_FAILED 16 + +#define ZMQ_EVENT_ACCEPTED 32 +#define ZMQ_EVENT_ACCEPT_FAILED 64 + +#define ZMQ_EVENT_CLOSED 128 +#define ZMQ_EVENT_CLOSE_FAILED 256 +#define ZMQ_EVENT_DISCONNECTED 512 +#define ZMQ_EVENT_MONITOR_STOPPED 1024 + +#define ZMQ_EVENT_ALL ( ZMQ_EVENT_CONNECTED | ZMQ_EVENT_CONNECT_DELAYED | \ + ZMQ_EVENT_CONNECT_RETRIED | ZMQ_EVENT_LISTENING | \ + ZMQ_EVENT_BIND_FAILED | ZMQ_EVENT_ACCEPTED | \ + ZMQ_EVENT_ACCEPT_FAILED | ZMQ_EVENT_CLOSED | \ + ZMQ_EVENT_CLOSE_FAILED | ZMQ_EVENT_DISCONNECTED | \ + ZMQ_EVENT_MONITOR_STOPPED) + +/* Socket event data */ +typedef struct { + uint16_t event; // id of the event as bitfield + int32_t value ; // value is either error code, fd or reconnect interval +} zmq_event_t; + +ZMQ_EXPORT void *zmq_socket (void *, int type); +ZMQ_EXPORT int zmq_close (void *s); +ZMQ_EXPORT int zmq_setsockopt (void *s, int option, const void *optval, + size_t optvallen); +ZMQ_EXPORT int zmq_getsockopt (void *s, int option, void *optval, + size_t *optvallen); +ZMQ_EXPORT int zmq_bind (void *s, const char *addr); +ZMQ_EXPORT int zmq_connect (void *s, const char *addr); +ZMQ_EXPORT int zmq_unbind (void *s, const char *addr); +ZMQ_EXPORT int zmq_disconnect (void *s, const char *addr); +ZMQ_EXPORT int zmq_send (void *s, const void *buf, size_t len, int flags); +ZMQ_EXPORT int zmq_send_const (void *s, const void *buf, size_t len, int flags); +ZMQ_EXPORT int zmq_recv (void *s, void *buf, size_t len, int flags); +ZMQ_EXPORT int zmq_socket_monitor (void *s, const char *addr, int events); + +ZMQ_EXPORT int zmq_sendmsg (void *s, zmq_msg_t *msg, int flags); +ZMQ_EXPORT int zmq_recvmsg (void *s, zmq_msg_t *msg, int flags); + +/* Experimental */ +struct iovec; + +ZMQ_EXPORT int zmq_sendiov (void *s, struct iovec *iov, size_t count, int flags); +ZMQ_EXPORT int zmq_recviov (void *s, struct iovec *iov, size_t *count, int flags); + +/******************************************************************************/ +/* I/O multiplexing. */ +/******************************************************************************/ + +#define ZMQ_POLLIN 1 +#define ZMQ_POLLOUT 2 +#define ZMQ_POLLERR 4 + +typedef struct +{ + void *socket; +#if defined _WIN32 + SOCKET fd; +#else + int fd; +#endif + short events; + short revents; +} zmq_pollitem_t; + +#define ZMQ_POLLITEMS_DFLT 16 + +ZMQ_EXPORT int zmq_poll (zmq_pollitem_t *items, int nitems, long timeout); + +/* Built-in message proxy (3-way) */ + +ZMQ_EXPORT int zmq_proxy (void *frontend, void *backend, void *capture); + +/* Encode a binary key as printable text using ZMQ RFC 32 */ +ZMQ_EXPORT char *zmq_z85_encode (char *dest, uint8_t *data, size_t size); + +/* Encode a binary key from printable text per ZMQ RFC 32 */ +ZMQ_EXPORT uint8_t *zmq_z85_decode (uint8_t *dest, char *string); + +/* Deprecated aliases */ +#define ZMQ_STREAMER 1 +#define ZMQ_FORWARDER 2 +#define ZMQ_QUEUE 3 +/* Deprecated method */ +ZMQ_EXPORT int zmq_device (int type, void *frontend, void *backend); + +#undef ZMQ_EXPORT + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 983fd1fb8..37e7c7406 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -17,6 +17,9 @@ #include #include #include + +#include //zmq + using namespace std; #define WRITE_HEADERS @@ -44,6 +47,7 @@ UDPStandardImplementation::UDPStandardImplementation(){ }else if(system("echo 250000 > /proc/sys/net/core/netdev_max_backlog")){ FILE_LOG(logDEBUG) << "Warning: No root permission to change max length of input queue in file /proc/sys/net/core/netdev_max_backlog"; } + /** permanent setting by heiner net.core.rmem_max = 104857600 # 100MiB net.core.netdev_max_backlog = 250000 @@ -85,12 +89,12 @@ void UDPStandardImplementation::deleteMembers(){ } for(int i=0; i config_map){ } +void UDPStandardImplementation::setFileName(const char c[]){ + FILE_LOG(logDEBUG) << __AT__ << " starting"; + + char oldfilename[MAX_STR_LENGTH]; + strcpy(oldfilename,fileName); + + if(strlen(c)) + strcpy(fileName, c); + + if(strlen(fileName)){ + int detindex = -1; + string tempname(fileName); + size_t uscore=tempname.rfind("_"); + if (uscore!=string::npos){ + if (sscanf(tempname.substr(uscore+1,tempname.size()-uscore-1).c_str(),"d%d",&detindex)) { + detID = detindex; + } + } + if(detindex == -1) + detID = 0; + } + + + if(dataCallbackEnabled && (strcmp(oldfilename,fileName))){cout<<"***Going to destroy data callback threads and create!!!"<0) && (getFrameandPacketNumber(ithread, latestData[ithread]+offset, fnum, pnum)==FAIL)){ + offset+= onePacketSize; + } + + //end of buffer + if(offset >= size) + break; + + //new frame + if(currentfnum==-1){ + currentfnum = fnum; + } + + //last packet + if(pnum == packetsPerFrame){ + memcpy(buffer+((pnum-1)*oneDataSize), latestData[ithread]+offset+8,oneDataSize); + offset+= onePacketSize; + zmq_send(zmqsocket, buffer, oneframesize, 0); + memset(buffer,0xFF,oneframesize); + currentfnum = -1; + } + //same frame (not last) or next frame + else { + //next frame + if(fnum > currentfnum){ + zmq_send(zmqsocket, buffer, oneframesize, 0); + memset(buffer,0xFF,oneframesize); + currentfnum = fnum; + } + + memcpy(buffer+((pnum-1)*oneDataSize), latestData[ithread]+offset+8,oneDataSize); + offset+= onePacketSize; + } + + } - /*check if it should be added to previous (processlistening buffer for datacompression)*/ - zmq_send(socket, buffer.data(), buffer.size(), 0); }/*--end of loop for each buffer (inner loop)*/ + //free resources + delete[] buffer; + zmq_unbind(zmqsocket, hostName); + zmq_close(zmqsocket); + zmq_ctx_destroy(context); + + + //end of acquisition, wait for next acquisition/change of parameters sem_wait(&dataCallbackSemaphore[ithread]); + //check to exit thread (for change of parameters) - only EXIT possibility if(killAllDataCallbackThreads){ - cprintf(BLUE,"DataCallback_Thread %d:Goodbye!\n",ithread); - //free resources at exit - zmq_unbind(socket, hostName); - zmq_close(socket); - zmq_ctx_destroy(context); + cprintf(MAGENTA,"DataCallback_Thread %d:Goodbye!\n",ithread); pthread_exit(NULL); } @@ -1701,7 +1764,7 @@ void UDPStandardImplementation::startDataCallback(){ -void UDPStandardImplementation::startListening(){ +void UDPStandardImplementation::startListening(){cprintf(BLUE,"startlistening thread started %d\n",currentThreadIndex); FILE_LOG(logDEBUG) << __AT__ << " called"; //set current thread value index @@ -2136,7 +2199,7 @@ uint32_t UDPStandardImplementation::processListeningBuffer(int ithread, int &cSi -void UDPStandardImplementation::startWriting(){ +void UDPStandardImplementation::startWriting(){cprintf(GREEN,"start writing thread started %d\n",currentThreadIndex); FILE_LOG(logDEBUG) << __AT__ << " called"; //set current thread value index @@ -2157,7 +2220,6 @@ void UDPStandardImplementation::startWriting(){ //--reset parameters before acquisition nf = 0; - guiData[ithread] = latestData[ithread]; //so that the first frame is always copied if(dataCompressionEnable) listenfifoIndex = 0; //compression has only one listening thread @@ -2255,7 +2317,7 @@ void UDPStandardImplementation::waitWritingBufferForNextAcquisition(int ithread) if(myDetectorType == EIGER){ int detindex = -1; string tempname(fileName); - + //detid (more than 1 half module) size_t uscore=tempname.rfind("_"); if (uscore!=string::npos){ if (sscanf(tempname.substr(uscore+1,tempname.size()-uscore-1).c_str(),"d%d",&detindex)) { @@ -2263,11 +2325,12 @@ void UDPStandardImplementation::waitWritingBufferForNextAcquisition(int ithread) sprintf(fileNamePerThread[ithread],"%s_d%d",tempname.c_str(),detindex*2+ithread); } } - + //only one half module, so no detid if(detindex == -1) sprintf(fileNamePerThread[ithread],"%s_d%d",fileName,ithread); - } + }else + strcpy(fileNamePerThread[0],fileName); if(dataCompressionEnable){ #ifdef MYROOT1 @@ -2335,6 +2398,14 @@ void UDPStandardImplementation::stopWriting(int ithread, char* wbuffer){ cprintf(YELLOW,"Writing_Thread %d: Freeing dummy-end buffer. Pushed into fifofree %p for listener %d\n", ithread,(void*)(wbuffer),ithread); #endif + if(dataCallbackEnabled){ + //ensure previous frame was processed + sem_wait(&writerGuiSemaphore[ithread]); + guiNumPackets[ithread] = dummyPacketValue; + //let it know its got data + sem_post(&dataCallbackWriterSemaphore[ithread]); + } + //all threads need to close file, reset mask and exit loop closeFile(ithread); @@ -2349,18 +2420,12 @@ void UDPStandardImplementation::stopWriting(int ithread, char* wbuffer){ //thread 0 waits for all threads to finish & print statistics if(ithread == 0){ //wait for all other threads - if(dataCompressionEnable){ - cprintf(GREEN,"Writing_Thread %d: Waiting for jobs to be done.. current mask:0x%x\n",ithread, writerThreadsMask); - while(writerThreadsMask){ - /*cout << "." << flush;*/ - usleep(50000); - } - cprintf(GREEN,"Writing_Thread %d: Jobs Done!\n",ithread); - } - + while(writerThreadsMask) + usleep(5000); //ensure listening threads done before updating status as it returns to client (from stopReceiver) while(listeningThreadsMask) usleep(5000); + //ensure datacallbacks threads are done while(dataCallbackThreadsMask) usleep(5000); //update status @@ -2412,7 +2477,8 @@ void UDPStandardImplementation::handleWithoutDataCompression(int ithread, char* //get current frame number uint64_t tempframenumber; - if(getFrameNumber(ithread, wbuffer + HEADER_SIZE_NUM_TOT_PACKETS,tempframenumber) == FAIL){ + uint32_t pnum; + if(getFrameandPacketNumber(ithread, wbuffer + HEADER_SIZE_NUM_TOT_PACKETS,tempframenumber,pnum) == FAIL){ //error in frame number sent by fpga while(!fifoFree[ithread]->push(wbuffer)); @@ -2432,7 +2498,7 @@ void UDPStandardImplementation::handleWithoutDataCompression(int ithread, char* //callback to write data if (cbAction < DO_EVERYTHING) rawDataReadyCallBack((int)currentFrameNumber[ithread], wbuffer + HEADER_SIZE_NUM_TOT_PACKETS, npackets * onePacketSize, - sfilefd[ithread], guiData[ithread],pRawDataReady);//know which thread from sfilefd + sfilefd[ithread], latestData[ithread],pRawDataReady);//know which thread from sfilefd @@ -2446,7 +2512,7 @@ void UDPStandardImplementation::handleWithoutDataCompression(int ithread, char* //copy frame for gui //if(npackets >= (packetsPerFrame/numberofListeningThreads)) - if(npackets) + if(dataCallbackEnabled && npackets) copyFrameToGui(ithread, wbuffer,npackets); #ifdef DEBUG4 cprintf(GREEN,"Writing_Thread: Copied frame\n"); @@ -2487,8 +2553,9 @@ void UDPStandardImplementation::writeFileWithoutCompression(int ithread, char* w if(numpackets &&(lastFrameNumberInFile[ithread]>=0)){ //get start frame (required to create new file at the right juncture) uint64_t startframe =-1; + uint32_t pnum; //if(ithread) cout<<"getting start frame number"<push(wbuffer)); return; @@ -2545,7 +2612,8 @@ void UDPStandardImplementation::writeFileWithoutCompression(int ithread, char* w if(numpackets){ //get last frame number uint64_t finalLastFrameNumberToSave = 0; - if(getFrameNumber(ithread, wbuffer + HEADER_SIZE_NUM_TOT_PACKETS + ((numpackets - 1) * onePacketSize), finalLastFrameNumberToSave) == FAIL){ + uint32_t pnum; + if(getFrameandPacketNumber(ithread, wbuffer + HEADER_SIZE_NUM_TOT_PACKETS + ((numpackets - 1) * onePacketSize), finalLastFrameNumberToSave,pnum) == FAIL){ //error in frame number sent by fpga while(!fifoFree[ithread]->push(wbuffer)); return; @@ -2621,50 +2689,32 @@ void UDPStandardImplementation::updateFileHeader(int ithread){ } - +//called only if datacallback enabled void UDPStandardImplementation::copyFrameToGui(int ithread, char* buffer, uint32_t numpackets){ FILE_LOG(logDEBUG) << __AT__ << " called"; - - //if nthe frame, wait for your turn (1st frame always shown as its zero) if(FrameToGuiFrequency && ((frametoGuiCounter[ithread])%FrameToGuiFrequency)); //random read (gui ready) or nth frame read: gui needs data now or it is the first frame else{ - //tell datacallback to pick up data - sem_post(&dataCallbackSemaphore[ithread]); - - - memcpy(latestData[ithread],buffer , numpackets*onePacketSize); - #ifdef DEBUG4 - cprintf(GREEN,"Writing_Thread: CopyingFrame: Gui needs data now OR 1st frame\n"); + cprintf(GREEN,"Writing_Thread: CopyingFrame: Going to copy data\n"); #endif - pthread_mutex_lock(&dataReadyMutex); - guiDataReady[ithread]=0; -#ifdef DEBUG4 - cprintf(GREEN,"Writing_Thread: CopyingFrame: guidataready is 0, Copying data\n"); -#endif - memcpy(latestData[ithread],buffer , numpackets*onePacketSize); + //ensure previous frame was processed + sem_wait(&writerGuiSemaphore[ithread]); + + //copy date + guiNumPackets[ithread] = numpackets; strcpy(guiFileName[ithread],completeFileName[ithread]); - guiDataReady[ithread]=1; - pthread_mutex_unlock(&dataReadyMutex); -#ifdef DEBUG4 - cprintf(GREEN,"Writing_Thread: CopyingFrame: Copied Data, guidataready is 1\n"); -#endif + memcpy(latestData[ithread],buffer+ HEADER_SIZE_NUM_TOT_PACKETS , numpackets*onePacketSize); + //let it know its got data + sem_post(&dataCallbackWriterSemaphore[ithread]); - //nth frame read, block current process if the guireader hasnt read it yet - if(FrameToGuiFrequency){ #ifdef DEBUG4 - cprintf(GREEN,"Writing_Thread: CopyingFrame: Waiting after copying\n"); + cprintf(GREEN,"Writing_Thread: CopyingFrame: Copied Data\n"); #endif - sem_wait(&writerGuiSemaphore[ithread]); -#ifdef DEBUG4 - cprintf(GREEN,"Writing_Thread: CopyingFrame: Done waiting\n"); -#endif - } } @@ -2684,7 +2734,8 @@ void UDPStandardImplementation::handleDataCompression(int ithread, char* wbuffer //get frame number uint64_t tempframenumber=-1; - if(getFrameNumber(ithread, wbuffer + HEADER_SIZE_NUM_TOT_PACKETS, tempframenumber) == FAIL){ + uint32_t pnum; + if(getFrameandPacketNumber(ithread, wbuffer + HEADER_SIZE_NUM_TOT_PACKETS, tempframenumber,pnum) == FAIL){ //error in frame number sent by fpga while(!fifoFree[ithread]->push(wbuffer)); return; @@ -2795,7 +2846,8 @@ void UDPStandardImplementation::handleDataCompression(int ithread, char* wbuffer #endif if(!once){ - copyFrameToGui(ithread, buff[0],(uint32_t)packetsPerFrame); + if(dataCallbackEnabled) + copyFrameToGui(ithread, buff[0],(uint32_t)packetsPerFrame); once = 1; } } @@ -2819,59 +2871,60 @@ void UDPStandardImplementation::handleDataCompression(int ithread, char* wbuffer -int UDPStandardImplementation::getFrameNumber(int ithread, char* wbuffer, uint64_t &tempframenumber){ +int UDPStandardImplementation::getFrameandPacketNumber(int ithread, char* wbuffer, uint64_t &framenumber, uint32_t &packetnumber){ FILE_LOG(logDEBUG) << __AT__ << " called"; eiger_packet_footer_t* footer=0; jfrau_packet_header_t* header=0; - int pnum=-1; switch(myDetectorType){ case EIGER: footer = (eiger_packet_footer_t*)(wbuffer + footerOffset); - tempframenumber = (uint32_t)(*( (uint64_t*) footer)); + framenumber = (uint32_t)(*( (uint64_t*) footer)); //error in frame number sent by fpga if(!((uint32_t)(*( (uint64_t*) footer)))){ - tempframenumber = -1; + framenumber = -1; FILE_LOG(logERROR) << "Fifo "<< ithread << ": Frame Number is zero from firmware."; return FAIL; } + packetnumber = (*( (uint16_t*) footer->packetNumber)); #ifdef DEBUG4 if(!ithread) cprintf(GREEN,"Writing_Thread %d: fnum:%lld pnum:%d FPGA_fnum:%d footeroffset:%d\n", ithread, - (long long int)tempframenumber, - (*( (uint16_t*) footer->packetNumber)), - (uint32_t)(*( (uint64_t*) footer)), + (long long int)framenumber, + packetnumber, + framenumber, footerOffset); #endif - tempframenumber += (startFrameIndex - 1); + framenumber += (startFrameIndex - 1); break; case JUNGFRAU: header = (jfrau_packet_header_t*)(wbuffer); - tempframenumber = (*( (uint32_t*) header->frameNumber))&frameIndexMask; + framenumber = (*( (uint32_t*) header->frameNumber))&frameIndexMask; + packetnumber = (uint32_t)(*( (uint8_t*) header->packetNumber)); #ifdef DEBUG4 cprintf(GREEN, "Writing_Thread %d: fnum:%lld\t pnum:%d\n", - (long long int)tempframenumber, - (*( (uint8_t*) header->packetNumber))); + (long long int)framenumber, + packetnumber); #endif - tempframenumber += startFrameIndex; + framenumber += startFrameIndex; break; default: - tempframenumber = ((uint32_t)(*((uint32_t*)(wbuffer)))); + framenumber = ((uint32_t)(*((uint32_t*)(wbuffer)))); //for gotthard and normal frame, increment frame number to separate fnum and pnum if (myDetectorType == PROPIX ||(myDetectorType == GOTTHARD && shortFrameEnable == -1)) - tempframenumber++; - pnum = tempframenumber&packetIndexMask; - tempframenumber = (tempframenumber & frameIndexMask) >> frameIndexOffset; + framenumber++; + packetnumber = framenumber&packetIndexMask; + framenumber = (framenumber & frameIndexMask) >> frameIndexOffset; #ifdef DEBUG4 cprintf(GREEN, "Writing_Thread %d: fnum:%lld\t pnum:%d\n", - (long long int)tempframenumber, - pnum); + (long long int)framenumber, + packetnumber); #endif - tempframenumber += startFrameIndex; + framenumber += startFrameIndex; break; } return OK; @@ -2890,9 +2943,10 @@ int UDPStandardImplementation::writeUptoFrameNumber(int ithread, char* wbuffer, int endoffset = startoffset + numpackets * onePacketSize; uint64_t tempframenumber=-1; offset = endoffset; + uint32_t pnum; //get last frame number - if(getFrameNumber(ithread, wbuffer + (endoffset-onePacketSize), tempframenumber) == FAIL){ + if(getFrameandPacketNumber(ithread, wbuffer + (endoffset-onePacketSize), tempframenumber,pnum) == FAIL){ //error in frame number sent by fpga while(!fifoFree[ithread]->push(wbuffer)); return FAIL; @@ -2918,7 +2972,7 @@ int UDPStandardImplementation::writeUptoFrameNumber(int ithread, char* wbuffer, offset -= bigIncrements; if(offsetpush(wbuffer)); return FAIL; @@ -2926,7 +2980,7 @@ int UDPStandardImplementation::writeUptoFrameNumber(int ithread, char* wbuffer, } if(offsetpush(wbuffer)); return FAIL; @@ -2934,7 +2988,7 @@ int UDPStandardImplementation::writeUptoFrameNumber(int ithread, char* wbuffer, } while(tempframenumberpush(wbuffer)); return FAIL; diff --git a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp index 500db2988..5d6f56973 100644 --- a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp +++ b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp @@ -353,6 +353,10 @@ int slsReceiverTCPIPInterface::set_detector_type(){ sprintf(mess,"Receiver locked by %s\n", socket->lastClientIP); ret=FAIL; } + else if((receiverBase)&&(receiverBase->getStatus()==RUNNING || receiverBase->getStatus()==TRANSMITTING)){ + strcpy(mess,"Can not set detector type while receiver not idle\n"); + ret = FAIL; + } else{ switch(dr){ @@ -443,6 +447,10 @@ int slsReceiverTCPIPInterface::set_file_name() { strcpy(mess,SET_RECEIVER_ERR_MESSAGE); ret=FAIL; } + else if(receiverBase->getStatus()==RUNNING || receiverBase->getStatus()==TRANSMITTING){ + strcpy(mess,"Can not set file name while receiver not idle\n"); + ret = FAIL; + } else{ receiverBase->setFileName(fName); retval = receiverBase->getFileName(); @@ -506,15 +514,15 @@ int slsReceiverTCPIPInterface::set_file_dir() { if (lockStatus==1 && socket->differentClients==1){ sprintf(mess,"Receiver locked by %s\n", socket->lastClientIP); ret=FAIL; - }/* - else if((strlen(fPath))&&(receiverBase->getStatus()==RUNNING)){ - strcpy(mess,"Can not set file path while receiver running\n"); - ret = FAIL; - }*/ + } else if (receiverBase == NULL){ strcpy(mess,SET_RECEIVER_ERR_MESSAGE); ret=FAIL; } + else if(receiverBase->getStatus()==RUNNING || receiverBase->getStatus()==TRANSMITTING){ + strcpy(mess,"Can not set file path while receiver not idle\n"); + ret = FAIL; + } else{ receiverBase->setFilePath(fPath); retval = receiverBase->getFilePath(); @@ -584,6 +592,10 @@ int slsReceiverTCPIPInterface::set_file_index() { strcpy(mess,SET_RECEIVER_ERR_MESSAGE); ret=FAIL; } + else if(receiverBase->getStatus()==RUNNING || receiverBase->getStatus()==TRANSMITTING){ + strcpy(mess,"Can not set file index while receiver not idle\n"); + ret = FAIL; + } else{ if(index >= 0) receiverBase->setFileIndex(index); @@ -648,6 +660,10 @@ int slsReceiverTCPIPInterface::set_frame_index() { strcpy(mess,SET_RECEIVER_ERR_MESSAGE); ret=FAIL; } + else if(receiverBase->getStatus()==RUNNING || receiverBase->getStatus()==TRANSMITTING){ + strcpy(mess,"Can not set frame index while receiver not idle\n"); + ret = FAIL; + } else{ //client sets to 0, but for receiver it is just an enable //client uses this value for other detectors not using receiver, @@ -725,9 +741,9 @@ int slsReceiverTCPIPInterface::setup_udp(){ strcpy(mess,SET_RECEIVER_ERR_MESSAGE); ret=FAIL; } - else if(receiverBase->getStatus()==RUNNING){ + else if(receiverBase->getStatus()==RUNNING || receiverBase->getStatus()==TRANSMITTING){ + strcpy(mess,"Can not set up udp while receiver not idle\n"); ret = FAIL; - strcpy(mess,"cannot set up udp when receiver is running\n"); } else{ //set up udp port @@ -859,9 +875,12 @@ int slsReceiverTCPIPInterface::stop_receiver(){ ret=FAIL; } else{ - if(receiverBase->getStatus()!=IDLE) + if(receiverBase->getStatus()==RUNNING || receiverBase->getStatus()==TRANSMITTING){ receiverBase->stopReceiver(); + cout<<"receiver stopped"<getStatus(); + cout<<"to stop, receiver status:"<getStatus()==RUNNING){ + else if(receiverBase->getStatus()==RUNNING || receiverBase->getStatus()==TRANSMITTING){ strcpy(mess,"Cannot set short frame while status is running\n"); ret=FAIL; } @@ -2077,6 +2096,10 @@ int slsReceiverTCPIPInterface::set_read_frequency(){ strcpy(mess,SET_RECEIVER_ERR_MESSAGE); ret=FAIL; } + else if(receiverBase->getStatus()==RUNNING || receiverBase->getStatus()==TRANSMITTING){ + strcpy(mess,"Can not set receiver frequency mode while receiver not idle\n"); + ret = FAIL; + } /* else if((receiverBase->getStatus()==RUNNING) && (index >= 0)){ ret = FAIL; @@ -2142,6 +2165,10 @@ int slsReceiverTCPIPInterface::enable_file_write(){ strcpy(mess,SET_RECEIVER_ERR_MESSAGE); ret=FAIL; } + else if(receiverBase->getStatus()==RUNNING || receiverBase->getStatus()==TRANSMITTING){ + strcpy(mess,"Can not set file write mode while receiver not idle\n"); + ret = FAIL; + } else{ if(enable >= 0) receiverBase->setFileWriteEnable(enable); @@ -2213,7 +2240,12 @@ int slsReceiverTCPIPInterface::start_readout(){ if (receiverBase == NULL){ strcpy(mess,SET_RECEIVER_ERR_MESSAGE); ret=FAIL; - }else{ + } + else if(receiverBase->getStatus()==RUNNING || receiverBase->getStatus()==TRANSMITTING){ + strcpy(mess,"Can not start receiver readout while receiver not idle\n"); + ret = FAIL; + } + else{ receiverBase->startReadout(); retval = receiverBase->getStatus(); if((retval == TRANSMITTING) || (retval == RUN_FINISHED) || (retval == IDLE)) @@ -2269,6 +2301,10 @@ int slsReceiverTCPIPInterface::set_timer() { strcpy(mess,SET_RECEIVER_ERR_MESSAGE); ret=FAIL; } + else if(receiverBase->getStatus()==RUNNING || receiverBase->getStatus()==TRANSMITTING){ + strcpy(mess,"Can not set timer while receiver not idle\n"); + ret = FAIL; + } else{ if(index[0] == FRAME_PERIOD){ if(index[1]>=0){ @@ -2344,7 +2380,7 @@ int slsReceiverTCPIPInterface::enable_compression() { strcpy(mess,SET_RECEIVER_ERR_MESSAGE); ret=FAIL; } - else if(receiverBase->getStatus()==RUNNING){ + else if(receiverBase->getStatus()==RUNNING || receiverBase->getStatus()==TRANSMITTING){ strcpy(mess,"Cannot enable/disable compression while status is running\n"); ret=FAIL; } @@ -2413,6 +2449,10 @@ int slsReceiverTCPIPInterface::set_detector_hostname() { strcpy(mess,SET_RECEIVER_ERR_MESSAGE); ret=FAIL; } + else if(receiverBase->getStatus()==RUNNING || receiverBase->getStatus()==TRANSMITTING){ + strcpy(mess,"Can not set detector hostname while receiver not idle\n"); + ret = FAIL; + } else{ receiverBase->initialize(hostname); retval = receiverBase->getDetectorHostname(); @@ -2494,7 +2534,12 @@ int slsReceiverTCPIPInterface::set_dynamic_range() { if (receiverBase == NULL){ strcpy(mess,SET_RECEIVER_ERR_MESSAGE); ret=FAIL; - }else{ + } + else if(receiverBase->getStatus()==RUNNING || receiverBase->getStatus()==TRANSMITTING){ + strcpy(mess,"Can not set dynamic range while receiver not idle\n"); + ret = FAIL; + } + else{ if(dr > 0){ ret = receiverBase->setDynamicRange(dr); if(ret == FAIL) @@ -2571,6 +2616,10 @@ int slsReceiverTCPIPInterface::enable_overwrite() { strcpy(mess,SET_RECEIVER_ERR_MESSAGE); ret=FAIL; } + else if(receiverBase->getStatus()==RUNNING || receiverBase->getStatus()==TRANSMITTING){ + strcpy(mess,"Can not set overwrite mode while receiver not idle\n"); + ret = FAIL; + } else{ if(index >= 0) receiverBase->setOverwriteEnable(index); @@ -2634,6 +2683,10 @@ int slsReceiverTCPIPInterface::enable_tengiga() { strcpy(mess,SET_RECEIVER_ERR_MESSAGE); ret=FAIL; } + else if(receiverBase->getStatus()==RUNNING || receiverBase->getStatus()==TRANSMITTING){ + strcpy(mess,"Can not set up 1Giga/10Giga mode while receiver not idle\n"); + ret = FAIL; + } else{ if(val >= 0) ret = receiverBase->setTenGigaEnable(val); @@ -2699,7 +2752,7 @@ int slsReceiverTCPIPInterface::set_fifo_depth() { strcpy(mess,SET_RECEIVER_ERR_MESSAGE); ret=FAIL; } - else if(receiverBase->getStatus()==RUNNING){ + else if(receiverBase->getStatus()==RUNNING || receiverBase->getStatus()==TRANSMITTING){ strcpy(mess,"Cannot set/get fifo depth while status is running\n"); ret=FAIL; } From c80b1c9a91e248b983c589f95852bedcb0741ac3 Mon Sep 17 00:00:00 2001 From: wang_x1 Date: Wed, 14 Sep 2016 11:58:39 +0200 Subject: [PATCH 243/474] add missing preprossor macros --- slsReceiverSoftware/CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/slsReceiverSoftware/CMakeLists.txt b/slsReceiverSoftware/CMakeLists.txt index f84b0d2bc..98f3574b2 100644 --- a/slsReceiverSoftware/CMakeLists.txt +++ b/slsReceiverSoftware/CMakeLists.txt @@ -9,6 +9,10 @@ set(SOURCES src/utilities.cpp ) +add_definitions( + -DDACS_INT -DSLS_RECEIVER_UDP_FUNCTIONS +) + include_directories( include ../slsDetectorCalibration From 7d86e6204541eef5c51cd18cea373bf1b1180de8 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Thu, 15 Sep 2016 12:16:08 +0200 Subject: [PATCH 244/474] almost --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 5 ++++- slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp | 2 -- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 37e7c7406..e43d253bd 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -450,10 +450,12 @@ void UDPStandardImplementation::setFileName(const char c[]){ createDataCallbackThreads(true); zmqThreadStarted = false; } + cout<<"***datacallback threads destroyed"<getStatus()==RUNNING || receiverBase->getStatus()==TRANSMITTING){ receiverBase->stopReceiver(); - cout<<"receiver stopped"<getStatus(); - cout<<"to stop, receiver status:"< Date: Thu, 15 Sep 2016 17:16:00 +0200 Subject: [PATCH 245/474] works, need to do json header and send dataready --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index e43d253bd..7b31db4ae 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1664,7 +1664,7 @@ void UDPStandardImplementation::startDataCallback(){cprintf(MAGENTA,"start data void *context = zmq_ctx_new(); // create a publisher - void *zmqsocket = zmq_socket(context, ZMQ_PUB); + void *zmqsocket = zmq_socket(context, ZMQ_PUSH); // bind zmq_bind(zmqsocket,hostName); @@ -1685,8 +1685,11 @@ void UDPStandardImplementation::startDataCallback(){cprintf(MAGENTA,"start data /**suing this in clientzmq_msg_more, * in serve use zmq_msg_send (&message, sender, ZMQ_SNDMORE); and 0 for last packet, but better to check lengt*/ + /*if (checkJoinThread()){for different scans + break; + }*/ zmq_send (zmqsocket, "end", 3, 0); - cprintf(BLUE,"sent done\n"); + //cprintf(BLUE,"sent done\n"); pthread_mutex_lock(&statusMutex); dataCallbackThreadsMask^=(1< Date: Fri, 16 Sep 2016 12:49:39 +0200 Subject: [PATCH 246/474] done --- .../include/UDPBaseImplementation.h | 22 ++++- slsReceiverSoftware/include/UDPInterface.h | 17 +++- .../include/UDPStandardImplementation.h | 13 ++- .../include/slsReceiverTCPIPInterface.h | 3 + .../include/sls_receiver_funcs.h | 4 +- .../src/UDPBaseImplementation.cpp | 25 ++++-- .../src/UDPStandardImplementation.cpp | 80 ++++++++++++------ .../src/slsReceiverTCPIPInterface.cpp | 82 +++++++++++++++++-- 8 files changed, 198 insertions(+), 48 deletions(-) diff --git a/slsReceiverSoftware/include/UDPBaseImplementation.h b/slsReceiverSoftware/include/UDPBaseImplementation.h index 60e07ef64..f576e2666 100644 --- a/slsReceiverSoftware/include/UDPBaseImplementation.h +++ b/slsReceiverSoftware/include/UDPBaseImplementation.h @@ -154,6 +154,13 @@ class UDPBaseImplementation : protected virtual slsReceiverDefs, public UDPInter */ uint32_t getFrameToGuiFrequency() const; + /** + * Get the data stream enable + * @return 1 to send via zmq, else 0 + */ + uint32_t getDataStreamEnable() const; + + /** * Get Acquisition Period * @return acquisition period @@ -298,10 +305,17 @@ class UDPBaseImplementation : protected virtual slsReceiverDefs, public UDPInter /** * Set the Frequency of Frames Sent to GUI - * @param i 0 for random frame requests, n for nth frame frequency + * @param freq 0 for random frame requests, n for nth frame frequency * @return OK or FAIL */ - int setFrameToGuiFrequency(const uint32_t i); + int setFrameToGuiFrequency(const uint32_t freq); + + /** + * Set the data stream enable + * @param enable 0 to disable, 1 to enable + * @return OK or FAIL + */ + uint32_t setDataStreamEnable(const uint32_t enable); /** * Set Acquisition Period @@ -525,7 +539,9 @@ class UDPBaseImplementation : protected virtual slsReceiverDefs, public UDPInter /* Short Frame Enable or index of adc enabled, else -1 if all enabled (gotthard specific) TODO: move to setROI */ int shortFrameEnable; /** Frequency of Frames sent to GUI */ - uint32_t FrameToGuiFrequency; + uint32_t frameToGuiFrequency; + /** Data Stream Enable from Receiver */ + int32_t dataStreamEnable; diff --git a/slsReceiverSoftware/include/UDPInterface.h b/slsReceiverSoftware/include/UDPInterface.h index 754aa5bd7..9ef30c680 100644 --- a/slsReceiverSoftware/include/UDPInterface.h +++ b/slsReceiverSoftware/include/UDPInterface.h @@ -214,6 +214,12 @@ class UDPInterface { */ virtual uint32_t getFrameToGuiFrequency() const = 0; + /** + * Get the data stream enable + * @return 1 to send via zmq, else 0 + */ + virtual uint32_t getDataStreamEnable() const = 0; + /** * Get Acquisition Period * @return acquisition period @@ -355,10 +361,17 @@ class UDPInterface { /** * Set the Frequency of Frames Sent to GUI - * @param i 0 for random frame requests, n for nth frame frequency + * @param freq 0 for random frame requests, n for nth frame frequency * @return OK or FAIL */ - virtual int setFrameToGuiFrequency(const uint32_t i) = 0; + virtual int setFrameToGuiFrequency(const uint32_t freq) = 0; + + /** + * Set the data stream enable + * @param enable 0 to disable, 1 to enable + * @return OK or FAIL + */ + virtual uint32_t setDataStreamEnable(const uint32_t enable) = 0; /** * Set Acquisition Period diff --git a/slsReceiverSoftware/include/UDPStandardImplementation.h b/slsReceiverSoftware/include/UDPStandardImplementation.h index 15efda79f..18f9e546f 100644 --- a/slsReceiverSoftware/include/UDPStandardImplementation.h +++ b/slsReceiverSoftware/include/UDPStandardImplementation.h @@ -107,12 +107,18 @@ class UDPStandardImplementation: private virtual slsReceiverDefs, public UDPBase void setShortFrameEnable(const int i); /** - * Overridden method * Set the Frequency of Frames Sent to GUI - * @param i 0 for random frame requests, n for nth frame frequency + * @param freq 0 for random frame requests, n for nth frame frequency * @return OK or FAIL */ - int setFrameToGuiFrequency(const uint32_t i); + int setFrameToGuiFrequency(const uint32_t freq); + + /** + * Set the data stream enable + * @param enable 0 to disable, 1 to enable + * @return OK or FAIL + */ + uint32_t setDataStreamEnable(const uint32_t enable); /** * Overridden method @@ -702,7 +708,6 @@ private: /** Set to self-terminate data callback threads waiting for semaphores */ bool killAllDataCallbackThreads; - bool dataCallbackEnabled; //***general and listening thread parameters*** diff --git a/slsReceiverSoftware/include/slsReceiverTCPIPInterface.h b/slsReceiverSoftware/include/slsReceiverTCPIPInterface.h index 8b5c4527f..8b30be84f 100644 --- a/slsReceiverSoftware/include/slsReceiverTCPIPInterface.h +++ b/slsReceiverSoftware/include/slsReceiverTCPIPInterface.h @@ -176,6 +176,9 @@ private: /** Sets the receiver to send every nth frame to gui, or only upon gui request */ int set_read_frequency(); + /* Set the data stream enable */ + int set_data_stream_enable(); + /** Enable File Write*/ int enable_file_write(); diff --git a/slsReceiverSoftware/include/sls_receiver_funcs.h b/slsReceiverSoftware/include/sls_receiver_funcs.h index e1ef93040..cc3490c42 100644 --- a/slsReceiverSoftware/include/sls_receiver_funcs.h +++ b/slsReceiverSoftware/include/sls_receiver_funcs.h @@ -49,7 +49,9 @@ enum { F_ENABLE_RECEIVER_OVERWRITE, /**< set overwrite flag in receiver */ F_ENABLE_RECEIVER_TEN_GIGA, /**< enable 10Gbe in receiver */ - F_SET_RECEIVER_FIFO_DEPTH /**< set receiver fifo depth */ + F_SET_RECEIVER_FIFO_DEPTH, /**< set receiver fifo depth */ + + F_STREAM_DATA_FROM_RECEIVER /**< stream data from receiver to client */ /* Always append functions hereafter!!! */ }; diff --git a/slsReceiverSoftware/src/UDPBaseImplementation.cpp b/slsReceiverSoftware/src/UDPBaseImplementation.cpp index d4bbbcfbd..4032f27e8 100644 --- a/slsReceiverSoftware/src/UDPBaseImplementation.cpp +++ b/slsReceiverSoftware/src/UDPBaseImplementation.cpp @@ -75,7 +75,8 @@ void UDPBaseImplementation::initializeMembers(){ //***acquisition parameters*** shortFrameEnable = -1; - FrameToGuiFrequency = 0; + frameToGuiFrequency = 0; + dataStreamEnable = false; } UDPBaseImplementation::~UDPBaseImplementation(){} @@ -172,7 +173,9 @@ char *UDPBaseImplementation::getEthernetInterface() const{ /***acquisition parameters***/ int UDPBaseImplementation::getShortFrameEnable() const{ FILE_LOG(logDEBUG) << __AT__ << " starting"; return shortFrameEnable;} -uint32_t UDPBaseImplementation::getFrameToGuiFrequency() const{ FILE_LOG(logDEBUG) << __AT__ << " starting"; return FrameToGuiFrequency;} +uint32_t UDPBaseImplementation::getFrameToGuiFrequency() const{ FILE_LOG(logDEBUG) << __AT__ << " starting"; return frameToGuiFrequency;} + +uint32_t UDPBaseImplementation::getDataStreamEnable() const{ FILE_LOG(logDEBUG) << __AT__ << " starting"; return dataStreamEnable;} uint64_t UDPBaseImplementation::getAcquisitionPeriod() const{ FILE_LOG(logDEBUG) << __AT__ << " starting"; return acquisitionPeriod;} @@ -314,16 +317,28 @@ void UDPBaseImplementation::setShortFrameEnable(const int i){ FILE_LOG(logINFO) << "Short Frame Enable: " << stringEnable(shortFrameEnable); } -int UDPBaseImplementation::setFrameToGuiFrequency(const uint32_t i){ +int UDPBaseImplementation::setFrameToGuiFrequency(const uint32_t freq){ FILE_LOG(logDEBUG) << __AT__ << " starting"; - FrameToGuiFrequency = i; - FILE_LOG(logINFO) << "Frame To Gui Frequency:" << FrameToGuiFrequency; + frameToGuiFrequency = freq; + FILE_LOG(logINFO) << "Frame To Gui Frequency:" << frameToGuiFrequency; //overrridden child classes might return FAIL return OK; } + +uint32_t UDPBaseImplementation::setDataStreamEnable(const uint32_t enable){ + FILE_LOG(logDEBUG) << __AT__ << " starting"; + + dataStreamEnable = enable; + FILE_LOG(logINFO) << "Streaming Data from Receiver:" << dataStreamEnable; + + //overrridden child classes might return FAIL + return OK; +} + + int UDPBaseImplementation::setAcquisitionPeriod(const uint64_t i){ FILE_LOG(logDEBUG) << __AT__ << " starting"; diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 7b31db4ae..22e9ef00c 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -195,7 +195,8 @@ void UDPStandardImplementation::initializeMembers(){ numberofDataCallbackThreads = 1; dataCallbackThreadsMask = 0x0; killAllDataCallbackThreads = false; - dataCallbackEnabled = true; /**false*/ + dataStreamEnable = false; + //***general and listening thread parameters*** threadStarted = false; @@ -282,8 +283,8 @@ int UDPStandardImplementation::setupFifoStructure(){ //else calculate best possible number of frames to listen to at a time (for fast readouts like gotthard) else{ //if frequency to gui is not random (every nth frame), then listen to only n frames per buffer - if(FrameToGuiFrequency) - numberofJobsPerBuffer = FrameToGuiFrequency; + if(frameToGuiFrequency) + numberofJobsPerBuffer = frameToGuiFrequency; //random frame sent to gui, then frames per buffer depends on acquisition period else{ //calculate 100ms/period to get frames to listen to at a time @@ -445,17 +446,13 @@ void UDPStandardImplementation::setFileName(const char c[]){ } - if(dataCallbackEnabled && (strcmp(oldfilename,fileName))){cout<<"***Going to destroy data callback threads and create!!!"<= (packetsPerFrame/numberofListeningThreads)) - if(dataCallbackEnabled && npackets) + if(dataStreamEnable && npackets) copyFrameToGui(ithread, wbuffer,npackets); #ifdef DEBUG4 cprintf(GREEN,"Writing_Thread: Copied frame\n"); @@ -2700,7 +2732,7 @@ void UDPStandardImplementation::copyFrameToGui(int ithread, char* buffer, uint32 FILE_LOG(logDEBUG) << __AT__ << " called"; //if nthe frame, wait for your turn (1st frame always shown as its zero) - if(FrameToGuiFrequency && ((frametoGuiCounter[ithread])%FrameToGuiFrequency)); + if(frameToGuiFrequency && ((frametoGuiCounter[ithread])%frameToGuiFrequency)); //random read (gui ready) or nth frame read: gui needs data now or it is the first frame else{ @@ -2725,7 +2757,7 @@ void UDPStandardImplementation::copyFrameToGui(int ithread, char* buffer, uint32 } //update the counter for nth frame - if(FrameToGuiFrequency) + if(frameToGuiFrequency) frametoGuiCounter[ithread]++; @@ -2852,7 +2884,7 @@ void UDPStandardImplementation::handleDataCompression(int ithread, char* wbuffer #endif if(!once){ - if(dataCallbackEnabled) + if(dataStreamEnable) copyFrameToGui(ithread, buff[0],(uint32_t)packetsPerFrame); once = 1; } diff --git a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp index 1ee51c37d..ff39c681b 100644 --- a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp +++ b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp @@ -262,7 +262,7 @@ int slsReceiverTCPIPInterface::function_table(){ flist[F_ENABLE_RECEIVER_TEN_GIGA] = &slsReceiverTCPIPInterface::enable_tengiga; flist[F_SET_RECEIVER_FIFO_DEPTH] = &slsReceiverTCPIPInterface::set_fifo_depth; - + flist[F_STREAM_DATA_FROM_RECEIVER] = &slsReceiverTCPIPInterface::set_data_stream_enable; #ifdef VERYVERBOSE for (int i=0;igetStatus()==RUNNING || receiverBase->getStatus()==TRANSMITTING){ strcpy(mess,"Can not set receiver frequency mode while receiver not idle\n"); + cprintf(RED,"%s\n",mess); ret = FAIL; } - /* - else if((receiverBase->getStatus()==RUNNING) && (index >= 0)){ - ret = FAIL; - strcpy(mess,"cannot set up receiver mode when receiver is running\n"); - }*/ else{ - if(index >= 0){ + if(index >= 0 ){ ret = receiverBase->setFrameToGuiFrequency(index); - if(ret == FAIL) + if(ret == FAIL){ strcpy(mess, "Could not allocate memory for listening fifo\n"); + cprintf(RED,"%s\n",mess); + } } retval=receiverBase->getFrameToGuiFrequency(); - if(index>=0 && retval!=index) + if(index>=0 && retval!=index){ + strcpy(mess,"Could not set frame to gui frequency"); + cprintf(RED,"%s\n",mess); ret = FAIL; + } } } @@ -2138,6 +2139,69 @@ int slsReceiverTCPIPInterface::set_read_frequency(){ +int slsReceiverTCPIPInterface::set_data_stream_enable(){ + ret=OK; + int retval=-1; + int index; + strcpy(mess,"Could not set data stream enable\n"); + + + // receive arguments + if(socket->ReceiveDataOnly(&index,sizeof(index)) < 0 ){ + strcpy(mess,"Error reading from socket\n"); + ret = FAIL; + } + + // execute action if the arguments correctly arrived +#ifdef SLS_RECEIVER_UDP_FUNCTIONS + if (ret==OK) { + if (lockStatus==1 && socket->differentClients==1){ + sprintf(mess,"Receiver locked by %s\n", socket->lastClientIP); + ret=FAIL; + } + else if (receiverBase == NULL){ + strcpy(mess,SET_RECEIVER_ERR_MESSAGE); + ret=FAIL; + } + else if(receiverBase->getStatus()==RUNNING || receiverBase->getStatus()==TRANSMITTING){ + strcpy(mess,"Can not set data stream enable while receiver not idle\n"); + cprintf(RED,"%s\n",mess); + ret = FAIL; + } + else{ + if(index >= 0 ) + ret = receiverBase->setDataStreamEnable(index); + retval=receiverBase->getDataStreamEnable(); + if(index>=0 && retval!=index){ + strcpy(mess,"Could not set data stream enable"); + cprintf(RED,"%s\n",mess); + ret = FAIL; + } + } + } + +#endif + + if(ret==OK && socket->differentClients){ + FILE_LOG(logDEBUG) << "Force update"; + ret=FORCE_UPDATE; + } + + // send answer + socket->SendDataOnly(&ret,sizeof(ret)); + if(ret==FAIL){ + cprintf(RED,"%s\n",mess); + socket->SendDataOnly(mess,sizeof(mess)); + } + socket->SendDataOnly(&retval,sizeof(retval)); + + //return ok/fail + return ret; +} + + + + int slsReceiverTCPIPInterface::enable_file_write(){ ret=OK; From 57e741c36cd33e78269fd8186e4817d1d563b5ed Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Fri, 16 Sep 2016 17:19:55 +0200 Subject: [PATCH 247/474] included json example with dummy values --- slsReceiverSoftware/CMakeLists.txt | 8 ++ .../src/UDPStandardImplementation.cpp | 82 ++++++++++++++++--- 2 files changed, 79 insertions(+), 11 deletions(-) diff --git a/slsReceiverSoftware/CMakeLists.txt b/slsReceiverSoftware/CMakeLists.txt index 98f3574b2..79c9b6c73 100644 --- a/slsReceiverSoftware/CMakeLists.txt +++ b/slsReceiverSoftware/CMakeLists.txt @@ -18,6 +18,12 @@ include_directories( ../slsDetectorCalibration ) +add_library(zmq STATIC IMPORTED ) + +set_target_properties(zmq PROPERTIES + IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/include/libzmq.a +) + add_library(slsReceiverStatic STATIC ${SOURCES} ${HEADERS} @@ -45,4 +51,6 @@ set_target_properties(slsReceiver PROPERTIES target_link_libraries(slsReceiver slsReceiverShared pthread + zmq + rt ) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 22e9ef00c..b3b81318d 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -16,9 +16,10 @@ #include #include #include -#include +#include #include //zmq +#include using namespace std; @@ -1669,7 +1670,7 @@ void UDPStandardImplementation::startDataCallback(){cprintf(MAGENTA,"start data //set current thread value index int ithread = currentThreadIndex; - + struct timespec begin,end; // server address to bind char hostName[100] = "tcp://127.0.0.1:"; @@ -1686,22 +1687,24 @@ void UDPStandardImplementation::startDataCallback(){cprintf(MAGENTA,"start data memset(buffer,0xFF,oneframesize); int bufferoffset = 0; int size = 0; - int offset=0; - int currentfnum = 0; + int offset = 0; + int currentfnum = -1; uint64_t fnum = 0; uint32_t pnum = 0; - void *context = zmq_ctx_new(); - // create a publisher - void *zmqsocket = zmq_socket(context, ZMQ_PUSH); - // bind - zmq_bind(zmqsocket,hostName); + bool randomSendNow = true; + + void *context = zmq_ctx_new(); + void *zmqsocket = zmq_socket(context, ZMQ_PUSH); // create a publisher + zmq_bind(zmqsocket,hostName); // bind //let calling function know thread started and obtained current (after sockets created) if(!zmqThreadStarted) zmqThreadStarted = true; - currentfnum = -1; + const char *type = "float64"; + const char *shape= "[1024, 512]"; + /* inner loop - loop for each buffer */ //until mask reset (dummy pcaket got by writer) while((1 << ithread) & dataCallbackThreadsMask){ @@ -1720,8 +1723,16 @@ void UDPStandardImplementation::startDataCallback(){cprintf(MAGENTA,"start data /*if (checkJoinThread()){for different scans break; }*/ + ostringstream header; + header << "{\"htype\":[\"chunk-1.0\"], " + << "\"type\":" << "\"" << type << "\", " + << "\"shape\":" << shape + << "}"; + //send header + zmq_send(zmqsocket, header.str().c_str(), header.str().length(), ZMQ_SNDMORE); + sleep(1); + //send data zmq_send (zmqsocket, "end", 3, 0); - //cprintf(BLUE,"sent done\n"); pthread_mutex_lock(&statusMutex); dataCallbackThreadsMask^=(1< currentfnum){ + ostringstream header; + header << "{\"htype\":[\"chunk-1.0\"], " + << "\"type\":" << "\"" << type << "\", " + << "\"shape\":" << shape + << "}"; + //send header + zmq_send(zmqsocket, header.str().c_str(), header.str().length(), ZMQ_SNDMORE); + sleep(1); + //send data zmq_send(zmqsocket, buffer, oneframesize, 0); +#ifdef DEBUG + cprintf(BLUE,"%d sent (last packet)\n",ithread); +#endif + //start clock after sending + if(!frameToGuiFrequency){ + randomSendNow = false; + clock_gettime(CLOCK_REALTIME, &begin); + } memset(buffer,0xFF,oneframesize); currentfnum = fnum; } From 82669103af1edd18f1605fbf04a95f624d633400 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Fri, 16 Sep 2016 17:22:44 +0200 Subject: [PATCH 248/474] added rapidjson lib --- .../include/rapidjson/allocators.h | 271 ++ .../include/rapidjson/document.h | 2575 +++++++++++++++++ .../include/rapidjson/encodedstream.h | 299 ++ .../include/rapidjson/encodings.h | 716 +++++ .../include/rapidjson/error/en.h | 74 + .../include/rapidjson/error/error.h | 155 + .../include/rapidjson/filereadstream.h | 99 + .../include/rapidjson/filewritestream.h | 104 + slsReceiverSoftware/include/rapidjson/fwd.h | 151 + .../include/rapidjson/internal/biginteger.h | 290 ++ .../include/rapidjson/internal/diyfp.h | 258 ++ .../include/rapidjson/internal/dtoa.h | 245 ++ .../include/rapidjson/internal/ieee754.h | 78 + .../include/rapidjson/internal/itoa.h | 304 ++ .../include/rapidjson/internal/meta.h | 181 ++ .../include/rapidjson/internal/pow10.h | 55 + .../include/rapidjson/internal/regex.h | 701 +++++ .../include/rapidjson/internal/stack.h | 230 ++ .../include/rapidjson/internal/strfunc.h | 55 + .../include/rapidjson/internal/strtod.h | 269 ++ .../include/rapidjson/internal/swap.h | 46 + .../include/rapidjson/istreamwrapper.h | 115 + .../include/rapidjson/memorybuffer.h | 70 + .../include/rapidjson/memorystream.h | 71 + .../include/rapidjson/msinttypes/inttypes.h | 316 ++ .../include/rapidjson/msinttypes/stdint.h | 300 ++ .../include/rapidjson/ostreamwrapper.h | 81 + .../include/rapidjson/pointer.h | 1358 +++++++++ .../include/rapidjson/prettywriter.h | 255 ++ .../include/rapidjson/rapidjson.h | 615 ++++ .../include/rapidjson/reader.h | 1879 ++++++++++++ .../include/rapidjson/schema.h | 2006 +++++++++++++ .../include/rapidjson/stream.h | 179 ++ .../include/rapidjson/stringbuffer.h | 117 + .../include/rapidjson/writer.h | 610 ++++ 35 files changed, 15128 insertions(+) create mode 100644 slsReceiverSoftware/include/rapidjson/allocators.h create mode 100644 slsReceiverSoftware/include/rapidjson/document.h create mode 100644 slsReceiverSoftware/include/rapidjson/encodedstream.h create mode 100644 slsReceiverSoftware/include/rapidjson/encodings.h create mode 100644 slsReceiverSoftware/include/rapidjson/error/en.h create mode 100644 slsReceiverSoftware/include/rapidjson/error/error.h create mode 100644 slsReceiverSoftware/include/rapidjson/filereadstream.h create mode 100644 slsReceiverSoftware/include/rapidjson/filewritestream.h create mode 100644 slsReceiverSoftware/include/rapidjson/fwd.h create mode 100644 slsReceiverSoftware/include/rapidjson/internal/biginteger.h create mode 100644 slsReceiverSoftware/include/rapidjson/internal/diyfp.h create mode 100644 slsReceiverSoftware/include/rapidjson/internal/dtoa.h create mode 100644 slsReceiverSoftware/include/rapidjson/internal/ieee754.h create mode 100644 slsReceiverSoftware/include/rapidjson/internal/itoa.h create mode 100644 slsReceiverSoftware/include/rapidjson/internal/meta.h create mode 100644 slsReceiverSoftware/include/rapidjson/internal/pow10.h create mode 100644 slsReceiverSoftware/include/rapidjson/internal/regex.h create mode 100644 slsReceiverSoftware/include/rapidjson/internal/stack.h create mode 100644 slsReceiverSoftware/include/rapidjson/internal/strfunc.h create mode 100644 slsReceiverSoftware/include/rapidjson/internal/strtod.h create mode 100644 slsReceiverSoftware/include/rapidjson/internal/swap.h create mode 100644 slsReceiverSoftware/include/rapidjson/istreamwrapper.h create mode 100644 slsReceiverSoftware/include/rapidjson/memorybuffer.h create mode 100644 slsReceiverSoftware/include/rapidjson/memorystream.h create mode 100644 slsReceiverSoftware/include/rapidjson/msinttypes/inttypes.h create mode 100644 slsReceiverSoftware/include/rapidjson/msinttypes/stdint.h create mode 100644 slsReceiverSoftware/include/rapidjson/ostreamwrapper.h create mode 100644 slsReceiverSoftware/include/rapidjson/pointer.h create mode 100644 slsReceiverSoftware/include/rapidjson/prettywriter.h create mode 100644 slsReceiverSoftware/include/rapidjson/rapidjson.h create mode 100644 slsReceiverSoftware/include/rapidjson/reader.h create mode 100644 slsReceiverSoftware/include/rapidjson/schema.h create mode 100644 slsReceiverSoftware/include/rapidjson/stream.h create mode 100644 slsReceiverSoftware/include/rapidjson/stringbuffer.h create mode 100644 slsReceiverSoftware/include/rapidjson/writer.h diff --git a/slsReceiverSoftware/include/rapidjson/allocators.h b/slsReceiverSoftware/include/rapidjson/allocators.h new file mode 100644 index 000000000..98affe03f --- /dev/null +++ b/slsReceiverSoftware/include/rapidjson/allocators.h @@ -0,0 +1,271 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_ALLOCATORS_H_ +#define RAPIDJSON_ALLOCATORS_H_ + +#include "rapidjson.h" + +RAPIDJSON_NAMESPACE_BEGIN + +/////////////////////////////////////////////////////////////////////////////// +// Allocator + +/*! \class rapidjson::Allocator + \brief Concept for allocating, resizing and freeing memory block. + + Note that Malloc() and Realloc() are non-static but Free() is static. + + So if an allocator need to support Free(), it needs to put its pointer in + the header of memory block. + +\code +concept Allocator { + static const bool kNeedFree; //!< Whether this allocator needs to call Free(). + + // Allocate a memory block. + // \param size of the memory block in bytes. + // \returns pointer to the memory block. + void* Malloc(size_t size); + + // Resize a memory block. + // \param originalPtr The pointer to current memory block. Null pointer is permitted. + // \param originalSize The current size in bytes. (Design issue: since some allocator may not book-keep this, explicitly pass to it can save memory.) + // \param newSize the new size in bytes. + void* Realloc(void* originalPtr, size_t originalSize, size_t newSize); + + // Free a memory block. + // \param pointer to the memory block. Null pointer is permitted. + static void Free(void *ptr); +}; +\endcode +*/ + +/////////////////////////////////////////////////////////////////////////////// +// CrtAllocator + +//! C-runtime library allocator. +/*! This class is just wrapper for standard C library memory routines. + \note implements Allocator concept +*/ +class CrtAllocator { +public: + static const bool kNeedFree = true; + void* Malloc(size_t size) { + if (size) // behavior of malloc(0) is implementation defined. + return std::malloc(size); + else + return NULL; // standardize to returning NULL. + } + void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) { + (void)originalSize; + if (newSize == 0) { + std::free(originalPtr); + return NULL; + } + return std::realloc(originalPtr, newSize); + } + static void Free(void *ptr) { std::free(ptr); } +}; + +/////////////////////////////////////////////////////////////////////////////// +// MemoryPoolAllocator + +//! Default memory allocator used by the parser and DOM. +/*! This allocator allocate memory blocks from pre-allocated memory chunks. + + It does not free memory blocks. And Realloc() only allocate new memory. + + The memory chunks are allocated by BaseAllocator, which is CrtAllocator by default. + + User may also supply a buffer as the first chunk. + + If the user-buffer is full then additional chunks are allocated by BaseAllocator. + + The user-buffer is not deallocated by this allocator. + + \tparam BaseAllocator the allocator type for allocating memory chunks. Default is CrtAllocator. + \note implements Allocator concept +*/ +template +class MemoryPoolAllocator { +public: + static const bool kNeedFree = false; //!< Tell users that no need to call Free() with this allocator. (concept Allocator) + + //! Constructor with chunkSize. + /*! \param chunkSize The size of memory chunk. The default is kDefaultChunkSize. + \param baseAllocator The allocator for allocating memory chunks. + */ + MemoryPoolAllocator(size_t chunkSize = kDefaultChunkCapacity, BaseAllocator* baseAllocator = 0) : + chunkHead_(0), chunk_capacity_(chunkSize), userBuffer_(0), baseAllocator_(baseAllocator), ownBaseAllocator_(0) + { + } + + //! Constructor with user-supplied buffer. + /*! The user buffer will be used firstly. When it is full, memory pool allocates new chunk with chunk size. + + The user buffer will not be deallocated when this allocator is destructed. + + \param buffer User supplied buffer. + \param size Size of the buffer in bytes. It must at least larger than sizeof(ChunkHeader). + \param chunkSize The size of memory chunk. The default is kDefaultChunkSize. + \param baseAllocator The allocator for allocating memory chunks. + */ + MemoryPoolAllocator(void *buffer, size_t size, size_t chunkSize = kDefaultChunkCapacity, BaseAllocator* baseAllocator = 0) : + chunkHead_(0), chunk_capacity_(chunkSize), userBuffer_(buffer), baseAllocator_(baseAllocator), ownBaseAllocator_(0) + { + RAPIDJSON_ASSERT(buffer != 0); + RAPIDJSON_ASSERT(size > sizeof(ChunkHeader)); + chunkHead_ = reinterpret_cast(buffer); + chunkHead_->capacity = size - sizeof(ChunkHeader); + chunkHead_->size = 0; + chunkHead_->next = 0; + } + + //! Destructor. + /*! This deallocates all memory chunks, excluding the user-supplied buffer. + */ + ~MemoryPoolAllocator() { + Clear(); + RAPIDJSON_DELETE(ownBaseAllocator_); + } + + //! Deallocates all memory chunks, excluding the user-supplied buffer. + void Clear() { + while (chunkHead_ && chunkHead_ != userBuffer_) { + ChunkHeader* next = chunkHead_->next; + baseAllocator_->Free(chunkHead_); + chunkHead_ = next; + } + if (chunkHead_ && chunkHead_ == userBuffer_) + chunkHead_->size = 0; // Clear user buffer + } + + //! Computes the total capacity of allocated memory chunks. + /*! \return total capacity in bytes. + */ + size_t Capacity() const { + size_t capacity = 0; + for (ChunkHeader* c = chunkHead_; c != 0; c = c->next) + capacity += c->capacity; + return capacity; + } + + //! Computes the memory blocks allocated. + /*! \return total used bytes. + */ + size_t Size() const { + size_t size = 0; + for (ChunkHeader* c = chunkHead_; c != 0; c = c->next) + size += c->size; + return size; + } + + //! Allocates a memory block. (concept Allocator) + void* Malloc(size_t size) { + if (!size) + return NULL; + + size = RAPIDJSON_ALIGN(size); + if (chunkHead_ == 0 || chunkHead_->size + size > chunkHead_->capacity) + if (!AddChunk(chunk_capacity_ > size ? chunk_capacity_ : size)) + return NULL; + + void *buffer = reinterpret_cast(chunkHead_) + RAPIDJSON_ALIGN(sizeof(ChunkHeader)) + chunkHead_->size; + chunkHead_->size += size; + return buffer; + } + + //! Resizes a memory block (concept Allocator) + void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) { + if (originalPtr == 0) + return Malloc(newSize); + + if (newSize == 0) + return NULL; + + originalSize = RAPIDJSON_ALIGN(originalSize); + newSize = RAPIDJSON_ALIGN(newSize); + + // Do not shrink if new size is smaller than original + if (originalSize >= newSize) + return originalPtr; + + // Simply expand it if it is the last allocation and there is sufficient space + if (originalPtr == reinterpret_cast(chunkHead_) + RAPIDJSON_ALIGN(sizeof(ChunkHeader)) + chunkHead_->size - originalSize) { + size_t increment = static_cast(newSize - originalSize); + if (chunkHead_->size + increment <= chunkHead_->capacity) { + chunkHead_->size += increment; + return originalPtr; + } + } + + // Realloc process: allocate and copy memory, do not free original buffer. + if (void* newBuffer = Malloc(newSize)) { + if (originalSize) + std::memcpy(newBuffer, originalPtr, originalSize); + return newBuffer; + } + else + return NULL; + } + + //! Frees a memory block (concept Allocator) + static void Free(void *ptr) { (void)ptr; } // Do nothing + +private: + //! Copy constructor is not permitted. + MemoryPoolAllocator(const MemoryPoolAllocator& rhs) /* = delete */; + //! Copy assignment operator is not permitted. + MemoryPoolAllocator& operator=(const MemoryPoolAllocator& rhs) /* = delete */; + + //! Creates a new chunk. + /*! \param capacity Capacity of the chunk in bytes. + \return true if success. + */ + bool AddChunk(size_t capacity) { + if (!baseAllocator_) + ownBaseAllocator_ = baseAllocator_ = RAPIDJSON_NEW(BaseAllocator()); + if (ChunkHeader* chunk = reinterpret_cast(baseAllocator_->Malloc(RAPIDJSON_ALIGN(sizeof(ChunkHeader)) + capacity))) { + chunk->capacity = capacity; + chunk->size = 0; + chunk->next = chunkHead_; + chunkHead_ = chunk; + return true; + } + else + return false; + } + + static const int kDefaultChunkCapacity = 64 * 1024; //!< Default chunk capacity. + + //! Chunk header for perpending to each chunk. + /*! Chunks are stored as a singly linked list. + */ + struct ChunkHeader { + size_t capacity; //!< Capacity of the chunk in bytes (excluding the header itself). + size_t size; //!< Current size of allocated memory in bytes. + ChunkHeader *next; //!< Next chunk in the linked list. + }; + + ChunkHeader *chunkHead_; //!< Head of the chunk linked-list. Only the head chunk serves allocation. + size_t chunk_capacity_; //!< The minimum capacity of chunk when they are allocated. + void *userBuffer_; //!< User supplied buffer. + BaseAllocator* baseAllocator_; //!< base allocator for allocating memory chunks. + BaseAllocator* ownBaseAllocator_; //!< base allocator created by this object. +}; + +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_ENCODINGS_H_ diff --git a/slsReceiverSoftware/include/rapidjson/document.h b/slsReceiverSoftware/include/rapidjson/document.h new file mode 100644 index 000000000..e3e20dfbd --- /dev/null +++ b/slsReceiverSoftware/include/rapidjson/document.h @@ -0,0 +1,2575 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_DOCUMENT_H_ +#define RAPIDJSON_DOCUMENT_H_ + +/*! \file document.h */ + +#include "reader.h" +#include "internal/meta.h" +#include "internal/strfunc.h" +#include "memorystream.h" +#include "encodedstream.h" +#include // placement new +#include + +RAPIDJSON_DIAG_PUSH +#ifdef _MSC_VER +RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant +RAPIDJSON_DIAG_OFF(4244) // conversion from kXxxFlags to 'uint16_t', possible loss of data +#endif + +#ifdef __clang__ +RAPIDJSON_DIAG_OFF(padded) +RAPIDJSON_DIAG_OFF(switch-enum) +RAPIDJSON_DIAG_OFF(c++98-compat) +#endif + +#ifdef __GNUC__ +RAPIDJSON_DIAG_OFF(effc++) +#if __GNUC__ >= 6 +RAPIDJSON_DIAG_OFF(terminate) // ignore throwing RAPIDJSON_ASSERT in RAPIDJSON_NOEXCEPT functions +#endif +#endif // __GNUC__ + +#ifndef RAPIDJSON_NOMEMBERITERATORCLASS +#include // std::iterator, std::random_access_iterator_tag +#endif + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS +#include // std::move +#endif + +RAPIDJSON_NAMESPACE_BEGIN + +// Forward declaration. +template +class GenericValue; + +template +class GenericDocument; + +//! Name-value pair in a JSON object value. +/*! + This class was internal to GenericValue. It used to be a inner struct. + But a compiler (IBM XL C/C++ for AIX) have reported to have problem with that so it moved as a namespace scope struct. + https://code.google.com/p/rapidjson/issues/detail?id=64 +*/ +template +struct GenericMember { + GenericValue name; //!< name of member (must be a string) + GenericValue value; //!< value of member. +}; + +/////////////////////////////////////////////////////////////////////////////// +// GenericMemberIterator + +#ifndef RAPIDJSON_NOMEMBERITERATORCLASS + +//! (Constant) member iterator for a JSON object value +/*! + \tparam Const Is this a constant iterator? + \tparam Encoding Encoding of the value. (Even non-string values need to have the same encoding in a document) + \tparam Allocator Allocator type for allocating memory of object, array and string. + + This class implements a Random Access Iterator for GenericMember elements + of a GenericValue, see ISO/IEC 14882:2003(E) C++ standard, 24.1 [lib.iterator.requirements]. + + \note This iterator implementation is mainly intended to avoid implicit + conversions from iterator values to \c NULL, + e.g. from GenericValue::FindMember. + + \note Define \c RAPIDJSON_NOMEMBERITERATORCLASS to fall back to a + pointer-based implementation, if your platform doesn't provide + the C++ header. + + \see GenericMember, GenericValue::MemberIterator, GenericValue::ConstMemberIterator + */ +template +class GenericMemberIterator + : public std::iterator >::Type> { + + friend class GenericValue; + template friend class GenericMemberIterator; + + typedef GenericMember PlainType; + typedef typename internal::MaybeAddConst::Type ValueType; + typedef std::iterator BaseType; + +public: + //! Iterator type itself + typedef GenericMemberIterator Iterator; + //! Constant iterator type + typedef GenericMemberIterator ConstIterator; + //! Non-constant iterator type + typedef GenericMemberIterator NonConstIterator; + + //! Pointer to (const) GenericMember + typedef typename BaseType::pointer Pointer; + //! Reference to (const) GenericMember + typedef typename BaseType::reference Reference; + //! Signed integer type (e.g. \c ptrdiff_t) + typedef typename BaseType::difference_type DifferenceType; + + //! Default constructor (singular value) + /*! Creates an iterator pointing to no element. + \note All operations, except for comparisons, are undefined on such values. + */ + GenericMemberIterator() : ptr_() {} + + //! Iterator conversions to more const + /*! + \param it (Non-const) iterator to copy from + + Allows the creation of an iterator from another GenericMemberIterator + that is "less const". Especially, creating a non-constant iterator + from a constant iterator are disabled: + \li const -> non-const (not ok) + \li const -> const (ok) + \li non-const -> const (ok) + \li non-const -> non-const (ok) + + \note If the \c Const template parameter is already \c false, this + constructor effectively defines a regular copy-constructor. + Otherwise, the copy constructor is implicitly defined. + */ + GenericMemberIterator(const NonConstIterator & it) : ptr_(it.ptr_) {} + Iterator& operator=(const NonConstIterator & it) { ptr_ = it.ptr_; return *this; } + + //! @name stepping + //@{ + Iterator& operator++(){ ++ptr_; return *this; } + Iterator& operator--(){ --ptr_; return *this; } + Iterator operator++(int){ Iterator old(*this); ++ptr_; return old; } + Iterator operator--(int){ Iterator old(*this); --ptr_; return old; } + //@} + + //! @name increment/decrement + //@{ + Iterator operator+(DifferenceType n) const { return Iterator(ptr_+n); } + Iterator operator-(DifferenceType n) const { return Iterator(ptr_-n); } + + Iterator& operator+=(DifferenceType n) { ptr_+=n; return *this; } + Iterator& operator-=(DifferenceType n) { ptr_-=n; return *this; } + //@} + + //! @name relations + //@{ + bool operator==(ConstIterator that) const { return ptr_ == that.ptr_; } + bool operator!=(ConstIterator that) const { return ptr_ != that.ptr_; } + bool operator<=(ConstIterator that) const { return ptr_ <= that.ptr_; } + bool operator>=(ConstIterator that) const { return ptr_ >= that.ptr_; } + bool operator< (ConstIterator that) const { return ptr_ < that.ptr_; } + bool operator> (ConstIterator that) const { return ptr_ > that.ptr_; } + //@} + + //! @name dereference + //@{ + Reference operator*() const { return *ptr_; } + Pointer operator->() const { return ptr_; } + Reference operator[](DifferenceType n) const { return ptr_[n]; } + //@} + + //! Distance + DifferenceType operator-(ConstIterator that) const { return ptr_-that.ptr_; } + +private: + //! Internal constructor from plain pointer + explicit GenericMemberIterator(Pointer p) : ptr_(p) {} + + Pointer ptr_; //!< raw pointer +}; + +#else // RAPIDJSON_NOMEMBERITERATORCLASS + +// class-based member iterator implementation disabled, use plain pointers + +template +struct GenericMemberIterator; + +//! non-const GenericMemberIterator +template +struct GenericMemberIterator { + //! use plain pointer as iterator type + typedef GenericMember* Iterator; +}; +//! const GenericMemberIterator +template +struct GenericMemberIterator { + //! use plain const pointer as iterator type + typedef const GenericMember* Iterator; +}; + +#endif // RAPIDJSON_NOMEMBERITERATORCLASS + +/////////////////////////////////////////////////////////////////////////////// +// GenericStringRef + +//! Reference to a constant string (not taking a copy) +/*! + \tparam CharType character type of the string + + This helper class is used to automatically infer constant string + references for string literals, especially from \c const \b (!) + character arrays. + + The main use is for creating JSON string values without copying the + source string via an \ref Allocator. This requires that the referenced + string pointers have a sufficient lifetime, which exceeds the lifetime + of the associated GenericValue. + + \b Example + \code + Value v("foo"); // ok, no need to copy & calculate length + const char foo[] = "foo"; + v.SetString(foo); // ok + + const char* bar = foo; + // Value x(bar); // not ok, can't rely on bar's lifetime + Value x(StringRef(bar)); // lifetime explicitly guaranteed by user + Value y(StringRef(bar, 3)); // ok, explicitly pass length + \endcode + + \see StringRef, GenericValue::SetString +*/ +template +struct GenericStringRef { + typedef CharType Ch; //!< character type of the string + + //! Create string reference from \c const character array +#ifndef __clang__ // -Wdocumentation + /*! + This constructor implicitly creates a constant string reference from + a \c const character array. It has better performance than + \ref StringRef(const CharType*) by inferring the string \ref length + from the array length, and also supports strings containing null + characters. + + \tparam N length of the string, automatically inferred + + \param str Constant character array, lifetime assumed to be longer + than the use of the string in e.g. a GenericValue + + \post \ref s == str + + \note Constant complexity. + \note There is a hidden, private overload to disallow references to + non-const character arrays to be created via this constructor. + By this, e.g. function-scope arrays used to be filled via + \c snprintf are excluded from consideration. + In such cases, the referenced string should be \b copied to the + GenericValue instead. + */ +#endif + template + GenericStringRef(const CharType (&str)[N]) RAPIDJSON_NOEXCEPT + : s(str), length(N-1) {} + + //! Explicitly create string reference from \c const character pointer +#ifndef __clang__ // -Wdocumentation + /*! + This constructor can be used to \b explicitly create a reference to + a constant string pointer. + + \see StringRef(const CharType*) + + \param str Constant character pointer, lifetime assumed to be longer + than the use of the string in e.g. a GenericValue + + \post \ref s == str + + \note There is a hidden, private overload to disallow references to + non-const character arrays to be created via this constructor. + By this, e.g. function-scope arrays used to be filled via + \c snprintf are excluded from consideration. + In such cases, the referenced string should be \b copied to the + GenericValue instead. + */ +#endif + explicit GenericStringRef(const CharType* str) + : s(str), length(internal::StrLen(str)){ RAPIDJSON_ASSERT(s != 0); } + + //! Create constant string reference from pointer and length +#ifndef __clang__ // -Wdocumentation + /*! \param str constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue + \param len length of the string, excluding the trailing NULL terminator + + \post \ref s == str && \ref length == len + \note Constant complexity. + */ +#endif + GenericStringRef(const CharType* str, SizeType len) + : s(str), length(len) { RAPIDJSON_ASSERT(s != 0); } + + GenericStringRef(const GenericStringRef& rhs) : s(rhs.s), length(rhs.length) {} + + GenericStringRef& operator=(const GenericStringRef& rhs) { s = rhs.s; length = rhs.length; } + + //! implicit conversion to plain CharType pointer + operator const Ch *() const { return s; } + + const Ch* const s; //!< plain CharType pointer + const SizeType length; //!< length of the string (excluding the trailing NULL terminator) + +private: + //! Disallow construction from non-const array + template + GenericStringRef(CharType (&str)[N]) /* = delete */; +}; + +//! Mark a character pointer as constant string +/*! Mark a plain character pointer as a "string literal". This function + can be used to avoid copying a character string to be referenced as a + value in a JSON GenericValue object, if the string's lifetime is known + to be valid long enough. + \tparam CharType Character type of the string + \param str Constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue + \return GenericStringRef string reference object + \relatesalso GenericStringRef + + \see GenericValue::GenericValue(StringRefType), GenericValue::operator=(StringRefType), GenericValue::SetString(StringRefType), GenericValue::PushBack(StringRefType, Allocator&), GenericValue::AddMember +*/ +template +inline GenericStringRef StringRef(const CharType* str) { + return GenericStringRef(str, internal::StrLen(str)); +} + +//! Mark a character pointer as constant string +/*! Mark a plain character pointer as a "string literal". This function + can be used to avoid copying a character string to be referenced as a + value in a JSON GenericValue object, if the string's lifetime is known + to be valid long enough. + + This version has better performance with supplied length, and also + supports string containing null characters. + + \tparam CharType character type of the string + \param str Constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue + \param length The length of source string. + \return GenericStringRef string reference object + \relatesalso GenericStringRef +*/ +template +inline GenericStringRef StringRef(const CharType* str, size_t length) { + return GenericStringRef(str, SizeType(length)); +} + +#if RAPIDJSON_HAS_STDSTRING +//! Mark a string object as constant string +/*! Mark a string object (e.g. \c std::string) as a "string literal". + This function can be used to avoid copying a string to be referenced as a + value in a JSON GenericValue object, if the string's lifetime is known + to be valid long enough. + + \tparam CharType character type of the string + \param str Constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue + \return GenericStringRef string reference object + \relatesalso GenericStringRef + \note Requires the definition of the preprocessor symbol \ref RAPIDJSON_HAS_STDSTRING. +*/ +template +inline GenericStringRef StringRef(const std::basic_string& str) { + return GenericStringRef(str.data(), SizeType(str.size())); +} +#endif + +/////////////////////////////////////////////////////////////////////////////// +// GenericValue type traits +namespace internal { + +template +struct IsGenericValueImpl : FalseType {}; + +// select candidates according to nested encoding and allocator types +template struct IsGenericValueImpl::Type, typename Void::Type> + : IsBaseOf, T>::Type {}; + +// helper to match arbitrary GenericValue instantiations, including derived classes +template struct IsGenericValue : IsGenericValueImpl::Type {}; + +} // namespace internal + +/////////////////////////////////////////////////////////////////////////////// +// TypeHelper + +namespace internal { + +template +struct TypeHelper {}; + +template +struct TypeHelper { + static bool Is(const ValueType& v) { return v.IsBool(); } + static bool Get(const ValueType& v) { return v.GetBool(); } + static ValueType& Set(ValueType& v, bool data) { return v.SetBool(data); } + static ValueType& Set(ValueType& v, bool data, typename ValueType::AllocatorType&) { return v.SetBool(data); } +}; + +template +struct TypeHelper { + static bool Is(const ValueType& v) { return v.IsInt(); } + static int Get(const ValueType& v) { return v.GetInt(); } + static ValueType& Set(ValueType& v, int data) { return v.SetInt(data); } + static ValueType& Set(ValueType& v, int data, typename ValueType::AllocatorType&) { return v.SetInt(data); } +}; + +template +struct TypeHelper { + static bool Is(const ValueType& v) { return v.IsUint(); } + static unsigned Get(const ValueType& v) { return v.GetUint(); } + static ValueType& Set(ValueType& v, unsigned data) { return v.SetUint(data); } + static ValueType& Set(ValueType& v, unsigned data, typename ValueType::AllocatorType&) { return v.SetUint(data); } +}; + +template +struct TypeHelper { + static bool Is(const ValueType& v) { return v.IsInt64(); } + static int64_t Get(const ValueType& v) { return v.GetInt64(); } + static ValueType& Set(ValueType& v, int64_t data) { return v.SetInt64(data); } + static ValueType& Set(ValueType& v, int64_t data, typename ValueType::AllocatorType&) { return v.SetInt64(data); } +}; + +template +struct TypeHelper { + static bool Is(const ValueType& v) { return v.IsUint64(); } + static uint64_t Get(const ValueType& v) { return v.GetUint64(); } + static ValueType& Set(ValueType& v, uint64_t data) { return v.SetUint64(data); } + static ValueType& Set(ValueType& v, uint64_t data, typename ValueType::AllocatorType&) { return v.SetUint64(data); } +}; + +template +struct TypeHelper { + static bool Is(const ValueType& v) { return v.IsDouble(); } + static double Get(const ValueType& v) { return v.GetDouble(); } + static ValueType& Set(ValueType& v, double data) { return v.SetDouble(data); } + static ValueType& Set(ValueType& v, double data, typename ValueType::AllocatorType&) { return v.SetDouble(data); } +}; + +template +struct TypeHelper { + static bool Is(const ValueType& v) { return v.IsFloat(); } + static float Get(const ValueType& v) { return v.GetFloat(); } + static ValueType& Set(ValueType& v, float data) { return v.SetFloat(data); } + static ValueType& Set(ValueType& v, float data, typename ValueType::AllocatorType&) { return v.SetFloat(data); } +}; + +template +struct TypeHelper { + typedef const typename ValueType::Ch* StringType; + static bool Is(const ValueType& v) { return v.IsString(); } + static StringType Get(const ValueType& v) { return v.GetString(); } + static ValueType& Set(ValueType& v, const StringType data) { return v.SetString(typename ValueType::StringRefType(data)); } + static ValueType& Set(ValueType& v, const StringType data, typename ValueType::AllocatorType& a) { return v.SetString(data, a); } +}; + +#if RAPIDJSON_HAS_STDSTRING +template +struct TypeHelper > { + typedef std::basic_string StringType; + static bool Is(const ValueType& v) { return v.IsString(); } + static StringType Get(const ValueType& v) { return StringType(v.GetString(), v.GetStringLength()); } + static ValueType& Set(ValueType& v, const StringType& data, typename ValueType::AllocatorType& a) { return v.SetString(data, a); } +}; +#endif + +template +struct TypeHelper { + typedef typename ValueType::Array ArrayType; + static bool Is(const ValueType& v) { return v.IsArray(); } + static ArrayType Get(ValueType& v) { return v.GetArray(); } + static ValueType& Set(ValueType& v, ArrayType data) { return v = data; } + static ValueType& Set(ValueType& v, ArrayType data, typename ValueType::AllocatorType&) { return v = data; } +}; + +template +struct TypeHelper { + typedef typename ValueType::ConstArray ArrayType; + static bool Is(const ValueType& v) { return v.IsArray(); } + static ArrayType Get(const ValueType& v) { return v.GetArray(); } +}; + +template +struct TypeHelper { + typedef typename ValueType::Object ObjectType; + static bool Is(const ValueType& v) { return v.IsObject(); } + static ObjectType Get(ValueType& v) { return v.GetObject(); } + static ValueType& Set(ValueType& v, ObjectType data) { return v = data; } + static ValueType& Set(ValueType& v, ObjectType data, typename ValueType::AllocatorType&) { v = data; } +}; + +template +struct TypeHelper { + typedef typename ValueType::ConstObject ObjectType; + static bool Is(const ValueType& v) { return v.IsObject(); } + static ObjectType Get(const ValueType& v) { return v.GetObject(); } +}; + +} // namespace internal + +// Forward declarations +template class GenericArray; +template class GenericObject; + +/////////////////////////////////////////////////////////////////////////////// +// GenericValue + +//! Represents a JSON value. Use Value for UTF8 encoding and default allocator. +/*! + A JSON value can be one of 7 types. This class is a variant type supporting + these types. + + Use the Value if UTF8 and default allocator + + \tparam Encoding Encoding of the value. (Even non-string values need to have the same encoding in a document) + \tparam Allocator Allocator type for allocating memory of object, array and string. +*/ +template > +class GenericValue { +public: + //! Name-value pair in an object. + typedef GenericMember Member; + typedef Encoding EncodingType; //!< Encoding type from template parameter. + typedef Allocator AllocatorType; //!< Allocator type from template parameter. + typedef typename Encoding::Ch Ch; //!< Character type derived from Encoding. + typedef GenericStringRef StringRefType; //!< Reference to a constant string + typedef typename GenericMemberIterator::Iterator MemberIterator; //!< Member iterator for iterating in object. + typedef typename GenericMemberIterator::Iterator ConstMemberIterator; //!< Constant member iterator for iterating in object. + typedef GenericValue* ValueIterator; //!< Value iterator for iterating in array. + typedef const GenericValue* ConstValueIterator; //!< Constant value iterator for iterating in array. + typedef GenericValue ValueType; //!< Value type of itself. + typedef GenericArray Array; + typedef GenericArray ConstArray; + typedef GenericObject Object; + typedef GenericObject ConstObject; + + //!@name Constructors and destructor. + //@{ + + //! Default constructor creates a null value. + GenericValue() RAPIDJSON_NOEXCEPT : data_() { data_.f.flags = kNullFlag; } + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + //! Move constructor in C++11 + GenericValue(GenericValue&& rhs) RAPIDJSON_NOEXCEPT : data_(rhs.data_) { + rhs.data_.f.flags = kNullFlag; // give up contents + } +#endif + +private: + //! Copy constructor is not permitted. + GenericValue(const GenericValue& rhs); + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + //! Moving from a GenericDocument is not permitted. + template + GenericValue(GenericDocument&& rhs); + + //! Move assignment from a GenericDocument is not permitted. + template + GenericValue& operator=(GenericDocument&& rhs); +#endif + +public: + + //! Constructor with JSON value type. + /*! This creates a Value of specified type with default content. + \param type Type of the value. + \note Default content for number is zero. + */ + explicit GenericValue(Type type) RAPIDJSON_NOEXCEPT : data_() { + static const uint16_t defaultFlags[7] = { + kNullFlag, kFalseFlag, kTrueFlag, kObjectFlag, kArrayFlag, kShortStringFlag, + kNumberAnyFlag + }; + RAPIDJSON_ASSERT(type <= kNumberType); + data_.f.flags = defaultFlags[type]; + + // Use ShortString to store empty string. + if (type == kStringType) + data_.ss.SetLength(0); + } + + //! Explicit copy constructor (with allocator) + /*! Creates a copy of a Value by using the given Allocator + \tparam SourceAllocator allocator of \c rhs + \param rhs Value to copy from (read-only) + \param allocator Allocator for allocating copied elements and buffers. Commonly use GenericDocument::GetAllocator(). + \see CopyFrom() + */ + template< typename SourceAllocator > + GenericValue(const GenericValue& rhs, Allocator & allocator); + + //! Constructor for boolean value. + /*! \param b Boolean value + \note This constructor is limited to \em real boolean values and rejects + implicitly converted types like arbitrary pointers. Use an explicit cast + to \c bool, if you want to construct a boolean JSON value in such cases. + */ +#ifndef RAPIDJSON_DOXYGEN_RUNNING // hide SFINAE from Doxygen + template + explicit GenericValue(T b, RAPIDJSON_ENABLEIF((internal::IsSame))) RAPIDJSON_NOEXCEPT // See #472 +#else + explicit GenericValue(bool b) RAPIDJSON_NOEXCEPT +#endif + : data_() { + // safe-guard against failing SFINAE + RAPIDJSON_STATIC_ASSERT((internal::IsSame::Value)); + data_.f.flags = b ? kTrueFlag : kFalseFlag; + } + + //! Constructor for int value. + explicit GenericValue(int i) RAPIDJSON_NOEXCEPT : data_() { + data_.n.i64 = i; + data_.f.flags = (i >= 0) ? (kNumberIntFlag | kUintFlag | kUint64Flag) : kNumberIntFlag; + } + + //! Constructor for unsigned value. + explicit GenericValue(unsigned u) RAPIDJSON_NOEXCEPT : data_() { + data_.n.u64 = u; + data_.f.flags = (u & 0x80000000) ? kNumberUintFlag : (kNumberUintFlag | kIntFlag | kInt64Flag); + } + + //! Constructor for int64_t value. + explicit GenericValue(int64_t i64) RAPIDJSON_NOEXCEPT : data_() { + data_.n.i64 = i64; + data_.f.flags = kNumberInt64Flag; + if (i64 >= 0) { + data_.f.flags |= kNumberUint64Flag; + if (!(static_cast(i64) & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x00000000))) + data_.f.flags |= kUintFlag; + if (!(static_cast(i64) & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000))) + data_.f.flags |= kIntFlag; + } + else if (i64 >= static_cast(RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000))) + data_.f.flags |= kIntFlag; + } + + //! Constructor for uint64_t value. + explicit GenericValue(uint64_t u64) RAPIDJSON_NOEXCEPT : data_() { + data_.n.u64 = u64; + data_.f.flags = kNumberUint64Flag; + if (!(u64 & RAPIDJSON_UINT64_C2(0x80000000, 0x00000000))) + data_.f.flags |= kInt64Flag; + if (!(u64 & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x00000000))) + data_.f.flags |= kUintFlag; + if (!(u64 & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000))) + data_.f.flags |= kIntFlag; + } + + //! Constructor for double value. + explicit GenericValue(double d) RAPIDJSON_NOEXCEPT : data_() { data_.n.d = d; data_.f.flags = kNumberDoubleFlag; } + + //! Constructor for constant string (i.e. do not make a copy of string) + GenericValue(const Ch* s, SizeType length) RAPIDJSON_NOEXCEPT : data_() { SetStringRaw(StringRef(s, length)); } + + //! Constructor for constant string (i.e. do not make a copy of string) + explicit GenericValue(StringRefType s) RAPIDJSON_NOEXCEPT : data_() { SetStringRaw(s); } + + //! Constructor for copy-string (i.e. do make a copy of string) + GenericValue(const Ch* s, SizeType length, Allocator& allocator) : data_() { SetStringRaw(StringRef(s, length), allocator); } + + //! Constructor for copy-string (i.e. do make a copy of string) + GenericValue(const Ch*s, Allocator& allocator) : data_() { SetStringRaw(StringRef(s), allocator); } + +#if RAPIDJSON_HAS_STDSTRING + //! Constructor for copy-string from a string object (i.e. do make a copy of string) + /*! \note Requires the definition of the preprocessor symbol \ref RAPIDJSON_HAS_STDSTRING. + */ + GenericValue(const std::basic_string& s, Allocator& allocator) : data_() { SetStringRaw(StringRef(s), allocator); } +#endif + + //! Constructor for Array. + /*! + \param a An array obtained by \c GetArray(). + \note \c Array is always pass-by-value. + \note the source array is moved into this value and the sourec array becomes empty. + */ + GenericValue(Array a) RAPIDJSON_NOEXCEPT : data_(a.value_.data_) { + a.value_.data_ = Data(); + a.value_.data_.f.flags = kArrayFlag; + } + + //! Constructor for Object. + /*! + \param o An object obtained by \c GetObject(). + \note \c Object is always pass-by-value. + \note the source object is moved into this value and the sourec object becomes empty. + */ + GenericValue(Object o) RAPIDJSON_NOEXCEPT : data_(o.value_.data_) { + o.value_.data_ = Data(); + o.value_.data_.f.flags = kObjectFlag; + } + + //! Destructor. + /*! Need to destruct elements of array, members of object, or copy-string. + */ + ~GenericValue() { + if (Allocator::kNeedFree) { // Shortcut by Allocator's trait + switch(data_.f.flags) { + case kArrayFlag: + { + GenericValue* e = GetElementsPointer(); + for (GenericValue* v = e; v != e + data_.a.size; ++v) + v->~GenericValue(); + Allocator::Free(e); + } + break; + + case kObjectFlag: + for (MemberIterator m = MemberBegin(); m != MemberEnd(); ++m) + m->~Member(); + Allocator::Free(GetMembersPointer()); + break; + + case kCopyStringFlag: + Allocator::Free(const_cast(GetStringPointer())); + break; + + default: + break; // Do nothing for other types. + } + } + } + + //@} + + //!@name Assignment operators + //@{ + + //! Assignment with move semantics. + /*! \param rhs Source of the assignment. It will become a null value after assignment. + */ + GenericValue& operator=(GenericValue& rhs) RAPIDJSON_NOEXCEPT { + RAPIDJSON_ASSERT(this != &rhs); + this->~GenericValue(); + RawAssign(rhs); + return *this; + } + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + //! Move assignment in C++11 + GenericValue& operator=(GenericValue&& rhs) RAPIDJSON_NOEXCEPT { + return *this = rhs.Move(); + } +#endif + + //! Assignment of constant string reference (no copy) + /*! \param str Constant string reference to be assigned + \note This overload is needed to avoid clashes with the generic primitive type assignment overload below. + \see GenericStringRef, operator=(T) + */ + GenericValue& operator=(StringRefType str) RAPIDJSON_NOEXCEPT { + GenericValue s(str); + return *this = s; + } + + //! Assignment with primitive types. + /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t + \param value The value to be assigned. + + \note The source type \c T explicitly disallows all pointer types, + especially (\c const) \ref Ch*. This helps avoiding implicitly + referencing character strings with insufficient lifetime, use + \ref SetString(const Ch*, Allocator&) (for copying) or + \ref StringRef() (to explicitly mark the pointer as constant) instead. + All other pointer types would implicitly convert to \c bool, + use \ref SetBool() instead. + */ + template + RAPIDJSON_DISABLEIF_RETURN((internal::IsPointer), (GenericValue&)) + operator=(T value) { + GenericValue v(value); + return *this = v; + } + + //! Deep-copy assignment from Value + /*! Assigns a \b copy of the Value to the current Value object + \tparam SourceAllocator Allocator type of \c rhs + \param rhs Value to copy from (read-only) + \param allocator Allocator to use for copying + */ + template + GenericValue& CopyFrom(const GenericValue& rhs, Allocator& allocator) { + RAPIDJSON_ASSERT(static_cast(this) != static_cast(&rhs)); + this->~GenericValue(); + new (this) GenericValue(rhs, allocator); + return *this; + } + + //! Exchange the contents of this value with those of other. + /*! + \param other Another value. + \note Constant complexity. + */ + GenericValue& Swap(GenericValue& other) RAPIDJSON_NOEXCEPT { + GenericValue temp; + temp.RawAssign(*this); + RawAssign(other); + other.RawAssign(temp); + return *this; + } + + //! free-standing swap function helper + /*! + Helper function to enable support for common swap implementation pattern based on \c std::swap: + \code + void swap(MyClass& a, MyClass& b) { + using std::swap; + swap(a.value, b.value); + // ... + } + \endcode + \see Swap() + */ + friend inline void swap(GenericValue& a, GenericValue& b) RAPIDJSON_NOEXCEPT { a.Swap(b); } + + //! Prepare Value for move semantics + /*! \return *this */ + GenericValue& Move() RAPIDJSON_NOEXCEPT { return *this; } + //@} + + //!@name Equal-to and not-equal-to operators + //@{ + //! Equal-to operator + /*! + \note If an object contains duplicated named member, comparing equality with any object is always \c false. + \note Linear time complexity (number of all values in the subtree and total lengths of all strings). + */ + template + bool operator==(const GenericValue& rhs) const { + typedef GenericValue RhsType; + if (GetType() != rhs.GetType()) + return false; + + switch (GetType()) { + case kObjectType: // Warning: O(n^2) inner-loop + if (data_.o.size != rhs.data_.o.size) + return false; + for (ConstMemberIterator lhsMemberItr = MemberBegin(); lhsMemberItr != MemberEnd(); ++lhsMemberItr) { + typename RhsType::ConstMemberIterator rhsMemberItr = rhs.FindMember(lhsMemberItr->name); + if (rhsMemberItr == rhs.MemberEnd() || lhsMemberItr->value != rhsMemberItr->value) + return false; + } + return true; + + case kArrayType: + if (data_.a.size != rhs.data_.a.size) + return false; + for (SizeType i = 0; i < data_.a.size; i++) + if ((*this)[i] != rhs[i]) + return false; + return true; + + case kStringType: + return StringEqual(rhs); + + case kNumberType: + if (IsDouble() || rhs.IsDouble()) { + double a = GetDouble(); // May convert from integer to double. + double b = rhs.GetDouble(); // Ditto + return a >= b && a <= b; // Prevent -Wfloat-equal + } + else + return data_.n.u64 == rhs.data_.n.u64; + + default: + return true; + } + } + + //! Equal-to operator with const C-string pointer + bool operator==(const Ch* rhs) const { return *this == GenericValue(StringRef(rhs)); } + +#if RAPIDJSON_HAS_STDSTRING + //! Equal-to operator with string object + /*! \note Requires the definition of the preprocessor symbol \ref RAPIDJSON_HAS_STDSTRING. + */ + bool operator==(const std::basic_string& rhs) const { return *this == GenericValue(StringRef(rhs)); } +#endif + + //! Equal-to operator with primitive types + /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t, \c double, \c true, \c false + */ + template RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr,internal::IsGenericValue >), (bool)) operator==(const T& rhs) const { return *this == GenericValue(rhs); } + + //! Not-equal-to operator + /*! \return !(*this == rhs) + */ + template + bool operator!=(const GenericValue& rhs) const { return !(*this == rhs); } + + //! Not-equal-to operator with const C-string pointer + bool operator!=(const Ch* rhs) const { return !(*this == rhs); } + + //! Not-equal-to operator with arbitrary types + /*! \return !(*this == rhs) + */ + template RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue), (bool)) operator!=(const T& rhs) const { return !(*this == rhs); } + + //! Equal-to operator with arbitrary types (symmetric version) + /*! \return (rhs == lhs) + */ + template friend RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue), (bool)) operator==(const T& lhs, const GenericValue& rhs) { return rhs == lhs; } + + //! Not-Equal-to operator with arbitrary types (symmetric version) + /*! \return !(rhs == lhs) + */ + template friend RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue), (bool)) operator!=(const T& lhs, const GenericValue& rhs) { return !(rhs == lhs); } + //@} + + //!@name Type + //@{ + + Type GetType() const { return static_cast(data_.f.flags & kTypeMask); } + bool IsNull() const { return data_.f.flags == kNullFlag; } + bool IsFalse() const { return data_.f.flags == kFalseFlag; } + bool IsTrue() const { return data_.f.flags == kTrueFlag; } + bool IsBool() const { return (data_.f.flags & kBoolFlag) != 0; } + bool IsObject() const { return data_.f.flags == kObjectFlag; } + bool IsArray() const { return data_.f.flags == kArrayFlag; } + bool IsNumber() const { return (data_.f.flags & kNumberFlag) != 0; } + bool IsInt() const { return (data_.f.flags & kIntFlag) != 0; } + bool IsUint() const { return (data_.f.flags & kUintFlag) != 0; } + bool IsInt64() const { return (data_.f.flags & kInt64Flag) != 0; } + bool IsUint64() const { return (data_.f.flags & kUint64Flag) != 0; } + bool IsDouble() const { return (data_.f.flags & kDoubleFlag) != 0; } + bool IsString() const { return (data_.f.flags & kStringFlag) != 0; } + + // Checks whether a number can be losslessly converted to a double. + bool IsLosslessDouble() const { + if (!IsNumber()) return false; + if (IsUint64()) { + uint64_t u = GetUint64(); + volatile double d = static_cast(u); + return (d >= 0.0) + && (d < static_cast(std::numeric_limits::max())) + && (u == static_cast(d)); + } + if (IsInt64()) { + int64_t i = GetInt64(); + volatile double d = static_cast(i); + return (d >= static_cast(std::numeric_limits::min())) + && (d < static_cast(std::numeric_limits::max())) + && (i == static_cast(d)); + } + return true; // double, int, uint are always lossless + } + + // Checks whether a number is a float (possible lossy). + bool IsFloat() const { + if ((data_.f.flags & kDoubleFlag) == 0) + return false; + double d = GetDouble(); + return d >= -3.4028234e38 && d <= 3.4028234e38; + } + // Checks whether a number can be losslessly converted to a float. + bool IsLosslessFloat() const { + if (!IsNumber()) return false; + double a = GetDouble(); + if (a < static_cast(-std::numeric_limits::max()) + || a > static_cast(std::numeric_limits::max())) + return false; + double b = static_cast(static_cast(a)); + return a >= b && a <= b; // Prevent -Wfloat-equal + } + + //@} + + //!@name Null + //@{ + + GenericValue& SetNull() { this->~GenericValue(); new (this) GenericValue(); return *this; } + + //@} + + //!@name Bool + //@{ + + bool GetBool() const { RAPIDJSON_ASSERT(IsBool()); return data_.f.flags == kTrueFlag; } + //!< Set boolean value + /*! \post IsBool() == true */ + GenericValue& SetBool(bool b) { this->~GenericValue(); new (this) GenericValue(b); return *this; } + + //@} + + //!@name Object + //@{ + + //! Set this value as an empty object. + /*! \post IsObject() == true */ + GenericValue& SetObject() { this->~GenericValue(); new (this) GenericValue(kObjectType); return *this; } + + //! Get the number of members in the object. + SizeType MemberCount() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.size; } + + //! Check whether the object is empty. + bool ObjectEmpty() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.size == 0; } + + //! Get a value from an object associated with the name. + /*! \pre IsObject() == true + \tparam T Either \c Ch or \c const \c Ch (template used for disambiguation with \ref operator[](SizeType)) + \note In version 0.1x, if the member is not found, this function returns a null value. This makes issue 7. + Since 0.2, if the name is not correct, it will assert. + If user is unsure whether a member exists, user should use HasMember() first. + A better approach is to use FindMember(). + \note Linear time complexity. + */ + template + RAPIDJSON_DISABLEIF_RETURN((internal::NotExpr::Type, Ch> >),(GenericValue&)) operator[](T* name) { + GenericValue n(StringRef(name)); + return (*this)[n]; + } + template + RAPIDJSON_DISABLEIF_RETURN((internal::NotExpr::Type, Ch> >),(const GenericValue&)) operator[](T* name) const { return const_cast(*this)[name]; } + + //! Get a value from an object associated with the name. + /*! \pre IsObject() == true + \tparam SourceAllocator Allocator of the \c name value + + \note Compared to \ref operator[](T*), this version is faster because it does not need a StrLen(). + And it can also handle strings with embedded null characters. + + \note Linear time complexity. + */ + template + GenericValue& operator[](const GenericValue& name) { + MemberIterator member = FindMember(name); + if (member != MemberEnd()) + return member->value; + else { + RAPIDJSON_ASSERT(false); // see above note + + // This will generate -Wexit-time-destructors in clang + // static GenericValue NullValue; + // return NullValue; + + // Use static buffer and placement-new to prevent destruction + static char buffer[sizeof(GenericValue)]; + return *new (buffer) GenericValue(); + } + } + template + const GenericValue& operator[](const GenericValue& name) const { return const_cast(*this)[name]; } + +#if RAPIDJSON_HAS_STDSTRING + //! Get a value from an object associated with name (string object). + GenericValue& operator[](const std::basic_string& name) { return (*this)[GenericValue(StringRef(name))]; } + const GenericValue& operator[](const std::basic_string& name) const { return (*this)[GenericValue(StringRef(name))]; } +#endif + + //! Const member iterator + /*! \pre IsObject() == true */ + ConstMemberIterator MemberBegin() const { RAPIDJSON_ASSERT(IsObject()); return ConstMemberIterator(GetMembersPointer()); } + //! Const \em past-the-end member iterator + /*! \pre IsObject() == true */ + ConstMemberIterator MemberEnd() const { RAPIDJSON_ASSERT(IsObject()); return ConstMemberIterator(GetMembersPointer() + data_.o.size); } + //! Member iterator + /*! \pre IsObject() == true */ + MemberIterator MemberBegin() { RAPIDJSON_ASSERT(IsObject()); return MemberIterator(GetMembersPointer()); } + //! \em Past-the-end member iterator + /*! \pre IsObject() == true */ + MemberIterator MemberEnd() { RAPIDJSON_ASSERT(IsObject()); return MemberIterator(GetMembersPointer() + data_.o.size); } + + //! Check whether a member exists in the object. + /*! + \param name Member name to be searched. + \pre IsObject() == true + \return Whether a member with that name exists. + \note It is better to use FindMember() directly if you need the obtain the value as well. + \note Linear time complexity. + */ + bool HasMember(const Ch* name) const { return FindMember(name) != MemberEnd(); } + +#if RAPIDJSON_HAS_STDSTRING + //! Check whether a member exists in the object with string object. + /*! + \param name Member name to be searched. + \pre IsObject() == true + \return Whether a member with that name exists. + \note It is better to use FindMember() directly if you need the obtain the value as well. + \note Linear time complexity. + */ + bool HasMember(const std::basic_string& name) const { return FindMember(name) != MemberEnd(); } +#endif + + //! Check whether a member exists in the object with GenericValue name. + /*! + This version is faster because it does not need a StrLen(). It can also handle string with null character. + \param name Member name to be searched. + \pre IsObject() == true + \return Whether a member with that name exists. + \note It is better to use FindMember() directly if you need the obtain the value as well. + \note Linear time complexity. + */ + template + bool HasMember(const GenericValue& name) const { return FindMember(name) != MemberEnd(); } + + //! Find member by name. + /*! + \param name Member name to be searched. + \pre IsObject() == true + \return Iterator to member, if it exists. + Otherwise returns \ref MemberEnd(). + + \note Earlier versions of Rapidjson returned a \c NULL pointer, in case + the requested member doesn't exist. For consistency with e.g. + \c std::map, this has been changed to MemberEnd() now. + \note Linear time complexity. + */ + MemberIterator FindMember(const Ch* name) { + GenericValue n(StringRef(name)); + return FindMember(n); + } + + ConstMemberIterator FindMember(const Ch* name) const { return const_cast(*this).FindMember(name); } + + //! Find member by name. + /*! + This version is faster because it does not need a StrLen(). It can also handle string with null character. + \param name Member name to be searched. + \pre IsObject() == true + \return Iterator to member, if it exists. + Otherwise returns \ref MemberEnd(). + + \note Earlier versions of Rapidjson returned a \c NULL pointer, in case + the requested member doesn't exist. For consistency with e.g. + \c std::map, this has been changed to MemberEnd() now. + \note Linear time complexity. + */ + template + MemberIterator FindMember(const GenericValue& name) { + RAPIDJSON_ASSERT(IsObject()); + RAPIDJSON_ASSERT(name.IsString()); + MemberIterator member = MemberBegin(); + for ( ; member != MemberEnd(); ++member) + if (name.StringEqual(member->name)) + break; + return member; + } + template ConstMemberIterator FindMember(const GenericValue& name) const { return const_cast(*this).FindMember(name); } + +#if RAPIDJSON_HAS_STDSTRING + //! Find member by string object name. + /*! + \param name Member name to be searched. + \pre IsObject() == true + \return Iterator to member, if it exists. + Otherwise returns \ref MemberEnd(). + */ + MemberIterator FindMember(const std::basic_string& name) { return FindMember(GenericValue(StringRef(name))); } + ConstMemberIterator FindMember(const std::basic_string& name) const { return FindMember(GenericValue(StringRef(name))); } +#endif + + //! Add a member (name-value pair) to the object. + /*! \param name A string value as name of member. + \param value Value of any type. + \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). + \return The value itself for fluent API. + \note The ownership of \c name and \c value will be transferred to this object on success. + \pre IsObject() && name.IsString() + \post name.IsNull() && value.IsNull() + \note Amortized Constant time complexity. + */ + GenericValue& AddMember(GenericValue& name, GenericValue& value, Allocator& allocator) { + RAPIDJSON_ASSERT(IsObject()); + RAPIDJSON_ASSERT(name.IsString()); + + ObjectData& o = data_.o; + if (o.size >= o.capacity) { + if (o.capacity == 0) { + o.capacity = kDefaultObjectCapacity; + SetMembersPointer(reinterpret_cast(allocator.Malloc(o.capacity * sizeof(Member)))); + } + else { + SizeType oldCapacity = o.capacity; + o.capacity += (oldCapacity + 1) / 2; // grow by factor 1.5 + SetMembersPointer(reinterpret_cast(allocator.Realloc(GetMembersPointer(), oldCapacity * sizeof(Member), o.capacity * sizeof(Member)))); + } + } + Member* members = GetMembersPointer(); + members[o.size].name.RawAssign(name); + members[o.size].value.RawAssign(value); + o.size++; + return *this; + } + + //! Add a constant string value as member (name-value pair) to the object. + /*! \param name A string value as name of member. + \param value constant string reference as value of member. + \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). + \return The value itself for fluent API. + \pre IsObject() + \note This overload is needed to avoid clashes with the generic primitive type AddMember(GenericValue&,T,Allocator&) overload below. + \note Amortized Constant time complexity. + */ + GenericValue& AddMember(GenericValue& name, StringRefType value, Allocator& allocator) { + GenericValue v(value); + return AddMember(name, v, allocator); + } + +#if RAPIDJSON_HAS_STDSTRING + //! Add a string object as member (name-value pair) to the object. + /*! \param name A string value as name of member. + \param value constant string reference as value of member. + \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). + \return The value itself for fluent API. + \pre IsObject() + \note This overload is needed to avoid clashes with the generic primitive type AddMember(GenericValue&,T,Allocator&) overload below. + \note Amortized Constant time complexity. + */ + GenericValue& AddMember(GenericValue& name, std::basic_string& value, Allocator& allocator) { + GenericValue v(value, allocator); + return AddMember(name, v, allocator); + } +#endif + + //! Add any primitive value as member (name-value pair) to the object. + /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t + \param name A string value as name of member. + \param value Value of primitive type \c T as value of member + \param allocator Allocator for reallocating memory. Commonly use GenericDocument::GetAllocator(). + \return The value itself for fluent API. + \pre IsObject() + + \note The source type \c T explicitly disallows all pointer types, + especially (\c const) \ref Ch*. This helps avoiding implicitly + referencing character strings with insufficient lifetime, use + \ref AddMember(StringRefType, GenericValue&, Allocator&) or \ref + AddMember(StringRefType, StringRefType, Allocator&). + All other pointer types would implicitly convert to \c bool, + use an explicit cast instead, if needed. + \note Amortized Constant time complexity. + */ + template + RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (GenericValue&)) + AddMember(GenericValue& name, T value, Allocator& allocator) { + GenericValue v(value); + return AddMember(name, v, allocator); + } + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + GenericValue& AddMember(GenericValue&& name, GenericValue&& value, Allocator& allocator) { + return AddMember(name, value, allocator); + } + GenericValue& AddMember(GenericValue&& name, GenericValue& value, Allocator& allocator) { + return AddMember(name, value, allocator); + } + GenericValue& AddMember(GenericValue& name, GenericValue&& value, Allocator& allocator) { + return AddMember(name, value, allocator); + } + GenericValue& AddMember(StringRefType name, GenericValue&& value, Allocator& allocator) { + GenericValue n(name); + return AddMember(n, value, allocator); + } +#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS + + + //! Add a member (name-value pair) to the object. + /*! \param name A constant string reference as name of member. + \param value Value of any type. + \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). + \return The value itself for fluent API. + \note The ownership of \c value will be transferred to this object on success. + \pre IsObject() + \post value.IsNull() + \note Amortized Constant time complexity. + */ + GenericValue& AddMember(StringRefType name, GenericValue& value, Allocator& allocator) { + GenericValue n(name); + return AddMember(n, value, allocator); + } + + //! Add a constant string value as member (name-value pair) to the object. + /*! \param name A constant string reference as name of member. + \param value constant string reference as value of member. + \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). + \return The value itself for fluent API. + \pre IsObject() + \note This overload is needed to avoid clashes with the generic primitive type AddMember(StringRefType,T,Allocator&) overload below. + \note Amortized Constant time complexity. + */ + GenericValue& AddMember(StringRefType name, StringRefType value, Allocator& allocator) { + GenericValue v(value); + return AddMember(name, v, allocator); + } + + //! Add any primitive value as member (name-value pair) to the object. + /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t + \param name A constant string reference as name of member. + \param value Value of primitive type \c T as value of member + \param allocator Allocator for reallocating memory. Commonly use GenericDocument::GetAllocator(). + \return The value itself for fluent API. + \pre IsObject() + + \note The source type \c T explicitly disallows all pointer types, + especially (\c const) \ref Ch*. This helps avoiding implicitly + referencing character strings with insufficient lifetime, use + \ref AddMember(StringRefType, GenericValue&, Allocator&) or \ref + AddMember(StringRefType, StringRefType, Allocator&). + All other pointer types would implicitly convert to \c bool, + use an explicit cast instead, if needed. + \note Amortized Constant time complexity. + */ + template + RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (GenericValue&)) + AddMember(StringRefType name, T value, Allocator& allocator) { + GenericValue n(name); + return AddMember(n, value, allocator); + } + + //! Remove all members in the object. + /*! This function do not deallocate memory in the object, i.e. the capacity is unchanged. + \note Linear time complexity. + */ + void RemoveAllMembers() { + RAPIDJSON_ASSERT(IsObject()); + for (MemberIterator m = MemberBegin(); m != MemberEnd(); ++m) + m->~Member(); + data_.o.size = 0; + } + + //! Remove a member in object by its name. + /*! \param name Name of member to be removed. + \return Whether the member existed. + \note This function may reorder the object members. Use \ref + EraseMember(ConstMemberIterator) if you need to preserve the + relative order of the remaining members. + \note Linear time complexity. + */ + bool RemoveMember(const Ch* name) { + GenericValue n(StringRef(name)); + return RemoveMember(n); + } + +#if RAPIDJSON_HAS_STDSTRING + bool RemoveMember(const std::basic_string& name) { return RemoveMember(GenericValue(StringRef(name))); } +#endif + + template + bool RemoveMember(const GenericValue& name) { + MemberIterator m = FindMember(name); + if (m != MemberEnd()) { + RemoveMember(m); + return true; + } + else + return false; + } + + //! Remove a member in object by iterator. + /*! \param m member iterator (obtained by FindMember() or MemberBegin()). + \return the new iterator after removal. + \note This function may reorder the object members. Use \ref + EraseMember(ConstMemberIterator) if you need to preserve the + relative order of the remaining members. + \note Constant time complexity. + */ + MemberIterator RemoveMember(MemberIterator m) { + RAPIDJSON_ASSERT(IsObject()); + RAPIDJSON_ASSERT(data_.o.size > 0); + RAPIDJSON_ASSERT(GetMembersPointer() != 0); + RAPIDJSON_ASSERT(m >= MemberBegin() && m < MemberEnd()); + + MemberIterator last(GetMembersPointer() + (data_.o.size - 1)); + if (data_.o.size > 1 && m != last) + *m = *last; // Move the last one to this place + else + m->~Member(); // Only one left, just destroy + --data_.o.size; + return m; + } + + //! Remove a member from an object by iterator. + /*! \param pos iterator to the member to remove + \pre IsObject() == true && \ref MemberBegin() <= \c pos < \ref MemberEnd() + \return Iterator following the removed element. + If the iterator \c pos refers to the last element, the \ref MemberEnd() iterator is returned. + \note This function preserves the relative order of the remaining object + members. If you do not need this, use the more efficient \ref RemoveMember(MemberIterator). + \note Linear time complexity. + */ + MemberIterator EraseMember(ConstMemberIterator pos) { + return EraseMember(pos, pos +1); + } + + //! Remove members in the range [first, last) from an object. + /*! \param first iterator to the first member to remove + \param last iterator following the last member to remove + \pre IsObject() == true && \ref MemberBegin() <= \c first <= \c last <= \ref MemberEnd() + \return Iterator following the last removed element. + \note This function preserves the relative order of the remaining object + members. + \note Linear time complexity. + */ + MemberIterator EraseMember(ConstMemberIterator first, ConstMemberIterator last) { + RAPIDJSON_ASSERT(IsObject()); + RAPIDJSON_ASSERT(data_.o.size > 0); + RAPIDJSON_ASSERT(GetMembersPointer() != 0); + RAPIDJSON_ASSERT(first >= MemberBegin()); + RAPIDJSON_ASSERT(first <= last); + RAPIDJSON_ASSERT(last <= MemberEnd()); + + MemberIterator pos = MemberBegin() + (first - MemberBegin()); + for (MemberIterator itr = pos; itr != last; ++itr) + itr->~Member(); + std::memmove(&*pos, &*last, static_cast(MemberEnd() - last) * sizeof(Member)); + data_.o.size -= static_cast(last - first); + return pos; + } + + //! Erase a member in object by its name. + /*! \param name Name of member to be removed. + \return Whether the member existed. + \note Linear time complexity. + */ + bool EraseMember(const Ch* name) { + GenericValue n(StringRef(name)); + return EraseMember(n); + } + +#if RAPIDJSON_HAS_STDSTRING + bool EraseMember(const std::basic_string& name) { return EraseMember(GenericValue(StringRef(name))); } +#endif + + template + bool EraseMember(const GenericValue& name) { + MemberIterator m = FindMember(name); + if (m != MemberEnd()) { + EraseMember(m); + return true; + } + else + return false; + } + + Object GetObject() { RAPIDJSON_ASSERT(IsObject()); return Object(*this); } + ConstObject GetObject() const { RAPIDJSON_ASSERT(IsObject()); return ConstObject(*this); } + + //@} + + //!@name Array + //@{ + + //! Set this value as an empty array. + /*! \post IsArray == true */ + GenericValue& SetArray() { this->~GenericValue(); new (this) GenericValue(kArrayType); return *this; } + + //! Get the number of elements in array. + SizeType Size() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.size; } + + //! Get the capacity of array. + SizeType Capacity() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.capacity; } + + //! Check whether the array is empty. + bool Empty() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.size == 0; } + + //! Remove all elements in the array. + /*! This function do not deallocate memory in the array, i.e. the capacity is unchanged. + \note Linear time complexity. + */ + void Clear() { + RAPIDJSON_ASSERT(IsArray()); + GenericValue* e = GetElementsPointer(); + for (GenericValue* v = e; v != e + data_.a.size; ++v) + v->~GenericValue(); + data_.a.size = 0; + } + + //! Get an element from array by index. + /*! \pre IsArray() == true + \param index Zero-based index of element. + \see operator[](T*) + */ + GenericValue& operator[](SizeType index) { + RAPIDJSON_ASSERT(IsArray()); + RAPIDJSON_ASSERT(index < data_.a.size); + return GetElementsPointer()[index]; + } + const GenericValue& operator[](SizeType index) const { return const_cast(*this)[index]; } + + //! Element iterator + /*! \pre IsArray() == true */ + ValueIterator Begin() { RAPIDJSON_ASSERT(IsArray()); return GetElementsPointer(); } + //! \em Past-the-end element iterator + /*! \pre IsArray() == true */ + ValueIterator End() { RAPIDJSON_ASSERT(IsArray()); return GetElementsPointer() + data_.a.size; } + //! Constant element iterator + /*! \pre IsArray() == true */ + ConstValueIterator Begin() const { return const_cast(*this).Begin(); } + //! Constant \em past-the-end element iterator + /*! \pre IsArray() == true */ + ConstValueIterator End() const { return const_cast(*this).End(); } + + //! Request the array to have enough capacity to store elements. + /*! \param newCapacity The capacity that the array at least need to have. + \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). + \return The value itself for fluent API. + \note Linear time complexity. + */ + GenericValue& Reserve(SizeType newCapacity, Allocator &allocator) { + RAPIDJSON_ASSERT(IsArray()); + if (newCapacity > data_.a.capacity) { + SetElementsPointer(reinterpret_cast(allocator.Realloc(GetElementsPointer(), data_.a.capacity * sizeof(GenericValue), newCapacity * sizeof(GenericValue)))); + data_.a.capacity = newCapacity; + } + return *this; + } + + //! Append a GenericValue at the end of the array. + /*! \param value Value to be appended. + \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). + \pre IsArray() == true + \post value.IsNull() == true + \return The value itself for fluent API. + \note The ownership of \c value will be transferred to this array on success. + \note If the number of elements to be appended is known, calls Reserve() once first may be more efficient. + \note Amortized constant time complexity. + */ + GenericValue& PushBack(GenericValue& value, Allocator& allocator) { + RAPIDJSON_ASSERT(IsArray()); + if (data_.a.size >= data_.a.capacity) + Reserve(data_.a.capacity == 0 ? kDefaultArrayCapacity : (data_.a.capacity + (data_.a.capacity + 1) / 2), allocator); + GetElementsPointer()[data_.a.size++].RawAssign(value); + return *this; + } + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + GenericValue& PushBack(GenericValue&& value, Allocator& allocator) { + return PushBack(value, allocator); + } +#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS + + //! Append a constant string reference at the end of the array. + /*! \param value Constant string reference to be appended. + \param allocator Allocator for reallocating memory. It must be the same one used previously. Commonly use GenericDocument::GetAllocator(). + \pre IsArray() == true + \return The value itself for fluent API. + \note If the number of elements to be appended is known, calls Reserve() once first may be more efficient. + \note Amortized constant time complexity. + \see GenericStringRef + */ + GenericValue& PushBack(StringRefType value, Allocator& allocator) { + return (*this).template PushBack(value, allocator); + } + + //! Append a primitive value at the end of the array. + /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t + \param value Value of primitive type T to be appended. + \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). + \pre IsArray() == true + \return The value itself for fluent API. + \note If the number of elements to be appended is known, calls Reserve() once first may be more efficient. + + \note The source type \c T explicitly disallows all pointer types, + especially (\c const) \ref Ch*. This helps avoiding implicitly + referencing character strings with insufficient lifetime, use + \ref PushBack(GenericValue&, Allocator&) or \ref + PushBack(StringRefType, Allocator&). + All other pointer types would implicitly convert to \c bool, + use an explicit cast instead, if needed. + \note Amortized constant time complexity. + */ + template + RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (GenericValue&)) + PushBack(T value, Allocator& allocator) { + GenericValue v(value); + return PushBack(v, allocator); + } + + //! Remove the last element in the array. + /*! + \note Constant time complexity. + */ + GenericValue& PopBack() { + RAPIDJSON_ASSERT(IsArray()); + RAPIDJSON_ASSERT(!Empty()); + GetElementsPointer()[--data_.a.size].~GenericValue(); + return *this; + } + + //! Remove an element of array by iterator. + /*! + \param pos iterator to the element to remove + \pre IsArray() == true && \ref Begin() <= \c pos < \ref End() + \return Iterator following the removed element. If the iterator pos refers to the last element, the End() iterator is returned. + \note Linear time complexity. + */ + ValueIterator Erase(ConstValueIterator pos) { + return Erase(pos, pos + 1); + } + + //! Remove elements in the range [first, last) of the array. + /*! + \param first iterator to the first element to remove + \param last iterator following the last element to remove + \pre IsArray() == true && \ref Begin() <= \c first <= \c last <= \ref End() + \return Iterator following the last removed element. + \note Linear time complexity. + */ + ValueIterator Erase(ConstValueIterator first, ConstValueIterator last) { + RAPIDJSON_ASSERT(IsArray()); + RAPIDJSON_ASSERT(data_.a.size > 0); + RAPIDJSON_ASSERT(GetElementsPointer() != 0); + RAPIDJSON_ASSERT(first >= Begin()); + RAPIDJSON_ASSERT(first <= last); + RAPIDJSON_ASSERT(last <= End()); + ValueIterator pos = Begin() + (first - Begin()); + for (ValueIterator itr = pos; itr != last; ++itr) + itr->~GenericValue(); + std::memmove(pos, last, static_cast(End() - last) * sizeof(GenericValue)); + data_.a.size -= static_cast(last - first); + return pos; + } + + Array GetArray() { RAPIDJSON_ASSERT(IsArray()); return Array(*this); } + ConstArray GetArray() const { RAPIDJSON_ASSERT(IsArray()); return ConstArray(*this); } + + //@} + + //!@name Number + //@{ + + int GetInt() const { RAPIDJSON_ASSERT(data_.f.flags & kIntFlag); return data_.n.i.i; } + unsigned GetUint() const { RAPIDJSON_ASSERT(data_.f.flags & kUintFlag); return data_.n.u.u; } + int64_t GetInt64() const { RAPIDJSON_ASSERT(data_.f.flags & kInt64Flag); return data_.n.i64; } + uint64_t GetUint64() const { RAPIDJSON_ASSERT(data_.f.flags & kUint64Flag); return data_.n.u64; } + + //! Get the value as double type. + /*! \note If the value is 64-bit integer type, it may lose precision. Use \c IsLosslessDouble() to check whether the converison is lossless. + */ + double GetDouble() const { + RAPIDJSON_ASSERT(IsNumber()); + if ((data_.f.flags & kDoubleFlag) != 0) return data_.n.d; // exact type, no conversion. + if ((data_.f.flags & kIntFlag) != 0) return data_.n.i.i; // int -> double + if ((data_.f.flags & kUintFlag) != 0) return data_.n.u.u; // unsigned -> double + if ((data_.f.flags & kInt64Flag) != 0) return static_cast(data_.n.i64); // int64_t -> double (may lose precision) + RAPIDJSON_ASSERT((data_.f.flags & kUint64Flag) != 0); return static_cast(data_.n.u64); // uint64_t -> double (may lose precision) + } + + //! Get the value as float type. + /*! \note If the value is 64-bit integer type, it may lose precision. Use \c IsLosslessFloat() to check whether the converison is lossless. + */ + float GetFloat() const { + return static_cast(GetDouble()); + } + + GenericValue& SetInt(int i) { this->~GenericValue(); new (this) GenericValue(i); return *this; } + GenericValue& SetUint(unsigned u) { this->~GenericValue(); new (this) GenericValue(u); return *this; } + GenericValue& SetInt64(int64_t i64) { this->~GenericValue(); new (this) GenericValue(i64); return *this; } + GenericValue& SetUint64(uint64_t u64) { this->~GenericValue(); new (this) GenericValue(u64); return *this; } + GenericValue& SetDouble(double d) { this->~GenericValue(); new (this) GenericValue(d); return *this; } + GenericValue& SetFloat(float f) { this->~GenericValue(); new (this) GenericValue(f); return *this; } + + //@} + + //!@name String + //@{ + + const Ch* GetString() const { RAPIDJSON_ASSERT(IsString()); return (data_.f.flags & kInlineStrFlag) ? data_.ss.str : GetStringPointer(); } + + //! Get the length of string. + /*! Since rapidjson permits "\\u0000" in the json string, strlen(v.GetString()) may not equal to v.GetStringLength(). + */ + SizeType GetStringLength() const { RAPIDJSON_ASSERT(IsString()); return ((data_.f.flags & kInlineStrFlag) ? (data_.ss.GetLength()) : data_.s.length); } + + //! Set this value as a string without copying source string. + /*! This version has better performance with supplied length, and also support string containing null character. + \param s source string pointer. + \param length The length of source string, excluding the trailing null terminator. + \return The value itself for fluent API. + \post IsString() == true && GetString() == s && GetStringLength() == length + \see SetString(StringRefType) + */ + GenericValue& SetString(const Ch* s, SizeType length) { return SetString(StringRef(s, length)); } + + //! Set this value as a string without copying source string. + /*! \param s source string reference + \return The value itself for fluent API. + \post IsString() == true && GetString() == s && GetStringLength() == s.length + */ + GenericValue& SetString(StringRefType s) { this->~GenericValue(); SetStringRaw(s); return *this; } + + //! Set this value as a string by copying from source string. + /*! This version has better performance with supplied length, and also support string containing null character. + \param s source string. + \param length The length of source string, excluding the trailing null terminator. + \param allocator Allocator for allocating copied buffer. Commonly use GenericDocument::GetAllocator(). + \return The value itself for fluent API. + \post IsString() == true && GetString() != s && strcmp(GetString(),s) == 0 && GetStringLength() == length + */ + GenericValue& SetString(const Ch* s, SizeType length, Allocator& allocator) { this->~GenericValue(); SetStringRaw(StringRef(s, length), allocator); return *this; } + + //! Set this value as a string by copying from source string. + /*! \param s source string. + \param allocator Allocator for allocating copied buffer. Commonly use GenericDocument::GetAllocator(). + \return The value itself for fluent API. + \post IsString() == true && GetString() != s && strcmp(GetString(),s) == 0 && GetStringLength() == length + */ + GenericValue& SetString(const Ch* s, Allocator& allocator) { return SetString(s, internal::StrLen(s), allocator); } + +#if RAPIDJSON_HAS_STDSTRING + //! Set this value as a string by copying from source string. + /*! \param s source string. + \param allocator Allocator for allocating copied buffer. Commonly use GenericDocument::GetAllocator(). + \return The value itself for fluent API. + \post IsString() == true && GetString() != s.data() && strcmp(GetString(),s.data() == 0 && GetStringLength() == s.size() + \note Requires the definition of the preprocessor symbol \ref RAPIDJSON_HAS_STDSTRING. + */ + GenericValue& SetString(const std::basic_string& s, Allocator& allocator) { return SetString(s.data(), SizeType(s.size()), allocator); } +#endif + + //@} + + //!@name Array + //@{ + + //! Templated version for checking whether this value is type T. + /*! + \tparam T Either \c bool, \c int, \c unsigned, \c int64_t, \c uint64_t, \c double, \c float, \c const \c char*, \c std::basic_string + */ + template + bool Is() const { return internal::TypeHelper::Is(*this); } + + template + T Get() const { return internal::TypeHelper::Get(*this); } + + template + T Get() { return internal::TypeHelper::Get(*this); } + + template + ValueType& Set(const T& data) { return internal::TypeHelper::Set(*this, data); } + + template + ValueType& Set(const T& data, AllocatorType& allocator) { return internal::TypeHelper::Set(*this, data, allocator); } + + //@} + + //! Generate events of this value to a Handler. + /*! This function adopts the GoF visitor pattern. + Typical usage is to output this JSON value as JSON text via Writer, which is a Handler. + It can also be used to deep clone this value via GenericDocument, which is also a Handler. + \tparam Handler type of handler. + \param handler An object implementing concept Handler. + */ + template + bool Accept(Handler& handler) const { + switch(GetType()) { + case kNullType: return handler.Null(); + case kFalseType: return handler.Bool(false); + case kTrueType: return handler.Bool(true); + + case kObjectType: + if (RAPIDJSON_UNLIKELY(!handler.StartObject())) + return false; + for (ConstMemberIterator m = MemberBegin(); m != MemberEnd(); ++m) { + RAPIDJSON_ASSERT(m->name.IsString()); // User may change the type of name by MemberIterator. + if (RAPIDJSON_UNLIKELY(!handler.Key(m->name.GetString(), m->name.GetStringLength(), (m->name.data_.f.flags & kCopyFlag) != 0))) + return false; + if (RAPIDJSON_UNLIKELY(!m->value.Accept(handler))) + return false; + } + return handler.EndObject(data_.o.size); + + case kArrayType: + if (RAPIDJSON_UNLIKELY(!handler.StartArray())) + return false; + for (const GenericValue* v = Begin(); v != End(); ++v) + if (RAPIDJSON_UNLIKELY(!v->Accept(handler))) + return false; + return handler.EndArray(data_.a.size); + + case kStringType: + return handler.String(GetString(), GetStringLength(), (data_.f.flags & kCopyFlag) != 0); + + default: + RAPIDJSON_ASSERT(GetType() == kNumberType); + if (IsDouble()) return handler.Double(data_.n.d); + else if (IsInt()) return handler.Int(data_.n.i.i); + else if (IsUint()) return handler.Uint(data_.n.u.u); + else if (IsInt64()) return handler.Int64(data_.n.i64); + else return handler.Uint64(data_.n.u64); + } + } + +private: + template friend class GenericValue; + template friend class GenericDocument; + + enum { + kBoolFlag = 0x0008, + kNumberFlag = 0x0010, + kIntFlag = 0x0020, + kUintFlag = 0x0040, + kInt64Flag = 0x0080, + kUint64Flag = 0x0100, + kDoubleFlag = 0x0200, + kStringFlag = 0x0400, + kCopyFlag = 0x0800, + kInlineStrFlag = 0x1000, + + // Initial flags of different types. + kNullFlag = kNullType, + kTrueFlag = kTrueType | kBoolFlag, + kFalseFlag = kFalseType | kBoolFlag, + kNumberIntFlag = kNumberType | kNumberFlag | kIntFlag | kInt64Flag, + kNumberUintFlag = kNumberType | kNumberFlag | kUintFlag | kUint64Flag | kInt64Flag, + kNumberInt64Flag = kNumberType | kNumberFlag | kInt64Flag, + kNumberUint64Flag = kNumberType | kNumberFlag | kUint64Flag, + kNumberDoubleFlag = kNumberType | kNumberFlag | kDoubleFlag, + kNumberAnyFlag = kNumberType | kNumberFlag | kIntFlag | kInt64Flag | kUintFlag | kUint64Flag | kDoubleFlag, + kConstStringFlag = kStringType | kStringFlag, + kCopyStringFlag = kStringType | kStringFlag | kCopyFlag, + kShortStringFlag = kStringType | kStringFlag | kCopyFlag | kInlineStrFlag, + kObjectFlag = kObjectType, + kArrayFlag = kArrayType, + + kTypeMask = 0x07 + }; + + static const SizeType kDefaultArrayCapacity = 16; + static const SizeType kDefaultObjectCapacity = 16; + + struct Flag { +#if RAPIDJSON_48BITPOINTER_OPTIMIZATION + char payload[sizeof(SizeType) * 2 + 6]; // 2 x SizeType + lower 48-bit pointer +#elif RAPIDJSON_64BIT + char payload[sizeof(SizeType) * 2 + sizeof(void*) + 6]; // 6 padding bytes +#else + char payload[sizeof(SizeType) * 2 + sizeof(void*) + 2]; // 2 padding bytes +#endif + uint16_t flags; + }; + + struct String { + SizeType length; + SizeType hashcode; //!< reserved + const Ch* str; + }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode + + // implementation detail: ShortString can represent zero-terminated strings up to MaxSize chars + // (excluding the terminating zero) and store a value to determine the length of the contained + // string in the last character str[LenPos] by storing "MaxSize - length" there. If the string + // to store has the maximal length of MaxSize then str[LenPos] will be 0 and therefore act as + // the string terminator as well. For getting the string length back from that value just use + // "MaxSize - str[LenPos]". + // This allows to store 13-chars strings in 32-bit mode, 21-chars strings in 64-bit mode, + // 13-chars strings for RAPIDJSON_48BITPOINTER_OPTIMIZATION=1 inline (for `UTF8`-encoded strings). + struct ShortString { + enum { MaxChars = sizeof(static_cast(0)->payload) / sizeof(Ch), MaxSize = MaxChars - 1, LenPos = MaxSize }; + Ch str[MaxChars]; + + inline static bool Usable(SizeType len) { return (MaxSize >= len); } + inline void SetLength(SizeType len) { str[LenPos] = static_cast(MaxSize - len); } + inline SizeType GetLength() const { return static_cast(MaxSize - str[LenPos]); } + }; // at most as many bytes as "String" above => 12 bytes in 32-bit mode, 16 bytes in 64-bit mode + + // By using proper binary layout, retrieval of different integer types do not need conversions. + union Number { +#if RAPIDJSON_ENDIAN == RAPIDJSON_LITTLEENDIAN + struct I { + int i; + char padding[4]; + }i; + struct U { + unsigned u; + char padding2[4]; + }u; +#else + struct I { + char padding[4]; + int i; + }i; + struct U { + char padding2[4]; + unsigned u; + }u; +#endif + int64_t i64; + uint64_t u64; + double d; + }; // 8 bytes + + struct ObjectData { + SizeType size; + SizeType capacity; + Member* members; + }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode + + struct ArrayData { + SizeType size; + SizeType capacity; + GenericValue* elements; + }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode + + union Data { + String s; + ShortString ss; + Number n; + ObjectData o; + ArrayData a; + Flag f; + }; // 16 bytes in 32-bit mode, 24 bytes in 64-bit mode, 16 bytes in 64-bit with RAPIDJSON_48BITPOINTER_OPTIMIZATION + + RAPIDJSON_FORCEINLINE const Ch* GetStringPointer() const { return RAPIDJSON_GETPOINTER(Ch, data_.s.str); } + RAPIDJSON_FORCEINLINE const Ch* SetStringPointer(const Ch* str) { return RAPIDJSON_SETPOINTER(Ch, data_.s.str, str); } + RAPIDJSON_FORCEINLINE GenericValue* GetElementsPointer() const { return RAPIDJSON_GETPOINTER(GenericValue, data_.a.elements); } + RAPIDJSON_FORCEINLINE GenericValue* SetElementsPointer(GenericValue* elements) { return RAPIDJSON_SETPOINTER(GenericValue, data_.a.elements, elements); } + RAPIDJSON_FORCEINLINE Member* GetMembersPointer() const { return RAPIDJSON_GETPOINTER(Member, data_.o.members); } + RAPIDJSON_FORCEINLINE Member* SetMembersPointer(Member* members) { return RAPIDJSON_SETPOINTER(Member, data_.o.members, members); } + + // Initialize this value as array with initial data, without calling destructor. + void SetArrayRaw(GenericValue* values, SizeType count, Allocator& allocator) { + data_.f.flags = kArrayFlag; + if (count) { + GenericValue* e = static_cast(allocator.Malloc(count * sizeof(GenericValue))); + SetElementsPointer(e); + std::memcpy(e, values, count * sizeof(GenericValue)); + } + else + SetElementsPointer(0); + data_.a.size = data_.a.capacity = count; + } + + //! Initialize this value as object with initial data, without calling destructor. + void SetObjectRaw(Member* members, SizeType count, Allocator& allocator) { + data_.f.flags = kObjectFlag; + if (count) { + Member* m = static_cast(allocator.Malloc(count * sizeof(Member))); + SetMembersPointer(m); + std::memcpy(m, members, count * sizeof(Member)); + } + else + SetMembersPointer(0); + data_.o.size = data_.o.capacity = count; + } + + //! Initialize this value as constant string, without calling destructor. + void SetStringRaw(StringRefType s) RAPIDJSON_NOEXCEPT { + data_.f.flags = kConstStringFlag; + SetStringPointer(s); + data_.s.length = s.length; + } + + //! Initialize this value as copy string with initial data, without calling destructor. + void SetStringRaw(StringRefType s, Allocator& allocator) { + Ch* str = 0; + if (ShortString::Usable(s.length)) { + data_.f.flags = kShortStringFlag; + data_.ss.SetLength(s.length); + str = data_.ss.str; + } else { + data_.f.flags = kCopyStringFlag; + data_.s.length = s.length; + str = static_cast(allocator.Malloc((s.length + 1) * sizeof(Ch))); + SetStringPointer(str); + } + std::memcpy(str, s, s.length * sizeof(Ch)); + str[s.length] = '\0'; + } + + //! Assignment without calling destructor + void RawAssign(GenericValue& rhs) RAPIDJSON_NOEXCEPT { + data_ = rhs.data_; + // data_.f.flags = rhs.data_.f.flags; + rhs.data_.f.flags = kNullFlag; + } + + template + bool StringEqual(const GenericValue& rhs) const { + RAPIDJSON_ASSERT(IsString()); + RAPIDJSON_ASSERT(rhs.IsString()); + + const SizeType len1 = GetStringLength(); + const SizeType len2 = rhs.GetStringLength(); + if(len1 != len2) { return false; } + + const Ch* const str1 = GetString(); + const Ch* const str2 = rhs.GetString(); + if(str1 == str2) { return true; } // fast path for constant string + + return (std::memcmp(str1, str2, sizeof(Ch) * len1) == 0); + } + + Data data_; +}; + +//! GenericValue with UTF8 encoding +typedef GenericValue > Value; + +/////////////////////////////////////////////////////////////////////////////// +// GenericDocument + +//! A document for parsing JSON text as DOM. +/*! + \note implements Handler concept + \tparam Encoding Encoding for both parsing and string storage. + \tparam Allocator Allocator for allocating memory for the DOM + \tparam StackAllocator Allocator for allocating memory for stack during parsing. + \warning Although GenericDocument inherits from GenericValue, the API does \b not provide any virtual functions, especially no virtual destructor. To avoid memory leaks, do not \c delete a GenericDocument object via a pointer to a GenericValue. +*/ +template , typename StackAllocator = CrtAllocator> +class GenericDocument : public GenericValue { +public: + typedef typename Encoding::Ch Ch; //!< Character type derived from Encoding. + typedef GenericValue ValueType; //!< Value type of the document. + typedef Allocator AllocatorType; //!< Allocator type from template parameter. + + //! Constructor + /*! Creates an empty document of specified type. + \param type Mandatory type of object to create. + \param allocator Optional allocator for allocating memory. + \param stackCapacity Optional initial capacity of stack in bytes. + \param stackAllocator Optional allocator for allocating memory for stack. + */ + explicit GenericDocument(Type type, Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity, StackAllocator* stackAllocator = 0) : + GenericValue(type), allocator_(allocator), ownAllocator_(0), stack_(stackAllocator, stackCapacity), parseResult_() + { + if (!allocator_) + ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator()); + } + + //! Constructor + /*! Creates an empty document which type is Null. + \param allocator Optional allocator for allocating memory. + \param stackCapacity Optional initial capacity of stack in bytes. + \param stackAllocator Optional allocator for allocating memory for stack. + */ + GenericDocument(Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity, StackAllocator* stackAllocator = 0) : + allocator_(allocator), ownAllocator_(0), stack_(stackAllocator, stackCapacity), parseResult_() + { + if (!allocator_) + ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator()); + } + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + //! Move constructor in C++11 + GenericDocument(GenericDocument&& rhs) RAPIDJSON_NOEXCEPT + : ValueType(std::forward(rhs)), // explicit cast to avoid prohibited move from Document + allocator_(rhs.allocator_), + ownAllocator_(rhs.ownAllocator_), + stack_(std::move(rhs.stack_)), + parseResult_(rhs.parseResult_) + { + rhs.allocator_ = 0; + rhs.ownAllocator_ = 0; + rhs.parseResult_ = ParseResult(); + } +#endif + + ~GenericDocument() { + Destroy(); + } + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + //! Move assignment in C++11 + GenericDocument& operator=(GenericDocument&& rhs) RAPIDJSON_NOEXCEPT + { + // The cast to ValueType is necessary here, because otherwise it would + // attempt to call GenericValue's templated assignment operator. + ValueType::operator=(std::forward(rhs)); + + // Calling the destructor here would prematurely call stack_'s destructor + Destroy(); + + allocator_ = rhs.allocator_; + ownAllocator_ = rhs.ownAllocator_; + stack_ = std::move(rhs.stack_); + parseResult_ = rhs.parseResult_; + + rhs.allocator_ = 0; + rhs.ownAllocator_ = 0; + rhs.parseResult_ = ParseResult(); + + return *this; + } +#endif + + //! Exchange the contents of this document with those of another. + /*! + \param rhs Another document. + \note Constant complexity. + \see GenericValue::Swap + */ + GenericDocument& Swap(GenericDocument& rhs) RAPIDJSON_NOEXCEPT { + ValueType::Swap(rhs); + stack_.Swap(rhs.stack_); + internal::Swap(allocator_, rhs.allocator_); + internal::Swap(ownAllocator_, rhs.ownAllocator_); + internal::Swap(parseResult_, rhs.parseResult_); + return *this; + } + + //! free-standing swap function helper + /*! + Helper function to enable support for common swap implementation pattern based on \c std::swap: + \code + void swap(MyClass& a, MyClass& b) { + using std::swap; + swap(a.doc, b.doc); + // ... + } + \endcode + \see Swap() + */ + friend inline void swap(GenericDocument& a, GenericDocument& b) RAPIDJSON_NOEXCEPT { a.Swap(b); } + + //! Populate this document by a generator which produces SAX events. + /*! \tparam Generator A functor with bool f(Handler) prototype. + \param g Generator functor which sends SAX events to the parameter. + \return The document itself for fluent API. + */ + template + GenericDocument& Populate(Generator& g) { + ClearStackOnExit scope(*this); + if (g(*this)) { + RAPIDJSON_ASSERT(stack_.GetSize() == sizeof(ValueType)); // Got one and only one root object + ValueType::operator=(*stack_.template Pop(1));// Move value from stack to document + } + return *this; + } + + //!@name Parse from stream + //!@{ + + //! Parse JSON text from an input stream (with Encoding conversion) + /*! \tparam parseFlags Combination of \ref ParseFlag. + \tparam SourceEncoding Encoding of input stream + \tparam InputStream Type of input stream, implementing Stream concept + \param is Input stream to be parsed. + \return The document itself for fluent API. + */ + template + GenericDocument& ParseStream(InputStream& is) { + GenericReader reader( + stack_.HasAllocator() ? &stack_.GetAllocator() : 0); + ClearStackOnExit scope(*this); + parseResult_ = reader.template Parse(is, *this); + if (parseResult_) { + RAPIDJSON_ASSERT(stack_.GetSize() == sizeof(ValueType)); // Got one and only one root object + ValueType::operator=(*stack_.template Pop(1));// Move value from stack to document + } + return *this; + } + + //! Parse JSON text from an input stream + /*! \tparam parseFlags Combination of \ref ParseFlag. + \tparam InputStream Type of input stream, implementing Stream concept + \param is Input stream to be parsed. + \return The document itself for fluent API. + */ + template + GenericDocument& ParseStream(InputStream& is) { + return ParseStream(is); + } + + //! Parse JSON text from an input stream (with \ref kParseDefaultFlags) + /*! \tparam InputStream Type of input stream, implementing Stream concept + \param is Input stream to be parsed. + \return The document itself for fluent API. + */ + template + GenericDocument& ParseStream(InputStream& is) { + return ParseStream(is); + } + //!@} + + //!@name Parse in-place from mutable string + //!@{ + + //! Parse JSON text from a mutable string + /*! \tparam parseFlags Combination of \ref ParseFlag. + \param str Mutable zero-terminated string to be parsed. + \return The document itself for fluent API. + */ + template + GenericDocument& ParseInsitu(Ch* str) { + GenericInsituStringStream s(str); + return ParseStream(s); + } + + //! Parse JSON text from a mutable string (with \ref kParseDefaultFlags) + /*! \param str Mutable zero-terminated string to be parsed. + \return The document itself for fluent API. + */ + GenericDocument& ParseInsitu(Ch* str) { + return ParseInsitu(str); + } + //!@} + + //!@name Parse from read-only string + //!@{ + + //! Parse JSON text from a read-only string (with Encoding conversion) + /*! \tparam parseFlags Combination of \ref ParseFlag (must not contain \ref kParseInsituFlag). + \tparam SourceEncoding Transcoding from input Encoding + \param str Read-only zero-terminated string to be parsed. + */ + template + GenericDocument& Parse(const typename SourceEncoding::Ch* str) { + RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag)); + GenericStringStream s(str); + return ParseStream(s); + } + + //! Parse JSON text from a read-only string + /*! \tparam parseFlags Combination of \ref ParseFlag (must not contain \ref kParseInsituFlag). + \param str Read-only zero-terminated string to be parsed. + */ + template + GenericDocument& Parse(const Ch* str) { + return Parse(str); + } + + //! Parse JSON text from a read-only string (with \ref kParseDefaultFlags) + /*! \param str Read-only zero-terminated string to be parsed. + */ + GenericDocument& Parse(const Ch* str) { + return Parse(str); + } + + template + GenericDocument& Parse(const typename SourceEncoding::Ch* str, size_t length) { + RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag)); + MemoryStream ms(static_cast(str), length * sizeof(typename SourceEncoding::Ch)); + EncodedInputStream is(ms); + ParseStream(is); + return *this; + } + + template + GenericDocument& Parse(const Ch* str, size_t length) { + return Parse(str, length); + } + + GenericDocument& Parse(const Ch* str, size_t length) { + return Parse(str, length); + } + +#if RAPIDJSON_HAS_STDSTRING + template + GenericDocument& Parse(const std::basic_string& str) { + // c_str() is constant complexity according to standard. Should be faster than Parse(const char*, size_t) + return Parse(str.c_str()); + } + + template + GenericDocument& Parse(const std::basic_string& str) { + return Parse(str.c_str()); + } + + GenericDocument& Parse(const std::basic_string& str) { + return Parse(str); + } +#endif // RAPIDJSON_HAS_STDSTRING + + //!@} + + //!@name Handling parse errors + //!@{ + + //! Whether a parse error has occured in the last parsing. + bool HasParseError() const { return parseResult_.IsError(); } + + //! Get the \ref ParseErrorCode of last parsing. + ParseErrorCode GetParseError() const { return parseResult_.Code(); } + + //! Get the position of last parsing error in input, 0 otherwise. + size_t GetErrorOffset() const { return parseResult_.Offset(); } + + //! Implicit conversion to get the last parse result +#ifndef __clang // -Wdocumentation + /*! \return \ref ParseResult of the last parse operation + + \code + Document doc; + ParseResult ok = doc.Parse(json); + if (!ok) + printf( "JSON parse error: %s (%u)\n", GetParseError_En(ok.Code()), ok.Offset()); + \endcode + */ +#endif + operator ParseResult() const { return parseResult_; } + //!@} + + //! Get the allocator of this document. + Allocator& GetAllocator() { + RAPIDJSON_ASSERT(allocator_); + return *allocator_; + } + + //! Get the capacity of stack in bytes. + size_t GetStackCapacity() const { return stack_.GetCapacity(); } + +private: + // clear stack on any exit from ParseStream, e.g. due to exception + struct ClearStackOnExit { + explicit ClearStackOnExit(GenericDocument& d) : d_(d) {} + ~ClearStackOnExit() { d_.ClearStack(); } + private: + ClearStackOnExit(const ClearStackOnExit&); + ClearStackOnExit& operator=(const ClearStackOnExit&); + GenericDocument& d_; + }; + + // callers of the following private Handler functions + // template friend class GenericReader; // for parsing + template friend class GenericValue; // for deep copying + +public: + // Implementation of Handler + bool Null() { new (stack_.template Push()) ValueType(); return true; } + bool Bool(bool b) { new (stack_.template Push()) ValueType(b); return true; } + bool Int(int i) { new (stack_.template Push()) ValueType(i); return true; } + bool Uint(unsigned i) { new (stack_.template Push()) ValueType(i); return true; } + bool Int64(int64_t i) { new (stack_.template Push()) ValueType(i); return true; } + bool Uint64(uint64_t i) { new (stack_.template Push()) ValueType(i); return true; } + bool Double(double d) { new (stack_.template Push()) ValueType(d); return true; } + + bool RawNumber(const Ch* str, SizeType length, bool copy) { + if (copy) + new (stack_.template Push()) ValueType(str, length, GetAllocator()); + else + new (stack_.template Push()) ValueType(str, length); + return true; + } + + bool String(const Ch* str, SizeType length, bool copy) { + if (copy) + new (stack_.template Push()) ValueType(str, length, GetAllocator()); + else + new (stack_.template Push()) ValueType(str, length); + return true; + } + + bool StartObject() { new (stack_.template Push()) ValueType(kObjectType); return true; } + + bool Key(const Ch* str, SizeType length, bool copy) { return String(str, length, copy); } + + bool EndObject(SizeType memberCount) { + typename ValueType::Member* members = stack_.template Pop(memberCount); + stack_.template Top()->SetObjectRaw(members, memberCount, GetAllocator()); + return true; + } + + bool StartArray() { new (stack_.template Push()) ValueType(kArrayType); return true; } + + bool EndArray(SizeType elementCount) { + ValueType* elements = stack_.template Pop(elementCount); + stack_.template Top()->SetArrayRaw(elements, elementCount, GetAllocator()); + return true; + } + +private: + //! Prohibit copying + GenericDocument(const GenericDocument&); + //! Prohibit assignment + GenericDocument& operator=(const GenericDocument&); + + void ClearStack() { + if (Allocator::kNeedFree) + while (stack_.GetSize() > 0) // Here assumes all elements in stack array are GenericValue (Member is actually 2 GenericValue objects) + (stack_.template Pop(1))->~ValueType(); + else + stack_.Clear(); + stack_.ShrinkToFit(); + } + + void Destroy() { + RAPIDJSON_DELETE(ownAllocator_); + } + + static const size_t kDefaultStackCapacity = 1024; + Allocator* allocator_; + Allocator* ownAllocator_; + internal::Stack stack_; + ParseResult parseResult_; +}; + +//! GenericDocument with UTF8 encoding +typedef GenericDocument > Document; + +// defined here due to the dependency on GenericDocument +template +template +inline +GenericValue::GenericValue(const GenericValue& rhs, Allocator& allocator) +{ + switch (rhs.GetType()) { + case kObjectType: + case kArrayType: { // perform deep copy via SAX Handler + GenericDocument d(&allocator); + rhs.Accept(d); + RawAssign(*d.stack_.template Pop(1)); + } + break; + case kStringType: + if (rhs.data_.f.flags == kConstStringFlag) { + data_.f.flags = rhs.data_.f.flags; + data_ = *reinterpret_cast(&rhs.data_); + } else { + SetStringRaw(StringRef(rhs.GetString(), rhs.GetStringLength()), allocator); + } + break; + default: + data_.f.flags = rhs.data_.f.flags; + data_ = *reinterpret_cast(&rhs.data_); + break; + } +} + +//! Helper class for accessing Value of array type. +/*! + Instance of this helper class is obtained by \c GenericValue::GetArray(). + In addition to all APIs for array type, it provides range-based for loop if \c RAPIDJSON_HAS_CXX11_RANGE_FOR=1. +*/ +template +class GenericArray { +public: + typedef GenericArray ConstArray; + typedef GenericArray Array; + typedef ValueT PlainType; + typedef typename internal::MaybeAddConst::Type ValueType; + typedef ValueType* ValueIterator; // This may be const or non-const iterator + typedef const ValueT* ConstValueIterator; + typedef typename ValueType::AllocatorType AllocatorType; + typedef typename ValueType::StringRefType StringRefType; + + template + friend class GenericValue; + + GenericArray(const GenericArray& rhs) : value_(rhs.value_) {} + GenericArray& operator=(const GenericArray& rhs) { value_ = rhs.value_; return *this; } + ~GenericArray() {} + + SizeType Size() const { return value_.Size(); } + SizeType Capacity() const { return value_.Capacity(); } + bool Empty() const { return value_.Empty(); } + void Clear() const { value_.Clear(); } + ValueType& operator[](SizeType index) const { return value_[index]; } + ValueIterator Begin() const { return value_.Begin(); } + ValueIterator End() const { return value_.End(); } + GenericArray Reserve(SizeType newCapacity, AllocatorType &allocator) const { value_.Reserve(newCapacity, allocator); return *this; } + GenericArray PushBack(ValueType& value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; } +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + GenericArray PushBack(ValueType&& value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; } +#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS + GenericArray PushBack(StringRefType value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; } + template RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (const GenericArray&)) PushBack(T value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; } + GenericArray PopBack() const { value_.PopBack(); return *this; } + ValueIterator Erase(ConstValueIterator pos) const { return value_.Erase(pos); } + ValueIterator Erase(ConstValueIterator first, ConstValueIterator last) const { return value_.Erase(first, last); } + +#if RAPIDJSON_HAS_CXX11_RANGE_FOR + ValueIterator begin() const { return value_.Begin(); } + ValueIterator end() const { return value_.End(); } +#endif + +private: + GenericArray(); + GenericArray(ValueType& value) : value_(value) {} + ValueType& value_; +}; + +//! Helper class for accessing Value of object type. +/*! + Instance of this helper class is obtained by \c GenericValue::GetObject(). + In addition to all APIs for array type, it provides range-based for loop if \c RAPIDJSON_HAS_CXX11_RANGE_FOR=1. +*/ +template +class GenericObject { +public: + typedef GenericObject ConstObject; + typedef GenericObject Object; + typedef ValueT PlainType; + typedef typename internal::MaybeAddConst::Type ValueType; + typedef GenericMemberIterator MemberIterator; // This may be const or non-const iterator + typedef GenericMemberIterator ConstMemberIterator; + typedef typename ValueType::AllocatorType AllocatorType; + typedef typename ValueType::StringRefType StringRefType; + typedef typename ValueType::EncodingType EncodingType; + typedef typename ValueType::Ch Ch; + + template + friend class GenericValue; + + GenericObject(const GenericObject& rhs) : value_(rhs.value_) {} + GenericObject& operator=(const GenericObject& rhs) { value_ = rhs.value_; return *this; } + ~GenericObject() {} + + SizeType MemberCount() const { return value_.MemberCount(); } + bool ObjectEmpty() const { return value_.ObjectEmpty(); } + template ValueType& operator[](T* name) const { return value_[name]; } + template ValueType& operator[](const GenericValue& name) const { return value_[name]; } +#if RAPIDJSON_HAS_STDSTRING + ValueType& operator[](const std::basic_string& name) const { return value_[name]; } +#endif + MemberIterator MemberBegin() const { return value_.MemberBegin(); } + MemberIterator MemberEnd() const { return value_.MemberEnd(); } + bool HasMember(const Ch* name) const { return value_.HasMember(name); } +#if RAPIDJSON_HAS_STDSTRING + bool HasMember(const std::basic_string& name) const { return value_.HasMember(name); } +#endif + template bool HasMember(const GenericValue& name) const { return value_.HasMember(name); } + MemberIterator FindMember(const Ch* name) const { return value_.FindMember(name); } + template MemberIterator FindMember(const GenericValue& name) const { return value_.FindMember(name); } +#if RAPIDJSON_HAS_STDSTRING + MemberIterator FindMember(const std::basic_string& name) const { return value_.FindMember(name); } +#endif + GenericObject AddMember(ValueType& name, ValueType& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; } + GenericObject AddMember(ValueType& name, StringRefType value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; } +#if RAPIDJSON_HAS_STDSTRING + GenericObject AddMember(ValueType& name, std::basic_string& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; } +#endif + template RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (ValueType&)) AddMember(ValueType& name, T value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; } +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + GenericObject AddMember(ValueType&& name, ValueType&& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; } + GenericObject AddMember(ValueType&& name, ValueType& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; } + GenericObject AddMember(ValueType& name, ValueType&& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; } + GenericObject AddMember(StringRefType name, ValueType&& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; } +#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS + GenericObject AddMember(StringRefType name, ValueType& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; } + GenericObject AddMember(StringRefType name, StringRefType value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; } + template RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (GenericObject)) AddMember(StringRefType name, T value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; } + void RemoveAllMembers() { return value_.RemoveAllMembers(); } + bool RemoveMember(const Ch* name) const { return value_.RemoveMember(name); } +#if RAPIDJSON_HAS_STDSTRING + bool RemoveMember(const std::basic_string& name) const { return value_.RemoveMember(name); } +#endif + template bool RemoveMember(const GenericValue& name) const { return value_.RemoveMember(name); } + MemberIterator RemoveMember(MemberIterator m) const { return value_.RemoveMember(m); } + MemberIterator EraseMember(ConstMemberIterator pos) const { return value_.EraseMember(pos); } + MemberIterator EraseMember(ConstMemberIterator first, ConstMemberIterator last) const { return value_.EraseMember(first, last); } + bool EraseMember(const Ch* name) const { return value_.EraseMember(name); } +#if RAPIDJSON_HAS_STDSTRING + bool EraseMember(const std::basic_string& name) const { return EraseMember(ValueType(StringRef(name))); } +#endif + template bool EraseMember(const GenericValue& name) const { return value_.EraseMember(name); } + +#if RAPIDJSON_HAS_CXX11_RANGE_FOR + MemberIterator begin() const { return value_.MemberBegin(); } + MemberIterator end() const { return value_.MemberEnd(); } +#endif + +private: + GenericObject(); + GenericObject(ValueType& value) : value_(value) {} + ValueType& value_; +}; + +RAPIDJSON_NAMESPACE_END +RAPIDJSON_DIAG_POP + +#endif // RAPIDJSON_DOCUMENT_H_ diff --git a/slsReceiverSoftware/include/rapidjson/encodedstream.h b/slsReceiverSoftware/include/rapidjson/encodedstream.h new file mode 100644 index 000000000..145068386 --- /dev/null +++ b/slsReceiverSoftware/include/rapidjson/encodedstream.h @@ -0,0 +1,299 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_ENCODEDSTREAM_H_ +#define RAPIDJSON_ENCODEDSTREAM_H_ + +#include "stream.h" +#include "memorystream.h" + +#ifdef __GNUC__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(effc++) +#endif + +#ifdef __clang__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(padded) +#endif + +RAPIDJSON_NAMESPACE_BEGIN + +//! Input byte stream wrapper with a statically bound encoding. +/*! + \tparam Encoding The interpretation of encoding of the stream. Either UTF8, UTF16LE, UTF16BE, UTF32LE, UTF32BE. + \tparam InputByteStream Type of input byte stream. For example, FileReadStream. +*/ +template +class EncodedInputStream { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); +public: + typedef typename Encoding::Ch Ch; + + EncodedInputStream(InputByteStream& is) : is_(is) { + current_ = Encoding::TakeBOM(is_); + } + + Ch Peek() const { return current_; } + Ch Take() { Ch c = current_; current_ = Encoding::Take(is_); return c; } + size_t Tell() const { return is_.Tell(); } + + // Not implemented + void Put(Ch) { RAPIDJSON_ASSERT(false); } + void Flush() { RAPIDJSON_ASSERT(false); } + Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } + size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } + +private: + EncodedInputStream(const EncodedInputStream&); + EncodedInputStream& operator=(const EncodedInputStream&); + + InputByteStream& is_; + Ch current_; +}; + +//! Specialized for UTF8 MemoryStream. +template <> +class EncodedInputStream, MemoryStream> { +public: + typedef UTF8<>::Ch Ch; + + EncodedInputStream(MemoryStream& is) : is_(is) { + if (static_cast(is_.Peek()) == 0xEFu) is_.Take(); + if (static_cast(is_.Peek()) == 0xBBu) is_.Take(); + if (static_cast(is_.Peek()) == 0xBFu) is_.Take(); + } + Ch Peek() const { return is_.Peek(); } + Ch Take() { return is_.Take(); } + size_t Tell() const { return is_.Tell(); } + + // Not implemented + void Put(Ch) {} + void Flush() {} + Ch* PutBegin() { return 0; } + size_t PutEnd(Ch*) { return 0; } + + MemoryStream& is_; + +private: + EncodedInputStream(const EncodedInputStream&); + EncodedInputStream& operator=(const EncodedInputStream&); +}; + +//! Output byte stream wrapper with statically bound encoding. +/*! + \tparam Encoding The interpretation of encoding of the stream. Either UTF8, UTF16LE, UTF16BE, UTF32LE, UTF32BE. + \tparam OutputByteStream Type of input byte stream. For example, FileWriteStream. +*/ +template +class EncodedOutputStream { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); +public: + typedef typename Encoding::Ch Ch; + + EncodedOutputStream(OutputByteStream& os, bool putBOM = true) : os_(os) { + if (putBOM) + Encoding::PutBOM(os_); + } + + void Put(Ch c) { Encoding::Put(os_, c); } + void Flush() { os_.Flush(); } + + // Not implemented + Ch Peek() const { RAPIDJSON_ASSERT(false); return 0;} + Ch Take() { RAPIDJSON_ASSERT(false); return 0;} + size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; } + Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } + size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } + +private: + EncodedOutputStream(const EncodedOutputStream&); + EncodedOutputStream& operator=(const EncodedOutputStream&); + + OutputByteStream& os_; +}; + +#define RAPIDJSON_ENCODINGS_FUNC(x) UTF8::x, UTF16LE::x, UTF16BE::x, UTF32LE::x, UTF32BE::x + +//! Input stream wrapper with dynamically bound encoding and automatic encoding detection. +/*! + \tparam CharType Type of character for reading. + \tparam InputByteStream type of input byte stream to be wrapped. +*/ +template +class AutoUTFInputStream { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); +public: + typedef CharType Ch; + + //! Constructor. + /*! + \param is input stream to be wrapped. + \param type UTF encoding type if it is not detected from the stream. + */ + AutoUTFInputStream(InputByteStream& is, UTFType type = kUTF8) : is_(&is), type_(type), hasBOM_(false) { + RAPIDJSON_ASSERT(type >= kUTF8 && type <= kUTF32BE); + DetectType(); + static const TakeFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Take) }; + takeFunc_ = f[type_]; + current_ = takeFunc_(*is_); + } + + UTFType GetType() const { return type_; } + bool HasBOM() const { return hasBOM_; } + + Ch Peek() const { return current_; } + Ch Take() { Ch c = current_; current_ = takeFunc_(*is_); return c; } + size_t Tell() const { return is_->Tell(); } + + // Not implemented + void Put(Ch) { RAPIDJSON_ASSERT(false); } + void Flush() { RAPIDJSON_ASSERT(false); } + Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } + size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } + +private: + AutoUTFInputStream(const AutoUTFInputStream&); + AutoUTFInputStream& operator=(const AutoUTFInputStream&); + + // Detect encoding type with BOM or RFC 4627 + void DetectType() { + // BOM (Byte Order Mark): + // 00 00 FE FF UTF-32BE + // FF FE 00 00 UTF-32LE + // FE FF UTF-16BE + // FF FE UTF-16LE + // EF BB BF UTF-8 + + const unsigned char* c = reinterpret_cast(is_->Peek4()); + if (!c) + return; + + unsigned bom = static_cast(c[0] | (c[1] << 8) | (c[2] << 16) | (c[3] << 24)); + hasBOM_ = false; + if (bom == 0xFFFE0000) { type_ = kUTF32BE; hasBOM_ = true; is_->Take(); is_->Take(); is_->Take(); is_->Take(); } + else if (bom == 0x0000FEFF) { type_ = kUTF32LE; hasBOM_ = true; is_->Take(); is_->Take(); is_->Take(); is_->Take(); } + else if ((bom & 0xFFFF) == 0xFFFE) { type_ = kUTF16BE; hasBOM_ = true; is_->Take(); is_->Take(); } + else if ((bom & 0xFFFF) == 0xFEFF) { type_ = kUTF16LE; hasBOM_ = true; is_->Take(); is_->Take(); } + else if ((bom & 0xFFFFFF) == 0xBFBBEF) { type_ = kUTF8; hasBOM_ = true; is_->Take(); is_->Take(); is_->Take(); } + + // RFC 4627: Section 3 + // "Since the first two characters of a JSON text will always be ASCII + // characters [RFC0020], it is possible to determine whether an octet + // stream is UTF-8, UTF-16 (BE or LE), or UTF-32 (BE or LE) by looking + // at the pattern of nulls in the first four octets." + // 00 00 00 xx UTF-32BE + // 00 xx 00 xx UTF-16BE + // xx 00 00 00 UTF-32LE + // xx 00 xx 00 UTF-16LE + // xx xx xx xx UTF-8 + + if (!hasBOM_) { + unsigned pattern = (c[0] ? 1 : 0) | (c[1] ? 2 : 0) | (c[2] ? 4 : 0) | (c[3] ? 8 : 0); + switch (pattern) { + case 0x08: type_ = kUTF32BE; break; + case 0x0A: type_ = kUTF16BE; break; + case 0x01: type_ = kUTF32LE; break; + case 0x05: type_ = kUTF16LE; break; + case 0x0F: type_ = kUTF8; break; + default: break; // Use type defined by user. + } + } + + // Runtime check whether the size of character type is sufficient. It only perform checks with assertion. + if (type_ == kUTF16LE || type_ == kUTF16BE) RAPIDJSON_ASSERT(sizeof(Ch) >= 2); + if (type_ == kUTF32LE || type_ == kUTF32BE) RAPIDJSON_ASSERT(sizeof(Ch) >= 4); + } + + typedef Ch (*TakeFunc)(InputByteStream& is); + InputByteStream* is_; + UTFType type_; + Ch current_; + TakeFunc takeFunc_; + bool hasBOM_; +}; + +//! Output stream wrapper with dynamically bound encoding and automatic encoding detection. +/*! + \tparam CharType Type of character for writing. + \tparam OutputByteStream type of output byte stream to be wrapped. +*/ +template +class AutoUTFOutputStream { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); +public: + typedef CharType Ch; + + //! Constructor. + /*! + \param os output stream to be wrapped. + \param type UTF encoding type. + \param putBOM Whether to write BOM at the beginning of the stream. + */ + AutoUTFOutputStream(OutputByteStream& os, UTFType type, bool putBOM) : os_(&os), type_(type) { + RAPIDJSON_ASSERT(type >= kUTF8 && type <= kUTF32BE); + + // Runtime check whether the size of character type is sufficient. It only perform checks with assertion. + if (type_ == kUTF16LE || type_ == kUTF16BE) RAPIDJSON_ASSERT(sizeof(Ch) >= 2); + if (type_ == kUTF32LE || type_ == kUTF32BE) RAPIDJSON_ASSERT(sizeof(Ch) >= 4); + + static const PutFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Put) }; + putFunc_ = f[type_]; + + if (putBOM) + PutBOM(); + } + + UTFType GetType() const { return type_; } + + void Put(Ch c) { putFunc_(*os_, c); } + void Flush() { os_->Flush(); } + + // Not implemented + Ch Peek() const { RAPIDJSON_ASSERT(false); return 0;} + Ch Take() { RAPIDJSON_ASSERT(false); return 0;} + size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; } + Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } + size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } + +private: + AutoUTFOutputStream(const AutoUTFOutputStream&); + AutoUTFOutputStream& operator=(const AutoUTFOutputStream&); + + void PutBOM() { + typedef void (*PutBOMFunc)(OutputByteStream&); + static const PutBOMFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(PutBOM) }; + f[type_](*os_); + } + + typedef void (*PutFunc)(OutputByteStream&, Ch); + + OutputByteStream* os_; + UTFType type_; + PutFunc putFunc_; +}; + +#undef RAPIDJSON_ENCODINGS_FUNC + +RAPIDJSON_NAMESPACE_END + +#ifdef __clang__ +RAPIDJSON_DIAG_POP +#endif + +#ifdef __GNUC__ +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_FILESTREAM_H_ diff --git a/slsReceiverSoftware/include/rapidjson/encodings.h b/slsReceiverSoftware/include/rapidjson/encodings.h new file mode 100644 index 000000000..baa7c2b17 --- /dev/null +++ b/slsReceiverSoftware/include/rapidjson/encodings.h @@ -0,0 +1,716 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_ENCODINGS_H_ +#define RAPIDJSON_ENCODINGS_H_ + +#include "rapidjson.h" + +#ifdef _MSC_VER +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(4244) // conversion from 'type1' to 'type2', possible loss of data +RAPIDJSON_DIAG_OFF(4702) // unreachable code +#elif defined(__GNUC__) +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(effc++) +RAPIDJSON_DIAG_OFF(overflow) +#endif + +RAPIDJSON_NAMESPACE_BEGIN + +/////////////////////////////////////////////////////////////////////////////// +// Encoding + +/*! \class rapidjson::Encoding + \brief Concept for encoding of Unicode characters. + +\code +concept Encoding { + typename Ch; //! Type of character. A "character" is actually a code unit in unicode's definition. + + enum { supportUnicode = 1 }; // or 0 if not supporting unicode + + //! \brief Encode a Unicode codepoint to an output stream. + //! \param os Output stream. + //! \param codepoint An unicode codepoint, ranging from 0x0 to 0x10FFFF inclusively. + template + static void Encode(OutputStream& os, unsigned codepoint); + + //! \brief Decode a Unicode codepoint from an input stream. + //! \param is Input stream. + //! \param codepoint Output of the unicode codepoint. + //! \return true if a valid codepoint can be decoded from the stream. + template + static bool Decode(InputStream& is, unsigned* codepoint); + + //! \brief Validate one Unicode codepoint from an encoded stream. + //! \param is Input stream to obtain codepoint. + //! \param os Output for copying one codepoint. + //! \return true if it is valid. + //! \note This function just validating and copying the codepoint without actually decode it. + template + static bool Validate(InputStream& is, OutputStream& os); + + // The following functions are deal with byte streams. + + //! Take a character from input byte stream, skip BOM if exist. + template + static CharType TakeBOM(InputByteStream& is); + + //! Take a character from input byte stream. + template + static Ch Take(InputByteStream& is); + + //! Put BOM to output byte stream. + template + static void PutBOM(OutputByteStream& os); + + //! Put a character to output byte stream. + template + static void Put(OutputByteStream& os, Ch c); +}; +\endcode +*/ + +/////////////////////////////////////////////////////////////////////////////// +// UTF8 + +//! UTF-8 encoding. +/*! http://en.wikipedia.org/wiki/UTF-8 + http://tools.ietf.org/html/rfc3629 + \tparam CharType Code unit for storing 8-bit UTF-8 data. Default is char. + \note implements Encoding concept +*/ +template +struct UTF8 { + typedef CharType Ch; + + enum { supportUnicode = 1 }; + + template + static void Encode(OutputStream& os, unsigned codepoint) { + if (codepoint <= 0x7F) + os.Put(static_cast(codepoint & 0xFF)); + else if (codepoint <= 0x7FF) { + os.Put(static_cast(0xC0 | ((codepoint >> 6) & 0xFF))); + os.Put(static_cast(0x80 | ((codepoint & 0x3F)))); + } + else if (codepoint <= 0xFFFF) { + os.Put(static_cast(0xE0 | ((codepoint >> 12) & 0xFF))); + os.Put(static_cast(0x80 | ((codepoint >> 6) & 0x3F))); + os.Put(static_cast(0x80 | (codepoint & 0x3F))); + } + else { + RAPIDJSON_ASSERT(codepoint <= 0x10FFFF); + os.Put(static_cast(0xF0 | ((codepoint >> 18) & 0xFF))); + os.Put(static_cast(0x80 | ((codepoint >> 12) & 0x3F))); + os.Put(static_cast(0x80 | ((codepoint >> 6) & 0x3F))); + os.Put(static_cast(0x80 | (codepoint & 0x3F))); + } + } + + template + static void EncodeUnsafe(OutputStream& os, unsigned codepoint) { + if (codepoint <= 0x7F) + PutUnsafe(os, static_cast(codepoint & 0xFF)); + else if (codepoint <= 0x7FF) { + PutUnsafe(os, static_cast(0xC0 | ((codepoint >> 6) & 0xFF))); + PutUnsafe(os, static_cast(0x80 | ((codepoint & 0x3F)))); + } + else if (codepoint <= 0xFFFF) { + PutUnsafe(os, static_cast(0xE0 | ((codepoint >> 12) & 0xFF))); + PutUnsafe(os, static_cast(0x80 | ((codepoint >> 6) & 0x3F))); + PutUnsafe(os, static_cast(0x80 | (codepoint & 0x3F))); + } + else { + RAPIDJSON_ASSERT(codepoint <= 0x10FFFF); + PutUnsafe(os, static_cast(0xF0 | ((codepoint >> 18) & 0xFF))); + PutUnsafe(os, static_cast(0x80 | ((codepoint >> 12) & 0x3F))); + PutUnsafe(os, static_cast(0x80 | ((codepoint >> 6) & 0x3F))); + PutUnsafe(os, static_cast(0x80 | (codepoint & 0x3F))); + } + } + + template + static bool Decode(InputStream& is, unsigned* codepoint) { +#define COPY() c = is.Take(); *codepoint = (*codepoint << 6) | (static_cast(c) & 0x3Fu) +#define TRANS(mask) result &= ((GetRange(static_cast(c)) & mask) != 0) +#define TAIL() COPY(); TRANS(0x70) + typename InputStream::Ch c = is.Take(); + if (!(c & 0x80)) { + *codepoint = static_cast(c); + return true; + } + + unsigned char type = GetRange(static_cast(c)); + if (type >= 32) { + *codepoint = 0; + } else { + *codepoint = (0xFF >> type) & static_cast(c); + } + bool result = true; + switch (type) { + case 2: TAIL(); return result; + case 3: TAIL(); TAIL(); return result; + case 4: COPY(); TRANS(0x50); TAIL(); return result; + case 5: COPY(); TRANS(0x10); TAIL(); TAIL(); return result; + case 6: TAIL(); TAIL(); TAIL(); return result; + case 10: COPY(); TRANS(0x20); TAIL(); return result; + case 11: COPY(); TRANS(0x60); TAIL(); TAIL(); return result; + default: return false; + } +#undef COPY +#undef TRANS +#undef TAIL + } + + template + static bool Validate(InputStream& is, OutputStream& os) { +#define COPY() os.Put(c = is.Take()) +#define TRANS(mask) result &= ((GetRange(static_cast(c)) & mask) != 0) +#define TAIL() COPY(); TRANS(0x70) + Ch c; + COPY(); + if (!(c & 0x80)) + return true; + + bool result = true; + switch (GetRange(static_cast(c))) { + case 2: TAIL(); return result; + case 3: TAIL(); TAIL(); return result; + case 4: COPY(); TRANS(0x50); TAIL(); return result; + case 5: COPY(); TRANS(0x10); TAIL(); TAIL(); return result; + case 6: TAIL(); TAIL(); TAIL(); return result; + case 10: COPY(); TRANS(0x20); TAIL(); return result; + case 11: COPY(); TRANS(0x60); TAIL(); TAIL(); return result; + default: return false; + } +#undef COPY +#undef TRANS +#undef TAIL + } + + static unsigned char GetRange(unsigned char c) { + // Referring to DFA of http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ + // With new mapping 1 -> 0x10, 7 -> 0x20, 9 -> 0x40, such that AND operation can test multiple types. + static const unsigned char type[] = { + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10, + 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40, + 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + 8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, + 10,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3, 11,6,6,6,5,8,8,8,8,8,8,8,8,8,8,8, + }; + return type[c]; + } + + template + static CharType TakeBOM(InputByteStream& is) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); + typename InputByteStream::Ch c = Take(is); + if (static_cast(c) != 0xEFu) return c; + c = is.Take(); + if (static_cast(c) != 0xBBu) return c; + c = is.Take(); + if (static_cast(c) != 0xBFu) return c; + c = is.Take(); + return c; + } + + template + static Ch Take(InputByteStream& is) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); + return static_cast(is.Take()); + } + + template + static void PutBOM(OutputByteStream& os) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); + os.Put(static_cast(0xEFu)); + os.Put(static_cast(0xBBu)); + os.Put(static_cast(0xBFu)); + } + + template + static void Put(OutputByteStream& os, Ch c) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); + os.Put(static_cast(c)); + } +}; + +/////////////////////////////////////////////////////////////////////////////// +// UTF16 + +//! UTF-16 encoding. +/*! http://en.wikipedia.org/wiki/UTF-16 + http://tools.ietf.org/html/rfc2781 + \tparam CharType Type for storing 16-bit UTF-16 data. Default is wchar_t. C++11 may use char16_t instead. + \note implements Encoding concept + + \note For in-memory access, no need to concern endianness. The code units and code points are represented by CPU's endianness. + For streaming, use UTF16LE and UTF16BE, which handle endianness. +*/ +template +struct UTF16 { + typedef CharType Ch; + RAPIDJSON_STATIC_ASSERT(sizeof(Ch) >= 2); + + enum { supportUnicode = 1 }; + + template + static void Encode(OutputStream& os, unsigned codepoint) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 2); + if (codepoint <= 0xFFFF) { + RAPIDJSON_ASSERT(codepoint < 0xD800 || codepoint > 0xDFFF); // Code point itself cannot be surrogate pair + os.Put(static_cast(codepoint)); + } + else { + RAPIDJSON_ASSERT(codepoint <= 0x10FFFF); + unsigned v = codepoint - 0x10000; + os.Put(static_cast((v >> 10) | 0xD800)); + os.Put((v & 0x3FF) | 0xDC00); + } + } + + + template + static void EncodeUnsafe(OutputStream& os, unsigned codepoint) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 2); + if (codepoint <= 0xFFFF) { + RAPIDJSON_ASSERT(codepoint < 0xD800 || codepoint > 0xDFFF); // Code point itself cannot be surrogate pair + PutUnsafe(os, static_cast(codepoint)); + } + else { + RAPIDJSON_ASSERT(codepoint <= 0x10FFFF); + unsigned v = codepoint - 0x10000; + PutUnsafe(os, static_cast((v >> 10) | 0xD800)); + PutUnsafe(os, (v & 0x3FF) | 0xDC00); + } + } + + template + static bool Decode(InputStream& is, unsigned* codepoint) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 2); + typename InputStream::Ch c = is.Take(); + if (c < 0xD800 || c > 0xDFFF) { + *codepoint = static_cast(c); + return true; + } + else if (c <= 0xDBFF) { + *codepoint = (static_cast(c) & 0x3FF) << 10; + c = is.Take(); + *codepoint |= (static_cast(c) & 0x3FF); + *codepoint += 0x10000; + return c >= 0xDC00 && c <= 0xDFFF; + } + return false; + } + + template + static bool Validate(InputStream& is, OutputStream& os) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 2); + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 2); + typename InputStream::Ch c; + os.Put(static_cast(c = is.Take())); + if (c < 0xD800 || c > 0xDFFF) + return true; + else if (c <= 0xDBFF) { + os.Put(c = is.Take()); + return c >= 0xDC00 && c <= 0xDFFF; + } + return false; + } +}; + +//! UTF-16 little endian encoding. +template +struct UTF16LE : UTF16 { + template + static CharType TakeBOM(InputByteStream& is) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); + CharType c = Take(is); + return static_cast(c) == 0xFEFFu ? Take(is) : c; + } + + template + static CharType Take(InputByteStream& is) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); + unsigned c = static_cast(is.Take()); + c |= static_cast(static_cast(is.Take())) << 8; + return static_cast(c); + } + + template + static void PutBOM(OutputByteStream& os) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); + os.Put(static_cast(0xFFu)); + os.Put(static_cast(0xFEu)); + } + + template + static void Put(OutputByteStream& os, CharType c) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); + os.Put(static_cast(static_cast(c) & 0xFFu)); + os.Put(static_cast((static_cast(c) >> 8) & 0xFFu)); + } +}; + +//! UTF-16 big endian encoding. +template +struct UTF16BE : UTF16 { + template + static CharType TakeBOM(InputByteStream& is) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); + CharType c = Take(is); + return static_cast(c) == 0xFEFFu ? Take(is) : c; + } + + template + static CharType Take(InputByteStream& is) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); + unsigned c = static_cast(static_cast(is.Take())) << 8; + c |= static_cast(is.Take()); + return static_cast(c); + } + + template + static void PutBOM(OutputByteStream& os) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); + os.Put(static_cast(0xFEu)); + os.Put(static_cast(0xFFu)); + } + + template + static void Put(OutputByteStream& os, CharType c) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); + os.Put(static_cast((static_cast(c) >> 8) & 0xFFu)); + os.Put(static_cast(static_cast(c) & 0xFFu)); + } +}; + +/////////////////////////////////////////////////////////////////////////////// +// UTF32 + +//! UTF-32 encoding. +/*! http://en.wikipedia.org/wiki/UTF-32 + \tparam CharType Type for storing 32-bit UTF-32 data. Default is unsigned. C++11 may use char32_t instead. + \note implements Encoding concept + + \note For in-memory access, no need to concern endianness. The code units and code points are represented by CPU's endianness. + For streaming, use UTF32LE and UTF32BE, which handle endianness. +*/ +template +struct UTF32 { + typedef CharType Ch; + RAPIDJSON_STATIC_ASSERT(sizeof(Ch) >= 4); + + enum { supportUnicode = 1 }; + + template + static void Encode(OutputStream& os, unsigned codepoint) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 4); + RAPIDJSON_ASSERT(codepoint <= 0x10FFFF); + os.Put(codepoint); + } + + template + static void EncodeUnsafe(OutputStream& os, unsigned codepoint) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 4); + RAPIDJSON_ASSERT(codepoint <= 0x10FFFF); + PutUnsafe(os, codepoint); + } + + template + static bool Decode(InputStream& is, unsigned* codepoint) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 4); + Ch c = is.Take(); + *codepoint = c; + return c <= 0x10FFFF; + } + + template + static bool Validate(InputStream& is, OutputStream& os) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 4); + Ch c; + os.Put(c = is.Take()); + return c <= 0x10FFFF; + } +}; + +//! UTF-32 little endian enocoding. +template +struct UTF32LE : UTF32 { + template + static CharType TakeBOM(InputByteStream& is) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); + CharType c = Take(is); + return static_cast(c) == 0x0000FEFFu ? Take(is) : c; + } + + template + static CharType Take(InputByteStream& is) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); + unsigned c = static_cast(is.Take()); + c |= static_cast(static_cast(is.Take())) << 8; + c |= static_cast(static_cast(is.Take())) << 16; + c |= static_cast(static_cast(is.Take())) << 24; + return static_cast(c); + } + + template + static void PutBOM(OutputByteStream& os) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); + os.Put(static_cast(0xFFu)); + os.Put(static_cast(0xFEu)); + os.Put(static_cast(0x00u)); + os.Put(static_cast(0x00u)); + } + + template + static void Put(OutputByteStream& os, CharType c) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); + os.Put(static_cast(c & 0xFFu)); + os.Put(static_cast((c >> 8) & 0xFFu)); + os.Put(static_cast((c >> 16) & 0xFFu)); + os.Put(static_cast((c >> 24) & 0xFFu)); + } +}; + +//! UTF-32 big endian encoding. +template +struct UTF32BE : UTF32 { + template + static CharType TakeBOM(InputByteStream& is) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); + CharType c = Take(is); + return static_cast(c) == 0x0000FEFFu ? Take(is) : c; + } + + template + static CharType Take(InputByteStream& is) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); + unsigned c = static_cast(static_cast(is.Take())) << 24; + c |= static_cast(static_cast(is.Take())) << 16; + c |= static_cast(static_cast(is.Take())) << 8; + c |= static_cast(static_cast(is.Take())); + return static_cast(c); + } + + template + static void PutBOM(OutputByteStream& os) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); + os.Put(static_cast(0x00u)); + os.Put(static_cast(0x00u)); + os.Put(static_cast(0xFEu)); + os.Put(static_cast(0xFFu)); + } + + template + static void Put(OutputByteStream& os, CharType c) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); + os.Put(static_cast((c >> 24) & 0xFFu)); + os.Put(static_cast((c >> 16) & 0xFFu)); + os.Put(static_cast((c >> 8) & 0xFFu)); + os.Put(static_cast(c & 0xFFu)); + } +}; + +/////////////////////////////////////////////////////////////////////////////// +// ASCII + +//! ASCII encoding. +/*! http://en.wikipedia.org/wiki/ASCII + \tparam CharType Code unit for storing 7-bit ASCII data. Default is char. + \note implements Encoding concept +*/ +template +struct ASCII { + typedef CharType Ch; + + enum { supportUnicode = 0 }; + + template + static void Encode(OutputStream& os, unsigned codepoint) { + RAPIDJSON_ASSERT(codepoint <= 0x7F); + os.Put(static_cast(codepoint & 0xFF)); + } + + template + static void EncodeUnsafe(OutputStream& os, unsigned codepoint) { + RAPIDJSON_ASSERT(codepoint <= 0x7F); + PutUnsafe(os, static_cast(codepoint & 0xFF)); + } + + template + static bool Decode(InputStream& is, unsigned* codepoint) { + uint8_t c = static_cast(is.Take()); + *codepoint = c; + return c <= 0X7F; + } + + template + static bool Validate(InputStream& is, OutputStream& os) { + uint8_t c = static_cast(is.Take()); + os.Put(static_cast(c)); + return c <= 0x7F; + } + + template + static CharType TakeBOM(InputByteStream& is) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); + uint8_t c = static_cast(Take(is)); + return static_cast(c); + } + + template + static Ch Take(InputByteStream& is) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); + return static_cast(is.Take()); + } + + template + static void PutBOM(OutputByteStream& os) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); + (void)os; + } + + template + static void Put(OutputByteStream& os, Ch c) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); + os.Put(static_cast(c)); + } +}; + +/////////////////////////////////////////////////////////////////////////////// +// AutoUTF + +//! Runtime-specified UTF encoding type of a stream. +enum UTFType { + kUTF8 = 0, //!< UTF-8. + kUTF16LE = 1, //!< UTF-16 little endian. + kUTF16BE = 2, //!< UTF-16 big endian. + kUTF32LE = 3, //!< UTF-32 little endian. + kUTF32BE = 4 //!< UTF-32 big endian. +}; + +//! Dynamically select encoding according to stream's runtime-specified UTF encoding type. +/*! \note This class can be used with AutoUTFInputtStream and AutoUTFOutputStream, which provides GetType(). +*/ +template +struct AutoUTF { + typedef CharType Ch; + + enum { supportUnicode = 1 }; + +#define RAPIDJSON_ENCODINGS_FUNC(x) UTF8::x, UTF16LE::x, UTF16BE::x, UTF32LE::x, UTF32BE::x + + template + RAPIDJSON_FORCEINLINE static void Encode(OutputStream& os, unsigned codepoint) { + typedef void (*EncodeFunc)(OutputStream&, unsigned); + static const EncodeFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Encode) }; + (*f[os.GetType()])(os, codepoint); + } + + template + RAPIDJSON_FORCEINLINE static void EncodeUnsafe(OutputStream& os, unsigned codepoint) { + typedef void (*EncodeFunc)(OutputStream&, unsigned); + static const EncodeFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(EncodeUnsafe) }; + (*f[os.GetType()])(os, codepoint); + } + + template + RAPIDJSON_FORCEINLINE static bool Decode(InputStream& is, unsigned* codepoint) { + typedef bool (*DecodeFunc)(InputStream&, unsigned*); + static const DecodeFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Decode) }; + return (*f[is.GetType()])(is, codepoint); + } + + template + RAPIDJSON_FORCEINLINE static bool Validate(InputStream& is, OutputStream& os) { + typedef bool (*ValidateFunc)(InputStream&, OutputStream&); + static const ValidateFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Validate) }; + return (*f[is.GetType()])(is, os); + } + +#undef RAPIDJSON_ENCODINGS_FUNC +}; + +/////////////////////////////////////////////////////////////////////////////// +// Transcoder + +//! Encoding conversion. +template +struct Transcoder { + //! Take one Unicode codepoint from source encoding, convert it to target encoding and put it to the output stream. + template + RAPIDJSON_FORCEINLINE static bool Transcode(InputStream& is, OutputStream& os) { + unsigned codepoint; + if (!SourceEncoding::Decode(is, &codepoint)) + return false; + TargetEncoding::Encode(os, codepoint); + return true; + } + + template + RAPIDJSON_FORCEINLINE static bool TranscodeUnsafe(InputStream& is, OutputStream& os) { + unsigned codepoint; + if (!SourceEncoding::Decode(is, &codepoint)) + return false; + TargetEncoding::EncodeUnsafe(os, codepoint); + return true; + } + + //! Validate one Unicode codepoint from an encoded stream. + template + RAPIDJSON_FORCEINLINE static bool Validate(InputStream& is, OutputStream& os) { + return Transcode(is, os); // Since source/target encoding is different, must transcode. + } +}; + +// Forward declaration. +template +inline void PutUnsafe(Stream& stream, typename Stream::Ch c); + +//! Specialization of Transcoder with same source and target encoding. +template +struct Transcoder { + template + RAPIDJSON_FORCEINLINE static bool Transcode(InputStream& is, OutputStream& os) { + os.Put(is.Take()); // Just copy one code unit. This semantic is different from primary template class. + return true; + } + + template + RAPIDJSON_FORCEINLINE static bool TranscodeUnsafe(InputStream& is, OutputStream& os) { + PutUnsafe(os, is.Take()); // Just copy one code unit. This semantic is different from primary template class. + return true; + } + + template + RAPIDJSON_FORCEINLINE static bool Validate(InputStream& is, OutputStream& os) { + return Encoding::Validate(is, os); // source/target encoding are the same + } +}; + +RAPIDJSON_NAMESPACE_END + +#if defined(__GNUC__) || defined(_MSC_VER) +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_ENCODINGS_H_ diff --git a/slsReceiverSoftware/include/rapidjson/error/en.h b/slsReceiverSoftware/include/rapidjson/error/en.h new file mode 100644 index 000000000..2db838bff --- /dev/null +++ b/slsReceiverSoftware/include/rapidjson/error/en.h @@ -0,0 +1,74 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_ERROR_EN_H_ +#define RAPIDJSON_ERROR_EN_H_ + +#include "error.h" + +#ifdef __clang__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(switch-enum) +RAPIDJSON_DIAG_OFF(covered-switch-default) +#endif + +RAPIDJSON_NAMESPACE_BEGIN + +//! Maps error code of parsing into error message. +/*! + \ingroup RAPIDJSON_ERRORS + \param parseErrorCode Error code obtained in parsing. + \return the error message. + \note User can make a copy of this function for localization. + Using switch-case is safer for future modification of error codes. +*/ +inline const RAPIDJSON_ERROR_CHARTYPE* GetParseError_En(ParseErrorCode parseErrorCode) { + switch (parseErrorCode) { + case kParseErrorNone: return RAPIDJSON_ERROR_STRING("No error."); + + case kParseErrorDocumentEmpty: return RAPIDJSON_ERROR_STRING("The document is empty."); + case kParseErrorDocumentRootNotSingular: return RAPIDJSON_ERROR_STRING("The document root must not be followed by other values."); + + case kParseErrorValueInvalid: return RAPIDJSON_ERROR_STRING("Invalid value."); + + case kParseErrorObjectMissName: return RAPIDJSON_ERROR_STRING("Missing a name for object member."); + case kParseErrorObjectMissColon: return RAPIDJSON_ERROR_STRING("Missing a colon after a name of object member."); + case kParseErrorObjectMissCommaOrCurlyBracket: return RAPIDJSON_ERROR_STRING("Missing a comma or '}' after an object member."); + + case kParseErrorArrayMissCommaOrSquareBracket: return RAPIDJSON_ERROR_STRING("Missing a comma or ']' after an array element."); + + case kParseErrorStringUnicodeEscapeInvalidHex: return RAPIDJSON_ERROR_STRING("Incorrect hex digit after \\u escape in string."); + case kParseErrorStringUnicodeSurrogateInvalid: return RAPIDJSON_ERROR_STRING("The surrogate pair in string is invalid."); + case kParseErrorStringEscapeInvalid: return RAPIDJSON_ERROR_STRING("Invalid escape character in string."); + case kParseErrorStringMissQuotationMark: return RAPIDJSON_ERROR_STRING("Missing a closing quotation mark in string."); + case kParseErrorStringInvalidEncoding: return RAPIDJSON_ERROR_STRING("Invalid encoding in string."); + + case kParseErrorNumberTooBig: return RAPIDJSON_ERROR_STRING("Number too big to be stored in double."); + case kParseErrorNumberMissFraction: return RAPIDJSON_ERROR_STRING("Miss fraction part in number."); + case kParseErrorNumberMissExponent: return RAPIDJSON_ERROR_STRING("Miss exponent in number."); + + case kParseErrorTermination: return RAPIDJSON_ERROR_STRING("Terminate parsing due to Handler error."); + case kParseErrorUnspecificSyntaxError: return RAPIDJSON_ERROR_STRING("Unspecific syntax error."); + + default: return RAPIDJSON_ERROR_STRING("Unknown error."); + } +} + +RAPIDJSON_NAMESPACE_END + +#ifdef __clang__ +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_ERROR_EN_H_ diff --git a/slsReceiverSoftware/include/rapidjson/error/error.h b/slsReceiverSoftware/include/rapidjson/error/error.h new file mode 100644 index 000000000..95cb31a72 --- /dev/null +++ b/slsReceiverSoftware/include/rapidjson/error/error.h @@ -0,0 +1,155 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_ERROR_ERROR_H_ +#define RAPIDJSON_ERROR_ERROR_H_ + +#include "../rapidjson.h" + +#ifdef __clang__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(padded) +#endif + +/*! \file error.h */ + +/*! \defgroup RAPIDJSON_ERRORS RapidJSON error handling */ + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_ERROR_CHARTYPE + +//! Character type of error messages. +/*! \ingroup RAPIDJSON_ERRORS + The default character type is \c char. + On Windows, user can define this macro as \c TCHAR for supporting both + unicode/non-unicode settings. +*/ +#ifndef RAPIDJSON_ERROR_CHARTYPE +#define RAPIDJSON_ERROR_CHARTYPE char +#endif + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_ERROR_STRING + +//! Macro for converting string literial to \ref RAPIDJSON_ERROR_CHARTYPE[]. +/*! \ingroup RAPIDJSON_ERRORS + By default this conversion macro does nothing. + On Windows, user can define this macro as \c _T(x) for supporting both + unicode/non-unicode settings. +*/ +#ifndef RAPIDJSON_ERROR_STRING +#define RAPIDJSON_ERROR_STRING(x) x +#endif + +RAPIDJSON_NAMESPACE_BEGIN + +/////////////////////////////////////////////////////////////////////////////// +// ParseErrorCode + +//! Error code of parsing. +/*! \ingroup RAPIDJSON_ERRORS + \see GenericReader::Parse, GenericReader::GetParseErrorCode +*/ +enum ParseErrorCode { + kParseErrorNone = 0, //!< No error. + + kParseErrorDocumentEmpty, //!< The document is empty. + kParseErrorDocumentRootNotSingular, //!< The document root must not follow by other values. + + kParseErrorValueInvalid, //!< Invalid value. + + kParseErrorObjectMissName, //!< Missing a name for object member. + kParseErrorObjectMissColon, //!< Missing a colon after a name of object member. + kParseErrorObjectMissCommaOrCurlyBracket, //!< Missing a comma or '}' after an object member. + + kParseErrorArrayMissCommaOrSquareBracket, //!< Missing a comma or ']' after an array element. + + kParseErrorStringUnicodeEscapeInvalidHex, //!< Incorrect hex digit after \\u escape in string. + kParseErrorStringUnicodeSurrogateInvalid, //!< The surrogate pair in string is invalid. + kParseErrorStringEscapeInvalid, //!< Invalid escape character in string. + kParseErrorStringMissQuotationMark, //!< Missing a closing quotation mark in string. + kParseErrorStringInvalidEncoding, //!< Invalid encoding in string. + + kParseErrorNumberTooBig, //!< Number too big to be stored in double. + kParseErrorNumberMissFraction, //!< Miss fraction part in number. + kParseErrorNumberMissExponent, //!< Miss exponent in number. + + kParseErrorTermination, //!< Parsing was terminated. + kParseErrorUnspecificSyntaxError //!< Unspecific syntax error. +}; + +//! Result of parsing (wraps ParseErrorCode) +/*! + \ingroup RAPIDJSON_ERRORS + \code + Document doc; + ParseResult ok = doc.Parse("[42]"); + if (!ok) { + fprintf(stderr, "JSON parse error: %s (%u)", + GetParseError_En(ok.Code()), ok.Offset()); + exit(EXIT_FAILURE); + } + \endcode + \see GenericReader::Parse, GenericDocument::Parse +*/ +struct ParseResult { +public: + //! Default constructor, no error. + ParseResult() : code_(kParseErrorNone), offset_(0) {} + //! Constructor to set an error. + ParseResult(ParseErrorCode code, size_t offset) : code_(code), offset_(offset) {} + + //! Get the error code. + ParseErrorCode Code() const { return code_; } + //! Get the error offset, if \ref IsError(), 0 otherwise. + size_t Offset() const { return offset_; } + + //! Conversion to \c bool, returns \c true, iff !\ref IsError(). + operator bool() const { return !IsError(); } + //! Whether the result is an error. + bool IsError() const { return code_ != kParseErrorNone; } + + bool operator==(const ParseResult& that) const { return code_ == that.code_; } + bool operator==(ParseErrorCode code) const { return code_ == code; } + friend bool operator==(ParseErrorCode code, const ParseResult & err) { return code == err.code_; } + + //! Reset error code. + void Clear() { Set(kParseErrorNone); } + //! Update error code and offset. + void Set(ParseErrorCode code, size_t offset = 0) { code_ = code; offset_ = offset; } + +private: + ParseErrorCode code_; + size_t offset_; +}; + +//! Function pointer type of GetParseError(). +/*! \ingroup RAPIDJSON_ERRORS + + This is the prototype for \c GetParseError_X(), where \c X is a locale. + User can dynamically change locale in runtime, e.g.: +\code + GetParseErrorFunc GetParseError = GetParseError_En; // or whatever + const RAPIDJSON_ERROR_CHARTYPE* s = GetParseError(document.GetParseErrorCode()); +\endcode +*/ +typedef const RAPIDJSON_ERROR_CHARTYPE* (*GetParseErrorFunc)(ParseErrorCode); + +RAPIDJSON_NAMESPACE_END + +#ifdef __clang__ +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_ERROR_ERROR_H_ diff --git a/slsReceiverSoftware/include/rapidjson/filereadstream.h b/slsReceiverSoftware/include/rapidjson/filereadstream.h new file mode 100644 index 000000000..b56ea13b3 --- /dev/null +++ b/slsReceiverSoftware/include/rapidjson/filereadstream.h @@ -0,0 +1,99 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_FILEREADSTREAM_H_ +#define RAPIDJSON_FILEREADSTREAM_H_ + +#include "stream.h" +#include + +#ifdef __clang__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(padded) +RAPIDJSON_DIAG_OFF(unreachable-code) +RAPIDJSON_DIAG_OFF(missing-noreturn) +#endif + +RAPIDJSON_NAMESPACE_BEGIN + +//! File byte stream for input using fread(). +/*! + \note implements Stream concept +*/ +class FileReadStream { +public: + typedef char Ch; //!< Character type (byte). + + //! Constructor. + /*! + \param fp File pointer opened for read. + \param buffer user-supplied buffer. + \param bufferSize size of buffer in bytes. Must >=4 bytes. + */ + FileReadStream(std::FILE* fp, char* buffer, size_t bufferSize) : fp_(fp), buffer_(buffer), bufferSize_(bufferSize), bufferLast_(0), current_(buffer_), readCount_(0), count_(0), eof_(false) { + RAPIDJSON_ASSERT(fp_ != 0); + RAPIDJSON_ASSERT(bufferSize >= 4); + Read(); + } + + Ch Peek() const { return *current_; } + Ch Take() { Ch c = *current_; Read(); return c; } + size_t Tell() const { return count_ + static_cast(current_ - buffer_); } + + // Not implemented + void Put(Ch) { RAPIDJSON_ASSERT(false); } + void Flush() { RAPIDJSON_ASSERT(false); } + Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } + size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } + + // For encoding detection only. + const Ch* Peek4() const { + return (current_ + 4 <= bufferLast_) ? current_ : 0; + } + +private: + void Read() { + if (current_ < bufferLast_) + ++current_; + else if (!eof_) { + count_ += readCount_; + readCount_ = fread(buffer_, 1, bufferSize_, fp_); + bufferLast_ = buffer_ + readCount_ - 1; + current_ = buffer_; + + if (readCount_ < bufferSize_) { + buffer_[readCount_] = '\0'; + ++bufferLast_; + eof_ = true; + } + } + } + + std::FILE* fp_; + Ch *buffer_; + size_t bufferSize_; + Ch *bufferLast_; + Ch *current_; + size_t readCount_; + size_t count_; //!< Number of characters read + bool eof_; +}; + +RAPIDJSON_NAMESPACE_END + +#ifdef __clang__ +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_FILESTREAM_H_ diff --git a/slsReceiverSoftware/include/rapidjson/filewritestream.h b/slsReceiverSoftware/include/rapidjson/filewritestream.h new file mode 100644 index 000000000..6378dd60e --- /dev/null +++ b/slsReceiverSoftware/include/rapidjson/filewritestream.h @@ -0,0 +1,104 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_FILEWRITESTREAM_H_ +#define RAPIDJSON_FILEWRITESTREAM_H_ + +#include "stream.h" +#include + +#ifdef __clang__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(unreachable-code) +#endif + +RAPIDJSON_NAMESPACE_BEGIN + +//! Wrapper of C file stream for input using fread(). +/*! + \note implements Stream concept +*/ +class FileWriteStream { +public: + typedef char Ch; //!< Character type. Only support char. + + FileWriteStream(std::FILE* fp, char* buffer, size_t bufferSize) : fp_(fp), buffer_(buffer), bufferEnd_(buffer + bufferSize), current_(buffer_) { + RAPIDJSON_ASSERT(fp_ != 0); + } + + void Put(char c) { + if (current_ >= bufferEnd_) + Flush(); + + *current_++ = c; + } + + void PutN(char c, size_t n) { + size_t avail = static_cast(bufferEnd_ - current_); + while (n > avail) { + std::memset(current_, c, avail); + current_ += avail; + Flush(); + n -= avail; + avail = static_cast(bufferEnd_ - current_); + } + + if (n > 0) { + std::memset(current_, c, n); + current_ += n; + } + } + + void Flush() { + if (current_ != buffer_) { + size_t result = fwrite(buffer_, 1, static_cast(current_ - buffer_), fp_); + if (result < static_cast(current_ - buffer_)) { + // failure deliberately ignored at this time + // added to avoid warn_unused_result build errors + } + current_ = buffer_; + } + } + + // Not implemented + char Peek() const { RAPIDJSON_ASSERT(false); return 0; } + char Take() { RAPIDJSON_ASSERT(false); return 0; } + size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; } + char* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } + size_t PutEnd(char*) { RAPIDJSON_ASSERT(false); return 0; } + +private: + // Prohibit copy constructor & assignment operator. + FileWriteStream(const FileWriteStream&); + FileWriteStream& operator=(const FileWriteStream&); + + std::FILE* fp_; + char *buffer_; + char *bufferEnd_; + char *current_; +}; + +//! Implement specialized version of PutN() with memset() for better performance. +template<> +inline void PutN(FileWriteStream& stream, char c, size_t n) { + stream.PutN(c, n); +} + +RAPIDJSON_NAMESPACE_END + +#ifdef __clang__ +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_FILESTREAM_H_ diff --git a/slsReceiverSoftware/include/rapidjson/fwd.h b/slsReceiverSoftware/include/rapidjson/fwd.h new file mode 100644 index 000000000..e8104e841 --- /dev/null +++ b/slsReceiverSoftware/include/rapidjson/fwd.h @@ -0,0 +1,151 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_FWD_H_ +#define RAPIDJSON_FWD_H_ + +#include "rapidjson.h" + +RAPIDJSON_NAMESPACE_BEGIN + +// encodings.h + +template struct UTF8; +template struct UTF16; +template struct UTF16BE; +template struct UTF16LE; +template struct UTF32; +template struct UTF32BE; +template struct UTF32LE; +template struct ASCII; +template struct AutoUTF; + +template +struct Transcoder; + +// allocators.h + +class CrtAllocator; + +template +class MemoryPoolAllocator; + +// stream.h + +template +struct GenericStringStream; + +typedef GenericStringStream > StringStream; + +template +struct GenericInsituStringStream; + +typedef GenericInsituStringStream > InsituStringStream; + +// stringbuffer.h + +template +class GenericStringBuffer; + +typedef GenericStringBuffer, CrtAllocator> StringBuffer; + +// filereadstream.h + +class FileReadStream; + +// filewritestream.h + +class FileWriteStream; + +// memorybuffer.h + +template +struct GenericMemoryBuffer; + +typedef GenericMemoryBuffer MemoryBuffer; + +// memorystream.h + +struct MemoryStream; + +// reader.h + +template +struct BaseReaderHandler; + +template +class GenericReader; + +typedef GenericReader, UTF8, CrtAllocator> Reader; + +// writer.h + +template +class Writer; + +// prettywriter.h + +template +class PrettyWriter; + +// document.h + +template +struct GenericMember; + +template +class GenericMemberIterator; + +template +struct GenericStringRef; + +template +class GenericValue; + +typedef GenericValue, MemoryPoolAllocator > Value; + +template +class GenericDocument; + +typedef GenericDocument, MemoryPoolAllocator, CrtAllocator> Document; + +// pointer.h + +template +class GenericPointer; + +typedef GenericPointer Pointer; + +// schema.h + +template +class IGenericRemoteSchemaDocumentProvider; + +template +class GenericSchemaDocument; + +typedef GenericSchemaDocument SchemaDocument; +typedef IGenericRemoteSchemaDocumentProvider IRemoteSchemaDocumentProvider; + +template < + typename SchemaDocumentType, + typename OutputHandler, + typename StateAllocator> +class GenericSchemaValidator; + +typedef GenericSchemaValidator, void>, CrtAllocator> SchemaValidator; + +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_RAPIDJSONFWD_H_ diff --git a/slsReceiverSoftware/include/rapidjson/internal/biginteger.h b/slsReceiverSoftware/include/rapidjson/internal/biginteger.h new file mode 100644 index 000000000..9d3e88c99 --- /dev/null +++ b/slsReceiverSoftware/include/rapidjson/internal/biginteger.h @@ -0,0 +1,290 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_BIGINTEGER_H_ +#define RAPIDJSON_BIGINTEGER_H_ + +#include "../rapidjson.h" + +#if defined(_MSC_VER) && defined(_M_AMD64) +#include // for _umul128 +#pragma intrinsic(_umul128) +#endif + +RAPIDJSON_NAMESPACE_BEGIN +namespace internal { + +class BigInteger { +public: + typedef uint64_t Type; + + BigInteger(const BigInteger& rhs) : count_(rhs.count_) { + std::memcpy(digits_, rhs.digits_, count_ * sizeof(Type)); + } + + explicit BigInteger(uint64_t u) : count_(1) { + digits_[0] = u; + } + + BigInteger(const char* decimals, size_t length) : count_(1) { + RAPIDJSON_ASSERT(length > 0); + digits_[0] = 0; + size_t i = 0; + const size_t kMaxDigitPerIteration = 19; // 2^64 = 18446744073709551616 > 10^19 + while (length >= kMaxDigitPerIteration) { + AppendDecimal64(decimals + i, decimals + i + kMaxDigitPerIteration); + length -= kMaxDigitPerIteration; + i += kMaxDigitPerIteration; + } + + if (length > 0) + AppendDecimal64(decimals + i, decimals + i + length); + } + + BigInteger& operator=(const BigInteger &rhs) + { + if (this != &rhs) { + count_ = rhs.count_; + std::memcpy(digits_, rhs.digits_, count_ * sizeof(Type)); + } + return *this; + } + + BigInteger& operator=(uint64_t u) { + digits_[0] = u; + count_ = 1; + return *this; + } + + BigInteger& operator+=(uint64_t u) { + Type backup = digits_[0]; + digits_[0] += u; + for (size_t i = 0; i < count_ - 1; i++) { + if (digits_[i] >= backup) + return *this; // no carry + backup = digits_[i + 1]; + digits_[i + 1] += 1; + } + + // Last carry + if (digits_[count_ - 1] < backup) + PushBack(1); + + return *this; + } + + BigInteger& operator*=(uint64_t u) { + if (u == 0) return *this = 0; + if (u == 1) return *this; + if (*this == 1) return *this = u; + + uint64_t k = 0; + for (size_t i = 0; i < count_; i++) { + uint64_t hi; + digits_[i] = MulAdd64(digits_[i], u, k, &hi); + k = hi; + } + + if (k > 0) + PushBack(k); + + return *this; + } + + BigInteger& operator*=(uint32_t u) { + if (u == 0) return *this = 0; + if (u == 1) return *this; + if (*this == 1) return *this = u; + + uint64_t k = 0; + for (size_t i = 0; i < count_; i++) { + const uint64_t c = digits_[i] >> 32; + const uint64_t d = digits_[i] & 0xFFFFFFFF; + const uint64_t uc = u * c; + const uint64_t ud = u * d; + const uint64_t p0 = ud + k; + const uint64_t p1 = uc + (p0 >> 32); + digits_[i] = (p0 & 0xFFFFFFFF) | (p1 << 32); + k = p1 >> 32; + } + + if (k > 0) + PushBack(k); + + return *this; + } + + BigInteger& operator<<=(size_t shift) { + if (IsZero() || shift == 0) return *this; + + size_t offset = shift / kTypeBit; + size_t interShift = shift % kTypeBit; + RAPIDJSON_ASSERT(count_ + offset <= kCapacity); + + if (interShift == 0) { + std::memmove(&digits_[count_ - 1 + offset], &digits_[count_ - 1], count_ * sizeof(Type)); + count_ += offset; + } + else { + digits_[count_] = 0; + for (size_t i = count_; i > 0; i--) + digits_[i + offset] = (digits_[i] << interShift) | (digits_[i - 1] >> (kTypeBit - interShift)); + digits_[offset] = digits_[0] << interShift; + count_ += offset; + if (digits_[count_]) + count_++; + } + + std::memset(digits_, 0, offset * sizeof(Type)); + + return *this; + } + + bool operator==(const BigInteger& rhs) const { + return count_ == rhs.count_ && std::memcmp(digits_, rhs.digits_, count_ * sizeof(Type)) == 0; + } + + bool operator==(const Type rhs) const { + return count_ == 1 && digits_[0] == rhs; + } + + BigInteger& MultiplyPow5(unsigned exp) { + static const uint32_t kPow5[12] = { + 5, + 5 * 5, + 5 * 5 * 5, + 5 * 5 * 5 * 5, + 5 * 5 * 5 * 5 * 5, + 5 * 5 * 5 * 5 * 5 * 5, + 5 * 5 * 5 * 5 * 5 * 5 * 5, + 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5, + 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5, + 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5, + 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5, + 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 + }; + if (exp == 0) return *this; + for (; exp >= 27; exp -= 27) *this *= RAPIDJSON_UINT64_C2(0X6765C793, 0XFA10079D); // 5^27 + for (; exp >= 13; exp -= 13) *this *= static_cast(1220703125u); // 5^13 + if (exp > 0) *this *= kPow5[exp - 1]; + return *this; + } + + // Compute absolute difference of this and rhs. + // Assume this != rhs + bool Difference(const BigInteger& rhs, BigInteger* out) const { + int cmp = Compare(rhs); + RAPIDJSON_ASSERT(cmp != 0); + const BigInteger *a, *b; // Makes a > b + bool ret; + if (cmp < 0) { a = &rhs; b = this; ret = true; } + else { a = this; b = &rhs; ret = false; } + + Type borrow = 0; + for (size_t i = 0; i < a->count_; i++) { + Type d = a->digits_[i] - borrow; + if (i < b->count_) + d -= b->digits_[i]; + borrow = (d > a->digits_[i]) ? 1 : 0; + out->digits_[i] = d; + if (d != 0) + out->count_ = i + 1; + } + + return ret; + } + + int Compare(const BigInteger& rhs) const { + if (count_ != rhs.count_) + return count_ < rhs.count_ ? -1 : 1; + + for (size_t i = count_; i-- > 0;) + if (digits_[i] != rhs.digits_[i]) + return digits_[i] < rhs.digits_[i] ? -1 : 1; + + return 0; + } + + size_t GetCount() const { return count_; } + Type GetDigit(size_t index) const { RAPIDJSON_ASSERT(index < count_); return digits_[index]; } + bool IsZero() const { return count_ == 1 && digits_[0] == 0; } + +private: + void AppendDecimal64(const char* begin, const char* end) { + uint64_t u = ParseUint64(begin, end); + if (IsZero()) + *this = u; + else { + unsigned exp = static_cast(end - begin); + (MultiplyPow5(exp) <<= exp) += u; // *this = *this * 10^exp + u + } + } + + void PushBack(Type digit) { + RAPIDJSON_ASSERT(count_ < kCapacity); + digits_[count_++] = digit; + } + + static uint64_t ParseUint64(const char* begin, const char* end) { + uint64_t r = 0; + for (const char* p = begin; p != end; ++p) { + RAPIDJSON_ASSERT(*p >= '0' && *p <= '9'); + r = r * 10u + static_cast(*p - '0'); + } + return r; + } + + // Assume a * b + k < 2^128 + static uint64_t MulAdd64(uint64_t a, uint64_t b, uint64_t k, uint64_t* outHigh) { +#if defined(_MSC_VER) && defined(_M_AMD64) + uint64_t low = _umul128(a, b, outHigh) + k; + if (low < k) + (*outHigh)++; + return low; +#elif (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) && defined(__x86_64__) + __extension__ typedef unsigned __int128 uint128; + uint128 p = static_cast(a) * static_cast(b); + p += k; + *outHigh = static_cast(p >> 64); + return static_cast(p); +#else + const uint64_t a0 = a & 0xFFFFFFFF, a1 = a >> 32, b0 = b & 0xFFFFFFFF, b1 = b >> 32; + uint64_t x0 = a0 * b0, x1 = a0 * b1, x2 = a1 * b0, x3 = a1 * b1; + x1 += (x0 >> 32); // can't give carry + x1 += x2; + if (x1 < x2) + x3 += (static_cast(1) << 32); + uint64_t lo = (x1 << 32) + (x0 & 0xFFFFFFFF); + uint64_t hi = x3 + (x1 >> 32); + + lo += k; + if (lo < k) + hi++; + *outHigh = hi; + return lo; +#endif + } + + static const size_t kBitCount = 3328; // 64bit * 54 > 10^1000 + static const size_t kCapacity = kBitCount / sizeof(Type); + static const size_t kTypeBit = sizeof(Type) * 8; + + Type digits_[kCapacity]; + size_t count_; +}; + +} // namespace internal +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_BIGINTEGER_H_ diff --git a/slsReceiverSoftware/include/rapidjson/internal/diyfp.h b/slsReceiverSoftware/include/rapidjson/internal/diyfp.h new file mode 100644 index 000000000..c9fefdc61 --- /dev/null +++ b/slsReceiverSoftware/include/rapidjson/internal/diyfp.h @@ -0,0 +1,258 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +// This is a C++ header-only implementation of Grisu2 algorithm from the publication: +// Loitsch, Florian. "Printing floating-point numbers quickly and accurately with +// integers." ACM Sigplan Notices 45.6 (2010): 233-243. + +#ifndef RAPIDJSON_DIYFP_H_ +#define RAPIDJSON_DIYFP_H_ + +#include "../rapidjson.h" + +#if defined(_MSC_VER) && defined(_M_AMD64) +#include +#pragma intrinsic(_BitScanReverse64) +#pragma intrinsic(_umul128) +#endif + +RAPIDJSON_NAMESPACE_BEGIN +namespace internal { + +#ifdef __GNUC__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(effc++) +#endif + +#ifdef __clang__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(padded) +#endif + +struct DiyFp { + DiyFp() : f(), e() {} + + DiyFp(uint64_t fp, int exp) : f(fp), e(exp) {} + + explicit DiyFp(double d) { + union { + double d; + uint64_t u64; + } u = { d }; + + int biased_e = static_cast((u.u64 & kDpExponentMask) >> kDpSignificandSize); + uint64_t significand = (u.u64 & kDpSignificandMask); + if (biased_e != 0) { + f = significand + kDpHiddenBit; + e = biased_e - kDpExponentBias; + } + else { + f = significand; + e = kDpMinExponent + 1; + } + } + + DiyFp operator-(const DiyFp& rhs) const { + return DiyFp(f - rhs.f, e); + } + + DiyFp operator*(const DiyFp& rhs) const { +#if defined(_MSC_VER) && defined(_M_AMD64) + uint64_t h; + uint64_t l = _umul128(f, rhs.f, &h); + if (l & (uint64_t(1) << 63)) // rounding + h++; + return DiyFp(h, e + rhs.e + 64); +#elif (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) && defined(__x86_64__) + __extension__ typedef unsigned __int128 uint128; + uint128 p = static_cast(f) * static_cast(rhs.f); + uint64_t h = static_cast(p >> 64); + uint64_t l = static_cast(p); + if (l & (uint64_t(1) << 63)) // rounding + h++; + return DiyFp(h, e + rhs.e + 64); +#else + const uint64_t M32 = 0xFFFFFFFF; + const uint64_t a = f >> 32; + const uint64_t b = f & M32; + const uint64_t c = rhs.f >> 32; + const uint64_t d = rhs.f & M32; + const uint64_t ac = a * c; + const uint64_t bc = b * c; + const uint64_t ad = a * d; + const uint64_t bd = b * d; + uint64_t tmp = (bd >> 32) + (ad & M32) + (bc & M32); + tmp += 1U << 31; /// mult_round + return DiyFp(ac + (ad >> 32) + (bc >> 32) + (tmp >> 32), e + rhs.e + 64); +#endif + } + + DiyFp Normalize() const { +#if defined(_MSC_VER) && defined(_M_AMD64) + unsigned long index; + _BitScanReverse64(&index, f); + return DiyFp(f << (63 - index), e - (63 - index)); +#elif defined(__GNUC__) && __GNUC__ >= 4 + int s = __builtin_clzll(f); + return DiyFp(f << s, e - s); +#else + DiyFp res = *this; + while (!(res.f & (static_cast(1) << 63))) { + res.f <<= 1; + res.e--; + } + return res; +#endif + } + + DiyFp NormalizeBoundary() const { + DiyFp res = *this; + while (!(res.f & (kDpHiddenBit << 1))) { + res.f <<= 1; + res.e--; + } + res.f <<= (kDiySignificandSize - kDpSignificandSize - 2); + res.e = res.e - (kDiySignificandSize - kDpSignificandSize - 2); + return res; + } + + void NormalizedBoundaries(DiyFp* minus, DiyFp* plus) const { + DiyFp pl = DiyFp((f << 1) + 1, e - 1).NormalizeBoundary(); + DiyFp mi = (f == kDpHiddenBit) ? DiyFp((f << 2) - 1, e - 2) : DiyFp((f << 1) - 1, e - 1); + mi.f <<= mi.e - pl.e; + mi.e = pl.e; + *plus = pl; + *minus = mi; + } + + double ToDouble() const { + union { + double d; + uint64_t u64; + }u; + const uint64_t be = (e == kDpDenormalExponent && (f & kDpHiddenBit) == 0) ? 0 : + static_cast(e + kDpExponentBias); + u.u64 = (f & kDpSignificandMask) | (be << kDpSignificandSize); + return u.d; + } + + static const int kDiySignificandSize = 64; + static const int kDpSignificandSize = 52; + static const int kDpExponentBias = 0x3FF + kDpSignificandSize; + static const int kDpMaxExponent = 0x7FF - kDpExponentBias; + static const int kDpMinExponent = -kDpExponentBias; + static const int kDpDenormalExponent = -kDpExponentBias + 1; + static const uint64_t kDpExponentMask = RAPIDJSON_UINT64_C2(0x7FF00000, 0x00000000); + static const uint64_t kDpSignificandMask = RAPIDJSON_UINT64_C2(0x000FFFFF, 0xFFFFFFFF); + static const uint64_t kDpHiddenBit = RAPIDJSON_UINT64_C2(0x00100000, 0x00000000); + + uint64_t f; + int e; +}; + +inline DiyFp GetCachedPowerByIndex(size_t index) { + // 10^-348, 10^-340, ..., 10^340 + static const uint64_t kCachedPowers_F[] = { + RAPIDJSON_UINT64_C2(0xfa8fd5a0, 0x081c0288), RAPIDJSON_UINT64_C2(0xbaaee17f, 0xa23ebf76), + RAPIDJSON_UINT64_C2(0x8b16fb20, 0x3055ac76), RAPIDJSON_UINT64_C2(0xcf42894a, 0x5dce35ea), + RAPIDJSON_UINT64_C2(0x9a6bb0aa, 0x55653b2d), RAPIDJSON_UINT64_C2(0xe61acf03, 0x3d1a45df), + RAPIDJSON_UINT64_C2(0xab70fe17, 0xc79ac6ca), RAPIDJSON_UINT64_C2(0xff77b1fc, 0xbebcdc4f), + RAPIDJSON_UINT64_C2(0xbe5691ef, 0x416bd60c), RAPIDJSON_UINT64_C2(0x8dd01fad, 0x907ffc3c), + RAPIDJSON_UINT64_C2(0xd3515c28, 0x31559a83), RAPIDJSON_UINT64_C2(0x9d71ac8f, 0xada6c9b5), + RAPIDJSON_UINT64_C2(0xea9c2277, 0x23ee8bcb), RAPIDJSON_UINT64_C2(0xaecc4991, 0x4078536d), + RAPIDJSON_UINT64_C2(0x823c1279, 0x5db6ce57), RAPIDJSON_UINT64_C2(0xc2109436, 0x4dfb5637), + RAPIDJSON_UINT64_C2(0x9096ea6f, 0x3848984f), RAPIDJSON_UINT64_C2(0xd77485cb, 0x25823ac7), + RAPIDJSON_UINT64_C2(0xa086cfcd, 0x97bf97f4), RAPIDJSON_UINT64_C2(0xef340a98, 0x172aace5), + RAPIDJSON_UINT64_C2(0xb23867fb, 0x2a35b28e), RAPIDJSON_UINT64_C2(0x84c8d4df, 0xd2c63f3b), + RAPIDJSON_UINT64_C2(0xc5dd4427, 0x1ad3cdba), RAPIDJSON_UINT64_C2(0x936b9fce, 0xbb25c996), + RAPIDJSON_UINT64_C2(0xdbac6c24, 0x7d62a584), RAPIDJSON_UINT64_C2(0xa3ab6658, 0x0d5fdaf6), + RAPIDJSON_UINT64_C2(0xf3e2f893, 0xdec3f126), RAPIDJSON_UINT64_C2(0xb5b5ada8, 0xaaff80b8), + RAPIDJSON_UINT64_C2(0x87625f05, 0x6c7c4a8b), RAPIDJSON_UINT64_C2(0xc9bcff60, 0x34c13053), + RAPIDJSON_UINT64_C2(0x964e858c, 0x91ba2655), RAPIDJSON_UINT64_C2(0xdff97724, 0x70297ebd), + RAPIDJSON_UINT64_C2(0xa6dfbd9f, 0xb8e5b88f), RAPIDJSON_UINT64_C2(0xf8a95fcf, 0x88747d94), + RAPIDJSON_UINT64_C2(0xb9447093, 0x8fa89bcf), RAPIDJSON_UINT64_C2(0x8a08f0f8, 0xbf0f156b), + RAPIDJSON_UINT64_C2(0xcdb02555, 0x653131b6), RAPIDJSON_UINT64_C2(0x993fe2c6, 0xd07b7fac), + RAPIDJSON_UINT64_C2(0xe45c10c4, 0x2a2b3b06), RAPIDJSON_UINT64_C2(0xaa242499, 0x697392d3), + RAPIDJSON_UINT64_C2(0xfd87b5f2, 0x8300ca0e), RAPIDJSON_UINT64_C2(0xbce50864, 0x92111aeb), + RAPIDJSON_UINT64_C2(0x8cbccc09, 0x6f5088cc), RAPIDJSON_UINT64_C2(0xd1b71758, 0xe219652c), + RAPIDJSON_UINT64_C2(0x9c400000, 0x00000000), RAPIDJSON_UINT64_C2(0xe8d4a510, 0x00000000), + RAPIDJSON_UINT64_C2(0xad78ebc5, 0xac620000), RAPIDJSON_UINT64_C2(0x813f3978, 0xf8940984), + RAPIDJSON_UINT64_C2(0xc097ce7b, 0xc90715b3), RAPIDJSON_UINT64_C2(0x8f7e32ce, 0x7bea5c70), + RAPIDJSON_UINT64_C2(0xd5d238a4, 0xabe98068), RAPIDJSON_UINT64_C2(0x9f4f2726, 0x179a2245), + RAPIDJSON_UINT64_C2(0xed63a231, 0xd4c4fb27), RAPIDJSON_UINT64_C2(0xb0de6538, 0x8cc8ada8), + RAPIDJSON_UINT64_C2(0x83c7088e, 0x1aab65db), RAPIDJSON_UINT64_C2(0xc45d1df9, 0x42711d9a), + RAPIDJSON_UINT64_C2(0x924d692c, 0xa61be758), RAPIDJSON_UINT64_C2(0xda01ee64, 0x1a708dea), + RAPIDJSON_UINT64_C2(0xa26da399, 0x9aef774a), RAPIDJSON_UINT64_C2(0xf209787b, 0xb47d6b85), + RAPIDJSON_UINT64_C2(0xb454e4a1, 0x79dd1877), RAPIDJSON_UINT64_C2(0x865b8692, 0x5b9bc5c2), + RAPIDJSON_UINT64_C2(0xc83553c5, 0xc8965d3d), RAPIDJSON_UINT64_C2(0x952ab45c, 0xfa97a0b3), + RAPIDJSON_UINT64_C2(0xde469fbd, 0x99a05fe3), RAPIDJSON_UINT64_C2(0xa59bc234, 0xdb398c25), + RAPIDJSON_UINT64_C2(0xf6c69a72, 0xa3989f5c), RAPIDJSON_UINT64_C2(0xb7dcbf53, 0x54e9bece), + RAPIDJSON_UINT64_C2(0x88fcf317, 0xf22241e2), RAPIDJSON_UINT64_C2(0xcc20ce9b, 0xd35c78a5), + RAPIDJSON_UINT64_C2(0x98165af3, 0x7b2153df), RAPIDJSON_UINT64_C2(0xe2a0b5dc, 0x971f303a), + RAPIDJSON_UINT64_C2(0xa8d9d153, 0x5ce3b396), RAPIDJSON_UINT64_C2(0xfb9b7cd9, 0xa4a7443c), + RAPIDJSON_UINT64_C2(0xbb764c4c, 0xa7a44410), RAPIDJSON_UINT64_C2(0x8bab8eef, 0xb6409c1a), + RAPIDJSON_UINT64_C2(0xd01fef10, 0xa657842c), RAPIDJSON_UINT64_C2(0x9b10a4e5, 0xe9913129), + RAPIDJSON_UINT64_C2(0xe7109bfb, 0xa19c0c9d), RAPIDJSON_UINT64_C2(0xac2820d9, 0x623bf429), + RAPIDJSON_UINT64_C2(0x80444b5e, 0x7aa7cf85), RAPIDJSON_UINT64_C2(0xbf21e440, 0x03acdd2d), + RAPIDJSON_UINT64_C2(0x8e679c2f, 0x5e44ff8f), RAPIDJSON_UINT64_C2(0xd433179d, 0x9c8cb841), + RAPIDJSON_UINT64_C2(0x9e19db92, 0xb4e31ba9), RAPIDJSON_UINT64_C2(0xeb96bf6e, 0xbadf77d9), + RAPIDJSON_UINT64_C2(0xaf87023b, 0x9bf0ee6b) + }; + static const int16_t kCachedPowers_E[] = { + -1220, -1193, -1166, -1140, -1113, -1087, -1060, -1034, -1007, -980, + -954, -927, -901, -874, -847, -821, -794, -768, -741, -715, + -688, -661, -635, -608, -582, -555, -529, -502, -475, -449, + -422, -396, -369, -343, -316, -289, -263, -236, -210, -183, + -157, -130, -103, -77, -50, -24, 3, 30, 56, 83, + 109, 136, 162, 189, 216, 242, 269, 295, 322, 348, + 375, 402, 428, 455, 481, 508, 534, 561, 588, 614, + 641, 667, 694, 720, 747, 774, 800, 827, 853, 880, + 907, 933, 960, 986, 1013, 1039, 1066 + }; + return DiyFp(kCachedPowers_F[index], kCachedPowers_E[index]); +} + +inline DiyFp GetCachedPower(int e, int* K) { + + //int k = static_cast(ceil((-61 - e) * 0.30102999566398114)) + 374; + double dk = (-61 - e) * 0.30102999566398114 + 347; // dk must be positive, so can do ceiling in positive + int k = static_cast(dk); + if (dk - k > 0.0) + k++; + + unsigned index = static_cast((k >> 3) + 1); + *K = -(-348 + static_cast(index << 3)); // decimal exponent no need lookup table + + return GetCachedPowerByIndex(index); +} + +inline DiyFp GetCachedPower10(int exp, int *outExp) { + unsigned index = (static_cast(exp) + 348u) / 8u; + *outExp = -348 + static_cast(index) * 8; + return GetCachedPowerByIndex(index); + } + +#ifdef __GNUC__ +RAPIDJSON_DIAG_POP +#endif + +#ifdef __clang__ +RAPIDJSON_DIAG_POP +RAPIDJSON_DIAG_OFF(padded) +#endif + +} // namespace internal +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_DIYFP_H_ diff --git a/slsReceiverSoftware/include/rapidjson/internal/dtoa.h b/slsReceiverSoftware/include/rapidjson/internal/dtoa.h new file mode 100644 index 000000000..8d6350e62 --- /dev/null +++ b/slsReceiverSoftware/include/rapidjson/internal/dtoa.h @@ -0,0 +1,245 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +// This is a C++ header-only implementation of Grisu2 algorithm from the publication: +// Loitsch, Florian. "Printing floating-point numbers quickly and accurately with +// integers." ACM Sigplan Notices 45.6 (2010): 233-243. + +#ifndef RAPIDJSON_DTOA_ +#define RAPIDJSON_DTOA_ + +#include "itoa.h" // GetDigitsLut() +#include "diyfp.h" +#include "ieee754.h" + +RAPIDJSON_NAMESPACE_BEGIN +namespace internal { + +#ifdef __GNUC__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(effc++) +RAPIDJSON_DIAG_OFF(array-bounds) // some gcc versions generate wrong warnings https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59124 +#endif + +inline void GrisuRound(char* buffer, int len, uint64_t delta, uint64_t rest, uint64_t ten_kappa, uint64_t wp_w) { + while (rest < wp_w && delta - rest >= ten_kappa && + (rest + ten_kappa < wp_w || /// closer + wp_w - rest > rest + ten_kappa - wp_w)) { + buffer[len - 1]--; + rest += ten_kappa; + } +} + +inline unsigned CountDecimalDigit32(uint32_t n) { + // Simple pure C++ implementation was faster than __builtin_clz version in this situation. + if (n < 10) return 1; + if (n < 100) return 2; + if (n < 1000) return 3; + if (n < 10000) return 4; + if (n < 100000) return 5; + if (n < 1000000) return 6; + if (n < 10000000) return 7; + if (n < 100000000) return 8; + // Will not reach 10 digits in DigitGen() + //if (n < 1000000000) return 9; + //return 10; + return 9; +} + +inline void DigitGen(const DiyFp& W, const DiyFp& Mp, uint64_t delta, char* buffer, int* len, int* K) { + static const uint32_t kPow10[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 }; + const DiyFp one(uint64_t(1) << -Mp.e, Mp.e); + const DiyFp wp_w = Mp - W; + uint32_t p1 = static_cast(Mp.f >> -one.e); + uint64_t p2 = Mp.f & (one.f - 1); + unsigned kappa = CountDecimalDigit32(p1); // kappa in [0, 9] + *len = 0; + + while (kappa > 0) { + uint32_t d = 0; + switch (kappa) { + case 9: d = p1 / 100000000; p1 %= 100000000; break; + case 8: d = p1 / 10000000; p1 %= 10000000; break; + case 7: d = p1 / 1000000; p1 %= 1000000; break; + case 6: d = p1 / 100000; p1 %= 100000; break; + case 5: d = p1 / 10000; p1 %= 10000; break; + case 4: d = p1 / 1000; p1 %= 1000; break; + case 3: d = p1 / 100; p1 %= 100; break; + case 2: d = p1 / 10; p1 %= 10; break; + case 1: d = p1; p1 = 0; break; + default:; + } + if (d || *len) + buffer[(*len)++] = static_cast('0' + static_cast(d)); + kappa--; + uint64_t tmp = (static_cast(p1) << -one.e) + p2; + if (tmp <= delta) { + *K += kappa; + GrisuRound(buffer, *len, delta, tmp, static_cast(kPow10[kappa]) << -one.e, wp_w.f); + return; + } + } + + // kappa = 0 + for (;;) { + p2 *= 10; + delta *= 10; + char d = static_cast(p2 >> -one.e); + if (d || *len) + buffer[(*len)++] = static_cast('0' + d); + p2 &= one.f - 1; + kappa--; + if (p2 < delta) { + *K += kappa; + int index = -static_cast(kappa); + GrisuRound(buffer, *len, delta, p2, one.f, wp_w.f * (index < 9 ? kPow10[-static_cast(kappa)] : 0)); + return; + } + } +} + +inline void Grisu2(double value, char* buffer, int* length, int* K) { + const DiyFp v(value); + DiyFp w_m, w_p; + v.NormalizedBoundaries(&w_m, &w_p); + + const DiyFp c_mk = GetCachedPower(w_p.e, K); + const DiyFp W = v.Normalize() * c_mk; + DiyFp Wp = w_p * c_mk; + DiyFp Wm = w_m * c_mk; + Wm.f++; + Wp.f--; + DigitGen(W, Wp, Wp.f - Wm.f, buffer, length, K); +} + +inline char* WriteExponent(int K, char* buffer) { + if (K < 0) { + *buffer++ = '-'; + K = -K; + } + + if (K >= 100) { + *buffer++ = static_cast('0' + static_cast(K / 100)); + K %= 100; + const char* d = GetDigitsLut() + K * 2; + *buffer++ = d[0]; + *buffer++ = d[1]; + } + else if (K >= 10) { + const char* d = GetDigitsLut() + K * 2; + *buffer++ = d[0]; + *buffer++ = d[1]; + } + else + *buffer++ = static_cast('0' + static_cast(K)); + + return buffer; +} + +inline char* Prettify(char* buffer, int length, int k, int maxDecimalPlaces) { + const int kk = length + k; // 10^(kk-1) <= v < 10^kk + + if (0 <= k && kk <= 21) { + // 1234e7 -> 12340000000 + for (int i = length; i < kk; i++) + buffer[i] = '0'; + buffer[kk] = '.'; + buffer[kk + 1] = '0'; + return &buffer[kk + 2]; + } + else if (0 < kk && kk <= 21) { + // 1234e-2 -> 12.34 + std::memmove(&buffer[kk + 1], &buffer[kk], static_cast(length - kk)); + buffer[kk] = '.'; + if (0 > k + maxDecimalPlaces) { + // When maxDecimalPlaces = 2, 1.2345 -> 1.23, 1.102 -> 1.1 + // Remove extra trailing zeros (at least one) after truncation. + for (int i = kk + maxDecimalPlaces; i > kk + 1; i--) + if (buffer[i] != '0') + return &buffer[i + 1]; + return &buffer[kk + 2]; // Reserve one zero + } + else + return &buffer[length + 1]; + } + else if (-6 < kk && kk <= 0) { + // 1234e-6 -> 0.001234 + const int offset = 2 - kk; + std::memmove(&buffer[offset], &buffer[0], static_cast(length)); + buffer[0] = '0'; + buffer[1] = '.'; + for (int i = 2; i < offset; i++) + buffer[i] = '0'; + if (length - kk > maxDecimalPlaces) { + // When maxDecimalPlaces = 2, 0.123 -> 0.12, 0.102 -> 0.1 + // Remove extra trailing zeros (at least one) after truncation. + for (int i = maxDecimalPlaces + 1; i > 2; i--) + if (buffer[i] != '0') + return &buffer[i + 1]; + return &buffer[3]; // Reserve one zero + } + else + return &buffer[length + offset]; + } + else if (kk < -maxDecimalPlaces) { + // Truncate to zero + buffer[0] = '0'; + buffer[1] = '.'; + buffer[2] = '0'; + return &buffer[3]; + } + else if (length == 1) { + // 1e30 + buffer[1] = 'e'; + return WriteExponent(kk - 1, &buffer[2]); + } + else { + // 1234e30 -> 1.234e33 + std::memmove(&buffer[2], &buffer[1], static_cast(length - 1)); + buffer[1] = '.'; + buffer[length + 1] = 'e'; + return WriteExponent(kk - 1, &buffer[0 + length + 2]); + } +} + +inline char* dtoa(double value, char* buffer, int maxDecimalPlaces = 324) { + RAPIDJSON_ASSERT(maxDecimalPlaces >= 1); + Double d(value); + if (d.IsZero()) { + if (d.Sign()) + *buffer++ = '-'; // -0.0, Issue #289 + buffer[0] = '0'; + buffer[1] = '.'; + buffer[2] = '0'; + return &buffer[3]; + } + else { + if (value < 0) { + *buffer++ = '-'; + value = -value; + } + int length, K; + Grisu2(value, buffer, &length, &K); + return Prettify(buffer, length, K, maxDecimalPlaces); + } +} + +#ifdef __GNUC__ +RAPIDJSON_DIAG_POP +#endif + +} // namespace internal +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_DTOA_ diff --git a/slsReceiverSoftware/include/rapidjson/internal/ieee754.h b/slsReceiverSoftware/include/rapidjson/internal/ieee754.h new file mode 100644 index 000000000..82bb0b99e --- /dev/null +++ b/slsReceiverSoftware/include/rapidjson/internal/ieee754.h @@ -0,0 +1,78 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_IEEE754_ +#define RAPIDJSON_IEEE754_ + +#include "../rapidjson.h" + +RAPIDJSON_NAMESPACE_BEGIN +namespace internal { + +class Double { +public: + Double() {} + Double(double d) : d_(d) {} + Double(uint64_t u) : u_(u) {} + + double Value() const { return d_; } + uint64_t Uint64Value() const { return u_; } + + double NextPositiveDouble() const { + RAPIDJSON_ASSERT(!Sign()); + return Double(u_ + 1).Value(); + } + + bool Sign() const { return (u_ & kSignMask) != 0; } + uint64_t Significand() const { return u_ & kSignificandMask; } + int Exponent() const { return static_cast(((u_ & kExponentMask) >> kSignificandSize) - kExponentBias); } + + bool IsNan() const { return (u_ & kExponentMask) == kExponentMask && Significand() != 0; } + bool IsInf() const { return (u_ & kExponentMask) == kExponentMask && Significand() == 0; } + bool IsNanOrInf() const { return (u_ & kExponentMask) == kExponentMask; } + bool IsNormal() const { return (u_ & kExponentMask) != 0 || Significand() == 0; } + bool IsZero() const { return (u_ & (kExponentMask | kSignificandMask)) == 0; } + + uint64_t IntegerSignificand() const { return IsNormal() ? Significand() | kHiddenBit : Significand(); } + int IntegerExponent() const { return (IsNormal() ? Exponent() : kDenormalExponent) - kSignificandSize; } + uint64_t ToBias() const { return (u_ & kSignMask) ? ~u_ + 1 : u_ | kSignMask; } + + static unsigned EffectiveSignificandSize(int order) { + if (order >= -1021) + return 53; + else if (order <= -1074) + return 0; + else + return static_cast(order) + 1074; + } + +private: + static const int kSignificandSize = 52; + static const int kExponentBias = 0x3FF; + static const int kDenormalExponent = 1 - kExponentBias; + static const uint64_t kSignMask = RAPIDJSON_UINT64_C2(0x80000000, 0x00000000); + static const uint64_t kExponentMask = RAPIDJSON_UINT64_C2(0x7FF00000, 0x00000000); + static const uint64_t kSignificandMask = RAPIDJSON_UINT64_C2(0x000FFFFF, 0xFFFFFFFF); + static const uint64_t kHiddenBit = RAPIDJSON_UINT64_C2(0x00100000, 0x00000000); + + union { + double d_; + uint64_t u_; + }; +}; + +} // namespace internal +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_IEEE754_ diff --git a/slsReceiverSoftware/include/rapidjson/internal/itoa.h b/slsReceiverSoftware/include/rapidjson/internal/itoa.h new file mode 100644 index 000000000..01a4e7e72 --- /dev/null +++ b/slsReceiverSoftware/include/rapidjson/internal/itoa.h @@ -0,0 +1,304 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_ITOA_ +#define RAPIDJSON_ITOA_ + +#include "../rapidjson.h" + +RAPIDJSON_NAMESPACE_BEGIN +namespace internal { + +inline const char* GetDigitsLut() { + static const char cDigitsLut[200] = { + '0','0','0','1','0','2','0','3','0','4','0','5','0','6','0','7','0','8','0','9', + '1','0','1','1','1','2','1','3','1','4','1','5','1','6','1','7','1','8','1','9', + '2','0','2','1','2','2','2','3','2','4','2','5','2','6','2','7','2','8','2','9', + '3','0','3','1','3','2','3','3','3','4','3','5','3','6','3','7','3','8','3','9', + '4','0','4','1','4','2','4','3','4','4','4','5','4','6','4','7','4','8','4','9', + '5','0','5','1','5','2','5','3','5','4','5','5','5','6','5','7','5','8','5','9', + '6','0','6','1','6','2','6','3','6','4','6','5','6','6','6','7','6','8','6','9', + '7','0','7','1','7','2','7','3','7','4','7','5','7','6','7','7','7','8','7','9', + '8','0','8','1','8','2','8','3','8','4','8','5','8','6','8','7','8','8','8','9', + '9','0','9','1','9','2','9','3','9','4','9','5','9','6','9','7','9','8','9','9' + }; + return cDigitsLut; +} + +inline char* u32toa(uint32_t value, char* buffer) { + const char* cDigitsLut = GetDigitsLut(); + + if (value < 10000) { + const uint32_t d1 = (value / 100) << 1; + const uint32_t d2 = (value % 100) << 1; + + if (value >= 1000) + *buffer++ = cDigitsLut[d1]; + if (value >= 100) + *buffer++ = cDigitsLut[d1 + 1]; + if (value >= 10) + *buffer++ = cDigitsLut[d2]; + *buffer++ = cDigitsLut[d2 + 1]; + } + else if (value < 100000000) { + // value = bbbbcccc + const uint32_t b = value / 10000; + const uint32_t c = value % 10000; + + const uint32_t d1 = (b / 100) << 1; + const uint32_t d2 = (b % 100) << 1; + + const uint32_t d3 = (c / 100) << 1; + const uint32_t d4 = (c % 100) << 1; + + if (value >= 10000000) + *buffer++ = cDigitsLut[d1]; + if (value >= 1000000) + *buffer++ = cDigitsLut[d1 + 1]; + if (value >= 100000) + *buffer++ = cDigitsLut[d2]; + *buffer++ = cDigitsLut[d2 + 1]; + + *buffer++ = cDigitsLut[d3]; + *buffer++ = cDigitsLut[d3 + 1]; + *buffer++ = cDigitsLut[d4]; + *buffer++ = cDigitsLut[d4 + 1]; + } + else { + // value = aabbbbcccc in decimal + + const uint32_t a = value / 100000000; // 1 to 42 + value %= 100000000; + + if (a >= 10) { + const unsigned i = a << 1; + *buffer++ = cDigitsLut[i]; + *buffer++ = cDigitsLut[i + 1]; + } + else + *buffer++ = static_cast('0' + static_cast(a)); + + const uint32_t b = value / 10000; // 0 to 9999 + const uint32_t c = value % 10000; // 0 to 9999 + + const uint32_t d1 = (b / 100) << 1; + const uint32_t d2 = (b % 100) << 1; + + const uint32_t d3 = (c / 100) << 1; + const uint32_t d4 = (c % 100) << 1; + + *buffer++ = cDigitsLut[d1]; + *buffer++ = cDigitsLut[d1 + 1]; + *buffer++ = cDigitsLut[d2]; + *buffer++ = cDigitsLut[d2 + 1]; + *buffer++ = cDigitsLut[d3]; + *buffer++ = cDigitsLut[d3 + 1]; + *buffer++ = cDigitsLut[d4]; + *buffer++ = cDigitsLut[d4 + 1]; + } + return buffer; +} + +inline char* i32toa(int32_t value, char* buffer) { + uint32_t u = static_cast(value); + if (value < 0) { + *buffer++ = '-'; + u = ~u + 1; + } + + return u32toa(u, buffer); +} + +inline char* u64toa(uint64_t value, char* buffer) { + const char* cDigitsLut = GetDigitsLut(); + const uint64_t kTen8 = 100000000; + const uint64_t kTen9 = kTen8 * 10; + const uint64_t kTen10 = kTen8 * 100; + const uint64_t kTen11 = kTen8 * 1000; + const uint64_t kTen12 = kTen8 * 10000; + const uint64_t kTen13 = kTen8 * 100000; + const uint64_t kTen14 = kTen8 * 1000000; + const uint64_t kTen15 = kTen8 * 10000000; + const uint64_t kTen16 = kTen8 * kTen8; + + if (value < kTen8) { + uint32_t v = static_cast(value); + if (v < 10000) { + const uint32_t d1 = (v / 100) << 1; + const uint32_t d2 = (v % 100) << 1; + + if (v >= 1000) + *buffer++ = cDigitsLut[d1]; + if (v >= 100) + *buffer++ = cDigitsLut[d1 + 1]; + if (v >= 10) + *buffer++ = cDigitsLut[d2]; + *buffer++ = cDigitsLut[d2 + 1]; + } + else { + // value = bbbbcccc + const uint32_t b = v / 10000; + const uint32_t c = v % 10000; + + const uint32_t d1 = (b / 100) << 1; + const uint32_t d2 = (b % 100) << 1; + + const uint32_t d3 = (c / 100) << 1; + const uint32_t d4 = (c % 100) << 1; + + if (value >= 10000000) + *buffer++ = cDigitsLut[d1]; + if (value >= 1000000) + *buffer++ = cDigitsLut[d1 + 1]; + if (value >= 100000) + *buffer++ = cDigitsLut[d2]; + *buffer++ = cDigitsLut[d2 + 1]; + + *buffer++ = cDigitsLut[d3]; + *buffer++ = cDigitsLut[d3 + 1]; + *buffer++ = cDigitsLut[d4]; + *buffer++ = cDigitsLut[d4 + 1]; + } + } + else if (value < kTen16) { + const uint32_t v0 = static_cast(value / kTen8); + const uint32_t v1 = static_cast(value % kTen8); + + const uint32_t b0 = v0 / 10000; + const uint32_t c0 = v0 % 10000; + + const uint32_t d1 = (b0 / 100) << 1; + const uint32_t d2 = (b0 % 100) << 1; + + const uint32_t d3 = (c0 / 100) << 1; + const uint32_t d4 = (c0 % 100) << 1; + + const uint32_t b1 = v1 / 10000; + const uint32_t c1 = v1 % 10000; + + const uint32_t d5 = (b1 / 100) << 1; + const uint32_t d6 = (b1 % 100) << 1; + + const uint32_t d7 = (c1 / 100) << 1; + const uint32_t d8 = (c1 % 100) << 1; + + if (value >= kTen15) + *buffer++ = cDigitsLut[d1]; + if (value >= kTen14) + *buffer++ = cDigitsLut[d1 + 1]; + if (value >= kTen13) + *buffer++ = cDigitsLut[d2]; + if (value >= kTen12) + *buffer++ = cDigitsLut[d2 + 1]; + if (value >= kTen11) + *buffer++ = cDigitsLut[d3]; + if (value >= kTen10) + *buffer++ = cDigitsLut[d3 + 1]; + if (value >= kTen9) + *buffer++ = cDigitsLut[d4]; + if (value >= kTen8) + *buffer++ = cDigitsLut[d4 + 1]; + + *buffer++ = cDigitsLut[d5]; + *buffer++ = cDigitsLut[d5 + 1]; + *buffer++ = cDigitsLut[d6]; + *buffer++ = cDigitsLut[d6 + 1]; + *buffer++ = cDigitsLut[d7]; + *buffer++ = cDigitsLut[d7 + 1]; + *buffer++ = cDigitsLut[d8]; + *buffer++ = cDigitsLut[d8 + 1]; + } + else { + const uint32_t a = static_cast(value / kTen16); // 1 to 1844 + value %= kTen16; + + if (a < 10) + *buffer++ = static_cast('0' + static_cast(a)); + else if (a < 100) { + const uint32_t i = a << 1; + *buffer++ = cDigitsLut[i]; + *buffer++ = cDigitsLut[i + 1]; + } + else if (a < 1000) { + *buffer++ = static_cast('0' + static_cast(a / 100)); + + const uint32_t i = (a % 100) << 1; + *buffer++ = cDigitsLut[i]; + *buffer++ = cDigitsLut[i + 1]; + } + else { + const uint32_t i = (a / 100) << 1; + const uint32_t j = (a % 100) << 1; + *buffer++ = cDigitsLut[i]; + *buffer++ = cDigitsLut[i + 1]; + *buffer++ = cDigitsLut[j]; + *buffer++ = cDigitsLut[j + 1]; + } + + const uint32_t v0 = static_cast(value / kTen8); + const uint32_t v1 = static_cast(value % kTen8); + + const uint32_t b0 = v0 / 10000; + const uint32_t c0 = v0 % 10000; + + const uint32_t d1 = (b0 / 100) << 1; + const uint32_t d2 = (b0 % 100) << 1; + + const uint32_t d3 = (c0 / 100) << 1; + const uint32_t d4 = (c0 % 100) << 1; + + const uint32_t b1 = v1 / 10000; + const uint32_t c1 = v1 % 10000; + + const uint32_t d5 = (b1 / 100) << 1; + const uint32_t d6 = (b1 % 100) << 1; + + const uint32_t d7 = (c1 / 100) << 1; + const uint32_t d8 = (c1 % 100) << 1; + + *buffer++ = cDigitsLut[d1]; + *buffer++ = cDigitsLut[d1 + 1]; + *buffer++ = cDigitsLut[d2]; + *buffer++ = cDigitsLut[d2 + 1]; + *buffer++ = cDigitsLut[d3]; + *buffer++ = cDigitsLut[d3 + 1]; + *buffer++ = cDigitsLut[d4]; + *buffer++ = cDigitsLut[d4 + 1]; + *buffer++ = cDigitsLut[d5]; + *buffer++ = cDigitsLut[d5 + 1]; + *buffer++ = cDigitsLut[d6]; + *buffer++ = cDigitsLut[d6 + 1]; + *buffer++ = cDigitsLut[d7]; + *buffer++ = cDigitsLut[d7 + 1]; + *buffer++ = cDigitsLut[d8]; + *buffer++ = cDigitsLut[d8 + 1]; + } + + return buffer; +} + +inline char* i64toa(int64_t value, char* buffer) { + uint64_t u = static_cast(value); + if (value < 0) { + *buffer++ = '-'; + u = ~u + 1; + } + + return u64toa(u, buffer); +} + +} // namespace internal +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_ITOA_ diff --git a/slsReceiverSoftware/include/rapidjson/internal/meta.h b/slsReceiverSoftware/include/rapidjson/internal/meta.h new file mode 100644 index 000000000..5a9aaa428 --- /dev/null +++ b/slsReceiverSoftware/include/rapidjson/internal/meta.h @@ -0,0 +1,181 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_INTERNAL_META_H_ +#define RAPIDJSON_INTERNAL_META_H_ + +#include "../rapidjson.h" + +#ifdef __GNUC__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(effc++) +#endif +#if defined(_MSC_VER) +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(6334) +#endif + +#if RAPIDJSON_HAS_CXX11_TYPETRAITS +#include +#endif + +//@cond RAPIDJSON_INTERNAL +RAPIDJSON_NAMESPACE_BEGIN +namespace internal { + +// Helper to wrap/convert arbitrary types to void, useful for arbitrary type matching +template struct Void { typedef void Type; }; + +/////////////////////////////////////////////////////////////////////////////// +// BoolType, TrueType, FalseType +// +template struct BoolType { + static const bool Value = Cond; + typedef BoolType Type; +}; +typedef BoolType TrueType; +typedef BoolType FalseType; + + +/////////////////////////////////////////////////////////////////////////////// +// SelectIf, BoolExpr, NotExpr, AndExpr, OrExpr +// + +template struct SelectIfImpl { template struct Apply { typedef T1 Type; }; }; +template <> struct SelectIfImpl { template struct Apply { typedef T2 Type; }; }; +template struct SelectIfCond : SelectIfImpl::template Apply {}; +template struct SelectIf : SelectIfCond {}; + +template struct AndExprCond : FalseType {}; +template <> struct AndExprCond : TrueType {}; +template struct OrExprCond : TrueType {}; +template <> struct OrExprCond : FalseType {}; + +template struct BoolExpr : SelectIf::Type {}; +template struct NotExpr : SelectIf::Type {}; +template struct AndExpr : AndExprCond::Type {}; +template struct OrExpr : OrExprCond::Type {}; + + +/////////////////////////////////////////////////////////////////////////////// +// AddConst, MaybeAddConst, RemoveConst +template struct AddConst { typedef const T Type; }; +template struct MaybeAddConst : SelectIfCond {}; +template struct RemoveConst { typedef T Type; }; +template struct RemoveConst { typedef T Type; }; + + +/////////////////////////////////////////////////////////////////////////////// +// IsSame, IsConst, IsMoreConst, IsPointer +// +template struct IsSame : FalseType {}; +template struct IsSame : TrueType {}; + +template struct IsConst : FalseType {}; +template struct IsConst : TrueType {}; + +template +struct IsMoreConst + : AndExpr::Type, typename RemoveConst::Type>, + BoolType::Value >= IsConst::Value> >::Type {}; + +template struct IsPointer : FalseType {}; +template struct IsPointer : TrueType {}; + +/////////////////////////////////////////////////////////////////////////////// +// IsBaseOf +// +#if RAPIDJSON_HAS_CXX11_TYPETRAITS + +template struct IsBaseOf + : BoolType< ::std::is_base_of::value> {}; + +#else // simplified version adopted from Boost + +template struct IsBaseOfImpl { + RAPIDJSON_STATIC_ASSERT(sizeof(B) != 0); + RAPIDJSON_STATIC_ASSERT(sizeof(D) != 0); + + typedef char (&Yes)[1]; + typedef char (&No) [2]; + + template + static Yes Check(const D*, T); + static No Check(const B*, int); + + struct Host { + operator const B*() const; + operator const D*(); + }; + + enum { Value = (sizeof(Check(Host(), 0)) == sizeof(Yes)) }; +}; + +template struct IsBaseOf + : OrExpr, BoolExpr > >::Type {}; + +#endif // RAPIDJSON_HAS_CXX11_TYPETRAITS + + +////////////////////////////////////////////////////////////////////////// +// EnableIf / DisableIf +// +template struct EnableIfCond { typedef T Type; }; +template struct EnableIfCond { /* empty */ }; + +template struct DisableIfCond { typedef T Type; }; +template struct DisableIfCond { /* empty */ }; + +template +struct EnableIf : EnableIfCond {}; + +template +struct DisableIf : DisableIfCond {}; + +// SFINAE helpers +struct SfinaeTag {}; +template struct RemoveSfinaeTag; +template struct RemoveSfinaeTag { typedef T Type; }; + +#define RAPIDJSON_REMOVEFPTR_(type) \ + typename ::RAPIDJSON_NAMESPACE::internal::RemoveSfinaeTag \ + < ::RAPIDJSON_NAMESPACE::internal::SfinaeTag&(*) type>::Type + +#define RAPIDJSON_ENABLEIF(cond) \ + typename ::RAPIDJSON_NAMESPACE::internal::EnableIf \ + ::Type * = NULL + +#define RAPIDJSON_DISABLEIF(cond) \ + typename ::RAPIDJSON_NAMESPACE::internal::DisableIf \ + ::Type * = NULL + +#define RAPIDJSON_ENABLEIF_RETURN(cond,returntype) \ + typename ::RAPIDJSON_NAMESPACE::internal::EnableIf \ + ::Type + +#define RAPIDJSON_DISABLEIF_RETURN(cond,returntype) \ + typename ::RAPIDJSON_NAMESPACE::internal::DisableIf \ + ::Type + +} // namespace internal +RAPIDJSON_NAMESPACE_END +//@endcond + +#if defined(__GNUC__) || defined(_MSC_VER) +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_INTERNAL_META_H_ diff --git a/slsReceiverSoftware/include/rapidjson/internal/pow10.h b/slsReceiverSoftware/include/rapidjson/internal/pow10.h new file mode 100644 index 000000000..02f475d70 --- /dev/null +++ b/slsReceiverSoftware/include/rapidjson/internal/pow10.h @@ -0,0 +1,55 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_POW10_ +#define RAPIDJSON_POW10_ + +#include "../rapidjson.h" + +RAPIDJSON_NAMESPACE_BEGIN +namespace internal { + +//! Computes integer powers of 10 in double (10.0^n). +/*! This function uses lookup table for fast and accurate results. + \param n non-negative exponent. Must <= 308. + \return 10.0^n +*/ +inline double Pow10(int n) { + static const double e[] = { // 1e-0...1e308: 309 * 8 bytes = 2472 bytes + 1e+0, + 1e+1, 1e+2, 1e+3, 1e+4, 1e+5, 1e+6, 1e+7, 1e+8, 1e+9, 1e+10, 1e+11, 1e+12, 1e+13, 1e+14, 1e+15, 1e+16, 1e+17, 1e+18, 1e+19, 1e+20, + 1e+21, 1e+22, 1e+23, 1e+24, 1e+25, 1e+26, 1e+27, 1e+28, 1e+29, 1e+30, 1e+31, 1e+32, 1e+33, 1e+34, 1e+35, 1e+36, 1e+37, 1e+38, 1e+39, 1e+40, + 1e+41, 1e+42, 1e+43, 1e+44, 1e+45, 1e+46, 1e+47, 1e+48, 1e+49, 1e+50, 1e+51, 1e+52, 1e+53, 1e+54, 1e+55, 1e+56, 1e+57, 1e+58, 1e+59, 1e+60, + 1e+61, 1e+62, 1e+63, 1e+64, 1e+65, 1e+66, 1e+67, 1e+68, 1e+69, 1e+70, 1e+71, 1e+72, 1e+73, 1e+74, 1e+75, 1e+76, 1e+77, 1e+78, 1e+79, 1e+80, + 1e+81, 1e+82, 1e+83, 1e+84, 1e+85, 1e+86, 1e+87, 1e+88, 1e+89, 1e+90, 1e+91, 1e+92, 1e+93, 1e+94, 1e+95, 1e+96, 1e+97, 1e+98, 1e+99, 1e+100, + 1e+101,1e+102,1e+103,1e+104,1e+105,1e+106,1e+107,1e+108,1e+109,1e+110,1e+111,1e+112,1e+113,1e+114,1e+115,1e+116,1e+117,1e+118,1e+119,1e+120, + 1e+121,1e+122,1e+123,1e+124,1e+125,1e+126,1e+127,1e+128,1e+129,1e+130,1e+131,1e+132,1e+133,1e+134,1e+135,1e+136,1e+137,1e+138,1e+139,1e+140, + 1e+141,1e+142,1e+143,1e+144,1e+145,1e+146,1e+147,1e+148,1e+149,1e+150,1e+151,1e+152,1e+153,1e+154,1e+155,1e+156,1e+157,1e+158,1e+159,1e+160, + 1e+161,1e+162,1e+163,1e+164,1e+165,1e+166,1e+167,1e+168,1e+169,1e+170,1e+171,1e+172,1e+173,1e+174,1e+175,1e+176,1e+177,1e+178,1e+179,1e+180, + 1e+181,1e+182,1e+183,1e+184,1e+185,1e+186,1e+187,1e+188,1e+189,1e+190,1e+191,1e+192,1e+193,1e+194,1e+195,1e+196,1e+197,1e+198,1e+199,1e+200, + 1e+201,1e+202,1e+203,1e+204,1e+205,1e+206,1e+207,1e+208,1e+209,1e+210,1e+211,1e+212,1e+213,1e+214,1e+215,1e+216,1e+217,1e+218,1e+219,1e+220, + 1e+221,1e+222,1e+223,1e+224,1e+225,1e+226,1e+227,1e+228,1e+229,1e+230,1e+231,1e+232,1e+233,1e+234,1e+235,1e+236,1e+237,1e+238,1e+239,1e+240, + 1e+241,1e+242,1e+243,1e+244,1e+245,1e+246,1e+247,1e+248,1e+249,1e+250,1e+251,1e+252,1e+253,1e+254,1e+255,1e+256,1e+257,1e+258,1e+259,1e+260, + 1e+261,1e+262,1e+263,1e+264,1e+265,1e+266,1e+267,1e+268,1e+269,1e+270,1e+271,1e+272,1e+273,1e+274,1e+275,1e+276,1e+277,1e+278,1e+279,1e+280, + 1e+281,1e+282,1e+283,1e+284,1e+285,1e+286,1e+287,1e+288,1e+289,1e+290,1e+291,1e+292,1e+293,1e+294,1e+295,1e+296,1e+297,1e+298,1e+299,1e+300, + 1e+301,1e+302,1e+303,1e+304,1e+305,1e+306,1e+307,1e+308 + }; + RAPIDJSON_ASSERT(n >= 0 && n <= 308); + return e[n]; +} + +} // namespace internal +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_POW10_ diff --git a/slsReceiverSoftware/include/rapidjson/internal/regex.h b/slsReceiverSoftware/include/rapidjson/internal/regex.h new file mode 100644 index 000000000..422a5240b --- /dev/null +++ b/slsReceiverSoftware/include/rapidjson/internal/regex.h @@ -0,0 +1,701 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_INTERNAL_REGEX_H_ +#define RAPIDJSON_INTERNAL_REGEX_H_ + +#include "../allocators.h" +#include "../stream.h" +#include "stack.h" + +#ifdef __clang__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(padded) +RAPIDJSON_DIAG_OFF(switch-enum) +RAPIDJSON_DIAG_OFF(implicit-fallthrough) +#endif + +#ifdef __GNUC__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(effc++) +#endif + +#ifdef _MSC_VER +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated +#endif + +#ifndef RAPIDJSON_REGEX_VERBOSE +#define RAPIDJSON_REGEX_VERBOSE 0 +#endif + +RAPIDJSON_NAMESPACE_BEGIN +namespace internal { + +/////////////////////////////////////////////////////////////////////////////// +// GenericRegex + +static const SizeType kRegexInvalidState = ~SizeType(0); //!< Represents an invalid index in GenericRegex::State::out, out1 +static const SizeType kRegexInvalidRange = ~SizeType(0); + +//! Regular expression engine with subset of ECMAscript grammar. +/*! + Supported regular expression syntax: + - \c ab Concatenation + - \c a|b Alternation + - \c a? Zero or one + - \c a* Zero or more + - \c a+ One or more + - \c a{3} Exactly 3 times + - \c a{3,} At least 3 times + - \c a{3,5} 3 to 5 times + - \c (ab) Grouping + - \c ^a At the beginning + - \c a$ At the end + - \c . Any character + - \c [abc] Character classes + - \c [a-c] Character class range + - \c [a-z0-9_] Character class combination + - \c [^abc] Negated character classes + - \c [^a-c] Negated character class range + - \c [\b] Backspace (U+0008) + - \c \\| \\\\ ... Escape characters + - \c \\f Form feed (U+000C) + - \c \\n Line feed (U+000A) + - \c \\r Carriage return (U+000D) + - \c \\t Tab (U+0009) + - \c \\v Vertical tab (U+000B) + + \note This is a Thompson NFA engine, implemented with reference to + Cox, Russ. "Regular Expression Matching Can Be Simple And Fast (but is slow in Java, Perl, PHP, Python, Ruby,...).", + https://swtch.com/~rsc/regexp/regexp1.html +*/ +template +class GenericRegex { +public: + typedef typename Encoding::Ch Ch; + + GenericRegex(const Ch* source, Allocator* allocator = 0) : + states_(allocator, 256), ranges_(allocator, 256), root_(kRegexInvalidState), stateCount_(), rangeCount_(), + stateSet_(), state0_(allocator, 0), state1_(allocator, 0), anchorBegin_(), anchorEnd_() + { + GenericStringStream ss(source); + DecodedStream > ds(ss); + Parse(ds); + } + + ~GenericRegex() { + Allocator::Free(stateSet_); + } + + bool IsValid() const { + return root_ != kRegexInvalidState; + } + + template + bool Match(InputStream& is) const { + return SearchWithAnchoring(is, true, true); + } + + bool Match(const Ch* s) const { + GenericStringStream is(s); + return Match(is); + } + + template + bool Search(InputStream& is) const { + return SearchWithAnchoring(is, anchorBegin_, anchorEnd_); + } + + bool Search(const Ch* s) const { + GenericStringStream is(s); + return Search(is); + } + +private: + enum Operator { + kZeroOrOne, + kZeroOrMore, + kOneOrMore, + kConcatenation, + kAlternation, + kLeftParenthesis + }; + + static const unsigned kAnyCharacterClass = 0xFFFFFFFF; //!< For '.' + static const unsigned kRangeCharacterClass = 0xFFFFFFFE; + static const unsigned kRangeNegationFlag = 0x80000000; + + struct Range { + unsigned start; // + unsigned end; + SizeType next; + }; + + struct State { + SizeType out; //!< Equals to kInvalid for matching state + SizeType out1; //!< Equals to non-kInvalid for split + SizeType rangeStart; + unsigned codepoint; + }; + + struct Frag { + Frag(SizeType s, SizeType o, SizeType m) : start(s), out(o), minIndex(m) {} + SizeType start; + SizeType out; //!< link-list of all output states + SizeType minIndex; + }; + + template + class DecodedStream { + public: + DecodedStream(SourceStream& ss) : ss_(ss), codepoint_() { Decode(); } + unsigned Peek() { return codepoint_; } + unsigned Take() { + unsigned c = codepoint_; + if (c) // No further decoding when '\0' + Decode(); + return c; + } + + private: + void Decode() { + if (!Encoding::Decode(ss_, &codepoint_)) + codepoint_ = 0; + } + + SourceStream& ss_; + unsigned codepoint_; + }; + + State& GetState(SizeType index) { + RAPIDJSON_ASSERT(index < stateCount_); + return states_.template Bottom()[index]; + } + + const State& GetState(SizeType index) const { + RAPIDJSON_ASSERT(index < stateCount_); + return states_.template Bottom()[index]; + } + + Range& GetRange(SizeType index) { + RAPIDJSON_ASSERT(index < rangeCount_); + return ranges_.template Bottom()[index]; + } + + const Range& GetRange(SizeType index) const { + RAPIDJSON_ASSERT(index < rangeCount_); + return ranges_.template Bottom()[index]; + } + + template + void Parse(DecodedStream& ds) { + Allocator allocator; + Stack operandStack(&allocator, 256); // Frag + Stack operatorStack(&allocator, 256); // Operator + Stack atomCountStack(&allocator, 256); // unsigned (Atom per parenthesis) + + *atomCountStack.template Push() = 0; + + unsigned codepoint; + while (ds.Peek() != 0) { + switch (codepoint = ds.Take()) { + case '^': + anchorBegin_ = true; + break; + + case '$': + anchorEnd_ = true; + break; + + case '|': + while (!operatorStack.Empty() && *operatorStack.template Top() < kAlternation) + if (!Eval(operandStack, *operatorStack.template Pop(1))) + return; + *operatorStack.template Push() = kAlternation; + *atomCountStack.template Top() = 0; + break; + + case '(': + *operatorStack.template Push() = kLeftParenthesis; + *atomCountStack.template Push() = 0; + break; + + case ')': + while (!operatorStack.Empty() && *operatorStack.template Top() != kLeftParenthesis) + if (!Eval(operandStack, *operatorStack.template Pop(1))) + return; + if (operatorStack.Empty()) + return; + operatorStack.template Pop(1); + atomCountStack.template Pop(1); + ImplicitConcatenation(atomCountStack, operatorStack); + break; + + case '?': + if (!Eval(operandStack, kZeroOrOne)) + return; + break; + + case '*': + if (!Eval(operandStack, kZeroOrMore)) + return; + break; + + case '+': + if (!Eval(operandStack, kOneOrMore)) + return; + break; + + case '{': + { + unsigned n, m; + if (!ParseUnsigned(ds, &n)) + return; + + if (ds.Peek() == ',') { + ds.Take(); + if (ds.Peek() == '}') + m = kInfinityQuantifier; + else if (!ParseUnsigned(ds, &m) || m < n) + return; + } + else + m = n; + + if (!EvalQuantifier(operandStack, n, m) || ds.Peek() != '}') + return; + ds.Take(); + } + break; + + case '.': + PushOperand(operandStack, kAnyCharacterClass); + ImplicitConcatenation(atomCountStack, operatorStack); + break; + + case '[': + { + SizeType range; + if (!ParseRange(ds, &range)) + return; + SizeType s = NewState(kRegexInvalidState, kRegexInvalidState, kRangeCharacterClass); + GetState(s).rangeStart = range; + *operandStack.template Push() = Frag(s, s, s); + } + ImplicitConcatenation(atomCountStack, operatorStack); + break; + + case '\\': // Escape character + if (!CharacterEscape(ds, &codepoint)) + return; // Unsupported escape character + // fall through to default + + default: // Pattern character + PushOperand(operandStack, codepoint); + ImplicitConcatenation(atomCountStack, operatorStack); + } + } + + while (!operatorStack.Empty()) + if (!Eval(operandStack, *operatorStack.template Pop(1))) + return; + + // Link the operand to matching state. + if (operandStack.GetSize() == sizeof(Frag)) { + Frag* e = operandStack.template Pop(1); + Patch(e->out, NewState(kRegexInvalidState, kRegexInvalidState, 0)); + root_ = e->start; + +#if RAPIDJSON_REGEX_VERBOSE + printf("root: %d\n", root_); + for (SizeType i = 0; i < stateCount_ ; i++) { + State& s = GetState(i); + printf("[%2d] out: %2d out1: %2d c: '%c'\n", i, s.out, s.out1, (char)s.codepoint); + } + printf("\n"); +#endif + } + + // Preallocate buffer for SearchWithAnchoring() + RAPIDJSON_ASSERT(stateSet_ == 0); + if (stateCount_ > 0) { + stateSet_ = static_cast(states_.GetAllocator().Malloc(GetStateSetSize())); + state0_.template Reserve(stateCount_); + state1_.template Reserve(stateCount_); + } + } + + SizeType NewState(SizeType out, SizeType out1, unsigned codepoint) { + State* s = states_.template Push(); + s->out = out; + s->out1 = out1; + s->codepoint = codepoint; + s->rangeStart = kRegexInvalidRange; + return stateCount_++; + } + + void PushOperand(Stack& operandStack, unsigned codepoint) { + SizeType s = NewState(kRegexInvalidState, kRegexInvalidState, codepoint); + *operandStack.template Push() = Frag(s, s, s); + } + + void ImplicitConcatenation(Stack& atomCountStack, Stack& operatorStack) { + if (*atomCountStack.template Top()) + *operatorStack.template Push() = kConcatenation; + (*atomCountStack.template Top())++; + } + + SizeType Append(SizeType l1, SizeType l2) { + SizeType old = l1; + while (GetState(l1).out != kRegexInvalidState) + l1 = GetState(l1).out; + GetState(l1).out = l2; + return old; + } + + void Patch(SizeType l, SizeType s) { + for (SizeType next; l != kRegexInvalidState; l = next) { + next = GetState(l).out; + GetState(l).out = s; + } + } + + bool Eval(Stack& operandStack, Operator op) { + switch (op) { + case kConcatenation: + RAPIDJSON_ASSERT(operandStack.GetSize() >= sizeof(Frag) * 2); + { + Frag e2 = *operandStack.template Pop(1); + Frag e1 = *operandStack.template Pop(1); + Patch(e1.out, e2.start); + *operandStack.template Push() = Frag(e1.start, e2.out, Min(e1.minIndex, e2.minIndex)); + } + return true; + + case kAlternation: + if (operandStack.GetSize() >= sizeof(Frag) * 2) { + Frag e2 = *operandStack.template Pop(1); + Frag e1 = *operandStack.template Pop(1); + SizeType s = NewState(e1.start, e2.start, 0); + *operandStack.template Push() = Frag(s, Append(e1.out, e2.out), Min(e1.minIndex, e2.minIndex)); + return true; + } + return false; + + case kZeroOrOne: + if (operandStack.GetSize() >= sizeof(Frag)) { + Frag e = *operandStack.template Pop(1); + SizeType s = NewState(kRegexInvalidState, e.start, 0); + *operandStack.template Push() = Frag(s, Append(e.out, s), e.minIndex); + return true; + } + return false; + + case kZeroOrMore: + if (operandStack.GetSize() >= sizeof(Frag)) { + Frag e = *operandStack.template Pop(1); + SizeType s = NewState(kRegexInvalidState, e.start, 0); + Patch(e.out, s); + *operandStack.template Push() = Frag(s, s, e.minIndex); + return true; + } + return false; + + default: + RAPIDJSON_ASSERT(op == kOneOrMore); + if (operandStack.GetSize() >= sizeof(Frag)) { + Frag e = *operandStack.template Pop(1); + SizeType s = NewState(kRegexInvalidState, e.start, 0); + Patch(e.out, s); + *operandStack.template Push() = Frag(e.start, s, e.minIndex); + return true; + } + return false; + } + } + + bool EvalQuantifier(Stack& operandStack, unsigned n, unsigned m) { + RAPIDJSON_ASSERT(n <= m); + RAPIDJSON_ASSERT(operandStack.GetSize() >= sizeof(Frag)); + + if (n == 0) { + if (m == 0) // a{0} not support + return false; + else if (m == kInfinityQuantifier) + Eval(operandStack, kZeroOrMore); // a{0,} -> a* + else { + Eval(operandStack, kZeroOrOne); // a{0,5} -> a? + for (unsigned i = 0; i < m - 1; i++) + CloneTopOperand(operandStack); // a{0,5} -> a? a? a? a? a? + for (unsigned i = 0; i < m - 1; i++) + Eval(operandStack, kConcatenation); // a{0,5} -> a?a?a?a?a? + } + return true; + } + + for (unsigned i = 0; i < n - 1; i++) // a{3} -> a a a + CloneTopOperand(operandStack); + + if (m == kInfinityQuantifier) + Eval(operandStack, kOneOrMore); // a{3,} -> a a a+ + else if (m > n) { + CloneTopOperand(operandStack); // a{3,5} -> a a a a + Eval(operandStack, kZeroOrOne); // a{3,5} -> a a a a? + for (unsigned i = n; i < m - 1; i++) + CloneTopOperand(operandStack); // a{3,5} -> a a a a? a? + for (unsigned i = n; i < m; i++) + Eval(operandStack, kConcatenation); // a{3,5} -> a a aa?a? + } + + for (unsigned i = 0; i < n - 1; i++) + Eval(operandStack, kConcatenation); // a{3} -> aaa, a{3,} -> aaa+, a{3.5} -> aaaa?a? + + return true; + } + + static SizeType Min(SizeType a, SizeType b) { return a < b ? a : b; } + + void CloneTopOperand(Stack& operandStack) { + const Frag src = *operandStack.template Top(); // Copy constructor to prevent invalidation + SizeType count = stateCount_ - src.minIndex; // Assumes top operand contains states in [src->minIndex, stateCount_) + State* s = states_.template Push(count); + memcpy(s, &GetState(src.minIndex), count * sizeof(State)); + for (SizeType j = 0; j < count; j++) { + if (s[j].out != kRegexInvalidState) + s[j].out += count; + if (s[j].out1 != kRegexInvalidState) + s[j].out1 += count; + } + *operandStack.template Push() = Frag(src.start + count, src.out + count, src.minIndex + count); + stateCount_ += count; + } + + template + bool ParseUnsigned(DecodedStream& ds, unsigned* u) { + unsigned r = 0; + if (ds.Peek() < '0' || ds.Peek() > '9') + return false; + while (ds.Peek() >= '0' && ds.Peek() <= '9') { + if (r >= 429496729 && ds.Peek() > '5') // 2^32 - 1 = 4294967295 + return false; // overflow + r = r * 10 + (ds.Take() - '0'); + } + *u = r; + return true; + } + + template + bool ParseRange(DecodedStream& ds, SizeType* range) { + bool isBegin = true; + bool negate = false; + int step = 0; + SizeType start = kRegexInvalidRange; + SizeType current = kRegexInvalidRange; + unsigned codepoint; + while ((codepoint = ds.Take()) != 0) { + if (isBegin) { + isBegin = false; + if (codepoint == '^') { + negate = true; + continue; + } + } + + switch (codepoint) { + case ']': + if (start == kRegexInvalidRange) + return false; // Error: nothing inside [] + if (step == 2) { // Add trailing '-' + SizeType r = NewRange('-'); + RAPIDJSON_ASSERT(current != kRegexInvalidRange); + GetRange(current).next = r; + } + if (negate) + GetRange(start).start |= kRangeNegationFlag; + *range = start; + return true; + + case '\\': + if (ds.Peek() == 'b') { + ds.Take(); + codepoint = 0x0008; // Escape backspace character + } + else if (!CharacterEscape(ds, &codepoint)) + return false; + // fall through to default + + default: + switch (step) { + case 1: + if (codepoint == '-') { + step++; + break; + } + // fall through to step 0 for other characters + + case 0: + { + SizeType r = NewRange(codepoint); + if (current != kRegexInvalidRange) + GetRange(current).next = r; + if (start == kRegexInvalidRange) + start = r; + current = r; + } + step = 1; + break; + + default: + RAPIDJSON_ASSERT(step == 2); + GetRange(current).end = codepoint; + step = 0; + } + } + } + return false; + } + + SizeType NewRange(unsigned codepoint) { + Range* r = ranges_.template Push(); + r->start = r->end = codepoint; + r->next = kRegexInvalidRange; + return rangeCount_++; + } + + template + bool CharacterEscape(DecodedStream& ds, unsigned* escapedCodepoint) { + unsigned codepoint; + switch (codepoint = ds.Take()) { + case '^': + case '$': + case '|': + case '(': + case ')': + case '?': + case '*': + case '+': + case '.': + case '[': + case ']': + case '{': + case '}': + case '\\': + *escapedCodepoint = codepoint; return true; + case 'f': *escapedCodepoint = 0x000C; return true; + case 'n': *escapedCodepoint = 0x000A; return true; + case 'r': *escapedCodepoint = 0x000D; return true; + case 't': *escapedCodepoint = 0x0009; return true; + case 'v': *escapedCodepoint = 0x000B; return true; + default: + return false; // Unsupported escape character + } + } + + template + bool SearchWithAnchoring(InputStream& is, bool anchorBegin, bool anchorEnd) const { + RAPIDJSON_ASSERT(IsValid()); + DecodedStream ds(is); + + state0_.Clear(); + Stack *current = &state0_, *next = &state1_; + const size_t stateSetSize = GetStateSetSize(); + std::memset(stateSet_, 0, stateSetSize); + + bool matched = AddState(*current, root_); + unsigned codepoint; + while (!current->Empty() && (codepoint = ds.Take()) != 0) { + std::memset(stateSet_, 0, stateSetSize); + next->Clear(); + matched = false; + for (const SizeType* s = current->template Bottom(); s != current->template End(); ++s) { + const State& sr = GetState(*s); + if (sr.codepoint == codepoint || + sr.codepoint == kAnyCharacterClass || + (sr.codepoint == kRangeCharacterClass && MatchRange(sr.rangeStart, codepoint))) + { + matched = AddState(*next, sr.out) || matched; + if (!anchorEnd && matched) + return true; + } + if (!anchorBegin) + AddState(*next, root_); + } + internal::Swap(current, next); + } + + return matched; + } + + size_t GetStateSetSize() const { + return (stateCount_ + 31) / 32 * 4; + } + + // Return whether the added states is a match state + bool AddState(Stack& l, SizeType index) const { + RAPIDJSON_ASSERT(index != kRegexInvalidState); + + const State& s = GetState(index); + if (s.out1 != kRegexInvalidState) { // Split + bool matched = AddState(l, s.out); + return AddState(l, s.out1) || matched; + } + else if (!(stateSet_[index >> 5] & (1 << (index & 31)))) { + stateSet_[index >> 5] |= (1 << (index & 31)); + *l.template PushUnsafe() = index; + } + return s.out == kRegexInvalidState; // by using PushUnsafe() above, we can ensure s is not validated due to reallocation. + } + + bool MatchRange(SizeType rangeIndex, unsigned codepoint) const { + bool yes = (GetRange(rangeIndex).start & kRangeNegationFlag) == 0; + while (rangeIndex != kRegexInvalidRange) { + const Range& r = GetRange(rangeIndex); + if (codepoint >= (r.start & ~kRangeNegationFlag) && codepoint <= r.end) + return yes; + rangeIndex = r.next; + } + return !yes; + } + + Stack states_; + Stack ranges_; + SizeType root_; + SizeType stateCount_; + SizeType rangeCount_; + + static const unsigned kInfinityQuantifier = ~0u; + + // For SearchWithAnchoring() + uint32_t* stateSet_; // allocated by states_.GetAllocator() + mutable Stack state0_; + mutable Stack state1_; + bool anchorBegin_; + bool anchorEnd_; +}; + +typedef GenericRegex > Regex; + +} // namespace internal +RAPIDJSON_NAMESPACE_END + +#ifdef __clang__ +RAPIDJSON_DIAG_POP +#endif + +#ifdef _MSC_VER +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_INTERNAL_REGEX_H_ diff --git a/slsReceiverSoftware/include/rapidjson/internal/stack.h b/slsReceiverSoftware/include/rapidjson/internal/stack.h new file mode 100644 index 000000000..022c9aab4 --- /dev/null +++ b/slsReceiverSoftware/include/rapidjson/internal/stack.h @@ -0,0 +1,230 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_INTERNAL_STACK_H_ +#define RAPIDJSON_INTERNAL_STACK_H_ + +#include "../allocators.h" +#include "swap.h" + +#if defined(__clang__) +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(c++98-compat) +#endif + +RAPIDJSON_NAMESPACE_BEGIN +namespace internal { + +/////////////////////////////////////////////////////////////////////////////// +// Stack + +//! A type-unsafe stack for storing different types of data. +/*! \tparam Allocator Allocator for allocating stack memory. +*/ +template +class Stack { +public: + // Optimization note: Do not allocate memory for stack_ in constructor. + // Do it lazily when first Push() -> Expand() -> Resize(). + Stack(Allocator* allocator, size_t stackCapacity) : allocator_(allocator), ownAllocator_(0), stack_(0), stackTop_(0), stackEnd_(0), initialCapacity_(stackCapacity) { + } + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + Stack(Stack&& rhs) + : allocator_(rhs.allocator_), + ownAllocator_(rhs.ownAllocator_), + stack_(rhs.stack_), + stackTop_(rhs.stackTop_), + stackEnd_(rhs.stackEnd_), + initialCapacity_(rhs.initialCapacity_) + { + rhs.allocator_ = 0; + rhs.ownAllocator_ = 0; + rhs.stack_ = 0; + rhs.stackTop_ = 0; + rhs.stackEnd_ = 0; + rhs.initialCapacity_ = 0; + } +#endif + + ~Stack() { + Destroy(); + } + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + Stack& operator=(Stack&& rhs) { + if (&rhs != this) + { + Destroy(); + + allocator_ = rhs.allocator_; + ownAllocator_ = rhs.ownAllocator_; + stack_ = rhs.stack_; + stackTop_ = rhs.stackTop_; + stackEnd_ = rhs.stackEnd_; + initialCapacity_ = rhs.initialCapacity_; + + rhs.allocator_ = 0; + rhs.ownAllocator_ = 0; + rhs.stack_ = 0; + rhs.stackTop_ = 0; + rhs.stackEnd_ = 0; + rhs.initialCapacity_ = 0; + } + return *this; + } +#endif + + void Swap(Stack& rhs) RAPIDJSON_NOEXCEPT { + internal::Swap(allocator_, rhs.allocator_); + internal::Swap(ownAllocator_, rhs.ownAllocator_); + internal::Swap(stack_, rhs.stack_); + internal::Swap(stackTop_, rhs.stackTop_); + internal::Swap(stackEnd_, rhs.stackEnd_); + internal::Swap(initialCapacity_, rhs.initialCapacity_); + } + + void Clear() { stackTop_ = stack_; } + + void ShrinkToFit() { + if (Empty()) { + // If the stack is empty, completely deallocate the memory. + Allocator::Free(stack_); + stack_ = 0; + stackTop_ = 0; + stackEnd_ = 0; + } + else + Resize(GetSize()); + } + + // Optimization note: try to minimize the size of this function for force inline. + // Expansion is run very infrequently, so it is moved to another (probably non-inline) function. + template + RAPIDJSON_FORCEINLINE void Reserve(size_t count = 1) { + // Expand the stack if needed + if (RAPIDJSON_UNLIKELY(stackTop_ + sizeof(T) * count > stackEnd_)) + Expand(count); + } + + template + RAPIDJSON_FORCEINLINE T* Push(size_t count = 1) { + Reserve(count); + return PushUnsafe(count); + } + + template + RAPIDJSON_FORCEINLINE T* PushUnsafe(size_t count = 1) { + RAPIDJSON_ASSERT(stackTop_ + sizeof(T) * count <= stackEnd_); + T* ret = reinterpret_cast(stackTop_); + stackTop_ += sizeof(T) * count; + return ret; + } + + template + T* Pop(size_t count) { + RAPIDJSON_ASSERT(GetSize() >= count * sizeof(T)); + stackTop_ -= count * sizeof(T); + return reinterpret_cast(stackTop_); + } + + template + T* Top() { + RAPIDJSON_ASSERT(GetSize() >= sizeof(T)); + return reinterpret_cast(stackTop_ - sizeof(T)); + } + + template + const T* Top() const { + RAPIDJSON_ASSERT(GetSize() >= sizeof(T)); + return reinterpret_cast(stackTop_ - sizeof(T)); + } + + template + T* End() { return reinterpret_cast(stackTop_); } + + template + const T* End() const { return reinterpret_cast(stackTop_); } + + template + T* Bottom() { return reinterpret_cast(stack_); } + + template + const T* Bottom() const { return reinterpret_cast(stack_); } + + bool HasAllocator() const { + return allocator_ != 0; + } + + Allocator& GetAllocator() { + RAPIDJSON_ASSERT(allocator_); + return *allocator_; + } + + bool Empty() const { return stackTop_ == stack_; } + size_t GetSize() const { return static_cast(stackTop_ - stack_); } + size_t GetCapacity() const { return static_cast(stackEnd_ - stack_); } + +private: + template + void Expand(size_t count) { + // Only expand the capacity if the current stack exists. Otherwise just create a stack with initial capacity. + size_t newCapacity; + if (stack_ == 0) { + if (!allocator_) + ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator()); + newCapacity = initialCapacity_; + } else { + newCapacity = GetCapacity(); + newCapacity += (newCapacity + 1) / 2; + } + size_t newSize = GetSize() + sizeof(T) * count; + if (newCapacity < newSize) + newCapacity = newSize; + + Resize(newCapacity); + } + + void Resize(size_t newCapacity) { + const size_t size = GetSize(); // Backup the current size + stack_ = static_cast(allocator_->Realloc(stack_, GetCapacity(), newCapacity)); + stackTop_ = stack_ + size; + stackEnd_ = stack_ + newCapacity; + } + + void Destroy() { + Allocator::Free(stack_); + RAPIDJSON_DELETE(ownAllocator_); // Only delete if it is owned by the stack + } + + // Prohibit copy constructor & assignment operator. + Stack(const Stack&); + Stack& operator=(const Stack&); + + Allocator* allocator_; + Allocator* ownAllocator_; + char *stack_; + char *stackTop_; + char *stackEnd_; + size_t initialCapacity_; +}; + +} // namespace internal +RAPIDJSON_NAMESPACE_END + +#if defined(__clang__) +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_STACK_H_ diff --git a/slsReceiverSoftware/include/rapidjson/internal/strfunc.h b/slsReceiverSoftware/include/rapidjson/internal/strfunc.h new file mode 100644 index 000000000..2edfae526 --- /dev/null +++ b/slsReceiverSoftware/include/rapidjson/internal/strfunc.h @@ -0,0 +1,55 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_INTERNAL_STRFUNC_H_ +#define RAPIDJSON_INTERNAL_STRFUNC_H_ + +#include "../stream.h" + +RAPIDJSON_NAMESPACE_BEGIN +namespace internal { + +//! Custom strlen() which works on different character types. +/*! \tparam Ch Character type (e.g. char, wchar_t, short) + \param s Null-terminated input string. + \return Number of characters in the string. + \note This has the same semantics as strlen(), the return value is not number of Unicode codepoints. +*/ +template +inline SizeType StrLen(const Ch* s) { + const Ch* p = s; + while (*p) ++p; + return SizeType(p - s); +} + +//! Returns number of code points in a encoded string. +template +bool CountStringCodePoint(const typename Encoding::Ch* s, SizeType length, SizeType* outCount) { + GenericStringStream is(s); + const typename Encoding::Ch* end = s + length; + SizeType count = 0; + while (is.src_ < end) { + unsigned codepoint; + if (!Encoding::Decode(is, &codepoint)) + return false; + count++; + } + *outCount = count; + return true; +} + +} // namespace internal +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_INTERNAL_STRFUNC_H_ diff --git a/slsReceiverSoftware/include/rapidjson/internal/strtod.h b/slsReceiverSoftware/include/rapidjson/internal/strtod.h new file mode 100644 index 000000000..289c413b0 --- /dev/null +++ b/slsReceiverSoftware/include/rapidjson/internal/strtod.h @@ -0,0 +1,269 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_STRTOD_ +#define RAPIDJSON_STRTOD_ + +#include "ieee754.h" +#include "biginteger.h" +#include "diyfp.h" +#include "pow10.h" + +RAPIDJSON_NAMESPACE_BEGIN +namespace internal { + +inline double FastPath(double significand, int exp) { + if (exp < -308) + return 0.0; + else if (exp >= 0) + return significand * internal::Pow10(exp); + else + return significand / internal::Pow10(-exp); +} + +inline double StrtodNormalPrecision(double d, int p) { + if (p < -308) { + // Prevent expSum < -308, making Pow10(p) = 0 + d = FastPath(d, -308); + d = FastPath(d, p + 308); + } + else + d = FastPath(d, p); + return d; +} + +template +inline T Min3(T a, T b, T c) { + T m = a; + if (m > b) m = b; + if (m > c) m = c; + return m; +} + +inline int CheckWithinHalfULP(double b, const BigInteger& d, int dExp) { + const Double db(b); + const uint64_t bInt = db.IntegerSignificand(); + const int bExp = db.IntegerExponent(); + const int hExp = bExp - 1; + + int dS_Exp2 = 0, dS_Exp5 = 0, bS_Exp2 = 0, bS_Exp5 = 0, hS_Exp2 = 0, hS_Exp5 = 0; + + // Adjust for decimal exponent + if (dExp >= 0) { + dS_Exp2 += dExp; + dS_Exp5 += dExp; + } + else { + bS_Exp2 -= dExp; + bS_Exp5 -= dExp; + hS_Exp2 -= dExp; + hS_Exp5 -= dExp; + } + + // Adjust for binary exponent + if (bExp >= 0) + bS_Exp2 += bExp; + else { + dS_Exp2 -= bExp; + hS_Exp2 -= bExp; + } + + // Adjust for half ulp exponent + if (hExp >= 0) + hS_Exp2 += hExp; + else { + dS_Exp2 -= hExp; + bS_Exp2 -= hExp; + } + + // Remove common power of two factor from all three scaled values + int common_Exp2 = Min3(dS_Exp2, bS_Exp2, hS_Exp2); + dS_Exp2 -= common_Exp2; + bS_Exp2 -= common_Exp2; + hS_Exp2 -= common_Exp2; + + BigInteger dS = d; + dS.MultiplyPow5(static_cast(dS_Exp5)) <<= static_cast(dS_Exp2); + + BigInteger bS(bInt); + bS.MultiplyPow5(static_cast(bS_Exp5)) <<= static_cast(bS_Exp2); + + BigInteger hS(1); + hS.MultiplyPow5(static_cast(hS_Exp5)) <<= static_cast(hS_Exp2); + + BigInteger delta(0); + dS.Difference(bS, &delta); + + return delta.Compare(hS); +} + +inline bool StrtodFast(double d, int p, double* result) { + // Use fast path for string-to-double conversion if possible + // see http://www.exploringbinary.com/fast-path-decimal-to-floating-point-conversion/ + if (p > 22 && p < 22 + 16) { + // Fast Path Cases In Disguise + d *= internal::Pow10(p - 22); + p = 22; + } + + if (p >= -22 && p <= 22 && d <= 9007199254740991.0) { // 2^53 - 1 + *result = FastPath(d, p); + return true; + } + else + return false; +} + +// Compute an approximation and see if it is within 1/2 ULP +inline bool StrtodDiyFp(const char* decimals, size_t length, size_t decimalPosition, int exp, double* result) { + uint64_t significand = 0; + size_t i = 0; // 2^64 - 1 = 18446744073709551615, 1844674407370955161 = 0x1999999999999999 + for (; i < length; i++) { + if (significand > RAPIDJSON_UINT64_C2(0x19999999, 0x99999999) || + (significand == RAPIDJSON_UINT64_C2(0x19999999, 0x99999999) && decimals[i] > '5')) + break; + significand = significand * 10u + static_cast(decimals[i] - '0'); + } + + if (i < length && decimals[i] >= '5') // Rounding + significand++; + + size_t remaining = length - i; + const unsigned kUlpShift = 3; + const unsigned kUlp = 1 << kUlpShift; + int64_t error = (remaining == 0) ? 0 : kUlp / 2; + + DiyFp v(significand, 0); + v = v.Normalize(); + error <<= -v.e; + + const int dExp = static_cast(decimalPosition) - static_cast(i) + exp; + + int actualExp; + DiyFp cachedPower = GetCachedPower10(dExp, &actualExp); + if (actualExp != dExp) { + static const DiyFp kPow10[] = { + DiyFp(RAPIDJSON_UINT64_C2(0xa0000000, 00000000), -60), // 10^1 + DiyFp(RAPIDJSON_UINT64_C2(0xc8000000, 00000000), -57), // 10^2 + DiyFp(RAPIDJSON_UINT64_C2(0xfa000000, 00000000), -54), // 10^3 + DiyFp(RAPIDJSON_UINT64_C2(0x9c400000, 00000000), -50), // 10^4 + DiyFp(RAPIDJSON_UINT64_C2(0xc3500000, 00000000), -47), // 10^5 + DiyFp(RAPIDJSON_UINT64_C2(0xf4240000, 00000000), -44), // 10^6 + DiyFp(RAPIDJSON_UINT64_C2(0x98968000, 00000000), -40) // 10^7 + }; + int adjustment = dExp - actualExp - 1; + RAPIDJSON_ASSERT(adjustment >= 0 && adjustment < 7); + v = v * kPow10[adjustment]; + if (length + static_cast(adjustment)> 19u) // has more digits than decimal digits in 64-bit + error += kUlp / 2; + } + + v = v * cachedPower; + + error += kUlp + (error == 0 ? 0 : 1); + + const int oldExp = v.e; + v = v.Normalize(); + error <<= oldExp - v.e; + + const unsigned effectiveSignificandSize = Double::EffectiveSignificandSize(64 + v.e); + unsigned precisionSize = 64 - effectiveSignificandSize; + if (precisionSize + kUlpShift >= 64) { + unsigned scaleExp = (precisionSize + kUlpShift) - 63; + v.f >>= scaleExp; + v.e += scaleExp; + error = (error >> scaleExp) + 1 + static_cast(kUlp); + precisionSize -= scaleExp; + } + + DiyFp rounded(v.f >> precisionSize, v.e + static_cast(precisionSize)); + const uint64_t precisionBits = (v.f & ((uint64_t(1) << precisionSize) - 1)) * kUlp; + const uint64_t halfWay = (uint64_t(1) << (precisionSize - 1)) * kUlp; + if (precisionBits >= halfWay + static_cast(error)) { + rounded.f++; + if (rounded.f & (DiyFp::kDpHiddenBit << 1)) { // rounding overflows mantissa (issue #340) + rounded.f >>= 1; + rounded.e++; + } + } + + *result = rounded.ToDouble(); + + return halfWay - static_cast(error) >= precisionBits || precisionBits >= halfWay + static_cast(error); +} + +inline double StrtodBigInteger(double approx, const char* decimals, size_t length, size_t decimalPosition, int exp) { + const BigInteger dInt(decimals, length); + const int dExp = static_cast(decimalPosition) - static_cast(length) + exp; + Double a(approx); + int cmp = CheckWithinHalfULP(a.Value(), dInt, dExp); + if (cmp < 0) + return a.Value(); // within half ULP + else if (cmp == 0) { + // Round towards even + if (a.Significand() & 1) + return a.NextPositiveDouble(); + else + return a.Value(); + } + else // adjustment + return a.NextPositiveDouble(); +} + +inline double StrtodFullPrecision(double d, int p, const char* decimals, size_t length, size_t decimalPosition, int exp) { + RAPIDJSON_ASSERT(d >= 0.0); + RAPIDJSON_ASSERT(length >= 1); + + double result; + if (StrtodFast(d, p, &result)) + return result; + + // Trim leading zeros + while (*decimals == '0' && length > 1) { + length--; + decimals++; + decimalPosition--; + } + + // Trim trailing zeros + while (decimals[length - 1] == '0' && length > 1) { + length--; + decimalPosition--; + exp++; + } + + // Trim right-most digits + const int kMaxDecimalDigit = 780; + if (static_cast(length) > kMaxDecimalDigit) { + int delta = (static_cast(length) - kMaxDecimalDigit); + exp += delta; + decimalPosition -= static_cast(delta); + length = kMaxDecimalDigit; + } + + // If too small, underflow to zero + if (int(length) + exp < -324) + return 0.0; + + if (StrtodDiyFp(decimals, length, decimalPosition, exp, &result)) + return result; + + // Use approximation from StrtodDiyFp and make adjustment with BigInteger comparison + return StrtodBigInteger(result, decimals, length, decimalPosition, exp); +} + +} // namespace internal +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_STRTOD_ diff --git a/slsReceiverSoftware/include/rapidjson/internal/swap.h b/slsReceiverSoftware/include/rapidjson/internal/swap.h new file mode 100644 index 000000000..666e49f97 --- /dev/null +++ b/slsReceiverSoftware/include/rapidjson/internal/swap.h @@ -0,0 +1,46 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_INTERNAL_SWAP_H_ +#define RAPIDJSON_INTERNAL_SWAP_H_ + +#include "../rapidjson.h" + +#if defined(__clang__) +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(c++98-compat) +#endif + +RAPIDJSON_NAMESPACE_BEGIN +namespace internal { + +//! Custom swap() to avoid dependency on C++ header +/*! \tparam T Type of the arguments to swap, should be instantiated with primitive C++ types only. + \note This has the same semantics as std::swap(). +*/ +template +inline void Swap(T& a, T& b) RAPIDJSON_NOEXCEPT { + T tmp = a; + a = b; + b = tmp; +} + +} // namespace internal +RAPIDJSON_NAMESPACE_END + +#if defined(__clang__) +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_INTERNAL_SWAP_H_ diff --git a/slsReceiverSoftware/include/rapidjson/istreamwrapper.h b/slsReceiverSoftware/include/rapidjson/istreamwrapper.h new file mode 100644 index 000000000..f5fe28977 --- /dev/null +++ b/slsReceiverSoftware/include/rapidjson/istreamwrapper.h @@ -0,0 +1,115 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_ISTREAMWRAPPER_H_ +#define RAPIDJSON_ISTREAMWRAPPER_H_ + +#include "stream.h" +#include + +#ifdef __clang__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(padded) +#endif + +#ifdef _MSC_VER +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(4351) // new behavior: elements of array 'array' will be default initialized +#endif + +RAPIDJSON_NAMESPACE_BEGIN + +//! Wrapper of \c std::basic_istream into RapidJSON's Stream concept. +/*! + The classes can be wrapped including but not limited to: + + - \c std::istringstream + - \c std::stringstream + - \c std::wistringstream + - \c std::wstringstream + - \c std::ifstream + - \c std::fstream + - \c std::wifstream + - \c std::wfstream + + \tparam StreamType Class derived from \c std::basic_istream. +*/ + +template +class BasicIStreamWrapper { +public: + typedef typename StreamType::char_type Ch; + BasicIStreamWrapper(StreamType& stream) : stream_(stream), count_(), peekBuffer_() {} + + Ch Peek() const { + typename StreamType::int_type c = stream_.peek(); + return RAPIDJSON_LIKELY(c != StreamType::traits_type::eof()) ? static_cast(c) : '\0'; + } + + Ch Take() { + typename StreamType::int_type c = stream_.get(); + if (RAPIDJSON_LIKELY(c != StreamType::traits_type::eof())) { + count_++; + return static_cast(c); + } + else + return '\0'; + } + + // tellg() may return -1 when failed. So we count by ourself. + size_t Tell() const { return count_; } + + Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } + void Put(Ch) { RAPIDJSON_ASSERT(false); } + void Flush() { RAPIDJSON_ASSERT(false); } + size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } + + // For encoding detection only. + const Ch* Peek4() const { + RAPIDJSON_ASSERT(sizeof(Ch) == 1); // Only usable for byte stream. + int i; + bool hasError = false; + for (i = 0; i < 4; ++i) { + typename StreamType::int_type c = stream_.get(); + if (c == StreamType::traits_type::eof()) { + hasError = true; + stream_.clear(); + break; + } + peekBuffer_[i] = static_cast(c); + } + for (--i; i >= 0; --i) + stream_.putback(peekBuffer_[i]); + return !hasError ? peekBuffer_ : 0; + } + +private: + BasicIStreamWrapper(const BasicIStreamWrapper&); + BasicIStreamWrapper& operator=(const BasicIStreamWrapper&); + + StreamType& stream_; + size_t count_; //!< Number of characters read. Note: + mutable Ch peekBuffer_[4]; +}; + +typedef BasicIStreamWrapper IStreamWrapper; +typedef BasicIStreamWrapper WIStreamWrapper; + +#if defined(__clang__) || defined(_MSC_VER) +RAPIDJSON_DIAG_POP +#endif + +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_ISTREAMWRAPPER_H_ diff --git a/slsReceiverSoftware/include/rapidjson/memorybuffer.h b/slsReceiverSoftware/include/rapidjson/memorybuffer.h new file mode 100644 index 000000000..39bee1dec --- /dev/null +++ b/slsReceiverSoftware/include/rapidjson/memorybuffer.h @@ -0,0 +1,70 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_MEMORYBUFFER_H_ +#define RAPIDJSON_MEMORYBUFFER_H_ + +#include "stream.h" +#include "internal/stack.h" + +RAPIDJSON_NAMESPACE_BEGIN + +//! Represents an in-memory output byte stream. +/*! + This class is mainly for being wrapped by EncodedOutputStream or AutoUTFOutputStream. + + It is similar to FileWriteBuffer but the destination is an in-memory buffer instead of a file. + + Differences between MemoryBuffer and StringBuffer: + 1. StringBuffer has Encoding but MemoryBuffer is only a byte buffer. + 2. StringBuffer::GetString() returns a null-terminated string. MemoryBuffer::GetBuffer() returns a buffer without terminator. + + \tparam Allocator type for allocating memory buffer. + \note implements Stream concept +*/ +template +struct GenericMemoryBuffer { + typedef char Ch; // byte + + GenericMemoryBuffer(Allocator* allocator = 0, size_t capacity = kDefaultCapacity) : stack_(allocator, capacity) {} + + void Put(Ch c) { *stack_.template Push() = c; } + void Flush() {} + + void Clear() { stack_.Clear(); } + void ShrinkToFit() { stack_.ShrinkToFit(); } + Ch* Push(size_t count) { return stack_.template Push(count); } + void Pop(size_t count) { stack_.template Pop(count); } + + const Ch* GetBuffer() const { + return stack_.template Bottom(); + } + + size_t GetSize() const { return stack_.GetSize(); } + + static const size_t kDefaultCapacity = 256; + mutable internal::Stack stack_; +}; + +typedef GenericMemoryBuffer<> MemoryBuffer; + +//! Implement specialized version of PutN() with memset() for better performance. +template<> +inline void PutN(MemoryBuffer& memoryBuffer, char c, size_t n) { + std::memset(memoryBuffer.stack_.Push(n), c, n * sizeof(c)); +} + +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_MEMORYBUFFER_H_ diff --git a/slsReceiverSoftware/include/rapidjson/memorystream.h b/slsReceiverSoftware/include/rapidjson/memorystream.h new file mode 100644 index 000000000..1d71d8a4f --- /dev/null +++ b/slsReceiverSoftware/include/rapidjson/memorystream.h @@ -0,0 +1,71 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_MEMORYSTREAM_H_ +#define RAPIDJSON_MEMORYSTREAM_H_ + +#include "stream.h" + +#ifdef __clang__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(unreachable-code) +RAPIDJSON_DIAG_OFF(missing-noreturn) +#endif + +RAPIDJSON_NAMESPACE_BEGIN + +//! Represents an in-memory input byte stream. +/*! + This class is mainly for being wrapped by EncodedInputStream or AutoUTFInputStream. + + It is similar to FileReadBuffer but the source is an in-memory buffer instead of a file. + + Differences between MemoryStream and StringStream: + 1. StringStream has encoding but MemoryStream is a byte stream. + 2. MemoryStream needs size of the source buffer and the buffer don't need to be null terminated. StringStream assume null-terminated string as source. + 3. MemoryStream supports Peek4() for encoding detection. StringStream is specified with an encoding so it should not have Peek4(). + \note implements Stream concept +*/ +struct MemoryStream { + typedef char Ch; // byte + + MemoryStream(const Ch *src, size_t size) : src_(src), begin_(src), end_(src + size), size_(size) {} + + Ch Peek() const { return RAPIDJSON_UNLIKELY(src_ == end_) ? '\0' : *src_; } + Ch Take() { return RAPIDJSON_UNLIKELY(src_ == end_) ? '\0' : *src_++; } + size_t Tell() const { return static_cast(src_ - begin_); } + + Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } + void Put(Ch) { RAPIDJSON_ASSERT(false); } + void Flush() { RAPIDJSON_ASSERT(false); } + size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } + + // For encoding detection only. + const Ch* Peek4() const { + return Tell() + 4 <= size_ ? src_ : 0; + } + + const Ch* src_; //!< Current read position. + const Ch* begin_; //!< Original head of the string. + const Ch* end_; //!< End of stream. + size_t size_; //!< Size of the stream. +}; + +RAPIDJSON_NAMESPACE_END + +#ifdef __clang__ +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_MEMORYBUFFER_H_ diff --git a/slsReceiverSoftware/include/rapidjson/msinttypes/inttypes.h b/slsReceiverSoftware/include/rapidjson/msinttypes/inttypes.h new file mode 100644 index 000000000..18111286b --- /dev/null +++ b/slsReceiverSoftware/include/rapidjson/msinttypes/inttypes.h @@ -0,0 +1,316 @@ +// ISO C9x compliant inttypes.h for Microsoft Visual Studio +// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 +// +// Copyright (c) 2006-2013 Alexander Chemeris +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the product nor the names of its contributors may +// be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED +// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////////// + +// The above software in this distribution may have been modified by +// THL A29 Limited ("Tencent Modifications"). +// All Tencent Modifications are Copyright (C) 2015 THL A29 Limited. + +#ifndef _MSC_VER // [ +#error "Use this header only with Microsoft Visual C++ compilers!" +#endif // _MSC_VER ] + +#ifndef _MSC_INTTYPES_H_ // [ +#define _MSC_INTTYPES_H_ + +#if _MSC_VER > 1000 +#pragma once +#endif + +#include "stdint.h" + +// miloyip: VC supports inttypes.h since VC2013 +#if _MSC_VER >= 1800 +#include +#else + +// 7.8 Format conversion of integer types + +typedef struct { + intmax_t quot; + intmax_t rem; +} imaxdiv_t; + +// 7.8.1 Macros for format specifiers + +#if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS) // [ See footnote 185 at page 198 + +// The fprintf macros for signed integers are: +#define PRId8 "d" +#define PRIi8 "i" +#define PRIdLEAST8 "d" +#define PRIiLEAST8 "i" +#define PRIdFAST8 "d" +#define PRIiFAST8 "i" + +#define PRId16 "hd" +#define PRIi16 "hi" +#define PRIdLEAST16 "hd" +#define PRIiLEAST16 "hi" +#define PRIdFAST16 "hd" +#define PRIiFAST16 "hi" + +#define PRId32 "I32d" +#define PRIi32 "I32i" +#define PRIdLEAST32 "I32d" +#define PRIiLEAST32 "I32i" +#define PRIdFAST32 "I32d" +#define PRIiFAST32 "I32i" + +#define PRId64 "I64d" +#define PRIi64 "I64i" +#define PRIdLEAST64 "I64d" +#define PRIiLEAST64 "I64i" +#define PRIdFAST64 "I64d" +#define PRIiFAST64 "I64i" + +#define PRIdMAX "I64d" +#define PRIiMAX "I64i" + +#define PRIdPTR "Id" +#define PRIiPTR "Ii" + +// The fprintf macros for unsigned integers are: +#define PRIo8 "o" +#define PRIu8 "u" +#define PRIx8 "x" +#define PRIX8 "X" +#define PRIoLEAST8 "o" +#define PRIuLEAST8 "u" +#define PRIxLEAST8 "x" +#define PRIXLEAST8 "X" +#define PRIoFAST8 "o" +#define PRIuFAST8 "u" +#define PRIxFAST8 "x" +#define PRIXFAST8 "X" + +#define PRIo16 "ho" +#define PRIu16 "hu" +#define PRIx16 "hx" +#define PRIX16 "hX" +#define PRIoLEAST16 "ho" +#define PRIuLEAST16 "hu" +#define PRIxLEAST16 "hx" +#define PRIXLEAST16 "hX" +#define PRIoFAST16 "ho" +#define PRIuFAST16 "hu" +#define PRIxFAST16 "hx" +#define PRIXFAST16 "hX" + +#define PRIo32 "I32o" +#define PRIu32 "I32u" +#define PRIx32 "I32x" +#define PRIX32 "I32X" +#define PRIoLEAST32 "I32o" +#define PRIuLEAST32 "I32u" +#define PRIxLEAST32 "I32x" +#define PRIXLEAST32 "I32X" +#define PRIoFAST32 "I32o" +#define PRIuFAST32 "I32u" +#define PRIxFAST32 "I32x" +#define PRIXFAST32 "I32X" + +#define PRIo64 "I64o" +#define PRIu64 "I64u" +#define PRIx64 "I64x" +#define PRIX64 "I64X" +#define PRIoLEAST64 "I64o" +#define PRIuLEAST64 "I64u" +#define PRIxLEAST64 "I64x" +#define PRIXLEAST64 "I64X" +#define PRIoFAST64 "I64o" +#define PRIuFAST64 "I64u" +#define PRIxFAST64 "I64x" +#define PRIXFAST64 "I64X" + +#define PRIoMAX "I64o" +#define PRIuMAX "I64u" +#define PRIxMAX "I64x" +#define PRIXMAX "I64X" + +#define PRIoPTR "Io" +#define PRIuPTR "Iu" +#define PRIxPTR "Ix" +#define PRIXPTR "IX" + +// The fscanf macros for signed integers are: +#define SCNd8 "d" +#define SCNi8 "i" +#define SCNdLEAST8 "d" +#define SCNiLEAST8 "i" +#define SCNdFAST8 "d" +#define SCNiFAST8 "i" + +#define SCNd16 "hd" +#define SCNi16 "hi" +#define SCNdLEAST16 "hd" +#define SCNiLEAST16 "hi" +#define SCNdFAST16 "hd" +#define SCNiFAST16 "hi" + +#define SCNd32 "ld" +#define SCNi32 "li" +#define SCNdLEAST32 "ld" +#define SCNiLEAST32 "li" +#define SCNdFAST32 "ld" +#define SCNiFAST32 "li" + +#define SCNd64 "I64d" +#define SCNi64 "I64i" +#define SCNdLEAST64 "I64d" +#define SCNiLEAST64 "I64i" +#define SCNdFAST64 "I64d" +#define SCNiFAST64 "I64i" + +#define SCNdMAX "I64d" +#define SCNiMAX "I64i" + +#ifdef _WIN64 // [ +# define SCNdPTR "I64d" +# define SCNiPTR "I64i" +#else // _WIN64 ][ +# define SCNdPTR "ld" +# define SCNiPTR "li" +#endif // _WIN64 ] + +// The fscanf macros for unsigned integers are: +#define SCNo8 "o" +#define SCNu8 "u" +#define SCNx8 "x" +#define SCNX8 "X" +#define SCNoLEAST8 "o" +#define SCNuLEAST8 "u" +#define SCNxLEAST8 "x" +#define SCNXLEAST8 "X" +#define SCNoFAST8 "o" +#define SCNuFAST8 "u" +#define SCNxFAST8 "x" +#define SCNXFAST8 "X" + +#define SCNo16 "ho" +#define SCNu16 "hu" +#define SCNx16 "hx" +#define SCNX16 "hX" +#define SCNoLEAST16 "ho" +#define SCNuLEAST16 "hu" +#define SCNxLEAST16 "hx" +#define SCNXLEAST16 "hX" +#define SCNoFAST16 "ho" +#define SCNuFAST16 "hu" +#define SCNxFAST16 "hx" +#define SCNXFAST16 "hX" + +#define SCNo32 "lo" +#define SCNu32 "lu" +#define SCNx32 "lx" +#define SCNX32 "lX" +#define SCNoLEAST32 "lo" +#define SCNuLEAST32 "lu" +#define SCNxLEAST32 "lx" +#define SCNXLEAST32 "lX" +#define SCNoFAST32 "lo" +#define SCNuFAST32 "lu" +#define SCNxFAST32 "lx" +#define SCNXFAST32 "lX" + +#define SCNo64 "I64o" +#define SCNu64 "I64u" +#define SCNx64 "I64x" +#define SCNX64 "I64X" +#define SCNoLEAST64 "I64o" +#define SCNuLEAST64 "I64u" +#define SCNxLEAST64 "I64x" +#define SCNXLEAST64 "I64X" +#define SCNoFAST64 "I64o" +#define SCNuFAST64 "I64u" +#define SCNxFAST64 "I64x" +#define SCNXFAST64 "I64X" + +#define SCNoMAX "I64o" +#define SCNuMAX "I64u" +#define SCNxMAX "I64x" +#define SCNXMAX "I64X" + +#ifdef _WIN64 // [ +# define SCNoPTR "I64o" +# define SCNuPTR "I64u" +# define SCNxPTR "I64x" +# define SCNXPTR "I64X" +#else // _WIN64 ][ +# define SCNoPTR "lo" +# define SCNuPTR "lu" +# define SCNxPTR "lx" +# define SCNXPTR "lX" +#endif // _WIN64 ] + +#endif // __STDC_FORMAT_MACROS ] + +// 7.8.2 Functions for greatest-width integer types + +// 7.8.2.1 The imaxabs function +#define imaxabs _abs64 + +// 7.8.2.2 The imaxdiv function + +// This is modified version of div() function from Microsoft's div.c found +// in %MSVC.NET%\crt\src\div.c +#ifdef STATIC_IMAXDIV // [ +static +#else // STATIC_IMAXDIV ][ +_inline +#endif // STATIC_IMAXDIV ] +imaxdiv_t __cdecl imaxdiv(intmax_t numer, intmax_t denom) +{ + imaxdiv_t result; + + result.quot = numer / denom; + result.rem = numer % denom; + + if (numer < 0 && result.rem > 0) { + // did division wrong; must fix up + ++result.quot; + result.rem -= denom; + } + + return result; +} + +// 7.8.2.3 The strtoimax and strtoumax functions +#define strtoimax _strtoi64 +#define strtoumax _strtoui64 + +// 7.8.2.4 The wcstoimax and wcstoumax functions +#define wcstoimax _wcstoi64 +#define wcstoumax _wcstoui64 + +#endif // _MSC_VER >= 1800 + +#endif // _MSC_INTTYPES_H_ ] diff --git a/slsReceiverSoftware/include/rapidjson/msinttypes/stdint.h b/slsReceiverSoftware/include/rapidjson/msinttypes/stdint.h new file mode 100644 index 000000000..3d4477b9a --- /dev/null +++ b/slsReceiverSoftware/include/rapidjson/msinttypes/stdint.h @@ -0,0 +1,300 @@ +// ISO C9x compliant stdint.h for Microsoft Visual Studio +// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 +// +// Copyright (c) 2006-2013 Alexander Chemeris +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the product nor the names of its contributors may +// be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED +// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////////// + +// The above software in this distribution may have been modified by +// THL A29 Limited ("Tencent Modifications"). +// All Tencent Modifications are Copyright (C) 2015 THL A29 Limited. + +#ifndef _MSC_VER // [ +#error "Use this header only with Microsoft Visual C++ compilers!" +#endif // _MSC_VER ] + +#ifndef _MSC_STDINT_H_ // [ +#define _MSC_STDINT_H_ + +#if _MSC_VER > 1000 +#pragma once +#endif + +// miloyip: Originally Visual Studio 2010 uses its own stdint.h. However it generates warning with INT64_C(), so change to use this file for vs2010. +#if _MSC_VER >= 1600 // [ +#include + +#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260 + +#undef INT8_C +#undef INT16_C +#undef INT32_C +#undef INT64_C +#undef UINT8_C +#undef UINT16_C +#undef UINT32_C +#undef UINT64_C + +// 7.18.4.1 Macros for minimum-width integer constants + +#define INT8_C(val) val##i8 +#define INT16_C(val) val##i16 +#define INT32_C(val) val##i32 +#define INT64_C(val) val##i64 + +#define UINT8_C(val) val##ui8 +#define UINT16_C(val) val##ui16 +#define UINT32_C(val) val##ui32 +#define UINT64_C(val) val##ui64 + +// 7.18.4.2 Macros for greatest-width integer constants +// These #ifndef's are needed to prevent collisions with . +// Check out Issue 9 for the details. +#ifndef INTMAX_C // [ +# define INTMAX_C INT64_C +#endif // INTMAX_C ] +#ifndef UINTMAX_C // [ +# define UINTMAX_C UINT64_C +#endif // UINTMAX_C ] + +#endif // __STDC_CONSTANT_MACROS ] + +#else // ] _MSC_VER >= 1700 [ + +#include + +// For Visual Studio 6 in C++ mode and for many Visual Studio versions when +// compiling for ARM we have to wrap include with 'extern "C++" {}' +// or compiler would give many errors like this: +// error C2733: second C linkage of overloaded function 'wmemchr' not allowed +#if defined(__cplusplus) && !defined(_M_ARM) +extern "C" { +#endif +# include +#if defined(__cplusplus) && !defined(_M_ARM) +} +#endif + +// Define _W64 macros to mark types changing their size, like intptr_t. +#ifndef _W64 +# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300 +# define _W64 __w64 +# else +# define _W64 +# endif +#endif + + +// 7.18.1 Integer types + +// 7.18.1.1 Exact-width integer types + +// Visual Studio 6 and Embedded Visual C++ 4 doesn't +// realize that, e.g. char has the same size as __int8 +// so we give up on __intX for them. +#if (_MSC_VER < 1300) + typedef signed char int8_t; + typedef signed short int16_t; + typedef signed int int32_t; + typedef unsigned char uint8_t; + typedef unsigned short uint16_t; + typedef unsigned int uint32_t; +#else + typedef signed __int8 int8_t; + typedef signed __int16 int16_t; + typedef signed __int32 int32_t; + typedef unsigned __int8 uint8_t; + typedef unsigned __int16 uint16_t; + typedef unsigned __int32 uint32_t; +#endif +typedef signed __int64 int64_t; +typedef unsigned __int64 uint64_t; + + +// 7.18.1.2 Minimum-width integer types +typedef int8_t int_least8_t; +typedef int16_t int_least16_t; +typedef int32_t int_least32_t; +typedef int64_t int_least64_t; +typedef uint8_t uint_least8_t; +typedef uint16_t uint_least16_t; +typedef uint32_t uint_least32_t; +typedef uint64_t uint_least64_t; + +// 7.18.1.3 Fastest minimum-width integer types +typedef int8_t int_fast8_t; +typedef int16_t int_fast16_t; +typedef int32_t int_fast32_t; +typedef int64_t int_fast64_t; +typedef uint8_t uint_fast8_t; +typedef uint16_t uint_fast16_t; +typedef uint32_t uint_fast32_t; +typedef uint64_t uint_fast64_t; + +// 7.18.1.4 Integer types capable of holding object pointers +#ifdef _WIN64 // [ + typedef signed __int64 intptr_t; + typedef unsigned __int64 uintptr_t; +#else // _WIN64 ][ + typedef _W64 signed int intptr_t; + typedef _W64 unsigned int uintptr_t; +#endif // _WIN64 ] + +// 7.18.1.5 Greatest-width integer types +typedef int64_t intmax_t; +typedef uint64_t uintmax_t; + + +// 7.18.2 Limits of specified-width integer types + +#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259 + +// 7.18.2.1 Limits of exact-width integer types +#define INT8_MIN ((int8_t)_I8_MIN) +#define INT8_MAX _I8_MAX +#define INT16_MIN ((int16_t)_I16_MIN) +#define INT16_MAX _I16_MAX +#define INT32_MIN ((int32_t)_I32_MIN) +#define INT32_MAX _I32_MAX +#define INT64_MIN ((int64_t)_I64_MIN) +#define INT64_MAX _I64_MAX +#define UINT8_MAX _UI8_MAX +#define UINT16_MAX _UI16_MAX +#define UINT32_MAX _UI32_MAX +#define UINT64_MAX _UI64_MAX + +// 7.18.2.2 Limits of minimum-width integer types +#define INT_LEAST8_MIN INT8_MIN +#define INT_LEAST8_MAX INT8_MAX +#define INT_LEAST16_MIN INT16_MIN +#define INT_LEAST16_MAX INT16_MAX +#define INT_LEAST32_MIN INT32_MIN +#define INT_LEAST32_MAX INT32_MAX +#define INT_LEAST64_MIN INT64_MIN +#define INT_LEAST64_MAX INT64_MAX +#define UINT_LEAST8_MAX UINT8_MAX +#define UINT_LEAST16_MAX UINT16_MAX +#define UINT_LEAST32_MAX UINT32_MAX +#define UINT_LEAST64_MAX UINT64_MAX + +// 7.18.2.3 Limits of fastest minimum-width integer types +#define INT_FAST8_MIN INT8_MIN +#define INT_FAST8_MAX INT8_MAX +#define INT_FAST16_MIN INT16_MIN +#define INT_FAST16_MAX INT16_MAX +#define INT_FAST32_MIN INT32_MIN +#define INT_FAST32_MAX INT32_MAX +#define INT_FAST64_MIN INT64_MIN +#define INT_FAST64_MAX INT64_MAX +#define UINT_FAST8_MAX UINT8_MAX +#define UINT_FAST16_MAX UINT16_MAX +#define UINT_FAST32_MAX UINT32_MAX +#define UINT_FAST64_MAX UINT64_MAX + +// 7.18.2.4 Limits of integer types capable of holding object pointers +#ifdef _WIN64 // [ +# define INTPTR_MIN INT64_MIN +# define INTPTR_MAX INT64_MAX +# define UINTPTR_MAX UINT64_MAX +#else // _WIN64 ][ +# define INTPTR_MIN INT32_MIN +# define INTPTR_MAX INT32_MAX +# define UINTPTR_MAX UINT32_MAX +#endif // _WIN64 ] + +// 7.18.2.5 Limits of greatest-width integer types +#define INTMAX_MIN INT64_MIN +#define INTMAX_MAX INT64_MAX +#define UINTMAX_MAX UINT64_MAX + +// 7.18.3 Limits of other integer types + +#ifdef _WIN64 // [ +# define PTRDIFF_MIN _I64_MIN +# define PTRDIFF_MAX _I64_MAX +#else // _WIN64 ][ +# define PTRDIFF_MIN _I32_MIN +# define PTRDIFF_MAX _I32_MAX +#endif // _WIN64 ] + +#define SIG_ATOMIC_MIN INT_MIN +#define SIG_ATOMIC_MAX INT_MAX + +#ifndef SIZE_MAX // [ +# ifdef _WIN64 // [ +# define SIZE_MAX _UI64_MAX +# else // _WIN64 ][ +# define SIZE_MAX _UI32_MAX +# endif // _WIN64 ] +#endif // SIZE_MAX ] + +// WCHAR_MIN and WCHAR_MAX are also defined in +#ifndef WCHAR_MIN // [ +# define WCHAR_MIN 0 +#endif // WCHAR_MIN ] +#ifndef WCHAR_MAX // [ +# define WCHAR_MAX _UI16_MAX +#endif // WCHAR_MAX ] + +#define WINT_MIN 0 +#define WINT_MAX _UI16_MAX + +#endif // __STDC_LIMIT_MACROS ] + + +// 7.18.4 Limits of other integer types + +#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260 + +// 7.18.4.1 Macros for minimum-width integer constants + +#define INT8_C(val) val##i8 +#define INT16_C(val) val##i16 +#define INT32_C(val) val##i32 +#define INT64_C(val) val##i64 + +#define UINT8_C(val) val##ui8 +#define UINT16_C(val) val##ui16 +#define UINT32_C(val) val##ui32 +#define UINT64_C(val) val##ui64 + +// 7.18.4.2 Macros for greatest-width integer constants +// These #ifndef's are needed to prevent collisions with . +// Check out Issue 9 for the details. +#ifndef INTMAX_C // [ +# define INTMAX_C INT64_C +#endif // INTMAX_C ] +#ifndef UINTMAX_C // [ +# define UINTMAX_C UINT64_C +#endif // UINTMAX_C ] + +#endif // __STDC_CONSTANT_MACROS ] + +#endif // _MSC_VER >= 1600 ] + +#endif // _MSC_STDINT_H_ ] diff --git a/slsReceiverSoftware/include/rapidjson/ostreamwrapper.h b/slsReceiverSoftware/include/rapidjson/ostreamwrapper.h new file mode 100644 index 000000000..6f4667c08 --- /dev/null +++ b/slsReceiverSoftware/include/rapidjson/ostreamwrapper.h @@ -0,0 +1,81 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_OSTREAMWRAPPER_H_ +#define RAPIDJSON_OSTREAMWRAPPER_H_ + +#include "stream.h" +#include + +#ifdef __clang__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(padded) +#endif + +RAPIDJSON_NAMESPACE_BEGIN + +//! Wrapper of \c std::basic_ostream into RapidJSON's Stream concept. +/*! + The classes can be wrapped including but not limited to: + + - \c std::ostringstream + - \c std::stringstream + - \c std::wpstringstream + - \c std::wstringstream + - \c std::ifstream + - \c std::fstream + - \c std::wofstream + - \c std::wfstream + + \tparam StreamType Class derived from \c std::basic_ostream. +*/ + +template +class BasicOStreamWrapper { +public: + typedef typename StreamType::char_type Ch; + BasicOStreamWrapper(StreamType& stream) : stream_(stream) {} + + void Put(Ch c) { + stream_.put(c); + } + + void Flush() { + stream_.flush(); + } + + // Not implemented + char Peek() const { RAPIDJSON_ASSERT(false); return 0; } + char Take() { RAPIDJSON_ASSERT(false); return 0; } + size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; } + char* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } + size_t PutEnd(char*) { RAPIDJSON_ASSERT(false); return 0; } + +private: + BasicOStreamWrapper(const BasicOStreamWrapper&); + BasicOStreamWrapper& operator=(const BasicOStreamWrapper&); + + StreamType& stream_; +}; + +typedef BasicOStreamWrapper OStreamWrapper; +typedef BasicOStreamWrapper WOStreamWrapper; + +#ifdef __clang__ +RAPIDJSON_DIAG_POP +#endif + +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_OSTREAMWRAPPER_H_ diff --git a/slsReceiverSoftware/include/rapidjson/pointer.h b/slsReceiverSoftware/include/rapidjson/pointer.h new file mode 100644 index 000000000..0206ac1c8 --- /dev/null +++ b/slsReceiverSoftware/include/rapidjson/pointer.h @@ -0,0 +1,1358 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_POINTER_H_ +#define RAPIDJSON_POINTER_H_ + +#include "document.h" +#include "internal/itoa.h" + +#ifdef __clang__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(switch-enum) +#endif + +#ifdef _MSC_VER +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated +#endif + +RAPIDJSON_NAMESPACE_BEGIN + +static const SizeType kPointerInvalidIndex = ~SizeType(0); //!< Represents an invalid index in GenericPointer::Token + +//! Error code of parsing. +/*! \ingroup RAPIDJSON_ERRORS + \see GenericPointer::GenericPointer, GenericPointer::GetParseErrorCode +*/ +enum PointerParseErrorCode { + kPointerParseErrorNone = 0, //!< The parse is successful + + kPointerParseErrorTokenMustBeginWithSolidus, //!< A token must begin with a '/' + kPointerParseErrorInvalidEscape, //!< Invalid escape + kPointerParseErrorInvalidPercentEncoding, //!< Invalid percent encoding in URI fragment + kPointerParseErrorCharacterMustPercentEncode //!< A character must percent encoded in URI fragment +}; + +/////////////////////////////////////////////////////////////////////////////// +// GenericPointer + +//! Represents a JSON Pointer. Use Pointer for UTF8 encoding and default allocator. +/*! + This class implements RFC 6901 "JavaScript Object Notation (JSON) Pointer" + (https://tools.ietf.org/html/rfc6901). + + A JSON pointer is for identifying a specific value in a JSON document + (GenericDocument). It can simplify coding of DOM tree manipulation, because it + can access multiple-level depth of DOM tree with single API call. + + After it parses a string representation (e.g. "/foo/0" or URI fragment + representation (e.g. "#/foo/0") into its internal representation (tokens), + it can be used to resolve a specific value in multiple documents, or sub-tree + of documents. + + Contrary to GenericValue, Pointer can be copy constructed and copy assigned. + Apart from assignment, a Pointer cannot be modified after construction. + + Although Pointer is very convenient, please aware that constructing Pointer + involves parsing and dynamic memory allocation. A special constructor with user- + supplied tokens eliminates these. + + GenericPointer depends on GenericDocument and GenericValue. + + \tparam ValueType The value type of the DOM tree. E.g. GenericValue > + \tparam Allocator The allocator type for allocating memory for internal representation. + + \note GenericPointer uses same encoding of ValueType. + However, Allocator of GenericPointer is independent of Allocator of Value. +*/ +template +class GenericPointer { +public: + typedef typename ValueType::EncodingType EncodingType; //!< Encoding type from Value + typedef typename ValueType::Ch Ch; //!< Character type from Value + + //! A token is the basic units of internal representation. + /*! + A JSON pointer string representation "/foo/123" is parsed to two tokens: + "foo" and 123. 123 will be represented in both numeric form and string form. + They are resolved according to the actual value type (object or array). + + For token that are not numbers, or the numeric value is out of bound + (greater than limits of SizeType), they are only treated as string form + (i.e. the token's index will be equal to kPointerInvalidIndex). + + This struct is public so that user can create a Pointer without parsing and + allocation, using a special constructor. + */ + struct Token { + const Ch* name; //!< Name of the token. It has null character at the end but it can contain null character. + SizeType length; //!< Length of the name. + SizeType index; //!< A valid array index, if it is not equal to kPointerInvalidIndex. + }; + + //!@name Constructors and destructor. + //@{ + + //! Default constructor. + GenericPointer(Allocator* allocator = 0) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {} + + //! Constructor that parses a string or URI fragment representation. + /*! + \param source A null-terminated, string or URI fragment representation of JSON pointer. + \param allocator User supplied allocator for this pointer. If no allocator is provided, it creates a self-owned one. + */ + explicit GenericPointer(const Ch* source, Allocator* allocator = 0) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) { + Parse(source, internal::StrLen(source)); + } + +#if RAPIDJSON_HAS_STDSTRING + //! Constructor that parses a string or URI fragment representation. + /*! + \param source A string or URI fragment representation of JSON pointer. + \param allocator User supplied allocator for this pointer. If no allocator is provided, it creates a self-owned one. + \note Requires the definition of the preprocessor symbol \ref RAPIDJSON_HAS_STDSTRING. + */ + explicit GenericPointer(const std::basic_string& source, Allocator* allocator = 0) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) { + Parse(source.c_str(), source.size()); + } +#endif + + //! Constructor that parses a string or URI fragment representation, with length of the source string. + /*! + \param source A string or URI fragment representation of JSON pointer. + \param length Length of source. + \param allocator User supplied allocator for this pointer. If no allocator is provided, it creates a self-owned one. + \note Slightly faster than the overload without length. + */ + GenericPointer(const Ch* source, size_t length, Allocator* allocator = 0) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) { + Parse(source, length); + } + + //! Constructor with user-supplied tokens. + /*! + This constructor let user supplies const array of tokens. + This prevents the parsing process and eliminates allocation. + This is preferred for memory constrained environments. + + \param tokens An constant array of tokens representing the JSON pointer. + \param tokenCount Number of tokens. + + \b Example + \code + #define NAME(s) { s, sizeof(s) / sizeof(s[0]) - 1, kPointerInvalidIndex } + #define INDEX(i) { #i, sizeof(#i) - 1, i } + + static const Pointer::Token kTokens[] = { NAME("foo"), INDEX(123) }; + static const Pointer p(kTokens, sizeof(kTokens) / sizeof(kTokens[0])); + // Equivalent to static const Pointer p("/foo/123"); + + #undef NAME + #undef INDEX + \endcode + */ + GenericPointer(const Token* tokens, size_t tokenCount) : allocator_(), ownAllocator_(), nameBuffer_(), tokens_(const_cast(tokens)), tokenCount_(tokenCount), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {} + + //! Copy constructor. + GenericPointer(const GenericPointer& rhs, Allocator* allocator = 0) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) { + *this = rhs; + } + + //! Destructor. + ~GenericPointer() { + if (nameBuffer_) // If user-supplied tokens constructor is used, nameBuffer_ is nullptr and tokens_ are not deallocated. + Allocator::Free(tokens_); + RAPIDJSON_DELETE(ownAllocator_); + } + + //! Assignment operator. + GenericPointer& operator=(const GenericPointer& rhs) { + if (this != &rhs) { + // Do not delete ownAllcator + if (nameBuffer_) + Allocator::Free(tokens_); + + tokenCount_ = rhs.tokenCount_; + parseErrorOffset_ = rhs.parseErrorOffset_; + parseErrorCode_ = rhs.parseErrorCode_; + + if (rhs.nameBuffer_) + CopyFromRaw(rhs); // Normally parsed tokens. + else { + tokens_ = rhs.tokens_; // User supplied const tokens. + nameBuffer_ = 0; + } + } + return *this; + } + + //@} + + //!@name Append token + //@{ + + //! Append a token and return a new Pointer + /*! + \param token Token to be appended. + \param allocator Allocator for the newly return Pointer. + \return A new Pointer with appended token. + */ + GenericPointer Append(const Token& token, Allocator* allocator = 0) const { + GenericPointer r; + r.allocator_ = allocator; + Ch *p = r.CopyFromRaw(*this, 1, token.length + 1); + std::memcpy(p, token.name, (token.length + 1) * sizeof(Ch)); + r.tokens_[tokenCount_].name = p; + r.tokens_[tokenCount_].length = token.length; + r.tokens_[tokenCount_].index = token.index; + return r; + } + + //! Append a name token with length, and return a new Pointer + /*! + \param name Name to be appended. + \param length Length of name. + \param allocator Allocator for the newly return Pointer. + \return A new Pointer with appended token. + */ + GenericPointer Append(const Ch* name, SizeType length, Allocator* allocator = 0) const { + Token token = { name, length, kPointerInvalidIndex }; + return Append(token, allocator); + } + + //! Append a name token without length, and return a new Pointer + /*! + \param name Name (const Ch*) to be appended. + \param allocator Allocator for the newly return Pointer. + \return A new Pointer with appended token. + */ + template + RAPIDJSON_DISABLEIF_RETURN((internal::NotExpr::Type, Ch> >), (GenericPointer)) + Append(T* name, Allocator* allocator = 0) const { + return Append(name, StrLen(name), allocator); + } + +#if RAPIDJSON_HAS_STDSTRING + //! Append a name token, and return a new Pointer + /*! + \param name Name to be appended. + \param allocator Allocator for the newly return Pointer. + \return A new Pointer with appended token. + */ + GenericPointer Append(const std::basic_string& name, Allocator* allocator = 0) const { + return Append(name.c_str(), static_cast(name.size()), allocator); + } +#endif + + //! Append a index token, and return a new Pointer + /*! + \param index Index to be appended. + \param allocator Allocator for the newly return Pointer. + \return A new Pointer with appended token. + */ + GenericPointer Append(SizeType index, Allocator* allocator = 0) const { + char buffer[21]; + char* end = sizeof(SizeType) == 4 ? internal::u32toa(index, buffer) : internal::u64toa(index, buffer); + SizeType length = static_cast(end - buffer); + buffer[length] = '\0'; + + if (sizeof(Ch) == 1) { + Token token = { reinterpret_cast(buffer), length, index }; + return Append(token, allocator); + } + else { + Ch name[21]; + for (size_t i = 0; i <= length; i++) + name[i] = buffer[i]; + Token token = { name, length, index }; + return Append(token, allocator); + } + } + + //! Append a token by value, and return a new Pointer + /*! + \param token token to be appended. + \param allocator Allocator for the newly return Pointer. + \return A new Pointer with appended token. + */ + GenericPointer Append(const ValueType& token, Allocator* allocator = 0) const { + if (token.IsString()) + return Append(token.GetString(), token.GetStringLength(), allocator); + else { + RAPIDJSON_ASSERT(token.IsUint64()); + RAPIDJSON_ASSERT(token.GetUint64() <= SizeType(~0)); + return Append(static_cast(token.GetUint64()), allocator); + } + } + + //!@name Handling Parse Error + //@{ + + //! Check whether this is a valid pointer. + bool IsValid() const { return parseErrorCode_ == kPointerParseErrorNone; } + + //! Get the parsing error offset in code unit. + size_t GetParseErrorOffset() const { return parseErrorOffset_; } + + //! Get the parsing error code. + PointerParseErrorCode GetParseErrorCode() const { return parseErrorCode_; } + + //@} + + //! Get the allocator of this pointer. + Allocator& GetAllocator() { return *allocator_; } + + //!@name Tokens + //@{ + + //! Get the token array (const version only). + const Token* GetTokens() const { return tokens_; } + + //! Get the number of tokens. + size_t GetTokenCount() const { return tokenCount_; } + + //@} + + //!@name Equality/inequality operators + //@{ + + //! Equality operator. + /*! + \note When any pointers are invalid, always returns false. + */ + bool operator==(const GenericPointer& rhs) const { + if (!IsValid() || !rhs.IsValid() || tokenCount_ != rhs.tokenCount_) + return false; + + for (size_t i = 0; i < tokenCount_; i++) { + if (tokens_[i].index != rhs.tokens_[i].index || + tokens_[i].length != rhs.tokens_[i].length || + (tokens_[i].length != 0 && std::memcmp(tokens_[i].name, rhs.tokens_[i].name, sizeof(Ch)* tokens_[i].length) != 0)) + { + return false; + } + } + + return true; + } + + //! Inequality operator. + /*! + \note When any pointers are invalid, always returns true. + */ + bool operator!=(const GenericPointer& rhs) const { return !(*this == rhs); } + + //@} + + //!@name Stringify + //@{ + + //! Stringify the pointer into string representation. + /*! + \tparam OutputStream Type of output stream. + \param os The output stream. + */ + template + bool Stringify(OutputStream& os) const { + return Stringify(os); + } + + //! Stringify the pointer into URI fragment representation. + /*! + \tparam OutputStream Type of output stream. + \param os The output stream. + */ + template + bool StringifyUriFragment(OutputStream& os) const { + return Stringify(os); + } + + //@} + + //!@name Create value + //@{ + + //! Create a value in a subtree. + /*! + If the value is not exist, it creates all parent values and a JSON Null value. + So it always succeed and return the newly created or existing value. + + Remind that it may change types of parents according to tokens, so it + potentially removes previously stored values. For example, if a document + was an array, and "/foo" is used to create a value, then the document + will be changed to an object, and all existing array elements are lost. + + \param root Root value of a DOM subtree to be resolved. It can be any value other than document root. + \param allocator Allocator for creating the values if the specified value or its parents are not exist. + \param alreadyExist If non-null, it stores whether the resolved value is already exist. + \return The resolved newly created (a JSON Null value), or already exists value. + */ + ValueType& Create(ValueType& root, typename ValueType::AllocatorType& allocator, bool* alreadyExist = 0) const { + RAPIDJSON_ASSERT(IsValid()); + ValueType* v = &root; + bool exist = true; + for (const Token *t = tokens_; t != tokens_ + tokenCount_; ++t) { + if (v->IsArray() && t->name[0] == '-' && t->length == 1) { + v->PushBack(ValueType().Move(), allocator); + v = &((*v)[v->Size() - 1]); + exist = false; + } + else { + if (t->index == kPointerInvalidIndex) { // must be object name + if (!v->IsObject()) + v->SetObject(); // Change to Object + } + else { // object name or array index + if (!v->IsArray() && !v->IsObject()) + v->SetArray(); // Change to Array + } + + if (v->IsArray()) { + if (t->index >= v->Size()) { + v->Reserve(t->index + 1, allocator); + while (t->index >= v->Size()) + v->PushBack(ValueType().Move(), allocator); + exist = false; + } + v = &((*v)[t->index]); + } + else { + typename ValueType::MemberIterator m = v->FindMember(GenericStringRef(t->name, t->length)); + if (m == v->MemberEnd()) { + v->AddMember(ValueType(t->name, t->length, allocator).Move(), ValueType().Move(), allocator); + v = &(--v->MemberEnd())->value; // Assumes AddMember() appends at the end + exist = false; + } + else + v = &m->value; + } + } + } + + if (alreadyExist) + *alreadyExist = exist; + + return *v; + } + + //! Creates a value in a document. + /*! + \param document A document to be resolved. + \param alreadyExist If non-null, it stores whether the resolved value is already exist. + \return The resolved newly created, or already exists value. + */ + template + ValueType& Create(GenericDocument& document, bool* alreadyExist = 0) const { + return Create(document, document.GetAllocator(), alreadyExist); + } + + //@} + + //!@name Query value + //@{ + + //! Query a value in a subtree. + /*! + \param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root. + \param unresolvedTokenIndex If the pointer cannot resolve a token in the pointer, this parameter can obtain the index of unresolved token. + \return Pointer to the value if it can be resolved. Otherwise null. + + \note + There are only 3 situations when a value cannot be resolved: + 1. A value in the path is not an array nor object. + 2. An object value does not contain the token. + 3. A token is out of range of an array value. + + Use unresolvedTokenIndex to retrieve the token index. + */ + ValueType* Get(ValueType& root, size_t* unresolvedTokenIndex = 0) const { + RAPIDJSON_ASSERT(IsValid()); + ValueType* v = &root; + for (const Token *t = tokens_; t != tokens_ + tokenCount_; ++t) { + switch (v->GetType()) { + case kObjectType: + { + typename ValueType::MemberIterator m = v->FindMember(GenericStringRef(t->name, t->length)); + if (m == v->MemberEnd()) + break; + v = &m->value; + } + continue; + case kArrayType: + if (t->index == kPointerInvalidIndex || t->index >= v->Size()) + break; + v = &((*v)[t->index]); + continue; + default: + break; + } + + // Error: unresolved token + if (unresolvedTokenIndex) + *unresolvedTokenIndex = static_cast(t - tokens_); + return 0; + } + return v; + } + + //! Query a const value in a const subtree. + /*! + \param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root. + \return Pointer to the value if it can be resolved. Otherwise null. + */ + const ValueType* Get(const ValueType& root, size_t* unresolvedTokenIndex = 0) const { + return Get(const_cast(root), unresolvedTokenIndex); + } + + //@} + + //!@name Query a value with default + //@{ + + //! Query a value in a subtree with default value. + /*! + Similar to Get(), but if the specified value do not exists, it creates all parents and clone the default value. + So that this function always succeed. + + \param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root. + \param defaultValue Default value to be cloned if the value was not exists. + \param allocator Allocator for creating the values if the specified value or its parents are not exist. + \see Create() + */ + ValueType& GetWithDefault(ValueType& root, const ValueType& defaultValue, typename ValueType::AllocatorType& allocator) const { + bool alreadyExist; + Value& v = Create(root, allocator, &alreadyExist); + return alreadyExist ? v : v.CopyFrom(defaultValue, allocator); + } + + //! Query a value in a subtree with default null-terminated string. + ValueType& GetWithDefault(ValueType& root, const Ch* defaultValue, typename ValueType::AllocatorType& allocator) const { + bool alreadyExist; + Value& v = Create(root, allocator, &alreadyExist); + return alreadyExist ? v : v.SetString(defaultValue, allocator); + } + +#if RAPIDJSON_HAS_STDSTRING + //! Query a value in a subtree with default std::basic_string. + ValueType& GetWithDefault(ValueType& root, const std::basic_string& defaultValue, typename ValueType::AllocatorType& allocator) const { + bool alreadyExist; + Value& v = Create(root, allocator, &alreadyExist); + return alreadyExist ? v : v.SetString(defaultValue, allocator); + } +#endif + + //! Query a value in a subtree with default primitive value. + /*! + \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t, \c bool + */ + template + RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (ValueType&)) + GetWithDefault(ValueType& root, T defaultValue, typename ValueType::AllocatorType& allocator) const { + return GetWithDefault(root, ValueType(defaultValue).Move(), allocator); + } + + //! Query a value in a document with default value. + template + ValueType& GetWithDefault(GenericDocument& document, const ValueType& defaultValue) const { + return GetWithDefault(document, defaultValue, document.GetAllocator()); + } + + //! Query a value in a document with default null-terminated string. + template + ValueType& GetWithDefault(GenericDocument& document, const Ch* defaultValue) const { + return GetWithDefault(document, defaultValue, document.GetAllocator()); + } + +#if RAPIDJSON_HAS_STDSTRING + //! Query a value in a document with default std::basic_string. + template + ValueType& GetWithDefault(GenericDocument& document, const std::basic_string& defaultValue) const { + return GetWithDefault(document, defaultValue, document.GetAllocator()); + } +#endif + + //! Query a value in a document with default primitive value. + /*! + \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t, \c bool + */ + template + RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (ValueType&)) + GetWithDefault(GenericDocument& document, T defaultValue) const { + return GetWithDefault(document, defaultValue, document.GetAllocator()); + } + + //@} + + //!@name Set a value + //@{ + + //! Set a value in a subtree, with move semantics. + /*! + It creates all parents if they are not exist or types are different to the tokens. + So this function always succeeds but potentially remove existing values. + + \param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root. + \param value Value to be set. + \param allocator Allocator for creating the values if the specified value or its parents are not exist. + \see Create() + */ + ValueType& Set(ValueType& root, ValueType& value, typename ValueType::AllocatorType& allocator) const { + return Create(root, allocator) = value; + } + + //! Set a value in a subtree, with copy semantics. + ValueType& Set(ValueType& root, const ValueType& value, typename ValueType::AllocatorType& allocator) const { + return Create(root, allocator).CopyFrom(value, allocator); + } + + //! Set a null-terminated string in a subtree. + ValueType& Set(ValueType& root, const Ch* value, typename ValueType::AllocatorType& allocator) const { + return Create(root, allocator) = ValueType(value, allocator).Move(); + } + +#if RAPIDJSON_HAS_STDSTRING + //! Set a std::basic_string in a subtree. + ValueType& Set(ValueType& root, const std::basic_string& value, typename ValueType::AllocatorType& allocator) const { + return Create(root, allocator) = ValueType(value, allocator).Move(); + } +#endif + + //! Set a primitive value in a subtree. + /*! + \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t, \c bool + */ + template + RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (ValueType&)) + Set(ValueType& root, T value, typename ValueType::AllocatorType& allocator) const { + return Create(root, allocator) = ValueType(value).Move(); + } + + //! Set a value in a document, with move semantics. + template + ValueType& Set(GenericDocument& document, ValueType& value) const { + return Create(document) = value; + } + + //! Set a value in a document, with copy semantics. + template + ValueType& Set(GenericDocument& document, const ValueType& value) const { + return Create(document).CopyFrom(value, document.GetAllocator()); + } + + //! Set a null-terminated string in a document. + template + ValueType& Set(GenericDocument& document, const Ch* value) const { + return Create(document) = ValueType(value, document.GetAllocator()).Move(); + } + +#if RAPIDJSON_HAS_STDSTRING + //! Sets a std::basic_string in a document. + template + ValueType& Set(GenericDocument& document, const std::basic_string& value) const { + return Create(document) = ValueType(value, document.GetAllocator()).Move(); + } +#endif + + //! Set a primitive value in a document. + /*! + \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t, \c bool + */ + template + RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (ValueType&)) + Set(GenericDocument& document, T value) const { + return Create(document) = value; + } + + //@} + + //!@name Swap a value + //@{ + + //! Swap a value with a value in a subtree. + /*! + It creates all parents if they are not exist or types are different to the tokens. + So this function always succeeds but potentially remove existing values. + + \param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root. + \param value Value to be swapped. + \param allocator Allocator for creating the values if the specified value or its parents are not exist. + \see Create() + */ + ValueType& Swap(ValueType& root, ValueType& value, typename ValueType::AllocatorType& allocator) const { + return Create(root, allocator).Swap(value); + } + + //! Swap a value with a value in a document. + template + ValueType& Swap(GenericDocument& document, ValueType& value) const { + return Create(document).Swap(value); + } + + //@} + + //! Erase a value in a subtree. + /*! + \param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root. + \return Whether the resolved value is found and erased. + + \note Erasing with an empty pointer \c Pointer(""), i.e. the root, always fail and return false. + */ + bool Erase(ValueType& root) const { + RAPIDJSON_ASSERT(IsValid()); + if (tokenCount_ == 0) // Cannot erase the root + return false; + + ValueType* v = &root; + const Token* last = tokens_ + (tokenCount_ - 1); + for (const Token *t = tokens_; t != last; ++t) { + switch (v->GetType()) { + case kObjectType: + { + typename ValueType::MemberIterator m = v->FindMember(GenericStringRef(t->name, t->length)); + if (m == v->MemberEnd()) + return false; + v = &m->value; + } + break; + case kArrayType: + if (t->index == kPointerInvalidIndex || t->index >= v->Size()) + return false; + v = &((*v)[t->index]); + break; + default: + return false; + } + } + + switch (v->GetType()) { + case kObjectType: + return v->EraseMember(GenericStringRef(last->name, last->length)); + case kArrayType: + if (last->index == kPointerInvalidIndex || last->index >= v->Size()) + return false; + v->Erase(v->Begin() + last->index); + return true; + default: + return false; + } + } + +private: + //! Clone the content from rhs to this. + /*! + \param rhs Source pointer. + \param extraToken Extra tokens to be allocated. + \param extraNameBufferSize Extra name buffer size (in number of Ch) to be allocated. + \return Start of non-occupied name buffer, for storing extra names. + */ + Ch* CopyFromRaw(const GenericPointer& rhs, size_t extraToken = 0, size_t extraNameBufferSize = 0) { + if (!allocator_) // allocator is independently owned. + ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator()); + + size_t nameBufferSize = rhs.tokenCount_; // null terminators for tokens + for (Token *t = rhs.tokens_; t != rhs.tokens_ + rhs.tokenCount_; ++t) + nameBufferSize += t->length; + + tokenCount_ = rhs.tokenCount_ + extraToken; + tokens_ = static_cast(allocator_->Malloc(tokenCount_ * sizeof(Token) + (nameBufferSize + extraNameBufferSize) * sizeof(Ch))); + nameBuffer_ = reinterpret_cast(tokens_ + tokenCount_); + if (rhs.tokenCount_ > 0) { + std::memcpy(tokens_, rhs.tokens_, rhs.tokenCount_ * sizeof(Token)); + } + if (nameBufferSize > 0) { + std::memcpy(nameBuffer_, rhs.nameBuffer_, nameBufferSize * sizeof(Ch)); + } + + // Adjust pointers to name buffer + std::ptrdiff_t diff = nameBuffer_ - rhs.nameBuffer_; + for (Token *t = tokens_; t != tokens_ + rhs.tokenCount_; ++t) + t->name += diff; + + return nameBuffer_ + nameBufferSize; + } + + //! Check whether a character should be percent-encoded. + /*! + According to RFC 3986 2.3 Unreserved Characters. + \param c The character (code unit) to be tested. + */ + bool NeedPercentEncode(Ch c) const { + return !((c >= '0' && c <= '9') || (c >= 'A' && c <='Z') || (c >= 'a' && c <= 'z') || c == '-' || c == '.' || c == '_' || c =='~'); + } + + //! Parse a JSON String or its URI fragment representation into tokens. +#ifndef __clang__ // -Wdocumentation + /*! + \param source Either a JSON Pointer string, or its URI fragment representation. Not need to be null terminated. + \param length Length of the source string. + \note Source cannot be JSON String Representation of JSON Pointer, e.g. In "/\u0000", \u0000 will not be unescaped. + */ +#endif + void Parse(const Ch* source, size_t length) { + RAPIDJSON_ASSERT(source != NULL); + RAPIDJSON_ASSERT(nameBuffer_ == 0); + RAPIDJSON_ASSERT(tokens_ == 0); + + // Create own allocator if user did not supply. + if (!allocator_) + ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator()); + + // Count number of '/' as tokenCount + tokenCount_ = 0; + for (const Ch* s = source; s != source + length; s++) + if (*s == '/') + tokenCount_++; + + Token* token = tokens_ = static_cast(allocator_->Malloc(tokenCount_ * sizeof(Token) + length * sizeof(Ch))); + Ch* name = nameBuffer_ = reinterpret_cast(tokens_ + tokenCount_); + size_t i = 0; + + // Detect if it is a URI fragment + bool uriFragment = false; + if (source[i] == '#') { + uriFragment = true; + i++; + } + + if (i != length && source[i] != '/') { + parseErrorCode_ = kPointerParseErrorTokenMustBeginWithSolidus; + goto error; + } + + while (i < length) { + RAPIDJSON_ASSERT(source[i] == '/'); + i++; // consumes '/' + + token->name = name; + bool isNumber = true; + + while (i < length && source[i] != '/') { + Ch c = source[i]; + if (uriFragment) { + // Decoding percent-encoding for URI fragment + if (c == '%') { + PercentDecodeStream is(&source[i], source + length); + GenericInsituStringStream os(name); + Ch* begin = os.PutBegin(); + if (!Transcoder, EncodingType>().Validate(is, os) || !is.IsValid()) { + parseErrorCode_ = kPointerParseErrorInvalidPercentEncoding; + goto error; + } + size_t len = os.PutEnd(begin); + i += is.Tell() - 1; + if (len == 1) + c = *name; + else { + name += len; + isNumber = false; + i++; + continue; + } + } + else if (NeedPercentEncode(c)) { + parseErrorCode_ = kPointerParseErrorCharacterMustPercentEncode; + goto error; + } + } + + i++; + + // Escaping "~0" -> '~', "~1" -> '/' + if (c == '~') { + if (i < length) { + c = source[i]; + if (c == '0') c = '~'; + else if (c == '1') c = '/'; + else { + parseErrorCode_ = kPointerParseErrorInvalidEscape; + goto error; + } + i++; + } + else { + parseErrorCode_ = kPointerParseErrorInvalidEscape; + goto error; + } + } + + // First check for index: all of characters are digit + if (c < '0' || c > '9') + isNumber = false; + + *name++ = c; + } + token->length = static_cast(name - token->name); + if (token->length == 0) + isNumber = false; + *name++ = '\0'; // Null terminator + + // Second check for index: more than one digit cannot have leading zero + if (isNumber && token->length > 1 && token->name[0] == '0') + isNumber = false; + + // String to SizeType conversion + SizeType n = 0; + if (isNumber) { + for (size_t j = 0; j < token->length; j++) { + SizeType m = n * 10 + static_cast(token->name[j] - '0'); + if (m < n) { // overflow detection + isNumber = false; + break; + } + n = m; + } + } + + token->index = isNumber ? n : kPointerInvalidIndex; + token++; + } + + RAPIDJSON_ASSERT(name <= nameBuffer_ + length); // Should not overflow buffer + parseErrorCode_ = kPointerParseErrorNone; + return; + + error: + Allocator::Free(tokens_); + nameBuffer_ = 0; + tokens_ = 0; + tokenCount_ = 0; + parseErrorOffset_ = i; + return; + } + + //! Stringify to string or URI fragment representation. + /*! + \tparam uriFragment True for stringifying to URI fragment representation. False for string representation. + \tparam OutputStream type of output stream. + \param os The output stream. + */ + template + bool Stringify(OutputStream& os) const { + RAPIDJSON_ASSERT(IsValid()); + + if (uriFragment) + os.Put('#'); + + for (Token *t = tokens_; t != tokens_ + tokenCount_; ++t) { + os.Put('/'); + for (size_t j = 0; j < t->length; j++) { + Ch c = t->name[j]; + if (c == '~') { + os.Put('~'); + os.Put('0'); + } + else if (c == '/') { + os.Put('~'); + os.Put('1'); + } + else if (uriFragment && NeedPercentEncode(c)) { + // Transcode to UTF8 sequence + GenericStringStream source(&t->name[j]); + PercentEncodeStream target(os); + if (!Transcoder >().Validate(source, target)) + return false; + j += source.Tell() - 1; + } + else + os.Put(c); + } + } + return true; + } + + //! A helper stream for decoding a percent-encoded sequence into code unit. + /*! + This stream decodes %XY triplet into code unit (0-255). + If it encounters invalid characters, it sets output code unit as 0 and + mark invalid, and to be checked by IsValid(). + */ + class PercentDecodeStream { + public: + typedef typename ValueType::Ch Ch; + + //! Constructor + /*! + \param source Start of the stream + \param end Past-the-end of the stream. + */ + PercentDecodeStream(const Ch* source, const Ch* end) : src_(source), head_(source), end_(end), valid_(true) {} + + Ch Take() { + if (*src_ != '%' || src_ + 3 > end_) { // %XY triplet + valid_ = false; + return 0; + } + src_++; + Ch c = 0; + for (int j = 0; j < 2; j++) { + c = static_cast(c << 4); + Ch h = *src_; + if (h >= '0' && h <= '9') c = static_cast(c + h - '0'); + else if (h >= 'A' && h <= 'F') c = static_cast(c + h - 'A' + 10); + else if (h >= 'a' && h <= 'f') c = static_cast(c + h - 'a' + 10); + else { + valid_ = false; + return 0; + } + src_++; + } + return c; + } + + size_t Tell() const { return static_cast(src_ - head_); } + bool IsValid() const { return valid_; } + + private: + const Ch* src_; //!< Current read position. + const Ch* head_; //!< Original head of the string. + const Ch* end_; //!< Past-the-end position. + bool valid_; //!< Whether the parsing is valid. + }; + + //! A helper stream to encode character (UTF-8 code unit) into percent-encoded sequence. + template + class PercentEncodeStream { + public: + PercentEncodeStream(OutputStream& os) : os_(os) {} + void Put(char c) { // UTF-8 must be byte + unsigned char u = static_cast(c); + static const char hexDigits[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; + os_.Put('%'); + os_.Put(hexDigits[u >> 4]); + os_.Put(hexDigits[u & 15]); + } + private: + OutputStream& os_; + }; + + Allocator* allocator_; //!< The current allocator. It is either user-supplied or equal to ownAllocator_. + Allocator* ownAllocator_; //!< Allocator owned by this Pointer. + Ch* nameBuffer_; //!< A buffer containing all names in tokens. + Token* tokens_; //!< A list of tokens. + size_t tokenCount_; //!< Number of tokens in tokens_. + size_t parseErrorOffset_; //!< Offset in code unit when parsing fail. + PointerParseErrorCode parseErrorCode_; //!< Parsing error code. +}; + +//! GenericPointer for Value (UTF-8, default allocator). +typedef GenericPointer Pointer; + +//!@name Helper functions for GenericPointer +//@{ + +////////////////////////////////////////////////////////////////////////////// + +template +typename T::ValueType& CreateValueByPointer(T& root, const GenericPointer& pointer, typename T::AllocatorType& a) { + return pointer.Create(root, a); +} + +template +typename T::ValueType& CreateValueByPointer(T& root, const CharType(&source)[N], typename T::AllocatorType& a) { + return GenericPointer(source, N - 1).Create(root, a); +} + +// No allocator parameter + +template +typename DocumentType::ValueType& CreateValueByPointer(DocumentType& document, const GenericPointer& pointer) { + return pointer.Create(document); +} + +template +typename DocumentType::ValueType& CreateValueByPointer(DocumentType& document, const CharType(&source)[N]) { + return GenericPointer(source, N - 1).Create(document); +} + +////////////////////////////////////////////////////////////////////////////// + +template +typename T::ValueType* GetValueByPointer(T& root, const GenericPointer& pointer, size_t* unresolvedTokenIndex = 0) { + return pointer.Get(root, unresolvedTokenIndex); +} + +template +const typename T::ValueType* GetValueByPointer(const T& root, const GenericPointer& pointer, size_t* unresolvedTokenIndex = 0) { + return pointer.Get(root, unresolvedTokenIndex); +} + +template +typename T::ValueType* GetValueByPointer(T& root, const CharType (&source)[N], size_t* unresolvedTokenIndex = 0) { + return GenericPointer(source, N - 1).Get(root, unresolvedTokenIndex); +} + +template +const typename T::ValueType* GetValueByPointer(const T& root, const CharType(&source)[N], size_t* unresolvedTokenIndex = 0) { + return GenericPointer(source, N - 1).Get(root, unresolvedTokenIndex); +} + +////////////////////////////////////////////////////////////////////////////// + +template +typename T::ValueType& GetValueByPointerWithDefault(T& root, const GenericPointer& pointer, const typename T::ValueType& defaultValue, typename T::AllocatorType& a) { + return pointer.GetWithDefault(root, defaultValue, a); +} + +template +typename T::ValueType& GetValueByPointerWithDefault(T& root, const GenericPointer& pointer, const typename T::Ch* defaultValue, typename T::AllocatorType& a) { + return pointer.GetWithDefault(root, defaultValue, a); +} + +#if RAPIDJSON_HAS_STDSTRING +template +typename T::ValueType& GetValueByPointerWithDefault(T& root, const GenericPointer& pointer, const std::basic_string& defaultValue, typename T::AllocatorType& a) { + return pointer.GetWithDefault(root, defaultValue, a); +} +#endif + +template +RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (typename T::ValueType&)) +GetValueByPointerWithDefault(T& root, const GenericPointer& pointer, T2 defaultValue, typename T::AllocatorType& a) { + return pointer.GetWithDefault(root, defaultValue, a); +} + +template +typename T::ValueType& GetValueByPointerWithDefault(T& root, const CharType(&source)[N], const typename T::ValueType& defaultValue, typename T::AllocatorType& a) { + return GenericPointer(source, N - 1).GetWithDefault(root, defaultValue, a); +} + +template +typename T::ValueType& GetValueByPointerWithDefault(T& root, const CharType(&source)[N], const typename T::Ch* defaultValue, typename T::AllocatorType& a) { + return GenericPointer(source, N - 1).GetWithDefault(root, defaultValue, a); +} + +#if RAPIDJSON_HAS_STDSTRING +template +typename T::ValueType& GetValueByPointerWithDefault(T& root, const CharType(&source)[N], const std::basic_string& defaultValue, typename T::AllocatorType& a) { + return GenericPointer(source, N - 1).GetWithDefault(root, defaultValue, a); +} +#endif + +template +RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (typename T::ValueType&)) +GetValueByPointerWithDefault(T& root, const CharType(&source)[N], T2 defaultValue, typename T::AllocatorType& a) { + return GenericPointer(source, N - 1).GetWithDefault(root, defaultValue, a); +} + +// No allocator parameter + +template +typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const GenericPointer& pointer, const typename DocumentType::ValueType& defaultValue) { + return pointer.GetWithDefault(document, defaultValue); +} + +template +typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const GenericPointer& pointer, const typename DocumentType::Ch* defaultValue) { + return pointer.GetWithDefault(document, defaultValue); +} + +#if RAPIDJSON_HAS_STDSTRING +template +typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const GenericPointer& pointer, const std::basic_string& defaultValue) { + return pointer.GetWithDefault(document, defaultValue); +} +#endif + +template +RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (typename DocumentType::ValueType&)) +GetValueByPointerWithDefault(DocumentType& document, const GenericPointer& pointer, T2 defaultValue) { + return pointer.GetWithDefault(document, defaultValue); +} + +template +typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const CharType(&source)[N], const typename DocumentType::ValueType& defaultValue) { + return GenericPointer(source, N - 1).GetWithDefault(document, defaultValue); +} + +template +typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const CharType(&source)[N], const typename DocumentType::Ch* defaultValue) { + return GenericPointer(source, N - 1).GetWithDefault(document, defaultValue); +} + +#if RAPIDJSON_HAS_STDSTRING +template +typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const CharType(&source)[N], const std::basic_string& defaultValue) { + return GenericPointer(source, N - 1).GetWithDefault(document, defaultValue); +} +#endif + +template +RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (typename DocumentType::ValueType&)) +GetValueByPointerWithDefault(DocumentType& document, const CharType(&source)[N], T2 defaultValue) { + return GenericPointer(source, N - 1).GetWithDefault(document, defaultValue); +} + +////////////////////////////////////////////////////////////////////////////// + +template +typename T::ValueType& SetValueByPointer(T& root, const GenericPointer& pointer, typename T::ValueType& value, typename T::AllocatorType& a) { + return pointer.Set(root, value, a); +} + +template +typename T::ValueType& SetValueByPointer(T& root, const GenericPointer& pointer, const typename T::ValueType& value, typename T::AllocatorType& a) { + return pointer.Set(root, value, a); +} + +template +typename T::ValueType& SetValueByPointer(T& root, const GenericPointer& pointer, const typename T::Ch* value, typename T::AllocatorType& a) { + return pointer.Set(root, value, a); +} + +#if RAPIDJSON_HAS_STDSTRING +template +typename T::ValueType& SetValueByPointer(T& root, const GenericPointer& pointer, const std::basic_string& value, typename T::AllocatorType& a) { + return pointer.Set(root, value, a); +} +#endif + +template +RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (typename T::ValueType&)) +SetValueByPointer(T& root, const GenericPointer& pointer, T2 value, typename T::AllocatorType& a) { + return pointer.Set(root, value, a); +} + +template +typename T::ValueType& SetValueByPointer(T& root, const CharType(&source)[N], typename T::ValueType& value, typename T::AllocatorType& a) { + return GenericPointer(source, N - 1).Set(root, value, a); +} + +template +typename T::ValueType& SetValueByPointer(T& root, const CharType(&source)[N], const typename T::ValueType& value, typename T::AllocatorType& a) { + return GenericPointer(source, N - 1).Set(root, value, a); +} + +template +typename T::ValueType& SetValueByPointer(T& root, const CharType(&source)[N], const typename T::Ch* value, typename T::AllocatorType& a) { + return GenericPointer(source, N - 1).Set(root, value, a); +} + +#if RAPIDJSON_HAS_STDSTRING +template +typename T::ValueType& SetValueByPointer(T& root, const CharType(&source)[N], const std::basic_string& value, typename T::AllocatorType& a) { + return GenericPointer(source, N - 1).Set(root, value, a); +} +#endif + +template +RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (typename T::ValueType&)) +SetValueByPointer(T& root, const CharType(&source)[N], T2 value, typename T::AllocatorType& a) { + return GenericPointer(source, N - 1).Set(root, value, a); +} + +// No allocator parameter + +template +typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const GenericPointer& pointer, typename DocumentType::ValueType& value) { + return pointer.Set(document, value); +} + +template +typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const GenericPointer& pointer, const typename DocumentType::ValueType& value) { + return pointer.Set(document, value); +} + +template +typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const GenericPointer& pointer, const typename DocumentType::Ch* value) { + return pointer.Set(document, value); +} + +#if RAPIDJSON_HAS_STDSTRING +template +typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const GenericPointer& pointer, const std::basic_string& value) { + return pointer.Set(document, value); +} +#endif + +template +RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (typename DocumentType::ValueType&)) +SetValueByPointer(DocumentType& document, const GenericPointer& pointer, T2 value) { + return pointer.Set(document, value); +} + +template +typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const CharType(&source)[N], typename DocumentType::ValueType& value) { + return GenericPointer(source, N - 1).Set(document, value); +} + +template +typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const CharType(&source)[N], const typename DocumentType::ValueType& value) { + return GenericPointer(source, N - 1).Set(document, value); +} + +template +typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const CharType(&source)[N], const typename DocumentType::Ch* value) { + return GenericPointer(source, N - 1).Set(document, value); +} + +#if RAPIDJSON_HAS_STDSTRING +template +typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const CharType(&source)[N], const std::basic_string& value) { + return GenericPointer(source, N - 1).Set(document, value); +} +#endif + +template +RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (typename DocumentType::ValueType&)) +SetValueByPointer(DocumentType& document, const CharType(&source)[N], T2 value) { + return GenericPointer(source, N - 1).Set(document, value); +} + +////////////////////////////////////////////////////////////////////////////// + +template +typename T::ValueType& SwapValueByPointer(T& root, const GenericPointer& pointer, typename T::ValueType& value, typename T::AllocatorType& a) { + return pointer.Swap(root, value, a); +} + +template +typename T::ValueType& SwapValueByPointer(T& root, const CharType(&source)[N], typename T::ValueType& value, typename T::AllocatorType& a) { + return GenericPointer(source, N - 1).Swap(root, value, a); +} + +template +typename DocumentType::ValueType& SwapValueByPointer(DocumentType& document, const GenericPointer& pointer, typename DocumentType::ValueType& value) { + return pointer.Swap(document, value); +} + +template +typename DocumentType::ValueType& SwapValueByPointer(DocumentType& document, const CharType(&source)[N], typename DocumentType::ValueType& value) { + return GenericPointer(source, N - 1).Swap(document, value); +} + +////////////////////////////////////////////////////////////////////////////// + +template +bool EraseValueByPointer(T& root, const GenericPointer& pointer) { + return pointer.Erase(root); +} + +template +bool EraseValueByPointer(T& root, const CharType(&source)[N]) { + return GenericPointer(source, N - 1).Erase(root); +} + +//@} + +RAPIDJSON_NAMESPACE_END + +#ifdef __clang__ +RAPIDJSON_DIAG_POP +#endif + +#ifdef _MSC_VER +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_POINTER_H_ diff --git a/slsReceiverSoftware/include/rapidjson/prettywriter.h b/slsReceiverSoftware/include/rapidjson/prettywriter.h new file mode 100644 index 000000000..0dcb0fee9 --- /dev/null +++ b/slsReceiverSoftware/include/rapidjson/prettywriter.h @@ -0,0 +1,255 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_PRETTYWRITER_H_ +#define RAPIDJSON_PRETTYWRITER_H_ + +#include "writer.h" + +#ifdef __GNUC__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(effc++) +#endif + +RAPIDJSON_NAMESPACE_BEGIN + +//! Combination of PrettyWriter format flags. +/*! \see PrettyWriter::SetFormatOptions + */ +enum PrettyFormatOptions { + kFormatDefault = 0, //!< Default pretty formatting. + kFormatSingleLineArray = 1 //!< Format arrays on a single line. +}; + +//! Writer with indentation and spacing. +/*! + \tparam OutputStream Type of ouptut os. + \tparam SourceEncoding Encoding of source string. + \tparam TargetEncoding Encoding of output stream. + \tparam StackAllocator Type of allocator for allocating memory of stack. +*/ +template, typename TargetEncoding = UTF8<>, typename StackAllocator = CrtAllocator, unsigned writeFlags = kWriteDefaultFlags> +class PrettyWriter : public Writer { +public: + typedef Writer Base; + typedef typename Base::Ch Ch; + + //! Constructor + /*! \param os Output stream. + \param allocator User supplied allocator. If it is null, it will create a private one. + \param levelDepth Initial capacity of stack. + */ + explicit PrettyWriter(OutputStream& os, StackAllocator* allocator = 0, size_t levelDepth = Base::kDefaultLevelDepth) : + Base(os, allocator, levelDepth), indentChar_(' '), indentCharCount_(4), formatOptions_(kFormatDefault) {} + + + explicit PrettyWriter(StackAllocator* allocator = 0, size_t levelDepth = Base::kDefaultLevelDepth) : + Base(allocator, levelDepth), indentChar_(' '), indentCharCount_(4) {} + + //! Set custom indentation. + /*! \param indentChar Character for indentation. Must be whitespace character (' ', '\\t', '\\n', '\\r'). + \param indentCharCount Number of indent characters for each indentation level. + \note The default indentation is 4 spaces. + */ + PrettyWriter& SetIndent(Ch indentChar, unsigned indentCharCount) { + RAPIDJSON_ASSERT(indentChar == ' ' || indentChar == '\t' || indentChar == '\n' || indentChar == '\r'); + indentChar_ = indentChar; + indentCharCount_ = indentCharCount; + return *this; + } + + //! Set pretty writer formatting options. + /*! \param options Formatting options. + */ + PrettyWriter& SetFormatOptions(PrettyFormatOptions options) { + formatOptions_ = options; + return *this; + } + + /*! @name Implementation of Handler + \see Handler + */ + //@{ + + bool Null() { PrettyPrefix(kNullType); return Base::WriteNull(); } + bool Bool(bool b) { PrettyPrefix(b ? kTrueType : kFalseType); return Base::WriteBool(b); } + bool Int(int i) { PrettyPrefix(kNumberType); return Base::WriteInt(i); } + bool Uint(unsigned u) { PrettyPrefix(kNumberType); return Base::WriteUint(u); } + bool Int64(int64_t i64) { PrettyPrefix(kNumberType); return Base::WriteInt64(i64); } + bool Uint64(uint64_t u64) { PrettyPrefix(kNumberType); return Base::WriteUint64(u64); } + bool Double(double d) { PrettyPrefix(kNumberType); return Base::WriteDouble(d); } + + bool RawNumber(const Ch* str, SizeType length, bool copy = false) { + (void)copy; + PrettyPrefix(kNumberType); + return Base::WriteString(str, length); + } + + bool String(const Ch* str, SizeType length, bool copy = false) { + (void)copy; + PrettyPrefix(kStringType); + return Base::WriteString(str, length); + } + +#if RAPIDJSON_HAS_STDSTRING + bool String(const std::basic_string& str) { + return String(str.data(), SizeType(str.size())); + } +#endif + + bool StartObject() { + PrettyPrefix(kObjectType); + new (Base::level_stack_.template Push()) typename Base::Level(false); + return Base::WriteStartObject(); + } + + bool Key(const Ch* str, SizeType length, bool copy = false) { return String(str, length, copy); } + +#if RAPIDJSON_HAS_STDSTRING + bool Key(const std::basic_string& str) { + return Key(str.data(), SizeType(str.size())); + } +#endif + + bool EndObject(SizeType memberCount = 0) { + (void)memberCount; + RAPIDJSON_ASSERT(Base::level_stack_.GetSize() >= sizeof(typename Base::Level)); + RAPIDJSON_ASSERT(!Base::level_stack_.template Top()->inArray); + bool empty = Base::level_stack_.template Pop(1)->valueCount == 0; + + if (!empty) { + Base::os_->Put('\n'); + WriteIndent(); + } + bool ret = Base::WriteEndObject(); + (void)ret; + RAPIDJSON_ASSERT(ret == true); + if (Base::level_stack_.Empty()) // end of json text + Base::os_->Flush(); + return true; + } + + bool StartArray() { + PrettyPrefix(kArrayType); + new (Base::level_stack_.template Push()) typename Base::Level(true); + return Base::WriteStartArray(); + } + + bool EndArray(SizeType memberCount = 0) { + (void)memberCount; + RAPIDJSON_ASSERT(Base::level_stack_.GetSize() >= sizeof(typename Base::Level)); + RAPIDJSON_ASSERT(Base::level_stack_.template Top()->inArray); + bool empty = Base::level_stack_.template Pop(1)->valueCount == 0; + + if (!empty && !(formatOptions_ & kFormatSingleLineArray)) { + Base::os_->Put('\n'); + WriteIndent(); + } + bool ret = Base::WriteEndArray(); + (void)ret; + RAPIDJSON_ASSERT(ret == true); + if (Base::level_stack_.Empty()) // end of json text + Base::os_->Flush(); + return true; + } + + //@} + + /*! @name Convenience extensions */ + //@{ + + //! Simpler but slower overload. + bool String(const Ch* str) { return String(str, internal::StrLen(str)); } + bool Key(const Ch* str) { return Key(str, internal::StrLen(str)); } + + //@} + + //! Write a raw JSON value. + /*! + For user to write a stringified JSON as a value. + + \param json A well-formed JSON value. It should not contain null character within [0, length - 1] range. + \param length Length of the json. + \param type Type of the root of json. + \note When using PrettyWriter::RawValue(), the result json may not be indented correctly. + */ + bool RawValue(const Ch* json, size_t length, Type type) { PrettyPrefix(type); return Base::WriteRawValue(json, length); } + +protected: + void PrettyPrefix(Type type) { + (void)type; + if (Base::level_stack_.GetSize() != 0) { // this value is not at root + typename Base::Level* level = Base::level_stack_.template Top(); + + if (level->inArray) { + if (level->valueCount > 0) { + Base::os_->Put(','); // add comma if it is not the first element in array + if (formatOptions_ & kFormatSingleLineArray) + Base::os_->Put(' '); + } + + if (!(formatOptions_ & kFormatSingleLineArray)) { + Base::os_->Put('\n'); + WriteIndent(); + } + } + else { // in object + if (level->valueCount > 0) { + if (level->valueCount % 2 == 0) { + Base::os_->Put(','); + Base::os_->Put('\n'); + } + else { + Base::os_->Put(':'); + Base::os_->Put(' '); + } + } + else + Base::os_->Put('\n'); + + if (level->valueCount % 2 == 0) + WriteIndent(); + } + if (!level->inArray && level->valueCount % 2 == 0) + RAPIDJSON_ASSERT(type == kStringType); // if it's in object, then even number should be a name + level->valueCount++; + } + else { + RAPIDJSON_ASSERT(!Base::hasRoot_); // Should only has one and only one root. + Base::hasRoot_ = true; + } + } + + void WriteIndent() { + size_t count = (Base::level_stack_.GetSize() / sizeof(typename Base::Level)) * indentCharCount_; + PutN(*Base::os_, static_cast(indentChar_), count); + } + + Ch indentChar_; + unsigned indentCharCount_; + PrettyFormatOptions formatOptions_; + +private: + // Prohibit copy constructor & assignment operator. + PrettyWriter(const PrettyWriter&); + PrettyWriter& operator=(const PrettyWriter&); +}; + +RAPIDJSON_NAMESPACE_END + +#ifdef __GNUC__ +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_RAPIDJSON_H_ diff --git a/slsReceiverSoftware/include/rapidjson/rapidjson.h b/slsReceiverSoftware/include/rapidjson/rapidjson.h new file mode 100644 index 000000000..053b2ce43 --- /dev/null +++ b/slsReceiverSoftware/include/rapidjson/rapidjson.h @@ -0,0 +1,615 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_RAPIDJSON_H_ +#define RAPIDJSON_RAPIDJSON_H_ + +/*!\file rapidjson.h + \brief common definitions and configuration + + \see RAPIDJSON_CONFIG + */ + +/*! \defgroup RAPIDJSON_CONFIG RapidJSON configuration + \brief Configuration macros for library features + + Some RapidJSON features are configurable to adapt the library to a wide + variety of platforms, environments and usage scenarios. Most of the + features can be configured in terms of overriden or predefined + preprocessor macros at compile-time. + + Some additional customization is available in the \ref RAPIDJSON_ERRORS APIs. + + \note These macros should be given on the compiler command-line + (where applicable) to avoid inconsistent values when compiling + different translation units of a single application. + */ + +#include // malloc(), realloc(), free(), size_t +#include // memset(), memcpy(), memmove(), memcmp() + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_VERSION_STRING +// +// ALWAYS synchronize the following 3 macros with corresponding variables in /CMakeLists.txt. +// + +//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN +// token stringification +#define RAPIDJSON_STRINGIFY(x) RAPIDJSON_DO_STRINGIFY(x) +#define RAPIDJSON_DO_STRINGIFY(x) #x +//!@endcond + +/*! \def RAPIDJSON_MAJOR_VERSION + \ingroup RAPIDJSON_CONFIG + \brief Major version of RapidJSON in integer. +*/ +/*! \def RAPIDJSON_MINOR_VERSION + \ingroup RAPIDJSON_CONFIG + \brief Minor version of RapidJSON in integer. +*/ +/*! \def RAPIDJSON_PATCH_VERSION + \ingroup RAPIDJSON_CONFIG + \brief Patch version of RapidJSON in integer. +*/ +/*! \def RAPIDJSON_VERSION_STRING + \ingroup RAPIDJSON_CONFIG + \brief Version of RapidJSON in ".." string format. +*/ +#define RAPIDJSON_MAJOR_VERSION 1 +#define RAPIDJSON_MINOR_VERSION 1 +#define RAPIDJSON_PATCH_VERSION 0 +#define RAPIDJSON_VERSION_STRING \ + RAPIDJSON_STRINGIFY(RAPIDJSON_MAJOR_VERSION.RAPIDJSON_MINOR_VERSION.RAPIDJSON_PATCH_VERSION) + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_NAMESPACE_(BEGIN|END) +/*! \def RAPIDJSON_NAMESPACE + \ingroup RAPIDJSON_CONFIG + \brief provide custom rapidjson namespace + + In order to avoid symbol clashes and/or "One Definition Rule" errors + between multiple inclusions of (different versions of) RapidJSON in + a single binary, users can customize the name of the main RapidJSON + namespace. + + In case of a single nesting level, defining \c RAPIDJSON_NAMESPACE + to a custom name (e.g. \c MyRapidJSON) is sufficient. If multiple + levels are needed, both \ref RAPIDJSON_NAMESPACE_BEGIN and \ref + RAPIDJSON_NAMESPACE_END need to be defined as well: + + \code + // in some .cpp file + #define RAPIDJSON_NAMESPACE my::rapidjson + #define RAPIDJSON_NAMESPACE_BEGIN namespace my { namespace rapidjson { + #define RAPIDJSON_NAMESPACE_END } } + #include "rapidjson/..." + \endcode + + \see rapidjson + */ +/*! \def RAPIDJSON_NAMESPACE_BEGIN + \ingroup RAPIDJSON_CONFIG + \brief provide custom rapidjson namespace (opening expression) + \see RAPIDJSON_NAMESPACE +*/ +/*! \def RAPIDJSON_NAMESPACE_END + \ingroup RAPIDJSON_CONFIG + \brief provide custom rapidjson namespace (closing expression) + \see RAPIDJSON_NAMESPACE +*/ +#ifndef RAPIDJSON_NAMESPACE +#define RAPIDJSON_NAMESPACE rapidjson +#endif +#ifndef RAPIDJSON_NAMESPACE_BEGIN +#define RAPIDJSON_NAMESPACE_BEGIN namespace RAPIDJSON_NAMESPACE { +#endif +#ifndef RAPIDJSON_NAMESPACE_END +#define RAPIDJSON_NAMESPACE_END } +#endif + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_HAS_STDSTRING + +#ifndef RAPIDJSON_HAS_STDSTRING +#ifdef RAPIDJSON_DOXYGEN_RUNNING +#define RAPIDJSON_HAS_STDSTRING 1 // force generation of documentation +#else +#define RAPIDJSON_HAS_STDSTRING 0 // no std::string support by default +#endif +/*! \def RAPIDJSON_HAS_STDSTRING + \ingroup RAPIDJSON_CONFIG + \brief Enable RapidJSON support for \c std::string + + By defining this preprocessor symbol to \c 1, several convenience functions for using + \ref rapidjson::GenericValue with \c std::string are enabled, especially + for construction and comparison. + + \hideinitializer +*/ +#endif // !defined(RAPIDJSON_HAS_STDSTRING) + +#if RAPIDJSON_HAS_STDSTRING +#include +#endif // RAPIDJSON_HAS_STDSTRING + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_NO_INT64DEFINE + +/*! \def RAPIDJSON_NO_INT64DEFINE + \ingroup RAPIDJSON_CONFIG + \brief Use external 64-bit integer types. + + RapidJSON requires the 64-bit integer types \c int64_t and \c uint64_t types + to be available at global scope. + + If users have their own definition, define RAPIDJSON_NO_INT64DEFINE to + prevent RapidJSON from defining its own types. +*/ +#ifndef RAPIDJSON_NO_INT64DEFINE +//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN +#if defined(_MSC_VER) && (_MSC_VER < 1800) // Visual Studio 2013 +#include "msinttypes/stdint.h" +#include "msinttypes/inttypes.h" +#else +// Other compilers should have this. +#include +#include +#endif +//!@endcond +#ifdef RAPIDJSON_DOXYGEN_RUNNING +#define RAPIDJSON_NO_INT64DEFINE +#endif +#endif // RAPIDJSON_NO_INT64TYPEDEF + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_FORCEINLINE + +#ifndef RAPIDJSON_FORCEINLINE +//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN +#if defined(_MSC_VER) && defined(NDEBUG) +#define RAPIDJSON_FORCEINLINE __forceinline +#elif defined(__GNUC__) && __GNUC__ >= 4 && defined(NDEBUG) +#define RAPIDJSON_FORCEINLINE __attribute__((always_inline)) +#else +#define RAPIDJSON_FORCEINLINE +#endif +//!@endcond +#endif // RAPIDJSON_FORCEINLINE + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_ENDIAN +#define RAPIDJSON_LITTLEENDIAN 0 //!< Little endian machine +#define RAPIDJSON_BIGENDIAN 1 //!< Big endian machine + +//! Endianness of the machine. +/*! + \def RAPIDJSON_ENDIAN + \ingroup RAPIDJSON_CONFIG + + GCC 4.6 provided macro for detecting endianness of the target machine. But other + compilers may not have this. User can define RAPIDJSON_ENDIAN to either + \ref RAPIDJSON_LITTLEENDIAN or \ref RAPIDJSON_BIGENDIAN. + + Default detection implemented with reference to + \li https://gcc.gnu.org/onlinedocs/gcc-4.6.0/cpp/Common-Predefined-Macros.html + \li http://www.boost.org/doc/libs/1_42_0/boost/detail/endian.hpp +*/ +#ifndef RAPIDJSON_ENDIAN +// Detect with GCC 4.6's macro +# ifdef __BYTE_ORDER__ +# if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +# define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN +# elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ +# define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN +# else +# error Unknown machine endianess detected. User needs to define RAPIDJSON_ENDIAN. +# endif // __BYTE_ORDER__ +// Detect with GLIBC's endian.h +# elif defined(__GLIBC__) +# include +# if (__BYTE_ORDER == __LITTLE_ENDIAN) +# define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN +# elif (__BYTE_ORDER == __BIG_ENDIAN) +# define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN +# else +# error Unknown machine endianess detected. User needs to define RAPIDJSON_ENDIAN. +# endif // __GLIBC__ +// Detect with _LITTLE_ENDIAN and _BIG_ENDIAN macro +# elif defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN) +# define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN +# elif defined(_BIG_ENDIAN) && !defined(_LITTLE_ENDIAN) +# define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN +// Detect with architecture macros +# elif defined(__sparc) || defined(__sparc__) || defined(_POWER) || defined(__powerpc__) || defined(__ppc__) || defined(__hpux) || defined(__hppa) || defined(_MIPSEB) || defined(_POWER) || defined(__s390__) +# define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN +# elif defined(__i386__) || defined(__alpha__) || defined(__ia64) || defined(__ia64__) || defined(_M_IX86) || defined(_M_IA64) || defined(_M_ALPHA) || defined(__amd64) || defined(__amd64__) || defined(_M_AMD64) || defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || defined(__bfin__) +# define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN +# elif defined(_MSC_VER) && defined(_M_ARM) +# define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN +# elif defined(RAPIDJSON_DOXYGEN_RUNNING) +# define RAPIDJSON_ENDIAN +# else +# error Unknown machine endianess detected. User needs to define RAPIDJSON_ENDIAN. +# endif +#endif // RAPIDJSON_ENDIAN + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_64BIT + +//! Whether using 64-bit architecture +#ifndef RAPIDJSON_64BIT +#if defined(__LP64__) || (defined(__x86_64__) && defined(__ILP32__)) || defined(_WIN64) || defined(__EMSCRIPTEN__) +#define RAPIDJSON_64BIT 1 +#else +#define RAPIDJSON_64BIT 0 +#endif +#endif // RAPIDJSON_64BIT + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_ALIGN + +//! Data alignment of the machine. +/*! \ingroup RAPIDJSON_CONFIG + \param x pointer to align + + Some machines require strict data alignment. Currently the default uses 4 bytes + alignment on 32-bit platforms and 8 bytes alignment for 64-bit platforms. + User can customize by defining the RAPIDJSON_ALIGN function macro. +*/ +#ifndef RAPIDJSON_ALIGN +#if RAPIDJSON_64BIT == 1 +#define RAPIDJSON_ALIGN(x) (((x) + static_cast(7u)) & ~static_cast(7u)) +#else +#define RAPIDJSON_ALIGN(x) (((x) + 3u) & ~3u) +#endif +#endif + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_UINT64_C2 + +//! Construct a 64-bit literal by a pair of 32-bit integer. +/*! + 64-bit literal with or without ULL suffix is prone to compiler warnings. + UINT64_C() is C macro which cause compilation problems. + Use this macro to define 64-bit constants by a pair of 32-bit integer. +*/ +#ifndef RAPIDJSON_UINT64_C2 +#define RAPIDJSON_UINT64_C2(high32, low32) ((static_cast(high32) << 32) | static_cast(low32)) +#endif + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_48BITPOINTER_OPTIMIZATION + +//! Use only lower 48-bit address for some pointers. +/*! + \ingroup RAPIDJSON_CONFIG + + This optimization uses the fact that current X86-64 architecture only implement lower 48-bit virtual address. + The higher 16-bit can be used for storing other data. + \c GenericValue uses this optimization to reduce its size form 24 bytes to 16 bytes in 64-bit architecture. +*/ +#ifndef RAPIDJSON_48BITPOINTER_OPTIMIZATION +#if defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64) || defined(_M_X64) || defined(_M_AMD64) +#define RAPIDJSON_48BITPOINTER_OPTIMIZATION 1 +#else +#define RAPIDJSON_48BITPOINTER_OPTIMIZATION 0 +#endif +#endif // RAPIDJSON_48BITPOINTER_OPTIMIZATION + +#if RAPIDJSON_48BITPOINTER_OPTIMIZATION == 1 +#if RAPIDJSON_64BIT != 1 +#error RAPIDJSON_48BITPOINTER_OPTIMIZATION can only be set to 1 when RAPIDJSON_64BIT=1 +#endif +#define RAPIDJSON_SETPOINTER(type, p, x) (p = reinterpret_cast((reinterpret_cast(p) & static_cast(RAPIDJSON_UINT64_C2(0xFFFF0000, 0x00000000))) | reinterpret_cast(reinterpret_cast(x)))) +#define RAPIDJSON_GETPOINTER(type, p) (reinterpret_cast(reinterpret_cast(p) & static_cast(RAPIDJSON_UINT64_C2(0x0000FFFF, 0xFFFFFFFF)))) +#else +#define RAPIDJSON_SETPOINTER(type, p, x) (p = (x)) +#define RAPIDJSON_GETPOINTER(type, p) (p) +#endif + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_SSE2/RAPIDJSON_SSE42/RAPIDJSON_SIMD + +/*! \def RAPIDJSON_SIMD + \ingroup RAPIDJSON_CONFIG + \brief Enable SSE2/SSE4.2 optimization. + + RapidJSON supports optimized implementations for some parsing operations + based on the SSE2 or SSE4.2 SIMD extensions on modern Intel-compatible + processors. + + To enable these optimizations, two different symbols can be defined; + \code + // Enable SSE2 optimization. + #define RAPIDJSON_SSE2 + + // Enable SSE4.2 optimization. + #define RAPIDJSON_SSE42 + \endcode + + \c RAPIDJSON_SSE42 takes precedence, if both are defined. + + If any of these symbols is defined, RapidJSON defines the macro + \c RAPIDJSON_SIMD to indicate the availability of the optimized code. +*/ +#if defined(RAPIDJSON_SSE2) || defined(RAPIDJSON_SSE42) \ + || defined(RAPIDJSON_DOXYGEN_RUNNING) +#define RAPIDJSON_SIMD +#endif + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_NO_SIZETYPEDEFINE + +#ifndef RAPIDJSON_NO_SIZETYPEDEFINE +/*! \def RAPIDJSON_NO_SIZETYPEDEFINE + \ingroup RAPIDJSON_CONFIG + \brief User-provided \c SizeType definition. + + In order to avoid using 32-bit size types for indexing strings and arrays, + define this preprocessor symbol and provide the type rapidjson::SizeType + before including RapidJSON: + \code + #define RAPIDJSON_NO_SIZETYPEDEFINE + namespace rapidjson { typedef ::std::size_t SizeType; } + #include "rapidjson/..." + \endcode + + \see rapidjson::SizeType +*/ +#ifdef RAPIDJSON_DOXYGEN_RUNNING +#define RAPIDJSON_NO_SIZETYPEDEFINE +#endif +RAPIDJSON_NAMESPACE_BEGIN +//! Size type (for string lengths, array sizes, etc.) +/*! RapidJSON uses 32-bit array/string indices even on 64-bit platforms, + instead of using \c size_t. Users may override the SizeType by defining + \ref RAPIDJSON_NO_SIZETYPEDEFINE. +*/ +typedef unsigned SizeType; +RAPIDJSON_NAMESPACE_END +#endif + +// always import std::size_t to rapidjson namespace +RAPIDJSON_NAMESPACE_BEGIN +using std::size_t; +RAPIDJSON_NAMESPACE_END + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_ASSERT + +//! Assertion. +/*! \ingroup RAPIDJSON_CONFIG + By default, rapidjson uses C \c assert() for internal assertions. + User can override it by defining RAPIDJSON_ASSERT(x) macro. + + \note Parsing errors are handled and can be customized by the + \ref RAPIDJSON_ERRORS APIs. +*/ +#ifndef RAPIDJSON_ASSERT +#include +#define RAPIDJSON_ASSERT(x) assert(x) +#endif // RAPIDJSON_ASSERT + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_STATIC_ASSERT + +// Adopt from boost +#ifndef RAPIDJSON_STATIC_ASSERT +#ifndef __clang__ +//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN +#endif +RAPIDJSON_NAMESPACE_BEGIN +template struct STATIC_ASSERTION_FAILURE; +template <> struct STATIC_ASSERTION_FAILURE { enum { value = 1 }; }; +template struct StaticAssertTest {}; +RAPIDJSON_NAMESPACE_END + +#define RAPIDJSON_JOIN(X, Y) RAPIDJSON_DO_JOIN(X, Y) +#define RAPIDJSON_DO_JOIN(X, Y) RAPIDJSON_DO_JOIN2(X, Y) +#define RAPIDJSON_DO_JOIN2(X, Y) X##Y + +#if defined(__GNUC__) +#define RAPIDJSON_STATIC_ASSERT_UNUSED_ATTRIBUTE __attribute__((unused)) +#else +#define RAPIDJSON_STATIC_ASSERT_UNUSED_ATTRIBUTE +#endif +#ifndef __clang__ +//!@endcond +#endif + +/*! \def RAPIDJSON_STATIC_ASSERT + \brief (Internal) macro to check for conditions at compile-time + \param x compile-time condition + \hideinitializer + */ +#define RAPIDJSON_STATIC_ASSERT(x) \ + typedef ::RAPIDJSON_NAMESPACE::StaticAssertTest< \ + sizeof(::RAPIDJSON_NAMESPACE::STATIC_ASSERTION_FAILURE)> \ + RAPIDJSON_JOIN(StaticAssertTypedef, __LINE__) RAPIDJSON_STATIC_ASSERT_UNUSED_ATTRIBUTE +#endif + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_LIKELY, RAPIDJSON_UNLIKELY + +//! Compiler branching hint for expression with high probability to be true. +/*! + \ingroup RAPIDJSON_CONFIG + \param x Boolean expression likely to be true. +*/ +#ifndef RAPIDJSON_LIKELY +#if defined(__GNUC__) || defined(__clang__) +#define RAPIDJSON_LIKELY(x) __builtin_expect(!!(x), 1) +#else +#define RAPIDJSON_LIKELY(x) (x) +#endif +#endif + +//! Compiler branching hint for expression with low probability to be true. +/*! + \ingroup RAPIDJSON_CONFIG + \param x Boolean expression unlikely to be true. +*/ +#ifndef RAPIDJSON_UNLIKELY +#if defined(__GNUC__) || defined(__clang__) +#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0) +#else +#define RAPIDJSON_UNLIKELY(x) (x) +#endif +#endif + +/////////////////////////////////////////////////////////////////////////////// +// Helpers + +//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN + +#define RAPIDJSON_MULTILINEMACRO_BEGIN do { +#define RAPIDJSON_MULTILINEMACRO_END \ +} while((void)0, 0) + +// adopted from Boost +#define RAPIDJSON_VERSION_CODE(x,y,z) \ + (((x)*100000) + ((y)*100) + (z)) + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_DIAG_PUSH/POP, RAPIDJSON_DIAG_OFF + +#if defined(__GNUC__) +#define RAPIDJSON_GNUC \ + RAPIDJSON_VERSION_CODE(__GNUC__,__GNUC_MINOR__,__GNUC_PATCHLEVEL__) +#endif + +#if defined(__clang__) || (defined(RAPIDJSON_GNUC) && RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,2,0)) + +#define RAPIDJSON_PRAGMA(x) _Pragma(RAPIDJSON_STRINGIFY(x)) +#define RAPIDJSON_DIAG_PRAGMA(x) RAPIDJSON_PRAGMA(GCC diagnostic x) +#define RAPIDJSON_DIAG_OFF(x) \ + RAPIDJSON_DIAG_PRAGMA(ignored RAPIDJSON_STRINGIFY(RAPIDJSON_JOIN(-W,x))) + +// push/pop support in Clang and GCC>=4.6 +#if defined(__clang__) || (defined(RAPIDJSON_GNUC) && RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,6,0)) +#define RAPIDJSON_DIAG_PUSH RAPIDJSON_DIAG_PRAGMA(push) +#define RAPIDJSON_DIAG_POP RAPIDJSON_DIAG_PRAGMA(pop) +#else // GCC >= 4.2, < 4.6 +#define RAPIDJSON_DIAG_PUSH /* ignored */ +#define RAPIDJSON_DIAG_POP /* ignored */ +#endif + +#elif defined(_MSC_VER) + +// pragma (MSVC specific) +#define RAPIDJSON_PRAGMA(x) __pragma(x) +#define RAPIDJSON_DIAG_PRAGMA(x) RAPIDJSON_PRAGMA(warning(x)) + +#define RAPIDJSON_DIAG_OFF(x) RAPIDJSON_DIAG_PRAGMA(disable: x) +#define RAPIDJSON_DIAG_PUSH RAPIDJSON_DIAG_PRAGMA(push) +#define RAPIDJSON_DIAG_POP RAPIDJSON_DIAG_PRAGMA(pop) + +#else + +#define RAPIDJSON_DIAG_OFF(x) /* ignored */ +#define RAPIDJSON_DIAG_PUSH /* ignored */ +#define RAPIDJSON_DIAG_POP /* ignored */ + +#endif // RAPIDJSON_DIAG_* + +/////////////////////////////////////////////////////////////////////////////// +// C++11 features + +#ifndef RAPIDJSON_HAS_CXX11_RVALUE_REFS +#if defined(__clang__) +#if __has_feature(cxx_rvalue_references) && \ + (defined(_LIBCPP_VERSION) || defined(__GLIBCXX__) && __GLIBCXX__ >= 20080306) +#define RAPIDJSON_HAS_CXX11_RVALUE_REFS 1 +#else +#define RAPIDJSON_HAS_CXX11_RVALUE_REFS 0 +#endif +#elif (defined(RAPIDJSON_GNUC) && (RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,3,0)) && defined(__GXX_EXPERIMENTAL_CXX0X__)) || \ + (defined(_MSC_VER) && _MSC_VER >= 1600) + +#define RAPIDJSON_HAS_CXX11_RVALUE_REFS 1 +#else +#define RAPIDJSON_HAS_CXX11_RVALUE_REFS 0 +#endif +#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS + +#ifndef RAPIDJSON_HAS_CXX11_NOEXCEPT +#if defined(__clang__) +#define RAPIDJSON_HAS_CXX11_NOEXCEPT __has_feature(cxx_noexcept) +#elif (defined(RAPIDJSON_GNUC) && (RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,6,0)) && defined(__GXX_EXPERIMENTAL_CXX0X__)) +// (defined(_MSC_VER) && _MSC_VER >= ????) // not yet supported +#define RAPIDJSON_HAS_CXX11_NOEXCEPT 1 +#else +#define RAPIDJSON_HAS_CXX11_NOEXCEPT 0 +#endif +#endif +#if RAPIDJSON_HAS_CXX11_NOEXCEPT +#define RAPIDJSON_NOEXCEPT noexcept +#else +#define RAPIDJSON_NOEXCEPT /* noexcept */ +#endif // RAPIDJSON_HAS_CXX11_NOEXCEPT + +// no automatic detection, yet +#ifndef RAPIDJSON_HAS_CXX11_TYPETRAITS +#define RAPIDJSON_HAS_CXX11_TYPETRAITS 0 +#endif + +#ifndef RAPIDJSON_HAS_CXX11_RANGE_FOR +#if defined(__clang__) +#define RAPIDJSON_HAS_CXX11_RANGE_FOR __has_feature(cxx_range_for) +#elif (defined(RAPIDJSON_GNUC) && (RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,3,0)) && defined(__GXX_EXPERIMENTAL_CXX0X__)) || \ + (defined(_MSC_VER) && _MSC_VER >= 1700) +#define RAPIDJSON_HAS_CXX11_RANGE_FOR 1 +#else +#define RAPIDJSON_HAS_CXX11_RANGE_FOR 0 +#endif +#endif // RAPIDJSON_HAS_CXX11_RANGE_FOR + +//!@endcond + +/////////////////////////////////////////////////////////////////////////////// +// new/delete + +#ifndef RAPIDJSON_NEW +///! customization point for global \c new +#define RAPIDJSON_NEW(x) new x +#endif +#ifndef RAPIDJSON_DELETE +///! customization point for global \c delete +#define RAPIDJSON_DELETE(x) delete x +#endif + +/////////////////////////////////////////////////////////////////////////////// +// Type + +/*! \namespace rapidjson + \brief main RapidJSON namespace + \see RAPIDJSON_NAMESPACE +*/ +RAPIDJSON_NAMESPACE_BEGIN + +//! Type of JSON value +enum Type { + kNullType = 0, //!< null + kFalseType = 1, //!< false + kTrueType = 2, //!< true + kObjectType = 3, //!< object + kArrayType = 4, //!< array + kStringType = 5, //!< string + kNumberType = 6 //!< number +}; + +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_RAPIDJSON_H_ diff --git a/slsReceiverSoftware/include/rapidjson/reader.h b/slsReceiverSoftware/include/rapidjson/reader.h new file mode 100644 index 000000000..19f8849b1 --- /dev/null +++ b/slsReceiverSoftware/include/rapidjson/reader.h @@ -0,0 +1,1879 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_READER_H_ +#define RAPIDJSON_READER_H_ + +/*! \file reader.h */ + +#include "allocators.h" +#include "stream.h" +#include "encodedstream.h" +#include "internal/meta.h" +#include "internal/stack.h" +#include "internal/strtod.h" +#include + +#if defined(RAPIDJSON_SIMD) && defined(_MSC_VER) +#include +#pragma intrinsic(_BitScanForward) +#endif +#ifdef RAPIDJSON_SSE42 +#include +#elif defined(RAPIDJSON_SSE2) +#include +#endif + +#ifdef _MSC_VER +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant +RAPIDJSON_DIAG_OFF(4702) // unreachable code +#endif + +#ifdef __clang__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(old-style-cast) +RAPIDJSON_DIAG_OFF(padded) +RAPIDJSON_DIAG_OFF(switch-enum) +#endif + +#ifdef __GNUC__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(effc++) +#endif + +//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN +#define RAPIDJSON_NOTHING /* deliberately empty */ +#ifndef RAPIDJSON_PARSE_ERROR_EARLY_RETURN +#define RAPIDJSON_PARSE_ERROR_EARLY_RETURN(value) \ + RAPIDJSON_MULTILINEMACRO_BEGIN \ + if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \ + RAPIDJSON_MULTILINEMACRO_END +#endif +#define RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID \ + RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING) +//!@endcond + +/*! \def RAPIDJSON_PARSE_ERROR_NORETURN + \ingroup RAPIDJSON_ERRORS + \brief Macro to indicate a parse error. + \param parseErrorCode \ref rapidjson::ParseErrorCode of the error + \param offset position of the error in JSON input (\c size_t) + + This macros can be used as a customization point for the internal + error handling mechanism of RapidJSON. + + A common usage model is to throw an exception instead of requiring the + caller to explicitly check the \ref rapidjson::GenericReader::Parse's + return value: + + \code + #define RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode,offset) \ + throw ParseException(parseErrorCode, #parseErrorCode, offset) + + #include // std::runtime_error + #include "rapidjson/error/error.h" // rapidjson::ParseResult + + struct ParseException : std::runtime_error, rapidjson::ParseResult { + ParseException(rapidjson::ParseErrorCode code, const char* msg, size_t offset) + : std::runtime_error(msg), ParseResult(code, offset) {} + }; + + #include "rapidjson/reader.h" + \endcode + + \see RAPIDJSON_PARSE_ERROR, rapidjson::GenericReader::Parse + */ +#ifndef RAPIDJSON_PARSE_ERROR_NORETURN +#define RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset) \ + RAPIDJSON_MULTILINEMACRO_BEGIN \ + RAPIDJSON_ASSERT(!HasParseError()); /* Error can only be assigned once */ \ + SetParseError(parseErrorCode, offset); \ + RAPIDJSON_MULTILINEMACRO_END +#endif + +/*! \def RAPIDJSON_PARSE_ERROR + \ingroup RAPIDJSON_ERRORS + \brief (Internal) macro to indicate and handle a parse error. + \param parseErrorCode \ref rapidjson::ParseErrorCode of the error + \param offset position of the error in JSON input (\c size_t) + + Invokes RAPIDJSON_PARSE_ERROR_NORETURN and stops the parsing. + + \see RAPIDJSON_PARSE_ERROR_NORETURN + \hideinitializer + */ +#ifndef RAPIDJSON_PARSE_ERROR +#define RAPIDJSON_PARSE_ERROR(parseErrorCode, offset) \ + RAPIDJSON_MULTILINEMACRO_BEGIN \ + RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset); \ + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; \ + RAPIDJSON_MULTILINEMACRO_END +#endif + +#include "error/error.h" // ParseErrorCode, ParseResult + +RAPIDJSON_NAMESPACE_BEGIN + +/////////////////////////////////////////////////////////////////////////////// +// ParseFlag + +/*! \def RAPIDJSON_PARSE_DEFAULT_FLAGS + \ingroup RAPIDJSON_CONFIG + \brief User-defined kParseDefaultFlags definition. + + User can define this as any \c ParseFlag combinations. +*/ +#ifndef RAPIDJSON_PARSE_DEFAULT_FLAGS +#define RAPIDJSON_PARSE_DEFAULT_FLAGS kParseNoFlags +#endif + +//! Combination of parseFlags +/*! \see Reader::Parse, Document::Parse, Document::ParseInsitu, Document::ParseStream + */ +enum ParseFlag { + kParseNoFlags = 0, //!< No flags are set. + kParseInsituFlag = 1, //!< In-situ(destructive) parsing. + kParseValidateEncodingFlag = 2, //!< Validate encoding of JSON strings. + kParseIterativeFlag = 4, //!< Iterative(constant complexity in terms of function call stack size) parsing. + kParseStopWhenDoneFlag = 8, //!< After parsing a complete JSON root from stream, stop further processing the rest of stream. When this flag is used, parser will not generate kParseErrorDocumentRootNotSingular error. + kParseFullPrecisionFlag = 16, //!< Parse number in full precision (but slower). + kParseCommentsFlag = 32, //!< Allow one-line (//) and multi-line (/**/) comments. + kParseNumbersAsStringsFlag = 64, //!< Parse all numbers (ints/doubles) as strings. + kParseTrailingCommasFlag = 128, //!< Allow trailing commas at the end of objects and arrays. + kParseNanAndInfFlag = 256, //!< Allow parsing NaN, Inf, Infinity, -Inf and -Infinity as doubles. + kParseDefaultFlags = RAPIDJSON_PARSE_DEFAULT_FLAGS //!< Default parse flags. Can be customized by defining RAPIDJSON_PARSE_DEFAULT_FLAGS +}; + +/////////////////////////////////////////////////////////////////////////////// +// Handler + +/*! \class rapidjson::Handler + \brief Concept for receiving events from GenericReader upon parsing. + The functions return true if no error occurs. If they return false, + the event publisher should terminate the process. +\code +concept Handler { + typename Ch; + + bool Null(); + bool Bool(bool b); + bool Int(int i); + bool Uint(unsigned i); + bool Int64(int64_t i); + bool Uint64(uint64_t i); + bool Double(double d); + /// enabled via kParseNumbersAsStringsFlag, string is not null-terminated (use length) + bool RawNumber(const Ch* str, SizeType length, bool copy); + bool String(const Ch* str, SizeType length, bool copy); + bool StartObject(); + bool Key(const Ch* str, SizeType length, bool copy); + bool EndObject(SizeType memberCount); + bool StartArray(); + bool EndArray(SizeType elementCount); +}; +\endcode +*/ +/////////////////////////////////////////////////////////////////////////////// +// BaseReaderHandler + +//! Default implementation of Handler. +/*! This can be used as base class of any reader handler. + \note implements Handler concept +*/ +template, typename Derived = void> +struct BaseReaderHandler { + typedef typename Encoding::Ch Ch; + + typedef typename internal::SelectIf, BaseReaderHandler, Derived>::Type Override; + + bool Default() { return true; } + bool Null() { return static_cast(*this).Default(); } + bool Bool(bool) { return static_cast(*this).Default(); } + bool Int(int) { return static_cast(*this).Default(); } + bool Uint(unsigned) { return static_cast(*this).Default(); } + bool Int64(int64_t) { return static_cast(*this).Default(); } + bool Uint64(uint64_t) { return static_cast(*this).Default(); } + bool Double(double) { return static_cast(*this).Default(); } + /// enabled via kParseNumbersAsStringsFlag, string is not null-terminated (use length) + bool RawNumber(const Ch* str, SizeType len, bool copy) { return static_cast(*this).String(str, len, copy); } + bool String(const Ch*, SizeType, bool) { return static_cast(*this).Default(); } + bool StartObject() { return static_cast(*this).Default(); } + bool Key(const Ch* str, SizeType len, bool copy) { return static_cast(*this).String(str, len, copy); } + bool EndObject(SizeType) { return static_cast(*this).Default(); } + bool StartArray() { return static_cast(*this).Default(); } + bool EndArray(SizeType) { return static_cast(*this).Default(); } +}; + +/////////////////////////////////////////////////////////////////////////////// +// StreamLocalCopy + +namespace internal { + +template::copyOptimization> +class StreamLocalCopy; + +//! Do copy optimization. +template +class StreamLocalCopy { +public: + StreamLocalCopy(Stream& original) : s(original), original_(original) {} + ~StreamLocalCopy() { original_ = s; } + + Stream s; + +private: + StreamLocalCopy& operator=(const StreamLocalCopy&) /* = delete */; + + Stream& original_; +}; + +//! Keep reference. +template +class StreamLocalCopy { +public: + StreamLocalCopy(Stream& original) : s(original) {} + + Stream& s; + +private: + StreamLocalCopy& operator=(const StreamLocalCopy&) /* = delete */; +}; + +} // namespace internal + +/////////////////////////////////////////////////////////////////////////////// +// SkipWhitespace + +//! Skip the JSON white spaces in a stream. +/*! \param is A input stream for skipping white spaces. + \note This function has SSE2/SSE4.2 specialization. +*/ +template +void SkipWhitespace(InputStream& is) { + internal::StreamLocalCopy copy(is); + InputStream& s(copy.s); + + typename InputStream::Ch c; + while ((c = s.Peek()) == ' ' || c == '\n' || c == '\r' || c == '\t') + s.Take(); +} + +inline const char* SkipWhitespace(const char* p, const char* end) { + while (p != end && (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t')) + ++p; + return p; +} + +#ifdef RAPIDJSON_SSE42 +//! Skip whitespace with SSE 4.2 pcmpistrm instruction, testing 16 8-byte characters at once. +inline const char *SkipWhitespace_SIMD(const char* p) { + // Fast return for single non-whitespace + if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t') + ++p; + else + return p; + + // 16-byte align to the next boundary + const char* nextAligned = reinterpret_cast((reinterpret_cast(p) + 15) & static_cast(~15)); + while (p != nextAligned) + if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t') + ++p; + else + return p; + + // The rest of string using SIMD + static const char whitespace[16] = " \n\r\t"; + const __m128i w = _mm_loadu_si128(reinterpret_cast(&whitespace[0])); + + for (;; p += 16) { + const __m128i s = _mm_load_si128(reinterpret_cast(p)); + const int r = _mm_cvtsi128_si32(_mm_cmpistrm(w, s, _SIDD_UBYTE_OPS | _SIDD_CMP_EQUAL_ANY | _SIDD_BIT_MASK | _SIDD_NEGATIVE_POLARITY)); + if (r != 0) { // some of characters is non-whitespace +#ifdef _MSC_VER // Find the index of first non-whitespace + unsigned long offset; + _BitScanForward(&offset, r); + return p + offset; +#else + return p + __builtin_ffs(r) - 1; +#endif + } + } +} + +inline const char *SkipWhitespace_SIMD(const char* p, const char* end) { + // Fast return for single non-whitespace + if (p != end && (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t')) + ++p; + else + return p; + + // The middle of string using SIMD + static const char whitespace[16] = " \n\r\t"; + const __m128i w = _mm_loadu_si128(reinterpret_cast(&whitespace[0])); + + for (; p <= end - 16; p += 16) { + const __m128i s = _mm_loadu_si128(reinterpret_cast(p)); + const int r = _mm_cvtsi128_si32(_mm_cmpistrm(w, s, _SIDD_UBYTE_OPS | _SIDD_CMP_EQUAL_ANY | _SIDD_BIT_MASK | _SIDD_NEGATIVE_POLARITY)); + if (r != 0) { // some of characters is non-whitespace +#ifdef _MSC_VER // Find the index of first non-whitespace + unsigned long offset; + _BitScanForward(&offset, r); + return p + offset; +#else + return p + __builtin_ffs(r) - 1; +#endif + } + } + + return SkipWhitespace(p, end); +} + +#elif defined(RAPIDJSON_SSE2) + +//! Skip whitespace with SSE2 instructions, testing 16 8-byte characters at once. +inline const char *SkipWhitespace_SIMD(const char* p) { + // Fast return for single non-whitespace + if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t') + ++p; + else + return p; + + // 16-byte align to the next boundary + const char* nextAligned = reinterpret_cast((reinterpret_cast(p) + 15) & static_cast(~15)); + while (p != nextAligned) + if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t') + ++p; + else + return p; + + // The rest of string + #define C16(c) { c, c, c, c, c, c, c, c, c, c, c, c, c, c, c, c } + static const char whitespaces[4][16] = { C16(' '), C16('\n'), C16('\r'), C16('\t') }; + #undef C16 + + const __m128i w0 = _mm_loadu_si128(reinterpret_cast(&whitespaces[0][0])); + const __m128i w1 = _mm_loadu_si128(reinterpret_cast(&whitespaces[1][0])); + const __m128i w2 = _mm_loadu_si128(reinterpret_cast(&whitespaces[2][0])); + const __m128i w3 = _mm_loadu_si128(reinterpret_cast(&whitespaces[3][0])); + + for (;; p += 16) { + const __m128i s = _mm_load_si128(reinterpret_cast(p)); + __m128i x = _mm_cmpeq_epi8(s, w0); + x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w1)); + x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w2)); + x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w3)); + unsigned short r = static_cast(~_mm_movemask_epi8(x)); + if (r != 0) { // some of characters may be non-whitespace +#ifdef _MSC_VER // Find the index of first non-whitespace + unsigned long offset; + _BitScanForward(&offset, r); + return p + offset; +#else + return p + __builtin_ffs(r) - 1; +#endif + } + } +} + +inline const char *SkipWhitespace_SIMD(const char* p, const char* end) { + // Fast return for single non-whitespace + if (p != end && (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t')) + ++p; + else + return p; + + // The rest of string + #define C16(c) { c, c, c, c, c, c, c, c, c, c, c, c, c, c, c, c } + static const char whitespaces[4][16] = { C16(' '), C16('\n'), C16('\r'), C16('\t') }; + #undef C16 + + const __m128i w0 = _mm_loadu_si128(reinterpret_cast(&whitespaces[0][0])); + const __m128i w1 = _mm_loadu_si128(reinterpret_cast(&whitespaces[1][0])); + const __m128i w2 = _mm_loadu_si128(reinterpret_cast(&whitespaces[2][0])); + const __m128i w3 = _mm_loadu_si128(reinterpret_cast(&whitespaces[3][0])); + + for (; p <= end - 16; p += 16) { + const __m128i s = _mm_loadu_si128(reinterpret_cast(p)); + __m128i x = _mm_cmpeq_epi8(s, w0); + x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w1)); + x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w2)); + x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w3)); + unsigned short r = static_cast(~_mm_movemask_epi8(x)); + if (r != 0) { // some of characters may be non-whitespace +#ifdef _MSC_VER // Find the index of first non-whitespace + unsigned long offset; + _BitScanForward(&offset, r); + return p + offset; +#else + return p + __builtin_ffs(r) - 1; +#endif + } + } + + return SkipWhitespace(p, end); +} + +#endif // RAPIDJSON_SSE2 + +#ifdef RAPIDJSON_SIMD +//! Template function specialization for InsituStringStream +template<> inline void SkipWhitespace(InsituStringStream& is) { + is.src_ = const_cast(SkipWhitespace_SIMD(is.src_)); +} + +//! Template function specialization for StringStream +template<> inline void SkipWhitespace(StringStream& is) { + is.src_ = SkipWhitespace_SIMD(is.src_); +} + +template<> inline void SkipWhitespace(EncodedInputStream, MemoryStream>& is) { + is.is_.src_ = SkipWhitespace_SIMD(is.is_.src_, is.is_.end_); +} +#endif // RAPIDJSON_SIMD + +/////////////////////////////////////////////////////////////////////////////// +// GenericReader + +//! SAX-style JSON parser. Use \ref Reader for UTF8 encoding and default allocator. +/*! GenericReader parses JSON text from a stream, and send events synchronously to an + object implementing Handler concept. + + It needs to allocate a stack for storing a single decoded string during + non-destructive parsing. + + For in-situ parsing, the decoded string is directly written to the source + text string, no temporary buffer is required. + + A GenericReader object can be reused for parsing multiple JSON text. + + \tparam SourceEncoding Encoding of the input stream. + \tparam TargetEncoding Encoding of the parse output. + \tparam StackAllocator Allocator type for stack. +*/ +template +class GenericReader { +public: + typedef typename SourceEncoding::Ch Ch; //!< SourceEncoding character type + + //! Constructor. + /*! \param stackAllocator Optional allocator for allocating stack memory. (Only use for non-destructive parsing) + \param stackCapacity stack capacity in bytes for storing a single decoded string. (Only use for non-destructive parsing) + */ + GenericReader(StackAllocator* stackAllocator = 0, size_t stackCapacity = kDefaultStackCapacity) : stack_(stackAllocator, stackCapacity), parseResult_() {} + + //! Parse JSON text. + /*! \tparam parseFlags Combination of \ref ParseFlag. + \tparam InputStream Type of input stream, implementing Stream concept. + \tparam Handler Type of handler, implementing Handler concept. + \param is Input stream to be parsed. + \param handler The handler to receive events. + \return Whether the parsing is successful. + */ + template + ParseResult Parse(InputStream& is, Handler& handler) { + if (parseFlags & kParseIterativeFlag) + return IterativeParse(is, handler); + + parseResult_.Clear(); + + ClearStackOnExit scope(*this); + + SkipWhitespaceAndComments(is); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_); + + if (RAPIDJSON_UNLIKELY(is.Peek() == '\0')) { + RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorDocumentEmpty, is.Tell()); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_); + } + else { + ParseValue(is, handler); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_); + + if (!(parseFlags & kParseStopWhenDoneFlag)) { + SkipWhitespaceAndComments(is); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_); + + if (RAPIDJSON_UNLIKELY(is.Peek() != '\0')) { + RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorDocumentRootNotSingular, is.Tell()); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_); + } + } + } + + return parseResult_; + } + + //! Parse JSON text (with \ref kParseDefaultFlags) + /*! \tparam InputStream Type of input stream, implementing Stream concept + \tparam Handler Type of handler, implementing Handler concept. + \param is Input stream to be parsed. + \param handler The handler to receive events. + \return Whether the parsing is successful. + */ + template + ParseResult Parse(InputStream& is, Handler& handler) { + return Parse(is, handler); + } + + //! Whether a parse error has occured in the last parsing. + bool HasParseError() const { return parseResult_.IsError(); } + + //! Get the \ref ParseErrorCode of last parsing. + ParseErrorCode GetParseErrorCode() const { return parseResult_.Code(); } + + //! Get the position of last parsing error in input, 0 otherwise. + size_t GetErrorOffset() const { return parseResult_.Offset(); } + +protected: + void SetParseError(ParseErrorCode code, size_t offset) { parseResult_.Set(code, offset); } + +private: + // Prohibit copy constructor & assignment operator. + GenericReader(const GenericReader&); + GenericReader& operator=(const GenericReader&); + + void ClearStack() { stack_.Clear(); } + + // clear stack on any exit from ParseStream, e.g. due to exception + struct ClearStackOnExit { + explicit ClearStackOnExit(GenericReader& r) : r_(r) {} + ~ClearStackOnExit() { r_.ClearStack(); } + private: + GenericReader& r_; + ClearStackOnExit(const ClearStackOnExit&); + ClearStackOnExit& operator=(const ClearStackOnExit&); + }; + + template + void SkipWhitespaceAndComments(InputStream& is) { + SkipWhitespace(is); + + if (parseFlags & kParseCommentsFlag) { + while (RAPIDJSON_UNLIKELY(Consume(is, '/'))) { + if (Consume(is, '*')) { + while (true) { + if (RAPIDJSON_UNLIKELY(is.Peek() == '\0')) + RAPIDJSON_PARSE_ERROR(kParseErrorUnspecificSyntaxError, is.Tell()); + else if (Consume(is, '*')) { + if (Consume(is, '/')) + break; + } + else + is.Take(); + } + } + else if (RAPIDJSON_LIKELY(Consume(is, '/'))) + while (is.Peek() != '\0' && is.Take() != '\n'); + else + RAPIDJSON_PARSE_ERROR(kParseErrorUnspecificSyntaxError, is.Tell()); + + SkipWhitespace(is); + } + } + } + + // Parse object: { string : value, ... } + template + void ParseObject(InputStream& is, Handler& handler) { + RAPIDJSON_ASSERT(is.Peek() == '{'); + is.Take(); // Skip '{' + + if (RAPIDJSON_UNLIKELY(!handler.StartObject())) + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); + + SkipWhitespaceAndComments(is); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; + + if (Consume(is, '}')) { + if (RAPIDJSON_UNLIKELY(!handler.EndObject(0))) // empty object + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); + return; + } + + for (SizeType memberCount = 0;;) { + if (RAPIDJSON_UNLIKELY(is.Peek() != '"')) + RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissName, is.Tell()); + + ParseString(is, handler, true); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; + + SkipWhitespaceAndComments(is); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; + + if (RAPIDJSON_UNLIKELY(!Consume(is, ':'))) + RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissColon, is.Tell()); + + SkipWhitespaceAndComments(is); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; + + ParseValue(is, handler); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; + + SkipWhitespaceAndComments(is); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; + + ++memberCount; + + switch (is.Peek()) { + case ',': + is.Take(); + SkipWhitespaceAndComments(is); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; + break; + case '}': + is.Take(); + if (RAPIDJSON_UNLIKELY(!handler.EndObject(memberCount))) + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); + return; + default: + RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissCommaOrCurlyBracket, is.Tell()); break; // This useless break is only for making warning and coverage happy + } + + if (parseFlags & kParseTrailingCommasFlag) { + if (is.Peek() == '}') { + if (RAPIDJSON_UNLIKELY(!handler.EndObject(memberCount))) + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); + is.Take(); + return; + } + } + } + } + + // Parse array: [ value, ... ] + template + void ParseArray(InputStream& is, Handler& handler) { + RAPIDJSON_ASSERT(is.Peek() == '['); + is.Take(); // Skip '[' + + if (RAPIDJSON_UNLIKELY(!handler.StartArray())) + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); + + SkipWhitespaceAndComments(is); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; + + if (Consume(is, ']')) { + if (RAPIDJSON_UNLIKELY(!handler.EndArray(0))) // empty array + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); + return; + } + + for (SizeType elementCount = 0;;) { + ParseValue(is, handler); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; + + ++elementCount; + SkipWhitespaceAndComments(is); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; + + if (Consume(is, ',')) { + SkipWhitespaceAndComments(is); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; + } + else if (Consume(is, ']')) { + if (RAPIDJSON_UNLIKELY(!handler.EndArray(elementCount))) + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); + return; + } + else + RAPIDJSON_PARSE_ERROR(kParseErrorArrayMissCommaOrSquareBracket, is.Tell()); + + if (parseFlags & kParseTrailingCommasFlag) { + if (is.Peek() == ']') { + if (RAPIDJSON_UNLIKELY(!handler.EndArray(elementCount))) + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); + is.Take(); + return; + } + } + } + } + + template + void ParseNull(InputStream& is, Handler& handler) { + RAPIDJSON_ASSERT(is.Peek() == 'n'); + is.Take(); + + if (RAPIDJSON_LIKELY(Consume(is, 'u') && Consume(is, 'l') && Consume(is, 'l'))) { + if (RAPIDJSON_UNLIKELY(!handler.Null())) + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); + } + else + RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell()); + } + + template + void ParseTrue(InputStream& is, Handler& handler) { + RAPIDJSON_ASSERT(is.Peek() == 't'); + is.Take(); + + if (RAPIDJSON_LIKELY(Consume(is, 'r') && Consume(is, 'u') && Consume(is, 'e'))) { + if (RAPIDJSON_UNLIKELY(!handler.Bool(true))) + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); + } + else + RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell()); + } + + template + void ParseFalse(InputStream& is, Handler& handler) { + RAPIDJSON_ASSERT(is.Peek() == 'f'); + is.Take(); + + if (RAPIDJSON_LIKELY(Consume(is, 'a') && Consume(is, 'l') && Consume(is, 's') && Consume(is, 'e'))) { + if (RAPIDJSON_UNLIKELY(!handler.Bool(false))) + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); + } + else + RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell()); + } + + template + RAPIDJSON_FORCEINLINE static bool Consume(InputStream& is, typename InputStream::Ch expect) { + if (RAPIDJSON_LIKELY(is.Peek() == expect)) { + is.Take(); + return true; + } + else + return false; + } + + // Helper function to parse four hexidecimal digits in \uXXXX in ParseString(). + template + unsigned ParseHex4(InputStream& is, size_t escapeOffset) { + unsigned codepoint = 0; + for (int i = 0; i < 4; i++) { + Ch c = is.Peek(); + codepoint <<= 4; + codepoint += static_cast(c); + if (c >= '0' && c <= '9') + codepoint -= '0'; + else if (c >= 'A' && c <= 'F') + codepoint -= 'A' - 10; + else if (c >= 'a' && c <= 'f') + codepoint -= 'a' - 10; + else { + RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorStringUnicodeEscapeInvalidHex, escapeOffset); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN(0); + } + is.Take(); + } + return codepoint; + } + + template + class StackStream { + public: + typedef CharType Ch; + + StackStream(internal::Stack& stack) : stack_(stack), length_(0) {} + RAPIDJSON_FORCEINLINE void Put(Ch c) { + *stack_.template Push() = c; + ++length_; + } + + RAPIDJSON_FORCEINLINE void* Push(SizeType count) { + length_ += count; + return stack_.template Push(count); + } + + size_t Length() const { return length_; } + + Ch* Pop() { + return stack_.template Pop(length_); + } + + private: + StackStream(const StackStream&); + StackStream& operator=(const StackStream&); + + internal::Stack& stack_; + SizeType length_; + }; + + // Parse string and generate String event. Different code paths for kParseInsituFlag. + template + void ParseString(InputStream& is, Handler& handler, bool isKey = false) { + internal::StreamLocalCopy copy(is); + InputStream& s(copy.s); + + RAPIDJSON_ASSERT(s.Peek() == '\"'); + s.Take(); // Skip '\"' + + bool success = false; + if (parseFlags & kParseInsituFlag) { + typename InputStream::Ch *head = s.PutBegin(); + ParseStringToStream(s, s); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; + size_t length = s.PutEnd(head) - 1; + RAPIDJSON_ASSERT(length <= 0xFFFFFFFF); + const typename TargetEncoding::Ch* const str = reinterpret_cast(head); + success = (isKey ? handler.Key(str, SizeType(length), false) : handler.String(str, SizeType(length), false)); + } + else { + StackStream stackStream(stack_); + ParseStringToStream(s, stackStream); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; + SizeType length = static_cast(stackStream.Length()) - 1; + const typename TargetEncoding::Ch* const str = stackStream.Pop(); + success = (isKey ? handler.Key(str, length, true) : handler.String(str, length, true)); + } + if (RAPIDJSON_UNLIKELY(!success)) + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, s.Tell()); + } + + // Parse string to an output is + // This function handles the prefix/suffix double quotes, escaping, and optional encoding validation. + template + RAPIDJSON_FORCEINLINE void ParseStringToStream(InputStream& is, OutputStream& os) { +//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN +#define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + static const char escape[256] = { + Z16, Z16, 0, 0,'\"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'/', + Z16, Z16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'\\', 0, 0, 0, + 0, 0,'\b', 0, 0, 0,'\f', 0, 0, 0, 0, 0, 0, 0,'\n', 0, + 0, 0,'\r', 0,'\t', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16 + }; +#undef Z16 +//!@endcond + + for (;;) { + // Scan and copy string before "\\\"" or < 0x20. This is an optional optimzation. + if (!(parseFlags & kParseValidateEncodingFlag)) + ScanCopyUnescapedString(is, os); + + Ch c = is.Peek(); + if (RAPIDJSON_UNLIKELY(c == '\\')) { // Escape + size_t escapeOffset = is.Tell(); // For invalid escaping, report the inital '\\' as error offset + is.Take(); + Ch e = is.Peek(); + if ((sizeof(Ch) == 1 || unsigned(e) < 256) && RAPIDJSON_LIKELY(escape[static_cast(e)])) { + is.Take(); + os.Put(static_cast(escape[static_cast(e)])); + } + else if (RAPIDJSON_LIKELY(e == 'u')) { // Unicode + is.Take(); + unsigned codepoint = ParseHex4(is, escapeOffset); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; + if (RAPIDJSON_UNLIKELY(codepoint >= 0xD800 && codepoint <= 0xDBFF)) { + // Handle UTF-16 surrogate pair + if (RAPIDJSON_UNLIKELY(!Consume(is, '\\') || !Consume(is, 'u'))) + RAPIDJSON_PARSE_ERROR(kParseErrorStringUnicodeSurrogateInvalid, escapeOffset); + unsigned codepoint2 = ParseHex4(is, escapeOffset); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; + if (RAPIDJSON_UNLIKELY(codepoint2 < 0xDC00 || codepoint2 > 0xDFFF)) + RAPIDJSON_PARSE_ERROR(kParseErrorStringUnicodeSurrogateInvalid, escapeOffset); + codepoint = (((codepoint - 0xD800) << 10) | (codepoint2 - 0xDC00)) + 0x10000; + } + TEncoding::Encode(os, codepoint); + } + else + RAPIDJSON_PARSE_ERROR(kParseErrorStringEscapeInvalid, escapeOffset); + } + else if (RAPIDJSON_UNLIKELY(c == '"')) { // Closing double quote + is.Take(); + os.Put('\0'); // null-terminate the string + return; + } + else if (RAPIDJSON_UNLIKELY(static_cast(c) < 0x20)) { // RFC 4627: unescaped = %x20-21 / %x23-5B / %x5D-10FFFF + if (c == '\0') + RAPIDJSON_PARSE_ERROR(kParseErrorStringMissQuotationMark, is.Tell()); + else + RAPIDJSON_PARSE_ERROR(kParseErrorStringEscapeInvalid, is.Tell()); + } + else { + size_t offset = is.Tell(); + if (RAPIDJSON_UNLIKELY((parseFlags & kParseValidateEncodingFlag ? + !Transcoder::Validate(is, os) : + !Transcoder::Transcode(is, os)))) + RAPIDJSON_PARSE_ERROR(kParseErrorStringInvalidEncoding, offset); + } + } + } + + template + static RAPIDJSON_FORCEINLINE void ScanCopyUnescapedString(InputStream&, OutputStream&) { + // Do nothing for generic version + } + +#if defined(RAPIDJSON_SSE2) || defined(RAPIDJSON_SSE42) + // StringStream -> StackStream + static RAPIDJSON_FORCEINLINE void ScanCopyUnescapedString(StringStream& is, StackStream& os) { + const char* p = is.src_; + + // Scan one by one until alignment (unaligned load may cross page boundary and cause crash) + const char* nextAligned = reinterpret_cast((reinterpret_cast(p) + 15) & static_cast(~15)); + while (p != nextAligned) + if (RAPIDJSON_UNLIKELY(*p == '\"') || RAPIDJSON_UNLIKELY(*p == '\\') || RAPIDJSON_UNLIKELY(static_cast(*p) < 0x20)) { + is.src_ = p; + return; + } + else + os.Put(*p++); + + // The rest of string using SIMD + static const char dquote[16] = { '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"' }; + static const char bslash[16] = { '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\' }; + static const char space[16] = { 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19 }; + const __m128i dq = _mm_loadu_si128(reinterpret_cast(&dquote[0])); + const __m128i bs = _mm_loadu_si128(reinterpret_cast(&bslash[0])); + const __m128i sp = _mm_loadu_si128(reinterpret_cast(&space[0])); + + for (;; p += 16) { + const __m128i s = _mm_load_si128(reinterpret_cast(p)); + const __m128i t1 = _mm_cmpeq_epi8(s, dq); + const __m128i t2 = _mm_cmpeq_epi8(s, bs); + const __m128i t3 = _mm_cmpeq_epi8(_mm_max_epu8(s, sp), sp); // s < 0x20 <=> max(s, 0x19) == 0x19 + const __m128i x = _mm_or_si128(_mm_or_si128(t1, t2), t3); + unsigned short r = static_cast(_mm_movemask_epi8(x)); + if (RAPIDJSON_UNLIKELY(r != 0)) { // some of characters is escaped + SizeType length; + #ifdef _MSC_VER // Find the index of first escaped + unsigned long offset; + _BitScanForward(&offset, r); + length = offset; + #else + length = static_cast(__builtin_ffs(r) - 1); + #endif + char* q = reinterpret_cast(os.Push(length)); + for (size_t i = 0; i < length; i++) + q[i] = p[i]; + + p += length; + break; + } + _mm_storeu_si128(reinterpret_cast<__m128i *>(os.Push(16)), s); + } + + is.src_ = p; + } + + // InsituStringStream -> InsituStringStream + static RAPIDJSON_FORCEINLINE void ScanCopyUnescapedString(InsituStringStream& is, InsituStringStream& os) { + RAPIDJSON_ASSERT(&is == &os); + (void)os; + + if (is.src_ == is.dst_) { + SkipUnescapedString(is); + return; + } + + char* p = is.src_; + char *q = is.dst_; + + // Scan one by one until alignment (unaligned load may cross page boundary and cause crash) + const char* nextAligned = reinterpret_cast((reinterpret_cast(p) + 15) & static_cast(~15)); + while (p != nextAligned) + if (RAPIDJSON_UNLIKELY(*p == '\"') || RAPIDJSON_UNLIKELY(*p == '\\') || RAPIDJSON_UNLIKELY(static_cast(*p) < 0x20)) { + is.src_ = p; + is.dst_ = q; + return; + } + else + *q++ = *p++; + + // The rest of string using SIMD + static const char dquote[16] = { '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"' }; + static const char bslash[16] = { '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\' }; + static const char space[16] = { 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19 }; + const __m128i dq = _mm_loadu_si128(reinterpret_cast(&dquote[0])); + const __m128i bs = _mm_loadu_si128(reinterpret_cast(&bslash[0])); + const __m128i sp = _mm_loadu_si128(reinterpret_cast(&space[0])); + + for (;; p += 16, q += 16) { + const __m128i s = _mm_load_si128(reinterpret_cast(p)); + const __m128i t1 = _mm_cmpeq_epi8(s, dq); + const __m128i t2 = _mm_cmpeq_epi8(s, bs); + const __m128i t3 = _mm_cmpeq_epi8(_mm_max_epu8(s, sp), sp); // s < 0x20 <=> max(s, 0x19) == 0x19 + const __m128i x = _mm_or_si128(_mm_or_si128(t1, t2), t3); + unsigned short r = static_cast(_mm_movemask_epi8(x)); + if (RAPIDJSON_UNLIKELY(r != 0)) { // some of characters is escaped + size_t length; +#ifdef _MSC_VER // Find the index of first escaped + unsigned long offset; + _BitScanForward(&offset, r); + length = offset; +#else + length = static_cast(__builtin_ffs(r) - 1); +#endif + for (const char* pend = p + length; p != pend; ) + *q++ = *p++; + break; + } + _mm_storeu_si128(reinterpret_cast<__m128i *>(q), s); + } + + is.src_ = p; + is.dst_ = q; + } + + // When read/write pointers are the same for insitu stream, just skip unescaped characters + static RAPIDJSON_FORCEINLINE void SkipUnescapedString(InsituStringStream& is) { + RAPIDJSON_ASSERT(is.src_ == is.dst_); + char* p = is.src_; + + // Scan one by one until alignment (unaligned load may cross page boundary and cause crash) + const char* nextAligned = reinterpret_cast((reinterpret_cast(p) + 15) & static_cast(~15)); + for (; p != nextAligned; p++) + if (RAPIDJSON_UNLIKELY(*p == '\"') || RAPIDJSON_UNLIKELY(*p == '\\') || RAPIDJSON_UNLIKELY(static_cast(*p) < 0x20)) { + is.src_ = is.dst_ = p; + return; + } + + // The rest of string using SIMD + static const char dquote[16] = { '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"' }; + static const char bslash[16] = { '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\' }; + static const char space[16] = { 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19 }; + const __m128i dq = _mm_loadu_si128(reinterpret_cast(&dquote[0])); + const __m128i bs = _mm_loadu_si128(reinterpret_cast(&bslash[0])); + const __m128i sp = _mm_loadu_si128(reinterpret_cast(&space[0])); + + for (;; p += 16) { + const __m128i s = _mm_load_si128(reinterpret_cast(p)); + const __m128i t1 = _mm_cmpeq_epi8(s, dq); + const __m128i t2 = _mm_cmpeq_epi8(s, bs); + const __m128i t3 = _mm_cmpeq_epi8(_mm_max_epu8(s, sp), sp); // s < 0x20 <=> max(s, 0x19) == 0x19 + const __m128i x = _mm_or_si128(_mm_or_si128(t1, t2), t3); + unsigned short r = static_cast(_mm_movemask_epi8(x)); + if (RAPIDJSON_UNLIKELY(r != 0)) { // some of characters is escaped + size_t length; +#ifdef _MSC_VER // Find the index of first escaped + unsigned long offset; + _BitScanForward(&offset, r); + length = offset; +#else + length = static_cast(__builtin_ffs(r) - 1); +#endif + p += length; + break; + } + } + + is.src_ = is.dst_ = p; + } +#endif + + template + class NumberStream; + + template + class NumberStream { + public: + typedef typename InputStream::Ch Ch; + + NumberStream(GenericReader& reader, InputStream& s) : is(s) { (void)reader; } + ~NumberStream() {} + + RAPIDJSON_FORCEINLINE Ch Peek() const { return is.Peek(); } + RAPIDJSON_FORCEINLINE Ch TakePush() { return is.Take(); } + RAPIDJSON_FORCEINLINE Ch Take() { return is.Take(); } + RAPIDJSON_FORCEINLINE void Push(char) {} + + size_t Tell() { return is.Tell(); } + size_t Length() { return 0; } + const char* Pop() { return 0; } + + protected: + NumberStream& operator=(const NumberStream&); + + InputStream& is; + }; + + template + class NumberStream : public NumberStream { + typedef NumberStream Base; + public: + NumberStream(GenericReader& reader, InputStream& is) : Base(reader, is), stackStream(reader.stack_) {} + ~NumberStream() {} + + RAPIDJSON_FORCEINLINE Ch TakePush() { + stackStream.Put(static_cast(Base::is.Peek())); + return Base::is.Take(); + } + + RAPIDJSON_FORCEINLINE void Push(char c) { + stackStream.Put(c); + } + + size_t Length() { return stackStream.Length(); } + + const char* Pop() { + stackStream.Put('\0'); + return stackStream.Pop(); + } + + private: + StackStream stackStream; + }; + + template + class NumberStream : public NumberStream { + typedef NumberStream Base; + public: + NumberStream(GenericReader& reader, InputStream& is) : Base(reader, is) {} + ~NumberStream() {} + + RAPIDJSON_FORCEINLINE Ch Take() { return Base::TakePush(); } + }; + + template + void ParseNumber(InputStream& is, Handler& handler) { + internal::StreamLocalCopy copy(is); + NumberStream s(*this, copy.s); + + size_t startOffset = s.Tell(); + double d = 0.0; + bool useNanOrInf = false; + + // Parse minus + bool minus = Consume(s, '-'); + + // Parse int: zero / ( digit1-9 *DIGIT ) + unsigned i = 0; + uint64_t i64 = 0; + bool use64bit = false; + int significandDigit = 0; + if (RAPIDJSON_UNLIKELY(s.Peek() == '0')) { + i = 0; + s.TakePush(); + } + else if (RAPIDJSON_LIKELY(s.Peek() >= '1' && s.Peek() <= '9')) { + i = static_cast(s.TakePush() - '0'); + + if (minus) + while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) { + if (RAPIDJSON_UNLIKELY(i >= 214748364)) { // 2^31 = 2147483648 + if (RAPIDJSON_LIKELY(i != 214748364 || s.Peek() > '8')) { + i64 = i; + use64bit = true; + break; + } + } + i = i * 10 + static_cast(s.TakePush() - '0'); + significandDigit++; + } + else + while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) { + if (RAPIDJSON_UNLIKELY(i >= 429496729)) { // 2^32 - 1 = 4294967295 + if (RAPIDJSON_LIKELY(i != 429496729 || s.Peek() > '5')) { + i64 = i; + use64bit = true; + break; + } + } + i = i * 10 + static_cast(s.TakePush() - '0'); + significandDigit++; + } + } + // Parse NaN or Infinity here + else if ((parseFlags & kParseNanAndInfFlag) && RAPIDJSON_LIKELY((s.Peek() == 'I' || s.Peek() == 'N'))) { + useNanOrInf = true; + if (RAPIDJSON_LIKELY(Consume(s, 'N') && Consume(s, 'a') && Consume(s, 'N'))) { + d = std::numeric_limits::quiet_NaN(); + } + else if (RAPIDJSON_LIKELY(Consume(s, 'I') && Consume(s, 'n') && Consume(s, 'f'))) { + d = (minus ? -std::numeric_limits::infinity() : std::numeric_limits::infinity()); + if (RAPIDJSON_UNLIKELY(s.Peek() == 'i' && !(Consume(s, 'i') && Consume(s, 'n') + && Consume(s, 'i') && Consume(s, 't') && Consume(s, 'y')))) + RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, s.Tell()); + } + else + RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, s.Tell()); + } + else + RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, s.Tell()); + + // Parse 64bit int + bool useDouble = false; + if (use64bit) { + if (minus) + while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) { + if (RAPIDJSON_UNLIKELY(i64 >= RAPIDJSON_UINT64_C2(0x0CCCCCCC, 0xCCCCCCCC))) // 2^63 = 9223372036854775808 + if (RAPIDJSON_LIKELY(i64 != RAPIDJSON_UINT64_C2(0x0CCCCCCC, 0xCCCCCCCC) || s.Peek() > '8')) { + d = static_cast(i64); + useDouble = true; + break; + } + i64 = i64 * 10 + static_cast(s.TakePush() - '0'); + significandDigit++; + } + else + while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) { + if (RAPIDJSON_UNLIKELY(i64 >= RAPIDJSON_UINT64_C2(0x19999999, 0x99999999))) // 2^64 - 1 = 18446744073709551615 + if (RAPIDJSON_LIKELY(i64 != RAPIDJSON_UINT64_C2(0x19999999, 0x99999999) || s.Peek() > '5')) { + d = static_cast(i64); + useDouble = true; + break; + } + i64 = i64 * 10 + static_cast(s.TakePush() - '0'); + significandDigit++; + } + } + + // Force double for big integer + if (useDouble) { + while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) { + if (RAPIDJSON_UNLIKELY(d >= 1.7976931348623157e307)) // DBL_MAX / 10.0 + RAPIDJSON_PARSE_ERROR(kParseErrorNumberTooBig, startOffset); + d = d * 10 + (s.TakePush() - '0'); + } + } + + // Parse frac = decimal-point 1*DIGIT + int expFrac = 0; + size_t decimalPosition; + if (Consume(s, '.')) { + decimalPosition = s.Length(); + + if (RAPIDJSON_UNLIKELY(!(s.Peek() >= '0' && s.Peek() <= '9'))) + RAPIDJSON_PARSE_ERROR(kParseErrorNumberMissFraction, s.Tell()); + + if (!useDouble) { +#if RAPIDJSON_64BIT + // Use i64 to store significand in 64-bit architecture + if (!use64bit) + i64 = i; + + while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) { + if (i64 > RAPIDJSON_UINT64_C2(0x1FFFFF, 0xFFFFFFFF)) // 2^53 - 1 for fast path + break; + else { + i64 = i64 * 10 + static_cast(s.TakePush() - '0'); + --expFrac; + if (i64 != 0) + significandDigit++; + } + } + + d = static_cast(i64); +#else + // Use double to store significand in 32-bit architecture + d = static_cast(use64bit ? i64 : i); +#endif + useDouble = true; + } + + while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) { + if (significandDigit < 17) { + d = d * 10.0 + (s.TakePush() - '0'); + --expFrac; + if (RAPIDJSON_LIKELY(d > 0.0)) + significandDigit++; + } + else + s.TakePush(); + } + } + else + decimalPosition = s.Length(); // decimal position at the end of integer. + + // Parse exp = e [ minus / plus ] 1*DIGIT + int exp = 0; + if (Consume(s, 'e') || Consume(s, 'E')) { + if (!useDouble) { + d = static_cast(use64bit ? i64 : i); + useDouble = true; + } + + bool expMinus = false; + if (Consume(s, '+')) + ; + else if (Consume(s, '-')) + expMinus = true; + + if (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) { + exp = static_cast(s.Take() - '0'); + if (expMinus) { + while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) { + exp = exp * 10 + static_cast(s.Take() - '0'); + if (exp >= 214748364) { // Issue #313: prevent overflow exponent + while (RAPIDJSON_UNLIKELY(s.Peek() >= '0' && s.Peek() <= '9')) // Consume the rest of exponent + s.Take(); + } + } + } + else { // positive exp + int maxExp = 308 - expFrac; + while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) { + exp = exp * 10 + static_cast(s.Take() - '0'); + if (RAPIDJSON_UNLIKELY(exp > maxExp)) + RAPIDJSON_PARSE_ERROR(kParseErrorNumberTooBig, startOffset); + } + } + } + else + RAPIDJSON_PARSE_ERROR(kParseErrorNumberMissExponent, s.Tell()); + + if (expMinus) + exp = -exp; + } + + // Finish parsing, call event according to the type of number. + bool cont = true; + + if (parseFlags & kParseNumbersAsStringsFlag) { + if (parseFlags & kParseInsituFlag) { + s.Pop(); // Pop stack no matter if it will be used or not. + typename InputStream::Ch* head = is.PutBegin(); + const size_t length = s.Tell() - startOffset; + RAPIDJSON_ASSERT(length <= 0xFFFFFFFF); + // unable to insert the \0 character here, it will erase the comma after this number + const typename TargetEncoding::Ch* const str = reinterpret_cast(head); + cont = handler.RawNumber(str, SizeType(length), false); + } + else { + SizeType numCharsToCopy = static_cast(s.Length()); + StringStream srcStream(s.Pop()); + StackStream dstStream(stack_); + while (numCharsToCopy--) { + Transcoder, TargetEncoding>::Transcode(srcStream, dstStream); + } + dstStream.Put('\0'); + const typename TargetEncoding::Ch* str = dstStream.Pop(); + const SizeType length = static_cast(dstStream.Length()) - 1; + cont = handler.RawNumber(str, SizeType(length), true); + } + } + else { + size_t length = s.Length(); + const char* decimal = s.Pop(); // Pop stack no matter if it will be used or not. + + if (useDouble) { + int p = exp + expFrac; + if (parseFlags & kParseFullPrecisionFlag) + d = internal::StrtodFullPrecision(d, p, decimal, length, decimalPosition, exp); + else + d = internal::StrtodNormalPrecision(d, p); + + cont = handler.Double(minus ? -d : d); + } + else if (useNanOrInf) { + cont = handler.Double(d); + } + else { + if (use64bit) { + if (minus) + cont = handler.Int64(static_cast(~i64 + 1)); + else + cont = handler.Uint64(i64); + } + else { + if (minus) + cont = handler.Int(static_cast(~i + 1)); + else + cont = handler.Uint(i); + } + } + } + if (RAPIDJSON_UNLIKELY(!cont)) + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, startOffset); + } + + // Parse any JSON value + template + void ParseValue(InputStream& is, Handler& handler) { + switch (is.Peek()) { + case 'n': ParseNull (is, handler); break; + case 't': ParseTrue (is, handler); break; + case 'f': ParseFalse (is, handler); break; + case '"': ParseString(is, handler); break; + case '{': ParseObject(is, handler); break; + case '[': ParseArray (is, handler); break; + default : + ParseNumber(is, handler); + break; + + } + } + + // Iterative Parsing + + // States + enum IterativeParsingState { + IterativeParsingStartState = 0, + IterativeParsingFinishState, + IterativeParsingErrorState, + + // Object states + IterativeParsingObjectInitialState, + IterativeParsingMemberKeyState, + IterativeParsingKeyValueDelimiterState, + IterativeParsingMemberValueState, + IterativeParsingMemberDelimiterState, + IterativeParsingObjectFinishState, + + // Array states + IterativeParsingArrayInitialState, + IterativeParsingElementState, + IterativeParsingElementDelimiterState, + IterativeParsingArrayFinishState, + + // Single value state + IterativeParsingValueState + }; + + enum { cIterativeParsingStateCount = IterativeParsingValueState + 1 }; + + // Tokens + enum Token { + LeftBracketToken = 0, + RightBracketToken, + + LeftCurlyBracketToken, + RightCurlyBracketToken, + + CommaToken, + ColonToken, + + StringToken, + FalseToken, + TrueToken, + NullToken, + NumberToken, + + kTokenCount + }; + + RAPIDJSON_FORCEINLINE Token Tokenize(Ch c) { + +//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN +#define N NumberToken +#define N16 N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N + // Maps from ASCII to Token + static const unsigned char tokenMap[256] = { + N16, // 00~0F + N16, // 10~1F + N, N, StringToken, N, N, N, N, N, N, N, N, N, CommaToken, N, N, N, // 20~2F + N, N, N, N, N, N, N, N, N, N, ColonToken, N, N, N, N, N, // 30~3F + N16, // 40~4F + N, N, N, N, N, N, N, N, N, N, N, LeftBracketToken, N, RightBracketToken, N, N, // 50~5F + N, N, N, N, N, N, FalseToken, N, N, N, N, N, N, N, NullToken, N, // 60~6F + N, N, N, N, TrueToken, N, N, N, N, N, N, LeftCurlyBracketToken, N, RightCurlyBracketToken, N, N, // 70~7F + N16, N16, N16, N16, N16, N16, N16, N16 // 80~FF + }; +#undef N +#undef N16 +//!@endcond + + if (sizeof(Ch) == 1 || static_cast(c) < 256) + return static_cast(tokenMap[static_cast(c)]); + else + return NumberToken; + } + + RAPIDJSON_FORCEINLINE IterativeParsingState Predict(IterativeParsingState state, Token token) { + // current state x one lookahead token -> new state + static const char G[cIterativeParsingStateCount][kTokenCount] = { + // Start + { + IterativeParsingArrayInitialState, // Left bracket + IterativeParsingErrorState, // Right bracket + IterativeParsingObjectInitialState, // Left curly bracket + IterativeParsingErrorState, // Right curly bracket + IterativeParsingErrorState, // Comma + IterativeParsingErrorState, // Colon + IterativeParsingValueState, // String + IterativeParsingValueState, // False + IterativeParsingValueState, // True + IterativeParsingValueState, // Null + IterativeParsingValueState // Number + }, + // Finish(sink state) + { + IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, + IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, + IterativeParsingErrorState + }, + // Error(sink state) + { + IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, + IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, + IterativeParsingErrorState + }, + // ObjectInitial + { + IterativeParsingErrorState, // Left bracket + IterativeParsingErrorState, // Right bracket + IterativeParsingErrorState, // Left curly bracket + IterativeParsingObjectFinishState, // Right curly bracket + IterativeParsingErrorState, // Comma + IterativeParsingErrorState, // Colon + IterativeParsingMemberKeyState, // String + IterativeParsingErrorState, // False + IterativeParsingErrorState, // True + IterativeParsingErrorState, // Null + IterativeParsingErrorState // Number + }, + // MemberKey + { + IterativeParsingErrorState, // Left bracket + IterativeParsingErrorState, // Right bracket + IterativeParsingErrorState, // Left curly bracket + IterativeParsingErrorState, // Right curly bracket + IterativeParsingErrorState, // Comma + IterativeParsingKeyValueDelimiterState, // Colon + IterativeParsingErrorState, // String + IterativeParsingErrorState, // False + IterativeParsingErrorState, // True + IterativeParsingErrorState, // Null + IterativeParsingErrorState // Number + }, + // KeyValueDelimiter + { + IterativeParsingArrayInitialState, // Left bracket(push MemberValue state) + IterativeParsingErrorState, // Right bracket + IterativeParsingObjectInitialState, // Left curly bracket(push MemberValue state) + IterativeParsingErrorState, // Right curly bracket + IterativeParsingErrorState, // Comma + IterativeParsingErrorState, // Colon + IterativeParsingMemberValueState, // String + IterativeParsingMemberValueState, // False + IterativeParsingMemberValueState, // True + IterativeParsingMemberValueState, // Null + IterativeParsingMemberValueState // Number + }, + // MemberValue + { + IterativeParsingErrorState, // Left bracket + IterativeParsingErrorState, // Right bracket + IterativeParsingErrorState, // Left curly bracket + IterativeParsingObjectFinishState, // Right curly bracket + IterativeParsingMemberDelimiterState, // Comma + IterativeParsingErrorState, // Colon + IterativeParsingErrorState, // String + IterativeParsingErrorState, // False + IterativeParsingErrorState, // True + IterativeParsingErrorState, // Null + IterativeParsingErrorState // Number + }, + // MemberDelimiter + { + IterativeParsingErrorState, // Left bracket + IterativeParsingErrorState, // Right bracket + IterativeParsingErrorState, // Left curly bracket + IterativeParsingObjectFinishState, // Right curly bracket + IterativeParsingErrorState, // Comma + IterativeParsingErrorState, // Colon + IterativeParsingMemberKeyState, // String + IterativeParsingErrorState, // False + IterativeParsingErrorState, // True + IterativeParsingErrorState, // Null + IterativeParsingErrorState // Number + }, + // ObjectFinish(sink state) + { + IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, + IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, + IterativeParsingErrorState + }, + // ArrayInitial + { + IterativeParsingArrayInitialState, // Left bracket(push Element state) + IterativeParsingArrayFinishState, // Right bracket + IterativeParsingObjectInitialState, // Left curly bracket(push Element state) + IterativeParsingErrorState, // Right curly bracket + IterativeParsingErrorState, // Comma + IterativeParsingErrorState, // Colon + IterativeParsingElementState, // String + IterativeParsingElementState, // False + IterativeParsingElementState, // True + IterativeParsingElementState, // Null + IterativeParsingElementState // Number + }, + // Element + { + IterativeParsingErrorState, // Left bracket + IterativeParsingArrayFinishState, // Right bracket + IterativeParsingErrorState, // Left curly bracket + IterativeParsingErrorState, // Right curly bracket + IterativeParsingElementDelimiterState, // Comma + IterativeParsingErrorState, // Colon + IterativeParsingErrorState, // String + IterativeParsingErrorState, // False + IterativeParsingErrorState, // True + IterativeParsingErrorState, // Null + IterativeParsingErrorState // Number + }, + // ElementDelimiter + { + IterativeParsingArrayInitialState, // Left bracket(push Element state) + IterativeParsingArrayFinishState, // Right bracket + IterativeParsingObjectInitialState, // Left curly bracket(push Element state) + IterativeParsingErrorState, // Right curly bracket + IterativeParsingErrorState, // Comma + IterativeParsingErrorState, // Colon + IterativeParsingElementState, // String + IterativeParsingElementState, // False + IterativeParsingElementState, // True + IterativeParsingElementState, // Null + IterativeParsingElementState // Number + }, + // ArrayFinish(sink state) + { + IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, + IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, + IterativeParsingErrorState + }, + // Single Value (sink state) + { + IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, + IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, + IterativeParsingErrorState + } + }; // End of G + + return static_cast(G[state][token]); + } + + // Make an advance in the token stream and state based on the candidate destination state which was returned by Transit(). + // May return a new state on state pop. + template + RAPIDJSON_FORCEINLINE IterativeParsingState Transit(IterativeParsingState src, Token token, IterativeParsingState dst, InputStream& is, Handler& handler) { + (void)token; + + switch (dst) { + case IterativeParsingErrorState: + return dst; + + case IterativeParsingObjectInitialState: + case IterativeParsingArrayInitialState: + { + // Push the state(Element or MemeberValue) if we are nested in another array or value of member. + // In this way we can get the correct state on ObjectFinish or ArrayFinish by frame pop. + IterativeParsingState n = src; + if (src == IterativeParsingArrayInitialState || src == IterativeParsingElementDelimiterState) + n = IterativeParsingElementState; + else if (src == IterativeParsingKeyValueDelimiterState) + n = IterativeParsingMemberValueState; + // Push current state. + *stack_.template Push(1) = n; + // Initialize and push the member/element count. + *stack_.template Push(1) = 0; + // Call handler + bool hr = (dst == IterativeParsingObjectInitialState) ? handler.StartObject() : handler.StartArray(); + // On handler short circuits the parsing. + if (!hr) { + RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorTermination, is.Tell()); + return IterativeParsingErrorState; + } + else { + is.Take(); + return dst; + } + } + + case IterativeParsingMemberKeyState: + ParseString(is, handler, true); + if (HasParseError()) + return IterativeParsingErrorState; + else + return dst; + + case IterativeParsingKeyValueDelimiterState: + RAPIDJSON_ASSERT(token == ColonToken); + is.Take(); + return dst; + + case IterativeParsingMemberValueState: + // Must be non-compound value. Or it would be ObjectInitial or ArrayInitial state. + ParseValue(is, handler); + if (HasParseError()) { + return IterativeParsingErrorState; + } + return dst; + + case IterativeParsingElementState: + // Must be non-compound value. Or it would be ObjectInitial or ArrayInitial state. + ParseValue(is, handler); + if (HasParseError()) { + return IterativeParsingErrorState; + } + return dst; + + case IterativeParsingMemberDelimiterState: + case IterativeParsingElementDelimiterState: + is.Take(); + // Update member/element count. + *stack_.template Top() = *stack_.template Top() + 1; + return dst; + + case IterativeParsingObjectFinishState: + { + // Transit from delimiter is only allowed when trailing commas are enabled + if (!(parseFlags & kParseTrailingCommasFlag) && src == IterativeParsingMemberDelimiterState) { + RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorObjectMissName, is.Tell()); + return IterativeParsingErrorState; + } + // Get member count. + SizeType c = *stack_.template Pop(1); + // If the object is not empty, count the last member. + if (src == IterativeParsingMemberValueState) + ++c; + // Restore the state. + IterativeParsingState n = static_cast(*stack_.template Pop(1)); + // Transit to Finish state if this is the topmost scope. + if (n == IterativeParsingStartState) + n = IterativeParsingFinishState; + // Call handler + bool hr = handler.EndObject(c); + // On handler short circuits the parsing. + if (!hr) { + RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorTermination, is.Tell()); + return IterativeParsingErrorState; + } + else { + is.Take(); + return n; + } + } + + case IterativeParsingArrayFinishState: + { + // Transit from delimiter is only allowed when trailing commas are enabled + if (!(parseFlags & kParseTrailingCommasFlag) && src == IterativeParsingElementDelimiterState) { + RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorValueInvalid, is.Tell()); + return IterativeParsingErrorState; + } + // Get element count. + SizeType c = *stack_.template Pop(1); + // If the array is not empty, count the last element. + if (src == IterativeParsingElementState) + ++c; + // Restore the state. + IterativeParsingState n = static_cast(*stack_.template Pop(1)); + // Transit to Finish state if this is the topmost scope. + if (n == IterativeParsingStartState) + n = IterativeParsingFinishState; + // Call handler + bool hr = handler.EndArray(c); + // On handler short circuits the parsing. + if (!hr) { + RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorTermination, is.Tell()); + return IterativeParsingErrorState; + } + else { + is.Take(); + return n; + } + } + + default: + // This branch is for IterativeParsingValueState actually. + // Use `default:` rather than + // `case IterativeParsingValueState:` is for code coverage. + + // The IterativeParsingStartState is not enumerated in this switch-case. + // It is impossible for that case. And it can be caught by following assertion. + + // The IterativeParsingFinishState is not enumerated in this switch-case either. + // It is a "derivative" state which cannot triggered from Predict() directly. + // Therefore it cannot happen here. And it can be caught by following assertion. + RAPIDJSON_ASSERT(dst == IterativeParsingValueState); + + // Must be non-compound value. Or it would be ObjectInitial or ArrayInitial state. + ParseValue(is, handler); + if (HasParseError()) { + return IterativeParsingErrorState; + } + return IterativeParsingFinishState; + } + } + + template + void HandleError(IterativeParsingState src, InputStream& is) { + if (HasParseError()) { + // Error flag has been set. + return; + } + + switch (src) { + case IterativeParsingStartState: RAPIDJSON_PARSE_ERROR(kParseErrorDocumentEmpty, is.Tell()); return; + case IterativeParsingFinishState: RAPIDJSON_PARSE_ERROR(kParseErrorDocumentRootNotSingular, is.Tell()); return; + case IterativeParsingObjectInitialState: + case IterativeParsingMemberDelimiterState: RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissName, is.Tell()); return; + case IterativeParsingMemberKeyState: RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissColon, is.Tell()); return; + case IterativeParsingMemberValueState: RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissCommaOrCurlyBracket, is.Tell()); return; + case IterativeParsingKeyValueDelimiterState: + case IterativeParsingArrayInitialState: + case IterativeParsingElementDelimiterState: RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell()); return; + default: RAPIDJSON_ASSERT(src == IterativeParsingElementState); RAPIDJSON_PARSE_ERROR(kParseErrorArrayMissCommaOrSquareBracket, is.Tell()); return; + } + } + + template + ParseResult IterativeParse(InputStream& is, Handler& handler) { + parseResult_.Clear(); + ClearStackOnExit scope(*this); + IterativeParsingState state = IterativeParsingStartState; + + SkipWhitespaceAndComments(is); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_); + while (is.Peek() != '\0') { + Token t = Tokenize(is.Peek()); + IterativeParsingState n = Predict(state, t); + IterativeParsingState d = Transit(state, t, n, is, handler); + + if (d == IterativeParsingErrorState) { + HandleError(state, is); + break; + } + + state = d; + + // Do not further consume streams if a root JSON has been parsed. + if ((parseFlags & kParseStopWhenDoneFlag) && state == IterativeParsingFinishState) + break; + + SkipWhitespaceAndComments(is); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_); + } + + // Handle the end of file. + if (state != IterativeParsingFinishState) + HandleError(state, is); + + return parseResult_; + } + + static const size_t kDefaultStackCapacity = 256; //!< Default stack capacity in bytes for storing a single decoded string. + internal::Stack stack_; //!< A stack for storing decoded string temporarily during non-destructive parsing. + ParseResult parseResult_; +}; // class GenericReader + +//! Reader with UTF8 encoding and default allocator. +typedef GenericReader, UTF8<> > Reader; + +RAPIDJSON_NAMESPACE_END + +#ifdef __clang__ +RAPIDJSON_DIAG_POP +#endif + + +#ifdef __GNUC__ +RAPIDJSON_DIAG_POP +#endif + +#ifdef _MSC_VER +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_READER_H_ diff --git a/slsReceiverSoftware/include/rapidjson/schema.h b/slsReceiverSoftware/include/rapidjson/schema.h new file mode 100644 index 000000000..b182aa27f --- /dev/null +++ b/slsReceiverSoftware/include/rapidjson/schema.h @@ -0,0 +1,2006 @@ +// Tencent is pleased to support the open source community by making RapidJSON available-> +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip-> All rights reserved-> +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License-> You may obtain a copy of the License at +// +// http://opensource->org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied-> See the License for the +// specific language governing permissions and limitations under the License-> + +#ifndef RAPIDJSON_SCHEMA_H_ +#define RAPIDJSON_SCHEMA_H_ + +#include "document.h" +#include "pointer.h" +#include // abs, floor + +#if !defined(RAPIDJSON_SCHEMA_USE_INTERNALREGEX) +#define RAPIDJSON_SCHEMA_USE_INTERNALREGEX 1 +#else +#define RAPIDJSON_SCHEMA_USE_INTERNALREGEX 0 +#endif + +#if !RAPIDJSON_SCHEMA_USE_INTERNALREGEX && !defined(RAPIDJSON_SCHEMA_USE_STDREGEX) && (__cplusplus >=201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)) +#define RAPIDJSON_SCHEMA_USE_STDREGEX 1 +#else +#define RAPIDJSON_SCHEMA_USE_STDREGEX 0 +#endif + +#if RAPIDJSON_SCHEMA_USE_INTERNALREGEX +#include "internal/regex.h" +#elif RAPIDJSON_SCHEMA_USE_STDREGEX +#include +#endif + +#if RAPIDJSON_SCHEMA_USE_INTERNALREGEX || RAPIDJSON_SCHEMA_USE_STDREGEX +#define RAPIDJSON_SCHEMA_HAS_REGEX 1 +#else +#define RAPIDJSON_SCHEMA_HAS_REGEX 0 +#endif + +#ifndef RAPIDJSON_SCHEMA_VERBOSE +#define RAPIDJSON_SCHEMA_VERBOSE 0 +#endif + +#if RAPIDJSON_SCHEMA_VERBOSE +#include "stringbuffer.h" +#endif + +RAPIDJSON_DIAG_PUSH + +#if defined(__GNUC__) +RAPIDJSON_DIAG_OFF(effc++) +#endif + +#ifdef __clang__ +RAPIDJSON_DIAG_OFF(weak-vtables) +RAPIDJSON_DIAG_OFF(exit-time-destructors) +RAPIDJSON_DIAG_OFF(c++98-compat-pedantic) +RAPIDJSON_DIAG_OFF(variadic-macros) +#endif + +#ifdef _MSC_VER +RAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated +#endif + +RAPIDJSON_NAMESPACE_BEGIN + +/////////////////////////////////////////////////////////////////////////////// +// Verbose Utilities + +#if RAPIDJSON_SCHEMA_VERBOSE + +namespace internal { + +inline void PrintInvalidKeyword(const char* keyword) { + printf("Fail keyword: %s\n", keyword); +} + +inline void PrintInvalidKeyword(const wchar_t* keyword) { + wprintf(L"Fail keyword: %ls\n", keyword); +} + +inline void PrintInvalidDocument(const char* document) { + printf("Fail document: %s\n\n", document); +} + +inline void PrintInvalidDocument(const wchar_t* document) { + wprintf(L"Fail document: %ls\n\n", document); +} + +inline void PrintValidatorPointers(unsigned depth, const char* s, const char* d) { + printf("S: %*s%s\nD: %*s%s\n\n", depth * 4, " ", s, depth * 4, " ", d); +} + +inline void PrintValidatorPointers(unsigned depth, const wchar_t* s, const wchar_t* d) { + wprintf(L"S: %*ls%ls\nD: %*ls%ls\n\n", depth * 4, L" ", s, depth * 4, L" ", d); +} + +} // namespace internal + +#endif // RAPIDJSON_SCHEMA_VERBOSE + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_INVALID_KEYWORD_RETURN + +#if RAPIDJSON_SCHEMA_VERBOSE +#define RAPIDJSON_INVALID_KEYWORD_VERBOSE(keyword) internal::PrintInvalidKeyword(keyword) +#else +#define RAPIDJSON_INVALID_KEYWORD_VERBOSE(keyword) +#endif + +#define RAPIDJSON_INVALID_KEYWORD_RETURN(keyword)\ +RAPIDJSON_MULTILINEMACRO_BEGIN\ + context.invalidKeyword = keyword.GetString();\ + RAPIDJSON_INVALID_KEYWORD_VERBOSE(keyword.GetString());\ + return false;\ +RAPIDJSON_MULTILINEMACRO_END + +/////////////////////////////////////////////////////////////////////////////// +// Forward declarations + +template +class GenericSchemaDocument; + +namespace internal { + +template +class Schema; + +/////////////////////////////////////////////////////////////////////////////// +// ISchemaValidator + +class ISchemaValidator { +public: + virtual ~ISchemaValidator() {} + virtual bool IsValid() const = 0; +}; + +/////////////////////////////////////////////////////////////////////////////// +// ISchemaStateFactory + +template +class ISchemaStateFactory { +public: + virtual ~ISchemaStateFactory() {} + virtual ISchemaValidator* CreateSchemaValidator(const SchemaType&) = 0; + virtual void DestroySchemaValidator(ISchemaValidator* validator) = 0; + virtual void* CreateHasher() = 0; + virtual uint64_t GetHashCode(void* hasher) = 0; + virtual void DestroryHasher(void* hasher) = 0; + virtual void* MallocState(size_t size) = 0; + virtual void FreeState(void* p) = 0; +}; + +/////////////////////////////////////////////////////////////////////////////// +// Hasher + +// For comparison of compound value +template +class Hasher { +public: + typedef typename Encoding::Ch Ch; + + Hasher(Allocator* allocator = 0, size_t stackCapacity = kDefaultSize) : stack_(allocator, stackCapacity) {} + + bool Null() { return WriteType(kNullType); } + bool Bool(bool b) { return WriteType(b ? kTrueType : kFalseType); } + bool Int(int i) { Number n; n.u.i = i; n.d = static_cast(i); return WriteNumber(n); } + bool Uint(unsigned u) { Number n; n.u.u = u; n.d = static_cast(u); return WriteNumber(n); } + bool Int64(int64_t i) { Number n; n.u.i = i; n.d = static_cast(i); return WriteNumber(n); } + bool Uint64(uint64_t u) { Number n; n.u.u = u; n.d = static_cast(u); return WriteNumber(n); } + bool Double(double d) { + Number n; + if (d < 0) n.u.i = static_cast(d); + else n.u.u = static_cast(d); + n.d = d; + return WriteNumber(n); + } + + bool RawNumber(const Ch* str, SizeType len, bool) { + WriteBuffer(kNumberType, str, len * sizeof(Ch)); + return true; + } + + bool String(const Ch* str, SizeType len, bool) { + WriteBuffer(kStringType, str, len * sizeof(Ch)); + return true; + } + + bool StartObject() { return true; } + bool Key(const Ch* str, SizeType len, bool copy) { return String(str, len, copy); } + bool EndObject(SizeType memberCount) { + uint64_t h = Hash(0, kObjectType); + uint64_t* kv = stack_.template Pop(memberCount * 2); + for (SizeType i = 0; i < memberCount; i++) + h ^= Hash(kv[i * 2], kv[i * 2 + 1]); // Use xor to achieve member order insensitive + *stack_.template Push() = h; + return true; + } + + bool StartArray() { return true; } + bool EndArray(SizeType elementCount) { + uint64_t h = Hash(0, kArrayType); + uint64_t* e = stack_.template Pop(elementCount); + for (SizeType i = 0; i < elementCount; i++) + h = Hash(h, e[i]); // Use hash to achieve element order sensitive + *stack_.template Push() = h; + return true; + } + + bool IsValid() const { return stack_.GetSize() == sizeof(uint64_t); } + + uint64_t GetHashCode() const { + RAPIDJSON_ASSERT(IsValid()); + return *stack_.template Top(); + } + +private: + static const size_t kDefaultSize = 256; + struct Number { + union U { + uint64_t u; + int64_t i; + }u; + double d; + }; + + bool WriteType(Type type) { return WriteBuffer(type, 0, 0); } + + bool WriteNumber(const Number& n) { return WriteBuffer(kNumberType, &n, sizeof(n)); } + + bool WriteBuffer(Type type, const void* data, size_t len) { + // FNV-1a from http://isthe.com/chongo/tech/comp/fnv/ + uint64_t h = Hash(RAPIDJSON_UINT64_C2(0x84222325, 0xcbf29ce4), type); + const unsigned char* d = static_cast(data); + for (size_t i = 0; i < len; i++) + h = Hash(h, d[i]); + *stack_.template Push() = h; + return true; + } + + static uint64_t Hash(uint64_t h, uint64_t d) { + static const uint64_t kPrime = RAPIDJSON_UINT64_C2(0x00000100, 0x000001b3); + h ^= d; + h *= kPrime; + return h; + } + + Stack stack_; +}; + +/////////////////////////////////////////////////////////////////////////////// +// SchemaValidationContext + +template +struct SchemaValidationContext { + typedef Schema SchemaType; + typedef ISchemaStateFactory SchemaValidatorFactoryType; + typedef typename SchemaType::ValueType ValueType; + typedef typename ValueType::Ch Ch; + + enum PatternValidatorType { + kPatternValidatorOnly, + kPatternValidatorWithProperty, + kPatternValidatorWithAdditionalProperty + }; + + SchemaValidationContext(SchemaValidatorFactoryType& f, const SchemaType* s) : + factory(f), + schema(s), + valueSchema(), + invalidKeyword(), + hasher(), + arrayElementHashCodes(), + validators(), + validatorCount(), + patternPropertiesValidators(), + patternPropertiesValidatorCount(), + patternPropertiesSchemas(), + patternPropertiesSchemaCount(), + valuePatternValidatorType(kPatternValidatorOnly), + propertyExist(), + inArray(false), + valueUniqueness(false), + arrayUniqueness(false) + { + } + + ~SchemaValidationContext() { + if (hasher) + factory.DestroryHasher(hasher); + if (validators) { + for (SizeType i = 0; i < validatorCount; i++) + factory.DestroySchemaValidator(validators[i]); + factory.FreeState(validators); + } + if (patternPropertiesValidators) { + for (SizeType i = 0; i < patternPropertiesValidatorCount; i++) + factory.DestroySchemaValidator(patternPropertiesValidators[i]); + factory.FreeState(patternPropertiesValidators); + } + if (patternPropertiesSchemas) + factory.FreeState(patternPropertiesSchemas); + if (propertyExist) + factory.FreeState(propertyExist); + } + + SchemaValidatorFactoryType& factory; + const SchemaType* schema; + const SchemaType* valueSchema; + const Ch* invalidKeyword; + void* hasher; // Only validator access + void* arrayElementHashCodes; // Only validator access this + ISchemaValidator** validators; + SizeType validatorCount; + ISchemaValidator** patternPropertiesValidators; + SizeType patternPropertiesValidatorCount; + const SchemaType** patternPropertiesSchemas; + SizeType patternPropertiesSchemaCount; + PatternValidatorType valuePatternValidatorType; + PatternValidatorType objectPatternValidatorType; + SizeType arrayElementIndex; + bool* propertyExist; + bool inArray; + bool valueUniqueness; + bool arrayUniqueness; +}; + +/////////////////////////////////////////////////////////////////////////////// +// Schema + +template +class Schema { +public: + typedef typename SchemaDocumentType::ValueType ValueType; + typedef typename SchemaDocumentType::AllocatorType AllocatorType; + typedef typename SchemaDocumentType::PointerType PointerType; + typedef typename ValueType::EncodingType EncodingType; + typedef typename EncodingType::Ch Ch; + typedef SchemaValidationContext Context; + typedef Schema SchemaType; + typedef GenericValue SValue; + friend class GenericSchemaDocument; + + Schema(SchemaDocumentType* schemaDocument, const PointerType& p, const ValueType& value, const ValueType& document, AllocatorType* allocator) : + allocator_(allocator), + enum_(), + enumCount_(), + not_(), + type_((1 << kTotalSchemaType) - 1), // typeless + validatorCount_(), + properties_(), + additionalPropertiesSchema_(), + patternProperties_(), + patternPropertyCount_(), + propertyCount_(), + minProperties_(), + maxProperties_(SizeType(~0)), + additionalProperties_(true), + hasDependencies_(), + hasRequired_(), + hasSchemaDependencies_(), + additionalItemsSchema_(), + itemsList_(), + itemsTuple_(), + itemsTupleCount_(), + minItems_(), + maxItems_(SizeType(~0)), + additionalItems_(true), + uniqueItems_(false), + pattern_(), + minLength_(0), + maxLength_(~SizeType(0)), + exclusiveMinimum_(false), + exclusiveMaximum_(false) + { + typedef typename SchemaDocumentType::ValueType ValueType; + typedef typename ValueType::ConstValueIterator ConstValueIterator; + typedef typename ValueType::ConstMemberIterator ConstMemberIterator; + + if (!value.IsObject()) + return; + + if (const ValueType* v = GetMember(value, GetTypeString())) { + type_ = 0; + if (v->IsString()) + AddType(*v); + else if (v->IsArray()) + for (ConstValueIterator itr = v->Begin(); itr != v->End(); ++itr) + AddType(*itr); + } + + if (const ValueType* v = GetMember(value, GetEnumString())) + if (v->IsArray() && v->Size() > 0) { + enum_ = static_cast(allocator_->Malloc(sizeof(uint64_t) * v->Size())); + for (ConstValueIterator itr = v->Begin(); itr != v->End(); ++itr) { + typedef Hasher > EnumHasherType; + char buffer[256 + 24]; + MemoryPoolAllocator<> hasherAllocator(buffer, sizeof(buffer)); + EnumHasherType h(&hasherAllocator, 256); + itr->Accept(h); + enum_[enumCount_++] = h.GetHashCode(); + } + } + + if (schemaDocument) { + AssignIfExist(allOf_, *schemaDocument, p, value, GetAllOfString(), document); + AssignIfExist(anyOf_, *schemaDocument, p, value, GetAnyOfString(), document); + AssignIfExist(oneOf_, *schemaDocument, p, value, GetOneOfString(), document); + } + + if (const ValueType* v = GetMember(value, GetNotString())) { + schemaDocument->CreateSchema(¬_, p.Append(GetNotString(), allocator_), *v, document); + notValidatorIndex_ = validatorCount_; + validatorCount_++; + } + + // Object + + const ValueType* properties = GetMember(value, GetPropertiesString()); + const ValueType* required = GetMember(value, GetRequiredString()); + const ValueType* dependencies = GetMember(value, GetDependenciesString()); + { + // Gather properties from properties/required/dependencies + SValue allProperties(kArrayType); + + if (properties && properties->IsObject()) + for (ConstMemberIterator itr = properties->MemberBegin(); itr != properties->MemberEnd(); ++itr) + AddUniqueElement(allProperties, itr->name); + + if (required && required->IsArray()) + for (ConstValueIterator itr = required->Begin(); itr != required->End(); ++itr) + if (itr->IsString()) + AddUniqueElement(allProperties, *itr); + + if (dependencies && dependencies->IsObject()) + for (ConstMemberIterator itr = dependencies->MemberBegin(); itr != dependencies->MemberEnd(); ++itr) { + AddUniqueElement(allProperties, itr->name); + if (itr->value.IsArray()) + for (ConstValueIterator i = itr->value.Begin(); i != itr->value.End(); ++i) + if (i->IsString()) + AddUniqueElement(allProperties, *i); + } + + if (allProperties.Size() > 0) { + propertyCount_ = allProperties.Size(); + properties_ = static_cast(allocator_->Malloc(sizeof(Property) * propertyCount_)); + for (SizeType i = 0; i < propertyCount_; i++) { + new (&properties_[i]) Property(); + properties_[i].name = allProperties[i]; + properties_[i].schema = GetTypeless(); + } + } + } + + if (properties && properties->IsObject()) { + PointerType q = p.Append(GetPropertiesString(), allocator_); + for (ConstMemberIterator itr = properties->MemberBegin(); itr != properties->MemberEnd(); ++itr) { + SizeType index; + if (FindPropertyIndex(itr->name, &index)) + schemaDocument->CreateSchema(&properties_[index].schema, q.Append(itr->name, allocator_), itr->value, document); + } + } + + if (const ValueType* v = GetMember(value, GetPatternPropertiesString())) { + PointerType q = p.Append(GetPatternPropertiesString(), allocator_); + patternProperties_ = static_cast(allocator_->Malloc(sizeof(PatternProperty) * v->MemberCount())); + patternPropertyCount_ = 0; + + for (ConstMemberIterator itr = v->MemberBegin(); itr != v->MemberEnd(); ++itr) { + new (&patternProperties_[patternPropertyCount_]) PatternProperty(); + patternProperties_[patternPropertyCount_].pattern = CreatePattern(itr->name); + schemaDocument->CreateSchema(&patternProperties_[patternPropertyCount_].schema, q.Append(itr->name, allocator_), itr->value, document); + patternPropertyCount_++; + } + } + + if (required && required->IsArray()) + for (ConstValueIterator itr = required->Begin(); itr != required->End(); ++itr) + if (itr->IsString()) { + SizeType index; + if (FindPropertyIndex(*itr, &index)) { + properties_[index].required = true; + hasRequired_ = true; + } + } + + if (dependencies && dependencies->IsObject()) { + PointerType q = p.Append(GetDependenciesString(), allocator_); + hasDependencies_ = true; + for (ConstMemberIterator itr = dependencies->MemberBegin(); itr != dependencies->MemberEnd(); ++itr) { + SizeType sourceIndex; + if (FindPropertyIndex(itr->name, &sourceIndex)) { + if (itr->value.IsArray()) { + properties_[sourceIndex].dependencies = static_cast(allocator_->Malloc(sizeof(bool) * propertyCount_)); + std::memset(properties_[sourceIndex].dependencies, 0, sizeof(bool)* propertyCount_); + for (ConstValueIterator targetItr = itr->value.Begin(); targetItr != itr->value.End(); ++targetItr) { + SizeType targetIndex; + if (FindPropertyIndex(*targetItr, &targetIndex)) + properties_[sourceIndex].dependencies[targetIndex] = true; + } + } + else if (itr->value.IsObject()) { + hasSchemaDependencies_ = true; + schemaDocument->CreateSchema(&properties_[sourceIndex].dependenciesSchema, q.Append(itr->name, allocator_), itr->value, document); + properties_[sourceIndex].dependenciesValidatorIndex = validatorCount_; + validatorCount_++; + } + } + } + } + + if (const ValueType* v = GetMember(value, GetAdditionalPropertiesString())) { + if (v->IsBool()) + additionalProperties_ = v->GetBool(); + else if (v->IsObject()) + schemaDocument->CreateSchema(&additionalPropertiesSchema_, p.Append(GetAdditionalPropertiesString(), allocator_), *v, document); + } + + AssignIfExist(minProperties_, value, GetMinPropertiesString()); + AssignIfExist(maxProperties_, value, GetMaxPropertiesString()); + + // Array + if (const ValueType* v = GetMember(value, GetItemsString())) { + PointerType q = p.Append(GetItemsString(), allocator_); + if (v->IsObject()) // List validation + schemaDocument->CreateSchema(&itemsList_, q, *v, document); + else if (v->IsArray()) { // Tuple validation + itemsTuple_ = static_cast(allocator_->Malloc(sizeof(const Schema*) * v->Size())); + SizeType index = 0; + for (ConstValueIterator itr = v->Begin(); itr != v->End(); ++itr, index++) + schemaDocument->CreateSchema(&itemsTuple_[itemsTupleCount_++], q.Append(index, allocator_), *itr, document); + } + } + + AssignIfExist(minItems_, value, GetMinItemsString()); + AssignIfExist(maxItems_, value, GetMaxItemsString()); + + if (const ValueType* v = GetMember(value, GetAdditionalItemsString())) { + if (v->IsBool()) + additionalItems_ = v->GetBool(); + else if (v->IsObject()) + schemaDocument->CreateSchema(&additionalItemsSchema_, p.Append(GetAdditionalItemsString(), allocator_), *v, document); + } + + AssignIfExist(uniqueItems_, value, GetUniqueItemsString()); + + // String + AssignIfExist(minLength_, value, GetMinLengthString()); + AssignIfExist(maxLength_, value, GetMaxLengthString()); + + if (const ValueType* v = GetMember(value, GetPatternString())) + pattern_ = CreatePattern(*v); + + // Number + if (const ValueType* v = GetMember(value, GetMinimumString())) + if (v->IsNumber()) + minimum_.CopyFrom(*v, *allocator_); + + if (const ValueType* v = GetMember(value, GetMaximumString())) + if (v->IsNumber()) + maximum_.CopyFrom(*v, *allocator_); + + AssignIfExist(exclusiveMinimum_, value, GetExclusiveMinimumString()); + AssignIfExist(exclusiveMaximum_, value, GetExclusiveMaximumString()); + + if (const ValueType* v = GetMember(value, GetMultipleOfString())) + if (v->IsNumber() && v->GetDouble() > 0.0) + multipleOf_.CopyFrom(*v, *allocator_); + } + + ~Schema() { + if (allocator_) { + allocator_->Free(enum_); + } + if (properties_) { + for (SizeType i = 0; i < propertyCount_; i++) + properties_[i].~Property(); + AllocatorType::Free(properties_); + } + if (patternProperties_) { + for (SizeType i = 0; i < patternPropertyCount_; i++) + patternProperties_[i].~PatternProperty(); + AllocatorType::Free(patternProperties_); + } + AllocatorType::Free(itemsTuple_); +#if RAPIDJSON_SCHEMA_HAS_REGEX + if (pattern_) { + pattern_->~RegexType(); + allocator_->Free(pattern_); + } +#endif + } + + bool BeginValue(Context& context) const { + if (context.inArray) { + if (uniqueItems_) + context.valueUniqueness = true; + + if (itemsList_) + context.valueSchema = itemsList_; + else if (itemsTuple_) { + if (context.arrayElementIndex < itemsTupleCount_) + context.valueSchema = itemsTuple_[context.arrayElementIndex]; + else if (additionalItemsSchema_) + context.valueSchema = additionalItemsSchema_; + else if (additionalItems_) + context.valueSchema = GetTypeless(); + else + RAPIDJSON_INVALID_KEYWORD_RETURN(GetItemsString()); + } + else + context.valueSchema = GetTypeless(); + + context.arrayElementIndex++; + } + return true; + } + + RAPIDJSON_FORCEINLINE bool EndValue(Context& context) const { + if (context.patternPropertiesValidatorCount > 0) { + bool otherValid = false; + SizeType count = context.patternPropertiesValidatorCount; + if (context.objectPatternValidatorType != Context::kPatternValidatorOnly) + otherValid = context.patternPropertiesValidators[--count]->IsValid(); + + bool patternValid = true; + for (SizeType i = 0; i < count; i++) + if (!context.patternPropertiesValidators[i]->IsValid()) { + patternValid = false; + break; + } + + if (context.objectPatternValidatorType == Context::kPatternValidatorOnly) { + if (!patternValid) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetPatternPropertiesString()); + } + else if (context.objectPatternValidatorType == Context::kPatternValidatorWithProperty) { + if (!patternValid || !otherValid) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetPatternPropertiesString()); + } + else if (!patternValid && !otherValid) // kPatternValidatorWithAdditionalProperty) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetPatternPropertiesString()); + } + + if (enum_) { + const uint64_t h = context.factory.GetHashCode(context.hasher); + for (SizeType i = 0; i < enumCount_; i++) + if (enum_[i] == h) + goto foundEnum; + RAPIDJSON_INVALID_KEYWORD_RETURN(GetEnumString()); + foundEnum:; + } + + if (allOf_.schemas) + for (SizeType i = allOf_.begin; i < allOf_.begin + allOf_.count; i++) + if (!context.validators[i]->IsValid()) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetAllOfString()); + + if (anyOf_.schemas) { + for (SizeType i = anyOf_.begin; i < anyOf_.begin + anyOf_.count; i++) + if (context.validators[i]->IsValid()) + goto foundAny; + RAPIDJSON_INVALID_KEYWORD_RETURN(GetAnyOfString()); + foundAny:; + } + + if (oneOf_.schemas) { + bool oneValid = false; + for (SizeType i = oneOf_.begin; i < oneOf_.begin + oneOf_.count; i++) + if (context.validators[i]->IsValid()) { + if (oneValid) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetOneOfString()); + else + oneValid = true; + } + if (!oneValid) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetOneOfString()); + } + + if (not_ && context.validators[notValidatorIndex_]->IsValid()) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetNotString()); + + return true; + } + + bool Null(Context& context) const { + if (!(type_ & (1 << kNullSchemaType))) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString()); + return CreateParallelValidator(context); + } + + bool Bool(Context& context, bool) const { + if (!(type_ & (1 << kBooleanSchemaType))) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString()); + return CreateParallelValidator(context); + } + + bool Int(Context& context, int i) const { + if (!CheckInt(context, i)) + return false; + return CreateParallelValidator(context); + } + + bool Uint(Context& context, unsigned u) const { + if (!CheckUint(context, u)) + return false; + return CreateParallelValidator(context); + } + + bool Int64(Context& context, int64_t i) const { + if (!CheckInt(context, i)) + return false; + return CreateParallelValidator(context); + } + + bool Uint64(Context& context, uint64_t u) const { + if (!CheckUint(context, u)) + return false; + return CreateParallelValidator(context); + } + + bool Double(Context& context, double d) const { + if (!(type_ & (1 << kNumberSchemaType))) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString()); + + if (!minimum_.IsNull() && !CheckDoubleMinimum(context, d)) + return false; + + if (!maximum_.IsNull() && !CheckDoubleMaximum(context, d)) + return false; + + if (!multipleOf_.IsNull() && !CheckDoubleMultipleOf(context, d)) + return false; + + return CreateParallelValidator(context); + } + + bool String(Context& context, const Ch* str, SizeType length, bool) const { + if (!(type_ & (1 << kStringSchemaType))) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString()); + + if (minLength_ != 0 || maxLength_ != SizeType(~0)) { + SizeType count; + if (internal::CountStringCodePoint(str, length, &count)) { + if (count < minLength_) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinLengthString()); + if (count > maxLength_) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaxLengthString()); + } + } + + if (pattern_ && !IsPatternMatch(pattern_, str, length)) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetPatternString()); + + return CreateParallelValidator(context); + } + + bool StartObject(Context& context) const { + if (!(type_ & (1 << kObjectSchemaType))) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString()); + + if (hasDependencies_ || hasRequired_) { + context.propertyExist = static_cast(context.factory.MallocState(sizeof(bool) * propertyCount_)); + std::memset(context.propertyExist, 0, sizeof(bool) * propertyCount_); + } + + if (patternProperties_) { // pre-allocate schema array + SizeType count = patternPropertyCount_ + 1; // extra for valuePatternValidatorType + context.patternPropertiesSchemas = static_cast(context.factory.MallocState(sizeof(const SchemaType*) * count)); + context.patternPropertiesSchemaCount = 0; + std::memset(context.patternPropertiesSchemas, 0, sizeof(SchemaType*) * count); + } + + return CreateParallelValidator(context); + } + + bool Key(Context& context, const Ch* str, SizeType len, bool) const { + if (patternProperties_) { + context.patternPropertiesSchemaCount = 0; + for (SizeType i = 0; i < patternPropertyCount_; i++) + if (patternProperties_[i].pattern && IsPatternMatch(patternProperties_[i].pattern, str, len)) + context.patternPropertiesSchemas[context.patternPropertiesSchemaCount++] = patternProperties_[i].schema; + } + + SizeType index; + if (FindPropertyIndex(ValueType(str, len).Move(), &index)) { + if (context.patternPropertiesSchemaCount > 0) { + context.patternPropertiesSchemas[context.patternPropertiesSchemaCount++] = properties_[index].schema; + context.valueSchema = GetTypeless(); + context.valuePatternValidatorType = Context::kPatternValidatorWithProperty; + } + else + context.valueSchema = properties_[index].schema; + + if (context.propertyExist) + context.propertyExist[index] = true; + + return true; + } + + if (additionalPropertiesSchema_) { + if (additionalPropertiesSchema_ && context.patternPropertiesSchemaCount > 0) { + context.patternPropertiesSchemas[context.patternPropertiesSchemaCount++] = additionalPropertiesSchema_; + context.valueSchema = GetTypeless(); + context.valuePatternValidatorType = Context::kPatternValidatorWithAdditionalProperty; + } + else + context.valueSchema = additionalPropertiesSchema_; + return true; + } + else if (additionalProperties_) { + context.valueSchema = GetTypeless(); + return true; + } + + if (context.patternPropertiesSchemaCount == 0) // patternProperties are not additional properties + RAPIDJSON_INVALID_KEYWORD_RETURN(GetAdditionalPropertiesString()); + + return true; + } + + bool EndObject(Context& context, SizeType memberCount) const { + if (hasRequired_) + for (SizeType index = 0; index < propertyCount_; index++) + if (properties_[index].required) + if (!context.propertyExist[index]) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetRequiredString()); + + if (memberCount < minProperties_) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinPropertiesString()); + + if (memberCount > maxProperties_) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaxPropertiesString()); + + if (hasDependencies_) { + for (SizeType sourceIndex = 0; sourceIndex < propertyCount_; sourceIndex++) + if (context.propertyExist[sourceIndex]) { + if (properties_[sourceIndex].dependencies) { + for (SizeType targetIndex = 0; targetIndex < propertyCount_; targetIndex++) + if (properties_[sourceIndex].dependencies[targetIndex] && !context.propertyExist[targetIndex]) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetDependenciesString()); + } + else if (properties_[sourceIndex].dependenciesSchema) + if (!context.validators[properties_[sourceIndex].dependenciesValidatorIndex]->IsValid()) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetDependenciesString()); + } + } + + return true; + } + + bool StartArray(Context& context) const { + if (!(type_ & (1 << kArraySchemaType))) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString()); + + context.arrayElementIndex = 0; + context.inArray = true; + + return CreateParallelValidator(context); + } + + bool EndArray(Context& context, SizeType elementCount) const { + context.inArray = false; + + if (elementCount < minItems_) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinItemsString()); + + if (elementCount > maxItems_) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaxItemsString()); + + return true; + } + + // Generate functions for string literal according to Ch +#define RAPIDJSON_STRING_(name, ...) \ + static const ValueType& Get##name##String() {\ + static const Ch s[] = { __VA_ARGS__, '\0' };\ + static const ValueType v(s, sizeof(s) / sizeof(Ch) - 1);\ + return v;\ + } + + RAPIDJSON_STRING_(Null, 'n', 'u', 'l', 'l') + RAPIDJSON_STRING_(Boolean, 'b', 'o', 'o', 'l', 'e', 'a', 'n') + RAPIDJSON_STRING_(Object, 'o', 'b', 'j', 'e', 'c', 't') + RAPIDJSON_STRING_(Array, 'a', 'r', 'r', 'a', 'y') + RAPIDJSON_STRING_(String, 's', 't', 'r', 'i', 'n', 'g') + RAPIDJSON_STRING_(Number, 'n', 'u', 'm', 'b', 'e', 'r') + RAPIDJSON_STRING_(Integer, 'i', 'n', 't', 'e', 'g', 'e', 'r') + RAPIDJSON_STRING_(Type, 't', 'y', 'p', 'e') + RAPIDJSON_STRING_(Enum, 'e', 'n', 'u', 'm') + RAPIDJSON_STRING_(AllOf, 'a', 'l', 'l', 'O', 'f') + RAPIDJSON_STRING_(AnyOf, 'a', 'n', 'y', 'O', 'f') + RAPIDJSON_STRING_(OneOf, 'o', 'n', 'e', 'O', 'f') + RAPIDJSON_STRING_(Not, 'n', 'o', 't') + RAPIDJSON_STRING_(Properties, 'p', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's') + RAPIDJSON_STRING_(Required, 'r', 'e', 'q', 'u', 'i', 'r', 'e', 'd') + RAPIDJSON_STRING_(Dependencies, 'd', 'e', 'p', 'e', 'n', 'd', 'e', 'n', 'c', 'i', 'e', 's') + RAPIDJSON_STRING_(PatternProperties, 'p', 'a', 't', 't', 'e', 'r', 'n', 'P', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's') + RAPIDJSON_STRING_(AdditionalProperties, 'a', 'd', 'd', 'i', 't', 'i', 'o', 'n', 'a', 'l', 'P', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's') + RAPIDJSON_STRING_(MinProperties, 'm', 'i', 'n', 'P', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's') + RAPIDJSON_STRING_(MaxProperties, 'm', 'a', 'x', 'P', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's') + RAPIDJSON_STRING_(Items, 'i', 't', 'e', 'm', 's') + RAPIDJSON_STRING_(MinItems, 'm', 'i', 'n', 'I', 't', 'e', 'm', 's') + RAPIDJSON_STRING_(MaxItems, 'm', 'a', 'x', 'I', 't', 'e', 'm', 's') + RAPIDJSON_STRING_(AdditionalItems, 'a', 'd', 'd', 'i', 't', 'i', 'o', 'n', 'a', 'l', 'I', 't', 'e', 'm', 's') + RAPIDJSON_STRING_(UniqueItems, 'u', 'n', 'i', 'q', 'u', 'e', 'I', 't', 'e', 'm', 's') + RAPIDJSON_STRING_(MinLength, 'm', 'i', 'n', 'L', 'e', 'n', 'g', 't', 'h') + RAPIDJSON_STRING_(MaxLength, 'm', 'a', 'x', 'L', 'e', 'n', 'g', 't', 'h') + RAPIDJSON_STRING_(Pattern, 'p', 'a', 't', 't', 'e', 'r', 'n') + RAPIDJSON_STRING_(Minimum, 'm', 'i', 'n', 'i', 'm', 'u', 'm') + RAPIDJSON_STRING_(Maximum, 'm', 'a', 'x', 'i', 'm', 'u', 'm') + RAPIDJSON_STRING_(ExclusiveMinimum, 'e', 'x', 'c', 'l', 'u', 's', 'i', 'v', 'e', 'M', 'i', 'n', 'i', 'm', 'u', 'm') + RAPIDJSON_STRING_(ExclusiveMaximum, 'e', 'x', 'c', 'l', 'u', 's', 'i', 'v', 'e', 'M', 'a', 'x', 'i', 'm', 'u', 'm') + RAPIDJSON_STRING_(MultipleOf, 'm', 'u', 'l', 't', 'i', 'p', 'l', 'e', 'O', 'f') + +#undef RAPIDJSON_STRING_ + +private: + enum SchemaValueType { + kNullSchemaType, + kBooleanSchemaType, + kObjectSchemaType, + kArraySchemaType, + kStringSchemaType, + kNumberSchemaType, + kIntegerSchemaType, + kTotalSchemaType + }; + +#if RAPIDJSON_SCHEMA_USE_INTERNALREGEX + typedef internal::GenericRegex RegexType; +#elif RAPIDJSON_SCHEMA_USE_STDREGEX + typedef std::basic_regex RegexType; +#else + typedef char RegexType; +#endif + + struct SchemaArray { + SchemaArray() : schemas(), count() {} + ~SchemaArray() { AllocatorType::Free(schemas); } + const SchemaType** schemas; + SizeType begin; // begin index of context.validators + SizeType count; + }; + + static const SchemaType* GetTypeless() { + static SchemaType typeless(0, PointerType(), ValueType(kObjectType).Move(), ValueType(kObjectType).Move(), 0); + return &typeless; + } + + template + void AddUniqueElement(V1& a, const V2& v) { + for (typename V1::ConstValueIterator itr = a.Begin(); itr != a.End(); ++itr) + if (*itr == v) + return; + V1 c(v, *allocator_); + a.PushBack(c, *allocator_); + } + + static const ValueType* GetMember(const ValueType& value, const ValueType& name) { + typename ValueType::ConstMemberIterator itr = value.FindMember(name); + return itr != value.MemberEnd() ? &(itr->value) : 0; + } + + static void AssignIfExist(bool& out, const ValueType& value, const ValueType& name) { + if (const ValueType* v = GetMember(value, name)) + if (v->IsBool()) + out = v->GetBool(); + } + + static void AssignIfExist(SizeType& out, const ValueType& value, const ValueType& name) { + if (const ValueType* v = GetMember(value, name)) + if (v->IsUint64() && v->GetUint64() <= SizeType(~0)) + out = static_cast(v->GetUint64()); + } + + void AssignIfExist(SchemaArray& out, SchemaDocumentType& schemaDocument, const PointerType& p, const ValueType& value, const ValueType& name, const ValueType& document) { + if (const ValueType* v = GetMember(value, name)) { + if (v->IsArray() && v->Size() > 0) { + PointerType q = p.Append(name, allocator_); + out.count = v->Size(); + out.schemas = static_cast(allocator_->Malloc(out.count * sizeof(const Schema*))); + memset(out.schemas, 0, sizeof(Schema*)* out.count); + for (SizeType i = 0; i < out.count; i++) + schemaDocument.CreateSchema(&out.schemas[i], q.Append(i, allocator_), (*v)[i], document); + out.begin = validatorCount_; + validatorCount_ += out.count; + } + } + } + +#if RAPIDJSON_SCHEMA_USE_INTERNALREGEX + template + RegexType* CreatePattern(const ValueType& value) { + if (value.IsString()) { + RegexType* r = new (allocator_->Malloc(sizeof(RegexType))) RegexType(value.GetString()); + if (!r->IsValid()) { + r->~RegexType(); + AllocatorType::Free(r); + r = 0; + } + return r; + } + return 0; + } + + static bool IsPatternMatch(const RegexType* pattern, const Ch *str, SizeType) { + return pattern->Search(str); + } +#elif RAPIDJSON_SCHEMA_USE_STDREGEX + template + RegexType* CreatePattern(const ValueType& value) { + if (value.IsString()) + try { + return new (allocator_->Malloc(sizeof(RegexType))) RegexType(value.GetString(), std::size_t(value.GetStringLength()), std::regex_constants::ECMAScript); + } + catch (const std::regex_error&) { + } + return 0; + } + + static bool IsPatternMatch(const RegexType* pattern, const Ch *str, SizeType length) { + std::match_results r; + return std::regex_search(str, str + length, r, *pattern); + } +#else + template + RegexType* CreatePattern(const ValueType&) { return 0; } + + static bool IsPatternMatch(const RegexType*, const Ch *, SizeType) { return true; } +#endif // RAPIDJSON_SCHEMA_USE_STDREGEX + + void AddType(const ValueType& type) { + if (type == GetNullString() ) type_ |= 1 << kNullSchemaType; + else if (type == GetBooleanString()) type_ |= 1 << kBooleanSchemaType; + else if (type == GetObjectString() ) type_ |= 1 << kObjectSchemaType; + else if (type == GetArrayString() ) type_ |= 1 << kArraySchemaType; + else if (type == GetStringString() ) type_ |= 1 << kStringSchemaType; + else if (type == GetIntegerString()) type_ |= 1 << kIntegerSchemaType; + else if (type == GetNumberString() ) type_ |= (1 << kNumberSchemaType) | (1 << kIntegerSchemaType); + } + + bool CreateParallelValidator(Context& context) const { + if (enum_ || context.arrayUniqueness) + context.hasher = context.factory.CreateHasher(); + + if (validatorCount_) { + RAPIDJSON_ASSERT(context.validators == 0); + context.validators = static_cast(context.factory.MallocState(sizeof(ISchemaValidator*) * validatorCount_)); + context.validatorCount = validatorCount_; + + if (allOf_.schemas) + CreateSchemaValidators(context, allOf_); + + if (anyOf_.schemas) + CreateSchemaValidators(context, anyOf_); + + if (oneOf_.schemas) + CreateSchemaValidators(context, oneOf_); + + if (not_) + context.validators[notValidatorIndex_] = context.factory.CreateSchemaValidator(*not_); + + if (hasSchemaDependencies_) { + for (SizeType i = 0; i < propertyCount_; i++) + if (properties_[i].dependenciesSchema) + context.validators[properties_[i].dependenciesValidatorIndex] = context.factory.CreateSchemaValidator(*properties_[i].dependenciesSchema); + } + } + + return true; + } + + void CreateSchemaValidators(Context& context, const SchemaArray& schemas) const { + for (SizeType i = 0; i < schemas.count; i++) + context.validators[schemas.begin + i] = context.factory.CreateSchemaValidator(*schemas.schemas[i]); + } + + // O(n) + bool FindPropertyIndex(const ValueType& name, SizeType* outIndex) const { + SizeType len = name.GetStringLength(); + const Ch* str = name.GetString(); + for (SizeType index = 0; index < propertyCount_; index++) + if (properties_[index].name.GetStringLength() == len && + (std::memcmp(properties_[index].name.GetString(), str, sizeof(Ch) * len) == 0)) + { + *outIndex = index; + return true; + } + return false; + } + + bool CheckInt(Context& context, int64_t i) const { + if (!(type_ & ((1 << kIntegerSchemaType) | (1 << kNumberSchemaType)))) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString()); + + if (!minimum_.IsNull()) { + if (minimum_.IsInt64()) { + if (exclusiveMinimum_ ? i <= minimum_.GetInt64() : i < minimum_.GetInt64()) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinimumString()); + } + else if (minimum_.IsUint64()) { + RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinimumString()); // i <= max(int64_t) < minimum.GetUint64() + } + else if (!CheckDoubleMinimum(context, static_cast(i))) + return false; + } + + if (!maximum_.IsNull()) { + if (maximum_.IsInt64()) { + if (exclusiveMaximum_ ? i >= maximum_.GetInt64() : i > maximum_.GetInt64()) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaximumString()); + } + else if (maximum_.IsUint64()) + /* do nothing */; // i <= max(int64_t) < maximum_.GetUint64() + else if (!CheckDoubleMaximum(context, static_cast(i))) + return false; + } + + if (!multipleOf_.IsNull()) { + if (multipleOf_.IsUint64()) { + if (static_cast(i >= 0 ? i : -i) % multipleOf_.GetUint64() != 0) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetMultipleOfString()); + } + else if (!CheckDoubleMultipleOf(context, static_cast(i))) + return false; + } + + return true; + } + + bool CheckUint(Context& context, uint64_t i) const { + if (!(type_ & ((1 << kIntegerSchemaType) | (1 << kNumberSchemaType)))) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString()); + + if (!minimum_.IsNull()) { + if (minimum_.IsUint64()) { + if (exclusiveMinimum_ ? i <= minimum_.GetUint64() : i < minimum_.GetUint64()) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinimumString()); + } + else if (minimum_.IsInt64()) + /* do nothing */; // i >= 0 > minimum.Getint64() + else if (!CheckDoubleMinimum(context, static_cast(i))) + return false; + } + + if (!maximum_.IsNull()) { + if (maximum_.IsUint64()) { + if (exclusiveMaximum_ ? i >= maximum_.GetUint64() : i > maximum_.GetUint64()) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaximumString()); + } + else if (maximum_.IsInt64()) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaximumString()); // i >= 0 > maximum_ + else if (!CheckDoubleMaximum(context, static_cast(i))) + return false; + } + + if (!multipleOf_.IsNull()) { + if (multipleOf_.IsUint64()) { + if (i % multipleOf_.GetUint64() != 0) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetMultipleOfString()); + } + else if (!CheckDoubleMultipleOf(context, static_cast(i))) + return false; + } + + return true; + } + + bool CheckDoubleMinimum(Context& context, double d) const { + if (exclusiveMinimum_ ? d <= minimum_.GetDouble() : d < minimum_.GetDouble()) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinimumString()); + return true; + } + + bool CheckDoubleMaximum(Context& context, double d) const { + if (exclusiveMaximum_ ? d >= maximum_.GetDouble() : d > maximum_.GetDouble()) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaximumString()); + return true; + } + + bool CheckDoubleMultipleOf(Context& context, double d) const { + double a = std::abs(d), b = std::abs(multipleOf_.GetDouble()); + double q = std::floor(a / b); + double r = a - q * b; + if (r > 0.0) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetMultipleOfString()); + return true; + } + + struct Property { + Property() : schema(), dependenciesSchema(), dependenciesValidatorIndex(), dependencies(), required(false) {} + ~Property() { AllocatorType::Free(dependencies); } + SValue name; + const SchemaType* schema; + const SchemaType* dependenciesSchema; + SizeType dependenciesValidatorIndex; + bool* dependencies; + bool required; + }; + + struct PatternProperty { + PatternProperty() : schema(), pattern() {} + ~PatternProperty() { + if (pattern) { + pattern->~RegexType(); + AllocatorType::Free(pattern); + } + } + const SchemaType* schema; + RegexType* pattern; + }; + + AllocatorType* allocator_; + uint64_t* enum_; + SizeType enumCount_; + SchemaArray allOf_; + SchemaArray anyOf_; + SchemaArray oneOf_; + const SchemaType* not_; + unsigned type_; // bitmask of kSchemaType + SizeType validatorCount_; + SizeType notValidatorIndex_; + + Property* properties_; + const SchemaType* additionalPropertiesSchema_; + PatternProperty* patternProperties_; + SizeType patternPropertyCount_; + SizeType propertyCount_; + SizeType minProperties_; + SizeType maxProperties_; + bool additionalProperties_; + bool hasDependencies_; + bool hasRequired_; + bool hasSchemaDependencies_; + + const SchemaType* additionalItemsSchema_; + const SchemaType* itemsList_; + const SchemaType** itemsTuple_; + SizeType itemsTupleCount_; + SizeType minItems_; + SizeType maxItems_; + bool additionalItems_; + bool uniqueItems_; + + RegexType* pattern_; + SizeType minLength_; + SizeType maxLength_; + + SValue minimum_; + SValue maximum_; + SValue multipleOf_; + bool exclusiveMinimum_; + bool exclusiveMaximum_; +}; + +template +struct TokenHelper { + RAPIDJSON_FORCEINLINE static void AppendIndexToken(Stack& documentStack, SizeType index) { + *documentStack.template Push() = '/'; + char buffer[21]; + size_t length = static_cast((sizeof(SizeType) == 4 ? u32toa(index, buffer) : u64toa(index, buffer)) - buffer); + for (size_t i = 0; i < length; i++) + *documentStack.template Push() = buffer[i]; + } +}; + +// Partial specialized version for char to prevent buffer copying. +template +struct TokenHelper { + RAPIDJSON_FORCEINLINE static void AppendIndexToken(Stack& documentStack, SizeType index) { + if (sizeof(SizeType) == 4) { + char *buffer = documentStack.template Push(1 + 10); // '/' + uint + *buffer++ = '/'; + const char* end = internal::u32toa(index, buffer); + documentStack.template Pop(static_cast(10 - (end - buffer))); + } + else { + char *buffer = documentStack.template Push(1 + 20); // '/' + uint64 + *buffer++ = '/'; + const char* end = internal::u64toa(index, buffer); + documentStack.template Pop(static_cast(20 - (end - buffer))); + } + } +}; + +} // namespace internal + +/////////////////////////////////////////////////////////////////////////////// +// IGenericRemoteSchemaDocumentProvider + +template +class IGenericRemoteSchemaDocumentProvider { +public: + typedef typename SchemaDocumentType::Ch Ch; + + virtual ~IGenericRemoteSchemaDocumentProvider() {} + virtual const SchemaDocumentType* GetRemoteDocument(const Ch* uri, SizeType length) = 0; +}; + +/////////////////////////////////////////////////////////////////////////////// +// GenericSchemaDocument + +//! JSON schema document. +/*! + A JSON schema document is a compiled version of a JSON schema. + It is basically a tree of internal::Schema. + + \note This is an immutable class (i.e. its instance cannot be modified after construction). + \tparam ValueT Type of JSON value (e.g. \c Value ), which also determine the encoding. + \tparam Allocator Allocator type for allocating memory of this document. +*/ +template +class GenericSchemaDocument { +public: + typedef ValueT ValueType; + typedef IGenericRemoteSchemaDocumentProvider IRemoteSchemaDocumentProviderType; + typedef Allocator AllocatorType; + typedef typename ValueType::EncodingType EncodingType; + typedef typename EncodingType::Ch Ch; + typedef internal::Schema SchemaType; + typedef GenericPointer PointerType; + friend class internal::Schema; + template + friend class GenericSchemaValidator; + + //! Constructor. + /*! + Compile a JSON document into schema document. + + \param document A JSON document as source. + \param remoteProvider An optional remote schema document provider for resolving remote reference. Can be null. + \param allocator An optional allocator instance for allocating memory. Can be null. + */ + explicit GenericSchemaDocument(const ValueType& document, IRemoteSchemaDocumentProviderType* remoteProvider = 0, Allocator* allocator = 0) : + remoteProvider_(remoteProvider), + allocator_(allocator), + ownAllocator_(), + root_(), + schemaMap_(allocator, kInitialSchemaMapSize), + schemaRef_(allocator, kInitialSchemaRefSize) + { + if (!allocator_) + ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator()); + + // Generate root schema, it will call CreateSchema() to create sub-schemas, + // And call AddRefSchema() if there are $ref. + CreateSchemaRecursive(&root_, PointerType(), document, document); + + // Resolve $ref + while (!schemaRef_.Empty()) { + SchemaRefEntry* refEntry = schemaRef_.template Pop(1); + if (const SchemaType* s = GetSchema(refEntry->target)) { + if (refEntry->schema) + *refEntry->schema = s; + + // Create entry in map if not exist + if (!GetSchema(refEntry->source)) { + new (schemaMap_.template Push()) SchemaEntry(refEntry->source, const_cast(s), false, allocator_); + } + } + refEntry->~SchemaRefEntry(); + } + + RAPIDJSON_ASSERT(root_ != 0); + + schemaRef_.ShrinkToFit(); // Deallocate all memory for ref + } + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + //! Move constructor in C++11 + GenericSchemaDocument(GenericSchemaDocument&& rhs) RAPIDJSON_NOEXCEPT : + remoteProvider_(rhs.remoteProvider_), + allocator_(rhs.allocator_), + ownAllocator_(rhs.ownAllocator_), + root_(rhs.root_), + schemaMap_(std::move(rhs.schemaMap_)), + schemaRef_(std::move(rhs.schemaRef_)) + { + rhs.remoteProvider_ = 0; + rhs.allocator_ = 0; + rhs.ownAllocator_ = 0; + } +#endif + + //! Destructor + ~GenericSchemaDocument() { + while (!schemaMap_.Empty()) + schemaMap_.template Pop(1)->~SchemaEntry(); + + RAPIDJSON_DELETE(ownAllocator_); + } + + //! Get the root schema. + const SchemaType& GetRoot() const { return *root_; } + +private: + //! Prohibit copying + GenericSchemaDocument(const GenericSchemaDocument&); + //! Prohibit assignment + GenericSchemaDocument& operator=(const GenericSchemaDocument&); + + struct SchemaRefEntry { + SchemaRefEntry(const PointerType& s, const PointerType& t, const SchemaType** outSchema, Allocator *allocator) : source(s, allocator), target(t, allocator), schema(outSchema) {} + PointerType source; + PointerType target; + const SchemaType** schema; + }; + + struct SchemaEntry { + SchemaEntry(const PointerType& p, SchemaType* s, bool o, Allocator* allocator) : pointer(p, allocator), schema(s), owned(o) {} + ~SchemaEntry() { + if (owned) { + schema->~SchemaType(); + Allocator::Free(schema); + } + } + PointerType pointer; + SchemaType* schema; + bool owned; + }; + + void CreateSchemaRecursive(const SchemaType** schema, const PointerType& pointer, const ValueType& v, const ValueType& document) { + if (schema) + *schema = SchemaType::GetTypeless(); + + if (v.GetType() == kObjectType) { + const SchemaType* s = GetSchema(pointer); + if (!s) + CreateSchema(schema, pointer, v, document); + + for (typename ValueType::ConstMemberIterator itr = v.MemberBegin(); itr != v.MemberEnd(); ++itr) + CreateSchemaRecursive(0, pointer.Append(itr->name, allocator_), itr->value, document); + } + else if (v.GetType() == kArrayType) + for (SizeType i = 0; i < v.Size(); i++) + CreateSchemaRecursive(0, pointer.Append(i, allocator_), v[i], document); + } + + void CreateSchema(const SchemaType** schema, const PointerType& pointer, const ValueType& v, const ValueType& document) { + RAPIDJSON_ASSERT(pointer.IsValid()); + if (v.IsObject()) { + if (!HandleRefSchema(pointer, schema, v, document)) { + SchemaType* s = new (allocator_->Malloc(sizeof(SchemaType))) SchemaType(this, pointer, v, document, allocator_); + new (schemaMap_.template Push()) SchemaEntry(pointer, s, true, allocator_); + if (schema) + *schema = s; + } + } + } + + bool HandleRefSchema(const PointerType& source, const SchemaType** schema, const ValueType& v, const ValueType& document) { + static const Ch kRefString[] = { '$', 'r', 'e', 'f', '\0' }; + static const ValueType kRefValue(kRefString, 4); + + typename ValueType::ConstMemberIterator itr = v.FindMember(kRefValue); + if (itr == v.MemberEnd()) + return false; + + if (itr->value.IsString()) { + SizeType len = itr->value.GetStringLength(); + if (len > 0) { + const Ch* s = itr->value.GetString(); + SizeType i = 0; + while (i < len && s[i] != '#') // Find the first # + i++; + + if (i > 0) { // Remote reference, resolve immediately + if (remoteProvider_) { + if (const GenericSchemaDocument* remoteDocument = remoteProvider_->GetRemoteDocument(s, i - 1)) { + PointerType pointer(&s[i], len - i, allocator_); + if (pointer.IsValid()) { + if (const SchemaType* sc = remoteDocument->GetSchema(pointer)) { + if (schema) + *schema = sc; + return true; + } + } + } + } + } + else if (s[i] == '#') { // Local reference, defer resolution + PointerType pointer(&s[i], len - i, allocator_); + if (pointer.IsValid()) { + if (const ValueType* nv = pointer.Get(document)) + if (HandleRefSchema(source, schema, *nv, document)) + return true; + + new (schemaRef_.template Push()) SchemaRefEntry(source, pointer, schema, allocator_); + return true; + } + } + } + } + return false; + } + + const SchemaType* GetSchema(const PointerType& pointer) const { + for (const SchemaEntry* target = schemaMap_.template Bottom(); target != schemaMap_.template End(); ++target) + if (pointer == target->pointer) + return target->schema; + return 0; + } + + PointerType GetPointer(const SchemaType* schema) const { + for (const SchemaEntry* target = schemaMap_.template Bottom(); target != schemaMap_.template End(); ++target) + if (schema == target->schema) + return target->pointer; + return PointerType(); + } + + static const size_t kInitialSchemaMapSize = 64; + static const size_t kInitialSchemaRefSize = 64; + + IRemoteSchemaDocumentProviderType* remoteProvider_; + Allocator *allocator_; + Allocator *ownAllocator_; + const SchemaType* root_; //!< Root schema. + internal::Stack schemaMap_; // Stores created Pointer -> Schemas + internal::Stack schemaRef_; // Stores Pointer from $ref and schema which holds the $ref +}; + +//! GenericSchemaDocument using Value type. +typedef GenericSchemaDocument SchemaDocument; +//! IGenericRemoteSchemaDocumentProvider using SchemaDocument. +typedef IGenericRemoteSchemaDocumentProvider IRemoteSchemaDocumentProvider; + +/////////////////////////////////////////////////////////////////////////////// +// GenericSchemaValidator + +//! JSON Schema Validator. +/*! + A SAX style JSON schema validator. + It uses a \c GenericSchemaDocument to validate SAX events. + It delegates the incoming SAX events to an output handler. + The default output handler does nothing. + It can be reused multiple times by calling \c Reset(). + + \tparam SchemaDocumentType Type of schema document. + \tparam OutputHandler Type of output handler. Default handler does nothing. + \tparam StateAllocator Allocator for storing the internal validation states. +*/ +template < + typename SchemaDocumentType, + typename OutputHandler = BaseReaderHandler, + typename StateAllocator = CrtAllocator> +class GenericSchemaValidator : + public internal::ISchemaStateFactory, + public internal::ISchemaValidator +{ +public: + typedef typename SchemaDocumentType::SchemaType SchemaType; + typedef typename SchemaDocumentType::PointerType PointerType; + typedef typename SchemaType::EncodingType EncodingType; + typedef typename EncodingType::Ch Ch; + + //! Constructor without output handler. + /*! + \param schemaDocument The schema document to conform to. + \param allocator Optional allocator for storing internal validation states. + \param schemaStackCapacity Optional initial capacity of schema path stack. + \param documentStackCapacity Optional initial capacity of document path stack. + */ + GenericSchemaValidator( + const SchemaDocumentType& schemaDocument, + StateAllocator* allocator = 0, + size_t schemaStackCapacity = kDefaultSchemaStackCapacity, + size_t documentStackCapacity = kDefaultDocumentStackCapacity) + : + schemaDocument_(&schemaDocument), + root_(schemaDocument.GetRoot()), + outputHandler_(GetNullHandler()), + stateAllocator_(allocator), + ownStateAllocator_(0), + schemaStack_(allocator, schemaStackCapacity), + documentStack_(allocator, documentStackCapacity), + valid_(true) +#if RAPIDJSON_SCHEMA_VERBOSE + , depth_(0) +#endif + { + } + + //! Constructor with output handler. + /*! + \param schemaDocument The schema document to conform to. + \param allocator Optional allocator for storing internal validation states. + \param schemaStackCapacity Optional initial capacity of schema path stack. + \param documentStackCapacity Optional initial capacity of document path stack. + */ + GenericSchemaValidator( + const SchemaDocumentType& schemaDocument, + OutputHandler& outputHandler, + StateAllocator* allocator = 0, + size_t schemaStackCapacity = kDefaultSchemaStackCapacity, + size_t documentStackCapacity = kDefaultDocumentStackCapacity) + : + schemaDocument_(&schemaDocument), + root_(schemaDocument.GetRoot()), + outputHandler_(outputHandler), + stateAllocator_(allocator), + ownStateAllocator_(0), + schemaStack_(allocator, schemaStackCapacity), + documentStack_(allocator, documentStackCapacity), + valid_(true) +#if RAPIDJSON_SCHEMA_VERBOSE + , depth_(0) +#endif + { + } + + //! Destructor. + ~GenericSchemaValidator() { + Reset(); + RAPIDJSON_DELETE(ownStateAllocator_); + } + + //! Reset the internal states. + void Reset() { + while (!schemaStack_.Empty()) + PopSchema(); + documentStack_.Clear(); + valid_ = true; + } + + //! Checks whether the current state is valid. + // Implementation of ISchemaValidator + virtual bool IsValid() const { return valid_; } + + //! Gets the JSON pointer pointed to the invalid schema. + PointerType GetInvalidSchemaPointer() const { + return schemaStack_.Empty() ? PointerType() : schemaDocument_->GetPointer(&CurrentSchema()); + } + + //! Gets the keyword of invalid schema. + const Ch* GetInvalidSchemaKeyword() const { + return schemaStack_.Empty() ? 0 : CurrentContext().invalidKeyword; + } + + //! Gets the JSON pointer pointed to the invalid value. + PointerType GetInvalidDocumentPointer() const { + return documentStack_.Empty() ? PointerType() : PointerType(documentStack_.template Bottom(), documentStack_.GetSize() / sizeof(Ch)); + } + +#if RAPIDJSON_SCHEMA_VERBOSE +#define RAPIDJSON_SCHEMA_HANDLE_BEGIN_VERBOSE_() \ +RAPIDJSON_MULTILINEMACRO_BEGIN\ + *documentStack_.template Push() = '\0';\ + documentStack_.template Pop(1);\ + internal::PrintInvalidDocument(documentStack_.template Bottom());\ +RAPIDJSON_MULTILINEMACRO_END +#else +#define RAPIDJSON_SCHEMA_HANDLE_BEGIN_VERBOSE_() +#endif + +#define RAPIDJSON_SCHEMA_HANDLE_BEGIN_(method, arg1)\ + if (!valid_) return false; \ + if (!BeginValue() || !CurrentSchema().method arg1) {\ + RAPIDJSON_SCHEMA_HANDLE_BEGIN_VERBOSE_();\ + return valid_ = false;\ + } + +#define RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(method, arg2)\ + for (Context* context = schemaStack_.template Bottom(); context != schemaStack_.template End(); context++) {\ + if (context->hasher)\ + static_cast(context->hasher)->method arg2;\ + if (context->validators)\ + for (SizeType i_ = 0; i_ < context->validatorCount; i_++)\ + static_cast(context->validators[i_])->method arg2;\ + if (context->patternPropertiesValidators)\ + for (SizeType i_ = 0; i_ < context->patternPropertiesValidatorCount; i_++)\ + static_cast(context->patternPropertiesValidators[i_])->method arg2;\ + } + +#define RAPIDJSON_SCHEMA_HANDLE_END_(method, arg2)\ + return valid_ = EndValue() && outputHandler_.method arg2 + +#define RAPIDJSON_SCHEMA_HANDLE_VALUE_(method, arg1, arg2) \ + RAPIDJSON_SCHEMA_HANDLE_BEGIN_ (method, arg1);\ + RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(method, arg2);\ + RAPIDJSON_SCHEMA_HANDLE_END_ (method, arg2) + + bool Null() { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Null, (CurrentContext() ), ( )); } + bool Bool(bool b) { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Bool, (CurrentContext(), b), (b)); } + bool Int(int i) { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Int, (CurrentContext(), i), (i)); } + bool Uint(unsigned u) { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Uint, (CurrentContext(), u), (u)); } + bool Int64(int64_t i) { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Int64, (CurrentContext(), i), (i)); } + bool Uint64(uint64_t u) { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Uint64, (CurrentContext(), u), (u)); } + bool Double(double d) { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Double, (CurrentContext(), d), (d)); } + bool RawNumber(const Ch* str, SizeType length, bool copy) + { RAPIDJSON_SCHEMA_HANDLE_VALUE_(String, (CurrentContext(), str, length, copy), (str, length, copy)); } + bool String(const Ch* str, SizeType length, bool copy) + { RAPIDJSON_SCHEMA_HANDLE_VALUE_(String, (CurrentContext(), str, length, copy), (str, length, copy)); } + + bool StartObject() { + RAPIDJSON_SCHEMA_HANDLE_BEGIN_(StartObject, (CurrentContext())); + RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(StartObject, ()); + return valid_ = outputHandler_.StartObject(); + } + + bool Key(const Ch* str, SizeType len, bool copy) { + if (!valid_) return false; + AppendToken(str, len); + if (!CurrentSchema().Key(CurrentContext(), str, len, copy)) return valid_ = false; + RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(Key, (str, len, copy)); + return valid_ = outputHandler_.Key(str, len, copy); + } + + bool EndObject(SizeType memberCount) { + if (!valid_) return false; + RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(EndObject, (memberCount)); + if (!CurrentSchema().EndObject(CurrentContext(), memberCount)) return valid_ = false; + RAPIDJSON_SCHEMA_HANDLE_END_(EndObject, (memberCount)); + } + + bool StartArray() { + RAPIDJSON_SCHEMA_HANDLE_BEGIN_(StartArray, (CurrentContext())); + RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(StartArray, ()); + return valid_ = outputHandler_.StartArray(); + } + + bool EndArray(SizeType elementCount) { + if (!valid_) return false; + RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(EndArray, (elementCount)); + if (!CurrentSchema().EndArray(CurrentContext(), elementCount)) return valid_ = false; + RAPIDJSON_SCHEMA_HANDLE_END_(EndArray, (elementCount)); + } + +#undef RAPIDJSON_SCHEMA_HANDLE_BEGIN_VERBOSE_ +#undef RAPIDJSON_SCHEMA_HANDLE_BEGIN_ +#undef RAPIDJSON_SCHEMA_HANDLE_PARALLEL_ +#undef RAPIDJSON_SCHEMA_HANDLE_VALUE_ + + // Implementation of ISchemaStateFactory + virtual ISchemaValidator* CreateSchemaValidator(const SchemaType& root) { + return new (GetStateAllocator().Malloc(sizeof(GenericSchemaValidator))) GenericSchemaValidator(*schemaDocument_, root, +#if RAPIDJSON_SCHEMA_VERBOSE + depth_ + 1, +#endif + &GetStateAllocator()); + } + + virtual void DestroySchemaValidator(ISchemaValidator* validator) { + GenericSchemaValidator* v = static_cast(validator); + v->~GenericSchemaValidator(); + StateAllocator::Free(v); + } + + virtual void* CreateHasher() { + return new (GetStateAllocator().Malloc(sizeof(HasherType))) HasherType(&GetStateAllocator()); + } + + virtual uint64_t GetHashCode(void* hasher) { + return static_cast(hasher)->GetHashCode(); + } + + virtual void DestroryHasher(void* hasher) { + HasherType* h = static_cast(hasher); + h->~HasherType(); + StateAllocator::Free(h); + } + + virtual void* MallocState(size_t size) { + return GetStateAllocator().Malloc(size); + } + + virtual void FreeState(void* p) { + return StateAllocator::Free(p); + } + +private: + typedef typename SchemaType::Context Context; + typedef GenericValue, StateAllocator> HashCodeArray; + typedef internal::Hasher HasherType; + + GenericSchemaValidator( + const SchemaDocumentType& schemaDocument, + const SchemaType& root, +#if RAPIDJSON_SCHEMA_VERBOSE + unsigned depth, +#endif + StateAllocator* allocator = 0, + size_t schemaStackCapacity = kDefaultSchemaStackCapacity, + size_t documentStackCapacity = kDefaultDocumentStackCapacity) + : + schemaDocument_(&schemaDocument), + root_(root), + outputHandler_(GetNullHandler()), + stateAllocator_(allocator), + ownStateAllocator_(0), + schemaStack_(allocator, schemaStackCapacity), + documentStack_(allocator, documentStackCapacity), + valid_(true) +#if RAPIDJSON_SCHEMA_VERBOSE + , depth_(depth) +#endif + { + } + + StateAllocator& GetStateAllocator() { + if (!stateAllocator_) + stateAllocator_ = ownStateAllocator_ = RAPIDJSON_NEW(StateAllocator()); + return *stateAllocator_; + } + + bool BeginValue() { + if (schemaStack_.Empty()) + PushSchema(root_); + else { + if (CurrentContext().inArray) + internal::TokenHelper, Ch>::AppendIndexToken(documentStack_, CurrentContext().arrayElementIndex); + + if (!CurrentSchema().BeginValue(CurrentContext())) + return false; + + SizeType count = CurrentContext().patternPropertiesSchemaCount; + const SchemaType** sa = CurrentContext().patternPropertiesSchemas; + typename Context::PatternValidatorType patternValidatorType = CurrentContext().valuePatternValidatorType; + bool valueUniqueness = CurrentContext().valueUniqueness; + if (CurrentContext().valueSchema) + PushSchema(*CurrentContext().valueSchema); + + if (count > 0) { + CurrentContext().objectPatternValidatorType = patternValidatorType; + ISchemaValidator**& va = CurrentContext().patternPropertiesValidators; + SizeType& validatorCount = CurrentContext().patternPropertiesValidatorCount; + va = static_cast(MallocState(sizeof(ISchemaValidator*) * count)); + for (SizeType i = 0; i < count; i++) + va[validatorCount++] = CreateSchemaValidator(*sa[i]); + } + + CurrentContext().arrayUniqueness = valueUniqueness; + } + return true; + } + + bool EndValue() { + if (!CurrentSchema().EndValue(CurrentContext())) + return false; + +#if RAPIDJSON_SCHEMA_VERBOSE + GenericStringBuffer sb; + schemaDocument_->GetPointer(&CurrentSchema()).Stringify(sb); + + *documentStack_.template Push() = '\0'; + documentStack_.template Pop(1); + internal::PrintValidatorPointers(depth_, sb.GetString(), documentStack_.template Bottom()); +#endif + + uint64_t h = CurrentContext().arrayUniqueness ? static_cast(CurrentContext().hasher)->GetHashCode() : 0; + + PopSchema(); + + if (!schemaStack_.Empty()) { + Context& context = CurrentContext(); + if (context.valueUniqueness) { + HashCodeArray* a = static_cast(context.arrayElementHashCodes); + if (!a) + CurrentContext().arrayElementHashCodes = a = new (GetStateAllocator().Malloc(sizeof(HashCodeArray))) HashCodeArray(kArrayType); + for (typename HashCodeArray::ConstValueIterator itr = a->Begin(); itr != a->End(); ++itr) + if (itr->GetUint64() == h) + RAPIDJSON_INVALID_KEYWORD_RETURN(SchemaType::GetUniqueItemsString()); + a->PushBack(h, GetStateAllocator()); + } + } + + // Remove the last token of document pointer + while (!documentStack_.Empty() && *documentStack_.template Pop(1) != '/') + ; + + return true; + } + + void AppendToken(const Ch* str, SizeType len) { + documentStack_.template Reserve(1 + len * 2); // worst case all characters are escaped as two characters + *documentStack_.template PushUnsafe() = '/'; + for (SizeType i = 0; i < len; i++) { + if (str[i] == '~') { + *documentStack_.template PushUnsafe() = '~'; + *documentStack_.template PushUnsafe() = '0'; + } + else if (str[i] == '/') { + *documentStack_.template PushUnsafe() = '~'; + *documentStack_.template PushUnsafe() = '1'; + } + else + *documentStack_.template PushUnsafe() = str[i]; + } + } + + RAPIDJSON_FORCEINLINE void PushSchema(const SchemaType& schema) { new (schemaStack_.template Push()) Context(*this, &schema); } + + RAPIDJSON_FORCEINLINE void PopSchema() { + Context* c = schemaStack_.template Pop(1); + if (HashCodeArray* a = static_cast(c->arrayElementHashCodes)) { + a->~HashCodeArray(); + StateAllocator::Free(a); + } + c->~Context(); + } + + const SchemaType& CurrentSchema() const { return *schemaStack_.template Top()->schema; } + Context& CurrentContext() { return *schemaStack_.template Top(); } + const Context& CurrentContext() const { return *schemaStack_.template Top(); } + + static OutputHandler& GetNullHandler() { + static OutputHandler nullHandler; + return nullHandler; + } + + static const size_t kDefaultSchemaStackCapacity = 1024; + static const size_t kDefaultDocumentStackCapacity = 256; + const SchemaDocumentType* schemaDocument_; + const SchemaType& root_; + OutputHandler& outputHandler_; + StateAllocator* stateAllocator_; + StateAllocator* ownStateAllocator_; + internal::Stack schemaStack_; //!< stack to store the current path of schema (BaseSchemaType *) + internal::Stack documentStack_; //!< stack to store the current path of validating document (Ch) + bool valid_; +#if RAPIDJSON_SCHEMA_VERBOSE + unsigned depth_; +#endif +}; + +typedef GenericSchemaValidator SchemaValidator; + +/////////////////////////////////////////////////////////////////////////////// +// SchemaValidatingReader + +//! A helper class for parsing with validation. +/*! + This helper class is a functor, designed as a parameter of \ref GenericDocument::Populate(). + + \tparam parseFlags Combination of \ref ParseFlag. + \tparam InputStream Type of input stream, implementing Stream concept. + \tparam SourceEncoding Encoding of the input stream. + \tparam SchemaDocumentType Type of schema document. + \tparam StackAllocator Allocator type for stack. +*/ +template < + unsigned parseFlags, + typename InputStream, + typename SourceEncoding, + typename SchemaDocumentType = SchemaDocument, + typename StackAllocator = CrtAllocator> +class SchemaValidatingReader { +public: + typedef typename SchemaDocumentType::PointerType PointerType; + typedef typename InputStream::Ch Ch; + + //! Constructor + /*! + \param is Input stream. + \param sd Schema document. + */ + SchemaValidatingReader(InputStream& is, const SchemaDocumentType& sd) : is_(is), sd_(sd), invalidSchemaKeyword_(), isValid_(true) {} + + template + bool operator()(Handler& handler) { + GenericReader reader; + GenericSchemaValidator validator(sd_, handler); + parseResult_ = reader.template Parse(is_, validator); + + isValid_ = validator.IsValid(); + if (isValid_) { + invalidSchemaPointer_ = PointerType(); + invalidSchemaKeyword_ = 0; + invalidDocumentPointer_ = PointerType(); + } + else { + invalidSchemaPointer_ = validator.GetInvalidSchemaPointer(); + invalidSchemaKeyword_ = validator.GetInvalidSchemaKeyword(); + invalidDocumentPointer_ = validator.GetInvalidDocumentPointer(); + } + + return parseResult_; + } + + const ParseResult& GetParseResult() const { return parseResult_; } + bool IsValid() const { return isValid_; } + const PointerType& GetInvalidSchemaPointer() const { return invalidSchemaPointer_; } + const Ch* GetInvalidSchemaKeyword() const { return invalidSchemaKeyword_; } + const PointerType& GetInvalidDocumentPointer() const { return invalidDocumentPointer_; } + +private: + InputStream& is_; + const SchemaDocumentType& sd_; + + ParseResult parseResult_; + PointerType invalidSchemaPointer_; + const Ch* invalidSchemaKeyword_; + PointerType invalidDocumentPointer_; + bool isValid_; +}; + +RAPIDJSON_NAMESPACE_END +RAPIDJSON_DIAG_POP + +#endif // RAPIDJSON_SCHEMA_H_ diff --git a/slsReceiverSoftware/include/rapidjson/stream.h b/slsReceiverSoftware/include/rapidjson/stream.h new file mode 100644 index 000000000..fef82c252 --- /dev/null +++ b/slsReceiverSoftware/include/rapidjson/stream.h @@ -0,0 +1,179 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#include "rapidjson.h" + +#ifndef RAPIDJSON_STREAM_H_ +#define RAPIDJSON_STREAM_H_ + +#include "encodings.h" + +RAPIDJSON_NAMESPACE_BEGIN + +/////////////////////////////////////////////////////////////////////////////// +// Stream + +/*! \class rapidjson::Stream + \brief Concept for reading and writing characters. + + For read-only stream, no need to implement PutBegin(), Put(), Flush() and PutEnd(). + + For write-only stream, only need to implement Put() and Flush(). + +\code +concept Stream { + typename Ch; //!< Character type of the stream. + + //! Read the current character from stream without moving the read cursor. + Ch Peek() const; + + //! Read the current character from stream and moving the read cursor to next character. + Ch Take(); + + //! Get the current read cursor. + //! \return Number of characters read from start. + size_t Tell(); + + //! Begin writing operation at the current read pointer. + //! \return The begin writer pointer. + Ch* PutBegin(); + + //! Write a character. + void Put(Ch c); + + //! Flush the buffer. + void Flush(); + + //! End the writing operation. + //! \param begin The begin write pointer returned by PutBegin(). + //! \return Number of characters written. + size_t PutEnd(Ch* begin); +} +\endcode +*/ + +//! Provides additional information for stream. +/*! + By using traits pattern, this type provides a default configuration for stream. + For custom stream, this type can be specialized for other configuration. + See TEST(Reader, CustomStringStream) in readertest.cpp for example. +*/ +template +struct StreamTraits { + //! Whether to make local copy of stream for optimization during parsing. + /*! + By default, for safety, streams do not use local copy optimization. + Stream that can be copied fast should specialize this, like StreamTraits. + */ + enum { copyOptimization = 0 }; +}; + +//! Reserve n characters for writing to a stream. +template +inline void PutReserve(Stream& stream, size_t count) { + (void)stream; + (void)count; +} + +//! Write character to a stream, presuming buffer is reserved. +template +inline void PutUnsafe(Stream& stream, typename Stream::Ch c) { + stream.Put(c); +} + +//! Put N copies of a character to a stream. +template +inline void PutN(Stream& stream, Ch c, size_t n) { + PutReserve(stream, n); + for (size_t i = 0; i < n; i++) + PutUnsafe(stream, c); +} + +/////////////////////////////////////////////////////////////////////////////// +// StringStream + +//! Read-only string stream. +/*! \note implements Stream concept +*/ +template +struct GenericStringStream { + typedef typename Encoding::Ch Ch; + + GenericStringStream(const Ch *src) : src_(src), head_(src) {} + + Ch Peek() const { return *src_; } + Ch Take() { return *src_++; } + size_t Tell() const { return static_cast(src_ - head_); } + + Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } + void Put(Ch) { RAPIDJSON_ASSERT(false); } + void Flush() { RAPIDJSON_ASSERT(false); } + size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } + + const Ch* src_; //!< Current read position. + const Ch* head_; //!< Original head of the string. +}; + +template +struct StreamTraits > { + enum { copyOptimization = 1 }; +}; + +//! String stream with UTF8 encoding. +typedef GenericStringStream > StringStream; + +/////////////////////////////////////////////////////////////////////////////// +// InsituStringStream + +//! A read-write string stream. +/*! This string stream is particularly designed for in-situ parsing. + \note implements Stream concept +*/ +template +struct GenericInsituStringStream { + typedef typename Encoding::Ch Ch; + + GenericInsituStringStream(Ch *src) : src_(src), dst_(0), head_(src) {} + + // Read + Ch Peek() { return *src_; } + Ch Take() { return *src_++; } + size_t Tell() { return static_cast(src_ - head_); } + + // Write + void Put(Ch c) { RAPIDJSON_ASSERT(dst_ != 0); *dst_++ = c; } + + Ch* PutBegin() { return dst_ = src_; } + size_t PutEnd(Ch* begin) { return static_cast(dst_ - begin); } + void Flush() {} + + Ch* Push(size_t count) { Ch* begin = dst_; dst_ += count; return begin; } + void Pop(size_t count) { dst_ -= count; } + + Ch* src_; + Ch* dst_; + Ch* head_; +}; + +template +struct StreamTraits > { + enum { copyOptimization = 1 }; +}; + +//! Insitu string stream with UTF8 encoding. +typedef GenericInsituStringStream > InsituStringStream; + +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_STREAM_H_ diff --git a/slsReceiverSoftware/include/rapidjson/stringbuffer.h b/slsReceiverSoftware/include/rapidjson/stringbuffer.h new file mode 100644 index 000000000..78f34d209 --- /dev/null +++ b/slsReceiverSoftware/include/rapidjson/stringbuffer.h @@ -0,0 +1,117 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_STRINGBUFFER_H_ +#define RAPIDJSON_STRINGBUFFER_H_ + +#include "stream.h" +#include "internal/stack.h" + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS +#include // std::move +#endif + +#include "internal/stack.h" + +#if defined(__clang__) +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(c++98-compat) +#endif + +RAPIDJSON_NAMESPACE_BEGIN + +//! Represents an in-memory output stream. +/*! + \tparam Encoding Encoding of the stream. + \tparam Allocator type for allocating memory buffer. + \note implements Stream concept +*/ +template +class GenericStringBuffer { +public: + typedef typename Encoding::Ch Ch; + + GenericStringBuffer(Allocator* allocator = 0, size_t capacity = kDefaultCapacity) : stack_(allocator, capacity) {} + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + GenericStringBuffer(GenericStringBuffer&& rhs) : stack_(std::move(rhs.stack_)) {} + GenericStringBuffer& operator=(GenericStringBuffer&& rhs) { + if (&rhs != this) + stack_ = std::move(rhs.stack_); + return *this; + } +#endif + + void Put(Ch c) { *stack_.template Push() = c; } + void PutUnsafe(Ch c) { *stack_.template PushUnsafe() = c; } + void Flush() {} + + void Clear() { stack_.Clear(); } + void ShrinkToFit() { + // Push and pop a null terminator. This is safe. + *stack_.template Push() = '\0'; + stack_.ShrinkToFit(); + stack_.template Pop(1); + } + + void Reserve(size_t count) { stack_.template Reserve(count); } + Ch* Push(size_t count) { return stack_.template Push(count); } + Ch* PushUnsafe(size_t count) { return stack_.template PushUnsafe(count); } + void Pop(size_t count) { stack_.template Pop(count); } + + const Ch* GetString() const { + // Push and pop a null terminator. This is safe. + *stack_.template Push() = '\0'; + stack_.template Pop(1); + + return stack_.template Bottom(); + } + + size_t GetSize() const { return stack_.GetSize(); } + + static const size_t kDefaultCapacity = 256; + mutable internal::Stack stack_; + +private: + // Prohibit copy constructor & assignment operator. + GenericStringBuffer(const GenericStringBuffer&); + GenericStringBuffer& operator=(const GenericStringBuffer&); +}; + +//! String buffer with UTF8 encoding +typedef GenericStringBuffer > StringBuffer; + +template +inline void PutReserve(GenericStringBuffer& stream, size_t count) { + stream.Reserve(count); +} + +template +inline void PutUnsafe(GenericStringBuffer& stream, typename Encoding::Ch c) { + stream.PutUnsafe(c); +} + +//! Implement specialized version of PutN() with memset() for better performance. +template<> +inline void PutN(GenericStringBuffer >& stream, char c, size_t n) { + std::memset(stream.stack_.Push(n), c, n * sizeof(c)); +} + +RAPIDJSON_NAMESPACE_END + +#if defined(__clang__) +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_STRINGBUFFER_H_ diff --git a/slsReceiverSoftware/include/rapidjson/writer.h b/slsReceiverSoftware/include/rapidjson/writer.h new file mode 100644 index 000000000..94f22dd5f --- /dev/null +++ b/slsReceiverSoftware/include/rapidjson/writer.h @@ -0,0 +1,610 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_WRITER_H_ +#define RAPIDJSON_WRITER_H_ + +#include "stream.h" +#include "internal/stack.h" +#include "internal/strfunc.h" +#include "internal/dtoa.h" +#include "internal/itoa.h" +#include "stringbuffer.h" +#include // placement new + +#if defined(RAPIDJSON_SIMD) && defined(_MSC_VER) +#include +#pragma intrinsic(_BitScanForward) +#endif +#ifdef RAPIDJSON_SSE42 +#include +#elif defined(RAPIDJSON_SSE2) +#include +#endif + +#ifdef _MSC_VER +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant +#endif + +#ifdef __clang__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(padded) +RAPIDJSON_DIAG_OFF(unreachable-code) +#endif + +RAPIDJSON_NAMESPACE_BEGIN + +/////////////////////////////////////////////////////////////////////////////// +// WriteFlag + +/*! \def RAPIDJSON_WRITE_DEFAULT_FLAGS + \ingroup RAPIDJSON_CONFIG + \brief User-defined kWriteDefaultFlags definition. + + User can define this as any \c WriteFlag combinations. +*/ +#ifndef RAPIDJSON_WRITE_DEFAULT_FLAGS +#define RAPIDJSON_WRITE_DEFAULT_FLAGS kWriteNoFlags +#endif + +//! Combination of writeFlags +enum WriteFlag { + kWriteNoFlags = 0, //!< No flags are set. + kWriteValidateEncodingFlag = 1, //!< Validate encoding of JSON strings. + kWriteNanAndInfFlag = 2, //!< Allow writing of Infinity, -Infinity and NaN. + kWriteDefaultFlags = RAPIDJSON_WRITE_DEFAULT_FLAGS //!< Default write flags. Can be customized by defining RAPIDJSON_WRITE_DEFAULT_FLAGS +}; + +//! JSON writer +/*! Writer implements the concept Handler. + It generates JSON text by events to an output os. + + User may programmatically calls the functions of a writer to generate JSON text. + + On the other side, a writer can also be passed to objects that generates events, + + for example Reader::Parse() and Document::Accept(). + + \tparam OutputStream Type of output stream. + \tparam SourceEncoding Encoding of source string. + \tparam TargetEncoding Encoding of output stream. + \tparam StackAllocator Type of allocator for allocating memory of stack. + \note implements Handler concept +*/ +template, typename TargetEncoding = UTF8<>, typename StackAllocator = CrtAllocator, unsigned writeFlags = kWriteDefaultFlags> +class Writer { +public: + typedef typename SourceEncoding::Ch Ch; + + static const int kDefaultMaxDecimalPlaces = 324; + + //! Constructor + /*! \param os Output stream. + \param stackAllocator User supplied allocator. If it is null, it will create a private one. + \param levelDepth Initial capacity of stack. + */ + explicit + Writer(OutputStream& os, StackAllocator* stackAllocator = 0, size_t levelDepth = kDefaultLevelDepth) : + os_(&os), level_stack_(stackAllocator, levelDepth * sizeof(Level)), maxDecimalPlaces_(kDefaultMaxDecimalPlaces), hasRoot_(false) {} + + explicit + Writer(StackAllocator* allocator = 0, size_t levelDepth = kDefaultLevelDepth) : + os_(0), level_stack_(allocator, levelDepth * sizeof(Level)), maxDecimalPlaces_(kDefaultMaxDecimalPlaces), hasRoot_(false) {} + + //! Reset the writer with a new stream. + /*! + This function reset the writer with a new stream and default settings, + in order to make a Writer object reusable for output multiple JSONs. + + \param os New output stream. + \code + Writer writer(os1); + writer.StartObject(); + // ... + writer.EndObject(); + + writer.Reset(os2); + writer.StartObject(); + // ... + writer.EndObject(); + \endcode + */ + void Reset(OutputStream& os) { + os_ = &os; + hasRoot_ = false; + level_stack_.Clear(); + } + + //! Checks whether the output is a complete JSON. + /*! + A complete JSON has a complete root object or array. + */ + bool IsComplete() const { + return hasRoot_ && level_stack_.Empty(); + } + + int GetMaxDecimalPlaces() const { + return maxDecimalPlaces_; + } + + //! Sets the maximum number of decimal places for double output. + /*! + This setting truncates the output with specified number of decimal places. + + For example, + + \code + writer.SetMaxDecimalPlaces(3); + writer.StartArray(); + writer.Double(0.12345); // "0.123" + writer.Double(0.0001); // "0.0" + writer.Double(1.234567890123456e30); // "1.234567890123456e30" (do not truncate significand for positive exponent) + writer.Double(1.23e-4); // "0.0" (do truncate significand for negative exponent) + writer.EndArray(); + \endcode + + The default setting does not truncate any decimal places. You can restore to this setting by calling + \code + writer.SetMaxDecimalPlaces(Writer::kDefaultMaxDecimalPlaces); + \endcode + */ + void SetMaxDecimalPlaces(int maxDecimalPlaces) { + maxDecimalPlaces_ = maxDecimalPlaces; + } + + /*!@name Implementation of Handler + \see Handler + */ + //@{ + + bool Null() { Prefix(kNullType); return EndValue(WriteNull()); } + bool Bool(bool b) { Prefix(b ? kTrueType : kFalseType); return EndValue(WriteBool(b)); } + bool Int(int i) { Prefix(kNumberType); return EndValue(WriteInt(i)); } + bool Uint(unsigned u) { Prefix(kNumberType); return EndValue(WriteUint(u)); } + bool Int64(int64_t i64) { Prefix(kNumberType); return EndValue(WriteInt64(i64)); } + bool Uint64(uint64_t u64) { Prefix(kNumberType); return EndValue(WriteUint64(u64)); } + + //! Writes the given \c double value to the stream + /*! + \param d The value to be written. + \return Whether it is succeed. + */ + bool Double(double d) { Prefix(kNumberType); return EndValue(WriteDouble(d)); } + + bool RawNumber(const Ch* str, SizeType length, bool copy = false) { + (void)copy; + Prefix(kNumberType); + return EndValue(WriteString(str, length)); + } + + bool String(const Ch* str, SizeType length, bool copy = false) { + (void)copy; + Prefix(kStringType); + return EndValue(WriteString(str, length)); + } + +#if RAPIDJSON_HAS_STDSTRING + bool String(const std::basic_string& str) { + return String(str.data(), SizeType(str.size())); + } +#endif + + bool StartObject() { + Prefix(kObjectType); + new (level_stack_.template Push()) Level(false); + return WriteStartObject(); + } + + bool Key(const Ch* str, SizeType length, bool copy = false) { return String(str, length, copy); } + + bool EndObject(SizeType memberCount = 0) { + (void)memberCount; + RAPIDJSON_ASSERT(level_stack_.GetSize() >= sizeof(Level)); + RAPIDJSON_ASSERT(!level_stack_.template Top()->inArray); + level_stack_.template Pop(1); + return EndValue(WriteEndObject()); + } + + bool StartArray() { + Prefix(kArrayType); + new (level_stack_.template Push()) Level(true); + return WriteStartArray(); + } + + bool EndArray(SizeType elementCount = 0) { + (void)elementCount; + RAPIDJSON_ASSERT(level_stack_.GetSize() >= sizeof(Level)); + RAPIDJSON_ASSERT(level_stack_.template Top()->inArray); + level_stack_.template Pop(1); + return EndValue(WriteEndArray()); + } + //@} + + /*! @name Convenience extensions */ + //@{ + + //! Simpler but slower overload. + bool String(const Ch* str) { return String(str, internal::StrLen(str)); } + bool Key(const Ch* str) { return Key(str, internal::StrLen(str)); } + + //@} + + //! Write a raw JSON value. + /*! + For user to write a stringified JSON as a value. + + \param json A well-formed JSON value. It should not contain null character within [0, length - 1] range. + \param length Length of the json. + \param type Type of the root of json. + */ + bool RawValue(const Ch* json, size_t length, Type type) { Prefix(type); return EndValue(WriteRawValue(json, length)); } + +protected: + //! Information for each nested level + struct Level { + Level(bool inArray_) : valueCount(0), inArray(inArray_) {} + size_t valueCount; //!< number of values in this level + bool inArray; //!< true if in array, otherwise in object + }; + + static const size_t kDefaultLevelDepth = 32; + + bool WriteNull() { + PutReserve(*os_, 4); + PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'u'); PutUnsafe(*os_, 'l'); PutUnsafe(*os_, 'l'); return true; + } + + bool WriteBool(bool b) { + if (b) { + PutReserve(*os_, 4); + PutUnsafe(*os_, 't'); PutUnsafe(*os_, 'r'); PutUnsafe(*os_, 'u'); PutUnsafe(*os_, 'e'); + } + else { + PutReserve(*os_, 5); + PutUnsafe(*os_, 'f'); PutUnsafe(*os_, 'a'); PutUnsafe(*os_, 'l'); PutUnsafe(*os_, 's'); PutUnsafe(*os_, 'e'); + } + return true; + } + + bool WriteInt(int i) { + char buffer[11]; + const char* end = internal::i32toa(i, buffer); + PutReserve(*os_, static_cast(end - buffer)); + for (const char* p = buffer; p != end; ++p) + PutUnsafe(*os_, static_cast(*p)); + return true; + } + + bool WriteUint(unsigned u) { + char buffer[10]; + const char* end = internal::u32toa(u, buffer); + PutReserve(*os_, static_cast(end - buffer)); + for (const char* p = buffer; p != end; ++p) + PutUnsafe(*os_, static_cast(*p)); + return true; + } + + bool WriteInt64(int64_t i64) { + char buffer[21]; + const char* end = internal::i64toa(i64, buffer); + PutReserve(*os_, static_cast(end - buffer)); + for (const char* p = buffer; p != end; ++p) + PutUnsafe(*os_, static_cast(*p)); + return true; + } + + bool WriteUint64(uint64_t u64) { + char buffer[20]; + char* end = internal::u64toa(u64, buffer); + PutReserve(*os_, static_cast(end - buffer)); + for (char* p = buffer; p != end; ++p) + PutUnsafe(*os_, static_cast(*p)); + return true; + } + + bool WriteDouble(double d) { + if (internal::Double(d).IsNanOrInf()) { + if (!(writeFlags & kWriteNanAndInfFlag)) + return false; + if (internal::Double(d).IsNan()) { + PutReserve(*os_, 3); + PutUnsafe(*os_, 'N'); PutUnsafe(*os_, 'a'); PutUnsafe(*os_, 'N'); + return true; + } + if (internal::Double(d).Sign()) { + PutReserve(*os_, 9); + PutUnsafe(*os_, '-'); + } + else + PutReserve(*os_, 8); + PutUnsafe(*os_, 'I'); PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'f'); + PutUnsafe(*os_, 'i'); PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'i'); PutUnsafe(*os_, 't'); PutUnsafe(*os_, 'y'); + return true; + } + + char buffer[25]; + char* end = internal::dtoa(d, buffer, maxDecimalPlaces_); + PutReserve(*os_, static_cast(end - buffer)); + for (char* p = buffer; p != end; ++p) + PutUnsafe(*os_, static_cast(*p)); + return true; + } + + bool WriteString(const Ch* str, SizeType length) { + static const typename TargetEncoding::Ch hexDigits[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; + static const char escape[256] = { +#define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + //0 1 2 3 4 5 6 7 8 9 A B C D E F + 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'b', 't', 'n', 'u', 'f', 'r', 'u', 'u', // 00 + 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', // 10 + 0, 0, '"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 20 + Z16, Z16, // 30~4F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'\\', 0, 0, 0, // 50 + Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16 // 60~FF +#undef Z16 + }; + + if (TargetEncoding::supportUnicode) + PutReserve(*os_, 2 + length * 6); // "\uxxxx..." + else + PutReserve(*os_, 2 + length * 12); // "\uxxxx\uyyyy..." + + PutUnsafe(*os_, '\"'); + GenericStringStream is(str); + while (ScanWriteUnescapedString(is, length)) { + const Ch c = is.Peek(); + if (!TargetEncoding::supportUnicode && static_cast(c) >= 0x80) { + // Unicode escaping + unsigned codepoint; + if (RAPIDJSON_UNLIKELY(!SourceEncoding::Decode(is, &codepoint))) + return false; + PutUnsafe(*os_, '\\'); + PutUnsafe(*os_, 'u'); + if (codepoint <= 0xD7FF || (codepoint >= 0xE000 && codepoint <= 0xFFFF)) { + PutUnsafe(*os_, hexDigits[(codepoint >> 12) & 15]); + PutUnsafe(*os_, hexDigits[(codepoint >> 8) & 15]); + PutUnsafe(*os_, hexDigits[(codepoint >> 4) & 15]); + PutUnsafe(*os_, hexDigits[(codepoint ) & 15]); + } + else { + RAPIDJSON_ASSERT(codepoint >= 0x010000 && codepoint <= 0x10FFFF); + // Surrogate pair + unsigned s = codepoint - 0x010000; + unsigned lead = (s >> 10) + 0xD800; + unsigned trail = (s & 0x3FF) + 0xDC00; + PutUnsafe(*os_, hexDigits[(lead >> 12) & 15]); + PutUnsafe(*os_, hexDigits[(lead >> 8) & 15]); + PutUnsafe(*os_, hexDigits[(lead >> 4) & 15]); + PutUnsafe(*os_, hexDigits[(lead ) & 15]); + PutUnsafe(*os_, '\\'); + PutUnsafe(*os_, 'u'); + PutUnsafe(*os_, hexDigits[(trail >> 12) & 15]); + PutUnsafe(*os_, hexDigits[(trail >> 8) & 15]); + PutUnsafe(*os_, hexDigits[(trail >> 4) & 15]); + PutUnsafe(*os_, hexDigits[(trail ) & 15]); + } + } + else if ((sizeof(Ch) == 1 || static_cast(c) < 256) && RAPIDJSON_UNLIKELY(escape[static_cast(c)])) { + is.Take(); + PutUnsafe(*os_, '\\'); + PutUnsafe(*os_, static_cast(escape[static_cast(c)])); + if (escape[static_cast(c)] == 'u') { + PutUnsafe(*os_, '0'); + PutUnsafe(*os_, '0'); + PutUnsafe(*os_, hexDigits[static_cast(c) >> 4]); + PutUnsafe(*os_, hexDigits[static_cast(c) & 0xF]); + } + } + else if (RAPIDJSON_UNLIKELY(!(writeFlags & kWriteValidateEncodingFlag ? + Transcoder::Validate(is, *os_) : + Transcoder::TranscodeUnsafe(is, *os_)))) + return false; + } + PutUnsafe(*os_, '\"'); + return true; + } + + bool ScanWriteUnescapedString(GenericStringStream& is, size_t length) { + return RAPIDJSON_LIKELY(is.Tell() < length); + } + + bool WriteStartObject() { os_->Put('{'); return true; } + bool WriteEndObject() { os_->Put('}'); return true; } + bool WriteStartArray() { os_->Put('['); return true; } + bool WriteEndArray() { os_->Put(']'); return true; } + + bool WriteRawValue(const Ch* json, size_t length) { + PutReserve(*os_, length); + for (size_t i = 0; i < length; i++) { + RAPIDJSON_ASSERT(json[i] != '\0'); + PutUnsafe(*os_, json[i]); + } + return true; + } + + void Prefix(Type type) { + (void)type; + if (RAPIDJSON_LIKELY(level_stack_.GetSize() != 0)) { // this value is not at root + Level* level = level_stack_.template Top(); + if (level->valueCount > 0) { + if (level->inArray) + os_->Put(','); // add comma if it is not the first element in array + else // in object + os_->Put((level->valueCount % 2 == 0) ? ',' : ':'); + } + if (!level->inArray && level->valueCount % 2 == 0) + RAPIDJSON_ASSERT(type == kStringType); // if it's in object, then even number should be a name + level->valueCount++; + } + else { + RAPIDJSON_ASSERT(!hasRoot_); // Should only has one and only one root. + hasRoot_ = true; + } + } + + // Flush the value if it is the top level one. + bool EndValue(bool ret) { + if (RAPIDJSON_UNLIKELY(level_stack_.Empty())) // end of json text + os_->Flush(); + return ret; + } + + OutputStream* os_; + internal::Stack level_stack_; + int maxDecimalPlaces_; + bool hasRoot_; + +private: + // Prohibit copy constructor & assignment operator. + Writer(const Writer&); + Writer& operator=(const Writer&); +}; + +// Full specialization for StringStream to prevent memory copying + +template<> +inline bool Writer::WriteInt(int i) { + char *buffer = os_->Push(11); + const char* end = internal::i32toa(i, buffer); + os_->Pop(static_cast(11 - (end - buffer))); + return true; +} + +template<> +inline bool Writer::WriteUint(unsigned u) { + char *buffer = os_->Push(10); + const char* end = internal::u32toa(u, buffer); + os_->Pop(static_cast(10 - (end - buffer))); + return true; +} + +template<> +inline bool Writer::WriteInt64(int64_t i64) { + char *buffer = os_->Push(21); + const char* end = internal::i64toa(i64, buffer); + os_->Pop(static_cast(21 - (end - buffer))); + return true; +} + +template<> +inline bool Writer::WriteUint64(uint64_t u) { + char *buffer = os_->Push(20); + const char* end = internal::u64toa(u, buffer); + os_->Pop(static_cast(20 - (end - buffer))); + return true; +} + +template<> +inline bool Writer::WriteDouble(double d) { + if (internal::Double(d).IsNanOrInf()) { + // Note: This code path can only be reached if (RAPIDJSON_WRITE_DEFAULT_FLAGS & kWriteNanAndInfFlag). + if (!(kWriteDefaultFlags & kWriteNanAndInfFlag)) + return false; + if (internal::Double(d).IsNan()) { + PutReserve(*os_, 3); + PutUnsafe(*os_, 'N'); PutUnsafe(*os_, 'a'); PutUnsafe(*os_, 'N'); + return true; + } + if (internal::Double(d).Sign()) { + PutReserve(*os_, 9); + PutUnsafe(*os_, '-'); + } + else + PutReserve(*os_, 8); + PutUnsafe(*os_, 'I'); PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'f'); + PutUnsafe(*os_, 'i'); PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'i'); PutUnsafe(*os_, 't'); PutUnsafe(*os_, 'y'); + return true; + } + + char *buffer = os_->Push(25); + char* end = internal::dtoa(d, buffer, maxDecimalPlaces_); + os_->Pop(static_cast(25 - (end - buffer))); + return true; +} + +#if defined(RAPIDJSON_SSE2) || defined(RAPIDJSON_SSE42) +template<> +inline bool Writer::ScanWriteUnescapedString(StringStream& is, size_t length) { + if (length < 16) + return RAPIDJSON_LIKELY(is.Tell() < length); + + if (!RAPIDJSON_LIKELY(is.Tell() < length)) + return false; + + const char* p = is.src_; + const char* end = is.head_ + length; + const char* nextAligned = reinterpret_cast((reinterpret_cast(p) + 15) & static_cast(~15)); + const char* endAligned = reinterpret_cast(reinterpret_cast(end) & static_cast(~15)); + if (nextAligned > end) + return true; + + while (p != nextAligned) + if (*p < 0x20 || *p == '\"' || *p == '\\') { + is.src_ = p; + return RAPIDJSON_LIKELY(is.Tell() < length); + } + else + os_->PutUnsafe(*p++); + + // The rest of string using SIMD + static const char dquote[16] = { '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"' }; + static const char bslash[16] = { '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\' }; + static const char space[16] = { 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19 }; + const __m128i dq = _mm_loadu_si128(reinterpret_cast(&dquote[0])); + const __m128i bs = _mm_loadu_si128(reinterpret_cast(&bslash[0])); + const __m128i sp = _mm_loadu_si128(reinterpret_cast(&space[0])); + + for (; p != endAligned; p += 16) { + const __m128i s = _mm_load_si128(reinterpret_cast(p)); + const __m128i t1 = _mm_cmpeq_epi8(s, dq); + const __m128i t2 = _mm_cmpeq_epi8(s, bs); + const __m128i t3 = _mm_cmpeq_epi8(_mm_max_epu8(s, sp), sp); // s < 0x20 <=> max(s, 0x19) == 0x19 + const __m128i x = _mm_or_si128(_mm_or_si128(t1, t2), t3); + unsigned short r = static_cast(_mm_movemask_epi8(x)); + if (RAPIDJSON_UNLIKELY(r != 0)) { // some of characters is escaped + SizeType len; +#ifdef _MSC_VER // Find the index of first escaped + unsigned long offset; + _BitScanForward(&offset, r); + len = offset; +#else + len = static_cast(__builtin_ffs(r) - 1); +#endif + char* q = reinterpret_cast(os_->PushUnsafe(len)); + for (size_t i = 0; i < len; i++) + q[i] = p[i]; + + p += len; + break; + } + _mm_storeu_si128(reinterpret_cast<__m128i *>(os_->PushUnsafe(16)), s); + } + + is.src_ = p; + return RAPIDJSON_LIKELY(is.Tell() < length); +} +#endif // defined(RAPIDJSON_SSE2) || defined(RAPIDJSON_SSE42) + +RAPIDJSON_NAMESPACE_END + +#ifdef _MSC_VER +RAPIDJSON_DIAG_POP +#endif + +#ifdef __clang__ +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_RAPIDJSON_H_ From 6a244c10573ed47ca66a0d21d5ddf736352ee045 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Mon, 19 Sep 2016 12:34:38 +0200 Subject: [PATCH 249/474] bug fixed, rapidjson parse error --- .../src/UDPStandardImplementation.cpp | 95 ++++++++++--------- 1 file changed, 52 insertions(+), 43 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index b3b81318d..0158d2107 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1053,6 +1053,7 @@ void UDPStandardImplementation::stopReceiver(){ } //semaphore destroy + cout<<"gonna destroy writerguisemphore"< currentfnum){ ostringstream header; - header << "{\"htype\":[\"chunk-1.0\"], " - << "\"type\":" << "\"" << type << "\", " - << "\"shape\":" << shape - << "}"; - //send header - zmq_send(zmqsocket, header.str().c_str(), header.str().length(), ZMQ_SNDMORE); - sleep(1); - //send data + header << "{\"htype\":[\"chunk-1.0\"], " + << "\"type\":" << "\"" << type << "\", " + << "\"shape\":" << shape + << "}"; + //cout< Date: Mon, 19 Sep 2016 17:21:28 +0200 Subject: [PATCH 250/474] only missing data left to be handled in zmqthread in receiver --- .../include/UDPStandardImplementation.h | 3 +- .../src/UDPStandardImplementation.cpp | 122 +++++++++--------- 2 files changed, 61 insertions(+), 64 deletions(-) diff --git a/slsReceiverSoftware/include/UDPStandardImplementation.h b/slsReceiverSoftware/include/UDPStandardImplementation.h index 18f9e546f..14e0f638f 100644 --- a/slsReceiverSoftware/include/UDPStandardImplementation.h +++ b/slsReceiverSoftware/include/UDPStandardImplementation.h @@ -515,9 +515,10 @@ private: * @param wbuffer writer buffer * @param framenumber reference to the frame number * @param packetnumber reference to the packet number + * @param subframenumber reference to the subframe number * @return OK or FAIL */ - int getFrameandPacketNumber(int ithread, char* wbuffer, uint64_t &framenumber, uint32_t &packetnumber); + int getFrameandPacketNumber(int ithread, char* wbuffer, uint64_t &framenumber, uint32_t &packetnumber, uint32_t &subframenumber); /** * Find offset upto this frame number and write it to file diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 0158d2107..68f850c53 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -568,23 +568,18 @@ uint32_t UDPStandardImplementation::setDataStreamEnable(const uint32_t enable){ FILE_LOG(logDEBUG) << __AT__ << " called"; - cout<<"************datasend:"<0) && (getFrameandPacketNumber(ithread, latestData[ithread]+offset, fnum, pnum)==FAIL)){ + while((size>0) && (getFrameandPacketNumber(ithread, latestData[ithread]+offset, fnum, pnum,snum)==FAIL)){ offset+= onePacketSize; } @@ -1780,24 +1774,23 @@ void UDPStandardImplementation::startDataCallback(){ //new frame if(currentfnum==-1){ currentfnum = fnum; + //update frame details + frameIndex = fnum; + acquisitionIndex = fnum - startAcquisitionIndex; + if(dynamicRange == 32) subframeIndex = snum; } //last packet if(pnum == packetsPerFrame){ memcpy(buffer+((pnum-1)*oneDataSize), latestData[ithread]+offset+8,oneDataSize); offset+= onePacketSize; - ostringstream header; - header << "{\"htype\":[\"chunk-1.0\"], " - << "\"type\":" << "\"" << type << "\", " - << "\"shape\":" << shape - << "}"; - //cout< currentfnum){ - ostringstream header; - header << "{\"htype\":[\"chunk-1.0\"], " - << "\"type\":" << "\"" << type << "\", " - << "\"shape\":" << shape - << "}"; - //cout<push(wbuffer)); @@ -2660,8 +2647,9 @@ void UDPStandardImplementation::writeFileWithoutCompression(int ithread, char* w //get start frame (required to create new file at the right juncture) uint64_t startframe =-1; uint32_t pnum; + uint32_t snum; //if(ithread) cout<<"getting start frame number"<push(wbuffer)); return; @@ -2719,7 +2707,8 @@ void UDPStandardImplementation::writeFileWithoutCompression(int ithread, char* w //get last frame number uint64_t finalLastFrameNumberToSave = 0; uint32_t pnum; - if(getFrameandPacketNumber(ithread, wbuffer + HEADER_SIZE_NUM_TOT_PACKETS + ((numpackets - 1) * onePacketSize), finalLastFrameNumberToSave,pnum) == FAIL){ + uint32_t snum; + if(getFrameandPacketNumber(ithread, wbuffer + HEADER_SIZE_NUM_TOT_PACKETS + ((numpackets - 1) * onePacketSize), finalLastFrameNumberToSave,pnum,snum) == FAIL){ //error in frame number sent by fpga while(!fifoFree[ithread]->push(wbuffer)); return; @@ -2809,9 +2798,8 @@ void UDPStandardImplementation::copyFrameToGui(int ithread, char* buffer, uint32 cprintf(GREEN,"Writing_Thread: CopyingFrame: Going to copy data\n"); #endif //ensure previous frame was processed - if(!ithread) cout<<"*** waiting for writerguisemiphore (copyfrmae)"<push(wbuffer)); return; @@ -2978,11 +2967,15 @@ void UDPStandardImplementation::handleDataCompression(int ithread, char* wbuffer -int UDPStandardImplementation::getFrameandPacketNumber(int ithread, char* wbuffer, uint64_t &framenumber, uint32_t &packetnumber){ +int UDPStandardImplementation::getFrameandPacketNumber(int ithread, char* wbuffer, uint64_t &framenumber, uint32_t &packetnumber,uint32_t &subframenumber){ FILE_LOG(logDEBUG) << __AT__ << " called"; eiger_packet_footer_t* footer=0; + eiger_packet_header_t* e_header=0; jfrau_packet_header_t* header=0; + framenumber = 0; + packetnumber = 0; + subframenumber = 0; switch(myDetectorType){ @@ -2996,12 +2989,15 @@ int UDPStandardImplementation::getFrameandPacketNumber(int ithread, char* wbuffe return FAIL; } packetnumber = (*( (uint16_t*) footer->packetNumber)); + e_header = (eiger_packet_header_t*) (wbuffer); + subframenumber = *( (uint32_t*) e_header->subFrameNumber); #ifdef DEBUG4 - if(!ithread) cprintf(GREEN,"Writing_Thread %d: fnum:%lld pnum:%d FPGA_fnum:%d footeroffset:%d\n", + if(!ithread) cprintf(GREEN,"Writing_Thread %d: fnum:%lld pnum:%d FPGA_fnum:%d subfnum:%d footeroffset:%d\n", ithread, (long long int)framenumber, packetnumber, framenumber, + subframenumber, footerOffset); #endif framenumber += (startFrameIndex - 1); @@ -3051,9 +3047,9 @@ int UDPStandardImplementation::writeUptoFrameNumber(int ithread, char* wbuffer, uint64_t tempframenumber=-1; offset = endoffset; uint32_t pnum; - + uint32_t snum; //get last frame number - if(getFrameandPacketNumber(ithread, wbuffer + (endoffset-onePacketSize), tempframenumber,pnum) == FAIL){ + if(getFrameandPacketNumber(ithread, wbuffer + (endoffset-onePacketSize), tempframenumber,pnum,snum) == FAIL){ //error in frame number sent by fpga while(!fifoFree[ithread]->push(wbuffer)); return FAIL; @@ -3079,7 +3075,7 @@ int UDPStandardImplementation::writeUptoFrameNumber(int ithread, char* wbuffer, offset -= bigIncrements; if(offsetpush(wbuffer)); return FAIL; @@ -3087,7 +3083,7 @@ int UDPStandardImplementation::writeUptoFrameNumber(int ithread, char* wbuffer, } if(offsetpush(wbuffer)); return FAIL; @@ -3095,7 +3091,7 @@ int UDPStandardImplementation::writeUptoFrameNumber(int ithread, char* wbuffer, } while(tempframenumberpush(wbuffer)); return FAIL; From bdcbdba2ab9307c89c20ec99b16d4dbb27c3e5b0 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 20 Sep 2016 10:42:49 +0200 Subject: [PATCH 251/474] done with eiger --- .../src/UDPStandardImplementation.cpp | 67 ++++++++++++------- 1 file changed, 44 insertions(+), 23 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 68f850c53..985cff7c3 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1684,7 +1684,7 @@ void UDPStandardImplementation::startDataCallback(){ int bufferoffset = 0; int size = 0; int offset = 0; - int currentfnum = -1; + int currentfnum = 0; uint64_t fnum = 0; uint32_t pnum = 0; uint32_t snum = 0; @@ -1695,7 +1695,7 @@ void UDPStandardImplementation::startDataCallback(){ void *context = zmq_ctx_new(); void *zmqsocket = zmq_socket(context, ZMQ_PUSH); // create a publisher int val = -1; - //zmq_setsockopt(zmq_socket, ZMQ_LINGER, &val,sizeof(val)); // wait for the unsent packets before closing socket + zmq_setsockopt(zmqsocket, ZMQ_LINGER, &val,sizeof(val)); // wait for the unsent packets before closing socket zmq_bind(zmqsocket,hostName); // bind //let calling function know thread started and obtained current (after sockets created) if(!zmqThreadStarted) @@ -1708,6 +1708,7 @@ void UDPStandardImplementation::startDataCallback(){ int acquisitionIndex = -1; int frameIndex = -1; int subframeIndex = -1; + bool newFrame = false; /* inner loop - loop for each buffer */ //until mask reset (dummy pcaket got by writer) @@ -1721,17 +1722,33 @@ void UDPStandardImplementation::startDataCallback(){ //everything is done if(guiNumPackets[ithread] == dummyPacketValue){ - /**suing this in clientzmq_msg_more, - * in serve use zmq_msg_send (&message, sender, ZMQ_SNDMORE); and 0 for last packet, but better to check lengt*/ - /*if (checkJoinThread()){for different scans - break; - }*/ - /*send half frames from before if any */ - //send header + //sending previous half frames if any + if(newFrame){cout<<"dummy but something remaining"<= size) break; - //new frame - if(currentfnum==-1){ - currentfnum = fnum; + + //last packet of same frame + if(fnum == currentfnum && pnum == packetsPerFrame){ + memcpy(buffer+((pnum-1)*oneDataSize), latestData[ithread]+offset+8,oneDataSize); + offset+= onePacketSize; + //send header //update frame details frameIndex = fnum; acquisitionIndex = fnum - startAcquisitionIndex; if(dynamicRange == 32) subframeIndex = snum; - } - - //last packet - if(pnum == packetsPerFrame){ - memcpy(buffer+((pnum-1)*oneDataSize), latestData[ithread]+offset+8,oneDataSize); - offset+= onePacketSize; - //send header int len = sprintf(buf,jsonFmt,type,shape, acquisitionIndex, frameIndex, subframeIndex,completeFileName[ithread]); zmq_send(zmqsocket, buf,len, ZMQ_SNDMORE); //send data zmq_send(zmqsocket, buffer, oneframesize, 0); + newFrame = false; #ifdef DEBUG if(!ithread)cprintf(BLUE,"%d sent (last packet)\n",ithread); #endif + currentfnum++; //start clock after sending if(!frameToGuiFrequency){ randomSendNow = false; clock_gettime(CLOCK_REALTIME, &begin); } memset(buffer,0xFF,oneframesize); - currentfnum = -1; + } //same frame (not last) or next frame else { //next frame - if(fnum > currentfnum){ + while(fnum > currentfnum){ //send header + //update frame details + frameIndex = fnum; + acquisitionIndex = fnum - startAcquisitionIndex; + if(dynamicRange == 32) subframeIndex = snum; int len = sprintf(buf,jsonFmt,type,shape, acquisitionIndex, frameIndex, subframeIndex,completeFileName[ithread]); zmq_send(zmqsocket, buf,len, ZMQ_SNDMORE); //send data zmq_send(zmqsocket, buffer, oneframesize, 0); + newFrame = false; #ifdef DEBUG cprintf(BLUE,"%d sent (last packet of previous frame)\n",ithread); #endif + currentfnum++; //start clock after sending if(!frameToGuiFrequency){ randomSendNow = false; clock_gettime(CLOCK_REALTIME, &begin); } memset(buffer,0xFF,oneframesize); - currentfnum = fnum; } memcpy(buffer+((pnum-1)*oneDataSize), latestData[ithread]+offset+8,oneDataSize); offset+= onePacketSize; + newFrame = true; } } From d6ca7ecbc4ba5c15d87b881102f6b5fe4f059227 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 20 Sep 2016 15:12:26 +0200 Subject: [PATCH 252/474] done for eiger, some checks for frameindex=-1,socket closing earlier than last socket etc --- slsReceiverSoftware/include/genericSocket.h | 2 +- .../src/UDPStandardImplementation.cpp | 95 +++++++++++-------- .../src/slsReceiverTCPIPInterface.cpp | 2 +- 3 files changed, 60 insertions(+), 39 deletions(-) diff --git a/slsReceiverSoftware/include/genericSocket.h b/slsReceiverSoftware/include/genericSocket.h index 11828c8a7..91debdec1 100644 --- a/slsReceiverSoftware/include/genericSocket.h +++ b/slsReceiverSoftware/include/genericSocket.h @@ -619,7 +619,7 @@ enum communicationProtocol{ nsent = recvfrom(socketDescriptor,(char*)buf+total_sent,nsending, 0, (struct sockaddr *) &clientAddress, &clientAddress_length); if(nsent < packet_size) { if(nsent){ - if(nsent != header_packet_size) + if((nsent != header_packet_size) && (nsent != -1)) cprintf(RED,"Incomplete Packet size %d\n",nsent); } break; diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 985cff7c3..e51d65def 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -164,7 +164,7 @@ void UDPStandardImplementation::initializeMembers(){ for(int i=0; i0) && (getFrameandPacketNumber(ithread, latestData[ithread]+offset, fnum, pnum,snum)==FAIL)){ offset+= onePacketSize; } + //if(!ithread) cout<< ithread <<" fnum:"<< fnum<<" pnum:"<= size) break; @@ -1791,11 +1798,14 @@ void UDPStandardImplementation::startDataCallback(){ //last packet of same frame if(fnum == currentfnum && pnum == packetsPerFrame){ +#ifdef DEBUG + oldpnum=0; +#endif memcpy(buffer+((pnum-1)*oneDataSize), latestData[ithread]+offset+8,oneDataSize); offset+= onePacketSize; //send header //update frame details - frameIndex = fnum; + frameIndex = fnum;if(frameIndex==-1) cprintf(RED,"frameindex = -1, 222\n"); acquisitionIndex = fnum - startAcquisitionIndex; if(dynamicRange == 32) subframeIndex = snum; int len = sprintf(buf,jsonFmt,type,shape, acquisitionIndex, frameIndex, subframeIndex,completeFileName[ithread]); @@ -1818,10 +1828,20 @@ void UDPStandardImplementation::startDataCallback(){ //same frame (not last) or next frame else { //next frame +#ifdef DEBUG + int once = true; +#endif while(fnum > currentfnum){ +#ifdef DEBUG + if(once){ + if((fnum-currentfnum-1)>1) cprintf(RED,"%d Complete sub image missing:%d (cfnum:%d nfnum:%d)\n", + ithread,fnum-currentfnum-1,currentfnum,fnum); + once = false; + } +#endif //send header //update frame details - frameIndex = fnum; + frameIndex = fnum;if(frameIndex==-1) cprintf(RED,"frameindex = -1, 333\n"); acquisitionIndex = fnum - startAcquisitionIndex; if(dynamicRange == 32) subframeIndex = snum; int len = sprintf(buf,jsonFmt,type,shape, acquisitionIndex, frameIndex, subframeIndex,completeFileName[ithread]); @@ -2160,10 +2180,11 @@ void UDPStandardImplementation::stopListening(int ithread, int numbytes){ //reset mask and exit loop pthread_mutex_lock(&statusMutex); listeningThreadsMask^=(1<= (packetsPerFrame/numberofListeningThreads)) - if(dataStreamEnable && npackets) + if(dataStreamEnable && npackets > 0) copyFrameToGui(ithread, wbuffer,npackets); #ifdef DEBUG4 cprintf(GREEN,"Writing_Thread: Copied frame\n"); diff --git a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp index ff39c681b..822eb7fa6 100644 --- a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp +++ b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp @@ -2163,7 +2163,7 @@ int slsReceiverTCPIPInterface::set_data_stream_enable(){ strcpy(mess,SET_RECEIVER_ERR_MESSAGE); ret=FAIL; } - else if(receiverBase->getStatus()==RUNNING || receiverBase->getStatus()==TRANSMITTING){ + else if((index >= 0) && (receiverBase->getStatus()==RUNNING || receiverBase->getStatus()==TRANSMITTING)){ strcpy(mess,"Can not set data stream enable while receiver not idle\n"); cprintf(RED,"%s\n",mess); ret = FAIL; From 1aff36efb8d18ee155583e6ffdbad2c716db5da5 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Wed, 21 Sep 2016 16:37:52 +0200 Subject: [PATCH 253/474] small print out change --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index e51d65def..d46ca831f 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1254,7 +1254,7 @@ int UDPStandardImplementation::createDataCallbackThreads(bool destroy){ zmqThreadStarted = false; currentThreadIndex = i; if(pthread_create(&dataCallbackThreads[i], NULL,startDataCallbackThread, (void*) this)){ - FILE_LOG(logERROR) << "Could not create listening thread with index " << i; + FILE_LOG(logERROR) << "Could not create data call back thread with index " << i; return FAIL; } while(!zmqThreadStarted); From 44870480be2f33be577e623fc64fd499238bb539 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Thu, 22 Sep 2016 13:17:17 +0200 Subject: [PATCH 254/474] merging for gotthard, not done --- slsReceiverSoftware/include/receiver_defs.h | 4 ++- .../src/UDPStandardImplementation.cpp | 27 ++++++++++++------- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/slsReceiverSoftware/include/receiver_defs.h b/slsReceiverSoftware/include/receiver_defs.h index 0c60b892c..d0cd07320 100755 --- a/slsReceiverSoftware/include/receiver_defs.h +++ b/slsReceiverSoftware/include/receiver_defs.h @@ -169,7 +169,9 @@ typedef struct { #define EIGER_MAX_PORTS 2 -#define EIGER_HEADER_LENGTH 48 +#define EIGER_HEADER_PACKET_LENGTH 48 + +#define EIGER_HEADER_SIZE 8 #define EIGER_FIFO_SIZE 100 /*#define EIGER_ALIGNED_FRAME_SIZE 65536*/ diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index d46ca831f..01bf81401 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1219,7 +1219,7 @@ void UDPStandardImplementation::closeFile(int ithread){ int UDPStandardImplementation::createDataCallbackThreads(bool destroy){ FILE_LOG(logDEBUG) << __AT__ << " starting"; - + if(!destroy) cprintf(MAGENTA,"Data Callback thread created\n"); else cprintf(MAGENTA,"Data Callback thread destroyed\n"); //reset masks killAllDataCallbackThreads = false; pthread_mutex_lock(&statusMutex); @@ -1270,7 +1270,7 @@ int UDPStandardImplementation::createDataCallbackThreads(bool destroy){ int UDPStandardImplementation::createListeningThreads(bool destroy){ FILE_LOG(logDEBUG) << __AT__ << " starting"; - + if(!destroy) cprintf(BLUE,"Listening thread created\n"); else cprintf(BLUE,"Listening thread destroyed\n"); //reset masks killAllListeningThreads = false; pthread_mutex_lock(&statusMutex); @@ -1321,7 +1321,7 @@ int UDPStandardImplementation::createListeningThreads(bool destroy){ int UDPStandardImplementation::createWriterThreads(bool destroy){ FILE_LOG(logDEBUG) << __AT__ << " starting"; - + if(!destroy) cprintf(GREEN,"Writer thread created\n"); else cprintf(GREEN,"Writer thread destroyed\n"); //reset masks killAllWritingThreads = false; pthread_mutex_lock(&statusMutex); @@ -1439,7 +1439,7 @@ int UDPStandardImplementation::createUDPSockets(){ shutDownUDPSockets(); int headerpacketsize = 0; if(myDetectorType == EIGER) - headerpacketsize = EIGER_HEADER_LENGTH; + headerpacketsize = EIGER_HEADER_PACKET_LENGTH; //if no eth, listen to all if(!strlen(eth)){ @@ -1668,6 +1668,15 @@ void UDPStandardImplementation::startDataCallback(){ sprintf(hostName,"%s%d",hostName,portno); FILE_LOG(logINFO) << "Thread" << ithread << ": ZMQ Server at " << hostName; + + int headersize=0; + switch(myDetectorType){ + case EIGER: + headersize = EIGER_HEADER_SIZE; break; + + } + + /* outer loop - loops once for each acquisition */ //infinite loop, exited only to change dynamic range, 10G parameters etc (then recreated again) while(true){ @@ -1705,7 +1714,7 @@ void UDPStandardImplementation::startDataCallback(){ int frameIndex = -1; int subframeIndex = -1; #ifdef DEBUG - int oldpnum = 0; + int oldpnum = -1; #endif int datapacketscaught = 0; @@ -1797,11 +1806,11 @@ void UDPStandardImplementation::startDataCallback(){ //last packet of same frame - if(fnum == currentfnum && pnum == packetsPerFrame){ + if(fnum == currentfnum && pnum == (packetsPerFrame-1)){ #ifdef DEBUG oldpnum=0; #endif - memcpy(buffer+((pnum-1)*oneDataSize), latestData[ithread]+offset+8,oneDataSize); + memcpy(buffer+(pnum*oneDataSize), latestData[ithread]+offset+headersize,oneDataSize); offset+= onePacketSize; //send header //update frame details @@ -1861,7 +1870,7 @@ void UDPStandardImplementation::startDataCallback(){ memset(buffer,0xFF,oneframesize); } - memcpy(buffer+((pnum-1)*oneDataSize), latestData[ithread]+offset+8,oneDataSize); + memcpy(buffer+(pnum*oneDataSize), latestData[ithread]+offset+headersize,oneDataSize); offset+= onePacketSize; newFrame = true; } @@ -3030,7 +3039,7 @@ int UDPStandardImplementation::getFrameandPacketNumber(int ithread, char* wbuffe FILE_LOG(logERROR) << "Fifo "<< ithread << ": Frame Number is zero from firmware."; return FAIL; } - packetnumber = (*( (uint16_t*) footer->packetNumber)); + packetnumber = (*( (uint16_t*) footer->packetNumber))-1; e_header = (eiger_packet_header_t*) (wbuffer); subframenumber = *( (uint32_t*) e_header->subFrameNumber); #ifdef DEBUG4 From 01ed24263f228a62680a238c7fdcc5970a38656a Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Thu, 29 Sep 2016 10:29:24 +0200 Subject: [PATCH 255/474] updaterev --- slsReceiverSoftware/gitInfo.txt | 10 +++++----- slsReceiverSoftware/include/gitInfoReceiver.h | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/slsReceiverSoftware/gitInfo.txt b/slsReceiverSoftware/gitInfo.txt index 82c68fc0a..6e3160308 100644 --- a/slsReceiverSoftware/gitInfo.txt +++ b/slsReceiverSoftware/gitInfo.txt @@ -1,9 +1,9 @@ Path: slsDetectorsPackage/slsReceiverSoftware URL: origin git@git.psi.ch:sls_detectors_software/sls_receiver_software.git Repository Root: origin git@git.psi.ch:sls_detectors_software/sls_receiver_software.git -Repsitory UUID: 10000196185a0991cd13457cd69966d79f860134 -Revision: 251 +Repsitory UUID: 1c7a5892a984a6954b8f65e052e803a908153e9f +Revision: 254 Branch: developer -Last Changed Author: Dhanya_Maliakal -Last Changed Rev: 251 -Last Changed Date: 2016-08-12 13:48:30 +0200 +Last Changed Author: wang_x1_ +Last Changed Rev: 254 +Last Changed Date: 2016-09-14 11:58:39 +0200 diff --git a/slsReceiverSoftware/include/gitInfoReceiver.h b/slsReceiverSoftware/include/gitInfoReceiver.h index 10c4e9caa..168f020ed 100644 --- a/slsReceiverSoftware/include/gitInfoReceiver.h +++ b/slsReceiverSoftware/include/gitInfoReceiver.h @@ -1,11 +1,11 @@ //#define SVNPATH "" #define SVNURL "git@git.psi.ch:sls_detectors_software/sls_receiver_software.git" //#define SVNREPPATH "" -#define SVNREPUUID "10000196185a0991cd13457cd69966d79f860134" -//#define SVNREV 0x251 +#define SVNREPUUID "1c7a5892a984a6954b8f65e052e803a908153e9f" +//#define SVNREV 0x254 //#define SVNKIND "" //#define SVNSCHED "" -#define SVNAUTH "Dhanya_Maliakal" -#define SVNREV 0x251 -#define SVNDATE 0x20160812 +#define SVNAUTH "wang_x1_" +#define SVNREV 0x254 +#define SVNDATE 0x20160914 // From 572047b72dec3bcd847b1fc0a3af98f60ba17ac5 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Fri, 30 Sep 2016 15:13:12 +0200 Subject: [PATCH 256/474] was making 3 threads for each set detector type command, because it created standard receiver object each time --- .../src/slsReceiverTCPIPInterface.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp index 1e2b5c49e..c1017a4a7 100644 --- a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp +++ b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp @@ -370,13 +370,15 @@ int slsReceiverTCPIPInterface::set_detector_type(){ } if(ret != FAIL){ #ifndef REST - receiverBase = UDPInterface::create("standard"); - if(startAcquisitionCallBack) - receiverBase->registerCallBackStartAcquisition(startAcquisitionCallBack,pStartAcquisition); - if(acquisitionFinishedCallBack) - receiverBase->registerCallBackAcquisitionFinished(acquisitionFinishedCallBack,pAcquisitionFinished); - if(rawDataReadyCallBack) - receiverBase->registerCallBackRawDataReady(rawDataReadyCallBack,pRawDataReady); + if(receiverBase == NULL){ + receiverBase = UDPInterface::create("standard"); + if(startAcquisitionCallBack) + receiverBase->registerCallBackStartAcquisition(startAcquisitionCallBack,pStartAcquisition); + if(acquisitionFinishedCallBack) + receiverBase->registerCallBackAcquisitionFinished(acquisitionFinishedCallBack,pAcquisitionFinished); + if(rawDataReadyCallBack) + receiverBase->registerCallBackRawDataReady(rawDataReadyCallBack,pRawDataReady); + } #endif myDetectorType = dr; ret=receiverBase->setDetectorType(myDetectorType); From 2a4bd8022ec88827c0f128bc6600bb9aef6281e0 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 4 Oct 2016 07:36:00 +0200 Subject: [PATCH 257/474] works for deactivated server and receiver --- .../include/UDPBaseImplementation.h | 18 ++++ slsReceiverSoftware/include/UDPInterface.h | 15 ++++ .../include/UDPStandardImplementation.h | 4 + .../include/slsReceiverTCPIPInterface.h | 4 + .../include/sls_receiver_funcs.h | 4 +- .../src/UDPBaseImplementation.cpp | 14 ++- .../src/UDPStandardImplementation.cpp | 88 +++++++++++++++---- .../src/slsReceiverTCPIPInterface.cpp | 68 ++++++++++++++ 8 files changed, 195 insertions(+), 20 deletions(-) diff --git a/slsReceiverSoftware/include/UDPBaseImplementation.h b/slsReceiverSoftware/include/UDPBaseImplementation.h index 568183e42..101816cbe 100644 --- a/slsReceiverSoftware/include/UDPBaseImplementation.h +++ b/slsReceiverSoftware/include/UDPBaseImplementation.h @@ -193,6 +193,14 @@ class UDPBaseImplementation : protected virtual slsReceiverDefs, public UDPInter */ runStatus getStatus() const; + /** + * Get activate + * If deactivated, receiver will write dummy packets 0xFF + * (as it will receive nothing from detector) + * @return 0 for deactivated, 1 for activated + */ + int getActivate() const; + @@ -417,6 +425,13 @@ class UDPBaseImplementation : protected virtual slsReceiverDefs, public UDPInter */ void closeFile(int i = -1); + /** + * Activate / Deactivate Receiver + * If deactivated, receiver will write dummy packets 0xFF + * (as it will receive nothing from detector) + */ + int setActivate(int enable = -1); + //***callback functions*** /** @@ -485,6 +500,8 @@ class UDPBaseImplementation : protected virtual slsReceiverDefs, public UDPInter const static int MAX_NUMBER_OF_LISTENING_THREADS = 2; /** Receiver Status */ runStatus status; + /** Activated/Deactivated */ + int activated; //***connection parameters*** /** Ethernet Interface */ @@ -528,6 +545,7 @@ class UDPBaseImplementation : protected virtual slsReceiverDefs, public UDPInter + //***callback parameters*** /** * function being called back for start acquisition diff --git a/slsReceiverSoftware/include/UDPInterface.h b/slsReceiverSoftware/include/UDPInterface.h index 9ad5a7e6a..d4c746c0f 100644 --- a/slsReceiverSoftware/include/UDPInterface.h +++ b/slsReceiverSoftware/include/UDPInterface.h @@ -252,6 +252,14 @@ class UDPInterface { */ virtual slsReceiverDefs::runStatus getStatus() const = 0; + /** + * Get activate + * If deactivated, receiver will write dummy packets 0xFF + * (as it will receive nothing from detector) + * @return 0 for deactivated, 1 for activated + */ + virtual int getActivate() const = 0; + @@ -474,6 +482,13 @@ class UDPInterface { */ virtual void closeFile(int i = -1) = 0; + /** + * Activate / Deactivate Receiver + * If deactivated, receiver will write dummy packets 0xFF + * (as it will receive nothing from detector) + */ + virtual int setActivate(int enable = -1) = 0; + //***callback functions*** /** diff --git a/slsReceiverSoftware/include/UDPStandardImplementation.h b/slsReceiverSoftware/include/UDPStandardImplementation.h index a3af9ab03..e2c9a5dcf 100644 --- a/slsReceiverSoftware/include/UDPStandardImplementation.h +++ b/slsReceiverSoftware/include/UDPStandardImplementation.h @@ -597,6 +597,7 @@ private: /** Missing Packet identifier value */ const static uint16_t missingPacketValue = 0xFFFF; + const static uint16_t deactivatedPacketValue = 0xFEFE; /** Dummy Packet identifier value */ const static uint32_t dummyPacketValue = 0xFFFFFFFF; @@ -675,6 +676,9 @@ private: bool killAllWritingThreads; + //***deactivated parameters*** + uint64_t deactivated_framenumber[MAX_NUMBER_OF_LISTENING_THREADS]; + uint32_t deactivated_packetnumber[MAX_NUMBER_OF_LISTENING_THREADS]; diff --git a/slsReceiverSoftware/include/slsReceiverTCPIPInterface.h b/slsReceiverSoftware/include/slsReceiverTCPIPInterface.h index 8b5c4527f..6eb7b8491 100644 --- a/slsReceiverSoftware/include/slsReceiverTCPIPInterface.h +++ b/slsReceiverSoftware/include/slsReceiverTCPIPInterface.h @@ -207,6 +207,10 @@ private: /** set fifo depth */ int set_fifo_depth(); + /** activate/ deactivate */ + int set_activate(); + + //General Functions /** Locks Receiver */ int lock_receiver(); diff --git a/slsReceiverSoftware/include/sls_receiver_funcs.h b/slsReceiverSoftware/include/sls_receiver_funcs.h index e1ef93040..c5e99c1b9 100644 --- a/slsReceiverSoftware/include/sls_receiver_funcs.h +++ b/slsReceiverSoftware/include/sls_receiver_funcs.h @@ -49,7 +49,9 @@ enum { F_ENABLE_RECEIVER_OVERWRITE, /**< set overwrite flag in receiver */ F_ENABLE_RECEIVER_TEN_GIGA, /**< enable 10Gbe in receiver */ - F_SET_RECEIVER_FIFO_DEPTH /**< set receiver fifo depth */ + F_SET_RECEIVER_FIFO_DEPTH, /**< set receiver fifo depth */ + + F_ACTIVATE /** < activate/deactivate readout */ /* Always append functions hereafter!!! */ }; diff --git a/slsReceiverSoftware/src/UDPBaseImplementation.cpp b/slsReceiverSoftware/src/UDPBaseImplementation.cpp index a76cf0e9f..b37885ac4 100644 --- a/slsReceiverSoftware/src/UDPBaseImplementation.cpp +++ b/slsReceiverSoftware/src/UDPBaseImplementation.cpp @@ -49,6 +49,7 @@ void UDPBaseImplementation::initializeMembers(){ //***receiver parameters*** status = IDLE; + activated = true; //***connection parameters*** strcpy(eth,""); @@ -187,7 +188,7 @@ uint32_t UDPBaseImplementation::getFifoDepth() const{ FILE_LOG(logDEBUG) << __AT /***receiver status***/ slsReceiverDefs::runStatus UDPBaseImplementation::getStatus() const{ FILE_LOG(logDEBUG) << __AT__ << " starting"; return status;} - +int UDPBaseImplementation::getActivate() const{FILE_LOG(logDEBUG) << __AT__ << " starting"; return activated;} /************************************************************************* @@ -448,6 +449,17 @@ void UDPBaseImplementation::closeFile(int i){ } +int UDPBaseImplementation::setActivate(int enable){ + FILE_LOG(logDEBUG) << __AT__ << " starting"; + + if(enable != -1){ + activated = enable; + FILE_LOG(logINFO) << "Activation: " << stringEnable(activated); + } + + return activated; +} + /***callback functions***/ void UDPBaseImplementation::registerCallBackStartAcquisition(int (*func)(char*, char*,int, int, void*),void *arg){ startAcquisitionCallBack=func; diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index d64692b65..829b736a3 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -191,6 +191,12 @@ void UDPStandardImplementation::initializeMembers(){ createFileMask = 0x0; killAllWritingThreads = false; + //***deactivated parameters*** + for(int i=0; i < MAX_NUMBER_OF_LISTENING_THREADS; i++){ + deactivated_framenumber[i] = 0; + deactivated_packetnumber[i] = 0; + } + //***filter parameters*** commonModeSubtractionEnable = false; moenchCommonModeSubtraction = NULL; @@ -837,6 +843,11 @@ int UDPStandardImplementation::startReceiver(char *c){ fileCreateSuccess = false; pthread_mutex_unlock(&statusMutex); + //deactivated parameters + for(int i = 0; i < numberofListeningThreads; ++i){ + deactivated_framenumber[i] = 0; + deactivated_packetnumber[i] = 0; + } //Print Receiver Configuration if(myDetectorType != EIGER){ @@ -959,32 +970,34 @@ void UDPStandardImplementation::startReadout(){ if(status == RUNNING){ - //check if all packets got - int totalP = 0,prev,i; - for(i=0; imissingPacket) = deactivatedPacketValue; + *( (uint64_t*) footer) = deactivated_framenumber[ithread]; + *( (uint16_t*) footer->packetNumber) = deactivated_packetnumber[ithread]; + //*( (uint16_t*) footer->packetNumber) = ithread*(packetsPerFrame/numberofListeningThreads)+deactivated_packetnumber[ithread]; +#ifdef MANUALDEBUG + eiger_packet_footer_t* efooter = (eiger_packet_footer_t*)(buffer[ithread] + footerOffset + HEADER_SIZE_NUM_TOT_PACKETS); + cprintf(GREEN,"thread:%d pnum:%d fnum:%d\n", + ithread, + (*( (uint16_t*) efooter->packetNumber)), + (uint32_t)(*( (uint64_t*) efooter))); +#endif + return onePacketSize; + } + int receivedSize = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS + cSize, lSize + cSize); //throw away packets that is not one packet size, need to check status if socket is shut down @@ -1622,6 +1671,7 @@ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int lSize, in } totalListeningFrameCount[ithread] += (receivedSize/onePacketSize); + #ifdef MANUALDEBUG if(receivedSize>0){ if(myDetectorType == JUNGFRAU){ @@ -2565,6 +2615,8 @@ void UDPStandardImplementation::stopWriting(int ithread, char* wbuffer[]){ cprintf(GREEN, "Total Packets Caught:%lld\n", (long long int)totalPacketsCaught); cprintf(GREEN, "Total Frames Caught:%lld\n",(long long int)(totalPacketsCaught/packetsPerFrame)); } + if(!activated) + cprintf(RED,"Note: Deactivated Receiver\n"); //acquisition end if (acquisitionFinishedCallBack) acquisitionFinishedCallBack((int)(totalPacketsCaught/packetsPerFrame), pAcquisitionFinished); diff --git a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp index c1017a4a7..92ebcfc8a 100644 --- a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp +++ b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp @@ -262,6 +262,7 @@ int slsReceiverTCPIPInterface::function_table(){ flist[F_ENABLE_RECEIVER_TEN_GIGA] = &slsReceiverTCPIPInterface::enable_tengiga; flist[F_SET_RECEIVER_FIFO_DEPTH] = &slsReceiverTCPIPInterface::set_fifo_depth; + flist[F_ACTIVATE] = &slsReceiverTCPIPInterface::set_activate; #ifdef VERYVERBOSE @@ -2720,8 +2721,75 @@ int slsReceiverTCPIPInterface::set_fifo_depth() { +int slsReceiverTCPIPInterface::set_activate() { + ret=OK; + int retval=-1; + int enable; + strcpy(mess,"Could not activate/deactivate\n"); + // receive arguments + if(socket->ReceiveDataOnly(&enable,sizeof(enable)) < 0 ){ + strcpy(mess,"Error reading from socket\n"); + cprintf(RED,"%s",mess); + ret = FAIL; + } + + // execute action if the arguments correctly arrived +#ifdef SLS_RECEIVER_UDP_FUNCTIONS + if (ret==OK) { + if (lockStatus==1 && socket->differentClients==1){ + sprintf(mess,"Receiver locked by %s\n", socket->lastClientIP); + ret=FAIL; + } + + if(ret!=FAIL){ + if (receiverBase == NULL){ + strcpy(mess,SET_RECEIVER_ERR_MESSAGE); + cprintf(RED,"%s",mess); + ret=FAIL; + }else if(receiverBase->getStatus()==RUNNING){ + strcpy(mess,"Cannot activate/deactivate while status is running\n"); + cprintf(RED,"%s",mess); + ret=FAIL; + }else{ + if(enable != -1) + receiverBase->setActivate(enable); + retval = receiverBase->getActivate(); + if(enable >= 0 && retval != enable){ + sprintf(mess,"Tried to set activate to %d, but returned %d\n",enable,retval); + ret = FAIL; + cprintf(RED,"%s",mess); + } + } + } + } +#endif +#ifdef VERYVERBOSE + if(ret!=FAIL) + cout << "Activate: " << retval << endl; + else + cout << mess << endl; +#endif + + + if(ret==OK && socket->differentClients){ + FILE_LOG(logDEBUG) << "Force update"; + ret=FORCE_UPDATE; + } + + // send answer + socket->SendDataOnly(&ret,sizeof(ret)); + if(ret==FAIL){ + cprintf(RED,"%s\n",mess); + socket->SendDataOnly(mess,sizeof(mess)); + } + socket->SendDataOnly(&retval,sizeof(retval)); + + //return ok/fail + return ret; +} + From 94667c5dde58249ebfc1a42bfc758f5d3247a821 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 4 Oct 2016 15:15:08 +0200 Subject: [PATCH 258/474] got rif of unnecessary usleep in lisetning --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 829b736a3..02a50018a 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1527,9 +1527,6 @@ void UDPStandardImplementation::startListening(){ tempBuffer = new char[onePacketSize * (packetsPerFrame - 1)]; //store maximum of 1 packets less in a frame } - if(!activated) - usleep(1* 1000 * 1000); - /* inner loop - loop for each buffer */ //until mask unset (udp sockets shut down by client) while((1 << ithread) & listeningThreadsMask){ From 489b623afd4c3dd9b7effb41f0db5e66092f8e8f Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Wed, 5 Oct 2016 08:24:35 +0200 Subject: [PATCH 259/474] trying to get in changes for activate in receiver --- .../include/UDPBaseImplementation.h | 15 +++ slsReceiverSoftware/include/UDPInterface.h | 14 +++ .../include/UDPStandardImplementation.h | 5 + .../include/slsReceiverTCPIPInterface.h | 4 + .../include/sls_receiver_funcs.h | 1 + .../src/UDPBaseImplementation.cpp | 14 ++- .../src/UDPStandardImplementation.cpp | 115 ++++++++++++++---- .../src/slsReceiverTCPIPInterface.cpp | 72 +++++++++++ 8 files changed, 212 insertions(+), 28 deletions(-) diff --git a/slsReceiverSoftware/include/UDPBaseImplementation.h b/slsReceiverSoftware/include/UDPBaseImplementation.h index f576e2666..8af8b8fa0 100644 --- a/slsReceiverSoftware/include/UDPBaseImplementation.h +++ b/slsReceiverSoftware/include/UDPBaseImplementation.h @@ -200,6 +200,13 @@ class UDPBaseImplementation : protected virtual slsReceiverDefs, public UDPInter */ runStatus getStatus() const; + /** + * Get activate + * If deactivated, receiver will write dummy packets 0xFF + * (as it will receive nothing from detector) + * @return 0 for deactivated, 1 for activated + */ + int getActivate() const; @@ -432,6 +439,12 @@ class UDPBaseImplementation : protected virtual slsReceiverDefs, public UDPInter */ void closeFile(int ithread = 0); + /** + * Activate / Deactivate Receiver + * If deactivated, receiver will write dummy packets 0xFF + * (as it will receive nothing from detector) + */ + int setActivate(int enable = -1); //***callback functions*** /** @@ -500,6 +513,8 @@ class UDPBaseImplementation : protected virtual slsReceiverDefs, public UDPInter const static int MAX_NUMBER_OF_LISTENING_THREADS = 2; /** Receiver Status */ runStatus status; + /** Activated/Deactivated */ + int activated; //***connection parameters*** /** Ethernet Interface */ diff --git a/slsReceiverSoftware/include/UDPInterface.h b/slsReceiverSoftware/include/UDPInterface.h index 9ef30c680..0afda8d67 100644 --- a/slsReceiverSoftware/include/UDPInterface.h +++ b/slsReceiverSoftware/include/UDPInterface.h @@ -258,6 +258,13 @@ class UDPInterface { */ virtual slsReceiverDefs::runStatus getStatus() const = 0; + /** + * Get activate + * If deactivated, receiver will write dummy packets 0xFF + * (as it will receive nothing from detector) + * @return 0 for deactivated, 1 for activated + */ + virtual int getActivate() const = 0; @@ -489,6 +496,13 @@ class UDPInterface { virtual void closeFile(int ithread = 0) = 0; + /** + * Activate / Deactivate Receiver + * If deactivated, receiver will write dummy packets 0xFF + * (as it will receive nothing from detector) + */ + virtual int setActivate(int enable = -1) = 0; + //***callback functions*** /** * Call back for start acquisition diff --git a/slsReceiverSoftware/include/UDPStandardImplementation.h b/slsReceiverSoftware/include/UDPStandardImplementation.h index 14e0f638f..6e687b856 100644 --- a/slsReceiverSoftware/include/UDPStandardImplementation.h +++ b/slsReceiverSoftware/include/UDPStandardImplementation.h @@ -663,6 +663,7 @@ private: /** Missing Packet identifier value */ const static uint16_t missingPacketValue = 0xFFFF; + const static uint16_t deactivatedPacketValue = 0xFEFE; /** Dummy Packet identifier value */ const static uint32_t dummyPacketValue = 0xFFFFFFFF; @@ -756,6 +757,10 @@ private: + //***deactivated parameters*** + uint64_t deactivatedFrameNumber[MAX_NUMBER_OF_LISTENING_THREADS]; + int deactivatedFrameIncrement; + //***filter parameters*** diff --git a/slsReceiverSoftware/include/slsReceiverTCPIPInterface.h b/slsReceiverSoftware/include/slsReceiverTCPIPInterface.h index 8b30be84f..3deaac0a8 100644 --- a/slsReceiverSoftware/include/slsReceiverTCPIPInterface.h +++ b/slsReceiverSoftware/include/slsReceiverTCPIPInterface.h @@ -210,6 +210,10 @@ private: /** set fifo depth */ int set_fifo_depth(); + /** activate/ deactivate */ + int set_activate(); + + //General Functions /** Locks Receiver */ int lock_receiver(); diff --git a/slsReceiverSoftware/include/sls_receiver_funcs.h b/slsReceiverSoftware/include/sls_receiver_funcs.h index cc3490c42..6294a13ab 100644 --- a/slsReceiverSoftware/include/sls_receiver_funcs.h +++ b/slsReceiverSoftware/include/sls_receiver_funcs.h @@ -51,6 +51,7 @@ enum { F_ENABLE_RECEIVER_TEN_GIGA, /**< enable 10Gbe in receiver */ F_SET_RECEIVER_FIFO_DEPTH, /**< set receiver fifo depth */ + F_ACTIVATE, /** < activate/deactivate readout */ F_STREAM_DATA_FROM_RECEIVER /**< stream data from receiver to client */ /* Always append functions hereafter!!! */ diff --git a/slsReceiverSoftware/src/UDPBaseImplementation.cpp b/slsReceiverSoftware/src/UDPBaseImplementation.cpp index 4032f27e8..22c24e05d 100644 --- a/slsReceiverSoftware/src/UDPBaseImplementation.cpp +++ b/slsReceiverSoftware/src/UDPBaseImplementation.cpp @@ -49,6 +49,7 @@ void UDPBaseImplementation::initializeMembers(){ //***receiver parameters*** status = IDLE; + activated = true; //***connection parameters*** strcpy(eth,""); @@ -190,7 +191,7 @@ uint32_t UDPBaseImplementation::getFifoDepth() const{ FILE_LOG(logDEBUG) << __AT /***receiver status***/ slsReceiverDefs::runStatus UDPBaseImplementation::getStatus() const{ FILE_LOG(logDEBUG) << __AT__ << " starting"; return status;} - +int UDPBaseImplementation::getActivate() const{FILE_LOG(logDEBUG) << __AT__ << " starting"; return activated;} /************************************************************************* @@ -464,6 +465,17 @@ void UDPBaseImplementation::closeFile(int ithread){ } +int UDPBaseImplementation::setActivate(int enable){ + FILE_LOG(logDEBUG) << __AT__ << " starting"; + + if(enable != -1){ + activated = enable; + FILE_LOG(logINFO) << "Activation: " << stringEnable(activated); + } + + return activated; +} + /***callback functions***/ void UDPBaseImplementation::registerCallBackStartAcquisition(int (*func)(char*, char*,int, int, void*),void *arg){ startAcquisitionCallBack=func; diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 01bf81401..cd0ac82b3 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -212,6 +212,12 @@ void UDPStandardImplementation::initializeMembers(){ createFileMask = 0x0; killAllWritingThreads = false; + + //***deactivated parameters*** + for(int i=0; i < MAX_NUMBER_OF_LISTENING_THREADS; i++) + deactivatedFrameNumber[i] = 0; + deactivatedFrameIncrement = 0; + //***filter parameters*** commonModeSubtractionEnable = false; moenchCommonModeSubtraction = NULL; @@ -957,6 +963,11 @@ int UDPStandardImplementation::startReceiver(char *c){ fileCreateSuccess = false; pthread_mutex_unlock(&statusMutex); + //deactivated parameters + for(int i = 0; i < numberofListeningThreads; ++i) + deactivatedFrameNumber[i] = 0; + deactivatedFrameIncrement = (bufferSize/(onePacketSize*packetsPerFrame))*numberofJobsPerBuffer; + FILE_LOG(logINFO) << "Deactivated Frame Increment:" << deactivatedFrameIncrement; //Print Receiver Configuration @@ -1095,44 +1106,48 @@ void UDPStandardImplementation::startReadout(){ if(status == RUNNING){ - //check if all packets got - int totalP = 0,prev=-1,i; - for(i=0; igetCurrentTotalReceived(); + //needs to wait for packets only if activated + if(activated){ + //check if all packets got + int totalP = 0,prev=-1,i; + for(i=0; igetCurrentTotalReceived(); - //wait as long as there is change from prev totalP, - //and also change from received in buffer to previous value - //(as one listens to many at a time, shouldnt cut off in between) - while((prev != totalP) || (prevReceivedInBuffer!= currentReceivedInBuffer)){ + //wait for all packets + if(totalP!=numberOfFrames*packetsPerFrame*numberofListeningThreads){ + + //wait as long as there is change from prev totalP, + //and also change from received in buffer to previous value + //(as one listens to many at a time, shouldnt cut off in between) + while((prev != totalP) || (prevReceivedInBuffer!= currentReceivedInBuffer)){ #ifdef DEBUG5 - cprintf(MAGENTA,"waiting for all packets totalP:%d currently in buffer:%d\n",totalP,currentReceivedInBuffer); + cprintf(MAGENTA,"waiting for all packets totalP:%d currently in buffer:%d\n",totalP,currentReceivedInBuffer); #endif - usleep(5000);/* Need to find optimal time (exposure time and acquisition period) **/ - prev = totalP; - totalP = 0; - for(i=0; igetCurrentTotalReceived(); + prevReceivedInBuffer = currentReceivedInBuffer; + currentReceivedInBuffer = 0; + for(i=0; igetCurrentTotalReceived(); #ifdef DEBUG5 - cprintf(MAGENTA,"\tupdated: totalP:%d currently in buffer:%d\n",totalP,currentReceivedInBuffer); + cprintf(MAGENTA,"\tupdated: totalP:%d currently in buffer:%d\n",totalP,currentReceivedInBuffer); #endif + } + } - } //set status @@ -1953,7 +1968,7 @@ void UDPStandardImplementation::startListening(){ //udpsocket doesnt exist - if(status == TRANSMITTING){ + if ((status == TRANSMITTING)||(rc == 0 && activated == 0)){ FILE_LOG(logERROR) << "Listening_Thread " << ithread << ": UDP Socket not created or shut down earlier"; stopListening(ithread,0); continue; @@ -2023,6 +2038,50 @@ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int cSize, ch //carry over from previous buffer if(cSize) memcpy(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS, temp, cSize); + + if(!activated){ + //cSize = 0 for deactivated + int framestoclone = 0; + //done + if(deactivatedFrameNumber[ithread] == numberOfFrames) + return 0; + //last + if((deactivatedFrameNumber[ithread] + deactivatedFrameIncrement) > numberOfFrames) + framestoclone = numberOfFrames - deactivatedFrameNumber[ithread]; + //in progress + else + framestoclone = deactivatedFrameIncrement; + + //copy dummy packets + memset(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS, 0xFF,framestoclone*packetsPerFrame*onePacketSize); + + //set fnum, pnum and deactivatedpacket label + eiger_packet_header_t* header; + eiger_packet_footer_t* footer; + int pnum=0; + //loop by each packet + for(int offset=HEADER_SIZE_NUM_TOT_PACKETS; + offsetpacketNumber) = ++pnum; + *( (uint16_t*) header->missingPacket) = deactivatedPacketValue; +#ifdef MANUALDEBUG + cprintf(GREEN,"thread:%d pnum:%d fnum:%d\n", + ithread, + (*( (uint16_t*) footer->packetNumber)), + (uint32_t)(*( (uint64_t*) footer))); +#endif + if(pnum == packetsPerFrame) + pnum = 0; + } + + return framestoclone*onePacketSize; + } + + if(status != TRANSMITTING) receivedSize = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS + cSize, (bufferSize * numberofJobsPerBuffer) - cSize); //eiger returns 0 when header packet caught @@ -2604,6 +2663,8 @@ void UDPStandardImplementation::stopWriting(int ithread, char* wbuffer){ } } + if(!activated) + cprintf(RED,"Note: Deactivated Receiver\n"); //acquisition end if (acquisitionFinishedCallBack) diff --git a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp index 607b00e14..9b7518e95 100644 --- a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp +++ b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp @@ -262,6 +262,7 @@ int slsReceiverTCPIPInterface::function_table(){ flist[F_ENABLE_RECEIVER_TEN_GIGA] = &slsReceiverTCPIPInterface::enable_tengiga; flist[F_SET_RECEIVER_FIFO_DEPTH] = &slsReceiverTCPIPInterface::set_fifo_depth; + flist[F_ACTIVATE] = &slsReceiverTCPIPInterface::set_activate; flist[F_STREAM_DATA_FROM_RECEIVER] = &slsReceiverTCPIPInterface::set_data_stream_enable; #ifdef VERYVERBOSE @@ -2862,6 +2863,77 @@ int slsReceiverTCPIPInterface::set_fifo_depth() { +int slsReceiverTCPIPInterface::set_activate() { + ret=OK; + int retval=-1; + int enable; + strcpy(mess,"Could not activate/deactivate\n"); + + + // receive arguments + if(socket->ReceiveDataOnly(&enable,sizeof(enable)) < 0 ){ + strcpy(mess,"Error reading from socket\n"); + cprintf(RED,"%s",mess); + ret = FAIL; + } + + + // execute action if the arguments correctly arrived +#ifdef SLS_RECEIVER_UDP_FUNCTIONS + if (ret==OK) { + if (lockStatus==1 && socket->differentClients==1){ + sprintf(mess,"Receiver locked by %s\n", socket->lastClientIP); + ret=FAIL; + } + + if(ret!=FAIL){ + if (receiverBase == NULL){ + strcpy(mess,SET_RECEIVER_ERR_MESSAGE); + cprintf(RED,"%s",mess); + ret=FAIL; + }else if(receiverBase->getStatus()==RUNNING){ + strcpy(mess,"Cannot activate/deactivate while status is running\n"); + cprintf(RED,"%s",mess); + ret=FAIL; + }else{ + if(enable != -1) + receiverBase->setActivate(enable); + retval = receiverBase->getActivate(); + if(enable >= 0 && retval != enable){ + sprintf(mess,"Tried to set activate to %d, but returned %d\n",enable,retval); + ret = FAIL; + cprintf(RED,"%s",mess); + } + } + } + } +#endif +#ifdef VERYVERBOSE + if(ret!=FAIL) + cout << "Activate: " << retval << endl; + else + cout << mess << endl; +#endif + + + if(ret==OK && socket->differentClients){ + FILE_LOG(logDEBUG) << "Force update"; + ret=FORCE_UPDATE; + } + + // send answer + socket->SendDataOnly(&ret,sizeof(ret)); + if(ret==FAIL){ + cprintf(RED,"%s\n",mess); + socket->SendDataOnly(mess,sizeof(mess)); + } + socket->SendDataOnly(&retval,sizeof(retval)); + + //return ok/fail + return ret; +} + + From bf54c1556072c43fe25f64be750f0579616a01a9 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Wed, 5 Oct 2016 09:30:08 +0200 Subject: [PATCH 260/474] updated to have activate function implemented --- .../src/UDPStandardImplementation.cpp | 47 ++++++++++++------- .../src/slsReceiverTCPIPInterface.cpp | 2 +- 2 files changed, 30 insertions(+), 19 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index cd0ac82b3..cf126b771 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -97,6 +97,10 @@ void UDPStandardImplementation::deleteMembers(){ createWriterThreads(true); threadStarted = false; } + if(zmqThreadStarted){ + createDataCallbackThreads(true); + zmqThreadStarted = false; + } } void UDPStandardImplementation::deleteFilter(){ @@ -452,7 +456,6 @@ void UDPStandardImplementation::setFileName(const char c[]){ detID = 0; } - if(dataStreamEnable && (strcmp(oldfilename,fileName))){ if(zmqThreadStarted) createDataCallbackThreads(true); @@ -576,6 +579,8 @@ uint32_t UDPStandardImplementation::setDataStreamEnable(const uint32_t enable){ int olddatasend = dataStreamEnable; dataStreamEnable = enable; + FILE_LOG(logINFO) << "Data Send to Gui: " << dataStreamEnable; + //if there is a change if(olddatasend != dataStreamEnable){ if(zmqThreadStarted) @@ -589,9 +594,6 @@ uint32_t UDPStandardImplementation::setDataStreamEnable(const uint32_t enable){ } } - FILE_LOG(logINFO) << "Data Send to Gui: " << dataStreamEnable; - - return OK; } @@ -1968,7 +1970,7 @@ void UDPStandardImplementation::startListening(){ //udpsocket doesnt exist - if ((status == TRANSMITTING)||(rc == 0 && activated == 0)){ + if(activated && udpSocket[ithread] == NULL){ FILE_LOG(logERROR) << "Listening_Thread " << ithread << ": UDP Socket not created or shut down earlier"; stopListening(ithread,0); continue; @@ -1981,7 +1983,7 @@ void UDPStandardImplementation::startListening(){ if((!measurementStarted) && (rc > 0)) startFrameIndices(ithread); //problem in receiving or end of acquisition - if (status == TRANSMITTING){ + if (status == TRANSMITTING||(rc == 0 && activated == 0)){ stopListening(ithread,rc); continue; } @@ -2040,20 +2042,25 @@ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int cSize, ch if(!activated){ + //cSize = 0 for deactivated int framestoclone = 0; + //first + if(deactivatedFrameNumber[ithread]==0) + deactivatedFrameNumber[ithread]++; //done - if(deactivatedFrameNumber[ithread] == numberOfFrames) + if(deactivatedFrameNumber[ithread] == (numberOfFrames+1)) return 0; //last - if((deactivatedFrameNumber[ithread] + deactivatedFrameIncrement) > numberOfFrames) - framestoclone = numberOfFrames - deactivatedFrameNumber[ithread]; + if((deactivatedFrameNumber[ithread] + deactivatedFrameIncrement) > (numberOfFrames+1)) + framestoclone = (numberOfFrames+1) - deactivatedFrameNumber[ithread]; //in progress else framestoclone = deactivatedFrameIncrement; //copy dummy packets - memset(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS, 0xFF,framestoclone*packetsPerFrame*onePacketSize); + receivedSize = framestoclone*packetsPerFrame*onePacketSize; + memset(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS, 0xFF,receivedSize); //set fnum, pnum and deactivatedpacket label eiger_packet_header_t* header; @@ -2061,24 +2068,28 @@ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int cSize, ch int pnum=0; //loop by each packet for(int offset=HEADER_SIZE_NUM_TOT_PACKETS; - offsetpacketNumber) = ++pnum; *( (uint16_t*) header->missingPacket) = deactivatedPacketValue; #ifdef MANUALDEBUG - cprintf(GREEN,"thread:%d pnum:%d fnum:%d\n", - ithread, - (*( (uint16_t*) footer->packetNumber)), - (uint32_t)(*( (uint64_t*) footer))); + if(!ithread){ + cprintf(GREEN,"thread:%d pnum:%d fnum:%d\n", + ithread, + (*( (uint16_t*) footer->packetNumber)), + (uint32_t)(*( (uint64_t*) footer))); + } #endif - if(pnum == packetsPerFrame) + if(pnum == packetsPerFrame){ pnum = 0; + deactivatedFrameNumber[ithread]++; + } } - return framestoclone*onePacketSize; + return receivedSize; } diff --git a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp index 9b7518e95..c99df4f36 100644 --- a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp +++ b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp @@ -877,7 +877,7 @@ int slsReceiverTCPIPInterface::stop_receiver(){ ret=FAIL; } else{ - if(receiverBase->getStatus()==RUNNING || receiverBase->getStatus()==TRANSMITTING){ + if(receiverBase->getStatus()==RUNNING || receiverBase->getStatus()==TRANSMITTING || receiverBase->getStatus()==RUN_FINISHED){ receiverBase->stopReceiver(); } s = receiverBase->getStatus(); From 09e8bf414458505dc13bad914ad784fd8cbc5666 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Wed, 5 Oct 2016 15:27:25 +0200 Subject: [PATCH 261/474] somewhere --- .../src/UDPStandardImplementation.cpp | 37 +++++-------------- 1 file changed, 10 insertions(+), 27 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index cf126b771..996e708b9 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -95,12 +95,9 @@ void UDPStandardImplementation::deleteMembers(){ if(threadStarted){ createListeningThreads(true); createWriterThreads(true); - threadStarted = false; } - if(zmqThreadStarted){ + if(zmqThreadStarted) createDataCallbackThreads(true); - zmqThreadStarted = false; - } } void UDPStandardImplementation::deleteFilter(){ @@ -338,7 +335,6 @@ int UDPStandardImplementation::setupFifoStructure(){ if(threadStarted){ createListeningThreads(true); createWriterThreads(true); - threadStarted = false; } @@ -456,16 +452,6 @@ void UDPStandardImplementation::setFileName(const char c[]){ detID = 0; } - if(dataStreamEnable && (strcmp(oldfilename,fileName))){ - if(zmqThreadStarted) - createDataCallbackThreads(true); - numberofDataCallbackThreads = MAX_NUMBER_OF_LISTENING_THREADS; - if(createDataCallbackThreads() == FAIL){ - cprintf(BG_RED,"Error: Could not create data callback threads\n"); - } - } - - FILE_LOG(logINFO) << "File name:" << fileName; } @@ -576,21 +562,17 @@ int UDPStandardImplementation::setFrameToGuiFrequency(const uint32_t freq){ uint32_t UDPStandardImplementation::setDataStreamEnable(const uint32_t enable){ FILE_LOG(logDEBUG) << __AT__ << " called"; - - int olddatasend = dataStreamEnable; dataStreamEnable = enable; FILE_LOG(logINFO) << "Data Send to Gui: " << dataStreamEnable; - //if there is a change - if(olddatasend != dataStreamEnable){ - if(zmqThreadStarted) - createDataCallbackThreads(true); + //data sockets have to be created again as the client ones are + if(zmqThreadStarted) + createDataCallbackThreads(true); - if(dataStreamEnable){ - numberofDataCallbackThreads = MAX_NUMBER_OF_LISTENING_THREADS; - if(createDataCallbackThreads() == FAIL){ - cprintf(BG_RED,"Error: Could not create data callback threads\n"); - } + if(dataStreamEnable){ + numberofDataCallbackThreads = MAX_NUMBER_OF_LISTENING_THREADS; + if(createDataCallbackThreads() == FAIL){ + cprintf(BG_RED,"Error: Could not create data callback threads\n"); } } @@ -1690,7 +1672,8 @@ void UDPStandardImplementation::startDataCallback(){ switch(myDetectorType){ case EIGER: headersize = EIGER_HEADER_SIZE; break; - + default: + headersize = 0; break; } From 65acd118c5d190f6e317dbb33ce760560ab6443d Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Thu, 6 Oct 2016 13:51:23 +0200 Subject: [PATCH 262/474] looks done --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 996e708b9..eb099aaf8 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1665,7 +1665,7 @@ void UDPStandardImplementation::startDataCallback(){ char hostName[100] = "tcp://127.0.0.1:"; int portno = DEFAULT_ZMQ_PORTNO + (detID*2+ithread); sprintf(hostName,"%s%d",hostName,portno); - FILE_LOG(logINFO) << "Thread" << ithread << ": ZMQ Server at " << hostName; + int headersize=0; @@ -1700,6 +1700,7 @@ void UDPStandardImplementation::startDataCallback(){ int val = -1; zmq_setsockopt(zmqsocket, ZMQ_LINGER, &val,sizeof(val)); // wait for the unsent packets before closing socket zmq_bind(zmqsocket,hostName); // bind + FILE_LOG(logINFO) << "Thread" << ithread << ": ZMQ Server at " << hostName; //let calling function know thread started and obtained current (after sockets created) if(!zmqThreadStarted) From 6f6199ad204de56c62f18a381756a6a59735fdb0 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Thu, 6 Oct 2016 14:43:56 +0200 Subject: [PATCH 263/474] moved created socket outside innner and outer loop --- .../src/UDPStandardImplementation.cpp | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index eb099aaf8..317eadd25 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1666,6 +1666,13 @@ void UDPStandardImplementation::startDataCallback(){ int portno = DEFAULT_ZMQ_PORTNO + (detID*2+ithread); sprintf(hostName,"%s%d",hostName,portno); + //socket details + void *context = zmq_ctx_new(); + void *zmqsocket = zmq_socket(context, ZMQ_PUSH); // create a publisher + int val = -1; + zmq_setsockopt(zmqsocket, ZMQ_LINGER, &val,sizeof(val)); // wait for the unsent packets before closing socket + zmq_bind(zmqsocket,hostName); // bind + FILE_LOG(logINFO) << "Thread" << ithread << ": ZMQ Server at " << hostName; int headersize=0; @@ -1676,6 +1683,9 @@ void UDPStandardImplementation::startDataCallback(){ headersize = 0; break; } + //let calling function know thread started and obtained current (after sockets created) + if(!zmqThreadStarted) + zmqThreadStarted = true; /* outer loop - loops once for each acquisition */ //infinite loop, exited only to change dynamic range, 10G parameters etc (then recreated again) @@ -1694,17 +1704,7 @@ void UDPStandardImplementation::startDataCallback(){ bool randomSendNow = true; bool newFrame = false; - //socket details - void *context = zmq_ctx_new(); - void *zmqsocket = zmq_socket(context, ZMQ_PUSH); // create a publisher - int val = -1; - zmq_setsockopt(zmqsocket, ZMQ_LINGER, &val,sizeof(val)); // wait for the unsent packets before closing socket - zmq_bind(zmqsocket,hostName); // bind - FILE_LOG(logINFO) << "Thread" << ithread << ": ZMQ Server at " << hostName; - //let calling function know thread started and obtained current (after sockets created) - if(!zmqThreadStarted) - zmqThreadStarted = true; //header details const char *type = "float64"; @@ -1884,24 +1884,24 @@ void UDPStandardImplementation::startDataCallback(){ //free resources delete[] buffer; - zmq_unbind(zmqsocket, hostName); /* will this be too soon and cut the sending*/ - zmq_close(zmqsocket); - zmq_ctx_destroy(context); //end of acquisition, wait for next acquisition/change of parameters sem_wait(&dataCallbackSemaphore[ithread]); - - //check to exit thread (for change of parameters) - only EXIT possibility if(killAllDataCallbackThreads){ - cprintf(MAGENTA,"DataCallback_Thread %d:Goodbye!\n",ithread); - pthread_exit(NULL); + break;//pthread_exit(NULL); } }/*--end of loop for each acquisition (outer loop) */ + + //free resources + zmq_unbind(zmqsocket, hostName); /* will this be too soon and cut the sending*/ + zmq_close(zmqsocket); + zmq_ctx_destroy(context); + cprintf(MAGENTA,"DataCallback_Thread %d:Goodbye!\n",ithread); } From e6db70354ce16d1498a59ad2e7a72660d86d0eda Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Thu, 6 Oct 2016 15:50:11 +0200 Subject: [PATCH 264/474] thread starting if rxr closed and others --- .../src/UDPStandardImplementation.cpp | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 317eadd25..e4113089f 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -562,17 +562,21 @@ int UDPStandardImplementation::setFrameToGuiFrequency(const uint32_t freq){ uint32_t UDPStandardImplementation::setDataStreamEnable(const uint32_t enable){ FILE_LOG(logDEBUG) << __AT__ << " called"; + int oldvalue = dataStreamEnable; dataStreamEnable = enable; FILE_LOG(logINFO) << "Data Send to Gui: " << dataStreamEnable; - //data sockets have to be created again as the client ones are - if(zmqThreadStarted) - createDataCallbackThreads(true); - if(dataStreamEnable){ - numberofDataCallbackThreads = MAX_NUMBER_OF_LISTENING_THREADS; - if(createDataCallbackThreads() == FAIL){ - cprintf(BG_RED,"Error: Could not create data callback threads\n"); + if(oldvalue!=dataStreamEnable){ + //data sockets have to be created again as the client ones are + if(zmqThreadStarted) + createDataCallbackThreads(true); + + if(dataStreamEnable){ + numberofDataCallbackThreads = MAX_NUMBER_OF_LISTENING_THREADS; + if(createDataCallbackThreads() == FAIL){ + cprintf(BG_RED,"Error: Could not create data callback threads\n"); + } } } From 59f3aef703f4208d63479d8392e274c03844c0d1 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Fri, 7 Oct 2016 10:15:19 +0200 Subject: [PATCH 265/474] back to subscriber publisher --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index e4113089f..8d2ec4c6e 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1672,8 +1672,8 @@ void UDPStandardImplementation::startDataCallback(){ //socket details void *context = zmq_ctx_new(); - void *zmqsocket = zmq_socket(context, ZMQ_PUSH); // create a publisher - int val = -1; + void *zmqsocket = zmq_socket(context, ZMQ_PUB); // create a publisher + int val = 100; zmq_setsockopt(zmqsocket, ZMQ_LINGER, &val,sizeof(val)); // wait for the unsent packets before closing socket zmq_bind(zmqsocket,hostName); // bind FILE_LOG(logINFO) << "Thread" << ithread << ": ZMQ Server at " << hostName; From 831bd8e160bf8d25ccd0972d28c85f6d527f614b Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Fri, 7 Oct 2016 11:40:56 +0200 Subject: [PATCH 266/474] some changes for quitting gui and continuing with acquire from command line --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 5 +++-- slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 8d2ec4c6e..4971cc589 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1672,8 +1672,8 @@ void UDPStandardImplementation::startDataCallback(){ //socket details void *context = zmq_ctx_new(); - void *zmqsocket = zmq_socket(context, ZMQ_PUB); // create a publisher - int val = 100; + void *zmqsocket = zmq_socket(context, ZMQ_PUSH); // create a publisher + int val = -1; zmq_setsockopt(zmqsocket, ZMQ_LINGER, &val,sizeof(val)); // wait for the unsent packets before closing socket zmq_bind(zmqsocket,hostName); // bind FILE_LOG(logINFO) << "Thread" << ithread << ": ZMQ Server at " << hostName; @@ -1746,6 +1746,7 @@ void UDPStandardImplementation::startDataCallback(){ zmq_send(zmqsocket, buf,len, ZMQ_SNDMORE); //send data zmq_send(zmqsocket, buffer, oneframesize, 0); + cout<<"sent last dummy"< Date: Fri, 7 Oct 2016 12:14:08 +0200 Subject: [PATCH 267/474] removing check for read out --- slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp index aba6205a5..fd06334ab 100644 --- a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp +++ b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp @@ -2305,10 +2305,10 @@ int slsReceiverTCPIPInterface::start_readout(){cprintf(BLUE,"In start readout!\n strcpy(mess,SET_RECEIVER_ERR_MESSAGE); ret=FAIL; } - else if(receiverBase->getStatus()==RUNNING || receiverBase->getStatus()==TRANSMITTING){ + /*else if(receiverBase->getStatus()==RUNNING || receiverBase->getStatus()==TRANSMITTING){ strcpy(mess,"Can not start receiver readout while receiver not idle\n"); ret = FAIL; - } + }*/ else{ receiverBase->startReadout(); retval = receiverBase->getStatus(); From 47516cafdef86f005205d03afacd45e82f00f9a5 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Fri, 7 Oct 2016 14:26:53 +0200 Subject: [PATCH 268/474] works --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 4971cc589..2180bf2a0 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -2250,7 +2250,7 @@ void UDPStandardImplementation::stopListening(int ithread, int numbytes){ listeningThreadsMask^=(1< Date: Tue, 11 Oct 2016 12:35:49 +0200 Subject: [PATCH 269/474] somewhere --- slsReceiverSoftware/include/receiver_defs.h | 8 +++----- .../src/UDPStandardImplementation.cpp | 18 ++++++++++++++---- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/slsReceiverSoftware/include/receiver_defs.h b/slsReceiverSoftware/include/receiver_defs.h index d0cd07320..8ecd46ba9 100755 --- a/slsReceiverSoftware/include/receiver_defs.h +++ b/slsReceiverSoftware/include/receiver_defs.h @@ -171,7 +171,6 @@ typedef struct { #define EIGER_MAX_PORTS 2 #define EIGER_HEADER_PACKET_LENGTH 48 -#define EIGER_HEADER_SIZE 8 #define EIGER_FIFO_SIZE 100 /*#define EIGER_ALIGNED_FRAME_SIZE 65536*/ @@ -182,7 +181,7 @@ typedef struct { #define EIGER_ONE_GIGA_ONE_DATA_SIZE 1024 #define EIGER_TEN_GIGA_ONE_PACKET_SIZE 4112 #define EIGER_TEN_GIGA_ONE_DATA_SIZE 4096 -#define EIGER_PACKET_HEADER_SIZE 8 +#define EIGER_DATA_PACKET_HEADER_SIZE 8 //#define EIGER_BUFFER_SIZE_CONSTANT (EIGER_ONE_PACKET_SIZE*EIGER_PACKETS_PER_FRAME_COSTANT)//1040*16*2//*bit mode //#define EIGER_DATA_BYTES_CONSTANT (EIGER_ONE_DATA_SIZE*EIGER_PACKETS_PER_FRAME_COSTANT) //1024*16*2//*bit mode @@ -190,9 +189,8 @@ typedef struct { #define EIGER_FRAME_INDEX_OFFSET 0 #define EIGER_PACKET_INDEX_MASK 0x0 -#define EIGER_IMAGE_HEADER_SIZE 48 - -#define EIGER_PIXELS_IN_ONE_ROW (256*4) +//for each thread +#define EIGER_PIXELS_IN_ONE_ROW (256*2) #define EIGER_PIXELS_IN_ONE_COL (256) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 2180bf2a0..667892f95 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -671,7 +671,7 @@ int UDPStandardImplementation::setTenGigaEnable(const bool b){ oneDataSize = EIGER_ONE_GIGA_ONE_DATA_SIZE; } bufferSize = onePacketSize * packetsPerFrame; - footerOffset = EIGER_PACKET_HEADER_SIZE + oneDataSize; + footerOffset = EIGER_DATA_PACKET_HEADER_SIZE + oneDataSize; FILE_LOG(logDEBUG) << dec << "packetsPerFrame:" << packetsPerFrame << "\nonePacketSize:" << onePacketSize << @@ -803,7 +803,7 @@ int UDPStandardImplementation::setDetectorType(const detectorType d){ maxFramesPerFile = EIGER_MAX_FRAMES_PER_FILE; fifoSize = EIGER_FIFO_SIZE; fifoDepth = EIGER_FIFO_SIZE; - footerOffset = EIGER_PACKET_HEADER_SIZE + oneDataSize; + footerOffset = EIGER_DATA_PACKET_HEADER_SIZE + oneDataSize; break; case JUNGFRAUCTB: packetsPerFrame = JCTB_PACKETS_PER_FRAME; @@ -1682,7 +1682,7 @@ void UDPStandardImplementation::startDataCallback(){ int headersize=0; switch(myDetectorType){ case EIGER: - headersize = EIGER_HEADER_SIZE; break; + headersize = EIGER_DATA_PACKET_HEADER_SIZE; break; default: headersize = 0; break; } @@ -2884,13 +2884,23 @@ void UDPStandardImplementation::updateFileHeader(int ithread){ while((unsigned int)length!=strlen(fileHeader[ithread])){ length = strlen(fileHeader[ithread]); sprintf(fileHeader[ithread],"\nHeader\t\t %d bytes\n" + "Top\t\t %d\n" + "Left\t\t %d\n" "Dynamic Range\t %d\n" + "Ten Giga\t %d\n" "Packet\t\t %d bytes\n" + "Data\t\t %d bytes\n" "x\t\t %d pixels\n" "y\t\t %d pixels\n" "Timestamp\t %s\n\n" "%s", - length,dynamicRange,onePacketSize,xpix,ypix,ctime(&t), + length, + (bottomEnable?0:1),(ithread?0:1), + dynamicRange,tengigaEnable, + onePacketSize,oneDataSize, + xpix,ypix, + + ctime(&t), packetheader); } From 5c4d55af6b27fce7523a679f514e32bec292ae09 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Wed, 12 Oct 2016 08:53:13 +0200 Subject: [PATCH 270/474] random read, the current fnum shoud be sent, not the padded frame --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 667892f95..f5df08f7b 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1810,6 +1810,9 @@ void UDPStandardImplementation::startDataCallback(){ if(offset >= size) break; + if(!frameToGuiFrequency) + currentfnum = fnum; + //last packet of same frame if(fnum == currentfnum && pnum == (packetsPerFrame-1)){ From b0bedc516d6d9f69b058003f8b2aefe5e646799a Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Fri, 14 Oct 2016 16:08:43 +0200 Subject: [PATCH 271/474] works for missing packets and image reconstruction --- .../include/UDPStandardImplementation.h | 9 +- .../src/UDPStandardImplementation.cpp | 94 +++++++++---------- 2 files changed, 48 insertions(+), 55 deletions(-) diff --git a/slsReceiverSoftware/include/UDPStandardImplementation.h b/slsReceiverSoftware/include/UDPStandardImplementation.h index 6e687b856..7ec396ba0 100644 --- a/slsReceiverSoftware/include/UDPStandardImplementation.h +++ b/slsReceiverSoftware/include/UDPStandardImplementation.h @@ -591,7 +591,9 @@ private: /** If file created successfully for all Writer Threads */ bool fileCreateSuccess; - char fileHeader[MAX_NUMBER_OF_WRITER_THREADS][MAX_STR_LENGTH]; + const static int FILE_HEADER_SIZE = 400; + + char fileHeader[MAX_NUMBER_OF_WRITER_THREADS][FILE_HEADER_SIZE]; @@ -661,9 +663,8 @@ private: /** Total fifo size */ uint32_t fifoSize; - /** Missing Packet identifier value */ - const static uint16_t missingPacketValue = 0xFFFF; - const static uint16_t deactivatedPacketValue = 0xFEFE; + /** Missing Packet */ + int missingPacketinFile; /** Dummy Packet identifier value */ const static uint32_t dummyPacketValue = 0xFFFFFFFF; diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index f5df08f7b..eee2f5373 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1586,7 +1586,7 @@ int UDPStandardImplementation::createNewFile(int ithread){ //write file header if(myDetectorType == EIGER) - fwrite((void*)fileHeader[ithread], 1, strlen(fileHeader[ithread]), sfilefd[ithread]); + fwrite((void*)fileHeader[ithread], 1, FILE_HEADER_SIZE, sfilefd[ithread]); } //reset counters for each new file @@ -1823,7 +1823,7 @@ void UDPStandardImplementation::startDataCallback(){ offset+= onePacketSize; //send header //update frame details - frameIndex = fnum;if(frameIndex==-1) cprintf(RED,"frameindex = -1, 222\n"); + frameIndex = fnum; acquisitionIndex = fnum - startAcquisitionIndex; if(dynamicRange == 32) subframeIndex = snum; int len = sprintf(buf,jsonFmt,type,shape, acquisitionIndex, frameIndex, subframeIndex,completeFileName[ithread]); @@ -1859,7 +1859,7 @@ void UDPStandardImplementation::startDataCallback(){ #endif //send header //update frame details - frameIndex = fnum;if(frameIndex==-1) cprintf(RED,"frameindex = -1, 333\n"); + frameIndex = fnum; acquisitionIndex = fnum - startAcquisitionIndex; if(dynamicRange == 32) subframeIndex = snum; int len = sprintf(buf,jsonFmt,type,shape, acquisitionIndex, frameIndex, subframeIndex,completeFileName[ithread]); @@ -2066,7 +2066,6 @@ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int cSize, ch footer = (eiger_packet_footer_t*)(buffer[ithread] + offset + footerOffset); *( (uint64_t*) footer) = deactivatedFrameNumber[ithread]; *( (uint16_t*) footer->packetNumber) = ++pnum; - *( (uint16_t*) header->missingPacket) = deactivatedPacketValue; #ifdef MANUALDEBUG if(!ithread){ cprintf(GREEN,"thread:%d pnum:%d fnum:%d\n", @@ -2613,6 +2612,12 @@ void UDPStandardImplementation::stopWriting(int ithread, char* wbuffer){ //all threads need to close file, reset mask and exit loop + missingPacketinFile = (long long int)numberOfFrames*packetsPerFrame-totalWritingPacketCount[ithread]; + if(missingPacketinFile){ + updateFileHeader(ithread); + fseek(sfilefd[ithread],0,0); + fwrite((void*)fileHeader[ithread], 1, FILE_HEADER_SIZE, sfilefd[ithread]); + } closeFile(ithread); pthread_mutex_lock(&statusMutex); writerThreadsMask^=(1< FILE_HEADER_SIZE) + cprintf(BG_RED,"File Header Size is too small for file header\n"); - ctime(&t), - packetheader); - } } From 37c0ea74534921fe708f703e87bfca34c0971a9f Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 18 Oct 2016 08:43:21 +0200 Subject: [PATCH 272/474] almost there --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index eee2f5373..28d079009 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1673,8 +1673,10 @@ void UDPStandardImplementation::startDataCallback(){ //socket details void *context = zmq_ctx_new(); void *zmqsocket = zmq_socket(context, ZMQ_PUSH); // create a publisher - int val = -1; + int val = 4; zmq_setsockopt(zmqsocket, ZMQ_LINGER, &val,sizeof(val)); // wait for the unsent packets before closing socket + //val = 10; + //zmq_setsockopt(zmqsocket,ZMQ_SNDHWM,&val,sizeof(val)); //set SEND HIGH WATER MARK (8-9ms slower) zmq_bind(zmqsocket,hostName); // bind FILE_LOG(logINFO) << "Thread" << ithread << ": ZMQ Server at " << hostName; @@ -1750,6 +1752,8 @@ void UDPStandardImplementation::startDataCallback(){ newFrame = false; } + + /* //send final header //update frame details #ifdef DEBUG @@ -1762,6 +1766,7 @@ void UDPStandardImplementation::startDataCallback(){ zmq_send(zmqsocket, buf,len, ZMQ_SNDMORE); //send final data zmq_send (zmqsocket, "end", 3, 0); + */ pthread_mutex_lock(&statusMutex); dataCallbackThreadsMask^=(1< Date: Tue, 18 Oct 2016 11:10:42 +0200 Subject: [PATCH 273/474] done --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 28d079009..7f811a830 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1785,7 +1785,7 @@ void UDPStandardImplementation::startDataCallback(){ cprintf(BLUE,"%d Elapsed time:%f seconds\n",ithread,( end.tv_sec - begin.tv_sec ) + ( end.tv_nsec - begin.tv_nsec ) / 1000000000.0); #endif //still less than 250 ms, keep waiting - if((( end.tv_sec - begin.tv_sec ) + ( end.tv_nsec - begin.tv_nsec ) / 1000000000.0) < 0.250)/**fixed 250 ms*/ + if((( end.tv_sec - begin.tv_sec ) + ( end.tv_nsec - begin.tv_nsec ) / 1000000000.0) < 0.5)/**fixed 250 ms*/ continue; //done with timer, look into data randomSendNow = true; From e00ad76e556a3449ba9c1790d87c7bffeff5d07d Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 18 Oct 2016 12:08:11 +0200 Subject: [PATCH 274/474] trying --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 7f811a830..92423380d 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1673,7 +1673,8 @@ void UDPStandardImplementation::startDataCallback(){ //socket details void *context = zmq_ctx_new(); void *zmqsocket = zmq_socket(context, ZMQ_PUSH); // create a publisher - int val = 4; + int val = -1; + /*int val = 4;*/ zmq_setsockopt(zmqsocket, ZMQ_LINGER, &val,sizeof(val)); // wait for the unsent packets before closing socket //val = 10; //zmq_setsockopt(zmqsocket,ZMQ_SNDHWM,&val,sizeof(val)); //set SEND HIGH WATER MARK (8-9ms slower) @@ -1753,7 +1754,7 @@ void UDPStandardImplementation::startDataCallback(){ } - /* + /*/**/ //send final header //update frame details #ifdef DEBUG @@ -1766,7 +1767,7 @@ void UDPStandardImplementation::startDataCallback(){ zmq_send(zmqsocket, buf,len, ZMQ_SNDMORE); //send final data zmq_send (zmqsocket, "end", 3, 0); - */ + /* */ pthread_mutex_lock(&statusMutex); dataCallbackThreadsMask^=(1< Date: Tue, 18 Oct 2016 12:19:20 +0200 Subject: [PATCH 275/474] switched --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 92423380d..85d14ab52 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1673,8 +1673,8 @@ void UDPStandardImplementation::startDataCallback(){ //socket details void *context = zmq_ctx_new(); void *zmqsocket = zmq_socket(context, ZMQ_PUSH); // create a publisher - int val = -1; - /*int val = 4;*/ + /*int val = -1;*/ + int val = 4; zmq_setsockopt(zmqsocket, ZMQ_LINGER, &val,sizeof(val)); // wait for the unsent packets before closing socket //val = 10; //zmq_setsockopt(zmqsocket,ZMQ_SNDHWM,&val,sizeof(val)); //set SEND HIGH WATER MARK (8-9ms slower) @@ -1754,7 +1754,7 @@ void UDPStandardImplementation::startDataCallback(){ } - /*/**/ + /* //send final header //update frame details #ifdef DEBUG @@ -1767,7 +1767,7 @@ void UDPStandardImplementation::startDataCallback(){ zmq_send(zmqsocket, buf,len, ZMQ_SNDMORE); //send final data zmq_send (zmqsocket, "end", 3, 0); - /* */ + */ pthread_mutex_lock(&statusMutex); dataCallbackThreadsMask^=(1< Date: Tue, 18 Oct 2016 14:05:05 +0200 Subject: [PATCH 276/474] back --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 85d14ab52..f9e38ec03 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1673,8 +1673,7 @@ void UDPStandardImplementation::startDataCallback(){ //socket details void *context = zmq_ctx_new(); void *zmqsocket = zmq_socket(context, ZMQ_PUSH); // create a publisher - /*int val = -1;*/ - int val = 4; + int val = -1; zmq_setsockopt(zmqsocket, ZMQ_LINGER, &val,sizeof(val)); // wait for the unsent packets before closing socket //val = 10; //zmq_setsockopt(zmqsocket,ZMQ_SNDHWM,&val,sizeof(val)); //set SEND HIGH WATER MARK (8-9ms slower) @@ -1754,7 +1753,7 @@ void UDPStandardImplementation::startDataCallback(){ } - /* + //send final header //update frame details #ifdef DEBUG @@ -1767,7 +1766,7 @@ void UDPStandardImplementation::startDataCallback(){ zmq_send(zmqsocket, buf,len, ZMQ_SNDMORE); //send final data zmq_send (zmqsocket, "end", 3, 0); - */ + pthread_mutex_lock(&statusMutex); dataCallbackThreadsMask^=(1< Date: Tue, 18 Oct 2016 14:31:05 +0200 Subject: [PATCH 277/474] overwriting --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index f9e38ec03..7e8cf4a05 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -2618,7 +2618,7 @@ void UDPStandardImplementation::stopWriting(int ithread, char* wbuffer){ //all threads need to close file, reset mask and exit loop missingPacketinFile = (long long int)numberOfFrames*packetsPerFrame-totalWritingPacketCount[ithread]; - if(missingPacketinFile){ + if(fileWriteEnable && (cbAction > DO_NOTHING) && missingPacketinFile){ updateFileHeader(ithread); fseek(sfilefd[ithread],0,0); fwrite((void*)fileHeader[ithread], 1, FILE_HEADER_SIZE, sfilefd[ithread]); From 09c853ae267ba0a9b37400284aafb15681dc6dcd Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Thu, 20 Oct 2016 07:55:56 +0200 Subject: [PATCH 278/474] fixed the print file packet loss progress bug --- .../src/UDPStandardImplementation.cpp | 47 ++++++++++++------- 1 file changed, 31 insertions(+), 16 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 02a50018a..4f6ee79ae 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1373,8 +1373,10 @@ int UDPStandardImplementation::createNewFile(){ FILE_LOG(logDEBUG) << __AT__ << " called"; int index = 0; - if(packetsCaught) + if(packetsCaught){ index = frameIndex; + cout << endl << "File:" << completeFileName < Date: Thu, 20 Oct 2016 08:13:42 +0200 Subject: [PATCH 279/474] fixed the print file packet loss progress bug --- .../src/UDPStandardImplementation.cpp | 42 ++++++++++++------- 1 file changed, 28 insertions(+), 14 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 7e8cf4a05..79069fb02 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1529,8 +1529,10 @@ int UDPStandardImplementation::createNewFile(int ithread){ FILE_LOG(logDEBUG) << __AT__ << " called"; int index = 0; - if(totalWritingPacketCount[ithread]) + if(totalWritingPacketCount[ithread]){ index = frameIndex[ithread]; + cout << "\nThread " << ithread << "\tFile:" << completeFileName < Date: Thu, 20 Oct 2016 08:24:54 +0200 Subject: [PATCH 280/474] proper update of progressfile bug --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 4f6ee79ae..4515f9b5e 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -2574,6 +2574,7 @@ void UDPStandardImplementation::stopWriting(int ithread, char* wbuffer[]){ //all threads need to close file, reset mask and exit loop if(packetsCaught){ + cout << endl << "File:" << completeFileName < Date: Thu, 20 Oct 2016 08:30:38 +0200 Subject: [PATCH 281/474] proper update of progressfile bug --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 4515f9b5e..bc2ae3787 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -2580,7 +2580,7 @@ void UDPStandardImplementation::stopWriting(int ithread, char* wbuffer[]){ // dec << (int)((( (currentFrameNumber-1-previousFrameNumber) - ((packetsInFile-numTotMissingPacketsInFile)/packetsPerFrame))/ // (double)(currentFrameNumber-1-previousFrameNumber))*100.000) // << "%\t" - << "Packets Lost:" << dec << ( ((int)(currentFrameNumber-1-previousFrameNumber)) - + << "Packets Lost:" << dec << ( ((int)(currentFrameNumber-previousFrameNumber)) - ((packetsInFile-numTotMissingPacketsInFile)/packetsPerFrame)) << "\tCurrentFrameNumber:" << currentFrameNumber << "\tPreviousFrameNumber:" << previousFrameNumber From 0cd926133202dd19a8cb3e74e210319f62575594 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Thu, 20 Oct 2016 09:17:42 +0200 Subject: [PATCH 282/474] merge fix --- slsReceiverSoftware/include/UDPInterface.h | 7 -- .../src/UDPStandardImplementation.cpp | 29 ++++---- .../src/slsReceiverTCPIPInterface.cpp | 69 ------------------- 3 files changed, 16 insertions(+), 89 deletions(-) diff --git a/slsReceiverSoftware/include/UDPInterface.h b/slsReceiverSoftware/include/UDPInterface.h index 4769cab55..5065f3ab4 100644 --- a/slsReceiverSoftware/include/UDPInterface.h +++ b/slsReceiverSoftware/include/UDPInterface.h @@ -502,13 +502,6 @@ class UDPInterface { virtual int setActivate(int enable = -1) = 0; - /** - * Activate / Deactivate Receiver - * If deactivated, receiver will write dummy packets 0xFF - * (as it will receive nothing from detector) - */ - virtual int setActivate(int enable = -1) = 0; - //***callback functions*** /** * Call back for start acquisition diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index a185326a9..5823220be 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1531,7 +1531,7 @@ int UDPStandardImplementation::createNewFile(int ithread){ int index = 0; if(totalWritingPacketCount[ithread]){ index = frameIndex[ithread]; - cout << "\nThread " << ithread << "\tFile:" << completeFileName <ReceiveDataOnly(&enable,sizeof(enable)) < 0 ){ - strcpy(mess,"Error reading from socket\n"); - cprintf(RED,"%s",mess); - ret = FAIL; - } - - // execute action if the arguments correctly arrived -#ifdef SLS_RECEIVER_UDP_FUNCTIONS - if (ret==OK) { - if (lockStatus==1 && socket->differentClients==1){ - sprintf(mess,"Receiver locked by %s\n", socket->lastClientIP); - ret=FAIL; - } - - if(ret!=FAIL){ - if (receiverBase == NULL){ - strcpy(mess,SET_RECEIVER_ERR_MESSAGE); - cprintf(RED,"%s",mess); - ret=FAIL; - }else if(receiverBase->getStatus()==RUNNING){ - strcpy(mess,"Cannot activate/deactivate while status is running\n"); - cprintf(RED,"%s",mess); - ret=FAIL; - }else{ - if(enable != -1) - receiverBase->setActivate(enable); - retval = receiverBase->getActivate(); - if(enable >= 0 && retval != enable){ - sprintf(mess,"Tried to set activate to %d, but returned %d\n",enable,retval); - ret = FAIL; - cprintf(RED,"%s",mess); - } - } - } - } -#endif -#ifdef VERYVERBOSE - if(ret!=FAIL) - cout << "Activate: " << retval << endl; - else - cout << mess << endl; -#endif - - - if(ret==OK && socket->differentClients){ - FILE_LOG(logDEBUG) << "Force update"; - ret=FORCE_UPDATE; - } - - // send answer - socket->SendDataOnly(&ret,sizeof(ret)); - if(ret==FAIL){ - cprintf(RED,"%s\n",mess); - socket->SendDataOnly(mess,sizeof(mess)); - } - socket->SendDataOnly(&retval,sizeof(retval)); - - //return ok/fail - return ret; -} - int slsReceiverTCPIPInterface::set_activate() { ret=OK; From 58b48aefe2fa81ba7909abc9dfc4083bf7e3717f Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 25 Oct 2016 12:08:46 +0200 Subject: [PATCH 283/474] changed the file max to test for 9m and trying to fix packetloss print --- slsReceiverSoftware/include/sls_receiver_defs.h | 2 +- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 9 +++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/slsReceiverSoftware/include/sls_receiver_defs.h b/slsReceiverSoftware/include/sls_receiver_defs.h index e37639b07..1d93459df 100755 --- a/slsReceiverSoftware/include/sls_receiver_defs.h +++ b/slsReceiverSoftware/include/sls_receiver_defs.h @@ -23,7 +23,7 @@ typedef int int32_t; #define MAX_FRAMES_PER_FILE 20000 #define SHORT_MAX_FRAMES_PER_FILE 100000 #define MOENCH_MAX_FRAMES_PER_FILE 1000 -#define EIGER_MAX_FRAMES_PER_FILE 2000 +#define EIGER_MAX_FRAMES_PER_FILE 5 #define JFRAU_MAX_FRAMES_PER_FILE 2000 #define JFCTB_MAX_FRAMES_PER_FILE 100000 diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 5823220be..082e1dcd1 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1572,13 +1572,16 @@ int UDPStandardImplementation::createNewFile(int ithread){ frameNumberInPreviousFile[ithread] = -1; cout << "Thread " << ithread << " File:" << completeFileName[ithread] << endl; }else{ + if(frameNumberInPreviousFile[ithread] == -1) + frameNumberInPreviousFile[ithread] = startFrameIndex - 1; + cout //<< "Packet Loss:" << //setw(4)< Date: Tue, 25 Oct 2016 12:16:38 +0200 Subject: [PATCH 284/474] trying to fix packetloss print --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 082e1dcd1..4b24fe79e 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1573,7 +1573,7 @@ int UDPStandardImplementation::createNewFile(int ithread){ cout << "Thread " << ithread << " File:" << completeFileName[ithread] << endl; }else{ if(frameNumberInPreviousFile[ithread] == -1) - frameNumberInPreviousFile[ithread] = startFrameIndex - 1; + frameNumberInPreviousFile[ithread] = startFrameIndex; cout //<< "Packet Loss:" << @@ -2632,7 +2632,7 @@ void UDPStandardImplementation::stopWriting(int ithread, char* wbuffer){ if(totalWritingPacketCount[ithread]){ if(frameNumberInPreviousFile[ithread]==-1) - frameNumberInPreviousFile[ithread] = startFrameIndex - 1; + frameNumberInPreviousFile[ithread] = startFrameIndex; cout << "\nThread " << ithread << "\tFile:" << completeFileName[ithread] < Date: Tue, 25 Oct 2016 12:26:53 +0200 Subject: [PATCH 285/474] trying to fix packetloss print --- .../src/UDPStandardImplementation.cpp | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 4b24fe79e..714a1928f 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1575,18 +1575,25 @@ int UDPStandardImplementation::createNewFile(int ithread){ if(frameNumberInPreviousFile[ithread] == -1) frameNumberInPreviousFile[ithread] = startFrameIndex; - cout + printf("\nThread %d\tFile:%s\n" + "\tPackets Lost:%d\tCurrentFrameNumber:%lld\tPreviousFrameNumber:%lld\n", + ithread,completeFileName[ithread], + ( ((int)(currentFrameNumber[ithread]-frameNumberInPreviousFile[ithread])*packetsPerFrame) - totalPacketsInFile[ithread]), + currentFrameNumber[ithread],frameNumberInPreviousFile[ithread]); + /* + cout << "\nThread " << ithread << "\tFile:" << completeFileName[ithread] < Date: Tue, 25 Oct 2016 12:29:56 +0200 Subject: [PATCH 286/474] trying to fix packetloss print --- .../src/UDPStandardImplementation.cpp | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 714a1928f..e69cee168 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1575,9 +1575,10 @@ int UDPStandardImplementation::createNewFile(int ithread){ if(frameNumberInPreviousFile[ithread] == -1) frameNumberInPreviousFile[ithread] = startFrameIndex; - printf("\nThread %d\tFile:%s\n" - "\tPackets Lost:%d\tCurrentFrameNumber:%lld\tPreviousFrameNumber:%lld\n", + printf("\nThread:%d File:%s\n" + "\totalpacketsinfile:%d\tPackets Lost:%d\tCurrentFrameNumber:%lld\tPreviousFrameNumber:%lld\n", ithread,completeFileName[ithread], + totalPacketsInFile[ithread], ( ((int)(currentFrameNumber[ithread]-frameNumberInPreviousFile[ithread])*packetsPerFrame) - totalPacketsInFile[ithread]), currentFrameNumber[ithread],frameNumberInPreviousFile[ithread]); /* @@ -1587,10 +1588,6 @@ int UDPStandardImplementation::createNewFile(int ithread){ //dec << (int)((( (currentFrameNumber-1-previousFrameNumber) - ((packetsInFile-numTotMissingPacketsInFile)/packetsPerFrame))/ // (double)(currentFrameNumber-1-previousFrameNumber))*100.000) //<< "%\t" - cout<< "\tPackets Lost:" << dec << ( ((int)(currentFrameNumber[ithread]-frameNumberInPreviousFile[ithread])*packetsPerFrame) - - totalPacketsInFile[ithread]) - << "\tCurrentFrameNumber:" << currentFrameNumber[ithread] - << "\tPreviousFrameNumber:" << frameNumberInPreviousFile[ithread] //<< "\tIndex:" << dec << index << endl; */ @@ -2640,9 +2637,11 @@ void UDPStandardImplementation::stopWriting(int ithread, char* wbuffer){ if(totalWritingPacketCount[ithread]){ if(frameNumberInPreviousFile[ithread]==-1) frameNumberInPreviousFile[ithread] = startFrameIndex; - printf("\nThread %d\tFile:%s\n" - "\tPackets Lost:%d\tCurrentFrameNumber:%lld\tPreviousFrameNumber:%lld\n", + + printf("\nThread:%d File:%s\n" + "\totalpacketsinfile:%d\tPackets Lost:%d\tCurrentFrameNumber:%lld\tPreviousFrameNumber:%lld\n", ithread,completeFileName[ithread], + totalPacketsInFile[ithread], ( ((int)(currentFrameNumber[ithread]-frameNumberInPreviousFile[ithread])*packetsPerFrame) - totalPacketsInFile[ithread]), currentFrameNumber[ithread],frameNumberInPreviousFile[ithread]); /* @@ -2652,10 +2651,6 @@ void UDPStandardImplementation::stopWriting(int ithread, char* wbuffer){ //dec << (int)((( (currentFrameNumber-1-previousFrameNumber) - ((packetsInFile-numTotMissingPacketsInFile)/packetsPerFrame))/ // (double)(currentFrameNumber-1-previousFrameNumber))*100.000) //<< "%\t" - cout << "\tPackets Lost:" << dec << ( ((int)(currentFrameNumber[ithread]-frameNumberInPreviousFile[ithread])*packetsPerFrame) - - totalPacketsInFile[ithread]) - << "\tCurrentFrameNumber:" << currentFrameNumber[ithread] - << "\tPreviousFrameNumber:" << frameNumberInPreviousFile[ithread] //<< "\tIndex:" << dec << index << endl; */ From 38b2a272ee865861f20466f4208e0588e72eed50 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 25 Oct 2016 13:14:25 +0200 Subject: [PATCH 287/474] trying to fix packetloss print --- .../src/UDPStandardImplementation.cpp | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index e69cee168..ee1baf1b5 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -2733,20 +2733,10 @@ void UDPStandardImplementation::handleWithoutDataCompression(int ithread, char* return; } - //update current frame number - currentFrameNumber[ithread] = tempframenumber; - - //set indices - pthread_mutex_lock(&progressMutex); - if((currentFrameNumber[ithread] - startAcquisitionIndex) > acquisitionIndex) - acquisitionIndex = currentFrameNumber[ithread] - startAcquisitionIndex; - if((currentFrameNumber[ithread] - startFrameIndex) > frameIndex[ithread]) - frameIndex[ithread] = currentFrameNumber[ithread] - startFrameIndex; - pthread_mutex_unlock(&progressMutex); //callback to write data if (cbAction < DO_EVERYTHING) - rawDataReadyCallBack((int)currentFrameNumber[ithread], wbuffer + HEADER_SIZE_NUM_TOT_PACKETS, npackets * onePacketSize, + rawDataReadyCallBack((int)tempframenumber, wbuffer + HEADER_SIZE_NUM_TOT_PACKETS, npackets * onePacketSize, sfilefd[ithread], latestData[ithread],pRawDataReady);//know which thread from sfilefd @@ -2852,6 +2842,8 @@ void UDPStandardImplementation::writeFileWithoutCompression(int ithread, char* w totalPacketsCaught += packetsWritten; pthread_mutex_unlock(&writeMutex); currentFrameNumber[ithread] += lastFrameNumberInFile[ithread]; + + } } } From 173c5b961127ac40d968707e88058d9c5be9ac19 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 25 Oct 2016 13:23:49 +0200 Subject: [PATCH 288/474] trying to fix packetloss print --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index ee1baf1b5..55165c502 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1570,13 +1570,12 @@ int UDPStandardImplementation::createNewFile(int ithread){ //Print packet loss and filenames if(!totalWritingPacketCount[ithread]){ frameNumberInPreviousFile[ithread] = -1; - cout << "Thread " << ithread << " File:" << completeFileName[ithread] << endl; }else{ if(frameNumberInPreviousFile[ithread] == -1) frameNumberInPreviousFile[ithread] = startFrameIndex; printf("\nThread:%d File:%s\n" - "\totalpacketsinfile:%d\tPackets Lost:%d\tCurrentFrameNumber:%lld\tPreviousFrameNumber:%lld\n", + "\ttotalpacketsinfile:%d\tPackets Lost:%d\tCurrentFrameNumber:%lld\tPreviousFrameNumber:%lld\n", ithread,completeFileName[ithread], totalPacketsInFile[ithread], ( ((int)(currentFrameNumber[ithread]-frameNumberInPreviousFile[ithread])*packetsPerFrame) - totalPacketsInFile[ithread]), @@ -2639,7 +2638,7 @@ void UDPStandardImplementation::stopWriting(int ithread, char* wbuffer){ frameNumberInPreviousFile[ithread] = startFrameIndex; printf("\nThread:%d File:%s\n" - "\totalpacketsinfile:%d\tPackets Lost:%d\tCurrentFrameNumber:%lld\tPreviousFrameNumber:%lld\n", + "\ttotalpacketsinfile:%d\tPackets Lost:%d\tCurrentFrameNumber:%lld\tPreviousFrameNumber:%lld\n", ithread,completeFileName[ithread], totalPacketsInFile[ithread], ( ((int)(currentFrameNumber[ithread]-frameNumberInPreviousFile[ithread])*packetsPerFrame) - totalPacketsInFile[ithread]), From 0fddcd162d1dc7c6bc60847f92a08a0c3ada9180 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 25 Oct 2016 13:26:35 +0200 Subject: [PATCH 289/474] trying to fix packetloss print --- .../src/UDPStandardImplementation.cpp | 27 +------------------ 1 file changed, 1 insertion(+), 26 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 55165c502..e67d4246d 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1528,12 +1528,6 @@ int UDPStandardImplementation::setupWriter(){ int UDPStandardImplementation::createNewFile(int ithread){ FILE_LOG(logDEBUG) << __AT__ << " called"; - int index = 0; - if(totalWritingPacketCount[ithread]){ - index = frameIndex[ithread]; - cout << "\nThread " << ithread << "\tFile:" << completeFileName[ithread] < Date: Tue, 25 Oct 2016 13:29:17 +0200 Subject: [PATCH 290/474] trying to fix packetloss print --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index e67d4246d..d25ee21f2 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1564,7 +1564,7 @@ int UDPStandardImplementation::createNewFile(int ithread){ //Print packet loss and filenames if(!totalWritingPacketCount[ithread]){ frameNumberInPreviousFile[ithread] = -1; - printf("\nThread:%d File:%s\n",ithread,completeFileName[ithread]); + printf("Thread:%d File:%s\n",ithread,completeFileName[ithread]); }else{ if(frameNumberInPreviousFile[ithread] == -1) frameNumberInPreviousFile[ithread] = startFrameIndex; @@ -2816,6 +2816,7 @@ void UDPStandardImplementation::writeFileWithoutCompression(int ithread, char* w totalPacketsCaught += packetsWritten; pthread_mutex_unlock(&writeMutex); currentFrameNumber[ithread] += lastFrameNumberInFile[ithread]; + if(!ithread)cprintf(BLUE,"currentFrameNumber[ithread]:%d\n",currentFrameNumber[ithread]); } From 636d5840aa783a1721791905d2f0691ada19e68d Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 25 Oct 2016 13:31:11 +0200 Subject: [PATCH 291/474] trying to fix packetloss print --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index d25ee21f2..e5cce450f 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1567,7 +1567,7 @@ int UDPStandardImplementation::createNewFile(int ithread){ printf("Thread:%d File:%s\n",ithread,completeFileName[ithread]); }else{ if(frameNumberInPreviousFile[ithread] == -1) - frameNumberInPreviousFile[ithread] = startFrameIndex; + frameNumberInPreviousFile[ithread] = startFrameIndex -1; printf("\nThread:%d File:%s\n" "\ttotalpacketsinfile:%d\tPackets Lost:%d\tCurrentFrameNumber:%lld\tPreviousFrameNumber:%lld\n", @@ -2620,7 +2620,7 @@ void UDPStandardImplementation::stopWriting(int ithread, char* wbuffer){ if(totalWritingPacketCount[ithread]){ if(frameNumberInPreviousFile[ithread]==-1) - frameNumberInPreviousFile[ithread] = startFrameIndex; + frameNumberInPreviousFile[ithread] = startFrameIndex-1; printf("\nThread:%d File:%s\n" "\ttotalpacketsinfile:%d\tPackets Lost:%d\tCurrentFrameNumber:%lld\tPreviousFrameNumber:%lld\n", From 7b36c63d8f6a5f4824d9f73cd9d177761ed17499 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 25 Oct 2016 14:08:31 +0200 Subject: [PATCH 292/474] fixed packetloss print --- .../include/sls_receiver_defs.h | 2 +- .../src/UDPStandardImplementation.cpp | 31 +++++++++++-------- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/slsReceiverSoftware/include/sls_receiver_defs.h b/slsReceiverSoftware/include/sls_receiver_defs.h index 1d93459df..e37639b07 100755 --- a/slsReceiverSoftware/include/sls_receiver_defs.h +++ b/slsReceiverSoftware/include/sls_receiver_defs.h @@ -23,7 +23,7 @@ typedef int int32_t; #define MAX_FRAMES_PER_FILE 20000 #define SHORT_MAX_FRAMES_PER_FILE 100000 #define MOENCH_MAX_FRAMES_PER_FILE 1000 -#define EIGER_MAX_FRAMES_PER_FILE 5 +#define EIGER_MAX_FRAMES_PER_FILE 2000 #define JFRAU_MAX_FRAMES_PER_FILE 2000 #define JFCTB_MAX_FRAMES_PER_FILE 100000 diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index e5cce450f..433e777ef 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1570,11 +1570,15 @@ int UDPStandardImplementation::createNewFile(int ithread){ frameNumberInPreviousFile[ithread] = startFrameIndex -1; printf("\nThread:%d File:%s\n" - "\ttotalpacketsinfile:%d\tPackets Lost:%d\tCurrentFrameNumber:%lld\tPreviousFrameNumber:%lld\n", + //"\ttotalpacketsinfile:%d\t" + "Packets Lost:%d" + //"\tCurrentFrameNumber:%lld\tPreviousFrameNumber:%lld" + "\n", ithread,completeFileName[ithread], - totalPacketsInFile[ithread], - ( ((int)(currentFrameNumber[ithread]-frameNumberInPreviousFile[ithread])*packetsPerFrame) - totalPacketsInFile[ithread]), - currentFrameNumber[ithread],frameNumberInPreviousFile[ithread]); + //totalPacketsInFile[ithread], + ( ((int)(currentFrameNumber[ithread]-frameNumberInPreviousFile[ithread])*packetsPerFrame) - totalPacketsInFile[ithread]) + //,currentFrameNumber[ithread],frameNumberInPreviousFile[ithread] + ); } //write file header @@ -2251,7 +2255,7 @@ void UDPStandardImplementation::stopListening(int ithread, int numbytes){ listeningThreadsMask^=(1< Date: Thu, 27 Oct 2016 08:27:31 +0200 Subject: [PATCH 293/474] changes to make jungfrau work --- .../include/UDPStandardImplementation.h | 3 + slsReceiverSoftware/include/genericSocket.h | 11 +- slsReceiverSoftware/include/receiver_defs.h | 2 +- .../src/UDPStandardImplementation.cpp | 103 ++++++++++-------- 4 files changed, 69 insertions(+), 50 deletions(-) diff --git a/slsReceiverSoftware/include/UDPStandardImplementation.h b/slsReceiverSoftware/include/UDPStandardImplementation.h index 1912bcbea..cc69e0da0 100644 --- a/slsReceiverSoftware/include/UDPStandardImplementation.h +++ b/slsReceiverSoftware/include/UDPStandardImplementation.h @@ -663,6 +663,9 @@ private: /** Total fifo size */ uint32_t fifoSize; + /** fifo buffer header size */ + uint32_t fifoBufferHeaderSize; + /** Missing Packet */ int missingPacketinFile; diff --git a/slsReceiverSoftware/include/genericSocket.h b/slsReceiverSoftware/include/genericSocket.h index 91debdec1..1ceb7203b 100644 --- a/slsReceiverSoftware/include/genericSocket.h +++ b/slsReceiverSoftware/include/genericSocket.h @@ -615,13 +615,14 @@ enum communicationProtocol{ /*int k = 0;*/ while(length>0){ - nsending = (length>packet_size) ? packet_size:length; + if(lengthpacket_size) ? packet_size:length; //works for eiger to get packets to discard image header packets nsent = recvfrom(socketDescriptor,(char*)buf+total_sent,nsending, 0, (struct sockaddr *) &clientAddress, &clientAddress_length); - if(nsent < packet_size) { - if(nsent){ - if((nsent != header_packet_size) && (nsent != -1)) + if(nsent != nsending){ //if((nsent != nsending)){ && (nsent < packet_size)){ + if(nsent && (nsent != header_packet_size) && (nsent != -1)) cprintf(RED,"Incomplete Packet size %d\n",nsent); - } break; } length-=nsent; diff --git a/slsReceiverSoftware/include/receiver_defs.h b/slsReceiverSoftware/include/receiver_defs.h index 8ecd46ba9..29c3f4994 100755 --- a/slsReceiverSoftware/include/receiver_defs.h +++ b/slsReceiverSoftware/include/receiver_defs.h @@ -129,7 +129,7 @@ typedef struct { - +#define JFRAU_FILE_FRAME_HEADER_LENGTH 16 #define JFRAU_FIFO_SIZE 2500 //cannot be less than max jobs per thread = 1000 #define JFRAU_PACKETS_PER_FRAME 128 #define JFRAU_HEADER_LENGTH 22 diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 5823220be..bb64f86f9 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -368,7 +368,7 @@ int UDPStandardImplementation::setupFifoStructure(){ fifo[i] = new CircularFifo(fifoSize); //allocate memory - mem0[i] = (char*)malloc((bufferSize * numberofJobsPerBuffer + HEADER_SIZE_NUM_TOT_PACKETS) * fifoSize); + mem0[i] = (char*)malloc((bufferSize * numberofJobsPerBuffer + fifoBufferHeaderSize) * fifoSize); if (mem0[i] == NULL){ cprintf(BG_RED,"Error: Could not allocate memory for listening \n"); return FAIL; @@ -376,10 +376,10 @@ int UDPStandardImplementation::setupFifoStructure(){ //push free address into fifoFree buffer[i]=mem0[i]; - while (buffer[i] < (mem0[i]+(bufferSize * numberofJobsPerBuffer + HEADER_SIZE_NUM_TOT_PACKETS) * (fifoSize-1))) { + while (buffer[i] < (mem0[i]+(bufferSize * numberofJobsPerBuffer + fifoBufferHeaderSize) * (fifoSize-1))) { //cprintf(BLUE,"fifofree %d: push 0x%p\n",i,(void*)buffer[i]); /*for(int k=0;kpush(buffer[i])); @@ -387,7 +387,7 @@ int UDPStandardImplementation::setupFifoStructure(){ #ifdef DEBUG5 cprintf(BLUE,"Info: %d fifostructure free pushed into fifofree %p\n", i, (void*)(buffer[i])); #endif - buffer[i] += (bufferSize * numberofJobsPerBuffer + HEADER_SIZE_NUM_TOT_PACKETS); + buffer[i] += (bufferSize * numberofJobsPerBuffer + fifoBufferHeaderSize); } } cout << "Fifo structure(s) reconstructed" << endl; @@ -763,6 +763,7 @@ int UDPStandardImplementation::setDetectorType(const detectorType d){ maxFramesPerFile = MAX_FRAMES_PER_FILE; fifoSize = GOTTHARD_FIFO_SIZE; fifoDepth = GOTTHARD_FIFO_SIZE; + fifoBufferHeaderSize= HEADER_SIZE_NUM_TOT_PACKETS; //footerOffset = Not applicable; break; case PROPIX: @@ -776,6 +777,7 @@ int UDPStandardImplementation::setDetectorType(const detectorType d){ maxFramesPerFile = MAX_FRAMES_PER_FILE; fifoSize = PROPIX_FIFO_SIZE; fifoDepth = PROPIX_FIFO_SIZE; + fifoBufferHeaderSize= HEADER_SIZE_NUM_TOT_PACKETS; //footerOffset = Not applicable; break; case MOENCH: @@ -789,6 +791,7 @@ int UDPStandardImplementation::setDetectorType(const detectorType d){ maxFramesPerFile = MOENCH_MAX_FRAMES_PER_FILE; fifoSize = MOENCH_FIFO_SIZE; fifoDepth = MOENCH_FIFO_SIZE; + fifoBufferHeaderSize= HEADER_SIZE_NUM_TOT_PACKETS; //footerOffset = Not applicable; break; case EIGER: @@ -804,6 +807,7 @@ int UDPStandardImplementation::setDetectorType(const detectorType d){ fifoSize = EIGER_FIFO_SIZE; fifoDepth = EIGER_FIFO_SIZE; footerOffset = EIGER_DATA_PACKET_HEADER_SIZE + oneDataSize; + fifoBufferHeaderSize= HEADER_SIZE_NUM_TOT_PACKETS; break; case JUNGFRAUCTB: packetsPerFrame = JCTB_PACKETS_PER_FRAME; @@ -816,6 +820,7 @@ int UDPStandardImplementation::setDetectorType(const detectorType d){ maxFramesPerFile = JFCTB_MAX_FRAMES_PER_FILE; fifoSize = JCTB_FIFO_SIZE; fifoDepth = JCTB_FIFO_SIZE; + fifoBufferHeaderSize= HEADER_SIZE_NUM_TOT_PACKETS; //footerOffset = Not applicable; break; case JUNGFRAU: @@ -829,6 +834,7 @@ int UDPStandardImplementation::setDetectorType(const detectorType d){ maxFramesPerFile = JFRAU_MAX_FRAMES_PER_FILE; fifoDepth = JFRAU_FIFO_SIZE; fifoSize = JFRAU_FIFO_SIZE; + fifoBufferHeaderSize= JFRAU_FILE_FRAME_HEADER_LENGTH; //footerOffset = Not applicable; break; default: @@ -1988,8 +1994,7 @@ void UDPStandardImplementation::startListening(){ } //write packet count to buffer - if(myDetectorType == EIGER) - (*((uint32_t*)(buffer[ithread]))) = (rc/onePacketSize); + (*((uint32_t*)(buffer[ithread]))) = (rc/onePacketSize); if(dataCompressionEnable) (*((uint32_t*)(buffer[ithread]))) = processListeningBuffer(ithread, carryonBufferSize, tempBuffer, rc); @@ -2037,7 +2042,7 @@ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int cSize, ch int receivedSize = 0; //carry over from previous buffer - if(cSize) memcpy(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS, temp, cSize); + if(cSize) memcpy(buffer[ithread] + fifoBufferHeaderSize, temp, cSize); if(!activated){ @@ -2059,14 +2064,14 @@ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int cSize, ch //copy dummy packets receivedSize = framestoclone*packetsPerFrame*onePacketSize; - memset(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS, 0xFF,receivedSize); + memset(buffer[ithread] + fifoBufferHeaderSize, 0xFF,receivedSize); //set fnum, pnum and deactivatedpacket label eiger_packet_header_t* header; eiger_packet_footer_t* footer; int pnum=0; //loop by each packet - for(int offset=HEADER_SIZE_NUM_TOT_PACKETS; + for(int offset=fifoBufferHeaderSize; offsetReceiveDataOnly(buffer[ithread] + fifoBufferHeaderSize, lSize); + header = (jfrau_packet_header_t*)(buffer[ithread] + fifoBufferHeaderSize + iloop * (JFRAU_HEADER_LENGTH+JFRAU_ONE_DATA_SIZE)); + } + else{ + receivedSize = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + fifoBufferHeaderSize + cSize, (bufferSize * numberofJobsPerBuffer) - cSize); + //eiger returns 0 when header packet caught + while(receivedSize < onePacketSize && status != TRANSMITTING) + receivedSize = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + fifoBufferHeaderSize + cSize, (bufferSize * numberofJobsPerBuffer) - cSize); - if(status != TRANSMITTING) - receivedSize = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS + cSize, (bufferSize * numberofJobsPerBuffer) - cSize); - //eiger returns 0 when header packet caught - while(receivedSize < onePacketSize && status != TRANSMITTING) - receivedSize = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS + cSize, (bufferSize * numberofJobsPerBuffer) - cSize); + } + } totalListeningPacketCount[ithread] += (receivedSize/onePacketSize); @@ -2105,14 +2120,14 @@ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int cSize, ch if(myDetectorType == JUNGFRAU){ jfrau_packet_header_t* header; - for(int iloop=0;iloop<2;iloop++){ - header = (jfrau_packet_header_t*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS + iloop * (JFRAU_HEADER_LENGTH+JFRAU_ONE_DATA_SIZE)); - cprintf(RED,"[%d]: packetnumber:%x\n",iloop, (*( (uint8_t*) header->packetNumber))); - cprintf(RED," : framenumber :%x\n", (*( (uint32_t*) header->frameNumber))&0xffffff); + for(int iloop=0;iloop<128;iloop++){ + header = (jfrau_packet_header_t*)(buffer[ithread] + fifoBufferHeaderSize + iloop * (JFRAU_HEADER_LENGTH+JFRAU_ONE_DATA_SIZE)); + cprintf(RED,"[%d]: packetnumber:%d\n",iloop, (*( (uint8_t*) header->packetNumber))); + cprintf(RED," : framenumber :%d\n", (*( (uint32_t*) header->frameNumber))&frameIndexMask); } }else if(myDetectorType == EIGER){ - eiger_packet_header_t* header = (eiger_packet_header_t*) (buffer[ithread]+HEADER_SIZE_NUM_TOT_PACKETS); - eiger_packet_footer_t* footer = (eiger_packet_footer_t*)(buffer[ithread] + footerOffset + HEADER_SIZE_NUM_TOT_PACKETS); + eiger_packet_header_t* header = (eiger_packet_header_t*) (buffer[ithread]+fifoBufferHeaderSize); + eiger_packet_footer_t* footer = (eiger_packet_footer_t*)(buffer[ithread] + footerOffset + fifoBufferHeaderSize); cprintf(GREEN,"thread:%d footeroffset:%dsubframenum:%d oldpacketnum:%d new pnum:%d new fnum:%d\n", ithread,footerOffset, (*( (unsigned int*) header->subFrameNumber)), @@ -2143,15 +2158,15 @@ void UDPStandardImplementation::startFrameIndices(int ithread){ startFrameIndex = 0; //frame number always resets break; case JUNGFRAU: - header = (jfrau_packet_header_t*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS); - startFrameIndex = (*( (uint32_t*) header->frameNumber))&0xffffff; + header = (jfrau_packet_header_t*)(buffer[ithread] + fifoBufferHeaderSize); + startFrameIndex = (*( (uint32_t*) header->frameNumber))&frameIndexMask; break; default: if(shortFrameEnable < 0){ - startFrameIndex = (((((uint32_t)(*((uint32_t*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS))))+1) + startFrameIndex = (((((uint32_t)(*((uint32_t*)(buffer[ithread] + fifoBufferHeaderSize))))+1) & (frameIndexMask)) >> frameIndexOffset); }else{ - startFrameIndex = ((((uint32_t)(*((uint32_t*)(buffer[ithread]+HEADER_SIZE_NUM_TOT_PACKETS)))) + startFrameIndex = ((((uint32_t)(*((uint32_t*)(buffer[ithread]+fifoBufferHeaderSize)))) & (frameIndexMask)) >> frameIndexOffset); } break; @@ -2302,7 +2317,7 @@ uint32_t UDPStandardImplementation::processListeningBuffer(int ithread, int &cSi case PROPIX: //for short frames, 1 packet/frame, so split frames is not a topic if(shortFrameEnable == -1){ - lastPacketOffset = (((packetCount - 1) * onePacketSize) + HEADER_SIZE_NUM_TOT_PACKETS); + lastPacketOffset = (((packetCount - 1) * onePacketSize) + fifoBufferHeaderSize); #ifdef DEBUG4 cprintf(BLUE, "Listening_Thread %d: Last Packet Offset:%d\n",ithread, lastPacketOffset); #endif @@ -2319,17 +2334,17 @@ uint32_t UDPStandardImplementation::processListeningBuffer(int ithread, int &cSi } } #ifdef DEBUG4 - cprintf(BLUE, "Listening_Thread %d: First Header:%d\n", (((((uint32_t)(*((uint32_t*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS))))+1) + cprintf(BLUE, "Listening_Thread %d: First Header:%d\n", (((((uint32_t)(*((uint32_t*)(buffer[ithread] + fifoBufferHeaderSize))))+1) & (frameIndexMask)) >> frameIndexOffset)); #endif break; case MOENCH: - lastPacketOffset = (((packetCount - 1) * onePacketSize) + HEADER_SIZE_NUM_TOT_PACKETS); + lastPacketOffset = (((packetCount - 1) * onePacketSize) + fifoBufferHeaderSize); #ifdef DEBUG4 cprintf(BLUE, "Listening_Thread %d: First Header:%d\t First Packet:%d\t Last Header:%d\t Last Packet:%d\tLast Packet Offset:%d\n", - (((((uint32_t)(*((uint32_t*)(buffer[ithread]+HEADER_SIZE_NUM_TOT_PACKETS))))) & (frameIndexMask)) >> frameIndexOffset), - ((((uint32_t)(*((uint32_t*)(buffer[ithread]+HEADER_SIZE_NUM_TOT_PACKETS))))) & (packetIndexMask)), + (((((uint32_t)(*((uint32_t*)(buffer[ithread]+fifoBufferHeaderSize))))) & (frameIndexMask)) >> frameIndexOffset), + ((((uint32_t)(*((uint32_t*)(buffer[ithread]+fifoBufferHeaderSize))))) & (packetIndexMask)), (((((uint32_t)(*((uint32_t*)(buffer[ithread]+lastpacketoffset))))) & (frameIndexMask)) >> frameIndexOffset), ((((uint32_t)(*((uint32_t*)(buffer[ithread]+lastpacketoffset))))) & (packetIndexMask)), lastPacketOffset); @@ -2357,33 +2372,33 @@ uint32_t UDPStandardImplementation::processListeningBuffer(int ithread, int &cSi case JUNGFRAU: - lastPacketOffset = (((packetCount - 1) * onePacketSize) + HEADER_SIZE_NUM_TOT_PACKETS); + lastPacketOffset = (((packetCount - 1) * onePacketSize) + fifoBufferHeaderSize); #ifdef DEBUG4 - header = (jfrau_packet_header_t*) (buffer[ithread]+HEADER_SIZE_NUM_TOT_PACKETS); + header = (jfrau_packet_header_t*) (buffer[ithread]+fifoBufferHeaderSize); cprintf(BLUE, "Listening_Thread: First Header:%d\t First Packet:%d\n", - (*( (uint32_t*) header->frameNumber))&0xffffff, + (*( (uint32_t*) header->frameNumber))&frameIndexMask, (*( (uint8_t*) header->packetNumber))); #endif header = (jfrau_packet_header_t*) (buffer[ithread]+lastPacketOffset); #ifdef DEBUG4 cprintf(BLUE, "Listening_Thread: Last Header:%du\t Last Packet:%d\n", - (*( (uint32_t*) header->frameNumber))&0xffffff, + (*( (uint32_t*) header->frameNumber))&frameIndexMask, (*( (uint8_t*) header->packetNumber))); #endif //jungfrau last packet value is 0, so find the last packet and store the others in a temp storage if((*( (uint8_t*) header->packetNumber))){ //cprintf(RED,"entering missing packet zone\n"); - lastFrameHeader64 = (*( (uint32_t*) header->frameNumber))&0xffffff; + lastFrameHeader64 = (*( (uint32_t*) header->frameNumber))&frameIndexMask; cSize += onePacketSize; lastPacketOffset -= onePacketSize; --packetCount; - while (lastFrameHeader64 == ((*( (uint32_t*) header->frameNumber))&0xffffff)){ + while (lastFrameHeader64 == ((*( (uint32_t*) header->frameNumber))&frameIndexMask)){ cSize += onePacketSize; lastPacketOffset -= onePacketSize; header = (jfrau_packet_header_t*) (buffer[ithread]+lastPacketOffset); #ifdef DEBUG4 cprintf(RED,"new header:%d new packet:%d\n", - (*( (uint32_t*) header->frameNumber))&0xffffff, + (*( (uint32_t*) header->frameNumber))&frameIndexMask, (*( (uint8_t*) header->packetNumber))); #endif --packetCount; @@ -2713,7 +2728,7 @@ void UDPStandardImplementation::handleWithoutDataCompression(int ithread, char* uint64_t tempframenumber; uint32_t pnum; uint32_t snum; - if(getFrameandPacketNumber(ithread, wbuffer + HEADER_SIZE_NUM_TOT_PACKETS,tempframenumber,pnum,snum) == FAIL){ + if(getFrameandPacketNumber(ithread, wbuffer + fifoBufferHeaderSize,tempframenumber,pnum,snum) == FAIL){ //error in frame number sent by fpga while(!fifoFree[ithread]->push(wbuffer)); @@ -2732,7 +2747,7 @@ void UDPStandardImplementation::handleWithoutDataCompression(int ithread, char* //callback to write data if (cbAction < DO_EVERYTHING) - rawDataReadyCallBack((int)currentFrameNumber[ithread], wbuffer + HEADER_SIZE_NUM_TOT_PACKETS, npackets * onePacketSize, + rawDataReadyCallBack((int)currentFrameNumber[ithread], wbuffer + fifoBufferHeaderSize, npackets * onePacketSize, sfilefd[ithread], latestData[ithread],pRawDataReady);//know which thread from sfilefd @@ -2778,7 +2793,7 @@ void UDPStandardImplementation::writeFileWithoutCompression(int ithread, char* w //if write enabled if((fileWriteEnable) && (sfilefd[ithread])){ if(numpackets){ - int offset = HEADER_SIZE_NUM_TOT_PACKETS; + int offset = fifoBufferHeaderSize; uint64_t nextFileFrameNumber; int packetsWritten = 0; //if(ithread) cout<<"numpackets:"<push(wbuffer)); return; @@ -2942,7 +2957,7 @@ void UDPStandardImplementation::copyFrameToGui(int ithread, char* buffer, uint32 //copy date guiNumPackets[ithread] = numpackets; strcpy(guiFileName[ithread],completeFileName[ithread]); - memcpy(latestData[ithread],buffer+ HEADER_SIZE_NUM_TOT_PACKETS , numpackets*onePacketSize); + memcpy(latestData[ithread],buffer+ fifoBufferHeaderSize , numpackets*onePacketSize); //let it know its got data sem_post(&dataCallbackWriterSemaphore[ithread]); @@ -2970,7 +2985,7 @@ void UDPStandardImplementation::handleDataCompression(int ithread, char* wbuffer uint64_t tempframenumber=-1; uint32_t pnum; uint32_t snum; - if(getFrameandPacketNumber(ithread, wbuffer + HEADER_SIZE_NUM_TOT_PACKETS, tempframenumber,pnum,snum) == FAIL){ + if(getFrameandPacketNumber(ithread, wbuffer + fifoBufferHeaderSize, tempframenumber,pnum,snum) == FAIL){ //error in frame number sent by fpga while(!fifoFree[ithread]->push(wbuffer)); return; @@ -2988,7 +3003,7 @@ void UDPStandardImplementation::handleDataCompression(int ithread, char* wbuffer //variable definitions char* buff[2]={0,0}; //an array just to be compatible with copyframetogui - char* data = wbuffer+ HEADER_SIZE_NUM_TOT_PACKETS; //data pointer to the next memory to be analysed + char* data = wbuffer+ fifoBufferHeaderSize; //data pointer to the next memory to be analysed int ndata; //size of data returned uint32_t np; //remaining number of packets returned uint32_t npackets = (uint32_t)(*((uint32_t*)wbuffer)); //number of total packets @@ -3089,7 +3104,7 @@ void UDPStandardImplementation::handleDataCompression(int ithread, char* wbuffer remainingsize -= ((buff[0] + ndata) - data); data = buff[0] + ndata; - if(data > (wbuffer + HEADER_SIZE_NUM_TOT_PACKETS + npackets * onePacketSize) ) + if(data > (wbuffer + fifoBufferHeaderSize + npackets * onePacketSize) ) cprintf(BG_RED,"Writing_Thread %d: Error: Compression data goes out of bounds!\n", ithread); } From de53e480786062868cfdb85d962434b763c64132 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Thu, 27 Oct 2016 08:38:28 +0200 Subject: [PATCH 294/474] somewhere --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index bb64f86f9..9134788dd 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -2099,8 +2099,7 @@ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int cSize, ch if(myDetectorType == JUNGFRAU){ jfrau_packet_header_t* header; int pcount = packetsPerFrame-1; - lSize = JFRAU_HEADER_LENGTH; - receivedSize = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + fifoBufferHeaderSize, lSize); + receivedSize = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + fifoBufferHeaderSize, JFRAU_HEADER_LENGTH); header = (jfrau_packet_header_t*)(buffer[ithread] + fifoBufferHeaderSize + iloop * (JFRAU_HEADER_LENGTH+JFRAU_ONE_DATA_SIZE)); } else{ From c2c80c6bf694ca5f50bf8620602acc155fcf6fa4 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Thu, 27 Oct 2016 08:50:44 +0200 Subject: [PATCH 295/474] root receiver crashing bug resolved --- .../src/UDPStandardImplementation.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 433e777ef..03754d0f8 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1402,12 +1402,14 @@ void UDPStandardImplementation::setThreadPriorities(){ break; } } - for(int i = 0; i < numberofDataCallbackThreads; ++i){ - if(rights) - if (pthread_setschedparam(dataCallbackThreads[i], SCHED_RR, &datacallback_param) == EPERM){ - rights = false; - break; - } + if(dataStreamEnable){ + for(int i = 0; i < numberofDataCallbackThreads; ++i){ + if(rights) + if (pthread_setschedparam(dataCallbackThreads[i], SCHED_RR, &datacallback_param) == EPERM){ + rights = false; + break; + } + } } if (pthread_setschedparam(pthread_self(),5 , &tcp_param) == EPERM) rights = false; From e908beb38a151f9d177de7d844fd918ab17a0825 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Thu, 27 Oct 2016 09:17:44 +0200 Subject: [PATCH 296/474] 9m try shutdown of client socket before close --- slsReceiverSoftware/include/genericSocket.h | 1 + 1 file changed, 1 insertion(+) diff --git a/slsReceiverSoftware/include/genericSocket.h b/slsReceiverSoftware/include/genericSocket.h index 91debdec1..07f1e30e2 100644 --- a/slsReceiverSoftware/include/genericSocket.h +++ b/slsReceiverSoftware/include/genericSocket.h @@ -446,6 +446,7 @@ enum communicationProtocol{ close(file_des); } else { + ShutDownSocket(); close(socketDescriptor); socketDescriptor=-1; } From 434fa863d0ab39803610279d76f0984c160726c3 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Thu, 27 Oct 2016 09:48:04 +0200 Subject: [PATCH 297/474] shutdown bug --- slsReceiverSoftware/include/genericSocket.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/slsReceiverSoftware/include/genericSocket.h b/slsReceiverSoftware/include/genericSocket.h index 07f1e30e2..0fad365fe 100644 --- a/slsReceiverSoftware/include/genericSocket.h +++ b/slsReceiverSoftware/include/genericSocket.h @@ -446,7 +446,7 @@ enum communicationProtocol{ close(file_des); } else { - ShutDownSocket(); + while(!shutdown(socketDescriptor, SHUT_RDWR)); close(socketDescriptor); socketDescriptor=-1; } From a1639a9a72bd64722d7b2e944547c93e6743a502 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Thu, 27 Oct 2016 11:32:30 +0200 Subject: [PATCH 298/474] somehwere in btween --- .../src/UDPStandardImplementation.cpp | 46 +++++++++++++++++-- 1 file changed, 43 insertions(+), 3 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 9134788dd..9d2b70db9 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -2097,10 +2097,50 @@ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int cSize, ch if(status != TRANSMITTING){ if(myDetectorType == JUNGFRAU){ + jfrau_packet_header_t* header; - int pcount = packetsPerFrame-1; - receivedSize = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + fifoBufferHeaderSize, JFRAU_HEADER_LENGTH); - header = (jfrau_packet_header_t*)(buffer[ithread] + fifoBufferHeaderSize + iloop * (JFRAU_HEADER_LENGTH+JFRAU_ONE_DATA_SIZE)); + int offset = fifoBufferHeaderSize; + int pnum = packetsPerFrame-1; + int currentpnum; + + //read first packet header + receivedSize = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + offset, JFRAU_HEADER_LENGTH); + if(!receivedSize) return 0; + header = (jfrau_packet_header_t*)(buffer[ithread] + offset); + currentpnum = (*( (uint8_t*) header->packetNumber)); + + while(true){ + + //correct packet + if(currentpnum == pnum){ + receivedSize = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + offset, oneDataSize); + if(!receivedSize) return 0; + offset+=oneDataSize; + + //got a complete frame + if(pnum == 0) + break; + pnum --; + } + + //wrong packet + else{ + pnum = packetsPerFrame-1; + offset = fifoBufferHeaderSize; + //find the start of next image + while(currentpnum != (packetsPerFrame-1)){ + receivedSize = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + offset, oneDataSize); + if(!receivedSize) return 0; + receivedSize = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + offset, JFRAU_HEADER_LENGTH); + if(!receivedSize) return 0; + header = (jfrau_packet_header_t*)(buffer[ithread] + offset); + currentpnum = (*( (uint8_t*) header->packetNumber)); + } + + } + }//----- got a whole frame ------- + + receivedSize = oneDataSize * packetsPerFrame; } else{ receivedSize = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + fifoBufferHeaderSize + cSize, (bufferSize * numberofJobsPerBuffer) - cSize); From ac87ae3d5ba0373fa8f14a3f94e91aabaf3cfd5c Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Mon, 31 Oct 2016 12:27:54 +0100 Subject: [PATCH 299/474] some changes, almost done --- .../include/UDPStandardImplementation.h | 10 +++ .../src/UDPStandardImplementation.cpp | 83 ++++++++++++++++++- 2 files changed, 89 insertions(+), 4 deletions(-) diff --git a/slsReceiverSoftware/include/UDPStandardImplementation.h b/slsReceiverSoftware/include/UDPStandardImplementation.h index cc69e0da0..2a8a553c7 100644 --- a/slsReceiverSoftware/include/UDPStandardImplementation.h +++ b/slsReceiverSoftware/include/UDPStandardImplementation.h @@ -463,6 +463,16 @@ private: */ void handleWithoutDataCompression(int ithread, char* wbuffer,uint32_t npackets); + /** + * Called by processWritingBuffer for jungfrau + * writes to dummy file, doesnt need to read packet numbers + * Copies data for gui display and frees addresses popped from FIFOs + * @param ithread writing thread index + * @param wbuffer writing buffer popped out from FIFO + * @param npackets number of packets + */ + void handleWithoutMissingPackets(int ithread, char* wbuffer,uint32_t npackets); + /** * Calle by handleWithoutDataCompression * Creating headers Writing to file without compression diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 1f726bb7e..08627ffc8 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -2099,6 +2099,7 @@ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int cSize, ch int offset = fifoBufferHeaderSize; int pnum = packetsPerFrame-1; int currentpnum; + int currentfnum=-1; //read first packet header receivedSize = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + offset, JFRAU_HEADER_LENGTH); @@ -2110,6 +2111,9 @@ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int cSize, ch //correct packet if(currentpnum == pnum){ + //complete frame, get frame number while u can + if(pnum == 0) + (*((uint32_t*)(buffer[ithread]+8))) = (*( (uint32_t*) header->frameNumber))&frameIndexMask; receivedSize = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + offset, oneDataSize); if(!receivedSize) return 0; offset+=oneDataSize; @@ -2133,7 +2137,6 @@ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int cSize, ch header = (jfrau_packet_header_t*)(buffer[ithread] + offset); currentpnum = (*( (uint8_t*) header->packetNumber)); } - } }//----- got a whole frame ------- @@ -2516,8 +2519,11 @@ void UDPStandardImplementation::startWriting(){ + //jungfrau + if(myDetectorType == JUNGFRAU) + handleWithoutMissingPackets(ithread, wbuf, numPackets); //normal - if(!dataCompressionEnable) + else if(!dataCompressionEnable) handleWithoutDataCompression(ithread, wbuf, numPackets); //compression @@ -2760,7 +2766,6 @@ void UDPStandardImplementation::stopWriting(int ithread, char* wbuffer){ void UDPStandardImplementation::handleWithoutDataCompression(int ithread, char* wbuffer, uint32_t npackets){ FILE_LOG(logDEBUG) << __AT__ << " called"; - //get current frame number uint64_t tempframenumber; uint32_t pnum; @@ -2772,13 +2777,13 @@ void UDPStandardImplementation::handleWithoutDataCompression(int ithread, char* return; } + //callback to write data if (cbAction < DO_EVERYTHING) rawDataReadyCallBack((int)tempframenumber, wbuffer + fifoBufferHeaderSize, npackets * onePacketSize, sfilefd[ithread], latestData[ithread],pRawDataReady);//know which thread from sfilefd - //write to file if enabled and update write parameters if(npackets > 0) writeFileWithoutCompression(ithread, wbuffer, npackets); @@ -2814,6 +2819,76 @@ void UDPStandardImplementation::handleWithoutDataCompression(int ithread, char* +void UDPStandardImplementation::handleWithoutMissingPackets(int ithread, char* wbuffer, uint32_t npackets){ + FILE_LOG(logDEBUG) << __AT__ << " called"; + + //get current frame number + uint64_t tempframenumber; + tempframenumber = (*((uint32_t*)(buffer[ithread]+8))); + cout<<"handling: frame number:"< 0){ + if((fileWriteEnable) && (sfilefd[ithread])){ + if(tempframenumber >= maxFramesPerFile) + createNewFile(ithread); + fwrite(wbuffer, 1, oneDataSize*packetsPerFrame+fifoBufferHeaderSize, sfilefd[ithread]); + } + + totalPacketsInFile[ithread] += npackets; + totalWritingPacketCount[ithread] += npackets; + lastFrameNumberInFile[ithread] = tempframenumber; + currentFrameNumber[ithread] = tempframenumber; + + if(numberofWriterThreads > 1) + pthread_mutex_lock(&writeMutex); + packetsCaught += npackets; + totalPacketsCaught += npackets; + if((currentFrameNumber[ithread] - startAcquisitionIndex) > acquisitionIndex) + acquisitionIndex = currentFrameNumber[ithread] - startAcquisitionIndex; + if((currentFrameNumber[ithread] - startFrameIndex) > frameIndex[ithread]) + frameIndex[ithread] = currentFrameNumber[ithread] - startFrameIndex; + + if(numberofWriterThreads > 1) + pthread_mutex_unlock(&writeMutex); + + } +#ifdef DEBUG4 + cprintf(GREEN,"Writing_Thread: Writing done\nGoing to copy frame\n"); +#endif + + + //copy frame for gui + //if(npackets >= (packetsPerFrame/numberofListeningThreads)) + if(dataStreamEnable && npackets > 0) + copyFrameToGui(ithread, wbuffer,npackets); +#ifdef DEBUG4 + cprintf(GREEN,"Writing_Thread: Copied frame\n"); +#endif + + + //free fifo addresses + int listenfifoThread = ithread; + if(dataCompressionEnable) + listenfifoThread = 0; + while(!fifoFree[listenfifoThread]->push(wbuffer)); +#ifdef EVERYFIFODEBUG + if(fifoFree[listenfifoThread]->getSemValue()<100) + cprintf(GREEN,"FifoFree[%d]: value:%d, push 0x%x\n",listenfifoThread,fifoFree[listenfifoThread]->getSemValue(),(void*)(wbuffer)); +#endif +#ifdef DEBUG5 + cprintf(GREEN,"Writing_Thread %d: Freed buffer, pushed into fifofree %p for listener %d \n",listenfifoThread, (void*)(wbuffer), listenfifoThread); +#endif + +} + + + void UDPStandardImplementation::writeFileWithoutCompression(int ithread, char* wbuffer,uint32_t numpackets){ FILE_LOG(logDEBUG) << __AT__ << " called"; From 873d536729c0034a5f0315fca64b9b5dff2249c9 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Mon, 31 Oct 2016 14:13:00 +0100 Subject: [PATCH 300/474] trying --- slsReceiverSoftware/include/genericSocket.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/slsReceiverSoftware/include/genericSocket.h b/slsReceiverSoftware/include/genericSocket.h index b4a5cb712..1191fa5b2 100644 --- a/slsReceiverSoftware/include/genericSocket.h +++ b/slsReceiverSoftware/include/genericSocket.h @@ -616,10 +616,14 @@ enum communicationProtocol{ /*int k = 0;*/ while(length>0){ - if(lengthpacket_size) ? packet_size:length; //works for eiger to get packets to discard image header packets + } nsent = recvfrom(socketDescriptor,(char*)buf+total_sent,nsending, 0, (struct sockaddr *) &clientAddress, &clientAddress_length); if(nsent != nsending){ //if((nsent != nsending)){ && (nsent < packet_size)){ if(nsent && (nsent != header_packet_size) && (nsent != -1)) From e3455fe1ff70882367842c8fb9fae7d0ea170bc4 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Mon, 31 Oct 2016 14:24:23 +0100 Subject: [PATCH 301/474] trying --- slsReceiverSoftware/include/genericSocket.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/slsReceiverSoftware/include/genericSocket.h b/slsReceiverSoftware/include/genericSocket.h index 1191fa5b2..dc3fe3eee 100644 --- a/slsReceiverSoftware/include/genericSocket.h +++ b/slsReceiverSoftware/include/genericSocket.h @@ -618,13 +618,14 @@ enum communicationProtocol{ while(length>0){ if(lengthpacket_size) ? packet_size:length; //works for eiger to get packets to discard image header packets } nsent = recvfrom(socketDescriptor,(char*)buf+total_sent,nsending, 0, (struct sockaddr *) &clientAddress, &clientAddress_length); + cprintf(BLUE,"read %d\n",nsending); if(nsent != nsending){ //if((nsent != nsending)){ && (nsent < packet_size)){ if(nsent && (nsent != header_packet_size) && (nsent != -1)) cprintf(RED,"Incomplete Packet size %d\n",nsent); From cc2346be6725699d689bc5792ae41bde3cb90529 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Mon, 31 Oct 2016 14:28:15 +0100 Subject: [PATCH 302/474] trying --- slsReceiverSoftware/include/genericSocket.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/slsReceiverSoftware/include/genericSocket.h b/slsReceiverSoftware/include/genericSocket.h index dc3fe3eee..0a664aecd 100644 --- a/slsReceiverSoftware/include/genericSocket.h +++ b/slsReceiverSoftware/include/genericSocket.h @@ -621,7 +621,7 @@ enum communicationProtocol{ cprintf(BLUE,"will read %d\n",nsending); } else{ - cprintf(BG_RED,"should not have been here length:%d packet_size:%d !!\n"); + cprintf(BG_RED,"should not have been here length:%d packet_size:%d !!\n",length, packet_size); nsending = (length>packet_size) ? packet_size:length; //works for eiger to get packets to discard image header packets } nsent = recvfrom(socketDescriptor,(char*)buf+total_sent,nsending, 0, (struct sockaddr *) &clientAddress, &clientAddress_length); From 6a843b28d1c54725f5d15b9527613f5a824d980d Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Mon, 31 Oct 2016 14:30:48 +0100 Subject: [PATCH 303/474] trying --- slsReceiverSoftware/include/genericSocket.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/slsReceiverSoftware/include/genericSocket.h b/slsReceiverSoftware/include/genericSocket.h index 0a664aecd..ba4f559d6 100644 --- a/slsReceiverSoftware/include/genericSocket.h +++ b/slsReceiverSoftware/include/genericSocket.h @@ -584,7 +584,7 @@ enum communicationProtocol{ int ReceiveDataOnly(void* buf,int length=0){ if (buf==NULL) return -1; - + cprintf(RED,"length:%d\n",length); total_sent=0; From 63d9e3ca5f790adee63d31ce098cb304ec3c1501 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Mon, 31 Oct 2016 14:34:47 +0100 Subject: [PATCH 304/474] trying --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 08627ffc8..d53694126 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -826,7 +826,7 @@ int UDPStandardImplementation::setDetectorType(const detectorType d){ case JUNGFRAU: packetsPerFrame = JFRAU_PACKETS_PER_FRAME; onePacketSize = JFRAU_ONE_PACKET_SIZE; - oneDataSize = JFRAU_DATA_BYTES; + oneDataSize = JFRAU_ONE_DATA_SIZE; bufferSize = JFRAU_BUFFER_SIZE; frameIndexMask = JFRAU_FRAME_INDEX_MASK; frameIndexOffset = JFRAU_FRAME_INDEX_OFFSET; @@ -2142,7 +2142,7 @@ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int cSize, ch receivedSize = oneDataSize * packetsPerFrame; } - else{ + else{cprintf(BG_RED,"for only eiger or other dets. should not be here!!\n"); receivedSize = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + fifoBufferHeaderSize + cSize, (bufferSize * numberofJobsPerBuffer) - cSize); //eiger returns 0 when header packet caught while(receivedSize < onePacketSize && status != TRANSMITTING) From e030a79aba17bebd197415d3a109b944b57eced7 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Mon, 31 Oct 2016 14:36:13 +0100 Subject: [PATCH 305/474] trying --- slsReceiverSoftware/include/genericSocket.h | 10 ++-------- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 2 +- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/slsReceiverSoftware/include/genericSocket.h b/slsReceiverSoftware/include/genericSocket.h index ba4f559d6..c8bfdaa2b 100644 --- a/slsReceiverSoftware/include/genericSocket.h +++ b/slsReceiverSoftware/include/genericSocket.h @@ -584,7 +584,6 @@ enum communicationProtocol{ int ReceiveDataOnly(void* buf,int length=0){ if (buf==NULL) return -1; - cprintf(RED,"length:%d\n",length); total_sent=0; @@ -616,16 +615,11 @@ enum communicationProtocol{ /*int k = 0;*/ while(length>0){ - if(lengthpacket_size) ? packet_size:length; //works for eiger to get packets to discard image header packets - } nsent = recvfrom(socketDescriptor,(char*)buf+total_sent,nsending, 0, (struct sockaddr *) &clientAddress, &clientAddress_length); - cprintf(BLUE,"read %d\n",nsending); if(nsent != nsending){ //if((nsent != nsending)){ && (nsent < packet_size)){ if(nsent && (nsent != header_packet_size) && (nsent != -1)) cprintf(RED,"Incomplete Packet size %d\n",nsent); diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index d53694126..d6d912efc 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -2142,7 +2142,7 @@ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int cSize, ch receivedSize = oneDataSize * packetsPerFrame; } - else{cprintf(BG_RED,"for only eiger or other dets. should not be here!!\n"); + else{ receivedSize = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + fifoBufferHeaderSize + cSize, (bufferSize * numberofJobsPerBuffer) - cSize); //eiger returns 0 when header packet caught while(receivedSize < onePacketSize && status != TRANSMITTING) From 25e010a3d8b83253e09cca0a3743bf9b89cf686b Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Mon, 31 Oct 2016 14:37:40 +0100 Subject: [PATCH 306/474] trying --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index d6d912efc..580a0c093 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -2106,14 +2106,17 @@ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int cSize, ch if(!receivedSize) return 0; header = (jfrau_packet_header_t*)(buffer[ithread] + offset); currentpnum = (*( (uint8_t*) header->packetNumber)); + cout<<"currentpnum:"<frameNumber))&frameIndexMask; + cout<<"current fnum:"<<(*((uint32_t*)(buffer[ithread]+8)))<ReceiveDataOnly(buffer[ithread] + offset, oneDataSize); if(!receivedSize) return 0; offset+=oneDataSize; @@ -2136,6 +2139,7 @@ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int cSize, ch if(!receivedSize) return 0; header = (jfrau_packet_header_t*)(buffer[ithread] + offset); currentpnum = (*( (uint8_t*) header->packetNumber)); + cout<<"currentpnum:"< Date: Mon, 31 Oct 2016 14:41:12 +0100 Subject: [PATCH 307/474] trying --- .../src/UDPStandardImplementation.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 580a0c093..1a47b100f 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -2106,12 +2106,13 @@ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int cSize, ch if(!receivedSize) return 0; header = (jfrau_packet_header_t*)(buffer[ithread] + offset); currentpnum = (*( (uint8_t*) header->packetNumber)); - cout<<"currentpnum:"<frameNumber))&frameIndexMask; @@ -2119,16 +2120,23 @@ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int cSize, ch } receivedSize = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + offset, oneDataSize); if(!receivedSize) return 0; + cout<<"got data for " << pnum << endl; offset+=oneDataSize; //got a complete frame if(pnum == 0) break; pnum --; + receivedSize = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + offset, JFRAU_HEADER_LENGTH); + if(!receivedSize) return 0; + header = (jfrau_packet_header_t*)(buffer[ithread] + offset); + currentpnum = (*( (uint8_t*) header->packetNumber)); + cout<<"next currentpnum:"<packetNumber)); - cout<<"currentpnum:"< Date: Mon, 31 Oct 2016 14:45:19 +0100 Subject: [PATCH 308/474] trying --- slsReceiverSoftware/include/genericSocket.h | 1 + slsReceiverSoftware/src/UDPStandardImplementation.cpp | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/slsReceiverSoftware/include/genericSocket.h b/slsReceiverSoftware/include/genericSocket.h index c8bfdaa2b..c0e9b4b65 100644 --- a/slsReceiverSoftware/include/genericSocket.h +++ b/slsReceiverSoftware/include/genericSocket.h @@ -620,6 +620,7 @@ enum communicationProtocol{ else nsending = (length>packet_size) ? packet_size:length; //works for eiger to get packets to discard image header packets nsent = recvfrom(socketDescriptor,(char*)buf+total_sent,nsending, 0, (struct sockaddr *) &clientAddress, &clientAddress_length); + cout<<"nsent:"<frameNumber))&frameIndexMask; cout<<"current fnum:"<<(*((uint32_t*)(buffer[ithread]+8)))<ReceiveDataOnly(buffer[ithread] + offset, oneDataSize); if(!receivedSize) return 0; cout<<"got data for " << pnum << endl; offset+=oneDataSize; - + cout<<"offset now at:" << offset << endl; //got a complete frame if(pnum == 0) break; pnum --; + receivedSize = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + offset, JFRAU_HEADER_LENGTH); if(!receivedSize) return 0; header = (jfrau_packet_header_t*)(buffer[ithread] + offset); From 8f318f19ff2abcaca9b185fd4bcd3ba3f0bd3259 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Mon, 31 Oct 2016 14:48:50 +0100 Subject: [PATCH 309/474] trying --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 980f12b5f..8b8572895 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -2106,6 +2106,7 @@ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int cSize, ch if(!receivedSize) return 0; header = (jfrau_packet_header_t*)(buffer[ithread] + offset); currentpnum = (*( (uint8_t*) header->packetNumber)); + cout<<"1 current fnum:"<< (*( (uint32_t*) header->frameNumber))&frameIndexMask <packetNumber)); cout<<"next currentpnum:"<frameNumber))&frameIndexMask <packetNumber)); cout<<"trying to find currentpnum:"<frameNumber))&frameIndexMask < Date: Mon, 31 Oct 2016 14:49:39 +0100 Subject: [PATCH 310/474] trying --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 8b8572895..7e34a91e4 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -2106,7 +2106,7 @@ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int cSize, ch if(!receivedSize) return 0; header = (jfrau_packet_header_t*)(buffer[ithread] + offset); currentpnum = (*( (uint8_t*) header->packetNumber)); - cout<<"1 current fnum:"<< (*( (uint32_t*) header->frameNumber))&frameIndexMask <frameNumber))&frameIndexMask) <packetNumber)); cout<<"next currentpnum:"<frameNumber))&frameIndexMask <frameNumber))&frameIndexMask) <packetNumber)); cout<<"trying to find currentpnum:"<frameNumber))&frameIndexMask <frameNumber))&frameIndexMask) < Date: Mon, 31 Oct 2016 14:53:58 +0100 Subject: [PATCH 311/474] trying --- slsReceiverSoftware/include/genericSocket.h | 9 ++++++--- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 1 + 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/slsReceiverSoftware/include/genericSocket.h b/slsReceiverSoftware/include/genericSocket.h index c0e9b4b65..e4bddfe04 100644 --- a/slsReceiverSoftware/include/genericSocket.h +++ b/slsReceiverSoftware/include/genericSocket.h @@ -617,8 +617,10 @@ enum communicationProtocol{ while(length>0){ if(lengthpacket_size) ? packet_size:length; //works for eiger to get packets to discard image header packets + } nsent = recvfrom(socketDescriptor,(char*)buf+total_sent,nsending, 0, (struct sockaddr *) &clientAddress, &clientAddress_length); cout<<"nsent:"<ReceiveDataOnly(buffer[ithread] + fifoBufferHeaderSize + cSize, (bufferSize * numberofJobsPerBuffer) - cSize); //eiger returns 0 when header packet caught while(receivedSize < onePacketSize && status != TRANSMITTING) From f81ede500d7d8dffe109a7f25300898b62aca38f Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Mon, 31 Oct 2016 15:06:38 +0100 Subject: [PATCH 312/474] trying --- slsReceiverSoftware/include/genericSocket.h | 6 +++--- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 5 +++++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/slsReceiverSoftware/include/genericSocket.h b/slsReceiverSoftware/include/genericSocket.h index e4bddfe04..2bff4a583 100644 --- a/slsReceiverSoftware/include/genericSocket.h +++ b/slsReceiverSoftware/include/genericSocket.h @@ -622,7 +622,7 @@ enum communicationProtocol{ nsending = (length>packet_size) ? packet_size:length; //works for eiger to get packets to discard image header packets } nsent = recvfrom(socketDescriptor,(char*)buf+total_sent,nsending, 0, (struct sockaddr *) &clientAddress, &clientAddress_length); - cout<<"nsent:"<ReceiveDataOnly(buffer[ithread] + offset, JFRAU_HEADER_LENGTH); if(!receivedSize) return 0; header = (jfrau_packet_header_t*)(buffer[ithread] + offset); @@ -2120,6 +2121,7 @@ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int cSize, ch cout<<"current fnum:"<<(*((uint32_t*)(buffer[ithread]+8)))<ReceiveDataOnly(buffer[ithread] + offset, oneDataSize); if(!receivedSize) return 0; cout<<"got data for " << pnum << endl; @@ -2130,6 +2132,7 @@ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int cSize, ch break; pnum --; + cout<<"going to read header " << JFRAU_HEADER_LENGTH <ReceiveDataOnly(buffer[ithread] + offset, JFRAU_HEADER_LENGTH); if(!receivedSize) return 0; header = (jfrau_packet_header_t*)(buffer[ithread] + offset); @@ -2145,8 +2148,10 @@ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int cSize, ch offset = fifoBufferHeaderSize; //find the start of next image while(currentpnum != (packetsPerFrame-1)){ + cout<<"going to read data " << oneDataSize <ReceiveDataOnly(buffer[ithread] + offset, oneDataSize); if(!receivedSize) return 0; + cout<<"going to read header " << JFRAU_HEADER_LENGTH <ReceiveDataOnly(buffer[ithread] + offset, JFRAU_HEADER_LENGTH); if(!receivedSize) return 0; header = (jfrau_packet_header_t*)(buffer[ithread] + offset); From d2a4483e489fbdf516f499c8ea2b1ec912333d28 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Mon, 31 Oct 2016 15:12:31 +0100 Subject: [PATCH 313/474] trying --- .../src/UDPStandardImplementation.cpp | 35 +++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index eddd850b7..7aa6de3fb 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -2101,6 +2101,36 @@ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int cSize, ch int currentpnum; int currentfnum=-1; + + + cout<<"going to read header " << JFRAU_HEADER_LENGTH <ReceiveDataOnly(buffer[ithread] + offset, JFRAU_HEADER_LENGTH); + cout<<"receivedsize:"<packetNumber)); + cout<<"1 current fnum:"<< ((*( (uint32_t*) header->frameNumber))&frameIndexMask) <ReceiveDataOnly(buffer[ithread] + offset, oneDataSize); + cout<<"receivedsize:"<ReceiveDataOnly(buffer[ithread] + offset, JFRAU_HEADER_LENGTH); + cout<<"receivedsize:"<packetNumber)); + cout<<"2 current fnum:"<< ((*( (uint32_t*) header->frameNumber))&frameIndexMask) <ReceiveDataOnly(buffer[ithread] + offset, JFRAU_HEADER_LENGTH); @@ -2137,13 +2167,14 @@ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int cSize, ch if(!receivedSize) return 0; header = (jfrau_packet_header_t*)(buffer[ithread] + offset); currentpnum = (*( (uint8_t*) header->packetNumber)); - cout<<"next currentpnum:"<frameNumber))&frameIndexMask) < Date: Mon, 31 Oct 2016 15:14:40 +0100 Subject: [PATCH 314/474] trying --- .../src/UDPStandardImplementation.cpp | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 7aa6de3fb..17cdb402c 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -2103,24 +2103,23 @@ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int cSize, ch - cout<<"going to read header " << JFRAU_HEADER_LENGTH <ReceiveDataOnly(buffer[ithread] + offset, JFRAU_HEADER_LENGTH); + cout<<"\ngoing to read header " << JFRAU_HEADER_LENGTH <ReceiveDataOnly(buffer[ithread], JFRAU_HEADER_LENGTH); cout<<"receivedsize:"<packetNumber)); cout<<"1 current fnum:"<< ((*( (uint32_t*) header->frameNumber))&frameIndexMask) <ReceiveDataOnly(buffer[ithread] + offset, oneDataSize); + cout<<"\ngoing to read data " << oneDataSize <ReceiveDataOnly(buffer[ithread], oneDataSize); cout<<"receivedsize:"<ReceiveDataOnly(buffer[ithread] + offset, JFRAU_HEADER_LENGTH); + cout<<"\ngoing to read header " << JFRAU_HEADER_LENGTH <ReceiveDataOnly(buffer[ithread], JFRAU_HEADER_LENGTH); cout<<"receivedsize:"<packetNumber)); cout<<"2 current fnum:"<< ((*( (uint32_t*) header->frameNumber))&frameIndexMask) < Date: Mon, 31 Oct 2016 15:22:27 +0100 Subject: [PATCH 315/474] trying --- slsReceiverSoftware/include/genericSocket.h | 45 +++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/slsReceiverSoftware/include/genericSocket.h b/slsReceiverSoftware/include/genericSocket.h index 2bff4a583..77b67b73e 100644 --- a/slsReceiverSoftware/include/genericSocket.h +++ b/slsReceiverSoftware/include/genericSocket.h @@ -83,6 +83,18 @@ using namespace std; #define DEFAULT_GUI_PORTNO 65000 #define DEFAULT_ZMQ_PORTNO 70001 + +typedef struct { + unsigned char emptyHeader[6]; + unsigned char reserved[4]; + unsigned char packetNumber[1]; + unsigned char frameNumber[3]; + unsigned char bunchid[8]; +} jfrau_packet_header_t; + + + + class genericSocket{ public: @@ -612,6 +624,39 @@ enum communicationProtocol{ //if length given, listens to length, else listens for packetsize till length is reached if(length){ + + jfrau_packet_header_t* header; + int currentpnum; + + cout<<"\ngoing to read header " << endl; + nsent = recvfrom(socketDescriptor,(char*)buf,22, 0, (struct sockaddr *) &clientAddress, &clientAddress_length); + cout<<"nsent:"<packetNumber)); + cout<<"1 current fnum:"<< ((*( (uint32_t*) header->frameNumber))&0xffffff) <packetNumber)); + cout<<"2 current fnum:"<< ((*( (uint32_t*) header->frameNumber))&0xffffff) <0){ From 966b513f8f1f7c5ca1b426ef98dc9dabefc02395 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Mon, 31 Oct 2016 15:24:52 +0100 Subject: [PATCH 316/474] trying --- .../src/UDPStandardImplementation.cpp | 28 ------------------- 1 file changed, 28 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 17cdb402c..4e659c176 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -2102,34 +2102,6 @@ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int cSize, ch int currentfnum=-1; - - cout<<"\ngoing to read header " << JFRAU_HEADER_LENGTH <ReceiveDataOnly(buffer[ithread], JFRAU_HEADER_LENGTH); - cout<<"receivedsize:"<packetNumber)); - cout<<"1 current fnum:"<< ((*( (uint32_t*) header->frameNumber))&frameIndexMask) <ReceiveDataOnly(buffer[ithread], oneDataSize); - cout<<"receivedsize:"<ReceiveDataOnly(buffer[ithread], JFRAU_HEADER_LENGTH); - cout<<"receivedsize:"<packetNumber)); - cout<<"2 current fnum:"<< ((*( (uint32_t*) header->frameNumber))&frameIndexMask) <ReceiveDataOnly(buffer[ithread] + offset, JFRAU_HEADER_LENGTH); From 21ccb211c19ac46ca8af564878c4d14dd48308ba Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Mon, 31 Oct 2016 15:29:40 +0100 Subject: [PATCH 317/474] trying --- slsReceiverSoftware/include/genericSocket.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/slsReceiverSoftware/include/genericSocket.h b/slsReceiverSoftware/include/genericSocket.h index 77b67b73e..16e21fe8c 100644 --- a/slsReceiverSoftware/include/genericSocket.h +++ b/slsReceiverSoftware/include/genericSocket.h @@ -90,7 +90,7 @@ typedef struct { unsigned char packetNumber[1]; unsigned char frameNumber[3]; unsigned char bunchid[8]; -} jfrau_packet_header_t; +} jfrau_packet_header_t1; @@ -625,13 +625,13 @@ enum communicationProtocol{ //if length given, listens to length, else listens for packetsize till length is reached if(length){ - jfrau_packet_header_t* header; + jfrau_packet_header_t1* header; int currentpnum; cout<<"\ngoing to read header " << endl; nsent = recvfrom(socketDescriptor,(char*)buf,22, 0, (struct sockaddr *) &clientAddress, &clientAddress_length); cout<<"nsent:"<packetNumber)); cout<<"1 current fnum:"<< ((*( (uint32_t*) header->frameNumber))&0xffffff) <packetNumber)); cout<<"2 current fnum:"<< ((*( (uint32_t*) header->frameNumber))&0xffffff) < Date: Mon, 31 Oct 2016 15:33:35 +0100 Subject: [PATCH 318/474] trying --- slsReceiverSoftware/include/genericSocket.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/slsReceiverSoftware/include/genericSocket.h b/slsReceiverSoftware/include/genericSocket.h index 16e21fe8c..e3404b30c 100644 --- a/slsReceiverSoftware/include/genericSocket.h +++ b/slsReceiverSoftware/include/genericSocket.h @@ -629,7 +629,7 @@ enum communicationProtocol{ int currentpnum; cout<<"\ngoing to read header " << endl; - nsent = recvfrom(socketDescriptor,(char*)buf,22, 0, (struct sockaddr *) &clientAddress, &clientAddress_length); + nsent = recv(socketDescriptor,(char*)buf,22, 0); cout<<"nsent:"<packetNumber)); @@ -637,12 +637,12 @@ enum communicationProtocol{ cout<<"1 currentpnum:"<packetNumber)); From 59ade286c200a46d58926ad75eb9b45c61914fe7 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Mon, 31 Oct 2016 16:04:46 +0100 Subject: [PATCH 319/474] trying --- slsReceiverSoftware/include/genericSocket.h | 53 +------------------ .../src/UDPStandardImplementation.cpp | 31 ++++------- 2 files changed, 11 insertions(+), 73 deletions(-) diff --git a/slsReceiverSoftware/include/genericSocket.h b/slsReceiverSoftware/include/genericSocket.h index e3404b30c..7c45765f3 100644 --- a/slsReceiverSoftware/include/genericSocket.h +++ b/slsReceiverSoftware/include/genericSocket.h @@ -84,16 +84,6 @@ using namespace std; #define DEFAULT_ZMQ_PORTNO 70001 -typedef struct { - unsigned char emptyHeader[6]; - unsigned char reserved[4]; - unsigned char packetNumber[1]; - unsigned char frameNumber[3]; - unsigned char bunchid[8]; -} jfrau_packet_header_t1; - - - class genericSocket{ @@ -625,49 +615,11 @@ enum communicationProtocol{ //if length given, listens to length, else listens for packetsize till length is reached if(length){ - jfrau_packet_header_t1* header; - int currentpnum; - - cout<<"\ngoing to read header " << endl; - nsent = recv(socketDescriptor,(char*)buf,22, 0); - cout<<"nsent:"<packetNumber)); - cout<<"1 current fnum:"<< ((*( (uint32_t*) header->frameNumber))&0xffffff) <packetNumber)); - cout<<"2 current fnum:"<< ((*( (uint32_t*) header->frameNumber))&0xffffff) <0){ - if(lengthpacket_size) ? packet_size:length; //works for eiger to get packets to discard image header packets - } - nsent = recvfrom(socketDescriptor,(char*)buf+total_sent,nsending, 0, (struct sockaddr *) &clientAddress, &clientAddress_length); - cprintf(BLUE,"read %d\n",nsent); + nsending = (length>packet_size) ? packet_size:length; + nsent = recvfrom(socketDescriptor,(char*)buf+total_sent,nsending, 0, (struct sockaddr *) &clientAddress, &clientAddress_length); if(nsent != nsending){ //if((nsent != nsending)){ && (nsent < packet_size)){ if(nsent && (nsent != header_packet_size) && (nsent != -1)) cprintf(RED,"Incomplete Packet size %d\n",nsent); @@ -679,7 +631,6 @@ enum communicationProtocol{ } //listens to only 1 packet else{ - cprintf(BG_RED,"should not be here, length is zero\n"); //normal nsending=packet_size; nsent = recvfrom(socketDescriptor,(char*)buf+total_sent,nsending, 0, (struct sockaddr *) &clientAddress, &clientAddress_length); diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 4e659c176..29d6562c1 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -2102,45 +2102,36 @@ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int cSize, ch int currentfnum=-1; - //read first packet header - cout<<"going to read header " << JFRAU_HEADER_LENGTH <ReceiveDataOnly(buffer[ithread] + offset, JFRAU_HEADER_LENGTH); + //read first packet + receivedSize = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + offset, onePacketSize); if(!receivedSize) return 0; header = (jfrau_packet_header_t*)(buffer[ithread] + offset); currentpnum = (*( (uint8_t*) header->packetNumber)); - cout<<"1 current fnum:"<< ((*( (uint32_t*) header->frameNumber))&frameIndexMask) <frameNumber))&frameIndexMask; cout<<"current fnum:"<<(*((uint32_t*)(buffer[ithread]+8)))<ReceiveDataOnly(buffer[ithread] + offset, oneDataSize); - if(!receivedSize) return 0; - cout<<"got data for " << pnum << endl; + + memcpy(buffer[ithread] + offset,buffer[ithread] + JFRAU_HEADER_LENGTH, oneDataSize); offset+=oneDataSize; - cout<<"offset now at:" << offset << endl; //got a complete frame if(pnum == 0) break; pnum --; - cout<<"going to read header " << JFRAU_HEADER_LENGTH <ReceiveDataOnly(buffer[ithread] + offset, JFRAU_HEADER_LENGTH); + receivedSize = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + offset, onePacketSize); if(!receivedSize) return 0; header = (jfrau_packet_header_t*)(buffer[ithread] + offset); currentpnum = (*( (uint8_t*) header->packetNumber)); - cout<<"offset:"<frameNumber))&frameIndexMask) <ReceiveDataOnly(buffer[ithread] + offset, oneDataSize); - if(!receivedSize) return 0; - cout<<"going to read header " << JFRAU_HEADER_LENGTH <ReceiveDataOnly(buffer[ithread] + offset, JFRAU_HEADER_LENGTH); + + receivedSize = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + offset, onePacketSize); if(!receivedSize) return 0; header = (jfrau_packet_header_t*)(buffer[ithread] + offset); currentpnum = (*( (uint8_t*) header->packetNumber)); cout<<"trying to find currentpnum:"<frameNumber))&frameIndexMask) < Date: Mon, 31 Oct 2016 16:08:49 +0100 Subject: [PATCH 320/474] trying --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 29d6562c1..591c55636 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -2701,14 +2701,14 @@ void UDPStandardImplementation::stopWriting(int ithread, char* wbuffer){ frameNumberInPreviousFile[ithread] = startFrameIndex-1; printf("\nThread:%d File:%s\n" - //"\ttotalpacketsinfile:%d\t" + "\ttotalpacketsinfile:%d\t" "Packets Lost:%d" - //"\tCurrentFrameNumber:%lld\tPreviousFrameNumber:%lld" + "\tCurrentFrameNumber:%lld\tPreviousFrameNumber:%lld" "\n", ithread,completeFileName[ithread], - //totalPacketsInFile[ithread], + totalPacketsInFile[ithread], ( ((int)(currentFrameNumber[ithread]-frameNumberInPreviousFile[ithread])*packetsPerFrame) - totalPacketsInFile[ithread]) - //,currentFrameNumber[ithread],frameNumberInPreviousFile[ithread] + ,currentFrameNumber[ithread],frameNumberInPreviousFile[ithread] ); } closeFile(ithread); From a2b8d9beb928d7edb4e0bd3389c2a04f834a844c Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Mon, 31 Oct 2016 16:12:11 +0100 Subject: [PATCH 321/474] trying --- .../src/UDPStandardImplementation.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 591c55636..7f96be772 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1991,7 +1991,10 @@ void UDPStandardImplementation::startListening(){ } //write packet count to buffer - (*((uint32_t*)(buffer[ithread]))) = (rc/onePacketSize); + if(myDetectorType == JUNGFRAU) + (*((uint32_t*)(buffer[ithread]))) = (rc/oneDataSize); + else + (*((uint32_t*)(buffer[ithread]))) = (rc/onePacketSize); if(dataCompressionEnable) (*((uint32_t*)(buffer[ithread]))) = processListeningBuffer(ithread, carryonBufferSize, tempBuffer, rc); @@ -2515,16 +2518,16 @@ void UDPStandardImplementation::startWriting(){ cprintf(GREEN,"Writing_Thread %d: Popped %p from FIFO %d\n", ithread, (void*)(wbuf),listenfifoIndex); #endif uint32_t numPackets = (uint32_t)(*((uint32_t*)wbuf)); -#ifdef DEBUG4 +//#ifdef DEBUG4 cprintf(GREEN,"Writing_Thread %d: Number of Packets: %d for FIFO %d\n", ithread, numPackets, listenfifoIndex); -#endif +//#endif //end of acquisition if(numPackets == dummyPacketValue){ -#ifdef DEBUG4 +//#ifdef DEBUG4 cprintf(GREEN,"Writing_Thread %d: Dummy frame popped out of FIFO %d",ithread, listenfifoIndex); -#endif +//#endif stopWriting(ithread,wbuf); continue; } From 10a6bc7157622ecdeb616bb8b1cbb1b15b8a0c43 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Mon, 31 Oct 2016 16:15:49 +0100 Subject: [PATCH 322/474] trying --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 7f96be772..be2842407 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -2742,7 +2742,7 @@ void UDPStandardImplementation::stopWriting(int ithread, char* wbuffer){ //statistics FILE_LOG(logINFO) << "Status: Run Finished"; for(int i=0;i Date: Mon, 31 Oct 2016 16:19:10 +0100 Subject: [PATCH 323/474] trying --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index be2842407..e454023a9 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -2742,7 +2742,10 @@ void UDPStandardImplementation::stopWriting(int ithread, char* wbuffer){ //statistics FILE_LOG(logINFO) << "Status: Run Finished"; for(int i=0;i Date: Mon, 31 Oct 2016 16:20:33 +0100 Subject: [PATCH 324/474] trying --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index e454023a9..741c1f089 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -2744,6 +2744,8 @@ void UDPStandardImplementation::stopWriting(int ithread, char* wbuffer){ for(int i=0;i Date: Mon, 31 Oct 2016 16:21:31 +0100 Subject: [PATCH 325/474] trying --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 741c1f089..9044e4978 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -2744,7 +2744,7 @@ void UDPStandardImplementation::stopWriting(int ithread, char* wbuffer){ for(int i=0;i Date: Mon, 31 Oct 2016 16:24:23 +0100 Subject: [PATCH 326/474] trying --- slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp index 1a477e7cd..c87200ddd 100644 --- a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp +++ b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp @@ -2354,7 +2354,7 @@ int slsReceiverTCPIPInterface::set_timer() { strcpy(mess,"Error reading from socket\n"); ret = FAIL; } - + printf("index[0]:%d index[1]:%d\n",index[0],index[1]); // execute action if the arguments correctly arrived #ifdef SLS_RECEIVER_UDP_FUNCTIONS if (ret==OK) { From ca93ff798b3ea36abd6acbf3e63000516a5b1b7d Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Mon, 31 Oct 2016 16:43:50 +0100 Subject: [PATCH 327/474] trying --- slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp index c87200ddd..1a477e7cd 100644 --- a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp +++ b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp @@ -2354,7 +2354,7 @@ int slsReceiverTCPIPInterface::set_timer() { strcpy(mess,"Error reading from socket\n"); ret = FAIL; } - printf("index[0]:%d index[1]:%d\n",index[0],index[1]); + // execute action if the arguments correctly arrived #ifdef SLS_RECEIVER_UDP_FUNCTIONS if (ret==OK) { From 6e0f9eaa78c445a45fdad24a13736f2f1ae02e91 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Mon, 31 Oct 2016 16:47:10 +0100 Subject: [PATCH 328/474] trying --- .../src/UDPStandardImplementation.cpp | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 9044e4978..b42c6d18f 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -2704,14 +2704,14 @@ void UDPStandardImplementation::stopWriting(int ithread, char* wbuffer){ frameNumberInPreviousFile[ithread] = startFrameIndex-1; printf("\nThread:%d File:%s\n" - "\ttotalpacketsinfile:%d\t" + //"\ttotalpacketsinfile:%d\t" "Packets Lost:%d" - "\tCurrentFrameNumber:%lld\tPreviousFrameNumber:%lld" + //"\tCurrentFrameNumber:%lld\tPreviousFrameNumber:%lld" "\n", ithread,completeFileName[ithread], - totalPacketsInFile[ithread], + //totalPacketsInFile[ithread], ( ((int)(currentFrameNumber[ithread]-frameNumberInPreviousFile[ithread])*packetsPerFrame) - totalPacketsInFile[ithread]) - ,currentFrameNumber[ithread],frameNumberInPreviousFile[ithread] + //,currentFrameNumber[ithread],frameNumberInPreviousFile[ithread] ); } closeFile(ithread); @@ -2742,12 +2742,6 @@ void UDPStandardImplementation::stopWriting(int ithread, char* wbuffer){ //statistics FILE_LOG(logINFO) << "Status: Run Finished"; for(int i=0;i Date: Mon, 31 Oct 2016 16:56:21 +0100 Subject: [PATCH 329/474] trying --- slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp index 1a477e7cd..f662845dd 100644 --- a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp +++ b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp @@ -296,9 +296,9 @@ int slsReceiverTCPIPInterface::decode_function(){ cout << "size of data received " << n <numberOfFunctions-1) fnum = numberOfFunctions-1; From a330706d863caa7b98b1fb89397e0aa0a148da74 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Mon, 31 Oct 2016 17:05:07 +0100 Subject: [PATCH 330/474] sorta done --- slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp index f662845dd..29806a82a 100644 --- a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp +++ b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp @@ -296,9 +296,9 @@ int slsReceiverTCPIPInterface::decode_function(){ cout << "size of data received " << n <numberOfFunctions-1) fnum = numberOfFunctions-1; From 9c7fb4da388e54fa15c6b9bbb5ce7aee0f397202 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 1 Nov 2016 09:13:16 +0100 Subject: [PATCH 331/474] added gui stuff --- .../src/UDPStandardImplementation.cpp | 172 ++++++++++-------- 1 file changed, 98 insertions(+), 74 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index b42c6d18f..553717ff5 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1743,7 +1743,7 @@ void UDPStandardImplementation::startDataCallback(){ if(guiNumPackets[ithread] == dummyPacketValue){ //sending previous half frames if any - if(newFrame){ + if((myDetectorType != JUNGFRAU) && newFrame){ //send header //update frame details frameIndex = fnum;if(frameIndex==-1) cprintf(RED,"frameindex = -1, 111\n"); @@ -1797,76 +1797,61 @@ void UDPStandardImplementation::startDataCallback(){ } } - size = guiNumPackets[ithread]*onePacketSize; - datapacketscaught+=guiNumPackets[ithread]; - offset=0; - - //copy packet by packet -getting rid of headers, -in the right order(padding missing packets) - while(offset < size){ - - //until getting frame number is not error - while((size>0) && (getFrameandPacketNumber(ithread, latestData[ithread]+offset, fnum, pnum,snum)==FAIL)){ - offset+= onePacketSize; + if(myDetectorType == JUNGFRAU){ + //send header + //update frame details + frameIndex = (*((uint32_t*)(latestData[ithread]+8))); + acquisitionIndex = frameIndex - startAcquisitionIndex; + subframeIndex = -1; + int len = sprintf(buf+JFRAU_FILE_FRAME_HEADER_LENGTH,jsonFmt,type,shape, acquisitionIndex, frameIndex, subframeIndex,completeFileName[ithread]); + zmq_send(zmqsocket, buf,len, ZMQ_SNDMORE); + //send data + zmq_send(zmqsocket, latestData[ithread]+JFRAU_FILE_FRAME_HEADER_LENGTH, oneframesize, 0); + //start clock after sending + if(!frameToGuiFrequency){ + randomSendNow = false; + clock_gettime(CLOCK_REALTIME, &begin); } - //if(!ithread) cout<< ithread <<" fnum:"<< fnum<<" pnum:"<= size) - break; - - if(!frameToGuiFrequency) - currentfnum = fnum; + } - //last packet of same frame - if(fnum == currentfnum && pnum == (packetsPerFrame-1)){ -#ifdef DEBUG - oldpnum=0; -#endif - memcpy(buffer+(pnum*oneDataSize), latestData[ithread]+offset+headersize,oneDataSize); - offset+= onePacketSize; - //send header - //update frame details - frameIndex = fnum; - acquisitionIndex = fnum - startAcquisitionIndex; - if(dynamicRange == 32) subframeIndex = snum; - int len = sprintf(buf,jsonFmt,type,shape, acquisitionIndex, frameIndex, subframeIndex,completeFileName[ithread]); - zmq_send(zmqsocket, buf,len, ZMQ_SNDMORE); - //send data - zmq_send(zmqsocket, buffer, oneframesize, 0); - newFrame = false; -#ifdef DEBUG - if(!ithread)cprintf(BLUE,"%d sent (last packet)\n",ithread); -#endif - currentfnum++; - //start clock after sending - if(!frameToGuiFrequency){ - randomSendNow = false; - clock_gettime(CLOCK_REALTIME, &begin); + //eiger + else{ + + size = guiNumPackets[ithread]*onePacketSize; + datapacketscaught+=guiNumPackets[ithread]; + offset=0; + + //copy packet by packet -getting rid of headers, -in the right order(padding missing packets) + while(offset < size){ + + //until getting frame number is not error + while((size>0) && (getFrameandPacketNumber(ithread, latestData[ithread]+offset, fnum, pnum,snum)==FAIL)){ + offset+= onePacketSize; } - memset(buffer,0xFF,oneframesize); + //if(!ithread) cout<< ithread <<" fnum:"<< fnum<<" pnum:"< currentfnum){ + //end of buffer + if(offset >= size) + break; + + if(!frameToGuiFrequency) + currentfnum = fnum; + + + //last packet of same frame + if(fnum == currentfnum && pnum == (packetsPerFrame-1)){ #ifdef DEBUG - if(once){ - if((fnum-currentfnum-1)>1) cprintf(RED,"%d Complete sub image missing:%d (cfnum:%d nfnum:%d)\n", - ithread,fnum-currentfnum-1,currentfnum,fnum); - once = false; - } + oldpnum=0; #endif + memcpy(buffer+(pnum*oneDataSize), latestData[ithread]+offset+headersize,oneDataSize); + offset+= onePacketSize; //send header //update frame details frameIndex = fnum; @@ -1878,7 +1863,7 @@ void UDPStandardImplementation::startDataCallback(){ zmq_send(zmqsocket, buffer, oneframesize, 0); newFrame = false; #ifdef DEBUG - cprintf(BLUE,"%d sent (last packet of previous frame)\n",ithread); + if(!ithread)cprintf(BLUE,"%d sent (last packet)\n",ithread); #endif currentfnum++; //start clock after sending @@ -1887,13 +1872,50 @@ void UDPStandardImplementation::startDataCallback(){ clock_gettime(CLOCK_REALTIME, &begin); } memset(buffer,0xFF,oneframesize); + + } + //same frame (not last) or next frame + else { + //next frame +#ifdef DEBUG + int once = true; +#endif + while(fnum > currentfnum){ +#ifdef DEBUG + if(once){ + if((fnum-currentfnum-1)>1) cprintf(RED,"%d Complete sub image missing:%d (cfnum:%d nfnum:%d)\n", + ithread,fnum-currentfnum-1,currentfnum,fnum); + once = false; + } +#endif + //send header + //update frame details + frameIndex = fnum; + acquisitionIndex = fnum - startAcquisitionIndex; + if(dynamicRange == 32) subframeIndex = snum; + int len = sprintf(buf,jsonFmt,type,shape, acquisitionIndex, frameIndex, subframeIndex,completeFileName[ithread]); + zmq_send(zmqsocket, buf,len, ZMQ_SNDMORE); + //send data + zmq_send(zmqsocket, buffer, oneframesize, 0); + newFrame = false; +#ifdef DEBUG + cprintf(BLUE,"%d sent (last packet of previous frame)\n",ithread); +#endif + currentfnum++; + //start clock after sending + if(!frameToGuiFrequency){ + randomSendNow = false; + clock_gettime(CLOCK_REALTIME, &begin); + } + memset(buffer,0xFF,oneframesize); + } + + memcpy(buffer+(pnum*oneDataSize), latestData[ithread]+offset+headersize,oneDataSize); + offset+= onePacketSize; + newFrame = true; } - memcpy(buffer+(pnum*oneDataSize), latestData[ithread]+offset+headersize,oneDataSize); - offset+= onePacketSize; - newFrame = true; } - } @@ -2110,17 +2132,17 @@ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int cSize, ch if(!receivedSize) return 0; header = (jfrau_packet_header_t*)(buffer[ithread] + offset); currentpnum = (*( (uint8_t*) header->packetNumber)); - cout<<"1 currentpnum:"<frameNumber))&frameIndexMask; - cout<<"current fnum:"<<(*((uint32_t*)(buffer[ithread]+8)))<packetNumber)); - cout<<"next currentpnum :"<packetNumber)); - cout<<"trying to find currentpnum:"<ReceiveDataOnly(buffer[ithread] + fifoBufferHeaderSize + cSize, (bufferSize * numberofJobsPerBuffer) - cSize); //eiger returns 0 when header packet caught while(receivedSize < onePacketSize && status != TRANSMITTING) @@ -3073,7 +3094,10 @@ void UDPStandardImplementation::copyFrameToGui(int ithread, char* buffer, uint32 //copy date guiNumPackets[ithread] = numpackets; strcpy(guiFileName[ithread],completeFileName[ithread]); - memcpy(latestData[ithread],buffer+ fifoBufferHeaderSize , numpackets*onePacketSize); + if(myDetectorType == JUNGFRAU) + memcpy(latestData[ithread],buffer, numpackets*onePacketSize); + else + memcpy(latestData[ithread],buffer+ fifoBufferHeaderSize , numpackets*onePacketSize); //let it know its got data sem_post(&dataCallbackWriterSemaphore[ithread]); From d6e78c19ad928f0a5143f43a64f4b0d8613f8e24 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 1 Nov 2016 11:09:28 +0100 Subject: [PATCH 332/474] changing send, rc timeout --- slsReceiverSoftware/include/genericSocket.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/slsReceiverSoftware/include/genericSocket.h b/slsReceiverSoftware/include/genericSocket.h index 0fad365fe..0292d6c23 100644 --- a/slsReceiverSoftware/include/genericSocket.h +++ b/slsReceiverSoftware/include/genericSocket.h @@ -473,13 +473,13 @@ enum communicationProtocol{ //cout << "socketdescriptor "<< socketDescriptor << endl; struct timeval tout; tout.tv_sec = 0; - tout.tv_usec = 0; + tout.tv_usec = 500;//0; if(::setsockopt(socketDescriptor, SOL_SOCKET, SO_RCVTIMEO, &tout, sizeof(struct timeval)) <0) { cerr << "Error in setsockopt SO_RCVTIMEO "<< 0 << endl; } - tout.tv_sec = ts; - tout.tv_usec = 0; + tout.tv_sec = 0;//ts; + tout.tv_usec = 500;//0; if(::setsockopt(socketDescriptor, SOL_SOCKET, SO_SNDTIMEO, &tout, sizeof(struct timeval)) < 0) { cerr << "Error in setsockopt SO_SNDTIMEO " << ts << endl; From a3cab06a406cc680288507fd23e7088a6e915929 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 1 Nov 2016 11:27:30 +0100 Subject: [PATCH 333/474] something --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 553717ff5..486c14d8a 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1672,7 +1672,7 @@ void UDPStandardImplementation::startDataCallback(){ // server address to bind char hostName[100] = "tcp://127.0.0.1:"; - int portno = DEFAULT_ZMQ_PORTNO + (detID*2+ithread); + int portno = DEFAULT_ZMQ_PORTNO + (detID*numberofListeningThreads+ithread); sprintf(hostName,"%s%d",hostName,portno); //socket details From 0c257dbcddf18a82eb47e79c67e716d0666afade Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 1 Nov 2016 12:04:08 +0100 Subject: [PATCH 334/474] something --- slsReceiverSoftware/include/genericSocket.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/slsReceiverSoftware/include/genericSocket.h b/slsReceiverSoftware/include/genericSocket.h index 0292d6c23..36f7b5bbc 100644 --- a/slsReceiverSoftware/include/genericSocket.h +++ b/slsReceiverSoftware/include/genericSocket.h @@ -404,10 +404,12 @@ enum communicationProtocol{ cerr << "Can not create socket "<0){ nsending = (length>packet_size) ? packet_size:length; + cout<<"going to read from " << serverAddress.sin_port << endl; nsent = read(file_des,(char*)buf+total_sent,nsending); + cout <<"read**" <0){ nsending = (length>packet_size) ? packet_size:length; + cout<<"going to send to " << serverAddress.sin_port << endl; nsent = write(file_des,(char*)buf+total_sent,nsending); + cout<<"sent**" < Date: Tue, 1 Nov 2016 12:06:08 +0100 Subject: [PATCH 335/474] something --- slsReceiverSoftware/include/genericSocket.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/slsReceiverSoftware/include/genericSocket.h b/slsReceiverSoftware/include/genericSocket.h index 36f7b5bbc..aa3a29639 100644 --- a/slsReceiverSoftware/include/genericSocket.h +++ b/slsReceiverSoftware/include/genericSocket.h @@ -448,7 +448,7 @@ enum communicationProtocol{ close(file_des); } else { - while(!shutdown(socketDescriptor, SHUT_RDWR)); + //while(!shutdown(socketDescriptor, SHUT_RDWR)); close(socketDescriptor); socketDescriptor=-1; } From 8bb0249d5bf3f5ae78da73b58aaa5029c7958981 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 1 Nov 2016 13:09:16 +0100 Subject: [PATCH 336/474] reverted timeouts --- slsReceiverSoftware/include/genericSocket.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/slsReceiverSoftware/include/genericSocket.h b/slsReceiverSoftware/include/genericSocket.h index aa3a29639..77b8ba2f6 100644 --- a/slsReceiverSoftware/include/genericSocket.h +++ b/slsReceiverSoftware/include/genericSocket.h @@ -480,8 +480,8 @@ enum communicationProtocol{ { cerr << "Error in setsockopt SO_RCVTIMEO "<< 0 << endl; } - tout.tv_sec = 0;//ts; - tout.tv_usec = 500;//0; + tout.tv_sec = ts; + tout.tv_usec = 0; if(::setsockopt(socketDescriptor, SOL_SOCKET, SO_SNDTIMEO, &tout, sizeof(struct timeval)) < 0) { cerr << "Error in setsockopt SO_SNDTIMEO " << ts << endl; From 5de9ade51d32cc3ba40fb89dbb0cfc736a4b9f31 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 1 Nov 2016 14:04:37 +0100 Subject: [PATCH 337/474] some changes --- slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp index 1a477e7cd..231fad345 100644 --- a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp +++ b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp @@ -911,14 +911,15 @@ int slsReceiverTCPIPInterface::stop_receiver(){ int slsReceiverTCPIPInterface::get_status(){ ret=OK; - enum runStatus retval = ERROR; + int retval=-1; + enum runStatus s=ERROR; // execute action if the arguments correctly arrived #ifdef SLS_RECEIVER_UDP_FUNCTIONS if (receiverBase == NULL){ strcpy(mess,SET_RECEIVER_ERR_MESSAGE); ret=FAIL; - }else retval=receiverBase->getStatus(); + }else s=receiverBase->getStatus(); #endif if(ret==OK && socket->differentClients){ @@ -932,6 +933,7 @@ int slsReceiverTCPIPInterface::get_status(){ cprintf(RED, "%s\n", mess); socket->SendDataOnly(mess,sizeof(mess)); } + retval = (runStatus(s)) socket->SendDataOnly(&retval,sizeof(retval)); //return ok/fail return ret; From e0aee67dcd3035772fcd803d2c279f509f6700d0 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 1 Nov 2016 14:06:45 +0100 Subject: [PATCH 338/474] some changes --- slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp index 231fad345..94ab9461f 100644 --- a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp +++ b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp @@ -933,7 +933,7 @@ int slsReceiverTCPIPInterface::get_status(){ cprintf(RED, "%s\n", mess); socket->SendDataOnly(mess,sizeof(mess)); } - retval = (runStatus(s)) + retval = (runStatus(s)); socket->SendDataOnly(&retval,sizeof(retval)); //return ok/fail return ret; From b9ac75330c80b31341e8ead641a4ed970b2ca795 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 1 Nov 2016 16:36:32 +0100 Subject: [PATCH 339/474] removed all prints in generic --- slsReceiverSoftware/include/genericSocket.h | 6 ------ 1 file changed, 6 deletions(-) diff --git a/slsReceiverSoftware/include/genericSocket.h b/slsReceiverSoftware/include/genericSocket.h index 77b8ba2f6..d1e17575b 100644 --- a/slsReceiverSoftware/include/genericSocket.h +++ b/slsReceiverSoftware/include/genericSocket.h @@ -404,12 +404,10 @@ enum communicationProtocol{ cerr << "Can not create socket "<0){ nsending = (length>packet_size) ? packet_size:length; - cout<<"going to read from " << serverAddress.sin_port << endl; nsent = read(file_des,(char*)buf+total_sent,nsending); - cout <<"read**" <0){ nsending = (length>packet_size) ? packet_size:length; - cout<<"going to send to " << serverAddress.sin_port << endl; nsent = write(file_des,(char*)buf+total_sent,nsending); - cout<<"sent**" < Date: Wed, 2 Nov 2016 15:12:02 +0100 Subject: [PATCH 340/474] increased max file size for jungfrau --- slsReceiverSoftware/include/sls_receiver_defs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/slsReceiverSoftware/include/sls_receiver_defs.h b/slsReceiverSoftware/include/sls_receiver_defs.h index e37639b07..ce0fad9fa 100755 --- a/slsReceiverSoftware/include/sls_receiver_defs.h +++ b/slsReceiverSoftware/include/sls_receiver_defs.h @@ -24,7 +24,7 @@ typedef int int32_t; #define SHORT_MAX_FRAMES_PER_FILE 100000 #define MOENCH_MAX_FRAMES_PER_FILE 1000 #define EIGER_MAX_FRAMES_PER_FILE 2000 -#define JFRAU_MAX_FRAMES_PER_FILE 2000 +#define JFRAU_MAX_FRAMES_PER_FILE 10000 #define JFCTB_MAX_FRAMES_PER_FILE 100000 From f71378e67f90c59c31c4c1222bef66556ccd7975 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Wed, 2 Nov 2016 15:25:23 +0100 Subject: [PATCH 341/474] frame number in header corected, create file logic --- .../src/UDPStandardImplementation.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 486c14d8a..93b8f28ad 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -2141,7 +2141,7 @@ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int cSize, ch if(currentpnum == pnum){ //cout<<"correct packet"<frameNumber))&frameIndexMask; + (*((uint32_t*)(buffer[ithread]+8))) = ((*( (uint32_t*) header->frameNumber))&frameIndexMask)-startFrameIndex; //cout<<"current fnum:"<<(*((uint32_t*)(buffer[ithread]+8)))< 0){ if((fileWriteEnable) && (sfilefd[ithread])){ - if(tempframenumber >= maxFramesPerFile) + if((tempframenumber%maxFramesPerFile) == 0) createNewFile(ithread); fwrite(wbuffer, 1, oneDataSize*packetsPerFrame+fifoBufferHeaderSize, sfilefd[ithread]); } From ece614eb7e59c40d714abbe6a214febcd8e881b1 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Wed, 2 Nov 2016 15:40:25 +0100 Subject: [PATCH 342/474] startframeindex corrected --- .../src/UDPStandardImplementation.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 93b8f28ad..69513b8fc 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1533,7 +1533,7 @@ int UDPStandardImplementation::setupWriter(){ -int UDPStandardImplementation::createNewFile(int ithread){ +int UDPStandardImplementation::createNewFile(int ithread){cprintf(BLUE,"Creating new file\n"); FILE_LOG(logDEBUG) << __AT__ << " called"; //create file name @@ -2141,8 +2141,8 @@ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int cSize, ch if(currentpnum == pnum){ //cout<<"correct packet"<frameNumber))&frameIndexMask)-startFrameIndex; - //cout<<"current fnum:"<<(*((uint32_t*)(buffer[ithread]+8)))<frameNumber))&frameIndexMask); + cout<<"current fnum:"<<(*((uint32_t*)(buffer[ithread]+8)))<frameNumber))&frameIndexMask; + startFrameIndex = (*((uint32_t*)(buffer[ithread]+8))); break; default: if(shortFrameEnable < 0){ @@ -2870,8 +2869,9 @@ void UDPStandardImplementation::handleWithoutMissingPackets(int ithread, char* w //write to file if enabled and update write parameters if(npackets > 0){ if((fileWriteEnable) && (sfilefd[ithread])){ - if((tempframenumber%maxFramesPerFile) == 0) + if((tempframenumber%maxFramesPerFile) == 0){ createNewFile(ithread); + } fwrite(wbuffer, 1, oneDataSize*packetsPerFrame+fifoBufferHeaderSize, sfilefd[ithread]); } From e2d6bf31a3effc5feefab609fbc7b8d76b21bda7 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Wed, 2 Nov 2016 15:42:15 +0100 Subject: [PATCH 343/474] startframeindex corrected --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 69513b8fc..052601bbb 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -2858,7 +2858,7 @@ void UDPStandardImplementation::handleWithoutMissingPackets(int ithread, char* w //get current frame number uint64_t tempframenumber; - tempframenumber = (*((uint32_t*)(buffer[ithread]+8))); + tempframenumber = (*((uint32_t*)(buffer[ithread]+8))) - startFrameIndex; cout<<"handling: frame number:"< Date: Wed, 2 Nov 2016 15:44:28 +0100 Subject: [PATCH 344/474] startframeindex corrected --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 052601bbb..8986ca800 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -2858,8 +2858,10 @@ void UDPStandardImplementation::handleWithoutMissingPackets(int ithread, char* w //get current frame number uint64_t tempframenumber; - tempframenumber = (*((uint32_t*)(buffer[ithread]+8))) - startFrameIndex; + tempframenumber = (*((uint32_t*)(buffer[ithread]+8))); cout<<"handling: frame number:"< 0){ if((fileWriteEnable) && (sfilefd[ithread])){ if((tempframenumber%maxFramesPerFile) == 0){ + exit(-1); createNewFile(ithread); } fwrite(wbuffer, 1, oneDataSize*packetsPerFrame+fifoBufferHeaderSize, sfilefd[ithread]); From b9caa1e1e11fb8d413e5d7b77d566b80e118770e Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Wed, 2 Nov 2016 15:45:45 +0100 Subject: [PATCH 345/474] startframeindex corrected --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 8986ca800..39efbe66f 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -2871,7 +2871,7 @@ void UDPStandardImplementation::handleWithoutMissingPackets(int ithread, char* w //write to file if enabled and update write parameters if(npackets > 0){ if((fileWriteEnable) && (sfilefd[ithread])){ - if((tempframenumber%maxFramesPerFile) == 0){ + if(tempframenumber && (tempframenumber%maxFramesPerFile) == 0){ exit(-1); createNewFile(ithread); } From f0c82d902785a24d17f252421d596e6f97e575a2 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Wed, 2 Nov 2016 15:47:51 +0100 Subject: [PATCH 346/474] startframeindex corrected --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 39efbe66f..bb044ad9d 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -2858,7 +2858,7 @@ void UDPStandardImplementation::handleWithoutMissingPackets(int ithread, char* w //get current frame number uint64_t tempframenumber; - tempframenumber = (*((uint32_t*)(buffer[ithread]+8))); + tempframenumber = (*((uint32_t*)(wbuffer+8))); cout<<"handling: frame number:"< Date: Wed, 2 Nov 2016 15:49:46 +0100 Subject: [PATCH 347/474] startframeindex corrected --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index bb044ad9d..b21cfcc68 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -2142,7 +2142,7 @@ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int cSize, ch //cout<<"correct packet"<frameNumber))&frameIndexMask); - cout<<"current fnum:"<<(*((uint32_t*)(buffer[ithread]+8)))< 0){ if((fileWriteEnable) && (sfilefd[ithread])){ if(tempframenumber && (tempframenumber%maxFramesPerFile) == 0){ - exit(-1); createNewFile(ithread); } fwrite(wbuffer, 1, oneDataSize*packetsPerFrame+fifoBufferHeaderSize, sfilefd[ithread]); From 8eb91bc46d951c889970c68fc7d1b97f3cc9d699 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Wed, 2 Nov 2016 15:56:10 +0100 Subject: [PATCH 348/474] startframeindex corrected --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index b21cfcc68..32bb47c54 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -2161,17 +2161,17 @@ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int cSize, ch //wrong packet else{ - cprintf(RED,"wrong packet\n"); + cprintf(RED,"wrong packet fnum of last good one:%d\n",(*((uint32_t*)(buffer[ithread]+8)))); pnum = packetsPerFrame-1; offset = fifoBufferHeaderSize; //find the start of next image - while(currentpnum != (packetsPerFrame-1)){ + while(currentpnum != pnum){ receivedSize = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + offset, onePacketSize); if(!receivedSize) return 0; header = (jfrau_packet_header_t*)(buffer[ithread] + offset); currentpnum = (*( (uint8_t*) header->packetNumber)); - //cout<<"trying to find currentpnum:"< 0){ if((fileWriteEnable) && (sfilefd[ithread])){ if(tempframenumber && (tempframenumber%maxFramesPerFile) == 0){ + cout<<"going to create new file: frame number:"< Date: Wed, 2 Nov 2016 16:01:55 +0100 Subject: [PATCH 349/474] startframeindex corrected --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 32bb47c54..2e3d2866a 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -2132,7 +2132,7 @@ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int cSize, ch if(!receivedSize) return 0; header = (jfrau_packet_header_t*)(buffer[ithread] + offset); currentpnum = (*( (uint8_t*) header->packetNumber)); - //cout<<"1 currentpnum:"<frameNumber))&frameIndexMask); - //cout<<"current fnum:"<<(*((uint32_t*)(buffer[ithread]+8)))<packetNumber)); - //cout<<"next currentpnum :"<packetNumber)); - //cout<<"trying to find: currentpnum:"< Date: Wed, 2 Nov 2016 16:08:02 +0100 Subject: [PATCH 350/474] lskjgf --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 2e3d2866a..32bb47c54 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -2132,7 +2132,7 @@ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int cSize, ch if(!receivedSize) return 0; header = (jfrau_packet_header_t*)(buffer[ithread] + offset); currentpnum = (*( (uint8_t*) header->packetNumber)); - cout<<"1 currentpnum:"<frameNumber))&frameIndexMask); - cout<<"current fnum:"<<(*((uint32_t*)(buffer[ithread]+8)))<packetNumber)); - cout<<"next currentpnum :"<packetNumber)); - cout<<"trying to find: currentpnum:"< Date: Thu, 3 Nov 2016 09:16:36 +0100 Subject: [PATCH 351/474] introduced ignored packets and changed meaning of missing packets for jungfrau --- .../include/UDPStandardImplementation.h | 3 +++ .../src/UDPStandardImplementation.cpp | 24 +++++++++++++++---- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/slsReceiverSoftware/include/UDPStandardImplementation.h b/slsReceiverSoftware/include/UDPStandardImplementation.h index 2a8a553c7..413d98147 100644 --- a/slsReceiverSoftware/include/UDPStandardImplementation.h +++ b/slsReceiverSoftware/include/UDPStandardImplementation.h @@ -636,6 +636,9 @@ private: /** Total packet Count listened to by listening threads */ int totalListeningPacketCount[MAX_NUMBER_OF_LISTENING_THREADS]; + /** Total packet Count ignored by listening threads */ + int totalIgnoredPacketCount[MAX_NUMBER_OF_LISTENING_THREADS]; + /** Pckets currently in current file, starts new file when it reaches max */ int64_t lastFrameNumberInFile[MAX_NUMBER_OF_WRITER_THREADS]; diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 32bb47c54..d71d54a51 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -161,6 +161,7 @@ void UDPStandardImplementation::initializeMembers(){ for(int i = 0; i < MAX_NUMBER_OF_LISTENING_THREADS; ++i){ measurementStarted[i] = false; totalListeningPacketCount[i] = 0; + totalIgnoredPacketCount[i] = 0; } for(int i=0; iReceiveDataOnly(buffer[ithread] + offset, onePacketSize); if(!receivedSize) return 0; @@ -2136,6 +2137,7 @@ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int cSize, ch while(true){ + totalListeningPacketCount[ithread]++; //correct packet if(currentpnum == pnum){ @@ -2153,7 +2155,10 @@ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int cSize, ch pnum --; receivedSize = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + offset, onePacketSize); - if(!receivedSize) return 0; + if(!receivedSize){ + totalIgnoredPacketCount[ithread] += (packetsPerFrame - pnum); + return 0; + } header = (jfrau_packet_header_t*)(buffer[ithread] + offset); currentpnum = (*( (uint8_t*) header->packetNumber)); //cout<<"next currentpnum :"<ReceiveDataOnly(buffer[ithread] + offset, onePacketSize); if(!receivedSize) return 0; header = (jfrau_packet_header_t*)(buffer[ithread] + offset); @@ -2177,7 +2185,11 @@ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int cSize, ch }//----- got a whole frame ------- receivedSize = oneDataSize * packetsPerFrame; + return receivedSize; } + + + //other detectors else{ receivedSize = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + fifoBufferHeaderSize + cSize, (bufferSize * numberofJobsPerBuffer) - cSize); //eiger returns 0 when header packet caught @@ -2765,7 +2777,11 @@ void UDPStandardImplementation::stopWriting(int ithread, char* wbuffer){ if(totalWritingPacketCount[i] < ((uint64_t)numberOfFrames*packetsPerFrame)){ cprintf(RED, "\nPort %d\n",udpPortNum[i]); - cprintf(RED, "Missing Packets \t: %lld\n",(long long int)numberOfFrames*packetsPerFrame-totalWritingPacketCount[i]); + if(myDetectorType == JUNGFRAU){ + cprintf(RED, "Ignored Packets \t: %lld\n",(long long int)totalIgnoredPacketCount[i]); + cprintf(RED, "Missing Packets \t: %lld\n",(long long int)numberOfFrames*packetsPerFrame-totalWritingPacketCount[i]-totalIgnoredPacketCount[i]); + }else + cprintf(RED, "Missing Packets \t: %lld\n",(long long int)numberOfFrames*packetsPerFrame-totalWritingPacketCount[i]); cprintf(RED, "Packets Caught \t\t: %lld\n",(long long int)totalWritingPacketCount[i]); cprintf(RED, "Frames Caught \t\t: %lld\n",(long long int)(totalWritingPacketCount[i]/packetsPerFrame)); int64_t lastFrameNumber = 0; From 170d3145403a72e7d6a9fdc1ba9707bab70c5796 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Thu, 3 Nov 2016 09:21:09 +0100 Subject: [PATCH 352/474] debugging --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index d71d54a51..a915ea842 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -2166,7 +2166,7 @@ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int cSize, ch //wrong packet else{ - cprintf(RED,"wrong packet fnum of last good one:%d\n",(*((uint32_t*)(buffer[ithread]+8)))); + cprintf(RED,"wrong packet %d, expected packet %d fnum of last good one:%d\n",currentpnum,pnum,(*((uint32_t*)(buffer[ithread]+8)))); totalIgnoredPacketCount[ithread] += (packetsPerFrame - pnum -1); //extra 1 subtracted now to be added in the while loop anyway pnum = packetsPerFrame-1; From 014175689fe623b4b85b6e492b8b3579ca0742ac Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Thu, 3 Nov 2016 09:25:30 +0100 Subject: [PATCH 353/474] debugging --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index a915ea842..0d1d5b995 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -2791,7 +2791,11 @@ void UDPStandardImplementation::stopWriting(int ithread, char* wbuffer){ cprintf(RED, "Last Frame Number Caught :%lld\n",(long long int)lastFrameNumber); }else{ cprintf(GREEN, "\nPort %d\n",udpPortNum[i]); - cprintf(GREEN, "Missing Packets \t: %lld\n",(long long int)numberOfFrames*packetsPerFrame-totalWritingPacketCount[i]); + if(myDetectorType == JUNGFRAU){ + cprintf(GREEN, "Ignored Packets \t: %lld\n",(long long int)totalIgnoredPacketCount[i]); + cprintf(GREEN, "Missing Packets \t: %lld\n",(long long int)numberOfFrames*packetsPerFrame-totalWritingPacketCount[i]-totalIgnoredPacketCount[i]); + }else + cprintf(GREEN, "Missing Packets \t: %lld\n",(long long int)numberOfFrames*packetsPerFrame-totalWritingPacketCount[i]); cprintf(GREEN, "Packets Caught \t\t: %lld\n",(long long int)totalWritingPacketCount[i]); cprintf(GREEN, "Frames Caught \t\t: %lld\n",(long long int)(totalWritingPacketCount[i]/packetsPerFrame)); int64_t lastFrameNumber = 0; From 7fdc12735652a95c01972a917980ceeeadd42c8e Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Thu, 3 Nov 2016 12:31:53 +0100 Subject: [PATCH 354/474] included bunch id in jungfrau header --- slsReceiverSoftware/include/receiver_defs.h | 1 + .../src/UDPStandardImplementation.cpp | 13 +++++++------ 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/slsReceiverSoftware/include/receiver_defs.h b/slsReceiverSoftware/include/receiver_defs.h index 29c3f4994..77a3623d2 100755 --- a/slsReceiverSoftware/include/receiver_defs.h +++ b/slsReceiverSoftware/include/receiver_defs.h @@ -130,6 +130,7 @@ typedef struct { #define JFRAU_FILE_FRAME_HEADER_LENGTH 16 +#define JFRAU_FILE_HEADER_BUNCHID_OFFSET 8 #define JFRAU_FIFO_SIZE 2500 //cannot be less than max jobs per thread = 1000 #define JFRAU_PACKETS_PER_FRAME 128 #define JFRAU_HEADER_LENGTH 22 diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 0d1d5b995..fd65b4260 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -835,7 +835,7 @@ int UDPStandardImplementation::setDetectorType(const detectorType d){ maxFramesPerFile = JFRAU_MAX_FRAMES_PER_FILE; fifoDepth = JFRAU_FIFO_SIZE; fifoSize = JFRAU_FIFO_SIZE; - fifoBufferHeaderSize= JFRAU_FILE_FRAME_HEADER_LENGTH; + fifoBufferHeaderSize= (HEADER_SIZE_NUM_TOT_PACKETS + JFRAU_FILE_FRAME_HEADER_LENGTH); //footerOffset = Not applicable; break; default: @@ -1535,7 +1535,7 @@ int UDPStandardImplementation::setupWriter(){ -int UDPStandardImplementation::createNewFile(int ithread){cprintf(BLUE,"Creating new file\n"); +int UDPStandardImplementation::createNewFile(int ithread){ FILE_LOG(logDEBUG) << __AT__ << " called"; //create file name @@ -2143,7 +2143,8 @@ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int cSize, ch if(currentpnum == pnum){ //cout<<"correct packet"<frameNumber))&frameIndexMask); + (*((uint32_t*)(buffer[ithread]+HEADER_SIZE_NUM_TOT_PACKETS))) = ((*( (uint32_t*) header->frameNumber))&frameIndexMask); + (*((uint64_t*)(buffer[ithread]+HEADER_SIZE_NUM_TOT_PACKETS+JFRAU_FILE_HEADER_BUNCHID_OFFSET))) = (*( (uint64_t*) header->bunchid)); //cout<<"current fnum:"<<(*((uint32_t*)(buffer[ithread]+8)))< DO_NOTHING) && missingPacketinFile){ + if(myDetectorType == EIGER && fileWriteEnable && (cbAction > DO_NOTHING) && missingPacketinFile){ updateFileHeader(ithread); fseek(sfilefd[ithread],0,0); fwrite((void*)fileHeader[ithread], 1, FILE_HEADER_SIZE, sfilefd[ithread]); @@ -2894,7 +2895,7 @@ void UDPStandardImplementation::handleWithoutMissingPackets(int ithread, char* w cout<<"going to create new file: frame number:"< Date: Thu, 3 Nov 2016 12:33:14 +0100 Subject: [PATCH 355/474] updaterev --- slsReceiverSoftware/gitInfo.txt | 10 +++++----- slsReceiverSoftware/include/gitInfoReceiver.h | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/slsReceiverSoftware/gitInfo.txt b/slsReceiverSoftware/gitInfo.txt index 6e3160308..e0313299d 100644 --- a/slsReceiverSoftware/gitInfo.txt +++ b/slsReceiverSoftware/gitInfo.txt @@ -1,9 +1,9 @@ Path: slsDetectorsPackage/slsReceiverSoftware URL: origin git@git.psi.ch:sls_detectors_software/sls_receiver_software.git Repository Root: origin git@git.psi.ch:sls_detectors_software/sls_receiver_software.git -Repsitory UUID: 1c7a5892a984a6954b8f65e052e803a908153e9f -Revision: 254 +Repsitory UUID: 8520c582734b323d48a73bf8a289fb64dc2c6ad3 +Revision: 394 Branch: developer -Last Changed Author: wang_x1_ -Last Changed Rev: 254 -Last Changed Date: 2016-09-14 11:58:39 +0200 +Last Changed Author: Dhanya_Maliakal +Last Changed Rev: 394 +Last Changed Date: 2016-11-03 12:31:53 +0100 diff --git a/slsReceiverSoftware/include/gitInfoReceiver.h b/slsReceiverSoftware/include/gitInfoReceiver.h index 168f020ed..443395c2b 100644 --- a/slsReceiverSoftware/include/gitInfoReceiver.h +++ b/slsReceiverSoftware/include/gitInfoReceiver.h @@ -1,11 +1,11 @@ //#define SVNPATH "" #define SVNURL "git@git.psi.ch:sls_detectors_software/sls_receiver_software.git" //#define SVNREPPATH "" -#define SVNREPUUID "1c7a5892a984a6954b8f65e052e803a908153e9f" -//#define SVNREV 0x254 +#define SVNREPUUID "8520c582734b323d48a73bf8a289fb64dc2c6ad3" +//#define SVNREV 0x394 //#define SVNKIND "" //#define SVNSCHED "" -#define SVNAUTH "wang_x1_" -#define SVNREV 0x254 -#define SVNDATE 0x20160914 +#define SVNAUTH "Dhanya_Maliakal" +#define SVNREV 0x394 +#define SVNDATE 0x20161103 // From b7ead7e61ee8769dca71bcb4ff703e0e11bc7c2e Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Thu, 3 Nov 2016 13:30:58 +0100 Subject: [PATCH 356/474] creating new files --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index fd65b4260..dd0b63870 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -2879,7 +2879,7 @@ void UDPStandardImplementation::handleWithoutMissingPackets(int ithread, char* w //get current frame number uint64_t tempframenumber; - tempframenumber = (*((uint32_t*)(wbuffer+8))); + tempframenumber = (*((uint32_t*)(wbuffer+HEADER_SIZE_NUM_TOT_PACKETS))); tempframenumber -= startFrameIndex; //cout<<"handling: frame number:"< Date: Thu, 3 Nov 2016 13:37:30 +0100 Subject: [PATCH 357/474] creating new files --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index dd0b63870..46bb0efbe 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1574,7 +1574,7 @@ int UDPStandardImplementation::createNewFile(int ithread){ //Print packet loss and filenames if(!totalWritingPacketCount[ithread]){ frameNumberInPreviousFile[ithread] = -1; - printf("Thread:%d File:%s\n",ithread,completeFileName[ithread]); + //printf("Thread:%d File:%s\n",ithread,completeFileName[ithread]); }else{ if(frameNumberInPreviousFile[ithread] == -1) frameNumberInPreviousFile[ithread] = startFrameIndex -1; @@ -2881,10 +2881,11 @@ void UDPStandardImplementation::handleWithoutMissingPackets(int ithread, char* w uint64_t tempframenumber; tempframenumber = (*((uint32_t*)(wbuffer+HEADER_SIZE_NUM_TOT_PACKETS))); tempframenumber -= startFrameIndex; + currentFrameNumber[ithread] = tempframenumber; //cout<<"handling: frame number:"< 0){ if((fileWriteEnable) && (sfilefd[ithread])){ if(tempframenumber && (tempframenumber%maxFramesPerFile) == 0){ - cout<<"going to create new file: frame number:"< 1) pthread_mutex_lock(&writeMutex); From 26d8d6e108d904bc67f1aad282faaf6bfa1843a0 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Thu, 3 Nov 2016 13:40:26 +0100 Subject: [PATCH 358/474] creating new files --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 46bb0efbe..506ae64a2 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -2885,7 +2885,7 @@ void UDPStandardImplementation::handleWithoutMissingPackets(int ithread, char* w //cout<<"handling: frame number:"< Date: Thu, 3 Nov 2016 13:44:24 +0100 Subject: [PATCH 359/474] progress bug --- slsReceiverSoftware/include/sls_receiver_defs.h | 2 +- .../src/UDPStandardImplementation.cpp | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/slsReceiverSoftware/include/sls_receiver_defs.h b/slsReceiverSoftware/include/sls_receiver_defs.h index ce0fad9fa..00b53598e 100755 --- a/slsReceiverSoftware/include/sls_receiver_defs.h +++ b/slsReceiverSoftware/include/sls_receiver_defs.h @@ -25,7 +25,7 @@ typedef int int32_t; #define MOENCH_MAX_FRAMES_PER_FILE 1000 #define EIGER_MAX_FRAMES_PER_FILE 2000 #define JFRAU_MAX_FRAMES_PER_FILE 10000 -#define JFCTB_MAX_FRAMES_PER_FILE 100000 +#define JFCTB_MAX_FRAMES_PER_FILE 5 /** diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 506ae64a2..7ee679ed5 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1582,12 +1582,12 @@ int UDPStandardImplementation::createNewFile(int ithread){ printf("\nThread:%d File:%s\n" //"\ttotalpacketsinfile:%d\t" "Packets Lost:%d" - //"\tCurrentFrameNumber:%lld\tPreviousFrameNumber:%lld" + "\tCurrentFrameNumber:%lld\tPreviousFrameNumber:%lld" "\n", ithread,completeFileName[ithread], //totalPacketsInFile[ithread], ( ((int)(currentFrameNumber[ithread]-frameNumberInPreviousFile[ithread])*packetsPerFrame) - totalPacketsInFile[ithread]) - //,currentFrameNumber[ithread],frameNumberInPreviousFile[ithread] + ,currentFrameNumber[ithread],frameNumberInPreviousFile[ithread] ); } @@ -2737,14 +2737,14 @@ void UDPStandardImplementation::stopWriting(int ithread, char* wbuffer){ frameNumberInPreviousFile[ithread] = startFrameIndex-1; printf("\nThread:%d File:%s\n" - //"\ttotalpacketsinfile:%d\t" + "\ttotalpacketsinfile:%d\t" "Packets Lost:%d" - //"\tCurrentFrameNumber:%lld\tPreviousFrameNumber:%lld" + "\tCurrentFrameNumber:%lld\tPreviousFrameNumber:%lld" "\n", ithread,completeFileName[ithread], - //totalPacketsInFile[ithread], + totalPacketsInFile[ithread], ( ((int)(currentFrameNumber[ithread]-frameNumberInPreviousFile[ithread])*packetsPerFrame) - totalPacketsInFile[ithread]) - //,currentFrameNumber[ithread],frameNumberInPreviousFile[ithread] + ,currentFrameNumber[ithread],frameNumberInPreviousFile[ithread] ); } closeFile(ithread); From 0cc89efb20a0dbe2881d00c55b9eccd9efbd159e Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Thu, 3 Nov 2016 13:47:24 +0100 Subject: [PATCH 360/474] progress bug --- slsReceiverSoftware/include/sls_receiver_defs.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/slsReceiverSoftware/include/sls_receiver_defs.h b/slsReceiverSoftware/include/sls_receiver_defs.h index 00b53598e..fb8fbda2f 100755 --- a/slsReceiverSoftware/include/sls_receiver_defs.h +++ b/slsReceiverSoftware/include/sls_receiver_defs.h @@ -24,8 +24,8 @@ typedef int int32_t; #define SHORT_MAX_FRAMES_PER_FILE 100000 #define MOENCH_MAX_FRAMES_PER_FILE 1000 #define EIGER_MAX_FRAMES_PER_FILE 2000 -#define JFRAU_MAX_FRAMES_PER_FILE 10000 -#define JFCTB_MAX_FRAMES_PER_FILE 5 +#define JFRAU_MAX_FRAMES_PER_FILE 5 +#define JFCTB_MAX_FRAMES_PER_FILE 100000 /** From 6498b206129c1d6f1f44fe247cedacb809252fb0 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Thu, 3 Nov 2016 13:51:03 +0100 Subject: [PATCH 361/474] progress bug --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 7ee679ed5..a8dda285e 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -2881,11 +2881,10 @@ void UDPStandardImplementation::handleWithoutMissingPackets(int ithread, char* w uint64_t tempframenumber; tempframenumber = (*((uint32_t*)(wbuffer+HEADER_SIZE_NUM_TOT_PACKETS))); tempframenumber -= startFrameIndex; - currentFrameNumber[ithread] = tempframenumber; //cout<<"handling: frame number:"< 1) pthread_mutex_lock(&writeMutex); From 3ed427e7f06c4952e239a5ef3304f95c5e2a4268 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Thu, 3 Nov 2016 13:55:03 +0100 Subject: [PATCH 362/474] progress bug --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index a8dda285e..b5debd195 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -2901,6 +2901,7 @@ void UDPStandardImplementation::handleWithoutMissingPackets(int ithread, char* w totalWritingPacketCount[ithread] += npackets; lastFrameNumberInFile[ithread] = tempframenumber; currentFrameNumber[ithread] = tempframenumber; + cout<<"curentframenumber:"< 1) pthread_mutex_lock(&writeMutex); From 3a3e5668d76f02e3260cc9a87bc8c28ef58483ab Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Thu, 3 Nov 2016 13:56:31 +0100 Subject: [PATCH 363/474] progress bug --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index b5debd195..0891830ba 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -2880,8 +2880,9 @@ void UDPStandardImplementation::handleWithoutMissingPackets(int ithread, char* w //get current frame number uint64_t tempframenumber; tempframenumber = (*((uint32_t*)(wbuffer+HEADER_SIZE_NUM_TOT_PACKETS))); + cout<<"handling: before frame number:"< Date: Thu, 3 Nov 2016 13:57:43 +0100 Subject: [PATCH 364/474] progress bug --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 0891830ba..16df9d5b1 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -2246,7 +2246,7 @@ void UDPStandardImplementation::startFrameIndices(int ithread){ startFrameIndex = 0; //frame number always resets break; case JUNGFRAU: - startFrameIndex = (*((uint32_t*)(buffer[ithread]+8))); + startFrameIndex = (*((uint32_t*)(buffer[ithread]+HEADER_SIZE_NUM_TOT_PACKETS))); break; default: if(shortFrameEnable < 0){ From fbd0f01fa70a729c14753951d04f1a0790c5723d Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Thu, 3 Nov 2016 13:59:58 +0100 Subject: [PATCH 365/474] progress bug --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 16df9d5b1..352a09e84 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -2004,7 +2004,7 @@ void UDPStandardImplementation::startListening(){ rc = prepareAndListenBuffer(ithread, carryonBufferSize, tempBuffer); carryonBufferSize = 0; - + cout<<"measurement started:"< 0)) startFrameIndices(ithread); @@ -2236,7 +2236,7 @@ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int cSize, ch -void UDPStandardImplementation::startFrameIndices(int ithread){ +void UDPStandardImplementation::startFrameIndices(int ithread){cprintf(RED,"at startframeindeices\n"); FILE_LOG(logDEBUG) << __AT__ << " called"; //determine startFrameIndex From 5fb38694d3809acd78a3ee1cfcb99c8358dcf9f8 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Thu, 3 Nov 2016 14:01:24 +0100 Subject: [PATCH 366/474] progress bug --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 352a09e84..654f98059 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -2004,9 +2004,9 @@ void UDPStandardImplementation::startListening(){ rc = prepareAndListenBuffer(ithread, carryonBufferSize, tempBuffer); carryonBufferSize = 0; - cout<<"measurement started:"< 0)) + if((!measurementStarted[ithread]) && (rc > 0)) startFrameIndices(ithread); //problem in receiving or end of acquisition if (status == TRANSMITTING||(rc == 0 && activated == 0)){ From 274fffa609d1830f4a5e57e0eaf1e4970a90be15 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Thu, 3 Nov 2016 14:16:07 +0100 Subject: [PATCH 367/474] progress bug --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 654f98059..33298c5ec 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1576,8 +1576,6 @@ int UDPStandardImplementation::createNewFile(int ithread){ frameNumberInPreviousFile[ithread] = -1; //printf("Thread:%d File:%s\n",ithread,completeFileName[ithread]); }else{ - if(frameNumberInPreviousFile[ithread] == -1) - frameNumberInPreviousFile[ithread] = startFrameIndex -1; printf("\nThread:%d File:%s\n" //"\ttotalpacketsinfile:%d\t" @@ -2236,7 +2234,7 @@ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int cSize, ch -void UDPStandardImplementation::startFrameIndices(int ithread){cprintf(RED,"at startframeindeices\n"); +void UDPStandardImplementation::startFrameIndices(int ithread){ FILE_LOG(logDEBUG) << __AT__ << " called"; //determine startFrameIndex @@ -2733,8 +2731,6 @@ void UDPStandardImplementation::stopWriting(int ithread, char* wbuffer){ } if(totalWritingPacketCount[ithread]){ - if(frameNumberInPreviousFile[ithread]==-1) - frameNumberInPreviousFile[ithread] = startFrameIndex-1; printf("\nThread:%d File:%s\n" "\ttotalpacketsinfile:%d\t" From 4b65c3b69411320ea0f490ebb8ba0dba7d66d450 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Thu, 3 Nov 2016 14:17:53 +0100 Subject: [PATCH 368/474] progress bug --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 33298c5ec..c1e30700d 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -2733,14 +2733,14 @@ void UDPStandardImplementation::stopWriting(int ithread, char* wbuffer){ if(totalWritingPacketCount[ithread]){ printf("\nThread:%d File:%s\n" - "\ttotalpacketsinfile:%d\t" + //"\ttotalpacketsinfile:%d\t" "Packets Lost:%d" - "\tCurrentFrameNumber:%lld\tPreviousFrameNumber:%lld" + //"\tCurrentFrameNumber:%lld\tPreviousFrameNumber:%lld" "\n", ithread,completeFileName[ithread], - totalPacketsInFile[ithread], + //totalPacketsInFile[ithread], ( ((int)(currentFrameNumber[ithread]-frameNumberInPreviousFile[ithread])*packetsPerFrame) - totalPacketsInFile[ithread]) - ,currentFrameNumber[ithread],frameNumberInPreviousFile[ithread] + //,currentFrameNumber[ithread],frameNumberInPreviousFile[ithread] ); } closeFile(ithread); From 48ae4b4ec2c396392c43d2360e7b6c0167b5310c Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Thu, 3 Nov 2016 14:21:51 +0100 Subject: [PATCH 369/474] progress bug --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index c1e30700d..9ad7fc966 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -2876,9 +2876,9 @@ void UDPStandardImplementation::handleWithoutMissingPackets(int ithread, char* w //get current frame number uint64_t tempframenumber; tempframenumber = (*((uint32_t*)(wbuffer+HEADER_SIZE_NUM_TOT_PACKETS))); - cout<<"handling: before frame number:"< Date: Thu, 3 Nov 2016 14:22:37 +0100 Subject: [PATCH 370/474] progress bug --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 9ad7fc966..7f903e31a 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -2898,7 +2898,7 @@ void UDPStandardImplementation::handleWithoutMissingPackets(int ithread, char* w totalWritingPacketCount[ithread] += npackets; lastFrameNumberInFile[ithread] = tempframenumber; currentFrameNumber[ithread] = tempframenumber; - cout<<"curentframenumber:"< 1) pthread_mutex_lock(&writeMutex); From 68241924a53b7972a8c517551e83cd2b17f29f41 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Thu, 3 Nov 2016 14:22:48 +0100 Subject: [PATCH 371/474] progress bug --- slsReceiverSoftware/include/sls_receiver_defs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/slsReceiverSoftware/include/sls_receiver_defs.h b/slsReceiverSoftware/include/sls_receiver_defs.h index fb8fbda2f..ce0fad9fa 100755 --- a/slsReceiverSoftware/include/sls_receiver_defs.h +++ b/slsReceiverSoftware/include/sls_receiver_defs.h @@ -24,7 +24,7 @@ typedef int int32_t; #define SHORT_MAX_FRAMES_PER_FILE 100000 #define MOENCH_MAX_FRAMES_PER_FILE 1000 #define EIGER_MAX_FRAMES_PER_FILE 2000 -#define JFRAU_MAX_FRAMES_PER_FILE 5 +#define JFRAU_MAX_FRAMES_PER_FILE 10000 #define JFCTB_MAX_FRAMES_PER_FILE 100000 From f865026c3d236f240ee3e2982d7f197563fc44cc Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Thu, 3 Nov 2016 15:08:18 +0100 Subject: [PATCH 372/474] lastframe number bug --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 7f903e31a..587662ce9 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -2782,9 +2782,10 @@ void UDPStandardImplementation::stopWriting(int ithread, char* wbuffer){ cprintf(RED, "Packets Caught \t\t: %lld\n",(long long int)totalWritingPacketCount[i]); cprintf(RED, "Frames Caught \t\t: %lld\n",(long long int)(totalWritingPacketCount[i]/packetsPerFrame)); int64_t lastFrameNumber = 0; - lastFrameNumber = lastFrameNumberInFile[i] - startFrameIndex;//lastFrameNumberInFile updated even if not written + lastFrameNumber = lastFrameNumberInFile[i];//lastFrameNumberInFile updated even if not written if(myDetectorType == EIGER) - lastFrameNumber+= 1; + lastFrameNumber= lastFrameNumberInFile[i] - startFrameIndex + 1; + cprintf(RED, "Last Frame Number Caught :%lld\n",(long long int)lastFrameNumber); }else{ cprintf(GREEN, "\nPort %d\n",udpPortNum[i]); @@ -2796,9 +2797,9 @@ void UDPStandardImplementation::stopWriting(int ithread, char* wbuffer){ cprintf(GREEN, "Packets Caught \t\t: %lld\n",(long long int)totalWritingPacketCount[i]); cprintf(GREEN, "Frames Caught \t\t: %lld\n",(long long int)(totalWritingPacketCount[i]/packetsPerFrame)); int64_t lastFrameNumber = 0; - lastFrameNumber = lastFrameNumberInFile[i] - startFrameIndex;//lastFrameNumberInFile updated even if not written + lastFrameNumber = lastFrameNumberInFile[i];//lastFrameNumberInFile updated even if not written if(myDetectorType == EIGER) - lastFrameNumber+= 1; + lastFrameNumber= lastFrameNumberInFile[i] - startFrameIndex + 1; cprintf(GREEN, "Last Frame Number Caught: %lld\n",(long long int)lastFrameNumber); } From 8b6689e167068438c9688c5d78a599820ef8c103 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Thu, 3 Nov 2016 15:49:32 +0100 Subject: [PATCH 373/474] moved an offset to get data --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 587662ce9..d58689ce9 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -828,7 +828,7 @@ int UDPStandardImplementation::setDetectorType(const detectorType d){ packetsPerFrame = JFRAU_PACKETS_PER_FRAME; onePacketSize = JFRAU_ONE_PACKET_SIZE; oneDataSize = JFRAU_ONE_DATA_SIZE; - bufferSize = JFRAU_BUFFER_SIZE; + bufferSize = oneDataSize * packetsPerFrame; frameIndexMask = JFRAU_FRAME_INDEX_MASK; frameIndexOffset = JFRAU_FRAME_INDEX_OFFSET; packetIndexMask = JFRAU_PACKET_INDEX_MASK; @@ -2146,7 +2146,7 @@ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int cSize, ch //cout<<"current fnum:"<<(*((uint32_t*)(buffer[ithread]+8)))< Date: Thu, 3 Nov 2016 16:04:24 +0100 Subject: [PATCH 374/474] number of data call back threads made equal to numberoflistening threads --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index d58689ce9..633b6c823 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -574,7 +574,7 @@ uint32_t UDPStandardImplementation::setDataStreamEnable(const uint32_t enable){ createDataCallbackThreads(true); if(dataStreamEnable){ - numberofDataCallbackThreads = MAX_NUMBER_OF_LISTENING_THREADS; + numberofDataCallbackThreads = numberofListeningThreads; if(createDataCallbackThreads() == FAIL){ cprintf(BG_RED,"Error: Could not create data callback threads\n"); } @@ -865,7 +865,7 @@ int UDPStandardImplementation::setDetectorType(const detectorType d){ numberofJobsPerBuffer = -1; setupFifoStructure(); - numberofDataCallbackThreads = MAX_NUMBER_OF_LISTENING_THREADS; + numberofDataCallbackThreads = numberofListeningThreads; if(dataStreamEnable) createDataCallbackThreads(); From a659fa96dcbe89b11343a037c37a9f3cd9a62a9b Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Thu, 3 Nov 2016 16:21:50 +0100 Subject: [PATCH 375/474] debugging gui --- .../src/UDPStandardImplementation.cpp | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 633b6c823..372f7ac48 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1761,9 +1761,9 @@ void UDPStandardImplementation::startDataCallback(){ //send final header //update frame details -#ifdef DEBUG +//#ifdef DEBUG cout << "sending dummy" << endl; -#endif +//#endif frameIndex = -9; acquisitionIndex = -9; subframeIndex = -9; @@ -1771,14 +1771,14 @@ void UDPStandardImplementation::startDataCallback(){ zmq_send(zmqsocket, buf,len, ZMQ_SNDMORE); //send final data zmq_send (zmqsocket, "end", 3, 0); - + cout<<"dummy sent"< Date: Thu, 3 Nov 2016 16:26:41 +0100 Subject: [PATCH 376/474] something --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 372f7ac48..82e56e382 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1800,15 +1800,16 @@ void UDPStandardImplementation::startDataCallback(){ if(myDetectorType == JUNGFRAU){ //send header //update frame details - frameIndex = (*((uint32_t*)(latestData[ithread]))); + frameIndex = (*((uint32_t*)(latestData[ithread]))) - startFrameIndex; cout<<"frameindex:"< Date: Thu, 3 Nov 2016 16:33:44 +0100 Subject: [PATCH 377/474] something --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 82e56e382..9715884c9 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1805,6 +1805,7 @@ void UDPStandardImplementation::startDataCallback(){ acquisitionIndex = frameIndex - startAcquisitionIndex; subframeIndex = -1; int len = sprintf(buf,jsonFmt,type,shape, acquisitionIndex, frameIndex, subframeIndex,completeFileName[ithread]); + cout<<"buf:"< Date: Thu, 3 Nov 2016 16:39:14 +0100 Subject: [PATCH 378/474] something --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 9715884c9..89c85c8ba 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1806,7 +1806,7 @@ void UDPStandardImplementation::startDataCallback(){ subframeIndex = -1; int len = sprintf(buf,jsonFmt,type,shape, acquisitionIndex, frameIndex, subframeIndex,completeFileName[ithread]); cout<<"buf:"< Date: Thu, 3 Nov 2016 17:06:02 +0100 Subject: [PATCH 379/474] trying different machine zmq --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 89c85c8ba..2ae3ccbbe 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1801,12 +1801,10 @@ void UDPStandardImplementation::startDataCallback(){ //send header //update frame details frameIndex = (*((uint32_t*)(latestData[ithread]))) - startFrameIndex; - cout<<"frameindex:"< Date: Thu, 3 Nov 2016 17:12:41 +0100 Subject: [PATCH 380/474] trying different machine zmq --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 2ae3ccbbe..97f6c842a 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1671,7 +1671,7 @@ void UDPStandardImplementation::startDataCallback(){ struct timespec begin,end; // server address to bind - char hostName[100] = "tcp://127.0.0.1:"; + char hostName[100] = "tcp://*:";//"tcp://127.0.0.1:"; int portno = DEFAULT_ZMQ_PORTNO + (detID*numberofListeningThreads+ithread); sprintf(hostName,"%s%d",hostName,portno); From 44eb790f2d1c814ccf8ed9df7bffc05b0b9fb59d Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Thu, 3 Nov 2016 17:16:53 +0100 Subject: [PATCH 381/474] trying different machine zmq --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 97f6c842a..a52ca1ae3 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1682,7 +1682,7 @@ void UDPStandardImplementation::startDataCallback(){ zmq_setsockopt(zmqsocket, ZMQ_LINGER, &val,sizeof(val)); // wait for the unsent packets before closing socket //val = 10; //zmq_setsockopt(zmqsocket,ZMQ_SNDHWM,&val,sizeof(val)); //set SEND HIGH WATER MARK (8-9ms slower) - zmq_bind(zmqsocket,hostName); // bind + cprintf(RED,"bind ret: %d\n",zmq_bind(zmqsocket,hostName)); // bind FILE_LOG(logINFO) << "Thread" << ithread << ": ZMQ Server at " << hostName; From 78c1372950b66fe842830a3dbb90bac3cbfdf73e Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Fri, 4 Nov 2016 10:20:30 +0100 Subject: [PATCH 382/474] trying different machine zmq --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index a52ca1ae3..6d5fc6168 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1801,7 +1801,7 @@ void UDPStandardImplementation::startDataCallback(){ //send header //update frame details frameIndex = (*((uint32_t*)(latestData[ithread]))) - startFrameIndex; - acquisitionIndex = frameIndex - startAcquisitionIndex; + acquisitionIndex = (*((uint32_t*)(latestData[ithread]))) - startAcquisitionIndex; subframeIndex = -1; int len = sprintf(buf,jsonFmt,type,shape, acquisitionIndex, frameIndex, subframeIndex,completeFileName[ithread]); zmq_send(zmqsocket, buf,len, ZMQ_SNDMORE); From d4733543ab0f5d48346ae386316b69d696faa3f6 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Fri, 4 Nov 2016 10:25:00 +0100 Subject: [PATCH 383/474] trying different machine zmq --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 6d5fc6168..537f3f195 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -2735,14 +2735,14 @@ void UDPStandardImplementation::stopWriting(int ithread, char* wbuffer){ if(totalWritingPacketCount[ithread]){ printf("\nThread:%d File:%s\n" - //"\ttotalpacketsinfile:%d\t" + "\ttotalpacketsinfile:%d\t" "Packets Lost:%d" - //"\tCurrentFrameNumber:%lld\tPreviousFrameNumber:%lld" + "\tCurrentFrameNumber:%lld\tPreviousFrameNumber:%lld" "\n", ithread,completeFileName[ithread], - //totalPacketsInFile[ithread], + totalPacketsInFile[ithread], ( ((int)(currentFrameNumber[ithread]-frameNumberInPreviousFile[ithread])*packetsPerFrame) - totalPacketsInFile[ithread]) - //,currentFrameNumber[ithread],frameNumberInPreviousFile[ithread] + ,currentFrameNumber[ithread],frameNumberInPreviousFile[ithread] ); } closeFile(ithread); From 11d35114609cad3ab705afdfcec6ab3e3b9767b7 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Fri, 4 Nov 2016 11:03:24 +0100 Subject: [PATCH 384/474] trying different machine zmq --- .../src/UDPStandardImplementation.cpp | 82 ++++++++++--------- 1 file changed, 42 insertions(+), 40 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 537f3f195..0a89c0b95 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -84,12 +84,12 @@ void UDPStandardImplementation::deleteMembers(){ //filter deleteFilter(); for(int i=0; igetSemValue(),(void*)(buffer[i])); } delete fifoFree[i]; - fifoFree[i] = NULL; + fifoFree[i] = 0; } if(fifo[i]){ while(!fifo[i]->isEmpty()){ @@ -357,11 +357,11 @@ int UDPStandardImplementation::setupFifoStructure(){ //cprintf(CYAN,"Fifo[%d]: value:%d, pop 0x%x\n",i,fifo[i]->getSemValue(),(void*)(buffer[i])); } delete fifo[i]; - fifo[i] = NULL; + fifo[i] = 0; } - if(mem0[i]){ + if(!mem0[i]){ free(mem0[i]); - mem0[i] = NULL; + mem0[i] = 0; } //creating @@ -370,7 +370,7 @@ int UDPStandardImplementation::setupFifoStructure(){ //allocate memory mem0[i] = (char*)malloc((bufferSize * numberofJobsPerBuffer + fifoBufferHeaderSize) * fifoSize); - if (mem0[i] == NULL){ + if (mem0[i]){ cprintf(BG_RED,"Error: Could not allocate memory for listening \n"); return FAIL; } @@ -633,7 +633,7 @@ int UDPStandardImplementation::setDynamicRange(const uint32_t i){ //gui buffer for(int i=0;iShutDownSocket(); FILE_LOG(logINFO) << "Shut down UDP Socket " << i; delete udpSocket[i]; - udpSocket[i] = NULL; + udpSocket[i] = 0; } } return OK; @@ -1178,7 +1178,7 @@ void UDPStandardImplementation::closeFile(int ithread){ FILE_LOG(logDEBUG4) << "Going to close file: " << fileno(sfilefd)); #endif fclose(sfilefd[ithread]); - sfilefd[ithread] = NULL; + sfilefd[ithread] = 0; } } @@ -1190,7 +1190,7 @@ void UDPStandardImplementation::closeFile(int ithread){ FILE_LOG(logDEBUG4) << "sfilefd: " << (int)sfilefd[i]; #endif fclose(sfilefd[0]); - sfilefd[0] = NULL; + sfilefd[0] = 0; } #endif @@ -1211,10 +1211,10 @@ void UDPStandardImplementation::closeFile(int ithread){ //close file if(myTree[ithread] && myFile[ithread]) myFile[ithread] = myTree[ithread]->GetCurrentFile(); - if(myFile[ithread] != NULL) + if(myFile[ithread] != 0) myFile[ithread]->Close(); - myFile[ithread] = NULL; - myTree[ithread] = NULL; + myFile[ithread] = 0; + myTree[ithread] = 0; pthread_mutex_unlock(&writeMutex); #endif @@ -1554,17 +1554,19 @@ int UDPStandardImplementation::createNewFile(int ithread){ //close file pointers if(sfilefd[ithread]){ fclose(sfilefd[ithread]); - sfilefd[ithread] = NULL; + sfilefd[ithread] = 0; } //create file if(!overwriteEnable){ if (NULL == (sfilefd[ithread] = fopen((const char *) (completeFileName[ithread]), "wx"))){ FILE_LOG(logERROR) << "Could not create/overwrite file" << completeFileName[ithread]; + sfilefd[ithread] = 0; return FAIL; } }else if (NULL == (sfilefd[ithread] = fopen((const char *) (completeFileName[ithread]), "w"))){ FILE_LOG(logERROR) << "Could not create file" << completeFileName[ithread]; + sfilefd[ithread] = 0; return FAIL; } //setting file buffer size to 16mb @@ -1961,7 +1963,7 @@ void UDPStandardImplementation::startListening(){ uint32_t rc; //size of buffer received in bytes //split frames for data compression int carryonBufferSize; //from previous buffer to keep frames together in a buffer - char* tempBuffer = NULL; //temporary buffer to store split frames + char* tempBuffer = 0; //temporary buffer to store split frames /* outer loop - loops once for each acquisition */ @@ -1971,7 +1973,7 @@ void UDPStandardImplementation::startListening(){ //compression variables reset before acquisition carryonBufferSize = 0; if(dataCompressionEnable){ - if(tempBuffer!=NULL){delete []tempBuffer;tempBuffer=NULL;} + if(tempBuffer){delete []tempBuffer;tempBuffer=0;} tempBuffer = new char[onePacketSize * (packetsPerFrame - 1)]; //store maximum of 1 packets less in a frame } @@ -1996,7 +1998,7 @@ void UDPStandardImplementation::startListening(){ //udpsocket doesnt exist - if(activated && udpSocket[ithread] == NULL){ + if(activated && !udpSocket[ithread]){ FILE_LOG(logERROR) << "Listening_Thread " << ithread << ": UDP Socket not created or shut down earlier"; stopListening(ithread,0); continue; @@ -2523,7 +2525,7 @@ void UDPStandardImplementation::startWriting(){ //variable definitions char* wbuf; //buffer popped from FIFO - sfilefd[ithread] = NULL; //file pointer + sfilefd[ithread] = 0; //file pointer uint64_t nf; //for compression, number of frames int listenfifoIndex = ithread; From ff1b2ac19a30a2dcbf6975ccb3167193c9afd06c Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Fri, 4 Nov 2016 11:24:19 +0100 Subject: [PATCH 385/474] solving latestdata crash --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 0a89c0b95..5725996c3 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -632,8 +632,10 @@ int UDPStandardImplementation::setDynamicRange(const uint32_t i){ if(oldDynamicRange != dynamicRange){ //gui buffer - for(int i=0;i Date: Fri, 4 Nov 2016 12:12:06 +0100 Subject: [PATCH 386/474] memry allcation --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 5725996c3..2edaaa9f2 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -359,7 +359,7 @@ int UDPStandardImplementation::setupFifoStructure(){ delete fifo[i]; fifo[i] = 0; } - if(!mem0[i]){ + if(mem0[i]){ free(mem0[i]); mem0[i] = 0; } From 947a0e5f414cf3c3413ea78bed8079ad918ed513 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Fri, 4 Nov 2016 12:15:47 +0100 Subject: [PATCH 387/474] memry allcation --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 2edaaa9f2..6104f0928 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -370,7 +370,7 @@ int UDPStandardImplementation::setupFifoStructure(){ //allocate memory mem0[i] = (char*)malloc((bufferSize * numberofJobsPerBuffer + fifoBufferHeaderSize) * fifoSize); - if (mem0[i]){ + if (mem0[i] == NULL){ cprintf(BG_RED,"Error: Could not allocate memory for listening \n"); return FAIL; } From e2299b526955e48ccca8c2d591db43e71dabc169 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Fri, 4 Nov 2016 13:49:16 +0100 Subject: [PATCH 388/474] removed prints --- .../src/UDPStandardImplementation.cpp | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 6104f0928..924f44125 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1761,7 +1761,6 @@ void UDPStandardImplementation::startDataCallback(){ zmq_send(zmqsocket, buf,len, ZMQ_SNDMORE); //send data zmq_send(zmqsocket, buffer, oneframesize, 0); - cout<<"sent last dummy"< Date: Fri, 4 Nov 2016 14:09:19 +0100 Subject: [PATCH 389/474] removed prints --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 924f44125..2b73491c1 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1582,6 +1582,7 @@ int UDPStandardImplementation::createNewFile(int ithread){ //Print packet loss and filenames if(!totalWritingPacketCount[ithread]){ frameNumberInPreviousFile[ithread] = -1; + cprintf(RED,"frameNumberInPreviousFile:%d\n",frameNumberInPreviousFile[ithread]); //printf("Thread:%d File:%s\n",ithread,completeFileName[ithread]); }else{ @@ -2739,14 +2740,14 @@ void UDPStandardImplementation::stopWriting(int ithread, char* wbuffer){ if(totalWritingPacketCount[ithread]){ printf("\nThread:%d File:%s\n" - "\ttotalpacketsinfile:%d\t" + //"\ttotalpacketsinfile:%d\t" "Packets Lost:%d" - "\tCurrentFrameNumber:%lld\tPreviousFrameNumber:%lld" + //"\tCurrentFrameNumber:%lld\tPreviousFrameNumber:%lld" "\n", ithread,completeFileName[ithread], - totalPacketsInFile[ithread], + //totalPacketsInFile[ithread], ( ((int)(currentFrameNumber[ithread]-frameNumberInPreviousFile[ithread])*packetsPerFrame) - totalPacketsInFile[ithread]) - ,currentFrameNumber[ithread],frameNumberInPreviousFile[ithread] + //,currentFrameNumber[ithread],frameNumberInPreviousFile[ithread] ); } closeFile(ithread); From d6733676670474a0fc83a88f5e78c16cdf233e12 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Fri, 4 Nov 2016 14:11:31 +0100 Subject: [PATCH 390/474] removed prints --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 2b73491c1..f1587f0f0 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1578,7 +1578,7 @@ int UDPStandardImplementation::createNewFile(int ithread){ //setting file buffer size to 16mb setvbuf(sfilefd[ithread],NULL,_IOFBF,BUF_SIZE); - + cprintf(RED,"totalWritingPacketCount:%d\n",totalWritingPacketCount[ithread]); //Print packet loss and filenames if(!totalWritingPacketCount[ithread]){ frameNumberInPreviousFile[ithread] = -1; From 57979ce9709e8581b5aae52fec0fa4510ad0465b Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Fri, 4 Nov 2016 14:17:51 +0100 Subject: [PATCH 391/474] removed prints --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index f1587f0f0..adc69e92f 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1541,7 +1541,7 @@ int UDPStandardImplementation::setupWriter(){ -int UDPStandardImplementation::createNewFile(int ithread){ +int UDPStandardImplementation::createNewFile(int ithread){ cprintf(RED,"createnewfile:\n"); FILE_LOG(logDEBUG) << __AT__ << " called"; //create file name From 3f9c5af61ca7653a569a3cf7a3d7b90c22e148b1 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Fri, 4 Nov 2016 14:19:49 +0100 Subject: [PATCH 392/474] removed prints --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index adc69e92f..4eb22d5d9 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1555,14 +1555,14 @@ int UDPStandardImplementation::createNewFile(int ithread){ cprintf(RED,"createne #endif //filewrite enable & we allowed to create/close files - if(fileWriteEnable && cbAction > DO_NOTHING){ + if(fileWriteEnable && cbAction > DO_NOTHING){cprintf(RED,"createnewfile11:\n"); //close file pointers if(sfilefd[ithread]){ fclose(sfilefd[ithread]); sfilefd[ithread] = 0; } - + cprintf(RED,"createnewfile 222:\n"); //create file if(!overwriteEnable){ if (NULL == (sfilefd[ithread] = fopen((const char *) (completeFileName[ithread]), "wx"))){ From 6df77b5ff27ece7cf3aa42fd4ba21fb065df4057 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Fri, 4 Nov 2016 14:21:59 +0100 Subject: [PATCH 393/474] removed prints --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 4eb22d5d9..42fc3524b 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1553,6 +1553,7 @@ int UDPStandardImplementation::createNewFile(int ithread){ cprintf(RED,"createne #ifdef DEBUG4 FILE_LOG(logINFO) << completefileName; #endif + cprintf(RED,"fileWriteEnable:%d cbAction:%d\n",fileWriteEnable,cbAction); //filewrite enable & we allowed to create/close files if(fileWriteEnable && cbAction > DO_NOTHING){cprintf(RED,"createnewfile11:\n"); From ede6ccd720f205d23d190eee4d888ec4105af64e Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Fri, 4 Nov 2016 14:23:46 +0100 Subject: [PATCH 394/474] removed prints --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 42fc3524b..2cc472506 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1541,7 +1541,7 @@ int UDPStandardImplementation::setupWriter(){ -int UDPStandardImplementation::createNewFile(int ithread){ cprintf(RED,"createnewfile:\n"); +int UDPStandardImplementation::createNewFile(int ithread){ FILE_LOG(logDEBUG) << __AT__ << " called"; //create file name @@ -1553,7 +1553,6 @@ int UDPStandardImplementation::createNewFile(int ithread){ cprintf(RED,"createne #ifdef DEBUG4 FILE_LOG(logINFO) << completefileName; #endif - cprintf(RED,"fileWriteEnable:%d cbAction:%d\n",fileWriteEnable,cbAction); //filewrite enable & we allowed to create/close files if(fileWriteEnable && cbAction > DO_NOTHING){cprintf(RED,"createnewfile11:\n"); @@ -1579,11 +1578,9 @@ int UDPStandardImplementation::createNewFile(int ithread){ cprintf(RED,"createne //setting file buffer size to 16mb setvbuf(sfilefd[ithread],NULL,_IOFBF,BUF_SIZE); - cprintf(RED,"totalWritingPacketCount:%d\n",totalWritingPacketCount[ithread]); //Print packet loss and filenames if(!totalWritingPacketCount[ithread]){ frameNumberInPreviousFile[ithread] = -1; - cprintf(RED,"frameNumberInPreviousFile:%d\n",frameNumberInPreviousFile[ithread]); //printf("Thread:%d File:%s\n",ithread,completeFileName[ithread]); }else{ @@ -1608,7 +1605,8 @@ int UDPStandardImplementation::createNewFile(int ithread){ cprintf(RED,"createne if(totalWritingPacketCount[ithread]){ frameNumberInPreviousFile[ithread] = currentFrameNumber[ithread]; totalPacketsInFile[ithread] = 0; - } + }else + frameNumberInPreviousFile[ithread] = -1; From 3a3e2e26d8462484d675af3fe07e00944e51caec Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Mon, 7 Nov 2016 10:29:56 +0100 Subject: [PATCH 395/474] to see the receiver output --- slsReceiverSoftware/src/main.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/slsReceiverSoftware/src/main.cpp b/slsReceiverSoftware/src/main.cpp index a005f569d..7644287fd 100644 --- a/slsReceiverSoftware/src/main.cpp +++ b/slsReceiverSoftware/src/main.cpp @@ -7,6 +7,7 @@ #include #include #include //SIGINT +#include //system #include "utilities.h" #include "logger.h" @@ -49,6 +50,8 @@ int main(int argc, char *argv[]) { //Catch signal SIGINT to close files properly signal(SIGINT,closeFile); + system("setterm -term linux -back black"); + int ret = slsReceiverDefs::OK; receiver = new slsReceiverUsers(argc, argv, ret); From a17e65c22f81aadaf29651536f2101f094a0c930 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Mon, 7 Nov 2016 10:55:09 +0100 Subject: [PATCH 396/474] switched background to white, used dark gray with bold option for info text --- slsReceiverSoftware/include/ansi.h | 1 + slsReceiverSoftware/include/logger.h | 2 +- slsReceiverSoftware/src/main.cpp | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/slsReceiverSoftware/include/ansi.h b/slsReceiverSoftware/include/ansi.h index 210491373..c28be61d4 100644 --- a/slsReceiverSoftware/include/ansi.h +++ b/slsReceiverSoftware/include/ansi.h @@ -5,6 +5,7 @@ #define MAGENTA "\x1b[35m" #define CYAN "\x1b[36m" #define GRAY "\x1b[37m" +#define DARKGRAY "\x1b[30m" #define BG_RED "\x1b[41m" #define BG_GREEN "\x1b[42m" #define BG_YELLOW "\x1b[43m" diff --git a/slsReceiverSoftware/include/logger.h b/slsReceiverSoftware/include/logger.h index 7732abffc..aeb2ebd79 100644 --- a/slsReceiverSoftware/include/logger.h +++ b/slsReceiverSoftware/include/logger.h @@ -222,7 +222,7 @@ inline void Output2FILE::Output(const std::string& msg, TLogLevel level) switch(level){ case logERROR: cprintf(RED BOLD,"%s",msg.c_str()); break; case logWARNING: cprintf(YELLOW BOLD,"%s",msg.c_str()); break; - case logINFO: cprintf(GRAY,"%s",msg.c_str()); break; + case logINFO: cprintf(DARKGRAY BOLD,"%s",msg.c_str()); break; default: fprintf(pStream,"%s",msg.c_str()); break; } fflush(pStream); diff --git a/slsReceiverSoftware/src/main.cpp b/slsReceiverSoftware/src/main.cpp index 7644287fd..6f175e3e0 100644 --- a/slsReceiverSoftware/src/main.cpp +++ b/slsReceiverSoftware/src/main.cpp @@ -50,7 +50,7 @@ int main(int argc, char *argv[]) { //Catch signal SIGINT to close files properly signal(SIGINT,closeFile); - system("setterm -term linux -back black"); + system("setterm -background white"); int ret = slsReceiverDefs::OK; receiver = new slsReceiverUsers(argc, argv, ret); From 96284fde8748bfb9561aa67fb847ee47aaa312d1 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Mon, 7 Nov 2016 11:19:20 +0100 Subject: [PATCH 397/474] for now, leaving as before the background colors --- slsReceiverSoftware/include/logger.h | 3 ++- slsReceiverSoftware/src/main.cpp | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/slsReceiverSoftware/include/logger.h b/slsReceiverSoftware/include/logger.h index aeb2ebd79..53e6ead8f 100644 --- a/slsReceiverSoftware/include/logger.h +++ b/slsReceiverSoftware/include/logger.h @@ -222,7 +222,8 @@ inline void Output2FILE::Output(const std::string& msg, TLogLevel level) switch(level){ case logERROR: cprintf(RED BOLD,"%s",msg.c_str()); break; case logWARNING: cprintf(YELLOW BOLD,"%s",msg.c_str()); break; - case logINFO: cprintf(DARKGRAY BOLD,"%s",msg.c_str()); break; + case logINFO: cprintf(GRAY,"%s",msg.c_str());break; + // case logINFO: cprintf(DARKGRAY BOLD,"%s",msg.c_str());break; default: fprintf(pStream,"%s",msg.c_str()); break; } fflush(pStream); diff --git a/slsReceiverSoftware/src/main.cpp b/slsReceiverSoftware/src/main.cpp index 6f175e3e0..b4e5ef142 100644 --- a/slsReceiverSoftware/src/main.cpp +++ b/slsReceiverSoftware/src/main.cpp @@ -50,7 +50,7 @@ int main(int argc, char *argv[]) { //Catch signal SIGINT to close files properly signal(SIGINT,closeFile); - system("setterm -background white"); + //system("setterm -linux term -background white -clear"); int ret = slsReceiverDefs::OK; receiver = new slsReceiverUsers(argc, argv, ret); From 1825ebd42659644f0a41ac48a5e8a100873dcc1e Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Mon, 7 Nov 2016 11:21:12 +0100 Subject: [PATCH 398/474] for now, leaving as before the background colors --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 2cc472506..6730c96c8 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1555,14 +1555,14 @@ int UDPStandardImplementation::createNewFile(int ithread){ #endif //filewrite enable & we allowed to create/close files - if(fileWriteEnable && cbAction > DO_NOTHING){cprintf(RED,"createnewfile11:\n"); + if(fileWriteEnable && cbAction > DO_NOTHING){ //close file pointers if(sfilefd[ithread]){ fclose(sfilefd[ithread]); sfilefd[ithread] = 0; } - cprintf(RED,"createnewfile 222:\n"); + //create file if(!overwriteEnable){ if (NULL == (sfilefd[ithread] = fopen((const char *) (completeFileName[ithread]), "wx"))){ From c6dbeda8b7e58ee3f9c3f8852641057943da3423 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 8 Nov 2016 09:03:07 +0100 Subject: [PATCH 399/474] debugging --- slsReceiverSoftware/include/genericSocket.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/slsReceiverSoftware/include/genericSocket.h b/slsReceiverSoftware/include/genericSocket.h index 2f75a985b..d44365f2e 100644 --- a/slsReceiverSoftware/include/genericSocket.h +++ b/slsReceiverSoftware/include/genericSocket.h @@ -618,11 +618,12 @@ enum communicationProtocol{ /*int k = 0;*/ while(length>0){ + cprintf(RED,"packet_size:%d Length:%d nsending:%d\n",packet_size,length,nsending); nsending = (length>packet_size) ? packet_size:length; nsent = recvfrom(socketDescriptor,(char*)buf+total_sent,nsending, 0, (struct sockaddr *) &clientAddress, &clientAddress_length); if(nsent != nsending){ //if((nsent != nsending)){ && (nsent < packet_size)){ if(nsent && (nsent != header_packet_size) && (nsent != -1)) - cprintf(RED,"Incomplete Packet size %d\n",nsent); + cprintf(RED,"packet_size:%d Length:%d nsending:%d Incomplete Packet size %d\n",packet_size,length,nsending,nsent); break; } length-=nsent; From 8fd1b9b61716c40ce2f5881a40a821262cb36e1a Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 8 Nov 2016 09:08:09 +0100 Subject: [PATCH 400/474] debugging --- slsReceiverSoftware/include/genericSocket.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/slsReceiverSoftware/include/genericSocket.h b/slsReceiverSoftware/include/genericSocket.h index d44365f2e..d328f6ecd 100644 --- a/slsReceiverSoftware/include/genericSocket.h +++ b/slsReceiverSoftware/include/genericSocket.h @@ -177,7 +177,7 @@ enum communicationProtocol{ total_sent(0), header_packet_size(hsize) { - +cprintf(RED,"packet_soze:%d\n",packet_size); /* // you can specify an IP address: */ /* // or you can let it automatically select one: */ /* myaddr.sin_addr.s_addr = INADDR_ANY; */ @@ -618,12 +618,11 @@ enum communicationProtocol{ /*int k = 0;*/ while(length>0){ - cprintf(RED,"packet_size:%d Length:%d nsending:%d\n",packet_size,length,nsending); nsending = (length>packet_size) ? packet_size:length; nsent = recvfrom(socketDescriptor,(char*)buf+total_sent,nsending, 0, (struct sockaddr *) &clientAddress, &clientAddress_length); if(nsent != nsending){ //if((nsent != nsending)){ && (nsent < packet_size)){ if(nsent && (nsent != header_packet_size) && (nsent != -1)) - cprintf(RED,"packet_size:%d Length:%d nsending:%d Incomplete Packet size %d\n",packet_size,length,nsending,nsent); + cprintf(RED,"Incomplete Packet size %d\n",nsent); break; } length-=nsent; From a5c4434ae812c3b5215fb5cefae4e8d4a0b2309a Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 8 Nov 2016 09:18:32 +0100 Subject: [PATCH 401/474] debugging --- slsReceiverSoftware/include/genericSocket.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/slsReceiverSoftware/include/genericSocket.h b/slsReceiverSoftware/include/genericSocket.h index d328f6ecd..ef2d58e7c 100644 --- a/slsReceiverSoftware/include/genericSocket.h +++ b/slsReceiverSoftware/include/genericSocket.h @@ -492,7 +492,7 @@ cprintf(RED,"packet_soze:%d\n",packet_size); }; - int setPacketSize(int i=-1) { if (i>=0) packet_size=i; return packet_size;}; + int setPacketSize(int i=-1) { if (i>=0) packet_size=i;cprintf(RED,"changed packet_soze:%d\n",packet_size); return packet_size;}; From 01db6b988b3fd5989819452479fe151c5bf1a898 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 8 Nov 2016 09:22:18 +0100 Subject: [PATCH 402/474] debugging --- slsReceiverSoftware/include/genericSocket.h | 2 +- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/slsReceiverSoftware/include/genericSocket.h b/slsReceiverSoftware/include/genericSocket.h index ef2d58e7c..c52eba455 100644 --- a/slsReceiverSoftware/include/genericSocket.h +++ b/slsReceiverSoftware/include/genericSocket.h @@ -611,7 +611,7 @@ cprintf(RED,"packet_soze:%d\n",packet_size); break; case UDP: if (socketDescriptor<0) return -1; - +cprintf(RED,"length:%d packetsize:%d\n",length,packet_size); //if length given, listens to length, else listens for packetsize till length is reached if(length){ diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 6730c96c8..992391d72 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -2133,7 +2133,7 @@ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int cSize, ch int currentfnum=-1; //read first packet - receivedSize = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + offset, onePacketSize); + receivedSize = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + offset); if(!receivedSize) return 0; header = (jfrau_packet_header_t*)(buffer[ithread] + offset); currentpnum = (*( (uint8_t*) header->packetNumber)); @@ -2159,7 +2159,7 @@ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int cSize, ch break; pnum --; - receivedSize = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + offset, onePacketSize); + receivedSize = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + offset); if(!receivedSize){ totalIgnoredPacketCount[ithread] += (packetsPerFrame - pnum); return 0; @@ -2180,7 +2180,7 @@ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int cSize, ch //find the start of next image while(currentpnum != pnum){ totalIgnoredPacketCount[ithread]++; - receivedSize = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + offset, onePacketSize); + receivedSize = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + offset); if(!receivedSize) return 0; header = (jfrau_packet_header_t*)(buffer[ithread] + offset); currentpnum = (*( (uint8_t*) header->packetNumber)); From cbd077e984d9b23b48357f0a243ff32a42a8fb67 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 8 Nov 2016 09:28:05 +0100 Subject: [PATCH 403/474] debugging --- slsReceiverSoftware/include/genericSocket.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/slsReceiverSoftware/include/genericSocket.h b/slsReceiverSoftware/include/genericSocket.h index c52eba455..a513337df 100644 --- a/slsReceiverSoftware/include/genericSocket.h +++ b/slsReceiverSoftware/include/genericSocket.h @@ -177,7 +177,7 @@ enum communicationProtocol{ total_sent(0), header_packet_size(hsize) { -cprintf(RED,"packet_soze:%d\n",packet_size); + /* // you can specify an IP address: */ /* // or you can let it automatically select one: */ /* myaddr.sin_addr.s_addr = INADDR_ANY; */ @@ -611,7 +611,6 @@ cprintf(RED,"packet_soze:%d\n",packet_size); break; case UDP: if (socketDescriptor<0) return -1; -cprintf(RED,"length:%d packetsize:%d\n",length,packet_size); //if length given, listens to length, else listens for packetsize till length is reached if(length){ From 2eade342ad56a0672bed56b7baee6d093ea04f57 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 8 Nov 2016 09:28:56 +0100 Subject: [PATCH 404/474] debugging --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 992391d72..8bf11da73 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1050,7 +1050,7 @@ int UDPStandardImplementation::startReceiver(char *c){ void UDPStandardImplementation::stopReceiver(){ FILE_LOG(logDEBUG) << __AT__ << " called"; - FILE_LOG(logINFO) << "Stopping Receiver"; + //FILE_LOG(logINFO) << "Stopping Receiver"; //set status to transmitting startReadout(); From 9effdab69b9dd54d9560c5ea3a58d9939ca3732d Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 8 Nov 2016 09:29:42 +0100 Subject: [PATCH 405/474] debugging --- slsReceiverSoftware/include/genericSocket.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/slsReceiverSoftware/include/genericSocket.h b/slsReceiverSoftware/include/genericSocket.h index a513337df..dc304102e 100644 --- a/slsReceiverSoftware/include/genericSocket.h +++ b/slsReceiverSoftware/include/genericSocket.h @@ -492,7 +492,7 @@ enum communicationProtocol{ }; - int setPacketSize(int i=-1) { if (i>=0) packet_size=i;cprintf(RED,"changed packet_soze:%d\n",packet_size); return packet_size;}; + int setPacketSize(int i=-1) { if (i>=0) packet_size=i;return packet_size;}; From 96e79c7b993da50dcb6a9584ae333fa8c280004e Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 8 Nov 2016 09:34:56 +0100 Subject: [PATCH 406/474] debugged --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 8bf11da73..992391d72 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1050,7 +1050,7 @@ int UDPStandardImplementation::startReceiver(char *c){ void UDPStandardImplementation::stopReceiver(){ FILE_LOG(logDEBUG) << __AT__ << " called"; - //FILE_LOG(logINFO) << "Stopping Receiver"; + FILE_LOG(logINFO) << "Stopping Receiver"; //set status to transmitting startReadout(); From cb274095fd64bb3f8644e3bc22150ddbdfee0972 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 8 Nov 2016 10:19:14 +0100 Subject: [PATCH 407/474] debugging --- slsReceiverSoftware/include/logger.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/slsReceiverSoftware/include/logger.h b/slsReceiverSoftware/include/logger.h index 53e6ead8f..212a0f2f3 100644 --- a/slsReceiverSoftware/include/logger.h +++ b/slsReceiverSoftware/include/logger.h @@ -125,7 +125,7 @@ inline std::string NowTime() inline std::string NowTime() { - char buffer[11]; + char buffer[11];cout<<"111"< Log::Log():lev(logDEBUG){} template std::ostringstream& Log::Get(TLogLevel level) { lev = level; - os << "- " << NowTime(); - os << " " << ToString(level) << ": "; - os << std::string(level > logDEBUG ? level - logDEBUG : 0, '\t'); + os << "- " << NowTime();cout<<"111 "< logDEBUG ? level - logDEBUG : 0, '\t');cout<<"333 "< Date: Tue, 8 Nov 2016 10:22:31 +0100 Subject: [PATCH 408/474] debugging --- slsReceiverSoftware/include/logger.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/slsReceiverSoftware/include/logger.h b/slsReceiverSoftware/include/logger.h index 212a0f2f3..d77640286 100644 --- a/slsReceiverSoftware/include/logger.h +++ b/slsReceiverSoftware/include/logger.h @@ -145,9 +145,9 @@ template Log::Log():lev(logDEBUG){} template std::ostringstream& Log::Get(TLogLevel level) { lev = level; - os << "- " << NowTime();cout<<"111 "< logDEBUG ? level - logDEBUG : 0, '\t');cout<<"333 "< logDEBUG ? level - logDEBUG : 0, '\t'); return os; } From cb5fa6223a06096c604b0d6cf2c203ad44123a40 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 8 Nov 2016 10:24:37 +0100 Subject: [PATCH 409/474] debugging --- slsReceiverSoftware/include/logger.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/slsReceiverSoftware/include/logger.h b/slsReceiverSoftware/include/logger.h index d77640286..fa12e848a 100644 --- a/slsReceiverSoftware/include/logger.h +++ b/slsReceiverSoftware/include/logger.h @@ -125,7 +125,7 @@ inline std::string NowTime() inline std::string NowTime() { - char buffer[11];cout<<"111"< Date: Tue, 8 Nov 2016 10:28:29 +0100 Subject: [PATCH 410/474] debugging --- slsReceiverSoftware/include/logger.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/slsReceiverSoftware/include/logger.h b/slsReceiverSoftware/include/logger.h index fa12e848a..7066841e5 100644 --- a/slsReceiverSoftware/include/logger.h +++ b/slsReceiverSoftware/include/logger.h @@ -125,7 +125,7 @@ inline std::string NowTime() inline std::string NowTime() { - char buffer[100];// char buffer[11]; + char buffer[11]; time_t t; time(&t); tm r = {0}; @@ -134,6 +134,8 @@ inline std::string NowTime() gettimeofday(&tv, 0); char result[100] = {0}; sprintf(result, "%s.%03ld", buffer, (long)tv.tv_usec / 1000); + cout<<"result:"< Date: Tue, 8 Nov 2016 10:30:02 +0100 Subject: [PATCH 411/474] debugging --- slsReceiverSoftware/include/logger.h | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/slsReceiverSoftware/include/logger.h b/slsReceiverSoftware/include/logger.h index 7066841e5..162dd7668 100644 --- a/slsReceiverSoftware/include/logger.h +++ b/slsReceiverSoftware/include/logger.h @@ -125,15 +125,16 @@ inline std::string NowTime() inline std::string NowTime() { + cout<<"111"< Log::Log():lev(logDEBUG){} template std::ostringstream& Log::Get(TLogLevel level) { - lev = level; - os << "- " << NowTime(); + lev = level;cout<<"gonna do nowtime"< logDEBUG ? level - logDEBUG : 0, '\t'); return os; From 385941d75e20f714069a3164f3dd9678efe35c9c Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 8 Nov 2016 10:31:53 +0100 Subject: [PATCH 412/474] debugging --- slsReceiverSoftware/include/logger.h | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/slsReceiverSoftware/include/logger.h b/slsReceiverSoftware/include/logger.h index 162dd7668..a91dea9f4 100644 --- a/slsReceiverSoftware/include/logger.h +++ b/slsReceiverSoftware/include/logger.h @@ -125,18 +125,15 @@ inline std::string NowTime() inline std::string NowTime() { - cout<<"111"< Log::Log():lev(logDEBUG){} template std::ostringstream& Log::Get(TLogLevel level) { - lev = level;cout<<"gonna do nowtime"< logDEBUG ? level - logDEBUG : 0, '\t'); return os; From cf5978d7304b612d2634abc9634f3133713af2fc Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 8 Nov 2016 11:05:49 +0100 Subject: [PATCH 413/474] debugging --- slsReceiverSoftware/include/logger.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/slsReceiverSoftware/include/logger.h b/slsReceiverSoftware/include/logger.h index a91dea9f4..02c5c6569 100644 --- a/slsReceiverSoftware/include/logger.h +++ b/slsReceiverSoftware/include/logger.h @@ -46,6 +46,7 @@ void error(const char *location, const char *msg){ inline std::string NowTime(); enum TLogLevel {logERROR, logWARNING, logINFO, logDEBUG, logDEBUG1, logDEBUG2, logDEBUG3, logDEBUG4, logDEBUG5}; +static const char TLevelValues[] = {"ERROR", "WARNING", "INFO", "DEBUG", "DEBUG1", "DEBUG2", "DEBUG3", "DEBUG4","DEBUG5"}; template class Log{ public: @@ -169,8 +170,9 @@ template TLogLevel& Log::ReportingLevel() template std::string Log::ToString(TLogLevel level) { - static const char* const buffer[] = {"ERROR", "WARNING", "INFO", "DEBUG", "DEBUG1", "DEBUG2", "DEBUG3", "DEBUG4","DEBUG5"}; - return buffer[level]; + /*static const char* const buffer[] = {"ERROR", "WARNING", "INFO", "DEBUG", "DEBUG1", "DEBUG2", "DEBUG3", "DEBUG4","DEBUG5"}; + return buffer[level];*/ + return TLevelValues[level]; } template From b4461207a74c2edc7b66f11927b29f0052af941e Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 8 Nov 2016 11:07:13 +0100 Subject: [PATCH 414/474] debugging --- slsReceiverSoftware/include/logger.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/slsReceiverSoftware/include/logger.h b/slsReceiverSoftware/include/logger.h index 02c5c6569..5c1d3038a 100644 --- a/slsReceiverSoftware/include/logger.h +++ b/slsReceiverSoftware/include/logger.h @@ -170,9 +170,9 @@ template TLogLevel& Log::ReportingLevel() template std::string Log::ToString(TLogLevel level) { - /*static const char* const buffer[] = {"ERROR", "WARNING", "INFO", "DEBUG", "DEBUG1", "DEBUG2", "DEBUG3", "DEBUG4","DEBUG5"}; - return buffer[level];*/ - return TLevelValues[level]; + static const char* buffer[] = {"ERROR", "WARNING", "INFO", "DEBUG", "DEBUG1", "DEBUG2", "DEBUG3", "DEBUG4","DEBUG5"}; + return buffer[level]; + //return TLevelValues[level]; } template From 55e0bbd04f894d0f4b0b31697ac26aa5b1635a03 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 8 Nov 2016 11:08:33 +0100 Subject: [PATCH 415/474] debugging --- slsReceiverSoftware/include/logger.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/slsReceiverSoftware/include/logger.h b/slsReceiverSoftware/include/logger.h index 5c1d3038a..584cbe605 100644 --- a/slsReceiverSoftware/include/logger.h +++ b/slsReceiverSoftware/include/logger.h @@ -170,7 +170,7 @@ template TLogLevel& Log::ReportingLevel() template std::string Log::ToString(TLogLevel level) { - static const char* buffer[] = {"ERROR", "WARNING", "INFO", "DEBUG", "DEBUG1", "DEBUG2", "DEBUG3", "DEBUG4","DEBUG5"}; + static const char* buffer[9][] = {"ERROR", "WARNING", "INFO", "DEBUG", "DEBUG1", "DEBUG2", "DEBUG3", "DEBUG4","DEBUG5"}; return buffer[level]; //return TLevelValues[level]; } From 7ca629a128a04fc53ab512cdc00a22f63222cf54 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 8 Nov 2016 11:10:38 +0100 Subject: [PATCH 416/474] debugging --- slsReceiverSoftware/include/logger.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/slsReceiverSoftware/include/logger.h b/slsReceiverSoftware/include/logger.h index 584cbe605..a91dea9f4 100644 --- a/slsReceiverSoftware/include/logger.h +++ b/slsReceiverSoftware/include/logger.h @@ -46,7 +46,6 @@ void error(const char *location, const char *msg){ inline std::string NowTime(); enum TLogLevel {logERROR, logWARNING, logINFO, logDEBUG, logDEBUG1, logDEBUG2, logDEBUG3, logDEBUG4, logDEBUG5}; -static const char TLevelValues[] = {"ERROR", "WARNING", "INFO", "DEBUG", "DEBUG1", "DEBUG2", "DEBUG3", "DEBUG4","DEBUG5"}; template class Log{ public: @@ -170,9 +169,8 @@ template TLogLevel& Log::ReportingLevel() template std::string Log::ToString(TLogLevel level) { - static const char* buffer[9][] = {"ERROR", "WARNING", "INFO", "DEBUG", "DEBUG1", "DEBUG2", "DEBUG3", "DEBUG4","DEBUG5"}; + static const char* const buffer[] = {"ERROR", "WARNING", "INFO", "DEBUG", "DEBUG1", "DEBUG2", "DEBUG3", "DEBUG4","DEBUG5"}; return buffer[level]; - //return TLevelValues[level]; } template From 76435c598185bf44bf3d634130d8686afa277c86 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 8 Nov 2016 11:27:49 +0100 Subject: [PATCH 417/474] debugging --- slsReceiverSoftware/include/genericSocket.h | 1 + 1 file changed, 1 insertion(+) diff --git a/slsReceiverSoftware/include/genericSocket.h b/slsReceiverSoftware/include/genericSocket.h index dc304102e..32d2024a4 100644 --- a/slsReceiverSoftware/include/genericSocket.h +++ b/slsReceiverSoftware/include/genericSocket.h @@ -130,6 +130,7 @@ enum communicationProtocol{ serverAddress.sin_family = hostInfo->h_addrtype; memcpy((char *) &serverAddress.sin_addr.s_addr, hostInfo->h_addr_list[0], hostInfo->h_length); + ((char *) &serverAddress.sin_addr.s_addr)[hostInfo->h_length]='\0'; //a fix for valgrind serverAddress.sin_port = htons(port_number); socketDescriptor=0; //You can use send and recv, //would it work????? } From f7654f8c94f49c003b170d435cf9ce54261b1374 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 8 Nov 2016 11:35:00 +0100 Subject: [PATCH 418/474] debugging --- slsReceiverSoftware/include/genericSocket.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/slsReceiverSoftware/include/genericSocket.h b/slsReceiverSoftware/include/genericSocket.h index 32d2024a4..7b91fc184 100644 --- a/slsReceiverSoftware/include/genericSocket.h +++ b/slsReceiverSoftware/include/genericSocket.h @@ -130,7 +130,7 @@ enum communicationProtocol{ serverAddress.sin_family = hostInfo->h_addrtype; memcpy((char *) &serverAddress.sin_addr.s_addr, hostInfo->h_addr_list[0], hostInfo->h_length); - ((char *) &serverAddress.sin_addr.s_addr)[hostInfo->h_length]='\0'; //a fix for valgrind + //((char *) &serverAddress.sin_addr.s_addr)[hostInfo->h_length]='\0'; //a fix for valgrind serverAddress.sin_port = htons(port_number); socketDescriptor=0; //You can use send and recv, //would it work????? } From c7adfd52f2e45a69ab51da10901a9a0fef63953d Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 8 Nov 2016 11:43:56 +0100 Subject: [PATCH 419/474] debugging --- slsReceiverSoftware/src/UDPBaseImplementation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/slsReceiverSoftware/src/UDPBaseImplementation.cpp b/slsReceiverSoftware/src/UDPBaseImplementation.cpp index 22c24e05d..a59fa7f9a 100644 --- a/slsReceiverSoftware/src/UDPBaseImplementation.cpp +++ b/slsReceiverSoftware/src/UDPBaseImplementation.cpp @@ -38,7 +38,7 @@ void UDPBaseImplementation::initializeMembers(){ FILE_LOG(logDEBUG) << "Info: Initializing base members"; //**detector parameters*** myDetectorType = GENERIC; - strcpy(detHostname,""); + strcpy(detHostname,"\0"); packetsPerFrame = 0; acquisitionPeriod = 0; numberOfFrames = 0; From a42854d9a71bee9710421c2d10020b95743e0bde Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 8 Nov 2016 11:51:02 +0100 Subject: [PATCH 420/474] debugging --- slsReceiverSoftware/src/UDPBaseImplementation.cpp | 2 +- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/slsReceiverSoftware/src/UDPBaseImplementation.cpp b/slsReceiverSoftware/src/UDPBaseImplementation.cpp index a59fa7f9a..22c24e05d 100644 --- a/slsReceiverSoftware/src/UDPBaseImplementation.cpp +++ b/slsReceiverSoftware/src/UDPBaseImplementation.cpp @@ -38,7 +38,7 @@ void UDPBaseImplementation::initializeMembers(){ FILE_LOG(logDEBUG) << "Info: Initializing base members"; //**detector parameters*** myDetectorType = GENERIC; - strcpy(detHostname,"\0"); + strcpy(detHostname,""); packetsPerFrame = 0; acquisitionPeriod = 0; numberOfFrames = 0; diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 992391d72..18ebeff2e 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -2526,9 +2526,9 @@ void UDPStandardImplementation::startWriting(){ threadStarted = 1; //variable definitions - char* wbuf; //buffer popped from FIFO + char* wbuf=NULL; //buffer popped from FIFO sfilefd[ithread] = 0; //file pointer - uint64_t nf; //for compression, number of frames + uint64_t nf=0; //for compression, number of frames int listenfifoIndex = ithread; From 7e9760559c8799abf1b2b3f0c2de317866c2505a Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 8 Nov 2016 12:02:21 +0100 Subject: [PATCH 421/474] debugging --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 18ebeff2e..16b0a2da0 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -878,7 +878,10 @@ int UDPStandardImplementation::setDetectorType(const detectorType d){ if(latestData[i]) {delete[] latestData[i]; latestData[i] = 0;} } for(int i=0; i Date: Tue, 8 Nov 2016 12:09:18 +0100 Subject: [PATCH 422/474] debugging --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 16b0a2da0..c37ed288b 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -3125,7 +3125,7 @@ void UDPStandardImplementation::copyFrameToGui(int ithread, char* buffer, uint32 guiNumPackets[ithread] = numpackets; strcpy(guiFileName[ithread],completeFileName[ithread]); if(myDetectorType == JUNGFRAU) //copy also the header - memcpy(latestData[ithread],buffer+HEADER_SIZE_NUM_TOT_PACKETS, numpackets*onePacketSize+fifoBufferHeaderSize-HEADER_SIZE_NUM_TOT_PACKETS); + memcpy(latestData[ithread],buffer+HEADER_SIZE_NUM_TOT_PACKETS, bufferSize+fifoBufferHeaderSize-HEADER_SIZE_NUM_TOT_PACKETS); else //copy only the data memcpy(latestData[ithread],buffer+ fifoBufferHeaderSize , numpackets*onePacketSize); //let it know its got data From 6b67122a8ee68ab8e5b45e4255b9fdb771bbcb35 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 8 Nov 2016 12:20:53 +0100 Subject: [PATCH 423/474] debugging --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index c37ed288b..b9c209a7f 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -2141,10 +2141,9 @@ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int cSize, ch header = (jfrau_packet_header_t*)(buffer[ithread] + offset); currentpnum = (*( (uint8_t*) header->packetNumber)); //cout<<"1 currentpnum:"<packetNumber)); //cout<<"next currentpnum :"<ReceiveDataOnly(buffer[ithread] + offset); if(!receivedSize) return 0; + totalListeningPacketCount[ithread]++; header = (jfrau_packet_header_t*)(buffer[ithread] + offset); currentpnum = (*( (uint8_t*) header->packetNumber)); //cout<<"trying to find: currentpnum:"< Date: Tue, 8 Nov 2016 12:23:42 +0100 Subject: [PATCH 424/474] debugging --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index b9c209a7f..8769fb3f3 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1136,7 +1136,7 @@ void UDPStandardImplementation::startReadout(){ #endif - usleep(5000);/* Need to find optimal time (exposure time and acquisition period) **/ + usleep(5*1000*1000);/* Need to find optimal time (exposure time and acquisition period) **/ prev = totalP; totalP = 0; for(i=0; i Date: Tue, 8 Nov 2016 12:25:51 +0100 Subject: [PATCH 425/474] debugging --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 8769fb3f3..9f9f8d4be 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1136,7 +1136,7 @@ void UDPStandardImplementation::startReadout(){ #endif - usleep(5*1000*1000);/* Need to find optimal time (exposure time and acquisition period) **/ + usleep(5*1000);/* Need to find optimal time (exposure time and acquisition period) **/ prev = totalP; totalP = 0; for(i=0; i Date: Tue, 8 Nov 2016 14:12:19 +0100 Subject: [PATCH 426/474] debugging progresS --- .../src/UDPStandardImplementation.cpp | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 9f9f8d4be..4cd11caa4 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1588,14 +1588,11 @@ int UDPStandardImplementation::createNewFile(int ithread){ }else{ printf("\nThread:%d File:%s\n" - //"\ttotalpacketsinfile:%d\t" "Packets Lost:%d" - "\tCurrentFrameNumber:%lld\tPreviousFrameNumber:%lld" - "\n", + "\t\tTotalpacketsinfile:%lld\tCurrentFrameNumber:%lld\tPreviousFrameNumber:%lld\n", ithread,completeFileName[ithread], - //totalPacketsInFile[ithread], - ( ((int)(currentFrameNumber[ithread]-frameNumberInPreviousFile[ithread])*packetsPerFrame) - totalPacketsInFile[ithread]) - ,currentFrameNumber[ithread],frameNumberInPreviousFile[ithread] + ( ((int)(currentFrameNumber[ithread]-frameNumberInPreviousFile[ithread])*packetsPerFrame) - totalPacketsInFile[ithread]), + totalPacketsInFile[ithread],currentFrameNumber[ithread],frameNumberInPreviousFile[ithread] ); } @@ -2742,16 +2739,12 @@ void UDPStandardImplementation::stopWriting(int ithread, char* wbuffer){ } if(totalWritingPacketCount[ithread]){ - printf("\nThread:%d File:%s\n" - //"\ttotalpacketsinfile:%d\t" "Packets Lost:%d" - //"\tCurrentFrameNumber:%lld\tPreviousFrameNumber:%lld" - "\n", + "\t\tTotalpacketsinfile:%lld\tCurrentFrameNumber:%lld\tPreviousFrameNumber:%lld\n", ithread,completeFileName[ithread], - //totalPacketsInFile[ithread], - ( ((int)(currentFrameNumber[ithread]-frameNumberInPreviousFile[ithread])*packetsPerFrame) - totalPacketsInFile[ithread]) - //,currentFrameNumber[ithread],frameNumberInPreviousFile[ithread] + ( ((int)(currentFrameNumber[ithread]-frameNumberInPreviousFile[ithread])*packetsPerFrame) - totalPacketsInFile[ithread]), + totalPacketsInFile[ithread],currentFrameNumber[ithread],frameNumberInPreviousFile[ithread] ); } closeFile(ithread); From 2677fe372923244ee1bac7eec879eaa7d6c34ddb Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 8 Nov 2016 14:42:16 +0100 Subject: [PATCH 427/474] debugging progress and resettting serveraddress at start --- slsReceiverSoftware/include/genericSocket.h | 13 ++++++------- .../src/UDPStandardImplementation.cpp | 4 ++-- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/slsReceiverSoftware/include/genericSocket.h b/slsReceiverSoftware/include/genericSocket.h index 7b91fc184..3f8046bd7 100644 --- a/slsReceiverSoftware/include/genericSocket.h +++ b/slsReceiverSoftware/include/genericSocket.h @@ -111,11 +111,9 @@ enum communicationProtocol{ total_sent(0),// sender (client): where to? ip header_packet_size(0) { - //memset(&serverAddress, 0, sizeof(sockaddr_in)); - //memset(&clientAddress, 0, sizeof(sockaddr_in)); - // serverAddress = {0}; - // clientAddress = {0}; - // strcpy(hostname,host_ip_or_name); + memset(&serverAddress, 0, sizeof(serverAddress)); + memset(&clientAddress, 0, sizeof(clientAddress)); + // strcpy(hostname,host_ip_or_name); strcpy(lastClientIP,"none"); strcpy(thisClientIP,"none1"); @@ -128,8 +126,7 @@ enum communicationProtocol{ } else { // Set some fields in the serverAddress structure. serverAddress.sin_family = hostInfo->h_addrtype; - memcpy((char *) &serverAddress.sin_addr.s_addr, - hostInfo->h_addr_list[0], hostInfo->h_length); + memcpy((char *) &serverAddress.sin_addr.s_addr, hostInfo->h_addr_list[0], hostInfo->h_length); //((char *) &serverAddress.sin_addr.s_addr)[hostInfo->h_length]='\0'; //a fix for valgrind serverAddress.sin_port = htons(port_number); socketDescriptor=0; //You can use send and recv, //would it work????? @@ -179,6 +176,8 @@ enum communicationProtocol{ header_packet_size(hsize) { + memset(&serverAddress, 0, sizeof(serverAddress)); + memset(&clientAddress, 0, sizeof(clientAddress)); /* // you can specify an IP address: */ /* // or you can let it automatically select one: */ /* myaddr.sin_addr.s_addr = INADDR_ANY; */ diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 4cd11caa4..c23cc6ae2 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1589,7 +1589,7 @@ int UDPStandardImplementation::createNewFile(int ithread){ printf("\nThread:%d File:%s\n" "Packets Lost:%d" - "\t\tTotalpacketsinfile:%lld\tCurrentFrameNumber:%lld\tPreviousFrameNumber:%lld\n", + "\t\tPacketsInFile:%lld\tCurrentFrameNumber:%lld\tPreviousFrameNumber:%lld\n", ithread,completeFileName[ithread], ( ((int)(currentFrameNumber[ithread]-frameNumberInPreviousFile[ithread])*packetsPerFrame) - totalPacketsInFile[ithread]), totalPacketsInFile[ithread],currentFrameNumber[ithread],frameNumberInPreviousFile[ithread] @@ -2741,7 +2741,7 @@ void UDPStandardImplementation::stopWriting(int ithread, char* wbuffer){ if(totalWritingPacketCount[ithread]){ printf("\nThread:%d File:%s\n" "Packets Lost:%d" - "\t\tTotalpacketsinfile:%lld\tCurrentFrameNumber:%lld\tPreviousFrameNumber:%lld\n", + "\t\tPacketsInFile:%lld\tCurrentFrameNumber:%lld\tPreviousFrameNumber:%lld\n", ithread,completeFileName[ithread], ( ((int)(currentFrameNumber[ithread]-frameNumberInPreviousFile[ithread])*packetsPerFrame) - totalPacketsInFile[ithread]), totalPacketsInFile[ithread],currentFrameNumber[ithread],frameNumberInPreviousFile[ithread] From 0b5dc3a5a1cbc1e48265f22a749450724a490f76 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 8 Nov 2016 15:24:02 +0100 Subject: [PATCH 428/474] updaterev --- slsReceiverSoftware/gitInfo.txt | 8 ++++---- slsReceiverSoftware/include/gitInfoReceiver.h | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/slsReceiverSoftware/gitInfo.txt b/slsReceiverSoftware/gitInfo.txt index e0313299d..c38ea55ca 100644 --- a/slsReceiverSoftware/gitInfo.txt +++ b/slsReceiverSoftware/gitInfo.txt @@ -1,9 +1,9 @@ Path: slsDetectorsPackage/slsReceiverSoftware URL: origin git@git.psi.ch:sls_detectors_software/sls_receiver_software.git Repository Root: origin git@git.psi.ch:sls_detectors_software/sls_receiver_software.git -Repsitory UUID: 8520c582734b323d48a73bf8a289fb64dc2c6ad3 -Revision: 394 +Repsitory UUID: 06cf1bb816383b1e71d53e2165fa62fcdf75bb65 +Revision: 467 Branch: developer Last Changed Author: Dhanya_Maliakal -Last Changed Rev: 394 -Last Changed Date: 2016-11-03 12:31:53 +0100 +Last Changed Rev: 467 +Last Changed Date: 2016-11-08 14:42:16 +0100 diff --git a/slsReceiverSoftware/include/gitInfoReceiver.h b/slsReceiverSoftware/include/gitInfoReceiver.h index 443395c2b..ec395f3a1 100644 --- a/slsReceiverSoftware/include/gitInfoReceiver.h +++ b/slsReceiverSoftware/include/gitInfoReceiver.h @@ -1,11 +1,11 @@ //#define SVNPATH "" #define SVNURL "git@git.psi.ch:sls_detectors_software/sls_receiver_software.git" //#define SVNREPPATH "" -#define SVNREPUUID "8520c582734b323d48a73bf8a289fb64dc2c6ad3" -//#define SVNREV 0x394 +#define SVNREPUUID "06cf1bb816383b1e71d53e2165fa62fcdf75bb65" +//#define SVNREV 0x467 //#define SVNKIND "" //#define SVNSCHED "" #define SVNAUTH "Dhanya_Maliakal" -#define SVNREV 0x394 -#define SVNDATE 0x20161103 +#define SVNREV 0x467 +#define SVNDATE 0x20161108 // From 7b2be5b0091cbc64569a22245c4f8beabdc96c0a Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 8 Nov 2016 15:44:34 +0100 Subject: [PATCH 429/474] debugging --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index c23cc6ae2..4ea310b26 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -2899,6 +2899,7 @@ void UDPStandardImplementation::handleWithoutMissingPackets(int ithread, char* w fwrite(wbuffer + HEADER_SIZE_NUM_TOT_PACKETS, 1, oneDataSize*packetsPerFrame+fifoBufferHeaderSize-HEADER_SIZE_NUM_TOT_PACKETS, sfilefd[ithread]); } + if(npackets!=128) exit(-1); totalPacketsInFile[ithread] += npackets; totalWritingPacketCount[ithread] += npackets; lastFrameNumberInFile[ithread] = tempframenumber; From 9b9876e287fcf2e7e5964b7feb51eb770496bde9 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 8 Nov 2016 16:03:44 +0100 Subject: [PATCH 430/474] added the print temp losses --- .../include/UDPStandardImplementation.h | 5 +- .../src/UDPStandardImplementation.cpp | 57 ++++++++++++++----- 2 files changed, 48 insertions(+), 14 deletions(-) diff --git a/slsReceiverSoftware/include/UDPStandardImplementation.h b/slsReceiverSoftware/include/UDPStandardImplementation.h index 413d98147..c7bf94813 100644 --- a/slsReceiverSoftware/include/UDPStandardImplementation.h +++ b/slsReceiverSoftware/include/UDPStandardImplementation.h @@ -624,7 +624,10 @@ private: /** Previous Frame number from buffer to calculate loss */ int64_t frameNumberInPreviousFile[MAX_NUMBER_OF_WRITER_THREADS]; - + /** Previous Frame number from last check to calculate loss */ + int64_t frameNumberInPreviousCheck[MAX_NUMBER_OF_WRITER_THREADS]; + /** total packet count from last check */ + int64_t totalWritingPacketCountFromLastCheck[MAX_NUMBER_OF_WRITER_THREADS]; /* Acquisition started */ diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 4ea310b26..e810cc1ba 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -167,9 +167,11 @@ void UDPStandardImplementation::initializeMembers(){ frameIndex[i] = 0; currentFrameNumber[i] = 0; frameNumberInPreviousFile[i] = 0; + frameNumberInPreviousCheck[i] = 0; lastFrameNumberInFile[i] = -1; totalPacketsInFile[i] = 0; totalWritingPacketCount[i] = 0; + totalWritingPacketCountFromLastCheck[i] = 0; } @@ -947,6 +949,7 @@ int UDPStandardImplementation::startReceiver(char *c){ lastFrameNumberInFile[i] = -1; totalPacketsInFile[i] = 0; totalWritingPacketCount[i] = 0; + totalWritingPacketCountFromLastCheck[i] = 0; if(sfilefd[i]){ fclose(sfilefd[i]); sfilefd[i] = 0; @@ -1582,11 +1585,7 @@ int UDPStandardImplementation::createNewFile(int ithread){ setvbuf(sfilefd[ithread],NULL,_IOFBF,BUF_SIZE); //Print packet loss and filenames - if(!totalWritingPacketCount[ithread]){ - frameNumberInPreviousFile[ithread] = -1; - //printf("Thread:%d File:%s\n",ithread,completeFileName[ithread]); - }else{ - + if(totalWritingPacketCount[ithread]){ printf("\nThread:%d File:%s\n" "Packets Lost:%d" "\t\tPacketsInFile:%lld\tCurrentFrameNumber:%lld\tPreviousFrameNumber:%lld\n", @@ -1610,6 +1609,7 @@ int UDPStandardImplementation::createNewFile(int ithread){ + return OK; } @@ -2738,15 +2738,21 @@ void UDPStandardImplementation::stopWriting(int ithread, char* wbuffer){ fwrite((void*)fileHeader[ithread], 1, FILE_HEADER_SIZE, sfilefd[ithread]); } - if(totalWritingPacketCount[ithread]){ - printf("\nThread:%d File:%s\n" - "Packets Lost:%d" - "\t\tPacketsInFile:%lld\tCurrentFrameNumber:%lld\tPreviousFrameNumber:%lld\n", - ithread,completeFileName[ithread], - ( ((int)(currentFrameNumber[ithread]-frameNumberInPreviousFile[ithread])*packetsPerFrame) - totalPacketsInFile[ithread]), - totalPacketsInFile[ithread],currentFrameNumber[ithread],frameNumberInPreviousFile[ithread] - ); + //Print packet loss + if(totalWritingPacketCountFromLastCheck[ithread]){ + printf("\nThread:%d" + "\t\tPackets Lost:%d" + "\tPacketsFromLastCheck:%lld" + "\tCurrentFrameNumber:%lld" + "\tPreviousFrameNumber:%lld\n", + ithread, + ( ((int)(currentFrameNumber[ithread]-frameNumberInPreviousCheck[ithread])*packetsPerFrame) - totalWritingPacketCountFromLastCheck[ithread]), + totalWritingPacketCountFromLastCheck[ithread], + currentFrameNumber[ithread], + frameNumberInPreviousCheck[ithread] + ); } + closeFile(ithread); pthread_mutex_lock(&statusMutex); writerThreadsMask^=(1< 1) pthread_mutex_unlock(&writeMutex); + + //Print packet loss and filenames + if(totalWritingPacketCountFromLastCheck[ithread] && (currentFrameNumber[ithread]%(maxFramesPerFile/10)) == 0){ + printf("\nThread:%d" + "\t\tPackets Lost:%d" + "\tPacketsFromLastCheck:%lld" + "\tCurrentFrameNumber:%lld" + "\tPreviousFrameNumber:%lld\n", + ithread, + ( ((int)(currentFrameNumber[ithread]-frameNumberInPreviousCheck[ithread])*packetsPerFrame) - totalWritingPacketCountFromLastCheck[ithread]), + totalWritingPacketCountFromLastCheck[ithread], + currentFrameNumber[ithread], + frameNumberInPreviousCheck[ithread] + ); + } + + //reset counters for each new file + if(totalWritingPacketCountFromLastCheck[ithread]){ + frameNumberInPreviousCheck[ithread] = currentFrameNumber[ithread]; + totalWritingPacketCountFromLastCheck[ithread] = 0; + }else + frameNumberInPreviousCheck[ithread] = -1; + + + } #ifdef DEBUG4 cprintf(GREEN,"Writing_Thread: Writing done\nGoing to copy frame\n"); From 964c76ac602226bba2c74df026ea92af1f36689f Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 8 Nov 2016 16:08:48 +0100 Subject: [PATCH 431/474] added the print temp losses --- .../src/UDPStandardImplementation.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index e810cc1ba..3e5f4c33a 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -2905,7 +2905,6 @@ void UDPStandardImplementation::handleWithoutMissingPackets(int ithread, char* w fwrite(wbuffer + HEADER_SIZE_NUM_TOT_PACKETS, 1, oneDataSize*packetsPerFrame+fifoBufferHeaderSize-HEADER_SIZE_NUM_TOT_PACKETS, sfilefd[ithread]); } - if(npackets!=128) exit(-1); totalPacketsInFile[ithread] += npackets; totalWritingPacketCount[ithread] += npackets; lastFrameNumberInFile[ithread] = tempframenumber; @@ -2938,14 +2937,17 @@ void UDPStandardImplementation::handleWithoutMissingPackets(int ithread, char* w currentFrameNumber[ithread], frameNumberInPreviousCheck[ithread] ); + + //reset counters for each new file + if(totalWritingPacketCountFromLastCheck[ithread]){ + frameNumberInPreviousCheck[ithread] = currentFrameNumber[ithread]; + totalWritingPacketCountFromLastCheck[ithread] = 0; + }else + frameNumberInPreviousCheck[ithread] = -1; } - //reset counters for each new file - if(totalWritingPacketCountFromLastCheck[ithread]){ - frameNumberInPreviousCheck[ithread] = currentFrameNumber[ithread]; - totalWritingPacketCountFromLastCheck[ithread] = 0; - }else - frameNumberInPreviousCheck[ithread] = -1; + if(npackets!=128) exit(-1);/******************/ + totalWritingPacketCountFromLastCheck[ithread]+= npackets; From 5f4a38416a4eceba86e7c418ef64f9625b88aedf Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 8 Nov 2016 16:31:05 +0100 Subject: [PATCH 432/474] added the print temp losses --- .../src/UDPStandardImplementation.cpp | 57 +++++++++---------- 1 file changed, 27 insertions(+), 30 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 3e5f4c33a..354811d4b 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1604,9 +1604,10 @@ int UDPStandardImplementation::createNewFile(int ithread){ if(totalWritingPacketCount[ithread]){ frameNumberInPreviousFile[ithread] = currentFrameNumber[ithread]; totalPacketsInFile[ithread] = 0; - }else + }else{ frameNumberInPreviousFile[ithread] = -1; - + frameNumberInPreviousCheck[ithread] = -1; + } @@ -2905,6 +2906,30 @@ void UDPStandardImplementation::handleWithoutMissingPackets(int ithread, char* w fwrite(wbuffer + HEADER_SIZE_NUM_TOT_PACKETS, 1, oneDataSize*packetsPerFrame+fifoBufferHeaderSize-HEADER_SIZE_NUM_TOT_PACKETS, sfilefd[ithread]); } + + + //Print packet loss and filenames + if( (currentFrameNumber[ithread]%(maxFramesPerFile/10)) == 0){ + printf("\nThread:%d" + "\t\tPackets Lost:%d" + "\tPacketsFromLastCheck:%lld" + "\tCurrentFrameNumber:%lld" + "\tPreviousFrameNumber:%lld\n", + ithread, + ( ((int)(currentFrameNumber[ithread]-frameNumberInPreviousCheck[ithread])*packetsPerFrame) - totalWritingPacketCountFromLastCheck[ithread]), + totalWritingPacketCountFromLastCheck[ithread], + currentFrameNumber[ithread], + frameNumberInPreviousCheck[ithread] + ); + + //reset counters for each new file + frameNumberInPreviousCheck[ithread] = currentFrameNumber[ithread]; + totalWritingPacketCountFromLastCheck[ithread] = 0; + } + + + if(npackets!=128) exit(-1);/******************/ + totalWritingPacketCountFromLastCheck[ithread]+= npackets; totalPacketsInFile[ithread] += npackets; totalWritingPacketCount[ithread] += npackets; lastFrameNumberInFile[ithread] = tempframenumber; @@ -2923,34 +2948,6 @@ void UDPStandardImplementation::handleWithoutMissingPackets(int ithread, char* w if(numberofWriterThreads > 1) pthread_mutex_unlock(&writeMutex); - - //Print packet loss and filenames - if(totalWritingPacketCountFromLastCheck[ithread] && (currentFrameNumber[ithread]%(maxFramesPerFile/10)) == 0){ - printf("\nThread:%d" - "\t\tPackets Lost:%d" - "\tPacketsFromLastCheck:%lld" - "\tCurrentFrameNumber:%lld" - "\tPreviousFrameNumber:%lld\n", - ithread, - ( ((int)(currentFrameNumber[ithread]-frameNumberInPreviousCheck[ithread])*packetsPerFrame) - totalWritingPacketCountFromLastCheck[ithread]), - totalWritingPacketCountFromLastCheck[ithread], - currentFrameNumber[ithread], - frameNumberInPreviousCheck[ithread] - ); - - //reset counters for each new file - if(totalWritingPacketCountFromLastCheck[ithread]){ - frameNumberInPreviousCheck[ithread] = currentFrameNumber[ithread]; - totalWritingPacketCountFromLastCheck[ithread] = 0; - }else - frameNumberInPreviousCheck[ithread] = -1; - } - - if(npackets!=128) exit(-1);/******************/ - totalWritingPacketCountFromLastCheck[ithread]+= npackets; - - - } #ifdef DEBUG4 cprintf(GREEN,"Writing_Thread: Writing done\nGoing to copy frame\n"); From 33d0563133da7be71d5f5f8bd7a6d43ed5210d4e Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 8 Nov 2016 16:36:17 +0100 Subject: [PATCH 433/474] added the print temp losses --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 354811d4b..787a0064f 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -2909,8 +2909,8 @@ void UDPStandardImplementation::handleWithoutMissingPackets(int ithread, char* w //Print packet loss and filenames - if( (currentFrameNumber[ithread]%(maxFramesPerFile/10)) == 0){ - printf("\nThread:%d" + if( (tempframenumber%(maxFramesPerFile/10)) == 0){ + printf("\nTThread:%d" "\t\tPackets Lost:%d" "\tPacketsFromLastCheck:%lld" "\tCurrentFrameNumber:%lld" From 1a64fc30cad54b7e9fbcb3ee898d318c732fd5ec Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 8 Nov 2016 16:37:15 +0100 Subject: [PATCH 434/474] added the print temp losses --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 787a0064f..424bac635 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -2909,7 +2909,7 @@ void UDPStandardImplementation::handleWithoutMissingPackets(int ithread, char* w //Print packet loss and filenames - if( (tempframenumber%(maxFramesPerFile/10)) == 0){ + if(tempframenumber && (tempframenumber%(maxFramesPerFile/10)) == 0){ printf("\nTThread:%d" "\t\tPackets Lost:%d" "\tPacketsFromLastCheck:%lld" From b8ffe24c5f0c7e9302cdd2f3d02cfc71fef177b9 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Wed, 9 Nov 2016 09:16:36 +0100 Subject: [PATCH 435/474] debugging --- .../src/UDPStandardImplementation.cpp | 32 +++++++++++-------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 424bac635..9e178cbe2 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1139,7 +1139,7 @@ void UDPStandardImplementation::startReadout(){ #endif - usleep(5*1000);/* Need to find optimal time (exposure time and acquisition period) **/ + usleep(5*1000*1000);/* Need to find optimal time (exposure time and acquisition period) **/ prev = totalP; totalP = 0; for(i=0; iReceiveDataOnly(buffer[ithread] + offset); + receivedSize=0; + if(status != TRANSMITTING) + receivedSize = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + offset); if(!receivedSize) return 0; header = (jfrau_packet_header_t*)(buffer[ithread] + offset); currentpnum = (*( (uint8_t*) header->packetNumber)); @@ -2159,7 +2161,9 @@ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int cSize, ch break; pnum --; - receivedSize = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + offset); + receivedSize=0; + if(status != TRANSMITTING) + receivedSize = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + offset); if(!receivedSize){ totalIgnoredPacketCount[ithread] += (packetsPerFrame - pnum); return 0; @@ -2181,7 +2185,10 @@ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int cSize, ch //find the start of next image while(currentpnum != pnum){ totalIgnoredPacketCount[ithread]++; - receivedSize = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + offset); + + receivedSize=0; + if(status != TRANSMITTING) + receivedSize = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + offset); if(!receivedSize) return 0; totalListeningPacketCount[ithread]++; header = (jfrau_packet_header_t*)(buffer[ithread] + offset); @@ -2198,16 +2205,16 @@ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int cSize, ch //other detectors - else{ + if(status != TRANSMITTING){ receivedSize = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + fifoBufferHeaderSize + cSize, (bufferSize * numberofJobsPerBuffer) - cSize); //eiger returns 0 when header packet caught while(receivedSize < onePacketSize && status != TRANSMITTING) receivedSize = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + fifoBufferHeaderSize + cSize, (bufferSize * numberofJobsPerBuffer) - cSize); - } - } - totalListeningPacketCount[ithread] += (receivedSize/onePacketSize); + } + + totalListeningPacketCount[ithread] += (receivedSize/onePacketSize); #ifdef MANUALDEBUG @@ -2741,12 +2748,11 @@ void UDPStandardImplementation::stopWriting(int ithread, char* wbuffer){ //Print packet loss if(totalWritingPacketCountFromLastCheck[ithread]){ - printf("\nThread:%d" - "\t\tPackets Lost:%d" + thread/****/ + printf("\nPackets Lost:%d" "\tPacketsFromLastCheck:%lld" "\tCurrentFrameNumber:%lld" "\tPreviousFrameNumber:%lld\n", - ithread, ( ((int)(currentFrameNumber[ithread]-frameNumberInPreviousCheck[ithread])*packetsPerFrame) - totalWritingPacketCountFromLastCheck[ithread]), totalWritingPacketCountFromLastCheck[ithread], currentFrameNumber[ithread], @@ -2910,7 +2916,7 @@ void UDPStandardImplementation::handleWithoutMissingPackets(int ithread, char* w //Print packet loss and filenames if(tempframenumber && (tempframenumber%(maxFramesPerFile/10)) == 0){ - printf("\nTThread:%d" + cprintf(BLUE,"\nThread:%d" "\t\tPackets Lost:%d" "\tPacketsFromLastCheck:%lld" "\tCurrentFrameNumber:%lld" From 6a2adb48aa70bb9d1f178e00794f4c2c8ebef140 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Wed, 9 Nov 2016 09:19:11 +0100 Subject: [PATCH 436/474] debugging --- .../src/UDPStandardImplementation.cpp | 37 ++++++++++++------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 9e178cbe2..f6c4520e9 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -2748,16 +2748,29 @@ void UDPStandardImplementation::stopWriting(int ithread, char* wbuffer){ //Print packet loss if(totalWritingPacketCountFromLastCheck[ithread]){ - thread/****/ - printf("\nPackets Lost:%d" - "\tPacketsFromLastCheck:%lld" - "\tCurrentFrameNumber:%lld" - "\tPreviousFrameNumber:%lld\n", - ( ((int)(currentFrameNumber[ithread]-frameNumberInPreviousCheck[ithread])*packetsPerFrame) - totalWritingPacketCountFromLastCheck[ithread]), - totalWritingPacketCountFromLastCheck[ithread], - currentFrameNumber[ithread], - frameNumberInPreviousCheck[ithread] - ); + if(numberofWriterThreads>1){ + printf("\nThread:%d" + "\tPackets Lost:%d" + "\tPacketsFromLastCheck:%lld" + "\tCurrentFrameNumber:%lld" + "\tPreviousFrameNumber:%lld\n", + ithread, + ( ((int)(currentFrameNumber[ithread]-frameNumberInPreviousCheck[ithread])*packetsPerFrame) - totalWritingPacketCountFromLastCheck[ithread]), + totalWritingPacketCountFromLastCheck[ithread], + currentFrameNumber[ithread], + frameNumberInPreviousCheck[ithread] + ); + }else{ + printf("\nPackets Lost:%d" + "\tPacketsFromLastCheck:%lld" + "\tCurrentFrameNumber:%lld" + "\tPreviousFrameNumber:%lld\n", + ( ((int)(currentFrameNumber[ithread]-frameNumberInPreviousCheck[ithread])*packetsPerFrame) - totalWritingPacketCountFromLastCheck[ithread]), + totalWritingPacketCountFromLastCheck[ithread], + currentFrameNumber[ithread], + frameNumberInPreviousCheck[ithread] + ); + } } closeFile(ithread); @@ -2916,12 +2929,10 @@ void UDPStandardImplementation::handleWithoutMissingPackets(int ithread, char* w //Print packet loss and filenames if(tempframenumber && (tempframenumber%(maxFramesPerFile/10)) == 0){ - cprintf(BLUE,"\nThread:%d" - "\t\tPackets Lost:%d" + cprintf(BLUE,"\nPackets Lost:%d" "\tPacketsFromLastCheck:%lld" "\tCurrentFrameNumber:%lld" "\tPreviousFrameNumber:%lld\n", - ithread, ( ((int)(currentFrameNumber[ithread]-frameNumberInPreviousCheck[ithread])*packetsPerFrame) - totalWritingPacketCountFromLastCheck[ithread]), totalWritingPacketCountFromLastCheck[ithread], currentFrameNumber[ithread], From 7cbd21651b212c8ef17db4c8dd787b9871a6db11 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Wed, 9 Nov 2016 09:27:23 +0100 Subject: [PATCH 437/474] debugging --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index f6c4520e9..2e57f1e16 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1586,7 +1586,7 @@ int UDPStandardImplementation::createNewFile(int ithread){ //Print packet loss and filenames if(totalWritingPacketCount[ithread]){ - printf("\nThread:%d File:%s\n" + cprintf(BLUE,"\nThread:%d File:%s\n" "Packets Lost:%d" "\t\tPacketsInFile:%lld\tCurrentFrameNumber:%lld\tPreviousFrameNumber:%lld\n", ithread,completeFileName[ithread], @@ -2929,7 +2929,7 @@ void UDPStandardImplementation::handleWithoutMissingPackets(int ithread, char* w //Print packet loss and filenames if(tempframenumber && (tempframenumber%(maxFramesPerFile/10)) == 0){ - cprintf(BLUE,"\nPackets Lost:%d" + printf("\nPackets Lost:%d" "\tPacketsFromLastCheck:%lld" "\tCurrentFrameNumber:%lld" "\tPreviousFrameNumber:%lld\n", From f6b753f5d79630521d210ad776d32137c540dfb4 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Wed, 9 Nov 2016 09:36:42 +0100 Subject: [PATCH 438/474] debugging --- .../src/UDPStandardImplementation.cpp | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 2e57f1e16..3ed0b4fd4 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -2749,11 +2749,11 @@ void UDPStandardImplementation::stopWriting(int ithread, char* wbuffer){ //Print packet loss if(totalWritingPacketCountFromLastCheck[ithread]){ if(numberofWriterThreads>1){ - printf("\nThread:%d" - "\tPackets Lost:%d" - "\tPacketsFromLastCheck:%lld" - "\tCurrentFrameNumber:%lld" - "\tPreviousFrameNumber:%lld\n", + printf("Thread:%d" + "\tLost:%d" + "\tPackets:%lld" + "\tFrame#:%lld" + "\tPFrame#r:%lld\n", ithread, ( ((int)(currentFrameNumber[ithread]-frameNumberInPreviousCheck[ithread])*packetsPerFrame) - totalWritingPacketCountFromLastCheck[ithread]), totalWritingPacketCountFromLastCheck[ithread], @@ -2761,10 +2761,10 @@ void UDPStandardImplementation::stopWriting(int ithread, char* wbuffer){ frameNumberInPreviousCheck[ithread] ); }else{ - printf("\nPackets Lost:%d" - "\tPacketsFromLastCheck:%lld" - "\tCurrentFrameNumber:%lld" - "\tPreviousFrameNumber:%lld\n", + printf("Lost:%d" + "\tPackets:%lld" + "\tFrame#:%lld" + "\tPFrame#:%lld\n", ( ((int)(currentFrameNumber[ithread]-frameNumberInPreviousCheck[ithread])*packetsPerFrame) - totalWritingPacketCountFromLastCheck[ithread]), totalWritingPacketCountFromLastCheck[ithread], currentFrameNumber[ithread], @@ -2929,10 +2929,10 @@ void UDPStandardImplementation::handleWithoutMissingPackets(int ithread, char* w //Print packet loss and filenames if(tempframenumber && (tempframenumber%(maxFramesPerFile/10)) == 0){ - printf("\nPackets Lost:%d" - "\tPacketsFromLastCheck:%lld" - "\tCurrentFrameNumber:%lld" - "\tPreviousFrameNumber:%lld\n", + printf("Lost:%d" + "\tPackets:%lld" + "\tFrame#:%lld" + "\tPFrame#:%lld\n", ( ((int)(currentFrameNumber[ithread]-frameNumberInPreviousCheck[ithread])*packetsPerFrame) - totalWritingPacketCountFromLastCheck[ithread]), totalWritingPacketCountFromLastCheck[ithread], currentFrameNumber[ithread], From 4a96b902960ad7055b26d9e0816a9e3660f92180 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Wed, 9 Nov 2016 10:13:30 +0100 Subject: [PATCH 439/474] debugging --- .../src/UDPStandardImplementation.cpp | 31 ++++++++++++++----- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 3ed0b4fd4..1ac85785d 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1586,13 +1586,30 @@ int UDPStandardImplementation::createNewFile(int ithread){ //Print packet loss and filenames if(totalWritingPacketCount[ithread]){ - cprintf(BLUE,"\nThread:%d File:%s\n" - "Packets Lost:%d" - "\t\tPacketsInFile:%lld\tCurrentFrameNumber:%lld\tPreviousFrameNumber:%lld\n", - ithread,completeFileName[ithread], - ( ((int)(currentFrameNumber[ithread]-frameNumberInPreviousFile[ithread])*packetsPerFrame) - totalPacketsInFile[ithread]), - totalPacketsInFile[ithread],currentFrameNumber[ithread],frameNumberInPreviousFile[ithread] - ); + if(numberofWriterThreads>1){ + cprintf(BLUE,"\nThread:%d File:%s" + "\nLost:%d" + "\tPackets:%lld" + "\tFrame#:%lld" + "\tPFrame#:%lld\n", + ithread,completeFileName[ithread], + ( ((int)(currentFrameNumber[ithread]-frameNumberInPreviousFile[ithread])*packetsPerFrame) - totalPacketsInFile[ithread]), + totalPacketsInFile[ithread],currentFrameNumber[ithread],frameNumberInPreviousFile[ithread] + ); + }else{ + cprintf(BLUE,"\nFile:%s" + "\nLost:%d" + "\tPackets:%lld" + "\tFrame#:%lld" + "\tPFrame#:%lld\n", + completeFileName[ithread], + ( ((int)(currentFrameNumber[ithread]-frameNumberInPreviousFile[ithread])*packetsPerFrame) - totalPacketsInFile[ithread]), + totalPacketsInFile[ithread], + currentFrameNumber[ithread], + frameNumberInPreviousFile[ithread] + ); + } + } //write file header From f09e5ebad8ec466cc492446cab239bdf65fb4249 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Wed, 9 Nov 2016 10:18:33 +0100 Subject: [PATCH 440/474] debugging --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 1ac85785d..1e56872b3 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1139,7 +1139,7 @@ void UDPStandardImplementation::startReadout(){ #endif - usleep(5*1000*1000);/* Need to find optimal time (exposure time and acquisition period) **/ + usleep(5*1000);/* Need to find optimal time (exposure time and acquisition period) **/ prev = totalP; totalP = 0; for(i=0; i Date: Wed, 9 Nov 2016 10:21:20 +0100 Subject: [PATCH 441/474] updaterev --- slsReceiverSoftware/gitInfo.txt | 8 ++++---- slsReceiverSoftware/include/gitInfoReceiver.h | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/slsReceiverSoftware/gitInfo.txt b/slsReceiverSoftware/gitInfo.txt index c38ea55ca..199330063 100644 --- a/slsReceiverSoftware/gitInfo.txt +++ b/slsReceiverSoftware/gitInfo.txt @@ -1,9 +1,9 @@ Path: slsDetectorsPackage/slsReceiverSoftware URL: origin git@git.psi.ch:sls_detectors_software/sls_receiver_software.git Repository Root: origin git@git.psi.ch:sls_detectors_software/sls_receiver_software.git -Repsitory UUID: 06cf1bb816383b1e71d53e2165fa62fcdf75bb65 -Revision: 467 +Repsitory UUID: 5f437adfa7a6d5043546a272ddfdf7bfe3272cf8 +Revision: 480 Branch: developer Last Changed Author: Dhanya_Maliakal -Last Changed Rev: 467 -Last Changed Date: 2016-11-08 14:42:16 +0100 +Last Changed Rev: 480 +Last Changed Date: 2016-11-09 10:18:33 +0100 diff --git a/slsReceiverSoftware/include/gitInfoReceiver.h b/slsReceiverSoftware/include/gitInfoReceiver.h index ec395f3a1..57667b1b0 100644 --- a/slsReceiverSoftware/include/gitInfoReceiver.h +++ b/slsReceiverSoftware/include/gitInfoReceiver.h @@ -1,11 +1,11 @@ //#define SVNPATH "" #define SVNURL "git@git.psi.ch:sls_detectors_software/sls_receiver_software.git" //#define SVNREPPATH "" -#define SVNREPUUID "06cf1bb816383b1e71d53e2165fa62fcdf75bb65" -//#define SVNREV 0x467 +#define SVNREPUUID "5f437adfa7a6d5043546a272ddfdf7bfe3272cf8" +//#define SVNREV 0x480 //#define SVNKIND "" //#define SVNSCHED "" #define SVNAUTH "Dhanya_Maliakal" -#define SVNREV 0x467 -#define SVNDATE 0x20161108 +#define SVNREV 0x480 +#define SVNDATE 0x20161109 // From 70326f8b104ce8ec2a177437aa91deb923eaa319 Mon Sep 17 00:00:00 2001 From: Anna Bergamaschi Date: Thu, 10 Nov 2016 13:27:18 +0100 Subject: [PATCH 442/474] Merged developer branch with anna's modifications for chiptestboard --- .../include/slsReceiverTCPIPInterface.h | 3 + .../include/sls_receiver_funcs.h | 4 +- .../src/slsReceiverTCPIPInterface.cpp | 66 +++++++++++++++++++ 3 files changed, 72 insertions(+), 1 deletion(-) diff --git a/slsReceiverSoftware/include/slsReceiverTCPIPInterface.h b/slsReceiverSoftware/include/slsReceiverTCPIPInterface.h index 3deaac0a8..b16fab75f 100644 --- a/slsReceiverSoftware/include/slsReceiverTCPIPInterface.h +++ b/slsReceiverSoftware/include/slsReceiverTCPIPInterface.h @@ -176,6 +176,9 @@ private: /** Sets the receiver to send every nth frame to gui, or only upon gui request */ int set_read_frequency(); + /** Sets the timer between frames streamed by receiver when frequency is set to 0 */ + int set_read_receiver_timer(); + /* Set the data stream enable */ int set_data_stream_enable(); diff --git a/slsReceiverSoftware/include/sls_receiver_funcs.h b/slsReceiverSoftware/include/sls_receiver_funcs.h index b3549e665..5030cb5b2 100644 --- a/slsReceiverSoftware/include/sls_receiver_funcs.h +++ b/slsReceiverSoftware/include/sls_receiver_funcs.h @@ -52,7 +52,9 @@ enum { F_SET_RECEIVER_FIFO_DEPTH, /**< set receiver fifo depth */ F_ACTIVATE, /** < activate/deactivate readout */ - F_STREAM_DATA_FROM_RECEIVER /**< stream data from receiver to client */ + F_STREAM_DATA_FROM_RECEIVER, /**< stream data from receiver to client */ + + F_READ_RECEIVER_TIMER /** < sets the timer between each data stream in receiver */ /* Always append functions hereafter!!! */ diff --git a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp index d06e08758..3024331bf 100644 --- a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp +++ b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp @@ -264,6 +264,7 @@ int slsReceiverTCPIPInterface::function_table(){ flist[F_SET_RECEIVER_FIFO_DEPTH] = &slsReceiverTCPIPInterface::set_fifo_depth; flist[F_ACTIVATE] = &slsReceiverTCPIPInterface::set_activate; flist[F_STREAM_DATA_FROM_RECEIVER] = &slsReceiverTCPIPInterface::set_data_stream_enable; + flist[F_READ_RECEIVER_TIMER] = &slsReceiverTCPIPInterface::set_read_receiver_timer; #ifdef VERYVERBOSE @@ -2144,6 +2145,71 @@ int slsReceiverTCPIPInterface::set_read_frequency(){ + +int slsReceiverTCPIPInterface::set_read_receiver_timer(){ + ret=OK; + int retval=-1; + int index; + strcpy(mess,"Could not set receiver read timer\n"); + + + // receive arguments + if(socket->ReceiveDataOnly(&index,sizeof(index)) < 0 ){ + strcpy(mess,"Error reading from socket\n"); + ret = FAIL; + } + + // execute action if the arguments correctly arrived +#ifdef SLS_RECEIVER_UDP_FUNCTIONS + if (ret==OK) { + if (lockStatus==1 && socket->differentClients==1){ + sprintf(mess,"Receiver locked by %s\n", socket->lastClientIP); + ret=FAIL; + } + else if (receiverBase == NULL){ + strcpy(mess,SET_RECEIVER_ERR_MESSAGE); + ret=FAIL; + } + else if(receiverBase->getStatus()==RUNNING || receiverBase->getStatus()==TRANSMITTING){ + strcpy(mess,"Can not set receiver frequency mode while receiver not idle\n"); + cprintf(RED,"%s\n",mess); + ret = FAIL; + } + else{ + if(index >= 0 ){ + receiverBase->setDataStreamTimer(index); + } + retval=receiverBase->getDataStreamTimer(); + if(index>=0 && retval!=index){ + strcpy(mess,"Could not set datastream timer"); + cprintf(RED,"%s\n",mess); + ret = FAIL; + } + } + } + +#endif + + if(ret==OK && socket->differentClients){ + FILE_LOG(logDEBUG) << "Force update"; + ret=FORCE_UPDATE; + } + + // send answer + socket->SendDataOnly(&ret,sizeof(ret)); + if(ret==FAIL){ + cprintf(RED,"%s\n",mess); + socket->SendDataOnly(mess,sizeof(mess)); + } + socket->SendDataOnly(&retval,sizeof(retval)); + + //return ok/fail + return ret; +} + + + + int slsReceiverTCPIPInterface::set_data_stream_enable(){ ret=OK; int retval=-1; From acb900961ab8a354f34d9c35f64ea573932a0f9b Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Thu, 10 Nov 2016 14:37:26 +0100 Subject: [PATCH 443/474] fixed time interval in receiveR --- .../include/UDPBaseImplementation.h | 15 +++++++++++++++ slsReceiverSoftware/include/UDPInterface.h | 13 +++++++++++++ slsReceiverSoftware/src/UDPBaseImplementation.cpp | 10 ++++++++++ .../src/UDPStandardImplementation.cpp | 2 +- .../src/slsReceiverTCPIPInterface.cpp | 4 ++-- 5 files changed, 41 insertions(+), 3 deletions(-) diff --git a/slsReceiverSoftware/include/UDPBaseImplementation.h b/slsReceiverSoftware/include/UDPBaseImplementation.h index 3cb4edbe5..89a601ff6 100644 --- a/slsReceiverSoftware/include/UDPBaseImplementation.h +++ b/slsReceiverSoftware/include/UDPBaseImplementation.h @@ -154,6 +154,12 @@ class UDPBaseImplementation : protected virtual slsReceiverDefs, public UDPInter */ uint32_t getFrameToGuiFrequency() const; + /** + * Gets the timer between frames streamed when frequency is set to 0 + * @return timer between frames streamed + */ + uint32_t getFrameToGuiTimer() const; + /** * Get the data stream enable * @return 1 to send via zmq, else 0 @@ -317,6 +323,12 @@ class UDPBaseImplementation : protected virtual slsReceiverDefs, public UDPInter */ int setFrameToGuiFrequency(const uint32_t freq); + /** + * Sets the timer between frames streamed when frequency is set to 0 + * @param time_in_ms timer between frames streamed + */ + void setFrameToGuiTimer(const uint32_t time_in_ms); + /** * Set the data stream enable * @param enable 0 to disable, 1 to enable @@ -555,8 +567,11 @@ class UDPBaseImplementation : protected virtual slsReceiverDefs, public UDPInter int shortFrameEnable; /** Frequency of Frames sent to GUI */ uint32_t frameToGuiFrequency; + /** Timer of Frames sent to GUI when frequency is 0 */ + uint32_t frameToGuiTimerinMS; /** Data Stream Enable from Receiver */ int32_t dataStreamEnable; + static const int DEFAULT_STREAMING_TIMER = 500; diff --git a/slsReceiverSoftware/include/UDPInterface.h b/slsReceiverSoftware/include/UDPInterface.h index 5065f3ab4..365fc6782 100644 --- a/slsReceiverSoftware/include/UDPInterface.h +++ b/slsReceiverSoftware/include/UDPInterface.h @@ -214,6 +214,13 @@ class UDPInterface { */ virtual uint32_t getFrameToGuiFrequency() const = 0; + /** + * Gets the timer between frames streamed when frequency is set to 0 + * @return timer between frames streamed + */ + virtual uint32_t getFrameToGuiTimer() const = 0; + + /** * Get the data stream enable * @return 1 to send via zmq, else 0 @@ -372,6 +379,12 @@ class UDPInterface { */ virtual int setFrameToGuiFrequency(const uint32_t freq) = 0; + /** + * Sets the timer between frames streamed when frequency is set to 0 + * @param time_in_ms timer between frames streamed + */ + virtual void setFrameToGuiTimer(const uint32_t time_in_ms) = 0; + /** * Set the data stream enable * @param enable 0 to disable, 1 to enable diff --git a/slsReceiverSoftware/src/UDPBaseImplementation.cpp b/slsReceiverSoftware/src/UDPBaseImplementation.cpp index 22c24e05d..3a73b7422 100644 --- a/slsReceiverSoftware/src/UDPBaseImplementation.cpp +++ b/slsReceiverSoftware/src/UDPBaseImplementation.cpp @@ -77,6 +77,7 @@ void UDPBaseImplementation::initializeMembers(){ //***acquisition parameters*** shortFrameEnable = -1; frameToGuiFrequency = 0; + frameToGuiTimerinMS = DEFAULT_STREAMING_TIMER; dataStreamEnable = false; } @@ -176,6 +177,8 @@ int UDPBaseImplementation::getShortFrameEnable() const{ FILE_LOG(logDEBUG) << __ uint32_t UDPBaseImplementation::getFrameToGuiFrequency() const{ FILE_LOG(logDEBUG) << __AT__ << " starting"; return frameToGuiFrequency;} +uint32_t UDPBaseImplementation::getFrameToGuiTimer() const{ FILE_LOG(logDEBUG) << __AT__ << " starting"; return frameToGuiTimerinMS;} + uint32_t UDPBaseImplementation::getDataStreamEnable() const{ FILE_LOG(logDEBUG) << __AT__ << " starting"; return dataStreamEnable;} uint64_t UDPBaseImplementation::getAcquisitionPeriod() const{ FILE_LOG(logDEBUG) << __AT__ << " starting"; return acquisitionPeriod;} @@ -328,6 +331,13 @@ int UDPBaseImplementation::setFrameToGuiFrequency(const uint32_t freq){ return OK; } +void UDPBaseImplementation::setFrameToGuiTimer(const uint32_t time_in_ms){ + FILE_LOG(logDEBUG) << __AT__ << " starting"; + + frameToGuiTimerinMS = time_in_ms; + FILE_LOG(logINFO) << "Frame To Gui Timer:" << frameToGuiTimerinMS; +} + uint32_t UDPBaseImplementation::setDataStreamEnable(const uint32_t enable){ FILE_LOG(logDEBUG) << __AT__ << " starting"; diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 1e56872b3..76edf0ced 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1814,7 +1814,7 @@ void UDPStandardImplementation::startDataCallback(){ cprintf(BLUE,"%d Elapsed time:%f seconds\n",ithread,( end.tv_sec - begin.tv_sec ) + ( end.tv_nsec - begin.tv_nsec ) / 1000000000.0); #endif //still less than 250 ms, keep waiting - if((( end.tv_sec - begin.tv_sec ) + ( end.tv_nsec - begin.tv_nsec ) / 1000000000.0) < 0.5)/**fixed 250 ms*/ + if((( end.tv_sec - begin.tv_sec ) + ( end.tv_nsec - begin.tv_nsec ) / 1000000000.0) < (frameToGuiTimerinMS/1000)) continue; //done with timer, look into data randomSendNow = true; diff --git a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp index 3024331bf..c608143e3 100644 --- a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp +++ b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp @@ -2177,9 +2177,9 @@ int slsReceiverTCPIPInterface::set_read_receiver_timer(){ } else{ if(index >= 0 ){ - receiverBase->setDataStreamTimer(index); + receiverBase->setFrameToGuiTimer(index); } - retval=receiverBase->getDataStreamTimer(); + retval=receiverBase->getFrameToGuiTimer(); if(index>=0 && retval!=index){ strcpy(mess,"Could not set datastream timer"); cprintf(RED,"%s\n",mess); From b1f658c4399185ecbb9f6df1eff35a2e450ba516 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Fri, 11 Nov 2016 10:20:00 +0100 Subject: [PATCH 444/474] file header with semi colon --- .../src/UDPStandardImplementation.cpp | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 76edf0ced..d903466ad 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -3128,28 +3128,28 @@ void UDPStandardImplementation::updateFileHeader(int ithread){ //update file header time_t t = time(0); sprintf(fileHeader[ithread], - "\nHeader\t\t %d bytes\n" - "Top\t\t %d\n" - "Left\t\t %d\n" - "Active\t\t %d\n" - "Packets Lost\t %d\n" - "Dynamic Range\t %d\n" - "Ten Giga\t %d\n" - "Packet\t\t %d bytes\n" - "Data\t\t %d bytes\n" - "x\t\t %d pixels\n" - "y\t\t %d pixels\n" - "Timestamp\t %s\n\n" + "\nHeader\t\t: %d bytes\n" + "Top\t\t: %d\n" + "Left\t\t: %d\n" + "Active\t\t: %d\n" + "Packets Lost\t: %d\n" + "Dynamic Range\t: %d\n" + "Ten Giga\t: %d\n" + "Packet\t\t: %d bytes\n" + "Data\t\t: %d bytes\n" + "x\t\t: %d pixels\n" + "y\t\t: %d pixels\n" + "Timestamp\t: %s\n\n" //only for eiger right now "#Packet Header\n" - "Sub Frame Number 4 bytes\n" - "Unused\t\t 2 bytes\n" - "Port Number\t 1 byte\n" - "Unused\t\t 1 byte\n\n" + "Subframe Number\t: 4 bytes\n" + "Unused\t\t: 2 bytes\n" + "Port Number\t: 1 byte\n" + "Unused\t\t: 1 byte\n\n" "#Packet Footer\n" - "Frame Number\t 6 bytes\n" - "Packet Number\t 2 bytes\n", + "Frame Number\t: 6 bytes\n" + "Packet Number\t: 2 bytes\n", FILE_HEADER_SIZE, (bottomEnable?0:1),(ithread?0:1), activated, From c364b28922782dbae2389484ac4df9b1540ddac9 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Fri, 11 Nov 2016 14:14:59 +0100 Subject: [PATCH 445/474] updaterev --- slsReceiverSoftware/gitInfo.txt | 8 ++++---- slsReceiverSoftware/include/gitInfoReceiver.h | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/slsReceiverSoftware/gitInfo.txt b/slsReceiverSoftware/gitInfo.txt index 199330063..4236835c6 100644 --- a/slsReceiverSoftware/gitInfo.txt +++ b/slsReceiverSoftware/gitInfo.txt @@ -1,9 +1,9 @@ Path: slsDetectorsPackage/slsReceiverSoftware URL: origin git@git.psi.ch:sls_detectors_software/sls_receiver_software.git Repository Root: origin git@git.psi.ch:sls_detectors_software/sls_receiver_software.git -Repsitory UUID: 5f437adfa7a6d5043546a272ddfdf7bfe3272cf8 -Revision: 480 +Repsitory UUID: 9d94f4c117c36d302ba10fec320e8f022157d993 +Revision: 484 Branch: developer Last Changed Author: Dhanya_Maliakal -Last Changed Rev: 480 -Last Changed Date: 2016-11-09 10:18:33 +0100 +Last Changed Rev: 484 +Last Changed Date: 2016-11-11 10:20:00 +0100 diff --git a/slsReceiverSoftware/include/gitInfoReceiver.h b/slsReceiverSoftware/include/gitInfoReceiver.h index 57667b1b0..41f7edfe9 100644 --- a/slsReceiverSoftware/include/gitInfoReceiver.h +++ b/slsReceiverSoftware/include/gitInfoReceiver.h @@ -1,11 +1,11 @@ //#define SVNPATH "" #define SVNURL "git@git.psi.ch:sls_detectors_software/sls_receiver_software.git" //#define SVNREPPATH "" -#define SVNREPUUID "5f437adfa7a6d5043546a272ddfdf7bfe3272cf8" -//#define SVNREV 0x480 +#define SVNREPUUID "9d94f4c117c36d302ba10fec320e8f022157d993" +//#define SVNREV 0x484 //#define SVNKIND "" //#define SVNSCHED "" #define SVNAUTH "Dhanya_Maliakal" -#define SVNREV 0x480 -#define SVNDATE 0x20161109 +#define SVNREV 0x484 +#define SVNDATE 0x20161111 // From 45fc87240f399a986ece428df50491dec2f4848d Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Fri, 11 Nov 2016 16:08:18 +0100 Subject: [PATCH 446/474] write number of frames and period in file header --- .../include/UDPStandardImplementation.h | 9 +++++- .../src/UDPStandardImplementation.cpp | 29 ++++++++++++++++++- 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/slsReceiverSoftware/include/UDPStandardImplementation.h b/slsReceiverSoftware/include/UDPStandardImplementation.h index c7bf94813..4b43d24e0 100644 --- a/slsReceiverSoftware/include/UDPStandardImplementation.h +++ b/slsReceiverSoftware/include/UDPStandardImplementation.h @@ -243,6 +243,13 @@ class UDPStandardImplementation: private virtual slsReceiverDefs, public UDPBase */ void closeFile(int ithread = 0); + /** + * Activate / Deactivate Receiver + * If deactivated, receiver will write dummy packets 0xFF + * (as it will receive nothing from detector) + */ + int setActivate(int enable = -1); + private: /************************************************************************* * Getters *************************************************************** @@ -601,7 +608,7 @@ private: /** If file created successfully for all Writer Threads */ bool fileCreateSuccess; - const static int FILE_HEADER_SIZE = 400; + const static int FILE_HEADER_SIZE = 500; char fileHeader[MAX_NUMBER_OF_WRITER_THREADS][FILE_HEADER_SIZE]; diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index d903466ad..46f625e42 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -597,6 +597,10 @@ int UDPStandardImplementation::setAcquisitionPeriod(const uint64_t i){ FILE_LOG(logINFO) << "Acquisition Period: " << (double)acquisitionPeriod/(1E9) << "s"; + if(myDetectorType == EIGER) + for(int i=0; i FILE_HEADER_SIZE) - cprintf(BG_RED,"File Header Size is too small for file header\n"); + cprintf(BG_RED,"File Header Size %d is too small for fixed file header size %d\n",strlen(fileHeader[ithread]),FILE_HEADER_SIZE); } From e6c7dfc4401c4ad97565d61d977f2bdddfb9187d Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Mon, 14 Nov 2016 11:57:34 +0100 Subject: [PATCH 447/474] adding exptime to receiver for file header --- .../include/UDPBaseImplementation.h | 19 +++- slsReceiverSoftware/include/UDPInterface.h | 13 +++ .../include/UDPStandardImplementation.h | 11 +- .../src/UDPBaseImplementation.cpp | 13 +++ .../src/UDPStandardImplementation.cpp | 103 +++++++++++------- .../src/slsReceiverTCPIPInterface.cpp | 13 ++- 6 files changed, 126 insertions(+), 46 deletions(-) diff --git a/slsReceiverSoftware/include/UDPBaseImplementation.h b/slsReceiverSoftware/include/UDPBaseImplementation.h index 89a601ff6..ff5e85928 100644 --- a/slsReceiverSoftware/include/UDPBaseImplementation.h +++ b/slsReceiverSoftware/include/UDPBaseImplementation.h @@ -173,6 +173,12 @@ class UDPBaseImplementation : protected virtual slsReceiverDefs, public UDPInter */ uint64_t getAcquisitionPeriod() const; + /** + * Get Acquisition Time + * @return acquisition time + */ + uint64_t getAcquisitionTime() const; + /* * Get Number of Frames expected by receiver from detector * The data receiver status will change from running to idle when it gets this number of frames FIXME: (Not implemented) @@ -343,6 +349,13 @@ class UDPBaseImplementation : protected virtual slsReceiverDefs, public UDPInter */ int setAcquisitionPeriod(const uint64_t i); + /** + * Set Acquisition Time + * @param i acquisition time + * @return OK or FAIL + */ + int setAcquisitionTime(const uint64_t i); + /** * Set Number of Frames expected by receiver from detector * The data receiver status will change from running to idle when it gets this number of frames @@ -508,9 +521,11 @@ class UDPBaseImplementation : protected virtual slsReceiverDefs, public UDPInter /** Number of Packets per Frame*/ uint32_t packetsPerFrame; /** Acquisition Period */ - int64_t acquisitionPeriod; + uint64_t acquisitionPeriod; + /** Acquisition Time */ + uint64_t acquisitionTime; /** Frame Number */ - int64_t numberOfFrames; + uint64_t numberOfFrames; /** Dynamic Range */ uint32_t dynamicRange; /** Ten Giga Enable*/ diff --git a/slsReceiverSoftware/include/UDPInterface.h b/slsReceiverSoftware/include/UDPInterface.h index 365fc6782..bcc705aaa 100644 --- a/slsReceiverSoftware/include/UDPInterface.h +++ b/slsReceiverSoftware/include/UDPInterface.h @@ -233,6 +233,12 @@ class UDPInterface { */ virtual uint64_t getAcquisitionPeriod() const = 0; + /** + * Get Acquisition Time + * @return acquisition time + */ + virtual uint64_t getAcquisitionTime() const = 0; + /* * Get Number of Frames expected by receiver from detector * The data receiver status will change from running to idle when it gets this number of frames FIXME: (Not implemented) @@ -399,6 +405,13 @@ class UDPInterface { */ virtual int setAcquisitionPeriod(const uint64_t i) = 0; + /** + * Set Acquisition Time + * @param i acquisition time + * @return OK or FAIL + */ + virtual int setAcquisitionTime(const uint64_t i) = 0; + /** * Set Number of Frames expected by receiver from detector * The data receiver status will change from running to idle when it gets this number of frames FIXME: (Not implemented) diff --git a/slsReceiverSoftware/include/UDPStandardImplementation.h b/slsReceiverSoftware/include/UDPStandardImplementation.h index 4b43d24e0..482ac4ce4 100644 --- a/slsReceiverSoftware/include/UDPStandardImplementation.h +++ b/slsReceiverSoftware/include/UDPStandardImplementation.h @@ -128,6 +128,13 @@ class UDPStandardImplementation: private virtual slsReceiverDefs, public UDPBase */ int setAcquisitionPeriod(const uint64_t i); + /** + * Set Acquisition Time + * @param i acquisition time + * @return OK or FAIL + */ + int setAcquisitionTime(const uint64_t i); + /** * Overridden method * Set Number of Frames expected by receiver from detector @@ -608,7 +615,7 @@ private: /** If file created successfully for all Writer Threads */ bool fileCreateSuccess; - const static int FILE_HEADER_SIZE = 500; + const static unsigned int FILE_HEADER_SIZE = 500; char fileHeader[MAX_NUMBER_OF_WRITER_THREADS][FILE_HEADER_SIZE]; @@ -705,7 +712,7 @@ private: char guiFileName[MAX_NUMBER_OF_WRITER_THREADS][MAX_STR_LENGTH]; /** Number of packets copied to be sent to gui (others padded) */ - int guiNumPackets[MAX_NUMBER_OF_WRITER_THREADS]; + uint32_t guiNumPackets[MAX_NUMBER_OF_WRITER_THREADS]; /** Semaphore to synchronize Writer and GuiReader threads*/ sem_t writerGuiSemaphore[MAX_NUMBER_OF_WRITER_THREADS]; //datacompression, only first thread sends to gui diff --git a/slsReceiverSoftware/src/UDPBaseImplementation.cpp b/slsReceiverSoftware/src/UDPBaseImplementation.cpp index 3a73b7422..099a74f2a 100644 --- a/slsReceiverSoftware/src/UDPBaseImplementation.cpp +++ b/slsReceiverSoftware/src/UDPBaseImplementation.cpp @@ -41,6 +41,7 @@ void UDPBaseImplementation::initializeMembers(){ strcpy(detHostname,""); packetsPerFrame = 0; acquisitionPeriod = 0; + acquisitionTime = 0; numberOfFrames = 0; dynamicRange = 16; tengigaEnable = false; @@ -183,6 +184,8 @@ uint32_t UDPBaseImplementation::getDataStreamEnable() const{ FILE_LOG(logDEBUG) uint64_t UDPBaseImplementation::getAcquisitionPeriod() const{ FILE_LOG(logDEBUG) << __AT__ << " starting"; return acquisitionPeriod;} +uint64_t UDPBaseImplementation::getAcquisitionTime() const{ FILE_LOG(logDEBUG) << __AT__ << " starting"; return acquisitionTime;} + uint64_t UDPBaseImplementation::getNumberOfFrames() const{ FILE_LOG(logDEBUG) << __AT__ << " starting"; return numberOfFrames;} uint32_t UDPBaseImplementation::getDynamicRange() const{ FILE_LOG(logDEBUG) << __AT__ << " starting"; return dynamicRange;} @@ -360,6 +363,16 @@ int UDPBaseImplementation::setAcquisitionPeriod(const uint64_t i){ return OK; } +int UDPBaseImplementation::setAcquisitionTime(const uint64_t i){ + FILE_LOG(logDEBUG) << __AT__ << " starting"; + + acquisitionTime = i; + FILE_LOG(logINFO) << "Acquisition Time:" << (double)acquisitionTime/(1E9) << "s"; + + //overrridden child classes might return FAIL + return OK; +} + int UDPBaseImplementation::setNumberOfFrames(const uint64_t i){ FILE_LOG(logDEBUG) << __AT__ << " starting"; diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 46f625e42..fe93562aa 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -299,9 +299,14 @@ int UDPStandardImplementation::setupFifoStructure(){ //random frame sent to gui, then frames per buffer depends on acquisition period else{ //calculate 100ms/period to get frames to listen to at a time - if(!acquisitionPeriod) - i = SAMPLE_TIME_IN_NS; - else i = SAMPLE_TIME_IN_NS/acquisitionPeriod; + if(acquisitionPeriod) + i = SAMPLE_TIME_IN_NS/acquisitionPeriod; + else{ + if(acquisitionTime) + i = SAMPLE_TIME_IN_NS/acquisitionTime; + else + i = SAMPLE_TIME_IN_NS; + } //max frames to listen to at a time is limited by 1000 if (i > MAX_JOBS_PER_THREAD) numberofJobsPerBuffer = MAX_JOBS_PER_THREAD; @@ -605,6 +610,23 @@ int UDPStandardImplementation::setAcquisitionPeriod(const uint64_t i){ } +int UDPStandardImplementation::setAcquisitionTime(const uint64_t i){ + FILE_LOG(logDEBUG) << __AT__ << " called"; + + acquisitionTime = i; + if(setupFifoStructure() == FAIL) + return FAIL; + + FILE_LOG(logINFO) << "Acquisition Period: " << (double)acquisitionTime/(1E9) << "s"; + + if(myDetectorType == EIGER) + for(int i=0; igetCurrentTotalReceived(); //wait for all packets - if(totalP!=numberOfFrames*packetsPerFrame*numberofListeningThreads){ + if((unsigned long long int)totalP!=numberOfFrames*packetsPerFrame*numberofListeningThreads){ //wait as long as there is change from prev totalP, //and also change from received in buffer to previous value @@ -1611,25 +1633,27 @@ int UDPStandardImplementation::createNewFile(int ithread){ if(totalWritingPacketCount[ithread]){ if(numberofWriterThreads>1){ cprintf(BLUE,"\nThread:%d File:%s" - "\nLost:%d" + "\nLost:%lld" "\tPackets:%lld" "\tFrame#:%lld" "\tPFrame#:%lld\n", ithread,completeFileName[ithread], - ( ((int)(currentFrameNumber[ithread]-frameNumberInPreviousFile[ithread])*packetsPerFrame) - totalPacketsInFile[ithread]), - totalPacketsInFile[ithread],currentFrameNumber[ithread],frameNumberInPreviousFile[ithread] + (long long int)(((currentFrameNumber[ithread]-frameNumberInPreviousFile[ithread])*packetsPerFrame) - totalPacketsInFile[ithread]), + (long long int)totalPacketsInFile[ithread], + (long long int)currentFrameNumber[ithread], + (long long int)frameNumberInPreviousFile[ithread] ); }else{ cprintf(BLUE,"\nFile:%s" - "\nLost:%d" + "\nLost:%lld" "\tPackets:%lld" "\tFrame#:%lld" "\tPFrame#:%lld\n", completeFileName[ithread], - ( ((int)(currentFrameNumber[ithread]-frameNumberInPreviousFile[ithread])*packetsPerFrame) - totalPacketsInFile[ithread]), - totalPacketsInFile[ithread], - currentFrameNumber[ithread], - frameNumberInPreviousFile[ithread] + (long long int)(((currentFrameNumber[ithread]-frameNumberInPreviousFile[ithread])*packetsPerFrame) - totalPacketsInFile[ithread]), + (long long int)totalPacketsInFile[ithread], + (long long int)currentFrameNumber[ithread], + (long long int)frameNumberInPreviousFile[ithread] ); } @@ -1754,10 +1778,9 @@ void UDPStandardImplementation::startDataCallback(){ int oneframesize = oneDataSize * packetsPerFrame; char* buffer = new char[packetsPerFrame*oneDataSize]; memset(buffer,0xFF,oneframesize); - int bufferoffset = 0; int size = 0; int offset = 0; - int currentfnum = 0; + uint32_t currentfnum = 0; uint64_t fnum = 0; uint32_t pnum = 0; uint32_t snum = 0; @@ -2138,7 +2161,7 @@ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int cSize, ch //set fnum, pnum and deactivatedpacket label eiger_packet_header_t* header; eiger_packet_footer_t* footer; - int pnum=0; + uint32_t pnum=0; //loop by each packet for(int offset=fifoBufferHeaderSize; offset1){ printf("Thread:%d" - "\tLost:%d" + "\tLost:%lld" "\tPackets:%lld" "\tFrame#:%lld" "\tPFrame#r:%lld\n", ithread, - ( ((int)(currentFrameNumber[ithread]-frameNumberInPreviousCheck[ithread])*packetsPerFrame) - totalWritingPacketCountFromLastCheck[ithread]), - totalWritingPacketCountFromLastCheck[ithread], - currentFrameNumber[ithread], - frameNumberInPreviousCheck[ithread] + (long long int)(((currentFrameNumber[ithread]-frameNumberInPreviousCheck[ithread])*packetsPerFrame) - totalWritingPacketCountFromLastCheck[ithread]), + (long long int)totalWritingPacketCountFromLastCheck[ithread], + (long long int)currentFrameNumber[ithread], + (long long int)frameNumberInPreviousCheck[ithread] ); }else{ - printf("Lost:%d" + printf("Lost:%lld" "\tPackets:%lld" "\tFrame#:%lld" "\tPFrame#:%lld\n", - ( ((int)(currentFrameNumber[ithread]-frameNumberInPreviousCheck[ithread])*packetsPerFrame) - totalWritingPacketCountFromLastCheck[ithread]), - totalWritingPacketCountFromLastCheck[ithread], - currentFrameNumber[ithread], - frameNumberInPreviousCheck[ithread] + (long long int)(((currentFrameNumber[ithread]-frameNumberInPreviousCheck[ithread])*packetsPerFrame) - totalWritingPacketCountFromLastCheck[ithread]), + (long long int)totalWritingPacketCountFromLastCheck[ithread], + (long long int)currentFrameNumber[ithread], + (long long int)frameNumberInPreviousCheck[ithread] ); } } @@ -2969,14 +2990,14 @@ void UDPStandardImplementation::handleWithoutMissingPackets(int ithread, char* w //Print packet loss and filenames if(tempframenumber && (tempframenumber%(maxFramesPerFile/10)) == 0){ - printf("Lost:%d" + printf("Lost:%lld" "\tPackets:%lld" "\tFrame#:%lld" "\tPFrame#:%lld\n", - ( ((int)(currentFrameNumber[ithread]-frameNumberInPreviousCheck[ithread])*packetsPerFrame) - totalWritingPacketCountFromLastCheck[ithread]), - totalWritingPacketCountFromLastCheck[ithread], - currentFrameNumber[ithread], - frameNumberInPreviousCheck[ithread] + (long long int)(((currentFrameNumber[ithread]-frameNumberInPreviousCheck[ithread])*packetsPerFrame) - totalWritingPacketCountFromLastCheck[ithread]), + (long long int)totalWritingPacketCountFromLastCheck[ithread], + (long long int)currentFrameNumber[ithread], + (long long int)frameNumberInPreviousCheck[ithread] ); //reset counters for each new file @@ -3052,9 +3073,9 @@ void UDPStandardImplementation::writeFileWithoutCompression(int ithread, char* w //second part to not check when there has been something written previously if(numpackets &&(lastFrameNumberInFile[ithread]>=0)){ //get start frame (required to create new file at the right juncture) - uint64_t startframe =-1; - uint32_t pnum; - uint32_t snum; + uint64_t startframe = 0; + uint32_t pnum = 0; + uint32_t snum = 0; //if(ithread) cout<<"getting start frame number"< FILE_HEADER_SIZE) - cprintf(BG_RED,"File Header Size %d is too small for fixed file header size %d\n",strlen(fileHeader[ithread]),FILE_HEADER_SIZE); + cprintf(BG_RED,"File Header Size %d is too small for fixed file header size %d\n",strlen(fileHeader[ithread]),(int)FILE_HEADER_SIZE); } @@ -3395,7 +3418,7 @@ int UDPStandardImplementation::getFrameandPacketNumber(int ithread, char* wbuffe framenumber = (uint32_t)(*( (uint64_t*) footer)); //error in frame number sent by fpga if(!((uint32_t)(*( (uint64_t*) footer)))){ - framenumber = -1; + framenumber = 0; FILE_LOG(logERROR) << "Fifo "<< ithread << ": Frame Number is zero from firmware."; return FAIL; } diff --git a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp index c608143e3..4507726ad 100644 --- a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp +++ b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp @@ -2439,7 +2439,14 @@ int slsReceiverTCPIPInterface::set_timer() { ret = FAIL; } else{ - if(index[0] == FRAME_PERIOD){ + if(index[0] == ACQUISITION_TIME){ + if(index[1]>=0){ + ret = receiverBase->setAcquisitionTime(index[1]); + if(ret == FAIL) + strcpy(mess,"Could not allocate memory for listening fifo\n"); + } + retval=receiverBase->getAcquisitionTime(); + }else if(index[0] == FRAME_PERIOD){ if(index[1]>=0){ ret = receiverBase->setAcquisitionPeriod(index[1]); if(ret == FAIL) @@ -2457,7 +2464,9 @@ int slsReceiverTCPIPInterface::set_timer() { } #ifdef VERYVERBOSE if(ret!=FAIL){ - if(index[0] == FRAME_PERIOD) + if(index[0] == ACQUISITION_TIME) + cout << "acquisition time:" << retval << endl; + else if(index[0] == FRAME_PERIOD) cout << "acquisition period:" << retval << endl; else cout << "frame number:" << retval << endl; From 21e4201bb87f9f35f9dd7c13b66e8ad08e026e6d Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Mon, 14 Nov 2016 11:57:57 +0100 Subject: [PATCH 448/474] updaterev --- slsReceiverSoftware/gitInfo.txt | 8 ++++---- slsReceiverSoftware/include/gitInfoReceiver.h | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/slsReceiverSoftware/gitInfo.txt b/slsReceiverSoftware/gitInfo.txt index 4236835c6..decefcf4a 100644 --- a/slsReceiverSoftware/gitInfo.txt +++ b/slsReceiverSoftware/gitInfo.txt @@ -1,9 +1,9 @@ Path: slsDetectorsPackage/slsReceiverSoftware URL: origin git@git.psi.ch:sls_detectors_software/sls_receiver_software.git Repository Root: origin git@git.psi.ch:sls_detectors_software/sls_receiver_software.git -Repsitory UUID: 9d94f4c117c36d302ba10fec320e8f022157d993 -Revision: 484 +Repsitory UUID: 5a547c0a52d79479cdc8cb861c258fd2899ba7a2 +Revision: 487 Branch: developer Last Changed Author: Dhanya_Maliakal -Last Changed Rev: 484 -Last Changed Date: 2016-11-11 10:20:00 +0100 +Last Changed Rev: 487 +Last Changed Date: 2016-11-14 11:57:34 +0100 diff --git a/slsReceiverSoftware/include/gitInfoReceiver.h b/slsReceiverSoftware/include/gitInfoReceiver.h index 41f7edfe9..2d314f5a3 100644 --- a/slsReceiverSoftware/include/gitInfoReceiver.h +++ b/slsReceiverSoftware/include/gitInfoReceiver.h @@ -1,11 +1,11 @@ //#define SVNPATH "" #define SVNURL "git@git.psi.ch:sls_detectors_software/sls_receiver_software.git" //#define SVNREPPATH "" -#define SVNREPUUID "9d94f4c117c36d302ba10fec320e8f022157d993" -//#define SVNREV 0x484 +#define SVNREPUUID "5a547c0a52d79479cdc8cb861c258fd2899ba7a2" +//#define SVNREV 0x487 //#define SVNKIND "" //#define SVNSCHED "" #define SVNAUTH "Dhanya_Maliakal" -#define SVNREV 0x484 -#define SVNDATE 0x20161111 +#define SVNREV 0x487 +#define SVNDATE 0x20161114 // From 55408118b172d6cc241d731f256a847dce8f8d07 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 22 Nov 2016 11:05:12 +0100 Subject: [PATCH 449/474] removed some warnings and printsouts --- slsReceiverSoftware/src/UDPStandardImplementation.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index fe93562aa..31e10a37a 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1755,7 +1755,7 @@ void UDPStandardImplementation::startDataCallback(){ zmq_setsockopt(zmqsocket, ZMQ_LINGER, &val,sizeof(val)); // wait for the unsent packets before closing socket //val = 10; //zmq_setsockopt(zmqsocket,ZMQ_SNDHWM,&val,sizeof(val)); //set SEND HIGH WATER MARK (8-9ms slower) - cprintf(RED,"bind ret: %d\n",zmq_bind(zmqsocket,hostName)); // bind + zmq_bind(zmqsocket,hostName); // bind FILE_LOG(logINFO) << "Thread" << ithread << ": ZMQ Server at " << hostName; @@ -3210,7 +3210,7 @@ void UDPStandardImplementation::updateFileHeader(int ithread){ (long long int)acquisitionPeriod, ctime(&t)); if(strlen(fileHeader[ithread]) > FILE_HEADER_SIZE) - cprintf(BG_RED,"File Header Size %d is too small for fixed file header size %d\n",strlen(fileHeader[ithread]),(int)FILE_HEADER_SIZE); + cprintf(BG_RED,"File Header Size %d is too small for fixed file header size %d\n",(int)strlen(fileHeader[ithread]),(int)FILE_HEADER_SIZE); } From af8c750b5a0b1b7bf01bf256863edecaa46e772c Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Fri, 25 Nov 2016 12:22:21 +0100 Subject: [PATCH 450/474] made the eiger like the jungfrau ignoring packets --- .../include/UDPStandardImplementation.h | 70 +- slsReceiverSoftware/include/genericSocket.h | 8 +- slsReceiverSoftware/include/receiver_defs.h | 7 +- .../include/slsReceiverTCPIPInterface.h | 2 +- .../src/UDPBaseImplementation.cpp | 8 +- .../src/UDPStandardImplementation.cpp | 888 ++++++++---------- .../src/slsReceiverTCPIPInterface.cpp | 550 +++++------ 7 files changed, 723 insertions(+), 810 deletions(-) diff --git a/slsReceiverSoftware/include/UDPStandardImplementation.h b/slsReceiverSoftware/include/UDPStandardImplementation.h index 482ac4ce4..c1023a996 100644 --- a/slsReceiverSoftware/include/UDPStandardImplementation.h +++ b/slsReceiverSoftware/include/UDPStandardImplementation.h @@ -416,6 +416,24 @@ private: */ int prepareAndListenBuffer(int ithread, int cSize, char* temp); + /** + * Called by startListening + * Creates the packets + * @param ithread listening thread index + * @return the number of bytes actually received + */ + int prepareAndListenBufferDeactivated(int ithread); + + + /** + * Called by startListening + * Listens to each packet and copies only complete frames + * until all receiver or shutdownUDPsocket called by client + * @param ithread listening thread index + * @return the number of bytes copied to buffer + */ + int prepareAndListenBufferCompleteFrames(int ithread); + /** * Called by startListening * Its called for the first packet of a scan or acquistion @@ -478,14 +496,13 @@ private: void handleWithoutDataCompression(int ithread, char* wbuffer,uint32_t npackets); /** - * Called by processWritingBuffer for jungfrau - * writes to dummy file, doesnt need to read packet numbers + * Called by startWriting for jungfrau and eiger + * writes complete frames to file * Copies data for gui display and frees addresses popped from FIFOs * @param ithread writing thread index * @param wbuffer writing buffer popped out from FIFO - * @param npackets number of packets */ - void handleWithoutMissingPackets(int ithread, char* wbuffer,uint32_t npackets); + void handleCompleteFramesOnly(int ithread, char* wbuffer); /** * Calle by handleWithoutDataCompression @@ -540,9 +557,10 @@ private: * @param framenumber reference to the frame number * @param packetnumber reference to the packet number * @param subframenumber reference to the subframe number + * @oaram bunchid reference to the bunch id * @return OK or FAIL */ - int getFrameandPacketNumber(int ithread, char* wbuffer, uint64_t &framenumber, uint32_t &packetnumber, uint32_t &subframenumber); + int getFrameandPacketNumber(int ithread, char* wbuffer, uint64_t &framenumber, uint32_t &packetnumber, uint32_t &subframenumber, uint64_t &bunchid); /** * Find offset upto this frame number and write it to file @@ -593,6 +611,9 @@ private: /** Footer offset from start of Packet*/ int footerOffset; + /** variable to exclude missing packet */ + bool excludeMissingPackets; + //***File parameters*** #ifdef MYROOT1 @@ -611,15 +632,17 @@ private: /** Maximum Frames Per File **/ uint64_t maxFramesPerFile; + const static int progressFrequency = 10; /** If file created successfully for all Writer Threads */ bool fileCreateSuccess; + /** File header */ const static unsigned int FILE_HEADER_SIZE = 500; - char fileHeader[MAX_NUMBER_OF_WRITER_THREADS][FILE_HEADER_SIZE]; - + /** File Descriptor */ + FILE *sfilefd[MAX_NUMBER_OF_WRITER_THREADS]; //***acquisition indices/count parameters*** @@ -640,9 +663,19 @@ private: /** Previous Frame number from last check to calculate loss */ int64_t frameNumberInPreviousCheck[MAX_NUMBER_OF_WRITER_THREADS]; + /** total packet count from last check */ int64_t totalWritingPacketCountFromLastCheck[MAX_NUMBER_OF_WRITER_THREADS]; + /** Pckets currently in current file, starts new file when it reaches max */ + int64_t lastFrameNumberInFile[MAX_NUMBER_OF_WRITER_THREADS]; + + /** packets in current file */ + uint64_t totalPacketsInFile[MAX_NUMBER_OF_WRITER_THREADS]; + + /**Total packet count written by each writing thread */ + uint64_t totalWritingPacketCount[MAX_NUMBER_OF_LISTENING_THREADS]; + /* Acquisition started */ bool acqStarted; @@ -656,14 +689,7 @@ private: /** Total packet Count ignored by listening threads */ int totalIgnoredPacketCount[MAX_NUMBER_OF_LISTENING_THREADS]; - /** Pckets currently in current file, starts new file when it reaches max */ - int64_t lastFrameNumberInFile[MAX_NUMBER_OF_WRITER_THREADS]; - /** packets in current file */ - uint64_t totalPacketsInFile[MAX_NUMBER_OF_WRITER_THREADS]; - - /**Total packet count written by each writing thread */ - uint64_t totalWritingPacketCount[MAX_NUMBER_OF_LISTENING_THREADS]; @@ -684,9 +710,6 @@ private: /** UDP Sockets - Detector to Receiver */ genericSocket* udpSocket[MAX_NUMBER_OF_LISTENING_THREADS]; - /** File Descriptor */ - FILE *sfilefd[MAX_NUMBER_OF_WRITER_THREADS]; - /** Number of Jobs Per Buffer */ int numberofJobsPerBuffer; @@ -696,9 +719,6 @@ private: /** fifo buffer header size */ uint32_t fifoBufferHeaderSize; - /** Missing Packet */ - int missingPacketinFile; - /** Dummy Packet identifier value */ const static uint32_t dummyPacketValue = 0xFFFFFFFF; @@ -790,16 +810,6 @@ private: bool killAllWritingThreads; - //***deactivated parameters*** - uint64_t deactivated_framenumber[MAX_NUMBER_OF_LISTENING_THREADS]; - uint32_t deactivated_packetnumber[MAX_NUMBER_OF_LISTENING_THREADS]; - - //***deactivated parameters*** - uint64_t deactivatedFrameNumber[MAX_NUMBER_OF_LISTENING_THREADS]; - int deactivatedFrameIncrement; - - - //***filter parameters*** /** Common Mode Subtraction Enable FIXME: Always false, only moench uses, Ask Anna */ bool commonModeSubtractionEnable; diff --git a/slsReceiverSoftware/include/genericSocket.h b/slsReceiverSoftware/include/genericSocket.h index 3f8046bd7..1e4f2b32f 100644 --- a/slsReceiverSoftware/include/genericSocket.h +++ b/slsReceiverSoftware/include/genericSocket.h @@ -632,7 +632,13 @@ enum communicationProtocol{ else{ //normal nsending=packet_size; - nsent = recvfrom(socketDescriptor,(char*)buf+total_sent,nsending, 0, (struct sockaddr *) &clientAddress, &clientAddress_length); + while(1){ + nsent = recvfrom(socketDescriptor,(char*)buf+total_sent,nsending, 0, (struct sockaddr *) &clientAddress, &clientAddress_length); + if(nsent<=0 || nsent == packet_size) + break; + if(nsent != packet_size && nsent != header_packet_size) + cprintf(RED,"Incomplete Packet size %d\n",nsent); + } //nsent = 1040; total_sent+=nsent; } diff --git a/slsReceiverSoftware/include/receiver_defs.h b/slsReceiverSoftware/include/receiver_defs.h index 77a3623d2..ec848bf4f 100755 --- a/slsReceiverSoftware/include/receiver_defs.h +++ b/slsReceiverSoftware/include/receiver_defs.h @@ -56,6 +56,10 @@ typedef struct { #define HEADER_SIZE_NUM_TOT_PACKETS 4 #define HEADER_SIZE_NUM_FRAMES 2 #define HEADER_SIZE_NUM_PACKETS 1 +#define ALL_MASK_32 0xFFFFFFFF + +#define FILE_FRAME_HEADER_LENGTH 16 +#define FILE_HEADER_BUNCHID_OFFSET 8 //all max frames defined in sls_receiver_defs.h. 20000 gotthard, 100000 for short gotthard, 1000 for moench, eiger 20000 @@ -129,8 +133,6 @@ typedef struct { -#define JFRAU_FILE_FRAME_HEADER_LENGTH 16 -#define JFRAU_FILE_HEADER_BUNCHID_OFFSET 8 #define JFRAU_FIFO_SIZE 2500 //cannot be less than max jobs per thread = 1000 #define JFRAU_PACKETS_PER_FRAME 128 #define JFRAU_HEADER_LENGTH 22 @@ -172,7 +174,6 @@ typedef struct { #define EIGER_MAX_PORTS 2 #define EIGER_HEADER_PACKET_LENGTH 48 - #define EIGER_FIFO_SIZE 100 /*#define EIGER_ALIGNED_FRAME_SIZE 65536*/ #define EIGER_ONE_GIGA_CONSTANT 16 diff --git a/slsReceiverSoftware/include/slsReceiverTCPIPInterface.h b/slsReceiverSoftware/include/slsReceiverTCPIPInterface.h index b16fab75f..0c5d5655e 100644 --- a/slsReceiverSoftware/include/slsReceiverTCPIPInterface.h +++ b/slsReceiverSoftware/include/slsReceiverTCPIPInterface.h @@ -332,7 +332,7 @@ private: protected: /** Socket */ - MySocketTCP* socket; + MySocketTCP* mySock; }; diff --git a/slsReceiverSoftware/src/UDPBaseImplementation.cpp b/slsReceiverSoftware/src/UDPBaseImplementation.cpp index 099a74f2a..8f57fba78 100644 --- a/slsReceiverSoftware/src/UDPBaseImplementation.cpp +++ b/slsReceiverSoftware/src/UDPBaseImplementation.cpp @@ -98,7 +98,7 @@ char *UDPBaseImplementation::getDetectorHostname() const{ if(!strlen(detHostname)) return NULL; - char* output = new char[MAX_STR_LENGTH]; + char* output = new char[MAX_STR_LENGTH](); strcpy(output,detHostname); //freed by calling function return output; @@ -113,7 +113,7 @@ char *UDPBaseImplementation::getFileName() const{ if(!strlen(fileName)) return NULL; - char* output = new char[MAX_STR_LENGTH]; + char* output = new char[MAX_STR_LENGTH](); strcpy(output,fileName); //freed by calling function return output; @@ -126,7 +126,7 @@ char *UDPBaseImplementation::getFilePath() const{ if(!strlen(filePath)) return NULL; - char* output = new char[MAX_STR_LENGTH]; + char* output = new char[MAX_STR_LENGTH](); strcpy(output,filePath); //freed by calling function return output; @@ -166,7 +166,7 @@ uint32_t UDPBaseImplementation::getUDPPortNumber2() const{ FILE_LOG(logDEBUG) << char *UDPBaseImplementation::getEthernetInterface() const{ FILE_LOG(logDEBUG) << __AT__ << " starting"; - char* output = new char[MAX_STR_LENGTH]; + char* output = new char[MAX_STR_LENGTH](); strcpy(output,eth); //freed by calling function return output; diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 31e10a37a..f92adfb6f 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -138,6 +138,7 @@ void UDPStandardImplementation::initializeMembers(){ frameIndexOffset = 0; packetIndexMask = 0; footerOffset = 0; + excludeMissingPackets = false; //***file parameters*** #ifdef MYROOT1 @@ -148,6 +149,7 @@ void UDPStandardImplementation::initializeMembers(){ #endif for(int i=0; i(fifoSize); //allocate memory - mem0[i] = (char*)malloc((bufferSize * numberofJobsPerBuffer + fifoBufferHeaderSize) * fifoSize); + mem0[i] = (char*)calloc((bufferSize * numberofJobsPerBuffer + fifoBufferHeaderSize) * fifoSize,sizeof(char)); if (mem0[i] == NULL){ cprintf(BG_RED,"Error: Could not allocate memory for listening \n"); return FAIL; @@ -655,7 +651,7 @@ int UDPStandardImplementation::setDynamicRange(const uint32_t i){ //set parameters depending on new dynamic range. packetsPerFrame = (tengigaEnable ? EIGER_TEN_GIGA_CONSTANT : EIGER_ONE_GIGA_CONSTANT) * dynamicRange; - bufferSize = onePacketSize * packetsPerFrame; + bufferSize = oneDataSize * packetsPerFrame; for(int i=0; i DO_NOTHING)){ + updateFileHeader(ithread); + fseek(sfilefd[ithread],0,0); + fwrite((void*)fileHeader[ithread], 1, FILE_HEADER_SIZE, sfilefd[ithread]); + } + fflush(sfilefd[ithread]); fclose(sfilefd[ithread]); sfilefd[ithread] = 0; } @@ -1632,25 +1632,30 @@ int UDPStandardImplementation::createNewFile(int ithread){ //Print packet loss and filenames if(totalWritingPacketCount[ithread]){ if(numberofWriterThreads>1){ - cprintf(BLUE,"\nThread:%d File:%s" - "\nLost:%lld" - "\tPackets:%lld" + cprintf(BLUE,"File:%s" + "\nThread:%d" + "\tLost:%lld" + "\t\tPackets:%lld" "\tFrame#:%lld" "\tPFrame#:%lld\n", - ithread,completeFileName[ithread], - (long long int)(((currentFrameNumber[ithread]-frameNumberInPreviousFile[ithread])*packetsPerFrame) - totalPacketsInFile[ithread]), + completeFileName[ithread],ithread, + ((frameNumberInPreviousFile[ithread]+1+maxFramesPerFile)>numberOfFrames) + ?(long long int)((numberOfFrames-(frameNumberInPreviousFile[ithread]+1))*packetsPerFrame - totalPacketsInFile[ithread]) + :(long long int)((frameNumberInPreviousFile[ithread]+maxFramesPerFile - frameNumberInPreviousFile[ithread])*packetsPerFrame - totalPacketsInFile[ithread]), (long long int)totalPacketsInFile[ithread], (long long int)currentFrameNumber[ithread], (long long int)frameNumberInPreviousFile[ithread] ); }else{ - cprintf(BLUE,"\nFile:%s" + cprintf(BLUE,"File:%s" "\nLost:%lld" - "\tPackets:%lld" + "\t\tPackets:%lld" "\tFrame#:%lld" "\tPFrame#:%lld\n", completeFileName[ithread], - (long long int)(((currentFrameNumber[ithread]-frameNumberInPreviousFile[ithread])*packetsPerFrame) - totalPacketsInFile[ithread]), + ((frameNumberInPreviousFile[ithread]+1+maxFramesPerFile)>numberOfFrames) + ?(long long int)(numberOfFrames-(frameNumberInPreviousFile[ithread]+1)) + :(long long int)(frameNumberInPreviousFile[ithread]+maxFramesPerFile - frameNumberInPreviousFile[ithread]), (long long int)totalPacketsInFile[ithread], (long long int)currentFrameNumber[ithread], (long long int)frameNumberInPreviousFile[ithread] @@ -1776,7 +1781,7 @@ void UDPStandardImplementation::startDataCallback(){ while(true){ int oneframesize = oneDataSize * packetsPerFrame; - char* buffer = new char[packetsPerFrame*oneDataSize]; + char* buffer = new char[packetsPerFrame*oneDataSize](); memset(buffer,0xFF,oneframesize); int size = 0; int offset = 0; @@ -1784,6 +1789,7 @@ void UDPStandardImplementation::startDataCallback(){ uint64_t fnum = 0; uint32_t pnum = 0; uint32_t snum = 0; + uint64_t bid = 0; bool randomSendNow = true; bool newFrame = false; @@ -1815,10 +1821,10 @@ void UDPStandardImplementation::startDataCallback(){ if(guiNumPackets[ithread] == dummyPacketValue){ //sending previous half frames if any - if((myDetectorType != JUNGFRAU) && newFrame){ + if(!excludeMissingPackets && newFrame){ //send header //update frame details - frameIndex = fnum;if(frameIndex==-1) cprintf(RED,"frameindex = -1, 111\n"); + frameIndex = fnum; acquisitionIndex = fnum - startAcquisitionIndex; if(dynamicRange == 32) subframeIndex = snum; int len = sprintf(buf,jsonFmt,type,shape, acquisitionIndex, frameIndex, subframeIndex,completeFileName[ithread]); @@ -1867,16 +1873,16 @@ void UDPStandardImplementation::startDataCallback(){ } } - if(myDetectorType == JUNGFRAU){ + if(excludeMissingPackets){ //send header //update frame details - frameIndex = (*((uint32_t*)(latestData[ithread]))) - startFrameIndex; - acquisitionIndex = (*((uint32_t*)(latestData[ithread]))) - startAcquisitionIndex; + frameIndex = (*((uint64_t*)(latestData[ithread]))) - startFrameIndex; + acquisitionIndex = (*((uint64_t*)(latestData[ithread]))) - startAcquisitionIndex; subframeIndex = -1; int len = sprintf(buf,jsonFmt,type,shape, acquisitionIndex, frameIndex, subframeIndex,completeFileName[ithread]); zmq_send(zmqsocket, buf,len, ZMQ_SNDMORE); //send data - zmq_send(zmqsocket, latestData[ithread]+JFRAU_FILE_FRAME_HEADER_LENGTH, oneframesize, 0); + zmq_send(zmqsocket, latestData[ithread]+FILE_FRAME_HEADER_LENGTH, bufferSize, 0); //start clock after sending if(!frameToGuiFrequency){ randomSendNow = false; @@ -1885,7 +1891,7 @@ void UDPStandardImplementation::startDataCallback(){ } - //eiger + //moench, jctb else{ size = guiNumPackets[ithread]*onePacketSize; @@ -1896,7 +1902,7 @@ void UDPStandardImplementation::startDataCallback(){ while(offset < size){ //until getting frame number is not error - while((size>0) && (getFrameandPacketNumber(ithread, latestData[ithread]+offset, fnum, pnum,snum)==FAIL)){ + while((size>0) && (getFrameandPacketNumber(ithread, latestData[ithread]+offset, fnum, pnum,snum,bid)==FAIL)){ offset+= onePacketSize; } //if(!ithread) cout<< ithread <<" fnum:"<< fnum<<" pnum:"<pop(buffer[ithread]); -#ifdef EVERYFIFODEBUG - if(fifoFree[ithread]->getSemValue()<100) - cprintf(BLUE,"FifoFree[%d]: value:%d, pop 0x%x\n",ithread,fifoFree[ithread]->getSemValue(),(void*)(buffer[ithread])); -#endif -#ifdef CFIFODEBUG - if(ithread == 0) - cprintf(CYAN,"Listening_Thread %d :Listener popped from fifofree %p\n", ithread, (void*)(buffer[ithread])); - else - cprintf(YELLOW,"Listening_Thread %d :Listener popped from fifofree %p\n", ithread, (void*)(buffer[ithread])); -#endif - - //udpsocket doesnt exist if(activated && !udpSocket[ithread]){ FILE_LOG(logERROR) << "Listening_Thread " << ithread << ": UDP Socket not created or shut down earlier"; @@ -2070,44 +2064,27 @@ void UDPStandardImplementation::startListening(){ continue; } - rc = prepareAndListenBuffer(ithread, carryonBufferSize, tempBuffer); - carryonBufferSize = 0; + if(!activated) //eiger not activated modules + rc = prepareAndListenBufferDeactivated(ithread); + else if(excludeMissingPackets) //eiger and jungfrau + rc = prepareAndListenBufferCompleteFrames(ithread); + else{ + rc = prepareAndListenBuffer(ithread, carryonBufferSize, tempBuffer); //others + carryonBufferSize = 0; + } - //start indices for each start of scan/acquisition - if((!measurementStarted[ithread]) && (rc > 0)) - startFrameIndices(ithread); //problem in receiving or end of acquisition if (status == TRANSMITTING||(rc == 0 && activated == 0)){ stopListening(ithread,rc); continue; } - //write packet count to buffer - if(myDetectorType == JUNGFRAU) - (*((uint32_t*)(buffer[ithread]))) = (rc/oneDataSize); - else - (*((uint32_t*)(buffer[ithread]))) = (rc/onePacketSize); - if(dataCompressionEnable) (*((uint32_t*)(buffer[ithread]))) = processListeningBuffer(ithread, carryonBufferSize, tempBuffer, rc); - //push buffer to FIFO while(!fifo[ithread]->push(buffer[ithread])); -#ifdef EVERYFIFODEBUG - if(fifo[ithread]->getSemValue()>(fifoSize-100)) - cprintf(MAGENTA,"Fifo[%d]: value:%d, push 0x%x\n",ithread,fifo[ithread]->getSemValue(),(void*)(buffer[ithread])); -#endif -#ifdef CFIFODEBUG - if(ithread == 0) - cprintf(CYAN,"Listening_Thread %d: Listener pushed into fifo %p\n",ithread, (void*)(buffer[ithread])); - else - cprintf(YELLOW,"Listening_Thread %d: Listener pushed into fifo %p\n",ithread, (void*)(buffer[ithread])); - -#endif - - }/*--end of loop for each buffer (inner loop)*/ //end of acquisition, wait for next acquisition/change of parameters @@ -2134,173 +2111,22 @@ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int cSize, ch int receivedSize = 0; //carry over from previous buffer - if(cSize) memcpy(buffer[ithread] + fifoBufferHeaderSize, temp, cSize); + if(cSize) + memcpy(buffer[ithread] + fifoBufferHeaderSize, temp, cSize); + //listen to after the carry over buffer + if(status != TRANSMITTING) + receivedSize = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + fifoBufferHeaderSize + cSize, + (bufferSize * numberofJobsPerBuffer) - cSize); - if(!activated){ + //write packet count to buffer + *((uint32_t*)(buffer[ithread])) = (receivedSize/onePacketSize); + totalListeningPacketCount[ithread] += (receivedSize/onePacketSize); - //cSize = 0 for deactivated - int framestoclone = 0; - //first - if(deactivatedFrameNumber[ithread]==0) - deactivatedFrameNumber[ithread]++; - //done - if(deactivatedFrameNumber[ithread] == (numberOfFrames+1)) - return 0; - //last - if((deactivatedFrameNumber[ithread] + deactivatedFrameIncrement) > (numberOfFrames+1)) - framestoclone = (numberOfFrames+1) - deactivatedFrameNumber[ithread]; - //in progress - else - framestoclone = deactivatedFrameIncrement; + //start indices for each start of scan/acquisition + if((!measurementStarted[ithread]) && (receivedSize > 0)) + startFrameIndices(ithread); - //copy dummy packets - receivedSize = framestoclone*packetsPerFrame*onePacketSize; - memset(buffer[ithread] + fifoBufferHeaderSize, 0xFF,receivedSize); - - //set fnum, pnum and deactivatedpacket label - eiger_packet_header_t* header; - eiger_packet_footer_t* footer; - uint32_t pnum=0; - //loop by each packet - for(int offset=fifoBufferHeaderSize; - offsetpacketNumber) = ++pnum; -#ifdef MANUALDEBUG - if(!ithread){ - cprintf(GREEN,"thread:%d pnum:%d fnum:%d\n", - ithread, - (*( (uint16_t*) footer->packetNumber)), - (uint32_t)(*( (uint64_t*) footer))); - } -#endif - if(pnum == packetsPerFrame){ - pnum = 0; - deactivatedFrameNumber[ithread]++; - } - } - - return receivedSize; - } - - - if(myDetectorType == JUNGFRAU){ - - jfrau_packet_header_t* header; - int offset = fifoBufferHeaderSize; - uint32_t pnum = packetsPerFrame-1; - uint32_t currentpnum; - - //read first packet - receivedSize=0; - if(status != TRANSMITTING) - receivedSize = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + offset); - if(!receivedSize) return 0; - header = (jfrau_packet_header_t*)(buffer[ithread] + offset); - currentpnum = (*( (uint8_t*) header->packetNumber)); - //cout<<"1 currentpnum:"<frameNumber))&frameIndexMask); - (*((uint64_t*)(buffer[ithread]+HEADER_SIZE_NUM_TOT_PACKETS+JFRAU_FILE_HEADER_BUNCHID_OFFSET))) = (*( (uint64_t*) header->bunchid)); - //cout<<"current fnum:"<<(*((uint32_t*)(buffer[ithread]+8)))<ReceiveDataOnly(buffer[ithread] + offset); - if(!receivedSize){ - totalIgnoredPacketCount[ithread] += (packetsPerFrame - pnum); - return 0; - } - totalListeningPacketCount[ithread]++; - header = (jfrau_packet_header_t*)(buffer[ithread] + offset); - currentpnum = (*( (uint8_t*) header->packetNumber)); - //cout<<"next currentpnum :"<ReceiveDataOnly(buffer[ithread] + offset); - if(!receivedSize) return 0; - totalListeningPacketCount[ithread]++; - header = (jfrau_packet_header_t*)(buffer[ithread] + offset); - currentpnum = (*( (uint8_t*) header->packetNumber)); - //cout<<"trying to find: currentpnum:"<ReceiveDataOnly(buffer[ithread] + fifoBufferHeaderSize + cSize, (bufferSize * numberofJobsPerBuffer) - cSize); - //eiger returns 0 when header packet caught - while(receivedSize < onePacketSize && status != TRANSMITTING) - receivedSize = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + fifoBufferHeaderSize + cSize, (bufferSize * numberofJobsPerBuffer) - cSize); - - - } - - totalListeningPacketCount[ithread] += (receivedSize/onePacketSize); - - -#ifdef MANUALDEBUG - if(receivedSize>0){ - if(myDetectorType == JUNGFRAU){ - jfrau_packet_header_t* header; - - for(int iloop=0;iloop<128;iloop++){ - header = (jfrau_packet_header_t*)(buffer[ithread] + fifoBufferHeaderSize + iloop * (JFRAU_HEADER_LENGTH+JFRAU_ONE_DATA_SIZE)); - cprintf(RED,"[%d]: packetnumber:%d\n",iloop, (*( (uint8_t*) header->packetNumber))); - cprintf(RED," : framenumber :%d\n", (*( (uint32_t*) header->frameNumber))&frameIndexMask); - } - }else if(myDetectorType == EIGER){ - eiger_packet_header_t* header = (eiger_packet_header_t*) (buffer[ithread]+fifoBufferHeaderSize); - eiger_packet_footer_t* footer = (eiger_packet_footer_t*)(buffer[ithread] + footerOffset + fifoBufferHeaderSize); - cprintf(GREEN,"thread:%d footeroffset:%dsubframenum:%d oldpacketnum:%d new pnum:%d new fnum:%d\n", - ithread,footerOffset, - (*( (unsigned int*) header->subFrameNumber)), - (*( (uint8_t*) header->dynamicRange)), - (*( (uint16_t*) footer->packetNumber)), - (uint32_t)(*( (uint64_t*) footer))); - } - } -#endif #ifdef DEBUG cprintf(BLUE, "Listening_Thread %d : Received bytes: %d. Expected bytes: %d\n", ithread, receivedSize, bufferSize * numberofJobsPerBuffer-cSize); #endif @@ -2312,16 +2138,188 @@ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int cSize, ch + +int UDPStandardImplementation::prepareAndListenBufferDeactivated(int ithread){ + FILE_LOG(logDEBUG) << __AT__ << " called"; + + //last + if(currentFrameNumber[ithread] == numberOfFrames) + return 0; + + //copy dummy packets + memset(buffer[ithread] + fifoBufferHeaderSize, 0xFF,bufferSize); + + //write fnum and number of packets + (*((uint64_t*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS))) = currentFrameNumber[ithread]+1; + (*((uint32_t*)(buffer[ithread]))) = packetsPerFrame; + + //start indices for each start of scan/acquisition (rc > 0) + if(!measurementStarted[ithread]) + startFrameIndices(ithread); + + return bufferSize; +} + + + + +int UDPStandardImplementation::prepareAndListenBufferCompleteFrames(int ithread){ + FILE_LOG(logDEBUG) << __AT__ << " called"; + + int headerlength = 0; + uint32_t LASTPNUM = 0; + uint32_t FIRSTPNUM = 0; + int INCORDECR = 0; + switch(myDetectorType){ + case JUNGFRAU: + headerlength = JFRAU_HEADER_LENGTH; + FIRSTPNUM = packetsPerFrame-1; + LASTPNUM = 0; + INCORDECR = -1; + break; + case EIGER: + headerlength = EIGER_DATA_PACKET_HEADER_SIZE; + FIRSTPNUM = 0; + LASTPNUM = packetsPerFrame-1; + INCORDECR = 1; + break; + default:break; + } + + + int offset = fifoBufferHeaderSize; + uint32_t pnum = 0; + uint64_t fnum = 0; + uint64_t bnum = 0; + int rc = 0; + //from getframeandpacketnumber() + uint32_t pi = 0; + uint64_t fi = 0; + uint64_t bi = 0; + uint32_t si = 0; + + + //read first packet + pnum = FIRSTPNUM; //first packet number to validate + if(status != TRANSMITTING) rc = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + offset); + if(!rc) return 0; + if(getFrameandPacketNumber(ithread,buffer[ithread] + offset,fi,pi,si,bi) == FAIL) + pi = ALL_MASK_32; //got 0 from fpga + fnum = fi; //fnum of first packet + bnum = bi; //bnum of first packet + totalListeningPacketCount[ithread]++; +#ifdef VERBOSE + if(!ithread) cout << "1 pnum:" << pnum << endl; +#endif + //start indices for each start of scan/acquisition (rc > 0) + if(!measurementStarted[ithread]) + startFrameIndices(ithread); + + + while(true){ + + //------------------------------------------------------ correct packet -------------------------------------------------------- + if((myDetectorType == JUNGFRAU && pnum == pi) || //jungfrau only looks at pnum + (myDetectorType == EIGER && pnum == pi && fnum == fi)){ // eiger looks at pnum and fnum +#ifdef VERBOSE + if(!ithread) cout << "correct packet" << endl; +#endif + //copy only data + memcpy(buffer[ithread] + offset,buffer[ithread] + offset + headerlength, oneDataSize); + offset+=oneDataSize; + + //if complete frame + if(pnum == LASTPNUM) + break; + //else increment/decrement + pnum += INCORDECR; + + rc=0; //listen again + if(status != TRANSMITTING) + rc = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + offset); + if(!rc){ //end: update ignored and return + if(myDetectorType == JUNGFRAU) + totalIgnoredPacketCount[ithread] += (packetsPerFrame - pnum); + else + totalIgnoredPacketCount[ithread] += (pnum + 1); + return 0; + } + totalListeningPacketCount[ithread]++; + if(getFrameandPacketNumber(ithread, buffer[ithread] + offset,fi,pi,si,bi) == FAIL) + pi = ALL_MASK_32; //got 0 from fpga + if(myDetectorType == EIGER) + fnum = fi; //update currentfnum for eiger (next packets should have currentfnum value) +#ifdef VERBOSE + if(!ithread) cout << "next currentpnum :" << pnum << endl; +#endif + } + + //------------------------------------------------------ wrong packet -------------------------------------------------------- + else{ +#ifdef VERBOSE + if(!ithread) cprintf(RED,"wrong packet %d, expected packet %d fnum of last good one:%d\n", + pi,pnum,(*((uint32_t*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS)))); +#endif + if(myDetectorType == JUNGFRAU) + totalIgnoredPacketCount[ithread] += (packetsPerFrame - pnum -1); //extra 1 subtracted now to be added in the while loop anyway + else + totalIgnoredPacketCount[ithread] += pnum; //extra 1 subtracted now to be added in the while loop anyway + pnum = FIRSTPNUM; + offset = fifoBufferHeaderSize; + + //find the start of next image + while(pnum != pi){ + totalIgnoredPacketCount[ithread]++; + + rc=0; + if(status != TRANSMITTING) + rc = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + offset); + if(!rc){ + if(myDetectorType == JUNGFRAU) + totalIgnoredPacketCount[ithread] += (packetsPerFrame - pnum); + else + totalIgnoredPacketCount[ithread] += (pnum + 1); + return 0; + } + totalListeningPacketCount[ithread]++; + if(getFrameandPacketNumber(ithread, buffer[ithread] + offset,fi,pi,si,bi) == FAIL) + pi = ALL_MASK_32; //got 0 from fpga +#ifdef VERBOSE + if(!ithread) cout << "trying to find pnum:" << pnum << " got " << pi << endl; +#endif + } + fnum = fi; //fnum of first packet + bnum = bi; //bnum of first packet + } + } + //------------------------------------------------------ got a complete frame -------------------------------------------------------- + + //write frame number + (*((uint64_t*)(buffer[ithread]+HEADER_SIZE_NUM_TOT_PACKETS))) = fnum + startAcquisitionIndex; +#ifdef VERBOSE + if(!ithread) cout << "fnum:" << (*((uint64_t*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS))) << endl; +#endif + if(myDetectorType == JUNGFRAU) + (*((uint64_t*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS + FILE_HEADER_BUNCHID_OFFSET))) = bnum; + //write packet count to buffer + *((uint32_t*)(buffer[ithread])) = packetsPerFrame; + return bufferSize; +} + + + void UDPStandardImplementation::startFrameIndices(int ithread){ FILE_LOG(logDEBUG) << __AT__ << " called"; - //determine startFrameIndex + + jfrau_packet_header_t* header=0; switch(myDetectorType){ case EIGER: - startFrameIndex = 0; //frame number always resets + startFrameIndex = 1; //frame number always resets break; case JUNGFRAU: - startFrameIndex = (*((uint32_t*)(buffer[ithread]+HEADER_SIZE_NUM_TOT_PACKETS))); + header = (jfrau_packet_header_t*)(buffer[ithread]+HEADER_SIZE_NUM_TOT_PACKETS); + startFrameIndex = (*( (uint32_t*) header->frameNumber))&frameIndexMask; break; default: if(shortFrameEnable < 0){ @@ -2361,103 +2359,45 @@ void UDPStandardImplementation::stopListening(int ithread, int numbytes){ cprintf(BLUE,"Listening_Thread %d: Stop Listening\nStatus: %s numbytes:%d\n", ithread, runStatusType(status).c_str(),numbytes); #endif - //less than 1 packet size (especially for eiger), ignore the buffer (so that 2 dummy buffers are not sent with pc=0) - if(numbytes < onePacketSize) - numbytes = 0; - - //free empty buffer if(numbytes <= 0){ FILE_LOG(logINFO) << "Listening "<< ithread << ": End of Acquisition"; while(!fifoFree[ithread]->push(buffer[ithread])); -#ifdef EVERYFIFODEBUG - if(fifoFree[ithread]->getSemValue()<100) - cprintf(GREEN,"Fifofree[%d]: value:%d, push 0x%x\n",ithread,fifoFree[ithread]->getSemValue(),(void*)(buffer[ithread])); -#endif -#ifdef CFIFODEBUG - if(ithread == 0) - cprintf(CYAN,"Listening_Thread %d :Listener push empty buffer into fifofree %p\n", ithread, (void*)(buffer[ithread])); - else - cprintf(YELLOW,"Listening_Thread %d :Listener push empty buffer into fifofree %p\n", ithread, (void*)(buffer[ithread])); -#endif } //push last non empty buffer into fifo else{ - (*((uint32_t*)(buffer[ithread]))) = numbytes/onePacketSize; - totalListeningPacketCount[ithread] += (numbytes/onePacketSize); + if(excludeMissingPackets){ + (*((uint32_t*)(buffer[ithread]))) = numbytes/oneDataSize; + totalListeningPacketCount[ithread] += (numbytes/oneDataSize); + }else{ + (*((uint32_t*)(buffer[ithread]))) = numbytes/onePacketSize; + totalListeningPacketCount[ithread] += (numbytes/onePacketSize); + } #ifdef DEBUG cprintf(BLUE,"Listening_Thread %d: Last Buffer numBytes:%d\n",ithread, numbytes); - cprintf(BLUE,"Listening_Thread %d: Last Buffer packet count:%d\n",ithread, numbytes/onePacketSize); + cprintf(BLUE,"Listening_Thread %d: Last Buffer packet count:%d\n",ithread,(*((uint32_t*)(buffer[ithread]))) ); #endif while(!fifo[ithread]->push(buffer[ithread])); -#ifdef EVERYFIFODEBUG - if(fifo[ithread]->getSemValue()>(fifoSize-100)) - cprintf(MAGENTA,"Fifo[%d]: value:%d, push 0x%x\n",ithread,fifo[ithread]->getSemValue(),(void*)(buffer[ithread])); -#endif -#ifdef CFIFODEBUG - if(ithread == 0) - cprintf(CYAN,"Listening_Thread %d: Listener Last Buffer pushed into fifo %p\n", ithread,(void*)(buffer[ithread])); - else - cprintf(YELLOW,"Listening_Thread %d: Listener Last Buffer pushed into fifo %p\n", ithread,(void*)(buffer[ithread])); -#endif } //push dummy-end buffer into fifo for all writer threads fifoFree[ithread]->pop(buffer[ithread]); -#ifdef EVERYFIFODEBUG - if(fifoFree[ithread]->getSemValue()<100) - cprintf(BLUE,"FifoFree[%d]: value:%d, pop 0x%x\n",ithread,fifoFree[ithread]->getSemValue(),(void*)(buffer[ithread])); -#endif -#ifdef CFIFODEBUG - if(ithread == 0) - cprintf(CYAN,"Listening_Thread %d: Popped Dummy from fifoFree %p\n", ithread,(void*)(buffer[ithread])); - else - cprintf(YELLOW,"Listening_Thread %d: Popped Dummy from fifoFree %p\n", ithread,(void*)(buffer[ithread])); -#endif + //creating dummy-end buffer with pc=0xFFFF (*((uint32_t*)(buffer[ithread]))) = dummyPacketValue; while(!fifo[ithread]->push(buffer[ithread])); -#ifdef EVERYFIFODEBUG - if(fifo[ithread]->getSemValue()>(fifoSize-100)) - cprintf(MAGENTA,"Fifo[%d]: value:%d, push 0x%x\n",ithread,fifo[ithread]->getSemValue(),(void*)(buffer[ithread])); -#endif -#ifdef CFIFODEBUG - if(ithread == 0) - cprintf(CYAN,"Listening_Thread %d: Listener pushed dummy-end buffer into fifo %p\n", ithread,(void*)(buffer[ithread])); - else - cprintf(YELLOW,"Listening_Thread %d: Listener pushed dummy-end buffer into fifo %p\n", ithread,(void*)(buffer[ithread])); -#endif - //reset mask and exit loop pthread_mutex_lock(&statusMutex); listeningThreadsMask^=(1< 1) - cprintf(BLUE,"Listening_Thread %d: Waiting for other listening threads to be done.. current mask:0x%x\n", ithread, listeningThreadsMask); -#endif - while(listeningThreadsMask) - usleep(5000); -#ifdef DEBUG4 - int t=0; - for(i=0;iframeNumber))&frameIndexMask, - (*( (uint8_t*) header->packetNumber))); -#endif - header = (jfrau_packet_header_t*) (buffer[ithread]+lastPacketOffset); -#ifdef DEBUG4 - cprintf(BLUE, "Listening_Thread: Last Header:%du\t Last Packet:%d\n", - (*( (uint32_t*) header->frameNumber))&frameIndexMask, - (*( (uint8_t*) header->packetNumber))); -#endif - //jungfrau last packet value is 0, so find the last packet and store the others in a temp storage - if((*( (uint8_t*) header->packetNumber))){ - //cprintf(RED,"entering missing packet zone\n"); - lastFrameHeader64 = (*( (uint32_t*) header->frameNumber))&frameIndexMask; - cSize += onePacketSize; - lastPacketOffset -= onePacketSize; - --packetCount; - while (lastFrameHeader64 == ((*( (uint32_t*) header->frameNumber))&frameIndexMask)){ - cSize += onePacketSize; - lastPacketOffset -= onePacketSize; - header = (jfrau_packet_header_t*) (buffer[ithread]+lastPacketOffset); -#ifdef DEBUG4 - cprintf(RED,"new header:%d new packet:%d\n", - (*( (uint32_t*) header->frameNumber))&frameIndexMask, - (*( (uint8_t*) header->packetNumber))); -#endif - --packetCount; - } - memcpy(temp, buffer[ithread]+(lastPacketOffset+onePacketSize), cSize); - } - - break; - default: cprintf(RED,"Listening_Thread %d: Error: This detector %s is not implemented in the receiver\n", ithread, getDetectorType(myDetectorType).c_str()); @@ -2591,15 +2493,12 @@ uint32_t UDPStandardImplementation::processListeningBuffer(int ithread, int &cSi void UDPStandardImplementation::startWriting(){ FILE_LOG(logDEBUG) << __AT__ << " called"; - //set current thread value index - int ithread = currentThreadIndex; - //let calling function know thread started and obtained current - threadStarted = 1; + int ithread = currentThreadIndex; //set current thread value index + threadStarted = 1; //let calling function know thread started and obtained current - //variable definitions - char* wbuf=NULL; //buffer popped from FIFO + char* wbuf = NULL; //buffer popped from FIFO sfilefd[ithread] = 0; //file pointer - uint64_t nf=0; //for compression, number of frames + uint64_t nf = 0; //for compression, number of frames int listenfifoIndex = ithread; @@ -2607,10 +2506,12 @@ void UDPStandardImplementation::startWriting(){ //infinite loop, exited only to change dynamic range, 10G parameters etc (then recreated again) while(true){ - //--reset parameters before acquisition - nf = 0; + //--reset parameters before acquisition (depending on compression) + nf = 0; //compression has only one listening thread (anything not eiger) if(dataCompressionEnable) - listenfifoIndex = 0; //compression has only one listening thread + listenfifoIndex = 0; //compression has only one listening thread (anything not eiger) + else + listenfifoIndex = ithread; /* inner loop - loop for each buffer */ @@ -2618,13 +2519,6 @@ void UDPStandardImplementation::startWriting(){ while((1 << ithread) & writerThreadsMask){ //pop fifo[listenfifoIndex]->pop(wbuf); -#ifdef EVERYFIFODEBUG - if(fifo[listenfifoIndex]->getSemValue()>(fifoSize-100)) - cprintf(CYAN,"Fifo[%d]: value:%d, pop 0x%x\n",listenfifoIndex,fifo[listenfifoIndex]->getSemValue(),(void*)(wbuf)); -#endif -#ifdef DEBUG4 - cprintf(GREEN,"Writing_Thread %d: Popped %p from FIFO %d\n", ithread, (void*)(wbuf),listenfifoIndex); -#endif uint32_t numPackets = (uint32_t)(*((uint32_t*)wbuf)); #ifdef DEBUG4 cprintf(GREEN,"Writing_Thread %d: Number of Packets: %d for FIFO %d\n", ithread, numPackets, listenfifoIndex); @@ -2640,11 +2534,9 @@ void UDPStandardImplementation::startWriting(){ continue; } - - - //jungfrau - if(myDetectorType == JUNGFRAU) - handleWithoutMissingPackets(ithread, wbuf, numPackets); + //jungfrau and eiger + if(excludeMissingPackets) + handleCompleteFramesOnly(ithread, wbuf); //normal else if(!dataCompressionEnable) handleWithoutDataCompression(ithread, wbuf, numPackets); @@ -2697,10 +2589,6 @@ void UDPStandardImplementation::waitWritingBufferForNextAcquisition(int ithread) cprintf(RED,"%d:fifo emptied\n", ithread); fifo[ithread]->pop(temp); fifoFree[ithread]->push(temp); -#ifdef EVERYFIFODEBUG - if(fifo[ithread]->getSemValue()>(fifoSize-100)) - cprintf(CYAN,"Fifo[%d]: value:%d, pop 0x%x\n",ithread,fifo[ithread]->getSemValue(),(void*)(temp)); -#endif } //create file @@ -2779,60 +2667,51 @@ void UDPStandardImplementation::stopWriting(int ithread, char* wbuffer){ //free fifo while(!fifoFree[ithread]->push(wbuffer)); -#ifdef EVERYFIFODEBUG - if(fifoFree[ithread]->getSemValue()<100) - cprintf(GREEN,"FifoFree[%d]: value:%d, push 0x%x\n",ithread,fifoFree[ithread]->getSemValue(),(void*)(wbuffer)); -#endif -#ifdef CFIFODEBUG - if(ithread==0) - cprintf(CYAN,"Writing_Thread %d: Freeing dummy-end buffer. Pushed into fifofree %p for listener %d\n", ithread,(void*)(wbuffer),ithread); - else - cprintf(YELLOW,"Writing_Thread %d: Freeing dummy-end buffer. Pushed into fifofree %p for listener %d\n", ithread,(void*)(wbuffer),ithread); -#endif if(dataStreamEnable){ - //ensure previous frame was processed - sem_wait(&writerGuiSemaphore[ithread]); + sem_wait(&writerGuiSemaphore[ithread]); //ensure previous frame was processed guiNumPackets[ithread] = dummyPacketValue; - //let it know its got data - sem_post(&dataCallbackWriterSemaphore[ithread]); + sem_post(&dataCallbackWriterSemaphore[ithread]); //let it know its got data } //all threads need to close file, reset mask and exit loop - missingPacketinFile = (long long int)numberOfFrames*packetsPerFrame-totalWritingPacketCount[ithread]; - if(myDetectorType == EIGER && fileWriteEnable && (cbAction > DO_NOTHING) && missingPacketinFile){ + if(myDetectorType == EIGER && fileWriteEnable && (cbAction > DO_NOTHING)){ updateFileHeader(ithread); fseek(sfilefd[ithread],0,0); fwrite((void*)fileHeader[ithread], 1, FILE_HEADER_SIZE, sfilefd[ithread]); } //Print packet loss - if(totalWritingPacketCountFromLastCheck[ithread]){ + //if(totalWritingPacketCountFromLastCheck[ithread]){ if(numberofWriterThreads>1){ printf("Thread:%d" "\tLost:%lld" - "\tPackets:%lld" + "\t\tPackets:%lld" "\tFrame#:%lld" - "\tPFrame#r:%lld\n", + "\tPFrame#:%lld\n", ithread, - (long long int)(((currentFrameNumber[ithread]-frameNumberInPreviousCheck[ithread])*packetsPerFrame) - totalWritingPacketCountFromLastCheck[ithread]), + ((frameNumberInPreviousCheck[ithread]+1+(maxFramesPerFile/progressFrequency))>numberOfFrames) + ?(long long int)((numberOfFrames-(frameNumberInPreviousCheck[ithread]+1))*packetsPerFrame - totalWritingPacketCountFromLastCheck[ithread]) + :(long long int)((frameNumberInPreviousCheck[ithread]+(maxFramesPerFile/progressFrequency) - frameNumberInPreviousCheck[ithread])*packetsPerFrame - totalWritingPacketCountFromLastCheck[ithread]), (long long int)totalWritingPacketCountFromLastCheck[ithread], (long long int)currentFrameNumber[ithread], (long long int)frameNumberInPreviousCheck[ithread] ); }else{ printf("Lost:%lld" - "\tPackets:%lld" + "\t\tPackets:%lld" "\tFrame#:%lld" "\tPFrame#:%lld\n", - (long long int)(((currentFrameNumber[ithread]-frameNumberInPreviousCheck[ithread])*packetsPerFrame) - totalWritingPacketCountFromLastCheck[ithread]), + ((frameNumberInPreviousCheck[ithread]+1+(maxFramesPerFile/progressFrequency))>numberOfFrames) + ?(long long int)((numberOfFrames-(frameNumberInPreviousCheck[ithread]+1))*packetsPerFrame - totalWritingPacketCountFromLastCheck[ithread]) + :(long long int)((frameNumberInPreviousCheck[ithread]+(maxFramesPerFile/progressFrequency) - frameNumberInPreviousCheck[ithread])*packetsPerFrame - totalWritingPacketCountFromLastCheck[ithread]), (long long int)totalWritingPacketCountFromLastCheck[ithread], (long long int)currentFrameNumber[ithread], (long long int)frameNumberInPreviousCheck[ithread] ); } - } + //} closeFile(ithread); pthread_mutex_lock(&statusMutex); @@ -2865,7 +2744,7 @@ void UDPStandardImplementation::stopWriting(int ithread, char* wbuffer){ if(totalWritingPacketCount[i] < ((uint64_t)numberOfFrames*packetsPerFrame)){ cprintf(RED, "\nPort %d\n",udpPortNum[i]); - if(myDetectorType == JUNGFRAU){ + if(excludeMissingPackets){ cprintf(RED, "Ignored Packets \t: %lld\n",(long long int)totalIgnoredPacketCount[i]); cprintf(RED, "Missing Packets \t: %lld\n",(long long int)numberOfFrames*packetsPerFrame-totalWritingPacketCount[i]-totalIgnoredPacketCount[i]); }else @@ -2880,7 +2759,7 @@ void UDPStandardImplementation::stopWriting(int ithread, char* wbuffer){ cprintf(RED, "Last Frame Number Caught :%lld\n",(long long int)lastFrameNumber); }else{ cprintf(GREEN, "\nPort %d\n",udpPortNum[i]); - if(myDetectorType == JUNGFRAU){ + if(excludeMissingPackets){ cprintf(GREEN, "Ignored Packets \t: %lld\n",(long long int)totalIgnoredPacketCount[i]); cprintf(GREEN, "Missing Packets \t: %lld\n",(long long int)numberOfFrames*packetsPerFrame-totalWritingPacketCount[i]-totalIgnoredPacketCount[i]); }else @@ -2913,7 +2792,8 @@ void UDPStandardImplementation::handleWithoutDataCompression(int ithread, char* uint64_t tempframenumber; uint32_t pnum; uint32_t snum; - if(getFrameandPacketNumber(ithread, wbuffer + fifoBufferHeaderSize,tempframenumber,pnum,snum) == FAIL){ + uint64_t bunchid; + if(getFrameandPacketNumber(ithread, wbuffer + fifoBufferHeaderSize,tempframenumber,pnum,snum,bunchid) == FAIL){ //error in frame number sent by fpga while(!fifoFree[ithread]->push(wbuffer)); @@ -2962,96 +2842,102 @@ void UDPStandardImplementation::handleWithoutDataCompression(int ithread, char* -void UDPStandardImplementation::handleWithoutMissingPackets(int ithread, char* wbuffer, uint32_t npackets){ +void UDPStandardImplementation::handleCompleteFramesOnly(int ithread, char* wbuffer){ FILE_LOG(logDEBUG) << __AT__ << " called"; //get current frame number uint64_t tempframenumber; - tempframenumber = (*((uint32_t*)(wbuffer+HEADER_SIZE_NUM_TOT_PACKETS))); - //cout<<"handling: before frame number:"< 0){ - if((fileWriteEnable) && (sfilefd[ithread])){ - if(tempframenumber && (tempframenumber%maxFramesPerFile) == 0){ - createNewFile(ithread); - } - fwrite(wbuffer + HEADER_SIZE_NUM_TOT_PACKETS, 1, oneDataSize*packetsPerFrame+fifoBufferHeaderSize-HEADER_SIZE_NUM_TOT_PACKETS, sfilefd[ithread]); - } + if((fileWriteEnable) && (sfilefd[ithread])){ + if(tempframenumber && (tempframenumber%maxFramesPerFile) == 0) + createNewFile(ithread); + fwrite(wbuffer + HEADER_SIZE_NUM_TOT_PACKETS, 1, bufferSize + FILE_FRAME_HEADER_LENGTH, sfilefd[ithread]); + } - - //Print packet loss and filenames - if(tempframenumber && (tempframenumber%(maxFramesPerFile/10)) == 0){ - printf("Lost:%lld" - "\tPackets:%lld" + //progress + if(tempframenumber && (tempframenumber%(maxFramesPerFile/progressFrequency)) == 0){ + if(numberofWriterThreads>1){ + printf("Thread:%d" + "\tLost:%lld" + "\t\tPackets:%lld" "\tFrame#:%lld" "\tPFrame#:%lld\n", - (long long int)(((currentFrameNumber[ithread]-frameNumberInPreviousCheck[ithread])*packetsPerFrame) - totalWritingPacketCountFromLastCheck[ithread]), + ithread, + ((frameNumberInPreviousCheck[ithread]+1+(maxFramesPerFile/progressFrequency))>numberOfFrames) + ?(long long int)((numberOfFrames-(frameNumberInPreviousCheck[ithread]+1))*packetsPerFrame - totalWritingPacketCountFromLastCheck[ithread]) + :(long long int)((frameNumberInPreviousCheck[ithread]+(maxFramesPerFile/progressFrequency) - frameNumberInPreviousCheck[ithread])*packetsPerFrame - totalWritingPacketCountFromLastCheck[ithread]), + (long long int)totalWritingPacketCountFromLastCheck[ithread], + (long long int)currentFrameNumber[ithread], + (long long int)frameNumberInPreviousCheck[ithread] + ); + }else{ + printf("Lost:%lld" + "\t\tPackets:%lld" + "\tFrame#:%lld" + "\tPFrame#:%lld\n", + ((frameNumberInPreviousCheck[ithread]+1+(maxFramesPerFile/progressFrequency))>numberOfFrames) + ?(long long int)((numberOfFrames-(frameNumberInPreviousCheck[ithread]+1))*packetsPerFrame - totalWritingPacketCountFromLastCheck[ithread]) + :(long long int)((frameNumberInPreviousCheck[ithread]+(maxFramesPerFile/progressFrequency) - frameNumberInPreviousCheck[ithread])*packetsPerFrame - totalWritingPacketCountFromLastCheck[ithread]), (long long int)totalWritingPacketCountFromLastCheck[ithread], (long long int)currentFrameNumber[ithread], (long long int)frameNumberInPreviousCheck[ithread] ); - - //reset counters for each new file - frameNumberInPreviousCheck[ithread] = currentFrameNumber[ithread]; - totalWritingPacketCountFromLastCheck[ithread] = 0; } - - - if(npackets!=128) exit(-1);/******************/ - totalWritingPacketCountFromLastCheck[ithread]+= npackets; - totalPacketsInFile[ithread] += npackets; - totalWritingPacketCount[ithread] += npackets; - lastFrameNumberInFile[ithread] = tempframenumber; - currentFrameNumber[ithread] = tempframenumber; - //cout<<"curentframenumber:"< 1) - pthread_mutex_lock(&writeMutex); - packetsCaught += npackets; - totalPacketsCaught += npackets; - if((currentFrameNumber[ithread] - startAcquisitionIndex) > acquisitionIndex) - acquisitionIndex = currentFrameNumber[ithread] - startAcquisitionIndex; - if((currentFrameNumber[ithread] - startFrameIndex) > frameIndex[ithread]) - frameIndex[ithread] = currentFrameNumber[ithread] - startFrameIndex; - - if(numberofWriterThreads > 1) - pthread_mutex_unlock(&writeMutex); - + //reset counters for each new file + frameNumberInPreviousCheck[ithread] = currentFrameNumber[ithread]; + totalWritingPacketCountFromLastCheck[ithread] = 0; } + + totalWritingPacketCountFromLastCheck[ithread]+= packetsPerFrame; + totalPacketsInFile[ithread] += packetsPerFrame; + totalWritingPacketCount[ithread] += packetsPerFrame; + lastFrameNumberInFile[ithread] = tempframenumber; + currentFrameNumber[ithread] = tempframenumber; + //cout<<"curentframenumber:"< 1) + pthread_mutex_lock(&writeMutex); + + packetsCaught += packetsPerFrame; + totalPacketsCaught += packetsPerFrame; + if((currentFrameNumber[ithread] - startAcquisitionIndex) > acquisitionIndex) + acquisitionIndex = currentFrameNumber[ithread] - startAcquisitionIndex; + if((currentFrameNumber[ithread] - startFrameIndex) > frameIndex[ithread]) + frameIndex[ithread] = currentFrameNumber[ithread] - startFrameIndex; + + if(numberofWriterThreads > 1) + pthread_mutex_unlock(&writeMutex); + + if(!activated) + currentFrameNumber[ithread]++; + #ifdef DEBUG4 cprintf(GREEN,"Writing_Thread: Writing done\nGoing to copy frame\n"); #endif //copy frame for gui - //if(npackets >= (packetsPerFrame/numberofListeningThreads)) - if(dataStreamEnable && npackets > 0) - copyFrameToGui(ithread, wbuffer,npackets); + if(dataStreamEnable) + copyFrameToGui(ithread, wbuffer, packetsPerFrame); #ifdef DEBUG4 cprintf(GREEN,"Writing_Thread: Copied frame\n"); #endif //free fifo addresses - int listenfifoThread = ithread; - if(dataCompressionEnable) - listenfifoThread = 0; - while(!fifoFree[listenfifoThread]->push(wbuffer)); -#ifdef EVERYFIFODEBUG - if(fifoFree[listenfifoThread]->getSemValue()<100) - cprintf(GREEN,"FifoFree[%d]: value:%d, push 0x%x\n",listenfifoThread,fifoFree[listenfifoThread]->getSemValue(),(void*)(wbuffer)); -#endif + while(!fifoFree[ithread]->push(wbuffer)); #ifdef DEBUG5 - cprintf(GREEN,"Writing_Thread %d: Freed buffer, pushed into fifofree %p for listener %d \n",listenfifoThread, (void*)(wbuffer), listenfifoThread); + cprintf(GREEN,"Writing_Thread %d: Freed buffer, pushed into fifofree %p for listener %d \n",ithread, (void*)(wbuffer), ithread); #endif } @@ -3076,8 +2962,9 @@ void UDPStandardImplementation::writeFileWithoutCompression(int ithread, char* w uint64_t startframe = 0; uint32_t pnum = 0; uint32_t snum = 0; + uint64_t bunchid = 0; //if(ithread) cout<<"getting start frame number"<push(wbuffer)); return; @@ -3136,7 +3023,8 @@ void UDPStandardImplementation::writeFileWithoutCompression(int ithread, char* w uint64_t finalLastFrameNumberToSave = 0; uint32_t pnum; uint32_t snum; - if(getFrameandPacketNumber(ithread, wbuffer + fifoBufferHeaderSize + ((numpackets - 1) * onePacketSize), finalLastFrameNumberToSave,pnum,snum) == FAIL){ + uint64_t bunchid = 0; + if(getFrameandPacketNumber(ithread, wbuffer + fifoBufferHeaderSize + ((numpackets - 1) * onePacketSize), finalLastFrameNumberToSave,pnum,snum,bunchid) == FAIL){ //error in frame number sent by fpga while(!fifoFree[ithread]->push(wbuffer)); return; @@ -3176,18 +3064,18 @@ void UDPStandardImplementation::updateFileHeader(int ithread){ "Top\t\t: %d\n" "Left\t\t: %d\n" "Active\t\t: %d\n" - "Packets Lost\t: %d\n" + "Frames Caught\t: %d\n" + "Frames Lost\t: %d\n" "Dynamic Range\t: %d\n" "Ten Giga\t: %d\n" "Packet\t\t: %d bytes\n" "Data\t\t: %d bytes\n" "x\t\t: %d pixels\n" "y\t\t: %d pixels\n" - "Frames\t\t: %lld\n" + "Total Frames\t: %lld\n" "Exptime (ns)\t: %lld\n" "Period (ns)\t: %lld\n" "Timestamp\t: %s\n\n" - //only for eiger right now "#Packet Header\n" "Subframe Number\t: 4 bytes\n" @@ -3200,7 +3088,10 @@ void UDPStandardImplementation::updateFileHeader(int ithread){ FILE_HEADER_SIZE, (bottomEnable?0:1),(ithread?0:1), activated, - missingPacketinFile, + (long long int)(totalPacketsInFile[ithread]/packetsPerFrame), + ((frameNumberInPreviousFile[ithread]+1+maxFramesPerFile)>numberOfFrames) + ?(long long int)((numberOfFrames-(frameNumberInPreviousFile[ithread]+1)) - (totalPacketsInFile[ithread]/packetsPerFrame)) + :(long long int)((frameNumberInPreviousFile[ithread]+maxFramesPerFile - frameNumberInPreviousFile[ithread]) - (totalPacketsInFile[ithread]/packetsPerFrame)), dynamicRange,tengigaEnable, onePacketSize,oneDataSize, //only for eiger right now @@ -3234,8 +3125,8 @@ void UDPStandardImplementation::copyFrameToGui(int ithread, char* buffer, uint32 //copy date guiNumPackets[ithread] = numpackets; strcpy(guiFileName[ithread],completeFileName[ithread]); - if(myDetectorType == JUNGFRAU) //copy also the header - memcpy(latestData[ithread],buffer+HEADER_SIZE_NUM_TOT_PACKETS, bufferSize+fifoBufferHeaderSize-HEADER_SIZE_NUM_TOT_PACKETS); + if(excludeMissingPackets) //copy also the header + memcpy(latestData[ithread],buffer+HEADER_SIZE_NUM_TOT_PACKETS, bufferSize + FILE_FRAME_HEADER_LENGTH); else //copy only the data memcpy(latestData[ithread],buffer+ fifoBufferHeaderSize , numpackets*onePacketSize); //let it know its got data @@ -3265,7 +3156,8 @@ void UDPStandardImplementation::handleDataCompression(int ithread, char* wbuffer uint64_t tempframenumber=-1; uint32_t pnum; uint32_t snum; - if(getFrameandPacketNumber(ithread, wbuffer + fifoBufferHeaderSize, tempframenumber,pnum,snum) == FAIL){ + uint64_t bunchid=-1; + if(getFrameandPacketNumber(ithread, wbuffer + fifoBufferHeaderSize, tempframenumber,pnum,snum,bunchid) == FAIL){ //error in frame number sent by fpga while(!fifoFree[ithread]->push(wbuffer)); return; @@ -3401,7 +3293,7 @@ void UDPStandardImplementation::handleDataCompression(int ithread, char* wbuffer -int UDPStandardImplementation::getFrameandPacketNumber(int ithread, char* wbuffer, uint64_t &framenumber, uint32_t &packetnumber,uint32_t &subframenumber){ +int UDPStandardImplementation::getFrameandPacketNumber(int ithread, char* wbuffer, uint64_t &framenumber, uint32_t &packetnumber,uint32_t &subframenumber, uint64_t &bunchid){ FILE_LOG(logDEBUG) << __AT__ << " called"; eiger_packet_footer_t* footer=0; @@ -3410,6 +3302,7 @@ int UDPStandardImplementation::getFrameandPacketNumber(int ithread, char* wbuffe framenumber = 0; packetnumber = 0; subframenumber = 0; + bunchid = 0; switch(myDetectorType){ @@ -3417,7 +3310,7 @@ int UDPStandardImplementation::getFrameandPacketNumber(int ithread, char* wbuffe footer = (eiger_packet_footer_t*)(wbuffer + footerOffset); framenumber = (uint32_t)(*( (uint64_t*) footer)); //error in frame number sent by fpga - if(!((uint32_t)(*( (uint64_t*) footer)))){ + if(((uint32_t)(*( (uint64_t*) footer)))==0){ framenumber = 0; FILE_LOG(logERROR) << "Fifo "<< ithread << ": Frame Number is zero from firmware."; return FAIL; @@ -3434,19 +3327,21 @@ int UDPStandardImplementation::getFrameandPacketNumber(int ithread, char* wbuffe subframenumber, footerOffset); #endif - framenumber += (startFrameIndex - 1); + framenumber -= startFrameIndex; break; case JUNGFRAU: header = (jfrau_packet_header_t*)(wbuffer); framenumber = (*( (uint32_t*) header->frameNumber))&frameIndexMask; packetnumber = (uint32_t)(*( (uint8_t*) header->packetNumber)); + bunchid = (*((uint64_t*) header->bunchid)); #ifdef DEBUG4 - cprintf(GREEN, "Writing_Thread %d: fnum:%lld\t pnum:%d\n", + cprintf(GREEN, "Writing_Thread %d: fnum:%lld\t pnum:%d bunchid:%lld\n", (long long int)framenumber, - packetnumber); + packetnumber, + (long long int)bunchid); #endif - framenumber += startFrameIndex; + framenumber -= startFrameIndex; break; default: @@ -3461,7 +3356,7 @@ int UDPStandardImplementation::getFrameandPacketNumber(int ithread, char* wbuffe (long long int)framenumber, packetnumber); #endif - framenumber += startFrameIndex; + framenumber -= startFrameIndex; break; } return OK; @@ -3482,8 +3377,9 @@ int UDPStandardImplementation::writeUptoFrameNumber(int ithread, char* wbuffer, offset = endoffset; uint32_t pnum; uint32_t snum; + uint64_t bunchid=-1; //get last frame number - if(getFrameandPacketNumber(ithread, wbuffer + (endoffset-onePacketSize), tempframenumber,pnum,snum) == FAIL){ + if(getFrameandPacketNumber(ithread, wbuffer + (endoffset-onePacketSize), tempframenumber,pnum,snum,bunchid) == FAIL){ //error in frame number sent by fpga while(!fifoFree[ithread]->push(wbuffer)); return FAIL; @@ -3509,7 +3405,7 @@ int UDPStandardImplementation::writeUptoFrameNumber(int ithread, char* wbuffer, offset -= bigIncrements; if(offsetpush(wbuffer)); return FAIL; @@ -3517,7 +3413,7 @@ int UDPStandardImplementation::writeUptoFrameNumber(int ithread, char* wbuffer, } if(offsetpush(wbuffer)); return FAIL; @@ -3525,7 +3421,7 @@ int UDPStandardImplementation::writeUptoFrameNumber(int ithread, char* wbuffer, } while(tempframenumberpush(wbuffer)); return FAIL; diff --git a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp index 4507726ad..db4e91a33 100644 --- a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp +++ b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp @@ -24,7 +24,7 @@ using namespace std; slsReceiverTCPIPInterface::~slsReceiverTCPIPInterface() { stop(); - if(socket) {delete socket; socket=NULL;} + if(mySock) {delete mySock; mySock=NULL;} } slsReceiverTCPIPInterface::slsReceiverTCPIPInterface(int &success, UDPInterface* rbase, int pn, bool bot): @@ -39,7 +39,7 @@ slsReceiverTCPIPInterface::slsReceiverTCPIPInterface(int &success, UDPInterface* tenGigaEnable(0), portNumber(DEFAULT_PORTNO+2), bottom(bot), - socket(NULL){ + mySock(NULL){ strcpy(SET_RECEIVER_ERR_MESSAGE,"Receiver not set up. Please use rx_hostname first.\n"); @@ -51,7 +51,7 @@ slsReceiverTCPIPInterface::slsReceiverTCPIPInterface(int &success, UDPInterface* rawDataReadyCallBack = NULL; pRawDataReady = NULL; - int port_no=portNumber; + unsigned short int port_no=portNumber; if(receiverBase == NULL) receiverBase = 0; if (pn>0) @@ -61,16 +61,16 @@ slsReceiverTCPIPInterface::slsReceiverTCPIPInterface(int &success, UDPInterface* //create socket if(success == OK){ - socket = new MySocketTCP(port_no); - if (socket->getErrorStatus()) { + mySock = new MySocketTCP(port_no); + if (mySock->getErrorStatus()) { success = FAIL; - delete socket; - socket=NULL; + delete mySock; + mySock=NULL; } else { portNumber=port_no; //initialize variables - strcpy(socket->lastClientIP,"none"); - strcpy(socket->thisClientIP,"none1"); + strcpy(mySock->lastClientIP,"none"); + strcpy(mySock->thisClientIP,"none1"); strcpy(mess,"dummy message"); function_table(); #ifdef VERYVERBOSE @@ -96,13 +96,13 @@ int slsReceiverTCPIPInterface::setPortNumber(int pn){ cout << mess << endl; } else { - oldsocket=socket; - socket = new MySocketTCP(p_number); - if(socket){ - sd = socket->getErrorStatus(); + oldsocket=mySock; + mySock = new MySocketTCP(p_number); + if(mySock){ + sd = mySock->getErrorStatus(); if (!sd){ portNumber=p_number; - strcpy(socket->lastClientIP,oldsocket->lastClientIP); + strcpy(mySock->lastClientIP,oldsocket->lastClientIP); delete oldsocket; } else { cout << "Could not bind port " << p_number << endl; @@ -110,13 +110,13 @@ int slsReceiverTCPIPInterface::setPortNumber(int pn){ cout << "Port "<< p_number << " already set" << endl; } else { - delete socket; - socket=oldsocket; + delete mySock; + mySock=oldsocket; } } } else { - socket=oldsocket; + mySock=oldsocket; } } } @@ -143,7 +143,7 @@ int slsReceiverTCPIPInterface::start(){ void slsReceiverTCPIPInterface::stop(){ cout << "Shutting down UDP Socket" << endl; killTCPServerThread = 1; - if(socket) socket->ShutDownSocket(); + if(mySock) mySock->ShutDownSocket(); cout<<"Socket closed"<Connect()>=0){ + if(mySock->Connect()>=0){ #ifdef VERY_VERBOSE cout << "Conenction accepted" << endl; #endif @@ -183,7 +183,7 @@ void slsReceiverTCPIPInterface::startTCPServer(){ #ifdef VERY_VERBOSE cout << "function executed" << endl; #endif - socket->Disconnect(); + mySock->Disconnect(); #ifdef VERY_VERBOSE cout << "connection closed" << endl; #endif @@ -199,7 +199,7 @@ void slsReceiverTCPIPInterface::startTCPServer(){ receiverBase->closeFile(); } - socket->exitServer(); + mySock->exitServer(); pthread_exit(NULL); } @@ -285,7 +285,7 @@ int slsReceiverTCPIPInterface::decode_function(){ #ifdef VERYVERBOSE cout << "receive data" << endl; #endif - n = socket->ReceiveDataOnly(&fnum,sizeof(fnum)); + n = mySock->ReceiveDataOnly(&fnum,sizeof(fnum)); if (n <= 0) { #ifdef VERYVERBOSE cout << "ERROR reading from socket " << n << ", " << fnum << endl; @@ -322,8 +322,8 @@ int slsReceiverTCPIPInterface::M_nofunc(){ sprintf(mess,"Unrecognized Function\n"); cout << mess << endl; - socket->SendDataOnly(&ret,sizeof(ret)); - socket->SendDataOnly(mess,sizeof(mess)); + mySock->SendDataOnly(&ret,sizeof(ret)); + mySock->SendDataOnly(mess,sizeof(mess)); return GOODBYE; } @@ -344,7 +344,7 @@ int slsReceiverTCPIPInterface::set_detector_type(){ // receive arguments - if(socket->ReceiveDataOnly(&dr,sizeof(dr)) < 0 ){ + if(mySock->ReceiveDataOnly(&dr,sizeof(dr)) < 0 ){ strcpy(mess,"Error reading from socket\n"); ret = FAIL; } @@ -352,8 +352,8 @@ int slsReceiverTCPIPInterface::set_detector_type(){ // execute action if the arguments correctly arrived #ifdef SLS_RECEIVER_UDP_FUNCTIONS if (ret==OK) { - if (lockStatus==1 && socket->differentClients==1){ - sprintf(mess,"Receiver locked by %s\n", socket->lastClientIP); + if (lockStatus==1 && mySock->differentClients==1){ + sprintf(mess,"Receiver locked by %s\n", mySock->lastClientIP); ret=FAIL; } else if((receiverBase)&&(receiverBase->getStatus()==RUNNING || receiverBase->getStatus()==TRANSMITTING)){ @@ -405,16 +405,16 @@ int slsReceiverTCPIPInterface::set_detector_type(){ //#endif #endif - if(ret==OK && socket->differentClients){ + if(ret==OK && mySock->differentClients){ FILE_LOG(logDEBUG) << "Force update"; ret=FORCE_UPDATE; } // send answer - socket->SendDataOnly(&ret,sizeof(ret)); + mySock->SendDataOnly(&ret,sizeof(ret)); if(ret==FAIL) - socket->SendDataOnly(mess,sizeof(mess)); - socket->SendDataOnly(&retval,sizeof(retval)); + mySock->SendDataOnly(mess,sizeof(mess)); + mySock->SendDataOnly(&retval,sizeof(retval)); //return ok/fail return ret; @@ -434,7 +434,7 @@ int slsReceiverTCPIPInterface::set_file_name() { strcpy(mess,"Could not set file name"); // receive arguments - if(socket->ReceiveDataOnly(fName,MAX_STR_LENGTH) < 0 ){ + if(mySock->ReceiveDataOnly(fName,MAX_STR_LENGTH) < 0 ){ strcpy(mess,"Error reading from socket\n"); ret = FAIL; } @@ -443,8 +443,8 @@ int slsReceiverTCPIPInterface::set_file_name() { #ifdef SLS_RECEIVER_UDP_FUNCTIONS if (ret==OK) { - if (lockStatus==1 && socket->differentClients==1){ - sprintf(mess,"Receiver locked by %s\n", socket->lastClientIP); + if (lockStatus==1 && mySock->differentClients==1){ + sprintf(mess,"Receiver locked by %s\n", mySock->lastClientIP); ret=FAIL; } else if (receiverBase == NULL){ @@ -471,21 +471,21 @@ int slsReceiverTCPIPInterface::set_file_name() { #endif - if(ret==OK && socket->differentClients){ + if(ret==OK && mySock->differentClients){ FILE_LOG(logDEBUG) << "Force update"; ret=FORCE_UPDATE; } // send answer - socket->SendDataOnly(&ret,sizeof(ret)); + mySock->SendDataOnly(&ret,sizeof(ret)); if(ret==FAIL){ cprintf(RED, "%s\n", mess); - socket->SendDataOnly(mess,sizeof(mess)); + mySock->SendDataOnly(mess,sizeof(mess)); } if(retval == NULL) - socket->SendDataOnly(defaultVal,MAX_STR_LENGTH); + mySock->SendDataOnly(defaultVal,MAX_STR_LENGTH); else{ - socket->SendDataOnly(retval,MAX_STR_LENGTH); + mySock->SendDataOnly(retval,MAX_STR_LENGTH); delete[] retval; } @@ -507,7 +507,7 @@ int slsReceiverTCPIPInterface::set_file_dir() { strcpy(mess,"Could not set file path\n"); // receive arguments - if(socket->ReceiveDataOnly(fPath,MAX_STR_LENGTH) < 0 ){ + if(mySock->ReceiveDataOnly(fPath,MAX_STR_LENGTH) < 0 ){ strcpy(mess,"Error reading from socket\n"); ret = FAIL; } @@ -515,8 +515,8 @@ int slsReceiverTCPIPInterface::set_file_dir() { // execute action if the arguments correctly arrived #ifdef SLS_RECEIVER_UDP_FUNCTIONS if (ret==OK) { - if (lockStatus==1 && socket->differentClients==1){ - sprintf(mess,"Receiver locked by %s\n", socket->lastClientIP); + if (lockStatus==1 && mySock->differentClients==1){ + sprintf(mess,"Receiver locked by %s\n", mySock->lastClientIP); ret=FAIL; } else if (receiverBase == NULL){ @@ -545,21 +545,21 @@ int slsReceiverTCPIPInterface::set_file_dir() { #endif #endif - if(ret==OK && socket->differentClients){ + if(ret==OK && mySock->differentClients){ FILE_LOG(logDEBUG) << "Force update"; ret=FORCE_UPDATE; } // send answer - socket->SendDataOnly(&ret,sizeof(ret)); + mySock->SendDataOnly(&ret,sizeof(ret)); if(ret==FAIL){ cprintf(RED, "%s\n", mess); - socket->SendDataOnly(mess,sizeof(mess)); + mySock->SendDataOnly(mess,sizeof(mess)); } if(retval == NULL) - socket->SendDataOnly(defaultVal,MAX_STR_LENGTH); + mySock->SendDataOnly(defaultVal,MAX_STR_LENGTH); else{ - socket->SendDataOnly(retval,MAX_STR_LENGTH); + mySock->SendDataOnly(retval,MAX_STR_LENGTH); delete[] retval; } @@ -580,7 +580,7 @@ int slsReceiverTCPIPInterface::set_file_index() { // receive arguments - if(socket->ReceiveDataOnly(&index,sizeof(index)) < 0 ){ + if(mySock->ReceiveDataOnly(&index,sizeof(index)) < 0 ){ strcpy(mess,"Error reading from socket\n"); ret = FAIL; } @@ -588,8 +588,8 @@ int slsReceiverTCPIPInterface::set_file_index() { // execute action if the arguments correctly arrived #ifdef SLS_RECEIVER_UDP_FUNCTIONS if (ret==OK) { - if (lockStatus==1 && socket->differentClients==1){ - sprintf(mess,"Receiver locked by %s\n", socket->lastClientIP); + if (lockStatus==1 && mySock->differentClients==1){ + sprintf(mess,"Receiver locked by %s\n", mySock->lastClientIP); ret=FAIL; } else if (receiverBase == NULL){ @@ -616,18 +616,18 @@ int slsReceiverTCPIPInterface::set_file_index() { #endif #endif - if(ret==OK && socket->differentClients){ + if(ret==OK && mySock->differentClients){ FILE_LOG(logDEBUG) << "Force update"; ret=FORCE_UPDATE; } // send answer - socket->SendDataOnly(&ret,sizeof(ret)); + mySock->SendDataOnly(&ret,sizeof(ret)); if(ret==FAIL){ cprintf(RED, "%s\n", mess); - socket->SendDataOnly(mess,sizeof(mess)); + mySock->SendDataOnly(mess,sizeof(mess)); } - socket->SendDataOnly(&retval,sizeof(retval)); + mySock->SendDataOnly(&retval,sizeof(retval)); //return ok/fail return ret; @@ -648,7 +648,7 @@ int slsReceiverTCPIPInterface::set_frame_index() { // receive arguments - if(socket->ReceiveDataOnly(&index,sizeof(index)) < 0 ){ + if(mySock->ReceiveDataOnly(&index,sizeof(index)) < 0 ){ strcpy(mess,"Error reading from socket\n"); ret = FAIL; } @@ -656,8 +656,8 @@ int slsReceiverTCPIPInterface::set_frame_index() { // execute action if the arguments correctly arrived #ifdef SLS_RECEIVER_UDP_FUNCTIONS if (ret==OK) { - if (lockStatus==1 && socket->differentClients==1){ - sprintf(mess,"Receiver locked by %s\n", socket->lastClientIP); + if (lockStatus==1 && mySock->differentClients==1){ + sprintf(mess,"Receiver locked by %s\n", mySock->lastClientIP); ret=FAIL; } else if (receiverBase == NULL){ @@ -693,18 +693,18 @@ int slsReceiverTCPIPInterface::set_frame_index() { #endif #endif - if(ret==OK && socket->differentClients){ + if(ret==OK && mySock->differentClients){ FILE_LOG(logDEBUG) << "Force update"; ret=FORCE_UPDATE; } // send answer - socket->SendDataOnly(&ret,sizeof(ret)); + mySock->SendDataOnly(&ret,sizeof(ret)); if(ret==FAIL){ cprintf(RED, "%s\n", mess); - socket->SendDataOnly(mess,sizeof(mess)); + mySock->SendDataOnly(mess,sizeof(mess)); } - socket->SendDataOnly(&retval,sizeof(retval)); + mySock->SendDataOnly(&retval,sizeof(retval)); //return ok/fail return ret; @@ -729,7 +729,7 @@ int slsReceiverTCPIPInterface::setup_udp(){ // receive arguments - if(socket->ReceiveDataOnly(args,sizeof(args)) < 0 ){ + if(mySock->ReceiveDataOnly(args,sizeof(args)) < 0 ){ strcpy(mess,"Error reading from socket\n"); ret = FAIL; } @@ -737,8 +737,8 @@ int slsReceiverTCPIPInterface::setup_udp(){ // execute action if the arguments correctly arrived #ifdef SLS_RECEIVER_UDP_FUNCTIONS if (ret==OK) { - if (lockStatus==1 && socket->differentClients==1){ - sprintf(mess,"Receiver locked by %s\n", socket->lastClientIP); + if (lockStatus==1 && mySock->differentClients==1){ + sprintf(mess,"Receiver locked by %s\n", mySock->lastClientIP); ret=FAIL; } else if (receiverBase == NULL){ @@ -790,18 +790,18 @@ int slsReceiverTCPIPInterface::setup_udp(){ } #endif - if(ret==OK && socket->differentClients){ + if(ret==OK && mySock->differentClients){ FILE_LOG(logDEBUG) << "Force update"; ret=FORCE_UPDATE; } // send answer - socket->SendDataOnly(&ret,sizeof(ret)); + mySock->SendDataOnly(&ret,sizeof(ret)); if(ret==FAIL){ FILE_LOG(logERROR) << mess; - socket->SendDataOnly(mess,sizeof(mess)); + mySock->SendDataOnly(mess,sizeof(mess)); } - socket->SendDataOnly(retval,MAX_STR_LENGTH); + mySock->SendDataOnly(retval,MAX_STR_LENGTH); //return ok/fail return ret; @@ -820,8 +820,8 @@ int slsReceiverTCPIPInterface::start_receiver(){ // execute action if the arguments correctly arrived #ifdef SLS_RECEIVER_UDP_FUNCTIONS - if (lockStatus==1 && socket->differentClients==1){ - sprintf(mess,"Receiver locked by %s\n", socket->lastClientIP); + if (lockStatus==1 && mySock->differentClients==1){ + sprintf(mess,"Receiver locked by %s\n", mySock->lastClientIP); ret=FAIL; } /* @@ -845,16 +845,16 @@ int slsReceiverTCPIPInterface::start_receiver(){ } #endif - if(ret==OK && socket->differentClients){ + if(ret==OK && mySock->differentClients){ FILE_LOG(logDEBUG) << "Force update"; ret=FORCE_UPDATE; } // send answer - socket->SendDataOnly(&ret,sizeof(ret)); + mySock->SendDataOnly(&ret,sizeof(ret)); if(ret==FAIL){ cprintf(RED, "Error:%s\n", mess); - socket->SendDataOnly(mess,sizeof(mess)); + mySock->SendDataOnly(mess,sizeof(mess)); } //return ok/fail return ret; @@ -870,8 +870,8 @@ int slsReceiverTCPIPInterface::stop_receiver(){ // execute action if the arguments correctly arrived #ifdef SLS_RECEIVER_UDP_FUNCTIONS - if (lockStatus==1 && socket->differentClients==1){ - sprintf(mess,"Receiver locked by %s\n", socket->lastClientIP); + if (lockStatus==1 && mySock->differentClients==1){ + sprintf(mess,"Receiver locked by %s\n", mySock->lastClientIP); ret=FAIL; } else if (receiverBase == NULL){ @@ -892,16 +892,16 @@ int slsReceiverTCPIPInterface::stop_receiver(){ } #endif - if(ret==OK && socket->differentClients){ + if(ret==OK && mySock->differentClients){ FILE_LOG(logDEBUG) << "Force update"; ret=FORCE_UPDATE; } // send answer - socket->SendDataOnly(&ret,sizeof(ret)); + mySock->SendDataOnly(&ret,sizeof(ret)); if(ret==FAIL){ cprintf(RED, "%s\n", mess); - socket->SendDataOnly(mess,sizeof(mess)); + mySock->SendDataOnly(mess,sizeof(mess)); } //return ok/fail return ret; @@ -923,19 +923,19 @@ int slsReceiverTCPIPInterface::get_status(){ }else s=receiverBase->getStatus(); #endif - if(ret==OK && socket->differentClients){ + if(ret==OK && mySock->differentClients){ FILE_LOG(logDEBUG) << "Force update"; ret=FORCE_UPDATE; } // send answer - socket->SendDataOnly(&ret,sizeof(ret)); + mySock->SendDataOnly(&ret,sizeof(ret)); if(ret==FAIL){ cprintf(RED, "%s\n", mess); - socket->SendDataOnly(mess,sizeof(mess)); + mySock->SendDataOnly(mess,sizeof(mess)); } retval = (runStatus(s)); - socket->SendDataOnly(&retval,sizeof(retval)); + mySock->SendDataOnly(&retval,sizeof(retval)); //return ok/fail return ret; @@ -954,18 +954,18 @@ int slsReceiverTCPIPInterface::get_frames_caught(){ ret=FAIL; }else retval=receiverBase->getTotalFramesCaught(); #endif - if(ret==OK && socket->differentClients){ + if(ret==OK && mySock->differentClients){ FILE_LOG(logDEBUG) << "Force update"; ret=FORCE_UPDATE; } // send answer - socket->SendDataOnly(&ret,sizeof(ret)); + mySock->SendDataOnly(&ret,sizeof(ret)); if(ret==FAIL){ cprintf(RED, "%s\n", mess); - socket->SendDataOnly(mess,sizeof(mess)); + mySock->SendDataOnly(mess,sizeof(mess)); } - socket->SendDataOnly(&retval,sizeof(retval)); + mySock->SendDataOnly(&retval,sizeof(retval)); //return ok/fail return ret; @@ -986,18 +986,18 @@ int slsReceiverTCPIPInterface::get_frame_index(){ retval=receiverBase->getAcquisitionIndex(); #endif - if(ret==OK && socket->differentClients){ + if(ret==OK && mySock->differentClients){ FILE_LOG(logDEBUG) << "Force update"; ret=FORCE_UPDATE; } // send answer - socket->SendDataOnly(&ret,sizeof(ret)); + mySock->SendDataOnly(&ret,sizeof(ret)); if(ret==FAIL){ cprintf(RED, "%s\n", mess); - socket->SendDataOnly(mess,sizeof(mess)); + mySock->SendDataOnly(mess,sizeof(mess)); } - socket->SendDataOnly(&retval,sizeof(retval)); + mySock->SendDataOnly(&retval,sizeof(retval)); //return ok/fail return ret; @@ -1014,8 +1014,8 @@ int slsReceiverTCPIPInterface::reset_frames_caught(){ // execute action if the arguments correctly arrived #ifdef SLS_RECEIVER_UDP_FUNCTIONS if (ret==OK) { - if (lockStatus==1 && socket->differentClients==1){ - sprintf(mess,"Receiver locked by %s\n", socket->lastClientIP); + if (lockStatus==1 && mySock->differentClients==1){ + sprintf(mess,"Receiver locked by %s\n", mySock->lastClientIP); ret=FAIL; } else if (receiverBase == NULL){ @@ -1031,16 +1031,16 @@ int slsReceiverTCPIPInterface::reset_frames_caught(){ } #endif - if(ret==OK && socket->differentClients){ + if(ret==OK && mySock->differentClients){ FILE_LOG(logDEBUG) << "Force update"; ret=FORCE_UPDATE; } // send answer - socket->SendDataOnly(&ret,sizeof(ret)); + mySock->SendDataOnly(&ret,sizeof(ret)); if(ret==FAIL){ cprintf(RED, "%s\n", mess); - socket->SendDataOnly(mess,sizeof(mess)); + mySock->SendDataOnly(mess,sizeof(mess)); } //return ok/fail return ret; @@ -1066,7 +1066,7 @@ int slsReceiverTCPIPInterface::set_short_frame() { } // receive arguments - if(socket->ReceiveDataOnly(&index,sizeof(index)) < 0 ){ + if(mySock->ReceiveDataOnly(&index,sizeof(index)) < 0 ){ strcpy(mess,"Error reading from socket\n"); ret = FAIL; } @@ -1075,8 +1075,8 @@ int slsReceiverTCPIPInterface::set_short_frame() { // execute action if the arguments correctly arrived #ifdef SLS_RECEIVER_UDP_FUNCTIONS if (ret==OK) { - if (lockStatus==1 && socket->differentClients==1){ - sprintf(mess,"Receiver locked by %s\n", socket->lastClientIP); + if (lockStatus==1 && mySock->differentClients==1){ + sprintf(mess,"Receiver locked by %s\n", mySock->lastClientIP); ret=FAIL; } else if (receiverBase == NULL){ @@ -1099,18 +1099,18 @@ int slsReceiverTCPIPInterface::set_short_frame() { } #endif - if(ret==OK && socket->differentClients){ + if(ret==OK && mySock->differentClients){ FILE_LOG(logDEBUG) << "Force update"; ret=FORCE_UPDATE; } // send answer - socket->SendDataOnly(&ret,sizeof(ret)); + mySock->SendDataOnly(&ret,sizeof(ret)); if(ret==FAIL){ cprintf(RED, "%s\n", mess); - socket->SendDataOnly(mess,sizeof(mess)); + mySock->SendDataOnly(mess,sizeof(mess)); } - socket->SendDataOnly(&retval,sizeof(retval)); + mySock->SendDataOnly(&retval,sizeof(retval)); //return ok/fail return ret; @@ -1281,22 +1281,22 @@ int slsReceiverTCPIPInterface::moench_read_frame(){ #endif - if(ret==OK && socket->differentClients){ + if(ret==OK && mySock->differentClients){ FILE_LOG(logDEBUG) << "Force update"; ret=FORCE_UPDATE; } // send answer - socket->SendDataOnly(&ret,sizeof(ret)); + mySock->SendDataOnly(&ret,sizeof(ret)); if(ret==FAIL){ cprintf(RED,"%s\n",mess); - socket->SendDataOnly(mess,sizeof(mess)); + mySock->SendDataOnly(mess,sizeof(mess)); } else{ - socket->SendDataOnly(fName,MAX_STR_LENGTH); - socket->SendDataOnly(&acquisitionIndex,sizeof(acquisitionIndex)); - socket->SendDataOnly(&frameIndex,sizeof(frameIndex)); - socket->SendDataOnly(retval,MOENCH_DATA_BYTES); + mySock->SendDataOnly(fName,MAX_STR_LENGTH); + mySock->SendDataOnly(&acquisitionIndex,sizeof(acquisitionIndex)); + mySock->SendDataOnly(&frameIndex,sizeof(frameIndex)); + mySock->SendDataOnly(retval,MOENCH_DATA_BYTES); } //return ok/fail @@ -1462,22 +1462,22 @@ int slsReceiverTCPIPInterface::gotthard_read_frame(){ #endif - if(ret==OK && socket->differentClients){ + if(ret==OK && mySock->differentClients){ FILE_LOG(logDEBUG) << "Force update"; ret=FORCE_UPDATE; } // send answer - socket->SendDataOnly(&ret,sizeof(ret)); + mySock->SendDataOnly(&ret,sizeof(ret)); if(ret==FAIL){ cprintf(RED,"%s\n",mess); - socket->SendDataOnly(mess,sizeof(mess)); + mySock->SendDataOnly(mess,sizeof(mess)); } else{ - socket->SendDataOnly(fName,MAX_STR_LENGTH); - socket->SendDataOnly(&acquisitionIndex,sizeof(acquisitionIndex)); - socket->SendDataOnly(&frameIndex,sizeof(frameIndex)); - socket->SendDataOnly(retval,GOTTHARD_DATA_BYTES); + mySock->SendDataOnly(fName,MAX_STR_LENGTH); + mySock->SendDataOnly(&acquisitionIndex,sizeof(acquisitionIndex)); + mySock->SendDataOnly(&frameIndex,sizeof(frameIndex)); + mySock->SendDataOnly(retval,GOTTHARD_DATA_BYTES); } delete [] retval; @@ -1616,22 +1616,22 @@ int slsReceiverTCPIPInterface::propix_read_frame(){ #endif - if(ret==OK && socket->differentClients){ + if(ret==OK && mySock->differentClients){ FILE_LOG(logDEBUG) << "Force update"; ret=FORCE_UPDATE; } // send answer - socket->SendDataOnly(&ret,sizeof(ret)); + mySock->SendDataOnly(&ret,sizeof(ret)); if(ret==FAIL){ cprintf(RED,"%s\n",mess); - socket->SendDataOnly(mess,sizeof(mess)); + mySock->SendDataOnly(mess,sizeof(mess)); } else{ - socket->SendDataOnly(fName,MAX_STR_LENGTH); - socket->SendDataOnly(&acquisitionIndex,sizeof(acquisitionIndex)); - socket->SendDataOnly(&frameIndex,sizeof(frameIndex)); - socket->SendDataOnly(retval,PROPIX_DATA_BYTES); + mySock->SendDataOnly(fName,MAX_STR_LENGTH); + mySock->SendDataOnly(&acquisitionIndex,sizeof(acquisitionIndex)); + mySock->SendDataOnly(&frameIndex,sizeof(frameIndex)); + mySock->SendDataOnly(retval,PROPIX_DATA_BYTES); } delete [] retval; @@ -1670,8 +1670,8 @@ int slsReceiverTCPIPInterface::eiger_read_frame(){ onePacketSize = EIGER_TEN_GIGA_ONE_PACKET_SIZE; } char* raw; - char* origVal = new char[frameSize]; - char* retval = new char[dataSize]; + char* origVal = new char[frameSize](); + char* retval = new char[dataSize](); memset(origVal,0xFF,frameSize); memset(retval,0xFF,dataSize); @@ -1883,23 +1883,23 @@ int slsReceiverTCPIPInterface::eiger_read_frame(){ #endif - if(ret==OK && socket->differentClients){ + if(ret==OK && mySock->differentClients){ FILE_LOG(logDEBUG) << "Force update"; ret=FORCE_UPDATE; } // send answer - socket->SendDataOnly(&ret,sizeof(ret)); + mySock->SendDataOnly(&ret,sizeof(ret)); if(ret==FAIL){ cprintf(RED,"%s\n",mess); - socket->SendDataOnly(mess,sizeof(mess)); + mySock->SendDataOnly(mess,sizeof(mess)); } else{ - socket->SendDataOnly(fName,MAX_STR_LENGTH); - socket->SendDataOnly(&acquisitionIndex,sizeof(acquisitionIndex)); - socket->SendDataOnly(&frameIndex,sizeof(frameIndex)); - socket->SendDataOnly(&subframenumber,sizeof(subframenumber)); - socket->SendDataOnly(retval,dataSize); + mySock->SendDataOnly(fName,MAX_STR_LENGTH); + mySock->SendDataOnly(&acquisitionIndex,sizeof(acquisitionIndex)); + mySock->SendDataOnly(&frameIndex,sizeof(frameIndex)); + mySock->SendDataOnly(&subframenumber,sizeof(subframenumber)); + mySock->SendDataOnly(retval,dataSize); } delete [] retval; @@ -1932,9 +1932,9 @@ int slsReceiverTCPIPInterface::jungfrau_read_frame(){ int oneDataSize = JFRAU_ONE_DATA_SIZE; char* raw; - char* origVal = new char[frameSize]; - char* retval = new char[dataSize]; - char* blackpacket = new char[oneDataSize]; + char* origVal = new char[frameSize](); + char* retval = new char[dataSize](); + char* blackpacket = new char[oneDataSize](); for(int i=0;idifferentClients){ + if(ret==OK && mySock->differentClients){ FILE_LOG(logDEBUG) << "Force update"; ret=FORCE_UPDATE; } // send answer - socket->SendDataOnly(&ret,sizeof(ret)); + mySock->SendDataOnly(&ret,sizeof(ret)); if(ret==FAIL){ cprintf(RED,"%s\n",mess); - socket->SendDataOnly(mess,sizeof(mess)); + mySock->SendDataOnly(mess,sizeof(mess)); } else{ - socket->SendDataOnly(fName,MAX_STR_LENGTH); - socket->SendDataOnly(&acquisitionIndex,sizeof(acquisitionIndex)); - socket->SendDataOnly(&frameIndex,sizeof(frameIndex)); - socket->SendDataOnly(retval,dataSize); + mySock->SendDataOnly(fName,MAX_STR_LENGTH); + mySock->SendDataOnly(&acquisitionIndex,sizeof(acquisitionIndex)); + mySock->SendDataOnly(&frameIndex,sizeof(frameIndex)); + mySock->SendDataOnly(retval,dataSize); } delete [] retval; @@ -2084,7 +2084,7 @@ int slsReceiverTCPIPInterface::set_read_frequency(){ // receive arguments - if(socket->ReceiveDataOnly(&index,sizeof(index)) < 0 ){ + if(mySock->ReceiveDataOnly(&index,sizeof(index)) < 0 ){ strcpy(mess,"Error reading from socket\n"); ret = FAIL; } @@ -2092,8 +2092,8 @@ int slsReceiverTCPIPInterface::set_read_frequency(){ // execute action if the arguments correctly arrived #ifdef SLS_RECEIVER_UDP_FUNCTIONS if (ret==OK) { - if (lockStatus==1 && socket->differentClients==1){ - sprintf(mess,"Receiver locked by %s\n", socket->lastClientIP); + if (lockStatus==1 && mySock->differentClients==1){ + sprintf(mess,"Receiver locked by %s\n", mySock->lastClientIP); ret=FAIL; } else if (receiverBase == NULL){ @@ -2124,18 +2124,18 @@ int slsReceiverTCPIPInterface::set_read_frequency(){ #endif - if(ret==OK && socket->differentClients){ + if(ret==OK && mySock->differentClients){ FILE_LOG(logDEBUG) << "Force update"; ret=FORCE_UPDATE; } // send answer - socket->SendDataOnly(&ret,sizeof(ret)); + mySock->SendDataOnly(&ret,sizeof(ret)); if(ret==FAIL){ cprintf(RED,"%s\n",mess); - socket->SendDataOnly(mess,sizeof(mess)); + mySock->SendDataOnly(mess,sizeof(mess)); } - socket->SendDataOnly(&retval,sizeof(retval)); + mySock->SendDataOnly(&retval,sizeof(retval)); //return ok/fail return ret; @@ -2154,7 +2154,7 @@ int slsReceiverTCPIPInterface::set_read_receiver_timer(){ // receive arguments - if(socket->ReceiveDataOnly(&index,sizeof(index)) < 0 ){ + if(mySock->ReceiveDataOnly(&index,sizeof(index)) < 0 ){ strcpy(mess,"Error reading from socket\n"); ret = FAIL; } @@ -2162,8 +2162,8 @@ int slsReceiverTCPIPInterface::set_read_receiver_timer(){ // execute action if the arguments correctly arrived #ifdef SLS_RECEIVER_UDP_FUNCTIONS if (ret==OK) { - if (lockStatus==1 && socket->differentClients==1){ - sprintf(mess,"Receiver locked by %s\n", socket->lastClientIP); + if (lockStatus==1 && mySock->differentClients==1){ + sprintf(mess,"Receiver locked by %s\n", mySock->lastClientIP); ret=FAIL; } else if (receiverBase == NULL){ @@ -2190,18 +2190,18 @@ int slsReceiverTCPIPInterface::set_read_receiver_timer(){ #endif - if(ret==OK && socket->differentClients){ + if(ret==OK && mySock->differentClients){ FILE_LOG(logDEBUG) << "Force update"; ret=FORCE_UPDATE; } // send answer - socket->SendDataOnly(&ret,sizeof(ret)); + mySock->SendDataOnly(&ret,sizeof(ret)); if(ret==FAIL){ cprintf(RED,"%s\n",mess); - socket->SendDataOnly(mess,sizeof(mess)); + mySock->SendDataOnly(mess,sizeof(mess)); } - socket->SendDataOnly(&retval,sizeof(retval)); + mySock->SendDataOnly(&retval,sizeof(retval)); //return ok/fail return ret; @@ -2218,7 +2218,7 @@ int slsReceiverTCPIPInterface::set_data_stream_enable(){ // receive arguments - if(socket->ReceiveDataOnly(&index,sizeof(index)) < 0 ){ + if(mySock->ReceiveDataOnly(&index,sizeof(index)) < 0 ){ strcpy(mess,"Error reading from socket\n"); ret = FAIL; } @@ -2226,8 +2226,8 @@ int slsReceiverTCPIPInterface::set_data_stream_enable(){ // execute action if the arguments correctly arrived #ifdef SLS_RECEIVER_UDP_FUNCTIONS if (ret==OK) { - if (lockStatus==1 && socket->differentClients==1){ - sprintf(mess,"Receiver locked by %s\n", socket->lastClientIP); + if (lockStatus==1 && mySock->differentClients==1){ + sprintf(mess,"Receiver locked by %s\n", mySock->lastClientIP); ret=FAIL; } else if (receiverBase == NULL){ @@ -2253,18 +2253,18 @@ int slsReceiverTCPIPInterface::set_data_stream_enable(){ #endif - if(ret==OK && socket->differentClients){ + if(ret==OK && mySock->differentClients){ FILE_LOG(logDEBUG) << "Force update"; ret=FORCE_UPDATE; } // send answer - socket->SendDataOnly(&ret,sizeof(ret)); + mySock->SendDataOnly(&ret,sizeof(ret)); if(ret==FAIL){ cprintf(RED,"%s\n",mess); - socket->SendDataOnly(mess,sizeof(mess)); + mySock->SendDataOnly(mess,sizeof(mess)); } - socket->SendDataOnly(&retval,sizeof(retval)); + mySock->SendDataOnly(&retval,sizeof(retval)); //return ok/fail return ret; @@ -2282,7 +2282,7 @@ int slsReceiverTCPIPInterface::enable_file_write(){ // receive arguments - if(socket->ReceiveDataOnly(&enable,sizeof(enable)) < 0 ){ + if(mySock->ReceiveDataOnly(&enable,sizeof(enable)) < 0 ){ strcpy(mess,"Error reading from socket\n"); ret = FAIL; } @@ -2290,8 +2290,8 @@ int slsReceiverTCPIPInterface::enable_file_write(){ // execute action if the arguments correctly arrived #ifdef SLS_RECEIVER_UDP_FUNCTIONS if (ret==OK) { - if (lockStatus==1 && socket->differentClients==1){ - sprintf(mess,"Receiver locked by %s\n", socket->lastClientIP); + if (lockStatus==1 && mySock->differentClients==1){ + sprintf(mess,"Receiver locked by %s\n", mySock->lastClientIP); ret=FAIL; } else if (receiverBase == NULL){ @@ -2312,18 +2312,18 @@ int slsReceiverTCPIPInterface::enable_file_write(){ } #endif - if(ret==OK && socket->differentClients){ + if(ret==OK && mySock->differentClients){ FILE_LOG(logDEBUG) << "Force update"; ret=FORCE_UPDATE; } // send answer - socket->SendDataOnly(&ret,sizeof(ret)); + mySock->SendDataOnly(&ret,sizeof(ret)); if(ret==FAIL){ cprintf(RED,"%s\n",mess); - socket->SendDataOnly(mess,sizeof(mess)); + mySock->SendDataOnly(mess,sizeof(mess)); } - socket->SendDataOnly(&retval,sizeof(retval)); + mySock->SendDataOnly(&retval,sizeof(retval)); //return ok/fail return ret; @@ -2340,14 +2340,14 @@ int slsReceiverTCPIPInterface::get_id(){ retval = getReceiverVersion(); #endif - if(socket->differentClients){ + if(mySock->differentClients){ FILE_LOG(logDEBUG) << "Force update"; ret=FORCE_UPDATE; } // send answer - socket->SendDataOnly(&ret,sizeof(ret)); - socket->SendDataOnly(&retval,sizeof(retval)); + mySock->SendDataOnly(&ret,sizeof(ret)); + mySock->SendDataOnly(&retval,sizeof(retval)); //return ok/fail return ret; @@ -2388,18 +2388,18 @@ int slsReceiverTCPIPInterface::start_readout(){cprintf(BLUE,"In start readout!\n } #endif - if(ret==OK && socket->differentClients){ + if(ret==OK && mySock->differentClients){ FILE_LOG(logDEBUG) << "Force update"; ret=FORCE_UPDATE; } // send answer - socket->SendDataOnly(&ret,sizeof(ret)); + mySock->SendDataOnly(&ret,sizeof(ret)); if(ret==FAIL){ cprintf(RED,"%s\n",mess); - socket->SendDataOnly(mess,sizeof(mess)); + mySock->SendDataOnly(mess,sizeof(mess)); } - socket->SendDataOnly(&retval,sizeof(retval)); + mySock->SendDataOnly(&retval,sizeof(retval)); //return ok/fail return ret; @@ -2418,7 +2418,7 @@ int slsReceiverTCPIPInterface::set_timer() { // receive arguments - if(socket->ReceiveDataOnly(index,sizeof(index)) < 0 ){ + if(mySock->ReceiveDataOnly(index,sizeof(index)) < 0 ){ strcpy(mess,"Error reading from socket\n"); ret = FAIL; } @@ -2426,8 +2426,8 @@ int slsReceiverTCPIPInterface::set_timer() { // execute action if the arguments correctly arrived #ifdef SLS_RECEIVER_UDP_FUNCTIONS if (ret==OK) { - if (lockStatus==1 && socket->differentClients==1){ - sprintf(mess,"Receiver locked by %s\n", socket->lastClientIP); + if (lockStatus==1 && mySock->differentClients==1){ + sprintf(mess,"Receiver locked by %s\n", mySock->lastClientIP); ret=FAIL; } else if (receiverBase == NULL){ @@ -2475,18 +2475,18 @@ int slsReceiverTCPIPInterface::set_timer() { #endif #endif - if(ret==OK && socket->differentClients){ + if(ret==OK && mySock->differentClients){ FILE_LOG(logDEBUG) << "Force update"; ret=FORCE_UPDATE; } // send answer - socket->SendDataOnly(&ret,sizeof(ret)); + mySock->SendDataOnly(&ret,sizeof(ret)); if(ret==FAIL){ cprintf(RED,"%s\n",mess); - socket->SendDataOnly(mess,sizeof(mess)); + mySock->SendDataOnly(mess,sizeof(mess)); } - socket->SendDataOnly(&retval,sizeof(retval)); + mySock->SendDataOnly(&retval,sizeof(retval)); //return ok/fail return ret; @@ -2504,7 +2504,7 @@ int slsReceiverTCPIPInterface::enable_compression() { strcpy(mess,"Could not enable/disable compression for receiver\n"); // receive arguments - if(socket->ReceiveDataOnly(&enable,sizeof(enable)) < 0 ){ + if(mySock->ReceiveDataOnly(&enable,sizeof(enable)) < 0 ){ strcpy(mess,"Error reading from socket\n"); ret = FAIL; } @@ -2514,8 +2514,8 @@ int slsReceiverTCPIPInterface::enable_compression() { #ifdef SLS_RECEIVER_UDP_FUNCTIONS if (ret==OK) { if(enable >= 0){ - if (lockStatus==1 && socket->differentClients==1){ - sprintf(mess,"Receiver locked by %s\n", socket->lastClientIP); + if (lockStatus==1 && mySock->differentClients==1){ + sprintf(mess,"Receiver locked by %s\n", mySock->lastClientIP); ret=FAIL; } else if (receiverBase == NULL){ @@ -2546,18 +2546,18 @@ int slsReceiverTCPIPInterface::enable_compression() { } #endif - if(ret==OK && socket->differentClients){ + if(ret==OK && mySock->differentClients){ FILE_LOG(logDEBUG) << "Force update"; ret=FORCE_UPDATE; } // send answer - socket->SendDataOnly(&ret,sizeof(ret)); + mySock->SendDataOnly(&ret,sizeof(ret)); if(ret==FAIL){ cprintf(RED,"%s\n",mess); - socket->SendDataOnly(mess,sizeof(mess)); + mySock->SendDataOnly(mess,sizeof(mess)); } - socket->SendDataOnly(&retval,sizeof(retval)); + mySock->SendDataOnly(&retval,sizeof(retval)); //return ok/fail return ret; @@ -2574,7 +2574,7 @@ int slsReceiverTCPIPInterface::set_detector_hostname() { strcpy(mess,"Could not set detector hostname"); // receive arguments - if(socket->ReceiveDataOnly(hostname,MAX_STR_LENGTH) < 0 ){ + if(mySock->ReceiveDataOnly(hostname,MAX_STR_LENGTH) < 0 ){ strcpy(mess,"Error reading from socket\n"); ret = FAIL; } @@ -2583,8 +2583,8 @@ int slsReceiverTCPIPInterface::set_detector_hostname() { #ifdef SLS_RECEIVER_UDP_FUNCTIONS if (ret==OK) { - if (lockStatus==1 && socket->differentClients==1){ - sprintf(mess,"Receiver locked by %s\n", socket->lastClientIP); + if (lockStatus==1 && mySock->differentClients==1){ + sprintf(mess,"Receiver locked by %s\n", mySock->lastClientIP); ret=FAIL; } else if (receiverBase == NULL){ @@ -2611,21 +2611,21 @@ int slsReceiverTCPIPInterface::set_detector_hostname() { #endif #endif - if(ret==OK && socket->differentClients){ + if(ret==OK && mySock->differentClients){ FILE_LOG(logDEBUG) << "Force update"; ret=FORCE_UPDATE; } // send answer - socket->SendDataOnly(&ret,sizeof(ret)); + mySock->SendDataOnly(&ret,sizeof(ret)); if(ret==FAIL){ cprintf(RED, "%s\n", mess); - socket->SendDataOnly(mess,sizeof(mess)); + mySock->SendDataOnly(mess,sizeof(mess)); } if(retval == NULL) - socket->SendDataOnly(defaultVal,MAX_STR_LENGTH); + mySock->SendDataOnly(defaultVal,MAX_STR_LENGTH); else{ - socket->SendDataOnly(retval,MAX_STR_LENGTH); + mySock->SendDataOnly(retval,MAX_STR_LENGTH); delete[] retval; } @@ -2647,7 +2647,7 @@ int slsReceiverTCPIPInterface::set_dynamic_range() { // receive arguments - if(socket->ReceiveDataOnly(&dr,sizeof(dr)) < 0 ){ + if(mySock->ReceiveDataOnly(&dr,sizeof(dr)) < 0 ){ strcpy(mess,"Error reading from socket\n"); ret = FAIL; } @@ -2655,8 +2655,8 @@ int slsReceiverTCPIPInterface::set_dynamic_range() { // execute action if the arguments correctly arrived #ifdef SLS_RECEIVER_UDP_FUNCTIONS if (ret==OK) { - if (lockStatus==1 && socket->differentClients==1){ - sprintf(mess,"Receiver locked by %s\n", socket->lastClientIP); + if (lockStatus==1 && mySock->differentClients==1){ + sprintf(mess,"Receiver locked by %s\n", mySock->lastClientIP); ret=FAIL; } else if (dr>0) { @@ -2711,18 +2711,18 @@ int slsReceiverTCPIPInterface::set_dynamic_range() { #endif #endif - if(ret==OK && socket->differentClients){ + if(ret==OK && mySock->differentClients){ FILE_LOG(logDEBUG) << "Force update"; ret=FORCE_UPDATE; } // send answer - socket->SendDataOnly(&ret,sizeof(ret)); + mySock->SendDataOnly(&ret,sizeof(ret)); if(ret==FAIL){ cprintf(RED,"%s\n",mess); - socket->SendDataOnly(mess,sizeof(mess)); + mySock->SendDataOnly(mess,sizeof(mess)); } - socket->SendDataOnly(&retval,sizeof(retval)); + mySock->SendDataOnly(&retval,sizeof(retval)); //return ok/fail return ret; @@ -2742,7 +2742,7 @@ int slsReceiverTCPIPInterface::enable_overwrite() { // receive arguments - if(socket->ReceiveDataOnly(&index,sizeof(index)) < 0 ){ + if(mySock->ReceiveDataOnly(&index,sizeof(index)) < 0 ){ strcpy(mess,"Error reading from socket\n"); ret = FAIL; } @@ -2750,8 +2750,8 @@ int slsReceiverTCPIPInterface::enable_overwrite() { // execute action if the arguments correctly arrived #ifdef SLS_RECEIVER_UDP_FUNCTIONS if (ret==OK) { - if (lockStatus==1 && socket->differentClients==1){ - sprintf(mess,"Receiver locked by %s\n", socket->lastClientIP); + if (lockStatus==1 && mySock->differentClients==1){ + sprintf(mess,"Receiver locked by %s\n", mySock->lastClientIP); ret=FAIL; } else if (receiverBase == NULL){ @@ -2778,18 +2778,18 @@ int slsReceiverTCPIPInterface::enable_overwrite() { #endif #endif - if(ret==OK && socket->differentClients){ + if(ret==OK && mySock->differentClients){ FILE_LOG(logDEBUG) << "Force update"; ret=FORCE_UPDATE; } // send answer - socket->SendDataOnly(&ret,sizeof(ret)); + mySock->SendDataOnly(&ret,sizeof(ret)); if(ret==FAIL){ cprintf(RED,"%s\n",mess); - socket->SendDataOnly(mess,sizeof(mess)); + mySock->SendDataOnly(mess,sizeof(mess)); } - socket->SendDataOnly(&retval,sizeof(retval)); + mySock->SendDataOnly(&retval,sizeof(retval)); //return ok/fail return ret; @@ -2809,7 +2809,7 @@ int slsReceiverTCPIPInterface::enable_tengiga() { // receive arguments - if(socket->ReceiveDataOnly(&val,sizeof(val)) < 0 ){ + if(mySock->ReceiveDataOnly(&val,sizeof(val)) < 0 ){ strcpy(mess,"Error reading from socket\n"); ret = FAIL; } @@ -2817,8 +2817,8 @@ int slsReceiverTCPIPInterface::enable_tengiga() { // execute action if the arguments correctly arrived #ifdef SLS_RECEIVER_UDP_FUNCTIONS if (ret==OK) { - if (lockStatus==1 && socket->differentClients==1){ - sprintf(mess,"Receiver locked by %s\n", socket->lastClientIP); + if (lockStatus==1 && mySock->differentClients==1){ + sprintf(mess,"Receiver locked by %s\n", mySock->lastClientIP); ret=FAIL; } else if (receiverBase == NULL){ @@ -2847,18 +2847,18 @@ int slsReceiverTCPIPInterface::enable_tengiga() { #endif #endif - if(ret==OK && socket->differentClients){ + if(ret==OK && mySock->differentClients){ FILE_LOG(logDEBUG) << "Force update"; ret=FORCE_UPDATE; } // send answer - socket->SendDataOnly(&ret,sizeof(ret)); + mySock->SendDataOnly(&ret,sizeof(ret)); if(ret==FAIL){ cprintf(RED,"%s\n",mess); - socket->SendDataOnly(mess,sizeof(mess)); + mySock->SendDataOnly(mess,sizeof(mess)); } - socket->SendDataOnly(&retval,sizeof(retval)); + mySock->SendDataOnly(&retval,sizeof(retval)); //return ok/fail return ret; @@ -2876,7 +2876,7 @@ int slsReceiverTCPIPInterface::set_fifo_depth() { strcpy(mess,"Could not set/get fifo depth for receiver\n"); // receive arguments - if(socket->ReceiveDataOnly(&value,sizeof(value)) < 0 ){ + if(mySock->ReceiveDataOnly(&value,sizeof(value)) < 0 ){ strcpy(mess,"Error reading from socket\n"); ret = FAIL; } @@ -2886,8 +2886,8 @@ int slsReceiverTCPIPInterface::set_fifo_depth() { #ifdef SLS_RECEIVER_UDP_FUNCTIONS if (ret==OK) { if(value >= 0){ - if (lockStatus==1 && socket->differentClients==1){ - sprintf(mess,"Receiver locked by %s\n", socket->lastClientIP); + if (lockStatus==1 && mySock->differentClients==1){ + sprintf(mess,"Receiver locked by %s\n", mySock->lastClientIP); ret=FAIL; } else if (receiverBase == NULL){ @@ -2918,18 +2918,18 @@ int slsReceiverTCPIPInterface::set_fifo_depth() { } #endif - if(ret==OK && socket->differentClients){ + if(ret==OK && mySock->differentClients){ FILE_LOG(logDEBUG) << "Force update"; ret=FORCE_UPDATE; } // send answer - socket->SendDataOnly(&ret,sizeof(ret)); + mySock->SendDataOnly(&ret,sizeof(ret)); if(ret==FAIL){ cprintf(RED,"%s\n",mess); - socket->SendDataOnly(mess,sizeof(mess)); + mySock->SendDataOnly(mess,sizeof(mess)); } - socket->SendDataOnly(&retval,sizeof(retval)); + mySock->SendDataOnly(&retval,sizeof(retval)); //return ok/fail return ret; @@ -2947,7 +2947,7 @@ int slsReceiverTCPIPInterface::set_activate() { // receive arguments - if(socket->ReceiveDataOnly(&enable,sizeof(enable)) < 0 ){ + if(mySock->ReceiveDataOnly(&enable,sizeof(enable)) < 0 ){ strcpy(mess,"Error reading from socket\n"); cprintf(RED,"%s",mess); ret = FAIL; @@ -2957,8 +2957,8 @@ int slsReceiverTCPIPInterface::set_activate() { // execute action if the arguments correctly arrived #ifdef SLS_RECEIVER_UDP_FUNCTIONS if (ret==OK) { - if (lockStatus==1 && socket->differentClients==1){ - sprintf(mess,"Receiver locked by %s\n", socket->lastClientIP); + if (lockStatus==1 && mySock->differentClients==1){ + sprintf(mess,"Receiver locked by %s\n", mySock->lastClientIP); ret=FAIL; } @@ -2992,18 +2992,18 @@ int slsReceiverTCPIPInterface::set_activate() { #endif - if(ret==OK && socket->differentClients){ + if(ret==OK && mySock->differentClients){ FILE_LOG(logDEBUG) << "Force update"; ret=FORCE_UPDATE; } // send answer - socket->SendDataOnly(&ret,sizeof(ret)); + mySock->SendDataOnly(&ret,sizeof(ret)); if(ret==FAIL){ cprintf(RED,"%s\n",mess); - socket->SendDataOnly(mess,sizeof(mess)); + mySock->SendDataOnly(mess,sizeof(mess)); } - socket->SendDataOnly(&retval,sizeof(retval)); + mySock->SendDataOnly(&retval,sizeof(retval)); //return ok/fail return ret; @@ -3045,7 +3045,7 @@ int slsReceiverTCPIPInterface::lock_receiver() { int lock; // receive arguments - if(socket->ReceiveDataOnly(&lock,sizeof(lock)) < 0 ){ + if(mySock->ReceiveDataOnly(&lock,sizeof(lock)) < 0 ){ sprintf(mess,"Error reading from socket\n"); cout << "Error reading from socket (lock)" << endl; ret=FAIL; @@ -3053,27 +3053,27 @@ int slsReceiverTCPIPInterface::lock_receiver() { // execute action if the arguments correctly arrived if(ret==OK){ if (lock>=0) { - if (lockStatus==0 || strcmp(socket->lastClientIP,socket->thisClientIP)==0 || strcmp(socket->lastClientIP,"none")==0) { + if (lockStatus==0 || strcmp(mySock->lastClientIP,mySock->thisClientIP)==0 || strcmp(mySock->lastClientIP,"none")==0) { lockStatus=lock; - strcpy(socket->lastClientIP,socket->thisClientIP); + strcpy(mySock->lastClientIP,mySock->thisClientIP); } else { ret=FAIL; - sprintf(mess,"Receiver already locked by %s\n", socket->lastClientIP); + sprintf(mess,"Receiver already locked by %s\n", mySock->lastClientIP); } } } - if (socket->differentClients && ret==OK) + if (mySock->differentClients && ret==OK) ret=FORCE_UPDATE; // send answer - socket->SendDataOnly(&ret,sizeof(ret)); + mySock->SendDataOnly(&ret,sizeof(ret)); if(ret==FAIL){ cprintf(RED,"%s\n",mess); - socket->SendDataOnly(mess,sizeof(mess)); + mySock->SendDataOnly(mess,sizeof(mess)); } else - socket->SendDataOnly(&lockStatus,sizeof(lockStatus)); + mySock->SendDataOnly(&lockStatus,sizeof(lockStatus)); //return ok/fail return ret; @@ -3094,13 +3094,13 @@ int slsReceiverTCPIPInterface::set_port() { int p_number; // receive arguments - if(socket->ReceiveDataOnly(&p_type,sizeof(p_type)) < 0 ){ + if(mySock->ReceiveDataOnly(&p_type,sizeof(p_type)) < 0 ){ strcpy(mess,"Error reading from socket\n"); cout << mess << endl; ret=FAIL; } - if(socket->ReceiveDataOnly(&p_number,sizeof(p_number)) < 0 ){ + if(mySock->ReceiveDataOnly(&p_number,sizeof(p_number)) < 0 ){ strcpy(mess,"Error reading from socket\n"); cout << mess << endl; ret=FAIL; @@ -3108,9 +3108,9 @@ int slsReceiverTCPIPInterface::set_port() { // execute action if the arguments correctly arrived if (ret==OK) { - if (socket->differentClients==1 && lockStatus==1 ) { + if (mySock->differentClients==1 && lockStatus==1 ) { ret=FAIL; - sprintf(mess,"Detector locked by %s\n",socket->lastClientIP); + sprintf(mess,"Detector locked by %s\n",mySock->lastClientIP); } else { if (p_number<1024) { @@ -3119,14 +3119,14 @@ int slsReceiverTCPIPInterface::set_port() { ret=FAIL; } cout << "set port " << p_type << " to " << p_number <lastClientIP); + strcpy(oldLastClientIP, mySock->lastClientIP); mySocket = new MySocketTCP(p_number); } if(mySocket){ sd = mySocket->getErrorStatus(); if (!sd){ ret=OK; - strcpy(socket->lastClientIP,oldLastClientIP); + strcpy(mySock->lastClientIP,oldLastClientIP); if (mySocket->differentClients) ret=FORCE_UPDATE; } else { @@ -3142,16 +3142,16 @@ int slsReceiverTCPIPInterface::set_port() { } // send answer - socket->SendDataOnly(&ret,sizeof(ret)); + mySock->SendDataOnly(&ret,sizeof(ret)); if(ret==FAIL){ cprintf(RED,"%s\n",mess); - socket->SendDataOnly(mess,sizeof(mess)); + mySock->SendDataOnly(mess,sizeof(mess)); }else { - socket->SendDataOnly(&p_number,sizeof(p_number)); + mySock->SendDataOnly(&p_number,sizeof(p_number)); if(sd>=0){ - socket->Disconnect(); - delete socket; - socket = mySocket; + mySock->Disconnect(); + delete mySock; + mySock = mySocket; } } @@ -3167,11 +3167,11 @@ int slsReceiverTCPIPInterface::set_port() { int slsReceiverTCPIPInterface::get_last_client_ip() { ret=OK; - if (socket->differentClients ) + if (mySock->differentClients ) ret=FORCE_UPDATE; - socket->SendDataOnly(&ret,sizeof(ret)); - socket->SendDataOnly(socket->lastClientIP,sizeof(socket->lastClientIP)); + mySock->SendDataOnly(&ret,sizeof(ret)); + mySock->SendDataOnly(mySock->lastClientIP,sizeof(mySock->lastClientIP)); return ret; } @@ -3188,14 +3188,14 @@ int slsReceiverTCPIPInterface::send_update() { char defaultVal[MAX_STR_LENGTH]=""; char* path = NULL; - socket->SendDataOnly(socket->lastClientIP,sizeof(socket->lastClientIP)); + mySock->SendDataOnly(mySock->lastClientIP,sizeof(mySock->lastClientIP)); //index #ifdef SLS_RECEIVER_UDP_FUNCTIONS ind=receiverBase->getFileIndex(); - socket->SendDataOnly(&ind,sizeof(ind)); + mySock->SendDataOnly(&ind,sizeof(ind)); #endif //filepath @@ -3203,9 +3203,9 @@ int slsReceiverTCPIPInterface::send_update() { path = receiverBase->getFilePath(); #endif if(path == NULL) - socket->SendDataOnly(defaultVal,MAX_STR_LENGTH); + mySock->SendDataOnly(defaultVal,MAX_STR_LENGTH); else{ - socket->SendDataOnly(path,MAX_STR_LENGTH); + mySock->SendDataOnly(path,MAX_STR_LENGTH); delete[] path; } @@ -3215,14 +3215,14 @@ int slsReceiverTCPIPInterface::send_update() { path = receiverBase->getFileName(); #endif if(path == NULL) - socket->SendDataOnly(defaultVal,MAX_STR_LENGTH); + mySock->SendDataOnly(defaultVal,MAX_STR_LENGTH); else{ - socket->SendDataOnly(path,MAX_STR_LENGTH); + mySock->SendDataOnly(path,MAX_STR_LENGTH); delete[] path; } if (lockStatus==0) { - strcpy(socket->lastClientIP,socket->thisClientIP); + strcpy(mySock->lastClientIP,mySock->thisClientIP); } return ret; @@ -3241,10 +3241,10 @@ int slsReceiverTCPIPInterface::update_client() { strcpy(mess,SET_RECEIVER_ERR_MESSAGE); ret=FAIL; } - socket->SendDataOnly(&ret,sizeof(ret)); + mySock->SendDataOnly(&ret,sizeof(ret)); if(ret==FAIL){ cprintf(RED,"%s\n",mess); - socket->SendDataOnly(mess,sizeof(mess)); + mySock->SendDataOnly(mess,sizeof(mess)); return ret; } @@ -3259,9 +3259,9 @@ int slsReceiverTCPIPInterface::update_client() { int slsReceiverTCPIPInterface::exit_server() { ret=GOODBYE; - socket->SendDataOnly(&ret,sizeof(ret)); + mySock->SendDataOnly(&ret,sizeof(ret)); strcpy(mess,"closing server"); - socket->SendDataOnly(mess,sizeof(mess)); + mySock->SendDataOnly(mess,sizeof(mess)); cprintf(RED,"%s\n",mess); return ret; } @@ -3277,7 +3277,7 @@ int slsReceiverTCPIPInterface::exec_command() { int sysret=0; // receive arguments - if(socket->ReceiveDataOnly(cmd,MAX_STR_LENGTH) < 0 ){ + if(mySock->ReceiveDataOnly(cmd,MAX_STR_LENGTH) < 0 ){ sprintf(mess,"Error reading from socket\n"); ret=FAIL; } @@ -3287,14 +3287,14 @@ int slsReceiverTCPIPInterface::exec_command() { #ifdef VERYVERBOSE cout << "executing command " << cmd << endl; #endif - if (lockStatus==0 || socket->differentClients==0) + if (lockStatus==0 || mySock->differentClients==0) sysret=system(cmd); //should be replaced by popen if (sysret==0) { strcpy(answer,"Succeeded\n"); - if (lockStatus==1 && socket->differentClients==1) - sprintf(answer,"Detector locked by %s\n", socket->lastClientIP); + if (lockStatus==1 && mySock->differentClients==1) + sprintf(answer,"Detector locked by %s\n", mySock->lastClientIP); } else { strcpy(answer,"Failed\n"); ret=FAIL; @@ -3304,8 +3304,8 @@ int slsReceiverTCPIPInterface::exec_command() { // send answer - socket->SendDataOnly(&ret,sizeof(ret)); - if(socket->SendDataOnly(answer,MAX_STR_LENGTH) < 0){ + mySock->SendDataOnly(&ret,sizeof(ret)); + if(mySock->SendDataOnly(answer,MAX_STR_LENGTH) < 0){ strcpy(mess,"Error writing to socket"); ret=FAIL; } From 5445552b17e53009bbd1d57fdc7e06bd88b0decb Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Fri, 25 Nov 2016 14:34:49 +0100 Subject: [PATCH 451/474] removed bug where it shuts down socket and tries to read it as it is -1 --- .../src/UDPStandardImplementation.cpp | 104 +++++++++++++----- 1 file changed, 74 insertions(+), 30 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index f92adfb6f..5215e0f58 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1140,13 +1140,13 @@ void UDPStandardImplementation::startReadout(){ //needs to wait for packets only if activated if(activated){ //check if all packets got - int totalP = 0,prev=-1,i; - for(i=0; igetCurrentTotalReceived(); //wait for all packets @@ -1157,19 +1157,19 @@ void UDPStandardImplementation::startReadout(){ //(as one listens to many at a time, shouldnt cut off in between) while((prev != totalP) || (prevReceivedInBuffer!= currentReceivedInBuffer)){ #ifdef DEBUG5 - cprintf(MAGENTA,"waiting for all packets totalP:%d currently in buffer:%d\n",totalP,currentReceivedInBuffer); + cprintf(MAGENTA,"waiting for all packets prevP:%d totalP:%d PrevBuffer:%d currentBuffer:%d\n",prev,totalP,prevReceivedInBuffer,currentReceivedInBuffer); #endif //usleep(2*1000*1000); usleep(5*1000);/* Need to find optimal time (exposure time and acquisition period) **/ prev = totalP; totalP = 0; - for(i=0; igetCurrentTotalReceived(); #ifdef DEBUG5 cprintf(MAGENTA,"\tupdated: totalP:%d currently in buffer:%d\n",totalP,currentReceivedInBuffer); @@ -1662,7 +1662,8 @@ int UDPStandardImplementation::createNewFile(int ithread){ ); } - } + }else + printf("Thread:%d File opened:%s\n",ithread, completeFileName[ithread]); //write file header if(myDetectorType == EIGER) @@ -2074,7 +2075,7 @@ void UDPStandardImplementation::startListening(){ } //problem in receiving or end of acquisition - if (status == TRANSMITTING||(rc == 0 && activated == 0)){ + if (status == TRANSMITTING||(rc <= 0 && activated == 0)){ stopListening(ithread,rc); continue; } @@ -2119,14 +2120,15 @@ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int cSize, ch receivedSize = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + fifoBufferHeaderSize + cSize, (bufferSize * numberofJobsPerBuffer) - cSize); - //write packet count to buffer - *((uint32_t*)(buffer[ithread])) = (receivedSize/onePacketSize); - totalListeningPacketCount[ithread] += (receivedSize/onePacketSize); - - //start indices for each start of scan/acquisition - if((!measurementStarted[ithread]) && (receivedSize > 0)) - startFrameIndices(ithread); + if(receivedSize > 0){ + //write packet count to buffer + *((uint32_t*)(buffer[ithread])) = (receivedSize/onePacketSize); + totalListeningPacketCount[ithread] += (receivedSize/onePacketSize); + //start indices for each start of scan/acquisition + if(!measurementStarted[ithread]) //and rc>0 + startFrameIndices(ithread); + } #ifdef DEBUG cprintf(BLUE, "Listening_Thread %d : Received bytes: %d. Expected bytes: %d\n", ithread, receivedSize, bufferSize * numberofJobsPerBuffer-cSize); #endif @@ -2202,10 +2204,13 @@ int UDPStandardImplementation::prepareAndListenBufferCompleteFrames(int ithread) //read first packet pnum = FIRSTPNUM; //first packet number to validate if(status != TRANSMITTING) rc = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + offset); - if(!rc) return 0; - if(getFrameandPacketNumber(ithread,buffer[ithread] + offset,fi,pi,si,bi) == FAIL) + if(rc <= 0) return 0; + if(getFrameandPacketNumber(ithread,buffer[ithread] + offset,fi,pi,si,bi) == FAIL){ pi = ALL_MASK_32; //got 0 from fpga - fnum = fi; //fnum of first packet + fi = ALL_MASK_32; + } + else + fnum = fi; //fnum of first packet bnum = bi; //bnum of first packet totalListeningPacketCount[ithread]++; #ifdef VERBOSE @@ -2237,7 +2242,7 @@ int UDPStandardImplementation::prepareAndListenBufferCompleteFrames(int ithread) rc=0; //listen again if(status != TRANSMITTING) rc = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + offset); - if(!rc){ //end: update ignored and return + if(rc <= 0){ //end: update ignored and return if(myDetectorType == JUNGFRAU) totalIgnoredPacketCount[ithread] += (packetsPerFrame - pnum); else @@ -2245,10 +2250,13 @@ int UDPStandardImplementation::prepareAndListenBufferCompleteFrames(int ithread) return 0; } totalListeningPacketCount[ithread]++; - if(getFrameandPacketNumber(ithread, buffer[ithread] + offset,fi,pi,si,bi) == FAIL) + if(getFrameandPacketNumber(ithread, buffer[ithread] + offset,fi,pi,si,bi) == FAIL){ pi = ALL_MASK_32; //got 0 from fpga - if(myDetectorType == EIGER) - fnum = fi; //update currentfnum for eiger (next packets should have currentfnum value) + fi = ALL_MASK_32; + totalIgnoredPacketCount[ithread] += (pnum + 1); + } + else if(myDetectorType == EIGER) + fnum = fi; //update currentfnum for eiger (next packets should have currentfnum value) #ifdef VERBOSE if(!ithread) cout << "next currentpnum :" << pnum << endl; #endif @@ -2274,7 +2282,7 @@ int UDPStandardImplementation::prepareAndListenBufferCompleteFrames(int ithread) rc=0; if(status != TRANSMITTING) rc = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + offset); - if(!rc){ + if(rc <= 0){ if(myDetectorType == JUNGFRAU) totalIgnoredPacketCount[ithread] += (packetsPerFrame - pnum); else @@ -2282,13 +2290,16 @@ int UDPStandardImplementation::prepareAndListenBufferCompleteFrames(int ithread) return 0; } totalListeningPacketCount[ithread]++; - if(getFrameandPacketNumber(ithread, buffer[ithread] + offset,fi,pi,si,bi) == FAIL) + if(getFrameandPacketNumber(ithread, buffer[ithread] + offset,fi,pi,si,bi) == FAIL){ pi = ALL_MASK_32; //got 0 from fpga + fi = ALL_MASK_32; + } #ifdef VERBOSE if(!ithread) cout << "trying to find pnum:" << pnum << " got " << pi << endl; #endif } - fnum = fi; //fnum of first packet + if(fi!=ALL_MASK_32) + fnum = fi; //fnum of first packet bnum = bi; //bnum of first packet } } @@ -2508,17 +2519,17 @@ void UDPStandardImplementation::startWriting(){ //--reset parameters before acquisition (depending on compression) nf = 0; //compression has only one listening thread (anything not eiger) - if(dataCompressionEnable) - listenfifoIndex = 0; //compression has only one listening thread (anything not eiger) - else - listenfifoIndex = ithread; /* inner loop - loop for each buffer */ //until mask unset (udp sockets shut down by client) while((1 << ithread) & writerThreadsMask){ + //pop - fifo[listenfifoIndex]->pop(wbuf); + if(!dataCompressionEnable) + fifo[ithread]->pop(wbuf); + else + fifo[0]->pop(wbuf); uint32_t numPackets = (uint32_t)(*((uint32_t*)wbuf)); #ifdef DEBUG4 cprintf(GREEN,"Writing_Thread %d: Number of Packets: %d for FIFO %d\n", ithread, numPackets, listenfifoIndex); @@ -2684,6 +2695,7 @@ void UDPStandardImplementation::stopWriting(int ithread, char* wbuffer){ //Print packet loss //if(totalWritingPacketCountFromLastCheck[ithread]){ +#ifdef VERBOSE if(numberofWriterThreads>1){ printf("Thread:%d" "\tLost:%lld" @@ -2711,6 +2723,38 @@ void UDPStandardImplementation::stopWriting(int ithread, char* wbuffer){ (long long int)frameNumberInPreviousCheck[ithread] ); } + + if(numberofWriterThreads>1){ + cprintf(BLUE,"File:%s" + "\nThread:%d" + "\tLost:%lld" + "\t\tPackets:%lld" + "\tFrame#:%lld" + "\tPFrame#:%lld\n", + completeFileName[ithread],ithread, + ((frameNumberInPreviousFile[ithread]+1+maxFramesPerFile)>numberOfFrames) + ?(long long int)((numberOfFrames-(frameNumberInPreviousFile[ithread]+1))*packetsPerFrame - totalPacketsInFile[ithread]) + :(long long int)((frameNumberInPreviousFile[ithread]+maxFramesPerFile - frameNumberInPreviousFile[ithread])*packetsPerFrame - totalPacketsInFile[ithread]), + (long long int)totalPacketsInFile[ithread], + (long long int)currentFrameNumber[ithread], + (long long int)frameNumberInPreviousFile[ithread] + ); + }else{ + cprintf(BLUE,"File:%s" + "\nLost:%lld" + "\t\tPackets:%lld" + "\tFrame#:%lld" + "\tPFrame#:%lld\n", + completeFileName[ithread], + ((frameNumberInPreviousFile[ithread]+1+maxFramesPerFile)>numberOfFrames) + ?(long long int)(numberOfFrames-(frameNumberInPreviousFile[ithread]+1)) + :(long long int)(frameNumberInPreviousFile[ithread]+maxFramesPerFile - frameNumberInPreviousFile[ithread]), + (long long int)totalPacketsInFile[ithread], + (long long int)currentFrameNumber[ithread], + (long long int)frameNumberInPreviousFile[ithread] + ); + } +#endif //} closeFile(ithread); From 0c8ca874e41df8aaee6ba55d7bf9388ede568170 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Mon, 28 Nov 2016 14:52:46 +0100 Subject: [PATCH 452/474] image reconstruction should work now --- .../src/UDPStandardImplementation.cpp | 21 +++++++------------ 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 5215e0f58..b48646afa 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -3112,32 +3112,27 @@ void UDPStandardImplementation::updateFileHeader(int ithread){ "Frames Lost\t: %d\n" "Dynamic Range\t: %d\n" "Ten Giga\t: %d\n" - "Packet\t\t: %d bytes\n" - "Data\t\t: %d bytes\n" + "Image Size\t: %d bytes\n" "x\t\t: %d pixels\n" "y\t\t: %d pixels\n" "Total Frames\t: %lld\n" "Exptime (ns)\t: %lld\n" "Period (ns)\t: %lld\n" "Timestamp\t: %s\n\n" - //only for eiger right now - "#Packet Header\n" - "Subframe Number\t: 4 bytes\n" - "Unused\t\t: 2 bytes\n" - "Port Number\t: 1 byte\n" - "Unused\t\t: 1 byte\n\n" - "#Packet Footer\n" - "Frame Number\t: 6 bytes\n" - "Packet Number\t: 2 bytes\n", + + "#Frame Header\n" + "Frame Number\t: 8 bytes\n" + "Bunch ID\t: 8 bytes\n", FILE_HEADER_SIZE, - (bottomEnable?0:1),(ithread?0:1), + (bottomEnable?0:1), + (ithread?0:1), activated, (long long int)(totalPacketsInFile[ithread]/packetsPerFrame), ((frameNumberInPreviousFile[ithread]+1+maxFramesPerFile)>numberOfFrames) ?(long long int)((numberOfFrames-(frameNumberInPreviousFile[ithread]+1)) - (totalPacketsInFile[ithread]/packetsPerFrame)) :(long long int)((frameNumberInPreviousFile[ithread]+maxFramesPerFile - frameNumberInPreviousFile[ithread]) - (totalPacketsInFile[ithread]/packetsPerFrame)), dynamicRange,tengigaEnable, - onePacketSize,oneDataSize, + bufferSize, //only for eiger right now EIGER_PIXELS_IN_ONE_ROW,EIGER_PIXELS_IN_ONE_COL, (long long int)numberOfFrames, From 09645cbba86a7bf20cc1c391c108678123bddbc5 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Wed, 30 Nov 2016 10:36:46 +0100 Subject: [PATCH 453/474] bottom is defined as flippeddatax in config file, not anymore as argument for receiver --- .../include/UDPBaseImplementation.h | 18 +++-- slsReceiverSoftware/include/UDPInterface.h | 16 ++-- .../include/UDPStandardImplementation.h | 8 -- .../include/slsReceiverTCPIPInterface.h | 9 +-- .../include/sls_receiver_funcs.h | 3 +- .../src/UDPBaseImplementation.cpp | 17 +++-- .../src/UDPStandardImplementation.cpp | 36 ++------- slsReceiverSoftware/src/slsReceiver.cpp | 16 +--- .../src/slsReceiverTCPIPInterface.cpp | 74 +++++++++++++++++-- 9 files changed, 116 insertions(+), 81 deletions(-) diff --git a/slsReceiverSoftware/include/UDPBaseImplementation.h b/slsReceiverSoftware/include/UDPBaseImplementation.h index ff5e85928..4b9766307 100644 --- a/slsReceiverSoftware/include/UDPBaseImplementation.h +++ b/slsReceiverSoftware/include/UDPBaseImplementation.h @@ -50,6 +50,12 @@ class UDPBaseImplementation : protected virtual slsReceiverDefs, public UDPInter */ char *getDetectorHostname() const; + /* + * Get flipped data across 'axis' + * @return if data is flipped across 'axis' + */ + int getFlippedData(int axis=0) const; + //***file parameters*** /** @@ -234,11 +240,11 @@ class UDPBaseImplementation : protected virtual slsReceiverDefs, public UDPInter */ void configure(map config_map); - /** - * Set Bottom Enable (eiger specific, should be moved to configure, and later from client via TCPIP) - * @param b is true for bottom enabled or false for bottom disabled + /* + * Get flipped data across 'axis' + * @return if data is flipped across 'axis' */ - void setBottomEnable(const bool b); + void setFlippedData(int axis=0, int enable=-1); //***file parameters*** @@ -532,8 +538,8 @@ class UDPBaseImplementation : protected virtual slsReceiverDefs, public UDPInter bool tengigaEnable; /** Fifo Depth */ uint32_t fifoDepth; - /** Bottom Half Module Enable */ - bool bottomEnable; + /** enable for flipping data across both axes */ + bool flippedData[2]; //***receiver parameters*** /** Maximum Number of Listening Threads/ UDP Ports */ diff --git a/slsReceiverSoftware/include/UDPInterface.h b/slsReceiverSoftware/include/UDPInterface.h index bcc705aaa..8bdc1a87e 100644 --- a/slsReceiverSoftware/include/UDPInterface.h +++ b/slsReceiverSoftware/include/UDPInterface.h @@ -103,13 +103,19 @@ class UDPInterface { * They access local cache of configuration or detector parameters ******* *************************************************************************/ - //**initial parameters*** + //**initial/detector parameters*** /* * Get detector hostname * @return hostname or NULL if uninitialized, must be released by calling function (max of 1000 characters) */ virtual char *getDetectorHostname() const = 0; + /* + * Get flipped data across 'axis' + * @return if data is flipped across 'axis' + */ + virtual int getFlippedData(int axis=0) const = 0; + //***file parameters*** /** @@ -292,11 +298,11 @@ class UDPInterface { */ virtual void configure(map config_map) = 0; - /** - * Set Bottom Enable (eiger specific, should be moved to configure, and later from client via TCPIP) - * @param b is true for bottom enabled or false for bottom disabled + /* + * Get flipped data across 'axis' + * @return if data is flipped across 'axis' */ - virtual void setBottomEnable(const bool b)= 0; + virtual void setFlippedData(int axis=0, int enable=-1) = 0; //***file parameters*** diff --git a/slsReceiverSoftware/include/UDPStandardImplementation.h b/slsReceiverSoftware/include/UDPStandardImplementation.h index c1023a996..ad455e791 100644 --- a/slsReceiverSoftware/include/UDPStandardImplementation.h +++ b/slsReceiverSoftware/include/UDPStandardImplementation.h @@ -61,14 +61,6 @@ class UDPStandardImplementation: private virtual slsReceiverDefs, public UDPBase *************************************************************************/ //**initial parameters*** - - /** - * Overridden method - * Configure command line parameters - * @param config_map mapping of config parameters passed from command line arguments - */ - void configure(map config_map); - //*** file parameters*** /** * Set File Name Prefix (without frame index, file index and extension (_d0_f000000000000_8.raw)) diff --git a/slsReceiverSoftware/include/slsReceiverTCPIPInterface.h b/slsReceiverSoftware/include/slsReceiverTCPIPInterface.h index 0c5d5655e..f0bf66f03 100644 --- a/slsReceiverSoftware/include/slsReceiverTCPIPInterface.h +++ b/slsReceiverSoftware/include/slsReceiverTCPIPInterface.h @@ -26,10 +26,9 @@ class slsReceiverTCPIPInterface : private virtual slsReceiverDefs { * @param succecc socket creation was successfull * @param rbase pointer to the receiver base * @param pn port number (defaults to default port number) - * @param bot mode is bottom if true, else its a top half module */ - slsReceiverTCPIPInterface(int &success, UDPInterface* rbase, int pn=-1, bool bot=false); + slsReceiverTCPIPInterface(int &success, UDPInterface* rbase, int pn=-1); /** * Sets the port number to listen to. @@ -216,6 +215,9 @@ private: /** activate/ deactivate */ int set_activate(); + /** enable flipped data */ + int set_flipped_data(); + //General Functions /** Locks Receiver */ @@ -284,9 +286,6 @@ private: /** port number */ int portNumber; - /** true if bottom half module for eiger */ - bool bottom; - /** Receiver not setup error message */ char SET_RECEIVER_ERR_MESSAGE[MAX_STR_LENGTH]; diff --git a/slsReceiverSoftware/include/sls_receiver_funcs.h b/slsReceiverSoftware/include/sls_receiver_funcs.h index 5030cb5b2..3fffb7d30 100644 --- a/slsReceiverSoftware/include/sls_receiver_funcs.h +++ b/slsReceiverSoftware/include/sls_receiver_funcs.h @@ -54,8 +54,9 @@ enum { F_ACTIVATE, /** < activate/deactivate readout */ F_STREAM_DATA_FROM_RECEIVER, /**< stream data from receiver to client */ - F_READ_RECEIVER_TIMER /** < sets the timer between each data stream in receiver */ + F_READ_RECEIVER_TIMER, /** < sets the timer between each data stream in receiver */ + F_SET_FLIPPED_DATA_RECEIVER /** < sets the enable to flip data across x/y axis (bottom/top) */ /* Always append functions hereafter!!! */ }; diff --git a/slsReceiverSoftware/src/UDPBaseImplementation.cpp b/slsReceiverSoftware/src/UDPBaseImplementation.cpp index 8f57fba78..80e98e226 100644 --- a/slsReceiverSoftware/src/UDPBaseImplementation.cpp +++ b/slsReceiverSoftware/src/UDPBaseImplementation.cpp @@ -46,7 +46,8 @@ void UDPBaseImplementation::initializeMembers(){ dynamicRange = 16; tengigaEnable = false; fifoDepth = 0; - bottomEnable = false; + flippedData[0] = false; + flippedData[1] = false; //***receiver parameters*** status = IDLE; @@ -104,6 +105,12 @@ char *UDPBaseImplementation::getDetectorHostname() const{ return output; } +int UDPBaseImplementation::getFlippedData(int axis) const{ + FILE_LOG(logDEBUG) << __AT__ << " starting"; + if(axis<0 || axis > 1) return -1; + return flippedData[axis]; +} + /***file parameters***/ char *UDPBaseImplementation::getFileName() const{ @@ -211,11 +218,11 @@ void UDPBaseImplementation::configure(map config_map){ FILE_LOG(logERROR) << __AT__ << " must be overridden by child classes"; } -void UDPBaseImplementation::setBottomEnable(const bool b){ +void UDPBaseImplementation::setFlippedData(int axis, int enable){ FILE_LOG(logDEBUG) << __AT__ << " starting"; - - bottomEnable = b; - FILE_LOG(logINFO) << "Bottom - " << stringEnable(bottomEnable); + if(axis<0 || axis>1) return; + flippedData[axis] = enable; + FILE_LOG(logINFO) << "Flipped Data: " << flippedData[0] << " , " << flippedData[1]; } diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index b48646afa..0b8b58ce3 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -416,23 +416,6 @@ int UDPStandardImplementation::setupFifoStructure(){ -void UDPStandardImplementation::configure(map config_map){ - FILE_LOG(logDEBUG) << __AT__ << " starting"; - - map::const_iterator pos; - pos = config_map.find("mode"); - if (pos != config_map.end() ){ - int b; - if(!sscanf(pos->second.c_str(), "%d", &b)){ - cout << "Warning: Could not parse mode. Assuming top mode." << endl; - b = 0; - } - bottomEnable = b!= 0; - FILE_LOG(logINFO) << "Bottom: " << stringEnable(bottomEnable); - } - -} - void UDPStandardImplementation::setFileName(const char c[]){ FILE_LOG(logDEBUG) << __AT__ << " starting"; @@ -1489,11 +1472,7 @@ int UDPStandardImplementation::createUDPSockets(){ uint32_t port[2]; port[0]= udpPortNum[0]; port[1]= udpPortNum[1]; - //port = udpPortNum; - if(bottomEnable){ - port[0] = udpPortNum[1]; - port[1] = udpPortNum[0]; - } + //if eth is mistaken with ip address if (strchr(eth,'.') != NULL) @@ -2420,10 +2399,8 @@ uint32_t UDPStandardImplementation::processListeningBuffer(int ithread, int &cSi int lastPacketOffset; //the offset of the last packet uint32_t lastFrameHeader; //frame number of last packet in buffer - uint64_t lastFrameHeader64; //frame number of last packet in buffer uint32_t packetCount = (rc/onePacketSize);//(packetsPerFrame/numberofListeningThreads) * numberofJobsPerBuffer; //packets received cSize = 0; //reset size - jfrau_packet_header_t* header; switch(myDetectorType){ case GOTTHARD: @@ -2510,7 +2487,6 @@ void UDPStandardImplementation::startWriting(){ char* wbuf = NULL; //buffer popped from FIFO sfilefd[ithread] = 0; //file pointer uint64_t nf = 0; //for compression, number of frames - int listenfifoIndex = ithread; /* outer loop - loops once for each acquisition */ @@ -2532,14 +2508,14 @@ void UDPStandardImplementation::startWriting(){ fifo[0]->pop(wbuf); uint32_t numPackets = (uint32_t)(*((uint32_t*)wbuf)); #ifdef DEBUG4 - cprintf(GREEN,"Writing_Thread %d: Number of Packets: %d for FIFO %d\n", ithread, numPackets, listenfifoIndex); + cprintf(GREEN,"Writing_Thread %d: Number of Packets: %d for FIFO %d\n", ithread, numPackets, dataCompressionEnable?0:ithread); #endif //end of acquisition if(numPackets == dummyPacketValue){ #ifdef DEBUG4 - cprintf(GREEN,"Writing_Thread %d: Dummy frame popped out of FIFO %d",ithread, listenfifoIndex); + cprintf(GREEN,"Writing_Thread %d: Dummy frame popped out of FIFO %d",ithread, dataCompressionEnable?0:ithread); #endif stopWriting(ithread,wbuf); continue; @@ -3108,8 +3084,8 @@ void UDPStandardImplementation::updateFileHeader(int ithread){ "Top\t\t: %d\n" "Left\t\t: %d\n" "Active\t\t: %d\n" - "Frames Caught\t: %d\n" - "Frames Lost\t: %d\n" + "Frames Caught\t: %lld\n" + "Frames Lost\t: %lld\n" "Dynamic Range\t: %d\n" "Ten Giga\t: %d\n" "Image Size\t: %d bytes\n" @@ -3124,7 +3100,7 @@ void UDPStandardImplementation::updateFileHeader(int ithread){ "Frame Number\t: 8 bytes\n" "Bunch ID\t: 8 bytes\n", FILE_HEADER_SIZE, - (bottomEnable?0:1), + (flippedData[0]?0:1), (ithread?0:1), activated, (long long int)(totalPacketsInFile[ithread]/packetsPerFrame), diff --git a/slsReceiverSoftware/src/slsReceiver.cpp b/slsReceiverSoftware/src/slsReceiver.cpp index a6c231a3e..04bc29563 100644 --- a/slsReceiverSoftware/src/slsReceiver.cpp +++ b/slsReceiverSoftware/src/slsReceiver.cpp @@ -41,14 +41,12 @@ slsReceiver::slsReceiver(int argc, char *argv[], int &success){ string rest_hostname = "localhost:8081"; udp_interface = NULL; - bool bottom = false; //TODO: properly set new parameter -> mode? //parse command line for config static struct option long_options[] = { /* These options set a flag. */ //{"verbose", no_argument, &verbose_flag, 1}, /* These options don’t set a flag. We distinguish them by their indices. */ - {"mode", required_argument, 0, 'm'}, {"type", required_argument, 0, 't'}, {"config", required_argument, 0, 'f'}, {"rx_tcpport", required_argument, 0, 'b'}, @@ -62,7 +60,7 @@ slsReceiver::slsReceiver(int argc, char *argv[], int &success){ optind = 1; while ( c != -1 ){ - c = getopt_long (argc, argv, "mbfhtr", long_options, &option_index); + c = getopt_long (argc, argv, "bfhtr", long_options, &option_index); /* Detect the end of the options. */ if (c == -1) @@ -70,13 +68,6 @@ slsReceiver::slsReceiver(int argc, char *argv[], int &success){ switch(c){ - case 'm': - int b; - sscanf(optarg, "%d", &b); - bottom = b != 0; - configuration_map["mode"] = optarg; - break; - case 'f': fname = optarg; //cout << long_options[option_index].name << " " << optarg << endl; @@ -98,7 +89,6 @@ slsReceiver::slsReceiver(int argc, char *argv[], int &success){ string help_message = """\nSLS Receiver Server\n\n"""; help_message += """usage: slsReceiver --config config_fname [--rx_tcpport port]\n\n"""; help_message += """\t--config:\t configuration filename for SLS Detector receiver\n"""; - help_message += """\t--mode:\t 1 for bottom and 0 for top\n"""; help_message += """\t--rx_tcpport:\t TCP Communication Port with the client. Default: 1954.\n\n"""; help_message += """\t--rest_hostname:\t Receiver hostname:port. It applies only to REST receivers, and indicates the hostname of the REST backend. Default: localhost:8081.\n\n"""; @@ -132,12 +122,12 @@ slsReceiver::slsReceiver(int argc, char *argv[], int &success){ } if (success==OK){ - FILE_LOG(logINFO) << "SLS Receiver starting " << udp_interface_type << " on port " << tcpip_port_no << " with mode " << bottom << endl; + FILE_LOG(logINFO) << "SLS Receiver starting " << udp_interface_type << " on port " << tcpip_port_no << endl; #ifdef REST udp_interface = UDPInterface::create(udp_interface_type); udp_interface->configure(configuration_map); #endif - tcpipInterface = new slsReceiverTCPIPInterface(success, udp_interface, tcpip_port_no, bottom); + tcpipInterface = new slsReceiverTCPIPInterface(success, udp_interface, tcpip_port_no); } } diff --git a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp index db4e91a33..99948460b 100644 --- a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp +++ b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp @@ -27,7 +27,7 @@ slsReceiverTCPIPInterface::~slsReceiverTCPIPInterface() { if(mySock) {delete mySock; mySock=NULL;} } -slsReceiverTCPIPInterface::slsReceiverTCPIPInterface(int &success, UDPInterface* rbase, int pn, bool bot): +slsReceiverTCPIPInterface::slsReceiverTCPIPInterface(int &success, UDPInterface* rbase, int pn): myDetectorType(GOTTHARD), receiverBase(rbase), ret(OK), @@ -38,7 +38,6 @@ slsReceiverTCPIPInterface::slsReceiverTCPIPInterface(int &success, UDPInterface* killTCPServerThread(0), tenGigaEnable(0), portNumber(DEFAULT_PORTNO+2), - bottom(bot), mySock(NULL){ strcpy(SET_RECEIVER_ERR_MESSAGE,"Receiver not set up. Please use rx_hostname first.\n"); @@ -265,7 +264,7 @@ int slsReceiverTCPIPInterface::function_table(){ flist[F_ACTIVATE] = &slsReceiverTCPIPInterface::set_activate; flist[F_STREAM_DATA_FROM_RECEIVER] = &slsReceiverTCPIPInterface::set_data_stream_enable; flist[F_READ_RECEIVER_TIMER] = &slsReceiverTCPIPInterface::set_read_receiver_timer; - + flist[F_SET_FLIPPED_DATA_RECEIVER] = &slsReceiverTCPIPInterface::set_flipped_data; #ifdef VERYVERBOSE for (int i=0;isetDetectorType(myDetectorType); retval = myDetectorType; -#ifndef REST - receiverBase->setBottomEnable(bottom); -#endif } } @@ -1652,7 +1648,7 @@ int slsReceiverTCPIPInterface::propix_read_frame(){ int slsReceiverTCPIPInterface::eiger_read_frame(){ ret=OK; - +/* char fName[MAX_STR_LENGTH]=""; int acquisitionIndex = -1; int frameIndex= -1; @@ -1905,7 +1901,7 @@ int slsReceiverTCPIPInterface::eiger_read_frame(){ delete [] retval; delete [] origVal; delete [] raw; - +*/ return ret; } @@ -3013,6 +3009,68 @@ int slsReceiverTCPIPInterface::set_activate() { +int slsReceiverTCPIPInterface::set_flipped_data(){ + ret=OK; + int retval = -1; + int args[2]={0,-1}; + strcpy(mess,"Could not set flipped data in receiver\n"); + + + // receive arguments + if(mySock->ReceiveDataOnly(args,sizeof(args)) < 0 ){ + strcpy(mess,"Error reading from socket\n"); + ret = FAIL; + } + + // execute action if the arguments correctly arrived +#ifdef SLS_RECEIVER_UDP_FUNCTIONS + if (ret==OK) { + if (lockStatus==1 && mySock->differentClients==1){ + sprintf(mess,"Receiver locked by %s\n", mySock->lastClientIP); + ret=FAIL; + } + else if (receiverBase == NULL){ + strcpy(mess,SET_RECEIVER_ERR_MESSAGE); + ret=FAIL; + } + else if(receiverBase->getStatus()==RUNNING || receiverBase->getStatus()==TRANSMITTING){ + strcpy(mess,"Can not set flipped data while receiver not idle\n"); + ret = FAIL; + } + else{ + if(args[1] > -1) + receiverBase->setFlippedData(args[0],args[1]); + retval=receiverBase->getFlippedData(args[0]); + } + } +#ifdef VERYVERBOSE + if(ret!=FAIL){ + cout << "Flipped Data:" << retval << endl; + }else + cout << mess << endl; +#endif +#endif + + if(ret==OK && mySock->differentClients){ + FILE_LOG(logDEBUG) << "Force update"; + ret=FORCE_UPDATE; + } + + // send answer + mySock->SendDataOnly(&ret,sizeof(ret)); + if(ret==FAIL){ + cprintf(RED,"%s\n",mess); + mySock->SendDataOnly(mess,sizeof(mess)); + } + mySock->SendDataOnly(&retval,sizeof(retval)); + + //return ok/fail + return ret; +} + + + + From ce086fe79d3f1e6a6437e4fbc79cee07af755e6d Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Wed, 30 Nov 2016 11:20:42 +0100 Subject: [PATCH 454/474] updaterev --- slsReceiverSoftware/gitInfo.txt | 8 ++++---- slsReceiverSoftware/include/gitInfoReceiver.h | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/slsReceiverSoftware/gitInfo.txt b/slsReceiverSoftware/gitInfo.txt index decefcf4a..6282454d0 100644 --- a/slsReceiverSoftware/gitInfo.txt +++ b/slsReceiverSoftware/gitInfo.txt @@ -1,9 +1,9 @@ Path: slsDetectorsPackage/slsReceiverSoftware URL: origin git@git.psi.ch:sls_detectors_software/sls_receiver_software.git Repository Root: origin git@git.psi.ch:sls_detectors_software/sls_receiver_software.git -Repsitory UUID: 5a547c0a52d79479cdc8cb861c258fd2899ba7a2 -Revision: 487 +Repsitory UUID: 2f78f4e118bfba443f84a3f72b2839610a8858a3 +Revision: 493 Branch: developer Last Changed Author: Dhanya_Maliakal -Last Changed Rev: 487 -Last Changed Date: 2016-11-14 11:57:34 +0100 +Last Changed Rev: 493 +Last Changed Date: 2016-11-30 10:36:46 +0100 diff --git a/slsReceiverSoftware/include/gitInfoReceiver.h b/slsReceiverSoftware/include/gitInfoReceiver.h index 2d314f5a3..66704494f 100644 --- a/slsReceiverSoftware/include/gitInfoReceiver.h +++ b/slsReceiverSoftware/include/gitInfoReceiver.h @@ -1,11 +1,11 @@ //#define SVNPATH "" #define SVNURL "git@git.psi.ch:sls_detectors_software/sls_receiver_software.git" //#define SVNREPPATH "" -#define SVNREPUUID "5a547c0a52d79479cdc8cb861c258fd2899ba7a2" -//#define SVNREV 0x487 +#define SVNREPUUID "2f78f4e118bfba443f84a3f72b2839610a8858a3" +//#define SVNREV 0x493 //#define SVNKIND "" //#define SVNSCHED "" #define SVNAUTH "Dhanya_Maliakal" -#define SVNREV 0x487 -#define SVNDATE 0x20161114 +#define SVNREV 0x493 +#define SVNDATE 0x20161130 // From f61d8195994540d88e2043ac9900290dbfd77509 Mon Sep 17 00:00:00 2001 From: Leonardo Sala Date: Thu, 1 Dec 2016 07:43:46 +0000 Subject: [PATCH 455/474] wip for Eiger9M --- slsReceiverSoftware/include/RestHelper.h | 4 +- .../include/UDPRESTImplementation.h | 9 +- slsReceiverSoftware/src/UDPInterface.cpp | 1 + .../src/UDPRESTImplementation.cpp | 261 ++++++++++-------- 4 files changed, 162 insertions(+), 113 deletions(-) diff --git a/slsReceiverSoftware/include/RestHelper.h b/slsReceiverSoftware/include/RestHelper.h index 92846750d..f808cea01 100644 --- a/slsReceiverSoftware/include/RestHelper.h +++ b/slsReceiverSoftware/include/RestHelper.h @@ -167,8 +167,8 @@ class RestHelper { string answer; int code = send_request(session, req, &answer); if(code == 0 ) { - FILE_LOG(logDEBUG) << __AT__ << " REQUEST: " << " ANSWER: " << answer; - json_value->loadFromString(answer); + //FILE_LOG(logDEBUG) << __AT__ << " REQUEST: " << " ANSWER: " << answer; + json_value->loadFromString(answer); } delete uri; return code; diff --git a/slsReceiverSoftware/include/UDPRESTImplementation.h b/slsReceiverSoftware/include/UDPRESTImplementation.h index 374199721..14296f648 100644 --- a/slsReceiverSoftware/include/UDPRESTImplementation.h +++ b/slsReceiverSoftware/include/UDPRESTImplementation.h @@ -42,8 +42,8 @@ public: /** * Get Rest State */ - int get_rest_state(RestHelper * rest, string *rest_state); - + string get_rest_state(RestHelper * rest/*, string *rest_state*/); + /************************************************************************* * Setters *************************************************************** @@ -138,12 +138,15 @@ public: */ void closeFile(int i = -1); + uint64_t getTotalFramesCaught() const; + + private: - bool isInitialized; RestHelper * rest ; int rest_port; // receiver backend port string rest_hostname; // receiver hostname + bool is_main_receiver; }; diff --git a/slsReceiverSoftware/src/UDPInterface.cpp b/slsReceiverSoftware/src/UDPInterface.cpp index 17491bc3a..a6bd2cfac 100644 --- a/slsReceiverSoftware/src/UDPInterface.cpp +++ b/slsReceiverSoftware/src/UDPInterface.cpp @@ -28,6 +28,7 @@ UDPInterface * UDPInterface::create(string receiver_type){ } #ifdef REST else if (receiver_type == "REST"){ + FILE_LOG(logINFO) << "Starting " << receiver_type; return new UDPRESTImplementation(); } #endif diff --git a/slsReceiverSoftware/src/UDPRESTImplementation.cpp b/slsReceiverSoftware/src/UDPRESTImplementation.cpp index ab650257f..f16fadb03 100644 --- a/slsReceiverSoftware/src/UDPRESTImplementation.cpp +++ b/slsReceiverSoftware/src/UDPRESTImplementation.cpp @@ -29,10 +29,11 @@ UDPRESTImplementation::UDPRESTImplementation(){ //TODO I do not really know what to do with bottom... // Default values - isInitialized = false; + isInitialized = true; rest = NULL; rest_hostname = "localhost"; - rest_port = 8081; + rest_port = 8080; + is_main_receiver = false; } @@ -42,6 +43,7 @@ UDPRESTImplementation::~UDPRESTImplementation(){ void UDPRESTImplementation::configure(map config_map){ + // am I ever getting there? FILE_LOG(logWARNING) << __AT__ << " called"; map::const_iterator pos; @@ -65,16 +67,20 @@ void UDPRESTImplementation::configure(map config_map){ } -int UDPRESTImplementation::get_rest_state(RestHelper * rest, string *rest_state){ +string UDPRESTImplementation::get_rest_state(RestHelper * rest/*, string *rest_state*/){ JsonBox::Value answer; - //string rest_state = ""; - int code = rest->get_json("state", &answer); + string rest_state = ""; + + int code = rest->get_json("v1/state", &answer); if ( code != -1 ){ - (*rest_state) = answer["state"].getString(); + + rest_state = answer["global_state"].getString(); + std::cout << rest_state << std::endl; } + //rest_state = *prs; - return code; + return rest_state; } @@ -83,78 +89,102 @@ void UDPRESTImplementation::initialize_REST(){ FILE_LOG(logDEBUG) << __AT__ << " called"; FILE_LOG(logDEBUG) << __AT__ << " REST status is initialized: " << isInitialized; + + std::cout<< fileIndex << " " << getUDPPortNumber() << std::endl; + string rest_state = ""; + std::string answer = ""; + + // HORRIBLE FIX ME ASAP! + if (getUDPPortNumber() == 50011){ + is_main_receiver = true; + } + + // if (is_main_receiver){ + if (rest_hostname.empty()) { - FILE_LOG(logDEBUG) << __AT__ <<"can't initialize with empty string or NULL for detectorHostname"; + FILE_LOG(logDEBUG) << __AT__ <<"can't initialize with empty string or NULL for detectorHostname"; + throw; } - else if (isInitialized == true) { - FILE_LOG(logDEBUG) << __AT__ << "already initialized, can't initialize several times"; - } - else { - FILE_LOG(logDEBUG) << __AT__ << "with receiverHostName=" << rest_hostname << ":" << rest_port; + rest = new RestHelper() ; + rest->init(rest_hostname, rest_port); + rest->set_connection_params(1, 3); + + int code; - rest = new RestHelper() ; - std::string answer; - int code; - try{ - rest->init(rest_hostname, rest_port); - code = get_rest_state(rest, &answer); - std::cout << "AAAAAAAa " << answer << std::endl; - - - if (code != 0){ - FILE_LOG(logERROR) << __AT__ << " REST state returned: " << answer; - throw; - } - else{ - isInitialized = true; - status = slsReceiverDefs::IDLE; - } - FILE_LOG(logDEBUG) << __func__ << "Answer: " << answer; - } - catch(std::string e){ - FILE_LOG(logERROR) << __func__ << ": " << e; - throw; - } - - //JsonBox::Object json_object; - //json_object["configfile"] = JsonBox::Value("FILENAME"); - JsonBox::Value json_request; - //json_request["configfile"] = "config.py"; - json_request["path"] = filePath; - - stringstream ss; - string test; - //std::cout << "GetSTring: " << json_request << std::endl; - json_request.writeToStream(ss, false); - //ss << json_request; - ss >> test; - - - code = rest->get_json("state", &answer); - FILE_LOG(logDEBUG) << __AT__ << " state got " << code << " " << answer << "\n"; - if (answer != "INITIALIZED"){ - test = "{\"path\":\"" + string( getFilePath() ) + "\"}"; - code = rest->post_json("state/initialize", &answer, test); - } - else{ - test = "{\"path\":\"" + string( getFilePath() ) + "\"}"; - code = rest->post_json("state/configure", &answer, test); - } - FILE_LOG(logDEBUG) << __AT__ << " state/configure got " << code; - code = rest->get_json("state", &answer); - FILE_LOG(logDEBUG) << __AT__ << " state got " << code << " " << answer << "\n"; - - - /* - std::std::cout << string << std::endl; << "---- REST test 3: true, json object "<< std::endl; - JsonBox::Value json_value; - code = rest.get_json("status", &json_value); - std::cout << "JSON " << json_value["status"] << std::endl; - */ + if (!is_main_receiver){ + isInitialized = true; + status = slsReceiverDefs::IDLE; + return; } + if (isInitialized == true) { + FILE_LOG(logDEBUG) << __AT__ << "already initialized, can't initialize several times"; + } + else { + FILE_LOG(logDEBUG) << __AT__ << "with receiverHostName=" << rest_hostname << ":" << rest_port; + + try{ + rest_state = get_rest_state(rest); + std::cout << "AAAAAAAa " << rest_state << std::endl; + + + if (rest_state == ""){ + FILE_LOG(logERROR) << __AT__ << " REST state returned: " << rest_state; + throw; + } + else{ + isInitialized = true; + status = slsReceiverDefs::IDLE; + } + FILE_LOG(logDEBUG) << __func__ << "Answer: " << answer; + } + catch(std::string e){ + FILE_LOG(logERROR) << __func__ << ": " << e; + throw; + } + + + //JsonBox::Object json_object; + //json_object["configfile"] = JsonBox::Value("FILENAME"); + JsonBox::Value json_request; + //json_request["configfile"] = "config.py"; + json_request["path"] = filePath; + + stringstream ss; + string test; + //std::cout << "GetSTring: " << json_request << std::endl; + json_request.writeToStream(ss, false); + //ss << json_request; + ss >> test; + + rest_state = get_rest_state(rest); + + //code = rest->get_json("v1/state", &answer); + FILE_LOG(logDEBUG) << __AT__ << " state got " << code << " " << answer << "\n"; + if (rest_state != "INITIALIZED"){ + test = "{\"path\":\"" + string( getFilePath() ) + "\", \"n_frames\":10}"; + code = rest->post_json("v1/state/initialize", &answer, test); + } + else{ + test = "{\"path\":\"" + string( getFilePath() ) + "\"}"; + test = "{\"path\":\"" + string( getFilePath() ) + "\", \"n_frames\":10}"; + code = rest->post_json("v1/state/configure", &answer, test); + } + FILE_LOG(logDEBUG) << __AT__ << " state/configure got " << code; + + rest_state = get_rest_state(rest); + + FILE_LOG(logDEBUG) << __AT__ << " state got " << rest_state << "\n"; + + + /* + std::std::cout << string << std::endl; << "---- REST test 3: true, json object "<< std::endl; + JsonBox::Value json_value; + code = rest.get_json("status", &json_value); + std::cout << "JSON " << json_value["status"] << std::endl; + */ + } FILE_LOG(logDEBUG) << __func__ << ": initialize() done"; - } @@ -187,19 +217,23 @@ int UDPRESTImplementation::startReceiver(char message[]){ cout << "Starting Receiver" << endl; - - std::string request_body = "{\"settings\": {\"bit_depth\": " + str_dr + ", \"nimages\": " + str_n + "}}"; + string rest_state = ""; + std::string request_body = "{\"settings\": {\"bit_depth\": " + str_dr + ", \"n_frames\": " + str_n + "}}"; //std::string request_body = "{\"settings\": {\"nimages\":1, \"scanid\":999, \"bit_depth\":16}}"; - FILE_LOG(logDEBUG) << __FILE__ << "::" << " sending this configuration body: " << request_body; - code = rest->post_json("state/configure", &answer, request_body); - code = rest->get_json("state", &answer); - FILE_LOG(logDEBUG) << __FILE__ << "::" << " got: " << answer; + if(is_main_receiver){ + FILE_LOG(logDEBUG) << __FILE__ << "::" << " sending this configuration body: " << request_body; + code = rest->post_json("v1/state/configure", &answer, request_body); + code = rest->get_json("v1/state", &answer); + FILE_LOG(logDEBUG) << __FILE__ << "::" << " got: " << answer; + + rest_state = get_rest_state(rest); - //code = rest->post_json("state/open", &answer); - //code = rest->get_json("state", &answer); + code = rest->post_json("v1/state/open", &answer); + std::cout << "AAAAAA " << rest_state << std::endl; + } status = RUNNING; - + return OK; } @@ -251,6 +285,7 @@ int UDPRESTImplementation::shutDownUDPSockets(){ FILE_LOG(logDEBUG) << __AT__ << "called"; // this is just to be sure, it could be removed + /* for(int i=0;iget_json("state", &answer); - be_state = answer["state"].getString(); - - // LEO: this is probably wrong - if (be_state == "OPEN"){ - while (be_state != "TRANSIENT"){ - code = rest->get_json("state", &answer); - be_state = answer["state"].getString(); - cout << "be_State: " << be_state << endl; - usleep(10000); - } - - code = rest->post_json("state/close", &answer); - std::cout <post_json("state/reset", &answer); - std::cout << code << " " << answer << std::endl; - - code = rest->get_json("state", &answer); - std::cout << code << " " << answer << std::endl; + if (is_main_receiver){ + + FILE_LOG(logWARNING) << "PLEASE WAIT WHILE CHECKING AND SHUTTING DOWN ALL CONNECTIONS!"; + rest_state = get_rest_state(rest); + std::cout << rest_state << std::endl; + + while (rest_state != "OPEN"){ + rest_state = get_rest_state(rest); + std::cout << rest_state << std::endl; + usleep(10000); + } + //while (rest_state != "TRANSIENT"){ + // rest_state = get_rest_state(rest); + // usleep(10000); + //} + + code = rest->post_json("v1/state/close", &answer); + std::cout <post_json("v1/state/reset", &answer); + std::cout << code << " " << answer << std::endl; + + rest_state = get_rest_state(rest); + std::cout << rest_state << std::endl; } status = slsReceiverDefs::RUN_FINISHED; - + //LEO: not sure it's needed - delete rest; + //delete rest; FILE_LOG(logDEBUG) << __AT__ << "finished"; return OK; @@ -308,7 +346,7 @@ int UDPRESTImplementation::shutDownUDPSockets(){ * in your gui to get data from receiver. you probably have a different way * of reconstructing complete data set from all receivers */ -void UDPRESTImplementation::readFramee(char* c,char** raw, uint64_t &startAcq, uint64_t &startFrame){ +void UDPRESTImplementation::readFrame(char* c,char** raw, uint64_t &startAcq, uint64_t &startFrame){ FILE_LOG(logDEBUG) << __AT__ << " called"; strcpy(c,""); *raw = NULL; @@ -317,6 +355,7 @@ void UDPRESTImplementation::readFramee(char* c,char** raw, uint64_t &startAcq, u + /* FIXME * Its called by TCP in case of illegal shut down such as Ctrl + c. * Upto you what you want to do with it. @@ -327,5 +366,11 @@ void UDPRESTImplementation::closeFile(int ithr){ } +uint64_t UDPRESTImplementation::getTotalFramesCaught() const{ + FILE_LOG(logDEBUG) << __AT__ << " starting"; + return (0); +} + + #endif From 657d3e575906a77d20faaf5e821ff1ce617a8953 Mon Sep 17 00:00:00 2001 From: Leonardo Sala Date: Thu, 1 Dec 2016 15:59:12 +0000 Subject: [PATCH 456/474] first functional commit, still some workarounds. Can start, acquire, stop, restart --- slsReceiverSoftware/include/RestHelper.h | 15 +++++++++++++-- slsReceiverSoftware/src/UDPRESTImplementation.cpp | 7 +++---- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/slsReceiverSoftware/include/RestHelper.h b/slsReceiverSoftware/include/RestHelper.h index f808cea01..d789448ab 100644 --- a/slsReceiverSoftware/include/RestHelper.h +++ b/slsReceiverSoftware/include/RestHelper.h @@ -18,6 +18,7 @@ #include #include "JsonBox/Value.h" +#include "JsonBox/JsonParsingError.h" //#include "logger.h" @@ -167,7 +168,7 @@ class RestHelper { string answer; int code = send_request(session, req, &answer); if(code == 0 ) { - //FILE_LOG(logDEBUG) << __AT__ << " REQUEST: " << " ANSWER: " << answer; + FILE_LOG(logDEBUG) << __AT__ << " REQUEST: " << " ANSWER: " << answer; json_value->loadFromString(answer); } delete uri; @@ -220,7 +221,17 @@ class RestHelper { string answer; int code = send_request(session, req, &answer, request_body); if(code==0){ - json_value->loadFromString(answer); + try{ + json_value->loadFromString(answer); + } + catch (JsonBox::JsonParsingError& e){ + try{ + json_value->loadFromString("{\"global_state\":\"" + answer + "\"}"); + } + catch(exception &e){ + FILE_LOG(logERROR) << "Exception converting answer: " << e.what() ; + } + } } delete uri; return code; diff --git a/slsReceiverSoftware/src/UDPRESTImplementation.cpp b/slsReceiverSoftware/src/UDPRESTImplementation.cpp index f16fadb03..1e5498585 100644 --- a/slsReceiverSoftware/src/UDPRESTImplementation.cpp +++ b/slsReceiverSoftware/src/UDPRESTImplementation.cpp @@ -4,7 +4,6 @@ * @short does all the functions for a receiver, set/get parameters, start/stop etc. ***********************************************/ - #include "UDPRESTImplementation.h" #include // exit() @@ -74,7 +73,7 @@ string UDPRESTImplementation::get_rest_state(RestHelper * rest/*, string *rest_s int code = rest->get_json("v1/state", &answer); if ( code != -1 ){ - + std::cout << answer << std::endl; rest_state = answer["global_state"].getString(); std::cout << rest_state << std::endl; } @@ -327,8 +326,8 @@ int UDPRESTImplementation::shutDownUDPSockets(){ code = rest->post_json("v1/state/reset", &answer); std::cout << code << " " << answer << std::endl; - rest_state = get_rest_state(rest); - std::cout << rest_state << std::endl; + //rest_state = get_rest_state(rest); + //std::cout << rest_state << std::endl; } status = slsReceiverDefs::RUN_FINISHED; From 28b0897dd715089afdf8bfbbf039b48f79af9401 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Fri, 2 Dec 2016 08:55:07 +0100 Subject: [PATCH 457/474] fixed bug of crash when changing dr sometimes, latestdata was incorrectly inititalized --- .../include/UDPBaseImplementation.h | 2 +- .../src/UDPBaseImplementation.cpp | 6 +- .../src/UDPStandardImplementation.cpp | 33 +++++----- .../src/slsReceiverTCPIPInterface.cpp | 60 ++++++++++++------- 4 files changed, 62 insertions(+), 39 deletions(-) diff --git a/slsReceiverSoftware/include/UDPBaseImplementation.h b/slsReceiverSoftware/include/UDPBaseImplementation.h index 4b9766307..ce8a3ddb7 100644 --- a/slsReceiverSoftware/include/UDPBaseImplementation.h +++ b/slsReceiverSoftware/include/UDPBaseImplementation.h @@ -539,7 +539,7 @@ class UDPBaseImplementation : protected virtual slsReceiverDefs, public UDPInter /** Fifo Depth */ uint32_t fifoDepth; /** enable for flipping data across both axes */ - bool flippedData[2]; + int flippedData[2]; //***receiver parameters*** /** Maximum Number of Listening Threads/ UDP Ports */ diff --git a/slsReceiverSoftware/src/UDPBaseImplementation.cpp b/slsReceiverSoftware/src/UDPBaseImplementation.cpp index 80e98e226..e0bf65f6d 100644 --- a/slsReceiverSoftware/src/UDPBaseImplementation.cpp +++ b/slsReceiverSoftware/src/UDPBaseImplementation.cpp @@ -46,8 +46,8 @@ void UDPBaseImplementation::initializeMembers(){ dynamicRange = 16; tengigaEnable = false; fifoDepth = 0; - flippedData[0] = false; - flippedData[1] = false; + flippedData[0] = 0; + flippedData[1] = 0; //***receiver parameters*** status = IDLE; @@ -221,7 +221,7 @@ void UDPBaseImplementation::configure(map config_map){ void UDPBaseImplementation::setFlippedData(int axis, int enable){ FILE_LOG(logDEBUG) << __AT__ << " starting"; if(axis<0 || axis>1) return; - flippedData[axis] = enable; + flippedData[axis] = enable==0?0:1; FILE_LOG(logINFO) << "Flipped Data: " << flippedData[0] << " , " << flippedData[1]; } diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 0b8b58ce3..79d8e0520 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -89,7 +89,7 @@ void UDPStandardImplementation::deleteMembers(){ if(fifoFree[i]) {delete fifoFree[i]; fifoFree[i] = 0;} } for(int i=0; i 1 numberofJobsPerBuffer - if(fifoSize % numberofJobsPerBuffer) - fifoSize = (fifoSize/numberofJobsPerBuffer)+1; + if(fifoDepth % numberofJobsPerBuffer) + fifoSize = (fifoDepth/numberofJobsPerBuffer)+1; else - fifoSize = fifoSize/numberofJobsPerBuffer; + fifoSize = fifoDepth/numberofJobsPerBuffer; //do not rebuild fifo structure if it is the same (oldfifosize differs only for different packetsperframe) if((oldNumberofJobsPerBuffer == numberofJobsPerBuffer) && (oldFifoSize == fifoSize)) @@ -343,7 +342,7 @@ int UDPStandardImplementation::setupFifoStructure(){ //set up fifo structure - for(int i=0;i(fifoSize); fifo[i] = new CircularFifo(fifoSize); @@ -382,7 +385,7 @@ int UDPStandardImplementation::setupFifoStructure(){ buffer[i]=mem0[i]; while (buffer[i] < (mem0[i]+(bufferSize * numberofJobsPerBuffer + fifoBufferHeaderSize) * (fifoSize-1))) { //cprintf(BLUE,"fifofree %d: push 0x%p\n",i,(void*)buffer[i]); - /*for(int k=0;kpop(wbuf); uint32_t numPackets = (uint32_t)(*((uint32_t*)wbuf)); + #ifdef DEBUG4 cprintf(GREEN,"Writing_Thread %d: Number of Packets: %d for FIFO %d\n", ithread, numPackets, dataCompressionEnable?0:ithread); #endif @@ -2880,7 +2884,7 @@ void UDPStandardImplementation::handleCompleteFramesOnly(int ithread, char* wbuf if((fileWriteEnable) && (sfilefd[ithread])){ if(tempframenumber && (tempframenumber%maxFramesPerFile) == 0) createNewFile(ithread); - fwrite(wbuffer + HEADER_SIZE_NUM_TOT_PACKETS, 1, bufferSize + FILE_FRAME_HEADER_LENGTH, sfilefd[ithread]); + fwrite(wbuffer + HEADER_SIZE_NUM_TOT_PACKETS, 1, (bufferSize + FILE_FRAME_HEADER_LENGTH), sfilefd[ithread]); } @@ -3140,6 +3144,7 @@ void UDPStandardImplementation::copyFrameToGui(int ithread, char* buffer, uint32 //copy date guiNumPackets[ithread] = numpackets; strcpy(guiFileName[ithread],completeFileName[ithread]); + if(excludeMissingPackets) //copy also the header memcpy(latestData[ithread],buffer+HEADER_SIZE_NUM_TOT_PACKETS, bufferSize + FILE_FRAME_HEADER_LENGTH); else //copy only the data diff --git a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp index 99948460b..e477c6655 100644 --- a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp +++ b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp @@ -355,8 +355,9 @@ int slsReceiverTCPIPInterface::set_detector_type(){ sprintf(mess,"Receiver locked by %s\n", mySock->lastClientIP); ret=FAIL; } - else if((receiverBase)&&(receiverBase->getStatus()==RUNNING || receiverBase->getStatus()==TRANSMITTING)){ + else if((receiverBase)&&(receiverBase->getStatus()!= IDLE)){ strcpy(mess,"Can not set detector type while receiver not idle\n"); + cprintf(RED,"%s",mess); ret = FAIL; } else{ @@ -447,8 +448,9 @@ int slsReceiverTCPIPInterface::set_file_name() { strcpy(mess,SET_RECEIVER_ERR_MESSAGE); ret=FAIL; } - else if(receiverBase->getStatus()==RUNNING || receiverBase->getStatus()==TRANSMITTING){ + else if(receiverBase->getStatus()!= IDLE){ strcpy(mess,"Can not set file name while receiver not idle\n"); + cprintf(RED,"%s",mess); ret = FAIL; } else{ @@ -519,8 +521,9 @@ int slsReceiverTCPIPInterface::set_file_dir() { strcpy(mess,SET_RECEIVER_ERR_MESSAGE); ret=FAIL; } - else if(receiverBase->getStatus()==RUNNING || receiverBase->getStatus()==TRANSMITTING){ + else if(receiverBase->getStatus()!= IDLE){ strcpy(mess,"Can not set file path while receiver not idle\n"); + cprintf(RED,"%s",mess); ret = FAIL; } else{ @@ -592,8 +595,9 @@ int slsReceiverTCPIPInterface::set_file_index() { strcpy(mess,SET_RECEIVER_ERR_MESSAGE); ret=FAIL; } - else if(receiverBase->getStatus()==RUNNING || receiverBase->getStatus()==TRANSMITTING){ + else if(receiverBase->getStatus()!= IDLE){ strcpy(mess,"Can not set file index while receiver not idle\n"); + cprintf(RED,"%s",mess); ret = FAIL; } else{ @@ -660,8 +664,9 @@ int slsReceiverTCPIPInterface::set_frame_index() { strcpy(mess,SET_RECEIVER_ERR_MESSAGE); ret=FAIL; } - else if(receiverBase->getStatus()==RUNNING || receiverBase->getStatus()==TRANSMITTING){ + else if(receiverBase->getStatus()!= IDLE){ strcpy(mess,"Can not set frame index while receiver not idle\n"); + cprintf(RED,"%s",mess); ret = FAIL; } else{ @@ -741,8 +746,9 @@ int slsReceiverTCPIPInterface::setup_udp(){ strcpy(mess,SET_RECEIVER_ERR_MESSAGE); ret=FAIL; } - else if(receiverBase->getStatus()==RUNNING || receiverBase->getStatus()==TRANSMITTING){ + else if(receiverBase->getStatus()!= IDLE){ strcpy(mess,"Can not set up udp while receiver not idle\n"); + cprintf(RED,"%s",mess); ret = FAIL; } else{ @@ -836,6 +842,7 @@ int slsReceiverTCPIPInterface::start_receiver(){ ret=receiverBase->startReceiver(mess); else{ sprintf(mess,"Cannot start Receiver as it is in %s state\n",runStatusType(s).c_str()); + cprintf(RED,"%s",mess); ret=FAIL; } } @@ -875,7 +882,7 @@ int slsReceiverTCPIPInterface::stop_receiver(){ ret=FAIL; } else{ - if(receiverBase->getStatus()==RUNNING || receiverBase->getStatus()==TRANSMITTING || receiverBase->getStatus()==RUN_FINISHED){ + if(receiverBase->getStatus()!= IDLE){ receiverBase->stopReceiver(); } s = receiverBase->getStatus(); @@ -883,6 +890,7 @@ int slsReceiverTCPIPInterface::stop_receiver(){ ret = OK; else{ sprintf(mess,"Could not stop receiver. It is in %s state\n",runStatusType(s).c_str()); + cprintf(RED,"%s",mess); ret = FAIL; } } @@ -1079,8 +1087,9 @@ int slsReceiverTCPIPInterface::set_short_frame() { strcpy(mess,SET_RECEIVER_ERR_MESSAGE); ret=FAIL; } - else if(receiverBase->getStatus()==RUNNING || receiverBase->getStatus()==TRANSMITTING){ + else if(receiverBase->getStatus()!= IDLE){ strcpy(mess,"Cannot set short frame while status is running\n"); + cprintf(RED,"%s",mess); ret=FAIL; } else{ @@ -2096,7 +2105,7 @@ int slsReceiverTCPIPInterface::set_read_frequency(){ strcpy(mess,SET_RECEIVER_ERR_MESSAGE); ret=FAIL; } - else if(receiverBase->getStatus()==RUNNING || receiverBase->getStatus()==TRANSMITTING){ + else if(receiverBase->getStatus()!= IDLE){ strcpy(mess,"Can not set receiver frequency mode while receiver not idle\n"); cprintf(RED,"%s\n",mess); ret = FAIL; @@ -2166,7 +2175,7 @@ int slsReceiverTCPIPInterface::set_read_receiver_timer(){ strcpy(mess,SET_RECEIVER_ERR_MESSAGE); ret=FAIL; } - else if(receiverBase->getStatus()==RUNNING || receiverBase->getStatus()==TRANSMITTING){ + else if(receiverBase->getStatus()!= IDLE){ strcpy(mess,"Can not set receiver frequency mode while receiver not idle\n"); cprintf(RED,"%s\n",mess); ret = FAIL; @@ -2230,7 +2239,7 @@ int slsReceiverTCPIPInterface::set_data_stream_enable(){ strcpy(mess,SET_RECEIVER_ERR_MESSAGE); ret=FAIL; } - else if((index >= 0) && (receiverBase->getStatus()==RUNNING || receiverBase->getStatus()==TRANSMITTING)){ + else if((index >= 0) && (receiverBase->getStatus()!= IDLE)){ strcpy(mess,"Can not set data stream enable while receiver not idle\n"); cprintf(RED,"%s\n",mess); ret = FAIL; @@ -2294,8 +2303,9 @@ int slsReceiverTCPIPInterface::enable_file_write(){ strcpy(mess,SET_RECEIVER_ERR_MESSAGE); ret=FAIL; } - else if(receiverBase->getStatus()==RUNNING || receiverBase->getStatus()==TRANSMITTING){ + else if(receiverBase->getStatus()!= IDLE){ strcpy(mess,"Can not set file write mode while receiver not idle\n"); + cprintf(RED,"%s",mess); ret = FAIL; } else{ @@ -2370,7 +2380,7 @@ int slsReceiverTCPIPInterface::start_readout(){cprintf(BLUE,"In start readout!\n strcpy(mess,SET_RECEIVER_ERR_MESSAGE); ret=FAIL; } - /*else if(receiverBase->getStatus()==RUNNING || receiverBase->getStatus()==TRANSMITTING){ + /*else if(receiverBase->getStatus()!= IDLE){ strcpy(mess,"Can not start receiver readout while receiver not idle\n"); ret = FAIL; }*/ @@ -2430,8 +2440,9 @@ int slsReceiverTCPIPInterface::set_timer() { strcpy(mess,SET_RECEIVER_ERR_MESSAGE); ret=FAIL; } - else if(receiverBase->getStatus()==RUNNING || receiverBase->getStatus()==TRANSMITTING){ + else if(receiverBase->getStatus()!= IDLE){ strcpy(mess,"Can not set timer while receiver not idle\n"); + cprintf(RED,"%s",mess); ret = FAIL; } else{ @@ -2518,8 +2529,9 @@ int slsReceiverTCPIPInterface::enable_compression() { strcpy(mess,SET_RECEIVER_ERR_MESSAGE); ret=FAIL; } - else if(receiverBase->getStatus()==RUNNING || receiverBase->getStatus()==TRANSMITTING){ + else if(receiverBase->getStatus()!= IDLE){ strcpy(mess,"Cannot enable/disable compression while status is running\n"); + cprintf(RED,"%s",mess); ret=FAIL; } else{ @@ -2587,8 +2599,9 @@ int slsReceiverTCPIPInterface::set_detector_hostname() { strcpy(mess,SET_RECEIVER_ERR_MESSAGE); ret=FAIL; } - else if(receiverBase->getStatus()==RUNNING || receiverBase->getStatus()==TRANSMITTING){ + else if(receiverBase->getStatus()!= IDLE){ strcpy(mess,"Can not set detector hostname while receiver not idle\n"); + cprintf(RED,"%s",mess); ret = FAIL; } else{ @@ -2673,8 +2686,9 @@ int slsReceiverTCPIPInterface::set_dynamic_range() { strcpy(mess,SET_RECEIVER_ERR_MESSAGE); ret=FAIL; } - else if(receiverBase->getStatus()==RUNNING || receiverBase->getStatus()==TRANSMITTING){ + else if(receiverBase->getStatus()!= IDLE){ strcpy(mess,"Can not set dynamic range while receiver not idle\n"); + cprintf(RED,"%s",mess); ret = FAIL; } else{ @@ -2754,8 +2768,9 @@ int slsReceiverTCPIPInterface::enable_overwrite() { strcpy(mess,SET_RECEIVER_ERR_MESSAGE); ret=FAIL; } - else if(receiverBase->getStatus()==RUNNING || receiverBase->getStatus()==TRANSMITTING){ + else if(receiverBase->getStatus()!= IDLE){ strcpy(mess,"Can not set overwrite mode while receiver not idle\n"); + cprintf(RED,"%s",mess); ret = FAIL; } else{ @@ -2821,8 +2836,9 @@ int slsReceiverTCPIPInterface::enable_tengiga() { strcpy(mess,SET_RECEIVER_ERR_MESSAGE); ret=FAIL; } - else if(receiverBase->getStatus()==RUNNING || receiverBase->getStatus()==TRANSMITTING){ + else if(receiverBase->getStatus()!= IDLE){ strcpy(mess,"Can not set up 1Giga/10Giga mode while receiver not idle\n"); + cprintf(RED,"%s",mess); ret = FAIL; } else{ @@ -2890,8 +2906,9 @@ int slsReceiverTCPIPInterface::set_fifo_depth() { strcpy(mess,SET_RECEIVER_ERR_MESSAGE); ret=FAIL; } - else if(receiverBase->getStatus()==RUNNING || receiverBase->getStatus()==TRANSMITTING){ + else if(receiverBase->getStatus()!= IDLE){ strcpy(mess,"Cannot set/get fifo depth while status is running\n"); + cprintf(RED,"%s",mess); ret=FAIL; } else{ @@ -3033,8 +3050,9 @@ int slsReceiverTCPIPInterface::set_flipped_data(){ strcpy(mess,SET_RECEIVER_ERR_MESSAGE); ret=FAIL; } - else if(receiverBase->getStatus()==RUNNING || receiverBase->getStatus()==TRANSMITTING){ + else if(receiverBase->getStatus()!= IDLE){ strcpy(mess,"Can not set flipped data while receiver not idle\n"); + cprintf(RED,"%s",mess); ret = FAIL; } else{ From 3c0ce23bc251410b3431e9eb064f843f0a69fb1f Mon Sep 17 00:00:00 2001 From: Leonardo Sala Date: Fri, 2 Dec 2016 15:21:22 +0000 Subject: [PATCH 458/474] fixed hardcoded port number, cleanup --- .../src/UDPRESTImplementation.cpp | 20 +++---------------- 1 file changed, 3 insertions(+), 17 deletions(-) diff --git a/slsReceiverSoftware/src/UDPRESTImplementation.cpp b/slsReceiverSoftware/src/UDPRESTImplementation.cpp index 1e5498585..df683a946 100644 --- a/slsReceiverSoftware/src/UDPRESTImplementation.cpp +++ b/slsReceiverSoftware/src/UDPRESTImplementation.cpp @@ -73,9 +73,7 @@ string UDPRESTImplementation::get_rest_state(RestHelper * rest/*, string *rest_s int code = rest->get_json("v1/state", &answer); if ( code != -1 ){ - std::cout << answer << std::endl; rest_state = answer["global_state"].getString(); - std::cout << rest_state << std::endl; } //rest_state = *prs; @@ -89,17 +87,15 @@ void UDPRESTImplementation::initialize_REST(){ FILE_LOG(logDEBUG) << __AT__ << " REST status is initialized: " << isInitialized; - std::cout<< fileIndex << " " << getUDPPortNumber() << std::endl; string rest_state = ""; std::string answer = ""; - // HORRIBLE FIX ME ASAP! - if (getUDPPortNumber() == 50011){ + // HORRIBLE FIX to get the main receiver + string filename = getFileName(); + if (filename.substr(filename.length() - 2) == "d0"){ is_main_receiver = true; } - // if (is_main_receiver){ - if (rest_hostname.empty()) { FILE_LOG(logDEBUG) << __AT__ <<"can't initialize with empty string or NULL for detectorHostname"; throw; @@ -124,8 +120,6 @@ void UDPRESTImplementation::initialize_REST(){ try{ rest_state = get_rest_state(rest); - std::cout << "AAAAAAAa " << rest_state << std::endl; - if (rest_state == ""){ FILE_LOG(logERROR) << __AT__ << " REST state returned: " << rest_state; @@ -200,8 +194,6 @@ int UDPRESTImplementation::startReceiver(char message[]){ initialize_REST(); FILE_LOG(logDEBUG) << __FILE__ << "::" << __func__ << " initialized"; - cout << "Starting Receiver" << endl; - std::string answer; int code; //char *intStr = itoa(a); @@ -215,7 +207,6 @@ int UDPRESTImplementation::startReceiver(char message[]){ string str_n = ss2.str(); - cout << "Starting Receiver" << endl; string rest_state = ""; std::string request_body = "{\"settings\": {\"bit_depth\": " + str_dr + ", \"n_frames\": " + str_n + "}}"; //std::string request_body = "{\"settings\": {\"nimages\":1, \"scanid\":999, \"bit_depth\":16}}"; @@ -228,7 +219,6 @@ int UDPRESTImplementation::startReceiver(char message[]){ rest_state = get_rest_state(rest); code = rest->post_json("v1/state/open", &answer); - std::cout << "AAAAAA " << rest_state << std::endl; } status = RUNNING; @@ -309,11 +299,9 @@ int UDPRESTImplementation::shutDownUDPSockets(){ FILE_LOG(logWARNING) << "PLEASE WAIT WHILE CHECKING AND SHUTTING DOWN ALL CONNECTIONS!"; rest_state = get_rest_state(rest); - std::cout << rest_state << std::endl; while (rest_state != "OPEN"){ rest_state = get_rest_state(rest); - std::cout << rest_state << std::endl; usleep(10000); } //while (rest_state != "TRANSIENT"){ @@ -322,9 +310,7 @@ int UDPRESTImplementation::shutDownUDPSockets(){ //} code = rest->post_json("v1/state/close", &answer); - std::cout <post_json("v1/state/reset", &answer); - std::cout << code << " " << answer << std::endl; //rest_state = get_rest_state(rest); //std::cout << rest_state << std::endl; From a1f00518b82921496027aba3762525908b7b623d Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Fri, 10 Feb 2017 11:50:24 +0100 Subject: [PATCH 459/474] updaterev --- slsReceiverSoftware/gitInfo.txt | 10 +++++----- slsReceiverSoftware/include/gitInfoReceiver.h | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/slsReceiverSoftware/gitInfo.txt b/slsReceiverSoftware/gitInfo.txt index 6282454d0..d82f2848d 100644 --- a/slsReceiverSoftware/gitInfo.txt +++ b/slsReceiverSoftware/gitInfo.txt @@ -1,9 +1,9 @@ Path: slsDetectorsPackage/slsReceiverSoftware URL: origin git@git.psi.ch:sls_detectors_software/sls_receiver_software.git Repository Root: origin git@git.psi.ch:sls_detectors_software/sls_receiver_software.git -Repsitory UUID: 2f78f4e118bfba443f84a3f72b2839610a8858a3 -Revision: 493 -Branch: developer +Repsitory UUID: 398e8b241fe37a2102709553b8b0fa3650f97966 +Revision: 499 +Branch: 2.3-rc Last Changed Author: Dhanya_Maliakal -Last Changed Rev: 493 -Last Changed Date: 2016-11-30 10:36:46 +0100 +Last Changed Rev: 499 +Last Changed Date: 2016-12-15 14:32:34 +0100 diff --git a/slsReceiverSoftware/include/gitInfoReceiver.h b/slsReceiverSoftware/include/gitInfoReceiver.h index 66704494f..421bf31c3 100644 --- a/slsReceiverSoftware/include/gitInfoReceiver.h +++ b/slsReceiverSoftware/include/gitInfoReceiver.h @@ -1,11 +1,11 @@ //#define SVNPATH "" #define SVNURL "git@git.psi.ch:sls_detectors_software/sls_receiver_software.git" //#define SVNREPPATH "" -#define SVNREPUUID "2f78f4e118bfba443f84a3f72b2839610a8858a3" -//#define SVNREV 0x493 +#define SVNREPUUID "398e8b241fe37a2102709553b8b0fa3650f97966" +//#define SVNREV 0x499 //#define SVNKIND "" //#define SVNSCHED "" #define SVNAUTH "Dhanya_Maliakal" -#define SVNREV 0x493 -#define SVNDATE 0x20161130 +#define SVNREV 0x499 +#define SVNDATE 0x20161215 // From 53be854efdc328ef30f6ece3482abdf8b2488aa4 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Mon, 13 Mar 2017 11:33:06 +0100 Subject: [PATCH 460/474] including subframe number --- .../include/UDPBaseImplementation.h | 32 +++++++------ slsReceiverSoftware/include/UDPInterface.h | 12 +++-- slsReceiverSoftware/include/receiver_defs.h | 6 ++- slsReceiverSoftware/include/slsReceiver.h | 41 ++++++++++------ .../include/slsReceiverTCPIPInterface.h | 32 +++++++------ .../include/slsReceiverUsers.h | 16 ++----- .../src/UDPBaseImplementation.cpp | 6 +-- .../src/UDPStandardImplementation.cpp | 48 ++++++++++++++----- slsReceiverSoftware/src/slsReceiver.cpp | 6 +-- .../src/slsReceiverTCPIPInterface.cpp | 6 +-- slsReceiverSoftware/src/slsReceiverUsers.cpp | 6 +-- 11 files changed, 126 insertions(+), 85 deletions(-) diff --git a/slsReceiverSoftware/include/UDPBaseImplementation.h b/slsReceiverSoftware/include/UDPBaseImplementation.h index ce8a3ddb7..728f39d6c 100644 --- a/slsReceiverSoftware/include/UDPBaseImplementation.h +++ b/slsReceiverSoftware/include/UDPBaseImplementation.h @@ -486,30 +486,32 @@ class UDPBaseImplementation : protected virtual slsReceiverDefs, public UDPInter * fileindex * datasize * - * return value is the action which decides what the user and default responsibilities to save data are + * return value is * 0 callback takes care of open,close,wrie file * 1 callback writes file, we have to open, close it * 2 we open, close, write file, callback does not do anything */ - void registerCallBackStartAcquisition(int (*func)(char*, char*,int, int, void*),void *arg); + void registerCallBackStartAcquisition(int (*func)(char*, char*, uint64_t, uint32_t, void*),void *arg); /** * Call back for acquisition finished * callback argument is * total frames caught */ - void registerCallBackAcquisitionFinished(void (*func)(int, void*),void *arg); + void registerCallBackAcquisitionFinished(void (*func)(uint64_t, void*),void *arg); /** * Call back for raw data * args to raw data ready callback are - * framenum + * index + * frame number + * timestamp/ bunch id + * exposure length/ sub frame number * datapointer * datasize in bytes * file descriptor - * guidatapointer (NULL, no data required) */ - void registerCallBackRawDataReady(void (*func)(int, char*, int, FILE*, char*, void*),void *arg); + void registerCallBackRawDataReady(void (*func)(int, uint64_t, uint64_t, uint64_t, char*, uint32_t, FILE*, void*),void *arg); @@ -599,7 +601,7 @@ class UDPBaseImplementation : protected virtual slsReceiverDefs, public UDPInter //***callback parameters*** /** - * function being called back for start acquisition + * Call back for start acquisition * callback arguments are * filepath * filename @@ -611,28 +613,30 @@ class UDPBaseImplementation : protected virtual slsReceiverDefs, public UDPInter * 1 callback writes file, we have to open, close it * 2 we open, close, write file, callback does not do anything */ - int (*startAcquisitionCallBack)(char*, char*,int, int, void*); + int (*startAcquisitionCallBack)(char*, char*, uint64_t, uint32_t, void*); void *pStartAcquisition; /** - * function being called back for acquisition finished + * Call back for acquisition finished * callback argument is * total frames caught */ - void (*acquisitionFinishedCallBack)(int, void*); + void (*acquisitionFinishedCallBack)(uint64_t, void*); void *pAcquisitionFinished; /** - * function being called back for raw data + * Call back for raw data * args to raw data ready callback are - * framenum + * index + * frame number + * timestamp/ bunch id + * exposure length/ sub frame number * datapointer * datasize in bytes * file descriptor - * guidatapointer (NULL, no data required) */ - void (*rawDataReadyCallBack)(int, char*, int, FILE*, char*, void*); + void (*rawDataReadyCallBack)(int, uint64_t, uint64_t, uint64_t, char*, uint32_t, FILE*, void*); void *pRawDataReady; diff --git a/slsReceiverSoftware/include/UDPInterface.h b/slsReceiverSoftware/include/UDPInterface.h index 8bdc1a87e..3c42dbfd1 100644 --- a/slsReceiverSoftware/include/UDPInterface.h +++ b/slsReceiverSoftware/include/UDPInterface.h @@ -548,25 +548,27 @@ class UDPInterface { * 1 callback writes file, we have to open, close it * 2 we open, close, write file, callback does not do anything */ - virtual void registerCallBackStartAcquisition(int (*func)(char*, char*,int, int, void*),void *arg) = 0; + virtual void registerCallBackStartAcquisition(int (*func)(char*, char*, uint64_t, uint32_t, void*),void *arg) = 0; /** * Call back for acquisition finished * callback argument is * total frames caught */ - virtual void registerCallBackAcquisitionFinished(void (*func)(int, void*),void *arg) = 0; + virtual void registerCallBackAcquisitionFinished(void (*func)(uint64_t, void*),void *arg) = 0; /** * Call back for raw data * args to raw data ready callback are - * framenum + * index + * frame number + * timestamp/ bunch id + * exposure length/ sub frame number * datapointer * datasize in bytes * file descriptor - * guidatapointer (NULL, no data required) */ - virtual void registerCallBackRawDataReady(void (*func)(int, char*, int, FILE*, char*, void*),void *arg) = 0; + virtual void registerCallBackRawDataReady(void (*func)(int, uint64_t, uint64_t, uint64_t, char*, uint32_t, FILE*, void*),void *arg) = 0; protected: diff --git a/slsReceiverSoftware/include/receiver_defs.h b/slsReceiverSoftware/include/receiver_defs.h index ec848bf4f..6f4b8fb83 100755 --- a/slsReceiverSoftware/include/receiver_defs.h +++ b/slsReceiverSoftware/include/receiver_defs.h @@ -58,8 +58,10 @@ typedef struct { #define HEADER_SIZE_NUM_PACKETS 1 #define ALL_MASK_32 0xFFFFFFFF -#define FILE_FRAME_HEADER_LENGTH 16 -#define FILE_HEADER_BUNCHID_OFFSET 8 +#define FILE_FRAME_HEADER_LENGTH (8*3) +#define FILE_HEADER_TIMESTAMP_OFFSET 8 //start of frame/ bunch id +#define FILE_HEADER_EXPLENGTH_OFFSET 16 //exposure length/ sub frame number + //all max frames defined in sls_receiver_defs.h. 20000 gotthard, 100000 for short gotthard, 1000 for moench, eiger 20000 diff --git a/slsReceiverSoftware/include/slsReceiver.h b/slsReceiverSoftware/include/slsReceiver.h index e76ea7d1b..5a2118cab 100644 --- a/slsReceiverSoftware/include/slsReceiver.h +++ b/slsReceiverSoftware/include/slsReceiver.h @@ -58,28 +58,39 @@ class slsReceiver : private virtual slsReceiverDefs { int64_t getReceiverVersion(); /** - @sort register calbback for starting the acquisition - @param func callback to be called when starting the acquisition. Its arguments are filepath filename fileindex data size - \returns 0 callback takes care of open,close,write file; 1 callback writes file, we have to open, close it; 2 we open, close, write file, callback does not do anything + * Call back for start acquisition + * callback arguments are + * filepath + * filename + * fileindex + * datasize + * + * return value is + * 0 callback takes care of open,close,wrie file + * 1 callback writes file, we have to open, close it + * 2 we open, close, write file, callback does not do anything */ - void registerCallBackStartAcquisition(int (*func)(char*, char*,int, int, void*),void *arg); - + void registerCallBackStartAcquisition(int (*func)(char*, char*, uint64_t, uint32_t, void*),void *arg); /** - callback argument is - toatal farmes caught + * Call back for acquisition finished + * callback argument is + * total frames caught */ - void registerCallBackAcquisitionFinished(void (*func)(int, void*),void *arg); + void registerCallBackAcquisitionFinished(void (*func)(uint64_t, void*),void *arg); /** - args to raw data ready callback are - framenum - datapointer - datasize in bytes - file descriptor - guidatapointer (NULL, no data required) + * Call back for raw data + * args to raw data ready callback are + * index + * frame number + * timestamp/ bunch id + * exposure length/ sub frame number + * datapointer + * datasize in bytes + * file descriptor */ - void registerCallBackRawDataReady(void (*func)(int, char*, int, FILE*, char*, void*),void *arg); + void registerCallBackRawDataReady(void (*func)(int, uint64_t, uint64_t, uint64_t, char*, uint32_t, FILE*, void*),void *arg); private: diff --git a/slsReceiverSoftware/include/slsReceiverTCPIPInterface.h b/slsReceiverSoftware/include/slsReceiverTCPIPInterface.h index f0bf66f03..c967d4335 100644 --- a/slsReceiverSoftware/include/slsReceiverTCPIPInterface.h +++ b/slsReceiverSoftware/include/slsReceiverTCPIPInterface.h @@ -65,30 +65,32 @@ class slsReceiverTCPIPInterface : private virtual slsReceiverDefs { * fileindex * datasize * - * return value is the action which decides what the user and default responsibilities to save data are + * return value is * 0 callback takes care of open,close,wrie file * 1 callback writes file, we have to open, close it * 2 we open, close, write file, callback does not do anything */ - void registerCallBackStartAcquisition(int (*func)(char*, char*,int, int, void*),void *arg); + void registerCallBackStartAcquisition(int (*func)(char*, char*, uint64_t, uint32_t, void*),void *arg); /** * Call back for acquisition finished * callback argument is * total frames caught */ - void registerCallBackAcquisitionFinished(void (*func)(int, void*),void *arg); + void registerCallBackAcquisitionFinished(void (*func)(uint64_t, void*),void *arg); /** * Call back for raw data * args to raw data ready callback are - * framenum + * index + * frame number + * timestamp/ bunch id + * exposure length/ sub frame number * datapointer * datasize in bytes * file descriptor - * guidatapointer (NULL, no data required) */ - void registerCallBackRawDataReady(void (*func)(int, char*, int, FILE*, char*, void*),void *arg); + void registerCallBackRawDataReady(void (*func)(int, uint64_t, uint64_t, uint64_t, char*, uint32_t, FILE*, void*),void *arg); private: @@ -292,7 +294,7 @@ private: //***callback parameters*** /** - * function being called back for start acquisition + * Call back for start acquisition * callback arguments are * filepath * filename @@ -304,28 +306,30 @@ private: * 1 callback writes file, we have to open, close it * 2 we open, close, write file, callback does not do anything */ - int (*startAcquisitionCallBack)(char*, char*,int, int, void*); + int (*startAcquisitionCallBack)(char*, char*, uint64_t, uint32_t, void*); void *pStartAcquisition; /** - * function being called back for acquisition finished + * Call back for acquisition finished * callback argument is * total frames caught */ - void (*acquisitionFinishedCallBack)(int, void*); + void (*acquisitionFinishedCallBack)(uint64_t, void*); void *pAcquisitionFinished; /** - * function being called back for raw data + * Call back for raw data * args to raw data ready callback are - * framenum + * index + * frame number + * timestamp/ bunch id + * exposure length/ sub frame number * datapointer * datasize in bytes * file descriptor - * guidatapointer (NULL, no data required) */ - void (*rawDataReadyCallBack)(int, char*, int, FILE*, char*, void*); + void (*rawDataReadyCallBack)(int, uint64_t, uint64_t, uint64_t, char*, uint32_t, FILE*, void*); void *pRawDataReady; diff --git a/slsReceiverSoftware/include/slsReceiverUsers.h b/slsReceiverSoftware/include/slsReceiverUsers.h index eea403560..45e6d62e0 100644 --- a/slsReceiverSoftware/include/slsReceiverUsers.h +++ b/slsReceiverSoftware/include/slsReceiverUsers.h @@ -55,13 +55,10 @@ public: /** @sort register calbback for starting the acquisition - \param func callback to be called when starting the acquisition. Its arguments are filepath filename fileindex data size - + \param func callback to be called when starting the acquisition. Its arguments are filepath, filename, fileindex, datasize \returns 0 callback takes care of open,close,write file; 1 callback writes file, we have to open, close it; 2 we open, close, write file, callback does not do anything - */ - - void registerCallBackStartAcquisition(int (*func)(char* filepath, char* filename,int fileindex, int datasize, void*),void *arg); + void registerCallBackStartAcquisition(int (*func)(char* filepath, char* filename, uint64_t fileindex, uint32_t datasize, void*),void *arg); /** @@ -69,20 +66,17 @@ public: \param func end of acquisition callback. Argument nf is total frames caught \returns nothing */ - - - void registerCallBackAcquisitionFinished(void (*func)(int nf, void*),void *arg); + void registerCallBackAcquisitionFinished(void (*func)(uint64_t nf, void*),void *arg); /** @sort register callback to be called when data are available (to process and/or save the data). - \param func raw data ready callback. arguments are framenum datapointer datasize file descriptor guidatapointer (NULL, no data required) + \param func raw data ready callback. arguments are index, frame number, timestamp/ bunch id, exposure length/ sub frame number, datapointer, datasize in bytes, file descriptor \returns nothing */ + void registerCallBackRawDataReady(void (*func)(int index, uint64_t framenumber, uint64_t timestamp, uint64_t explength, char* datapointer, uint32_t datasize, FILE* filedescriptor, void*),void *arg); - void registerCallBackRawDataReady(void (*func)(int framenumber, char* datapointer, int datasize, FILE* filedescriptor, char* guidatapointer, void*),void *arg); - //receiver object slsReceiver* receiver; }; diff --git a/slsReceiverSoftware/src/UDPBaseImplementation.cpp b/slsReceiverSoftware/src/UDPBaseImplementation.cpp index e0bf65f6d..b2a5f69b0 100644 --- a/slsReceiverSoftware/src/UDPBaseImplementation.cpp +++ b/slsReceiverSoftware/src/UDPBaseImplementation.cpp @@ -507,17 +507,17 @@ int UDPBaseImplementation::setActivate(int enable){ } /***callback functions***/ -void UDPBaseImplementation::registerCallBackStartAcquisition(int (*func)(char*, char*,int, int, void*),void *arg){ +void UDPBaseImplementation::registerCallBackStartAcquisition(int (*func)(char*, char*, uint64_t, uint32_t, void*),void *arg){ startAcquisitionCallBack=func; pStartAcquisition=arg; } -void UDPBaseImplementation::registerCallBackAcquisitionFinished(void (*func)(int, void*),void *arg){ +void UDPBaseImplementation::registerCallBackAcquisitionFinished(void (*func)(uint64_t, void*),void *arg){ acquisitionFinishedCallBack=func; pAcquisitionFinished=arg; } -void UDPBaseImplementation::registerCallBackRawDataReady(void (*func)(int, char*, int, FILE*, char*, void*),void *arg){ +void UDPBaseImplementation::registerCallBackRawDataReady(void (*func)(int, uint64_t, uint64_t, uint64_t, char*, uint32_t, FILE*, void*),void *arg){ rawDataReadyCallBack=func; pRawDataReady=arg; } diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 79d8e0520..2672a3fbd 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1527,7 +1527,7 @@ int UDPStandardImplementation::setupWriter(){ //acquisition start call back returns enable write cbAction = DO_EVERYTHING; if (startAcquisitionCallBack) - cbAction=startAcquisitionCallBack(filePath,fileNamePerThread[0],(int)fileIndex,bufferSize,pStartAcquisition); + cbAction=startAcquisitionCallBack(filePath,fileNamePerThread[0],fileIndex, (uint32_t)bufferSize,pStartAcquisition); if(cbAction < DO_EVERYTHING){ @@ -2175,6 +2175,7 @@ int UDPStandardImplementation::prepareAndListenBufferCompleteFrames(int ithread) uint32_t pnum = 0; uint64_t fnum = 0; uint64_t bnum = 0; + uint64_t snum = 0; int rc = 0; //from getframeandpacketnumber() uint32_t pi = 0; @@ -2193,7 +2194,8 @@ int UDPStandardImplementation::prepareAndListenBufferCompleteFrames(int ithread) } else fnum = fi; //fnum of first packet - bnum = bi; //bnum of first packet + bnum = bi; //bnum of first packet + snum = si; //snum of first packet totalListeningPacketCount[ithread]++; #ifdef VERBOSE if(!ithread) cout << "1 pnum:" << pnum << endl; @@ -2283,6 +2285,7 @@ int UDPStandardImplementation::prepareAndListenBufferCompleteFrames(int ithread) if(fi!=ALL_MASK_32) fnum = fi; //fnum of first packet bnum = bi; //bnum of first packet + snum = si; //snum of first packet } } //------------------------------------------------------ got a complete frame -------------------------------------------------------- @@ -2292,8 +2295,21 @@ int UDPStandardImplementation::prepareAndListenBufferCompleteFrames(int ithread) #ifdef VERBOSE if(!ithread) cout << "fnum:" << (*((uint64_t*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS))) << endl; #endif - if(myDetectorType == JUNGFRAU) - (*((uint64_t*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS + FILE_HEADER_BUNCHID_OFFSET))) = bnum; + switch (myDetectorType) { + case JUNGFRAU: + (*((uint64_t*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS + FILE_HEADER_TIMESTAMP_OFFSET))) = bnum; + (*((uint64_t*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS + FILE_HEADER_EXPLENGTH_OFFSET))) = 0; + break; + case EIGER: + (*((uint64_t*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS + FILE_HEADER_TIMESTAMP_OFFSET))) = 0; + (*((uint64_t*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS + FILE_HEADER_EXPLENGTH_OFFSET))) = snum; + break; + default: + (*((uint64_t*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS + FILE_HEADER_TIMESTAMP_OFFSET))) = 0; + (*((uint64_t*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS + FILE_HEADER_EXPLENGTH_OFFSET))) = 0; + break; + } + //write packet count to buffer *((uint32_t*)(buffer[ithread])) = packetsPerFrame; return bufferSize; @@ -2802,7 +2818,7 @@ void UDPStandardImplementation::stopWriting(int ithread, char* wbuffer){ cprintf(RED,"Note: Deactivated Receiver\n"); //acquisition end if (acquisitionFinishedCallBack) - acquisitionFinishedCallBack((int)totalPacketsCaught, pAcquisitionFinished); + acquisitionFinishedCallBack(totalPacketsCaught, pAcquisitionFinished); } } @@ -2827,8 +2843,12 @@ void UDPStandardImplementation::handleWithoutDataCompression(int ithread, char* //callback to write data if (cbAction < DO_EVERYTHING) - rawDataReadyCallBack((int)tempframenumber, wbuffer + fifoBufferHeaderSize, npackets * onePacketSize, - sfilefd[ithread], latestData[ithread],pRawDataReady);//know which thread from sfilefd + rawDataReadyCallBack(detID*numberofListeningThreads+ithread, tempframenumber, + 0,0, + wbuffer + fifoBufferHeaderSize, + bufferSize * numberofJobsPerBuffer + fifoBufferHeaderSize, + sfilefd[ithread], pRawDataReady);//know which thread from sfilefd + //write to file if enabled and update write parameters @@ -2870,14 +2890,17 @@ void UDPStandardImplementation::handleCompleteFramesOnly(int ithread, char* wbuf FILE_LOG(logDEBUG) << __AT__ << " called"; //get current frame number - uint64_t tempframenumber; - tempframenumber = (*((uint64_t*)(wbuffer+HEADER_SIZE_NUM_TOT_PACKETS))); - tempframenumber -= startFrameIndex; + uint64_t tempframenumber = (*((uint64_t*)(wbuffer + HEADER_SIZE_NUM_TOT_PACKETS))); + uint64_t bnum = (*((uint64_t*)(wbuffer + HEADER_SIZE_NUM_TOT_PACKETS + FILE_HEADER_TIMESTAMP_OFFSET))); + uint64_t snum = (*((uint64_t*)(wbuffer + HEADER_SIZE_NUM_TOT_PACKETS + FILE_HEADER_EXPLENGTH_OFFSET))); if (cbAction < DO_EVERYTHING) - rawDataReadyCallBack((int)tempframenumber, wbuffer + HEADER_SIZE_NUM_TOT_PACKETS, bufferSize + FILE_FRAME_HEADER_LENGTH, - sfilefd[ithread], latestData[ithread],pRawDataReady); + rawDataReadyCallBack(detID*numberofListeningThreads+ithread, tempframenumber, + bnum, snum, + wbuffer + fifoBufferHeaderSize, + bufferSize * numberofJobsPerBuffer + fifoBufferHeaderSize, + sfilefd[ithread], pRawDataReady); //write to file if enabled and update write parameters @@ -2887,6 +2910,7 @@ void UDPStandardImplementation::handleCompleteFramesOnly(int ithread, char* wbuf fwrite(wbuffer + HEADER_SIZE_NUM_TOT_PACKETS, 1, (bufferSize + FILE_FRAME_HEADER_LENGTH), sfilefd[ithread]); } + tempframenumber -= startFrameIndex; //progress if(tempframenumber && (tempframenumber%(maxFramesPerFile/progressFrequency)) == 0){ diff --git a/slsReceiverSoftware/src/slsReceiver.cpp b/slsReceiverSoftware/src/slsReceiver.cpp index 04bc29563..85750c517 100644 --- a/slsReceiverSoftware/src/slsReceiver.cpp +++ b/slsReceiverSoftware/src/slsReceiver.cpp @@ -160,7 +160,7 @@ int64_t slsReceiver::getReceiverVersion(){ } -void slsReceiver::registerCallBackStartAcquisition(int (*func)(char*, char*,int, int, void*),void *arg){ +void slsReceiver::registerCallBackStartAcquisition(int (*func)(char*, char*, uint64_t, uint32_t, void*),void *arg){ //tcpipInterface if(udp_interface) udp_interface->registerCallBackStartAcquisition(func,arg); @@ -170,7 +170,7 @@ void slsReceiver::registerCallBackStartAcquisition(int (*func)(char*, char*,int, -void slsReceiver::registerCallBackAcquisitionFinished(void (*func)(int, void*),void *arg){ +void slsReceiver::registerCallBackAcquisitionFinished(void (*func)(uint64_t, void*),void *arg){ //tcpipInterface if(udp_interface) udp_interface->registerCallBackAcquisitionFinished(func,arg); @@ -179,7 +179,7 @@ void slsReceiver::registerCallBackAcquisitionFinished(void (*func)(int, void*),v } -void slsReceiver::registerCallBackRawDataReady(void (*func)(int, char*, int, FILE*, char*, void*),void *arg){ +void slsReceiver::registerCallBackRawDataReady(void (*func)(int, uint64_t, uint64_t, uint64_t, char*, uint32_t, FILE*, void*),void *arg){ //tcpipInterface if(udp_interface) udp_interface->registerCallBackRawDataReady(func,arg); diff --git a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp index e477c6655..304476e56 100644 --- a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp +++ b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp @@ -3393,17 +3393,17 @@ int slsReceiverTCPIPInterface::exec_command() { /***callback functions***/ -void slsReceiverTCPIPInterface::registerCallBackStartAcquisition(int (*func)(char*, char*,int, int, void*),void *arg){ +void slsReceiverTCPIPInterface::registerCallBackStartAcquisition(int (*func)(char*, char*, uint64_t, uint32_t, void*),void *arg){ startAcquisitionCallBack=func; pStartAcquisition=arg; } -void slsReceiverTCPIPInterface::registerCallBackAcquisitionFinished(void (*func)(int, void*),void *arg){ +void slsReceiverTCPIPInterface::registerCallBackAcquisitionFinished(void (*func)(uint64_t, void*),void *arg){ acquisitionFinishedCallBack=func; pAcquisitionFinished=arg; } -void slsReceiverTCPIPInterface::registerCallBackRawDataReady(void (*func)(int, char*, int, FILE*, char*, void*),void *arg){ +void slsReceiverTCPIPInterface::registerCallBackRawDataReady(void (*func)(int, uint64_t, uint64_t, uint64_t, char*, uint32_t, FILE*, void*),void *arg){ rawDataReadyCallBack=func; pRawDataReady=arg; } diff --git a/slsReceiverSoftware/src/slsReceiverUsers.cpp b/slsReceiverSoftware/src/slsReceiverUsers.cpp index 8a1d17f43..384ce86ea 100644 --- a/slsReceiverSoftware/src/slsReceiverUsers.cpp +++ b/slsReceiverSoftware/src/slsReceiverUsers.cpp @@ -27,18 +27,18 @@ int64_t slsReceiverUsers::getReceiverVersion(){ } -void slsReceiverUsers::registerCallBackStartAcquisition(int (*func)(char*, char*,int, int, void*),void *arg){ +void slsReceiverUsers::registerCallBackStartAcquisition(int (*func)(char*, char*, uint64_t, uint32_t, void*),void *arg){ receiver->registerCallBackStartAcquisition(func,arg); } -void slsReceiverUsers::registerCallBackAcquisitionFinished(void (*func)(int, void*),void *arg){ +void slsReceiverUsers::registerCallBackAcquisitionFinished(void (*func)(uint64_t, void*),void *arg){ receiver->registerCallBackAcquisitionFinished(func,arg); } -void slsReceiverUsers::registerCallBackRawDataReady(void (*func)(int, char*, int, FILE*, char*, void*),void *arg){ +void slsReceiverUsers::registerCallBackRawDataReady(void (*func)(int, uint64_t, uint64_t, uint64_t, char*, uint32_t, FILE*, void*), void *arg){ receiver->registerCallBackRawDataReady(func,arg); } From 36e92c194de0b6f6a75e44c2423222462b7adb2f Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 14 Mar 2017 08:23:47 +0100 Subject: [PATCH 461/474] changes for callback to work --- .../src/UDPStandardImplementation.cpp | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 2672a3fbd..09b86ac2e 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1526,9 +1526,15 @@ int UDPStandardImplementation::setupWriter(){ //acquisition start call back returns enable write cbAction = DO_EVERYTHING; - if (startAcquisitionCallBack) - cbAction=startAcquisitionCallBack(filePath,fileNamePerThread[0],fileIndex, (uint32_t)bufferSize,pStartAcquisition); - + if (startAcquisitionCallBack) { + //remove detector index in the file name + int deti = -1; + string tempname(fileName); + size_t uscore=tempname.rfind("_"); + if ((uscore!=string::npos) && (sscanf(tempname.substr(uscore+1,tempname.size()-uscore-1).c_str(),"d%d",&deti))) + tempname=tempname.substr(0,uscore); + cbAction=startAcquisitionCallBack(filePath, (char*)tempname.c_str(),fileIndex, (uint32_t)bufferSize,pStartAcquisition); + } if(cbAction < DO_EVERYTHING){ FILE_LOG(logINFO) << "Call back activated. Data saving must be taken care of by user in call back."; @@ -2302,7 +2308,10 @@ int UDPStandardImplementation::prepareAndListenBufferCompleteFrames(int ithread) break; case EIGER: (*((uint64_t*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS + FILE_HEADER_TIMESTAMP_OFFSET))) = 0; - (*((uint64_t*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS + FILE_HEADER_EXPLENGTH_OFFSET))) = snum; + if (dynamicRange == 32) + (*((uint64_t*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS + FILE_HEADER_EXPLENGTH_OFFSET))) = snum; + else + (*((uint64_t*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS + FILE_HEADER_EXPLENGTH_OFFSET))) = 0; break; default: (*((uint64_t*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS + FILE_HEADER_TIMESTAMP_OFFSET))) = 0; @@ -2818,7 +2827,7 @@ void UDPStandardImplementation::stopWriting(int ithread, char* wbuffer){ cprintf(RED,"Note: Deactivated Receiver\n"); //acquisition end if (acquisitionFinishedCallBack) - acquisitionFinishedCallBack(totalPacketsCaught, pAcquisitionFinished); + acquisitionFinishedCallBack((totalPacketsCaught/(packetsPerFrame*numberofListeningThreads)), pAcquisitionFinished); } } From 9f68fc6f3b26be3b4bad659b40b9d4453291de7c Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Wed, 15 Mar 2017 15:00:25 +0100 Subject: [PATCH 462/474] fixed call backs with new standard header --- .../include/UDPBaseImplementation.h | 53 +++++++---- slsReceiverSoftware/include/UDPInterface.h | 26 ++++-- slsReceiverSoftware/include/receiver_defs.h | 7 +- slsReceiverSoftware/include/slsReceiver.h | 27 ++++-- .../include/slsReceiverTCPIPInterface.h | 52 +++++++---- .../include/slsReceiverUsers.h | 10 +- .../include/sls_receiver_defs.h | 34 +++++++ .../src/UDPBaseImplementation.cpp | 3 +- .../src/UDPStandardImplementation.cpp | 93 +++++++++++-------- slsReceiverSoftware/src/slsReceiver.cpp | 3 +- .../src/slsReceiverTCPIPInterface.cpp | 3 +- slsReceiverSoftware/src/slsReceiverUsers.cpp | 9 +- 12 files changed, 219 insertions(+), 101 deletions(-) diff --git a/slsReceiverSoftware/include/UDPBaseImplementation.h b/slsReceiverSoftware/include/UDPBaseImplementation.h index 728f39d6c..0519d1a56 100644 --- a/slsReceiverSoftware/include/UDPBaseImplementation.h +++ b/slsReceiverSoftware/include/UDPBaseImplementation.h @@ -503,15 +503,25 @@ class UDPBaseImplementation : protected virtual slsReceiverDefs, public UDPInter /** * Call back for raw data * args to raw data ready callback are - * index - * frame number - * timestamp/ bunch id - * exposure length/ sub frame number - * datapointer - * datasize in bytes - * file descriptor + * frameNumber is the frame number + * expLength is the subframe number (32 bit eiger) or real time exposure time in 100ns (others) + * packetNumber is the packet number + * bunchId is the bunch id from beamline + * timestamp is the time stamp with 10 MHz clock + * modId is the unique module id (unique even for left, right, top, bottom) + * xCoord is the x coordinate in the complete detector system + * yCoord is the y coordinate in the complete detector system + * zCoord is the z coordinate in the complete detector system + * debug is for debugging purposes + * roundRNumber is the round robin set number + * detType is the detector type see :: detectorType + * version is the version number of this structure format + * dataPointer is the pointer to the data + * dataSize in bytes is the size of the data in bytes + * fileDescriptor is the file descriptor */ - void registerCallBackRawDataReady(void (*func)(int, uint64_t, uint64_t, uint64_t, char*, uint32_t, FILE*, void*),void *arg); + void registerCallBackRawDataReady(void (*func)(uint64_t, uint32_t, uint32_t, uint64_t, uint64_t, uint16_t, uint16_t, uint16_t, uint16_t, uint32_t, uint16_t, uint8_t, uint8_t, + char*, uint32_t, FILE*, void*),void *arg); @@ -628,18 +638,29 @@ class UDPBaseImplementation : protected virtual slsReceiverDefs, public UDPInter /** * Call back for raw data * args to raw data ready callback are - * index - * frame number - * timestamp/ bunch id - * exposure length/ sub frame number - * datapointer - * datasize in bytes - * file descriptor + * frameNumber is the frame number + * expLength is the subframe number (32 bit eiger) or real time exposure time in 100ns (others) + * packetNumber is the packet number + * bunchId is the bunch id from beamline + * timestamp is the time stamp with 10 MHz clock + * modId is the unique module id (unique even for left, right, top, bottom) + * xCoord is the x coordinate in the complete detector system + * yCoord is the y coordinate in the complete detector system + * zCoord is the z coordinate in the complete detector system + * debug is for debugging purposes + * roundRNumber is the round robin set number + * detType is the detector type see :: detectorType + * version is the version number of this structure format + * dataPointer is the pointer to the data + * dataSize in bytes is the size of the data in bytes + * fileDescriptor is the file descriptor */ - void (*rawDataReadyCallBack)(int, uint64_t, uint64_t, uint64_t, char*, uint32_t, FILE*, void*); + void (*rawDataReadyCallBack)(uint64_t, uint32_t, uint32_t, uint64_t, uint64_t, uint16_t, uint16_t, uint16_t, uint16_t, uint32_t, uint16_t, uint8_t, uint8_t, + char*, uint32_t, FILE*, void*); void *pRawDataReady; + private: }; diff --git a/slsReceiverSoftware/include/UDPInterface.h b/slsReceiverSoftware/include/UDPInterface.h index 3c42dbfd1..de497a0b6 100644 --- a/slsReceiverSoftware/include/UDPInterface.h +++ b/slsReceiverSoftware/include/UDPInterface.h @@ -560,15 +560,25 @@ class UDPInterface { /** * Call back for raw data * args to raw data ready callback are - * index - * frame number - * timestamp/ bunch id - * exposure length/ sub frame number - * datapointer - * datasize in bytes - * file descriptor + * frameNumber is the frame number + * expLength is the subframe number (32 bit eiger) or real time exposure time in 100ns (others) + * packetNumber is the packet number + * bunchId is the bunch id from beamline + * timestamp is the time stamp with 10 MHz clock + * modId is the unique module id (unique even for left, right, top, bottom) + * xCoord is the x coordinate in the complete detector system + * yCoord is the y coordinate in the complete detector system + * zCoord is the z coordinate in the complete detector system + * debug is for debugging purposes + * roundRNumber is the round robin set number + * detType is the detector type see :: detectorType + * version is the version number of this structure format + * dataPointer is the pointer to the data + * dataSize in bytes is the size of the data in bytes + * fileDescriptor is the file descriptor */ - virtual void registerCallBackRawDataReady(void (*func)(int, uint64_t, uint64_t, uint64_t, char*, uint32_t, FILE*, void*),void *arg) = 0; + virtual void registerCallBackRawDataReady(void (*func)(uint64_t, uint32_t, uint32_t, uint64_t, uint64_t, uint16_t, uint16_t, uint16_t, uint16_t, uint32_t, uint16_t, uint8_t, uint8_t, + char*, uint32_t, FILE*, void*),void *arg) = 0; protected: diff --git a/slsReceiverSoftware/include/receiver_defs.h b/slsReceiverSoftware/include/receiver_defs.h index 6f4b8fb83..6301f879a 100755 --- a/slsReceiverSoftware/include/receiver_defs.h +++ b/slsReceiverSoftware/include/receiver_defs.h @@ -58,9 +58,10 @@ typedef struct { #define HEADER_SIZE_NUM_PACKETS 1 #define ALL_MASK_32 0xFFFFFFFF -#define FILE_FRAME_HEADER_LENGTH (8*3) -#define FILE_HEADER_TIMESTAMP_OFFSET 8 //start of frame/ bunch id -#define FILE_HEADER_EXPLENGTH_OFFSET 16 //exposure length/ sub frame number +#define SLS_DETECTOR_HEADER_VERSION 0x1 +//#define FILE_FRAME_HEADER_LENGTH (8*3) +//#define FILE_HEADER_TIMESTAMP_OFFSET 8 //start of frame/ bunch id +//#define FILE_HEADER_EXPLENGTH_OFFSET 16 //exposure length/ sub frame number diff --git a/slsReceiverSoftware/include/slsReceiver.h b/slsReceiverSoftware/include/slsReceiver.h index 5a2118cab..35feec9f4 100644 --- a/slsReceiverSoftware/include/slsReceiver.h +++ b/slsReceiverSoftware/include/slsReceiver.h @@ -82,15 +82,26 @@ class slsReceiver : private virtual slsReceiverDefs { /** * Call back for raw data * args to raw data ready callback are - * index - * frame number - * timestamp/ bunch id - * exposure length/ sub frame number - * datapointer - * datasize in bytes - * file descriptor + * frameNumber is the frame number + * expLength is the subframe number (32 bit eiger) or real time exposure time in 100ns (others) + * packetNumber is the packet number + * bunchId is the bunch id from beamline + * timestamp is the time stamp with 10 MHz clock + * modId is the unique module id (unique even for left, right, top, bottom) + * xCoord is the x coordinate in the complete detector system + * yCoord is the y coordinate in the complete detector system + * zCoord is the z coordinate in the complete detector system + * debug is for debugging purposes + * roundRNumber is the round robin set number + * detType is the detector type see :: detectorType + * version is the version number of this structure format + * dataPointer is the pointer to the data + * dataSize in bytes is the size of the data in bytes + * fileDescriptor is the file descriptor */ - void registerCallBackRawDataReady(void (*func)(int, uint64_t, uint64_t, uint64_t, char*, uint32_t, FILE*, void*),void *arg); + void registerCallBackRawDataReady(void (*func)(uint64_t, uint32_t, uint32_t, uint64_t, uint64_t, uint16_t, uint16_t, uint16_t, uint16_t, uint32_t, uint16_t, uint8_t, uint8_t, + char*, uint32_t, FILE*, void*),void *arg); + private: diff --git a/slsReceiverSoftware/include/slsReceiverTCPIPInterface.h b/slsReceiverSoftware/include/slsReceiverTCPIPInterface.h index c967d4335..bed74d936 100644 --- a/slsReceiverSoftware/include/slsReceiverTCPIPInterface.h +++ b/slsReceiverSoftware/include/slsReceiverTCPIPInterface.h @@ -82,15 +82,25 @@ class slsReceiverTCPIPInterface : private virtual slsReceiverDefs { /** * Call back for raw data * args to raw data ready callback are - * index - * frame number - * timestamp/ bunch id - * exposure length/ sub frame number - * datapointer - * datasize in bytes - * file descriptor + * frameNumber is the frame number + * expLength is the subframe number (32 bit eiger) or real time exposure time in 100ns (others) + * packetNumber is the packet number + * bunchId is the bunch id from beamline + * timestamp is the time stamp with 10 MHz clock + * modId is the unique module id (unique even for left, right, top, bottom) + * xCoord is the x coordinate in the complete detector system + * yCoord is the y coordinate in the complete detector system + * zCoord is the z coordinate in the complete detector system + * debug is for debugging purposes + * roundRNumber is the round robin set number + * detType is the detector type see :: detectorType + * version is the version number of this structure format + * dataPointer is the pointer to the data + * dataSize in bytes is the size of the data in bytes + * fileDescriptor is the file descriptor */ - void registerCallBackRawDataReady(void (*func)(int, uint64_t, uint64_t, uint64_t, char*, uint32_t, FILE*, void*),void *arg); + void registerCallBackRawDataReady(void (*func)(uint64_t, uint32_t, uint32_t, uint64_t, uint64_t, uint16_t, uint16_t, uint16_t, uint16_t, uint32_t, uint16_t, uint8_t, uint8_t, + char*, uint32_t, FILE*, void*),void *arg); private: @@ -321,15 +331,25 @@ private: /** * Call back for raw data * args to raw data ready callback are - * index - * frame number - * timestamp/ bunch id - * exposure length/ sub frame number - * datapointer - * datasize in bytes - * file descriptor + * frameNumber is the frame number + * expLength is the subframe number (32 bit eiger) or real time exposure time in 100ns (others) + * packetNumber is the packet number + * bunchId is the bunch id from beamline + * timestamp is the time stamp with 10 MHz clock + * modId is the unique module id (unique even for left, right, top, bottom) + * xCoord is the x coordinate in the complete detector system + * yCoord is the y coordinate in the complete detector system + * zCoord is the z coordinate in the complete detector system + * debug is for debugging purposes + * roundRNumber is the round robin set number + * detType is the detector type see :: detectorType + * version is the version number of this structure format + * dataPointer is the pointer to the data + * dataSize in bytes is the size of the data in bytes + * fileDescriptor is the file descriptor */ - void (*rawDataReadyCallBack)(int, uint64_t, uint64_t, uint64_t, char*, uint32_t, FILE*, void*); + void (*rawDataReadyCallBack)(uint64_t, uint32_t, uint32_t, uint64_t, uint64_t, uint16_t, uint16_t, uint16_t, uint16_t, uint32_t, uint16_t, uint8_t, uint8_t, + char*, uint32_t, FILE*, void*); void *pRawDataReady; diff --git a/slsReceiverSoftware/include/slsReceiverUsers.h b/slsReceiverSoftware/include/slsReceiverUsers.h index 45e6d62e0..c59e4cf13 100644 --- a/slsReceiverSoftware/include/slsReceiverUsers.h +++ b/slsReceiverSoftware/include/slsReceiverUsers.h @@ -72,10 +72,12 @@ public: /** @sort register callback to be called when data are available (to process and/or save the data). - \param func raw data ready callback. arguments are index, frame number, timestamp/ bunch id, exposure length/ sub frame number, datapointer, datasize in bytes, file descriptor - \returns nothing - */ - void registerCallBackRawDataReady(void (*func)(int index, uint64_t framenumber, uint64_t timestamp, uint64_t explength, char* datapointer, uint32_t datasize, FILE* filedescriptor, void*),void *arg); + \param func raw data ready callback. arguments are frameNumber, expLength, packetNumber, bunchId, timestamp, modId, xCoord, yCoord, zCoord, debug, roundRNumber, detType, version, dataPointer, dataSize, fileDescriptor + \returns nothing + */ + void registerCallBackRawDataReady(void (*func)(uint64_t frameNumber, uint32_t expLength, uint32_t packetNumber, uint64_t bunchId, uint64_t timestamp, + uint16_t modId, uint16_t xCoord, uint16_t yCoord, uint16_t zCoord, uint32_t debug, uint16_t roundRNumber, uint8_t detType, uint8_t version, + char* datapointer, uint32_t datasize, FILE* filedescriptor, void*),void *arg); //receiver object slsReceiver* receiver; diff --git a/slsReceiverSoftware/include/sls_receiver_defs.h b/slsReceiverSoftware/include/sls_receiver_defs.h index ce0fad9fa..2dee3ddd1 100755 --- a/slsReceiverSoftware/include/sls_receiver_defs.h +++ b/slsReceiverSoftware/include/sls_receiver_defs.h @@ -116,6 +116,40 @@ public: STOPPED /**< acquisition stopped externally */ }; + + /** + @short structure for a Detector Packet or Image Header + @li frameNumber is the frame number + @li expLength is the subframe number (32 bit eiger) or real time exposure time in 100ns (others) + @li packetNumber is the packet number + @li bunchId is the bunch id from beamline + @li timestamp is the time stamp with 10 MHz clock + @li modId is the unique module id (unique even for left, right, top, bottom) + @li xCoord is the x coordinate in the complete detector system + @li yCoord is the y coordinate in the complete detector system + @li zCoord is the z coordinate in the complete detector system + @li debug is for debugging purposes + @li roundRNumber is the round robin set number + @li detType is the detector type see :: detectorType + @li version is the version number of this structure format + */ + typedef struct { + uint64_t frameNumber; /**< is the frame number */ + uint32_t expLength; /**< is the subframe number (32 bit eiger) or real time exposure time in 100ns (others) */ + uint32_t packetNumber; /**< is the packet number */ + uint64_t bunchId; /**< is the bunch id from beamline */ + uint64_t timestamp; /**< is the time stamp with 10 MHz clock */ + uint16_t modId; /**< is the unique module id (unique even for left, right, top, bottom) */ + uint16_t xCoord; /**< is the x coordinate in the complete detector system */ + uint16_t yCoord; /**< is the y coordinate in the complete detector system */ + uint16_t zCoord; /**< is the z coordinate in the complete detector system */ + uint32_t debug; /**< is for debugging purposes */ + uint16_t roundRNumber; /**< is the round robin set number */ + uint8_t detType; /**< is the detector type see :: detectorType */ + uint8_t version; /**< is the version number of this structure format */ + } sls_detector_header; + + #ifdef __cplusplus /** returns string from enabled/disabled \param b true or false diff --git a/slsReceiverSoftware/src/UDPBaseImplementation.cpp b/slsReceiverSoftware/src/UDPBaseImplementation.cpp index b2a5f69b0..8d184ed82 100644 --- a/slsReceiverSoftware/src/UDPBaseImplementation.cpp +++ b/slsReceiverSoftware/src/UDPBaseImplementation.cpp @@ -517,7 +517,8 @@ void UDPBaseImplementation::registerCallBackAcquisitionFinished(void (*func)(uin pAcquisitionFinished=arg; } -void UDPBaseImplementation::registerCallBackRawDataReady(void (*func)(int, uint64_t, uint64_t, uint64_t, char*, uint32_t, FILE*, void*),void *arg){ +void UDPBaseImplementation::registerCallBackRawDataReady(void (*func)(uint64_t, uint32_t, uint32_t, uint64_t, uint64_t, uint16_t, uint16_t, uint16_t, uint16_t, uint32_t, uint16_t, uint8_t, uint8_t, + char*, uint32_t, FILE*, void*),void *arg){ rawDataReadyCallBack=func; pRawDataReady=arg; } diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 09b86ac2e..216dfabb9 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -650,7 +650,7 @@ int UDPStandardImplementation::setDynamicRange(const uint32_t i){ if(latestData[i]){delete[] latestData[i];latestData[i] = 0;} } for(int i=0;iframeNumber = (uint64_t) (fnum + startAcquisitionIndex); + if (myDetectorType == EIGER && dynamicRange == 32) + header->expLength = (uint32_t) snum; + header->packetNumber = (uint32_t) packetsPerFrame; + if (myDetectorType == JUNGFRAU) + header->bunchId = (uint64_t) bnum; + header->xCoord = (uint16_t) detID * numberofListeningThreads + ithread; + header->detType = (uint8_t) myDetectorType; + header->version = (uint8_t) SLS_DETECTOR_HEADER_VERSION; + #ifdef VERBOSE - if(!ithread) cout << "fnum:" << (*((uint64_t*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS))) << endl; + if(!ithread) + cprintf(BLUE, + "framenumber:%llu\tsubfnum:%u\tpnum:%u\tbunchid:%llu\txcoord:%u\tdettype:%u\tversion:%u\n", + header->frameNumber, header->expLength, header->packetNumber, + header->bunchId, header->xCoord, header->detType, header->version); #endif - switch (myDetectorType) { - case JUNGFRAU: - (*((uint64_t*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS + FILE_HEADER_TIMESTAMP_OFFSET))) = bnum; - (*((uint64_t*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS + FILE_HEADER_EXPLENGTH_OFFSET))) = 0; - break; - case EIGER: - (*((uint64_t*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS + FILE_HEADER_TIMESTAMP_OFFSET))) = 0; - if (dynamicRange == 32) - (*((uint64_t*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS + FILE_HEADER_EXPLENGTH_OFFSET))) = snum; - else - (*((uint64_t*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS + FILE_HEADER_EXPLENGTH_OFFSET))) = 0; - break; - default: - (*((uint64_t*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS + FILE_HEADER_TIMESTAMP_OFFSET))) = 0; - (*((uint64_t*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS + FILE_HEADER_EXPLENGTH_OFFSET))) = 0; - break; - } //write packet count to buffer *((uint32_t*)(buffer[ithread])) = packetsPerFrame; @@ -2852,8 +2849,20 @@ void UDPStandardImplementation::handleWithoutDataCompression(int ithread, char* //callback to write data if (cbAction < DO_EVERYTHING) - rawDataReadyCallBack(detID*numberofListeningThreads+ithread, tempframenumber, - 0,0, + rawDataReadyCallBack( + tempframenumber,//frameNumber + 0,//expLength + 0,//packetNumber + 0,//bunchId + 0,//timestamp + 0,//modId + detID*numberofListeningThreads+ithread,//xCoord + 0,//yCoord + 0,//zCoord + 0,//debug + 0,//roundRNumber + (uint8_t)myDetectorType,//detType + SLS_DETECTOR_HEADER_VERSION,//version wbuffer + fifoBufferHeaderSize, bufferSize * numberofJobsPerBuffer + fifoBufferHeaderSize, sfilefd[ithread], pRawDataReady);//know which thread from sfilefd @@ -2898,15 +2907,25 @@ void UDPStandardImplementation::handleWithoutDataCompression(int ithread, char* void UDPStandardImplementation::handleCompleteFramesOnly(int ithread, char* wbuffer){ FILE_LOG(logDEBUG) << __AT__ << " called"; - //get current frame number - uint64_t tempframenumber = (*((uint64_t*)(wbuffer + HEADER_SIZE_NUM_TOT_PACKETS))); - uint64_t bnum = (*((uint64_t*)(wbuffer + HEADER_SIZE_NUM_TOT_PACKETS + FILE_HEADER_TIMESTAMP_OFFSET))); - uint64_t snum = (*((uint64_t*)(wbuffer + HEADER_SIZE_NUM_TOT_PACKETS + FILE_HEADER_EXPLENGTH_OFFSET))); - + //get header + sls_detector_header* header = (sls_detector_header*) (wbuffer + HEADER_SIZE_NUM_TOT_PACKETS); + uint64_t tempframenumber = header->frameNumber; if (cbAction < DO_EVERYTHING) - rawDataReadyCallBack(detID*numberofListeningThreads+ithread, tempframenumber, - bnum, snum, + rawDataReadyCallBack( + header->frameNumber, + header->expLength, + header->packetNumber, + header->bunchId, + header->timestamp, + header->modId, + header->xCoord, + header->yCoord, + header->zCoord, + header->debug, + header->roundRNumber, + header->detType, + header->version, wbuffer + fifoBufferHeaderSize, bufferSize * numberofJobsPerBuffer + fifoBufferHeaderSize, sfilefd[ithread], pRawDataReady); @@ -2916,7 +2935,7 @@ void UDPStandardImplementation::handleCompleteFramesOnly(int ithread, char* wbuf if((fileWriteEnable) && (sfilefd[ithread])){ if(tempframenumber && (tempframenumber%maxFramesPerFile) == 0) createNewFile(ithread); - fwrite(wbuffer + HEADER_SIZE_NUM_TOT_PACKETS, 1, (bufferSize + FILE_FRAME_HEADER_LENGTH), sfilefd[ithread]); + fwrite(wbuffer + HEADER_SIZE_NUM_TOT_PACKETS, 1, (bufferSize + sizeof(sls_detector_header)), sfilefd[ithread]); } tempframenumber -= startFrameIndex; @@ -3179,7 +3198,7 @@ void UDPStandardImplementation::copyFrameToGui(int ithread, char* buffer, uint32 strcpy(guiFileName[ithread],completeFileName[ithread]); if(excludeMissingPackets) //copy also the header - memcpy(latestData[ithread],buffer+HEADER_SIZE_NUM_TOT_PACKETS, bufferSize + FILE_FRAME_HEADER_LENGTH); + memcpy(latestData[ithread],buffer+ HEADER_SIZE_NUM_TOT_PACKETS, bufferSize + sizeof(sls_detector_header)); else //copy only the data memcpy(latestData[ithread],buffer+ fifoBufferHeaderSize , numpackets*onePacketSize); //let it know its got data diff --git a/slsReceiverSoftware/src/slsReceiver.cpp b/slsReceiverSoftware/src/slsReceiver.cpp index 85750c517..0db3dc793 100644 --- a/slsReceiverSoftware/src/slsReceiver.cpp +++ b/slsReceiverSoftware/src/slsReceiver.cpp @@ -179,7 +179,8 @@ void slsReceiver::registerCallBackAcquisitionFinished(void (*func)(uint64_t, voi } -void slsReceiver::registerCallBackRawDataReady(void (*func)(int, uint64_t, uint64_t, uint64_t, char*, uint32_t, FILE*, void*),void *arg){ +void slsReceiver::registerCallBackRawDataReady(void (*func)(uint64_t, uint32_t, uint32_t, uint64_t, uint64_t, uint16_t, uint16_t, uint16_t, uint16_t, uint32_t, uint16_t, uint8_t, uint8_t, + char*, uint32_t, FILE*, void*),void *arg){ //tcpipInterface if(udp_interface) udp_interface->registerCallBackRawDataReady(func,arg); diff --git a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp index 304476e56..a21bc8ca8 100644 --- a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp +++ b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp @@ -3403,7 +3403,8 @@ void slsReceiverTCPIPInterface::registerCallBackAcquisitionFinished(void (*func) pAcquisitionFinished=arg; } -void slsReceiverTCPIPInterface::registerCallBackRawDataReady(void (*func)(int, uint64_t, uint64_t, uint64_t, char*, uint32_t, FILE*, void*),void *arg){ +void slsReceiverTCPIPInterface::registerCallBackRawDataReady(void (*func)(uint64_t, uint32_t, uint32_t, uint64_t, uint64_t, uint16_t, uint16_t, uint16_t, uint16_t, uint32_t, uint16_t, uint8_t, uint8_t, + char*, uint32_t, FILE*, void*),void *arg){ rawDataReadyCallBack=func; pRawDataReady=arg; } diff --git a/slsReceiverSoftware/src/slsReceiverUsers.cpp b/slsReceiverSoftware/src/slsReceiverUsers.cpp index 384ce86ea..512e838ac 100644 --- a/slsReceiverSoftware/src/slsReceiverUsers.cpp +++ b/slsReceiverSoftware/src/slsReceiverUsers.cpp @@ -17,7 +17,6 @@ void slsReceiverUsers::stop() { receiver->stop(); } - void slsReceiverUsers::closeFile(int p) { receiver->closeFile(p); } @@ -26,19 +25,17 @@ int64_t slsReceiverUsers::getReceiverVersion(){ return receiver->getReceiverVersion(); } - void slsReceiverUsers::registerCallBackStartAcquisition(int (*func)(char*, char*, uint64_t, uint32_t, void*),void *arg){ receiver->registerCallBackStartAcquisition(func,arg); } - - void slsReceiverUsers::registerCallBackAcquisitionFinished(void (*func)(uint64_t, void*),void *arg){ receiver->registerCallBackAcquisitionFinished(func,arg); } - -void slsReceiverUsers::registerCallBackRawDataReady(void (*func)(int, uint64_t, uint64_t, uint64_t, char*, uint32_t, FILE*, void*), void *arg){ +void slsReceiverUsers::registerCallBackRawDataReady(void (*func)(uint64_t frameNumber, uint32_t expLength, uint32_t packetNumber, uint64_t bunchId, uint64_t timestamp, + uint16_t modId, uint16_t xCoord, uint16_t yCoord, uint16_t zCoord, uint32_t debug, uint16_t roundRNumber, uint8_t detType, uint8_t version, + char* datapointer, uint32_t datasize, FILE* filedescriptor, void*), void *arg){ receiver->registerCallBackRawDataReady(func,arg); } From 141324461746d6d3ad22738ad88150ee2b4d8890 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Wed, 15 Mar 2017 15:02:28 +0100 Subject: [PATCH 463/474] update rev --- slsReceiverSoftware/gitInfo.txt | 8 ++++---- slsReceiverSoftware/include/gitInfoReceiver.h | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/slsReceiverSoftware/gitInfo.txt b/slsReceiverSoftware/gitInfo.txt index d82f2848d..87759958f 100644 --- a/slsReceiverSoftware/gitInfo.txt +++ b/slsReceiverSoftware/gitInfo.txt @@ -1,9 +1,9 @@ Path: slsDetectorsPackage/slsReceiverSoftware URL: origin git@git.psi.ch:sls_detectors_software/sls_receiver_software.git Repository Root: origin git@git.psi.ch:sls_detectors_software/sls_receiver_software.git -Repsitory UUID: 398e8b241fe37a2102709553b8b0fa3650f97966 -Revision: 499 +Repsitory UUID: 5edf56eead747efd9f52c5b29d3e23a235a74479 +Revision: 503 Branch: 2.3-rc Last Changed Author: Dhanya_Maliakal -Last Changed Rev: 499 -Last Changed Date: 2016-12-15 14:32:34 +0100 +Last Changed Rev: 503 +Last Changed Date: 2017-03-15 15:00:25 +0100 diff --git a/slsReceiverSoftware/include/gitInfoReceiver.h b/slsReceiverSoftware/include/gitInfoReceiver.h index 421bf31c3..39383e175 100644 --- a/slsReceiverSoftware/include/gitInfoReceiver.h +++ b/slsReceiverSoftware/include/gitInfoReceiver.h @@ -1,11 +1,11 @@ //#define SVNPATH "" #define SVNURL "git@git.psi.ch:sls_detectors_software/sls_receiver_software.git" //#define SVNREPPATH "" -#define SVNREPUUID "398e8b241fe37a2102709553b8b0fa3650f97966" -//#define SVNREV 0x499 +#define SVNREPUUID "5edf56eead747efd9f52c5b29d3e23a235a74479" +//#define SVNREV 0x503 //#define SVNKIND "" //#define SVNSCHED "" #define SVNAUTH "Dhanya_Maliakal" -#define SVNREV 0x499 -#define SVNDATE 0x20161215 +#define SVNREV 0x503 +#define SVNDATE 0x20170315 // From 575c9617c721ee76df67d5db5b12d72de08b2e5f Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Mon, 20 Mar 2017 09:28:15 +0100 Subject: [PATCH 464/474] fixed gui for new header --- slsReceiverSoftware/gitInfo.txt | 8 +- slsReceiverSoftware/include/gitInfoReceiver.h | 6 +- slsReceiverSoftware/include/receiver_defs.h | 3 +- .../src/UDPStandardImplementation.cpp | 79 ++++++++++++++----- 4 files changed, 70 insertions(+), 26 deletions(-) diff --git a/slsReceiverSoftware/gitInfo.txt b/slsReceiverSoftware/gitInfo.txt index 87759958f..b25cc0fe8 100644 --- a/slsReceiverSoftware/gitInfo.txt +++ b/slsReceiverSoftware/gitInfo.txt @@ -1,9 +1,9 @@ Path: slsDetectorsPackage/slsReceiverSoftware URL: origin git@git.psi.ch:sls_detectors_software/sls_receiver_software.git Repository Root: origin git@git.psi.ch:sls_detectors_software/sls_receiver_software.git -Repsitory UUID: 5edf56eead747efd9f52c5b29d3e23a235a74479 -Revision: 503 +Repsitory UUID: 37c93c568669422f853cc8eb3f22d3b4afc257ba +Revision: 504 Branch: 2.3-rc Last Changed Author: Dhanya_Maliakal -Last Changed Rev: 503 -Last Changed Date: 2017-03-15 15:00:25 +0100 +Last Changed Rev: 504 +Last Changed Date: 2017-03-15 15:02:28 +0100 diff --git a/slsReceiverSoftware/include/gitInfoReceiver.h b/slsReceiverSoftware/include/gitInfoReceiver.h index 39383e175..91121b015 100644 --- a/slsReceiverSoftware/include/gitInfoReceiver.h +++ b/slsReceiverSoftware/include/gitInfoReceiver.h @@ -1,11 +1,11 @@ //#define SVNPATH "" #define SVNURL "git@git.psi.ch:sls_detectors_software/sls_receiver_software.git" //#define SVNREPPATH "" -#define SVNREPUUID "5edf56eead747efd9f52c5b29d3e23a235a74479" -//#define SVNREV 0x503 +#define SVNREPUUID "37c93c568669422f853cc8eb3f22d3b4afc257ba" +//#define SVNREV 0x504 //#define SVNKIND "" //#define SVNSCHED "" #define SVNAUTH "Dhanya_Maliakal" -#define SVNREV 0x503 +#define SVNREV 0x504 #define SVNDATE 0x20170315 // diff --git a/slsReceiverSoftware/include/receiver_defs.h b/slsReceiverSoftware/include/receiver_defs.h index 6301f879a..795557dee 100755 --- a/slsReceiverSoftware/include/receiver_defs.h +++ b/slsReceiverSoftware/include/receiver_defs.h @@ -58,7 +58,8 @@ typedef struct { #define HEADER_SIZE_NUM_PACKETS 1 #define ALL_MASK_32 0xFFFFFFFF -#define SLS_DETECTOR_HEADER_VERSION 0x1 +#define SLS_DETECTOR_HEADER_VERSION 0x1 +#define SLS_DETECTOR_JSON_HEADER_VERSION 0x2 //#define FILE_FRAME_HEADER_LENGTH (8*3) //#define FILE_HEADER_TIMESTAMP_OFFSET 8 //start of frame/ bunch id //#define FILE_HEADER_EXPLENGTH_OFFSET 16 //exposure length/ sub frame number diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 216dfabb9..1f43355ce 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1785,13 +1785,38 @@ void UDPStandardImplementation::startDataCallback(){ //header details - const char *type = "float64"; - const char *shape= "[1024, 512]"; - const char *jsonFmt ="{\"htype\":[\"chunk-1.0\"], \"type\":\"%s\", \"shape\":%s, \"acqIndex\":%d, \"fIndex\":%d, \"subfnum\":%d, \"fname\":\"%s\"}"; + const char *jsonFmt ="{" + "\"jsonversion\":%u, " + "\"acqIndex\":%llu, " + "\"fIndex\":%llu, " + "\"bitmode\":%d, " + "\"shape\":[%d, %d], " + "\"fname\":\"%s\", " + + "\"frameNumber\":%llu, " + "\"expLength\":%u, " + "\"packetNumber\":%u, " + "\"bunchId\":%llu, " + "\"timestamp\":%llu, " + "\"modId\":%u, " + "\"xCoord\":%u, " + "\"yCoord\":%u, " + "\"zCoord\":%u, " + "\"debug\":%u, " + "\"roundRNumber\":%u, " + "\"detType\":%u, " + "\"version\":%u" + "}"; + int npixelsx=0, npixelsy=0; + switch(myDetectorType) { + case JUNGFRAU: npixelsx = JFRAU_PIXELS_IN_ONE_ROW; npixelsy = JFRAU_PIXELS_IN_ONE_COL; break; + case EIGER: npixelsx = EIGER_PIXELS_IN_ONE_ROW; npixelsy = EIGER_PIXELS_IN_ONE_COL; break; + default:break; /* will not work for other detectors*/ + } char buf[1000]; - int acquisitionIndex = -1; - int frameIndex = -1; - int subframeIndex = -1; + uint64_t acquisitionIndex = -1; + uint64_t frameIndex = -1; + uint32_t subframeIndex = -1; #ifdef DEBUG int oldpnum = -1; #endif @@ -1816,7 +1841,9 @@ void UDPStandardImplementation::startDataCallback(){ frameIndex = fnum; acquisitionIndex = fnum - startAcquisitionIndex; if(dynamicRange == 32) subframeIndex = snum; - int len = sprintf(buf,jsonFmt,type,shape, acquisitionIndex, frameIndex, subframeIndex,completeFileName[ithread]); + int len = sprintf(buf,jsonFmt, + SLS_DETECTOR_JSON_HEADER_VERSION, acquisitionIndex, frameIndex, dynamicRange, npixelsx, npixelsy,completeFileName[ithread], + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 );/* will not work for other detectors*/ zmq_send(zmqsocket, buf,len, ZMQ_SNDMORE); //send data zmq_send(zmqsocket, buffer, oneframesize, 0); @@ -1828,12 +1855,15 @@ void UDPStandardImplementation::startDataCallback(){ //send final header //update frame details #ifdef DEBUG - cout << "sending dummy" << endl; + cprintf(BLUE,"%d sending dummy\n"); #endif - frameIndex = -9; - acquisitionIndex = -9; - subframeIndex = -9; - int len = sprintf(buf,jsonFmt,type,shape, acquisitionIndex, frameIndex, subframeIndex,completeFileName[ithread]); + + frameIndex = -1; + acquisitionIndex = -1; + int len = sprintf(buf,jsonFmt, + SLS_DETECTOR_JSON_HEADER_VERSION, acquisitionIndex, frameIndex, dynamicRange, npixelsx, npixelsy,completeFileName[ithread], + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + zmq_send(zmqsocket, buf,len, ZMQ_SNDMORE); //send final data zmq_send (zmqsocket, "end", 3, 0); @@ -1863,12 +1893,21 @@ void UDPStandardImplementation::startDataCallback(){ } if(excludeMissingPackets){ +#ifdef DEBUG + cprintf(BLUE,"%d sending image\n", ithread); +#endif //send header //update frame details - frameIndex = (*((uint64_t*)(latestData[ithread]))) - startFrameIndex; - acquisitionIndex = (*((uint64_t*)(latestData[ithread]))) - startAcquisitionIndex; - subframeIndex = -1; - int len = sprintf(buf,jsonFmt,type,shape, acquisitionIndex, frameIndex, subframeIndex,completeFileName[ithread]); + sls_detector_header* header = (sls_detector_header*) (latestData[ithread]); + uint64_t fnum = header->frameNumber; + frameIndex = fnum - startFrameIndex; + acquisitionIndex = fnum - startAcquisitionIndex; + + int len = sprintf(buf,jsonFmt, + SLS_DETECTOR_JSON_HEADER_VERSION, acquisitionIndex, frameIndex, dynamicRange, npixelsx, npixelsy,completeFileName[ithread], + header->frameNumber, header->expLength, header->packetNumber, header->bunchId, header->timestamp, + header->modId, header->xCoord, header->yCoord, header->zCoord, header->debug, header->roundRNumber, header->detType, header->version); + zmq_send(zmqsocket, buf,len, ZMQ_SNDMORE); //send data zmq_send(zmqsocket, (latestData[ithread]+sizeof(sls_detector_header)), bufferSize, 0); @@ -1922,7 +1961,9 @@ void UDPStandardImplementation::startDataCallback(){ frameIndex = fnum; acquisitionIndex = fnum - startAcquisitionIndex; if(dynamicRange == 32) subframeIndex = snum; - int len = sprintf(buf,jsonFmt,type,shape, acquisitionIndex, frameIndex, subframeIndex,completeFileName[ithread]); + int len = sprintf(buf,jsonFmt, + SLS_DETECTOR_JSON_HEADER_VERSION, acquisitionIndex, frameIndex, dynamicRange, npixelsx, npixelsy,completeFileName[ithread], + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 );/* will not work for other detectors*/ zmq_send(zmqsocket, buf,len, ZMQ_SNDMORE); //send data zmq_send(zmqsocket, buffer, oneframesize, 0); @@ -1958,7 +1999,9 @@ void UDPStandardImplementation::startDataCallback(){ frameIndex = fnum; acquisitionIndex = fnum - startAcquisitionIndex; if(dynamicRange == 32) subframeIndex = snum; - int len = sprintf(buf,jsonFmt,type,shape, acquisitionIndex, frameIndex, subframeIndex,completeFileName[ithread]); + int len = sprintf(buf,jsonFmt, + SLS_DETECTOR_JSON_HEADER_VERSION, acquisitionIndex, frameIndex, dynamicRange, npixelsx, npixelsy,completeFileName[ithread], + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 );/* will not work for other detectors*/ zmq_send(zmqsocket, buf,len, ZMQ_SNDMORE); //send data zmq_send(zmqsocket, buffer, oneframesize, 0); From 78958c76999a1581e454a5e967cead717ef04ea5 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Mon, 20 Mar 2017 09:30:15 +0100 Subject: [PATCH 465/474] updaterev --- slsReceiverSoftware/gitInfo.txt | 8 ++++---- slsReceiverSoftware/include/gitInfoReceiver.h | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/slsReceiverSoftware/gitInfo.txt b/slsReceiverSoftware/gitInfo.txt index b25cc0fe8..2bad189e9 100644 --- a/slsReceiverSoftware/gitInfo.txt +++ b/slsReceiverSoftware/gitInfo.txt @@ -1,9 +1,9 @@ Path: slsDetectorsPackage/slsReceiverSoftware URL: origin git@git.psi.ch:sls_detectors_software/sls_receiver_software.git Repository Root: origin git@git.psi.ch:sls_detectors_software/sls_receiver_software.git -Repsitory UUID: 37c93c568669422f853cc8eb3f22d3b4afc257ba -Revision: 504 +Repsitory UUID: 41fa05e555865e703acd55c143ca0d3cc6dc1022 +Revision: 505 Branch: 2.3-rc Last Changed Author: Dhanya_Maliakal -Last Changed Rev: 504 -Last Changed Date: 2017-03-15 15:02:28 +0100 +Last Changed Rev: 505 +Last Changed Date: 2017-03-20 09:28:15 +0100 diff --git a/slsReceiverSoftware/include/gitInfoReceiver.h b/slsReceiverSoftware/include/gitInfoReceiver.h index 91121b015..45fabf65e 100644 --- a/slsReceiverSoftware/include/gitInfoReceiver.h +++ b/slsReceiverSoftware/include/gitInfoReceiver.h @@ -1,11 +1,11 @@ //#define SVNPATH "" #define SVNURL "git@git.psi.ch:sls_detectors_software/sls_receiver_software.git" //#define SVNREPPATH "" -#define SVNREPUUID "37c93c568669422f853cc8eb3f22d3b4afc257ba" -//#define SVNREV 0x504 +#define SVNREPUUID "41fa05e555865e703acd55c143ca0d3cc6dc1022" +//#define SVNREV 0x505 //#define SVNKIND "" //#define SVNSCHED "" #define SVNAUTH "Dhanya_Maliakal" -#define SVNREV 0x504 -#define SVNDATE 0x20170315 +#define SVNREV 0x505 +#define SVNDATE 0x20170320 // From 6f34dddb5afadcdc45b43c63346666dec85431a3 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Thu, 23 Mar 2017 13:41:37 +0100 Subject: [PATCH 466/474] changed the file header size t0 1kb and changed its description in the header --- .../include/UDPStandardImplementation.h | 2 +- .../src/UDPStandardImplementation.cpp | 16 ++++++++++++++-- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/slsReceiverSoftware/include/UDPStandardImplementation.h b/slsReceiverSoftware/include/UDPStandardImplementation.h index ad455e791..a1542e000 100644 --- a/slsReceiverSoftware/include/UDPStandardImplementation.h +++ b/slsReceiverSoftware/include/UDPStandardImplementation.h @@ -630,7 +630,7 @@ private: bool fileCreateSuccess; /** File header */ - const static unsigned int FILE_HEADER_SIZE = 500; + const static unsigned int FILE_HEADER_SIZE = 1000; char fileHeader[MAX_NUMBER_OF_WRITER_THREADS][FILE_HEADER_SIZE]; /** File Descriptor */ diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 1f43355ce..46548b3dd 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -3196,8 +3196,20 @@ void UDPStandardImplementation::updateFileHeader(int ithread){ "Timestamp\t: %s\n\n" "#Frame Header\n" - "Frame Number\t: 8 bytes\n" - "Bunch ID\t: 8 bytes\n", + "Frame Number : 8 bytes\n" + "Exposure Length : 4 bytes\n" + "Packet Number : 4 bytes\n" + "Bunch ID : 8 bytes\n" + "Timestamp : 8 bytes\n" + "Module Id : 2 bytes\n" + "X Coordinate : 2 bytes\n" + "Y Coordinate : 2 bytes\n" + "Z Coordinate : 2 bytes\n" + "Debug : 4 bytes\n" + "Round Robin Number : 2 bytes\n" + "Detector Type : 1 byte\n" + "Header Version : 1 byte\n" + , FILE_HEADER_SIZE, (flippedData[0]?0:1), (ithread?0:1), From 0814f6369d126f34b01c1271dc057c5ef5ba09d7 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Thu, 23 Mar 2017 13:46:16 +0100 Subject: [PATCH 467/474] udpaterev --- slsReceiverSoftware/gitInfo.txt | 10 +++++----- slsReceiverSoftware/include/gitInfoReceiver.h | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/slsReceiverSoftware/gitInfo.txt b/slsReceiverSoftware/gitInfo.txt index 2bad189e9..2cea640e9 100644 --- a/slsReceiverSoftware/gitInfo.txt +++ b/slsReceiverSoftware/gitInfo.txt @@ -1,9 +1,9 @@ Path: slsDetectorsPackage/slsReceiverSoftware URL: origin git@git.psi.ch:sls_detectors_software/sls_receiver_software.git Repository Root: origin git@git.psi.ch:sls_detectors_software/sls_receiver_software.git -Repsitory UUID: 41fa05e555865e703acd55c143ca0d3cc6dc1022 -Revision: 505 -Branch: 2.3-rc +Repsitory UUID: 09606556f452f6051706557b8201e6221fa44ed6 +Revision: 507 +Branch: 2.3 Last Changed Author: Dhanya_Maliakal -Last Changed Rev: 505 -Last Changed Date: 2017-03-20 09:28:15 +0100 +Last Changed Rev: 507 +Last Changed Date: 2017-03-23 13:41:37 +0100 diff --git a/slsReceiverSoftware/include/gitInfoReceiver.h b/slsReceiverSoftware/include/gitInfoReceiver.h index 45fabf65e..999cfdb8d 100644 --- a/slsReceiverSoftware/include/gitInfoReceiver.h +++ b/slsReceiverSoftware/include/gitInfoReceiver.h @@ -1,11 +1,11 @@ //#define SVNPATH "" #define SVNURL "git@git.psi.ch:sls_detectors_software/sls_receiver_software.git" //#define SVNREPPATH "" -#define SVNREPUUID "41fa05e555865e703acd55c143ca0d3cc6dc1022" -//#define SVNREV 0x505 +#define SVNREPUUID "09606556f452f6051706557b8201e6221fa44ed6" +//#define SVNREV 0x507 //#define SVNKIND "" //#define SVNSCHED "" #define SVNAUTH "Dhanya_Maliakal" -#define SVNREV 0x505 -#define SVNDATE 0x20170320 +#define SVNREV 0x507 +#define SVNDATE 0x20170323 // From 54371bc6beeec22166f4644da3d9cc035361d123 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Thu, 23 Mar 2017 13:48:18 +0100 Subject: [PATCH 468/474] updaterev --- slsReceiverSoftware/gitInfo.txt | 8 ++++---- slsReceiverSoftware/include/gitInfoReceiver.h | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/slsReceiverSoftware/gitInfo.txt b/slsReceiverSoftware/gitInfo.txt index 2cea640e9..ff5aae18b 100644 --- a/slsReceiverSoftware/gitInfo.txt +++ b/slsReceiverSoftware/gitInfo.txt @@ -1,9 +1,9 @@ Path: slsDetectorsPackage/slsReceiverSoftware URL: origin git@git.psi.ch:sls_detectors_software/sls_receiver_software.git Repository Root: origin git@git.psi.ch:sls_detectors_software/sls_receiver_software.git -Repsitory UUID: 09606556f452f6051706557b8201e6221fa44ed6 -Revision: 507 +Repsitory UUID: 08da5f3560f705d87317ab91e3e0dd75351847e0 +Revision: 508 Branch: 2.3 Last Changed Author: Dhanya_Maliakal -Last Changed Rev: 507 -Last Changed Date: 2017-03-23 13:41:37 +0100 +Last Changed Rev: 508 +Last Changed Date: 2017-03-23 13:46:16 +0100 diff --git a/slsReceiverSoftware/include/gitInfoReceiver.h b/slsReceiverSoftware/include/gitInfoReceiver.h index 999cfdb8d..8edf062cf 100644 --- a/slsReceiverSoftware/include/gitInfoReceiver.h +++ b/slsReceiverSoftware/include/gitInfoReceiver.h @@ -1,11 +1,11 @@ //#define SVNPATH "" #define SVNURL "git@git.psi.ch:sls_detectors_software/sls_receiver_software.git" //#define SVNREPPATH "" -#define SVNREPUUID "09606556f452f6051706557b8201e6221fa44ed6" -//#define SVNREV 0x507 +#define SVNREPUUID "08da5f3560f705d87317ab91e3e0dd75351847e0" +//#define SVNREV 0x508 //#define SVNKIND "" //#define SVNSCHED "" #define SVNAUTH "Dhanya_Maliakal" -#define SVNREV 0x507 +#define SVNREV 0x508 #define SVNDATE 0x20170323 // From 404be013a2ffa046dfb33a46a05c1b9f78d10c56 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Thu, 23 Mar 2017 14:08:43 +0100 Subject: [PATCH 469/474] changes to new callback arguments without filepointer --- .../include/UDPBaseImplementation.h | 12 ++++-------- slsReceiverSoftware/include/UDPInterface.h | 8 +++----- slsReceiverSoftware/include/receiver_defs.h | 3 +-- slsReceiverSoftware/include/slsReceiver.h | 6 ++---- .../include/slsReceiverTCPIPInterface.h | 13 ++++--------- slsReceiverSoftware/include/slsReceiverUsers.h | 6 +++--- .../src/UDPBaseImplementation.cpp | 2 +- .../src/UDPStandardImplementation.cpp | 16 ++++++++-------- slsReceiverSoftware/src/slsReceiver.cpp | 2 +- .../src/slsReceiverTCPIPInterface.cpp | 2 +- slsReceiverSoftware/src/slsReceiverUsers.cpp | 2 +- 11 files changed, 29 insertions(+), 43 deletions(-) diff --git a/slsReceiverSoftware/include/UDPBaseImplementation.h b/slsReceiverSoftware/include/UDPBaseImplementation.h index 0519d1a56..6c7a1b500 100644 --- a/slsReceiverSoftware/include/UDPBaseImplementation.h +++ b/slsReceiverSoftware/include/UDPBaseImplementation.h @@ -488,8 +488,7 @@ class UDPBaseImplementation : protected virtual slsReceiverDefs, public UDPInter * * return value is * 0 callback takes care of open,close,wrie file - * 1 callback writes file, we have to open, close it - * 2 we open, close, write file, callback does not do anything + * 1 we open, close, write file, callback does not do anything */ void registerCallBackStartAcquisition(int (*func)(char*, char*, uint64_t, uint32_t, void*),void *arg); @@ -518,10 +517,9 @@ class UDPBaseImplementation : protected virtual slsReceiverDefs, public UDPInter * version is the version number of this structure format * dataPointer is the pointer to the data * dataSize in bytes is the size of the data in bytes - * fileDescriptor is the file descriptor */ void registerCallBackRawDataReady(void (*func)(uint64_t, uint32_t, uint32_t, uint64_t, uint64_t, uint16_t, uint16_t, uint16_t, uint16_t, uint32_t, uint16_t, uint8_t, uint8_t, - char*, uint32_t, FILE*, void*),void *arg); + char*, uint32_t, void*),void *arg); @@ -620,8 +618,7 @@ class UDPBaseImplementation : protected virtual slsReceiverDefs, public UDPInter * * return value is * 0 callback takes care of open,close,wrie file - * 1 callback writes file, we have to open, close it - * 2 we open, close, write file, callback does not do anything + * 1 we open, close, write file, callback does not do anything */ int (*startAcquisitionCallBack)(char*, char*, uint64_t, uint32_t, void*); void *pStartAcquisition; @@ -653,10 +650,9 @@ class UDPBaseImplementation : protected virtual slsReceiverDefs, public UDPInter * version is the version number of this structure format * dataPointer is the pointer to the data * dataSize in bytes is the size of the data in bytes - * fileDescriptor is the file descriptor */ void (*rawDataReadyCallBack)(uint64_t, uint32_t, uint32_t, uint64_t, uint64_t, uint16_t, uint16_t, uint16_t, uint16_t, uint32_t, uint16_t, uint8_t, uint8_t, - char*, uint32_t, FILE*, void*); + char*, uint32_t, void*); void *pRawDataReady; diff --git a/slsReceiverSoftware/include/UDPInterface.h b/slsReceiverSoftware/include/UDPInterface.h index de497a0b6..5aa47b58e 100644 --- a/slsReceiverSoftware/include/UDPInterface.h +++ b/slsReceiverSoftware/include/UDPInterface.h @@ -544,9 +544,8 @@ class UDPInterface { * datasize * * return value is - * 0 callback takes care of open,close,wrie file - * 1 callback writes file, we have to open, close it - * 2 we open, close, write file, callback does not do anything + * 0 callback takes care of open,close,write file + * 1 we open, close, write file, callback does not do anything */ virtual void registerCallBackStartAcquisition(int (*func)(char*, char*, uint64_t, uint32_t, void*),void *arg) = 0; @@ -575,10 +574,9 @@ class UDPInterface { * version is the version number of this structure format * dataPointer is the pointer to the data * dataSize in bytes is the size of the data in bytes - * fileDescriptor is the file descriptor */ virtual void registerCallBackRawDataReady(void (*func)(uint64_t, uint32_t, uint32_t, uint64_t, uint64_t, uint16_t, uint16_t, uint16_t, uint16_t, uint32_t, uint16_t, uint8_t, uint8_t, - char*, uint32_t, FILE*, void*),void *arg) = 0; + char*, uint32_t, void*),void *arg) = 0; protected: diff --git a/slsReceiverSoftware/include/receiver_defs.h b/slsReceiverSoftware/include/receiver_defs.h index 795557dee..fe142ddea 100755 --- a/slsReceiverSoftware/include/receiver_defs.h +++ b/slsReceiverSoftware/include/receiver_defs.h @@ -47,8 +47,7 @@ typedef struct { #define GOODBYE -200 #define DO_NOTHING 0 -#define CREATE_FILES 1 -#define DO_EVERYTHING 2 +#define DO_EVERYTHING 1 #define BUF_SIZE (16*1024*1024) //16mb #define SAMPLE_TIME_IN_NS 100000000//100ms diff --git a/slsReceiverSoftware/include/slsReceiver.h b/slsReceiverSoftware/include/slsReceiver.h index 35feec9f4..7617f43f7 100644 --- a/slsReceiverSoftware/include/slsReceiver.h +++ b/slsReceiverSoftware/include/slsReceiver.h @@ -67,8 +67,7 @@ class slsReceiver : private virtual slsReceiverDefs { * * return value is * 0 callback takes care of open,close,wrie file - * 1 callback writes file, we have to open, close it - * 2 we open, close, write file, callback does not do anything + * 1 we open, close, write file, callback does not do anything */ void registerCallBackStartAcquisition(int (*func)(char*, char*, uint64_t, uint32_t, void*),void *arg); @@ -97,10 +96,9 @@ class slsReceiver : private virtual slsReceiverDefs { * version is the version number of this structure format * dataPointer is the pointer to the data * dataSize in bytes is the size of the data in bytes - * fileDescriptor is the file descriptor */ void registerCallBackRawDataReady(void (*func)(uint64_t, uint32_t, uint32_t, uint64_t, uint64_t, uint16_t, uint16_t, uint16_t, uint16_t, uint32_t, uint16_t, uint8_t, uint8_t, - char*, uint32_t, FILE*, void*),void *arg); + char*, uint32_t, void*),void *arg); diff --git a/slsReceiverSoftware/include/slsReceiverTCPIPInterface.h b/slsReceiverSoftware/include/slsReceiverTCPIPInterface.h index bed74d936..d497f8fb8 100644 --- a/slsReceiverSoftware/include/slsReceiverTCPIPInterface.h +++ b/slsReceiverSoftware/include/slsReceiverTCPIPInterface.h @@ -67,8 +67,7 @@ class slsReceiverTCPIPInterface : private virtual slsReceiverDefs { * * return value is * 0 callback takes care of open,close,wrie file - * 1 callback writes file, we have to open, close it - * 2 we open, close, write file, callback does not do anything + * 1 we open, close, write file, callback does not do anything */ void registerCallBackStartAcquisition(int (*func)(char*, char*, uint64_t, uint32_t, void*),void *arg); @@ -97,11 +96,9 @@ class slsReceiverTCPIPInterface : private virtual slsReceiverDefs { * version is the version number of this structure format * dataPointer is the pointer to the data * dataSize in bytes is the size of the data in bytes - * fileDescriptor is the file descriptor */ void registerCallBackRawDataReady(void (*func)(uint64_t, uint32_t, uint32_t, uint64_t, uint64_t, uint16_t, uint16_t, uint16_t, uint16_t, uint32_t, uint16_t, uint8_t, uint8_t, - char*, uint32_t, FILE*, void*),void *arg); - + char*, uint32_t, void*),void *arg); private: /** @@ -313,8 +310,7 @@ private: * * return value is * 0 callback takes care of open,close,wrie file - * 1 callback writes file, we have to open, close it - * 2 we open, close, write file, callback does not do anything + * 1 we open, close, write file, callback does not do anything */ int (*startAcquisitionCallBack)(char*, char*, uint64_t, uint32_t, void*); void *pStartAcquisition; @@ -346,10 +342,9 @@ private: * version is the version number of this structure format * dataPointer is the pointer to the data * dataSize in bytes is the size of the data in bytes - * fileDescriptor is the file descriptor */ void (*rawDataReadyCallBack)(uint64_t, uint32_t, uint32_t, uint64_t, uint64_t, uint16_t, uint16_t, uint16_t, uint16_t, uint32_t, uint16_t, uint8_t, uint8_t, - char*, uint32_t, FILE*, void*); + char*, uint32_t, void*); void *pRawDataReady; diff --git a/slsReceiverSoftware/include/slsReceiverUsers.h b/slsReceiverSoftware/include/slsReceiverUsers.h index c59e4cf13..ee60ed2cd 100644 --- a/slsReceiverSoftware/include/slsReceiverUsers.h +++ b/slsReceiverSoftware/include/slsReceiverUsers.h @@ -56,7 +56,7 @@ public: @sort register calbback for starting the acquisition \param func callback to be called when starting the acquisition. Its arguments are filepath, filename, fileindex, datasize - \returns 0 callback takes care of open,close,write file; 1 callback writes file, we have to open, close it; 2 we open, close, write file, callback does not do anything + \returns 0 callback takes care of open,close,write file; 1 we open, close, write file, callback does not do anything */ void registerCallBackStartAcquisition(int (*func)(char* filepath, char* filename, uint64_t fileindex, uint32_t datasize, void*),void *arg); @@ -72,12 +72,12 @@ public: /** @sort register callback to be called when data are available (to process and/or save the data). - \param func raw data ready callback. arguments are frameNumber, expLength, packetNumber, bunchId, timestamp, modId, xCoord, yCoord, zCoord, debug, roundRNumber, detType, version, dataPointer, dataSize, fileDescriptor + \param func raw data ready callback. arguments are frameNumber, expLength, packetNumber, bunchId, timestamp, modId, xCoord, yCoord, zCoord, debug, roundRNumber, detType, version, dataPointer, dataSize \returns nothing */ void registerCallBackRawDataReady(void (*func)(uint64_t frameNumber, uint32_t expLength, uint32_t packetNumber, uint64_t bunchId, uint64_t timestamp, uint16_t modId, uint16_t xCoord, uint16_t yCoord, uint16_t zCoord, uint32_t debug, uint16_t roundRNumber, uint8_t detType, uint8_t version, - char* datapointer, uint32_t datasize, FILE* filedescriptor, void*),void *arg); + char* datapointer, uint32_t datasize, void*),void *arg); //receiver object slsReceiver* receiver; diff --git a/slsReceiverSoftware/src/UDPBaseImplementation.cpp b/slsReceiverSoftware/src/UDPBaseImplementation.cpp index 8d184ed82..5539b4d95 100644 --- a/slsReceiverSoftware/src/UDPBaseImplementation.cpp +++ b/slsReceiverSoftware/src/UDPBaseImplementation.cpp @@ -518,7 +518,7 @@ void UDPBaseImplementation::registerCallBackAcquisitionFinished(void (*func)(uin } void UDPBaseImplementation::registerCallBackRawDataReady(void (*func)(uint64_t, uint32_t, uint32_t, uint64_t, uint64_t, uint16_t, uint16_t, uint16_t, uint16_t, uint32_t, uint16_t, uint8_t, uint8_t, - char*, uint32_t, FILE*, void*),void *arg){ + char*, uint32_t, void*),void *arg){ rawDataReadyCallBack=func; pRawDataReady=arg; } diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 46548b3dd..0c2a6d063 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -1536,7 +1536,7 @@ int UDPStandardImplementation::setupWriter(){ cbAction=startAcquisitionCallBack(filePath, (char*)tempname.c_str(),fileIndex, (uint32_t)bufferSize,pStartAcquisition); } - if(cbAction < DO_EVERYTHING){ + if(cbAction == DO_NOTHING){ FILE_LOG(logINFO) << "Call back activated. Data saving must be taken care of by user in call back."; if (rawDataReadyCallBack){ FILE_LOG(logINFO) << "Data Write has been defined externally"; @@ -1587,12 +1587,12 @@ int UDPStandardImplementation::createNewFile(int ithread){ #endif //filewrite enable & we allowed to create/close files - if(fileWriteEnable && cbAction > DO_NOTHING){ + if(fileWriteEnable && cbAction == DO_EVERYTHING){ //close file pointers if(sfilefd[ithread]){ //all threads need to close file, reset mask and exit loop - if(myDetectorType == EIGER && fileWriteEnable && (cbAction > DO_NOTHING)){ + if(myDetectorType == EIGER && fileWriteEnable && (cbAction == DO_EVERYTHING)){ updateFileHeader(ithread); fseek(sfilefd[ithread],0,0); fwrite((void*)fileHeader[ithread], 1, FILE_HEADER_SIZE, sfilefd[ithread]); @@ -2732,7 +2732,7 @@ void UDPStandardImplementation::stopWriting(int ithread, char* wbuffer){ //all threads need to close file, reset mask and exit loop - if(myDetectorType == EIGER && fileWriteEnable && (cbAction > DO_NOTHING)){ + if(myDetectorType == EIGER && fileWriteEnable && (cbAction == DO_EVERYTHING)){ updateFileHeader(ithread); fseek(sfilefd[ithread],0,0); fwrite((void*)fileHeader[ithread], 1, FILE_HEADER_SIZE, sfilefd[ithread]); @@ -2891,7 +2891,7 @@ void UDPStandardImplementation::handleWithoutDataCompression(int ithread, char* //callback to write data - if (cbAction < DO_EVERYTHING) + if (cbAction == DO_NOTHING) rawDataReadyCallBack( tempframenumber,//frameNumber 0,//expLength @@ -2908,7 +2908,7 @@ void UDPStandardImplementation::handleWithoutDataCompression(int ithread, char* SLS_DETECTOR_HEADER_VERSION,//version wbuffer + fifoBufferHeaderSize, bufferSize * numberofJobsPerBuffer + fifoBufferHeaderSize, - sfilefd[ithread], pRawDataReady);//know which thread from sfilefd + pRawDataReady);//know which thread from sfilefd @@ -2954,7 +2954,7 @@ void UDPStandardImplementation::handleCompleteFramesOnly(int ithread, char* wbuf sls_detector_header* header = (sls_detector_header*) (wbuffer + HEADER_SIZE_NUM_TOT_PACKETS); uint64_t tempframenumber = header->frameNumber; - if (cbAction < DO_EVERYTHING) + if (cbAction == DO_NOTHING) rawDataReadyCallBack( header->frameNumber, header->expLength, @@ -2971,7 +2971,7 @@ void UDPStandardImplementation::handleCompleteFramesOnly(int ithread, char* wbuf header->version, wbuffer + fifoBufferHeaderSize, bufferSize * numberofJobsPerBuffer + fifoBufferHeaderSize, - sfilefd[ithread], pRawDataReady); + pRawDataReady); //write to file if enabled and update write parameters diff --git a/slsReceiverSoftware/src/slsReceiver.cpp b/slsReceiverSoftware/src/slsReceiver.cpp index 0db3dc793..4a28ab8e1 100644 --- a/slsReceiverSoftware/src/slsReceiver.cpp +++ b/slsReceiverSoftware/src/slsReceiver.cpp @@ -180,7 +180,7 @@ void slsReceiver::registerCallBackAcquisitionFinished(void (*func)(uint64_t, voi void slsReceiver::registerCallBackRawDataReady(void (*func)(uint64_t, uint32_t, uint32_t, uint64_t, uint64_t, uint16_t, uint16_t, uint16_t, uint16_t, uint32_t, uint16_t, uint8_t, uint8_t, - char*, uint32_t, FILE*, void*),void *arg){ + char*, uint32_t, void*),void *arg){ //tcpipInterface if(udp_interface) udp_interface->registerCallBackRawDataReady(func,arg); diff --git a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp index a21bc8ca8..8f4fd537a 100644 --- a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp +++ b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp @@ -3404,7 +3404,7 @@ void slsReceiverTCPIPInterface::registerCallBackAcquisitionFinished(void (*func) } void slsReceiverTCPIPInterface::registerCallBackRawDataReady(void (*func)(uint64_t, uint32_t, uint32_t, uint64_t, uint64_t, uint16_t, uint16_t, uint16_t, uint16_t, uint32_t, uint16_t, uint8_t, uint8_t, - char*, uint32_t, FILE*, void*),void *arg){ + char*, uint32_t, void*),void *arg){ rawDataReadyCallBack=func; pRawDataReady=arg; } diff --git a/slsReceiverSoftware/src/slsReceiverUsers.cpp b/slsReceiverSoftware/src/slsReceiverUsers.cpp index 512e838ac..a0126764d 100644 --- a/slsReceiverSoftware/src/slsReceiverUsers.cpp +++ b/slsReceiverSoftware/src/slsReceiverUsers.cpp @@ -35,7 +35,7 @@ void slsReceiverUsers::registerCallBackAcquisitionFinished(void (*func)(uint64_t void slsReceiverUsers::registerCallBackRawDataReady(void (*func)(uint64_t frameNumber, uint32_t expLength, uint32_t packetNumber, uint64_t bunchId, uint64_t timestamp, uint16_t modId, uint16_t xCoord, uint16_t yCoord, uint16_t zCoord, uint32_t debug, uint16_t roundRNumber, uint8_t detType, uint8_t version, - char* datapointer, uint32_t datasize, FILE* filedescriptor, void*), void *arg){ + char* datapointer, uint32_t datasize, void*), void *arg){ receiver->registerCallBackRawDataReady(func,arg); } From da8d535dae95e9621cff09ac07b7e3bdeda59ba6 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Thu, 23 Mar 2017 14:09:01 +0100 Subject: [PATCH 470/474] updaterev --- slsReceiverSoftware/gitInfo.txt | 8 ++++---- slsReceiverSoftware/include/gitInfoReceiver.h | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/slsReceiverSoftware/gitInfo.txt b/slsReceiverSoftware/gitInfo.txt index ff5aae18b..e43d9a0d2 100644 --- a/slsReceiverSoftware/gitInfo.txt +++ b/slsReceiverSoftware/gitInfo.txt @@ -1,9 +1,9 @@ Path: slsDetectorsPackage/slsReceiverSoftware URL: origin git@git.psi.ch:sls_detectors_software/sls_receiver_software.git Repository Root: origin git@git.psi.ch:sls_detectors_software/sls_receiver_software.git -Repsitory UUID: 08da5f3560f705d87317ab91e3e0dd75351847e0 -Revision: 508 +Repsitory UUID: b4698af6a1ed52ff9a03881f14c93097f249588c +Revision: 510 Branch: 2.3 Last Changed Author: Dhanya_Maliakal -Last Changed Rev: 508 -Last Changed Date: 2017-03-23 13:46:16 +0100 +Last Changed Rev: 510 +Last Changed Date: 2017-03-23 14:08:43 +0100 diff --git a/slsReceiverSoftware/include/gitInfoReceiver.h b/slsReceiverSoftware/include/gitInfoReceiver.h index 8edf062cf..b4579fe95 100644 --- a/slsReceiverSoftware/include/gitInfoReceiver.h +++ b/slsReceiverSoftware/include/gitInfoReceiver.h @@ -1,11 +1,11 @@ //#define SVNPATH "" #define SVNURL "git@git.psi.ch:sls_detectors_software/sls_receiver_software.git" //#define SVNREPPATH "" -#define SVNREPUUID "08da5f3560f705d87317ab91e3e0dd75351847e0" -//#define SVNREV 0x508 +#define SVNREPUUID "b4698af6a1ed52ff9a03881f14c93097f249588c" +//#define SVNREV 0x510 //#define SVNKIND "" //#define SVNSCHED "" #define SVNAUTH "Dhanya_Maliakal" -#define SVNREV 0x508 +#define SVNREV 0x510 #define SVNDATE 0x20170323 // From 70a7217353199cfbccc7f3448285e52c30884f0f Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Thu, 23 Mar 2017 15:17:21 +0100 Subject: [PATCH 471/474] changed the header size to a better number --- slsReceiverSoftware/include/UDPStandardImplementation.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/slsReceiverSoftware/include/UDPStandardImplementation.h b/slsReceiverSoftware/include/UDPStandardImplementation.h index a1542e000..b52c53b30 100644 --- a/slsReceiverSoftware/include/UDPStandardImplementation.h +++ b/slsReceiverSoftware/include/UDPStandardImplementation.h @@ -630,7 +630,7 @@ private: bool fileCreateSuccess; /** File header */ - const static unsigned int FILE_HEADER_SIZE = 1000; + const static unsigned int FILE_HEADER_SIZE = 1024; char fileHeader[MAX_NUMBER_OF_WRITER_THREADS][FILE_HEADER_SIZE]; /** File Descriptor */ From e450f5ec6a5fba5b1e03448a0e636a3f8d20acf3 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Thu, 23 Mar 2017 15:17:34 +0100 Subject: [PATCH 472/474] updaterev --- slsReceiverSoftware/gitInfo.txt | 8 ++++---- slsReceiverSoftware/include/gitInfoReceiver.h | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/slsReceiverSoftware/gitInfo.txt b/slsReceiverSoftware/gitInfo.txt index e43d9a0d2..09ad992a7 100644 --- a/slsReceiverSoftware/gitInfo.txt +++ b/slsReceiverSoftware/gitInfo.txt @@ -1,9 +1,9 @@ Path: slsDetectorsPackage/slsReceiverSoftware URL: origin git@git.psi.ch:sls_detectors_software/sls_receiver_software.git Repository Root: origin git@git.psi.ch:sls_detectors_software/sls_receiver_software.git -Repsitory UUID: b4698af6a1ed52ff9a03881f14c93097f249588c -Revision: 510 +Repsitory UUID: 9f0ea629975864abb9bb3fd9f59c1d9188e0f3d1 +Revision: 512 Branch: 2.3 Last Changed Author: Dhanya_Maliakal -Last Changed Rev: 510 -Last Changed Date: 2017-03-23 14:08:43 +0100 +Last Changed Rev: 512 +Last Changed Date: 2017-03-23 15:17:21 +0100 diff --git a/slsReceiverSoftware/include/gitInfoReceiver.h b/slsReceiverSoftware/include/gitInfoReceiver.h index b4579fe95..aab086be3 100644 --- a/slsReceiverSoftware/include/gitInfoReceiver.h +++ b/slsReceiverSoftware/include/gitInfoReceiver.h @@ -1,11 +1,11 @@ //#define SVNPATH "" #define SVNURL "git@git.psi.ch:sls_detectors_software/sls_receiver_software.git" //#define SVNREPPATH "" -#define SVNREPUUID "b4698af6a1ed52ff9a03881f14c93097f249588c" -//#define SVNREV 0x510 +#define SVNREPUUID "9f0ea629975864abb9bb3fd9f59c1d9188e0f3d1" +//#define SVNREV 0x512 //#define SVNKIND "" //#define SVNSCHED "" #define SVNAUTH "Dhanya_Maliakal" -#define SVNREV 0x510 +#define SVNREV 0x512 #define SVNDATE 0x20170323 // From 86490226edf8f82a1e8e782bb0a394ba8d68ba4b Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Fri, 24 Mar 2017 13:41:56 +0100 Subject: [PATCH 473/474] removing the return value usage in start acquisition callback, callbacks will be called if registered, and we will write files if file write enabled --- .../include/UDPBaseImplementation.h | 12 ++++---- slsReceiverSoftware/include/UDPInterface.h | 6 ++-- .../include/UDPStandardImplementation.h | 7 ----- slsReceiverSoftware/include/slsReceiver.h | 6 ++-- .../include/slsReceiverTCPIPInterface.h | 12 ++++---- .../include/slsReceiverUsers.h | 2 +- .../src/UDPStandardImplementation.cpp | 28 +++++++------------ 7 files changed, 29 insertions(+), 44 deletions(-) diff --git a/slsReceiverSoftware/include/UDPBaseImplementation.h b/slsReceiverSoftware/include/UDPBaseImplementation.h index 6c7a1b500..ebc0ee095 100644 --- a/slsReceiverSoftware/include/UDPBaseImplementation.h +++ b/slsReceiverSoftware/include/UDPBaseImplementation.h @@ -486,9 +486,9 @@ class UDPBaseImplementation : protected virtual slsReceiverDefs, public UDPInter * fileindex * datasize * - * return value is - * 0 callback takes care of open,close,wrie file - * 1 we open, close, write file, callback does not do anything + * return value is insignificant at the moment + * we write depending on file write enable + * users get data to write depending on call backs registered */ void registerCallBackStartAcquisition(int (*func)(char*, char*, uint64_t, uint32_t, void*),void *arg); @@ -616,9 +616,9 @@ class UDPBaseImplementation : protected virtual slsReceiverDefs, public UDPInter * fileindex * datasize * - * return value is - * 0 callback takes care of open,close,wrie file - * 1 we open, close, write file, callback does not do anything + * return value is insignificant at the moment + * we write depending on file write enable + * users get data to write depending on call backs registered */ int (*startAcquisitionCallBack)(char*, char*, uint64_t, uint32_t, void*); void *pStartAcquisition; diff --git a/slsReceiverSoftware/include/UDPInterface.h b/slsReceiverSoftware/include/UDPInterface.h index 5aa47b58e..adaa7e0de 100644 --- a/slsReceiverSoftware/include/UDPInterface.h +++ b/slsReceiverSoftware/include/UDPInterface.h @@ -543,9 +543,9 @@ class UDPInterface { * fileindex * datasize * - * return value is - * 0 callback takes care of open,close,write file - * 1 we open, close, write file, callback does not do anything + * return value is insignificant at the moment + * we write depending on file write enable + * users get data to write depending on call backs registered */ virtual void registerCallBackStartAcquisition(int (*func)(char*, char*, uint64_t, uint32_t, void*),void *arg) = 0; diff --git a/slsReceiverSoftware/include/UDPStandardImplementation.h b/slsReceiverSoftware/include/UDPStandardImplementation.h index b52c53b30..ccada5681 100644 --- a/slsReceiverSoftware/include/UDPStandardImplementation.h +++ b/slsReceiverSoftware/include/UDPStandardImplementation.h @@ -832,13 +832,6 @@ private: pthread_mutex_t progressMutex; - //***callback*** - /** The action which decides what the user and default responsibilities to save data are - * 0 raw data ready callback takes care of open,close,write file - * 1 callback writes file, we have to open, close it - * 2 we open, close, write file, callback does not do anything */ - int cbAction; - }; diff --git a/slsReceiverSoftware/include/slsReceiver.h b/slsReceiverSoftware/include/slsReceiver.h index 7617f43f7..0dfd2b6a7 100644 --- a/slsReceiverSoftware/include/slsReceiver.h +++ b/slsReceiverSoftware/include/slsReceiver.h @@ -65,9 +65,9 @@ class slsReceiver : private virtual slsReceiverDefs { * fileindex * datasize * - * return value is - * 0 callback takes care of open,close,wrie file - * 1 we open, close, write file, callback does not do anything + * return value is undefined at the moment + * we write depending on file write enable + * users get data to write depending on call backs registered */ void registerCallBackStartAcquisition(int (*func)(char*, char*, uint64_t, uint32_t, void*),void *arg); diff --git a/slsReceiverSoftware/include/slsReceiverTCPIPInterface.h b/slsReceiverSoftware/include/slsReceiverTCPIPInterface.h index d497f8fb8..f574773aa 100644 --- a/slsReceiverSoftware/include/slsReceiverTCPIPInterface.h +++ b/slsReceiverSoftware/include/slsReceiverTCPIPInterface.h @@ -65,9 +65,9 @@ class slsReceiverTCPIPInterface : private virtual slsReceiverDefs { * fileindex * datasize * - * return value is - * 0 callback takes care of open,close,wrie file - * 1 we open, close, write file, callback does not do anything + * return value is insignificant at the moment + * we write depending on file write enable + * users get data to write depending on call backs registered */ void registerCallBackStartAcquisition(int (*func)(char*, char*, uint64_t, uint32_t, void*),void *arg); @@ -308,9 +308,9 @@ private: * fileindex * datasize * - * return value is - * 0 callback takes care of open,close,wrie file - * 1 we open, close, write file, callback does not do anything + * return value is insignificant at the moment + * we write depending on file write enable + * users get data to write depending on call backs registered */ int (*startAcquisitionCallBack)(char*, char*, uint64_t, uint32_t, void*); void *pStartAcquisition; diff --git a/slsReceiverSoftware/include/slsReceiverUsers.h b/slsReceiverSoftware/include/slsReceiverUsers.h index ee60ed2cd..2edb540dc 100644 --- a/slsReceiverSoftware/include/slsReceiverUsers.h +++ b/slsReceiverSoftware/include/slsReceiverUsers.h @@ -56,7 +56,7 @@ public: @sort register calbback for starting the acquisition \param func callback to be called when starting the acquisition. Its arguments are filepath, filename, fileindex, datasize - \returns 0 callback takes care of open,close,write file; 1 we open, close, write file, callback does not do anything + \return value is insignificant at the moment, we write depending on file write enable, users get data to write depending on call backs registered */ void registerCallBackStartAcquisition(int (*func)(char* filepath, char* filename, uint64_t fileindex, uint32_t datasize, void*),void *arg); diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 0c2a6d063..c31a037cb 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -226,9 +226,6 @@ void UDPStandardImplementation::initializeMembers(){ receiverData[i] = 0; } - - //***callback*** - cbAction = DO_EVERYTHING; } @@ -1525,7 +1522,6 @@ int UDPStandardImplementation::setupWriter(){ FILE_LOG(logDEBUG) << __AT__ << " starting"; //acquisition start call back returns enable write - cbAction = DO_EVERYTHING; if (startAcquisitionCallBack) { //remove detector index in the file name int deti = -1; @@ -1533,17 +1529,13 @@ int UDPStandardImplementation::setupWriter(){ size_t uscore=tempname.rfind("_"); if ((uscore!=string::npos) && (sscanf(tempname.substr(uscore+1,tempname.size()-uscore-1).c_str(),"d%d",&deti))) tempname=tempname.substr(0,uscore); - cbAction=startAcquisitionCallBack(filePath, (char*)tempname.c_str(),fileIndex, (uint32_t)bufferSize,pStartAcquisition); + startAcquisitionCallBack(filePath, (char*)tempname.c_str(),fileIndex, (uint32_t)bufferSize,pStartAcquisition); } - - if(cbAction == DO_NOTHING){ - FILE_LOG(logINFO) << "Call back activated. Data saving must be taken care of by user in call back."; - if (rawDataReadyCallBack){ - FILE_LOG(logINFO) << "Data Write has been defined externally"; - } - }else if(!fileWriteEnable){ + if (rawDataReadyCallBack) + FILE_LOG(logINFO) << "Data Write has been defined externally"; + if (!fileWriteEnable) FILE_LOG(logINFO) << "Data will not be saved"; - } + //creating first file @@ -1587,12 +1579,12 @@ int UDPStandardImplementation::createNewFile(int ithread){ #endif //filewrite enable & we allowed to create/close files - if(fileWriteEnable && cbAction == DO_EVERYTHING){ + if(fileWriteEnable){ //close file pointers if(sfilefd[ithread]){ //all threads need to close file, reset mask and exit loop - if(myDetectorType == EIGER && fileWriteEnable && (cbAction == DO_EVERYTHING)){ + if(myDetectorType == EIGER && fileWriteEnable){ updateFileHeader(ithread); fseek(sfilefd[ithread],0,0); fwrite((void*)fileHeader[ithread], 1, FILE_HEADER_SIZE, sfilefd[ithread]); @@ -2732,7 +2724,7 @@ void UDPStandardImplementation::stopWriting(int ithread, char* wbuffer){ //all threads need to close file, reset mask and exit loop - if(myDetectorType == EIGER && fileWriteEnable && (cbAction == DO_EVERYTHING)){ + if(myDetectorType == EIGER && fileWriteEnable){ updateFileHeader(ithread); fseek(sfilefd[ithread],0,0); fwrite((void*)fileHeader[ithread], 1, FILE_HEADER_SIZE, sfilefd[ithread]); @@ -2891,7 +2883,7 @@ void UDPStandardImplementation::handleWithoutDataCompression(int ithread, char* //callback to write data - if (cbAction == DO_NOTHING) + if (rawDataReadyCallBack) rawDataReadyCallBack( tempframenumber,//frameNumber 0,//expLength @@ -2954,7 +2946,7 @@ void UDPStandardImplementation::handleCompleteFramesOnly(int ithread, char* wbuf sls_detector_header* header = (sls_detector_header*) (wbuffer + HEADER_SIZE_NUM_TOT_PACKETS); uint64_t tempframenumber = header->frameNumber; - if (cbAction == DO_NOTHING) + if (rawDataReadyCallBack) rawDataReadyCallBack( header->frameNumber, header->expLength, From cacb4c9d936ad8fc06c0f54e2cef8a44c934e22d Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Fri, 24 Mar 2017 13:42:11 +0100 Subject: [PATCH 474/474] updaterev --- slsReceiverSoftware/gitInfo.txt | 8 ++++---- slsReceiverSoftware/include/gitInfoReceiver.h | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/slsReceiverSoftware/gitInfo.txt b/slsReceiverSoftware/gitInfo.txt index 09ad992a7..bfc610dae 100644 --- a/slsReceiverSoftware/gitInfo.txt +++ b/slsReceiverSoftware/gitInfo.txt @@ -1,9 +1,9 @@ Path: slsDetectorsPackage/slsReceiverSoftware URL: origin git@git.psi.ch:sls_detectors_software/sls_receiver_software.git Repository Root: origin git@git.psi.ch:sls_detectors_software/sls_receiver_software.git -Repsitory UUID: 9f0ea629975864abb9bb3fd9f59c1d9188e0f3d1 -Revision: 512 +Repsitory UUID: a453c1d55d73fecc18af9df6ada21621a989ee4b +Revision: 514 Branch: 2.3 Last Changed Author: Dhanya_Maliakal -Last Changed Rev: 512 -Last Changed Date: 2017-03-23 15:17:21 +0100 +Last Changed Rev: 514 +Last Changed Date: 2017-03-24 13:41:56 +0100 diff --git a/slsReceiverSoftware/include/gitInfoReceiver.h b/slsReceiverSoftware/include/gitInfoReceiver.h index aab086be3..29510e4e9 100644 --- a/slsReceiverSoftware/include/gitInfoReceiver.h +++ b/slsReceiverSoftware/include/gitInfoReceiver.h @@ -1,11 +1,11 @@ //#define SVNPATH "" #define SVNURL "git@git.psi.ch:sls_detectors_software/sls_receiver_software.git" //#define SVNREPPATH "" -#define SVNREPUUID "9f0ea629975864abb9bb3fd9f59c1d9188e0f3d1" -//#define SVNREV 0x512 +#define SVNREPUUID "a453c1d55d73fecc18af9df6ada21621a989ee4b" +//#define SVNREV 0x514 //#define SVNKIND "" //#define SVNSCHED "" #define SVNAUTH "Dhanya_Maliakal" -#define SVNREV 0x512 -#define SVNDATE 0x20170323 +#define SVNREV 0x514 +#define SVNDATE 0x20170324 //