Merge remote branch 'slsReceiverSoftware/2.1.1' into 2.1.1

This commit is contained in:
Dhanya Maliakal 2017-12-04 16:47:22 +01:00
commit 69da61b1fb
39 changed files with 13049 additions and 0 deletions

7
slsReceiverSoftware/.gitignore vendored Normal file
View File

@ -0,0 +1,7 @@
*~
*.o
build/*
GPATH
GRTAGS
GSYMS
GTAGS

View File

@ -0,0 +1,115 @@
include ../Makefile.include
DESTDIR ?= ../bin
LIBDIR ?= $(DESTDIR)
DOCDIR ?= docs
SRCDIR = src
TESTDIR = test
BUILDDIR = build
PROGS = $(DESTDIR)/slsReceiver
CFLAGS= -g -DC_ONLY -fPIC
#FLAGS+= #-DVERBOSE -DVERYVERBOSE
DFLAGS= -g -DDACS_INT -DSLS_RECEIVER_UDP_FUNCTIONS
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
DUMMY_MAIN_SRC = dummyMain.cpp
OBJS=$(SRC_CLNT:%.cpp=$(BUILDDIR)/%.o)
$(info )
$(info #######################################)
$(info # Compiling slsReceiverSoftware #)
$(info #######################################)
$(info )
.PHONY: all intdoc package eigerReceiver clean
all: builddir lib receiver
dummy: $(DESTDIR)/dummyReceiver
intdoc: $(SRC_H) $(SRC_CLNT)
doxygen doxy.config
$(BUILDDIR)/%.o : $(SRCDIR)/%.cpp Makefile
ifeq ($(ROOTSLS),yes)
$(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)
endif
lib: $(OBJS) $(DESTDIR)/libSlsReceiver.so $(DESTDIR)/libSlsReceiver.a
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
$(shell test -d $(DESTDIR) || mkdir -p $(DESTDIR))
mv libSlsReceiver.so $(DESTDIR)
$(DESTDIR)/libSlsReceiver.a: $(OBJS)
ar rcs libSlsReceiver.a $(OBJS)
mv libSlsReceiver.a $(DESTDIR)
$(DESTDIR)/slsReceiver: lib
$(CXX) -o $@ $(SRCDIR)/$(MAIN_SRC) $(FLAGS) $(INCLUDES) $(CLAGS) $(LIBS) $(LDFLAGRXR) -fPIC
#$(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
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: buildclean
make testclean
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
buildclean:
rm -rf $(OBJS)
testclean:
if [ -f $(TESTDIR)/rec ]; then \
cd $(TESTDIR) && rm *.o rec send; \
fi
#-------------------------------------------------------------------------------
install: package
install_inc:
$(shell test -d $(DESTDIR) || mkdir -p $(DESTDIR))
cp -P slsReceiver/slsReceiverUsers.h $(DESTDIR)

View File

@ -0,0 +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
Branch: developer
Last Changed Author: Dhanya_Maliakal
Last Changed Rev: 251
Last Changed Date: 2016-08-12 13:48:30 +0200

View File

@ -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

View File

@ -0,0 +1,296 @@
/**
* @file RestHelper.h
* @author Leonardo Sala <leonardo.sala@psi.ch>
* @date Tue Mar 25 09:28:19 2014
*
* @brief
*
*
*/
#include <Poco/Net/HTTPClientSession.h>
#include <Poco/Net/HTTPRequest.h>
#include <Poco/Net/HTTPResponse.h>
#include <Poco/StreamCopier.h>
#include <Poco/Path.h>
#include <Poco/URI.h>
#include <Poco/Exception.h>
#include <Poco/Timespan.h>
#include "JsonBox/Value.h"
//#include "logger.h"
#include <iostream>
#include <sstream>
#include <string>
#include <exception>
#include <unistd.h>
using namespace Poco::Net;
using namespace Poco;
using namespace std;
class RestHelper {
public:
RestHelper(int timeout=10, int n_tries=1){
/**
*
*
* @param timeout default=10
* @param n_tries default=1
*/
http_timeout = timeout;
n_connection_tries = n_tries;
}
~RestHelper(){
delete session;
};
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 ) {
FILE_LOG(logDEBUG) << __AT__ << " REQUEST: " << " 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_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="{}"){
/**
*
*
* @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(n < n_connection_tries){
req.setContentType("application/json");
//without this you need to tell the lenght: http://pocoproject.org/forum/viewtopic.php?f=12&t=5741&p=10019&hilit=post+json#p10019
// request.setContentLength(my_string.length());
req.setChunkedTransferEncoding(true);
try {
//istringstream rs(request_body);
//req.read(rs);
//cout << " --- " << rs << endl;
if (request_body == "")
session->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 << "/"<<n_connection_tries << ")";
sleep(5);
}
n+=1;
}
std::cout << "Hostname: " << full_hostname << std::endl;
FILE_LOG(logERROR) << "Cannot connect to the REST server host " << full_hostname << "! Please check..." ;
throw std::runtime_error("Cannot connect to the REST server! Please check...");
//return code;
}
};

View File

@ -0,0 +1,595 @@
//#ifdef UDP_BASE_IMPLEMENTATION
#ifndef UDP_BASE_IMPLEMENTATION_H
#define UDP_BASE_IMPLEMENTATION_H
/********************************************//**
* @file UDPBaseImplementation.h
* @short does all the functions for a receiver, set/get parameters, start/stop etc.
***********************************************/
//#include "sls_receiver_defs.h"
#include "UDPInterface.h"
//#include <stdio.h>
/**
* @short does all the base functions for a receiver, set/get parameters, start/stop etc.
*/
class UDPBaseImplementation : protected virtual slsReceiverDefs, public UDPInterface {
public:
/*************************************************************************
* Constructor & Destructor **********************************************
* They access local cache of configuration or detector parameters *******
*************************************************************************/
/**
* Constructor
*/
UDPBaseImplementation();
/**
* Destructor
*/
virtual ~UDPBaseImplementation();
/*
* Initialize class members
*/
void initializeMembers();
/*************************************************************************
* Getters ***************************************************************
* They access local cache of configuration or detector parameters *******
*************************************************************************/
//**initial parameters***
/*
* Get detector hostname
* @return NULL or hostname or NULL if uninitialized (max of 1000 characters)
*/
char *getDetectorHostname() const;
//***file parameters***
/**
* 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)
*/
char *getFileName() const;
/**
* Get File Path
* @return NULL or file path (max of 1000 characters)
*/
char *getFilePath() const;
/**
* Get File Index
* @return file index of acquisition
*/
uint64_t getFileIndex() const;
/**
* Get Scan Tag
* @return scan tag //FIXME: needed? (unsigned integer?)
*/
int getScanTag() const;
/**
* 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
*/
bool getFrameIndexEnable() const;
/**
* Get File Write Enable
* @return true if file write enabled, else false
*/
bool getFileWriteEnable() const;
/**
* Get File Over Write Enable
* @return true if file over write enabled, else false
*/
bool getOverwriteEnable() const;
/**
* Get data compression, by saving only hits (so far implemented only for Moench and Gotthard)
* @return true if data compression enabled, else false
*/
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;
/**
* Get Frames Caught for each real time acquisition (eg. for each scan)
* @return number of frames caught for each scan
*/
uint64_t getFramesCaught() const;
/**
* Get Current Frame Index for an entire acquisition (including all scans)
* @return current frame index (represents all scans too)
*/
int64_t getAcquisitionIndex() const;
//***connection parameters***
/**
* Get UDP Port Number
* @return udp port number
*/
uint32_t getUDPPortNumber() const;
/**
* Get Second UDP Port Number (eiger specific)
* @return second udp port number
*/
uint32_t getUDPPortNumber2() const;
/**
* Get Ehernet Interface
* @ethernet interface. eg. eth0 or "" if listening to all (max of 1000 characters)
*/
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;
/**
* Get the Frequency of Frames Sent to GUI
* @return 0 for random frame requests, n for nth frame frequency
*/
uint32_t getFrameToGuiFrequency() const;
/**
* Get Acquisition Period
* @return acquisition period
*/
uint64_t getAcquisitionPeriod() 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)
* @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;
/**
* Get Fifo Depth
* @return fifo depth
*/
uint32_t getFifoDepth() const;
//***receiver status***
/**
* Get Listening Status of Receiver
* @return can be idle, listening or error depending on if the receiver is listening or not
*/
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;
/*************************************************************************
* 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<string, string> 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
* @return OK or FAIL
*/
int setDataCompressionEnable(const bool b);
//***connection parameters***
/**
* Set UDP Port Number
* @param i udp port number
*/
void setUDPPortNumber(const uint32_t i);
/**
* Set Second UDP Port Number (eiger specific)
* @return second udp port number
*/
void setUDPPortNumber2(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);
//***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
*/
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
* @return OK or FAIL
*/
int setFrameToGuiFrequency(const uint32_t i);
/**
* Set Acquisition Period
* @param i acquisition period
* @return OK or FAIL
*/
int 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
* @param i number of frames expected
* @return OK or FAIL
*/
int 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
* @return OK or FAIL
*/
int setDynamicRange(const uint32_t i);
/**
* Set Ten Giga Enable
* @param b true if 10Giga enabled, else false (1G enabled)
* @return OK or FAIL
*/
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***************************************************
* 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 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 and deletes UDP Sockets
* @return OK or FAIL
*/
int shutDownUDPSockets();
/**
* 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);
/**
* abort acquisition with minimum damage: close open files, cleanup.
* does nothing if state already is 'idle'
*/
void abort(); //FIXME: needed, isn't stopReceiver enough?
/**
* 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);
/**
* 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***
/**
* 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);
/**
* 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);
protected:
/*************************************************************************
* Class Members *********************************************************
*************************************************************************/
//**detector parameters***
/** detector type */
detectorType myDetectorType;
/** detector hostname */
char detHostname[MAX_STR_LENGTH];
/** Number of Packets per Frame*/
uint32_t packetsPerFrame;
/** Acquisition Period */
int64_t acquisitionPeriod;
/** Frame Number */
int64_t numberOfFrames;
/** Dynamic Range */
uint32_t dynamicRange;
/** Ten Giga Enable*/
bool tengigaEnable;
/** Fifo Depth */
uint32_t fifoDepth;
/** Bottom Half Module Enable */
bool bottomEnable;
//***receiver parameters***
/** Maximum Number of Listening Threads/ UDP Ports */
const static int MAX_NUMBER_OF_LISTENING_THREADS = 2;
/** Receiver Status */
runStatus status;
/** Activated/Deactivated */
int activated;
//***connection parameters***
/** Ethernet Interface */
char eth[MAX_STR_LENGTH];
/** Server UDP Port Number*/
uint32_t udpPortNum[MAX_NUMBER_OF_LISTENING_THREADS];
//***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 */
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;
//***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) */
uint64_t packetsCaught;
//***acquisition indices parameters***
/** Actual current frame index of an entire acquisition (including all scans) */
uint64_t acquisitionIndex;
//***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***
/**
* 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;
private:
};
#endif
//#endif

View File

@ -0,0 +1,533 @@
#ifndef UDPINTERFACE_H
#define UDPINTERFACE_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 <exception>
#include "sls_receiver_defs.h"
#include "receiver_defs.h"
#include "utilities.h"
#include "logger.h"
class 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() //FIXME: only once functionality implemented in the derived REST class, so not mention here?
*
* get*() : anytime after initialize(), multiples times
*
* set*() : anytime after initialize(), multiple times
*
* 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
*
*
*
* 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;
*
* 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() {};
/*************************************************************************
* 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)
*/
virtual char *getDetectorHostname() const = 0;
//***file parameters***
/**
* 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;
/**
* 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;
/**
* Get File Index
* @return NULL or file index of acquisition
*/
virtual uint64_t getFileIndex() const = 0;
/**
* 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 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 getUDPPortNumber() const = 0;
/**
* Get Second UDP Port Number (eiger specific)
* @return second udp port number
*/
virtual uint32_t getUDPPortNumber2() 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;
/*
* 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 uint64_t getNumberOfFrames() const = 0;
/**
* Get Dynamic Range or Number of Bits Per Pixel
* @return dynamic range that is 4, 8, 16 or 32
*/
virtual uint32_t getDynamicRange() const = 0;
/**
* Get Ten Giga Enable
* @return true if 10Giga enabled, else false (1G enabled)
*/
virtual bool getTenGigaEnable() const = 0;
/**
* Get Fifo Depth
* @return fifo depth
*/
virtual uint32_t getFifoDepth() 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;
/**
* 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;
/*************************************************************************
* 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<string, string> 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
* Checks for file directory existence before setting file path
* @param c file path (max of 1000 characters)
*/
virtual void setFilePath(const char c[]) = 0;
/**
* Set File Index of acquisition
* @param i file index of acquisition
*/
virtual void setFileIndex(const uint64_t i) = 0;
/**
* Set Scan Tag
* @param i scan tag //FIXME: needed? (unsigned integer?)
*/
virtual void setScanTag(const int i) = 0;
/**
* 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 void setFrameIndexEnable(const bool b) = 0;
/**
* Set File Write Enable
* @param b true for file write enable, else false
*/
virtual void setFileWriteEnable(const bool b) = 0;
/**
* Set File Overwrite Enable
* @param b true for file overwrite enable, else false
*/
virtual void setOverwriteEnable(const bool b) = 0;
/**
* 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 int setDataCompressionEnable(const bool b) = 0;
//***connection parameters***
/**
* Set UDP Port Number
* @param i udp port number
*/
virtual void setUDPPortNumber(const uint32_t i) = 0;
/**
* Set Second UDP Port Number (eiger specific)
* @return second udp port number
*/
virtual void setUDPPortNumber2(const uint32_t i) = 0;
/**
* Set Ethernet Interface to listen to
* @param c ethernet inerface eg. eth0 (max of 1000 characters)
*/
virtual void setEthernetInterface(const char* c) = 0;
//***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
*/
virtual void setShortFrameEnable(const int i) = 0;
/**
* 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 int setFrameToGuiFrequency(const uint32_t i) = 0;
/**
* Set Acquisition Period
* @param i acquisition period
* @return OK or FAIL
*/
virtual int setAcquisitionPeriod(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)
* @param i number of frames expected
* @return OK or FAIL
*/
virtual int setNumberOfFrames(const uint64_t i) = 0;
/**
* 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 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 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***************************************************
* 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)
*/
virtual void resetAcquisitionCount() = 0;
/**
* 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 and deletes UDP Sockets
* @return OK or FAIL
*/
virtual int shutDownUDPSockets() = 0;
/**
* 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
*/
virtual void readFrame(char* c,char** raw, uint64_t &startAcq, uint64_t &startFrame)=0;
/**
* 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?
/**
* 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;
/**
* 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
* 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 UDPINTERFACE_H */

View File

@ -0,0 +1,153 @@
//#ifdef REST
#ifndef UDP_REST_IMPLEMENTATION_H
#define UDP_REST_IMPLEMENTATION_H
/********************************************//**
* @file UDPRESTImplementation.h
* @short does all the functions for a receiver, set/get parameters, start/stop etc.
***********************************************/
#include "UDPBaseImplementation.h"
#include "RestHelper.h"
#include <string.h>
#include <stdio.h>
/**
* @short does all the functions for a receiver, set/get parameters, start/stop etc.
*/
class UDPRESTImplementation : protected virtual slsReceiverDefs, public UDPBaseImplementation {
public:
/*************************************************************************
* Constructor & Destructor **********************************************
*************************************************************************/
/**
* Constructor
*/
UDPRESTImplementation();
/**
* Destructor
*/
virtual ~UDPRESTImplementation();
protected:
/*************************************************************************
* 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<string, string> config_map);
/*************************************************************************
* Behavioral functions***************************************************
* They may modify the status of the receiver ****************************
*************************************************************************/
/**
* 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
*/
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, 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 stopReceiver();
/**
* 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();
/**
* 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:
bool isInitialized;
RestHelper * rest ;
int rest_port; // receiver backend port
string rest_hostname; // receiver hostname
};
#endif
//#endif /*REST*/

View File

@ -0,0 +1,726 @@
//#ifdef UDP_BASE_IMPLEMENTATION
#ifndef UDP_STANDARD_IMPLEMENTATION_H
#define UDP_STANDARD_IMPLEMENTATION_H
/********************************************//**
* @file UDPBaseImplementation.h
* @short does all the functions for a receiver, set/get parameters, start/stop etc.
***********************************************/
#include "UDPBaseImplementation.h"
#include "genericSocket.h"
#include "circularFifo.h"
#include "singlePhotonDetector.h"
#include "slsReceiverData.h"
#include "moenchCommonMode.h"
#ifdef MYROOT1
#include <TTree.h>
#include <TFile.h>
#endif
#include <string.h>
#include <pthread.h>
#include <stdio.h>
#include <semaphore.h>
/**
* @short does all the functions for a receiver, set/get parameters, start/stop etc.
*/
class UDPStandardImplementation: private virtual slsReceiverDefs, public UDPBaseImplementation {
public:
/*************************************************************************
* Constructor & Destructor **********************************************
*************************************************************************/
/**
* Constructor
*/
UDPStandardImplementation();
/**
* Destructor
*/
virtual ~UDPStandardImplementation();
/*************************************************************************
* Getters ***************************************************************
* They access local cache of configuration or detector 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<string, string> config_map);
//*** file 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
* @return OK or FAIL
*/
int 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);
/**
* 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 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
* @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);
/**
* Overridden method
* Set Fifo Depth
* @param i fifo depth value
* @return OK or FAIL
*/
int setFifoDepth(const uint32_t i);
/*************************************************************************
* 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 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
* When this function returns, it has status RUNNING(upon SUCCESS) or IDLE (upon failure)
* @param c error message if FAIL
* @return OK or FAIL
*/
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, 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 stopReceiver();
/**
* 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();
/**
* 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:
/*************************************************************************
* 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***
/**
* 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();
/**
* 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();
/*************************************************************************
* Listening and Writing Threads *****************************************
*************************************************************************/
/**
* 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();
/**
* Creates UDP Sockets
* @return OK or FAIL
*/
int createUDPSockets();
/**
* Initializes writer variables and creates the first file
* also does the startAcquisitionCallBack
* @return OK or FAIL
*/
int setupWriter();
/**
* 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
*/
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();
/**
* 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);
/**
* 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 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<char>* fifoTempFree[]);
/**
* 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
* 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[]);
/**
* 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
* @param wbuffer writing buffer popped out from FIFO
* @param npackets number of packets
*/
void handleWithoutDataCompression(int ithread, char* wbuffer[],uint32_t 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[],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[]);
/**
* 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
* Uses semaphore for nth frame mode
* @param buffer buffer to copy
*/
void copyFrameToGui(char* buffer[]);
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[], uint64_t &nf);
/*************************************************************************
* Class Members *********************************************************
*************************************************************************/
//**detector parameters***
/** 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***
#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 */
bool fileCreateSuccess;
char fileHeader[1000];
//***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;
/** Previous Frame number from buffer to calculate loss */
int64_t previousFrameNumber;
/** Last Frame Index Listened To */
int32_t lastFrameIndex;
/* Acquisition started */
bool acqStarted;
/* Measurement started */
bool measurementStarted;
/** 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;
//***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<char>* fifo[MAX_NUMBER_OF_LISTENING_THREADS];
/** Circular fifo to point to address already written and freed, to be reused */
CircularFifo<char>* 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;
/** Total fifo size */
uint32_t fifoSize;
/** 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;
//***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;
/** counter for nth frame to gui */
int frametoGuiCounter;
//***general and listening thread parameters***
/** Ensures if threads created successfully */
bool threadStarted;
/** Current Thread Index*/
int currentThreadIndex;
/** 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];
/** 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;
//***deactivated parameters***
uint64_t deactivated_framenumber[MAX_NUMBER_OF_LISTENING_THREADS];
uint32_t deactivated_packetnumber[MAX_NUMBER_OF_LISTENING_THREADS];
//***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<uint16_t> *singlePhotonDetectorObject[MAX_NUMBER_OF_WRITER_THREADS];
/** Receiver Data Object for each writer thread */
slsReceiverData<uint16_t> *receiverData[MAX_NUMBER_OF_WRITER_THREADS];
//***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
* 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;
};
#endif
//#endif

