Browse Source

编译通过

guohui 2 years ago
parent
commit
d1cb79dca0
42 changed files with 9827 additions and 8668 deletions
  1. 21 4
      04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/CMakeLists.txt
  2. 1 0
      04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/build/CMakeFiles/Makefile.cmake
  3. 39 2
      04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/build/CMakeFiles/Makefile2
  4. 1 0
      04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/build/CMakeFiles/TargetDirectories.txt
  5. 1 1
      04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/build/CMakeFiles/progress.marks
  6. 224 0
      04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/build/Makefile
  7. 22 0
      04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/config/cfg.h
  8. 0 230
      04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/modbus/config.h
  9. 0 233
      04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/modbus/modbus-data.c
  10. 0 116
      04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/modbus/modbus-private.h
  11. 0 76
      04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/modbus/modbus-rtu-private.h
  12. 0 1299
      04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/modbus/modbus-rtu.c
  13. 0 42
      04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/modbus/modbus-rtu.h
  14. 0 44
      04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/modbus/modbus-tcp-private.h
  15. 0 929
      04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/modbus/modbus-tcp.c
  16. 0 52
      04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/modbus/modbus-tcp.h
  17. 0 53
      04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/modbus/modbus-version.h
  18. 0 1911
      04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/modbus/modbus.c
  19. 0 293
      04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/modbus/modbus.h
  20. 4704 2406
      04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/mongoose/mongoose.c
  21. 601 520
      04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/mongoose/mongoose.h
  22. 73 121
      04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/src/app.c
  23. 4 0
      04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/src/appweb.conf
  24. 500 320
      04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/src/appweb_handle.c
  25. 235 0
      04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/src/cascade.c
  26. 46 0
      04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/src/cascade.h
  27. 3 1
      04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/src/common.c
  28. 19 9
      04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/src/common.h
  29. 51 0
      04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/src/dflt.c
  30. 23 0
      04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/src/modbus_handle.c
  31. 2 0
      04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/src/modbus_handle.h
  32. 187 0
      04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/src/paras.c
  33. 40 0
      04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/src/paras.h
  34. 880 0
      04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/src/sys.c
  35. 57 0
      04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/src/sys.h
  36. 13 6
      04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/src/websocket_handle.c
  37. 851 0
      04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/src/xlist.c
  38. 93 0
      04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/src/xlist.h
  39. 192 0
      04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/upgrade/md5.c
  40. 68 0
      04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/upgrade/md5.h
  41. 753 0
      04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/upgrade/upgrade.c
  42. 123 0
      04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/upgrade/upgrade.h

+ 21 - 4
04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/CMakeLists.txt

@@ -24,13 +24,15 @@ include_directories (${PROJECT_SOURCE_DIR}/mongoose)
 include_directories (${PROJECT_SOURCE_DIR}/sqlite)
 include_directories (${PROJECT_SOURCE_DIR}/modbus)
 include_directories (${PROJECT_SOURCE_DIR}/snmp/include)
+include_directories (${PROJECT_SOURCE_DIR}/upgrade)
+include_directories (${PROJECT_SOURCE_DIR}/config)
 
 
 link_directories(${PROJECT_SOURCE_DIR}/appweb/lib ${PROJECT_SOURCE_DIR}/snmp/lib)
 
 add_definitions("-Wall -g")
 
