mirror of
https://github.com/slsdetectorgroup/slsDetectorPackage.git
synced 2025-06-17 07:17:13 +02:00
Compare commits
22 Commits
2020.03.11
...
2020.03.18
Author | SHA1 | Date | |
---|---|---|---|
cb8403f1b0 | |||
b751238fc1 | |||
5479d3a198 | |||
e1768905dd | |||
775d0842e9 | |||
e7e201bd2a | |||
ec9f8305e9 | |||
3307bfab1b | |||
ce2c62000d | |||
cf817c4ec1 | |||
bd01a5f2d2 | |||
b059ba7c90 | |||
89d70097f6 | |||
41d115a394 | |||
45c1d3a553 | |||
17227be4df | |||
7f4f8e8f09 | |||
6809bd6567 | |||
711d40a56e | |||
81911fae3c | |||
f940397e3a | |||
dc53887a48 |
@ -203,11 +203,9 @@ if(SLS_BUILD_DOCS)
|
|||||||
add_subdirectory(docs)
|
add_subdirectory(docs)
|
||||||
endif(SLS_BUILD_DOCS)
|
endif(SLS_BUILD_DOCS)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if(SLS_MASTER_PROJECT)
|
if(SLS_MASTER_PROJECT)
|
||||||
# Set install dir CMake packages
|
# Set install dir CMake packages
|
||||||
set(CMAKE_INSTALL_DIR ${CMAKE_INSTALL_DATADIR}/cmake/sls)
|
set(CMAKE_INSTALL_DIR "share/cmake/${PROJECT_NAME}")
|
||||||
# Set the list of exported targets
|
# Set the list of exported targets
|
||||||
set(PROJECT_LIBRARIES slsSupportLib slsDetectorShared slsReceiverShared)
|
set(PROJECT_LIBRARIES slsSupportLib slsDetectorShared slsReceiverShared)
|
||||||
# Generate and install package config file and version
|
# Generate and install package config file and version
|
||||||
|
@ -15,17 +15,20 @@ configure_package_config_file(
|
|||||||
write_basic_package_version_file(
|
write_basic_package_version_file(
|
||||||
"${PROJECT_BINARY_DIR}/${PROJECT_NAME_LOWER}-config-version.cmake"
|
"${PROJECT_BINARY_DIR}/${PROJECT_NAME_LOWER}-config-version.cmake"
|
||||||
VERSION ${PROJECT_VERSION}
|
VERSION ${PROJECT_VERSION}
|
||||||
COMPATIBILITY SameMajorVersion)
|
COMPATIBILITY SameMajorVersion
|
||||||
|
)
|
||||||
|
|
||||||
install(FILES
|
install(FILES
|
||||||
"${PROJECT_BINARY_DIR}/${PROJECT_NAME_LOWER}-config.cmake"
|
"${PROJECT_BINARY_DIR}/${PROJECT_NAME_LOWER}-config.cmake"
|
||||||
"${PROJECT_BINARY_DIR}/${PROJECT_NAME_LOWER}-config-version.cmake"
|
"${PROJECT_BINARY_DIR}/${PROJECT_NAME_LOWER}-config-version.cmake"
|
||||||
COMPONENT devel
|
COMPONENT devel
|
||||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME_LOWER})
|
DESTINATION ${CMAKE_INSTALL_DIR}
|
||||||
|
)
|
||||||
|
|
||||||
if (PROJECT_LIBRARIES OR PROJECT_STATIC_LIBRARIES)
|
if (PROJECT_LIBRARIES OR PROJECT_STATIC_LIBRARIES)
|
||||||
install(
|
install(
|
||||||
EXPORT "${TARGETS_EXPORT_NAME}"
|
EXPORT "${TARGETS_EXPORT_NAME}"
|
||||||
FILE ${PROJECT_NAME_LOWER}-targets.cmake
|
FILE ${PROJECT_NAME_LOWER}-targets.cmake
|
||||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME_LOWER})
|
DESTINATION ${CMAKE_INSTALL_DIR}
|
||||||
|
)
|
||||||
endif ()
|
endif ()
|
||||||
|
@ -5,18 +5,20 @@ mkdir $PREFIX/include
|
|||||||
mkdir $PREFIX/include/slsDetectorPackage
|
mkdir $PREFIX/include/slsDetectorPackage
|
||||||
|
|
||||||
#Shared and static libraries
|
#Shared and static libraries
|
||||||
cp build/bin/libSlsDetector.so $PREFIX/lib/.
|
# cp build/bin/libSlsDetector.so $PREFIX/lib/.
|
||||||
cp build/bin/libSlsReceiver.so $PREFIX/lib/.
|
# cp build/bin/libSlsReceiver.so $PREFIX/lib/.
|
||||||
cp build/bin/libSlsSupport.so $PREFIX/lib/.
|
# cp build/bin/libSlsSupport.so $PREFIX/lib/.
|
||||||
|
|
||||||
|
cp build/install/lib/* $PREFIX/lib/
|
||||||
|
|
||||||
#Binaries
|
#Binaries
|
||||||
cp build/bin/sls_detector_acquire $PREFIX/bin/.
|
cp build/install/bin/sls_detector_acquire $PREFIX/bin/.
|
||||||
cp build/bin/sls_detector_get $PREFIX/bin/.
|
cp build/install/bin/sls_detector_get $PREFIX/bin/.
|
||||||
cp build/bin/sls_detector_put $PREFIX/bin/.
|
cp build/install/bin/sls_detector_put $PREFIX/bin/.
|
||||||
cp build/bin/sls_detector_help $PREFIX/bin/.
|
cp build/install/bin/sls_detector_help $PREFIX/bin/.
|
||||||
cp build/bin/slsReceiver $PREFIX/bin/.
|
cp build/install/bin/slsReceiver $PREFIX/bin/.
|
||||||
cp build/bin/slsMultiReceiver $PREFIX/bin/.
|
cp build/install/bin/slsMultiReceiver $PREFIX/bin/.
|
||||||
|
|
||||||
#Which headers do we need for development??
|
|
||||||
cp build/install/include/* $PREFIX/include/slsDetectorPackage/
|
cp build/install/include/* $PREFIX/include/
|
||||||
# cp include/some_lib.h $PREFIX/include/.
|
cp -r build/install/share/ $PREFIX/share
|
||||||
|
@ -7,7 +7,7 @@ source:
|
|||||||
- path: ..
|
- path: ..
|
||||||
|
|
||||||
build:
|
build:
|
||||||
number: 2
|
number: 0
|
||||||
binary_relocation: True
|
binary_relocation: True
|
||||||
rpaths:
|
rpaths:
|
||||||
- lib/
|
- lib/
|
||||||
@ -37,6 +37,7 @@ requirements:
|
|||||||
host:
|
host:
|
||||||
- libstdcxx-ng
|
- libstdcxx-ng
|
||||||
- libgcc-ng
|
- libgcc-ng
|
||||||
|
- zeromq
|
||||||
- xorg-libx11
|
- xorg-libx11
|
||||||
- xorg-libice
|
- xorg-libice
|
||||||
- xorg-libxext
|
- xorg-libxext
|
||||||
@ -46,6 +47,7 @@ requirements:
|
|||||||
- xorg-libxfixes
|
- xorg-libxfixes
|
||||||
|
|
||||||
run:
|
run:
|
||||||
|
- zeromq
|
||||||
- libstdcxx-ng
|
- libstdcxx-ng
|
||||||
- libgcc-ng
|
- libgcc-ng
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ find_package(Sphinx)
|
|||||||
|
|
||||||
|
|
||||||
if (DOXYGEN_FOUND AND SPHINX_FOUND)
|
if (DOXYGEN_FOUND AND SPHINX_FOUND)
|
||||||
message(${CMAKE_PROJECT_SORURCE_DIR}/slsDetectorSoftware/src)
|
# message(${CMAKE_PROJECT_SORURCE_DIR}/slsDetectorSoftware/src)
|
||||||
# Utility to generate command line documentation
|
# Utility to generate command line documentation
|
||||||
add_executable(gendoc src/gendoc.cpp)
|
add_executable(gendoc src/gendoc.cpp)
|
||||||
# This is a bit hacky, but better than exposing stuff?
|
# This is a bit hacky, but better than exposing stuff?
|
||||||
@ -30,6 +30,7 @@ if (DOXYGEN_FOUND AND SPHINX_FOUND)
|
|||||||
set(SPHINX_SOURCE_FILES
|
set(SPHINX_SOURCE_FILES
|
||||||
src/commandline.rst
|
src/commandline.rst
|
||||||
src/container_utils.rst
|
src/container_utils.rst
|
||||||
|
src/consuming.rst
|
||||||
src/dependencies.rst
|
src/dependencies.rst
|
||||||
src/detector.rst
|
src/detector.rst
|
||||||
src/index.rst
|
src/index.rst
|
||||||
@ -41,6 +42,7 @@ if (DOXYGEN_FOUND AND SPHINX_FOUND)
|
|||||||
src/result.rst
|
src/result.rst
|
||||||
src/type_traits.rst
|
src/type_traits.rst
|
||||||
src/ToString.rst
|
src/ToString.rst
|
||||||
|
src/examples.rst
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
95
docs/src/consuming.rst
Normal file
95
docs/src/consuming.rst
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
Consuming slsDetectorPackage
|
||||||
|
===============================
|
||||||
|
|
||||||
|
Depending on how you want to build your integration with
|
||||||
|
slsDetectorPackage there are a few different ways to
|
||||||
|
consume our package. The recommended way is to use one of the
|
||||||
|
CMake approaches.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
CMake: slsDetectorPackage as submodule in your project
|
||||||
|
---------------------------------------
|
||||||
|
|
||||||
|
If you are using CMake to build your integration and want to build everything
|
||||||
|
in one go, we support adding slsDetectorPackage as a subfolder in your cmake project.
|
||||||
|
|
||||||
|
A minimal CMakeLists.txt could look like this:
|
||||||
|
|
||||||
|
.. code-block:: cmake
|
||||||
|
|
||||||
|
project(myDetectorIntegration)
|
||||||
|
cmake_minimum_required(VERSION 3.12)
|
||||||
|
add_subdirectory(slsDetectorPackage)
|
||||||
|
|
||||||
|
#Add your executable
|
||||||
|
add_executable(example main.cpp)
|
||||||
|
target_compile_features(example PRIVATE cxx_std_11)
|
||||||
|
|
||||||
|
#Link towards slsDetectorShared
|
||||||
|
target_link_libraries(example slsDetectorShared)
|
||||||
|
|
||||||
|
A fully working example can be found at:
|
||||||
|
|
||||||
|
https://github.com/slsdetectorgroup/cmake-subfolder-example
|
||||||
|
|
||||||
|
|
||||||
|
CMake: find_package(slsDetectorPackage)
|
||||||
|
------------------------------------------
|
||||||
|
|
||||||
|
If you have compiled and installed slsDetectorPackage we also support
|
||||||
|
find_package in CMake. If installed in a system wide location no path
|
||||||
|
should be needed, otherwise specify cmake prefix path.
|
||||||
|
|
||||||
|
.. code-block:: cmake
|
||||||
|
|
||||||
|
cmake_minimum_required(VERSION 3.12)
|
||||||
|
project(myintegration)
|
||||||
|
|
||||||
|
find_package(slsDetectorPackage 5.0 REQUIRED)
|
||||||
|
add_executable(example main.cpp)
|
||||||
|
target_link_libraries(example slsDetectorShared)
|
||||||
|
|
||||||
|
|
||||||
|
Then assuming the slsDetectorPackage is installed in /path/to/sls/install
|
||||||
|
you should be able to configure and build your project in this way.
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
cmake ../path/to/your/source -DCMAKE_PREFIX_PATH=/path/to/sls/install
|
||||||
|
make
|
||||||
|
|
||||||
|
|
||||||
|
A minimal example is available at: https://github.com/slsdetectorgroup/minimal-cmake
|
||||||
|
|
||||||
|
No tools minimal approach
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
While not recommended it is still possible to specify the include and library paths
|
||||||
|
manually when invoking g++. This can sometimes be handy for a quick try.
|
||||||
|
|
||||||
|
.. code-block:: cpp
|
||||||
|
|
||||||
|
#include "Detector.h"
|
||||||
|
#include <iostream>
|
||||||
|
int main(){
|
||||||
|
|
||||||
|
sls::Detector det;
|
||||||
|
|
||||||
|
//Get all values and print them
|
||||||
|
std::cout << "Hostname: " << det.getHostname() << "\n";
|
||||||
|
std::cout << "Type: " << det.getDetectorType() << "\n";
|
||||||
|
std::cout << "Udp ip: " << det.getSourceUDPIP() << "\n";
|
||||||
|
|
||||||
|
|
||||||
|
//Get mac addr
|
||||||
|
const int module = 0;
|
||||||
|
auto mac = det.getSourceUDPMAC()[module];
|
||||||
|
std::cout << "Mac addr of module "<< module << " is " << mac.str() << '\n';
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
g++ -I/install/path/include/ -L/install/path/lib64/ myapp.cpp -lSlsDetector -lSlsSupport -Wl,-rpath=../install/path/lib64
|
@ -13,7 +13,7 @@ To use the basic building blocks, meaning sls_detector_get/put and
|
|||||||
the shared libraries these are needed:
|
the shared libraries these are needed:
|
||||||
|
|
||||||
* Linux, preferably recent kernel (currently no cross platform support)
|
* Linux, preferably recent kernel (currently no cross platform support)
|
||||||
* CMake > 3.9
|
* CMake > 3.12
|
||||||
* C++11 compatible compiler. (We test with gcc and clang)
|
* C++11 compatible compiler. (We test with gcc and clang)
|
||||||
* ZeroMQ version 4
|
* ZeroMQ version 4
|
||||||
|
|
||||||
@ -24,7 +24,7 @@ GUI
|
|||||||
The GUI is currently using Qt4 but watch out for an upgrade to 5.
|
The GUI is currently using Qt4 but watch out for an upgrade to 5.
|
||||||
|
|
||||||
* Qt 4.8
|
* Qt 4.8
|
||||||
* Qwt 6
|
* Qwt 6.1
|
||||||
|
|
||||||
-----------------------
|
-----------------------
|
||||||
Python bindings
|
Python bindings
|
||||||
|
115
docs/src/examples.rst
Normal file
115
docs/src/examples.rst
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Examples
|
||||||
|
===========
|
||||||
|
|
||||||
|
Setup
|
||||||
|
------------
|
||||||
|
|
||||||
|
The examples here assume that you have compiled and installed slsDetectorPackage
|
||||||
|
to ~/sls/install and that the option for SLS_USE_SIMULATOR was enabled. This also builds
|
||||||
|
the virtual detector servers that we will be using for testing.
|
||||||
|
|
||||||
|
We also add ~/sls/detector/install/bin to the path for convenience.
|
||||||
|
|
||||||
|
Compile examples
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
The source code of the examples is available at:
|
||||||
|
https://github.com/slsdetectorgroup/api-examples
|
||||||
|
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
git clone https://github.com/slsdetectorgroup/api-examples.git
|
||||||
|
mkdir build && cd build
|
||||||
|
cmake ../api-examples -DCMAKE_PREFIX_PATH=~/sls/detector/install
|
||||||
|
make
|
||||||
|
|
||||||
|
Below follows a short description of what is included in the examples.
|
||||||
|
|
||||||
|
|
||||||
|
Running a config file [e1]
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
|
||||||
|
.. code-block:: cpp
|
||||||
|
|
||||||
|
#include "Detector.h"
|
||||||
|
...
|
||||||
|
sls::Detector det;
|
||||||
|
det.loadConfig("path/to/config/file.config");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
To configure the connection between PC and detector the easiest
|
||||||
|
is to run a config file. For this example we first launch a virtual Jungfrau server and
|
||||||
|
then set up the detector.
|
||||||
|
|
||||||
|
**Launch a virtual detector server**
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
jungfrauDetectorServer_virtual
|
||||||
|
|
||||||
|
This launches a virtual Jungfrau detector server. As default is uses port 1952 and 1953
|
||||||
|
for communication over TCP. Most commands go on 1952 and only stop and status on 1953.
|
||||||
|
|
||||||
|
**Run example to configure**
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
./e1-config one_det_no_receiver.config
|
||||||
|
- 12:01:06.371 INFO: Shared memory deleted /slsDetectorPackage_multi_0_sls_0
|
||||||
|
- 12:01:06.371 INFO: Shared memory deleted /slsDetectorPackage_multi_0
|
||||||
|
- 12:01:06.372 INFO: Shared memory created /slsDetectorPackage_multi_0
|
||||||
|
- 12:01:06.376 INFO: Loading configuration file: one_det_no_receiver.config
|
||||||
|
- 12:01:06.376 INFO: Adding detector localhost
|
||||||
|
- 12:01:06.377 INFO: Shared memory created /slsDetectorPackage_multi_0_sls_0
|
||||||
|
- 12:01:06.377 INFO: Checking Detector Version Compatibility
|
||||||
|
- 12:01:06.378 INFO: Detector connecting - updating!
|
||||||
|
hostname [localhost]
|
||||||
|
|
||||||
|
|
||||||
|
Jungfrau detector with 1 modules configured
|
||||||
|
|
||||||
|
|
||||||
|
Using the return type sls::Result [e2]
|
||||||
|
-----------------------------------------
|
||||||
|
|
||||||
|
Since many our detectors have multiple modules we cannot return
|
||||||
|
a single value when reading from the Detector. Hostname, Ip and also
|
||||||
|
for example exposure time can differ between modules.
|
||||||
|
|
||||||
|
Therefore we return Result<T> which is a thin wrapper around
|
||||||
|
std::vector.
|
||||||
|
|
||||||
|
.. code-block:: cpp
|
||||||
|
|
||||||
|
sls::Result<int> res1{1, 1, 1};
|
||||||
|
std::cout << "res1: " << res1 << '\n';
|
||||||
|
res1.squash();
|
||||||
|
res1.squash(-1);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Setting exposure time [e3]
|
||||||
|
-----------------------------------------
|
||||||
|
|
||||||
|
For setting times, like exposure time, period, delay etc.
|
||||||
|
we use std::chrono::duration.
|
||||||
|
|
||||||
|
Example 3 shows how to set and read exposure time as well
|
||||||
|
as converting to floating point.
|
||||||
|
|
||||||
|
.. code-block:: cpp
|
||||||
|
|
||||||
|
#include "Detector.h"
|
||||||
|
#include <chrono>
|
||||||
|
...
|
||||||
|
std::chrono::microseconds t0{500};
|
||||||
|
det.setExptime(t0);
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -6,12 +6,18 @@
|
|||||||
Welcome to slsDetectorPackage's documentation!
|
Welcome to slsDetectorPackage's documentation!
|
||||||
==============================================
|
==============================================
|
||||||
|
|
||||||
|
.. note ::
|
||||||
|
|
||||||
|
This is the documentation for the latest development version of slsDetectorPackage
|
||||||
|
For documentation on current and previous releases visit the official page: https://www.psi.ch/en/detectors/documentation
|
||||||
|
|
||||||
.. toctree::
|
.. toctree::
|
||||||
:maxdepth: 1
|
:maxdepth: 1
|
||||||
:caption: Installation:
|
:caption: Installation:
|
||||||
|
|
||||||
installation
|
installation
|
||||||
dependencies
|
dependencies
|
||||||
|
consuming
|
||||||
|
|
||||||
.. toctree::
|
.. toctree::
|
||||||
:caption: C++ API
|
:caption: C++ API
|
||||||
@ -20,6 +26,7 @@ Welcome to slsDetectorPackage's documentation!
|
|||||||
detector
|
detector
|
||||||
result
|
result
|
||||||
receiver
|
receiver
|
||||||
|
examples
|
||||||
|
|
||||||
.. toctree::
|
.. toctree::
|
||||||
:caption: Python API
|
:caption: Python API
|
||||||
|
@ -2,4 +2,24 @@
|
|||||||
Installation
|
Installation
|
||||||
==============================================
|
==============================================
|
||||||
|
|
||||||
get the source etc.
|
Build from source using CMake
|
||||||
|
---------------------------------
|
||||||
|
|
||||||
|
.. note ::
|
||||||
|
|
||||||
|
The default branch of our git repository is developer. It contains the
|
||||||
|
latest development version. It is expected to compile and work but
|
||||||
|
features might be added or tweaked. In some cases the API might also change
|
||||||
|
without being communicated. If absolute stability of the API is needed please
|
||||||
|
use one of the release versions.
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
git clone https://github.com/slsdetectorgroup/slsDetectorPackage.git
|
||||||
|
mkdir build && cd build
|
||||||
|
cmake ../slsDetectorPackage -DCMAKE_INSTALL_PREFIX=/your/install/path
|
||||||
|
make -j12
|
||||||
|
make install
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
Detector
|
Detector
|
||||||
=====================================================
|
=====================================================
|
||||||
|
|
||||||
.. py:currentmodule:: sls_detector
|
.. py:currentmodule:: slsdet
|
||||||
|
|
||||||
.. autoclass:: ExperimentalDetector
|
.. autoclass:: Detector
|
||||||
:members:
|
:members:
|
||||||
:undoc-members:
|
:undoc-members:
|
||||||
:show-inheritance:
|
:show-inheritance:
|
@ -45,7 +45,7 @@ ext_modules = [
|
|||||||
# get_pybind_include(),
|
# get_pybind_include(),
|
||||||
# get_pybind_include(user=True),
|
# get_pybind_include(user=True),
|
||||||
os.path.join('../libs/pybind11/include'),
|
os.path.join('../libs/pybind11/include'),
|
||||||
os.path.join(get_conda_path(), 'include/slsDetectorPackage'),
|
os.path.join(get_conda_path(), 'include'),
|
||||||
|
|
||||||
],
|
],
|
||||||
libraries=['SlsDetector', 'SlsReceiver', 'zmq'],
|
libraries=['SlsDetector', 'SlsReceiver', 'zmq'],
|
||||||
|
@ -103,10 +103,10 @@ set_target_properties(slsDetectorGui PROPERTIES
|
|||||||
)
|
)
|
||||||
|
|
||||||
install(TARGETS slsDetectorGui
|
install(TARGETS slsDetectorGui
|
||||||
EXPORT "${TARGETS_EXPORT_NAME}"
|
# EXPORT "${TARGETS_EXPORT_NAME}"
|
||||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
# LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
# ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||||
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
|
# PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#include "SlsQt2DPlot.h"
|
#include "SlsQt2DPlot.h"
|
||||||
#include "ansi.h"
|
// #include "ansi.h"
|
||||||
|
|
||||||
#include <qlist.h>
|
#include <qlist.h>
|
||||||
#include <qprinter.h>
|
#include <qprinter.h>
|
||||||
|
Binary file not shown.
@ -47,9 +47,10 @@ int injectedChannelsIncrement = 0;
|
|||||||
int vetoReference[NCHIP][NCHAN];
|
int vetoReference[NCHIP][NCHAN];
|
||||||
uint8_t adcConfiguration[NCHIP][NADC];
|
uint8_t adcConfiguration[NCHIP][NADC];
|
||||||
int burstMode = BURST_INTERNAL;
|
int burstMode = BURST_INTERNAL;
|
||||||
int64_t numTriggers = 1;
|
int64_t numTriggersReg = 1;
|
||||||
int64_t numBursts = 1;
|
int64_t delayReg = 0;
|
||||||
int64_t burstPeriodNs = 0;
|
int64_t numBurstsReg = 1;
|
||||||
|
int64_t burstPeriodReg = 0;
|
||||||
int detPos[2] = {};
|
int detPos[2] = {};
|
||||||
|
|
||||||
int isInitCheckDone() {
|
int isInitCheckDone() {
|
||||||
@ -354,9 +355,10 @@ void setupDetector() {
|
|||||||
injectedChannelsOffset = 0;
|
injectedChannelsOffset = 0;
|
||||||
injectedChannelsIncrement = 0;
|
injectedChannelsIncrement = 0;
|
||||||
burstMode = BURST_INTERNAL;
|
burstMode = BURST_INTERNAL;
|
||||||
numTriggers = 1;
|
numTriggersReg = 1;
|
||||||
numBursts = 1;
|
delayReg = 0;
|
||||||
burstPeriodNs = 0;
|
numBurstsReg = 1;
|
||||||
|
burstPeriodReg = 0;
|
||||||
{
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
for (i = 0; i < NUM_CLOCKS; ++i) {
|
for (i = 0; i < NUM_CLOCKS; ++i) {
|
||||||
@ -736,32 +738,31 @@ int setDynamicRange(int dr){
|
|||||||
/* parameters - timer */
|
/* parameters - timer */
|
||||||
void setNumFrames(int64_t val) {
|
void setNumFrames(int64_t val) {
|
||||||
if (val > 0) {
|
if (val > 0) {
|
||||||
LOG(logINFO, ("Setting number of frames %lld [local]\n", val));
|
|
||||||
// continuous mode
|
|
||||||
if (burstMode == BURST_OFF) {
|
if (burstMode == BURST_OFF) {
|
||||||
setNumFramesCont(val);
|
LOG(logINFO, ("Setting number of frames %lld [Continuous mode]\n", val));
|
||||||
setNumFramesBurst(1);
|
set64BitReg(val, SET_FRAMES_LSB_REG, SET_FRAMES_MSB_REG);
|
||||||
} else {
|
} else {
|
||||||
setNumFramesBurst(val);
|
LOG(logINFO, ("Setting number of frames %d [Burst mode]\n", (int)val));
|
||||||
setNumFramesCont(1);
|
bus_w(ASIC_INT_FRAMES_REG, bus_r(ASIC_INT_FRAMES_REG) &~ ASIC_INT_FRAMES_MSK);
|
||||||
|
bus_w(ASIC_INT_FRAMES_REG, bus_r(ASIC_INT_FRAMES_REG) | (((int)val << ASIC_INT_FRAMES_OFST) & ASIC_INT_FRAMES_MSK));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t getNumFrames() {
|
int64_t getNumFrames() {
|
||||||
if (burstMode == BURST_OFF) {
|
if (burstMode == BURST_OFF) {
|
||||||
return getNumFramesCont();
|
return get64BitReg(SET_FRAMES_LSB_REG, SET_FRAMES_MSB_REG);
|
||||||
} else {
|
} else {
|
||||||
return getNumFramesBurst();
|
return ((bus_r(ASIC_INT_FRAMES_REG) & ASIC_INT_FRAMES_MSK) >> ASIC_INT_FRAMES_OFST);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void setNumTriggers(int64_t val) {
|
void setNumTriggers(int64_t val) {
|
||||||
if (val > 0) {
|
if (val > 0) {
|
||||||
LOG(logINFO, ("Setting number of triggers %lld\n", val));
|
LOG(logINFO, ("Setting number of triggers %lld\n", val));
|
||||||
numTriggers = val;
|
if (getTiming() == AUTO_TIMING) {
|
||||||
if (burstMode != BURST_OFF && getTiming() == AUTO_TIMING) {
|
LOG(logINFO, ("\tNot trigger mode: not writing to register\n"));
|
||||||
LOG(logINFO, ("\tBurst and Auto mode: not writing #triggers to register\n"));
|
numTriggersReg = val;
|
||||||
} else {
|
} else {
|
||||||
set64BitReg(val, SET_CYCLES_LSB_REG, SET_CYCLES_MSB_REG);
|
set64BitReg(val, SET_CYCLES_LSB_REG, SET_CYCLES_MSB_REG);
|
||||||
}
|
}
|
||||||
@ -769,8 +770,8 @@ void setNumTriggers(int64_t val) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int64_t getNumTriggers() {
|
int64_t getNumTriggers() {
|
||||||
if (burstMode != BURST_OFF && getTiming() == AUTO_TIMING) {
|
if (getTiming() == AUTO_TIMING) {
|
||||||
return numTriggers;
|
return numTriggersReg;
|
||||||
}
|
}
|
||||||
return get64BitReg(SET_CYCLES_LSB_REG, SET_CYCLES_MSB_REG);
|
return get64BitReg(SET_CYCLES_LSB_REG, SET_CYCLES_MSB_REG);
|
||||||
}
|
}
|
||||||
@ -778,20 +779,20 @@ int64_t getNumTriggers() {
|
|||||||
void setNumBursts(int64_t val) {
|
void setNumBursts(int64_t val) {
|
||||||
if (val > 0) {
|
if (val > 0) {
|
||||||
LOG(logINFO, ("Setting number of bursts %lld\n", val));
|
LOG(logINFO, ("Setting number of bursts %lld\n", val));
|
||||||
numBursts = val;
|
|
||||||
if (burstMode != BURST_OFF && getTiming() == AUTO_TIMING) {
|
if (burstMode != BURST_OFF && getTiming() == AUTO_TIMING) {
|
||||||
set64BitReg(val, SET_CYCLES_LSB_REG, SET_CYCLES_MSB_REG);
|
set64BitReg(val, SET_FRAMES_LSB_REG, SET_FRAMES_MSB_REG);
|
||||||
} else {
|
} else {
|
||||||
LOG(logINFO, ("\tNot (Burst and Auto mode): not writing #bursts to register\n"));
|
LOG(logINFO, ("\tNot (Burst and Auto mode): not writing to register\n"));
|
||||||
|
numBurstsReg = val;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t getNumBursts() {
|
int64_t getNumBursts() {
|
||||||
if (burstMode != BURST_OFF && getTiming() == AUTO_TIMING) {
|
if (burstMode != BURST_OFF && getTiming() == AUTO_TIMING) {
|
||||||
return get64BitReg(SET_CYCLES_LSB_REG, SET_CYCLES_MSB_REG);
|
return get64BitReg(SET_FRAMES_LSB_REG, SET_FRAMES_MSB_REG);
|
||||||
}
|
}
|
||||||
return numBursts;
|
return numBurstsReg;
|
||||||
}
|
}
|
||||||
|
|
||||||
int setExpTime(int64_t val) {
|
int setExpTime(int64_t val) {
|
||||||
@ -799,17 +800,21 @@ int setExpTime(int64_t val) {
|
|||||||
LOG(logERROR, ("Invalid exptime: %lld ns\n", val));
|
LOG(logERROR, ("Invalid exptime: %lld ns\n", val));
|
||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
LOG(logINFO, ("Setting exptime %lld ns [local]\n", val));
|
LOG(logINFO, ("Setting exptime %lld ns\n", val));
|
||||||
// continuous mode
|
val *= (1E-9 * systemFrequency);
|
||||||
if (burstMode == BURST_OFF) {
|
set64BitReg(val, ASIC_INT_EXPTIME_LSB_REG, ASIC_INT_EXPTIME_MSB_REG);
|
||||||
return setExptimeCont(val);
|
|
||||||
} else {
|
// validate for tolerance
|
||||||
return setExptimeBurst(val);
|
int64_t retval = getExpTime();
|
||||||
}
|
val /= (1E-9 * systemFrequency);
|
||||||
|
if (val != retval) {
|
||||||
|
return FAIL;
|
||||||
|
}
|
||||||
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t getExpTime() {
|
int64_t getExpTime() {
|
||||||
return getExptimeBoth();
|
return get64BitReg(ASIC_INT_EXPTIME_LSB_REG, ASIC_INT_EXPTIME_MSB_REG) / (1E-9 * systemFrequency);
|
||||||
}
|
}
|
||||||
|
|
||||||
int setPeriod(int64_t val) {
|
int setPeriod(int64_t val) {
|
||||||
@ -817,110 +822,31 @@ int setPeriod(int64_t val) {
|
|||||||
LOG(logERROR, ("Invalid period: %lld ns\n", val));
|
LOG(logERROR, ("Invalid period: %lld ns\n", val));
|
||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
LOG(logINFO, ("Setting period %lld ns [local]\n", val));
|
val *= (1E-9 * systemFrequency);
|
||||||
// continuous mode
|
|
||||||
if (burstMode == BURST_OFF) {
|
if (burstMode == BURST_OFF) {
|
||||||
setPeriodBurst(0);
|
LOG(logINFO, ("Setting period %lld ns [Continuous mode]\n", val));
|
||||||
return setPeriodCont(val);
|
set64BitReg(val, SET_PERIOD_LSB_REG, SET_PERIOD_MSB_REG);
|
||||||
} else {
|
} else {
|
||||||
//setPeriodCont(0);
|
LOG(logINFO, ("Setting period %lld ns [Burst mode]\n", val));
|
||||||
return setPeriodBurst(val);
|
set64BitReg(val, ASIC_INT_PERIOD_LSB_REG, ASIC_INT_PERIOD_MSB_REG);
|
||||||
}
|
}
|
||||||
|
// validate for tolerance
|
||||||
|
int64_t retval = getPeriod();
|
||||||
|
val /= (1E-9 * systemFrequency);
|
||||||
|
if (val != retval) {
|
||||||
|
return FAIL;
|
||||||
|
}
|
||||||
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t getPeriod() {
|
int64_t getPeriod() {
|
||||||
if (burstMode == BURST_OFF) {
|
if (burstMode == BURST_OFF) {
|
||||||
return getPeriodCont();
|
return get64BitReg(SET_PERIOD_LSB_REG, SET_PERIOD_MSB_REG)/ (1E-9 * systemFrequency);
|
||||||
} else {
|
} else {
|
||||||
return getPeriodBurst();
|
return get64BitReg(ASIC_INT_PERIOD_LSB_REG, ASIC_INT_PERIOD_MSB_REG)/ (1E-9 * systemFrequency);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void setNumFramesBurst(int64_t val) {
|
|
||||||
LOG(logINFO, ("Setting number of frames %d [Burst mode]\n", (int)val));
|
|
||||||
bus_w(ASIC_INT_FRAMES_REG, bus_r(ASIC_INT_FRAMES_REG) &~ ASIC_INT_FRAMES_MSK);
|
|
||||||
bus_w(ASIC_INT_FRAMES_REG, bus_r(ASIC_INT_FRAMES_REG) | (((int)val << ASIC_INT_FRAMES_OFST) & ASIC_INT_FRAMES_MSK));
|
|
||||||
}
|
|
||||||
|
|
||||||
int64_t getNumFramesBurst() {
|
|
||||||
return ((bus_r(ASIC_INT_FRAMES_REG) & ASIC_INT_FRAMES_MSK) >> ASIC_INT_FRAMES_OFST);
|
|
||||||
}
|
|
||||||
|
|
||||||
void setNumFramesCont(int64_t val) {
|
|
||||||
LOG(logINFO, ("Setting number of frames %lld [Continuous mode]\n", val));
|
|
||||||
set64BitReg(val, SET_FRAMES_LSB_REG, SET_FRAMES_MSB_REG);
|
|
||||||
}
|
|
||||||
|
|
||||||
int64_t getNumFramesCont() {
|
|
||||||
return get64BitReg(SET_FRAMES_LSB_REG, SET_FRAMES_MSB_REG);
|
|
||||||
}
|
|
||||||
|
|
||||||
int setExptimeBurst(int64_t val) {
|
|
||||||
LOG(logINFO, ("Setting exptime %lld ns [Burst mode]\n", val));
|
|
||||||
return setExptimeBoth(val);
|
|
||||||
}
|
|
||||||
|
|
||||||
int setExptimeCont(int64_t val) {
|
|
||||||
LOG(logINFO, ("Setting exptime %lld ns [Continuous mode]\n", val));
|
|
||||||
return setExptimeBoth(val);
|
|
||||||
}
|
|
||||||
|
|
||||||
int setExptimeBoth(int64_t val) {
|
|
||||||
val *= (1E-9 * systemFrequency);
|
|
||||||
set64BitReg(val, ASIC_INT_EXPTIME_LSB_REG, ASIC_INT_EXPTIME_MSB_REG);
|
|
||||||
|
|
||||||
// validate for tolerance
|
|
||||||
int64_t retval = getExptimeBoth();
|
|
||||||
val /= (1E-9 * systemFrequency);
|
|
||||||
if (val != retval) {
|
|
||||||
return FAIL;
|
|
||||||
}
|
|
||||||
return OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int64_t getExptimeBoth() {
|
|
||||||
return get64BitReg(ASIC_INT_EXPTIME_LSB_REG, ASIC_INT_EXPTIME_MSB_REG) / (1E-9 * systemFrequency);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int setPeriodBurst(int64_t val) {
|
|
||||||
LOG(logINFO, ("Setting period %lld ns [Burst mode]\n", val));
|
|
||||||
val *= (1E-9 * systemFrequency);
|
|
||||||
set64BitReg(val, ASIC_INT_PERIOD_LSB_REG, ASIC_INT_PERIOD_MSB_REG);
|
|
||||||
|
|
||||||
// validate for tolerance
|
|
||||||
int64_t retval = getPeriodBurst();
|
|
||||||
val /= (1E-9 * systemFrequency);
|
|
||||||
if (val != retval) {
|
|
||||||
return FAIL;
|
|
||||||
}
|
|
||||||
return OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int64_t getPeriodBurst() {
|
|
||||||
LOG(logDEBUG, ("Getting period [Burst mode]\n"));
|
|
||||||
return get64BitReg(ASIC_INT_PERIOD_LSB_REG, ASIC_INT_PERIOD_MSB_REG)/ (1E-9 * systemFrequency);
|
|
||||||
}
|
|
||||||
|
|
||||||
int setPeriodCont(int64_t val) {
|
|
||||||
LOG(logINFO, ("Setting period %lld ns [Continuous mode]\n", val));
|
|
||||||
val *= (1E-9 * systemFrequency);
|
|
||||||
set64BitReg(val, SET_PERIOD_LSB_REG, SET_PERIOD_MSB_REG);
|
|
||||||
|
|
||||||
// validate for tolerance
|
|
||||||
int64_t retval = getPeriodCont();
|
|
||||||
val /= (1E-9 * systemFrequency);
|
|
||||||
if (val != retval) {
|
|
||||||
return FAIL;
|
|
||||||
}
|
|
||||||
return OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int64_t getPeriodCont() {
|
|
||||||
LOG(logDEBUG, ("Getting period [Continuous mode]\n"));
|
|
||||||
return get64BitReg(SET_PERIOD_LSB_REG, SET_PERIOD_MSB_REG)/ (1E-9 * systemFrequency);
|
|
||||||
}
|
|
||||||
|
|
||||||
int setDelayAfterTrigger(int64_t val) {
|
int setDelayAfterTrigger(int64_t val) {
|
||||||
if (val < 0) {
|
if (val < 0) {
|
||||||
LOG(logERROR, ("Invalid delay after trigger: %lld ns\n", val));
|
LOG(logERROR, ("Invalid delay after trigger: %lld ns\n", val));
|
||||||
@ -928,8 +854,12 @@ int setDelayAfterTrigger(int64_t val) {
|
|||||||
}
|
}
|
||||||
LOG(logINFO, ("Setting delay after trigger %lld ns\n", val));
|
LOG(logINFO, ("Setting delay after trigger %lld ns\n", val));
|
||||||
val *= (1E-9 * systemFrequency);
|
val *= (1E-9 * systemFrequency);
|
||||||
set64BitReg(val, SET_TRIGGER_DELAY_LSB_REG, SET_TRIGGER_DELAY_MSB_REG);
|
if (getTiming() == AUTO_TIMING) {
|
||||||
|
LOG(logINFO, ("\tNot trigger mode: not writing to register\n"));
|
||||||
|
delayReg = val;
|
||||||
|
} else {
|
||||||
|
set64BitReg(val, SET_TRIGGER_DELAY_LSB_REG, SET_TRIGGER_DELAY_MSB_REG);
|
||||||
|
}
|
||||||
// validate for tolerance
|
// validate for tolerance
|
||||||
int64_t retval = getDelayAfterTrigger();
|
int64_t retval = getDelayAfterTrigger();
|
||||||
val /= (1E-9 * systemFrequency);
|
val /= (1E-9 * systemFrequency);
|
||||||
@ -940,6 +870,9 @@ int setDelayAfterTrigger(int64_t val) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int64_t getDelayAfterTrigger() {
|
int64_t getDelayAfterTrigger() {
|
||||||
|
if (getTiming() == AUTO_TIMING) {
|
||||||
|
return delayReg / (1E-9 * systemFrequency);
|
||||||
|
}
|
||||||
return get64BitReg(SET_TRIGGER_DELAY_LSB_REG, SET_TRIGGER_DELAY_MSB_REG) / (1E-9 * systemFrequency);
|
return get64BitReg(SET_TRIGGER_DELAY_LSB_REG, SET_TRIGGER_DELAY_MSB_REG) / (1E-9 * systemFrequency);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -949,12 +882,12 @@ int setBurstPeriod(int64_t val) {
|
|||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
LOG(logINFO, ("Setting burst period %lld ns\n", val));
|
LOG(logINFO, ("Setting burst period %lld ns\n", val));
|
||||||
burstPeriodNs = val;
|
|
||||||
val *= (1E-9 * systemFrequency);
|
val *= (1E-9 * systemFrequency);
|
||||||
if (burstMode != BURST_OFF) {
|
if (burstMode != BURST_OFF && getTiming() == AUTO_TIMING) {
|
||||||
set64BitReg(val, SET_PERIOD_LSB_REG, SET_PERIOD_MSB_REG);
|
set64BitReg(val, SET_PERIOD_LSB_REG, SET_PERIOD_MSB_REG);
|
||||||
} else {
|
} else {
|
||||||
LOG(logINFO, ("\t(Continuous mode): not writing burst period to register\n"));
|
LOG(logINFO, ("\tNot (Burst and Auto mode): not writing to register\n"));
|
||||||
|
burstPeriodReg = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
// validate for tolerance
|
// validate for tolerance
|
||||||
@ -967,10 +900,10 @@ int setBurstPeriod(int64_t val) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int64_t getBurstPeriod() {
|
int64_t getBurstPeriod() {
|
||||||
if (burstMode != BURST_OFF) {
|
if (burstMode != BURST_OFF && getTiming() == AUTO_TIMING) {
|
||||||
return get64BitReg(SET_PERIOD_LSB_REG, SET_PERIOD_MSB_REG) / (1E-9 * systemFrequency);
|
return get64BitReg(SET_PERIOD_LSB_REG, SET_PERIOD_MSB_REG) / (1E-9 * systemFrequency);
|
||||||
}
|
}
|
||||||
return burstPeriodNs;
|
return burstPeriodReg / (1E-9 * systemFrequency);
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t getNumFramesLeft() {
|
int64_t getNumFramesLeft() {
|
||||||
@ -1185,6 +1118,18 @@ int setHighVoltage(int val){
|
|||||||
|
|
||||||
/* parameters - timing */
|
/* parameters - timing */
|
||||||
void setTiming( enum timingMode arg){
|
void setTiming( enum timingMode arg){
|
||||||
|
// update
|
||||||
|
// trigger
|
||||||
|
if (getTiming() == TRIGGER_EXPOSURE) {
|
||||||
|
numTriggersReg = get64BitReg(SET_CYCLES_LSB_REG, SET_CYCLES_MSB_REG);
|
||||||
|
delayReg = get64BitReg(SET_TRIGGER_DELAY_LSB_REG, SET_TRIGGER_DELAY_MSB_REG);
|
||||||
|
}
|
||||||
|
// auto and burst
|
||||||
|
else if (burstMode != BURST_OFF) {
|
||||||
|
numBurstsReg = get64BitReg(SET_FRAMES_LSB_REG, SET_FRAMES_MSB_REG);
|
||||||
|
burstPeriodReg = get64BitReg(SET_PERIOD_LSB_REG, SET_PERIOD_MSB_REG);
|
||||||
|
}
|
||||||
|
|
||||||
switch(arg){
|
switch(arg){
|
||||||
case AUTO_TIMING:
|
case AUTO_TIMING:
|
||||||
LOG(logINFO, ("Set Timing: Auto\n"));
|
LOG(logINFO, ("Set Timing: Auto\n"));
|
||||||
@ -1198,9 +1143,32 @@ void setTiming( enum timingMode arg){
|
|||||||
LOG(logERROR, ("Unknown timing mode %d\n", arg));
|
LOG(logERROR, ("Unknown timing mode %d\n", arg));
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG(logINFO, ("\tUpdating trigger/burst and delay/burst period registers\n"))
|
LOG(logINFO, ("\tUpdating registers\n"))
|
||||||
setNumTriggers(numTriggers);
|
// trigger
|
||||||
setNumBursts(numBursts);
|
if (getTiming() == TRIGGER_EXPOSURE) {
|
||||||
|
set64BitReg(numTriggersReg, SET_CYCLES_LSB_REG, SET_CYCLES_MSB_REG);
|
||||||
|
set64BitReg(delayReg, SET_TRIGGER_DELAY_LSB_REG, SET_TRIGGER_DELAY_MSB_REG);
|
||||||
|
LOG(logINFO, ("\tTriggers reg: %lld, Delay reg: %lldns\n", getNumTriggers(), getDelayAfterTrigger()));
|
||||||
|
// burst
|
||||||
|
if (burstMode != BURST_OFF) {
|
||||||
|
LOG(logINFO, ("\tFrame reg: 1, Period reg: 0\n"))
|
||||||
|
set64BitReg(1, SET_FRAMES_LSB_REG, SET_FRAMES_MSB_REG);
|
||||||
|
set64BitReg(0, SET_PERIOD_LSB_REG, SET_PERIOD_MSB_REG);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// auto
|
||||||
|
else {
|
||||||
|
LOG(logINFO, ("\tTrigger reg: 1, Delay reg: 0\n"))
|
||||||
|
set64BitReg(1, SET_CYCLES_LSB_REG, SET_CYCLES_MSB_REG);
|
||||||
|
set64BitReg(0, SET_TRIGGER_DELAY_LSB_REG, SET_TRIGGER_DELAY_MSB_REG);
|
||||||
|
// burst
|
||||||
|
if (burstMode != BURST_OFF) {
|
||||||
|
set64BitReg(numBurstsReg, SET_FRAMES_LSB_REG, SET_FRAMES_MSB_REG);
|
||||||
|
set64BitReg(burstPeriodReg, SET_PERIOD_LSB_REG, SET_PERIOD_MSB_REG);
|
||||||
|
LOG(logINFO, ("\tFrames reg (bursts): %lld, Period reg(burst period): %lldns\n", getNumBursts(), getBurstPeriod()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LOG(logINFO, ("\tDone Updating registers\n"))
|
||||||
}
|
}
|
||||||
|
|
||||||
enum timingMode getTiming() {
|
enum timingMode getTiming() {
|
||||||
@ -1875,23 +1843,62 @@ int setBurstModeinFPGA(enum burstMode value) {
|
|||||||
int setBurstMode(enum burstMode burst) {
|
int setBurstMode(enum burstMode burst) {
|
||||||
LOG(logINFO, ("Setting burst mode to %s\n", burst == BURST_OFF ? "off" : (burst == BURST_INTERNAL ? "internal" : "external")));
|
LOG(logINFO, ("Setting burst mode to %s\n", burst == BURST_OFF ? "off" : (burst == BURST_INTERNAL ? "internal" : "external")));
|
||||||
|
|
||||||
// remember the number of frames and period (before changing burst mode)
|
// update
|
||||||
int64_t frames = getNumFrames();
|
int64_t framesReg = 0;
|
||||||
int64_t period = getPeriod();
|
int64_t periodReg = 0;
|
||||||
|
// burst
|
||||||
|
if (burstMode != BURST_OFF) {
|
||||||
|
framesReg = ((bus_r(ASIC_INT_FRAMES_REG) & ASIC_INT_FRAMES_MSK) >> ASIC_INT_FRAMES_OFST);
|
||||||
|
periodReg = get64BitReg(ASIC_INT_PERIOD_LSB_REG, ASIC_INT_PERIOD_MSB_REG);
|
||||||
|
// auto
|
||||||
|
if (getTiming() == AUTO_TIMING) {
|
||||||
|
numBurstsReg = get64BitReg(SET_FRAMES_LSB_REG, SET_FRAMES_MSB_REG);
|
||||||
|
burstPeriodReg = get64BitReg(SET_PERIOD_LSB_REG, SET_PERIOD_MSB_REG);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// continuous
|
||||||
|
else {
|
||||||
|
framesReg = get64BitReg(SET_FRAMES_LSB_REG, SET_FRAMES_MSB_REG);
|
||||||
|
periodReg = get64BitReg(SET_PERIOD_LSB_REG, SET_PERIOD_MSB_REG);
|
||||||
|
}
|
||||||
|
|
||||||
if (setBurstModeinFPGA(burst) == FAIL) {
|
if (setBurstModeinFPGA(burst) == FAIL) {
|
||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG(logINFO, ("\tUpdating trigger/burst and burst period registers\n"))
|
LOG(logINFO, ("\tUpdating registers\n"));
|
||||||
setNumTriggers(numTriggers);
|
// continuous
|
||||||
setNumBursts(numBursts);
|
if (burstMode == BURST_OFF) {
|
||||||
setBurstPeriod(burstPeriodNs);
|
set64BitReg(framesReg, SET_FRAMES_LSB_REG, SET_FRAMES_MSB_REG);
|
||||||
|
set64BitReg(periodReg, SET_PERIOD_LSB_REG, SET_PERIOD_MSB_REG);
|
||||||
|
LOG(logINFO, ("\tFrames reg: %lld, Period reg: %lldns\n", getNumFrames(), getPeriod()));
|
||||||
|
|
||||||
// set number of frames and period again (set registers according to timing mode)
|
LOG(logINFO, ("\tInt. Frame reg: 1, Int. Period reg: 0\n"))
|
||||||
LOG(logINFO, ("\tUpdating #frames and period registers\n"));
|
bus_w(ASIC_INT_FRAMES_REG, bus_r(ASIC_INT_FRAMES_REG) &~ ASIC_INT_FRAMES_MSK);
|
||||||
setNumFrames(frames);
|
bus_w(ASIC_INT_FRAMES_REG, bus_r(ASIC_INT_FRAMES_REG) | ((1 << ASIC_INT_FRAMES_OFST) & ASIC_INT_FRAMES_MSK));
|
||||||
setPeriod(period);
|
set64BitReg(0, ASIC_INT_PERIOD_LSB_REG, ASIC_INT_PERIOD_MSB_REG);
|
||||||
|
}
|
||||||
|
// burst
|
||||||
|
else {
|
||||||
|
bus_w(ASIC_INT_FRAMES_REG, bus_r(ASIC_INT_FRAMES_REG) &~ ASIC_INT_FRAMES_MSK);
|
||||||
|
bus_w(ASIC_INT_FRAMES_REG, bus_r(ASIC_INT_FRAMES_REG) | (((int)framesReg << ASIC_INT_FRAMES_OFST) & ASIC_INT_FRAMES_MSK));
|
||||||
|
set64BitReg(periodReg, ASIC_INT_PERIOD_LSB_REG, ASIC_INT_PERIOD_MSB_REG);
|
||||||
|
LOG(logINFO, ("\tInt. Frames reg: %lld, Int. Period reg: %lldns\n", getNumFrames(), getPeriod()));
|
||||||
|
|
||||||
|
// trigger
|
||||||
|
if (getTiming() == TRIGGER_EXPOSURE) {
|
||||||
|
LOG(logINFO, ("\tFrame reg: 1, Period reg: 0\n"))
|
||||||
|
set64BitReg(1, SET_FRAMES_LSB_REG, SET_FRAMES_MSB_REG);
|
||||||
|
set64BitReg(0, SET_PERIOD_LSB_REG, SET_PERIOD_MSB_REG);
|
||||||
|
}
|
||||||
|
//auto
|
||||||
|
else {
|
||||||
|
set64BitReg(numBurstsReg, SET_FRAMES_LSB_REG, SET_FRAMES_MSB_REG);
|
||||||
|
set64BitReg(burstPeriodReg, SET_PERIOD_LSB_REG, SET_PERIOD_MSB_REG);
|
||||||
|
LOG(logINFO, ("\tFrames reg (bursts): %lld, Period reg(burst period): %lldns\n", getNumBursts(), getBurstPeriod()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LOG(logINFO, ("\tDone Updating registers\n"))
|
||||||
|
|
||||||
LOG(logINFO, ("\tSetting %s Mode in Chip\n", burstMode == BURST_OFF ? "Continuous" : "Burst"));
|
LOG(logINFO, ("\tSetting %s Mode in Chip\n", burstMode == BURST_OFF ? "Continuous" : "Burst"));
|
||||||
int value = burstMode ? ASIC_GLOBAL_BURST_VALUE : ASIC_GLOBAL_CONT_VALUE;
|
int value = burstMode ? ASIC_GLOBAL_BURST_VALUE : ASIC_GLOBAL_CONT_VALUE;
|
||||||
|
@ -14,15 +14,12 @@ add_executable(jungfrauDetectorServer_virtual
|
|||||||
../slsDetectorServer/src/communication_funcs_UDP.c
|
../slsDetectorServer/src/communication_funcs_UDP.c
|
||||||
)
|
)
|
||||||
|
|
||||||
include_directories(
|
target_include_directories(jungfrauDetectorServer_virtual
|
||||||
|
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
../slsDetectorServer/include
|
../slsDetectorServer/include
|
||||||
../../slsSupportLib/include
|
../../slsSupportLib/include
|
||||||
)
|
)
|
||||||
|
|
||||||
target_include_directories(jungfrauDetectorServer_virtual
|
|
||||||
PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}
|
|
||||||
)
|
|
||||||
|
|
||||||
target_compile_definitions(jungfrauDetectorServer_virtual
|
target_compile_definitions(jungfrauDetectorServer_virtual
|
||||||
PUBLIC JUNGFRAUD VIRTUAL STOP_SERVER
|
PUBLIC JUNGFRAUD VIRTUAL STOP_SERVER
|
||||||
)
|
)
|
||||||
@ -36,5 +33,6 @@ set_target_properties(jungfrauDetectorServer_virtual PROPERTIES
|
|||||||
)
|
)
|
||||||
|
|
||||||
install(TARGETS jungfrauDetectorServer_virtual
|
install(TARGETS jungfrauDetectorServer_virtual
|
||||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
EXPORT "${TARGETS_EXPORT_NAME}"
|
||||||
|
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||||
)
|
)
|
@ -202,19 +202,6 @@ void setNumBursts(int64_t val);
|
|||||||
int64_t getNumBursts();
|
int64_t getNumBursts();
|
||||||
int setBurstPeriod(int64_t val);
|
int setBurstPeriod(int64_t val);
|
||||||
int64_t getBurstPeriod();
|
int64_t getBurstPeriod();
|
||||||
|
|
||||||
void setNumFramesBurst(int64_t val);
|
|
||||||
int64_t getNumFramesBurst();
|
|
||||||
void setNumFramesCont(int64_t val);
|
|
||||||
int64_t getNumFramesCont();
|
|
||||||
int setExptimeBurst(int64_t val);
|
|
||||||
int setExptimeCont(int64_t val);
|
|
||||||
int setExptimeBoth(int64_t val);
|
|
||||||
int64_t getExptimeBoth();
|
|
||||||
int setPeriodBurst(int64_t val);
|
|
||||||
int64_t getPeriodBurst();
|
|
||||||
int setPeriodCont(int64_t val);
|
|
||||||
int64_t getPeriodCont();
|
|
||||||
#endif
|
#endif
|
||||||
#ifdef EIGERD
|
#ifdef EIGERD
|
||||||
int setSubExpTime(int64_t val);
|
int setSubExpTime(int64_t val);
|
||||||
|
@ -15,7 +15,6 @@ add_library(slsDetectorShared SHARED
|
|||||||
${HEADERS}
|
${HEADERS}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
# Do we have link time optimization?
|
# Do we have link time optimization?
|
||||||
check_ipo_supported(RESULT LTO_AVAILABLE)
|
check_ipo_supported(RESULT LTO_AVAILABLE)
|
||||||
if(LTO_AVAILABLE)
|
if(LTO_AVAILABLE)
|
||||||
@ -28,15 +27,18 @@ target_include_directories(slsDetectorShared PUBLIC
|
|||||||
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
|
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(slsDetectorShared PUBLIC
|
target_link_libraries(slsDetectorShared
|
||||||
slsProjectOptions
|
PUBLIC
|
||||||
slsProjectWarnings
|
|
||||||
slsSupportLib
|
slsSupportLib
|
||||||
${ZeroMQ_LIBRARIES}
|
|
||||||
pthread
|
pthread
|
||||||
rt
|
rt
|
||||||
|
slsProjectOptions
|
||||||
|
PRIVATE
|
||||||
|
slsProjectWarnings
|
||||||
|
${ZeroMQ_LIBRARIES}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
set(PUBLICHEADERS
|
set(PUBLICHEADERS
|
||||||
include/slsDetectorUsers.h
|
include/slsDetectorUsers.h
|
||||||
include/detectorData.h
|
include/detectorData.h
|
||||||
@ -69,7 +71,7 @@ foreach(val RANGE ${len2})
|
|||||||
target_link_libraries(${val1}
|
target_link_libraries(${val1}
|
||||||
slsDetectorShared
|
slsDetectorShared
|
||||||
pthread
|
pthread
|
||||||
${ZeroMQ_LIBRARIES}
|
zmq
|
||||||
rt
|
rt
|
||||||
)
|
)
|
||||||
set_target_properties(${val1} PROPERTIES
|
set_target_properties(${val1} PROPERTIES
|
||||||
|
@ -1,15 +1,17 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "Result.h"
|
#include "Result.h"
|
||||||
|
#include "network_utils.h"
|
||||||
#include "sls_detector_defs.h"
|
#include "sls_detector_defs.h"
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
class DetectorImpl;
|
|
||||||
class detectorData;
|
class detectorData;
|
||||||
|
|
||||||
namespace sls {
|
namespace sls {
|
||||||
using ns = std::chrono::nanoseconds;
|
using ns = std::chrono::nanoseconds;
|
||||||
|
class DetectorImpl;
|
||||||
class MacAddr;
|
class MacAddr;
|
||||||
class IpAddr;
|
class IpAddr;
|
||||||
|
|
||||||
|
@ -1782,7 +1782,7 @@ std::string CmdProxy::MinMaxEnergyThreshold(int action) {
|
|||||||
os << "[n_value]\n\t[Moench] Minimum energy threshold (soft "
|
os << "[n_value]\n\t[Moench] Minimum energy threshold (soft "
|
||||||
"setting) for processor."
|
"setting) for processor."
|
||||||
<< '\n';
|
<< '\n';
|
||||||
} else if (cmd == "emin") {
|
} else if (cmd == "emax") {
|
||||||
os << "[n_value]\n\t[Moench] Maximum energy threshold (soft "
|
os << "[n_value]\n\t[Moench] Maximum energy threshold (soft "
|
||||||
"setting) for processor."
|
"setting) for processor."
|
||||||
<< '\n';
|
<< '\n';
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include "DetectorImpl.h"
|
#include "DetectorImpl.h"
|
||||||
#include "Module.h"
|
#include "Module.h"
|
||||||
#include "sls_detector_defs.h"
|
#include "sls_detector_defs.h"
|
||||||
|
#include "versionAPI.h"
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
@ -97,11 +98,11 @@ void Detector::setVirtualDetectorServers(int numServers, int startingPort) {
|
|||||||
int Detector::getShmId() const { return pimpl->getMultiId(); }
|
int Detector::getShmId() const { return pimpl->getMultiId(); }
|
||||||
|
|
||||||
std::string Detector::getPackageVersion() const {
|
std::string Detector::getPackageVersion() const {
|
||||||
return pimpl->getPackageVersion();
|
return GITBRANCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t Detector::getClientVersion() const {
|
int64_t Detector::getClientVersion() const {
|
||||||
return pimpl->getClientSoftwareVersion();
|
return APILIB;
|
||||||
}
|
}
|
||||||
|
|
||||||
Result<int64_t> Detector::getFirmwareVersion(Positions pos) const {
|
Result<int64_t> Detector::getFirmwareVersion(Positions pos) const {
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
#include <future>
|
#include <future>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
using namespace sls;
|
namespace sls{
|
||||||
|
|
||||||
DetectorImpl::DetectorImpl(int multi_id, bool verify, bool update)
|
DetectorImpl::DetectorImpl(int multi_id, bool verify, bool update)
|
||||||
: multiId(multi_id), multi_shm(multi_id, -1) {
|
: multiId(multi_id), multi_shm(multi_id, -1) {
|
||||||
@ -49,10 +49,6 @@ void DetectorImpl::setAcquiringFlag(bool flag) {
|
|||||||
|
|
||||||
int DetectorImpl::getMultiId() const { return multiId; }
|
int DetectorImpl::getMultiId() const { return multiId; }
|
||||||
|
|
||||||
std::string DetectorImpl::getPackageVersion() const { return GITBRANCH; }
|
|
||||||
|
|
||||||
int64_t DetectorImpl::getClientSoftwareVersion() const { return APILIB; }
|
|
||||||
|
|
||||||
void DetectorImpl::freeSharedMemory(int multiId, int detPos) {
|
void DetectorImpl::freeSharedMemory(int multiId, int detPos) {
|
||||||
// single
|
// single
|
||||||
if (detPos >= 0) {
|
if (detPos >= 0) {
|
||||||
@ -160,7 +156,6 @@ void DetectorImpl::initializeDetectorStructure() {
|
|||||||
multi_shm()->numberOfChannels.x = 0;
|
multi_shm()->numberOfChannels.x = 0;
|
||||||
multi_shm()->numberOfChannels.y = 0;
|
multi_shm()->numberOfChannels.y = 0;
|
||||||
multi_shm()->acquiringFlag = false;
|
multi_shm()->acquiringFlag = false;
|
||||||
multi_shm()->receiver_upstream = false;
|
|
||||||
multi_shm()->initialChecks = true;
|
multi_shm()->initialChecks = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -822,46 +817,6 @@ bool DetectorImpl::enableDataStreamingToClient(int enable) {
|
|||||||
return client_downstream;
|
return client_downstream;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DetectorImpl::savePattern(const std::string &fname) {
|
|
||||||
// std::ofstream outfile;
|
|
||||||
// outfile.open(fname.c_str(), std::ios_base::out);
|
|
||||||
// if (!outfile.is_open()) {
|
|
||||||
// throw RuntimeError("Could not create file to save pattern");
|
|
||||||
// }
|
|
||||||
// // get pattern limits
|
|
||||||
// auto r = Parallel(&Module::setPatternLoopAddresses, {}, -1, -1, -1)
|
|
||||||
// .tsquash("Inconsistent pattern limits");
|
|
||||||
// // pattern words
|
|
||||||
// for (int i = r[0]; i <= r[1]; ++i) {
|
|
||||||
// std::ostringstream os;
|
|
||||||
// os << "patword 0x" << std::hex << i;
|
|
||||||
// std::string cmd = os.str();
|
|
||||||
// multiSlsDetectorClient(cmd, GET_ACTION, this, outfile);
|
|
||||||
// }
|
|
||||||
// // rest of pattern file
|
|
||||||
// const std::vector<std::string> commands{
|
|
||||||
// "patioctrl",
|
|
||||||
// "patclkctrl",
|
|
||||||
// "patlimits",
|
|
||||||
// "patloop0",
|
|
||||||
// "patnloop0",
|
|
||||||
// "patloop1",
|
|
||||||
// "patnloop1",
|
|
||||||
// "patloop2",
|
|
||||||
// "patnloop2",
|
|
||||||
// "patwait0",
|
|
||||||
// "patwaittime0",
|
|
||||||
// "patwait1",
|
|
||||||
// "patwaittime1",
|
|
||||||
// "patwait2",
|
|
||||||
// "patwaittime2",
|
|
||||||
// "patmask",
|
|
||||||
// "patsetbit",
|
|
||||||
// };
|
|
||||||
// for (const auto &cmd : commands)
|
|
||||||
// multiSlsDetectorClient(cmd, GET_ACTION, this, outfile);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DetectorImpl::registerAcquisitionFinishedCallback(void (*func)(double, int,
|
void DetectorImpl::registerAcquisitionFinishedCallback(void (*func)(double, int,
|
||||||
void *),
|
void *),
|
||||||
void *pArg) {
|
void *pArg) {
|
||||||
@ -1199,3 +1154,5 @@ std::vector<char> DetectorImpl::readProgrammingFile(const std::string &fname) {
|
|||||||
LOG(logINFO) << "Read file into memory";
|
LOG(logINFO) << "Read file into memory";
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}//namespace sls
|
@ -5,10 +5,6 @@
|
|||||||
#include "logger.h"
|
#include "logger.h"
|
||||||
#include "sls_detector_defs.h"
|
#include "sls_detector_defs.h"
|
||||||
|
|
||||||
namespace sls{
|
|
||||||
class Module;
|
|
||||||
}
|
|
||||||
|
|
||||||
class ZmqSocket;
|
class ZmqSocket;
|
||||||
class detectorData;
|
class detectorData;
|
||||||
|
|
||||||
@ -25,6 +21,11 @@ class detectorData;
|
|||||||
|
|
||||||
#include <future>
|
#include <future>
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
|
|
||||||
|
namespace sls{
|
||||||
|
|
||||||
|
class Module;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @short structure allocated in shared memory to store detector settings
|
* @short structure allocated in shared memory to store detector settings
|
||||||
* for IPC and cache
|
* for IPC and cache
|
||||||
@ -64,9 +65,6 @@ struct sharedMultiSlsDetector {
|
|||||||
/** flag for acquiring */
|
/** flag for acquiring */
|
||||||
bool acquiringFlag;
|
bool acquiringFlag;
|
||||||
|
|
||||||
/** data streaming (up stream) enable in receiver */
|
|
||||||
bool receiver_upstream;
|
|
||||||
|
|
||||||
/** initial checks */
|
/** initial checks */
|
||||||
bool initialChecks;
|
bool initialChecks;
|
||||||
};
|
};
|
||||||
@ -202,10 +200,6 @@ class DetectorImpl : public virtual slsDetectorDefs {
|
|||||||
/** return multi detector shared memory ID */
|
/** return multi detector shared memory ID */
|
||||||
int getMultiId() const;
|
int getMultiId() const;
|
||||||
|
|
||||||
std::string getPackageVersion() const;
|
|
||||||
|
|
||||||
int64_t getClientSoftwareVersion() const;
|
|
||||||
|
|
||||||
/** Free specific shared memory from the command line without creating object */
|
/** Free specific shared memory from the command line without creating object */
|
||||||
static void freeSharedMemory(int multiId, int detPos = -1);
|
static void freeSharedMemory(int multiId, int detPos = -1);
|
||||||
|
|
||||||
@ -255,8 +249,6 @@ class DetectorImpl : public virtual slsDetectorDefs {
|
|||||||
*/
|
*/
|
||||||
bool enableDataStreamingToClient(int enable = -1);
|
bool enableDataStreamingToClient(int enable = -1);
|
||||||
|
|
||||||
void savePattern(const std::string &fname);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* register callback for accessing acquisition final data
|
* register callback for accessing acquisition final data
|
||||||
* @param func function to be called at the end of the acquisition.
|
* @param func function to be called at the end of the acquisition.
|
||||||
@ -393,14 +385,6 @@ class DetectorImpl : public virtual slsDetectorDefs {
|
|||||||
*/
|
*/
|
||||||
int kbhit();
|
int kbhit();
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert a double holding time in seconds to an int64_t with nano seconds
|
|
||||||
* Used for conversion when sending time to detector
|
|
||||||
* @param t time in seconds
|
|
||||||
* @returns time in nano seconds
|
|
||||||
*/
|
|
||||||
int64_t secondsToNanoSeconds(double t);
|
|
||||||
|
|
||||||
/** Multi detector Id */
|
/** Multi detector Id */
|
||||||
const int multiId{0};
|
const int multiId{0};
|
||||||
|
|
||||||
@ -448,3 +432,5 @@ class DetectorImpl : public virtual slsDetectorDefs {
|
|||||||
void (*dataReady)(detectorData *, uint64_t, uint32_t, void *){nullptr};
|
void (*dataReady)(detectorData *, uint64_t, uint32_t, void *){nullptr};
|
||||||
void *pCallbackArg{nullptr};
|
void *pCallbackArg{nullptr};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
}//namespace sls
|
@ -164,6 +164,29 @@ void Module::sendToDetector(int fnum) {
|
|||||||
sendToDetector(fnum, nullptr, 0, nullptr, 0);
|
sendToDetector(fnum, nullptr, 0, nullptr, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename Ret>
|
||||||
|
Ret Module::sendToDetector(int fnum){
|
||||||
|
LOG(logDEBUG1) << "Sending: ["
|
||||||
|
<< getFunctionNameFromEnum(static_cast<slsDetectorDefs::detFuncs>(fnum))
|
||||||
|
<< ", nullptr, 0, " << typeid(Ret).name() << ", " << sizeof(Ret) << "]";
|
||||||
|
Ret retval{};
|
||||||
|
sendToDetector(fnum, nullptr, 0, &retval, sizeof(retval));
|
||||||
|
LOG(logDEBUG1) << "Got back: " << retval;
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Ret, typename Arg>
|
||||||
|
Ret Module::sendToDetector(int fnum, const Arg &args){
|
||||||
|
LOG(logDEBUG1) << "Sending: ["
|
||||||
|
<< getFunctionNameFromEnum(static_cast<slsDetectorDefs::detFuncs>(fnum))
|
||||||
|
<< ", " << args << ", " << sizeof(args) << ", " << typeid(Ret).name() << ", " << sizeof(Ret) << "]";
|
||||||
|
Ret retval{};
|
||||||
|
sendToDetector(fnum, &args, sizeof(args), &retval, sizeof(retval));
|
||||||
|
LOG(logDEBUG1) << "Got back: " << retval;
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Module::sendToDetectorStop(int fnum, const void *args,
|
void Module::sendToDetectorStop(int fnum, const void *args,
|
||||||
size_t args_size, void *retval,
|
size_t args_size, void *retval,
|
||||||
size_t retval_size) {
|
size_t retval_size) {
|
||||||
@ -265,14 +288,58 @@ void Module::sendToReceiver(int fnum, std::nullptr_t, Ret &retval) const {
|
|||||||
sendToReceiver(fnum, nullptr, 0, &retval, sizeof(retval));
|
sendToReceiver(fnum, nullptr, 0, &retval, sizeof(retval));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Module::sendToReceiver(int fnum) {
|
template <typename Ret>
|
||||||
sendToReceiver(fnum, nullptr, 0, nullptr, 0);
|
Ret Module::sendToReceiver(int fnum){
|
||||||
|
LOG(logDEBUG1) << "Sending: ["
|
||||||
|
<< getFunctionNameFromEnum(static_cast<slsDetectorDefs::detFuncs>(fnum))
|
||||||
|
<< ", nullptr, 0, " << typeid(Ret).name() << ", " << sizeof(Ret) << "]";
|
||||||
|
Ret retval{};
|
||||||
|
sendToReceiver(fnum, nullptr, 0, &retval, sizeof(retval));
|
||||||
|
LOG(logDEBUG1) << "Got back: " << retval;
|
||||||
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Module::sendToReceiver(int fnum) const {
|
template <typename Ret>
|
||||||
sendToReceiver(fnum, nullptr, 0, nullptr, 0);
|
Ret Module::sendToReceiver(int fnum) const{
|
||||||
|
LOG(logDEBUG1) << "Sending: ["
|
||||||
|
<< getFunctionNameFromEnum(static_cast<slsDetectorDefs::detFuncs>(fnum))
|
||||||
|
<< ", nullptr, 0, " << typeid(Ret).name() << ", " << sizeof(Ret) << "]";
|
||||||
|
Ret retval{};
|
||||||
|
sendToReceiver(fnum, nullptr, 0, &retval, sizeof(retval));
|
||||||
|
LOG(logDEBUG1) << "Got back: " << retval;
|
||||||
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename Ret, typename Arg>
|
||||||
|
Ret Module::sendToReceiver(int fnum, const Arg &args){
|
||||||
|
LOG(logDEBUG1) << "Sending: ["
|
||||||
|
<< getFunctionNameFromEnum(static_cast<slsDetectorDefs::detFuncs>(fnum))
|
||||||
|
<< ", " << args << ", " << sizeof(args) << ", " << typeid(Ret).name() << ", " << sizeof(Ret) << "]";
|
||||||
|
Ret retval{};
|
||||||
|
sendToReceiver(fnum, &args, sizeof(args), &retval, sizeof(retval));
|
||||||
|
LOG(logDEBUG1) << "Got back: " << retval;
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Ret, typename Arg>
|
||||||
|
Ret Module::sendToReceiver(int fnum, const Arg &args) const{
|
||||||
|
LOG(logDEBUG1) << "Sending: ["
|
||||||
|
<< getFunctionNameFromEnum(static_cast<slsDetectorDefs::detFuncs>(fnum))
|
||||||
|
<< ", " << args << ", " << sizeof(args) << ", " << typeid(Ret).name() << ", " << sizeof(Ret) << "]";
|
||||||
|
Ret retval{};
|
||||||
|
sendToReceiver(fnum, &args, sizeof(args), &retval, sizeof(retval));
|
||||||
|
LOG(logDEBUG1) << "Got back: " << retval;
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
// void Module::sendToReceiver(int fnum) {
|
||||||
|
// sendToReceiver(fnum, nullptr, 0, nullptr, 0);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// void Module::sendToReceiver(int fnum) const {
|
||||||
|
// sendToReceiver(fnum, nullptr, 0, nullptr, 0);
|
||||||
|
// }
|
||||||
|
|
||||||
void Module::freeSharedMemory() {
|
void Module::freeSharedMemory() {
|
||||||
if (shm.IsExisting()) {
|
if (shm.IsExisting()) {
|
||||||
shm.RemoveSharedMemory();
|
shm.RemoveSharedMemory();
|
||||||
@ -1277,10 +1344,7 @@ void Module::setNumberOfDigitalSamples(int value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int64_t Module::getExptime() {
|
int64_t Module::getExptime() {
|
||||||
int64_t retval = -1;
|
return sendToDetector<int64_t>(F_GET_EXPTIME);
|
||||||
sendToDetector(F_GET_EXPTIME, nullptr, retval);
|
|
||||||
LOG(logDEBUG1) << "exptime :" << retval << "ns";
|
|
||||||
return retval;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Module::setExptime(int64_t value) {
|
void Module::setExptime(int64_t value) {
|
||||||
@ -1303,10 +1367,7 @@ void Module::setExptime(int64_t value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int64_t Module::getPeriod() {
|
int64_t Module::getPeriod() {
|
||||||
int64_t retval = -1;
|
return sendToDetector<int64_t>(F_GET_PERIOD);
|
||||||
sendToDetector(F_GET_PERIOD, nullptr, retval);
|
|
||||||
LOG(logDEBUG1) << "period :" << retval << "ns";
|
|
||||||
return retval;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Module::setPeriod(int64_t value) {
|
void Module::setPeriod(int64_t value) {
|
||||||
@ -1319,10 +1380,7 @@ void Module::setPeriod(int64_t value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int64_t Module::getDelayAfterTrigger() {
|
int64_t Module::getDelayAfterTrigger() {
|
||||||
int64_t retval = -1;
|
return sendToDetector<int64_t>(F_GET_DELAY_AFTER_TRIGGER);
|
||||||
sendToDetector(F_GET_DELAY_AFTER_TRIGGER, nullptr, retval);
|
|
||||||
LOG(logDEBUG1) << "delay after trigger :" << retval << "ns";
|
|
||||||
return retval;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Module::setDelayAfterTrigger(int64_t value) {
|
void Module::setDelayAfterTrigger(int64_t value) {
|
||||||
@ -1331,10 +1389,7 @@ void Module::setDelayAfterTrigger(int64_t value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int64_t Module::getBurstPeriod() {
|
int64_t Module::getBurstPeriod() {
|
||||||
int64_t retval = -1;
|
return sendToDetector<int64_t>(F_GET_BURST_PERIOD);
|
||||||
sendToDetector(F_GET_BURST_PERIOD, nullptr, retval);
|
|
||||||
LOG(logDEBUG1) << "burst period :" << retval << "ns";
|
|
||||||
return retval;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Module::setBurstPeriod(int64_t value) {
|
void Module::setBurstPeriod(int64_t value) {
|
||||||
@ -1343,10 +1398,7 @@ void Module::setBurstPeriod(int64_t value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int64_t Module::getSubExptime() {
|
int64_t Module::getSubExptime() {
|
||||||
int64_t retval = -1;
|
return sendToDetector<int64_t>(F_GET_SUB_EXPTIME);
|
||||||
sendToDetector(F_GET_SUB_EXPTIME, nullptr, retval);
|
|
||||||
LOG(logDEBUG1) << "sub exptime :" << retval << "ns";
|
|
||||||
return retval;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Module::setSubExptime(int64_t value) {
|
void Module::setSubExptime(int64_t value) {
|
||||||
@ -1369,10 +1421,7 @@ void Module::setSubExptime(int64_t value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int64_t Module::getSubDeadTime() {
|
int64_t Module::getSubDeadTime() {
|
||||||
int64_t retval = -1;
|
return sendToDetector<int64_t>(F_GET_SUB_DEADTIME);
|
||||||
sendToDetector(F_GET_SUB_DEADTIME, nullptr, retval);
|
|
||||||
LOG(logDEBUG1) << "sub deadtime :" << retval << "ns";
|
|
||||||
return retval;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Module::setSubDeadTime(int64_t value) {
|
void Module::setSubDeadTime(int64_t value) {
|
||||||
@ -1623,31 +1672,17 @@ void Module::setInterruptSubframe(const bool enable) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool Module::getInterruptSubframe() {
|
bool Module::getInterruptSubframe() {
|
||||||
int retval = -1;
|
auto retval = sendToDetector<int>(F_GET_INTERRUPT_SUBFRAME);
|
||||||
LOG(logDEBUG1) << "Getting Interrupt subframe";
|
|
||||||
sendToDetector(F_GET_INTERRUPT_SUBFRAME, nullptr, retval);
|
|
||||||
LOG(logDEBUG1) << "Interrupt subframe: " << retval;
|
|
||||||
return static_cast<bool>(retval);
|
return static_cast<bool>(retval);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t Module::writeRegister(uint32_t addr, uint32_t val) {
|
uint32_t Module::writeRegister(uint32_t addr, uint32_t val) {
|
||||||
uint32_t args[]{addr, val};
|
uint32_t args[]{addr, val};
|
||||||
uint32_t retval = -1;
|
return sendToDetector<uint32_t>(F_WRITE_REGISTER, args);
|
||||||
LOG(logDEBUG1) << "Writing to reg 0x" << std::hex << addr << "data: 0x"
|
|
||||||
<< std::hex << val << std::dec;
|
|
||||||
sendToDetector(F_WRITE_REGISTER, args, retval);
|
|
||||||
LOG(logDEBUG1) << "Reg 0x" << std::hex << addr << ": 0x" << std::hex
|
|
||||||
<< retval << std::dec;
|
|
||||||
return retval;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t Module::readRegister(uint32_t addr) {
|
uint32_t Module::readRegister(uint32_t addr) {
|
||||||
uint32_t retval = -1;
|
return sendToDetector<uint32_t>(F_READ_REGISTER, addr);
|
||||||
LOG(logDEBUG1) << "Reading reg 0x" << std::hex << addr << std::dec;
|
|
||||||
sendToDetector(F_READ_REGISTER, addr, retval);
|
|
||||||
LOG(logDEBUG1) << "Reg 0x" << std::hex << addr << ": 0x" << std::hex
|
|
||||||
<< retval << std::dec;
|
|
||||||
return retval;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t Module::setBit(uint32_t addr, int n) {
|
uint32_t Module::setBit(uint32_t addr, int n) {
|
||||||
@ -2032,12 +2067,8 @@ void Module::setClientStreamingPort(int port) { shm()->zmqport = port; }
|
|||||||
int Module::getClientStreamingPort() { return shm()->zmqport; }
|
int Module::getClientStreamingPort() { return shm()->zmqport; }
|
||||||
|
|
||||||
void Module::setReceiverStreamingPort(int port) {
|
void Module::setReceiverStreamingPort(int port) {
|
||||||
int fnum = F_SET_RECEIVER_STREAMING_PORT;
|
|
||||||
int retval = -1;
|
|
||||||
LOG(logDEBUG1) << "Sending receiver streaming port to receiver: "
|
|
||||||
<< port;
|
|
||||||
if (shm()->useReceiverFlag) {
|
if (shm()->useReceiverFlag) {
|
||||||
sendToReceiver(fnum, port, retval);
|
auto retval = sendToReceiver<int>(F_SET_RECEIVER_STREAMING_PORT, port);
|
||||||
LOG(logDEBUG1) << "Receiver streaming port: " << retval;
|
LOG(logDEBUG1) << "Receiver streaming port: " << retval;
|
||||||
shm()->rxZmqport = retval;
|
shm()->rxZmqport = retval;
|
||||||
} else {
|
} else {
|
||||||
@ -2278,14 +2309,7 @@ int64_t Module::getReceiverUDPSocketBufferSize() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int64_t Module::getReceiverRealUDPSocketBufferSize() const {
|
int64_t Module::getReceiverRealUDPSocketBufferSize() const {
|
||||||
int64_t retval = -1;
|
return sendToReceiver<int64_t>(F_RECEIVER_REAL_UDP_SOCK_BUF_SIZE);
|
||||||
LOG(logDEBUG1) << "Getting real UDP Socket Buffer size from receiver";
|
|
||||||
if (shm()->useReceiverFlag) {
|
|
||||||
sendToReceiver(F_RECEIVER_REAL_UDP_SOCK_BUF_SIZE, nullptr, retval);
|
|
||||||
LOG(logDEBUG1)
|
|
||||||
<< "Real Receiver UDP Socket Buffer size: " << retval;
|
|
||||||
}
|
|
||||||
return retval;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Module::executeFirmwareTest() {
|
void Module::executeFirmwareTest() {
|
||||||
@ -3136,7 +3160,7 @@ sls::IpAddr Module::getReceiverLastClientIP() const {
|
|||||||
void Module::exitReceiver() {
|
void Module::exitReceiver() {
|
||||||
LOG(logDEBUG1) << "Sending exit command to receiver server";
|
LOG(logDEBUG1) << "Sending exit command to receiver server";
|
||||||
if (shm()->useReceiverFlag) {
|
if (shm()->useReceiverFlag) {
|
||||||
sendToReceiver(F_EXIT_RECEIVER);
|
sendToReceiver(F_EXIT_RECEIVER, nullptr, nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3431,7 +3455,7 @@ int64_t Module::incrementFileIndex() {
|
|||||||
void Module::startReceiver() {
|
void Module::startReceiver() {
|
||||||
LOG(logDEBUG1) << "Starting Receiver";
|
LOG(logDEBUG1) << "Starting Receiver";
|
||||||
if (shm()->useReceiverFlag) {
|
if (shm()->useReceiverFlag) {
|
||||||
sendToReceiver(F_START_RECEIVER);
|
sendToReceiver(F_START_RECEIVER, nullptr, nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3635,7 +3659,7 @@ bool Module::setReceiverSilentMode(int value) {
|
|||||||
void Module::restreamStopFromReceiver() {
|
void Module::restreamStopFromReceiver() {
|
||||||
LOG(logDEBUG1) << "Restream stop dummy from Receiver via zmq";
|
LOG(logDEBUG1) << "Restream stop dummy from Receiver via zmq";
|
||||||
if (shm()->useReceiverFlag) {
|
if (shm()->useReceiverFlag) {
|
||||||
sendToReceiver(F_RESTREAM_STOP_FROM_RECEIVER);
|
sendToReceiver(F_RESTREAM_STOP_FROM_RECEIVER, nullptr, nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1915,6 +1915,12 @@ class Module : public virtual slsDetectorDefs {
|
|||||||
void sendToDetector(int fnum, std::nullptr_t, Ret &retval);
|
void sendToDetector(int fnum, std::nullptr_t, Ret &retval);
|
||||||
void sendToDetector(int fnum);
|
void sendToDetector(int fnum);
|
||||||
|
|
||||||
|
template <typename Ret>
|
||||||
|
Ret sendToDetector(int fnum);
|
||||||
|
|
||||||
|
template <typename Ret, typename Arg>
|
||||||
|
Ret sendToDetector(int fnum, const Arg &args);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send function parameters to detector (stop server)
|
* Send function parameters to detector (stop server)
|
||||||
* @param fnum function enum
|
* @param fnum function enum
|
||||||
@ -1983,9 +1989,17 @@ class Module : public virtual slsDetectorDefs {
|
|||||||
template <typename Ret>
|
template <typename Ret>
|
||||||
void sendToReceiver(int fnum, std::nullptr_t, Ret &retval) const;
|
void sendToReceiver(int fnum, std::nullptr_t, Ret &retval) const;
|
||||||
|
|
||||||
void sendToReceiver(int fnum);
|
template <typename Ret>
|
||||||
|
Ret sendToReceiver(int fnum);
|
||||||
|
|
||||||
void sendToReceiver(int fnum) const;
|
template <typename Ret>
|
||||||
|
Ret sendToReceiver(int fnum) const;
|
||||||
|
|
||||||
|
template <typename Ret, typename Arg>
|
||||||
|
Ret sendToReceiver(int fnum, const Arg &args);
|
||||||
|
|
||||||
|
template <typename Ret, typename Arg>
|
||||||
|
Ret sendToReceiver(int fnum, const Arg &args) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get Detector Type from Shared Memory (opening shm without verifying size)
|
* Get Detector Type from Shared Memory (opening shm without verifying size)
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
*@short functions basic implemenation of shared memory
|
*@short functions basic implemenation of shared memory
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "ansi.h"
|
|
||||||
#include "logger.h"
|
#include "logger.h"
|
||||||
#include "sls_detector_exceptions.h"
|
#include "sls_detector_exceptions.h"
|
||||||
|
|
||||||
@ -18,7 +17,7 @@
|
|||||||
#include <fcntl.h> // O_CREAT, O_TRUNC..
|
#include <fcntl.h> // O_CREAT, O_TRUNC..
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <stdio.h> // printf
|
// #include <stdio.h> // printf
|
||||||
#include <sys/mman.h> // shared memory
|
#include <sys/mman.h> // shared memory
|
||||||
#include <sys/stat.h> // fstat
|
#include <sys/stat.h> // fstat
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
@ -9,7 +9,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "ansi.h"
|
|
||||||
#include "logger.h"
|
#include "logger.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sys/stat.h> // stat
|
#include <sys/stat.h> // stat
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
/** cosntructor & destructor */
|
/** cosntructor & destructor */
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@ set(SOURCES
|
|||||||
src/ServerSocket.cpp
|
src/ServerSocket.cpp
|
||||||
src/ServerInterface.cpp
|
src/ServerInterface.cpp
|
||||||
src/network_utils.cpp
|
src/network_utils.cpp
|
||||||
|
src/ZmqSocket.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
set(HEADERS
|
set(HEADERS
|
||||||
@ -20,7 +21,6 @@ set(PUBLICHEADERS
|
|||||||
include/file_utils.h
|
include/file_utils.h
|
||||||
include/container_utils.h
|
include/container_utils.h
|
||||||
include/string_utils.h
|
include/string_utils.h
|
||||||
include/genericSocket.h
|
|
||||||
include/logger.h
|
include/logger.h
|
||||||
include/ClientSocket.h
|
include/ClientSocket.h
|
||||||
include/DataSocket.h
|
include/DataSocket.h
|
||||||
@ -44,22 +44,36 @@ if(result)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
target_include_directories(slsSupportLib PUBLIC
|
target_include_directories(slsSupportLib PUBLIC
|
||||||
${ZeroMQ_INCLUDE_DIRS}
|
|
||||||
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>"
|
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>"
|
||||||
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
|
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
target_include_directories(slsSupportLib PRIVATE
|
||||||
|
${ZeroMQ_INCLUDE_DIRS}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
set_target_properties(slsSupportLib PROPERTIES
|
set_target_properties(slsSupportLib PROPERTIES
|
||||||
LIBRARY_OUTPUT_NAME SlsSupport
|
LIBRARY_OUTPUT_NAME SlsSupport
|
||||||
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
|
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
|
||||||
PUBLIC_HEADER "${PUBLICHEADERS}"
|
PUBLIC_HEADER "${PUBLICHEADERS}"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
message(${ZeroMQ_LIBRARIES})
|
||||||
|
|
||||||
target_link_libraries(slsSupportLib
|
target_link_libraries(slsSupportLib
|
||||||
|
PUBLIC
|
||||||
slsProjectOptions
|
slsProjectOptions
|
||||||
|
# ${ZeroMQ_LIBRARIES}
|
||||||
|
zmq
|
||||||
|
PRIVATE
|
||||||
|
|
||||||
slsProjectWarnings
|
slsProjectWarnings
|
||||||
${ZeroMQ_LIBRARIES}
|
PUBLIC
|
||||||
rapidjson)
|
rapidjson
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (SLS_USE_TESTS)
|
if (SLS_USE_TESTS)
|
||||||
add_subdirectory(tests)
|
add_subdirectory(tests)
|
||||||
|
@ -9,7 +9,6 @@ this might be deprecated in the future
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// #include "genericSocket.h"
|
|
||||||
#include "network_utils.h"
|
#include "network_utils.h"
|
||||||
#include "sls_detector_exceptions.h"
|
#include "sls_detector_exceptions.h"
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
@ -7,20 +7,8 @@
|
|||||||
*@short functions to open/close zmq sockets
|
*@short functions to open/close zmq sockets
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "ansi.h"
|
|
||||||
#include "sls_detector_exceptions.h"
|
#include "sls_detector_exceptions.h"
|
||||||
|
|
||||||
#include <arpa/inet.h> //inet_ntoa
|
|
||||||
#include <errno.h>
|
|
||||||
#include <iostream>
|
|
||||||
#include <netdb.h> //gethostbyname()
|
|
||||||
#include <rapidjson/document.h> //json header in zmq stream
|
#include <rapidjson/document.h> //json header in zmq stream
|
||||||
#include <string.h>
|
|
||||||
#include <unistd.h> //usleep in some machines
|
|
||||||
#include <vector>
|
|
||||||
#include <zmq.h>
|
|
||||||
using namespace rapidjson;
|
|
||||||
|
|
||||||
|
|
||||||
#define MAX_STR_LENGTH 1000
|
#define MAX_STR_LENGTH 1000
|
||||||
|
|
||||||
@ -28,404 +16,161 @@ using namespace rapidjson;
|
|||||||
#define ROIVERBOSITY
|
#define ROIVERBOSITY
|
||||||
|
|
||||||
|
|
||||||
|
class zmq_msg_t;
|
||||||
class ZmqSocket {
|
class ZmqSocket {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
// Socket Options for optimization
|
||||||
|
// ZMQ_LINGER default is already -1 means no messages discarded. use this
|
||||||
|
// options if optimizing required ZMQ_SNDHWM default is 0 means no limit. use
|
||||||
|
// this to optimize if optimizing required
|
||||||
|
// eg. int value = -1;
|
||||||
|
// if (zmq_setsockopt(socketDescriptor, ZMQ_LINGER, &value,sizeof(value))) {
|
||||||
|
// Close();
|
||||||
|
/**
|
||||||
|
* Constructor for a client
|
||||||
|
* Creates socket, context and connects to server
|
||||||
|
* @param hostname hostname or ip of server
|
||||||
|
* @param portnumber port number
|
||||||
|
*/
|
||||||
|
ZmqSocket(const char *const hostname_or_ip, const uint32_t portnumber);
|
||||||
|
|
||||||
//Socket Options for optimization
|
/**
|
||||||
//ZMQ_LINGER default is already -1 means no messages discarded. use this options if optimizing required
|
* Constructor for a server
|
||||||
//ZMQ_SNDHWM default is 0 means no limit. use this to optimize if optimizing required
|
* Creates socket, context and connects to server
|
||||||
// eg. int value = -1;
|
* @param hostname hostname or ip of server
|
||||||
// if (zmq_setsockopt(socketDescriptor, ZMQ_LINGER, &value,sizeof(value))) {
|
* @param portnumber port number
|
||||||
// Close();
|
* @param ethip is the ip of the ethernet interface to stream zmq from
|
||||||
/**
|
*/
|
||||||
* Constructor for a client
|
ZmqSocket(const uint32_t portnumber, const char *ethip);
|
||||||
* Creates socket, context and connects to server
|
|
||||||
* @param hostname hostname or ip of server
|
|
||||||
* @param portnumber port number
|
|
||||||
*/
|
|
||||||
ZmqSocket (const char* const hostname_or_ip, const uint32_t portnumber):
|
|
||||||
portno (portnumber)
|
|
||||||
// headerMessage(0)
|
|
||||||
{
|
|
||||||
char ip[MAX_STR_LENGTH] = "";
|
|
||||||
memset(ip, 0, MAX_STR_LENGTH);
|
|
||||||
|
|
||||||
// convert hostname to ip (not required, but a test that returns if failed)
|
/**
|
||||||
struct addrinfo *result;
|
* Destructor
|
||||||
if ((ConvertHostnameToInternetAddress(hostname_or_ip, &result)) ||
|
*/
|
||||||
(ConvertInternetAddresstoIpString(result, ip, MAX_STR_LENGTH)))
|
~ZmqSocket() = default;
|
||||||
throw sls::ZmqSocketError("Could convert IP to string");
|
|
||||||
|
|
||||||
// construct address
|
/**
|
||||||
sprintf (sockfd.serverAddress, "tcp://%s:%d", ip, portno);
|
* Returns Port Number
|
||||||
#ifdef VERBOSE
|
* @returns Port Number
|
||||||
cprintf(BLUE,"address:%s\n",sockfd.serverAddress);
|
*/
|
||||||
#endif
|
uint32_t GetPortNumber() { return portno; }
|
||||||
|
|
||||||
// create context
|
/**
|
||||||
sockfd.contextDescriptor = zmq_ctx_new();
|
* Returns Server Address
|
||||||
if (sockfd.contextDescriptor == 0)
|
* @returns Server Address
|
||||||
throw sls::ZmqSocketError("Could not create contextDescriptor");
|
*/
|
||||||
|
char *GetZmqServerAddress() { return sockfd.serverAddress; }
|
||||||
|
|
||||||
// create publisher
|
/**
|
||||||
sockfd.socketDescriptor = zmq_socket (sockfd.contextDescriptor, ZMQ_SUB);
|
* Returns Socket Descriptor
|
||||||
if (sockfd.socketDescriptor == 0) {
|
* @reutns Socket descriptor
|
||||||
PrintError ();
|
*/
|
||||||
Close ();
|
|
||||||
throw sls::ZmqSocketError("Could not create socket");
|
|
||||||
}
|
|
||||||
|
|
||||||
//Socket Options provided above
|
void *GetsocketDescriptor() { return sockfd.socketDescriptor; }
|
||||||
// an empty string implies receiving any messages
|
|
||||||
if ( zmq_setsockopt(sockfd.socketDescriptor, ZMQ_SUBSCRIBE, "", 0)) {
|
|
||||||
PrintError ();
|
|
||||||
Close();
|
|
||||||
throw sls::ZmqSocketError("Could set socket opt");
|
|
||||||
}
|
|
||||||
//ZMQ_LINGER default is already -1 means no messages discarded. use this options if optimizing required
|
|
||||||
//ZMQ_SNDHWM default is 0 means no limit. use this to optimize if optimizing required
|
|
||||||
// eg. int value = -1;
|
|
||||||
int value = 0;
|
|
||||||
if (zmq_setsockopt(sockfd.socketDescriptor, ZMQ_LINGER, &value,sizeof(value))) {
|
|
||||||
PrintError ();
|
|
||||||
Close();
|
|
||||||
throw sls::ZmqSocketError("Could not set ZMQ_LINGER");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor for a server
|
* Connect client socket to server socket
|
||||||
* Creates socket, context and connects to server
|
* @returns 1 for fail, 0 for success
|
||||||
* @param hostname hostname or ip of server
|
*/
|
||||||
* @param portnumber port number
|
int Connect();
|
||||||
* @param ethip is the ip of the ethernet interface to stream zmq from
|
|
||||||
*/
|
|
||||||
ZmqSocket (const uint32_t portnumber, const char *ethip):
|
|
||||||
|
|
||||||
portno (portnumber)
|
/**
|
||||||
// headerMessage(0)
|
* Unbinds the Socket
|
||||||
{
|
*/
|
||||||
sockfd.server = true;
|
void Disconnect() { sockfd.Disconnect(); };
|
||||||
|
|
||||||
// create context
|
/**
|
||||||
sockfd.contextDescriptor = zmq_ctx_new();
|
* Close Socket and destroy Context
|
||||||
if (sockfd.contextDescriptor == 0)
|
*/
|
||||||
throw sls::ZmqSocketError("Could not create contextDescriptor");
|
void Close() { sockfd.Close(); };
|
||||||
// create publisher
|
|
||||||
sockfd.socketDescriptor = zmq_socket (sockfd.contextDescriptor, ZMQ_PUB);
|
|
||||||
if (sockfd.socketDescriptor == 0) {
|
|
||||||
PrintError ();
|
|
||||||
Close ();
|
|
||||||
throw sls::ZmqSocketError("Could not create socket");
|
|
||||||
}
|
|
||||||
|
|
||||||
//Socket Options provided above
|
/**
|
||||||
|
* 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);
|
||||||
|
|
||||||
// construct addresss
|
/**
|
||||||
sprintf (sockfd.serverAddress,"tcp://%s:%d", ethip, portno);
|
* Convert Internet Address structure pointer to ip string (char*)
|
||||||
#ifdef VERBOSE
|
* Clears the internet address structure as well
|
||||||
cprintf(BLUE,"address:%s\n",sockfd.serverAddress);
|
* @param res pointer to internet address structure
|
||||||
#endif
|
* @param ip pointer to char array to store result in
|
||||||
// bind address
|
* @param ipsize size available in ip buffer
|
||||||
if (zmq_bind (sockfd.socketDescriptor, sockfd.serverAddress) < 0) {
|
* @return 1 for fail, 0 for success
|
||||||
PrintError ();
|
*/
|
||||||
Close ();
|
// Do not make this static (for multi threading environment)
|
||||||
throw sls::ZmqSocketError("Could not bind socket");
|
int ConvertInternetAddresstoIpString(struct addrinfo *res, char *ip,
|
||||||
}
|
const int ipsize);
|
||||||
|
|
||||||
//sleep for a few milliseconds to allow a slow-joiner
|
/**
|
||||||
usleep(200* 1000);
|
* Send Message Header
|
||||||
};
|
* @param index self index for debugging
|
||||||
|
* @param dummy true if a dummy message for end of acquisition
|
||||||
|
* @param jsonversion json version
|
||||||
|
* @param dynamicrange dynamic range
|
||||||
|
* @param fileIndex file or acquisition index
|
||||||
|
* @param ndetx number of detectors in x axis
|
||||||
|
* @param ndety number of detectors in y axis
|
||||||
|
* @param npixelsx number of pixels/channels in x axis for this zmq socket
|
||||||
|
* @param npixelsy number of pixels/channels in y axis for this zmq socket
|
||||||
|
* @param imageSize number of bytes for an image in this socket
|
||||||
|
* @param frameNumber current frame number
|
||||||
|
* @param expLength exposure length or subframe index if eiger
|
||||||
|
* @param packetNumber number of packets caught for this frame
|
||||||
|
* @param bunchId bunch id
|
||||||
|
* @param timestamp time stamp
|
||||||
|
* @param modId module Id
|
||||||
|
* @param row row index in complete detector
|
||||||
|
* @param column column index in complete detector
|
||||||
|
* @param reserved reserved
|
||||||
|
* @param debug debug
|
||||||
|
* @param roundRNumber not used yet
|
||||||
|
* @param detType detector enum
|
||||||
|
* @param version detector header version
|
||||||
|
* @param gapPixelsEnable gap pixels enable (exception: if gap pixels enable
|
||||||
|
* for 4 bit mode, data is not yet gap pixel enabled in receiver)
|
||||||
|
* @param flippedDataX if it is flipped across x axis
|
||||||
|
* @param quadEnable if quad is enabled
|
||||||
|
* @param additionalJsonHeader additional json header
|
||||||
|
* @returns 0 if error, else 1
|
||||||
|
*/
|
||||||
|
int SendHeaderData(
|
||||||
|
int index, bool dummy, uint32_t jsonversion, uint32_t dynamicrange = 0,
|
||||||
|
uint64_t fileIndex = 0, uint32_t ndetx = 0, uint32_t ndety = 0,
|
||||||
|
uint32_t npixelsx = 0, uint32_t npixelsy = 0, uint32_t imageSize = 0,
|
||||||
|
uint64_t acqIndex = 0, uint64_t fIndex = 0, const char *fname = nullptr,
|
||||||
|
uint64_t frameNumber = 0, uint32_t expLength = 0,
|
||||||
|
uint32_t packetNumber = 0, uint64_t bunchId = 0, uint64_t timestamp = 0,
|
||||||
|
uint16_t modId = 0, uint16_t row = 0, uint16_t column = 0,
|
||||||
|
uint16_t reserved = 0, uint32_t debug = 0, uint16_t roundRNumber = 0,
|
||||||
|
uint8_t detType = 0, uint8_t version = 0, int gapPixelsEnable = 0,
|
||||||
|
int flippedDataX = 0, uint32_t quadEnable = 0,
|
||||||
|
std::string *additionalJsonHeader = 0);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destructor
|
* Send Message Body
|
||||||
*/
|
* @param buf message
|
||||||
~ZmqSocket () {
|
* @param length length of message
|
||||||
//mySocketDescriptor destructor also gets called
|
* @returns 0 if error, else 1
|
||||||
};
|
*/
|
||||||
|
int SendData(char *buf, int length);
|
||||||
/**
|
|
||||||
* Returns Port Number
|
|
||||||
* @returns Port Number
|
|
||||||
*/
|
|
||||||
uint32_t GetPortNumber () { return portno; };
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns Server Address
|
|
||||||
* @returns Server Address
|
|
||||||
*/
|
|
||||||
char* GetZmqServerAddress () { return sockfd.serverAddress; };
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns Socket Descriptor
|
|
||||||
* @reutns Socket descriptor
|
|
||||||
*/
|
|
||||||
|
|
||||||
void* GetsocketDescriptor () { return sockfd.socketDescriptor; };
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Connect client socket to server socket
|
|
||||||
* @returns 1 for fail, 0 for success
|
|
||||||
*/
|
|
||||||
int Connect() {
|
|
||||||
if (zmq_connect(sockfd.socketDescriptor, sockfd.serverAddress) < 0) {
|
|
||||||
PrintError ();
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Unbinds the Socket
|
|
||||||
*/
|
|
||||||
void Disconnect () {sockfd.Disconnect();};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Close Socket and destroy Context
|
|
||||||
*/
|
|
||||||
void Close () { sockfd.Close(); };
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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) {
|
|
||||||
LOG(logERROR) << "Error: Could not convert hostname " << hostname << " to internet address (zmq):"
|
|
||||||
<< gai_strerror(errcode);
|
|
||||||
} else {
|
|
||||||
if (*res == NULL) {
|
|
||||||
LOG(logERROR) << "Could not convert hostname " << hostname << " to internet address (zmq): "
|
|
||||||
"gettaddrinfo returned null";
|
|
||||||
} else{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
LOG(logERROR) << "Could not convert hostname to internet address";
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
LOG(logERROR) << "Could not convert internet address to ip string";
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send Message Header
|
* Receive Header (Important to close message after parsing header)
|
||||||
* @param index self index for debugging
|
* @param index self index for debugging
|
||||||
* @param dummy true if a dummy message for end of acquisition
|
* @param document parsed document reference
|
||||||
* @param jsonversion json version
|
* @param version version that has to match, -1 to not care
|
||||||
* @param dynamicrange dynamic range
|
* @returns 0 if error or end of acquisition, else 1 (call
|
||||||
* @param fileIndex file or acquisition index
|
* CloseHeaderMessage after parsing header)
|
||||||
* @param ndetx number of detectors in x axis
|
*/
|
||||||
* @param ndety number of detectors in y axis
|
int ReceiveHeader(const int index, rapidjson::Document &document, uint32_t version);
|
||||||
* @param npixelsx number of pixels/channels in x axis for this zmq socket
|
|
||||||
* @param npixelsy number of pixels/channels in y axis for this zmq socket
|
|
||||||
* @param imageSize number of bytes for an image in this socket
|
|
||||||
* @param frameNumber current frame number
|
|
||||||
* @param expLength exposure length or subframe index if eiger
|
|
||||||
* @param packetNumber number of packets caught for this frame
|
|
||||||
* @param bunchId bunch id
|
|
||||||
* @param timestamp time stamp
|
|
||||||
* @param modId module Id
|
|
||||||
* @param row row index in complete detector
|
|
||||||
* @param column column index in complete detector
|
|
||||||
* @param reserved reserved
|
|
||||||
* @param debug debug
|
|
||||||
* @param roundRNumber not used yet
|
|
||||||
* @param detType detector enum
|
|
||||||
* @param version detector header version
|
|
||||||
* @param gapPixelsEnable gap pixels enable (exception: if gap pixels enable for 4 bit mode, data is not yet gap pixel enabled in receiver)
|
|
||||||
* @param flippedDataX if it is flipped across x axis
|
|
||||||
* @param quadEnable if quad is enabled
|
|
||||||
* @param additionalJsonHeader additional json header
|
|
||||||
* @returns 0 if error, else 1
|
|
||||||
*/
|
|
||||||
int SendHeaderData ( int index, bool dummy, uint32_t jsonversion, uint32_t dynamicrange = 0, uint64_t fileIndex = 0,
|
|
||||||
uint32_t ndetx = 0, uint32_t ndety = 0, uint32_t npixelsx = 0, uint32_t npixelsy = 0, uint32_t imageSize = 0,
|
|
||||||
uint64_t acqIndex = 0, uint64_t fIndex = 0, const char* fname = NULL,
|
|
||||||
uint64_t frameNumber = 0, uint32_t expLength = 0, uint32_t packetNumber = 0,
|
|
||||||
uint64_t bunchId = 0, uint64_t timestamp = 0,
|
|
||||||
uint16_t modId = 0, uint16_t row = 0, uint16_t column = 0, uint16_t reserved = 0,
|
|
||||||
uint32_t debug = 0, uint16_t roundRNumber = 0,
|
|
||||||
uint8_t detType = 0, uint8_t version = 0, int gapPixelsEnable = 0, int flippedDataX = 0,
|
|
||||||
uint32_t quadEnable = 0,
|
|
||||||
std::string* additionalJsonHeader = 0) {
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** Json Header Format */
|
|
||||||
const char jsonHeaderFormat[] =
|
|
||||||
"{"
|
|
||||||
"\"jsonversion\":%u, "
|
|
||||||
"\"bitmode\":%u, "
|
|
||||||
"\"fileIndex\":%lu, "
|
|
||||||
"\"detshape\":[%u, %u], "
|
|
||||||
"\"shape\":[%u, %u], "
|
|
||||||
"\"size\":%u, "
|
|
||||||
"\"acqIndex\":%lu, "
|
|
||||||
"\"fIndex\":%lu, "
|
|
||||||
"\"fname\":\"%s\", "
|
|
||||||
"\"data\": %d, "
|
|
||||||
|
|
||||||
"\"frameNumber\":%lu, "
|
|
||||||
"\"expLength\":%u, "
|
|
||||||
"\"packetNumber\":%u, "
|
|
||||||
"\"bunchId\":%lu, "
|
|
||||||
"\"timestamp\":%lu, "
|
|
||||||
"\"modId\":%u, "
|
|
||||||
"\"row\":%u, "
|
|
||||||
"\"column\":%u, "
|
|
||||||
"\"reserved\":%u, "
|
|
||||||
"\"debug\":%u, "
|
|
||||||
"\"roundRNumber\":%u, "
|
|
||||||
"\"detType\":%u, "
|
|
||||||
"\"version\":%u, "
|
|
||||||
|
|
||||||
//additional stuff
|
|
||||||
"\"gappixels\":%u, "
|
|
||||||
"\"flippedDataX\":%u, "
|
|
||||||
"\"quad\":%u"
|
|
||||||
|
|
||||||
;//"}\n";
|
|
||||||
char buf[MAX_STR_LENGTH] = "";
|
|
||||||
sprintf(buf, jsonHeaderFormat,
|
|
||||||
jsonversion, dynamicrange, fileIndex, ndetx, ndety, npixelsx, npixelsy, imageSize,
|
|
||||||
acqIndex, fIndex, (fname == NULL)? "":fname, dummy?0:1,
|
|
||||||
|
|
||||||
frameNumber, expLength, packetNumber, bunchId, timestamp,
|
|
||||||
modId, row, column, reserved, debug, roundRNumber,
|
|
||||||
detType, version,
|
|
||||||
|
|
||||||
//additional stuff
|
|
||||||
gapPixelsEnable,
|
|
||||||
flippedDataX,
|
|
||||||
quadEnable
|
|
||||||
);
|
|
||||||
|
|
||||||
if (additionalJsonHeader && !((*additionalJsonHeader).empty())) {
|
|
||||||
strcat(buf, ", ");
|
|
||||||
strcat(buf, (*additionalJsonHeader).c_str());
|
|
||||||
}
|
|
||||||
strcat(buf, "}\n");
|
|
||||||
int length = strlen(buf);
|
|
||||||
|
|
||||||
#ifdef VERBOSE
|
|
||||||
//if(!index)
|
|
||||||
cprintf(BLUE,"%d : Streamer: buf: %s\n", index, buf);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if(zmq_send (sockfd.socketDescriptor, buf, length, dummy?0:ZMQ_SNDMORE) < 0) {
|
|
||||||
PrintError ();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#ifdef VERBOSE
|
|
||||||
cprintf(GREEN,"[%u] send header data\n",portno);
|
|
||||||
#endif
|
|
||||||
return 1;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send Message Body
|
|
||||||
* @param buf message
|
|
||||||
* @param length length of message
|
|
||||||
* @returns 0 if error, else 1
|
|
||||||
*/
|
|
||||||
int SendData (char* buf, int length) {
|
|
||||||
if(zmq_send (sockfd.socketDescriptor, buf, length, 0) < 0) {
|
|
||||||
PrintError ();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#ifdef VERBOSE
|
|
||||||
cprintf(GREEN,"[%u] send data\n",portno);
|
|
||||||
#endif
|
|
||||||
return 1;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Receive Message
|
|
||||||
* @param index self index for debugging
|
|
||||||
* @param message message
|
|
||||||
* @returns length of message, -1 if error
|
|
||||||
*/
|
|
||||||
int ReceiveMessage(const int index, zmq_msg_t& message) {
|
|
||||||
int length = zmq_msg_recv (&message, sockfd.socketDescriptor, 0);
|
|
||||||
if (length == -1) {
|
|
||||||
PrintError ();
|
|
||||||
LOG(logERROR) << "Could not read header for socket " << index;
|
|
||||||
}
|
|
||||||
#ifdef VERBOSE
|
|
||||||
else
|
|
||||||
cprintf( RED,"Message %d Length: %d Header:%s \n", index, length, (char*) zmq_msg_data (&message) );
|
|
||||||
#endif
|
|
||||||
return length;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Receive Header (Important to close message after parsing header)
|
|
||||||
* @param index self index for debugging
|
|
||||||
* @param document parsed document reference
|
|
||||||
* @param version version that has to match, -1 to not care
|
|
||||||
* @returns 0 if error or end of acquisition, else 1 (call CloseHeaderMessage after parsing header)
|
|
||||||
*/
|
|
||||||
int ReceiveHeader(const int index, Document& document, uint32_t version)
|
|
||||||
{
|
|
||||||
std::vector<char>buffer(MAX_STR_LENGTH);
|
|
||||||
int len = zmq_recv(sockfd.socketDescriptor, buffer.data(), buffer.size(),0);
|
|
||||||
if ( len > 0 ) {
|
|
||||||
bool dummy = false;
|
|
||||||
#ifdef ZMQ_DETAIL
|
|
||||||
cprintf( BLUE,"Header %d [%d] Length: %d Header:%s \n", index, portno, len, buffer.data());
|
|
||||||
#endif
|
|
||||||
if ( ParseHeader (index, len, buffer.data(), document, dummy, version)) {
|
|
||||||
#ifdef ZMQ_DETAIL
|
|
||||||
cprintf( RED,"Parsed Header %d [%d] Length: %d Header:%s \n", index, portno, len, buffer.data() );
|
|
||||||
#endif
|
|
||||||
if (dummy) {
|
|
||||||
#ifdef ZMQ_DETAIL
|
|
||||||
cprintf(RED,"%d [%d] Received end of acquisition\n", index, portno );
|
|
||||||
#endif
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#ifdef ZMQ_DETAIL
|
|
||||||
cprintf(GREEN,"%d [%d] data\n",index, portno );
|
|
||||||
#endif
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Close Header Message. Call this function if ReceiveHeader returned 1
|
* Close Header Message. Call this function if ReceiveHeader returned 1
|
||||||
@ -445,183 +190,60 @@ public:
|
|||||||
* @param version version that has to match, -1 to not care
|
* @param version version that has to match, -1 to not care
|
||||||
* @returns true if successful else false
|
* @returns true if successful else false
|
||||||
*/
|
*/
|
||||||
int ParseHeader(const int index, int length, char* buff,
|
int ParseHeader(const int index, int length, char *buff, rapidjson::Document &document,
|
||||||
Document& document, bool& dummy, uint32_t version)
|
bool &dummy, uint32_t version);
|
||||||
{
|
|
||||||
if ( document.Parse( buff, length).HasParseError() ) {
|
|
||||||
LOG(logERROR) << index << " Could not parse. len:" << length << ": Message:" << buff;
|
|
||||||
fflush ( stdout );
|
|
||||||
// char* buf = (char*) zmq_msg_data (&message);
|
|
||||||
for ( int i= 0; i < length; ++i ) {
|
|
||||||
cprintf(RED,"%02x ",buff[i]);
|
|
||||||
}
|
|
||||||
printf("\n");
|
|
||||||
fflush( stdout );
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (document["jsonversion"].GetUint() != version) {
|
/**
|
||||||
LOG(logERROR) << "version mismatch. required " << version << ", got " << document["jsonversion"].GetUint();
|
* Receive Data
|
||||||
return 0;
|
* @param index self index for debugging
|
||||||
}
|
* @param buf buffer to copy image data to
|
||||||
|
* @param size size of image
|
||||||
|
* @returns length of data received
|
||||||
|
*/
|
||||||
|
int ReceiveData(const int index, char *buf, const int size);
|
||||||
|
|
||||||
dummy = false;
|
/**
|
||||||
int temp = document["data"].GetUint();
|
* Print error
|
||||||
dummy = temp ? false : true;
|
*/
|
||||||
|
void PrintError();
|
||||||
|
|
||||||
return 1;
|
private:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Receive Message
|
||||||
|
* @param index self index for debugging
|
||||||
|
* @param message message
|
||||||
|
* @returns length of message, -1 if error
|
||||||
|
*/
|
||||||
|
int ReceiveMessage(const int index, zmq_msg_t &message);
|
||||||
|
/**
|
||||||
|
* Class to close socket descriptors automatically
|
||||||
|
* upon encountering exceptions in the ZmqSocket constructor
|
||||||
|
*/
|
||||||
|
class mySocketDescriptors {
|
||||||
|
public:
|
||||||
|
/** Constructor */
|
||||||
|
mySocketDescriptors();
|
||||||
|
/** Destructor */
|
||||||
|
~mySocketDescriptors();
|
||||||
|
/** Unbinds the Socket */
|
||||||
|
void Disconnect();
|
||||||
|
/** Close Socket and destroy Context */
|
||||||
|
void Close();
|
||||||
|
/** true if server, else false */
|
||||||
|
bool server;
|
||||||
|
/** Server Address */
|
||||||
|
char serverAddress[1000];
|
||||||
|
/** Context Descriptor */
|
||||||
|
void *contextDescriptor;
|
||||||
|
/** Socket Descriptor */
|
||||||
|
void *socketDescriptor;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
/** Port Number */
|
||||||
|
uint32_t portno;
|
||||||
|
|
||||||
/**
|
/** Socket descriptor */
|
||||||
* Receive Data
|
mySocketDescriptors sockfd;
|
||||||
* @param index self index for debugging
|
|
||||||
* @param buf buffer to copy image data to
|
|
||||||
* @param size size of image
|
|
||||||
* @returns length of data received
|
|
||||||
*/
|
|
||||||
int ReceiveData(const int index, char* buf, const int size)
|
|
||||||
{
|
|
||||||
zmq_msg_t message;
|
|
||||||
zmq_msg_init (&message);
|
|
||||||
int length = ReceiveMessage(index, message);
|
|
||||||
|
|
||||||
//actual data
|
|
||||||
if (length == size) {
|
|
||||||
#ifdef VERBOSE
|
|
||||||
cprintf(BLUE,"%d actual data\n", index);
|
|
||||||
#endif
|
|
||||||
memcpy(buf, (char*)zmq_msg_data(&message), size);
|
|
||||||
}
|
|
||||||
|
|
||||||
//incorrect size (smaller)
|
|
||||||
else if (length < size){
|
|
||||||
#ifdef ROIVERBOSITY
|
|
||||||
cprintf(RED,"Error: Received smaller packet size %d for socket %d\n", length, index);
|
|
||||||
#endif
|
|
||||||
memcpy(buf, (char*)zmq_msg_data(&message), length);
|
|
||||||
memset(buf+length,0xFF,size-length);
|
|
||||||
}
|
|
||||||
//incorrect size (larger)
|
|
||||||
else {
|
|
||||||
LOG(logERROR) << "Received weird packet size " << length << " for socket " << index;
|
|
||||||
memset(buf,0xFF,size);
|
|
||||||
}
|
|
||||||
|
|
||||||
zmq_msg_close(&message);
|
|
||||||
return length;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Print error
|
|
||||||
*/
|
|
||||||
void PrintError () {
|
|
||||||
switch (errno) {
|
|
||||||
case EINVAL:
|
|
||||||
LOG(logERROR) << "The socket type/option or value/endpoint supplied is invalid (zmq)";
|
|
||||||
break;
|
|
||||||
case EAGAIN:
|
|
||||||
LOG(logERROR) << "Non-blocking mode was requested and the message cannot be sent/available at the moment (zmq)";
|
|
||||||
break;
|
|
||||||
case ENOTSUP:
|
|
||||||
LOG(logERROR) << "The zmq_send()/zmq_msg_recv() operation is not supported by this socket type (zmq)";
|
|
||||||
break;
|
|
||||||
case EFSM:
|
|
||||||
LOG(logERROR) << "The zmq_send()/zmq_msg_recv() unavailable now as socket in inappropriate state (eg. ZMQ_REP). Look up messaging patterns (zmq)";
|
|
||||||
break;
|
|
||||||
case EFAULT:
|
|
||||||
LOG(logERROR) << "The provided context/message is invalid (zmq)";
|
|
||||||
break;
|
|
||||||
case EMFILE:
|
|
||||||
LOG(logERROR) << "The limit on the total number of open ØMQ sockets has been reached (zmq)";
|
|
||||||
break;
|
|
||||||
case EPROTONOSUPPORT:
|
|
||||||
LOG(logERROR) << "The requested transport protocol is not supported (zmq)";
|
|
||||||
break;
|
|
||||||
case ENOCOMPATPROTO:
|
|
||||||
LOG(logERROR) << "The requested transport protocol is not compatible with the socket type (zmq)";
|
|
||||||
break;
|
|
||||||
case EADDRINUSE:
|
|
||||||
LOG(logERROR) << "The requested address is already in use (zmq)";
|
|
||||||
break;
|
|
||||||
case EADDRNOTAVAIL:
|
|
||||||
LOG(logERROR) << "The requested address was not local (zmq)";
|
|
||||||
break;
|
|
||||||
case ENODEV:
|
|
||||||
LOG(logERROR) << "The requested address specifies a nonexistent interface (zmq)";
|
|
||||||
break;
|
|
||||||
case ETERM:
|
|
||||||
LOG(logERROR) << "The ØMQ context associated with the specified socket was terminated (zmq)";
|
|
||||||
break;
|
|
||||||
case ENOTSOCK:
|
|
||||||
LOG(logERROR) << "The provided socket was invalid (zmq)";
|
|
||||||
break;
|
|
||||||
case EINTR:
|
|
||||||
LOG(logERROR) << "The operation was interrupted by delivery of a signal (zmq)";
|
|
||||||
break;
|
|
||||||
case EMTHREAD:
|
|
||||||
LOG(logERROR) << "No I/O thread is available to accomplish the task (zmq)";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
LOG(logERROR) << "Unknown socket error (zmq)";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class to close socket descriptors automatically
|
|
||||||
* upon encountering exceptions in the ZmqSocket constructor
|
|
||||||
*/
|
|
||||||
class mySocketDescriptors {
|
|
||||||
public:
|
|
||||||
/** Constructor */
|
|
||||||
mySocketDescriptors():
|
|
||||||
server(false),
|
|
||||||
contextDescriptor(0),
|
|
||||||
socketDescriptor(0) {};
|
|
||||||
/** Destructor */
|
|
||||||
~mySocketDescriptors() {
|
|
||||||
Disconnect();
|
|
||||||
Close();
|
|
||||||
}
|
|
||||||
/** Unbinds the Socket */
|
|
||||||
void Disconnect () {
|
|
||||||
if (server)
|
|
||||||
zmq_unbind (socketDescriptor, serverAddress);
|
|
||||||
else
|
|
||||||
zmq_disconnect (socketDescriptor, serverAddress);
|
|
||||||
};
|
|
||||||
/** Close Socket and destroy Context */
|
|
||||||
void Close () {
|
|
||||||
if (socketDescriptor != NULL) {
|
|
||||||
zmq_close (socketDescriptor);
|
|
||||||
socketDescriptor = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (contextDescriptor != NULL) {
|
|
||||||
zmq_ctx_destroy (contextDescriptor);
|
|
||||||
contextDescriptor = NULL;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
/** true if server, else false */
|
|
||||||
bool server;
|
|
||||||
/** Server Address */
|
|
||||||
char serverAddress[1000];
|
|
||||||
/** Context Descriptor */
|
|
||||||
void* contextDescriptor;
|
|
||||||
/** Socket Descriptor */
|
|
||||||
void* socketDescriptor;
|
|
||||||
};
|
|
||||||
|
|
||||||
private:
|
|
||||||
/** Port Number */
|
|
||||||
uint32_t portno;
|
|
||||||
|
|
||||||
/** Socket descriptor */
|
|
||||||
mySocketDescriptors sockfd;
|
|
||||||
};
|
};
|
||||||
|
@ -14,8 +14,6 @@
|
|||||||
#define __cplusplus
|
#define __cplusplus
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "ansi.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
//C++ includes
|
//C++ includes
|
||||||
#include "sls_detector_exceptions.h"
|
#include "sls_detector_exceptions.h"
|
||||||
|
@ -5,8 +5,8 @@
|
|||||||
#define APIGUI 0x200227
|
#define APIGUI 0x200227
|
||||||
#define APICTB 0x200310
|
#define APICTB 0x200310
|
||||||
#define APIGOTTHARD 0x200310
|
#define APIGOTTHARD 0x200310
|
||||||
#define APIGOTTHARD2 0x200310
|
|
||||||
#define APIJUNGFRAU 0x200310
|
#define APIJUNGFRAU 0x200310
|
||||||
#define APIMYTHEN3 0x200310
|
#define APIMYTHEN3 0x200310
|
||||||
#define APIMOENCH 0x200310
|
#define APIMOENCH 0x200310
|
||||||
#define APIEIGER 0x200310
|
#define APIEIGER 0x200310
|
||||||
|
#define APIGOTTHARD2 0x200313
|
||||||
|
410
slsSupportLib/src/ZmqSocket.cpp
Normal file
410
slsSupportLib/src/ZmqSocket.cpp
Normal file
@ -0,0 +1,410 @@
|
|||||||
|
#include "ZmqSocket.h"
|
||||||
|
#include <zmq.h>
|
||||||
|
#include <vector>
|
||||||
|
#include <arpa/inet.h> //inet_ntoa
|
||||||
|
#include <errno.h>
|
||||||
|
#include <iostream>
|
||||||
|
#include <netdb.h> //gethostbyname()
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h> //usleep in some machines
|
||||||
|
|
||||||
|
using namespace rapidjson;
|
||||||
|
ZmqSocket::ZmqSocket(const char *const hostname_or_ip,
|
||||||
|
const uint32_t portnumber)
|
||||||
|
: portno(portnumber)
|
||||||
|
// headerMessage(0)
|
||||||
|
{
|
||||||
|
char ip[MAX_STR_LENGTH] = "";
|
||||||
|
memset(ip, 0, MAX_STR_LENGTH);
|
||||||
|
|
||||||
|
// convert hostname to ip (not required, but a test that returns if failed)
|
||||||
|
struct addrinfo *result;
|
||||||
|
if ((ConvertHostnameToInternetAddress(hostname_or_ip, &result)) ||
|
||||||
|
(ConvertInternetAddresstoIpString(result, ip, MAX_STR_LENGTH)))
|
||||||
|
throw sls::ZmqSocketError("Could convert IP to string");
|
||||||
|
|
||||||
|
// construct address
|
||||||
|
sprintf(sockfd.serverAddress, "tcp://%s:%d", ip, portno);
|
||||||
|
#ifdef VERBOSE
|
||||||
|
cprintf(BLUE, "address:%s\n", sockfd.serverAddress);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// create context
|
||||||
|
sockfd.contextDescriptor = zmq_ctx_new();
|
||||||
|
if (sockfd.contextDescriptor == 0)
|
||||||
|
throw sls::ZmqSocketError("Could not create contextDescriptor");
|
||||||
|
|
||||||
|
// create publisher
|
||||||
|
sockfd.socketDescriptor = zmq_socket(sockfd.contextDescriptor, ZMQ_SUB);
|
||||||
|
if (sockfd.socketDescriptor == 0) {
|
||||||
|
PrintError();
|
||||||
|
Close();
|
||||||
|
throw sls::ZmqSocketError("Could not create socket");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Socket Options provided above
|
||||||
|
// an empty string implies receiving any messages
|
||||||
|
if (zmq_setsockopt(sockfd.socketDescriptor, ZMQ_SUBSCRIBE, "", 0)) {
|
||||||
|
PrintError();
|
||||||
|
Close();
|
||||||
|
throw sls::ZmqSocketError("Could set socket opt");
|
||||||
|
}
|
||||||
|
// ZMQ_LINGER default is already -1 means no messages discarded. use this
|
||||||
|
// options if optimizing required ZMQ_SNDHWM default is 0 means no limit.
|
||||||
|
// use this to optimize if optimizing required eg. int value = -1;
|
||||||
|
int value = 0;
|
||||||
|
if (zmq_setsockopt(sockfd.socketDescriptor, ZMQ_LINGER, &value,
|
||||||
|
sizeof(value))) {
|
||||||
|
PrintError();
|
||||||
|
Close();
|
||||||
|
throw sls::ZmqSocketError("Could not set ZMQ_LINGER");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ZmqSocket::ZmqSocket(const uint32_t portnumber, const char *ethip)
|
||||||
|
:
|
||||||
|
|
||||||
|
portno(portnumber)
|
||||||
|
// headerMessage(0)
|
||||||
|
{
|
||||||
|
sockfd.server = true;
|
||||||
|
|
||||||
|
// create context
|
||||||
|
sockfd.contextDescriptor = zmq_ctx_new();
|
||||||
|
if (sockfd.contextDescriptor == 0)
|
||||||
|
throw sls::ZmqSocketError("Could not create contextDescriptor");
|
||||||
|
// create publisher
|
||||||
|
sockfd.socketDescriptor = zmq_socket(sockfd.contextDescriptor, ZMQ_PUB);
|
||||||
|
if (sockfd.socketDescriptor == 0) {
|
||||||
|
PrintError();
|
||||||
|
Close();
|
||||||
|
throw sls::ZmqSocketError("Could not create socket");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Socket Options provided above
|
||||||
|
|
||||||
|
// construct addresss
|
||||||
|
sprintf(sockfd.serverAddress, "tcp://%s:%d", ethip, portno);
|
||||||
|
#ifdef VERBOSE
|
||||||
|
cprintf(BLUE, "address:%s\n", sockfd.serverAddress);
|
||||||
|
#endif
|
||||||
|
// bind address
|
||||||
|
if (zmq_bind(sockfd.socketDescriptor, sockfd.serverAddress) < 0) {
|
||||||
|
PrintError();
|
||||||
|
Close();
|
||||||
|
throw sls::ZmqSocketError("Could not bind socket");
|
||||||
|
}
|
||||||
|
|
||||||
|
// sleep for a few milliseconds to allow a slow-joiner
|
||||||
|
usleep(200 * 1000);
|
||||||
|
};
|
||||||
|
|
||||||
|
int ZmqSocket::Connect() {
|
||||||
|
if (zmq_connect(sockfd.socketDescriptor, sockfd.serverAddress) < 0) {
|
||||||
|
PrintError();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ZmqSocket::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) {
|
||||||
|
LOG(logERROR) << "Error: Could not convert hostname " << hostname
|
||||||
|
<< " to internet address (zmq):" << gai_strerror(errcode);
|
||||||
|
} else {
|
||||||
|
if (*res == NULL) {
|
||||||
|
LOG(logERROR) << "Could not convert hostname " << hostname
|
||||||
|
<< " to internet address (zmq): "
|
||||||
|
"gettaddrinfo returned null";
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LOG(logERROR) << "Could not convert hostname to internet address";
|
||||||
|
return 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
int ZmqSocket::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;
|
||||||
|
}
|
||||||
|
LOG(logERROR) << "Could not convert internet address to ip string";
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZmqSocket::PrintError() {
|
||||||
|
switch (errno) {
|
||||||
|
case EINVAL:
|
||||||
|
LOG(logERROR) << "The socket type/option or value/endpoint supplied is "
|
||||||
|
"invalid (zmq)";
|
||||||
|
break;
|
||||||
|
case EAGAIN:
|
||||||
|
LOG(logERROR) << "Non-blocking mode was requested and the message "
|
||||||
|
"cannot be sent/available at the moment (zmq)";
|
||||||
|
break;
|
||||||
|
case ENOTSUP:
|
||||||
|
LOG(logERROR) << "The zmq_send()/zmq_msg_recv() operation is not "
|
||||||
|
"supported by this socket type (zmq)";
|
||||||
|
break;
|
||||||
|
case EFSM:
|
||||||
|
LOG(logERROR) << "The zmq_send()/zmq_msg_recv() unavailable now as "
|
||||||
|
"socket in inappropriate state (eg. ZMQ_REP). Look up "
|
||||||
|
"messaging patterns (zmq)";
|
||||||
|
break;
|
||||||
|
case EFAULT:
|
||||||
|
LOG(logERROR) << "The provided context/message is invalid (zmq)";
|
||||||
|
break;
|
||||||
|
case EMFILE:
|
||||||
|
LOG(logERROR) << "The limit on the total number of open ØMQ sockets "
|
||||||
|
"has been reached (zmq)";
|
||||||
|
break;
|
||||||
|
case EPROTONOSUPPORT:
|
||||||
|
LOG(logERROR)
|
||||||
|
<< "The requested transport protocol is not supported (zmq)";
|
||||||
|
break;
|
||||||
|
case ENOCOMPATPROTO:
|
||||||
|
LOG(logERROR) << "The requested transport protocol is not compatible "
|
||||||
|
"with the socket type (zmq)";
|
||||||
|
break;
|
||||||
|
case EADDRINUSE:
|
||||||
|
LOG(logERROR) << "The requested address is already in use (zmq)";
|
||||||
|
break;
|
||||||
|
case EADDRNOTAVAIL:
|
||||||
|
LOG(logERROR) << "The requested address was not local (zmq)";
|
||||||
|
break;
|
||||||
|
case ENODEV:
|
||||||
|
LOG(logERROR)
|
||||||
|
<< "The requested address specifies a nonexistent interface (zmq)";
|
||||||
|
break;
|
||||||
|
case ETERM:
|
||||||
|
LOG(logERROR) << "The ØMQ context associated with the specified socket "
|
||||||
|
"was terminated (zmq)";
|
||||||
|
break;
|
||||||
|
case ENOTSOCK:
|
||||||
|
LOG(logERROR) << "The provided socket was invalid (zmq)";
|
||||||
|
break;
|
||||||
|
case EINTR:
|
||||||
|
LOG(logERROR)
|
||||||
|
<< "The operation was interrupted by delivery of a signal (zmq)";
|
||||||
|
break;
|
||||||
|
case EMTHREAD:
|
||||||
|
LOG(logERROR)
|
||||||
|
<< "No I/O thread is available to accomplish the task (zmq)";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
LOG(logERROR) << "Unknown socket error (zmq)";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int ZmqSocket::ReceiveData(const int index, char *buf, const int size) {
|
||||||
|
zmq_msg_t message;
|
||||||
|
zmq_msg_init(&message);
|
||||||
|
int length = ReceiveMessage(index, message);
|
||||||
|
if (length == size) {
|
||||||
|
memcpy(buf, (char *)zmq_msg_data(&message), size);
|
||||||
|
} else if (length < size) {
|
||||||
|
memcpy(buf, (char *)zmq_msg_data(&message), length);
|
||||||
|
memset(buf + length, 0xFF, size - length);
|
||||||
|
} else {
|
||||||
|
LOG(logERROR) << "Received weird packet size " << length
|
||||||
|
<< " for socket " << index;
|
||||||
|
memset(buf, 0xFF, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
zmq_msg_close(&message);
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ZmqSocket::ParseHeader(const int index, int length, char *buff,
|
||||||
|
Document &document, bool &dummy, uint32_t version) {
|
||||||
|
if (document.Parse(buff, length).HasParseError()) {
|
||||||
|
LOG(logERROR) << index << " Could not parse. len:" << length
|
||||||
|
<< ": Message:" << buff;
|
||||||
|
fflush(stdout);
|
||||||
|
// char* buf = (char*) zmq_msg_data (&message);
|
||||||
|
for (int i = 0; i < length; ++i) {
|
||||||
|
cprintf(RED, "%02x ", buff[i]);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
fflush(stdout);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (document["jsonversion"].GetUint() != version) {
|
||||||
|
LOG(logERROR) << "version mismatch. required " << version << ", got "
|
||||||
|
<< document["jsonversion"].GetUint();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
dummy = false;
|
||||||
|
int temp = document["data"].GetUint();
|
||||||
|
dummy = temp ? false : true;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ZmqSocket::ReceiveHeader(const int index, Document &document,
|
||||||
|
uint32_t version) {
|
||||||
|
std::vector<char> buffer(MAX_STR_LENGTH);
|
||||||
|
int len =
|
||||||
|
zmq_recv(sockfd.socketDescriptor, buffer.data(), buffer.size(), 0);
|
||||||
|
if (len > 0) {
|
||||||
|
bool dummy = false;
|
||||||
|
#ifdef ZMQ_DETAIL
|
||||||
|
cprintf(BLUE, "Header %d [%d] Length: %d Header:%s \n", index, portno,
|
||||||
|
len, buffer.data());
|
||||||
|
#endif
|
||||||
|
if (ParseHeader(index, len, buffer.data(), document, dummy, version)) {
|
||||||
|
#ifdef ZMQ_DETAIL
|
||||||
|
cprintf(RED, "Parsed Header %d [%d] Length: %d Header:%s \n", index,
|
||||||
|
portno, len, buffer.data());
|
||||||
|
#endif
|
||||||
|
if (dummy) {
|
||||||
|
#ifdef ZMQ_DETAIL
|
||||||
|
cprintf(RED, "%d [%d] Received end of acquisition\n", index,
|
||||||
|
portno);
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#ifdef ZMQ_DETAIL
|
||||||
|
cprintf(GREEN, "%d [%d] data\n", index, portno);
|
||||||
|
#endif
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
int ZmqSocket::ReceiveMessage(const int index, zmq_msg_t &message) {
|
||||||
|
int length = zmq_msg_recv(&message, sockfd.socketDescriptor, 0);
|
||||||
|
if (length == -1) {
|
||||||
|
PrintError();
|
||||||
|
LOG(logERROR) << "Could not read header for socket " << index;
|
||||||
|
}
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ZmqSocket::SendData(char *buf, int length) {
|
||||||
|
if (zmq_send(sockfd.socketDescriptor, buf, length, 0) < 0) {
|
||||||
|
PrintError();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ZmqSocket::SendHeaderData(
|
||||||
|
int index, bool dummy, uint32_t jsonversion, uint32_t dynamicrange,
|
||||||
|
uint64_t fileIndex, uint32_t ndetx, uint32_t ndety, uint32_t npixelsx,
|
||||||
|
uint32_t npixelsy, uint32_t imageSize, uint64_t acqIndex, uint64_t fIndex,
|
||||||
|
const char *fname, uint64_t frameNumber, uint32_t expLength,
|
||||||
|
uint32_t packetNumber, uint64_t bunchId, uint64_t timestamp, uint16_t modId,
|
||||||
|
uint16_t row, uint16_t column, uint16_t reserved, uint32_t debug,
|
||||||
|
uint16_t roundRNumber, uint8_t detType, uint8_t version,
|
||||||
|
int gapPixelsEnable, int flippedDataX, uint32_t quadEnable,
|
||||||
|
std::string *additionalJsonHeader) {
|
||||||
|
|
||||||
|
/** Json Header Format */
|
||||||
|
const char jsonHeaderFormat[] = "{"
|
||||||
|
"\"jsonversion\":%u, "
|
||||||
|
"\"bitmode\":%u, "
|
||||||
|
"\"fileIndex\":%lu, "
|
||||||
|
"\"detshape\":[%u, %u], "
|
||||||
|
"\"shape\":[%u, %u], "
|
||||||
|
"\"size\":%u, "
|
||||||
|
"\"acqIndex\":%lu, "
|
||||||
|
"\"fIndex\":%lu, "
|
||||||
|
"\"fname\":\"%s\", "
|
||||||
|
"\"data\": %d, "
|
||||||
|
|
||||||
|
"\"frameNumber\":%lu, "
|
||||||
|
"\"expLength\":%u, "
|
||||||
|
"\"packetNumber\":%u, "
|
||||||
|
"\"bunchId\":%lu, "
|
||||||
|
"\"timestamp\":%lu, "
|
||||||
|
"\"modId\":%u, "
|
||||||
|
"\"row\":%u, "
|
||||||
|
"\"column\":%u, "
|
||||||
|
"\"reserved\":%u, "
|
||||||
|
"\"debug\":%u, "
|
||||||
|
"\"roundRNumber\":%u, "
|
||||||
|
"\"detType\":%u, "
|
||||||
|
"\"version\":%u, "
|
||||||
|
|
||||||
|
// additional stuff
|
||||||
|
"\"gappixels\":%u, "
|
||||||
|
"\"flippedDataX\":%u, "
|
||||||
|
"\"quad\":%u"
|
||||||
|
|
||||||
|
; //"}\n";
|
||||||
|
char buf[MAX_STR_LENGTH] = "";
|
||||||
|
sprintf(buf, jsonHeaderFormat, jsonversion, dynamicrange, fileIndex, ndetx,
|
||||||
|
ndety, npixelsx, npixelsy, imageSize, acqIndex, fIndex,
|
||||||
|
(fname == NULL) ? "" : fname, dummy ? 0 : 1,
|
||||||
|
|
||||||
|
frameNumber, expLength, packetNumber, bunchId, timestamp, modId,
|
||||||
|
row, column, reserved, debug, roundRNumber, detType, version,
|
||||||
|
|
||||||
|
// additional stuff
|
||||||
|
gapPixelsEnable, flippedDataX, quadEnable);
|
||||||
|
|
||||||
|
if (additionalJsonHeader && !((*additionalJsonHeader).empty())) {
|
||||||
|
strcat(buf, ", ");
|
||||||
|
strcat(buf, (*additionalJsonHeader).c_str());
|
||||||
|
}
|
||||||
|
strcat(buf, "}\n");
|
||||||
|
int length = strlen(buf);
|
||||||
|
|
||||||
|
#ifdef VERBOSE
|
||||||
|
// if(!index)
|
||||||
|
cprintf(BLUE, "%d : Streamer: buf: %s\n", index, buf);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (zmq_send(sockfd.socketDescriptor, buf, length,
|
||||||
|
dummy ? 0 : ZMQ_SNDMORE) < 0) {
|
||||||
|
PrintError();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#ifdef VERBOSE
|
||||||
|
cprintf(GREEN, "[%u] send header data\n", portno);
|
||||||
|
#endif
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//Nested class to do RAII handling of socket descriptors
|
||||||
|
ZmqSocket::mySocketDescriptors::mySocketDescriptors()
|
||||||
|
: server(false), contextDescriptor(0), socketDescriptor(0){};
|
||||||
|
ZmqSocket::mySocketDescriptors::~mySocketDescriptors() {
|
||||||
|
Disconnect();
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
void ZmqSocket::mySocketDescriptors::Disconnect() {
|
||||||
|
if (server)
|
||||||
|
zmq_unbind(socketDescriptor, serverAddress);
|
||||||
|
else
|
||||||
|
zmq_disconnect(socketDescriptor, serverAddress);
|
||||||
|
};
|
||||||
|
void ZmqSocket::mySocketDescriptors::Close() {
|
||||||
|
if (socketDescriptor != NULL) {
|
||||||
|
zmq_close(socketDescriptor);
|
||||||
|
socketDescriptor = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (contextDescriptor != NULL) {
|
||||||
|
zmq_ctx_destroy(contextDescriptor);
|
||||||
|
contextDescriptor = NULL;
|
||||||
|
}
|
||||||
|
};
|
Reference in New Issue
Block a user