View File

@ -0,0 +1,60 @@
#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__)
/*
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);
}
*/

View File

@ -0,0 +1,160 @@
/* CircularFifo.h
* Not any company's property but Public-Domain
* Do with source-code as you will. No requirement to keep this
* header if need to use it/change it/ or do whatever with it
*
* Note that there is No guarantee that this code will work
* and I take no responsibility for this code and any problems you
* might get if using it. The code is highly platform dependent!
*
* Code & platform dependent issues with it was originally
* published at http://www.kjellkod.cc/threadsafecircularqueue
* 2009-11-02
* @author Kjell Hedstr<EFBFBD>m, hedstrom@kjellkod.cc */
#ifndef CIRCULARFIFO_H_
#define CIRCULARFIFO_H_
//#include "sls_receiver_defs.h"
#include <semaphore.h>
#include <vector>
#include <iostream>
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<typename Element>
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() {
sem_destroy(&free_mutex);
}
bool push(Element*& item_);
bool pop(Element*& item_);
bool isEmpty() const;
bool isFull() const;
int getSemValue();
private:
volatile unsigned int tail; // input index
vector <Element*> array;
volatile unsigned int head; // output index
unsigned int Capacity;
sem_t free_mutex;
unsigned int increment(unsigned int idx_) const;
};
template<typename Element>
int CircularFifo<Element>::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<typename Element>
bool CircularFifo<Element>::push(Element*& item_)
{
//cout<<"*head:"<<head<<endl;
//cout<<"*tail before"<<tail<<endl;
unsigned int nextTail = increment(tail);
//cout<<"*next tail"<<nextTail<<endl;
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<typename Element>
bool CircularFifo<Element>::pop(Element*& item_)
{
//cout<<"-tail:"<<tail<<endl;
//cout<<"-head before:"<<head<<endl;
//if(head == tail)
// return false; // empty queue
sem_wait(&free_mutex);
item_ = array[head];
head = increment(head);
//cout<<"-head after:"<<head<<endl;
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<typename Element>
bool CircularFifo<Element>::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<typename Element>
bool CircularFifo<Element>::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<typename Element>
unsigned int CircularFifo<Element>::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_ */

View File

@ -0,0 +1,436 @@
#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"
#include "genericSocket.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<string, string> 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;
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
/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 */

View File

@ -0,0 +1,732 @@
#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 <arpa/inet.h>
#include <netdb.h>
#include <netinet/in.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <ifaddrs.h>
#endif
#include <stdlib.h> /******exit */
#include <unistd.h>
#include <string.h>
#include <iostream>
#include <math.h>
#include <errno.h>
#include <stdio.h>
using namespace std;
#define DEFAULT_PACKET_SIZE 1286
/*#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
#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) :
// portno(port_number),
protocol(p),
is_a_server(0),
socketDescriptor(-1),
file_des(-1),
packet_size(ps),
nsending(0),
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);
strcpy(lastClientIP,"none");
strcpy(thisClientIP,"none1");
strcpy(dummyClientIP,"dummy");
differentClients = 0;
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, 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)
{
/* // 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");
differentClients = 0;
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 "<<endl;
return;
}
// Set some fields in the serverAddress structure.
serverAddress.sin_family = AF_INET;
serverAddress.sin_port = htons(port_number);
serverAddress.sin_addr.s_addr = htonl(INADDR_ANY);
if (string(ip)!=string("0.0.0.0")) {
if (inet_pton(AF_INET, ip, &(serverAddress.sin_addr)))
;
else
serverAddress.sin_addr.s_addr = htonl(INADDR_ANY);
}
// reuse port
int val=1;
if (setsockopt(socketDescriptor,SOL_SOCKET,SO_REUSEADDR,&val,sizeof(int)) == -1) {
cerr << "setsockopt" << endl;
socketDescriptor=-1;
return;
}
//increase buffer size if its udp
val = SOCKET_BUFFER_SIZE;
if((p == UDP) && (setsockopt(socketDescriptor, SOL_SOCKET, SO_RCVBUF, &val, sizeof(int)) == -1))
{
cerr << "WARNING:Could not set socket receive buffer size" << endl;
//socketDescriptor=-1;
//return;
}
if(bind(socketDescriptor,(struct sockaddr *) &serverAddress,sizeof(serverAddress))<0){
cerr << "Can not bind socket "<< endl;
socketDescriptor=-1;
return;
}
if (getProtocol()==SOCK_STREAM)
listen(socketDescriptor, DEFAULT_BACKLOG);
}
/**
The destructor: disconnects and close the socket
@short the destructor
*/
~genericSocket(){ \
Disconnect();
if (socketDescriptor >= 0){ \
close(socketDescriptor); \
} \
if(is_a_server and getProtocol() == TCP){\
if(file_des>0)\
close(file_des);\
}
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"<<endl;
if(file_des>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"<<endl;
switch(errno) {
case EWOULDBLOCK:
printf("ewouldblock eagain\n");
break;
case EBADF:
printf("ebadf\n");
break;
case ECONNABORTED:
printf("econnaborted\n");
break;
case EFAULT:
printf("efault\n");
break;
case EINTR:
printf("eintr\n");
break;
case EINVAL:
printf("einval\n");
break;
case EMFILE:
printf("emfile\n");
break;
case ENFILE:
printf("enfile\n");
break;
case ENOTSOCK:
printf("enotsock\n");
break;
case EOPNOTSUPP:
printf("eOPNOTSUPP\n");
break;
case ENOBUFS:
printf("ENOBUFS\n");
break;
case ENOMEM:
printf("ENOMEM\n");
break;
case ENOSR:
printf("ENOSR\n");
break;
case EPROTO:
printf("EPROTO\n");
break;
default:
printf("unknown error\n");
}
socketDescriptor=-1;
}
else{
inet_ntop(AF_INET, &(clientAddress.sin_addr), dummyClientIP, INET_ADDRSTRLEN);
#ifdef VERY_VERBOSE
cout << "client connected "<< file_des << endl;
#endif
}
}
// file_des = socketDescriptor;
#ifdef VERY_VERBOSE
cout << "fd " << file_des << endl;
#endif
} else {
if (socketDescriptor<=0)
socketDescriptor = socket(AF_INET, getProtocol(),0);
// SetTimeOut(10);
if (socketDescriptor < 0){
cerr << "Can not create socket "<<endl;
file_des = socketDescriptor;
} else {
if(connect(socketDescriptor,(struct sockaddr *) &serverAddress,sizeof(serverAddress))<0){
cerr << "Can not connect to socket "<<endl;
file_des = -1;
} else{
file_des = socketDescriptor;
}
}
}
return file_des;
}
uint16_t getPortNumber(){
return ntohs(serverAddress.sin_port);
}
int getFileDes(){return file_des;};
int getsocketDescriptor(){return socketDescriptor;};
void exitServer(){
if(is_a_server){
if (socketDescriptor>=0){
close(socketDescriptor);
socketDescriptor = -1;
}
}
}
/** @short free connection */
void Disconnect(){
if (protocol==UDP){
close(socketDescriptor);
socketDescriptor=-1;
}
else{
if(file_des>=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));
Disconnect();
};
/** 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';
if(sock!=1){
close(sock);
}
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';
if(sock!=1){
close(sock);
}
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;
}
if (total_sent>0)
strcpy(thisClientIP,dummyClientIP);
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);
if(nsent <1000){
if(nsent < 48){
cout << " "<<dec<<nsent<<" ";
}else{
cout << "nsent: " << dec<<nsent << "\tfnum:" <<
htonl(*(unsigned int*)((eiger_image_header32 *)((char*)(buf)))->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;
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;
#endif
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;
// pthread_mutex_t mp;
};
#endif

View File

@ -0,0 +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 SVNKIND ""
//#define SVNSCHED ""
#define SVNAUTH "Dhanya_Maliakal"
#define SVNREV 0x251
#define SVNDATE 0x20160812
//

View File

@ -0,0 +1,11 @@
//#define SVNPATH ""
#define SVNURL ""
//#define SVNREPPATH ""
#define SVNREPUUID ""
//#define SVNREV ""
//#define SVNKIND ""
//#define SVNSCHED ""
#define SVNAUTH ""
#define SVNREV ""
#define SVNDATE ""
//

View File

@ -0,0 +1,245 @@
//#ifndef __LOG_H__
//#define __LOG_H__
#include <sstream>
#include <string>
#include <stdio.h>
#include <unistd.h>
#include <ansi.h>
#ifdef VERBOSE
#define FILELOG_MAX_LEVEL logDEBUG
#endif
#ifdef VERYVERBOSE
#define FILELOG_MAX_LEVEL logDEBUG4
#endif
#ifdef FIFODEBUG
#define FILELOG_MAX_LEVEL logDEBUG5
#endif
#ifndef FILELOG_MAX_LEVEL
#define FILELOG_MAX_LEVEL logINFO
#endif
#define STRINGIFY(x) #x
#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__)
/*
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, logDEBUG5};
template <typename T> class Log{
public:
Log();
virtual ~Log();
std::ostringstream& Get(TLogLevel level = logINFO);
static TLogLevel& ReportingLevel();
static std::string ToString(TLogLevel level);
static TLogLevel FromString(const std::string& level);
protected:
std::ostringstream os;
TLogLevel lev;
private:
Log(const Log&);
Log& operator =(const Log&);
};
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__)
# 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<Output2FILE> {};
//typedef Log<Output2FILE> 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__)
#include <windows.h>
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 <sys/time.h>
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
template <typename T> Log<T>::Log():lev(logDEBUG){}
template <typename T> std::ostringstream& Log<T>::Get(TLogLevel level)
{
lev = level;
os << "- " << NowTime();
os << " " << ToString(level) << ": ";
os << std::string(level > logDEBUG ? level - logDEBUG : 0, '\t');
return os;
}
template <typename T> Log<T>::~Log()
{
os << std::endl;
#ifdef REST
T::Output( os.str());
#else
T::Output( os.str(),lev);
#endif
}
template <typename T> TLogLevel& Log<T>::ReportingLevel()
{
static TLogLevel reportingLevel = logDEBUG5;
return reportingLevel;
}
template <typename T> std::string Log<T>::ToString(TLogLevel level)
{
static const char* const buffer[] = {"ERROR", "WARNING", "INFO", "DEBUG", "DEBUG1", "DEBUG2", "DEBUG3", "DEBUG4","DEBUG5"};
return buffer[level];
}
template <typename T>
TLogLevel Log<T>::FromString(const std::string& level)
{
if (level == "DEBUG5")
return logDEBUG5;
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<T>().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);
}
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)
# 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__

View File

@ -0,0 +1,197 @@
#ifndef RECEIVER_DEFS_H
#define RECEIVER_DEFS_H
#include "sls_receiver_defs.h"
#include <stdint.h>
/**
* 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 reserved[4];
unsigned char packetNumber[1];
unsigned char frameNumber[3];
unsigned char bunchid[8];
} jfrau_packet_header_t;
#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 4
#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, eiger 20000
#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_ONE_DATA_SIZE 1280
#define GOTTHARD_BUFFER_SIZE (GOTTHARD_ONE_PACKET_SIZE*GOTTHARD_PACKETS_PER_FRAME) //1286*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
#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_ONE_PACKET_SIZE 518
#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 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
#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 (MOENCH_ONE_DATA_SIZE*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 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 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 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
#define JCTB_BYTES_IN_ONE_ROW (JCTB_PIXELS_IN_ONE_ROW*2)
#define EIGER_MAX_PORTS 2
#define EIGER_HEADER_LENGTH 48
#define EIGER_FIFO_SIZE 100
/*#define EIGER_ALIGNED_FRAME_SIZE 65536*/
#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_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 0xFFFFFFFF //32 bit for now
#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)
#define EIGER_PIXELS_IN_ONE_COL (256)
#endif