-set( SRC_LIST
+set(PDU_SRC_LIST
 	${PROJECT_SOURCE_DIR}/letter/src/shell_cmd_list.c
 	${PROJECT_SOURCE_DIR}/letter/src/shell_companion.c
 	${PROJECT_SOURCE_DIR}/letter/src/shell_ext.c
@@ -60,7 +62,12 @@ set( SRC_LIST
 	${PROJECT_SOURCE_DIR}/src/sqlite_handle.c
 	${PROJECT_SOURCE_DIR}/src/switch_ctrl.c
 	${PROJECT_SOURCE_DIR}/src/json_handle.c
-	${PROJECT_SOURCE_DIR}/src/main.c
+	${PROJECT_SOURCE_DIR}/src/sys.c
+	${PROJECT_SOURCE_DIR}/src/dflt.c
+	${PROJECT_SOURCE_DIR}/src/paras.c
+	${PROJECT_SOURCE_DIR}/src/xlist.c
+	${PROJECT_SOURCE_DIR}/src/cascade.c
+	${PROJECT_SOURCE_DIR}/src/main.c	
 
 	${PROJECT_SOURCE_DIR}/modbus/modbus.c
 	${PROJECT_SOURCE_DIR}/modbus/modbus-data.c
@@ -75,10 +82,20 @@ set( SRC_LIST
 	${PROJECT_SOURCE_DIR}/src/pduMIB_scalar.c
 	${PROJECT_SOURCE_DIR}/src/pduMIB_trap.c)
 
-add_executable(smartPDU ${SRC_LIST})
 
+set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
 
-target_link_libraries (smartPDU -lappweb -lesp -lhttp -lmpr -lpcre -lc -ldl -lpthread -lnetsnmp -lnetsnmpagent)
 
+add_executable(smartPDU ${PDU_SRC_LIST})
+target_link_libraries(smartPDU -lappweb -lesp -lhttp -lmpr -lpcre -lc -ldl -lpthread -lnetsnmp -lnetsnmpagent)
+
+
+set(UPG_SRC_LIST
+	${PROJECT_SOURCE_DIR}/upgrade/md5.c
+	${PROJECT_SOURCE_DIR}/upgrade/upgrade.c)
+	
+add_executable(smartUPG ${UPG_SRC_LIST})
+target_link_libraries(smartUPG -lc -lpthread)
 
 

+ 1 - 0
04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/build/CMakeFiles/Makefile.cmake

@@ -42,4 +42,5 @@ set(CMAKE_MAKEFILE_PRODUCTS
 # Dependency information for all targets:
 set(CMAKE_DEPEND_INFO_FILES
   "CMakeFiles/smartPDU.dir/DependInfo.cmake"
+  "CMakeFiles/smartUPG.dir/DependInfo.cmake"
   )

+ 39 - 2
04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/build/CMakeFiles/Makefile2

@@ -66,7 +66,7 @@ CMAKE_BINARY_DIR = /home/tronlong/pdu/SmartPDUPro/04-软件设计及源码/03-
 CMakeFiles/smartPDU.dir/all:
 	$(MAKE) -f CMakeFiles/smartPDU.dir/build.make CMakeFiles/smartPDU.dir/depend
 	$(MAKE) -f CMakeFiles/smartPDU.dir/build.make CMakeFiles/smartPDU.dir/build
-	@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --progress-dir=/home/tronlong/pdu/SmartPDUPro/04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/build/CMakeFiles --progress-num=1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38 "Built target smartPDU"
+	@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --progress-dir=/home/tronlong/pdu/SmartPDUPro/04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/build/CMakeFiles --progress-num=1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43 "Built target smartPDU"
 .PHONY : CMakeFiles/smartPDU.dir/all
 
 # Include target in all.
@@ -76,7 +76,7 @@ all: CMakeFiles/smartPDU.dir/all
 
 # Build rule for subdir invocation for target.
 CMakeFiles/smartPDU.dir/rule: cmake_check_build_system
-	$(CMAKE_COMMAND) -E cmake_progress_start /home/tronlong/pdu/SmartPDUPro/04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/build/CMakeFiles 38
+	$(CMAKE_COMMAND) -E cmake_progress_start /home/tronlong/pdu/SmartPDUPro/04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/build/CMakeFiles 43
 	$(MAKE) -f CMakeFiles/Makefile2 CMakeFiles/smartPDU.dir/all
 	$(CMAKE_COMMAND) -E cmake_progress_start /home/tronlong/pdu/SmartPDUPro/04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/build/CMakeFiles 0
 .PHONY : CMakeFiles/smartPDU.dir/rule
@@ -96,6 +96,43 @@ clean: CMakeFiles/smartPDU.dir/clean
 
 .PHONY : clean
 
+#=============================================================================
+# Target rules for target CMakeFiles/smartUPG.dir
+
+# All Build rule for target.
+CMakeFiles/smartUPG.dir/all:
+	$(MAKE) -f CMakeFiles/smartUPG.dir/build.make CMakeFiles/smartUPG.dir/depend
+	$(MAKE) -f CMakeFiles/smartUPG.dir/build.make CMakeFiles/smartUPG.dir/build
+	@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --progress-dir=/home/tronlong/pdu/SmartPDUPro/04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/build/CMakeFiles --progress-num=44,45,46 "Built target smartUPG"
+.PHONY : CMakeFiles/smartUPG.dir/all
+
+# Include target in all.
+all: CMakeFiles/smartUPG.dir/all
+
+.PHONY : all
+
+# Build rule for subdir invocation for target.
+CMakeFiles/smartUPG.dir/rule: cmake_check_build_system
+	$(CMAKE_COMMAND) -E cmake_progress_start /home/tronlong/pdu/SmartPDUPro/04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/build/CMakeFiles 3
+	$(MAKE) -f CMakeFiles/Makefile2 CMakeFiles/smartUPG.dir/all
+	$(CMAKE_COMMAND) -E cmake_progress_start /home/tronlong/pdu/SmartPDUPro/04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/build/CMakeFiles 0
+.PHONY : CMakeFiles/smartUPG.dir/rule
+
+# Convenience name for target.
+smartUPG: CMakeFiles/smartUPG.dir/rule
+
+.PHONY : smartUPG
+
+# clean rule for target.
+CMakeFiles/smartUPG.dir/clean:
+	$(MAKE) -f CMakeFiles/smartUPG.dir/build.make CMakeFiles/smartUPG.dir/clean
+.PHONY : CMakeFiles/smartUPG.dir/clean
+
+# clean rule for target.
+clean: CMakeFiles/smartUPG.dir/clean
+
+.PHONY : clean
+
 #=============================================================================
 # Special targets to cleanup operation of make.
 

+ 1 - 0
04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/build/CMakeFiles/TargetDirectories.txt

@@ -1,3 +1,4 @@
 /home/tronlong/pdu/SmartPDUPro/04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/build/CMakeFiles/rebuild_cache.dir
 /home/tronlong/pdu/SmartPDUPro/04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/build/CMakeFiles/smartPDU.dir
 /home/tronlong/pdu/SmartPDUPro/04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/build/CMakeFiles/edit_cache.dir
+/home/tronlong/pdu/SmartPDUPro/04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/build/CMakeFiles/smartUPG.dir

+ 1 - 1
04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/build/CMakeFiles/progress.marks

@@ -1 +1 @@
-38
+46

+ 224 - 0
04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/build/Makefile

@@ -123,6 +123,19 @@ smartPDU/fast:
 	$(MAKE) -f CMakeFiles/smartPDU.dir/build.make CMakeFiles/smartPDU.dir/build
 .PHONY : smartPDU/fast
 
+#=============================================================================
+# Target rules for targets named smartUPG
+
+# Build rule for target.
+smartUPG: cmake_check_build_system
+	$(MAKE) -f CMakeFiles/Makefile2 smartUPG
+.PHONY : smartUPG
+
+# fast build rule for target.
+smartUPG/fast:
+	$(MAKE) -f CMakeFiles/smartUPG.dir/build.make CMakeFiles/smartUPG.dir/build
+.PHONY : smartUPG/fast
+
 easylogger/os/port/elog_file_port.o: easylogger/os/port/elog_file_port.c.o
 
 .PHONY : easylogger/os/port/elog_file_port.o
@@ -690,6 +703,33 @@ src/cJSON.c.s:
 	$(MAKE) -f CMakeFiles/smartPDU.dir/build.make CMakeFiles/smartPDU.dir/src/cJSON.c.s
 .PHONY : src/cJSON.c.s
 
+src/cascade.o: src/cascade.c.o
+
+.PHONY : src/cascade.o
+
+# target to build an object file
+src/cascade.c.o:
+	$(MAKE) -f CMakeFiles/smartPDU.dir/build.make CMakeFiles/smartPDU.dir/src/cascade.c.o
+.PHONY : src/cascade.c.o
+
+src/cascade.i: src/cascade.c.i
+
+.PHONY : src/cascade.i
+
+# target to preprocess a source file
+src/cascade.c.i:
+	$(MAKE) -f CMakeFiles/smartPDU.dir/build.make CMakeFiles/smartPDU.dir/src/cascade.c.i
+.PHONY : src/cascade.c.i
+
+src/cascade.s: src/cascade.c.s
+
+.PHONY : src/cascade.s
+
+# target to generate assembly for a file
+src/cascade.c.s:
+	$(MAKE) -f CMakeFiles/smartPDU.dir/build.make CMakeFiles/smartPDU.dir/src/cascade.c.s
+.PHONY : src/cascade.c.s
+
 src/common.o: src/common.c.o
 
 .PHONY : src/common.o
@@ -717,6 +757,33 @@ src/common.c.s:
 	$(MAKE) -f CMakeFiles/smartPDU.dir/build.make CMakeFiles/smartPDU.dir/src/common.c.s
 .PHONY : src/common.c.s
 
+src/dflt.o: src/dflt.c.o
+
+.PHONY : src/dflt.o
+
+# target to build an object file
+src/dflt.c.o:
+	$(MAKE) -f CMakeFiles/smartPDU.dir/build.make CMakeFiles/smartPDU.dir/src/dflt.c.o
+.PHONY : src/dflt.c.o
+
+src/dflt.i: src/dflt.c.i
+
+.PHONY : src/dflt.i
+
+# target to preprocess a source file
+src/dflt.c.i:
+	$(MAKE) -f CMakeFiles/smartPDU.dir/build.make CMakeFiles/smartPDU.dir/src/dflt.c.i
+.PHONY : src/dflt.c.i
+
+src/dflt.s: src/dflt.c.s
+
+.PHONY : src/dflt.s
+
+# target to generate assembly for a file
+src/dflt.c.s:
+	$(MAKE) -f CMakeFiles/smartPDU.dir/build.make CMakeFiles/smartPDU.dir/src/dflt.c.s
+.PHONY : src/dflt.c.s
+
 src/io.o: src/io.c.o
 
 .PHONY : src/io.o
@@ -933,6 +1000,33 @@ src/ntpclient.c.s:
 	$(MAKE) -f CMakeFiles/smartPDU.dir/build.make CMakeFiles/smartPDU.dir/src/ntpclient.c.s
 .PHONY : src/ntpclient.c.s
 
+src/paras.o: src/paras.c.o
+
+.PHONY : src/paras.o
+
+# target to build an object file
+src/paras.c.o:
+	$(MAKE) -f CMakeFiles/smartPDU.dir/build.make CMakeFiles/smartPDU.dir/src/paras.c.o
+.PHONY : src/paras.c.o
+
+src/paras.i: src/paras.c.i
+
+.PHONY : src/paras.i
+
+# target to preprocess a source file
+src/paras.c.i:
+	$(MAKE) -f CMakeFiles/smartPDU.dir/build.make CMakeFiles/smartPDU.dir/src/paras.c.i
+.PHONY : src/paras.c.i
+
+src/paras.s: src/paras.c.s
+
+.PHONY : src/paras.s
+
+# target to generate assembly for a file
+src/paras.c.s:
+	$(MAKE) -f CMakeFiles/smartPDU.dir/build.make CMakeFiles/smartPDU.dir/src/paras.c.s
+.PHONY : src/paras.c.s
+
 src/pduMIB_form.o: src/pduMIB_form.c.o
 
 .PHONY : src/pduMIB_form.o
@@ -1095,6 +1189,33 @@ src/switch_ctrl.c.s:
 	$(MAKE) -f CMakeFiles/smartPDU.dir/build.make CMakeFiles/smartPDU.dir/src/switch_ctrl.c.s
 .PHONY : src/switch_ctrl.c.s
 
+src/sys.o: src/sys.c.o
+
+.PHONY : src/sys.o
+
+# target to build an object file
+src/sys.c.o:
+	$(MAKE) -f CMakeFiles/smartPDU.dir/build.make CMakeFiles/smartPDU.dir/src/sys.c.o
+.PHONY : src/sys.c.o
+
+src/sys.i: src/sys.c.i
+
+.PHONY : src/sys.i
+
+# target to preprocess a source file
+src/sys.c.i:
+	$(MAKE) -f CMakeFiles/smartPDU.dir/build.make CMakeFiles/smartPDU.dir/src/sys.c.i
+.PHONY : src/sys.c.i
+
+src/sys.s: src/sys.c.s
+
+.PHONY : src/sys.s
+
+# target to generate assembly for a file
+src/sys.c.s:
+	$(MAKE) -f CMakeFiles/smartPDU.dir/build.make CMakeFiles/smartPDU.dir/src/sys.c.s
+.PHONY : src/sys.c.s
+
 src/websocket_handle.o: src/websocket_handle.c.o
 
 .PHONY : src/websocket_handle.o
@@ -1122,6 +1243,87 @@ src/websocket_handle.c.s:
 	$(MAKE) -f CMakeFiles/smartPDU.dir/build.make CMakeFiles/smartPDU.dir/src/websocket_handle.c.s
 .PHONY : src/websocket_handle.c.s
 
+src/xlist.o: src/xlist.c.o
+
+.PHONY : src/xlist.o
+
+# target to build an object file
+src/xlist.c.o:
+	$(MAKE) -f CMakeFiles/smartPDU.dir/build.make CMakeFiles/smartPDU.dir/src/xlist.c.o
+.PHONY : src/xlist.c.o
+
+src/xlist.i: src/xlist.c.i
+
+.PHONY : src/xlist.i
+
+# target to preprocess a source file
+src/xlist.c.i:
+	$(MAKE) -f CMakeFiles/smartPDU.dir/build.make CMakeFiles/smartPDU.dir/src/xlist.c.i
+.PHONY : src/xlist.c.i
+
+src/xlist.s: src/xlist.c.s
+
+.PHONY : src/xlist.s
+
+# target to generate assembly for a file
+src/xlist.c.s:
+	$(MAKE) -f CMakeFiles/smartPDU.dir/build.make CMakeFiles/smartPDU.dir/src/xlist.c.s
+.PHONY : src/xlist.c.s
+
+upgrade/md5.o: upgrade/md5.c.o
+
+.PHONY : upgrade/md5.o
+
+# target to build an object file
+upgrade/md5.c.o:
+	$(MAKE) -f CMakeFiles/smartUPG.dir/build.make CMakeFiles/smartUPG.dir/upgrade/md5.c.o
+.PHONY : upgrade/md5.c.o
+
+upgrade/md5.i: upgrade/md5.c.i
+
+.PHONY : upgrade/md5.i
+
+# target to preprocess a source file
+upgrade/md5.c.i:
+	$(MAKE) -f CMakeFiles/smartUPG.dir/build.make CMakeFiles/smartUPG.dir/upgrade/md5.c.i
+.PHONY : upgrade/md5.c.i
+
+upgrade/md5.s: upgrade/md5.c.s
+
+.PHONY : upgrade/md5.s
+
+# target to generate assembly for a file
+upgrade/md5.c.s:
+	$(MAKE) -f CMakeFiles/smartUPG.dir/build.make CMakeFiles/smartUPG.dir/upgrade/md5.c.s
+.PHONY : upgrade/md5.c.s
+
+upgrade/upgrade.o: upgrade/upgrade.c.o
+
+.PHONY : upgrade/upgrade.o
+
+# target to build an object file
+upgrade/upgrade.c.o:
+	$(MAKE) -f CMakeFiles/smartUPG.dir/build.make CMakeFiles/smartUPG.dir/upgrade/upgrade.c.o
+.PHONY : upgrade/upgrade.c.o
+
+upgrade/upgrade.i: upgrade/upgrade.c.i
+
+.PHONY : upgrade/upgrade.i
+
+# target to preprocess a source file
+upgrade/upgrade.c.i:
+	$(MAKE) -f CMakeFiles/smartUPG.dir/build.make CMakeFiles/smartUPG.dir/upgrade/upgrade.c.i
+.PHONY : upgrade/upgrade.c.i
+
+upgrade/upgrade.s: upgrade/upgrade.c.s
+
+.PHONY : upgrade/upgrade.s
+
+# target to generate assembly for a file
+upgrade/upgrade.c.s:
+	$(MAKE) -f CMakeFiles/smartUPG.dir/build.make CMakeFiles/smartUPG.dir/upgrade/upgrade.c.s
+.PHONY : upgrade/upgrade.c.s
+
 # Help Target
 help:
 	@echo "The following are some of the valid targets for this Makefile:"
@@ -1131,6 +1333,7 @@ help:
 	@echo "... rebuild_cache"
 	@echo "... smartPDU"
 	@echo "... edit_cache"
+	@echo "... smartUPG"
 	@echo "... easylogger/os/port/elog_file_port.o"
 	@echo "... easylogger/os/port/elog_file_port.i"
 	@echo "... easylogger/os/port/elog_file_port.s"
@@ -1194,9 +1397,15 @@ help:
 	@echo "... src/cJSON.o"
 	@echo "... src/cJSON.i"
 	@echo "... src/cJSON.s"
+	@echo "... src/cascade.o"
+	@echo "... src/cascade.i"
+	@echo "... src/cascade.s"
 	@echo "... src/common.o"
 	@echo "... src/common.i"
 	@echo "... src/common.s"
+	@echo "... src/dflt.o"
+	@echo "... src/dflt.i"
+	@echo "... src/dflt.s"
 	@echo "... src/io.o"
 	@echo "... src/io.i"
 	@echo "... src/io.s"
@@ -1221,6 +1430,9 @@ help:
 	@echo "... src/ntpclient.o"
 	@echo "... src/ntpclient.i"
 	@echo "... src/ntpclient.s"
+	@echo "... src/paras.o"
+	@echo "... src/paras.i"
+	@echo "... src/paras.s"
 	@echo "... src/pduMIB_form.o"
 	@echo "... src/pduMIB_form.i"
 	@echo "... src/pduMIB_form.s"
@@ -1239,9 +1451,21 @@ help:
 	@echo "... src/switch_ctrl.o"
 	@echo "... src/switch_ctrl.i"
 	@echo "... src/switch_ctrl.s"
+	@echo "... src/sys.o"
+	@echo "... src/sys.i"
+	@echo "... src/sys.s"
 	@echo "... src/websocket_handle.o"
 	@echo "... src/websocket_handle.i"
 	@echo "... src/websocket_handle.s"
+	@echo "... src/xlist.o"
+	@echo "... src/xlist.i"
+	@echo "... src/xlist.s"
+	@echo "... upgrade/md5.o"
+	@echo "... upgrade/md5.i"
+	@echo "... upgrade/md5.s"
+	@echo "... upgrade/upgrade.o"
+	@echo "... upgrade/upgrade.i"
+	@echo "... upgrade/upgrade.s"
 .PHONY : help
 
 

+ 22 - 0
04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/config/cfg.h

@@ -0,0 +1,22 @@
+#ifndef __CONFIG_Hx__
+#define __CONFIG_Hx__
+
+
+#define VERSION             "V0.0.1"
+
+
+#define PROD_ID             1
+#define PROD_TYPE           1
+#define PROD_POWER_TYPE     1
+
+
+#define LANGUAGE            0
+#define SMPLE_TIME          100         //ms
+#define SAVE_TIME           1000        //ms
+#define CASCADE_CNT         5
+
+
+
+#endif
+
+

+ 0 - 230
04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/modbus/config.h

@@ -1,230 +0,0 @@
-/* config.h.  Generated from config.h.in by configure.  */
-/* config.h.in.  Generated from configure.ac by autoheader.  */
-
-/* Define to 1 if you have the `accept4' function. */
-#define HAVE_ACCEPT4 1
-
-/* Define to 1 if you have the <arpa/inet.h> header file. */
-#define HAVE_ARPA_INET_H 1
-
-/* Define to 1 if you have the <byteswap.h> header file. */
-#define HAVE_BYTESWAP_H 1
-
-/* Define to 1 if you have the declaration of `TIOCM_RTS', and to 0 if you
-   don't. */
-#define HAVE_DECL_TIOCM_RTS 1
-
-/* Define to 1 if you have the declaration of `TIOCSRS485', and to 0 if you
-   don't. */
-#define HAVE_DECL_TIOCSRS485 1
-
-/* Define to 1 if you have the declaration of `__CYGWIN__', and to 0 if you
-   don't. */
-#define HAVE_DECL___CYGWIN__ 0
-
-/* Define to 1 if you have the <dlfcn.h> header file. */
-#define HAVE_DLFCN_H 1
-
-/* Define to 1 if you have the <errno.h> header file. */
-#define HAVE_ERRNO_H 1
-
-/* Define to 1 if you have the <fcntl.h> header file. */
-#define HAVE_FCNTL_H 1
-
-/* Define to 1 if you have the `getaddrinfo' function. */
-#define HAVE_GETADDRINFO 1
-
-/* Define to 1 if you have the `gettimeofday' function. */
-#define HAVE_GETTIMEOFDAY 1
-
-/* Define to 1 if you have the `inet_ntoa' function. */
-#define HAVE_INET_NTOA 1
-
-/* Define to 1 if you have the <inttypes.h> header file. */
-#define HAVE_INTTYPES_H 1
-
-/* Define to 1 if you have the <limits.h> header file. */
-#define HAVE_LIMITS_H 1
-
-/* Define to 1 if you have the <linux/serial.h> header file. */
-#define HAVE_LINUX_SERIAL_H 1
-
-/* Define to 1 if you have the <memory.h> header file. */
-#define HAVE_MEMORY_H 1
-
-/* Define to 1 if you have the <netdb.h> header file. */
-#define HAVE_NETDB_H 1
-
-/* Define to 1 if you have the <netinet/in.h> header file. */
-#define HAVE_NETINET_IN_H 1
-
-/* Define to 1 if you have the <netinet/tcp.h> header file. */
-#define HAVE_NETINET_TCP_H 1
-
-/* Define to 1 if you have the `select' function. */
-#define HAVE_SELECT 1
-
-/* Define to 1 if you have the `socket' function. */
-#define HAVE_SOCKET 1
-
-/* Define to 1 if you have the <stdint.h> header file. */
-#define HAVE_STDINT_H 1
-
-/* Define to 1 if you have the <stdlib.h> header file. */
-#define HAVE_STDLIB_H 1
-
-/* Define to 1 if you have the `strerror' function. */
-#define HAVE_STRERROR 1
-
-/* Define to 1 if you have the <strings.h> header file. */
-#define HAVE_STRINGS_H 1
-
-/* Define to 1 if you have the <string.h> header file. */
-#define HAVE_STRING_H 1
-
-/* Define to 1 if you have the `strlcpy' function. */
-#define HAVE_STRLCPY 1
-
-/* Define to 1 if you have the <sys/ioctl.h> header file. */
-#define HAVE_SYS_IOCTL_H 1
-
-/* Define to 1 if you have the <sys/params.h> header file. */
-/* #undef HAVE_SYS_PARAMS_H */
-
-/* Define to 1 if you have the <sys/socket.h> header file. */
-#define HAVE_SYS_SOCKET_H 1
-
-/* Define to 1 if you have the <sys/stat.h> header file. */
-#define HAVE_SYS_STAT_H 1
-
-/* Define to 1 if you have the <sys/time.h> header file. */
-#define HAVE_SYS_TIME_H 1
-
-/* Define to 1 if you have the <sys/types.h> header file. */
-#define HAVE_SYS_TYPES_H 1
-
-/* Define to 1 if you have the <termios.h> header file. */
-#define HAVE_TERMIOS_H 1
-
-/* Define to 1 if you have the <time.h> header file. */
-#define HAVE_TIME_H 1
-
-/* Define to 1 if you have the <unistd.h> header file. */
-#define HAVE_UNISTD_H 1
-
-/* Define to 1 if you have the <winsock2.h> header file. */
-/* #undef HAVE_WINSOCK2_H */
-
-/* Define to the sub-directory where libtool stores uninstalled libraries. */
-#define LT_OBJDIR ".libs/"
-
-/* Name of package */
-#define PACKAGE "libmodbus"
-
-/* Define to the address where bug reports for this package should be sent. */
-#define PACKAGE_BUGREPORT "https://github.com/stephane/libmodbus/issues"
-
-/* Define to the full name of this package. */
-#define PACKAGE_NAME "libmodbus"
-
-/* Define to the full name and version of this package. */
-#define PACKAGE_STRING "libmodbus 3.1.6"
-
-/* Define to the one symbol short name of this package. */
-#define PACKAGE_TARNAME "libmodbus"
-
-/* Define to the home page for this package. */
-#define PACKAGE_URL "http://libmodbus.org/"
-
-/* Define to the version of this package. */
-#define PACKAGE_VERSION "3.1.6"
-
-/* Define to 1 if you have the ANSI C header files. */
-#define STDC_HEADERS 1
-
-/* Enable extensions on AIX 3, Interix.  */
-#ifndef _ALL_SOURCE
-# define _ALL_SOURCE 1
-#endif
-/* Enable GNU extensions on systems that have them.  */
-#ifndef _GNU_SOURCE
-# define _GNU_SOURCE 1
-#endif
-/* Enable threading extensions on Solaris.  */
-#ifndef _POSIX_PTHREAD_SEMANTICS
-# define _POSIX_PTHREAD_SEMANTICS 1
-#endif
-/* Enable extensions on HP NonStop.  */
-#ifndef _TANDEM_SOURCE
-# define _TANDEM_SOURCE 1
-#endif
-/* Enable general extensions on Solaris.  */
-#ifndef __EXTENSIONS__
-# define __EXTENSIONS__ 1
-#endif
-
-
-/* Version number of package */
-#define VERSION "3.1.6"
-
-/* _ */
-#define WINVER 0x0501
-
-/* Enable large inode numbers on Mac OS X 10.5.  */
-#ifndef _DARWIN_USE_64_BIT_INODE
-# define _DARWIN_USE_64_BIT_INODE 1
-#endif
-
-/* Number of bits in a file offset, on hosts where this is settable. */
-/* #undef _FILE_OFFSET_BITS */
-
-/* Define for large files, on AIX-style hosts. */
-/* #undef _LARGE_FILES */
-
-/* Define to 1 if on MINIX. */
-/* #undef _MINIX */
-
-/* Define to 2 if the system does not provide POSIX.1 features except with
-   this defined. */
-/* #undef _POSIX_1_SOURCE */
-
-/* Define to 1 if you need to in order for `stat' and other things to work. */
-/* #undef _POSIX_SOURCE */
-
-/* Define for Solaris 2.5.1 so the uint32_t typedef from <sys/synch.h>,
-   <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
-   #define below would cause a syntax error. */
-/* #undef _UINT32_T */
-
-/* Define for Solaris 2.5.1 so the uint8_t typedef from <sys/synch.h>,
-   <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
-   #define below would cause a syntax error. */
-/* #undef _UINT8_T */
-
-/* Define to `__inline__' or `__inline' if that's what the C compiler
-   calls it, or to nothing if 'inline' is not supported under any name.  */
-#ifndef __cplusplus
-/* #undef inline */
-#endif
-
-/* Define to the type of a signed integer type of width exactly 64 bits if
-   such a type exists and the standard includes do not define it. */
-/* #undef int64_t */
-
-/* Define to `unsigned int' if <sys/types.h> does not define. */
-/* #undef size_t */
-
-/* Define to `int' if <sys/types.h> does not define. */
-/* #undef ssize_t */
-
-/* Define to the type of an unsigned integer type of width exactly 16 bits if
-   such a type exists and the standard includes do not define it. */
-/* #undef uint16_t */
-
-/* Define to the type of an unsigned integer type of width exactly 32 bits if
-   such a type exists and the standard includes do not define it. */
-/* #undef uint32_t */
-
-/* Define to the type of an unsigned integer type of width exactly 8 bits if
-   such a type exists and the standard includes do not define it. */
-/* #undef uint8_t */

+ 0 - 233
04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/modbus/modbus-data.c

@@ -1,233 +0,0 @@
-/*
- * Copyright © 2010-2014 Stéphane Raimbault <stephane.raimbault@gmail.com>
- *
- * SPDX-License-Identifier: LGPL-2.1+
- */
-
-#include <stdlib.h>
-
-#ifndef _MSC_VER
-#  include <stdint.h>
-#else
-#  include "stdint.h"
-#endif
-
-#include <string.h>
-#include <assert.h>
-
-#if defined(_WIN32)
-#  include <winsock2.h>
-#else
-#  include <arpa/inet.h>
-#endif
-
-#include <config.h>
-
-#include "modbus.h"
-
-#if defined(HAVE_BYTESWAP_H)
-#  include <byteswap.h>
-#endif
-
-#if defined(__APPLE__)
-#  include <libkern/OSByteOrder.h>
-#  define bswap_16 OSSwapInt16
-#  define bswap_32 OSSwapInt32
-#  define bswap_64 OSSwapInt64
-#endif
-
-#if defined(__GNUC__)
-#  define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__ * 10)
-#  if GCC_VERSION >= 430
-// Since GCC >= 4.30, GCC provides __builtin_bswapXX() alternatives so we switch to them
-#    undef bswap_32
-#    define bswap_32 __builtin_bswap32
-#  endif
-#  if GCC_VERSION >= 480
-#    undef bswap_16
-#    define bswap_16 __builtin_bswap16
-#  endif
-#endif
-
-#if defined(_MSC_VER) && (_MSC_VER >= 1400)
-#  define bswap_32 _byteswap_ulong
-#  define bswap_16 _byteswap_ushort
-#endif
-
-#if !defined(bswap_16)
-#  warning "Fallback on C functions for bswap_16"
-static inline uint16_t bswap_16(uint16_t x)
-{
-    return (x >> 8) | (x << 8);
-}
-#endif
-
-#if !defined(bswap_32)
-#  warning "Fallback on C functions for bswap_32"
-static inline uint32_t bswap_32(uint32_t x)
-{
-    return (bswap_16(x & 0xffff) << 16) | (bswap_16(x >> 16));
-}
-#endif
-
-/* Sets many bits from a single byte value (all 8 bits of the byte value are
-   set) */
-void modbus_set_bits_from_byte(uint8_t *dest, int idx, const uint8_t value)
-{
-    int i;
-
-    for (i=0; i < 8; i++) {
-        dest[idx+i] = (value & (1 << i)) ? 1 : 0;
-    }
-}
-
-/* Sets many bits from a table of bytes (only the bits between idx and
-   idx + nb_bits are set) */
-void modbus_set_bits_from_bytes(uint8_t *dest, int idx, unsigned int nb_bits,
-                                const uint8_t *tab_byte)
-{
-    unsigned int i;
-    int shift = 0;
-
-    for (i = idx; i < idx + nb_bits; i++) {
-        dest[i] = tab_byte[(i - idx) / 8] & (1 << shift) ? 1 : 0;
-        /* gcc doesn't like: shift = (++shift) % 8; */
-        shift++;
-        shift %= 8;
-    }
-}
-
-/* Gets the byte value from many bits.
-   To obtain a full byte, set nb_bits to 8. */
-uint8_t modbus_get_byte_from_bits(const uint8_t *src, int idx,
-                                  unsigned int nb_bits)
-{
-    unsigned int i;
-    uint8_t value = 0;
-
-    if (nb_bits > 8) {
-        /* Assert is ignored if NDEBUG is set */
-        assert(nb_bits < 8);
-        nb_bits = 8;
-    }
-
-    for (i=0; i < nb_bits; i++) {
-        value |= (src[idx+i] << i);
-    }
-
-    return value;
-}
-
-/* Get a float from 4 bytes (Modbus) without any conversion (ABCD) */
-float modbus_get_float_abcd(const uint16_t *src)
-{
-    float f;
-    uint32_t i;
-
-    i = ntohl(((uint32_t)src[0] << 16) + src[1]);
-    memcpy(&f, &i, sizeof(float));
-
-    return f;
-}
-
-/* Get a float from 4 bytes (Modbus) in inversed format (DCBA) */
-float modbus_get_float_dcba(const uint16_t *src)
-{
-    float f;
-    uint32_t i;
-
-    i = ntohl(bswap_32((((uint32_t)src[0]) << 16) + src[1]));
-    memcpy(&f, &i, sizeof(float));
-
-    return f;
-}
-
-/* Get a float from 4 bytes (Modbus) with swapped bytes (BADC) */
-float modbus_get_float_badc(const uint16_t *src)
-{
-    float f;
-    uint32_t i;
-
-    i = ntohl((uint32_t)(bswap_16(src[0]) << 16) + bswap_16(src[1]));
-    memcpy(&f, &i, sizeof(float));
-
-    return f;
-}
-
-/* Get a float from 4 bytes (Modbus) with swapped words (CDAB) */
-float modbus_get_float_cdab(const uint16_t *src)
-{
-    float f;
-    uint32_t i;
-
-    i = ntohl((((uint32_t)src[1]) << 16) + src[0]);
-    memcpy(&f, &i, sizeof(float));
-
-    return f;
-}
-
-/* DEPRECATED - Get a float from 4 bytes in sort of Modbus format */
-float modbus_get_float(const uint16_t *src)
-{
-    float f;
-    uint32_t i;
-
-    i = (((uint32_t)src[1]) << 16) + src[0];
-    memcpy(&f, &i, sizeof(float));
-
-    return f;
-}
-
-/* Set a float to 4 bytes for Modbus w/o any conversion (ABCD) */
-void modbus_set_float_abcd(float f, uint16_t *dest)
-{
-    uint32_t i;
-
-    memcpy(&i, &f, sizeof(uint32_t));
-    i = htonl(i);
-    dest[0] = (uint16_t)(i >> 16);
-    dest[1] = (uint16_t)i;
-}
-
-/* Set a float to 4 bytes for Modbus with byte and word swap conversion (DCBA) */
-void modbus_set_float_dcba(float f, uint16_t *dest)
-{
-    uint32_t i;
-
-    memcpy(&i, &f, sizeof(uint32_t));
-    i = bswap_32(htonl(i));
-    dest[0] = (uint16_t)(i >> 16);
-    dest[1] = (uint16_t)i;
-}
-
-/* Set a float to 4 bytes for Modbus with byte swap conversion (BADC) */
-void modbus_set_float_badc(float f, uint16_t *dest)
-{
-    uint32_t i;
-
-    memcpy(&i, &f, sizeof(uint32_t));
-    i = htonl(i);
-    dest[0] = (uint16_t)bswap_16(i >> 16);
-    dest[1] = (uint16_t)bswap_16(i & 0xFFFF);
-}
-
-/* Set a float to 4 bytes for Modbus with word swap conversion (CDAB) */
-void modbus_set_float_cdab(float f, uint16_t *dest)
-{
-    uint32_t i;
-
-    memcpy(&i, &f, sizeof(uint32_t));
-    i = htonl(i);
-    dest[0] = (uint16_t)i;
-    dest[1] = (uint16_t)(i >> 16);
-}
-
-/* DEPRECATED - Set a float to 4 bytes in a sort of Modbus format! */
-void modbus_set_float(float f, uint16_t *dest)
-{
-    uint32_t i;
-
-    memcpy(&i, &f, sizeof(uint32_t));
-    dest[0] = (uint16_t)i;
-    dest[1] = (uint16_t)(i >> 16);
-}

+ 0 - 116
04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/modbus/modbus-private.h

@@ -1,116 +0,0 @@
-/*
- * Copyright © 2010-2012 Stéphane Raimbault <stephane.raimbault@gmail.com>
- *
- * SPDX-License-Identifier: LGPL-2.1+
- */
-
-#ifndef MODBUS_PRIVATE_H
-#define MODBUS_PRIVATE_H
-
-#ifndef _MSC_VER
-# include <stdint.h>
-# include <sys/time.h>
-#else
-# include "stdint.h"
-# include <time.h>
-typedef int ssize_t;
-#endif
-#include <sys/types.h>
-#include <config.h>
-
-#include "modbus.h"
-
-MODBUS_BEGIN_DECLS
-
-/* It's not really the minimal length (the real one is report slave ID
- * in RTU (4 bytes)) but it's a convenient size to use in RTU or TCP
- * communications to read many values or write a single one.
- * Maximum between :
- * - HEADER_LENGTH_TCP (7) + function (1) + address (2) + number (2)
- * - HEADER_LENGTH_RTU (1) + function (1) + address (2) + number (2) + CRC (2)
- */
-#define _MIN_REQ_LENGTH 12
-
-#define _REPORT_SLAVE_ID 180
-
-#define _MODBUS_EXCEPTION_RSP_LENGTH 5
-
-/* Timeouts in microsecond (0.5 s) */
-#define _RESPONSE_TIMEOUT    500000
-#define _BYTE_TIMEOUT        500000
-
-typedef enum {
-    _MODBUS_BACKEND_TYPE_RTU=0,
-    _MODBUS_BACKEND_TYPE_TCP
-} modbus_backend_type_t;
-
-/*
- *  ---------- Request     Indication ----------
- *  | Client | ---------------------->| Server |
- *  ---------- Confirmation  Response ----------
- */
-typedef enum {
-    /* Request message on the server side */
-    MSG_INDICATION,
-    /* Request message on the client side */
-    MSG_CONFIRMATION
-} msg_type_t;
-
-/* This structure reduces the number of params in functions and so
- * optimizes the speed of execution (~ 37%). */
-typedef struct _sft {
-    int slave;
-    int function;
-    int t_id;
-} sft_t;
-
-typedef struct _modbus_backend {
-    unsigned int backend_type;
-    unsigned int header_length;
-    unsigned int checksum_length;
-    unsigned int max_adu_length;
-    int (*set_slave) (modbus_t *ctx, int slave);
-    int (*build_request_basis) (modbus_t *ctx, int function, int addr,
-                                int nb, uint8_t *req);
-    int (*build_response_basis) (sft_t *sft, uint8_t *rsp);
-    int (*prepare_response_tid) (const uint8_t *req, int *req_length);
-    int (*send_msg_pre) (uint8_t *req, int req_length);
-    ssize_t (*send) (modbus_t *ctx, const uint8_t *req, int req_length);
-    int (*receive) (modbus_t *ctx, uint8_t *req);
-    ssize_t (*recv) (modbus_t *ctx, uint8_t *rsp, int rsp_length);
-    int (*check_integrity) (modbus_t *ctx, uint8_t *msg,
-                            const int msg_length);
-    int (*pre_check_confirmation) (modbus_t *ctx, const uint8_t *req,
-                                   const uint8_t *rsp, int rsp_length);
-    int (*connect) (modbus_t *ctx);
-    void (*close) (modbus_t *ctx);
-    int (*flush) (modbus_t *ctx);
-    int (*select) (modbus_t *ctx, fd_set *rset, struct timeval *tv, int msg_length);
-    void (*free) (modbus_t *ctx);
-} modbus_backend_t;
-
-struct _modbus {
-    /* Slave address */
-    int slave;
-    /* Socket or file descriptor */
-    int s;
-    int debug;
-    int error_recovery;
-    struct timeval response_timeout;
-    struct timeval byte_timeout;
-    struct timeval indication_timeout;
-    const modbus_backend_t *backend;
-    void *backend_data;
-};
-
-void _modbus_init_common(modbus_t *ctx);
-void _error_print(modbus_t *ctx, const char *context);
-int _modbus_receive_msg(modbus_t *ctx, uint8_t *msg, msg_type_t msg_type);
-
-#ifndef HAVE_STRLCPY
-size_t strlcpy(char *dest, const char *src, size_t dest_size);
-#endif
-
-MODBUS_END_DECLS
-
-#endif  /* MODBUS_PRIVATE_H */

+ 0 - 76
04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/modbus/modbus-rtu-private.h

@@ -1,76 +0,0 @@
-/*
- * Copyright © 2001-2011 Stéphane Raimbault <stephane.raimbault@gmail.com>
- *
- * SPDX-License-Identifier: LGPL-2.1+
- */
-
-#ifndef MODBUS_RTU_PRIVATE_H
-#define MODBUS_RTU_PRIVATE_H
-
-#ifndef _MSC_VER
-#include <stdint.h>
-#else
-#include "stdint.h"
-#endif
-
-#if defined(_WIN32)
-#include <windows.h>
-#else
-#include <termios.h>
-#endif
-
-#define _MODBUS_RTU_HEADER_LENGTH      1
-#define _MODBUS_RTU_PRESET_REQ_LENGTH  6
-#define _MODBUS_RTU_PRESET_RSP_LENGTH  2
-
-#define _MODBUS_RTU_CHECKSUM_LENGTH    2
-
-#if defined(_WIN32)
-#if !defined(ENOTSUP)
-#define ENOTSUP WSAEOPNOTSUPP
-#endif
-
-/* WIN32: struct containing serial handle and a receive buffer */
-#define PY_BUF_SIZE 512
-struct win32_ser {
-    /* File handle */
-    HANDLE fd;
-    /* Receive buffer */
-    uint8_t buf[PY_BUF_SIZE];
-    /* Received chars */
-    DWORD n_bytes;
-};
-#endif /* _WIN32 */
-
-typedef struct _modbus_rtu {
-    /* Device: "/dev/ttyS0", "/dev/ttyUSB0" or "/dev/tty.USA19*" on Mac OS X. */
-    char *device;
-    /* Bauds: 9600, 19200, 57600, 115200, etc */
-    int baud;
-    /* Data bit */
-    uint8_t data_bit;
-    /* Stop bit */
-    uint8_t stop_bit;
-    /* Parity: 'N', 'O', 'E' */
-    char parity;
-#if defined(_WIN32)
-    struct win32_ser w_ser;
-    DCB old_dcb;
-#else
-    /* Save old termios settings */
-    struct termios old_tios;
-#endif
-#if HAVE_DECL_TIOCSRS485
-    int serial_mode;
-#endif
-#if HAVE_DECL_TIOCM_RTS
-    int rts;
-    int rts_delay;
-    int onebyte_time;
-    void (*set_rts) (modbus_t *ctx, int on);
-#endif
-    /* To handle many slaves on the same link */
-    int confirmation_to_ignore;
-} modbus_rtu_t;
-
-#endif /* MODBUS_RTU_PRIVATE_H */

File diff suppressed because it is too large
+ 0 - 1299
04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/modbus/modbus-rtu.c


+ 0 - 42
04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/modbus/modbus-rtu.h

@@ -1,42 +0,0 @@
-/*
- * Copyright © 2001-2011 Stéphane Raimbault <stephane.raimbault@gmail.com>
- *
- * SPDX-License-Identifier: LGPL-2.1+
- */
-
-#ifndef MODBUS_RTU_H
-#define MODBUS_RTU_H
-
-#include "modbus.h"
-
-MODBUS_BEGIN_DECLS
-
-/* Modbus_Application_Protocol_V1_1b.pdf Chapter 4 Section 1 Page 5
- * RS232 / RS485 ADU = 253 bytes + slave (1 byte) + CRC (2 bytes) = 256 bytes
- */
-#define MODBUS_RTU_MAX_ADU_LENGTH  256
-
-MODBUS_API modbus_t* modbus_new_rtu(const char *device, int baud, char parity,
-                                    int data_bit, int stop_bit);
-
-#define MODBUS_RTU_RS232 0
-#define MODBUS_RTU_RS485 1
-
-MODBUS_API int modbus_rtu_set_serial_mode(modbus_t *ctx, int mode);
-MODBUS_API int modbus_rtu_get_serial_mode(modbus_t *ctx);
-
-#define MODBUS_RTU_RTS_NONE   0
-#define MODBUS_RTU_RTS_UP     1
-#define MODBUS_RTU_RTS_DOWN   2
-
-MODBUS_API int modbus_rtu_set_rts(modbus_t *ctx, int mode);
-MODBUS_API int modbus_rtu_get_rts(modbus_t *ctx);
-
-MODBUS_API int modbus_rtu_set_custom_rts(modbus_t *ctx, void (*set_rts) (modbus_t *ctx, int on));
-
-MODBUS_API int modbus_rtu_set_rts_delay(modbus_t *ctx, int us);
-MODBUS_API int modbus_rtu_get_rts_delay(modbus_t *ctx);
-
-MODBUS_END_DECLS
-
-#endif /* MODBUS_RTU_H */

+ 0 - 44
04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/modbus/modbus-tcp-private.h

@@ -1,44 +0,0 @@
-/*
- * Copyright © 2001-2011 Stéphane Raimbault <stephane.raimbault@gmail.com>
- *
- * SPDX-License-Identifier: LGPL-2.1+
- */
-
-#ifndef MODBUS_TCP_PRIVATE_H
-#define MODBUS_TCP_PRIVATE_H
-
-#define _MODBUS_TCP_HEADER_LENGTH      7
-#define _MODBUS_TCP_PRESET_REQ_LENGTH 12
-#define _MODBUS_TCP_PRESET_RSP_LENGTH  8
-
-#define _MODBUS_TCP_CHECKSUM_LENGTH    0
-
-/* In both structures, the transaction ID must be placed on first position
-   to have a quick access not dependant of the TCP backend */
-typedef struct _modbus_tcp {
-    /* Extract from MODBUS Messaging on TCP/IP Implementation Guide V1.0b
-       (page 23/46):
-       The transaction identifier is used to associate the future response
-       with the request. This identifier is unique on each TCP connection. */
-    uint16_t t_id;
-    /* TCP port */
-    int port;
-    /* IP address */
-    char ip[16];
-} modbus_tcp_t;
-
-#define _MODBUS_TCP_PI_NODE_LENGTH    1025
-#define _MODBUS_TCP_PI_SERVICE_LENGTH   32
-
-typedef struct _modbus_tcp_pi {
-    /* Transaction ID */
-    uint16_t t_id;
-    /* TCP port */
-    int port;
-    /* Node */
-    char node[_MODBUS_TCP_PI_NODE_LENGTH];
-    /* Service */
-    char service[_MODBUS_TCP_PI_SERVICE_LENGTH];
-} modbus_tcp_pi_t;
-
-#endif /* MODBUS_TCP_PRIVATE_H */

+ 0 - 929
04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/modbus/modbus-tcp.c

@@ -1,929 +0,0 @@
-/*
- * Copyright © 2001-2013 Stéphane Raimbault <stephane.raimbault@gmail.com>
- *
- * SPDX-License-Identifier: LGPL-2.1+
- */
-
-#if defined(_WIN32)
-# define OS_WIN32
-/* ws2_32.dll has getaddrinfo and freeaddrinfo on Windows XP and later.
- * minwg32 headers check WINVER before allowing the use of these */
-# ifndef WINVER
-#   define WINVER 0x0501
-# endif
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#ifndef _MSC_VER
-#include <unistd.h>
-#endif
-#include <signal.h>
-#include <sys/types.h>
-
-#if defined(_WIN32)
-/* Already set in modbus-tcp.h but it seems order matters in VS2005 */
-# include <winsock2.h>
-# include <ws2tcpip.h>
-# define SHUT_RDWR 2
-# define close closesocket
-#else
-# include <sys/socket.h>
-# include <sys/ioctl.h>
-
-#if defined(__OpenBSD__) || (defined(__FreeBSD__) && __FreeBSD__ < 5)
-# define OS_BSD
-# include <netinet/in_systm.h>
-#endif
-
-# include <netinet/in.h>
-# include <netinet/ip.h>
-# include <netinet/tcp.h>
-# include <arpa/inet.h>
-# include <netdb.h>
-#endif
-
-#if !defined(MSG_NOSIGNAL)
-#define MSG_NOSIGNAL 0
-#endif
-
-#if defined(_AIX) && !defined(MSG_DONTWAIT)
-#define MSG_DONTWAIT MSG_NONBLOCK
-#endif
-
-#include "modbus-private.h"
-
-#include "modbus-tcp.h"
-#include "modbus-tcp-private.h"
-
-#ifdef OS_WIN32
-static int _modbus_tcp_init_win32(void)
-{
-    /* Initialise Windows Socket API */
-    WSADATA wsaData;
-
-    if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
-        fprintf(stderr, "WSAStartup() returned error code %d\n",
-                (unsigned int)GetLastError());
-        errno = EIO;
-        return -1;
-    }
-    return 0;
-}
-#endif
-
-static int _modbus_set_slave(modbus_t *ctx, int slave)
-{
-    /* Broadcast address is 0 (MODBUS_BROADCAST_ADDRESS) */
-    if (slave >= 0 && slave <= 247) {
-        ctx->slave = slave;
-    } else if (slave == MODBUS_TCP_SLAVE) {
-        /* The special value MODBUS_TCP_SLAVE (0xFF) can be used in TCP mode to
-         * restore the default value. */
-        ctx->slave = slave;
-    } else {
-        errno = EINVAL;
-        return -1;
-    }
-
-    return 0;
-}
-
-/* Builds a TCP request header */
-static int _modbus_tcp_build_request_basis(modbus_t *ctx, int function,
-                                           int addr, int nb,
-                                           uint8_t *req)
-{
-    modbus_tcp_t *ctx_tcp = ctx->backend_data;
-
-    /* Increase transaction ID */
-    if (ctx_tcp->t_id < UINT16_MAX)
-        ctx_tcp->t_id++;
-    else
-        ctx_tcp->t_id = 0;
-    req[0] = ctx_tcp->t_id >> 8;
-    req[1] = ctx_tcp->t_id & 0x00ff;
-
-    /* Protocol Modbus */
-    req[2] = 0;
-    req[3] = 0;
-
-    /* Length will be defined later by set_req_length_tcp at offsets 4
-       and 5 */
-
-    req[6] = ctx->slave;
-    req[7] = function;
-    req[8] = addr >> 8;
-    req[9] = addr & 0x00ff;
-    req[10] = nb >> 8;
-    req[11] = nb & 0x00ff;
-
-    return _MODBUS_TCP_PRESET_REQ_LENGTH;
-}
-
-/* Builds a TCP response header */
-static int _modbus_tcp_build_response_basis(sft_t *sft, uint8_t *rsp)
-{
-    /* Extract from MODBUS Messaging on TCP/IP Implementation
-       Guide V1.0b (page 23/46):
-       The transaction identifier is used to associate the future
-       response with the request. */
-    rsp[0] = sft->t_id >> 8;
-    rsp[1] = sft->t_id & 0x00ff;
-
-    /* Protocol Modbus */
-    rsp[2] = 0;
-    rsp[3] = 0;
-
-    /* Length will be set later by send_msg (4 and 5) */
-
-    /* The slave ID is copied from the indication */
-    rsp[6] = sft->slave;
-    rsp[7] = sft->function;
-
-    return _MODBUS_TCP_PRESET_RSP_LENGTH;
-}
-
-
-static int _modbus_tcp_prepare_response_tid(const uint8_t *req, int *req_length)
-{
-    return (req[0] << 8) + req[1];
-}
-
-static int _modbus_tcp_send_msg_pre(uint8_t *req, int req_length)
-{
-    /* Substract the header length to the message length */
-    int mbap_length = req_length - 6;
-
-    req[4] = mbap_length >> 8;
-    req[5] = mbap_length & 0x00FF;
-
-    return req_length;
-}
-
-static ssize_t _modbus_tcp_send(modbus_t *ctx, const uint8_t *req, int req_length)
-{
-    /* MSG_NOSIGNAL
-       Requests not to send SIGPIPE on errors on stream oriented
-       sockets when the other end breaks the connection.  The EPIPE
-       error is still returned. */
-    return send(ctx->s, (const char *)req, req_length, MSG_NOSIGNAL);
-}
-
-static int _modbus_tcp_receive(modbus_t *ctx, uint8_t *req) {
-    return _modbus_receive_msg(ctx, req, MSG_INDICATION);
-}
-
-static ssize_t _modbus_tcp_recv(modbus_t *ctx, uint8_t *rsp, int rsp_length) {
-    return recv(ctx->s, (char *)rsp, rsp_length, 0);
-}
-
-static int _modbus_tcp_check_integrity(modbus_t *ctx, uint8_t *msg, const int msg_length)
-{
-    return msg_length;
-}
-
-static int _modbus_tcp_pre_check_confirmation(modbus_t *ctx, const uint8_t *req,
-                                              const uint8_t *rsp, int rsp_length)
-{
-    /* Check transaction ID */
-    if (req[0] != rsp[0] || req[1] != rsp[1]) {
-        if (ctx->debug) {
-            fprintf(stderr, "Invalid transaction ID received 0x%X (not 0x%X)\n",
-                    (rsp[0] << 8) + rsp[1], (req[0] << 8) + req[1]);
-        }
-        errno = EMBBADDATA;
-        return -1;
-    }
-
-    /* Check protocol ID */
-    if (rsp[2] != 0x0 && rsp[3] != 0x0) {
-        if (ctx->debug) {
-            fprintf(stderr, "Invalid protocol ID received 0x%X (not 0x0)\n",
-                    (rsp[2] << 8) + rsp[3]);
-        }
-        errno = EMBBADDATA;
-        return -1;
-    }
-
-    return 0;
-}
-
-static int _modbus_tcp_set_ipv4_options(int s)
-{
-    int rc;
-    int option;
-
-    /* Set the TCP no delay flag */
-    /* SOL_TCP = IPPROTO_TCP */
-    option = 1;
-    rc = setsockopt(s, IPPROTO_TCP, TCP_NODELAY,
-                    (const void *)&option, sizeof(int));
-    if (rc == -1) {
-        return -1;
-    }
-
-    /* If the OS does not offer SOCK_NONBLOCK, fall back to setting FIONBIO to
-     * make sockets non-blocking */
-    /* Do not care about the return value, this is optional */
-#if !defined(SOCK_NONBLOCK) && defined(FIONBIO)
-#ifdef OS_WIN32
-    {
-        /* Setting FIONBIO expects an unsigned long according to MSDN */
-        u_long loption = 1;
-        ioctlsocket(s, FIONBIO, &loption);
-    }
-#else
-    option = 1;
-    ioctl(s, FIONBIO, &option);
-#endif
-#endif
-
-#ifndef OS_WIN32
-    /**
-     * Cygwin defines IPTOS_LOWDELAY but can't handle that flag so it's
-     * necessary to workaround that problem.
-     **/
-    /* Set the IP low delay option */
-    option = IPTOS_LOWDELAY;
-    rc = setsockopt(s, IPPROTO_IP, IP_TOS,
-                    (const void *)&option, sizeof(int));
-    if (rc == -1) {
-        return -1;
-    }
-#endif
-
-    return 0;
-}
-
-static int _connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen,
-                    const struct timeval *ro_tv)
-{
-    int rc = connect(sockfd, addr, addrlen);
-
-#ifdef OS_WIN32
-    int wsaError = 0;
-    if (rc == -1) {
-        wsaError = WSAGetLastError();
-    }
-
-    if (wsaError == WSAEWOULDBLOCK || wsaError == WSAEINPROGRESS) {
-#else
-    if (rc == -1 && errno == EINPROGRESS) {
-#endif
-        fd_set wset;
-        int optval;
-        socklen_t optlen = sizeof(optval);
-        struct timeval tv = *ro_tv;
-
-        /* Wait to be available in writing */
-        FD_ZERO(&wset);
-        FD_SET(sockfd, &wset);
-        rc = select(sockfd + 1, NULL, &wset, NULL, &tv);
-        if (rc <= 0) {
-            /* Timeout or fail */
-            return -1;
-        }
-
-        /* The connection is established if SO_ERROR and optval are set to 0 */
-        rc = getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (void *)&optval, &optlen);
-        if (rc == 0 && optval == 0) {
-            return 0;
-        } else {
-            errno = ECONNREFUSED;
-            return -1;
-        }
-    }
-    return rc;
-}
-
-/* Establishes a modbus TCP connection with a Modbus server. */
-static int _modbus_tcp_connect(modbus_t *ctx)
-{
-    int rc;
-    /* Specialized version of sockaddr for Internet socket address (same size) */
-    struct sockaddr_in addr;
-    modbus_tcp_t *ctx_tcp = ctx->backend_data;
-    int flags = SOCK_STREAM;
-
-#ifdef OS_WIN32
-    if (_modbus_tcp_init_win32() == -1) {
-        return -1;
-    }
-#endif
-
-#ifdef SOCK_CLOEXEC
-    flags |= SOCK_CLOEXEC;
-#endif
-
-#ifdef SOCK_NONBLOCK
-    flags |= SOCK_NONBLOCK;
-#endif
-
-    ctx->s = socket(PF_INET, flags, 0);
-    if (ctx->s == -1) {
-        return -1;
-    }
-
-    rc = _modbus_tcp_set_ipv4_options(ctx->s);
-    if (rc == -1) {
-        close(ctx->s);
-        ctx->s = -1;
-        return -1;
-    }
-
-    if (ctx->debug) {
-        printf("Connecting to %s:%d\n", ctx_tcp->ip, ctx_tcp->port);
-    }
-
-    addr.sin_family = AF_INET;
-    addr.sin_port = htons(ctx_tcp->port);
-    addr.sin_addr.s_addr = inet_addr(ctx_tcp->ip);
-    rc = _connect(ctx->s, (struct sockaddr *)&addr, sizeof(addr), &ctx->response_timeout);
-    if (rc == -1) {
-        close(ctx->s);
-        ctx->s = -1;
-        return -1;
-    }
-
-    return 0;
-}
-
-/* Establishes a modbus TCP PI connection with a Modbus server. */
-static int _modbus_tcp_pi_connect(modbus_t *ctx)
-{
-    int rc;
-    struct addrinfo *ai_list;
-    struct addrinfo *ai_ptr;
-    struct addrinfo ai_hints;
-    modbus_tcp_pi_t *ctx_tcp_pi = ctx->backend_data;
-
-#ifdef OS_WIN32
-    if (_modbus_tcp_init_win32() == -1) {
-        return -1;
-    }
-#endif
-
-    memset(&ai_hints, 0, sizeof(ai_hints));
-#ifdef AI_ADDRCONFIG
-    ai_hints.ai_flags |= AI_ADDRCONFIG;
-#endif
-    ai_hints.ai_family = AF_UNSPEC;
-    ai_hints.ai_socktype = SOCK_STREAM;
-    ai_hints.ai_addr = NULL;
-    ai_hints.ai_canonname = NULL;
-    ai_hints.ai_next = NULL;
-
-    ai_list = NULL;
-    rc = getaddrinfo(ctx_tcp_pi->node, ctx_tcp_pi->service,
-                     &ai_hints, &ai_list);
-    if (rc != 0) {
-        if (ctx->debug) {
-            fprintf(stderr, "Error returned by getaddrinfo: %s\n", gai_strerror(rc));
-        }
-        errno = ECONNREFUSED;
-        return -1;
-    }
-
-    for (ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next) {
-        int flags = ai_ptr->ai_socktype;
-        int s;
-
-#ifdef SOCK_CLOEXEC
-        flags |= SOCK_CLOEXEC;
-#endif
-
-#ifdef SOCK_NONBLOCK
-        flags |= SOCK_NONBLOCK;
-#endif
-
-        s = socket(ai_ptr->ai_family, flags, ai_ptr->ai_protocol);
-        if (s < 0)
-            continue;
-
-        if (ai_ptr->ai_family == AF_INET)
-            _modbus_tcp_set_ipv4_options(s);
-
-        if (ctx->debug) {
-            printf("Connecting to [%s]:%s\n", ctx_tcp_pi->node, ctx_tcp_pi->service);
-        }
-
-        rc = _connect(s, ai_ptr->ai_addr, ai_ptr->ai_addrlen, &ctx->response_timeout);
-        if (rc == -1) {
-            close(s);
-            continue;
-        }
-
-        ctx->s = s;
-        break;
-    }
-
-    freeaddrinfo(ai_list);
-
-    if (ctx->s < 0) {
-        return -1;
-    }
-
-    return 0;
-}
-
-/* Closes the network connection and socket in TCP mode */
-static void _modbus_tcp_close(modbus_t *ctx)
-{
-    if (ctx->s != -1) {
-        shutdown(ctx->s, SHUT_RDWR);
-        close(ctx->s);
-        ctx->s = -1;
-    }
-}
-
-static int _modbus_tcp_flush(modbus_t *ctx)
-{
-    int rc;
-    int rc_sum = 0;
-
-    do {
-        /* Extract the garbage from the socket */
-        char devnull[MODBUS_TCP_MAX_ADU_LENGTH];
-#ifndef OS_WIN32
-        rc = recv(ctx->s, devnull, MODBUS_TCP_MAX_ADU_LENGTH, MSG_DONTWAIT);
-#else
-        /* On Win32, it's a bit more complicated to not wait */
-        fd_set rset;
-        struct timeval tv;
-
-        tv.tv_sec = 0;
-        tv.tv_usec = 0;
-        FD_ZERO(&rset);
-        FD_SET(ctx->s, &rset);
-        rc = select(ctx->s+1, &rset, NULL, NULL, &tv);
-        if (rc == -1) {
-            return -1;
-        }
-
-        if (rc == 1) {
-            /* There is data to flush */
-            rc = recv(ctx->s, devnull, MODBUS_TCP_MAX_ADU_LENGTH, 0);
-        }
-#endif
-        if (rc > 0) {
-            rc_sum += rc;
-        }
-    } while (rc == MODBUS_TCP_MAX_ADU_LENGTH);
-
-    return rc_sum;
-}
-
-/* Listens for any request from one or many modbus masters in TCP */
-int modbus_tcp_listen(modbus_t *ctx, int nb_connection)
-{
-    int new_s;
-    int enable;
-    int flags;
-    struct sockaddr_in addr;
-    modbus_tcp_t *ctx_tcp;
-
-    if (ctx == NULL) {
-        errno = EINVAL;
-        return -1;
-    }
-
-    ctx_tcp = ctx->backend_data;
-
-#ifdef OS_WIN32
-    if (_modbus_tcp_init_win32() == -1) {
-        return -1;
-    }
-#endif
-
-    flags = SOCK_STREAM;
-
-#ifdef SOCK_CLOEXEC
-    flags |= SOCK_CLOEXEC;
-#endif
-
-    new_s = socket(PF_INET, flags, IPPROTO_TCP);
-    if (new_s == -1) {
-        return -1;
-    }
-
-    enable = 1;
-    if (setsockopt(new_s, SOL_SOCKET, SO_REUSEADDR,
-                   (char *)&enable, sizeof(enable)) == -1) {
-        close(new_s);
-        return -1;
-    }
-
-    memset(&addr, 0, sizeof(addr));
-    addr.sin_family = AF_INET;
-    /* If the modbus port is < to 1024, we need the setuid root. */
-    addr.sin_port = htons(ctx_tcp->port);
-    if (ctx_tcp->ip[0] == '0') {
-        /* Listen any addresses */
-        addr.sin_addr.s_addr = htonl(INADDR_ANY);
-    } else {
-        /* Listen only specified IP address */
-        addr.sin_addr.s_addr = inet_addr(ctx_tcp->ip);
-    }
-    if (bind(new_s, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
-        close(new_s);
-        return -1;
-    }
-
-    if (listen(new_s, nb_connection) == -1) {
-        close(new_s);
-        return -1;
-    }
-
-    return new_s;
-}
-
-int modbus_tcp_pi_listen(modbus_t *ctx, int nb_connection)
-{
-    int rc;
-    struct addrinfo *ai_list;
-    struct addrinfo *ai_ptr;
-    struct addrinfo ai_hints;
-    const char *node;
-    const char *service;
-    int new_s;
-    modbus_tcp_pi_t *ctx_tcp_pi;
-
-    if (ctx == NULL) {
-        errno = EINVAL;
-        return -1;
-    }
-
-    ctx_tcp_pi = ctx->backend_data;
-
-#ifdef OS_WIN32
-    if (_modbus_tcp_init_win32() == -1) {
-        return -1;
-    }
-#endif
-
-    if (ctx_tcp_pi->node[0] == 0) {
-        node = NULL; /* == any */
-    } else {
-        node = ctx_tcp_pi->node;
-    }
-
-    if (ctx_tcp_pi->service[0] == 0) {
-        service = "502";
-    } else {
-        service = ctx_tcp_pi->service;
-    }
-
-    memset(&ai_hints, 0, sizeof (ai_hints));
-    /* If node is not NULL, than the AI_PASSIVE flag is ignored. */
-    ai_hints.ai_flags |= AI_PASSIVE;
-#ifdef AI_ADDRCONFIG
-    ai_hints.ai_flags |= AI_ADDRCONFIG;
-#endif
-    ai_hints.ai_family = AF_UNSPEC;
-    ai_hints.ai_socktype = SOCK_STREAM;
-    ai_hints.ai_addr = NULL;
-    ai_hints.ai_canonname = NULL;
-    ai_hints.ai_next = NULL;
-
-    ai_list = NULL;
-    rc = getaddrinfo(node, service, &ai_hints, &ai_list);
-    if (rc != 0) {
-        if (ctx->debug) {
-            fprintf(stderr, "Error returned by getaddrinfo: %s\n", gai_strerror(rc));
-        }
-        errno = ECONNREFUSED;
-        return -1;
-    }
-
-    new_s = -1;
-    for (ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next) {
-        int flags = ai_ptr->ai_socktype;
-        int s;
-
-#ifdef SOCK_CLOEXEC
-        flags |= SOCK_CLOEXEC;
-#endif
-
-        s = socket(ai_ptr->ai_family, flags, ai_ptr->ai_protocol);
-        if (s < 0) {
-            if (ctx->debug) {
-                perror("socket");
-            }
-            continue;
-        } else {
-            int enable = 1;
-            rc = setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
-                            (void *)&enable, sizeof (enable));
-            if (rc != 0) {
-                close(s);
-                if (ctx->debug) {
-                    perror("setsockopt");
-                }
-                continue;
-            }
-        }
-
-        rc = bind(s, ai_ptr->ai_addr, ai_ptr->ai_addrlen);
-        if (rc != 0) {
-            close(s);
-            if (ctx->debug) {
-                perror("bind");
-            }
-            continue;
-        }
-
-        rc = listen(s, nb_connection);
-        if (rc != 0) {
-            close(s);
-            if (ctx->debug) {
-                perror("listen");
-            }
-            continue;
-        }
-
-        new_s = s;
-        break;
-    }
-    freeaddrinfo(ai_list);
-
-    if (new_s < 0) {
-        return -1;
-    }
-
-    return new_s;
-}
-
-int modbus_tcp_accept(modbus_t *ctx, int *s)
-{
-    struct sockaddr_in addr;
-    socklen_t addrlen;
-
-    if (ctx == NULL) {
-        errno = EINVAL;
-        return -1;
-    }
-
-    addrlen = sizeof(addr);
-#ifdef HAVE_ACCEPT4
-    /* Inherit socket flags and use accept4 call */
-    ctx->s = accept4(*s, (struct sockaddr *)&addr, &addrlen, SOCK_CLOEXEC);
-#else
-    ctx->s = accept(*s, (struct sockaddr *)&addr, &addrlen);
-#endif
-
-    if (ctx->s == -1) {
-        return -1;
-    }
-
-    if (ctx->debug) {
-        printf("The client connection from %s is accepted\n",
-               inet_ntoa(addr.sin_addr));
-    }
-
-    return ctx->s;
-}
-
-int modbus_tcp_pi_accept(modbus_t *ctx, int *s)
-{
-    struct sockaddr_storage addr;
-    socklen_t addrlen;
-
-    if (ctx == NULL) {
-        errno = EINVAL;
-        return -1;
-    }
-
-    addrlen = sizeof(addr);
-#ifdef HAVE_ACCEPT4
-    /* Inherit socket flags and use accept4 call */
-    ctx->s = accept4(*s, (struct sockaddr *)&addr, &addrlen, SOCK_CLOEXEC);
-#else
-    ctx->s = accept(*s, (struct sockaddr *)&addr, &addrlen);
-#endif
-
-    if (ctx->s == -1) {
-        return -1;
-    }
-
-    if (ctx->debug) {
-        printf("The client connection is accepted.\n");
-    }
-
-    return ctx->s;
-}
-
-static int _modbus_tcp_select(modbus_t *ctx, fd_set *rset, struct timeval *tv, int length_to_read)
-{
-    int s_rc;
-    while ((s_rc = select(ctx->s+1, rset, NULL, NULL, tv)) == -1) {
-        if (errno == EINTR) {
-            if (ctx->debug) {
-                fprintf(stderr, "A non blocked signal was caught\n");
-            }
-            /* Necessary after an error */
-            FD_ZERO(rset);
-            FD_SET(ctx->s, rset);
-        } else {
-            return -1;
-        }
-    }
-
-    if (s_rc == 0) {
-        errno = ETIMEDOUT;
-        return -1;
-    }
-
-    return s_rc;
-}
-
-static void _modbus_tcp_free(modbus_t *ctx) {
-    free(ctx->backend_data);
-    free(ctx);
-}
-
-const modbus_backend_t _modbus_tcp_backend = {
-    _MODBUS_BACKEND_TYPE_TCP,
-    _MODBUS_TCP_HEADER_LENGTH,
-    _MODBUS_TCP_CHECKSUM_LENGTH,
-    MODBUS_TCP_MAX_ADU_LENGTH,
-    _modbus_set_slave,
-    _modbus_tcp_build_request_basis,
-    _modbus_tcp_build_response_basis,
-    _modbus_tcp_prepare_response_tid,
-    _modbus_tcp_send_msg_pre,
-    _modbus_tcp_send,
-    _modbus_tcp_receive,
-    _modbus_tcp_recv,
-    _modbus_tcp_check_integrity,
-    _modbus_tcp_pre_check_confirmation,
-    _modbus_tcp_connect,
-    _modbus_tcp_close,
-    _modbus_tcp_flush,
-    _modbus_tcp_select,
-    _modbus_tcp_free
-};
-
-
-const modbus_backend_t _modbus_tcp_pi_backend = {
-    _MODBUS_BACKEND_TYPE_TCP,
-    _MODBUS_TCP_HEADER_LENGTH,
-    _MODBUS_TCP_CHECKSUM_LENGTH,
-    MODBUS_TCP_MAX_ADU_LENGTH,
-    _modbus_set_slave,
-    _modbus_tcp_build_request_basis,
-    _modbus_tcp_build_response_basis,
-    _modbus_tcp_prepare_response_tid,
-    _modbus_tcp_send_msg_pre,
-    _modbus_tcp_send,
-    _modbus_tcp_receive,
-    _modbus_tcp_recv,
-    _modbus_tcp_check_integrity,
-    _modbus_tcp_pre_check_confirmation,
-    _modbus_tcp_pi_connect,
-    _modbus_tcp_close,
-    _modbus_tcp_flush,
-    _modbus_tcp_select,
-    _modbus_tcp_free
-};
-
-modbus_t* modbus_new_tcp(const char *ip, int port)
-{
-    modbus_t *ctx;
-    modbus_tcp_t *ctx_tcp;
-    size_t dest_size;
-    size_t ret_size;
-
-#if defined(OS_BSD)
-    /* MSG_NOSIGNAL is unsupported on *BSD so we install an ignore
-       handler for SIGPIPE. */
-    struct sigaction sa;
-
-    sa.sa_handler = SIG_IGN;
-    if (sigaction(SIGPIPE, &sa, NULL) < 0) {
-        /* The debug flag can't be set here... */
-        fprintf(stderr, "Could not install SIGPIPE handler.\n");
-        return NULL;
-    }
-#endif
-
-    ctx = (modbus_t *)malloc(sizeof(modbus_t));
-    if (ctx == NULL) {
-        return NULL;
-    }
-    _modbus_init_common(ctx);
-
-    /* Could be changed after to reach a remote serial Modbus device */
-    ctx->slave = MODBUS_TCP_SLAVE;
-
-    ctx->backend = &_modbus_tcp_backend;
-
-    ctx->backend_data = (modbus_tcp_t *)malloc(sizeof(modbus_tcp_t));
-    if (ctx->backend_data == NULL) {
-        modbus_free(ctx);
-        errno = ENOMEM;
-        return NULL;
-    }
-    ctx_tcp = (modbus_tcp_t *)ctx->backend_data;
-
-    if (ip != NULL) {
-        dest_size = sizeof(char) * 16;
-        ret_size = strlcpy(ctx_tcp->ip, ip, dest_size);
-        if (ret_size == 0) {
-            fprintf(stderr, "The IP string is empty\n");
-            modbus_free(ctx);
-            errno = EINVAL;
-            return NULL;
-        }
-
-        if (ret_size >= dest_size) {
-            fprintf(stderr, "The IP string has been truncated\n");
-            modbus_free(ctx);
-            errno = EINVAL;
-            return NULL;
-        }
-    } else {
-        ctx_tcp->ip[0] = '0';
-    }
-    ctx_tcp->port = port;
-    ctx_tcp->t_id = 0;
-
-    return ctx;
-}
-
-
-modbus_t* modbus_new_tcp_pi(const char *node, const char *service)
-{
-    modbus_t *ctx;
-    modbus_tcp_pi_t *ctx_tcp_pi;
-    size_t dest_size;
-    size_t ret_size;
-
-    ctx = (modbus_t *)malloc(sizeof(modbus_t));
-    if (ctx == NULL) {
-        return NULL;
-    }
-    _modbus_init_common(ctx);
-
-    /* Could be changed after to reach a remote serial Modbus device */
-    ctx->slave = MODBUS_TCP_SLAVE;
-
-    ctx->backend = &_modbus_tcp_pi_backend;
-
-    ctx->backend_data = (modbus_tcp_pi_t *)malloc(sizeof(modbus_tcp_pi_t));
-    if (ctx->backend_data == NULL) {
-        modbus_free(ctx);
-        errno = ENOMEM;
-        return NULL;
-    }
-    ctx_tcp_pi = (modbus_tcp_pi_t *)ctx->backend_data;
-
-    if (node == NULL) {
-        /* The node argument can be empty to indicate any hosts */
-        ctx_tcp_pi->node[0] = 0;
-    } else {
-        dest_size = sizeof(char) * _MODBUS_TCP_PI_NODE_LENGTH;
-        ret_size = strlcpy(ctx_tcp_pi->node, node, dest_size);
-        if (ret_size == 0) {
-            fprintf(stderr, "The node string is empty\n");
-            modbus_free(ctx);
-            errno = EINVAL;
-            return NULL;
-        }
-
-        if (ret_size >= dest_size) {
-            fprintf(stderr, "The node string has been truncated\n");
-            modbus_free(ctx);
-            errno = EINVAL;
-            return NULL;
-        }
-    }
-
-    if (service != NULL) {
-        dest_size = sizeof(char) * _MODBUS_TCP_PI_SERVICE_LENGTH;
-        ret_size = strlcpy(ctx_tcp_pi->service, service, dest_size);
-    } else {
-        /* Empty service is not allowed, error catched below. */
-        ret_size = 0;
-    }
-
-    if (ret_size == 0) {
-        fprintf(stderr, "The service string is empty\n");
-        modbus_free(ctx);
-        errno = EINVAL;
-        return NULL;
-    }
-
-    if (ret_size >= dest_size) {
-        fprintf(stderr, "The service string has been truncated\n");
-        modbus_free(ctx);
-        errno = EINVAL;
-        return NULL;
-    }
-
-    ctx_tcp_pi->t_id = 0;
-
-    return ctx;
-}

+ 0 - 52
04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/modbus/modbus-tcp.h

@@ -1,52 +0,0 @@
-/*
- * Copyright © 2001-2010 Stéphane Raimbault <stephane.raimbault@gmail.com>
- *
- * SPDX-License-Identifier: LGPL-2.1+
- */
-
-#ifndef MODBUS_TCP_H
-#define MODBUS_TCP_H
-
-#include "modbus.h"
-
-MODBUS_BEGIN_DECLS
-
-#if defined(_WIN32) && !defined(__CYGWIN__)
-/* Win32 with MinGW, supplement to <errno.h> */
-#include <winsock2.h>
-#if !defined(ECONNRESET)
-#define ECONNRESET   WSAECONNRESET
-#endif
-#if !defined(ECONNREFUSED)
-#define ECONNREFUSED WSAECONNREFUSED
-#endif
-#if !defined(ETIMEDOUT)
-#define ETIMEDOUT    WSAETIMEDOUT
-#endif
-#if !defined(ENOPROTOOPT)
-#define ENOPROTOOPT  WSAENOPROTOOPT
-#endif
-#if !defined(EINPROGRESS)
-#define EINPROGRESS  WSAEINPROGRESS
-#endif
-#endif
-
-#define MODBUS_TCP_DEFAULT_PORT   502
-#define MODBUS_TCP_SLAVE         0xFF
-
-/* Modbus_Application_Protocol_V1_1b.pdf Chapter 4 Section 1 Page 5
- * TCP MODBUS ADU = 253 bytes + MBAP (7 bytes) = 260 bytes
- */
-#define MODBUS_TCP_MAX_ADU_LENGTH  260
-
-MODBUS_API modbus_t* modbus_new_tcp(const char *ip_address, int port);
-MODBUS_API int modbus_tcp_listen(modbus_t *ctx, int nb_connection);
-MODBUS_API int modbus_tcp_accept(modbus_t *ctx, int *s);
-
-MODBUS_API modbus_t* modbus_new_tcp_pi(const char *node, const char *service);
-MODBUS_API int modbus_tcp_pi_listen(modbus_t *ctx, int nb_connection);
-MODBUS_API int modbus_tcp_pi_accept(modbus_t *ctx, int *s);
-
-MODBUS_END_DECLS
-
-#endif /* MODBUS_TCP_H */

+ 0 - 53
04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/modbus/modbus-version.h

@@ -1,53 +0,0 @@
-/*
- * Copyright © 2010-2014 Stéphane Raimbault <stephane.raimbault@gmail.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifndef MODBUS_VERSION_H
-#define MODBUS_VERSION_H
-
-/* The major version, (1, if %LIBMODBUS_VERSION is 1.2.3) */
-#define LIBMODBUS_VERSION_MAJOR (3)
-
-/* The minor version (2, if %LIBMODBUS_VERSION is 1.2.3) */
-#define LIBMODBUS_VERSION_MINOR (1)
-
-/* The micro version (3, if %LIBMODBUS_VERSION is 1.2.3) */
-#define LIBMODBUS_VERSION_MICRO (6)
-
-/* The full version, like 1.2.3 */
-#define LIBMODBUS_VERSION        3.1.6
-
-/* The full version, in string form (suited for string concatenation)
- */
-#define LIBMODBUS_VERSION_STRING "3.1.6"
-
-/* Numerically encoded version, eg. v1.2.3 is 0x010203 */
-#define LIBMODBUS_VERSION_HEX ((LIBMODBUS_VERSION_MAJOR << 16) |  \
-                               (LIBMODBUS_VERSION_MINOR <<  8) |  \
-                               (LIBMODBUS_VERSION_MICRO <<  0))
-
-/* Evaluates to True if the version is greater than @major, @minor and @micro
- */
-#define LIBMODBUS_VERSION_CHECK(major,minor,micro)      \
-    (LIBMODBUS_VERSION_MAJOR > (major) ||               \
-     (LIBMODBUS_VERSION_MAJOR == (major) &&             \
-      LIBMODBUS_VERSION_MINOR > (minor)) ||             \
-     (LIBMODBUS_VERSION_MAJOR == (major) &&             \
-      LIBMODBUS_VERSION_MINOR == (minor) &&             \
-      LIBMODBUS_VERSION_MICRO >= (micro)))
-
-#endif /* MODBUS_VERSION_H */

File diff suppressed because it is too large
+ 0 - 1911
04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/modbus/modbus.c


+ 0 - 293
04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/modbus/modbus.h

@@ -1,293 +0,0 @@
-/*
- * Copyright © 2001-2013 Stéphane Raimbault <stephane.raimbault@gmail.com>
- *
- * SPDX-License-Identifier: LGPL-2.1+
- */
-
-#ifndef MODBUS_H
-#define MODBUS_H
-
-/* Add this for macros that defined unix flavor */
-#if (defined(__unix__) || defined(unix)) && !defined(USG)
-#include <sys/param.h>
-#endif
-
-#ifndef _MSC_VER
-#include <stdint.h>
-#else
-#include "stdint.h"
-#endif
-
-#include "modbus-version.h"
-
-#if defined(_MSC_VER)
-# if defined(DLLBUILD)
-/* define DLLBUILD when building the DLL */
-#  define MODBUS_API __declspec(dllexport)
-# else
-#  define MODBUS_API __declspec(dllimport)
-# endif
-#else
-# define MODBUS_API
-#endif
-
-#ifdef  __cplusplus
-# define MODBUS_BEGIN_DECLS  extern "C" {
-# define MODBUS_END_DECLS    }
-#else
-# define MODBUS_BEGIN_DECLS
-# define MODBUS_END_DECLS
-#endif
-
-MODBUS_BEGIN_DECLS
-
-#ifndef FALSE
-#define FALSE 0
-#endif
-
-#ifndef TRUE
-#define TRUE 1
-#endif
-
-#ifndef OFF
-#define OFF 0
-#endif
-
-#ifndef ON
-#define ON 1
-#endif
-
-/* Modbus function codes */
-#define MODBUS_FC_READ_COILS                0x01
-#define MODBUS_FC_READ_DISCRETE_INPUTS      0x02
-#define MODBUS_FC_READ_HOLDING_REGISTERS    0x03
-#define MODBUS_FC_READ_INPUT_REGISTERS      0x04
-#define MODBUS_FC_WRITE_SINGLE_COIL         0x05
-#define MODBUS_FC_WRITE_SINGLE_REGISTER     0x06
-#define MODBUS_FC_READ_EXCEPTION_STATUS     0x07
-#define MODBUS_FC_WRITE_MULTIPLE_COILS      0x0F
-#define MODBUS_FC_WRITE_MULTIPLE_REGISTERS  0x10
-#define MODBUS_FC_REPORT_SLAVE_ID           0x11
-#define MODBUS_FC_MASK_WRITE_REGISTER       0x16
-#define MODBUS_FC_WRITE_AND_READ_REGISTERS  0x17
-
-#define MODBUS_BROADCAST_ADDRESS    0
-
-/* Modbus_Application_Protocol_V1_1b.pdf (chapter 6 section 1 page 12)
- * Quantity of Coils to read (2 bytes): 1 to 2000 (0x7D0)
- * (chapter 6 section 11 page 29)
- * Quantity of Coils to write (2 bytes): 1 to 1968 (0x7B0)
- */
-#define MODBUS_MAX_READ_BITS              2000
-#define MODBUS_MAX_WRITE_BITS             1968
-
-/* Modbus_Application_Protocol_V1_1b.pdf (chapter 6 section 3 page 15)
- * Quantity of Registers to read (2 bytes): 1 to 125 (0x7D)
- * (chapter 6 section 12 page 31)
- * Quantity of Registers to write (2 bytes) 1 to 123 (0x7B)
- * (chapter 6 section 17 page 38)
- * Quantity of Registers to write in R/W registers (2 bytes) 1 to 121 (0x79)
- */
-#define MODBUS_MAX_READ_REGISTERS          125
-#define MODBUS_MAX_WRITE_REGISTERS         123
-#define MODBUS_MAX_WR_WRITE_REGISTERS      121
-#define MODBUS_MAX_WR_READ_REGISTERS       125
-
-/* The size of the MODBUS PDU is limited by the size constraint inherited from
- * the first MODBUS implementation on Serial Line network (max. RS485 ADU = 256
- * bytes). Therefore, MODBUS PDU for serial line communication = 256 - Server
- * address (1 byte) - CRC (2 bytes) = 253 bytes.
- */
-#define MODBUS_MAX_PDU_LENGTH              253
-
-/* Consequently:
- * - RTU MODBUS ADU = 253 bytes + Server address (1 byte) + CRC (2 bytes) = 256
- *   bytes.
- * - TCP MODBUS ADU = 253 bytes + MBAP (7 bytes) = 260 bytes.
- * so the maximum of both backend in 260 bytes. This size can used to allocate
- * an array of bytes to store responses and it will be compatible with the two
- * backends.
- */
-#define MODBUS_MAX_ADU_LENGTH              260
-
-/* Random number to avoid errno conflicts */
-#define MODBUS_ENOBASE 112345678
-
-/* Protocol exceptions */
-enum {
-    MODBUS_EXCEPTION_ILLEGAL_FUNCTION = 0x01,
-    MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS,
-    MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE,
-    MODBUS_EXCEPTION_SLAVE_OR_SERVER_FAILURE,
-    MODBUS_EXCEPTION_ACKNOWLEDGE,
-    MODBUS_EXCEPTION_SLAVE_OR_SERVER_BUSY,
-    MODBUS_EXCEPTION_NEGATIVE_ACKNOWLEDGE,
-    MODBUS_EXCEPTION_MEMORY_PARITY,
-    MODBUS_EXCEPTION_NOT_DEFINED,
-    MODBUS_EXCEPTION_GATEWAY_PATH,
-    MODBUS_EXCEPTION_GATEWAY_TARGET,
-    MODBUS_EXCEPTION_MAX
-};
-
-#define EMBXILFUN  (MODBUS_ENOBASE + MODBUS_EXCEPTION_ILLEGAL_FUNCTION)
-#define EMBXILADD  (MODBUS_ENOBASE + MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS)
-#define EMBXILVAL  (MODBUS_ENOBASE + MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE)
-#define EMBXSFAIL  (MODBUS_ENOBASE + MODBUS_EXCEPTION_SLAVE_OR_SERVER_FAILURE)
-#define EMBXACK    (MODBUS_ENOBASE + MODBUS_EXCEPTION_ACKNOWLEDGE)
-#define EMBXSBUSY  (MODBUS_ENOBASE + MODBUS_EXCEPTION_SLAVE_OR_SERVER_BUSY)
-#define EMBXNACK   (MODBUS_ENOBASE + MODBUS_EXCEPTION_NEGATIVE_ACKNOWLEDGE)
-#define EMBXMEMPAR (MODBUS_ENOBASE + MODBUS_EXCEPTION_MEMORY_PARITY)
-#define EMBXGPATH  (MODBUS_ENOBASE + MODBUS_EXCEPTION_GATEWAY_PATH)
-#define EMBXGTAR   (MODBUS_ENOBASE + MODBUS_EXCEPTION_GATEWAY_TARGET)
-
-/* Native libmodbus error codes */
-#define EMBBADCRC  (EMBXGTAR + 1)
-#define EMBBADDATA (EMBXGTAR + 2)
-#define EMBBADEXC  (EMBXGTAR + 3)
-#define EMBUNKEXC  (EMBXGTAR + 4)
-#define EMBMDATA   (EMBXGTAR + 5)
-#define EMBBADSLAVE (EMBXGTAR + 6)
-
-extern const unsigned int libmodbus_version_major;
-extern const unsigned int libmodbus_version_minor;
-extern const unsigned int libmodbus_version_micro;
-
-typedef struct _modbus modbus_t;
-
-typedef struct _modbus_mapping_t {
-    int nb_bits;
-    int start_bits;
-    int nb_input_bits;
-    int start_input_bits;
-    int nb_input_registers;
-    int start_input_registers;
-    int nb_registers;
-    int start_registers;
-    uint8_t *tab_bits;
-    uint8_t *tab_input_bits;
-    uint16_t *tab_input_registers;
-    uint16_t *tab_registers;
-} modbus_mapping_t;
-
-typedef enum
-{
-    MODBUS_ERROR_RECOVERY_NONE          = 0,
-    MODBUS_ERROR_RECOVERY_LINK          = (1<<1),
-    MODBUS_ERROR_RECOVERY_PROTOCOL      = (1<<2)
-} modbus_error_recovery_mode;
-
-MODBUS_API int modbus_set_slave(modbus_t* ctx, int slave);
-MODBUS_API int modbus_get_slave(modbus_t* ctx);
-MODBUS_API int modbus_set_error_recovery(modbus_t *ctx, modbus_error_recovery_mode error_recovery);
-MODBUS_API int modbus_set_socket(modbus_t *ctx, int s);
-MODBUS_API int modbus_get_socket(modbus_t *ctx);
-
-MODBUS_API int modbus_get_response_timeout(modbus_t *ctx, uint32_t *to_sec, uint32_t *to_usec);
-MODBUS_API int modbus_set_response_timeout(modbus_t *ctx, uint32_t to_sec, uint32_t to_usec);
-
-MODBUS_API int modbus_get_byte_timeout(modbus_t *ctx, uint32_t *to_sec, uint32_t *to_usec);
-MODBUS_API int modbus_set_byte_timeout(modbus_t *ctx, uint32_t to_sec, uint32_t to_usec);
-
-MODBUS_API int modbus_get_indication_timeout(modbus_t *ctx, uint32_t *to_sec, uint32_t *to_usec);
-MODBUS_API int modbus_set_indication_timeout(modbus_t *ctx, uint32_t to_sec, uint32_t to_usec);
-
-MODBUS_API int modbus_get_header_length(modbus_t *ctx);
-
-MODBUS_API int modbus_connect(modbus_t *ctx);
-MODBUS_API void modbus_close(modbus_t *ctx);
-
-MODBUS_API void modbus_free(modbus_t *ctx);
-
-MODBUS_API int modbus_flush(modbus_t *ctx);
-MODBUS_API int modbus_set_debug(modbus_t *ctx, int flag);
-
-MODBUS_API const char *modbus_strerror(int errnum);
-
-MODBUS_API int modbus_read_bits(modbus_t *ctx, int addr, int nb, uint8_t *dest);
-MODBUS_API int modbus_read_input_bits(modbus_t *ctx, int addr, int nb, uint8_t *dest);
-MODBUS_API int modbus_read_registers(modbus_t *ctx, int addr, int nb, uint16_t *dest);
-MODBUS_API int modbus_read_input_registers(modbus_t *ctx, int addr, int nb, uint16_t *dest);
-MODBUS_API int modbus_write_bit(modbus_t *ctx, int coil_addr, int status);
-MODBUS_API int modbus_write_register(modbus_t *ctx, int reg_addr, const uint16_t value);
-MODBUS_API int modbus_write_bits(modbus_t *ctx, int addr, int nb, const uint8_t *data);
-MODBUS_API int modbus_write_registers(modbus_t *ctx, int addr, int nb, const uint16_t *data);
-MODBUS_API int modbus_mask_write_register(modbus_t *ctx, int addr, uint16_t and_mask, uint16_t or_mask);
-MODBUS_API int modbus_write_and_read_registers(modbus_t *ctx, int write_addr, int write_nb,
-                                               const uint16_t *src, int read_addr, int read_nb,
-                                               uint16_t *dest);
-MODBUS_API int modbus_report_slave_id(modbus_t *ctx, int max_dest, uint8_t *dest);
-
-MODBUS_API modbus_mapping_t* modbus_mapping_new_start_address(
-    unsigned int start_bits, unsigned int nb_bits,
-    unsigned int start_input_bits, unsigned int nb_input_bits,
-    unsigned int start_registers, unsigned int nb_registers,
-    unsigned int start_input_registers, unsigned int nb_input_registers);
-
-MODBUS_API modbus_mapping_t* modbus_mapping_new(int nb_bits, int nb_input_bits,
-                                                int nb_registers, int nb_input_registers);
-MODBUS_API void modbus_mapping_free(modbus_mapping_t *mb_mapping);
-
-MODBUS_API int modbus_send_raw_request(modbus_t *ctx, const uint8_t *raw_req, int raw_req_length);
-
-MODBUS_API int modbus_receive(modbus_t *ctx, uint8_t *req);
-
-MODBUS_API int modbus_receive_confirmation(modbus_t *ctx, uint8_t *rsp);
-
-MODBUS_API int modbus_reply(modbus_t *ctx, const uint8_t *req,
-                            int req_length, modbus_mapping_t *mb_mapping);
-MODBUS_API int modbus_reply_exception(modbus_t *ctx, const uint8_t *req,
-                                      unsigned int exception_code);
-
-/**
- * UTILS FUNCTIONS
- **/
-
-#define MODBUS_GET_HIGH_BYTE(data) (((data) >> 8) & 0xFF)
-#define MODBUS_GET_LOW_BYTE(data) ((data) & 0xFF)
-#define MODBUS_GET_INT64_FROM_INT16(tab_int16, index) \
-    (((int64_t)tab_int16[(index)    ] << 48) + \
-     ((int64_t)tab_int16[(index) + 1] << 32) + \
-     ((int64_t)tab_int16[(index) + 2] << 16) + \
-      (int64_t)tab_int16[(index) + 3])
-#define MODBUS_GET_INT32_FROM_INT16(tab_int16, index) ((tab_int16[(index)] << 16) + tab_int16[(index) + 1])
-#define MODBUS_GET_INT16_FROM_INT8(tab_int8, index) ((tab_int8[(index)] << 8) + tab_int8[(index) + 1])
-#define MODBUS_SET_INT16_TO_INT8(tab_int8, index, value) \
-    do { \
-        tab_int8[(index)] = (value) >> 8;  \
-        tab_int8[(index) + 1] = (value) & 0xFF; \
-    } while (0)
-#define MODBUS_SET_INT32_TO_INT16(tab_int16, index, value) \
-    do { \
-        tab_int16[(index)    ] = (value) >> 16; \
-        tab_int16[(index) + 1] = (value); \
-    } while (0)
-#define MODBUS_SET_INT64_TO_INT16(tab_int16, index, value) \
-    do { \
-        tab_int16[(index)    ] = (value) >> 48; \
-        tab_int16[(index) + 1] = (value) >> 32; \
-        tab_int16[(index) + 2] = (value) >> 16; \
-        tab_int16[(index) + 3] = (value); \
-    } while (0)
-
-MODBUS_API void modbus_set_bits_from_byte(uint8_t *dest, int idx, const uint8_t value);
-MODBUS_API void modbus_set_bits_from_bytes(uint8_t *dest, int idx, unsigned int nb_bits,
-                                       const uint8_t *tab_byte);
-MODBUS_API uint8_t modbus_get_byte_from_bits(const uint8_t *src, int idx, unsigned int nb_bits);
-MODBUS_API float modbus_get_float(const uint16_t *src);
-MODBUS_API float modbus_get_float_abcd(const uint16_t *src);
-MODBUS_API float modbus_get_float_dcba(const uint16_t *src);
-MODBUS_API float modbus_get_float_badc(const uint16_t *src);
-MODBUS_API float modbus_get_float_cdab(const uint16_t *src);
-
-MODBUS_API void modbus_set_float(float f, uint16_t *dest);
-MODBUS_API void modbus_set_float_abcd(float f, uint16_t *dest);
-MODBUS_API void modbus_set_float_dcba(float f, uint16_t *dest);
-MODBUS_API void modbus_set_float_badc(float f, uint16_t *dest);
-MODBUS_API void modbus_set_float_cdab(float f, uint16_t *dest);
-
-#include "modbus-tcp.h"
-#include "modbus-rtu.h"
-
-MODBUS_END_DECLS
-
-#endif  /* MODBUS_H */

File diff suppressed because it is too large
+ 4704 - 2406
04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/mongoose/mongoose.c


File diff suppressed because it is too large
+ 601 - 520
04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/mongoose/mongoose.h


+ 73 - 121
04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/src/app.c

@@ -10,10 +10,9 @@
 #include "elog.h"
 #include "sensor_handle.h"
 #include "websocket_handle.h"
+#include "sys.h"
 
 static int keep_running;
-int get_path(char *path, char *name);
-
 RETSIGTYPE stop_server(int __attribute__((unused)) a)
 {
     keep_running = 0;
@@ -22,10 +21,9 @@ RETSIGTYPE stop_server(int __attribute__((unused)) a)
 /// @brief 电源数据采集线程
 /// @param arg 
 /// @return 
-int _global_power_samp_func(void* arg)
+void* power_thread(void* arg)
 {
     int ret = 0 ;
-    GlobalDeviceManager* _globalDeviceManager = (GlobalDeviceManager*)arg;
     GlobalPowerManger* _globalPowerMangerTemp = NULL ;
     GlobalPowerInfo _globalPowerInfo ;
     GlobalPowerInfo _globalTotalPowerInfo ; //总电源信息
@@ -34,6 +32,9 @@ int _global_power_samp_func(void* arg)
     struct timeval tv;
     struct timezone tz ;
     int nSaveIndex =0;
+    thread_handle_t *h=(thread_handle_t*)arg;
+    GlobalDeviceManager* _globalDeviceManager = (GlobalDeviceManager*)h->arg;
+    
     dev_search_last_Index(_globalDeviceManager->db,&nSaveIndex);//查询日志最大点
     _globalDeviceManager->_global_alarmLanguage=create_hash_table(13);
     InitHashTable(_globalDeviceManager->_global_alarmLanguage);
@@ -62,8 +63,9 @@ int _global_power_samp_func(void* arg)
         }
         //usleep(300000);
     }
+    
     //采集线程
-    while (_globalDeviceManager->dev_samp_flag)
+    while (h->quit==0)
     {
         if (_globalDeviceManager->_ReloadChm_flag)
         {
@@ -497,7 +499,7 @@ int _global_power_samp_func(void* arg)
 /// @brief 传感器硬件接口初始化
 /// @param _globalDeviceManager 
 /// @return 
-int dev_sensor_init(GlobalDeviceManager* _globalDeviceManager)
+int sensor_init(GlobalDeviceManager* _globalDeviceManager)
 {
     int ret = 0 ;
 
@@ -510,7 +512,7 @@ int dev_sensor_init(GlobalDeviceManager* _globalDeviceManager)
                         "sensor");
     if(ret!=0)
     {
-        printf("sensor modbus init error.\n");
+        log_e("sensor modbus init error.\n");
     }
 
 
@@ -522,10 +524,11 @@ int dev_sensor_init(GlobalDeviceManager* _globalDeviceManager)
 /// @brief 传感器采集线程
 /// @param arg 
 /// @return 
-int _global_sensor_samp_func(void* arg)
+void* sensor_thread(void* arg)
 {
+    thread_handle_t *h=(thread_handle_t*)arg;
+    GlobalDeviceManager* _globalDeviceManager = (GlobalDeviceManager*)h->arg;
     #if 0
-    GlobalDeviceManager* _globalDeviceManager = (GlobalDeviceManager*)arg;
     unsigned int samp_time = _globalDeviceManager->_global_device_info->product_samp_time;
     GlobalSensorManger* _globalSensorMangerTemp;
     int ret = 0 ;
@@ -536,12 +539,12 @@ int _global_sensor_samp_func(void* arg)
     //硬件初始化
     //初始化modbus
     //初始化gpio
-    dev_sensor_init(_globalDeviceManager);
+    sensor_init(_globalDeviceManager);
 
             float temperature =0.0;
                     float humidity =0.0;
     //采集线程
-    while (_globalDeviceManager->dev_samp_flag)
+    while (h->quit)
     {
         list_for_each_entry(_globalSensorMangerTemp, &_globalDeviceManager->_globalSensorManger.list, list)
         {
@@ -605,12 +608,13 @@ int _global_sensor_samp_func(void* arg)
     pthread_exit(NULL);
 }
 
-int ntp_thread(void *arg)
+void* ntp_thread(void *arg)
 {
     time_t start_t, end_t;
+    thread_handle_t *h=(thread_handle_t*)arg;
 
     start_t = time(NULL);
-    while(bStopNTPthread == false)
+    while(h->quit==0)
     {
         if (end_t - start_t >= 1 && _globalNTPManager.mode == true)
         {
@@ -619,8 +623,7 @@ int ntp_thread(void *arg)
             if (getCurrentTimeFromNTP(globalNTPclient, &current_time) < 0)
             {  
                 log_e("Failed to get time from NTP server.");  
-                destroyNTPClient(globalNTPclient);  
-                return;  
+                continue;
             }
             time_t t = time(NULL);
             struct tm* ptm = localtime(&t);
@@ -634,21 +637,22 @@ int ntp_thread(void *arg)
     }
     destroyNTPClient(globalNTPclient);
 
-    return 0;
+    pthread_exit(NULL);
 }
 
-int snmp_thread(void *arg)
+void* snmp_thread(void *arg)
 {
     //int ret = 0 ;
-    //GlobalDeviceManager* _globalDeviceManager = (GlobalDeviceManager*)arg;
+    thread_handle_t *h=(thread_handle_t*)arg;
+    
+    /* we are a subagent */
     char path[PATH_MAX];
-
     /* we are a subagent */
     
     netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_ROLE, 1);
     
     /* initialize the agent library */
-    get_path(path, SNMP_MIB_NAME);
+    sys_get_path(path, SNMP_MIB_NAME);
     init_agent(path);
     
     /* initialize your mib code here */
@@ -658,7 +662,7 @@ int snmp_thread(void *arg)
     /* pduMIB will be used to read pduMIB.conf files. */
     init_snmp(path);
     int reconfig=0;
-    while(bStopNTPthread == false)
+    while(h->quit==0)
     {
         if (reconfig) {  
         free_config();  
@@ -674,21 +678,41 @@ int snmp_thread(void *arg)
     /* shutdown the agent library */
     shutdown_agent();
 
-    return 0;
+    pthread_exit(NULL);
+}
+
+
+
+#include <errno.h>
+#include <sys/ipc.h> 
+#include <sys/msg.h>
+#include "upgrade.h"
+static key_t upgkey=0;
+int upg_send(int evt)
+{
+    int r,msgid;
+    upgrade_msg_t msg={.type=1, .evt=evt};
+
+    msgid = msgget(upgkey, 0666| IPC_CREAT);
+    log_e("+++++++++++ key: %d, msgid: %d\n", upgkey, msgid);
+    
+    r = msgsnd(msgid, &msg, sizeof(msg), IPC_NOWAIT);
+    if(r<0) {
+        log_e("+++++++++++ msgsnd failed, %d, errno: %d\n", r, errno);
+    }
+    
+    return r;
 }
-int get_path(char *path, char *name)
+static int upg_init(void)
 {
-    char tmp[PATH_MAX];
-
-    pid_t pid = getpid();
-    snprintf(tmp, sizeof(tmp), "/proc/%d/exe", pid); 
-    readlink(tmp, path, sizeof(tmp));
-    char *p = strrchr(path, '/');
-    if(p && strlen(path)>1) {
-        *p = 0;
-        strcat(path, "/");
-        strcat(path, name);
+    int r,msgid;
+    
+    upgkey = ftok(UPG_KEY_PATH, UPG_KEY_SN);
+    if(upgkey<0) {
+        log_e("ftok %s failed, errno: %d\n", UPG_KEY_PATH, errno);
+        return -1;
     }
+    upg_send(UPGRADE_EVT_APP_RUNNING);
     
     return 0;
 }
@@ -703,10 +727,9 @@ int _global_device_manage_init(GlobalDeviceManager* _globalDeviceManager)
     int ret = 0 ;
     int type = 0 ;
     int chn = 0 ;
-
+    char path[PATH_MAX];
     int io_thread_flag = 0 ;
     int sensor_thread_flag = 0 ;
-    char path[PATH_MAX];
 
     //初始化用户登录列表
     INIT_LIST_HEAD(&_GlobalUserLoginInfo.list);
@@ -724,14 +747,15 @@ int _global_device_manage_init(GlobalDeviceManager* _globalDeviceManager)
     _globalDeviceManager->useSlaveCount = 0 ;
 
     //链接数据库获取配置信息
-    get_path(path, DATABASE_NAME);
+    sys_get_path(path, DATABASE_NAME);
+    log_i("database: %s\n", path);
     ret = sqlite_init(&_globalDeviceManager->db, path);
     if(ret<0)
     {
-        log_e("open database error.\n");
+        log_e("database %s open error.\n", path);
         return -1 ;
     }
-    log_i("database init ok.\n");
+    log_i("database %s open ok.\n", path);
 
     //查询设备总体参数
     if(dev_get_device_info(_globalDeviceManager->db,_globalDeviceManager->_global_device_info)!=0)
@@ -1187,11 +1211,14 @@ int _global_device_manage_init(GlobalDeviceManager* _globalDeviceManager)
 #endif
     //查询数据库获取传感器信息 
 
+    //保存配置
+    paras_save();    
+
     //创建modbus采集线程 继电器控制线程
     #if(OS_HANDWARE==1)
     _globalDeviceManager->dev_samp_flag = true;
-    pthread_create(&_globalDeviceManager->dev_samp_thread, NULL,_global_power_samp_func,_globalDeviceManager);
-    pthread_create(&_globalDeviceManager->sensor_thread, NULL,_global_sensor_samp_func,_globalDeviceManager);
+    sys_start_thread(THREAD_ID_POWER,  power_thread, _globalDeviceManager);
+    sys_start_thread(THREAD_ID_SENSOR, sensor_thread, _globalDeviceManager);
    #endif
     //创建传感器采集控制线程
 
@@ -1227,94 +1254,19 @@ int _global_device_manage_init(GlobalDeviceManager* _globalDeviceManager)
         log_d("get ntp info from database succeeded");
     }
 
-    pthread_create(&NTPthread, NULL, ntp_thread, NULL);
-#endif
-#if 0
-    _globalSNMPManager.public = malloc(128);
-    _globalSNMPManager.version = malloc(128);
-    ret = dev_get_snmp_info(_globalDeviceManager->db,  &_globalSNMPManager);
-    if (ret == -1)
-    {
-        log_e("get snmp info from database failed");
-    }
-    else if (ret == -2)
-    {
-        _globalSNMPManager.mode = 1;
-        _globalSNMPManager.version = 0;
-        strcpy(_globalSNMPManager.public, "SNMP");
-        _globalSNMPManager.product_id = _globalDeviceManager->_global_device_info->product_id;
-        _globalSNMPManager.trapmode = 1;
-        if (dev_insert_snmp_info(_globalDeviceManager->db,  &_globalSNMPManager))
-        {
-            log_e("insert snmp info failed");
-        }
-    }
-    else
-    {
-        log_d("get snmp info from database succeeded");
-    }
+    sys_start_thread(THREAD_ID_NTP, ntp_thread, NULL);
 #endif
-    // globalSMTPManager.account = malloc(128);
-    // globalSMTPManager.password = malloc(128);
-    // globalSMTPManager.server = malloc(128);
-    // ret = dev_get_smtp_info(_globalDeviceManager->db, &globalSMTPManager);
-    // if (ret)
-    // {
-    //     log_e("get smtp info from database failed");
-    // }
-    // else
-    // {
-    //     log_d("get smtp info from database succeeded");
-    // }
-    // INIT_LIST_HEAD(&globalSMTPManager.receive_account->list);
-    // ret = dev_get_smtp_recv_user_list(_globalDeviceManager->db, globalSMTPManager.receive_account);
-    // if (ret)
-    // {
-    //     log_e("get smtp receive user list from database failed");
-    // }
-    // else
-    // {
-    //     log_d("get smtp receive user list from database succeeded");
-    // }
-    //snmp线程
-    pthread_create(&_globalDeviceManager->snmp_agent_thread, NULL,snmp_thread,_globalDeviceManager);
+    sys_start_thread(THREAD_ID_SNMP, snmp_thread, _globalDeviceManager);
+
+    cascade_init();
     
     //初始化webapp
     websocket_init();
     appweb_init();
-    //
-    #if 0//合并到线程中
-    const char *app_name = "pduMIB";
-    /* we are a subagent */
-    netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_ROLE, 1);
-    
-    /* initialize the agent library */
-    init_agent(app_name);
-    
-    /* initialize your mib code here */
-    init_pduMIB_form();
-    init_pduMIB_scalar();
-    
-    /* pduMIB will be used to read pduMIB.conf files. */
-    init_snmp("pduMIB");
 
-    keep_running = 1;
-    while(keep_running)
-    {
-        agent_check_and_process(1);/* block every 1 second */
-    }
-    /* at shutdown time */
-    snmp_shutdown(app_name);
-    
-    /* deinitialize your mib code here */
+    //通知upgd,app已经运行起来
+    upg_init();
     
-    /* shutdown the agent library */
-    shutdown_agent();
-    #endif
-    //等待
-    pthread_join(_globalDeviceManager->dev_samp_thread,NULL);
-    pthread_join(NTPthread, NULL);
-    pthread_join(_globalDeviceManager->snmp_agent_thread,NULL);
     while(1)
     {
         sleep(1);

+ 4 - 0
04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/src/appweb.conf

@@ -6,6 +6,10 @@ Listen 80
 AddHandler fileHandler
 # AddHandler espHandler esp
 
+Documents ../web
+UploadDir /root/dl
+LimitUpload 100MB
+
 
 <Route ^/action/>
     SetHandler actionHandler

File diff suppressed because it is too large
+ 500 - 320
04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/src/appweb_handle.c


+ 235 - 0
04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/src/cascade.c

@@ -0,0 +1,235 @@
+#include "cascade.h"
+#include "common.h"
+#include "xlist.h"
+#include "elog.h"
+#include "modbus-rtu.h"
+#include "sys.h"
+
+
+#if 0
+#define LOGD   log_d
+#define LOGE   log_e
+#else
+#define LOGD   printf
+#define LOGE   printf
+#endif
+
+
+#define ERR_MAX                 5
+#define CASCADE_MAX             247
+
+
+typedef struct {
+    uint8_t             addr;
+    int                 err;      //err times
+}slave_t;
+
+typedef struct {
+    Modbus_Manger       m;  //级联modbus口
+    handle_t            l;
+    int                 inited;
+    
+    modbus_mapping_t    *map;
+    uint8_t             query[MODBUS_RTU_MAX_ADU_LENGTH];
+}cascade_handle_t;
+
+static cascade_handle_t casHandle={0}; 
+
+static inline GlobalDeviceManager *get_dm(void)
+{
+    return &__globalDeviceManage;
+}
+
+static int iterator_fn(handle_t l, node_t *node, node_t *xd, void *arg, int *act)
+{
+    slave_t *s1 = (slave_t*)node->buf;
+    slave_t *s2 = (slave_t*)xd->buf;
+    
+    if(s1->addr==s2->addr) {
+        *act = LIST_ACT_STOP;
+        return 1;
+    }
+    return 0;
+}
+
+static int in_list(cascade_handle_t *cas, int addr)
+{
+    int r=0;
+    slave_t sl={addr,0};
+    node_t nod={0, &sl,sizeof(sl),sizeof(sl)};
+
+    r = xlist_iterator(cas->l, &nod, iterator_fn, NULL);
+    if(r<0) r=0;
+    
+    return r;
+}
+
+static int cascade_scan(cascade_handle_t *cas)
+{
+    int i,r=0 ;
+    slave_t slav;
+    uint16_t tmp[100];
+
+    for(i=1; i<CASCADE_MAX; i++) {
+        if(!in_list(cas, i)) {
+            r = g_modbus_read_reg(&cas->m, i, CASCADE_REG_SCAN, tmp);;
+            if(r==0) {
+                slav.addr = i; slav.err = 0;
+
+                xlist_append(cas->l, 0, &slav, sizeof(slav));
+            }
+        }
+    }
+    LOGD("___cascade scan, slave num: %d\n", xlist_size(cas->l));
+        
+    return 0;
+}
+static int master_query(cascade_handle_t *cas)
+{
+    int i,r,sz;
+    list_node_t *ln;
+    uint16_t tmp[100];
+
+    sz = xlist_size(cas->l);
+    for(i=0; i<sz; i++) {
+        r = xlist_take_node(cas->l, &ln, 0);
+        if(r==0) {
+            slave_t *sl=(slave_t*)ln->data.buf;
+            r = g_modbus_read_reg(&cas->m, sl->addr, CASCADE_REG_POWER, tmp);
+            if(r==0) {
+                sl->err = 0;
+            }
+            else {
+                sl->err++;
+            }
+
+            if(sl->err>=ERR_MAX) {      //错误次数超限后,从设备列表删除
+                xlist_back_node(cas->l, ln);
+            }
+            else {
+                xlist_append_node(cas->l, ln);
+            }
+        }
+    }
+
+}
+static int slave_rceive(cascade_handle_t *cas)
+{
+    int r;
+
+    r = g_modbus_receive(&cas->m, cas->query);
+    if (r > 0) {
+        //r = g_modbus_reply(&cas->m, cas->query, r, cas->map);
+    }
+
+    return r;
+}
+
+
+
+static void* cascade_thread(void *arg)
+{
+    int r;
+    thread_handle_t *h=(thread_handle_t*)arg;
+    cascade_handle_t *cas=&casHandle;
+    ModbusInfo_t *info=&get_dm()->_global_device_info->_gmodbus_info;
+    
+    while(h->quit==0) {
+        
+        if(info->product_modbus_type==0) {      //主模式
+            r= master_query(cas);
+        }
+        else {                                  //从模式,等待主设备发起数据请求
+            r = slave_rceive(cas);
+        }  
+    }
+    modbus_mapping_free(cas->map);
+    
+    pthread_exit(NULL);
+}
+static void* scan_thread(void *arg)
+{
+    int r;
+    cascade_handle_t *cas=&casHandle;
+    ModbusInfo_t *info=&get_dm()->_global_device_info->_gmodbus_info;
+    
+    while(1) {
+        if(info->product_modbus_type==0) {  //master
+            r = cascade_scan(cas);
+        }
+        sleep(5);
+    }
+
+    pthread_exit(NULL);
+}
+
+
+int mbus_init(void)
+{
+    int r;
+    cascade_handle_t *cas=&casHandle;
+    ModbusInfo_t *info=&get_dm()->_global_device_info->_gmodbus_info;
+
+    if(cas->inited) {
+        g_modbus_deinit(&cas->m);
+    }
+
+    cas->inited = 0;
+    r = g_modbus_init(&cas->m,
+                        CASCADE_MODBUS_PORT,
+                        info->product_modbus_baud,
+                        info->product_modbus_type,
+                        (info->product_modbus_type==0)?0:info->product_modbus_addr,
+                        "cascade");
+    if(r!=0) {
+        LOGE("cascade modbus init error.\n");
+        return -1;
+    }
+    cas->inited = 1;
+
+    return 0;
+}
+
+
+
+int cascade_init(void)
+{
+    int i,r=0;
+    list_cfg_t lc;
+    cascade_handle_t *cas=&casHandle;
+    
+    lc.log = 0;
+    lc.max = 100;
+    lc.mode = LIST_FULL_FIFO;
+    cas->l = xlist_init(&lc);
+    cas->map = modbus_mapping_new(MODBUS_MAX_READ_BITS, 0, MODBUS_MAX_READ_REGISTERS, 0);
+
+    mbus_init();
+
+    sys_start_thread(THREAD_ID_CASCADE, cascade_thread, NULL);
+    sys_start_thread(THREAD_ID_SCAN, scan_thread, NULL);
+        
+    return 0;
+}
+
+
+int cascade_reinit(void)
+{
+    return mbus_init();
+}
+
+
+int cascade_get(int addr, int type, void* data)
+{
+    return 0;
+}
+
+
+int cascade_set(int addr, int type, void* data)
+{
+    return 0;
+}
+
+
+
+

+ 46 - 0
04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/src/cascade.h

@@ -0,0 +1,46 @@
+#ifndef __CASCADE_Hx__
+#define __CASCADE_Hx__
+
+
+#define CASCADE_REG_SCAN        0x1000
+#define CASCADE_REG_POWER       0x1001
+#define CASCADE_REG_SENSOR      0x1002
+
+enum {
+    TYPE_PWR_CHN=0,
+    TYPE_PWR_TOTAL,
+    
+    TYPE_CFG_IMPORT,
+    TYPE_CFG_EXPORT,
+    
+    TYPE_SYS_REBOOT,
+    TYPE_SYS_UPGRADE,
+    TYPE_SYS_FACTORY,
+    
+    TYPE_SYS_INFO,
+};
+
+#if 0
+typedef struct {
+    
+
+}factory_data_t;
+typedef struct {
+    
+
+}config_data_t;
+typedef struct {
+    
+
+}device_data_t;
+#endif
+
+
+int cascade_init(void);
+int cascade_reinit(void);
+int cascade_get(int addr, int type, void* data);
+int cascade_set(int addr, int type, void* data);
+
+#endif
+
+

+ 3 - 1
04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/src/common.c

@@ -367,4 +367,6 @@ int is_process_running(const char *process_name)
   
     closedir(dir);  
     return 0; // 进程未启动  
-}
+}
+
+

+ 19 - 9
04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/src/common.h

@@ -23,12 +23,18 @@
 #include "language_hashmap.h"
 
 
+#define MAX_CHN_COUNT 16
+#define MAX_RELAY_CHN 100
+
 //是否在OS环境下运行
 #define OS_HANDWARE 1
 
-#define MAX_CHN_COUNT   16
-#define DATABASE_NAME   "pdu_dat.db" 
-#define SNMP_MIB_NAME   "pduMIB"
+#define WEB_ROOT       "../web"
+#define PARAS_FILE     "pduParas"
+
+#define DATABASE_NAME  "pdu_dat.db" 
+#define SNMP_MIB_NAME  "pduMIB"
+
 
 #define INTERL_MODBUS_PORT "/dev/ttyAS5"
 #define INTERL_MODBUS_BAUD 115200
@@ -38,6 +44,10 @@
 #define INTERL_SENSOR_MODBUS_PORT "/dev/ttyAS2"
 #define INTERL_SENSOR_MODBUS_BAUD 9600
 
+//表头级联接口
+#define CASCADE_MODBUS_PORT     "/dev/ttyAS5"
+#define CASCADE_MODBUS_BAUD     9600
+
 #define AC_SINGLE_S_CUR_CHN_NUM 8
 #define AC_SINGLE_B_CUR_CHN_NUM 4
 
@@ -141,12 +151,12 @@ typedef struct
 
 typedef struct
 {
-    int           mode;    //dhcp模式
-    char          ip_address[16] ; //ip地址
-    char          mask[16]; //子网掩码
-    char          gateway[16]; //网关
-    char          dns1[16];    //dns1
-    char          dns2[16];    //dns2
+    int           mode;    						//1: static  0: dhcp
+    char          ip_address[64] ; 				//ip地址
+    char          mask[64]; 					//子网掩码
+    char          gateway[64]; 					//网关
+    char          dns1[64];    					//dns1
+    char          dns2[64];    					//dns2
 }NetworkInfo_t;
 
 

+ 51 - 0
04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/src/dflt.c

@@ -0,0 +1,51 @@
+#include "paras.h"
+#include "cfg.h"
+
+
+AllParasInfo DFLT_PARAS={
+
+    .dev = {
+        .product_id         = PROD_ID,
+        .product_number     = "X000001",
+        .product_name       = "SmartPDU",
+        .product_status     = "",
+        .product_type       = PROD_TYPE,
+        .product_pwr_type   = PROD_POWER_TYPE,
+        .product_version    = VERSION,
+        .product_language   = LANGUAGE,                  //多国语言
+        .product_count      = CASCADE_CNT,               //级联设备数
+        .product_samp_time  = SMPLE_TIME,                //采集周期 单位ms
+        .product_save_time  = SAVE_TIME,                 //保存周期 单位ms
+        
+        ._modbus_info = {                                //继电器控制端口
+            .product_modbus_type = 0,                    //modbus模式,0: master     1: slave
+            .product_modbus_baud = 115200,
+            .product_modbus_addr = 1,
+            .product_relay_ctrl_port = "/dev/ttyAS2",    //继电器modbus控制端口路径
+        },
+        
+        ._network_info = {
+            .mode = 1,                                   //0:dhcp   1:static
+            .ip_address = "192.168.1.132",
+            .mask = "255.255.255.0",
+            .gateway = "192.168.1.1",
+            .dns1 = "",
+            .dns2 = "",
+        },
+        
+        ._gmodbus_info = {
+            .product_modbus_type = 0,                   //modbus模式,0: master     1: slave
+            .product_modbus_baud = 115200,
+            .product_modbus_addr = 1,
+            .product_relay_ctrl_port = "/dev/ttyXXX",   //表头级联串口对应路径
+        },
+    },
+
+    .relay = {
+        0
+    },
+    
+};
+
+
+

+ 23 - 0
04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/src/modbus_handle.c

@@ -142,6 +142,29 @@ int g_modbus_write_x_reg(void* manger,int saddr,unsigned short reg,unsigned int
     return ret ;
 }
 
+
+
+//slave receive
+int g_modbus_receive(void* manger, uint8_t *req)
+{
+    int ret = 0 ;
+    Modbus_Manger *modbus_manger = (Modbus_Manger *)manger;
+    pthread_mutex_lock(&modbus_manger->mutex);
+    ret = modbus_receive(modbus_manger->mb, req);
+    pthread_mutex_unlock(&modbus_manger->mutex);
+    return ret ;
+}
+int g_modbus_reply(void* manger, uint8_t *req, int reqlen, modbus_mapping_t *map)
+{
+    int ret = 0 ;
+    Modbus_Manger *modbus_manger = (Modbus_Manger *)manger;
+    pthread_mutex_lock(&modbus_manger->mutex);
+    ret = modbus_reply(modbus_manger->mb, req, reqlen, map);
+    pthread_mutex_unlock(&modbus_manger->mutex);
+    return ret ;
+}
+
+
 /// @brief 读取单个寄存器值
 /// @param manger 
 /// @param reg 

+ 2 - 0
04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/src/modbus_handle.h

@@ -31,4 +31,6 @@ int g_modbus_read_x_reg(void* manger,int saddr,unsigned short reg,unsigned int s
 int g_modbus_read_x_reg_delay(void* manger,int saddr,unsigned short reg,unsigned int size,unsigned short *data);
 void g_modbus_deinit(void* manger);
 
+int g_modbus_receive(void* manger, uint8_t *req);
+int g_modbus_reply(void* manger, uint8_t *req, int reqlen, modbus_mapping_t *map);
 #endif

+ 187 - 0
04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/src/paras.c

@@ -0,0 +1,187 @@
+#include "paras.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include "sys.h"
+
+
+//#define LOG log_print
+#define LOG printf
+
+
+AllParasInfo allParas;
+////////////////////////////////////////////////////////////
+static int file_length(char* path)
+{
+    int r;
+    struct stat st;
+
+    r = stat(path, &st);
+    if (r) {
+        return -1;
+    }
+
+    return st.st_size;
+}
+
+static int file_save(char *path, void *buf, int len)
+{
+    int r;
+    FILE *fp;
+    
+    fp = fopen(path, "wb");
+    if(!fp) {
+        LOG("file_save, fopen %s failed, %d, %d\n", path);
+        return -1;
+    }
+    r = fwrite(buf, 1, len, fp);
+    if(r!=len) {
+        LOG("file_save %s failed, %d, %d\n", path, r, len);
+        r = -1;
+    }
+    else {
+        r = 0;
+    }
+    fclose(fp);
+
+    return r;
+}
+static int file_load(char* path, void* buf, int len)
+{
+    int r;
+    FILE* fp;
+
+    fp = fopen(path, "rb");
+    if (!fp) {
+        LOG("file_load, fopen %s failed, %d, %d\n", path);
+        return -1;
+    }
+    r = fread(buf, 1, len, fp);
+    if (r != len) {
+        LOG("file_load %s failed, %d, %d\n", path, r, len);
+        r = -1;
+    }
+    else {
+        r = 0;
+    }
+    fclose(fp);
+
+    return r;
+}
+static int file_remove(char *path)
+{
+    return remove(path);
+}
+
+static int do_check(AllParasInfo *paras)
+{
+    int i,j;
+    
+
+    return 0;
+}
+///////////////////////////////////////////////////////
+int paras_load(void)
+{
+    int i,r=-1;
+    int flen,rlen;
+    char path[PATH_MAX];
+    NetworkInfo_t *p=&allParas.dev._network_info;
+
+    allParas = DFLT_PARAS;
+    sys_get_path(path, PARAS_FILE);
+    
+    flen = file_length(path);
+    if(flen==sizeof(allParas)) {
+        rlen = file_load(path, &allParas, flen);
+        if(rlen==flen) {
+            r = do_check(&allParas);
+            if(r) {
+                allParas = DFLT_PARAS;
+            }
+        }
+    }
+    
+    if(r) {
+        paras_save();
+        sys_set_net(p, IP_V4);
+    }
+    else {
+        sys_get_net(p, IP_V4);
+    }
+    
+    return r;
+}
+
+
+int paras_save(void)
+{
+    int r,flen;
+    char path[PATH_MAX];
+    AllParasInfo *p;
+    
+    r = do_check(&allParas);
+    if(r) {
+        return -1;
+    }
+    sys_get_path(path, PARAS_FILE);
+    flen = file_length(path);
+
+    if(flen==sizeof(allParas)) {
+        p = malloc(sizeof(allParas));
+        if(p) {
+            file_load(path, p, flen);
+            if(memcmp(p, &allParas, sizeof(allParas))==0) {
+                free(p); return -1;
+            }
+            free(p);
+        }
+    }
+    
+    return file_save(path, &allParas, sizeof(allParas));
+}
+
+
+int paras_reset(void)
+{
+    allParas = DFLT_PARAS;
+    return paras_save();
+}
+
+
+AllParasInfo* paras_get(void)
+{
+    return &allParas;
+}
+
+
+int paras_power_set(int saddr, GlobalPowerManger *pm)
+{
+    int i,j;
+    RelayPowerInfo *rp=&allParas.relay.ch[saddr];
+
+    if(pm) rp->pwr[pm->product_ch_id] = *pm;
+    rp->inited = 1;
+
+    return 0;
+}
+
+int paras_power_get(int addr, int saddr, GlobalPowerManger *pm)
+{
+    int i,j;
+    RelayPowerInfo *rp=&allParas.relay.ch[saddr];
+
+    if(rp->inited==0) {
+        return -1;
+    }
+    if(pm) rp->pwr[saddr] = *pm;
+
+    return 0;
+}
+
+
+
+
+
+
+
+

+ 40 - 0
04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/src/paras.h

@@ -0,0 +1,40 @@
+#ifndef __PARAS_Hx__
+#define __PARAS_Hx__
+
+#include "common.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+    char              inited;
+    GlobalPowerManger pwr[MAX_RELAY_CHN];
+}RelayPowerInfo;
+typedef struct {
+    RelayPowerInfo    ch[MAX_RELAY_CHN];
+}RelayParas;
+typedef struct {
+    GlobalDeviceInfo  dev;
+    RelayParas        relay;
+}AllParasInfo;
+
+extern AllParasInfo allParas;
+extern AllParasInfo DFLT_PARAS;
+
+
+int paras_load(void);
+int paras_save(void);
+int paras_reset(void);
+AllParasInfo* paras_get(void);
+int paras_power_set(int saddr, GlobalPowerManger *pm);
+int paras_power_get(int addr, int saddr, GlobalPowerManger *pm);
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+

+ 880 - 0
04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/src/sys.c

@@ -0,0 +1,880 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+#include <limits.h>
+#include "elog.h"
+#include "sys.h"
+#include "upgrade.h"
+#include "paras.h"
+
+
+#if 0
+//#define LOGE  log_e
+//#define LOGD  log_d
+#else
+#define LOGD  printf
+#define LOGE  printf
+#endif
+
+
+//#define USE_BASH
+#define USE_FILE
+//#define USE_API
+
+#define DFLT_NIC        "eth0"
+#define FILE_INTERFACE  "/etc/network/interfaces"
+
+
+
+typedef struct {
+	char *pbuf;
+    int  dlen;
+    int  blen;
+}node_t;
+
+static int node_free(node_t *nd)
+{
+    if(!nd) {
+        return -1;
+    }
+
+    free(nd->pbuf);
+    nd->pbuf = NULL;
+    nd->dlen = 0;
+    nd->blen = 0;
+}
+
+static int exe_cmd(char *cmd, node_t *nd)
+{
+    int r=0;
+	FILE *fp=NULL;
+    char *pbuf=NULL;
+    int onelen=1000;
+    int dlen=0,blen=onelen;
+
+    pbuf = malloc(onelen);
+    if(!pbuf) {
+        return -1;
+    }
+    
+    fp = popen(cmd, "r");
+    if (fp == NULL) {
+        return -1;
+    }
+
+	while(1) {
+        r = fread(pbuf+dlen, sizeof(char), onelen, fp);
+        if(r<=0) {
+            LOGE("exe_cmd fread failed\n");
+            break;
+        }
+        dlen += r;
+        if(dlen+onelen>blen) {
+            char* p = realloc(pbuf, dlen+onelen);
+            if(!p) {
+                LOGE("exe_cmd relloac %d failed\n", dlen+onelen);
+                free(pbuf); pclose(fp);
+                return -1;
+            }
+            pbuf = p;
+            blen = dlen+onelen;
+        }
+	}
+    pclose(fp);
+    
+    nd->pbuf = pbuf;
+    nd->dlen = dlen;
+    nd->blen = blen;
+    
+	return 0;
+}
+////////////////////////////////////////////////////////////////////
+int sys_reboot(void)
+{
+    int r=0;
+
+    r = system("reboot -f");
+    if(r) {
+        LOGE("sys_reboot failed!\n");
+        return -1;
+    }
+
+    return r;
+}
+
+
+#include "upgrade.h"
+int sys_set_factory(void)
+{
+    paras_reset();
+    return system("reboot -f");
+}
+
+
+int sys_get_path(char *path, char *name)
+{
+    char tmp[PATH_MAX];
+
+    pid_t pid = getpid();
+    snprintf(tmp, sizeof(tmp), "/proc/%d/exe", pid); 
+    readlink(tmp, path, sizeof(tmp));
+    char *p = strrchr(path, '/');
+    if(p && strlen(path)>1) {
+        *p = 0;
+        strcat(path, "/");
+        strcat(path, name);
+    }
+    
+    return 0;
+}
+
+////////////////////////////////////////////////
+#include <net/if.h>
+#include <sys/socket.h>
+#include <net/route.h>
+#include <sys/ioctl.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <unistd.h>
+#include <net/if.h>
+#include <ifaddrs.h>
+#include <netinet/in.h>
+#include <linux/if_link.h>
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+
+void print_net(char*s, NetworkInfo_t *p)
+{
+    LOGD("__%s__net.mode:    %d\n", s, p->mode);
+    LOGD("__%s__net.addr:    %s\n", s, p->ip_address);
+    LOGD("__%s__net.mask:    %s\n", s, p->mask);
+    LOGD("__%s__net.gateway: %s\n", s, p->gateway);
+    LOGD("__%s__net.dns1:    %s\n", s, p->dns1);
+    LOGD("__%s__net.dns2:    %s\n", s, p->dns2);
+}
+void print_modbus(char*s, ModbusInfo_t *p)
+{
+    LOGD("__%s__mbus.mode:    %d\n", s, p->product_modbus_type);
+    LOGD("__%s__mbus.addr:    %d\n", s, p->product_modbus_baud);
+    LOGD("__%s__mbus.mask:    %d\n", s, p->product_modbus_addr);
+    LOGD("__%s__mbus.mask:    %s\n", s, p->product_relay_ctrl_port);
+}
+
+static int set_ipaddr(int family, const char* iface, const char* addr, const char* netmask)
+{
+    struct ifreq ifr;
+    struct sockaddr_in  *sin;
+    struct sockaddr_in6 *sin6;
+     
+    int fd = socket(family, SOCK_DGRAM, 0);
+    if (fd < 0) {
+        LOGD("socket SOCK_DGRAM failed\n");
+        return -1;
+    }
+ 
+    strcpy(ifr.ifr_name, iface);
+    sin  = (struct sockaddr_in*)&ifr.ifr_addr;
+    sin6 = (struct sockaddr_in6*)&ifr.ifr_addr;
+
+    if(family==AF_INET) {
+        sin->sin_family = family;
+        sin->sin_port = 0;
+        inet_pton(family, addr, &sin->sin_addr);
+     
+        if (ioctl(fd, SIOCSIFADDR, &ifr) < 0) {
+            LOGD("ioctl SIOCSIFADDR \n");
+            close(fd);
+            return -1;
+        }
+     
+        sin->sin_family = family;
+        inet_pton(family, netmask, &sin->sin_addr);
+        if (ioctl(fd, SIOCSIFNETMASK, &ifr) < 0) {
+            LOGD("ioctl SIOCSIFNETMASK \n");
+            close(fd);
+            return -1;
+        }
+    }
+    else {
+        sin6->sin6_family = family;
+        sin6->sin6_port = 0;
+        inet_pton(family, addr, &sin6->sin6_addr);
+     
+        if (ioctl(fd, SIOCSIFADDR, &ifr) < 0) {
+            LOGD("ioctl SIOCSIFADDR \n");
+            close(fd);
+            return -1;
+        }
+     
+        sin6->sin6_family = family;
+        inet_pton(family, netmask, &sin6->sin6_addr);
+        if (ioctl(fd, SIOCSIFNETMASK, &ifr) < 0) {
+            LOGD("ioctl SIOCSIFNETMASK \n");
+            close(fd);
+            return -1;
+        }
+    }
+    close(fd);
+    
+    return 0;
+}
+static int get_ipaddr(int family, char* iface, char* addr, char* netmask)
+{
+    struct ifaddrs *ifap, *ifa;
+
+    if (getifaddrs(&ifap) == -1) {
+        LOGE("getifaddrs() error\n");
+        return -1;
+    }
+
+    for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
+        if (ifa->ifa_addr != NULL && ifa->ifa_addr->sa_family == family) {
+            if(family==IP_V4) {
+                struct sockaddr_in *sa,*msk;
+                sa = (struct sockaddr_in *)  ifa->ifa_addr;
+                msk = (struct sockaddr_in *) ifa->ifa_netmask;
+
+                inet_ntop(family, &sa->sin_addr,  addr,    INET6_ADDRSTRLEN);
+                inet_ntop(family, &msk->sin_addr, netmask, INET6_ADDRSTRLEN);
+            }
+            else {
+                struct sockaddr_in6 *sa,*msk;
+                sa = (struct sockaddr_in6 *)  ifa->ifa_addr;
+                msk = (struct sockaddr_in6 *) ifa->ifa_netmask;
+                
+                inet_ntop(family, &sa->sin6_addr,  addr,    INET6_ADDRSTRLEN);
+                inet_ntop(family, &msk->sin6_addr, netmask, INET6_ADDRSTRLEN);
+            }
+        }
+    }
+    freeifaddrs(ifap);
+    
+    return 0;
+}
+
+static int set_gateway(int family, const char* gateway)
+{
+    struct rtentry rt;
+    
+    int fd;
+ 
+    fd = socket(family, SOCK_DGRAM, 0);
+    if (fd < 0) {
+        LOGE("socket SOCK_DGRAM failed\n");
+        return -1;
+    }
+ 
+    memset(&rt, 0, sizeof(rt));
+
+    if(family==AF_INET) {
+        struct sockaddr_in* sin;
+        sin = (struct sockaddr_in*)&rt.rt_gateway;
+        sin->sin_family = family;
+        sin->sin_port = 0;
+        inet_pton(family, gateway, &sin->sin_addr);
+     
+        sin = (struct sockaddr_in*)&rt.rt_dst;
+        sin->sin_family = family;
+        sin->sin_addr.s_addr = 0;
+    }
+    else {
+        struct sockaddr_in6* sin;
+        sin = (struct sockaddr_in6*)&rt.rt_gateway;
+        sin->sin6_family = family;
+        sin->sin6_port = 0;
+        inet_pton(family, gateway, &sin->sin6_addr);
+     
+        sin = (struct sockaddr_in6*)&rt.rt_dst;
+        sin->sin6_family = family;
+        //sin->sin6_addr.s_addr[0] = 0;
+    }
+ 
+    rt.rt_flags = RTF_GATEWAY;
+    if (ioctl(fd, SIOCADDRT, &rt) < 0) {
+        LOGE("ioctl SIOCADDRT failed\n");
+        close(fd);
+        return -1;
+    }
+    close(fd);
+    
+    return 0;
+
+}
+static int get_gateway(int family, const char* gateway)
+{
+#if 0
+    int sockfd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
+    if (sockfd == -1) {
+        log_e("set_gateway, socket AF_NETLINK error\n");
+        return -1;
+    }
+
+    struct sockaddr_nl sa;
+    memset(&sa, 0, sizeof(sa));
+    sa.nl_family = AF_NETLINK;
+    if (bind(sockfd, (struct sockaddr *) &sa, sizeof(sa)) == -1) {
+        log_e("set_gateway, bind error\n");
+        return -1;
+    }
+    
+    struct nlreq req;
+    memset(&req, 0, sizeof(req));
+    req.hdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
+    req.hdr.nlmsg_type = RTM_GETROUTE;
+    req.hdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
+    req.msg.rtm_family = family;
+    req.msg.rtm_table = RT_TABLE_MAIN;
+    req.msg.rtm_protocol = RTPROT_UNSPEC;
+    req.msg.rtm_scope = RT_SCOPE_UNIVERSE;
+    req.msg.rtm_type = RTN_UNICAST;
+
+    struct iovec iov;
+    memset(&iov, 0, sizeof(iov));
+    iov.iov_base = &req;
+    iov.iov_len = req.hdr.nlmsg_len;
+
+    struct msghdr msg;
+    memset(&msg, 0, sizeof(msg));
+    msg.msg_name = &sa;
+    msg.msg_namelen = sizeof(sa);
+    msg.msg_iov = &iov;
+    msg.msg_iovlen = 1;
+    
+    char buf[BUFSIZE];
+    memset(buf, 0, sizeof(buf));
+    struct nlmsghdr *hdr;
+    int len;
+    if (sendmsg(sockfd, &msg, 0) == -1) {
+        log_e("set_gateway, sendmsg error\n");
+        return -1;
+    }
+    while ((len = recv(sockfd, buf, sizeof(buf), 0)) > 0) {
+        for (hdr = (struct nlmsghdr *) buf; NLMSG_OK(hdr, len); hdr = NLMSG_NEXT(hdr, len)) {
+            if (hdr->nlmsg_type == NLMSG_DONE) {
+                goto finish;
+            }
+            if (hdr->nlmsg_type == NLMSG_ERROR) {
+                log_e("set_gateway, NLMSG_ERROR\n");
+                return -1;
+            }
+            struct rtmsg *rt = (struct rtmsg *) NLMSG_DATA(hdr);
+            if (rt->rtm_family != family || rt->rtm_table != RT_TABLE_MAIN || rt->rtm_type != RTN_UNICAST) {
+                continue;
+            }
+            struct rtattr *attr;
+            int attrlen;
+            for (attr = (struct rtattr *) RTM_RTA(rt), attrlen = RTM_PAYLOAD(hdr); RTA_OK(attr, attrlen); attr = RTA_NEXT(attr, attrlen)) {
+                if (attr->rta_type == RTA_GATEWAY) {
+                    char gw_addr[INET_ADDRSTRLEN];
+                    struct in_addr addr;
+                    memcpy(&addr, RTA_DATA(attr), sizeof(addr));
+                    if (inet_ntop(family, &addr, gateway, INET6_ADDRSTRLEN) == NULL) {
+                        log_e("set_gateway, inet_ntop error\n");
+                        continue;
+                    }
+                    printf("Gateway address: %s\n", gw_addr);
+                    log_i("set_gateway, Gateway address: %s\n");
+                    goto finish;
+                }
+            }
+        }
+    }
+finish:
+    close(sockfd);
+#endif
+
+    return 0;
+
+}
+static int set_dhcp(int on)
+{
+    return 0;
+}
+
+static int set_dns(int family, const char* iface, char* dns1, char *dns2)
+{
+    int fd;
+    struct ifreq ifr;
+    
+#if 0 
+    fd = socket(family, SOCK_DGRAM, 0);
+    if (fd < 0) {
+        log_e("socket SOCK_DGRAM failed\n");
+        return -1;
+    }
+ 
+    memset(&ifr, 0, sizeof(ifr));
+    strncpy(ifr.ifr_name, iface, sizeof(ifr.ifr_name));
+ 
+    struct sockaddr_in* addr = (struct sockaddr_in*)&ifr.ifr_addr;
+    addr->sin_family = family;
+    inet_pton(family, dns1, &addr->sin_addr);
+
+
+    if (ioctl(fd, SIOCSIFDNS, &ifr) < 0) {
+        log_e("socket SIOCSIFDNS failed\n");
+        close(fd);
+        return -1;
+    }
+#endif
+    close(fd);
+    
+    return 0;
+}
+static int get_dns(int family, const char* iface, char* dns1, char *dns2)
+{
+    return 0;
+}
+
+
+
+static int ip_check(char* addr)
+{
+    int flag = IP_ERR;
+    int len = 0;
+    int num = 0;
+    int Count = 0;
+    int first = 0;
+    int i = 0,j=0;
+ 
+    len = strlen(addr);
+    if (strchr(addr,'.') != NULL) {// 含 .的情况,判断是否是IPv4
+        for(i = 0;i <= len-1; i++) {
+            if(addr[i] >= '0' && addr[i] <= '9') {
+                num = num * 10 + addr[i] - '0';
+            }
+            else if(addr[i] == '.') {
+                if((i == 0)||(i == len-1)) {
+                    break;
+                }
+ 
+                if(addr[i-1] < '0' || addr[i-1] > '9') {
+                    break;
+                }
+ 
+                if(addr[i] == '.') {
+                    Count++;
+                    if(Count > 3) {
+                        break;
+                    }
+                }
+ 
+                if(num > 255) {
+                    break;
+                }
+ 
+                if(num != 0 && addr[first] == '0') {
+                    break;
+                }
+                first = i+1;
+                num = 0;
+            }
+            else {
+                break;
+            }
+        }
+ 
+        if(Count == 3) {
+            flag = IP_V4;
+        }
+    }
+    else if (strchr(addr,':') != NULL) {// 含 :的情况,判断是否是IPv6
+        for(i = 0;i <= len-1; i++) {
+            if((addr[i] >= '0' && addr[i] <= '9')||(tolower(addr[i]) >= 'a' && tolower(addr[i]) <= 'f')) {
+                j++;
+                if (j > 4) {
+                    break;
+                }
+            }
+            else if(addr[i] == ':') {
+                if((i == 0)||(i == len-1)) {
+                    break;
+                }
+                if (j == 0) {
+                    break;
+                }
+                Count++;
+                if(Count > 7) {
+                    break;
+                }
+                j = 0;
+            }
+            else {
+                break;
+            }
+        }
+ 
+        if((Count == 7)&&(j <= 4))
+        {
+            flag = IP_V6;
+        }
+    }
+    
+    return flag;
+}
+
+
+///////////////////////////////////////////////
+static int file_length(char* path)
+{
+    int r;
+    struct stat st;
+
+    r = stat(path, &st);
+    if (r) {
+        return -1;
+    }
+
+    return st.st_size;
+}
+
+static int file_save(char *path, void *buf, int len)
+{
+    int r;
+    FILE *fp;
+    
+    fp = fopen(path, "w");
+    if(!fp) {
+        LOGE("file_save, fopen %s failed, %d, %d\n", path);
+        return -1;
+    }
+    r = fwrite(buf, 1, len, fp);
+    if(r!=len) {
+        LOGE("file_save %s failed, %d, %d\n", path, r, len);
+        r = -1;
+    }
+    else {
+        r = 0;
+    }
+    fclose(fp);
+
+    return r;
+}
+
+static int file_load(char* path, void* buf, int len)
+{
+    int r;
+    FILE* fp;
+
+    fp = fopen(path, "r");
+    if (!fp) {
+        LOGE("file_load, fopen %s failed, %d, %d\n", path);
+        return -1;
+    }
+    r = fread(buf, 1, len, fp);
+    if (r != len) {
+        LOGE("file_load %s failed, %d, %d\n", path, r, len);
+        r = -1;
+    }
+    else {
+        r = 0;
+    }
+    fclose(fp);
+
+    return r;
+}
+
+typedef struct {
+    char lo[500];
+    char e0[500];
+    char e1[500];
+}net_t;
+static net_t sNet;
+typedef uint32_t u32;
+static int get_nic(char *nbuf, char *nic, char *fbuf, int flen)
+{
+    char *p,*p1,*p2;
+    char tmp[20];
+    char *fend=fbuf+flen-1;
+
+    p = fbuf;
+    sprintf(tmp, "auto %s", nic);
+    while(p<=fend) {
+        p1 = strstr(p, tmp);
+        if(p1) {
+            p2 = strstr(p1+1, "auto");
+            if(!p2) {
+                p2 = fend;
+            }
+            memcpy(nbuf, p1, (u32)p2-(u32)p1); nbuf[(u32)p2-(u32)p1] = 0;
+            return 0;
+        }
+        p = p1+1;
+    }
+
+    return -1;
+}
+static int get_ip(char *nbuf, char *token, char *ipaddr)
+{
+    int cnt=0;
+    char *p,*p1,*p2;
+
+    p = strstr(nbuf, token);
+    if(p) {
+        while(!isdigit(*p)) p++;
+        p1 = p;
+        while(!isspace(*p)) p++;
+        p2 = p;
+
+        for(p=p1; p<p2; p++) {
+            if(isgraph(*p)) {
+                ipaddr[cnt++] = *p;
+            }
+        }
+        ipaddr[cnt] = 0;
+    }
+
+}
+
+static int get_net(NetworkInfo_t *para)
+{
+    char *fpath=FILE_INTERFACE;
+    int xlen=10*1000;
+    net_t *pNet=&sNet;
+
+    int flen=file_length(fpath);
+    char *fbuf=malloc(xlen);
+    if(!fbuf) {
+        LOGE("___ malloc %d failed\n", flen);
+        return -1;
+    }
+    file_load(fpath, fbuf, flen);
+    fbuf[flen] = 0;
+    
+    get_nic(pNet->lo, "lo",   fbuf, flen);
+    get_nic(pNet->e0, "eth0", fbuf, flen);
+    get_nic(pNet->e1, "eth1", fbuf, flen);
+
+    if(strstr(pNet->e0, "dhcp")) {
+        para->mode = 0;
+    }
+    else if(strstr(pNet->e0, "static")) {
+        para->mode = 1;
+    }
+    
+    get_ip(pNet->e0, "address", para->ip_address);
+    get_ip(pNet->e0, "netmask", para->mask);
+    get_ip(pNet->e0, "gateway", para->gateway);
+    
+    free(fbuf);
+
+    return 0;
+}
+
+static int set_net(NetworkInfo_t *para)
+{
+    int r;
+    char *p1,*p2,*p3,*p4;
+    char *fpath=FILE_INTERFACE;
+    int xlen=10*1000;
+    NetworkInfo_t para2;
+    net_t *pNet=&sNet;
+
+    memset(&para2, 0, sizeof(para2));
+    get_net(&para2);
+    
+    if(para->mode<2 && para->mode!=para2.mode) {
+        para2.mode = para->mode;
+    }
+    
+    if(ip_check(para->ip_address) && strcmp(para->ip_address, para2.ip_address)) {
+        strcpy(para2.ip_address, para->ip_address);
+    }
+    
+    if(ip_check(para->mask) && strcmp(para->mask, para2.mask)) {
+        strcpy(para2.mask, para->mask);
+    }
+
+    if(ip_check(para->gateway) && strcmp(para->gateway, para2.gateway)) {
+        strcpy(para2.gateway, para->gateway);
+    }
+    
+    int flen=file_length(fpath);
+    char *fbuf=malloc(xlen);
+    if(!fbuf) {
+        LOGE("___ malloc %d failed\n", flen);
+        return -1;
+    }
+    file_load(fpath, fbuf, flen);
+    fbuf[flen] = 0;
+
+    get_nic(pNet->lo, "lo",   fbuf, flen);
+    get_nic(pNet->e1, "eth1", fbuf, flen);
+
+    snprintf(pNet->e0, sizeof(pNet->e0), "auto eth0\niface eth0 inet %s\n  address %s\n  netmask %s\n  gateway %s\n\n", 
+                              para2.mode?"static":"dhcp", para2.ip_address, para2.mask, para2.gateway);
+    strcpy(fbuf, pNet->lo);
+    strcat(fbuf, pNet->e0);
+    strcat(fbuf, pNet->e1);
+
+    r = file_save(fpath, fbuf, strlen(fbuf));
+    free(fbuf);
+
+    if(r==0) {
+        paras_get()->dev._network_info = para2;
+    }
+
+    return r;
+
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+int sys_set_net(NetworkInfo_t *para, int ipVersion)
+{
+    int r,ipv;
+
+#ifdef USE_BASH
+    char cmd[200];
+
+    snprintf(cmd, sizeof(cmd), "ip addr flush dev %s", DFLT_NIC);
+    r = system(cmd);
+    if(r) {
+        LOGE("set ipaddr failed\n");
+        return -1;
+    }
+
+    snprintf(cmd, sizeof(cmd), "ip addr add %s/%s dev %s", para->ip_address, para->mask, DFLT_NIC);
+    r = system(cmd);
+    if(r) {
+        LOGE("set netmask %s failed\n", para->mask);
+        return -1;
+    }
+
+    snprintf(cmd, sizeof(cmd), "ip route add default via %s dev %s", para->gateway, DFLT_NIC);
+    r = system(cmd);
+    if(r) {
+        LOGE("set gateway %s failed\n", para->gateway);
+        return -1;
+    }
+
+    snprintf(cmd, sizeof(cmd), "ip link set dev %s up", DFLT_NIC);
+    r = system(cmd);
+    if(r) {
+        LOGE("restart %s failed\n", DFLT_NIC);
+        return -1;
+    }
+
+#elif defined USE_FILE
+    r = set_net(para);
+#elif defined USE_API
+    if(para->mode==IP_DHCP) {
+        r = set_dhcp(1);
+    }
+    else {
+        set_dhcp(0);
+
+        int family=(ipv==IP_V4)?AF_INET:AF_INET6;
+        r = set_ipaddr(family, "eth0", para->ip_address, para->mask);
+        if(r) {
+            LOGE("set_ipaddr failed\n");
+            return r;
+        }
+        
+        r = set_gateway(family, para->gateway);
+        if(r) {
+            LOGE("set_gateway failed\n");
+            return r;
+        }
+
+        r = set_dns(family, "eth0", para->dns1, para->dns2);
+        if(r) {
+            LOGE("set_dns failed\n");
+            return r;
+        }
+    }
+#endif
+
+    system("ifdown eth0 && ifup eth0");
+    //system("重启dns服务器"); //目前dns服务未启动
+    
+    return r;
+}
+
+int sys_get_net(NetworkInfo_t *para, int ipVersion)
+{
+    int r;
+    int family=AF_INET;
+#ifdef USE_BASH
+    
+
+#elif defined USE_FILE
+    r = get_net(para);
+#elif defined USE_API  
+    r = get_ipaddr(family, DFLT_NIC, para->ip_address, para->mask);
+    if(r) {
+        LOGE("set_ipaddr failed\n");
+        return r;
+    }
+    
+    r = get_gateway(family, para->gateway);
+    if(r) {
+        LOGE("set_gateway failed\n");
+        return r;
+    }
+
+    r = get_dns(family, DFLT_NIC, para->dns1, para->dns2);
+    if(r) {
+        LOGE("set_dns failed\n");
+        return r;
+    }
+#endif
+
+    return 0;
+}
+
+
+
+static thread_handle_t myThdHandles[THREAD_ID_MAX]={0};
+int sys_start_thread(int id, thread_fn fn, void *arg)
+{
+    if(id>=THREAD_ID_MAX) {
+        return -1;
+    }
+    thread_handle_t *h=&myThdHandles[id];
+
+    h->arg  = arg;
+    h->quit = 0;
+    return pthread_create(&h->tid, NULL, fn, h);
+}
+
+int sys_stop_thread(int id)
+{
+    if(id>=THREAD_ID_MAX) {
+        return -1;
+    }
+    thread_handle_t *h=&myThdHandles[id];
+
+    h->quit = 1;
+
+#ifdef USE_WEBAPP
+    if(id==THREAD_ID_WEB) {
+    extern void httpStopEndpoints();
+        httpStopEndpoints();
+    }
+#endif
+    pthread_join(h->tid, NULL);
+    h->tid = 0;
+    h->arg = NULL;
+    h->fn  = NULL;
+    
+    return 0;
+}
+
+
+int sys_stop_all_thread(void)
+{
+    int i;
+
+    for(i=0; i<THREAD_ID_MAX; i++) {
+        sys_stop_thread(i);
+    }
+
+    return 0;
+}
+
+

+ 57 - 0
04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/src/sys.h

@@ -0,0 +1,57 @@
+#ifndef __SYS_H__
+#define __SYS_H__
+
+#include <stdint.h>
+#include "pthread.h"
+#include "common.h"
+
+
+enum {
+    IP_DHCP=0,
+    IP_STATIC,
+};
+enum {
+    IP_ERR=0,
+    IP_V4,
+    IP_V6,
+};
+
+enum {
+    THREAD_ID_IO=0,
+    THREAD_ID_WS,
+    THREAD_ID_WEB,
+    THREAD_ID_NTP,
+    THREAD_ID_SNMP,
+    THREAD_ID_POWER,
+    THREAD_ID_SENSOR,
+    THREAD_ID_UPDATE,
+    THREAD_ID_CASCADE,
+    THREAD_ID_SCAN,
+
+    THREAD_ID_MAX=30
+};
+
+typedef void *(*thread_fn)(void *arg);
+typedef struct {
+    pthread_t  tid;
+    int        quit;
+    void       *arg;
+    thread_fn  fn;
+}thread_handle_t;
+
+
+int sys_reboot(void);
+int sys_set_factory(void);
+int sys_get_path(char *path, char *name);
+int sys_get_net(NetworkInfo_t *para, int ipVersion);
+int sys_set_net(NetworkInfo_t *para, int ipVersion);
+
+
+int sys_start_thread(int id, thread_fn fn, void *arg);
+int sys_stop_thread(int id);
+int sys_stop_all(void);
+
+
+
+
+#endif

+ 13 - 6
04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/src/websocket_handle.c

@@ -3,6 +3,7 @@
 #include "pthread.h"
 #include "elog.h"
 #include "common.h"
+#include "sys.h"
 
 //获取本地IP以及端口进行初始化操作
 //static const char *s_listen_on = "ws://192.168.2.132:6785";
@@ -23,7 +24,7 @@ static void fn(struct mg_connection *c, int ev, void *ev_data)
   {
     struct mg_http_message *hm = (struct mg_http_message *) ev_data;
     //通过检查/websocket进行协议升级
-    if (mg_http_match_uri(hm, "/websocket/PDU-WebSocket")) 
+    if (mg_match(hm->uri, mg_str("/websocket/PDU-WebSocket"), NULL)) 
     {
       // Upgrade to websocket. From now on, a connection is a full-duplex
       // Websocket connection, which will receive MG_EV_WS_MSG events.
@@ -38,7 +39,7 @@ static void fn(struct mg_connection *c, int ev, void *ev_data)
         log_d("ws upgrade new connection ID:%d\n",c->id);
     }
     //测试用例
-    else if (mg_http_match_uri(hm, "/rest")) 
+    else if (mg_match(hm->uri, mg_str("/rest"), NULL)) 
     {
       // Serve REST response
       mg_http_reply(c, 200, "", "{\"result\": %d}\n", 123);
@@ -71,19 +72,24 @@ static void fn(struct mg_connection *c, int ev, void *ev_data)
   {
     // Got websocket frame. Received data is wm->data. Echo it back!
     struct mg_ws_message *wm = (struct mg_ws_message *) ev_data;
-    mg_ws_send(c, wm->data.ptr, wm->data.len, WEBSOCKET_OP_TEXT);
+    mg_ws_send(c, wm->data.buf, wm->data.len, WEBSOCKET_OP_TEXT);
   }
  
 }
 
-static void websocket_func(void* arg)
+static void* websocket_thread(void* arg)
 {
+    thread_handle_t *h=(thread_handle_t*)arg;
     struct mg_mgr mgr;  // Event manager
     mg_mgr_init(&mgr);  // Initialise event manager
     log_d("Starting WS listener on %s/websocket\n", s_listen_on);
     mg_http_listen(&mgr, s_listen_on, fn, NULL);  // Create HTTP listener
-    for (;;) mg_mgr_poll(&mgr, 1000);             // Infinite event loop
+    while(h->quit==0) {
+	    mg_mgr_poll(&mgr, 1000);                    // Infinite event loop
+    }
     mg_mgr_free(&mgr);
+
+    pthread_exit(NULL);
 }
 
 void ReadIPaddress()
@@ -103,8 +109,9 @@ int websocket_init(void)
         return -1;  
     }  
     ReadIPaddress();
+    
     pthread_t websockt_thread;
-    pthread_create(&websockt_thread,NULL,websocket_func,NULL);
+    sys_start_thread(THREAD_ID_WS, websocket_thread, NULL);
     return 0;
 }
 

+ 851 - 0
04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/src/xlist.c

@@ -0,0 +1,851 @@
+#include "xlist.h"
+#include "elog.h"
+#include "pthread.h"
+
+
+#define MALLOC  malloc
+#define FREE    free
+
+#define LOGD    log_d
+#define LOGE    log_e
+#define LOGW    log_w
+
+
+#define MIN(a,b)  (((a)>(b))?(b):(a))
+#define MAX(a,b)  (((a)>(b))?(a):(b))
+
+
+typedef struct {
+    list_node_t         *head;
+    list_node_t         *tail;
+    int                 size;
+}dlist_t;
+
+
+typedef struct {
+    dlist_t             used;
+  
+    handle_t            lock;
+    list_cfg_t          cfg;
+    
+    dlist_t             free;
+}list_t;
+static list_node_t *node_get(list_t *l, int index);
+
+static void* lock_init(void)
+{
+    int r;
+    
+    pthread_mutex_t *m=MALLOC(sizeof(pthread_mutex_t));
+    if(!m) {
+        return NULL;
+    }
+	r = pthread_mutex_init(m, NULL);
+	if(r) {
+        FREE(m);
+        return NULL;
+	}
+
+	return m;
+}
+static int lock_free(void *h)
+{
+    if(!h) {
+        return -1;
+    }
+	pthread_mutex_destroy((pthread_mutex_t*)h);
+	FREE(h);
+	return 0;
+}
+static int lock_on(void *h)
+{
+    if(!h) {
+        return -1;
+    }
+
+	return pthread_mutex_lock((pthread_mutex_t*)h);
+}
+static int lock_off(void *h)
+{
+    if(!h) {
+        return -1;
+    }
+
+    return pthread_mutex_unlock((pthread_mutex_t*)h);
+}
+
+
+
+
+static list_node_t* node_from_free(list_t *l, int dlen)
+{
+    int i;
+    list_node_t *tmp=NULL;
+    dlist_t *dl=&l->free;
+    
+    tmp = dl->head;         //从头部开始搜索合适节点
+    while(tmp) {
+        if(tmp->data.buf && tmp->data.blen>=dlen) {
+            
+            if(tmp==dl->head) {            //head
+                if(dl->size==1) {
+                    dl->head = NULL;
+                    dl->tail = NULL;
+                }
+                else {
+                    tmp->next->prev = NULL;
+                    dl->head = tmp->next;
+                }
+            }
+            else if(tmp==dl->tail) {
+                if(dl->size==1) {
+                    dl->head = NULL;
+                    dl->tail = NULL;
+                }
+                else {
+                    tmp->next->next = NULL;
+                    dl->tail = tmp->next;
+                }
+            }
+            else {
+                tmp->prev->next = tmp->next;
+                tmp->next->prev = tmp->prev;
+            }
+            
+            dl->size--;
+            
+            return tmp;
+        }
+        tmp = tmp->next;
+    }
+    
+    return NULL;
+}
+static int node_to_free(list_t *l, list_node_t *node)
+{
+    int r=-1;
+    list_node_t *tail=NULL;
+    dlist_t *dl=&l->free;
+    
+    tail = dl->tail;          //新节点加在free列表尾部
+    if(tail==NULL) {          //无节点
+        node->prev = NULL;
+        node->next = NULL;
+        
+        dl->head = node;
+        dl->tail = node;
+    }
+    else {
+        
+        node->prev = tail;
+        node->next = NULL;
+        
+        tail->next = node;
+        dl->tail = node;
+        if(dl->head==NULL) {
+            dl->head = node;
+        }
+    }
+    dl->size++;
+    
+    return 0;
+}
+static list_node_t *node_new(list_t *l, node_t *n)
+{
+    list_node_t *node=NULL;
+    
+    node = node_from_free(l, n->dlen);
+    if(!node) {
+        node = MALLOC(sizeof(list_node_t));
+        if (!node) return NULL;
+        
+        node->prev = NULL;
+        node->next = NULL;
+        
+        node->data.buf = MALLOC(n->dlen);
+        if(!node->data.buf) {
+            FREE(node);
+            return NULL;
+        }
+        node->data.blen = n->dlen;
+    }
+    
+    memcpy(node->data.buf, n->buf, n->dlen);
+    node->data.dlen = n->dlen;
+    node->data.tp = n->tp;
+
+    return node;
+}
+static int node_free(list_t *l, list_node_t *node)
+{
+    FREE(node->data.buf);
+    FREE(node);
+    
+    return 0;
+}
+static int node_remove(list_t *l, list_node_t *node, int ds)
+{
+    int index;
+    list_node_t *tmp=node;
+    dlist_t *dl=&l->used;
+    
+    if(tmp==dl->head) {
+        if(dl->size==1) {
+            dl->head = NULL;
+            dl->tail = NULL;
+        }
+        else {
+            dl->head = tmp->next;
+            dl->head->prev = NULL;
+        }
+    }
+    else if(tmp==dl->tail) {
+        if(dl->size==1) {
+            dl->head = NULL;
+            dl->tail = NULL;
+        }
+        else {
+            dl->tail = tmp->prev;
+            if(dl->tail) {
+                dl->tail->next = NULL;
+            }
+        }
+    }
+    else {
+        tmp->prev->next = tmp->next;
+        tmp->next->prev = tmp->prev;
+    }
+    dl->size--;
+    
+    if(ds==1) {
+        node_to_free(l, tmp);
+    }
+    else if(ds==2) {
+        node_free(l, tmp);
+    }
+    
+    return 0;
+}
+static int node_insert(list_t *l, list_node_t *node, int index)
+{
+    list_node_t *xd,*tmp=node;
+    dlist_t *dl=&l->used;
+    
+    if(dl->size==0) {
+        tmp->prev = NULL;
+        tmp->next = NULL;
+        
+        dl->head = tmp;
+        dl->tail = tmp;
+    }
+    else {
+        if(index==0) {                                  //head
+            tmp->prev = NULL;
+            tmp->next = dl->head;
+            
+            xd->prev = tmp;
+            dl->head = tmp;
+        }
+        else if((index==(dl->size)) || (index==-1)) {   //tail
+            tmp->prev = dl->tail;
+            tmp->next = NULL;
+            
+            dl->tail->next = tmp;
+            dl->tail = tmp;
+        }
+        else {
+            xd = node_get(l, index);
+            
+            tmp->prev = xd->prev;
+            tmp->next = xd;
+            xd->prev->next = tmp;
+            xd->prev = tmp;
+        }
+    }
+    dl->size++;
+    
+    return 0;
+}
+
+static int node_set(list_t *l, list_node_t *node, node_t *nd)
+{
+    FREE(node->data.buf);
+    node->data.buf = MALLOC(nd->dlen);
+    if(!node->data.buf) {
+        return -1;
+    }
+    
+    memcpy(node->data.buf, nd->buf, nd->dlen);
+    node->data.blen = nd->dlen;
+    node->data.dlen = nd->dlen;
+    
+    return 0;
+}
+
+static list_node_t *node_get(list_t *l, int index)
+{
+    int idx=0;
+    dlist_t *dl=&l->used;
+    list_node_t *tmp=dl->head;
+    
+    if(index==0) {
+        return dl->head;
+    }
+    else if(index==dl->size-1) {
+        return dl->tail;
+    }
+    else {
+        while(tmp) {
+            if(idx==index) {
+                return tmp;
+            }
+            tmp = tmp->next;
+            idx++;
+        }
+    }
+    
+    return NULL;
+}
+static int node_swap(list_node_t *n1, list_node_t *n2)
+{
+    if(!n1 || !n2) {
+        return -1;;
+    }
+    
+    node_t x=n1->data;
+    n1->data = n2->data;
+    n2->data = x;
+    
+    return 0;
+}
+
+///////////////////////////////////////////////////////////
+handle_t xlist_init(list_cfg_t *cfg)
+{
+    list_t *l=NULL;
+    
+    if (!cfg)
+        return NULL;
+    
+    l = MALLOC(sizeof(list_t));
+    if (!l)
+        return NULL;
+    
+    l->used.head = NULL;
+    l->used.tail = NULL;
+    l->used.size = 0;
+    l->lock = lock_init();
+    l->cfg = *cfg;
+    
+    l->free.head = NULL;
+    l->free.tail = NULL;
+    l->free.size = 0;
+    
+    return l;
+}
+
+
+int xlist_free(handle_t l)
+{
+    int i;
+    list_node_t *xd;
+    list_t *hl=(list_t*)l;
+    
+    if(!hl) {
+        return -1;
+    }
+    
+    if(lock_on(hl->lock)) {
+        if (hl->cfg.log) LOGE("___ list_free lock failed\n");
+        return -1;
+    }
+    
+    xd = hl->used.head;
+    while(xd) {
+        node_free(hl, xd);
+        xd = xd->next;
+    }
+    
+    xd = hl->free.head;
+    while(xd) {
+        node_free(hl, xd);
+        xd = xd->next;
+    }
+    lock_off(hl->lock);
+    
+    lock_free(hl->lock);
+    free(hl->free.head);
+    free(hl);
+    
+    return 0;
+}
+
+
+int xlist_get_node(handle_t l, list_node_t **lnode, int index)
+{
+    int r=-1;
+    list_node_t *ln=NULL;
+    list_t *hl=(list_t*)l;
+    
+    if(!hl || !lnode || index<0) {
+        return -1;
+    }
+    
+    if(lock_on(hl->lock)) {
+        if (hl->cfg.log) LOGE("___ list_get lock failed\n");
+        return -1;
+    }
+    
+    if (hl->used.size<=0 || index>=hl->used.size) {
+        goto quit;
+    }
+    
+    ln = node_get(hl, index);
+    if(!ln) {
+        goto quit;
+    }
+    
+    *lnode = ln;
+    r = 0;
+    
+quit:
+    lock_off(hl->lock);
+    return r;
+}
+
+
+int xlist_set_node(handle_t l, list_node_t *lnode, int index)
+{
+    int r=-1;
+    list_node_t *ln=NULL;
+    list_t *hl=(list_t*)l;
+    
+    if(!hl || !lnode || index<0) {
+        return -1;
+    }
+    
+    if(lock_on(hl->lock)) {
+        if (hl->cfg.log) LOGE("___ list_set lock failed\n");
+        return -1;
+    }
+    
+    if (hl->used.size<=0 || index>=hl->used.size) {
+        goto quit;
+    }
+    
+    ln = node_get(hl, index);
+    if(ln) {
+        r = node_set(hl, ln, &lnode->data);
+    }
+    
+quit:
+    lock_off(hl->lock);    
+    return r;
+}
+
+
+int xlist_take_node(handle_t l, list_node_t **lnode, int index)
+{
+    int r=-1;
+    list_node_t *ln=NULL;
+    list_t *hl=(list_t*)l;
+    
+    if(!hl || !lnode || index<0) {
+        return -1;
+    }
+    
+    if(lock_on(hl->lock)) {
+        if (hl->cfg.log) LOGE("___ list_take_node lock failed\n");
+        return -1;
+    }
+    
+    if (hl->used.size<=0 || index>=hl->used.size) {
+       goto quit;
+    }
+    
+    ln = node_get(hl, index);
+    if(!ln) {
+        goto quit;
+    }
+    *lnode = ln;
+    r = node_remove(hl, ln, 0);
+
+quit:
+    lock_off(hl->lock);    
+    return r;
+}
+
+
+int xlist_back_node(handle_t l, list_node_t *lnode)
+{
+    list_t *hl=(list_t*)l;
+    
+    if(!hl || !lnode) {
+        return -1;
+    }
+    
+    if(lock_on(hl->lock)) {
+        if (hl->cfg.log) LOGE("___ list_back_node lock failed\n");
+        return -1;
+    }
+    
+    node_to_free(l, lnode);
+    lock_off(hl->lock);
+    
+    return 0;
+}
+
+
+int xlist_discard_node(handle_t l, list_node_t *lnode)
+{
+    list_t *hl=(list_t*)l;
+    
+    if(!hl || !lnode) {
+        return -1;
+    }
+    
+    if(lock_on(hl->lock)) {
+        if (hl->cfg.log) LOGE("___ list_discard_node lock failed\n");
+        return -1;
+    }
+    node_free(l, lnode);
+    
+    lock_off(hl->lock);
+    return 0;
+}
+
+
+int xlist_insert(handle_t l, node_t *node, int index)
+{
+    int r=-1;
+    list_t *hl=(list_t*)l;
+    list_node_t *xd,*tmp;
+    
+    if(!hl || !node) {
+        return -1;
+    }
+    
+    if(lock_on(hl->lock)) {
+        if (hl->cfg.log) LOGE("___list_insert lock failed\n");
+        return -1;
+    }
+    
+    if (index>hl->used.size) {
+        if (hl->cfg.log) LOGE("___list_insert, invalid index, size: %d, index: %d\n", hl->used.size, index);
+        goto quit;
+    }
+    
+    if (hl->cfg.max>0 && hl->used.size>=hl->cfg.max) {
+        //链表装满时, 根据策略丢数据
+        //如果要插入的位置为末尾, 则丢弃
+        if(index<0 || index>=hl->used.size-1) {
+            if(hl->cfg.mode==LIST_FULL_FILO) { //策略为丢新数据时
+                if (hl->cfg.log) {
+                    //LOGW("___list_insert, list full, discard the new data\n");
+                }
+                r = -2; goto quit;
+            }
+            
+            if (hl->cfg.log) {
+                //LOGW("___list_insert, list full, discard the old data\n");
+            }
+            
+            xd = node_get(hl, 0);              //找最老的数据丢
+            node_remove(hl, xd, 1);
+        }
+        else {  //如果插入位置位于中间, 则需丢最后一个数据
+            if (hl->cfg.log) {
+                LOGW("___list_insert, insert to the middle, discard the last data\n");
+            }
+            
+            xd = node_get(hl, hl->used.size-1);
+            node_remove(hl, xd, 1);
+        }
+    }
+    
+    tmp = node_new(hl, node);
+    if(!tmp) {
+        if (hl->cfg.log) LOGE("___list_insert, malloc %d error, l: 0x%08x, used.size: %d, free.size: %d\n", node->dlen, (uint32_t)hl, hl->used.size, hl->free.size);
+        goto quit;
+    }
+    r = node_insert(l, tmp, index);
+
+quit:
+    lock_off(hl->lock);
+    
+    return r;
+}
+
+
+int xlist_insert_node(handle_t l, list_node_t *lnode, int index)
+{
+    int r=-1;
+    list_t *hl=(list_t*)l;
+    list_node_t *xd,*tmp=lnode;
+    
+    if(!hl || !lnode) {
+        return -1;
+    }
+    
+    if(lock_on(hl->lock)) {
+        if (hl->cfg.log) LOGE("___ list_addto lock failed\n");
+        return -1;
+    }
+    
+    if (index>hl->used.size) {
+        if (hl->cfg.log) LOGE("list_addto, invalid index, size: %d, index: %d\n", hl->used.size, index);
+        goto quit;
+    }
+    
+    if (hl->cfg.max>0 && hl->used.size>=hl->cfg.max) {
+        //链表装满时, 根据策略丢数据
+        //如果要插入的位置为末尾, 则丢弃
+        if(index<0 || index>=hl->used.size-1) {
+            if(hl->cfg.mode==LIST_FULL_FILO) { //策略为丢新数据时
+                r = 0; goto quit;
+            }
+            xd = node_get(hl, 0);              //找最老的数据丢
+            node_remove(hl, xd, 1);
+        }
+        else {  //如果插入位置位于中间, 则需丢最后一个数据
+            xd = node_get(hl, hl->used.size-1);
+            node_remove(hl, xd, 1);
+        }
+    }
+    r = node_insert(l, lnode, index);
+
+quit:
+    lock_off(hl->lock);
+    return r;
+}
+
+
+int xlist_append(handle_t l, int tp, void *data, int len)
+{
+    node_t node={tp, data, len, len};
+    
+    return xlist_insert(l, &node, -1);
+}
+
+
+int xlist_append_node(handle_t l, list_node_t *lnode)
+{
+    return xlist_insert_node(l, lnode, -1);
+}
+
+
+int xlist_infront(handle_t l, int tp, void *data, int len)
+{
+    node_t node={tp, data, len, len};
+    
+    return xlist_insert(l, &node, 0);
+}
+
+
+int xlist_infront_node(handle_t l, list_node_t *lnode)
+{
+    return xlist_insert_node(l, lnode, 0);
+}
+
+
+int xlist_remove(handle_t l, int index)
+{
+    int r=-1;
+    list_node_t *xd;
+    list_t *hl=(list_t*)l;
+    
+    if (!hl) {
+        return -1;
+    }
+    
+    if(lock_on(hl->lock)) {
+        if (hl->cfg.log) LOGE("___ list_remove lock failed\n");
+        return -1;
+    }
+    
+    xd = node_get(l, index);
+    if(!xd) {
+        goto quit;
+    }
+    r = node_remove(hl, xd, 1);
+    
+quit:
+    lock_off(hl->lock);
+    return r;
+}
+
+
+
+int xlist_delete(handle_t l, int index)
+{
+    int r=-1;
+    list_node_t *xd;
+    list_t *hl=(list_t*)l;
+    
+    if (!hl) {
+        return -1;
+    }
+    
+    if(lock_on(hl->lock)) {
+        if (hl->cfg.log) LOGE("___ list_delete lock failed\n");
+        return -1;
+    }
+    
+    if(hl->used.size<=0 || index>=hl->used.size) {
+        goto quit;
+    }
+    
+    xd = node_get(l, index);
+    r = node_free(hl, xd);
+    
+quit:
+    lock_off(hl->lock);
+    return r;
+}
+
+
+int xlist_sort(handle_t l, int order)
+{
+    int r=-1;
+    list_t *hl=(list_t*)l;
+    
+    if (!hl || order>=LIST_SORT_MAX) {
+        return -1;
+    }
+    
+    if(lock_on(hl->lock)) {
+        if (hl->cfg.log) LOGE("___ list_sort lock failed\n");
+        return -1;
+    }
+    
+    if(hl->used.size<2) {
+        goto quit;
+    }
+    
+    {
+        int len,cmp;
+        dlist_t *dl=&hl->used;
+        list_node_t *p2,*p1=dl->head;
+        
+        while(p1) {
+            p2 = p1->next;
+            while(p2) {
+                len = MIN(p1->data.dlen, p2->data.dlen);
+                cmp = memcmp(p1->data.buf, p2->data.buf, len);
+                if(((cmp>0) && (order==LIST_SORT_ASCEND)) || ((cmp<0) && (order==LIST_SORT_DESCEND))) {
+                    node_swap(p1, p2);
+                }
+                
+                p2 = p2->next;
+            }
+            p1 = p1->next;
+        }  
+    }
+    r = 0;
+    
+quit:
+    lock_off(hl->lock);
+    return r;
+}
+
+
+int xlist_size(handle_t l)
+{
+    int size=0;
+    list_t *hl=(list_t*)l;
+    
+    if (!hl) {
+        return -1;
+    }
+    
+    if(lock_on(hl->lock)) {
+        if (hl->cfg.log) LOGE("___ list_size lock failed\n");
+        return -1;
+    }
+    
+    size = hl->used.size;
+    lock_off(hl->lock);
+    
+    return size;
+}
+
+
+int xlist_clear(handle_t l)
+{
+    int r=-1;
+    list_node_t *xd;
+    list_t *hl=(list_t*)l;
+    
+    if (!hl) {
+        return -1;
+    }
+    
+    if(lock_on(hl->lock)) {
+        if (hl->cfg.log) LOGE("___ list_clear lock failed\n");
+        return -1;
+    }
+    
+    if(hl->used.size<=0) {
+        goto quit;
+    }
+    
+    xd = hl->used.head;
+    while(xd) {
+        node_remove(hl, xd, 1);
+        xd = xd->next;
+    }
+    hl->used.size = 0;
+    hl->used.head = NULL;
+    hl->used.tail = NULL;
+    r = 0;
+    
+quit:
+    lock_off(hl->lock);
+    return r;
+}
+
+
+
+int xlist_iterator(handle_t l, node_t *node, list_callback_t callback, void *arg)
+{
+    int r=-1,act=0;
+    list_node_t *xd=NULL;
+    list_t *hl=(list_t*)l;
+    dlist_t *dl=NULL;
+
+    if (!hl) {
+        return -1;
+    }
+
+    if(lock_on(hl->lock)) {
+        if (hl->cfg.log) LOGE("___ list_iterator lock failed\n");
+        return -1;
+    }
+
+    dl = &hl->used;
+    if (dl->size<=0) {
+        goto quit;
+    }
+
+    xd = dl->head;
+    while (xd) {
+        if (callback) {
+            r = callback(hl, node, &xd->data, arg, &act);
+            if(act==LIST_ACT_STOP) {
+                break;
+            }
+            else if(act==LIST_ACT_REMOVE) {
+                node_remove(l, xd, 1);
+            }
+            else if(act==LIST_ACT_DELETE) {
+                node_remove(l, xd, 2);
+            }
+        }
+        xd = xd->next;
+    }
+    
+quit:
+    lock_off(hl->lock);
+    return r;
+}
+

+ 93 - 0
04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/src/xlist.h

@@ -0,0 +1,93 @@
+#ifndef __XLIST_Hx__
+#define __XLIST_Hx__
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef void* handle_t;
+
+enum {
+    LIST_FULL_FIFO=0,
+    LIST_FULL_FILO,
+};
+
+enum {
+    LIST_SORT_ASCEND=0,
+    LIST_SORT_DESCEND,
+    
+    LIST_SORT_MAX
+};
+
+enum {
+    LIST_ACT_NONE=0,
+    LIST_ACT_STOP,
+    LIST_ACT_REMOVE,
+    LIST_ACT_DELETE,
+};
+
+typedef struct {
+    int  tp;            //type
+    void *buf;
+    int  dlen;          //data len
+    int  blen;          //buf len
+}node_t;
+
+
+typedef struct list_node {
+    node_t              data;
+    struct list_node    *prev;
+    struct list_node    *next;
+}list_node_t;
+
+typedef struct {
+    int         log;        //0:disable  1: enable
+    int         mode;
+    int         max;        //the max count
+}list_cfg_t;
+
+
+
+//该函数返回负值是表示结束,将退出迭代循环
+//该函数返回值>=0将继续迭代至结束
+typedef int (*list_callback_t)(handle_t l, node_t *node, node_t *xd, void *arg, int *act);
+
+
+handle_t xlist_init(list_cfg_t *cfg);
+int xlist_free(handle_t l);
+int xlist_get_node(handle_t l, list_node_t **lnode, int index);
+int xlist_set_node(handle_t l, list_node_t  *lnode, int index);
+
+int xlist_take_node(handle_t l, list_node_t **lnode, int index);
+int xlist_back_node(handle_t l, list_node_t *lnode);
+int xlist_discard_node(handle_t l, list_node_t *lnode);
+
+int xlist_insert(handle_t l, node_t *node, int index);
+int xlist_insert_node(handle_t l, list_node_t *lnode, int index);
+
+int xlist_append(handle_t l, int tp, void *data, int len);
+int xlist_append_node(handle_t l, list_node_t *lnode);
+
+int xlist_infront(handle_t l, int tp, void *data, int len);
+int xlist_infront_node(handle_t l, list_node_t *lnode);
+
+int xlist_remove(handle_t l, int index);
+int xlist_delete(handle_t l, int index);
+
+int xlist_sort(handle_t l, int order);
+int xlist_size(handle_t l);
+int xlist_clear(handle_t l);
+int xlist_iterator(handle_t l, node_t *node, list_callback_t callback, void *arg);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+

+ 192 - 0
04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/upgrade/md5.c

@@ -0,0 +1,192 @@
+#include <string.h>
+#include "md5.h"  
+  
+uint8_t PADDING[]={0x80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};  
+  
+void md5_init(md5_ctx_t *ctx)
+{  
+    ctx->count[0] = 0;
+    ctx->count[1] = 0;
+    ctx->state[0] = 0x67452301;
+    ctx->state[1] = 0xEFCDAB89;
+    ctx->state[2] = 0x98BADCFE;
+    ctx->state[3] = 0x10325476;
+}  
+void md5_update(md5_ctx_t* ctx, uint8_t *input,uint32_t inputlen)
+{  
+    uint32_t i = 0,index = 0,partlen = 0;  
+    index = (ctx->count[0] >> 3) & 0x3F;
+    partlen = 64 - index;  
+    ctx->count[0] += inputlen << 3;
+    if(ctx->count[0] < (inputlen << 3))
+        ctx->count[1]++;
+    ctx->count[1] += inputlen >> 29;
+  
+    if(inputlen >= partlen)  
+    {  
+        memcpy(&ctx->buffer[index],input,partlen);
+        md5_transform(ctx->state, ctx->buffer);
+        for(i = partlen;i+64 <= inputlen;i+=64)  
+            md5_transform(ctx->state,&input[i]);
+        index = 0;          
+    }    
+    else  
+    {  
+        i = 0;  
+    }  
+    memcpy(&ctx->buffer[index],&input[i],inputlen-i);
+}  
+void md5_final(md5_ctx_t* ctx,uint8_t digest[16])
+{  
+    uint32_t index = 0,padlen = 0;  
+    uint8_t bits[8];  
+    index = (ctx->count[0] >> 3) & 0x3F;
+    padlen = (index < 56)?(56-index):(120-index);  
+    md5_encode(bits, ctx->count,8);
+    md5_update(ctx,PADDING,padlen);
+    md5_update(ctx,bits,8);
+    md5_encode(digest, ctx->state,16);
+}  
+void md5_encode(uint8_t *output,uint32_t *input,uint32_t len)  
+{  
+    uint32_t i = 0,j = 0;  
+    while(j < len)  
+    {  
+        output[j] = input[i] & 0xFF;    
+        output[j+1] = (input[i] >> 8) & 0xFF;  
+        output[j+2] = (input[i] >> 16) & 0xFF;  
+        output[j+3] = (input[i] >> 24) & 0xFF;  
+        i++;  
+        j+=4;  
+    }  
+}  
+void md5_decode(uint32_t *output,uint8_t *input,uint32_t len)  
+{  
+    uint32_t i = 0,j = 0;  
+    while(j < len)  
+    {  
+        output[i] = (input[j]) |  
+            (input[j+1] << 8) |  
+            (input[j+2] << 16) |  
+            (input[j+3] << 24);  
+        i++;  
+        j+=4;   
+    }  
+}  
+void md5_transform(uint32_t state[4],uint8_t block[64])  
+{  
+    uint32_t a = state[0];  
+    uint32_t b = state[1];  
+    uint32_t c = state[2];  
+    uint32_t d = state[3];  
+    uint32_t x[64];  
+    md5_decode(x,block,64);  
+    FF(a, b, c, d, x[ 0], 7, 0xd76aa478);   
+    FF(d, a, b, c, x[ 1], 12, 0xe8c7b756);   
+    FF(c, d, a, b, x[ 2], 17, 0x242070db);   
+    FF(b, c, d, a, x[ 3], 22, 0xc1bdceee);   
+    FF(a, b, c, d, x[ 4], 7, 0xf57c0faf);   
+    FF(d, a, b, c, x[ 5], 12, 0x4787c62a);   
+    FF(c, d, a, b, x[ 6], 17, 0xa8304613);   
+    FF(b, c, d, a, x[ 7], 22, 0xfd469501);   
+    FF(a, b, c, d, x[ 8], 7, 0x698098d8);   
+    FF(d, a, b, c, x[ 9], 12, 0x8b44f7af);   
+    FF(c, d, a, b, x[10], 17, 0xffff5bb1);   
+    FF(b, c, d, a, x[11], 22, 0x895cd7be);   
+    FF(a, b, c, d, x[12], 7, 0x6b901122);   
+    FF(d, a, b, c, x[13], 12, 0xfd987193);   
+    FF(c, d, a, b, x[14], 17, 0xa679438e);   
+    FF(b, c, d, a, x[15], 22, 0x49b40821);   
+  
+      
+    GG(a, b, c, d, x[ 1], 5, 0xf61e2562);   
+    GG(d, a, b, c, x[ 6], 9, 0xc040b340);   
+    GG(c, d, a, b, x[11], 14, 0x265e5a51);   
+    GG(b, c, d, a, x[ 0], 20, 0xe9b6c7aa);   
+    GG(a, b, c, d, x[ 5], 5, 0xd62f105d);   
+    GG(d, a, b, c, x[10], 9,  0x2441453);   
+    GG(c, d, a, b, x[15], 14, 0xd8a1e681);   
+    GG(b, c, d, a, x[ 4], 20, 0xe7d3fbc8);   
+    GG(a, b, c, d, x[ 9], 5, 0x21e1cde6);   
+    GG(d, a, b, c, x[14], 9, 0xc33707d6);   
+    GG(c, d, a, b, x[ 3], 14, 0xf4d50d87);   
+    GG(b, c, d, a, x[ 8], 20, 0x455a14ed);   
+    GG(a, b, c, d, x[13], 5, 0xa9e3e905);   
+    GG(d, a, b, c, x[ 2], 9, 0xfcefa3f8);   
+    GG(c, d, a, b, x[ 7], 14, 0x676f02d9);   
+    GG(b, c, d, a, x[12], 20, 0x8d2a4c8a);   
+  
+      
+    HH(a, b, c, d, x[ 5], 4, 0xfffa3942);   
+    HH(d, a, b, c, x[ 8], 11, 0x8771f681);   
+    HH(c, d, a, b, x[11], 16, 0x6d9d6122);   
+    HH(b, c, d, a, x[14], 23, 0xfde5380c);   
+    HH(a, b, c, d, x[ 1], 4, 0xa4beea44);   
+    HH(d, a, b, c, x[ 4], 11, 0x4bdecfa9);   
+    HH(c, d, a, b, x[ 7], 16, 0xf6bb4b60);   
+    HH(b, c, d, a, x[10], 23, 0xbebfbc70);   
+    HH(a, b, c, d, x[13], 4, 0x289b7ec6);   
+    HH(d, a, b, c, x[ 0], 11, 0xeaa127fa);   
+    HH(c, d, a, b, x[ 3], 16, 0xd4ef3085);   
+    HH(b, c, d, a, x[ 6], 23,  0x4881d05);   
+    HH(a, b, c, d, x[ 9], 4, 0xd9d4d039);   
+    HH(d, a, b, c, x[12], 11, 0xe6db99e5);   
+    HH(c, d, a, b, x[15], 16, 0x1fa27cf8);   
+    HH(b, c, d, a, x[ 2], 23, 0xc4ac5665);   
+  
+      
+    II(a, b, c, d, x[ 0], 6, 0xf4292244);   
+    II(d, a, b, c, x[ 7], 10, 0x432aff97);   
+    II(c, d, a, b, x[14], 15, 0xab9423a7);   
+    II(b, c, d, a, x[ 5], 21, 0xfc93a039);   
+    II(a, b, c, d, x[12], 6, 0x655b59c3);   
+    II(d, a, b, c, x[ 3], 10, 0x8f0ccc92);   
+    II(c, d, a, b, x[10], 15, 0xffeff47d);   
+    II(b, c, d, a, x[ 1], 21, 0x85845dd1);   
+    II(a, b, c, d, x[ 8], 6, 0x6fa87e4f);   
+    II(d, a, b, c, x[15], 10, 0xfe2ce6e0);   
+    II(c, d, a, b, x[ 6], 15, 0xa3014314);   
+    II(b, c, d, a, x[13], 21, 0x4e0811a1);   
+    II(a, b, c, d, x[ 4], 6, 0xf7537e82);   
+    II(d, a, b, c, x[11], 10, 0xbd3af235);   
+    II(c, d, a, b, x[ 2], 15, 0x2ad7d2bb);   
+    II(b, c, d, a, x[ 9], 21, 0xeb86d391);   
+    state[0] += a;  
+    state[1] += b;  
+    state[2] += c;  
+    state[3] += d;  
+}
+
+#define CHAR(b) (b<=9)?(b+0x30):(b-10+0x61);
+static void byte2char(char *chr, uint8_t b)
+{
+    char h,l;
+    
+    l = b&0x0f;
+    h = (b>>4)&0x0f;
+    
+    chr[0] = CHAR(h);
+    chr[1] = CHAR(l);
+}
+
+int md5_calc(void *p1, int len1, void *p2, int len2, char *md5)
+{
+    int i;
+    uint8_t tmp[16];
+    md5_ctx_t ctx;
+    
+    md5_init(&ctx);
+    md5_update(&ctx, (uint8_t*)p1, len1);
+    md5_update(&ctx, (uint8_t*)p2, len2);
+    md5_final(&ctx, tmp);
+    
+    for (i=0; i<16; i++) {
+        byte2char(&md5[i*2], tmp[i]);
+    }
+    
+    return 0;
+}
+

+ 68 - 0
04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/upgrade/md5.h

@@ -0,0 +1,68 @@
+#ifndef MD5_H  
+#define MD5_H  
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+typedef struct
+{
+	uint32_t count[2];
+	uint32_t state[4];
+	uint8_t buffer[64];
+}md5_ctx_t;
+
+
+#define F(x,y,z) ((x & y) | (~x & z))  
+#define G(x,y,z) ((x & z) | (y & ~z))  
+#define H(x,y,z) (x^y^z)  
+#define I(x,y,z) (y ^ (x | ~z))  
+#define ROTATE_LEFT(x,n) ((x << n) | (x >> (32-n)))  
+
+#define FF(a,b,c,d,x,s,ac) \
+	{ \
+		a += F(b, c, d) + x + ac; \
+		a = ROTATE_LEFT(a, s); \
+		a += b; \
+	}
+
+#define GG(a,b,c,d,x,s,ac) \
+	{ \
+		a += G(b, c, d) + x + ac; \
+		a = ROTATE_LEFT(a, s); \
+		a += b; \
+	}
+
+#define HH(a,b,c,d,x,s,ac) \
+	{ \
+		a += H(b, c, d) + x + ac; \
+		a = ROTATE_LEFT(a, s); \
+		a += b; \
+	}
+
+#define II(a,b,c,d,x,s,ac) \
+	{ \
+		a += I(b, c, d) + x + ac; \
+		a = ROTATE_LEFT(a, s); \
+		a += b; \
+	}
+
+void md5_init(md5_ctx_t* context);
+void md5_update(md5_ctx_t* context, uint8_t* input, uint32_t inputlen);
+void md5_final(md5_ctx_t* context, uint8_t digest[16]);
+void md5_transform(uint32_t state[4], uint8_t block[64]);
+void md5_encode(uint8_t* output, uint32_t* input, uint32_t len);
+void md5_decode(uint32_t* output, uint8_t* input, uint32_t len);
+
+int md5_calc(void* p1, int len1, void* p2, int len2, char* md5);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif  

+ 753 - 0
04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/upgrade/upgrade.c

@@ -0,0 +1,753 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <pthread.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ipc.h> 
+#include <sys/msg.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <unistd.h>
+#include <signal.h>
+#include <string.h>
+#include <stdarg.h>
+#include <dirent.h>
+#include "upgrade.h"
+#include "md5.h"
+
+
+typedef struct {
+	char *pbuf;
+    int  dlen;
+    int  blen;
+}node_t;
+typedef struct {
+	uint32_t  src;      //
+	uint8_t   obj;      //升级对象,解压后扫描文件,赋值到该变量
+	uint8_t   stat;     //当前升级所处状态
+	uint8_t   step;     //当前升级所处阶段
+
+	pthread_t tid;
+    FILE*     log;
+    key_t     key;
+}upg_handle_t;
+static upg_handle_t upgHandle;
+static int log_print(const char *fmt, ...);
+
+//#define LOG log_print
+#define LOG printf
+
+
+
+static int node_free(node_t *nd)
+{
+    if(!nd) {
+        return -1;
+    }
+
+    free(nd->pbuf);
+    nd->pbuf = NULL;
+    nd->dlen = 0;
+    nd->blen = 0;
+}
+static int exe_cmd(char *cmd, node_t *nd)
+{
+    int r=0;
+	FILE *fp=NULL;
+    char *pbuf=NULL;
+    int onelen=1000;
+    int dlen=0,blen=onelen;
+
+    pbuf = malloc(onelen);
+    if(!pbuf) {
+        return -1;
+    }
+    
+    fp = popen(cmd, "r");
+    if (fp == NULL) {
+        return -1;
+    }
+
+	while(1) {
+        r = fread(pbuf+dlen, sizeof(char), onelen, fp);
+        if(r<=0) {
+            LOG("upgrade relloac %d failed\n", dlen+onelen);
+            break;
+        }
+        dlen += r;
+        if(dlen+onelen>blen) {
+            char* p = realloc(pbuf, dlen+onelen);
+            if(!p) {
+                LOG("upgrade relloac %d failed\n", dlen+onelen);
+                free(pbuf); pclose(fp);
+                return -1;
+            }
+            pbuf = p;
+            blen = dlen+onelen;
+        }
+	}
+    pclose(fp);
+    
+    nd->pbuf = pbuf;
+    nd->dlen = dlen;
+    nd->blen = blen;
+    
+	return 0;
+}
+static int exe_cmd2(char *cmd)
+{
+    return system(cmd);
+}
+
+//https://blog.csdn.net/qq_38650447/article/details/136284071
+static int log_init(void)
+{
+    char *path=UPG_LOG_PATH;
+    char tmp[200];
+    
+    if (upgHandle.log) {
+        return -1;
+    }
+
+    snprintf(tmp, sizeof(tmp), "mkdir -p %s", path);
+    system(tmp);
+
+    upgHandle.log = fopen(path, "wt");
+    if (!upgHandle.log) {
+        printf("%s open failed\n", path);
+        return -1;
+    }
+
+    return 0;
+}
+static int log_print(const char *fmt, ...)
+{
+    int r;
+    va_list va;
+    char buf[1000];
+
+    va_start(va, fmt);
+    r = vsprintf(buf, fmt, va);
+    va_end(va);
+
+    if (upgHandle.log) {
+        fprintf(upgHandle.log, "%s", buf);
+    }
+    else {
+        printf("%s", buf);
+    }
+
+    return 0;
+}
+static int log_flush(void)
+{
+    if (upgHandle.log) {
+        return -1;
+    }
+    fflush(upgHandle.log);
+
+    return 0;
+}
+static int file_exist(char* path)
+{
+    int r;
+    struct stat st;
+
+    r = stat(path, &st);
+    if (r == 0) {
+        return 1;
+    }
+    else {
+        return 0;
+    }
+}
+static int file_length(char* path)
+{
+    int r;
+    struct stat st;
+
+    r = stat(path, &st);
+    if (r) {
+        return -1;
+    }
+
+    return st.st_size;
+}
+static int file_touch(int id)
+{
+    int r;
+    char tmp[200];
+
+    snprintf(tmp, sizeof(tmp), "touch %s/s%d", UPG_FOLDER, id);
+    return system(tmp);       // 使用写入模式创建一个新文件
+}
+static int file_untouch(int id)
+{
+    int r;
+    char tmp[200];
+
+    snprintf(tmp, sizeof(tmp), "rm %s/s%d", UPG_FOLDER, id);
+    return system(tmp);       // 使用写入模式创建一个新文件
+}
+
+
+static int folder_init(void)
+{
+    char tmp[200];
+
+    snprintf(tmp, sizeof(tmp), "mkdir -p %s", RUN_FOLDER);
+    system(tmp);
+
+    snprintf(tmp, sizeof(tmp), "mkdir -p %s", BAK_FOLDER);
+    system(tmp);
+
+    snprintf(tmp, sizeof(tmp), "mkdir -p %s", UPG_FOLDER);
+    system(tmp);
+
+    snprintf(tmp, sizeof(tmp), "mkdir -p %s", DOWN_FOLDER);
+    system(tmp);
+
+    return 0;
+}
+static int file_save(char *path, void *buf, int len)
+{
+    int r;
+    FILE *fp;
+    
+    fp = fopen(path, "wb");
+    if(!fp) {
+        LOG("file_save, fopen %s failed, %d, %d\n", path);
+        return -1;
+    }
+    r = fwrite(buf, 1, len, fp);
+    if(r!=len) {
+        LOG("file_save %s failed, %d, %d\n", path, r, len);
+        r = -1;
+    }
+    else {
+        r = 0;
+    }
+    fclose(fp);
+
+    return r;
+}
+static int file_load(char* path, void* buf, int len)
+{
+    int r;
+    FILE* fp;
+
+    fp = fopen(path, "rb");
+    if (!fp) {
+        LOG("file_load, fopen %s failed, %d, %d\n", path);
+        return -1;
+    }
+    r = fread(buf, 1, len, fp);
+    if (r != len) {
+        LOG("file_load %s failed, %d, %d\n", path, r, len);
+        r = -1;
+    }
+    else {
+        r = 0;
+    }
+    fclose(fp);
+
+    return r;
+}
+static int file_remove(char *path)
+{
+    return remove(path);
+}
+
+/*
+    tar pdutar to run/
+*/
+static int file_cover(char *path)
+{
+    int r;
+    char cmd[200];
+
+    snprintf(cmd, sizeof(cmd), "tar -xpf %s -C / > /dev/null 2>&1", path);
+    r = system(cmd);
+    if(r) {
+        LOG("%s failed\n", cmd);
+        return -1;
+    }
+
+    return 0;
+}
+
+
+static int dir_is_empty(char *path)
+{
+    struct dirent *entry;
+    int is_empty = 1;
+
+    DIR *dir = opendir(path);
+    if (dir == NULL) {
+        perror("opendir");
+        return -1; // 错误处理
+    }
+    
+    while ((entry = readdir(dir)) != NULL) {
+        // 忽略'.'和'..'
+        if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) {
+            is_empty = 0;
+            break;
+        }
+    }
+ 
+    closedir(dir);
+    return is_empty;
+}
+
+//when app run success, copy run/* to bak/
+static int file_backup(void)
+{
+    int r;
+    char tmp[100];
+    char cmd[200];
+
+    //dl目录有tar压缩包,则拷贝到bak目录
+    snprintf(tmp, sizeof(tmp), "%s/%s", DOWN_FOLDER, UPG_TAR_NAME);
+    if(file_exist(tmp)) {
+        LOG("%s exist\n", tmp);
+        snprintf(cmd, sizeof(cmd), "cp -f %s %s/", tmp, BAK_FOLDER);
+        r = system(cmd);
+        if(r==0) {
+            return 0;
+        }
+        LOG("cp %s to %s failed\n", tmp, BAK_FOLDER);
+    }
+    else {
+        LOG("%s not exist\n", tmp);
+    }
+
+    //bak目录有tar压缩包,则退出
+    snprintf(tmp, sizeof(tmp), "%s/%s", BAK_FOLDER, UPG_TAR_NAME);
+    if(file_exist(tmp)) {
+        LOG("%s exist\n", tmp);
+        return 0;
+    }
+    else {
+        LOG("%s not exist\n", tmp);
+    }
+
+    //bak目录没有tar压缩包,则将run目录打包存进bak目录
+    LOG("tar %s to %s/%s\n", RUN_FOLDER, BAK_FOLDER, UPG_TAR_NAME);
+    snprintf(cmd, sizeof(cmd), "tar -czpPf %s/%s %s > /dev/null 2>&1", BAK_FOLDER, UPG_TAR_NAME, RUN_FOLDER);
+    r = system(cmd);
+    if(r) {
+        LOG("% failed, %d\n", cmd, r);
+        return -1;
+    }
+
+    return 0;
+}
+
+/*
+    when app run failed, copy to bak/ run/
+*/
+static int file_restore(void)
+{
+    int r;
+    char cmd[200];
+
+    snprintf(cmd, sizeof(cmd), "tar -xpf %s/%s -C / > /dev/null 2>&1", DOWN_FOLDER, UPG_TAR_NAME);
+    r = system(cmd);
+    if(r) {
+        LOG("% failed, %d\n", cmd, r);
+        return -1;
+    }
+
+    return 0;
+}
+
+
+#define CHAR(b) (((b)<=9)?((b)+0x30):((b)-10+0x61));
+static void byte2char(char *chr, uint8_t b)
+{
+    chr[0] = CHAR(b>>4);
+    chr[1] = CHAR(b&0x0f);
+}
+static void print_md5(char *s, md5_t *m)
+{
+    int i;
+    
+    LOG("__%s", s);
+    for(i=0; i<32; i++) {
+        LOG("%c", m->data[i]);
+    }
+    LOG("\n");
+}
+
+//md5相同返回0,否则返回1
+static int md5_check(upgrade_file_t *h)
+{
+    md5_ctx_t ctx;
+    uint8_t i,tmp[16];
+    md5_t m1,m2;
+
+    md5_init(&ctx);
+    md5_update(&ctx, (char*)h, h->dlen+sizeof(upgrade_file_t));
+    md5_final(&ctx, tmp);
+
+    for (i=0; i<16; i++) {
+        byte2char(&m2.data[i*2], tmp[i]);
+    }
+    memcpy(&m1, h->data+h->dlen, sizeof(md5_t));
+
+    print_md5("ori md5: ", &m1);
+    print_md5("cal md5: ", &m2);
+    if(memcmp(&m1, &m2, sizeof(md5_t))) {
+        return -1;
+    }
+
+    return 0;
+}
+static int file_split(void)
+{
+    int r=0,flen;
+    char *fbuf=NULL;
+    char path[200];
+
+    snprintf(path, sizeof(path), "%s/%s", DOWN_FOLDER, UPG_PKG_NAME);
+    flen = file_length(path);
+    if(flen<=0) {
+        LOG("file_length %s failed\n", path);
+        return -1;
+    }
+    
+    fbuf = (char*)malloc(flen);
+    if(!fbuf) {
+        LOG("malloc %d failed\n", flen);
+        return -1;
+    }
+    
+    r = file_load(path, fbuf, flen);
+    if(r) {
+        LOG("%s load failed\n", path);
+        return -1;
+    }
+    upgrade_file_t *hfile = (upgrade_file_t*)fbuf;
+    
+    snprintf(path, sizeof(path), "%s/%s", DOWN_FOLDER, UPG_HDR_NAME);
+    r = file_save(path, hfile, sizeof(upgrade_file_t));
+    if(r) {
+        LOG("file_save %s failed\n", path);
+        return -1;
+    }
+
+    snprintf(path, sizeof(path), "%s/%s", DOWN_FOLDER, UPG_TAR_NAME);
+    r = file_save(path, hfile->data, hfile->dlen);
+    if(r) {
+        LOG("file_save %s failed\n", path);
+        return -1;
+    }
+
+    snprintf(path, sizeof(path), "%s/%s", DOWN_FOLDER, UPG_PKG_NAME);
+    r = file_remove(path);
+    if(r) {
+        LOG("file_remove %s failed\n", path);
+        return -1;
+    }
+
+    return 0;
+}
+
+static int file_check(char *path)
+{
+    int r=0,flen;
+    char *fbuf=NULL;
+    upgrade_file_t *hfile=NULL;
+
+    flen = file_length(path);
+    if(flen<=0) {
+        LOG("file_length %s failed\n", path);
+        return -1;
+    }
+    
+    fbuf = (char*)malloc(flen);
+    if(!fbuf) {
+        LOG("malloc %d failed\n", flen);
+        return -1;
+    }
+    
+    r = file_load(path, fbuf, flen);
+    if(r) {
+        LOG("%s load failed\n", path);
+        return -1;
+    }
+
+    hfile = (upgrade_file_t*)fbuf;
+    if(hfile->magic!=UPG_FILE_MAGIC ||
+       hfile->dlen!=flen-sizeof(upgrade_file_t)-sizeof(md5_t)) {
+        r = -1;
+        LOG("magic: 0x%08x, should be: 0x%08x\n", hfile->magic, UPG_FILE_MAGIC);
+        LOG("num:  %d, should < %d\n", hfile->obj.num,  UPGRADE_NUM_MAX);
+        LOG("stra: %d, should < %d\n", hfile->obj.stra, UPGRADE_STRA_MAX);
+        
+        LOG("file hdr check failed\n");
+        goto fail;
+    }
+    
+    r = md5_check(hfile);
+    if(r) {
+        LOG("md5 check failed\n");
+        goto fail;
+    }
+    
+fail:
+    free(fbuf);
+    return r;
+}
+static int file_scan(upg_handle_t *h)
+{
+    //检查DOWN目录,如有升级文件
+    
+    //udisk检查,如有升级文件,拷贝到DOWN_FOLDER目录,并设置step为UPGRADE_STEP_DOWN
+
+    //tcard检查,如有升级文件,拷贝到DOWN_FOLDER目录,并设置step为UPGRADE_STEP_DOWN
+    
+    return 0;
+}
+static int file_clear(void)
+{
+    char tmp[200];
+
+    snprintf(tmp, sizeof(tmp), "rm -r %s/* %s/*", DOWN_FOLDER, UPG_FOLDER);
+    return system(tmp);
+}
+
+
+
+//////////////////////////////////////////////////
+static int app_start(void)
+{
+    return system("/etc/init.d/S90PDUApp start");
+}
+static int app_stop(void)
+{
+    return system("/etc/init.d/S90PDUApp stop");
+}
+static int app_restart(void)
+{
+    return system("/etc/init.d/S90PDUApp restart");
+}
+
+//////////////////////////////////////////////////
+static void* upg_thread(void *arg)
+{
+    int r=0;
+    int msgid;
+    upgrade_msg_t msg;
+    upg_handle_t *h=(upg_handle_t*)arg;
+
+    LOG("upg_thread running\n");
+    msgid = msgget(h->key, 0666| IPC_CREAT);
+    LOG("___ key: %d, msgid: %d\n", h->key, msgid);
+
+    while(1) {
+        r = msgrcv(msgid, &msg, sizeof(msg), 1, 0); 
+        if(r<=0) {
+            continue;
+        }
+        LOG("___ msg.evt: 0x%02x\n", msg.evt);
+        
+        switch(msg.evt) {
+            case UPGRADE_EVT_APP_RUNNING:
+            {
+                LOG("___ smartPDU running!\n");
+                h->step = UPGRADE_STEP_SUCCESS;
+            }
+            break;
+
+            case UPGRADE_EVT_UPLOAD_FINISH:
+            {
+                LOG("___ upgrade package upload finished!\n");
+                h->step = UPGRADE_STEP_DOWN;
+                file_touch(UPGRADE_STEP_DOWN);
+            }
+            break;
+
+        }
+    }
+
+    pthread_exit(NULL);
+}
+static int upg_init(upg_handle_t *h)
+{
+    int id,r;
+    char tmp[200];
+    key_t key;
+
+    folder_init();
+        
+    key = ftok(UPG_KEY_PATH, UPG_KEY_SN);
+    if(key<0) {
+        LOG("ftok %s failed, errno: %d\n", UPG_KEY_PATH, errno);
+    }
+	h->src  = UPGRADE_SRC_NONE;
+    h->stat = UPGRADE_STAT_NONE;
+    h->key  = key;
+
+    return pthread_create(&h->tid, NULL, upg_thread, h);
+}
+static int upg_check(upg_handle_t *h)
+{
+    int i,r;
+    char tmp[200];
+
+    for(i=1; i<UPGRADE_STEP_MAX; i++) {
+        snprintf(tmp, sizeof(tmp), "%s/s%d", UPG_FOLDER, i);
+        r = file_exist(tmp);
+        if(r) {
+            LOG("%s exist\n", tmp);
+            //重启后如果是覆盖完成,则将进度置为SUCCESS
+            h->step = i+1;
+            break;
+        }
+        LOG("%s not exist\n", tmp);
+    }
+
+    return r;
+}
+static int upg_handle(upg_handle_t *h)
+{
+    int r=-1;
+    char tmp[200];
+
+    LOG("___h->step: %d\n", h->step);
+    while(h->step!=UPGRADE_STEP_NONE) {
+        switch(h->step) {
+            case UPGRADE_STEP_DOWN:
+            {
+                LOG("___ UPGRADE_STEP_DOWN\n");
+
+                //先检查下载目录是否存在pdupkg文件
+                snprintf(tmp, sizeof(tmp), "%s/%s", DOWN_FOLDER, UPG_PKG_NAME);
+                if(file_exist(tmp)) {
+                    file_touch(UPGRADE_STEP_DOWN);
+                    h->step = UPGRADE_STEP_SPLIT;
+                }
+                else {
+                    LOG("___ %s not exist, ", tmp);
+
+                    //下载目录不存在pdupkg文件,则继续检查是否存在pdutar文件
+                    snprintf(tmp, sizeof(tmp), "%s/%s", DOWN_FOLDER, UPG_TAR_NAME);
+                    LOG("read %s\n", tmp);
+                    
+                    if(file_exist(tmp)) {
+                        file_touch(UPGRADE_STEP_DOWN);
+                        h->step = UPGRADE_STEP_COVER;
+                    }
+                    else {
+                        file_untouch(UPGRADE_STEP_DOWN);
+                        h->step = UPGRADE_STEP_NONE;
+                    }
+                }
+            }
+            break;
+
+            case UPGRADE_STEP_SPLIT:
+            {
+                LOG("___ UPGRADE_STEP_SPLIT\n");
+
+                snprintf(tmp, sizeof(tmp), "%s/%s", DOWN_FOLDER, UPG_PKG_NAME);
+                r = file_check(tmp);
+                if(r==0) {
+                    r = file_split();
+                    if(r==0) {
+                        file_touch(UPGRADE_STEP_SPLIT);
+                        h->step = UPGRADE_STEP_COVER;
+                    }
+                    else {
+                        file_untouch(UPGRADE_STEP_SPLIT);
+                        h->step = UPGRADE_STEP_NONE;
+                    }
+                }
+                else {
+                    file_remove(tmp);
+                    h->step = UPGRADE_STEP_NONE;
+                }
+                file_untouch(UPGRADE_STEP_DOWN);
+            }
+            break;
+
+            case UPGRADE_STEP_COVER:
+            {
+                LOG("___ UPGRADE_STEP_COVER\n");
+                app_stop();
+
+                snprintf(tmp, sizeof(tmp), "%s/%s", DOWN_FOLDER, UPG_TAR_NAME);
+                r = file_cover(tmp);
+                if(r==0) {
+                    file_touch(UPGRADE_STEP_COVER);
+                    h->step = UPGRADE_STEP_FINISH;
+                    app_start();
+                }
+                else {
+                    LOG("file_cover, delete %s!\n", tmp);
+                    file_remove(tmp);
+                    snprintf(tmp, sizeof(tmp), "%s/%s", DOWN_FOLDER, UPG_HDR_NAME);
+                    file_remove(tmp);
+
+                    h->step = UPGRADE_STEP_NONE;
+                    file_untouch(UPGRADE_STEP_COVER);
+                    
+                    file_restore();
+                    app_start();
+                }
+                file_untouch(UPGRADE_STEP_DOWN);
+                file_untouch(UPGRADE_STEP_SPLIT);
+            }
+            break;
+
+            case UPGRADE_STEP_FINISH:
+            {
+                LOG("___ UPGRADE_STEP_FINISH\n");
+                h->step = UPGRADE_STEP_NONE;
+            }
+            break;
+
+            case UPGRADE_STEP_SUCCESS:
+            {
+                LOG("___ UPGRADE_STEP_SUCCESS\n");
+
+                h->step = UPGRADE_STEP_NONE;
+                
+                file_backup();  //启动成功才证明程序有效,可进行备份, 备份成功,删除下载目录中的文件以节省空间
+                file_clear();
+                
+                app_start();
+                
+            }
+            break;
+
+            default:
+            LOG("___ wrong step: %d\n", h->step);
+            r = 1;
+            break;
+        }
+    }
+
+    return r;
+}
+/////////////////////////////////////////////////////////////////////////
+int main(void)
+{
+    int id,r=0;
+    upg_handle_t *h=&upgHandle;
+
+    LOG("___ upgd running ...\n");
+    
+    upg_init(h);
+    upg_check(h);
+    while(1) {
+        upg_handle(h);
+        sleep(1);
+    }
+    
+    return 0;
+}

+
+

+ 123 - 0
04-软件设计及源码/03-核心板/V1.0/05.src/smart_pdu/upgrade/upgrade.h

@@ -0,0 +1,123 @@
+#ifndef __UPGRADE_H__
+#define __UPGRADE_H__
+
+#include <stdint.h>
+
+#define UPG_KEY_PATH    "/tmp"
+#define UPG_KEY_SN      123
+
+#define RUN_FOLDER      "/root/run"
+#define BAK_FOLDER      "/root/bak"
+#define UPG_FOLDER      "/root/upg"                     //用于存放升级过程文件
+#define DOWN_FOLDER     "/root/dl"                      //网页下载到该目录,然后移到UPG_FOLDER目录
+
+#define UPG_PKG_NAME    "pdupkg"                        //所有文件需要打包成一个文件,包括文件头,校验码
+#define UPG_HDR_NAME    "pduhdr"                        //升级头文件
+#define UPG_TAR_NAME    "pdutar"                        //升级数据包
+
+#define UPG_LOG_PATH    UPG_FOLDER"/log.txt"
+
+#define UPG_PKT_MAGIC   0xdeadbeer
+#define UPG_FILE_MAGIC  0xfacebeef
+
+
+enum {  //升级状态state
+	UPGRADE_EVT_APP_RUNNING=0x12,
+	UPGRADE_EVT_UPG_RUNNING,
+	UPGRADE_EVT_UPLOAD_FINISH,
+	
+
+	UPGRADE_EVT_MAX,
+};
+
+enum {  //升级状态state
+	UPGRADE_STAT_NONE=0,
+	UPGRADE_STAT_GOING,
+	UPGRADE_STAT_FAILED,
+
+	UPGRADE_STAT_MAX,
+};
+
+enum {  //升级数据来源source
+	UPGRADE_SRC_NONE=0,
+	UPGRADE_SRC_TCP,
+	UPGRADE_SRC_HTTP,
+	UPGRADE_SRC_MQTT,
+	UPGRADE_SRC_UDISK,
+	UPGRADE_SRC_TCARD,
+	UPGRADE_SRC_RS485,
+
+	UPGRADE_SRC_MAX,
+};
+
+enum {  //升级对象object, 可以同时升级多个
+	UPGRADE_OBJ_PWR=(1<<0),
+	UPGRADE_OBJ_WEB=(1<<1),
+	UPGRADE_OBJ_APP=(1<<2),
+};
+
+enum {  //升级策略strategy
+	UPGRADE_STRA_OLD=0,						//升级版本或编译/修改时间较老的设备
+	UPGRADE_STRA_FORCE,						//强制升级
+
+	UPGRADE_STRA_MAX,
+};  
+
+enum {  //升级对象的数量number
+	UPGRADE_NUM_SINGLE=0,					//单个设备升级
+	UPGRADE_NUM_BAT,						//批量升级
+	UPGRADE_NUM_ALL,						//全部升级
+
+	UPGRADE_NUM_MAX,
+};  
+
+enum {  //升级进度step
+	UPGRADE_STEP_NONE=0,
+	UPGRADE_STEP_DOWN,
+	UPGRADE_STEP_SPLIT,
+    UPGRADE_STEP_COVER,
+    UPGRADE_STEP_FINISH,
+    UPGRADE_STEP_SUCCESS,
+
+	UPGRADE_STEP_MAX,
+};
+
+#pragma pack(1)
+
+typedef struct {    //升级目标数据结构
+    uint32_t        type;
+    uint32_t        evt;					//upgrade_evt
+    uint32_t        flag;					//reserved
+}upgrade_msg_t;
+
+typedef struct {    //升级目标数据结构
+    uint8_t			num;					//obj number
+    uint8_t			stra;					//obj strategy
+	char			obj1[64];				//obj1 addr or name
+	char			obj2[64];				//obj2 addr or name
+}upgrade_obj_t;
+
+typedef struct {
+    uint32_t        magic;					//UPG_PKT_MAGIC
+    uint8_t         addr;					//device modbus addr
+    uint16_t        dataLen;
+    uint8_t         data[0];
+}upgrade_pkt_t;
+
+typedef struct {
+    char			data[32];
+}md5_t;
+typedef struct {
+    uint32_t        magic;					//UPG_FILE_MAGIC
+    upgrade_obj_t   obj;
+    uint32_t        dlen;
+    uint8_t         data[0];
+    /*
+    uint8_t         data[x];
+    md5_t           md5;
+    */
+}upgrade_file_t;
+#pragma pack()
+
+
+#endif