diff --git a/CMakeLists.txt b/CMakeLists.txt index b307dfc82..23f4fad04 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -96,6 +96,20 @@ target_compile_options(slsProjectWarnings INTERFACE ) +#Settings for C code +add_library(slsProjectCSettings INTERFACE) +target_compile_features(slsProjectCSettings INTERFACE c_std_99) +target_compile_options(slsProjectCSettings INTERFACE + -Wall + -Wextra + -Wno-unused-parameter + -Wdouble-promotion + -Wformat=2 + -Wredundant-decls + -Wdouble-promotion + -Werror=return-type + ) + #Testing for minimum version for compilers if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") diff --git a/slsDetectorServers/CMakeLists.txt b/slsDetectorServers/CMakeLists.txt index 20948bac8..af46daa94 100644 --- a/slsDetectorServers/CMakeLists.txt +++ b/slsDetectorServers/CMakeLists.txt @@ -1,17 +1,5 @@ -add_library(slsProjectCSettings INTERFACE) -target_compile_features(slsProjectCSettings INTERFACE c_std_99) -target_compile_options(slsProjectCSettings INTERFACE - -Wall - -Wextra - -Wno-unused-parameter #Needs to be slowly mitigated - -Wdouble-promotion - -Wformat=2 - -Wredundant-decls - # -Wconversion - -Wdouble-promotion - -Werror=return-type - ) + # Install fake the library install(TARGETS slsProjectCSettings diff --git a/slsDetectorServers/ctbDetectorServer/CMakeLists.txt b/slsDetectorServers/ctbDetectorServer/CMakeLists.txt index b909f6ecb..fab32df54 100644 --- a/slsDetectorServers/ctbDetectorServer/CMakeLists.txt +++ b/slsDetectorServers/ctbDetectorServer/CMakeLists.txt @@ -18,6 +18,7 @@ add_executable(ctbDetectorServer_virtual ../slsDetectorServer/src/programFpgaBlackfin.c ../slsDetectorServer/src/sharedMemory.c ../slsDetectorServer/src/loadPattern.c + ../../slsSupportLib/src/md5.c ) include_directories( diff --git a/slsDetectorServers/ctbDetectorServer/Makefile b/slsDetectorServers/ctbDetectorServer/Makefile index fd5df8565..fea8d8db6 100755 --- a/slsDetectorServers/ctbDetectorServer/Makefile +++ b/slsDetectorServers/ctbDetectorServer/Makefile @@ -3,6 +3,7 @@ main_inc = ../slsDetectorServer/include/ main_src = ../slsDetectorServer/src/ support_lib = ../../slsSupportLib/include/ det_lib = ../../slsDetectorSoftware/include/sls/ +md5_dir = ../../slsSupportLib/src/ CROSS = bfin-uclinux- CC = $(CROSS)gcc @@ -13,7 +14,7 @@ DESTDIR ?= bin INSTMODE = 0777 SRCS = slsDetectorFunctionList.c -SRCS += $(main_src)slsDetectorServer.c $(main_src)slsDetectorServer_funcs.c $(main_src)communication_funcs.c $(main_src)blackfin.c $(main_src)common.c $(main_src)commonServerFunctions.c $(main_src)communication_funcs_UDP.c $(main_src)UDPPacketHeaderGenerator.c $(main_src)AD7689.c $(main_src)AD9257.c $(main_src)ALTERA_PLL.c $(main_src)I2C.c $(main_src)INA226.c $(main_src)LTC2620.c $(main_src)MAX1932.c $(main_src)programFpgaBlackfin.c $(main_src)/sharedMemory.c $(main_src)/loadPattern.c +SRCS += $(main_src)slsDetectorServer.c $(main_src)slsDetectorServer_funcs.c $(main_src)communication_funcs.c $(main_src)blackfin.c $(main_src)common.c $(main_src)commonServerFunctions.c $(main_src)communication_funcs_UDP.c $(main_src)UDPPacketHeaderGenerator.c $(main_src)AD7689.c $(main_src)AD9257.c $(main_src)ALTERA_PLL.c $(main_src)I2C.c $(main_src)INA226.c $(main_src)LTC2620.c $(main_src)MAX1932.c $(main_src)programFpgaBlackfin.c $(main_src)/sharedMemory.c $(main_src)/loadPattern.c $(md5_dir)md5.c OBJS = $(SRCS:.c=.o) @@ -34,10 +35,10 @@ $(PROGS): $(OBJS) $(CC) -o $@ $^ $(CFLAGS) $(LDLIBS) mv $(PROGS) $(DESTDIR) rm *.gdb - rm $(main_src)*.o + rm $(main_src)*.o $(md5_dir)*.o clean: - rm -rf $(DESTDIR)/$(PROGS) *.o *.gdb $(main_src)*.o + rm -rf $(DESTDIR)/$(PROGS) *.o *.gdb $(main_src)*.o $(md5_dir)*.o diff --git a/slsDetectorServers/ctbDetectorServer/bin/ctbDetectorServer_developer b/slsDetectorServers/ctbDetectorServer/bin/ctbDetectorServer_developer index a46b62898..dc568e406 100755 Binary files a/slsDetectorServers/ctbDetectorServer/bin/ctbDetectorServer_developer and b/slsDetectorServers/ctbDetectorServer/bin/ctbDetectorServer_developer differ diff --git a/slsDetectorServers/eigerDetectorServer/CMakeLists.txt b/slsDetectorServers/eigerDetectorServer/CMakeLists.txt index a0f660f2e..64f1635e1 100644 --- a/slsDetectorServers/eigerDetectorServer/CMakeLists.txt +++ b/slsDetectorServers/eigerDetectorServer/CMakeLists.txt @@ -6,6 +6,7 @@ set(src ../slsDetectorServer/src/communication_funcs_UDP.c ../slsDetectorServer/src/common.c ../slsDetectorServer/src/sharedMemory.c + ../../slsSupportLib/src/md5.c ) include_directories( diff --git a/slsDetectorServers/eigerDetectorServer/Makefile b/slsDetectorServers/eigerDetectorServer/Makefile index 10b0793ff..5f1d61d2d 100755 --- a/slsDetectorServers/eigerDetectorServer/Makefile +++ b/slsDetectorServers/eigerDetectorServer/Makefile @@ -2,18 +2,19 @@ current_dir = $(shell pwd) main_inc = ../slsDetectorServer/include/ main_src = ../slsDetectorServer/src/ support_lib = ../../slsSupportLib/include/ +md5_dir = ../../slsSupportLib/src/ BLACKFIN_CC = bfin-uclinux-gcc CROSS = powerpc-4xx-softfloat- CC = $(CROSS)gcc -CFLAGS += -Wall -std=gnu99 -DEIGERD -DSTOP_SERVER -I$(main_inc) -I$(support_lib) -I$(current_dir) #-DDEBUG1 #-DVERBOSEI #-DVERBOSE +CFLAGS += -Wall -std=gnu99 -DEIGERD -DSTOP_SERVER -I$(main_inc) -I$(support_lib) -I$(current_dir) #-DDEBUG1 #-DVERBOSEI #-DVERBOSE LDLIBS += -lm -lrt -pthread PROGS = eigerDetectorServer DESTDIR = bin INSTMODE = 0777 SRCS = slsDetectorFunctionList.c HardwareIO.c LocalLinkInterface.c FebInterface.c FebControl.c Beb.c -SRCS += $(main_src)communication_funcs.c $(main_src)slsDetectorServer.c $(main_src)slsDetectorServer_funcs.c $(main_src)communication_funcs_UDP.c $(main_src)common.c $(main_src)/sharedMemory.c +SRCS += $(main_src)communication_funcs.c $(main_src)slsDetectorServer.c $(main_src)slsDetectorServer_funcs.c $(main_src)communication_funcs_UDP.c $(main_src)common.c $(main_src)/sharedMemory.c $(md5_dir)md5.c OBJS = $(SRCS:.c=.o) @@ -40,9 +41,9 @@ $(PROGS): $(OBJS) hv9m_blackfin_server:9mhvserial_bf.c $(BLACKFIN_CC) -o hv9m_blackfin_server 9mhvserial_bf.c -Wall #-DVERBOSE mv hv9m_blackfin_server $(DESTDIR) - rm hv9m_blackfin_server.gdb $(main_server)*.o + rm hv9m_blackfin_server.gdb $(main_src)*.o $(md5_dir)*.o clean: - rm -rf $(DESTDIR)/$(PROGS) *.o $(DESTDIR)/hv9m_blackfin_server $(main_server)*.o + rm -rf $(DESTDIR)/$(PROGS) *.o $(DESTDIR)/hv9m_blackfin_server $(main_src)*.o $(md5_dir)*.o diff --git a/slsDetectorServers/eigerDetectorServer/bin/eigerDetectorServer_developer b/slsDetectorServers/eigerDetectorServer/bin/eigerDetectorServer_developer index 808f51423..09e8e2183 100755 Binary files a/slsDetectorServers/eigerDetectorServer/bin/eigerDetectorServer_developer and b/slsDetectorServers/eigerDetectorServer/bin/eigerDetectorServer_developer differ diff --git a/slsDetectorServers/gotthard2DetectorServer/CMakeLists.txt b/slsDetectorServers/gotthard2DetectorServer/CMakeLists.txt index 9cebb9e9f..f1399bf9c 100644 --- a/slsDetectorServers/gotthard2DetectorServer/CMakeLists.txt +++ b/slsDetectorServers/gotthard2DetectorServer/CMakeLists.txt @@ -12,6 +12,7 @@ add_executable(gotthard2DetectorServer_virtual ../slsDetectorServer/src/ASIC_Driver.c ../slsDetectorServer/src/programFpgaNios.c ../slsDetectorServer/src/sharedMemory.c + ../../slsSupportLib/src/md5.c ) include_directories( diff --git a/slsDetectorServers/gotthard2DetectorServer/Makefile b/slsDetectorServers/gotthard2DetectorServer/Makefile index 1238ad467..481827eab 100755 --- a/slsDetectorServers/gotthard2DetectorServer/Makefile +++ b/slsDetectorServers/gotthard2DetectorServer/Makefile @@ -2,17 +2,18 @@ current_dir = $(shell pwd) main_inc = ../slsDetectorServer/include/ main_src = ../slsDetectorServer/src/ support_lib = ../../slsSupportLib/include/ +md5_dir = ../../slsSupportLib/src/ CROSS = nios2-buildroot-linux-gnu- CC = $(CROSS)gcc -CFLAGS += -Wall -std=gnu99 -DGOTTHARD2D -DSTOP_SERVER -I$(main_inc) -I$(support_lib) -I$(current_dir) #-DDEBUG1 #-DVERBOSEI #-DVERBOSE +CFLAGS += -Wall -std=gnu99 -DGOTTHARD2D -DSTOP_SERVER -I$(main_inc) -I$(support_lib) -I$(current_dir) #-DDEBUG1 #-DVERBOSEI #-DVERBOSE LDLIBS += -lm -lrt -pthread PROGS = gotthard2DetectorServer DESTDIR ?= bin INSTMODE = 0777 SRCS = slsDetectorFunctionList.c -SRCS += $(main_src)slsDetectorServer.c $(main_src)slsDetectorServer_funcs.c $(main_src)communication_funcs.c $(main_src)nios.c $(main_src)common.c $(main_src)DAC6571.c $(main_src)LTC2620_Driver.c $(main_src)ALTERA_PLL_CYCLONE10.c $(main_src)ASIC_Driver.c $(main_src)/programFpgaNios.c $(main_src)/sharedMemory.c +SRCS += $(main_src)slsDetectorServer.c $(main_src)slsDetectorServer_funcs.c $(main_src)communication_funcs.c $(main_src)nios.c $(main_src)common.c $(main_src)DAC6571.c $(main_src)LTC2620_Driver.c $(main_src)ALTERA_PLL_CYCLONE10.c $(main_src)ASIC_Driver.c $(main_src)/programFpgaNios.c $(main_src)/sharedMemory.c $(md5_dir)md5.c OBJS = $(SRCS:.c=.o) @@ -34,10 +35,10 @@ $(PROGS): $(OBJS) mv $(PROGS) $(DESTDIR) cp config_gotthard2.txt $(DESTDIR) cp detid_gotthard2.txt $(DESTDIR) - rm $(main_src)*.o + rm $(main_src)*.o $(md5_dir)*.o clean: - rm -rf $(DESTDIR)/$(PROGS) *.o *.gdb $(main_src)*.o + rm -rf $(DESTDIR)/$(PROGS) *.o *.gdb $(main_src)*.o $(md5_dir)*.o \ No newline at end of file diff --git a/slsDetectorServers/gotthard2DetectorServer/bin/gotthard2DetectorServer_developer b/slsDetectorServers/gotthard2DetectorServer/bin/gotthard2DetectorServer_developer index c3de81e50..12df14554 100755 Binary files a/slsDetectorServers/gotthard2DetectorServer/bin/gotthard2DetectorServer_developer and b/slsDetectorServers/gotthard2DetectorServer/bin/gotthard2DetectorServer_developer differ diff --git a/slsDetectorServers/gotthardDetectorServer/CMakeLists.txt b/slsDetectorServers/gotthardDetectorServer/CMakeLists.txt index d3a14b689..8dc6bf58a 100644 --- a/slsDetectorServers/gotthardDetectorServer/CMakeLists.txt +++ b/slsDetectorServers/gotthardDetectorServer/CMakeLists.txt @@ -11,6 +11,7 @@ add_executable(gotthardDetectorServer_virtual ../slsDetectorServer/src/commonServerFunctions.c ../slsDetectorServer/src/communication_funcs_UDP.c ../slsDetectorServer/src/sharedMemory.c + ../../slsSupportLib/src/md5.c ) include_directories( diff --git a/slsDetectorServers/gotthardDetectorServer/Makefile b/slsDetectorServers/gotthardDetectorServer/Makefile index ef245754a..9544d991c 100755 --- a/slsDetectorServers/gotthardDetectorServer/Makefile +++ b/slsDetectorServers/gotthardDetectorServer/Makefile @@ -2,17 +2,18 @@ current_dir = $(shell pwd) main_inc = ../slsDetectorServer/include/ main_src = ../slsDetectorServer/src/ support_lib = ../../slsSupportLib/include/ +md5_dir = ../../slsSupportLib/src/ CROSS = bfin-uclinux- CC = $(CROSS)gcc -CFLAGS += -Wall -std=gnu99 -DGOTTHARDD -DSTOP_SERVER -I$(main_inc) -I$(support_lib) -I$(current_dir)#-DVERBOSEI #-DVERBOSE +CFLAGS += -Wall -std=gnu99 -DGOTTHARDD -DSTOP_SERVER -I$(main_inc) -I$(support_lib) -I$(current_dir) #-DVERBOSEI #-DVERBOSE LDLIBS += -lm -lrt -pthread PROGS = gotthardDetectorServer DESTDIR ?= bin INSTMODE = 0777 SRCS = slsDetectorFunctionList.c -SRCS += $(main_src)slsDetectorServer.c $(main_src)slsDetectorServer_funcs.c $(main_src)communication_funcs.c $(main_src)blackfin.c $(main_src)AD9252.c $(main_src)AD9257.c $(main_src)LTC2620.c $(main_src)common.c $(main_src)commonServerFunctions.c $(main_src)/sharedMemory.c +SRCS += $(main_src)slsDetectorServer.c $(main_src)slsDetectorServer_funcs.c $(main_src)communication_funcs.c $(main_src)blackfin.c $(main_src)AD9252.c $(main_src)AD9257.c $(main_src)LTC2620.c $(main_src)common.c $(main_src)commonServerFunctions.c $(main_src)/sharedMemory.c $(md5_dir)md5.c OBJS = $(SRCS:.c=.o) all: clean $(PROGS) @@ -33,10 +34,10 @@ $(PROGS): $(OBJS) mv $(PROGS) $(DESTDIR) cp config_gotthard.txt $(DESTDIR) rm *.gdb - rm $(main_src)*.o + rm $(main_src)*.o $(md5_dir)*.o clean: - rm -rf $(DESTDIR)/$(PROGS) *.o *.gdb $(main_src)*.o + rm -rf $(DESTDIR)/$(PROGS) *.o *.gdb $(main_src)*.o $(md5_dir)*.o diff --git a/slsDetectorServers/gotthardDetectorServer/bin/gotthardDetectorServer_developer b/slsDetectorServers/gotthardDetectorServer/bin/gotthardDetectorServer_developer index 94c0a4721..1dd093d7c 100755 Binary files a/slsDetectorServers/gotthardDetectorServer/bin/gotthardDetectorServer_developer and b/slsDetectorServers/gotthardDetectorServer/bin/gotthardDetectorServer_developer differ diff --git a/slsDetectorServers/jungfrauDetectorServer/CMakeLists.txt b/slsDetectorServers/jungfrauDetectorServer/CMakeLists.txt index 2d1a6fd12..d5d251e81 100644 --- a/slsDetectorServers/jungfrauDetectorServer/CMakeLists.txt +++ b/slsDetectorServers/jungfrauDetectorServer/CMakeLists.txt @@ -13,6 +13,7 @@ add_executable(jungfrauDetectorServer_virtual ../slsDetectorServer/src/programFpgaBlackfin.c ../slsDetectorServer/src/communication_funcs_UDP.c ../slsDetectorServer/src/sharedMemory.c + ../../slsSupportLib/src/md5.c ) target_include_directories(jungfrauDetectorServer_virtual diff --git a/slsDetectorServers/jungfrauDetectorServer/Makefile b/slsDetectorServers/jungfrauDetectorServer/Makefile index 551b9137c..054f2c62a 100755 --- a/slsDetectorServers/jungfrauDetectorServer/Makefile +++ b/slsDetectorServers/jungfrauDetectorServer/Makefile @@ -2,17 +2,18 @@ current_dir = $(shell pwd) main_inc = ../slsDetectorServer/include/ main_src = ../slsDetectorServer/src/ support_lib = ../../slsSupportLib/include/ +md5_dir = ../../slsSupportLib/src/ CROSS = bfin-uclinux- CC = $(CROSS)gcc -CFLAGS += -Wall -std=gnu99 -DJUNGFRAUD -DSTOP_SERVER -I$(main_inc) -I$(support_lib) -I$(current_dir)#-DVERBOSEI #-DVERBOSE +CFLAGS += -Wall -std=gnu99 -DJUNGFRAUD -DSTOP_SERVER -I$(main_inc) -I$(support_lib) -I$(current_dir) #-DVERBOSEI #-DVERBOSE LDLIBS += -lm -lrt -pthread PROGS = jungfrauDetectorServer DESTDIR ?= bin INSTMODE = 0777 SRCS = slsDetectorFunctionList.c -SRCS += $(main_src)slsDetectorServer.c $(main_src)slsDetectorServer_funcs.c $(main_src)communication_funcs.c $(main_src)blackfin.c $(main_src)common.c $(main_src)commonServerFunctions.c $(main_src)AD9257.c $(main_src)ALTERA_PLL.c $(main_src)LTC2620.c $(main_src)MAX1932.c $(main_src)programFpgaBlackfin.c $(main_src)/sharedMemory.c +SRCS += $(main_src)slsDetectorServer.c $(main_src)slsDetectorServer_funcs.c $(main_src)communication_funcs.c $(main_src)blackfin.c $(main_src)common.c $(main_src)commonServerFunctions.c $(main_src)AD9257.c $(main_src)ALTERA_PLL.c $(main_src)LTC2620.c $(main_src)MAX1932.c $(main_src)programFpgaBlackfin.c $(main_src)/sharedMemory.c $(md5_dir)md5.c OBJS = $(SRCS:.c=.o) @@ -34,10 +35,10 @@ $(PROGS): $(OBJS) mv $(PROGS) $(DESTDIR) cp config_jungfrau.txt $(DESTDIR) rm *.gdb - rm $(main_src)*.o + rm $(main_src)*.o $(md5_dir)*.o clean: - rm -rf $(DESTDIR)/$(PROGS) *.o *.gdb $(main_src)*.o + rm -rf $(DESTDIR)/$(PROGS) *.o *.gdb $(main_src)*.o $(md5_dir)*.o \ No newline at end of file diff --git a/slsDetectorServers/jungfrauDetectorServer/bin/jungfrauDetectorServer_developer b/slsDetectorServers/jungfrauDetectorServer/bin/jungfrauDetectorServer_developer index 3b7140044..d6234b849 100755 Binary files a/slsDetectorServers/jungfrauDetectorServer/bin/jungfrauDetectorServer_developer and b/slsDetectorServers/jungfrauDetectorServer/bin/jungfrauDetectorServer_developer differ diff --git a/slsDetectorServers/jungfrauDetectorServer/slsDetectorServer_defs.h b/slsDetectorServers/jungfrauDetectorServer/slsDetectorServer_defs.h index e441b626e..fb8f81312 100644 --- a/slsDetectorServers/jungfrauDetectorServer/slsDetectorServer_defs.h +++ b/slsDetectorServers/jungfrauDetectorServer/slsDetectorServer_defs.h @@ -3,7 +3,7 @@ #include "sls/sls_detector_defs.h" #define MIN_REQRD_VRSN_T_RD_API 0x171220 -#define REQRD_FRMWRE_VRSN_BOARD2 0x210621 // 1.0 pcb (version = 010) +#define REQRD_FRMWRE_VRSN_BOARD2 0x210831 // 1.0 pcb (version = 010) #define REQRD_FRMWRE_VRSN 0x210622 // 2.0 pcb (version = 011) #define CTRL_SRVR_INIT_TIME_US (300 * 1000) diff --git a/slsDetectorServers/moenchDetectorServer/CMakeLists.txt b/slsDetectorServers/moenchDetectorServer/CMakeLists.txt index 9c36d155b..8a2a02ed6 100644 --- a/slsDetectorServers/moenchDetectorServer/CMakeLists.txt +++ b/slsDetectorServers/moenchDetectorServer/CMakeLists.txt @@ -15,6 +15,7 @@ add_executable(moenchDetectorServer_virtual ../slsDetectorServer/src/programFpgaBlackfin.c ../slsDetectorServer/src/loadPattern.c ../slsDetectorServer/src/sharedMemory.c + ../../slsSupportLib/src/md5.c ) include_directories( diff --git a/slsDetectorServers/moenchDetectorServer/Makefile b/slsDetectorServers/moenchDetectorServer/Makefile index c7226f169..3091c6564 100755 --- a/slsDetectorServers/moenchDetectorServer/Makefile +++ b/slsDetectorServers/moenchDetectorServer/Makefile @@ -3,17 +3,18 @@ main_inc = ../slsDetectorServer/include/ main_src = ../slsDetectorServer/src/ support_lib = ../../slsSupportLib/include/ det_lib = ../../slsDetectorSoftware/include/sls/ +md5_dir = ../../slsSupportLib/src/ CROSS = bfin-uclinux- CC = $(CROSS)gcc -CFLAGS += -Wall -std=gnu99 -DMOENCHD -DSTOP_SERVER -I$(main_inc) -I$(support_lib) -I$(det_lib) -I$(current_dir)#-DVERBOSEI #-DVERBOSE +CFLAGS += -Wall -std=gnu99 -DMOENCHD -DSTOP_SERVER -I$(main_inc) -I$(support_lib) -I$(det_lib) -I$(current_dir) #-DVERBOSEI #-DVERBOSE LDLIBS += -lm -lrt -pthread PROGS = moenchDetectorServer DESTDIR ?= bin INSTMODE = 0777 SRCS = slsDetectorFunctionList.c -SRCS += $(main_src)slsDetectorServer.c $(main_src)slsDetectorServer_funcs.c $(main_src)communication_funcs.c $(main_src)blackfin.c $(main_src)common.c $(main_src)commonServerFunctions.c $(main_src)communication_funcs_UDP.c $(main_src)UDPPacketHeaderGenerator.c $(main_src)AD9257.c $(main_src)ALTERA_PLL.c $(main_src)LTC2620.c $(main_src)MAX1932.c $(main_src)programFpgaBlackfin.c $(main_src)loadPattern.c $(main_src)/sharedMemory.c +SRCS += $(main_src)slsDetectorServer.c $(main_src)slsDetectorServer_funcs.c $(main_src)communication_funcs.c $(main_src)blackfin.c $(main_src)common.c $(main_src)commonServerFunctions.c $(main_src)communication_funcs_UDP.c $(main_src)UDPPacketHeaderGenerator.c $(main_src)AD9257.c $(main_src)ALTERA_PLL.c $(main_src)LTC2620.c $(main_src)MAX1932.c $(main_src)programFpgaBlackfin.c $(main_src)loadPattern.c $(main_src)/sharedMemory.c $(md5_dir)md5.c OBJS = $(SRCS:.c=.o) @@ -36,10 +37,10 @@ $(PROGS): $(OBJS) cp DefaultPattern_moench.txt $(DESTDIR) rm *.gdb rm $(main_src)*.o - rm *.o + rm *.o $(md5_dir)*.o clean: - rm -rf $(DESTDIR)/$(PROGS) *.o *.gdb $(main_src)*.o + rm -rf $(DESTDIR)/$(PROGS) *.o *.gdb $(main_src)*.o $(md5_dir)*.o \ No newline at end of file diff --git a/slsDetectorServers/moenchDetectorServer/bin/moenchDetectorServer_developer b/slsDetectorServers/moenchDetectorServer/bin/moenchDetectorServer_developer index 6859be991..aae9b1c0c 100755 Binary files a/slsDetectorServers/moenchDetectorServer/bin/moenchDetectorServer_developer and b/slsDetectorServers/moenchDetectorServer/bin/moenchDetectorServer_developer differ diff --git a/slsDetectorServers/mythen3DetectorServer/CMakeLists.txt b/slsDetectorServers/mythen3DetectorServer/CMakeLists.txt index ea43df079..aee0a6b57 100644 --- a/slsDetectorServers/mythen3DetectorServer/CMakeLists.txt +++ b/slsDetectorServers/mythen3DetectorServer/CMakeLists.txt @@ -13,6 +13,7 @@ add_executable(mythen3DetectorServer_virtual ../slsDetectorServer/src/programFpgaNios.c ../slsDetectorServer/src/loadPattern.c ../slsDetectorServer/src/sharedMemory.c + ../../slsSupportLib/src/md5.c ) include_directories( diff --git a/slsDetectorServers/mythen3DetectorServer/Makefile b/slsDetectorServers/mythen3DetectorServer/Makefile index 9c6c8827b..f8fb7e3c4 100755 --- a/slsDetectorServers/mythen3DetectorServer/Makefile +++ b/slsDetectorServers/mythen3DetectorServer/Makefile @@ -3,17 +3,18 @@ main_inc = ../slsDetectorServer/include/ main_src = ../slsDetectorServer/src/ support_lib = ../../slsSupportLib/include/ det_lib = ../../slsDetectorSoftware/include/sls/ +md5_dir = ../../slsSupportLib/src/ CROSS = nios2-buildroot-linux-gnu- CC = $(CROSS)gcc -CFLAGS += -Wall -std=gnu99 -DMYTHEN3D -DSTOP_SERVER -I$(main_inc) -I$(support_lib) -I$(det_lib) -I$(current_dir) #-DDEBUG1 #-DVERBOSEI #-DVERBOSE +CFLAGS += -Wall -std=gnu99 -DMYTHEN3D -DSTOP_SERVER -I$(main_inc) -I$(support_lib) -I$(det_lib) -I$(current_dir) #-DDEBUG1 #-DVERBOSEI #-DVERBOSE LDLIBS += -lm -lrt -pthread PROGS = mythen3DetectorServer DESTDIR ?= bin INSTMODE = 0777 SRCS = slsDetectorFunctionList.c -SRCS += $(main_src)slsDetectorServer.c $(main_src)slsDetectorServer_funcs.c $(main_src)communication_funcs.c $(main_src)nios.c $(main_src)DAC6571.c $(main_src)common.c $(main_src)LTC2620_Driver.c $(main_src)ALTERA_PLL_CYCLONE10.c $(main_src)/programFpgaNios.c $(main_src)/sharedMemory.c $(main_src)/loadPattern.c mythen3.c +SRCS += $(main_src)slsDetectorServer.c $(main_src)slsDetectorServer_funcs.c $(main_src)communication_funcs.c $(main_src)nios.c $(main_src)DAC6571.c $(main_src)common.c $(main_src)LTC2620_Driver.c $(main_src)ALTERA_PLL_CYCLONE10.c $(main_src)/programFpgaNios.c $(main_src)/sharedMemory.c $(main_src)/loadPattern.c mythen3.c $(md5_dir)md5.c OBJS = $(SRCS:.c=.o) @@ -35,10 +36,10 @@ $(PROGS): $(OBJS) mv $(PROGS) $(DESTDIR) cp DefaultPattern_mythen3.txt $(DESTDIR) cp detid_mythen3.txt $(DESTDIR) - rm $(main_src)*.o + rm $(main_src)*.o $(md5_dir)*.o clean: - rm -rf $(DESTDIR)/$(PROGS) *.o *.gdb $(main_src)*.o + rm -rf $(DESTDIR)/$(PROGS) *.o *.gdb $(main_src)*.o $(md5_dir)*.o diff --git a/slsDetectorServers/mythen3DetectorServer/bin/mythen3DetectorServer_developer b/slsDetectorServers/mythen3DetectorServer/bin/mythen3DetectorServer_developer index 3c4cc76a8..c93911a12 100755 Binary files a/slsDetectorServers/mythen3DetectorServer/bin/mythen3DetectorServer_developer and b/slsDetectorServers/mythen3DetectorServer/bin/mythen3DetectorServer_developer differ diff --git a/slsDetectorServers/slsDetectorServer/include/common.h b/slsDetectorServers/slsDetectorServer/include/common.h index d0beaca28..a05e77bd1 100644 --- a/slsDetectorServers/slsDetectorServer/include/common.h +++ b/slsDetectorServers/slsDetectorServer/include/common.h @@ -1,7 +1,9 @@ #pragma once +#include "sls/md5.h" #include // int64_t #include +#include #include enum numberMode { DEC, HEX }; @@ -30,4 +32,10 @@ void validate64(int *ret, char *mess, int64_t arg, int64_t retval, char *modename, enum numberMode nummode); int getModuleIdInFile(int *ret, char *mess, char *fileName); -int setModuleIdInFile(char *mess, int arg, char *fileName); \ No newline at end of file +int setModuleIdInFile(char *mess, int arg, char *fileName); +int verifyChecksumFromBuffer(char *mess, char *clientChecksum, char *buffer, + ssize_t bytes); +int verifyChecksumFromFile(char *mess, char *clientChecksum, char *fname); +int verifyChecksumFromFlash(char *mess, char *clientChecksum, char *fname, + ssize_t fsize); +int verifyChecksum(char *mess, char *clientChecksum, MD5_CTX *c, char *msg); \ No newline at end of file diff --git a/slsDetectorServers/slsDetectorServer/include/programFpgaBlackfin.h b/slsDetectorServers/slsDetectorServer/include/programFpgaBlackfin.h index 142fe5695..0fff822d2 100644 --- a/slsDetectorServers/slsDetectorServer/include/programFpgaBlackfin.h +++ b/slsDetectorServers/slsDetectorServer/include/programFpgaBlackfin.h @@ -2,54 +2,29 @@ #include #include +#include + +#define TEMP_PROG_FILE_NAME "/var/tmp/tmp.rawbin" -/** - * Define GPIO pins if not defined - */ void defineGPIOpins(); - -/** - * Notify FPGA to not touch flash - */ void FPGAdontTouchFlash(); - -/** - * Notify FPGA to program from flash - */ void FPGATouchFlash(); - -/** - * Reset FPGA - */ void resetFPGA(); +int deleteOldFile(char *mess); /** - * Erasing flash + * deletes old file + * verify memory available to copy + * open file to copy */ -void eraseFlash(); - -/** - * Open the drive to copy program and - * notify FPGA not to touch the program - * @param filefp pointer to flash - * @return 0 for success, 1 for fail (cannot open file for writing program) +int preparetoCopyFPGAProgram(FILE **fd, uint64_t fsize, char *mess); +int copyToFlash(ssize_t fsize, char *clientChecksum, char *mess); +int getDrive(char *mess); +/** Notify fpga not to touch flash, open src and flash drive to write */ +int openFileForFlash(FILE **flashfd, FILE **srcfd, char *mess); +int eraseFlash(char *mess); +/* write from tmp file to flash */ +int writeToFlash(ssize_t fsize, FILE *flashfd, FILE *srcfd, char *mess); +/** Notify fpga to pick up firmware from flash and wait for status confirmation */ -int startWritingFPGAprogram(FILE **filefp); - -/** - * When done writing the program, close file pointer and - * notify FPGA to pick up the program from flash - * @param filefp pointer to flash - * @return 0 for success, 1 for fail (time taken for fpga to touch flash - * exceeded) - */ -int stopWritingFPGAprogram(FILE *filefp); - -/** - * Write FPGA Program to flash - * @param fpgasrc source program - * @param fsize size of program - * @param filefp pointer to flash - * @return 0 for success, 1 for fail (cannot write) - */ -int writeFPGAProgram(char *fpgasrc, uint64_t fsize, FILE *filefp); +int waitForFPGAtoTouchFlash(char *mess); diff --git a/slsDetectorServers/slsDetectorServer/include/programFpgaNios.h b/slsDetectorServers/slsDetectorServer/include/programFpgaNios.h index 87633f0c7..c999a8da1 100644 --- a/slsDetectorServers/slsDetectorServer/include/programFpgaNios.h +++ b/slsDetectorServers/slsDetectorServer/include/programFpgaNios.h @@ -11,29 +11,8 @@ void NotifyServerStartSuccess(); /** reset fpga and controller(only implemented for >= v1.1 boards) */ void rebootControllerAndFPGA(); -/** finds the right mtd drive - * @param mess error message - * @returns ok or fail - */ -int findFlash(char *mess); - -/** erase flash */ -void eraseFlash(); - -/** erase and write flash - * @param mess error message - * @param fpgasrc program source - * @param fsize file size - * @returns ok or fail - */ -int eraseAndWriteToFlash(char *mess, char *fpgasrc, uint64_t fsize); - -/** - * Write FPGA Program to flash - * @param mess error message - * @param fpgasrc source program - * @param fsize size of program - * @param filefp pointer to flash - * @return ok or fail - */ -int writeFPGAProgram(char *mess, char *fpgasrc, uint64_t fsize, FILE *filefp); +int eraseAndWriteToFlash(char *mess, char *checksum, char *fpgasrc, uint64_t fsize); +int getDrive(char *mess); +int openFileForFlash(FILE **flashfd, char *mess); +int eraseFlash(char *mess); +int writeToFlash(ssize_t fsize, FILE *flashfd, char *buffer, char *mess); \ No newline at end of file diff --git a/slsDetectorServers/slsDetectorServer/src/common.c b/slsDetectorServers/slsDetectorServer/src/common.c index 08a172d06..85ac9009b 100644 --- a/slsDetectorServers/slsDetectorServer/src/common.c +++ b/slsDetectorServers/slsDetectorServer/src/common.c @@ -7,6 +7,7 @@ #include #include // readlink + int ConvertToDifferentRange(int inputMin, int inputMax, int outputMin, int outputMax, int inputValue, int *outputValue) { LOG(logDEBUG1, (" Input Value: %d (Input:(%d - %d), Output:(%d - %d))\n", @@ -178,3 +179,147 @@ int setModuleIdInFile(char *mess, int arg, char *fileName) { } return OK; } + +int verifyChecksumFromBuffer(char *mess, char *clientChecksum, char *buffer, + ssize_t bytes) { + LOG(logINFO, ("\tVerifying Checksum...\n")); + MD5_CTX c; + if (!MD5_Init_SLS(&c)) { + strcpy(mess, "Unable to calculate checksum (MD5_Init_SLS)\n"); + LOG(logERROR, (mess)); + return FAIL; + } + if (!MD5_Update_SLS(&c, buffer, bytes)) { + strcpy(mess, "Unable to calculate checksum (MD5_Update_SLS)\n"); + LOG(logERROR, (mess)); + return FAIL; + } + return verifyChecksum(mess, clientChecksum, &c, "copied program"); +} + +int verifyChecksumFromFile(char *mess, char *clientChecksum, char *fname) { + LOG(logINFO, ("\tVerifying Checksum...\n")); + + FILE *fp = fopen(fname, "r"); + if (fp == NULL) { + sprintf(mess, "Unable to open %s in read mode to get checksum\n", + fname); + LOG(logERROR, (mess)); + return FAIL; + } + + MD5_CTX c; + if (!MD5_Init_SLS(&c)) { + fclose(fp); + strcpy(mess, "Unable to calculate checksum (MD5_Init_SLS)\n"); + LOG(logERROR, (mess)); + return FAIL; + } + const int readUnitSize = 128; + char buf[readUnitSize]; + ssize_t bytes = fread(buf, 1, readUnitSize, fp); + ssize_t totalBytesRead = bytes; + while (bytes > 0) { + if (!MD5_Update_SLS(&c, buf, bytes)) { + fclose(fp); + strcpy(mess, "Unable to calculate checksum (MD5_Update_SLS)\n"); + LOG(logERROR, (mess)); + return FAIL; + } + bytes = fread(buf, 1, readUnitSize, fp); + totalBytesRead += bytes; + } + LOG(logINFO, ("\tRead %lu bytes to calculate checksum\n", totalBytesRead)); + fclose(fp); + return verifyChecksum(mess, clientChecksum, &c, "copied program"); +} + +int verifyChecksumFromFlash(char *mess, char *clientChecksum, char *fname, + ssize_t fsize) { + LOG(logINFO, ("\tVerifying FlashChecksum...\n")); + + FILE *fp = fopen(fname, "r"); + if (fp == NULL) { + sprintf(mess, "Unable to open %s in read mode to get checksum\n", + fname); + LOG(logERROR, (mess)); + return FAIL; + } + + MD5_CTX c; + if (!MD5_Init_SLS(&c)) { + fclose(fp); + strcpy(mess, "Unable to calculate checksum (MD5_Init_SLS)\n"); + LOG(logERROR, (mess)); + return FAIL; + } + const int readUnitSize = 128; + char buf[readUnitSize]; + ssize_t bytes = fread(buf, 1, readUnitSize, fp); + ssize_t totalBytesRead = bytes; + int oldProgress = 0; + + while (bytes > 0) { + int progress = (int)(((double)(totalBytesRead) / fsize) * 100); + if (oldProgress != progress) { + printf("%d%%\r", progress); + fflush(stdout); + oldProgress = progress; + } + + if (!MD5_Update_SLS(&c, buf, bytes)) { + fclose(fp); + strcpy(mess, "Unable to calculate checksum (MD5_Update_SLS)\n"); + LOG(logERROR, (mess)); + return FAIL; + } + + // read only until a particular size (drive) + if (fsize != 0 && totalBytesRead >= fsize) { + LOG(logINFO, ("\tReached %lu bytes. Not reading more\n", totalBytesRead)); + break; + } + bytes = fread(buf, 1, readUnitSize, fp); + totalBytesRead += bytes; + } + LOG(logINFO, ("\tRead %lu bytes to calculate checksum\n", totalBytesRead)); + fclose(fp); + int ret = verifyChecksum(mess, clientChecksum, &c, "flash"); + if (ret == OK) { + LOG(logINFO, ("Checksum in Flash verified\n")); + } + return ret; +} + +int verifyChecksum(char *mess, char *clientChecksum, MD5_CTX *c, char *msg) { + unsigned char out[MD5_DIGEST_LENGTH]; + if (!MD5_Final_SLS(out, c)) { + strcpy(mess, "Unable to calculate checksum (MD5_Final_SLS)\n"); + LOG(logERROR, (mess)); + return FAIL; + } + + char checksum[512]; + memset(checksum, 0, 512); + for (int i = 0; i != MD5_DIGEST_LENGTH; ++i) { + char part[16]; + memset(part, 0, 16); + sprintf(part, "%02x", out[i]); + strcat(checksum, part); + } + + LOG(logDEBUG1, + ("\nC checksum: %s\nS checksum: %s\n", clientChecksum, checksum)); + + // compare checksum + if (strcmp(clientChecksum, checksum)) { + sprintf(mess, + "Checksum of %s does not match. Client " + "checksum:%s, copied checksum:%s\n", + msg, clientChecksum, checksum); + LOG(logERROR, (mess)); + return FAIL; + } + LOG(logINFO, ("\tChecksum verified\n")); + return OK; +} \ No newline at end of file diff --git a/slsDetectorServers/slsDetectorServer/src/programFpgaBlackfin.c b/slsDetectorServers/slsDetectorServer/src/programFpgaBlackfin.c index e44d5ff8c..bd8b4a6b6 100644 --- a/slsDetectorServers/slsDetectorServer/src/programFpgaBlackfin.c +++ b/slsDetectorServers/slsDetectorServer/src/programFpgaBlackfin.c @@ -1,19 +1,31 @@ #include "programFpgaBlackfin.h" #include "clogger.h" +#include "common.h" #include "sls/ansi.h" #include "slsDetectorServer_defs.h" #include #include // usleep +#include /* global variables */ -#define MTDSIZE 10 +// clang-format off #define MAX_TIME_FPGA_TOUCH_FLASH_US (10 * 1000 * 1000) // 10s +#define CMD_GET_FLASH "awk \'$4== \"\\\"bitfile(spi)\\\"\" {print $1}\' /proc/mtd" +#define CMD_FPGA_PICKED_STATUS "cat /sys/class/gpio/gpio7/value" +#define FLASH_BUFFER_MEMORY_SIZE (128 * 1024) // 500 KB +// clang-format on +#define FLASH_DRIVE_NAME_SIZE 16 +char flashDriveName[FLASH_DRIVE_NAME_SIZE] = {0}; int gpioDefined = 0; -char mtdvalue[MTDSIZE] = {0}; + +extern int executeCommand(char *command, char *result, enum TLogLevel level); void defineGPIOpins() { +#ifdef VIRTUAL + return; +#endif if (!gpioDefined) { // define the gpio pins system("echo 7 > /sys/class/gpio/export"); @@ -28,35 +40,125 @@ void defineGPIOpins() { } void FPGAdontTouchFlash() { +#ifdef VIRTUAL + return; +#endif // tell FPGA to not touch flash system("echo 0 > /sys/class/gpio/gpio9/value"); // usleep(100*1000); } void FPGATouchFlash() { +#ifdef VIRTUAL + return; +#endif // tell FPGA to touch flash to program itself system("echo 1 > /sys/class/gpio/gpio9/value"); } void resetFPGA() { LOG(logINFOBLUE, ("Reseting FPGA\n")); +#ifdef VIRTUAL + return; +#endif FPGAdontTouchFlash(); FPGATouchFlash(); usleep(CTRL_SRVR_INIT_TIME_US); } -void eraseFlash() { - LOG(logDEBUG1, ("Erasing Flash\n")); - char command[255]; - memset(command, 0, 255); - sprintf(command, "flash_eraseall %s", mtdvalue); - system(command); - LOG(logINFO, ("Flash erased\n")); +int deleteOldFile(char *mess) { + char cmd[MAX_STR_LENGTH] = {0}; + char retvals[MAX_STR_LENGTH] = {0}; + sprintf(cmd, "rm -fr %s", TEMP_PROG_FILE_NAME); + if (FAIL == executeCommand(cmd, retvals, logDEBUG1)) { + strcpy(mess, + "Could not program fpga. (could not delete old file: "); + strncat(mess, retvals, sizeof(mess) - strlen(mess) - 1); + strcat(mess, "\n"); + LOG(logERROR, (mess)); + return FAIL; + } + LOG(logINFO, ("\tDeleted old programming file (%s)\n", TEMP_PROG_FILE_NAME)); + return OK; } -int startWritingFPGAprogram(FILE **filefp) { - LOG(logDEBUG1, ("Start Writing of FPGA program\n")); +int preparetoCopyFPGAProgram(FILE **fd, uint64_t fsize, char *mess) { + if (deleteOldFile(mess) == FAIL) { + return FAIL; + } + + // check available memory to copy program + { + struct sysinfo info; + sysinfo(&info); + if (fsize >= info.freeram) { + sprintf(mess, + "Could not program fpga. Not enough memory to copy " + "program. [File size:%ldMB, free RAM: %ldMB]\n", + (long int)(fsize / (1024 * 1024)), + (long int)(info.freeram / (1024 * 1024))); + LOG(logERROR, (mess)); + return FAIL; + } + } + + // open file to copy program + *fd = fopen(TEMP_PROG_FILE_NAME, "w"); + if (*fd == NULL) { + sprintf(mess, "Unable to open %s in write mode\n", TEMP_PROG_FILE_NAME); + LOG(logERROR, (mess)); + return FAIL; + } + LOG(logINFO, ("\tGoing to copy program to %s\n", TEMP_PROG_FILE_NAME)); + return OK; +} + +int copyToFlash(ssize_t fsize, char *clientChecksum, char *mess) { + + if (getDrive(mess) == FAIL) { + return FAIL; + } + + FILE *flashfd = NULL; + FILE *srcfd = NULL; + if (openFileForFlash(&flashfd, &srcfd, mess) == FAIL) { + return FAIL; + } + + if (eraseFlash(mess) == FAIL) { + fclose(flashfd); + fclose(srcfd); + return FAIL; + } + + if (writeToFlash(fsize, flashfd, srcfd, mess) == FAIL) { + return FAIL; + } + + if (deleteOldFile(mess) == FAIL) { + return FAIL; + } + +/* ignoring this until a consistent way to read from bfin flash + if (verifyChecksumFromFlash(mess, clientChecksum, flashDriveName, fsize) == + FAIL) { + return FAIL; + } +*/ + if (waitForFPGAtoTouchFlash(mess) == FAIL) { + return FAIL; + } + + return OK; +} + +int getDrive(char *mess) { +#ifdef VIRTUAL + strcpy(flashDriveName, "/tmp/SLS_mtd3"); + return OK; +#endif + LOG(logDEBUG1, ("Finding flash drive...\n")); // getting the drive // root:/> cat /proc/mtd // dev: size erasesize name @@ -64,86 +166,189 @@ int startWritingFPGAprogram(FILE **filefp) { // mtd1: 00100000 00020000 "linux kernel(nor)" // mtd2: 002c0000 00020000 "file system(nor)" // mtd3: 01000000 00010000 "bitfile(spi)" - char output[255]; - memset(output, 0, 255); - FILE *fp = popen( - "awk \'$4== \"\\\"bitfile(spi)\\\"\" {print $1}\' /proc/mtd", "r"); - if (fp == NULL) { - LOG(logERROR, ("popen returned NULL. Need that to get mtd drive.\n")); - return 1; + + char cmd[MAX_STR_LENGTH] = {0}; + char retvals[MAX_STR_LENGTH] = {0}; + strcpy(cmd, CMD_GET_FLASH); + if (executeCommand(cmd, retvals, logDEBUG1) == FAIL) { + strcpy(mess, "Could not program fpga. (could not get flash drive: "); + strncat(mess, retvals, sizeof(mess) - strlen(mess) - 1); + strcat(mess, "\n"); + LOG(logERROR, (mess)); + return FAIL; } - if (fgets(output, sizeof(output), fp) == NULL) { - LOG(logERROR, ("fgets returned NULL. Need that to get mtd drive.\n")); - return 1; - } - pclose(fp); - memset(mtdvalue, 0, MTDSIZE); - strcpy(mtdvalue, "/dev/"); - char *pch = strtok(output, ":"); + + char *pch = strtok(retvals, ":"); if (pch == NULL) { - LOG(logERROR, ("Could not get mtd value\n")); - return 1; + strcpy(mess, "Could not get mtd drive to flash (strtok fail).\n"); + LOG(logERROR, (mess)); + return FAIL; } - strcat(mtdvalue, pch); - LOG(logINFO, ("Flash drive found: %s\n", mtdvalue)); - FPGAdontTouchFlash(); - - // writing the program to flash - *filefp = fopen(mtdvalue, "w"); - if (*filefp == NULL) { - LOG(logERROR, ("Unable to open %s in write mode\n", mtdvalue)); - return 1; - } - LOG(logINFO, ("Flash ready for writing\n")); - - return 0; + memset(flashDriveName, 0, sizeof(flashDriveName)); + strcpy(flashDriveName, "/dev/"); + strcat(flashDriveName, pch); + LOG(logINFO, ("\tFlash drive found: %s\n", flashDriveName)); + return OK; } -int stopWritingFPGAprogram(FILE *filefp) { - LOG(logDEBUG1, ("Stopping of writing FPGA program\n")); +int openFileForFlash(FILE **flashfd, FILE **srcfd, char *mess) { + FPGAdontTouchFlash(); - if (filefp != NULL) { - fclose(filefp); + // open src file + *srcfd = fopen(TEMP_PROG_FILE_NAME, "r"); + if (*srcfd == NULL) { + sprintf(mess, + "Could not flash. Unable to open temp program file %s in read " + "mode\n", + TEMP_PROG_FILE_NAME); + LOG(logERROR, (mess)); + return FAIL; + } + LOG(logDEBUG1, ("Temp file ready for reading\n")); + + // open flash drive for writing + *flashfd = fopen(flashDriveName, "w"); + if (*flashfd == NULL) { + fclose(*srcfd); + sprintf(mess, "Unable to open flash drive %s in write mode\n", + flashDriveName); + LOG(logERROR, (mess)); + return FAIL; + } + LOG(logINFO, ("\tFlash ready for writing\n")); + return OK; +} + +int eraseFlash(char *mess) { + LOG(logINFO, ("\tErasing Flash...\n")); + +#ifdef VIRTUAL + return OK; +#endif + char cmd[MAX_STR_LENGTH] = {0}; + char retvals[MAX_STR_LENGTH] = {0}; + sprintf(cmd, "flash_eraseall %s", flashDriveName); + if (FAIL == executeCommand(cmd, retvals, logDEBUG1)) { + strcpy(mess, "Could not program fpga. (could not erase flash: "); + strncat(mess, retvals, sizeof(mess) - strlen(mess) - 1); + strcat(mess, "\n"); + LOG(logERROR, (mess)); + return FAIL; } - // touch and program + LOG(logINFO, ("\tFlash erased\n")); + return OK; +} + +int writeToFlash(ssize_t fsize, FILE *flashfd, FILE *srcfd, char *mess) { + LOG(logDEBUG1, ("writing to flash\n")); + + + char* buffer = malloc(FLASH_BUFFER_MEMORY_SIZE); + if (buffer == NULL) { + fclose(flashfd); + fclose(srcfd); + strcpy(mess, "Could not program fpga. Memory allocation to write to " + "flash failed.\n"); + LOG(logERROR, (mess)); + return FAIL; + } + LOG(logINFO, ("\tWriting to Flash...\n")); + + int oldProgress = 0; + ssize_t totalBytes = 0; + ssize_t bytes = fread((void*)buffer, sizeof(char), FLASH_BUFFER_MEMORY_SIZE, srcfd); + + while (bytes > 0) { + + ssize_t bytesWritten = + fwrite((void*)buffer, sizeof(char), bytes, flashfd); + totalBytes += bytesWritten; + + if (bytesWritten != bytes) { + free(buffer); + fclose(flashfd); + fclose(srcfd); + sprintf(mess, + "Could not write to flash (bytes written:%ld, expected: " + "%ld, total written:%ld)\n", + (long int)bytesWritten, (long int)bytes, + (long int)totalBytes); + LOG(logERROR, (mess)); + return FAIL; + } + + // print progress + if (fsize > 0) { + int progress = (int)(((double)(totalBytes) / fsize) * 100); + if (oldProgress != progress) { + printf("%d%%\r", progress); + fflush(stdout); + oldProgress = progress; + } + } else printf("."); + + bytes = fread((void*)buffer, sizeof(char), FLASH_BUFFER_MEMORY_SIZE, srcfd); + } + if (fsize <= 0) { + printf("\n"); + } + free(buffer); + fclose(flashfd); + fclose(srcfd); + LOG(logINFO, ("\tWrote %ld bytes to flash\n", totalBytes)); + + if (totalBytes != fsize) { + sprintf(mess, "Could not program fpga. Incorrect bytes written to flash %lu [expected: %lu]\n", totalBytes, fsize); + LOG(logERROR, (mess)); + return FAIL; + } + return OK; +} + +int waitForFPGAtoTouchFlash(char* mess) { + // touch and program FPGATouchFlash(); - LOG(logINFO, ("Waiting for FPGA to program from flash\n")); - // waiting for success or done - char output[255]; - int res = 0; +#ifdef VIRTUAL + return OK; +#endif + LOG(logINFO, ("\tWaiting for FPGA to program from flash\n")); int timeSpent = 0; - while (res == 0) { + + int result = 0; + while (result == 0) { // time taken for fpga to pick up from flash usleep(1000); timeSpent += 1000; if (timeSpent >= MAX_TIME_FPGA_TOUCH_FLASH_US) { - return 1; + sprintf(mess, "Could not program fpga. (exceeded max time allowed: %ds)\n", + MAX_TIME_FPGA_TOUCH_FLASH_US/(1000 * 1000)); + LOG(logERROR, (mess)); + return FAIL; } - FILE *sysFile = popen("cat /sys/class/gpio/gpio7/value", "r"); - fgets(output, sizeof(output), sysFile); - pclose(sysFile); - sscanf(output, "%d", &res); - LOG(logDEBUG1, ("gpi07 returned %d\n", res)); - } - LOG(logINFO, ("FPGA has picked up the program from flash\n")); - return 0; -} -int writeFPGAProgram(char *fpgasrc, uint64_t fsize, FILE *filefp) { - LOG(logDEBUG1, - ("Writing of FPGA Program\n" - "\taddress of fpgasrc:%p\n" - "\tfsize:%llu\n\tpointer:%p\n", - (void *)fpgasrc, (long long unsigned int)fsize, (void *)filefp)); + // read gpio status + char retvals[MAX_STR_LENGTH] = {0}; + if (FAIL == executeCommand(CMD_FPGA_PICKED_STATUS, retvals, logDEBUG1)) { + strcpy(mess, + "Could not program fpga. (could not read gpio status: "); + strncat(mess, retvals, sizeof(mess) - strlen(mess) - 1); + strcat(mess, "\n"); + LOG(logERROR, (mess)); + return FAIL; + } - if (fwrite((void *)fpgasrc, sizeof(char), fsize, filefp) != fsize) { - LOG(logERROR, ("Could not write FPGA source to flash (size:%llu)\n", - (long long unsigned int)fsize)); - return 1; + // convert to int + if (sscanf(retvals, "%d\n", &result) != 1) { + sprintf(mess, "Could not program fpga. (could not scan int for gpio status: [%s])\n", + retvals); + LOG(logERROR, (mess)); + return FAIL; + } + LOG(logDEBUG1, ("gpi07 returned %d\n", result)); } - LOG(logDEBUG1, ("program written to flash\n")); - return 0; + LOG(logINFO, ("\tFPGA has picked up the program from flash\n")); + return OK; } diff --git a/slsDetectorServers/slsDetectorServer/src/programFpgaNios.c b/slsDetectorServers/slsDetectorServer/src/programFpgaNios.c index bfd5957c3..08dbe4f13 100644 --- a/slsDetectorServers/slsDetectorServer/src/programFpgaNios.c +++ b/slsDetectorServers/slsDetectorServer/src/programFpgaNios.c @@ -1,5 +1,6 @@ #include "programFpgaNios.h" #include "clogger.h" +#include "common.h" #include "sls/ansi.h" #include "slsDetectorServer_defs.h" @@ -7,10 +8,15 @@ #include // usleep /* global variables */ -#define MTDSIZE 10 -char mtdvalue[MTDSIZE] = {0}; + +#define CMD_GET_FLASH "awk \'$5== \"Application\" {print $1}\' /proc/mtd" + +#define FLASH_DRIVE_NAME_SIZE 16 +char flashDriveName[FLASH_DRIVE_NAME_SIZE] = {0}; #define MICROCONTROLLER_FILE "/dev/ttyAL0" +extern int executeCommand(char *command, char *result, enum TLogLevel level); + void NotifyServerStartSuccess() { LOG(logINFOBLUE, ("Server started successfully\n")); char command[255]; @@ -27,7 +33,44 @@ void rebootControllerAndFPGA() { system(command); } -int findFlash(char *mess) { +int eraseAndWriteToFlash(char *mess, char *checksum, char *fpgasrc, + uint64_t fsize) { + + if (verifyChecksumFromBuffer(mess, checksum, fpgasrc, fsize) == FAIL) { + return FAIL; + } + + if (getDrive(mess) == FAIL) { + return FAIL; + } + + FILE *flashfd = NULL; + if (openFileForFlash(&flashfd, mess) == FAIL) { + return FAIL; + } + + if (eraseFlash(mess) == FAIL) { + fclose(flashfd); + return FAIL; + } + + if (writeToFlash(fsize, flashfd, fpgasrc, mess) == FAIL) { + return FAIL; + } + /* ignoring this until a consistent way to read from nios flash + if (verifyChecksumFromFlash(mess, checksum, flashDriveName, fsize) == + FAIL) { + return FAIL; + } + */ + return OK; +} + +int getDrive(char *mess) { +#ifdef VIRTUAL + strcpy(flashDriveName, "/tmp/SLS_mtd3"); + return OK; +#endif LOG(logDEBUG1, ("Finding flash drive...\n")); // getting the drive // # cat /proc/mtd @@ -38,82 +81,78 @@ int findFlash(char *mess) { // mtd3: 00800000 00010000 "qspi Linux Kernel with initramfs Backup" // mtd4: 02500000 00010000 "qspi ubi filesystem" // mtd5: 04000000 00010000 "qspi Complete Flash" - char output[255]; - memset(output, 0, 255); - FILE *fp = popen("awk \'$5== \"Application\" {print $1}\' /proc/mtd", "r"); - if (fp == NULL) { - strcpy(mess, "popen returned NULL. Need that to get mtd drive.\n"); + + char cmd[MAX_STR_LENGTH] = {0}; + char retvals[MAX_STR_LENGTH] = {0}; + strcpy(cmd, CMD_GET_FLASH); + if (executeCommand(cmd, retvals, logDEBUG1) == FAIL) { + strcpy(mess, "Could not program fpga. (could not get flash drive: "); + strncat(mess, retvals, sizeof(mess) - strlen(mess) - 1); + strcat(mess, "\n"); LOG(logERROR, (mess)); return FAIL; } - if (fgets(output, sizeof(output), fp) == NULL) { - strcpy(mess, "fgets returned NULL. Need that to get mtd drive.\n"); - LOG(logERROR, (mess)); - return FAIL; - } - pclose(fp); - memset(mtdvalue, 0, MTDSIZE); - strcpy(mtdvalue, "/dev/"); - char *pch = strtok(output, ":"); + + char *pch = strtok(retvals, ":"); if (pch == NULL) { - strcpy(mess, "Could not get mtd value\n"); + strcpy(mess, "Could not get mtd drive to flash (strtok fail).\n"); LOG(logERROR, (mess)); return FAIL; } - strcat(mtdvalue, pch); - LOG(logINFO, ("\tFlash drive found: %s\n", mtdvalue)); + + memset(flashDriveName, 0, sizeof(flashDriveName)); + strcpy(flashDriveName, "/dev/"); + strcat(flashDriveName, pch); + LOG(logINFO, ("\tFlash drive found: %s\n", flashDriveName)); return OK; } -void eraseFlash() { - LOG(logDEBUG1, ("Erasing Flash...\n")); - char command[255]; - memset(command, 0, 255); - sprintf(command, "flash_erase %s 0 0", mtdvalue); - system(command); - LOG(logINFO, ("\tFlash erased\n")); -} - -int eraseAndWriteToFlash(char *mess, char *fpgasrc, uint64_t fsize) { - if (findFlash(mess) == FAIL) { - return FAIL; - } - eraseFlash(); - - // open file pointer to flash - FILE *filefp = fopen(mtdvalue, "w"); - if (filefp == NULL) { - sprintf(mess, "Unable to open %s in write mode\n", mtdvalue); +int openFileForFlash(FILE **flashfd, char *mess) { + *flashfd = fopen(flashDriveName, "w"); + if (*flashfd == NULL) { + sprintf(mess, "Unable to open flash drive %s in write mode\n", + flashDriveName); LOG(logERROR, (mess)); return FAIL; } LOG(logINFO, ("\tFlash ready for writing\n")); - - // write to flash - if (writeFPGAProgram(mess, fpgasrc, fsize, filefp) == FAIL) { - fclose(filefp); - return FAIL; - } - - fclose(filefp); return OK; } -int writeFPGAProgram(char *mess, char *fpgasrc, uint64_t fsize, FILE *filefp) { - LOG(logDEBUG1, ("Writing to flash...\n" - "\taddress of fpgasrc:%p\n" - "\tfsize:%lu\n\tpointer:%p\n", - (void *)fpgasrc, fsize, (void *)filefp)); +int eraseFlash(char *mess) { + LOG(logINFO, ("\tErasing Flash...\n")); - uint64_t retval = fwrite((void *)fpgasrc, sizeof(char), fsize, filefp); - if (retval != fsize) { - sprintf( - mess, - "Could not write FPGA source to flash (size:%llu), write %llu\n", - (long long unsigned int)fsize, (long long unsigned int)retval); +#ifdef VIRTUAL + return OK; +#endif + char cmd[MAX_STR_LENGTH] = {0}; + char retvals[MAX_STR_LENGTH] = {0}; + sprintf(cmd, "flash_erase %s 0 0", flashDriveName); + if (FAIL == executeCommand(cmd, retvals, logDEBUG1)) { + strcpy(mess, "Could not program fpga. (could not erase flash: "); + strncat(mess, retvals, sizeof(mess) - strlen(mess) - 1); + strcat(mess, "\n"); LOG(logERROR, (mess)); return FAIL; } - LOG(logINFO, ("\tProgram written to flash\n")); + + LOG(logINFO, ("\tFlash erased\n")); + return OK; +} + +int writeToFlash(ssize_t fsize, FILE *flashfd, char *buffer, char *mess) { + LOG(logINFO, ("\tWriting to Flash...\n")); + + ssize_t bytesWritten = fwrite((void *)buffer, sizeof(char), fsize, flashfd); + if (bytesWritten != fsize) { + fclose(flashfd); + sprintf( + mess, + "Could not program fpga. Incorrect bytes written to flash %lu [expected: %lu]\n", + (long int)bytesWritten, (long int)fsize); + LOG(logERROR, (mess)); + return FAIL; + } + LOG(logINFO, ("\tWritten to Flash\n")); return OK; } diff --git a/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c b/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c index 9a01cd4ea..54fcbcf0a 100644 --- a/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c +++ b/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c @@ -14,6 +14,7 @@ #include #include #include +#include // defined in the detector specific Makefile #ifdef GOTTHARDD @@ -444,11 +445,13 @@ int executeCommand(char *command, char *result, enum TLogLevel level) { memset(temp, 0, tempsize); memset(result, 0, MAX_STR_LENGTH); - LOG(level, ("Executing command:\n[%s]\n", command)); - strcat(command, " 2>&1"); + // copy command + char cmd[MAX_STR_LENGTH]= {0}; + sprintf(cmd, "%s 2>&1", command); + LOG(level, ("Executing command:\n[%s]\n", cmd)); fflush(stdout); - FILE *sysFile = popen(command, "r"); + FILE *sysFile = popen(cmd, "r"); while (fgets(temp, tempsize, sysFile) != NULL) { // size left excludes terminating character size_t sizeleft = MAX_STR_LENGTH - strlen(result) - 1; @@ -460,16 +463,19 @@ int executeCommand(char *command, char *result, enum TLogLevel level) { strncat(result, temp, tempsize); memset(temp, 0, tempsize); } - int sucess = pclose(sysFile); + result[MAX_STR_LENGTH - 1] = '\0'; + int success = pclose(sysFile); if (strlen(result)) { - if (sucess) { - sucess = FAIL; + if (success) { + success = FAIL; LOG(logERROR, ("%s\n", result)); } else { LOG(level, ("Result:\n[%s]\n", result)); } + } else { + LOG(level, ("No result\n")); } - return sucess; + return success; } int M_nofunc(int file_des) { @@ -3674,19 +3680,25 @@ int program_fpga(int file_des) { n = receiveData(file_des, mess, MAX_STR_LENGTH, OTHER); functionNotImplemented(); #else -#ifndef VIRTUAL // only set if (Server_VerifyLock() == OK) { LOG(logINFOBLUE, ("Programming FPGA...\n")); -#if defined(MYTHEN3D) || defined(GOTTHARD2D) - uint64_t filesize = 0; // filesize + uint64_t filesize = 0; if (receiveData(file_des, &filesize, sizeof(filesize), INT64) < 0) return printSocketReadError(); - LOG(logDEBUG1, ("Total program size is: %llx\n", - (long long unsigned int)filesize)); + LOG(logDEBUG1, ("Program size is: %lld\n", (long long int)filesize)); + + // checksum + char checksum[MAX_STR_LENGTH]; + memset(checksum, 0, MAX_STR_LENGTH); + if (receiveData(file_des, checksum, MAX_STR_LENGTH, OTHER) < 0) + return printSocketReadError(); + LOG(logDEBUG1, ("checksum is: %s\n\n", checksum)); + +#if defined(MYTHEN3D) || defined(GOTTHARD2D) if (filesize > NIOS_MAX_APP_IMAGE_SIZE) { ret = FAIL; sprintf(mess, @@ -3701,119 +3713,108 @@ int program_fpga(int file_des) { // receive program if (ret == OK) { char *fpgasrc = malloc(filesize); - if (receiveData(file_des, fpgasrc, filesize, OTHER) < 0) + if (receiveData(file_des, fpgasrc, filesize, OTHER) < 0) { + free(fpgasrc); return printSocketReadError(); - - ret = eraseAndWriteToFlash(mess, fpgasrc, filesize); + } + ret = eraseAndWriteToFlash(mess, checksum, fpgasrc, filesize); Server_SendResult(file_des, INT32, NULL, 0); - - // free resources free(fpgasrc); } + if (ret == FAIL) { + LOG(logERROR, ("Program FPGA FAIL!\n")); + return FAIL; + } #else // jungfrau, ctb, moench - uint64_t filesize = 0; - uint64_t totalsize = 0; - uint64_t unitprogramsize = 0; - char *fpgasrc = NULL; - FILE *fp = NULL; - // filesize - if (receiveData(file_des, &filesize, sizeof(filesize), INT32) < 0) - return printSocketReadError(); - totalsize = filesize; - LOG(logDEBUG1, ("Total program size is: %lld\n", - (long long unsigned int)totalsize)); - - // opening file pointer to flash and telling FPGA to not touch flash - if (startWritingFPGAprogram(&fp) != OK) { - ret = FAIL; - sprintf(mess, "Could not write to flash. Error at startup.\n"); - LOG(logERROR, (mess)); + // open file and allocate memory for part program + FILE *fd = NULL; + ret = preparetoCopyFPGAProgram(&fd, filesize, mess); + char *src = NULL; + if (ret == OK) { + src = malloc(MAX_FPGAPROGRAMSIZE); + if (src == NULL) { + fclose(fd); + struct sysinfo info; + sysinfo(&info); + sprintf(mess, "Could not allocate memory to get fpga program. Free space: %d MB\n", (int)(info.freeram/ (1024 * 1024))); + LOG(logERROR, (mess)); + ret = FAIL; + } } Server_SendResult(file_des, INT32, NULL, 0); - - // erasing flash - if (ret != FAIL) { - eraseFlash(); - fpgasrc = malloc(MAX_FPGAPROGRAMSIZE); + if (ret == FAIL) { + LOG(logERROR, ("Program FPGA FAIL1!\n")); + return FAIL; } - // writing to flash part by part - int clientSocketCrash = 0; - while (ret != FAIL && filesize) { - - unitprogramsize = MAX_FPGAPROGRAMSIZE; // 2mb - if (unitprogramsize > filesize) // less than 2mb + // copying program part by part + uint64_t totalsize = filesize; + while (ret == OK && filesize) { + uint64_t unitprogramsize = MAX_FPGAPROGRAMSIZE; // 2mb + if (unitprogramsize > filesize) // less than 2mb unitprogramsize = filesize; - LOG(logDEBUG1, ("unit size to receive is:%lld\nfilesize:%lld\n", + LOG(logDEBUG1, ("unit size to receive is:%lld [filesize:%lld]\n", (long long unsigned int)unitprogramsize, (long long unsigned int)filesize)); // receive part of program - if (receiveData(file_des, fpgasrc, unitprogramsize, OTHER) < 0) { + if (receiveData(file_des, src, unitprogramsize, OTHER) < 0) { printSocketReadError(); - clientSocketCrash = 1; + break; + } + + if (unitprogramsize - filesize == 0) { + // src[unitprogramsize] = '\0'; + filesize -= unitprogramsize; + // unitprogramsize++; + } else + filesize -= unitprogramsize; + + // copy program + if (fwrite((void *)src, sizeof(char), unitprogramsize, fd) != + unitprogramsize) { ret = FAIL; - } - // client has not crashed yet, so write to flash and send ret - else { - if (!(unitprogramsize - filesize)) { - fpgasrc[unitprogramsize] = '\0'; - filesize -= unitprogramsize; - unitprogramsize++; - } else - filesize -= unitprogramsize; - - // write part to flash - ret = writeFPGAProgram(fpgasrc, unitprogramsize, fp); - Server_SendResult(file_des, INT32, NULL, 0); - if (ret == FAIL) { - strcpy(mess, "Could not write to flash. Breaking out of " - "program receiving. Try to flash again " - "without rebooting.\n"); - LOG(logERROR, (mess)); - } else { - // print progress - LOG(logINFO, - ("Writing to Flash:%d%%\r", - (int)(((double)(totalsize - filesize) / totalsize) * - 100))); - fflush(stdout); - } - } - } - - if (ret == OK) { - LOG(logINFO, ("Done copying program\n")); - // closing file pointer to flash and informing FPGA - ret = stopWritingFPGAprogram(fp); - if (ret == FAIL) { - strcpy(mess, "Failed to program fpga. FPGA is taking too long " - "to pick up program from flash! Try to flash " - "again without rebooting!\n"); + sprintf(mess, "Could not copy program to /var/tmp (size:%ld)\n", + (long int)unitprogramsize); LOG(logERROR, (mess)); } + Server_SendResult(file_des, INT32, NULL, 0); + if (ret == FAIL) { + break; + } + // print progress + LOG(logINFO, + ("\t%d%%\r", + (int)(((double)(totalsize - filesize) / totalsize) * 100))); + fflush(stdout); + } + free(src); + fclose(fd); + + // checksum of copied program + if (ret == OK) { + ret = + verifyChecksumFromFile(mess, checksum, TEMP_PROG_FILE_NAME); + } + Server_SendResult(file_des, INT32, NULL, 0); + if (ret == FAIL) { + LOG(logERROR, ("Program FPGA FAIL!\n")); + return FAIL; } - // free resources - free(fpgasrc); - if (fp != NULL) - fclose(fp); - - // send final ret (if no client crash) - if (clientSocketCrash == 0) { - Server_SendResult(file_des, INT32, NULL, 0); + // copy to flash + ret = copyToFlash(totalsize, checksum, mess); + Server_SendResult(file_des, INT32, NULL, 0); + if (ret == FAIL) { + LOG(logERROR, ("Program FPGA FAIL!\n")); + return FAIL; } #endif // end of Blackfin programming - if (ret == FAIL) { - LOG(logERROR, ("Program FPGA FAIL!\n")); - } else { - LOG(logINFOGREEN, ("Programming FPGA completed successfully\n")); - } + LOG(logINFOGREEN, ("Programming FPGA completed successfully\n")); } -#endif #endif return ret; } @@ -4322,11 +4323,19 @@ int reboot_controller(int file_des) { Server_SendResult(file_des, INT32, NULL, 0); return GOODBYE; } +#ifdef VIRTUAL + ret = GOODBYE; +#else ret = REBOOT; +#endif #elif EIGERD functionNotImplemented(); +#else +#ifdef VIRTUAL + ret = GOODBYE; #else ret = REBOOT; +#endif #endif Server_SendResult(file_des, INT32, NULL, 0); return ret; @@ -4783,7 +4792,7 @@ int set_read_n_rows(int file_des) { LOG(logERROR, (mess)); } else #elif JUNGFRAUD - if ((check_detector_idle("set nmber of rows") == OK) && (arg % READ_N_ROWS_MULTIPLE != 0)) { + if ((check_detector_idle("set number of rows") == OK) && (arg % READ_N_ROWS_MULTIPLE != 0)) { ret = FAIL; sprintf(mess, "Could not set number of rows. %d must be a multiple " diff --git a/slsDetectorSoftware/src/DetectorImpl.cpp b/slsDetectorSoftware/src/DetectorImpl.cpp index edc4440a4..9ea7f2213 100644 --- a/slsDetectorSoftware/src/DetectorImpl.cpp +++ b/slsDetectorSoftware/src/DetectorImpl.cpp @@ -1266,7 +1266,6 @@ std::vector DetectorImpl::readProgrammingFile(const std::string &fname) { << "Updating Firmware. This can take awhile. Please be patient..."; LOG(logDEBUG1) << "Programming FPGA with file name:" << fname; - size_t filesize = 0; // check if it exists struct stat st; if (stat(fname.c_str(), &st) != 0) { @@ -1281,6 +1280,16 @@ std::vector DetectorImpl::readProgrammingFile(const std::string &fname) { fname); } + // get srcSize to print progress + if (fseek(src, 0, SEEK_END) != 0) { + throw RuntimeError("Program FPGA: Seek error in src file"); + } + size_t srcSize = ftell(src); + if (srcSize <= 0) { + throw RuntimeError("Program FPGA: Could not get length of source file"); + } + rewind(src); + // create temp destination file char destfname[] = "/tmp/SLS_DET_MCB.XXXXXX"; int dst = mkstemp(destfname); // create temporary file and open it in r/w @@ -1294,6 +1303,7 @@ std::vector DetectorImpl::readProgrammingFile(const std::string &fname) { // convert src to dst rawbin LOG(logDEBUG1) << "Converting " << fname << " to " << destfname; + LOG(logINFO) << "Converting program to rawbin"; { constexpr int pofNumHeaderBytes = 0x11C; constexpr int pofFooterOfst = 0x1000000; @@ -1312,7 +1322,15 @@ std::vector DetectorImpl::readProgrammingFile(const std::string &fname) { } } // Swap bits from source and write to dest + int oldProgress = 0; while (!feof(src)) { + // print progress + int progress = (int)(((double)(dstFilePos) / srcSize) * 100); + if (oldProgress != progress) { + printf("%d%%\r", progress); + fflush(stdout); + oldProgress = progress; + } // pof: exit early to discard footer if (isPof && dstFilePos >= pofFooterOfst) { break; @@ -1342,9 +1360,10 @@ std::vector DetectorImpl::readProgrammingFile(const std::string &fname) { if (close(dst) != 0) { throw RuntimeError("Program FPGA: Could not close destination file"); } - LOG(logDEBUG1) << "File has been converted to " << destfname; + LOG(logINFOBLUE) << "File has been converted to " << destfname; // loading dst file to memory + // FILE *fp = fopen("/tmp/SLS_DET_MCB.tzgmUT", "r"); FILE *fp = fopen(destfname, "r"); if (fp == nullptr) { throw RuntimeError("Program FPGA: Could not open rawbin file"); @@ -1352,7 +1371,7 @@ std::vector DetectorImpl::readProgrammingFile(const std::string &fname) { if (fseek(fp, 0, SEEK_END) != 0) { throw RuntimeError("Program FPGA: Seek error in rawbin file"); } - filesize = ftell(fp); + size_t filesize = ftell(fp); if (filesize <= 0) { throw RuntimeError("Program FPGA: Could not get length of rawbin file"); } @@ -1367,9 +1386,10 @@ std::vector DetectorImpl::readProgrammingFile(const std::string &fname) { throw RuntimeError( "Program FPGA: Could not close destination file after converting"); } - unlink(destfname); // delete temporary file + + //unlink(destfname); // delete temporary file LOG(logDEBUG1) << "Successfully loaded the rawbin file to program memory"; - LOG(logINFO) << "Read file into memory"; + LOG(logDEBUG1) << "Read file into memory"; return buffer; } diff --git a/slsDetectorSoftware/src/Module.cpp b/slsDetectorSoftware/src/Module.cpp index bdda7310e..9ad65141a 100644 --- a/slsDetectorSoftware/src/Module.cpp +++ b/slsDetectorSoftware/src/Module.cpp @@ -5,11 +5,13 @@ #include "sls/bit_utils.h" #include "sls/container_utils.h" #include "sls/file_utils.h" +#include "sls/md5_helper.h" #include "sls/network_utils.h" #include "sls/sls_detector_exceptions.h" #include "sls/sls_detector_funcs.h" #include "sls/string_utils.h" #include "sls/versionAPI.h" + #include #include #include @@ -3405,56 +3407,41 @@ sls_detector_module Module::readSettingsFile(const std::string &fname, } void Module::programFPGAviaBlackfin(std::vector buffer) { - uint64_t filesize = buffer.size(); // send program from memory to detector - LOG(logINFO) << "Sending programming binary (from pof) to detector " + LOG(logINFO) << "Sending programming binary (from pof) to module " << moduleIndex << " (" << shm()->hostname << ")"; auto client = DetectorSocket(shm()->hostname, shm()->controlPort); client.Send(F_PROGRAM_FPGA); + uint64_t filesize = buffer.size(); client.Send(filesize); - // error in detector at opening file pointer to flash + + // checksum + std::string checksum = sls::md5_calculate_checksum(buffer.data(), filesize); + LOG(logDEBUG1) << "Checksum:" << checksum; + char cChecksum[MAX_STR_LENGTH]; + memset(cChecksum, 0, MAX_STR_LENGTH); + strcpy(cChecksum, checksum.c_str()); + client.Send(cChecksum); + + // opening file fail if (client.Receive() == FAIL) { + std::cout << '\n'; std::ostringstream os; os << "Detector " << moduleIndex << " (" << shm()->hostname << ")" << " returned error: " << client.readErrorMessage(); throw RuntimeError(os.str()); } - // erasing flash - LOG(logINFO) << "Erasing Flash for detector " << moduleIndex << " (" - << shm()->hostname << ")"; - printf("%d%%\r", 0); - std::cout << std::flush; - // erasing takes 65 seconds, printing here (otherwise need threads - // in server-unnecessary) - const int ERASE_TIME = 65; - int count = ERASE_TIME + 1; - while (count > 0) { - std::this_thread::sleep_for(std::chrono::seconds(1)); - --count; - printf( - "%d%%\r", - static_cast( - (static_cast(ERASE_TIME - count) / ERASE_TIME) * 100)); - std::cout << std::flush; - } - printf("\n"); - LOG(logINFO) << "Writing to Flash to detector " << moduleIndex << " (" - << shm()->hostname << ")"; - printf("%d%%\r", 0); - std::cout << std::flush; - // sending program in parts of 2mb each uint64_t unitprogramsize = 0; int currentPointer = 0; - uint64_t totalsize = filesize; while (filesize > 0) { unitprogramsize = MAX_FPGAPROGRAMSIZE; // 2mb if (unitprogramsize > filesize) { // less than 2mb unitprogramsize = filesize; } - LOG(logDEBUG1) << "unitprogramsize:" << unitprogramsize - << "\t filesize:" << filesize; + LOG(logDEBUG) << "unitprogramsize:" << unitprogramsize + << "\t filesize:" << filesize; client.Send(&buffer[currentPointer], unitprogramsize); if (client.Receive() == FAIL) { @@ -3466,23 +3453,70 @@ void Module::programFPGAviaBlackfin(std::vector buffer) { } filesize -= unitprogramsize; currentPointer += unitprogramsize; - - // print progress - printf( - "%d%%\r", - static_cast( - (static_cast(totalsize - filesize) / totalsize) * 100)); - std::cout << std::flush; } - std::cout << '\n'; - // fpga has picked up from flash successfully + // checksum if (client.Receive() == FAIL) { std::ostringstream os; os << "Detector " << moduleIndex << " (" << shm()->hostname << ")" << " returned error: " << client.readErrorMessage(); throw RuntimeError(os.str()); } + LOG(logINFO) << "Checksum verified for module " << moduleIndex << " (" + << shm()->hostname << ")"; + + // simulating erasing flash + { + LOG(logINFO) << "(Simulating) Erasing Flash for module " << moduleIndex << " (" + << shm()->hostname << ")"; + printf("%d%%\r", 0); + std::cout << std::flush; + // erasing takes 65 seconds, printing here (otherwise need threads + // in server-unnecessary) + const int ERASE_TIME = 65; + int count = ERASE_TIME + 1; + while (count > 0) { + std::this_thread::sleep_for(std::chrono::seconds(1)); + --count; + printf( + "%d%%\r", + static_cast( + (static_cast(ERASE_TIME - count) / ERASE_TIME) * 100)); + std::cout << std::flush; + } + printf("\n"); + } + + // simulating writing to flash + { + LOG(logINFO) << "(Simulating) Writing to Flash for module " << moduleIndex << " (" << shm()->hostname << ")"; + printf("%d%%\r", 0); + std::cout << std::flush; + // writing takes 30 seconds, printing here (otherwise need threads + // in server-unnecessary) + const int ERASE_TIME = 30; + int count = ERASE_TIME + 1; + while (count > 0) { + std::this_thread::sleep_for(std::chrono::seconds(1)); + --count; + printf( + "%d%%\r", + static_cast( + (static_cast(ERASE_TIME - count) / ERASE_TIME) * 100)); + std::cout << std::flush; + } + printf("\n"); + } + + if (client.Receive() == FAIL) { + std::ostringstream os; + os << "Detector " << moduleIndex << " (" << shm()->hostname << ")" + << " returned error: " << client.readErrorMessage(); + throw RuntimeError(os.str()); + } + if (moduleIndex == 0) { + LOG(logINFO) << "Copied to flash and checksum verified"; + } LOG(logINFO) << "FPGA programmed successfully"; rebootController(); @@ -3496,6 +3530,16 @@ void Module::programFPGAviaNios(std::vector buffer) { client.Send(F_PROGRAM_FPGA); uint64_t filesize = buffer.size(); client.Send(filesize); + + // checksum + std::string checksum = sls::md5_calculate_checksum(buffer.data(), filesize); + LOG(logDEBUG1) << "Checksum:" << checksum; + char cChecksum[MAX_STR_LENGTH]; + memset(cChecksum, 0, MAX_STR_LENGTH); + strcpy(cChecksum, checksum.c_str()); + client.Send(cChecksum); + + // validate file size before sending program if (client.Receive() == FAIL) { std::ostringstream os; os << "Detector " << moduleIndex << " (" << shm()->hostname << ")" @@ -3503,6 +3547,49 @@ void Module::programFPGAviaNios(std::vector buffer) { throw RuntimeError(os.str()); } client.Send(buffer); + + // simulating erasing flash + { + LOG(logINFO) << "(Simulating) Erasing Flash for module " << moduleIndex << " (" + << shm()->hostname << ")"; + printf("%d%%\r", 0); + std::cout << std::flush; + // erasing takes 10 seconds, printing here (otherwise need threads + // in server-unnecessary) + const int ERASE_TIME = 10; + int count = ERASE_TIME + 1; + while (count > 0) { + std::this_thread::sleep_for(std::chrono::seconds(1)); + --count; + printf( + "%d%%\r", + static_cast( + (static_cast(ERASE_TIME - count) / ERASE_TIME) * 100)); + std::cout << std::flush; + } + printf("\n"); + } + + // simulating writing to flash + { + LOG(logINFO) << "(Simulating) Writing to Flash for module " << moduleIndex << " (" << shm()->hostname << ")"; + printf("%d%%\r", 0); + std::cout << std::flush; + // writing takes 45 seconds, printing here (otherwise need threads + // in server-unnecessary) + const int ERASE_TIME = 45; + int count = ERASE_TIME + 1; + while (count > 0) { + std::this_thread::sleep_for(std::chrono::seconds(1)); + --count; + printf( + "%d%%\r", + static_cast( + (static_cast(ERASE_TIME - count) / ERASE_TIME) * 100)); + std::cout << std::flush; + } + printf("\n"); + } if (client.Receive() == FAIL) { std::ostringstream os; os << "Detector " << moduleIndex << " (" << shm()->hostname << ")" diff --git a/slsSupportLib/CMakeLists.txt b/slsSupportLib/CMakeLists.txt index cb35702bb..78262d5a7 100755 --- a/slsSupportLib/CMakeLists.txt +++ b/slsSupportLib/CMakeLists.txt @@ -10,7 +10,7 @@ set(SOURCES src/ZmqSocket.cpp src/UdpRxSocket.cpp src/sls_detector_exceptions.cpp - # src/sls_detector_defs.cpp + src/md5_helper.cpp ) # Header files to install as a part of the library @@ -44,9 +44,25 @@ if(SLS_DEVEL_HEADERS) include/sls/versionAPI.h include/sls/ZmqSocket.h include/sls/bit_utils.h + include/sls/mdf5.h + include/sls/md5_helper.h ) endif() + +# Library for md5 c code that we are using (and potentially other c code) +# Maybe this should be broken out into it's own folder etc. +add_library(md5sls STATIC + src/md5.c +) + +target_include_directories(md5sls + PUBLIC + "$" + "$" +) + + # Create an object library to avoid building the library twice add_library(slsSupportObject OBJECT ${SOURCES} @@ -65,7 +81,8 @@ target_link_libraries(slsSupportObject libzmq rapidjson PRIVATE - slsProjectWarnings + slsProjectWarnings + md5sls ) if (SLS_USE_TESTS) @@ -103,6 +120,9 @@ if((CMAKE_BUILD_TYPE STREQUAL "Release") AND SLS_LTO_AVAILABLE) set_property(TARGET ${SUPPORT_LIBRARY_TARGETS} PROPERTY INTERPROCEDURAL_OPTIMIZATION True) endif() + +list(APPEND SUPPORT_LIBRARY_TARGETS md5sls) + install(TARGETS ${SUPPORT_LIBRARY_TARGETS} EXPORT "${TARGETS_EXPORT_NAME}" LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} diff --git a/slsSupportLib/include/sls/md5.h b/slsSupportLib/include/sls/md5.h new file mode 100644 index 000000000..08057dcaf --- /dev/null +++ b/slsSupportLib/include/sls/md5.h @@ -0,0 +1,385 @@ +/* + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ +/* + * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +/* + * Modifications 2021 Paul Scherrer Institut + * Removed most of the code that is not relevant for our scope. + * Snippets copied from md5_local.h or md32_common.h has been marked + */ + + +#ifndef HEADER_MD5_H +# define HEADER_MD5_H + +# include + + +# ifdef __cplusplus +/* + * Modifications 2021 Paul Scherrer Institut + * namespace sls added + */ +namespace sls { +extern "C" { +# endif + +/* + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * ! MD5_LONG has to be at least 32 bits wide. ! + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + */ +# define MD5_LONG unsigned int +# define MD5_CBLOCK 64 +# define MD5_LBLOCK (MD5_CBLOCK/4) +# define MD5_DIGEST_LENGTH 16 + +/** + * Modification 2021 Paul Scherrer Institut + * Comment from md32_common.h + */ +/*- + * This is a generic 32 bit "collector" for message digest algorithms. + * Whenever needed it collects input character stream into chunks of + * 32 bit values and invokes a block function that performs actual hash + * calculations. + * + * Porting guide. + * + * Obligatory macros: + * + * DATA_ORDER_IS_BIG_ENDIAN or DATA_ORDER_IS_LITTLE_ENDIAN + * this macro defines byte order of input stream. + * HASH_CBLOCK + * size of a unit chunk HASH_BLOCK operates on. + * HASH_LONG + * has to be at least 32 bit wide. + * HASH_CTX + * context structure that at least contains following + * members: + * typedef struct { + * ... + * HASH_LONG Nl,Nh; + * either { + * HASH_LONG data[HASH_LBLOCK]; + * unsigned char data[HASH_CBLOCK]; + * }; + * unsigned int num; + * ... + * } HASH_CTX; + * data[] vector is expected to be zeroed upon first call to + * HASH_UPDATE. + * HASH_UPDATE + * name of "Update" function, implemented here. + * HASH_TRANSFORM + * name of "Transform" function, implemented here. + * HASH_FINAL + * name of "Final" function, implemented here. + * HASH_BLOCK_DATA_ORDER + * name of "block" function capable of treating *unaligned* input + * message in original (data) byte order, implemented externally. + * HASH_MAKE_STRING + * macro converting context variables to an ASCII hash string. + * + * MD5 example: + * + * #define DATA_ORDER_IS_LITTLE_ENDIAN + * + * #define HASH_LONG MD5_LONG + * #define HASH_CTX MD5_CTX + * #define HASH_CBLOCK MD5_CBLOCK + * #define HASH_UPDATE MD5_Update_SLS + * #define HASH_TRANSFORM MD5_Transform + * #define HASH_FINAL MD5_Final_SLS + * #define HASH_BLOCK_DATA_ORDER md5_block_data_order + */ +# define MD32_REG_T int + +/** + * Modification 2021 Paul Scherrer Institut + * Made default little endian if big endian not defined + */ +#ifndef DATA_ORDER_IS_BIG_ENDIAN +#define DATA_ORDER_IS_LITTLE_ENDIAN +#endif + +/** + * Modification 2021 Paul Scherrer Institut + * Macros exported from md32_common.h + */ +#define HASH_LONG MD5_LONG +#define HASH_CTX MD5_CTX +#define HASH_CBLOCK MD5_CBLOCK +#define HASH_UPDATE MD5_Update_SLS +#define HASH_TRANSFORM MD5_Transform +#define HASH_FINAL MD5_Final_SLS +#define HASH_BLOCK_DATA_ORDER md5_block_data_order +#define HASH_MAKE_STRING(c,s) do { \ + unsigned long ll; \ + ll=(c)->A; (void)HOST_l2c(ll,(s)); \ + ll=(c)->B; (void)HOST_l2c(ll,(s)); \ + ll=(c)->C; (void)HOST_l2c(ll,(s)); \ + ll=(c)->D; (void)HOST_l2c(ll,(s)); \ + } while (0) +#define ROTATE(a,n) (((a)<<(n))|(((a)&0xffffffff)>>(32-(n)))) +#if defined(DATA_ORDER_IS_BIG_ENDIAN) + +# define HOST_c2l(c,l) (l =(((unsigned long)(*((c)++)))<<24), \ + l|=(((unsigned long)(*((c)++)))<<16), \ + l|=(((unsigned long)(*((c)++)))<< 8), \ + l|=(((unsigned long)(*((c)++))) ) ) +# define HOST_l2c(l,c) (*((c)++)=(unsigned char)(((l)>>24)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16)&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ + *((c)++)=(unsigned char)(((l) )&0xff), \ + l) + +#elif defined(DATA_ORDER_IS_LITTLE_ENDIAN) + +# define HOST_c2l(c,l) (l =(((unsigned long)(*((c)++))) ), \ + l|=(((unsigned long)(*((c)++)))<< 8), \ + l|=(((unsigned long)(*((c)++)))<<16), \ + l|=(((unsigned long)(*((c)++)))<<24) ) +# define HOST_l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16)&0xff), \ + *((c)++)=(unsigned char)(((l)>>24)&0xff), \ + l) + +#endif + + + + + +typedef struct MD5state_st { + MD5_LONG A, B, C, D; + MD5_LONG Nl, Nh; + MD5_LONG data[MD5_LBLOCK]; + unsigned int num; +} MD5_CTX; + +int MD5_Init_SLS(MD5_CTX *c); +int MD5_Update_SLS(MD5_CTX *c, const void *data, size_t len); +int MD5_Final_SLS(unsigned char *md, MD5_CTX *c); + +/** + * Modification 2021 Paul Scherrer Institut + * from md32_common.h + */ +void md5_block_data_order(MD5_CTX *c, const void *p, size_t num); +# ifdef __cplusplus +} + +} // namespace sls +# endif +# endif + diff --git a/slsSupportLib/include/sls/md5_helper.h b/slsSupportLib/include/sls/md5_helper.h new file mode 100644 index 000000000..07ef38d8b --- /dev/null +++ b/slsSupportLib/include/sls/md5_helper.h @@ -0,0 +1,7 @@ +#pragma once + +#include + +namespace sls { +std::string md5_calculate_checksum(char *buffer, ssize_t bytes); +} // namespace sls \ No newline at end of file diff --git a/slsSupportLib/include/sls/sls_detector_defs.h b/slsSupportLib/include/sls/sls_detector_defs.h index 85d10288f..2bb69285b 100644 --- a/slsSupportLib/include/sls/sls_detector_defs.h +++ b/slsSupportLib/include/sls/sls_detector_defs.h @@ -54,7 +54,8 @@ #define MAX_TRIMEN 100 /** maximum unit size of program sent to detector */ -#define MAX_FPGAPROGRAMSIZE (2 * 1024 * 1024) +//#define MAX_FPGAPROGRAMSIZE (2 * 1024 * 1024) +#define MAX_FPGAPROGRAMSIZE (128 * 1024) #define GET_FLAG -1 diff --git a/slsSupportLib/include/sls/versionAPI.h b/slsSupportLib/include/sls/versionAPI.h index 556c634f8..208b017d7 100644 --- a/slsSupportLib/include/sls/versionAPI.h +++ b/slsSupportLib/include/sls/versionAPI.h @@ -4,11 +4,10 @@ #define APIRECEIVER 0x210831 #define APIGUI 0x210819 - -#define APICTB 0x210909 -#define APIGOTTHARD 0x210909 -#define APIGOTTHARD2 0x210909 -#define APIJUNGFRAU 0x210909 -#define APIMYTHEN3 0x210909 -#define APIMOENCH 0x210909 -#define APIEIGER 0x210909 +#define APICTB 0x210916 +#define APIGOTTHARD 0x210916 +#define APIGOTTHARD2 0x210916 +#define APIJUNGFRAU 0x210916 +#define APIMYTHEN3 0x210916 +#define APIMOENCH 0x210916 +#define APIEIGER 0x210916 diff --git a/slsSupportLib/src/md5.c b/slsSupportLib/src/md5.c new file mode 100644 index 000000000..b8508620e --- /dev/null +++ b/slsSupportLib/src/md5.c @@ -0,0 +1,515 @@ +/* + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ +/* + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +/* + * MD5 low level APIs are deprecated for public use, but still ok for + * internal use. + */ + +/* + * Modifications 2021 Paul Scherrer Institut + * Removed most of the code that is not relevant for our scope + * from md5_dgst.c and renamed to md5.c + * from md32_common.h and replaced their macros with their defines + */ + +#include + +/** + * Modification 2021 Paul Scherrer Institut + * Header included was md5_local.h + * and string.h header was included + * sls namespace added + */ +#include "sls/md5.h" +#include +#ifdef __cplusplus +namespace sls { +#endif + +/** + * Modification 2021 Paul Scherrer Institut + * Macros exported from md5_local.h + */ +#define F(b,c,d) ((((c) ^ (d)) & (b)) ^ (d)) +#define G(b,c,d) ((((b) ^ (c)) & (d)) ^ (c)) +#define H(b,c,d) ((b) ^ (c) ^ (d)) +#define I(b,c,d) (((~(d)) | (b)) ^ (c)) + +#define R0(a,b,c,d,k,s,t) { \ + a+=((k)+(t)+F((b),(c),(d))); \ + a=ROTATE(a,s); \ + a+=b; }; + +#define R1(a,b,c,d,k,s,t) { \ + a+=((k)+(t)+G((b),(c),(d))); \ + a=ROTATE(a,s); \ + a+=b; }; + +#define R2(a,b,c,d,k,s,t) { \ + a+=((k)+(t)+H((b),(c),(d))); \ + a=ROTATE(a,s); \ + a+=b; }; + +#define R3(a,b,c,d,k,s,t) { \ + a+=((k)+(t)+I((b),(c),(d))); \ + a=ROTATE(a,s); \ + a+=b; }; + + + +/* + * Implemented from RFC1321 The MD5 Message-Digest Algorithm + */ + +#define INIT_DATA_A (unsigned long)0x67452301L +#define INIT_DATA_B (unsigned long)0xefcdab89L +#define INIT_DATA_C (unsigned long)0x98badcfeL +#define INIT_DATA_D (unsigned long)0x10325476L + +int MD5_Init_SLS(MD5_CTX *c) +{ + memset(c, 0, sizeof(*c)); + c->A = INIT_DATA_A; + c->B = INIT_DATA_B; + c->C = INIT_DATA_C; + c->D = INIT_DATA_D; + return 1; +} + +void md5_block_data_order(MD5_CTX *c, const void *data_, size_t num) +{ + const unsigned char *data = data_; + register unsigned MD32_REG_T A, B, C, D, l; + /* See comment in crypto/sha/sha_local.h for details. */ + unsigned MD32_REG_T XX0, XX1, XX2, XX3, XX4, XX5, XX6, XX7, + XX8, XX9, XX10, XX11, XX12, XX13, XX14, XX15; +# define X(i) XX##i + + A = c->A; + B = c->B; + C = c->C; + D = c->D; + + for (; num--;) { + (void)HOST_c2l(data, l); + X(0) = l; + (void)HOST_c2l(data, l); + X(1) = l; + /* Round 0 */ + R0(A, B, C, D, X(0), 7, 0xd76aa478L); + (void)HOST_c2l(data, l); + X(2) = l; + R0(D, A, B, C, X(1), 12, 0xe8c7b756L); + (void)HOST_c2l(data, l); + X(3) = l; + R0(C, D, A, B, X(2), 17, 0x242070dbL); + (void)HOST_c2l(data, l); + X(4) = l; + R0(B, C, D, A, X(3), 22, 0xc1bdceeeL); + (void)HOST_c2l(data, l); + X(5) = l; + R0(A, B, C, D, X(4), 7, 0xf57c0fafL); + (void)HOST_c2l(data, l); + X(6) = l; + R0(D, A, B, C, X(5), 12, 0x4787c62aL); + (void)HOST_c2l(data, l); + X(7) = l; + R0(C, D, A, B, X(6), 17, 0xa8304613L); + (void)HOST_c2l(data, l); + X(8) = l; + R0(B, C, D, A, X(7), 22, 0xfd469501L); + (void)HOST_c2l(data, l); + X(9) = l; + R0(A, B, C, D, X(8), 7, 0x698098d8L); + (void)HOST_c2l(data, l); + X(10) = l; + R0(D, A, B, C, X(9), 12, 0x8b44f7afL); + (void)HOST_c2l(data, l); + X(11) = l; + R0(C, D, A, B, X(10), 17, 0xffff5bb1L); + (void)HOST_c2l(data, l); + X(12) = l; + R0(B, C, D, A, X(11), 22, 0x895cd7beL); + (void)HOST_c2l(data, l); + X(13) = l; + R0(A, B, C, D, X(12), 7, 0x6b901122L); + (void)HOST_c2l(data, l); + X(14) = l; + R0(D, A, B, C, X(13), 12, 0xfd987193L); + (void)HOST_c2l(data, l); + X(15) = l; + R0(C, D, A, B, X(14), 17, 0xa679438eL); + R0(B, C, D, A, X(15), 22, 0x49b40821L); + /* Round 1 */ + R1(A, B, C, D, X(1), 5, 0xf61e2562L); + R1(D, A, B, C, X(6), 9, 0xc040b340L); + R1(C, D, A, B, X(11), 14, 0x265e5a51L); + R1(B, C, D, A, X(0), 20, 0xe9b6c7aaL); + R1(A, B, C, D, X(5), 5, 0xd62f105dL); + R1(D, A, B, C, X(10), 9, 0x02441453L); + R1(C, D, A, B, X(15), 14, 0xd8a1e681L); + R1(B, C, D, A, X(4), 20, 0xe7d3fbc8L); + R1(A, B, C, D, X(9), 5, 0x21e1cde6L); + R1(D, A, B, C, X(14), 9, 0xc33707d6L); + R1(C, D, A, B, X(3), 14, 0xf4d50d87L); + R1(B, C, D, A, X(8), 20, 0x455a14edL); + R1(A, B, C, D, X(13), 5, 0xa9e3e905L); + R1(D, A, B, C, X(2), 9, 0xfcefa3f8L); + R1(C, D, A, B, X(7), 14, 0x676f02d9L); + R1(B, C, D, A, X(12), 20, 0x8d2a4c8aL); + /* Round 2 */ + R2(A, B, C, D, X(5), 4, 0xfffa3942L); + R2(D, A, B, C, X(8), 11, 0x8771f681L); + R2(C, D, A, B, X(11), 16, 0x6d9d6122L); + R2(B, C, D, A, X(14), 23, 0xfde5380cL); + R2(A, B, C, D, X(1), 4, 0xa4beea44L); + R2(D, A, B, C, X(4), 11, 0x4bdecfa9L); + R2(C, D, A, B, X(7), 16, 0xf6bb4b60L); + R2(B, C, D, A, X(10), 23, 0xbebfbc70L); + R2(A, B, C, D, X(13), 4, 0x289b7ec6L); + R2(D, A, B, C, X(0), 11, 0xeaa127faL); + R2(C, D, A, B, X(3), 16, 0xd4ef3085L); + R2(B, C, D, A, X(6), 23, 0x04881d05L); + R2(A, B, C, D, X(9), 4, 0xd9d4d039L); + R2(D, A, B, C, X(12), 11, 0xe6db99e5L); + R2(C, D, A, B, X(15), 16, 0x1fa27cf8L); + R2(B, C, D, A, X(2), 23, 0xc4ac5665L); + /* Round 3 */ + R3(A, B, C, D, X(0), 6, 0xf4292244L); + R3(D, A, B, C, X(7), 10, 0x432aff97L); + R3(C, D, A, B, X(14), 15, 0xab9423a7L); + R3(B, C, D, A, X(5), 21, 0xfc93a039L); + R3(A, B, C, D, X(12), 6, 0x655b59c3L); + R3(D, A, B, C, X(3), 10, 0x8f0ccc92L); + R3(C, D, A, B, X(10), 15, 0xffeff47dL); + R3(B, C, D, A, X(1), 21, 0x85845dd1L); + R3(A, B, C, D, X(8), 6, 0x6fa87e4fL); + R3(D, A, B, C, X(15), 10, 0xfe2ce6e0L); + R3(C, D, A, B, X(6), 15, 0xa3014314L); + R3(B, C, D, A, X(13), 21, 0x4e0811a1L); + R3(A, B, C, D, X(4), 6, 0xf7537e82L); + R3(D, A, B, C, X(11), 10, 0xbd3af235L); + R3(C, D, A, B, X(2), 15, 0x2ad7d2bbL); + R3(B, C, D, A, X(9), 21, 0xeb86d391L); + + A = c->A += A; + B = c->B += B; + C = c->C += C; + D = c->D += D; + } +} + +/** + * Modification 2021 Paul Scherrer Institut + * from md32_common.h + */ +int HASH_UPDATE(HASH_CTX *c, const void *data_, size_t len) +{ + const unsigned char *data = data_; + unsigned char *p; + HASH_LONG l; + size_t n; + + if (len == 0) + return 1; + + l = (c->Nl + (((HASH_LONG) len) << 3)) & 0xffffffffUL; + if (l < c->Nl) /* overflow */ + c->Nh++; + c->Nh += (HASH_LONG) (len >> 29); /* might cause compiler warning on + * 16-bit */ + c->Nl = l; + + n = c->num; + if (n != 0) { + p = (unsigned char *)c->data; + + if (len >= HASH_CBLOCK || len + n >= HASH_CBLOCK) { + memcpy(p + n, data, HASH_CBLOCK - n); + HASH_BLOCK_DATA_ORDER(c, p, 1); + n = HASH_CBLOCK - n; + data += n; + len -= n; + c->num = 0; + /* + * We use memset rather than OPENSSL_cleanse() here deliberately. + * Using OPENSSL_cleanse() here could be a performance issue. It + * will get properly cleansed on finalisation so this isn't a + * security problem. + */ + memset(p, 0, HASH_CBLOCK); /* keep it zeroed */ + } else { + memcpy(p + n, data, len); + c->num += (unsigned int)len; + return 1; + } + } + + n = len / HASH_CBLOCK; + if (n > 0) { + HASH_BLOCK_DATA_ORDER(c, data, n); + n *= HASH_CBLOCK; + data += n; + len -= n; + } + + if (len != 0) { + p = (unsigned char *)c->data; + c->num = (unsigned int)len; + memcpy(p, data, len); + } + return 1; +} + +/** + * Modification 2021 Paul Scherrer Institut + * from md32_common.h + */ +int HASH_FINAL(unsigned char *md, HASH_CTX *c) +{ + unsigned char *p = (unsigned char *)c->data; + size_t n = c->num; + + p[n] = 0x80; /* there is always room for one */ + n++; + + if (n > (HASH_CBLOCK - 8)) { + memset(p + n, 0, HASH_CBLOCK - n); + n = 0; + HASH_BLOCK_DATA_ORDER(c, p, 1); + } + memset(p + n, 0, HASH_CBLOCK - 8 - n); + + p += HASH_CBLOCK - 8; +#if defined(DATA_ORDER_IS_BIG_ENDIAN) + (void)HOST_l2c(c->Nh, p); + (void)HOST_l2c(c->Nl, p); +#elif defined(DATA_ORDER_IS_LITTLE_ENDIAN) + (void)HOST_l2c(c->Nl, p); + (void)HOST_l2c(c->Nh, p); +#endif + p -= HASH_CBLOCK; + HASH_BLOCK_DATA_ORDER(c, p, 1); + c->num = 0; + // OPENSSL_cleanse(p, HASH_CBLOCK); + //Erik: Since we don't do encryption secure cleaning is not needed + memset(p, 0, HASH_CBLOCK); + + HASH_MAKE_STRING(c, md); + + return 1; +} + +#ifdef __cplusplus +} // namespace sls +#endif \ No newline at end of file diff --git a/slsSupportLib/src/md5_helper.cpp b/slsSupportLib/src/md5_helper.cpp new file mode 100644 index 000000000..9af895faa --- /dev/null +++ b/slsSupportLib/src/md5_helper.cpp @@ -0,0 +1,30 @@ +#include "sls/md5_helper.h" + +#include "sls/md5.h" + +#include +#include +#include + +namespace sls { + +std::string md5_calculate_checksum(char *buffer, ssize_t bytes) { + MD5_CTX c; + if (!MD5_Init_SLS(&c)) { + throw std::runtime_error( + "Could not calculate md5 checksum.[initializing]"); + } + if (!MD5_Update_SLS(&c, buffer, bytes)) { + throw std::runtime_error("Could not calculate md5 checksum.[Updating]"); + } + unsigned char out[MD5_DIGEST_LENGTH]; + if (!MD5_Final_SLS(out, &c)) { + throw std::runtime_error("Could not calculate md5 checksum.[Final]"); + } + std::ostringstream oss; + for (int i = 0; i != MD5_DIGEST_LENGTH; ++i) + oss << std::hex << std::setw(2) << std::setfill('0') << +out[i]; + return oss.str(); +} + +} // namespace sls