View File

@ -0,0 +1,91 @@
/********************************************//**
* @file slsReceiver.h
* @short creates the UDP and TCP class objects
***********************************************/
#ifndef SLS_RECEIVER_H
#define SLS_RECEIVER_H
#include "slsReceiverTCPIPInterface.h"
#include "UDPInterface.h"
#include "receiver_defs.h"
#include "MySocketTCP.h"
//#include "utilities.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;
UDPInterface* udp_interface;
};
#endif

View File

@ -0,0 +1,333 @@
/********************************************//**
* @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 "UDPInterface.h"
/**
*@short interface between receiver and client
*/
class slsReceiverTCPIPInterface : private virtual slsReceiverDefs {
public:
/**
* Constructor
* reads config file, creates socket, assigns function table
* @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);
/**
* 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
\returns OK or FAIL
*/
int start();
/** stop listening on the TCP & UDP port for client comminication */
void stop();
/** Destructor */
virtual ~slsReceiverTCPIPInterface();
/** Close all threaded Files and exit */
void closeFile(int p);
/** gets version */
int64_t getReceiverVersion();
//***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);
/**
* 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:
/**
* 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();
/** 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();
/** propix specific read frame */
int propix_read_frame();
/** moench specific read frame */
int moench_read_frame();
/** 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();
/** 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();
/** enable 10Gbe */
int enable_tengiga();
/** set fifo depth */
int set_fifo_depth();
/** activate/ deactivate */
int set_activate();
//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;
/** slsReceiverBase object */
UDPInterface *receiverBase;
/** 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;
/** Dynamic Range */
int dynamicrange;
/** kill tcp server thread */
int killTCPServerThread;
/** thread for TCP server */
pthread_t TCPServer_thread;
/** size of one frame*/
int tenGigaEnable;
/** 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];
//***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;
};
#endif

View File

@ -0,0 +1,91 @@
#ifndef SLS_RECEIVER_USERS_H
#define SLS_RECEIVER_USERS_H
#include <stdio.h>
#include <stdint.h>
class slsReceiver;
/**
@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
\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();
/**
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);
//receiver object
slsReceiver* receiver;
};
#endif

View File

@ -0,0 +1,195 @@
#ifndef SLS_RECEIVER_DEFS_H
#define SLS_RECEIVER_DEFS_H
#ifdef __CINT__
#define MYROOT
#define __cplusplus
#endif
#include <stdint.h>
#ifdef __cplusplus
#include <string>
#endif
#include "ansi.h"
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
#define EIGER_MAX_FRAMES_PER_FILE 2000
#define JFRAU_MAX_FRAMES_PER_FILE 2000
#define JFCTB_MAX_FRAMES_PER_FILE 100000
/**
\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 */
JUNGFRAU, /**< jungfrau */
JUNGFRAUCTB, /**< jungfrauCTBversion */
PROPIX /**< propix */
};
/**
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,
FRAMES_FROM_START,
FRAMES_FROM_START_PG,
SAMPLES_JCTB,
SUBFRAME_ACQUISITION_TIME, /**< subframe exposure time */
MAX_TIMERS
};
/**
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 */
STOPPED /**< acquisition stopped externally */
};
#ifdef __cplusplus
/** returns string from enabled/disabled
\param b true or false
\returns string enabled, disabled
*/
static std::string stringEnable(bool b){\
if(b) return std::string("enabled"); \
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"); \
case STOPPED: return std::string("stopped"); \
default: return std::string("idle"); \
}};
#endif
#ifdef __cplusplus
protected:
#endif
#ifndef MYROOT
#include "sls_receiver_funcs.h"
#endif
#ifdef __cplusplus
};
#endif
;
#endif
;

