mirror of
https://github.com/slsdetectorgroup/slsDetectorPackage.git
synced 2025-06-13 05:17:13 +02:00
updated documentation
This commit is contained in:
18
exampleCode/customReceiverExample/Makefile
Executable file
18
exampleCode/customReceiverExample/Makefile
Executable file
@ -0,0 +1,18 @@
|
||||
INCLUDES = -I .
|
||||
SRC_REC = dummyMain.cpp
|
||||
LDFLAG_REC = -L. -lSlsReceiver -L/usr/lib64/ -lpthread -lrt -L. -lzmq
|
||||
DESTDIR ?= ../docs
|
||||
|
||||
all: dummyReceiver
|
||||
|
||||
|
||||
dummyReceiver:$(SRC_REC)
|
||||
echo "creating receiver"
|
||||
g++ -o dummyReceiver $(SRC_REC) $(INCLUDES) $(LDFLAG_REC) -lm -lstdc++
|
||||
|
||||
|
||||
clean:
|
||||
echo "cleaning"
|
||||
rm -rf dummyReceiver
|
||||
|
||||
|
67
exampleCode/customReceiverExample/MySocketTCP.h
Executable file
67
exampleCode/customReceiverExample/MySocketTCP.h
Executable file
@ -0,0 +1,67 @@
|
||||
#pragma once
|
||||
/**
|
||||
*
|
||||
* @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;
|
||||
|
||||
|
||||
};
|
||||
|
730
exampleCode/customReceiverExample/UDPBaseImplementation.h
Executable file
730
exampleCode/customReceiverExample/UDPBaseImplementation.h
Executable file
@ -0,0 +1,730 @@
|
||||
#pragma once
|
||||
/********************************************//**
|
||||
* @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 multi detector size
|
||||
* @return pointer to array of multi detector size in every dimension
|
||||
*/
|
||||
int* getMultiDetectorSize() const;
|
||||
|
||||
|
||||
/*
|
||||
* Get detector position id
|
||||
* @return detector position id
|
||||
*/
|
||||
int getDetectorPositionId() const;
|
||||
|
||||
/*
|
||||
* Get detector hostname
|
||||
* @return NULL or hostname or NULL if uninitialized (max of 1000 characters)
|
||||
*/
|
||||
char *getDetectorHostname() const;
|
||||
|
||||
/*
|
||||
* Get flipped data across 'axis'
|
||||
* @return if data is flipped across 'axis'
|
||||
*/
|
||||
int getFlippedData(int axis=0) const;
|
||||
|
||||
|
||||
//***file parameters***
|
||||
/**
|
||||
* Get File Format
|
||||
* @return file format
|
||||
*/
|
||||
fileFormat getFileFormat() const;
|
||||
/**
|
||||
* 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 -1 if no frames have been caught, else 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;
|
||||
|
||||
/**
|
||||
* Gets the timer between frames streamed when frequency is set to 0
|
||||
* @return timer between frames streamed
|
||||
*/
|
||||
uint32_t getFrameToGuiTimer() const;
|
||||
|
||||
/**
|
||||
* Get the data stream enable
|
||||
* @return data stream enable
|
||||
*/
|
||||
bool getDataStreamEnable() const;
|
||||
|
||||
|
||||
/**
|
||||
* Get Acquisition Period
|
||||
* @return acquisition period
|
||||
*/
|
||||
uint64_t getAcquisitionPeriod() const;
|
||||
|
||||
/**
|
||||
* Get Acquisition Time
|
||||
* @return acquisition time
|
||||
*/
|
||||
uint64_t getAcquisitionTime() const;
|
||||
|
||||
/**
|
||||
* Get Sub Exposure Time
|
||||
* @return Sub Exposure Time
|
||||
*/
|
||||
uint64_t getSubExpTime() 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 Silent Mode
|
||||
* @return silent mode
|
||||
*/
|
||||
uint32_t getSilentMode() 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;
|
||||
|
||||
/**
|
||||
* Get Streaming Port
|
||||
* @return streaming port
|
||||
*/
|
||||
uint32_t getStreamingPort() 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 multi detector size
|
||||
* @param pointer to array of multi detector size in every dimension
|
||||
*/
|
||||
void setMultiDetectorSize(const int* size);
|
||||
|
||||
/*
|
||||
* Get flipped data across 'axis'
|
||||
* @return if data is flipped across 'axis'
|
||||
*/
|
||||
void setFlippedData(int axis=0, int enable=-1);
|
||||
|
||||
|
||||
//***file parameters***
|
||||
/**
|
||||
* Set File Format
|
||||
* @param f fileformat binary or hdf5
|
||||
*/
|
||||
void setFileFormat(slsReceiverDefs::fileFormat f);
|
||||
|
||||
/**
|
||||
* 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 exists, it sets it
|
||||
* @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
|
||||
* @return OK or FAIL
|
||||
*/
|
||||
int setShortFrameEnable(const int i);
|
||||
|
||||
/**
|
||||
* Set the Frequency of Frames Sent to GUI
|
||||
* @param freq 0 for random frame requests, n for nth frame frequency
|
||||
* @return OK or FAIL
|
||||
*/
|
||||
int setFrameToGuiFrequency(const uint32_t freq);
|
||||
|
||||
/**
|
||||
* Sets the timer between frames streamed when frequency is set to 0
|
||||
* @param time_in_ms timer between frames streamed
|
||||
*/
|
||||
void setFrameToGuiTimer(const uint32_t time_in_ms);
|
||||
|
||||
/**
|
||||
* Set the data stream enable
|
||||
* @param enable data stream enable
|
||||
* @return OK or FAIL
|
||||
*/
|
||||
int setDataStreamEnable(const bool enable);
|
||||
|
||||
/**
|
||||
* Set Acquisition Period
|
||||
* @param i acquisition period
|
||||
* @return OK or FAIL
|
||||
*/
|
||||
int setAcquisitionPeriod(const uint64_t i);
|
||||
|
||||
/**
|
||||
* Set Acquisition Time
|
||||
* @param i acquisition time
|
||||
* @return OK or FAIL
|
||||
*/
|
||||
int setAcquisitionTime(const uint64_t i);
|
||||
|
||||
/**
|
||||
* Set Sub Exposure Time
|
||||
* @param i Sub Exposure Time
|
||||
* @return OK or FAIL
|
||||
*/
|
||||
void setSubExpTime(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);
|
||||
|
||||
//***receiver parameters***
|
||||
/**
|
||||
* Set Silent Mode
|
||||
* @param i silent mode. 1 sets, 0 unsets
|
||||
*/
|
||||
void setSilentMode(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);
|
||||
|
||||
/**
|
||||
* Set detector position id
|
||||
* @param i position id
|
||||
*/
|
||||
void setDetectorPositionId(const int i);
|
||||
|
||||
/**
|
||||
* Sets detector hostname
|
||||
* It is second function called by the client when connecting to receiver.
|
||||
* you can call this function only once.
|
||||
* @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
|
||||
*/
|
||||
void shutDownUDPSockets();
|
||||
|
||||
/**
|
||||
* Get the buffer-current frame read by receiver
|
||||
* @param ithread port thread index
|
||||
* @param c pointer to current file name
|
||||
* @param raw address of pointer, pointing to current frame to send to gui
|
||||
* @param startAcq start index of the acquisition
|
||||
* @param startFrame start index of the scan
|
||||
*/
|
||||
void readFrame(int ithread, char* c,char** raw, int64_t &startAcq, int64_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?
|
||||
|
||||
/**
|
||||
* Activate / Deactivate Receiver
|
||||
* If deactivated, receiver will write dummy packets 0xFF
|
||||
* (as it will receive nothing from detector)
|
||||
*/
|
||||
int setActivate(int enable = -1);
|
||||
|
||||
/**
|
||||
* Set streaming port
|
||||
* @param i streaming port
|
||||
*/
|
||||
void setStreamingPort(const uint32_t i);
|
||||
|
||||
/**
|
||||
* Restream stop dummy packet from receiver
|
||||
* @return OK or FAIL
|
||||
*/
|
||||
int restreamStop();
|
||||
|
||||
//***callback functions***
|
||||
/**
|
||||
* Call back for start acquisition
|
||||
* callback arguments are
|
||||
* filepath
|
||||
* filename
|
||||
* fileindex
|
||||
* datasize
|
||||
*
|
||||
* return value is insignificant at the moment
|
||||
* we write depending on file write enable
|
||||
* users get data to write depending on call backs registered
|
||||
*/
|
||||
void registerCallBackStartAcquisition(int (*func)(char*, char*, uint64_t, uint32_t, void*),void *arg);
|
||||
|
||||
/**
|
||||
* Call back for acquisition finished
|
||||
* callback argument is
|
||||
* total frames caught
|
||||
*/
|
||||
void registerCallBackAcquisitionFinished(void (*func)(uint64_t, void*),void *arg);
|
||||
|
||||
/**
|
||||
* Call back for raw data
|
||||
* args to raw data ready callback are
|
||||
* frameNumber is the frame number
|
||||
* expLength is the subframe number (32 bit eiger) or real time exposure time in 100ns (others)
|
||||
* packetNumber is the packet number
|
||||
* bunchId is the bunch id from beamline
|
||||
* timestamp is the time stamp with 10 MHz clock
|
||||
* modId is the unique module id (unique even for left, right, top, bottom)
|
||||
* xCoord is the x coordinate in the complete detector system
|
||||
* yCoord is the y coordinate in the complete detector system
|
||||
* zCoord is the z coordinate in the complete detector system
|
||||
* debug is for debugging purposes
|
||||
* roundRNumber is the round robin set number
|
||||
* detType is the detector type see :: detectorType
|
||||
* version is the version number of this structure format
|
||||
* dataPointer is the pointer to the data
|
||||
* dataSize in bytes is the size of the data in bytes
|
||||
*/
|
||||
void registerCallBackRawDataReady(void (*func)(uint64_t, uint32_t, uint32_t, uint64_t, uint64_t, uint16_t, uint16_t, uint16_t, uint16_t, uint32_t, uint16_t, uint8_t, uint8_t,
|
||||
char*, uint32_t, void*),void *arg);
|
||||
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
/*************************************************************************
|
||||
* Class Members *********************************************************
|
||||
*************************************************************************/
|
||||
//**detector parameters***
|
||||
/** detector type */
|
||||
detectorType myDetectorType;
|
||||
/** Number of Detectors in each dimension direction */
|
||||
int numDet[MAX_DIMENSIONS];
|
||||
/*Detector Readout ID*/
|
||||
int detID;
|
||||
/** detector hostname */
|
||||
char detHostname[MAX_STR_LENGTH];
|
||||
/** Acquisition Period */
|
||||
uint64_t acquisitionPeriod;
|
||||
/** Acquisition Time */
|
||||
uint64_t acquisitionTime;
|
||||
/** Sub Exposure Time */
|
||||
uint64_t subExpTime;
|
||||
/** Frame Number */
|
||||
uint64_t numberOfFrames;
|
||||
/** Dynamic Range */
|
||||
uint32_t dynamicRange;
|
||||
/** Ten Giga Enable*/
|
||||
bool tengigaEnable;
|
||||
/** Fifo Depth */
|
||||
uint32_t fifoDepth;
|
||||
/** enable for flipping data across both axes */
|
||||
int flippedData[2];
|
||||
|
||||
//***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 format */
|
||||
fileFormat fileFormatType;
|
||||
/** 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 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;
|
||||
/** Timer of Frames sent to GUI when frequency is 0 */
|
||||
uint32_t frameToGuiTimerinMS;
|
||||
/** Data Stream Enable from Receiver */
|
||||
bool dataStreamEnable;
|
||||
/** streaming port */
|
||||
uint32_t streamingPort;
|
||||
|
||||
//***receiver parameters***
|
||||
uint32_t silentMode;
|
||||
|
||||
|
||||
//***callback parameters***
|
||||
/**
|
||||
* Call back for start acquisition
|
||||
* callback arguments are
|
||||
* filepath
|
||||
* filename
|
||||
* fileindex
|
||||
* datasize
|
||||
*
|
||||
* return value is insignificant at the moment
|
||||
* we write depending on file write enable
|
||||
* users get data to write depending on call backs registered
|
||||
*/
|
||||
int (*startAcquisitionCallBack)(char*, char*, uint64_t, uint32_t, void*);
|
||||
void *pStartAcquisition;
|
||||
|
||||
/**
|
||||
* Call back for acquisition finished
|
||||
* callback argument is
|
||||
* total frames caught
|
||||
*/
|
||||
void (*acquisitionFinishedCallBack)(uint64_t, void*);
|
||||
void *pAcquisitionFinished;
|
||||
|
||||
|
||||
/**
|
||||
* Call back for raw data
|
||||
* args to raw data ready callback are
|
||||
* frameNumber is the frame number
|
||||
* expLength is the subframe number (32 bit eiger) or real time exposure time in 100ns (others)
|
||||
* packetNumber is the packet number
|
||||
* bunchId is the bunch id from beamline
|
||||
* timestamp is the time stamp with 10 MHz clock
|
||||
* modId is the unique module id (unique even for left, right, top, bottom)
|
||||
* xCoord is the x coordinate in the complete detector system
|
||||
* yCoord is the y coordinate in the complete detector system
|
||||
* zCoord is the z coordinate in the complete detector system
|
||||
* debug is for debugging purposes
|
||||
* roundRNumber is the round robin set number
|
||||
* detType is the detector type see :: detectorType
|
||||
* version is the version number of this structure format
|
||||
* dataPointer is the pointer to the data
|
||||
* dataSize in bytes is the size of the data in bytes
|
||||
*/
|
||||
void (*rawDataReadyCallBack)(uint64_t, uint32_t, uint32_t, uint64_t, uint64_t, uint16_t, uint16_t, uint16_t, uint16_t, uint32_t, uint16_t, uint8_t, uint8_t,
|
||||
char*, uint32_t, void*);
|
||||
void *pRawDataReady;
|
||||
|
||||
|
||||
|
||||
private:
|
||||
|
||||
};
|
682
exampleCode/customReceiverExample/UDPInterface.h
Executable file
682
exampleCode/customReceiverExample/UDPInterface.h
Executable file
@ -0,0 +1,682 @@
|
||||
#pragma once
|
||||
/***********************************************
|
||||
* @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()
|
||||
*
|
||||
* Sequence of Calls from client (upon setting receiver)
|
||||
* -setDetectorType
|
||||
* -setMultiDetectorSize
|
||||
* -setDetectorPositionId
|
||||
* -initialize
|
||||
* -setUDPPortNumber,setUDPPortNumber2,setEthernetInterface
|
||||
* -setFilePath
|
||||
* -setFileName
|
||||
* -setFileIndex
|
||||
* -setFileFormat
|
||||
* -setFileWriteEnable
|
||||
* -setOverwriteEnable
|
||||
* -setFrameIndexEnable
|
||||
* -setAcquisitionPeriod
|
||||
* -setNumberOfFrames
|
||||
* -setAcquisitionTime
|
||||
* -setSubExpTime
|
||||
* -setDynamicRange
|
||||
* -setFlippedData
|
||||
* -setActivate
|
||||
* -setTenGigaEnable
|
||||
* -setStreamingPort
|
||||
* -setDataStreamEnable
|
||||
*
|
||||
*
|
||||
* 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 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 custom object
|
||||
* @param [in] receiver_type type can be standard or custom (must be derived from base class)
|
||||
* @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/detector parameters***
|
||||
|
||||
/*
|
||||
* Get multi detector size
|
||||
* @return pointer to array of multi detector size in every dimension
|
||||
*/
|
||||
virtual int* getMultiDetectorSize() const = 0;
|
||||
|
||||
/*
|
||||
* Get detector position id
|
||||
* @return detector position id
|
||||
*/
|
||||
virtual int getDetectorPositionId() const = 0;
|
||||
|
||||
/*
|
||||
* Get detector hostname
|
||||
* @return hostname or NULL if uninitialized, must be released by calling function (max of 1000 characters)
|
||||
*/
|
||||
virtual char *getDetectorHostname() const = 0;
|
||||
|
||||
/*
|
||||
* Get flipped data across 'axis'
|
||||
* @return if data is flipped across 'axis'
|
||||
*/
|
||||
virtual int getFlippedData(int axis=0) const = 0;
|
||||
|
||||
|
||||
//***file parameters***
|
||||
/**
|
||||
* Get File Format
|
||||
* @return file format
|
||||
*/
|
||||
virtual slsReceiverDefs::fileFormat getFileFormat() const = 0;
|
||||
|
||||
/**
|
||||
* 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 -1 if no frames have been caught, else 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;
|
||||
|
||||
/**
|
||||
* Gets the timer between frames streamed when frequency is set to 0
|
||||
* @return timer between frames streamed
|
||||
*/
|
||||
virtual uint32_t getFrameToGuiTimer() const = 0;
|
||||
|
||||
|
||||
/**
|
||||
* Get the data stream enable
|
||||
* @return data stream enable
|
||||
*/
|
||||
virtual bool getDataStreamEnable() const = 0;
|
||||
|
||||
/**
|
||||
* Get Acquisition Period
|
||||
* @return acquisition period
|
||||
*/
|
||||
virtual uint64_t getAcquisitionPeriod() const = 0;
|
||||
|
||||
/**
|
||||
* Get Acquisition Time
|
||||
* @return acquisition time
|
||||
*/
|
||||
virtual uint64_t getAcquisitionTime() const = 0;
|
||||
|
||||
/**
|
||||
* Get Sub Exposure Time
|
||||
* @return Sub Exposure Time
|
||||
*/
|
||||
virtual uint64_t getSubExpTime() 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 Silent Mode
|
||||
* @return silent mode
|
||||
*/
|
||||
virtual uint32_t getSilentMode() 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;
|
||||
|
||||
/**
|
||||
* Get Streaming Port
|
||||
* @return streaming port
|
||||
*/
|
||||
virtual uint32_t getStreamingPort() 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 multi detector size
|
||||
* @param pointer to array of multi detector size in every dimension
|
||||
*/
|
||||
virtual void setMultiDetectorSize(const int* size) = 0;
|
||||
|
||||
/*
|
||||
* Get flipped data across 'axis'
|
||||
* @return if data is flipped across 'axis'
|
||||
*/
|
||||
virtual void setFlippedData(int axis=0, int enable=-1) = 0;
|
||||
|
||||
|
||||
//***file parameters***
|
||||
/**
|
||||
* Set File Format
|
||||
* @param f fileformat binary or hdf5
|
||||
*/
|
||||
virtual void setFileFormat(slsReceiverDefs::fileFormat f) = 0;
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @return OK or FAIL
|
||||
*/
|
||||
virtual int setShortFrameEnable(const int i) = 0;
|
||||
|
||||
/**
|
||||
* Set the Frequency of Frames Sent to GUI
|
||||
* @param freq 0 for random frame requests, n for nth frame frequency
|
||||
* @return OK or FAIL
|
||||
*/
|
||||
virtual int setFrameToGuiFrequency(const uint32_t freq) = 0;
|
||||
|
||||
/**
|
||||
* Sets the timer between frames streamed when frequency is set to 0
|
||||
* @param time_in_ms timer between frames streamed
|
||||
*/
|
||||
virtual void setFrameToGuiTimer(const uint32_t time_in_ms) = 0;
|
||||
|
||||
/**
|
||||
* Set the data stream enable
|
||||
* @param enable data stream enable
|
||||
* @return OK or FAIL
|
||||
*/
|
||||
virtual int setDataStreamEnable(const bool enable) = 0;
|
||||
|
||||
/**
|
||||
* Set Acquisition Period
|
||||
* @param i acquisition period
|
||||
* @return OK or FAIL
|
||||
*/
|
||||
virtual int setAcquisitionPeriod(const uint64_t i) = 0;
|
||||
|
||||
/**
|
||||
* Set Acquisition Time
|
||||
* @param i acquisition time
|
||||
* @return OK or FAIL
|
||||
*/
|
||||
virtual int setAcquisitionTime(const uint64_t i) = 0;
|
||||
|
||||
/**
|
||||
* Set Sub Exposure Time
|
||||
* @param i Sub Exposure Time
|
||||
* @return OK or FAIL
|
||||
*/
|
||||
virtual void setSubExpTime(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;
|
||||
|
||||
|
||||
//***receiver parameters***
|
||||
/**
|
||||
* Set Silent Mode
|
||||
* @param i silent mode. 1 sets, 0 unsets
|
||||
*/
|
||||
virtual void setSilentMode(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;
|
||||
|
||||
/**
|
||||
* Set detector position id
|
||||
* @param i position id
|
||||
*/
|
||||
virtual void setDetectorPositionId(const int i) = 0;
|
||||
|
||||
/**
|
||||
* Sets detector hostname
|
||||
* It is second function called by the client when connecting to receiver.
|
||||
* you can call this function only once.
|
||||
* @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
|
||||
*/
|
||||
virtual void shutDownUDPSockets() = 0;
|
||||
|
||||
/**
|
||||
* Get the buffer-current frame read by receiver
|
||||
* @param ithread port thread index
|
||||
* @param c pointer to current file name
|
||||
* @param raw address of pointer, pointing to current frame to send to gui
|
||||
* @param startAcq start index of the acquisition
|
||||
* @param startFrame start index of the scan
|
||||
*/
|
||||
virtual void readFrame(int ithread, char* c,char** raw, int64_t &startAcq, int64_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?
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Set streaming port
|
||||
* @param i streaming port
|
||||
*/
|
||||
virtual void setStreamingPort(const uint32_t i) = 0;
|
||||
|
||||
/**
|
||||
* Restream stop dummy packet from receiver
|
||||
* @return OK or FAIL
|
||||
*/
|
||||
virtual int restreamStop() = 0;
|
||||
|
||||
|
||||
//***callback functions***
|
||||
/**
|
||||
* Call back for start acquisition
|
||||
* callback arguments are
|
||||
* filepath
|
||||
* filename
|
||||
* fileindex
|
||||
* datasize
|
||||
*
|
||||
* return value is insignificant at the moment
|
||||
* we write depending on file write enable
|
||||
* users get data to write depending on call backs registered
|
||||
*/
|
||||
virtual void registerCallBackStartAcquisition(int (*func)(char*, char*, uint64_t, uint32_t, void*),void *arg) = 0;
|
||||
|
||||
/**
|
||||
* Call back for acquisition finished
|
||||
* callback argument is
|
||||
* total frames caught
|
||||
*/
|
||||
virtual void registerCallBackAcquisitionFinished(void (*func)(uint64_t, void*),void *arg) = 0;
|
||||
|
||||
/**
|
||||
* Call back for raw data
|
||||
* args to raw data ready callback are
|
||||
* frameNumber is the frame number
|
||||
* expLength is the subframe number (32 bit eiger) or real time exposure time in 100ns (others)
|
||||
* packetNumber is the packet number
|
||||
* bunchId is the bunch id from beamline
|
||||
* timestamp is the time stamp with 10 MHz clock
|
||||
* modId is the unique module id (unique even for left, right, top, bottom)
|
||||
* xCoord is the x coordinate in the complete detector system
|
||||
* yCoord is the y coordinate in the complete detector system
|
||||
* zCoord is the z coordinate in the complete detector system
|
||||
* debug is for debugging purposes
|
||||
* roundRNumber is the round robin set number
|
||||
* detType is the detector type see :: detectorType
|
||||
* version is the version number of this structure format
|
||||
* dataPointer is the pointer to the data
|
||||
* dataSize in bytes is the size of the data in bytes
|
||||
*/
|
||||
virtual void registerCallBackRawDataReady(void (*func)(uint64_t, uint32_t, uint32_t, uint64_t, uint64_t, uint16_t, uint16_t, uint16_t, uint16_t, uint32_t, uint16_t, uint8_t, uint8_t,
|
||||
char*, uint32_t, void*),void *arg) = 0;
|
||||
|
||||
|
||||
protected:
|
||||
private:
|
||||
|
||||
};
|
66
exampleCode/customReceiverExample/ansi.h
Executable file
66
exampleCode/customReceiverExample/ansi.h
Executable file
@ -0,0 +1,66 @@
|
||||
#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 DARKGRAY "\x1b[30m"
|
||||
|
||||
#define BG_BLACK "\x1b[48;5;232m"
|
||||
#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"
|
||||
|
||||
//on background black
|
||||
#define bprintf(code, format, ...) printf(code BG_BLACK format RESET, ##__VA_ARGS__)
|
||||
|
||||
//normal printout
|
||||
#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);
|
||||
}
|
||||
|
||||
*/
|
79
exampleCode/customReceiverExample/dummyMain.cpp
Executable file
79
exampleCode/customReceiverExample/dummyMain.cpp
Executable file
@ -0,0 +1,79 @@
|
||||
/* 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 "ansi.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <string.h>
|
||||
#include <signal.h> //SIGINT
|
||||
#include <cstdlib> //system
|
||||
#include <sys/types.h> //wait
|
||||
#include <sys/wait.h> //wait
|
||||
#include <syscall.h>
|
||||
using namespace std;
|
||||
|
||||
bool keeprunning;
|
||||
|
||||
void sigInterruptHandler(int p){
|
||||
keeprunning = false;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
|
||||
keeprunning = true;
|
||||
bprintf(BLUE,"Created [ Tid: %ld ]\n", (long)syscall(SYS_gettid));
|
||||
|
||||
// Catch signal SIGINT to close files and call destructors properly
|
||||
struct sigaction sa;
|
||||
sa.sa_flags=0; // no flags
|
||||
sa.sa_handler=sigInterruptHandler; // handler function
|
||||
sigemptyset(&sa.sa_mask); // dont block additional signals during invocation of handler
|
||||
if (sigaction(SIGINT, &sa, NULL) == -1) {
|
||||
bprintf(RED, "Could not set handler function for SIGINT\n");
|
||||
}
|
||||
|
||||
|
||||
// if socket crash, ignores SISPIPE, prevents global signal handler
|
||||
// subsequent read/write to socket gives error - must handle locally
|
||||
struct sigaction asa;
|
||||
asa.sa_flags=0; // no flags
|
||||
asa.sa_handler=SIG_IGN; // handler function
|
||||
sigemptyset(&asa.sa_mask); // dont block additional signals during invocation of handler
|
||||
if (sigaction(SIGPIPE, &asa, NULL) == -1) {
|
||||
bprintf(RED, "Could not set handler function for SIGCHILD\n");
|
||||
}
|
||||
|
||||
|
||||
int ret = slsReceiverDefs::OK;
|
||||
int tcpip_port_no = 1954;
|
||||
dummyUDPInterface *udp_interface = new dummyUDPInterface();
|
||||
slsReceiverTCPIPInterface *tcpipInterface = new slsReceiverTCPIPInterface(ret, udp_interface, tcpip_port_no);
|
||||
if(ret==slsReceiverDefs::FAIL){
|
||||
delete tcpipInterface;
|
||||
bprintf(BLUE,"Exiting [ Tid: %ld ]\n", (long)syscall(SYS_gettid));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
|
||||
//start tcp server thread
|
||||
if (tcpipInterface->start() == slsReceiverDefs::FAIL){
|
||||
delete tcpipInterface;
|
||||
bprintf(BLUE,"Exiting [ Tid: %ld ]\n", (long)syscall(SYS_gettid));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
FILE_LOG(logINFO) << "Ready ... ";
|
||||
bprintf(GRAY, "\n[ Press \'Ctrl+c\' to exit ]\n");
|
||||
while(keeprunning)
|
||||
usleep(5 * 1000 * 1000);
|
||||
|
||||
delete tcpipInterface;
|
||||
bprintf(BLUE,"Exiting [ Tid: %ld ]\n", (long)syscall(SYS_gettid));
|
||||
FILE_LOG(logINFO) << "Goodbye!";
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
BIN
exampleCode/customReceiverExample/dummyReceiver
Executable file
BIN
exampleCode/customReceiverExample/dummyReceiver
Executable file
Binary file not shown.
36
exampleCode/customReceiverExample/dummyUDPInterface.h
Executable file
36
exampleCode/customReceiverExample/dummyUDPInterface.h
Executable file
@ -0,0 +1,36 @@
|
||||
#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 "UDPBaseImplementation.h"
|
||||
|
||||
|
||||
class dummyUDPInterface : public virtual slsReceiverDefs, public UDPBaseImplementation {
|
||||
|
||||
|
||||
|
||||
public:
|
||||
|
||||
/** cosntructor & destructor */
|
||||
dummyUDPInterface() { cout << "New dummy UDP Interface" << endl;};
|
||||
~dummyUDPInterface() {cout << "Destroying dummy UDP Interface" << endl;};
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
#endif /* #ifndef DUMMYUDPINTERFACE_H */
|
419
exampleCode/customReceiverExample/dummyUDPInterface_copy.h
Executable file
419
exampleCode/customReceiverExample/dummyUDPInterface_copy.h
Executable file
@ -0,0 +1,419 @@
|
||||
#ifndef DUMMYUDPINTERFACE_H
|
||||
#define DUMMYUDPINTERFACE_H
|
||||
|
||||
/***********************************************
|
||||
* @file UDPInterface.h
|
||||
* @short Base class with all the functions for the UDP inteface of the receiver
|
||||
***********************************************/
|
||||
/**
|
||||
* \mainpage Base class with all the functions for the UDP inteface of the receiver
|
||||
*/
|
||||
|
||||
/**
|
||||
* @short Base class with all the functions for the UDP inteface of the receiver
|
||||
*/
|
||||
|
||||
#include "UDPInterface.h"
|
||||
#include "sls_receiver_defs.h"
|
||||
|
||||
|
||||
class dummyUDPInterface : public UDPInterface {
|
||||
|
||||
|
||||
/* abstract class that defines the UDP interface of an sls detector data receiver.
|
||||
*
|
||||
* Use the factory method UDPInterface::create() to get an instance:
|
||||
*
|
||||
* UDPInterface *udp_interface = UDPInterface::create()
|
||||
*
|
||||
* supported sequence of method-calls:
|
||||
*
|
||||
* initialize() : once and only once after create()
|
||||
*
|
||||
* get*() : anytime after initialize(), multiples times
|
||||
* set*() : anytime after initialize(), multiple times
|
||||
*
|
||||
* startReceiver(): anytime after initialize(). Will fail if state already is 'running'
|
||||
*
|
||||
* abort(),
|
||||
* stopReceiver() : anytime after initialize(). Will do nothing if state already is idle.
|
||||
*
|
||||
* getStatus() returns the actual state of the data receiver - running or idle. All other
|
||||
* get*() and set*() methods access the local cache of configuration values only and *do not* modify the data receiver settings.
|
||||
*
|
||||
* Only startReceiver() does change the data receiver configuration, it does pass the whole configuration cache to the data receiver.
|
||||
*
|
||||
* get- and set-methods that return a char array (char *) allocate a new array at each call. The caller is responsible to free the allocated space:
|
||||
*
|
||||
* char *c = receiver->getFileName();
|
||||
* ....
|
||||
* delete[] c;
|
||||
*
|
||||
* always: 1:YES 0:NO for int as bool-like arguments
|
||||
*
|
||||
*/
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
dummyUDPInterface() : UDPInterface(), dynamicRange(16), scanTag(1000), nFrames(100), fWrite(1), fOverwrite(1), fIndex(0), fCaught(0), totfCaught(0), startAcqIndex(0), startFrameIndex(0), acqIndex(0), dataCompression(false), period(0), type(slsReceiverDefs::GENERIC), framesNeeded(100), udpPort1(1900), udpPort2(1901), shortFrame(0), nFramesToGui(0), e10G(0) {strcpy(detHostname,"none"); strcpy(fName,"run"); strcpy(fPath,"/scratch/"); strcpy(eth,"eth0"); cout << "New dummy UDP Interface" << endl;};
|
||||
|
||||
~dummyUDPInterface() {cout << "Destroying dummy UDP Interface" << endl;};
|
||||
|
||||
|
||||
void del(){cout << "Destroying dummy UDP Interface" << endl;};
|
||||
|
||||
virtual void configure(map<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; 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 */
|
779
exampleCode/customReceiverExample/genericSocket.h
Executable file
779
exampleCode/customReceiverExample/genericSocket.h
Executable file
@ -0,0 +1,779 @@
|
||||
#pragma once
|
||||
/**
|
||||
*
|
||||
* @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)
|
||||
*/
|
||||
|
||||
#include "ansi.h"
|
||||
|
||||
#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_BACKLOG 5
|
||||
|
||||
|
||||
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
|
||||
header_packet_size(0)
|
||||
{
|
||||
memset(&serverAddress, 0, sizeof(serverAddress));
|
||||
memset(&clientAddress, 0, sizeof(clientAddress));
|
||||
memset(lastClientIP,0,INET_ADDRSTRLEN);
|
||||
memset(thisClientIP,0,INET_ADDRSTRLEN);
|
||||
memset(dummyClientIP,0,INET_ADDRSTRLEN);
|
||||
differentClients = 0;
|
||||
|
||||
struct addrinfo *result;
|
||||
if (!ConvertHostnameToInternetAddress(host_ip_or_name, &result)) {
|
||||
serverAddress.sin_family = result->ai_family;
|
||||
memcpy((char *) &serverAddress.sin_addr.s_addr, &((struct sockaddr_in *) result->ai_addr)->sin_addr, sizeof(in_addr_t));
|
||||
freeaddrinfo(result);
|
||||
serverAddress.sin_port = htons(port_number);
|
||||
socketDescriptor=0;
|
||||
}
|
||||
clientAddress_length=sizeof(clientAddress);
|
||||
}
|
||||
|
||||
|
||||
int getProtocol(communicationProtocol p) {
|
||||
switch (p) {
|
||||
case TCP:
|
||||
return SOCK_STREAM;
|
||||
break;
|
||||
case UDP:
|
||||
return SOCK_DGRAM;
|
||||
|
||||
default:
|
||||
cerr << "unknown 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, int hsize=0):
|
||||
portno(port_number),
|
||||
protocol(p),
|
||||
is_a_server(1),
|
||||
socketDescriptor(-1),
|
||||
file_des(-1),
|
||||
packet_size(ps),
|
||||
nsending(0),
|
||||
nsent(0),
|
||||
total_sent(0),
|
||||
header_packet_size(hsize)
|
||||
{
|
||||
|
||||
|
||||
memset(&serverAddress, 0, sizeof(serverAddress));
|
||||
memset(&clientAddress, 0, sizeof(clientAddress));
|
||||
|
||||
/* // you can specify an IP address: */
|
||||
/* // or you can let it automatically select one: */
|
||||
/* myaddr.sin_addr.s_addr = INADDR_ANY; */
|
||||
memset(lastClientIP,0,INET_ADDRSTRLEN);
|
||||
memset(thisClientIP,0,INET_ADDRSTRLEN);
|
||||
memset(dummyClientIP,0,INET_ADDRSTRLEN);
|
||||
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(){
|
||||
|
||||
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 {
|
||||
//while(!shutdown(socketDescriptor, SHUT_RDWR));
|
||||
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;
|
||||
|
||||
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];
|
||||
const int buf_len = sizeof(buf);
|
||||
memset(buf,0,buf_len);
|
||||
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, buf_len);
|
||||
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];
|
||||
const int mac_len = sizeof(mac);
|
||||
memset(mac,0,mac_len);
|
||||
|
||||
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, mac_len-k-1, j ? ":%02X" : "%02X",
|
||||
(int)(unsigned int)(unsigned char)ifr.ifr_hwaddr.sa_data[j]);
|
||||
}
|
||||
mac[mac_len-1]='\0';
|
||||
|
||||
if(sock!=1){
|
||||
close(sock);
|
||||
}
|
||||
return string(mac);
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
static string nameToIp(string inf){
|
||||
struct ifreq ifr;
|
||||
int sock;
|
||||
char *p, addr[32];
|
||||
const int addr_len = sizeof(addr);
|
||||
memset(addr,0,addr_len);
|
||||
|
||||
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,addr_len-1);
|
||||
addr[addr_len-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;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Convert Hostname to Internet address info structure
|
||||
* One must use freeaddrinfo(res) after using it
|
||||
* @param hostname hostname
|
||||
* @param res address of pointer to address info structure
|
||||
* @return 1 for fail, 0 for success
|
||||
*/
|
||||
// Do not make this static (for multi threading environment)
|
||||
int ConvertHostnameToInternetAddress (const char* const hostname, struct addrinfo **res) {
|
||||
// criteria in selecting socket address structures returned by res
|
||||
struct addrinfo hints;
|
||||
memset (&hints, 0, sizeof (hints));
|
||||
hints.ai_family = AF_INET;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
// get host info into res
|
||||
int errcode = getaddrinfo (hostname, NULL, &hints, res);
|
||||
if (errcode != 0) {
|
||||
cprintf (RED,"Error: Could not convert %s hostname to internet address (zmq):"
|
||||
"%s\n", hostname, gai_strerror(errcode));
|
||||
} else {
|
||||
if (*res == NULL) {
|
||||
cprintf (RED,"Error: Could not convert %s hostname to internet address (zmq): "
|
||||
"gettaddrinfo returned null\n", hostname);
|
||||
} else{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
cerr << "Error: Could not convert hostname to internet address" << endl;
|
||||
return 1;
|
||||
};
|
||||
|
||||
/**
|
||||
* Convert Internet Address structure pointer to ip string (char*)
|
||||
* Clears the internet address structure as well
|
||||
* @param res pointer to internet address structure
|
||||
* @param ip pointer to char array to store result in
|
||||
* @param ipsize size available in ip buffer
|
||||
* @return 1 for fail, 0 for success
|
||||
*/
|
||||
// Do not make this static (for multi threading environment)
|
||||
int ConvertInternetAddresstoIpString (struct addrinfo *res, char* ip, const int ipsize) {
|
||||
if (inet_ntop (res->ai_family, &((struct sockaddr_in *) res->ai_addr)->sin_addr, ip, ipsize) != NULL) {
|
||||
freeaddrinfo(res);
|
||||
return 0;
|
||||
}
|
||||
cerr << "Error: Could not convert internet address to ip string" << endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
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) {
|
||||
if(!total_sent) {
|
||||
return -1; //to handle it
|
||||
}
|
||||
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){
|
||||
while(length>0){
|
||||
nsending = (length>packet_size) ? packet_size:length;
|
||||
nsent = recvfrom(socketDescriptor,(char*)buf+total_sent,nsending, 0, (struct sockaddr *) &clientAddress, &clientAddress_length);
|
||||
if(nsent == header_packet_size)
|
||||
continue;
|
||||
if(nsent != nsending){
|
||||
if(nsent && (nsent != -1))
|
||||
cprintf(RED,"Incomplete Packet size %d\n",nsent);
|
||||
break;
|
||||
}
|
||||
length-=nsent;
|
||||
total_sent+=nsent;
|
||||
}
|
||||
}
|
||||
//listens to only 1 packet
|
||||
else{
|
||||
//normal
|
||||
nsending=packet_size;
|
||||
while(1){
|
||||
#ifdef VERYVERBOSE
|
||||
cprintf(BLUE,"%d gonna listen\n", portno); fflush(stdout);
|
||||
#endif
|
||||
nsent = recvfrom(socketDescriptor,(char*)buf+total_sent,nsending, 0, (struct sockaddr *) &clientAddress, &clientAddress_length);
|
||||
//break out of loop only if read one packets size or read didnt work (cuz of shutdown)
|
||||
if(nsent<=0 || nsent == packet_size)
|
||||
break;
|
||||
//incomplete packets or header packets ignored and read buffer again
|
||||
if(nsent != packet_size && nsent != header_packet_size)
|
||||
cprintf(RED,"%d Incomplete Packet size %d\n", portno, nsent);
|
||||
}
|
||||
//nsent = 1040;
|
||||
if(nsent > 0)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(is_a_server && nsent < 0) {
|
||||
cprintf(BG_RED, "Error writing to socket. Possible client socket crash\n");
|
||||
break;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
int getCurrentTotalReceived(){
|
||||
return total_sent;
|
||||
}
|
||||
|
||||
char lastClientIP[INET_ADDRSTRLEN];
|
||||
char thisClientIP[INET_ADDRSTRLEN];
|
||||
int differentClients;
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
int portno;
|
||||
communicationProtocol protocol;
|
||||
int is_a_server;
|
||||
int socketDescriptor;
|
||||
int file_des;
|
||||
int packet_size;
|
||||
struct sockaddr_in clientAddress, serverAddress;
|
||||
socklen_t clientAddress_length;
|
||||
char dummyClientIP[INET_ADDRSTRLEN];
|
||||
|
||||
|
||||
private:
|
||||
|
||||
int nsending;
|
||||
int nsent;
|
||||
int total_sent;
|
||||
int header_packet_size;
|
||||
|
||||
// pthread_mutex_t mp;
|
||||
};
|
133
exampleCode/customReceiverExample/index.html
Executable file
133
exampleCode/customReceiverExample/index.html
Executable file
@ -0,0 +1,133 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
|
||||
<HTML><!-- #BeginTemplate "/templates/psi_template.dwt" -->
|
||||
<HEAD>
|
||||
|
||||
<!--#include virtual="/webbase/ssi/defaultvariables.shtml" -->
|
||||
|
||||
<!-- Change only the text within the 3 BeginEditable ... EndEditable Sections: -->
|
||||
<!-- MetaData - Definitions - BodyContent -->
|
||||
|
||||
<!-- #BeginEditable "MetaData" -->
|
||||
<TITLE>slsDetectorUsers Example</TITLE>
|
||||
<META name="keywords" content="slsDetectorUsers">
|
||||
<META name="description" content="SLS Detector Users Example">
|
||||
<META name="author" content="Anna Bergamaschi">
|
||||
<!-- #EndEditable -->
|
||||
|
||||
<!--#include virtual="/webbase/ssi/instructions.shtml" -->
|
||||
|
||||
<!--#include virtual="$PRJDIR/ssi/projectvariables.shtml" -->
|
||||
|
||||
<!-- # = Active changes to projectvariables or defaultvariables, no # = Inactive -->
|
||||
|
||||
<!-- #BeginEditable "Definitions" -->
|
||||
<!--#set var="PAGETITLE" value='Anna Bergamaschi' -->
|
||||
<!--set var="ALTLANGUAGE" value='english' -->
|
||||
<!--set var="DIRLANGUAGE" value='d/' -->
|
||||
<!--#set var="MAILTO" value='anna.bergamaschi@psi.ch' -->
|
||||
<!--#set var="MAILCC" value=' ' -->
|
||||
<!--set var="NAVTOP" value='/webbase/ssi/top_psi.shtml' -->
|
||||
<!--#set var="NAVLEFT" value='$SSIDIR/side.shtml' -->
|
||||
<!-- #EndEditable -->
|
||||
|
||||
<!--#include virtual="/webbase/ssi/head.shtml" -->
|
||||
|
||||
</head>
|
||||
|
||||
<!--#include virtual="/webbase/ssi/pretemplate.shtml" -->
|
||||
|
||||
<!-- #BeginEditable "BodyContent" -->
|
||||
|
||||
<H1>Custom SLS Receiver Example</H1>
|
||||
|
||||
|
||||
<H3> Main Files </H3>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="Makefile">Makefile</a> Edit to properly link the slsDetector libraries
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="dummyMain.cpp">dummyMain.cpp</a> Main combining the required TCPIP interface and the custom dummy UDP implementation
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="dummyUDPInterface.h">dummyUDPInterface.h</a> Dummy example of UDP interface implementation -- the UDP server never start listening!
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<H3> Library Files </H3>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="libSlsReceiver.so">libSlsReceiver.so</a> Receiver Library
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<H3> Include Files </H3>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="slsReceiverTCPIPInterface.h">slsReceiverTCPIPInterface.h</a> TCP/IP Interface between client and receiver
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="UDPInterface.h">UDPInterface.h</a> abstract UDP Interface of the receiver
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="UDPBaseImplementation.h">UDPBaseImplementation.h</a> Base Implementation of UDP Interface. Dummy Interface will be a child class of this
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="sls_receiver_defs.h">sls_receiver_defs.h</a> Includes definitions used in the example files
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="sls_receiver_funcs.h">sls_receiver_funcs.h</a> Required by sls_receiver_defs.h
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="sls_receiver_funcs.h">sls_receiver_funcs.h</a> Required by sls_receiver_defs.h
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="MySocketTCP.h">MySocketTCP.h</a> To create Sockets. Required by slsReceiverTCPIPInterface.h
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="genericSocket.h">genericSocket.h</a> Required by MySocketTCP.h
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="receiver_defs.h">receiver_defs.h</a> Required by slsReceiverTCPIPInterface.h
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="utilities.h">utilities.h</a> Required by UDPInterface.h
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="logger.h">logger.h</a> Required by UDPInterface.h
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="ansi.h">ansi.h</a> Colored print. Required by most files
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
|
||||
<H3> ZMQ Include Files </H3>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="zmq.h">zmq.h</a> Public Include file for ZMQ API users.
|
||||
</li>
|
||||
<li>
|
||||
<a href="libzmq.a">libzmq.a</a> Static libary file
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<!-- #EndEditable -->
|
||||
|
||||
<!--#include virtual="/webbase/ssi/posttemplate.shtml" -->
|
||||
<!-- #EndTemplate -->
|
||||
</HTML>
|
BIN
exampleCode/customReceiverExample/libSlsReceiver.so
Executable file
BIN
exampleCode/customReceiverExample/libSlsReceiver.so
Executable file
Binary file not shown.
BIN
exampleCode/customReceiverExample/libzmq.a
Executable file
BIN
exampleCode/customReceiverExample/libzmq.a
Executable file
Binary file not shown.
231
exampleCode/customReceiverExample/logger.h
Executable file
231
exampleCode/customReceiverExample/logger.h
Executable file
@ -0,0 +1,231 @@
|
||||
#pragma once
|
||||
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <ansi.h>
|
||||
|
||||
|
||||
|
||||
#ifdef FIFODEBUG
|
||||
#define FILELOG_MAX_LEVEL logDEBUG5
|
||||
#elif VERYVERBOSE
|
||||
#define FILELOG_MAX_LEVEL logDEBUG4
|
||||
#elif VERBOSE
|
||||
#define FILELOG_MAX_LEVEL logDEBUG
|
||||
#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("(): ")
|
||||
|
||||
|
||||
|
||||
|
||||
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;
|
||||
|
||||
#define FILE_LOG(level) \
|
||||
if (level > FILELOG_MAX_LEVEL) ; \
|
||||
else if (level > FILELog::ReportingLevel() || !Output2FILE::Stream()) ; \
|
||||
else FILELog().Get(level)
|
||||
|
||||
|
||||
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
|
||||
|
||||
#include <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];
|
||||
const int buffer_len = sizeof(buffer);
|
||||
time_t t;
|
||||
time(&t);
|
||||
tm r = {0};
|
||||
strftime(buffer, buffer_len, "%X", localtime_r(&t, &r));
|
||||
buffer[buffer_len - 1] = 0;
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, 0);
|
||||
char result[100];
|
||||
const int result_len = sizeof(result);
|
||||
snprintf(result, result_len, "%s.%03ld", buffer, (long)tv.tv_usec / 1000);
|
||||
result[result_len - 1] = 0;
|
||||
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) << ": ";
|
||||
if (level > logDEBUG)
|
||||
os << std::string(level - logDEBUG, '\t');
|
||||
return os;
|
||||
}
|
||||
|
||||
template <typename T> Log<T>::~Log()
|
||||
{
|
||||
os << std::endl;
|
||||
T::Output( os.str(),lev); // T::Output( os.str());
|
||||
}
|
||||
|
||||
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;
|
||||
bool out = true;
|
||||
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(RESET,"%s",msg.c_str()); break;
|
||||
default: fprintf(pStream,"%s",msg.c_str()); out = false; break;
|
||||
}
|
||||
fflush(out ? stdout : 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
|
||||
|
||||
|
47
exampleCode/customReceiverExample/receiver_defs.h
Executable file
47
exampleCode/customReceiverExample/receiver_defs.h
Executable file
@ -0,0 +1,47 @@
|
||||
#pragma once
|
||||
|
||||
#include "sls_receiver_defs.h"
|
||||
#include <stdint.h>
|
||||
|
||||
#define MAX_DIMENSIONS 2
|
||||
//socket
|
||||
#define GOODBYE -200
|
||||
#define RECEIVE_SOCKET_BUFFER_SIZE (100*1024*1024)
|
||||
#define MAX_SOCKET_INPUT_PACKET_QUEUE 250000
|
||||
|
||||
|
||||
//files
|
||||
#define DO_NOTHING 0
|
||||
#define DO_EVERYTHING 1
|
||||
|
||||
//binary
|
||||
#define FILE_BUFFER_SIZE (16*1024*1024) //16mb
|
||||
|
||||
//fifo
|
||||
#define FIFO_HEADER_NUMBYTES 4
|
||||
|
||||
|
||||
//hdf5
|
||||
#define MAX_CHUNKED_IMAGES 1
|
||||
|
||||
//versions
|
||||
#define HDF5_WRITER_VERSION 1.0 //1 decimal places
|
||||
#define BINARY_WRITER_VERSION 1.0 //1 decimal places
|
||||
#define SLS_DETECTOR_HEADER_VERSION 0x1
|
||||
#define SLS_DETECTOR_JSON_HEADER_VERSION 0x2
|
||||
|
||||
//parameters to calculate fifo depth
|
||||
#define SAMPLE_TIME_IN_NS 100000000//100ms
|
||||
#define MAX_JOBS_PER_THREAD 1000
|
||||
|
||||
|
||||
//to differentiate between gotthard and short gotthard
|
||||
#define GOTTHARD_PACKET_SIZE 1286
|
||||
|
||||
|
||||
#define DUMMY_PACKET_VALUE 0xFFFFFFFF
|
||||
|
||||
#define LISTENER_PRIORITY 90
|
||||
#define PROCESSOR_PRIORITY 70
|
||||
#define STREAMER_PRIORITY 10
|
||||
#define TCP_PRIORITY 10
|
358
exampleCode/customReceiverExample/slsReceiverTCPIPInterface.h
Executable file
358
exampleCode/customReceiverExample/slsReceiverTCPIPInterface.h
Executable file
@ -0,0 +1,358 @@
|
||||
#pragma once
|
||||
/********************************************//**
|
||||
* @file slsReceiverTCPIPInterface.h
|
||||
* @short interface between receiver and client
|
||||
***********************************************/
|
||||
|
||||
|
||||
#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:
|
||||
|
||||
/** Destructor */
|
||||
virtual ~slsReceiverTCPIPInterface();
|
||||
|
||||
/**
|
||||
* 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)
|
||||
*/
|
||||
|
||||
slsReceiverTCPIPInterface(int &success, UDPInterface* rbase, int pn=-1);
|
||||
|
||||
/**
|
||||
* Sets the port number to listen to.
|
||||
Take care that the client must know to whcih port it has to listen to, so normally it is better to use a fixes port from the instatiation or change it from the client.
|
||||
@param pn port number (-1 only get)
|
||||
\returns actual port number
|
||||
*/
|
||||
int setPortNumber(int pn=-1);
|
||||
|
||||
/**
|
||||
* 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();
|
||||
|
||||
|
||||
/** gets version */
|
||||
int64_t getReceiverVersion();
|
||||
|
||||
//***callback functions***
|
||||
/**
|
||||
* Call back for start acquisition
|
||||
* callback arguments are
|
||||
* filepath
|
||||
* filename
|
||||
* fileindex
|
||||
* datasize
|
||||
*
|
||||
* return value is insignificant at the moment
|
||||
* we write depending on file write enable
|
||||
* users get data to write depending on call backs registered
|
||||
*/
|
||||
void registerCallBackStartAcquisition(int (*func)(char*, char*, uint64_t, uint32_t, void*),void *arg);
|
||||
|
||||
/**
|
||||
* Call back for acquisition finished
|
||||
* callback argument is
|
||||
* total frames caught
|
||||
*/
|
||||
void registerCallBackAcquisitionFinished(void (*func)(uint64_t, void*),void *arg);
|
||||
|
||||
/**
|
||||
* Call back for raw data
|
||||
* args to raw data ready callback are
|
||||
* frameNumber is the frame number
|
||||
* expLength is the subframe number (32 bit eiger) or real time exposure time in 100ns (others)
|
||||
* packetNumber is the packet number
|
||||
* bunchId is the bunch id from beamline
|
||||
* timestamp is the time stamp with 10 MHz clock
|
||||
* modId is the unique module id (unique even for left, right, top, bottom)
|
||||
* xCoord is the x coordinate in the complete detector system
|
||||
* yCoord is the y coordinate in the complete detector system
|
||||
* zCoord is the z coordinate in the complete detector system
|
||||
* debug is for debugging purposes
|
||||
* roundRNumber is the round robin set number
|
||||
* detType is the detector type see :: detectorType
|
||||
* version is the version number of this structure format
|
||||
* dataPointer is the pointer to the data
|
||||
* dataSize in bytes is the size of the data in bytes
|
||||
*/
|
||||
void registerCallBackRawDataReady(void (*func)(uint64_t, uint32_t, uint32_t, uint64_t, uint64_t, uint16_t, uint16_t, uint16_t, uint16_t, uint32_t, uint16_t, uint8_t, uint8_t,
|
||||
char*, uint32_t, 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();
|
||||
|
||||
/** retuns function name with function index */
|
||||
const char* getFunctionName(enum recFuncs func);
|
||||
|
||||
/** assigns functions to the fnum enum */
|
||||
int function_table();
|
||||
|
||||
/** Decodes Function */
|
||||
int decode_function();
|
||||
|
||||
/** print socket read error */
|
||||
int printSocketReadError();
|
||||
|
||||
/** receiver object is null */
|
||||
void invalidReceiverObject();
|
||||
|
||||
/** receiver already locked */
|
||||
void receiverlocked();
|
||||
|
||||
/** receiver not idle */
|
||||
void receiverNotIdle();
|
||||
|
||||
/** function not implemented for specific detector */
|
||||
void functionNotImplemented();
|
||||
|
||||
/** Unrecognized Function */
|
||||
int M_nofunc();
|
||||
|
||||
|
||||
|
||||
/** Execute command */
|
||||
int exec_command();
|
||||
|
||||
/** Exit Receiver Server */
|
||||
int exit_server();
|
||||
|
||||
/** Locks Receiver */
|
||||
int lock_receiver();
|
||||
|
||||
/** Get Last Client IP*/
|
||||
int get_last_client_ip();
|
||||
|
||||
/** Set port */
|
||||
int set_port();
|
||||
|
||||
/** Updates Client if different clients connect */
|
||||
int update_client();
|
||||
|
||||
/** Sends the updated parameters to client */
|
||||
int send_update();
|
||||
|
||||
/** get version, calls get_version */
|
||||
int get_id();
|
||||
|
||||
/** Set detector type */
|
||||
int set_detector_type();
|
||||
|
||||
/** set detector hostname */
|
||||
int set_detector_hostname();
|
||||
|
||||
/** set short frame */
|
||||
int set_short_frame();
|
||||
|
||||
/** Set up UDP Details */
|
||||
int setup_udp();
|
||||
|
||||
/** set acquisition period, frame number etc */
|
||||
int set_timer();
|
||||
|
||||
/** set dynamic range */
|
||||
int set_dynamic_range();
|
||||
|
||||
/** Sets the receiver to send every nth frame to gui, or only upon gui request */
|
||||
int set_read_frequency();
|
||||
|
||||
/** Gets receiver status */
|
||||
int get_status();
|
||||
|
||||
/** Start Receiver - starts listening to udp packets from detector */
|
||||
int start_receiver();
|
||||
|
||||
/** Stop Receiver - stops listening to udp packets from detector*/
|
||||
int stop_receiver();
|
||||
|
||||
/** set status to transmitting and
|
||||
* when fifo is empty later, sets status to run_finished */
|
||||
int start_readout();
|
||||
|
||||
/** Reads Frame/ buffer */
|
||||
int read_frame();
|
||||
|
||||
/** Set File path */
|
||||
int set_file_dir();
|
||||
|
||||
/** Set File name without frame index, file index and extension */
|
||||
int set_file_name();
|
||||
|
||||
/** Set File index */
|
||||
int set_file_index();
|
||||
|
||||
/** Set Frame index */
|
||||
int set_frame_index();
|
||||
|
||||
/** Gets frame index for each acquisition */
|
||||
int get_frame_index();
|
||||
|
||||
/** Gets Total Frames Caught */
|
||||
int get_frames_caught();
|
||||
|
||||
/** Resets Total Frames Caught */
|
||||
int reset_frames_caught();
|
||||
|
||||
/** Enable File Write*/
|
||||
int enable_file_write();
|
||||
|
||||
/** enable compression */
|
||||
int enable_compression();
|
||||
|
||||
/** enable overwrite */
|
||||
int enable_overwrite();
|
||||
|
||||
/** enable 10Gbe */
|
||||
int enable_tengiga();
|
||||
|
||||
/** set fifo depth */
|
||||
int set_fifo_depth();
|
||||
|
||||
/** activate/ deactivate */
|
||||
int set_activate();
|
||||
|
||||
/* Set the data stream enable */
|
||||
int set_data_stream_enable();
|
||||
|
||||
/** Sets the timer between frames streamed by receiver when frequency is set to 0 */
|
||||
int set_read_receiver_timer();
|
||||
|
||||
/** enable flipped data */
|
||||
int set_flipped_data();
|
||||
|
||||
/** set file format */
|
||||
int set_file_format();
|
||||
|
||||
/** set position id */
|
||||
int set_detector_posid();
|
||||
|
||||
/** set multi detector size */
|
||||
int set_multi_detector_size();
|
||||
|
||||
/** set streaming port */
|
||||
int set_streaming_port();
|
||||
|
||||
/** set silent mode */
|
||||
int set_silent_mode();
|
||||
|
||||
/** restream stop packet */
|
||||
int restream_stop();
|
||||
|
||||
|
||||
|
||||
/** detector type */
|
||||
detectorType myDetectorType;
|
||||
|
||||
/** slsReceiverBase object */
|
||||
UDPInterface *receiverBase;
|
||||
|
||||
/** Function List */
|
||||
int (slsReceiverTCPIPInterface::*flist[NUM_REC_FUNCTIONS])();
|
||||
|
||||
/** Message */
|
||||
char mess[MAX_STR_LENGTH];
|
||||
|
||||
/** success/failure */
|
||||
int ret;
|
||||
|
||||
/** function index */
|
||||
int fnum;
|
||||
|
||||
/** Lock Status if server locked to a client */
|
||||
int lockStatus;
|
||||
|
||||
/** kill tcp server thread */
|
||||
int killTCPServerThread;
|
||||
|
||||
/** thread for TCP server */
|
||||
pthread_t TCPServer_thread;
|
||||
|
||||
/** port number */
|
||||
int portNumber;
|
||||
|
||||
//***callback parameters***
|
||||
/**
|
||||
* Call back for start acquisition
|
||||
* callback arguments are
|
||||
* filepath
|
||||
* filename
|
||||
* fileindex
|
||||
* datasize
|
||||
*
|
||||
* return value is insignificant at the moment
|
||||
* we write depending on file write enable
|
||||
* users get data to write depending on call backs registered
|
||||
*/
|
||||
int (*startAcquisitionCallBack)(char*, char*, uint64_t, uint32_t, void*);
|
||||
void *pStartAcquisition;
|
||||
|
||||
/**
|
||||
* Call back for acquisition finished
|
||||
* callback argument is
|
||||
* total frames caught
|
||||
*/
|
||||
void (*acquisitionFinishedCallBack)(uint64_t, void*);
|
||||
void *pAcquisitionFinished;
|
||||
|
||||
|
||||
/**
|
||||
* Call back for raw data
|
||||
* args to raw data ready callback are
|
||||
* frameNumber is the frame number
|
||||
* expLength is the subframe number (32 bit eiger) or real time exposure time in 100ns (others)
|
||||
* packetNumber is the packet number
|
||||
* bunchId is the bunch id from beamline
|
||||
* timestamp is the time stamp with 10 MHz clock
|
||||
* modId is the unique module id (unique even for left, right, top, bottom)
|
||||
* xCoord is the x coordinate in the complete detector system
|
||||
* yCoord is the y coordinate in the complete detector system
|
||||
* zCoord is the z coordinate in the complete detector system
|
||||
* debug is for debugging purposes
|
||||
* roundRNumber is the round robin set number
|
||||
* detType is the detector type see :: detectorType
|
||||
* version is the version number of this structure format
|
||||
* dataPointer is the pointer to the data
|
||||
* dataSize in bytes is the size of the data in bytes
|
||||
*/
|
||||
void (*rawDataReadyCallBack)(uint64_t, uint32_t, uint32_t, uint64_t, uint64_t, uint16_t, uint16_t, uint16_t, uint16_t, uint32_t, uint16_t, uint8_t, uint8_t,
|
||||
char*, uint32_t, void*);
|
||||
void *pRawDataReady;
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
/** Socket */
|
||||
MySocketTCP* mySock;
|
||||
};
|
260
exampleCode/customReceiverExample/sls_receiver_defs.h
Executable file
260
exampleCode/customReceiverExample/sls_receiver_defs.h
Executable file
@ -0,0 +1,260 @@
|
||||
#pragma once
|
||||
|
||||
|
||||
#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 10000
|
||||
#define JFCTB_MAX_FRAMES_PER_FILE 100000
|
||||
|
||||
|
||||
#define DEFAULT_STREAMING_TIMER_IN_MS 200
|
||||
|
||||
/** default ports */
|
||||
#define DEFAULT_PORTNO 1952
|
||||
#define DEFAULT_UDP_PORTNO 50001
|
||||
#define DEFAULT_GUI_PORTNO 65001
|
||||
#define DEFAULT_ZMQ_CL_PORTNO 30001
|
||||
#define DEFAULT_ZMQ_RX_PORTNO 30001
|
||||
|
||||
/**
|
||||
\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 */
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
@short structure for a Detector Packet or Image Header
|
||||
@li frameNumber is the frame number
|
||||
@li expLength is the subframe number (32 bit eiger) or real time exposure time in 100ns (others)
|
||||
@li packetNumber is the packet number
|
||||
@li bunchId is the bunch id from beamline
|
||||
@li timestamp is the time stamp with 10 MHz clock
|
||||
@li modId is the unique module id (unique even for left, right, top, bottom)
|
||||
@li xCoord is the x coordinate in the complete detector system
|
||||
@li yCoord is the y coordinate in the complete detector system
|
||||
@li zCoord is the z coordinate in the complete detector system
|
||||
@li debug is for debugging purposes
|
||||
@li roundRNumber is the round robin set number
|
||||
@li detType is the detector type see :: detectorType
|
||||
@li version is the version number of this structure format
|
||||
*/
|
||||
typedef struct {
|
||||
uint64_t frameNumber; /**< is the frame number */
|
||||
uint32_t expLength; /**< is the subframe number (32 bit eiger) or real time exposure time in 100ns (others) */
|
||||
uint32_t packetNumber; /**< is the packet number */
|
||||
uint64_t bunchId; /**< is the bunch id from beamline */
|
||||
uint64_t timestamp; /**< is the time stamp with 10 MHz clock */
|
||||
uint16_t modId; /**< is the unique module id (unique even for left, right, top, bottom) */
|
||||
uint16_t xCoord; /**< is the x coordinate in the complete detector system */
|
||||
uint16_t yCoord; /**< is the y coordinate in the complete detector system */
|
||||
uint16_t zCoord; /**< is the z coordinate in the complete detector system */
|
||||
uint32_t debug; /**< is for debugging purposes */
|
||||
uint16_t roundRNumber; /**< is the round robin set number */
|
||||
uint8_t detType; /**< is the detector type see :: detectorType */
|
||||
uint8_t version; /**< is the version number of this structure format */
|
||||
} sls_detector_header;
|
||||
|
||||
|
||||
/**
|
||||
format
|
||||
*/
|
||||
enum fileFormat {
|
||||
GET_FILE_FORMAT=-1,/**< the receiver will return its file format */
|
||||
BINARY, /**< binary format */
|
||||
ASCII, /**< ascii format */
|
||||
HDF5, /**< hdf5 format */
|
||||
NUM_FILE_FORMATS
|
||||
};
|
||||
|
||||
|
||||
#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"); \
|
||||
}};
|
||||
|
||||
|
||||
/** returns string from file format index
|
||||
\param s can be BINARY, ASCII, HDF5
|
||||
\returns string binary, ascii, hdf5
|
||||
*/
|
||||
static std::string getFileFormatType(fileFormat f){\
|
||||
switch (f) { \
|
||||
case ASCII: return std::string("ascii"); \
|
||||
case HDF5: return std::string("hdf5"); \
|
||||
case BINARY: return std::string("binary"); \
|
||||
default: return std::string("unknown"); \
|
||||
}};
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
protected:
|
||||
#endif
|
||||
|
||||
#ifndef MYROOT
|
||||
#include "sls_receiver_funcs.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
#endif
|
||||
;
|
73
exampleCode/customReceiverExample/sls_receiver_funcs.h
Executable file
73
exampleCode/customReceiverExample/sls_receiver_funcs.h
Executable file
@ -0,0 +1,73 @@
|
||||
#pragma once
|
||||
/**
|
||||
@internal
|
||||
function indexes to call on the server
|
||||
All set functions with argument -1 work as get, when possible
|
||||
*/
|
||||
|
||||
#define REC_FUNC_START_INDEX 128
|
||||
|
||||
enum recFuncs{
|
||||
//General functions
|
||||
F_EXEC_RECEIVER_COMMAND=REC_FUNC_START_INDEX, /**< 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_RECEIVER_ACTIVATE, /** < activate/deactivate readout */
|
||||
F_STREAM_DATA_FROM_RECEIVER, /**< stream data from receiver to client */
|
||||
F_READ_RECEIVER_TIMER, /** < sets the timer between each data stream in receiver */
|
||||
F_SET_FLIPPED_DATA_RECEIVER, /** < sets the enable to flip data across x/y axis (bottom/top) */
|
||||
F_SET_RECEIVER_FILE_FORMAT, /** < sets the receiver file format */
|
||||
|
||||
F_SEND_RECEIVER_DETPOSID, /** < sets the detector position id in the reveiver */
|
||||
F_SEND_RECEIVER_MULTIDETSIZE, /** < sets the multi detector size to the receiver */
|
||||
F_SET_RECEIVER_STREAMING_PORT, /** < sets the receiver streaming port */
|
||||
|
||||
F_SET_RECEIVER_SILENT_MODE, /** < sets the receiver silent mode */
|
||||
F_RESTREAM_STOP_FROM_RECEIVER, /** < restream stop from receiver */
|
||||
/* Always append functions hereafter!!! */
|
||||
|
||||
|
||||
/* Always append functions before!!! */
|
||||
NUM_REC_FUNCTIONS
|
||||
};
|
||||
|
16
exampleCode/customReceiverExample/utilities.h
Executable file
16
exampleCode/customReceiverExample/utilities.h
Executable file
@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
#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);
|
||||
|
417
exampleCode/customReceiverExample/zmq.h
Executable file
417
exampleCode/customReceiverExample/zmq.h
Executable file
@ -0,0 +1,417 @@
|
||||
/*
|
||||
Copyright (c) 2007-2013 Contributors as noted in the AUTHORS file
|
||||
|
||||
This file is part of 0MQ.
|
||||
|
||||
0MQ is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
0MQ is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*************************************************************************
|
||||
NOTE to contributors. This file comprises the principal public contract
|
||||
for ZeroMQ API users (along with zmq_utils.h). Any change to this file
|
||||
supplied in a stable release SHOULD not break existing applications.
|
||||
In practice this means that the value of constants must not change, and
|
||||
that old values may not be reused for new constants.
|
||||
*************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef __ZMQ_H_INCLUDED__
|
||||
#define __ZMQ_H_INCLUDED__
|
||||
|
||||
/* Version macros for compile-time API version detection */
|
||||
#define ZMQ_VERSION_MAJOR 4
|
||||
#define ZMQ_VERSION_MINOR 0
|
||||
#define ZMQ_VERSION_PATCH 8
|
||||
|
||||
#define ZMQ_MAKE_VERSION(major, minor, patch) \
|
||||
((major) * 10000 + (minor) * 100 + (patch))
|
||||
#define ZMQ_VERSION \
|
||||
ZMQ_MAKE_VERSION(ZMQ_VERSION_MAJOR, ZMQ_VERSION_MINOR, ZMQ_VERSION_PATCH)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if !defined _WIN32_WCE
|
||||
#include <errno.h>
|
||||
#endif
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#if defined _WIN32
|
||||
#include <winsock2.h>
|
||||
#endif
|
||||
|
||||
/* Handle DSO symbol visibility */
|
||||
#if defined _WIN32
|
||||
# if defined ZMQ_STATIC
|
||||
# define ZMQ_EXPORT
|
||||
# elif defined DLL_EXPORT
|
||||
# define ZMQ_EXPORT __declspec(dllexport)
|
||||
# else
|
||||
# define ZMQ_EXPORT __declspec(dllimport)
|
||||
# endif
|
||||
#else
|
||||
# if defined __SUNPRO_C || defined __SUNPRO_CC
|
||||
# define ZMQ_EXPORT __global
|
||||
# elif (defined __GNUC__ && __GNUC__ >= 4) || defined __INTEL_COMPILER
|
||||
# define ZMQ_EXPORT __attribute__ ((visibility("default")))
|
||||
# else
|
||||
# define ZMQ_EXPORT
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Define integer types needed for event interface */
|
||||
#if defined ZMQ_HAVE_SOLARIS || defined ZMQ_HAVE_OPENVMS
|
||||
# include <inttypes.h>
|
||||
#elif defined _MSC_VER && _MSC_VER < 1600
|
||||
# ifndef int32_t
|
||||
typedef __int32 int32_t;
|
||||
# endif
|
||||
# ifndef uint16_t
|
||||
typedef unsigned __int16 uint16_t;
|
||||
# endif
|
||||
# ifndef uint8_t
|
||||
typedef unsigned __int8 uint8_t;
|
||||
# endif
|
||||
#else
|
||||
# include <stdint.h>
|
||||
#endif
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/* 0MQ errors. */
|
||||
/******************************************************************************/
|
||||
|
||||
/* A number random enough not to collide with different errno ranges on */
|
||||
/* different OSes. The assumption is that error_t is at least 32-bit type. */
|
||||
#define ZMQ_HAUSNUMERO 156384712
|
||||
|
||||
/* On Windows platform some of the standard POSIX errnos are not defined. */
|
||||
#ifndef ENOTSUP
|
||||
#define ENOTSUP (ZMQ_HAUSNUMERO + 1)
|
||||
#endif
|
||||
#ifndef EPROTONOSUPPORT
|
||||
#define EPROTONOSUPPORT (ZMQ_HAUSNUMERO + 2)
|
||||
#endif
|
||||
#ifndef ENOBUFS
|
||||
#define ENOBUFS (ZMQ_HAUSNUMERO + 3)
|
||||
#endif
|
||||
#ifndef ENETDOWN
|
||||
#define ENETDOWN (ZMQ_HAUSNUMERO + 4)
|
||||
#endif
|
||||
#ifndef EADDRINUSE
|
||||
#define EADDRINUSE (ZMQ_HAUSNUMERO + 5)
|
||||
#endif
|
||||
#ifndef EADDRNOTAVAIL
|
||||
#define EADDRNOTAVAIL (ZMQ_HAUSNUMERO + 6)
|
||||
#endif
|
||||
#ifndef ECONNREFUSED
|
||||
#define ECONNREFUSED (ZMQ_HAUSNUMERO + 7)
|
||||
#endif
|
||||
#ifndef EINPROGRESS
|
||||
#define EINPROGRESS (ZMQ_HAUSNUMERO + 8)
|
||||
#endif
|
||||
#ifndef ENOTSOCK
|
||||
#define ENOTSOCK (ZMQ_HAUSNUMERO + 9)
|
||||
#endif
|
||||
#ifndef EMSGSIZE
|
||||
#define EMSGSIZE (ZMQ_HAUSNUMERO + 10)
|
||||
#endif
|
||||
#ifndef EAFNOSUPPORT
|
||||
#define EAFNOSUPPORT (ZMQ_HAUSNUMERO + 11)
|
||||
#endif
|
||||
#ifndef ENETUNREACH
|
||||
#define ENETUNREACH (ZMQ_HAUSNUMERO + 12)
|
||||
#endif
|
||||
#ifndef ECONNABORTED
|
||||
#define ECONNABORTED (ZMQ_HAUSNUMERO + 13)
|
||||
#endif
|
||||
#ifndef ECONNRESET
|
||||
#define ECONNRESET (ZMQ_HAUSNUMERO + 14)
|
||||
#endif
|
||||
#ifndef ENOTCONN
|
||||
#define ENOTCONN (ZMQ_HAUSNUMERO + 15)
|
||||
#endif
|
||||
#ifndef ETIMEDOUT
|
||||
#define ETIMEDOUT (ZMQ_HAUSNUMERO + 16)
|
||||
#endif
|
||||
#ifndef EHOSTUNREACH
|
||||
#define EHOSTUNREACH (ZMQ_HAUSNUMERO + 17)
|
||||
#endif
|
||||
#ifndef ENETRESET
|
||||
#define ENETRESET (ZMQ_HAUSNUMERO + 18)
|
||||
#endif
|
||||
|
||||
/* Native 0MQ error codes. */
|
||||
#define EFSM (ZMQ_HAUSNUMERO + 51)
|
||||
#define ENOCOMPATPROTO (ZMQ_HAUSNUMERO + 52)
|
||||
#define ETERM (ZMQ_HAUSNUMERO + 53)
|
||||
#define EMTHREAD (ZMQ_HAUSNUMERO + 54)
|
||||
|
||||
/* Run-time API version detection */
|
||||
ZMQ_EXPORT void zmq_version (int *major, int *minor, int *patch);
|
||||
|
||||
/* This function retrieves the errno as it is known to 0MQ library. The goal */
|
||||
/* of this function is to make the code 100% portable, including where 0MQ */
|
||||
/* compiled with certain CRT library (on Windows) is linked to an */
|
||||
/* application that uses different CRT library. */
|
||||
ZMQ_EXPORT int zmq_errno (void);
|
||||
|
||||
/* Resolves system errors and 0MQ errors to human-readable string. */
|
||||
ZMQ_EXPORT const char *zmq_strerror (int errnum);
|
||||
|
||||
/******************************************************************************/
|
||||
/* 0MQ infrastructure (a.k.a. context) initialisation & termination. */
|
||||
/******************************************************************************/
|
||||
|
||||
/* New API */
|
||||
/* Context options */
|
||||
#define ZMQ_IO_THREADS 1
|
||||
#define ZMQ_MAX_SOCKETS 2
|
||||
|
||||
/* Default for new contexts */
|
||||
#define ZMQ_IO_THREADS_DFLT 1
|
||||
#define ZMQ_MAX_SOCKETS_DFLT 1023
|
||||
|
||||
ZMQ_EXPORT void *zmq_ctx_new (void);
|
||||
ZMQ_EXPORT int zmq_ctx_term (void *context);
|
||||
ZMQ_EXPORT int zmq_ctx_shutdown (void *ctx_);
|
||||
ZMQ_EXPORT int zmq_ctx_set (void *context, int option, int optval);
|
||||
ZMQ_EXPORT int zmq_ctx_get (void *context, int option);
|
||||
|
||||
/* Old (legacy) API */
|
||||
ZMQ_EXPORT void *zmq_init (int io_threads);
|
||||
ZMQ_EXPORT int zmq_term (void *context);
|
||||
ZMQ_EXPORT int zmq_ctx_destroy (void *context);
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/* 0MQ message definition. */
|
||||
/******************************************************************************/
|
||||
|
||||
typedef struct zmq_msg_t {unsigned char _ [32];} zmq_msg_t;
|
||||
|
||||
typedef void (zmq_free_fn) (void *data, void *hint);
|
||||
|
||||
ZMQ_EXPORT int zmq_msg_init (zmq_msg_t *msg);
|
||||
ZMQ_EXPORT int zmq_msg_init_size (zmq_msg_t *msg, size_t size);
|
||||
ZMQ_EXPORT int zmq_msg_init_data (zmq_msg_t *msg, void *data,
|
||||
size_t size, zmq_free_fn *ffn, void *hint);
|
||||
ZMQ_EXPORT int zmq_msg_send (zmq_msg_t *msg, void *s, int flags);
|
||||
ZMQ_EXPORT int zmq_msg_recv (zmq_msg_t *msg, void *s, int flags);
|
||||
ZMQ_EXPORT int zmq_msg_close (zmq_msg_t *msg);
|
||||
ZMQ_EXPORT int zmq_msg_move (zmq_msg_t *dest, zmq_msg_t *src);
|
||||
ZMQ_EXPORT int zmq_msg_copy (zmq_msg_t *dest, zmq_msg_t *src);
|
||||
ZMQ_EXPORT void *zmq_msg_data (zmq_msg_t *msg);
|
||||
ZMQ_EXPORT size_t zmq_msg_size (zmq_msg_t *msg);
|
||||
ZMQ_EXPORT int zmq_msg_more (zmq_msg_t *msg);
|
||||
ZMQ_EXPORT int zmq_msg_get (zmq_msg_t *msg, int option);
|
||||
ZMQ_EXPORT int zmq_msg_set (zmq_msg_t *msg, int option, int optval);
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/* 0MQ socket definition. */
|
||||
/******************************************************************************/
|
||||
|
||||
/* Socket types. */
|
||||
#define ZMQ_PAIR 0
|
||||
#define ZMQ_PUB 1
|
||||
#define ZMQ_SUB 2
|
||||
#define ZMQ_REQ 3
|
||||
#define ZMQ_REP 4
|
||||
#define ZMQ_DEALER 5
|
||||
#define ZMQ_ROUTER 6
|
||||
#define ZMQ_PULL 7
|
||||
#define ZMQ_PUSH 8
|
||||
#define ZMQ_XPUB 9
|
||||
#define ZMQ_XSUB 10
|
||||
#define ZMQ_STREAM 11
|
||||
|
||||
/* Deprecated aliases */
|
||||
#define ZMQ_XREQ ZMQ_DEALER
|
||||
#define ZMQ_XREP ZMQ_ROUTER
|
||||
|
||||
/* Socket options. */
|
||||
#define ZMQ_AFFINITY 4
|
||||
#define ZMQ_IDENTITY 5
|
||||
#define ZMQ_SUBSCRIBE 6
|
||||
#define ZMQ_UNSUBSCRIBE 7
|
||||
#define ZMQ_RATE 8
|
||||
#define ZMQ_RECOVERY_IVL 9
|
||||
#define ZMQ_SNDBUF 11
|
||||
#define ZMQ_RCVBUF 12
|
||||
#define ZMQ_RCVMORE 13
|
||||
#define ZMQ_FD 14
|
||||
#define ZMQ_EVENTS 15
|
||||
#define ZMQ_TYPE 16
|
||||
#define ZMQ_LINGER 17
|
||||
#define ZMQ_RECONNECT_IVL 18
|
||||
#define ZMQ_BACKLOG 19
|
||||
#define ZMQ_RECONNECT_IVL_MAX 21
|
||||
#define ZMQ_MAXMSGSIZE 22
|
||||
#define ZMQ_SNDHWM 23
|
||||
#define ZMQ_RCVHWM 24
|
||||
#define ZMQ_MULTICAST_HOPS 25
|
||||
#define ZMQ_RCVTIMEO 27
|
||||
#define ZMQ_SNDTIMEO 28
|
||||
#define ZMQ_LAST_ENDPOINT 32
|
||||
#define ZMQ_ROUTER_MANDATORY 33
|
||||
#define ZMQ_TCP_KEEPALIVE 34
|
||||
#define ZMQ_TCP_KEEPALIVE_CNT 35
|
||||
#define ZMQ_TCP_KEEPALIVE_IDLE 36
|
||||
#define ZMQ_TCP_KEEPALIVE_INTVL 37
|
||||
#define ZMQ_TCP_ACCEPT_FILTER 38
|
||||
#define ZMQ_IMMEDIATE 39
|
||||
#define ZMQ_XPUB_VERBOSE 40
|
||||
#define ZMQ_ROUTER_RAW 41
|
||||
#define ZMQ_IPV6 42
|
||||
#define ZMQ_MECHANISM 43
|
||||
#define ZMQ_PLAIN_SERVER 44
|
||||
#define ZMQ_PLAIN_USERNAME 45
|
||||
#define ZMQ_PLAIN_PASSWORD 46
|
||||
#define ZMQ_CURVE_SERVER 47
|
||||
#define ZMQ_CURVE_PUBLICKEY 48
|
||||
#define ZMQ_CURVE_SECRETKEY 49
|
||||
#define ZMQ_CURVE_SERVERKEY 50
|
||||
#define ZMQ_PROBE_ROUTER 51
|
||||
#define ZMQ_REQ_CORRELATE 52
|
||||
#define ZMQ_REQ_RELAXED 53
|
||||
#define ZMQ_CONFLATE 54
|
||||
#define ZMQ_ZAP_DOMAIN 55
|
||||
|
||||
/* Message options */
|
||||
#define ZMQ_MORE 1
|
||||
|
||||
/* Send/recv options. */
|
||||
#define ZMQ_DONTWAIT 1
|
||||
#define ZMQ_SNDMORE 2
|
||||
|
||||
/* Security mechanisms */
|
||||
#define ZMQ_NULL 0
|
||||
#define ZMQ_PLAIN 1
|
||||
#define ZMQ_CURVE 2
|
||||
|
||||
/* Deprecated options and aliases */
|
||||
#define ZMQ_IPV4ONLY 31
|
||||
#define ZMQ_DELAY_ATTACH_ON_CONNECT ZMQ_IMMEDIATE
|
||||
#define ZMQ_NOBLOCK ZMQ_DONTWAIT
|
||||
#define ZMQ_FAIL_UNROUTABLE ZMQ_ROUTER_MANDATORY
|
||||
#define ZMQ_ROUTER_BEHAVIOR ZMQ_ROUTER_MANDATORY
|
||||
|
||||
/******************************************************************************/
|
||||
/* 0MQ socket events and monitoring */
|
||||
/******************************************************************************/
|
||||
|
||||
/* Socket transport events (tcp and ipc only) */
|
||||
#define ZMQ_EVENT_CONNECTED 1
|
||||
#define ZMQ_EVENT_CONNECT_DELAYED 2
|
||||
#define ZMQ_EVENT_CONNECT_RETRIED 4
|
||||
|
||||
#define ZMQ_EVENT_LISTENING 8
|
||||
#define ZMQ_EVENT_BIND_FAILED 16
|
||||
|
||||
#define ZMQ_EVENT_ACCEPTED 32
|
||||
#define ZMQ_EVENT_ACCEPT_FAILED 64
|
||||
|
||||
#define ZMQ_EVENT_CLOSED 128
|
||||
#define ZMQ_EVENT_CLOSE_FAILED 256
|
||||
#define ZMQ_EVENT_DISCONNECTED 512
|
||||
#define ZMQ_EVENT_MONITOR_STOPPED 1024
|
||||
|
||||
#define ZMQ_EVENT_ALL ( ZMQ_EVENT_CONNECTED | ZMQ_EVENT_CONNECT_DELAYED | \
|
||||
ZMQ_EVENT_CONNECT_RETRIED | ZMQ_EVENT_LISTENING | \
|
||||
ZMQ_EVENT_BIND_FAILED | ZMQ_EVENT_ACCEPTED | \
|
||||
ZMQ_EVENT_ACCEPT_FAILED | ZMQ_EVENT_CLOSED | \
|
||||
ZMQ_EVENT_CLOSE_FAILED | ZMQ_EVENT_DISCONNECTED | \
|
||||
ZMQ_EVENT_MONITOR_STOPPED)
|
||||
|
||||
/* Socket event data */
|
||||
typedef struct {
|
||||
uint16_t event; // id of the event as bitfield
|
||||
int32_t value ; // value is either error code, fd or reconnect interval
|
||||
} zmq_event_t;
|
||||
|
||||
ZMQ_EXPORT void *zmq_socket (void *, int type);
|
||||
ZMQ_EXPORT int zmq_close (void *s);
|
||||
ZMQ_EXPORT int zmq_setsockopt (void *s, int option, const void *optval,
|
||||
size_t optvallen);
|
||||
ZMQ_EXPORT int zmq_getsockopt (void *s, int option, void *optval,
|
||||
size_t *optvallen);
|
||||
ZMQ_EXPORT int zmq_bind (void *s, const char *addr);
|
||||
ZMQ_EXPORT int zmq_connect (void *s, const char *addr);
|
||||
ZMQ_EXPORT int zmq_unbind (void *s, const char *addr);
|
||||
ZMQ_EXPORT int zmq_disconnect (void *s, const char *addr);
|
||||
ZMQ_EXPORT int zmq_send (void *s, const void *buf, size_t len, int flags);
|
||||
ZMQ_EXPORT int zmq_send_const (void *s, const void *buf, size_t len, int flags);
|
||||
ZMQ_EXPORT int zmq_recv (void *s, void *buf, size_t len, int flags);
|
||||
ZMQ_EXPORT int zmq_socket_monitor (void *s, const char *addr, int events);
|
||||
|
||||
ZMQ_EXPORT int zmq_sendmsg (void *s, zmq_msg_t *msg, int flags);
|
||||
ZMQ_EXPORT int zmq_recvmsg (void *s, zmq_msg_t *msg, int flags);
|
||||
|
||||
/* Experimental */
|
||||
struct iovec;
|
||||
|
||||
ZMQ_EXPORT int zmq_sendiov (void *s, struct iovec *iov, size_t count, int flags);
|
||||
ZMQ_EXPORT int zmq_recviov (void *s, struct iovec *iov, size_t *count, int flags);
|
||||
|
||||
/******************************************************************************/
|
||||
/* I/O multiplexing. */
|
||||
/******************************************************************************/
|
||||
|
||||
#define ZMQ_POLLIN 1
|
||||
#define ZMQ_POLLOUT 2
|
||||
#define ZMQ_POLLERR 4
|
||||
|
||||
typedef struct
|
||||
{
|
||||
void *socket;
|
||||
#if defined _WIN32
|
||||
SOCKET fd;
|
||||
#else
|
||||
int fd;
|
||||
#endif
|
||||
short events;
|
||||
short revents;
|
||||
} zmq_pollitem_t;
|
||||
|
||||
#define ZMQ_POLLITEMS_DFLT 16
|
||||
|
||||
ZMQ_EXPORT int zmq_poll (zmq_pollitem_t *items, int nitems, long timeout);
|
||||
|
||||
/* Built-in message proxy (3-way) */
|
||||
|
||||
ZMQ_EXPORT int zmq_proxy (void *frontend, void *backend, void *capture);
|
||||
ZMQ_EXPORT int zmq_proxy_steerable (void *frontend, void *backend, void *capture, void *control);
|
||||
|
||||
/* Encode a binary key as printable text using ZMQ RFC 32 */
|
||||
ZMQ_EXPORT char *zmq_z85_encode (char *dest, uint8_t *data, size_t size);
|
||||
|
||||
/* Encode a binary key from printable text per ZMQ RFC 32 */
|
||||
ZMQ_EXPORT uint8_t *zmq_z85_decode (uint8_t *dest, char *string);
|
||||
|
||||
/* Deprecated aliases */
|
||||
#define ZMQ_STREAMER 1
|
||||
#define ZMQ_FORWARDER 2
|
||||
#define ZMQ_QUEUE 3
|
||||
/* Deprecated method */
|
||||
ZMQ_EXPORT int zmq_device (int type, void *frontend, void *backend);
|
||||
|
||||
#undef ZMQ_EXPORT
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
35
exampleCode/slsDetectorUsersExample/CMakeLists.txt
Normal file
35
exampleCode/slsDetectorUsersExample/CMakeLists.txt
Normal file
@ -0,0 +1,35 @@
|
||||
set(SOURCES
|
||||
mainReceiver.cpp
|
||||
)
|
||||
|
||||
include_directories(
|
||||
../../slsReceiverSoftware/include
|
||||
../../slsDetectorSoftware/slsDetectorAnalysis
|
||||
../../build/bin
|
||||
../../slsdetectorSoftware/slsDetector
|
||||
)
|
||||
|
||||
add_executable(slsMultiReceiver
|
||||
${SOURCES}
|
||||
)
|
||||
|
||||
target_link_libraries(slsMultiReceiver
|
||||
slsReceiverShared
|
||||
pthread
|
||||
zmq
|
||||
rt
|
||||
${HDF5_LIBRARIES}
|
||||
)
|
||||
|
||||
if (HDF5_FOUND)
|
||||
target_link_libraries(slsMultiReceiver
|
||||
${HDF5_LIBRARIES}
|
||||
)
|
||||
endif ()
|
||||
|
||||
|
||||
set_target_properties(slsMultiReceiver PROPERTIES
|
||||
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
|
||||
)
|
||||
|
||||
install(TARGETS slsMultiReceiver DESTINATION bin)
|
62
exampleCode/slsDetectorUsersExample/Makefile
Executable file
62
exampleCode/slsDetectorUsersExample/Makefile
Executable file
@ -0,0 +1,62 @@
|
||||
PKGDIR = ../..
|
||||
LIBDIR = $(PKGDIR)/build/bin
|
||||
INCLUDES = -I . -I$(PKGDIR)/slsReceiverSoftware/include -I$(PKGDIR)/slsDetectorSoftware/slsDetectorAnalysis -I$(LIBDIR) -I$(PKGDIR)/slsDetectorSoftware/slsDetector
|
||||
SRC_DET = mainClient.cpp
|
||||
SRC_REC = mainReceiver.cpp
|
||||
ZMQLIBDIR = $(PKGDIR)/slsReceiverSoftware/include
|
||||
LDFLAG_DET = -I. -L$(LIBDIR) -Wl,-rpath=$(LIBDIR) -lSlsDetector -L/usr/lib64/ -pthread -lrt -L$(ZMQLIBDIR) -Wl,-rpath=$(ZMQLIBDIR) -lzmq
|
||||
LDFLAG_REC = -I. -L$(LIBDIR) -Wl,-rpath=$(LIBDIR) -lSlsReceiver -L/usr/lib64/ -pthread -lrt -L$(ZMQLIBDIR) -Wl,-rpath=$(ZMQLIBDIR) -lzmq
|
||||
DESTDIR ?= ../docs
|
||||
|
||||
HDF5 ?= no
|
||||
HDF5_DIR ?= /opt/hdf5v1.10.0
|
||||
|
||||
ifeq ($(HDF5),yes)
|
||||
LDFLAG_REC += -L$(HDF5_DIR)/lib -Wl,-rpath=$(HDF5_DIR)/lib -lhdf5 -lhdf5_cpp -lsz -lz -DHDF5C
|
||||
endif
|
||||
|
||||
all: docs detUser slsMultiReceiver
|
||||
#all: docs
|
||||
|
||||
docs: createdocs docspdf docshtml removedocs
|
||||
|
||||
createdocs: slsDetectorUsers.doxy mainClient.cpp mainReceiver.cpp
|
||||
doxygen slsDetectorUsers.doxy
|
||||
|
||||
docspdf:
|
||||
cd slsDetectorUsersDocs/latex && make
|
||||
$(shell test -d $(DESTDIR) || mkdir -p $(DESTDIR))
|
||||
$(shell test -d $(DESTDIR)/pdf || mkdir -p $(DESTDIR)/pdf)
|
||||
mv slsDetectorUsersDocs/latex/refman.pdf $(DESTDIR)/pdf/slsDetectorUsersDocs.pdf
|
||||
|
||||
docshtml:
|
||||
$(shell test -d $(DESTDIR) || mkdir -p $(DESTDIR))
|
||||
$(shell test -d $(DESTDIR)/html || mkdir -p $(DESTDIR)/html)
|
||||
$(shell test -d $(DESTDIR)/html/slsDetectorUsersDocs && rm -r $(DESTDIR)/html/slsDetectorUsersDocs)
|
||||
mv slsDetectorUsersDocs/html $(DESTDIR)/html/slsDetectorUsersDocs
|
||||
|
||||
removedocs:
|
||||
rm -rf slsDetectorUsersDocs;
|
||||
|
||||
detUser:$(SRC_DET)
|
||||
echo "creating client"
|
||||
mkdir -p bin
|
||||
g++ -o bin/detUser $(SRC_DET) $(INCLUDES) $(LDFLAG_DET) -lm -lstdc++
|
||||
|
||||
slsMultiReceiver:$(SRC_REC)
|
||||
echo "creating receiver"
|
||||
echo $LDFLAG_REC
|
||||
mkdir -p bin
|
||||
g++ -o bin/slsMultiReceiver $(SRC_REC) $(INCLUDES) $(LDFLAG_REC) -lm -lstdc++
|
||||
cp bin/slsMultiReceiver $(LIBDIR)
|
||||
|
||||
clean:
|
||||
echo "cleaning for manual-api"
|
||||
rm -rf bin/detUser bin/slsMultiReceiver bin/detReceiver slsDetectorUsersDocs
|
||||
rm -rf slsDetectorUsersDocs
|
||||
rm -rf $(DESTDIR)/html/slsDetectorUsersDocs
|
||||
rm -rf $(DESTDIR)/pdf/slsDetectorUsersDocs.pdf
|
||||
rm -rf $(LIBDIR)/slsMultiReceiver
|
||||
|
||||
|
||||
|
66
exampleCode/slsDetectorUsersExample/index.html
Executable file
66
exampleCode/slsDetectorUsersExample/index.html
Executable file
@ -0,0 +1,66 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
|
||||
<HTML><!-- #BeginTemplate "/templates/psi_template.dwt" -->
|
||||
<HEAD>
|
||||
|
||||
<!--#include virtual="/webbase/ssi/defaultvariables.shtml" -->
|
||||
|
||||
<!-- Change only the text within the 3 BeginEditable ... EndEditable Sections: -->
|
||||
<!-- MetaData - Definitions - BodyContent -->
|
||||
|
||||
<!-- #BeginEditable "MetaData" -->
|
||||
<TITLE>slsDetectorUsers Example</TITLE>
|
||||
<META name="keywords" content="slsDetectorUsers">
|
||||
<META name="description" content="SLS Detector Users Example">
|
||||
<META name="author" content="Anna Bergamaschi">
|
||||
<!-- #EndEditable -->
|
||||
|
||||
<!--#include virtual="/webbase/ssi/instructions.shtml" -->
|
||||
|
||||
<!--#include virtual="$PRJDIR/ssi/projectvariables.shtml" -->
|
||||
|
||||
<!-- # = Active changes to projectvariables or defaultvariables, no # = Inactive -->
|
||||
|
||||
<!-- #BeginEditable "Definitions" -->
|
||||
<!--#set var="PAGETITLE" value='Anna Bergamaschi' -->
|
||||
<!--set var="ALTLANGUAGE" value='english' -->
|
||||
<!--set var="DIRLANGUAGE" value='d/' -->
|
||||
<!--#set var="MAILTO" value='anna.bergamaschi@psi.ch' -->
|
||||
<!--#set var="MAILCC" value=' ' -->
|
||||
<!--set var="NAVTOP" value='/webbase/ssi/top_psi.shtml' -->
|
||||
<!--#set var="NAVLEFT" value='$SSIDIR/side.shtml' -->
|
||||
<!-- #EndEditable -->
|
||||
|
||||
<!--#include virtual="/webbase/ssi/head.shtml" -->
|
||||
|
||||
</head>
|
||||
|
||||
<!--#include virtual="/webbase/ssi/pretemplate.shtml" -->
|
||||
|
||||
<!-- #BeginEditable "BodyContent" -->
|
||||
|
||||
<H1>SLS Detector Users Example</H1>
|
||||
|
||||
<H3> Main Files </H3>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="CMakeLists.txt">CMakeLists.txt</a> This is called from main package cmake to create slsMultiReceiver.
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="Makefile">Makefile</a> Edit to properly link the slsDetector libraries to build/bin or bin
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="mainClient.cpp">mainClient.cpp</a> Example of control client
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="mainReceiver.cpp">mainReceiver.cpp</a> Example of receiver. Can be used in same process as client or a separate process.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<!-- #EndEditable -->
|
||||
|
||||
<!--#include virtual="/webbase/ssi/posttemplate.shtml" -->
|
||||
<!-- #EndTemplate -->
|
||||
</HTML>
|
106
exampleCode/slsDetectorUsersExample/mainClient.cpp
Executable file
106
exampleCode/slsDetectorUsersExample/mainClient.cpp
Executable file
@ -0,0 +1,106 @@
|
||||
/**
|
||||
\file mainClient.cpp
|
||||
|
||||
This file is an example of how to implement the slsDetectorUsers class
|
||||
You can compile it linking it to the slsDetector library
|
||||
|
||||
g++ mainClient.cpp -L lib -lSlsDetector -L/usr/lib64/ -L lib2 -lzmq -pthread -lrt -lm -lstdc++
|
||||
|
||||
where,
|
||||
|
||||
lib is the location of libSlsDetector.so
|
||||
|
||||
lib2 is the location of the libzmq.a.
|
||||
[ libzmq.a is required only when using data call backs and enabling data streaming from receiver to client.
|
||||
It is linked in manual/manual-api from slsReceiverSoftware/include ]
|
||||
|
||||
*/
|
||||
|
||||
#include "slsDetectorUsers.h"
|
||||
#include "detectorData.h"
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
|
||||
/**
|
||||
* Data Call back function defined
|
||||
* @param pData pointer to data structure received from the call back
|
||||
* @param iframe frame number of data passed
|
||||
* @param isubframe sub frame number of data passed ( only valid for EIGER in 32 bit mode)
|
||||
* @param pArg pointer to object
|
||||
* \returns integer that is currently ignored
|
||||
*/
|
||||
int dataCallback(detectorData *pData, int iframe, int isubframe, void *pArg)
|
||||
{
|
||||
std::cout << " DataCallback:"
|
||||
<< "\n nx : " << pData->npoints
|
||||
<< "\n ny : " << pData->npy
|
||||
<< "\n Frame number : " << iframe << std::endl;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Example of a main program using the slsDetectorUsers class
|
||||
*
|
||||
* - Arguments are optional
|
||||
* - argv[1] : Configuration File
|
||||
* - argv[2] : Measurement Setup File
|
||||
* - argv[3] : Detector Id (default is zero)
|
||||
*/
|
||||
int main(int argc, char **argv) {
|
||||
/** - if specified, set ID from argv[3] */
|
||||
int id=0;
|
||||
if (argc>=4)
|
||||
id=atoi(argv[3]);
|
||||
|
||||
|
||||
/** - slsDetectorUsers Object is instantiated with appropriate ID */
|
||||
int ret = 1;
|
||||
slsDetectorUsers *pDetector = new slsDetectorUsers (ret, id);
|
||||
if (ret == 1) {
|
||||
std::cout << "Error: Could not instantiate slsDetectorUsers" << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
|
||||
/** - if specified, load configuration file (necessary at least the first time it is called to properly configure advanced settings in the shared memory) */
|
||||
if (argc>=2){
|
||||
pDetector->readConfigurationFile(argv[1]);
|
||||
std::cout << "Detector configured" << std::endl;
|
||||
}
|
||||
|
||||
/** - set detector in shared memory online (in case no config file was used) */
|
||||
pDetector->setOnline(1);
|
||||
|
||||
/** - set receiver in shared memory online (in case no config file was used) */
|
||||
pDetector->setReceiverOnline(1);
|
||||
|
||||
/** - registering data callback */
|
||||
pDetector->registerDataCallback(&dataCallback, NULL);
|
||||
|
||||
|
||||
/** - ensuring detector status is idle before starting acquisition. exiting if not idle */
|
||||
int status = pDetector->getDetectorStatus();
|
||||
if (status != 0){
|
||||
std::cout << "Detector not ready: " << slsDetectorUsers::runStatusType(status) << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** - if provided, load detector settings */
|
||||
if (argc>=3){
|
||||
pDetector->retrieveDetectorSetup(argv[2]);
|
||||
std::cout << "Detector measurement set-up done" << std::endl;
|
||||
}
|
||||
|
||||
|
||||
/** - start measurement */
|
||||
pDetector->startMeasurement();
|
||||
std::cout << "measurement finished" << std::endl;
|
||||
|
||||
/** - returning when acquisition is finished or data are avilable */
|
||||
|
||||
/** - delete slsDetectorUsers object */
|
||||
delete pDetector;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
306
exampleCode/slsDetectorUsersExample/mainReceiver.cpp
Executable file
306
exampleCode/slsDetectorUsersExample/mainReceiver.cpp
Executable file
@ -0,0 +1,306 @@
|
||||
/**
|
||||
\file mainReceiver.cpp
|
||||
|
||||
This file is an example of how to implement the slsReceiverUsers class
|
||||
You can compile it linking it to the slsReceiver library
|
||||
|
||||
g++ mainReceiver.cpp -L lib -lSlsReceiver -L/usr/lib64/ -L lib2 -lzmq -pthread -lrt -lm -lstdc++
|
||||
|
||||
where,
|
||||
|
||||
lib is the location of lSlsReceiver.so
|
||||
|
||||
lib2 is the location of the libzmq.a.
|
||||
[ libzmq.a is required only when using data call backs and enabling data streaming from receiver to client.
|
||||
It is linked in manual/manual-api from slsReceiverSoftware/include ]
|
||||
|
||||
*/
|
||||
|
||||
#include "sls_receiver_defs.h"
|
||||
#include "slsReceiverUsers.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <string.h>
|
||||
#include <signal.h> //SIGINT
|
||||
#include <cstdlib> //system
|
||||
//#include "utilities.h"
|
||||
//#include "logger.h"
|
||||
#include <sys/types.h> //wait
|
||||
#include <sys/wait.h> //wait
|
||||
#include <string>
|
||||
#include <unistd.h> //usleep
|
||||
#include <errno.h>
|
||||
#include <syscall.h> //tid
|
||||
using namespace std;
|
||||
|
||||
|
||||
/** Define Colors to print data call back in different colors for different recievers */
|
||||
#define PRINT_IN_COLOR(c,f, ...) printf ("\033[%dm" f RESET, 30 + c+1, ##__VA_ARGS__)
|
||||
|
||||
|
||||
/** Variable is true to continue running, set to false upon interrupt */
|
||||
bool keeprunning;
|
||||
|
||||
/**
|
||||
* Control+C Interrupt Handler
|
||||
* Sets the variable keeprunning to false, to let all the processes know to exit properly
|
||||
*/
|
||||
void sigInterruptHandler(int p){
|
||||
keeprunning = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* prints usage of this example program
|
||||
*/
|
||||
void printHelp() {
|
||||
cprintf(RESET, "Usage:\n"
|
||||
"./slsMultiReceiver(detReceiver) [start_tcp_port] [num_receivers] [1 for call back, 0 for none]\n\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Start Acquisition Call back
|
||||
* slsReceiver writes data if file write enabled.
|
||||
* Users get data to write using call back if registerCallBackRawDataReady is registered.
|
||||
* @param filepath file path
|
||||
* @param filename file name
|
||||
* @param fileindex file index
|
||||
* @param datasize data size in bytes
|
||||
* @param p pointer to object
|
||||
* \returns ignored
|
||||
*/
|
||||
int StartAcq(char* filepath, char* filename, uint64_t fileindex, uint32_t datasize, void*p){
|
||||
cprintf(BLUE, "#### StartAcq: filepath:%s filename:%s fileindex:%llu datasize:%u ####\n",
|
||||
filepath, filename, (long long unsigned int)fileindex, datasize);
|
||||
|
||||
cprintf(BLUE, "--StartAcq: returning 0\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Acquisition Finished Call back
|
||||
* @param frames Number of frames caught
|
||||
* @param p pointer to object
|
||||
*/
|
||||
void AcquisitionFinished(uint64_t frames, void*p){
|
||||
cprintf(BLUE, "#### AcquisitionFinished: frames:%llu ####\n",(long long unsigned int)frames);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get Receiver Data Call back
|
||||
* Prints in different colors(for each receiver process) the different headers for each image call back.
|
||||
* @param metadata sls_receiver_header metadata
|
||||
* @param datapointer pointer to data
|
||||
* @param datasize data size in bytes.
|
||||
* @param p pointer to object
|
||||
*/
|
||||
void GetData(char* metadata, char* datapointer, uint32_t datasize, void* p){
|
||||
slsReceiverDefs::sls_receiver_header* header = (slsReceiverDefs::sls_receiver_header*)metadata;
|
||||
slsReceiverDefs::sls_detector_header detectorHeader = header->detHeader;
|
||||
|
||||
PRINT_IN_COLOR (detectorHeader.modId?detectorHeader.modId:detectorHeader.row,
|
||||
"#### %d GetData: ####\n"
|
||||
"frameNumber: %llu\t\texpLength: %u\t\tpacketNumber: %u\t\tbunchId: %llu"
|
||||
"\t\ttimestamp: %llu\t\tmodId: %u\t\t"
|
||||
"row: %u\t\tcolumn: %u\t\treserved: %u\t\tdebug: %u"
|
||||
"\t\troundRNumber: %u\t\tdetType: %u\t\tversion: %u"
|
||||
//"\t\tpacketsMask:%s"
|
||||
"\t\tfirstbytedata: 0x%x\t\tdatsize: %u\n\n",
|
||||
detectorHeader.row, (long long unsigned int)detectorHeader.frameNumber,
|
||||
detectorHeader.expLength, detectorHeader.packetNumber, (long long unsigned int)detectorHeader.bunchId,
|
||||
(long long unsigned int)detectorHeader.timestamp, detectorHeader.modId,
|
||||
detectorHeader.row, detectorHeader.column, detectorHeader.reserved,
|
||||
detectorHeader.debug, detectorHeader.roundRNumber,
|
||||
detectorHeader.detType, detectorHeader.version,
|
||||
//header->packetsMask.to_string().c_str(),
|
||||
((uint8_t)(*((uint8_t*)(datapointer)))), datasize);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get Receiver Data Call back (modified)
|
||||
* Prints in different colors(for each receiver process) the different headers for each image call back.
|
||||
* @param metadata sls_receiver_header metadata
|
||||
* @param datapointer pointer to data
|
||||
* @param datasize data size in bytes.
|
||||
* @param revDatasize new data size in bytes after the callback.
|
||||
* This will be the size written/streamed. (only smaller value is allowed).
|
||||
* @param p pointer to object
|
||||
*/
|
||||
void GetData(char* metadata, char* datapointer, uint32_t &revDatasize, void* p){
|
||||
slsReceiverDefs::sls_receiver_header* header = (slsReceiverDefs::sls_receiver_header*)metadata;
|
||||
slsReceiverDefs::sls_detector_header detectorHeader = header->detHeader;
|
||||
|
||||
PRINT_IN_COLOR (detectorHeader.modId?detectorHeader.modId:detectorHeader.row,
|
||||
"#### %d GetData: ####\n"
|
||||
"frameNumber: %llu\t\texpLength: %u\t\tpacketNumber: %u\t\tbunchId: %llu"
|
||||
"\t\ttimestamp: %llu\t\tmodId: %u\t\t"
|
||||
"row: %u\t\tcolumn: %u\t\treserved: %u\t\tdebug: %u"
|
||||
"\t\troundRNumber: %u\t\tdetType: %u\t\tversion: %u"
|
||||
//"\t\tpacketsMask:%s"
|
||||
"\t\tfirstbytedata: 0x%x\t\tdatsize: %u\n\n",
|
||||
detectorHeader.row, (long long unsigned int)detectorHeader.frameNumber,
|
||||
detectorHeader.expLength, detectorHeader.packetNumber, (long long unsigned int)detectorHeader.bunchId,
|
||||
(long long unsigned int)detectorHeader.timestamp, detectorHeader.modId,
|
||||
detectorHeader.row, detectorHeader.column, detectorHeader.reserved,
|
||||
detectorHeader.debug, detectorHeader.roundRNumber,
|
||||
detectorHeader.detType, detectorHeader.version,
|
||||
//header->packetsMask.to_string().c_str(),
|
||||
((uint8_t)(*((uint8_t*)(datapointer)))), revDatasize);
|
||||
|
||||
// if data is modified, eg ROI and size is reduced
|
||||
revDatasize = 26000;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Example of main program using the slsReceiverUsers class
|
||||
*
|
||||
* - Defines in file for:
|
||||
* - Default Number of receivers is 1
|
||||
* - Default Start TCP port is 1954
|
||||
*/
|
||||
int main(int argc, char *argv[]) {
|
||||
|
||||
/** - set default values */
|
||||
int numReceivers = 1;
|
||||
int startTCPPort = 1954;
|
||||
int withCallback = 0;
|
||||
keeprunning = true;
|
||||
|
||||
/** - get number of receivers and start tcp port from command line arguments */
|
||||
if ( (argc != 4) || (!sscanf(argv[1],"%d", &startTCPPort)) || (!sscanf(argv[2],"%d", &numReceivers)) || (!sscanf(argv[3],"%d", &withCallback)) )
|
||||
printHelp();
|
||||
cprintf(BLUE,"Parent Process Created [ Tid: %ld ]\n", (long)syscall(SYS_gettid));
|
||||
cprintf(RESET, "Number of Receivers: %d\n", numReceivers);
|
||||
cprintf(RESET, "Start TCP Port: %d\n", startTCPPort);
|
||||
cprintf(RESET, "Callback Enable: %d\n", withCallback);
|
||||
|
||||
|
||||
|
||||
/** - Catch signal SIGINT to close files and call destructors properly */
|
||||
struct sigaction sa;
|
||||
sa.sa_flags=0; // no flags
|
||||
sa.sa_handler=sigInterruptHandler; // handler function
|
||||
sigemptyset(&sa.sa_mask); // dont block additional signals during invocation of handler
|
||||
if (sigaction(SIGINT, &sa, NULL) == -1) {
|
||||
cprintf(RED, "Could not set handler function for SIGINT\n");
|
||||
}
|
||||
|
||||
/** - Ignore SIG_PIPE, prevents global signal handler, handle locally,
|
||||
instead of a server crashing due to client crash when writing, it just gives error */
|
||||
struct sigaction asa;
|
||||
asa.sa_flags=0; // no flags
|
||||
asa.sa_handler=SIG_IGN; // handler function
|
||||
sigemptyset(&asa.sa_mask); // dont block additional signals during invocation of handler
|
||||
if (sigaction(SIGPIPE, &asa, NULL) == -1) {
|
||||
cprintf(RED, "Could not set handler function for SIGPIPE\n");
|
||||
}
|
||||
|
||||
|
||||
/** - loop over number of receivers */
|
||||
for (int i = 0; i < numReceivers; ++i) {
|
||||
|
||||
/** - fork process to create child process */
|
||||
pid_t pid = fork();
|
||||
|
||||
/** - if fork failed, raise SIGINT and properly destroy all child processes */
|
||||
if (pid < 0) {
|
||||
cprintf(RED,"fork() failed. Killing all the receiver objects\n");
|
||||
raise(SIGINT);
|
||||
}
|
||||
|
||||
/** - if child process */
|
||||
else if (pid == 0) {
|
||||
cprintf(BLUE,"Child process %d [ Tid: %ld ]\n", i, (long)syscall(SYS_gettid));
|
||||
|
||||
char temp[10];
|
||||
sprintf(temp,"%d",startTCPPort + i);
|
||||
char* args[] = {(char*)"ignored", (char*)"--rx_tcpport", temp};
|
||||
int ret = slsReceiverDefs::OK;
|
||||
/** - create slsReceiverUsers object with appropriate arguments */
|
||||
slsReceiverUsers *receiver = new slsReceiverUsers(3, args, ret);
|
||||
if(ret==slsReceiverDefs::FAIL){
|
||||
delete receiver;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
|
||||
/** - register callbacks. remember to set file write enable to 0 (using the client)
|
||||
if we should not write files and you will write data using the callbacks */
|
||||
if (withCallback) {
|
||||
|
||||
/** - Call back for start acquisition */
|
||||
cprintf(BLUE, "Registering StartAcq()\n");
|
||||
receiver->registerCallBackStartAcquisition(StartAcq, NULL);
|
||||
|
||||
/** - Call back for acquisition finished */
|
||||
cprintf(BLUE, "Registering AcquisitionFinished()\n");
|
||||
receiver->registerCallBackAcquisitionFinished(AcquisitionFinished, NULL);
|
||||
|
||||
/* - Call back for raw data */
|
||||
cprintf(BLUE, "Registering GetData() \n");
|
||||
if (withCallback == 1) receiver->registerCallBackRawDataReady(GetData,NULL);
|
||||
else if (withCallback == 2) receiver->registerCallBackRawDataModifyReady(GetData,NULL);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** - start tcp server thread */
|
||||
if (receiver->start() == slsReceiverDefs::FAIL){
|
||||
delete receiver;
|
||||
cprintf(BLUE,"Exiting Child Process [ Tid: %ld ]\n", (long)syscall(SYS_gettid));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/** - as long as keeprunning is true (changes with Ctrl+C) */
|
||||
while(keeprunning)
|
||||
pause();
|
||||
/** - interrupt caught, delete slsReceiverUsers object and exit */
|
||||
delete receiver;
|
||||
cprintf(BLUE,"Exiting Child Process [ Tid: %ld ]\n", (long)syscall(SYS_gettid));
|
||||
exit(EXIT_SUCCESS);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/** - Parent process ignores SIGINT (exits only when all child process exits) */
|
||||
sa.sa_flags=0; // no flags
|
||||
sa.sa_handler=SIG_IGN; // handler function
|
||||
sigemptyset(&sa.sa_mask); // dont block additional signals during invocation of handler
|
||||
if (sigaction(SIGINT, &sa, NULL) == -1) {
|
||||
cprintf(RED, "Could not set handler function for SIGINT\n");
|
||||
}
|
||||
|
||||
|
||||
/** - Print Ready and Instructions how to exit */
|
||||
cout << "Ready ... " << endl;
|
||||
cprintf(RESET, "\n[ Press \'Ctrl+c\' to exit ]\n");
|
||||
|
||||
/** - Parent process waits for all child processes to exit */
|
||||
for(;;) {
|
||||
pid_t childPid = waitpid (-1, NULL, 0);
|
||||
|
||||
// no child closed
|
||||
if (childPid == -1) {
|
||||
if (errno == ECHILD) {
|
||||
cprintf(GREEN,"All Child Processes have been closed\n");
|
||||
break;
|
||||
} else {
|
||||
cprintf(RED, "Unexpected error from waitpid(): (%s)\n",strerror(errno));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//child closed
|
||||
cprintf(BLUE,"Exiting Child Process [ Tid: %ld ]\n", (long int) childPid);
|
||||
}
|
||||
|
||||
cout << "Goodbye!" << endl;
|
||||
return 0;
|
||||
}
|
||||
|
87
exampleCode/slsDetectorUsersExample/slsDetectorUsers.doxy
Executable file
87
exampleCode/slsDetectorUsersExample/slsDetectorUsers.doxy
Executable file
@ -0,0 +1,87 @@
|
||||
# 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 = YES
|
||||
|
||||
SHOW_FILES = YES
|
||||
|
||||
SHOW_NAMESPACES = NO
|
||||
|
||||
COMPACT_LATEX = YES
|
||||
|
||||
PAPER_TYPE = a4
|
||||
|
||||
PDF_HYPERLINKS = YES
|
||||
|
||||
USE_PDFLATEX = YES
|
||||
|
||||
LATEX_HIDE_INDICES = YES
|
||||
|
||||
SOURCE_BROWSER = YES
|
||||
|
||||
PREDEFINED = __cplusplus
|
||||
|
||||
INPUT = slsDetectorUsers.h detectorData.h slsReceiverUsers.h mainClient.cpp mainReceiver.cpp
|
||||
|
||||
OUTPUT_DIRECTORY = slsDetectorUsersDocs
|
Reference in New Issue
Block a user