diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000000000000000000000000000000000000..1ff0c423042b46cb1d617b81efb715defbe8054d --- /dev/null +++ b/.gitattributes @@ -0,0 +1,63 @@ +############################################################################### +# Set default behavior to automatically normalize line endings. +############################################################################### +* text=auto + +############################################################################### +# Set default behavior for command prompt diff. +# +# This is need for earlier builds of msysgit that does not have it on by +# default for csharp files. +# Note: This is only used by command line +############################################################################### +#*.cs diff=csharp + +############################################################################### +# Set the merge driver for project and solution files +# +# Merging from the command prompt will add diff markers to the files if there +# are conflicts (Merging from VS is not affected by the settings below, in VS +# the diff markers are never inserted). Diff markers may cause the following +# file extensions to fail to load in VS. An alternative would be to treat +# these files as binary and thus will always conflict and require user +# intervention with every merge. To do so, just uncomment the entries below +############################################################################### +#*.sln merge=binary +#*.csproj merge=binary +#*.vbproj merge=binary +#*.vcxproj merge=binary +#*.vcproj merge=binary +#*.dbproj merge=binary +#*.fsproj merge=binary +#*.lsproj merge=binary +#*.wixproj merge=binary +#*.modelproj merge=binary +#*.sqlproj merge=binary +#*.wwaproj merge=binary + +############################################################################### +# behavior for image files +# +# image files are treated as binary by default. +############################################################################### +#*.jpg binary +#*.png binary +#*.gif binary + +############################################################################### +# diff behavior for common document formats +# +# Convert binary document formats to text before diffing them. This feature +# is only available from the command line. Turn it on by uncommenting the +# entries below. +############################################################################### +#*.doc diff=astextplain +#*.DOC diff=astextplain +#*.docx diff=astextplain +#*.DOCX diff=astextplain +#*.dot diff=astextplain +#*.DOT diff=astextplain +#*.pdf diff=astextplain +#*.PDF diff=astextplain +#*.rtf diff=astextplain +#*.RTF diff=astextplain diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..af6381dc6764b65942cfb69571d13a4df51528f1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,9 @@ +.vscode/ +build/ + +bin/ +obj/ +Debug/ +Release/ + +*.suo \ No newline at end of file diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000000000000000000000000000000000000..6a9360b4bd034f38f262c79fb4225bbdd7f4be70 --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,102 @@ +stages: + - build + - deploy + +before_script: + - echo "New job started" + +build_linux: + stage: build + script: + - if [ ! -d "build" ]; then + echo "build directory does not exist"; + mkdir build; + cd build; + cmake -DCMAKE_INSTALL_PREFIX=./class_api_install_linux ../src; + cd ..; + fi + - cd build + - make + cache: + paths: + - ./build + tags: + - linux + +build_windows_64: + stage: build + script: + # basic cmd shell is currently used + - echo %PATH% + # display the current directory location for debuggbing purposes + - cd + - dir + - if exist build_64 echo "Build_64 Folder already exists" + - if not exist build_64 ( + echo "Build_64 Folder does not exist" & + mkdir build_64 & + echo "Folder created" & + cd build_64 & + cmake -G "Visual Studio 15 2017 Win64" CMAKE_BUILD_TYPE=Release -DPYTHON_INCLUDE_DIR=C:\Users\class\AppData\Local\Programs\Python\Python37\include -DPYTHON_LIBRARY=C:\Users\class\AppData\Local\Programs\Python\Python37\libs\python37.lib -DCMAKE_INSTALL_PREFIX=./class_api_install_win ../src & + cd .. + ) + - cd build_64 + - cmake --build . --target ALL_BUILD --config Release + cache: + paths: + - ./build_64 + tags: + - windows + +deploy_windows_64: + stage: deploy + tags: + - windows + script: + # basic cmd shell is currently used + - echo %PATH% + # executing the install procedure + - cd build_64 + - cmake --build . --target INSTALL --config Release + # we assume here 7z.exe is in the PATH file + # - 7z a -tzip class_api_install_win.zip class_api_install_win + - dir + # write hash tag inside a file in the install + - echo "%CI_COMMIT_REF_NAME% %CI_COMMIT_SHA%" > ./class_api_install_win/hash.txt + cache: + paths: + - ./build_64 + artifacts: + paths: + - ./build_64/class_api_install_win + name: "class_api_win_%CI_COMMIT_REF_NAME%_%CI_COMMIT_SHA%" + only: + - /^release-.*$/ + - develop + - master + +deploy_linux_64: + stage: deploy + tags: + - linux + script: + # executing the install procedure + - pwd + - cd build + - make install + # write hash tag inside a file in the install + - echo "$CI_COMMIT_REF_NAME $CI_COMMIT_SHA" > ./class_api_install_linux/hash.txt + cache: + paths: + - ./build + artifacts: + paths: + - ./build/class_api_install_linux + name: "class_api_linux_$CI_COMMIT_REF_NAME_$CI_COMMIT_SHA" + only: + - /^release-.*$/ + - develop + - master + +after_script: + - echo "Job finished, well done" diff --git a/README.md b/README.md index 914747485227109637955a8dbd54913a6e8290d4..c64c8915c4abbb3c5401ac60469f7d7951444bd5 100644 --- a/README.md +++ b/README.md @@ -1,47 +1,45 @@ -This repo contains the source code of the API to communicate with a CLASS device. If you want to build the API you must install the same SW that is specified for the CI/CD. +This repo contains the source code to communicate with CLASS device through serial port. -# CI/CD +For building this project in both Windows and Linux the following tools must be installed: -A continuous integration process has been setup for building this project in both Windows and Linux. - -Requiriments of the machine in which the runner is installed: - Building tools -- cmake: required for building the project -- boost: the API depends on this header based library -- swig: for the generation of the wrappers/libraries for each of the languages programs we want to access the API from -- doxygen: for the generation of the doc for the API -- pandoc: converts README.md file to README.html +- cmake: for building the project +- swig: for the generation of wrappers +- doxygen: for the generation of the documentation - graphviz: required by doxygen ## Windows -- Build tools for Visual Studio (2017): Needed for compiling C++ stuff. There is no official link but [this](https://aka.ms/vs/15/release/vs_buildtools.exe) works. -- [boost](https://sourceforge.net/projects/boost/files/boost-binaries): download the correct binary according to your environment. +- [this](https://aka.ms/vs/15/release/vs_buildtools.exe) Build tools for Visual Studio (2017), needed for compiling C++. - [cmake](https://cmake.org/download/): Download .msi file and execute it. -- [pandoc](https://pandoc.org/installing.html): Download .msi file and execute it. - [swig](http://www.swig.org/survey.html): Download the .zip and unzip it. Include the folder into `path` environemnt variable. - [doxygen](https://www.doxygen.nl/download.html): Download .exe file and execute it. -- [python 3.7.9](https://www.python.org/downloads/release/python-379/): Download .msi file and execute it. ## Linux ``` sudo apt-get install build-essential sudo snap install cmake --classic -sudo apt-get install libboost-all-devlibrary sudo apt-get install swig sudo apt-get install doxygen sudo apt install graphviz -sudo apt-get install pandoc -sudo apt-get install python3.7 ``` -# Build proyect +# Build project +This code has been programmed in C++. Wrappers for C# are generated automatically by swig. +## C++ building with CMake +* Create a build folder and enter the folder +* Execute the following commands to configure the platform -Follow the steps of the official CMake link to build and configure the proyect if you need [cmake](https://cmake.org/cmake/help/v3.6/manual/cmake.1.html#build-tool-mode). If no custom configurations are need -Open Command Prompt (Windows) or Terminal (Linux) in the directory into where CMakeLists.txt is placed [src](./src) and run the following command + -Windows -cmake -B path-to-build + cmake -G "Visual Studio 15 2017 Win64" CMAKE_BUILD_TYPE=Release ../ + cmake --build . --target ALL_BUILD --config Release + + -Linux + + cmake ../ + make diff --git a/serial_port_class_api/CMakeLists.txt b/serial_port_class_api/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..86142f41ea15da3b4765badf77707af58c3fd1ee --- /dev/null +++ b/serial_port_class_api/CMakeLists.txt @@ -0,0 +1,38 @@ +cmake_minimum_required(VERSION 3.14) + +project(class_api) + +add_subdirectory(src) +add_subdirectory(libreria_LQL) + +find_package(SWIG REQUIRED) +include(${SWIG_USE_FILE}) + +set(NET_PROJECT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/wrappers/csharpwrapper") + +set(CMAKE_SWIG_FLAGS "") + +set_property(SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/wrappers/CLASS_SerialPort.i PROPERTY CPLUSPLUS ON) + +swig_add_library(CLASS_SerialPort + TYPE SHARED + LANGUAGE CSharp + SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/wrappers/CLASS_SerialPort.i + OUTPUT_DIR ${NET_PROJECT_DIR} + OUTFILE_DIR ${NET_PROJECT_DIR} + ) + swig_link_libraries(CLASS_SerialPort class_serial_port) + +set_target_properties(CLASS_SerialPort + PROPERTIES + RUNTIME_OUTPUT_DIRECTORY_RELEASE ${NET_PROJECT_DIR} + RUNTIME_OUTPUT_DIRECTORY_DEBUG ${NET_PROJECT_DIR} + LIBRARY_OUTPUT_DIRECTORY ${NET_PROJECT_DIR} + INCLUDE_DIRECTORIES ${CMAKE_CURRENT_SOURCE_DIR} + ) + +option(BUILD_DOC "Build documentation" ON) +message(STATUS "Build documentation: ${BUILD_DOC}") +if (BUILD_DOC) + add_subdirectory(docs) +endif() \ No newline at end of file diff --git a/serial_port_class_api/README.md b/serial_port_class_api/README.md new file mode 100644 index 0000000000000000000000000000000000000000..a3e4b9da741ca2f7a74a82528df872e9cf72a2f6 --- /dev/null +++ b/serial_port_class_api/README.md @@ -0,0 +1,7 @@ +# Project structure +Project is structured with the following folders: + * docs : documentation is automatically produced from comments by doxygen once a built is done, it will be found in docs/documentation/index.html. + * include : it contains header files for the API. + * src : contains API functions in CLASS_SerialPort.cpp and main.cpp file as example of how to use those funtions. + * wrappers : wrappers are automatically produced by swig. It generates files to be used in C# scripts. + diff --git a/serial_port_class_api/commands.h b/serial_port_class_api/commands.h new file mode 100644 index 0000000000000000000000000000000000000000..50328fce16e379ff96180d1e21ba3cb752d200fb --- /dev/null +++ b/serial_port_class_api/commands.h @@ -0,0 +1,139 @@ +/** + * @file commands.h + * @author Leire Querejeta Lomas <leire.querejeta@tecnalia.com> + * @brief headers for CLASS commands + * @date 2022-10-10 + * + * @copyright Copyright 2020 + * Tecnalia Research & Innovation. + * Distributed under the GNU GPL v3. + * For full terms see https://www.gnu.org/licenses/gpl.txt + */ +#pragma once +#include <string> + +namespace commands +{ + class ClassCommands + { + public: + + static std::string ClassCommands::CMD_ONSTIM; + static std::string ClassCommands::CMD_OFFSTIM; + static std::string ClassCommands::CMD_VELECSTIM; + + static std::string ClassCommands::CMD_GETTIC; + + static std::string ClassCommands::CMD_CONFIGVELEC; + static std::string ClassCommands::CMD_CONFIGVELEC_NAME; + static std::string ClassCommands::CMD_CONFIGVELEC_PADS; + static std::string ClassCommands::CMD_CONFIGVELEC_SELECTION; + static std::string ClassCommands::CMD_CONFIGVELEC_SYNCHRONOUS; + static std::string ClassCommands::CMD_CONFIGVELEC_CATHODE; + static std::string ClassCommands::CMD_CONFIGVELEC_ANODE; + static std::string ClassCommands::CMD_CONFIGVELEC_AMPLITUDE; + static std::string ClassCommands::CMD_CONFIGVELEC_PULSEWIDTH; + + static std::string ClassCommands::CMD_CONFIGPATTERN; + static std::string ClassCommands::CMD_CONFIGPATTERN_PARAM1; + static std::string ClassCommands::CMD_CONFIGPATTERN_PARAM2; + static std::string ClassCommands::CMD_CONFIGPATTERN_PARAM3; + + static std::string ClassCommands::CMD_GETHV; + static std::string ClassCommands::CMD_ONHV; + static std::string ClassCommands::CMD_OFFHV; + static std::string ClassCommands::CMD_SETHV; + + static std::string ClassCommands::CMD_SD_OPEN_DIRECTORY; + static std::string ClassCommands::CMD_SD_CHANGE_DIRECTORY; + static std::string ClassCommands::CMD_SD_PRINT_DIRECTORY; + static std::string ClassCommands::CMD_SD_DELETE_FILE; + static std::string ClassCommands::CMD_SD_CREATE_FILE; + static std::string ClassCommands::CMD_SD_EDIT_FILE; + static std::string ClassCommands::CMD_SD_CREATE_DIRECTORY; + static std::string ClassCommands::CMD_SD_RENAME_FILE; + static std::string ClassCommands::CMD_SD_SAVE_BOOT; + + static std::string ClassCommands::CMD_GETPROTOTYPE; + static std::string ClassCommands::CMD_SET_FES_PROTOTYPE; + static std::string ClassCommands::CMD_SET_TACTILITY_PROTOTYPE; + + static std::string ClassCommands::CMD_GETDEVICENAME; + static std::string ClassCommands::CMD_SETDEVICENAME; + + static std::string ClassCommands::CMD_GETFW; + + static std::string ClassCommands::CMD_GETHW; + + static std::string ClassCommands::CMD_GETSDFUNCTION; + static std::string ClassCommands::CMD_SETSDFUNCTION; + + static std::string ClassCommands::CMD_GETFRQUENCY; + static std::string ClassCommands::CMD_SETFREQ; + + static std::string ClassCommands::CMD_GETLOGEVENTS; + static std::string ClassCommands::CMD_ONLOGEVENTS; + static std::string ClassCommands::CMD_OFFLOGEVENTS; + + static std::string ClassCommands::CMD_GETSDNAME; + static std::string ClassCommands::CMD_SETSDNAME; + + static std::string ClassCommands::CMD_GETINTERVAL; + static std::string ClassCommands::CMD_SETINTERVAL; + + static std::string ClassCommands::CMD_GETBATTERY; + + static std::string ClassCommands::CMD_GETPULSE_VOLTAGES; + static std::string ClassCommands::CMD_GETPULSE_INTENSITIES; + static std::string ClassCommands::CMD_GETPULSE_NEGATIVEVOLTAGES; + static std::string ClassCommands::CMD_GETPULSE_POSITIVEVOLTAGES; + static std::string ClassCommands::CMD_GETPULSE_AVERAGEINTENSITY; + + static std::string ClassCommands::CMD_ONACQ; + static std::string ClassCommands::CMD_OFFACQ; + static std::string ClassCommands::CMD_NORMALACQ; + static std::string ClassCommands::CMD_TESTACQ; + static std::string ClassCommands::CMD_STREAMONACQ; + static std::string ClassCommands::CMD_STREAMOFFACQ; + static std::string ClassCommands::CMD_ONIMPEDANCEACQ; + static std::string ClassCommands::CMD_OFFIMPEDANCEACQ; + static std::string ClassCommands::CMD_CONFIGACQ; + static std::string ClassCommands::CMD_CONFIGACQ_CHANNELS; + static std::string ClassCommands::CMD_CONFIGACQ_FREQUENCY; + static std::string ClassCommands::CMD_CONFIGACQ_GAIN; + static std::string ClassCommands::CMD_CONFIGACQ_INPUT; + static std::string ClassCommands::CMD_CONFIGACQ_TYPE; + static std::string ClassCommands::CMD_CONFIGACQ_IMPEDANCEPOSITIVE; + static std::string ClassCommands::CMD_CONFIGACQ_IMPEDANCENEGATIVE; + static std::string ClassCommands::CMD_CONFIGACQ_LEADOFF_ON; + static std::string ClassCommands::CMD_CONFIGACQ_LEADOFF_OFF; + static std::string ClassCommands::CMD_CONFIGACQ_SETLEADOFF; + + static std::string ClassCommands::CMD_GETSTIMTIME; + + static std::string ClassCommands::CMD_GETBUZZER; + static std::string ClassCommands::CMD_SETBUZZER; + static std::string ClassCommands::CMD_PLAYBUZZER; + + static std::string ClassCommands::CMD_STARTFES; + static std::string ClassCommands::CMD_STARTTACTILITY; + static std::string ClassCommands::CMD_STARTCOMMUNICATION; + + static std::string ClassCommands::CMD_GETLOGERRORS; + static std::string ClassCommands::CMD_OPENLOGERRORS; + static std::string ClassCommands::CMD_CLOSELOGERRORS; + + static std::string ClassCommands::CMD_SWITCHOFF; + + static std::string ClassCommands::CMD_GETRTC; + static std::string ClassCommands::CMD_SETRTCDATE; + static std::string ClassCommands::CMD_SETRTCTIME; + + static std::string ClassCommands::CMD_PING; + static std::string ClassCommands::CMD_HELP; + + static std::string ClassCommands::CMD_AUX; + static std::string ClassCommands::CMD_AUX2; + + }; +} \ No newline at end of file diff --git a/serial_port_class_api/commands.lib b/serial_port_class_api/commands.lib new file mode 100644 index 0000000000000000000000000000000000000000..a6758c2e9955a79315c30a56aab910468d86289e Binary files /dev/null and b/serial_port_class_api/commands.lib differ diff --git a/src/docs/CMakeLists.txt b/serial_port_class_api/docs/CMakeLists.txt similarity index 59% rename from src/docs/CMakeLists.txt rename to serial_port_class_api/docs/CMakeLists.txt index b728f447d2c4fd4cb7c17777db549022f627fd36..db1964b005a63e617a1f11298bf4b4911968b52f 100644 --- a/src/docs/CMakeLists.txt +++ b/serial_port_class_api/docs/CMakeLists.txt @@ -1,19 +1,15 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 3.14) -project (doc) +cmake_minimum_required(VERSION 3.14) +project (documentation) -# check if Doxygen is installed find_package(Doxygen) if (DOXYGEN_FOUND) - # set input and output files set(DOXYGEN_IN ${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in) set(DOXYGEN_OUT ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile) - # request to configure the file configure_file(${DOXYGEN_IN} ${DOXYGEN_OUT} @ONLY) message("Doxygen build started") - # note the option ALL which allows to build the docs together with the application add_custom_target( doc_doxygen ALL COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYGEN_OUT} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} @@ -23,6 +19,4 @@ else (DOXYGEN_FOUND) message("Doxygen need to be installed to generate the doxygen documentation") endif (DOXYGEN_FOUND) -install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/doc_doxygen/html/ DESTINATION class_api/docs) -install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/README.html DESTINATION class_api) diff --git a/serial_port_class_api/docs/Doxyfile.in b/serial_port_class_api/docs/Doxyfile.in new file mode 100644 index 0000000000000000000000000000000000000000..c1f33e43c52f5aa25794497a9d6d0b558b173232 --- /dev/null +++ b/serial_port_class_api/docs/Doxyfile.in @@ -0,0 +1,6 @@ + +OUTPUT_DIRECTORY = @CMAKE_CURRENT_SOURCE_DIR@/documentation/ +INPUT = @CMAKE_CURRENT_SOURCE_DIR@/../include/CLASS_SerialPort.h +INPUT += @CMAKE_CURRENT_SOURCE_DIR@/../src/CLASS_SerialPort.cpp +GENERATE_LATEX = NO +PROJECT_NAME = "CLASS API" diff --git a/serial_port_class_api/include/CLASS_SerialPort.h b/serial_port_class_api/include/CLASS_SerialPort.h new file mode 100644 index 0000000000000000000000000000000000000000..62425f585d9acc89125b2ce74381aef1a2820897 --- /dev/null +++ b/serial_port_class_api/include/CLASS_SerialPort.h @@ -0,0 +1,193 @@ +/** + * @file CLASS_SerialPort.h + * @author Leire Querejeta Lomas <leire.querejeta@tecnalia.com> + * @brief headers for serial connection and CLASS commands + * @date 2022-10-10 + * + * @copyright Copyright 2020 + * Tecnalia Research & Innovation. + * Distributed under the GNU GPL v3. + * For full terms see https://www.gnu.org/licenses/gpl.txt + */ + +#ifndef __CLASS_SerialPort_H__ +#define __CLASS_SerialPort_H__ + +#include <string> +#include <windows.h> +#include <vector> +#include "CLASS_structures.hpp" + +#define BUFFER_SIZE 2000 // read maximum buffer size +#define FLUSH_BUFFSIZE 10 // flush buffer size + +class CLASS_SerialPort // CLASS serial port control +{ + +private: + HANDLE hCom; // handle to the Serial port + bool status; // setopen result + DCB dcb; // control settings for serial port + COMMTIMEOUTS timeouts; // time-out parameters for a communication device + + std::string devicePrototype; // type of prototype : FES, TACTILITY, PAIN ... + + std::string ERROR_NOT_VALID_VALUE = "ERROR out of range input value"; + int MAX_ALLOWED_VIRTUAL_ELECTRODES = 16; // allowed number of virtual electrodes + int MAX_CHAR_VIRTUAL_ELECTRODE_NAME = 16; // maximun number of characters for virtual electrode name + int MAX_VIRTUAL_ELECTRODE_PADS = 48; // allowed maximum number of pads per virtual electrode + double MAX_VIRTUAL_ELECTRODE_AMPLITUDE_FES = 92; // allowed maximum stimulation amplitude value for FES prototypes + double MAX_VIRTUAL_ELECTRODE_AMPLITUDE_TACTILITY = 9; // allowed maximum stimulation amplitude value for TACTILITY/PAIN prototypes + double MIN_VIRTUAL_ELECTRODE_AMPLITUDE = 0.1; // allowed minimum stimulation amplitude value + int MAX_VIRTUAL_ELECTRODE_PULSE_WIDTH = 4000; // allowed maximum stimulation pulse width + int MIN_VIRTUAL_ELECTRODE_PULSE_WIDTH = 30; // allowed minimum stimulation pulse width + int MAX_ALLOWED_PATTERNS = 16; // allowed number of patterns + int MAX_HIGH_VOLTAGE = 200; // allowed maximum high voltage value + int MIN_HIGH_VOLTAGE = 120; // allowed minimum high voltage value + int MAX_CHAR_DEVICENAME = 25; // maximun number of characters for device name + int MAX_CHAR_FUNCTIONNAME = 15; // maximun number of characters for sd pattern folder name + int MAX_FREQUENCY = 2000; // allowed maximum frequency value + int MIN_FREQUENCY = 0; // allowed minimum frequency value + int MAX_PULSE_INTERVAL = 1000; // allowed maximum inter pulses interval + int MIN_PULSE_INTERVAL = 250; // allowed minimum inter pulses interval + int MAX_CHAR_USERNAME = 15; // maximun number of characters for sd user folder + int ACQUISITION_ALLOWED_FREQUENCY1 = 250; // allowed acquisition frequency value + int ACQUISITION_ALLOWED_FREQUENCY2 = 500; // allowed acquisition frequency value + int ACQUISITION_ALLOWED_FREQUENCY3 = 1000; // allowed acquisition frequency value + int ACQUISITION_ALLOWED_FREQUENCY4 = 2000; // allowed acquisition frequency value + int ACQUISITION_ALLOWED_FREQUENCY5 = 4000; // allowed acquisition frequency value + std::string ACQUISITION_ALLOWED_TYPE1 = "bipolar"; // allowed acquisition frequency value + std::string ACQUISITION_ALLOWED_TYPE2 = "unipolar"; // allowed acquisition frequency value + int ACQUISITION_ALLOWED_GAIN1 = 1; // allowed acquisition gain value + int ACQUISITION_ALLOWED_GAIN2 = 2; // allowed acquisition gain value + int ACQUISITION_ALLOWED_GAIN3 = 4; // allowed acquisition gain value + int ACQUISITION_ALLOWED_GAIN4 = 8; // allowed acquisition gain value + int ACQUISITION_ALLOWED_GAIN5 = 12; // allowed acquisition gain value + int ACQUISITION_ALLOWED_GAIN6 = 24; // allowed acquisition gain value + std::string ACQUISITION_ALLOWED_CURRENT1 = "6nA"; // allowed acquisition leadoff current value + std::string ACQUISITION_ALLOWED_CURRENT2 = "24nA"; // allowed acquisition leadoff current value + std::string ACQUISITION_ALLOWED_CURRENT3 = "6uA"; // allowed acquisition leadoff current value + std::string ACQUISITION_ALLOWED_CURRENT4 = "24uA"; // allowed acquisition leadoff current value + int BUZZER_MAX_TEMPO_ms = 500; // allowed maximum number of miliseconds for buzzer duration + int BUZZER_MIN_TEMPO_ms = 25; // allowed minimum number of miliseconds for buzzer duration + +public: + + CLASS_SerialPort(); //constructor + ~CLASS_SerialPort(); //constructor + bool SetOpenPort(std::string &commPortName); //serial port settings + bool write(const char buffer[]); //write + void flush(); //flush serial port read buffer + int flushread(char *buffer, int buffLen); //auxiliar function for flush serial port + std::string read(); //read + std::string communication(const char buffer[]); //write/read + void CloseSerialPort(); //serial port close + + + std::string setStimulationOn(); + std::string setStimulationOff(); + std::string setStimulationVirtualElectrode(std::string &virtualElectrodeName); + + std::string getTic(); + + std::string getVirtualElectrode(std::string &virtualElectrodeNumber); + std::string setVirtualElectrodeOld(std::string &virtualElectrodeNumber, std::string &virtualElectrodeName, std::vector<int> cathodes, std::vector<int> anodes , std::vector<double> amplitudes, std::vector<int> pulsewiths, bool selected , bool sync); + std::string setVirtualElectrode(std::string &virtualElectrodeNumber, std::string virtualElectrodeName = "", std::vector<int> cathodes = {0}, std::vector<int> anodes = {0}, std::vector<CathodeAmplitude> amplitudes = {{"0",0.0}}, std::vector<CathodeWidth> pulsewiths = {{"0",0}}, std::string selected = "", std::string sync = ""); + std::string setVirtualElectrodeSelection(std::string &virtualElectrodeNumber, bool selection); + + std::string getPattern(std::string &patternNumber); + std::string clearPattern(std::string &patternNumber); + std::string setPattern(std::string &patternNumber,std::vector<Pattern> &patternsValues); + + std::string getHighVoltage(); + std::string setHighVoltageOn(); + std::string setHighVoltageOff(); + std::string setHighVoltageValue(std::string &highVoltageValue); + + std::string SDls(); + std::string SDcd(std::string &directoryName); + std::string SDpwd(); + std::string SDrm(std::string &fileName); + std::string SDcat(std::string &fileName); + std::string SDed(std::string &filePathName, std::string &text); + std::string SDmkdir(std::string &directoryName); + std::string SDrename(std::string &oldFileName, std::string &newFileName); + std::string SDsaveboot(); + + std::string getApplication(); + std::string setFESApplication(); + std::string setTACTILITYApplication(); + + std::string getDeviceName(); + std::string setDeviceName(std::string &deviceName); + + std::string getFirmware(); + + std::string getHardware(); + + std::string getSDPartternsFolder(); + std::string setSDPartternsFolder(std::string &sdPattern); + + std::string getFrequency(); + std::string setFrequency(std::string &frequency); + + std::string getPulsesInterval(); + std::string setPulsesInterval(std::string &interval); + + std::string getLogevents(); + std::string setLogeventsOn(); + std::string setLogeventsOff(); + + std::string getSDUserFolder(); + std::string setSDUserFolder(std::string &sdFolder); + + std::string getBattery(); + + std::string getPulseVoltages(); + std::string getPulseIntensities(); + std::string getPulseNegativeVoltages(); + std::string getPulsePositiveVoltages(); + std::string getPulseAverageIntensity(); + + std::string setAcquisitionOn(); + std::string setAcquisitionOff(); + std::string setAcquisitionConfiguratonOld(std::vector<int> &channels, int frequency, std::string type, int gain); + std::string setAcquisitionConfiguraton(std::vector<int> &channels, int frequency = 0, std::string type = "", int gain = 0); + std::string setAcquisitionTest(); + std::string setAcquisitionNormal(); + std::string setAcquisitionStreamOn(); + std::string setAcquisitionStreamOff(); + std::string setAcquisitionImpedanceOn(); + std::string setAcquisitionImpedanceOff(); + std::string setAcquisitionImpedanceChannelsPositive(); + std::string setAcquisitionImpedanceChannelsNegative(); + std::string setAcquisitionLeadoffOn(); + std::string setAcquisitionLeadoffOff(); + std::string setAcquisitionLeadoffConfiguration(std::string ¤t); + + std::string getStimulationTime(); + + std::string getBuzzerTempo(); + std::string setBuzzerTempo(std::string &buzzerTempo); + std::string playBuzzer(); + + std::string startFESCommunication(); + std::string startTACTILITYCommunication(); + std::string startCommunication(std::string &prototipeName); + + std::string showLogErrors(); + std::string createLogFile(); + std::string closeLogFile(); + + std::string shutDown(); + + std::string getRTC(); + std::string setRTCDate(std::string &rtcDate); + std::string setRTCTime(std::string &rtcTime); + + std::string ping(); + + std::string getHelp(); +}; + +#endif \ No newline at end of file diff --git a/serial_port_class_api/include/CLASS_structures.hpp b/serial_port_class_api/include/CLASS_structures.hpp new file mode 100644 index 0000000000000000000000000000000000000000..fd15c7d5ad470b222b0b3f3731176410ed2f8a01 --- /dev/null +++ b/serial_port_class_api/include/CLASS_structures.hpp @@ -0,0 +1,38 @@ +/** + * @file CLASS_structures.h + * @author Leire Querejeta Lomas <leire.querejeta@tecnalia.com> + * @brief structures needed for API + * @date 2022-10-10 + * + * @copyright Copyright 2020 + * Tecnalia Research & Innovation. + * Distributed under the GNU GPL v3. + * For full terms see https://www.gnu.org/licenses/gpl.txt + */ +#pragma once +#include <vector> + +//! Structure for pattern +struct Pattern +{ + std::string amp; + std::string pw; + std::string r; + int ampval; + int pwval; + int time; +}; + +//! Structure for virtual eletrode cathode amplitude configuration +struct CathodeAmplitude +{ + std::string cathodenumber; + double amplitude; +}; + +//! Structure for virtual eletrode cathode width configuration +struct CathodeWidth +{ + std::string cathodenumber; + int width; +}; \ No newline at end of file diff --git a/serial_port_class_api/libreria_LQL/CMakeLists.txt b/serial_port_class_api/libreria_LQL/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..c003702320d22581c6e87ac4dd9ddc22e6568ec6 --- /dev/null +++ b/serial_port_class_api/libreria_LQL/CMakeLists.txt @@ -0,0 +1,8 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) +project (api) + +#set(commands_files +# ${CMAKE_CURRENT_SOURCE_DIR}/commands.cpp +# ${CMAKE_CURRENT_SOURCE_DIR}/commands.h +#) +#add_library(commands STATIC ${commands_files}) \ No newline at end of file diff --git a/serial_port_class_api/libreria_LQL/commands.cpp b/serial_port_class_api/libreria_LQL/commands.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3864457824ab03ed06eef5318d1b5d63ff1c5985 --- /dev/null +++ b/serial_port_class_api/libreria_LQL/commands.cpp @@ -0,0 +1,134 @@ +/** + * @file commands.cpp + * @author Leire Querejeta Lomas <leire.querejeta@tecnalia.com> + * @brief CLASS commands DANGER this file should be hide for Open API + * @date 2022-10-10 + * + * @copyright Copyright 2020 + * Tecnalia Research & Innovation. + * Distributed under the GNU GPL v3. + * For full terms see https://www.gnu.org/licenses/gpl.txt + */ +#include "commands.h" +#define getName(var) #var + +namespace commands +{ + std::string ClassCommands::CMD_ONSTIM = "stim on\r\n"; + std::string ClassCommands::CMD_OFFSTIM = "stim off\r\n"; + std::string ClassCommands::CMD_VELECSTIM = "stim "; + + std::string ClassCommands::CMD_GETTIC = "tic\r\n"; + + std::string ClassCommands::CMD_CONFIGVELEC = "velec "; + std::string ClassCommands::CMD_CONFIGVELEC_NAME = " *name "; + std::string ClassCommands::CMD_CONFIGVELEC_PADS = " *pads "; + std::string ClassCommands::CMD_CONFIGVELEC_SELECTION = " *selected "; + std::string ClassCommands::CMD_CONFIGVELEC_SYNCHRONOUS = " *sync "; + std::string ClassCommands::CMD_CONFIGVELEC_CATHODE = "=C,"; + std::string ClassCommands::CMD_CONFIGVELEC_ANODE = "=A,"; + std::string ClassCommands::CMD_CONFIGVELEC_AMPLITUDE = " *amp "; + std::string ClassCommands::CMD_CONFIGVELEC_PULSEWIDTH = " *width "; + + std::string ClassCommands::CMD_CONFIGPATTERN = "pattern "; + std::string ClassCommands::CMD_CONFIGPATTERN_PARAM1 = " clear"; + std::string ClassCommands::CMD_CONFIGPATTERN_PARAM2 = " *newline "; + std::string ClassCommands::CMD_CONFIGPATTERN_PARAM3 = " register"; + + std::string ClassCommands::CMD_GETHV = "hv ?\r\n"; + std::string ClassCommands::CMD_ONHV = "hv on\r\n"; + std::string ClassCommands::CMD_OFFHV = "hv off\r\n"; + std::string ClassCommands::CMD_SETHV = "hv "; + + std::string ClassCommands::CMD_SD_OPEN_DIRECTORY = "sdcard ls\r\n"; + std::string ClassCommands::CMD_SD_CHANGE_DIRECTORY = "sdcard cd "; + std::string ClassCommands::CMD_SD_PRINT_DIRECTORY = "sdcard pwd\r\n"; + std::string ClassCommands::CMD_SD_DELETE_FILE = "sdcard rm "; + std::string ClassCommands::CMD_SD_CREATE_FILE = "sdcard cat > "; + std::string ClassCommands::CMD_SD_EDIT_FILE = "sdcard ed "; + std::string ClassCommands::CMD_SD_CREATE_DIRECTORY = "sdcard mkdir "; + std::string ClassCommands::CMD_SD_RENAME_FILE = "sdcard rename "; + std::string ClassCommands::CMD_SD_SAVE_BOOT = "sdcard save boot\r\n"; + + std::string ClassCommands::CMD_GETPROTOTYPE = "application ?\r\n"; + std::string ClassCommands::CMD_SET_FES_PROTOTYPE = "application FES\r\n"; + std::string ClassCommands::CMD_SET_TACTILITY_PROTOTYPE = "application TACTILITY\r\n"; + + std::string ClassCommands::CMD_GETDEVICENAME = "device ?\r\n"; + std::string ClassCommands::CMD_SETDEVICENAME = "device "; + + std::string ClassCommands::CMD_GETFW = "firmware ?\r\n"; + + std::string ClassCommands::CMD_GETHW = "hardware ?\r\n"; + + std::string ClassCommands::CMD_GETSDFUNCTION = "function ?\r\n"; + std::string ClassCommands::CMD_SETSDFUNCTION = "function "; + + + std::string ClassCommands::CMD_GETFRQUENCY = "frequency ?\r\n"; + std::string ClassCommands::CMD_SETFREQ = "frequency "; + + std::string ClassCommands::CMD_GETLOGEVENTS = "logevents ?\r\n"; + std::string ClassCommands::CMD_ONLOGEVENTS = "logevents on\r\n"; + std::string ClassCommands::CMD_OFFLOGEVENTS = "logevents off\r\n"; + + std::string ClassCommands::CMD_GETSDNAME = "uname ?\r\n"; + std::string ClassCommands::CMD_SETSDNAME = "uname "; + + std::string ClassCommands::CMD_GETINTERVAL = "interval ?\r\n"; + std::string ClassCommands::CMD_SETINTERVAL = "interval "; + + std::string ClassCommands::CMD_GETBATTERY = "battery ?\r\n"; + + std::string ClassCommands::CMD_GETPULSE_VOLTAGES = "pulse *vpulse ?\r\n"; + std::string ClassCommands::CMD_GETPULSE_INTENSITIES = "pulse *ipulse ?\r\n"; + std::string ClassCommands::CMD_GETPULSE_NEGATIVEVOLTAGES = "pulse *lowside ?\r\n"; + std::string ClassCommands::CMD_GETPULSE_POSITIVEVOLTAGES = "pulse *highside ?\r\n"; + std::string ClassCommands::CMD_GETPULSE_AVERAGEINTENSITY = "pulse *iavg ?\r\n"; + + std::string ClassCommands::CMD_ONACQ = "acq on\r\n"; + std::string ClassCommands::CMD_OFFACQ = "acq off\r\n"; + std::string ClassCommands::CMD_NORMALACQ = "acq config *input normal\r\n"; + std::string ClassCommands::CMD_TESTACQ = "acq config *input test\r\n"; + std::string ClassCommands::CMD_STREAMONACQ = "acq stream on\r\n"; + std::string ClassCommands::CMD_STREAMOFFACQ = "acq stream off\r\n"; + std::string ClassCommands::CMD_ONIMPEDANCEACQ = "acq impedance on\r\n"; + std::string ClassCommands::CMD_OFFIMPEDANCEACQ = "acq impedance off\r\n"; + std::string ClassCommands::CMD_CONFIGACQ = "acq config"; + std::string ClassCommands::CMD_CONFIGACQ_CHANNELS = " *channels "; + std::string ClassCommands::CMD_CONFIGACQ_FREQUENCY = " *freq "; + std::string ClassCommands::CMD_CONFIGACQ_GAIN = " *gain "; + std::string ClassCommands::CMD_CONFIGACQ_INPUT = " *input "; + std::string ClassCommands::CMD_CONFIGACQ_TYPE = " *type "; + std::string ClassCommands::CMD_CONFIGACQ_IMPEDANCEPOSITIVE = "acq impedance_config *channels positives\r\n"; + std::string ClassCommands::CMD_CONFIGACQ_IMPEDANCENEGATIVE = "acq impedance_config *channels negatives\r\n"; + std::string ClassCommands::CMD_CONFIGACQ_LEADOFF_ON = "acq leadoff on\r\n"; + std::string ClassCommands::CMD_CONFIGACQ_LEADOFF_OFF = "acq leadoff off\r\n"; + std::string ClassCommands::CMD_CONFIGACQ_SETLEADOFF = "acq leadoff_config *current "; + + std::string ClassCommands::CMD_GETSTIMTIME = "time ?\r\n"; + + std::string ClassCommands::CMD_GETBUZZER = "buzzer *tempo ?\r\n"; + std::string ClassCommands::CMD_SETBUZZER = "buzzer *tempo "; + std::string ClassCommands::CMD_PLAYBUZZER = "buzzer *play \r\n"; + + std::string ClassCommands::CMD_STARTFES = "iam DESKTOP\r\n"; + std::string ClassCommands::CMD_STARTTACTILITY = "iam TACTILITY\r\n"; + std::string ClassCommands::CMD_STARTCOMMUNICATION = "iam "; + + std::string ClassCommands::CMD_GETLOGERRORS = "log errors ?\r\n"; + std::string ClassCommands::CMD_OPENLOGERRORS = "log open\r\n"; + std::string ClassCommands::CMD_CLOSELOGERRORS = "log close\r\n"; + + std::string ClassCommands::CMD_SWITCHOFF = "shutdown\r\n"; + + std::string ClassCommands::CMD_GETRTC = "rtc ?\r\n"; + std::string ClassCommands::CMD_SETRTCDATE = "rtc *date "; + std::string ClassCommands::CMD_SETRTCTIME = "rtc *time "; + + std::string ClassCommands::CMD_PING = "ping\r\n"; + std::string ClassCommands::CMD_HELP = "help\r\n"; + + std::string ClassCommands::CMD_AUX = " \r\n"; + std::string ClassCommands::CMD_AUX2 = " ?"; +} \ No newline at end of file diff --git a/serial_port_class_api/libreria_LQL/commands.h b/serial_port_class_api/libreria_LQL/commands.h new file mode 100644 index 0000000000000000000000000000000000000000..0bdaaf5838533033d09a08ed9fb467f43e8c212c --- /dev/null +++ b/serial_port_class_api/libreria_LQL/commands.h @@ -0,0 +1,138 @@ +/** + * @file commands.h + * @author Leire Querejeta Lomas <leire.querejeta@tecnalia.com> + * @brief headers for CLASS commands + * @date 2022-10-10 + * + * @copyright Copyright 2020 + * Tecnalia Research & Innovation. + * Distributed under the GNU GPL v3. + * For full terms see https://www.gnu.org/licenses/gpl.txt + */ +#pragma once +#include <string> + +namespace commands +{ + class ClassCommands + { + public: + + static std::string ClassCommands::CMD_ONSTIM; + static std::string ClassCommands::CMD_OFFSTIM; + static std::string ClassCommands::CMD_VELECSTIM; + + static std::string ClassCommands::CMD_GETTIC; + + static std::string ClassCommands::CMD_CONFIGVELEC; + static std::string ClassCommands::CMD_CONFIGVELEC_NAME; + static std::string ClassCommands::CMD_CONFIGVELEC_PADS; + static std::string ClassCommands::CMD_CONFIGVELEC_SELECTION; + static std::string ClassCommands::CMD_CONFIGVELEC_SYNCHRONOUS; + static std::string ClassCommands::CMD_CONFIGVELEC_CATHODE; + static std::string ClassCommands::CMD_CONFIGVELEC_ANODE; + static std::string ClassCommands::CMD_CONFIGVELEC_AMPLITUDE; + static std::string ClassCommands::CMD_CONFIGVELEC_PULSEWIDTH; + + static std::string ClassCommands::CMD_CONFIGPATTERN; + static std::string ClassCommands::CMD_CONFIGPATTERN_PARAM1; + static std::string ClassCommands::CMD_CONFIGPATTERN_PARAM2; + static std::string ClassCommands::CMD_CONFIGPATTERN_PARAM3; + + static std::string ClassCommands::CMD_GETHV; + static std::string ClassCommands::CMD_ONHV; + static std::string ClassCommands::CMD_OFFHV; + static std::string ClassCommands::CMD_SETHV; + + static std::string ClassCommands::CMD_SD_OPEN_DIRECTORY; + static std::string ClassCommands::CMD_SD_CHANGE_DIRECTORY; + static std::string ClassCommands::CMD_SD_PRINT_DIRECTORY; + static std::string ClassCommands::CMD_SD_DELETE_FILE; + static std::string ClassCommands::CMD_SD_CREATE_FILE; + static std::string ClassCommands::CMD_SD_EDIT_FILE; + static std::string ClassCommands::CMD_SD_CREATE_DIRECTORY; + static std::string ClassCommands::CMD_SD_RENAME_FILE; + static std::string ClassCommands::CMD_SD_SAVE_BOOT; + + static std::string ClassCommands::CMD_GETPROTOTYPE; + static std::string ClassCommands::CMD_SET_FES_PROTOTYPE; + static std::string ClassCommands::CMD_SET_TACTILITY_PROTOTYPE; + + static std::string ClassCommands::CMD_GETDEVICENAME; + static std::string ClassCommands::CMD_SETDEVICENAME; + + static std::string ClassCommands::CMD_GETFW; + + static std::string ClassCommands::CMD_GETHW; + + static std::string ClassCommands::CMD_GETSDFUNCTION; + static std::string ClassCommands::CMD_SETSDFUNCTION; + + static std::string ClassCommands::CMD_GETFRQUENCY; + static std::string ClassCommands::CMD_SETFREQ; + + static std::string ClassCommands::CMD_GETLOGEVENTS; + static std::string ClassCommands::CMD_ONLOGEVENTS; + static std::string ClassCommands::CMD_OFFLOGEVENTS; + + static std::string ClassCommands::CMD_GETSDNAME; + static std::string ClassCommands::CMD_SETSDNAME; + + static std::string ClassCommands::CMD_GETINTERVAL; + static std::string ClassCommands::CMD_SETINTERVAL; + + static std::string ClassCommands::CMD_GETBATTERY; + + static std::string ClassCommands::CMD_GETPULSE_VOLTAGES; + static std::string ClassCommands::CMD_GETPULSE_INTENSITIES; + static std::string ClassCommands::CMD_GETPULSE_NEGATIVEVOLTAGES; + static std::string ClassCommands::CMD_GETPULSE_POSITIVEVOLTAGES; + static std::string ClassCommands::CMD_GETPULSE_AVERAGEINTENSITY; + + static std::string ClassCommands::CMD_ONACQ; + static std::string ClassCommands::CMD_OFFACQ; + static std::string ClassCommands::CMD_NORMALACQ; + static std::string ClassCommands::CMD_TESTACQ; + static std::string ClassCommands::CMD_STREAMONACQ; + static std::string ClassCommands::CMD_STREAMOFFACQ; + static std::string ClassCommands::CMD_ONIMPEDANCEACQ; + static std::string ClassCommands::CMD_OFFIMPEDANCEACQ; + static std::string ClassCommands::CMD_CONFIGACQ; + static std::string ClassCommands::CMD_CONFIGACQ_CHANNELS; + static std::string ClassCommands::CMD_CONFIGACQ_FREQUENCY; + static std::string ClassCommands::CMD_CONFIGACQ_GAIN; + static std::string ClassCommands::CMD_CONFIGACQ_INPUT; + static std::string ClassCommands::CMD_CONFIGACQ_TYPE; + static std::string ClassCommands::CMD_CONFIGACQ_IMPEDANCEPOSITIVE; + static std::string ClassCommands::CMD_CONFIGACQ_IMPEDANCENEGATIVE; + static std::string ClassCommands::CMD_CONFIGACQ_LEADOFF_ON; + static std::string ClassCommands::CMD_CONFIGACQ_LEADOFF_OFF; + static std::string ClassCommands::CMD_CONFIGACQ_SETLEADOFF; + + static std::string ClassCommands::CMD_GETSTIMTIME; + + static std::string ClassCommands::CMD_GETBUZZER; + static std::string ClassCommands::CMD_SETBUZZER; + static std::string ClassCommands::CMD_PLAYBUZZER; + + static std::string ClassCommands::CMD_STARTFES; + static std::string ClassCommands::CMD_STARTTACTILITY; + static std::string ClassCommands::CMD_STARTCOMMUNICATION; + + static std::string ClassCommands::CMD_GETLOGERRORS; + static std::string ClassCommands::CMD_OPENLOGERRORS; + static std::string ClassCommands::CMD_CLOSELOGERRORS; + + static std::string ClassCommands::CMD_SWITCHOFF; + + static std::string ClassCommands::CMD_GETRTC; + static std::string ClassCommands::CMD_SETRTCDATE; + static std::string ClassCommands::CMD_SETRTCTIME; + + static std::string ClassCommands::CMD_PING; + static std::string ClassCommands::CMD_HELP; + + static std::string ClassCommands::CMD_AUX; + static std::string ClassCommands::CMD_AUX2; + }; +} \ No newline at end of file diff --git a/serial_port_class_api/src/CLASS_SerialPort.cpp b/serial_port_class_api/src/CLASS_SerialPort.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8f8c8a29a26e96c41611ca0c3ebd5e26a0a60b07 --- /dev/null +++ b/serial_port_class_api/src/CLASS_SerialPort.cpp @@ -0,0 +1,1508 @@ +/** + * @file CLASS_SerialPort.cpp + * @author Leire Querejeta Lomas <leire.querejeta@tecnalia.com> + * @brief API -> serial connection and CLASS commands + * @date 2022-10-10 + * + * @copyright Copyright 2020 + * Tecnalia Research & Innovation. + * Distributed under the GNU GPL v3. + * For full terms see https://www.gnu.org/licenses/gpl.txt + */ +#include <iostream> +#include "../include/CLASS_SerialPort.h" +#include <algorithm> +#include <sstream> +#include <iomanip> +#include "../commands.h" +#include <vector> + +/** + * @brief construct a new class serialport::class serialport object + * + */ +CLASS_SerialPort::CLASS_SerialPort(){} +/** + * @brief destroy the class serialport::class serialport object and close seial port + * + */ +CLASS_SerialPort::~CLASS_SerialPort() +{ + CloseHandle(hCom); +} +/** + * @brief configure parameters and open serial port for the proper communication of the CLASS device + * + * @param commPortName name of port (ex: COM1) + * @return true serial port correct set and open + * @return false error during serial port open precess + */ +bool CLASS_SerialPort::SetOpenPort(std::string &commPortName) +{ + hCom = CreateFile(commPortName.c_str(), // port + GENERIC_READ|GENERIC_WRITE, // read/write access + 0, // must be opened with exclusive-access + NULL, // default security attributes + OPEN_EXISTING, // must use OPEN_EXISTING + 0, // not overlapped I/O + NULL); // must be NULL for comm devices + + if(hCom == INVALID_HANDLE_VALUE) + { + status = 0; + return status; + } + + //Set paremeters for the serial commutication device + memset(&dcb,0,sizeof(dcb)); + dcb.DCBlength = sizeof(dcb); //length + dcb.BaudRate = CBR_115200; //baud rate + dcb.ByteSize = 8; //data size + dcb.StopBits = ONESTOPBIT; //stop bit + dcb.Parity = NOPARITY; //parity bit + + if(!SetCommState(hCom,&dcb)) + { + CLASS_SerialPort::~CLASS_SerialPort(); + status = 0; + return status; + } + + //Set time-out parameter for a communication device (ms) + timeouts.ReadIntervalTimeout = MAXDWORD; //time allowed to elapse before the arrival of the next byte + timeouts.ReadTotalTimeoutMultiplier = 0; //multiplier used to calculate the total time-out period for read operations + timeouts.ReadTotalTimeoutConstant = 0; //a constant used to calculate the total time-out period for read operations + timeouts.WriteTotalTimeoutConstant = 0; //multiplier used to calculate the total time-out period for write operations + timeouts.WriteTotalTimeoutMultiplier = 0; //a constant used to calculate the total time-out period for write operations + + if(!SetCommTimeouts(hCom,&timeouts)) + { + CLASS_SerialPort::~CLASS_SerialPort(); + status = 0; + return status; + } + + status = 1; + return status; +} + +/** + * @brief writers command to CLASS device through serial port + * + * @param buffer command to send + * @return true write to serial port done + * @return false error during writting process + */ +bool CLASS_SerialPort::write(const char *buffer) +{ + DWORD numWritten; + WriteFile(hCom, buffer, strlen(buffer), &numWritten, NULL); + if(numWritten < strlen(buffer)) + return 0; + else + return 1; +} + +/** + * @brief auxiliar function to flush read serial port + * + * @param buffer buffer to read + * @param buffLen number of bytes to read FLUSH_BUFFSIZE + * @return int bytes readed + */ +int CLASS_SerialPort::flushread(char *buffer, int buffLen) +{ + DWORD numRead; + BOOL ret = ReadFile(hCom, buffer, buffLen, &numRead, NULL); + if(!ret) + return 0; + return numRead; +} + +/** + * @brief flush serial port read buffer + * + */ +void CLASS_SerialPort::flush() +{ + char buffer[FLUSH_BUFFSIZE]; + int numBytes = flushread(buffer, FLUSH_BUFFSIZE); + while(numBytes != 0) + numBytes = flushread(buffer, FLUSH_BUFFSIZE); +} + +/** + * @brief read information from CLASS device through serial port + * + * @return std::string received information + */ +std::string CLASS_SerialPort::read() +{ + char buffer[BUFFER_SIZE]; + int buffLen = BUFFER_SIZE; + DWORD numRead; + + --buffLen; + + bool ret = ReadFile(hCom, buffer, buffLen, &numRead, NULL); + + if(!ret) + return 0; + + buffer[numRead] = '\0'; + std::string r; + r.assign(buffer); + return r; +} + +/** + * @brief writers command to CLASS device and reads the answer through serial port + * + * @param buffer command to send + * @return std::string received information + */ +std::string CLASS_SerialPort::communication(const char *buffer) +{ + flush(); + + std::string result; + bool ret = write(buffer); + if(!ret) + { + result = "ERROR"; + } + else + { + result = ""; + for(int i = 0; i < 10; i++)//while(charsRead!=0)// //LQL DUDAS + { + result = result.append(read()); + Sleep(100); + } + } + /*std::string re = "Re:[] "; + std::string::size_type i = result.find(re); + + if (i != std::string::npos) + result.erase(i, re.length());*/ + + return result; +} + +/** + * @brief closes serial port + * + */ +void CLASS_SerialPort::CloseSerialPort() +{ + CloseHandle(hCom); +} + + +/** + * @brief turns stimulation on + * + * @return std::string answer + */ +std::string CLASS_SerialPort::setStimulationOn() +{ + std::string msg = commands::ClassCommands::CMD_ONSTIM; + std::string result = communication(msg.c_str()); + return result; +} + +/** + * @brief turns stimulation off + * + * @return std::string answer + */ +std::string CLASS_SerialPort::setStimulationOff() +{ + std::string msg = commands::ClassCommands::CMD_OFFSTIM; + std::string result = communication(msg.c_str()); + return result; +} + +/** + * @brief executes stimulation on a virutal electrode + * + * @param virtualElectrodeName selected virtual electrode to be stimulated + * @return std::string answer + */ +std::string CLASS_SerialPort::setStimulationVirtualElectrode(std::string &virtualElectrodeName) +{ + std::string msg = commands::ClassCommands::CMD_VELECSTIM + virtualElectrodeName + commands::ClassCommands::CMD_AUX; + std::string result = communication(msg.c_str()); + return result; +} + +/** + * @brief gives the battery level + * + * @return std::string answer + */ +std::string CLASS_SerialPort::getTic() +{ + std::string msg = commands::ClassCommands::CMD_GETTIC; + std::string result = communication(msg.c_str()); + return result; +} + +/** + * @brief gives information about a virtual electrode + * + * @param virtualElectrodeNumber selected virtual electrode + * @return std::string answer + */ +std::string CLASS_SerialPort::getVirtualElectrode(std::string &virtualElectrodeNumber) +{ + std::string msg = commands::ClassCommands::CMD_CONFIGVELEC + virtualElectrodeNumber + commands::ClassCommands::CMD_AUX2 + commands::ClassCommands::CMD_AUX; + std::string result = communication(msg.c_str()); + return result; +} + +/** + * @brief cofigures selected virtual electrode (all parameters must be included) + * + * @param virtualElectrodeNumber number of virtual electrode, maximum allowed value MAX_ALLOWED_VIRTUAL_ELECTRODES + * @param virtualElectrodeName name of virtual electrode, maximum number of characters MAX_CHAR_VIRTUAL_ELECTRODE_NAME + * @param cathodes to be active for the virtual electrode, allowed maximum number of pads per virtual electrode MAX_VIRTUAL_ELECTRODE_PADS + * @param anodes to be active for the virtual electrode + * @param amplitudes associated to each cathode, allowed minimum value MIN_VIRTUAL_ELECTRODE_AMPLITUDE, allowed maximum value for FES prototypes MAX_VIRTUAL_ELECTRODE_AMPLITUDE_FES, allowed maximum value for TACTILITY prototypes MAX_VIRTUAL_ELECTRODE_AMPLITUDE_TACTILITY + * @param pulsewiths associated to each cathode, allowed maximum value MAX_VIRTUAL_ELECTRODE_PULSE_WIDTH, allowd minumum value MIN_VIRTUAL_ELECTRODE_PULSE_WIDTH + * @param selected virtual electrode seleccted '1' or deselected '0' + * @param sync virtual electrode synchronous '1' or asynchronous '0' + * @return std::string answer + */ +std::string CLASS_SerialPort::setVirtualElectrodeOld(std::string &virtualElectrodeNumber, std::string &virtualElectrodeName, std::vector<int> cathodes, std::vector<int> anodes , std::vector<double> amplitudes, std::vector<int> pulsewiths, bool selected , bool sync) +{ + std::string result = ERROR_NOT_VALID_VALUE; + double aux_min_amplitude = *min_element(amplitudes.begin(),amplitudes.end()); + double aux_max_amplitude = *max_element(amplitudes.begin(),amplitudes.end()); + double allowed_max_amplitude = MAX_VIRTUAL_ELECTRODE_AMPLITUDE_FES; + + if(devicePrototype == "TACTILITY" || devicePrototype == "PAIN") + allowed_max_amplitude = MAX_VIRTUAL_ELECTRODE_AMPLITUDE_TACTILITY; + + int aux_widths = *max_element(pulsewiths.begin(), pulsewiths.end()); + + if(virtualElectrodeName.length() <= MAX_ALLOWED_VIRTUAL_ELECTRODES && virtualElectrodeName.length() <= MAX_CHAR_VIRTUAL_ELECTRODE_NAME && cathodes.size() <= MAX_VIRTUAL_ELECTRODE_PADS && aux_max_amplitude <= allowed_max_amplitude && aux_min_amplitude >= MIN_VIRTUAL_ELECTRODE_AMPLITUDE && aux_widths <= MAX_VIRTUAL_ELECTRODE_PULSE_WIDTH && aux_widths >= MIN_VIRTUAL_ELECTRODE_PULSE_WIDTH) + { + std::string msg = commands::ClassCommands::CMD_CONFIGVELEC + virtualElectrodeNumber + commands::ClassCommands::CMD_CONFIGVELEC_NAME + virtualElectrodeName + commands::ClassCommands::CMD_CONFIGVELEC_PADS; + + for (int i = 0; i < cathodes.size(); i++) + { + msg += std::to_string(cathodes[i]) + commands::ClassCommands::CMD_CONFIGVELEC_CATHODE; + } + for (int i = 0; i < anodes.size(); i++) + { + msg += std::to_string(anodes[i]) + commands::ClassCommands::CMD_CONFIGVELEC_ANODE; + } + msg += commands::ClassCommands::CMD_CONFIGVELEC_AMPLITUDE; + for (int i = 0; i < cathodes.size(); i++) + { + msg += std::to_string(cathodes[i]) + "=" + std::to_string(amplitudes[i]) + ","; + } + msg += commands::ClassCommands::CMD_CONFIGVELEC_PULSEWIDTH; + for (int i = 0; i < cathodes.size(); i++) + { + msg += std::to_string(cathodes[i]) + "=" + std::to_string(pulsewiths[i]) + ","; + } + msg += commands::ClassCommands::CMD_CONFIGVELEC_SELECTION + std::to_string(selected) + commands::ClassCommands::CMD_CONFIGVELEC_SYNCHRONOUS + std::to_string(sync) + commands::ClassCommands::CMD_AUX; + result = communication(msg.c_str()); + } + return result; +} +/** + * @brief cofigures selected virtual electrode, only virtualElectrodeNumber is compulsory. Each parameter can be included independetly allowing function to use defult values + * + * @param virtualElectrodeNumber number of virtual electrode, maximum allowed value MAX_ALLOWED_VIRTUAL_ELECTRODES + * @param virtualElectrodeName name of virtual electrode, maximum number of characters MAX_CHAR_VIRTUAL_ELECTRODE_NAME + * @param cathodes to be active for the virtual electrode, allowed maximum number of pads per virtual electrode MAX_VIRTUAL_ELECTRODE_PADS + * @param anodes to be active for the virtual electrode + * @param amplitudes associated to each cathode, allowed minimum value MIN_VIRTUAL_ELECTRODE_AMPLITUDE, allowed maximum value for FES prototypes MAX_VIRTUAL_ELECTRODE_AMPLITUDE_FES, allowed maximum value for TACTILITY prototypes MAX_VIRTUAL_ELECTRODE_AMPLITUDE_TACTILITY + * @param pulsewiths associated to each cathode, allowed maximum value MAX_VIRTUAL_ELECTRODE_PULSE_WIDTH, allowd minumum value MIN_VIRTUAL_ELECTRODE_PULSE_WIDTH + * @param selected virtual electrode seleccted '1' or deselected '0' + * @param sync virtual electrode synchronous '1' or asynchronous '0' + * @return std::string answer + */ +std::string CLASS_SerialPort::setVirtualElectrode(std::string &virtualElectrodeNumber, std::string virtualElectrodeName, std::vector<int> cathodes, std::vector<int> anodes, std::vector<CathodeAmplitude> amplitudes, std::vector<CathodeWidth> pulsewidths, std::string selected, std::string sync) +{ + std::string result = ERROR_NOT_VALID_VALUE; + std::string msg; + + if(std::stoi(virtualElectrodeNumber) <= MAX_ALLOWED_VIRTUAL_ELECTRODES) + { + msg += commands::ClassCommands::CMD_CONFIGVELEC + virtualElectrodeNumber; + } + else + { + return result; + } + + if(virtualElectrodeName.length() <= MAX_CHAR_VIRTUAL_ELECTRODE_NAME && !virtualElectrodeName.empty()) + { + msg += commands::ClassCommands::CMD_CONFIGVELEC_NAME + virtualElectrodeName; + } + else + { + return result; + } + if(cathodes.size() <= MAX_VIRTUAL_ELECTRODE_PADS && anodes.size() <= MAX_VIRTUAL_ELECTRODE_PADS) + { + if(cathodes[0] != 0 || anodes[0] != 0) + { + msg += commands::ClassCommands::CMD_CONFIGVELEC_PADS; + } + if(cathodes[0] != 0) + { + for (int i = 0; i < cathodes.size(); i++) + { + msg += std::to_string(cathodes[i]) + commands::ClassCommands::CMD_CONFIGVELEC_CATHODE; + } + } + if(anodes[0] != 0) + { + for (int i = 0; i < anodes.size(); i++) + { + msg += std::to_string(anodes[i]) + commands::ClassCommands::CMD_CONFIGVELEC_ANODE; + } + } + } + else + { + return result; + } + if(amplitudes[0].cathodenumber != "0") + { + std::vector<double> aux_amplitudes; + for(int i = 0; i < amplitudes.size(); i++) + { + aux_amplitudes.push_back(amplitudes[i].amplitude); + } + double aux_min_amplitude = *min_element(aux_amplitudes.begin(),aux_amplitudes.end()); + double aux_max_amplitude = *max_element(aux_amplitudes.begin(),aux_amplitudes.end()); + double allowed_max_amplitude = MAX_VIRTUAL_ELECTRODE_AMPLITUDE_FES; + + if(devicePrototype == "TACTILITY" || devicePrototype == "PAIN") + allowed_max_amplitude = MAX_VIRTUAL_ELECTRODE_AMPLITUDE_TACTILITY; + + if(aux_max_amplitude <= allowed_max_amplitude && aux_min_amplitude >= MIN_VIRTUAL_ELECTRODE_AMPLITUDE) + { + msg += commands::ClassCommands::CMD_CONFIGVELEC_AMPLITUDE; + for (int i = 0; i < amplitudes.size(); i++) + { + msg += amplitudes[i].cathodenumber + "=" + std::to_string(amplitudes[i].amplitude) + ","; + } + } + else + { + return result; + } + } + if(pulsewidths[0].cathodenumber != "0") + { + std::vector<int> aux_widths; + for(int i = 0; i < pulsewidths.size(); i++) + { + aux_widths.push_back(pulsewidths[i].width); + } + int aux_max_widths = *max_element(aux_widths.begin(), aux_widths.end()); + int aux_min_widths = *min_element(aux_widths.begin(), aux_widths.end()); + + if(aux_max_widths <= MAX_VIRTUAL_ELECTRODE_PULSE_WIDTH && aux_min_widths >= MIN_VIRTUAL_ELECTRODE_PULSE_WIDTH) + { + msg += commands::ClassCommands::CMD_CONFIGVELEC_PULSEWIDTH; + for (int i = 0; i < pulsewidths.size(); i++) + { + msg += pulsewidths[i].cathodenumber + "=" + std::to_string(pulsewidths[i].width ) + ","; + } + } + else + { + return result; + } + } + if(selected != "") + { + if(selected == "1" || selected == "0") + { + msg += commands::ClassCommands::CMD_CONFIGVELEC_SELECTION + selected; + } + else + { + return result; + } + } + if(sync !="") + { + if(sync == "1" || sync == "0") + { + msg += commands::ClassCommands::CMD_CONFIGVELEC_SYNCHRONOUS + sync; + } + else + { + return result; + } + } + msg += commands::ClassCommands::CMD_AUX; + result = communication(msg.c_str()); + return result; +} + +/** + * @brief cofigures virtual electrode to selected or not selected + * + * @param virtualElectrodeNumber number of virtual electrode, maximum allowed value MAX_ALLOWED_VIRTUAL_ELECTRODES + * @param selection virtual electrode seleccted '1' or deselected '0' + * @return std::string answer + */ +std::string CLASS_SerialPort::setVirtualElectrodeSelection(std::string &virtualElectrodeNumber, bool selection) +{ + std::string result = ERROR_NOT_VALID_VALUE; + std::string msg; + + if(std::stoi(virtualElectrodeNumber) <= MAX_ALLOWED_VIRTUAL_ELECTRODES) + { + msg += commands::ClassCommands::CMD_CONFIGVELEC + virtualElectrodeNumber; + std::string selected; + if(selection == true) + { + selected = "1"; + } + else + { + selected = "0"; + } + msg += commands::ClassCommands::CMD_CONFIGVELEC_SELECTION + selected; + } + else + { + return result; + } + + msg += commands::ClassCommands::CMD_AUX; + result = communication(msg.c_str()); + return result; +} + +/** + * @brief gives information about a pattern + * + * @param patternNumber selected pattern number, allowed number of patterns MAX_ALLOWED_PATTERNS + * @return std::string answer + */ +std::string CLASS_SerialPort::getPattern(std::string &patternNumber) +{ + std:: string result = ERROR_NOT_VALID_VALUE; + if(std::stoi(patternNumber) <= MAX_ALLOWED_PATTERNS) + { + std::string msg = commands::ClassCommands::CMD_CONFIGPATTERN + patternNumber + commands::ClassCommands::CMD_AUX2 + commands::ClassCommands::CMD_AUX; + result = communication(msg.c_str()); + } + + return result; +} + +/** + * @brief delete a pattern + * + * @param patternNumber selected pattern number, allowed number of patterns MAX_ALLOWED_PATTERNS + * @return std::string answer + */ +std::string CLASS_SerialPort::clearPattern(std::string &patternNumber) +{ + std::string result = ERROR_NOT_VALID_VALUE; + if(std::stoi(patternNumber) <= MAX_ALLOWED_PATTERNS) + { + std::string msg = commands::ClassCommands::CMD_CONFIGPATTERN + patternNumber + commands::ClassCommands::CMD_CONFIGPATTERN_PARAM1 + commands::ClassCommands::CMD_AUX; + result = communication(msg.c_str()); + } + + return result; +} + +/** + * @brief cofigures selected pattern + * + * @param patternNumber selected pattern, allowed number of patterns MAX_ALLOWED_PATTERNS + * @param patternsValues vector of Pattern structure + * @return std::string answer + */ +std::string CLASS_SerialPort::setPattern(std::string &patternNumber, std::vector<Pattern> &patternsValues) +{ + std::string result = ERROR_NOT_VALID_VALUE; + if(std::stoi(patternNumber) <= MAX_ALLOWED_PATTERNS) + { + result = clearPattern(patternNumber); + std::string msg; + for(int i = 0; i < patternsValues.size() ; i++) + { + msg = commands::ClassCommands::CMD_CONFIGPATTERN + patternNumber + commands::ClassCommands::CMD_CONFIGPATTERN_PARAM2 + patternsValues[i].amp + " " + patternsValues[i].pw + " " + patternsValues[i].r + " " + std::to_string(patternsValues[i].ampval) + " " + std::to_string(patternsValues[i].pwval) + " " + std::to_string(patternsValues[i].time) + commands::ClassCommands::CMD_AUX; + result = communication(msg.c_str()); + } + msg = commands::ClassCommands::CMD_CONFIGPATTERN + patternNumber + commands::ClassCommands::CMD_CONFIGPATTERN_PARAM3 + commands::ClassCommands::CMD_AUX; + result = communication(msg.c_str()); + } + return result; +} + +/** + * @brief gives information about high voltage value + * + * @return std::string answer + */ +std::string CLASS_SerialPort::getHighVoltage() +{ + std::string msg = commands::ClassCommands::CMD_GETHV; + std::string result = communication(msg.c_str()); + return result; +} + +/** + * @brief sets hihg voltage value to on + * + * @return std::string answer + */ +std::string CLASS_SerialPort::setHighVoltageOn() +{ + std::string msg = commands::ClassCommands::CMD_ONHV; + std::string result = communication(msg.c_str()); + return result; +} + +/** + * @brief sets high voltage value to off + * + * @return std::string answer + */ +std::string CLASS_SerialPort::setHighVoltageOff() +{ + std::string msg = commands::ClassCommands::CMD_OFFHV; + std::string result = communication(msg.c_str()); + return result; +} + +/** + * @brief sets high voltage value + * + * @param highVoltageValue allowed maximum high voltage value MAX_HIGH_VOLTAGE, allowed minimum high voltage value MIN_HIGH_VOLTAGE + * @return std::string answer + */ +std::string CLASS_SerialPort::setHighVoltageValue(std::string &highVoltageValue) +{ + std::string result = ERROR_NOT_VALID_VALUE; + if(MIN_HIGH_VOLTAGE <= std::stoi(highVoltageValue) && std::stoi(highVoltageValue) <= MAX_HIGH_VOLTAGE) + { + std::string msg = commands::ClassCommands::CMD_SETHV + highVoltageValue + commands::ClassCommands::CMD_AUX; + result = communication(msg.c_str()); + } + return result; +} + +/** + * @brief opens SD current directory + * + * @return std::string answer + */ +std::string CLASS_SerialPort::SDls() +{ + std::string msg = commands::ClassCommands::CMD_SD_OPEN_DIRECTORY; + std::string result = communication(msg.c_str()); + return result; +} + +/** + * @brief changes SD directory + * + * @param directoryName fully specified path + * @return std::string answer + */ +std::string CLASS_SerialPort::SDcd(std::string &directoryName) +{ + std::string msg = commands::ClassCommands::CMD_SD_CHANGE_DIRECTORY + directoryName + commands::ClassCommands::CMD_AUX; + std::string result = communication(msg.c_str()); + return result; +} + +/** + * @brief prints SD current directory + * + * @return std::string answer + */ +std::string CLASS_SerialPort::SDpwd() +{ + std::string msg = commands::ClassCommands::CMD_SD_PRINT_DIRECTORY; + std::string result = communication(msg.c_str()); + return result; +} + +/** + * @brief removes SD directory + * + * @param fileName fully specified path + * @return std::string answer + */ +std::string CLASS_SerialPort::SDrm(std::string &fileName) +{ + std::string msg = commands::ClassCommands::CMD_SD_DELETE_FILE + fileName + commands::ClassCommands::CMD_AUX; + std::string result = communication(msg.c_str()); + return result; +} + +/** + * @brief create new file into SD + * + * @param fileName fully specified path + * @return std::string answer + */ +std::string CLASS_SerialPort::SDcat(std::string &fileName) +{ + std::string msg = commands::ClassCommands::CMD_SD_CREATE_FILE + fileName + commands::ClassCommands::CMD_AUX; + std::string result = communication(msg.c_str()); + return result; +} + +/** + * @brief edit file into SD + * + * @param filePathName fully specified path + * @param text text to add + * @return std::string answer + */ +std::string CLASS_SerialPort::SDed(std::string &filePathName, std::string &text) +{ + std::string msg = commands::ClassCommands::CMD_SD_EDIT_FILE + filePathName + " " + text +commands::ClassCommands::CMD_AUX; + std::string result = communication(msg.c_str()); + return result; +} + +/** + * @brief creates new directory into SD + * + * @param directoryName fully specified path + * @return std::string answer + */ +std::string CLASS_SerialPort::SDmkdir(std::string &directoryName) +{ + std::string msg = commands::ClassCommands::CMD_SD_CREATE_DIRECTORY + directoryName + commands::ClassCommands::CMD_AUX; + std::string result = communication(msg.c_str()); + return result; +} + +/** + * @brief renames SD file + * + * @param oldFileName fully specified path + * @param newFileName fully specified new path + * @return std::string answer + */ +std::string CLASS_SerialPort::SDrename(std::string &oldFileName, std::string &newFileName) +{ + std::string msg = commands::ClassCommands::CMD_SD_RENAME_FILE + oldFileName + " " + newFileName + commands::ClassCommands::CMD_AUX; + std::string result = communication(msg.c_str()); + return result; +} + +/** + * @brief create and save in SD boot information file + * + * @return std::string answer + */ +std::string CLASS_SerialPort::SDsaveboot() +{ + std::string msg = commands::ClassCommands::CMD_SD_SAVE_BOOT; + std::string result = communication(msg.c_str()); + return result; +} + +/** + * @brief get prototype type : FES, TACTILITY + * + * @return std::string answer + */ +std::string CLASS_SerialPort::getApplication() +{ + std::string msg = commands::ClassCommands::CMD_GETPROTOTYPE; + std::string result = communication(msg.c_str()); + return result; +} + +/** + * @brief set prototype type to FES + * + * @return std::string answer + */ +std::string CLASS_SerialPort::setFESApplication() +{ + std::string msg = commands::ClassCommands::CMD_SET_FES_PROTOTYPE; + std::string result = communication(msg.c_str()); + return result; +} + +/** + * @brief set prototype type to TACTILITY + * + * @return std::string answer + */ +std::string CLASS_SerialPort::setTACTILITYApplication() +{ + std::string msg = commands::ClassCommands::CMD_SET_TACTILITY_PROTOTYPE; + std::string result = communication(msg.c_str()); + return result; +} + +/** + * @brief gives device name + * + * @return std::string answer + */ +std::string CLASS_SerialPort::getDeviceName() +{ + std::string msg = commands::ClassCommands::CMD_GETDEVICENAME; + std::string result = communication(msg.c_str()); + return result; +} + +/** + * @brief sets device name + * + * @param deviceName allowed maximun number of characters MAX_CHAR_DEVICENAME + * @return std::string answer + */ +std::string CLASS_SerialPort::setDeviceName(std::string &deviceName) +{ + std::string result = ERROR_NOT_VALID_VALUE; + if(deviceName.length() <= MAX_CHAR_DEVICENAME) + { + std::string msg = commands::ClassCommands::CMD_SETDEVICENAME + deviceName + commands::ClassCommands::CMD_AUX; + result = communication(msg.c_str()); + } + return result; +} + +/** + * @brief gives information about firmware + * + * @return std::string answer + */ +std::string CLASS_SerialPort::getFirmware() +{ + std::string msg = commands::ClassCommands::CMD_GETFW; + std::string result = communication(msg.c_str()); + return result; +} + +/** + * @brief gives information about hardware + * + * @return std::string answer + */ +std::string CLASS_SerialPort::getHardware() +{ + std::string msg = commands::ClassCommands::CMD_GETHW; + std::string result = communication(msg.c_str()); + return result; +} + +/** + * @brief gives the name of the SD card folder where patterns are saved + * + * @return std::string answer + */ +std::string CLASS_SerialPort::getSDPartternsFolder() +{ + std::string msg = commands::ClassCommands::CMD_GETSDFUNCTION; + std::string result = communication(msg.c_str()); + return result; +} + +/** + * @brief sets the name of SD card folder where patterns will be saved + * + * @param sdPattern name of folder, allowed maximum charaters MAX_CHAR_FUNCTIONNAME + * @return std::string answer + */ +std::string CLASS_SerialPort::setSDPartternsFolder(std::string &sdPattern) +{ + std::string result = ERROR_NOT_VALID_VALUE; + if(sdPattern.length() <= MAX_CHAR_FUNCTIONNAME) + { + std::string msg = commands::ClassCommands::CMD_SETSDFUNCTION + sdPattern + commands::ClassCommands::CMD_AUX; + result = communication(msg.c_str()); + } + return result; +} + +/** + * @brief gives information about stimulation frequency value in hertz + * + * @return std::string answer + */ +std::string CLASS_SerialPort::getFrequency() +{ + std::string msg = commands::ClassCommands::CMD_GETFRQUENCY; + std::string result = communication(msg.c_str()); + return result; +} + +/** + * @brief set the stimulation frequency value in hertz + * + * @param frequency allowed maximum value MAX_FREQUENCY, allowed minimum value MIN_FREQUENCY + * @return std::string answer + */ +std::string CLASS_SerialPort::setFrequency(std::string &frequency) +{ + std::string result = ERROR_NOT_VALID_VALUE; + if(MIN_FREQUENCY <= std::stoi(frequency) && std::stoi(frequency) <= MAX_FREQUENCY) + { + std::string msg = commands::ClassCommands::CMD_SETFREQ + frequency + commands::ClassCommands::CMD_AUX; + result = communication(msg.c_str()); + } + return result; +} + +/** + * @brief gives information about stimulation interpulses interval + * + * @return std::string answer + */ +std::string CLASS_SerialPort::getPulsesInterval() +{ + std::string msg = commands::ClassCommands::CMD_GETINTERVAL; + std::string result = communication(msg.c_str()); + return result; +} + +/** + * @brief set the stimulation interpulses interval + * + * @param interval allowed maximum value MAX_PULSE_INTERVAL, allowed minimum value MIN_PULSE_INTERVAL + * @return std::string answer + */ +std::string CLASS_SerialPort::setPulsesInterval(std::string &interval) +{ + std::string result = ERROR_NOT_VALID_VALUE; + if(MIN_PULSE_INTERVAL <= std::stoi(interval) && std::stoi(interval) <= MAX_PULSE_INTERVAL) + { + std::string msg = commands::ClassCommands::CMD_SETINTERVAL + interval + commands::ClassCommands::CMD_AUX; + result = communication(msg.c_str()); + } + return result; +} + +/** + * @brief gives information about events log status + * + * @return std::string answer + */ +std::string CLASS_SerialPort::getLogevents() +{ + std::string msg = commands::ClassCommands::CMD_GETLOGEVENTS; + std::string result = communication(msg.c_str()); + return result; +} + +/** + * @brief start loggind events + * + * @return std::string answer + */ +std::string CLASS_SerialPort::setLogeventsOn() +{ + std::string msg = commands::ClassCommands::CMD_ONLOGEVENTS; + std::string result = communication(msg.c_str()); + return result; +} + +/** + * @brief stop logging events + * + * @return std::string answer + */ +std::string CLASS_SerialPort::setLogeventsOff() +{ + std::string msg = commands::ClassCommands::CMD_OFFLOGEVENTS; + std::string result = communication(msg.c_str()); + return result; +} + +/** + * @brief gives the name of SD folder where the folder containing the pattern is saved + * + * @return std::string answer + */ +std::string CLASS_SerialPort::getSDUserFolder() +{ + std::string msg = commands::ClassCommands::CMD_GETSDNAME; + std::string result = communication(msg.c_str()); + return result; +} + +/** + * @brief sets the name of SD folder where the folder containing the pattern is saved + * + * @param sdFolder allowed maximum namber of characters MAX_CHAR_USERNAME + * @return std::string answer + */ +std::string CLASS_SerialPort::setSDUserFolder(std::string &sdFolder) +{ + std::string result = ERROR_NOT_VALID_VALUE; + if(sdFolder.length() <= MAX_CHAR_USERNAME) + { + std::string msg = commands::ClassCommands::CMD_SETSDNAME + sdFolder + commands::ClassCommands::CMD_AUX; + result = communication(msg.c_str()); + } + return result; +} + +/** + * @brief gives information about battery status + * + * @return std::string answer + */ +std::string CLASS_SerialPort::getBattery() +{ + std::string msg = commands::ClassCommands::CMD_GETBATTERY; + std::string result = communication(msg.c_str()); + return result; +} + +/** + * @brief gives information about last measured pulse voltages + * + * @return std::string answer + */ +std::string CLASS_SerialPort::getPulseVoltages() +{ + std::string msg = commands::ClassCommands::CMD_GETPULSE_VOLTAGES; + std::string result = communication(msg.c_str()); + return result; +} + +/** + * @brief gives information about last measured pulse intensities (mA) + * + * @return std::string answer + */ +std::string CLASS_SerialPort::getPulseIntensities() +{ + std::string msg = commands::ClassCommands::CMD_GETPULSE_INTENSITIES; + std::string result = communication(msg.c_str()); + return result; +} + +/** + * @brief gives information about last measured voltages of the negative pulse cycle + * + * @return std::string answer + */ +std::string CLASS_SerialPort::getPulseNegativeVoltages() +{ + std::string msg = commands::ClassCommands::CMD_GETPULSE_NEGATIVEVOLTAGES; + std::string result = communication(msg.c_str()); + return result; +} + +/** + * @brief gives information about last measured voltages of the positive pulse cycle + * + * @return std::string answer + */ +std::string CLASS_SerialPort::getPulsePositiveVoltages() +{ + std::string msg = commands::ClassCommands::CMD_GETPULSE_POSITIVEVOLTAGES; + std::string result = communication(msg.c_str()); + return result; +} + +/** + * @brief gives information about the average intensity (mA) for the positive cycle + * + * @return std::string answer + */ +std::string CLASS_SerialPort::getPulseAverageIntensity() +{ + std::string msg = commands::ClassCommands::CMD_GETPULSE_AVERAGEINTENSITY; + std::string result = communication(msg.c_str()); + return result; +} + +/** + * @brief start acquisition + * + * @return std::string answer + */ +std::string CLASS_SerialPort::setAcquisitionOn() +{ + std::string msg = commands::ClassCommands::CMD_ONACQ; + std::string result = communication(msg.c_str()); + return result; +} + +/** + * @brief stop acquisition + * + * @return std::string answer + */ +std::string CLASS_SerialPort::setAcquisitionOff() +{ + std::string msg = commands::ClassCommands::CMD_OFFACQ; + std::string result = communication(msg.c_str()); + return result; +} + +/** + * @brief sets configuration for acquisition (all parameters must be included) + * + * @param channels acquisition channels to be active + * @param frequency acquisition sampling rate, allowed values ACQUISITION_ALLOWED_FREQUENCY1, ACQUISITION_ALLOWED_FREQUENCY2, ACQUISITION_ALLOWED_FREQUENCY3, ACQUISITION_ALLOWED_FREQUENCY4, ACQUISITION_ALLOWED_FREQUENCY5 + * @param type unipolar or bipolar + * @param gain parameter that defines gain for the recording, allowed values ACQUISITION_ALLOWED_GAIN1, ACQUISITION_ALLOWED_GAIN2, ACQUISITION_ALLOWED_GAIN3, ACQUISITION_ALLOWED_GAIN4, ACQUISITION_ALLOWED_GAIN5, ACQUISITION_ALLOWED_GAIN6 + * @return std::string answer + */ +std::string CLASS_SerialPort::setAcquisitionConfiguratonOld( std::vector<int> &channels, int frequency, std::string type, int gain) +{ + std::string result = ERROR_NOT_VALID_VALUE; +std::string msg; + int aux_max_channel = *max_element(channels.begin(),channels.end()); + int aux_min_channel = *min_element(channels.begin(),channels.end()); + + if((aux_min_channel>=1 && aux_max_channel<16) + && (frequency == ACQUISITION_ALLOWED_FREQUENCY1 || frequency == ACQUISITION_ALLOWED_FREQUENCY2|| frequency == ACQUISITION_ALLOWED_FREQUENCY3 ||frequency == ACQUISITION_ALLOWED_FREQUENCY4 ||frequency == ACQUISITION_ALLOWED_FREQUENCY5) + && (type == ACQUISITION_ALLOWED_TYPE1 || type == ACQUISITION_ALLOWED_TYPE2) + && (gain == ACQUISITION_ALLOWED_GAIN1 || gain == ACQUISITION_ALLOWED_GAIN2 || gain == ACQUISITION_ALLOWED_GAIN3 || gain == ACQUISITION_ALLOWED_GAIN4 || gain == ACQUISITION_ALLOWED_GAIN5 || gain == ACQUISITION_ALLOWED_GAIN6)) + { + int channels_int = 0; + for (int i = 0; i < channels.size(); i++) + { + channels_int += (int)(pow(2, channels[i] - 1)); + } + std::stringstream stream; + stream << "0x" + << std::setfill('0') << std::setw(2) + << std::hex << channels_int; + std::string channels_hex_str(stream.str()); + msg = commands::ClassCommands::CMD_CONFIGACQ + commands::ClassCommands::CMD_CONFIGACQ_FREQUENCY + std::to_string(frequency) + commands::ClassCommands::CMD_CONFIGACQ_CHANNELS + channels_hex_str + commands::ClassCommands::CMD_CONFIGACQ_TYPE + type + commands::ClassCommands::CMD_CONFIGACQ_GAIN + std::to_string(gain) + commands::ClassCommands::CMD_AUX; + result = communication(msg.c_str()); + } + return result; +} + +/** + * @brief sets configuration for acquisition , only virtualElectrodeNumber is compulsory. Each parameter can be included independetly allowing function to use defult values + * + * @param channels acquisition channels to be active + * @param frequency acquisition sampling rate, allowed values ACQUISITION_ALLOWED_FREQUENCY1, ACQUISITION_ALLOWED_FREQUENCY2, ACQUISITION_ALLOWED_FREQUENCY3, ACQUISITION_ALLOWED_FREQUENCY4, ACQUISITION_ALLOWED_FREQUENCY5 + * @param type unipolar or bipolar + * @param gain parameter that defines gain for the recording, allowed values ACQUISITION_ALLOWED_GAIN1, ACQUISITION_ALLOWED_GAIN2, ACQUISITION_ALLOWED_GAIN3, ACQUISITION_ALLOWED_GAIN4, ACQUISITION_ALLOWED_GAIN5, ACQUISITION_ALLOWED_GAIN6 + * @return std::string answer + */ +std::string CLASS_SerialPort::setAcquisitionConfiguraton(std::vector<int> &channels, int frequency, std::string type, int gain) +{ + std::string result = ERROR_NOT_VALID_VALUE; + std::string msg; + + int aux_max_channel = *max_element(channels.begin(),channels.end()); + int aux_min_channel = *min_element(channels.begin(),channels.end()); + + if(aux_min_channel>=1 && aux_max_channel<16) + { + int channels_int = 0; + for (int i = 0; i < channels.size(); i++) + { + channels_int += (int)(pow(2, channels[i] - 1)); + } + std::stringstream stream; + stream << "0x" + << std::setfill('0') << std::setw(2) + << std::hex << channels_int; + std::string channels_hex_str(stream.str()); + msg = commands::ClassCommands::CMD_CONFIGACQ + commands::ClassCommands::CMD_CONFIGACQ_CHANNELS + channels_hex_str; + + if(frequency != 0) + { + if(frequency == ACQUISITION_ALLOWED_FREQUENCY1 || frequency == ACQUISITION_ALLOWED_FREQUENCY2|| frequency == ACQUISITION_ALLOWED_FREQUENCY3 ||frequency == ACQUISITION_ALLOWED_FREQUENCY4 ||frequency == ACQUISITION_ALLOWED_FREQUENCY5) + { + msg += commands::ClassCommands::CMD_CONFIGACQ_FREQUENCY + std::to_string(frequency); + } + else + { + return result; + } + } + if(type != "") + { + if(type == ACQUISITION_ALLOWED_TYPE1 || type == ACQUISITION_ALLOWED_TYPE2) + { + msg += commands::ClassCommands::CMD_CONFIGACQ_TYPE + type; + } + else + { + return result; + } + } + if(gain != 0) + { + if(gain == ACQUISITION_ALLOWED_GAIN1 || gain == ACQUISITION_ALLOWED_GAIN2 || gain == ACQUISITION_ALLOWED_GAIN3 || gain == ACQUISITION_ALLOWED_GAIN4 || gain == ACQUISITION_ALLOWED_GAIN5 || gain == ACQUISITION_ALLOWED_GAIN6) + { + msg += commands::ClassCommands::CMD_CONFIGACQ_GAIN + std::to_string(gain); + } + else + { + return result; + } + } + } + else + { + return result; + } + + msg += commands::ClassCommands::CMD_AUX; + result = communication(msg.c_str()); + return result; + +} + +/** + * @brief to generate a quadratic signal for input tests + * + * @return std::string answer + */ +std::string CLASS_SerialPort::setAcquisitionTest() +{ + std::string msg = commands::ClassCommands::CMD_TESTACQ; + std::string result = communication(msg.c_str()); + return result; +} + +/** + * @brief set normal input signal, biosignal recoding + * + * @return std::string answer + */ +std::string CLASS_SerialPort::setAcquisitionNormal() +{ + std::string msg = commands::ClassCommands::CMD_NORMALACQ; + std::string result = communication(msg.c_str()); + return result; +} + +/** + * @brief enable for streaming acquisition data by bluetooth + * + * @return std::string answer + */ +std::string CLASS_SerialPort::setAcquisitionStreamOn() +{ + std::string msg = commands::ClassCommands::CMD_STREAMONACQ; + std::string result = communication(msg.c_str()); + return result; +} + +/** + * @brief disable for streaming acquisition data by bluetooth + * + * @return std::string answer + */ +std::string CLASS_SerialPort::setAcquisitionStreamOff() +{ + std::string msg = commands::ClassCommands::CMD_STREAMOFFACQ; + std::string result = communication(msg.c_str()); + return result; +} + +/** + * @brief enable acquisition electrode impedance measurement mode + * + * @return std::string answer + */ +std::string CLASS_SerialPort::setAcquisitionImpedanceOn() +{ + std::string msg = commands::ClassCommands::CMD_ONIMPEDANCEACQ; + std::string result = communication(msg.c_str()); + return result; +} + +/** + * @brief desable acquisition electrode impedance measurement mode + * + * @return std::string answer + */ +std::string CLASS_SerialPort::setAcquisitionImpedanceOff() +{ + std::string msg = commands::ClassCommands::CMD_OFFIMPEDANCEACQ; + std::string result = communication(msg.c_str()); + return result; +} + +/** + * @brief enable acquisition impedance measurement for positive electrodes + * + * @return std::string answer + */ +std::string CLASS_SerialPort::setAcquisitionImpedanceChannelsPositive() +{ + std::string msg = commands::ClassCommands::CMD_CONFIGACQ_IMPEDANCEPOSITIVE; + std::string result = communication(msg.c_str()); + return result; +} + +/** + * @brief enable acquisition impedance measurement for negative electrodes + * + * @return std::string answer + */ +std::string CLASS_SerialPort::setAcquisitionImpedanceChannelsNegative() +{ + std::string msg = commands::ClassCommands::CMD_CONFIGACQ_IMPEDANCENEGATIVE; + std::string result = communication(msg.c_str()); + return result; +} + +/** + * @brief enable acquisition electrode disconnection alarm + * + * @return std::string answer + */ +std::string CLASS_SerialPort::setAcquisitionLeadoffOn() +{ + std::string msg = commands::ClassCommands::CMD_CONFIGACQ_LEADOFF_ON; + std::string result = communication(msg.c_str()); + return result; +} + +/** + * @brief disable acquisition electrode disconnection alarm + * + * @return std::string answer + */ +std::string CLASS_SerialPort::setAcquisitionLeadoffOff() +{ + std::string msg = commands::ClassCommands::CMD_CONFIGACQ_LEADOFF_OFF; + std::string result = communication(msg.c_str()); + return result; +} + +/** + * @brief configure leadoff signal current, depending on the electrode type higher or lower leadoff current is required + * + * @param current allowed values ACQUISITION_ALLOWED_CURRENT1, ACQUISITION_ALLOWED_CURRENT2, ACQUISITION_ALLOWED_CURRENT3, ACQUISITION_ALLOWED_CURRENT4 + * @return std::string answer + */ +std::string CLASS_SerialPort::setAcquisitionLeadoffConfiguration(std::string ¤t) +{ + std::string result = ERROR_NOT_VALID_VALUE; + if(current == ACQUISITION_ALLOWED_CURRENT1 || current == ACQUISITION_ALLOWED_CURRENT2 || current == ACQUISITION_ALLOWED_CURRENT3 || current == ACQUISITION_ALLOWED_CURRENT4) + { + std::string msg = commands::ClassCommands::CMD_CONFIGACQ_SETLEADOFF + current + commands::ClassCommands::CMD_AUX; + result = communication(msg.c_str()); + } + return result; +} + +/** + * @brief get the elapsed time since the stimulation began in in microsencond + * + * @return std::string answer + */ +std::string CLASS_SerialPort::getStimulationTime() +{ + std::string msg = commands::ClassCommands::CMD_GETSTIMTIME; + std::string result = communication(msg.c_str()); + return result; +} + +/** + * @brief get the time buzzer will sound in milliseconds + * + * @return std::string answer + */ +std::string CLASS_SerialPort::getBuzzerTempo() +{ + std::string msg = commands::ClassCommands::CMD_SETBUZZER + commands::ClassCommands::ClassCommands::CMD_AUX2 + commands::ClassCommands::ClassCommands::CMD_AUX; + std::string result = communication(msg.c_str()); + return result; +} + +/** + * @brief set the time buzzer will sound in milliseconds + * + * @param buzzerTempo allowed maximum value BUZZER_MAX_TEMPO_ms, allowed minimum value BUZZER_MIN_TEMPO_ms + * @return std::string answer + */ +std::string CLASS_SerialPort::setBuzzerTempo(std::string &buzzerTempo) +{ + std::string result = ERROR_NOT_VALID_VALUE; + if(BUZZER_MIN_TEMPO_ms <= std::stoi(buzzerTempo) && std::stoi(buzzerTempo) <= BUZZER_MAX_TEMPO_ms) + { + std::string msg = commands::ClassCommands::CMD_SETBUZZER + buzzerTempo + commands::ClassCommands::CMD_AUX; + result = communication(msg.c_str()); + } + + return result; +} + +/** + * @brief play buzzer + * + * @return std::string answer + */ +std::string CLASS_SerialPort::playBuzzer() +{ + std::string msg = commands::ClassCommands::CMD_PLAYBUZZER; + std::string result = communication(msg.c_str()); + return result; +} + +/** + * @brief start communication with FES prototype + * + * @return std::string answer + */ +std::string CLASS_SerialPort::startFESCommunication() +{ + std::string msg = commands::ClassCommands::CMD_STARTFES; + std::string result = communication(msg.c_str()); + devicePrototype = "FES"; + return result; +} + +/** + * @brief start communication with TACTILITY prototype + * + * @return std::string answer + */ +std::string CLASS_SerialPort::startTACTILITYCommunication() +{ + std::string msg = commands::ClassCommands::CMD_STARTTACTILITY; + std::string result = communication(msg.c_str()); + devicePrototype = "TACTILTIY"; + return result; +} + +/** + * @brief start communication with prototype + * + * @param prototipeName name of prototype + * @return std::string answer + */ +std::string CLASS_SerialPort::startCommunication(std::string &prototipeName) +{ + std::string msg = commands::ClassCommands::CMD_STARTCOMMUNICATION + prototipeName + commands::ClassCommands::CMD_AUX; + std::string result = communication(msg.c_str()); + devicePrototype = prototipeName; + return result; +} + +/** + * @brief gives information about the number of writing errors + * + * @return std::string answer + */ +std::string CLASS_SerialPort::showLogErrors() +{ + std::string msg = commands::ClassCommands::CMD_GETLOGERRORS; + std::string result = communication(msg.c_str()); + return result; +} + +/** + * @brief create a new file to log errors in SD card + * + * @return std::string answer + */ +std::string CLASS_SerialPort::createLogFile() +{ + std::string msg = commands::ClassCommands::CMD_OPENLOGERRORS; + std::string result = communication(msg.c_str()); + return result; +} + +/** + * @brief flush remaining data form the log file to SD card + * + * @return std::string answer + */ +std::string CLASS_SerialPort::closeLogFile() +{ + std::string msg = commands::ClassCommands::CMD_CLOSELOGERRORS; + std::string result = communication(msg.c_str()); + return result; +} + +/** + * @brief turn off device + * + * @return std::string answer + */ +std::string CLASS_SerialPort::shutDown() +{ + std::string msg = commands::ClassCommands::CMD_SWITCHOFF; + std::string result = communication(msg.c_str()); + return result; +} + +/** + * @brief gives information about RTC clock + * + * @return std::string answer + */ +std::string CLASS_SerialPort::getRTC() +{ + std::string msg = commands::ClassCommands::CMD_GETRTC; + std::string result = communication(msg.c_str()); + return result; +} + +/** + * @brief sets RTC date + * + * @param rtcDate format mm-dd-yyyy + * @return std::string answer + */ +std::string CLASS_SerialPort::setRTCDate(std::string &rtcDate) +{ + std::string msg = commands::ClassCommands::CMD_SETRTCDATE + rtcDate + commands::ClassCommands::CMD_AUX; + std::string result = communication(msg.c_str()); + return result; +} + +/** + * @brief sets RTC time + * + * @param rtcTime format hh:mm:ss + * @return std::string answer + */ +std::string CLASS_SerialPort::setRTCTime(std::string &rtcTime) +{ + std::string msg = commands::ClassCommands::CMD_SETRTCTIME + rtcTime + commands::ClassCommands::CMD_AUX; + std::string result = communication(msg.c_str()); + return result; +} + +/** + * @brief check connection + * + * @return std::string answer + */ +std::string CLASS_SerialPort::ping() +{ + std::string msg = commands::ClassCommands::CMD_PING; + std::string result = communication(msg.c_str()); + return result; +} + +/** + * @brief displays a list of commands + * + * @return std::string answer + */ +std::string CLASS_SerialPort::getHelp() +{ + std::string msg = commands::ClassCommands::CMD_HELP; + std::string result = communication(msg.c_str()); + return result; +} \ No newline at end of file diff --git a/serial_port_class_api/src/CMakeLists.txt b/serial_port_class_api/src/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..4e2d4154590b5ae080a1ad85916310f84dcb83de --- /dev/null +++ b/serial_port_class_api/src/CMakeLists.txt @@ -0,0 +1,19 @@ + +cmake_minimum_required(VERSION 3.14) +project (class_serial_port VERSION 0.1.0) + +add_executable(class_api_exe + CLASS_SerialPort.cpp + main.cpp) + +target_link_libraries(class_api_exe ${CMAKE_CURRENT_SOURCE_DIR}/../commands.lib) + + +set(class_files_local ${CMAKE_CURRENT_SOURCE_DIR}/CLASS_SerialPort.cpp) + +set(class_files ${class_files_local} PARENT_SCOPE) + +add_library(class_serial_port ${class_files_local}) + +target_link_libraries(class_serial_port ${CMAKE_CURRENT_SOURCE_DIR}/../commands.lib) +set_target_properties(class_serial_port PROPERTIES FOLDER class) diff --git a/serial_port_class_api/src/main.cpp b/serial_port_class_api/src/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..83ae980f7f60d299d39e59ea698421b946c8a162 --- /dev/null +++ b/serial_port_class_api/src/main.cpp @@ -0,0 +1,322 @@ +/** + * @file main.cpp + * @author Leire Querejeta Lomas <leire.querejeta@tecnalia.com> + * @brief example of the use of API + * @date 2022-10-10 + * + * @copyright Copyright 2020 + * Tecnalia Research & Innovation. + * Distributed under the GNU GPL v3. + * For full terms see https://www.gnu.org/licenses/gpl.txt + */ +#include <iostream> +#include <string> +#include "../include/CLASS_SerialPort.h" +#include <vector> +#include "../commands.h" + +using namespace std; + +int main(void) +{ + std::string port; + port = "COM3"; // name of port assigned to class bluetooth device + CLASS_SerialPort serial; + bool port_status = serial.SetOpenPort(port); + + cout << "Port Status :"; + cout << port_status <<endl; + + + + + + + + if(port_status == 1) + { + //start communication command depending on device --> startFESCommunication() ; startTACTILITYCommunication() ; startCommunication(std::string &prototipeName) + std::string start_communication = serial.startFESCommunication(); + cout << "start_communication : " + start_communication << endl; + + std::string setStimulationOn = serial.setStimulationOn(); + cout << "setStimulationOn : " << setStimulationOn << endl; + + std::string setStimulationOff = serial.setStimulationOff(); + cout << "setStimulationOff : " << setStimulationOff << endl; + + + //the virtual electrode need to be configured previous to it stimulation using setVirtualElectrodeOld or setVirtualElectrode functions + std::string virtual_electrode_number = "10"; + std::string virtual_electrode_name = "test"; + std::vector<int> virtual_electrode_cathodes; + virtual_electrode_cathodes.push_back(1); + std::vector<int> virtual_electrode_anodes; + virtual_electrode_anodes.push_back(2); + std::vector<double> virtual_electrode_amplitudes; + virtual_electrode_amplitudes.push_back(2.3); + std::vector<int> virtual_electrode_widths; + virtual_electrode_widths.push_back(300); + boolean selection = true; + boolean synchronous = false; + + std::string setVirtualElectrodeOld = serial.setVirtualElectrodeOld(virtual_electrode_number, virtual_electrode_name, virtual_electrode_cathodes, virtual_electrode_anodes, virtual_electrode_amplitudes, virtual_electrode_widths, selection, synchronous); + cout << "setVirtualElectrodeOld : " + setVirtualElectrodeOld << endl; + + + std::string namevelec = "test"; + std::string setStimulationVirtualElectrode = serial.setStimulationVirtualElectrode(namevelec); + cout << "setStimulationVirtualElectrode : " + setStimulationVirtualElectrode << endl; + + std::string getTic = serial.getTic(); + cout << "getTic: " << getTic << endl; + + std::string getvirtual_electrode_number = "10"; + std::string getVirtualElectrode = serial.getVirtualElectrode(getvirtual_electrode_number); + cout << "getVirtualElectrode :" + getVirtualElectrode << endl; + + std::string setvirtual_electrode_number = "11"; + std::string setvirtual_electrode_name = "test2"; + std::vector<int> setvirtual_electrode_cathodes = {4,5}; + std::vector<int> setvirtual_electrode_anodes = {8}; + std::vector<CathodeAmplitude> setvirtual_electrode_amplitudes; + CathodeAmplitude cathodeamplitude1 = {"4",2.3}; + CathodeAmplitude cathodeamplitude2 = {"5",2.4}; + setvirtual_electrode_amplitudes.push_back(cathodeamplitude1); + setvirtual_electrode_amplitudes.push_back(cathodeamplitude2); + std::vector<CathodeWidth> setvirtual_electrode_widths; + CathodeWidth cathodewidth1 = {"4",300}; + CathodeWidth cathodewidth2 = {"5",200}; + setvirtual_electrode_widths.push_back(cathodewidth1); + setvirtual_electrode_widths.push_back(cathodewidth2); + std::string setselection = "1"; + std::string setsynchronous = "0"; + + std::string setVirtualElectrode = serial.setVirtualElectrode(setvirtual_electrode_number, setvirtual_electrode_name, setvirtual_electrode_cathodes, setvirtual_electrode_anodes, setvirtual_electrode_amplitudes, setvirtual_electrode_widths, setselection, setsynchronous); + cout << "setVirtualElectrode :" + setVirtualElectrode << endl; + + std::string selectionvirtual_electrode_number = "11"; + bool selection_setselection = 0; + std::string setVirtualElectrodeSelection = serial.setVirtualElectrodeSelection(selectionvirtual_electrode_number, selection_setselection); + cout << "setVirtualElectrodeSelection :" + setVirtualElectrodeSelection << endl; + + std::string pattern_number = "11"; + std::string getPattern = serial.getPattern(pattern_number); + cout << "getPattern : " << getPattern << endl; + + std::string clearPattern = serial.clearPattern(pattern_number); + cout << "clearPattern : " << clearPattern << endl; + + vector<Pattern> patterns; + Pattern pattern1; + pattern1.amp = "CONST"; + pattern1.pw = "CONST"; + pattern1.r = "R"; + pattern1.ampval = 100; + pattern1.pwval = 100; + pattern1.time = 100; + Pattern pattern2; + pattern2.amp = "CONST"; + pattern2.pw = "CONST"; + pattern2.r = "R"; + pattern2.ampval = 100; + pattern2.pwval = 100; + pattern2.time = 100; + + patterns.push_back(pattern1); + patterns.push_back(pattern2); + + std::string setPattern = serial.setPattern(pattern_number,patterns); + cout << "setPattern : " << setPattern << endl; + + + std::string getHighVoltage = serial.getHighVoltage(); + cout << "getHighVoltage : " << getHighVoltage << endl; + + std::string setHighVoltageOn = serial.setHighVoltageOn(); + cout << "setHighVoltageOn : " << setHighVoltageOn << endl; + + std::string setHighVoltageOff = serial.setHighVoltageOff(); + cout << "setHighVoltageOff : " << setHighVoltageOff << endl; + + std::string hv = "150"; + std::string setHighVoltageValue = serial.setHighVoltageValue(hv); + cout << "setHighVoltageValue : " << setHighVoltageValue << endl; + + std::string getApplication = serial.getApplication(); + cout << "getApplication :" + getApplication << endl; + + //set application depending on device --> setFESApplication() ; setTACTILITYApplication() + std::string setFESApplication = serial.setFESApplication(); + cout << "setFESApplication :" + setFESApplication << endl; + + std::string getDeviceName = serial.getDeviceName(); + cout << "getDeviceName : " << getDeviceName << endl; + + std::string device = "new_name"; + std::string setDeviceName = serial.setDeviceName(device); + cout << "setDeviceName : " << setDeviceName << endl; + + std::string getFirmware = serial.getFirmware(); + cout << "getFirmware : " << getFirmware << endl; + + std::string getHardware = serial.getHardware(); + cout << "getHardware : " << getHardware << endl; + + std::string getSDPartternsFolder = serial.getSDPartternsFolder(); + cout << "getSDPartternsFolder : " << getSDPartternsFolder << endl; + + std::string sd_patternfolder = "new_folder"; + std::string setSDPartternsFolder = serial.setSDPartternsFolder(sd_patternfolder); + cout << "setSDPartternsFolder : " << setSDPartternsFolder << endl; + + std::string getFrequency = serial.getFrequency(); + cout << "getFrequency : " << getFrequency << endl; + + std::string set_frequency = "1000"; + std::string setFrequency = serial.setFrequency(set_frequency); + cout << "setFrequency : " << setFrequency << endl; + + std::string getPulsesInterval = serial.getPulsesInterval(); + cout << "getPulsesInterval : " << getPulsesInterval << endl; + + std::string set_interval = "300"; + std::string setPulsesInterval = serial.setPulsesInterval(set_interval); + cout << "setPulsesInterval : " << setPulsesInterval << endl; + + std::string getLogevents = serial.getLogevents(); + cout << "getLogevents : " << getLogevents << endl; + + std::string setLogeventsOn = serial.setLogeventsOn(); + cout << "setLogeventsOn : " << setLogeventsOn << endl; + + std::string setLogeventsOff = serial.setLogeventsOff(); + cout << "setLogeventsOff : " << setLogeventsOff << endl; + + std::string getSDUserFolder = serial.getSDUserFolder(); + cout << "getSDUserFolder : " << getSDUserFolder << endl; + + std::string sd_userfolder = "user_folder"; + std::string setSDUserFolder = serial.setSDUserFolder(sd_userfolder); + cout << "setSDUserFolder : " << setSDUserFolder << endl; + + std::string getBattery = serial.getBattery(); + cout << "getBattery : " << getBattery << endl; + + std::string getPulseVoltages = serial.getPulseVoltages(); + cout << "getPulseVoltages :" + getPulseVoltages << endl; + + std::string getPulseIntensities = serial.getPulseIntensities(); + cout << "getPulseIntensities :" + getPulseIntensities << endl; + + std::string getPulseNegativeVoltages = serial.getPulseNegativeVoltages(); + cout << "getPulseNegativeVoltages :" + getPulseNegativeVoltages << endl; + + std::string getPulsePositiveVoltages = serial.getPulsePositiveVoltages(); + cout << "getPulsePositiveVoltages :" + getPulsePositiveVoltages << endl; + + std::string getPulseAverageIntensity = serial.getPulseAverageIntensity(); + cout << "getPulseAverageIntensity :" + getPulseAverageIntensity << endl; + + std::string setAcquisitionOn = serial.setAcquisitionOn(); + cout << "setAcquisitionOn :" + setAcquisitionOn << endl; + + std::string setAcquisitionOff = serial.setAcquisitionOff(); + cout << "setAcquisitionOff :" + setAcquisitionOff << endl; + + + std::vector<int> acquisition_channels; + acquisition_channels.push_back(3); + acquisition_channels.push_back(12); + acquisition_channels.push_back(1); + acquisition_channels.push_back(7); + int frequencyconfig= 500; + std::string type = "bipolar"; + int gain= 2; + + std::string setAcquisitionConfiguraton = serial.setAcquisitionConfiguraton(acquisition_channels, frequencyconfig, type, gain); + cout << "setAcquisitionConfiguraton :" + setAcquisitionConfiguraton << endl; + + std::string setAcquisitionTest = serial.setAcquisitionTest(); + cout << "setAcquisitionTest :" + setAcquisitionTest << endl; + + std::string setAcquisitionNormal = serial.setAcquisitionNormal(); + cout << "setAcquisitionNormal :" + setAcquisitionNormal << endl; + + std::string setAcquisitionStreamOn = serial.setAcquisitionStreamOn(); + cout << "setAcquisitionStreamOn :" + setAcquisitionStreamOn << endl; + + std::string setAcquisitionStreamOff = serial.setAcquisitionStreamOff(); + cout << "setAcquisitionStreamOff :" + setAcquisitionStreamOff << endl; + + std::string setAcquisitionImpedanceOn = serial.setAcquisitionImpedanceOn(); + cout << "setAcquisitionImpedanceOn :" + setAcquisitionImpedanceOn << endl; + + std::string setAcquisitionImpedanceOff = serial.setAcquisitionImpedanceOff(); + cout << "setAcquisitionImpedanceOff :" + setAcquisitionImpedanceOff << endl; + + std::string setAcquisitionImpedanceChannelsPositive = serial.setAcquisitionImpedanceChannelsPositive(); + cout << "setAcquisitionImpedanceChannelsPositive :" + setAcquisitionImpedanceChannelsPositive << endl; + + std::string setAcquisitionImpedanceChannelsNegative = serial.setAcquisitionImpedanceChannelsNegative(); + cout << "setAcquisitionImpedanceChannelsNegative :" + setAcquisitionImpedanceChannelsNegative << endl; + + std::string setAcquisitionLeadoffOn = serial.setAcquisitionLeadoffOn(); + cout << "setAcquisitionLeadoffOn :" + setAcquisitionLeadoffOn << endl; + + std::string setAcquisitionLeadoffOff = serial.setAcquisitionLeadoffOff(); + cout << "setAcquisitionLeadoffOff :" + setAcquisitionLeadoffOff << endl; + + std::string current_acqleadoff = "6uA"; + std::string setAcquisitionLeadoffConfiguration = serial.setAcquisitionLeadoffConfiguration(current_acqleadoff); + cout << "setAcquisitionLeadoffConfiguration :" + setAcquisitionLeadoffConfiguration << endl; + + std::string getStimulationTime = serial.getStimulationTime(); + cout << "getStimulationTime : " << getStimulationTime << endl; + + std::string getBuzzerTempo = serial.getBuzzerTempo(); + cout << "getBuzzerTempo : " << getBuzzerTempo << endl; + + std::string buzzertempo = "25"; + std::string setBuzzerTempo = serial.setBuzzerTempo(buzzertempo); + cout << "setBuzzerTempo: " << setBuzzerTempo << endl; + + //std::string playBuzzer = serial.playBuzzer(); + //cout << "playBuzzer : " << playBuzzer << endl; + + std::string showLogErrors = serial.showLogErrors(); + cout << "showLogErrors : " << showLogErrors << endl; + + std::string createLogFile = serial.createLogFile(); + cout << "createLogFile : " << createLogFile << endl; + + std::string closeLogFile = serial.closeLogFile(); + cout << "closeLogFile : " << closeLogFile << endl; + + std::string getRTC = serial.getRTC(); + cout << "getRTC : " << getRTC << endl; + + //std::string date = "02-25-2022"; + //std::string setRTCDate = serial.setRTCDate(date); + //cout << "setRTCDate : " << setRTCDate << endl; + + //std::string time = "10:00:00"; + //std::string setRTCTime = serial.setRTCTime(time); + //cout << "setRTCTime : " << setRTCTime << endl; + + + std::string ping = serial.ping(); + cout << "ping : " + ping << endl; + + std::string help = serial.getHelp(); + cout << "Help : " + help << endl; + + std::string shutDown = serial.shutDown(); + cout << "shutDown : " << shutDown << endl; + + serial.CloseSerialPort(); + } + + return 0; + +} \ No newline at end of file diff --git a/serial_port_class_api/wrappers/CLASS_SerialPort.i b/serial_port_class_api/wrappers/CLASS_SerialPort.i new file mode 100644 index 0000000000000000000000000000000000000000..a94feda4dd62c58af8f3410a6043f8efc1eb0da1 --- /dev/null +++ b/serial_port_class_api/wrappers/CLASS_SerialPort.i @@ -0,0 +1,21 @@ +%module CLASS_SerialPortModule + +%include <std_string.i> +%include <std_vector.i> +%include <typemaps.i> +%apply const std::string & {std::string &}; + +%template(VectorOfDoubles) std::vector<double>; +%template(VectorOfInts) std::vector<int>; + +%{ + #include "../../include/CLASS_SerialPort.h" + #include "../../include/CLASS_structures.hpp" +%} + +%include "../include/CLASS_SerialPort.h" +%include "../include/CLASS_structures.hpp" + +%template(VectorOfPatterns) std::vector<Pattern>; +%template(VectorOfCathodeAmplitudes) std::vector<CathodeAmplitude>; +%template(VectorOfCathodeWidths) std::vector<CathodeWidth>; \ No newline at end of file diff --git a/src/.gitkeep b/src/.gitkeep deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt deleted file mode 100644 index 2d4f8dfecf7fc11c0bdf3cac6c073f413a5c5e67..0000000000000000000000000000000000000000 --- a/src/CMakeLists.txt +++ /dev/null @@ -1,205 +0,0 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 3.14) -project (class_api_wrappers) -message("cmake ${PROJECT_NAME}") - -CMAKE_MINIMUM_REQUIRED(VERSION 2.6) -project (class_api) -message("cmake ${PROJECT_NAME}") -message("Cmake version: ${CMAKE_VERSION}") - -if (WIN32) - set ( CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/class_api_install_win" CACHE PATH "Install dir" FORCE) -else() - set ( CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/class_api_install_linux" CACHE PATH "Install dir" FORCE) -endif() - -############################################# -# handlng compilation fields -if (CMAKE_VERSION VERSION_LESS "3.1") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") -else () - set (CMAKE_CXX_STANDARD 11) -endif () - -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fPIC") -if(UNIX) - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra") -endif() - -# see https://svn.boost.org/trac10/ticket/12974?replyto=description -if (WIN32) - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_WIN32_WINNT=0x0A00") -endif() -message("CMAKE_CXX_FLAGS: ${CMAKE_CXX_FLAGS}") - - -if (CMAKE_VERSION VERSION_LESS 3.2) - set(UPDATE_DISCONNECTED_IF_AVAILABLE "") -else() - set(UPDATE_DISCONNECTED_IF_AVAILABLE "UPDATE_DISCONNECTED 1") -endif() - - -set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pthread") -############################################# -# get the name of the host machine -site_name(hostname) -message ("Compiling on machine ${hostname}") - -############################################# -# get the 32 / 64 flag of the compiler used -MESSAGE( STATUS "CMAKE_GENERATOR: ${CMAKE_GENERATOR}") -MESSAGE( STATUS "CMAKE_GENERATOR_PLATFORM: ${CMAKE_GENERATOR_PLATFORM}") -MESSAGE( STATUS "CMAKE_SIZEOF_VOID_P: ${CMAKE_SIZEOF_VOID_P}") - -if (WIN32) - #some versions of cmake do not fill CMAKE_GENERATOR_PLATFORM - if (CMAKE_GENERATOR_PLATFORM STREQUAL "") - STRING( FIND ${CMAKE_GENERATOR} "64" APOSITION ) - else (CMAKE_GENERATOR_PLATFORM STREQUAL "") - STRING( FIND ${CMAKE_GENERATOR_PLATFORM} "64" APOSITION ) - endif (CMAKE_GENERATOR_PLATFORM STREQUAL "") - - #MESSAGE( STATUS "Position of character '64' ${CMAKE_GENERATOR_PLATFORM} in is ${APOSITION}" ) - if(${APOSITION} EQUAL -1) - MESSAGE( "32 bits compiler detected using CMAKE_GENERATOR_PLATFORM" ) - SET( EX_PLATFORM 32 ) - else() - MESSAGE( "64 bits compiler detected using CMAKE_GENERATOR_PLATFORM" ) - SET( EX_PLATFORM 64 ) - endif() -else (WIN32) - if( CMAKE_SIZEOF_VOID_P EQUAL 8 ) - MESSAGE( "64 bits compiler detected using CMAKE_SIZEOF_VOID_P" ) - SET( EX_PLATFORM 64 ) - else( CMAKE_SIZEOF_VOID_P EQUAL 8 ) - MESSAGE( "32 bits compiler detected using CMAKE_SIZEOF_VOID_P" ) - SET( EX_PLATFORM 32 ) - endif( CMAKE_SIZEOF_VOID_P EQUAL 8 ) -endif (WIN32) - -if (WIN32) - set_property(GLOBAL PROPERTY USE_FOLDERS ON) - - if( ${hostname} MATCHES "WKM0255A") - set(BOOST_ROOT "C:/local/boost_1_63_0") - endif( ${hostname} MATCHES "WKM0255A") - - # based on the defined variables, we extend def for 32/64 version - # Boost - if ( EX_PLATFORM EQUAL 32) - set(BOOST_LIBRARYDIR ${BOOST_ROOT}/lib32-msvc-14.0/) - else ( EX_PLATFORM EQUAL 32) - set(BOOST_LIBRARYDIR ${BOOST_ROOT}/lib64-msvc-14.0/) - endif ( EX_PLATFORM EQUAL 32) - -endif (WIN32) - - -############################################# -# Boost management -if (UNIX) - # Dynamic libraries are used. - set(BOOST_INCLUDEDIR ${BOOST_ROOT}) - set(Boost_USE_STATIC_LIBS OFF) - set(Boost_USE_MULTITHREADED ON) - set(Boost_USE_STATIC_RUNTIME OFF) - add_definitions(-DBOOST_ALL_DYN_LINK ) - add_definitions(-DBOOST_LOG_DYNLINK) -else (UNIX) - # Static libraries are used. - set(BOOST_INCLUDEDIR ${BOOST_ROOT}) - set(Boost_USE_STATIC_LIBS ON) - set(Boost_MULTITHREADED ON) -endif (UNIX) - -message("Boost reference repository set to: ${BOOST_ROOT}") -message("Boost Library dir: ${BOOST_LIBRARYDIR}") -find_package(Boost 1.63.0 REQUIRED COMPONENTS log log_setup thread program_options system date_time chrono regex atomic unit_test_framework filesystem) - -############################################# -# yaml-cpp management - -include(DownloadProject.cmake) - -if (UNIX) - download_project(PROJ yaml-cpp - GIT_REPOSITORY https://github.com/jbeder/yaml-cpp.git - GIT_TAG yaml-cpp-0.6.3 - ${UPDATE_DISCONNECTED_IF_AVAILABLE} - ) -endif (UNIX) - -if (WIN32) - if(MSVC_VERSION LESS_EQUAL 1900) - download_project(PROJ yaml-cpp - GIT_REPOSITORY https://github.com/jbeder/yaml-cpp.git - GIT_TAG yaml-cpp-0.6.3 - ${UPDATE_DISCONNECTED_IF_AVAILABLE} - ) - else (MSVC_VERSION LESS_EQUAL 1900) - #2017 requires master branch - download_project(PROJ yaml-cpp - GIT_REPOSITORY https://github.com/jbeder/yaml-cpp.git - GIT_TAG yaml-cpp-0.7.0 - ${UPDATE_DISCONNECTED_IF_AVAILABLE} - ) - endif (MSVC_VERSION LESS_EQUAL 1900) -endif (WIN32) - -message("Check: ${yaml-cpp_SOURCE_DIR} ${yaml-cpp_BINARY_DIR}") -set(YAML_CPP_BUILD_TESTS OFF) -add_subdirectory(${yaml-cpp_SOURCE_DIR} ${yaml-cpp_BINARY_DIR}) - - -message("Check") -message ("is it found?") -if (yaml-cpp_FOUND) - message("yaml-cpp is found!!!") - message("YAML_CPP_INCLUDE_DIR= ${YAML_CPP_INCLUDE_DIR}") - message("YAML_CPP_LIBRARIES= ${YAML_CPP_LIBRARIES}") - message("YAML_CPP_LIBRARY_DIRS= ${YAML_CPP_LIBRARY_DIRS}") - -else(yaml-cpp_FOUND) - message("yaml-cpp not found") -endif(yaml-cpp_FOUND) - -set(YAML_INCLUDE_DIR ${yaml-cpp_SOURCE_DIR}/include) -message ("YAML_INCLUDE_DIR= ${YAML_INCLUDE_DIR}") - -message("yaml static: ${YAML_CPP_LIBRARIES_STATIC}") -message("yaml shared: ${YAML_CPP_LIBRARIES_SHARED}") - -SET(LINKLIBS ${Boost_LIBRARIES} ${YAML_CPP_LIBRARIES_SHARED}) - -#option(BUILD_PYTHON "Build Python Library" ON) -if (WIN32) - option(BUILD_DOTNET "Build .NET Library" ON) -endif (WIN32) - -add_subdirectory(yaml_tools) -add_subdirectory(logger) -add_subdirectory(communication) -add_subdirectory(filter) -add_subdirectory(class_server) -add_subdirectory(api) -add_subdirectory(wrappers) -add_subdirectory(tests) - -option(BUILD_DOC "Build documentation" ON) -message(STATUS "Build documentation: ${BUILD_DOC}") -if (BUILD_DOC) - add_subdirectory(docs) -endif() - -INCLUDE(pandocology.cmake) - -add_document( - TARGET documentation - OUTPUT_FILE README.html - SOURCES README.md -) - -install(FILES ${CMAKE_BINARY_DIR}/README.html DESTINATION ./) -file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/docs/images/sw_arch.png DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/docs/images) -file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/docs/images/tecnalia.jpg DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/docs/images) \ No newline at end of file diff --git a/src/DownloadProject.CMakeLists.cmake.in b/src/DownloadProject.CMakeLists.cmake.in deleted file mode 100644 index d5739292e9fa26a03b38cf092f2f71ef4b87704a..0000000000000000000000000000000000000000 --- a/src/DownloadProject.CMakeLists.cmake.in +++ /dev/null @@ -1,18 +0,0 @@ -# Distributed under the OSI-approved MIT License. See accompanying -# file LICENSE or https://github.com/Crascit/DownloadProject for details. - -cmake_minimum_required(VERSION 2.8.2) - -project(${DL_ARGS_PROJ}-download NONE) -message("Check cmake in ${DL_ARGS_UNPARSED_ARGUMENTS}") -include(ExternalProject) -ExternalProject_Add(${DL_ARGS_PROJ}-download - ${DL_ARGS_UNPARSED_ARGUMENTS} - SOURCE_DIR "${DL_ARGS_SOURCE_DIR}" - BINARY_DIR "${DL_ARGS_BINARY_DIR}" - CONFIGURE_COMMAND "" - BUILD_COMMAND "" - INSTALL_COMMAND "" - TEST_COMMAND "" - CMAKE_ARGS -DYAML_CPP_BUILD_TESTS=OFF -) \ No newline at end of file diff --git a/src/DownloadProject.cmake b/src/DownloadProject.cmake deleted file mode 100644 index 1709e09adcc61b147cc8f55c3c6cdc8761ea2f49..0000000000000000000000000000000000000000 --- a/src/DownloadProject.cmake +++ /dev/null @@ -1,182 +0,0 @@ -# Distributed under the OSI-approved MIT License. See accompanying -# file LICENSE or https://github.com/Crascit/DownloadProject for details. -# -# MODULE: DownloadProject -# -# PROVIDES: -# download_project( PROJ projectName -# [PREFIX prefixDir] -# [DOWNLOAD_DIR downloadDir] -# [SOURCE_DIR srcDir] -# [BINARY_DIR binDir] -# [QUIET] -# ... -# ) -# -# Provides the ability to download and unpack a tarball, zip file, git repository, -# etc. at configure time (i.e. when the cmake command is run). How the downloaded -# and unpacked contents are used is up to the caller, but the motivating case is -# to download source code which can then be included directly in the build with -# add_subdirectory() after the call to download_project(). Source and build -# directories are set up with this in mind. -# -# The PROJ argument is required. The projectName value will be used to construct -# the following variables upon exit (obviously replace projectName with its actual -# value): -# -# projectName_SOURCE_DIR -# projectName_BINARY_DIR -# -# The SOURCE_DIR and BINARY_DIR arguments are optional and would not typically -# need to be provided. They can be specified if you want the downloaded source -# and build directories to be located in a specific place. The contents of -# projectName_SOURCE_DIR and projectName_BINARY_DIR will be populated with the -# locations used whether you provide SOURCE_DIR/BINARY_DIR or not. -# -# The DOWNLOAD_DIR argument does not normally need to be set. It controls the -# location of the temporary CMake build used to perform the download. -# -# The PREFIX argument can be provided to change the base location of the default -# values of DOWNLOAD_DIR, SOURCE_DIR and BINARY_DIR. If all of those three arguments -# are provided, then PREFIX will have no effect. The default value for PREFIX is -# CMAKE_BINARY_DIR. -# -# The QUIET option can be given if you do not want to show the output associated -# with downloading the specified project. -# -# In addition to the above, any other options are passed through unmodified to -# ExternalProject_Add() to perform the actual download, patch and update steps. -# The following ExternalProject_Add() options are explicitly prohibited (they -# are reserved for use by the download_project() command): -# -# CONFIGURE_COMMAND -# BUILD_COMMAND -# INSTALL_COMMAND -# TEST_COMMAND -# -# Only those ExternalProject_Add() arguments which relate to downloading, patching -# and updating of the project sources are intended to be used. Also note that at -# least one set of download-related arguments are required. -# -# If using CMake 3.2 or later, the UPDATE_DISCONNECTED option can be used to -# prevent a check at the remote end for changes every time CMake is run -# after the first successful download. See the documentation of the ExternalProject -# module for more information. It is likely you will want to use this option if it -# is available to you. Note, however, that the ExternalProject implementation contains -# bugs which result in incorrect handling of the UPDATE_DISCONNECTED option when -# using the URL download method or when specifying a SOURCE_DIR with no download -# method. Fixes for these have been created, the last of which is scheduled for -# inclusion in CMake 3.8.0. Details can be found here: -# -# https://gitlab.kitware.com/cmake/cmake/commit/bdca68388bd57f8302d3c1d83d691034b7ffa70c -# https://gitlab.kitware.com/cmake/cmake/issues/16428 -# -# If you experience build errors related to the update step, consider avoiding -# the use of UPDATE_DISCONNECTED. -# -# EXAMPLE USAGE: -# -# include(DownloadProject) -# download_project(PROJ googletest -# GIT_REPOSITORY https://github.com/google/googletest.git -# GIT_TAG master -# UPDATE_DISCONNECTED 1 -# QUIET -# ) -# -# add_subdirectory(${googletest_SOURCE_DIR} ${googletest_BINARY_DIR}) -# -#======================================================================================== - - -set(_DownloadProjectDir "${CMAKE_CURRENT_LIST_DIR}") - -include(CMakeParseArguments) - -function(download_project) - - set(options QUIET) - set(oneValueArgs - PROJ - PREFIX - DOWNLOAD_DIR - SOURCE_DIR - BINARY_DIR - # Prevent the following from being passed through - CONFIGURE_COMMAND - BUILD_COMMAND - INSTALL_COMMAND - TEST_COMMAND - ) - set(multiValueArgs "") - - cmake_parse_arguments(DL_ARGS "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) - - # Hide output if requested - if (DL_ARGS_QUIET) - set(OUTPUT_QUIET "OUTPUT_QUIET") - else() - unset(OUTPUT_QUIET) - message(STATUS "Downloading/updating ${DL_ARGS_PROJ}") - endif() - - # Set up where we will put our temporary CMakeLists.txt file and also - # the base point below which the default source and binary dirs will be. - # The prefix must always be an absolute path. - if (NOT DL_ARGS_PREFIX) - set(DL_ARGS_PREFIX "${CMAKE_BINARY_DIR}") - else() - get_filename_component(DL_ARGS_PREFIX "${DL_ARGS_PREFIX}" ABSOLUTE - BASE_DIR "${CMAKE_CURRENT_BINARY_DIR}") - endif() - if (NOT DL_ARGS_DOWNLOAD_DIR) - set(DL_ARGS_DOWNLOAD_DIR "${DL_ARGS_PREFIX}/${DL_ARGS_PROJ}-download") - endif() - - # Ensure the caller can know where to find the source and build directories - if (NOT DL_ARGS_SOURCE_DIR) - set(DL_ARGS_SOURCE_DIR "${DL_ARGS_PREFIX}/${DL_ARGS_PROJ}-src") - endif() - if (NOT DL_ARGS_BINARY_DIR) - set(DL_ARGS_BINARY_DIR "${DL_ARGS_PREFIX}/${DL_ARGS_PROJ}-build") - endif() - set(${DL_ARGS_PROJ}_SOURCE_DIR "${DL_ARGS_SOURCE_DIR}" PARENT_SCOPE) - set(${DL_ARGS_PROJ}_BINARY_DIR "${DL_ARGS_BINARY_DIR}" PARENT_SCOPE) - - # The way that CLion manages multiple configurations, it causes a copy of - # the CMakeCache.txt to be copied across due to it not expecting there to - # be a project within a project. This causes the hard-coded paths in the - # cache to be copied and builds to fail. To mitigate this, we simply - # remove the cache if it exists before we configure the new project. It - # is safe to do so because it will be re-generated. Since this is only - # executed at the configure step, it should not cause additional builds or - # downloads. - file(REMOVE "${DL_ARGS_DOWNLOAD_DIR}/CMakeCache.txt") - - # Create and build a separate CMake project to carry out the download. - # If we've already previously done these steps, they will not cause - # anything to be updated, so extra rebuilds of the project won't occur. - # Make sure to pass through CMAKE_MAKE_PROGRAM in case the main project - # has this set to something not findable on the PATH. - configure_file("${_DownloadProjectDir}/DownloadProject.CMakeLists.cmake.in" - "${DL_ARGS_DOWNLOAD_DIR}/CMakeLists.txt") - execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" - -D "CMAKE_MAKE_PROGRAM:FILE=${CMAKE_MAKE_PROGRAM}" - . - RESULT_VARIABLE result - ${OUTPUT_QUIET} - WORKING_DIRECTORY "${DL_ARGS_DOWNLOAD_DIR}" - ) - if(result) - message(FATAL_ERROR "CMake step for ${DL_ARGS_PROJ} failed: ${result}") - endif() - execute_process(COMMAND ${CMAKE_COMMAND} --build . - RESULT_VARIABLE result - ${OUTPUT_QUIET} - WORKING_DIRECTORY "${DL_ARGS_DOWNLOAD_DIR}" - ) - if(result) - message(FATAL_ERROR "Build step for ${DL_ARGS_PROJ} failed: ${result}") - endif() - -endfunction() \ No newline at end of file diff --git a/src/README.md b/src/README.md deleted file mode 100644 index 777eea6b87115f42d761a6b9c923814231e232fe..0000000000000000000000000000000000000000 --- a/src/README.md +++ /dev/null @@ -1,49 +0,0 @@ -This folder contains all the needed components to write and run applications which are able to interchange messages with a CLASS_DEVICE. It is structured as follows: - -* [class_server](./class_server): this folder contains the executable of the CLASS_SERVER. -* [class_api](./api): it contains the files needed for programming clients which communicates with a CLASS_DEVICE. - -# CLASS_SW ARCHITECTURE -The CLASS_SW is divided in two parts: CLASS_SERVER and CLASS_CLIENT. The CLASS_SERVER connects to the CLASS_DEVICE via Bluetooth (BT) and allows a CLASS_CLIENT for interacting with it. The CLASS_SERVER and the CLASS_CLIENT could be in the same or different host and the communication between them is through UDP. The CLASS_CLIENT applications will make use of the provided CLASS_API in order to connect to the CLASS_SERVER and be able to send commands to CLASS_DEVICE and receive messages from it. - -<p align="center"> - <img width="600" height="300" src="./docs/images/SW_arch.png" alt="SW Architecture"> -</p> - ->NOTE: CLASS_SW components have been programmed to be cross-platform (Windows and Linux). However, they have been only tested on Windows for the moment. - -## CLASS_SERVER -It is an standalone application. It acepts two arguments: -* the COM port of the CLASS device to connect with -* the port where it will listen for client connections. - -It must be run before any client application. The CLASS_DEVICE should have been paired beforehand. - -The CLASS_SERVER is currently available for Windows and Linux. The executable for launching it is located in [class_server](./class_server/Release) folder. The following commands illustrate how to run it for both Windows and Linux: - -``` -# The CLASS_DEVICE is assigned to COM14 and the CLASS_SERVER will listen to CLASS_CLIENTs on port 50000 - -# windows -class_server.exe COM14 50000 - -# linux -./class_server COM14 50000 -``` - -## CLASS_CLIENT -A CLASS_CLIENT is an appplication which wants to send/receive messages to/from a CLASS_DEVICE. For that it must make use of the CLASS_API. There are some client examples in [examples](../src/class_server/src/) folder. - -# CLASS_API -The API has been developed to be used from different languages. More information can be found in this [link](./docs/doc_doxygen/html/index.html). - -<hr> -<p align="center"> - <a href="https://www.tecnalia.com"> - <img width="200" height="60" src="./docs/images/tecnalia.jpg" alt="Tecnalia"> - </a> -</p> -<p align="center"> -©Copyright 2021 Tecnalia -</p> - diff --git a/src/api/.gitkeep b/src/api/.gitkeep deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/src/api/CMakeLists.txt b/src/api/CMakeLists.txt deleted file mode 100644 index d3b7f0dd0774427681dddd28d804a70fb266ab8b..0000000000000000000000000000000000000000 --- a/src/api/CMakeLists.txt +++ /dev/null @@ -1,4 +0,0 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 2.6) -project (api) - -add_subdirectory(class) diff --git a/src/api/class/.gitkeep b/src/api/class/.gitkeep deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/src/api/class/CMakeLists.txt b/src/api/class/CMakeLists.txt deleted file mode 100644 index 93fd829158d990f34f0750f060ffbf0876ac49e3..0000000000000000000000000000000000000000 --- a/src/api/class/CMakeLists.txt +++ /dev/null @@ -1,71 +0,0 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 2.6) -project(class) -message("cmake: ${PROJECT_NAME}") - -if (DEBUG_CMAKE) - set(CMAKE_VERBOSE_MAKEFILE yes) -endif (DEBUG_CMAKE) - -find_package(PythonLibs REQUIRED) - -include_directories(include ${Boost_INCLUDE_DIRS} ${YAML_INCLUDE_DIR} ${PYTHON_INCLUDE_DIRS}) -link_directories(${Boost_LIBRARY_DIRS} ${YAML_CPP_LIBRARY_DIRS}) - -set(class_api_files - ${CMAKE_CURRENT_SOURCE_DIR}/src/class.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/src/class_core.cpp - #${CMAKE_CURRENT_SOURCE_DIR}/src/class_core.hpp -) - -include (GenerateExportHeader) - -add_library(class SHARED - ${class_api_files} - ${logger_files} - ${communication_files} - ${yaml_tools_files} - ${filter_files} -) - -GENERATE_EXPORT_HEADER (class - # BASE_NAME class - # EXPORT_MACRO_NAME class_EXPORT - EXPORT_FILE_NAME class/class_Export.h - # STATIC_DEFINE class_BUILT_AS_STATIC -) - -set_target_properties(class PROPERTIES FOLDER class) - -target_include_directories(class PUBLIC - ${logger_SOURCE_DIR}/include - ${communication_SOURCE_DIR}/include - ${yaml_tools_SOURCE_DIR}/include - ${filter_SOURCE_DIR}/include - ${PROJECT_SOURCE_DIR} -) - -add_dependencies(class yaml-cpp) -target_link_libraries(class yaml-cpp ${Boost_LIBRARIES} communication logger filter ${PYTHON_LIBRARIES}) - -target_link_libraries(class ${CMAKE_CURRENT_SOURCE_DIR}/../../commands.lib) - -target_include_directories(class PUBLIC ${CMAKE_CURRENT_BINARY_DIR}) - -# 'make install' to the correct location -install(TARGETS class - ARCHIVE DESTINATION class_api/lib/cpp - LIBRARY DESTINATION class_api/lib/cpp - RUNTIME DESTINATION class_api/lib/cpp) # This is for Windows -install(DIRECTORY include/ DESTINATION class_api/include) -install(FILES ${CMAKE_CURRENT_BINARY_DIR}/class/class_Export.h DESTINATION class_api/include/class) -if (WIN32) - install(FILES ${PYTHON_LIBRARIES}/../../python37.dll DESTINATION class_api/lib/cpp) -endif (WIN32) - -export(TARGETS class - logger - yaml_tools - yaml-cpp - communication - filter - FILE class_Config.cmake) \ No newline at end of file diff --git a/src/api/class/include/.gitkeep b/src/api/class/include/.gitkeep deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/src/api/class/include/class/.gitkeep b/src/api/class/include/class/.gitkeep deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/src/api/class/include/class/class.hpp b/src/api/class/include/class/class.hpp deleted file mode 100644 index 7aeeea98830a559adac864a6314a75050cbe1f45..0000000000000000000000000000000000000000 --- a/src/api/class/include/class/class.hpp +++ /dev/null @@ -1,539 +0,0 @@ -/** - * @file class.hpp - * @author Alfonso Dominguez <alfonso.dominguez@tecnalia.com> and Leire Querejeta Lomas <leire.querejeta@tecnalia.com> - * @date 2020 - * - * Copyright 2020 Tecnalia Research & Innovation. - * Distributed under the GNU GPL v3. - * For full terms see https://www.gnu.org/licenses/gpl.txt - * - * @brief Header with the API methods - */ - -#pragma once - -#include <string> -#include <vector> - -#include "class_structures.hpp" -#include "class_error.hpp" -#include "class_cb.hpp" - -#include <class/class_Export.h> - -// forward declaration -class ClassCore; - -//! default server port to connect to -const int DEFAULT_SERVER_PORT = 50000; -//! default server ip to connect to -const std::string DEFAULT_SERVER_IP = "127.0.0.1"; -//! default port on which class_server messages are listened to -const int DEFAULT_LOCAL_PORT = 50001; -//! default ip on which class_server messages are listened to -const std::string DEFAULT_LOCAL_IP = "127.0.0.1"; - -//! API main class -class CLASS_EXPORT Class -{ -public: - - //! Allowed acquisition rates - enum AcqFreq { - FREQ_250, ///< 250Hz - FREQ_500, ///< 500Hz - FREQ_1000, ///< 1000Hz - FREQ_2000, ///< 2000Hz - FREQ_4000, ///< 4000Hz - FREQ_8000 ///< 8000Hz - }; - - //! Mode for initialization - enum InitMode { - TACTILITY, ///< Tactility: low amplitude stimulators, and includes a special fw version, such as the command of "selected 0/1" - PAIN, ///< Pain: low amplitude stimulators, including small steps (0.1 steps) - DESKTOP, ///< Desktop: high amplitudes, with bigger steps (0.1 are not allowed, only 1 steps) - NEURORESEARCH, - ICARE, - TIB_ACQ, - TIB_STIM - }; - - //! Allowed channel numbers for acquisition - enum AcqCh { - CH_1, ///< 1 channel - CH_2, ///< 2 channels - CH_3, ///< 3 channels - CH_4, ///< 4 channels - CH_5, ///< 5 channels - CH_6, ///< 6 channels - CH_7, ///< 7 channels - CH_8, ///< 8 channels - CH_9, ///< 9 channels - CH_10, ///< 10 channels - CH_11, ///< 11 channels - CH_12, ///< 12 channels - CH_13, ///< 13 channels - CH_14, ///< 14 channels - CH_15, ///< 15 channels - CH_16 ///< 16 channels - }; - - //! Acquisition types - enum AcqImpedancePolarity { - TYPE_UNIPOLAR, ///< Unipolar - TYPE_BIPOLAR ///< Bipolar - }; - - //! Impedance acquisition sign - enum AcqImpedanceSign { - TYPE_POSITIVE, ///< Positives - TYPE_NEGATIVE ///< Negatives - }; - - //! Acquisition gain - enum AcqGain { - GAIN_1, ///< 1.0 - GAIN_2, ///< 2.0 - GAIN_4, ///< 4.0 - GAIN_8, ///< 8.0 - GAIN_12, ///< 12.0 - GAIN_24 ///< 24.0 - }; - - //! Acquisition Input - enum AcqInput { - NORMAL, ///< Normal - TEST ///< Test - }; - - //! Basic constructor - Class(); - //! Basic destructor - ~Class(); - - /*! - \brief Connect to the CLASS server - \return Integer indicating the success of the connection (0-success, <0 error) - */ - ClassError::Error connect(); - - /*! - \brief Connect to the CLASS server - \param server_ip IP to connect with. - \param server_port Port to connect with. - \return Integer indicating the success of the connection (0-success, <0 error) - */ - ClassError::Error connect(const std::string & server_ip, const int & server_port); - - /*! - \brief Connect to the CLASS server - \param server_ip IP to connect with. - \param server_port Port to connect with. - \param local_port Port which listens for msgs coming from CLASS server. - \return Integer indicating the success of the connection (0-success, <0 error) - */ - ClassError::Error connect(const std::string & server_ip, const int & server_port, const int & local_port); - - /*! - \brief Connect to the CLASS server - \param server_ip IP to connect with. - \param server_port Port to connect with. - \param local_ip IP which listens for msgs coming from CLASS server. - \param local_port Port which listens for msgs coming from CLASS server. - \return Integer indicating the success of the connection (0-success, <0 error) - */ - ClassError::Error connect(const std::string & server_ip, const int & server_port, const std::string & local_ip, const int & local_port); - - /*! - \brief Disconnect from CLASS server - \return Integer indicating the success of the disconnection (0-success, <0 error) - */ - ClassError::Error disconnect(); - - /*! - \brief get acquisition frames - \return Vector with acquisition frames - */ - std::vector<AcqFrame> getAcqFrames(); - - /*! - \brief get the level of the battery - \return Integer indicating the success of the process (0-success, <0 error) - */ - ClassError::Error getBattery(); - - /*! - \brief get buzzer - \return Integer indicating the success of the process (0-success, <0 error) - */ - ClassError::Error getBuzzer(); - - /*! - \brief get device name - \return Integer indicating the success of the process (0-success, <0 error) - */ - ClassError::Error getDeviceName(); - - /*! - \brief get the firmware version - \return Integer indicating the success of the process (0-success, <0 error) - */ - ClassError::Error getFirmware(); - - /*! - \brief get frequency - \return Integer indicating the success of the process (0-success, <0 error) - */ - ClassError::Error getFrequency(); - - /*! - \brief get the hardware version - \return Integer indicating the success of the process (0-success, <0 error) - */ - ClassError::Error getHardware(); - - /*! - \brief get high voltage - \return Integer indicating the success of the process (0-success, <0 error) - */ - ClassError::Error getHv(); - - /*! - \brief get interval - \return Integer indicating the success of the process (0-success, <0 error) - */ - ClassError::Error getInterval(); - - /*! - \brief get logevents - \return Integer indicating the success of the process (0-success, <0 error) - */ - ClassError::Error getLogevents(); - - /*! - \brief get pattern - \param number number of pattern - \return Integer indicating the success of the process (0-success, <0 error) - */ - ClassError::Error getPatternStatus(const int& number); - - - /*! - \brief get rtc - \return Integer indicating the success of the process (0-success, <0 error) - */ - ClassError::Error getRTC(); - - /*! - \brief get sd function - \return Integer indicating the success of the process (0-success, <0 error) - */ - ClassError::Error getSDFunction(); - - /*! - \brief get sd user name - \return Integer indicating the success of the process (0-success, <0 error) - */ - ClassError::Error getSDUName(); - - /*! - \brief get the tic - \return Integer indicating the success of the process (0-success, <0 error) - */ - ClassError::Error getTic(); - - /*! - \brief get virtual electrode - \param number of virtual electrode - \return Integer indicating the success of the process (0-success, <0 error) - */ - ClassError::Error getVelecStatus(const int& number); - - /*! - \brief Init communication - \return Integer indicating the success of the process (0-success, <0 error) - */ - ClassError::Error initCommunication(); - - /*! - \brief Init communication sending iam mode - \param mode Initialization mode. - \return Integer indicating the success of the process (0-success, <0 error) - */ - ClassError::Error initCommunication(const InitMode& mode); - - /*! - \brief Clear pattern - \param id pattern to delete - \return Integer indicating the success of the process (0-success, <0 error) - */ - ClassError::Error patternDelete(const int& id); - - /*! - \brief Sends custom command to CLASS device - \param cmd Command. - \return Integer indicating the success of the process (0-success, <0 error) - */ - ClassError::Error sendCustomCmd(const std::string& cmd); - - /*! - \brief Sets class acq configurations - \param frequency Frequency of acquisition. - \param channel_numbers Channel numbers. - \param gain Gain for the acquisition. - \param input Acq input type, normal or test. - \return Integer indicating the success of the setting process (0-success, <0 error) - */ - ClassError::Error setAcqConfig(const AcqFreq& frequency, const std::vector<int>& channel_numbers, const AcqGain& gain, const AcqInput& input); - - /*! - \brief Sets the config for impedance acquisition - \param type Impedance acquisition type. - \return Integer indicating the success of the setting process (0-success, <0 error) - */ - ClassError::Error setAcqImpedanceConfig(const AcqImpedanceSign& type); - - /*! - \brief Sets the polarity for impedance acquisition - \param type Polarity acquisition type. - \return Integer indicating the success of the setting process (0-success, <0 error) - */ - ClassError::Error setAcqImpedancePolarity(const AcqImpedancePolarity& polarity); - - /*! - \brief Sets class acq input to normal (bio signal captured from channels) - \return Integer indicating the success of the setting process (0-success, <0 error) - */ - ClassError::Error setAcqInputNormal(); - - /*! - \brief Sets class acq input to test. The class will provide a quadratic signal. It is useful for testing and not getting saturated signal all the time. - \return Integer indicating the success of the setting process (0-success, <0 error) - */ - ClassError::Error setAcqInputTest(); - - /*! - \brief Sets the order of the filter used for impedance calculation - \param order Filter order (>0). - \return Integer indicating the success of the setting process (0-success, <0 error) - */ - ClassError::Error setImpedanceFilterOrder(const int& order); - - /*! - \brief Sets the duration of the buffer (ms*frequency//1000.0) - \param ms Time in ms. - \return Integer indicating the success of the setting process (0-success, <0 error) - */ - ClassError::Error setBufferDuration(const double& ms); - - /*! - \brief Sets buzzer on - \return Integer indicating the success of the process (0-success, <0 error) - */ - ClassError::Error setbuzzerPlay(); - - /*! - \brief Sets ms of buzzer song - \param tempo time in ms - \return Integer indicating the success of the process (0-success, <0 error) - */ - ClassError::Error setbuzzerTempo(const std::string& tempo); - - /*! - \brief set the callback - \param callback Callback - \param language Language which has defined the callback - \return Integer indicating the success of the process (0-success, <0 error) - */ - ClassError::Error setCallback(ClassCallback * callback, std::string language); - - /*! - \brief Sets name of device - \param name name of the device. - \return Integer indicating the success of the process (0-success, <0 error) - */ - ClassError::Error setDevName(const std::string& devicename); - - /*! - \brief Sets electrode pads number - \param id Electrode number/ID. - \param pads_number Number of pads of the electrode. - \return Integer indicating the success of the process (0-success, <0 error) - */ - ClassError::Error setElecPads(const int& id, const int& pads_number); - - /*! - \brief Sets high voltage to off - \return Integer indicating the success of the process (0-success, <0 error) - */ - ClassError::Error sethvOff(); - - /*! - \brief Sets name of device - \param hvvalue name of the device. - \return Integer indicating the success of the process (0-success, <0 error) - */ - ClassError::Error sethvValue(const std::string& hvvalue); - - /*! - \brief Sets high voltage to on - \return Integer indicating the success of the process (0-success, <0 error) - */ - ClassError::Error sethvOn(); - - /*! - \brief Sets interval value - \param interval value of stimulation interl pulses interval - \return Integer indicating the success of the process (0-success, <0 error) - */ - ClassError::Error setintervalValue(const std::string& interval); - /*! - \brief Sets logevents to off - \return Integer indicating the success of the process (0-success, <0 error) - */ - ClassError::Error setlogeventsOff(); - /*! - \brief Sets logevents to on - \return Integer indicating the success of the process (0-success, <0 error) - */ - ClassError::Error setlogeventsOn(); - - /*! - \brief set pattern - \param id pattern number - \param pat vector of patterns - \return Integer indicating the success of the process (0-success, <0 error) - */ - ClassError::Error setPattern(const int& id, const std::vector<Pattern>& pat); - - /*! - \brief set name of sd card folder where the pattern are saved - \param sdfunctionname name of the folder - \return Integer indicating the success of the process (0-success, <0 error) - */ - ClassError::Error setSDFunctionName(const std::string& sdfunctionname); - - /*! - \brief set name of sdcard folder where the folder containing the patterns is saved - \param sduname name of the folder - \return Integer indicating the success of the process (0-success, <0 error) - */ - ClassError::Error setSDUName(const std::string& sduname); - - /*! - \brief Shutdown - \return Integer indicating the success of the process (0-success, <0 error) - */ - ClassError::Error setShutdown(); - /*! - \brief Sets electrode pads number - \param frequency Frequency of the stimulation. - \return Integer indicating the success of the process (0-success, <0 error) - */ - ClassError::Error setStimFreq(const double& frequency); - - /*! - \brief Sets rtc date - \param date mm/dd/yyyy format - \return Integer indicating the success of the process (0-success, <0 error) - */ - ClassError::Error setrtcDate(const std::string& rtcDate); - - /*! - \brief Sets rtc time - \param date hh:mm:ss format - \return Integer indicating the success of the process (0-success, <0 error) - */ - ClassError::Error setrtcTime(const std::string& rtcTime); - - /*! - \brief Sets virtual electrode - \param id Virtual electrode number/ID. - \param name Name of the virtual electrode. - \param electrode_id Electrode ID/number. - \param cathodes List of integers with the IDs of the pads acting as cathodes - \param anodes List of integers with the IDs of the pads acting as cathodes - \param amp List of doubles with the amplitude (in mA) associated to each of the cathodes. Must have the same length as cathodes - \param width List of integers with the pulse width (in uS) associated to each of the cathodes. Must have the same length as cathodes - \param selected Defines if the velec is selected (‘true’ value) or deselected (‘false’ value). Only selected velecs will be executed with a “stim on” command - \param sync Defines if the velec is synchronous (‘rtue’ value) or asynchronous (‘false’ value). - \return Integer indicating the success of the process (0-success, <0 error) - */ - ClassError::Error setVelec(const int& id, const std::string& name, const int& electrode_id, const std::vector<int>& cathodes, const std::vector<int>& anodes, const std::vector<double>& amp, const std::vector<int>& width, const bool& selected, const bool& sync); - - /*! - \brief Sets whether the virtual electrode is selected or not - \param id Virtual electrode number/ID. - \param selected Defines if the velec is selected (‘true’ value) or deselected (‘false’ value). Only selected velecs will be executed with a “stim on” command. - \return Integer indicating the success of the process (0-success, <0 error) - */ - ClassError::Error setVelecSelected(const int& id, const bool& selected); - - /*! - \brief Sets whether the virtual electrodes are selected or not - \param id Vector with virtual electrode numbers/IDs. - \param selected Vector with bool indicating whether the velecs are selected (‘true’ value) or deselected (‘false’ value). Only selected velecs will be executed with a “stim on” command. - \return Integer indicating the success of the process (0-success, <0 error) - */ - ClassError::Error setVelecsSelected(const std::vector<int>& id, const std::vector<bool>& selected); - - /*! - \brief Starts acquisition - \return Integer indicating the success of the process (0-success, <0 error) - */ - ClassError::Error startAcq(); - - /*! - \brief Starts acquisition stream - \return Integer indicating the success of the process (0-success, <0 error) - */ - ClassError::Error startAcqStream(); - - /*! - \brief Starts impedance acquisition - \return Integer indicating the success of the process (0-success, <0 error) - */ - ClassError::Error startImpedanceAcq(); - - /*! - \brief Starts stimulation - \return Integer indicating the success of the process (0-success, <0 error) - */ - ClassError::Error startStim(); - - /*! - \brief Start stimulation of the virtual electrode which name is passed as parameter - \param name Name of the virtual electrode. - \return Integer indicating the success of the process (0-success, <0 error) - */ - ClassError::Error stimVelec(const std::string& name); - - /*! - \brief Stops acquisition - \return Integer indicating the success of the process (0-success, <0 error) - */ - ClassError::Error stopAcq(); - - /*! - \brief Stops acquisition stream - \return Integer indicating the success of the process (0-success, <0 error) - */ - ClassError::Error stopAcqStream(); - - /*! - \brief Stops impedance acquisition - \return Integer indicating the success of the process (0-success, <0 error) - */ - ClassError::Error stopImpedanceAcq(); - - /*! - \brief Stops stimulation - \return Integer indicating the success of the process (0-success, <0 error) - */ - ClassError::Error stopStim(); - -private: - //! Core internal component - ClassCore * core_; -}; diff --git a/src/api/class/include/class/class_cb.hpp b/src/api/class/include/class/class_cb.hpp deleted file mode 100644 index c7e7f79fac69028cb949d0761124f54c4d1585c0..0000000000000000000000000000000000000000 --- a/src/api/class/include/class/class_cb.hpp +++ /dev/null @@ -1,115 +0,0 @@ -/** - * @file class_cb.hpp - * @author Alfonso Dominguez <alfonso.dominguez@tecnalia.com> and Leire Querejeta Lomas <leire.querejeta@tecnalia.com> - * @date 2020 - * - * Copyright 2020 Tecnalia Research & Innovation. - * Distributed under the GNU GPL v3. - * For full terms see https://www.gnu.org/licenses/gpl.txt - * - * @brief Callbacks for Class - */ - -#pragma once -#include <string> - -//! Abstract class (interface) for receiving callbacks from device. -class ClassCallback -{ -public: - - /*! - \brief Handle for battery status callbacks - \param battery Received battery percentage - */ - virtual void batteryHandle(double battery) = 0; - - /*! - \brief Handle for buzzer status callbacks - \param buzzerstatus Received buzzer status message - */ - virtual void buzzerHandle(std::string buzzerstatus) = 0; - - /*! - \brief Handle for device name callbacks - \param device Received device name - */ - virtual void deviceNameHandle(std::string device) = 0; - - /*! - \brief Handle for frequncy callbacks - \param frequencystatus Received frequency - */ - virtual void frequencyHandle(std::string frequencystatus) = 0; - - /*! - \brief Handle for firmware callbacks - \param firmware Received firmware version - */ - virtual void firmwareHandle(std::string firmware) = 0; - - /*! - \brief Handle for hardware callbacks - \param hardware Received hardware version - */ - virtual void hardwareHandle(std::string hardware) = 0; - - /*! - \brief Handle for high voltage callbacks - \param hvstatus Received high voltage status - */ - virtual void hvHandle(std::string hvstatus) = 0; - - /*! - \brief Handle for interval callbacks - \param intervalstatus Received stimulation inter pulses interval - */ - virtual void intervalHandle(std::string intervalstatus) = 0; - - /*! - \brief Handle for logevents callbacks - \param logevents Received logevents message - */ - virtual void logeventsHandle(std::string logevents) = 0; - - /*! - \brief Handle for pattern callbacks - \param patternstatus Received pattern message - */ - virtual void patternHandle(std::string patternstatus) = 0; - - /*! - \brief Handle for rtc callbacks - \param rtcstatus Received rtc values - */ - virtual void rtcHandle(std::string rtcstatus) = 0; - - /*! - \brief Handle for sd function callbacks - \param sdfunctionstatus Received name of the sd card folder where patterns are saved - */ - virtual void sdfunctionHandle(std::string sdfunctionstatus) = 0; - - /*! - \brief Handle for sd user name callbacks - \param sdunamestatus Received name of the sd card folder where the folder containing patterns is saved - */ - virtual void sdunameHandle(std::string sdunamestatus) = 0; - - /*! - \brief Handle for tic callbacks - \param tic Received tic message - */ - virtual void ticHandle(std::string tic) = 0; - - /*! - \brief Handle for turning off callbacks - */ - virtual void turnOffHandle() = 0; - - /*! - \brief Handle for virtual electrodes callbacks - \param velecstatus Received virtual electrode message - */ - virtual void velecstatusHandle(std::string velecstatus) = 0; -}; \ No newline at end of file diff --git a/src/api/class/include/class/class_core.hpp b/src/api/class/include/class/class_core.hpp deleted file mode 100644 index 75d6b0f458fcda477b9baaa289c66681e051078d..0000000000000000000000000000000000000000 --- a/src/api/class/include/class/class_core.hpp +++ /dev/null @@ -1,772 +0,0 @@ -/** - * @file class_core.hpp - * @author Alfonso Dominguez <alfonso.dominguez@tecnalia.com> and Leire Querejeta Lomas <leire.querejeta@tecnalia.com> - * @date 2020 - * - * Copyright 2020 Tecnalia Research & Innovation. - * Distributed under the GNU GPL v3. - * For full terms see https://www.gnu.org/licenses/gpl.txt - * - * @brief Interface to the funccionalities of Class - */ - -#ifndef CLASS_CORE_HPP -#define CLASS_CORE_HPP - -#include <vector> -#include <string> -#include <memory> -#include <thread> -#include <mutex> -#include <cmath> -#include <iostream> -#include <fstream> - -#include <boost/circular_buffer.hpp> - -#include <communication/udp_server.hpp> -#include <communication/udp_client.hpp> -#include <logger/logger.hpp> -#include <class/class_structures.hpp> -#include <class/class_error.hpp> -#include <class/class_cb.hpp> -#include <filter/butterworth.hpp> - -#include <Python.h> - -/** - * @brief Core class - */ -class ClassCore:public UdpServerListener -{ -public: - //! Allowed values - - int BUZZER_MAX_VALUE = 500; - int BUZZER_MIN_VALUE = 25; - int FREQ_MAX_VALUE = 2000; - int FREQ_MIN_VALUE = 0; - int HV_MAX_VALUE = 200; - int HV_MIN_VALUE = 120; - int INTERVAL_MAX_VALUE = 1000; - int INTERVAL_MIN_VALUE = 250; - - //! Structure for electrode - struct Elec - { - int id; - int pads_number; - }; - - //! Structure for virtual electrode - struct Velec - { - int id; - std::string name; - bool selected; - }; - - //! basic constructor - ClassCore(); - //! basic destructor - ~ClassCore(); - - /*! - \brief Stops acquisition - \return Integer indicating the success of the process (0-success, <0 error) - */ - ClassError::Error acqOff(); - - /*! - \brief Starts acquisition - \return Integer indicating the success of the process (0-success, <0 error) - */ - ClassError::Error acqOn(); - - /*! - \brief Stops impedance acquisition - \return Integer indicating the success of the process (0-success, <0 error) - */ - ClassError::Error acqImpedanceOff(); - - /*! - \brief Starts impedance acquisition - \return Integer indicating the success of the process (0-success, <0 error) - */ - ClassError::Error acqImpedanceOn(); - - /*! - \brief Stops acquisition stream - \return Integer indicating the success of the process (0-success, <0 error) - */ - ClassError::Error acqStreamOff(); - - /*! - \brief Starts acquisition stream - \return Integer indicating the success of the process (0-success, <0 error) - */ - ClassError::Error acqStreamOn(); - - /*! - \brief Sets the config for impedance acquisition - \param positive Indicates whther is positive (true) or negative (false) - \return Integer indicating the success of the process (0-success, <0 error) - */ - ClassError::Error acqImpedanceConfig(const bool& positive); - - /*! - \brief Sets the polarity for impedance acquisition - \param unipolar Indicates whther is unipolar (true) or bipolar (false). - \return Integer indicating the success of the setting process (0-success, <0 error) - */ - ClassError::Error acqImpedancePolarity(const bool& unipolar); - - /*! - \brief Sets class acq input to normal (bio signal captured from channels) - \return Integer indicating the success of the setting process (0-success, <0 error) - */ - ClassError::Error acqInputNormal(); - - /*! - \brief Sets class acq input to test. The class will provide a quadratic signal. It is useful for testing and not getting saturated signal all the time. - \return Integer indicating the success of the setting process (0-success, <0 error) - */ - ClassError::Error acqInputTest(); - - /*! - \brief Sends the request for battery level - \return Integer indicating the success of the starting process (0-success, <0 error) - */ - ClassError::Error batteryLevel(); - - /*! - \brief Sets the duration of the buffer (ms*frequency//1000.0) - \param ms Time in ms - \return Integer indicating the success of the setting process (0-success, <0 error) - */ - ClassError::Error bufferDuration(const double& ms); - - /*! - \brief Sets buzzer on - \return Integer indicating the success of the process (0-success, <0 error) - */ - ClassError::Error buzzerPlay(); - - /*! - \brief Sends the request for buzzer - \return Integer indicating the success of the starting process (0-success, <0 error) - */ - ClassError::Error buzzerStatus(); - - /*! - \brief Sets ms of buzzer song - \param tempo time in ms - \return Integer indicating the success of the process (0-success, <0 error) - */ - ClassError::Error buzzerTempo(const std::string& tempo); - - /*! - \brief Connect to the CLASS server - \param server_ip IP of the CLASS server - \param server_port of the CLASS server - \param local_ip IP in which the instance is listening for messages coming from CLASS server - \param local_port Port in which the instance is listening for messages coming from CLASS server - \return Integer indicating the success of the connection (0-success, <0 error) - */ - ClassError::Error connect(const std::string & server_ip, const int & server_port, const std::string & local_ip, const int & local_port); - - /*! - \brief Sends the request for device name - \return Integer indicating the success of the starting process (0-success, <0 error) - */ - ClassError::Error deviceName(); - - /*! - \brief Sets name of device - \param devicename Name of the device - \return Integer indicating the success of the process (0-success, <0 error) - */ - ClassError::Error devName(const std::string& devicename); - - /*! - \brief Disconnect from the CLASS server - \return Integer indicating the success of the disconnection (0-success, <0 error) - */ - ClassError::Error disconnect(); - - /*! - \brief Sets electrode pads number - \param id Electrode number/ID - \param pads_number Number of pads of the electrode - \return Integer indicating the success of the process (0-success, <0 error) - */ - ClassError::Error elecPads(const int& id, const int& pads_number); - - /*! - \brief Sends the request for firmware version - \return Integer indicating the success of the starting process (0-success, <0 error) - */ - ClassError::Error firmwareVersion(); - - /*! - \brief Sends the request for frequency - \return Integer indicating the success of the starting process (0-success, <0 error) - */ - ClassError::Error frequencyStatus(); - - /*! - \brief Sets the config for impedance acquisition - \param acq_frames Vector to fill with acqusition frames - \return Integer indicating the success of the process (0-success, <0 error) - */ - ClassError::Error getAcqFrames(std::vector<AcqFrame>& acq_frames); - - /*! - \brief Sends the request for hardware version - \return Integer indicating the success of the starting process (0-success, <0 error) - */ - ClassError::Error hardwareVersion(); - - /*! - \brief Sets high voltage to off - \return Integer indicating the success of the process (0-success, <0 error) - */ - ClassError::Error hvOff(); - - /*! - \brief Sets high voltage to on - \return Integer indicating the success of the process (0-success, <0 error) - */ - ClassError::Error hvOn(); - - /*! - \brief Sends the request for high voltage status - \return Integer indicating the success of the starting process (0-success, <0 error) - */ - ClassError::Error hvStatus(); - - /*! - \brief Sets high voltage value - \param hvvalue value of high voltage - \return Integer indicating the success of the process (0-success, <0 error) - */ - ClassError::Error hvValue(const std::string& hvvalue); - - /*! - \brief Sets the order of the filter used for impedance calculation - \param order Filter order (>0) - \return Integer indicating the success of the setting process (0-success, <0 error) - */ - ClassError::Error impedanceFilterOrder(const int& order); - - /*! - \brief Init communication - \param init_mode Initialization mode - \return Integer indicating the success of the process (0-success, <0 error) - */ - ClassError::Error initCommunication(const std::string& init_mode); - - /*! - \brief Sends the request for interval status - \return Integer indicating the success of the starting process (0-success, <0 error) - */ - ClassError::Error intervalStatus(); - - /*! - \brief Sets stimulation inter pulses interval - \param interval value of stimulation inter pulses - \return Integer indicating the success of the process (0-success, <0 error) - */ - ClassError::Error intervalValue(const std::string& interval); - - /*! - \brief Sets logevents to off - \return Integer indicating the success of the process (0-success, <0 error) - */ - ClassError::Error logeventsOff(); - - /*! - \brief Sets logevents to on - \return Integer indicating the success of the process (0-success, <0 error) - */ - ClassError::Error logeventsOn(); - - /*! - \brief Sends the request for logevents - \return Integer indicating the success of the starting process (0-success, <0 error) - */ - ClassError::Error logeventsStatus(); - - /*! - \brief Sets pattern - \param number pattern number - \param pat vector of patterns - \return Integer indicating the success of the process (0-success, <0 error) - */ - ClassError::Error pattern(const int& number, const std::vector<Pattern>& pat); - - /*! - \brief Clear pattern - \param id pattern to delete - \return Integer indicating the success of the process (0-success, <0 error) - */ - ClassError::Error patternClear(const int& id); - - /*! - \brief Sends the request for pattern - \param number pattern - \return Integer indicating the success of the starting process (0-success, <0 error) - */ - ClassError::Error patternStatus(const int& number); - - /*! - \brief Sends the request for pattern - \param number pattern - \return Integer indicating the success of the starting process (0-success, <0 error) - */ - ClassError::Error velecStatus(const int& number); - - /*! - \brief Sets rtc date - \param rtcdate mm/dd/yyyy format - \return Integer indicating the success of the process (0-success, <0 error) - */ - ClassError::Error rtcDate(const std::string& rtcdate); - - /*! - \brief Sends the request for rtc - \return Integer indicating the success of the starting process (0-success, <0 error) - */ - ClassError::Error rtcStatus(); - - /*! - \brief Sets rtc time - \param rtctime hh:mm:ss format - \return Integer indicating the success of the process (0-success, <0 error) - */ - ClassError::Error rtcTime(const std::string& rtctime); - - /*! - \brief Sends the request for sd function - \return Integer indicating the success of the starting process (0-success, <0 error) - */ - ClassError::Error sdfunctionStatus(); - - /*! - \brief Sets name of sdcard folder where the pattern are saved - \param sdfunctionname name of the folder - \return Integer indicating the success of the process (0-success, <0 error) - */ - ClassError::Error sdFunctionName(const std::string& sdfunctionname); - - /*! - \brief Sets name of sdcard folder where the folder containing the patterns is saved - \param sduname name of the folder - \return Integer indicating the success of the process (0-success, <0 error) - */ - ClassError::Error sdUName(const std::string& sduname); - - /*! - \brief Sends the request for sd user name - \return Integer indicating the success of the starting process (0-success, <0 error) - */ - ClassError::Error sdunameStatus(); - - /*! - \brief Sends custom command to CLASS device - \param cmd Command - \return Integer indicating the success of the process (0-success, <0 error) - */ - ClassError::Error sendCustomCmd(const std::string& cmd); - - /*! - \brief Sets class acq configuration - \param frequency Frequency of acquisition - \param channel_numbers Channel numbers - \param gain Gain of the acquisition - \param input Acq input type, normal or test - \return Integer indicating the success of the setting process (0-success, <0 error) - */ - ClassError::Error setAcqConfig(const double& frequency, const std::vector<int>& channel_numbers, const double& gain, const std::string& input); - - /*! - \brief Sets the callback - \param callback Callback - \param language Language which has defined the callback - \return Integer indicating the success of the starting process (0-success, <0 error) - */ - ClassError::Error setCallback(ClassCallback* callback, std::string language); - - /*! - \brief Turn off - \return Integer indicating the success of the process (0-success, <0 error) - */ - ClassError::Error shutdown(); - - /*! - \brief Sets frequency of the stimulation - \param frequency Frequency of the stimulation - \return Integer indicating the success of the process (0-success, <0 error) - */ - ClassError::Error stimFreq(const double& frequency); - - /*! - \brief Stops stimulation - \return Integer indicating the success of the process (0-success, <0 error) - */ - ClassError::Error stimOff(); - - /*! - \brief Starts stimulation - \return Integer indicating the success of the process (0-success, <0 error) - */ - ClassError::Error stimOn(); - - /*! - \brief Starts stimulation of the virtual electrode which name is passed as parameter - \param name Name of the virtual electrode - \return Integer indicating the success of the process (0-success, <0 error) - */ - ClassError::Error stimVelec(const std::string& name); - - /*! - \brief Sends the request for tic - \return Integer indicating the success of the starting process (0-success, <0 error) - */ - ClassError::Error tic(); - - /*! - \brief Handles the reception of an UDP msg from the CLASS server - \param msg Msg - \param ip IP the message comes from - */ - void udpMsgReceived(std::string msg, std::string client_ip); - - /*! - \brief Sets virtual electrode - \param number Virtual electrode number/ID - \param name Name of the virtual electrode - \param electrode_id Electrode ID/number - \param cathodes List of integers with the IDs of the pads acting as cathodes - \param anodes List of integers with the IDs of the pads acting as cathodes - \param amp List of doubles with the amplitude (in mA) associated to each of the cathodes. Must have the same length as cathodes - \param width List of integers with the pulse width (in uS) associated to each of the cathodes. Must have the same length as cathodes - \param selected Defines if the velec is selected (‘true’ value) or deselected (‘false’ value). Only selected velecs will be executed with a “stim on” command - \param sync Defines if the velec is synchronous (‘rtue’ value) or asynchronous (‘false’ value). - \return Integer indicating the success of the process (0-success, <0 error) - */ - ClassError::Error velec(const int& id, const std::string& name, const int& electrode_id, const std::vector<int>& cathodes, const std::vector<int>& anodes, const std::vector<double>& amp, const std::vector<int>& width, const bool& selected, const bool& sync); - - /*! - \brief Sets whether the virtual electrode is selected or not - \param id Virtual electrode number/ID - \param selected Defines if the velec is selected (‘true’ value) or deselected (‘false’ value). Only selected velecs will be executed with a “stim on” command. - \return Integer indicating the success of the process (0-success, <0 error) - */ - ClassError::Error velecSelected(const int& id, const bool& selected); - - /*! - \brief Sets whether the virtual electrodes are selected or not - \param id Vector with virtual electrode number/ID. - \param selected Vector of bool values indicating whether the virtual electrode is selected - \return Integer indicating the success of the process (0-success, <0 error) - */ - ClassError::Error velecsSelected(const std::vector<int>& id, const std::vector<bool>& selected); - -private: - /*! - \brief Sends msg through serial - \param msg Msg to send. - \return Integer indicating the success of the starting process (0-success, <0 error) - */ - ClassError::Error sendMsg(std::string msg); - - /*! - \brief Sends msgs through serial - \param msgs Vector with msgs to send. - \return Integer indicating the success of the starting process (0-success, <0 error) - */ - ClassError::Error sendMsgs(std::vector<std::string> msgs); - - /*! - \brief Updates buffer capacity based on acq rate and seconds - \param seconds Buffer duration. - \return Integer indicating the success of the starting process (0-success, <0 error) - */ - ClassError::Error setBufferCapacity(const double& seconds); - - /*! - \brief Configures the filter for impedance - \param order Order of the filter - \param low_freq Lower frequency of the band - \param up_freq Upper freqeuncy of the band - \param acq_freq Sampling rate - \return Integer indicating the success of the starting process (0-success, <0 error) - */ - ClassError::Error configureFilter(int order, double low_freq, double up_freq, double acq_freq); - - /*! - \brief Sets the number of digits after decimal - \param value Value - \param digits_after_decimal Number of desired digits after decimal - \return Pair with the new_value and a bool indicating whether the operation has enough precision - */ - std::pair< double, bool > trunc_n( double value, std::size_t digits_after_decimal); - - /*! - \brief Increases lock error number - */ - void increaseLockError(); - - //! UDP server where it listens for command coming form the CLASS server - UDPServer *udp_server_; - //! UDP client which sends messages to CLASS server - UDPClient *udp_client_; - - //! indicates the IP where the CLASS server is listening - std::string server_ip_; - //! indicates the port where the CLASS server is listening - int server_port_; - //! indicates the local IP where the instance is listening for messages coming from CLASS server - std::string local_ip_; - //! indicates the local port where the instance is listening for messages coming from CLASS server - int local_port_; - - //! defined electrodes - std::vector<Elec> electrodes_; - - //! defined virual electrodes - std::vector<Velec> virtual_electrodes_; - - //! indicates whether it is acquiring frames - bool is_acquiring_frames_; - //! is_acquiring_frames mutex - std::mutex is_acquiring_frames_mutex_; - //! number of channels - int channels_number_; - //! frequency of the acquisition - double acq_frequency_; - //! acquisition time (determinates buffer maximum size) - double acq_seconds_; - //! acquisition time - int acq_buffer_capacity_; - //! acquisition buffer - boost::circular_buffer<AcqFrame> acq_buffer_; - //! acquisition buffer mutex - std::mutex acq_buffer_mutex_; - - //! indicates whether it is acquiring impedances - bool is_acquiring_impedances_; - //! is_acquiring_frames mutex - std::mutex is_acquiring_impedances_mutex_; - //! acquisition time - int acq_impedances_buffer_capacity_; - //! acquisition buffer - boost::circular_buffer<AcqFrame> acq_impedances_buffer_; - //! acquisition buffer mutex - std::mutex acq_impedances_buffer_mutex_; - - //! butterworth filters, one per channel - Butterworth **butterworth_; - //! order of the filter - int filter_order_; - - //! thread for waiting messages - std::thread *waiting_thread_; - //! function for waiting messages - void waitingThreadFunction_(); - //! Indicates whether to wait for special messages - bool waiting_; - //! Mutex for waiting - std::mutex waiting_mutex_; - - //! indicates whether it is waiting for tic - bool tic_received_; - //! indicates whether tic has been received - bool is_waiting_tic_; - //! mutex for tic - std::mutex tic_mutex_; - - //! indicates whether it is waiting for firmware - bool firmware_received_; - //! indicates whether firmware has been received - bool is_waiting_firmware_; - //! mutex for firmware - std::mutex firmware_mutex_; - - //! indicates whether it is waiting for device name - bool device_received_; - //! indicates whether device name has been received - bool is_waiting_device_; - //! mutex for firmware - std::mutex device_mutex_; - - //! indicates whether it is waiting for hardware - bool hardware_received_; - //! indicates whether hardware has been received - bool is_waiting_hardware_; - //! mutex for hardware - std::mutex hardware_mutex_; - - //! indicates whether it is waiting for battery - bool battery_received_; - //! indicates whether battery has been received - bool is_waiting_battery_; - //! mutex for battery - std::mutex battery_mutex_; - - //! indicates whether it is waiting for logevents - bool logevents_received_; - //! indicates whether logevents has been received - bool is_waiting_logevents_; - //! mutex for logevents - std::mutex logevents_mutex_; - - //! indicates whether it is waiting for high voltage status - bool hvstatus_received_; - //! indicates whether high voltage status has been received - bool is_waiting_hvstatus_; - //! mutex for high voltage status - std::mutex hvstatus_mutex_; - - //! indicates whether it is waiting for interval status - bool intervalstatus_received_; - //! indicates whether interval status has been received - bool is_waiting_intervalstatus_; - //! mutex for interval status - std::mutex intervalstatus_mutex_; - - //! indicates whether it is waiting for rtc status - bool rtcstatus_received_; - //! indicates whether rtc status has been received - bool is_waiting_rtcstatus_; - //! mutex for rtc status - std::mutex rtcstatus_mutex_; - - //! indicates whether it is waiting for buzzer status - bool buzzerstatus_received_; - //! indicates whether buzzer status has been received - bool is_waiting_buzzerstatus_; - //! mutex for buzzer status - std::mutex buzzerstatus_mutex_; - - //! indicates whether it is waiting for frequency status - bool frequencystatus_received_; - //! indicates whether frequency status has been received - bool is_waiting_frequencystatus_; - //! mutex for frequency status - std::mutex frequencystatus_mutex_; - - //! indicates whether it is waiting for sdfunction - bool sdfunction_received_; - //! indicates whether sdfunction has been received - bool is_waiting_sdfunction_; - //! mutex for sdfunction - std::mutex sdfunction_mutex_; - - //! indicates whether it is waiting for sduname - bool sduname_received_; - //! indicates whether sduname has been received - bool is_waiting_sduname_; - //! mutex for sduname - std::mutex sduname_mutex_; - - //! indicates whether it is waiting for pattern - bool patternstatus_received_; - //! indicates whether pattern has been received - bool is_waiting_patternstatus_; - //! mutex for logevents - std::mutex patternstatus_mutex_; - - //! indicates whether it is waiting for velecstatus - bool velecstatus_received_; - //! indicates whether velecstatus has been received - bool is_waiting_velecstatus_; - //! mutex for velecstatus - std::mutex velecstatus_mutex_; - - //! battery level - double battery_; - // tic text - std::string tic_; - // firmware text - std::string firmware_; - // hardware text - std::string hardware_; - // device text - std::string device_; - // logevents text - std::string logevents_; - // high voltage status text - std::string hvstatus_; - // interval status text - std::string intervalstatus_; - // rtc status text - std::string rtcstatus_; - // buzzer status text - std::string buzzerstatus_; - // frequency status text - std::string frequencystatus_; - // sdfunction status text - std::string sdfunctionstatus_; - // sduname status text - std::string sdunamestatus_; - // pattern status text - std::string patternstatus_; - // velecstatus text - std::string velecstatus_; - - //! mutex for lock errors - std::mutex lock_error_mutex_; - //! number of lock errors - int lock_error_number_; - //! max number of lock errors before launching error - int lock_error_number_max_; - //! thread for lock errors - std::thread *lock_error_thread_; - //! function for lock error - void lockErrorThreadFunction_(); - //! Indicates whether to wait for special messages - bool error_waiting_; - - //! callback for battery, turn_off, etc. - ClassCallback* class_cb_; - //! Language which has defined the callback - std::string language_; - - //! acq gainb - double gain_; - - //! log function - #define log_stream_(x) log_(std::stringstream() << x); - #define log_warn_stream_(x) log_warn_(std::stringstream() << x); - #define log_error_stream_(x) log_err_(std::stringstream() << x); - void log_(const std::string &text); - void log_(const std::stringstream &text); - void log_(std::ostream & text); - void log_err_(const std::string &text); - void log_err_(std::ostream & text); - void log_warn_(const std::string &text); - void log_warn_(std::ostream & text); -}; - -/** - * @brief Class for locking when accesing callback in Python - */ -class PyThreadStateLock -{ -public: - PyThreadStateLock(void) - { - state = PyGILState_Ensure( ); - } - - ~PyThreadStateLock(void) - { - PyGILState_Release( state ); - } -private: - PyGILState_STATE state; -}; - -#endif // CLASS_CORE_HPP diff --git a/src/api/class/include/class/class_error.hpp b/src/api/class/include/class/class_error.hpp deleted file mode 100644 index 3626520ba12a2628bbee73155a8b6205e25e2129..0000000000000000000000000000000000000000 --- a/src/api/class/include/class/class_error.hpp +++ /dev/null @@ -1,40 +0,0 @@ -/** - * @file class_error.hpp - * @author Alfonso Dominguez <alfonso.dominguez@tecnalia.com> and Leire Querejeta Lomas <leire.querejeta@tecnalia.com> - * @date 2020 - * - * Copyright 2020 Tecnalia Research & Innovation. - * Distributed under the GNU GPL v3. - * For full terms see https://www.gnu.org/licenses/gpl.txt - * - * @brief Errors thrown by the API methods - */ - -#pragma once - -//! Errors thrown by the API methods. -class ClassError -{ - public: - //! Enum for errors - enum Error - { - CLASS_NO_ERROR = 0, ///< No error - ERROR_CORE_NULL = -1, ///< Core object is null - ERROR_SENDING_MSG = -2, ///< Error sending msg to server - ERROR_NO_ELEC_WITH_ID = -3, ///< There is no electrode with the specified ID - ERROR_CATHODE_AMP_DIFFERENT_SIZE = -4, ///< Cathode and Amp vectors have different size - ERROR_NO_VELEC_WITH_ID = -5, ///< There is no virtual electrode with the specified ID - ERROR_NO_VELEC_WITH_NAME = -6, ///< There is no virtual electrode with the specified name - ERROR_DEVICE_NOT_ACQUIRING = -7, ///< The device is not acquiring frames/impedances. Have you configured for it? - ERROR_UDP_CLIENT_NULL = -8, ///< The sender object is null - ERROR_NOT_VALID_ORDER = -9, ///< Filter order is negative. It must be a integer > 0 - ERROR_NOT_VALID_MS = -10, ///< Duration for buffer is negative. It must be a double > 0 - ERROR_CB_NULL = -11, ///< Class callback is NULL. A callback must be set before getting any value - ERROR_DIF_VECTOR_SIZE = -12, ///< Vector sizes are different - ERROR_EMPTY_CATHODE = -13, ///< Cathode vector is empty - ERROR_EMPTY_ANODE = -14, ///< Cathode vector is empty - ERROR_NOT_VALID_CHANNEL_ID = -15, ///< Channel id is not in the limits (>=1 and <=16) - ERROR_NOT_VALID_VALUE = -16 ///< Out of range value - }; -}; \ No newline at end of file diff --git a/src/api/class/include/class/class_structures.hpp b/src/api/class/include/class/class_structures.hpp deleted file mode 100644 index 51ddb681689a1428292bb098b2223b028aadb970..0000000000000000000000000000000000000000 --- a/src/api/class/include/class/class_structures.hpp +++ /dev/null @@ -1,33 +0,0 @@ -/** - * @file class_structures.hpp - * @author Alfonso Dominguez <alfonso.dominguez@tecnalia.com> and Leire Querejeta Lomas <leire.querejeta@tecnalia.com> - * @date 2020 - * - * Copyright 2020 Tecnalia Research & Innovation. - * Distributed under the GNU GPL v3. - * For full terms see https://www.gnu.org/licenses/gpl.txt - * - * @brief Structures interchanged through the API methods - */ - -#pragma once - -#include <vector> - -//! Structure for a acquisition frame -struct AcqFrame -{ - double timestamp; ///< timestamp of the acquisition frame - std::vector<double> values; ///< values for the different channels -}; - -//! Structure for pattern -struct Pattern -{ - std::string amp; - std::string pw; - std::string r; - int ampval; - int pwval; - int time; -}; diff --git a/src/api/class/src/.gitkeep b/src/api/class/src/.gitkeep deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/src/api/class/src/class.cpp b/src/api/class/src/class.cpp deleted file mode 100644 index 867e09d2425004b45bee68cad4606b5e5720eece..0000000000000000000000000000000000000000 --- a/src/api/class/src/class.cpp +++ /dev/null @@ -1,597 +0,0 @@ -/** - * @file class.cpp - * @author Alfonso Dominguez <alfonso.dominguez@tecnalia.com> and Leire Querejeta Lomas <leire.querejeta@tecnalia.com> - * @date 2020 - * - * Copyright 2020 Tecnalia Research & Innovation. - * Distributed under the GNU GPL v3. - * For full terms see https://www.gnu.org/licenses/gpl.txt - * - * @brief Interface to the funcionalities of Class - */ - -#include "class/class.hpp" -#include <iostream> -#include <class/class_core.hpp> - -using namespace std; - -Class::Class() -{ - std::cout << "Class cstr" << std::endl; - core_ = new ClassCore(); -} - -Class::~Class() -{ - std::cout << "Class dstr" << std::endl; - if (core_ != NULL) - { - delete core_; - core_ = NULL; - } -} - -ClassError::Error Class::connect() -{ - std::string server_ip = DEFAULT_SERVER_IP; - int server_port = DEFAULT_SERVER_PORT; - - std::string local_ip = DEFAULT_LOCAL_IP; - int local_port = DEFAULT_LOCAL_PORT; - - return core_->connect(server_ip, server_port, local_ip, local_port); -} - -ClassError::Error Class::connect(const std::string & server_ip, const int & server_port) -{ - std::string local_ip = DEFAULT_LOCAL_IP; - int local_port = DEFAULT_LOCAL_PORT; - - return core_->connect(server_ip, server_port, local_ip, local_port); -} - -ClassError::Error Class::connect(const std::string & server_ip, const int & server_port, const int & local_port) -{ - std::string local_ip = DEFAULT_LOCAL_IP; - - return core_->connect(server_ip, server_port, local_ip, local_port); -} - -ClassError::Error Class::connect(const std::string & server_ip, const int & server_port, const std::string & local_ip, const int & local_port) -{ - return core_->connect(server_ip, server_port, local_ip, local_port); -} - -ClassError::Error Class::disconnect() -{ - if (core_ == NULL) - return ClassError::ERROR_CORE_NULL; - - return core_->disconnect(); -} - -ClassError::Error Class::setAcqConfig(const AcqFreq& frequency, const std::vector<int>& channel_numbers, const AcqGain& gain, const AcqInput& input) -{ - if (core_ == NULL) - return ClassError::ERROR_CORE_NULL; - - double freq = 0.0; - int channel_numb = 0; - double acq_gain = 0.0; - std::string input_str = "test"; - - switch(frequency) - { - case FREQ_250 : freq = 250; break; - case FREQ_500 : freq = 500; break; - case FREQ_1000 : freq = 1000; break; - case FREQ_2000 : freq = 2000; break; - case FREQ_4000 : freq = 4000; break; - case FREQ_8000 : freq = 8000; break; - } - - switch(gain) - { - case GAIN_1 : acq_gain = 1; break; - case GAIN_2 : acq_gain = 2; break; - case GAIN_4 : acq_gain = 4; break; - case GAIN_8 : acq_gain = 8; break; - case GAIN_12 : acq_gain = 12; break; - case GAIN_24 : acq_gain = 24; break; - } - - switch(input) - { - case NORMAL : input_str = "normal"; break; - case TEST : input_str = "test"; break; - } - - return core_->setAcqConfig(freq, channel_numbers, acq_gain, input_str); -} - -ClassError::Error Class::startAcq() -{ - if (core_ == NULL) - return ClassError::ERROR_CORE_NULL; - - return core_->acqOn(); -} - -ClassError::Error Class::startImpedanceAcq() -{ - if (core_ == NULL) - return ClassError::ERROR_CORE_NULL; - - return core_->acqImpedanceOn(); -} - -ClassError::Error Class::stopAcq() -{ - if (core_ == NULL) - return ClassError::ERROR_CORE_NULL; - - return core_->acqOff(); -} - -ClassError::Error Class::stopImpedanceAcq() -{ - if (core_ == NULL) - return ClassError::ERROR_CORE_NULL; - - return core_->acqImpedanceOff(); -} - -ClassError::Error Class::startAcqStream() -{ - if (core_ == NULL) - return ClassError::ERROR_CORE_NULL; - - return core_->acqStreamOn(); -} - -ClassError::Error Class::stopAcqStream() -{ - if (core_ == NULL) - return ClassError::ERROR_CORE_NULL; - - return core_->acqStreamOff(); -} - -ClassError::Error Class::setAcqInputNormal() -{ - if (core_ == NULL) - return ClassError::ERROR_CORE_NULL; - - return core_->acqInputNormal(); -} - -ClassError::Error Class::setAcqInputTest() -{ - if (core_ == NULL) - return ClassError::ERROR_CORE_NULL; - - return core_->acqInputTest(); -} - -ClassError::Error Class::initCommunication() -{ - if (core_ == NULL) - return ClassError::ERROR_CORE_NULL; - - return core_->initCommunication("DESKTOP"); -} - -ClassError::Error Class::initCommunication(const InitMode& mode) -{ - if (core_ == NULL) - return ClassError::ERROR_CORE_NULL; - - std::string init_mode = ""; - - switch(mode) - { - case TACTILITY: init_mode = "TACTILITY"; break; - case PAIN: init_mode = "PAIN"; break; - case DESKTOP: init_mode = "DESKTOP"; break; - case NEURORESEARCH: init_mode = "DESKTOP"; break; - case ICARE: init_mode = "ICARE"; break; - case TIB_ACQ: init_mode = "TIB_ACQ"; break; - case TIB_STIM: init_mode = "TIB_STIM"; break; - default: init_mode = "DESKTOP"; break; - } - - return core_->initCommunication(init_mode); -} - -std::vector<AcqFrame> Class::getAcqFrames() -{ - //std::cout << "getAcqFrames" << std::endl; - std::vector<AcqFrame> acqFrames; - - if (core_ == NULL) - return acqFrames; - - int output = core_->getAcqFrames(acqFrames); - - return acqFrames; -} - -ClassError::Error Class::patternDelete(const int& id) -{ - if (core_ == NULL) - return ClassError::ERROR_CORE_NULL; - - return core_->patternClear(id); -} - -ClassError::Error Class::getPatternStatus(const int& id) -{ - if (core_ == NULL) - return ClassError::ERROR_CORE_NULL; - - return core_->patternStatus(id); -} - -ClassError::Error Class::startStim() -{ - if (core_ == NULL) - return ClassError::ERROR_CORE_NULL; - - return core_->stimOn(); -} - -ClassError::Error Class::stopStim() -{ - if (core_ == NULL) - return ClassError::ERROR_CORE_NULL; - - return core_->stimOff(); -} - -ClassError::Error Class::setElecPads(const int& id, const int& pads_number) -{ - if (core_ == NULL) - return ClassError::ERROR_CORE_NULL; - - return core_->elecPads(id, pads_number); -} - -ClassError::Error Class::setStimFreq(const double& frequency) -{ - if (core_ == NULL) - return ClassError::ERROR_CORE_NULL; - - return core_->stimFreq(frequency); -} - -ClassError::Error Class::setDevName(const std::string& devicename) -{ - if (core_ == NULL) - return ClassError::ERROR_CORE_NULL; - - return core_->devName(devicename); -} - -ClassError::Error Class::sethvValue(const std::string& hvvalue) -{ - if (core_ == NULL) - return ClassError::ERROR_CORE_NULL; - - return core_->hvValue(hvvalue); -} - -ClassError::Error Class::sethvOn() -{ - if (core_ == NULL) - return ClassError::ERROR_CORE_NULL; - - return core_->hvOn(); -} - -ClassError::Error Class::sethvOff() -{ - if (core_ == NULL) - return ClassError::ERROR_CORE_NULL; - - return core_->hvOff(); -} - -ClassError::Error Class::setlogeventsOn() -{ - if (core_ == NULL) - return ClassError::ERROR_CORE_NULL; - - return core_->logeventsOn(); -} - -ClassError::Error Class::setlogeventsOff() -{ - if (core_ == NULL) - return ClassError::ERROR_CORE_NULL; - - return core_->logeventsOff(); -} - -ClassError::Error Class::setintervalValue(const std::string& interval) -{ - if (core_ == NULL) - return ClassError::ERROR_CORE_NULL; - - return core_->intervalValue(interval); -} - -ClassError::Error Class::setbuzzerTempo(const std::string& tempo) -{ - if (core_ == NULL) - return ClassError::ERROR_CORE_NULL; - - return core_->buzzerTempo(tempo); -} - -ClassError::Error Class::setbuzzerPlay() -{ - if (core_ == NULL) - return ClassError::ERROR_CORE_NULL; - - return core_->buzzerPlay(); -} - -ClassError::Error Class::setrtcDate(const std::string& rtcDate) -{ - if (core_ == NULL) - return ClassError::ERROR_CORE_NULL; - - return core_->rtcDate(rtcDate); -} - -ClassError::Error Class::setrtcTime(const std::string& rtcTime) -{ - if (core_ == NULL) - return ClassError::ERROR_CORE_NULL; - - return core_->rtcTime(rtcTime); -} - -ClassError::Error Class::setShutdown() -{ - if (core_ == NULL) - return ClassError::ERROR_CORE_NULL; - - return core_->shutdown(); -} - -ClassError::Error Class::setSDFunctionName(const std::string& sdfunctionname) -{ - if (core_ == NULL) - return ClassError::ERROR_CORE_NULL; - - return core_->sdFunctionName(sdfunctionname); -} - -ClassError::Error Class::setSDUName(const std::string& sduname) -{ - if (core_ == NULL) - return ClassError::ERROR_CORE_NULL; - - return core_->sdUName(sduname); -} - -ClassError::Error Class::setPattern(const int& id, const std::vector<Pattern>& pat) -{ - if (core_ == NULL) - return ClassError::ERROR_CORE_NULL; - - return core_->pattern(id,pat); -} - -ClassError::Error Class::setVelec(const int& id, const std::string& name, const int& electrode_id, const std::vector<int>& cathodes, const std::vector<int>& anodes, const std::vector<double>& amp, const std::vector<int>& width, const bool& selected, const bool& sync) -{ - if (core_ == NULL) - return ClassError::ERROR_CORE_NULL; - - return core_->velec(id, name, electrode_id, cathodes, anodes, amp, width, selected, sync); -} - -ClassError::Error Class::setVelecSelected(const int& id, const bool& selected) -{ - if (core_ == NULL) - return ClassError::ERROR_CORE_NULL; - - return core_->velecSelected(id, selected); -} - -ClassError::Error Class::setVelecsSelected(const std::vector<int>& id, const std::vector<bool>& selected) -{ - if (core_ == NULL) - return ClassError::ERROR_CORE_NULL; - - return core_->velecsSelected(id, selected); -} - -ClassError::Error Class::stimVelec(const std::string& name) -{ - if (core_ == NULL) - return ClassError::ERROR_CORE_NULL; - - return core_->stimVelec(name); -} - -ClassError::Error Class::getVelecStatus(const int& id) -{ - if (core_ == NULL) - return ClassError::ERROR_CORE_NULL; - - return core_->velecStatus(id); -} - -ClassError::Error Class::setAcqImpedanceConfig(const AcqImpedanceSign& type) -{ - if (core_ == NULL) - return ClassError::ERROR_CORE_NULL; - - bool positive = false; - switch(type) - { - case TYPE_POSITIVE : positive = true; break; - case TYPE_NEGATIVE : positive = false; break; - } - - return core_->acqImpedanceConfig(positive); -} - -ClassError::Error Class::setAcqImpedancePolarity(const AcqImpedancePolarity& polarity) -{ - if (core_ == NULL) - return ClassError::ERROR_CORE_NULL; - - bool unipolar = false; - switch(polarity) - { - case TYPE_UNIPOLAR : unipolar = true; break; - case TYPE_BIPOLAR : unipolar = false; break; - } - - return core_->acqImpedancePolarity(unipolar); -} - -ClassError::Error Class::setImpedanceFilterOrder(const int& order) -{ - if (core_ == NULL) - return ClassError::ERROR_CORE_NULL; - - return core_->impedanceFilterOrder(order); -} - -ClassError::Error Class::setBufferDuration(const double& ms) -{ - if (core_ == NULL) - return ClassError::ERROR_CORE_NULL; - - return core_->bufferDuration(ms); -} - -ClassError::Error Class::setCallback(ClassCallback * callback, std::string language) -{ - if (callback) - { - return core_->setCallback(callback, language); - } - else - { - return ClassError::ERROR_CB_NULL; - } -} - -ClassError::Error Class::getBattery() -{ - - if (core_ == NULL) - return ClassError::ERROR_CORE_NULL; - - return core_->batteryLevel(); -} - -ClassError::Error Class::getFirmware() -{ - if (core_ == NULL) - return ClassError::ERROR_CORE_NULL; - - return core_->firmwareVersion(); -} - -ClassError::Error Class::getDeviceName() -{ - if (core_ == NULL) - return ClassError::ERROR_CORE_NULL; - - return core_->deviceName(); -} - -ClassError::Error Class::getLogevents() -{ - if (core_ == NULL) - return ClassError::ERROR_CORE_NULL; - - return core_->logeventsStatus(); -} - -ClassError::Error Class::getHv() -{ - if (core_ == NULL) - return ClassError::ERROR_CORE_NULL; - - return core_->hvStatus(); -} - -ClassError::Error Class::getInterval() -{ - if (core_ == NULL) - return ClassError::ERROR_CORE_NULL; - - return core_->intervalStatus(); -} - -ClassError::Error Class::getRTC() -{ - if (core_ == NULL) - return ClassError::ERROR_CORE_NULL; - - return core_->rtcStatus(); -} - -ClassError::Error Class::getBuzzer() -{ - if (core_ == NULL) - return ClassError::ERROR_CORE_NULL; - - return core_->buzzerStatus(); -} - -ClassError::Error Class::getFrequency() -{ - if (core_ == NULL) - return ClassError::ERROR_CORE_NULL; - - return core_->frequencyStatus(); -} - -ClassError::Error Class::getHardware() -{ - if (core_ == NULL) - return ClassError::ERROR_CORE_NULL; - - return core_->hardwareVersion(); -} - -ClassError::Error Class::getSDFunction() -{ - if (core_ == NULL) - return ClassError::ERROR_CORE_NULL; - - return core_->sdfunctionStatus(); -} - -ClassError::Error Class::getSDUName() -{ - if (core_ == NULL) - return ClassError::ERROR_CORE_NULL; - - return core_->sdunameStatus(); -} - -ClassError::Error Class::getTic() -{ - if (core_ == NULL) - return ClassError::ERROR_CORE_NULL; - - return core_->tic(); -} - -ClassError::Error Class::sendCustomCmd(const std::string& cmd) -{ - if (core_ == NULL) - return ClassError::ERROR_CORE_NULL; - - return core_->sendCustomCmd(cmd); -} \ No newline at end of file diff --git a/src/api/class/src/class_core.cpp b/src/api/class/src/class_core.cpp deleted file mode 100644 index 5cba6bb9f84522a9586e9120c15b8c2d528ca553..0000000000000000000000000000000000000000 --- a/src/api/class/src/class_core.cpp +++ /dev/null @@ -1,2415 +0,0 @@ -/** - * @file ClassCore.cpp - * @author Alfonso Domminguez <alfonso.dominguez@tecnalia.com> and Leire Querejeta Lomas <leire.querejeta@tecnalia.com> - * @date 2020 - * - * Copyright 2' Tecnalia Research & Innovation. - * Distributed under the GNU GPL v3. - * For full terms see https://www.gnu.org/licenses/gpl.txt - * - * @brief Interface to the funcionalities of Class. - */ - -#include <class/class_core.hpp> -#include <iostream> -#include <numeric> -#include <chrono> -#include <thread> -#include <regex> -#include <math.h> -#include <bitset> -#include "../../commands.h" - -const double ACQ_SECONDS_DEFAULT = 2.0; -const int FILTER_ORDER_DEFAULT = 2; -const int MSG_MAX_LENGTH = 1024; - -ClassCore::ClassCore() -{ - - udp_server_ = nullptr; - udp_client_ = nullptr; - butterworth_ = nullptr; - - channels_number_ = 0; - gain_ = 0.0; - acq_seconds_ = ACQ_SECONDS_DEFAULT; - acq_buffer_capacity_ = 0; - is_acquiring_frames_ = false; - filter_order_ = FILTER_ORDER_DEFAULT; - - waiting_ = false; - - is_waiting_battery_ = false; - battery_received_ = false; - battery_ = 0.0; - tic_ = ""; - firmware_ = ""; - hardware_ = ""; - device_ = ""; - logevents_ = ""; - hvstatus_ = ""; - intervalstatus_ = ""; - rtcstatus_ = ""; - buzzerstatus_ = ""; - frequencystatus_ = ""; - sdfunctionstatus_ = ""; - sdunamestatus_ = ""; - patternstatus_ = ""; - velecstatus_ = ""; - - lock_error_number_ = 0; - lock_error_number_max_ = 10; - - language_ = ""; - class_cb_ = nullptr; - waiting_thread_ = new std::thread(&ClassCore::waitingThreadFunction_, this); - - lock_error_thread_ = new std::thread(&ClassCore::lockErrorThreadFunction_, this); - // myfile_.open ("msgs.txt"); -} - -ClassCore::~ClassCore() -{ - if (udp_server_ != nullptr) - { - delete udp_server_; - } - - if (udp_client_ != nullptr) - { - delete udp_client_; - } - - if (butterworth_ != nullptr) - { - for (int i = 0; i < channels_number_; ++i) - { - delete butterworth_[i]; - } - delete[] butterworth_; - } - - waiting_mutex_.lock(); - waiting_ = false; - waiting_mutex_.unlock(); - - lock_error_mutex_.lock(); - error_waiting_ = false; - lock_error_mutex_.unlock(); - // myfile_.close(); -} - -ClassError::Error ClassCore::connect(const std::string &server_ip, const int &server_port, const std::string &local_ip, const int &local_port) -{ - if (udp_server_ != nullptr) - { - log_("[connect] There is already a local UDP server listening for messages coming from CLASS server"); - } - else - { - log_stream_("[connect] Starting local server on port " << local_port); - udp_server_ = new UDPServer(local_port); - local_port_ = local_port; - udp_server_->startListening(); - udp_server_->addListener((UdpServerListener *)this); - log_stream_("[connect] Waiting for CLASS server messages on local port " << local_port); - } - - std::string server_port_str; - std::stringstream ss; - ss << server_port; - server_port_str = ss.str(); - log_stream_("[connect] Creating a client which connects to CLASS server (IP " << server_ip << ":" << server_port_str << ")"); - udp_client_ = new UDPClient(server_ip, server_port_str, -1); - - ss.str(std::string()); - ss << "connect " << local_port_; - std::string msg = ss.str(); - - return sendMsg(msg); -} - -ClassError::Error ClassCore::disconnect() -{ - std::stringstream ss; - ss << "disconnect " << local_port_; - std::string msg = ss.str(); - - int response = sendMsg(msg); - if (response != 0) - { - return ClassError::ERROR_SENDING_MSG; - } - - log_("[disconnect] Stopping local UPD server..."); - if (udp_server_ != nullptr) - { - udp_server_->removeListener((UdpServerListener *)this); - udp_server_->stopListening(); - } - log_("[disconnect] Local UDP server stopped"); - - return ClassError::CLASS_NO_ERROR; -} - -ClassError::Error ClassCore::setAcqConfig(const double &frequency, const std::vector<int> &channel_numbers, const double &gain, const std::string &input) -{ - // log_stream_("[setAcqConfig]"); - gain_ = gain; - - if (butterworth_ != nullptr) - { - for (int i = 0; i < channels_number_; ++i) - { - if (butterworth_[i] != nullptr) - { - delete butterworth_[i]; - } - } - delete[] butterworth_; - } - - channels_number_ = channel_numbers.size(); - log_stream_("[setAcqConfig] Number of channels: " << channels_number_); - - int channels_int = 0; - - for (int i = 0; i < channel_numbers.size(); i++) - { - if (channel_numbers[i] < 1 || channel_numbers[i] > 16) - { - log_error_stream_("[setAcqConfig] Channel " << i << "has the id " << channel_numbers[i] << " which is not in the interval >=1 and <=16"); - return ClassError::ERROR_NOT_VALID_CHANNEL_ID; - } - channels_int += (int)(pow(2, channel_numbers[i] - 1)); - } - - std::stringstream stream; - stream << "0x" - << std::setfill('0') << std::setw(2) // 2 digits hex 0xAA (4 digits does not work) - << std::hex << channels_int; - std::string channels_hex_str(stream.str()); - log_stream_("[setAcqConfig] channels hex: " << channels_hex_str); - - acq_frequency_ = frequency; - - log_("[setAcqConfig] setBufferCapacity"); - setBufferCapacity(acq_seconds_); - - log_("[setAcqConfig] configureFilter"); - configureFilter(filter_order_, 30.2, 32.2, acq_frequency_); - - return sendMsg(commands::ClassCommands::CMD_CONFIGACQ + std::to_string(frequency) + commands::ClassCommands::CMD_CONFIGACQ_PARAM1 +channels_hex_str + commands::ClassCommands::CMD_CONFIGACQ_PARAM2 + std::to_string(gain) + commands::ClassCommands::CMD_CONFIGACQ_PARAM3 + input + commands::ClassCommands::CMD_AUX); -} - -ClassError::Error ClassCore::setBufferCapacity(const double &seconds) -{ - acq_seconds_ = seconds; - if (acq_buffer_mutex_.try_lock()) - { - acq_buffer_.clear(); - acq_buffer_capacity_ = (int)(acq_frequency_ * acq_seconds_); - acq_buffer_.set_capacity(acq_buffer_capacity_); - acq_buffer_mutex_.unlock(); - } - else - { - log_warn_stream_("[setBufferCapacity] lock not acquired"); - increaseLockError(); - } - - return ClassError::CLASS_NO_ERROR; -} - -ClassError::Error ClassCore::configureFilter(int order, double low_freq, double up_freq, double acq_freq) -{ - filter_order_ = order; - double low = low_freq / (acq_freq / 2.0); - double up = up_freq / (acq_freq / 2.0); - - if (butterworth_ != nullptr) - { - for (int i = 0; i < channels_number_; ++i) - { - delete butterworth_[i]; - } - delete[] butterworth_; - } - - butterworth_ = new Butterworth *[channels_number_]; - for (int i = 0; i < channels_number_; ++i) - { - butterworth_[i] = new Butterworth(); - butterworth_[i]->configure(order, low, up); - } - - return ClassError::CLASS_NO_ERROR; -} - -ClassError::Error ClassCore::acqOn() -{ - ClassError::Error response = sendMsg(commands::ClassCommands::CMD_BUFFERFLUSH); - if (response != ClassError::CLASS_NO_ERROR) - { - return ClassError::ERROR_SENDING_MSG; - } - - if (acq_buffer_mutex_.try_lock()) - { - acq_buffer_.clear(); - acq_buffer_mutex_.unlock(); - } - else - { - log_warn_stream_("[acqOn] lock not acquired"); - increaseLockError(); - } - - is_acquiring_frames_mutex_.lock(); - is_acquiring_frames_ = true; - is_acquiring_frames_mutex_.unlock(); - - return sendMsg(commands::ClassCommands::CMD_ONACQ); -} - -ClassError::Error ClassCore::acqOff() -{ - is_acquiring_frames_mutex_.lock(); - is_acquiring_frames_ = false; - is_acquiring_frames_mutex_.unlock(); - - return sendMsg(commands::ClassCommands::CMD_OFFACQ); -} - -ClassError::Error ClassCore::acqImpedanceOn() -{ - ClassError::Error response = sendMsg(commands::ClassCommands::CMD_BUFFERFLUSH); - if (response != ClassError::CLASS_NO_ERROR) - { - return ClassError::ERROR_SENDING_MSG; - } - - if (acq_buffer_mutex_.try_lock()) - { - acq_buffer_.clear(); - acq_buffer_mutex_.unlock(); - } - else - { - log_warn_stream_("[acqImpedanceOn] lock not acquired"); - increaseLockError(); - } - - is_acquiring_impedances_mutex_.lock(); - is_acquiring_impedances_ = true; - is_acquiring_impedances_mutex_.unlock(); - - std::vector<std::string> msg_list; - msg_list.push_back(commands::ClassCommands::CMD_ONIMPEDANCEACQ); - msg_list.push_back(commands::ClassCommands::CMD_ONACQ); - - return sendMsgs(msg_list); -} - -ClassError::Error ClassCore::acqImpedanceOff() -{ - is_acquiring_impedances_mutex_.lock(); - is_acquiring_impedances_ = false; - is_acquiring_impedances_mutex_.unlock(); - - std::vector<std::string> msg_list; - msg_list.push_back(commands::ClassCommands::CMD_OFFIMPEDANCEACQ); - msg_list.push_back(commands::ClassCommands::CMD_OFFACQ); - - return sendMsgs(msg_list); -} - -ClassError::Error ClassCore::acqStreamOn() -{ - return sendMsg(commands::ClassCommands::CMD_STREAMONACQ); -} - -ClassError::Error ClassCore::acqStreamOff() -{ - return sendMsg(commands::ClassCommands::CMD_STREAMOFFACQ); -} - -ClassError::Error ClassCore::acqInputNormal() -{ - return sendMsg(commands::ClassCommands::CMD_NORMALACQ); -} - -ClassError::Error ClassCore::acqInputTest() -{ - return sendMsg(commands::ClassCommands::CMD_TESTACQ); -} - -ClassError::Error ClassCore::stimOn() -{ - return sendMsg(commands::ClassCommands::CMD_ONSTIM); -} - -ClassError::Error ClassCore::stimOff() -{ - return sendMsg(commands::ClassCommands::CMD_OFFSTIM); -} - -ClassError::Error ClassCore::elecPads(const int &id, const int &pads_number) -{ - // chek whether the electrode exists. If so, update, if not insert - int electrode_index = -1; - for (unsigned int i = 0; i < electrodes_.size(); i++) - { - Elec elec = electrodes_[i]; - if (elec.id == id) - { - electrode_index = i; - break; - } - } - - if (electrode_index >= 0) - { - electrodes_[electrode_index].pads_number = pads_number; - } - else - { - Elec elec; - elec.id = id; - elec.pads_number = pads_number; - - electrodes_.push_back(elec); - } - - return sendMsg(commands::ClassCommands::CMD_CONFIGELEC + std::to_string(id) + commands::ClassCommands::CMD_CONFIGACQ_PARAM1 + std::to_string(pads_number) + commands::ClassCommands::CMD_AUX); -} - -ClassError::Error ClassCore::stimFreq(const double &frequency) -{ - if(frequency < FREQ_MIN_VALUE || frequency > FREQ_MAX_VALUE) - { - return ClassError::ERROR_NOT_VALID_VALUE; - } - else - { - return sendMsg(commands::ClassCommands::CMD_SETFREQ + std::to_string(frequency) + commands::ClassCommands::CMD_AUX); - } -} - -ClassError::Error ClassCore::devName(const std::string& devicename) -{ - return sendMsg(commands::ClassCommands::CMD_SETDEVICENAME + devicename + commands::ClassCommands::CMD_AUX); -} - -ClassError::Error ClassCore::hvValue(const std::string& hvvalue) -{ - if(std::stoi(hvvalue) < HV_MIN_VALUE || std::stoi(hvvalue) > HV_MAX_VALUE) - { - return ClassError::ERROR_NOT_VALID_VALUE; - } - else - { - return sendMsg(commands::ClassCommands::CMD_SETHV + hvvalue + commands::ClassCommands::CMD_AUX); - } -} - -ClassError::Error ClassCore::hvOn() -{ - return sendMsg(commands::ClassCommands::CMD_ONHV); -} - -ClassError::Error ClassCore::hvOff() -{ - return sendMsg(commands::ClassCommands::CMD_OFFHV); -} - -ClassError::Error ClassCore::logeventsOn() -{ - return sendMsg(commands::ClassCommands::CMD_ONLOGEVENTS); -} - -ClassError::Error ClassCore::logeventsOff() -{ - return sendMsg(commands::ClassCommands::CMD_OFFLOGEVENTS); -} - -ClassError::Error ClassCore::intervalValue(const std::string& interval) -{ - if(std::stoi(interval) < INTERVAL_MIN_VALUE || std::stoi(interval) > INTERVAL_MAX_VALUE) - { - return ClassError::ERROR_NOT_VALID_VALUE; - } - else - { - return sendMsg(commands::ClassCommands::CMD_SETINTERVAL + interval + commands::ClassCommands::CMD_AUX); - } -} - -ClassError::Error ClassCore::buzzerTempo(const std::string& tempo) -{ - if(std::stoi(tempo) < BUZZER_MIN_VALUE || std::stoi(tempo) > BUZZER_MAX_VALUE) - { - return ClassError::ERROR_NOT_VALID_VALUE; - } - else - { - return sendMsg(commands::ClassCommands::CMD_SETBUZZER + tempo + commands::ClassCommands::CMD_AUX); - } -} - -ClassError::Error ClassCore::buzzerPlay() -{ - return sendMsg(commands::ClassCommands::CMD_PLAYBUZZER); -} - -ClassError::Error ClassCore::rtcDate(const std::string& rtcDate) -{ - return sendMsg(commands::ClassCommands::CMD_SETRTCDATE + rtcDate + commands::ClassCommands::CMD_AUX); -} - -ClassError::Error ClassCore::rtcTime(const std::string& rtcTime) -{ - return sendMsg(commands::ClassCommands::CMD_SETRTCTIME + rtcTime + commands::ClassCommands::CMD_AUX); -} - -ClassError::Error ClassCore::shutdown() -{ - return sendMsg(commands::ClassCommands::CMD_SWITCHOFF); -} - -ClassError::Error ClassCore::sdFunctionName(const std::string& sdfunctionname) -{ - return sendMsg(commands::ClassCommands::CMD_SETSDFUNCTION + sdfunctionname + commands::ClassCommands::CMD_AUX); -} - -ClassError::Error ClassCore::sdUName(const std::string& sduname) -{ - return sendMsg(commands::ClassCommands::CMD_SETSDNAME + sduname + commands::ClassCommands::CMD_AUX); -} - -ClassError::Error ClassCore::pattern(const int &id, const std::vector<Pattern> &pat) -{ - sendMsg(commands::ClassCommands::CMD_CONFIGPATTERN + std::to_string(id) + commands::ClassCommands::CMD_CONFIGACQ_PARAM1 + commands::ClassCommands::CMD_AUX); - - std::this_thread::sleep_for(std::chrono::milliseconds(300)); - for(int i = 0; i < pat.size() ; i++) - { - - sendMsg(commands::ClassCommands::CMD_CONFIGPATTERN + std::to_string(id) + commands::ClassCommands::CMD_CONFIGPATTERN_PARAM2 + pat[i].amp + " " + pat[i].pw + " " + pat[i].r + " " + std::to_string(pat[i].ampval) + " " + std::to_string(pat[i].pwval) + " " + std::to_string(pat[i].time) + commands::ClassCommands::CMD_AUX); - std::this_thread::sleep_for(std::chrono::milliseconds(300)); - } - - return sendMsg(commands::ClassCommands::CMD_CONFIGPATTERN + std::to_string(id) + commands::ClassCommands::CMD_CONFIGACQ_PARAM3 + commands::ClassCommands::CMD_AUX); - -} - -ClassError::Error ClassCore::patternClear(const int& id) -{ - return sendMsg(commands::ClassCommands::CMD_CONFIGPATTERN + std::to_string(id) + commands::ClassCommands::CMD_CONFIGACQ_PARAM1 + commands::ClassCommands::CMD_AUX); -} - -ClassError::Error ClassCore::velec(const int &id, const std::string &name, const int &electrode_id, const std::vector<int> &cathodes, const std::vector<int> &anodes, const std::vector<double> &, const std::vector<int> &width, const bool &selected, const bool &sync) -{ - // check whether there is an electrode in the list with id=electrode_id - int electrode_index = -1; - for (unsigned int i = 0; i < electrodes_.size(); i++) - { - Elec elec = electrodes_[i]; - if (elec.id == electrode_id) - { - electrode_index = i; - break; - } - } - - if (electrode_index < 0) - { - log_warn_stream_("[velec] No electrode with id: " << electrode_id << " configured from this client."); - } - - // check whether there is an virtual_electrode in the list with id=id - int virtual_electrode_index = -1; - for (unsigned int i = 0; i < virtual_electrodes_.size(); i++) - { - Velec elec = virtual_electrodes_[i]; - if (elec.id == id) - { - virtual_electrode_index = i; - break; - } - } - - if (virtual_electrode_index < 0) - { - // new velec - Velec elec; - elec.id = id; - elec.selected = selected; - elec.name = name; - - virtual_electrodes_.push_back(elec); - } - else - { - // update velec - virtual_electrodes_[electrode_index].selected = selected; - virtual_electrodes_[electrode_index].name = name; - } - - if (cathodes.size() == 0) - { - log_err_("[virtualElectrode] Cathode vector is empty"); - return ClassError::ERROR_EMPTY_CATHODE; - } - - if (anodes.size() == 0) - { - log_err_("[virtualElectrode] Anode vector is empty"); - return ClassError::ERROR_EMPTY_ANODE; - } - - // check whether the length of cathodes, amp and width are the same - if (cathodes.size() != amp.size() || cathodes.size() != width.size()) - { - log_err_("[virtualElectrode] Cathode, amp and width vector sizes are different"); - return ClassError::ERROR_CATHODE_AMP_DIFFERENT_SIZE; - } - - std::stringstream ss; - ss << "velec " << id << " *name " << name << " *elec " << electrode_id << " *pads "; - //commands::ClassCommands::CMD_CONFIGVELEC + id + commands::ClassCommands::CMD_CONFIGVELEC_PARAM1 + name + commands::ClassCommands::CMD_CONFIGVELEC_PARAM2 + electrode_id + commands::ClassCommands::CMD_CONFIGVELEC_PARAM3 - for (unsigned int i = 0; i < cathodes.size(); i++) - { - ss << cathodes[i] << "=C" - << ","; - } - for (unsigned int i = 0; i < anodes.size(); i++) - { - ss << anodes[i] << "=A" - << ","; - } - - ss << " *amp "; - for (unsigned int i = 0; i < amp.size(); i++) - { - ss << cathodes[i] << "=" << amp[i] << ","; - } - ss << " *width "; - for (unsigned int i = 0; i < width.size(); i++) - { - ss << cathodes[i] << "=" << width[i] << ","; - } - ss << " *selected "; - if (selected) - { - ss << "1"; - } - else - { - ss << "0"; - } - ss << " *sync "; - if (sync) - { - ss << "1"; - } - else - { - ss << "0"; - } - ss << "\r\n"; - std::string msg = ss.str(); - - return sendMsg(msg); -} - -ClassError::Error ClassCore::velecSelected(const int &id, const bool &selected) -{ - int virtual_electrode_index = -1; - for (unsigned int i = 0; i < virtual_electrodes_.size(); i++) - { - Velec elec = virtual_electrodes_[i]; - if (elec.id == id) - { - virtual_electrode_index = i; - break; - } - } - - if (virtual_electrode_index < 0) - { - log_warn_stream_("[velecSelected] No virtual electrode with id: " << id << " configured from this client."); - } - - if(selected) - { - return sendMsg(commands::ClassCommands::CMD_CONFIGVELEC + std::to_string(id) + commands::ClassCommands::CMD_CONFIGVELEC_PARAM4 + commands::ClassCommands::CMD_VELEC_SELECTED + commands::ClassCommands::CMD_AUX); - } - else - { - return sendMsg(commands::ClassCommands::CMD_CONFIGVELEC + std::to_string(id) + commands::ClassCommands::CMD_CONFIGVELEC_PARAM4 + commands::ClassCommands::CMD_VELEC_NOTSELECTED + commands::ClassCommands::CMD_AUX); - } -} - -ClassError::Error ClassCore::velecsSelected(const std::vector<int> &id, const std::vector<bool> &selected) -{ - if (id.size() != selected.size()) - { - return ClassError::ERROR_DIF_VECTOR_SIZE; - } - - std::vector<std::string> msg_list; - - for (int velecIndex = 0; velecIndex < id.size(); velecIndex++) - { - int virtual_electrode_index = -1; - for (unsigned int i = 0; i < virtual_electrodes_.size(); i++) - { - Velec elec = virtual_electrodes_[i]; - if (elec.id == id[velecIndex]) - { - virtual_electrode_index = i; - break; - } - } - - if (virtual_electrode_index < 0) - { - log_warn_stream_("[velecsSelected] No virtual electrode with id: " << id[velecIndex] << "configured from this client."); - } - - if (selected[velecIndex]) - { - msg_list.push_back(commands::ClassCommands::CMD_CONFIGVELEC + std::to_string(id[velecIndex]) + commands::ClassCommands::CMD_CONFIGVELEC_PARAM4 + commands::ClassCommands::CMD_VELEC_SELECTED + commands::ClassCommands::CMD_AUX); - } - else - { - msg_list.push_back(commands::ClassCommands::CMD_CONFIGVELEC + std::to_string(id[velecIndex]) + commands::ClassCommands::CMD_CONFIGVELEC_PARAM4 + commands::ClassCommands::CMD_VELEC_NOTSELECTED + commands::ClassCommands::CMD_AUX); //ss << "0"; - } - } - return sendMsgs(msg_list); -} - -ClassError::Error ClassCore::stimVelec(const std::string &name) -{ - int virtual_electrode_index = -1; - for (unsigned int i = 0; i < virtual_electrodes_.size(); i++) - { - Velec elec = virtual_electrodes_[i]; - if (elec.name == name) - { - virtual_electrode_index = i; - break; - } - } - - if (virtual_electrode_index < 0) - { - log_warn_stream_("[velecSelected] No virtual electrode with name: " << name << " condifgured from this client."); - } - - return sendMsg(commands::ClassCommands::CMD_VELECSTIM + name + commands::ClassCommands::CMD_AUX); - -} - -ClassError::Error ClassCore::acqImpedanceConfig(const bool &positive) -{ - std::stringstream ss; - ss << "acq impedance_config *channels "; - if (positive) - { - ss << "positives"; - } - else - { - ss << "negatives"; - } - ss << "\r\n"; - std::string msg = ss.str(); - - return sendMsg(msg); -} - -ClassError::Error ClassCore::acqImpedancePolarity(const bool &unipolar) -{ - std::stringstream ss; - ss << "acq config type "; - if (unipolar) - { - ss << "unipolar"; - } - else - { - ss << "bipolar"; - } - ss << "\r\n"; - std::string msg = ss.str(); - - return sendMsg(msg); -} - -ClassError::Error ClassCore::initCommunication(const std::string &init_mode) -{ - return sendMsg(commands::ClassCommands::CMD_INIT + init_mode + commands::ClassCommands::CMD_AUX); -} - -ClassError::Error ClassCore::getAcqFrames(std::vector<AcqFrame> &acq_frames) -{ - bool is_acquiring_frames = false; - is_acquiring_frames_mutex_.lock(); - is_acquiring_frames = is_acquiring_frames_; - is_acquiring_frames_mutex_.unlock(); - - bool is_acquiring_impedances = false; - is_acquiring_impedances_mutex_.lock(); - is_acquiring_impedances = is_acquiring_impedances_; - is_acquiring_impedances_mutex_.unlock(); - - if (!is_acquiring_frames && !is_acquiring_impedances) - { - log_stream_("[getAcqFrames] The device is not acquiring frames"); - return ClassError::ERROR_DEVICE_NOT_ACQUIRING; - } - - acq_frames.clear(); - if (acq_buffer_mutex_.try_lock()) - { - for (int i = 0; i < acq_buffer_.size(); i++) - { - acq_frames.push_back(acq_buffer_[i]); - } - acq_buffer_mutex_.unlock(); - } - else - { - log_warn_stream_("[getAcqFrames] lock not acquired"); - increaseLockError(); - } - - return ClassError::CLASS_NO_ERROR; -} - -ClassError::Error ClassCore::sendMsg(std::string msg) -{ - log_stream_("[sendMsg] Msg:" << msg); - if (udp_client_ == nullptr) - { - return ClassError::ERROR_UDP_CLIENT_NULL; - } - udp_client_->send(msg); - - // log_stream_("[sendMsg] Msg sent"); - - return ClassError::CLASS_NO_ERROR; -} - -ClassError::Error ClassCore::sendMsgs(std::vector<std::string> msgs) -{ - // wrap msgs in a string until MSG_MAX_LENGTH - std::string string_with_msgs_prev = ""; - std::stringstream ss; - int msg_index = 0; - while (msg_index < msgs.size()) - { - ss << msgs[msg_index]; - std::string string_with_msgs = ss.str(); - - if (string_with_msgs.length() > MSG_MAX_LENGTH) - { - // clear stringstream - ss.str(std::string()); - // send prev and do not increase index - ClassError::Error response = sendMsg(string_with_msgs_prev); - if (response != ClassError::CLASS_NO_ERROR) - { - return response; - } - - string_with_msgs_prev = ""; - } - else - { - // continue concatenating - msg_index += 1; - string_with_msgs_prev = string_with_msgs; - } - } - - if (string_with_msgs_prev.length() != 0) - { - ClassError::Error response = sendMsg(string_with_msgs_prev); - if (response != ClassError::CLASS_NO_ERROR) - { - return response; - } - } - - return ClassError::CLASS_NO_ERROR; -} - -void ClassCore::udpMsgReceived(std::string msg, std::string ip) -{ - // processing depends on the status - //log_stream_("[udpMsgReceived] Msg received from CLASS server: " << msg << ". Msg length: " << msg.length()); - - tic_ = ""; - firmware_ = ""; - device_ = ""; - logevents_ = ""; - - - std::string temphvstatus; - if (!hvstatus_.empty()){ - temphvstatus = hvstatus_; - } else { - temphvstatus = ""; - } - hvstatus_ = ""; - - intervalstatus_ = ""; - rtcstatus_ = ""; - buzzerstatus_ = ""; - frequencystatus_ = ""; - sdfunctionstatus_ = ""; - sdunamestatus_ = ""; - patternstatus_ = ""; - hardware_ = ""; - velecstatus_ = ""; - - std::string battery_capacity_str = "battery *capacity="; - std::size_t found = msg.find(battery_capacity_str); - - if (msg.find("tic ") != std::string::npos) - { - tic_ = msg; - - double is_waiting_tic = false; - if (tic_mutex_.try_lock()) - { - is_waiting_tic = is_waiting_tic_; - tic_mutex_.unlock(); - } - - if (is_waiting_tic) - { - if (tic_mutex_.try_lock()) - { - tic_ = msg; - tic_received_ = true; - tic_mutex_.unlock(); - } - } - } - else if (msg.find("firmware") != std::string::npos) - { - // firmware_ = msg; - double is_waiting_firmware = false; - if (firmware_mutex_.try_lock()) - { - is_waiting_firmware = is_waiting_firmware_; - firmware_mutex_.unlock(); - } - - if (is_waiting_firmware) - { - if (firmware_mutex_.try_lock()) - { - firmware_ = msg; - firmware_received_ = true; - firmware_mutex_.unlock(); - } - } - } - else if (msg.find("velec ") != std::string::npos && (msg.find("*name ") == std::string::npos)) - { - double is_waiting_velecstatus = false; - if (velecstatus_mutex_.try_lock()) - { - is_waiting_velecstatus = is_waiting_velecstatus_; - velecstatus_mutex_.unlock(); - } - if (is_waiting_velecstatus) - { - if (velecstatus_mutex_.try_lock()) - { - velecstatus_ = msg; - velecstatus_received_ = true; - velecstatus_mutex_.unlock(); - } - } - } - else if (msg.find("device") != std::string::npos) - { - double is_waiting_device = false; - if (device_mutex_.try_lock()) - { - is_waiting_device = is_waiting_device_; - device_mutex_.unlock(); - } - - if (is_waiting_device) - { - if (device_mutex_.try_lock()) - { - device_ = msg; - device_received_ = true; - device_mutex_.unlock(); - } - } - } - else if (msg.find("hardware ") != std::string::npos) - { - //hardware_ = msg; - double is_waiting_hardware = false; - if (hardware_mutex_.try_lock()) - { - is_waiting_hardware = is_waiting_hardware_; - hardware_mutex_.unlock(); - } - - if (is_waiting_hardware) - { - if (hardware_mutex_.try_lock()) - { - hardware_ = msg; - hardware_received_ = true; - hardware_mutex_.unlock(); - } - } - } - else if (msg.find("logevents ") != std::string::npos) - { - double is_waiting_logevents = false; - if (logevents_mutex_.try_lock()) - { - is_waiting_logevents = is_waiting_logevents_; - logevents_mutex_.unlock(); - } - if (is_waiting_logevents) - { - if (logevents_mutex_.try_lock()) - { - logevents_ = msg; - logevents_received_ = true; - logevents_mutex_.unlock(); - } - } - } - else if (msg.find("hv ") != std::string::npos) - { - double is_waiting_hvstatus = false; - if (hvstatus_mutex_.try_lock()) - { - is_waiting_hvstatus = is_waiting_hvstatus_; - hvstatus_mutex_.unlock(); - } - if (is_waiting_hvstatus) - { - if (hvstatus_mutex_.try_lock()) - { - hvstatus_ = temphvstatus + msg; - hvstatus_received_ = true; - hvstatus_mutex_.unlock(); - } - } - } - else if (msg.find("interval ") != std::string::npos) - { - double is_waiting_intervalstatus = false; - if (intervalstatus_mutex_.try_lock()) - { - is_waiting_intervalstatus = is_waiting_intervalstatus_; - intervalstatus_mutex_.unlock(); - } - if (is_waiting_intervalstatus) - { - if (intervalstatus_mutex_.try_lock()) - { - intervalstatus_ = msg; - intervalstatus_received_ = true; - intervalstatus_mutex_.unlock(); - } - } - } - else if (msg.find("rtc ") != std::string::npos) - { - double is_waiting_rtcstatus = false; - if (rtcstatus_mutex_.try_lock()) - { - is_waiting_rtcstatus = is_waiting_rtcstatus_; - rtcstatus_mutex_.unlock(); - } - if (is_waiting_rtcstatus) - { - if (rtcstatus_mutex_.try_lock()) - { - rtcstatus_ = msg; - rtcstatus_received_ = true; - rtcstatus_mutex_.unlock(); - } - } - } - else if (msg.find("buzzer ") != std::string::npos) - { - double is_waiting_buzzerstatus = false; - if (buzzerstatus_mutex_.try_lock()) - { - is_waiting_buzzerstatus = is_waiting_buzzerstatus_; - buzzerstatus_mutex_.unlock(); - } - if (is_waiting_buzzerstatus) - { - if (buzzerstatus_mutex_.try_lock()) - { - buzzerstatus_ = msg; - buzzerstatus_received_ = true; - buzzerstatus_mutex_.unlock(); - } - } - } - else if (msg.find("freq ") != std::string::npos) - { - double is_waiting_frequencystatus = false; - if (frequencystatus_mutex_.try_lock()) - { - is_waiting_frequencystatus = is_waiting_frequencystatus_; - frequencystatus_mutex_.unlock(); - } - if (is_waiting_frequencystatus) - { - if (frequencystatus_mutex_.try_lock()) - { - frequencystatus_ = msg; - frequencystatus_received_ = true; - frequencystatus_mutex_.unlock(); - } - } - } - else if (msg.find("function ") != std::string::npos) - { - double is_waiting_sdfunction = false; - if (sdfunction_mutex_.try_lock()) - { - is_waiting_sdfunction = is_waiting_sdfunction_; - sdfunction_mutex_.unlock(); - } - if (is_waiting_sdfunction) - { - if (sdfunction_mutex_.try_lock()) - { - sdfunctionstatus_ = msg; - sdfunction_received_ = true; - sdfunction_mutex_.unlock(); - } - } - } - else if (msg.find("uname ") != std::string::npos) - { - double is_waiting_sduname = false; - if (sduname_mutex_.try_lock()) - { - is_waiting_sduname = is_waiting_sduname_; - sduname_mutex_.unlock(); - } - if (is_waiting_sduname) - { - if (sduname_mutex_.try_lock()) - { - sdunamestatus_ = msg; - sduname_received_ = true; - sduname_mutex_.unlock(); - } - } - } - else if (msg.find("pattern ") != std::string::npos) - { - double is_waiting_patternstatus = false; - if (patternstatus_mutex_.try_lock()) - { - is_waiting_patternstatus = is_waiting_patternstatus_; - patternstatus_mutex_.unlock(); - } - if (is_waiting_patternstatus) - { - if (patternstatus_mutex_.try_lock()) - { - patternstatus_ = msg; - patternstatus_received_ = true; - patternstatus_mutex_.unlock(); - } - } - } - else if (msg.find("battery *capacity=") != std::string::npos) - { - // log_stream_("[udpMsgReceived] battery msg received:" << msg); - double is_waiting_battery = false; - if (battery_mutex_.try_lock()) - { - is_waiting_battery = is_waiting_battery_; - battery_mutex_.unlock(); - } - - if (is_waiting_battery) - { - // log_stream_("[udpMsgReceived] extract battery level"); - // extract battery level - double battery; - - std::size_t found_space = msg.find(" ", found + battery_capacity_str.length()); - if (found_space != std::string::npos) - { - std::string battery_str = msg.substr(found + battery_capacity_str.length(), found_space - (found + battery_capacity_str.length())); - - // log_stream_("[udpMsgReceived] battery str: " << battery_str); - - try - { - battery = std::stod(battery_str); - // log_stream_("[udpMsgReceived] battery: " << battery); - if (battery_mutex_.try_lock()) - { - battery_ = battery; - battery_received_ = true; - battery_mutex_.unlock(); - } - } - catch (std::exception ex) - { - log_error_stream_("[udpMsgReceived] battery. cannot convert to double: " << battery_str); - return; - } - } - } - } - else if (msg.find("turnning off") != std::string::npos) - { - log_stream_("[udpMsgReceived] turn off received:" << msg); - - if (class_cb_ != nullptr) - { - if (language_ == "python") - { - class PyThreadStateLock PyThreadLock; // fix segmentation fault - class_cb_->turnOffHandle(); - } - else - { - class_cb_->turnOffHandle(); - } - } - } - else - { - bool is_acquiring_frames = false; - is_acquiring_frames_mutex_.lock(); - is_acquiring_frames = is_acquiring_frames_; - is_acquiring_frames_mutex_.unlock(); - - bool is_acquiring_impedances = false; - is_acquiring_impedances_mutex_.lock(); - is_acquiring_impedances = is_acquiring_impedances_; - is_acquiring_impedances_mutex_.unlock(); - - if (is_acquiring_frames || is_acquiring_impedances) - { - // myfile_ << msg; - int expected_bytes = 3 + 1 + 2 + channels_number_ * (1 + 3); - if (msg.length() != expected_bytes) - { - // log_warn_stream_("[udpMsgReceived] The message , which length is " << msg.length() << ", does not have the expected length " << expected_bytes << ". Msg:" << msg); - return; - } - - std::string timestamp_bin = msg.substr(0, 6); - - if (timestamp_bin.substr(3, 1) != ".") - { - // log_warn_stream_("[udpMsgReceived] Timestamp part does not have a point: " << msg); - return; - } - - AcqFrame frame; - - try - { - std::string timestamp_ms_bin = timestamp_bin.substr(0, 3); - int timestamp_ms = ((unsigned char)(timestamp_ms_bin.at(0)) << 16) + ((unsigned char)(timestamp_ms_bin.at(1)) << 8) + (unsigned char)(timestamp_ms_bin.at(2)); - - std::string timestamp_us_bin = timestamp_bin.substr(4, 2); - int timestamp_us = ((unsigned char)(timestamp_us_bin.at(0)) << 8) + (unsigned char)(timestamp_us_bin.at(1)); - - std::stringstream timestamp_stream; - timestamp_stream << timestamp_ms << "." << timestamp_us; - std::string timestamp_str(timestamp_stream.str()); - - frame.timestamp = std::stod(timestamp_str); - - int starting_index = 7; - for (int i = 0; i < channels_number_; i++) - { - std::string data_bin_str = msg.substr(starting_index, 3); - int data_bin = ((unsigned char)(data_bin_str.at(0)) << 16) + ((unsigned char)(data_bin_str.at(1)) << 8) + (unsigned char)(data_bin_str.at(2)); - - // get value of bit 24 - int bit_number = 23; - int mask = 1 << bit_number; - int masked_n = data_bin & mask; - int bit_value = masked_n >> bit_number; - - int data; - if (bit_value == 1) - { - int data_bin_xor = data_bin ^ int(pow(2, bit_number + 1) - 1); // bit xor - data = (data_bin_xor + 1) * -1; - } - else - { - data = data_bin; - } - - double chDataV = (data * 2 * 2.048) / (gain_ * pow(2.0, 24.0)); - double chDataUV = round(chDataV * 1000000); - - if (is_acquiring_frames) - { - // log_stream_("[udpMsgReceived] Value " << i << ": " << chDataUV); - // truncate - const auto result = trunc_n(chDataUV, 4); - frame.values.push_back(result.first); - } - else - { - // log_stream_("[udpMsgReceived] Value before filtering " << i << ": " << chDataUV); - if (butterworth_ == nullptr) - { - return; - } - double chDataUV_filtered; - butterworth_[i]->update(chDataUV, chDataUV_filtered); - double chDataNV_filtered = chDataUV_filtered * 1000.0; - // log_stream_("[udpMsgReceived] Value after filtering " << i << ": " << chDataNV_filtered); - double currentNA = 6; - // CHECK: it is a value per channel or unique value? do we have to take into account previous values? - double impedance = (chDataNV_filtered / currentNA) - 4700; - // log_stream_("[udpMsgReceived] Impedance " << i << ": " << impedance); - - // truncate - const auto result = trunc_n(impedance, 4); - frame.values.push_back(result.first); - } - starting_index += (3 + 1); // 3bytes of channel info + 1byte of space - } - } - catch (std::exception ex) - { - // log_error_stream_("[udpMsgReceived] error converting to double some of the values: " << msg); - return; - } - - if (is_acquiring_frames || is_acquiring_impedances) - { - if (acq_buffer_mutex_.try_lock()) - { - acq_buffer_.push_back(frame); - acq_buffer_mutex_.unlock(); - } - else - { - log_warn_stream_("[udpMsgReceived] lock not acquired"); - increaseLockError(); - } - } - else - { - acq_impedances_buffer_mutex_.lock(); - acq_impedances_buffer_.push_back(frame); - acq_impedances_buffer_mutex_.unlock(); - } - } - } -} - -ClassError::Error ClassCore::impedanceFilterOrder(const int &order) -{ - if (order == filter_order_) - { - return ClassError::CLASS_NO_ERROR; - } - - if (order <= 0) - { - return ClassError::ERROR_NOT_VALID_ORDER; - } - - return configureFilter(order, 30.2, 32.2, acq_frequency_); -} - -ClassError::Error ClassCore::bufferDuration(const double &ms) -{ - if (ms <= 0) - { - return ClassError::ERROR_NOT_VALID_MS; - } - - return setBufferCapacity(ms / 1000.0); -} - -ClassError::Error ClassCore::batteryLevel() -{ - ClassError::Error response = sendMsg(commands::ClassCommands::CMD_GETBATTERY); - - if (battery_mutex_.try_lock()) - { - is_waiting_battery_ = true; - battery_mutex_.unlock(); - } - - return response; -} - -ClassError::Error ClassCore::firmwareVersion() -{ - ClassError::Error response = sendMsg(commands::ClassCommands::CMD_GETFW); - - if (firmware_mutex_.try_lock()) - { - is_waiting_firmware_ = true; - firmware_mutex_.unlock(); - } - - return response; -} - -ClassError::Error ClassCore::deviceName() -{ - ClassError::Error response = sendMsg(commands::ClassCommands::CMD_GETDEVICENAME); - if (device_mutex_.try_lock()) - { - is_waiting_device_ = true; - device_mutex_.unlock(); - } - - return response; -} - -ClassError::Error ClassCore::logeventsStatus() -{ - ClassError::Error response = sendMsg(commands::ClassCommands::CMD_GETLOGEVENTS); - - if (logevents_mutex_.try_lock()) - { - is_waiting_logevents_ = true; - logevents_mutex_.unlock(); - } - - return response; -} - -ClassError::Error ClassCore::velecStatus(const int &number) -{ - - ClassError::Error response = sendMsg(commands::ClassCommands::CMD_CONFIGVELEC + std::to_string(number) + commands::ClassCommands::CMD_AUX); - - if (velecstatus_mutex_.try_lock()) - { - is_waiting_velecstatus_ = true; - velecstatus_mutex_.unlock(); - } - - return response; -} - -ClassError::Error ClassCore::patternStatus(const int &number) -{ - ClassError::Error response = sendMsg(commands::ClassCommands::CMD_CONFIGPATTERN + std::to_string(number) + commands::ClassCommands::CMD_AUX2 + commands::ClassCommands::CMD_AUX); - if (patternstatus_mutex_.try_lock()) - { - is_waiting_patternstatus_ = true; - patternstatus_mutex_.unlock(); - } - - return response; -} - -ClassError::Error ClassCore::hvStatus() -{ - ClassError::Error response = sendMsg(commands::ClassCommands::CMD_GETHV); - - if (hvstatus_mutex_.try_lock()) - { - is_waiting_hvstatus_ = true; - hvstatus_mutex_.unlock(); - } - - return response; -} - -ClassError::Error ClassCore::intervalStatus() -{ - ClassError::Error response = sendMsg(commands::ClassCommands::CMD_GETINTERVAL); - - if (intervalstatus_mutex_.try_lock()) - { - is_waiting_intervalstatus_ = true; - intervalstatus_mutex_.unlock(); - } - - return response; -} - -ClassError::Error ClassCore::rtcStatus() -{ - ClassError::Error response = sendMsg(commands::ClassCommands::CMD_GETRTC); - - if (rtcstatus_mutex_.try_lock()) - { - is_waiting_rtcstatus_ = true; - rtcstatus_mutex_.unlock(); - } - - return response; -} - -ClassError::Error ClassCore::buzzerStatus() -{ - ClassError::Error response = sendMsg(commands::ClassCommands::CMD_GETBUZZER); - - if (buzzerstatus_mutex_.try_lock()) - { - is_waiting_buzzerstatus_ = true; - buzzerstatus_mutex_.unlock(); - } - - return response; -} - -ClassError::Error ClassCore::frequencyStatus() -{ - ClassError::Error response = sendMsg(commands::ClassCommands::CMD_GETFRQUENCY); - - if (frequencystatus_mutex_.try_lock()) - { - is_waiting_frequencystatus_ = true; - frequencystatus_mutex_.unlock(); - } - - return response; -} - -ClassError::Error ClassCore::sdfunctionStatus() -{ - ClassError::Error response = sendMsg(commands::ClassCommands::CMD_GETSDFUNCTION); - - if (sdfunction_mutex_.try_lock()) - { - is_waiting_sdfunction_ = true; - sdfunction_mutex_.unlock(); - } - - return response; -} - -ClassError::Error ClassCore::sdunameStatus() -{ - ClassError::Error response = sendMsg(commands::ClassCommands::CMD_GETSDNAME); - - if (sduname_mutex_.try_lock()) - { - is_waiting_sduname_ = true; - sduname_mutex_.unlock(); - } - - return response; -} - -ClassError::Error ClassCore::hardwareVersion() -{ - ClassError::Error response = sendMsg(commands::ClassCommands::CMD_GETHW); - - if (hardware_mutex_.try_lock()) - { - is_waiting_hardware_ = true; - hardware_mutex_.unlock(); - } - - return response; -} - -ClassError::Error ClassCore::tic() -{ - ClassError::Error response = sendMsg(commands::ClassCommands::CMD_GETTIC); - - if (tic_mutex_.try_lock()) - { - is_waiting_tic_ = true; - tic_mutex_.unlock(); - } - - return response; -} - -void ClassCore::waitingThreadFunction_() -{ - waiting_ = true; - - bool waiting = true; - - log_stream_("[waitingThreadFunction_] Thread for waiting for callback messages started"); - - do - { - bool is_waiting_tic = false; - bool tic_received = false; - - bool is_waiting_firmware = false; - bool firmware_received = false; - - bool is_waiting_hardware = false; - bool hardware_received = false; - - bool is_waiting_battery = false; - bool battery_received = false; - - bool is_waiting_device = false; - bool device_received = false; - - bool is_waiting_logevents = false; - bool logevents_received = false; - - bool is_waiting_hvstatus = false; - bool hvstatus_received = false; - - bool is_waiting_intervalstatus = false; - bool intervalstatus_received = false; - - bool is_waiting_rtcstatus = false; - bool rtcstatus_received = false; - - bool is_waiting_buzzerstatus = false; - bool buzzerstatus_received = false; - - bool is_waiting_frequencystatus = false; - bool frequencystatus_received = false; - - bool is_waiting_sdfunctionstatus = false; - bool sdfunctionstatus_received = false; - - bool is_waiting_sdunamestatus = false; - bool sdunamestatus_received = false; - - bool is_waiting_patternstatus = false; - bool patternstatus_received = false; - - bool is_waiting_velecstatus = false; - bool velecstatus_received = false; - - double battery = 0; - - std::string tic = ""; - std::string firmware = ""; - std::string hardware = ""; - std::string device = ""; - std::string logevents = ""; - std::string hvstatus = ""; - std::string intervalstatus = ""; - std::string rtcstatus = ""; - std::string buzzerstatus = ""; - std::string frequencystatus = ""; - std::string sdfunctionstatus = ""; - std::string sdunamestatus = ""; - std::string patternstatus = ""; - std::string velecstatus = ""; - - // FIRMWARE - // if (firmware_ != "") - // { - // firmware = firmware_; - // class_cb_->firmwareHandle(firmware); - // } - - if (firmware_mutex_.try_lock()) - { - is_waiting_firmware = is_waiting_firmware_; - firmware_received = firmware_received_; - firmware = firmware_; - firmware_mutex_.unlock(); - } - else - { - log_warn_stream_("[waitingThreadFunction_] firmware lock not acquired"); - } - - if (is_waiting_firmware && firmware_received) - { - if (class_cb_ != nullptr) - { - if (language_ == "python") - { - class PyThreadStateLock PyThreadLock; // fix segmentation fault - class_cb_->firmwareHandle(firmware); - } - else - { - class_cb_->firmwareHandle(firmware); - } - if (firmware_mutex_.try_lock()) - { - firmware_received_ = false; - is_waiting_firmware_ = false; - firmware_mutex_.unlock(); - } - } - else - { - log_error_stream_("[waitingThreadFunction_] callback is null"); - } - } - // END OF FIRMWARE -if (velecstatus_mutex_.try_lock()) - { - is_waiting_velecstatus = is_waiting_velecstatus_; - velecstatus_received = velecstatus_received_; - velecstatus = velecstatus_; - velecstatus_mutex_.unlock(); - } - else - { - log_warn_stream_("[waitingThreadFunction_] velecstatus lock not acquired"); - } - - if (is_waiting_velecstatus && velecstatus_received) - { - if (class_cb_ != nullptr) - { - if (language_ == "python") - { - class PyThreadStateLock PyThreadLock; // fix segmentation fault - class_cb_->velecstatusHandle(velecstatus); - } - else - { - class_cb_->velecstatusHandle(velecstatus); - } - if (velecstatus_mutex_.try_lock()) - { - velecstatus_received_ = false; - is_waiting_velecstatus_ = false; - velecstatus_mutex_.unlock(); - } - } - else - { - log_error_stream_("[waitingThreadFunction_] callback is null"); - } - } - // END OF VELECSTATUS - if (device_mutex_.try_lock()) - { - is_waiting_device = is_waiting_device_; - device_received = device_received_; - device = device_; - device_mutex_.unlock(); - } - else - { - log_warn_stream_("[waitingThreadFunction_] device lock not acquired"); - } - - if (is_waiting_device && device_received) - { - if (class_cb_ != nullptr) - { - if (language_ == "python") - { - class PyThreadStateLock PyThreadLock; // fix segmentation fault - class_cb_->deviceNameHandle(device); - } - else - { - class_cb_->deviceNameHandle(device); - } - if (device_mutex_.try_lock()) - { - device_received_ = false; - is_waiting_device_ = false; - device_mutex_.unlock(); - } - } - else - { - log_error_stream_("[waitingThreadFunction_] callback is null"); - } - } - - //END of device name - if (logevents_mutex_.try_lock()) - { - is_waiting_logevents = is_waiting_logevents_; - logevents_received = logevents_received_; - logevents = logevents_; - logevents_mutex_.unlock(); - } - else - { - log_warn_stream_("[waitingThreadFunction_] logevents lock not acquired"); - } - - if (is_waiting_logevents && logevents_received) - { - if (class_cb_ != nullptr) - { - if (language_ == "python") - { - class PyThreadStateLock PyThreadLock; // fix segmentation fault - class_cb_->logeventsHandle(logevents); - } - else - { - class_cb_->logeventsHandle(logevents); - } - if (logevents_mutex_.try_lock()) - { - logevents_received_ = false; - is_waiting_logevents_ = false; - logevents_mutex_.unlock(); - } - } - else - { - log_error_stream_("[waitingThreadFunction_] callback is null"); - } - } - //END of logevents - if (patternstatus_mutex_.try_lock()) - { - is_waiting_patternstatus = is_waiting_patternstatus_; - patternstatus_received = patternstatus_received_; - patternstatus = patternstatus_; - patternstatus_mutex_.unlock(); - } - else - { - log_warn_stream_("[waitingThreadFunction_] patternstatus lock not acquired"); - } - - if (is_waiting_patternstatus && patternstatus_received) - { - if (class_cb_ != nullptr) - { - if (language_ == "python") - { - class PyThreadStateLock PyThreadLock; // fix segmentation fault - class_cb_->patternHandle(patternstatus); - } - else - { - class_cb_->patternHandle(patternstatus); - } - if (patternstatus_mutex_.try_lock()) - { - patternstatus_received_ = false; - is_waiting_patternstatus_ = false; - patternstatus_mutex_.unlock(); - } - } - else - { - log_error_stream_("[waitingThreadFunction_] callback is null"); - } - } - //END of pattern status - if (hvstatus_mutex_.try_lock()) - { - is_waiting_hvstatus = is_waiting_hvstatus_; - hvstatus_received = hvstatus_received_; - hvstatus = hvstatus_; - hvstatus_mutex_.unlock(); - } - else - { - log_warn_stream_("[waitingThreadFunction_] hvstatus lock not acquired"); - } - - if (is_waiting_hvstatus && hvstatus_received) - { - if (class_cb_ != nullptr) - { - if (language_ == "python") - { - class PyThreadStateLock PyThreadLock; // fix segmentation fault - class_cb_->hvHandle(hvstatus); - } - else - { - class_cb_->hvHandle(hvstatus); - } - if (hvstatus_mutex_.try_lock()) - { - hvstatus_received_ = false; - is_waiting_hvstatus_ = false; - hvstatus_mutex_.unlock(); - } - } - else - { - log_error_stream_("[waitingThreadFunction_] callback is null"); - } - } - //END of hvstatus - - if (intervalstatus_mutex_.try_lock()) - { - is_waiting_intervalstatus = is_waiting_intervalstatus_; - intervalstatus_received = intervalstatus_received_; - intervalstatus = intervalstatus_; - intervalstatus_mutex_.unlock(); - } - else - { - log_warn_stream_("[waitingThreadFunction_] intervalstatus lock not acquired"); - } - - if (is_waiting_intervalstatus && intervalstatus_received) - { - if (class_cb_ != nullptr) - { - if (language_ == "python") - { - class PyThreadStateLock PyThreadLock; // fix segmentation fault - class_cb_->intervalHandle(intervalstatus); - } - else - { - class_cb_->intervalHandle(intervalstatus); - } - if (intervalstatus_mutex_.try_lock()) - { - intervalstatus_received_ = false; - is_waiting_intervalstatus_ = false; - intervalstatus_mutex_.unlock(); - } - } - else - { - log_error_stream_("[waitingThreadFunction_] callback is null"); - } - } - //END of intervalstatus - - if (rtcstatus_mutex_.try_lock()) - { - is_waiting_rtcstatus = is_waiting_rtcstatus_; - rtcstatus_received = rtcstatus_received_; - rtcstatus = rtcstatus_; - rtcstatus_mutex_.unlock(); - } - else - { - log_warn_stream_("[waitingThreadFunction_] rtcstatus lock not acquired"); - } - - if (is_waiting_rtcstatus && rtcstatus_received) - { - if (class_cb_ != nullptr) - { - if (language_ == "python") - { - class PyThreadStateLock PyThreadLock; // fix segmentation fault - class_cb_->rtcHandle(rtcstatus); - } - else - { - class_cb_->rtcHandle(rtcstatus); - } - if (rtcstatus_mutex_.try_lock()) - { - rtcstatus_received_ = false; - is_waiting_rtcstatus_ = false; - rtcstatus_mutex_.unlock(); - } - } - else - { - log_error_stream_("[waitingThreadFunction_] callback is null"); - } - } - //END of rtc - - if (buzzerstatus_mutex_.try_lock()) - { - is_waiting_buzzerstatus = is_waiting_buzzerstatus_; - buzzerstatus_received = buzzerstatus_received_; - buzzerstatus = buzzerstatus_; - buzzerstatus_mutex_.unlock(); - } - else - { - log_warn_stream_("[waitingThreadFunction_] buzzer lock not acquired"); - } - - if (is_waiting_buzzerstatus && buzzerstatus_received) - { - if (class_cb_ != nullptr) - { - if (language_ == "python") - { - class PyThreadStateLock PyThreadLock; // fix segmentation fault - class_cb_->buzzerHandle(buzzerstatus); - } - else - { - class_cb_->buzzerHandle(buzzerstatus); - } - if (buzzerstatus_mutex_.try_lock()) - { - buzzerstatus_received_ = false; - is_waiting_buzzerstatus_ = false; - buzzerstatus_mutex_.unlock(); - } - } - else - { - log_error_stream_("[waitingThreadFunction_] callback is null"); - } - } - //END of buzzer - if (frequencystatus_mutex_.try_lock()) - { - is_waiting_frequencystatus = is_waiting_frequencystatus_; - frequencystatus_received = frequencystatus_received_; - frequencystatus = frequencystatus_; - frequencystatus_mutex_.unlock(); - } - else - { - log_warn_stream_("[waitingThreadFunction_] frequency lock not acquired"); - } - - if (is_waiting_frequencystatus && frequencystatus_received) - { - if (class_cb_ != nullptr) - { - if (language_ == "python") - { - class PyThreadStateLock PyThreadLock; // fix segmentation fault - class_cb_->frequencyHandle(frequencystatus); - } - else - { - class_cb_->frequencyHandle(frequencystatus); - } - if (frequencystatus_mutex_.try_lock()) - { - frequencystatus_received_ = false; - is_waiting_frequencystatus_ = false; - frequencystatus_mutex_.unlock(); - } - } - else - { - log_error_stream_("[waitingThreadFunction_] callback is null"); - } - } - //END of frequency - - if (sdfunction_mutex_.try_lock()) - { - is_waiting_sdfunctionstatus = is_waiting_sdfunction_; - sdfunctionstatus_received = sdfunction_received_; - sdfunctionstatus = sdfunctionstatus_; - sdfunction_mutex_.unlock(); - } - else - { - log_warn_stream_("[waitingThreadFunction_] sdfunction lock not acquired"); - } - - if (is_waiting_sdfunctionstatus && sdfunctionstatus_received) - { - if (class_cb_ != nullptr) - { - if (language_ == "python") - { - class PyThreadStateLock PyThreadLock; // fix segmentation fault - class_cb_->sdfunctionHandle(sdfunctionstatus); - } - else - { - class_cb_->sdfunctionHandle(sdfunctionstatus); - } - if (sdfunction_mutex_.try_lock()) - { - sdfunction_received_ = false; - is_waiting_sdfunction_ = false; - sdfunction_mutex_.unlock(); - } - } - else - { - log_error_stream_("[waitingThreadFunction_] callback is null"); - } - } - //END of sdfunction - - if (sduname_mutex_.try_lock()) - { - is_waiting_sdunamestatus = is_waiting_sduname_; - sdunamestatus_received = sduname_received_; - sdunamestatus = sdunamestatus_; - sduname_mutex_.unlock(); - } - else - { - log_warn_stream_("[waitingThreadFunction_] sduname lock not acquired"); - } - - if (is_waiting_sdunamestatus && sdunamestatus_received) - { - if (class_cb_ != nullptr) - { - if (language_ == "python") - { - class PyThreadStateLock PyThreadLock; // fix segmentation fault - class_cb_->sdunameHandle(sdunamestatus); - } - else - { - class_cb_->sdunameHandle(sdunamestatus); - } - if (sduname_mutex_.try_lock()) - { - sduname_received_ = false; - is_waiting_sduname_ = false; - sduname_mutex_.unlock(); - } - } - else - { - log_error_stream_("[waitingThreadFunction_] callback is null"); - } - } - //END of sduname - - // HARDWARE - // if (hardware_ != "") - // { - // hardware = hardware_; - // class_cb_->hardwareHandle(hardware); - // } - - if (hardware_mutex_.try_lock()) - { - is_waiting_hardware = is_waiting_hardware_; - hardware_received = hardware_received_; - hardware = hardware_; - hardware_mutex_.unlock(); - } - else - { - log_warn_stream_("[waitingThreadFunction_] hardware lock not acquired"); - } - - if (is_waiting_hardware && hardware_received) - { - if (class_cb_ != nullptr) - { - if (language_ == "python") - { - class PyThreadStateLock PyThreadLock; // fix segmentation fault - class_cb_->hardwareHandle(hardware); - } - else - { - class_cb_->hardwareHandle(hardware); - } - if (hardware_mutex_.try_lock()) - { - hardware_received_ = false; - is_waiting_hardware_ = false; - hardware_mutex_.unlock(); - } - } - else - { - log_error_stream_("[waitingThreadFunction_] callback is null"); - } - } - - // END OF HARDWARE - - // TIC - // if (tic_ != "") - // { - // tic = tic_; - // class_cb_->ticHandle(tic); - // } - if (tic_mutex_.try_lock()) - { - is_waiting_tic = is_waiting_tic_; - tic_received = tic_received_; - tic = tic_; - tic_mutex_.unlock(); - } - else - { - log_warn_stream_("[waitingThreadFunction_] tic lock not acquired"); - } - - if (is_waiting_tic && tic_received) - { - if (class_cb_ != nullptr) - { - if (language_ == "python") - { - class PyThreadStateLock PyThreadLock; // fix segmentation fault - class_cb_->ticHandle(tic); - } - else - { - class_cb_->ticHandle(tic); - } - if (tic_mutex_.try_lock()) - { - tic_received_ = false; - is_waiting_tic_ = false; - tic_mutex_.unlock(); - } - } - else - { - log_error_stream_("[waitingThreadFunction_] callback is null"); - } - } - // END OF TIC - - // BATTERY - if (battery_mutex_.try_lock()) - { - is_waiting_battery = is_waiting_battery_; - battery_received = battery_received_; - battery = battery_; - battery_mutex_.unlock(); - } - else - { - log_warn_stream_("[waitingThreadFunction_] battery lock not acquired"); - } - - if (is_waiting_battery && battery_received) - { - if (class_cb_ != nullptr) - { - if (language_ == "python") - { - class PyThreadStateLock PyThreadLock; // fix segmentation fault - class_cb_->batteryHandle(battery); - } - else - { - class_cb_->batteryHandle(battery); - } - if (battery_mutex_.try_lock()) - { - battery_received_ = false; - is_waiting_battery_ = false; - battery_mutex_.unlock(); - } - } - else - { - log_error_stream_("[waitingThreadFunction_] callback is null"); - } - } - // END OF BATTERY - - std::this_thread::sleep_for(std::chrono::milliseconds(500)); // 0.5 secs - - if (waiting_mutex_.try_lock()) - { - waiting = waiting_; - waiting_mutex_.unlock(); - } - else - { - log_warn_stream_("[waitingThreadFunction_] waiting lock not acquired"); - } - } while (waiting); -} - -void ClassCore::lockErrorThreadFunction_() -{ - error_waiting_ = true; - - bool error_waiting = true; - - log_stream_("[lockErrorThreadFunction_] Thread for taking into account lock errors started"); - - do - { - int lock_error_number = 0; - - if (lock_error_mutex_.try_lock()) - { - lock_error_number = lock_error_number_; - lock_error_mutex_.unlock(); - } - else - { - log_warn_stream_("[lockErrorThreadFunction_] error lock not acquired"); - } - - if (lock_error_number >= lock_error_number_max_) - { - log_error_stream_("[lockErrorThreadFunction_] Number of errors when getting lock has overcome the limit. Check processes in your computer."); - } - - if (lock_error_mutex_.try_lock()) - { - lock_error_number_ = 0; - lock_error_mutex_.unlock(); - } - else - { - log_warn_stream_("[lockErrorThreadFunction_] error lock not acquired"); - } - - std::this_thread::sleep_for(std::chrono::milliseconds(1000)); // 1secs - - if (lock_error_mutex_.try_lock()) - { - error_waiting = error_waiting_; - lock_error_mutex_.unlock(); - } - else - { - log_warn_stream_("[lockErrorThreadFunction_] error lock not acquired"); - } - } while (error_waiting); -} - -ClassError::Error ClassCore::setCallback(ClassCallback *callback, std::string language) -{ - if (class_cb_ != nullptr) - { - delete class_cb_; - class_cb_ = nullptr; - } - - if (callback) - { - class_cb_ = callback; - } - else - { - return ClassError::ERROR_CB_NULL; - } - - language_ = language; - - return ClassError::CLASS_NO_ERROR; -} - -std::pair<double, bool> ClassCore::trunc_n(double value, std::size_t digits_after_decimal = 0) -{ - static constexpr std::intmax_t maxv = std::numeric_limits<std::intmax_t>::max(); - static constexpr std::intmax_t minv = std::numeric_limits<std::intmax_t>::min(); - - unsigned long long multiplier = 1; - for (std::size_t i = 0; i < digits_after_decimal; ++i) - multiplier *= 10; - - const auto scaled_value = value * multiplier; - - const bool did_trunc = scaled_value != scaled_value + 0.5 && scaled_value != scaled_value - 0.5; - - if (scaled_value >= minv && scaled_value <= maxv) - return {double(std::intmax_t(scaled_value)) / multiplier, did_trunc}; - else - return {std::trunc(scaled_value) / multiplier, did_trunc}; -} - -void ClassCore::increaseLockError() -{ - lock_error_mutex_.lock(); - lock_error_number_ += 1; - lock_error_mutex_.unlock(); -} -ClassError::Error ClassCore::sendCustomCmd(const std::string &cmd) -{ - return sendMsg(cmd); -} - -/*LOGGING functions*/ - -void ClassCore::log_(const std::string &text) -{ - LOG_INFO << "[ClassCore]: " << text; -} - -void ClassCore::log_(std::ostream &text) -{ - LOG_INFO << "[ClassCore]: " << text.rdbuf(); -} - -void ClassCore::log_(const std::stringstream &text) -{ - LOG_INFO << "[ClassCore]: " << text.str(); -} - -// see http://www.cplusplus.com/forum/unices/36461/ -// see https://docs.microsoft.com/en-us/windows/console/setconsoletextattribute - -#ifdef __unix__ -const std::string bold_red("\033[1;31m"); -const std::string bold_yellow("\033[1;33m"); -const std::string reset("\033[0m"); -#endif - -void ClassCore::log_err_(const std::string &text) -{ -#ifdef __unix__ - LOG_ERROR << bold_red << "[ClassCore]: " << text << reset; -#elif defined(_WIN32) || defined(WIN32) - HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); - SetConsoleTextAttribute(hConsole, 12); - LOG_ERROR << "[ClassCore]: " << text; - SetConsoleTextAttribute(hConsole, 7); -#endif -} - -void ClassCore::log_err_(std::ostream &text) -{ -#ifdef __unix__ - LOG_ERROR << bold_red << "[ClassCore]: " << text.rdbuf() << reset; -#elif defined(_WIN32) || defined(WIN32) - HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); - SetConsoleTextAttribute(hConsole, 12); - LOG_ERROR << "[ClassCore]: " << text.rdbuf(); - SetConsoleTextAttribute(hConsole, 7); -#endif -} - -void ClassCore::log_warn_(const std::string &text) -{ -#ifdef __unix__ - LOG_WARNING << bold_yellow << "[ClassCore]: " << text << reset; -#elif defined(_WIN32) || defined(WIN32) - HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); - SetConsoleTextAttribute(hConsole, 14); - LOG_WARNING << "[ClassCore]: " << text; - SetConsoleTextAttribute(hConsole, 7); -#endif -} - -void ClassCore::log_warn_(std::ostream &text) -{ -#ifdef __unix__ - LOG_WARNING << bold_yellow << "[ClassCore]: " << text.rdbuf() << reset; -#elif defined(_WIN32) || defined(WIN32) - HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); - SetConsoleTextAttribute(hConsole, 14); - LOG_WARNING << "[ClassCore]: " << text.rdbuf(); - SetConsoleTextAttribute(hConsole, 7); -#endif -} diff --git a/src/class_server/.gitkeep b/src/class_server/.gitkeep deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/src/class_server/CMakeLists.txt b/src/class_server/CMakeLists.txt deleted file mode 100644 index 554f34905a0e6c3a109f9797e4c4aaf7ec0be284..0000000000000000000000000000000000000000 --- a/src/class_server/CMakeLists.txt +++ /dev/null @@ -1,15 +0,0 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 3.14) -project (class_server) - -include_directories(include ${Boost_INCLUDE_DIRS} ${YAML_INCLUDE_DIR}) - -add_executable(${PROJECT_NAME} src/class_server_main.cpp src/class_server.cpp) -target_link_libraries(${PROJECT_NAME} logger communication yaml_tools yaml-cpp ${Boost_LIBRARIES}) - -add_executable(class_client src/class_client_example.cpp) -target_link_libraries(class_client logger communication yaml_tools yaml-cpp ${Boost_LIBRARIES}) - - -# 'make install' to the correct location -install(TARGETS ${PROJECT_NAME} - RUNTIME DESTINATION class_server) diff --git a/src/class_server/include/.gitkeep b/src/class_server/include/.gitkeep deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/src/class_server/include/class_server/.gitkeep b/src/class_server/include/class_server/.gitkeep deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/src/class_server/include/class_server/class_server.hpp b/src/class_server/include/class_server/class_server.hpp deleted file mode 100644 index dc45e07629132ba18005928fca9bf824bd9ff91b..0000000000000000000000000000000000000000 --- a/src/class_server/include/class_server/class_server.hpp +++ /dev/null @@ -1,178 +0,0 @@ -/** - * @file class_server.hpp - * @author Alfonso Dominguez <alfonso.dominguez@tecnalia.com> - * @date 2020 - * - * Copyright 2020 Tecnalia Research & Innovation. - * Distributed under the GNU GPL v3. - * For full terms see https://www.gnu.org/licenses/gpl.txt - * - * @brief Class for server which connects to CLASS device and waits for client connections - */ - -#ifndef CLASSSERVER_HPP -#define CLASSSERVER_HPP - -#include <string> -#include <sstream> -#include <thread> -#include <memory> -#include <mutex> -#include <fstream> - -#include <logger/logger.hpp> -//#include <communication/serial.hpp> -#include <communication/async_serial.hpp> -#include <communication/udp_server.hpp> -#include <communication/udp_client.hpp> - - -#if defined(_WIN32) || defined(WIN32) - #include <windows.h> -#endif - -class ClassServer: public UdpServerListener, public SerialListener -{ -public: - //! Basic constructor - ClassServer(); - //! Basic destructor - ~ClassServer(); - - /*! - \brief Connects to the CLASS and starts the server - \param port CLASS COM port to connect with. - \param listening_port Port in which server listens for connections. - \return Integer indicating the success of the connection (0-success, <0 error) - */ - int start(const std::string & port, const int & listening_port, boost::asio::io_service *io_service); - - /*! - \brief Disconnects from the CLASS and stops the server - \return Integer indicating the success of the connection (0-success, <0 error) - */ - int stop(); - - /*! - \brief Handles the reception of an UDP msg from a client - \param msg Msg - \param ip IP the message comes from - */ - void udpMsgReceived(std::string msg, std::string client_ip); - - /*! - \brief Handles the reception of a msg comming from serial - \param msg Msg - */ - void serialMsgReceived(std::string msg); - -private: - - //! thread for looking after variables - std::thread *wait_thread_; - //! function called by thread - void waitThreadFunction(); - - //! serial port for communication with CLASS - //Serial serial_; - AsyncSerial *serial_; - //! thread for sending msgs to CLASS - std::thread *serial_send_thread_; - //! function called by thread - void serialSendThreadFunction(); - //! list of msgs to be send to CLASS - std::vector<std::string> msgs_to_class_; - //! mutex for accessing msg list - std::mutex msgs_to_class_mutex_; - //! list of msgs received from CLASS - std::vector<std::string> msgs_from_class_; - //! mutex for accessing msg list - std::mutex msgs_from_class_mutex_; - - //! UDP server - UDPServer *udp_server_; - //! List of the ips connected to the server - std::vector<std::string> udp_client_ips_; - //! List of the ips connected to the server - std::vector<UDPClient*> udp_clients_; - //! thread for sending msgs to client - std::thread *udp_send_thread_; - //! function called by thread - void udpSendThreadFunction(); - //! mutex for upd_clients access - std::mutex udp_mutex_; - - //! indicates whether turn of has been received - bool turn_off_; - //! mutex for upd_clients access - std::mutex turn_off_mutex_; - //! indicates whether udp thread is running - bool continue_udp_; - //! indicates whether serial thread is running - bool continue_serial_; - - - // !external io_service - boost::asio::io_service *io_service_; - - // ! file where msgs are stored - //std::ofstream myfile_; - - - /*! - \brief Connects to the CLASS - \param port CLASS COM port to connect with. - \return Integer indicating the success of the connection (0-success, <0 error) - */ - int connectToSerial(const std::string & port); - - /*! - \brief Disconnects from the CLASS - \return Integer indicating the success of the connection (0-success, <0 error) - */ - int disconnectFromSerial(); - - /*! - \brief Starts listening fro UDP connections - \param port Port in which the server is listening. - \return Integer indicating the success of the connection (0-success, <0 error) - */ - int startUDPServer(const int & listening_port); - - /*! - \brief Stops listening - \param port Port in which the server is listening. - \return Integer indicating the success of the connection (0-success, <0 error) - */ - int stopUDPServer(); - - /*! - \brief Replaces substr in a string by another - \param str Original stringl - \param from substr to be replaced - \param to substr to replace - \return True if found and done - */ - bool replace(std::string& str, const std::string& from, const std::string& to); - - /*! - \brief Trims a string - \param str Original stringl - \return The trimmed string - */ - std::string trim(std::string str); - - //! log function - #define log_stream_(x) log_(std::stringstream() << x); - #define log_warn_stream_(x) log_warn_(std::stringstream() << x); - #define log_error_stream_(x) log_err_(std::stringstream() << x); - void log_(const std::string &text); - void log_(const std::stringstream &text); - void log_(std::ostream & text); - void log_err_(const std::string &text); - void log_err_(std::ostream & text); - void log_warn_(const std::string &text); - void log_warn_(std::ostream & text); -}; - -#endif // CLASSSERVER_HPP \ No newline at end of file diff --git a/src/class_server/src/.gitkeep b/src/class_server/src/.gitkeep deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/src/class_server/src/class_client_example.cpp b/src/class_server/src/class_client_example.cpp deleted file mode 100644 index 7e93b2c598a282dcd21c52cf36e2c9b7def99853..0000000000000000000000000000000000000000 --- a/src/class_server/src/class_client_example.cpp +++ /dev/null @@ -1,70 +0,0 @@ -/** - * @file class_client_example.cpp - * @author Alfonso Dominguez <alfonso.dominguez@tecnalia.com> - * @date 2020 - * - * Copyright 2020 Tecnalia Research & Innovation. - * Distributed under the GNU GPL v3. - * For full terms see https://www.gnu.org/licenses/gpl.txt - * - * @brief CLASS client for testing purposes - */ - -#include <string> -#include <communication/udp_client.hpp> -#include <iostream> -#include <boost/chrono.hpp> -#include <boost/thread/thread.hpp> - -int main(int argc, char* argv[]) -{ - if (argc != 4) - { - std::cerr << "ERROR: Executable expects 3 arguments (IP and port where the server is listening) and port where the client will wait for server msgs"<< std::endl; - std::cerr << "Usage: ./class_client <server_host> <server_port> <local_port>" << std::endl; - return 1; - } - - UDPClient client(argv[1], argv[2], -1); - - std::string local_port = argv[3]; - - std::stringstream ss; - ss << "connect " << local_port; - std::string msg = ss.str(); - - client.send(msg); - - int numberLoopMax = 10; - int numberLoop = 0; - - std::cout << "Wait for 10 secs and then disconnect" << std::endl; - - client.send("iam DESKTOP\r\n"); - - client.send("firmware ?\r\n"); - - //client.send("device ?\r\n"); - - client.send("acq config *freq 250.0 *channels 2 *type monopolar\r\n"); - - client.send("acq stream on\r\n"); - - client.send("acq on\r\n"); - - while (numberLoop < numberLoopMax) - { - boost::this_thread::sleep_for(boost::chrono::milliseconds(1000)); - numberLoop += 1; - std::cout << numberLoop << " sec(s)" << std::endl; - } - - client.send("acq off\r\n"); - - ss.str(std::string()); - ss << "disconnect " << local_port; - msg = ss.str(); - client.send(msg); - - return 0; -} diff --git a/src/class_server/src/class_server.cpp b/src/class_server/src/class_server.cpp deleted file mode 100644 index 85011a9556c19245271eff310274863af9b95b9c..0000000000000000000000000000000000000000 --- a/src/class_server/src/class_server.cpp +++ /dev/null @@ -1,540 +0,0 @@ -/** - * @file class_server.cpp - * @author Alfonso Dominguez <alfonso.dominguez@tecnalia.com> - * @date 2020 - * - * Copyright 2020 Tecnalia Research & Innovation. - * Distributed under the GNU GPL v3. - * For full terms see https://www.gnu.org/licenses/gpl.txt - * - * @brief Class for server which connects to CLASS device and waits for client connections - */ - -#include <class_server/class_server.hpp> -#include <iostream> -#include <regex> -#include <typeinfo> -#include <stdio.h> -#include <string> -#include "../../commands.h" - -using namespace std; - -ClassServer::ClassServer() -{ - log_("Constructor"); - turn_off_ = false; - continue_serial_ = true; - continue_udp_ = true; -} - -ClassServer::~ClassServer() -{ - log_("Destructor"); - if (udp_server_ != nullptr) - { - delete udp_server_; - } - - if (udp_send_thread_ != nullptr) - { - delete udp_send_thread_; - } - - if (serial_ != nullptr) - { - delete serial_; - } - - if (serial_send_thread_ != nullptr) - { - delete serial_send_thread_; - } - - if (wait_thread_ != nullptr) - { - delete wait_thread_; - } - - for (unsigned int i = 0; i < udp_clients_.size(); i++) - { - if (udp_clients_[i] != nullptr) - { - delete udp_clients_[i]; - } - } - - // myfile_.close(); -} - -int ClassServer::start(const std::string &port, const int &listening_port, boost::asio::io_service *io_service) -{ - io_service_ = io_service; - if (connectToSerial(port) != 0) - { - log_error_stream_("[start] Error connecting to CLASS"); - return -1; - } - else - { - log_stream_("[start] Connected to CLASS"); - } - - if (startUDPServer(listening_port) != 0) - { - log_error_stream_("[start] Error starting UDP server"); - return -1; - } - else - { - log_stream_("[start] UDP server is listening"); - } - - wait_thread_ = new std::thread(&ClassServer::waitThreadFunction, this); - wait_thread_->detach(); - - // myfile_.open ("msgs.txt"); - - return 0; -} - -int ClassServer::stop() -{ - disconnectFromSerial(); - stopUDPServer(); - io_service_->stop(); - return 0; -} - -int ClassServer::connectToSerial(const std::string &port) -{ - serial_ = new AsyncSerial(port, 115200); - // starts a thread for sending msgs to CLASS each 100ms - serial_->addListener((SerialListener *)this); - - serial_send_thread_ = new std::thread(&ClassServer::serialSendThreadFunction, this); - serial_send_thread_->detach(); - - return 0; -} - -int ClassServer::disconnectFromSerial() -{ - if (serial_ != nullptr) - { - log_("[disconnectFromSerial] close serial"); - serial_->close(); - delete serial_; - serial_ = nullptr; - log_("[disconnectFromSerial] serial closed"); - } - - if (serial_send_thread_ != nullptr) - { - delete serial_send_thread_; - serial_send_thread_ = nullptr; - } - - turn_off_mutex_.lock(); - continue_serial_ = false; - turn_off_mutex_.unlock(); - - return 0; -} - -void ClassServer::serialMsgReceived(std::string msg) -{ - //log_stream_("[serialMsgReceived] Msg received from CLASS: " << msg) - // myfile_ << msg; - - if (msg.find("turnning off") != std::string::npos) - { - log_("[serialMsgReceived] Device turned OFF"); - turn_off_mutex_.lock(); - turn_off_ = true; - turn_off_mutex_.unlock(); - } - msgs_from_class_mutex_.lock(); - msgs_from_class_.push_back(msg); - msgs_from_class_mutex_.unlock(); - - if(msg.find("tic") != string::npos) - { - log_stream_("[serialMsgReceived] Msg received from CLASS: " << msg) - } -} - -void ClassServer::waitThreadFunction() -{ - bool continueLoop = true; - while (continueLoop) - { - turn_off_mutex_.lock(); - continueLoop = continue_udp_ || continue_serial_; - turn_off_mutex_.unlock(); - - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - } - - log_("[waitThreadFunction] Thread stopped. Stop external service"); - io_service_->stop(); -} - -void ClassServer::serialSendThreadFunction() -{ - bool continueLoop = true; - while (continueLoop) - { - turn_off_mutex_.lock(); - continueLoop = !turn_off_; - turn_off_mutex_.unlock(); - - bool is_empty; - msgs_to_class_mutex_.lock(); - is_empty = msgs_to_class_.empty(); - msgs_to_class_mutex_.unlock(); - - if (!is_empty) - { - // send the first msg in queue - std::string msg; - msgs_to_class_mutex_.lock(); - msg = msgs_to_class_[0]; - commands::ClassCommands d; - log_stream_("[serialSendThreadFunction] Msg sent to CLASS device : " << d.Log(msg)); - msgs_to_class_.erase(msgs_to_class_.begin()); - msgs_to_class_mutex_.unlock(); - serial_->writeString(msg); - std::string msg_without_ending = msg; - replace(msg_without_ending, "\r\n", "\\r\\n"); - std::this_thread::sleep_for(std::chrono::milliseconds(50)); - } - else - { - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - } - } - - log_("[serialSendThreadFunction] Thread stopped. Disconnect from serial"); - disconnectFromSerial(); -} - -int ClassServer::startUDPServer(const int &listening_port) -{ - if (udp_server_ != nullptr) - { - log_("[startUDPServer] There is already a UDP server listening"); - } - - log_stream_("[startUDPServer] Starting UDP server on port " << listening_port); - udp_server_ = new UDPServer(listening_port); - udp_server_->startListening(); - udp_server_->addListener((UdpServerListener *)this); - - // starts a thread for sending msgs to clients - udp_send_thread_ = new std::thread(&ClassServer::udpSendThreadFunction, this); - udp_send_thread_->detach(); - - return 0; -} - -int ClassServer::stopUDPServer() -{ - if (udp_server_ != nullptr) - { - log_("[stopUDPServer] Stopping UDP server"); - udp_server_->removeListener((UdpServerListener *)this); - udp_server_->stopListening(); - delete udp_server_; - udp_server_ = nullptr; - turn_off_mutex_.lock(); - continue_udp_ = false; - turn_off_mutex_.unlock(); - log_("[stopUDPServer] UDP server stopped"); - } - - return 0; -} - -void ClassServer::udpMsgReceived(std::string msg, std::string ip) -{ - // parse message from client - if (msg.find("flush") != std::string::npos) - { - log_stream_("[udpMsgReceived] Message received from client (IP: " << ip << "): Flush"); - // flush async_serial buffer - if (serial_ != nullptr) - { - serial_->flush(); - } - // flush internal buffer - msgs_from_class_mutex_.lock(); - msgs_from_class_.clear(); - msgs_from_class_mutex_.unlock(); - } - else if (msg.find("disconnect") != std::string::npos) - { - // extract port where the client was listenening - std::regex regex("\\ "); - std::vector<std::string> out( - std::sregex_token_iterator(msg.begin(), msg.end(), regex, -1), - std::sregex_token_iterator()); - if (out.size() != 2) - { - return; - } - int client_port = 0; - try - { - client_port = std::stoi(out[1]); - } - catch (const std::exception &e) - { - log_error_stream_("[udpMsgReceived] disconnect command must be followed by an integer (port in which the client listens) but (" << out[1] << ") has been provided. Exc:" << e.what()); - return; - } - - if (udp_mutex_.try_lock()) - { - for (unsigned int i = 0; i < udp_clients_.size(); i++) - { - if (udp_clients_[i]->getIP() == ip && udp_clients_[i]->getPort() == client_port) - { - log_stream_("[udpMsgReceived] Client (IP: " << ip << ", port: " << client_port << ") is not listening anymore"); - delete udp_clients_[i]; - udp_clients_.erase(udp_clients_.begin() + i); - break; - } - } - udp_mutex_.unlock(); - } - } - else if (msg.find("connect") != std::string::npos) - { - // extract port where the client will listen - // extract port - std::regex regex("\\ "); - std::vector<std::string> out( - std::sregex_token_iterator(msg.begin(), msg.end(), regex, -1), - std::sregex_token_iterator()); - if (out.size() != 2) - { - return; - } - int client_port = 0; - try - { - client_port = std::stoi(out[1]); - } - catch (const std::exception &e) - { - log_error_stream_("[udpMsgReceived] connect command must be followed by an iteger (port in which the client listens) but (" << out[1] << ") has been provided. Exc:" << e.what()); - return; - } - - if (udp_mutex_.try_lock()) - { - bool found = false; - for (unsigned int i = 0; i < udp_clients_.size(); i++) - { - if (udp_clients_[i]->getIP() == ip && udp_clients_[i]->getPort() == client_port) - { - log_stream_("[udpMsgReceived] There is a client already listening (IP: " << ip << ", port: " << client_port << ")"); - found = true; - break; - } - } - - if (!found) - { - log_stream_("[udpMsgReceived] New client is listening (IP: " << ip << ", port: " << client_port << ")"); - udp_client_ips_.push_back(ip); - udp_clients_.push_back(new UDPClient(ip, out[1], -1)); - } - udp_mutex_.unlock(); - } - } - else - { - // send msg to CLASS_DEVICE - std::vector<string>::iterator it = std::find(udp_client_ips_.begin(), udp_client_ips_.end(), ip); - if (it == udp_client_ips_.end()) - { - log_warn_stream_("[udpMsgReceived] Client (IP: " << ip << ") is not connected"); - } - else - { - // std::string msg_without_ending = msg; - // replace(msg_without_ending, "\r\n", "\\r\\n"); - // log_stream_("[udpMsgReceived] Message received from client (IP: " << ip << "): " << msg_without_ending); - msgs_to_class_mutex_.lock(); - msgs_to_class_.push_back(msg); - msgs_to_class_mutex_.unlock(); - } - } -} - -bool ClassServer::replace(std::string &str, const std::string &from, const std::string &to) -{ - size_t start_pos = str.find(from); - while (start_pos != std::string::npos) - { - str.replace(start_pos, from.length(), to); - start_pos = str.find(from); - } - return true; -} - -std::string ClassServer::trim(string str) -{ - size_t first = str.find_first_not_of(' '); - if (string::npos == first) - { - return ""; - } - size_t last = str.find_last_not_of(' '); - return str.substr(first, (last - first + 1)); -} - -void ClassServer::udpSendThreadFunction() -{ - bool continueLoop = true; - while (continueLoop) - { - turn_off_mutex_.lock(); - continueLoop = !turn_off_; - turn_off_mutex_.unlock(); - - bool is_empty; - msgs_from_class_mutex_.lock(); - is_empty = msgs_from_class_.empty(); - msgs_from_class_mutex_.unlock(); - - if (!is_empty) - { - if (!udp_clients_.empty()) - // send the first msg in queue - { - std::vector<std::string> msgs; - msgs_from_class_mutex_.lock(); - msgs = msgs_from_class_; - msgs_from_class_.clear(); - msgs_from_class_mutex_.unlock(); - - if (!msgs.empty()) - { - if (udp_mutex_.try_lock()) - { - for (unsigned int i = 0; i < msgs.size(); i++) - { - for (unsigned int j = 0; j < udp_clients_.size(); j++) - { - msgs[i].erase(std::remove(msgs[i].begin(), msgs[i].end(), '\n'), msgs[i].end()); - - msgs[i].erase(std::remove(msgs[i].begin(), msgs[i].end(), '\r'), msgs[i].end()); - trim(msgs[i]); - - if (msgs[i].find("mac ") != std::string::npos){ - //log_stream_("mac text found"); - continue; - } - - if (!msgs[i].empty()) - { - //log_stream_("[SENDING ---->>>>] " << msgs[i]); - udp_clients_[j]->send(msgs[i]); - } - - // if (!msgs[i].empty()) - // { - // udp_clients_[j]->send(msgs[i]); - // } - } - } - udp_mutex_.unlock(); - } - // else - // { - // log_warn_stream_("[udpSendThreadFunction] udp_mutex_ not get amd msgs pending: " << msgs[0]); - // } - } - } - } - - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - } - log_("[udpSendThreadFunction] Thread stopped. UDP server stopped"); - stopUDPServer(); -} - -/*logging*/ - -void ClassServer::log_(const std::string &text) -{ - LOG_INFO << "[ClassServer]: " << text; -} - -void ClassServer::log_(std::ostream &text) -{ - LOG_INFO << "[ClassServer]: " << text.rdbuf(); -} -void ClassServer::log_(const std::stringstream &text) -{ - LOG_INFO << "[ClassServer]: " << text.str(); -} -// see http://www.cplusplus.com/forum/unices/36461/ -// see https://docs.microsoft.com/en-us/windows/console/setconsoletextattribute - -#ifdef __unix__ -const std::string bold_red("\033[1;31m"); -const std::string bold_yellow("\033[1;33m"); -const std::string reset("\033[0m"); -#endif - -void ClassServer::log_err_(const std::string &text) -{ -#ifdef __unix__ - LOG_ERROR << bold_red << "[ClassServer]: " << text << reset; -#elif defined(_WIN32) || defined(WIN32) - HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); - SetConsoleTextAttribute(hConsole, 12); - LOG_ERROR << "[ClassServer]: " << text; - SetConsoleTextAttribute(hConsole, 7); -#endif -} - -void ClassServer::log_err_(std::ostream &text) -{ -#ifdef __unix__ - LOG_ERROR << bold_red << "[ClassServer]: " << text.rdbuf() << reset; -#elif defined(_WIN32) || defined(WIN32) - HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); - SetConsoleTextAttribute(hConsole, 12); - LOG_ERROR << "[ClassServer]: " << text.rdbuf(); - SetConsoleTextAttribute(hConsole, 7); -#endif -} - -void ClassServer::log_warn_(const std::string &text) -{ -#ifdef __unix__ - LOG_WARNING << bold_yellow << "[ClassServer]: " << text << reset; -#elif defined(_WIN32) || defined(WIN32) - HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); - SetConsoleTextAttribute(hConsole, 14); - LOG_WARNING << "[ClassServer]: " << text; - SetConsoleTextAttribute(hConsole, 7); -#endif -} - -void ClassServer::log_warn_(std::ostream &text) -{ -#ifdef __unix__ - LOG_WARNING << bold_yellow << "[ClassServer]: " << text.rdbuf() << reset; -#elif defined(_WIN32) || defined(WIN32) - HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); - SetConsoleTextAttribute(hConsole, 14); - LOG_WARNING << "[ClassServer]: " << text.rdbuf(); - SetConsoleTextAttribute(hConsole, 7); -#endif -} \ No newline at end of file diff --git a/src/class_server/src/class_server_main.cpp b/src/class_server/src/class_server_main.cpp deleted file mode 100644 index 40d05f58547367abe33d7732f5444ca716b99bb7..0000000000000000000000000000000000000000 --- a/src/class_server/src/class_server_main.cpp +++ /dev/null @@ -1,71 +0,0 @@ -/** - * @file class_server_main.cpp - * @author Alfonso Dominguez <alfonso.dominguez@tecnalia.com> - * @date 2020 - * - * Copyright 2020 Tecnalia Research & Innovation. - * Distributed under the GNU GPL v3. - * For full terms see https://www.gnu.org/licenses/gpl.txt - * - * @brief CLASS server main program - */ - -#include <class_server/class_server.hpp> -#include <thread> -#include <memory> - -ClassServer server; - -void handler( const boost::system::error_code& error , int signal_number ) -{ - std::cout << "[CLASS server] Handling signal " << signal_number << std::endl; - server.stop(); - - exit(1); -} - -int main (int argc, char *argv[]) -{ - if (argc != 3) - { - std::cerr << "[CLASS server] ERROR: Executable expects 2 arguments (BT port to connect to CLASS device and UDP port where this server will listen for client msgs)"<< std::endl; - std::cerr << "[CLASS server] Usage example:"<< std::endl; - #ifdef _WINDOWS - std::cerr << "[CLASS server] class_server.exe COM14 50000" << std::endl; - #else - std::cerr << "[CLASS server] ./class_server COM14 50000" << std::endl; - #endif - - return 1; - } - - std::string bt_port = argv[1]; - std::cout << "[CLASS server] Connect to BT port: " << bt_port << std::endl; - std::string udp_port_str = argv[2]; - int udp_port = 0; - try - { - udp_port = std::stoi(udp_port_str); - } - catch(const std::exception& e) - { - std::cerr << "2nd parameter is not an integer (" << udp_port_str << "). Exc:" << e.what() << std::endl; - return 1; - } - std::cout << "[CLASS server] Listen in UDP port: " << udp_port << std::endl; - - - boost::asio::io_service *io_service = new boost::asio::io_service(); - boost::asio::signal_set signals(*io_service, SIGINT ); - - // Start an asynchronous wait for one of the signals to occur. - signals.async_wait( handler ); - - if(server.start(bt_port, udp_port, io_service) == 0) - { - std::cout << "[CLASS server] Waiting for connections. Ctrl+C for stop" << std::endl; - io_service->run(); - } - - std::cout << "[CLASS server] Bye" << std::endl; -} \ No newline at end of file diff --git a/src/cmspandoc.cmake b/src/cmspandoc.cmake deleted file mode 100644 index 1fcdf8b8651a2b1d6a6dcc9bf6272062693f059f..0000000000000000000000000000000000000000 --- a/src/cmspandoc.cmake +++ /dev/null @@ -1,105 +0,0 @@ -################################################################################ -## Configure Pandoc to use -## Usage: -## 1º Include Module: -## LIST(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/Modules/cmake-pandocology") -## INCLUDE(pandocology) -## INCLUDE(cmspandoc) -## 2º Call macro CONFIGUREPANDOCOLOGY() to configure -################################################################################ - -MACRO(CONFIGUREPANDOCOLOGY) - MESSAGE(STATUS "Configuring pandoc variables...") - - # Set predefined options - SET(PANDOC_OUTPUT_FORMAT pdf CACHE STRING "Choose final document") - SET(PANDOC_STANDALONE YES CACHE BOOL "Produce output with an appropriate header and footer (e.g. a standalone HTML, LaTeX, TEI, - or RTF file, not a fragment). This option is set automatically for pdf, epub, epub3, fb2, docx, and odt output.") - SET(PANDOC_DOCUMENTCLASS "report" CACHE STRING "Document class with Latex") - SET(PANDOC_LANGUAGE en CACHE STRING "Language with BCP 47 identifier") - SET(PANDOC_LATEX_ENGINE xelatex CACHE STRING "Latex engine") - SET(PANDOC_FONT_SIZE 12pt CACHE STRING "Font size") - SET(PANDOC_PAPER_SIZE a4 CACHE STRING "Paper size") - SET(PANDOC_MARGIN_LEFT 3cm CACHE STRING "Margin left") - SET(PANDOC_MARGIN_RIGHT 3cm CACHE STRING "Margin right") - SET(PANDOC_MARGIN_TOP 3cm CACHE STRING "Margin top") - SET(PANDOC_MARGIN_BOTTOM 3cm CACHE STRING "Margin bottom") - SET(PANDOC_FONT_MAIN "Liberation Sans" CACHE STRING "Font") - SET(PANDOC_FONT_MONO "Liberation Sans" CACHE STRING "Font") - SET(PANDOC_INCLUDE_CONTENT TRUE CACHE BOOL "Choose if you want include Tables of content (toc)") - SET(PANDOC_INCLUDE_FIGURE FALSE CACHE BOOL "Choose if you want include Tables of content (lof)") - SET(PANDOC_INCLUDE_TABLE FALSE CACHE BOOL "Choose if you want include Tables of content (lot)") - #SET(PANDOC_SECTION_NUMBERS en CACHE STRING "Add section numbers") - - # Set multiple options in cache variables - SET_PROPERTY(CACHE PANDOC_DOCUMENTCLASS PROPERTY STRINGS article report book letter slides) - SET_PROPERTY(CACHE PANDOC_OUTPUT_FORMAT PROPERTY STRINGS pdf doc odt html) - SET_PROPERTY(CACHE PANDOC_LANGUAGE PROPERTY STRINGS en es) - SET_PROPERTY(CACHE PANDOC_LATEX_ENGINE PROPERTY STRINGS pdflatex xelatex lualatex) - SET_PROPERTY(CACHE PANDOC_FONT_SIZE PROPERTY STRINGS 10pt 12pt 14pt 16pt 18pt 20pt 30pt 35pt 40pt) - SET_PROPERTY(CACHE PANDOC_PAPER_SIZE PROPERTY STRINGS a4 a3) - LIST(APPEND PANDOC_FONTS "Liberation Sans" "Inconsolata" "FreeMono" "Palatino") - SET_PROPERTY(CACHE PANDOC_FONT_MAIN PROPERTY STRINGS ${PANDOC_FONTS}) - SET_PROPERTY(CACHE PANDOC_FONT_MONO PROPERTY STRINGS ${PANDOC_FONTS}) - #SET_PROPERTY(CACHE PANDOC_SECTION_NUMBERS PROPERTY STRINGS yes no) - - # CMake Options - SET(CMAKE_BUILD_TYPE - Release - CACHE STRING "Release" FORCE) - SET(CMAKE_INSTALL_PREFIX - ${PROJECT_BINARY_DIR}/install - CACHE STRING "Build path" FORCE) - - # FORMAT Options - - # Pdf Options - SET(IMG_EXT_PDF pdf) - #LIST(APPEND PARAMS_PDF "-V babel-lang=$(LANG)") - - # Others - # odt TODO - # doc TODO - # html TODO - # presentation TODO - - # Condition - IF(PANDOC_STANDALONE) - SET(PANDOC_STANDALONE_VAR -s) - ELSE() - SET(PANDOC_STANDALONE_VAR ) - ENDIF() - - # Configure pandoc for all projects, you can use your own variable into different modules - SET(PANDOC_PDF_CONFIG - ${PANDOC_STANDALONE_VAR} - --variable documentclass=${PANDOC_DOCUMENTCLASS} - --latex-engine=${PANDOC_LATEX_ENGINE} - --default-image-extension=${IMG_EXT_PDF} - --variable lang=${PANDOC_LANGUAGE} - --variable fontsize=${PANDOC_FONT_SIZE} - --variable papersize=${PANDOC_PAPER_SIZE} - #--variable fontfamily=${PANDOC_FONT_FAMILY} # only pdflatex - --variable mainfont=${PANDOC_FONT_MAIN} - --variable monofont=${PANDOC_FONT_MONO} - --variable margin-left=${PANDOC_MARGIN_LEFT} - --variable margin-right=${PANDOC_MARGIN_RIGHT} - --variable margin-top=${PANDOC_MARGIN_TOP} - --variable margin-bottom=${PANDOC_MARGIN_BOTTOM} - ) - - # Add extra includes - IF(PANDOC_INCLUDE_CONTENT) - SET(PANDOC_PDF_CONFIG ${PANDOC_PDF_CONFIG} --variable toc) - ENDIF() - - IF(PANDOC_INCLUDE_FIGURE) - SET(PANDOC_PDF_CONFIG ${PANDOC_PDF_CONFIG} --variable lof) - ENDIF() - - IF(PANDOC_INCLUDE_TABLE) - SET(PANDOC_PDF_CONFIG ${PANDOC_PDF_CONFIG} --variable lot) - ENDIF() - - MESSAGE(STATUS "pandoc variables configured!") -ENDMACRO() diff --git a/src/commands.h b/src/commands.h deleted file mode 100644 index 3e1373bc34693d50a6477715e7deac7c833a537d..0000000000000000000000000000000000000000 --- a/src/commands.h +++ /dev/null @@ -1,103 +0,0 @@ -#pragma once -#include <string> - -namespace commands -{ - class ClassCommands - { - public: - - static std::string ClassCommands::CMD_ONACQ; - static std::string ClassCommands::CMD_OFFACQ; - static std::string ClassCommands::CMD_STREAMONACQ; - static std::string ClassCommands::CMD_STREAMOFFACQ; - static std::string ClassCommands::CMD_NORMALACQ; - - static std::string ClassCommands::CMD_ONIMPEDANCEACQ; - static std::string ClassCommands::CMD_OFFIMPEDANCEACQ; - - static std::string ClassCommands::CMD_TESTACQ; - static std::string ClassCommands::CMD_CONFIGACQ; - static std::string ClassCommands::CMD_CONFIGACQ_PARAM1; - static std::string ClassCommands::CMD_CONFIGACQ_PARAM2; - static std::string ClassCommands::CMD_CONFIGACQ_PARAM3; - static std::string ClassCommands::CMD_CONFIGVELEC_PARAM4; - - static std::string ClassCommands::CMD_VELEC_SELECTED; - static std::string ClassCommands::CMD_VELEC_NOTSELECTED; - - - static std::string ClassCommands::CMD_ONSTIM; - static std::string ClassCommands::CMD_OFFSTIM; - static std::string ClassCommands::CMD_VELECSTIM; - - - static std::string ClassCommands::CMD_CONFIGELEC; - static std::string ClassCommands::CMD_CONFIGELEC_PARAM1; - - static std::string ClassCommands::CMD_CONFIGPATTERN; - static std::string ClassCommands::CMD_CONFIGPATTERN_PARAM1; - static std::string ClassCommands::CMD_CONFIGPATTERN_PARAM2; - static std::string ClassCommands::CMD_CONFIGPATTERN_PARAM3; - - static std::string ClassCommands::CMD_CONFIGVELEC; - static std::string ClassCommands::CMD_CONFIGVELEC_PARAM1; - static std::string ClassCommands::CMD_CONFIGVELEC_PARAM2; - static std::string ClassCommands::CMD_CONFIGVELEC_PARAM3; - - static std::string ClassCommands::CMD_SETFREQ; - - static std::string ClassCommands::CMD_SETDEVICENAME; - static std::string ClassCommands::CMD_SETHV; - static std::string ClassCommands::CMD_ONHV; - static std::string ClassCommands::CMD_OFFHV; - static std::string ClassCommands::CMD_ONLOGEVENTS; - - static std::string ClassCommands::CMD_OFFLOGEVENTS; - static std::string ClassCommands::CMD_SETINTERVAL; - static std::string ClassCommands::CMD_SETBUZZER; - static std::string ClassCommands::CMD_PLAYBUZZER; - static std::string ClassCommands::CMD_SETRTCDATE; - - static std::string ClassCommands::CMD_SETRTCTIME; - static std::string ClassCommands::CMD_SWITCHOFF; - static std::string ClassCommands::CMD_SETSDFUNCTION; - static std::string ClassCommands::CMD_SETSDNAME; - //PATTERN - - //paTTERN CLEAR PONER IGUAL DELETE - //VELEC - //VELEC SELECTED - //sTIM VELEC - //ACQIMPEDANCECONFIG - //ACQIMPEDANCEPOLARITY - - static std::string ClassCommands::CMD_INIT; - - static std::string ClassCommands::CMD_GETBATTERY; - static std::string ClassCommands::CMD_GETFW; - static std::string ClassCommands::CMD_GETDEVICENAME; - static std::string ClassCommands::CMD_GETLOGEVENTS; - //velec - static std::string ClassCommands::CMD_GETPATTERN; - static std::string ClassCommands::CMD_GETHV; - static std::string ClassCommands::CMD_GETINTERVAL; - static std::string ClassCommands::CMD_GETRTC; - static std::string ClassCommands::CMD_GETBUZZER; - static std::string ClassCommands::CMD_GETFRQUENCY; - static std::string ClassCommands::CMD_GETSDFUNCTION; - static std::string ClassCommands::CMD_GETSDNAME; - static std::string ClassCommands::CMD_GETHW; - static std::string ClassCommands::CMD_GETTIC; - - static std::string ClassCommands::CMD_BUFFERFLUSH; - - static std::string ClassCommands::CMD_AUX; - static std::string ClassCommands::CMD_AUX2; - - - - std::string ClassCommands::Log(std::string val); - - }; -} \ No newline at end of file diff --git a/src/commands.lib b/src/commands.lib deleted file mode 100644 index 2c6c5c1789c267362d537d5567966680fba04819..0000000000000000000000000000000000000000 Binary files a/src/commands.lib and /dev/null differ diff --git a/src/communication/.gitkeep b/src/communication/.gitkeep deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/src/communication/CMakeLists.txt b/src/communication/CMakeLists.txt deleted file mode 100644 index 288f5b5443c266229393d191ded3b8b43cc45562..0000000000000000000000000000000000000000 --- a/src/communication/CMakeLists.txt +++ /dev/null @@ -1,43 +0,0 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 2.6) -project(communication) -message("cmake ${PROJECT_NAME}") -if (DEBUG_CMAKE) - set(CMAKE_VERBOSE_MAKEFILE yes) -endif (DEBUG_CMAKE) - -include_directories(include ${Boost_INCLUDE_DIR}) - -set(communication_files_local - ${CMAKE_CURRENT_SOURCE_DIR}/src/udp_client.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/include/communication/udp_client.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/src/udp_server.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/include/communication/udp_server.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/src/async_serial.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/include/communication/async_serial.hpp) - -set(communication_files - ${communication_files_local} - PARENT_SCOPE) - -add_library(communication - ${communication_files_local}) - -target_link_libraries(communication logger ) -set_target_properties(communication PROPERTIES FOLDER communication) - -target_link_libraries(communication ${CMAKE_CURRENT_SOURCE_DIR}/../commands.lib) - -# Define headers for this library. PUBLIC headers are used for -# compiling the library, and will be added to consumers' build -# paths. -target_include_directories(communication PUBLIC - $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> - $<INSTALL_INTERFACE:include> - PRIVATE src) - -# This makes the project importable from the build directory -export(TARGETS communication - logger - yaml_tools - yaml-cpp - FILE communication_Config.cmake) \ No newline at end of file diff --git a/src/communication/include/.gitkeep b/src/communication/include/.gitkeep deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/src/communication/include/communication/.gitkeep b/src/communication/include/communication/.gitkeep deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/src/communication/include/communication/async_serial.hpp b/src/communication/include/communication/async_serial.hpp deleted file mode 100644 index 53d0d073ffd22af0dfcd4eeb36a1ed810e3d781d..0000000000000000000000000000000000000000 --- a/src/communication/include/communication/async_serial.hpp +++ /dev/null @@ -1,267 +0,0 @@ -/** -* @file async_serial.hpp -* @author Alfonso Dominguez <alfonso.dominguez@tecnalia.com> -* @date 2020 -* -* Copyright 2020 Tecnalia Research & Innovation. -* Distributed under the GNU GPL v3. For full terms see https://www.gnu.org/licenses/gpl.txt -* -* @brief Asynchronous serial port. -*/ - -#ifndef ASYNCSERIAL_H -#define ASYNCSERIAL_H - -#include <vector> -#include <thread> -#include <mutex> -#include <boost/asio.hpp> -#include <boost/bind.hpp> -#include <boost/utility.hpp> -#include <boost/function.hpp> -#include <boost/shared_array.hpp> - - -#include <communication/serial_listener.hpp> - -/** - * Used internally (pimpl) - */ -class AsyncSerialImpl; - -/** - * Asyncronous serial class. - * Intended to be a base class. - */ -class AsyncSerial: private boost::noncopyable -{ -public: - AsyncSerial(); - - /** - * Constructor. Creates and opens a serial device. - * \param devname serial device name, example "/dev/ttyS0" or "COM1" - * \param baud_rate serial baud rate - * \param opt_parity serial parity, default none - * \param opt_csize serial character size, default 8bit - * \param opt_flow serial flow control, default none - * \param opt_stop serial stop bits, default 1 - * \throws boost::system::system_error if cannot open the - * serial device - */ - AsyncSerial(const std::string& devname, unsigned int baud_rate, - boost::asio::serial_port_base::parity opt_parity= - boost::asio::serial_port_base::parity( - boost::asio::serial_port_base::parity::none), - boost::asio::serial_port_base::character_size opt_csize= - boost::asio::serial_port_base::character_size(8), - boost::asio::serial_port_base::flow_control opt_flow= - boost::asio::serial_port_base::flow_control( - boost::asio::serial_port_base::flow_control::none), - boost::asio::serial_port_base::stop_bits opt_stop= - boost::asio::serial_port_base::stop_bits( - boost::asio::serial_port_base::stop_bits::one)); - - /** - * Opens a serial device. - * \param devname serial device name, example "/dev/ttyS0" or "COM1" - * \param baud_rate serial baud rate - * \param opt_parity serial parity, default none - * \param opt_csize serial character size, default 8bit - * \param opt_flow serial flow control, default none - * \param opt_stop serial stop bits, default 1 - * \throws boost::system::system_error if cannot open the - * serial device - */ - void open(const std::string& devname, unsigned int baud_rate, - boost::asio::serial_port_base::parity opt_parity= - boost::asio::serial_port_base::parity( - boost::asio::serial_port_base::parity::none), - boost::asio::serial_port_base::character_size opt_csize= - boost::asio::serial_port_base::character_size(8), - boost::asio::serial_port_base::flow_control opt_flow= - boost::asio::serial_port_base::flow_control( - boost::asio::serial_port_base::flow_control::none), - boost::asio::serial_port_base::stop_bits opt_stop= - boost::asio::serial_port_base::stop_bits( - boost::asio::serial_port_base::stop_bits::one)); - - /** - * \return true if serial device is open - */ - bool isOpen() const; - - /** - * \return true if error were found - */ - bool errorStatus() const; - - /** - * Close the serial device - * \throws boost::system::system_error if any error - */ - void close(); - - /** - * Write data asynchronously. Returns immediately. - * \param data array of char to be sent through the serial device - * \param size array size - */ - void write(const char *data, size_t size); - - /** - * Write data asynchronously. Returns immediately. - * \param data to be sent through the serial device - */ - void write(const std::vector<char>& data); - - /** - * Write a string asynchronously. Returns immediately. - * Can be used to send ASCII data to the serial device. - * To send binary data, use write() - * \param s string to send - */ - void writeString(const std::string& s); - - ~AsyncSerial(); - - /** - * @brief Adds a listener to the msgs comming from serial - * @param listener Listener - */ - void addListener(SerialListener *listener); - - /** - * @brief Removes a listener to the msgs comming from serial - * @param listener Listener - */ - void removeListener(SerialListener *listener); - - /** - * Read buffer maximum size - */ - static const int readBufferSize=512; - - /** - * Flushes the read buffer - */ - void flush(); -private: - - /** - * Callback called to start an asynchronous read operation. - * This callback is called by the io_service in the spawned thread. - */ - void doRead(); - - /** - * Callback called at the end of the asynchronous operation. - * This callback is called by the io_service in the spawned thread. - */ - void readEnd(const boost::system::error_code& error, - size_t bytes_transferred); - - /** - * Callback called to start an asynchronous write operation. - * If it is already in progress, does nothing. - * This callback is called by the io_service in the spawned thread. - */ - void doWrite(); - - /** - * Callback called at the end of an asynchronuous write operation, - * if there is more data to write, restarts a new write operation. - * This callback is called by the io_service in the spawned thread. - */ - void writeEnd(const boost::system::error_code& error); - - /** - * Callback to close serial port - */ - void doClose(); - - boost::shared_ptr<AsyncSerialImpl> pimpl; - - //! indicates whether the buffer is being read in order to flush it - bool flushing_; - -protected: - - /** - * To allow derived classes to report errors - * \param e error status - */ - void setErrorStatus(bool e); - - /** - * To allow derived classes to set a read callback - */ - void setReadCallback(const - boost::function<void (const char*, size_t)>& callback); - - /** - * To unregister the read callback in the derived class destructor so it - * does not get called after the derived class destructor but before the - * base class destructor - */ - void clearReadCallback(); - -private: - //! listeners - std::vector<SerialListener*> listeners_; - -}; - -/** - * Asynchronous serial class with read callback. User code can write data - * from one thread, and read data will be reported through a callback called - * from a separate thred. - */ -class CallbackAsyncSerial: public AsyncSerial -{ -public: - CallbackAsyncSerial(); - - /** - * Opens a serial device. - * \param devname serial device name, example "/dev/ttyS0" or "COM1" - * \param baud_rate serial baud rate - * \param opt_parity serial parity, default none - * \param opt_csize serial character size, default 8bit - * \param opt_flow serial flow control, default none - * \param opt_stop serial stop bits, default 1 - * \throws boost::system::system_error if cannot open the - * serial device - */ - CallbackAsyncSerial(const std::string& devname, unsigned int baud_rate, - boost::asio::serial_port_base::parity opt_parity= - boost::asio::serial_port_base::parity( - boost::asio::serial_port_base::parity::none), - boost::asio::serial_port_base::character_size opt_csize= - boost::asio::serial_port_base::character_size(8), - boost::asio::serial_port_base::flow_control opt_flow= - boost::asio::serial_port_base::flow_control( - boost::asio::serial_port_base::flow_control::none), - boost::asio::serial_port_base::stop_bits opt_stop= - boost::asio::serial_port_base::stop_bits( - boost::asio::serial_port_base::stop_bits::one)); - - /** - * Set the read callback, the callback will be called from a thread - * owned by the CallbackAsyncSerial class when data arrives from the - * serial port. - * \param callback the receive callback - */ - void setCallback(const - boost::function<void (const char*, size_t)>& callback); - - /** - * Removes the callback. Any data received after this function call will - * be lost. - */ - void clearCallback(); - - virtual ~CallbackAsyncSerial(); -}; - -#endif //ASYNCSERIAL_H \ No newline at end of file diff --git a/src/communication/include/communication/serial_listener.hpp b/src/communication/include/communication/serial_listener.hpp deleted file mode 100644 index 7bff29f8235368f511c7fa2ed22e842356ea2a12..0000000000000000000000000000000000000000 --- a/src/communication/include/communication/serial_listener.hpp +++ /dev/null @@ -1,5 +0,0 @@ -class SerialListener -{ -public: - virtual void serialMsgReceived(std::string msg){} -}; \ No newline at end of file diff --git a/src/communication/include/communication/udp_client.hpp b/src/communication/include/communication/udp_client.hpp deleted file mode 100644 index 6a94d007e0a263669d09475923cc26b0eee4cc84..0000000000000000000000000000000000000000 --- a/src/communication/include/communication/udp_client.hpp +++ /dev/null @@ -1,121 +0,0 @@ -/** -* @file udp_client.hpp -* @author Alfonso Dominguez <alfonso.dominguez@tecnalia.com> -* @date 2017 -* -* Copyright 2017 Tecnalia Research & Innovation. -* Distributed under the GNU GPL v3. For full terms see https://www.gnu.org/licenses/gpl.txt -* -* @brief Asynchronous udp client -*/ -#ifndef UDP_CLIENT_HPP -#define UDP_CLIENT_HPP - -#include <boost/asio.hpp> -#include <boost/bind.hpp> -#include <boost/thread.hpp> -#include <boost/asio/deadline_timer.hpp> -#include <iostream> -#include <mutex> - -using boost::asio::ip::udp; -using boost::asio::deadline_timer; - -class UDPClient -{ -public: - UDPClient(const std::string& host, const std::string& port, int timeout); - ~UDPClient(); - - /** - * @brief send message to endpoint - * @param msg - */ - void send(const std::string& msg); - - /** - * @brief start the client's loop - */ - void start(); - - /** - * @brief closes service and socket - */ - void close(); - - /** - * @brief get the latest received data - * @return data - */ - std::string getData(); - - /** - * @brief indicates if server is available - * @return server availability - */ - bool isServerAvailable(); - - /** - * @brief set timeout - * @return timeout - */ - void setTimeout(int timeout); - - /** - * @brief gets the IP of the endpoint - * @return IP of the endpoint - */ - std::string getIP(); - - /** - * @brief gets the port of the endpoint - * @return Port of the endpoint - */ - int getPort(); - -private: - boost::asio::io_service io_service_; - udp::socket socket_; - udp::endpoint endpoint_; - deadline_timer deadline_; - //! runner thread - boost::thread t; - //! buffer where received data is going to be stored - //boost::asio::mutable_buffer buffer_; - //! Variable in which the serial data that is read is stored - unsigned char *bytes_read_; - //! number of bytes to be read each time - std::size_t number_bytes_to_be_read_; - //! shared data - std::string data_; - //! mutex for accesing buffer - std::mutex mtx_; - //! error number - int error_number_; - //! max error number - int error_max_; - //! is server available? - bool server_available_; - //! timeout millis (if negative it is set to infinite) - int timeout_; - - /** - * @brief Check whether the deadline has passed - * @param error - */ - void check_deadline(const boost::system::error_code& error); - - /** - * @brief receive messahge - */ - void receive_(); - - /** - * @brief handles a connection from a client sending the current data - * @param error - * @param bytes_transferred - */ - void handleReceive_(const boost::system::error_code& e, std::size_t size); -}; - -#endif // UDP_CLIENT_HPP \ No newline at end of file diff --git a/src/communication/include/communication/udp_server.hpp b/src/communication/include/communication/udp_server.hpp deleted file mode 100644 index 34c3dd211951cc69e2262a46fb8447d37d97597b..0000000000000000000000000000000000000000 --- a/src/communication/include/communication/udp_server.hpp +++ /dev/null @@ -1,100 +0,0 @@ -/** -* @file udp_server.hpp -* @author Alfonso Dominguez <alfonso.dominguez@tecnalia.com> -* @date 2017 -* -* Copyright 2017 Tecnalia Research & Innovation. -* Distributed under the GNU GPL v3. For full terms see https://www.gnu.org/licenses/gpl.txt -* -* @brief Asynchronous udp server -*/ -#ifndef UDP_SERVER_HPP -#define UDP_SERVER_HPP - -#include <boost/asio.hpp> -#include <boost/bind.hpp> -#include <boost/thread.hpp> -#include <boost/array.hpp> -#include <boost/asio/deadline_timer.hpp> -#include <iostream> -#include <boost/circular_buffer.hpp> -#include <communication/udp_server_listener.hpp> - -using boost::asio::ip::udp; -using boost::asio::deadline_timer; - -class UDPServer -{ -public: - UDPServer(int listening_port); - ~UDPServer(); - - /** - * @brief start the listening process - */ - void startListening(); - - /** - * @brief stop the listening process - */ - void stopListening(); - - /** - * @brief get the first data in the buffer - * @param data_str the data - * @param messages_in_queue number of messages in the queue - * @return the first data in the queue. False if there is not data in the queue - */ - bool getFirstDataInQueue(std::string &data_str, int &messages_in_queue); - - /** - * @brief Adds a listener to the msgs the server receives - * @param listener Listener - */ - void addListener(UdpServerListener *listener); - - /** - * @brief Removes a listener to the msgs the server receives - * @param listener Listener - */ - void removeListener(UdpServerListener *listener); - -private: - //! listening socket - udp::socket* socket_; - //! server thread - boost::thread* server_thread_; - //! io service - boost::asio::io_service io_service_; - //! client end points - udp::endpoint temp_remote_endpoint_; - //!temporal buffer - boost::array<char, 255> temp_recv_buffer_; - //circular buffer for string received data - boost::circular_buffer<std::string> received_data_buffer_; - //mutex for buffer - boost::mutex buffer_mtx_; - //!thread; - boost::shared_ptr<boost::thread> thread_; - //! listeners - std::vector<UdpServerListener*> listeners_; - - /** - * @brief handles a connection from a client sending the current data - * @param error - * @param bytes_transferred - */ - void handleReceive(const boost::system::error_code& error, std::size_t bytes_transferred); - - /** - * @brief continue with the listening process - */ - void continueListening(); - - /** - * @brief run the service - */ - void serviceRun(); -}; - -#endif // UDP_SERVER_HPP diff --git a/src/communication/include/communication/udp_server_listener.hpp b/src/communication/include/communication/udp_server_listener.hpp deleted file mode 100644 index 72a446b26941dfd66dbdb0fdb6fb48103c2784a5..0000000000000000000000000000000000000000 --- a/src/communication/include/communication/udp_server_listener.hpp +++ /dev/null @@ -1,5 +0,0 @@ -class UdpServerListener -{ -public: - virtual void udpMsgReceived(std::string msg, std::string ip){} -}; \ No newline at end of file diff --git a/src/communication/src/.gitkeep b/src/communication/src/.gitkeep deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/src/communication/src/async_serial.cpp b/src/communication/src/async_serial.cpp deleted file mode 100644 index 58a291c5c4541b34a93f61ca6c13fe4c7b32a9d9..0000000000000000000000000000000000000000 --- a/src/communication/src/async_serial.cpp +++ /dev/null @@ -1,395 +0,0 @@ -/** -* @file async_serial.cpp -* @author Alfonso Dominguez <alfonso.dominguez@tecnalia.com> -* @date 2017 -* -* Copyright 2017 Tecnalia Research & Innovation. -* Distributed under the GNU GPL v3. For full terms see https://www.gnu.org/licenses/gpl.txt -* -* @brief Asynchronous serial port. -*/ - - -#include <communication/async_serial.hpp> - -#include <string> -#include <algorithm> -#include <iostream> -#include <boost/bind.hpp> - -//using namespace std; -using namespace boost; - -// -//Class AsyncSerial -// - - -class AsyncSerialImpl: private boost::noncopyable -{ -public: - AsyncSerialImpl(): io(), port(io), backgroundThread(), open(false), - error(false) {} - - boost::asio::io_service io; ///< Io service object - boost::asio::serial_port port; ///< Serial port object - std::thread backgroundThread; ///< Thread that runs read/write operations - bool open; ///< True if port open - bool error; ///< Error flag - mutable std::mutex errorMutex; ///< Mutex for access to error - - /// Data are queued here before they go in writeBuffer - std::vector<char> writeQueue; - boost::shared_array<char> writeBuffer; ///< Data being written - size_t writeBufferSize; ///< Size of writeBuffer - std::mutex writeQueueMutex; ///< Mutex for access to writeQueue - //char readBuffer[AsyncSerial::readBufferSize]; ///< data being read - boost::asio::streambuf readBuffer_; - - /// Read complete callback - boost::function<void (const char*, size_t)> callback; -}; - -AsyncSerial::AsyncSerial(): pimpl(new AsyncSerialImpl) -{ - flushing_ = false; -} - -AsyncSerial::AsyncSerial(const std::string& devname, unsigned int baud_rate, - asio::serial_port_base::parity opt_parity, - asio::serial_port_base::character_size opt_csize, - asio::serial_port_base::flow_control opt_flow, - asio::serial_port_base::stop_bits opt_stop) - : pimpl(new AsyncSerialImpl) -{ - flushing_ = false; - open(devname,baud_rate,opt_parity,opt_csize,opt_flow,opt_stop); -} - -void AsyncSerial::open(const std::string& devname, unsigned int baud_rate, - asio::serial_port_base::parity opt_parity, - asio::serial_port_base::character_size opt_csize, - asio::serial_port_base::flow_control opt_flow, - asio::serial_port_base::stop_bits opt_stop) -{ - if(isOpen()) close(); - - setErrorStatus(true);//If an exception is thrown, error_ remains true - pimpl->port.open(devname); - pimpl->port.set_option(asio::serial_port_base::baud_rate(baud_rate)); - pimpl->port.set_option(opt_parity); - pimpl->port.set_option(opt_csize); - pimpl->port.set_option(opt_flow); - pimpl->port.set_option(opt_stop); - - //This gives some work to the io_service before it is started - pimpl->io.post(boost::bind(&AsyncSerial::doRead, this)); - - std::thread t(boost::bind(&asio::io_service::run, &pimpl->io)); - pimpl->backgroundThread.swap(t); - setErrorStatus(false);//If we get here, no error - pimpl->open=true; //Port is now open -} - -bool AsyncSerial::isOpen() const -{ - return pimpl->open; -} - -bool AsyncSerial::errorStatus() const -{ - std::lock_guard<std::mutex> l(pimpl->errorMutex); - return pimpl->error; -} - -void AsyncSerial::close() -{ - if(!isOpen()) return; - - pimpl->open=false; - pimpl->io.post(boost::bind(&AsyncSerial::doClose, this)); - pimpl->backgroundThread.join(); - pimpl->io.reset(); - if(errorStatus()) - { - throw(boost::system::system_error(boost::system::error_code(), - "Error while closing the device")); - } -} - -void AsyncSerial::write(const char *data, size_t size) -{ - { - std::lock_guard<std::mutex> l(pimpl->writeQueueMutex); - pimpl->writeQueue.insert(pimpl->writeQueue.end(),data,data+size); - } - pimpl->io.post(boost::bind(&AsyncSerial::doWrite, this)); -} - -void AsyncSerial::write(const std::vector<char>& data) -{ - { - std::lock_guard<std::mutex> l(pimpl->writeQueueMutex); - pimpl->writeQueue.insert(pimpl->writeQueue.end(),data.begin(), - data.end()); - } - pimpl->io.post(boost::bind(&AsyncSerial::doWrite, this)); -} - -void AsyncSerial::writeString(const std::string& s) -{ - { - std::lock_guard<std::mutex> l(pimpl->writeQueueMutex); - pimpl->writeQueue.insert(pimpl->writeQueue.end(),s.begin(),s.end()); - } - pimpl->io.post(boost::bind(&AsyncSerial::doWrite, this)); -} - -AsyncSerial::~AsyncSerial() -{ - if(isOpen()) - { - try { - close(); - } catch(...) - { - //Don't throw from a destructor - } - } -} - -void AsyncSerial::doRead() -{ - /*pimpl->port.async_read_some(asio::buffer(pimpl->readBuffer,readBufferSize), - boost::bind(&AsyncSerial::readEnd, - this, - asio::placeholders::error, - asio::placeholders::bytes_transferred));*/ - boost::asio::async_read_until(pimpl->port, pimpl->readBuffer_, "\r", boost::bind(&AsyncSerial::readEnd, this, _1, _2)); -} - -void AsyncSerial::readEnd(const boost::system::error_code& error, - size_t bytes_transferred) -{ - if(error) - { - #ifdef __APPLE__ - if(error.value()==45) - { - //Bug on OS X, it might be necessary to repeat the setup - //http://osdir.com/ml/lib.boost.asio.user/2008-08/msg00004.html - doRead(); - return; - } - #endif //__APPLE__ - //error can be true even because the serial port was closed. - //In this case it is not a real error, so ignore - if(isOpen()) - { - doClose(); - setErrorStatus(true); - } - } - else - { - if(!flushing_) - { - flushing_ = false; - /*if(pimpl->callback) pimpl->callback(pimpl->readBuffer, - bytes_transferred);*/ - /*std::istream response_stream(&pimpl->readBuffer_); - std::string data_str; - std::getline(response_stream, data_str);*/ - std::string delimiter = "\r"; - std::string data_str{ - boost::asio::buffers_begin(pimpl->readBuffer_.data()), - boost::asio::buffers_begin(pimpl->readBuffer_.data()) + bytes_transferred - delimiter.size()}; - // Consume through the first delimiter. - pimpl->readBuffer_.consume(bytes_transferred); - - //std::cout << "[Serial::readEnd]Data str: " << data_str << ". Data length: " << data_str.length() << std::endl; - - for(int i = 0; i < listeners_.size(); i++) - { - listeners_[i]->serialMsgReceived(data_str); - } - } - doRead(); - } -} - -void AsyncSerial::doWrite() -{ - //If a write operation is already in progress, do nothing - if(pimpl->writeBuffer==0) - { - std::lock_guard<std::mutex> l(pimpl->writeQueueMutex); - pimpl->writeBufferSize=pimpl->writeQueue.size(); - pimpl->writeBuffer.reset(new char[pimpl->writeQueue.size()]); - copy(pimpl->writeQueue.begin(),pimpl->writeQueue.end(), - pimpl->writeBuffer.get()); - pimpl->writeQueue.clear(); - async_write(pimpl->port,asio::buffer(pimpl->writeBuffer.get(), - pimpl->writeBufferSize), - boost::bind(&AsyncSerial::writeEnd, this, asio::placeholders::error)); - } -} - -void AsyncSerial::writeEnd(const boost::system::error_code& error) -{ - if(!error) - { - std::lock_guard<std::mutex> l(pimpl->writeQueueMutex); - if(pimpl->writeQueue.empty()) - { - pimpl->writeBuffer.reset(); - pimpl->writeBufferSize=0; - - return; - } - pimpl->writeBufferSize=pimpl->writeQueue.size(); - pimpl->writeBuffer.reset(new char[pimpl->writeQueue.size()]); - copy(pimpl->writeQueue.begin(),pimpl->writeQueue.end(), - pimpl->writeBuffer.get()); - pimpl->writeQueue.clear(); - async_write(pimpl->port,asio::buffer(pimpl->writeBuffer.get(), - pimpl->writeBufferSize), - boost::bind(&AsyncSerial::writeEnd, this, asio::placeholders::error)); - } else { - setErrorStatus(true); - doClose(); - } -} - -void AsyncSerial::doClose() -{ - boost::system::error_code ec; - pimpl->port.cancel(ec); - if(ec) setErrorStatus(true); - pimpl->port.close(ec); - if(ec) setErrorStatus(true); -} - -void AsyncSerial::setErrorStatus(bool e) -{ - std::lock_guard<std::mutex> l(pimpl->errorMutex); - pimpl->error=e; -} - -void AsyncSerial::setReadCallback(const boost::function<void (const char*, size_t)>& callback) -{ - pimpl->callback=callback; -} - -void AsyncSerial::clearReadCallback() -{ - pimpl->callback.clear(); -} - -void AsyncSerial::addListener(SerialListener *listener) -{ - std::vector<SerialListener*>::iterator it = std::find(listeners_.begin(), listeners_.end(), listener); - if(it == listeners_.end()) - { - //std::cout << "[Serial::addListener]Add new listener" << std::endl; - listeners_.push_back(listener); - } -} - -void AsyncSerial::removeListener(SerialListener *listener) -{ - std::vector<SerialListener*>::iterator it = std::find(listeners_.begin(), listeners_.end(), listener); - if(it != listeners_.end()) - { - //std::cout << "[Serial::removeListener]Remove listener" << std::endl; - listeners_.erase(it); - } -} - -void AsyncSerial::flush() -{ - //std::cout << "[Serial::flush] Flush" << std::endl; - int value = 0; - bool error_in_method = false; - - #ifdef __unix__ - ::tcflush(pimpl->port.native_handle(), TCIOFLUSH); - #elif defined(_WIN32) || defined(WIN32) - if (PurgeComm(pimpl->port.native_handle(), PURGE_RXCLEAR | PURGE_TXCLEAR)) - { - //std::cout << "[Serial::flush] Flush done" << std::endl; - } - else - { - std::cout << "[Serial::flush] Error" << std::endl; - } - #endif - - // #ifdef __unix__ - // if (0 == ::ioctl(pimpl->port.lowest_layer().native_handle(), - // FIONREAD, &value)) - // { - // std::cout << "[Serial::flush] ioctl error " << std::endl; - // error_in_method = true; - // } - // #elif defined(_WIN32) || defined(WIN32) - // COMSTAT status; - // if (0 != ::ClearCommError(pimpl->port.lowest_layer().native_handle(), - // NULL, &status)) - // { - // value = status.cbInQue; - // } - // else - // { - // std::cout << "[Serial::flush] ClearCommError error" << std::endl; - // error_in_method = true; - // } - // #endif - - // if(!error_in_method) - // { - // std::size_t remaining_bytes = static_cast<size_t>(value); - // std::cout << "[Serial::flush] remaining_bytes:" << remaining_bytes << std::endl; - // if(remaining_bytes > 0) - // { - // flushing_ = true; - // boost::asio::async_read(pimpl->port, pimpl->readBuffer_, boost::bind(&AsyncSerial::readEnd, this, _1, _2)); - // } - // } -} - -// -//Class CallbackAsyncSerial -// - -CallbackAsyncSerial::CallbackAsyncSerial(): AsyncSerial() -{ - -} - -CallbackAsyncSerial::CallbackAsyncSerial(const std::string& devname, - unsigned int baud_rate, - asio::serial_port_base::parity opt_parity, - asio::serial_port_base::character_size opt_csize, - asio::serial_port_base::flow_control opt_flow, - asio::serial_port_base::stop_bits opt_stop) - :AsyncSerial(devname,baud_rate,opt_parity,opt_csize,opt_flow,opt_stop) -{ - -} - -void CallbackAsyncSerial::setCallback(const - boost::function<void (const char*, size_t)>& callback) -{ - setReadCallback(callback); -} - -void CallbackAsyncSerial::clearCallback() -{ - clearReadCallback(); -} - -CallbackAsyncSerial::~CallbackAsyncSerial() -{ - clearReadCallback(); -} \ No newline at end of file diff --git a/src/communication/src/udp_client.cpp b/src/communication/src/udp_client.cpp deleted file mode 100644 index 79c43046b5c3c40f4a5b141812d5d19a4d6fb423..0000000000000000000000000000000000000000 --- a/src/communication/src/udp_client.cpp +++ /dev/null @@ -1,163 +0,0 @@ -/** -* @file udp_client.cpp -* @author Alfonso Dominguez <alfonso.dominguez@tecnalia.com> -* @date 2017 -* -* Copyright 2017 Tecnalia Research & Innovation. -* Distributed under the GNU GPL v3. For full terms see https://www.gnu.org/licenses/gpl.txt -* -* @brief Asynchronous udp client -*/ - -#include <communication/udp_client.hpp> - -UDPClient::UDPClient(const std::string& host,const std::string& port, int timeout) - : socket_(io_service_, udp::endpoint(udp::v4(), 0)), - deadline_(io_service_) -{ - //std::cout << "UDPClient constructor start" << std::endl; - udp::resolver resolver(io_service_); - udp::resolver::query query(udp::v4(), host, port); - udp::resolver::iterator iter = resolver.resolve(query); - endpoint_ = *iter; - number_bytes_to_be_read_ = 32; - bytes_read_ = new unsigned char[number_bytes_to_be_read_]; - error_number_ = 0; - error_max_ = 10; - server_available_ = true; - timeout_ = timeout; -} - -UDPClient::~UDPClient() -{ - close(); - std::cout << "Wait thread to stop" << std::endl; - t.join(); - std::cout << "Thread stopped" << std::endl; - delete [] bytes_read_; -} - -void UDPClient::close() -{ - std::cout << "Close socket" << std::endl; - socket_.close(); - std::cout << "Close service" << std::endl; - io_service_.stop(); - std::cout << "Service closed" << std::endl; -} - -void UDPClient::start() -{ - //std::cout << "UDPClient start" << std::endl; - receive_(); - t = boost::thread(boost::bind(&boost::asio::io_service::run, &io_service_)); - t.detach(); -} - -void UDPClient::send(const std::string& msg) { - //std::cout << "UDPClient send" << msg << std::endl; - socket_.send_to(boost::asio::buffer(msg, msg.size()), endpoint_); -} - -void UDPClient::receive_() -{ - //std::cout << "UDPClient receive_" << std::endl; - int timeout; - mtx_.lock(); - timeout = timeout_; - mtx_.unlock(); - - if(timeout_ < 0) - { - deadline_.expires_at(boost::posix_time::pos_infin); - } - else - { - deadline_.expires_from_now(boost::posix_time::milliseconds(timeout)); - } - deadline_.async_wait(boost::bind(&UDPClient::check_deadline, this, boost::asio::placeholders::error)); - socket_.async_receive(boost::asio::buffer(&bytes_read_[0], number_bytes_to_be_read_), boost::bind(&UDPClient::handleReceive_, this, _1, _2)); -} - -void UDPClient::check_deadline(const boost::system::error_code& error) -{ - //std::cout << "check_deadline" << std::endl; - // Was the timeout cancelled? - if (error) - { - // yes - return; - } - //std::cout << "Deadline passed!!. Cancel socket async calls" << std::endl; - socket_.cancel(); -} - -void UDPClient::handleReceive_(const boost::system::error_code& e, std::size_t size) -{ - if (!e) - { - //std::cout << "UDPClient handleReceive_. size: " << size << std::endl; - // Read has finished, so cancel the timer. - deadline_.cancel(); - - mtx_.lock(); - if(bytes_read_ != NULL) - data_ = std::string (reinterpret_cast<char const*>(bytes_read_), size); - mtx_.unlock(); - } - else - { - //std::cout << "Read cancelled"<< std::endl; - error_number_ += 1; - if(error_number_ >= error_max_) - { - std::cout << "Server seems not to be available"<< std::endl; - mtx_.lock(); - server_available_ = false; - mtx_.unlock(); - return; - } - else - { - //std::cout << "Rearm reading"<< std::endl; - } - } - receive_(); -} - -std::string UDPClient::getData() -{ - std::string data; - mtx_.lock(); - data = data_; - data_ = ""; - mtx_.unlock(); - return data; -} - -std::string UDPClient::getIP() -{ - return endpoint_.address().to_string(); -} - -int UDPClient::getPort() -{ - return endpoint_.port(); -} - -bool UDPClient::isServerAvailable() -{ - bool server_available; - mtx_.lock(); - server_available = server_available_; - mtx_.unlock(); - return server_available; -} - - -void UDPClient::setTimeout(int timeout) -{ - mtx_.lock(); - timeout_ = timeout; - mtx_.unlock(); -} \ No newline at end of file diff --git a/src/communication/src/udp_server.cpp b/src/communication/src/udp_server.cpp deleted file mode 100644 index 845779c36f7006111af3d46eac0880f9ed08bd70..0000000000000000000000000000000000000000 --- a/src/communication/src/udp_server.cpp +++ /dev/null @@ -1,111 +0,0 @@ -/** -* @file udp_server.cpp -* @author Alfonso Dominguez <alfonso.dominguez@tecnalia.com> -* @date 2017 -* -* Copyright 2017 Tecnalia Research & Innovation. -* Distributed under the GNU GPL v3. For full terms see https://www.gnu.org/licenses/gpl.txt -* -* @brief Asynchronous udp server -*/ -#include <communication/udp_server.hpp> -#include "../../commands.h" -UDPServer::UDPServer(int listening_port) -{ - socket_ = new udp::socket(io_service_, udp::endpoint(udp::v4(), listening_port)); - received_data_buffer_.set_capacity(1000); -} - -UDPServer::~UDPServer() -{ - if(socket_ != nullptr) - { - delete socket_; - } -} - -void UDPServer::startListening() -{ - std::cout << "[UDPServer::startListening] " << std::endl; - continueListening(); - thread_ = boost::shared_ptr< boost::thread >(new boost::thread(boost::bind(&UDPServer::serviceRun, this))); - thread_->detach(); -} - -void UDPServer::serviceRun() -{ - //std::cout << "[UDPServer::serviceRun] " << std::endl; - io_service_.run(); -} - -void UDPServer::continueListening() -{ - socket_->async_receive_from(boost::asio::buffer(temp_recv_buffer_), temp_remote_endpoint_, boost::bind(&UDPServer::handleReceive, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); -} - -void UDPServer::stopListening() -{ - std::cout << "[UDPServer::stopListening] Stopping" << std::endl; - socket_->shutdown(boost::asio::ip::udp::socket::shutdown_both); - socket_->close(); - io_service_.stop(); - std::cout << "[UDPServer::stopListening] Stopped" << std::endl; -} - -void UDPServer::handleReceive(const boost::system::error_code& error, std::size_t bytes_transferred) -{ - //std::cout << "[UDPServer] connection received" << std::endl; - - if (!error || error == boost::asio::error::message_size) - { - std::string message; - std::copy(temp_recv_buffer_.begin(), temp_recv_buffer_.begin() + bytes_transferred, std::back_inserter(message)); - commands::ClassCommands d; - std::string msg2 = d.Log(message); - - std::cout << "[UDPServer] connection received ---->>>>" << msg2 << std::endl;//message << std::endl; - //std::cout << "[UDPServer::handleReceive] Message: " << message << ". Message length: " << message.length()<< std::endl; - for(int i = 0; i < listeners_.size(); i++) - { - listeners_[i]->udpMsgReceived(message, temp_remote_endpoint_.address().to_string()); - } - } - - continueListening(); -} - -bool UDPServer::getFirstDataInQueue(std::string &data_str, int &messages_in_queue) -{ - bool response = false; - buffer_mtx_.lock(); - messages_in_queue = received_data_buffer_.size(); - if (!received_data_buffer_.empty()) - { - data_str = received_data_buffer_[0]; - received_data_buffer_.pop_front(); - response = true; - } - buffer_mtx_.unlock(); - - return response; -} - -void UDPServer::addListener(UdpServerListener *listener) -{ - std::vector<UdpServerListener*>::iterator it = std::find(listeners_.begin(), listeners_.end(), listener); - if(it == listeners_.end()) - { - //std::cout << "[UDPServer::addListener]Add new listener" << std::endl; - listeners_.push_back(listener); - } -} - -void UDPServer::removeListener(UdpServerListener *listener) -{ - std::vector<UdpServerListener*>::iterator it = std::find(listeners_.begin(), listeners_.end(), listener); - if(it != listeners_.end()) - { - //std::cout << "[UDPServer::removeListener]Remove listener" << std::endl; - listeners_.erase(it); - } -} \ No newline at end of file diff --git a/src/docs/.gitkeep b/src/docs/.gitkeep deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/src/docs/Doxyfile.in b/src/docs/Doxyfile.in deleted file mode 100644 index a14ab9de9aeccd93dbccf2c6992f269a3fb25f5e..0000000000000000000000000000000000000000 --- a/src/docs/Doxyfile.in +++ /dev/null @@ -1,9 +0,0 @@ -OUTPUT_DIRECTORY = @CMAKE_CURRENT_BINARY_DIR@/doc_doxygen/ -INPUT = @CMAKE_CURRENT_SOURCE_DIR@/../api/class/include/class/class.hpp -INPUT += @CMAKE_CURRENT_SOURCE_DIR@/../api/class/include/class/class_structures.hpp -INPUT += @CMAKE_CURRENT_SOURCE_DIR@/../api/class/include/class/class_error.hpp -INPUT += @CMAKE_CURRENT_SOURCE_DIR@/../api/class/include/class/class_cb.hpp -INPUT += @CMAKE_CURRENT_SOURCE_DIR@/README.md -HTML_FOOTER = @CMAKE_CURRENT_SOURCE_DIR@/footer.html -USE_MDFILE_AS_MAINPAGE = README.md -PROJECT_NAME = "CLASS API" diff --git a/src/docs/README.html b/src/docs/README.html deleted file mode 100644 index 2e2390c9f38b44e11e23ebca7601f491c5f161c4..0000000000000000000000000000000000000000 --- a/src/docs/README.html +++ /dev/null @@ -1 +0,0 @@ -<meta http-equiv="REFRESH" content="0;URL=docs/index.html"> \ No newline at end of file diff --git a/src/docs/README.md b/src/docs/README.md deleted file mode 100644 index 33f894cc79a47065024aeb84ad5cd956ab42e717..0000000000000000000000000000000000000000 --- a/src/docs/README.md +++ /dev/null @@ -1,121 +0,0 @@ -The CLASS_API has been programmed in C++ (11). - -The documentation, you are just reading, has been automatically produced from comments on the source code using [Doxygen](https://www.doxygen.nl/index.html). You can dig in the different classes, methods and structures following the links in the webpage. - -Wrappers for C and C# have been generated using [SWIG](http://www.swig.org/). These wrappers allows for interacting with the CLASS_API from these programming languages. More languages will be taken into account in the future. - -The CLASS_API folder is structured as follows: - * [docs](../): the documentation of the CLASS_API is stored here. Automatically generated with [Doxygen](https://www.doxygen.nl/index.html). - * [tests](../../../tests): it contains examples on how to use the API for different programming languages. - * [c++](../../../api/class/Release): files for programming c++ client applications. - - * [C#](../../../wrappers/c_sharp/Release): wrapper to be used in C# scripts. - -# How to program your own code - -Examples on how to use the API for stimulation, acquisition and battery request can be found in [examples](../../../tests). These examples are available for C++ and C#. - -`CMakeLists.txt` files have been added where applicable to recompile the source code of the examples. - -Appropriate build tools (which depend on the OS and the language) must be installed before recompiling. Requisites for each of the languages can be found below. - -## C++ - -This point illustrates how to rebuild the c++ examples. For building your own program, take the source code and the CMakeLists.txt file in `src` folder as inspiration. - -### Pre-requisites - -- [CMake](https://cmake.org/): - - Windows: Download the [.msi file](https://cmake.org/download/) and install it. - - Linux: - - ``` - sudo snap install cmake --classic - ``` -- Compiler: - - Windows: Build tools for Visual Studio (2017): There is no official link but [this one](https://aka.ms/vs/15/release/vs_buildtools.exe) works. - - Linux: - - ``` - sudo apt-get install build-essential - ``` - -### Building with CMake - -Follow these steps in order to rebuild the examples (it is supposed `src` and `build` directories will be at same level): -- Create a `build` folder and enter the folder. -``` -mkdir build -cd build -``` -- Execute the following command to configure the platform: - - - Windows - ``` - cmake -G "Visual Studio 15 2017 Win64" CMAKE_BUILD_TYPE=Release ../src/cpp - ``` - - - Linux - ``` - cmake ../src/cpp - ``` -- Then execute the following command to build the executables: - - Windows - ``` - cmake --build . --target ALL_BUILD --config Release - ``` - - Linux - ``` - make - ``` - -> NOTE: The executables need the location of the libraries (dlls) to execute correctly. This can be done through a .bat file. - -## CSharp - -This point illustrates how to rebuild csharp examples using CMake and Microsoft Visual Studio. - -### Pre-requisites - -Two options: - - [CMake](https://cmake.org/download/) and Build tools for Visual Studio (2017): There is no official link but [this one](https://aka.ms/vs/15/release/vs_buildtools.exe) works. - - Microsoft Visual Studio - -### Building with CMake - -Follow these steps in order to rebuild the examples with CMake (it is supposed `src` and `build` directories will be at same level): -- Create a `build` folder and enter the folder. -``` -mkdir build -cd build -``` -- Execute the following command to configure the platform: -``` -cmake -G "Visual Studio 15 2017 Win64" CMAKE_BUILD_TYPE=Release ../src/csharp -``` -- Then execute the following command to build the executables: -``` -cmake --build . --target ALL_BUILD --config Release -``` -- The executables will be on `Release` folder in the created `build` directory. - -> NOTE: The executables need the location of the dlls to execute correctly. This can be done through a .bat file. There are some examples on how to do it [here](../../../tests/test_wrappers/csharp). - -### Building with Microsoft Visual Studio - -The user can use also Microsoft Visual Studio to program his/her examples in case the user is not used to [CMake](https://cmake.org/). Follow the next steps to do it: - -* Create and empty project (a Console Project, for example). -* Copy the source code in the main method of one of the [csharp examples](../../../tests/test_wrappers/csharp) to the main in your project or create new code using them as reference. -* To remove existing warnings/errors about non-existing references, click "Add existing elements" to the project and select all the `.cs` files that are located in the [csharp library folder](../../../wrappers/c_sharp/Release) or directly copy them to the source folder of the project. -* Then select between adding DLLs to the executable path or reference them in a .bat file: - * Add DLLS to executable path: - * Click "Add existing elements" to the project and select `csharpClass.dll` in the [csharp library folder](../../../wrappers/c_sharp/Release) and `class.dll` and `python37.dll` in the [csharp library folder](../../../wrappers/c_sharp/Release). - * Check the box in its properties to copy the file to the output folder when the executable is generated. - * Copy and modify one of the existing .bat files in [csharp examples folder] (../examples/src/csharp). -* Select `x64` as the platform for the solution and compile. - - -> NOTE: `csharpClass.dll` and `class.dll` should be in the same folder as the executable. If not, its location must be indicated through a `.bat` file which extends the `PATH` environment variable with the location of the `csharpClass.dll`. - -> NOTE: The csharp library has been tested with Microsoft Visual Studio 2017. \ No newline at end of file diff --git a/src/docs/footer.html b/src/docs/footer.html deleted file mode 100644 index 7cc103b9137194e8ceef3e66ae48b76859fedfd4..0000000000000000000000000000000000000000 --- a/src/docs/footer.html +++ /dev/null @@ -1,9 +0,0 @@ -<hr> -<p align="center"> - <a href="https://www.tecnalia.com"> - <img width="200" height="60" src="./images/tecnalia.jpg" alt="Tecnalia"> - </a> -</p> -<p align="center"> -©Copyright 2021 Tecnalia -</p> \ No newline at end of file diff --git a/src/docs/images/.gitkeep b/src/docs/images/.gitkeep deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/src/docs/images/sw_arch.png b/src/docs/images/sw_arch.png deleted file mode 100644 index fc71de5092b758e06e3478a2a48546a70db26ed7..0000000000000000000000000000000000000000 Binary files a/src/docs/images/sw_arch.png and /dev/null differ diff --git a/src/docs/images/tecnalia.jpg b/src/docs/images/tecnalia.jpg deleted file mode 100644 index b633abc6b439e736f79c4bc97a78186a7737ddcc..0000000000000000000000000000000000000000 Binary files a/src/docs/images/tecnalia.jpg and /dev/null differ diff --git a/src/filter/.gitkeep b/src/filter/.gitkeep deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/src/filter/CMakeLists.txt b/src/filter/CMakeLists.txt deleted file mode 100644 index 927f4133bab7cb79a920fae22956d74803241466..0000000000000000000000000000000000000000 --- a/src/filter/CMakeLists.txt +++ /dev/null @@ -1,37 +0,0 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 2.6) -project(filter) -message("cmake ${PROJECT_NAME}") -if (DEBUG_CMAKE) - set(CMAKE_VERBOSE_MAKEFILE yes) -endif (DEBUG_CMAKE) - -include_directories(include ${Boost_INCLUDE_DIR}) - -set(filter_files_local - ${CMAKE_CURRENT_SOURCE_DIR}/src/butterworth.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/include/filter/butterworth.hpp) - -set(filter_files - ${filter_files_local} - PARENT_SCOPE) - -add_library(filter - ${filter_files_local}) - -target_link_libraries(filter logger ) -set_target_properties(filter PROPERTIES FOLDER filter) - -# Define headers for this library. PUBLIC headers are used for -# compiling the library, and will be added to consumers' build -# paths. -target_include_directories(filter PUBLIC - $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> - $<INSTALL_INTERFACE:include> - PRIVATE src) - -# This makes the project importable from the build directory -export(TARGETS filter - logger - yaml_tools - yaml-cpp - FILE filter_Config.cmake) \ No newline at end of file diff --git a/src/filter/include/.gitkeep b/src/filter/include/.gitkeep deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/src/filter/include/filter/.gitkeep b/src/filter/include/filter/.gitkeep deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/src/filter/include/filter/butterworth.hpp b/src/filter/include/filter/butterworth.hpp deleted file mode 100644 index e3c66dce8d4cf0ff8e53390cb801055756633432..0000000000000000000000000000000000000000 --- a/src/filter/include/filter/butterworth.hpp +++ /dev/null @@ -1,42 +0,0 @@ -/** -* @file butterworth.hpp -* @author Alfonso Dominguez <alfonso.dominguez@tecnalia.com> -* @date 2020 -* -* Copyright 2020 Tecnalia Research & Innovation. -* Distributed under the GNU GPL v3. For full terms see https://www.gnu.org/licenses/gpl.txt -* -* @brief Implementation of a butterworth filter. -*/ -#include <boost/circular_buffer.hpp> -#include <boost/scoped_ptr.hpp> -#include <vector> - -class Butterworth -{ -public: - Butterworth(); - int configure (int filter_order, double low_cutoff, double up_cutoff); - bool update(const double & data_in, double & data_out); - -private: - double * ComputeLP(); - double * ComputeHP(); - double * TrinomialMultiply(double *b, double *c); - std::vector<double> ComputeNumCoeffs(); - std::vector<double> ComputeDenCoeffs(); - - int filter_order_; - double low_cutoff_; - double up_cutoff_; - - boost::scoped_ptr<boost::circular_buffer<double>> input_buffer_; //The input sample history. - boost::scoped_ptr<boost::circular_buffer<double>> output_buffer_; //The output sample history. - - std::vector<double> den_coeffs_; //Transfer functon coefficients (output). - std::vector<double> num_coeffs_; //Transfer functon coefficients (input). - - double temp_; //used for storage and preallocation - - bool configured_; //used for storage and preallocation -}; \ No newline at end of file diff --git a/src/filter/src/.gitkeep b/src/filter/src/.gitkeep deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/src/filter/src/butterworth.cpp b/src/filter/src/butterworth.cpp deleted file mode 100644 index ca9eb3764b4d9ca0b3d2f0c6281f38a82205727a..0000000000000000000000000000000000000000 --- a/src/filter/src/butterworth.cpp +++ /dev/null @@ -1,285 +0,0 @@ -/** -* @file butterworth.cpp -* @author Alfonso Dominguez <alfonso.dominguez@tecnalia.com> -* @date 2020 -* -* Copyright 2020 Tecnalia Research & Innovation. -* Distributed under the GNU GPL v3. For full terms see https://www.gnu.org/licenses/gpl.txt -* -* @brief Implementation of a butterworth filter. -*/ - -#include <filter/butterworth.hpp> - -#include <iostream> -#include <stdio.h> -#include <vector> -#include <math.h> - -#include <complex> - -using namespace std; - -#define N 10 //The number of images which construct a time series for each pixel -#define PI 3.1415926535897932384626433832795 - - -Butterworth::Butterworth() -{ - configured_ = false; - temp_ = 0.0; -} - - -int Butterworth::configure(int filter_order, double low_cutoff, double up_cutoff) -{ - filter_order_ = filter_order; - low_cutoff_ = low_cutoff; - up_cutoff_ = up_cutoff; - - den_coeffs_ = ComputeDenCoeffs(); - num_coeffs_ = ComputeNumCoeffs(); - - temp_ = 0.0; - - input_buffer_.reset(new boost::circular_buffer<double>(num_coeffs_.size()-1, temp_)); - output_buffer_.reset(new boost::circular_buffer<double>(den_coeffs_.size()-1, temp_)); - - configured_ = true; - - /*for (int i=0; i < den_coeffs_.size(); i++) - { - std::cout << "Den coff a" << i << ": " << den_coeffs_[i] << std::endl; - } - - for (int i=0; i < num_coeffs_.size(); i++) - { - std::cout << "Num coff b" << i << ": " << num_coeffs_[i] << std::endl; - }*/ - - return 0; -} - - -double * Butterworth::ComputeLP() -{ - double *NumCoeffs; - int m; - int i; - - NumCoeffs = (double *)calloc(filter_order_+1, sizeof(double)); - if(NumCoeffs == NULL) return(NULL); - - NumCoeffs[0] = 1; - NumCoeffs[1] = filter_order_; - m = filter_order_/2; - for(i=2; i <= m; ++i) - { - NumCoeffs[i] =(double) (filter_order_-i+1)*NumCoeffs[i-1]/i; - NumCoeffs[filter_order_-i]= NumCoeffs[i]; - } - NumCoeffs[filter_order_-1] = filter_order_; - NumCoeffs[filter_order_] = 1; - - return NumCoeffs; -} - - -double * Butterworth::ComputeHP() -{ - double *NumCoeffs; - int i; - - NumCoeffs = ComputeLP(); - if(NumCoeffs == NULL) return(NULL); - - for(i = 0; i <= filter_order_; ++i) - if(i % 2) NumCoeffs[i] = -NumCoeffs[i]; - - return NumCoeffs; -} - - -double * Butterworth::TrinomialMultiply(double *b, double *c) -{ - int i, j; - double *RetVal; - - RetVal = (double *)calloc(4 * filter_order_, sizeof(double)); - if(RetVal == NULL) return(NULL); - - RetVal[2] = c[0]; - RetVal[3] = c[1]; - RetVal[0] = b[0]; - RetVal[1] = b[1]; - - for(i = 1; i < filter_order_; ++i) - { - RetVal[2*(2*i+1)] += c[2*i] * RetVal[2*(2*i-1)] - c[2*i+1] * RetVal[2*(2*i-1)+1]; - RetVal[2*(2*i+1)+1] += c[2*i] * RetVal[2*(2*i-1)+1] + c[2*i+1] * RetVal[2*(2*i-1)]; - - for(j = 2*i; j > 1; --j) - { - RetVal[2*j] += b[2*i] * RetVal[2*(j-1)] - b[2*i+1] * RetVal[2*(j-1)+1] + - c[2*i] * RetVal[2*(j-2)] - c[2*i+1] * RetVal[2*(j-2)+1]; - RetVal[2*j+1] += b[2*i] * RetVal[2*(j-1)+1] + b[2*i+1] * RetVal[2*(j-1)] + - c[2*i] * RetVal[2*(j-2)+1] + c[2*i+1] * RetVal[2*(j-2)]; - } - - RetVal[2] += b[2*i] * RetVal[0] - b[2*i+1] * RetVal[1] + c[2*i]; - RetVal[3] += b[2*i] * RetVal[1] + b[2*i+1] * RetVal[0] + c[2*i+1]; - RetVal[0] += b[2*i]; - RetVal[1] += b[2*i+1]; - } - return RetVal; -} - - -std::vector<double> Butterworth::ComputeNumCoeffs() -{ - std::vector<double> num_coeffs; - double *TCoeffs; - double *NumCoeffs; - std::complex<double> *NormalizedKernel; - double Numbers[11]={0,1,2,3,4,5,6,7,8,9,10}; - int i; - - NumCoeffs = (double *)calloc(2*filter_order_+1, sizeof(double)); - if(NumCoeffs == NULL) return(num_coeffs); - - NormalizedKernel = (std::complex<double> *)calloc(2*filter_order_+1, sizeof(std::complex<double>)); - if(NormalizedKernel == NULL) return(num_coeffs); - - TCoeffs = ComputeHP(); - if(TCoeffs == NULL) return(num_coeffs); - - for(i = 0; i < filter_order_; ++i) - { - NumCoeffs[2*i] = TCoeffs[i]; - NumCoeffs[2*i+1] = 0.0; - } - NumCoeffs[2*filter_order_] = TCoeffs[filter_order_]; - double cp[2]; - //double Bw; - double Wn; - cp[0] = 2*2.0*tan(PI * low_cutoff_/ 2.0); - cp[1] = 2*2.0*tan(PI * up_cutoff_/2.0); - - //Bw = cp[1] - cp[0]; - //center frequency - Wn = sqrt(cp[0]*cp[1]); - Wn = 2*atan2(Wn,4); - //double kern; - const std::complex<double> result = std::complex<double>(-1,0); - - for(int k = 0; k<2*filter_order_+1; k++) - { - NormalizedKernel[k] = std::exp(-sqrt(result)*Wn*Numbers[k]); - } - double b=0; - double den=0; - for(int d = 0; d<2*filter_order_+1; d++) - { - b+=real(NormalizedKernel[d]*NumCoeffs[d]); - den+=real(NormalizedKernel[d]*den_coeffs_[d]); - } - for(int c = 0; c<2*filter_order_+1; c++) - { - NumCoeffs[c]=(NumCoeffs[c]*den)/b; - } - - for(int c = 0; c<2*filter_order_+1; c++) - { - num_coeffs.push_back(NumCoeffs[c]); - } - - free(TCoeffs); - - return num_coeffs; -} - - -std::vector<double> Butterworth::ComputeDenCoeffs() -{ - int k; // loop variables - double theta; // PI * (up_cutoff_ - low_cutoff_)/2.0 - double cp; // cosine of phi - double st; // sine of theta - double ct; // cosine of theta - double s2t; // sine of 2*theta - double c2t; // cosine 0f 2*theta - double *RCoeffs; // z^-2 coefficients - double *TCoeffs; // z^-1 coefficients - double *DenomCoeffs; // dk coefficients - double PoleAngle; // pole angle - double SinPoleAngle; // sine of pole angle - double CosPoleAngle; // cosine of pole angle - double a; // workspace variables - - cp = cos(PI * (up_cutoff_ + low_cutoff_)/2.0); - theta = PI * (up_cutoff_ - low_cutoff_)/2.0; - st = sin(theta); - ct = cos(theta); - s2t = 2.0*st*ct; // sine of 2*theta - c2t = 2.0*ct*ct - 1.0; // cosine of 2*theta - - RCoeffs = (double *)calloc(2 * filter_order_, sizeof(double)); - TCoeffs = (double *)calloc(2 * filter_order_, sizeof(double)); - - for(k = 0; k < filter_order_; ++k) - { - PoleAngle = PI * (double)(2*k+1)/(double)(2*filter_order_); - SinPoleAngle = sin(PoleAngle); - CosPoleAngle = cos(PoleAngle); - a = 1.0 + s2t*SinPoleAngle; - RCoeffs[2*k] = c2t/a; - RCoeffs[2*k+1] = s2t*CosPoleAngle/a; - TCoeffs[2*k] = -2.0*cp*(ct+st*SinPoleAngle)/a; - TCoeffs[2*k+1] = -2.0*cp*st*CosPoleAngle/a; - } - - DenomCoeffs = Butterworth::TrinomialMultiply(TCoeffs, RCoeffs); - free(TCoeffs); - free(RCoeffs); - - DenomCoeffs[1] = DenomCoeffs[0]; - DenomCoeffs[0] = 1.0; - for(k = 3; k <= 2*filter_order_; ++k) - DenomCoeffs[k] = DenomCoeffs[2*k-2]; - - std::vector<double> den_coeffs; - for(k = 0; k < 2*filter_order_ + 1; k++) - { - den_coeffs.push_back(DenomCoeffs[k]); - } - - return den_coeffs; -} - - -bool Butterworth::update(const double & data_in, double & data_out) -{ - if (!configured_) - { - return false; - } - - // Copy data to prevent mutation if in and out are the same ptr - temp_ = data_in; - - data_out=num_coeffs_[0] * temp_; - - for (uint32_t row = 1; row <= input_buffer_->size(); row++) - { - data_out += num_coeffs_[row] * (*input_buffer_)[row-1]; - } - for (uint32_t row = 1; row <= output_buffer_->size(); row++) - { - data_out -= den_coeffs_[row] * (*output_buffer_)[row-1]; - } - - input_buffer_->push_front(temp_); - output_buffer_->push_front(data_out); - - return true; -} \ No newline at end of file diff --git a/src/logger/.gitkeep b/src/logger/.gitkeep deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/src/logger/CMakeLists.txt b/src/logger/CMakeLists.txt deleted file mode 100644 index 553590027a063d61081262aac4929d6a9e62d94a..0000000000000000000000000000000000000000 --- a/src/logger/CMakeLists.txt +++ /dev/null @@ -1,38 +0,0 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 2.6) -project(logger) -message("cmake ${PROJECT_NAME}") -if (DEBUG_CMAKE) - set(CMAKE_VERBOSE_MAKEFILE yes) -endif (DEBUG_CMAKE) - -set(logger_files - ${CMAKE_CURRENT_SOURCE_DIR}/src/logger.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/include/logger/logger.hpp - ) - -set(logger_files ${logger_files} PARENT_SCOPE) - -include_directories( - include - ${Boost_INCLUDE_DIR} - ${YAML_INCLUDE_DIR} - ) - -add_library(logger ${logger_files}) -add_dependencies(logger yaml-cpp) -target_link_libraries(logger yaml_tools yaml-cpp ${Boost_LIBRARIES}) -set_target_properties(logger PROPERTIES FOLDER logger) - -# Define headers for this library. PUBLIC headers are used for -# compiling the library, and will be added to consumers' build -# paths. -target_include_directories(logger PUBLIC - $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> - $<INSTALL_INTERFACE:include> - PRIVATE src) - -# This makes the project importable from the build directory -export(TARGETS logger - yaml_tools - yaml-cpp - FILE loggerConfig.cmake) diff --git a/src/logger/include/.gitkeep b/src/logger/include/.gitkeep deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/src/logger/include/logger/.gitkeep b/src/logger/include/logger/.gitkeep deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/src/logger/include/logger/logger.hpp b/src/logger/include/logger/logger.hpp deleted file mode 100644 index 800d148bac553b6a2ab676c626539658ed24b09e..0000000000000000000000000000000000000000 --- a/src/logger/include/logger/logger.hpp +++ /dev/null @@ -1,50 +0,0 @@ -/** -* @logger.hpp -* @author Alfonso Dominguez (alfonso.dominguez@tecnalia.com) -* Copyright 2017 Tecnalia Research and Innovation -* -* @brief Logger class (inspired in https://github.com/gklingler/simpleLogger) -**/ - -#ifndef __LOGGER_HPP__ -#define __LOGGER_HPP__ - -#include <boost/log/trivial.hpp> -#include <boost/log/sources/global_logger_storage.hpp> -#include <string> - -// register a global logger -BOOST_LOG_GLOBAL_LOGGER(logger, boost::log::sources::severity_logger_mt<boost::log::trivial::severity_level>) - -// just a helper macro used by the macros below - don't use it in your code -#define LOG(severity) BOOST_LOG_SEV(logger::get(),boost::log::trivial::severity) - -// ===== log macros ===== -#define LOG_TRACE LOG(trace) -#define LOG_DEBUG LOG(debug) -#define LOG_INFO LOG(info) -#define LOG_WARNING LOG(warning) -#define LOG_ERROR LOG(error) -#define LOG_FATAL LOG(fatal) - -namespace equimetrix -{ - namespace Common - { - class Logger - { - public: - //! default constructor - Logger(); - ~Logger(); - /** - * @brief init the logger from file - * @param filename, configuration/launch file name - */ - void init(std::string filename); - - static std::string log_filename_; - }; - } // namespace Common -} // namespace equimetrix -#endif // LOGGER_HPP__ \ No newline at end of file diff --git a/src/logger/src/.gitkeep b/src/logger/src/.gitkeep deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/src/logger/src/logger.cpp b/src/logger/src/logger.cpp deleted file mode 100644 index 21138f914c77e546a9ba7eebd544ef677bd14bb6..0000000000000000000000000000000000000000 --- a/src/logger/src/logger.cpp +++ /dev/null @@ -1,274 +0,0 @@ -/** -* @logger.cpp -* @author Alfonso Dominguez (alfonso.dominguez@tecnalia.com) -* Copyright 2017 Tecnalia Research and Innovation -* -* @brief Logger class (inspired in https://github.com/gklingler/simpleLogger) -**/ - -#include <logger/logger.hpp> -#include <yaml_tools/yaml_tools.hpp> - -#if !defined(BOOST_USE_WINAPI_VERSION) -#if defined(_WIN32_WINNT) -#define BOOST_USE_WINAPI_VERSION _WIN32_WINNT -#elif defined(WINVER) -#define BOOST_USE_WINAPI_VERSION WINVER -#else -// By default use Windows Vista API on compilers that support it and XP on the others -#if (defined(_MSC_VER) && _MSC_VER < 1500) || defined(BOOST_WINAPI_IS_MINGW) -#define BOOST_USE_WINAPI_VERSION BOOST_WINAPI_VERSION_WINXP -#else -#define BOOST_USE_WINAPI_VERSION BOOST_WINAPI_VERSION_WIN6 -#endif -#endif -#endif - -#include <boost/log/core/core.hpp> -#include <boost/log/expressions/formatters/date_time.hpp> -#include <boost/log/expressions.hpp> -#include <boost/log/sinks/sync_frontend.hpp> -#include <boost/log/sinks/text_ostream_backend.hpp> -#include <boost/log/sources/severity_logger.hpp> -#include <boost/log/support/date_time.hpp> -#include <boost/log/trivial.hpp> -#include <boost/core/null_deleter.hpp> -#include <boost/log/utility/setup/common_attributes.hpp> -#include <boost/log/utility/setup/file.hpp> -#include <boost/make_shared.hpp> -#include <boost/shared_ptr.hpp> -#include <boost/filesystem.hpp> - -#include <fstream> -#include <ostream> - -#include <cstring> - -#include <stdio.h> /* defines FILENAME_MAX */ -#if defined(_WIN32) || defined(WIN32) -#include <direct.h> -#define GetCurrentDir _getcwd -#else -#include <unistd.h> -#define GetCurrentDir getcwd -#endif - -std::string equimetrix::Common::Logger::log_filename_ = ""; - -namespace logging = boost::log; -namespace src = boost::log::sources; -namespace expr = boost::log::expressions; -namespace sinks = boost::log::sinks; -namespace attrs = boost::log::attributes; - -BOOST_LOG_ATTRIBUTE_KEYWORD(line_id, "LineID", unsigned int) -BOOST_LOG_ATTRIBUTE_KEYWORD(timestamp, "TimeStamp", boost::posix_time::ptime) -BOOST_LOG_ATTRIBUTE_KEYWORD(severity, "Severity", logging::trivial::severity_level) - -BOOST_LOG_GLOBAL_LOGGER_INIT(logger, src::severity_logger_mt) { - boost::filesystem::path::imbue(std::locale("C")); - - char cCurrentPath[FILENAME_MAX]; - GetCurrentDir(cCurrentPath, sizeof(cCurrentPath)); - cCurrentPath[sizeof(cCurrentPath) - 1] = '\0'; - std::cout << "[Logger]The current working directory is "<< cCurrentPath << std::endl; - - std::cout << "[Logger] Default logger initialization" << std::endl; - src::severity_logger_mt<boost::log::trivial::severity_level> logger; - - time_t t = time(0); - struct tm * now = localtime(&t); - - char buffer[80]; - strftime(buffer, sizeof(buffer), "%Y%m%d_%H%M%S", now); - - std::wstring ws{ boost::filesystem::path::preferred_separator }; - std::string separator(ws.begin(), ws.end()); - std::ostringstream oss; - oss << std::string(cCurrentPath) << separator << "logs"; - std::string log_dir = oss.str(); - oss << separator << "log_"<< std::string(buffer)<< ".log"; - equimetrix::Common::Logger::log_filename_ = oss.str(); - - if (!(boost::filesystem::is_directory(log_dir) && boost::filesystem::exists(log_dir))) - { - std::cout << "[Logger] Logs dir does not exist. Create it!" << std::endl; - boost::filesystem::create_directory(log_dir); - } - else - { - std::cout << "[Logger] Logs dir already exists" << std::endl; - } - - std::cout << "[Logger] Default log to console and file" << std::endl; - std::cout << "[Logger] Default log_filename: " << equimetrix::Common::Logger::log_filename_ << std::endl; - std::cout << "[Logger] Default severity: " << 0 << std::endl; - - // add attributes - // lines are sequentially numbered - logger.add_attribute("LineID", attrs::counter<unsigned int>(1)); - // each log line gets a timestamp - logger.add_attribute("TimeStamp", attrs::local_clock()); - - // add a text sink - typedef sinks::synchronous_sink<sinks::text_ostream_backend> text_sink; - boost::shared_ptr<text_sink> sink = boost::make_shared<text_sink>(); - - // add a logfile stream to our sink - sink->locked_backend()->add_stream(boost::make_shared<std::ofstream>(equimetrix::Common::Logger::log_filename_)); - // add "console" output stream to our sink - sink->locked_backend()->add_stream(boost::shared_ptr<std::ostream>(&std::clog, boost::null_deleter())); - - // specify the format of the log message - logging::formatter formatter = expr::stream - << std::setw(7) << std::setfill('0') << line_id << std::setfill(' ') << " | " - << expr::format_date_time(timestamp, "%Y-%m-%d, %H:%M:%S.%f") << " " - << "[" << logging::trivial::severity << "]" - << " - " << expr::smessage; - sink->set_formatter(formatter); - - // only messages with severity >= SEVERITY_THRESHOLD are written - sink->set_filter(severity >= 0); - - // "register" our sink - logging::core::get()->add_sink(sink); - - return logger; -} - -namespace equimetrix -{ -namespace Common -{ - Logger::Logger() - { - } - - Logger::~Logger() - { - std::cout << "Logger destructed" << std::endl; - } - - - void Logger::init(std::string filename) - { - src::severity_logger_mt<boost::log::trivial::severity_level> &logger = logger::get(); - - int sink_mode = 2; - int severity_threshold = 0; - bool init_from_file_done = false; - - YAML::Node cfg; - - try - { - cfg = YAML::LoadFile(filename); - std::cout << "[Logger] Reading the config...done" << std::endl; - - std::vector <std::vector < std::string> > lconfig; - lconfig = {{"log", "sink_mode"}, - {"log", "severity_threshold"}}; - - if (!areTagsDefined(lconfig, cfg)) - { - std::cerr << "[Logger] Configuration file uncomplete " << std::endl; - } - else - { - sink_mode = cfg["log"]["sink_mode"].as<int>(); - severity_threshold = cfg["log"]["severity_threshold"].as<int>(); - init_from_file_done = true; - } - } - catch (YAML::BadFile &err) - { - std::cerr << "[Logger]Prb while opening file " << filename - << " : " << err.what() << std::endl; - } - catch (YAML::ParserException &err) - { - std::cerr << "Parsing error in file " << filename - << " : " << err.what() << std::endl; - } - catch (...) - { - std::cerr << "[Logger] Unexpected error while parsing the config file" << std::endl; - } - - if (init_from_file_done) - { - // first remove all the configured properties - std::cout << "[Logger] Custom initialization of the logger from a config file" << std::endl; - std::cout << "[Logger] First, remove default logger configuration (log file, sinks, severity)" << std::endl; - - logging::core::get()->remove_all_sinks(); - - if (std::remove(log_filename_.c_str()) != 0) // log file - { - std::cerr << "[Logger] Failed to remove default log file" << std::endl; - std::cerr << std::strerror(errno) << std::endl; - } - } - else - { - std::cout << "[Logger] Problems with config file, continue with the default configuration" << std::endl; - return; - } - - std::cout << "[Logger] sink_mode: " << sink_mode << std::endl; - std::cout << "[Logger] severity_threshold: " << severity_threshold << std::endl; - - // add a text sink - typedef sinks::synchronous_sink<sinks::text_ostream_backend> text_sink; - boost::shared_ptr<text_sink> sink = boost::make_shared<text_sink>(); - - time_t t = time(0); - struct tm * now = localtime(&t); - - char buffer[80]; - strftime(buffer, sizeof(buffer), "%Y%m%d_%H%M%S", now); - - if (sink_mode == 1 || sink_mode == 2) - { - char cCurrentPath[FILENAME_MAX]; - GetCurrentDir(cCurrentPath, sizeof(cCurrentPath)); - cCurrentPath[sizeof(cCurrentPath) - 1] = '\0'; - - // boost::filesystem::path::preferred_separator; - std::wstring ws{ boost::filesystem::path::preferred_separator }; - std::string separator(ws.begin(), ws.end()); - - equimetrix::Common::Logger::log_filename_ = ""; - std::ostringstream oss; - oss << std::string(cCurrentPath) << separator << "logs" << separator << "log_" << std::string(buffer) << ".log"; - equimetrix::Common::Logger::log_filename_ = oss.str(); - - std::cout << "[Logger] log_filename: " << log_filename_ << std::endl; - - // add a logfile stream to our sink - sink->locked_backend()->add_stream(boost::make_shared<std::ofstream>(log_filename_)); - // logging::add_file_log(log_filename_); - } - - if (sink_mode == 0 || sink_mode == 2) - { - // add "console" output stream to our sink - sink->locked_backend()->add_stream(boost::shared_ptr<std::ostream>(&std::clog, boost::null_deleter())); - } - - // specify the format of the log message - logging::formatter formatter = expr::stream - << std::setw(7) << std::setfill('0') << line_id << std::setfill(' ') << " | " - << expr::format_date_time(timestamp, "%Y-%m-%d, %H:%M:%S.%f") << " " - << "[" << logging::trivial::severity << "]" - << " - " << expr::smessage; - sink->set_formatter(formatter); - - // only messages with severity >= SEVERITY_THRESHOLD are written - sink->set_filter(severity >= severity_threshold); - - // "register" our sink - logging::core::get()->add_sink(sink); - } -} // namespace Common -} // namespace equimetrix diff --git a/src/pandocology.cmake b/src/pandocology.cmake deleted file mode 100644 index 76fc542a54cd668a8fe5b0538a020a8aa6147210..0000000000000000000000000000000000000000 --- a/src/pandocology.cmake +++ /dev/null @@ -1,482 +0,0 @@ -################################################################################ -## -## Provide Pandoc compilation support for the CMake build system -## -## Version: 0.0.1 -## Author: Jeet Sukumatan (jeetsukumaran@gmail.com) -## -## Copyright 2015 Jeet Sukumaran. -## -## This software is released under the BSD 3-Clause License. -## -## Redistribution and use in source and binary forms, with or without -## modification, are permitted provided that the following conditions are -## met: -## -## 1. Redistributions of source code must retain the above copyright notice, -## this list of conditions and the following disclaimer. -## -## 2. Redistributions in binary form must reproduce the above copyright -## notice, this list of conditions and the following disclaimer in the -## documentation and/or other materials provided with the distribution. -## -## 3. Neither the name of the copyright holder nor the names of its -## contributors may be used to endorse or promote products derived from this -## software without specific prior written permission. -## -## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -## IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -## PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -## LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -## NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -## SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -## -################################################################################ - -include(CMakeParseArguments) - -if(NOT EXISTS ${PANDOC_EXECUTABLE}) - # find_program(PANDOC_EXECUTABLE NAMES pandoc) - find_program(PANDOC_EXECUTABLE pandoc) - mark_as_advanced(PANDOC_EXECUTABLE) - if(NOT EXISTS ${PANDOC_EXECUTABLE}) - message(FATAL_ERROR "Pandoc not found. Install Pandoc (http://johnmacfarlane.net/pandoc/) or set cache variable PANDOC_EXECUTABLE.") - return() - endif() -endif() -if(NOT EXISTS ${PP_EXECUTABLE}) - find_program(PP_EXECUTABLE pp) - mark_as_advanced(PP_EXECUTABLE) - if(NOT EXISTS ${PP_EXECUTABLE}) - message("PP not found. If this is wrong, please set cache variable PP_EXECUTABLE.") - endif() -endif() -if(NOT DEFINED ${PREPROCESS_TEMP_DIRECTORY}) - set(PREPROCESS_TEMP_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/_preprocessed") -endif() - -############################################################################### -# Based on code from UseLATEX -# Author: Kenneth Moreland <kmorel@sandia.gov> -# Copyright 2004 Sandia Corporation. -# Under the terms of Contract DE-AC04-94AL85000, there is a non-exclusive -# license for use of this work by or on behalf of the -# U.S. Government. Redistribution and use in source and binary forms, with -# or without modification, are permitted provided that this Notice and any -# statement of authorship are reproduced on all copies. - -# Adds command to copy file from the source directory to the destination -# directory: used to move source files from source directory into build -# directory before main build -function(pandocology_add_input_file source_path dest_dir dest_filelist_var native_dest_filelist_var) - set(dest_filelist) - set(native_dest_filelist) - file(GLOB globbed_source_paths "${source_path}") - foreach(globbed_source_path ${globbed_source_paths}) - get_filename_component(filename ${globbed_source_path} NAME) - get_filename_component(absolute_dest_path ${dest_dir}/${filename} ABSOLUTE) - file(RELATIVE_PATH relative_dest_path ${CMAKE_CURRENT_BINARY_DIR} ${absolute_dest_path}) - list(APPEND dest_filelist ${absolute_dest_path}) - file(TO_NATIVE_PATH ${absolute_dest_path} native_dest_path) - list(APPEND native_dest_filelist ${native_dest_path}) - file(TO_NATIVE_PATH ${globbed_source_path} native_globbed_source_path) - ADD_CUSTOM_COMMAND( - OUTPUT ${relative_dest_path} - COMMAND ${CMAKE_COMMAND} -E copy_if_different ${native_globbed_source_path} ${native_dest_path} - DEPENDS ${globbed_source_path} - ) - set(${dest_filelist_var} ${${dest_filelist_var}} ${dest_filelist} PARENT_SCOPE) - set(${native_dest_filelist_var} ${${native_dest_filelist_var}} ${native_dest_filelist} PARENT_SCOPE) - endforeach() -endfunction() - -# A version of GET_FILENAME_COMPONENT that treats extensions after the last -# period rather than the first. -function(pandocology_get_file_stemname varname filename) - SET(result) - GET_FILENAME_COMPONENT(name ${filename} NAME) - STRING(REGEX REPLACE "\\.[^.]*\$" "" result "${name}") - SET(${varname} "${result}" PARENT_SCOPE) -endfunction() - -function(pandocology_get_file_extension varname filename) - SET(result) - GET_FILENAME_COMPONENT(name ${filename} NAME) - STRING(REGEX MATCH "\\.[^.]*\$" result "${name}") - SET(${varname} "${result}" PARENT_SCOPE) -endfunction() -############################################################################### - -function(pandocology_add_input_dir source_dir dest_parent_dir dir_dest_filelist_var native_dir_dest_filelist_var) - set(dir_dest_filelist) - set(native_dir_dest_filelist) - file(TO_CMAKE_PATH ${source_dir} source_dir) - get_filename_component(dir_name ${source_dir} NAME) - get_filename_component(absolute_dest_dir ${dest_parent_dir}/${dir_name} ABSOLUTE) - file(RELATIVE_PATH relative_dest_dir ${CMAKE_CURRENT_BINARY_DIR} ${absolute_dest_dir}) - file(TO_NATIVE_PATH ${absolute_dest_dir} native_absolute_dest_dir) - add_custom_command( - OUTPUT ${relative_dest_dir} - COMMAND ${CMAKE_COMMAND} -E make_directory ${native_absolute_dest_dir} - DEPENDS ${source_dir} - ) - file(GLOB_RECURSE source_files "${source_dir}/*") - foreach(source_file ${source_files}) - file(RELATIVE_PATH relative_source_file ${source_dir} ${source_file}) - # get_filename_component(absolute_source_path ${CMAKE_CURRENT_SOURCE_DIR}/${source_file} ABSOLUTE) - get_filename_component(relative_source_dir ${relative_source_file} DIRECTORY) - pandocology_add_input_file(${source_file} ${absolute_dest_dir}/${relative_source_dir} dir_dest_filelist native_dir_dest_filelist) - endforeach() - set(${dir_dest_filelist_var} ${${dir_dest_filelist_var}} ${dir_dest_filelist} PARENT_SCOPE) - set(${native_dir_dest_filelist_var} ${${native_dir_dest_filelist_var}} ${native_dir_dest_filelist} PARENT_SCOPE) -endfunction() - -function(add_to_make_clean filepath) - file(TO_NATIVE_PATH ${CMAKE_CURRENT_BINARY_DIR}/${filepath} native_filepath) - get_directory_property(make_clean_files ADDITIONAL_MAKE_CLEAN_FILES) - set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${make_clean_files};${native_filepath}") -endfunction() - -function(disable_insource_build) - IF ( CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR AND NOT MSVC_IDE ) - MESSAGE(FATAL_ERROR "The build directory must be different from the main project source " -"directory. Please create a directory such as '${CMAKE_SOURCE_DIR}/build', " -"and run CMake from there, passing the path to this source directory as " -"the path argument. E.g.: - $ cd ${CMAKE_SOURCE_DIR} - $ mkdir build - $ cd build - $ cmake .. && make && sudo make install -This process created the file `CMakeCache.txt' and the directory `CMakeFiles'. -Please delete them: - $ rm -r CMakeFiles/ CmakeCache.txt -") - ENDIF() -endfunction() - -# This builds a document -# -# Usage: -# -# -# INCLUDE(pandocology) -# -# add_document( -# TARGET figures -# OUTPUT_FILE figures.tex -# SOURCES figures.md -# RESOURCE_DIRS figs -# PANDOC_DIRECTIVES -t latex -# NO_EXPORT_PRODUCT -# ) -# -# add_document( -# TARGET opus -# OUTPUT_FILE opus.pdf -# SOURCES opus.md -# RESOURCE_FILES opus.bib systbiol.template.latex systematic-biology.csl -# RESOURCE_DIRS figs -# PANDOC_DIRECTIVES -t latex -# --smart -# --template systbiol.template.latex -# --filter pandoc-citeproc -# --csl systematic-biology.csl -# --bibliography opus.bib -# --include-after-body=figures.tex -# DEPENDS figures -# EXPORT_ARCHIVE -# ) -# -# -# Deprecated command signature for backwards compatibility: -# -# add_document( -# figures.tex -# SOURCES figures.md -# RESOURCE_DIRS figs -# PANDOC_DIRECTIVES -t latex -# NO_EXPORT_PRODUCT -# ) -# -# This command signature will cause an error due to a circular dependency during -# build when the sources are at the top level directory of the project. A -# warning is issued. The solution is to use the alternative commande signature. -# -function(add_document) - set(options EXPORT_ARCHIVE NO_EXPORT_PRODUCT EXPORT_PDF DIRECT_TEX_TO_PDF VERBOSE PREPROCESS) - set(oneValueArgs TARGET OUTPUT_FILE PRODUCT_DIRECTORY) - set(multiValueArgs SOURCES RESOURCE_FILES RESOURCE_DIRS PANDOC_DIRECTIVES PP_DIRECTIVES DEPENDS) - cmake_parse_arguments(ADD_DOCUMENT "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} ) - - # this is because `make clean` will dangerously clean up source files - disable_insource_build() - - if ("${ADD_DOCUMENT_TARGET}" STREQUAL "" AND "${ADD_DOCUMENT_OUTPUT_FILE}" STREQUAL "") - set(bw_comp_mode_args TRUE) - endif() - - if(bw_comp_mode_args) - list(LENGTH ADD_DOCUMENT_UNPARSED_ARGUMENTS unparsed_args_num) - if (${unparsed_args_num} GREATER 1) - message(FATAL_ERROR "add_document() requires at most one target name") - endif() - - if (${CMAKE_CURRENT_SOURCE_DIR} STREQUAL ${CMAKE_SOURCE_DIR}) - message(WARNING "This add_document() signature does not support sources on the top level directory. \ - It will cause a circular dependency error during build.") - endif() - - list(GET ADD_DOCUMENT_UNPARSED_ARGUMENTS 0 ADD_DOCUMENT_TARGET) - set(ADD_DOCUMENT_OUTPUT_FILE ${ADD_DOCUMENT_TARGET}) - endif() - - if ("${ADD_DOCUMENT_TARGET}" STREQUAL "") - MESSAGE(FATAL_ERROR "add_document() requires a target name by using the TARGET option") - endif() - - if ("${ADD_DOCUMENT_OUTPUT_FILE}" STREQUAL "") - MESSAGE(FATAL_ERROR "add_document() requires an output file name by using the OUTPUT_FILE option") - endif() - - if (NOT bw_comp_mode_args) - if ("${ADD_DOCUMENT_TARGET}" STREQUAL "${ADD_DOCUMENT_OUTPUT_FILE}") - message(FATAL_ERROR "Target '${ADD_DOCUMENT_TARGET}': Must different from OUTPUT_FILE") - endif() - endif() - - set(output_file ${ADD_DOCUMENT_OUTPUT_FILE}) - file(TO_NATIVE_PATH ${output_file} native_output_file) - - # get the stem of the target name - pandocology_get_file_stemname(output_file_stemname ${output_file}) - pandocology_get_file_extension(output_file_extension ${output_file}) - - if (${ADD_DOCUMENT_EXPORT_PDF}) - if (NOT "${output_file_extension}" STREQUAL ".tex" AND NOT "${output_file_extension}" STREQUAL ".latex") - MESSAGE(FATAL_ERROR "Target '${ADD_DOCUMENT_TARGET}': Cannot use 'EXPORT_PDF' for target of type '${output_file_extension}': target type must be '.tex' or '.latex'") - endif() - endif() - - if (${ADD_DOCUMENT_DIRECT_TEX_TO_PDF}) - list(LENGTH ${ADD_DOCUMENT_SOURCES} SOURCE_LEN) - if (SOURCE_LEN GREATER 1) - MESSAGE(FATAL_ERROR "Target '${ADD_DOCUMENT_TARGET}': Only one source can be specified when using the 'DIRECT_TEX_TO_PDF' option") - endif() - - pandocology_get_file_stemname(source_stemname ${ADD_DOCUMENT_SOURCES}) - pandocology_get_file_extension(source_extension ${ADD_DOCUMENT_SOURCES}) - - if (NOT "${source_extension}" STREQUAL ".tex" AND NOT "${source_extension}" STREQUAL ".latex") - MESSAGE(FATAL_ERROR "Target '${ADD_DOCUMENT_TARGET}': Cannot use 'DIRECT_TEX_TO_PDF' for source of type '${source_extension}': source type must be '.tex' or '.latex'") - endif() - - set(check_target ${source_stemname}.pdf) - if (NOT ${check_target} STREQUAL ${output_file}) - MESSAGE(FATAL_ERROR "Target '${ADD_DOCUMENT_TARGET}': Must use target name of '${check_target}' if using 'DIRECT_TEX_TO_PDF'") - endif() - endif() - - ## set up output directory - if ("${ADD_DOCUMENT_PRODUCT_DIRECTORY}" STREQUAL "") - set(ADD_DOCUMENT_PRODUCT_DIRECTORY "product") - endif() - - get_filename_component(product_directory ${CMAKE_BINARY_DIR}/${ADD_DOCUMENT_PRODUCT_DIRECTORY} ABSOLUTE) - file(TO_NATIVE_PATH ${product_directory} native_product_directory) - - set(dest_output_file ${product_directory}/${output_file}) - file(TO_NATIVE_PATH ${dest_output_file} native_dest_output_file) - - ## get primary source - set(build_sources) - set(native_build_sources) - foreach(input_file ${ADD_DOCUMENT_SOURCES} ) - pandocology_add_input_file(${CMAKE_CURRENT_SOURCE_DIR}/${input_file} ${CMAKE_CURRENT_BINARY_DIR} build_sources native_build_sources) - endforeach() - - ## get resource files - # set(build_resources) - # set(native_build_resources) - # foreach(resource_file ${ADD_DOCUMENT_RESOURCE_FILES}) - # if(IS_ABSOLUTE ${resource_file}) - # pandocology_add_input_file(${resource_file} ${CMAKE_CURRENT_BINARY_DIR} build_resources native_build_resources) - # else() - # pandocology_add_input_file(${CMAKE_CURRENT_SOURCE_DIR}/${resource_file} ${CMAKE_CURRENT_BINARY_DIR} build_resources native_build_resources) - # endforeach() - - ## get resource dirs - set(exported_resources) - set(native_exported_resources) - foreach(resource_dir ${ADD_DOCUMENT_RESOURCE_DIRS}) - if(IS_ABSOLUTE ${resource_dir}) - pandocology_add_input_dir(${resource_dir} ${CMAKE_CURRENT_BINARY_DIR} build_resources native_build_resources) - else() - pandocology_add_input_dir(${CMAKE_CURRENT_SOURCE_DIR}/${resource_dir} ${CMAKE_CURRENT_BINARY_DIR} build_resources native_build_resources) - endif() - if (${ADD_DOCUMENT_EXPORT_ARCHIVE}) - pandocology_add_input_dir(${CMAKE_CURRENT_SOURCE_DIR}/${resource_dir} ${product_directory} exported_resources native_exported_resources) - endif() - endforeach() - - ## primary command - if (${ADD_DOCUMENT_DIRECT_TEX_TO_PDF}) - if (${ADD_DOCUMENT_VERBOSE}) - add_custom_command( - OUTPUT ${output_file} # note that this is in the build directory - DEPENDS ${build_sources} ${build_resources} ${ADD_DOCUMENT_DEPENDS} - COMMAND ${CMAKE_COMMAND} -E make_directory ${native_product_directory} - COMMAND latexmk -gg -halt-on-error -interaction=nonstopmode -file-line-error -pdf ${native_build_sources} - ) - else() - add_custom_command( - OUTPUT ${output_file} # note that this is in the build directory - DEPENDS ${build_sources} ${build_resources} ${ADD_DOCUMENT_DEPENDS} - COMMAND ${CMAKE_COMMAND} -E make_directory ${native_product_directory} - COMMAND latexmk -gg -halt-on-error -interaction=nonstopmode -file-line-error -pdf ${native_build_sources} 2>/dev/null >/dev/null || (grep --no-messages -A8 ".*:[0-9]*:.*" ${output_file_stemname}.log && false) - ) - endif() - add_to_make_clean(${output_file}) - else() - if(${ADD_DOCUMENT_PREPROCESS}) - if(EXISTS ${PP_EXECUTABLE}) - message("Preprocessing documents with PP.") - set(PREPROCESSING_WITH_PP) - file(MAKE_DIRECTORY ${PREPROCESS_TEMP_DIRECTORY}) - set(preprocessed_build_sources) - foreach(native_build_source ${native_build_sources}) - get_filename_component(native_source_name ${native_build_source} NAME) - set(preprocessed_build_source "${PREPROCESS_TEMP_DIRECTORY}/${native_source_name}") - set(pp_working_directory ${CMAKE_CURRENT_SOURCE_DIR}) - file(RELATIVE_PATH preprocessed_output_filepath ${pp_working_directory} ${preprocessed_build_source}) - add_custom_command( - OUTPUT ${preprocessed_build_source} - DEPENDS ${build_sources} ${build_resources} ${ADD_DOCUMENT_DEPENDS} - COMMAND ${PP_EXECUTABLE} ${ADD_DOCUMENT_PP_DIRECTIVES} ${native_build_source} > ${preprocessed_output_filepath} - VERBATIM - WORKING_DIRECTORY ${pp_working_directory} - ) - add_to_make_clean(${preprocessed_build_source}) - list(APPEND preprocessed_build_sources ${preprocessed_build_source}) - endforeach() - add_custom_command( - OUTPUT ${output_file} # note that this is in the build directory - DEPENDS ${preprocessed_build_sources} ${build_resources} ${ADD_DOCUMENT_DEPENDS} - COMMAND ${CMAKE_COMMAND} -E make_directory ${native_product_directory} - COMMAND ${PANDOC_EXECUTABLE} ${preprocessed_build_sources} ${ADD_DOCUMENT_PANDOC_DIRECTIVES} -o ${native_output_file} - ) - add_to_make_clean(${output_file}) - else() - message(FATAL_ERROR "PREPROCESS set but no preprocessor found!") - return() - endif() - else() - add_custom_command( - OUTPUT ${output_file} # note that this is in the build directory - DEPENDS ${build_sources} ${build_resources} ${ADD_DOCUMENT_DEPENDS} - COMMAND ${CMAKE_COMMAND} -E make_directory ${native_product_directory} - COMMAND ${PANDOC_EXECUTABLE} ${native_build_sources} ${ADD_DOCUMENT_PANDOC_DIRECTIVES} -o ${native_output_file} - ) - add_to_make_clean(${output_file}) - endif() - endif() - - add_custom_target ( - ${output_file}_product - DEPENDS ${output_file} - ) - - ## figure out what all is going to be produced by this build set, and set - ## those as dependencies of the primary target - set(primary_target_dependencies) - set(primary_target_dependencies ${primary_target_dependencies} ${CMAKE_CURRENT_BINARY_DIR}/${output_file}) - if (NOT ${ADD_DOCUMENT_NO_EXPORT_PRODUCT}) - set(primary_target_dependencies ${primary_target_dependencies} ${product_directory}/${output_file}) - endif() - if (${ADD_DOCUMENT_EXPORT_PDF}) - set(primary_target_dependencies ${primary_target_dependencies} ${CMAKE_CURRENT_BINARY_DIR}/${output_file_stemname}.pdf) - set(primary_target_dependencies ${primary_target_dependencies} ${product_directory}/${output_file_stemname}.pdf) - endif() - if (${ADD_DOCUMENT_EXPORT_ARCHIVE}) - set(primary_target_dependencies ${primary_target_dependencies} ${product_directory}/${output_file_stemname}.tbz) - endif() - - ## primary target - # # target cannot have same (absolute name) as dependencies: - # # http://www.cmake.org/pipermail/cmake/2011-March/043378.html - add_custom_target( - ${ADD_DOCUMENT_TARGET} - ALL - DEPENDS ${primary_target_dependencies} ${ADD_DOCUMENT_DEPENDS} - ) - - # run post-pdf - if (${ADD_DOCUMENT_EXPORT_PDF}) - add_custom_command( - OUTPUT ${native_product_directory}/${output_file_stemname}.pdf ${CMAKE_CURRENT_BINARY_DIR}/${output_file_stemname}.pdf - DEPENDS ${output_file} ${build_sources} ${build_resources} ${ADD_DOCUMENT_DEPENDS} - - # Does not work: custom template used to generate tex is ignored - # COMMAND ${PANDOC_EXECUTABLE} ${output_file} -f latex -o ${output_file_stemname}.pdf - - # (1) Apparently, both nonstopmode and batchmode produce an output file - # even if there was an error. This tricks latexmk into believing - # the file is actually up-to-date. - # So we use `-halt-on-error` or `-interaction=errorstopmode` - # instead. - # (2) `grep` returns a non-zero error code if the pattern is not - # found. So, in our scheme below to filter the output of - # `pdflatex`, it is precisely when there is NO error that - # grep returns a non-zero code, which fools CMake into thinking - # tex'ing failed. - # Hence the need for `| grep ...| cat` or `| grep || true`. - # But we can go better: - # latexmk .. || (grep .. && false) - # So we can have our cake and eat it too: here we want to - # re-raise the error after a successful grep if there was an - # error in `latexmk`. - # COMMAND latexmk -gg -halt-on-error -interaction=nonstopmode # -file-line-error -pdf ${output_file} 2>&1 | grep -A8 ".*:[0-9]*:.*" || true - COMMAND latexmk -gg -halt-on-error -interaction=nonstopmode -file-line-error -pdf ${native_output_file} 2>/dev/null >/dev/null || (grep --no-messages -A8 ".*:[0-9]*:.*" ${output_file_stemname}.log && false) - - COMMAND ${CMAKE_COMMAND} -E copy ${output_file_stemname}.pdf ${native_product_directory} - ) - add_to_make_clean(${output_file_stemname}.pdf) - add_to_make_clean(${product_directory}/${output_file_stemname}.pdf) - endif() - - ## copy products - if (NOT ${ADD_DOCUMENT_NO_EXPORT_PRODUCT}) - add_custom_command( - OUTPUT ${native_dest_output_file} - DEPENDS ${build_sources} ${build_resources} ${ADD_DOCUMENT_DEPENDS} ${output_file}_product - COMMAND ${CMAKE_COMMAND} -E copy_if_different ${native_output_file} ${native_dest_output_file} - ) - add_to_make_clean(${product_directory}/${output_file}) - endif() - - ## copy resources - set(export_archive_file ${product_directory}/${output_file_stemname}.tbz) - file(TO_NATIVE_PATH ${export_archive_file} native_export_archive_file) - - if (${ADD_DOCUMENT_EXPORT_ARCHIVE}) - add_custom_command( - OUTPUT ${export_archive_file} - DEPENDS ${output_file} - COMMAND ${CMAKE_COMMAND} -E tar cjf ${native_export_archive_file} ${native_output_file} ${native_build_resources} ${ADD_DOCUMENT_DEPENDS} - ) - add_to_make_clean(${export_archive_file}) - endif() -endfunction(add_document) - -function(add_tex_document) - add_document(${ARGV} DIRECT_TEX_TO_PDF) -endfunction() - -# LEGACY SUPPORT -function(add_pandoc_document) - add_document(${ARGV}) -endfunction() \ No newline at end of file diff --git a/src/protobuf/.gitkeep b/src/protobuf/.gitkeep deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/src/protobuf/class.proto b/src/protobuf/class.proto deleted file mode 100644 index cf6dc161bc35b950be366ba82a8b2138e1873f5c..0000000000000000000000000000000000000000 --- a/src/protobuf/class.proto +++ /dev/null @@ -1,22 +0,0 @@ -syntax = "proto2"; - -package class; - -message Command { - optional string name = 1; - optional int32 id = 2; - optional string email = 3; - - enum PhoneType { - MOBILE = 0; - HOME = 1; - WORK = 2; - } - - message PhoneNumber { - optional string number = 1; - optional PhoneType type = 2 [default = HOME]; - } - - repeated PhoneNumber phones = 4; -} \ No newline at end of file diff --git a/src/tests/.gitkeep b/src/tests/.gitkeep deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt deleted file mode 100644 index bf95850eaf0e84d9c2447acd47e9cd8054521ff4..0000000000000000000000000000000000000000 --- a/src/tests/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 2.6) -project (tests) - -add_subdirectory(test_cpp) -add_subdirectory(test_wrappers) \ No newline at end of file diff --git a/src/tests/test_cpp/.gitkeep b/src/tests/test_cpp/.gitkeep deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/src/tests/test_cpp/CMakeLists.txt b/src/tests/test_cpp/CMakeLists.txt deleted file mode 100644 index c44b843f3c6c46951642199f5783fac6409c8645..0000000000000000000000000000000000000000 --- a/src/tests/test_cpp/CMakeLists.txt +++ /dev/null @@ -1,20 +0,0 @@ -cmake_minimum_required(VERSION 3.14) -project(test_cpp) - -include_directories(../../api/class/include/class) - -add_executable(test_cpp_acq test_cpp_acq.cpp) -target_link_libraries(test_cpp_acq class) - -add_executable(test_cpp_stim test_cpp_stim.cpp) -target_link_libraries(test_cpp_stim class) - -add_executable(test_cpp_callback test_cpp_callback.cpp) -target_link_libraries(test_cpp_callback class) - -install(TARGETS test_cpp_acq test_cpp_stim test_cpp_callback RUNTIME DESTINATION class_api/examples/bin/cpp) -install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/test_cpp_acq.cpp ${CMAKE_CURRENT_SOURCE_DIR}/test_cpp_stim.cpp ${CMAKE_CURRENT_SOURCE_DIR}/test_cpp_callback.cpp DESTINATION class_api/examples/src/cpp) -if (WIN32) - install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/test_cpp_acq.bat ${CMAKE_CURRENT_SOURCE_DIR}/test_cpp_stim.bat ${CMAKE_CURRENT_SOURCE_DIR}/test_cpp_callback.bat DESTINATION class_api/examples/bin/cpp) -endif (WIN32) -install (FILES ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists_install.txt DESTINATION class_api/examples/src/cpp RENAME CMakeLists.txt) \ No newline at end of file diff --git a/src/tests/test_cpp/CMakeLists_install.txt b/src/tests/test_cpp/CMakeLists_install.txt deleted file mode 100644 index 7e8cb985661f22fcb25d4c98374927029f2712cb..0000000000000000000000000000000000000000 --- a/src/tests/test_cpp/CMakeLists_install.txt +++ /dev/null @@ -1,19 +0,0 @@ -cmake_minimum_required(VERSION 3.14) -project(test_cpp) - -link_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../../lib/cpp) -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../../include/class ${CMAKE_CURRENT_SOURCE_DIR}/../../../include) - -add_library(class_dll SHARED IMPORTED) -set_target_properties(class_dll PROPERTIES IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/../../../lib/cpp/class.dll) -set_target_properties(class_dll PROPERTIES IMPORTED_IMPLIB ${CMAKE_CURRENT_SOURCE_DIR}/../../../lib/cpp/class.lib) -set_target_properties(class_dll PROPERTIES INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_SOURCE_DIR}/../../../include/class) - -add_executable(test_cpp_acq test_cpp_acq.cpp) -target_link_libraries(test_cpp_acq class_dll) - -add_executable(test_cpp_stim test_cpp_stim.cpp) -target_link_libraries(test_cpp_stim class_dll) - -add_executable(test_cpp_callback test_cpp_callback.cpp) -target_link_libraries(test_cpp_callback class_dll) \ No newline at end of file diff --git a/src/tests/test_cpp/test_cpp_acq.bat b/src/tests/test_cpp/test_cpp_acq.bat deleted file mode 100644 index e0889c87f75eb664558c49a1680a65e523bdfaf6..0000000000000000000000000000000000000000 --- a/src/tests/test_cpp/test_cpp_acq.bat +++ /dev/null @@ -1,3 +0,0 @@ -set CLASS_LIB_PATH=..\..\..\lib\cpp -echo %PATH%|find /i "%CLASS_LIB_PATH:"=%">nul || set PATH=%CLASS_LIB_PATH%;%PATH% -test_cpp_acq.exe \ No newline at end of file diff --git a/src/tests/test_cpp/test_cpp_acq.cpp b/src/tests/test_cpp/test_cpp_acq.cpp deleted file mode 100644 index e12bbaba1ebbb4a02c8fbe7effc944105e923b2e..0000000000000000000000000000000000000000 --- a/src/tests/test_cpp/test_cpp_acq.cpp +++ /dev/null @@ -1,100 +0,0 @@ -/** - * @file test_cpp_acq.hpp - * @author Alfonso Dominguez <alfonso.dominguez@tecnalia.com> and Leire Querejeta Lomas <leire.querejeta@tecnalia.com> - * @date 2020 - * - * Copyright 2020 Tecnalia Research & Innovation. - * - * @brief Example of use of CLASS_API in CPP for acquisition - */ - -#include "class.hpp" -#include <iostream> -#include <sstream> -#include <chrono> -#include <thread> -#include <iomanip> - -int main(int argc, char * argv[]) -{ - Class class_device; - std::cout << "[TestAcq] Connect" << std::endl; - int response = class_device.connect(); - if (response !=0 ) - { - return -1; - } - - std::cout << "[TestAcq] Configuring CLASS" << std::endl; - class_device.initCommunication(); - std::vector<int> channels; - //get acq from 7 - channels.push_back(7); - class_device.setAcqConfig(Class::FREQ_250, channels, Class::GAIN_24, Class::TEST); - class_device.startAcqStream(); - std::cout << "[TestAcq] Start acquisition" << std::endl; - class_device.startAcq(); - - std::cout << "[TestAcq] Wait 20 seconds" << std::endl; - int loop_number = 0; - while (loop_number < 20) - { - std::vector<AcqFrame> acq_frames = class_device.getAcqFrames(); - //std::cout << "[TestAcq]" << acq_frames.size() << " frames received" << std::endl; - for(int i=0; i <acq_frames.size(); i++) - { - std::ostringstream channels_string_oss; - int j = 1; - for(int j=0; j <acq_frames[i].values.size(); j++) - { - channels_string_oss << ", ch" << (j+1) << ": " << std::fixed << std::setprecision(4) << (double)acq_frames[i].values[j] << "(uV)"; - } - std::cout << "Frame " << i << ": Timestamp: " << std::fixed << std::setprecision(4) << acq_frames[i].timestamp << "(ms)" << channels_string_oss.str() << std::endl; - } - std::this_thread::sleep_for(std::chrono::milliseconds(1000)); - loop_number += 1; - std::cout << "[TestAcq] " << loop_number << " second(s)" << std::endl; - } - - std::cout << "[TestAcq] Stop acquisition" << std::endl; - class_device.stopAcq(); - - std::this_thread::sleep_for(std::chrono::milliseconds(1000)); - - class_device.setAcqImpedanceConfig(Class::TYPE_POSITIVE); - class_device.setAcqImpedancePolarity(Class::TYPE_UNIPOLAR); - - std::cout << "[TestAcq] Start impedance acquisition" << std::endl; - class_device.startAcqStream(); - class_device.startImpedanceAcq(); - std::cout << "[TestAcq] Wait 20 seconds" << std::endl; - loop_number = 0; - while (loop_number < 20) - { - std::vector<AcqFrame> acq_frames = class_device.getAcqFrames(); - for(int i=0; i <acq_frames.size(); i++) - { - std::ostringstream channels_string_oss; - int j = 1; - for(int j=0; j <acq_frames[i].values.size(); j++) - { - channels_string_oss << ", ch" << (j+1) << ": " << std::fixed << std::setprecision(4) << acq_frames[i].values[j] << "(ohms)"; - } - std::cout << "Frame " << i << ": Timestamp: " << std::fixed << std::setprecision(4) << acq_frames[i].timestamp << "(ms)" << channels_string_oss.str() << std::endl; - } - std::this_thread::sleep_for(std::chrono::milliseconds(1000)); - loop_number += 1; - std::cout << "[TestAcq] " << loop_number << " second(s)" << std::endl; - } - std::cout << "[TestAcq] Stop impedance acquisition" << std::endl; - class_device.stopImpedanceAcq(); - - std::cout << "[TestAcq] Disconnect" << std::endl; - response = class_device.disconnect(); - if (response !=0 ) - { - return -1; - } - - return 0; -} \ No newline at end of file diff --git a/src/tests/test_cpp/test_cpp_callback.bat b/src/tests/test_cpp/test_cpp_callback.bat deleted file mode 100644 index 87d94d3846c8373323e63de87524ef2d25437ab8..0000000000000000000000000000000000000000 --- a/src/tests/test_cpp/test_cpp_callback.bat +++ /dev/null @@ -1,3 +0,0 @@ -set CLASS_LIB_PATH=..\..\..\lib\cpp -echo %PATH%|find /i "%CLASS_LIB_PATH:"=%">nul || set PATH=%CLASS_LIB_PATH%;%PATH% -test_cpp_callback.exe \ No newline at end of file diff --git a/src/tests/test_cpp/test_cpp_callback.cpp b/src/tests/test_cpp/test_cpp_callback.cpp deleted file mode 100644 index 38782fafe9bae3a418267acb035419788490ac1f..0000000000000000000000000000000000000000 --- a/src/tests/test_cpp/test_cpp_callback.cpp +++ /dev/null @@ -1,150 +0,0 @@ -/** - * @file test_cpp.hpp - * @author Alfonso Dominguez <alfonso.dominguez@tecnalia.com> and Leire Querejeta Lomas <leire.querejeta@tecnalia.com> - * @date 2020 - * - * Copyright 2020 Tecnalia Research & Innovation. - * - * @brief Example of use of CLASS_API in CPP for stimulation - */ - -#include "class.hpp" -#include <iostream> -#include <sstream> -#include <chrono> -#include <thread> -#include <string> - -bool turnOffHandle_ = false; - -class TestCallback : ClassCallback -{ - public: - TestCallback() - { - - } - - void batteryHandle(double battery) - { - std::cout << "[TestCB] Received battery: " << battery << std::endl; - } - - void firmwareHandle(std::string firmware) - { - std::cout << "[TestCB] firmware value: " << firmware << std::endl; - } - - void deviceNameHandle(std::string device) - { - std::cout << "[TestCB] device value: " << device << std::endl; - } - - void logeventsHandle(std::string logevents) - { - std::cout << "[TestCB] logevents: " << logevents << std::endl; - } - - void patternHandle(std::string patternstatus) - { - std::cout << "[TestCB] patternstatus: " << patternstatus << std::endl; - } - - void velecstatusHandle(std::string velecstatus) - { - std::cout << "[TestCB] velecstatus: " << velecstatus << std::endl; - } - - void hvHandle(std::string hvstatus) - { - std::cout << "[TestCB] hvstatus: " << hvstatus << std::endl; - } - - void intervalHandle(std::string intervalstatus) - { - std::cout << "[TestCB] intervalstatus: " << intervalstatus << std::endl; - } - - void rtcHandle(std::string rtcstatus) - { - std::cout << "[TestCB] rtcstatus: " << rtcstatus << std::endl; - } - - void buzzerHandle(std::string buzzerstatus) - { - std::cout << "[TestCB] buzzerstatus: " << buzzerstatus << std::endl; - } - - void frequencyHandle(std::string frequencystatus) - { - std::cout << "[TestCB] frequency: " << frequencystatus << std::endl; - } - - void hardwareHandle(std::string hardware) - { - std::cout << "[TestCB] hardware value: " << hardware << std::endl; - } - - void ticHandle(std::string tic) - { - std::cout << "[TestCB] tic value: " << tic << std::endl; - } - - void turnOffHandle() - { - std::cout << "[TestCB] Received turn off" << std::endl; - turnOffHandle_ = true; - } - - void sdfunctionHandle(std::string sdfunctionstatus) - { - std::cout << "[TestCB] sd function: " << sdfunctionstatus << std::endl; - } - - void sdunameHandle(std::string sdunamestatus) - { - std::cout << "[TestCB] sd user name: " << sdunamestatus << std::endl; - } - -}; - -int main(int argc, char * argv[]) -{ - Class class_device; - std::cout << "[TestCB] Connect" << std::endl; - int response = class_device.connect(); - if (response !=0 ) - { - return -1; - } - - std::cout << "[TestCB] Configuring CLASS" << std::endl; - class_device.initCommunication(); - - std::cout << "[TestCB] Set battery callback"<< std::endl; - ClassCallback *callback; - TestCallback *test_callback = new TestCallback(); - callback = (ClassCallback *) test_callback; - class_device.setCallback(callback, "cpp"); - - std::cout << "[TestCB] Get battery. Wait 20 seconds"<< std::endl; - int loop_number = 0; - while (loop_number < 20 && !turnOffHandle_) - { - class_device.getBattery(); - std::this_thread::sleep_for(std::chrono::milliseconds(1000)); - loop_number += 1; - std::cout << "[TestCB] Waiting... " << loop_number << " second(s)"<< std::endl; - } - - std::cout << "[TestCB] Stop getting battery"<< std::endl; - - std::cout << "[TestCB] Disconnect" << std::endl; - response = class_device.disconnect(); - if (response !=0 ) - { - return -1; - } - - return 0; -} \ No newline at end of file diff --git a/src/tests/test_cpp/test_cpp_stim.bat b/src/tests/test_cpp/test_cpp_stim.bat deleted file mode 100644 index 062651826630f444c3ed0a6309edc432038704e1..0000000000000000000000000000000000000000 --- a/src/tests/test_cpp/test_cpp_stim.bat +++ /dev/null @@ -1,3 +0,0 @@ -set CLASS_LIB_PATH=..\..\..\lib\cpp -echo %PATH%|find /i "%CLASS_LIB_PATH:"=%">nul || set PATH=%CLASS_LIB_PATH%;%PATH% -test_cpp_stim.exe \ No newline at end of file diff --git a/src/tests/test_cpp/test_cpp_stim.cpp b/src/tests/test_cpp/test_cpp_stim.cpp deleted file mode 100644 index c6f3e2a66ab16d6cbc71f0bb5173d535e6167990..0000000000000000000000000000000000000000 --- a/src/tests/test_cpp/test_cpp_stim.cpp +++ /dev/null @@ -1,66 +0,0 @@ -/** - * @file test_cpp.hpp - * @author Alfonso Dominguez <alfonso.dominguez@tecnalia.com> - * @date 2020 - * - * Copyright 2020 Tecnalia Research & Innovation. - * - * @brief Example of use of CLASS_API in CPP for stimulation - */ - -#include "class.hpp" -#include <iostream> -#include <sstream> -#include <chrono> -#include <thread> - -int main(int argc, char * argv[]) -{ - Class class_device; - std::cout << "[TestStim] Connect" << std::endl; - int response = class_device.connect(); - if (response !=0 ) - { - return -1; - } - - std::cout << "[TestStim] Configuring CLASS" << std::endl; - class_device.initCommunication(); - - std::cout << "[TestStim] Create electrode 1. Set number of pads in electrode 1 to 32"<< std::endl; - class_device.setElecPads(1, 32); - std::cout << "[TestStim] Set frequency of stimulation to 35Hz"<< std::endl; - class_device.setStimFreq(35.0); - std::cout << "[TestStim] Create virtual electrode for thumb. Its ID is 10. One cathode in pad 7. One anode in pad 4. Amp set to 2,5. Width to 400. Selected. Not sync"<< std::endl; - std::vector<int> cathodes; - cathodes.push_back(4); - std::vector<int> anodes; - anodes.push_back(7); - std::vector<double> amp; - amp.push_back(2.5); - std::vector<int> width; - width.push_back(400); - class_device.setVelec(10, "thumb", 1, cathodes, anodes, amp, width, true, false); - std::cout << "[TestStim] Start stimulation"<< std::endl; - class_device.startStim(); - std::cout << "[TestStim] Stimulate 20 seconds"<< std::endl; - int loop_number = 0; - while (loop_number < 20) - { - std::this_thread::sleep_for(std::chrono::milliseconds(1000)); - loop_number += 1; - std::cout << "[TestStim] Stimulating... " << loop_number << " second(s)"<< std::endl; - } - std::cout << "[TestStim] Stop stimulation"<< std::endl; - class_device.stopStim(); - - - std::cout << "[TestStim] Disconnect" << std::endl; - response = class_device.disconnect(); - if (response !=0 ) - { - return -1; - } - - return 0; -} \ No newline at end of file diff --git a/src/tests/test_wrappers/.gitkeep b/src/tests/test_wrappers/.gitkeep deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/src/tests/test_wrappers/CMakeLists.txt b/src/tests/test_wrappers/CMakeLists.txt deleted file mode 100644 index 9381fe1b85ea4d428ae3044a1e048f38f671ca15..0000000000000000000000000000000000000000 --- a/src/tests/test_wrappers/CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 2.6) -project (tests_wrappers) - -#add_subdirectory(python) - -#if(BUILD_DOTNET) -# add_subdirectory(csharp) -#endif() \ No newline at end of file diff --git a/src/tests/test_wrappers/csharp/.gitkeep b/src/tests/test_wrappers/csharp/.gitkeep deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/src/tests/test_wrappers/csharp/CMakeLists.txt b/src/tests/test_wrappers/csharp/CMakeLists.txt deleted file mode 100644 index 6322784230f45cb85e659f27035108f3008ad1c1..0000000000000000000000000000000000000000 --- a/src/tests/test_wrappers/csharp/CMakeLists.txt +++ /dev/null @@ -1,113 +0,0 @@ -cmake_minimum_required(VERSION 3.13) -project(test_csharp_wrapper CSharp) - -add_custom_command( - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/../../../wrappers/c_sharp/Class.cs - DEPENDS csharpClass -) - -add_custom_command( - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/../../../wrappers/c_sharp/csClassPINVOKE.cs - DEPENDS csharpClass -) - -add_custom_command( - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/../../../wrappers/c_sharp/VectorOfDoubles.cs - DEPENDS csharpClass -) - -add_custom_command( - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/../../../wrappers/c_sharp/VectorOfInts.cs - DEPENDS csharpClass -) - -add_custom_command( - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/../../../wrappers/c_sharp/VectorOfAcqFrames.cs - DEPENDS csharpClass -) - -add_custom_command( - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/../../../wrappers/c_sharp/VectorOfPatterns.cs - DEPENDS csharpClass -) - -add_custom_command( - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/../../../wrappers/c_sharp/AcqFrame.cs - DEPENDS csharpClass -) - -add_custom_command( - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/../../../wrappers/c_sharp/Pattern.cs - DEPENDS csharpClass -) - -add_custom_command( - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/../../../wrappers/c_sharp/ClassError.cs - DEPENDS csharpClass -) - -add_custom_command( - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/../../../wrappers/c_sharp/ClassCallback.cs - DEPENDS csharpClass -) - -add_custom_command( - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/../../../wrappers/c_sharp/VectorOfBools.cs - DEPENDS csharpClass -) - -add_executable(TestCSharpWrapperAcq TestCSharpWrapperAcq.cs - ${CMAKE_CURRENT_BINARY_DIR}/../../../wrappers/c_sharp/Class.cs - ${CMAKE_CURRENT_BINARY_DIR}/../../../wrappers/c_sharp/csClassPINVOKE.cs - ${CMAKE_CURRENT_BINARY_DIR}/../../../wrappers/c_sharp/VectorOfDoubles.cs - ${CMAKE_CURRENT_BINARY_DIR}/../../../wrappers/c_sharp/VectorOfInts.cs - ${CMAKE_CURRENT_BINARY_DIR}/../../../wrappers/c_sharp/VectorOfAcqFrames.cs - ${CMAKE_CURRENT_BINARY_DIR}/../../../wrappers/c_sharp/VectorOfPatterns.cs - ${CMAKE_CURRENT_BINARY_DIR}/../../../wrappers/c_sharp/AcqFrame.cs - ${CMAKE_CURRENT_BINARY_DIR}/../../../wrappers/c_sharp/Pattern.cs - ${CMAKE_CURRENT_BINARY_DIR}/../../../wrappers/c_sharp/ClassError.cs - ${CMAKE_CURRENT_BINARY_DIR}/../../../wrappers/c_sharp/ClassCallback.cs - ${CMAKE_CURRENT_BINARY_DIR}/../../../wrappers/c_sharp/VectorOfBools.cs) - -add_executable(TestCSharpWrapperStim TestCSharpWrapperStim.cs - ${CMAKE_CURRENT_BINARY_DIR}/../../../wrappers/c_sharp/Class.cs - ${CMAKE_CURRENT_BINARY_DIR}/../../../wrappers/c_sharp/csClassPINVOKE.cs - ${CMAKE_CURRENT_BINARY_DIR}/../../../wrappers/c_sharp/VectorOfDoubles.cs - ${CMAKE_CURRENT_BINARY_DIR}/../../../wrappers/c_sharp/VectorOfInts.cs - ${CMAKE_CURRENT_BINARY_DIR}/../../../wrappers/c_sharp/VectorOfAcqFrames.cs - ${CMAKE_CURRENT_BINARY_DIR}/../../../wrappers/c_sharp/VectorOfPatterns.cs - ${CMAKE_CURRENT_BINARY_DIR}/../../../wrappers/c_sharp/AcqFrame.cs - ${CMAKE_CURRENT_BINARY_DIR}/../../../wrappers/c_sharp/Pattern.cs - ${CMAKE_CURRENT_BINARY_DIR}/../../../wrappers/c_sharp/ClassError.cs - ${CMAKE_CURRENT_BINARY_DIR}/../../../wrappers/c_sharp/ClassCallback.cs - ${CMAKE_CURRENT_BINARY_DIR}/../../../wrappers/c_sharp/VectorOfBools.cs) - -add_executable(TestCSharpWrapperCallback TestCSharpWrapperCallback.cs - ${CMAKE_CURRENT_BINARY_DIR}/../../../wrappers/c_sharp/Class.cs - ${CMAKE_CURRENT_BINARY_DIR}/../../../wrappers/c_sharp/csClassPINVOKE.cs - ${CMAKE_CURRENT_BINARY_DIR}/../../../wrappers/c_sharp/VectorOfDoubles.cs - ${CMAKE_CURRENT_BINARY_DIR}/../../../wrappers/c_sharp/VectorOfInts.cs - ${CMAKE_CURRENT_BINARY_DIR}/../../../wrappers/c_sharp/VectorOfAcqFrames.cs - ${CMAKE_CURRENT_BINARY_DIR}/../../../wrappers/c_sharp/VectorOfPatterns.cs - ${CMAKE_CURRENT_BINARY_DIR}/../../../wrappers/c_sharp/AcqFrame.cs - ${CMAKE_CURRENT_BINARY_DIR}/../../../wrappers/c_sharp/Pattern.cs - ${CMAKE_CURRENT_BINARY_DIR}/../../../wrappers/c_sharp/ClassError.cs - ${CMAKE_CURRENT_BINARY_DIR}/../../../wrappers/c_sharp/ClassCallback.cs - ${CMAKE_CURRENT_BINARY_DIR}/../../../wrappers/c_sharp/VectorOfBools.cs) - -# copy generated dll file to bin dir -add_custom_target( - copyCSharpClass ALL - COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/../../../wrappers/c_sharp/Release/cSharpClass.dll ${CMAKE_CURRENT_BINARY_DIR}/Release/cSharpClass.dll -) -add_dependencies(copyCSharpClass csharpClass) - - -install(FILES ${CMAKE_CURRENT_BINARY_DIR}/../../../wrappers/c_sharp/Class.cs ${CMAKE_CURRENT_BINARY_DIR}/../../../wrappers/c_sharp/csClassPINVOKE.cs ${CMAKE_CURRENT_BINARY_DIR}/../../../wrappers/c_sharp/VectorOfDoubles.cs ${CMAKE_CURRENT_BINARY_DIR}/../../../wrappers/c_sharp/VectorOfInts.cs ${CMAKE_CURRENT_BINARY_DIR}/../../../wrappers/c_sharp/VectorOfAcqFrames.cs ${CMAKE_CURRENT_BINARY_DIR}/../../../wrappers/c_sharp/VectorOfPatterns.cs ${CMAKE_CURRENT_BINARY_DIR}/../../../wrappers/c_sharp/AcqFrame.cs ${CMAKE_CURRENT_BINARY_DIR}/../../../wrappers/c_sharp/Pattern.cs ${CMAKE_CURRENT_BINARY_DIR}/../../../wrappers/c_sharp/ClassError.cs ${CMAKE_CURRENT_BINARY_DIR}/../../../wrappers/c_sharp/ClassCallback.cs ${CMAKE_CURRENT_BINARY_DIR}/../../../wrappers/c_sharp/VectorOfBools.cs DESTINATION class_api/lib/csharp) -install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/TestCSharpWrapperAcq.cs ${CMAKE_CURRENT_SOURCE_DIR}/TestCSharpWrapperStim.cs ${CMAKE_CURRENT_SOURCE_DIR}/TestCSharpWrapperCallback.cs DESTINATION class_api/examples/src/csharp) -install(TARGETS TestCSharpWrapperAcq TestCSharpWrapperStim TestCSharpWrapperCallback - RUNTIME DESTINATION class_api/examples/bin/csharp) -install (FILES ${CMAKE_CURRENT_SOURCE_DIR}/test_csharp_wrapper_acq.bat DESTINATION class_api/examples/bin/csharp) -install (FILES ${CMAKE_CURRENT_SOURCE_DIR}/test_csharp_wrapper_stim.bat DESTINATION class_api/examples/bin/csharp) -install (FILES ${CMAKE_CURRENT_SOURCE_DIR}/test_csharp_wrapper_callback.bat DESTINATION class_api/examples/bin/csharp) -install (FILES ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists_install.txt DESTINATION class_api/examples/src/csharp RENAME CMakeLists.txt) \ No newline at end of file diff --git a/src/tests/test_wrappers/csharp/CMakeLists_install.txt b/src/tests/test_wrappers/csharp/CMakeLists_install.txt deleted file mode 100644 index 7d1cfb9b3795e30504a167df06882ad67b464817..0000000000000000000000000000000000000000 --- a/src/tests/test_wrappers/csharp/CMakeLists_install.txt +++ /dev/null @@ -1,43 +0,0 @@ -cmake_minimum_required(VERSION 3.13) -project(test_csharp_wrapper CSharp) - -if (WIN32) - add_executable(TestCSharpWrapperAcq TestCSharpWrapperAcq.cs - ${CMAKE_CURRENT_SOURCE_DIR}/../../../lib/csharp/Class.cs - ${CMAKE_CURRENT_SOURCE_DIR}/../../../lib/csharp/csClassPINVOKE.cs - ${CMAKE_CURRENT_SOURCE_DIR}/../../../lib/csharp/VectorOfDoubles.cs - ${CMAKE_CURRENT_SOURCE_DIR}/../../../lib/csharp/VectorOfInts.cs - ${CMAKE_CURRENT_SOURCE_DIR}/../../../lib/csharp/VectorOfAcqFrames.cs - ${CMAKE_CURRENT_SOURCE_DIR}/../../../lib/csharp/VectorOfPatterns.cs - ${CMAKE_CURRENT_SOURCE_DIR}/../../../lib/csharp/AcqFrame.cs - ${CMAKE_CURRENT_SOURCE_DIR}/../../../lib/csharp/Pattern.cs - ${CMAKE_CURRENT_SOURCE_DIR}/../../../lib/csharp/ClassError.cs - ${CMAKE_CURRENT_SOURCE_DIR}/../../../lib/csharp/ClassCallback.cs - ${CMAKE_CURRENT_SOURCE_DIR}/../../../lib/csharp/VectorOfBools.cs) - - add_executable(TestCSharpWrapperStim TestCSharpWrapperStim.cs - ${CMAKE_CURRENT_SOURCE_DIR}/../../../lib/csharp/Class.cs - ${CMAKE_CURRENT_SOURCE_DIR}/../../../lib/csharp/csClassPINVOKE.cs - ${CMAKE_CURRENT_SOURCE_DIR}/../../../lib/csharp/VectorOfDoubles.cs - ${CMAKE_CURRENT_SOURCE_DIR}/../../../lib/csharp/VectorOfInts.cs - ${CMAKE_CURRENT_SOURCE_DIR}/../../../lib/csharp/VectorOfAcqFrames.cs - ${CMAKE_CURRENT_SOURCE_DIR}/../../../lib/csharp/VectorOfPatterns.cs - ${CMAKE_CURRENT_SOURCE_DIR}/../../../lib/csharp/AcqFrame.cs - ${CMAKE_CURRENT_SOURCE_DIR}/../../../lib/csharp/Pattern.cs - ${CMAKE_CURRENT_SOURCE_DIR}/../../../lib/csharp/ClassError.cs - ${CMAKE_CURRENT_SOURCE_DIR}/../../../lib/csharp/ClassCallback.cs - ${CMAKE_CURRENT_SOURCE_DIR}/../../../lib/csharp/VectorOfBools.cs) - - add_executable(TestCSharpWrapperCallback TestCSharpWrapperCallback.cs - ${CMAKE_CURRENT_SOURCE_DIR}/../../../lib/csharp/Class.cs - ${CMAKE_CURRENT_SOURCE_DIR}/../../../lib/csharp/csClassPINVOKE.cs - ${CMAKE_CURRENT_SOURCE_DIR}/../../../lib/csharp/VectorOfDoubles.cs - ${CMAKE_CURRENT_SOURCE_DIR}/../../../lib/csharp/VectorOfInts.cs - ${CMAKE_CURRENT_SOURCE_DIR}/../../../lib/csharp/VectorOfAcqFrames.cs - ${CMAKE_CURRENT_SOURCE_DIR}/../../../lib/csharp/VectorOfPatterns.cs - ${CMAKE_CURRENT_SOURCE_DIR}/../../../lib/csharp/AcqFrame.cs - ${CMAKE_CURRENT_SOURCE_DIR}/../../../lib/csharp/Pattern.cs - ${CMAKE_CURRENT_SOURCE_DIR}/../../../lib/csharp/ClassError.cs - ${CMAKE_CURRENT_SOURCE_DIR}/../../../lib/csharp/ClassCallback.cs - ${CMAKE_CURRENT_SOURCE_DIR}/../../../lib/csharp/VectorOfBools.cs) -endif (WIN32) diff --git a/src/tests/test_wrappers/csharp/TestCSharpWrapperAcq.cs b/src/tests/test_wrappers/csharp/TestCSharpWrapperAcq.cs deleted file mode 100644 index a198debd39a57e31260846ea7d7eacad33dce659..0000000000000000000000000000000000000000 --- a/src/tests/test_wrappers/csharp/TestCSharpWrapperAcq.cs +++ /dev/null @@ -1,128 +0,0 @@ -/** - * @file TestCSharpWrapperAcq.cs - * @author Alfonso Dominguez <alfonso.dominguez@tecnalia.com> - * @date 2020 - * - * Copyright 2020 Tecnalia Research & Innovation. - * - * @brief Example of use of CLASS_API for acquisition in c# - */ - -using System; -using System.Threading; -using System.Runtime.InteropServices; - -class TestCSharpWrapperAcq -{ - static void Main(string[] args) - { - //'.' instead of ',' for string containing double - System.Globalization.CultureInfo customCulture = (System.Globalization.CultureInfo)System.Threading.Thread.CurrentThread.CurrentCulture.Clone(); - customCulture.NumberFormat.NumberDecimalSeparator = "."; - System.Threading.Thread.CurrentThread.CurrentCulture = customCulture; - - Console.WriteLine("[TestAcq] Connect"); - Class classDevice = new Class(); - ClassError.Error response = classDevice.connect(); - if(response != ClassError.Error.CLASS_NO_ERROR) - { - Environment.Exit(-1); - } - - int loop_number = 0; - - Console.WriteLine("[TestAcq] Configuring CLASS"); - - classDevice.initCommunication(); - VectorOfInts channels = new VectorOfInts(); - //get acq from channel 1 and 4 - channels.Add(1); - channels.Add(4); - classDevice.setAcqConfig(Class.AcqFreq.FREQ_250, channels, Class.AcqGain.GAIN_24, Class.AcqInput.NORMAL); - classDevice.startAcqStream(); - - Console.WriteLine("[TestAcq] Start acquisition"); - classDevice.startAcq(); - Console.WriteLine("[TestAcq] Wait 20 seconds"); - while (loop_number < 20) - { - try - { - var acqFrames = classDevice.getAcqFrames(); - int i = 0; - foreach (var frame in acqFrames) - { - string channelsString = ""; - AcqFrame acqFrame = frame; - int j = 1; - foreach (var channel in acqFrame.values) - { - channelsString += ", ch" + j + ": " + string.Format("{0:0.0000}", (double)channel) + "(uV)"; - j += 1; - } - Console.WriteLine("[TestAcq] Frame " + i + ": Timestamp: " + string.Format("{0:0.0000}", acqFrame.timestamp) + "(ms)" + channelsString) ; - i += 1; - } - } - catch (System.Exception ex) - { - Console.WriteLine("[TestAcq] Exception: " + ex.ToString()); - } - - Thread.Sleep(1000); - loop_number += 1; - Console.WriteLine(loop_number + " second(s)"); - } - Console.WriteLine("[TestAcq] Stop acquisition"); - classDevice.stopAcq(); - - Thread.Sleep(1000); - - classDevice.setAcqImpedanceConfig(Class.AcqImpedanceSign.TYPE_POSITIVE); - classDevice.setAcqImpedancePolarity(Class.AcqImpedancePolarity.TYPE_UNIPOLAR); - - Console.WriteLine("[TestAcq] Start impedance acquisition"); - classDevice.startAcqStream(); - classDevice.startImpedanceAcq(); - Console.WriteLine("[TestAcq] Wait 20 seconds"); - loop_number = 0; - while (loop_number < 20) - { - try - { - var acqFrames = classDevice.getAcqFrames(); - int i = 0; - foreach (var frame in acqFrames) - { - string channelsString = ""; - AcqFrame acqFrame = frame; - int j = 1; - foreach (var channel in acqFrame.values) - { - channelsString += ", ch" + j + ": " + string.Format("{0:0.0000}", channel) + "(ohm)"; - j += 1; - } - Console.WriteLine("[TestAcq] Frame " + i + ": Timestamp: " + string.Format("{0:0.0000}", acqFrame.timestamp) + "(ms)" + channelsString) ; - i += 1; - } - } - catch (System.Exception ex) - { - Console.WriteLine("[TestAcq] Exception: " + ex.ToString()); - } - - Thread.Sleep(1000); - loop_number += 1; - Console.WriteLine(loop_number + " second(s)"); - } - Console.WriteLine("[TestAcq] Stop impedance acquisition"); - classDevice.stopImpedanceAcq(); - - Console.WriteLine("[TestAcq] Disconnect"); - response = classDevice.disconnect(); - if(response != ClassError.Error.CLASS_NO_ERROR) - { - Environment.Exit(-1); - } - } -} \ No newline at end of file diff --git a/src/tests/test_wrappers/csharp/TestCSharpWrapperCallback.cs b/src/tests/test_wrappers/csharp/TestCSharpWrapperCallback.cs deleted file mode 100644 index 422622f067e0059ba58054aadfa335a7f8bf55ef..0000000000000000000000000000000000000000 --- a/src/tests/test_wrappers/csharp/TestCSharpWrapperCallback.cs +++ /dev/null @@ -1,86 +0,0 @@ -/** - * @file TestCSharpWrapperCallback.cs - * @author Alfonso Dominguez <alfonso.dominguez@tecnalia.com> - * @date 2020 - * - * Copyright 2020 Tecnalia Research & Innovation. - * - * @brief Example of use of CLASS_API in c# - */ - -using System; -using System.Threading; -using System.Runtime.InteropServices; - -class TestCSharpWrapperCallback : ClassCallback -{ - static bool turnOff = false; - public override void batteryHandle(double battery) - { - System.Console.WriteLine("[TestCB] Battery received: " + battery); - } - - public override void firmwareHandle(string firmware) - { - System.Console.WriteLine("[TestCB] firmware received: " + firmware); - } - - public override void hardwareHandle(string hardware) - { - System.Console.WriteLine("[TestCB] hardware received: " + hardware); - } - - public override void ticHandle(string tic) - { - System.Console.WriteLine("[TestCB] tic received: " + tic); - } - - public override void turnOffHandle() - { - System.Console.WriteLine("[TestCB] Turn off received"); - turnOff = true; - } - - static void Main(string[] args) - { - TestCSharpWrapperCallback test = new TestCSharpWrapperCallback(); - Console.WriteLine("[TestCB] Connect"); - Class classDevice = new Class(); - ClassError.Error response = classDevice.connect(); - if(response != ClassError.Error.CLASS_NO_ERROR) - { - Environment.Exit(-1); - } - - int loop_number = 0; - - Console.WriteLine("[TestCB] Configuring CLASS"); - classDevice.initCommunication(); - - Console.WriteLine("[TestCB] Set callback"); - if(classDevice.setCallback(test, "csharp") == ClassError.Error.CLASS_NO_ERROR) - { - Console.WriteLine("[TestCB] Get Battery. Wait 20 secs"); - loop_number = 0; - while (loop_number < 20 && !turnOff) - { - classDevice.getBattery(); - Thread.Sleep(1000); - loop_number += 1; - Console.WriteLine("[TestCB] Waiting... " + loop_number + " second(s)"); - } - Console.WriteLine("[TestCB] Stop getting battery"); - } - else - { - Console.WriteLine("[TestCB] Error setting callback"); - } - - Console.WriteLine("[TestCB] Disconnect"); - response = classDevice.disconnect(); - if(response != ClassError.Error.CLASS_NO_ERROR) - { - Environment.Exit(-1); - } - } -} \ No newline at end of file diff --git a/src/tests/test_wrappers/csharp/TestCSharpWrapperStim.cs b/src/tests/test_wrappers/csharp/TestCSharpWrapperStim.cs deleted file mode 100644 index d823b4190c28a974036dd45dd6021a45c6c0cab3..0000000000000000000000000000000000000000 --- a/src/tests/test_wrappers/csharp/TestCSharpWrapperStim.cs +++ /dev/null @@ -1,66 +0,0 @@ -/** - * @file TestCSharpWrapperStim.cs - * @author Alfonso Dominguez <alfonso.dominguez@tecnalia.com> - * @date 2020 - * - * Copyright 2020 Tecnalia Research & Innovation. - * - * @brief Example of use of CLASS_API for Stimulation in c# - */ - -using System; -using System.Threading; -using System.Runtime.InteropServices; - -class TestCSharpWrapperStim -{ - static void Main(string[] args) - { - Console.WriteLine("[TestStim] Connect"); - Class classDevice = new Class(); - ClassError.Error response = classDevice.connect(); - if(response != ClassError.Error.CLASS_NO_ERROR) - { - Environment.Exit(-1); - } - - int loop_number = 0; - - Console.WriteLine("[TestStim] Configuring CLASS"); - classDevice.initCommunication(); - - Console.WriteLine("[TestStim] Create electrode 1. Set number of pads in electrode 1 to 32"); - classDevice.setElecPads(1, 32); - Console.WriteLine("[TestStim] Set frequency of stimulation to 35Hz"); - classDevice.setStimFreq(35.0); - Console.WriteLine("[TestStim] Create virtual electrode for thumb. Its ID is 10. One cathode in pad 7. One anode in pad 4. Amp set to 2,5. Width to 400. Selected. Not sync"); - VectorOfInts cathodes = new VectorOfInts(); - cathodes.Add(4); - VectorOfInts anodes = new VectorOfInts(); - anodes.Add(7); - VectorOfDoubles amp = new VectorOfDoubles(); - amp.Add(2.5); - VectorOfInts width = new VectorOfInts(); - width.Add(400); - classDevice.setVelec(10, "thumb", 1, cathodes, anodes, amp, width, true, false); - Console.WriteLine("[TestStim] Start stimulation"); - classDevice.startStim(); - Console.WriteLine("[TestStim] Stimulate 20 seconds"); - loop_number = 0; - while (loop_number < 20) - { - Thread.Sleep(1000); - loop_number += 1; - Console.WriteLine("[TestStim] Stimulating... " + loop_number + " second(s)"); - } - Console.WriteLine("[TestStim] Stop stimulation"); - classDevice.stopStim(); - - Console.WriteLine("[TestStim] Disconnect"); - response = classDevice.disconnect(); - if(response != ClassError.Error.CLASS_NO_ERROR) - { - Environment.Exit(-1); - } - } -} \ No newline at end of file diff --git a/src/tests/test_wrappers/csharp/test_csharp_wrapper_acq.bat b/src/tests/test_wrappers/csharp/test_csharp_wrapper_acq.bat deleted file mode 100644 index b2efba83e68184b51e5819e2e3fdffdf4340659f..0000000000000000000000000000000000000000 --- a/src/tests/test_wrappers/csharp/test_csharp_wrapper_acq.bat +++ /dev/null @@ -1,3 +0,0 @@ -set CLASS_LIB_PATH=..\..\..\lib\csharp;..\..\..\lib\cpp -echo %PATH%|find /i "%CLASS_LIB_PATH:"=%">nul || set PATH=%CLASS_LIB_PATH%;%PATH% -TestCSharpWrapperAcq.exe \ No newline at end of file diff --git a/src/tests/test_wrappers/csharp/test_csharp_wrapper_callback.bat b/src/tests/test_wrappers/csharp/test_csharp_wrapper_callback.bat deleted file mode 100644 index 491eac80c49ebb17826e18aa112c56cec8744f45..0000000000000000000000000000000000000000 --- a/src/tests/test_wrappers/csharp/test_csharp_wrapper_callback.bat +++ /dev/null @@ -1,3 +0,0 @@ -set CLASS_LIB_PATH=..\..\..\lib\csharp;..\..\..\lib\cpp -echo %PATH%|find /i "%CLASS_LIB_PATH:"=%">nul || set PATH=%CLASS_LIB_PATH%;%PATH% -TestCSharpWrapperCallback.exe \ No newline at end of file diff --git a/src/tests/test_wrappers/csharp/test_csharp_wrapper_stim.bat b/src/tests/test_wrappers/csharp/test_csharp_wrapper_stim.bat deleted file mode 100644 index 7c8c24e5faf2e2d8477949263ffe9d5c8835a884..0000000000000000000000000000000000000000 --- a/src/tests/test_wrappers/csharp/test_csharp_wrapper_stim.bat +++ /dev/null @@ -1,3 +0,0 @@ -set CLASS_LIB_PATH=..\..\..\lib\csharp;..\..\..\lib\cpp -echo %PATH%|find /i "%CLASS_LIB_PATH:"=%">nul || set PATH=%CLASS_LIB_PATH%;%PATH% -TestCSharpWrapperStim.exe \ No newline at end of file diff --git a/src/tests/test_wrappers/python/.gitkeep b/src/tests/test_wrappers/python/.gitkeep deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/src/tests/test_wrappers/python/CMakeLists.txt b/src/tests/test_wrappers/python/CMakeLists.txt deleted file mode 100644 index ec0d5554ac2c7fca86f881cb25ec8cdf3613f26d..0000000000000000000000000000000000000000 --- a/src/tests/test_wrappers/python/CMakeLists.txt +++ /dev/null @@ -1,40 +0,0 @@ -cmake_minimum_required(VERSION 3.13) -project(test_python_wrapper) - -find_package(Python REQUIRED COMPONENTS Interpreter) - -# copy src script to bin dir -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/test_python_wrapper_acq.py - ${CMAKE_CURRENT_BINARY_DIR} - COPYONLY) - -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/test_python_wrapper_stim.py - ${CMAKE_CURRENT_BINARY_DIR} - COPYONLY) - -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/test_python_wrapper_callback.py - ${CMAKE_CURRENT_BINARY_DIR} - COPYONLY) - -# copy generated file pyClass.py to bin dir -add_custom_target( - copyPyClass ALL - COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/../../../wrappers/python/pyClass.py ${CMAKE_CURRENT_BINARY_DIR} -) -add_dependencies(copyPyClass pyClass) - -install(FILES ${CMAKE_CURRENT_BINARY_DIR}/../../../wrappers/python/pyClass.py DESTINATION class_api/lib/python) -install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/test_python_wrapper_acq.py DESTINATION class_api/examples/src/python) -install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/test_python_wrapper_stim.py DESTINATION class_api/examples/src/python) -install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/test_python_wrapper_callback.py DESTINATION class_api/examples/src/python) -if (WIN32) - install (FILES ${CMAKE_CURRENT_SOURCE_DIR}/test_python_wrapper_acq.bat DESTINATION class_api/examples/bin/python) - install (FILES ${CMAKE_CURRENT_SOURCE_DIR}/test_python_wrapper_stim.bat DESTINATION class_api/examples/bin/python) - install (FILES ${CMAKE_CURRENT_SOURCE_DIR}/test_python_wrapper_callback.bat DESTINATION class_api/examples/bin/python) -endif (WIN32) - -if (UNIX) - install (FILES ${CMAKE_CURRENT_SOURCE_DIR}/test_python_wrapper_acq.sh DESTINATION class_api/examples/bin/python) - install (FILES ${CMAKE_CURRENT_SOURCE_DIR}/test_python_wrapper_stim.sh DESTINATION class_api/examples/bin/python) - install (FILES ${CMAKE_CURRENT_SOURCE_DIR}/test_python_wrapper_callback.sh DESTINATION class_api/examples/bin/python) -endif (UNIX) \ No newline at end of file diff --git a/src/tests/test_wrappers/python/test_python_wrapper_acq.bat b/src/tests/test_wrappers/python/test_python_wrapper_acq.bat deleted file mode 100644 index 7d836b5526d1d7934600902e7faacb76cb130612..0000000000000000000000000000000000000000 --- a/src/tests/test_wrappers/python/test_python_wrapper_acq.bat +++ /dev/null @@ -1,7 +0,0 @@ -set CLASS_PYTHON_LIB_PATH=..\..\..\lib\python -set CLASS_CPP_LIB_PATH=..\..\..\lib\cpp - -echo %PYTHONPATH%|find /i "%CLASS_PYTHON_LIB_PATH:"=%">nul || set PYTHONPATH=%PYTHONPATH%;%CLASS_PYTHON_LIB_PATH% -echo %PATH%|find /i "%CLASS_CPP_LIB_PATH:"=%">nul || set PATH=%CLASS_CPP_LIB_PATH%;%PATH% - -python ..\..\src\python\test_python_wrapper_acq.py \ No newline at end of file diff --git a/src/tests/test_wrappers/python/test_python_wrapper_acq.py b/src/tests/test_wrappers/python/test_python_wrapper_acq.py deleted file mode 100644 index 9ea316f291990f23d4ad79d14c08ec9e6820f289..0000000000000000000000000000000000000000 --- a/src/tests/test_wrappers/python/test_python_wrapper_acq.py +++ /dev/null @@ -1,68 +0,0 @@ -"""Example of use of CLASS_API in Python for acquisition""" -__author__ = "Alfonso Dominguez" -__email__ = "alfonso.dominguez@tecnalia.com" -__copyright__ = "Copyright (C) 2020 Tecnalia Research and Innovation" - - -import sys -import time - -from pyClass import Class, VectorOfInts, VectorOfDoubles - -def test(): - """ - Run tests - :return: - """ - class_device = Class() - print("[TestAcq] Connect") - class_device.connect() - - print("[TestAcq] Configuring CLASS") - class_device.initCommunication() - channels = VectorOfInts() - channels.append(1) - channels.append(4) - class_device.setAcqConfig(Class.FREQ_250, channels, Class.GAIN_24, Class.NORMAL) - class_device.startAcqStream() - - print("[TestAcq] Start acquisition") - class_device.startAcq() - print("[TestAcq] Wait 20 seconds") - for loop_number in range (20): - acq_frames = class_device.getAcqFrames() - for i in range(acq_frames.size()): - channelsString = '' - for j in range(acq_frames[i].values.size()): - channelsString += ", ch" + str(j+1) + ": " + "{:.4f}".format(acq_frames[i].values[j]).replace(',', '.') + "(uV)" - print('Frame ' + str(i) + ': Timestamp: ' + "{:.4f}".format(acq_frames[i].timestamp).replace(',', '.') + "(ms)" + channelsString) - time.sleep(1.0) - print(str(loop_number+1) + " second(s)") - print("[TestAcq] Stop acquisition") - class_device.stopAcq() - - time.sleep(1.0) - - class_device.setAcqImpedanceConfig(Class.TYPE_POSITIVE) - class_device.startAcqStream() - print("[TestAcq] Start impedance acquisition") - class_device.startImpedanceAcq() - print("[TestAcq] Wait 20 seconds") - for loop_number in range (20): - acq_frames = class_device.getAcqFrames() - for i in range(acq_frames.size()): - channelsString = '' - for j in range(acq_frames[i].values.size()): - channelsString += ", ch" + str(j+1) + ": " + "{:.4f}".format(acq_frames[i].values[j]).replace(',', '.') + "(ohm)" - print('Frame ' + str(i) + ': Timestamp: ' + "{:.4f}".format(acq_frames[i].timestamp).replace(',', '.') + "(ms)" + channelsString) - time.sleep(1.0) - print(str(loop_number+1) + " second(s)") - print("[TestAcq] Stop impedance acquisition") - class_device.stopAcq() - - print("[TestAcq] Disconnect") - class_device.disconnect() - - -if __name__ == '__main__': - test() \ No newline at end of file diff --git a/src/tests/test_wrappers/python/test_python_wrapper_acq.sh b/src/tests/test_wrappers/python/test_python_wrapper_acq.sh deleted file mode 100644 index 4ca214c35a6737fb34c47f320481361f04b2d75b..0000000000000000000000000000000000000000 --- a/src/tests/test_wrappers/python/test_python_wrapper_acq.sh +++ /dev/null @@ -1,2 +0,0 @@ -export PYTHONPATH=$PYTHONPATH:../../../lib/python -python ../../src/python/test_python_wrapper_acq.py \ No newline at end of file diff --git a/src/tests/test_wrappers/python/test_python_wrapper_callback.bat b/src/tests/test_wrappers/python/test_python_wrapper_callback.bat deleted file mode 100644 index 031e2006625c733d5d5c429d90ac6951d387b8a7..0000000000000000000000000000000000000000 --- a/src/tests/test_wrappers/python/test_python_wrapper_callback.bat +++ /dev/null @@ -1,7 +0,0 @@ -set CLASS_PYTHON_LIB_PATH=..\..\..\lib\python -set CLASS_CPP_LIB_PATH=..\..\..\lib\cpp - -echo %PYTHONPATH%|find /i "%CLASS_PYTHON_LIB_PATH:"=%">nul || set PYTHONPATH=%PYTHONPATH%;%CLASS_PYTHON_LIB_PATH% -echo %PATH%|find /i "%CLASS_CPP_LIB_PATH:"=%">nul || set PATH=%CLASS_CPP_LIB_PATH%;%PATH% - -python ..\..\src\python\test_python_wrapper_callback.py \ No newline at end of file diff --git a/src/tests/test_wrappers/python/test_python_wrapper_callback.py b/src/tests/test_wrappers/python/test_python_wrapper_callback.py deleted file mode 100644 index ab1e47088bbb3db3bbfc02828eb96cf5d949b060..0000000000000000000000000000000000000000 --- a/src/tests/test_wrappers/python/test_python_wrapper_callback.py +++ /dev/null @@ -1,57 +0,0 @@ -"""Example of use of CLASS_API in Python for callback""" -__author__ = "Alfonso Dominguez" -__email__ = "alfonso.dominguez@tecnalia.com" -__copyright__ = "Copyright (C) 2020 Tecnalia Research and Innovation" - - -import sys -import time -import types -import threading - -from pyClass import Class, VectorOfInts, VectorOfDoubles, ClassCallback - -class Test(ClassCallback): - turn_off = False - - def batteryHandle(self, battery): - print("[TestCB] Battery received: " + str(battery)) - - def ticHandle(self, tic): - print("[TestCB] tic received: " + tic) - - def turnOffHandle(self): - print("[TestCB] TurnOff received") - self.turn_off = True - - def test(self): - """ - Run tests - :return: - """ - class_device = Class() - print("[TestCB] Connect") - class_device.connect() - print("[TestCB] Configuring CLASS") - class_device.initCommunication() - - print("[TestCB] Set callback") - self.__disown__ = 0 - class_device.setCallback(self, "python") - - print("[TestCB] Get battery. Wait 20 seconds") - loop_number = 0 - while loop_number < 20 and not self.turn_off: - class_device.getBattery() - time.sleep(1.0) - loop_number +=1 - print("[TestCB] Waiting..." + str(loop_number+1) + " second(s)") - print("[TestCB] Stop getting battery") - - print("[TestCB] Disconnect") - class_device.disconnect() - - -if __name__ == '__main__': - t = Test() - t.test() \ No newline at end of file diff --git a/src/tests/test_wrappers/python/test_python_wrapper_callback.sh b/src/tests/test_wrappers/python/test_python_wrapper_callback.sh deleted file mode 100644 index e8f5e3662ceb1ec34b677c82d5ed9995979d6a54..0000000000000000000000000000000000000000 --- a/src/tests/test_wrappers/python/test_python_wrapper_callback.sh +++ /dev/null @@ -1,2 +0,0 @@ -export PYTHONPATH=$PYTHONPATH:../../../lib/python -python ../../src/python/test_python_wrapper_callback.py \ No newline at end of file diff --git a/src/tests/test_wrappers/python/test_python_wrapper_stim.bat b/src/tests/test_wrappers/python/test_python_wrapper_stim.bat deleted file mode 100644 index fe2e5dbd6a010fb33b581199e54acfb2bb7cad71..0000000000000000000000000000000000000000 --- a/src/tests/test_wrappers/python/test_python_wrapper_stim.bat +++ /dev/null @@ -1,7 +0,0 @@ -set CLASS_PYTHON_LIB_PATH=..\..\..\lib\python -set CLASS_CPP_LIB_PATH=..\..\..\lib\cpp - -echo %PYTHONPATH%|find /i "%CLASS_PYTHON_LIB_PATH:"=%">nul || set PYTHONPATH=%PYTHONPATH%;%CLASS_PYTHON_LIB_PATH% -echo %PATH%|find /i "%CLASS_CPP_LIB_PATH:"=%">nul || set PATH=%CLASS_CPP_LIB_PATH%;%PATH% - -python ..\..\src\python\test_python_wrapper_stim.py \ No newline at end of file diff --git a/src/tests/test_wrappers/python/test_python_wrapper_stim.py b/src/tests/test_wrappers/python/test_python_wrapper_stim.py deleted file mode 100644 index ff1b27cdb78592b4359f806c660f4cd37261b5ae..0000000000000000000000000000000000000000 --- a/src/tests/test_wrappers/python/test_python_wrapper_stim.py +++ /dev/null @@ -1,54 +0,0 @@ -"""Example of use of CLASS_API in Python for stimulation""" -__author__ = "Alfonso Dominguez" -__email__ = "alfonso.dominguez@tecnalia.com" -__copyright__ = "Copyright (C) 2020 Tecnalia Research and Innovation" - - -import sys -import time - -from pyClass import Class, VectorOfInts, VectorOfDoubles - -def test(): - """ - Run tests - :return: - """ - class_device = Class() - print("[TestStim] Connect") - class_device.connect() - print("[TestStim] Configuring CLASS") - class_device.initCommunication() - - print("[TestStim] Create electrode 1. Set number of pads in electrode 1 to 32") - class_device.setElecPads(1, 32) - print("[TestStim] Set frequency of stimulation to 35Hz") - class_device.setStimFreq(35.0) - print("[TestStim] Create virtual electrode for thumb. Its ID is 10. One cathode in pad 7. One anode in pad 4. Amp set to 2,5. Width to 400. Selected. Not sync") - cathodes = VectorOfInts() - cathodes.append(4) - anodes = VectorOfInts() - anodes.append(7) - amp = VectorOfDoubles() - amp.append(2.5) - width = VectorOfInts() - width.append(400) - class_device.setVelec(10, "thumb", 1, cathodes, anodes, amp, width, True, False) - print("[TestStim] Start stimulation") - class_device.startStim() - print("[TestStim] Stimulate 20 seconds") - loop_number = 0 - while loop_number < 20: - time.sleep(1.0) - loop_number += 1 - print("[TestStim] Stimulating... " + str(loop_number) + " second(s)") - print("[TestStim] Stop stimulation") - class_device.stopStim() - - print("[TestStim] Disconnect") - - class_device.disconnect() - - -if __name__ == '__main__': - test() \ No newline at end of file diff --git a/src/tests/test_wrappers/python/test_python_wrapper_stim.sh b/src/tests/test_wrappers/python/test_python_wrapper_stim.sh deleted file mode 100644 index 757c6f519cedd6a384bfc1e5efc35af8752a468a..0000000000000000000000000000000000000000 --- a/src/tests/test_wrappers/python/test_python_wrapper_stim.sh +++ /dev/null @@ -1,2 +0,0 @@ -export PYTHONPATH=$PYTHONPATH:../../../lib/python -python ../../src/python/test_python_wrapper_stim.py \ No newline at end of file diff --git a/src/wrappers/.gitkeep b/src/wrappers/.gitkeep deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/src/wrappers/CMakeLists.txt b/src/wrappers/CMakeLists.txt deleted file mode 100644 index 25636ff2e2457a9d5ebc44944897e8a82d09f123..0000000000000000000000000000000000000000 --- a/src/wrappers/CMakeLists.txt +++ /dev/null @@ -1,18 +0,0 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 3.14) -project (wrappers) - -find_package(SWIG) -include(${SWIG_USE_FILE}) - -message(STATUS "Build Python: ${BUILD_PYTHON}") -message(STATUS "Build .Net: ${BUILD_DOTNET}") - -#if(BUILD_PYTHON) -# add_subdirectory(python) -#endif() - -if(BUILD_DOTNET) - add_subdirectory(c_sharp) -endif() - -install (FILES ${CMAKE_CURRENT_SOURCE_DIR}/sw_arch.png DESTINATION ${CMAKE_BINARY_DIR}) \ No newline at end of file diff --git a/src/wrappers/c_sharp/.gitkeep b/src/wrappers/c_sharp/.gitkeep deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/src/wrappers/c_sharp/CMakeLists.txt b/src/wrappers/c_sharp/CMakeLists.txt deleted file mode 100644 index c82839abea8580fa93c13bbca774c81a7c41db46..0000000000000000000000000000000000000000 --- a/src/wrappers/c_sharp/CMakeLists.txt +++ /dev/null @@ -1,15 +0,0 @@ -cmake_minimum_required(VERSION 3.14) -project(csharpClass) - -set_property(SOURCE class.i PROPERTY CPLUSPLUS ON) - -swig_add_library(${PROJECT_NAME} LANGUAGE csharp SOURCES class.i) - -swig_link_libraries(${PROJECT_NAME} class) -set_target_properties(${PROJECT_NAME} PROPERTIES SWIG_USE_TARGET_INCLUDE_DIRECTORIES TRUE) - -# 'make install' to the correct location -install(TARGETS ${PROJECT_NAME} - ARCHIVE DESTINATION class_api/lib/csharp - LIBRARY DESTINATION class_api/lib/csharp - RUNTIME DESTINATION class_api/bin/csharp) \ No newline at end of file diff --git a/src/wrappers/c_sharp/class.i b/src/wrappers/c_sharp/class.i deleted file mode 100644 index b63f1765f5567506ed5faef811f5a73b8a4688e2..0000000000000000000000000000000000000000 --- a/src/wrappers/c_sharp/class.i +++ /dev/null @@ -1,27 +0,0 @@ -%module (directors="1") csClass - -%include "std_string.i" -%include "std_vector.i" - -%template(VectorOfDoubles) std::vector<double>; -%template(VectorOfInts) std::vector<int>; -%template(VectorOfBools) std::vector<bool>; - -%feature("director") ClassCallback; - -#define CLASS_EXPORT - -%{ -#include "../../api/class/include/class/class.hpp" -#include "../../api/class/include/class/class_structures.hpp" -#include "../../api/class/include/class/class_error.hpp" -#include "../../api/class/include/class/class_cb.hpp" -%} - -%include "../../api/class/include/class/class.hpp" -%include "../../api/class/include/class/class_structures.hpp" -%include "../../api/class/include/class/class_error.hpp" -%include "../../api/class/include/class/class_cb.hpp" - -%template(VectorOfAcqFrames) std::vector<AcqFrame>; -%template(VectorOfPatterns) std::vector<Pattern>; \ No newline at end of file diff --git a/src/wrappers/python/.gitkeep b/src/wrappers/python/.gitkeep deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/src/wrappers/python/CMakeLists.txt b/src/wrappers/python/CMakeLists.txt deleted file mode 100644 index bd6b72f9b9393fb4cf4d2de290199312f11d7520..0000000000000000000000000000000000000000 --- a/src/wrappers/python/CMakeLists.txt +++ /dev/null @@ -1,21 +0,0 @@ -cmake_minimum_required(VERSION 3.14) -project(pyClass) - -find_package(PythonLibs REQUIRED) - -include_directories(${PYTHON_INCLUDE_DIRS}) - -set_property(SOURCE class.i PROPERTY CPLUSPLUS ON) - -swig_add_library(${PROJECT_NAME} LANGUAGE python SOURCES class.i) - -message(STATUS "PYTHON_LIBRARIES = ${PYTHON_LIBRARIES}") - -swig_link_libraries(${PROJECT_NAME} class ${PYTHON_LIBRARIES}) -set_target_properties(${PROJECT_NAME} PROPERTIES SWIG_USE_TARGET_INCLUDE_DIRECTORIES TRUE) - -# 'make install' to the correct location -install(TARGETS ${PROJECT_NAME} - ARCHIVE DESTINATION class_api/lib/python - LIBRARY DESTINATION class_api/lib/python - RUNTIME DESTINATION class_api/bin/python) \ No newline at end of file diff --git a/src/wrappers/python/class.i b/src/wrappers/python/class.i deleted file mode 100644 index 913eedad2ee77c4facea568a310ddf4bf07816f0..0000000000000000000000000000000000000000 --- a/src/wrappers/python/class.i +++ /dev/null @@ -1,28 +0,0 @@ -%module (directors="1") pyClass - -%include "std_string.i" -%include "std_vector.i" - -%template(VectorOfDoubles) std::vector<double>; -%template(VectorOfInts) std::vector<int>; - -%template(VectorOfBools) std::vector<bool>; - -%feature("director") ClassCallback; - -#define CLASS_EXPORT - -%{ -#include "../../api/class/include/class/class.hpp" -#include "../../api/class/include/class/class_structures.hpp" -#include "../../api/class/include/class/class_error.hpp" -#include "../../api/class/include/class/class_cb.hpp" -%} - -%include "../../api/class/include/class/class.hpp" -%include "../../api/class/include/class/class_structures.hpp" -%include "../../api/class/include/class/class_error.hpp" -%include "../../api/class/include/class/class_cb.hpp" - -%template(VectorOfAcqFrames) std::vector<AcqFrame>; -%template(VectorOfPatterns) std::vector<Pattern>; \ No newline at end of file diff --git a/src/yaml_tools/.gitkeep b/src/yaml_tools/.gitkeep deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/src/yaml_tools/CMakeLists.txt b/src/yaml_tools/CMakeLists.txt deleted file mode 100644 index b38f7889f987629fa9994f2e8ea0382579326072..0000000000000000000000000000000000000000 --- a/src/yaml_tools/CMakeLists.txt +++ /dev/null @@ -1,36 +0,0 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 2.6) -project(yaml_tools) -message("cmake ${PROJECT_NAME}") -if (DEBUG_CMAKE) - set(CMAKE_VERBOSE_MAKEFILE yes) -endif (DEBUG_CMAKE) - -set(yaml_tools_files - ${CMAKE_CURRENT_SOURCE_DIR}/src/yaml_tools.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/include/yaml_tools/yaml_tools.hpp - ) - -set(yaml_tools_files ${yaml_tools_files} PARENT_SCOPE) - -include_directories( - include - ${Boost_INCLUDE_DIR} - ${YAML_INCLUDE_DIR} - ) - -add_library(yaml_tools ${yaml_tools_files}) -add_dependencies(yaml_tools yaml-cpp) -target_link_libraries(yaml_tools yaml-cpp) - -set_target_properties(yaml_tools PROPERTIES FOLDER yaml_tools) - -# Define headers for this library. PUBLIC headers are used for -# compiling the library, and will be added to consumers' build -# paths. -target_include_directories(yaml_tools PUBLIC - $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> - $<INSTALL_INTERFACE:include> - PRIVATE src) - -# This makes the project importable from the build directory -export(TARGETS yaml_tools yaml-cpp FILE yaml_toolsConfig.cmake) \ No newline at end of file diff --git a/src/yaml_tools/include/.gitkeep b/src/yaml_tools/include/.gitkeep deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/src/yaml_tools/include/yaml_tools/.gitkeep b/src/yaml_tools/include/yaml_tools/.gitkeep deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/src/yaml_tools/include/yaml_tools/yaml_tools.hpp b/src/yaml_tools/include/yaml_tools/yaml_tools.hpp deleted file mode 100644 index 332373fad33deafde0eef1d6b8d8ada21ad99c3d..0000000000000000000000000000000000000000 --- a/src/yaml_tools/include/yaml_tools/yaml_tools.hpp +++ /dev/null @@ -1,38 +0,0 @@ -/** - * @file yaml_utils.hpp - * @author Anthony Remazeilles <anthony.remazeilles@tecnalia.com> - * @date 2019 - * - * Copyright 2019 Tecnalia Research & Innovation. - * Distributed under the GNU GPL v3. For full terms see https://www.gnu.org/licenses/gpl.txt - * - * @brief helper functions for yaml-cpp package. - */ - -#ifndef YAML_UTILS_HPP -#define YAML_UTILS_HPP - -#include <yaml-cpp/yaml.h> -#include <string> -#include <vector> - -/** - * @brief check if a tag is defined in a yaml structure - * - * @param[in] tag list of strings bringing to the desired tag - * @param[in] n YAML node from where the tag is to be searched - * - * @return true if the tag is present in the yaml structure. - */ -bool isTagDefined(const std::vector < std::string> &tag, YAML::Node n); -/** - * @brief check if a list of tags are defined in a yaml structure - * - * @param[in] ltags list of strings bringing to the desired tags - * @param[in] n YAML node from where the tag is to be searched - * - * @return true if the tag is present in the yaml structure. - */ -bool areTagsDefined(const std::vector <std::vector < std::string> > <ags, - const YAML::Node & n); -#endif // YAML_UTILS_HPP diff --git a/src/yaml_tools/src/.gitkeep b/src/yaml_tools/src/.gitkeep deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/src/yaml_tools/src/yaml_tools.cpp b/src/yaml_tools/src/yaml_tools.cpp deleted file mode 100644 index 12b3c9a59b16f56847bf191b718a9172c969dcd4..0000000000000000000000000000000000000000 --- a/src/yaml_tools/src/yaml_tools.cpp +++ /dev/null @@ -1,54 +0,0 @@ -/** - * @file yaml_utils.cpp - * @author Anthony Remazeilles <anthony.remazeilles@tecnalia.com> - * @date 2019 - * - * Copyright 2019 Tecnalia Research & Innovation. - * Distributed under the GNU GPL v3. For full terms see https://www.gnu.org/licenses/gpl.txt - * - * @brief helper functions for yaml-cpp package. - */ - -#include <yaml_tools/yaml_tools.hpp> -#include <iostream> - -bool isTagDefined(const std::vector < std::string> &tag, YAML::Node n) -{ - YAML::Node node = YAML::Clone(n); - for (auto item : tag) - { - // std::cout << "Checking tag " << item << std::endl; - if (node[item]) - { - node = node[item]; - } - else - { - std::cerr << "Prb while searching for tag " << item << std::endl; - return false; - } - } - return true; -} -bool areTagsDefined(const std::vector <std::vector < std::string> > <ags, - const YAML::Node & n) -{ - for (auto item : ltags) - { - std::ostringstream oss; - for (auto tag : item) - { - oss << tag << "."; - } - std::string msg = oss.str(); - // remove last - msg.pop_back(); - YAML::Node node = n; - if (!isTagDefined(item, node)) - { - std::cerr << "Could not find the tag " << msg << std::endl; - return false; - } - } - return true; -}