View File

@ -0,0 +1,60 @@
/**
@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=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 */
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 */
F_ENABLE_RECEIVER_TEN_GIGA, /**< enable 10Gbe in receiver */
F_SET_RECEIVER_FIFO_DEPTH, /**< set receiver fifo depth */
F_ACTIVATE /** < activate/deactivate readout */
/* Always append functions hereafter!!! */
};
#endif
/** @endinternal */

View File

@ -0,0 +1,15 @@
#include <iostream>
#include <string>
#include <sstream>
#include <iostream>
#include <map>
using namespace std;
#include "sls_receiver_defs.h"
/* uncomment next line to enable debug output */
//#define EIGER_DEBUG
int read_config_file(string fname, int *tcpip_port_no, map<string, string> * configuration_map);

View File

@ -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

View File

@ -0,0 +1,51 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?fileVersion 4.0.0?>
<cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
<storageModule moduleId="org.eclipse.cdt.core.settings">
<cconfiguration id="0.1592123610">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="0.1592123610" moduleId="org.eclipse.cdt.core.settings" name="Default">
<externalSettings/>
<extensions>
<extension id="org.eclipse.cdt.core.VCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
</extensions>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration buildProperties="" description="" id="0.1592123610" name="Default" parent="org.eclipse.cdt.build.core.prefbase.cfg">
<folderInfo id="0.1592123610." name="/" resourcePath="">
<toolChain id="org.eclipse.cdt.build.core.prefbase.toolchain.2043853512" name="No ToolChain" resourceTypeBasedDiscovery="false" superClass="org.eclipse.cdt.build.core.prefbase.toolchain">
<targetPlatform id="org.eclipse.cdt.build.core.prefbase.toolchain.2043853512.1428560959" name=""/>
<builder id="org.eclipse.cdt.build.core.settings.default.builder.1228246701" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" superClass="org.eclipse.cdt.build.core.settings.default.builder"/>
<tool id="org.eclipse.cdt.build.core.settings.holder.libs.891716849" name="holder for library settings" superClass="org.eclipse.cdt.build.core.settings.holder.libs"/>
<tool id="org.eclipse.cdt.build.core.settings.holder.1775606856" name="Assembly" superClass="org.eclipse.cdt.build.core.settings.holder">
<inputType id="org.eclipse.cdt.build.core.settings.holder.inType.98773194" languageId="org.eclipse.cdt.core.assembly" languageName="Assembly" sourceContentType="org.eclipse.cdt.core.asmSource" superClass="org.eclipse.cdt.build.core.settings.holder.inType"/>
</tool>
<tool id="org.eclipse.cdt.build.core.settings.holder.41809089" name="GNU C++" superClass="org.eclipse.cdt.build.core.settings.holder">
<inputType id="org.eclipse.cdt.build.core.settings.holder.inType.817253715" languageId="org.eclipse.cdt.core.g++" languageName="GNU C++" sourceContentType="org.eclipse.cdt.core.cxxSource,org.eclipse.cdt.core.cxxHeader" superClass="org.eclipse.cdt.build.core.settings.holder.inType"/>
</tool>
<tool id="org.eclipse.cdt.build.core.settings.holder.1467561536" name="GNU C" superClass="org.eclipse.cdt.build.core.settings.holder">
<inputType id="org.eclipse.cdt.build.core.settings.holder.inType.210475521" languageId="org.eclipse.cdt.core.gcc" languageName="GNU C" sourceContentType="org.eclipse.cdt.core.cSource,org.eclipse.cdt.core.cHeader" superClass="org.eclipse.cdt.build.core.settings.holder.inType"/>
</tool>
</toolChain>
</folderInfo>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
</cconfiguration>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<project id="slsReceiver.null.670781774" name="slsReceiver"/>
</storageModule>
<storageModule moduleId="scannerConfiguration">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
<scannerConfigBuildInfo instanceId="0.1592123610">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</scannerConfigBuildInfo>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
</cproject>

View File

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>Receiver</name>
<comment></comment>
<projects>
<project>newMythenSoftware</project>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
<triggers>clean,full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
<triggers>full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.cdt.core.cnature</nature>
<nature>org.eclipse.cdt.core.ccnature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
</natures>
</projectDescription>

View File

@ -0,0 +1,53 @@
//version 1.0, base development, Ian 19/01/09
#include "MySocketTCP.h"
#include <string.h>
#include <iostream>
#include <cstdio>
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;
}

View File

@ -0,0 +1,480 @@
//#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 "genericSocket.h"
#include <sys/stat.h> // stat
#include <iostream>
#include <string.h>
using namespace std;
/*************************************************************************
* Constructor & Destructor **********************************************
* They access local cache of configuration or detector parameters *******
*************************************************************************/
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";
FILE_LOG(logDEBUG) << "Info: Initializing base members";
//**detector parameters***
myDetectorType = GENERIC;
strcpy(detHostname,"");
packetsPerFrame = 0;
acquisitionPeriod = 0;
numberOfFrames = 0;
dynamicRange = 16;
tengigaEnable = false;
fifoDepth = 0;
bottomEnable = false;
//***receiver parameters***
status = IDLE;
activated = true;
//***connection parameters***
strcpy(eth,"");
for(int i=0;i<MAX_NUMBER_OF_LISTENING_THREADS;i++){
udpPortNum[i] = DEFAULT_UDP_PORTNO + i;
}
//***file parameters***
strcpy(fileName,"run");
strcpy(filePath,"");
fileIndex = 0;
scanTag = 0;
frameIndexEnable = false;
fileWriteEnable = true;
overwriteEnable = true;
dataCompressionEnable = false;
//***acquisition count parameters***
totalPacketsCaught = 0;
packetsCaught = 0;
//***acquisition indices parameters***
acquisitionIndex = 0;
//***acquisition parameters***
shortFrameEnable = -1;
FrameToGuiFrequency = 0;
}
UDPBaseImplementation::~UDPBaseImplementation(){}
/*************************************************************************
* 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;
}
/***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";
//not initialized
if(!strlen(filePath))
return NULL;
char* output = new char[MAX_STR_LENGTH];
strcpy(output,filePath);
//freed by calling function
return output;
}
uint64_t UDPBaseImplementation::getFileIndex() const{ FILE_LOG(logDEBUG) << __AT__ << " starting"; return fileIndex;}
int UDPBaseImplementation::getScanTag() const{ FILE_LOG(logDEBUG) << __AT__ << " starting"; return scanTag;}
bool UDPBaseImplementation::getFrameIndexEnable() const{ FILE_LOG(logDEBUG) << __AT__ << " starting"; return frameIndexEnable;}
bool UDPBaseImplementation::getFileWriteEnable() const{ FILE_LOG(logDEBUG) << __AT__ << " starting"; return fileWriteEnable;}
bool UDPBaseImplementation::getOverwriteEnable() const{ FILE_LOG(logDEBUG) << __AT__ << " starting"; return overwriteEnable;}
bool UDPBaseImplementation::getDataCompressionEnable() const{ FILE_LOG(logDEBUG) << __AT__ << " starting"; return dataCompressionEnable;}
/***acquisition count parameters***/
uint64_t UDPBaseImplementation::getTotalFramesCaught() const{ FILE_LOG(logDEBUG) << __AT__ << " starting"; return (totalPacketsCaught/packetsPerFrame);}
uint64_t UDPBaseImplementation::getFramesCaught() const{ FILE_LOG(logDEBUG) << __AT__ << " starting"; return (packetsCaught/packetsPerFrame);}
int64_t UDPBaseImplementation::getAcquisitionIndex() const{
FILE_LOG(logDEBUG) << __AT__ << " starting";
if(!totalPacketsCaught)
return -1;
return acquisitionIndex;
}
/***connection parameters***/
uint32_t UDPBaseImplementation::getUDPPortNumber() const{ FILE_LOG(logDEBUG) << __AT__ << " starting"; return udpPortNum[0];}
uint32_t UDPBaseImplementation::getUDPPortNumber2() const{ FILE_LOG(logDEBUG) << __AT__ << " starting"; return udpPortNum[1];}
char *UDPBaseImplementation::getEthernetInterface() const{
FILE_LOG(logDEBUG) << __AT__ << " starting";
char* output = new char[MAX_STR_LENGTH];
strcpy(output,eth);
//freed by calling function
return output;
}
/***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;}
uint64_t UDPBaseImplementation::getAcquisitionPeriod() const{ FILE_LOG(logDEBUG) << __AT__ << " starting"; return acquisitionPeriod;}
uint64_t UDPBaseImplementation::getNumberOfFrames() const{ FILE_LOG(logDEBUG) << __AT__ << " starting"; return numberOfFrames;}
uint32_t UDPBaseImplementation::getDynamicRange() const{ FILE_LOG(logDEBUG) << __AT__ << " starting"; return dynamicRange;}
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;}
int UDPBaseImplementation::getActivate() const{FILE_LOG(logDEBUG) << __AT__ << " starting"; return activated;}
/*************************************************************************
* Setters ***************************************************************
* They modify the local cache of configuration or detector parameters ***
*************************************************************************/
/**initial parameters***/
void UDPBaseImplementation::configure(map<string, string> config_map){
FILE_LOG(logWARNING) << __AT__ << " doing nothing...";
FILE_LOG(logERROR) << __AT__ << " must be overridden by child classes";
}
void UDPBaseImplementation::setBottomEnable(const bool b){
FILE_LOG(logDEBUG) << __AT__ << " starting";
bottomEnable = b;
FILE_LOG(logINFO) << "Bottom - " << stringEnable(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;
if(stat(c,&st) == 0)
strcpy(filePath,c);
else{
strcpy(filePath,"");
FILE_LOG(logWARNING) << "FilePath does not exist:" << filePath;
}
strcpy(filePath, c);
}
FILE_LOG(logDEBUG) << "Info: File path:" << filePath;
}
void UDPBaseImplementation::setFileIndex(const uint64_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: " << stringEnable(frameIndexEnable);
}
void UDPBaseImplementation::setFileWriteEnable(const bool b){
FILE_LOG(logDEBUG) << __AT__ << " starting";
fileWriteEnable = b;
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: " << stringEnable(overwriteEnable);
}
int UDPBaseImplementation::setDataCompressionEnable(const bool b){
FILE_LOG(logDEBUG) << __AT__ << " starting";
dataCompressionEnable = b;
FILE_LOG(logINFO) << "Data Compression : " << stringEnable(dataCompressionEnable);
//overridden methods might return FAIL
return OK;
}
/***connection parameters***/
void UDPBaseImplementation::setUDPPortNumber(const uint32_t i){
FILE_LOG(logDEBUG) << __AT__ << " starting";
udpPortNum[0] = i;
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) << "UDP Port Number[1]:" << udpPortNum[1];
}
void UDPBaseImplementation::setEthernetInterface(const char* c){
FILE_LOG(logDEBUG) << __AT__ << " starting";
strcpy(eth, c);
FILE_LOG(logINFO) << "Ethernet Interface: " << eth;
}
/***acquisition parameters***/
void UDPBaseImplementation::setShortFrameEnable(const int i){
FILE_LOG(logDEBUG) << __AT__ << " starting";
shortFrameEnable = i;
FILE_LOG(logINFO) << "Short Frame Enable: " << stringEnable(shortFrameEnable);
}
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;
}
int UDPBaseImplementation::setAcquisitionPeriod(const uint64_t i){
FILE_LOG(logDEBUG) << __AT__ << " starting";
acquisitionPeriod = i;
FILE_LOG(logINFO) << "Acquisition Period:" << (double)acquisitionPeriod/(1E9) << "s";
//overrridden child classes might return FAIL
return OK;
}
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){
FILE_LOG(logDEBUG) << __AT__ << " starting";
dynamicRange = i;
FILE_LOG(logINFO) << "Dynamic Range:" << dynamicRange;
//overrridden child classes might return FAIL
return OK;
}
int UDPBaseImplementation::setTenGigaEnable(const bool b){
FILE_LOG(logDEBUG) << __AT__ << " starting";
tengigaEnable = b;
FILE_LOG(logINFO) << "Ten Giga Enable: " << stringEnable(tengigaEnable);
//overridden functions might return FAIL
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***************************************************
* They may modify the status of the receiver ****************************
*************************************************************************/
/***initial functions***/
int UDPBaseImplementation::setDetectorType(const detectorType d){
FILE_LOG(logDEBUG) << __AT__ << " starting";
myDetectorType = d;
//if eiger, set numberofListeningThreads = 2;
FILE_LOG(logINFO) << "Detector Type:" << getDetectorType(d);
return OK;
}
void UDPBaseImplementation::initialize(const char *c){
FILE_LOG(logDEBUG) << __AT__ << " starting";
if(strlen(c))
strcpy(detHostname, c);
FILE_LOG(logINFO) << "Detector Hostname:" << detHostname;
}
/***acquisition functions***/
void UDPBaseImplementation::resetAcquisitionCount(){
FILE_LOG(logDEBUG) << __AT__ << " starting";
totalPacketsCaught = 0;
FILE_LOG(logINFO) << "totalPacketsCaught:" << totalPacketsCaught;
}
int UDPBaseImplementation::startReceiver(char *c){
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";
//overridden functions might return FAIL
return OK;
}
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";
}
void UDPBaseImplementation::closeFile(int i){
FILE_LOG(logWARNING) << __AT__ << " doing nothing...";
FILE_LOG(logERROR) << __AT__ << " must be overridden by child classes";
}
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;
pStartAcquisition=arg;
}
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;
}
//#endif

View File

@ -0,0 +1,41 @@
//#ifdef SLS_RECEIVER_UDP_FUNCTIONS
/********************************************//**
* @file slsReceiverUDPFunctions.cpp
* @short does all the functions for a receiver, set/get parameters, start/stop etc.
***********************************************/
#include <iostream>
#include <string.h>
using namespace std;
#include "UDPInterface.h"
#include "UDPBaseImplementation.h"
#include "UDPStandardImplementation.h"
#ifdef REST
#include "UDPRESTImplementation.h"
#endif
using namespace std;
UDPInterface * UDPInterface::create(string receiver_type){
if (receiver_type == "standard"){
FILE_LOG(logINFO) << "Starting " << receiver_type;
return new UDPStandardImplementation();
}
#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();
}
}
//#endif

View File

@ -0,0 +1,331 @@
#ifdef SLS_RECEIVER_UDP_FUNCTIONS
/********************************************//**
* @file UDPRESTImplementation.cpp
* @short does all the functions for a receiver, set/get parameters, start/stop etc.
***********************************************/
#include "UDPRESTImplementation.h"
#include <stdlib.h> // exit()
#include <iomanip> // set precision
#include <map> // map
#include <iostream>
#include <string.h>
#include <stdint.h>
#include <sstream>
//#include "utilities.h"
using namespace std;
/*
TODO
+ filePath != getFilePath
+ better state handling. Now it is only IDLE - RUNNING - IDLE
*/
UDPRESTImplementation::UDPRESTImplementation(){
FILE_LOG(logDEBUG) << "PID: " << getpid() << __AT__ << " called";
//TODO I do not really know what to do with bottom...
// Default values
isInitialized = false;
rest = NULL;
rest_hostname = "localhost";
rest_port = 8081;
}
UDPRESTImplementation::~UDPRESTImplementation(){
delete rest;
}
void UDPRESTImplementation::configure(map<string, string> config_map){
FILE_LOG(logWARNING) << __AT__ << " called";
map<string, string>::const_iterator pos;
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);
}
}
/*
for(map<string, string>::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){
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";
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";
}
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 = 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;
*/
}
FILE_LOG(logDEBUG) << __func__ << ": initialize() done";
}
/** acquisition functions */
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;
return OK;
}
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";
// this is just to be sure, it could be removed
for(int i=0;i<numListeningThreads;i++){
if(udpSocket[i]){
FILE_LOG(logDEBUG) << __AT__ << " closing UDP socket #" << i;
udpSocket[i]->ShutDownSocket();
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
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 <<code << " " << answer << std::endl;
code = rest->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;
//LEO: not sure it's needed
delete rest;
FILE_LOG(logDEBUG) << __AT__ << "finished";
return OK;
}
/* 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";
strcpy(c,"");
*raw = NULL;
}
/* FIXME
* Its called by TCP in case of illegal shut down such as Ctrl + c.
* Upto you what you want to do with it.
*/
void UDPRESTImplementation::closeFile(int ithr){
FILE_LOG(logDEBUG) << __AT__ << "called for thread " << ithr;
FILE_LOG(logDEBUG) << __AT__ << "exited for thread " << ithr;
}
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,48 @@
/* 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 <iostream>
#include <string.h>
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;
udp->startReceiver();
if(udp)
delete udp;
return 0;
}

View File

@ -0,0 +1,118 @@
/* 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 <iostream>
#include <string.h>
#include <signal.h> //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 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
signal(SIGINT,closeFile);
int ret = slsReceiverDefs::OK;
receiver = new slsReceiverUsers(argc, argv, ret);
if(ret==slsReceiverDefs::FAIL){
deleteReceiver(receiver);
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(startAcquisitionCallBack,NULL);
/**
callback argument is
total farmes caught
registerCallBackAcquisitionFinished(void (*func)(int, void*),void *arg);
*/
//receiver->registerCallBackAcquisitionFinished(acquisitionFinishedCallBack,NULL);
/**
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(rawDataReadyCallBack,NULL);
//start tcp server thread
if(receiver->start() == slsReceiverDefs::OK){
FILE_LOG(logDEBUG1) << "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
receiver->stop();
}
deleteReceiver(receiver);
cout << "Goodbye!" << endl;
return 0;
}

View File

@ -0,0 +1,200 @@
/********************************************//**
* @file slsReceiver.cpp
* @short creates the UDP and TCP class objects
***********************************************/
#include <iostream>
#include <string>
#include <sstream>
#include <fstream>
#include <stdlib.h>
#include <map>
#include <getopt.h>
#include "slsReceiver.h"
//#include "UDPInterface.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
*/
udp_interface = NULL;
tcpipInterface = NULL;
//creating base receiver
map<string, string> configuration_map;
int tcpip_port_no = 1954;
success=OK;
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
static struct option long_options[] = {
/* These options set a flag. */
//{"verbose", no_argument, &verbose_flag, 1},
/* These options dont 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'},
{"rest_hostname", required_argument, 0, 'r'},
{"help", no_argument, 0, 'h'},
{0, 0, 0, 0}
};
/* getopt_long stores the option index here. */
int option_index = 0;
int c=0;
optind = 1;
while ( c != -1 ){
c = getopt_long (argc, argv, "mbfhtr", long_options, &option_index);
/* Detect the end of the options. */
if (c == -1)
break;
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;
break;
case 'b':
sscanf(optarg, "%d", &tcpip_port_no);
break;
case 't':
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--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""";
help_message += """\t--type:\t Type of the receiver. Possible arguments are: standard, REST. Default: standard.\n\n""";
cout << help_message << endl;
break;
}
}
// if required fname parameter not available, fail
//if (fname == "")
// success = FAIL;
if( !fname.empty() ){
try{
FILE_LOG(logINFO) << "config file name " << fname;
success = read_config_file(fname, &tcpip_port_no, &configuration_map);
//VERBOSE_PRINT("Read configuration file of " + iline + " lines");
}
catch(...){
FILE_LOG(logERROR) << "Error opening configuration file " << fname ;
success = FAIL;
}
}
if(success != OK){
FILE_LOG(logERROR) << "Failed: see output above for more information " ;
}
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);
}
}
slsReceiver::~slsReceiver() {
if(udp_interface)
delete udp_interface;
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(){
return tcpipInterface->getReceiverVersion();
}
void slsReceiver::registerCallBackStartAcquisition(int (*func)(char*, char*,int, int, void*),void *arg){
//tcpipInterface
if(udp_interface)
udp_interface->registerCallBackStartAcquisition(func,arg);
else
tcpipInterface->registerCallBackStartAcquisition(func,arg);
}
void slsReceiver::registerCallBackAcquisitionFinished(void (*func)(int, void*),void *arg){
//tcpipInterface
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
if(udp_interface)
udp_interface->registerCallBackRawDataReady(func,arg);
else
tcpipInterface->registerCallBackRawDataReady(func,arg);
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,45 @@
#include "slsReceiverUsers.h"
#include "slsReceiver.h"
slsReceiverUsers::slsReceiverUsers(int argc, char *argv[], int &success) {
receiver=new slsReceiver(argc, argv, success);
}
slsReceiverUsers::~slsReceiverUsers() {
delete receiver;
}
int slsReceiverUsers::start() {
return receiver->start();
}
void slsReceiverUsers::stop() {
receiver->stop();
}
void slsReceiverUsers::closeFile(int p) {
receiver->closeFile(p);
}
int64_t slsReceiverUsers::getReceiverVersion(){
return receiver->getReceiverVersion();
}
void slsReceiverUsers::registerCallBackStartAcquisition(int (*func)(char*, char*,int, int, void*),void *arg){
receiver->registerCallBackStartAcquisition(func,arg);
}
void slsReceiverUsers::registerCallBackAcquisitionFinished(void (*func)(int, void*),void *arg){
receiver->registerCallBackAcquisitionFinished(func,arg);
}
void slsReceiverUsers::registerCallBackRawDataReady(void (*func)(int, char*, int, FILE*, char*, void*),void *arg){
receiver->registerCallBackRawDataReady(func,arg);
}

View File

@ -0,0 +1,74 @@
#include <iostream>
#include <string>
#include <sstream>
#include <iostream>
#include <stdio.h>
#include <fstream>
#include <map>
#include "utilities.h"
using namespace std;
int read_config_file(string fname, int *tcpip_port_no, map<string, string> * configuration_map ){
ifstream infile;
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()){
getline(infile,sLine);
iline++;
//VERBOSE_PRINT(sLine);
if(sLine.find('#') != string::npos)
continue;
else if(sLine.length()<2)
continue;
else{
istringstream sstr(sLine);
//parameter name
if(sstr.good()){
sstr >> sargname;
if (! sstr.good())
continue;
sstr >> sargvalue;
(*configuration_map)[sargname] = sargvalue;
}
//tcp port
if(sargname=="rx_tcpport"){
if(sstr.good()) {
sstr >> sargname;
if(sscanf(sargname.c_str(),"%d",tcpip_port_no))
cout<<"dataport:"<<tcpip_port_no<<endl;
else{
cout << "could not decode port in config file. Exiting." << endl;
success = slsReceiverDefs::FAIL;
}
}
}
}
}
infile.close();
}
return success;
}

View File

@ -0,0 +1,31 @@
//version 1.0, base development ij 19/01/09
#include <iostream>
#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 :"<<sock->ReceiveDataAndKeepConnection(data,23000)<<endl;
cout<<"\tReceived :"<<sock->ReceiveData(data,32200)<<endl;
cout<<"\tReceived :"<<sock->ReceiveData(data,33300)<<endl;
cout<<"\tReceived :"<<sock->ReceiveData(data,30000)<<endl;
cout<<"\tReceived :"<<sock->ReceiveData(data,3222)<<endl;
delete sock;
return 0;
}

View File

@ -0,0 +1,40 @@
//version 1.0, base development ij 19/01/09
#include <iostream>
#include "MySocketTCP.h"
using namespace std;
int main(int argc, char *argv[]){
if(argc!=2){
cout<<"Usage: send ip_addess/hostName"<<endl;
return 1;
}
cout<<"rec function must be first called."<<endl;
char ip_address[200];
sprintf(ip_address,"%s",argv[1]);
unsigned short int portnum = 1952;
char data[50000];
int length=50000;
MySocketTCP* sock = new MySocketTCP(ip_address,portnum);
cout<<"\tSending :"<<sock->SendDataAndKeepConnection(data,2000)<<endl;
cout<<"\tSending :"<<sock->SendData(data,2200)<<endl;
cout<<"\tSending :"<<sock->SendData(data,1200)<<endl;
cout<<"\tSending :"<<sock->SendData(data,25000)<<endl;
cout<<"\tSending :"<<sock->SendData(data,222)<<endl;
delete sock;
return 0;
}