From d50c190957600784698fe134975970c775c4a722 Mon Sep 17 00:00:00 2001 From: Steve Karg Date: Fri, 13 Dec 2019 15:19:10 -0600 Subject: [PATCH] Issue 2 move folders and use deep path include file names to prevent collisions (#4) * moving folders and files and adjust server demo build * Fix Makefile for apps/server on Linux * fix unit test source file folders * fix datetime convert UTC functions. Add Code::Blocks project for datetime testing * added some ignore extensions * disable parallel make option * fix build for abort, dcc, and epics apps * fix build for dcc, epics, error, and getevent apps. * Fixed building of all apps * fix the ipv4 to ipv6 router app build * Change indent style from Google to Webkit * make pretty to re-format style * removed common Makefile since we already had one and two was too many * remove scripts from root folder that are no longer maintained or used * remove mercurial EOL and ignore files for git repo * remove .vscodeconfig files from repo * tweak clang-format style * clang-format src and apps with tweaked style * added clang-tidy to fix readability if braces in src * result of make tidy for src and apps * fix clang-tidy mangling * Added code::blocks project for BACnet server simulation * added code::blocks linux project for WhoIs app * update text files for EOL * fix EOL in some files * fixed make win32 apps for older gcc * Removed Borland C++ Makefile in apps. Unable to maintain support for Borland C++ compiler. * created codeblocks project for apps/epics for Windows * fixing ports/xplained to work with new data structure. * fix ports/xplained example for Atmel Studio compile * fix ports/stm32f10x example for gcc Makefile compile * fix ports/stm32f10x example for IAR EWARM compile * fix ports/xplained timer callback * fix ports/bdk_atxx_mspt build with subdirs * fix ports/bdk_atxx_mspt build with subdirs * updated git ignore for IAR build artifacts * updated gitignore for non-tracked files and folders * fixed bdk-atxx4-mstp port for Rowley Crossworks project file * fixed bdk-atxx4-mstp port for GCC AVR Makefile * fixed atmega168 port for IAR AVR and GCC AVR Makefile * fixed at91sam7s port for IAR ARM and GCC ARM Makefile * removed unmaintainable DOS, RTOS32, and atmega8 ports. Updated rx62n (untested). * changed arm7 to uip port --- .clang-format | 12 +- .gitattributes | 10 + .gitignore | 11 + .hgeol | 2 - .hgignore | 40 - Makefile | 185 +- README.md | 3 +- apps/Makefile | 275 ++ apps/abort/Makefile | 50 + {demo => apps}/abort/main.c | 77 +- apps/dcc/Makefile | 50 + {demo => apps}/dcc/main.c | 107 +- apps/epics/Makefile | 50 + apps/epics/bacepics.cbp | 305 ++ {demo => apps}/epics/bacepics.h | 0 {demo => apps}/epics/main.c | 349 ++- apps/error/Makefile | 47 + {demo => apps}/error/main.c | 85 +- {demo => apps}/gateway/Makefile | 0 {demo => apps}/gateway/gateway.h | 0 {demo => apps}/gateway/main.c | 116 +- apps/getevent/Makefile | 50 + {demo => apps}/getevent/main.c | 121 +- apps/iam/Makefile | 47 + {demo => apps}/iam/main.c | 100 +- apps/iamrouter/Makefile | 47 + {demo => apps}/iamrouter/main.c | 80 +- apps/initrouter/Makefile | 47 + {demo => apps}/initrouter/main.c | 89 +- apps/mstpcap/Makefile | 70 + {demo => apps}/mstpcap/main.c | 299 +- {demo => apps}/mstpcap/mstpcap.txt | 0 apps/mstpcrc/Makefile | 51 + {demo => apps}/mstpcrc/build.bat | 0 {demo => apps}/mstpcrc/main.c | 34 +- {demo => apps}/mstpcrc/readme.txt | 0 {demo => apps}/perl/Documentation/index.html | 0 {demo => apps}/perl/Documentation/jquery.js | 0 {demo => apps}/perl/Documentation/syntax.css | 0 {demo => apps}/perl/Documentation/syntax.js | 0 {demo => apps}/perl/bacnet.pl | 0 {demo => apps}/perl/example_readprop.pl | 0 {demo => apps}/perl/perl_bindings.c | 213 +- {demo => apps}/perl/readme.txt | 0 {demo => apps}/piface/Makefile | 0 {demo => apps}/piface/configure.sh | 0 {demo => apps}/piface/device.c | 326 +-- {demo => apps}/piface/main.c | 111 +- {demo => apps}/piface/readme.txt | 0 {demo => apps}/ptransfer/Makefile | 0 {demo/handler => apps/ptransfer}/h_pt.c | 77 +- apps/ptransfer/h_pt.h | 52 + {demo/handler => apps/ptransfer}/h_pt_a.c | 52 +- apps/ptransfer/h_pt_a.h | 52 + {demo => apps}/ptransfer/main.c | 166 +- {demo => apps}/ptransfer/ptransfer.sln | 0 apps/ptransfer/s_ptransfer.c | 123 + apps/ptransfer/s_ptransfer.h | 51 + apps/readbdt/Makefile | 47 + {demo => apps}/readbdt/main.c | 55 +- apps/readfile/Makefile | 52 + {demo => apps}/readfile/main.c | 139 +- {demo => apps}/readfile/main.ide | Bin apps/readprop/Makefile | 50 + {demo => apps}/readprop/bacrp.cbp | 0 {demo => apps}/readprop/main.c | 240 +- apps/readpropm/Makefile | 56 + {demo => apps}/readpropm/bacrpm.cbp | 0 {demo => apps}/readpropm/main.c | 230 +- apps/readrange/Makefile | 50 + {demo => apps}/readrange/main.c | 186 +- .../readrange/readrange/readrange.sln | 0 .../readrange/readrange/readrange.vcproj | 2086 ++++++------- apps/reinit/Makefile | 53 + {demo => apps}/reinit/main.c | 126 +- apps/router-ipv6/Makefile | 78 + {demo => apps}/router-ipv6/main.c | 188 +- {demo => apps}/router-ipv6/readme.txt | 44 +- {demo => apps}/router/Makefile | 0 {demo => apps}/router/init.cfg | 0 {demo => apps}/router/ipmodule.c | 87 +- {demo => apps}/router/ipmodule.h | 2 +- {demo => apps}/router/main.c | 72 +- {demo => apps}/router/msgqueue.c | 5 +- {demo => apps}/router/msgqueue.h | 4 +- {demo => apps}/router/mstpmodule.c | 15 +- {demo => apps}/router/mstpmodule.h | 0 {demo => apps}/router/network_layer.c | 40 +- {demo => apps}/router/network_layer.h | 8 +- {demo => apps}/router/portthread.c | 6 +- {demo => apps}/router/portthread.h | 4 +- {demo => apps}/router/readme.txt | 0 apps/scov/Makefile | 51 + {demo => apps}/scov/main.c | 203 +- {demo => apps}/server/.gdbinit | 0 apps/server/Makefile | 71 + {demo => apps}/server/PICS.odt | Bin apps/server/bacserv-linux.cbp | 673 +++++ apps/server/bacserv-windows.cbp | 676 +++++ apps/server/bin/Debug/bacserv | Bin 0 -> 2160360 bytes {demo => apps}/server/epics_vts3.tpi | 0 {demo => apps}/server/main.c | 169 +- apps/timesync/Makefile | 54 + {demo => apps}/timesync/main.c | 127 +- apps/ucov/Makefile | 53 + {demo => apps}/ucov/main.c | 61 +- apps/uevent/Makefile | 54 + {demo => apps}/uevent/main.c | 117 +- apps/uptransfer/Makefile | 51 + {demo => apps}/uptransfer/main.c | 104 +- apps/whohas/Makefile | 54 + {demo => apps}/whohas/main.c | 97 +- apps/whois/Makefile | 51 + apps/whois/bacwi-linux.cbp | 468 +++ apps/whois/bacwi.layout | 10 + {demo => apps}/whois/main.c | 217 +- apps/whoisrouter/Makefile | 47 + {demo => apps}/whoisrouter/main.c | 118 +- apps/writefile/Makefile | 54 + {demo => apps}/writefile/main.c | 104 +- {demo => apps}/writefile/main.ide | Bin apps/writeprop/Makefile | 49 + {demo => apps}/writeprop/main.c | 127 +- apps/writepropm/Makefile | 55 + {demo => apps}/writepropm/main.c | 158 +- bin/bacroute.sh | 38 +- borland.bat | 7 - build.sh | 23 - comment.sh | 25 - demo/BACnetDemo.workspace | 11 - demo/Makefile | 116 - demo/abort/Makefile | 39 - demo/dcc/Makefile | 40 - demo/dcc/makefile.b32 | 140 - demo/dcc/makefile.g++ | 506 ---- demo/dcc/tmake.pro | 59 - demo/epics/Makefile | 39 - demo/epics/bacepics.cbp | 60 - demo/epics/makefile.b32 | 139 - demo/error/Makefile | 39 - demo/gateway/makefile.b32 | 148 - demo/getevent/Makefile | 45 - demo/handler/s_ptransfer.c | 146 - demo/handler/txbuf.c | 32 - demo/iam/Makefile | 39 - demo/iam/makefile.b32 | 140 - demo/iamrouter/Makefile | 39 - demo/iamrouter/makefile.b32 | 140 - demo/initrouter/Makefile | 39 - demo/initrouter/makefile.b32 | 140 - demo/mstpcap/Makefile | 48 - demo/mstpcap/makefile.b32 | 139 - demo/mstpcrc/Makefile | 53 - demo/mstpcrc/makefile.b32 | 139 - demo/ptransfer/makefile.b32 | 139 - demo/ptransfer/rdproperty.vcproj | 975 ------- demo/readbdt/Makefile | 39 - demo/readbdt/makefile.b32 | 140 - demo/readfile/Makefile | 39 - demo/readfile/makefile.b32 | 139 - demo/readprop/Makefile | 45 - demo/readprop/makefile.b32 | 139 - demo/readpropm/Makefile | 40 - demo/readpropm/makefile.b32 | 139 - demo/readrange/Makefile | 45 - demo/reinit/Makefile | 40 - demo/reinit/makefile.b32 | 139 - demo/router-ipv6/Makefile | 59 - demo/scov/Makefile | 45 - demo/scov/makefile.b32 | 143 - demo/server/Makefile | 73 - demo/server/bacserv.cbp | 134 - demo/server/makefile.b32 | 148 - demo/server/server.h | 48 - demo/timesync/Makefile | 40 - demo/timesync/makefile.b32 | 139 - demo/ucov/Makefile | 40 - demo/ucov/makefile.b32 | 139 - demo/uevent/Makefile | 40 - demo/uptransfer/Makefile | 45 - demo/uptransfer/makefile.b32 | 143 - demo/whohas/Makefile | 40 - demo/whohas/makefile.b32 | 139 - demo/whois/Makefile | 39 - demo/whois/bacwi.dsp | 492 ---- demo/whois/makefile.b32 | 139 - demo/whoisrouter/Makefile | 39 - demo/whoisrouter/makefile.b32 | 140 - demo/writefile/Makefile | 40 - demo/writefile/makefile.b32 | 139 - demo/writeprop/Makefile | 40 - demo/writeprop/makefile.b32 | 143 - demo/writepropm/Makefile | 40 - doc/README.ubuntu | 32 +- doc/README.utils | 96 +- doc/indent/README.md | 16 +- export.sh | 19 - include/bacnet.h | 109 - include/client.h | 307 -- include/handlers.h | 368 --- include/mydata.h | 21 - lib/Makefile | 225 -- lib/bacnet.cbp | 436 --- lib/bacnetdll.cbp | 267 -- lib/main.cpp | 33 - lib/main.h | 26 - lib/makefile.b32 | 235 -- makefile.b32 | 341 --- ports/arduino_uno/apdu.c | 12 +- ports/arduino_uno/av.c | 14 +- ports/arduino_uno/av.h | 6 +- ports/arduino_uno/bip-init.c | 6 +- ports/arduino_uno/bip.c | 6 +- ports/arduino_uno/bip.h | 4 +- ports/arduino_uno/bv.c | 12 +- ports/arduino_uno/bv.h | 6 +- ports/arduino_uno/bvlc-arduino.c | 4 +- ports/arduino_uno/bvlc-arduino.h | 6 +- ports/arduino_uno/datalink.h | 14 +- ports/arduino_uno/device.c | 24 +- ports/arduino_uno/device.h | 8 +- ports/arduino_uno/h_rp.c | 22 +- ports/arduino_uno/h_whois.c | 18 +- ports/arduino_uno/h_wp.c | 22 +- ports/arduino_uno/main.c | 14 +- ports/arduino_uno/txbuf.h | 4 +- ports/at91sam7s/.gdbinit | 32 +- ports/at91sam7s/Makefile | 36 +- ports/at91sam7s/ai.c | 12 +- ports/at91sam7s/at91sam7s256.ld | 312 +- ports/at91sam7s/av.c | 14 +- ports/at91sam7s/bacnet.ewp | 1146 +------- ports/at91sam7s/bi.c | 12 +- ports/at91sam7s/bv.c | 12 +- ports/at91sam7s/crt.s | 638 ++-- ports/at91sam7s/device.c | 35 +- ports/at91sam7s/dlmstp.c | 18 +- ports/at91sam7s/isr.c | 1 + ports/at91sam7s/main.c | 22 +- ports/at91sam7s/rs485.c | 2 +- ports/at91sam7s/timer.c | 2 +- ports/atmega168/.splintrc | 26 +- ports/atmega168/Makefile | 42 +- ports/atmega168/ai.c | 8 +- ports/atmega168/ai.h | 6 +- ports/atmega168/apdu.c | 12 +- ports/atmega168/av.c | 81 +- ports/atmega168/av.h | 6 +- ports/atmega168/bacnet.aps | 2 +- ports/atmega168/bacnet.ewp | 213 +- ports/atmega168/bv.c | 85 +- ports/atmega168/bv.h | 6 +- ports/atmega168/device.c | 145 +- ports/atmega168/device.h | 8 +- ports/atmega168/dlmstp.c | 20 +- ports/atmega168/h_rp.c | 68 +- ports/atmega168/h_whois.c | 18 +- ports/atmega168/h_wp.c | 51 +- ports/atmega168/hardware.h | 2 +- ports/atmega168/main.c | 14 +- ports/atmega168/rs485.c | 2 +- ports/atmega8/Makefile | 180 -- ports/atmega8/apdu.c | 123 - ports/atmega8/avr035.h | 18 - ports/atmega8/bacnet.ewp | 2108 -------------- ports/atmega8/bacnet.eww | 10 - ports/atmega8/device.c | 343 --- ports/atmega8/dlmstp.c | 607 ---- ports/atmega8/hardware.h | 65 - ports/atmega8/hardware.ods | Bin 19823 -> 0 bytes ports/atmega8/iar2gcc.h | 345 --- ports/atmega8/main.c | 116 - ports/atmega8/readme.txt | 45 - ports/atmega8/rs485.c | 302 -- ports/atmega8/rs485.h | 70 - ports/atmega8/stdbool.h | 28 - ports/atmega8/stdint.h | 15 - ports/atmega8/timer.c | 110 - ports/bdk-atxx4-mstp/Makefile | 54 +- ports/bdk-atxx4-mstp/ai.c | 12 +- ports/bdk-atxx4-mstp/av.c | 16 +- ports/bdk-atxx4-mstp/avrosp/AVRBootloader.cpp | 1952 ++++++------- ports/bdk-atxx4-mstp/avrosp/AVRBootloader.hpp | 168 +- ports/bdk-atxx4-mstp/avrosp/AVRDevice.cpp | 314 +- ports/bdk-atxx4-mstp/avrosp/AVRDevice.hpp | 138 +- .../bdk-atxx4-mstp/avrosp/AVRInSystemProg.cpp | 1428 ++++----- .../bdk-atxx4-mstp/avrosp/AVRInSystemProg.hpp | 156 +- ports/bdk-atxx4-mstp/avrosp/AVROSP.dev | 338 +-- ports/bdk-atxx4-mstp/avrosp/AVRProgrammer.cpp | 140 +- ports/bdk-atxx4-mstp/avrosp/AVRProgrammer.hpp | 168 +- ports/bdk-atxx4-mstp/avrosp/CommChannel.cpp | 76 +- ports/bdk-atxx4-mstp/avrosp/CommChannel.hpp | 122 +- ports/bdk-atxx4-mstp/avrosp/ErrorMsg.cpp | 92 +- ports/bdk-atxx4-mstp/avrosp/ErrorMsg.hpp | 98 +- ports/bdk-atxx4-mstp/avrosp/HEXParser.cpp | 728 ++--- ports/bdk-atxx4-mstp/avrosp/HEXParser.hpp | 134 +- ports/bdk-atxx4-mstp/avrosp/JobInfo.cpp | 2592 ++++++++--------- ports/bdk-atxx4-mstp/avrosp/JobInfo.hpp | 210 +- ports/bdk-atxx4-mstp/avrosp/SerialPort.cpp | 406 +-- ports/bdk-atxx4-mstp/avrosp/SerialPort.hpp | 150 +- ports/bdk-atxx4-mstp/avrosp/Utility.cpp | 362 +-- ports/bdk-atxx4-mstp/avrosp/Utility.hpp | 140 +- ports/bdk-atxx4-mstp/avrosp/XMLParser.cpp | 1274 ++++---- ports/bdk-atxx4-mstp/avrosp/XMLParser.hpp | 130 +- ports/bdk-atxx4-mstp/avrosp/main.cpp | 94 +- ports/bdk-atxx4-mstp/bacnet.aps | 2 +- ports/bdk-atxx4-mstp/bacnet.atsln | 40 +- ports/bdk-atxx4-mstp/bacnet.c | 34 +- ports/bdk-atxx4-mstp/bacnet.cproj | 751 ++--- ports/bdk-atxx4-mstp/bacnet.ewp | 276 +- ports/bdk-atxx4-mstp/bacnet.hzp | 80 +- ports/bdk-atxx4-mstp/bi.c | 12 +- ports/bdk-atxx4-mstp/bname.c | 8 +- ports/bdk-atxx4-mstp/bname.h | 2 +- ports/bdk-atxx4-mstp/bo.c | 14 +- .../bdk-atxx4-mstp/bootloader/bootloader.aps | 2 +- ports/bdk-atxx4-mstp/device.c | 31 +- ports/bdk-atxx4-mstp/dlmstp.c | 20 +- ports/bdk-atxx4-mstp/epics_vts3.tpi | 708 ++--- ports/bdk-atxx4-mstp/hardware.h | 2 +- ports/bdk-atxx4-mstp/input.c | 10 +- ports/bdk-atxx4-mstp/led.c | 16 +- ports/bdk-atxx4-mstp/main.c | 8 +- .../{timer2.c => mstimer-init.c} | 21 +- ports/bdk-atxx4-mstp/rs485.c | 14 +- ports/bdk-atxx4-mstp/serial.c | 2 +- ports/bdk-atxx4-mstp/test.c | 18 +- ports/bdk-atxx4-mstp/timer.c | 431 --- ports/bdk-atxx4-mstp/timer.h | 115 - ports/bsd/{net.h => bacport.h} | 0 ports/bsd/bip-init.c | 6 +- ports/bsd/datetime-init.c | 91 + ports/bsd/main.c | 32 +- ports/bsd/mstimer-init.c | 94 + ports/bsd/readme.txt | 1 - ports/bsd/timer.c | 156 - ports/dos/bacnet.prj | Bin 4610 -> 0 bytes ports/dos/dlmstp.c | 1328 --------- ports/dos/extkword.h | 131 - ports/dos/main.c | 112 - ports/dos/mk_fp.h | 23 - ports/dos/pchwio.c | 83 - ports/dos/pchwio.h | 78 - ports/dos/queue.c | 68 - ports/dos/queue.h | 45 - ports/dos/readme.txt | 5 - ports/dos/rs485.c | 241 -- ports/dos/serial.c | 382 --- ports/dos/serial.h | 124 - ports/dos/stdbool.h | 20 - ports/dos/stdint.h | 31 - ports/dos/timer.c | 201 -- ports/esp32/lib/readme.txt | 72 +- ports/esp32/readme.txt | 132 +- ports/esp32/src/ai.c | 20 +- ports/esp32/src/ai.h | 14 +- ports/esp32/src/bip_init.c | 2 +- ports/esp32/src/bo.c | 18 +- ports/esp32/src/bo.h | 8 +- ports/esp32/src/device.c | 40 +- ports/esp32/src/device.h | 14 +- ports/esp32/src/main.c | 22 +- ports/linux/arcnet.c | 8 +- ports/linux/bacnet_ipv6.lua | 562 ++-- ports/linux/{net.h => bacport.h} | 0 ports/linux/bip-init.c | 6 +- ports/linux/bip6.c | 15 +- ports/linux/datetime-init.c | 91 + ports/linux/dlmstp.c | 18 +- ports/linux/dlmstp_linux.c | 16 +- ports/linux/dlmstp_linux.h | 12 +- ports/linux/ethernet.c | 8 +- ports/{win32/timer.h => linux/mstimer-init.c} | 102 +- ports/linux/mstpsnap.c | 14 +- ports/linux/rs485.c | 4 +- ports/linux/rs485.h | 2 +- ports/linux/rx_fsm.c | 6 +- ports/linux/timer.c | 140 - ports/lwip/bip.c | 14 +- ports/pic18f6720/18F6720.lkr | 82 +- .../nbproject/Makefile-genesis.properties | 16 +- .../nbproject/configurations.xml | 348 +-- .../BACnet-Server.X/nbproject/project.xml | 32 +- ports/pic18f6720/BACnet-Server.mcp | 564 ++-- ports/pic18f6720/ai.c | 14 +- ports/pic18f6720/apdu.c | 14 +- ports/pic18f6720/av.c | 16 +- ports/pic18f6720/bi.c | 14 +- ports/pic18f6720/bv.c | 14 +- ports/pic18f6720/device.c | 32 +- ports/pic18f6720/dlmstp.c | 10 +- ports/pic18f6720/dlmstp.h | 4 +- ports/pic18f6720/isr.c | 2 +- ports/pic18f6720/main.c | 12 +- ports/pic18f6720/mstp.c | 10 +- ports/pic18f6720/mstp.h | 6 +- ports/pic18f6720/rs485.c | 4 +- ports/pic18f6720/rs485.h | 2 +- .../nbproject/Makefile-genesis.properties | 16 +- .../nbproject/configurations.xml | 396 +-- .../nbproject/private/configurations.xml | 50 +- .../nbproject/private/private.xml | 22 +- .../BACnet-Server.X/nbproject/project.xml | 32 +- ports/pic18f97j60/ai.c | 14 +- ports/pic18f97j60/apdu.c | 14 +- ports/pic18f97j60/av.c | 16 +- ports/pic18f97j60/bi.c | 14 +- ports/pic18f97j60/bv.c | 14 +- ports/pic18f97j60/device.c | 32 +- ports/pic18f97j60/dlmstp.c | 10 +- ports/pic18f97j60/dlmstp.h | 4 +- ports/pic18f97j60/isr.c | 2 +- ports/pic18f97j60/main.c | 12 +- ports/pic18f97j60/mstp.c | 10 +- ports/pic18f97j60/mstp.h | 6 +- ports/pic18f97j60/rs485.c | 4 +- ports/pic18f97j60/rs485.h | 2 +- ports/rtos32/bip-init.c | 275 -- ports/rtos32/dlmstp.c | 280 -- ports/rtos32/ethernet.c | 345 --- ports/rtos32/hardware.cfg | 24 - ports/rtos32/init.c | 128 - ports/rtos32/main.c | 168 -- ports/rtos32/makefile.mak | 199 -- ports/rtos32/monitor.cfg | 47 - ports/rtos32/mstp.c | 1278 -------- ports/rtos32/mstp.h | 193 -- ports/rtos32/net.h | 80 - ports/rtos32/netcfg.h | 104 - ports/rtos32/rs485.c | 228 -- ports/rtos32/rs485.h | 60 - ports/rtos32/setvars.bat | 3 - ports/rtos32/software.cfg | 61 - ports/rtos32/stdbool.h | 28 - ports/rtos32/stdint.h | 19 - ports/rx62n/BACnet_Ethernet_RX62N.hwp | 310 -- ports/rx62n/bacnet.c | 28 +- ports/rx62n/bo.c | 14 +- ports/rx62n/device.c | 37 +- ports/rx62n/ethernet.c | 6 +- ports/rx62n/led.c | 20 +- ports/rx62n/main.c | 4 +- ports/rx62n/{timer-hdw.c => mstimer-init.c} | 19 +- ports/rx62n/readme.txt | 5 +- ports/rx62n/timer.c | 431 --- ports/rx62n/timer.h | 115 - ports/stm32f10x/CMSIS/CMSIS debug support.htm | 484 +-- ports/stm32f10x/Makefile | 47 +- ports/stm32f10x/automac.c | 10 +- ports/stm32f10x/bacnet.c | 28 +- ports/stm32f10x/bacnet.ewp | 134 +- ports/stm32f10x/bo.c | 14 +- ports/stm32f10x/device.c | 23 +- ports/stm32f10x/dlmstp.c | 20 +- ..._Notes_for_STM32F10x_StdPeriph_Driver.html | 588 ++-- ports/stm32f10x/led.c | 30 +- ports/stm32f10x/main.c | 20 +- .../stm32f10x/{timer_sys.c => mstimer-init.c} | 110 +- ports/stm32f10x/rs485.c | 22 +- ports/stm32f10x/timer.c | 431 --- ports/stm32f10x/timer.h | 115 - ports/{arm7 => uip}/_stdint.h | 0 ports/{arm7 => uip}/bip.c | 6 +- ports/{arm7 => uip}/net.h | 0 ports/{arm7 => uip}/stdbool.h | 0 ports/win32/{net.h => bacport.h} | 36 +- ports/win32/bip-init.c | 8 +- ports/win32/bip6.c | 13 +- ports/win32/datetime-init.c | 183 ++ ports/win32/dlmstp-mm.c | 12 +- ports/win32/dlmstp.c | 35 +- ports/win32/ethernet.c | 6 +- ports/win32/main.c | 50 +- ports/win32/mstimer-init.c | 89 + ports/win32/rs485.c | 8 +- ports/win32/rs485.h | 4 +- ports/win32/rx_fsm.c | 6 +- ports/win32/timer.c | 281 -- ports/xplained/ai.c | 12 +- ports/xplained/bacnet.c | 56 +- ports/xplained/bacnet.cproj | 997 ++++--- ports/xplained/bname.c | 8 +- ports/xplained/bname.h | 2 +- ports/xplained/device.c | 22 +- ports/xplained/dlmstp.c | 20 +- ports/xplained/led.c | 2 +- ports/xplained/main.c | 10 +- ports/xplained/{timer1.c => mstimer-init.c} | 119 +- ports/xplained/nvmdata.c | 4 +- ports/xplained/rs485.c | 20 +- ports/xplained/timer.c | 338 --- ports/xplained/timer.h | 96 - rebuild.sh | 21 - release.sh | 115 - splint.sh | 27 - src/Makefile | 50 + src/{ => bacnet}/abort.c | 66 +- {include => src/bacnet}/abort.h | 1 + src/{ => bacnet}/access_rule.c | 82 +- {include => src/bacnet}/access_rule.h | 6 +- src/{ => bacnet}/alarm_ack.c | 132 +- {include => src/bacnet}/alarm_ack.h | 6 +- ports/dos/rs485.h => src/bacnet/apdu.h | 55 +- src/{ => bacnet}/arf.c | 232 +- {include => src/bacnet}/arf.h | 4 +- src/{ => bacnet}/assigned_access_rights.c | 48 +- .../bacnet}/assigned_access_rights.h | 6 +- src/{ => bacnet}/authentication_factor.c | 57 +- .../bacnet}/authentication_factor.h | 4 +- .../authentication_factor_format.c | 53 +- .../bacnet}/authentication_factor_format.h | 2 +- src/{ => bacnet}/awf.c | 187 +- {include => src/bacnet}/awf.h | 2 +- src/{ => bacnet}/bacaddr.c | 36 +- {include => src/bacnet}/bacaddr.h | 2 +- src/{ => bacnet}/bacapp.c | 532 ++-- {include => src/bacnet}/bacapp.h | 12 +- src/{ => bacnet}/bacdcode.c | 373 +-- {include => src/bacnet}/bacdcode.h | 12 +- {include => src/bacnet}/bacdef.h | 4 +- src/{ => bacnet}/bacdevobjpropref.c | 108 +- {include => src/bacnet}/bacdevobjpropref.h | 4 +- {include => src/bacnet}/bacenum.h | 0 src/{ => bacnet}/bacerror.c | 114 +- {include => src/bacnet}/bacerror.h | 2 +- src/{ => bacnet}/bacint.c | 33 +- {include => src/bacnet}/bacint.h | 0 src/{ => bacnet}/bacprop.c | 45 +- {include => src/bacnet}/bacprop.h | 2 +- src/{ => bacnet}/bacpropstates.c | 128 +- {include => src/bacnet}/bacpropstates.h | 6 +- src/{ => bacnet}/bacreal.c | 22 +- {include => src/bacnet}/bacreal.h | 0 src/{ => bacnet}/bacstr.c | 178 +- {include => src/bacnet}/bacstr.h | 4 +- src/bacnet/bactext.c | 1413 +++++++++ {include => src/bacnet}/bactext.h | 2 +- src/{ => bacnet}/bactimevalue.c | 37 +- {include => src/bacnet}/bactimevalue.h | 6 +- .../bacnet/basic/bbmd6}/h_bbmd6.c | 198 +- .../bacnet/basic/bbmd6/h_bbmd6.h | 59 +- src/{ => bacnet/basic/bbmd6}/vmac.c | 8 +- {include => src/bacnet/basic/bbmd6}/vmac.h | 0 src/{ => bacnet/basic/binding}/address.c | 266 +- .../bacnet/basic/binding}/address.h | 4 +- .../bacnet/basic/npdu}/h_npdu.c | 33 +- src/bacnet/basic/npdu/h_npdu.h | 70 + .../bacnet/basic/npdu}/h_routed_npdu.c | 81 +- .../bacnet/basic/npdu/h_routed_npdu.h | 34 +- .../bacnet/basic/npdu}/s_router.c | 112 +- src/bacnet/basic/npdu/s_router.h | 73 + {demo => src/bacnet/basic}/object/Makefile | 0 .../bacnet/basic}/object/access_credential.c | 115 +- .../bacnet/basic}/object/access_credential.h | 18 +- .../basic}/object/access_credential.mak | 26 +- .../bacnet/basic}/object/access_door.c | 159 +- .../bacnet/basic}/object/access_door.h | 8 +- .../bacnet/basic}/object/access_door.mak | 20 +- .../bacnet/basic}/object/access_point.c | 95 +- .../bacnet/basic}/object/access_point.h | 12 +- .../bacnet/basic}/object/access_point.mak | 22 +- .../bacnet/basic}/object/access_rights.c | 98 +- .../bacnet/basic}/object/access_rights.h | 12 +- .../bacnet/basic}/object/access_rights.mak | 22 +- .../bacnet/basic}/object/access_user.c | 65 +- .../bacnet/basic}/object/access_user.h | 10 +- .../bacnet/basic}/object/access_user.mak | 20 +- .../bacnet/basic}/object/access_zone.c | 77 +- .../bacnet/basic}/object/access_zone.h | 10 +- .../bacnet/basic}/object/access_zone.mak | 20 +- {demo => src/bacnet/basic}/object/ai.c | 323 +- {demo => src/bacnet/basic}/object/ai.h | 14 +- {demo => src/bacnet/basic}/object/ai.mak | 20 +- {demo => src/bacnet/basic}/object/ao.c | 128 +- {demo => src/bacnet/basic}/object/ao.h | 8 +- {demo => src/bacnet/basic}/object/ao.mak | 20 +- {demo => src/bacnet/basic}/object/av.c | 323 +- {demo => src/bacnet/basic}/object/av.h | 16 +- {demo => src/bacnet/basic}/object/av.mak | 20 +- {demo => src/bacnet/basic}/object/bacfile.c | 170 +- {demo => src/bacnet/basic}/object/bacfile.h | 14 +- {demo => src/bacnet/basic}/object/bi.c | 101 +- {demo => src/bacnet/basic}/object/bi.h | 8 +- {demo => src/bacnet/basic}/object/bi.mak | 20 +- {demo => src/bacnet/basic}/object/bo.c | 110 +- {demo => src/bacnet/basic}/object/bo.h | 8 +- {demo => src/bacnet/basic}/object/bo.mak | 20 +- {demo => src/bacnet/basic}/object/bv.c | 107 +- {demo => src/bacnet/basic}/object/bv.h | 8 +- {demo => src/bacnet/basic}/object/bv.mak | 20 +- {demo => src/bacnet/basic}/object/channel.c | 248 +- {demo => src/bacnet/basic}/object/channel.h | 8 +- .../basic/object/client}/device-client.c | 231 +- {demo => src/bacnet/basic}/object/command.c | 258 +- {demo => src/bacnet/basic}/object/command.h | 6 +- {demo => src/bacnet/basic}/object/command.mak | 20 +- .../basic}/object/credential_data_input.c | 99 +- .../basic}/object/credential_data_input.h | 18 +- .../basic}/object/credential_data_input.mak | 26 +- {demo => src/bacnet/basic}/object/csv.c | 118 +- {demo => src/bacnet/basic}/object/csv.h | 8 +- {demo => src/bacnet/basic}/object/csv.mak | 20 +- {demo => src/bacnet/basic}/object/device.c | 707 ++--- {demo => src/bacnet/basic}/object/device.h | 14 +- {demo => src/bacnet/basic}/object/device.mak | 32 +- .../bacnet/basic/object/gateway}/gw_device.c | 192 +- {demo => src/bacnet/basic}/object/iv.c | 77 +- {demo => src/bacnet/basic}/object/iv.h | 8 +- {demo => src/bacnet/basic}/object/lc.c | 341 ++- {demo => src/bacnet/basic}/object/lc.h | 8 +- {demo => src/bacnet/basic}/object/lc.ide | Bin {demo => src/bacnet/basic}/object/lc.mak | 20 +- {demo => src/bacnet/basic}/object/lo.c | 200 +- {demo => src/bacnet/basic}/object/lo.h | 8 +- {demo => src/bacnet/basic}/object/lo.mak | 20 +- {demo => src/bacnet/basic}/object/lsp.c | 82 +- {demo => src/bacnet/basic}/object/lsp.h | 8 +- {demo => src/bacnet/basic}/object/lsp.mak | 20 +- {demo => src/bacnet/basic}/object/ms-input.c | 174 +- {demo => src/bacnet/basic}/object/ms-input.h | 8 +- .../bacnet/basic}/object/ms-input.mak | 20 +- {demo => src/bacnet/basic}/object/mso.c | 128 +- {demo => src/bacnet/basic}/object/mso.h | 8 +- {demo => src/bacnet/basic}/object/mso.mak | 20 +- {demo => src/bacnet/basic}/object/msv.c | 144 +- {demo => src/bacnet/basic}/object/msv.h | 8 +- {demo => src/bacnet/basic}/object/msv.mak | 20 +- {demo => src/bacnet/basic}/object/nc.c | 168 +- {demo => src/bacnet/basic}/object/nc.h | 2 +- {demo => src/bacnet/basic}/object/netport.c | 361 ++- {demo => src/bacnet/basic}/object/netport.h | 24 +- {demo => src/bacnet/basic}/object/netport.mak | 22 +- .../bacnet/basic/object}/objects.c | 21 +- .../bacnet/basic/object}/objects.h | 6 +- {demo => src/bacnet/basic}/object/osv.c | 96 +- {demo => src/bacnet/basic}/object/osv.h | 8 +- {demo => src/bacnet/basic}/object/osv.mak | 22 +- {demo => src/bacnet/basic}/object/piv.c | 103 +- {demo => src/bacnet/basic}/object/piv.h | 8 +- {demo => src/bacnet/basic}/object/piv.mak | 20 +- {demo => src/bacnet/basic}/object/schedule.c | 114 +- {demo => src/bacnet/basic}/object/schedule.h | 16 +- .../bacnet/basic}/object/schedule.mak | 22 +- {demo => src/bacnet/basic}/object/trendlog.c | 508 ++-- {demo => src/bacnet/basic}/object/trendlog.h | 8 +- .../bacnet/basic/service}/h_alarm_ack.c | 105 +- src/bacnet/basic/service/h_alarm_ack.h | 55 + src/{apdu.c => bacnet/basic/service/h_apdu.c} | 172 +- .../bacnet/basic/service/h_apdu.h | 38 +- .../bacnet/basic/service}/h_arf.c | 73 +- src/bacnet/basic/service/h_arf.h | 50 + .../bacnet/basic/service}/h_arf_a.c | 33 +- src/bacnet/basic/service/h_arf_a.h | 50 + .../bacnet/basic/service}/h_awf.c | 69 +- src/bacnet/basic/service/h_awf.h | 50 + .../bacnet/basic/service}/h_ccov.c | 60 +- src/bacnet/basic/service/h_ccov.h | 52 + .../bacnet/basic/service}/h_cov.c | 149 +- src/bacnet/basic/service/h_cov.h | 63 + .../bacnet/basic/service}/h_dcc.c | 95 +- src/bacnet/basic/service/h_dcc.h | 55 + .../bacnet/basic/service}/h_gas_a.c | 29 +- src/bacnet/basic/service/h_gas_a.h | 52 + .../bacnet/basic/service}/h_get_alarm_sum.c | 64 +- src/bacnet/basic/service/h_get_alarm_sum.h | 57 + .../bacnet/basic/service}/h_getevent.c | 99 +- src/bacnet/basic/service/h_getevent.h | 61 + .../bacnet/basic/service}/h_getevent_a.c | 28 +- src/bacnet/basic/service/h_getevent_a.h | 52 + .../bacnet/basic/service}/h_iam.c | 34 +- src/bacnet/basic/service/h_iam.h | 56 + .../bacnet/basic/service}/h_ihave.c | 26 +- .../bacnet/basic/service/h_ihave.h | 34 +- .../bacnet/basic/service}/h_lso.c | 65 +- src/bacnet/basic/service/h_lso.h | 52 + .../bacnet/basic/service/h_noserv.c | 36 +- src/bacnet/basic/service/h_noserv.h | 52 + .../bacnet/basic/service}/h_rd.c | 79 +- src/bacnet/basic/service/h_rd.h | 52 + .../bacnet/basic/service}/h_rp.c | 63 +- src/bacnet/basic/service/h_rp.h | 52 + .../bacnet/basic/service}/h_rp_a.c | 38 +- src/bacnet/basic/service/h_rp_a.h | 55 + .../bacnet/basic/service}/h_rpm.c | 114 +- src/bacnet/basic/service/h_rpm.h | 52 + .../bacnet/basic/service}/h_rpm_a.c | 78 +- src/bacnet/basic/service/h_rpm_a.h | 59 + .../bacnet/basic/service}/h_rr.c | 74 +- src/bacnet/basic/service/h_rr.h | 52 + .../bacnet/basic/service}/h_rr_a.c | 37 +- src/bacnet/basic/service/h_rr_a.h | 52 + .../bacnet/basic/service}/h_ts.c | 54 +- src/bacnet/basic/service/h_ts.h | 75 + .../bacnet/basic/service}/h_ucov.c | 37 +- .../bacnet/basic/service/h_ucov.h | 34 +- .../bacnet/basic/service}/h_upt.c | 33 +- src/bacnet/basic/service/h_upt.h | 54 + .../bacnet/basic/service}/h_whohas.c | 52 +- src/bacnet/basic/service/h_whohas.h | 56 + .../bacnet/basic/service}/h_whois.c | 59 +- src/bacnet/basic/service/h_whois.h | 66 + .../bacnet/basic/service}/h_wp.c | 87 +- src/bacnet/basic/service/h_wp.h | 66 + .../bacnet/basic/service}/h_wpm.c | 99 +- src/bacnet/basic/service/h_wpm.h | 53 + .../bacnet/basic/service}/s_abort.c | 51 +- src/bacnet/basic/service/s_abort.h | 64 + .../bacnet/basic/service}/s_ack_alarm.c | 58 +- src/bacnet/basic/service/s_ack_alarm.h | 51 + .../bacnet/basic/service}/s_arfs.c | 59 +- src/bacnet/basic/service/s_arfs.h | 51 + .../bacnet/basic/service}/s_awfs.c | 65 +- src/bacnet/basic/service/s_awfs.h | 52 + .../bacnet/basic/service}/s_cevent.c | 46 +- src/bacnet/basic/service/s_cevent.h | 51 + .../bacnet/basic/service}/s_cov.c | 67 +- src/bacnet/basic/service/s_cov.h | 63 + .../bacnet/basic/service}/s_dcc.c | 57 +- src/bacnet/basic/service/s_dcc.h | 51 + .../bacnet/basic/service}/s_error.c | 56 +- src/bacnet/basic/service/s_error.h | 65 + .../bacnet/basic/service}/s_get_alarm_sum.c | 49 +- src/bacnet/basic/service/s_get_alarm_sum.h | 50 + .../bacnet/basic/service}/s_get_event.c | 54 +- src/bacnet/basic/service/s_get_event.h | 53 + .../bacnet/basic/service}/s_getevent.c | 54 +- src/bacnet/basic/service/s_getevent.h | 51 + .../bacnet/basic/service}/s_iam.c | 67 +- src/bacnet/basic/service/s_iam.h | 58 + .../bacnet/basic/service}/s_ihave.c | 44 +- src/bacnet/basic/service/s_ihave.h | 53 + .../bacnet/basic/service}/s_lso.c | 54 +- src/bacnet/basic/service/s_lso.h | 51 + .../bacnet/basic/service}/s_rd.c | 57 +- src/bacnet/basic/service/s_rd.h | 51 + .../bacnet/basic/service}/s_readrange.c | 56 +- src/bacnet/basic/service/s_readrange.h | 51 + .../bacnet/basic/service}/s_rp.c | 69 +- src/bacnet/basic/service/s_rp.h | 61 + .../bacnet/basic/service}/s_rpm.c | 52 +- src/bacnet/basic/service/s_rpm.h | 54 + .../bacnet/basic/service}/s_ts.c | 71 +- src/bacnet/basic/service/s_ts.h | 64 + .../bacnet/basic/service}/s_uevent.c | 12 +- src/bacnet/basic/service/s_uevent.h | 52 + .../bacnet/basic/service}/s_upt.c | 46 +- src/bacnet/basic/service/s_upt.h | 51 + .../bacnet/basic/service}/s_whohas.c | 68 +- src/bacnet/basic/service/s_whohas.h | 55 + .../bacnet/basic/service}/s_whois.c | 67 +- src/bacnet/basic/service/s_whois.h | 63 + .../bacnet/basic/service}/s_wp.c | 95 +- src/bacnet/basic/service/s_wp.h | 65 + .../bacnet/basic/service}/s_wpm.c | 45 +- src/bacnet/basic/service/s_wpm.h | 54 + src/bacnet/basic/services.h | 98 + src/{ => bacnet/basic/sys}/bigend.c | 0 {include => src/bacnet/basic/sys}/bigend.h | 0 src/{ => bacnet/basic/sys}/debug.c | 8 +- {include => src/bacnet/basic/sys}/debug.h | 2 +- src/{ => bacnet/basic/sys}/fifo.c | 10 +- {include => src/bacnet/basic/sys}/fifo.h | 0 src/{ => bacnet/basic/sys}/filename.c | 2 +- {include => src/bacnet/basic/sys}/filename.h | 0 src/{ => bacnet/basic/sys}/key.c | 4 +- {include => src/bacnet/basic/sys}/key.h | 0 src/{ => bacnet/basic/sys}/keylist.c | 73 +- {include => src/bacnet/basic/sys}/keylist.h | 0 src/bacnet/basic/sys/mstimer.c | 123 + src/bacnet/basic/sys/mstimer.h | 66 + src/{ => bacnet/basic/sys}/ringbuf.c | 78 +- {include => src/bacnet/basic/sys}/ringbuf.h | 0 src/{ => bacnet/basic/sys}/sbuf.c | 20 +- {include => src/bacnet/basic/sys}/sbuf.h | 0 src/{ => bacnet/basic/tsm}/tsm.c | 67 +- {include => src/bacnet/basic/tsm}/tsm.h | 9 +- src/{ => bacnet/basic/ucix}/ucix.c | 89 +- {include => src/bacnet/basic/ucix}/ucix.h | 0 {include => src/bacnet}/bits.h | 0 {include => src/bacnet}/bytes.h | 0 {include => src/bacnet}/config.h | 5 + src/{ => bacnet}/cov.c | 360 +-- {include => src/bacnet}/cov.h | 2 +- .../credential_authentication_factor.c | 40 +- .../credential_authentication_factor.h | 6 +- {include => src/bacnet/datalink}/arcnet.h | 4 +- src/{ => bacnet/datalink}/bacsec.c | 169 +- {include => src/bacnet/datalink}/bacsec.h | 4 +- src/{ => bacnet/datalink}/bip.c | 59 +- {include => src/bacnet/datalink}/bip.h | 6 +- {include => src/bacnet/datalink}/bip6.h | 6 +- src/{ => bacnet/datalink}/bvlc.c | 211 +- {include => src/bacnet/datalink}/bvlc.h | 6 +- src/{ => bacnet/datalink}/bvlc6.c | 528 ++-- {include => src/bacnet/datalink}/bvlc6.h | 20 +- src/{ => bacnet/datalink}/crc.c | 112 +- {include => src/bacnet/datalink}/crc.h | 0 src/{ => bacnet/datalink}/datalink.c | 34 +- {include => src/bacnet/datalink}/datalink.h | 20 +- {demo/handler => src/bacnet/datalink}/dlenv.c | 56 +- {include => src/bacnet/datalink}/dlenv.h | 0 {include => src/bacnet/datalink}/dlmstp.h | 4 +- {include => src/bacnet/datalink}/ethernet.h | 4 +- src/{ => bacnet/datalink}/mstp.c | 248 +- {include => src/bacnet/datalink}/mstp.h | 2 +- {include => src/bacnet/datalink}/mstpdef.h | 2 +- src/{ => bacnet/datalink}/mstptext.c | 64 +- {include => src/bacnet/datalink}/mstptext.h | 0 src/{ => bacnet}/datetime.c | 238 +- {include => src/bacnet}/datetime.h | 19 + src/{ => bacnet}/dcc.c | 89 +- {include => src/bacnet}/dcc.h | 4 +- src/{ => bacnet}/event.c | 688 ++--- {include => src/bacnet}/event.h | 10 +- src/{ => bacnet}/get_alarm_sum.c | 32 +- {include => src/bacnet}/get_alarm_sum.h | 6 +- src/{ => bacnet}/getevent.c | 206 +- {include => src/bacnet}/getevent.h | 8 +- src/{ => bacnet}/iam.c | 88 +- {include => src/bacnet}/iam.h | 6 +- src/{ => bacnet}/ihave.c | 65 +- {include => src/bacnet}/ihave.h | 2 +- src/{ => bacnet}/indtext.c | 66 +- {include => src/bacnet}/indtext.h | 0 src/{ => bacnet}/lighting.c | 59 +- {include => src/bacnet}/lighting.h | 2 +- src/{ => bacnet}/lso.c | 39 +- {include => src/bacnet}/lso.h | 6 +- src/{ => bacnet}/memcopy.c | 15 +- {include => src/bacnet}/memcopy.h | 0 src/{ => bacnet}/npdu.c | 93 +- {include => src/bacnet}/npdu.h | 4 +- src/bacnet/property.c | 709 +++++ include/proplist.h => src/bacnet/property.h | 32 +- src/bacnet/proplist.c | 245 ++ ports/linux/timer.h => src/bacnet/proplist.h | 58 +- src/{ => bacnet}/ptransfer.c | 228 +- {include => src/bacnet}/ptransfer.h | 0 src/{ => bacnet}/rd.c | 59 +- {include => src/bacnet}/rd.h | 1 + src/{ => bacnet}/readrange.c | 185 +- {include => src/bacnet}/readrange.h | 4 +- src/{ => bacnet}/reject.c | 48 +- {include => src/bacnet}/reject.h | 1 + src/{ => bacnet}/rp.c | 118 +- {include => src/bacnet}/rp.h | 4 +- src/{ => bacnet}/rpm.c | 286 +- {include => src/bacnet}/rpm.h | 8 +- src/{ => bacnet}/timestamp.c | 103 +- {include => src/bacnet}/timestamp.h | 5 +- src/{ => bacnet}/timesync.c | 186 +- {include => src/bacnet}/timesync.h | 2 +- {include => src/bacnet}/version.h | 5 +- src/{ => bacnet}/whohas.c | 79 +- {include => src/bacnet}/whohas.h | 2 +- src/{ => bacnet}/whois.c | 40 +- {include => src/bacnet}/whois.h | 0 src/{ => bacnet}/wp.c | 108 +- {include => src/bacnet}/wp.h | 4 +- src/{ => bacnet}/wpm.c | 80 +- {include => src/bacnet}/wpm.h | 6 +- src/bactext.c | 1534 ---------- src/proplist.c | 1235 -------- src/version.c | 38 - svn2cl.xsl | 215 -- test/abort.mak | 14 +- test/address.mak | 26 +- test/arf.mak | 12 +- test/awf.mak | 12 +- test/bacapp.mak | 22 +- test/bacdcode.mak | 10 +- test/bacdevobjpropref.mak | 22 +- test/bacerror.mak | 12 +- test/bacint.mak | 6 +- test/bacstr.mak | 4 +- test/bbmd6.mak | 16 +- test/bvlc.mak | 12 +- test/bvlc6.mak | 12 +- test/cov.mak | 26 +- test/crc.mak | 4 +- test/datetime.cbp | 85 + test/datetime.mak | 22 +- test/dcc.mak | 12 +- test/event.mak | 32 +- test/fifo.mak | 4 +- test/filename.mak | 4 +- test/getevent.mak | 26 +- test/iam.mak | 12 +- test/ihave.mak | 12 +- test/indtext.mak | 4 +- test/key.mak | 4 +- test/keylist.mak | 4 +- test/lighting.mak | 12 +- test/lso.mak | 28 +- test/memcopy.mak | 4 +- test/mstp.mak | 12 +- test/npdu.mak | 16 +- test/objects.mak | 8 +- test/proplist.mak | 17 +- test/ptransfer.mak | 24 +- test/rd.mak | 12 +- test/reject.mak | 12 +- test/ringbuf.mak | 4 +- test/rp.mak | 12 +- test/rpm.mak | 28 +- test/sbuf.mak | 4 +- test/timer.mak | 4 +- test/timesync.mak | 26 +- test/vmac.mak | 6 +- test/whohas.mak | 12 +- test/whois.mak | 12 +- test/wp.mak | 24 +- 912 files changed, 36206 insertions(+), 52502 deletions(-) delete mode 100644 .hgeol delete mode 100644 .hgignore create mode 100644 apps/Makefile create mode 100644 apps/abort/Makefile rename {demo => apps}/abort/main.c (83%) create mode 100644 apps/dcc/Makefile rename {demo => apps}/dcc/main.c (77%) create mode 100644 apps/epics/Makefile create mode 100644 apps/epics/bacepics.cbp rename {demo => apps}/epics/bacepics.h (100%) mode change 100755 => 100644 rename {demo => apps}/epics/main.c (88%) create mode 100644 apps/error/Makefile rename {demo => apps}/error/main.c (81%) rename {demo => apps}/gateway/Makefile (100%) rename {demo => apps}/gateway/gateway.h (100%) rename {demo => apps}/gateway/main.c (79%) create mode 100644 apps/getevent/Makefile rename {demo => apps}/getevent/main.c (76%) mode change 100755 => 100644 create mode 100644 apps/iam/Makefile rename {demo => apps}/iam/main.c (76%) create mode 100644 apps/iamrouter/Makefile rename {demo => apps}/iamrouter/main.c (72%) create mode 100644 apps/initrouter/Makefile rename {demo => apps}/initrouter/main.c (85%) create mode 100644 apps/mstpcap/Makefile rename {demo => apps}/mstpcap/main.c (81%) rename {demo => apps}/mstpcap/mstpcap.txt (100%) create mode 100644 apps/mstpcrc/Makefile rename {demo => apps}/mstpcrc/build.bat (100%) rename {demo => apps}/mstpcrc/main.c (93%) rename {demo => apps}/mstpcrc/readme.txt (100%) rename {demo => apps}/perl/Documentation/index.html (100%) rename {demo => apps}/perl/Documentation/jquery.js (100%) mode change 100755 => 100644 rename {demo => apps}/perl/Documentation/syntax.css (100%) mode change 100755 => 100644 rename {demo => apps}/perl/Documentation/syntax.js (100%) mode change 100755 => 100644 rename {demo => apps}/perl/bacnet.pl (100%) rename {demo => apps}/perl/example_readprop.pl (100%) rename {demo => apps}/perl/perl_bindings.c (82%) rename {demo => apps}/perl/readme.txt (100%) rename {demo => apps}/piface/Makefile (100%) rename {demo => apps}/piface/configure.sh (100%) mode change 100755 => 100644 rename {demo => apps}/piface/device.c (85%) rename {demo => apps}/piface/main.c (76%) rename {demo => apps}/piface/readme.txt (100%) rename {demo => apps}/ptransfer/Makefile (100%) rename {demo/handler => apps/ptransfer}/h_pt.c (81%) create mode 100644 apps/ptransfer/h_pt.h rename {demo/handler => apps/ptransfer}/h_pt_a.c (85%) create mode 100644 apps/ptransfer/h_pt_a.h rename {demo => apps}/ptransfer/main.c (75%) rename {demo => apps}/ptransfer/ptransfer.sln (100%) create mode 100644 apps/ptransfer/s_ptransfer.c create mode 100644 apps/ptransfer/s_ptransfer.h create mode 100644 apps/readbdt/Makefile rename {demo => apps}/readbdt/main.c (83%) create mode 100644 apps/readfile/Makefile rename {demo => apps}/readfile/main.c (78%) rename {demo => apps}/readfile/main.ide (100%) create mode 100644 apps/readprop/Makefile rename {demo => apps}/readprop/bacrp.cbp (100%) rename {demo => apps}/readprop/main.c (63%) create mode 100644 apps/readpropm/Makefile rename {demo => apps}/readpropm/bacrpm.cbp (100%) rename {demo => apps}/readpropm/main.c (69%) create mode 100644 apps/readrange/Makefile rename {demo => apps}/readrange/main.c (70%) rename {demo => apps}/readrange/readrange/readrange.sln (100%) rename {demo => apps}/readrange/readrange/readrange.vcproj (94%) create mode 100644 apps/reinit/Makefile rename {demo => apps}/reinit/main.c (70%) create mode 100644 apps/router-ipv6/Makefile rename {demo => apps}/router-ipv6/main.c (88%) rename {demo => apps}/router-ipv6/readme.txt (96%) rename {demo => apps}/router/Makefile (100%) rename {demo => apps}/router/init.cfg (100%) rename {demo => apps}/router/ipmodule.c (84%) rename {demo => apps}/router/ipmodule.h (98%) rename {demo => apps}/router/main.c (93%) rename {demo => apps}/router/msgqueue.c (97%) rename {demo => apps}/router/msgqueue.h (97%) rename {demo => apps}/router/mstpmodule.c (93%) rename {demo => apps}/router/mstpmodule.h (100%) rename {demo => apps}/router/network_layer.c (91%) rename {demo => apps}/router/network_layer.h (95%) rename {demo => apps}/router/portthread.c (96%) rename {demo => apps}/router/portthread.h (98%) rename {demo => apps}/router/readme.txt (100%) create mode 100644 apps/scov/Makefile rename {demo => apps}/scov/main.c (70%) rename {demo => apps}/server/.gdbinit (100%) create mode 100644 apps/server/Makefile rename {demo => apps}/server/PICS.odt (100%) create mode 100644 apps/server/bacserv-linux.cbp create mode 100644 apps/server/bacserv-windows.cbp create mode 100755 apps/server/bin/Debug/bacserv rename {demo => apps}/server/epics_vts3.tpi (100%) rename {demo => apps}/server/main.c (69%) create mode 100644 apps/timesync/Makefile rename {demo => apps}/timesync/main.c (74%) create mode 100644 apps/ucov/Makefile rename {demo => apps}/ucov/main.c (87%) create mode 100644 apps/uevent/Makefile rename {demo => apps}/uevent/main.c (85%) create mode 100644 apps/uptransfer/Makefile rename {demo => apps}/uptransfer/main.c (84%) create mode 100644 apps/whohas/Makefile rename {demo => apps}/whohas/main.c (77%) create mode 100644 apps/whois/Makefile create mode 100644 apps/whois/bacwi-linux.cbp create mode 100644 apps/whois/bacwi.layout rename {demo => apps}/whois/main.c (70%) create mode 100644 apps/whoisrouter/Makefile rename {demo => apps}/whoisrouter/main.c (77%) create mode 100644 apps/writefile/Makefile rename {demo => apps}/writefile/main.c (80%) rename {demo => apps}/writefile/main.ide (100%) create mode 100644 apps/writeprop/Makefile rename {demo => apps}/writeprop/main.c (82%) create mode 100644 apps/writepropm/Makefile rename {demo => apps}/writepropm/main.c (82%) delete mode 100644 borland.bat delete mode 100755 build.sh delete mode 100755 comment.sh delete mode 100644 demo/BACnetDemo.workspace delete mode 100644 demo/Makefile delete mode 100644 demo/abort/Makefile delete mode 100644 demo/dcc/Makefile delete mode 100644 demo/dcc/makefile.b32 delete mode 100644 demo/dcc/makefile.g++ delete mode 100644 demo/dcc/tmake.pro delete mode 100644 demo/epics/Makefile delete mode 100644 demo/epics/bacepics.cbp delete mode 100644 demo/epics/makefile.b32 delete mode 100644 demo/error/Makefile delete mode 100644 demo/gateway/makefile.b32 delete mode 100644 demo/getevent/Makefile delete mode 100644 demo/handler/s_ptransfer.c delete mode 100644 demo/handler/txbuf.c delete mode 100644 demo/iam/Makefile delete mode 100644 demo/iam/makefile.b32 delete mode 100644 demo/iamrouter/Makefile delete mode 100644 demo/iamrouter/makefile.b32 delete mode 100644 demo/initrouter/Makefile delete mode 100644 demo/initrouter/makefile.b32 delete mode 100644 demo/mstpcap/Makefile delete mode 100644 demo/mstpcap/makefile.b32 delete mode 100644 demo/mstpcrc/Makefile delete mode 100644 demo/mstpcrc/makefile.b32 delete mode 100644 demo/ptransfer/makefile.b32 delete mode 100644 demo/ptransfer/rdproperty.vcproj delete mode 100644 demo/readbdt/Makefile delete mode 100644 demo/readbdt/makefile.b32 delete mode 100644 demo/readfile/Makefile delete mode 100644 demo/readfile/makefile.b32 delete mode 100644 demo/readprop/Makefile delete mode 100644 demo/readprop/makefile.b32 delete mode 100644 demo/readpropm/Makefile delete mode 100644 demo/readpropm/makefile.b32 delete mode 100644 demo/readrange/Makefile delete mode 100644 demo/reinit/Makefile delete mode 100644 demo/reinit/makefile.b32 delete mode 100644 demo/router-ipv6/Makefile delete mode 100644 demo/scov/Makefile delete mode 100644 demo/scov/makefile.b32 delete mode 100644 demo/server/Makefile delete mode 100644 demo/server/bacserv.cbp delete mode 100644 demo/server/makefile.b32 delete mode 100644 demo/server/server.h delete mode 100644 demo/timesync/Makefile delete mode 100644 demo/timesync/makefile.b32 delete mode 100644 demo/ucov/Makefile delete mode 100644 demo/ucov/makefile.b32 delete mode 100644 demo/uevent/Makefile delete mode 100644 demo/uptransfer/Makefile delete mode 100644 demo/uptransfer/makefile.b32 delete mode 100644 demo/whohas/Makefile delete mode 100644 demo/whohas/makefile.b32 delete mode 100644 demo/whois/Makefile delete mode 100644 demo/whois/bacwi.dsp delete mode 100644 demo/whois/makefile.b32 delete mode 100644 demo/whoisrouter/Makefile delete mode 100644 demo/whoisrouter/makefile.b32 delete mode 100644 demo/writefile/Makefile delete mode 100644 demo/writefile/makefile.b32 delete mode 100644 demo/writeprop/Makefile delete mode 100644 demo/writeprop/makefile.b32 delete mode 100644 demo/writepropm/Makefile delete mode 100755 export.sh delete mode 100644 include/bacnet.h delete mode 100644 include/client.h delete mode 100644 include/handlers.h delete mode 100644 include/mydata.h delete mode 100644 lib/Makefile delete mode 100644 lib/bacnet.cbp delete mode 100644 lib/bacnetdll.cbp delete mode 100644 lib/main.cpp delete mode 100644 lib/main.h delete mode 100644 lib/makefile.b32 delete mode 100644 makefile.b32 delete mode 100644 ports/atmega8/Makefile delete mode 100644 ports/atmega8/apdu.c delete mode 100644 ports/atmega8/avr035.h delete mode 100644 ports/atmega8/bacnet.ewp delete mode 100644 ports/atmega8/bacnet.eww delete mode 100644 ports/atmega8/device.c delete mode 100644 ports/atmega8/dlmstp.c delete mode 100644 ports/atmega8/hardware.h delete mode 100644 ports/atmega8/hardware.ods delete mode 100644 ports/atmega8/iar2gcc.h delete mode 100644 ports/atmega8/main.c delete mode 100644 ports/atmega8/readme.txt delete mode 100644 ports/atmega8/rs485.c delete mode 100644 ports/atmega8/rs485.h delete mode 100644 ports/atmega8/stdbool.h delete mode 100644 ports/atmega8/stdint.h delete mode 100644 ports/atmega8/timer.c rename ports/bdk-atxx4-mstp/{timer2.c => mstimer-init.c} (90%) delete mode 100644 ports/bdk-atxx4-mstp/timer.c delete mode 100644 ports/bdk-atxx4-mstp/timer.h rename ports/bsd/{net.h => bacport.h} (100%) create mode 100644 ports/bsd/datetime-init.c create mode 100644 ports/bsd/mstimer-init.c delete mode 100644 ports/bsd/timer.c delete mode 100644 ports/dos/bacnet.prj delete mode 100644 ports/dos/dlmstp.c delete mode 100644 ports/dos/extkword.h delete mode 100644 ports/dos/main.c delete mode 100644 ports/dos/mk_fp.h delete mode 100644 ports/dos/pchwio.c delete mode 100644 ports/dos/pchwio.h delete mode 100644 ports/dos/queue.c delete mode 100644 ports/dos/queue.h delete mode 100644 ports/dos/readme.txt delete mode 100644 ports/dos/rs485.c delete mode 100644 ports/dos/serial.c delete mode 100644 ports/dos/serial.h delete mode 100644 ports/dos/stdbool.h delete mode 100644 ports/dos/stdint.h delete mode 100644 ports/dos/timer.c rename ports/linux/{net.h => bacport.h} (100%) create mode 100644 ports/linux/datetime-init.c rename ports/{win32/timer.h => linux/mstimer-init.c} (50%) delete mode 100644 ports/linux/timer.c delete mode 100644 ports/rtos32/bip-init.c delete mode 100644 ports/rtos32/dlmstp.c delete mode 100644 ports/rtos32/ethernet.c delete mode 100644 ports/rtos32/hardware.cfg delete mode 100644 ports/rtos32/init.c delete mode 100644 ports/rtos32/main.c delete mode 100644 ports/rtos32/makefile.mak delete mode 100644 ports/rtos32/monitor.cfg delete mode 100644 ports/rtos32/mstp.c delete mode 100644 ports/rtos32/mstp.h delete mode 100644 ports/rtos32/net.h delete mode 100644 ports/rtos32/netcfg.h delete mode 100644 ports/rtos32/rs485.c delete mode 100644 ports/rtos32/rs485.h delete mode 100644 ports/rtos32/setvars.bat delete mode 100644 ports/rtos32/software.cfg delete mode 100644 ports/rtos32/stdbool.h delete mode 100644 ports/rtos32/stdint.h delete mode 100644 ports/rx62n/BACnet_Ethernet_RX62N.hwp rename ports/rx62n/{timer-hdw.c => mstimer-init.c} (84%) delete mode 100644 ports/rx62n/timer.c delete mode 100644 ports/rx62n/timer.h rename ports/stm32f10x/{timer_sys.c => mstimer-init.c} (57%) delete mode 100644 ports/stm32f10x/timer.c delete mode 100644 ports/stm32f10x/timer.h rename ports/{arm7 => uip}/_stdint.h (100%) rename ports/{arm7 => uip}/bip.c (98%) rename ports/{arm7 => uip}/net.h (100%) rename ports/{arm7 => uip}/stdbool.h (100%) rename ports/win32/{net.h => bacport.h} (72%) create mode 100644 ports/win32/datetime-init.c create mode 100644 ports/win32/mstimer-init.c delete mode 100644 ports/win32/timer.c rename ports/xplained/{timer1.c => mstimer-init.c} (52%) delete mode 100644 ports/xplained/timer.c delete mode 100644 ports/xplained/timer.h delete mode 100755 rebuild.sh delete mode 100755 release.sh delete mode 100755 splint.sh create mode 100644 src/Makefile rename src/{ => bacnet}/abort.c (79%) rename {include => src/bacnet}/abort.h (98%) rename src/{ => bacnet}/access_rule.c (74%) rename {include => src/bacnet}/access_rule.h (96%) rename src/{ => bacnet}/alarm_ack.c (60%) rename {include => src/bacnet}/alarm_ack.h (97%) rename ports/dos/rs485.h => src/bacnet/apdu.h (64%) rename src/{ => bacnet}/arf.c (67%) rename {include => src/bacnet}/arf.h (98%) rename src/{ => bacnet}/assigned_access_rights.c (79%) rename {include => src/bacnet}/assigned_access_rights.h (95%) rename src/{ => bacnet}/authentication_factor.c (81%) rename {include => src/bacnet}/authentication_factor.h (97%) rename src/{ => bacnet}/authentication_factor_format.c (82%) rename {include => src/bacnet}/authentication_factor_format.h (98%) rename src/{ => bacnet}/awf.c (70%) rename {include => src/bacnet}/awf.h (99%) rename src/{ => bacnet}/bacaddr.c (79%) rename {include => src/bacnet}/bacaddr.h (98%) rename src/{ => bacnet}/bacapp.c (79%) rename {include => src/bacnet}/bacapp.h (97%) rename src/{ => bacnet}/bacdcode.c (89%) rename {include => src/bacnet}/bacdcode.h (98%) rename {include => src/bacnet}/bacdef.h (99%) rename src/{ => bacnet}/bacdevobjpropref.c (78%) rename {include => src/bacnet}/bacdevobjpropref.h (98%) rename {include => src/bacnet}/bacenum.h (100%) rename src/{ => bacnet}/bacerror.c (66%) rename {include => src/bacnet}/bacerror.h (98%) rename src/{ => bacnet}/bacint.c (96%) rename {include => src/bacnet}/bacint.h (100%) rename src/{ => bacnet}/bacprop.c (63%) rename {include => src/bacnet}/bacprop.h (98%) rename src/{ => bacnet}/bacpropstates.c (72%) rename {include => src/bacnet}/bacpropstates.h (97%) rename src/{ => bacnet}/bacreal.c (95%) rename {include => src/bacnet}/bacreal.h (100%) rename src/{ => bacnet}/bacstr.c (86%) rename {include => src/bacnet}/bacstr.h (99%) create mode 100644 src/bacnet/bactext.c rename {include => src/bacnet}/bactext.h (99%) rename src/{ => bacnet}/bactimevalue.c (79%) rename {include => src/bacnet}/bactimevalue.h (96%) rename {demo/handler => src/bacnet/basic/bbmd6}/h_bbmd6.c (86%) rename ports/bsd/timer.h => src/bacnet/basic/bbmd6/h_bbmd6.h (58%) rename src/{ => bacnet/basic/bbmd6}/vmac.c (98%) rename {include => src/bacnet/basic/bbmd6}/vmac.h (100%) rename src/{ => bacnet/basic/binding}/address.c (85%) rename {include => src/bacnet/basic/binding}/address.h (98%) rename {demo/handler => src/bacnet/basic/npdu}/h_npdu.c (88%) create mode 100644 src/bacnet/basic/npdu/h_npdu.h rename {demo/handler => src/bacnet/basic/npdu}/h_routed_npdu.c (87%) rename ports/atmega8/timer.h => src/bacnet/basic/npdu/h_routed_npdu.h (70%) rename {demo/handler => src/bacnet/basic/npdu}/s_router.c (79%) create mode 100644 src/bacnet/basic/npdu/s_router.h rename {demo => src/bacnet/basic}/object/Makefile (100%) rename {demo => src/bacnet/basic}/object/access_credential.c (82%) rename {demo => src/bacnet/basic}/object/access_credential.h (92%) rename {demo => src/bacnet/basic}/object/access_credential.mak (54%) rename {demo => src/bacnet/basic}/object/access_door.c (81%) rename {demo => src/bacnet/basic}/object/access_door.h (97%) rename {demo => src/bacnet/basic}/object/access_door.mak (62%) rename {demo => src/bacnet/basic}/object/access_point.c (87%) rename {demo => src/bacnet/basic}/object/access_point.h (95%) rename {demo => src/bacnet/basic}/object/access_point.mak (60%) rename {demo => src/bacnet/basic}/object/access_rights.c (83%) rename {demo => src/bacnet/basic}/object/access_rights.h (95%) rename {demo => src/bacnet/basic}/object/access_rights.mak (60%) rename {demo => src/bacnet/basic}/object/access_user.c (88%) rename {demo => src/bacnet/basic}/object/access_user.h (95%) rename {demo => src/bacnet/basic}/object/access_user.mak (62%) rename {demo => src/bacnet/basic}/object/access_zone.c (88%) rename {demo => src/bacnet/basic}/object/access_zone.h (96%) rename {demo => src/bacnet/basic}/object/access_zone.mak (62%) rename {demo => src/bacnet/basic}/object/ai.c (83%) rename {demo => src/bacnet/basic}/object/ai.h (96%) rename {demo => src/bacnet/basic}/object/ai.mak (64%) mode change 100755 => 100644 rename {demo => src/bacnet/basic}/object/ao.c (83%) rename {demo => src/bacnet/basic}/object/ao.h (97%) rename {demo => src/bacnet/basic}/object/ao.mak (62%) mode change 100755 => 100644 rename {demo => src/bacnet/basic}/object/av.c (82%) rename {demo => src/bacnet/basic}/object/av.h (95%) rename {demo => src/bacnet/basic}/object/av.mak (62%) rename {demo => src/bacnet/basic}/object/bacfile.c (78%) rename {demo => src/bacnet/basic}/object/bacfile.h (95%) rename {demo => src/bacnet/basic}/object/bi.c (84%) rename {demo => src/bacnet/basic}/object/bi.h (97%) rename {demo => src/bacnet/basic}/object/bi.mak (61%) rename {demo => src/bacnet/basic}/object/bo.c (85%) rename {demo => src/bacnet/basic}/object/bo.h (97%) rename {demo => src/bacnet/basic}/object/bo.mak (62%) mode change 100755 => 100644 rename {demo => src/bacnet/basic}/object/bv.c (87%) rename {demo => src/bacnet/basic}/object/bv.h (97%) rename {demo => src/bacnet/basic}/object/bv.mak (62%) rename {demo => src/bacnet/basic}/object/channel.c (88%) rename {demo => src/bacnet/basic}/object/channel.h (98%) rename {demo/object => src/bacnet/basic/object/client}/device-client.c (81%) rename {demo => src/bacnet/basic}/object/command.c (81%) rename {demo => src/bacnet/basic}/object/command.h (98%) rename {demo => src/bacnet/basic}/object/command.mak (63%) rename {demo => src/bacnet/basic}/object/credential_data_input.c (85%) rename {demo => src/bacnet/basic}/object/credential_data_input.h (92%) rename {demo => src/bacnet/basic}/object/credential_data_input.mak (55%) rename {demo => src/bacnet/basic}/object/csv.c (81%) rename {demo => src/bacnet/basic}/object/csv.h (96%) rename {demo => src/bacnet/basic}/object/csv.mak (63%) rename {demo => src/bacnet/basic}/object/device.c (74%) rename {demo => src/bacnet/basic}/object/device.h (98%) rename {demo => src/bacnet/basic}/object/device.mak (57%) rename {demo/object => src/bacnet/basic/object/gateway}/gw_device.c (84%) rename {demo => src/bacnet/basic}/object/iv.c (85%) rename {demo => src/bacnet/basic}/object/iv.h (97%) rename {demo => src/bacnet/basic}/object/lc.c (84%) rename {demo => src/bacnet/basic}/object/lc.h (95%) rename {demo => src/bacnet/basic}/object/lc.ide (100%) rename {demo => src/bacnet/basic}/object/lc.mak (62%) rename {demo => src/bacnet/basic}/object/lo.c (88%) rename {demo => src/bacnet/basic}/object/lo.h (98%) rename {demo => src/bacnet/basic}/object/lo.mak (62%) mode change 100755 => 100644 rename {demo => src/bacnet/basic}/object/lsp.c (87%) rename {demo => src/bacnet/basic}/object/lsp.h (95%) rename {demo => src/bacnet/basic}/object/lsp.mak (62%) mode change 100755 => 100644 rename {demo => src/bacnet/basic}/object/ms-input.c (84%) rename {demo => src/bacnet/basic}/object/ms-input.h (97%) rename {demo => src/bacnet/basic}/object/ms-input.mak (63%) rename {demo => src/bacnet/basic}/object/mso.c (84%) rename {demo => src/bacnet/basic}/object/mso.h (97%) rename {demo => src/bacnet/basic}/object/mso.mak (62%) rename {demo => src/bacnet/basic}/object/msv.c (83%) rename {demo => src/bacnet/basic}/object/msv.h (97%) rename {demo => src/bacnet/basic}/object/msv.mak (62%) rename {demo => src/bacnet/basic}/object/nc.c (88%) rename {demo => src/bacnet/basic}/object/nc.h (99%) rename {demo => src/bacnet/basic}/object/netport.c (87%) rename {demo => src/bacnet/basic}/object/netport.h (93%) rename {demo => src/bacnet/basic}/object/netport.mak (60%) rename {demo/handler => src/bacnet/basic/object}/objects.c (91%) rename {include => src/bacnet/basic/object}/objects.h (97%) rename {demo => src/bacnet/basic}/object/osv.c (84%) rename {demo => src/bacnet/basic}/object/osv.h (97%) rename {demo => src/bacnet/basic}/object/osv.mak (61%) rename {demo => src/bacnet/basic}/object/piv.c (85%) rename {demo => src/bacnet/basic}/object/piv.h (97%) rename {demo => src/bacnet/basic}/object/piv.mak (63%) rename {demo => src/bacnet/basic}/object/schedule.c (87%) rename {demo => src/bacnet/basic}/object/schedule.h (94%) rename {demo => src/bacnet/basic}/object/schedule.mak (60%) rename {demo => src/bacnet/basic}/object/trendlog.c (80%) rename {demo => src/bacnet/basic}/object/trendlog.h (98%) rename {demo/handler => src/bacnet/basic/service}/h_alarm_ack.c (64%) create mode 100644 src/bacnet/basic/service/h_alarm_ack.h rename src/{apdu.c => bacnet/basic/service/h_apdu.c} (82%) rename include/apdu.h => src/bacnet/basic/service/h_apdu.h (87%) rename {demo/handler => src/bacnet/basic/service}/h_arf.c (80%) create mode 100644 src/bacnet/basic/service/h_arf.h rename {demo/handler => src/bacnet/basic/service}/h_arf_a.c (82%) create mode 100644 src/bacnet/basic/service/h_arf_a.h rename {demo/handler => src/bacnet/basic/service}/h_awf.c (78%) create mode 100644 src/bacnet/basic/service/h_awf.h rename {demo/handler => src/bacnet/basic/service}/h_ccov.c (78%) create mode 100644 src/bacnet/basic/service/h_ccov.h rename {demo/handler => src/bacnet/basic/service}/h_cov.c (87%) create mode 100644 src/bacnet/basic/service/h_cov.h rename {demo/handler => src/bacnet/basic/service}/h_dcc.c (71%) create mode 100644 src/bacnet/basic/service/h_dcc.h rename {demo/handler => src/bacnet/basic/service}/h_gas_a.c (81%) create mode 100644 src/bacnet/basic/service/h_gas_a.h rename {demo/handler => src/bacnet/basic/service}/h_get_alarm_sum.c (73%) create mode 100644 src/bacnet/basic/service/h_get_alarm_sum.h rename {demo/handler => src/bacnet/basic/service}/h_getevent.c (72%) create mode 100644 src/bacnet/basic/service/h_getevent.h rename {demo/handler => src/bacnet/basic/service}/h_getevent_a.c (85%) create mode 100644 src/bacnet/basic/service/h_getevent_a.h rename {demo/handler => src/bacnet/basic/service}/h_iam.c (78%) create mode 100644 src/bacnet/basic/service/h_iam.h rename {demo/handler => src/bacnet/basic/service}/h_ihave.c (80%) rename ports/dos/timer.h => src/bacnet/basic/service/h_ihave.h (72%) rename {demo/handler => src/bacnet/basic/service}/h_lso.c (67%) create mode 100644 src/bacnet/basic/service/h_lso.h rename demo/handler/noserv.c => src/bacnet/basic/service/h_noserv.c (78%) create mode 100644 src/bacnet/basic/service/h_noserv.h rename {demo/handler => src/bacnet/basic/service}/h_rd.c (68%) create mode 100644 src/bacnet/basic/service/h_rd.h rename {demo/handler => src/bacnet/basic/service}/h_rp.c (81%) create mode 100644 src/bacnet/basic/service/h_rp.h rename {demo/handler => src/bacnet/basic/service}/h_rp_a.c (93%) create mode 100644 src/bacnet/basic/service/h_rp_a.h rename {demo/handler => src/bacnet/basic/service}/h_rpm.c (82%) create mode 100644 src/bacnet/basic/service/h_rpm.h rename {demo/handler => src/bacnet/basic/service}/h_rpm_a.c (86%) create mode 100644 src/bacnet/basic/service/h_rpm_a.h rename {demo/handler => src/bacnet/basic/service}/h_rr.c (75%) create mode 100644 src/bacnet/basic/service/h_rr.h rename {demo/handler => src/bacnet/basic/service}/h_rr_a.c (85%) create mode 100644 src/bacnet/basic/service/h_rr_a.h rename {demo/handler => src/bacnet/basic/service}/h_ts.c (86%) create mode 100644 src/bacnet/basic/service/h_ts.h rename {demo/handler => src/bacnet/basic/service}/h_ucov.c (85%) rename include/txbuf.h => src/bacnet/basic/service/h_ucov.h (65%) rename {demo/handler => src/bacnet/basic/service}/h_upt.c (83%) create mode 100644 src/bacnet/basic/service/h_upt.h rename {demo/handler => src/bacnet/basic/service}/h_whohas.c (78%) create mode 100644 src/bacnet/basic/service/h_whohas.h rename {demo/handler => src/bacnet/basic/service}/h_whois.c (80%) create mode 100644 src/bacnet/basic/service/h_whois.h rename {demo/handler => src/bacnet/basic/service}/h_wp.c (76%) create mode 100644 src/bacnet/basic/service/h_wp.h rename {demo/handler => src/bacnet/basic/service}/h_wpm.c (69%) create mode 100644 src/bacnet/basic/service/h_wpm.h rename {demo/handler => src/bacnet/basic/service}/s_abort.c (77%) create mode 100644 src/bacnet/basic/service/s_abort.h rename {demo/handler => src/bacnet/basic/service}/s_ack_alarm.c (73%) create mode 100644 src/bacnet/basic/service/s_ack_alarm.h rename {demo/handler => src/bacnet/basic/service}/s_arfs.c (74%) create mode 100644 src/bacnet/basic/service/s_arfs.h rename {demo/handler => src/bacnet/basic/service}/s_awfs.c (73%) create mode 100644 src/bacnet/basic/service/s_awfs.h rename {demo/handler => src/bacnet/basic/service}/s_cevent.c (77%) create mode 100644 src/bacnet/basic/service/s_cevent.h rename {demo/handler => src/bacnet/basic/service}/s_cov.c (78%) create mode 100644 src/bacnet/basic/service/s_cov.h rename {demo/handler => src/bacnet/basic/service}/s_dcc.c (77%) create mode 100644 src/bacnet/basic/service/s_dcc.h rename {demo/handler => src/bacnet/basic/service}/s_error.c (73%) create mode 100644 src/bacnet/basic/service/s_error.h rename {demo/handler => src/bacnet/basic/service}/s_get_alarm_sum.c (74%) create mode 100644 src/bacnet/basic/service/s_get_alarm_sum.h rename {demo/handler => src/bacnet/basic/service}/s_get_event.c (75%) create mode 100644 src/bacnet/basic/service/s_get_event.h rename {demo/handler => src/bacnet/basic/service}/s_getevent.c (71%) create mode 100644 src/bacnet/basic/service/s_getevent.h rename {demo/handler => src/bacnet/basic/service}/s_iam.c (82%) create mode 100644 src/bacnet/basic/service/s_iam.h rename {demo/handler => src/bacnet/basic/service}/s_ihave.c (78%) create mode 100644 src/bacnet/basic/service/s_ihave.h rename {demo/handler => src/bacnet/basic/service}/s_lso.c (75%) create mode 100644 src/bacnet/basic/service/s_lso.h rename {demo/handler => src/bacnet/basic/service}/s_rd.c (75%) create mode 100644 src/bacnet/basic/service/s_rd.h rename {demo/handler => src/bacnet/basic/service}/s_readrange.c (75%) create mode 100644 src/bacnet/basic/service/s_readrange.h rename {demo/handler => src/bacnet/basic/service}/s_rp.c (74%) create mode 100644 src/bacnet/basic/service/s_rp.h rename {demo/handler => src/bacnet/basic/service}/s_rpm.c (80%) create mode 100644 src/bacnet/basic/service/s_rpm.h rename {demo/handler => src/bacnet/basic/service}/s_ts.c (73%) create mode 100644 src/bacnet/basic/service/s_ts.h rename {demo/handler => src/bacnet/basic/service}/s_uevent.c (90%) create mode 100644 src/bacnet/basic/service/s_uevent.h rename {demo/handler => src/bacnet/basic/service}/s_upt.c (71%) create mode 100644 src/bacnet/basic/service/s_upt.h rename {demo/handler => src/bacnet/basic/service}/s_whohas.c (76%) create mode 100644 src/bacnet/basic/service/s_whohas.h rename {demo/handler => src/bacnet/basic/service}/s_whois.c (81%) create mode 100644 src/bacnet/basic/service/s_whois.h rename {demo/handler => src/bacnet/basic/service}/s_wp.c (67%) create mode 100644 src/bacnet/basic/service/s_wp.h rename {demo/handler => src/bacnet/basic/service}/s_wpm.c (82%) create mode 100644 src/bacnet/basic/service/s_wpm.h create mode 100644 src/bacnet/basic/services.h rename src/{ => bacnet/basic/sys}/bigend.c (100%) rename {include => src/bacnet/basic/sys}/bigend.h (100%) rename src/{ => bacnet/basic/sys}/debug.c (90%) rename {include => src/bacnet/basic/sys}/debug.h (98%) rename src/{ => bacnet/basic/sys}/fifo.c (98%) mode change 100755 => 100644 rename {include => src/bacnet/basic/sys}/fifo.h (100%) mode change 100755 => 100644 rename src/{ => bacnet/basic/sys}/filename.c (98%) rename {include => src/bacnet/basic/sys}/filename.h (100%) rename src/{ => bacnet/basic/sys}/key.c (95%) rename {include => src/bacnet/basic/sys}/key.h (100%) rename src/{ => bacnet/basic/sys}/keylist.c (92%) rename {include => src/bacnet/basic/sys}/keylist.h (100%) create mode 100644 src/bacnet/basic/sys/mstimer.c create mode 100644 src/bacnet/basic/sys/mstimer.h rename src/{ => bacnet/basic/sys}/ringbuf.c (91%) rename {include => src/bacnet/basic/sys}/ringbuf.h (100%) rename src/{ => bacnet/basic/sys}/sbuf.c (92%) rename {include => src/bacnet/basic/sys}/sbuf.h (100%) rename src/{ => bacnet/basic/tsm}/tsm.c (89%) rename {include => src/bacnet/basic/tsm}/tsm.h (95%) rename src/{ => bacnet/basic/ucix}/ucix.c (63%) rename {include => src/bacnet/basic/ucix}/ucix.h (100%) rename {include => src/bacnet}/bits.h (100%) rename {include => src/bacnet}/bytes.h (100%) rename {include => src/bacnet}/config.h (98%) rename src/{ => bacnet}/cov.c (72%) rename {include => src/bacnet}/cov.h (99%) rename src/{ => bacnet}/credential_authentication_factor.c (84%) rename {include => src/bacnet}/credential_authentication_factor.h (96%) rename {include => src/bacnet/datalink}/arcnet.h (98%) rename src/{ => bacnet/datalink}/bacsec.c (82%) rename {include => src/bacnet/datalink}/bacsec.h (99%) rename src/{ => bacnet/datalink}/bip.c (90%) rename {include => src/bacnet/datalink}/bip.h (98%) rename {include => src/bacnet/datalink}/bip6.h (96%) rename src/{ => bacnet/datalink}/bvlc.c (91%) rename {include => src/bacnet/datalink}/bvlc.h (98%) rename src/{ => bacnet/datalink}/bvlc6.c (79%) rename {include => src/bacnet/datalink}/bvlc6.h (95%) rename src/{ => bacnet/datalink}/crc.c (60%) rename {include => src/bacnet/datalink}/crc.h (100%) rename src/{ => bacnet/datalink}/datalink.c (88%) rename {include => src/bacnet/datalink}/datalink.h (94%) rename {demo/handler => src/bacnet/datalink}/dlenv.c (94%) rename {include => src/bacnet/datalink}/dlenv.h (100%) rename {include => src/bacnet/datalink}/dlmstp.h (98%) rename {include => src/bacnet/datalink}/ethernet.h (98%) rename src/{ => bacnet/datalink}/mstp.c (91%) rename {include => src/bacnet/datalink}/mstp.h (99%) rename {include => src/bacnet/datalink}/mstpdef.h (99%) rename src/{ => bacnet/datalink}/mstptext.c (53%) rename {include => src/bacnet/datalink}/mstptext.h (100%) rename src/{ => bacnet}/datetime.c (84%) rename {include => src/bacnet}/datetime.h (92%) rename src/{ => bacnet}/dcc.c (79%) rename {include => src/bacnet}/dcc.h (98%) rename src/{ => bacnet}/event.c (66%) rename {include => src/bacnet}/event.h (98%) rename src/{ => bacnet}/get_alarm_sum.c (86%) rename {include => src/bacnet}/get_alarm_sum.h (97%) rename src/{ => bacnet}/getevent.c (65%) rename {include => src/bacnet}/getevent.h (96%) rename src/{ => bacnet}/iam.c (75%) mode change 100755 => 100644 rename {include => src/bacnet}/iam.h (96%) rename src/{ => bacnet}/ihave.c (77%) rename {include => src/bacnet}/ihave.h (98%) rename src/{ => bacnet}/indtext.c (75%) rename {include => src/bacnet}/indtext.h (100%) rename src/{ => bacnet}/lighting.c (85%) rename {include => src/bacnet}/lighting.h (99%) rename src/{ => bacnet}/lso.c (82%) rename {include => src/bacnet}/lso.h (96%) rename src/{ => bacnet}/memcopy.c (93%) rename {include => src/bacnet}/memcopy.h (100%) rename src/{ => bacnet}/npdu.c (92%) rename {include => src/bacnet}/npdu.h (98%) create mode 100644 src/bacnet/property.c rename include/proplist.h => src/bacnet/property.h (76%) create mode 100644 src/bacnet/proplist.c rename ports/linux/timer.h => src/bacnet/proplist.h (63%) rename src/{ => bacnet}/ptransfer.c (71%) rename {include => src/bacnet}/ptransfer.h (100%) rename src/{ => bacnet}/rd.c (77%) rename {include => src/bacnet}/rd.h (99%) rename src/{ => bacnet}/readrange.c (70%) rename {include => src/bacnet}/readrange.h (99%) rename src/{ => bacnet}/reject.c (85%) rename {include => src/bacnet}/reject.h (98%) rename src/{ => bacnet}/rp.c (79%) rename {include => src/bacnet}/rp.h (98%) rename src/{ => bacnet}/rpm.c (74%) rename {include => src/bacnet}/rpm.h (98%) rename src/{ => bacnet}/timestamp.c (73%) rename {include => src/bacnet}/timestamp.h (97%) rename src/{ => bacnet}/timesync.c (71%) rename {include => src/bacnet}/timesync.h (99%) rename {include => src/bacnet}/version.h (93%) rename src/{ => bacnet}/whohas.c (75%) rename {include => src/bacnet}/whohas.h (99%) rename src/{ => bacnet}/whois.c (86%) rename {include => src/bacnet}/whois.h (100%) rename src/{ => bacnet}/wp.c (80%) rename {include => src/bacnet}/wp.h (98%) rename src/{ => bacnet}/wpm.c (81%) rename {include => src/bacnet}/wpm.h (98%) delete mode 100644 src/bactext.c delete mode 100644 src/proplist.c delete mode 100644 src/version.c delete mode 100644 svn2cl.xsl create mode 100644 test/datetime.cbp diff --git a/.clang-format b/.clang-format index 2e98edb4..d5f24a0e 100644 --- a/.clang-format +++ b/.clang-format @@ -1,10 +1,18 @@ --- -BasedOnStyle: Google +BasedOnStyle: WebKit +BinPackParameters: false +AlignEscapedNewlines: Left +PointerAlignment: Right AllowShortFunctionsOnASingleLine: None AllowShortIfStatementsOnASingleLine: false AllowShortLoopsOnASingleLine: false -AlwaysBreakAfterReturnType: None BreakBeforeBraces: Linux +BreakBeforeBinaryOperators: None +KeepEmptyLinesAtTheStartOfBlocks: false +PenaltyBreakBeforeFirstCallParameter: 1 +IndentCaseLabels: true IndentWidth: 4 +UseTab: Never SortIncludes: false +ColumnLimit: 80 ... diff --git a/.gitattributes b/.gitattributes index 77d021ca..c20713d7 100644 --- a/.gitattributes +++ b/.gitattributes @@ -4,19 +4,29 @@ # Explicitly declare text files you want to always be normalized and converted # to native line endings on checkout. *.c text +*.cpp text +*.cxx text *.h text +*.hpp text *.s text Makefile.* text Makefile text *.mak text *.MAK text *.xml text +*.aps text *.mcp text +*.hwp text *.lkr text *.lua text *.txt text +*.htm text .cproject text .project text +.gdbinit text +.slintrc text +*.sh text +README.* text # Declare files that will always have CRLF line endings on checkout. *.sln text eol=crlf diff --git a/.gitignore b/.gitignore index f0f06099..15ca8962 100644 --- a/.gitignore +++ b/.gitignore @@ -17,6 +17,7 @@ *.config *.pbd *.ewd +*.ewt *.d *.r90 *.r90 @@ -44,5 +45,15 @@ *.hex *.elf *.emSession +*.depend +*.layout tags test-results.xml +.vscode/ +.vs/ +Debug/ +settings/ +*.componentinfo.xml +bin/ +Backup* +BACnet_BDT_table diff --git a/.hgeol b/.hgeol deleted file mode 100644 index b6910a22..00000000 --- a/.hgeol +++ /dev/null @@ -1,2 +0,0 @@ -[patterns] -** = native diff --git a/.hgignore b/.hgignore deleted file mode 100644 index f51507bf..00000000 --- a/.hgignore +++ /dev/null @@ -1,40 +0,0 @@ -# use glob syntax. -syntax: glob - -*.o -*.exe -*.bak -*~ -*.dep -*.orig -*.hex -*.map -*.bin -*.out -*.sim -*.dbgdt -*.dni -*.jlink -*.wsdt -*.config -*.pbd -*.ewd -*.d -*.r90 -*.s90 -*.pbi -*.cap -*.pcapng -*.pcap -*.patch -*.suo -*.sdf -*.lastbuildstate -*.obj -*.pdb -*.tlog -*.log -*.idb -*.lib -*.ilk -*.opendb diff --git a/Makefile b/Makefile index a1b9e9d2..31e3cb19 100644 --- a/Makefile +++ b/Makefile @@ -1,144 +1,127 @@ -# Main Makefile for BACnet-stack project with GCC - -# tools - only if you need them. -# Most platforms have this already defined -# CC = gcc -# AR = ar -# MAKE = make -# SIZE = size -# -# Assumes rm and cp are available - -# configuration -# If BACNET_DEFINES has not already been set, configure to your needs here -MY_BACNET_DEFINES = -DPRINT_ENABLED=1 -MY_BACNET_DEFINES += -DBACAPP_ALL -MY_BACNET_DEFINES += -DBACFILE -MY_BACNET_DEFINES += -DINTRINSIC_REPORTING -MY_BACNET_DEFINES += -DBACNET_TIME_MASTER -MY_BACNET_DEFINES += -DBACNET_PROPERTY_LISTS=1 -MY_BACNET_DEFINES += -DBACNET_PROTOCOL_REVISION=17 -BACNET_DEFINES ?= $(MY_BACNET_DEFINES) - -# un-comment the next line to build in uci integration -#BACNET_DEFINES += -DBAC_UCI -#UCI_LIB_DIR ?= /usr/local/lib - -#BACDL_DEFINE=-DBACDL_ETHERNET=1 -#BACDL_DEFINE=-DBACDL_ARCNET=1 -#BACDL_DEFINE=-DBACDL_MSTP=1 -BACDL_DEFINE?=-DBACDL_BIP=1 - -# Declare your level of BBMD support -BBMD_DEFINE ?=-DBBMD_ENABLED=1 -#BBMD_DEFINE ?= -DBBMD_ENABLED=0 -#BBMD_DEFINE ?= -DBBMD_CLIENT_ENABLED - -# Passing parameters via command line -MAKE_DEFINE ?= - -# Define WEAK_FUNC for [...somebody help here; I can't find any uses of it] -DEFINES = $(BACNET_DEFINES) $(BACDL_DEFINE) $(BBMD_DEFINE) -DWEAK_FUNC= -DEFINES += $(MAKE_DEFINE) - -# BACnet Ports Directory -BACNET_PORT ?= linux - -# Default compiler settings -OPTIMIZATION = -Os -DEBUGGING = -WARNINGS = -Wall -Wmissing-prototypes -ifeq (${BUILD},debug) -OPTIMIZATION = -O0 -DEBUGGING = -g -DDEBUG_ENABLED=1 -ifeq (${BACDL_DEFINE},-DBACDL_BIP=1) -DEFINES += -DBIP_DEBUG -endif -endif -CFLAGS = $(WARNINGS) $(DEBUGGING) $(OPTIMIZATION) $(STANDARDS) $(INCLUDES) $(DEFINES) +# Main Makefile for BACnet-stack applications, tests, and sample ports # Export the variables defined here to all subprocesses # (see http://www.gnu.org/software/automake/manual/make/Special-Targets.html) .EXPORT_ALL_VARIABLES: -all: library demos router-ipv6 ${DEMO_LINUX} -.PHONY : all library demos router gateway router-ipv6 clean test +# all: demos router-ipv6 ${DEMO_LINUX} -library: - $(MAKE) -s -C lib all +.PHONY: all +all: apps -demos: - $(MAKE) -C demo all +.PHONY: win32 +win32: + $(MAKE) BACNET_PORT=win32 -C apps all -gateway: - $(MAKE) -B -s -C demo gateway - -server: - $(MAKE) -j -B -C demo server - -mstpcap: - $(MAKE) -B -C demo mstpcap - -mstpcrc: library - $(MAKE) -B -C demo mstpcrc - -iam: - $(MAKE) -B -C demo iam - -uevent: - $(MAKE) -B -C demo uevent - -writepropm: - $(MAKE) -s -B -C demo writepropm +.PHONY: apps +apps: + $(MAKE) -s -C apps all +.PHONY: abort abort: - $(MAKE) -B -C demo abort + $(MAKE) -s -C apps $@ +.PHONY: dcc +dcc: + $(MAKE) -s -C apps $@ + +.PHONY: epics +epics: + $(MAKE) -s -C apps $@ + +.PHONY: error error: - $(MAKE) -B -C demo error + $(MAKE) -s -C apps $@ -router: library - $(MAKE) -s -C demo router +.PHONY: iam +iam: + $(MAKE) -s -C apps $@ -router-ipv6: library - $(MAKE) -B -s -C demo router-ipv6 +.PHONY: getevent +getevent: + $(MAKE) -s -C apps $@ + +.PHONY: gateway +gateway: + $(MAKE) -s -C apps $@ + +.PHONY: server +server: + $(MAKE) -s -C apps $@ + +.PHONY: mstpcap +mstpcap: + $(MAKE) -s -C apps $@ + +.PHONY: mstpcrc +mstpcrc: + $(MAKE) -s -C apps $@ + +.PHONY: uevent +uevent: + $(MAKE) -s -C apps $@ + +.PHONY: writepropm +writepropm: + $(MAKE) -s -C apps $@ + +.PHONY: router +router: + $(MAKE) -s -C apps $@ + +.PHONY: router-ipv6 +router-ipv6: + $(MAKE) -s -C apps $@ # Add "ports" to the build, if desired +.PHONY: ports ports: atmega168 bdk-atxx4-mstp at91sam7s stm32f10x @echo "Built the ARM7 and AVR ports" +.PHONY: atmega168 atmega168: ports/atmega168/Makefile $(MAKE) -s -C ports/atmega168 clean all +.PHONY: at91sam7s at91sam7s: ports/at91sam7s/Makefile $(MAKE) -s -C ports/at91sam7s clean all +.PHONY: stm32f10x stm32f10x: ports/stm32f10x/Makefile $(MAKE) -s -C ports/stm32f10x clean all +.PHONY: mstpsnap mstpsnap: ports/linux/mstpsnap.mak $(MAKE) -s -C ports/linux -f mstpsnap.mak clean all +.PHONY: bdk-atxx4-mstp bdk-atxx4-mstp: ports/bdk-atxx4-mstp/Makefile $(MAKE) -s -C ports/bdk-atxx4-mstp clean all +.PHONY: pretty pretty: - find ./src -iname *.h -o -iname *.c -exec clang-format -i -style=file -fallback-style=none {} \; - find ./include -iname *.h -o -iname *.c -exec clang-format -i -style=file -fallback-style=none {} \; - find ./demo -iname *.h -o -iname *.c -exec clang-format -i -style=file -fallback-style=none {} \; + find ./src -iname *.h -o -iname *.c -exec \ + clang-format -i -style=file -fallback-style=none {} \; + find ./apps -iname *.h -o -iname *.c -exec \ + clang-format -i -style=file -fallback-style=none {} \; +.PHONY : tidy +tidy: + find ./src -iname *.h -o -iname *.c -exec \ + clang-tidy {} -fix-errors -checks="readability-braces-around-statements" \ + -- -Isrc -Iports/linux \; + +.PHONY: clean clean: - $(MAKE) -s -C lib clean - $(MAKE) -s -C demo clean - $(MAKE) -s -C demo/router clean - $(MAKE) -s -C demo/router-ipv6 clean - $(MAKE) -s -C demo/gateway clean + $(MAKE) -s -C src clean + $(MAKE) -s -C apps clean + $(MAKE) -s -C apps/router clean + $(MAKE) -s -C apps/router-ipv6 clean + $(MAKE) -s -C apps/gateway clean +.PHONY: test test: $(MAKE) -s -C test clean $(MAKE) -s -C test all $(MAKE) -s -C test report - $(MAKE) -s -C demo/object clean - $(MAKE) -s -C demo/object all - $(MAKE) -s -C demo/object report diff --git a/README.md b/README.md index 08008ad9..9c5a2b6e 100644 --- a/README.md +++ b/README.md @@ -103,8 +103,7 @@ http://lists.sourceforge.net/mailman/listinfo/bacnet-developers I hope that you get your BACnet Device working! If not, join us on the mailing list and we can help. -Steve Karg -Birmingham, Alabama USA +Steve Karg, Birmingham, Alabama USA skarg@users.sourceforge.net ASHRAE® and BACnet® are registered trademarks of the diff --git a/apps/Makefile b/apps/Makefile new file mode 100644 index 00000000..0e221792 --- /dev/null +++ b/apps/Makefile @@ -0,0 +1,275 @@ +# tools - only if you need them. +# Most platforms have this already defined +# CC = gcc +# AR = ar +# MAKE = make +# SIZE = size +# +# Assumes rm and cp are available + +# Passing parameters via command line or from Makefile export to this one +BACNET_DEFINES ?= +BACNET_LIB ?= + +# choose a datalink to build the example applications +# Use BACDL=mstp or BACDL=bip and BBMD=server when invoking make + +ifeq (${BACDL_DEFINE},) +ifeq (${BACDL},ethernet) +BACDL_DEFINE=-DBACDL_ETHERNET=1 +endif +ifeq (${BACDL},arcnet) +BACDL_DEFINE=-DBACDL_ARCNET=1 +endif +ifeq (${BACDL},mstp) +BACDL_DEFINE=-DBACDL_MSTP=1 +endif +ifeq (${BACDL},bip) +BACDL_DEFINE=-DBACDL_BIP=1 +endif +ifeq (${BACDL},bip6) +BACDL_DEFINE=-DBACDL_BIP6=1 +endif +ifeq (${BACDL},) +BACDL_DEFINE ?= -DBACDL_BIP=1 +BBMD_DEFINE ?= -DBBMD_ENABLED=1 +endif + +ifeq (${BBMD},server) +BBMD_DEFINE=-DBBMD_ENABLED=1 +endif +ifeq (${BBMD},client) +BBMD_DEFINE=-DBBMD_ENABLED=1 +BBMD_DEFINE=-DBBMD_CLIENT_ENABLED +endif +endif + +# Define WEAK_FUNC for unsupported or specific compilers +BACNET_DEFINES += $(BACDL_DEFINE) +BACNET_DEFINES += $(BBMD_DEFINE) +BACNET_DEFINES += -DWEAK_FUNC= +BACNET_DEFINES += $(MAKE_DEFINE) + +# Choose a BACnet Ports Directory for the example applications target OS +# linux, win32, bsd +BACNET_PORT ?= linux + +# build in uci integration - use UCI=1 when invoking make +ifeq (${UCI},1) +BACNET_DEFINES += -DBAC_UCI +UCI_LIB_DIR ?= /usr/local/lib +BACNET_LIB += -L$(UCI_LIB_DIR),-luci +endif +# OS specific builds +ifeq (${BACNET_PORT},linux) +PFLAGS = -pthread +TARGET_EXT = +SYSTEM_LIB=-lc,-lgcc,-lrt,-lm +endif +ifeq (${BACNET_PORT},bsd) +PFLAGS = -pthread +TARGET_EXT = +SYSTEM_LIB=-lc,-lm +endif +ifeq (${BACNET_PORT},win32) +TARGET_EXT = .exe +SYSTEM_LIB=-lws2_32,-lgcc,-lm,-liphlpapi,-lwinmm +BACNET_DEFINES += -D_NO_OLDNAMES +endif + +# source file locations +BACNET_PORT_DIR = $(realpath ../ports/$(BACNET_PORT)) +BACNET_SRC_DIR = $(realpath ../src) + +#build for release (default) or debug +OPTIMIZATION ?= -Os +DEBUGGING ?= +WARNINGS ?= -Wall -Wmissing-prototypes +# dead code removal +ifeq (${BUILD},debug) +OPTIMIZATION = -O0 +DEBUGGING = -g -DDEBUG_ENABLED=1 +ifeq (${BACDL_DEFINE},-DBACDL_BIP=1) +BACNET_DEFINES += -DBIP_DEBUG +endif +endif + +# If BACNET_DEFINES has not already been set, configure to your needs here +BACNET_DEFINES ?= +BACNET_DEFINES += -DPRINT_ENABLED=1 +BACNET_DEFINES += -DBACAPP_ALL +BACNET_DEFINES += -DBACFILE +BACNET_DEFINES += -DINTRINSIC_REPORTING +BACNET_DEFINES += -DBACNET_TIME_MASTER +BACNET_DEFINES += -DBACNET_PROPERTY_LISTS=1 +BACNET_DEFINES += -DBACNET_PROTOCOL_REVISION=17 + +# put all the flags together +INCLUDES = -I$(BACNET_SRC_DIR) -I$(BACNET_PORT_DIR) +CFLAGS += $(WARNINGS) $(DEBUGGING) $(OPTIMIZATION) $(BACNET_DEFINES) $(INCLUDES) +LFLAGS += -Wl,$(SYSTEM_LIB) +ifneq (${BACNET_LIB},) +LFLAGS += -Wl,$(BACNET_LIB) +endif +# GCC dead code removal +CFLAGS += -ffunction-sections -fdata-sections +LFLAGS += -Wl,--gc-sections + +PORT_ARCNET_SRC = \ + $(BACNET_PORT_DIR)/arcnet.c + +PORT_MSTP_SRC = \ + $(BACNET_PORT_DIR)/rs485.c \ + $(BACNET_PORT_DIR)/dlmstp.c \ + $(BACNET_SRC_DIR)/bacnet/datalink/mstp.c \ + $(BACNET_SRC_DIR)/bacnet/datalink/mstptext.c \ + $(BACNET_SRC_DIR)/bacnet/datalink/crc.c + +PORT_ETHERNET_SRC = \ + $(BACNET_PORT_DIR)/ethernet.c + +PORT_BIP_SRC = \ + $(BACNET_PORT_DIR)/bip-init.c \ + $(BACNET_SRC_DIR)/bacnet/datalink/bvlc.c \ + $(BACNET_SRC_DIR)/bacnet/datalink/bip.c + +PORT_BIP6_SRC = \ + $(BACNET_PORT_DIR)/bip6.c \ + $(BACNET_SRC_DIR)/bacnet/basic/bbmd6/h_bbmd6.c \ + $(BACNET_SRC_DIR)/bacnet/basic/bbmd6/vmac.c \ + $(BACNET_SRC_DIR)/bacnet/datalink/bvlc6.c + +PORT_ALL_SRC = \ + $(BACNET_SRC_DIR)/bacnet/datalink/datalink.c \ + $(PORT_ARCNET_SRC) \ + $(PORT_MSTP_SRC) \ + $(PORT_ETHERNET_SRC) \ + $(PORT_BIP_SRC) \ + $(PORT_BIP6_SRC) + +ifeq (${BACDL_DEFINE},-DBACDL_BIP=1) +BACNET_PORT_SRC = ${PORT_BIP_SRC} +endif +ifeq (${BACDL_DEFINE},-DBACDL_BIP6=1) +BACNET_PORT_SRC = ${PORT_BIP6_SRC} +endif +ifeq (${BACDL_DEFINE},-DBACDL_MSTP=1) +BACNET_PORT_SRC = ${PORT_MSTP_SRC} +endif +ifeq (${BACDL_DEFINE},-DBACDL_ARCNET=1) +BACNET_PORT_SRC = ${PORT_ARCNET_SRC} +endif +ifeq (${BACDL_DEFINE},-DBACDL_ETHERNET=1) +BACNET_PORT_SRC = ${PORT_ETHERNET_SRC} +endif +ifdef BACDL_ALL +BACNET_PORT_SRC = ${PORT_ALL_SRC} +endif + +BACNET_PORT_SRC += \ + $(BACNET_SRC_DIR)/bacnet/datalink/dlenv.c \ + $(BACNET_PORT_DIR)/mstimer-init.c \ + $(BACNET_PORT_DIR)/datetime-init.c \ + +BACNET_SRC ?= \ + $(wildcard $(BACNET_SRC_DIR)/bacnet/*.c) \ + +BACNET_BASIC_SRC ?= \ + $(wildcard $(BACNET_SRC_DIR)/bacnet/basic/*.c) \ + $(wildcard $(BACNET_SRC_DIR)/bacnet/basic/binding/*.c) \ + $(wildcard $(BACNET_SRC_DIR)/bacnet/basic/sys/*.c) \ + $(BACNET_SRC_DIR)/bacnet/basic/npdu/h_npdu.c \ + $(BACNET_SRC_DIR)/bacnet/basic/npdu/s_router.c \ + $(BACNET_SRC_DIR)/bacnet/basic/tsm/tsm.c + +.EXPORT_ALL_VARIABLES: + +SUBDIRS = readprop writeprop readfile writefile reinit server dcc \ + whohas whois iam ucov scov timesync epics readpropm readrange \ + writepropm uptransfer getevent uevent abort error + +ifeq (${BACDL_DEFINE},-DBACDL_BIP=1) + SUBDIRS += whoisrouter iamrouter initrouter readbdt +endif + +ifeq (${BACNET_PORT},linux) +ifneq (${OSTYPE},cygwin) + SUBDIRS += mstpcap mstpcrc +endif +endif + +ifeq (${BACNET_PORT},win32) + SUBDIRS += mstpcap mstpcrc +endif + +.PHONY: all clean +TARGETS = all clean + +$(TARGETS): %: $(patsubst %, %.%, $(SUBDIRS)) + +$(foreach TGT, $(TARGETS), $(patsubst %, %.$(TGT), $(SUBDIRS))): + $(MAKE) -b -C $(subst ., , $@) + +.PHONY: gateway +gateway: + $(MAKE) -s -b -C gateway + +.PHONY: server +server: + $(MAKE) -s -b -C $@ + +.PHONY: mstpcap +mstpcap: + $(MAKE) -b -C $@ + +.PHONY: mstpcrc +mstpcrc: + $(MAKE) -b -C $@ + +.PHONY: abort +abort: + $(MAKE) -b -C $@ + +.PHONY: dcc +dcc: + $(MAKE) -b -C $@ + +.PHONY: epics +epics: + $(MAKE) -b -C $@ + +.PHONY: error +error: + $(MAKE) -b -C $@ + +.PHONY: getevent +getevent: + $(MAKE) -b -C $@ + +.PHONY: iam +iam: + $(MAKE) -b -C $@ + +.PHONY: iamrouter +iamrouter: + $(MAKE) -b -C $@ + +.PHONY: initrouter +initrouter: + $(MAKE) -b -C $@ + +.PHONY: uevent +uevent: + $(MAKE) -b -C $@ + +.PHONY: router +router: + $(MAKE) -s -b -C $@ + +.PHONY: router-ipv6 +router-ipv6: + $(MAKE) -b -C $@ + +.PHONY: writepropm +writepropm: + $(MAKE) -b -C $@ diff --git a/apps/abort/Makefile b/apps/abort/Makefile new file mode 100644 index 00000000..2af36baf --- /dev/null +++ b/apps/abort/Makefile @@ -0,0 +1,50 @@ +#Makefile to build BACnet Application for the GCC port + +# Executable file name +TARGET = bacabort + +# BACnet objects that are used with this app +BACNET_OBJECT_DIR = $(BACNET_SRC_DIR)/bacnet/basic/object +SRC = main.c \ + $(BACNET_OBJECT_DIR)/client/device-client.c \ + $(BACNET_OBJECT_DIR)/netport.c +BACNET_BASIC_SRC += \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_apdu.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_iam.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_noserv.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_rp.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_whois.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/s_iam.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/s_abort.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/s_whois.c + +# TARGET_EXT is defined in apps/Makefile as .exe or nothing +TARGET_BIN = ${TARGET}$(TARGET_EXT) + +SRCS = $(SRC) $(BACNET_SRC) $(BACNET_BASIC_SRC) $(BACNET_PORT_SRC) + +OBJS += ${SRCS:.c=.o} + +.PHONY: all +all: Makefile ${TARGET_BIN} + +${TARGET_BIN}: ${OBJS} + ${CC} ${PFLAGS} ${OBJS} ${LFLAGS} -o $@ + size $@ + cp $@ ../../bin + +.c.o: + ${CC} -c ${CFLAGS} $*.c -o $@ + +.PHONY: depend +depend: + rm -f .depend + ${CC} -MM ${CFLAGS} *.c >> .depend + +.PHONY: clean +clean: + rm -f core ${TARGET_BIN} ${OBJS} $(TARGET).map + +.PHONY: include +include: .depend + diff --git a/demo/abort/main.c b/apps/abort/main.c similarity index 83% rename from demo/abort/main.c rename to apps/abort/main.c index c37ac02d..56b760e1 100644 --- a/demo/abort/main.c +++ b/apps/abort/main.c @@ -30,22 +30,21 @@ #include #include /* for time */ #include -#include "bactext.h" -#include "iam.h" -#include "address.h" -#include "config.h" -#include "bacdef.h" -#include "npdu.h" -#include "apdu.h" -#include "device.h" -#include "datalink.h" -#include "version.h" +#include "bacnet/bactext.h" +#include "bacnet/iam.h" +#include "bacnet/config.h" +#include "bacnet/bacdef.h" +#include "bacnet/npdu.h" +#include "bacnet/apdu.h" +#include "bacnet/version.h" /* some demo stuff needed */ -#include "filename.h" -#include "handlers.h" -#include "client.h" -#include "txbuf.h" -#include "dlenv.h" +#include "bacnet/basic/binding/address.h" +#include "bacnet/basic/object/device.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/sys/filename.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/datalink/datalink.h" +#include "bacnet/datalink/dlenv.h" /* parsed command line parameters */ static uint8_t Target_Invoke_ID = 1; @@ -54,8 +53,8 @@ static bool Target_Server = true; /* flag for signalling errors */ static bool Error_Detected = false; -void MyAbortHandler(BACNET_ADDRESS *src, uint8_t invoke_id, - uint8_t abort_reason, bool server) +static void MyAbortHandler( + BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t abort_reason, bool server) { (void)src; (void)invoke_id; @@ -64,8 +63,8 @@ void MyAbortHandler(BACNET_ADDRESS *src, uint8_t invoke_id, Error_Detected = true; } -void MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, - uint8_t reject_reason) +static void MyRejectHandler( + BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason) { (void)src; (void)invoke_id; @@ -83,8 +82,8 @@ static void Init_Service_Handlers(void) It is required to send the proper reject message... */ apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service); /* we must implement read property - it's required! */ - apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY, - handler_read_property); + apdu_set_confirmed_handler( + SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property); /* handle the reply (request) coming back */ apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_I_AM, handler_i_am_add); /* handle any errors coming back */ @@ -121,24 +120,23 @@ static void print_help(char *filename) "or an IP string with optional port number like 10.1.2.3:47808\n" "or an Ethernet MAC in hex like 00:21:70:7e:32:bb\n" "\n"); - printf( - "abort-reason:\n" - " number from 0 to 65535\n" - "invoke-id:\n" - " number from 1 to 255\n" - "server:\n" - " 0=false, 1=true\n" - "Example:\n" - "%s 3 2 1\n", + printf("abort-reason:\n" + " number from 0 to 65535\n" + "invoke-id:\n" + " number from 1 to 255\n" + "server:\n" + " 0=false, 1=true\n" + "Example:\n" + "%s 3 2 1\n", filename); } int main(int argc, char *argv[]) { long dnet = -1; - BACNET_MAC_ADDRESS mac = {0}; - BACNET_MAC_ADDRESS adr = {0}; - BACNET_ADDRESS dest = {0}; + BACNET_MAC_ADDRESS mac = { 0 }; + BACNET_MAC_ADDRESS adr = { 0 }; + BACNET_ADDRESS dest = { 0 }; bool specific_address = false; int argi = 0; unsigned int target_args = 0; @@ -153,12 +151,11 @@ int main(int argc, char *argv[]) } if (strcmp(argv[argi], "--version") == 0) { printf("%s %s\n", filename, BACNET_VERSION_TEXT); - printf( - "Copyright (C) 2016 by Steve Karg and others.\n" - "This is free software; see the source for copying " - "conditions.\n" - "There is NO warranty; not even for MERCHANTABILITY or\n" - "FITNESS FOR A PARTICULAR PURPOSE.\n"); + printf("Copyright (C) 2016 by Steve Karg and others.\n" + "This is free software; see the source for copying " + "conditions.\n" + "There is NO warranty; not even for MERCHANTABILITY or\n" + "FITNESS FOR A PARTICULAR PURPOSE.\n"); return 0; } if (strcmp(argv[argi], "--mac") == 0) { @@ -235,7 +232,7 @@ int main(int argc, char *argv[]) atexit(datalink_cleanup); /* send the request */ Send_Abort_To_Network(&Handler_Transmit_Buffer[0], &dest, Target_Invoke_ID, - Target_Abort_Reason, Target_Server); + Target_Abort_Reason, Target_Server); return 0; } diff --git a/apps/dcc/Makefile b/apps/dcc/Makefile new file mode 100644 index 00000000..366728ab --- /dev/null +++ b/apps/dcc/Makefile @@ -0,0 +1,50 @@ +#Makefile to build BACnet Application for GCC compiler + +TARGET = bacdcc + +# BACnet objects that are used with this app +BACNET_OBJECT_DIR = $(BACNET_SRC_DIR)/bacnet/basic/object +SRC = main.c \ + $(BACNET_OBJECT_DIR)/client/device-client.c \ + $(BACNET_OBJECT_DIR)/netport.c +BACNET_BASIC_SRC += \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_apdu.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_dcc.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_iam.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_noserv.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_rp.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_whois.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/s_iam.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/s_dcc.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/s_whois.c + +# TARGET_EXT is defined in apps/Makefile as .exe or nothing +TARGET_BIN = ${TARGET}$(TARGET_EXT) + +SRCS = $(SRC) $(BACNET_SRC) $(BACNET_BASIC_SRC) $(BACNET_PORT_SRC) + +OBJS += ${SRCS:.c=.o} + +.PHONY: all +all: Makefile ${TARGET_BIN} + +${TARGET_BIN}: ${OBJS} + ${CC} ${PFLAGS} ${OBJS} ${LFLAGS} -o $@ + size $@ + cp $@ ../../bin + +.c.o: + ${CC} -c ${CFLAGS} $*.c -o $@ + +.PHONY: depend +depend: + rm -f .depend + ${CC} -MM ${CFLAGS} *.c >> .depend + +.PHONY: clean +clean: + rm -f core ${TARGET_BIN} ${OBJS} $(TARGET).map + +.PHONY: include +include: .depend + diff --git a/demo/dcc/main.c b/apps/dcc/main.c similarity index 77% rename from demo/dcc/main.c rename to apps/dcc/main.c index 31d207ce..312499ae 100644 --- a/demo/dcc/main.c +++ b/apps/dcc/main.c @@ -30,30 +30,30 @@ #include #include /* for time */ #include -#include "bactext.h" -#include "iam.h" -#include "arf.h" -#include "tsm.h" -#include "address.h" -#include "config.h" -#include "bacdef.h" -#include "npdu.h" -#include "apdu.h" -#include "device.h" -#include "net.h" -#include "datalink.h" -#include "whois.h" -#include "dcc.h" -#include "version.h" +#include "bacnet/bactext.h" +#include "bacnet/iam.h" +#include "bacnet/arf.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/basic/binding/address.h" +#include "bacnet/config.h" +#include "bacnet/bacdef.h" +#include "bacnet/npdu.h" +#include "bacnet/apdu.h" +#include "bacnet/basic/object/device.h" +#include "bacport.h" +#include "bacnet/datalink/datalink.h" +#include "bacnet/whois.h" +#include "bacnet/dcc.h" +#include "bacnet/version.h" /* some demo stuff needed */ -#include "filename.h" -#include "handlers.h" -#include "client.h" -#include "txbuf.h" -#include "dlenv.h" +#include "bacnet/basic/sys/filename.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/datalink/dlenv.h" /* buffer used for receive */ -static uint8_t Rx_Buf[MAX_MPDU] = {0}; +static uint8_t Rx_Buf[MAX_MPDU] = { 0 }; /* global variables used in this file */ static uint32_t Target_Device_Object_Instance = BACNET_MAX_INSTANCE; @@ -65,20 +65,21 @@ static char *Communication_Password = NULL; static bool Error_Detected = false; -static void MyErrorHandler(BACNET_ADDRESS *src, uint8_t invoke_id, - BACNET_ERROR_CLASS error_class, - BACNET_ERROR_CODE error_code) +static void MyErrorHandler(BACNET_ADDRESS *src, + uint8_t invoke_id, + BACNET_ERROR_CLASS error_class, + BACNET_ERROR_CODE error_code) { /* FIXME: verify src and invoke id */ (void)src; (void)invoke_id; printf("BACnet Error: %s: %s\n", bactext_error_class_name(error_class), - bactext_error_code_name(error_code)); + bactext_error_code_name(error_code)); Error_Detected = true; } -void MyAbortHandler(BACNET_ADDRESS *src, uint8_t invoke_id, - uint8_t abort_reason, bool server) +static void MyAbortHandler( + BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t abort_reason, bool server) { /* FIXME: verify src and invoke id */ (void)src; @@ -88,8 +89,8 @@ void MyAbortHandler(BACNET_ADDRESS *src, uint8_t invoke_id, Error_Detected = true; } -void MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, - uint8_t reject_reason) +static void MyRejectHandler( + BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason) { /* FIXME: verify src and invoke id */ (void)src; @@ -98,8 +99,8 @@ void MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, Error_Detected = true; } -void MyDeviceCommunicationControlSimpleAckHandler(BACNET_ADDRESS *src, - uint8_t invoke_id) +static void MyDeviceCommunicationControlSimpleAckHandler( + BACNET_ADDRESS *src, uint8_t invoke_id) { (void)src; (void)invoke_id; @@ -118,18 +119,18 @@ static void Init_Service_Handlers(void) It is required to send the proper reject message... */ apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service); /* we must implement read property - it's required! */ - apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY, - handler_read_property); + apdu_set_confirmed_handler( + SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property); /* handle communication so we can shutup when asked */ apdu_set_confirmed_handler(SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL, - handler_device_communication_control); + handler_device_communication_control); /* handle the ack coming back */ apdu_set_confirmed_simple_ack_handler( SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL, MyDeviceCommunicationControlSimpleAckHandler); /* handle any errors coming back */ - apdu_set_error_handler(SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL, - MyErrorHandler); + apdu_set_error_handler( + SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL, MyErrorHandler); apdu_set_abort_handler(MyAbortHandler); apdu_set_reject_handler(MyRejectHandler); } @@ -162,7 +163,7 @@ static void print_help(char *filename) int main(int argc, char *argv[]) { - BACNET_ADDRESS src = {0}; /* address where message came from */ + BACNET_ADDRESS src = { 0 }; /* address where message came from */ uint16_t pdu_len = 0; unsigned timeout = 100; /* milliseconds */ unsigned max_apdu = 0; @@ -184,12 +185,11 @@ int main(int argc, char *argv[]) } if (strcmp(argv[argi], "--version") == 0) { printf("%s %s\n", filename, BACNET_VERSION_TEXT); - printf( - "Copyright (C) 2014 by Steve Karg and others.\n" - "This is free software; see the source for copying " - "conditions.\n" - "There is NO warranty; not even for MERCHANTABILITY or\n" - "FITNESS FOR A PARTICULAR PURPOSE.\n"); + printf("Copyright (C) 2014 by Steve Karg and others.\n" + "This is free software; see the source for copying " + "conditions.\n" + "There is NO warranty; not even for MERCHANTABILITY or\n" + "FITNESS FOR A PARTICULAR PURPOSE.\n"); return 0; } } @@ -210,7 +210,7 @@ int main(int argc, char *argv[]) } if (Target_Device_Object_Instance >= BACNET_MAX_INSTANCE) { fprintf(stderr, "device-instance=%u - it must be less than %u\n", - Target_Device_Object_Instance, BACNET_MAX_INSTANCE); + Target_Device_Object_Instance, BACNET_MAX_INSTANCE); return 1; } /* setup my info */ @@ -223,11 +223,11 @@ int main(int argc, char *argv[]) last_seconds = time(NULL); timeout_seconds = (apdu_timeout() / 1000) * apdu_retries(); /* try to bind with the device */ - found = address_bind_request(Target_Device_Object_Instance, &max_apdu, - &Target_Address); + found = address_bind_request( + Target_Device_Object_Instance, &max_apdu, &Target_Address); if (!found) { - Send_WhoIs(Target_Device_Object_Instance, - Target_Device_Object_Instance); + Send_WhoIs( + Target_Device_Object_Instance, Target_Device_Object_Instance); } /* loop forever */ for (;;) { @@ -242,15 +242,16 @@ int main(int argc, char *argv[]) npdu_handler(&src, &Rx_Buf[0], pdu_len); } /* at least one second has passed */ - if (current_seconds != last_seconds) + if (current_seconds != last_seconds) { tsm_timer_milliseconds( (uint16_t)((current_seconds - last_seconds) * 1000)); + } if (Error_Detected) break; /* wait until the device is bound, or timeout and quit */ if (!found) { - found = address_bind_request(Target_Device_Object_Instance, - &max_apdu, &Target_Address); + found = address_bind_request( + Target_Device_Object_Instance, &max_apdu, &Target_Address); } if (found) { if (invoke_id == 0) { @@ -258,9 +259,9 @@ int main(int argc, char *argv[]) Target_Device_Object_Instance, Communication_Timeout_Minutes, Communication_State, Communication_Password); - } else if (tsm_invoke_id_free(invoke_id)) + } else if (tsm_invoke_id_free(invoke_id)) { break; - else if (tsm_invoke_id_failed(invoke_id)) { + } else if (tsm_invoke_id_failed(invoke_id)) { fprintf(stderr, "\rError: TSM Timeout!\n"); tsm_free_invoke_id(invoke_id); /* try again or abort? */ diff --git a/apps/epics/Makefile b/apps/epics/Makefile new file mode 100644 index 00000000..cdaea94b --- /dev/null +++ b/apps/epics/Makefile @@ -0,0 +1,50 @@ +#Makefile to build BACnet Application for the Linux Port + +TARGET = bacepics +BACNET_OBJECT_DIR = $(BACNET_SRC_DIR)/bacnet/basic/object +SRC = main.c \ + $(BACNET_OBJECT_DIR)/client/device-client.c \ + $(BACNET_OBJECT_DIR)/netport.c +BACNET_BASIC_SRC += \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_apdu.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_iam.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_noserv.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_rp.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_rp_a.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_rpm_a.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_whois.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/s_iam.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/s_rp.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/s_rpm.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/s_whois.c + +# TARGET_EXT is defined in apps/Makefile as .exe or nothing +TARGET_BIN = ${TARGET}$(TARGET_EXT) + +SRCS = $(SRC) $(BACNET_SRC) $(BACNET_BASIC_SRC) $(BACNET_PORT_SRC) + +OBJS += ${SRCS:.c=.o} + +.PHONY: all +all: Makefile ${TARGET_BIN} + +${TARGET_BIN}: ${OBJS} + ${CC} ${PFLAGS} ${OBJS} ${LFLAGS} -o $@ + size $@ + cp $@ ../../bin + +.c.o: + ${CC} -c ${CFLAGS} $*.c -o $@ + +.PHONY: depend +depend: + rm -f .depend + ${CC} -MM ${CFLAGS} *.c >> .depend + +.PHONY: clean +clean: + rm -f core ${TARGET_BIN} ${OBJS} $(TARGET).map + +.PHONY: include +include: .depend + diff --git a/apps/epics/bacepics.cbp b/apps/epics/bacepics.cbp new file mode 100644 index 00000000..2826df81 --- /dev/null +++ b/apps/epics/bacepics.cbp @@ -0,0 +1,305 @@ + + + + + + diff --git a/demo/epics/bacepics.h b/apps/epics/bacepics.h old mode 100755 new mode 100644 similarity index 100% rename from demo/epics/bacepics.h rename to apps/epics/bacepics.h diff --git a/demo/epics/main.c b/apps/epics/main.c similarity index 88% rename from demo/epics/main.c rename to apps/epics/main.c index a0b185e9..41090959 100644 --- a/demo/epics/main.c +++ b/apps/epics/main.c @@ -33,29 +33,30 @@ #include /* for time */ #include #include -#include "config.h" -#include "bactext.h" -#include "iam.h" -#include "arf.h" -#include "tsm.h" -#include "address.h" -#include "bacdef.h" -#include "npdu.h" -#include "apdu.h" -#include "device.h" -#include "net.h" -#include "datalink.h" -#include "whois.h" -#include "rp.h" -#include "proplist.h" -#include "version.h" +#include "bacnet/config.h" +#include "bacnet/bactext.h" +#include "bacnet/iam.h" +#include "bacnet/arf.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/bacdef.h" +#include "bacnet/npdu.h" +#include "bacnet/apdu.h" +#include "bacport.h" +#include "bacnet/whois.h" +#include "bacnet/rp.h" +#include "bacnet/proplist.h" +#include "bacnet/property.h" +#include "bacnet/version.h" /* some demo stuff needed */ -#include "filename.h" -#include "handlers.h" -#include "client.h" -#include "txbuf.h" -#include "dlenv.h" -#include "keylist.h" +#include "bacnet/basic/binding/address.h" +#include "bacnet/basic/object/device.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/sys/filename.h" +#include "bacnet/basic/sys/keylist.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/datalink/datalink.h" +#include "bacnet/datalink/dlenv.h" #include "bacepics.h" /* (Doxygen note: The next two lines pull all the following Javadoc @@ -71,7 +72,7 @@ */ /* buffer used for receive */ -static uint8_t Rx_Buf[MAX_MPDU] = {0}; +static uint8_t Rx_Buf[MAX_MPDU] = { 0 }; /* target information converted from command line */ static uint32_t Target_Device_Object_Instance = BACNET_MAX_INSTANCE; @@ -132,13 +133,12 @@ struct property_value_list_t { BACNET_APPLICATION_DATA_VALUE *value; }; static struct property_value_list_t Property_Value_List[] = { - {PROP_VENDOR_NAME, NULL}, - {PROP_MODEL_NAME, NULL}, - {PROP_MAX_APDU_LENGTH_ACCEPTED, NULL}, - {PROP_PROTOCOL_SERVICES_SUPPORTED, NULL}, - {PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED, NULL}, - {PROP_DESCRIPTION, NULL}, - {-1, NULL}}; + { PROP_VENDOR_NAME, NULL }, { PROP_MODEL_NAME, NULL }, + { PROP_MAX_APDU_LENGTH_ACCEPTED, NULL }, + { PROP_PROTOCOL_SERVICES_SUPPORTED, NULL }, + { PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED, NULL }, { PROP_DESCRIPTION, NULL }, + { -1, NULL } +}; static BACNET_APPLICATION_DATA_VALUE *object_property_value(int32_t property_id) { @@ -177,17 +177,18 @@ static bool Optional_Properties = false; #define PRINT_ERRORS 1 #endif -static void MyErrorHandler(BACNET_ADDRESS *src, uint8_t invoke_id, - BACNET_ERROR_CLASS error_class, - BACNET_ERROR_CODE error_code) +static void MyErrorHandler(BACNET_ADDRESS *src, + uint8_t invoke_id, + BACNET_ERROR_CLASS error_class, + BACNET_ERROR_CODE error_code) { if (address_match(&Target_Address, src) && (invoke_id == Request_Invoke_ID)) { #if PRINT_ERRORS if (ShowValues) { fprintf(stderr, "-- BACnet Error: %s: %s\n", - bactext_error_class_name(error_class), - bactext_error_code_name(error_code)); + bactext_error_class_name(error_class), + bactext_error_code_name(error_code)); } #endif Error_Detected = true; @@ -196,8 +197,8 @@ static void MyErrorHandler(BACNET_ADDRESS *src, uint8_t invoke_id, } } -void MyAbortHandler(BACNET_ADDRESS *src, uint8_t invoke_id, - uint8_t abort_reason, bool server) +static void MyAbortHandler( + BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t abort_reason, bool server) { (void)server; if (address_match(&Target_Address, src) && @@ -206,7 +207,7 @@ void MyAbortHandler(BACNET_ADDRESS *src, uint8_t invoke_id, /* It is normal for this to fail, so don't print. */ if ((myState != GET_ALL_RESPONSE) && !IsLongArray && ShowValues) { fprintf(stderr, "-- BACnet Abort: %s \n", - bactext_abort_reason_name(abort_reason)); + bactext_abort_reason_name(abort_reason)); } #endif Error_Detected = true; @@ -219,15 +220,15 @@ void MyAbortHandler(BACNET_ADDRESS *src, uint8_t invoke_id, } } -void MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, - uint8_t reject_reason) +static void MyRejectHandler( + BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason) { if (address_match(&Target_Address, src) && (invoke_id == Request_Invoke_ID)) { #if PRINT_ERRORS if (ShowValues) { fprintf(stderr, "BACnet Reject: %s\n", - bactext_reject_reason_name(reject_reason)); + bactext_reject_reason_name(reject_reason)); } #endif Error_Detected = true; @@ -240,9 +241,10 @@ void MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, } } -void MyReadPropertyAckHandler(uint8_t *service_request, uint16_t service_len, - BACNET_ADDRESS *src, - BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data) +static void MyReadPropertyAckHandler(uint8_t *service_request, + uint16_t service_len, + BACNET_ADDRESS *src, + BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data) { int len = 0; BACNET_READ_ACCESS_DATA *rp_data; @@ -251,12 +253,12 @@ void MyReadPropertyAckHandler(uint8_t *service_request, uint16_t service_len, (service_data->invoke_id == Request_Invoke_ID)) { rp_data = calloc(1, sizeof(BACNET_READ_ACCESS_DATA)); if (rp_data) { - len = rp_ack_fully_decode_service_request(service_request, - service_len, rp_data); + len = rp_ack_fully_decode_service_request( + service_request, service_len, rp_data); } if (len > 0) { memmove(&Read_Property_Multiple_Data.service_data, service_data, - sizeof(BACNET_CONFIRMED_SERVICE_ACK_DATA)); + sizeof(BACNET_CONFIRMED_SERVICE_ACK_DATA)); Read_Property_Multiple_Data.rpm_data = rp_data; Read_Property_Multiple_Data.new_data = true; } else { @@ -267,8 +269,9 @@ void MyReadPropertyAckHandler(uint8_t *service_request, uint16_t service_len, } } -void MyReadPropertyMultipleAckHandler( - uint8_t *service_request, uint16_t service_len, BACNET_ADDRESS *src, +static void MyReadPropertyMultipleAckHandler(uint8_t *service_request, + uint16_t service_len, + BACNET_ADDRESS *src, BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data) { int len = 0; @@ -278,12 +281,12 @@ void MyReadPropertyMultipleAckHandler( (service_data->invoke_id == Request_Invoke_ID)) { rpm_data = calloc(1, sizeof(BACNET_READ_ACCESS_DATA)); if (rpm_data) { - len = rpm_ack_decode_service_request(service_request, service_len, - rpm_data); + len = rpm_ack_decode_service_request( + service_request, service_len, rpm_data); } if (len > 0) { memmove(&Read_Property_Multiple_Data.service_data, service_data, - sizeof(BACNET_CONFIRMED_SERVICE_ACK_DATA)); + sizeof(BACNET_CONFIRMED_SERVICE_ACK_DATA)); Read_Property_Multiple_Data.rpm_data = rpm_data; Read_Property_Multiple_Data.new_data = true; /* Will process and free the RPM data later */ @@ -317,13 +320,13 @@ static void Init_Service_Handlers(void) It is required to send the proper reject message... */ apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service); /* we must implement read property - it's required! */ - apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY, - handler_read_property); + apdu_set_confirmed_handler( + SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property); /* handle the data coming back from confirmed requests */ - apdu_set_confirmed_ack_handler(SERVICE_CONFIRMED_READ_PROPERTY, - MyReadPropertyAckHandler); - apdu_set_confirmed_ack_handler(SERVICE_CONFIRMED_READ_PROP_MULTIPLE, - MyReadPropertyMultipleAckHandler); + apdu_set_confirmed_ack_handler( + SERVICE_CONFIRMED_READ_PROPERTY, MyReadPropertyAckHandler); + apdu_set_confirmed_ack_handler( + SERVICE_CONFIRMED_READ_PROP_MULTIPLE, MyReadPropertyMultipleAckHandler); /* handle any errors coming back */ apdu_set_error_handler(SERVICE_CONFIRMED_READ_PROPERTY, MyErrorHandler); apdu_set_abort_handler(MyAbortHandler); @@ -339,9 +342,9 @@ static void Init_Service_Handlers(void) * @param rpm_property [in] Points to structure holding the Property, * Value, and Error information. */ -void CheckIsWritableProperty(BACNET_OBJECT_TYPE object_type, - /* uint32_t object_instance, */ - BACNET_PROPERTY_REFERENCE *rpm_property) +static void CheckIsWritableProperty(BACNET_OBJECT_TYPE object_type, + /* uint32_t object_instance, */ + BACNET_PROPERTY_REFERENCE *rpm_property) { bool bIsWritable = false; if ((object_type == OBJECT_ANALOG_OUTPUT) || @@ -363,7 +366,7 @@ void CheckIsWritableProperty(BACNET_OBJECT_TYPE object_type, bIsWritable = true; } } else if ((object_type == OBJECT_LIFE_SAFETY_POINT) || - (object_type == OBJECT_LIFE_SAFETY_ZONE)) { + (object_type == OBJECT_LIFE_SAFETY_ZONE)) { if (rpm_property->propertyIdentifier == PROP_MODE) { bIsWritable = true; } @@ -376,8 +379,8 @@ void CheckIsWritableProperty(BACNET_OBJECT_TYPE object_type, bIsWritable = true; } } else if ((object_type == OBJECT_TRENDLOG) || - (object_type == OBJECT_EVENT_LOG) || - (object_type == OBJECT_TREND_LOG_MULTIPLE)) { + (object_type == OBJECT_EVENT_LOG) || + (object_type == OBJECT_TREND_LOG_MULTIPLE)) { if ((rpm_property->propertyIdentifier == PROP_ENABLE) || (rpm_property->propertyIdentifier == PROP_RECORD_COUNT)) { bIsWritable = true; @@ -391,17 +394,17 @@ void CheckIsWritableProperty(BACNET_OBJECT_TYPE object_type, bIsWritable = true; } } else if ((object_type == OBJECT_ACCESS_ZONE) || - (object_type == OBJECT_ACCESS_USER) || - (object_type == OBJECT_ACCESS_RIGHTS) || - (object_type == OBJECT_ACCESS_CREDENTIAL)) { + (object_type == OBJECT_ACCESS_USER) || + (object_type == OBJECT_ACCESS_RIGHTS) || + (object_type == OBJECT_ACCESS_CREDENTIAL)) { if (rpm_property->propertyIdentifier == PROP_GLOBAL_IDENTIFIER) { bIsWritable = true; } } else if (object_type == OBJECT_NETWORK_SECURITY) { if ((rpm_property->propertyIdentifier == - PROP_BASE_DEVICE_SECURITY_POLICY) || + PROP_BASE_DEVICE_SECURITY_POLICY) || (rpm_property->propertyIdentifier == - PROP_NETWORK_ACCESS_SECURITY_POLICIES) || + PROP_NETWORK_ACCESS_SECURITY_POLICIES) || (rpm_property->propertyIdentifier == PROP_SECURITY_TIME_WINDOW) || (rpm_property->propertyIdentifier == PROP_PACKET_REORDER_TIME) || (rpm_property->propertyIdentifier == PROP_LAST_KEY_SERVER) || @@ -453,8 +456,8 @@ static const char *protocol_services_supported_text(size_t bit_index) * @return True if success. Or otherwise. */ -bool PrettyPrintPropertyValue(FILE *stream, - BACNET_OBJECT_PROPERTY_VALUE *object_value) +static bool PrettyPrintPropertyValue( + FILE *stream, BACNET_OBJECT_PROPERTY_VALUE *object_value) { BACNET_APPLICATION_DATA_VALUE *value = NULL; bool status = true; /*return value */ @@ -466,17 +469,17 @@ bool PrettyPrintPropertyValue(FILE *stream, property = object_value->object_property; if ((value != NULL) && (value->tag == BACNET_APPLICATION_TAG_BIT_STRING) && ((property == PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED) || - (property == PROP_PROTOCOL_SERVICES_SUPPORTED))) { + (property == PROP_PROTOCOL_SERVICES_SUPPORTED))) { len = bitstring_bits_used(&value->type.Bit_String); fprintf(stream, "( \n "); for (i = 0; i < len; i++) { - fprintf( - stream, "%s", + fprintf(stream, "%s", bitstring_bit(&value->type.Bit_String, (uint8_t)i) ? "T" : "F"); - if (i < len - 1) + if (i < len - 1) { fprintf(stream, ","); - else + } else { fprintf(stream, " "); + } /* Tried with 8 per line, but with the comments, got way too long. */ if ((i == (len - 1)) || ((i % 4) == 3)) { /* line break every 4 */ @@ -485,12 +488,12 @@ bool PrettyPrintPropertyValue(FILE *stream, for (j = i - (i % 4); j <= i; j++) { if (bitstring_bit(&value->type.Bit_String, (uint8_t)j)) { if (property == PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED) { - fprintf(stream, " %s,", - bactext_object_type_name(j)); + fprintf( + stream, " %s,", bactext_object_type_name(j)); } else { /* PROP_PROTOCOL_SERVICES_SUPPORTED */ fprintf(stream, " %s,", - protocol_services_supported_text(j)); + protocol_services_supported_text(j)); } } else /* not supported */ fprintf(stream, ","); @@ -506,8 +509,8 @@ bool PrettyPrintPropertyValue(FILE *stream, strncpy(short_month, bactext_month_name(value->type.Date.month), 3); short_month[3] = 0; fprintf(stream, "(%u-%3s-%u, %u)", (unsigned)value->type.Date.day, - short_month, (unsigned)value->type.Date.year, - (unsigned)value->type.Date.wday); + short_month, (unsigned)value->type.Date.year, + (unsigned)value->type.Date.wday); } else if (value != NULL) { assert(false); /* How did I get here? Fix your code. */ /* Meanwhile, a fallback plan */ @@ -528,9 +531,9 @@ bool PrettyPrintPropertyValue(FILE *stream, * @param rpm_property [in] Points to structure holding the Property, * Value, and Error information. */ -void PrintReadPropertyData(BACNET_OBJECT_TYPE object_type, - uint32_t object_instance, - BACNET_PROPERTY_REFERENCE *rpm_property) +static void PrintReadPropertyData(BACNET_OBJECT_TYPE object_type, + uint32_t object_instance, + BACNET_PROPERTY_REFERENCE *rpm_property) { BACNET_OBJECT_PROPERTY_VALUE object_value; /* for bacapp printing */ BACNET_APPLICATION_DATA_VALUE *value, *old_value; @@ -546,8 +549,8 @@ void PrintReadPropertyData(BACNET_OBJECT_TYPE object_type, if (value == NULL) { /* Then we print the error information */ fprintf(stdout, "? -- BACnet Error: %s: %s\n", - bactext_error_class_name((int)rpm_property->error.error_class), - bactext_error_code_name((int)rpm_property->error.error_code)); + bactext_error_class_name((int)rpm_property->error.error_class), + bactext_error_code_name((int)rpm_property->error.error_code)); return; } object_value.object_type = object_type; @@ -607,7 +610,7 @@ void PrintReadPropertyData(BACNET_OBJECT_TYPE object_type, break; } else assert(Walked_List_Index == - (uint32_t)rpm_property->propertyArrayIndex); + (uint32_t)rpm_property->propertyArrayIndex); } else { Walked_List_Index++; /* If we got the whole Object List array in one RP call, @@ -636,22 +639,21 @@ void PrintReadPropertyData(BACNET_OBJECT_TYPE object_type, if (rpm_property->propertyIdentifier == PROP_OBJECT_LIST) { if (value->tag != BACNET_APPLICATION_TAG_OBJECT_ID) { - assert( - value->tag == - BACNET_APPLICATION_TAG_OBJECT_ID); /* Something not - right here */ + assert(value->tag == + BACNET_APPLICATION_TAG_OBJECT_ID); /* Something + not right + here */ break; } /* Store the object list so we can interrogate each object. */ - object_list_element = - KEY_ENCODE(value->type.Object_Id.type, - value->type.Object_Id.instance); + object_list_element = KEY_ENCODE(value->type.Object_Id.type, + value->type.Object_Id.instance); /* We don't have anything to put in the data pointer * yet, so just leave it null. The key is Key here. */ Keylist_Data_Add(Object_List, object_list_element, NULL); } else if (rpm_property->propertyIdentifier == - PROP_STATE_TEXT) { + PROP_STATE_TEXT) { /* Make sure it fits within 31 chars for original VTS3 * limitation. If longer, take first 15 dash, and last 15 * chars. */ @@ -660,18 +662,18 @@ void PrintReadPropertyData(BACNET_OBJECT_TYPE object_type, value->type.Character_String.length - 15; value->type.Character_String.value[15] = '-'; memcpy(&value->type.Character_String.value[16], - &value->type.Character_String.value[iLast15idx], - 15); + &value->type.Character_String.value[iLast15idx], + 15); value->type.Character_String.value[31] = 0; value->type.Character_String.length = 31; } } else if (rpm_property->propertyIdentifier == - PROP_SUBORDINATE_LIST) { + PROP_SUBORDINATE_LIST) { if (value->tag != BACNET_APPLICATION_TAG_OBJECT_ID) { - assert( - value->tag == - BACNET_APPLICATION_TAG_OBJECT_ID); /* Something not - right here */ + assert(value->tag == + BACNET_APPLICATION_TAG_OBJECT_ID); /* Something + not right + here */ break; } /* TODO: handle Sequence of { Device ObjID, Object ID }, */ @@ -753,7 +755,7 @@ void PrintReadPropertyData(BACNET_OBJECT_TYPE object_type, fprintf(stdout, " }"); } CheckIsWritableProperty(object_type, /* object_instance, */ - rpm_property); + rpm_property); fprintf(stdout, "\n"); } break; @@ -811,8 +813,8 @@ static void BuildPropRequest(BACNET_READ_ACCESS_DATA *rpm_object) * @return The invokeID of the message sent, or 0 if reached the end * of the property list. */ -static uint8_t Read_Properties(uint32_t device_instance, - BACNET_OBJECT_ID *pMyObject) +static uint8_t Read_Properties( + uint32_t device_instance, BACNET_OBJECT_ID *pMyObject) { uint8_t invoke_id = 0; struct special_property_list_t PropertyListStruct; @@ -828,7 +830,7 @@ static uint8_t Read_Properties(uint32_t device_instance, property_list_special(pMyObject->type, &PropertyListStruct); if (Optional_Properties) { Property_List_Length = PropertyListStruct.Required.count + - PropertyListStruct.Optional.count; + PropertyListStruct.Optional.count; } else { Property_List_Length = PropertyListStruct.Required.count; } @@ -875,9 +877,8 @@ static uint8_t Read_Properties(uint32_t device_instance, break; } } - invoke_id = - Send_Read_Property_Request(device_instance, pMyObject->type, - pMyObject->instance, prop, array_index); + invoke_id = Send_Read_Property_Request(device_instance, pMyObject->type, + pMyObject->instance, prop, array_index); } return invoke_id; @@ -894,8 +895,8 @@ static uint8_t Read_Properties(uint32_t device_instance, * if the RPM got good data, or GET_PROPERTY_REQUEST if we have to * singly process the list of Properties. */ -EPICS_STATES ProcessRPMData(BACNET_READ_ACCESS_DATA *rpm_data, - EPICS_STATES myState) +static EPICS_STATES ProcessRPMData( + BACNET_READ_ACCESS_DATA *rpm_data, EPICS_STATES myState) { BACNET_READ_ACCESS_DATA *old_rpm_data; BACNET_PROPERTY_REFERENCE *rpm_property; @@ -947,7 +948,7 @@ EPICS_STATES ProcessRPMData(BACNET_READ_ACCESS_DATA *rpm_data, Print_Property_Identifier(rpm_property->propertyIdentifier); fprintf(stdout, ": "); PrintReadPropertyData(rpm_data->object_type, - rpm_data->object_instance, rpm_property); + rpm_data->object_instance, rpm_property); } old_rpm_property = rpm_property; rpm_property = rpm_property->next; @@ -959,10 +960,10 @@ EPICS_STATES ProcessRPMData(BACNET_READ_ACCESS_DATA *rpm_data, } /* Now determine the next state */ - if (myState == GET_HEADING_RESPONSE) + if (myState == GET_HEADING_RESPONSE) { nextState = PRINT_HEADING; - /* press ahead with or without the data */ - else if (bSuccess && (myState == GET_ALL_RESPONSE)) + /* press ahead with or without the data */ + } else if (bSuccess && (myState == GET_ALL_RESPONSE)) nextState = NEXT_OBJECT; else if (bSuccess) { /* and GET_LIST_OF_ALL_RESPONSE */ /* Now append the properties we waited on. */ @@ -987,9 +988,8 @@ EPICS_STATES ProcessRPMData(BACNET_READ_ACCESS_DATA *rpm_data, static void print_usage(char *filename) { - printf( - "Usage: %s [-v] [-d] [-p sport] [-t target_mac [-n dnet]]" - " device-instance\n", + printf("Usage: %s [-v] [-d] [-p sport] [-t target_mac [-n dnet]]" + " device-instance\n", filename); printf(" [--version][--help]\n"); } @@ -997,12 +997,11 @@ static void print_usage(char *filename) static void print_help(char *filename) { printf("Generates Full EPICS file, including Object and Property List\n"); - printf( - "device-instance:\n" - "BACnet Device Object Instance number that you are\n" - "trying to communicate to. This number will be used\n" - "to try and bind with the device using Who-Is and\n" - "I-Am services.\n"); + printf("device-instance:\n" + "BACnet Device Object Instance number that you are\n" + "trying to communicate to. This number will be used\n" + "to try and bind with the device using Who-Is and\n" + "I-Am services.\n"); printf("\n"); printf("-v: show values instead of '?' \n"); printf("-d: show only device object properties\n"); @@ -1018,7 +1017,7 @@ static void print_help(char *filename) printf("e.g., bacepics 2701876 > epics-2701876.tpi \n"); } -int CheckCommandLineArgs(int argc, char *argv[]) +static int CheckCommandLineArgs(int argc, char *argv[]) { int i; bool bFoundTarget = false; @@ -1034,12 +1033,11 @@ int CheckCommandLineArgs(int argc, char *argv[]) } if (strcmp(argv[argi], "--version") == 0) { printf("%s %s\n", filename, BACNET_VERSION_TEXT); - printf( - "Copyright (C) 2014 by Steve Karg and others.\n" - "This is free software; see the source for copying " - "conditions.\n" - "There is NO warranty; not even for MERCHANTABILITY or\n" - "FITNESS FOR A PARTICULAR PURPOSE.\n"); + printf("Copyright (C) 2014 by Steve Karg and others.\n" + "This is free software; see the source for copying " + "conditions.\n" + "There is NO warranty; not even for MERCHANTABILITY or\n" + "FITNESS FOR A PARTICULAR PURPOSE.\n"); exit(0); } } @@ -1071,8 +1069,8 @@ int CheckCommandLineArgs(int argc, char *argv[]) case 'n': /* Destination Network Number */ if (Target_Address.mac_len == 0) - fprintf(stderr, - "Must provide a Target MAC before DNET \n"); + fprintf( + stderr, "Must provide a Target MAC before DNET \n"); if (++i < argc) Target_Address.net = (uint16_t)strtol(argv[i], NULL, 0); /* Used strtol so dest.net can be either 0x1234 or 4660 */ @@ -1087,7 +1085,7 @@ int CheckCommandLineArgs(int argc, char *argv[]) unsigned j; count = sscanf(argv[i], "%2x:%2x:%2x:%2x:%2x:%2x", &mac[0], - &mac[1], &mac[2], &mac[3], &mac[4], &mac[5]); + &mac[1], &mac[2], &mac[3], &mac[4], &mac[5]); if (count == 6) { /* success */ Target_Address.mac_len = count; for (j = 0; j < 6; j++) { @@ -1097,8 +1095,9 @@ int CheckCommandLineArgs(int argc, char *argv[]) Target_Address.len = 0; /* No src address */ Provided_Targ_MAC = true; break; - } else + } else { printf("ERROR: invalid Target MAC %s \n", argv[i]); + } /* And fall through to print_usage */ } /* Either break or fall through, as above */ @@ -1113,8 +1112,8 @@ int CheckCommandLineArgs(int argc, char *argv[]) Target_Device_Object_Instance = strtol(anArg, NULL, 0); if (Target_Device_Object_Instance > BACNET_MAX_INSTANCE) { fprintf(stdout, - "Error: device-instance=%u - it must be less than %u\n", - Target_Device_Object_Instance, BACNET_MAX_INSTANCE + 1); + "Error: device-instance=%u - it must be less than %u\n", + Target_Device_Object_Instance, BACNET_MAX_INSTANCE + 1); print_usage(filename); exit(0); } @@ -1130,7 +1129,7 @@ int CheckCommandLineArgs(int argc, char *argv[]) return 0; /* All OK if we reach here */ } -void PrintHeading() +static void PrintHeading(void) { BACNET_APPLICATION_DATA_VALUE *value = NULL; BACNET_OBJECT_PROPERTY_VALUE property_value; @@ -1147,7 +1146,7 @@ void PrintHeading() if ((value != NULL) && (value->tag == BACNET_APPLICATION_TAG_CHARACTER_STRING)) { printf("Vendor Name: \"%s\"\n", - characterstring_value(&value->type.Character_String)); + characterstring_value(&value->type.Character_String)); } else { printf("Vendor Name: \"your vendor name here\"\n"); } @@ -1157,9 +1156,9 @@ void PrintHeading() if ((value != NULL) && (value->tag == BACNET_APPLICATION_TAG_CHARACTER_STRING)) { printf("Product Name: \"%s\"\n", - characterstring_value(&value->type.Character_String)); + characterstring_value(&value->type.Character_String)); printf("Product Model Number: \"%s\"\n", - characterstring_value(&value->type.Character_String)); + characterstring_value(&value->type.Character_String)); } else { printf("Product Name: \"your product name here\"\n"); printf("Product Model Number: \"your model number here\"\n"); @@ -1169,11 +1168,10 @@ void PrintHeading() if ((value != NULL) && (value->tag == BACNET_APPLICATION_TAG_CHARACTER_STRING)) { printf("Product Description: \"%s\"\n\n", - characterstring_value(&value->type.Character_String)); + characterstring_value(&value->type.Character_String)); } else { - printf( - "Product Description: " - "\"your product description here\"\n\n"); + printf("Product Description: " + "\"your product description here\"\n\n"); } printf("BIBBs Supported:\n"); printf("{\n"); @@ -1347,9 +1345,8 @@ void PrintHeading() printf( " real: \n"); - printf( - " double: \n"); + printf(" double: \n"); printf(" date: \n"); printf(" octet-string: \n"); printf(" character-string: \n"); @@ -1369,7 +1366,7 @@ void PrintHeading() printf("}\n\n"); } -void Print_Device_Heading(void) +static void Print_Device_Heading(void) { printf("List of Objects in Test Device:\n"); /* Print Opening brace, then kick off the Device Object */ @@ -1378,8 +1375,8 @@ void Print_Device_Heading(void) } /* Initialize fields for a new Object */ -void StartNextObject(BACNET_READ_ACCESS_DATA *rpm_object, - BACNET_OBJECT_ID *pNewObject) +static void StartNextObject( + BACNET_READ_ACCESS_DATA *rpm_object, BACNET_OBJECT_ID *pNewObject) { BACNET_PROPERTY_REFERENCE *rpm_property; Error_Detected = false; @@ -1419,7 +1416,7 @@ int main(int argc, char *argv[]) time_t timeout_seconds = 0; bool found = false; BACNET_OBJECT_ID myObject; - uint8_t buffer[MAX_PDU] = {0}; + uint8_t buffer[MAX_PDU] = { 0 }; BACNET_READ_ACCESS_DATA *rpm_object = NULL; KEY nextKey; @@ -1453,27 +1450,27 @@ int main(int argc, char *argv[]) } #endif /* try to bind with the target device */ - found = address_bind_request(Target_Device_Object_Instance, &max_apdu, - &Target_Address); + found = address_bind_request( + Target_Device_Object_Instance, &max_apdu, &Target_Address); if (!found) { if (Provided_Targ_MAC) { if (Target_Address.net > 0) { /* We specified a DNET; call Who-Is to find the full * routed path to this Device */ Send_WhoIs_Remote(&Target_Address, - Target_Device_Object_Instance, - Target_Device_Object_Instance); + Target_Device_Object_Instance, + Target_Device_Object_Instance); } else { /* Update by adding the MAC address */ if (max_apdu == 0) max_apdu = MAX_APDU; /* Whatever set for this datalink. */ - address_add_binding(Target_Device_Object_Instance, max_apdu, - &Target_Address); + address_add_binding( + Target_Device_Object_Instance, max_apdu, &Target_Address); } } else { - Send_WhoIs(Target_Device_Object_Instance, - Target_Device_Object_Instance); + Send_WhoIs( + Target_Device_Object_Instance, Target_Device_Object_Instance); } } myObject.type = OBJECT_DEVICE; @@ -1500,17 +1497,17 @@ int main(int argc, char *argv[]) npdu_handler(&src, &Rx_Buf[0], pdu_len); } /* will wait until the device is bound, or timeout and quit */ - found = address_bind_request(Target_Device_Object_Instance, - &max_apdu, &Target_Address); + found = address_bind_request( + Target_Device_Object_Instance, &max_apdu, &Target_Address); if (!found) { /* increment timer - exit if timed out */ elapsed_seconds += (current_seconds - last_seconds); if (elapsed_seconds > timeout_seconds) { fprintf(stderr, - "\rError: Unable to bind to %u" - " after waiting %ld seconds.\n", - Target_Device_Object_Instance, - (long int)elapsed_seconds); + "\rError: Unable to bind to %u" + " after waiting %ld seconds.\n", + Target_Device_Object_Instance, + (long int)elapsed_seconds); break; } /* else, loop back and try again */ @@ -1580,7 +1577,7 @@ int main(int argc, char *argv[]) if ((Read_Property_Multiple_Data.new_data) && (Request_Invoke_ID == - Read_Property_Multiple_Data.service_data.invoke_id)) { + Read_Property_Multiple_Data.service_data.invoke_id)) { Read_Property_Multiple_Data.new_data = false; myState = ProcessRPMData( Read_Property_Multiple_Data.rpm_data, myState); @@ -1604,8 +1601,7 @@ int main(int argc, char *argv[]) /* Was it because the Device can't do RPM? */ Has_RPM = false; myState = GET_PROPERTY_REQUEST; - } else if ( - Last_Error_Code == + } else if (Last_Error_Code == ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED) { myState = GET_PROPERTY_REQUEST; StartNextObject(rpm_object, &myObject); @@ -1639,8 +1635,8 @@ int main(int argc, char *argv[]) myState = PRINT_HEADING; /* just press ahead without the data */ else - myState = - NEXT_OBJECT; /* Give up and move on to the next. */ + myState = NEXT_OBJECT; /* Give up and move on to the + next. */ Error_Count++; } break; @@ -1672,7 +1668,7 @@ int main(int argc, char *argv[]) if ((Read_Property_Multiple_Data.new_data) && (Request_Invoke_ID == - Read_Property_Multiple_Data.service_data.invoke_id)) { + Read_Property_Multiple_Data.service_data.invoke_id)) { Read_Property_Multiple_Data.new_data = false; PrintReadPropertyData( Read_Property_Multiple_Data.rpm_data->object_type, @@ -1752,8 +1748,8 @@ int main(int argc, char *argv[]) case NEXT_OBJECT: if (myObject.type == OBJECT_DEVICE) { - printf(" -- Found %d Objects \n", - Keylist_Count(Object_List)); + printf( + " -- Found %d Objects \n", Keylist_Count(Object_List)); Object_List_Index = -1; /* start over (will be incr to 0) */ if (ShowDeviceObjectOnly) { /* Closing brace for the Device Object */ @@ -1814,15 +1810,16 @@ int main(int argc, char *argv[]) elapsed_seconds += (current_seconds - last_seconds); if (elapsed_seconds > timeout_seconds) { fprintf(stderr, "\rError: APDU Timeout! (%lds)\n", - (long int)elapsed_seconds); + (long int)elapsed_seconds); break; } } } while (myObject.type < MAX_BACNET_OBJECT_TYPE); - if (Error_Count > 0) + if (Error_Count > 0) { fprintf(stdout, "\r-- Found %d Errors \n", Error_Count); + } /* Closing brace for all Objects, if we got any, and closing footer */ if (myState != INITIAL_BINDING) { diff --git a/apps/error/Makefile b/apps/error/Makefile new file mode 100644 index 00000000..c6476352 --- /dev/null +++ b/apps/error/Makefile @@ -0,0 +1,47 @@ +#Makefile to build BACnet Application + +TARGET = bacerror +BACNET_OBJECT_DIR = $(BACNET_SRC_DIR)/bacnet/basic/object +SRC = main.c \ + $(BACNET_OBJECT_DIR)/client/device-client.c \ + $(BACNET_OBJECT_DIR)/netport.c +BACNET_BASIC_SRC += \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_apdu.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_iam.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_noserv.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_rp.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_whois.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/s_iam.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/s_error.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/s_whois.c + +# TARGET_EXT is defined in apps/Makefile as .exe or nothing +TARGET_BIN = ${TARGET}$(TARGET_EXT) + +SRCS = $(SRC) $(BACNET_SRC) $(BACNET_BASIC_SRC) $(BACNET_PORT_SRC) + +OBJS += ${SRCS:.c=.o} + +.PHONY: all +all: Makefile ${TARGET_BIN} + +${TARGET_BIN}: ${OBJS} + ${CC} ${PFLAGS} ${OBJS} ${LFLAGS} -o $@ + size $@ + cp $@ ../../bin + +.c.o: + ${CC} -c ${CFLAGS} $*.c -o $@ + +.PHONY: depend +depend: + rm -f .depend + ${CC} -MM ${CFLAGS} *.c >> .depend + +.PHONY: clean +clean: + rm -f core ${TARGET_BIN} ${OBJS} $(TARGET).map + +.PHONY: include +include: .depend + diff --git a/demo/error/main.c b/apps/error/main.c similarity index 81% rename from demo/error/main.c rename to apps/error/main.c index 1d8d1709..b0f77399 100644 --- a/demo/error/main.c +++ b/apps/error/main.c @@ -30,22 +30,22 @@ #include #include /* for time */ #include -#include "bactext.h" -#include "iam.h" -#include "address.h" -#include "config.h" -#include "bacdef.h" -#include "npdu.h" -#include "apdu.h" -#include "device.h" -#include "datalink.h" -#include "version.h" +#include "bacnet/bactext.h" +#include "bacnet/iam.h" +#include "bacnet/config.h" +#include "bacnet/bacdef.h" +#include "bacnet/npdu.h" +#include "bacnet/apdu.h" +#include "bacnet/version.h" /* some demo stuff needed */ -#include "filename.h" -#include "handlers.h" -#include "client.h" -#include "txbuf.h" -#include "dlenv.h" +#include "bacnet/basic/binding/address.h" +#include "bacnet/basic/object/device.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/sys/filename.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/datalink/datalink.h" +#include "bacnet/datalink/dlenv.h" /* parsed command line parameters */ static uint16_t Target_Error_Class; @@ -55,8 +55,8 @@ static uint16_t Target_Service = SERVICE_CONFIRMED_READ_PROPERTY; /* flag for signalling errors */ static bool Error_Detected = false; -void MyAbortHandler(BACNET_ADDRESS *src, uint8_t invoke_id, - uint8_t abort_reason, bool server) +static void MyAbortHandler( + BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t abort_reason, bool server) { (void)src; (void)invoke_id; @@ -65,8 +65,8 @@ void MyAbortHandler(BACNET_ADDRESS *src, uint8_t invoke_id, Error_Detected = true; } -void MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, - uint8_t reject_reason) +static void MyRejectHandler( + BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason) { (void)src; (void)invoke_id; @@ -84,8 +84,8 @@ static void Init_Service_Handlers(void) It is required to send the proper reject message... */ apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service); /* we must implement read property - it's required! */ - apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY, - handler_read_property); + apdu_set_confirmed_handler( + SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property); /* handle the reply (request) coming back */ apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_I_AM, handler_i_am_add); /* handle any errors coming back */ @@ -96,7 +96,7 @@ static void Init_Service_Handlers(void) static void print_usage(char *filename) { printf("Usage: %s [error-class error-code service-number invoke-id]\n", - filename); + filename); printf(" [--dnet][--dadr][--mac]\n"); printf(" [--version][--help]\n"); } @@ -123,26 +123,25 @@ static void print_help(char *filename) "or an IP string with optional port number like 10.1.2.3:47808\n" "or an Ethernet MAC in hex like 00:21:70:7e:32:bb\n" "\n"); - printf( - "error-class:\n" - " number from 0 to 65535\n" - "error-code:\n" - " number from 0 to 65535\n" - "service-number:\n" - " number from 0 to 65535 for BACnet Services\n" - "invoke-id:\n" - " number from 1 to 255\n" - "Example:\n" - "%s 3 2 1\n", + printf("error-class:\n" + " number from 0 to 65535\n" + "error-code:\n" + " number from 0 to 65535\n" + "service-number:\n" + " number from 0 to 65535 for BACnet Services\n" + "invoke-id:\n" + " number from 1 to 255\n" + "Example:\n" + "%s 3 2 1\n", filename); } int main(int argc, char *argv[]) { long dnet = -1; - BACNET_MAC_ADDRESS mac = {0}; - BACNET_MAC_ADDRESS adr = {0}; - BACNET_ADDRESS dest = {0}; + BACNET_MAC_ADDRESS mac = { 0 }; + BACNET_MAC_ADDRESS adr = { 0 }; + BACNET_ADDRESS dest = { 0 }; bool specific_address = false; int argi = 0; unsigned int target_args = 0; @@ -157,12 +156,11 @@ int main(int argc, char *argv[]) } if (strcmp(argv[argi], "--version") == 0) { printf("%s %s\n", filename, BACNET_VERSION_TEXT); - printf( - "Copyright (C) 2016 by Steve Karg and others.\n" - "This is free software; see the source for copying " - "conditions.\n" - "There is NO warranty; not even for MERCHANTABILITY or\n" - "FITNESS FOR A PARTICULAR PURPOSE.\n"); + printf("Copyright (C) 2016 by Steve Karg and others.\n" + "This is free software; see the source for copying " + "conditions.\n" + "There is NO warranty; not even for MERCHANTABILITY or\n" + "FITNESS FOR A PARTICULAR PURPOSE.\n"); return 0; } if (strcmp(argv[argi], "--mac") == 0) { @@ -242,8 +240,7 @@ int main(int argc, char *argv[]) atexit(datalink_cleanup); /* send the request */ Send_Error_To_Network(&Handler_Transmit_Buffer[0], &dest, Target_Invoke_ID, - Target_Service, Target_Error_Class, - Target_Error_Code); + Target_Service, Target_Error_Class, Target_Error_Code); return 0; } diff --git a/demo/gateway/Makefile b/apps/gateway/Makefile similarity index 100% rename from demo/gateway/Makefile rename to apps/gateway/Makefile diff --git a/demo/gateway/gateway.h b/apps/gateway/gateway.h similarity index 100% rename from demo/gateway/gateway.h rename to apps/gateway/gateway.h diff --git a/demo/gateway/main.c b/apps/gateway/main.c similarity index 79% rename from demo/gateway/main.c rename to apps/gateway/main.c index 3354bcbc..30b62215 100644 --- a/demo/gateway/main.c +++ b/apps/gateway/main.c @@ -33,31 +33,31 @@ #include #include #include -#include "config.h" +#include "bacnet/config.h" #include "gateway.h" -#include "address.h" -#include "bacdef.h" -#include "handlers.h" -#include "client.h" -#include "dlenv.h" -#include "bacdcode.h" -#include "npdu.h" -#include "apdu.h" -#include "iam.h" -#include "tsm.h" -#include "device.h" -#include "bacfile.h" -#include "datalink.h" -#include "dcc.h" -#include "net.h" -#include "txbuf.h" -#include "lc.h" -#include "debug.h" -#include "version.h" +#include "bacnet/basic/binding/address.h" +#include "bacnet/bacdef.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/services.h" +#include "bacnet/datalink/dlenv.h" +#include "bacnet/bacdcode.h" +#include "bacnet/npdu.h" +#include "bacnet/apdu.h" +#include "bacnet/iam.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/basic/object/device.h" +#include "bacnet/basic/object/bacfile.h" +#include "bacnet/datalink/datalink.h" +#include "bacnet/dcc.h" +#include "bacport.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/basic/object/lc.h" +#include "bacnet/basic/sys/debug.h" +#include "bacnet/version.h" /* include the device object */ -#include "device.h" +#include "bacnet/basic/object/device.h" #ifdef BACNET_TEST_VMAC -#include "vmac.h" +#include "bacnet/basic/bbmd6/vmac.h" #endif /** @file gateway/main.c Example virtual gateway application using the BACnet @@ -71,7 +71,7 @@ /*@{*/ /** Buffer used for receiving */ -static uint8_t Rx_Buf[MAX_MPDU] = {0}; +static uint8_t Rx_Buf[MAX_MPDU] = { 0 }; /** The list of DNETs that our router can reach. * Only one entry since we don't support downstream routers. @@ -80,6 +80,9 @@ int DNET_list[2] = { VIRTUAL_DNET, -1 /* Need -1 terminator */ }; +/* current version of the BACnet stack */ +static const char *BACnet_Version = BACNET_VERSION_TEXT; + /** Initialize the Device Objects and each of the child Object instances. * @param first_object_instance Set the first (gateway) Device to this instance number, and subsequent devices to incremented values. @@ -124,41 +127,41 @@ static void Init_Service_Handlers(uint32_t first_object_instance) * Don't need the routed versions, since the npdu handler calls * each device in turn. */ - apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, - handler_who_is_unicast); + apdu_set_unconfirmed_handler( + SERVICE_UNCONFIRMED_WHO_IS, handler_who_is_unicast); apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_HAS, handler_who_has); /* set the handler for all the services we don't implement */ /* It is required to send the proper reject message... */ apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service); /* Set the handlers for any confirmed services that we support. */ /* We must implement read property - it's required! */ - apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY, - handler_read_property); - apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROP_MULTIPLE, - handler_read_property_multiple); - apdu_set_confirmed_handler(SERVICE_CONFIRMED_WRITE_PROPERTY, - handler_write_property); - apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_RANGE, - handler_read_range); + apdu_set_confirmed_handler( + SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property); + apdu_set_confirmed_handler( + SERVICE_CONFIRMED_READ_PROP_MULTIPLE, handler_read_property_multiple); + apdu_set_confirmed_handler( + SERVICE_CONFIRMED_WRITE_PROPERTY, handler_write_property); + apdu_set_confirmed_handler( + SERVICE_CONFIRMED_READ_RANGE, handler_read_range); #if defined(BACFILE) - apdu_set_confirmed_handler(SERVICE_CONFIRMED_ATOMIC_READ_FILE, - handler_atomic_read_file); - apdu_set_confirmed_handler(SERVICE_CONFIRMED_ATOMIC_WRITE_FILE, - handler_atomic_write_file); + apdu_set_confirmed_handler( + SERVICE_CONFIRMED_ATOMIC_READ_FILE, handler_atomic_read_file); + apdu_set_confirmed_handler( + SERVICE_CONFIRMED_ATOMIC_WRITE_FILE, handler_atomic_write_file); #endif - apdu_set_confirmed_handler(SERVICE_CONFIRMED_REINITIALIZE_DEVICE, - handler_reinitialize_device); - apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_UTC_TIME_SYNCHRONIZATION, - handler_timesync_utc); - apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_TIME_SYNCHRONIZATION, - handler_timesync); - apdu_set_confirmed_handler(SERVICE_CONFIRMED_SUBSCRIBE_COV, - handler_cov_subscribe); - apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_COV_NOTIFICATION, - handler_ucov_notification); + apdu_set_confirmed_handler( + SERVICE_CONFIRMED_REINITIALIZE_DEVICE, handler_reinitialize_device); + apdu_set_unconfirmed_handler( + SERVICE_UNCONFIRMED_UTC_TIME_SYNCHRONIZATION, handler_timesync_utc); + apdu_set_unconfirmed_handler( + SERVICE_UNCONFIRMED_TIME_SYNCHRONIZATION, handler_timesync); + apdu_set_confirmed_handler( + SERVICE_CONFIRMED_SUBSCRIBE_COV, handler_cov_subscribe); + apdu_set_unconfirmed_handler( + SERVICE_UNCONFIRMED_COV_NOTIFICATION, handler_ucov_notification); /* handle communication so we can shutup when asked */ apdu_set_confirmed_handler(SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL, - handler_device_communication_control); + handler_device_communication_control); } /** Initialize the BACnet Device Addresses for each Device object. @@ -224,7 +227,7 @@ static void Initialize_Device_Addresses() memcpy(&pDev->bacDevAddr.adr[0], &pDev->bacDevAddr.mac[0], 6); pDev->bacDevAddr.len = 6; printf(" - Routed device [%d] ID %u at %s \n", i, - pDev->bacObj.Object_Instance_Number, inet_ntoa(*netPtr)); + pDev->bacObj.Object_Instance_Number, inet_ntoa(*netPtr)); #elif defined(BACDL_MSTP) /* Todo: set MS/TP net and port #s */ pDev->bacDevAddr.mac_len = 2; @@ -248,7 +251,7 @@ static void Initialize_Device_Addresses() */ int main(int argc, char *argv[]) { - BACNET_ADDRESS src = {0}; /* address where message came from */ + BACNET_ADDRESS src = { 0 }; /* address where message came from */ uint16_t pdu_len = 0; unsigned timeout = 1000; /* milliseconds */ time_t last_seconds = 0; @@ -268,16 +271,15 @@ int main(int argc, char *argv[]) if ((first_object_instance == 0) || (first_object_instance >= BACNET_MAX_INSTANCE)) { printf("Error: Invalid Object Instance %s \n", argv[1]); - printf("Provide a number from 1 to %ul \n", - BACNET_MAX_INSTANCE - 1); + printf( + "Provide a number from 1 to %ul \n", BACNET_MAX_INSTANCE - 1); exit(1); } } - printf( - "BACnet Router Demo\n" - "BACnet Stack Version %s\n" - "BACnet Device ID: %u\n" - "Max APDU: %d\n", + printf("BACnet Router Demo\n" + "BACnet Stack Version %s\n" + "BACnet Device ID: %u\n" + "Max APDU: %d\n", BACnet_Version, first_object_instance, MAX_APDU); Init_Service_Handlers(first_object_instance); dlenv_init(); diff --git a/apps/getevent/Makefile b/apps/getevent/Makefile new file mode 100644 index 00000000..a1caf166 --- /dev/null +++ b/apps/getevent/Makefile @@ -0,0 +1,50 @@ +#Makefile to build BACnet Application using GCC compiler + +# Executable file name +TARGET = bacge +BACNET_OBJECT_DIR = $(BACNET_SRC_DIR)/bacnet/basic/object +SRC = main.c \ + $(BACNET_OBJECT_DIR)/client/device-client.c \ + $(BACNET_OBJECT_DIR)/netport.c +BACNET_BASIC_SRC += \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_apdu.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_getevent.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_iam.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_noserv.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_rp.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_rr_a.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_whois.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/s_iam.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/s_getevent.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/s_whois.c + +# TARGET_EXT is defined in apps/Makefile as .exe or nothing +TARGET_BIN = ${TARGET}$(TARGET_EXT) + +SRCS = $(SRC) $(BACNET_SRC) $(BACNET_BASIC_SRC) $(BACNET_PORT_SRC) + +OBJS += ${SRCS:.c=.o} + +.PHONY: all +all: Makefile ${TARGET_BIN} + +${TARGET_BIN}: ${OBJS} + ${CC} ${PFLAGS} ${OBJS} ${LFLAGS} -o $@ + size $@ + cp $@ ../../bin + +.c.o: + ${CC} -c ${CFLAGS} $*.c -o $@ + +.PHONY: depend +depend: + rm -f .depend + ${CC} -MM ${CFLAGS} *.c >> .depend + +.PHONY: clean +clean: + rm -f core ${TARGET_BIN} ${OBJS} $(TARGET).map + +.PHONY: include +include: .depend + diff --git a/demo/getevent/main.c b/apps/getevent/main.c old mode 100755 new mode 100644 similarity index 76% rename from demo/getevent/main.c rename to apps/getevent/main.c index 28e986eb..ff3a8b9b --- a/demo/getevent/main.c +++ b/apps/getevent/main.c @@ -29,30 +29,27 @@ #include #include #include - /* core stuff needed */ -#include "bacdef.h" -#include "config.h" -#include "bactext.h" -#include "bacerror.h" -#include "iam.h" -#include "arf.h" -#include "tsm.h" -#include "address.h" -#include "npdu.h" -#include "apdu.h" -#include "device.h" -#include "net.h" -#include "datalink.h" -#include "whois.h" -#include "getevent.h" - +#include "bacnet/bacdef.h" +#include "bacnet/config.h" +#include "bacnet/bactext.h" +#include "bacnet/bacerror.h" +#include "bacnet/iam.h" +#include "bacnet/arf.h" +#include "bacnet/npdu.h" +#include "bacnet/apdu.h" +#include "bacnet/whois.h" +#include "bacnet/getevent.h" /* some demo stuff needed */ -#include "filename.h" -#include "handlers.h" -#include "client.h" -#include "txbuf.h" -#include "dlenv.h" +#include "bacnet/basic/binding/address.h" +#include "bacnet/basic/object/device.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/sys/filename.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/datalink/datalink.h" +#include "bacnet/datalink/dlenv.h" +/* some port stuff needed */ +#include "bacport.h" /* Depending on on the max-APDU-length-accepted (varies per device), the amount of event entries in the GetEventInformation ACK can sum @@ -61,7 +58,7 @@ #define MAX_OBJ_IDS_IN_GE_ACK 24 /* buffer used for receive */ -static uint8_t Rx_Buf[MAX_MPDU] = {0}; +static uint8_t Rx_Buf[MAX_MPDU] = { 0 }; /* converted command line arguments */ static uint32_t Target_Device_Object_Instance = BACNET_MAX_INSTANCE; @@ -73,38 +70,39 @@ static bool Recieved_Ack = false; static bool More_Events = false; static BACNET_OBJECT_ID LastReceivedObjectIdentifier; -static void MyErrorHandler(BACNET_ADDRESS *src, uint8_t invoke_id, - BACNET_ERROR_CLASS error_class, - BACNET_ERROR_CODE error_code) +static void MyErrorHandler(BACNET_ADDRESS *src, + uint8_t invoke_id, + BACNET_ERROR_CLASS error_class, + BACNET_ERROR_CODE error_code) { if (address_match(&Target_Address, src) && (invoke_id == Request_Invoke_ID)) { printf("BACnet Error: %s: %s\r\n", - bactext_error_class_name((int)error_class), - bactext_error_code_name((int)error_code)); + bactext_error_class_name((int)error_class), + bactext_error_code_name((int)error_code)); Error_Detected = true; } } -void MyAbortHandler(BACNET_ADDRESS *src, uint8_t invoke_id, - uint8_t abort_reason, bool server) +static void MyAbortHandler( + BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t abort_reason, bool server) { (void)server; if (address_match(&Target_Address, src) && (invoke_id == Request_Invoke_ID)) { printf("BACnet Abort: %s\r\n", - bactext_abort_reason_name((int)abort_reason)); + bactext_abort_reason_name((int)abort_reason)); Error_Detected = true; } } -void MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, - uint8_t reject_reason) +static void MyRejectHandler( + BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason) { if (address_match(&Target_Address, src) && (invoke_id == Request_Invoke_ID)) { printf("BACnet Reject: %s\r\n", - bactext_reject_reason_name((int)reject_reason)); + bactext_reject_reason_name((int)reject_reason)); Error_Detected = true; } } @@ -119,9 +117,10 @@ void MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, * @param service_data [in] The BACNET_CONFIRMED_SERVICE_DATA information * decoded from the APDU header of this message. */ -void My_Get_Event_Ack_Handler(uint8_t *service_request, uint16_t service_len, - BACNET_ADDRESS *src, - BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data) +static void My_Get_Event_Ack_Handler(uint8_t *service_request, + uint16_t service_len, + BACNET_ADDRESS *src, + BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data) { int len = 0; int i; @@ -130,13 +129,13 @@ void My_Get_Event_Ack_Handler(uint8_t *service_request, uint16_t service_len, data[i].next = &data[i + 1]; printf("Recieved Ack. Saved invoke ID was %i, service returned %i\n", - Request_Invoke_ID, service_data->invoke_id); + Request_Invoke_ID, service_data->invoke_id); if (service_data->invoke_id == Request_Invoke_ID) { - len = getevent_ack_decode_service_request(service_request, service_len, - &data[0], &More_Events); + len = getevent_ack_decode_service_request( + service_request, service_len, &data[0], &More_Events); printf("Decode of Ack returned length %i. MoreEvents flag was %i \n", - len, More_Events); + len, More_Events); if (len > 0) { ge_ack_print_data(&(data[0]), Target_Device_Object_Instance); if (More_Events) { @@ -162,11 +161,11 @@ static void Init_Service_Handlers(void) It is required to send the proper reject message... */ apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service); /* we must implement getevent - it's required! */ - apdu_set_confirmed_handler(SERVICE_CONFIRMED_GET_EVENT_INFORMATION, - handler_get_event_information); + apdu_set_confirmed_handler( + SERVICE_CONFIRMED_GET_EVENT_INFORMATION, handler_get_event_information); /* handle the data coming back from confirmed requests */ - apdu_set_confirmed_ack_handler(SERVICE_CONFIRMED_GET_EVENT_INFORMATION, - My_Get_Event_Ack_Handler); + apdu_set_confirmed_ack_handler( + SERVICE_CONFIRMED_GET_EVENT_INFORMATION, My_Get_Event_Ack_Handler); /* handle any errors coming back */ apdu_set_error_handler(SERVICE_CONFIRMED_READ_PROPERTY, MyErrorHandler); apdu_set_abort_handler(MyAbortHandler); @@ -175,21 +174,20 @@ static void Init_Service_Handlers(void) static int print_help(char *exe_name) { - printf( - "Usage:\n" - "\n" - "%s device-instance [--help]\n" - "\n" - " Send BACnet GetEventInformation service retruequest to given " - "device, and wait\n" - " for responses.\n\n", + printf("Usage:\n" + "\n" + "%s device-instance [--help]\n" + "\n" + " Send BACnet GetEventInformation service retruequest to given " + "device, and wait\n" + " for responses.\n\n", exe_name); return 1; } int main(int argc, char *argv[]) { - BACNET_ADDRESS src = {0}; /* address where message came from */ + BACNET_ADDRESS src = { 0 }; /* address where message came from */ uint16_t pdu_len = 0; unsigned timeout = 100; /* milliseconds */ unsigned max_apdu = 0; @@ -220,11 +218,11 @@ int main(int argc, char *argv[]) last_seconds = time(NULL); timeout_seconds = (apdu_timeout() / 1000) * apdu_retries(); /* try to bind with the device */ - found = address_bind_request(Target_Device_Object_Instance, &max_apdu, - &Target_Address); + found = address_bind_request( + Target_Device_Object_Instance, &max_apdu, &Target_Address); if (!found) { - Send_WhoIs(Target_Device_Object_Instance, - Target_Device_Object_Instance); + Send_WhoIs( + Target_Device_Object_Instance, Target_Device_Object_Instance); } /* loop forever */ for (;;) { @@ -232,17 +230,18 @@ int main(int argc, char *argv[]) current_seconds = time(NULL); /* at least one second has passed */ - if (current_seconds != last_seconds) + if (current_seconds != last_seconds) { tsm_timer_milliseconds( (uint16_t)((current_seconds - last_seconds) * 1000)); + } if (Error_Detected) { break; } /* wait until the device is bound, or timeout and quit */ if (!found) { - found = address_bind_request(Target_Device_Object_Instance, - &max_apdu, &Target_Address); + found = address_bind_request( + Target_Device_Object_Instance, &max_apdu, &Target_Address); } if (found) { if (Request_Invoke_ID == 0) { diff --git a/apps/iam/Makefile b/apps/iam/Makefile new file mode 100644 index 00000000..c6a4ea17 --- /dev/null +++ b/apps/iam/Makefile @@ -0,0 +1,47 @@ +#Makefile to build BACnet Application for the Linux Port + +TARGET = baciam +# BACnet objects that are used with this app +BACNET_OBJECT_DIR = $(BACNET_SRC_DIR)/bacnet/basic/object +SRC = main.c \ + $(BACNET_OBJECT_DIR)/client/device-client.c \ + $(BACNET_OBJECT_DIR)/netport.c +BACNET_BASIC_SRC += \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_apdu.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_iam.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_noserv.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_rp.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_whois.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/s_iam.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/s_whois.c + +# TARGET_EXT is defined in apps/Makefile as .exe or nothing +TARGET_BIN = ${TARGET}$(TARGET_EXT) + +SRCS = $(SRC) $(BACNET_SRC) $(BACNET_BASIC_SRC) $(BACNET_PORT_SRC) + +OBJS += ${SRCS:.c=.o} + +.PHONY: all +all: Makefile ${TARGET_BIN} + +${TARGET_BIN}: ${OBJS} + ${CC} ${PFLAGS} ${OBJS} ${LFLAGS} -o $@ + size $@ + cp $@ ../../bin + +.c.o: + ${CC} -c ${CFLAGS} $*.c -o $@ + +.PHONY: depend +depend: + rm -f .depend + ${CC} -MM ${CFLAGS} *.c >> .depend + +.PHONY: clean +clean: + rm -f core ${TARGET_BIN} ${OBJS} $(TARGET).map + +.PHONY: include +include: .depend + diff --git a/demo/iam/main.c b/apps/iam/main.c similarity index 76% rename from demo/iam/main.c rename to apps/iam/main.c index 8aac47ed..5a917583 100644 --- a/demo/iam/main.c +++ b/apps/iam/main.c @@ -30,22 +30,22 @@ #include #include /* for time */ #include -#include "bactext.h" -#include "iam.h" -#include "address.h" -#include "config.h" -#include "bacdef.h" -#include "npdu.h" -#include "apdu.h" -#include "device.h" -#include "datalink.h" -#include "version.h" +#include "bacnet/bactext.h" +#include "bacnet/iam.h" +#include "bacnet/basic/binding/address.h" +#include "bacnet/config.h" +#include "bacnet/bacdef.h" +#include "bacnet/npdu.h" +#include "bacnet/apdu.h" +#include "bacnet/basic/object/device.h" +#include "bacnet/datalink/datalink.h" +#include "bacnet/version.h" /* some demo stuff needed */ -#include "filename.h" -#include "handlers.h" -#include "client.h" -#include "txbuf.h" -#include "dlenv.h" +#include "bacnet/basic/sys/filename.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/datalink/dlenv.h" /* parsed command line parameters */ static uint32_t Target_Device_ID = BACNET_MAX_INSTANCE; @@ -55,8 +55,8 @@ static int Target_Segmentation = SEGMENTATION_NONE; /* flag for signalling errors */ static bool Error_Detected = false; -void MyAbortHandler(BACNET_ADDRESS *src, uint8_t invoke_id, - uint8_t abort_reason, bool server) +static void MyAbortHandler( + BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t abort_reason, bool server) { (void)src; (void)invoke_id; @@ -65,8 +65,8 @@ void MyAbortHandler(BACNET_ADDRESS *src, uint8_t invoke_id, Error_Detected = true; } -void MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, - uint8_t reject_reason) +static void MyRejectHandler( + BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason) { (void)src; (void)invoke_id; @@ -84,8 +84,8 @@ static void Init_Service_Handlers(void) It is required to send the proper reject message... */ apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service); /* we must implement read property - it's required! */ - apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY, - handler_read_property); + apdu_set_confirmed_handler( + SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property); /* handle the reply (request) coming back */ apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_I_AM, handler_i_am_add); /* handle any errors coming back */ @@ -96,7 +96,7 @@ static void Init_Service_Handlers(void) static void print_usage(char *filename) { printf("Usage: %s [device-instance vendor-id max-apdu segmentation]\n", - filename); + filename); printf(" [--dnet][--dadr][--mac]\n"); printf(" [--version][--help]\n"); } @@ -104,25 +104,24 @@ static void print_usage(char *filename) static void print_help(char *filename) { printf("Send BACnet I-Am message for a device.\n"); - printf( - "--mac A\n" - "Optional BACnet mac address." - "Valid ranges are from 00 to FF (hex) for MS/TP or ARCNET,\n" - "or an IP string with optional port number like 10.1.2.3:47808\n" - "or an Ethernet MAC in hex like 00:21:70:7e:32:bb\n" - "\n" - "--dnet N\n" - "Optional BACnet network number N for directed requests.\n" - "Valid range is from 0 to 65535 where 0 is the local connection\n" - "and 65535 is network broadcast.\n" - "\n" - "--dadr A\n" - "Optional BACnet mac address on the destination BACnet network " - "number.\n" - "Valid ranges are from 00 to FF (hex) for MS/TP or ARCNET,\n" - "or an IP string with optional port number like 10.1.2.3:47808\n" - "or an Ethernet MAC in hex like 00:21:70:7e:32:bb\n" - "\n"); + printf("--mac A\n" + "Optional BACnet mac address." + "Valid ranges are from 00 to FF (hex) for MS/TP or ARCNET,\n" + "or an IP string with optional port number like 10.1.2.3:47808\n" + "or an Ethernet MAC in hex like 00:21:70:7e:32:bb\n" + "\n" + "--dnet N\n" + "Optional BACnet network number N for directed requests.\n" + "Valid range is from 0 to 65535 where 0 is the local connection\n" + "and 65535 is network broadcast.\n" + "\n" + "--dadr A\n" + "Optional BACnet mac address on the destination BACnet network " + "number.\n" + "Valid ranges are from 00 to FF (hex) for MS/TP or ARCNET,\n" + "or an IP string with optional port number like 10.1.2.3:47808\n" + "or an Ethernet MAC in hex like 00:21:70:7e:32:bb\n" + "\n"); printf( "device-instance:\n" " BACnet device-ID 0..4194303\n" @@ -140,9 +139,9 @@ static void print_help(char *filename) int main(int argc, char *argv[]) { long dnet = -1; - BACNET_MAC_ADDRESS mac = {0}; - BACNET_MAC_ADDRESS adr = {0}; - BACNET_ADDRESS dest = {0}; + BACNET_MAC_ADDRESS mac = { 0 }; + BACNET_MAC_ADDRESS adr = { 0 }; + BACNET_ADDRESS dest = { 0 }; bool specific_address = false; int argi = 0; unsigned int target_args = 0; @@ -157,12 +156,11 @@ int main(int argc, char *argv[]) } if (strcmp(argv[argi], "--version") == 0) { printf("%s %s\n", filename, BACNET_VERSION_TEXT); - printf( - "Copyright (C) 2016 by Steve Karg and others.\n" - "This is free software; see the source for copying " - "conditions.\n" - "There is NO warranty; not even for MERCHANTABILITY or\n" - "FITNESS FOR A PARTICULAR PURPOSE.\n"); + printf("Copyright (C) 2016 by Steve Karg and others.\n" + "This is free software; see the source for copying " + "conditions.\n" + "There is NO warranty; not even for MERCHANTABILITY or\n" + "FITNESS FOR A PARTICULAR PURPOSE.\n"); return 0; } if (strcmp(argv[argi], "--mac") == 0) { @@ -242,7 +240,7 @@ int main(int argc, char *argv[]) atexit(datalink_cleanup); /* send the request */ Send_I_Am_To_Network(&dest, Target_Device_ID, Target_Max_APDU, - Target_Segmentation, Target_Vendor_ID); + Target_Segmentation, Target_Vendor_ID); return 0; } diff --git a/apps/iamrouter/Makefile b/apps/iamrouter/Makefile new file mode 100644 index 00000000..409fd373 --- /dev/null +++ b/apps/iamrouter/Makefile @@ -0,0 +1,47 @@ +#Makefile to build BACnet Application for the Linux Port + +TARGET = baciamr +# BACnet objects that are used with this app +BACNET_OBJECT_DIR = $(BACNET_SRC_DIR)/bacnet/basic/object +SRC = main.c \ + $(BACNET_OBJECT_DIR)/client/device-client.c \ + $(BACNET_OBJECT_DIR)/netport.c +BACNET_BASIC_SRC += \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_apdu.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_iam.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_noserv.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_rp.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_whois.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/s_iam.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/s_whois.c + +# TARGET_EXT is defined in apps/Makefile as .exe or nothing +TARGET_BIN = ${TARGET}$(TARGET_EXT) + +SRCS = $(SRC) $(BACNET_SRC) $(BACNET_BASIC_SRC) $(BACNET_PORT_SRC) + +OBJS += ${SRCS:.c=.o} + +.PHONY: all +all: Makefile ${TARGET_BIN} + +${TARGET_BIN}: ${OBJS} + ${CC} ${PFLAGS} ${OBJS} ${LFLAGS} -o $@ + size $@ + cp $@ ../../bin + +.c.o: + ${CC} -c ${CFLAGS} $*.c -o $@ + +.PHONY: depend +depend: + rm -f .depend + ${CC} -MM ${CFLAGS} *.c >> .depend + +.PHONY: clean +clean: + rm -f core ${TARGET_BIN} ${OBJS} $(TARGET).map + +.PHONY: include +include: .depend + diff --git a/demo/iamrouter/main.c b/apps/iamrouter/main.c similarity index 72% rename from demo/iamrouter/main.c rename to apps/iamrouter/main.c index acd030e8..3fbde452 100644 --- a/demo/iamrouter/main.c +++ b/apps/iamrouter/main.c @@ -30,31 +30,31 @@ #include #include /* for time */ #include -#include "bactext.h" -#include "iam.h" -#include "address.h" -#include "config.h" -#include "bacdef.h" -#include "npdu.h" -#include "apdu.h" -#include "device.h" -#include "datalink.h" -#include "version.h" +#include "bacnet/bactext.h" +#include "bacnet/iam.h" +#include "bacnet/basic/binding/address.h" +#include "bacnet/config.h" +#include "bacnet/bacdef.h" +#include "bacnet/npdu.h" +#include "bacnet/apdu.h" +#include "bacnet/basic/object/device.h" +#include "bacnet/datalink/datalink.h" +#include "bacnet/version.h" /* some demo stuff needed */ -#include "filename.h" -#include "handlers.h" -#include "client.h" -#include "txbuf.h" -#include "dlenv.h" +#include "bacnet/basic/sys/filename.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/datalink/dlenv.h" /* global variables used in this file */ #define MAX_ROUTER_DNETS 64 -static int Target_Router_Networks[MAX_ROUTER_DNETS] = {-1}; +static int Target_Router_Networks[MAX_ROUTER_DNETS] = { -1 }; static bool Error_Detected = false; -void MyAbortHandler(BACNET_ADDRESS *src, uint8_t invoke_id, - uint8_t abort_reason, bool server) +static void MyAbortHandler( + BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t abort_reason, bool server) { /* FIXME: verify src and invoke id */ (void)src; @@ -64,8 +64,8 @@ void MyAbortHandler(BACNET_ADDRESS *src, uint8_t invoke_id, Error_Detected = true; } -void MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, - uint8_t reject_reason) +static void MyRejectHandler( + BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason) { /* FIXME: verify src and invoke id */ (void)src; @@ -84,8 +84,8 @@ static void Init_Service_Handlers(void) It is required to send the proper reject message... */ apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service); /* we must implement read property - it's required! */ - apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY, - handler_read_property); + apdu_set_confirmed_handler( + SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property); /* handle the reply (request) coming back */ apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_I_AM, handler_i_am_add); /* handle any errors coming back */ @@ -101,16 +101,15 @@ static void print_usage(char *filename) static void print_help(char *filename) { - printf( - "Send BACnet I-Am-Router-To-Network message for \n" - "one or more networks.\n" - "\nDNET:\n" - "BACnet destination network number 0-65534\n" - "To send a I-Am-Router-To-Network message for DNET 86:\n" - "%s 86\n" - "To send a I-Am-Router-To-Network message for multiple DNETs\n" - "use the following command:\n" - "%s 86 42 24 14\n", + printf("Send BACnet I-Am-Router-To-Network message for \n" + "one or more networks.\n" + "\nDNET:\n" + "BACnet destination network number 0-65534\n" + "To send a I-Am-Router-To-Network message for DNET 86:\n" + "%s 86\n" + "To send a I-Am-Router-To-Network message for multiple DNETs\n" + "use the following command:\n" + "%s 86 42 24 14\n", filename, filename); } @@ -129,12 +128,11 @@ int main(int argc, char *argv[]) } if (strcmp(argv[argi], "--version") == 0) { printf("%s %s\n", filename, BACNET_VERSION_TEXT); - printf( - "Copyright (C) 2014 by Steve Karg and others.\n" - "This is free software; see the source for copying " - "conditions.\n" - "There is NO warranty; not even for MERCHANTABILITY or\n" - "FITNESS FOR A PARTICULAR PURPOSE.\n"); + printf("Copyright (C) 2014 by Steve Karg and others.\n" + "This is free software; see the source for copying " + "conditions.\n" + "There is NO warranty; not even for MERCHANTABILITY or\n" + "FITNESS FOR A PARTICULAR PURPOSE.\n"); exit(0); } } @@ -146,8 +144,8 @@ int main(int argc, char *argv[]) if (argc > 1) { for (arg_count = 1; arg_count < argc; arg_count++) { if (arg_count > MAX_ROUTER_DNETS) { - fprintf(stderr, "Limited to %u DNETS. Sorry!\n", - MAX_ROUTER_DNETS); + fprintf( + stderr, "Limited to %u DNETS. Sorry!\n", MAX_ROUTER_DNETS); break; } Target_Router_Networks[arg_count - 1] = @@ -157,7 +155,7 @@ int main(int argc, char *argv[]) /* invalid DNET? */ if (Target_Router_Networks[arg_count - 1] >= 65535) { fprintf(stderr, "DNET=%u - it must be less than %u\n", - Target_Router_Networks[arg_count - 1], 65535); + Target_Router_Networks[arg_count - 1], 65535); return 1; } } diff --git a/apps/initrouter/Makefile b/apps/initrouter/Makefile new file mode 100644 index 00000000..7302bfec --- /dev/null +++ b/apps/initrouter/Makefile @@ -0,0 +1,47 @@ +#Makefile to build BACnet Application for the Linux Port + +TARGET = bacinitr +# BACnet objects that are used with this app +BACNET_OBJECT_DIR = $(BACNET_SRC_DIR)/bacnet/basic/object +SRC = main.c \ + $(BACNET_OBJECT_DIR)/client/device-client.c \ + $(BACNET_OBJECT_DIR)/netport.c +BACNET_BASIC_SRC += \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_apdu.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_iam.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_noserv.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_rp.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_whois.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/s_iam.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/s_whois.c + +# TARGET_EXT is defined in apps/Makefile as .exe or nothing +TARGET_BIN = ${TARGET}$(TARGET_EXT) + +SRCS = $(SRC) $(BACNET_SRC) $(BACNET_BASIC_SRC) $(BACNET_PORT_SRC) + +OBJS += ${SRCS:.c=.o} + +.PHONY: all +all: Makefile ${TARGET_BIN} + +${TARGET_BIN}: ${OBJS} + ${CC} ${PFLAGS} ${OBJS} ${LFLAGS} -o $@ + size $@ + cp $@ ../../bin + +.c.o: + ${CC} -c ${CFLAGS} $*.c -o $@ + +.PHONY: depend +depend: + rm -f .depend + ${CC} -MM ${CFLAGS} *.c >> .depend + +.PHONY: clean +clean: + rm -f core ${TARGET_BIN} ${OBJS} $(TARGET).map + +.PHONY: include +include: .depend + diff --git a/demo/initrouter/main.c b/apps/initrouter/main.c similarity index 85% rename from demo/initrouter/main.c rename to apps/initrouter/main.c index 5017f29c..0ad847d7 100644 --- a/demo/initrouter/main.c +++ b/apps/initrouter/main.c @@ -30,29 +30,29 @@ #include #include /* for time */ #include -#include "bactext.h" -#include "iam.h" -#include "address.h" -#include "config.h" -#include "bacdef.h" -#include "npdu.h" -#include "apdu.h" -#include "device.h" -#include "datalink.h" -#include "version.h" +#include "bacnet/bactext.h" +#include "bacnet/iam.h" +#include "bacnet/basic/binding/address.h" +#include "bacnet/config.h" +#include "bacnet/bacdef.h" +#include "bacnet/npdu.h" +#include "bacnet/apdu.h" +#include "bacnet/basic/object/device.h" +#include "bacnet/datalink/datalink.h" +#include "bacnet/version.h" /* some demo stuff needed */ #ifndef DEBUG_ENABLED #define DEBUG_ENABLED 0 #endif -#include "debug.h" -#include "filename.h" -#include "handlers.h" -#include "client.h" -#include "txbuf.h" -#include "dlenv.h" +#include "bacnet/basic/sys/debug.h" +#include "bacnet/basic/sys/filename.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/datalink/dlenv.h" /* buffer used for receive */ -static uint8_t Rx_Buf[MAX_MPDU] = {0}; +static uint8_t Rx_Buf[MAX_MPDU] = { 0 }; /* target address */ static BACNET_ADDRESS Target_Router_Address; @@ -68,8 +68,8 @@ int DNET_list[2] = { static bool Error_Detected = false; -static void MyAbortHandler(BACNET_ADDRESS *src, uint8_t invoke_id, - uint8_t abort_reason, bool server) +static void MyAbortHandler( + BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t abort_reason, bool server) { /* FIXME: verify src and invoke id */ (void)src; @@ -79,8 +79,8 @@ static void MyAbortHandler(BACNET_ADDRESS *src, uint8_t invoke_id, Error_Detected = true; } -static void MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, - uint8_t reject_reason) +static void MyRejectHandler( + BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason) { /* FIXME: verify src and invoke id */ (void)src; @@ -89,9 +89,10 @@ static void MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, Error_Detected = true; } -static void My_Router_Handler(BACNET_ADDRESS *src, BACNET_NPDU_DATA *npdu_data, - uint8_t *npdu, /* PDU data */ - uint16_t npdu_len) +static void My_Router_Handler(BACNET_ADDRESS *src, + BACNET_NPDU_DATA *npdu_data, + uint8_t *npdu, /* PDU data */ + uint16_t npdu_len) { uint16_t npdu_offset = 0; uint16_t dnet = 0; @@ -177,18 +178,18 @@ static void My_Router_Handler(BACNET_ADDRESS *src, BACNET_NPDU_DATA *npdu_data, } static void My_NPDU_Handler(BACNET_ADDRESS *src, /* source address */ - uint8_t *pdu, /* PDU data */ - uint16_t pdu_len) + uint8_t *pdu, /* PDU data */ + uint16_t pdu_len) { /* length PDU */ int apdu_offset = 0; - BACNET_ADDRESS dest = {0}; - BACNET_NPDU_DATA npdu_data = {0}; + BACNET_ADDRESS dest = { 0 }; + BACNET_NPDU_DATA npdu_data = { 0 }; apdu_offset = npdu_decode(&pdu[0], &dest, src, &npdu_data); if (npdu_data.network_layer_message) { if (apdu_offset <= pdu_len) { My_Router_Handler(src, &npdu_data, &pdu[apdu_offset], - (uint16_t)(pdu_len - apdu_offset)); + (uint16_t)(pdu_len - apdu_offset)); } } else if ((apdu_offset > 0) && (apdu_offset <= pdu_len)) { if ((npdu_data.protocol_version == BACNET_PROTOCOL_VERSION) && @@ -196,14 +197,14 @@ static void My_NPDU_Handler(BACNET_ADDRESS *src, /* source address */ /* only handle the version that we know how to handle */ /* and we are not a router, so ignore messages with routing information cause they are not for us */ - apdu_handler(src, &pdu[apdu_offset], - (uint16_t)(pdu_len - apdu_offset)); + apdu_handler( + src, &pdu[apdu_offset], (uint16_t)(pdu_len - apdu_offset)); } else { if (dest.net) { debug_printf("NPDU: DNET=%d. Discarded!\n", dest.net); } else { debug_printf("NPDU: BACnet Protocol Version=%d. Discarded!\n", - npdu_data.protocol_version); + npdu_data.protocol_version); } } } @@ -221,8 +222,8 @@ static void Init_Service_Handlers(void) It is required to send the proper reject message... */ apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service); /* we must implement read property - it's required! */ - apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY, - handler_read_property); + apdu_set_confirmed_handler( + SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property); /* handle the reply (request) coming back */ apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_I_AM, handler_i_am_add); /* handle any errors coming back */ @@ -267,7 +268,7 @@ static void address_parse(BACNET_ADDRESS *dst, int argc, char *argv[]) if (argc > 0) { count = sscanf(argv[0], "%u.%u.%u.%u:%u", &mac[0], &mac[1], &mac[2], - &mac[3], &port); + &mac[3], &port); if (count == 5) { dst->mac_len = 6; for (index = 0; index < 4; index++) { @@ -276,7 +277,7 @@ static void address_parse(BACNET_ADDRESS *dst, int argc, char *argv[]) encode_unsigned16(&dst->mac[4], port); } else { count = sscanf(argv[0], "%x:%x:%x:%x:%x:%x", &mac[0], &mac[1], - &mac[2], &mac[3], &mac[4], &mac[5]); + &mac[2], &mac[3], &mac[4], &mac[5]); dst->mac_len = count; for (index = 0; index < MAX_MAC_LEN; index++) { if (index < count) { @@ -296,7 +297,7 @@ static void address_parse(BACNET_ADDRESS *dst, int argc, char *argv[]) int main(int argc, char *argv[]) { - BACNET_ADDRESS src = {0}; /* address where message came from */ + BACNET_ADDRESS src = { 0 }; /* address where message came from */ uint16_t pdu_len = 0; unsigned timeout = 100; /* milliseconds */ time_t total_seconds = 0; @@ -316,12 +317,11 @@ int main(int argc, char *argv[]) } if (strcmp(argv[argi], "--version") == 0) { printf("%s %s\n", filename, BACNET_VERSION_TEXT); - printf( - "Copyright (C) 2014 by Steve Karg and others.\n" - "This is free software; see the source for copying " - "conditions.\n" - "There is NO warranty; not even for MERCHANTABILITY or\n" - "FITNESS FOR A PARTICULAR PURPOSE.\n"); + printf("Copyright (C) 2014 by Steve Karg and others.\n" + "This is free software; see the source for copying " + "conditions.\n" + "There is NO warranty; not even for MERCHANTABILITY or\n" + "FITNESS FOR A PARTICULAR PURPOSE.\n"); exit(0); } } @@ -373,8 +373,9 @@ int main(int argc, char *argv[]) #endif } total_seconds += elapsed_seconds; - if (total_seconds > timeout_seconds) + if (total_seconds > timeout_seconds) { break; + } /* keep track of time for next check */ last_seconds = current_seconds; } diff --git a/apps/mstpcap/Makefile b/apps/mstpcap/Makefile new file mode 100644 index 00000000..de353f28 --- /dev/null +++ b/apps/mstpcap/Makefile @@ -0,0 +1,70 @@ +#Makefile to build BACnet Application + +# Executable file name +TARGET = mstpcap + +# BACNET_PORT, BACNET_PORT_DIR, BACNET_PORT_SRC are defined in common Makefile +# BACNET_SRC_DIR is defined in common apps Makefile +SRCS = main.c \ + ${BACNET_PORT_DIR}/rs485.c \ + ${BACNET_PORT_DIR}/mstimer-init.c \ + ${BACNET_SRC_DIR}/bacnet/bacdcode.c \ + ${BACNET_SRC_DIR}/bacnet/bacint.c \ + ${BACNET_SRC_DIR}/bacnet/bacreal.c \ + ${BACNET_SRC_DIR}/bacnet/bacstr.c \ + ${BACNET_SRC_DIR}/bacnet/iam.c \ + ${BACNET_SRC_DIR}/bacnet/indtext.c \ + ${BACNET_SRC_DIR}/bacnet/npdu.c \ + ${BACNET_SRC_DIR}/bacnet/basic/sys/debug.c \ + ${BACNET_SRC_DIR}/bacnet/basic/sys/fifo.c \ + ${BACNET_SRC_DIR}/bacnet/basic/sys/filename.c \ + ${BACNET_SRC_DIR}/bacnet/basic/sys/mstimer.c \ + ${BACNET_SRC_DIR}/bacnet/basic/sys/ringbuf.c \ + ${BACNET_SRC_DIR}/bacnet/datalink/mstp.c \ + ${BACNET_SRC_DIR}/bacnet/datalink/mstptext.c \ + ${BACNET_SRC_DIR}/bacnet/datalink/crc.c + +# This demo seems to be a little unique +DEFINES = $(BACNET_DEFINES) -DBACDL_MSTP + +# BACNET_PORT, BACNET_PORT_DIR, BACNET_PORT_SRC are defined in common Makefile +# BACNET_SRC_DIR is defined in common apps Makefile +# WARNINGS, DEBUGGING, OPTIMIZATION are defined in common apps Makefile +# BACNET_DEFINES is defined in common apps Makefile +# put all the flags together +INCLUDES = -I$(BACNET_SRC_DIR) -I$(BACNET_PORT_DIR) +CFLAGS += $(WARNINGS) $(DEBUGGING) $(OPTIMIZATION) $(BACNET_DEFINES) $(INCLUDES) +LFLAGS += -Wl,$(SYSTEM_LIB) +ifneq (${BACNET_LIB},) +LFLAGS += -Wl,$(BACNET_LIB) +endif +# GCC dead code removal +CFLAGS += -ffunction-sections -fdata-sections +LFLAGS += -Wl,--gc-sections + +OBJS += ${SRCS:.c=.o} + +TARGET_BIN = ${TARGET}$(TARGET_EXT) + +.PHONY: all +all: Makefile ${TARGET_BIN} + +${TARGET_BIN}: ${OBJS} + ${CC} ${PFLAGS} ${OBJS} ${LFLAGS} -o $@ + size $@ + cp $@ ../../bin + +.c.o: + ${CC} -c ${CFLAGS} $*.c -o $@ + +.PHONY: depend +depend: + rm -f .depend + ${CC} -MM ${CFLAGS} *.c >> .depend + +.PHONY: clean +clean: + rm -f core ${TARGET_BIN} ${OBJS} $(TARGET).map + +.PHONY: include +include: .depend diff --git a/demo/mstpcap/main.c b/apps/mstpcap/main.c similarity index 81% rename from demo/mstpcap/main.c rename to apps/mstpcap/main.c index 6f1fe68a..db664a20 100644 --- a/demo/mstpcap/main.c +++ b/apps/mstpcap/main.c @@ -39,19 +39,18 @@ #include #include #include -/* OS specific include*/ -#include "net.h" -#include "timer.h" -/* local includes */ -#include "bytes.h" +#include "bacnet/bytes.h" +#include "bacnet/iam.h" +#include "bacnet/version.h" +/* basic datalink, timer, and filename */ +#include "bacnet/datalink/dlmstp.h" +#include "bacnet/basic/sys/mstimer.h" +#include "bacnet/datalink/crc.h" +#include "bacnet/datalink/mstptext.h" +#include "bacnet/basic/sys/filename.h" +/* OS specific includes */ +#include "bacport.h" #include "rs485.h" -#include "crc.h" -#include "mstptext.h" -#include "filename.h" -#include "version.h" -#include "dlmstp.h" -/* I-Am decoding */ -#include "iam.h" #ifdef _WIN32 #define strncasecmp(x, y, z) _strnicmp(x, y, z) @@ -78,6 +77,8 @@ static uint8_t TxBuffer[MAX_MPDU]; static volatile bool Exit_Requested; /* flag to indicate Wireshark is running the show - no stdout or stderr */ static bool Wireshark_Capture; +/* placed to track silence on the wire */ +static struct mstimer Silence_Timer; /* statistics derived from monitoring the network for each node */ struct mstp_statistics { @@ -139,16 +140,16 @@ static uint32_t timeval_diff_ms(struct timeval *old, struct timeval *now) /* convert to milliseconds */ ms = (now->tv_sec - old->tv_sec) * 1000 + - (now->tv_usec - old->tv_usec) / 1000; + (now->tv_usec - old->tv_usec) / 1000; return ms; } static void mstp_monitor_i_am(uint8_t mac, uint8_t *pdu, uint16_t pdu_len) { - BACNET_ADDRESS src = {0}; - BACNET_ADDRESS dest = {0}; - BACNET_NPDU_DATA npdu_data = {0}; + BACNET_ADDRESS src = { 0 }; + BACNET_ADDRESS dest = { 0 }; + BACNET_NPDU_DATA npdu_data = { 0 }; int apdu_offset = 0; uint16_t apdu_len = 0; uint8_t *apdu = NULL; @@ -182,10 +183,10 @@ static void mstp_monitor_i_am(uint8_t mac, uint8_t *pdu, uint16_t pdu_len) } } -static void packet_statistics(struct timeval *tv, - volatile struct mstp_port_struct_t *mstp_port) +static void packet_statistics( + struct timeval *tv, volatile struct mstp_port_struct_t *mstp_port) { - static struct timeval old_tv = {0}; + static struct timeval old_tv = { 0 }; static uint8_t old_frame = 255; static uint8_t old_src = 255; static uint8_t old_dst = 255; @@ -221,7 +222,7 @@ static void packet_statistics(struct timeval *tv, } } } else if ((old_frame == FRAME_TYPE_POLL_FOR_MASTER) && - (old_src == src)) { + (old_src == src)) { /* Tusage_timeout */ delta = timeval_diff_ms(&old_tv, tv); if (delta > MSTP_Statistics[src].tusage_timeout) { @@ -237,7 +238,7 @@ static void packet_statistics(struct timeval *tv, case FRAME_TYPE_POLL_FOR_MASTER: if (MSTP_Statistics[src].last_pfm_tokens) { npoll = MSTP_Statistics[src].token_received_count - - MSTP_Statistics[src].last_pfm_tokens; + MSTP_Statistics[src].last_pfm_tokens; if (npoll > MSTP_Statistics[src].npoll) { MSTP_Statistics[src].npoll = npoll; } @@ -288,8 +289,8 @@ static void packet_statistics(struct timeval *tv, (mstp_port->ReceivedValidFrameNotForUs)) { if ((mstp_port->DataLength <= mstp_port->InputBufferSize) && (mstp_port->DataLength > 0)) { - mstp_monitor_i_am(src, &mstp_port->InputBuffer[0], - mstp_port->DataLength); + mstp_monitor_i_am( + src, &mstp_port->InputBuffer[0], mstp_port->DataLength); } } break; @@ -325,8 +326,7 @@ static void packet_statistics_print(void) fprintf(stdout, "\n"); fprintf(stdout, "==== MS/TP Frame Counts ====\n"); fprintf(stdout, "%-8s%-8s%-8s%-8s%-8s%-8s%-8s%-8s%-8s%-7s", "MAC", "Device", - "Tokens", "PFM", "RPFM", "DER", "Postpd", "DNER", "TestReq", - "TestRsp"); + "Tokens", "PFM", "RPFM", "DER", "Postpd", "DNER", "TestReq", "TestRsp"); fprintf(stdout, "\n"); for (i = 0; i < MAX_MSTP_DEVICES; i++) { /* check for masters or slaves */ @@ -336,20 +336,20 @@ static void packet_statistics_print(void) fprintf(stdout, "%-8u", i); if (MSTP_Statistics[i].device_id <= 4194303) { fprintf(stdout, "%-8lu", - (long unsigned int)MSTP_Statistics[i].device_id); + (long unsigned int)MSTP_Statistics[i].device_id); } else { fprintf(stdout, "%-8s", "-"); } fprintf(stdout, "%-8lu%-8lu%-8lu%-8lu", - (long unsigned int)MSTP_Statistics[i].token_count, - (long unsigned int)MSTP_Statistics[i].pfm_count, - (long unsigned int)MSTP_Statistics[i].rpfm_count, - (long unsigned int)MSTP_Statistics[i].der_count); + (long unsigned int)MSTP_Statistics[i].token_count, + (long unsigned int)MSTP_Statistics[i].pfm_count, + (long unsigned int)MSTP_Statistics[i].rpfm_count, + (long unsigned int)MSTP_Statistics[i].der_count); fprintf(stdout, "%-8lu%-8lu%-8lu%-7lu", - (long unsigned int)MSTP_Statistics[i].reply_postponed_count, - (long unsigned int)MSTP_Statistics[i].dner_count, - (long unsigned int)MSTP_Statistics[i].test_request_count, - (long unsigned int)MSTP_Statistics[i].test_response_count); + (long unsigned int)MSTP_Statistics[i].reply_postponed_count, + (long unsigned int)MSTP_Statistics[i].dner_count, + (long unsigned int)MSTP_Statistics[i].test_request_count, + (long unsigned int)MSTP_Statistics[i].test_response_count); fprintf(stdout, "\n"); } } @@ -358,8 +358,8 @@ static void packet_statistics_print(void) fprintf(stdout, "\n"); fprintf(stdout, "==== MS/TP Usage and Timing Maximums ====\n"); fprintf(stdout, "%-8s%-8s%-8s%-8s%-8s%-8s%-8s%-8s%-8s%-7s", "MAC", - "MaxMstr", "Retries", "Npoll", "Self/TT", "Treply", "Tusage", - "Trpfm", "Tder", "Tpostpd"); + "MaxMstr", "Retries", "Npoll", "Self/TT", "Treply", "Tusage", "Trpfm", + "Tder", "Tpostpd"); fprintf(stdout, "\n"); for (i = 0; i < MAX_MSTP_DEVICES; i++) { /* check for masters or slaves */ @@ -367,25 +367,24 @@ static void packet_statistics_print(void) (MSTP_Statistics[i].der_reply) || (MSTP_Statistics[i].pfm_count)) { node_count++; self_or_ooo_count = MSTP_Statistics[i].self_token_count + - MSTP_Statistics[i].ooo_token_count; + MSTP_Statistics[i].ooo_token_count; fprintf(stdout, "%-8u", i); fprintf(stdout, "%-8lu%-8lu%-8lu%-8lu%-8lu", - (long unsigned int)MSTP_Statistics[i].max_master, - (long unsigned int)MSTP_Statistics[i].token_retries, - (long unsigned int)MSTP_Statistics[i].npoll, - self_or_ooo_count, - (long unsigned int)MSTP_Statistics[i].token_reply); + (long unsigned int)MSTP_Statistics[i].max_master, + (long unsigned int)MSTP_Statistics[i].token_retries, + (long unsigned int)MSTP_Statistics[i].npoll, self_or_ooo_count, + (long unsigned int)MSTP_Statistics[i].token_reply); fprintf(stdout, "%-8lu%-8lu%-8lu%-7lu", - (long unsigned int)MSTP_Statistics[i].tusage_timeout, - (long unsigned int)MSTP_Statistics[i].pfm_reply, - (long unsigned int)MSTP_Statistics[i].der_reply, - (long unsigned int)MSTP_Statistics[i].reply_postponed); + (long unsigned int)MSTP_Statistics[i].tusage_timeout, + (long unsigned int)MSTP_Statistics[i].pfm_reply, + (long unsigned int)MSTP_Statistics[i].der_reply, + (long unsigned int)MSTP_Statistics[i].reply_postponed); fprintf(stdout, "\n"); } } fprintf(stdout, "Node Count: %u\n", node_count); fprintf(stdout, "Invalid Frame Count: %lu\n", - (long unsigned int)Invalid_Frame_Count); + (long unsigned int)Invalid_Frame_Count); } static void packet_statistics_clear(void) @@ -401,12 +400,12 @@ static void packet_statistics_clear(void) static uint32_t Timer_Silence(void *pArg) { - return timer_milliseconds(TIMER_SILENCE); + return mstimer_remaining(&Silence_Timer); } static void Timer_Silence_Reset(void *pArg) { - timer_reset(TIMER_SILENCE); + mstimer_set(&Silence_Timer, 0); } /* functions used by the MS/TP state machine to put or get data */ @@ -419,16 +418,16 @@ uint16_t MSTP_Put_Receive(volatile struct mstp_port_struct_t *mstp_port) /* for the MS/TP state machine to use for getting data to send */ /* Return: amount of PDU data */ -uint16_t MSTP_Get_Send(volatile struct mstp_port_struct_t *mstp_port, - unsigned timeout) +uint16_t MSTP_Get_Send( + volatile struct mstp_port_struct_t *mstp_port, unsigned timeout) { /* milliseconds to wait for a packet */ (void)mstp_port; (void)timeout; return 0; } -uint16_t MSTP_Get_Reply(volatile struct mstp_port_struct_t *mstp_port, - unsigned timeout) +uint16_t MSTP_Get_Reply( + volatile struct mstp_port_struct_t *mstp_port, unsigned timeout) { /* milliseconds to wait for a packet */ (void)mstp_port; (void)timeout; @@ -448,16 +447,15 @@ static void named_pipe_create(char *pipe_name) while (hPipe == INVALID_HANDLE_VALUE) { /* use CreateFile rather than CreateNamedPipe */ hPipe = CreateFile(pipe_name, GENERIC_READ | GENERIC_WRITE, 0, NULL, - OPEN_EXISTING, 0, NULL); + OPEN_EXISTING, 0, NULL); if (hPipe != INVALID_HANDLE_VALUE) { break; } /* if an error occured at handle creation */ if (!WaitNamedPipe(pipe_name, 20000)) { - printf( - "Could not open pipe: waited for 20sec!\n" - "If this message was issued before the 20sec finished,\n" - "then the pipe doesn't exist!\n"); + printf("Could not open pipe: waited for 20sec!\n" + "If this message was issued before the 20sec finished,\n" + "then the pipe doesn't exist!\n"); Exit_Requested = true; return; } @@ -465,30 +463,30 @@ static void named_pipe_create(char *pipe_name) ConnectNamedPipe(hPipe, NULL); } -size_t data_write(const void *ptr, size_t size, size_t nitems) +static size_t data_write(const void *ptr, size_t size, size_t nitems) { DWORD cbWritten = 0; if (hPipe != INVALID_HANDLE_VALUE) { - (void)WriteFile(hPipe, /* handle to pipe */ - ptr, /* buffer to write from */ - size * nitems, /* number of bytes to write */ - &cbWritten, /* number of bytes written */ - NULL); /* not overlapped I/O */ + (void)WriteFile(hPipe, /* handle to pipe */ + ptr, /* buffer to write from */ + size * nitems, /* number of bytes to write */ + &cbWritten, /* number of bytes written */ + NULL); /* not overlapped I/O */ } return fwrite(ptr, size, nitems, pFile); } -size_t data_write_header(const void *ptr, size_t size, size_t nitems, - bool pipe_enable) +static size_t data_write_header( + const void *ptr, size_t size, size_t nitems, bool pipe_enable) { DWORD cbWritten = 0; if (pipe_enable && (hPipe != INVALID_HANDLE_VALUE)) { - (void)WriteFile(hPipe, /* handle to pipe */ - ptr, /* buffer to write from */ - size * nitems, /* number of bytes to write */ - &cbWritten, /* number of bytes written */ - NULL); /* not overlapped I/O */ + (void)WriteFile(hPipe, /* handle to pipe */ + ptr, /* buffer to write from */ + size * nitems, /* number of bytes to write */ + &cbWritten, /* number of bytes written */ + NULL); /* not overlapped I/O */ } return fwrite(ptr, size, nitems, pFile); @@ -510,7 +508,7 @@ static void named_pipe_create(char *name) } } -size_t data_write(const void *ptr, size_t size, size_t nitems) +static size_t data_write(const void *ptr, size_t size, size_t nitems) { ssize_t bytes = 0; if (FD_Pipe != -1) { @@ -520,8 +518,8 @@ size_t data_write(const void *ptr, size_t size, size_t nitems) return fwrite(ptr, size, nitems, pFile); } -size_t data_write_header(const void *ptr, size_t size, size_t nitems, - bool pipe_enable) +static size_t data_write_header( + const void *ptr, size_t size, size_t nitems, bool pipe_enable) { ssize_t bytes = 0; if (pipe_enable && (FD_Pipe != -1)) { @@ -541,32 +539,32 @@ static void filename_create(char *filename) my_time = time(NULL); today = localtime(&my_time); sprintf(filename, "mstp_%04d%02d%02d%02d%02d%02d.cap", - 1900 + today->tm_year, 1 + today->tm_mon, today->tm_mday, - today->tm_hour, today->tm_min, today->tm_sec); + 1900 + today->tm_year, 1 + today->tm_mon, today->tm_mday, + today->tm_hour, today->tm_min, today->tm_sec); } } /* write packet to file in libpcap format */ static void write_global_header(const char *filename) { - static bool pipe_enable = true; /* don't write more than one header */ + static bool pipe_enable = true; /* don't write more than one header */ uint32_t magic_number = 0xa1b2c3d4; /* magic number */ - uint16_t version_major = 2; /* major version number */ - uint16_t version_minor = 4; /* minor version number */ - int32_t thiszone = 0; /* GMT to local correction */ - uint32_t sigfigs = 0; /* accuracy of timestamps */ + uint16_t version_major = 2; /* major version number */ + uint16_t version_minor = 4; /* minor version number */ + int32_t thiszone = 0; /* GMT to local correction */ + uint32_t sigfigs = 0; /* accuracy of timestamps */ uint32_t snaplen = 65535; /* max length of captured packets, in octets */ uint32_t network = DLT_BACNET_MS_TP; /* data link type - BACNET_MS_TP */ /* create a new file. */ pFile = fopen(filename, "wb"); if (pFile) { - (void)data_write_header(&magic_number, sizeof(magic_number), 1, - pipe_enable); - (void)data_write_header(&version_major, sizeof(version_major), 1, - pipe_enable); - (void)data_write_header(&version_minor, sizeof(version_minor), 1, - pipe_enable); + (void)data_write_header( + &magic_number, sizeof(magic_number), 1, pipe_enable); + (void)data_write_header( + &version_major, sizeof(version_major), 1, pipe_enable); + (void)data_write_header( + &version_minor, sizeof(version_minor), 1, pipe_enable); (void)data_write_header(&thiszone, sizeof(thiszone), 1, pipe_enable); (void)data_write_header(&sigfigs, sizeof(sigfigs), 1, pipe_enable); (void)data_write_header(&snaplen, sizeof(snaplen), 1, pipe_enable); @@ -577,21 +575,21 @@ static void write_global_header(const char *filename) } } else { fprintf(stderr, "mstpcap[header]: failed to open %s: %s\n", filename, - strerror(errno)); + strerror(errno)); } if (pipe_enable) { pipe_enable = false; } } -static void write_received_packet(volatile struct mstp_port_struct_t *mstp_port, - size_t header_len) +static void write_received_packet( + volatile struct mstp_port_struct_t *mstp_port, size_t header_len) { - uint32_t ts_sec = 0; /* timestamp seconds */ - uint32_t ts_usec = 0; /* timestamp microseconds */ + uint32_t ts_sec = 0; /* timestamp seconds */ + uint32_t ts_usec = 0; /* timestamp microseconds */ uint32_t incl_len = 0; /* number of octets of packet saved in file */ uint32_t orig_len = 0; /* actual length of packet */ - uint8_t header[MSTP_HEADER_MAX] = {0}; /* MS/TP header */ + uint8_t header[MSTP_HEADER_MAX] = { 0 }; /* MS/TP header */ struct timeval tv; size_t max_data = 0; @@ -648,20 +646,20 @@ static void write_received_packet(volatile struct mstp_port_struct_t *mstp_port, } } else { fprintf(stderr, "mstpcap[packet]: failed to open %s: %s\n", - Capture_Filename, strerror(errno)); + Capture_Filename, strerror(errno)); } } /* read header from file in libpcap format */ static bool test_global_header(const char *filename) { - uint32_t magic_number = 0; /* magic number */ + uint32_t magic_number = 0; /* magic number */ uint16_t version_major = 0; /* major version number */ uint16_t version_minor = 0; /* minor version number */ - int32_t thiszone = 0; /* GMT to local correction */ - uint32_t sigfigs = 0; /* accuracy of timestamps */ - uint32_t snaplen = 0; /* max length of captured packets, in octets */ - uint32_t network = 0; /* data link type - BACNET_MS_TP */ + int32_t thiszone = 0; /* GMT to local correction */ + uint32_t sigfigs = 0; /* accuracy of timestamps */ + uint32_t snaplen = 0; /* max length of captured packets, in octets */ + uint32_t network = 0; /* data link type - BACNET_MS_TP */ size_t count = 0; /* open existing file. */ @@ -718,7 +716,7 @@ static bool test_global_header(const char *filename) } } else { fprintf(stderr, "mstpcap[scan]: failed to open %s: %s\n", filename, - strerror(errno)); + strerror(errno)); return false; } @@ -727,11 +725,11 @@ static bool test_global_header(const char *filename) static bool read_received_packet(volatile struct mstp_port_struct_t *mstp_port) { - uint32_t ts_sec = 0; /* timestamp seconds */ - uint32_t ts_usec = 0; /* timestamp microseconds */ - uint32_t incl_len = 0; /* number of octets of packet saved in file */ - uint32_t orig_len = 0; /* actual length of packet */ - uint8_t header[8] = {0}; /* MS/TP header */ + uint32_t ts_sec = 0; /* timestamp seconds */ + uint32_t ts_usec = 0; /* timestamp microseconds */ + uint32_t incl_len = 0; /* number of octets of packet saved in file */ + uint32_t orig_len = 0; /* actual length of packet */ + uint8_t header[8] = { 0 }; /* MS/TP header */ struct timeval tv; size_t count = 0; unsigned i = 0; @@ -814,8 +812,8 @@ static bool read_received_packet(volatile struct mstp_port_struct_t *mstp_port) } mstp_port->DataCRC = 0xFFFF; for (i = 0; i < mstp_port->DataLength; i++) { - mstp_port->DataCRC = CRC_Calc_Data(mstp_port->InputBuffer[i], - mstp_port->DataCRC); + mstp_port->DataCRC = CRC_Calc_Data( + mstp_port->InputBuffer[i], mstp_port->DataCRC); } mstp_port->DataCRC = CRC_Calc_Data(mstp_port->DataCRCActualMSB, mstp_port->DataCRC); @@ -836,7 +834,7 @@ static bool read_received_packet(volatile struct mstp_port_struct_t *mstp_port) if (mstp_port->ReceivedInvalidFrame) { Invalid_Frame_Count++; } else if ((mstp_port->ReceivedValidFrame) || - (mstp_port->ReceivedValidFrameNotForUs)) { + (mstp_port->ReceivedValidFrameNotForUs)) { packet_statistics(&tv, mstp_port); } } else { @@ -889,7 +887,7 @@ static void sig_int(int signo) exit(0); } -void signal_init(void) +static void signal_init(void) { signal(SIGINT, sig_int); signal(SIGHUP, sig_int); @@ -897,7 +895,7 @@ void signal_init(void) } #endif -void filename_create_new(void) +static void filename_create_new(void) { if (pFile) { fclose(pFile); @@ -919,40 +917,37 @@ static void print_usage(char *filename) static void print_help(char *filename) { - printf( - "%s --scan \n" - "perform statistic analysis on MS/TP capture file.\n", + printf("%s --scan \n" + "perform statistic analysis on MS/TP capture file.\n", filename); printf("\n"); - printf( - "Captures MS/TP packets from a serial interface\n" - "and saves them to a file. Saves packets in a\n" - "filename mstp_20090123091200.cap that has data and time.\n" - "After receiving 65535 packets, a new file is created.\n" - "\n" - "Command line options:\n" - "[--extcap-interface port] - serial interface.\n" + printf("Captures MS/TP packets from a serial interface\n" + "and saves them to a file. Saves packets in a\n" + "filename mstp_20090123091200.cap that has data and time.\n" + "After receiving 65535 packets, a new file is created.\n" + "\n" + "Command line options:\n" + "[--extcap-interface port] - serial interface.\n" #if defined(_WIN32) - " Supported values: COM1, COM2, etc.\n" + " Supported values: COM1, COM2, etc.\n" #else - " Supported values: /dev/ttyS0, /dev/ttyUSB0, etc.\n" + " Supported values: /dev/ttyS0, /dev/ttyUSB0, etc.\n" #endif - "[--baud baud] - MS/TP port baud rate.\n" - " Supported values: 9600, 19200, 38400, 57600, 76800, 115200.\n" - " Defaults to 38400.\n" - "[--fifo pipe] - FIFO pipe path and name\n" + "[--baud baud] - MS/TP port baud rate.\n" + " Supported values: 9600, 19200, 38400, 57600, 76800, 115200.\n" + " Defaults to 38400.\n" + "[--fifo pipe] - FIFO pipe path and name\n" #if defined(_WIN32) - " Supported values: \\\\.\\pipe\\wireshark\n" + " Supported values: \\\\.\\pipe\\wireshark\n" #else - " Supported values: any file name\n" + " Supported values: any file name\n" #endif - " Use that name as the interface name in Wireshark.\n"); + " Use that name as the interface name in Wireshark.\n"); printf("\n"); - printf( - "%s [--extcap-interfaces][--extcap-dlts][--extcap-config]\n" - "[--capture][--baud baud][--fifo pipe]\n" - "[--extcap-interface iface]\n" - "Usage from Wireshark ExtCap interface\n", + printf("%s [--extcap-interfaces][--extcap-dlts][--extcap-config]\n" + "[--capture][--baud baud][--fifo pipe]\n" + "[--extcap-interface iface]\n" + "Usage from Wireshark ExtCap interface\n", filename); } @@ -1007,12 +1002,11 @@ int main(int argc, char *argv[]) } if (strcmp(argv[argi], "--version") == 0) { printf("mstpcap %s\n", BACNET_VERSION_TEXT); - printf( - "Copyright (C) 2011-2016 by Steve Karg\n" - "This is free software; see the source for copying " - "conditions.\n" - "There is NO warranty; not even for MERCHANTABILITY or\n" - "FITNESS FOR A PARTICULAR PURPOSE.\n"); + printf("Copyright (C) 2011-2016 by Steve Karg\n" + "This is free software; see the source for copying " + "conditions.\n" + "There is NO warranty; not even for MERCHANTABILITY or\n" + "FITNESS FOR A PARTICULAR PURPOSE.\n"); return 0; } if (strcmp(argv[argi], "--scan") == 0) { @@ -1047,17 +1041,15 @@ int main(int argc, char *argv[]) printf("An interface must be provided.\n"); return 0; } - printf( - "dlt {number=%u}{name=BACnet MS/TP}" - "{display=BACnet MS/TP}\n", + printf("dlt {number=%u}{name=BACnet MS/TP}" + "{display=BACnet MS/TP}\n", DLT_BACNET_MS_TP); Exit_Requested = true; } if (strcmp(argv[argi], "--extcap-config") == 0) { - printf( - "arg {number=0}{call=--baud}{display=Baud Rate}" - "{tooltip=Serial port baud rate in bits per second}" - "{type=selector}\n"); + printf("arg {number=0}{call=--baud}{display=Baud Rate}" + "{tooltip=Serial port baud rate in bits per second}" + "{type=selector}\n"); printf("value {arg=0}{value=9600}{display=9600}{default=false}\n"); printf( "value {arg=0}{value=19200}{display=19200}{default=false}\n"); @@ -1077,9 +1069,8 @@ int main(int argc, char *argv[]) if (strcmp(argv[argi], "--extcap-interface") == 0) { argi++; if (argi >= argc) { - printf( - "An interface must be provided or " - "the selection must be displayed.\n"); + printf("An interface must be provided or " + "the selection must be displayed.\n"); return 0; } RS485_Set_Interface(argv[argi]); @@ -1132,10 +1123,10 @@ int main(int argc, char *argv[]) } atexit(cleanup); RS485_Initialize(); - timer_init(); + mstimer_init(); if (!Wireshark_Capture) { fprintf(stdout, "mstpcap: Using %s for capture at %ld bps.\n", - RS485_Interface(), (long)RS485_Get_Baud_Rate()); + RS485_Interface(), (long)RS485_Get_Baud_Rate()); } #if defined(_WIN32) SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), ENABLE_PROCESSED_INPUT); @@ -1191,7 +1182,7 @@ int main(int argc, char *argv[]) if (!Wireshark_Capture) { if (!(packet_count % 100)) { fprintf(stdout, "\r%hu packets, %hu invalid frames", - packet_count, Invalid_Frame_Count); + packet_count, Invalid_Frame_Count); } if (packet_count >= 65535) { packet_statistics_print(); diff --git a/demo/mstpcap/mstpcap.txt b/apps/mstpcap/mstpcap.txt similarity index 100% rename from demo/mstpcap/mstpcap.txt rename to apps/mstpcap/mstpcap.txt diff --git a/apps/mstpcrc/Makefile b/apps/mstpcrc/Makefile new file mode 100644 index 00000000..c445a934 --- /dev/null +++ b/apps/mstpcrc/Makefile @@ -0,0 +1,51 @@ +#Makefile to build BACnet Application + +# Executable file name +TARGET = mstpcrc + +SRCS = main.c \ + ${BACNET_PORT_DIR}/mstimer-init.c \ + $(BACNET_SRC_DIR)/bacnet/basic/sys/mstimer.c \ + $(BACNET_SRC_DIR)/bacnet/datalink/crc.c + +# BACNET_PORT, BACNET_PORT_DIR, BACNET_PORT_SRC are defined in common Makefile +# BACNET_SRC_DIR is defined in common apps Makefile +# WARNINGS, DEBUGGING, OPTIMIZATION are defined in common apps Makefile +# BACNET_DEFINES is defined in common apps Makefile +# put all the flags together +INCLUDES = -I$(BACNET_SRC_DIR) -I$(BACNET_PORT_DIR) +CFLAGS += $(WARNINGS) $(DEBUGGING) $(OPTIMIZATION) $(BACNET_DEFINES) $(INCLUDES) +LFLAGS += -Wl,$(SYSTEM_LIB) +ifneq (${BACNET_LIB},) +LFLAGS += -Wl,$(BACNET_LIB) +endif +# GCC dead code removal +CFLAGS += -ffunction-sections -fdata-sections +LFLAGS += -Wl,--gc-sections + +OBJS += ${SRCS:.c=.o} + +TARGET_BIN = ${TARGET}$(TARGET_EXT) + +.PHONY: all +all: Makefile ${TARGET_BIN} + +${TARGET_BIN}: ${OBJS} + ${CC} ${PFLAGS} ${OBJS} ${LFLAGS} -o $@ + size $@ + cp $@ ../../bin + +.c.o: + ${CC} -c ${CFLAGS} $*.c -o $@ + +.PHONY: depend +depend: + rm -f .depend + ${CC} -MM ${CFLAGS} *.c >> .depend + +.PHONY: clean +clean: + rm -f core ${TARGET_BIN} ${OBJS} $(TARGET).map + +.PHONY: include +include: .depend diff --git a/demo/mstpcrc/build.bat b/apps/mstpcrc/build.bat similarity index 100% rename from demo/mstpcrc/build.bat rename to apps/mstpcrc/build.bat diff --git a/demo/mstpcrc/main.c b/apps/mstpcrc/main.c similarity index 93% rename from demo/mstpcrc/main.c rename to apps/mstpcrc/main.c index 3338e66f..418daf28 100644 --- a/demo/mstpcrc/main.c +++ b/apps/mstpcrc/main.c @@ -42,12 +42,12 @@ #include #include /* OS specific include*/ -#include "net.h" -#include "timer.h" +#include "bacport.h" /* local includes */ -#include "bytes.h" -#include "crc.h" -#include "version.h" +#include "bacnet/bytes.h" +#include "bacnet/basic/sys/mstimer.h" +#include "bacnet/datalink/crc.h" +#include "bacnet/version.h" #ifndef max #define max(a, b) (((a)(b)) ? (a) : (b)) @@ -64,7 +64,7 @@ static unsigned CRC_Size = 8; static bool MSTP_Cap = false; static bool MSTP_Text_File = false; static char Capture_Filename[64] = "mstp_20090123091200.cap"; -static FILE *pFile = NULL; /* stream pointer */ +static FILE *pFile = NULL; /* stream pointer */ static FILE *pText_File = NULL; /* stream pointer */ /****************************************************************** @@ -162,8 +162,8 @@ static void filename_create(char *filename) my_time = time(NULL); today = localtime(&my_time); sprintf(filename, "mstp_%04d%02d%02d%02d%02d%02d.cap", - 1900 + today->tm_year, 1 + today->tm_mon, today->tm_mday, - today->tm_hour, today->tm_min, today->tm_sec); + 1900 + today->tm_year, 1 + today->tm_mon, today->tm_mday, + today->tm_hour, today->tm_min, today->tm_sec); } } @@ -171,12 +171,12 @@ static void filename_create(char *filename) static void write_global_header(const char *filename) { uint32_t magic_number = 0xa1b2c3d4; /* magic number */ - uint16_t version_major = 2; /* major version number */ - uint16_t version_minor = 4; /* minor version number */ - int32_t thiszone = 0; /* GMT to local correction */ - uint32_t sigfigs = 0; /* accuracy of timestamps */ + uint16_t version_major = 2; /* major version number */ + uint16_t version_minor = 4; /* minor version number */ + int32_t thiszone = 0; /* GMT to local correction */ + uint32_t sigfigs = 0; /* accuracy of timestamps */ uint32_t snaplen = 65535; /* max length of captured packets, in octets */ - uint32_t network = 165; /* data link type - BACNET_MS_TP */ + uint32_t network = 165; /* data link type - BACNET_MS_TP */ /* create a new file. */ pFile = fopen(filename, "wb"); @@ -192,14 +192,14 @@ static void write_global_header(const char *filename) fprintf(stdout, "mstpcap: saving capture to %s\n", filename); } else { fprintf(stderr, "mstpcap[header]: failed to open %s: %s\n", filename, - strerror(errno)); + strerror(errno)); } } static void write_received_packet(uint8_t *buffer, unsigned length) { - uint32_t ts_sec; /* timestamp seconds */ - uint32_t ts_usec; /* timestamp microseconds */ + uint32_t ts_sec; /* timestamp seconds */ + uint32_t ts_usec; /* timestamp microseconds */ uint32_t incl_len; /* number of octets of packet saved in file */ uint32_t orig_len; /* actual length of packet */ struct timeval tv; @@ -216,7 +216,7 @@ static void write_received_packet(uint8_t *buffer, unsigned length) (void)fwrite(buffer, length, 1, pFile); } else { fprintf(stderr, "mstpcrc[packet]: failed to open %s: %s\n", - Capture_Filename, strerror(errno)); + Capture_Filename, strerror(errno)); } } diff --git a/demo/mstpcrc/readme.txt b/apps/mstpcrc/readme.txt similarity index 100% rename from demo/mstpcrc/readme.txt rename to apps/mstpcrc/readme.txt diff --git a/demo/perl/Documentation/index.html b/apps/perl/Documentation/index.html similarity index 100% rename from demo/perl/Documentation/index.html rename to apps/perl/Documentation/index.html diff --git a/demo/perl/Documentation/jquery.js b/apps/perl/Documentation/jquery.js old mode 100755 new mode 100644 similarity index 100% rename from demo/perl/Documentation/jquery.js rename to apps/perl/Documentation/jquery.js diff --git a/demo/perl/Documentation/syntax.css b/apps/perl/Documentation/syntax.css old mode 100755 new mode 100644 similarity index 100% rename from demo/perl/Documentation/syntax.css rename to apps/perl/Documentation/syntax.css diff --git a/demo/perl/Documentation/syntax.js b/apps/perl/Documentation/syntax.js old mode 100755 new mode 100644 similarity index 100% rename from demo/perl/Documentation/syntax.js rename to apps/perl/Documentation/syntax.js diff --git a/demo/perl/bacnet.pl b/apps/perl/bacnet.pl similarity index 100% rename from demo/perl/bacnet.pl rename to apps/perl/bacnet.pl diff --git a/demo/perl/example_readprop.pl b/apps/perl/example_readprop.pl similarity index 100% rename from demo/perl/example_readprop.pl rename to apps/perl/example_readprop.pl diff --git a/demo/perl/perl_bindings.c b/apps/perl/perl_bindings.c similarity index 82% rename from demo/perl/perl_bindings.c rename to apps/perl/perl_bindings.c index 3e5f0c9d..169860f2 100644 --- a/demo/perl/perl_bindings.c +++ b/apps/perl/perl_bindings.c @@ -1,10 +1,10 @@ -#include "bacdef.h" -#include "handlers.h" -#include "bacenum.h" -#include "datalink.h" -#include "device.h" +#include "bacnet/bacdef.h" +#include "bacnet/basic/services.h" +#include "bacnet/bacenum.h" +#include "bacnet/datalink/datalink.h" +#include "bacnet/basic/object/device.h" #include -#include "arf.h" +#include "bacnet/arf.h" /* Free is redefined as a macro, but Perl does not like that. */ #undef free @@ -57,41 +57,42 @@ static void __LogAnswer(const char *msg, unsigned append) /**************************************/ /* error handlers */ /*************************************/ -static void MyAbortHandler(BACNET_ADDRESS *src, uint8_t invoke_id, - uint8_t abort_reason, bool server) +static void MyAbortHandler( + BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t abort_reason, bool server) { (void)server; if (address_match(&Target_Address, src) && (invoke_id == Request_Invoke_ID)) { char msg[MAX_ERROR_STRING]; sprintf(msg, "BACnet Abort: %s", - bactext_abort_reason_name((int)abort_reason)); + bactext_abort_reason_name((int)abort_reason)); LogError(msg); } } -static void MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, - uint8_t reject_reason) +static void MyRejectHandler( + BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason) { if (address_match(&Target_Address, src) && (invoke_id == Request_Invoke_ID)) { char msg[MAX_ERROR_STRING]; sprintf(msg, "BACnet Reject: %s", - bactext_reject_reason_name((int)reject_reason)); + bactext_reject_reason_name((int)reject_reason)); LogError(msg); } } -static void My_Error_Handler(BACNET_ADDRESS *src, uint8_t invoke_id, - BACNET_ERROR_CLASS error_class, - BACNET_ERROR_CODE error_code) +static void My_Error_Handler(BACNET_ADDRESS *src, + uint8_t invoke_id, + BACNET_ERROR_CLASS error_class, + BACNET_ERROR_CODE error_code) { if (address_match(&Target_Address, src) && (invoke_id == Request_Invoke_ID)) { char msg[MAX_ERROR_STRING]; sprintf(msg, "BACnet Error: %s: %s", - bactext_error_class_name((int)error_class), - bactext_error_code_name((int)error_code)); + bactext_error_class_name((int)error_class), + bactext_error_code_name((int)error_code)); LogError(msg); } } @@ -109,7 +110,7 @@ void rp_ack_extract_data(BACNET_READ_PROPERTY_DATA *data) char ackString[MAX_ACK_STRING] = ""; char *pAckString = &ackString[0]; BACNET_OBJECT_PROPERTY_VALUE object_value; /* for bacapp printing */ - BACNET_APPLICATION_DATA_VALUE value; /* for decode value data */ + BACNET_APPLICATION_DATA_VALUE value; /* for decode value data */ int len = 0; uint8_t *application_data; int application_data_len; @@ -136,8 +137,7 @@ void rp_ack_extract_data(BACNET_READ_PROPERTY_DATA *data) object_value.array_index = data->array_index; object_value.value = &value; bacapp_snprintf_value(pAckString, - MAX_ACK_STRING - (pAckString - ackString), - &object_value); + MAX_ACK_STRING - (pAckString - ackString), &object_value); if (len > 0) { if (len < application_data_len) { application_data += len; @@ -193,8 +193,8 @@ void rpm_ack_extract_data(BACNET_READ_ACCESS_DATA *rpm_data) object_value.array_index = listOfProperties->propertyArrayIndex; object_value.value = value; - bacapp_snprintf_value( - pAckString, MAX_ACK_STRING - (pAckString - ackString), + bacapp_snprintf_value(pAckString, + MAX_ACK_STRING - (pAckString - ackString), &object_value); if (value->next) { strncat(pAckString, ",", 1); @@ -210,10 +210,10 @@ void rpm_ack_extract_data(BACNET_READ_ACCESS_DATA *rpm_data) } else { /* AccessError */ sprintf(ackString, "BACnet Error: %s: %s", - bactext_error_class_name( - (int)listOfProperties->error.error_class), - bactext_error_code_name( - (int)listOfProperties->error.error_code)); + bactext_error_class_name( + (int)listOfProperties->error.error_class), + bactext_error_code_name( + (int)listOfProperties->error.error_code)); LogError(ackString); } listOfProperties = listOfProperties->next; @@ -229,8 +229,9 @@ void rpm_ack_extract_data(BACNET_READ_ACCESS_DATA *rpm_data) } } -static void AtomicReadFileAckHandler( - uint8_t *service_request, uint16_t service_len, BACNET_ADDRESS *src, +static void AtomicReadFileAckHandler(uint8_t *service_request, + uint16_t service_len, + BACNET_ADDRESS *src, BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data) { int len = 0; @@ -249,7 +250,7 @@ static void AtomicReadFileAckHandler( int i; sprintf(msg, "EOF=%d,start=%d,", data.endOfFile, - data.type.stream.fileStartPosition); + data.type.stream.fileStartPosition); __LogAnswer(msg, 0); pFileData = octetstring_value(&data.fileData); @@ -276,8 +277,9 @@ static void AtomicReadFileAckHandler( * @param service_data [in] The BACNET_CONFIRMED_SERVICE_DATA information * decoded from the APDU header of this message. */ -static void My_Read_Property_Ack_Handler( - uint8_t *service_request, uint16_t service_len, BACNET_ADDRESS *src, +static void My_Read_Property_Ack_Handler(uint8_t *service_request, + uint16_t service_len, + BACNET_ADDRESS *src, BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data) { int len = 0; @@ -304,8 +306,9 @@ static void My_Read_Property_Ack_Handler( * @param service_data [in] The BACNET_CONFIRMED_SERVICE_DATA information * decoded from the APDU header of this message. */ -static void My_Read_Property_Multiple_Ack_Handler( - uint8_t *service_request, uint16_t service_len, BACNET_ADDRESS *src, +static void My_Read_Property_Multiple_Ack_Handler(uint8_t *service_request, + uint16_t service_len, + BACNET_ADDRESS *src, BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data) { int len = 0; @@ -320,8 +323,8 @@ static void My_Read_Property_Multiple_Ack_Handler( (service_data->invoke_id == Request_Invoke_ID)) { rpm_data = calloc(1, sizeof(BACNET_READ_ACCESS_DATA)); if (rpm_data) { - len = rpm_ack_decode_service_request(service_request, service_len, - rpm_data); + len = rpm_ack_decode_service_request( + service_request, service_len, rpm_data); } if (len > 0) { while (rpm_data) { @@ -388,8 +391,8 @@ static void Init_Service_Handlers() apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service); /* we must implement read property - it's required! */ - apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY, - handler_read_property); + apdu_set_confirmed_handler( + SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property); /* handle generic errors coming back */ apdu_set_abort_handler(MyAbortHandler); @@ -408,8 +411,8 @@ static void Wait_For_Answer_Or_Timeout(unsigned timeout_ms, waitAction action) time_t timeout_seconds = (apdu_timeout() / 1000) * apdu_retries(); time_t elapsed_seconds = 0; uint16_t pdu_len = 0; - BACNET_ADDRESS src = {0}; /* address where message came from */ - uint8_t Rx_Buf[MAX_MPDU] = {0}; + BACNET_ADDRESS src = { 0 }; /* address where message came from */ + uint8_t Rx_Buf[MAX_MPDU] = { 0 }; while (true) { time_t current_seconds = time(NULL); @@ -447,7 +450,7 @@ static void Wait_For_Answer_Or_Timeout(unsigned timeout_ms, waitAction action) } } else if (action == waitBind) { if (address_bind_request(Target_Device_Object_Instance, - &Target_Max_APDU, &Target_Address)) { + &Target_Max_APDU, &Target_Address)) { break; } } else { @@ -490,10 +493,10 @@ int BacnetBindToDevice(int deviceInstanceNumber) Target_Device_Object_Instance = deviceInstanceNumber; /* try to bind with the device */ - if (!address_bind_request(deviceInstanceNumber, &Target_Max_APDU, - &Target_Address)) { - Send_WhoIs(Target_Device_Object_Instance, - Target_Device_Object_Instance); + if (!address_bind_request( + deviceInstanceNumber, &Target_Max_APDU, &Target_Address)) { + Send_WhoIs( + Target_Device_Object_Instance, Target_Device_Object_Instance); /* Wait for timeout, failure, or success */ Wait_For_Answer_Or_Timeout(100, waitBind); @@ -507,26 +510,27 @@ int BacnetBindToDevice(int deviceInstanceNumber) /****************************************************/ /* This is the interface to ReadProperty */ /****************************************************/ -int BacnetReadProperty(int deviceInstanceNumber, int objectType, - int objectInstanceNumber, int objectProperty, - int objectIndex) +int BacnetReadProperty(int deviceInstanceNumber, + int objectType, + int objectInstanceNumber, + int objectProperty, + int objectIndex) { if (!isReadPropertyHandlerRegistered) { /* handle the data coming back from confirmed requests */ - apdu_set_confirmed_ack_handler(SERVICE_CONFIRMED_READ_PROPERTY, - My_Read_Property_Ack_Handler); + apdu_set_confirmed_ack_handler( + SERVICE_CONFIRMED_READ_PROPERTY, My_Read_Property_Ack_Handler); /* handle any errors coming back */ - apdu_set_error_handler(SERVICE_CONFIRMED_READ_PROPERTY, - My_Error_Handler); + apdu_set_error_handler( + SERVICE_CONFIRMED_READ_PROPERTY, My_Error_Handler); /* indicate that handlers are now registered */ isReadPropertyHandlerRegistered = true; } /* Send the message out */ - Request_Invoke_ID = Send_Read_Property_Request( - deviceInstanceNumber, objectType, objectInstanceNumber, objectProperty, - objectIndex); + Request_Invoke_ID = Send_Read_Property_Request(deviceInstanceNumber, + objectType, objectInstanceNumber, objectProperty, objectIndex); Wait_For_Answer_Or_Timeout(100, waitAnswer); int isFailure = Error_Detected; @@ -546,7 +550,7 @@ int BacnetReadPropertyMultiple(int deviceInstanceNumber, ...) calloc(1, sizeof(BACNET_READ_ACCESS_DATA)); BACNET_READ_ACCESS_DATA *Read_Access_Data = rpm_object; BACNET_PROPERTY_REFERENCE *rpm_property; - uint8_t buffer[MAX_PDU] = {0}; + uint8_t buffer[MAX_PDU] = { 0 }; while (rpmIndex < Inline_Stack_Items) { SV *pSV = Inline_Stack_Item(rpmIndex++); @@ -622,11 +626,11 @@ int BacnetReadPropertyMultiple(int deviceInstanceNumber, ...) if (!isReadPropertyMultipleHandlerRegistered) { /* handle the data coming back from confirmed requests */ apdu_set_confirmed_ack_handler(SERVICE_CONFIRMED_READ_PROP_MULTIPLE, - My_Read_Property_Multiple_Ack_Handler); + My_Read_Property_Multiple_Ack_Handler); /* handle any errors coming back */ - apdu_set_error_handler(SERVICE_CONFIRMED_READ_PROP_MULTIPLE, - My_Error_Handler); + apdu_set_error_handler( + SERVICE_CONFIRMED_READ_PROP_MULTIPLE, My_Error_Handler); /* indicate that handlers are now registered */ isReadPropertyMultipleHandlerRegistered = true; @@ -664,23 +668,26 @@ int BacnetReadPropertyMultiple(int deviceInstanceNumber, ...) /****************************************************/ /* This is the interface to WriteProperty */ /****************************************************/ -int BacnetWriteProperty(int deviceInstanceNumber, int objectType, - int objectInstanceNumber, int objectProperty, - int objectPriority, int objectIndex, const char *tag, - const char *value) +int BacnetWriteProperty(int deviceInstanceNumber, + int objectType, + int objectInstanceNumber, + int objectProperty, + int objectPriority, + int objectIndex, + const char *tag, + const char *value) { char msg[MAX_ERROR_STRING]; int isFailure = 1; if (!isWritePropertyHandlerRegistered) { /* handle the ack coming back */ - apdu_set_confirmed_simple_ack_handler( - SERVICE_CONFIRMED_WRITE_PROPERTY, + apdu_set_confirmed_simple_ack_handler(SERVICE_CONFIRMED_WRITE_PROPERTY, My_Write_Property_SimpleAck_Handler); /* handle any errors coming back */ - apdu_set_error_handler(SERVICE_CONFIRMED_WRITE_PROPERTY, - My_Error_Handler); + apdu_set_error_handler( + SERVICE_CONFIRMED_WRITE_PROPERTY, My_Error_Handler); /* indicate that handlers are now registered */ isWritePropertyHandlerRegistered = true; @@ -707,12 +714,12 @@ int BacnetWriteProperty(int deviceInstanceNumber, int objectType, if (property_tag >= MAX_BACNET_APPLICATION_TAG) { sprintf(msg, "Error: tag=%u - it must be less than %u", - property_tag, MAX_BACNET_APPLICATION_TAG); + property_tag, MAX_BACNET_APPLICATION_TAG); LogError(msg); break; } - if (!bacapp_parse_application_data(property_tag, value, - &propertyValue)) { + if (!bacapp_parse_application_data( + property_tag, value, &propertyValue)) { sprintf(msg, "Error: unable to parse the tag value"); LogError(msg); break; @@ -720,9 +727,9 @@ int BacnetWriteProperty(int deviceInstanceNumber, int objectType, propertyValue.next = NULL; /* Send out the message */ - Request_Invoke_ID = Send_Write_Property_Request( - deviceInstanceNumber, objectType, objectInstanceNumber, - objectProperty, &propertyValue, objectPriority, objectIndex); + Request_Invoke_ID = Send_Write_Property_Request(deviceInstanceNumber, + objectType, objectInstanceNumber, objectProperty, &propertyValue, + objectPriority, objectIndex); Wait_For_Answer_Or_Timeout(100, waitAnswer); /* If we get here, then there were no explicit failures. However, there @@ -736,9 +743,11 @@ int BacnetWriteProperty(int deviceInstanceNumber, int objectType, return isFailure; } -int BacnetAtomicWriteFile(int deviceInstanceNumber, int fileInstanceNumber, - int blockStartAddr, int blockNumBytes, - char *nibbleBuffer) +int BacnetAtomicWriteFile(int deviceInstanceNumber, + int fileInstanceNumber, + int blockStartAddr, + int blockNumBytes, + char *nibbleBuffer) { BACNET_OCTET_STRING fileData; int i, nibble; @@ -747,8 +756,8 @@ int BacnetAtomicWriteFile(int deviceInstanceNumber, int fileInstanceNumber, if (!isAtomicWriteFileHandlerRegistered) { /* handle any errors coming back */ - apdu_set_error_handler(SERVICE_CONFIRMED_ATOMIC_WRITE_FILE, - My_Error_Handler); + apdu_set_error_handler( + SERVICE_CONFIRMED_ATOMIC_WRITE_FILE, My_Error_Handler); /* indicate that handlers are now registered */ isAtomicWriteFileHandlerRegistered = true; @@ -772,9 +781,8 @@ int BacnetAtomicWriteFile(int deviceInstanceNumber, int fileInstanceNumber, /* Send out the message and wait for answer */ if (!Error_Detected) { - Request_Invoke_ID = Send_Atomic_Write_File_Stream( - deviceInstanceNumber, fileInstanceNumber, blockStartAddr, - &fileData); + Request_Invoke_ID = Send_Atomic_Write_File_Stream(deviceInstanceNumber, + fileInstanceNumber, blockStartAddr, &fileData); Wait_For_Answer_Or_Timeout(100, waitAnswer); } @@ -811,8 +819,15 @@ int BacnetGetMaxApdu() return requestedOctetCount; } -int BacnetTimeSync(int deviceInstanceNumber, int year, int month, int day, - int hour, int minute, int second, int isUTC, int UTCOffset) +int BacnetTimeSync(int deviceInstanceNumber, + int year, + int month, + int day, + int hour, + int minute, + int second, + int isUTC, + int UTCOffset) { BACNET_DATE bdate; BACNET_TIME btime; @@ -826,8 +841,8 @@ int BacnetTimeSync(int deviceInstanceNumber, int year, int month, int day, my_time.tm_mday = day; my_time.tm_mon = month - 1; my_time.tm_year = year - 1900; - my_time.tm_wday = 0; /* does not matter */ - my_time.tm_yday = 0; /* does not matter */ + my_time.tm_wday = 0; /* does not matter */ + my_time.tm_yday = 0; /* does not matter */ my_time.tm_isdst = 0; /* does not matter */ aTime = mktime(&my_time); @@ -847,7 +862,7 @@ int BacnetTimeSync(int deviceInstanceNumber, int year, int month, int day, int bytes_sent = 0; BACNET_NPDU_DATA npdu_data; BACNET_ADDRESS my_address; - uint8_t Handler_Transmit_Buffer[MAX_PDU] = {0}; + uint8_t Handler_Transmit_Buffer[MAX_PDU] = { 0 }; /* Loop for eary exit */ do { @@ -860,21 +875,21 @@ int BacnetTimeSync(int deviceInstanceNumber, int year, int month, int day, npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL); datalink_get_my_address(&my_address); pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], &Target_Address, - &my_address, &npdu_data); + &my_address, &npdu_data); /* encode the APDU portion of the packet */ - len = timesync_encode_apdu(&Handler_Transmit_Buffer[pdu_len], &bdate, - &btime); + len = timesync_encode_apdu( + &Handler_Transmit_Buffer[pdu_len], &bdate, &btime); pdu_len += len; /* send it out the datalink */ - bytes_sent = datalink_send_pdu(&Target_Address, &npdu_data, - &Handler_Transmit_Buffer[0], pdu_len); + bytes_sent = datalink_send_pdu( + &Target_Address, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len); if (bytes_sent <= 0) { char errorMsg[64]; sprintf(errorMsg, - "Failed to Send Time-Synchronization Request (%s)!", - strerror(errno)); + "Failed to Send Time-Synchronization Request (%s)!", + strerror(errno)); LogError(errorMsg); break; } @@ -890,17 +905,19 @@ int BacnetTimeSync(int deviceInstanceNumber, int year, int month, int day, /****************************************************/ /* This is the interface to AtomicReadFile */ /****************************************************/ -int BacnetAtomicReadFile(int deviceInstanceNumber, int fileInstanceNumber, - int startOffset, int numBytes) +int BacnetAtomicReadFile(int deviceInstanceNumber, + int fileInstanceNumber, + int startOffset, + int numBytes) { if (!isAtomicReadFileHandlerRegistered) { /* handle the data coming back from confirmed requests */ - apdu_set_confirmed_ack_handler(SERVICE_CONFIRMED_ATOMIC_READ_FILE, - AtomicReadFileAckHandler); + apdu_set_confirmed_ack_handler( + SERVICE_CONFIRMED_ATOMIC_READ_FILE, AtomicReadFileAckHandler); /* handle any errors coming back */ - apdu_set_error_handler(SERVICE_CONFIRMED_ATOMIC_READ_FILE, - My_Error_Handler); + apdu_set_error_handler( + SERVICE_CONFIRMED_ATOMIC_READ_FILE, My_Error_Handler); /* indicate that handlers are now registered */ isAtomicReadFileHandlerRegistered = true; diff --git a/demo/perl/readme.txt b/apps/perl/readme.txt similarity index 100% rename from demo/perl/readme.txt rename to apps/perl/readme.txt diff --git a/demo/piface/Makefile b/apps/piface/Makefile similarity index 100% rename from demo/piface/Makefile rename to apps/piface/Makefile diff --git a/demo/piface/configure.sh b/apps/piface/configure.sh old mode 100755 new mode 100644 similarity index 100% rename from demo/piface/configure.sh rename to apps/piface/configure.sh diff --git a/demo/piface/device.c b/apps/piface/device.c similarity index 85% rename from demo/piface/device.c rename to apps/piface/device.c index b0afa3d1..0c45fc10 100644 --- a/demo/piface/device.c +++ b/apps/piface/device.c @@ -25,29 +25,29 @@ #include #include #include /* for memmove */ -#include /* for timezone, localtime */ -#include "bacdef.h" -#include "bacdcode.h" -#include "bacenum.h" -#include "bacapp.h" -#include "config.h" /* the custom stuff */ -#include "apdu.h" -#include "wp.h" /* WriteProperty handling */ -#include "rp.h" /* ReadProperty handling */ -#include "dcc.h" /* DeviceCommunicationControl handling */ -#include "version.h" -#include "device.h" /* me */ -#include "handlers.h" -#include "datalink.h" -#include "address.h" +#include /* for timezone, localtime */ +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacenum.h" +#include "bacnet/bacapp.h" +#include "bacnet/config.h" /* the custom stuff */ +#include "bacnet/apdu.h" +#include "bacnet/wp.h" /* WriteProperty handling */ +#include "bacnet/rp.h" /* ReadProperty handling */ +#include "bacnet/dcc.h" /* DeviceCommunicationControl handling */ +#include "bacnet/version.h" +#include "bacnet/basic/object/device.h" /* me */ +#include "bacnet/basic/services.h" +#include "bacnet/datalink/datalink.h" +#include "bacnet/basic/binding/address.h" /* include the OS specific */ -#include "timer.h" +#include "bacnet/basic/sys/mstimer.h" /* include the device object */ -#include "device.h" -#include "bi.h" -#include "bo.h" +#include "bacnet/basic/object/device.h" +#include "bacnet/basic/object/bi.h" +#include "bacnet/basic/object/bo.h" #if (BACNET_PROTOCOL_REVISION >= 17) -#include "netport.h" +#include "bacnet/basic/object/netport.h" #endif /* local forward (semi-private) and external prototypes */ @@ -61,40 +61,42 @@ extern bool Routed_Device_Write_Property_Local( static object_functions_t *Object_Table; static object_functions_t My_Object_Table[] = { - {OBJECT_DEVICE, NULL /* Init - don't init Device or it will recourse! */, - Device_Count, Device_Index_To_Instance, - Device_Valid_Object_Instance_Number, Device_Object_Name, - Device_Read_Property_Local, Device_Write_Property_Local, - Device_Property_Lists, DeviceGetRRInfo, NULL /* Iterator */, - NULL /* Value_Lists */, NULL /* COV */, NULL /* COV Clear */, - NULL /* Intrinsic Reporting */}, + { OBJECT_DEVICE, NULL /* Init - don't init Device or it will recourse! */, + Device_Count, Device_Index_To_Instance, + Device_Valid_Object_Instance_Number, Device_Object_Name, + Device_Read_Property_Local, Device_Write_Property_Local, + Device_Property_Lists, DeviceGetRRInfo, NULL /* Iterator */, + NULL /* Value_Lists */, NULL /* COV */, NULL /* COV Clear */, + NULL /* Intrinsic Reporting */ }, #if (BACNET_PROTOCOL_REVISION >= 17) - {OBJECT_NETWORK_PORT, Network_Port_Init, Network_Port_Count, - Network_Port_Index_To_Instance, Network_Port_Valid_Instance, - Network_Port_Object_Name, Network_Port_Read_Property, - Network_Port_Write_Property, Network_Port_Property_Lists, - NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */, - NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */}, + { OBJECT_NETWORK_PORT, Network_Port_Init, Network_Port_Count, + Network_Port_Index_To_Instance, Network_Port_Valid_Instance, + Network_Port_Object_Name, Network_Port_Read_Property, + Network_Port_Write_Property, Network_Port_Property_Lists, + NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */, + NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */ }, #endif - {OBJECT_BINARY_INPUT, Binary_Input_Init, Binary_Input_Count, - Binary_Input_Index_To_Instance, Binary_Input_Valid_Instance, - Binary_Input_Object_Name, Binary_Input_Read_Property, - Binary_Input_Write_Property, Binary_Input_Property_Lists, - NULL /* ReadRangeInfo */, NULL /* Iterator */, - Binary_Input_Encode_Value_List, Binary_Input_Change_Of_Value, - Binary_Input_Change_Of_Value_Clear, NULL /* Intrinsic Reporting */}, - {OBJECT_BINARY_OUTPUT, Binary_Output_Init, Binary_Output_Count, - Binary_Output_Index_To_Instance, Binary_Output_Valid_Instance, - Binary_Output_Object_Name, Binary_Output_Read_Property, - Binary_Output_Write_Property, Binary_Output_Property_Lists, - NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */, - NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */}, - {MAX_BACNET_OBJECT_TYPE, NULL /* Init */, NULL /* Count */, - NULL /* Index_To_Instance */, NULL /* Valid_Instance */, - NULL /* Object_Name */, NULL /* Read_Property */, - NULL /* Write_Property */, NULL /* Property_Lists */, - NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */, - NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */}}; + { OBJECT_BINARY_INPUT, Binary_Input_Init, Binary_Input_Count, + Binary_Input_Index_To_Instance, Binary_Input_Valid_Instance, + Binary_Input_Object_Name, Binary_Input_Read_Property, + Binary_Input_Write_Property, Binary_Input_Property_Lists, + NULL /* ReadRangeInfo */, NULL /* Iterator */, + Binary_Input_Encode_Value_List, Binary_Input_Change_Of_Value, + Binary_Input_Change_Of_Value_Clear, NULL /* Intrinsic Reporting */ }, + { OBJECT_BINARY_OUTPUT, Binary_Output_Init, Binary_Output_Count, + Binary_Output_Index_To_Instance, Binary_Output_Valid_Instance, + Binary_Output_Object_Name, Binary_Output_Read_Property, + Binary_Output_Write_Property, Binary_Output_Property_Lists, + NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */, + NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */ }, + { MAX_BACNET_OBJECT_TYPE, NULL /* Init */, NULL /* Count */, + NULL /* Index_To_Instance */, NULL /* Valid_Instance */, + NULL /* Object_Name */, NULL /* Read_Property */, + NULL /* Write_Property */, NULL /* Property_Lists */, + NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */, + NULL /* COV */, NULL /* COV Clear */, + NULL /* Intrinsic Reporting */ } +}; /** Glue function to let the Device object, when called by a handler, * lookup which Object type needs to be invoked. @@ -152,8 +154,8 @@ rr_info_function Device_Objects_RR_Info(BACNET_OBJECT_TYPE object_type) * properties with their counts. */ void Device_Objects_Property_List(BACNET_OBJECT_TYPE object_type, - uint32_t object_instance, - struct special_property_list_t *pPropertyList) + uint32_t object_instance, + struct special_property_list_t *pPropertyList) { struct object_functions *pObject = NULL; @@ -170,78 +172,59 @@ void Device_Objects_Property_List(BACNET_OBJECT_TYPE object_type, pObject = Device_Objects_Find_Functions(object_type); if ((pObject != NULL) && (pObject->Object_RPM_List != NULL)) { pObject->Object_RPM_List(&pPropertyList->Required.pList, - &pPropertyList->Optional.pList, - &pPropertyList->Proprietary.pList); + &pPropertyList->Optional.pList, &pPropertyList->Proprietary.pList); } /* Fetch the counts if available otherwise zero them */ - pPropertyList->Required.count = - pPropertyList->Required.pList == NULL - ? 0 - : property_list_count(pPropertyList->Required.pList); + pPropertyList->Required.count = pPropertyList->Required.pList == NULL + ? 0 + : property_list_count(pPropertyList->Required.pList); - pPropertyList->Optional.count = - pPropertyList->Optional.pList == NULL - ? 0 - : property_list_count(pPropertyList->Optional.pList); + pPropertyList->Optional.count = pPropertyList->Optional.pList == NULL + ? 0 + : property_list_count(pPropertyList->Optional.pList); - pPropertyList->Proprietary.count = - pPropertyList->Proprietary.pList == NULL - ? 0 - : property_list_count(pPropertyList->Proprietary.pList); + pPropertyList->Proprietary.count = pPropertyList->Proprietary.pList == NULL + ? 0 + : property_list_count(pPropertyList->Proprietary.pList); return; } /* These three arrays are used by the ReadPropertyMultiple handler */ -static const int Device_Properties_Required[] = { - PROP_OBJECT_IDENTIFIER, - PROP_OBJECT_NAME, - PROP_OBJECT_TYPE, - PROP_SYSTEM_STATUS, - PROP_VENDOR_NAME, - PROP_VENDOR_IDENTIFIER, - PROP_MODEL_NAME, - PROP_FIRMWARE_REVISION, - PROP_APPLICATION_SOFTWARE_VERSION, - PROP_PROTOCOL_VERSION, - PROP_PROTOCOL_REVISION, - PROP_PROTOCOL_SERVICES_SUPPORTED, - PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED, - PROP_OBJECT_LIST, - PROP_MAX_APDU_LENGTH_ACCEPTED, - PROP_SEGMENTATION_SUPPORTED, - PROP_APDU_TIMEOUT, - PROP_NUMBER_OF_APDU_RETRIES, - PROP_DEVICE_ADDRESS_BINDING, - PROP_DATABASE_REVISION, - -1}; +static const int Device_Properties_Required[] = { PROP_OBJECT_IDENTIFIER, + PROP_OBJECT_NAME, PROP_OBJECT_TYPE, PROP_SYSTEM_STATUS, PROP_VENDOR_NAME, + PROP_VENDOR_IDENTIFIER, PROP_MODEL_NAME, PROP_FIRMWARE_REVISION, + PROP_APPLICATION_SOFTWARE_VERSION, PROP_PROTOCOL_VERSION, + PROP_PROTOCOL_REVISION, PROP_PROTOCOL_SERVICES_SUPPORTED, + PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED, PROP_OBJECT_LIST, + PROP_MAX_APDU_LENGTH_ACCEPTED, PROP_SEGMENTATION_SUPPORTED, + PROP_APDU_TIMEOUT, PROP_NUMBER_OF_APDU_RETRIES, PROP_DEVICE_ADDRESS_BINDING, + PROP_DATABASE_REVISION, -1 }; static const int Device_Properties_Optional[] = { #if defined(BACDL_MSTP) - PROP_MAX_MASTER, - PROP_MAX_INFO_FRAMES, + PROP_MAX_MASTER, PROP_MAX_INFO_FRAMES, #endif - PROP_DESCRIPTION, - PROP_LOCAL_TIME, - PROP_UTC_OFFSET, - PROP_LOCAL_DATE, - PROP_DAYLIGHT_SAVINGS_STATUS, - PROP_LOCATION, - PROP_ACTIVE_COV_SUBSCRIPTIONS, - -1}; + PROP_DESCRIPTION, PROP_LOCAL_TIME, PROP_UTC_OFFSET, PROP_LOCAL_DATE, + PROP_DAYLIGHT_SAVINGS_STATUS, PROP_LOCATION, PROP_ACTIVE_COV_SUBSCRIPTIONS, + -1 +}; -static const int Device_Properties_Proprietary[] = {-1}; +static const int Device_Properties_Proprietary[] = { -1 }; -void Device_Property_Lists(const int **pRequired, const int **pOptional, - const int **pProprietary) +void Device_Property_Lists( + const int **pRequired, const int **pOptional, const int **pProprietary) { - if (pRequired) + if (pRequired) { *pRequired = Device_Properties_Required; - if (pOptional) + } + if (pOptional) { *pOptional = Device_Properties_Optional; - if (pProprietary) + } + if (pProprietary) { *pProprietary = Device_Properties_Proprietary; + } return; } @@ -258,6 +241,7 @@ static char *Vendor_Name = BACNET_VENDOR_NAME; static uint16_t Vendor_Identifier = BACNET_VENDOR_ID; static char Model_Name[MAX_DEV_MOD_LEN + 1] = "PiFace Digital"; static char Application_Software_Version[MAX_DEV_VER_LEN + 1] = "1.0"; +static const char *BACnet_Version = BACNET_VERSION_TEXT; static char Location[MAX_DEV_LOC_LEN + 1] = "USA"; static char Description[MAX_DEV_DESC_LEN + 1] = "Raspberry PiFace Digital Demo"; /* static uint8_t Protocol_Version = 1; - constant, not settable */ @@ -403,8 +387,8 @@ bool Device_Valid_Object_Instance_Number(uint32_t object_id) return (Object_Instance_Number == object_id); } -bool Device_Object_Name(uint32_t object_instance, - BACNET_CHARACTER_STRING *object_name) +bool Device_Object_Name( + uint32_t object_instance, BACNET_CHARACTER_STRING *object_name) { bool status = false; @@ -660,8 +644,8 @@ unsigned Device_Object_List_Count(void) * @param instance [out] The object's instance number, if found. * @return True if found, else false. */ -bool Device_Object_List_Identifier(uint32_t array_index, int *object_type, - uint32_t *instance) +bool Device_Object_List_Identifier( + uint32_t array_index, int *object_type, uint32_t *instance) { bool status = false; uint32_t count = 0; @@ -719,7 +703,8 @@ bool Device_Object_List_Identifier(uint32_t array_index, int *object_type, * @return True on success or else False if not found. */ bool Device_Valid_Object_Name(BACNET_CHARACTER_STRING *object_name1, - int *object_type, uint32_t *object_instance) + int *object_type, + uint32_t *object_instance) { bool found = false; int type = 0; @@ -736,7 +721,7 @@ bool Device_Valid_Object_Name(BACNET_CHARACTER_STRING *object_name1, pObject = Device_Objects_Find_Functions(type); if ((pObject != NULL) && (pObject->Object_Name != NULL) && (pObject->Object_Name(instance, &object_name2) && - characterstring_same(object_name1, &object_name2))) { + characterstring_same(object_name1, &object_name2))) { found = true; if (object_type) { *object_type = type; @@ -777,8 +762,8 @@ bool Device_Valid_Object_Id(int object_type, uint32_t object_instance) * @return True on success or else False if not found. */ bool Device_Object_Name_Copy(BACNET_OBJECT_TYPE object_type, - uint32_t object_instance, - BACNET_CHARACTER_STRING *object_name) + uint32_t object_instance, + BACNET_CHARACTER_STRING *object_name) { struct object_functions *pObject = NULL; bool found = false; @@ -823,15 +808,14 @@ int tm_isdst Daylight Savings flag. if (tblock) { datetime_set_date(&Local_Date, (uint16_t)tblock->tm_year + 1900, - (uint8_t)tblock->tm_mon + 1, - (uint8_t)tblock->tm_mday); + (uint8_t)tblock->tm_mon + 1, (uint8_t)tblock->tm_mday); #if !defined(_MSC_VER) datetime_set_time(&Local_Time, (uint8_t)tblock->tm_hour, - (uint8_t)tblock->tm_min, (uint8_t)tblock->tm_sec, - (uint8_t)(tv.tv_usec / 10000)); + (uint8_t)tblock->tm_min, (uint8_t)tblock->tm_sec, + (uint8_t)(tv.tv_usec / 10000)); #else datetime_set_time(&Local_Time, (uint8_t)tblock->tm_hour, - (uint8_t)tblock->tm_min, (uint8_t)tblock->tm_sec, 0); + (uint8_t)tblock->tm_min, (uint8_t)tblock->tm_sec, 0); #endif if (tblock->tm_isdst) { Daylight_Savings_Status = true; @@ -872,9 +856,9 @@ bool Device_Daylight_Savings_Status(void) int Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA *rpdata) { int apdu_len = 0; /* return value */ - int len = 0; /* apdu len intermediate value */ - BACNET_BIT_STRING bit_string = {0}; - BACNET_CHARACTER_STRING char_string = {0}; + int len = 0; /* apdu len intermediate value */ + BACNET_BIT_STRING bit_string = { 0 }; + BACNET_CHARACTER_STRING char_string = { 0 }; uint32_t i = 0; int object_type = 0; uint32_t instance = 0; @@ -892,8 +876,8 @@ int Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA *rpdata) apdu_max = rpdata->application_data_len; switch (rpdata->object_property) { case PROP_OBJECT_IDENTIFIER: - apdu_len = encode_application_object_id(&apdu[0], OBJECT_DEVICE, - Object_Instance_Number); + apdu_len = encode_application_object_id( + &apdu[0], OBJECT_DEVICE, Object_Instance_Number); break; case PROP_OBJECT_NAME: apdu_len = @@ -929,8 +913,8 @@ int Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA *rpdata) encode_application_character_string(&apdu[0], &char_string); break; case PROP_APPLICATION_SOFTWARE_VERSION: - characterstring_init_ansi(&char_string, - Application_Software_Version); + characterstring_init_ansi( + &char_string, Application_Software_Version); apdu_len = encode_application_character_string(&apdu[0], &char_string); break; @@ -957,20 +941,19 @@ int Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA *rpdata) encode_application_boolean(&apdu[0], Daylight_Savings_Status); break; case PROP_PROTOCOL_VERSION: - apdu_len = encode_application_unsigned(&apdu[0], - Device_Protocol_Version()); + apdu_len = encode_application_unsigned( + &apdu[0], Device_Protocol_Version()); break; case PROP_PROTOCOL_REVISION: - apdu_len = encode_application_unsigned(&apdu[0], - Device_Protocol_Revision()); + apdu_len = encode_application_unsigned( + &apdu[0], Device_Protocol_Revision()); break; case PROP_PROTOCOL_SERVICES_SUPPORTED: /* Note: list of services that are executed, not initiated. */ bitstring_init(&bit_string); for (i = 0; i < MAX_BACNET_SERVICES_SUPPORTED; i++) { /* automatic lookup based on handlers set */ - bitstring_set_bit( - &bit_string, (uint8_t)i, + bitstring_set_bit(&bit_string, (uint8_t)i, apdu_service_supported((BACNET_SERVICES_SUPPORTED)i)); } apdu_len = encode_application_bitstring(&apdu[0], &bit_string); @@ -1005,8 +988,8 @@ int Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA *rpdata) /* your maximum APDU size. */ else if (rpdata->array_index == BACNET_ARRAY_ALL) { for (i = 1; i <= count; i++) { - found = Device_Object_List_Identifier(i, &object_type, - &instance); + found = Device_Object_List_Identifier( + i, &object_type, &instance); if (found) { len = encode_application_object_id( &apdu[apdu_len], object_type, instance); @@ -1030,8 +1013,8 @@ int Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA *rpdata) } } } else { - found = Device_Object_List_Identifier(rpdata->array_index, - &object_type, &instance); + found = Device_Object_List_Identifier( + rpdata->array_index, &object_type, &instance); if (found) { apdu_len = encode_application_object_id( &apdu[0], object_type, instance); @@ -1132,8 +1115,8 @@ bool Device_Write_Property_Local(BACNET_WRITE_PROPERTY_DATA *wp_data) int temp; /* decode the some of the request */ - len = bacapp_decode_application_data(wp_data->application_data, - wp_data->application_data_len, &value); + len = bacapp_decode_application_data( + wp_data->application_data, wp_data->application_data_len, &value); if (len < 0) { /* error while decoding - a value larger than we can handle */ wp_data->error_class = ERROR_CLASS_PROPERTY; @@ -1150,9 +1133,8 @@ bool Device_Write_Property_Local(BACNET_WRITE_PROPERTY_DATA *wp_data) /* FIXME: len < application_data_len: more data? */ switch (wp_data->object_property) { case PROP_OBJECT_IDENTIFIER: - status = - WPValidateArgType(&value, BACNET_APPLICATION_TAG_OBJECT_ID, - &wp_data->error_class, &wp_data->error_code); + status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_OBJECT_ID, + &wp_data->error_class, &wp_data->error_code); if (status) { if ((value.type.Object_Id.type == OBJECT_DEVICE) && (Device_Set_Object_Instance_Number( @@ -1169,7 +1151,7 @@ bool Device_Write_Property_Local(BACNET_WRITE_PROPERTY_DATA *wp_data) case PROP_NUMBER_OF_APDU_RETRIES: status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_UNSIGNED_INT, - &wp_data->error_class, &wp_data->error_code); + &wp_data->error_class, &wp_data->error_code); if (status) { /* FIXME: bounds check? */ apdu_retries_set((uint8_t)value.type.Unsigned_Int); @@ -1178,7 +1160,7 @@ bool Device_Write_Property_Local(BACNET_WRITE_PROPERTY_DATA *wp_data) case PROP_APDU_TIMEOUT: status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_UNSIGNED_INT, - &wp_data->error_class, &wp_data->error_code); + &wp_data->error_class, &wp_data->error_code); if (status) { /* FIXME: bounds check? */ apdu_timeout_set((uint16_t)value.type.Unsigned_Int); @@ -1187,7 +1169,7 @@ bool Device_Write_Property_Local(BACNET_WRITE_PROPERTY_DATA *wp_data) case PROP_VENDOR_IDENTIFIER: status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_UNSIGNED_INT, - &wp_data->error_class, &wp_data->error_code); + &wp_data->error_class, &wp_data->error_code); if (status) { /* FIXME: bounds check? */ Device_Set_Vendor_Identifier((uint16_t)value.type.Unsigned_Int); @@ -1196,7 +1178,7 @@ bool Device_Write_Property_Local(BACNET_WRITE_PROPERTY_DATA *wp_data) case PROP_SYSTEM_STATUS: status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_ENUMERATED, - &wp_data->error_class, &wp_data->error_code); + &wp_data->error_class, &wp_data->error_code); if (status) { temp = Device_Set_System_Status( (BACNET_DEVICE_STATUS)value.type.Enumerated, false); @@ -1213,13 +1195,13 @@ bool Device_Write_Property_Local(BACNET_WRITE_PROPERTY_DATA *wp_data) } break; case PROP_OBJECT_NAME: - status = WPValidateString( - &value, characterstring_capacity(&My_Object_Name), false, + status = WPValidateString(&value, + characterstring_capacity(&My_Object_Name), false, &wp_data->error_class, &wp_data->error_code); if (status) { /* All the object names in a device must be unique */ if (Device_Valid_Object_Name(&value.type.Character_String, - &object_type, &object_instance)) { + &object_type, &object_instance)) { if ((object_type == wp_data->object_type) && (object_instance == wp_data->object_instance)) { /* writing same name to same object */ @@ -1235,9 +1217,8 @@ bool Device_Write_Property_Local(BACNET_WRITE_PROPERTY_DATA *wp_data) } break; case PROP_LOCATION: - status = - WPValidateString(&value, MAX_DEV_LOC_LEN, true, - &wp_data->error_class, &wp_data->error_code); + status = WPValidateString(&value, MAX_DEV_LOC_LEN, true, + &wp_data->error_class, &wp_data->error_code); if (status) { Device_Set_Location( characterstring_value(&value.type.Character_String), @@ -1246,9 +1227,8 @@ bool Device_Write_Property_Local(BACNET_WRITE_PROPERTY_DATA *wp_data) break; case PROP_DESCRIPTION: - status = - WPValidateString(&value, MAX_DEV_DESC_LEN, true, - &wp_data->error_class, &wp_data->error_code); + status = WPValidateString(&value, MAX_DEV_DESC_LEN, true, + &wp_data->error_class, &wp_data->error_code); if (status) { Device_Set_Description( characterstring_value(&value.type.Character_String), @@ -1256,9 +1236,8 @@ bool Device_Write_Property_Local(BACNET_WRITE_PROPERTY_DATA *wp_data) } break; case PROP_MODEL_NAME: - status = - WPValidateString(&value, MAX_DEV_MOD_LEN, true, - &wp_data->error_class, &wp_data->error_code); + status = WPValidateString(&value, MAX_DEV_MOD_LEN, true, + &wp_data->error_class, &wp_data->error_code); if (status) { Device_Set_Model_Name( characterstring_value(&value.type.Character_String), @@ -1270,7 +1249,7 @@ bool Device_Write_Property_Local(BACNET_WRITE_PROPERTY_DATA *wp_data) #if defined(BACDL_MSTP) status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_UNSIGNED_INT, - &wp_data->error_class, &wp_data->error_code); + &wp_data->error_class, &wp_data->error_code); if (status) { if (value.type.Unsigned_Int <= 255) { dlmstp_set_max_info_frames( @@ -1287,7 +1266,7 @@ bool Device_Write_Property_Local(BACNET_WRITE_PROPERTY_DATA *wp_data) #if defined(BACDL_MSTP) status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_UNSIGNED_INT, - &wp_data->error_class, &wp_data->error_code); + &wp_data->error_class, &wp_data->error_code); if (status) { if ((value.type.Unsigned_Int > 0) && (value.type.Unsigned_Int <= 127)) { @@ -1378,8 +1357,8 @@ bool Device_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) * @return True if the object instance supports this feature and value changed. */ bool Device_Encode_Value_List(BACNET_OBJECT_TYPE object_type, - uint32_t object_instance, - BACNET_PROPERTY_VALUE *value_list) + uint32_t object_instance, + BACNET_PROPERTY_VALUE *value_list) { bool status = false; /* Ever the pessamist! */ struct object_functions *pObject = NULL; @@ -1534,8 +1513,8 @@ void Device_Init(object_functions_t *object_table) } bool DeviceGetRRInfo(BACNET_READ_RANGE_DATA *pRequest, /* Info on the request */ - RR_PROP_INFO *pInfo) -{ /* Where to put the response */ + RR_PROP_INFO *pInfo) +{ /* Where to put the response */ bool status = false; /* return value */ switch (pRequest->object_property) { @@ -1612,8 +1591,9 @@ void Routing_Device_Init(uint32_t first_object_instance) #include "ctest.h" bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue, - uint8_t ucExpectedTag, BACNET_ERROR_CLASS *pErrorClass, - BACNET_ERROR_CODE *pErrorCode) + uint8_t ucExpectedTag, + BACNET_ERROR_CLASS *pErrorClass, + BACNET_ERROR_CODE *pErrorCode) { pValue = pValue; ucExpectedTag = ucExpectedTag; @@ -1623,9 +1603,11 @@ bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue, return false; } -bool WPValidateString(BACNET_APPLICATION_DATA_VALUE *pValue, int iMaxLen, - bool bEmptyAllowed, BACNET_ERROR_CLASS *pErrorClass, - BACNET_ERROR_CODE *pErrorCode) +bool WPValidateString(BACNET_APPLICATION_DATA_VALUE *pValue, + int iMaxLen, + bool bEmptyAllowed, + BACNET_ERROR_CLASS *pErrorClass, + BACNET_ERROR_CODE *pErrorCode) { pValue = pValue; iMaxLen = iMaxLen; @@ -1656,12 +1638,12 @@ void testDevice(Test *pTest) ct_test(pTest, Device_Object_Instance_Number() == BACNET_MAX_INSTANCE); ct_test(pTest, status == true); status = Device_Set_Object_Instance_Number(BACNET_MAX_INSTANCE / 2); - ct_test(pTest, - Device_Object_Instance_Number() == (BACNET_MAX_INSTANCE / 2)); + ct_test( + pTest, Device_Object_Instance_Number() == (BACNET_MAX_INSTANCE / 2)); ct_test(pTest, status == true); status = Device_Set_Object_Instance_Number(BACNET_MAX_INSTANCE + 1); - ct_test(pTest, - Device_Object_Instance_Number() != (BACNET_MAX_INSTANCE + 1)); + ct_test( + pTest, Device_Object_Instance_Number() != (BACNET_MAX_INSTANCE + 1)); ct_test(pTest, status == false); Device_Set_System_Status(STATUS_NON_OPERATIONAL, true); diff --git a/demo/piface/main.c b/apps/piface/main.c similarity index 76% rename from demo/piface/main.c rename to apps/piface/main.c index 9cc1de6a..f55ed2f2 100644 --- a/demo/piface/main.c +++ b/apps/piface/main.c @@ -29,30 +29,30 @@ #include #include -#include "config.h" -#include "address.h" -#include "bacdef.h" -#include "handlers.h" -#include "client.h" -#include "dlenv.h" -#include "bacdcode.h" -#include "npdu.h" -#include "apdu.h" -#include "iam.h" -#include "tsm.h" -#include "device.h" -#include "bacfile.h" -#include "datalink.h" -#include "dcc.h" -#include "getevent.h" -#include "net.h" -#include "txbuf.h" -#include "tsm.h" -#include "version.h" +#include "bacnet/config.h" +#include "bacnet/basic/binding/address.h" +#include "bacnet/bacdef.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/services.h" +#include "bacnet/datalink/dlenv.h" +#include "bacnet/bacdcode.h" +#include "bacnet/npdu.h" +#include "bacnet/apdu.h" +#include "bacnet/iam.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/basic/object/device.h" +#include "bacnet/basic/object/bacfile.h" +#include "bacnet/datalink/datalink.h" +#include "bacnet/dcc.h" +#include "bacnet/getevent.h" +#include "bacport.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/version.h" /* include the device object */ -#include "device.h" -#include "bi.h" -#include "bo.h" +#include "bacnet/basic/object/device.h" +#include "bacnet/basic/object/bi.h" +#include "bacnet/basic/object/bo.h" #include "pifacedigital.h" /** @file server/main.c Example server application using the BACnet Stack. */ @@ -63,7 +63,10 @@ /*@{*/ /** Buffer used for receiving */ -static uint8_t Rx_Buf[MAX_MPDU] = {0}; +static uint8_t Rx_Buf[MAX_MPDU] = { 0 }; + +/* current version of the BACnet stack */ +static const char *BACnet_Version = BACNET_VERSION_TEXT; /** Initialize the handlers we will utilize. * @see Device_Init, apdu_set_unconfirmed_handler, apdu_set_confirmed_handler @@ -81,32 +84,32 @@ static void Init_Service_Handlers(void) apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service); /* Set the handlers for any confirmed services that we support. */ /* We must implement read property - it's required! */ - apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY, - handler_read_property); - apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROP_MULTIPLE, - handler_read_property_multiple); - apdu_set_confirmed_handler(SERVICE_CONFIRMED_WRITE_PROPERTY, - handler_write_property); - apdu_set_confirmed_handler(SERVICE_CONFIRMED_WRITE_PROP_MULTIPLE, - handler_write_property_multiple); - apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_RANGE, - handler_read_range); - apdu_set_confirmed_handler(SERVICE_CONFIRMED_REINITIALIZE_DEVICE, - handler_reinitialize_device); - apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_UTC_TIME_SYNCHRONIZATION, - handler_timesync_utc); - apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_TIME_SYNCHRONIZATION, - handler_timesync); - apdu_set_confirmed_handler(SERVICE_CONFIRMED_SUBSCRIBE_COV, - handler_cov_subscribe); - apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_COV_NOTIFICATION, - handler_ucov_notification); + apdu_set_confirmed_handler( + SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property); + apdu_set_confirmed_handler( + SERVICE_CONFIRMED_READ_PROP_MULTIPLE, handler_read_property_multiple); + apdu_set_confirmed_handler( + SERVICE_CONFIRMED_WRITE_PROPERTY, handler_write_property); + apdu_set_confirmed_handler( + SERVICE_CONFIRMED_WRITE_PROP_MULTIPLE, handler_write_property_multiple); + apdu_set_confirmed_handler( + SERVICE_CONFIRMED_READ_RANGE, handler_read_range); + apdu_set_confirmed_handler( + SERVICE_CONFIRMED_REINITIALIZE_DEVICE, handler_reinitialize_device); + apdu_set_unconfirmed_handler( + SERVICE_UNCONFIRMED_UTC_TIME_SYNCHRONIZATION, handler_timesync_utc); + apdu_set_unconfirmed_handler( + SERVICE_UNCONFIRMED_TIME_SYNCHRONIZATION, handler_timesync); + apdu_set_confirmed_handler( + SERVICE_CONFIRMED_SUBSCRIBE_COV, handler_cov_subscribe); + apdu_set_unconfirmed_handler( + SERVICE_UNCONFIRMED_COV_NOTIFICATION, handler_ucov_notification); /* handle communication so we can shutup when asked */ apdu_set_confirmed_handler(SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL, - handler_device_communication_control); + handler_device_communication_control); /* handle the data coming back from private requests */ apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_PRIVATE_TRANSFER, - handler_unconfirmed_private_transfer); + handler_unconfirmed_private_transfer); } static void piface_init(void) @@ -131,9 +134,8 @@ static void piface_init(void) if (intenable == 0) { printf("Interrupts enabled.\n"); } else { - printf( - "Could not enable interrupts. " - "Try running using sudo to enable PiFaceDigital interrupts.\n"); + printf("Could not enable interrupts. " + "Try running using sudo to enable PiFaceDigital interrupts.\n"); } #endif } @@ -205,7 +207,7 @@ static void piface_task(void) */ int main(int argc, char *argv[]) { - BACNET_ADDRESS src = {0}; /* address where message came from */ + BACNET_ADDRESS src = { 0 }; /* address where message came from */ uint16_t pdu_len = 0; unsigned timeout = 1; /* milliseconds */ time_t last_seconds = 0; @@ -218,11 +220,10 @@ int main(int argc, char *argv[]) if (argc > 1) { Device_Set_Object_Instance_Number(strtol(argv[1], NULL, 0)); } - printf( - "BACnet Raspberry Pi PiFace Digital Demo\n" - "BACnet Stack Version %s\n" - "BACnet Device ID: %u\n" - "Max APDU: %d\n", + printf("BACnet Raspberry Pi PiFace Digital Demo\n" + "BACnet Stack Version %s\n" + "BACnet Device ID: %u\n" + "Max APDU: %d\n", BACnet_Version, Device_Object_Instance_Number(), MAX_APDU); /* load any static address bindings to show up in our device bindings list */ diff --git a/demo/piface/readme.txt b/apps/piface/readme.txt similarity index 100% rename from demo/piface/readme.txt rename to apps/piface/readme.txt diff --git a/demo/ptransfer/Makefile b/apps/ptransfer/Makefile similarity index 100% rename from demo/ptransfer/Makefile rename to apps/ptransfer/Makefile diff --git a/demo/handler/h_pt.c b/apps/ptransfer/h_pt.c similarity index 81% rename from demo/handler/h_pt.c rename to apps/ptransfer/h_pt.c index 6dd61786..8b65a507 100644 --- a/demo/handler/h_pt.c +++ b/apps/ptransfer/h_pt.c @@ -27,21 +27,15 @@ #include #include #include -#include "config.h" -#include "txbuf.h" -#include "bacdef.h" -#include "bacdcode.h" -#include "apdu.h" -#include "npdu.h" -#include "abort.h" -/*#include "arf.h" */ -/* demo objects */ -#if defined(BACFILE) -#include "bacfile.h" -#endif -#include "mydata.h" -#include "ptransfer.h" -#include "handlers.h" +#include "bacnet/config.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/apdu.h" +#include "bacnet/npdu.h" +#include "bacnet/abort.h" +#include "bacnet/ptransfer.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/tsm/tsm.h" /** @file h_pt.c Handles Confirmed Private Transfer requests. */ @@ -65,8 +59,8 @@ static void ProcessPT(BACNET_PRIVATE_TRANSFER_DATA *data) iLen = 0; /* Decode the block number */ - tag_len = decode_tag_number_and_value(&data->serviceParameters[iLen], - &tag_number, &len_value_type); + tag_len = decode_tag_number_and_value( + &data->serviceParameters[iLen], &tag_number, &len_value_type); iLen += tag_len; if (tag_number != BACNET_APPLICATION_TAG_UNSIGNED_INT) { /* Bail out early if wrong type */ @@ -75,8 +69,8 @@ static void ProcessPT(BACNET_PRIVATE_TRANSFER_DATA *data) return; } - iLen += decode_unsigned(&data->serviceParameters[iLen], len_value_type, - &ulTemp); + iLen += decode_unsigned( + &data->serviceParameters[iLen], len_value_type, &ulTemp); cBlockNumber = (char)ulTemp; if (cBlockNumber < MY_MAX_BLOCK) { if (data->serviceNumber == MY_SVC_READ) { @@ -124,8 +118,8 @@ static void ProcessPT(BACNET_PRIVATE_TRANSFER_DATA *data) data->serviceParametersLen = 0; return; } - iLen += decode_unsigned(&data->serviceParameters[iLen], - len_value_type, &ulTemp); + iLen += decode_unsigned( + &data->serviceParameters[iLen], len_value_type, &ulTemp); MyData[(int8_t)cBlockNumber].cMyByte1 = (char)ulTemp; tag_len = decode_tag_number_and_value( @@ -135,8 +129,8 @@ static void ProcessPT(BACNET_PRIVATE_TRANSFER_DATA *data) data->serviceParametersLen = 0; return; } - iLen += decode_unsigned(&data->serviceParameters[iLen], - len_value_type, &ulTemp); + iLen += decode_unsigned( + &data->serviceParameters[iLen], len_value_type, &ulTemp); MyData[(int8_t)cBlockNumber].cMyByte2 = (char)ulTemp; tag_len = decode_tag_number_and_value( @@ -147,7 +141,7 @@ static void ProcessPT(BACNET_PRIVATE_TRANSFER_DATA *data) return; } iLen += decode_real(&data->serviceParameters[iLen], - &MyData[(int8_t)cBlockNumber].fMyReal); + &MyData[(int8_t)cBlockNumber].fMyReal); tag_len = decode_tag_number_and_value( &data->serviceParameters[iLen], &tag_number, &len_value_type); @@ -156,11 +150,11 @@ static void ProcessPT(BACNET_PRIVATE_TRANSFER_DATA *data) data->serviceParametersLen = 0; return; } - decode_character_string(&data->serviceParameters[iLen], - len_value_type, &bsTemp); + decode_character_string( + &data->serviceParameters[iLen], len_value_type, &bsTemp); /* Only copy as much as we can accept */ strncpy((char *)MyData[(int8_t)cBlockNumber].sMyString, - characterstring_value(&bsTemp), MY_MAX_STR); + characterstring_value(&bsTemp), MY_MAX_STR); /* Make sure it is nul terminated */ MyData[(int8_t)cBlockNumber].sMyString[MY_MAX_STR] = '\0'; /* Signal success */ @@ -184,9 +178,10 @@ static void ProcessPT(BACNET_PRIVATE_TRANSFER_DATA *data) * */ -void handler_conf_private_trans(uint8_t *service_request, uint16_t service_len, - BACNET_ADDRESS *src, - BACNET_CONFIRMED_SERVICE_DATA *service_data) +void handler_conf_private_trans(uint8_t *service_request, + uint16_t service_len, + BACNET_ADDRESS *src, + BACNET_CONFIRMED_SERVICE_DATA *service_data) { BACNET_PRIVATE_TRANSFER_DATA data; int len; @@ -213,13 +208,13 @@ void handler_conf_private_trans(uint8_t *service_request, uint16_t service_len, datalink_get_my_address(&my_address); npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL); - pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address, - &npdu_data); + pdu_len = npdu_encode_pdu( + &Handler_Transmit_Buffer[0], src, &my_address, &npdu_data); if (service_data->segmented_message) { len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], - service_data->invoke_id, - ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true); + service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, + true); #if PRINT_ENABLED fprintf(stderr, "CPT: Segmented Message. Sending Abort!\n"); #endif @@ -230,8 +225,7 @@ void handler_conf_private_trans(uint8_t *service_request, uint16_t service_len, /* bad decoding - send an abort */ if (len < 0) { len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], - service_data->invoke_id, ABORT_REASON_OTHER, - true); + service_data->invoke_id, ABORT_REASON_OTHER, true); #if PRINT_ENABLED fprintf(stderr, "CPT: Bad Encoding. Sending Abort!\n"); #endif @@ -258,8 +252,8 @@ void handler_conf_private_trans(uint8_t *service_request, uint16_t service_len, fprintf(stderr, "CPT: Error servicing request!\n"); #endif } - len = ptransfer_ack_encode_apdu(&Handler_Transmit_Buffer[pdu_len], - service_data->invoke_id, &data); + len = ptransfer_ack_encode_apdu( + &Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, &data); } else { /* Not our vendor ID or bad service parameter */ error = true; @@ -272,13 +266,12 @@ void handler_conf_private_trans(uint8_t *service_request, uint16_t service_len, if (error) { len = ptransfer_error_encode_apdu(&Handler_Transmit_Buffer[pdu_len], - service_data->invoke_id, error_class, - error_code, &data); + service_data->invoke_id, error_class, error_code, &data); } CPT_ABORT: pdu_len += len; - bytes_sent = datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0], - pdu_len); + bytes_sent = datalink_send_pdu( + src, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len); #if PRINT_ENABLED if (bytes_sent <= 0) { diff --git a/apps/ptransfer/h_pt.h b/apps/ptransfer/h_pt.h new file mode 100644 index 00000000..b4896544 --- /dev/null +++ b/apps/ptransfer/h_pt.h @@ -0,0 +1,52 @@ +/** +* @file +* @author Steve Karg +* @date October 2019 +* @brief Header file for a basic ConfirmedPrivateTransfer service handler +* +* @section LICENSE +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +#ifndef HANDLER_CONFIRMED_PRIVATE_TRANSFER_H +#define HANDLER_CONFIRMED_PRIVATE_TRANSFER_H + +#include +#include +#include +#include +#include "bacnet/bacdef.h" +#include "bacnet/bacenum.h" +#include "bacnet/apdu.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + void handler_conf_private_trans( + uint8_t * service_request, + uint16_t service_len, + BACNET_ADDRESS * src, + BACNET_CONFIRMED_SERVICE_DATA * service_data); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/demo/handler/h_pt_a.c b/apps/ptransfer/h_pt_a.c similarity index 85% rename from demo/handler/h_pt_a.c rename to apps/ptransfer/h_pt_a.c index ee41993e..4e8fc38f 100644 --- a/demo/handler/h_pt_a.c +++ b/apps/ptransfer/h_pt_a.c @@ -27,21 +27,15 @@ #include #include #include -#include "config.h" -#include "txbuf.h" -#include "bacdef.h" -#include "bacdcode.h" -#include "apdu.h" -#include "npdu.h" -#include "abort.h" -/*#include "arf.h" */ -/* demo objects */ -#include "ptransfer.h" -#include "mydata.h" -#if defined(BACFILE) -#include "bacfile.h" -#endif -#include "handlers.h" +#include "bacnet/config.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/apdu.h" +#include "bacnet/npdu.h" +#include "bacnet/abort.h" +#include "bacnet/ptransfer.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/tsm/tsm.h" /** @file h_pt_a.c Handles Confirmed Private Transfer Acknowledgment. */ @@ -96,8 +90,8 @@ static void DecodeBlock(char cBlockNum, uint8_t *pData) return; iLen += decode_character_string(&pData[iLen], len_value_type, &bsName); - strncpy((char *)Response.sMyString, characterstring_value(&bsName), - MY_MAX_STR); + strncpy( + (char *)Response.sMyString, characterstring_value(&bsName), MY_MAX_STR); Response.sMyString[MY_MAX_STR] = '\0'; /* Make sure it is nul terminated */ printf("Private Transfer Read Block Response\n"); @@ -122,8 +116,8 @@ static void ProcessPTA(BACNET_PRIVATE_TRANSFER_DATA *data) /* Error code is returned for read and write operations */ - tag_len = decode_tag_number_and_value(&data->serviceParameters[iLen], - &tag_number, &len_value_type); + tag_len = decode_tag_number_and_value( + &data->serviceParameters[iLen], &tag_number, &len_value_type); iLen += tag_len; if (tag_number != BACNET_APPLICATION_TAG_UNSIGNED_INT) { #if PRINT_ENABLED @@ -131,8 +125,8 @@ static void ProcessPTA(BACNET_PRIVATE_TRANSFER_DATA *data) #endif return; } - iLen += decode_unsigned(&data->serviceParameters[iLen], len_value_type, - &uiErrorCode); + iLen += decode_unsigned( + &data->serviceParameters[iLen], len_value_type, &uiErrorCode); if (data->serviceNumber == MY_SVC_READ) { /* Read I/O block so should be full block of data or error */ @@ -151,18 +145,18 @@ static void ProcessPTA(BACNET_PRIVATE_TRANSFER_DATA *data) return; } - iLen += decode_unsigned(&data->serviceParameters[iLen], - len_value_type, &ulTemp); + iLen += decode_unsigned( + &data->serviceParameters[iLen], len_value_type, &ulTemp); cBlockNumber = (char)ulTemp; DecodeBlock(cBlockNumber, &data->serviceParameters[iLen]); } else { /* Read error */ printf("Private Transfer read operation returned error code: %lu\n", - (unsigned long)uiErrorCode); + (unsigned long)uiErrorCode); return; } } else { /* Write I/O block - should just be an OK type message */ printf("Private Transfer write operation returned error code: %lu\n", - (unsigned long)uiErrorCode); + (unsigned long)uiErrorCode); } } @@ -172,8 +166,9 @@ static void ProcessPTA(BACNET_PRIVATE_TRANSFER_DATA *data) * and decide what to do next... */ -void handler_conf_private_trans_ack( - uint8_t *service_request, uint16_t service_len, BACNET_ADDRESS *src, +void handler_conf_private_trans_ack(uint8_t *service_request, + uint16_t service_len, + BACNET_ADDRESS *src, BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data) { BACNET_PRIVATE_TRANSFER_DATA data; @@ -195,8 +190,7 @@ void handler_conf_private_trans_ack( printf("Received Confirmed Private Transfer Ack!\n"); #endif - len = ptransfer_decode_service_request( - service_request, service_len, + len = ptransfer_decode_service_request(service_request, service_len, &data); /* Same decode for ack as for service request! */ if (len < 0) { #if PRINT_ENABLED diff --git a/apps/ptransfer/h_pt_a.h b/apps/ptransfer/h_pt_a.h new file mode 100644 index 00000000..aa65f0dd --- /dev/null +++ b/apps/ptransfer/h_pt_a.h @@ -0,0 +1,52 @@ +/** +* @file +* @author Steve Karg +* @date October 2019 +* @brief Header file for a basic ConfirmedPrivateTransfer-Ack service handler +* +* @section LICENSE +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +#ifndef HANDLER_CONFIRMED_PRIVATE_TRANSFER_ACK_H +#define HANDLER_CONFIRMED_PRIVATE_TRANSFER_ACK_H + +#include +#include +#include +#include +#include "bacnet/bacdef.h" +#include "bacnet/bacenum.h" +#include "bacnet/apdu.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + void handler_conf_private_trans_ack( + uint8_t * service_request, + uint16_t service_len, + BACNET_ADDRESS * src, + BACNET_CONFIRMED_SERVICE_ACK_DATA * service_data); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/demo/ptransfer/main.c b/apps/ptransfer/main.c similarity index 75% rename from demo/ptransfer/main.c rename to apps/ptransfer/main.c index f2043c35..6ab215af 100644 --- a/demo/ptransfer/main.c +++ b/apps/ptransfer/main.c @@ -28,48 +28,54 @@ #include #include #include -#include /* for time */ +#include /* for time */ #include /* for tupper */ #if defined(WIN32) || defined(__BORLANDC__) #include #endif #define PRINT_ENABLED 1 -#include "bacdef.h" -#include "config.h" -#include "bactext.h" -#include "bacerror.h" -#include "iam.h" -#include "arf.h" -#include "tsm.h" -#include "address.h" -#include "npdu.h" -#include "apdu.h" -#include "device.h" -#include "net.h" -#include "datalink.h" -#include "whois.h" +#include "bacnet/bacdef.h" +#include "bacnet/config.h" +#include "bacnet/bactext.h" +#include "bacnet/bacerror.h" +#include "bacnet/iam.h" +#include "bacnet/arf.h" +#include "bacnet/npdu.h" +#include "bacnet/apdu.h" +#include "bacnet/whois.h" /* some demo stuff needed */ -#include "filename.h" -#include "handlers.h" -#include "client.h" -#include "txbuf.h" -#include "dlenv.h" -#include "mydata.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/basic/binding/address.h" +#include "bacnet/basic/object/device.h" +#include "bacnet/basic/sys/filename.h" +#include "bacnet/basic/services.h" +#include "bacnet/datalink/datalink.h" +#include "bacnet/datalink/dlenv.h" #if defined(__BORLANDC__) #define _kbhit kbhit #define _stricmp stricmp #endif -extern uint8_t Send_Private_Transfer_Request(uint32_t device_id, - uint16_t vendor_id, - uint32_t service_number, - char block_number, - DATABLOCK *block); +#define MY_MAX_STR 32 +#define MY_MAX_BLOCK 8 + +#define MY_SVC_READ 0 +#define MY_SVC_WRITE 1 + +#define MY_ERR_OK 0 +#define MY_ERR_BAD_INDEX 1 + +typedef struct MyData { + uint8_t cMyByte1; + uint8_t cMyByte2; + float fMyReal; + int8_t sMyString[MY_MAX_STR + 1]; /* A little extra for the nul */ +} DATABLOCK; /* buffer used for receive */ -static uint8_t Rx_Buf[MAX_MPDU] = {0}; +static uint8_t Rx_Buf[MAX_MPDU] = { 0 }; /* global variables used in this file */ static uint32_t Target_Device_Object_Instance = BACNET_MAX_INSTANCE; @@ -79,39 +85,40 @@ static int Target_Mode = 0; static BACNET_ADDRESS Target_Address; static bool Error_Detected = false; -static void MyErrorHandler(BACNET_ADDRESS *src, uint8_t invoke_id, - BACNET_ERROR_CLASS error_class, - BACNET_ERROR_CODE error_code) +static void MyErrorHandler(BACNET_ADDRESS *src, + uint8_t invoke_id, + BACNET_ERROR_CLASS error_class, + BACNET_ERROR_CODE error_code) { /* FIXME: verify src and invoke id */ (void)src; (void)invoke_id; printf("BACnet Error: %s: %s\r\n", - bactext_error_class_name((int)error_class), - bactext_error_code_name((int)error_code)); + bactext_error_class_name((int)error_class), + bactext_error_code_name((int)error_code)); /* Error_Detected = true; */ } -void MyAbortHandler(BACNET_ADDRESS *src, uint8_t invoke_id, - uint8_t abort_reason, bool server) +static void MyAbortHandler( + BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t abort_reason, bool server) { /* FIXME: verify src and invoke id */ (void)src; (void)invoke_id; (void)server; - printf("BACnet Abort: %s\r\n", - bactext_abort_reason_name((int)abort_reason)); + printf( + "BACnet Abort: %s\r\n", bactext_abort_reason_name((int)abort_reason)); Error_Detected = true; } -void MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, - uint8_t reject_reason) +static void MyRejectHandler( + BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason) { /* FIXME: verify src and invoke id */ (void)src; (void)invoke_id; printf("BACnet Reject: %s\r\n", - bactext_reject_reason_name((int)reject_reason)); + bactext_reject_reason_name((int)reject_reason)); Error_Detected = true; } @@ -127,17 +134,17 @@ static void Init_Service_Handlers(void) It is required to send the proper reject message... */ apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service); /* we must implement read property - it's required! */ - apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY, - handler_read_property); + apdu_set_confirmed_handler( + SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property); - apdu_set_confirmed_handler(SERVICE_CONFIRMED_PRIVATE_TRANSFER, - handler_conf_private_trans); + apdu_set_confirmed_handler( + SERVICE_CONFIRMED_PRIVATE_TRANSFER, handler_conf_private_trans); /* handle the data coming back from confirmed requests */ - apdu_set_confirmed_ack_handler(SERVICE_CONFIRMED_READ_PROPERTY, - handler_read_property_ack); + apdu_set_confirmed_ack_handler( + SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property_ack); - apdu_set_confirmed_ack_handler(SERVICE_CONFIRMED_PRIVATE_TRANSFER, - handler_conf_private_trans_ack); + apdu_set_confirmed_ack_handler( + SERVICE_CONFIRMED_PRIVATE_TRANSFER, handler_conf_private_trans_ack); /* handle any errors coming back */ apdu_set_error_handler(SERVICE_CONFIRMED_READ_PROPERTY, MyErrorHandler); @@ -146,9 +153,22 @@ static void Init_Service_Handlers(void) apdu_set_reject_handler(MyRejectHandler); } +len += encode_application_unsigned( + &pt_req_buffer[len], block_number); /* The block number */ +len += encode_application_unsigned( + &pt_req_buffer[len], block->cMyByte1); /* And Then the block contents */ +len += encode_application_unsigned(&pt_req_buffer[len], block->cMyByte2); +len += encode_application_real(&pt_req_buffer[len], block->fMyReal); +characterstring_init_ansi(&bsTemp, (char *)block->sMyString); +len += encode_application_character_string(&pt_req_buffer[len], &bsTemp); +} + +pt_block.serviceParameters = &pt_req_buffer[0]; +pt_block.serviceParametersLen = len; + int main(int argc, char *argv[]) { - BACNET_ADDRESS src = {0}; /* address where message came from */ + BACNET_ADDRESS src = { 0 }; /* address where message came from */ uint16_t pdu_len = 0; unsigned timeout = 100; /* milliseconds */ unsigned max_apdu = 0; @@ -166,9 +186,8 @@ int main(int argc, char *argv[]) if (((argc != 2) && (argc != 3)) || ((argc >= 2) && (strcmp(argv[1], "--help") == 0))) { printf("%s\n", argv[0]); - printf( - "Usage: %s server local-device-instance\r\n or\r\n" - " %s remote-device-instance\r\n", + printf("Usage: %s server local-device-instance\r\n or\r\n" + " %s remote-device-instance\r\n", filename_remove_path(argv[0]), filename_remove_path(argv[0])); if ((argc > 1) && (strcmp(argv[1], "--help") == 0)) { printf( @@ -194,24 +213,27 @@ int main(int argc, char *argv[]) return 0; } /* decode the command line parameters */ - if (_stricmp(argv[1], "server") == 0) + if (_stricmp(argv[1], "server") == 0) { Target_Mode = 1; - else + } else { Target_Mode = 0; + } Target_Device_Object_Instance = strtol(argv[1 + Target_Mode], NULL, 0); if (Target_Device_Object_Instance > BACNET_MAX_INSTANCE) { fprintf(stderr, "device-instance=%u - it must be less than %u\r\n", - Target_Device_Object_Instance, BACNET_MAX_INSTANCE); + Target_Device_Object_Instance, BACNET_MAX_INSTANCE); return 1; } /* setup my info */ - if (Target_Mode) + if (Target_Mode) { Device_Set_Object_Instance_Number(Target_Device_Object_Instance); - else - Device_Set_Object_Instance_Number(BACNET_MAX_INSTANCE); + } else { + Device_Set_Object_Instance_Number + } + (BACNET_MAX_INSTANCE); address_init(); Init_Service_Handlers(); @@ -255,11 +277,11 @@ int main(int argc, char *argv[]) } } else { /* try to bind with the device */ - found = address_bind_request(Target_Device_Object_Instance, &max_apdu, - &Target_Address); + found = address_bind_request( + Target_Device_Object_Instance, &max_apdu, &Target_Address); if (!found) { - Send_WhoIs(Target_Device_Object_Instance, - Target_Device_Object_Instance); + Send_WhoIs( + Target_Device_Object_Instance, Target_Device_Object_Instance); } /* loop forever */ for (;;) { @@ -274,15 +296,16 @@ int main(int argc, char *argv[]) npdu_handler(&src, &Rx_Buf[0], pdu_len); } /* at least one second has passed */ - if (current_seconds != last_seconds) + if (current_seconds != last_seconds) { tsm_timer_milliseconds( ((current_seconds - last_seconds) * 1000)); + } if (Error_Detected) break; /* wait until the device is bound, or timeout and quit */ if (!found) - found = address_bind_request(Target_Device_Object_Instance, - &max_apdu, &Target_Address); + found = address_bind_request( + Target_Device_Object_Instance, &max_apdu, &Target_Address); if (found) { if (invoke_id == 0) { /* Safe to send a new request */ switch (iType) { @@ -290,10 +313,11 @@ int main(int argc, char *argv[]) NewData.cMyByte1 = iCount; NewData.cMyByte2 = 255 - iCount; NewData.fMyReal = (float)iCount; - strcpy((char *)NewData.sMyString, - "Test Data - [x]"); + strcpy( + (char *)NewData.sMyString, "Test Data - [x]"); NewData.sMyString[13] = 'a' + iCount; - printf("Sending block %d\n", iCount); + pt_write_block_to_server() + printf("Sending block %d\n", iCount); invoke_id = Send_Private_Transfer_Request( Target_Device_Object_Instance, BACNET_VENDOR_ID, 1, iCount, &NewData); @@ -326,9 +350,8 @@ int main(int argc, char *argv[]) case 3: case 5: case 7: - printf( - "Requesting block %d with invalid " - "Vendor ID\n", + printf("Requesting block %d with invalid " + "Vendor ID\n", iCount); invoke_id = Send_Private_Transfer_Request( Target_Device_Object_Instance, @@ -348,8 +371,9 @@ int main(int argc, char *argv[]) iCount = 0; invoke_id = 0; - if (iType > 2) + if (iType > 2) { break; + } } } else if (tsm_invoke_id_failed(invoke_id)) { fprintf(stderr, "\rError: TSM Timeout!\r\n"); diff --git a/demo/ptransfer/ptransfer.sln b/apps/ptransfer/ptransfer.sln similarity index 100% rename from demo/ptransfer/ptransfer.sln rename to apps/ptransfer/ptransfer.sln diff --git a/apps/ptransfer/s_ptransfer.c b/apps/ptransfer/s_ptransfer.c new file mode 100644 index 00000000..a84715bf --- /dev/null +++ b/apps/ptransfer/s_ptransfer.c @@ -0,0 +1,123 @@ +/************************************************************************** + * + * Copyright (C) 2006 Steve Karg + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + *********************************************************************/ +#include +#include +#include +#include +#include +#include "bacnet/config.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/npdu.h" +#include "bacnet/apdu.h" +#include "bacnet/dcc.h" +#include "bacnet/ptransfer.h" +/* some demo stuff needed */ +#include "bacnet/basic/binding/address.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/basic/object/device.h" +#include "bacnet/datalink/datalink.h" +#include "bacnet/basic/services.h" + +/** @file s_ptransfer.c Send a Private Transfer request. */ + +uint8_t Send_Private_Transfer_Request(uint32_t device_id, + uint16_t vendor_id, + uint32_t service_number, + unsigned int block_number, + char *block) +{ /* NULL=optional */ + BACNET_ADDRESS dest; + BACNET_ADDRESS my_address; + unsigned max_apdu = 0; + uint8_t invoke_id = 0; + bool status = false; + int len = 0; + int pdu_len = 0; + int bytes_sent = 0; + BACNET_NPDU_DATA npdu_data; + static uint8_t + pt_req_buffer[300]; /* Somewhere to build the request packet */ + BACNET_PRIVATE_TRANSFER_DATA private_data; + + /* if we are forbidden to send, don't send! */ + if (!dcc_communication_enabled()) { + return 0; + } + + /* is the device bound? */ + status = address_get_by_device(device_id, &max_apdu, &dest); + /* is there a tsm available? */ + if (status) + invoke_id = tsm_next_free_invokeID(); + if (invoke_id) { + /* encode the NPDU portion of the packet */ + datalink_get_my_address(&my_address); + npdu_encode_npdu_data(&npdu_data, true, MESSAGE_PRIORITY_NORMAL); + pdu_len = npdu_encode_pdu( + &Handler_Transmit_Buffer[0], &dest, &my_address, &npdu_data); + /* encode the APDU portion of the packet */ + private_data.vendorID = vendor_id; + private_data.serviceNumber = service_number; + len = uptransfer_encode_apdu( + &Handler_Transmit_Buffer[pdu_len], &private_data); + pdu_len += len; + + if (service_number == MY_SVC_READ) { + } else { + len = ptransfer_encode_apdu( + &Handler_Transmit_Buffer[pdu_len], invoke_id, &pt_block); + pdu_len += len; + + /* will it fit in the sender? + note: if there is a bottleneck router in between + us and the destination, we won't know unless + we have a way to check for that and update the + max_apdu in the address binding table. */ + + if ((unsigned)pdu_len < max_apdu) { + tsm_set_confirmed_unsegmented_transaction(invoke_id, &dest, + &npdu_data, &Handler_Transmit_Buffer[0], (uint16_t)pdu_len); + bytes_sent = datalink_send_pdu( + &dest, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len); +#if PRINT_ENABLED + if (bytes_sent <= 0) + fprintf(stderr, + "Failed to Send Private Transfer Request (%s)!\n", + strerror(errno)); +#endif + } else { + tsm_free_invoke_id(invoke_id); + invoke_id = 0; +#if PRINT_ENABLED + fprintf(stderr, + "Failed to Send Private Transfer Request " + "(exceeds destination maximum APDU)!\n"); +#endif + } + } + + return invoke_id; + } diff --git a/apps/ptransfer/s_ptransfer.h b/apps/ptransfer/s_ptransfer.h new file mode 100644 index 00000000..28980704 --- /dev/null +++ b/apps/ptransfer/s_ptransfer.h @@ -0,0 +1,51 @@ +/** +* @file +* @author Steve Karg +* @date October 2019 +* @brief Header file for a basic WritePropertyMultiple service send +* +* @section LICENSE +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +#ifndef SEND_WRITE_PROPERTY_MULTIPLE_H +#define SEND_WRITE_PROPERTY_MULTIPLE_H + +#include +#include +#include +#include +#include "bacnet/bacapp.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacenum.h" +#include "bacnet/apdu.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +uint8_t Send_Private_Transfer_Request(uint32_t device_id, uint16_t vendor_id, + uint32_t service_number, + char block_number, DATABLOCK *block); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/apps/readbdt/Makefile b/apps/readbdt/Makefile new file mode 100644 index 00000000..9dc577d5 --- /dev/null +++ b/apps/readbdt/Makefile @@ -0,0 +1,47 @@ +#Makefile to build BACnet Application for the GCC Port + +TARGET = bacrbdt +# BACnet objects that are used with this app +BACNET_OBJECT_DIR = $(BACNET_SRC_DIR)/bacnet/basic/object +SRC = main.c \ + $(BACNET_OBJECT_DIR)/client/device-client.c \ + $(BACNET_OBJECT_DIR)/netport.c +BACNET_BASIC_SRC += \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_apdu.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_iam.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_noserv.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_rp.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_whois.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/s_iam.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/s_whois.c + +# TARGET_EXT is defined in apps/Makefile as .exe or nothing +TARGET_BIN = ${TARGET}$(TARGET_EXT) + +SRCS = $(SRC) $(BACNET_SRC) $(BACNET_BASIC_SRC) $(BACNET_PORT_SRC) + +OBJS += ${SRCS:.c=.o} + +.PHONY: all +all: Makefile ${TARGET_BIN} + +${TARGET_BIN}: ${OBJS} + ${CC} ${PFLAGS} ${OBJS} ${LFLAGS} -o $@ + size $@ + cp $@ ../../bin + +.c.o: + ${CC} -c ${CFLAGS} $*.c -o $@ + +.PHONY: depend +depend: + rm -f .depend + ${CC} -MM ${CFLAGS} *.c >> .depend + +.PHONY: clean +clean: + rm -f core ${TARGET_BIN} ${OBJS} $(TARGET).map + +.PHONY: include +include: .depend + diff --git a/demo/readbdt/main.c b/apps/readbdt/main.c similarity index 83% rename from demo/readbdt/main.c rename to apps/readbdt/main.c index 8196952f..1933e913 100644 --- a/demo/readbdt/main.c +++ b/apps/readbdt/main.c @@ -31,29 +31,29 @@ #include /* for time */ #include #include /* for toupper */ -#include "bactext.h" -#include "iam.h" -#include "address.h" -#include "config.h" -#include "bacdef.h" -#include "npdu.h" -#include "apdu.h" -#include "device.h" -#include "datalink.h" -#include "bvlc.h" +#include "bacnet/bactext.h" +#include "bacnet/iam.h" +#include "bacnet/basic/binding/address.h" +#include "bacnet/config.h" +#include "bacnet/bacdef.h" +#include "bacnet/npdu.h" +#include "bacnet/apdu.h" +#include "bacnet/basic/object/device.h" +#include "bacnet/datalink/datalink.h" +#include "bacnet/datalink/bvlc.h" /* some demo stuff needed */ #ifndef DEBUG_ENABLED #define DEBUG_ENABLED 0 #endif -#include "debug.h" -#include "filename.h" -#include "handlers.h" -#include "client.h" -#include "txbuf.h" -#include "dlenv.h" +#include "bacnet/basic/sys/debug.h" +#include "bacnet/basic/sys/filename.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/datalink/dlenv.h" /* buffer used for receive */ -static uint8_t Rx_Buf[MAX_MPDU] = {0}; +static uint8_t Rx_Buf[MAX_MPDU] = { 0 }; /* targets interpreted from the command line options */ static uint32_t Target_BBMD_Address; @@ -61,8 +61,8 @@ static uint16_t Target_BBMD_Port; static bool Error_Detected = false; -static void MyAbortHandler(BACNET_ADDRESS *src, uint8_t invoke_id, - uint8_t abort_reason, bool server) +static void MyAbortHandler( + BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t abort_reason, bool server) { /* FIXME: verify src and invoke id */ (void)src; @@ -72,8 +72,8 @@ static void MyAbortHandler(BACNET_ADDRESS *src, uint8_t invoke_id, Error_Detected = true; } -static void MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, - uint8_t reject_reason) +static void MyRejectHandler( + BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason) { /* FIXME: verify src and invoke id */ (void)src; @@ -92,8 +92,8 @@ static void Init_Service_Handlers(void) It is required to send the proper reject message... */ apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service); /* we must implement read property - it's required! */ - apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY, - handler_read_property); + apdu_set_confirmed_handler( + SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property); /* handle the reply (request) coming back */ apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_I_AM, handler_i_am_add); /* handle any errors coming back */ @@ -103,7 +103,7 @@ static void Init_Service_Handlers(void) int main(int argc, char *argv[]) { - BACNET_ADDRESS src = {0}; /* address where message came from */ + BACNET_ADDRESS src = { 0 }; /* address where message came from */ uint16_t pdu_len = 0; unsigned timeout = 100; /* milliseconds */ time_t total_seconds = 0; @@ -145,8 +145,8 @@ int main(int argc, char *argv[]) if ((port > 0) && (port <= 65535)) { Target_BBMD_Port = htons(port); } else { - fprintf(stderr, "port=%ld - port must be between 0-65535.\r\n", - port); + fprintf( + stderr, "port=%ld - port must be between 0-65535.\r\n", port); return 1; } } else { @@ -183,8 +183,9 @@ int main(int argc, char *argv[]) #endif } total_seconds += elapsed_seconds; - if (total_seconds > timeout_seconds) + if (total_seconds > timeout_seconds) { break; + } /* keep track of time for next check */ last_seconds = current_seconds; } diff --git a/apps/readfile/Makefile b/apps/readfile/Makefile new file mode 100644 index 00000000..668460c5 --- /dev/null +++ b/apps/readfile/Makefile @@ -0,0 +1,52 @@ +#Makefile to build BACnet Application for the Linux Port + +# tools - only if you need them. +# Most platforms have this already defined +# CC = gcc + +TARGET = bacarf +# BACnet objects that are used with this app +BACNET_OBJECT_DIR = $(BACNET_SRC_DIR)/bacnet/basic/object +SRC = main.c \ + $(BACNET_OBJECT_DIR)/client/device-client.c \ + $(BACNET_OBJECT_DIR)/netport.c +BACNET_BASIC_SRC += \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_apdu.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_iam.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_noserv.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_rp.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_whois.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/s_iam.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/s_arfs.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/s_whois.c + +# TARGET_EXT is defined in apps/Makefile as .exe or nothing +TARGET_BIN = ${TARGET}$(TARGET_EXT) + +SRCS = $(SRC) $(BACNET_SRC) $(BACNET_BASIC_SRC) $(BACNET_PORT_SRC) + +OBJS += ${SRCS:.c=.o} + +.PHONY: all +all: Makefile ${TARGET_BIN} + +${TARGET_BIN}: ${OBJS} + ${CC} ${PFLAGS} ${OBJS} ${LFLAGS} -o $@ + size $@ + cp $@ ../../bin + +.c.o: + ${CC} -c ${CFLAGS} $*.c -o $@ + +.PHONY: depend +depend: + rm -f .depend + ${CC} -MM ${CFLAGS} *.c >> .depend + +.PHONY: clean +clean: + rm -f core ${TARGET_BIN} ${OBJS} $(TARGET).map + +.PHONY: include +include: .depend + diff --git a/demo/readfile/main.c b/apps/readfile/main.c similarity index 78% rename from demo/readfile/main.c rename to apps/readfile/main.c index 17f292d2..2fb162a8 100644 --- a/demo/readfile/main.c +++ b/apps/readfile/main.c @@ -30,29 +30,29 @@ #include #include /* for time */ #include -#include "bactext.h" -#include "iam.h" -#include "arf.h" -#include "tsm.h" -#include "address.h" -#include "config.h" -#include "bacdef.h" -#include "npdu.h" -#include "apdu.h" -#include "device.h" -#include "net.h" -#include "datalink.h" -#include "whois.h" -#include "version.h" +#include "bacnet/bactext.h" +#include "bacnet/iam.h" +#include "bacnet/arf.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/basic/binding/address.h" +#include "bacnet/config.h" +#include "bacnet/bacdef.h" +#include "bacnet/npdu.h" +#include "bacnet/apdu.h" +#include "bacnet/basic/object/device.h" +#include "bacport.h" +#include "bacnet/datalink/datalink.h" +#include "bacnet/whois.h" +#include "bacnet/version.h" /* some demo stuff needed */ -#include "filename.h" -#include "handlers.h" -#include "client.h" -#include "txbuf.h" -#include "dlenv.h" +#include "bacnet/basic/sys/filename.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/datalink/dlenv.h" /* buffer used for receive */ -static uint8_t Rx_Buf[MAX_MPDU] = {0}; +static uint8_t Rx_Buf[MAX_MPDU] = { 0 }; /* global variables used in this file */ static uint32_t Target_File_Object_Instance = BACNET_MAX_INSTANCE; @@ -66,44 +66,45 @@ static bool Error_Detected = false; static uint8_t Request_Invoke_ID = 0; static void Atomic_Read_File_Error_Handler(BACNET_ADDRESS *src, - uint8_t invoke_id, - BACNET_ERROR_CLASS error_class, - BACNET_ERROR_CODE error_code) + uint8_t invoke_id, + BACNET_ERROR_CLASS error_class, + BACNET_ERROR_CODE error_code) { if (address_match(&Target_Address, src) && (invoke_id == Request_Invoke_ID)) { printf("BACnet Error: %s: %s\n", - bactext_error_class_name((int)error_class), - bactext_error_code_name((int)error_code)); + bactext_error_class_name((int)error_class), + bactext_error_code_name((int)error_code)); Error_Detected = true; } } -void MyAbortHandler(BACNET_ADDRESS *src, uint8_t invoke_id, - uint8_t abort_reason, bool server) +static void MyAbortHandler( + BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t abort_reason, bool server) { (void)server; if (address_match(&Target_Address, src) && (invoke_id == Request_Invoke_ID)) { - printf("BACnet Abort: %s\n", - bactext_abort_reason_name((int)abort_reason)); + printf( + "BACnet Abort: %s\n", bactext_abort_reason_name((int)abort_reason)); Error_Detected = true; } } -void MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, - uint8_t reject_reason) +static void MyRejectHandler( + BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason) { if (address_match(&Target_Address, src) && (invoke_id == Request_Invoke_ID)) { printf("BACnet Reject: %s\n", - bactext_reject_reason_name((int)reject_reason)); + bactext_reject_reason_name((int)reject_reason)); Error_Detected = true; } } -static void AtomicReadFileAckHandler( - uint8_t *service_request, uint16_t service_len, BACNET_ADDRESS *src, +static void AtomicReadFileAckHandler(uint8_t *service_request, + uint16_t service_len, + BACNET_ADDRESS *src, BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data) { int len = 0; @@ -130,12 +131,12 @@ static void AtomicReadFileAckHandler( in our case, an octet is one byte */ octets_written = fwrite(octetstring_value(&data.fileData[0]), 1, - octetstring_length(&data.fileData[0]), pFile); + octetstring_length(&data.fileData[0]), pFile); if (octets_written != octetstring_length(&data.fileData[0])) { fprintf(stderr, - "Unable to write data to file \"%s\".\n", - Local_File_Name); + "Unable to write data to file \"%s\".\n", + Local_File_Name); } else if (octets_written == 0) { fprintf(stderr, "Received 0 byte octet string!.\n"); } else { @@ -146,7 +147,7 @@ static void AtomicReadFileAckHandler( fflush(pFile); } else { fprintf(stderr, "Unable to seek to %d!\n", - data.type.stream.fileStartPosition); + data.type.stream.fileStartPosition); } fclose(pFile); } @@ -159,12 +160,12 @@ static void AtomicReadFileAckHandler( } } else { fprintf(stderr, "Address & Invoke ID mismatch! Invoke ID=%d\n", - Request_Invoke_ID); + Request_Invoke_ID); } } -static void LocalIAmHandler(uint8_t *service_request, uint16_t service_len, - BACNET_ADDRESS *src) +static void LocalIAmHandler( + uint8_t *service_request, uint16_t service_len, BACNET_ADDRESS *src) { int len = 0; uint32_t device_id = 0; @@ -174,12 +175,13 @@ static void LocalIAmHandler(uint8_t *service_request, uint16_t service_len, (void)src; (void)service_len; - len = iam_decode_service_request(service_request, &device_id, &max_apdu, - &segmentation, &vendor_id); + len = iam_decode_service_request( + service_request, &device_id, &max_apdu, &segmentation, &vendor_id); if (len != -1) { address_add(device_id, max_apdu, src); - } else + } else { fprintf(stderr, "!\n"); + } return; } @@ -196,14 +198,14 @@ static void Init_Service_Handlers(void) It is required to send the proper reject message... */ apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service); /* we must implement read property - it's required! */ - apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY, - handler_read_property); + apdu_set_confirmed_handler( + SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property); /* handle the data coming back from confirmed requests */ - apdu_set_confirmed_ack_handler(SERVICE_CONFIRMED_ATOMIC_READ_FILE, - AtomicReadFileAckHandler); + apdu_set_confirmed_ack_handler( + SERVICE_CONFIRMED_ATOMIC_READ_FILE, AtomicReadFileAckHandler); /* handle any errors coming back */ - apdu_set_error_handler(SERVICE_CONFIRMED_ATOMIC_READ_FILE, - Atomic_Read_File_Error_Handler); + apdu_set_error_handler( + SERVICE_CONFIRMED_ATOMIC_READ_FILE, Atomic_Read_File_Error_Handler); apdu_set_abort_handler(MyAbortHandler); apdu_set_reject_handler(MyRejectHandler); } @@ -241,7 +243,7 @@ static void print_help(char *filename) int main(int argc, char *argv[]) { - BACNET_ADDRESS src = {0}; /* address where message came from */ + BACNET_ADDRESS src = { 0 }; /* address where message came from */ uint16_t pdu_len = 0; unsigned timeout = 100; /* milliseconds */ unsigned max_apdu = 0; @@ -265,12 +267,11 @@ int main(int argc, char *argv[]) } if (strcmp(argv[argi], "--version") == 0) { printf("%s %s\n", filename, BACNET_VERSION_TEXT); - printf( - "Copyright (C) 2014 by Steve Karg and others.\n" - "This is free software; see the source for copying " - "conditions.\n" - "There is NO warranty; not even for MERCHANTABILITY or\n" - "FITNESS FOR A PARTICULAR PURPOSE.\n"); + printf("Copyright (C) 2014 by Steve Karg and others.\n" + "This is free software; see the source for copying " + "conditions.\n" + "There is NO warranty; not even for MERCHANTABILITY or\n" + "FITNESS FOR A PARTICULAR PURPOSE.\n"); return 0; } } @@ -284,12 +285,12 @@ int main(int argc, char *argv[]) Local_File_Name = argv[3]; if (Target_Device_Object_Instance >= BACNET_MAX_INSTANCE) { fprintf(stderr, "device-instance=%u - it must be less than %u\n", - Target_Device_Object_Instance, BACNET_MAX_INSTANCE); + Target_Device_Object_Instance, BACNET_MAX_INSTANCE); return 1; } if (Target_File_Object_Instance >= BACNET_MAX_INSTANCE) { fprintf(stderr, "file-instance=%u - it must be less than %u\n", - Target_File_Object_Instance, BACNET_MAX_INSTANCE + 1); + Target_File_Object_Instance, BACNET_MAX_INSTANCE + 1); return 1; } /* setup my info */ @@ -302,11 +303,11 @@ int main(int argc, char *argv[]) last_seconds = time(NULL); timeout_seconds = (apdu_timeout() / 1000) * apdu_retries(); /* try to bind with the device */ - found = address_bind_request(Target_Device_Object_Instance, &max_apdu, - &Target_Address); + found = address_bind_request( + Target_Device_Object_Instance, &max_apdu, &Target_Address); if (!found) { - Send_WhoIs(Target_Device_Object_Instance, - Target_Device_Object_Instance); + Send_WhoIs( + Target_Device_Object_Instance, Target_Device_Object_Instance); } /* loop forever */ for (;;) { @@ -326,8 +327,8 @@ int main(int argc, char *argv[]) } /* wait until the device is bound, or timeout and quit */ if (!found) { - found = address_bind_request(Target_Device_Object_Instance, - &max_apdu, &Target_Address); + found = address_bind_request( + Target_Device_Object_Instance, &max_apdu, &Target_Address); } if (found) { /* calculate the smaller of our APDU size or theirs @@ -358,10 +359,10 @@ int main(int argc, char *argv[]) /* the ACK will increment the start position if OK */ /* we'll read the file in chunks less than max_apdu to keep unsegmented */ - invoke_id = Send_Atomic_Read_File_Stream( - Target_Device_Object_Instance, Target_File_Object_Instance, - Target_File_Start_Position, - Target_File_Requested_Octet_Count); + invoke_id = + Send_Atomic_Read_File_Stream(Target_Device_Object_Instance, + Target_File_Object_Instance, Target_File_Start_Position, + Target_File_Requested_Octet_Count); Request_Invoke_ID = invoke_id; } else if (tsm_invoke_id_failed(invoke_id)) { fprintf(stderr, "\rError: TSM Timeout!\n"); diff --git a/demo/readfile/main.ide b/apps/readfile/main.ide similarity index 100% rename from demo/readfile/main.ide rename to apps/readfile/main.ide diff --git a/apps/readprop/Makefile b/apps/readprop/Makefile new file mode 100644 index 00000000..fa9dee7d --- /dev/null +++ b/apps/readprop/Makefile @@ -0,0 +1,50 @@ +#Makefile to build BACnet Application using GCC compiler + +# Executable file name +TARGET = bacrp +# BACnet objects that are used with this app +BACNET_OBJECT_DIR = $(BACNET_SRC_DIR)/bacnet/basic/object +SRC = main.c \ + $(BACNET_OBJECT_DIR)/client/device-client.c \ + $(BACNET_OBJECT_DIR)/netport.c +BACNET_BASIC_SRC += \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_apdu.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_iam.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_noserv.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_rp.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_rp_a.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_whois.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/s_iam.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/s_rp.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/s_whois.c + +# TARGET_EXT is defined in apps/Makefile as .exe or nothing +TARGET_BIN = ${TARGET}$(TARGET_EXT) + +SRCS = $(SRC) $(BACNET_SRC) $(BACNET_BASIC_SRC) $(BACNET_PORT_SRC) + +OBJS += ${SRCS:.c=.o} + +.PHONY: all +all: Makefile ${TARGET_BIN} + +${TARGET_BIN}: ${OBJS} + ${CC} ${PFLAGS} ${OBJS} ${LFLAGS} -o $@ + size $@ + cp $@ ../../bin + +.c.o: + ${CC} -c ${CFLAGS} $*.c -o $@ + +.PHONY: depend +depend: + rm -f .depend + ${CC} -MM ${CFLAGS} *.c >> .depend + +.PHONY: clean +clean: + rm -f core ${TARGET_BIN} ${OBJS} $(TARGET).map + +.PHONY: include +include: .depend + diff --git a/demo/readprop/bacrp.cbp b/apps/readprop/bacrp.cbp similarity index 100% rename from demo/readprop/bacrp.cbp rename to apps/readprop/bacrp.cbp diff --git a/demo/readprop/main.c b/apps/readprop/main.c similarity index 63% rename from demo/readprop/main.c rename to apps/readprop/main.c index dc2cba6a..192a459a 100644 --- a/demo/readprop/main.c +++ b/apps/readprop/main.c @@ -32,30 +32,30 @@ #define PRINT_ENABLED 1 -#include "bacdef.h" -#include "config.h" -#include "bactext.h" -#include "bacerror.h" -#include "iam.h" -#include "arf.h" -#include "tsm.h" -#include "address.h" -#include "npdu.h" -#include "apdu.h" -#include "device.h" -#include "net.h" -#include "datalink.h" -#include "whois.h" -#include "version.h" +#include "bacnet/bacdef.h" +#include "bacnet/config.h" +#include "bacnet/bactext.h" +#include "bacnet/bacerror.h" +#include "bacnet/iam.h" +#include "bacnet/arf.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/basic/binding/address.h" +#include "bacnet/npdu.h" +#include "bacnet/apdu.h" +#include "bacnet/basic/object/device.h" +#include "bacport.h" +#include "bacnet/datalink/datalink.h" +#include "bacnet/whois.h" +#include "bacnet/version.h" /* some demo stuff needed */ -#include "filename.h" -#include "handlers.h" -#include "client.h" -#include "txbuf.h" -#include "dlenv.h" +#include "bacnet/basic/sys/filename.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/datalink/dlenv.h" /* buffer used for receive */ -static uint8_t Rx_Buf[MAX_MPDU] = {0}; +static uint8_t Rx_Buf[MAX_MPDU] = { 0 }; /* converted command line arguments */ static uint32_t Target_Device_Object_Instance = BACNET_MAX_INSTANCE; @@ -68,38 +68,39 @@ static uint8_t Request_Invoke_ID = 0; static BACNET_ADDRESS Target_Address; static bool Error_Detected = false; -static void MyErrorHandler(BACNET_ADDRESS *src, uint8_t invoke_id, - BACNET_ERROR_CLASS error_class, - BACNET_ERROR_CODE error_code) +static void MyErrorHandler(BACNET_ADDRESS *src, + uint8_t invoke_id, + BACNET_ERROR_CLASS error_class, + BACNET_ERROR_CODE error_code) { if (address_match(&Target_Address, src) && (invoke_id == Request_Invoke_ID)) { printf("BACnet Error: %s: %s\n", - bactext_error_class_name((int)error_class), - bactext_error_code_name((int)error_code)); + bactext_error_class_name((int)error_class), + bactext_error_code_name((int)error_code)); Error_Detected = true; } } -void MyAbortHandler(BACNET_ADDRESS *src, uint8_t invoke_id, - uint8_t abort_reason, bool server) +static void MyAbortHandler( + BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t abort_reason, bool server) { (void)server; if (address_match(&Target_Address, src) && (invoke_id == Request_Invoke_ID)) { - printf("BACnet Abort: %s\n", - bactext_abort_reason_name((int)abort_reason)); + printf( + "BACnet Abort: %s\n", bactext_abort_reason_name((int)abort_reason)); Error_Detected = true; } } -void MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, - uint8_t reject_reason) +static void MyRejectHandler( + BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason) { if (address_match(&Target_Address, src) && (invoke_id == Request_Invoke_ID)) { printf("BACnet Reject: %s\n", - bactext_reject_reason_name((int)reject_reason)); + bactext_reject_reason_name((int)reject_reason)); Error_Detected = true; } } @@ -115,8 +116,9 @@ void MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, * @param service_data [in] The BACNET_CONFIRMED_SERVICE_DATA information * decoded from the APDU header of this message. */ -void My_Read_Property_Ack_Handler( - uint8_t *service_request, uint16_t service_len, BACNET_ADDRESS *src, +static void My_Read_Property_Ack_Handler(uint8_t *service_request, + uint16_t service_len, + BACNET_ADDRESS *src, BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data) { int len = 0; @@ -146,11 +148,11 @@ static void Init_Service_Handlers(void) It is required to send the proper reject message... */ apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service); /* we must implement read property - it's required! */ - apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY, - handler_read_property); + apdu_set_confirmed_handler( + SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property); /* handle the data coming back from confirmed requests */ - apdu_set_confirmed_ack_handler(SERVICE_CONFIRMED_READ_PROPERTY, - My_Read_Property_Ack_Handler); + apdu_set_confirmed_ack_handler( + SERVICE_CONFIRMED_READ_PROPERTY, My_Read_Property_Ack_Handler); /* handle any errors coming back */ apdu_set_error_handler(SERVICE_CONFIRMED_READ_PROPERTY, MyErrorHandler); apdu_set_abort_handler(MyAbortHandler); @@ -159,9 +161,8 @@ static void Init_Service_Handlers(void) static void print_usage(char *filename) { - printf( - "Usage: %s device-instance object-type object-instance " - "property [index]\n", + printf("Usage: %s device-instance object-type object-instance " + "property [index]\n", filename); printf(" [--dnet][--dadr][--mac]\n"); printf(" [--version][--help]\n"); @@ -169,67 +170,64 @@ static void print_usage(char *filename) static void print_help(char *filename) { - printf( - "Read a property from an object in a BACnet device\n" - "and print the value.\n"); - printf( - "--mac A\n" - "Optional BACnet mac address." - "Valid ranges are from 00 to FF (hex) for MS/TP or ARCNET,\n" - "or an IP string with optional port number like 10.1.2.3:47808\n" - "or an Ethernet MAC in hex like 00:21:70:7e:32:bb\n" - "\n" - "--dnet N\n" - "Optional BACnet network number N for directed requests.\n" - "Valid range is from 0 to 65535 where 0 is the local connection\n" - "and 65535 is network broadcast.\n" - "\n" - "--dadr A\n" - "Optional BACnet mac address on the destination BACnet network " - "number.\n" - "Valid ranges are from 00 to FF (hex) for MS/TP or ARCNET,\n" - "or an IP string with optional port number like 10.1.2.3:47808\n" - "or an Ethernet MAC in hex like 00:21:70:7e:32:bb\n" - "\n"); - printf( - "device-instance:\n" - "BACnet Device Object Instance number that you are\n" - "trying to communicate to. This number will be used\n" - "to try and bind with the device using Who-Is and\n" - "I-Am services. For example, if you were reading\n" - "Device Object 123, the device-instance would be 123.\n" - "\nobject-type:\n" - "The object type is the integer value of the enumeration\n" - "BACNET_OBJECT_TYPE in bacenum.h. It is the object\n" - "that you are reading. For example if you were\n" - "reading Analog Output 2, the object-type would be 1.\n" - "\nobject-instance:\n" - "This is the object instance number of the object that\n" - "you are reading. For example, if you were reading\n" - "Analog Output 2, the object-instance would be 2.\n" - "\nproperty:\n" - "The property is an integer value of the enumeration\n" - "BACNET_PROPERTY_ID in bacenum.h. It is the property\n" - "you are reading. For example, if you were reading the\n" - "Present Value property, use 85 as the property.\n" - "\nindex:\n" - "This integer parameter is the index number of an array.\n" - "If the property is an array, individual elements can\n" - "be read. If this parameter is missing and the property\n" - "is an array, the entire array will be read.\n" - "\nExample:\n" - "If you want read the Present-Value of Analog Output 101\n" - "in Device 123, you could send the following command:\n" - "%s 123 1 101 85\n" - "If you want read the Priority-Array of Analog Output 101\n" - "in Device 123, you could send the following command:\n" - "%s 123 1 101 87\n", + printf("Read a property from an object in a BACnet device\n" + "and print the value.\n"); + printf("--mac A\n" + "Optional BACnet mac address." + "Valid ranges are from 00 to FF (hex) for MS/TP or ARCNET,\n" + "or an IP string with optional port number like 10.1.2.3:47808\n" + "or an Ethernet MAC in hex like 00:21:70:7e:32:bb\n" + "\n" + "--dnet N\n" + "Optional BACnet network number N for directed requests.\n" + "Valid range is from 0 to 65535 where 0 is the local connection\n" + "and 65535 is network broadcast.\n" + "\n" + "--dadr A\n" + "Optional BACnet mac address on the destination BACnet network " + "number.\n" + "Valid ranges are from 00 to FF (hex) for MS/TP or ARCNET,\n" + "or an IP string with optional port number like 10.1.2.3:47808\n" + "or an Ethernet MAC in hex like 00:21:70:7e:32:bb\n" + "\n"); + printf("device-instance:\n" + "BACnet Device Object Instance number that you are\n" + "trying to communicate to. This number will be used\n" + "to try and bind with the device using Who-Is and\n" + "I-Am services. For example, if you were reading\n" + "Device Object 123, the device-instance would be 123.\n" + "\nobject-type:\n" + "The object type is the integer value of the enumeration\n" + "BACNET_OBJECT_TYPE in bacenum.h. It is the object\n" + "that you are reading. For example if you were\n" + "reading Analog Output 2, the object-type would be 1.\n" + "\nobject-instance:\n" + "This is the object instance number of the object that\n" + "you are reading. For example, if you were reading\n" + "Analog Output 2, the object-instance would be 2.\n" + "\nproperty:\n" + "The property is an integer value of the enumeration\n" + "BACNET_PROPERTY_ID in bacenum.h. It is the property\n" + "you are reading. For example, if you were reading the\n" + "Present Value property, use 85 as the property.\n" + "\nindex:\n" + "This integer parameter is the index number of an array.\n" + "If the property is an array, individual elements can\n" + "be read. If this parameter is missing and the property\n" + "is an array, the entire array will be read.\n" + "\nExample:\n" + "If you want read the Present-Value of Analog Output 101\n" + "in Device 123, you could send the following command:\n" + "%s 123 1 101 85\n" + "If you want read the Priority-Array of Analog Output 101\n" + "in Device 123, you could send the following command:\n" + "%s 123 1 101 87\n", filename, filename); } int main(int argc, char *argv[]) { - BACNET_ADDRESS src = {0}; /* address where message came from */ + BACNET_ADDRESS src = { 0 }; /* address where message came from */ uint16_t pdu_len = 0; unsigned timeout = 100; /* milliseconds */ unsigned max_apdu = 0; @@ -239,9 +237,9 @@ int main(int argc, char *argv[]) time_t timeout_seconds = 0; bool found = false; long dnet = -1; - BACNET_MAC_ADDRESS mac = {0}; - BACNET_MAC_ADDRESS adr = {0}; - BACNET_ADDRESS dest = {0}; + BACNET_MAC_ADDRESS mac = { 0 }; + BACNET_MAC_ADDRESS adr = { 0 }; + BACNET_ADDRESS dest = { 0 }; bool specific_address = false; int argi = 0; unsigned int target_args = 0; @@ -256,12 +254,11 @@ int main(int argc, char *argv[]) } if (strcmp(argv[argi], "--version") == 0) { printf("%s %s\n", filename, BACNET_VERSION_TEXT); - printf( - "Copyright (C) 2015 by Steve Karg and others.\n" - "This is free software; see the source for copying " - "conditions.\n" - "There is NO warranty; not even for MERCHANTABILITY or\n" - "FITNESS FOR A PARTICULAR PURPOSE.\n"); + printf("Copyright (C) 2015 by Steve Karg and others.\n" + "This is free software; see the source for copying " + "conditions.\n" + "There is NO warranty; not even for MERCHANTABILITY or\n" + "FITNESS FOR A PARTICULAR PURPOSE.\n"); return 0; } if (strcmp(argv[argi], "--mac") == 0) { @@ -311,7 +308,7 @@ int main(int argc, char *argv[]) } if (Target_Device_Object_Instance > BACNET_MAX_INSTANCE) { fprintf(stderr, "device-instance=%u - it must be less than %u\n", - Target_Device_Object_Instance, BACNET_MAX_INSTANCE); + Target_Device_Object_Instance, BACNET_MAX_INSTANCE); return 1; } address_init(); @@ -355,11 +352,11 @@ int main(int argc, char *argv[]) last_seconds = time(NULL); timeout_seconds = (apdu_timeout() / 1000) * apdu_retries(); /* try to bind with the device */ - found = address_bind_request(Target_Device_Object_Instance, &max_apdu, - &Target_Address); + found = address_bind_request( + Target_Device_Object_Instance, &max_apdu, &Target_Address); if (!found) { - Send_WhoIs(Target_Device_Object_Instance, - Target_Device_Object_Instance); + Send_WhoIs( + Target_Device_Object_Instance, Target_Device_Object_Instance); } /* loop forever */ for (;;) { @@ -367,25 +364,26 @@ int main(int argc, char *argv[]) current_seconds = time(NULL); /* at least one second has passed */ - if (current_seconds != last_seconds) + if (current_seconds != last_seconds) { tsm_timer_milliseconds( (uint16_t)((current_seconds - last_seconds) * 1000)); + } if (Error_Detected) break; /* wait until the device is bound, or timeout and quit */ if (!found) { - found = address_bind_request(Target_Device_Object_Instance, - &max_apdu, &Target_Address); + found = address_bind_request( + Target_Device_Object_Instance, &max_apdu, &Target_Address); } if (found) { if (Request_Invoke_ID == 0) { - Request_Invoke_ID = Send_Read_Property_Request( - Target_Device_Object_Instance, Target_Object_Type, - Target_Object_Instance, Target_Object_Property, - Target_Object_Index); - } else if (tsm_invoke_id_free(Request_Invoke_ID)) + Request_Invoke_ID = + Send_Read_Property_Request(Target_Device_Object_Instance, + Target_Object_Type, Target_Object_Instance, + Target_Object_Property, Target_Object_Index); + } else if (tsm_invoke_id_free(Request_Invoke_ID)) { break; - else if (tsm_invoke_id_failed(Request_Invoke_ID)) { + } else if (tsm_invoke_id_failed(Request_Invoke_ID)) { fprintf(stderr, "\rError: TSM Timeout!\n"); tsm_free_invoke_id(Request_Invoke_ID); Error_Detected = true; diff --git a/apps/readpropm/Makefile b/apps/readpropm/Makefile new file mode 100644 index 00000000..60821b08 --- /dev/null +++ b/apps/readpropm/Makefile @@ -0,0 +1,56 @@ +#Makefile to build BACnet Application for the Linux Port + +# tools - only if you need them. +# Most platforms have this already defined +# CC = gcc + +# Executable file name +TARGET = bacrpm +# BACnet objects that are used with this app +BACNET_OBJECT_DIR = $(BACNET_SRC_DIR)/bacnet/basic/object +SRC = main.c \ + $(BACNET_OBJECT_DIR)/client/device-client.c \ + $(BACNET_OBJECT_DIR)/netport.c +BACNET_BASIC_SRC += \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_apdu.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_iam.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_noserv.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_rp.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_rp_a.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_rpm_a.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_whois.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/s_iam.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/s_rp.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/s_rpm.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/s_whois.c + +# TARGET_EXT is defined in apps/Makefile as .exe or nothing +TARGET_BIN = ${TARGET}$(TARGET_EXT) + +SRCS = $(SRC) $(BACNET_SRC) $(BACNET_BASIC_SRC) $(BACNET_PORT_SRC) + +OBJS += ${SRCS:.c=.o} + +.PHONY: all +all: Makefile ${TARGET_BIN} + +${TARGET_BIN}: ${OBJS} + ${CC} ${PFLAGS} ${OBJS} ${LFLAGS} -o $@ + size $@ + cp $@ ../../bin + +.c.o: + ${CC} -c ${CFLAGS} $*.c -o $@ + +.PHONY: depend +depend: + rm -f .depend + ${CC} -MM ${CFLAGS} *.c >> .depend + +.PHONY: clean +clean: + rm -f core ${TARGET_BIN} ${OBJS} $(TARGET).map + +.PHONY: include +include: .depend + diff --git a/demo/readpropm/bacrpm.cbp b/apps/readpropm/bacrpm.cbp similarity index 100% rename from demo/readpropm/bacrpm.cbp rename to apps/readpropm/bacrpm.cbp diff --git a/demo/readpropm/main.c b/apps/readpropm/main.c similarity index 69% rename from demo/readpropm/main.c rename to apps/readpropm/main.c index fd52e28f..bf557d52 100644 --- a/demo/readpropm/main.c +++ b/apps/readpropm/main.c @@ -32,31 +32,31 @@ #define PRINT_ENABLED 1 -#include "bacdef.h" -#include "config.h" -#include "bactext.h" -#include "bacerror.h" -#include "iam.h" -#include "arf.h" -#include "tsm.h" -#include "address.h" -#include "npdu.h" -#include "apdu.h" -#include "device.h" -#include "net.h" -#include "datalink.h" -#include "whois.h" -#include "version.h" +#include "bacnet/bacdef.h" +#include "bacnet/config.h" +#include "bacnet/bactext.h" +#include "bacnet/bacerror.h" +#include "bacnet/iam.h" +#include "bacnet/arf.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/basic/binding/address.h" +#include "bacnet/npdu.h" +#include "bacnet/apdu.h" +#include "bacnet/basic/object/device.h" +#include "bacport.h" +#include "bacnet/datalink/datalink.h" +#include "bacnet/whois.h" +#include "bacnet/version.h" /* some demo stuff needed */ -#include "rpm.h" -#include "filename.h" -#include "handlers.h" -#include "client.h" -#include "txbuf.h" -#include "dlenv.h" +#include "bacnet/rpm.h" +#include "bacnet/basic/sys/filename.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/datalink/dlenv.h" /* buffer used for receive */ -static uint8_t Rx_Buf[MAX_MPDU] = {0}; +static uint8_t Rx_Buf[MAX_MPDU] = { 0 }; /* global variables used in this file */ static uint32_t Target_Device_Object_Instance = BACNET_MAX_INSTANCE; @@ -67,39 +67,40 @@ static BACNET_ADDRESS Target_Address; /* needed for return value of main application */ static bool Error_Detected = false; -static void MyErrorHandler(BACNET_ADDRESS *src, uint8_t invoke_id, - BACNET_ERROR_CLASS error_class, - BACNET_ERROR_CODE error_code) +static void MyErrorHandler(BACNET_ADDRESS *src, + uint8_t invoke_id, + BACNET_ERROR_CLASS error_class, + BACNET_ERROR_CODE error_code) { if (address_match(&Target_Address, src) && (invoke_id == Request_Invoke_ID)) { printf("BACnet Error: %s: %s\n", - bactext_error_class_name((int)error_class), - bactext_error_code_name((int)error_code)); + bactext_error_class_name((int)error_class), + bactext_error_code_name((int)error_code)); Error_Detected = true; } } -void MyAbortHandler(BACNET_ADDRESS *src, uint8_t invoke_id, - uint8_t abort_reason, bool server) +static void MyAbortHandler( + BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t abort_reason, bool server) { (void)server; if (address_match(&Target_Address, src) && (invoke_id == Request_Invoke_ID)) { - printf("BACnet Abort: %s\n", - bactext_abort_reason_name((int)abort_reason)); + printf( + "BACnet Abort: %s\n", bactext_abort_reason_name((int)abort_reason)); Error_Detected = true; } } -void MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, - uint8_t reject_reason) +static void MyRejectHandler( + BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason) { /* FIXME: verify src and invoke id */ if (address_match(&Target_Address, src) && (invoke_id == Request_Invoke_ID)) { printf("BACnet Reject: %s\n", - bactext_reject_reason_name((int)reject_reason)); + bactext_reject_reason_name((int)reject_reason)); Error_Detected = true; } } @@ -115,8 +116,9 @@ void MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, * @param service_data [in] The BACNET_CONFIRMED_SERVICE_DATA information * decoded from the APDU header of this message. */ -void My_Read_Property_Multiple_Ack_Handler( - uint8_t *service_request, uint16_t service_len, BACNET_ADDRESS *src, +static void My_Read_Property_Multiple_Ack_Handler(uint8_t *service_request, + uint16_t service_len, + BACNET_ADDRESS *src, BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data) { int len = 0; @@ -131,8 +133,8 @@ void My_Read_Property_Multiple_Ack_Handler( (service_data->invoke_id == Request_Invoke_ID)) { rpm_data = calloc(1, sizeof(BACNET_READ_ACCESS_DATA)); if (rpm_data) { - len = rpm_ack_decode_service_request(service_request, service_len, - rpm_data); + len = rpm_ack_decode_service_request( + service_request, service_len, rpm_data); } if (len > 0) { while (rpm_data) { @@ -188,18 +190,18 @@ static void Init_Service_Handlers(void) It is required to send the proper reject message... */ apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service); /* we must implement read property - it's required! */ - apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY, - handler_read_property); + apdu_set_confirmed_handler( + SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property); /* handle the data coming back from confirmed requests */ apdu_set_confirmed_ack_handler(SERVICE_CONFIRMED_READ_PROP_MULTIPLE, - My_Read_Property_Multiple_Ack_Handler); + My_Read_Property_Multiple_Ack_Handler); /* handle any errors coming back */ apdu_set_error_handler(SERVICE_CONFIRMED_READ_PROPERTY, MyErrorHandler); apdu_set_abort_handler(MyAbortHandler); apdu_set_reject_handler(MyRejectHandler); } -void cleanup(void) +static void cleanup(void) { BACNET_READ_ACCESS_DATA *rpm_object; BACNET_READ_ACCESS_DATA *old_rpm_object; @@ -223,67 +225,65 @@ void cleanup(void) static void print_usage(char *filename) { - printf( - "Usage: %s device-instance object-type object-instance " - "property[index][,property[index]] [object-type ...]\n", + printf("Usage: %s device-instance object-type object-instance " + "property[index][,property[index]] [object-type ...]\n", filename); printf(" [--version][--help]\n"); } static void print_help(char *filename) { - printf( - "Read one or more properties from one or more objects\n" - "in a BACnet device and print the value(s).\n" - "device-instance:\n" - "BACnet Device Object Instance number that you are\n" - "trying to communicate to. This number will be used\n" - "to try and bind with the device using Who-Is and\n" - "I-Am services. For example, if you were reading\n" - "Device Object 123, the device-instance would be 123.\n" - "\nobject-type:\n" - "The object type is the integer value of the enumeration\n" - "BACNET_OBJECT_TYPE in bacenum.h. It is the object\n" - "that you are reading. For example if you were\n" - "reading Analog Output 2, the object-type would be 1.\n" - "\nobject-instance:\n" - "This is the object instance number of the object that\n" - "you are reading. For example, if you were reading\n" - "Analog Output 2, the object-instance would be 2.\n" - "\nproperty:\n" - "The property is an integer value of the enumeration\n" - "BACNET_PROPERTY_ID in bacenum.h. It is the property\n" - "you are reading. For example, if you were reading the\n" - "Present Value property, use 85 as the property.\n" - "\n[index]:\n" - "This optional integer parameter is the index number of \n" - "an array property. Individual elements of an array can\n" - "be read. If this parameter is missing and the property\n" - "is an array, the entire array will be read.\n" - "\nExample:\n" - "If you want read the PRESENT_VALUE property and various\n" - "array elements of the PRIORITY_ARRAY in Device 123\n" - "Analog Output object 99, use the following command:\n" - "%s 123 1 99 85,87[0],87\n" - "If you want read the PRESENT_VALUE property in objects\n" - "Analog Input 77 and Analog Input 78 in Device 123\n" - "use the following command:\n" - "%s 123 0 77 85 0 78 85\n" - "If you want read the ALL property in\n" - "Device object 123, you would use the following command:\n" - "%s 123 8 123 8\n" - "If you want read the OPTIONAL property in\n" - "Device object 123, you would use the following command:\n" - "%s 123 8 123 80\n" - "If you want read the REQUIRED property in\n" - "Device object 123, you would use the following command:\n" - "%s 123 8 123 105\n", + printf("Read one or more properties from one or more objects\n" + "in a BACnet device and print the value(s).\n" + "device-instance:\n" + "BACnet Device Object Instance number that you are\n" + "trying to communicate to. This number will be used\n" + "to try and bind with the device using Who-Is and\n" + "I-Am services. For example, if you were reading\n" + "Device Object 123, the device-instance would be 123.\n" + "\nobject-type:\n" + "The object type is the integer value of the enumeration\n" + "BACNET_OBJECT_TYPE in bacenum.h. It is the object\n" + "that you are reading. For example if you were\n" + "reading Analog Output 2, the object-type would be 1.\n" + "\nobject-instance:\n" + "This is the object instance number of the object that\n" + "you are reading. For example, if you were reading\n" + "Analog Output 2, the object-instance would be 2.\n" + "\nproperty:\n" + "The property is an integer value of the enumeration\n" + "BACNET_PROPERTY_ID in bacenum.h. It is the property\n" + "you are reading. For example, if you were reading the\n" + "Present Value property, use 85 as the property.\n" + "\n[index]:\n" + "This optional integer parameter is the index number of \n" + "an array property. Individual elements of an array can\n" + "be read. If this parameter is missing and the property\n" + "is an array, the entire array will be read.\n" + "\nExample:\n" + "If you want read the PRESENT_VALUE property and various\n" + "array elements of the PRIORITY_ARRAY in Device 123\n" + "Analog Output object 99, use the following command:\n" + "%s 123 1 99 85,87[0],87\n" + "If you want read the PRESENT_VALUE property in objects\n" + "Analog Input 77 and Analog Input 78 in Device 123\n" + "use the following command:\n" + "%s 123 0 77 85 0 78 85\n" + "If you want read the ALL property in\n" + "Device object 123, you would use the following command:\n" + "%s 123 8 123 8\n" + "If you want read the OPTIONAL property in\n" + "Device object 123, you would use the following command:\n" + "%s 123 8 123 80\n" + "If you want read the REQUIRED property in\n" + "Device object 123, you would use the following command:\n" + "%s 123 8 123 105\n", filename, filename, filename, filename, filename); } int main(int argc, char *argv[]) { - BACNET_ADDRESS src = {0}; /* address where message came from */ + BACNET_ADDRESS src = { 0 }; /* address where message came from */ uint16_t pdu_len = 0; unsigned timeout = 100; /* milliseconds */ unsigned max_apdu = 0; @@ -293,7 +293,7 @@ int main(int argc, char *argv[]) time_t current_seconds = 0; time_t timeout_seconds = 0; bool found = false; - uint8_t buffer[MAX_PDU] = {0}; + uint8_t buffer[MAX_PDU] = { 0 }; BACNET_READ_ACCESS_DATA *rpm_object; BACNET_PROPERTY_REFERENCE *rpm_property; char *property_token = NULL; @@ -312,12 +312,11 @@ int main(int argc, char *argv[]) } if (strcmp(argv[argi], "--version") == 0) { printf("%s %s\n", filename, BACNET_VERSION_TEXT); - printf( - "Copyright (C) 2014 by Steve Karg and others.\n" - "This is free software; see the source for copying " - "conditions.\n" - "There is NO warranty; not even for MERCHANTABILITY or\n" - "FITNESS FOR A PARTICULAR PURPOSE.\n"); + printf("Copyright (C) 2014 by Steve Karg and others.\n" + "This is free software; see the source for copying " + "conditions.\n" + "There is NO warranty; not even for MERCHANTABILITY or\n" + "FITNESS FOR A PARTICULAR PURPOSE.\n"); return 0; } } @@ -329,7 +328,7 @@ int main(int argc, char *argv[]) Target_Device_Object_Instance = strtol(argv[1], NULL, 0); if (Target_Device_Object_Instance >= BACNET_MAX_INSTANCE) { fprintf(stderr, "device-instance=%u - it must be less than %u\n", - Target_Device_Object_Instance, BACNET_MAX_INSTANCE); + Target_Device_Object_Instance, BACNET_MAX_INSTANCE); return 1; } atexit(cleanup); @@ -348,7 +347,7 @@ int main(int argc, char *argv[]) } if (rpm_object->object_type >= MAX_BACNET_OBJECT_TYPE) { fprintf(stderr, "object-type=%u - it must be less than %u\n", - rpm_object->object_type, MAX_BACNET_OBJECT_TYPE); + rpm_object->object_type, MAX_BACNET_OBJECT_TYPE); return 1; } rpm_object->object_instance = strtol(argv[tag_value_arg], NULL, 0); @@ -360,7 +359,7 @@ int main(int argc, char *argv[]) } if (rpm_object->object_instance > BACNET_MAX_INSTANCE) { fprintf(stderr, "object-instance=%u - it must be less than %u\n", - rpm_object->object_instance, BACNET_MAX_INSTANCE + 1); + rpm_object->object_instance, BACNET_MAX_INSTANCE + 1); return 1; } rpm_property = calloc(1, sizeof(BACNET_PROPERTY_REFERENCE)); @@ -368,14 +367,14 @@ int main(int argc, char *argv[]) property_token = strtok(argv[tag_value_arg], ","); /* add all the properties and optional index to our list */ while (rpm_property) { - scan_count = sscanf(property_token, "%u[%u]", &property_id, - &property_array_index); + scan_count = sscanf( + property_token, "%u[%u]", &property_id, &property_array_index); if (scan_count > 0) { rpm_property->propertyIdentifier = property_id; if (rpm_property->propertyIdentifier > MAX_BACNET_PROPERTY_ID) { fprintf(stderr, "property=%u - it must be less than %u\n", - rpm_property->propertyIdentifier, - MAX_BACNET_PROPERTY_ID + 1); + rpm_property->propertyIdentifier, + MAX_BACNET_PROPERTY_ID + 1); return 1; } } @@ -416,11 +415,11 @@ int main(int argc, char *argv[]) last_seconds = time(NULL); timeout_seconds = (apdu_timeout() / 1000) * apdu_retries(); /* try to bind with the device */ - found = address_bind_request(Target_Device_Object_Instance, &max_apdu, - &Target_Address); + found = address_bind_request( + Target_Device_Object_Instance, &max_apdu, &Target_Address); if (!found) { - Send_WhoIs(Target_Device_Object_Instance, - Target_Device_Object_Instance); + Send_WhoIs( + Target_Device_Object_Instance, Target_Device_Object_Instance); } /* loop forever */ for (;;) { @@ -428,23 +427,24 @@ int main(int argc, char *argv[]) current_seconds = time(NULL); /* at least one second has passed */ - if (current_seconds != last_seconds) + if (current_seconds != last_seconds) { tsm_timer_milliseconds(((current_seconds - last_seconds) * 1000)); + } if (Error_Detected) break; /* wait until the device is bound, or timeout and quit */ if (!found) { - found = address_bind_request(Target_Device_Object_Instance, - &max_apdu, &Target_Address); + found = address_bind_request( + Target_Device_Object_Instance, &max_apdu, &Target_Address); } if (found) { if (Request_Invoke_ID == 0) { Request_Invoke_ID = Send_Read_Property_Multiple_Request( &buffer[0], sizeof(buffer), Target_Device_Object_Instance, Read_Access_Data); - } else if (tsm_invoke_id_free(Request_Invoke_ID)) + } else if (tsm_invoke_id_free(Request_Invoke_ID)) { break; - else if (tsm_invoke_id_failed(Request_Invoke_ID)) { + } else if (tsm_invoke_id_failed(Request_Invoke_ID)) { fprintf(stderr, "\rError: TSM Timeout!\n"); tsm_free_invoke_id(Request_Invoke_ID); Error_Detected = true; diff --git a/apps/readrange/Makefile b/apps/readrange/Makefile new file mode 100644 index 00000000..3445af40 --- /dev/null +++ b/apps/readrange/Makefile @@ -0,0 +1,50 @@ +#Makefile to build BACnet Application using GCC compiler + +# Executable file name +TARGET = bacrr +# BACnet objects that are used with this app +BACNET_OBJECT_DIR = $(BACNET_SRC_DIR)/bacnet/basic/object +SRC = main.c \ + $(BACNET_OBJECT_DIR)/client/device-client.c \ + $(BACNET_OBJECT_DIR)/netport.c +BACNET_BASIC_SRC += \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_apdu.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_iam.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_noserv.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_rp.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_rr_a.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_whois.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/s_iam.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/s_readrange.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/s_whois.c + +# TARGET_EXT is defined in apps/Makefile as .exe or nothing +TARGET_BIN = ${TARGET}$(TARGET_EXT) + +SRCS = $(SRC) $(BACNET_SRC) $(BACNET_BASIC_SRC) $(BACNET_PORT_SRC) + +OBJS += ${SRCS:.c=.o} + +.PHONY: all +all: Makefile ${TARGET_BIN} + +${TARGET_BIN}: ${OBJS} + ${CC} ${PFLAGS} ${OBJS} ${LFLAGS} -o $@ + size $@ + cp $@ ../../bin + +.c.o: + ${CC} -c ${CFLAGS} $*.c -o $@ + +.PHONY: depend +depend: + rm -f .depend + ${CC} -MM ${CFLAGS} *.c >> .depend + +.PHONY: clean +clean: + rm -f core ${TARGET_BIN} ${OBJS} $(TARGET).map + +.PHONY: include +include: .depend + diff --git a/demo/readrange/main.c b/apps/readrange/main.c similarity index 70% rename from demo/readrange/main.c rename to apps/readrange/main.c index 81a9d0a2..58ac346e 100644 --- a/demo/readrange/main.c +++ b/apps/readrange/main.c @@ -31,30 +31,30 @@ #include #include #include /* for time */ -#include "bacdef.h" -#include "config.h" -#include "bactext.h" -#include "bacerror.h" -#include "iam.h" -#include "tsm.h" -#include "address.h" -#include "npdu.h" -#include "apdu.h" -#include "device.h" -#include "net.h" -#include "datalink.h" -#include "whois.h" -#include "version.h" +#include "bacnet/bacdef.h" +#include "bacnet/config.h" +#include "bacnet/bactext.h" +#include "bacnet/bacerror.h" +#include "bacnet/iam.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/basic/binding/address.h" +#include "bacnet/npdu.h" +#include "bacnet/apdu.h" +#include "bacnet/basic/object/device.h" +#include "bacport.h" +#include "bacnet/datalink/datalink.h" +#include "bacnet/whois.h" +#include "bacnet/version.h" /* some demo stuff needed */ -#include "filename.h" -#include "handlers.h" -#include "client.h" -#include "txbuf.h" -#include "dlenv.h" -#include "readrange.h" +#include "bacnet/basic/sys/filename.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/datalink/dlenv.h" +#include "bacnet/readrange.h" /* buffer used for receive */ -static uint8_t Rx_Buf[MAX_MPDU] = {0}; +static uint8_t Rx_Buf[MAX_MPDU] = { 0 }; /* converted command line arguments */ static uint32_t Target_Device_Object_Instance = BACNET_MAX_INSTANCE; @@ -71,38 +71,39 @@ static bool Error_Detected = false; /* specific request data */ static BACNET_READ_RANGE_DATA RR_Request; -static void MyErrorHandler(BACNET_ADDRESS *src, uint8_t invoke_id, - BACNET_ERROR_CLASS error_class, - BACNET_ERROR_CODE error_code) +static void MyErrorHandler(BACNET_ADDRESS *src, + uint8_t invoke_id, + BACNET_ERROR_CLASS error_class, + BACNET_ERROR_CODE error_code) { if (address_match(&Target_Address, src) && (invoke_id == Request_Invoke_ID)) { printf("BACnet Error: %s: %s\r\n", - bactext_error_class_name((int)error_class), - bactext_error_code_name((int)error_code)); + bactext_error_class_name((int)error_class), + bactext_error_code_name((int)error_code)); Error_Detected = true; } } -void MyAbortHandler(BACNET_ADDRESS *src, uint8_t invoke_id, - uint8_t abort_reason, bool server) +static void MyAbortHandler( + BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t abort_reason, bool server) { (void)server; if (address_match(&Target_Address, src) && (invoke_id == Request_Invoke_ID)) { - printf("BACnet Abort: %s\n", - bactext_abort_reason_name((int)abort_reason)); + printf( + "BACnet Abort: %s\n", bactext_abort_reason_name((int)abort_reason)); Error_Detected = true; } } -void MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, - uint8_t reject_reason) +static void MyRejectHandler( + BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason) { if (address_match(&Target_Address, src) && (invoke_id == Request_Invoke_ID)) { printf("BACnet Reject: %s\n", - bactext_reject_reason_name((int)reject_reason)); + bactext_reject_reason_name((int)reject_reason)); Error_Detected = true; } } @@ -119,11 +120,11 @@ static void Init_Service_Handlers(void) It is required to send the proper reject message... */ apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service); /* we must implement read property - it's required! */ - apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY, - handler_read_property); + apdu_set_confirmed_handler( + SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property); /* handle the data coming back from confirmed requests */ - apdu_set_confirmed_ack_handler(SERVICE_CONFIRMED_READ_RANGE, - handler_read_range_ack); + apdu_set_confirmed_ack_handler( + SERVICE_CONFIRMED_READ_RANGE, handler_read_range_ack); /* handle any errors coming back */ apdu_set_error_handler(SERVICE_CONFIRMED_READ_PROPERTY, MyErrorHandler); @@ -135,50 +136,49 @@ static void Init_Service_Handlers(void) static void print_usage(char *filename) { printf("Usage: %s device-instance object-type object-instance property\n", - filename); + filename); printf(" range-type > count\n"); printf(" [--version][--help]\n"); } static void print_help(char *filename) { - printf( - "Read a range of properties from an array or list property\n" - "in an object in a BACnet device and print the values.\n" - "device-instance:\n" - "BACnet Device Object Instance number that you are\n" - "trying to communicate to. This number will be used\n" - "to try and bind with the device using Who-Is and\n" - "I-Am services. For example, if you were reading\n" - "Device Object 123, the device-instance would be 123.\n" - "\nobject-type:\n" - "The object type is the integer value of the enumeration\n" - "BACNET_OBJECT_TYPE in bacenum.h. It is the object\n" - "that you are reading. For example if you were\n" - "reading Trend Log 2, the object-type would be 20.\n" - "\nobject-instance:\n" - "This is the object instance number of the object that\n" - "you are reading. For example, if you were reading\n" - "Trend Log 2, the object-instance would be 2.\n" - "\nproperty:\n" - "The property is an integer value of the enumeration\n" - "BACNET_PROPERTY_ID in bacenum.h. It is the property\n" - "you are reading. For example, if you were reading the\n" - "Log_Buffer property, use 131 as the property.\n" - "\nrange-type:\n" - "1=By Position\n" - "2=By Sequence\n" - "3=By Time\n" - "4=All\n" - "\nindex or date/time:\n" - "This integer parameter is the starting index, or date & time.\n" - "\ncount:\n" - "This integer parameter is the number of elements to read.\n" - "\nExample:\n" - "If you want read the Log_Buffer of Trend Log 2\n" - "in Device 123, from starting position 1 and read 10 entries,\n" - "you could send the following command:\n" - "%s 123 20 2 131 1 1 10\n", + printf("Read a range of properties from an array or list property\n" + "in an object in a BACnet device and print the values.\n" + "device-instance:\n" + "BACnet Device Object Instance number that you are\n" + "trying to communicate to. This number will be used\n" + "to try and bind with the device using Who-Is and\n" + "I-Am services. For example, if you were reading\n" + "Device Object 123, the device-instance would be 123.\n" + "\nobject-type:\n" + "The object type is the integer value of the enumeration\n" + "BACNET_OBJECT_TYPE in bacenum.h. It is the object\n" + "that you are reading. For example if you were\n" + "reading Trend Log 2, the object-type would be 20.\n" + "\nobject-instance:\n" + "This is the object instance number of the object that\n" + "you are reading. For example, if you were reading\n" + "Trend Log 2, the object-instance would be 2.\n" + "\nproperty:\n" + "The property is an integer value of the enumeration\n" + "BACNET_PROPERTY_ID in bacenum.h. It is the property\n" + "you are reading. For example, if you were reading the\n" + "Log_Buffer property, use 131 as the property.\n" + "\nrange-type:\n" + "1=By Position\n" + "2=By Sequence\n" + "3=By Time\n" + "4=All\n" + "\nindex or date/time:\n" + "This integer parameter is the starting index, or date & time.\n" + "\ncount:\n" + "This integer parameter is the number of elements to read.\n" + "\nExample:\n" + "If you want read the Log_Buffer of Trend Log 2\n" + "in Device 123, from starting position 1 and read 10 entries,\n" + "you could send the following command:\n" + "%s 123 20 2 131 1 1 10\n", filename); printf("%s 123 20 2 131 2 1 10\n", filename); printf("%s 123 20 2 131 3 1/1/2014 00:00:01 10\n", filename); @@ -186,7 +186,7 @@ static void print_help(char *filename) int main(int argc, char *argv[]) { - BACNET_ADDRESS src = {0}; /* address where message came from */ + BACNET_ADDRESS src = { 0 }; /* address where message came from */ uint16_t pdu_len = 0; unsigned timeout = 100; /* milliseconds */ unsigned max_apdu = 0; @@ -210,12 +210,11 @@ int main(int argc, char *argv[]) } if (strcmp(argv[argi], "--version") == 0) { printf("%s %s\n", filename, BACNET_VERSION_TEXT); - printf( - "Copyright (C) 2014 by Steve Karg and others.\n" - "This is free software; see the source for copying " - "conditions.\n" - "There is NO warranty; not even for MERCHANTABILITY or\n" - "FITNESS FOR A PARTICULAR PURPOSE.\n"); + printf("Copyright (C) 2014 by Steve Karg and others.\n" + "This is free software; see the source for copying " + "conditions.\n" + "There is NO warranty; not even for MERCHANTABILITY or\n" + "FITNESS FOR A PARTICULAR PURPOSE.\n"); return 0; } } @@ -232,7 +231,7 @@ int main(int argc, char *argv[]) /* some bounds checking */ if (Target_Device_Object_Instance > BACNET_MAX_INSTANCE) { fprintf(stderr, "device-instance=%u - it must be less than %u\r\n", - Target_Device_Object_Instance, BACNET_MAX_INSTANCE); + Target_Device_Object_Instance, BACNET_MAX_INSTANCE); return 1; } if (Target_Object_Range_Type == 1) { @@ -264,7 +263,7 @@ int main(int argc, char *argv[]) count = sscanf(argv[6], "%4d/%3d/%3d:%3d", &year, &month, &day, &wday); if (count == 3) { datetime_set_date(&RR_Request.Range.RefTime.date, (uint16_t)year, - (uint8_t)month, (uint8_t)day); + (uint8_t)month, (uint8_t)day); } else if (count == 4) { RR_Request.Range.RefTime.date.year = (uint16_t)year; RR_Request.Range.RefTime.date.month = (uint8_t)month; @@ -318,11 +317,11 @@ int main(int argc, char *argv[]) last_seconds = time(NULL); timeout_seconds = (apdu_timeout() / 1000) * apdu_retries(); /* try to bind with the device */ - found = address_bind_request(Target_Device_Object_Instance, &max_apdu, - &Target_Address); + found = address_bind_request( + Target_Device_Object_Instance, &max_apdu, &Target_Address); if (!found) { - Send_WhoIs(Target_Device_Object_Instance, - Target_Device_Object_Instance); + Send_WhoIs( + Target_Device_Object_Instance, Target_Device_Object_Instance); } /* loop forever */ for (;;) { @@ -330,23 +329,24 @@ int main(int argc, char *argv[]) current_seconds = time(NULL); /* at least one second has passed */ - if (current_seconds != last_seconds) + if (current_seconds != last_seconds) { tsm_timer_milliseconds( (uint16_t)((current_seconds - last_seconds) * 1000)); + } if (Error_Detected) break; /* wait until the device is bound, or timeout and quit */ if (!found) { - found = address_bind_request(Target_Device_Object_Instance, - &max_apdu, &Target_Address); + found = address_bind_request( + Target_Device_Object_Instance, &max_apdu, &Target_Address); } if (found) { if (Request_Invoke_ID == 0) { Request_Invoke_ID = Send_ReadRange_Request( Target_Device_Object_Instance, &RR_Request); - } else if (tsm_invoke_id_free(Request_Invoke_ID)) + } else if (tsm_invoke_id_free(Request_Invoke_ID)) { break; - else if (tsm_invoke_id_failed(Request_Invoke_ID)) { + } else if (tsm_invoke_id_failed(Request_Invoke_ID)) { fprintf(stderr, "\rError: TSM Timeout!\n"); tsm_free_invoke_id(Request_Invoke_ID); Error_Detected = true; diff --git a/demo/readrange/readrange/readrange.sln b/apps/readrange/readrange/readrange.sln similarity index 100% rename from demo/readrange/readrange/readrange.sln rename to apps/readrange/readrange/readrange.sln diff --git a/demo/readrange/readrange/readrange.vcproj b/apps/readrange/readrange/readrange.vcproj similarity index 94% rename from demo/readrange/readrange/readrange.vcproj rename to apps/readrange/readrange/readrange.vcproj index d7a55a56..610b3d77 100644 --- a/demo/readrange/readrange/readrange.vcproj +++ b/apps/readrange/readrange/readrange.vcproj @@ -1,1043 +1,1043 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/reinit/Makefile b/apps/reinit/Makefile new file mode 100644 index 00000000..9c4aa0d4 --- /dev/null +++ b/apps/reinit/Makefile @@ -0,0 +1,53 @@ +#Makefile to build BACnet Application for the Linux Port + +# tools - only if you need them. +# Most platforms have this already defined +# CC = gcc + +# Executable file name +TARGET = bacrd +# BACnet objects that are used with this app +BACNET_OBJECT_DIR = $(BACNET_SRC_DIR)/bacnet/basic/object +SRC = main.c \ + $(BACNET_OBJECT_DIR)/client/device-client.c \ + $(BACNET_OBJECT_DIR)/netport.c +BACNET_BASIC_SRC += \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_apdu.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_iam.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_noserv.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_rp.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_whois.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/s_iam.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/s_rd.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/s_whois.c + +# TARGET_EXT is defined in apps/Makefile as .exe or nothing +TARGET_BIN = ${TARGET}$(TARGET_EXT) + +SRCS = $(SRC) $(BACNET_SRC) $(BACNET_BASIC_SRC) $(BACNET_PORT_SRC) + +OBJS += ${SRCS:.c=.o} + +.PHONY: all +all: Makefile ${TARGET_BIN} + +${TARGET_BIN}: ${OBJS} + ${CC} ${PFLAGS} ${OBJS} ${LFLAGS} -o $@ + size $@ + cp $@ ../../bin + +.c.o: + ${CC} -c ${CFLAGS} $*.c -o $@ + +.PHONY: depend +depend: + rm -f .depend + ${CC} -MM ${CFLAGS} *.c >> .depend + +.PHONY: clean +clean: + rm -f core ${TARGET_BIN} ${OBJS} $(TARGET).map + +.PHONY: include +include: .depend + diff --git a/demo/reinit/main.c b/apps/reinit/main.c similarity index 70% rename from demo/reinit/main.c rename to apps/reinit/main.c index 4b6dcf98..a257249e 100644 --- a/demo/reinit/main.c +++ b/apps/reinit/main.c @@ -30,29 +30,29 @@ #include #include /* for time */ #include -#include "bactext.h" -#include "iam.h" -#include "arf.h" -#include "tsm.h" -#include "address.h" -#include "config.h" -#include "bacdef.h" -#include "npdu.h" -#include "apdu.h" -#include "device.h" -#include "net.h" -#include "datalink.h" -#include "whois.h" -#include "rd.h" +#include "bacnet/bactext.h" +#include "bacnet/iam.h" +#include "bacnet/arf.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/basic/binding/address.h" +#include "bacnet/config.h" +#include "bacnet/bacdef.h" +#include "bacnet/npdu.h" +#include "bacnet/apdu.h" +#include "bacnet/basic/object/device.h" +#include "bacport.h" +#include "bacnet/datalink/datalink.h" +#include "bacnet/whois.h" +#include "bacnet/rd.h" /* some demo stuff needed */ -#include "filename.h" -#include "handlers.h" -#include "client.h" -#include "txbuf.h" -#include "dlenv.h" +#include "bacnet/basic/sys/filename.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/datalink/dlenv.h" /* buffer used for receive */ -static uint8_t Rx_Buf[MAX_MPDU] = {0}; +static uint8_t Rx_Buf[MAX_MPDU] = { 0 }; /* global variables used in this file */ static uint32_t Target_Device_Object_Instance = BACNET_MAX_INSTANCE; @@ -62,20 +62,21 @@ static char *Reinitialize_Password = NULL; static bool Error_Detected = false; -static void MyErrorHandler(BACNET_ADDRESS *src, uint8_t invoke_id, - BACNET_ERROR_CLASS error_class, - BACNET_ERROR_CODE error_code) +static void MyErrorHandler(BACNET_ADDRESS *src, + uint8_t invoke_id, + BACNET_ERROR_CLASS error_class, + BACNET_ERROR_CODE error_code) { /* FIXME: verify src and invoke id */ (void)src; (void)invoke_id; printf("BACnet Error: %s: %s\r\n", bactext_error_class_name(error_class), - bactext_error_code_name(error_code)); + bactext_error_code_name(error_code)); Error_Detected = true; } -void MyAbortHandler(BACNET_ADDRESS *src, uint8_t invoke_id, - uint8_t abort_reason, bool server) +static void MyAbortHandler( + BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t abort_reason, bool server) { /* FIXME: verify src and invoke id */ (void)src; @@ -85,8 +86,8 @@ void MyAbortHandler(BACNET_ADDRESS *src, uint8_t invoke_id, Error_Detected = true; } -void MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, - uint8_t reject_reason) +static void MyRejectHandler( + BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason) { /* FIXME: verify src and invoke id */ (void)src; @@ -95,8 +96,8 @@ void MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, Error_Detected = true; } -void MyReinitializeDeviceSimpleAckHandler(BACNET_ADDRESS *src, - uint8_t invoke_id) +static void MyReinitializeDeviceSimpleAckHandler( + BACNET_ADDRESS *src, uint8_t invoke_id) { (void)src; (void)invoke_id; @@ -115,21 +116,21 @@ static void Init_Service_Handlers(void) It is required to send the proper reject message... */ apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service); /* we must implement read property - it's required! */ - apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY, - handler_read_property); + apdu_set_confirmed_handler( + SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property); /* handle the ack coming back */ apdu_set_confirmed_simple_ack_handler(SERVICE_CONFIRMED_REINITIALIZE_DEVICE, - MyReinitializeDeviceSimpleAckHandler); + MyReinitializeDeviceSimpleAckHandler); /* handle any errors coming back */ - apdu_set_error_handler(SERVICE_CONFIRMED_REINITIALIZE_DEVICE, - MyErrorHandler); + apdu_set_error_handler( + SERVICE_CONFIRMED_REINITIALIZE_DEVICE, MyErrorHandler); apdu_set_abort_handler(MyAbortHandler); apdu_set_reject_handler(MyRejectHandler); } int main(int argc, char *argv[]) { - BACNET_ADDRESS src = {0}; /* address where message came from */ + BACNET_ADDRESS src = { 0 }; /* address where message came from */ uint16_t pdu_len = 0; unsigned timeout = 100; /* milliseconds */ unsigned max_apdu = 0; @@ -142,21 +143,20 @@ int main(int argc, char *argv[]) if (argc < 3) { /* note: priority 16 and 0 should produce the same end results... */ - printf( - "Usage: %s device-instance state [password]\r\n" - "Send BACnet ReinitializeDevice service to device.\r\n" - "\r\n" - "The device-instance can be 0 to %d.\r\n" - "Possible state values:\r\n" - " 0=coldstart\r\n" - " 1=warmstart\r\n" - " 2=startbackup\r\n" - " 3=endbackup\r\n" - " 4=startrestore\r\n" - " 5=endrestore\r\n" - " 6=abortrestore\r\n" - "The optional password is a character string of 1 to 20 " - "characters.\r\n", + printf("Usage: %s device-instance state [password]\r\n" + "Send BACnet ReinitializeDevice service to device.\r\n" + "\r\n" + "The device-instance can be 0 to %d.\r\n" + "Possible state values:\r\n" + " 0=coldstart\r\n" + " 1=warmstart\r\n" + " 2=startbackup\r\n" + " 3=endbackup\r\n" + " 4=startrestore\r\n" + " 5=endrestore\r\n" + " 6=abortrestore\r\n" + "The optional password is a character string of 1 to 20 " + "characters.\r\n", filename_remove_path(argv[0]), BACNET_MAX_INSTANCE - 1); return 0; } @@ -164,12 +164,13 @@ int main(int argc, char *argv[]) Target_Device_Object_Instance = strtol(argv[1], NULL, 0); Reinitialize_State = strtol(argv[2], NULL, 0); /* optional password */ - if (argc > 3) + if (argc > 3) { Reinitialize_Password = argv[3]; + } if (Target_Device_Object_Instance >= BACNET_MAX_INSTANCE) { fprintf(stderr, "device-instance=%u - it must be less than %u\r\n", - Target_Device_Object_Instance, BACNET_MAX_INSTANCE); + Target_Device_Object_Instance, BACNET_MAX_INSTANCE); return 1; } @@ -183,11 +184,11 @@ int main(int argc, char *argv[]) last_seconds = time(NULL); timeout_seconds = (apdu_timeout() / 1000) * apdu_retries(); /* try to bind with the device */ - found = address_bind_request(Target_Device_Object_Instance, &max_apdu, - &Target_Address); + found = address_bind_request( + Target_Device_Object_Instance, &max_apdu, &Target_Address); if (!found) { - Send_WhoIs(Target_Device_Object_Instance, - Target_Device_Object_Instance); + Send_WhoIs( + Target_Device_Object_Instance, Target_Device_Object_Instance); } /* loop forever */ for (;;) { @@ -202,23 +203,24 @@ int main(int argc, char *argv[]) npdu_handler(&src, &Rx_Buf[0], pdu_len); } /* at least one second has passed */ - if (current_seconds != last_seconds) + if (current_seconds != last_seconds) { tsm_timer_milliseconds(((current_seconds - last_seconds) * 1000)); + } if (Error_Detected) break; /* wait until the device is bound, or timeout and quit */ if (!found) { - found = address_bind_request(Target_Device_Object_Instance, - &max_apdu, &Target_Address); + found = address_bind_request( + Target_Device_Object_Instance, &max_apdu, &Target_Address); } if (found) { if (invoke_id == 0) { invoke_id = Send_Reinitialize_Device_Request( Target_Device_Object_Instance, Reinitialize_State, Reinitialize_Password); - } else if (tsm_invoke_id_free(invoke_id)) + } else if (tsm_invoke_id_free(invoke_id)) { break; - else if (tsm_invoke_id_failed(invoke_id)) { + } else if (tsm_invoke_id_failed(invoke_id)) { fprintf(stderr, "\rError: TSM Timeout!\r\n"); tsm_free_invoke_id(invoke_id); /* try again or abort? */ diff --git a/apps/router-ipv6/Makefile b/apps/router-ipv6/Makefile new file mode 100644 index 00000000..e7ca9846 --- /dev/null +++ b/apps/router-ipv6/Makefile @@ -0,0 +1,78 @@ +#Makefile to build BACnet Application for the GCC port + +# tools - only if you need them. +# Most platforms have this already defined +# CC = gcc + +# Executable file name +TARGET = bacroute + +TARGET_BIN = ${TARGET}$(TARGET_EXT) + +# BACNET_PORT, BACNET_PORT_DIR, BACNET_PORT_SRC are defined in common Makefile +# BACNET_SRC_DIR is defined in common apps Makefile +BACNET_OBJECT_DIR = $(BACNET_SRC_DIR)/bacnet/basic/object +SRC = main.c \ + $(BACNET_OBJECT_DIR)/netport.c \ + $(BACNET_OBJECT_DIR)/client/device-client.c + +PORT_BIP6_SRC = \ + $(BACNET_PORT_DIR)/bip6.c \ + $(BACNET_SRC_DIR)/bacnet/datalink/bvlc6.c \ + $(BACNET_SRC_DIR)/bacnet/basic/bbmd6/h_bbmd6.c \ + $(BACNET_SRC_DIR)/bacnet/basic/bbmd6/vmac.c + +PORT_BIP_SRC = \ + $(BACNET_PORT_DIR)/bip-init.c \ + $(BACNET_SRC_DIR)/bacnet/datalink/bvlc.c \ + $(BACNET_SRC_DIR)/bacnet/datalink/bip.c + +# WARNINGS, DEBUGGING, OPTIMIZATION are defined in common apps Makefile +# BACNET_DEFINES is defined in common apps Makefile +# put all the flags together +INCLUDES = -I$(BACNET_SRC_DIR) -I$(BACNET_PORT_DIR) +CFLAGS += $(WARNINGS) $(DEBUGGING) $(OPTIMIZATION) $(BACNET_DEFINES) $(INCLUDES) +LFLAGS += -Wl,$(SYSTEM_LIB) +ifneq (${BACNET_LIB},) +LFLAGS += -Wl,$(BACNET_LIB) +endif +# GCC dead code removal +CFLAGS += -ffunction-sections -fdata-sections +LFLAGS += -Wl,--gc-sections + +BACNET_SRC ?= \ + $(wildcard $(BACNET_SRC_DIR)/bacnet/*.c) \ + $(wildcard $(BACNET_SRC_DIR)/bacnet/basic/*.c) \ + $(wildcard $(BACNET_SRC_DIR)/bacnet/basic/binding/*.c) \ + $(wildcard $(BACNET_SRC_DIR)/bacnet/basic/service/*.c) \ + $(wildcard $(BACNET_SRC_DIR)/bacnet/basic/sys/*.c) \ + $(BACNET_SRC_DIR)/bacnet/basic/npdu/h_routed_npdu.c \ + $(BACNET_SRC_DIR)/bacnet/basic/npdu/s_router.c \ + $(BACNET_SRC_DIR)/bacnet/basic/tsm/tsm.c + +SRCS = ${SRC} $(BACNET_SRC) ${PORT_BIP6_SRC} ${PORT_BIP_SRC} + +OBJS += ${SRCS:.c=.o} + +.PHONY: all +all: Makefile ${TARGET_BIN} + +${TARGET_BIN}: ${OBJS} + ${CC} ${PFLAGS} ${OBJS} ${LFLAGS} -o $@ + size $@ + cp $@ ../../bin + +.c.o: + ${CC} -c ${CFLAGS} $*.c -o $@ + +.PHONY: depend +depend: + rm -f .depend + ${CC} -MM ${CFLAGS} *.c >> .depend + +.PHONY: clean +clean: + rm -f core ${TARGET_BIN} ${OBJS} $(TARGET).map + +.PHONY: include +include: .depend diff --git a/demo/router-ipv6/main.c b/apps/router-ipv6/main.c similarity index 88% rename from demo/router-ipv6/main.c rename to apps/router-ipv6/main.c index 335a54af..e37dc150 100644 --- a/demo/router-ipv6/main.c +++ b/apps/router-ipv6/main.c @@ -36,28 +36,33 @@ #include #include -#include "bacdef.h" -#include "config.h" -#include "debug.h" -#include "bactext.h" -#include "bacerror.h" -#include "iam.h" -#include "arf.h" -#include "tsm.h" -#include "address.h" -#include "npdu.h" -#include "apdu.h" -#include "client.h" -#include "net.h" -#include "version.h" - +#include "bacnet/bacdef.h" +#include "bacnet/config.h" +#include "bacnet/bactext.h" +#include "bacnet/bacerror.h" +#include "bacnet/iam.h" +#include "bacnet/arf.h" +#include "bacnet/npdu.h" +#include "bacnet/apdu.h" +#include "bacnet/version.h" +/* some demo modules we use */ +#include "bacnet/basic/sys/debug.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/basic/binding/address.h" +#include "bacnet/basic/services.h" +/* port agnostic file */ +#include "bacport.h" /* our datalink layers */ -#include "bvlc6.h" -#include "bip6.h" +#include "bacnet/datalink/bvlc6.h" +#include "bacnet/datalink/bip6.h" +#include "bacnet/basic/bbmd6/h_bbmd6.h" #undef MAX_HEADER #undef MAX_MPDU -#include "bip.h" -#include "bvlc.h" +#include "bacnet/datalink/bip.h" +#include "bacnet/datalink/bvlc.h" + +/* current version of the BACnet stack */ +static const char *BACnet_Version = BACNET_VERSION_TEXT; /** * 6.6.1 Routing Tables @@ -320,9 +325,11 @@ static void datalink_get_broadcast_address(BACNET_ADDRESS *dest) * * @return number of bytes sent */ -static int datalink_send_pdu(uint16_t snet, BACNET_ADDRESS *dest, - BACNET_NPDU_DATA *npdu_data, uint8_t *pdu, - unsigned int pdu_len) +static int datalink_send_pdu(uint16_t snet, + BACNET_ADDRESS *dest, + BACNET_NPDU_DATA *npdu_data, + uint8_t *pdu, + unsigned int pdu_len) { int bytes_sent = 0; @@ -341,36 +348,6 @@ static int datalink_send_pdu(uint16_t snet, BACNET_ADDRESS *dest, return bytes_sent; } -/** Initialize an npdu_data structure with given parameters and good defaults, - * and add the Network Layer Message fields. - * The name is a misnomer, as it doesn't do any actual encoding here. - * @see npdu_encode_npdu_data for a simpler version to use when sending an - * APDU instead of a Network Layer Message. - * - * @param npdu_data [out] Returns a filled-out structure with information - * provided by the other arguments and - * good defaults. - * @param network_message_type [in] The type of Network Layer Message. - * @param data_expecting_reply [in] True if message should have a reply. - * @param priority [in] One of the 4 priorities defined in section 6.2.2, - * like B'11' = Life Safety message - */ -static void npdu_encode_npdu_network( - BACNET_NPDU_DATA *npdu_data, - BACNET_NETWORK_MESSAGE_TYPE network_message_type, bool data_expecting_reply, - BACNET_MESSAGE_PRIORITY priority) -{ - if (npdu_data) { - npdu_data->data_expecting_reply = data_expecting_reply; - npdu_data->protocol_version = BACNET_PROTOCOL_VERSION; - npdu_data->network_layer_message = true; /* false if APDU */ - npdu_data->network_message_type = network_message_type; /* optional */ - npdu_data->vendor_id = 0; /* optional, if net message type is > 0x80 */ - npdu_data->priority = priority; - npdu_data->hop_count = HOP_COUNT_DEFAULT; - } -} - /** * Broadcast an I-am-router-to-network message * @@ -393,7 +370,7 @@ static void send_i_am_router_to_network(uint16_t snet, uint16_t net) datalink_get_broadcast_address(&dest); npdu_encode_npdu_network(&npdu_data, NETWORK_MESSAGE_I_AM_ROUTER_TO_NETWORK, - data_expecting_reply, MESSAGE_PRIORITY_NORMAL); + data_expecting_reply, MESSAGE_PRIORITY_NORMAL); /* We don't need src information, since a message can't originate from our downstream BACnet network. */ pdu_len = npdu_encode_pdu(&Tx_Buffer[0], &dest, NULL, &npdu_data); @@ -443,7 +420,7 @@ static void send_i_am_router_to_network(uint16_t snet, uint16_t net) * Optionally may designate a particular router destination, * especially when ACKing receipt of this message type. */ -void send_initialize_routing_table_ack(uint8_t snet, BACNET_ADDRESS *dst) +static void send_initialize_routing_table_ack(uint8_t snet, BACNET_ADDRESS *dst) { BACNET_ADDRESS dest; bool data_expecting_reply = false; @@ -460,7 +437,7 @@ void send_initialize_routing_table_ack(uint8_t snet, BACNET_ADDRESS *dst) datalink_get_broadcast_address(&dest); } npdu_encode_npdu_network(&npdu_data, NETWORK_MESSAGE_INIT_RT_TABLE_ACK, - data_expecting_reply, MESSAGE_PRIORITY_NORMAL); + data_expecting_reply, MESSAGE_PRIORITY_NORMAL); /* We don't need src information, since a message can't originate from our downstream BACnet network. */ pdu_len = npdu_encode_pdu(&Tx_Buffer[0], &dest, NULL, &npdu_data); @@ -502,8 +479,8 @@ void send_initialize_routing_table_ack(uint8_t snet, BACNET_ADDRESS *dst) * destination. * @param reject_reason [in] One of the BACNET_NETWORK_REJECT_REASONS codes. */ -void send_reject_message_to_network(uint16_t snet, BACNET_ADDRESS *dst, - uint8_t reject_reason, uint16_t dnet) +static void send_reject_message_to_network( + uint16_t snet, BACNET_ADDRESS *dst, uint8_t reject_reason, uint16_t dnet) { BACNET_ADDRESS dest; bool data_expecting_reply = false; @@ -517,8 +494,8 @@ void send_reject_message_to_network(uint16_t snet, BACNET_ADDRESS *dst, datalink_get_broadcast_address(&dest); } npdu_encode_npdu_network(&npdu_data, - NETWORK_MESSAGE_REJECT_MESSAGE_TO_NETWORK, - data_expecting_reply, MESSAGE_PRIORITY_NORMAL); + NETWORK_MESSAGE_REJECT_MESSAGE_TO_NETWORK, data_expecting_reply, + MESSAGE_PRIORITY_NORMAL); /* We don't need src information, since a message can't originate from our downstream BACnet network. */ pdu_len = npdu_encode_pdu(&Tx_Buffer[0], &dest, NULL, &npdu_data); @@ -548,8 +525,8 @@ static void send_who_is_router_to_network(uint16_t snet, uint16_t dnet) datalink_get_broadcast_address(&dest); npdu_encode_npdu_network(&npdu_data, - NETWORK_MESSAGE_WHO_IS_ROUTER_TO_NETWORK, - data_expecting_reply, MESSAGE_PRIORITY_NORMAL); + NETWORK_MESSAGE_WHO_IS_ROUTER_TO_NETWORK, data_expecting_reply, + MESSAGE_PRIORITY_NORMAL); pdu_len = npdu_encode_pdu(&Tx_Buffer[0], &dest, NULL, &npdu_data); if (dnet) { len = encode_unsigned16(&Tx_Buffer[pdu_len], dnet); @@ -615,9 +592,11 @@ static void send_who_is_router_to_network(uint16_t snet, uint16_t dnet) * bytes that have already been decoded. * @param npdu_len [in] The length of the remaining NPDU message in npdu[]. */ -static void who_is_router_to_network_handler(uint16_t snet, BACNET_ADDRESS *src, - BACNET_NPDU_DATA *npdu_data, - uint8_t *npdu, uint16_t npdu_len) +static void who_is_router_to_network_handler(uint16_t snet, + BACNET_ADDRESS *src, + BACNET_NPDU_DATA *npdu_data, + uint8_t *npdu, + uint16_t npdu_len) { DNET *port = NULL; uint16_t network = 0; @@ -664,9 +643,11 @@ static void who_is_router_to_network_handler(uint16_t snet, BACNET_ADDRESS *src, * bytes that have already been decoded. * @param npdu_len [in] The length of the remaining NPDU message in npdu[]. */ -static void network_control_handler(uint16_t snet, BACNET_ADDRESS *src, - BACNET_NPDU_DATA *npdu_data, uint8_t *npdu, - uint16_t npdu_len) +static void network_control_handler(uint16_t snet, + BACNET_ADDRESS *src, + BACNET_NPDU_DATA *npdu_data, + uint8_t *npdu, + uint16_t npdu_len) { uint16_t npdu_offset = 0; uint16_t dnet = 0; @@ -677,8 +658,8 @@ static void network_control_handler(uint16_t snet, BACNET_ADDRESS *src, fprintf(stderr, "Received %s\n", msg_name); switch (npdu_data->network_message_type) { case NETWORK_MESSAGE_WHO_IS_ROUTER_TO_NETWORK: - who_is_router_to_network_handler(snet, src, npdu_data, npdu, - npdu_len); + who_is_router_to_network_handler( + snet, src, npdu_data, npdu, npdu_len); break; case NETWORK_MESSAGE_I_AM_ROUTER_TO_NETWORK: /* add its DNETs to our routing table */ @@ -713,8 +694,8 @@ static void network_control_handler(uint16_t snet, BACNET_ADDRESS *src, fprintf(stderr, "Reason: Network is busy.\n"); break; case 3: - fprintf(stderr, - "Reason: Unknown network message type.\n"); + fprintf( + stderr, "Reason: Unknown network message type.\n"); break; case 4: fprintf(stderr, "Reason: Message too long.\n"); @@ -789,8 +770,8 @@ static void network_control_handler(uint16_t snet, BACNET_ADDRESS *src, * @param snet [in] The source network port where the message came from * @param src [in] The BACNET_ADDRESS of the message's original src. */ -static void routed_src_address(BACNET_ADDRESS *router_src, uint16_t snet, - BACNET_ADDRESS *src) +static void routed_src_address( + BACNET_ADDRESS *router_src, uint16_t snet, BACNET_ADDRESS *src) { unsigned int i = 0; @@ -837,9 +818,12 @@ static void routed_src_address(BACNET_ADDRESS *router_src, uint16_t snet, * @param apdu [in] The apdu portion of the request, to be processed. * @param apdu_len [in] The total (remaining) length of the apdu. */ -static void routed_apdu_handler(uint16_t snet, BACNET_NPDU_DATA *npdu, - BACNET_ADDRESS *src, BACNET_ADDRESS *dest, - uint8_t *apdu, uint16_t apdu_len) +static void routed_apdu_handler(uint16_t snet, + BACNET_NPDU_DATA *npdu, + BACNET_ADDRESS *src, + BACNET_ADDRESS *dest, + uint8_t *apdu, + uint16_t apdu_len) { DNET *port = NULL; BACNET_ADDRESS local_dest; @@ -874,7 +858,7 @@ static void routed_apdu_handler(uint16_t snet, BACNET_NPDU_DATA *npdu, while (port != NULL) { if (port->net != snet) { datalink_send_pdu(port->net, &local_dest, npdu, &Tx_Buffer[0], - npdu_len + apdu_len); + npdu_len + apdu_len); } port = port->next; } @@ -900,10 +884,10 @@ static void routed_apdu_handler(uint16_t snet, BACNET_NPDU_DATA *npdu, npdu_encode_pdu(&Tx_Buffer[0], &local_dest, &router_src, npdu); memmove(&Tx_Buffer[npdu_len], apdu, apdu_len); datalink_send_pdu(port->net, &local_dest, npdu, &Tx_Buffer[0], - npdu_len + apdu_len); + npdu_len + apdu_len); } else { - debug_printf("Routing to another Router %u\n", - (unsigned)remote_dest.net); + debug_printf( + "Routing to another Router %u\n", (unsigned)remote_dest.net); /* Case 2: the message must be relayed to another router for further transmission */ /* In the second case, if the Hop Count is greater than zero, @@ -917,7 +901,7 @@ static void routed_apdu_handler(uint16_t snet, BACNET_NPDU_DATA *npdu, npdu_encode_pdu(&Tx_Buffer[0], &remote_dest, &router_src, npdu); memmove(&Tx_Buffer[npdu_len], apdu, apdu_len); datalink_send_pdu(port->net, &remote_dest, npdu, &Tx_Buffer[0], - npdu_len + apdu_len); + npdu_len + apdu_len); } } else if (dest->net) { debug_printf("Routing to Unknown Route %u\n", (unsigned)dest->net); @@ -928,8 +912,8 @@ static void routed_apdu_handler(uint16_t snet, BACNET_NPDU_DATA *npdu, routed_src_address(&router_src, snet, src); npdu_len = npdu_encode_pdu(&Tx_Buffer[0], dest, &router_src, npdu); memmove(&Tx_Buffer[npdu_len], apdu, apdu_len); - datalink_send_pdu(port->net, dest, npdu, &Tx_Buffer[0], - npdu_len + apdu_len); + datalink_send_pdu( + port->net, dest, npdu, &Tx_Buffer[0], npdu_len + apdu_len); /* If the next router is unknown, an attempt shall be made to identify it using a Who-Is-Router-To-Network message. */ send_who_is_router_to_network(0, dest->net); @@ -951,12 +935,12 @@ static void routed_apdu_handler(uint16_t snet, BACNET_NPDU_DATA *npdu, * @param pdu [in] Buffer containing the NPDU and APDU of the received packet. * @param pdu_len [in] The size of the received message in the pdu[] buffer. */ -static void my_routing_npdu_handler(uint16_t snet, BACNET_ADDRESS *src, - uint8_t *pdu, uint16_t pdu_len) +static void my_routing_npdu_handler( + uint16_t snet, BACNET_ADDRESS *src, uint8_t *pdu, uint16_t pdu_len) { int apdu_offset = 0; - BACNET_ADDRESS dest = {0}; - BACNET_NPDU_DATA npdu_data = {0}; + BACNET_ADDRESS dest = { 0 }; + BACNET_NPDU_DATA npdu_data = { 0 }; if (!pdu) { /* no packet */ @@ -967,8 +951,7 @@ static void my_routing_npdu_handler(uint16_t snet, BACNET_ADDRESS *src, } else if (npdu_data.network_layer_message) { if ((dest.net == 0) || (dest.net == BACNET_BROADCAST_NETWORK)) { network_control_handler(snet, src, &npdu_data, - &pdu[apdu_offset], - (uint16_t)(pdu_len - apdu_offset)); + &pdu[apdu_offset], (uint16_t)(pdu_len - apdu_offset)); } else { /* The DNET is set, but we don't support downstream routers, * so we just silently drop this network layer message, @@ -982,24 +965,23 @@ static void my_routing_npdu_handler(uint16_t snet, BACNET_ADDRESS *src, routing information cause they are not for us */ if ((dest.net == BACNET_BROADCAST_NETWORK) && ((pdu[apdu_offset] & 0xF0) == - PDU_TYPE_CONFIRMED_SERVICE_REQUEST)) { + PDU_TYPE_CONFIRMED_SERVICE_REQUEST)) { /* hack for 5.4.5.1 - IDLE */ /* ConfirmedBroadcastReceived */ /* then enter IDLE - ignore the PDU */ } else { routed_apdu_handler(snet, &npdu_data, src, &dest, - &pdu[apdu_offset], - (uint16_t)(pdu_len - apdu_offset)); + &pdu[apdu_offset], (uint16_t)(pdu_len - apdu_offset)); /* add a Device object and application layer */ if ((dest.net == 0) || (dest.net == BACNET_BROADCAST_NETWORK)) { apdu_handler(src, &pdu[apdu_offset], - (uint16_t)(pdu_len - apdu_offset)); + (uint16_t)(pdu_len - apdu_offset)); } } } else { - fprintf(stderr, "NPDU: DNET=%u. Discarded!\n", - (unsigned)dest.net); + fprintf( + stderr, "NPDU: DNET=%u. Discarded!\n", (unsigned)dest.net); } } } else { @@ -1015,7 +997,7 @@ static void my_routing_npdu_handler(uint16_t snet, BACNET_ADDRESS *src, static void datalink_init(void) { char *pEnv = NULL; - BACNET_ADDRESS my_address = {0}; + BACNET_ADDRESS my_address = { 0 }; extern bool BIP_Debug; /* BACnet/IP Initialization */ @@ -1047,7 +1029,7 @@ static void datalink_init(void) if (pEnv) { BACNET_IP6_ADDRESS addr; bvlc6_address_set(&addr, (uint16_t)strtol(pEnv, NULL, 0), 0, 0, 0, 0, 0, - 0, BIP6_MULTICAST_GROUP_ID); + 0, BIP6_MULTICAST_GROUP_ID); bip6_set_broadcast_addr(&addr); } if (!bip6_init(getenv("BACNET_BIP6_IFACE"))) { @@ -1110,7 +1092,7 @@ static BOOL WINAPI CtrlCHandler(DWORD dwCtrlType) return TRUE; } -void control_c_hooks(void) +static void control_c_hooks(void) { SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), ENABLE_PROCESSED_INPUT); SetConsoleCtrlHandler((PHANDLER_ROUTINE)CtrlCHandler, TRUE); @@ -1123,14 +1105,14 @@ static void sig_int(int signo) exit(0); } -void signal_init(void) +static void signal_init(void) { signal(SIGINT, sig_int); signal(SIGHUP, sig_int); signal(SIGTERM, sig_int); } -void control_c_hooks(void) +static void control_c_hooks(void) { signal_init(); } @@ -1145,7 +1127,7 @@ void control_c_hooks(void) */ int main(int argc, char *argv[]) { - BACNET_ADDRESS src = {0}; /* address where message came from */ + BACNET_ADDRESS src = { 0 }; /* address where message came from */ uint16_t pdu_len = 0; time_t last_seconds = 0; time_t current_seconds = 0; @@ -1179,8 +1161,8 @@ int main(int argc, char *argv[]) /* process */ if (pdu_len) { debug_printf("BACnet/IPv6 Received packet\n"); - my_routing_npdu_handler(BIP6_Net, &src, &BIP6_Rx_Buffer[0], - pdu_len); + my_routing_npdu_handler( + BIP6_Net, &src, &BIP6_Rx_Buffer[0], pdu_len); } /* at least one second has passed */ elapsed_seconds = (uint32_t)(current_seconds - last_seconds); diff --git a/demo/router-ipv6/readme.txt b/apps/router-ipv6/readme.txt similarity index 96% rename from demo/router-ipv6/readme.txt rename to apps/router-ipv6/readme.txt index daab2349..0fdb0121 100644 --- a/demo/router-ipv6/readme.txt +++ b/apps/router-ipv6/readme.txt @@ -1,22 +1,22 @@ -BACnet Simple Router Demo -========================= - -The Simple Router demo connects one BACnet/IP and one BACnet/IPv6 network. -It also includes a BBMD so that Foreign Device Registration can be used -to tunnel local command line demos to BACnet/IP and BACnet IPv6 networks. - -Configuration -============= - -It uses environment variables to configure -the BACnet/IP port and BACnet/IPv6 address on Linux: - -export BACNET_IFACE=eth0 -export BACNET_BIP6_IFACE=eth0 - -Also uses these configurations, but defaults to these values if not set: -export BACNET_IP_PORT=47808 -export BACNET_BIP6_PORT=47808 -export BACNET_BIP6_BROADCAST=FF05 -export BACNET_IP_NET=1 -export BACNET_IP6_NET=2 +BACnet Simple Router Demo +========================= + +The Simple Router demo connects one BACnet/IP and one BACnet/IPv6 network. +It also includes a BBMD so that Foreign Device Registration can be used +to tunnel local command line demos to BACnet/IP and BACnet IPv6 networks. + +Configuration +============= + +It uses environment variables to configure +the BACnet/IP port and BACnet/IPv6 address on Linux: + +export BACNET_IFACE=eth0 +export BACNET_BIP6_IFACE=eth0 + +Also uses these configurations, but defaults to these values if not set: +export BACNET_IP_PORT=47808 +export BACNET_BIP6_PORT=47808 +export BACNET_BIP6_BROADCAST=FF05 +export BACNET_IP_NET=1 +export BACNET_IP6_NET=2 diff --git a/demo/router/Makefile b/apps/router/Makefile similarity index 100% rename from demo/router/Makefile rename to apps/router/Makefile diff --git a/demo/router/init.cfg b/apps/router/init.cfg similarity index 100% rename from demo/router/init.cfg rename to apps/router/init.cfg diff --git a/demo/router/ipmodule.c b/apps/router/ipmodule.c similarity index 84% rename from demo/router/ipmodule.c rename to apps/router/ipmodule.c index 9abab181..d0624f25 100644 --- a/demo/router/ipmodule.c +++ b/apps/router/ipmodule.c @@ -30,17 +30,17 @@ #include #include #include "ipmodule.h" -#include "bacint.h" +#include "bacnet/bacint.h" #ifdef TEST_PACKET -uint8_t test_packet[] = {0x81, 0x0a, 0x00, 0x16, /* BVLC header */ - 0x01, 0x24, 0x00, 0x01, 0x01, 0x0b, 0xff, /* NPDU */ - 0x00, 0x03, 0x01, 0x0c, 0x0c, 0x00, 0x00, - 0x00, 0x02, 0x19, 0x55}; /* APDU */ +uint8_t test_packet[] = { 0x81, 0x0a, 0x00, 0x16, /* BVLC header */ + 0x01, 0x24, 0x00, 0x01, 0x01, 0x0b, 0xff, /* NPDU */ + 0x00, 0x03, 0x01, 0x0c, 0x0c, 0x00, 0x00, 0x00, 0x02, 0x19, + 0x55 }; /* APDU */ #endif -extern int get_local_address_ioctl(char *ifname, struct in_addr *addr, - int request); +extern int get_local_address_ioctl( + char *ifname, struct in_addr *addr, int request); void *dl_ip_thread(void *pArgs) { @@ -49,7 +49,7 @@ void *dl_ip_thread(void *pArgs) MSG_DATA *msg_data; ROUTER_PORT *port = (ROUTER_PORT *)pArgs; IP_DATA ip_data; /* port specific parameters */ - BACNET_ADDRESS address = {0}; + BACNET_ADDRESS address = { 0 }; int status; uint8_t shutdown = 0; @@ -88,11 +88,11 @@ void *dl_ip_thread(void *pArgs) msg_data = (MSG_DATA *)bacmsg->data; memmove(&address.net, &msg_data->dest.net, 2); memmove(&address.mac_len, &msg_data->dest.len, 1); - memmove(&address.mac[0], &msg_data->dest.adr[0], - MAX_MAC_LEN); + memmove( + &address.mac[0], &msg_data->dest.adr[0], MAX_MAC_LEN); - dl_ip_send(&ip_data, &address, msg_data->pdu, - msg_data->pdu_len); + dl_ip_send( + &ip_data, &address, msg_data->pdu, msg_data->pdu_len); check_data(msg_data); @@ -152,28 +152,29 @@ bool dl_ip_init(ROUTER_PORT *port, IP_DATA *ip_data) return false; } /* get broadcast address */ - status = get_local_address_ioctl(port->iface, &ip_data->broadcast_addr, - SIOCGIFBRDADDR); + status = get_local_address_ioctl( + port->iface, &ip_data->broadcast_addr, SIOCGIFBRDADDR); if (status < 0) { return false; } ip_data->socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); - if (ip_data->socket < 0) + if (ip_data->socket < 0) { return false; + } /* setup socket options */ socket_opt = 1; status = setsockopt(ip_data->socket, SOL_SOCKET, SO_REUSEADDR, &socket_opt, - sizeof(socket_opt)); + sizeof(socket_opt)); if (status < 0) { close(ip_data->socket); return false; } status = setsockopt(ip_data->socket, SOL_SOCKET, SO_BROADCAST, &socket_opt, - sizeof(socket_opt)); + sizeof(socket_opt)); if (status < 0) { close(ip_data->socket); return false; @@ -187,7 +188,7 @@ bool dl_ip_init(ROUTER_PORT *port, IP_DATA *ip_data) memset(&sin.sin_zero, '\0', sizeof(sin.sin_zero)); status = bind(ip_data->socket, (const struct sockaddr *)&sin, - sizeof(struct sockaddr)); + sizeof(struct sockaddr)); if (status < 0) { close(ip_data->socket); return false; @@ -200,23 +201,24 @@ bool dl_ip_init(ROUTER_PORT *port, IP_DATA *ip_data) PRINT(INFO, "Interface: %s\n", port->iface); PRINT(INFO, "IP Address: %s\n", inet_ntoa(ip_data->local_addr)); - PRINT(INFO, "IP Broadcast Address: %s\n", - inet_ntoa(ip_data->broadcast_addr)); + PRINT( + INFO, "IP Broadcast Address: %s\n", inet_ntoa(ip_data->broadcast_addr)); PRINT(INFO, "UDP Port: 0x%04X [%hu]\n", (port->params.bip_params.port), - (port->params.bip_params.port)); + (port->params.bip_params.port)); return true; } -int dl_ip_send(IP_DATA *data, BACNET_ADDRESS *dest, uint8_t *pdu, - unsigned pdu_len) +int dl_ip_send( + IP_DATA *data, BACNET_ADDRESS *dest, uint8_t *pdu, unsigned pdu_len) { - struct sockaddr_in bip_dest = {0}; + struct sockaddr_in bip_dest = { 0 }; int buff_len = 0; int bytes_sent = 0; - if (data->socket < 0) + if (data->socket < 0) { return -1; + } data->buff[0] = BVLL_TYPE_BACNET_IP; bip_dest.sin_family = AF_INET; @@ -235,33 +237,34 @@ int dl_ip_send(IP_DATA *data, BACNET_ADDRESS *dest, uint8_t *pdu, } buff_len = 2; - buff_len += encode_unsigned16(&data->buff[buff_len], - (uint16_t)(pdu_len + 4 /*inclusive */)); + buff_len += encode_unsigned16( + &data->buff[buff_len], (uint16_t)(pdu_len + 4 /*inclusive */)); memcpy(&data->buff[buff_len], pdu, pdu_len); buff_len += pdu_len; /* send the packet */ bytes_sent = sendto(data->socket, (char *)data->buff, buff_len, 0, - (struct sockaddr *)&bip_dest, sizeof(struct sockaddr)); + (struct sockaddr *)&bip_dest, sizeof(struct sockaddr)); PRINT(DEBUG, "send to %s\n", inet_ntoa(bip_dest.sin_addr)); return bytes_sent; } -int dl_ip_recv(IP_DATA *data, MSG_DATA **msg_data, BACNET_ADDRESS *src, - unsigned timeout) +int dl_ip_recv( + IP_DATA *data, MSG_DATA **msg_data, BACNET_ADDRESS *src, unsigned timeout) { int received_bytes = 0; uint16_t buff_len = 0; /* return value */ fd_set read_fds; struct timeval select_timeout; - struct sockaddr_in sin = {0}; + struct sockaddr_in sin = { 0 }; socklen_t sin_len = sizeof(sin); /* make sure the socket is open */ - if (data->socket < 0) + if (data->socket < 0) { return 0; + } if (timeout >= 1000) { select_timeout.tv_sec = timeout / 1000; @@ -283,12 +286,12 @@ int dl_ip_recv(IP_DATA *data, MSG_DATA **msg_data, BACNET_ADDRESS *src, #else int ret = select(data->socket + 1, &read_fds, NULL, NULL, &select_timeout); /* see if there is a packet for us */ - if (ret > 0) - received_bytes = - recvfrom(data->socket, (char *)&data->buff[0], data->max_buff, 0, - (struct sockaddr *)&sin, &sin_len); - else + if (ret > 0) { + received_bytes = recvfrom(data->socket, (char *)&data->buff[0], + data->max_buff, 0, (struct sockaddr *)&sin, &sin_len); + } else { return 0; + } #endif PRINT(DEBUG, "received from %s\n", inet_ntoa(sin.sin_addr)); @@ -325,7 +328,7 @@ int dl_ip_recv(IP_DATA *data, MSG_DATA **msg_data, BACNET_ADDRESS *src, (*msg_data)->pdu = (uint8_t *)malloc((*msg_data)->pdu_len); /* fill up data message structure */ memmove(&(*msg_data)->pdu[0], &data->buff[4], - (*msg_data)->pdu_len); + (*msg_data)->pdu_len); memmove(&(*msg_data)->src, src, sizeof(BACNET_ADDRESS)); } /* ignore packets that are too large */ @@ -358,7 +361,7 @@ int dl_ip_recv(IP_DATA *data, MSG_DATA **msg_data, BACNET_ADDRESS *src, (*msg_data)->pdu = (uint8_t *)malloc((*msg_data)->pdu_len); /* fill up data message structure */ memmove(&(*msg_data)->pdu[0], &data->buff[4 + 6], - (*msg_data)->pdu_len); + (*msg_data)->pdu_len); memmove(&(*msg_data)->src, src, sizeof(BACNET_ADDRESS)); } else { /* ignore packets that are too large */ @@ -378,10 +381,12 @@ int dl_ip_recv(IP_DATA *data, MSG_DATA **msg_data, BACNET_ADDRESS *src, void dl_ip_cleanup(IP_DATA *ip_data) { /* free buffer */ - if (ip_data->buff) + if (ip_data->buff) { free(ip_data->buff); + } /* close socket */ - if (ip_data->socket > 0) + if (ip_data->socket > 0) { close(ip_data->socket); + } return; } diff --git a/demo/router/ipmodule.h b/apps/router/ipmodule.h similarity index 98% rename from demo/router/ipmodule.h rename to apps/router/ipmodule.h index 9e6b51c4..699d9a03 100644 --- a/demo/router/ipmodule.h +++ b/apps/router/ipmodule.h @@ -32,7 +32,7 @@ #include #include #include "portthread.h" -#include "bip.h" +#include "bacnet/datalink/bip.h" #define MAX_BIP_APDU 1476 #define MAX_BIP_PDU (MAX_NPDU + MAX_BIP_APDU) diff --git a/demo/router/main.c b/apps/router/main.c similarity index 93% rename from demo/router/main.c rename to apps/router/main.c index 81034a66..073a5eab 100644 --- a/demo/router/main.c +++ b/apps/router/main.c @@ -40,8 +40,8 @@ #include #include #include /* read config files */ -#include /* for getopt */ -#include /* used in kbhit() */ +#include /* for getopt */ +#include /* used in kbhit() */ #include #include #include @@ -103,8 +103,8 @@ int main(int argc, char *argv[]) return -1; } - send_network_message(NETWORK_MESSAGE_I_AM_ROUTER_TO_NETWORK, msg_data, - &buff, NULL); + send_network_message( + NETWORK_MESSAGE_I_AM_ROUTER_TO_NETWORK, msg_data, &buff, NULL); while (true) { if (kbhit()) { @@ -160,7 +160,7 @@ int main(int argc, char *argv[]) msg_data->ref_count = 1; send_to_msgbox(msg_src, &msg_storage); } else if (msg_data->dest.net != - BACNET_BROADCAST_NETWORK) { + BACNET_BROADCAST_NETWORK) { msg_data->ref_count = 1; port = find_dnet(msg_data->dest.net, &msg_data->dest); @@ -232,7 +232,7 @@ bool read_config(char *filepath) /* open configuration file */ if (!config_read_file(&cfg, filepath)) { PRINT(ERROR, "Config file error: %d - %s\n", config_error_line(&cfg), - config_error_text(&cfg)); + config_error_text(&cfg)); config_destroy(&cfg); return false; } @@ -281,13 +281,13 @@ bool read_config(char *filepath) if (fd) { struct ifreq ifr; strncpy(ifr.ifr_name, current->iface, - sizeof(ifr.ifr_name) - 1); + sizeof(ifr.ifr_name) - 1); result = ioctl(fd, SIOCGIFADDR, &ifr); if (result != -1) { close(fd); } else { PRINT(ERROR, - "Error: Invalid interface for BIP device\n"); + "Error: Invalid interface for BIP device\n"); return false; } } @@ -324,7 +324,7 @@ bool read_config(char *filepath) close(fd); } else { PRINT(ERROR, - "Error: Invalid interface for MSTP device\n"); + "Error: Invalid interface for MSTP device\n"); return false; } } else { @@ -338,15 +338,15 @@ bool read_config(char *filepath) current->route_info.mac[0] = 127; current->route_info.mac_len = 1; } - result = config_setting_lookup_int(port, "max_master", - (int *)¶m); + result = config_setting_lookup_int( + port, "max_master", (int *)¶m); if (result) { current->params.mstp_params.max_master = param; } else { current->params.mstp_params.max_master = 127; } - result = config_setting_lookup_int(port, "max_frames", - (int *)¶m); + result = config_setting_lookup_int( + port, "max_frames", (int *)¶m); if (result) { current->params.mstp_params.max_frames = param; } else { @@ -418,17 +418,17 @@ bool parse_cmd(int argc, char *argv[]) const char *bipString = "p:n:D:"; const char *mstpString = "m:b:p:d:s:n:D:"; const struct option Options[] = { - {"config", required_argument, NULL, 'c'}, - {"device", required_argument, NULL, 'D'}, - {"network", required_argument, NULL, 'n'}, - {"port", required_argument, NULL, 'P'}, - {"mac", required_argument, NULL, 'm'}, - {"baud", required_argument, NULL, 'b'}, - {"parity", required_argument, NULL, 'p'}, - {"databits", required_argument, NULL, 'd'}, - {"stopbits", required_argument, NULL, 's'}, - {"help", no_argument, NULL, 'h'}, - {NULL, no_argument, NULL, 0}, + { "config", required_argument, NULL, 'c' }, + { "device", required_argument, NULL, 'D' }, + { "network", required_argument, NULL, 'n' }, + { "port", required_argument, NULL, 'P' }, + { "mac", required_argument, NULL, 'm' }, + { "baud", required_argument, NULL, 'b' }, + { "parity", required_argument, NULL, 'p' }, + { "databits", required_argument, NULL, 'd' }, + { "stopbits", required_argument, NULL, 's' }, + { "help", no_argument, NULL, 'h' }, + { NULL, no_argument, NULL, 0 }, }; int opt, dev_opt, index, result, fd; @@ -485,13 +485,13 @@ bool parse_cmd(int argc, char *argv[]) if (fd) { struct ifreq ifr; strncpy(ifr.ifr_name, current->iface, - sizeof(ifr.ifr_name) - 1); + sizeof(ifr.ifr_name) - 1); result = ioctl(fd, SIOCGIFADDR, &ifr); if (result != -1) { close(fd); } else { PRINT(ERROR, - "Error: Invalid interface for BIP device \n"); + "Error: Invalid interface for BIP device \n"); return false; } } @@ -538,7 +538,7 @@ bool parse_cmd(int argc, char *argv[]) close(fd); } else { PRINT(ERROR, - "Error: Invalid interface for MSTP device\n"); + "Error: Invalid interface for MSTP device\n"); return false; } @@ -621,8 +621,8 @@ bool parse_cmd(int argc, char *argv[]) } break; } - dev_opt = getopt_long(argc, argv, mstpString, Options, - &index); + dev_opt = getopt_long( + argc, argv, mstpString, Options, &index); } opt = dev_opt; } else { @@ -666,8 +666,9 @@ bool init_router() ROUTER_PORT *port; msgboxid = create_msgbox(); - if (msgboxid == INVALID_MSGBOX_ID) + if (msgboxid == INVALID_MSGBOX_ID) { return false; + } port = head; /* add main message box id to all ports */ @@ -702,8 +703,9 @@ void cleanup() ROUTER_PORT *port; BACMSG msg; - if (head == NULL) + if (head == NULL) { return; + } msg.origin = head->main_id; msg.type = SERVICE; @@ -714,8 +716,9 @@ void cleanup() /* send shutdown message to all router ports */ port = head; while (port != NULL) { - if (port->state == RUNNING) + if (port->state == RUNNING) { send_to_msgbox(port->port_id, &msg); + } port = port->next; } @@ -741,8 +744,9 @@ void print_msg(BACMSG *msg) if (data->pdu_len) { PRINT(DEBUG, "Message PDU: "); - for (i = 0; i < data->pdu_len; i++) + for (i = 0; i < data->pdu_len; i++) { PRINT(DEBUG, "%02X ", data->pdu[i]); + } PRINT(DEBUG, "\n"); } } @@ -793,7 +797,7 @@ uint16_t process_msg(BACMSG *msg, MSG_DATA *data, uint8_t **buff) *buff = (uint8_t *)malloc(buff_len); memmove(*buff, npdu, npdu_len); /* copy newly formed NPDU */ memmove(*buff + npdu_len, &data->pdu[apdu_offset], - apdu_len); /* copy APDU */ + apdu_len); /* copy APDU */ } else { /* request net search */ diff --git a/demo/router/msgqueue.c b/apps/router/msgqueue.c similarity index 97% rename from demo/router/msgqueue.c rename to apps/router/msgqueue.c index ed460176..213dd2e0 100644 --- a/demo/router/msgqueue.c +++ b/apps/router/msgqueue.c @@ -73,10 +73,11 @@ BACMSG *recv_from_msgbox(MSGBOX_ID src, BACMSG *msg) void del_msgbox(MSGBOX_ID msgboxid) { - if (msgboxid == INVALID_MSGBOX_ID) + if (msgboxid == INVALID_MSGBOX_ID) { return; - else + } else { msgctl(msgboxid, IPC_RMID, NULL); + } } void free_data(MSG_DATA *data) diff --git a/demo/router/msgqueue.h b/apps/router/msgqueue.h similarity index 97% rename from demo/router/msgqueue.h rename to apps/router/msgqueue.h index 533e5fe5..3252aecb 100644 --- a/demo/router/msgqueue.h +++ b/apps/router/msgqueue.h @@ -34,8 +34,8 @@ #include #include #include -#include "bacdef.h" -#include "npdu.h" +#include "bacnet/bacdef.h" +#include "bacnet/npdu.h" extern pthread_mutex_t msg_lock; diff --git a/demo/router/mstpmodule.c b/apps/router/mstpmodule.c similarity index 93% rename from demo/router/mstpmodule.c rename to apps/router/mstpmodule.c index 9c36e5e7..8407d75d 100644 --- a/demo/router/mstpmodule.c +++ b/apps/router/mstpmodule.c @@ -30,7 +30,7 @@ #include #include #include "mstpmodule.h" -#include "bacint.h" +#include "bacnet/bacint.h" #include "dlmstp_linux.h" #include @@ -44,8 +44,8 @@ void *dl_mstp_thread(void *pArgs) { ROUTER_PORT *port = (ROUTER_PORT *)pArgs; - struct mstp_port_struct_t mstp_port = {(MSTP_RECEIVE_STATE)0}; - volatile SHARED_MSTP_DATA shared_port_data = {0}; + struct mstp_port_struct_t mstp_port = { (MSTP_RECEIVE_STATE)0 }; + volatile SHARED_MSTP_DATA shared_port_data = { 0 }; uint16_t pdu_len; uint8_t shutdown = 0; @@ -121,7 +121,7 @@ void *dl_mstp_thread(void *pArgs) } dlmstp_send_pdu(&mstp_port, &(msg_data->dest), - msg_data->pdu, msg_data->pdu_len); + msg_data->pdu, msg_data->pdu_len); check_data(msg_data); @@ -144,16 +144,15 @@ void *dl_mstp_thread(void *pArgs) if (pdu_len > 0) { msg_data = (MSG_DATA *)malloc(sizeof(MSG_DATA)); - memmove( - &(msg_data->src), + memmove(&(msg_data->src), (const void *)&(shared_port_data.Receive_Packet.address), sizeof(shared_port_data.Receive_Packet.address)); msg_data->src.adr[0] = msg_data->src.mac[0]; msg_data->src.len = 1; msg_data->pdu = (uint8_t *)malloc(pdu_len); memmove(msg_data->pdu, - (const void *)&(shared_port_data.Receive_Packet.pdu), - pdu_len); + (const void *)&(shared_port_data.Receive_Packet.pdu), + pdu_len); msg_data->pdu_len = pdu_len; msg_storage.type = DATA; diff --git a/demo/router/mstpmodule.h b/apps/router/mstpmodule.h similarity index 100% rename from demo/router/mstpmodule.h rename to apps/router/mstpmodule.h diff --git a/demo/router/network_layer.c b/apps/router/network_layer.c similarity index 91% rename from demo/router/network_layer.c rename to apps/router/network_layer.c index 57f1ccc5..292ad52f 100644 --- a/demo/router/network_layer.c +++ b/apps/router/network_layer.c @@ -30,7 +30,7 @@ #include #include #include "network_layer.h" -#include "bacint.h" +#include "bacnet/bacint.h" uint16_t process_network_message(BACMSG *msg, MSG_DATA *data, uint8_t **buff) { @@ -88,9 +88,9 @@ uint16_t process_network_message(BACMSG *msg, MSG_DATA *data, uint8_t **buff) int i; for (i = 0; i < net_count; i++) { decode_unsigned16(&data->pdu[apdu_offset + 2 * i], - &net); /* decode received NET values */ + &net); /* decode received NET values */ add_dnet(&srcport->route_info, net, - data->src); /* and update routing table */ + data->src); /* and update routing table */ } break; } @@ -125,9 +125,9 @@ uint16_t process_network_message(BACMSG *msg, MSG_DATA *data, uint8_t **buff) while (net_count--) { int i = 1; decode_unsigned16(&data->pdu[apdu_offset + i], - &net); /* decode received NET values */ + &net); /* decode received NET values */ add_dnet(&srcport->route_info, net, - data->src); /* and update routing table */ + data->src); /* and update routing table */ if (data->pdu[apdu_offset + i + 3] > 0) /* find next NET value */ i = data->pdu[apdu_offset + i + 3] + 4; @@ -148,9 +148,9 @@ uint16_t process_network_message(BACMSG *msg, MSG_DATA *data, uint8_t **buff) while (net_count--) { int i = 1; decode_unsigned16(&data->pdu[apdu_offset + i], - &net); /* decode received NET values */ + &net); /* decode received NET values */ add_dnet(&srcport->route_info, net, - data->src); /* and update routing table */ + data->src); /* and update routing table */ if (data->pdu[apdu_offset + i + 3] > 0) /* find next NET value */ i = data->pdu[apdu_offset + i + 3] + 4; @@ -180,8 +180,8 @@ uint16_t process_network_message(BACMSG *msg, MSG_DATA *data, uint8_t **buff) /* security messages */ break; case NETWORK_MESSAGE_WHAT_IS_NETWORK_NUMBER: - buff_len = create_network_message(NETWORK_MESSAGE_NETWORK_NUMBER_IS, - data, buff, &buff); + buff_len = create_network_message( + NETWORK_MESSAGE_NETWORK_NUMBER_IS, data, buff, &buff); break; default: @@ -193,8 +193,10 @@ uint16_t process_network_message(BACMSG *msg, MSG_DATA *data, uint8_t **buff) } uint16_t create_network_message( - BACNET_NETWORK_MESSAGE_TYPE network_message_type, MSG_DATA *data, - uint8_t **buff, void *val) + BACNET_NETWORK_MESSAGE_TYPE network_message_type, + MSG_DATA *data, + uint8_t **buff, + void *val) { int16_t buff_len; bool data_expecting_reply = false; @@ -229,8 +231,8 @@ uint16_t create_network_message( DNET *dnet; while (port != NULL) { if (port->route_info.net != data->src.net) { - buff_len += encode_unsigned16(*buff + buff_len, - port->route_info.net); + buff_len += encode_unsigned16( + *buff + buff_len, port->route_info.net); dnet = port->route_info.dnets; while (dnet != NULL) { buff_len += @@ -267,8 +269,8 @@ uint16_t create_network_message( uint8_t portID = 1; while (port != NULL) { - buff_len += encode_unsigned16(*buff + buff_len, - port->route_info.net); + buff_len += encode_unsigned16( + *buff + buff_len, port->route_info.net); (*buff)[buff_len++] = portID++; (*buff)[buff_len++] = 0; port = port->next; @@ -307,7 +309,9 @@ uint16_t create_network_message( } void send_network_message(BACNET_NETWORK_MESSAGE_TYPE network_message_type, - MSG_DATA *data, uint8_t **buff, void *val) + MSG_DATA *data, + uint8_t **buff, + void *val) { BACMSG msg; ROUTER_PORT *port = head; @@ -340,8 +344,8 @@ void send_network_message(BACNET_NETWORK_MESSAGE_TYPE network_message_type, } void init_npdu(BACNET_NPDU_DATA *npdu_data, - BACNET_NETWORK_MESSAGE_TYPE network_message_type, - bool data_expecting_reply) + BACNET_NETWORK_MESSAGE_TYPE network_message_type, + bool data_expecting_reply) { if (npdu_data) { npdu_data->data_expecting_reply = data_expecting_reply; diff --git a/demo/router/network_layer.h b/apps/router/network_layer.h similarity index 95% rename from demo/router/network_layer.h rename to apps/router/network_layer.h index 9f0b0893..6a976bb6 100644 --- a/demo/router/network_layer.h +++ b/apps/router/network_layer.h @@ -34,10 +34,10 @@ #include #include #include -#include "bacenum.h" -#include "bacdef.h" -#include "npdu.h" -#include "net.h" +#include "bacnet/bacenum.h" +#include "bacnet/bacdef.h" +#include "bacnet/npdu.h" +#include "bacport.h" #include "portthread.h" uint16_t process_network_message( diff --git a/demo/router/portthread.c b/apps/router/portthread.c similarity index 96% rename from demo/router/portthread.c rename to apps/router/portthread.c index a51e0cb1..ae681115 100644 --- a/demo/router/portthread.c +++ b/apps/router/portthread.c @@ -36,8 +36,9 @@ ROUTER_PORT *find_snet(MSGBOX_ID id) ROUTER_PORT *port = head; while (port != NULL) { - if (port->port_id == id) + if (port->port_id == id) { return port; + } port = port->next; } @@ -92,8 +93,9 @@ void add_dnet(RT_ENTRY *route_info, uint16_t net, BACNET_ADDRESS addr) route_info->dnets->next = NULL; } else { while (dnet != NULL) { - if (dnet->net == net) /* make sure NETs are not repeated */ + if (dnet->net == net) { /* make sure NETs are not repeated */ return; + } tmp = dnet; dnet = dnet->next; } diff --git a/demo/router/portthread.h b/apps/router/portthread.h similarity index 98% rename from demo/router/portthread.h rename to apps/router/portthread.h index 9e12a5c9..771cea58 100644 --- a/demo/router/portthread.h +++ b/apps/router/portthread.h @@ -33,8 +33,8 @@ #include #include #include "msgqueue.h" -#include "bacdef.h" -#include "npdu.h" +#include "bacnet/bacdef.h" +#include "bacnet/npdu.h" #define ERROR 1 #define INFO 2 diff --git a/demo/router/readme.txt b/apps/router/readme.txt similarity index 100% rename from demo/router/readme.txt rename to apps/router/readme.txt diff --git a/apps/scov/Makefile b/apps/scov/Makefile new file mode 100644 index 00000000..0a8392f9 --- /dev/null +++ b/apps/scov/Makefile @@ -0,0 +1,51 @@ +#Makefile to build BACnet Application using GCC compiler + +# Executable file name +TARGET = bacscov +# BACnet objects that are used with this app +BACNET_OBJECT_DIR = $(BACNET_SRC_DIR)/bacnet/basic/object +SRC = main.c \ + $(BACNET_OBJECT_DIR)/client/device-client.c \ + $(BACNET_OBJECT_DIR)/netport.c +BACNET_BASIC_SRC += \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_apdu.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_ccov.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_ucov.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_iam.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_noserv.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_rp.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_whois.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/s_cov.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/s_iam.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/s_whois.c + +# TARGET_EXT is defined in apps/Makefile as .exe or nothing +TARGET_BIN = ${TARGET}$(TARGET_EXT) + +SRCS = $(SRC) $(BACNET_SRC) $(BACNET_BASIC_SRC) $(BACNET_PORT_SRC) + +OBJS += ${SRCS:.c=.o} + +.PHONY: all +all: Makefile ${TARGET_BIN} + +${TARGET_BIN}: ${OBJS} + ${CC} ${PFLAGS} ${OBJS} ${LFLAGS} -o $@ + size $@ + cp $@ ../../bin + +.c.o: + ${CC} -c ${CFLAGS} $*.c -o $@ + +.PHONY: depend +depend: + rm -f .depend + ${CC} -MM ${CFLAGS} *.c >> .depend + +.PHONY: clean +clean: + rm -f core ${TARGET_BIN} ${OBJS} $(TARGET).map + +.PHONY: include +include: .depend + diff --git a/demo/scov/main.c b/apps/scov/main.c similarity index 70% rename from demo/scov/main.c rename to apps/scov/main.c index a5505e5b..7e36470f 100644 --- a/demo/scov/main.c +++ b/apps/scov/main.c @@ -28,34 +28,34 @@ #include #include #include -#include /* for time */ +#include /* for time */ #include /* for toupper */ #define PRINT_ENABLED 1 -#include "bacdef.h" -#include "config.h" -#include "bactext.h" -#include "bacerror.h" -#include "iam.h" -#include "arf.h" -#include "tsm.h" -#include "address.h" -#include "npdu.h" -#include "apdu.h" -#include "device.h" -#include "net.h" -#include "datalink.h" -#include "whois.h" +#include "bacnet/bacdef.h" +#include "bacnet/config.h" +#include "bacnet/bactext.h" +#include "bacnet/bacerror.h" +#include "bacnet/iam.h" +#include "bacnet/arf.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/basic/binding/address.h" +#include "bacnet/npdu.h" +#include "bacnet/apdu.h" +#include "bacnet/basic/object/device.h" +#include "bacport.h" +#include "bacnet/datalink/datalink.h" +#include "bacnet/whois.h" /* some demo stuff needed */ -#include "filename.h" -#include "handlers.h" -#include "client.h" -#include "txbuf.h" -#include "dlenv.h" +#include "bacnet/basic/sys/filename.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/datalink/dlenv.h" /* buffer used for receive */ -static uint8_t Rx_Buf[MAX_MPDU] = {0}; +static uint8_t Rx_Buf[MAX_MPDU] = { 0 }; /* converted command line arguments */ static uint32_t Target_Device_Object_Instance = BACNET_MAX_INSTANCE; @@ -73,57 +73,59 @@ BACNET_SUBSCRIBE_COV_DATA *COV_Subscribe_Data = NULL; static bool Simple_Ack_Detected = false; static bool Cancel_Requested = false; -static void MyErrorHandler(BACNET_ADDRESS *src, uint8_t invoke_id, - BACNET_ERROR_CLASS error_class, - BACNET_ERROR_CODE error_code) +static void MyErrorHandler(BACNET_ADDRESS *src, + uint8_t invoke_id, + BACNET_ERROR_CLASS error_class, + BACNET_ERROR_CODE error_code) { if (address_match(&Target_Address, src) && (invoke_id == Request_Invoke_ID)) { printf("BACnet Error: %s: %s\r\n", - bactext_error_class_name((int)error_class), - bactext_error_code_name((int)error_code)); + bactext_error_class_name((int)error_class), + bactext_error_code_name((int)error_code)); Error_Detected = true; } } -void MyAbortHandler(BACNET_ADDRESS *src, uint8_t invoke_id, - uint8_t abort_reason, bool server) +static void MyAbortHandler( + BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t abort_reason, bool server) { (void)server; if (address_match(&Target_Address, src) && (invoke_id == Request_Invoke_ID)) { printf("BACnet Abort: %s\r\n", - bactext_abort_reason_name((int)abort_reason)); + bactext_abort_reason_name((int)abort_reason)); Error_Detected = true; } } -void MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, - uint8_t reject_reason) +static void MyRejectHandler( + BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason) { if (address_match(&Target_Address, src) && (invoke_id == Request_Invoke_ID)) { printf("BACnet Reject: %s\r\n", - bactext_reject_reason_name((int)reject_reason)); + bactext_reject_reason_name((int)reject_reason)); Error_Detected = true; } } -void My_Unconfirmed_COV_Notification_Handler(uint8_t *service_request, - uint16_t service_len, - BACNET_ADDRESS *src) +static void My_Unconfirmed_COV_Notification_Handler( + uint8_t *service_request, uint16_t service_len, BACNET_ADDRESS *src) { handler_ucov_notification(service_request, service_len, src); } -void My_Confirmed_COV_Notification_Handler( - uint8_t *service_request, uint16_t service_len, BACNET_ADDRESS *src, +static void My_Confirmed_COV_Notification_Handler(uint8_t *service_request, + uint16_t service_len, + BACNET_ADDRESS *src, BACNET_CONFIRMED_SERVICE_DATA *service_data) { handler_ccov_notification(service_request, service_len, src, service_data); } -void MyWritePropertySimpleAckHandler(BACNET_ADDRESS *src, uint8_t invoke_id) +static void MyWritePropertySimpleAckHandler( + BACNET_ADDRESS *src, uint8_t invoke_id) { if (address_match(&Target_Address, src) && (invoke_id == Request_Invoke_ID)) { @@ -144,23 +146,23 @@ static void Init_Service_Handlers(void) It is required to send the proper reject message... */ apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service); /* we must implement read property - it's required! */ - apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY, - handler_read_property); + apdu_set_confirmed_handler( + SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property); /* handle the data coming back from COV subscriptions */ apdu_set_confirmed_handler(SERVICE_CONFIRMED_COV_NOTIFICATION, - My_Confirmed_COV_Notification_Handler); + My_Confirmed_COV_Notification_Handler); apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_COV_NOTIFICATION, - My_Unconfirmed_COV_Notification_Handler); + My_Unconfirmed_COV_Notification_Handler); /* handle the Simple ack coming back from SubscribeCOV */ - apdu_set_confirmed_simple_ack_handler(SERVICE_CONFIRMED_SUBSCRIBE_COV, - MyWritePropertySimpleAckHandler); + apdu_set_confirmed_simple_ack_handler( + SERVICE_CONFIRMED_SUBSCRIBE_COV, MyWritePropertySimpleAckHandler); /* handle any errors coming back */ apdu_set_error_handler(SERVICE_CONFIRMED_SUBSCRIBE_COV, MyErrorHandler); apdu_set_abort_handler(MyAbortHandler); apdu_set_reject_handler(MyRejectHandler); } -void cleanup(void) +static void cleanup(void) { BACNET_SUBSCRIBE_COV_DATA *cov_data = NULL; BACNET_SUBSCRIBE_COV_DATA *cov_data_old = NULL; @@ -175,7 +177,7 @@ void cleanup(void) int main(int argc, char *argv[]) { - BACNET_ADDRESS src = {0}; /* address where message came from */ + BACNET_ADDRESS src = { 0 }; /* address where message came from */ uint16_t pdu_len = 0; unsigned timeout = 100; /* milliseconds */ unsigned max_apdu = 0; @@ -201,54 +203,52 @@ int main(int argc, char *argv[]) } if (print_usage_terse) { filename = filename_remove_path(argv[0]); - printf( - "Usage: %s device-id object-type object-instance " - "process-id <[un]confirmed lifetime|cancel>\r\n", + printf("Usage: %s device-id object-type object-instance " + "process-id <[un]confirmed lifetime|cancel>\r\n", filename); if (!print_usage_verbose) { return 0; } } if (print_usage_verbose) { - printf( - "\r\n" - "device-id:\r\n" - "The subscriber BACnet Device Object Instance number.\r\n" - "\r\n" - "object-type:\r\n" - "The monitored object type is the integer value of the\r\n" - "enumeration BACNET_OBJECT_TYPE in bacenum.h. For example,\r\n" - "if you were monitoring Analog Output 2, the object-type\r\n" - "would be 1.\r\n" - "\r\n" - "object-instance:\r\n" - "The monitored object instance number.\r\n" - "\r\n" - "process-id:\r\n" - "Process Identifier for this COV subscription.\r\n" - "\r\n" - "confirmed:\r\n" - "Optional flag to subscribe using Confirmed notifications.\r\n" - "Use the word \'confirmed\' or \'unconfirmed\'.\r\n" - "\r\n" - "lifetime:\r\n" - "Optional subscription lifetime is conveyed in seconds.\r\n" - "\r\n" - "cancel:\r\n" - "Use the word \'cancel\' instead of confirm and lifetime.\r\n" - "This shall indicate a cancellation request.\r\n" - "\r\n" - "Example:\r\n" - "If you want subscribe to Device 123 Analog Input 9 object\r\n" - "using confirmed COV notifications for 5 minutes,\r\n" - "you could send the following command:\r\n" - "%s 123 0 9 1 confirmed 600\r\n" - "To send the same COV subscription request for unconfirmed\r\n" - "notifications, send the following command:\r\n" - "%s 123 0 9 1 unconfirmed 600\r\n" - "To cancel the same COV subscription request,\r\n" - "send the following command:\r\n" - "%s 123 0 9 1 cancel\r\n", + printf("\r\n" + "device-id:\r\n" + "The subscriber BACnet Device Object Instance number.\r\n" + "\r\n" + "object-type:\r\n" + "The monitored object type is the integer value of the\r\n" + "enumeration BACNET_OBJECT_TYPE in bacenum.h. For example,\r\n" + "if you were monitoring Analog Output 2, the object-type\r\n" + "would be 1.\r\n" + "\r\n" + "object-instance:\r\n" + "The monitored object instance number.\r\n" + "\r\n" + "process-id:\r\n" + "Process Identifier for this COV subscription.\r\n" + "\r\n" + "confirmed:\r\n" + "Optional flag to subscribe using Confirmed notifications.\r\n" + "Use the word \'confirmed\' or \'unconfirmed\'.\r\n" + "\r\n" + "lifetime:\r\n" + "Optional subscription lifetime is conveyed in seconds.\r\n" + "\r\n" + "cancel:\r\n" + "Use the word \'cancel\' instead of confirm and lifetime.\r\n" + "This shall indicate a cancellation request.\r\n" + "\r\n" + "Example:\r\n" + "If you want subscribe to Device 123 Analog Input 9 object\r\n" + "using confirmed COV notifications for 5 minutes,\r\n" + "you could send the following command:\r\n" + "%s 123 0 9 1 confirmed 600\r\n" + "To send the same COV subscription request for unconfirmed\r\n" + "notifications, send the following command:\r\n" + "%s 123 0 9 1 unconfirmed 600\r\n" + "To cancel the same COV subscription request,\r\n" + "send the following command:\r\n" + "%s 123 0 9 1 cancel\r\n", filename, filename, filename); return 0; } @@ -256,7 +256,7 @@ int main(int argc, char *argv[]) Target_Device_Object_Instance = strtol(argv[1], NULL, 0); if (Target_Device_Object_Instance >= BACNET_MAX_INSTANCE) { fprintf(stderr, "device-instance=%u - it must be less than %u\r\n", - Target_Device_Object_Instance, BACNET_MAX_INSTANCE); + Target_Device_Object_Instance, BACNET_MAX_INSTANCE); return 1; } atexit(cleanup); @@ -268,8 +268,8 @@ int main(int argc, char *argv[]) if (cov_data->monitoredObjectIdentifier.type >= MAX_BACNET_OBJECT_TYPE) { fprintf(stderr, "object-type=%u - it must be less than %u\r\n", - cov_data->monitoredObjectIdentifier.type, - MAX_BACNET_OBJECT_TYPE); + cov_data->monitoredObjectIdentifier.type, + MAX_BACNET_OBJECT_TYPE); return 1; } argi++; @@ -278,8 +278,8 @@ int main(int argc, char *argv[]) if (cov_data->monitoredObjectIdentifier.instance > BACNET_MAX_INSTANCE) { fprintf(stderr, "object-instance=%u - it must be less than %u\r\n", - cov_data->monitoredObjectIdentifier.instance, - BACNET_MAX_INSTANCE + 1); + cov_data->monitoredObjectIdentifier.instance, + BACNET_MAX_INSTANCE + 1); return 1; } argi++; @@ -325,11 +325,11 @@ int main(int argc, char *argv[]) last_seconds = time(NULL); timeout_seconds = (apdu_timeout() / 1000) * apdu_retries(); /* try to bind with the device */ - found = address_bind_request(Target_Device_Object_Instance, &max_apdu, - &Target_Address); + found = address_bind_request( + Target_Device_Object_Instance, &max_apdu, &Target_Address); if (!found) { - Send_WhoIs(Target_Device_Object_Instance, - Target_Device_Object_Instance); + Send_WhoIs( + Target_Device_Object_Instance, Target_Device_Object_Instance); } /* start at the beginning of the subscribe list */ cov_data = COV_Subscribe_Data; @@ -351,8 +351,8 @@ int main(int argc, char *argv[]) } /* wait until the device is bound, or timeout and quit */ if (!found) { - found = address_bind_request(Target_Device_Object_Instance, - &max_apdu, &Target_Address); + found = address_bind_request( + Target_Device_Object_Instance, &max_apdu, &Target_Address); } if (found) { if (Request_Invoke_ID == 0) { @@ -371,9 +371,8 @@ int main(int argc, char *argv[]) /* increase the timeout to the longest lifetime */ timeout_seconds = cov_data->lifetime; } - printf( - "Sent SubscribeCOV request. " - " Waiting up to %u seconds....\r\n", + printf("Sent SubscribeCOV request. " + " Waiting up to %u seconds....\r\n", (unsigned)(timeout_seconds - elapsed_seconds)); } else if (tsm_invoke_id_free(Request_Invoke_ID)) { if (cov_data->next) { diff --git a/demo/server/.gdbinit b/apps/server/.gdbinit similarity index 100% rename from demo/server/.gdbinit rename to apps/server/.gdbinit diff --git a/apps/server/Makefile b/apps/server/Makefile new file mode 100644 index 00000000..6107727a --- /dev/null +++ b/apps/server/Makefile @@ -0,0 +1,71 @@ +#Makefile to build BACnet Application for the GCC port + +# Executable file name +TARGET = bacserv +BACNET_OBJECT_DIR = $(BACNET_SRC_DIR)/bacnet/basic/object +SRC = main.c \ + $(BACNET_OBJECT_DIR)/device.c \ + $(BACNET_OBJECT_DIR)/ai.c \ + $(BACNET_OBJECT_DIR)/ao.c \ + $(BACNET_OBJECT_DIR)/av.c \ + $(BACNET_OBJECT_DIR)/bi.c \ + $(BACNET_OBJECT_DIR)/bo.c \ + $(BACNET_OBJECT_DIR)/bv.c \ + $(BACNET_OBJECT_DIR)/channel.c \ + $(BACNET_OBJECT_DIR)/command.c \ + $(BACNET_OBJECT_DIR)/csv.c \ + $(BACNET_OBJECT_DIR)/iv.c \ + $(BACNET_OBJECT_DIR)/lc.c \ + $(BACNET_OBJECT_DIR)/lo.c \ + $(BACNET_OBJECT_DIR)/lsp.c \ + $(BACNET_OBJECT_DIR)/ms-input.c \ + $(BACNET_OBJECT_DIR)/mso.c \ + $(BACNET_OBJECT_DIR)/msv.c \ + $(BACNET_OBJECT_DIR)/osv.c \ + $(BACNET_OBJECT_DIR)/piv.c \ + $(BACNET_OBJECT_DIR)/nc.c \ + $(BACNET_OBJECT_DIR)/netport.c \ + $(BACNET_OBJECT_DIR)/trendlog.c \ + $(BACNET_OBJECT_DIR)/schedule.c \ + $(BACNET_OBJECT_DIR)/access_credential.c \ + $(BACNET_OBJECT_DIR)/access_door.c \ + $(BACNET_OBJECT_DIR)/access_point.c \ + $(BACNET_OBJECT_DIR)/access_rights.c \ + $(BACNET_OBJECT_DIR)/access_user.c \ + $(BACNET_OBJECT_DIR)/access_zone.c \ + $(BACNET_OBJECT_DIR)/credential_data_input.c \ + $(BACNET_OBJECT_DIR)/bacfile.c + +BACNET_BASIC_SRC += \ + $(wildcard $(BACNET_SRC_DIR)/bacnet/basic/service/*.c) \ + +# TARGET_EXT is defined in apps/Makefile as .exe or nothing +TARGET_BIN = ${TARGET}$(TARGET_EXT) + +SRCS = $(SRC) $(BACNET_SRC) $(BACNET_BASIC_SRC) $(BACNET_PORT_SRC) + +OBJS += ${SRCS:.c=.o} + +.PHONY: all +all: Makefile ${TARGET_BIN} + +${TARGET_BIN}: ${OBJS} + ${CC} ${PFLAGS} ${OBJS} ${LFLAGS} -o $@ + size $@ + cp $@ ../../bin + +.c.o: + ${CC} -c ${CFLAGS} $*.c -o $@ + +.PHONY: depend +depend: + rm -f .depend + ${CC} -MM ${CFLAGS} *.c >> .depend + +.PHONY: clean +clean: + rm -f core ${TARGET_BIN} ${OBJS} $(TARGET).map + +.PHONY: include +include: .depend + diff --git a/demo/server/PICS.odt b/apps/server/PICS.odt similarity index 100% rename from demo/server/PICS.odt rename to apps/server/PICS.odt diff --git a/apps/server/bacserv-linux.cbp b/apps/server/bacserv-linux.cbp new file mode 100644 index 00000000..4b0997c6 --- /dev/null +++ b/apps/server/bacserv-linux.cbp @@ -0,0 +1,673 @@ + + + + + + diff --git a/apps/server/bacserv-windows.cbp b/apps/server/bacserv-windows.cbp new file mode 100644 index 00000000..68f56b6e --- /dev/null +++ b/apps/server/bacserv-windows.cbp @@ -0,0 +1,676 @@ + + + + + + diff --git a/apps/server/bin/Debug/bacserv b/apps/server/bin/Debug/bacserv new file mode 100755 index 0000000000000000000000000000000000000000..643cdee19ca6ce781a6725107004e9a395ebd87f GIT binary patch literal 2160360 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

Z@bj(x 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�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

{Zo!o=Y;JlBU7UcN4EImEDL3HNhT?c1R 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�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�iecz{R1PI@!YcsU@K3y+@@O`>AK+N~)x*3G;(?!Df=_29#bdm6Vy1oYC z`*hK^&7M!!>!@dIOGhp?(l~N4X&FZ@HrI3HqLM5)xt$7L%-#(uo#RilGa8W~m!m1% zPdsi5M=tU`M=nVlM=qvg_GT!FW@0b0`6Z5A_Db3yj$HOCNz#$aUM)#FawX@|uyhv% zCgKl{Tq9YQj$Fy@$ob9rHJs}y?GDVu?}-V|t%T=R!gDL(xy5JI#Q8Oe^J@~GTixKP zG6><+l)JtNkA`rw!E;VOID6o!pg){-`r`&lxr^~{pmNuB!!wI=CnIkVJY!I9sB-ro zX<5VILsN&lEBMnDSk?%*TlC-&8URu7N$+Y zb1UJw74+On$qq4+13W(DmOn2<*DU8HKF&JJ<+~4_N|n?73V#2z5oN8`x1EEhgW}K( zh6pWaozzI7O@f~r>rsL7nshvbmpyTkyCg$98 zFrGu5C6n=->D-F%6z9eR0NrtRfuH7_J01_E&WfpcICdUII@5XMKs@?7!;u?zo`lY9 z=PBsPaoz;SacZXlQ0gp3x|P!l@~xe9sH=^$0;SqIM?iC~b0Vy2=X8h8_Rd?7@8Il# zwH=+G_s1_fP8Dp(cXpvvfj_@qi7sc;{+rVcWX?`ZdWB+t)aeE(Gm==XH_2xw^=Jj{ z36G~`7yL7vN_?+$w&T~2RnBS1UG4Tq z+JZlHIxlZl>s4T;w28fsMP@vXWEuC3{h15x-J`jYoq7y6vbtlrkqtSD8(HQYZe)A# z!aeG&n#YZ7Gh|}UVc^(K65h!tJL6C`#i^K&jm&KX2bKQ$1YKztFjGdy2BQk?4U~G# zdq@j%ICbOOkkydd)N4OM(s%=&!kl{ zt-WW`s+cz3GilYIQ;&Ghq}9%$9(vED)lo)!&!p8et-WW`8kpAJGihC!Hr_L7-D*+R z^G>>gdbD?v=rP_&WWzg&tXq(jx0}9q(n;X>-bp*DKzk>B4QVSydnd7^=bc0mcqiQl z)@~%*HzLvOokagF-#e+Qji;?nYt!CIWWzg&O8X({YtY_FF|f1)P)7OZR6qxyj0(;K z?EsWfMYit%lu@lo;{cS=MU%z>D5FM`#sMg!R+Gj7D5LHxsL~EV8TCwS2cV1wrnLi5 zMpq8Mb^yxgMx)^Xr2Ujak;u;gBZwbRM)wgYqWyp}3;MT(;b#LNms!X;rTu_1i};RK z`vGNkqE_t(lvzv};|G-4nGRm?1InuY5()7G$`Y%^4=AgF<-`vttNUY2(hn%B7wr{4 zpsc=9jDA2_1K7Rd2b494VKeGq5Xie zrn0CUa_}9P;s=y9jY)IJLDt;Mshfu!WX)qA>O&5)PNezzkb|uGLm{FMImlYTQQ98O z-6h8U`ck_0Zwvw3C z7cWm}ej15%v$&b%d0x@q}p35>E(68O%Yt z;HkeuvIp64Q;0-phm}rAo=PKzz)fL2CC{d0A33Zh{8>04`LZX83(F&vT=f+s`;iTY z1|wNGn1q{}tIFSj9D|z0iy$hhyV>&R*5f2e4)%dTHqvz?`HY4|9le+*i<5f?H5Y$y_ z@Ly$D8PQ|$2CQUrpxg_4m8)%8?hPZlvk>Ke2$YMVd9>!gsITTkZQ8tipbq96;u+X! z6}Dlo?I&&iljJ?!ZP-Wv3 zXDD!i^EwG|Y=6b2xd3Mqbdm!D#!Ihn0bR213A(;lVb2!Rj``AW^;XF_CiB7qjHYA? z(yQbW!+#%zeh3yK4y@#Qle+`CPM+=>Pi5KdCi7k_ijoHcl0AJ%tK=!e{~j8~8vX*v zzis#mzpOK)Pjjc&V6cEjE%{qO;=;WoIGmK&6Og!PFNr!WQ5G{3t)3>fHUz8uU@vj> zPoc?7L*^cnDJ>-=v82J|vLD)GENQLohZ?JFV6c)=hG-2v1AR%WY_j2}qW?<{3#dCX zAmlAKJ)^pF8TXU%eZkBqOa=Ll(q)tu;h2voPs^esu@?v*bMJi%CkcZ3`_8M- zx41;@11-{jTOd^3QovYUb2z&3WMgfyXKk6fkA-j1b)& z?c!>nSJ1PuiJPn*+qfCqa@pA9(o<@@9@!k}r_nH8=9s6(?`Dk!x6JfLwthd( zu^)K_`sz3(28{L1h<3892AN{JIPo8Zq6V>J7cbpOxxlE&WdE6SeH=+y2)n86Opx6; ze4bk0tY2m1UPpd)%RJwzS)6arQqPCSYO6BzKU^0ZF_zk@=V(=0J6Ltl>9_%S?qy82 zB_OpKFR=JqAWJ%$mT~($8g0^hidAyB;d944)$q9&&o_K-U)TD4&I519TosUbVlN4A z$GkKk@%dg7X2&eqU?jL>DzwS7>YhN!BEw(Ixuoj3*VbCK9|t5@Dv(=)pQ*0okly>e z={Uz9&fEQtyO$l;xjnF^GJf}S{A94aLQ${K12R|#L$tbOo7_;#3DO2bs)`__1GDZGO=@q^KxA+El8hisbi2={ifR=f_0e_|eS5RfsZw%m=YXhz@ z2FMJ)iqhc@-VEMA1NH+cz2Ir_jkrdPI0O0BE%SUM>e=gOa$(FiMs(4gfGNv$pp7^) zXvEo+e!w?k4UO2hqcOtM;u~?U7;!rCt6S!IM)canb+eRu)ZwVJxAgo{)~QE&IkT+p z&rs~>4#v*G5Hlj?yGWO+4W7_f^k z%FVu~;7teqwH-tz^c1|QCdT&^ys0L}TKzPpb0G?c&qlfaf)>rY6STo}=Au0VtbrW2 zLyT2;y(Ayi#Cz#RUcJ?XL6h(=Y7O=vlv$S!_8^owJ%@Op&A}dc(%CxLLrgkf4E4h0 zJ3Z83FGhZP@4-WE0Lm19>3s(uiU&3RIjaVHa7kyTkIZxhnK`%_j%nT1nJwxnn z-b)rb&tOj}a;~ifYTMyCcE!%o;CFVCN8nD$xf{EBsdG1S%bZL5;;z+6fF~2+$pm;Z z0iOI7cSZ^DWCA>y08d(nD)&0P=sZlhrPT; zRBkSwX=W++{W{A!3J}v?cx9p74#V;K9s$7{@pP%&Igp%#(C_*13{>tms6GxS8|-6Q z$0Mrz5WF!{?kl)D&sFZdBjJF9;yo|P-`Bbw2QNsJfA4j?!!Y*tvQte!zBm9YEaP z{@~|02TjAv3g^m$h}&BaPAjMQVB+>3hfEviDde_wicl)oIR?3imp&c8@;Eyt5V!Xw zbar$$fRpERJdlqek3h1(X+MdNA*-OF$e9Igog9VSV&^$%=CtDLsHWF_l)0{m>XF7Ma=d`azy1jEA_#K^R@Ll25 zWb>!{-FRhQ>pYl29NJ;v#GC^BL|p9*!*_}^FP9+NcRJvupc4is!zs$+0!)A>6X3}N zcrpQ=On@h`Cnms?xJvxN;7JeP_z+e9YxqVM{TJ|!L|4Y_t@!rwjr-$zDMtM7@r^9{ z{{r85IEuH&v$xfZZ+uPcV+P_r;G*s!8&3vDkd2okAwZ9?d}mq(^S{AQhP5lfN1S92 zfXE*{AMr)40>L+Sy+1fbqz0{2DKJ4(au{IaCt_uF@wTG(+vHi9&B8eZ33##sP{yhbI?$sK!Zx z*E<@tMm0`0sK&MPN-hMTB6PAgB~@F(5Qv>{gH%eu#$6~>)>5E62ft+CVS$B@ZdrJp zI>alyjfGnZ1Pg!Kvha=S3a{|bEZkDS6t3vJNSmAsLmohhN&#b5YA|NSbfdNyxu2Tc z1&{&i1R?}uRvIv7#XAAfYzzPuY0=siqE-7W)^*mf@zql}z7O+<@9XDl{(k0{d)2hK z5Thr^$%lC&M8_iFuLNGYh4S|o10y9k%1206b`Dtu0;7CXqbR?cTOcUPtr|qRY+mh; zoHmbfOe;%5R-J&;9w%VVs+IZhL~kVDL{<&J1y7RLw-j{<*77MXi%Uof6!U3rBFSZl zgvh~bzp%x~f8POj!!q#uL#C`{esJuLY+1I0n&K6n&%!MQf`uP3h4D+7d{j(b>=nL* zghb= zp*}uenr2mO3}lY?Gp&ky4Syw+9q;p5Xn<9*%VeI9%=2`nAGvU`RcKX|m>rXL-tl_^ zjYfbPp7GUN6>|awKlAy<*3~BS3KUAmypf%R6Dm2}{T8#LD=siXoIn*usJR1g4X7Bi zw~Bpz754{J%xS5j%DWoqy=4g3`>kBKGtAyH(9$0zfW|HYM%wfVcn@H)bPEu#*EF>=}oiC!ljFYL}~Ro>l!2 zyI=#&-OrS5M#6C|>NtTL*ad1rtpL%kq4YoxfRGz_JB9L}K;O;A)PW~`;Wv0)u;_!U{)n9n28 ztMA-@BSubvJs5t1iAWPTsD9 zP#d(o9qa8X2sKTN?x+gjx@YPMAl8T0g5l2lQ{o?q-A3dnu^FM(*o;sc?8X0c zVyf}z1-RY9pL0lKGg58H^N%3l8vZnf%?iWdh;{ZA7Q%V3Ct^rBFE#SO zV;&qc)~NyRV4O1xm!|!luK)%Z@63ec1SbJpO90mrz_kQ$4Vy$f0bEM}*Al=r#GFy? zm3V?$1!P@6M4drM#{O__RPHbU<<0^k4;S6D5dyLoBC#XdBVN;;quky=>z#`rjNK5g z8u1wLfdFXuQo&tQ{1qdXG>-2@nU5ZQbMan%96va z(&rN8UN{V~;Sm=Si}Et%{x}p*?aFO~tNi84<*TtPlzTevfUZ<7ox876?xrCL;2Lgu z9#`&TxVL#ixeL%ePb&9A4AoQ0eFu3@D|bs@ylw-&vJYOmDz_TL@tksJqvxMj?f?KX zUr=rep88)@?s-5>zNFkN_&B_x+;WW3tIB;G!~YtBcB0(t%DoCAZ(uSE!fD3J{T!;_ zR4z|pcnk4~@^R#ea*Hu4?!2CqHw}Sc<0YstmGv&UD+qutS{3yIRQSJ)ZvQxF{h^G91 z3|u=WGBl3o{zM?Ze|I3iU^K;Dk*aJALeW8ZSpJU-ceyvf37s&56r2knUzq2WC0{QKt{J)4r zdw_aOAisgFq32%=9q)XXSD4V$d7Cj$S;nhuR#a$dyD#K%mqKA z`~fP^f&4fVyg+_r2LkzN(huaPNk5RECjCHun)CztJxW_r_C-%*)HCe`@?-jc8OX0a zigi;&7AMG`P{G^x;abkRL5Gf&8APG9Ac|&HGItzZ?KI3>J;%{1yg0Fj_HhFio(%K%BdHAkJMp5a%vl#-bVr7B63jqOV5tiA9PB z_9BQ>=GKJV*zHD(w=-&`6A4hSb*7OM9IbM?kF6yIkX-YZ9i}X zi*_6mve1*|8(6fw@33lWr+|+LMMNColg^R4&=>WvXs3(NXPu1DQb^wK3B|1FjYt;^ zp}HPq1B;dt(dsD4SR7Jk*owYN$vyn3wGY|Aq6H;006G&%V9|c1 zzXfxIqNQ_}DXC{{(v5heg|0=%u6u zi?*L&(YAH*uxO(Ni`J{g!=jB*ZJ}Qx?0tlXx6_wvQ&P1hh?Sy#fZe4$%lDf}lEZYf|2S8OyLFcZ4Qp@d)*vIuNg0KmsbM(teWo?>$U z3pm*!E429(y?!sz-@wTh8qpC22%`0nA(pT))z@-pp5&@pdy3Zgkv}pN*VwWr8!@&| zqgfhT_B7?ct@E&D&yYN_-outX%iRfw0UK=DbDZ4lbd4>0o|uIr8&Fp8WH0na*_^H# zw(uf}xga#2>?KZ^he-;a>}4*rA>9xfiUUxyRGaIMUcR~upgI|Vb0JjLQXn{bXPLt6 z0)AAA`iEEeb{1|a;EkTOMAy0!B{T8nhNGu3VO_0?(I#^=p7%>6Q)9xW82))EG$dF^ zFi}UF+{=+mf6k!Fss$!<99mqlJRrH!m$WL*H~br*;Y!2D)wkkW!@m>!Ek0ksNCvHS zPe9_My(BzL*i!+CXnp`vqYNgj>LnxbG-gZ12LbUedx_WMSa6g1FzngaWHv*aEHftT zhogeIfTmStnoOxA*CQZ#t}kg-%noSyQ-HtR@Lz-cR-ey)7+_UAVlqEK=Epj7Z!FkX z0j)`BBgSWMfmE}isiC75z?`rux*I+l)Z6Dv_ghuoJ}9fOZUcAX2N#L_IBAWKGl|zpQ1RnbubIYHkCY zsPr&n1n&>{QB9oA^ zuz`9CjS&OI1RBwZmT3&s)$ECk9v&9$>fzWGrhwE~w2c(R<;-08G#2ez>bwpzU0Y); z>WuPyPxj|XpHR4GkO!4XiscQy@>^74b^D|GUE`g%WU}b=T z)h(d-*prNC4`1|Uh_Vy*XElA%NW#E`I0S@-fsJP^2<>ZTi&b|d4IAj;m+*pLKB|fH zre0uRjpN&~-g<$7X<~f6z`!)IHw>&l$^~FxJ@qn{BhIpRoaMTlwXmlA$$dof{lP{Mb5sQ z-#iL7vW7_<1$#gK+4i&ej%~qLNF^=C`iPPd84s<|+!ah7gs-GFM=*IUiYK+j&6*YA zd9X>j=P}9iU}M`3KvJIvYkzkxGUYs2`};<)^?9)N&#XnC2W#(UTAv4N|H8BmX=eY* zv_22k-ovy$57xF634I={t%T6$!P+4q^m(v$L)M?KDM$^?9&%mJs?pSUX#7M2>O0oC#d9Zf15E>a~cM(FL2W!^|q0fW0>l9D4*5|?6^1C#nZSo>-=SDy!KU)KnB7G}XkH+1*O0`iu!+EC z34EB7z=tL9VF`R#1Ft*oNAoD0h2zVEUDNHV`nalsg?aS*?}( zaX(x?0aqA^Uv!lFEU+uNz&-${&<@}QFxxAa-V+^^`+6ZBd=Z5T#q)rwsl&~SayQ~O zwm`Z2493%(a+^ltB_CpE^+F^VM7=_RVt_1Ayt8t54#4XY<*o%(qZIfXh?FU}5jU0P zz)TFngS2v&p}tDxUNIE!uax_J8J;+lTh<59L&`n1FYbwyy9%!_YJuNC?RCl>1zYNs zI~5IUQ0^{>bOj`+C!Asur@|%znRAc!j@L>UbSZa1?4ITpws3rBB$gV7G=LzK2zZJQa`f_9$9<{td z*cI7M_}qUIa;x>*2O^MFO*D#zdChz!nv;!Y{u2~e>cpfYDE3F8xKd{%v0BfF*-1~k z(4IhXB~V-m6xSby;!153J06QHfZ|H+8|#l(xc`?ZuGG=7*Rht{Zut(c$mEdo)L!;{ zR=V*gyyJ4-!YgIvob>}kyBhViphprS;qyc|r)@ss# zzcTA^n`yvbne|L-@KMK5umI>-BKH)wpBkC(Yna#7>O-Hl0MdRf^gA%w`yn@}T;a+i>^7`D? zxJ-F{ZfpF&G>B`sS9~gq0`6toY-{9dOyBr4Ch@C6E^0XJ34n;A*`3ycFu}igZ>m9G z*`0SG8A;&@tJx*GYxUu#vkvZxpQi|@e==qp=Rr+>I9Z!i4AO?fv!&=&`J1B%Pc z1n4W$cPn0cRA+-_+sv?SSrIn-Rs+Ct@+VY8_@W){%Y95V}e7;H}Q z?KCwd3(GO5GfmZp!RD0EI1K>HDWz@sR%8S^CZ~)rC);L?wtZ6A{ID<%q%7?`t03PQ zdp$^*M9z2)j!Yuw0GcC{$eFT@NlqeXsy~UG=`x9i9gP`(jK~ge2Z4p00#@=}KjKY^ zGx|+v&YgG249gkAZqPfXvxxQEDLgsXSxk{q7)K)_5B>z!DNMHOh-9f!jbqzmF^}Ai zWju(+VKHMO{er~c_eINq?~xwT8_Ij6%tjeClzVxfl-0064P)s6`8%u;W~H+w#|LPhHoM%T@qQ`m2b3N~iR5tpuho!7pRU2zb)HbF6}<@Q zqT8TKjUgM6Wzr(ek}rCa_?>1mCEL@YiDV~-7aPf<)7h3unz_(0J3U982PFNto;xm{ zcjX(brr{m%nhU=`PflV_oQ_|ei)VY(gQRA7)CZuf&JiklCdwWia*dl%CdtQD6{Ty_ezyn^0a!nGDRXU4}dQtKx_eJ>& znlJ`0McKbkljhu3FAKe>9}di1Y|I#nY4syoQz5a>Dl}NFdJ- z4@4OItir@TtGv*N+C_M+_e!ALfqRv!YgulG5xuPjH);oQ;dCC&`PotWXXtslaeJ^n`B6=~ z3o!x`YOQ0m8)o3`=plWSZ@!e+Zyu-ln@#R(T`cQmlY0vI4;g+5_+R;aZwQ_; zxlcob$jeH?VDAf(b{ZSMhHRc_S$8B-ZO9LA}& z*rC$6Lwy(FH6msNuoanlxRP`|-|<>vbsOR7{Xw3ojwLPi{wNx*16`H&yY)=xzVxn0 z9lcHuQj=c~H{cRMVZA5yJPkc15*hBj$i3KW%J#v|C!yiCM~EB_uiLb=TCPq#ZA>)je~G zXK@pM_0m`AJ0rYG7Xat3NBYi48tB=e^+?|>jlYky^vpe?@hi}kpBS~Yvb@rm=HhC# z0@`6RPBS()Ika#-)>oquV)Y{6-31u|tM+7Cy-e!3{akHzzW#?R+d{mbFUjPHFN-kU zXOw64awMl$ zU`>w4bW;sh`J8}E>F>$(w8~!y$c*|unL4Yy*bENqI_~#m8my{O0hyMzgzN(J$v?hB zpZpMF3yxo@jju}b`h=Im61g+@A;dd_@5iA}9$tVFKZbax(PgsNN4r9tvl~Iz@p(c0 z6ynS6cL96TeY9I@Xmup$8##M^3GqoJdJO2Mqd@-}!suGp&ju~`HG4wbmCBC=-GTQx zR(KoevyKOyvk0^bb6?wi0@r{sn>P)WUmJq=B9*%h!QH+xwo13|XA=2_h;;?g(-7Gt zW*b7ZooWctw$>1$?OH>KwkHiC+TJsSXvcTbUt5TR%gHwnGdd+7=js+N#bsL=gM6A@C;qy zxzY%*o4D`k*}7I{Ysoy!&LZw+Yo)|_CwjAWZHRZ#zs$#Mk`;WOCsI7jZ_~=n0xBl5; z^!+D!jmVZI*KQFSA(sV5G%N;P^`cQzD&02$-8Z4g*8MnM`mvI|@}pvvZ{TQkeunu~ z@=i%#vv(=3!tE!cN_pPfrM7`?yVx^fm*PYD0?^uopGD&)(sGZoTimXG23_@`sb=qc zlvlok9q)^lCL_Rog&)?*fHc3&yMY4#}d%Go)4v-J4wqu%SWQ|SI|`(f4AP% zyb?SnrAmyziMm?U+lZ}6xBoGzcj6M%+vRAKcwF?}MOyCBo{;=6NiXPy{3jLPQI#wO zeH3<7^_1jK2VJ(NC!U|5QM~&Lts7H0*VI~%5h`D92v*GZk=&{Mr`1ZYWAr`6hul4{ z5X+xBO^@6(-|_;y(9o7&AvIq@OBVfv5?3l-PhSSDudf?~u3ZLNp6ss{jcY;kYJ81Q zZ!uTKaih>Zm*e(pdp%y57<;kf%SYX+zJb~GNtoqr8h(a^n%eLc|4qbGn6Z)rp9cHT zIJrTs`r2g7#RI!so1m-n8(a$uWg3k!`6qd`H1XbFH*cXd?>HEwC+10F;0>guxr?NE z-+|W6T`cs#6<%{s5&7Fdv$;!z`i!~K+@(UNoeEl3)-thYB4}y;RmQN^o?)xiE;Ou$ z&A%E#HSB@MnP4A$j)YZyM4%V4(G0&AE@;sUbJ+{Gu@@$Z&0n6X2l-I1vL-%(>0X#D zy^wdB*9()y?n$6^s}B?n_mGxBK1lL=pRQXyRj4yS=~hn@`XSKeznV%pW}Ac7mj0f# z>$sWpkTPDwY7c3TKf#ox_)|0NQ-s-MZ+4<9FqY;ZDp>E$v~k$16_V^ zz`ALA^5_}$rpfST6#KIFCoc6889~p>z<+FL;>)70%PCPR)~E^k;iFvSF%oUK+_Hr_ z$7nC`+r}3gx^3BdBvxW1WCO~UjbajLvp0)|b)=;=uC(SU&{Y=&TI05Luq^v zjoGi@Ggfe%U%?Jma04rlTl}4}S63bNyA|}{9DbD&V}DZt-?``(yvho;`xU%S`L?UQ z3f|BaO#Iyn9%C16-i-@+Pm_)P%4+gR7Fw)!!vTg~)iR=0{NKkjv_9?B1g-RcWJ zly$2^{Ak!2y&H$zfS2s}%joMz!)~>z@d(@x@Gq;o@9)&cdj1j1^8KAMW(__9J0t&E zAFl>am;@h4{IzPU8ZSmc{EER2gD3b@HhG_0-Oww5@XTQv80{0C4Y(7S z?>ycIPwvi}C2-PohT(?qBhQGCgmjDq!MmYxJgR5NhRE*5Q|5-*WsPQVahG7wyeXIdr%SX`{BcemwQJd7%=Xy zXDGKn@@6VG7x(b9l>0s&Adf~SgPF3Fn*bG+v57L9MO?s?h55b z@$XdSjw?gJD+D`+2hZtXRsvn4+)rT3%0w9LgqzfVS{UtfBHOb7XiT_C{af9nQeKYC z$ixo`8r+|)=UAIo|;RC%$inf78?GyT7eWxWCB zd$Fu9MsX9%nltO4#j>W1AIo|Q%1SKjp>6T1anvwnW!2K^|2CF2?KQEirI?Oo%}zG4 ztT|#PmNjR>Z(~_=Mw?jHoRlV(H7zr-tVgp79m|@{`%NtC^)T1OvZlHJESB}vknv(! zv#7+f-WLfI%bH0)mUT%k^yygEyqEmn#Ij~l?bh_)#j@sIgCEP97kRohaoO}hahd7O zv8-=^Wigu>UM%aoJ@c{)n$7#4#j<8rgGK^=; z<^an{%b$ZO3q8+j_wrBZwn*8$1lH8~R>rETCud=GO z+fvm^qvpf^hrRazkE+`GhtHl#GLvK2pPLLy9N1)9;$QR5y35`a&NOs}(P-SIfysU@!haO-N{`oLc0gTjS z9%;VJl?S@6C@k9gpjMwkX2DXC&P!7_SgA0Ii)N-(xDE`DfuU}_ky|gI*3JLx)|1e< zmyF^G(AlFv-2hWPZgMbUoD?o7qUqv zw=H0oqYHS_={0*H%h-k%JdBR8z%cf3eVS~BG5l@}jR1=NB4HGqj@Euw1>N zYP032YlFtk?nPn*5=GA$%6wP_7O7Q`3{yxe*_(`23M^%_f8~jO;c$p`-t;KiYZ$cF z4B&Z*mbGkP!9U4@#oW80hFIGG#WggZ+JePw!G%yNo%bZ&LiES)tI#!0#@2JEty+9iM-Y$ zrB)AzO+b${t;b2yrfL1^M0j+)%?Qq?(&aw_|(psw@1H={%wmDb}h>+vdB>A9oxj&+W3`}zwV zt=_BE%3&JN>I1FS5D=G~SsBo3_FvFy2g}@Qw8CywsgU;k^{^^#CaDk5sp%g}^gMhi#NkEP z^OpRc&jWO3koUQ)mV5?T+7cwUAbTFa)w7Hq#U7>X;44O2VmTcQCM|YZt@up#ATfU* z+16DgYb9k@*SM@US582772gERe`0c*B^M#Pn${h??MFW7RylsMN?l4_ZO9gP&)+aP zx9w7`XBTYDJ`m9LZW3+IZg8RV7g}3IeGOG_y?qB>{^TAA>5>POB`la+d^2t~|Yx=FG(3Bdy$Lf*4$BX!LZz zG3!7OgBhn+GJ_Lf(C7i(z1h(HQA4Ax9Ozz&A-NAEubrEut07qhk{`}ZGT4w1%%OrG z4%y)hK@$wgvmhxuH_1FhvJ)hioSWn!L-GblZaz23Hbe3rNS2+OXd~%w$j;hG za#sXxB-1t384Juk@#jb@-`R@!q+RhToijSoR_FNO?$%QSM?*Tu>TR_XZL4?Q?`)i% zXyc52z}Yw}srfy~w&qQ@in7-(gQxZZaL^>$hRjybyrd%jwT(fj&zWE(p|vGf;~GpKf7>qWF9SdcKK=+% zxd*z@$KSJ3T?sfKeEg4e*#Xt)@@W87gvrOZdvq+URfEJ3f1uOH?MpRlIi0gW#!;v9AXs>!{a*b zWq-rp+RMJHdEym?L8iY;q2d2iFZ+sv(Q6dCN2r-VB(T+QpY9X zjfG58{$^r?xsS36*%gIGy7Mna~7KyP`wx48u|1pgK0VDhk`+*bX32 zhudPiRO8x%NUh4p#8%$(uo@IyVMEo2Ie1X7)}Yp-&MyL2Rlfj_s?@!mpn_Ufh6lx} zF|O!Rz1I=ysFf)&i|T^CH%f(LFN;<`VOx(;Tfr?>-Bu1A)YV8URn-zZf+_*GI5nyb zHd6I@Q%rKz5^d|Ny%~5Ar;2fMYoJy`hlZ*nWHnNGkkVLrQCsJ5U*~XN=WxGFRaN6D zoVv9uUXWI8vFARhVzHuEsy$dKtJHC<<<;urRLgoub;p`rqmnCe%1~8U(T}LBur?p9 zbGTP^4)=8q_jPee{PaYr&f&h!;l3^|2~M0d8du z3jZ>Y9KvfQI77c9{9odzdl+$#iY@D1gj7nltRr}p1J~R4gnuqBweRCq6XKUK|ezbCgeUxASm$s z0->L9;r>$iM|HETuY`XpbU7~K8smg~>J%NNQ|VkD>za()04Gete)mUo=I=Gj!gtdp zbms40LudXYchQ-@GtwcdY%!hrA6`gj{)9zz=D&Rko%#ENCS0AIMrZ!ZX40AeeejX$ zd8BPsIuCc3{_s0Vx)ncmHtIijUk_=H>^UJb?fCqgcW#UT9O zuZx3H_Z~pqdjS8j_W%$F2fum)-*M_Ye8;O*ph-}7fkS;OzCALL-+3Q{+D;snnNZrqVL1xT zoj5GVkqoiiIu6T~pmE}`yg~Fj4vVJOaaaz3-igCPX(tW~rNKwXVOc(ChlSEk92QDDaabtrw%j@n%X`G<P;ww`=ja06UBwnP8636@NlBIP*aZLvLA)~qC?E(lnlggd4zb=iw?0FbdGl7 zw~+cy{1$Cn9lu4}mV%Hi9qC;%68$ln4-$Kd+;;o^07ppJl5YjHoeIK>WC61~4LsjYkBqIL6W~kC=C$=Is(UzF54M59E zWzb-IE%zwwj4HDb^l8$cve0SgPu1-fUyV&PO}CpBNTXfuP*kL|Gyb9-_(?4;IjRxl zkkR8(YK}axx4_*5lVV z;<8piTd&uT#;FNm@ufGD0>A%=oxVBs-%6gl2(OkqYgNlzA}WAjJx`xgGvUHlJT0E?2~ zW5};QB#WJxP@9**$&z1vNaYr}%N@V}G(qEYBl0>(OS(t_J-zCn{r)qww;<}9t%GGU zz&LyCsOv1zTF{ulOKxb+!3^A{uQfVo6)e$SM1VH;B#GbDx~VdcGK z+6;m1^4a+$A8v8u!J%NZ>C$zm>IgngHC*ndjI|1Vre(u4yb`b^C{vL2nAYPTXn2Qi zNKL?4w8+Rbwp#c6qhr!N6ToI8%`keUqIA)V$UfZ?#5-1k z6}&PxQRWL|N;#IwGc>N(tU{I@CpXiA`We~gtJCoe#pq|F3H^!fHzmW=Pot{!YL``Z zW_|hP)IqB-V~y??S*@VJWagr7DVmdoC!)NYDPN58t$}hH82sc|5cRNTu?n>Z0<~5_ zYg4`s<=+IA_cY}XLS$$PN#W=z1(%uf=Rlvv}K znesPLKH8My98s{zl+)9sy94DkBMLAh;Gp8kli=#PSumj!CAf)%EmEI%$#4wk8tOk9b= zbSITsls?%?b=TyA7JsQ$!5^meDU{3(w6+SJt%H|9iv|{8q*q;QrWaNZ|A`vvQ!#^x zuA(h=5GGkg#cP;&t7w{v-lgmv{SZyz#i(mZlhol7s+m~gVVYqV$$);_<{GK&cDww$>zl=AL7 zn|MwFO>>2TNHolo9p>}KqD^i-sy2cqHyw#%NaR%*!iXk3m1?=tjG`%uw@|RFg}e8e zw@~s=e+wnAi(yb-GthIfmJKd$+n@st8($cctn+fn1UHjq#j7Z8#XY{6dfb`^doop7 zMXwXtI4b_rxG%Y>9Dj&Yg?1W;b{zBRW3|~vd+aF6{bI<&n3%|m=2GQgve37t(i5nx z!bL+P;tnQZaKUfUoyaS1GNfYzr1L>aJ8BmaV?PY@Z8J3K!M%4Dzt!ShVpQh1U*!iF z(Pd3z)0RJgp>?onb;e-R>P!!-En(BTlh&fK+lygq^>_$UNslAn>O(3_sz;@SP3unj zl|*>GK9qQfxLvT%AH^tduYLYDQ)}(>mjtuI=Z{9{Z_^t|T<|Aq==#}-c7OQ%y?}r4 z`FnMUWzk2KR66c|F}3c03AOHj0pGs*wZ47zcT~Q9HDXcW<8Kyl1gsB7K*v9@{@0aP z4h9$%J}S5JJ6!eXQ?F%Zr-vOl+seV$dy$c7}kf2;q-$5dBVrnA>crmc)9~& zyJ%KD>riQ}I#k*^RN6XJ z+KzQja&Tr=>CG*x&PlG$Nv_UGZofJL?}ay1Y>TRr`_f%D9cresC$;mn=xjHAgIw!e0RN6;{{{bAa>QHI_ zfA1t05$hU@hYRMH{)k-H0{pz9w&RB_OWkq-o++sJFT{j8_(@Myp*BYC z2G3aa3i$ZcVU#FUcsZUGsfkF(sS41?tNDb%ceqaOa!c%;^*?y$8yO*6qBnI8~UL*s~TE#dT*txxkn|AlI z3wH&$orZ2p#RlE>onQ_c-In2D+1;yNvuO!XN8{SkOwjIL^>V2=;O(hjaIrTf1c3mNi&0M zJD)^oTwChi8SY-u&EAE&2G^F<)$U%=IW%{)yH|8BrM0_P^rfGG#=*6vri^Pl7YT!F zOG%9z8P7s8u31vsQ`NCbde$Hmy}6 zHjA2`)8&jL23*carGU#B=|nDPMDaJ8pW$+LEs8u|s_=MeXf+Ws7u+=Vh#D%w!J-g945#yN z^252sJmfRjrDp_tMEM_aS(yy9I8q#?X*z%2*e1WF;^+CNG*65L|A{+<4c<-b!98IB z8Z~tzF&&AlGbx+ZN6i}4WG~C8rlKexTRB0+%snv+GWdtr2geaSPl_6aLoisEpfX^0jW_2Bt!0&qwTAikCd2&fKoui~!F1oFo9XN_<>MAZ9)-EtXG#g$ zu*hdC(=!31>=!h@$^7Z;H5JDWX<{wfv!_%%4_^z)v#V5spgrJTxOZ-F^O)<4JATvy@UOH?YnENh6LH%D9+@8i_gQ@%wm0JUqR=%?l@e(Qg zl6I(H`08#}$hDUK6E$R-BKETRg{~!{Pf?hQsL6#y^e$$no8MX@(+yLS{9AsfBinRj zig_D5L2P?HZg!U>!#^-t|K#1}Db#13S?BC7g}X`MXT;~P$Mv+u3gACclZj+0tM@sn z_azvWvfI<=QP@pOpMV;y;+Lf20?M*hUlF%`$Tp`XHgG5iki5kG(e*0xlBf!h`L60O`J$q|Gt9*P5300d3lS!KU38Y}(gI@AIJqnf7%u z?XAe@PV6VPy`MCub@&H5@g{d*1M0KRtaD6Tek-ZBjRn$0qy<}Y8)>6Gq_&gziWiCM z1){QAZl}5Oq@bm%sn-*=j=jE~6w(bhP(!OQhc@4pR6NmiAEyic6E(EO>+Y}A-9L}7 zYpaRcIwq1M4zlPYn;v%Mv>b061&Tca4cp16E(C7^}Ja~!oPx* z^t@R}^QQTF$HwRb+YIIBWwZuOWyWHhbt(F#DPH&b%3I)cH!!o7&?L zW)Dpw7>?kK#0(N%YKY-)WOPqNzqRf&N%xizrFEZ4y5Ekho*#Eo^Uo;Dy3e8^DcoRm zuP|%_y3hH|(Y+67vd*k`bnkn*?twXfw06!PBi$#G@O(oYrd7uUw>NaxgFaCYx}Gi^ zr`>AZktWx8(lhIS%R^U*_lq8Vd3s070#%)?LlMJ#_?IpcO=wMXNwqUw{3$4)XyTu z+0~ieMGUj6Gd-+!t?{hF)#^qxcDF`5?Izf21M)~-gDTp$TCm4pD}xe91J=kW86J>I z$49fQJ3R}E$Z@ziOE1Xto=RM5b#^=kqZfB}00Vt3DtCoxz`)LqyPw^%v*Ye(x9aS; z`>7dK4s@U@7o8ovK((W@<2OS z+EdUur;as;z^|skjQ^IWp!-WNY@T@)4Cr!&-WQ6@S)uH~)N(@EQ~IBVvR_P1ftI0J`$0He7O){{WWMDP9 ztPImqGO(ItU^U6WYLbD~Bm=9-pGtB6FBw=(GO(ItU^U6WYLbD~Bm=8S23C^{tR@*) zO){{WWMDPPz-p3#)g<09u#)7UO3O-?keDi1fq-HqIftsqUVD#R3(*B9VT7&!vv znKHZ!?hhor%h6OmjoK`^xD|d9k}X@{4o!Nof#t|sb8s$|dq9&X3Enhc{*3Pec`>dv zg|bmKwg6cT`eK;~ni9F97#AM7xdi)?TnheWG9(LFhH@@wTF6^qu?krV`?Qq(Qg8{E z70|Yo9FOnTvI}IjkxM&Z%ay$#y`Ahw7ePmmB(e#yP~C z`cXbycEC7}kc*+=NSTHa86~4(fotR*$h}r}1Lbvc9Au4_6`;Rf4np6@$ltqI)>yed z)w0IP<&b-W3ZW!{$>YIh@}j3t;D| zvH+S)lMP_K>GF}*I9|$Ip!03=CD`_MxfWKMA#)&crW_Aj-67vc`cBy!<2XxxirU$7 z3C3uSd>-k!@&I}?PnKhS&6iJ|XIXd2cCg9a@@KSKAY);Zdt^J5-z)C~hlTP3d@qux zI$73z(vN*|vHTWtm&kdT2{ken*0^5|#5{aJu7Vww%Dcc}nPgx!$-ruofz@OzB(9VU ztR@*)O@0hpJtP@eO){{Wtb$D*kyoL2kII9PvQ~ZoYdj|3ZDU!F%geELo{)D#$~svE zDNoASZh(lDFQN7+Ssx>^LHaSu8|58Emi4rp0REfgM;QHQWC$oX%Zbo`i#&vqXJu>j z=s7tMb9k%VhLUY^Kjz`{@^bLmF4w{SFUW(i!%MP0=EDwI4copfe}z7KWCiBfURi{( z*e8!+bY7L0z^bpwH^B3CnSzr2l6}S``;1BU8I$ZYCfR39=A)+vCHss?_8F7xGbY(* zOtR0IWMDOU7gG z7zeMgw_=in3;RjPju7^2h>a9>Ci)_U-2jWq7WOz$))V&Obo^i}Y(Hi|w6L|$nEf%D z#|rxg2=WO#8zZTNeH2@PU)ZxSr{jb@5C({cbm*KQ>?ll;`oi9aQA&i?FhT=izm39% z!cN10Hxl+iDA8EhzoB`Ousx8TEbNugIz`yk&@)xoH85nFupdQl)6oYs$PhNYTa_v7 z<50edu;-!EO@&=$5{i-r9?Cfy~%_CorlumtScU)am>?=qMUgL*k;0n9o;*c)KF zfx^x~9|j3q1FP9OlDVxTncMwgi6Iyqu)a#zI+D4qBbnQYFwZby>qzFdj%04@Naps* z_7ut7z6SlfM%cHYN7o8lM>4l{By(FwGPiXkb6ZC;w;RD&=caHeZsy6OM5Y92zHz$ z!u}nDQzPsItg-urJsRWwfUs}HELbY+F_69toyN3Tj#&qi6~dkgbsxl%!PHnO?EBD% zRnQYWSA#XC#zVq>4?NchI}|;77`BF>M}$2W*QH0XjxgQU3j1Nq*2jchf<8QsO#r*r z6PPGqy-wIygYrpXUyn7m9#aZhKPBur7=R7J{sZkc3j1*sJ}vC^=-4JG2opSmjSTzC zW??6R*%o0xkG?-EY~RtFaPUMyy4y-(PA7>-wk zJqpcVgFLA8y09bAvHilPXee(8TLY`v8d%NNz-qPzR5hR`il&H#rrISky=r9f?l zd=(rr7%I5Mua4VCU;9M@-fM$yQCEA{H+uK2k8|A1S`0sr)*~cR=G4tvP3}#v^!eGjJD9MzCpv;g5 z@!M&b%yJ8Kc1) zZM3`r-%aIk$c>SkQ5!3JgO5+<;aka2Q2J#Oc*e=&sEwCVpihux&;-*Kx9o{>E$-|a z$V#Le$_JraBUu57jpd`zFiEb*BZ6eP3ewYMJZe+qXndzyQ6Z@CZVaW-bqwMTyPXWO z_!*icqaUS7GWKbjB)?$VxC3N;!wwS}d*#WIHxt>MNkrBcX}7!*=@2;q-=XqBe22;N zQ0|f2@$Ho>@ZHw-q8tbvQ9G#YY8LA#F)FOJAKck1Pqy|E$H-XXzFyH%jYnmOJR)hC z4{t~dc?^1xAZMezft=cymTD)|rpx^LwDe}i(c&t`w^zErt(k0!Wf3mvr{5g;COBgm zqB}+MX{3|oo0$6<^09bYyuHCWR<@6%ZDeEvnutjW)Z2Zi4U=6_BIPNhqvS?tk|^_# zZYb|Ud1JX3-`TPNJPYJW$SRau>ybsSK#51DK+il`iSGzGHjx&_dyQyAbEBl5OiQB0 zz+QQB79=*3OQ2z@yc8VLWIOcKFPETIrW}BNHIW&Ro+9f*+hVyCvP$GBl$6RbNH>># z@m(f2K%a8i9U8Wfzrzj{Qb0;exe*f2lW%~&mGt1dwLAhTZRGc`LtFVMWVMrNXxm;c z1^*6mC%!w%+rXid+>hGMl0wf`$~R%vD!Br->LQ~crCN5ycy*Q0klsyh!HAqMZ$sZN zkiEe9LU}i2b(bGPdJj1Pt$NBw(U)HG0dVdu2ZLK5$zFN#GxYr;nGCJ^$rnI*vFrlP zFOjc-@>2N|r1Y2DVU5dVI5=D`uR_TH=>~^^(gXTIvIr%EWk>M2LbioHuar-s?GUUJ zdd_eMw7pt30EeNn2Ko$>Ux3eW`7Ai#IRi8wDO*7LC^-S&*T@gS^IB=4*VoBRq({pa zF?QF>p`aWiFF?P>%2&Z*oE!{UH^^T>GhSW|DL2X`pqwD5L7$uCSFqkcWFKfUQAVTW zX4wf6C&|&EnJfwSX^Ld8Jn4nSrpg%bpC+^MJzdTO&s*gfl;0+E@O`^H3jJru>8PD) zw?W#%%@EkpBAbCiZ-VDj^xs)ziJp5PUA{}t{A4CJ3Lzyn94ujMbZ$8rdqarKSG4Js zdugM46W<4VM_z#vuM8VaYqRGFS{K8>CnLhNN-!3tt@vn%Ftv5Eqd}4tqXw_KRqy z=?M!iBKsKVUFym~6Re0FO1pgt5l|zS(gq7IBCj*?VQ0UHLUP#i5f)rT5z$y`)Ua!; zh+;|$HD<^aRzwMLe-aS0|n(tN=N%V z9;E-Gbb@bz7wNw#o$Nd5Li!Y?o5tS;p3)MODTs$%@C<`95H~4E;p^g`AhKxAjE(O> z+Qf?GsJSuz1(Fkoh*Vh2@$V8@yudAlH8s8izGZ?~3~tlnTT`2c;t^zK#P^|0hFA-N zdGTGT&$(g~GK=DSQYMcx%i=GlOg?AU#1EuQ0cY05Urm`JL8I|Ze5bdODQ4Za$KOOX zrD7fA?64AEAX_bt1>6d*pUbF|zOTYiw49Qb?;6s51$Ec!OCr@*Q*Wd3)5B#b^LP)^ z2tSV^Qk$n6mC|T(>2{~o2VY=_NK7ViZ3LAk?je3{b$S7nx8rn#0HJ+5$&83Xu|0#6 z6duN&$;rX!RJ}w}#9JT9WbAYetWZDxMNoK{dJU)~)}Ra$(wtAD4AP!tHS~_b#X6UY z$?ddZ7wlS5c{&>w(r`7lps0MEMR@e-*mjWS63Hg;owiD|{nG|C_?+{W#&Ys7S*U7+#1M9`Ubm&TRYZ)3VJv-a%?WstV6 z#^iPyb0O_qji1E{HKr$N*0`zxl6^iP5gKKXx`!W`7-i7!pbR#_h0~`|2Fb{l@9kWO z;H_9F3L_fBTd|9``j|_}FVdTI9P>5iGHS|hr|+TApbS#dUx-2aJ~U>`bmC1mj2TNd zM64h(z&KJrgm=7{8*)M7O`=hX8Be2hG*mO6KyAMW#mp{8!hOXJAh?N={wsFjjyp6q z-G}S7PeT~ejjrV*7m(OY&77QCW1HxK(-4MKE`1upkeWs(MPnMqHlsQHb|`BQ%NL_} zLX!^NjG7!eZNC?qG_N;U<_7J5t|g<{hc;%b=#wK2qP8N$Mx~NMT=`2b|`=J*Rw3XY3(q@XX# z#xBMF5gk7+AsOBN3YW6@8%Qn7mvlbT<9CAu(3aaVJ>qZt2^sfh97^M-=7HSfEx|X> z`6?usYYL@ML+soOF%AiN7bEHM4#0Q1`+O{zgyti-WHi1rXd<{PiLT8pTzWgclgR-0 zB9TJXmU}-AzzN-!qrl^R2;VI7StL@3Foja6p*iY~B3AwOp~T~T6W>gF3<)N++!y1X zJmIRZx&BA0CkY}YAnJJ>)Dy0gDDZe=@y+cssh&kq3N?4o;-7|vm2eY@a!-PJ5~jB2 zR#o^;?d7xpz^M;)cTipIt022EVPR4#%)6M17wH+cn$q`O08U;XZWpbD#RHL!_8q0p zEV%*c1m7^Csd)kEWFNVcC)|H8(oKCwu!IsGcnhOi;QJ8|F%p*MBVF!mPxQ-ZWwrIa zhgFlXJPq_!zOh(~2`i2v-Q9PBdhj6izMtxL9Bep<9Q%bhv(gSGM zxG7yGnr6fLV!$n67w%ruEt7PGMl?D2Yavy%M_HWJv?-Aex}8a_sW^(@kG)f#bBL4` zx)$lI=2)F#xZra4G6i)U($5`Ij}>}|NFyw7Ffaf{$` z_mze;>jM^d)mir|Ya6DiSS;u%ces1MDQ(u9I4t3N zfUHtXc2Of}n8V#48E$;QUGAupY-RPM{@pL;Q;~anFx4)HD%#4rn)p5-HZj#aL)B~_ z>9AB_Vd#VN38zI{E9(KW@G|iww`d#a3nsrj? zXW{OhPHBDI+QSERFZXJP!{G#$jaV;e8ic!dIJ5_-Z(EH$w>zc7v3SKUL04n+*l=ie zilpu4zGPoP?V5Xt+n%S;Is84s-`Lq|LNEY1vz|w?xrerW(I;o#m7p*4&`vFS=dzP= z3vRu7BW7pbbW+ae8MaHax+uVE1X$&Ni5(oZG;MzbdF~HnIKPMLT0iZw3T`#cfVGF; zbm2tkOo2jjH-6jr4AM-eZ6tdP+45uqBnQ4c-r^odiVU_ z$7J!W>=R0}(mns=m|V{+XwaAIvk}j=;?wi+xb+3CO0?F*68D52Mc-Tgh`Ku{=xfO* zMp+7?dkR%##xc=_cq<7qt&(}$HG?=*XE)PBfeM&eoJT}>{i)DEKbOC3Xj`=b-*1B& zUU_=MqB9%1jFu@7Qj%^mB=P=#(Xiam=1{{+f*KzDuN#)k52AHtpVqAwXJ}XQu%V@& zdFwMRK#r}FpG|QYWS46ewObnw?k{S?wMX@p!4mKi5nGH5*UvrXXrxtAXlUm)hr@zH zJA;f&1I=S`a*S0n&XD~DMON05StT_=vJN^GJV@}&Msrbkro^XAi}Rt~x4H%JYps%P zro11@!*a}QK=~`Cd}0f1fn3hZtmOM3$=x+Q%^O;U|3tFqC2bdyJTyo`tSKkSQ-aDH zneq#nE_}&f_=qa=680y~*T;(&eh&b}agn z_>EEIhtiFzd;YS?6XozmeZvy8PN^lPhRjww6d7LOdcyoYN%%2%55k8>RCtS=$zYY_newkto@vT& z<~@<7RtHo23u-%>T0J{%Ms4pPVVCJzEo@W}(1=o&j7zxkCkH)OOyL>F`SBPY>&Jl^EY ziSXSh8E6Q|PNGlB%GVnE?u%y-axuT2=+hp}*6ze3_x(>rSg5>5lS;ngLARI#PHp<)l#0w=s?Lt3d!^Ui2a*2FT!wKM%zvV08_3JQGsPAbuvNT( zE~mTP&znNr<`~*PK%4*7`Cz@vP3cQt!3lqNa9fX;9s;-hDHI%Da4*@Q?TT}y;V=jS z3bvc#9P}I3s=dwU)$D8%m|eK3Hx~dL#cJ>H(IqblSkI=IZshYbPKXgTZk!19?caJg z-S0jGHTCV)Q*OG59;H0LGQ7e4Y%;91$GIpz?WT+31C-~B;wF~xC-Nl=j2IVgWWGi( zpg7+aH-FMp(75wuOW&YAPDh-j+}=6+;K;~-qK3|_TEnI8X(%h+>u9)?H5`e&zSUXI z9QIP4Z>?6ahVFgPXi$(wlfW>b(LYYp2-dobo+XWEPR@)v70~5ftnK{YNZavjje+2; zb-U3`b5}Hxa8sJk1r8nN{3tU=>35gj3wk*++N#7Vh>S)R(_+)&y@*G3G{$HmKS7)D8k| zq&-~NNXr`=8XCFMQj>X{iF>;yVP$tTW#yQU^hyvhnT&6)Eq88Ac@28JG+Z8jYFc(5 zJqT;Xn&0z`p6M?I%u4Fz(@#*MHFtY0bk}BW&1U_b@_ce@&1Svmb!W)iGRLPW&nLNd z+&*qU@{3*szxJHJo$^1>O6|b;f;QoA*wnFW$RQxz;SkHab z)OZ4n%WzYabAldL)?@wggsIj3Fl56yd-$vd?IYc&4RMoSsA&HLJ&QW!ItG5C{Ro=h zf9Op1Z!ToManUY0+c2pJNG(J%|AKXB^o@%iU`~hn`Q%!HJla|Nk=G0FJLb^vEtl1y z118RL!%8`PPWgM8hkBiyB?Z#!LjpE-<0p1U;Q z%q|_(U0MqQ?$Ya&pe}jwxV>P^nO$-Y=l`Tj6KRAFvPvD!?$RP!^{=o(;b(Q}V4zE{ zaQhO-*IjyryEFxPJxY6-!#?D>OO4L#(rda)AqP#DnoxqeG!Th`!ZW+%oSDz;lHfra z7y_Mlutwsn9<}O8lkj=2J@GWA68?gQFqu}!de-)NQ(HSLcj0DP58--lKMTs~{;uc# zzJt8(?*`_Oe#rFqEyF4>D>v!>_6GqE;bclsf1g33;B!MBn3c|*%9;Ijc~fXs_8_Gn zW0f|Y)uq<&(luj^OPqrCZ77-_GIY;qwaTMq{UB!^I;&l)^T~|&G1sMM)n>1zW6UKk z+Gfu;wLOU`{zT0kt*~kEgWF5k(;rXaW5ZE#37Z8^;rVf1e{TH=dTh1YM0<1}Chlz5 z)$T#r189zR=f-)aHbKjRFnVH?&(9OPv$EcIV8V8W>|D>~^<(nvDb)K8%rx5Urx*bK z6EzE4gDIaqI=G%q#{L1OdT2Xwi=D`qG&RlWf^;PsV5_dZo5ont38SQoA?gXDng4{S zyt^TyZQRO!o_3ismNV9z!DrI{V-m8a<*eyt$ZJh2n8U-!7u;*u zkP^@m7U&KAYL$i1*J!wlxXE_&vq}UTg9enIdge5^k|{_it^(QFbQMVB2H%-wMzfLr zFat_9@dKj5QqXW-#J^Sz-KaN+X98_kv_-#eJq|X9 zM90Q(Uw+rI_F--@2lmvAo|e2w$KpnQ=b8VaI<-6k_ej}JXXrRT6# z@glnDPZQHkC-7i{|3nQv63YqO4MnC4atOf^dl07@C)YcNfgns>536_vjaCQou9*mP z0*oGMhaT~xst$rq;qRgcdVY1}-{yQrkiUTjpp)1KLEVto2bfAhr|?ISFZsi;rL)^$ zFw}Fbk5!szIyO}onv*v_gLjQdw#u8B`bp?`d7I!&pP-DDJ&cB|K%^z({VF31qsM=u zhNS8)6mS0Hzq3M)c7g zk7xQJ;A(Zs#4mcT%uS$oj{|w<$3x&P!1>M}qR^F@nubyeK9%U~40dUkOi6u)&=aphRt`TeJ1yzt! z?VxHz4y$$`JYp7CI}jd8EvkRQ^rKJmBh|a`k3Pw(tJ|-^#K$LcUiBJWdgzl>RK0X8 zejUOma#r=PWAM^3K9MuK?t=dGsUC)t1bzI?s~w1slpWO$#7D~4-5d~*lycGSvCHwk zA3iA_(d|Pic|1SGCv{-;BwRb`lUCj>92YS9 zM7TutL#uJOicjR&^Pj|S@en>47Nx2Qjf6gtBdcG9h3FGGzWN>5jXvpF)s?uE(I>sM zdOAwz<1e&wanBiI%^Zi3(lN^}QW}Y5`z}3zA7NV2-$!?1BK=!PB>xnC1a=C*k5Kxb z!jH_QN)10kNrE5QjQ`%p@#SEUP=Ns+!H`(){`fi#cw{h@4#0{DO`J~2THujz_Sg3O zG7*&#TDZ6r<3nWq2?VsThSu zy@!jMtyZSsfumv+8pS9yicx43qtGZup;3%NqZoxoF$#@h6dJ`SG>TDZ6r<26MxjxR zLZdoDRwKnIG>TDZ6r<26MxjxRLZkL(!VOI^3XNhE8pS9yicx43qtGZup;3%NqZoxo zF$#@h6dJ`SG>TDZ6r<26MxjxRLZcXkMllMFViX$1C^U*uXcVK+sJXa6wNQ*gqZoxo z^@B~$Q;b5R7==bL3XNI{`?pn$LZcXkMllMFViX!R5v@8YMxjxRLZcXkMpd+{i(H1c z!_@jz%NnPa;}CpTQZqXcVK+C`O@Cj6$Org+}$pIL=axLZcXkMllMFViX!xj`cNP zF$#@pmkc}t^)qx{pcsWlF$#@h6dJ`SG>TDZ6r<26MxjyjFcWGNqtGZup;4TDZ6r<26 zMxjxRLZcXkMllMFViX$1C^V`X&y8PJj6$Org+?(7jXH*d+^dRFXcVK+s1%gcMJ@vh zjbEeC_%#ZRU!&0YH42SC6Z1g|zeb_)YZMy4MxpU*6dJ!qq48@J8ox%N@oN+sKRsXf z3%^F8@oN+szeb_)M`4Q87k-UGdgkPi3_~+tM`@Zo1jcx4%;U9wi>_g#y zC=K`X!ha7aj|smOX1fjG=7aj z6Bj_CiBH9rjmTv;x$$<1Ir4XMZS>=`|K(CT54<|VLi+L*bdFj(ozDMT?!kNaYX1WG z^Qfcv9W=Tx>UvOKuTD&*JBZt7<91hl zvmB2MR63-rQO_>~(vfQV0G^DfF-Y%L2@e7rNIiBdoj~L=JXBMo?#A7@`T`u*s?oUZ zp08%j#M}MqQ#=6phgt7ZlzTlNC{W>tb#q%MUWn;K0>dhIyH;#R$7ApI`#AYz*JHv@1r}Hwy;l>>W=h! zbqKmetCP3kWknSM={KwAA$^isk5;kj8%Xr2k!X9D`eh05jnruH+^5E%_EmK?D3#i< zn9h4W@8$CzIQ!LuppR3x;2SZ(P=1ek6@9r^4Y~tEr7lAGICTZ=Gg*BKZ5OITE8#4u zwxAbN)Gx5oeJTunsjnu?!@DbL;azxnMSTkCx2Q_cPgO7CS?4rWg}ygbvEbH74MXjV z>J5}PR*A6i4QeA=y`ai&$Is^KlUwjuSVh&~$&!jh`BSP2G#gYrERd>ZfoGc9fqtc{ zuHcrTVqlF-^&K?dp>74uOX?+P+eAHxwoTQ$pwCj1(WAxcZrFK=N?e=wGMsE zQSU(RcvXzHx#~GsI8W^Y=Nfen#%{Xupl!bD4!ad72`Po@S7=_OK7;-5R~^x|SRDa< ziJA|4ma5kw2L))JM>&wfX}zZPd5mvr#<=Ydo#$qol2R3-hp@8jM!$)$3?=qpC!!3F-!nNC&k8 z^c~gbpzow+!_J-6SV*i?$1nq{)E;QtMGb^L52&ADho$N#*kPISqU~~3A68wVmY}v; z4Zs|JP+f|dzf#q}!d+D#wC$!Qp!R(A2Ks)1N=NyHY8B>ucl8Xud#Hav;>+q~%!i(8 zDtPu%JupM&sI}0rxB3UlpI1-7o_*Al==&=54f=AsS_{kfRgYracdC4h*F~x$(*2Yh z`pi&6rve*99YBA#t7oClCF)J^xm2yj==4|pL3x?F1--jm&4;x&sqxT!i|PyMGgW_3 z-k~I<+^Lc^_fb7#XeV4 z(2FnBGK~9|Y7?ybmD&w$kE;XV|FxR7+_Jt=3!&k+Y7#X0PD#{$uSQIVM zLGzOu1H1jKE`$ERs1C63uc`p$zbOg3{jRP++Y{{)g2`#RTM_*FVzeq z^|ya1G}*qzZ(~Sa*y6to^Ww!V{vu5Bm$vxxpv{gg{wXlt&Mp2QV2xc{{F7iZ{1`AC zy#WA1eg$GTM6?h)nhBOZzPYktqfuQw&6=7>G>myomNs1|m}o zM5ac9zJcli{tXoaktqfuQ_E43q#9pJ``(M-pQ0FuOfe9dVjwalP@AC`h)gjMnPMO^ z)fG~*6a$g{uLrfH%eONKCqn!QFn=1%{C{6i%k!vfpYEWpt=Uayld2c#Wbqxo-2n^q z4Vyz`|G}V^B-XL-sIZ?JfIGuyDTdEd44q!)Gam&r%GZr5HX-F?^O{_$FUNPP>@+oE_AX zicL_*2sk4EgmO2{`yB2G|CN;^RlWZ8Gqgpo6wk7xFn4o}?FW^7Z^CmAAn-FMlA z=L=bDS%)Mv_IR&y(>D#Uz1hNzAqshkCt2ZD@STvN`4kj2>UtEbrcBR&4@T-QWXoSh zgOG@KK_*%pK^p6l+S89p%mXLjqg2_FSRgLY_IwaQ&}4jVbcn*N&{asME^ZCV)>Mqh zl5rumlpi{jKs$V$C?9JB%Jx(o?j9IS8J-#t9D0H%Q;26LDh_w|Gn8q$)cl~heV@Vs$c}!o2SU zw_MCE#v}WxJ=nT4kk8s})Ors3 zMyKn3-az(o;m7x^`g^p}-J0Mb64&xO$yw>9d>2}EKCRV6$SF3pZ=&|f(`vypyOpUu zMrN)wnGZlZGeBx(U1ZAXSK;NRoQ89lDgOoKF9phJI14Z=@KwzEM-auQr%}+r5yk8v z3J=Dhc4&(P2^N@AVUpHBcKh_e& zoj-wi?&C*%tuGvhxw6@az=fOt#Agj4qG%qfCW5}`RwULSk@JorjKeIfo%pmgT;61C zh2ie*f8d&izhz<%a7K1l$vnc=AlxKip4^v*d0vy}&yv;pC*N&G+ z>jKj%nMI+eHMAXQlk6aq?1i#^A?IH`k zfNV~AkiO7W&+6PN(%^C8*wEA~r0Gx8(C}#u9w!Yx0ha>SU>(sL0Z)>EMxQ}I$~gsm zNuz!r5uGqTlQ>N9pQxDv0mVG(_mKe6N9(+VsM~_2l{=WO7q?U8FQ#<}w> zyqy}LHP6tQL_LdIm&~Wm-9(k&nbu)}*10EJp>h~mE5;}u8K^A4?9e?QM%;FQn^tWE zG5d>p8+WeWmX0KeJss~*eLf*wX-XD{?MAX!0cNo1Q_NoBI@7zDox*jdht>SCmvEp> zqVu7fuHj_^28=;|1M=k@5-=$d6S9R>;rIqeFRpNWgMBSpI-b21jytc~QQ^4rs;|#; z+<6hx?>xtCSJf94j(@J*vchr7wOds_F@I&QihuOW#=v z&36vpSvnazzO$5ed}k@05J6bS9*uPzaS{wX8tXWcu#Po^j}3OLg+W?6aUFW9d= z2J1MIu#Po}6Ijy(qJIFhiA5$k}Y^ot~{V~-baT;W%aNNhEhCqlf8%+SaY#7**v z>$*t7I`%|!W^7~+(k52m#{uic$QMYC!8(p4tYeSCIwn*f%ab7R(ycWuvNg47h}ZA1 zt4H>sOomtvf_agIb?h-%$B~3}>@ir!k%V>ZF<8fu11V#$jw1={*i$4#yepz?N{_IUS# zUnnhIFMY)b5PNSY9byRk*gJ!hgnjIt$;rV`B0P~4vy;(a5I(V1XkTjkf7tsD=&Gu; z?Xz=llAD`^gs}Ia3P~s-q$dPI51|E66e*%uu!D-IAfh4)HbfK;G2nT7+HRw(DunyI-DtoY9#j7CRd$!&Hu^ z-vrur^JaT>ndx~D8SjhI%nVBK;s<6R9cMZk--ua}naOl4-kmgAOlQU4XL&Z$x$*Cq zZo{;W8`9)3-64Jw<>WHmC0@dGTc-2l5z=Tbrrz;QE51So6-C~O2MYy>E51So6-C~VgBr|kk1HUbnj0u(l5d*J1W$rysZ zF#;4e0u(j^6gC1BHUbnj0u(j^6gC1BHUbnj0u(j^6gC1BHUbnj0u(j^6gC1BHUbnj z0u(mS^umX2BS2vzKw%?5VIx3cBS2vzKw%?5VIx3cBS2vzKw%?5VIx3cBS2vzKw%?5 zVIx3cBS2vzKw%?5VIx3cBS2vzKw-1E0eig>ps*33uo0lJ5umUUps*33uo0lJ5umUU zps*33uo0lJ5umUUps*33uo*ZUpPx;Se)zy_BwVFAy${|U7ztNtBwVF=Z~z`C%nPt# z4yrvonS848t%xOl#RT>FbX(U{wk#LpffqZ-< zHWIGV6qn-8)kwHXvvoX{n~`vpM#5E^?=bp@n5m#Y)JV8WBjGBIgsU_XuF^=jN+aPa zjfAT--7#Bc8wpowBwVGDaFs^FRT>FbX%0l&=NbuDX#^;2*5V#xz7e3X5umUUps*33 zu=!yifF?$O!bX6?Mu5UbfWk(A!bX6?Mu5UbfWk(A!sf=IfFKwF3L60m8vzO%0SX%d z3L60m8vzO%0SX%d3L60m8vzQNI;^i%Mu5U*IQnF@5umUUps*33uo0lJ5umUUps*33 zuo0lJ5umUUps*33u(=lfaFr3Duo0lJ5umUUps>k<#%s*eBLNOD0u(k|3jy3Q0u(j^ z6gC1BHUbnj0u(j^6gF=R0|dtiP}m4i*a%SA2vFDvP}m4i*a%SA2vFDvP}m4i*a%SA z2vFDvP}m4i*a%SA2vFDvP}m4i*a%SA2vFDvP}m4i*a%SA2vFDvP}m4i*a%SA2vFDv zP}oSgN+aPa%}L_`3osI{(nz>UQ-M|Rs*!M&M#5E^6zmdj8VOfv8b{+@laX+hW^(~P z{2K{ZY1W_*|6$$*?*~T0RhsMj;@QebxJo18Doq7u{-@@_QTXt0BwVGDaFs^FRhs4K z|DTM6t2Fzf|F;-wE?KMfo;d zrEkMk`Zipp|G^mCiYecQtMn~U*tbAo-vWjG^Po0U`MuDVEah9Euy29Fz6A>V7AWjn zps;U&!oCFx`xYqdZ^0&Sly8B;z6A>VAHe1g%Fn?>?5KPT6!tAp*tbAo-vWhw3l#P( zP}sLXVc!CU{c-4{Lgibauy29Fz6A>V7AWk02IGsAZ-K(T1q%BXDC}FHuy29Fz6A>V z7AWjnps;U&!oCFx`xYqdTcEISfx^B83i}o)?DrjkhY01{aFzZ(*f57G--fI7ZMaI` zhO6{#xJuuKtMs1$-)QCAaFxCdSLr{A88sHYREN!4`8Hgo-x*`OtMb3Z9=)6L+mr(Z zr2J`B*s+y=5Qcvb<-Z1!iORR(Dt#NS(zoF%eH*UQx8W-Nftc@mDSvejY~9M=P|I+Y zz71FD$Dn<>@{2JG_Er8`{I{R-8+HZCNBPI2TMtnFofy9v$}hz#I8gaET%~WrRr)qu zrN1xc=%LF03q&8Ld>gLPx8W-NPUxOl%D3SveH*UQx8W-N?G4z^m47taceL^sqeXL+ z|2keV9HV?2uF^jPtvycpHe97|!&UmbptFuwz71FD+i;b>4Oi(;!Fo6my#y&IDc^>x z^li9G|8}(K6y@7+mA(yE>92?JrzzittMqNSO5cX7^li9G--fI7Q*lWWZd3l@xa$5@`Ns`rxJthPR^Org^DzK-D&K~y^lw4o-O9J&Dt#NS(zoF%eH*UQ ze;955oAPbAO5cX7^li9GzaE|Zu<~uVO5cX7^li9G--fI7Q!pbpDnEwp=`rk)SWb^C z--fI7ZMaI`hO6{#xJrKm?l7LgVusb5lyAdT`ZippUyt@Zr~Eh?_Pp{fP}sLXVc!CU zeG3%!El}8BgBz#Uly8B;{wENc4v3XUzTzK@A=nH^ze7_1m5$%y*sWh<|%9l5i=I)Xh?j1l(-lpXfPvaFe7L% zBWN&l>mSw_%c=Hh+ubYlb!W&{mp z1Px{c4Q2!lW&{mp1Px{c4Q2!lW&{mpp4uO+GJ*y(f(A1aA-{_eG?)=Im|2UGZbr~x zM$lkJ&|pT;U`EhjM$lkJ&|pT;U`EhjM$lkJ&|v0}>39)uBrK(ou#`r^QW^wHMw>83{}2+pv_r3rpEyBUrLujB<>E z5!)91mV+Q@Fr%hZ_;k?4{}qDz`$C`mOEUD8N&Nh8rE&7!^W&}$^Rq><>7W*bb% zGAkxSk6E%G2SK7sn%AH?*GP0p^CX5e&q#Dhvl;Z-NOVaf(It&UmoySx(kua2M{_6| z)X5x=A?<7=x}=fll18FS8i_7x%3w*pvC$=iroEKfu^pNwXfPvaFe7L%W6@v%+0?Wn zNhWA8bJQv90STsPB$%R+V2Vb9DH;i;Xe5}Tkzk5u9q8-**dhyaWH80-!_%lXkUl%@ zc^}dR4Q2!lW&{mp1Px{c4Q2!lW&{mp=3;O<7(s&>L4z4VgBd}C89{>?L4z4VgBd}C z89{>?L4z4VgBd}C89{>?L4z4VgBd}C89{>?L4z4VgBd}C89{>?L4z4VgBd}C89{>? zL4z4VgBd}C89{>?L4z4VgPD1q__Qu)Fe7L%BWN%qXfU(9171xV38rWyn4*zjislM% z^)eDn(MT{wBf%7n1XDB;OwmX%MI*r!jRaFP5=_xZFhwK56paK^G!jhFq<6t>m62eI z=Ib1claXMGrh8`qvW)~&G!jhFNH9es!4!=IQ#2Ax(MT{wBf%7n1XDB;OwmX%MROJw z&IBXD6wPYr+QUdNMI*r!&0jF=lZ*sYG!jhF2pY^tFhwK56wQWA+({V;rf4LXqLE;V zW<7diKO?~ujRaFP5=_yggZ@BMtpR;D5=_xZFhwK56paK^G!jhFbcTePrl~9LoQwoh zG!jhFNH9es!4!=IQ#2Ax(Rk>SV~hk-G=$h3XJ%&cDOiFj8VROo4#L>YHxf+I9Nr!; z9L*J=JkgvEdrmT+;@i~8MuI6C38rX9Wy9gYNH9es!4!?4!Hfh`G!jhFNH9es!4!=I zQ#2Ax(QJYJOU)Uu;T(S$(s){N!4x|zMPYV_^b@eiI`#8$2!cdC%=! z>+SK<-#m>=q3$tEB&bNW$S{nc}L#gbr&MuH_8 z36^LiSfY_&iRR$r@utp5utX!l5{(2)^lh+2-vvwTz+j2lyQjB<3JW4@b2ZnZfXLch z^C8;h#rcV(&9&bk>4GJ;xo#=xC0Jrk@eiaYh%Bd%rDw3joRT*|pVFDZ5_3wKj>J2} z@j9%GX%{Rpr~F>Z5fE8U)ewxHfXH&HN#k`Uh%BduY1Nq^vYft5TM$`JEz=G}meUUr z)4YtWyFoxs-E7KXu*94JG|h`MSYpmVig&>ha|Sh%UO;EL-LE7)L1(!=L~oqmt8#m? z7z4thn~{`Pkq&g0+iL+zy4YZexxGK70D{hPi?@T?i!)eaZXa^Stgup&0CctyMZY4s z3mytW&{=NTy(sE3XBxbRQgf?HI|kCKtu!&GFN*g840tOLH~RnLVe3w+C~VcG)U^7=Aufp2-WY?_Yqi)UUx zn!D4mdU^df(QpZ?*RJ3ZunX|5T_M+j1-`X&9d-nUt)1&I0^i#8B#i^Uwd-{zc)LBB zs>_e8JJ|x?v@BZHnPK&`EZP*=6!i4JgC6lqDYV z3I$nKeHuyt7@N=wvhX_nRCKW2$W`rAs4_=(;y%7Bkr(D*?BFS0lstSyWuJ&ovRus+LKK~jd>Yq?36vo*GOsE zBxKCKz|u#la9kghWJG2-OAFWGI-+*7h4n$<{w&`Z8!FxSPToXC>c~Zok7I1b#x2gSX;V}Uxr(GUy z1%h^UXRjTYf|88L%z(3;;tsWihXjSw*g1#W!Wn@$cI<&k;yz*HXHOJydjv!rh~*)X zXa-{BYsx!$zL4ezr1yc8G5Z1{yzBGSX={bZTZoMSzicXfHHm06C7sUm+%h8d?ePdo zqEqqb*MKO;OZ^P#!skeN7K<|?UNU9RZlTUpgLL6MQl7`+jL65yu*2O0N<0P)BjqdX z!Idn=$$*Zs(+b$_=I~;5IqJ+%ka^}^j=L$w-xTvWN+PBPlu@rke>U`NH4CKKq`w>g z+!*y5%z<30_?9dqlIyyvSCpd8aiyLsEjpQ{Gb6IQybX=`&9glMoI?)Y2=o>J zTr(d5QYW~SBZT8Z<}ZB&SB@j)JlwKRQoKF_Xgn&i0Fur_zL#K3W=EdF3g?mS#j814 z=0vzRj{P*nD|w;RX3Jc!qTM^T32RaPhOK5rB>;2-L6ouxqm{5 z2$Mzdo@b^!j*H|Q7&|)|&K8c6uQ6F9_Qz7m=i&Q$FTsDFlfug*|))DTb{xlV*GcIkJGcyliVESiUs|7ehMe^R^|mgx*~=5PKST*rdsS( zYxoviU)04Z+tC3s)&2^CG8Ve2R&o*M-z|=KCFkXzQ>yV!tdyUiUnVgNt8YUt^9SPF zkifk9v*TEg4jTt@PSAxYf5eqzkm-rigHKsC1m6~iiM;AombJ| zYT2qG$+Z-Iu&dmL%6(c^p5-c2tKpU1tg_mxxW!fGqVm$@%G5>PT(8ip*x(4dfMBB~ z$UMcZUc^{{dFevgJk7^$CJdCC)Xm3M8%g$B1gN* zMG(0?N#tx>o@@&z6Uo-TVND(j&1Z(Py^8g&d@{<{h2`v_UA>CxH!Txq;KMB|m$^y~ z*;~yjF=Q_#Rc>opdBs~+?4|fP)D{~XZDj9U=gQeT6;jUS?P{xV+y*xRPj<_i%nsPQ zj!L=lWm|}2FXgA2hT(Gycdnyl=c>T&(d)FYu))lcoeKdOUEt2X{1Q{>Hrg?k+fxft zI)cCUaMZ=aJG`s(xP#HetSan(Ry-0WujR8nq=;6BURrGSC zr-1a81Zi+*4T?7$1;fQCU`$}UA1sa9u2nrETineNXft21iq8dYH%lv*|H+IVP|?-Z zUX0rQVXaqD=E~QieBZDfMkaM)#mFS0#g-^h%^5`v(;X2z>@p{b^YC<6&JNjN%d-|X z?-1CDadLFqK({%G|6*5u6D;KSXghw;s``2r*Cz?@+D9rWJnTXmN8uA*OpMCd1YNUH zneQ>?O~oOOl%qn#6ZAC`2}_eG&Pz~)!n}$rlPGRYP=scA6|Xu9juu@m*ec!~PHwl* ztL_0qnh)+Lj-12yV@QsGWv-mV*BM{YLNST)@hZl>WE;aa@Xr|Rq9(`w2P2{|)W@g0SljJGFz z9Whw@5YV7TIsrAI0IIhF8k~TkbB{Ziv?6Y@H}DW%y9%WB0oHq6$j-}>?Y{zP@?mIl z@fm#R>@NNDI`X`}^^jcmUxME3De^8s-Ww)Cky4df4q5dp*w?9&9-guS>2!qO@x0-~ z<7iGyT>u)iiSIPhV@pucFrMc9#L=DXt}Vku>(0cD_y}=B`1us{DL?i5!Qd&KfvQcQDV>7E&q&mr;Rv_d z@k>bMy5;RSyif34ml0X+9{4K}xKrW?*R6J}ybrTO51xboJl=1FZa$32<9#=8^fva^ zCww)g`0PAJ+WHCG+9=Q3pRuY@{6#*O%jwu-cpZL+Y4v5u@s4l^*%l#dxQO%RRThtO zMxn3er9>Or>k6rU&rzyB*;&#~@R2m}B7H^9ZE6ogmnKaN#*V ziQ*p#iZ$USzHV_61^AQpcyHG+T!I(8YQU z#AYUX6OtT2W`l2c>j3gFM2)cyAU)B|dw3H$n2oNpvO-mSK~c+hA!^E=@8iFyH!1KG z(U(sOJVpEglU_Ooz(V}f*G~?dMy3QOythwRQvz3!_H}Af;2x4YXws+~Fx>c;J7iMe z9@2j4lpcGcyYa7mL``}b@2B~%{l!y))8O0BQd2%S&Yl?Gezcl&$&mmF;a~gJlLGgV z+*y+XKb7{MPYT>k+RvO6II^_gIEkNs_%Cbxr2Audh{3EB<@S8*@)EoWY0R}lbK`}$y^cnI z#eKtn-Sed{c$*&;&v_l$bASBljn`6MG@3f==y_f$)9$GF2J*yGcfp#F!P?k<0Wg`vC424q5a7aAP8yD$^FyIhG(=2cNdm4_x->j@eQDlcRnZwyV$%D zNVgsm-+D;A7T*soz8_kAKlG;lJRnefKeYIM=m+vK$F%rChZf%t zExsRmD(DZ@;`^b+_d|>ChZf%tExsRGd_T1KerWOi(Bk`{#rH#t?}rxO4=uhQT6{mW z_U=X%N zpKXgl5O)qO?i^a&IkdQQXmRJz#WV06sKuQ_i#vxFcMdJ?99rBtw77FwGyzo={qPy{mOK-dxZ&&qU_v7WRe)$&co?iRc z@n3vedKnlxo&pG~6R}VFpDE&75pnLV6tV6v6j60MMSKkr^?D*|cX;heHdZALo%=Z0!il`l6l=7q!;gytm6Fkps_~`TY7qjWR<)I`jk%e4#_HI z+Ioj%l`-wSL$b=ZQjR-fcqZl8BZf&695KvvaKtdv!4bnuher&Tw1*sb#PFp^yCa54 zW3krRJy{HI4;EdIq`c4!j~JedlJJP(50G(34D%hU_4df_Lr&}MkzGm>czdiz(T_-W z;oH%~5yN+&C_G}g2%j6Rv}!AjAJ?+`vKZbT6k3O5D1qJ{*|iEq!4bn-k#{}HtKpgL6K6jTE!>CP7BWD3p}=KI*-Y+;HE&K4$3c((8lkRxXczXu`iY+;(~ z&K4$LH@aBl_TR)LT`Y13(olD{u&~*)h1sv}Y+(+PJ6o88@6Hw$VGVGx$laBb*qtrR zdFaj-re*GIVfy#DvxV6_ymOAO#0QY@Y~dPwqI72q)7;=};n$EL7^SmaKp z`$urLFj>XL;$sxLvxS)q+M% zkylLCTshx3uMdrQ*`9BlCtHL&-#D+7Cb{#C^U7$`7PxuProF%}%Oh~}$SZ$R>|;fG zj6<6qI}3#Av7=Fv@l6-yU8AZm#RpY;gs{wMFaAzfe1z>=2Eu6k>265ZG98Q4g+}$` z_-4gRneNXWxVJrxxQ>H~WmdY&)A(|x2H0#`=`OQKInZWPOXGuCJBY2WjK2#5)L^Fj z#$yFY522#E_$j0r%Jks)x%WZrFz(a!@vrfTQPD5o8yQ#R9ZuUDmYnd-v^t2;X1+j&$KgR55|YaH0vE8e|-Rb8z2_Qhy?4 zj1Ac<9mN@uLmXw{UL20SZQ%@8*nJY4A4@&|YkYgcuiXBJ5BPN9?12yX@l;-#pT|f0 z9>)Z^^xsn8zSG2>*dAT(SWzTD)pP?`duCiMwd_nar56PKE|=SwS9Ct7!gJ9NLDgG; z3C~GQZ{c_@N{-_D*whzUwVv_r|2!Va(%RWR|pb@^;W1bY!C)3 z^bry2744wZ+oF?0hTD=D{+h&ayJhGzlf6?H<)nM{3)?k!yLPIk1>NAmFHRP9(Su;s zB=kzDfKdht$L+}X5T}YkQLe&=eh2nkfF6UR1F)WWZgP40msac^_`>`$?5ZH(D7V6% z5?%hdtDTP89j^8S&;XkP5;`4JIH!Zk&5ra#K!VG!{K`rtUw@cMsg|#@CEo@|dSE41 z(l(dbj7<3f<8G{I0mOgyi)NkST6ZnkS`P8g7YH0ZqT=&OneK@k8t0iZ$a73+zD1h zI0quD*3T{Nd>vG+jBugd8iBmdvyfjE`2zVLqY;_K7epG6yE_%N;%l%v!Z9^z$cwMR zg%NJtpCDf~rW(i5d~O@kA58qIwCJt*a2hxWbv5Y`uX-;e79mm7lCtk?)T~8K-vvlK zg+%SqPS_79;6R*0iT$YNSyzKwOHX|hNh@$FyqHtb4~hP)6|s9GCt@!|qSm+x8Him( zv6a_;Vl9sYL0f*a%gn(*l|VSPFGTrIuKXmFk8tI4QJ(RsWj+(-hlb^xZk#s29G7=a zqBy%51t%ma%91GP{2~(?eclZa*{5#@cR*u&nf zm}li(T;@7RIx|63Ug^qjNBPxZIW3O$^U4>y+Wr+doDE(a%GaP zpPJP|X5|g8_Qg_={?%pJ3thU0y-@zRD{qgb+*iu2;ul=`lc3)-qz^iHi>sA^`pjk6 zcPE6TUga;YJdYh5brbp}5YhR?O}NT-uKej@5bcsgv>}P8)RlkAsoU3O*pd$uMCJRt z^4F?xR{`e_yP%xK<<};0b#b+v@DI3h+BG072bZe%%HL07qPq)3CVM$xS-6!(oeLcI zBAJF*%H_Md+IJ!QvYoLXo<#81P`OvR%9StTj(wTSu)VJ)5nb=f`xJrbc9&r@eoZ0@ zu1$7BUc~GCv9iHE<2GaryZlrWm6ZsD?>N~YpTSmAA{V9OWCM-DU$RavV)I0TS1On2 z<7NK@4$`ZA#mRL0jzvTEIgvL5(?!HuM}WoTl=7Nnl};C>=Ri)WDBVvu9${Ye>@Rvg zrJn0{rlC$k!gfGaY?i;B7)* z;TrA;u(+I_+e1BlMbFceD{bi~9FfdGPk+%N_(s$I5KP>FHp99U!?F#Jt`aRyAjWs>WdU! z$rmAS+xL}7xQlt2BVVU9p#BTwYfsy$-r2k_d{v~3a|CFV{8ZC%q25^Q)gs{==B0fXir&F(q4(^a>V1xP z-6x6Ey&M5L(~Tdm(N?deI16%Y`xXkv!_14GQ$){J>e+XvdiLgM94gioJA%YUd3mVk zP?1}f7w9=$I1Xc8^vo1J%aE@v->IHox!!gcu5BOKd4l_E*B)LsZF_bXJsTjWclkHa|6e#P^??&2!@C4b;-s%Mz}G9RYU^{#4UG*wU=tEYW)~axl=uD zxXyo6+{daM0d6_vr5z$kz_q zsorO)cZ*1gJA%YI=PNj?cZ=u+;@h?Fec>3uyy)2~dJaUsHfN`L$~ixu5$oRjhn+}R z-11XRyxp~WHi@1~A*W>K-RR;?imz>6K;GUkJS!5M(&t3!E*+rs6DPCzr0K%Ncc+NB z&k-ahC+}0O(z`_IWXQ3DcaLzK$GkM|UeWVc>Un6Vdg`d>Ph#2MHSy8b>bXkv z{0cdC@UBvP-_W-s^vL8~D-u>SFM8LB-gl5MKQ~D)JzjACC^tp5_qd8rahJmTRNTya zeHuAw&lG9n|6mUv46Hq8i9LgGc)PXdEU{-E^46ZEBH<W>I0vzjRIEoa+hMuKUXyoWN);o_t;TeAG_H>k+Rq7!bLS&R!4W z_*O*TtabDHT+8J+LE2UC#Luz~z;?qoCbp+`m!5hN=G)t~-KFuFy96UOQSy_SmzlMv zNIVz$+QuZSgHiMPZ07Q;5~^3;w6Oe&E-td!nMQ^ObYGbvyrt!iyd!-dVJw%*9|XX@B*>D z~NFjT~Eq4=R9dJFl7$%XQLQVkQS zTUqMWZ{=q52#ede#>`_meyWLTtg(+!+Ho*pu!z}6`oAzMq8_8DZO9HscRkKbWdW>h zx3k`BK%;q$O7sVNQO)nzl28^o*2W+r;0 zZhjQslDhGAWrQzXM_aG1zac-=dUdgJW4y+|Su6MQ##Lb9zjg!01|C|Cf#;N7-55A! zWe;i$oU*cqGzLytdTC?eM5Skr3!J$S_op#%sL~r71CJ~Hd1JTP`0j;&ZH9~syuft2 zYCIAf6#wZ18$UP-4qW)xrg41W1Z6`2H3mLh2m#cHt7+7WFTp!kg-28z)851SLp|_~ zT}C;xNr|QJ!T(g+@u-XJ!yfBdhQG}nq0oncBh&&U z14k&Pog>sB@-%aVTER-|2*o5Fq40Uei`_y>m9`N2Qd#hS8TV&l3cg77I0q**{YY~H zM<{9u9HE#F9HE#F9HE#F9HE#F9if;B9if;B9if;B9if;B9if;B9if;B9ii@og`p$V z{m6ulP&7DngkmOigt{1+&=HEgA38#fMJ9BFS`TTVBh>TAgpN>aK^8hf-Gof&2*ph3 z2*ph32*ph32=xszp(7M+3mu_eg`Pje{b3`WBNUT?BNUq(I6_ef9idJ~S$b?ca@ibz znl0Y5EahlQ>4!mS3r8rH2aZsZc8*X?TTi=GJp6im@(vuKXoGWvlB9KnlH@^{`!4Pe zZt16sp;+<Q+)#?b<>IkJJ2#%H@I9h_>XbFO& z7vnzsEGoAjvk(m za0vQ)NVrf-5F9N*aP+y5aEX2ge=pS%1V@{ZIG;j)S?+mP=#>TdSfM2dj+P)e`r6?L zg45~<)#?b<>IhY$%xPE+rLB%ot&UI#f@5qD9AksvnDyOp_o<8xf@5qD9Aksv7#jq~ z*dRE@2Ej2l2#&EqaEuLtV{8x{GX}3v&Q)eRWG+|62Ej2l2#&EqaEuLtV+t`NS0QFa zo#$Pk%wjz0tX9Sb!7)7J<|1Wm5FB$n-Z5RGj17Wg3b4~(ri=}OV{8x{V}sxr8wAH3 zi_d$1QpN_sF*XQ}u|aT*4T58A5FBHJ;20YO$Jih^#sf@4XbFO&B?ykTL2v@%=OfWv5Kmgp2ZY{N;Ejde zw+Rmu`ppaQ%&SKu9o7BuT%M|LxCD>Ky2GV-g3)K6hKCouFK9CK_S5m4q4zrnhnVWO zAty^ejC8iHU5STKlW{Iys{m|1?>ta_6rpK>ZXI1s-Els5>vHgTdd5YxU=>PI^sJ?{ z;O?_%!E)G9`my<)m`E5Z9VaRN6*5GiWHrPl8Al+B~iU=p@JbF z<8PXN4z=m}S-c5~>96oNLl5hv(ByugWRp{ni;sxXH6+k6D*8ZMNFRZwdAevB|E@ia zP5uSllcK+a!4W+cB~jgghNS8f*0ISxx;|ZBfnkX02pW>1&sf4H-@BSk?uo``=`MH} z&(<%4w~cNGIXQa6Rd@*1wdlaM`UiAEp6+=j-W=)b^PyHR0I$){tp!L)U-~DUyQ6!e zZ#tM^v`U#rT}OQhb@7?e2+R%|aYS@G8*wL^?CEZ3q|y`7MJf6z>8O?HoO)A+zwCr5 z=#2OY(I=Dm&yOx{2TlpRq$Ti@mcUE;h`rhTV`s4W5_m~V;3X}Am-Ok=*nA1Rq$Ti@ zmcUE;P|#;-3B05w@RI&uDw{8Xm$U?4(h_({OW-9fftR!dUeXeHNlV}*ErFM`1YXkJ z_oI`T1YXh;A-{{3z)Si|yn5=Y*P^7GmcUC|0xxL^yrd=Yl9s?rT2066el3BQv;c#RBgSag^Q)3YRmwD>py5_}SN?pOG{S!|;A)A`^9?AZLo_bUp zERxx2qdP!)tEZj>UTXE!(-L?|OW-9fftR!dUeXeHNlV}*ErFM`1YXh-cu7aH@m5w# z;3X}Am$U?4()E~JhiD1Bq$Ti@mcUC|0xxL^yrd=Yl9s?rS^_U=3B05w@RF9mOWNy< zce`2wFKG$9q$Ti@mcUC|0x#)ZwDXaB6WdMTBljVap^w}X zq<21YeLI52`p8*&>m&C(=mQ@)rUM^2rb8dOpD4%q$StHC>mx^+z(&VNXonJ&`0iUl!QKV+bDn$k+O@w0d?Rb zN6x@UjwJAryN|VQP%VPM*QRuG860DD$ zK~dl%_Y(y?bqq`{;YLWZEBbfeB_u8 zeB?O%fsY)G4t?a@0e{X_ZZEI|u5!C!?KxLD&Z)pvj&JM(S2;=zT;)g;y2|B(S6t<` zBjH@-Xti^dBcF4XdyGlzDo1;rtDLY|S2=dCbCu&*IafK(0p}_w!WtUrD#y9(T;(_& zovR!zbFOl!G>6fMa`$HQ@KvI@s~qT2d;9{AR};!$#v*IrDz^aifvX&E5CT^@Ue5FJ z@rLF(SGfbgmL7W%e?wQf0|C`>u5t+@@_HqV$SX=1k=Hw6L|!pj16Mg35xUAzW9TYJ zlR{TH+O!3(a-=v8?6S@hu5w$&K31g1IJD_8erryTF)C0tpS`X{LKb?OSMV{OW>m#R zD9MOa?%oT8AmY=?(@8{4{OnzMzYygHM0^_fDv9V8N~(TWh`tV@5y`U^{DuN`AK+O* z^^Kw=Bl3Jm1S1C|5ml0?f3Xm42#DB*{R5(GFLeUa1xu-OAd531`5i2FK;rQ%4Jh&4 zwt$px@yTvDi!&mzWXjtEN<4S1Bjw?Egi#||3=p`ZENrBrQpL&p_aE>8gx~M>KOhwb z=EE6H{IE*ZDQN$600?>rq@`Rq?q^=ktgn!BjqAHdyq@BhRVk++uR-1hyQxx>F?f+x zE9VvQaN%`7S{<395Nl;`b#ga+3f>oWzk#W^B|)DD1)nF((|&5fJWkykFz5FGb4vop zT=JW1;6})L6&$5Rj^&nGkFb&}oK4T6R-xgnJpq5=5e5=^gq1pvu#%C^0+NS(a5b#`);6Lvf((8*PPiw)RN~O}038uWpe2>kmk*JCb}vA@#GUJ5 zW;Y>QAl_W-xwFxEt3aH&HgI9k|E=ohZz1&&&iEBY;2r%kvX63=e8p^pQ*k4w`qJLW z@_M5lj}=0O~_WSxD>=s@ zF+M-uUhivstW_=8_3*}z%lpj1jVzzw~8xMVc&bHg;3fD#hbua z%d&p8$oVA^uU|b96OiandjmF5$WL7(^YARx7q_f)>O4;rUg#9gpu&&l2MQkmXD!P_ zVH$>56b?l~6b5W96wXI|am%_;p-lb$ZU%?zCZg`3R<4_y$lj75xo?-XWcJn90rPWY zZb{&nOU`tIvK4bU*4?g*g#e{p?aIGIdC#z%E2h#bdB9b2S`U#*fkl=);mUsj)AVE} zf;dasxE`g*xnZqWQs~N4@kV-OSWZ==ypqF`m~L)ac~(;8V_~INa&uDo+ezh*yYgIU z`oWdcve#XCXOy?cyKmV%WP7N@nrDkYO`;gkjDi~oDYhq3Om9X}?I_x~F`|}Jno-m^ zijIz=7bvc96bosG^k12)W&hoqTub#+lPaGNE4`BWN##G;@?a6=MV4n~zd zfN4+`TsQ0%m&2>f&D<+yxGipYu&$con5Gqio4e&h6n=|IS0R|!TTaK-WoQ}pG=aR{ zMnd>(yGvx1Typ+Onae;^GnbRY2?wA2)SVy0q~7PFY6EC`pN_;ANYt%#gbc|7ixW~g zc{nh@yJBO{h`jFbuBG8Q^jA67ddrFq22Vl&?kDbpZtgsC7tqZca4dJ#KXK1h+*vFX z?<%%+kZi|mSv5$of9trrdV^PyV>Q!iZpg7(IE3sXAuB(U7mjmTJkc2yAv=Dmi2;Cy z2=TchXNouUc@Dzq%#C;CX+li$@)eY|fW0}=Ri=lPUs9Hg&;lyMIrPJJ@DAa?&m6XG z?~t?{JzO9`dJd*6#OQIuRSB2$L#VrBIgA{3D{Yw=VB;!6evaZ0ffnw$0;7nC4FWB+ znaM*0T4*y9z51IU#Z7cKUil(dfN!{k7T$^cKnpDdT-$5#MzGf>yH;g|s(8U4$vsj{ z8Fe`ROZP@6Fo>fQ7{oCF261!(SJ;?@D;%8w6OK+m3`c(jyZA4A(C7q8adZNuIJP;K zaC8!uuonFh^?2li!xElQWU++7eM1}9ibYqV16r|!UixphU|3tRgsoV@b6T;4csHRB z9E0b0o!JkYvEB^luR{F{cDU~P+A5qfqK~WOXB&o>>ZLQr;$#nfH+JUU`fk(~>&u70 zZAK3ofQx%8mar8|*or08@6^HHL%%T$aZdIASUb1s)wq4VO*f85P-UIBtLNRWA4TmQ zx?`#5-Kh<3m+#Wcs^M*@PsGF2J^KA(+sypIFcB3AL75$k05%xT-2V(s`qpOGFSysQ- z7jJ6xK3KWW>K7pMxmGM;E0(YoOX%&T%xWygRxDvFmJsikRV$WInGRa-s|m?t4y|IBpT2SLT8e_@FD3i(AE) zl<9-T^|CULnNJ{kvoif_;J&QPcln<8rZPQoje1L& z6%9CcPnq9wjeJL$L+d^7U1k0Z%eDYD3d;AC*&imouS_FIwkk6S!v3Mm+qhtUpiCAD zKUC&ccI?0Mszug6or?so(KF1ijca`a#Rj29w$CCVduG5$vNcPLNQOF)wr z!j`s0YXB1aUkVG`hfVv}u&|p*_8)|WQEdVi*4BsgR#;doEUfha_x~g;>|QLg=CH7{ zxX}J*VPU&KMF0!C2kCzW3%h{y4i>h9^#3L->=DXwu&^;e^2n(~>5Ef>$AuP;hLs-~Tv?adV zG3b>VrUO_Q)BjCaSRq&fSXhUSFnl@QZ{!qmPW>xb7->RS*qe|eurNaG94w4h|5I2P z?RBs)VY9F>cCUklajYCHjC0_RurSVL2MgnLbg(d5=3rsZQ<#N?v3Y-hg>}RSF$W8y zx&I0l)*UheSQuFa7WOO(9W0E=02X!$MO#=HZ%_X_urRXj3>L;4ga8)C%XvO9RnJ4T zgN5}0TYBtD{0(7YrJbD-c|8+G{MTS%Wc}B$Fq#y?!e~^7K-qj0%5uk7=8JyAs;NB;B{;=67pwt2`mx*-vTMQI3rvQ{MsqRqYi!o z`l<>TVqR(i(gm}&!?YnR&WO}^jwUFl2b3u|P=S;uvZcdWoDu1rOnGKNiJRu*h4NQW zj$|<)XO6P)QGAY6^(pL{;vE)UbDLF%FUcG819(_{N+YZug73W+9@ZcnO~_j~*oc$` zu<@b_)X(~nY9!yGGJuDTO6i6{B#NoW_TJDqI^{#qUy1r2L^rB2lHaci^ql&tQTQXP zKAzi4K30#F`pBx!=N27wPWiwn0em%aG_+jl_9KjACLj z5+5Q_+>*D?Us01$6Y=^yh(s9^Pa$y#6R#j~1rkLc;w5gt7!Q<=Q4uQr5p^$uD3lx! zlpG6(N`Mm1ch)XIwhK7QaLU=Lp8+6`KSQ3Ug%}*z^_xk9+4St z_7#@#WaRoXAlE1hUw)Sq;|VEC0EFv(4(fh@jlCBk(YY@YbCDR%#7rdK zN20hTZ=VZMvu7>3;VLASF>xajA2V?m65aX%-NB9t7*hkKzjUTf_RCbzgo11KabIH)2D`q# z2Gvg{l%ab${eCp1loZ-v?wkQ5_(YY7zlHSQZ>8zl)>&3a|A`_e)|d%Xh7` zj8!ce=Q-L>iosYBu^MUj!Im+5Auc05V)?!1dWGHDgp@@f+}jb(!5f?vLP$K1)W*an znl>#mcT1*Mx+;nGZlRU=(}JvWvm^T(bbEyjT(b8oF7W}|?I!WHwGEpDwRRU+Zm7bSGac?sU&Ph^Sl|=DIGYU?3P*nceQ5?Zp{$LV$2HyH%Eu)cCSwr$Fuk=Yr z(GErxISLsB>5TW1_{aW{9|nExDA-+xCG*pk9j;Pri93LES71&PnlkGZF0fc}WW5SQhLA+e9cRy*Nohq0|cO zu5@jZu7Qq=%lg(NT?g9oWYiw*23cir*_NeRRZ@(lx6VvZs_iD5A2kg5v=m4qvwmRhT#z?-%8~( zgmt7--d|KxId5-jWQ-0J4GQmjIsKc5h&J^;WYvnS zAtI|*#&)QTZLN&!Fd5fc8Pj?hQ!Bkeq*u#$j*zBQ%UF(-v83nBrRUn{=H&511Ep}Fq#25>7RZDkWgS@rW z7fU0f0^8b)#6if*U1A_Qw5_8mhHSC#ED#m9ByjeX-|1}Pmcu)t@6=>0ar2#;^2d8W zTrehc5`E1}p4tHUbu!Ffe~1Rv$tZur1zabC{4LjRos98!Gf+A}di;k$pdBD1{393a z02$z)xK;+ptFKd2Y;?pM zilN<1UG>Ne5hZU>aLt&AH;e-tXb3y+E$O$_s4s3=7mVw`2RW`!QQ@cC?DWI!nfz1} zZ=|e&Ptm}qAjsPE3~e%v$jS=ZME2c~6*B@kp&8GL8JD8IxMf{nMtwT_>A_c>30e%` zg61X3n(!b^costJ;iV7C;JH3}nD(TPbp`}dLIXC40VSv}Zdn%?Fz^lb!)+A$pfdt* z738Oycqcko2I@8%0W9vEh4}AwQcr+X+bMU@h|2;a0x6*pcZm@%(1@0Gp%LA<8C*rN zE1VIS&hk@DyqB>?tg%Meez2Lzc0Q~lYx=mrqN{1qBxGe=0+FFb*NR2wqQ1CgU1-t% z?3N3taQ+{* zqr=H=H=9|k^6DQY+0;$J)tzPdsU{u=%*|mM$$o*=BZ@F>zI1de(ba0d<)G=^fa1}+ z;;FSi62~D?-rkv4jGMjieoOH#R-TUclqaESyvOv0QD{g{&G@PPMd(F=&6;{8)2pSRVNu{^sv>W#Z<9uDHezwG7X?pXlb8vbRU zKkk9+uuJ1#_MCAEfc*FiGL*-E?G9Jt0lE`f3%A3*3$ zof;pUylc|cxCC&1Tmm>hE&$G(rQ-q^zL~jOfT8z2ro0b&vKdpB;mTnT;oZB$0_THA z(-mp9`3J2-&$R;QTY>ZGQKOeGDGRKhYKA@kFX090k;( zz8~x8d);{izQX8}u)coO%SR&Mk-i7_Y(Hzh)7_>o1J^J5Pq=;iRsXpk-X!bOuzr8j zy9~vV4SF`#><+UP(mcQ`^YK@iP6K)CW1fXc5oPuTPgI$&kV{qOgE4@~wF2i`f%C1v zdCyy@%`Tq|OL`??HZ;O847J$+2`{Is3D}rY9)BE6l zKr56)^i=$f>f#xM%vVk0p}faT!JAcm&jEO&q8IIrm+ksi{Eh1y_u`?v+fbgRS4_sc zA-!ZjeCyMXBAugOn+`aaZbWTc{Ul`O>8Bv4o!*QRt*iFup}Y%`_Vqx}x7VwntAkzw zu8#UpNbaPMhgF?*f5_~j-vIqCdIzlSs(+otr?fKIkgvCas~`lOzm(b;uR#9`$oJVK z`wt@DsWyRpf6+jCEAqV+`QD0r|4$;{PsAc?j(i{EW1;=eBH!P^S`Lu!3!v^_A>Su~ zCP2QgC;h*Pd_SFX9P&NZ9&-N815ux$oR^NmUYy;%j&lBpd}pykzBeK%pwsX`)OIKd zk?&_xz&}U6lf)t4FGe!Nt=CMz1)^*cr3J|MCqik>knb#Z$oJQiC0OM9S`-Dy_tQJT z9E*JCObC$gEKWkc+iZw@x7iT+ZnGis-DX4N`!a|MkncV14L%y$~3X6Pa^ZtN*e*@+^Z3>X@Jngmx@_i19(qpVhk8x-N{JX*TM8UlGM?w~QME>S@1zY>zYh=Fyl;gmz z0MyQr+BYQi3dV22(i*s{5UmY}PQ_?04v6Aj>aj={98FZi5Ef@d>bpik0?nlSOF)Tp zN(rhjsKNI+HIl^uq9;?n5>Vn+^f6NIK@-QY7(jGKS$HoM?WbsI$5@K!+1>t!@59S> z0Xj#{Dcw(HfbSppNNbTn2MEWA-H^ZZ5j1LspmW+!Kwe_b9w_+}n7`gY!$E@Xxq0^h zqk6Df0A00v1VHse)D})oU{H&Am|%5=wITeleujFe3%*0Yg1S?|RNRuF&j@^b0Kk#V zSGHunO8puzuOo9y0>@l3&UL^z$m)ou%Ta{kIi@R}*eR$T>1ypcraY*y**T_}ace$F z=QJa2dE{wXp(8EFTh6kXE;ECTDPO~peUAOqKGn)giLjCA?k1AkLrtHXg=zX2nq?0) zeS!355)Ky??C*=ro{g+M)bu6pPKiTJU*_aa9BTRsfdgkx4$dikbr7=4r$90w0ZT$qpx@2h2p&RK2H>Hz7Nb|97It-`7uyR1(2^i|^g5+mW_AI8fR5c4 zFqe?IB|$KHXS+_C16Q!n>QqS(}o!kv0qc7UU}6|<#eP7?W#&B$xKl9OEJ&9F!3x9o@WT`l{eD!CRI z;Ib=|m0a&K_kwb2NQo0VT{-*b=%n&oH`**eH!NpA)O#fpUFD;wyvbH3BXPZwB}v?W z-x+i9KE+ zXrql>R1+|9YX&}x*}RbpM@_C0ETEhOd^YO(a^DK1qy|!+l>P26ob)a0+@$x)+tPr0 zDD=~)ol@9G<)@lB*=xjzduW83Vzu7KrTi?UR*6OTlR0ggGa`@@8u5S_F%k8}E$c!f zs%gXxlyieKVz{*dJ5>Q%X3r+QQMMNdvS*Xtn1d_IOUT-@NpB)yM&vYiS+r-9-b|U@ z_QtWl+j;;&?dk&C8X)n^)eB+w?_j+f>Jk7cBBqO&nI+cpno8S>=^q$cz6H7LReJM_7)ZYU+#*uMy*xh@2_jz+Wl#B<6-Y@-!hPdHL6r zHHYIh&{d{~m4{Q7z#!*P8IWt$n@PTR%#l`yq<4apoiLqh2BDFaN4U%Z$k=mH_oWt` z7we{qSA8W78yg^$5>PNsni_$EjqBW*dTRsdVehdDKdczY)ui>j64Z^WE1n92e0lG_X93G&%^yec2NEf25 zj|d=L2&O(f0qGi^fOHKHAYFRt@Bq@KXAVE|gdp(x$N=4Cqpc55V8^^~@o6;b<(`k{ z1Pk<@%UjKlOAi> z-2+^UTY+A!K(AJym)Tl_553BK(+^*Il_}X3&*I8#>5msW$}Dfh$6jS-VCl36%xoy$ zgyXAC>l zn#%PU{Eh2*oe21Q3vaKpHBYc=qr2lXOs;MPdbI+*T7h1zK(D08*R4RWR-jjI2|siF zCxBj^s{lFpIyHB0e_Vm$C*T=AcOIild-3$+kv^W^Oi?aW{^Ha(CZ=lE;!ImET8~%nUvT?W=yRh2- z-Sbn)`hS5Un-2CCD6&mrA1j)p$c~eeA*dBB*@ehjESWn$weJ}yLD1vw|?MIBMWc%E@uXA8Z6^FFX|3pqteaH#6Qt-|l^Zk5nt4aBX7@7>>`JtuH84lrtOjvV$;rWVh_Tbwml)RH;>!P?QJ7n7nQWL zN@t^%VZB*<0{-HtN{|pC*4rIbSvD*I z1yRw_Ng{mQfQNc1qG*Y$T?ek36kQ3jH#=!GPTJDX8(9*|;d5(Oiz%lwl*;|v2u@n??W7*4ETlgPdN zWbzuXD6OsS;^$#cS63FQ_8lfh=R8)U`7#$wl;0cJwYkvTrIjqT1h%9EdJIsSl;ykPwXAS3LmDlIUB#MM) zsjb9=^Xu%u>1wiTMFK##4bp7qO_$E=axl)V6gbj;vc;4=UyS2299ydGa!(zg%D13= z3WzIOR#r|&2jEvYkeA8{(&dAk0NlsOPc@y2`B)``HbL~NDRzkV5c&n76%!Ly1VTb9 zCRr;Ur4=nJLo24!ib|1sN_L89e<-wqtHQRvO03uhQQhUlP@6yUkl-lHDml(^8}hby zYQ!!c=Ga#bbDVx?Fv)5~*UZBr=z<;W_HM#D+9}6ZCi$tRy@8stU6Aj(z^b;nH4tD` z6^g1Ja*$tlk>wpu;e&V~ii)-kS+-?ohQhg_+m=N|_;|2X$=QX`W(QNIiSSEM%eJIT zTb@JCjz&zRKQc4o$vgd zLljMepc*-r^2ejFa-T-FuS~|D2cfq32xR40#ch;!AhNZbo`KlVtY0sOSecJ*+o79~7hwkQ;(6-}Ew&Q)M?I*qc<}Jvo z$+i`5vlZn>M!f#$>vz6E<}hSzlisD^y^lh~cQz@|5H{&OY0iD9uV`5pcJve)_$(EE zo@wU;E?x3dO}vq@20lvzzk(oZ)AO`x&}?L7g1tcYxyXtcft=8cm&A;RP+!rqE-+&N zker@+_;1dH#8`7v>nBV8VVa<(^b?5Y!)$oaLmOz#_ksFAMyUQ#QD1sA)VHh))K_1` zHFrCOu5%_Nb{*aZS`%)!CiE2(?j-d=kZQZ+E*fz&veE~El+cKK#E1`QM9aF+h`VUS zpD1=8XG9}p@~4`3$+1RUmD~?DGuh6DwPfu)C$MN8Ejk=ou_zE3T6B$AbQS6=TGoXY zb>=>}iVBDSpz}s8-sirevgq@*hQt$Z?WQXHy>U|>68!%>CK2Mz^dOxGymUV&Nfju}SPotb- zr#CHNZ>s*5l_yeXFIS1(RepGyVb918bRxNds2y}W$&ZxWPpGx$YaU5%#Ce*W&NBQ|6EOr_{`-=w&9OK&wk@`w`yAbRbf-FSK4{8IQM?c8%L|Y=3yD7O zJE9L!khsS4?gD2);*keuLH1VmEXX|e@1ORw+001790056l0Dwm&Ai86cu)t%Iu)w1d zSm05kZor|H_?JCoR00b;DuD%VYz_eShGPl=^?Lzc@>taG6`1*>G3ovRA^+9m992&| zqqcXDCQp2$poFBm1(T zLp_t@&sJXK^=c$zujBo|>(L+bah=HMagOq$KkkWQFQYB~M1NgCl8m`f6y45rZU&LL z(chTvka1xQ>ED^o&)5zD(H%_pj-LgYQBR(0E91Cn#&J!Osf+(WNhy-4kKe(*iAtt1 zo#j@gpfMOVQwC;CMy5t=TOU7(HMQy_ zXxQjwZeU+s9=i^?4$(DiWX7i$$LLxny$oDjyy!YMHX+80!H-ejUw;c-C&&e_66Z0>N(IZqTq$h zD0gN5`;7^?|HY$HqdogVgIimXtJ(EM+>s-D?vG^eQ;~ElE|uxXerQj$xPd%LD=@nJ zVpehmM$cn1EtY-<{)@#P!{7A#@yD&jR2D=gLwIVZc}#Lyrghkh$!o!$)^Qe-2S80) zr*oO)VoiU2ERq?rSYtmdMP;0eHTENI^5R^qv0ter7UyD(ZD%?+&cz!0jp+_?F4oxZ zOy|eBSYtbw?w!fS8bjC;f?09f+6brNTSSYs(cI@63`GD>jxso}(AL09EN{<4?O->?}yo>Cp!Km)ZF= zeBChfMj&lA*W)T=jz@WlxfXW@5fdAXRbkF5gPrExQp{^}J!;dVtu%YXsw%U~I6O$2aiFg;oj}vqtgC^4wz&_xQ9pAP zIJJgJYu3_dX^nbmX1ntAkuIQNt zb31BBm?s9}C6ZYPu2JUyu=gg=Q59R;@Tqh<>D0;4ot!!ea}q)bnF)b}Fqkj~0T~1Y znGsMx5ClQIfDDREDu@GM6hT202gDIY#R+i$LA{QsIHP!-uUEaO-?Mks>Fyx+z3=<4 z`~GWv-=fz_r-og7@7gt-(|w+PDihxJQ0vgIo@ye>YgJW^W%W`y==JG}iBuI6sVXK? zRZOI+m`GI}f)D)_6R9dDQdLZ(s=jTBZ-x{TsVXK?RikPx>n!ysbPiQp(Tic~Wq5wJ zdY}h**3}@$k5IcaEo-D2jb4vZt>FJ?buD5$Mt$5HpXe3cWsg%gpzS&82aMo&H3ae# z)N6>|L^TUC=c=`s3FoO+&@f3UluuUlqx30i17di-YK{?^s)C5XH1#6vUZDCwa=N+* zwq~d*$X}?&qVF@+&xrOcwKLnYE>fFdceY}Dy<&X5Vtl<~e7$0Py?PXJn5P(DuNYsi z7+pc zqVEM(szDgXRq9jJUa4-x7+s~FMEYv=SM+GLs>J$QqwdF=x<=I?CTrD?XmzbhMNFk>0GT;s32F6&7z(FG9l>bqxBqs*e$?+f{#P-lj4U;X70V3?>yVW~biT9{cSUdNswXm{7)k5=qDz%Sg?Nra8_I}j>Bl3V!8081m3hW6FskzYq zu=)t2|A>l(&M`<(g-{=BHFFvng}Wf+T>)raWaeswmYdO#h5&R0|xN)D=b;q4)niXOeH zEC3R237cs)fx#q^g)mRWXsOtBF+I379BCxSB}S)kLbUCQ@}Zk*fPC#xYK~qY<)r z;qIfoS-6j5k|YTCK15#%_eus^hncQwA=)%bch1yiJfa5cW()%bc>0d3}dH7c&+%=d$U4%OfbzOz~JlgdT?wObqJ%u|2 zhH5b?S=g(En}Vr)x^S~m*c;=3vF#(=uVJsRaFen4&JgZU>_7d4I}Venzi{7#$N=F^ z!~`CQA;xH)DO`ccJ4m>nV891s;BxVMYT;I4zMm!BwHVEz!hH&(IZU|UVqu*v+yJZ( zM5yIVse3E)wn;=Bi!2&@{5H# z7#8LtO3-qNaQ}gI{}bdKs!E$19M_EMjByVBit9!m21#fKlm=)*n2J%Vw+7ZU}lcLS=gV-LeYgy0e39>DgrOSsLT>`~!9iM~H3+>YqcZsF!5td9$~D=a)A+-l^W z6z&3ewg-y@v*0P=K7_734P}VnGs2C*jC>Ze92TB~YAmO{!qxbCcMig{Pq-gJ%M0i& z>R!a^z(Ris(-dC6EZkxY$9~~XMe_r&2bW$Eu0+QUVxnO39TIL3i}E#i20vdH?p_4z zuUNil_l9t9fykSf3|;YcjBvkz>bJ4KpnvaR>%wGz7c&c^au{L7LU<1=2kY;B;Z8u5 zKEQ;AXGbs`ko-`%qu|mgnKV?pJOY5&ZEM89ew`- z&SUC-iFFHKj*0Z9=*k~|AbuHyueVcU*88wKn_K>azT+vl;XZSfh4;K0>7IW?9o_T4 zdkx+5_dq&URcxSp{yT1_eqIwePB-M5` zwnaB#C0VyJW?hN;&wZ<4&9i+~?4l5?ju=d~M~@`i_YNZ4lZTP*8Dq%y(Gg@jaVXjT zemL1)f^WJnS3=KG6kwN zWC~S3q>EH0WQx^=kS|d$p^v319{#je7VMU(EWEc-6_6}f4dFvubs8kwsrArSp>m!UyvM1I zD34cr@E%Z`@m}rHx3o0LpGD3-H;&ADPE3vK;X*s}vZ~H$q|ruojN0i?-_jLne>agP z=j6sT{bpitGSrnQZ=@DCr3uy@wK=M!0Zo|YP*$Sa;60#XpePEE6Rin|bmZ}Bfkfj>H+cs(=`cUFB8=YczdpD1P$k@I`}h5 z9fh9B>M>}*hiZ6!zG@HaQ`KC&Pg5U2=LO0_ucxbAq-Ut7o6v{q^B_4>oq>MMQv0Fd zA~g=SW~-kdGe?~ZD;KL9Avsqqfj^h1FA=@JsKM}Lo(iI5zUmH(3)BqAT&i9|+!iW^ z>#G1FwpfLre~Bu<`(f5BE<^2d_cWv}Tt1mokkO+8-CuGF~=|Cj1`A#H({q z5>Rn7Xb}yZLRXW5+0gHHK?#iBeW5m5LWTX}2f~E6vbzK_5Crv)GJ*Hs+Tlr>8q!w4 z-~;XPSVrAlj;AncUL^Xb`sGw#IKaGgyC)`M) z?V;6DKcZZy-%4P?%CIWYzhc&;d1n)ErEP(EXA^Jx9I>z@QDP--`5wtw%Qqf(KZ#p! zhm6PbdYt4n&+B29r)Tj=EvOhguT+$X3B=!*hIwA!L}i%gwHK-l&+BijfR6Y~%BPkA zhFK>Sk_dQSpF`2vNH)ezR}}m|9YtZD*Oka;yHifZ;CUsbbTF$Ji5vGy8qX#6;^TqwTx*pe(YQ;xscL6nIX}wB1$7JixZG3zMb?ik8X17LQH+; z(M>KR8LP?ENz<(4Hk1}kW==TAN-n2#j2w3z^tYw7&+?U%o_61mo{#%NL2~5?(zE;; z$h0TdEV+g3R+0KR%lAV+WI9wJ(=;)qWDWi|+wuf%e@bb*njLu@$<~})Su3oRGE!zG zjNXG?D5d#8EHH+Dr{vHbnI#F;k zLn4bj&7u@)h;}hyV?0P~Q!ct6Y5672B~F=5vX*St7wI|Ypg3Up_5_i+_$p+~^R7UE z8fY%yVEzt_rm@ZEY{h$*zB#?Y=R{^>yOR840}wl zRA*yjv(KH1Y-^o0T)@GyB63*vB|U8@t+{}M<&@T3z`?c@JV)}6586>cGAv(1j83rP zC31CKB}zhB_miuu@QEpuO)Fdfpdr*;5A5VFD9<51iLwkIl0q#=#<2f}a%ZD$^L_r* z;&F{JnTY*2mHlM)-_&wy*K8>ImRdpM)$E)e5U3&#nf*7l6E`FF-_&Yabj<#n+Lcx? zv;U^{py|Twzp1@gS(h%*(1)fuv;U^{qgl@Ezo`SsGiLuy9Zcb8_TSWD)IG~Qg={ni zy?@J}n*RXYW%l3H0t&1CQAjE;ThV0J*mJE^UbZp3&7}^10y+XY^t+AJk<=9Izk$Fc zB$)j-brdDdZzj@mx;BA6`r$@ei^!r$%O&??dC{b`j4Yb8JRMtFG-<7>06UVlzYa!9iiJ9*?!rseDP zJQ}o`09%0oSquc$;=^SiKtr4G2re+yqRqOd@T3Wzeu{ERB8^Lq;C(JuK8r`dq8*j{ z&l<0y!~PJWD%~mqKXEyflQ&c9jHf*IzEf`nldKO|cS^5v4dW za3_j%SI(p)F1}>(X;08^C7cc0J~8Bnu;5uFVaY>u+cA{VLOx1EF^tkNR?}tT+`LRI z(p)M$?;A{!X7|&5$0UkmvqbFoVlsKsYz!r*kS#0WuNa(dV#JeZC_jot`ACYrB{yPo z7o#3UG9aI#i7=Y11hab|f!#4QnAmhf**B3hV|6wzB%h#ojU&laxs>954#m`we-LtQNaV+t%YC6ro8RR9ntDh@D14L{o z-hRw9LP?hY6QpxT(rlYW#R{y5x$);J}&{+Otq;qG`+PH*@@l&2?$y!e`*78@9 zA9e6dK+!Kjy)v%`Z{6jMVY3 zX7&bXD}y>#zE>+BWaUk!6}O96JTsct)3Zpv@!M!aCsM>Z`7_l z9iR3eGntlsu|q(6DgSt?RR4IYcxr(*O<(X8e_=9r7b4>Yx(w~Cyjv+`mGKm^S2A^z z*#R$PBwxTkbE=Gg4^CeJr}Ft{O;z0DI5}B+31ZnHo-WnoWYMo9k?$B!7j(|Y&qcmd zJZ=4y&*vfN98W`#dlAs;-}>=k6rUP&?_XlYH=rV)@t7~icY!yLB409`Fj08@T7^&L zXi$pZkj%&X0Q@S2T;xSx{w;6E>t34vMEn@;ZPa& zDm19yg?mlyf7OLEjEvWX%b-Pfp)s2oPG&|&nIZmeiV<~Ta(x3)T`11X(w;5riK$g# zGCdH>9o&9!WQ(whdq&9?KV>r8d!XUVCNlsHKhh0h#47nHN}lC`FsEG!9^qwk{BDmfU{ z=$3kwWmd^2rt(s>d?LCsCQu2dT4)c+-r+yh7MR)g^& zM&cHD_<)fJulbUDquRewuRS}2_RmB~{9I3hEue?{jRZUNmdViYG-(x?0H2%km%792 z?@Web-6bMa5|^vTU}-me0m9{azK2XX?I;(A<-PfyX=-^Y7nlsqt((H4R&kXnujm5% zT});>gr1HP8eq!jR6}S)l%~(4gr=DC7DW)69VL{QAMS3+N>e@(*R32b*FCx3lv7W- zgyp@SY%#T;(t6twrTW~ks8#ZuDL>c=-#kXCJ{YC?rm(zGUGk}^J)@&#Js8#M+o)Er z{i#)@xmZv%zm2XHZLH#*rZTSr-tIOT8d6md3B(~&p4<-GAeZYv95&??h~8m&FA&E} z?NZ!!mi%Ng&y)k?nn3~>S$^g@Nb_Q#nWe#wYVA= z@LgP^_`}G*Og9C5*VlwK_~&>x2~Fd%zN`Vrm)&I4{@#ltg5RqR#*NxGx?7K7Ef*RA z?;b$ZT^Y6;!**{Zy=*s@Tf82&<7Yd~E{2^sC$;lBebP7@NBwJK1h5qOCF*7%aJqkA z#8LkyK~KScy6^oW?os47Bd_m9j>S=b#9aKkhx_{#YqZ+_*awe1j9%PP@=JUlHyn!F zHAMKO@9^zDF5Os>f_$(t7Vo{Gr);`u_7Dm%QxbeMgTWt{1SD^P^$a*3ioje$X`XFGR5Pr;5=XfZ#IJ~4b0 zwsR@lshRIhu!XGAD#UND7ID=|RFzFWsS96Hh{tk+d?SFZ*tn2}{Y|?tj$JqgJ=%qF zaa5PH!0YOGwzGutJpL0{<9_5z+CSaW3s2<%qME)bqmNH{!)Rr7 zVXa>@)l(r7D%yv&pIzC{j7vQ~yK<-oAg_nMJNvl;m zbN#i*>!2k@f|kTp@1v@0Qk3(a<5u1e^zGtNKkcEhMqpUjrKN2=myY_sM``CJo=ac& zY0sQPd3NbbKh3wVkk>){itBq{<^}O@Y+*6-B~FwdBVfSurEHj~@Pf$q*oiYOU#tlu zJ{|Lv%lnqTwt9h8KGWpH$ws#dI*u>0)B9mmJNcrY)@9t~o|7-LlM|5Faof)td0igh zs(VpY_Oh{1f3mHouK@4m2CIxfWU_4!yRd^@NLlK+u!G}Ni@c80PPTJ9<$1E*&lI8INR3NKD(U;fd2f9D0M0jUiu<(4r^&;1R|UB%COxzY`66?=;h6M zF1MIWdA4&2+j$WAvf`84nMadgID2=r@rjdwZbfzfMzEbfphr)F5j+VhmwR?bv7H-` z*OOp0Yvf5VhO0hARoQpOLj6hb2kkgD+~7VV5Sau!!Y*`S7iv~`E_C5Za0&9dtKHbn z+mz=?(493lUx`WZXq4UMQ0RrZ>=RRQ!X)_kgh?=g_K$4VH_f!@8lD7nQ?G-R%^psJ zMLh|!{q&UmcI353IjkXWmFIB__IM!jWwWC^^t`k3KBGw>Sxavt5Saw4!*(UxT~2y= z5+rhqr^9xV*iO=wu+#sfb}pe?&97r=`)X_i^o?~1w;myzR%H}-^CVp zK&c+wU9mK{Um&js_c7K`d$l*XyV;3rkuQ7EsI5QkJJ2;_6KmOM1R{e=Xn$>Y6We`> z^zz`|$}M77dvOb|bZ250Glsr8*8S_tb}oP(eLHXl>)nQY`?2^IKbH3Ecs#UhKh6^U zIaf`&b1X4{b8{&-9^ck;ZYOej+Zn`qjv=oX!C>|TKO;D)v!iH5=d;Kf<80*K<-QJ{ zv-#|7+iN{%3)sjs%JYpvVJzJ!>_=WZQOxy)*CEe?Rl*j|LB3>@F+-E@av1P-m$Hvc zg}3+djY9HFEKlDTX8+?`1za@qUZCrAA}j4~n&D#|zeF8mdb zZ^O=g>!aOE-QdOWTOY;n4CJ-Z?|rmk-A#Fp;Sa3wAIO)aN7;P=3O(CpHKxLgp}C3p zH0t_6;oC`5^dRdy&_GYoYW9!z*Yoi0ln&oP_OQ!3c*slPppPcyUy#=xy~-LMpgdpP zUt^E0^;jBj7`64cm>}7Ggtcrp0+B6-z7^AUA7Q%{(4&{&qugRT<=M_-Z09kuv*V<8 zE}^BqfxXK%0?Whw+tb;zb0gdFZ$SToG@)+f5$KG(wsRBPxe0ka>^HMUE5CF(gg0{I z&q+8y1AYtV%WlL2sdsoM_0fa=m^Fh+YNLFd1LNLkm0V*g-o;0;t91o`OSIXP(|%h%eBbsxGd6fDf`OUu0QDa&=xa>MK&6N$a0{kgW9>V?A-fM zs<)J}JQ(RWc}CA+qq8Z`%V9ig+=G0{wkW%AL7^AmvR6&T3CrQg3CrOX8owIWH`cU3 z)cGaq=2Uwg*06{6&E9gT;Q)3+UVGG)HO!|xPt$Jf@e9b8O^Wi+^Ulh9lCJcvSW9Ok z5Lpf%gzdIsyJ;JtmzQAyx9CH8wo}Mq+hGpy`pu-X$3U>@@rmb@cE@k3bsR z`4D>aa@Q>y-s1I7v4%4#&vsq5yAt^_byB;lseix6&_?)ex}KJ}r80J(4BP!ZhBm^d zNiW|!S#0N@VLO8DG}{C_e>ZCC&#)eJyLgoC954deVLSBLK=i+F!JD)(0?%(bhx?^f`tJl9LSi=y?v)w1z z?p4T_-F#BJ-D&0C&RP~30Ts48FKqXAw)-6PXga4mxP>utCmZ>lj4VB=k-juZ=CW)5 zbYock(y$SFoTNK<2^(p98#*_KzC61mhCcOAqx|AYxNKb#L)WJL$m`C{W4nc0yw1;O z3+GV&5G{uVF~33nUdqSQRq0aJm$emCZ%Gy%_njdrxY&AFb>?tYx(kh-|2T3)|hpcJGCr^6MxZPjicaHu4M` zIZ8&ZJE@Us`uuq(yEgq#oug;{I)dBTNVB`W&TSX;gT$f8>yf*gHQYvd?%X|W_b~Eh z7oXJb1N6<^by|xNh|J9WVY}C{-L!k4_v&?s_YK^l59Qg;I<_+%`LdBGwR4QV99qcU z)Bnxb_XC|R(evqZD<>v!mW~w z070MWCF<@D+nvI8myupRu6!!Dcq(jX8r%7l?4+L5&eJqW263y89lgTwe4AgQjuuM+ z$7wL@X}kl+YV-5Z!EDz9?VZK#&qJ-1_ZAJzX)OMC1KLXpE9`hWKzpnJL^&u0XCbSv zVR^J}Olzfx>pnBBF;Dm<>ZVd_mM>y?JV>p|CI6do_Q;>sb+GeP1D8_MT~0Z{O%JmaP6tEBbL$9~m41DQSAaU#W}D@AFw5nN;-G zN0A+YtY#cMPTR&dWIOW=`Hi$$WqVI*Z!@j34@u%$Q{M{0^b&RNhwXht_C6qcOvd^V zJ>JaN>Dl{)?9HJp+xwKXJ%wz^O;ILafHH6UFWY4*A`dt58@n^;x_WSdsdC8&yhL3e zT)8{O?L+d=$FQ4tKis(W8817OvP>w*wYMQ#c8$?NE%DTp9;o7bdHfrM=e_th0M=~U zk#31GlJm4NSfjfN9pqc6)8CSMHol3Bw|c-czL~P)D9grgrR-D4>LJ)dA<29YY>my0 z1sZ0n`ZL@K#5B7fNgqAnuDK@`SM_EOB46_X-eQ_viJ4yWte=vd-Ahh1hM} zg$N1$)Us|jz-{_dYkN`;%JG+BQL0;nXt7(`T;SUAmsHnn{$KEmKm4Va_M{jc#$Sd- zDeJ2o`d!rh*W+QQrcS&Q^Mt4q8yJ{y1)@c-Av+PZ|2ExQ5n9xzd&4&_mZ5t?&%$(X zls0s49jHw`y0@#TQq#Rr5_E5YUHBikha@%YqMr&3)7w-^j=)=7Mt@3brnhmF936ww zhL=%NGriFa@|fP{q0%tDkvksK8(Hy~-YD%cy;0g@dZV<*^hW70(;H>NOmCD4GrdtJ z%=AW?Fw+}l!c1?J2{XMt01v}VZ;v7qW_lxs!%T0K2{XN6NFz*d6#X#M8?BWv)7u_s z3p2ePL?+Diwh3ZkrnkG02{XM>Cd~9knK08EWx`Bv-ysubdL!S$OmA<%&YzgxsFQ~2 zjglVI8+F%XdLt!496YiFW$}UI$R*MEliSH%kf2f;O)mY+D?NefjmkZyH%=R-H%i9` z_CSe01xr0ZZ-(iOd@xLJoLqtpAz?WuHPah8mZZ>N2>!tI)|=XDrZ*~yXDo7kzPGga zSeo&6qp>OYy~C`oNIP#=W8-x$>VoO*Y$?HHb(q%8VOlqbY26&Ab#s{3&0$(MhiTm$ zrgd|e*3CJLPiaXG)4DlK>*g@6o5Qqj4%50hOzY+_t((KNZVuDBIZW&3Fs+-zv~CX5 zx;aei<}j_B!?bP=)4H8HHr-)bHz%z*08$Rqx;aei<}j_B^LTsw0^K=;G41a#t((KN zZVuDBIZW&3Fs+-zv~CX5x;aei<}j_B!?bP=)4DlK>*nmvw5*X1)4DlK>*g@6o5Qqj z4%50hOzY+_t(!9h@)I1Ub#s{3&0$(MhiTm$rgd|e*3DsBH-~B69Hw=1nAXit-#iWNew!_L}CC{638G_9M`v~Eh%x+zWT zrZlaadLHe12t}XhdV=<$4EI<PgECDFR6Y!vnusu4EEK0;|)H>GLal%{o4 zY2B2jbyH0ctc!%w zv~Eh%x+zWTrZlaa(zI?$)4C~5>!x<1NArc!v~Eh%x~V;IexXpB)=gY2B2jbyHawvGqb}S~sO>-IS(vQ<~OIX<9d>Y26h4u=f^p z8q?;~vFV_7J9TV2J=aY)v~HL9@Tt+<@)yNypnLv3_@=~i7M(%&{O|Rnd;S-&A^4nL zNP`Z{2wxSO7J?Y_usO`b<}eSN!#r%xj4=>)j^bml-(em$hk4i>=3#S~hs|LgHivoG zoC%OmbeM=3#S~hs|LgHivoG9Ohwjn1{__9yW)0 z*qi~--`HUuHivoGoJ}bCzwX#{@UYPsd4upv?5{Kk&FR|(hk4i>=3#S~hs|LgHm4Oj z>UWrj&0!ukhk4kX1;g-Z(P17ohk4i>=3#S~hs|LgHivoG9Ohwjn1{{T2V1EQ^RPM0 z!{#s#n=@}TeyZm%51Ye0Y!36VIn2Z6Fb|umvNn*^y<}eSN!#r#b^RPM0!{#s#o5MV84)d@% zd*p3ws?kxrF%){m|51Ye0Y!36VIn2Z6Fb|tExiJ=%!#r#b z^RPM0!{#s#o5MV84)d@%%){m|51Ye0Y!36VIn2Z6Fb|u@A~!=^M3n=(9X>4t~x6Rc&Ar)&Yt z8J@Ctv3YttWuGA#<|!Kn8O`gJ)M_uu)3NDE`C6WMy^;zJLO!M;@p>f{Qd;wRB^6QH z@OmW`)3VpRUP-N!v0RzgE2)fRtcJwvmDGmPq9O5mC6!ZJ^LizhCk_$-$ylM1RW*w4^akn1kO-n8sM%peIYFYdI$*uQ?wUudY>`plqgEx(o zz8|fDc+-;GG7sFjfG0Fg$zPrU7haeSO0EK$304#0#7ZfmV&cSVLY!DB#X1`o+k`l= zQc85zAKQdDu~JHPHa51&x%kRGrM1o)POOx&)lj85u~OPlT61Ehlv7%BVx_dD;n$p4 zDecJV41Av-eP9hUWTjMmfxc*ltYFp$XwD2-!EBmS=E(2n^zCUtPDaRrIiyuHWCdH0 zjA6(M=59vYru+P%;;S0qUW6F3LhLm&WQEG99W!KwDxRYxF=U0R$X{m23U%UU#E=!L zrtmUDR;VkD6*FXode9tThOAI8R@Ma!S)o2Omzg0e)Q_ekGh~GZl4s126&id4nK*qG z^bVu$;qeEb(_qzWQBMEh=#x}?rVmu)RsE7L_w9Br(;VLRH?0~X)u!* zvQqOehWzV(K3hGNSLs{+Ok&7NEu{N}!~RTS$Vx4u%li>9WYJ(RM01|w9z#}Y@pten zK0pMm>odKu>1Nfs*+-?Q-0wk1Eu4swf!D8KG$=njbvXrvzUS$WLAlgbB^jYYl{W0TUv zXEc$Cy5_PkA@2y%T`)Wwty*ide$UT5aU6~oPC?yvC@4Bnptu@OJ@L!@tBt=sk!=WV zc!C}?Gl+-T#8Xo;&8S_BF9O<|T888M*5J}u^0KKOh{oeh^&EO2E{J-9&PAuk;WLle zR%xd_QFny(b0@UJWx-#pFKXfv~^(U0MBG>Qq7SgpNv zYUU&DQDwC>AGgq?_{}`|uc6__OVp98`moTgwEu3yxa)I+w>HA`{1Msgf9!?ewk%{5 ze3||6B^zEEd3guvtbWvIwfm_#wm&ntnJj@ecfE~dVF-TCflOf>61O5zQDg+^yaDto zqSaerF@a1hums=5X4fheLlXc+N&EvZ%;k!XM!^BC!25~6=N!7clXk8fXq6l`UB*i1 zm#Cvfue*E$b@>&zq;b9LNxsoz$TFg71Ffow$X3!~@$`guqB`D$Zbp64iFIb701-^c zoaGdyJB%A`*a?a}Db;SQAU9rzqBgu8t{^uucOy&0qGAPI$IeGqd$o$ZdW5pP*Ir4= zzeSc;v}YykHiptcrQ2$tT_<#A$d$kwP2EY^dq< zGxesU2ev8kG}n>64vdWIq#BX49T=3QGlM!XDoST?#_I}nGN!{_XzZgkR>im{&R5kS zI58bAMpYH#o;vWS20j(m*NlpNP2n1!3hQh30Esc!saZpKk5gf3{@rBykce7(i8{Jo zcBQK;PKBL~e^IBxhBkyxg;nh%r^0%OrsNLc!(Edjhr7DV!pFwC&xVhUb-(KF;i}wM z!pFwCm7=?cnsUzzp9Gt39e5f@Y!CjFJgNI6e14<9}-kEy?o|D1nv~x2`5_;66qA)=@j1S6yB*DzC}2NcRGc4I)!&~_!!Gm zcqfOCv2;?qfRw@EV=Ns$#?s+qES(aRzv1vPmJT0d>F_a@4j*Ib@G+JSA7gn6?{o_9 zbPDe@PMpF!iBotdq4Y79N*`mX^f8u7A7iP`#b@&Sgu1XJ9b>7w;Cq_;aU@(d9b>8V zF_!8c6h0)BKE_h%V=R?E#!~5HEERpN^q5fk7)zCpPtA`DrH`>x)yO?5ls?8%>0>OF zKE_h%V=R?E#!>|;=om|NpgkR9c?$3JukcP+#eNpV!;n)Drt!n^$im^HBpp6V(&3{d z9X?9Z;iDuSK1$Nzqa+F0U9X?7@>7yi-IZ879 zSu_EJX=*(P(|$bW`+pR|^doic-$R&s;0fS=62e4gBM>G!zwi`<$>F0UomKb_wu!?> zNjiL#q{Bx^Iyd6G`CNyOl5|?&DP5MsM@c$-l%&H)NjiL#q{Bx^I((F*!$(Ove3Yca zM@c$-l%&H)NjiL#q{Bx^I((F*!$(Ove3YcaM@c$-l%&H)NuGi*Iee6)!$(Ov=i!Up znGPQ%>F`mK4j(1y@KKTuA0_GVQIZZHCF$@{k`5mw>F`mK4j(1y@KKTuA0_GhCm~D& zv1sc+`oe`6+*^?Fs&!~|Bn!+5u}HYCQNGmA?b;`0WhQg zIfUsp(qkY@Aw1tZ351D?4TLER$@&ncuh2dWVH!mW{%Z&mi5Lje1xTI%VJbvX7{YW* zSX(^^6BQc>(|yqzG=%9A6zOCAQu0S&YcUWenh73+iHf5jOgbBeFzIXvu$%aI*NJT?~4HNy+cn z9_rF?%b^iWlfww6-6RYoKc?Q$wp#Q?p<9T$xd6gw1d}61A+WwDJOq==Eyhuv0XFH3 zV0sF9jbO@P1XI$J9)hWX*hTX=j9_XgNO!@5_^|q`F&lm)Un~y5(Zc6YcNP>BohVQ| z8=q0pcq#;Xm`-9%@=J6S*-%`#7Ijymap5u~c2Z(K5^s{a6Ppy@3w6bhu+Ea@#+hG{ zt%f4PltfTbi;OitK0r?~wf_S4e52++jPo(|=@tJFac z^Av##^)R(L(6FPPhWYS(u&FIUEuG4!5k8FM!RaicP3_T4%lgdJ&O@t7rksAj|9iNV zRWjF<(-VBx;DY8rex)fVFk5A~oS-%yD(j{wiL>iTc&My zGgyBek!X!X#b_fq6J8?-5v>$)il+x|+V?NOP1B5m#ae*}Zt|SNLaU|?l(9>xMiw(& zdsRofMkOO*SO9EJj44`A+x|%S7X@wFhHQIUAD))*7FEY<;|S`DPOLL)!>W3PoLEjV z5~M?;Zy3qcL8F++VuuKVN#lYTz0_7Cm#D2(^&yR)MiLzk>-jU1=xo|t7)kV@L38-H z$F%X=+30h9B++v6j*&#~8u9SruPghJph3gP{OhJNf+RYNbk#=^wIE%6FEyfr!)70Z zC?SdZ(XQk^i(vkW5>E~&DSnB8g_)QeD^Opkkhq5u5{Xxl07_^)Y47AgR3a!L(pAYQ zq0UD!JH_BiMhWT6ph`vw=}di;5KYz&5tLAe2ui5Kzd#8MLW?MrP=|UbAsX9HOxN*Y zQg^9tKALo;D;Q8h2k|e~>OvFmTO$b9jUZiUy3(~t4DL$TDlv$!T?3!10&{$@(t zfy5g~@MQFKgeT+GJQ=h1Vltjs=S{{Q9&uA>LytAj;5WheQ|)_t98Ntv{w4R>9xbNR z`LP(UuWCKsCcutrJw7KFd`=NSQ;+U<0CjTcgoPe>Ydz%?Ub4zd!QdMV<5O`B!;Db4IlzE(6pquG~ytFETXZ?PnNS5or7W?zbJ2pFPfU-C!Tm;4RJQ7N%6 z`5RtFNn&4$d#ekQ_1SO|^simx8-0ffBxiMnfPA|eb3rm2j$}3*$!s{1*>EJY;mB=J z6)%|$M=~3ZWHuamO9gHMB(vej!`*PxDwz#OG8>L$HXO-pIFi|LB(vd2X2X%ph9j8` zM=~3ZWHubhY&eqHa3r(gNM^&4%!VVG4M);(qRr&ko)&1K>~{EiOTL|tn^gHyE-2;X zme#oYloys_ddVp$&y@+iEUTq_2+_}z523b|+|UU}iOLS`ad#&J7|B9;c_GM0<%^Ih zmhG|lOXQDuFO|bEds@pTr(?I5r$fGtYzUchxf%G;wsIH7yq(+#{S`8{74`{vHDub$ zMTl6HY>W7GkVCPkI?5_|+eyyBduQ1Twoa295&vp=Cal-UK9wLtlRHt{RX$$@iZMA4 zt-8xhc-up+L%({;i72m?RW)E(kj#c7nGHuW8;)c)9La1rlG$+NA^6Z=G8>L$HXO-p zIFi|LB(vd2X2X%ph9j8`M=~3ZWHubhY&eqHaOCbxT(%^$;Yen~k<5l8nGHwIMNGy? zX2X%ph9ieSeu88+9La1rlG$)1v*Ac)!;#E}Bbg0HG8>L$HXO-pIFi|LB(vd2X2X$V z(f65>*>L2}Y|FYxZi3y}a&Jcfo8{Xr!NnzeB4TspyNJ~#^6z;6i+mJum?zIbZ0E}_ zF&`GlT^O%RZ#DQd5jH^Smo@=2txmVd<@TP-WGzShY5;o&v11~FMH ze?+TmWh!_xu9Gz=zh16{h8yJjcwZ;~=nh5%sj!+h$gg4dM!6a@p-!e^zTG6pU>@Eq zw;&E1C8I+mv*Ac)!;#E}BU54VHpy%_@)-1QmCS}CnGHuW8;-0+OzxBu(Yx)E*>L3h zh{oOWozrk#l%ueA?v-m{WrwVVpZCesKKOJapF!>YvH@oA15)9p=s~%n3=aY2T#UuT z@*~XuM`SD{cgcD1|55oSN*)&mOr0@qbFb0Y9IS z4Y01Cm8T=N&&i+Q&x^7Od_`uVQ`BFX(Pmak)3jooVjWB|LmzSVNKgm^yz(3@}=;P0F1mg3H zT#r`2%A2v?|0!=rACJq0&GAD3*#y1&UDB~9f7l;GnUgaIJRcPvG-v{^+J>| zl}{J8X2Y=?VQl*dTeIQVnhnR+Y&f=N!?E9l$N*t$HXK{C;nG&lhGT0s96JE(!x0I@bA+%r;onGv4ud)hvjAZoEo{w(V{0}XTeIQVnhnR+Y&iA^ zL}CI42O*y*Y|VyaYc?EPv*Fm94aZ)A!I>g#&4yzi??P-iwr0bz7okTN2wSt^*qRN; z)@(SoX2Y>H8;;!s!MaG;nhnR+Y&f=N!?86Rj;+~nY|VyaYc?EvCweqr*qRN;)@(TT z9yq^H*qRN;)@(SoX2Y>H8;-5naBR(nV{0}Xdm~oIGGS{r99y&D*gdf;t`zoh=v;-F zjNV=;Y|VyaYc?EPv*Fm;n2~FQt=VwwMOgQ1g{|3eY|VyaYc?EPv*Fm94ad&Hh^-g4 zX2Y>H8;-5naBR(nW6!{{xLMem4ae4OIJRcPv4>z8ZWi`(?9#Vl$>36Po3PhorEYgrK5L=@| zY>f`FH9Ew;3Ip(fur)fw*60vhqeEl#MbB#`$+`(F=1grK5L=@|Y>f`FpTpk!ys+nBf7vJOkD%oR^cG9|MPWaMh5nMT zS72v&S=hzc$o30+DmH-w!mh@y{EDz8LU2&n*I*+%BS> z?hRqz0+BZ{8M<25Tf+VVs^7-`g8lOyY+ab_?+UvG_VU9BD;C0gSUFgK?_-Zdls*vl z?eOdfh69ox3VRe>`bgNd5cycx9iZ$JVZVow{uEm?3O~bMhur7bN}%&7wpgsjFW@{D z^OwS23}23k#HQ%VAA}A`A~u}()EFtS)tg)XgTARrxG0>t%EEizjdagHq7GLV`R+Bi zxX2zz$I6NgxU|SSZorjAW~`%o{wo&JGnx^QNsz~vps5_WobLJGgPuhBB+^N;?P}b| z+6gPkde|P&D9I3KG>T+G9m#|`a`G^;H)9OhJ34~wF`BopdLCe)D= zAfG6iP)9PMj$}d|$%HzR33VhB>c}&P;Nm5jP)9PMj$}d|$%HzR33VhB>PRNkkxZx~ z2S9&g$%HzR33cQqlr)n~htp?_r$^FfjK)LhGsd#B=rhKo(exQZptgnF4~x0-IQr63 zUO0$8WAuhhE13qFe934O$!HYGXcWn46v=25$!HYGXcWn46v=25$!HYW5I(e(j7E`+ zMv;t0k&H&MH5$b>Xp|&Eqr?M^f?@Us{g>GNDHw$2a1HkZa8pPo)R9c6BbiV~wt^AA zWI`RuggTN5btDt&NG8;gOsFG&L5C706Y9vt2uZSJLLK=gEC(eM>d1Ytl`3BtOoQ+? zU`I+6)>BopdLCe)FO(W-%DLLJG3I+6)>BopdLCe)Eks3VIoWiq8E)bYCZn*T@Y z8lzDp6Y9v?r)fTGLLEBopdLCe)Eks3VzBM>3&~ zZ3uOeh)^f~+&D7pX`dRmJq_BKP)9PMj$}d|$%HzR33VhB>d48Bao;4FP)9PMj$}d| z$%HzxqybGBCe)Eks3VzBM>3&~WI`RuggTN5btDt&NG8;gcc;^oV?rItggWy4Mih4@ z)R9c6BYUGHQT_qR6!{=LX()@4ZY=33P*eF5-V0=DDt+8N4o_Ok$FX+(@*I@J%dDpK zk+>(`rJU7}7XRTUwCsH-NtVr<(bzK@MKT&iG8#oP8bvZ1MKT&iG8#oP8bvZ1MKT&i zG8#oP8bvZ1MKT&iG8#oP8bvZ1MKT&iG8#oP8bvZ1MKT&iG8#oP8bvZ1MefDWcaw}p zkxZx~nNUYEp^jui9hrhSoGzJAM>3&~WI`Re6n#HKGNF!SLLJG3I+6)>BopdLCe)Ek zs3VzBM}8KM$=na)m*_Jg-_CkElmIp9RhRYuu+=BEv8 zBjX`IR+gb;oa_cY=g8^|{ODcYhqe=B75Xw!u7J1a%0|#|o~%RsC&{DGGg&?c4O8TX zMEpEewukkpaxUJd$q%6O0%>7PRNkkxZx~ znNUYEp^jui9m#|`k_mMr6YAKSP{%feI!Q#R6W=fXVFWtZs{|Lkz^wydE>toF>D%6g zgI1{5-;mz&8Ip!jC$O~;GO5S93QJ#N6Pm6gA6J2tM93Z0Ajy{#@kOIgzKi!*nTK+} zTmtbp*&ikGmhVnv5^_hNRq(0=Tyqmz9U-#>YDvh~W{H<4LG$vY5id^y(~|f?84_1y zrX?}FJPF0Ok{$-NB(%;`&_ke>1Py9QBVL{a&C8QUygUh-mnSstI>@_h$cnJyumHXSuNKpWq$RSbdiL&wKD52+hPzlzp7i z!BBiW()y>Gp=$$3|4!wZq2n<~|3T@zjHS?NTY@sB8Hg4>fpexZwfskwUusoavvD>PIGyGea}}piDp zR>lDGCRJPy>5DU-B0H`qM`mHhJ0zAaa0hEG&ge?oGQ@k(wj`r7wP`H=hRm{z!IWts zHbG!@MsMnKk+=()br}OGQ_PuLGKNv6gfrVR#!#k|GdnWQrA(Rl4s9OE=>9q~ZP>Rx z8JAE^Tk!+zJZm+0iej}PxE1y?>|3alp)cc5w26{dXd3yxnYtSYH6z!z((n*9J;9jb z0}U{SJa5Qto`h6NqsgT{Y@b}3W;Og8CK_duxzhxdH+qruRqOP%R9?gB#sY$gSCGxd zDJV`{#z~^0Ph8H)afo|TLvqAPfqer1G_m|c@vkva(I+*ck|6UyCFiH%Y8rZBI#x#k zZD3YY;(&U{2nU;6 z$z=_pDiG>RdfHGrF?1&>DW`NWw2U-p9;gsK08IYZJW$CMGs*FBl^BbZtVw7dTGbM} za5im)R%lKY(#`3)K_EmtP$`-WC{)%0=@ukoKvXHYg=pJspFdcffxSJGc%Xvpb>@{9 zK#F;wGKa#+AoDAg}!D?F0nKjr;f?a8E$b5$cdeEMe*%O;{ zka?goyI^Y#_MyEq^PUVO`_cB7`B*%X1Ie?@+D1qY&LR^8q6!Y9?s*_8cMRNm%OA|2 z40l7BCYN;bkbW0)41{ET@rBEws z8q6X#s8IgJX!^Q8iv~1g*r2kA4JuSfH@k=ZS;PhvDx!N+K&g0}4&oMocUF%LDpb6P z{iBNDx@WO-rDk4*G`p9Y6>%?Bvq7PhL-NF;khXM0woDP>wVnW;N@J3x2Cv*XMMKi zPewZTEO;o2sTk-ogYRO=T2B&pFO?*@3+6;Q6({(%MN1Ny5$nW9hjApinRK?JV(?=b z$(DuGe1*9GH0-l@eZue94eOfWb~f)i41!oGC_NO9ne*s22YI@&x{dN%biM`Zzem0m zp7~$NSC-Dt<9Mq6Sc?Vg6;#x5;YBDctgY6TUdCot1SrgWyblV@vu0Y^ms;5{A0MEw z#Rq6s75_jE%o7y-DaOUxu#5MHU7W`*u7m!(<=1cvs{04>B^OSZX^91_!79DV=y(&x z*Fl0Dm`M&0FG=BDQMFtXXKLULO|jxxJSwcqPgiKXCSpp^OVsVdCyP90{VEp35Hw_; z&uY!!tagl%D`0F#1-E_>b*-53tCAzr@&z0*#o&dmzK&92nZxEfbndWkv`Z_jLAn>QjDi{NV&!`f~m z`JX7uvDwlA+1p<7Ssf11P;aHFR>h#T+i4Hmhnifb{n|!X8Q+>CGjo~t>kitO2oBc~ zbM8*knffwL%IelZJ8~-u=oOQN=eu;HF5V-V(m|$P;NERhCWpnIZv`@Q0-3q9t!#=w zsa3kdNF_q*`F|x<_^OdghZMqlf}RHRj9Pib-xM=Dyx=j%JLOhsH}}IQdToT89ofyJ zJ&oXO9wT`8qNya?^kkasFR0fK$Lp4{zh>XexNNKN8`F>i@aIP8 zymcDQyMtyxvA+2w?t2$jc-kF-b8Szo_oiL9_PS%)Q2%>9r)y~L&BG9^Ga~fFt1*H> z{hCMp!d76F-fC)#prFdsa<94e1yfsz+JWI(tMqGA-WBCD!{yNFUtrC{u2L#Yw@F~5 z7C2$N;#snJoK@;KWOOZ=-)Ab9q4LderB%A5lMc;Vl+)8_nqJ-{)N8AOH$~etZIe@f zO_c67t;uAWZf&M}jaB-ysiYw}JzQy3c)Kv~N7WC~4zlhnGj*}8@k`XvOl!}`wRNAN z$hY5T)$nG!j&I%vRWU-2NzFQl2v>GSxV|_4*2vs z_3VV*T(+czS*NQY)Aq!A(+3n9l}i)GXi2+8z9_qvdKI_Evu(c-zzT4s!^p~)y@An8O{UzMo*Fzl!H}s954$tsVhkadai2T>C z@2-5nQ}E}u>6^A2pBd<{sBZ+8*tf-Wd@jJB`&HlJlku%B{(@`z9l>WU`g13Veo+X; zz8*qRcIeyv4vkQho%%))iv6OXjeR3%#l92p>6QLcD*D$4F81|+i*k~+zAJS(?^b-m z(KKoohqxQc9T=W%4jPbQs!y&>jK8yc+jHGvhBo*)p zlK*oIqxa?AOHkoY5>QNU{{q>VnuPECP9YmRw5LZpr;v@Okd3F1ji-=}r;v@Okd3F1 zjp7ut5inPLHa&%GwC)Ddw-Qiyz?+MJbr+|QjsI668w>COzyo0w#q_3oem>_<@;QH! z&-s&l&Y#rh{CUDx#XgG%Z>M01|G&c$X^gx<_$79G3I^f-O;{p<^8PI>@g4sUBsRGg z^BBMQ!51y^GJL5K0~QJVi+|rwTD))_@n;4h7C4=R@4?e@AqU~vCxrW;W&9`pKca+( z#4RA<{~+M85c)h$zx50Sh^Dr$L+RD2imF{v7G`-X;*?O?i}cX5_=NW4niV3bKtdI% zkF$I~^h2gY4l*9HaW2VgWFy-($VMs#tb~e|Bk6QOB8+Stgc9W;8~2g|jchy)A;3iN zEw^OYX22jDNhHBaqpv>SMA9W?5oF`Fq|HM%2Jkhw)>fvqG0?J{iUZmm0=tDZXk_C@ z(BNShZv$fOBpAkBFzI0!DeYkxDVh0@i06bL(h*1!}t+0=cPwu7}KLMjOo!B#`I_mV|p}( zF&$r!6Nd39v@J;|i~%r=KO?g&JsQK9ZZM1wLwa4h!7x(hmUM$*q|CN-gJGo1j&y@z zq|taJJsQK9ZZM3$rxS)Tqdta_I%zPBl=Lu+)ZG&?jN4HbAIQP5@(dxjdAd<4jV6~S zXPDA7u=AmR4KriW$NXmZkDAj2FROgJGl~dl*KFm`K$aMoPyR4CAGc(L`{;k<^qijQIoz+Du5xQIu33 zdXZ?!40@41M0w~%azECf7jJ7Ze&8yg#+({ds{r?rUqoR%B$Ijv>H=d`?t&uOhLhRTf4u-!0~PZO(g=w~up zK;?y@I`XEF(xstYlrADY<)JGmT}Z*b%#oV8gD6T}Q>Sm$9Q*5PKiXI66LK;r;*D-sf@?m}lmD-tT$8_xXO_-|r-A z?Y;KeYuB^SI_sXG4{QUxkQKnzb6o<+(cb}y#z+aS zXtQjW+XIzNv<#_~G+c*cfR5e*CZSk#0tP9Oi$5{H`B>JmA&mJw(A4o0-bed`2uDzO zDzamw={0YzGq@n?_W*e_m=$=2d|wZ6rjREej{(ji97|S`CQdk>{DA4%gcHf{3Fi>j zNuM;igo~2Ll23wgX|gZjB;oR8m^Au4z}3m;S=Q%U&qgQzek9QVQrfAUlGAZpC|pVT zO1{R;p>P$;myo#dDi$wUN`low@GS{$69RTa;q4^onJ8Mn48_Yf;MH=`8v>qy+@cLv zF?BjBFM9J1fMzi=QR>ch@_F=Qj^I%zpOfj)01rEfGH^^3z4{iCk`2f!dTS0qyv8L_ z$@7q==tE|f)Ir9gj|fKPwXxinvS3mpoLilYpOIBujv?v>X97qs?nxLP1qdI>J7Y!Y z2XZgAE0EGN)_v62a`f)&q#sSfvhf6W6mS-69V7RX7g%O2JGSgPrj8TvNz(2l_a3hY z!11i6Y}{mk6WE5bbFkTTpGXc)q5v$4x(`1E^(A-4ak+czC`@c8`5fBZeFQ6vB}b6q zNWxz7T~^ulHrT|S@OvbhL|GGufad7#yC2vSW%r~k)66|)A>lo^v4xTg2=7V$iR4|B zVK1f^CGR9Wo$1xd1mV3|S7Y+hcE~e>_p;_>Z`QjH+cz_7tsCl?yhig|?M2 zqPF%_`Ab0gT0j(cG9Cw9Re{>oU?#&fx(3sf>_|x)MyWdHWPDA^gIMtnO!mSv(?yIK4V6S$GO&$O~FPdbS zU^%saNK5}TE&U#w{^0<81elioTN-^Kc!53n^vl~X#6~#eZ_}`Ca5UdSMmakM!>A zVZ(bXfcXTj0`O-77Xg_1I)J4BUINgc1qVCd)y`K^G>3G@1@DQsb17<;2(PVF@#O>HD|Ufw57Jv~>El@%5;VVWGap4}tr}(Oc^=4KhC_JSR}i4P z&Dem9dFdJ3*^G~naZY;144Xk=t}_|5;;%ixrhkL`arQ>O}IR-4HT=;q=C76t2|d|WU=JCACX=bigtM% z8zi3{6bQ4yVxV8>^2m%8%UwSj~nWtg?KYKd99S7mVRPJ9db zXOsTw4BoxM%PwA0`@9wFm;U&E0CtJNz`SGAi_w!$+4K%G7ctvqtiQG-y+Oh+AW$@G zfi<4TXDFPv{hivQ_b}~l1XV`0sQ~*=?U^=x7}EQs(xnh8P%YS3EyWm6jP68%&G-(R z*^bOZOlIfG+iB@u`BVA{TIGug3yux7WhW(IJ5VeU46YH4LNi^fhV z$A_@nlW$T89Y**_6~44EEP)rhs5RPUzEYa)TWKVzrg8J6=(3~zT3OND;@@3 zBDk{&_(jA^1wV@TT@L~8F8Chr0pEr4^boxGec)%Zg=HCXg#7@YH?_CI*^zB3R9x~? zl^F;3!vSGm3mt_{*lIf{+k ze6Ve8uoPcl-+$duWCx!jEnBn1<@T1b?3N`LMmSuHQCIP-Ej)kf#FHZmp8YOLqYz1? z#{MSP8FC?yMaM>XEIn&)!>ioyf-n3GxQy*-g7^F!_(>ewGXx*-1@KbhO9g+2_)OmH&W!M}rrTG*=aB!| zg4g`T&V_4i*JMFR{?xL_f_gg_s=mcs=t>aGg?TefXL3ZZMG1@mJ~lGntSxk8KttRH z+vQOIi>2ladD2ja7Ic~+JKMQMiqASx1mk^U8pSroo1fIGEE%0(sb8yXqgLF|7>sw8 zjQ37xnpw+PGTxs8H{+cx91i^sxQus>;NK9J@y?a;p7dAXGTsRp??;Hsc;`v~-~2sr z8Si|-NB#}CjJFp2PU8Kz)_uYI`~Y0ma)IE{AMN=3YG>WC2DC{Edw=|7{ z17yml7UWmln!XBiL0)2)E;>MdY6TBWW+iNh{$h)!I^@SN zzi*QcSpuSAT?v8?xz!frEoeAO$P_}$A4%Ir_D!XyHZR;|UQVMpxf6x74HO@yQP8ol z;Y}XWd!T5ZZH8kQ?oy9g3V9fjJF-XHnNpYTc5_m<6L=pt6M>_8s9 zdANeU2oInZapN2_0A4+C%bkhQvjMXJ9TzzV!eiflWWRl4_L}gVcP2~A)d>vw@KK)3*3m)BH|SO0$iT)2ZnhFc?x*H_iQz35)Ao}&lUy3 zW0B3Cl#*g*Gd>}f!$_g54>fg%^Y;UNQMf0%T1_#VS+Phs{x^J=#~XjZ#tqn%hGpHH z1cG5*Gwr%@hBUD)s}wuGxXtv&pE3;xwPMClbiRCFzDkv2-L3|!8hQA;T1xz7bJ%H> zhr4U!oAR~ch*K{Qiq|T7KA?uf^v-pPgZ1Y~#Hm>h2M+3b#rIr`GC+SKd*TMgC&BQt zbsaS?@anG5p&2HZADG(6Su0JTkJlu07S#O5(N9i0k+_qn30E} z1ZSk|lN8md?J>!8!AHox++;I@Yn{6Rzf$jOzf!L~#nN(RthKE8(Eq4S=gg&(Mphwu zjnsMR?`b8!N>Mnqg*%(tSu$tfRwc2~46ziHkB&yc`=849bs9JN4c=OghF!L__KeQl zxU+R??IKG{*>38@&E5iPSEg}$y)(BVUAY~}m;3m!9eCJwi)fstB%#I2OUjWu)R4+U`gW6zRNtVgQ*3$%M3`sONxveE zez{F&pFEsOPu*N_GQQtZ@J#)B8poH?O8&HUNsRO_mV!N0Iru;Ap&fTMVzY-P7}9O_ z&}>UbmJ2$w?Ak-~Eh$@kt|65kddjA=hgREk_E30=5rOm%r_oo~boS7Dsr2+78fPik zLqDZ)+$XJM@sO=%FM8-mOYslLGQ?7FDMNp_4omrNo1HPragH?E%s_rYa8eqMPr}20 zvs!x2BsI=y?nSc^{1PZvdx}LU|Ef+>1hf88OTkWkKB&g*7+bBO%XTxYN&8c0+O2k% z57TISVH-|c>09v~Xz%RgyGv)95a<*sb4@t@*EUY~|uLL#d@cxAJd0>cwqFNb%h)mFt7$ zz8#iZL5(Q$B8tbs$FuFW{;L%t_3WCZs)pHZJtqg-dRKyATOYck>Df{Y+9;IZUT3ty zqn+B*Z6+JEmt;73vD`O8<0wuW#!afnU*;| zmFd*pX44x{XqHXq+FfVU`EYPbDqWayNnoYDl18z*6NRh-P<)g|@pLDO;E4QV8pRi# zD4J|7YOLvmozMxf?SsZb4jGPGn>z)$ebaN{L}L*YaUrL6J4-SXB)c1utPcCo3XdG% zWNBk~ZI#CE*ln;Ya%zuBW4HQ0W7h-kGA!+(sQTd)JE!(Jo6doKJuUrvo6h<3by|9f zJqnWE#dI}O(y1L~(@EcBOL}u~tTU_mTb`W$!lT?0yO2b)BdfXFaI9u=Nb&V|Na&B% zG*Wy)eBGxz4q`x!FNkmJfO_E*?5;RUPJ7>x=QE%gJs2D>u*^XyKlQi2L!`!CSs9GY z8pi?X2cX~WmT)1YMoYGE<>cbjffEPZ=DqN1_FZLPH7)!-yeK&R9=1hKGet24P-Y7Q zd}iL)?u?i4VX8+Wg1brDlgvtVB?o39o@Cl5nn^2ni_0vs3_@?RMCOfF=9^K@ zaIdKx_#5i#`aSF4X5oJ7;AIsz;>`;W6j-Og_ zeJdO`2=TGPXR0&)5t1K8>|jftdJI`H;w?VD&EaUwwwW;8ke^!deJgm040Bi+U1#>Bh|Cro}KsvKTD4p;3PcgG73 zTxG58J?F!y16SE`?duodffrZi#P(Ht;OKy>?2yT8_r{X~uCh!uc^>}rDl1p*mmiL& z4P51w?Mn}X)iJKj(d{#j!~0oWnPVqEj!a%_Ove}aZM;B#-Rr`)N2CgvLABZ6k46efC z+J|Cjc@<7>-{P;Mec5Ap;e@N_koF(YAYR_v?H3%6tp-H)~u~By5hWWC_6|^{urY3!hCPv;*n#@ z3x7h7kOMOhA-A}qz(-`##N15?GB1#-AUHphCgyP8cQ=qrGihS()(f&K zlP2bFgCI9#&Lq+($eK)=n7ad1Gs@hTNfUFoNn~4>NfUFoMZJg`9(TfrPllQ<`US|c zXl?FZ9$Sr!B6k(r>(OJbdlf;)JB-b^nk|oc^qA|eX2TQco8yt@#>gYiL1zoHIS-jS zABd!G3R3f(oUZ}rmb1Fyis`wuHg{VMOlxy@gurg>aWIL-P;-KRk_yDJ(1 zhJds_k1Z8&7KX$treN_L6xbP8o)aC-va~+;N|=%#jc^)g)`iXnrq{It(eibtmajXt zeBG(d*PZ@NyMnYSv`<>Wb0bMG(-MF}O8^Qj0VuQtpwLIo#PZM*fI`Qop*8xiSW{6g z0Vwp|SY@7;02EpRQ0VDD`QvC&vKi#zipwL$#rA$iz3jHTg_S6!9LQ4P& zeb7GGk+p)%y|o0O(7#|E_t6r7LQ4P&EdeOB1fb9ofI>?E3M~OBv;?5g5`aQW017Pu zD6|Bi(1XCaSrGtuznSz8qvStZ+ATee>3!C3}mT(uni`fx*erlJr94Q`g^3r z^x>fK^m`LgkDdUHX_j7tzj1x{&X~>mA(YM0%aKy7SAsHEUjxd7E=F!rAC13xx*z!D z>vzCY>sgS&*GZ%l=qr$0sJ}zmB7GeAbkhZZd!(jerkjmrrW+n*L)PK1(g)ygNMDS< zVaNX%|1xu3wlXG?d!nJqmS zxiP&Q^q#&LxtaR?d)U&2ce16|-^G?52A(-O1o~V(?GCoF&jV~@E-3SK9?Iqyymbre zRgQn-I`F7-yFr#fvIciEC7YR~WIgjK+5SEyyB8^8-GRRmO#|o*Jpg}QJ-wKceOKf- ztp%^*FFf@JymoWjv9k5r#pERcHnarT&=O!n?}zk=J_dg?^fmbFY6-BR*DYczug2fj z0vli>;5gU4DHFUTsD_rH8d`#CXbGyJ3n6JlOHd6hK{d1l)zA`DLrYK%EkQN31l7<> zai4C`5>!J=Pz^0XHM9iP&=OQbm!ri4v;@`A{PMQ9mY^D1f@)|9s-Y#QhL)fjT7qh5 z396wbsD_rH8d`#CXbGyJC8&m$pc-0&YG?_np(Ut>?%4zGUG-S}&D0W9LrYK%EkQN3 z1l7=MAW4Cipc-0&YG?_np(Ut>mY^D1f@+A1;GSB7YG?_np(Ut>?&t!J=Pz^0XHT2z(VLMIh{Oz>_)zA`DLw}3fTeSq$(3K^4e$*0FLqC~-k&%|58d`#C zX!=YZt6#~+Lxh%~8d`#CXbGyJC8&m$pc?wLJOtIy5>!J=Pz}8awYO^ts-Y#QhL)fj zT7qh5396w#!RYL+C8&m$pc-0&YG?_np(Ut>mY^D%PW@+S396wbsD_rH8d`#CXbGyJ zTQPt4(-KreOHd6hK{d1l)zA`DLw^Q72Wttcp(Ut>mY^D1f@)|9s-YdU`UqWxmk>v4 z396wbsD_?|o}8y8sD_?}x)x{&s-Y#QhL)fj`ecphlv;vnXbGyJC8&m$pc-0&YG?_n zp(Ut>mY^D1f@)|9s-Y#QhL)fjT7qh5396w_!DGzQg5g-Nc)?_YYWNJQky#YwLXDk? zyJ}w6(#=?6-bsM7&Uyy4PT|~rXFFNvGFcTKw*NdQ>jIodoLC`W@MK*?n#{s|_dCkT zx|lRsPMk@(XuX^w@QLLrGQ0F1WX2?hM%FdMk?S#rM%K0D<#=?mn04JIfcBHptkuP! ziAnH_c+Kgg=O?A{T0_rIO5=T5QK*ogl*aoJ4tqtYBwk0@eo`8*A5T8=NolTKK!IKK7^t<9-jc? zL&@HLQW_uj7LX$INoaQUcIao1pM+-DG=tvp_(^DXEh~t5d^48aPe{yRs}0mt%%naE z&92KtQmhial*lQ6g3M~Z#zx7Lpa;}gm5+C96Sev=HiwWeww^%rh#8y-cljK^^&H5!m-i>Y4W`O)DUrrED0?JA zyD$3<+#X%L`vEKOGgG0f+ zqfGt`2ZS8f@5XqSb7O3-tflEll1fk<1b7Rl5zswg*G5LZizj-CH zy$w8V4P-Tr$1j-j2N8~-#IeXukS5NDtOo$dQiXu0<7}>1-h`Co*Epf;RV-=v9*XI?{9>q}%)m#YbYVs4Or$6I#ZXZ%@<{TFp`roO+7HpR zBI(Q|zZfbSCaLRDu3I%{eq6Kva5I!a+Z=Yv_s8I?{&?D=3UvyfLUCw+gozV|TAjf4 z7%l$PiZwXKR9uK*RugsvqbblcR+N%}cO^PWN1XCES*8b>a{MNZ>)6v%iyz>2k*9DfKpYSrpz3>sW z7(M);5)Ci=yaP`|WTp-<%qk=g_=VpG42P!}_OL`L;a*Dd3WV!p`Bir1cjzdbYNWA; zr1-UV6FeL z*w)u{pykxx5~X_X#yUJJNK3y-ahha_Qa$(6R+5!ley3T|lw@lc2K-72f}vgg??`s9 zB?4#psfQj7IE_tldSjcM%2REuTWF{4Ak3mSQJ!k{4tzs&u1z0_^q+0I{kp`wt*X1m zQnZ1hOtU0E>fk#KzN(mvw~tQUE0$&&Xod+*yK0tK08X7}=kILf&6d2>*DvRHfF`3u zyvWy0uyluk?rcjZ2I%f$xDDD|j2h*Acm1`N@E8y_ylj!XO$qzrn~T?}+ider1>y5n zsz#^o06S?Y>}Nr;74{CBw+wk67L@dX&Q9ICX#~AH5jge1Y+QlDbq#hzSj(i& zgmuT-Jl1kVr##dWij8;bg6Tt6X9&eqrq{2rC9g+%eK0fD5_#X|JPgF?`4Kn0ra(Je z7)+fN+$1U(lt(pFW7L5O)L6nzu9-W$n&R~TGZsr|AMT#vJg^!-by#ShB7*WdVV`_# z>rJ>1QA3&_N%Ip+5Ze}4g+r+2J22)In%eR*#NgF!M9V+$k5_J6OEv!S${pLX3jNQk zxT<9c#NbsjvgM^o`0fQ)a?-%tqRQb_dWagh94Aa(-Oo}jOYk(!t4C$au23BCDr;{U z0j|8tdk-9pf4q90tp){e5*!Xj#5w0CoTZE&yL6J#V+Xx=Ep}o4!p}l}73*L#LeVqP z8G&-kkp$NACmM5pD6 zPRkRWmM1zbPjp(I=(If1X?dd4@p6IkZ(P??2)AB^8<%v$q z6P=bPIxSChTAt{%Jke=+qSNw3r{#%G%M+cJCps-pbXuO#X=N5;9%URXy%03&&kVm!R#@8(henLAO)tH<9= z?{=hQIhl9jU&fM*-_TP*6(?mJfH~uh$zt#Qn8X6}z6BieqAsE&dQ&l@BVK)ua{73c zdHA^6%Rx$&*B_LhV{58KCsNGVm<$zC>=J zmkatLZxAHu=2hYVTdX_>nJ22V zAU16#W7B5LagPGOfcspx2IpNgfFmkuG*8rMo~Y40QKNaHM)O3C=7}236E&JAYBX<0 z9CLelqDJ#Xjpm6O%@Z}6Cu%fL)M%cl(L7P3d7?)1M2+T&8qE_mnkQ;BPt<6hsL?!8 zqj{o6^F)p2i5krlHJT@CG*8rMo~Y40QKNaHM)O3C=7}236E&JAYBW#OXr8FiJW->0 zqDJ#Xjpm6O%@Z}6Cu%fL)M%cl(L9Mw>xml86E&JAYBW#OXr8FiJW->0qDJ#Xjpm6O z%@Z}6Cu%fL)M%cl(L7P3d7?)1M2+T&8qE_mnkQ;BPt<6hsL?!8qj{o6^F)p2i5krl zHJT@CG*8rMo~Y40QKNaHM)O3C=7}236E&JAYBW#OXr8FiJW->0qDJ#Xjpm6O%@Z}6 zCu%fL)M%cl(L7P3d7?)1M2+T&8qE_mnkQ;BEC9r%@SroQ51a% zi!3f`GA3sT~u2#S`wc$&_pA}HFEpp#8SP_%-u%BCVHT1hyRO+`?&*IbZ9 zvZ)A)_9h(5rXna>#fswDR0Ku)5YEn~A}Cr-xU(WCT5}nzcP3%SiuT<%Reis->g!DP z!n&R;LWXq%;jm%dNEjNrn{r4?*?f~6`;BmUHs2)2HWRK+@=bEgQA8S(IC)dD#%c?h}16$L&b$v4Td zgdp>he3Kl@Q>P*4=p^4H$85mWB;O>*Y{1pzC~_-Ojo@~2l5dh@rK%Ok8A;xIW4+Zf z5S*Xno8(xXS^?zJB;O>*>IGSq}nA+Q_6p~8tS z0g2By$KL6z-shWR?+gL?=Ga>*Am1Ek7E`9&Q$h78t^y}YowLt3$C)Ke>8w?BW1NMu z%zi{>;YeW6u=&)mWmSEQr107{oEsYB*pA#-9{v{f!JlrMkkyTgw;NGpag~PeBJG&L zLc0TLr)^E!jcF*5jou1>zygyFk^+abz!Daa8Yq|(J{+qfKIKdyIG+SJk)U(!-IxZB zT#Mm$7MT8^6yQEy^fn8mICkTqq8so1PPmPg@Arw2ennCjTUZ(?CFmxrI(#)r59QwI z#tQMbsNdG4PVs4|TMc2ac;RQy?v4L=PT3RtiyB5=UifL7n9H-?0bn7sq`Omm7m0@N zh7>5r>M*+a3DH>rQKnP8mPFHz6Qb6Ds1Aa!35dXHIwV#5tr8+#!Nh%q+a-^ z1tu|90sSH<3HHmeqp4%wl9H0D^(;5&pZy_rAmV%b5UPywC z;XFfCGLyYir8pj5_>3U+3Z~X6c0HPIQ%g5IitYPqHJOi$_%)dxfnx9#?1kM$^>?-6 zpx%P#(H>$ieU0L*XfFc(7PWoXDh@<#w+NKun9XXnk{O5Z%}cV_((9GXmu1VBlyRTN zXEq$8hl@e~9v&I-nGJE+W-lobMdVGwKfLVHB_%I^h5Va^e|XtROUgyrc#CW)*Oj2W zI4-%>mOpVx$$1Mvf17$z_?@z(M0AF?Tl|bACE^=mjm6JiQuZHzfIN3d`BzFKPT4$c zLTatzR6L=3#Oe79I$`c1rfcvBCO`F{`XC2S)Y(vHZ30ncSAt&MkQ3?wb>~sG=vO!z z;K`p|+T&2e4Uc>BQ!lFRq5Q4*5P4N7Q`wcE*Eh)7iQFn}QF80u&mw;p)>VCMO?!e@ zALx%3;O~?Sd@YN3z1592GlWO%`Gz3KI>=`I5hCAd%XYAA^n2A#)lMI(c2+Iv18vem zq)+3p^r2$&q$N((?Y8s_Qj$(4Kqrm{svk+K^JBwUH9A!xD>k*$V4YT?YCoH$Q&~>c zjW(^Xq@^0P)+Vz-VjO>q&CmM?Lt_qACpb$q8%)mPZ8Y-HVNva*6t zjo}#s{ecg(C@-`D)oU#=6)!Juix@oy4MO#kX-t3H7F{~ijcH7)Fya`*&Juv>8R+ud z!%X`|85%p#2sg-qF0z?y;S58NVYB+$Ec*F8&X(;6qhT18>d7{<0ht#_CX=gbrpCYTN zYUoxuSCW-?jpTA`Bdei!&{n(1PBdVv0`-fz?=?&AX$P4Bx+NvqLD)IW&e<$G+gvPW zvvamciTjDm&N)!=mi<@a(p7_meupyPvNH}=`Jcvh1>$C`^IlWY}uMr*)b^F zC|$FeMc+r!{vzaN-ac9KBg(ij-c(D1jthk%w6>F>j8P{OOxh|>H8tY?+lGzZRC%(gl59^U+i$?9Sw4w4jYT(B z2DO|{w3@Lf8w%JB$Ng#*&k#(0YQ^c`YC7s=KgQlM2C7$Ad57c=un@@NU^%+ zJqY50lDRvJR`0?^n*M}F87gDE!Aksk*l z+1Nx!e!iY0ViO(tg|M-Sj{Hj4*hEKuBW!G9lVr-%#t{}!HIucVCKtf{^9m!Oe0x>qxk+`D3#wI$F5X9I-NAlEp$T2q2 zkpjg|G&a$ZLNybJv5AfpsVl+F*hEK4)onnGO?0HUx*TN2COT55t^;Chq9gT!7@O!w zgCNExI?^bJv5AfhP`yyb*hEK~L^fj+9cfW_p`OPbF@%m-L+HpVHc||sBUceLhR~6# z*<51?9a+uR@=2B&SU2_-usBDWVrO&mF_oh!sgDP#>4wme;fm>E2pwrPFrQ>2BLsG1 zcY#UtFCaTw+R6aM7-Ncpc9$vu|2{d z1dAv04FOL;ZsrC)==d}c$$WDZKt~$KM5!AFB99}HIfBDL2) z%(vhK0>3DU5;PFW{E(T6I>?y$5kWV`21-Z&0jO|pb)x4076Xy29*XH=Ad*#PU>b|W%Npn*vC0BJ1^M6#tb6EqOX9ww>lQ7)%?I7J$PKM`lqZRm5e`~B7K zekZ(uf&1^={ZRR~_qj`$VPB>ZPTS|~WD7R77LG7gbe%W0WhfMEY=nc2jc~BB5e_ys z!l{joNNQsvlG@maq&7Apsf~?DYGWgk+Sqt-Pi<@+K>m%5jl1~2v9TQkZmErpb3L`O zodO1_jg8x6YGWgk+SrJsHZ~&v#>RFY>e*^zVO|%w;P*)W@8gDZDV@@RGC-<*w{9+ zfZ5oX(s|d4Ujz0-klbZ|t45MNLX5vXwTO1u*&HDbdhx$`5nY2t{reHZ`TYp7)k^!H zcZBG&;CP_ef9nM|1xddjA^vYVLj0keM~J~|QoG+BcJ~VuJ{(2p}!I^`wM1eP7mdf$N-SX+FyXDhUw|FIJ&1oe1!wI;5$Y~^+_UUQ# z=Rc7|9+G4)s|IE_Rz<@-=`8i}TVdKyjt^fa0$Uyhp7NHqP^(`fpqr_mz$ z3e=oNqNVc5r8$j6d&_5}<}?zmQ|lm(IgLc?1u>_QXoDc;G!ktT#GFQ=>7SlP(?30p zwy2NM9{cHO44s9SWqfxSwNG5pRcx;uOrlp2GzXLD)z1Jn2a{;((^Ec?K|=x_agP5c zpkkxV)U$v{>JLF``oSbRTrph^Cec;{^I#GkA+Q_68NiA5z#2&Kk9>OSolY6#(^KyZ z0nH0U0nH0UPTe@4wPX);qI~bu zj%|lkpiisABc0yV4{gymAUCSp2A~IYw?=e{zIaERfb^w( zTyJR9bQAP+C3-bvDAl7;S9e{HT6*Xha?A9-V=@1A79LJ|>Njig#zQ|>g^$!Vof-Dh zM}c#1eF)O4w6_z~-})ZZSgr3tZjHViveoKgLtyl&W00qxJ{7gp>1RPxuZN%?8uZ`r zw^8o_sru{g7gU=@<#VUtHKbr3Nc%`XSdYRu9-=RYgoo-%jL2M_Ko1xrN|LeEECN9v)VKT7Y5 zws+{Cc7mEwudQ&L`T8oO|d$QYYy~NOH0+LGPWSZ`uLT0`!TH`853)`u22v3wr4c z-48V`)eF&AXX=fB&(ieWbGH5%x##FBP~*A!5y0o^^=Q%gdN9`4GJPi`yg-jYpDfpZ zL#YdO9{S`WJp$<$>$AY&68$dzUaB`^WnHFy%=63j*QoajeLiNw3Y~}E_=BE_d3dG1 z4*jrFUjPoP^f;tkrB4NXwQhy{*XTUdc&&aG9In$}g8yp$A^Pfiy$d+spv%z@H|lZd zlbiGbXx+{Fb<}c;eiyxQt9}bB@isjJYv*>o9JQ>`Hd^-Rp+hxEfpd04-MdH9H) z0Y2;W8ub68`gO?pnC^!8@VFk2zI{Uf2zj2>Lor^@=>Zsv=k@z&-JkWI=+zhW%i#H< z?unF_^xKg3Wu1o>y`qmrZ@j8kfZJ<&DoU-_4M=}oKZjPlp}*{l&<#2SN#544p_X^_ zILx$-`Zvh%u6`5!{DD3SGvPzM3VryI-h{Fr>rIgM6MX~f`c#j`%=t_of!X-EZUE0O z^h1#3OZ@;i|4o-*1b@)Sg4>V!Z1lk2^}T50PkMTVVB)7~|+Fe;;&N zRQXSHZ&v<8m?WO^??By|%0CCyW+}f4ZHX(t1WnCW{(Mm8DF4k~*rJv1V+JIYA4lVo z%Ks3>^OXM`D#}-WUyP(y{(IO8eC3~wIbERqndpE*)DD@8l%IzY)q`hF%(}{5_C2O8HNr+!*EWil&TJ{%)vf97Y8*YA5s( zrt)~@S0Hf$#sOnHQTbn^zBc9OVDU{-{xr02XXVer@b9AhH$c*^`~%R*lQG2TrCpV; z(7RKV{}H-wDh3YSvl}`D^L=;aFUM$3Q~smqmpzpKEhgQb%8#M;z0ecr&*{p)3jg*- z*I`g+U>2ZT_fh^`=(?H8?}s+*tNfE7%Pi%uMrX}del@WDFze70`(tpx`T*tshS@tu z`NNTSAm%5!=OE>8Lcn6l|KxP zJ`clzIdMKl8r`}~`Ol&$7ohE^VY%`bf%S!$Qs|J2l)nT*T#Ru*MVBc5XH3OQmERL1 zcA4@o!qUDRGX#tB3g!QV!C9gFBCN4LDE~-|`<2Q+6|-Qa@;gxbDl{4$c@<_INUm1? zQiyvEmJB-iTIFAcHe3fe!E-fOqnXz${~hqW0gXnBZbV@2s83=%yQK51XyD^J*oUBK>3vN7ovNfR{jUz@(fywyl1gG zu+X2wG=o zlzUzIt3dJwCc`L1c~t)AVErcc7qss!Y+ab_Z)0X*RNg_iVj*nA%E9`37keanX%i+i zBzq6T0m}E4KLa9tp!{(l`4Dpn%sx{7M)b?a*qV{}3HCZ*pJFQk&(E;MqV1nUcuf5- zux=sCm#Ux#nzDH_`meA8P*z@Oei)my@ivn+JfnXC+xh=oe8WaYYSZBWE_|H>kNyNyMfZ{_pO|3QBxzV%m9c;h-qR_E@QCRu|!J_(s-;?MtM ze3rVB*%(rXBWSSG?~RT6OUg^8hBe^QV~FTaJFXR@k<|J9Xnx< zjK!}R$2#b3A$~1+8E*^m>wW-ey)DF7SAxcPTga|CpY-&$kX>u&>1`pqFDnWa)7wIJ zKf=b_LUtWt>un*so;E+m+d_8#4dg>_3)urmgSNrjLUt2jRZMRS+0BHFw}tE$!q(eD z_P{I1=T&rWBBwHz4?YaYozqMB$QS%My_pQlR3;Sxl=jd*ikP zk!iD;TSf7W|AyQ?gpL1(+-ky|&GvI^?qv1izadezoYkMS4qYq7jQ@s2jj4V)(`!xj z^xu%^%iY5GZ%EW}8!-MG67`%K#(zVi!Bi>!8xoED79=*O1D%+x-N8p)&tQEe`*LBK z2+_$psY^v8-FISEy+Lh+=wyRIZG`A#qd{$i=wyF`h9h1aRU`+nhM3nzK23z<-c9oX zHxo{HXJ7#)TYf;z+GBH)11TyZM4Ol6;bJWAl4S~^Dz-uLPO^_ zvz&y6&L8v|L57CTA4)+bG<5#W885F{~)`kcRz!}DH7`Ijz;j$v82(Qsoc0fc8SK-#ec zW9Ps@V!1Bcv5;~@@2$(p&+-0%blubN?jS5<81o(_T*-7y3DWmw(IRmEj+}R8cGWKc zVTlJKH^vRsjrBoi$o_H+sAWrliG_IJ@T(3)Ql~c}1?fmQ3X3`PJjnS6-BR}fFv=hD0(X!AZ~gj z60aLYA2L(CZWMh)(2cQyqDH*~sBms|qE`VHqYA|7Wx5zuAWpBqG^#+H-YbwUUN=g5 zk%xHQDB0q5qhyQMjgl>1H%hBHYb$CnifVY**B@%d$}&71i?QbL-O$CK!1k?D{AskZ z?K}2{#|$y5A2A)di-A^(<>$y*KsN&IElw~-bK8VP{G8tRv7Q|#AQwI{=JdW0nqxJF zl^_u3oT^dG9n0ypT~);CBj)i`k~nLCR*5f;oro^)15|u*j3>IF8WoB2jR~B42%9pe z`WMVpb>7^=(KYzh+>RTPvesH)>$5@**X8sfX^8zJ{z~$lo_3y^06gKHRU*lbC-#9SBle*mME<$B1WT? zG&Kv4ni&*+CslYCOVoMR?Ack2$z3@eb5p=625%vzM-Sg7r{>O_POwDib@{1_{uXd* zPH|ebO-}1Nb9$_+OlObkVY_B#iqm_RD7D58vrJNBHXiD|rw%hinuJs{!33KH<|Ro6 zI1O*w%u-|?oyv3?zP9Ookbb#MUm%4VxwSOHV$tpb13>YxP)rFO4+{D~sl!(*3sChW zOS3&_-Vz%4KtZPJ?=+lb^Tr`hnLSL(PYEq#dALAX;8Zvbk6W@`K~`(YmQWDaxIjUL z+@PI?&(rD}BZLss)YTZQ<{4np7)+dlh#X_Pa2}Ch_?7@^c+}>c1!S4!*WYRU!X{sW zWGBvp1=p3m$ESM=c>~GTQ^-bw##2a57)n*#JNZI8L6VfGknUYQg$#^b8On5;=i*i~ z8&`LSP|Kw_1M|v1C*?_`bc-jE#1>B?iLoh9B0aWv5-A(m5(OJxdiR$5@VLdRyrm_+ z2F<}$zC+4mNYCDb0*@gT@E8)f8mT->4Sovy2QP=(6nqbMCyr~z#_^P0jd@nkPmd-* zh2IUY@g((s#tZiE1_~KCy8UjT@VkM+?*26QEmSFqT2W-s*P`>+7vRXP1Y-s1Mylbu#^~{ zaSv3M|G%&j*~o_cD=QJUHfX!=F2tLQ|68m?K2MWuH+MZH``?H}_oy_#N2U2aD$Rc_DvfWV()izJ8#^hw)66Q0zK=!L**NQVF0}t%SasIh+mXH|Z zEINGcVw^>f!71acbEw|GSx3%hgUe^zQWzdvymO)d-Sq4oRXBjkQoW&Xf<1E5~aTei!*Es8PN^Fg@mQrG4oW*tXuZ*)u zlQPblh_YgwH5jk!t#KB`{ZEavD5y2gl48a##wCMR>oOpLR@Q{MREU?an^<45g2E&s2FDr2Vjk}2*!p^hJ)Swebd`1Vm+TXsm~tInjC9&tosTp(M%Ufp(-9#c{|JI9W3h#)3jV3F7#VESSd3-GSgbDq zYb-`EFczZ&?tft{#!=apu^5X|_(kMwjK$6%=el-<4+LvE@Fw4Iu4Pv^o|vBXCAWwN zcXp2M$B~PBM}l705zh8*Ls#p1(kHwDq-iK;E#6(EX(Y{HZ#qUm_vakkPKHSj;4rny zFzF@^(`e~l-Aob2LBbCx;nQT%LQss?E<#=xH%R$UjoO6ZpBl9t0@DC%)Fz-YYCDdp#;ENqfTo#D zl)9}^8*>D=Mr~IF_!gtKyO3m!+C~7xn^6*3qc&z*qc(zRMr|Jh70xhfTMsxeYGZm} z)Fvj|piYg0v9gCgBI0o4eDx=!~Dq9YB8_rl@6SmtWf(PUE0DXDhMD@PCQ@B%6t zLw=6;1DTKA1W?66i$V&zjuBE<`rA8m*#4`O0Q_>x7&mPMl> z{HYc9R^f9vvHQyiufjAu8`d$s#PH7z)ADcEelWQc%fD#&7Ul!*C8mF|@LJ$s0m z085Htke?bG&Z)2rH>Mb#+?C$6Y%rk>B|V%$5N#POf+^C z5JTU<;oZ)Xo)E==_YZ$u3E{p%dJCBKeGkAN2)qU$qZz={0OkT{Bz^y%fIS1Oe+1Uv zRV@G#0B!=%@Krs&L$$nLBJWQ_w}W@To(=fp^AER;e!qgOk@@}WfPP38{PKPGfdF;{ zu!=xCfX@l+4WQ?sh%?|I01c0#eCK4~4fA8bqPf8$Eg-6U$RgxqxqwfbZEq_`o-=&h z4v8h@)UCI96V03n((SPBYjaccZu@XcFFQ@{f$(Nn7h9^-uwL-brpe8gGBr&mg-;Fm zeURe!^uNvTXxrWtzd_;G1AaM!1NknpR4Mt+*lOB=fz0C_PBLAaVmLKig|7i*p$$zj z+{;p>7`Ap{s3uu{hg!;VP6qtcjPQ{GzXMYI&bCz3WDv|+#b#-lVgx_5Ti|REEJb;a zZ3oi-Vbc#o`pq_du`KsSEO%J!HRakRd<-aF6bf4GaWCk=-^sA`bee}-no~g2w4X)J z1MA2u>^gF7WO28mwSv3JR85oD?easg&kwFtAD2=m<#;3D+y z!gt&-;6CpEh_1$7@V3K!X!@zZ_Xx2Dnz>uur`ju&iM?3AfEGAJHNpqHh3MNynpJvvoXWsZuMcpzGE#+ODJr zk2U;KThZO2bpgK{Qv5bpsuaJz+u+wQ4!e7g;|#xDq8N{dLRaEL(Z2g5{Wb9Fy9a=U z+heO{ZvP{Jtq0bB5rFa?BF@mI0Qkkg(2E3EGpGMm0G1)E|E&PtA#gu{w&5UtLTJvP z)Bj}vmmy`?MgY=DeXJ0vMm?b}s_-)sfKyE{mTO*(rfzCX>OE3SVs%ou33qWQBy53Ty1e)Geps|+UpDblXAkd%H z!hqk^DSn%}@>|n|Ux**b{j@FH=l3U zR4d4vN6@V$eiMn@XOU?{zO%?|B1yY$c#3E~&mxB*r|Aoe90SC|9${`h?9TyC)8B38 zDafp|ne4IXEy#fA%*I)xwk0>4lYTn^}_!mSTjOCT%&~OFO zX-38cINqB>!!)5ahlV}WmP5myYRjQvFC~YD``Ma)(DWY2p@NF$HdpY19~CQ$ADhPJGd{jUd4`hkz+ggDATm*<{!>I ze2^I-a=t_{KSMPmM9h~+zxR$nWzM|BDf0->kup_YVeXz|BF-q0`BkFp$0DBgKlVlw zU!#^cyzJYKQPRKbIqVOQi#Vfs3q9A$0LkR1-YLREv)n;{1kH9`^W_fOZztYCn;x)b z*I=o%pwyPV5-0ILr)BPCGP4%j9zt($M+Mb;X;dd}n+m7#e7fDm??F^VpKhoqXW2&` z7e-8ngPqef#nL+l+d07GVGuaR8v6smw+U1xxx0NPn`GF6ks1OFB)9EZs)X z^%!6VIW2Mvn*ia?Poo;WZ7MW$wWazDybj(r6?omB#_RlTQ-Rm>mWus;&$g++>k~`$ zH&DH^Z7T5k%~EX!Rm?m_r^kkoHuCW)Hq~iL&NIWn{;2;av`$l>ZUMbUGCx&WbA2KNj=G@~DHK_wZ zXnFOBs!D&uI(d zNSBXn3xY)Vteg~l&{c7kYC92xyecc(=AlD)RaUhHv7>wSo)mlu*86O=bMW<7+oveO ztE$hW=YN8~AY45Xs_h(fH!nS`?O^2c@(*hpiGRHG__ndgZK7X7grBYO?o=6 z99})*s_m~BUS9r*Z6AP=mw$3wHOlky_iNkoA>5=hlgi=MBdm6jkLD%@AI_lX^|Y zT@qJCShanyE1ni`RXj532rLU;6~k293*+D<30KA3Hgzzj6Rz&PobmZk0Xlo%i!H=_ zAvbL|^MzcXkT@vJc?dscZ)1l2ANoRWZ%ooi4Htw|9yuH5KSyGsM9v||m?#h7f8e*5 zaCka1wm9p}*y60$c=I*Rdfgum26J)N>!vyDb$><=@Kpg$_3kf(jk8|&SHi|wulpNe z9Xsg;nxIO}!Oo%Oou&U)PXT5HNAjVm*+bD=}*6XG_>vhwe^|~$MA=o*a%~8zYZ62c2GX<@t=M+?FMko1dhnJL`3ai*sUe z*6X$!_(Gh8+z|r1vB$wL8pDK3@Q*m_jh#*z#943b3<2q^H?~wjI_vd{dEbfWpuo40uNPpKOyEG$icq%!XWkAKI;tyczq5o_7ycqW<9yu2%m) z@Gmpwvb8~xO!p)f`DbRFKAnAK=DK^O74h9tbm9M3W}F4q*_VIgI!IRMo|`6FgFBCs z%}lcWJ+XNzy}!@)-;0#6?!e!Oo{D>Nh8}>wuAYuJ=TZF~&hf1U*4bCkF(cep$m_nf zmYD5&0_-#5dUGLOg=>k~t|ex>mYD6D)*gMe#BA5UK$8AiVz%qq zIHN>$&mK6{X^GjcC1$&pnC)6(wrh#m{=1Rs??$HoH6zmkV`N%jjZBS=XV%guv8=?# zGwZBpuopOmbikK&E|XOu9q?sc@EVe1g;W`2T|}D9LOS5fx|lSu@nq8L0Ohu4Z9KCs z<#H`D4(Q_5`I)GMHjeQ$2XygTmNX9N;{Alg+(Q|0yW4Q&1rF%qb?<|lu~5t|UqNQH zP|WU0&{!yDR}eN9irJNfjfG-%n)|ryH1~1YRjk~&kIU{u*tn0&t|r{seOz`;1Na#W z#hj|#EOyvB5J@rPJ}#%mRKJ|*wWfMnDCYF#{l{1+=G5`VVk{JM>e;EreOyk1sZ!j> z!d5W@()N6d#2I=RJ3 zS5lmG6({o6cZ*{`rjxF`Hw2_TQ{ILerqZ4%@690qP1Betb;F*Coy8o%Vb8P)_)Y;H z*fZt5Itxi+&y@GpH;@xsDv89NDepsOiak@_M+Ds%8z{%8kX_Q#IW2bp^iR~xk>CSL2oJX97;LZE5UARj_> zF-nw*68TV0e!QaYC>1^OT+TAQ4(+IzL{{s5uq~+E3xc0x5u8Nir{-7Z;6ZT#vIgz~ z%cDa8RNZ8W&IN+_!d`e?Bc#KRVSxK1ys?@Hbqd*S=*sT+qXTxcQtSc&QtaOA!Y&lU zz9Rh2KgINRg;dAhemdZHZi?TnmMFz<6>N^u#S6toS$>aO(mnyd)AMp|b00|Y`@|Cc zL7Hn?2vaW0)N;x>wTomI%nCStlH%0Y5~U=Yxs_x)SbnoDX=)&DUmNhtYYztEgs%KP z+ln9b)zWi+>?+>_A-vv~f!!g+@6E3K%3&|nx#t4;zOba_LC-xoG2nM_ieKhwrc*li z+)T?9kHa(U{I~&KOAomWIo^Tv`8NGdq@QNfkC*Ay$mxYp(`QY5>srBvyWr~Tey+RLU3K|C&pUJOy+qXS z+n-g0x{F4;#&ww)x~Lk;#C9&o{5Ab67HChF&gn5#~T zdZeRAQAN~YF3!W^;TNeykRdf1;Z|}-l?$p{9fx6F<5Cw~ir|L(oTmn!w?i7{f?AoP z#(0ez9YG5S8p9?YOpkF*IT9YP={AlWV>pibu8#2@kdIo~EsK%K{VCIv5gZV@e?|3V zJ5yeQZc+{9>%ew+^2Vd1HK!>hc~-5rRZ1?Q(<&v4G0L{!EkKn_oFsihrDT;TC0kQ! z#@0~HSTd|NR5Rv}YYo+m`8&0Sy2aA^)=;5XHoWz12*__@cx$LREU$0Yy+=3YpgS+_S?q}?!_*=v7>Q=68V(xzpmv}u_?u1(8I zY16V&+O(|l<=`5%#;UVhGD;zbUb_dv^eMY?`uEOm5JNwMmqw-@4R@C3-#7t_*!~$G zfhhOvIhbQamK=&?u~XrW*g0<==e&`n3|4uZ^G58PH;;4Ph@JE1an2jLgfzKc{xjgV z0L}tdotyJUR^avO<&JKJgpsRnhC9Y{O_6K({`F#`{|)YIH^AwPPDj?@9%wID&JpF* zzD@dz=3>s$lgzystt#i#F&IaK81!d2B|mqLD5w5zgt*H|b8!g-bd$|Hp~7RF97lV9 zg;+0Ef^4HLbgLLa-e@24%80#A8ku=!#{Nim8^a;mO=CgS_n%0RyADs%I{n4VX!IB_ zJk?ff8N>7LX{)u2QEREK)-sj@4VAW9%h+-}#@cEvW8Xq3ZMBy1Gr?0kt!12Wg?3uY z_!s2lw3hMTAW!YImhl4ea$3uH5jvfATFdxmdeGm&bVj^^+XLkG$a&ubC_-!O} zTFdwzl*VZ-Or?rf~NiwIkjE^9vR}pGMq^bJJ*lc(kC;ewJksTJ)j+YO=P;D5DWTZHWkZX-qEA3t zT#W!dL@~VhS@Iid-BeZTVd8eG$^#K%6w>%-F?&;hAAhkpsipLnh?82%T+veI9|D5w z@D042l}tb_Wo`vSwp{Auj@nasm9d^*A|}RzPO&;ZNM39v!ejNNa7Sa0V_=K*;^Tll z^$m<@cmnixnIw-&8QAj%4_*mvcqMdReGY;mQ9iSgC?As2!;w&J+j($QE7_&WWZV3< z3eLaaby6mi?(O&-Z#yB&OUR^q`&z`F1#g+`nctxi-nH55KWpdL-Wo?Rdpzc^5*Z=iUi-fPn9WFe%4pe$IUlEs^$4_|Lo~u?u18LRkK9 zAuKH!=VDMbG7&K{5iv3mF)|S`b|MmRBI5VYm=4lV3%@k05YK#<&658-n)SwhKL zBbzDN&jNN$j_iS1$YxkV+ zkj|WO8dW)147a0o)qs_5ojb}cR@KVAps%fxHTnR8bhEIqu97wSK(4b_!&@zD^g)** zc0FTdjXro4ygerY+>%9k2m8ut@YV>{B{IH8udLv=W9&tf;gxd|+tYjHp70(+p?08m zJ-j`jcOJsNRyzfrgFQ8ro}J*Sk+bTqvG~9A{co`xd>6PdUpLx#ubL&Z}FFa?f;ONjPVZDu534w;}2sWYg;!I2yu)Pr=hj zTy2FzN*al)HF9Tmf1nWLH*m4dqXuI0qmDQ{k>ztak!f0Xj>m*lsuGrzX}c=Yf|mA4vT!)vZ5y^eDC0vA*b zL87KVyKq|E8tua8OWHQn6+ogUEv`wU7$s6^U4=F#mfU4e$6H+li(>W$f1oM5oQ`{Rc)o~y2eMXWS6Rv)3$xMwmlC`)KUSxv+Bb~UQP7+q(L(efVkB{Gmp}lf@az< zFbOn6lD;7{Qz6hyzYvcp9o8>}$Mj3#G5vOhaQw!H_Y0w!vig1@G?N(K?@~na8z0p# zgjmXJ`zQ5g+yI~Dl{|zukHu1&rdqvOSO+l_jh_cLcInNCz;*3R_OAD-do)K7cp1=>baL{08B<=0MQL z%<_FPS2C9%Hs8EI8S^7k1b5tA1^$JmV^7Tc%mjoNn`xjlW)=7cW(7h@Ox<+A59UeG zl$mD`n=rLVRc;PNY=zka{432zkhYuo1U$Q&D-lv8C`%9Yg?KtMaeK9|x ze479oYwtJKxR&&^_Zw^C+TPQ=j6K%;44fIIyo^28n{ImY3CZ8o2 zLWXT9ny0Tt;bI+RkMe$oJx8%^i{Y`#!@Szrq^I&QFHL!vSI1zdJUk9gsV}EI%&Q;4 z^kR=Uzxq?Ar}8kr2c1@Vm|sJ;RUYQo(ruN8`Dwe|^Xo=|++LQRpSIiGZdE3mZ5C9jgCMcOz*=>d&yCENt2rG!w-vX<_qRxMz4VO2uGl z|vyuOQ#17(c(oeuQ=&>!kRgI8Wfkmx{zH}``RGkOw<4m8-vNYQ}?o9Il_fo4NjC7huH z{Q^;<11;&U7%n={k}B(_4z#o;<1ggI-A!dF9cWof2U?ao3s9EQfhHRG%)}OU) zG#YiFnP_&^dLV*y=8UVI4)hELj{AHG^26sJXf1x!%C~}02Re?5)F+{6u{zLQIZn>p zE7XDR_B>*L39r?G?*1~oAHr*OpyN46T#WONRtGwP-og98D>~4L^q#OUl$WBdoW#)p z+m;qu)#hZDV(@ejA5R(gq<00qqA;Dpv;{M8owyi^o66atsue?VdvPvTWfh`(vv=aU z?}gneW`fByK8BggRxG4mbszTjQ^10HRq@;lPq%yUEUJCk`)N$C=4xgxW(l_65B6CW zF?Pe+vu%CVW#Xw)Pt`wJ3eB4f>jtj;sKa|exzy|Th`JRi8(xQ_F--V(c$&mKsM91i zQFGcv&FLU4vdC}gIW~_P%g$3L9U1a_Gs*8JN0j6jZ?~Gs6u{c-O(DOtll(Sy=6CY<_zi&ebEs?8Vie#pa6zMq zR&-An-W}oZyYQ2wh;3*^C^VZ7brg-D&_;?6oi3Yr0e;8B+?m(B+R?OwrcP*}IYlHi zx6N<4xFLw!P2!+k{raQ`s*w)~s9?>9n%m||*9pde@;FP0BL<*zmPC;!`@GjY+!0O! z;bm5&7>uZeW@akA=5rhc1-i=#gaU~`>s{Oo#J#(f)GXS3?0}!*I>y&dlz9||G0ner zF^7OdJq8$rZ;?MZM3Kev+DsE5sR60AY*TVx7#foqXsb@H-XkHUkR_EQF9_F^+RF5izg=hWer?>dGmF(p7HwoP z)5Q-3vD$7ZLL~bI%>DuwXP_uY_8b@|!b&PT7@is{!b(TOTIWX%KPTjIJ$c-*6&^bC z(ByC{ebs9TTS{6lM*9d9PTtY5A6bVTy%`7bRg=jf+1@375D$0s_tNhi|AdhiY4|)z zH{H@Xq=6*KJIC!IkO8SfAjvz$6RA7J3sQHA7o_eKFHhYmUNL;YlW1yw3x^EI#vi|h zBL|$1KYj~G54aEgk>A2ylh=z^)(s4gcyv2g4G0m6?zMwLgko^r6}2M|oImG)14ob4 z6OTXQKs|cyyrcJs^M?On zY-hjk4R~`cuByj3V^5DZpR>HT;BolKdFbC%EQOESA!rbOF8_d&&i^0JnuLc`7H5sb zyjF{+4_lRe?Vl=X1` z)WMWHNWWBLtjKBXf%!p<3-BDf0FQA2o?{o_d0c?!*adj343oN?^aXfMpH1W=3-Fx2 zbI6Am?&R17cpewvId%b_#|3zfU4X~-zZf*>3-FwQy^%Io7T`I9FC`x?z;m{tXkLtq z!<-JXcMI^GZD~!*9;}JhK0|sgz@v5nE(dF(bqsa~Yu3Y=ey}E5e+@#mI9Q{b+cBib z!5ZCr6JqVb8r?#-Jy@gD4%X(SQoMsej`g!$R(~X zm0idsuHVceqjAR}SHJ#JQ0H-p>-QQ0r#&d-_Z|bcTjKgH762;-pO^RcZzs=C)b_cDdM4r+^Cv{zZpeb?&SJve|TmW@$^ovJH1oH(>uBD z^iB~^@8r7EJ4HOblj~0J6!G*adgxs~cTcorA&^iHljy;H=~ zJGt)kP7zP<rU?!5!uUir+12YdMDSN-YMegom_W%r--L_atEk|$memd zn5TDg-RYg&)hwi(-pRd^PJ4PM_bL|Gp5Dn#p5AFjSR{H4$|mP@D0cGn4qH<~mxiIm zp5f`8pqkkYQ49}wdM9_NbuVZ5Fmb!nJ9i_tL?KP=EM{NA(>t-n;^gU_*b;H_^iG~A z9`a#_!TUSDrC!b_Ou*ASc@+%VQgxFnT9y3T)A1&d(>wV+IofzJYE|;pq(@jAoA53bJ3-HcJtK&%+3~65nbyG3PTi(ciqe zyqYVB_x7vi#CpSiUXQ7c^jVO3`8OhOCX%Y@>D9aozWnA-s10WnUIXH@ysIBgzSFx+ zv+wkf)v0Vsd}jY?%XfO$Ss?(eK1aqbYiy{4E^BNUJ-%;^&0;M6lIsyG7>j=n2LZ2` zXOI1*3|7TFd+gh@$Hm;D=-ac$#XNiLUqTv(vD^cvEP))x;;-PbA~$8RgV~ltb0o?n zq9^_W4l@Ko*}Nn1$zEO`LYV9b*}hRd6jRu@b3`r1;;bXmT*+dbfcPDc?V)`Is34jm9xTf3VJaKUR%ySEay^q zZ8_UUf$6`&Ys=Z!mUFBvXFprc-EBGhlQd)5L|e{wTh1}vnDNbSyiV#SJD$etwfk=o zHD)&S36H~3{fr}uV5mlA=*)MVMhsP=`l3eEj@TVScCS0iBe-_oAs->aYJQSco~x2T zSlQG%Gd=*dCLa-Mup>$ewc|b^r>l~jCOM*{P@i=cY8SjPZ*&5&Etle(-j-vfEq9l; zoG5KM#w+jP*j7WpHIl%#W!OKZEo)vtXLYt`-v&{wUE%+M&eUGQo_M7n48k}`>N3#$ z{Kk6M>4)(w;+wa3efS#e6>c@mm#v0%DFr~?tO?5FH?P^_j3vvv{PE5hI z*1BrE;bX{`w*KvUS9ZNC??m6|vRwLOmP`LD-j((+kbm`u7|dlqf}eI6$WK2Em0y31(G}#^aDkmn0Fjc98gx9~YLx>K^%#ZQ|pMgu2ont_baAgH)Xl_S^Z*H%{_-W?!%5I_Oo{(oVE^lw;@ zAKD;Y^8O>xZWlyY+OX_FWE_Ux|E>+vfit;Xa>H6k))IL*O|sU=wUq2%+8`Y`liT6$ zN~%t`vb&POKefA(G;ZbpPdM{9p-Aqoq=ezo<~|tve`d@Sro@Kj%T`v%oJr=qzTnPDLYbX_?n%e-Xo* zZ1(n`GrMVc(3$=3Cl5Mvg(?`FxKSnix@@?ck8!1H74=_=;BbM#zsIWEO(09%Qb>LFVg`yc;+16~7_QlQBdVue*n# z_8{}qaN6Q9Q1W)0_!uL8w~23E=npsX6~FRV1i6FE3*p2xltk_zGb7zWW;)Y0@zrR@ zd8n6D1b29lnc?9{(iZO)UNQjc5?JhFaI zMEw>VdX0snAxv>NJaVXbv71t-4%s$fHcNhYI(~iGX!xjU?}q%oN%H%nBU&i@Fe}Hg zR9xB0^^SamQ|5(M%o-P{4x;g7k*wF;P_k-Al$30WW0I1r*-2K{ncvuxLVgpH{Dybt zcTcC1Vr!Bu=$y{%CcF@`Ta;vXW@mQmI5x$2DKNhjLRLz}p&TwtA3KYi(1viHAobv+w z%C(waaT4uW6PGrU(XKk)DT@u`TZc7xxCjo5TA213izpm`~vGdZ#Va zW+I@)>JAU4Gqq6b6Y360(i*PLy2PhATM(~d&r zHQMaCyvS>^*>ic3*UYYCmlt_0>=Sl*ktfqXd+|qJ`cbI7w!vdV>w<#zVR#+Lx}ZQNf}Z{wv%`Yq;hsuF$4MjWf@yH1uM6U< z#v(-41@YA3o_OkTPkfCKa9t2j9qx(C;hsdi@U^FryqxQT!Z*apbwS}e29$GMP`Lg> zIPJQCf$8f4#-y(cz7GB2x}fltLKH>T1%+>3K|Wp%iDX?+xRH^vE-2hYXWF`8IK09c z>wPCUv;Sqz?C()ZreJI@}X9uoqPH+ZU7U zft}yS*gk}{My06P2Yvv$H!!KI6gB%Gs@da*Ln|(7_Q71HkA}BW)&<)XzpyW5wQoW271AS50{QisE@2MlKM5-fW~UUQjY70}^<|Et2o&2} z_L#XM66xzOe+7t8KhV*11I+=JOYS_++E&IbtK_teSHF{^Y5>()E-!N8e3<-B!hZP0 zj;23odWA*bfu6fu%oupQhP0{X8(`IFr<(83nVM=gg;PzEG>22oa+zxOPE9p?hf~d9 zSnqJEnK!O?IMvMCsdsqUKuLY?aH?54ymvUKEURk?=ah+aRiD(H5@%$xyhEPDNM+}g zXP^gjP8k;EFSet2Cx6y8r|gm0wv0nFE0i|mepqBOUOruBR=UirbeUQC zS`mUtXzDfL#-^jqSEHhYT~+UzY} zxEtPGAzsM$*iYhxA0e-@!ZE(Z>vQ4jIT@*cP&e=-B0J%PcOobfWm`s~8}Pe@ZlJJTLzDg^nBgX*j*~`o z13lr89+AWh4MKhtGZX^q2DWPa_yQz%#*f8mF~ijiwV2`Ua9Z5}10`>V88Sxv4l`UE z`a|77@hj^Q~%Kv#a4S&^&A5WArGbU4d9@;bRQF-qE3MU>80FL*F)k_5eG(KoJGWo9}|jK zd9f|fts4eE4r|puQ<~X9HWG{VBvTYr|xsJ3doJ=On*_JM$a*J$?X1rDacaq}5^lt$Z)!S2jOv*~=Z#mMuHm zF@>h(GpCZd7ft^)(xZ1$sni&C{pN9mm&1fI!;h8z)yD4H<~4S66u$+<4njdC5F(Mj z!GfZVa~#c^pxH}k0E!|Kh-BjxF7AEAo#Jv}`iYWH2#Pjta%7)^>{pI#5y{*Ip~#Sr zHJD~D`w(WQzjpNBfc{xaZzIOI_KZNK^Lr=DV6X937fcbqbHOO0i1@aPD@2kK#G?|J zm)H2Mi>O3Ii$w4VZrsJyb_0S(CWD)fcESA-+!Qw34)k2>V#dI;#r2#t811g-yo}D2 zLM(YbCrOgmb5@H&Y-`tZmj2ZBoMox&IdLcFAsFHKEf|!3CugWU!%dwNFzw>EVq@}p z&PrU*8Jc70mb#O(d+JWks`NWKe}S?l4q{L1DtP0_rx5~XkZ+1^VtB*`^29Kktup)VgejKE#Y?$|S>Hqh&(GE4(15wNFJ6P@C~&SbhakM(=+T&HnY)l< zgSiW_jpj1Q)?~Kb21BcfLZ05{4CK;co&`-GvkmH@)qIZMHZv7c^)=nbz#NVl1N#1^ z95n6bs{Wogz}$-?Ed$Le@E>HdAnjmtK4`Wvr=Z3<%mB!|t(k&4+0Jx8+U?D;_}#&b zMqWeAD%Af_GXc2|Gh}no_47-`%L5AJU!H{qd(}q?UZ|0yx6U?W*U>d;8 z2IV9(6m2)z?7Oq)?P=}<&nadN!l#<&A^BeB4$OV`HWNWV%{)-;dHa~@DD}Rk5%Nzr z%aQL4vvC*C+s_=2I@#a+0%;F0pP>b3n#rI)(7b}$JIEXjnpx%|$S~V9g2NmWApBr6 z0_}K+xeO8>YHHCUhnYBPV6J%<`5tb@g7OG+4DveCbb$USvmeSn&wM=^^KtX*8f>^S zS0dl}=1KI}W6gTVd7Rk^HFmst3w3pZ`2xQun)^@>3(T(Ie3JPHGA}gug2N(n1M2)_ z(-WyqF>Oe7s%e8Hr^k>e6`Eb8iP^A6nS zn2Bh|bItpRJORetwzx1o>WWEwoh zc^9>Di+K}I;;m+1JUh3Ui;&ChW@m8zl_?tQdA~M~A@(;Wffl*L1Zd?u&Dj_e?lQ-N z|J~*fX#IOk7AWsE3y}ML<_(10Z+1Yw511L~!w;H=5b}_D3H|V4voH9pHMgVwA2F{( z&c{pw{o!#l26g*{`4aLxYdX+g&zXK`i|5VnQMwn*UZ~X<&F{eTx26X|UNUb%+TWQX zl;~x10&3$Gvl851HItC)HPedl*UfV%#T(}1W-J3u1|)gQyoy}jHanxIy<`3f8QwMP zQO|!cN1-QdG^*ZrDtHkhWvXBr(qyUNFYsln;C-}XLs9bEgzu$- z3sC3=6?A~4Q3b;xb(0EiLv=T+;AG_2TLo93d@U;Y5u7baVWPl1*q5cP|pdCC1sbB?KW_uOvg{I#@1!sfx5D1U% zKU4(^@Hb2a%TPEhm$g;l*)}XQuP(cHHGtui%69=Mk!1^E+{1d%*mI{U-ZZ`TSs%MT0 zHlSb!qn6M(hp3<%YWGkTd^;TDxeDfja;^$aL5U7m!8))$0!<95k5s|wDD6=ycm-W* zo(k?k)g6uGsH|gDuq#SCUj^IaSvpn)*P+UfQ^6$Ua6D=WTuwlj!gGJ33id>a7O3FY zDA7qOxE+BDRlv)v7pY(^gg;pY33P^2RB$20JyiwS_&ZGn(HS7id1!aYvQ!1zqR{7~InXCAKue=q zm#N@c6y-vc9XVX2f|I~{Il2@o*W4~0vk!bfTRB#4*!73HZL+-0lXjJ5t=yf2uN(D>KYl{sDktHUb+d-5xU#WD!2iSdJCQhl;Ktk z0%-T!&{4qpb`{J5<*!t56sq;t=u(jSH!4_)2Dn27|3JDsRd6c;??S7fV0S}6RKYzM z$S}U#tAZ*pyH5oVqwM#qU^|rP0Tnc%S|3!w2;}gP3Wmb>unHDJvbA_f&!CffI zqhN*_d`txy=#h`3mm`NKz#5O!lPY)uluxPPSX9r`D);{_EQhU70IKZx{O75FIFOXw)*e7{pc91rCykPLFZs)8p`S+C*oMY`8juo@(9 zpfil{ymc!06Iidu_=57iiJ=Rf{Vnt?w94D4Ry+vr;K{-B_b$dr)Y1lYXh`-Rngf)- zSHZpz=?^N{86+Fgm%wb33f@7zypN$7fq%qU2j2%6O2G3&46!KtpCCNC{zrIjA`Rn)OoPP*tP7dtN$$`5$ zxzyd9JiY*LO4kTOvR4ifnQke!y-LPz_%cu+^N~iG`Wb*Fuyij z=#~cL{#J~O7t$;YDs*I(59Y>9ZtjJIPYdILSDO@4aj{Db39UwH#eay6U-IhJkjhAZj-up z2>fe11cD*x8y;S(s6;+wi&6Qwh~+udehB3skGf8W@)I-?mb;X}DnTP*xzB$VHVkZ?D>LN9Q;>FEr2)6*U9rlG3V z*FwTAcGKJJFJgF;&ED>&=lC4%rsu%>le_7Q!9Tjgn&qWVQLqDp}VHI z=(Rs0xghmLZ;10`g%Nk%mkcFRU$j1g;lm>J43xYbQqLIiJEXoO^oK}&(JOod2vT44 z<^xELftN&r)E8}Jq#*T0o9IkK>Sw?!oQHZjyTdI=eQ|fia6#&etE`(yy{X9HQPTIjgbs z-g`ob1jNo=&9N(`-~L1p%YlI1Nc>B9Ey}+;yBiM#)V@KKe^pNwr}P)7E`0E! zlaJcxD~wZhH&;WygOv4G!qKbU5j_r%p!+Mn2ijuABK-Dsq?qr^N39u!H<9q`wIJko zVrPCkZG+aqCxrJE79_&1WrYM^q*zMMt-ONoPyG2QM zhjwPSwllk39lIkPWwP=P>5mtv6!xYhyQQ7kZRpHyxMR23QC3M^pr@RBYRK-5B)dv6 z3yno%wQCE%bKMPd?7BP3q;wZ@LLt&+o)k94ww>8kc4mhKxHQEcjEbLm7 z?2dFquZVQvMvFm7p5t-e*YTV0NRv&w{D_d>-bsEJbrvsY+fF@YkYl&PQ6@`!$-^PL zvy$xY?98t6huFQ{S-M;DF)NbN{wB%p@15E0oh+!^^%C~ue|DB`#Xcds4M}ztm)Xvq zY}&q^r5o%DJJeAo>+X)5Lw30f!=~M*GrPk(OE=Q7o9igiX!21HeHpSFlw`Nm5pCJD zsVid|H#w~TU9ibV9}ag~{N08B3E^!nT=qezaHmDS8xKAQ#YCatMb@dE7W1(}*xu1> z22JBM=ka?$qb3PtJHs*;93c2gm(%yQQhbUN=j$C|H3*-!gt_zGSs+~9!kiZ(o9`T1 zGsxa^{1~2a59%O3Ydjcy^OCxEIB1>gj5JCW4!GaGt~IndLku&=a=e8T71hG0WiDV&lcV;OjPCJWS_S zHeQeS+1wz*Xp=*KAwLs`vAapGdx)ums3xuu(Le~PJ zYk|S+1wz*Xp=*KAwLs`vAapGdx)ums3xuu(Le~PJYk|=91J!_Fv_R-u zAapGdx)ums3xuu(Le~PJ>&c)$Pz!{v1wz*Xp=*KAwLs`vAapGdx)ums3xuu(Le~PJ zYk|S+1wz+@@q8`Q0-@_+ zsFRDdKS+1wz*Xp=*KAwLs`vAapGdx)ums3xuu( zLf6OF04UJ{p=*KA^#Y6r_i2I9wLs`vAapGdx)ums3xuu(Le~PJYk|S+ z1wz-WQHPtfK_br6(TL|5^5V~(6bl*bgzJ<_z3!(cKLig)Y zmYDJ_gzj4i-Cy665V~(6bl*bgzJ<_z3!(cKLigXpARj2-Lg>DQ(0vP``xZj?Erjk{ z2;H|3x^E$L|8?|@?#j0ix^E$L-$LlVh0uKqq5Bp>_br6(TL|6%7{d2bzJ<_z3!(cK zLia6%?pp}mw-CB-A#~qD=)Q%}eG8%c7DD$egzj4i-M0|BZy|KwLg>DQ(0vP``xZj? zErjk{2;H|3x^E$L-$LlVh0uKqq5Bp>_br6(TL|5+K--R0{wLcILia6%?pp}mw-CDj z21xc$zJ<{J>3EhVDBnWpzJ<_z3!(cKLia6%?pp}mw-CB-A#~qD=)Q%}eG8%c$DmrL zE8jxszJ<_z3!(cKLia6%?pp}mw-CB-A#~qD=)Q%}eG8%c7DD$egzj4i-M0|Be+o); zxbiK8?pp}mw-CB-A#~qD=)Q%}eG8%c7DD$egzj4i-M0|BZy|KwLg@alQKFNSZy|Kw zLg>DQ(0vP``xZj?Erjk{2;H|3x^E$L-$LmADm)#Fm2V+*-$LlVh0uKqq5Bp>_br6( zTL|5^5V~J8j1anSA#~qD=)Q%}eG8%c7DD$egzj4i-S2@}`=!da5V~(6bl*bgzJ<_z z3!(cKLia6%?pp}mw-CB-A#~qD=)Q%}eG8%c7DD$egzj4i-M0|BZy|L53Us%dm2V+* z-$LlVh0uKqq5Bp>_br6(TL|4>iUznt`4&R=Erjk{2;H|3x^E$L-$LmA!>Hu@m2V+* z-$LlVh0uKqq5Bp>_br6(TL|5^5V~(6bl*bg{)>2=o>abt(0vP``xZj?Erjk{2;H|3 zx^E$L|1gYhFDlDQ(0vP``=6n+zomQ& zq5Bp>_br6(TL|5^5W0UcD1Wbf3!(cKLia6%?pp}mw-CB-A#~qD=)Q%}eG8%c7DCTW zLg+C<=s86hSYLU0ZpyzjYaXB^EfBh%z7Oa8w@u`n|KO=uDd;0-V5y-$#5y8d$EIM} zp#Qcvc<9sMj_Q5(LQ>rWl)nBA!gKY3ppWV0Sb^l}OAwo{-=B;ZiY|gXuCD_BLfx?^ zl*W1j!i)7ZP#V1o`~$rLAtkzQI_LaPf~HJAgV=S+1wz*Xq5Bp>_Z@^D zBZQvwau$!5g^e&d@;f$yfVEn{S}kC$7O++eSgQrB)dJRP0c*8@wOYVh-+{F;g0(rb zBD}3MdLztknY6 zY5{AtfVEn{S}kC$7O++eSgQrB)dJRP0c*8@wOYVhEnuyFzLZ@{z*;R}troCW3s|cK ztknY6Y5{AtfVEn{S}kC$7O++eSgQrB)dJRP0c*8@wOYVhEnuw{uvQCLs|Bpp0@i8) zYqfy2TEJQ@V67IgRts3G1+3Kq)@lK3wScu+z*;R}troCW3s|cKtknY6Y5{AtfVEn{ zS}kC$7O++eSgQrB)dJRP0c*8@wOYVhEnuw{uvQCLs|Bpp0@i8)Yqfy2TEJQ@V67Ig zR-XreYqI_$V6;7THM+%cW^~&zpO{YHupM&-N z;Bbh(3?2Vay$y0dOdpTmxq1V590K+ag-*W!4#(*I zk=K0vC1{S-vyjVi`f^YnuTO(KC+Lp=b)TpwL6QYJj*ye|j>vJLJ`yyG^mFLFC+lAz z$5V6^^>C^#1pm`?Gk#CkOThCCJrCh$>fZQ0OTP#C7wgjzyTrF(t?$6v7{S_{vYdCo zEB})t;Fj%3Ios#l#0Tx2Lp=PRb|}Zveur}`-SJ?Kr3G_2mTo?VW9j0f+2PlMCPyED zkf@Fvi9~ul()zl2KE_giI6^$--*S{7#IaTc=IoX;99a~c4V6$)bcu(e#!rPidd>#W zdWA%Yqe~gA3W*R$FZ>9>(L$Pwie5|_zmN!V^b*qKdPNM1!&y884u=p&SKQ4!MzDxmY

DRx7 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%0A{;iqWtOp~rP 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

55BfZe8Jm!3QZ9Awx{C#oWv5Q6V_|+ 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%0DF?t|7iEYrpuSlzmo*p4)97C|2!ub!0uqTD}Z-L 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 JfU}Rq{{=2)1I_>d literal 0 HcmV?d00001 diff --git a/demo/server/epics_vts3.tpi b/apps/server/epics_vts3.tpi similarity index 100% rename from demo/server/epics_vts3.tpi rename to apps/server/epics_vts3.tpi diff --git a/demo/server/main.c b/apps/server/main.c similarity index 69% rename from demo/server/main.c rename to apps/server/main.c index cf06cb47..7e1b6198 100644 --- a/demo/server/main.c +++ b/apps/server/main.c @@ -27,41 +27,36 @@ #include #include #include +#include #include - -#include "config.h" -#include "server.h" -#include "address.h" -#include "bacdef.h" -#include "handlers.h" -#include "client.h" -#include "dlenv.h" -#include "bacdcode.h" -#include "npdu.h" -#include "apdu.h" -#include "iam.h" -#include "tsm.h" -#include "device.h" -#include "bacfile.h" -#include "datalink.h" -#include "dcc.h" -#include "filename.h" -#include "getevent.h" -#include "net.h" -#include "txbuf.h" -#include "lc.h" -#include "version.h" +#include "bacnet/config.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/apdu.h" +#include "bacnet/dcc.h" +#include "bacnet/iam.h" +#include "bacnet/npdu.h" +#include "bacnet/getevent.h" +#include "bacnet/version.h" +#include "bacnet/basic/services.h" +#include "bacnet/datalink/dlenv.h" +#include "bacnet/basic/sys/filename.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/datalink/datalink.h" +#include "bacnet/basic/binding/address.h" /* include the device object */ -#include "device.h" -#include "trendlog.h" +#include "bacnet/basic/object/device.h" +#include "bacnet/basic/object/lc.h" +#include "bacnet/basic/object/trendlog.h" #if defined(INTRINSIC_REPORTING) -#include "nc.h" +#include "bacnet/basic/object/nc.h" #endif /* defined(INTRINSIC_REPORTING) */ #if defined(BACFILE) -#include "bacfile.h" +#include "bacnet/basic/object/bacfile.h" #endif /* defined(BACFILE) */ #if defined(BAC_UCI) -#include "ucix.h" +#include "bacnet/basic/ucix/ucix.h" #endif /* defined(BAC_UCI) */ /** @file server/main.c Example server application using the BACnet Stack. */ @@ -71,8 +66,11 @@ /** @addtogroup ServerDemo */ /*@{*/ +/* current version of the BACnet stack */ +static const char *BACnet_Version = BACNET_VERSION_TEXT; + /** Buffer used for receiving */ -static uint8_t Rx_Buf[MAX_MPDU] = {0}; +static uint8_t Rx_Buf[MAX_MPDU] = { 0 }; /** Initialize the handlers we will utilize. * @see Device_Init, apdu_set_unconfirmed_handler, apdu_set_confirmed_handler @@ -103,45 +101,45 @@ static void Init_Service_Handlers(void) apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service); /* Set the handlers for any confirmed services that we support. */ /* We must implement read property - it's required! */ - apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY, - handler_read_property); - apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROP_MULTIPLE, - handler_read_property_multiple); - apdu_set_confirmed_handler(SERVICE_CONFIRMED_WRITE_PROPERTY, - handler_write_property); - apdu_set_confirmed_handler(SERVICE_CONFIRMED_WRITE_PROP_MULTIPLE, - handler_write_property_multiple); - apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_RANGE, - handler_read_range); + apdu_set_confirmed_handler( + SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property); + apdu_set_confirmed_handler( + SERVICE_CONFIRMED_READ_PROP_MULTIPLE, handler_read_property_multiple); + apdu_set_confirmed_handler( + SERVICE_CONFIRMED_WRITE_PROPERTY, handler_write_property); + apdu_set_confirmed_handler( + SERVICE_CONFIRMED_WRITE_PROP_MULTIPLE, handler_write_property_multiple); + apdu_set_confirmed_handler( + SERVICE_CONFIRMED_READ_RANGE, handler_read_range); #if defined(BACFILE) - apdu_set_confirmed_handler(SERVICE_CONFIRMED_ATOMIC_READ_FILE, - handler_atomic_read_file); - apdu_set_confirmed_handler(SERVICE_CONFIRMED_ATOMIC_WRITE_FILE, - handler_atomic_write_file); + apdu_set_confirmed_handler( + SERVICE_CONFIRMED_ATOMIC_READ_FILE, handler_atomic_read_file); + apdu_set_confirmed_handler( + SERVICE_CONFIRMED_ATOMIC_WRITE_FILE, handler_atomic_write_file); #endif - apdu_set_confirmed_handler(SERVICE_CONFIRMED_REINITIALIZE_DEVICE, - handler_reinitialize_device); - apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_UTC_TIME_SYNCHRONIZATION, - handler_timesync_utc); - apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_TIME_SYNCHRONIZATION, - handler_timesync); - apdu_set_confirmed_handler(SERVICE_CONFIRMED_SUBSCRIBE_COV, - handler_cov_subscribe); - apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_COV_NOTIFICATION, - handler_ucov_notification); + apdu_set_confirmed_handler( + SERVICE_CONFIRMED_REINITIALIZE_DEVICE, handler_reinitialize_device); + apdu_set_unconfirmed_handler( + SERVICE_UNCONFIRMED_UTC_TIME_SYNCHRONIZATION, handler_timesync_utc); + apdu_set_unconfirmed_handler( + SERVICE_UNCONFIRMED_TIME_SYNCHRONIZATION, handler_timesync); + apdu_set_confirmed_handler( + SERVICE_CONFIRMED_SUBSCRIBE_COV, handler_cov_subscribe); + apdu_set_unconfirmed_handler( + SERVICE_UNCONFIRMED_COV_NOTIFICATION, handler_ucov_notification); /* handle communication so we can shutup when asked */ apdu_set_confirmed_handler(SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL, - handler_device_communication_control); + handler_device_communication_control); /* handle the data coming back from private requests */ apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_PRIVATE_TRANSFER, - handler_unconfirmed_private_transfer); + handler_unconfirmed_private_transfer); #if defined(INTRINSIC_REPORTING) - apdu_set_confirmed_handler(SERVICE_CONFIRMED_ACKNOWLEDGE_ALARM, - handler_alarm_ack); - apdu_set_confirmed_handler(SERVICE_CONFIRMED_GET_EVENT_INFORMATION, - handler_get_event_information); - apdu_set_confirmed_handler(SERVICE_CONFIRMED_GET_ALARM_SUMMARY, - handler_get_alarm_summary); + apdu_set_confirmed_handler( + SERVICE_CONFIRMED_ACKNOWLEDGE_ALARM, handler_alarm_ack); + apdu_set_confirmed_handler( + SERVICE_CONFIRMED_GET_EVENT_INFORMATION, handler_get_event_information); + apdu_set_confirmed_handler( + SERVICE_CONFIRMED_GET_ALARM_SUMMARY, handler_get_alarm_summary); #endif /* defined(INTRINSIC_REPORTING) */ #if defined(BACNET_TIME_MASTER) handler_timesync_init(); @@ -156,21 +154,18 @@ static void print_usage(const char *filename) static void print_help(const char *filename) { - printf( - "Simulate a BACnet server device\n" - "device-instance:\n" - "BACnet Device Object Instance number that you are\n" - "trying simulate.\n" - "device-name:\n" - "The Device object-name is the text name for the device.\n" - "\nExample:\n"); - printf( - "To simulate Device 123, use the following command:\n" - "%s 123\n", + printf("Simulate a BACnet server device\n" + "device-instance:\n" + "BACnet Device Object Instance number that you are\n" + "trying simulate.\n" + "device-name:\n" + "The Device object-name is the text name for the device.\n" + "\nExample:\n"); + printf("To simulate Device 123, use the following command:\n" + "%s 123\n", filename); - printf( - "To simulate Device 123 named Fred, use following command:\n" - "%s 123 Fred\n", + printf("To simulate Device 123 named Fred, use following command:\n" + "%s 123 Fred\n", filename); } @@ -188,7 +183,7 @@ static void print_help(const char *filename) */ int main(int argc, char *argv[]) { - BACNET_ADDRESS src = {0}; /* address where message came from */ + BACNET_ADDRESS src = { 0 }; /* address where message came from */ uint16_t pdu_len = 0; unsigned timeout = 1; /* milliseconds */ time_t last_seconds = 0; @@ -196,7 +191,9 @@ int main(int argc, char *argv[]) uint32_t elapsed_seconds = 0; uint32_t elapsed_milliseconds = 0; uint32_t address_binding_tmr = 0; +#if defined(INTRINSIC_REPORTING) uint32_t recipient_scan_tmr = 0; +#endif #if defined(BACNET_TIME_MASTER) BACNET_DATE_TIME bdatetime; #endif @@ -216,12 +213,11 @@ int main(int argc, char *argv[]) } if (strcmp(argv[argi], "--version") == 0) { printf("%s %s\n", filename, BACNET_VERSION_TEXT); - printf( - "Copyright (C) 2014 by Steve Karg and others.\n" - "This is free software; see the source for copying " - "conditions.\n" - "There is NO warranty; not even for MERCHANTABILITY or\n" - "FITNESS FOR A PARTICULAR PURPOSE.\n"); + printf("Copyright (C) 2014 by Steve Karg and others.\n" + "This is free software; see the source for copying " + "conditions.\n" + "There is NO warranty; not even for MERCHANTABILITY or\n" + "FITNESS FOR A PARTICULAR PURPOSE.\n"); return 0; } } @@ -247,11 +243,10 @@ int main(int argc, char *argv[]) ucix_cleanup(ctx); #endif /* defined(BAC_UCI) */ - printf( - "BACnet Server Demo\n" - "BACnet Stack Version %s\n" - "BACnet Device ID: %u\n" - "Max APDU: %d\n", + printf("BACnet Server Demo\n" + "BACnet Stack Version %s\n" + "BACnet Device ID: %u\n" + "Max APDU: %d\n", BACnet_Version, Device_Object_Instance_Number(), MAX_APDU); /* load any static address bindings to show up in our device bindings list */ diff --git a/apps/timesync/Makefile b/apps/timesync/Makefile new file mode 100644 index 00000000..492bbb93 --- /dev/null +++ b/apps/timesync/Makefile @@ -0,0 +1,54 @@ +#Makefile to build BACnet Application for the Linux Port + +# tools - only if you need them. +# Most platforms have this already defined +# CC = gcc + +# Executable file name +TARGET = bacts +# BACnet objects that are used with this app +BACNET_OBJECT_DIR = $(BACNET_SRC_DIR)/bacnet/basic/object +SRC = main.c \ + $(BACNET_OBJECT_DIR)/client/device-client.c \ + $(BACNET_OBJECT_DIR)/netport.c +BACNET_BASIC_SRC += \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_apdu.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_iam.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_noserv.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_ts.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_rp.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_whois.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/s_ts.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/s_iam.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/s_whois.c + +# TARGET_EXT is defined in apps/Makefile as .exe or nothing +TARGET_BIN = ${TARGET}$(TARGET_EXT) + +SRCS = $(SRC) $(BACNET_SRC) $(BACNET_BASIC_SRC) $(BACNET_PORT_SRC) + +OBJS += ${SRCS:.c=.o} + +.PHONY: all +all: Makefile ${TARGET_BIN} + +${TARGET_BIN}: ${OBJS} + ${CC} ${PFLAGS} ${OBJS} ${LFLAGS} -o $@ + size $@ + cp $@ ../../bin + +.c.o: + ${CC} -c ${CFLAGS} $*.c -o $@ + +.PHONY: depend +depend: + rm -f .depend + ${CC} -MM ${CFLAGS} *.c >> .depend + +.PHONY: clean +clean: + rm -f core ${TARGET_BIN} ${OBJS} $(TARGET).map + +.PHONY: include +include: .depend + diff --git a/demo/timesync/main.c b/apps/timesync/main.c similarity index 74% rename from demo/timesync/main.c rename to apps/timesync/main.c index 704fdced..53544441 100644 --- a/demo/timesync/main.c +++ b/apps/timesync/main.c @@ -31,31 +31,31 @@ #include #include /* for time */ #include -#include "address.h" -#include "bactext.h" -#include "config.h" -#include "bacdef.h" -#include "npdu.h" -#include "apdu.h" -#include "device.h" -#include "net.h" -#include "datalink.h" -#include "timesync.h" -#include "version.h" +#include "bacnet/basic/binding/address.h" +#include "bacnet/bactext.h" +#include "bacnet/config.h" +#include "bacnet/bacdef.h" +#include "bacnet/npdu.h" +#include "bacnet/apdu.h" +#include "bacnet/basic/object/device.h" +#include "bacport.h" +#include "bacnet/datalink/datalink.h" +#include "bacnet/timesync.h" +#include "bacnet/version.h" /* some demo stuff needed */ -#include "filename.h" -#include "handlers.h" -#include "client.h" -#include "txbuf.h" -#include "dlenv.h" +#include "bacnet/basic/sys/filename.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/datalink/dlenv.h" /* buffer used for receive */ -static uint8_t Rx_Buf[MAX_MPDU] = {0}; +static uint8_t Rx_Buf[MAX_MPDU] = { 0 }; /* error flag */ static bool Error_Detected = false; -void MyAbortHandler(BACNET_ADDRESS *src, uint8_t invoke_id, - uint8_t abort_reason, bool server) +static void MyAbortHandler( + BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t abort_reason, bool server) { /* FIXME: verify src and invoke id */ (void)src; @@ -65,8 +65,8 @@ void MyAbortHandler(BACNET_ADDRESS *src, uint8_t invoke_id, Error_Detected = true; } -void MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, - uint8_t reject_reason) +static void MyRejectHandler( + BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason) { /* FIXME: verify src and invoke id */ (void)src; @@ -85,13 +85,13 @@ static void Init_Service_Handlers(void) It is required to send the proper reject message... */ apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service); /* we must implement read property - it's required! */ - apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY, - handler_read_property); + apdu_set_confirmed_handler( + SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property); /* handle the reply (request) coming in */ - apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_UTC_TIME_SYNCHRONIZATION, - handler_timesync_utc); - apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_TIME_SYNCHRONIZATION, - handler_timesync); + apdu_set_unconfirmed_handler( + SERVICE_UNCONFIRMED_UTC_TIME_SYNCHRONIZATION, handler_timesync_utc); + apdu_set_unconfirmed_handler( + SERVICE_UNCONFIRMED_TIME_SYNCHRONIZATION, handler_timesync); /* handle any errors coming back */ apdu_set_abort_handler(MyAbortHandler); apdu_set_reject_handler(MyRejectHandler); @@ -105,38 +105,35 @@ static void print_usage(char *filename) static void print_help(char *filename) { - printf( - "Send BACnet TimeSynchronization request.\n" - "\n" - "--mac A\n" - "BACnet mac address." - "Valid ranges are from 0 to 255\n" - "or an IP string with optional port number like 10.1.2.3:47808\n" - "or an Ethernet MAC in hex like 00:21:70:7e:32:bb\n" - "\n" - "--dnet N\n" - "BACnet network number N for directed requests.\n" - "Valid range is from 0 to 65535 where 0 is the local connection\n" - "and 65535 is network broadcast.\n" - "\n" - "--dadr A\n" - "BACnet mac address on the destination BACnet network number.\n" - "Valid ranges are from 0 to 255\n" - "or an IP string with optional port number like 10.1.2.3:47808\n" - "or an Ethernet MAC in hex like 00:21:70:7e:32:bb\n" - "\n"); - printf( - "Examples:\n" - "Send a TimeSynchronization request to DNET 123:\n" - "%s --dnet 123\n", + printf("Send BACnet TimeSynchronization request.\n" + "\n" + "--mac A\n" + "BACnet mac address." + "Valid ranges are from 0 to 255\n" + "or an IP string with optional port number like 10.1.2.3:47808\n" + "or an Ethernet MAC in hex like 00:21:70:7e:32:bb\n" + "\n" + "--dnet N\n" + "BACnet network number N for directed requests.\n" + "Valid range is from 0 to 65535 where 0 is the local connection\n" + "and 65535 is network broadcast.\n" + "\n" + "--dadr A\n" + "BACnet mac address on the destination BACnet network number.\n" + "Valid ranges are from 0 to 255\n" + "or an IP string with optional port number like 10.1.2.3:47808\n" + "or an Ethernet MAC in hex like 00:21:70:7e:32:bb\n" + "\n"); + printf("Examples:\n" + "Send a TimeSynchronization request to DNET 123:\n" + "%s --dnet 123\n", filename); printf( "Send a TimeSynchronization request to MAC 10.0.0.1 DNET 123 DADR 5:\n" "%s --mac 10.0.0.1 --dnet 123 --dadr 5\n", filename); - printf( - "Send a TimeSynchronization request to MAC 10.1.2.3:47808:\n" - "%s --mac 10.1.2.3:47808\n", + printf("Send a TimeSynchronization request to MAC 10.1.2.3:47808:\n" + "%s --mac 10.1.2.3:47808\n", filename); #if 0 /* FIXME: it would be nice to be able to send arbitrary time values */ @@ -153,7 +150,7 @@ static void print_help(char *filename) int main(int argc, char *argv[]) { - BACNET_ADDRESS src = {0}; /* address where message came from */ + BACNET_ADDRESS src = { 0 }; /* address where message came from */ uint16_t pdu_len = 0; unsigned timeout = 100; /* milliseconds */ time_t elapsed_seconds = 0; @@ -165,9 +162,9 @@ int main(int argc, char *argv[]) BACNET_DATE bdate; BACNET_TIME btime; long dnet = -1; - BACNET_MAC_ADDRESS mac = {0}; - BACNET_MAC_ADDRESS adr = {0}; - BACNET_ADDRESS dest = {0}; + BACNET_MAC_ADDRESS mac = { 0 }; + BACNET_MAC_ADDRESS adr = { 0 }; + BACNET_ADDRESS dest = { 0 }; bool global_broadcast = true; int argi = 0; char *filename = NULL; @@ -182,12 +179,11 @@ int main(int argc, char *argv[]) } if (strcmp(argv[argi], "--version") == 0) { printf("%s %s\n", filename, BACNET_VERSION_TEXT); - printf( - "Copyright (C) 2014 by Steve Karg and others.\n" - "This is free software; see the source for copying " - "conditions.\n" - "There is NO warranty; not even for MERCHANTABILITY or\n" - "FITNESS FOR A PARTICULAR PURPOSE.\n"); + printf("Copyright (C) 2014 by Steve Karg and others.\n" + "This is free software; see the source for copying " + "conditions.\n" + "There is NO warranty; not even for MERCHANTABILITY or\n" + "FITNESS FOR A PARTICULAR PURPOSE.\n"); return 0; } if (strcmp(argv[argi], "--mac") == 0) { @@ -279,8 +275,9 @@ int main(int argc, char *argv[]) break; /* increment timer - exit if timed out */ elapsed_seconds += (current_seconds - last_seconds); - if (elapsed_seconds > timeout_seconds) + if (elapsed_seconds > timeout_seconds) { break; + } /* keep track of time for next check */ last_seconds = current_seconds; } diff --git a/apps/ucov/Makefile b/apps/ucov/Makefile new file mode 100644 index 00000000..c0958850 --- /dev/null +++ b/apps/ucov/Makefile @@ -0,0 +1,53 @@ +#Makefile to build BACnet Application for the Linux Port + +# tools - only if you need them. +# Most platforms have this already defined +# CC = gcc + +# Executable file name +TARGET = bacucov +# BACnet objects that are used with this app +BACNET_OBJECT_DIR = $(BACNET_SRC_DIR)/bacnet/basic/object +SRC = main.c \ + $(BACNET_OBJECT_DIR)/client/device-client.c \ + $(BACNET_OBJECT_DIR)/netport.c +BACNET_BASIC_SRC += \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_apdu.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_iam.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_noserv.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_rp.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_whois.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/s_cov.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/s_iam.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/s_whois.c + +# TARGET_EXT is defined in apps/Makefile as .exe or nothing +TARGET_BIN = ${TARGET}$(TARGET_EXT) + +SRCS = $(SRC) $(BACNET_SRC) $(BACNET_BASIC_SRC) $(BACNET_PORT_SRC) + +OBJS += ${SRCS:.c=.o} + +.PHONY: all +all: Makefile ${TARGET_BIN} + +${TARGET_BIN}: ${OBJS} + ${CC} ${PFLAGS} ${OBJS} ${LFLAGS} -o $@ + size $@ + cp $@ ../../bin + +.c.o: + ${CC} -c ${CFLAGS} $*.c -o $@ + +.PHONY: depend +depend: + rm -f .depend + ${CC} -MM ${CFLAGS} *.c >> .depend + +.PHONY: clean +clean: + rm -f core ${TARGET_BIN} ${OBJS} $(TARGET).map + +.PHONY: include +include: .depend + diff --git a/demo/ucov/main.c b/apps/ucov/main.c similarity index 87% rename from demo/ucov/main.c rename to apps/ucov/main.c index a8bbb591..4bb1b216 100644 --- a/demo/ucov/main.c +++ b/apps/ucov/main.c @@ -30,25 +30,25 @@ #include #include /* for time */ #include -#include "bactext.h" -#include "iam.h" -#include "cov.h" -#include "tsm.h" -#include "address.h" -#include "config.h" -#include "bacdef.h" -#include "npdu.h" -#include "apdu.h" -#include "device.h" -#include "net.h" -#include "datalink.h" -#include "whois.h" +#include "bacnet/bactext.h" +#include "bacnet/iam.h" +#include "bacnet/cov.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/basic/binding/address.h" +#include "bacnet/config.h" +#include "bacnet/bacdef.h" +#include "bacnet/npdu.h" +#include "bacnet/apdu.h" +#include "bacnet/basic/object/device.h" +#include "bacport.h" +#include "bacnet/datalink/datalink.h" +#include "bacnet/whois.h" /* some demo stuff needed */ -#include "filename.h" -#include "handlers.h" -#include "client.h" -#include "txbuf.h" -#include "dlenv.h" +#include "bacnet/basic/sys/filename.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/datalink/dlenv.h" static void Init_Service_Handlers(void) { @@ -62,8 +62,8 @@ static void Init_Service_Handlers(void) It is required to send the proper reject message... */ apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service); /* we must implement read property - it's required! */ - apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY, - handler_read_property); + apdu_set_confirmed_handler( + SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property); } int main(int argc, char *argv[]) @@ -187,34 +187,33 @@ int main(int argc, char *argv[]) if (cov_data.initiatingDeviceIdentifier >= BACNET_MAX_INSTANCE) { fprintf(stderr, "device-instance=%u - it must be less than %u\r\n", - cov_data.initiatingDeviceIdentifier, BACNET_MAX_INSTANCE); + cov_data.initiatingDeviceIdentifier, BACNET_MAX_INSTANCE); return 1; } if (cov_data.monitoredObjectIdentifier.type >= MAX_BACNET_OBJECT_TYPE) { fprintf(stderr, "object-type=%u - it must be less than %u\r\n", - cov_data.monitoredObjectIdentifier.type, - MAX_BACNET_OBJECT_TYPE); + cov_data.monitoredObjectIdentifier.type, MAX_BACNET_OBJECT_TYPE); return 1; } if (cov_data.monitoredObjectIdentifier.instance > BACNET_MAX_INSTANCE) { fprintf(stderr, "object-instance=%u - it must be less than %u\r\n", - cov_data.monitoredObjectIdentifier.instance, - BACNET_MAX_INSTANCE + 1); + cov_data.monitoredObjectIdentifier.instance, + BACNET_MAX_INSTANCE + 1); return 1; } if (cov_data.listOfValues->propertyIdentifier > MAX_BACNET_PROPERTY_ID) { fprintf(stderr, "property-identifier=%u - it must be less than %u\r\n", - cov_data.listOfValues->propertyIdentifier, - MAX_BACNET_PROPERTY_ID + 1); + cov_data.listOfValues->propertyIdentifier, + MAX_BACNET_PROPERTY_ID + 1); return 1; } if (tag >= MAX_BACNET_APPLICATION_TAG) { fprintf(stderr, "tag=%u - it must be less than %u\r\n", tag, - MAX_BACNET_APPLICATION_TAG); + MAX_BACNET_APPLICATION_TAG); return 1; } - status = bacapp_parse_application_data(tag, value_string, - &cov_data.listOfValues->value); + status = bacapp_parse_application_data( + tag, value_string, &cov_data.listOfValues->value); if (!status) { /* FIXME: show the expected entry format for the tag */ fprintf(stderr, "unable to parse the tag value\r\n"); @@ -226,7 +225,7 @@ int main(int argc, char *argv[]) dlenv_init(); atexit(datalink_cleanup); Send_UCOV_Notify(&Handler_Transmit_Buffer[0], - sizeof(Handler_Transmit_Buffer), &cov_data); + sizeof(Handler_Transmit_Buffer), &cov_data); return 0; } diff --git a/apps/uevent/Makefile b/apps/uevent/Makefile new file mode 100644 index 00000000..73b7e9a1 --- /dev/null +++ b/apps/uevent/Makefile @@ -0,0 +1,54 @@ +#Makefile to build BACnet Application with GNU Make + +# tools - only if you need them. +# Most platforms have this already defined +# CC = gcc + +# Executable file name +TARGET = bacuevent +# BACnet objects that are used with this app +BACNET_OBJECT_DIR = $(BACNET_SRC_DIR)/bacnet/basic/object +SRC = main.c \ + $(BACNET_OBJECT_DIR)/client/device-client.c \ + $(BACNET_OBJECT_DIR)/netport.c +BACNET_BASIC_SRC += \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_apdu.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_iam.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_noserv.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_rp.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_rr_a.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_whois.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/s_iam.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/s_uevent.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/s_whois.c + +# TARGET_EXT is defined in apps/Makefile as .exe or nothing +TARGET_BIN = ${TARGET}$(TARGET_EXT) + +SRCS = $(SRC) $(BACNET_SRC) $(BACNET_BASIC_SRC) $(BACNET_PORT_SRC) + +OBJS += ${SRCS:.c=.o} + +.PHONY: all +all: Makefile ${TARGET_BIN} + +${TARGET_BIN}: ${OBJS} + ${CC} ${PFLAGS} ${OBJS} ${LFLAGS} -o $@ + size $@ + cp $@ ../../bin + +.c.o: + ${CC} -c ${CFLAGS} $*.c -o $@ + +.PHONY: depend +depend: + rm -f .depend + ${CC} -MM ${CFLAGS} *.c >> .depend + +.PHONY: clean +clean: + rm -f core ${TARGET_BIN} ${OBJS} $(TARGET).map + +.PHONY: include +include: .depend + diff --git a/demo/uevent/main.c b/apps/uevent/main.c similarity index 85% rename from demo/uevent/main.c rename to apps/uevent/main.c index a5c36590..62976442 100644 --- a/demo/uevent/main.c +++ b/apps/uevent/main.c @@ -30,27 +30,27 @@ #include #include /* for time */ #include -#include "bactext.h" -#include "iam.h" -#include "cov.h" -#include "tsm.h" -#include "address.h" -#include "config.h" -#include "bacdef.h" -#include "npdu.h" -#include "apdu.h" -#include "device.h" -#include "net.h" -#include "datalink.h" -#include "event.h" -#include "whois.h" +#include "bacnet/bactext.h" +#include "bacnet/iam.h" +#include "bacnet/cov.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/basic/binding/address.h" +#include "bacnet/config.h" +#include "bacnet/bacdef.h" +#include "bacnet/npdu.h" +#include "bacnet/apdu.h" +#include "bacnet/basic/object/device.h" +#include "bacport.h" +#include "bacnet/datalink/datalink.h" +#include "bacnet/event.h" +#include "bacnet/whois.h" /* some demo stuff needed */ -#include "version.h" -#include "filename.h" -#include "handlers.h" -#include "client.h" -#include "txbuf.h" -#include "dlenv.h" +#include "bacnet/version.h" +#include "bacnet/basic/sys/filename.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/datalink/dlenv.h" static void Init_Service_Handlers(void) { @@ -64,20 +64,19 @@ static void Init_Service_Handlers(void) It is required to send the proper reject message... */ apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service); /* we must implement read property - it's required! */ - apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY, - handler_read_property); + apdu_set_confirmed_handler( + SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property); } static void print_usage(char *filename) { - printf( - "Usage: %s pid object-type object-instance \n" - " event-object-type event-object-instance \n" - " sequence-number notification-class priority event-type\n" - " [reference-bit-string status-flags message notify-type\n" - " ack-required from-state to-state]\n" - " [new-state status-flags message notify-type\n" - " ack-required from-state to-state]\n", + printf("Usage: %s pid object-type object-instance \n" + " event-object-type event-object-instance \n" + " sequence-number notification-class priority event-type\n" + " [reference-bit-string status-flags message notify-type\n" + " ack-required from-state to-state]\n" + " [new-state status-flags message notify-type\n" + " ack-required from-state to-state]\n", filename); printf(" [--dnet][--dadr][--mac]\n"); printf(" [--version][--help]\n"); @@ -86,37 +85,36 @@ static void print_usage(char *filename) static void print_help(char *filename) { printf("Send BACnet UnconfirmedEventNotification message for a device.\n"); - printf( - "--mac A\n" - "Optional BACnet mac address." - "Valid ranges are from 00 to FF (hex) for MS/TP or ARCNET,\n" - "or an IP string with optional port number like 10.1.2.3:47808\n" - "or an Ethernet MAC in hex like 00:21:70:7e:32:bb\n" - "\n" - "--dnet N\n" - "Optional BACnet network number N for directed requests.\n" - "Valid range is from 0 to 65535 where 0 is the local connection\n" - "and 65535 is network broadcast.\n" - "\n" - "--dadr A\n" - "Optional BACnet mac address on the destination BACnet network " - "number.\n" - "Valid ranges are from 00 to FF (hex) for MS/TP or ARCNET,\n" - "or an IP string with optional port number like 10.1.2.3:47808\n" - "or an Ethernet MAC in hex like 00:21:70:7e:32:bb\n" - "\n"); + printf("--mac A\n" + "Optional BACnet mac address." + "Valid ranges are from 00 to FF (hex) for MS/TP or ARCNET,\n" + "or an IP string with optional port number like 10.1.2.3:47808\n" + "or an Ethernet MAC in hex like 00:21:70:7e:32:bb\n" + "\n" + "--dnet N\n" + "Optional BACnet network number N for directed requests.\n" + "Valid range is from 0 to 65535 where 0 is the local connection\n" + "and 65535 is network broadcast.\n" + "\n" + "--dadr A\n" + "Optional BACnet mac address on the destination BACnet network " + "number.\n" + "Valid ranges are from 00 to FF (hex) for MS/TP or ARCNET,\n" + "or an IP string with optional port number like 10.1.2.3:47808\n" + "or an Ethernet MAC in hex like 00:21:70:7e:32:bb\n" + "\n"); } int main(int argc, char *argv[]) { - BACNET_EVENT_NOTIFICATION_DATA event_data = {0}; + BACNET_EVENT_NOTIFICATION_DATA event_data = { 0 }; BACNET_BIT_STRING *pBitString; BACNET_CHARACTER_STRING bcstring; BACNET_PROPERTY_STATE_TYPE tag = BOOLEAN_VALUE; long dnet = -1; - BACNET_MAC_ADDRESS mac = {0}; - BACNET_MAC_ADDRESS adr = {0}; - BACNET_ADDRESS dest = {0}; + BACNET_MAC_ADDRESS mac = { 0 }; + BACNET_MAC_ADDRESS adr = { 0 }; + BACNET_ADDRESS dest = { 0 }; bool specific_address = false; int argi = 0; unsigned int target_args = 0; @@ -131,12 +129,11 @@ int main(int argc, char *argv[]) } if (strcmp(argv[argi], "--version") == 0) { printf("%s %s\n", filename, BACNET_VERSION_TEXT); - printf( - "Copyright (C) 2016 by Steve Karg and others.\n" - "This is free software; see the source for copying " - "conditions.\n" - "There is NO warranty; not even for MERCHANTABILITY or\n" - "FITNESS FOR A PARTICULAR PURPOSE.\n"); + printf("Copyright (C) 2016 by Steve Karg and others.\n" + "This is free software; see the source for copying " + "conditions.\n" + "There is NO warranty; not even for MERCHANTABILITY or\n" + "FITNESS FOR A PARTICULAR PURPOSE.\n"); return 0; } if (strcmp(argv[argi], "--mac") == 0) { @@ -319,7 +316,7 @@ int main(int argc, char *argv[]) } else if (event_data.eventType == EVENT_FLOATING_LIMIT) { } else if (event_data.eventType == EVENT_OUT_OF_RANGE) { } else if (event_data.eventType == - EVENT_CHANGE_OF_LIFE_SAFETY) { + EVENT_CHANGE_OF_LIFE_SAFETY) { } else if (event_data.eventType == EVENT_EXTENDED) { } else if (event_data.eventType == EVENT_BUFFER_READY) { } else if (event_data.eventType == EVENT_UNSIGNED_RANGE) { diff --git a/apps/uptransfer/Makefile b/apps/uptransfer/Makefile new file mode 100644 index 00000000..bf740d2a --- /dev/null +++ b/apps/uptransfer/Makefile @@ -0,0 +1,51 @@ +#Makefile to build BACnet Application using GCC compiler + +# Executable file name +TARGET = bacupt +# BACnet objects that are used with this app +BACNET_OBJECT_DIR = $(BACNET_SRC_DIR)/bacnet/basic/object +SRC = main.c \ + $(BACNET_OBJECT_DIR)/client/device-client.c \ + $(BACNET_OBJECT_DIR)/netport.c +BACNET_BASIC_SRC += \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_apdu.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_iam.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_noserv.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_rp.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_upt.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_whois.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/s_iam.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/s_rp.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/s_upt.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/s_whois.c + +# TARGET_EXT is defined in apps/Makefile as .exe or nothing +TARGET_BIN = ${TARGET}$(TARGET_EXT) + +SRCS = $(SRC) $(BACNET_SRC) $(BACNET_BASIC_SRC) $(BACNET_PORT_SRC) + +OBJS += ${SRCS:.c=.o} + +.PHONY: all +all: Makefile ${TARGET_BIN} + +${TARGET_BIN}: ${OBJS} + ${CC} ${PFLAGS} ${OBJS} ${LFLAGS} -o $@ + size $@ + cp $@ ../../bin + +.c.o: + ${CC} -c ${CFLAGS} $*.c -o $@ + +.PHONY: depend +depend: + rm -f .depend + ${CC} -MM ${CFLAGS} *.c >> .depend + +.PHONY: clean +clean: + rm -f core ${TARGET_BIN} ${OBJS} $(TARGET).map + +.PHONY: include +include: .depend + diff --git a/demo/uptransfer/main.c b/apps/uptransfer/main.c similarity index 84% rename from demo/uptransfer/main.c rename to apps/uptransfer/main.c index b7f5ff20..bfde5e4d 100644 --- a/demo/uptransfer/main.c +++ b/apps/uptransfer/main.c @@ -28,34 +28,34 @@ #include #include #include -#include /* for time */ +#include /* for time */ #include /* for toupper */ #define PRINT_ENABLED 1 -#include "bacdef.h" -#include "config.h" -#include "bactext.h" -#include "bacerror.h" -#include "iam.h" -#include "arf.h" -#include "tsm.h" -#include "address.h" -#include "npdu.h" -#include "apdu.h" -#include "device.h" -#include "net.h" -#include "datalink.h" -#include "whois.h" +#include "bacnet/bacdef.h" +#include "bacnet/config.h" +#include "bacnet/bactext.h" +#include "bacnet/bacerror.h" +#include "bacnet/iam.h" +#include "bacnet/arf.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/basic/binding/address.h" +#include "bacnet/npdu.h" +#include "bacnet/apdu.h" +#include "bacnet/basic/object/device.h" +#include "bacport.h" +#include "bacnet/datalink/datalink.h" +#include "bacnet/whois.h" /* some demo stuff needed */ -#include "filename.h" -#include "handlers.h" -#include "client.h" -#include "txbuf.h" -#include "dlenv.h" +#include "bacnet/basic/sys/filename.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/datalink/dlenv.h" /* buffer used for receive */ -static uint8_t Rx_Buf[MAX_MPDU] = {0}; +static uint8_t Rx_Buf[MAX_MPDU] = { 0 }; /* converted command line arguments */ static bool Target_Broadcast; @@ -76,38 +76,39 @@ static uint8_t Request_Invoke_ID = 0; static BACNET_ADDRESS Target_Address; static bool Error_Detected = false; -static void MyErrorHandler(BACNET_ADDRESS *src, uint8_t invoke_id, - BACNET_ERROR_CLASS error_class, - BACNET_ERROR_CODE error_code) +static void MyErrorHandler(BACNET_ADDRESS *src, + uint8_t invoke_id, + BACNET_ERROR_CLASS error_class, + BACNET_ERROR_CODE error_code) { if (address_match(&Target_Address, src) && (invoke_id == Request_Invoke_ID)) { printf("BACnet Error: %s: %s\r\n", - bactext_error_class_name((int)error_class), - bactext_error_code_name((int)error_code)); + bactext_error_class_name((int)error_class), + bactext_error_code_name((int)error_code)); Error_Detected = true; } } -void MyAbortHandler(BACNET_ADDRESS *src, uint8_t invoke_id, - uint8_t abort_reason, bool server) +static void MyAbortHandler( + BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t abort_reason, bool server) { (void)server; if (address_match(&Target_Address, src) && (invoke_id == Request_Invoke_ID)) { printf("BACnet Abort: %s\r\n", - bactext_abort_reason_name((int)abort_reason)); + bactext_abort_reason_name((int)abort_reason)); Error_Detected = true; } } -void MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, - uint8_t reject_reason) +static void MyRejectHandler( + BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason) { if (address_match(&Target_Address, src) && (invoke_id == Request_Invoke_ID)) { printf("BACnet Reject: %s\r\n", - bactext_reject_reason_name((int)reject_reason)); + bactext_reject_reason_name((int)reject_reason)); Error_Detected = true; } } @@ -124,11 +125,11 @@ static void Init_Service_Handlers(void) It is required to send the proper reject message... */ apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service); /* we must implement read property - it's required! */ - apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY, - handler_read_property); + apdu_set_confirmed_handler( + SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property); /* handle the data coming back from requests */ apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_PRIVATE_TRANSFER, - handler_unconfirmed_private_transfer); + handler_unconfirmed_private_transfer); /* handle any errors coming back */ apdu_set_error_handler(SERVICE_CONFIRMED_READ_PROPERTY, MyErrorHandler); apdu_set_abort_handler(MyAbortHandler); @@ -137,7 +138,7 @@ static void Init_Service_Handlers(void) int main(int argc, char *argv[]) { - BACNET_ADDRESS src = {0}; /* address where message came from */ + BACNET_ADDRESS src = { 0 }; /* address where message came from */ uint16_t pdu_len = 0; unsigned timeout = 10; /* milliseconds */ unsigned max_apdu = 0; @@ -153,15 +154,14 @@ int main(int argc, char *argv[]) int args_remaining = 0, tag_value_arg = 0, i = 0; BACNET_APPLICATION_TAG property_tag; uint8_t context_tag = 0; - BACNET_PRIVATE_TRANSFER_DATA private_data = {0}; + BACNET_PRIVATE_TRANSFER_DATA private_data = { 0 }; int len = 0; bool sent_message = false; if (argc < 6) { filename = filename_remove_path(argv[0]); - printf( - "Usage: %s vendor-id" - " service-number tag value [tag value...]\r\n", + printf("Usage: %s vendor-id" + " service-number tag value [tag value...]\r\n", filename); if ((argc > 1) && (strcmp(argv[1], "--help") == 0)) { printf( @@ -228,7 +228,7 @@ int main(int argc, char *argv[]) if ((!Target_Broadcast) && (Target_Device_Object_Instance > BACNET_MAX_INSTANCE)) { fprintf(stderr, "device-instance=%u - it must be less than %u\r\n", - Target_Device_Object_Instance, BACNET_MAX_INSTANCE); + Target_Device_Object_Instance, BACNET_MAX_INSTANCE); return 1; } args_remaining = (argc - (6 - 2)); @@ -256,7 +256,7 @@ int main(int argc, char *argv[]) i, property_tag, i, value_string); */ if (property_tag >= MAX_BACNET_APPLICATION_TAG) { fprintf(stderr, "Error: tag=%u - it must be less than %u\r\n", - property_tag, MAX_BACNET_APPLICATION_TAG); + property_tag, MAX_BACNET_APPLICATION_TAG); return 1; } status = bacapp_parse_application_data( @@ -277,7 +277,7 @@ int main(int argc, char *argv[]) } if (args_remaining > 0) { fprintf(stderr, "Error: Exceeded %d tag-value pairs.\r\n", - MAX_PROPERTY_VALUES); + MAX_PROPERTY_VALUES); return 1; } /* setup my info */ @@ -296,11 +296,11 @@ int main(int argc, char *argv[]) } else { timeout_seconds = (apdu_timeout() / 1000) * apdu_retries(); /* try to bind with the device */ - found = address_bind_request(Target_Device_Object_Instance, &max_apdu, - &Target_Address); + found = address_bind_request( + Target_Device_Object_Instance, &max_apdu, &Target_Address); if (!found) { - Send_WhoIs(Target_Device_Object_Instance, - Target_Device_Object_Instance); + Send_WhoIs( + Target_Device_Object_Instance, Target_Device_Object_Instance); } } /* loop forever */ @@ -318,13 +318,13 @@ int main(int argc, char *argv[]) break; /* wait until the device is bound, or timeout and quit */ if (!found) { - found = address_bind_request(Target_Device_Object_Instance, - &max_apdu, &Target_Address); + found = address_bind_request( + Target_Device_Object_Instance, &max_apdu, &Target_Address); } if (!sent_message) { if (found) { - len = bacapp_encode_data(&Service_Parameters[0], - &Target_Object_Property_Value[0]); + len = bacapp_encode_data( + &Service_Parameters[0], &Target_Object_Property_Value[0]); private_data.serviceParameters = &Service_Parameters[0]; private_data.serviceParametersLen = len; private_data.vendorID = Target_Vendor_Identifier; @@ -333,7 +333,7 @@ int main(int argc, char *argv[]) printf("Sent PrivateTransfer."); if (timeout_seconds) { printf(" Waiting %u seconds.\r\n", - (unsigned)(timeout_seconds - elapsed_seconds)); + (unsigned)(timeout_seconds - elapsed_seconds)); } else { printf("\r\n"); } diff --git a/apps/whohas/Makefile b/apps/whohas/Makefile new file mode 100644 index 00000000..2c9d54a1 --- /dev/null +++ b/apps/whohas/Makefile @@ -0,0 +1,54 @@ +#Makefile to build BACnet Application for the Linux Port + +# tools - only if you need them. +# Most platforms have this already defined +# CC = gcc + +# Executable file name +TARGET = bacwh +# BACnet objects that are used with this app +BACNET_OBJECT_DIR = $(BACNET_SRC_DIR)/bacnet/basic/object +SRC = main.c \ + $(BACNET_OBJECT_DIR)/client/device-client.c \ + $(BACNET_OBJECT_DIR)/netport.c +BACNET_BASIC_SRC += \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_apdu.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_iam.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_noserv.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_rp.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_whois.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_ihave.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/s_iam.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/s_whohas.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/s_whois.c + +# TARGET_EXT is defined in apps/Makefile as .exe or nothing +TARGET_BIN = ${TARGET}$(TARGET_EXT) + +SRCS = $(SRC) $(BACNET_SRC) $(BACNET_BASIC_SRC) $(BACNET_PORT_SRC) + +OBJS += ${SRCS:.c=.o} + +.PHONY: all +all: Makefile ${TARGET_BIN} + +${TARGET_BIN}: ${OBJS} + ${CC} ${PFLAGS} ${OBJS} ${LFLAGS} -o $@ + size $@ + cp $@ ../../bin + +.c.o: + ${CC} -c ${CFLAGS} $*.c -o $@ + +.PHONY: depend +depend: + rm -f .depend + ${CC} -MM ${CFLAGS} *.c >> .depend + +.PHONY: clean +clean: + rm -f core ${TARGET_BIN} ${OBJS} $(TARGET).map + +.PHONY: include +include: .depend + diff --git a/demo/whohas/main.c b/apps/whohas/main.c similarity index 77% rename from demo/whohas/main.c rename to apps/whohas/main.c index 8f9ca51c..274ce706 100644 --- a/demo/whohas/main.c +++ b/apps/whohas/main.c @@ -30,28 +30,28 @@ #include #include /* for time */ #include -#include "bactext.h" -#include "iam.h" -#include "arf.h" -#include "tsm.h" -#include "address.h" -#include "config.h" -#include "bacdef.h" -#include "npdu.h" -#include "apdu.h" -#include "device.h" -#include "net.h" -#include "datalink.h" -#include "whohas.h" +#include "bacnet/bactext.h" +#include "bacnet/iam.h" +#include "bacnet/arf.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/basic/binding/address.h" +#include "bacnet/config.h" +#include "bacnet/bacdef.h" +#include "bacnet/npdu.h" +#include "bacnet/apdu.h" +#include "bacnet/basic/object/device.h" +#include "bacport.h" +#include "bacnet/datalink/datalink.h" +#include "bacnet/whohas.h" /* some demo stuff needed */ -#include "filename.h" -#include "handlers.h" -#include "client.h" -#include "txbuf.h" -#include "dlenv.h" +#include "bacnet/basic/sys/filename.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/datalink/dlenv.h" /* buffer used for receive */ -static uint8_t Rx_Buf[MAX_MPDU] = {0}; +static uint8_t Rx_Buf[MAX_MPDU] = { 0 }; /* global variables used in this file */ static BACNET_OBJECT_TYPE Target_Object_Type = MAX_BACNET_OBJECT_TYPE; @@ -62,8 +62,8 @@ static int32_t Target_Object_Instance_Max = -1; static bool Error_Detected = false; -void MyAbortHandler(BACNET_ADDRESS *src, uint8_t invoke_id, - uint8_t abort_reason, bool server) +static void MyAbortHandler( + BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t abort_reason, bool server) { /* FIXME: verify src and invoke id */ (void)src; @@ -73,8 +73,8 @@ void MyAbortHandler(BACNET_ADDRESS *src, uint8_t invoke_id, Error_Detected = true; } -void MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, - uint8_t reject_reason) +static void MyRejectHandler( + BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason) { /* FIXME: verify src and invoke id */ (void)src; @@ -93,8 +93,8 @@ static void Init_Service_Handlers(void) It is required to send the proper reject message... */ apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service); /* we must implement read property - it's required! */ - apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY, - handler_read_property); + apdu_set_confirmed_handler( + SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property); /* handle the reply (request) coming back */ apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_I_HAVE, handler_i_have); /* handle any errors coming back */ @@ -104,32 +104,30 @@ static void Init_Service_Handlers(void) static void print_usage(char *filename) { - printf( - "Usage: %s [device-instance-min device-instance-min] " - " [--help]\r\n", + printf("Usage: %s [device-instance-min device-instance-min] " + " [--help]\r\n", filename); } static void print_help(char *filename) { print_usage(filename); - printf( - "Send BACnet WhoHas request to devices, \r\n" - "and wait %u milliseconds (BACNET_APDU_TIMEOUT) for responses.\r\n" - "The device-instance-min or max can be 0 to %d.\r\n" - "\r\n" - "Use either:\r\n" - "The object-type can be 0 to %d.\r\n" - "The object-instance can be 0 to %d.\r\n" - "or:\r\n" - "The object-name can be any string of characters.\r\n", + printf("Send BACnet WhoHas request to devices, \r\n" + "and wait %u milliseconds (BACNET_APDU_TIMEOUT) for responses.\r\n" + "The device-instance-min or max can be 0 to %d.\r\n" + "\r\n" + "Use either:\r\n" + "The object-type can be 0 to %d.\r\n" + "The object-instance can be 0 to %d.\r\n" + "or:\r\n" + "The object-name can be any string of characters.\r\n", BACNET_MAX_INSTANCE, (unsigned)apdu_timeout(), BACNET_MAX_OBJECT, BACNET_MAX_INSTANCE); } int main(int argc, char *argv[]) { - BACNET_ADDRESS src = {0}; /* address where message came from */ + BACNET_ADDRESS src = { 0 }; /* address where message came from */ uint16_t pdu_len = 0; unsigned timeout = 100; /* milliseconds */ time_t elapsed_seconds = 0; @@ -180,8 +178,8 @@ int main(int argc, char *argv[]) if (by_name) { if (Target_Object_Name) { if (Target_Object_Name[0] == 0) { - fprintf(stderr, - "object-name must be at least 1 character.\r\n"); + fprintf( + stderr, "object-name must be at least 1 character.\r\n"); return 1; } } else { @@ -191,23 +189,23 @@ int main(int argc, char *argv[]) } else { if (Target_Object_Instance > BACNET_MAX_INSTANCE) { fprintf(stderr, "object-instance=%u - it must be less than %u\r\n", - Target_Object_Instance, BACNET_MAX_INSTANCE + 1); + Target_Object_Instance, BACNET_MAX_INSTANCE + 1); return 1; } if (Target_Object_Type > BACNET_MAX_OBJECT) { fprintf(stderr, "object-type=%u - it must be less than %u\r\n", - Target_Object_Type, BACNET_MAX_OBJECT + 1); + Target_Object_Type, BACNET_MAX_OBJECT + 1); return 1; } } if (Target_Object_Instance_Min > BACNET_MAX_INSTANCE) { fprintf(stderr, "object-instance-min=%u - it must be less than %u\r\n", - Target_Object_Instance_Min, BACNET_MAX_INSTANCE + 1); + Target_Object_Instance_Min, BACNET_MAX_INSTANCE + 1); return 1; } if (Target_Object_Instance_Max > BACNET_MAX_INSTANCE) { fprintf(stderr, "object-instance-max=%u - it must be less than %u\r\n", - Target_Object_Instance_Max, BACNET_MAX_INSTANCE + 1); + Target_Object_Instance_Max, BACNET_MAX_INSTANCE + 1); return 1; } /* setup my info */ @@ -221,11 +219,11 @@ int main(int argc, char *argv[]) /* send the request */ if (by_name) { Send_WhoHas_Name(Target_Object_Instance_Min, Target_Object_Instance_Max, - Target_Object_Name); + Target_Object_Name); } else { Send_WhoHas_Object(Target_Object_Instance_Min, - Target_Object_Instance_Max, Target_Object_Type, - Target_Object_Instance); + Target_Object_Instance_Max, Target_Object_Type, + Target_Object_Instance); } /* loop forever */ for (;;) { @@ -241,8 +239,9 @@ int main(int argc, char *argv[]) break; /* increment timer - exit if timed out */ elapsed_seconds += (current_seconds - last_seconds); - if (elapsed_seconds > timeout_seconds) + if (elapsed_seconds > timeout_seconds) { break; + } /* keep track of time for next check */ last_seconds = current_seconds; } diff --git a/apps/whois/Makefile b/apps/whois/Makefile new file mode 100644 index 00000000..1b896539 --- /dev/null +++ b/apps/whois/Makefile @@ -0,0 +1,51 @@ +#Makefile to build BACnet Application for the Linux Port + +# tools - only if you need them. +# Most platforms have this already defined +# CC = gcc + +TARGET = bacwi +# BACnet objects that are used with this app +BACNET_OBJECT_DIR = $(BACNET_SRC_DIR)/bacnet/basic/object +SRC = main.c \ + $(BACNET_OBJECT_DIR)/client/device-client.c \ + $(BACNET_OBJECT_DIR)/netport.c +BACNET_BASIC_SRC += \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_apdu.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_iam.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_noserv.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_rp.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_whois.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/s_iam.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/s_whois.c + +# TARGET_EXT is defined in apps/Makefile as .exe or nothing +TARGET_BIN = ${TARGET}$(TARGET_EXT) + +SRCS = $(SRC) $(BACNET_SRC) $(BACNET_BASIC_SRC) $(BACNET_PORT_SRC) + +OBJS += ${SRCS:.c=.o} + +.PHONY: all +all: Makefile ${TARGET_BIN} + +${TARGET_BIN}: ${OBJS} + ${CC} ${PFLAGS} ${OBJS} ${LFLAGS} -o $@ + size $@ + cp $@ ../../bin + +.c.o: + ${CC} -c ${CFLAGS} $*.c -o $@ + +.PHONY: depend +depend: + rm -f .depend + ${CC} -MM ${CFLAGS} *.c >> .depend + +.PHONY: clean +clean: + rm -f core ${TARGET_BIN} ${OBJS} $(TARGET).map + +.PHONY: include +include: .depend + diff --git a/apps/whois/bacwi-linux.cbp b/apps/whois/bacwi-linux.cbp new file mode 100644 index 00000000..87e2c46f --- /dev/null +++ b/apps/whois/bacwi-linux.cbp @@ -0,0 +1,468 @@ + + + + + + diff --git a/apps/whois/bacwi.layout b/apps/whois/bacwi.layout new file mode 100644 index 00000000..90c8aefc --- /dev/null +++ b/apps/whois/bacwi.layout @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/demo/whois/main.c b/apps/whois/main.c similarity index 70% rename from demo/whois/main.c rename to apps/whois/main.c index 08b22f91..b795615a 100644 --- a/demo/whois/main.c +++ b/apps/whois/main.c @@ -31,30 +31,30 @@ #include #include /* for time */ #include -#include "bactext.h" -#include "iam.h" -#include "address.h" -#include "config.h" -#include "bacdef.h" -#include "npdu.h" -#include "apdu.h" -#include "device.h" -#include "datalink.h" -#include "bactext.h" -#include "version.h" +#include "bacnet/bactext.h" +#include "bacnet/iam.h" +#include "bacnet/basic/binding/address.h" +#include "bacnet/config.h" +#include "bacnet/bacdef.h" +#include "bacnet/npdu.h" +#include "bacnet/apdu.h" +#include "bacnet/basic/object/device.h" +#include "bacnet/datalink/datalink.h" +#include "bacnet/bactext.h" +#include "bacnet/version.h" /* some demo stuff needed */ -#include "filename.h" -#include "handlers.h" -#include "client.h" -#include "txbuf.h" +#include "bacnet/basic/sys/filename.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/tsm/tsm.h" #if defined(BACDL_MSTP) #include "rs485.h" #endif -#include "dlenv.h" -#include "net.h" +#include "bacnet/datalink/dlenv.h" +#include "bacport.h" /* buffer used for receive */ -static uint8_t Rx_Buf[MAX_MPDU] = {0}; +static uint8_t Rx_Buf[MAX_MPDU] = { 0 }; /* global variables used in this file */ static int32_t Target_Object_Instance_Min = -1; @@ -74,9 +74,9 @@ struct address_entry { static struct address_table { struct address_entry *first; struct address_entry *last; -} Address_Table = {0}; +} Address_Table = { 0 }; -struct address_entry *alloc_address_entry(void) +static struct address_entry *alloc_address_entry(void) { struct address_entry *rval; rval = (struct address_entry *)calloc(1, sizeof(struct address_entry)); @@ -89,21 +89,8 @@ struct address_entry *alloc_address_entry(void) return rval; } -bool bacnet_address_matches(BACNET_ADDRESS *a1, BACNET_ADDRESS *a2) -{ - int i = 0; - if (a1->net != a2->net) - return false; - if (a1->len != a2->len) - return false; - for (; i < a1->len; i++) - if (a1->adr[i] != a2->adr[i]) - return false; - return true; -} - -void address_table_add(uint32_t device_id, unsigned max_apdu, - BACNET_ADDRESS *src) +static void address_table_add( + uint32_t device_id, unsigned max_apdu, BACNET_ADDRESS *src) { struct address_entry *pMatch; uint8_t flags = 0; @@ -111,8 +98,9 @@ void address_table_add(uint32_t device_id, unsigned max_apdu, pMatch = Address_Table.first; while (pMatch) { if (pMatch->device_id == device_id) { - if (bacnet_address_matches(&pMatch->address, src)) + if (bacnet_address_same(&pMatch->address, src)) { return; + } flags |= BAC_ADDRESS_MULT; pMatch->Flags |= BAC_ADDRESS_MULT; } @@ -129,8 +117,8 @@ void address_table_add(uint32_t device_id, unsigned max_apdu, return; } -void my_i_am_handler(uint8_t *service_request, uint16_t service_len, - BACNET_ADDRESS *src) +static void my_i_am_handler( + uint8_t *service_request, uint16_t service_len, BACNET_ADDRESS *src) { int len = 0; uint32_t device_id = 0; @@ -140,8 +128,8 @@ void my_i_am_handler(uint8_t *service_request, uint16_t service_len, unsigned i = 0; (void)service_len; - len = iam_decode_service_request(service_request, &device_id, &max_apdu, - &segmentation, &vendor_id); + len = iam_decode_service_request( + service_request, &device_id, &max_apdu, &segmentation, &vendor_id); #if PRINT_ENABLED fprintf(stderr, "Received I-Am Request"); #endif @@ -150,9 +138,9 @@ void my_i_am_handler(uint8_t *service_request, uint16_t service_len, fprintf(stderr, " from %lu, MAC = ", (unsigned long)device_id); if ((src->mac_len == 6) && (src->len == 0)) { fprintf(stderr, "%u.%u.%u.%u %02X%02X\n", (unsigned)src->mac[0], - (unsigned)src->mac[1], (unsigned)src->mac[2], - (unsigned)src->mac[3], (unsigned)src->mac[4], - (unsigned)src->mac[5]); + (unsigned)src->mac[1], (unsigned)src->mac[2], + (unsigned)src->mac[3], (unsigned)src->mac[4], + (unsigned)src->mac[5]); } else { for (i = 0; i < src->mac_len; i++) { fprintf(stderr, "%02X", (unsigned)src->mac[i]); @@ -173,26 +161,26 @@ void my_i_am_handler(uint8_t *service_request, uint16_t service_len, return; } -void MyAbortHandler(BACNET_ADDRESS *src, uint8_t invoke_id, - uint8_t abort_reason, bool server) +static void MyAbortHandler( + BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t abort_reason, bool server) { /* FIXME: verify src and invoke id */ (void)src; (void)invoke_id; (void)server; - fprintf(stderr, "BACnet Abort: %s\n", - bactext_abort_reason_name(abort_reason)); + fprintf( + stderr, "BACnet Abort: %s\n", bactext_abort_reason_name(abort_reason)); Error_Detected = true; } -void MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, - uint8_t reject_reason) +static void MyRejectHandler( + BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason) { /* FIXME: verify src and invoke id */ (void)src; (void)invoke_id; fprintf(stderr, "BACnet Reject: %s\n", - bactext_reject_reason_name(reject_reason)); + bactext_reject_reason_name(reject_reason)); Error_Detected = true; } @@ -205,8 +193,8 @@ static void init_service_handlers(void) It is required to send the proper reject message... */ apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service); /* we must implement read property - it's required! */ - apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY, - handler_read_property); + apdu_set_confirmed_handler( + SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property); /* handle the reply (request) coming back */ apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_I_AM, my_i_am_handler); /* handle any errors coming back */ @@ -214,7 +202,7 @@ static void init_service_handlers(void) apdu_set_reject_handler(MyRejectHandler); } -void print_macaddr(uint8_t *addr, int len) +static void print_macaddr(uint8_t *addr, int len) { int j = 0; @@ -243,7 +231,7 @@ static void print_address_cache(void) so these must be compatible. */ printf(";%-7s %-20s %-5s %-20s %-4s\n", "Device", "MAC (hex)", "SNET", - "SADR (hex)", "APDU"); + "SADR (hex)", "APDU"); printf(";-------- -------------------- ----- -------------------- ----\n"); addr = Address_Table.first; @@ -285,68 +273,59 @@ static void print_usage(char *filename) static void print_help(char *filename) { - printf( - "Send BACnet WhoIs service request to a device or multiple\n" - "devices, and wait for responses. Displays any devices found\n" - "and their network information.\n" - "\n" - "device-instance:\n" - "BACnet Device Object Instance number that you are trying\n" - "to send a Who-Is service request. The value should be in\n" - "the range of 0 to 4194303. A range of values can also be\n" - "specified by using a minimum value and a maximum value.\n" - "\n"); - printf( - "--mac A\n" - "BACnet mac address." - "Valid ranges are from 00 to FF (hex) for MS/TP or ARCNET,\n" - "or an IP string with optional port number like 10.1.2.3:47808\n" - "or an Ethernet MAC in hex like 00:21:70:7e:32:bb\n" - "\n" - "--dnet N\n" - "BACnet network number N for directed requests.\n" - "Valid range is from 0 to 65535 where 0 is the local connection\n" - "and 65535 is network broadcast.\n" - "\n" - "--dadr A\n" - "BACnet mac address on the destination BACnet network number.\n" - "Valid ranges are from 00 to FF (hex) for MS/TP or ARCNET,\n" - "or an IP string with optional port number like 10.1.2.3:47808\n" - "or an Ethernet MAC in hex like 00:21:70:7e:32:bb\n" - "\n"); - printf( - "Send a WhoIs request to DNET 123:\n" - "%s --dnet 123\n", + printf("Send BACnet WhoIs service request to a device or multiple\n" + "devices, and wait for responses. Displays any devices found\n" + "and their network information.\n" + "\n" + "device-instance:\n" + "BACnet Device Object Instance number that you are trying\n" + "to send a Who-Is service request. The value should be in\n" + "the range of 0 to 4194303. A range of values can also be\n" + "specified by using a minimum value and a maximum value.\n" + "\n"); + printf("--mac A\n" + "BACnet mac address." + "Valid ranges are from 00 to FF (hex) for MS/TP or ARCNET,\n" + "or an IP string with optional port number like 10.1.2.3:47808\n" + "or an Ethernet MAC in hex like 00:21:70:7e:32:bb\n" + "\n" + "--dnet N\n" + "BACnet network number N for directed requests.\n" + "Valid range is from 0 to 65535 where 0 is the local connection\n" + "and 65535 is network broadcast.\n" + "\n" + "--dadr A\n" + "BACnet mac address on the destination BACnet network number.\n" + "Valid ranges are from 00 to FF (hex) for MS/TP or ARCNET,\n" + "or an IP string with optional port number like 10.1.2.3:47808\n" + "or an Ethernet MAC in hex like 00:21:70:7e:32:bb\n" + "\n"); + printf("Send a WhoIs request to DNET 123:\n" + "%s --dnet 123\n", filename); - printf( - "Send a WhoIs request to MAC 10.0.0.1 DNET 123 DADR 05h:\n" - "%s --mac 10.0.0.1 --dnet 123 --dadr 05\n", + printf("Send a WhoIs request to MAC 10.0.0.1 DNET 123 DADR 05h:\n" + "%s --mac 10.0.0.1 --dnet 123 --dadr 05\n", filename); - printf( - "Send a WhoIs request to MAC 10.1.2.3:47808:\n" - "%s --mac 10.1.2.3:47808\n", + printf("Send a WhoIs request to MAC 10.1.2.3:47808:\n" + "%s --mac 10.1.2.3:47808\n", filename); - printf( - "Send a WhoIs request to Device 123:\n" - "%s 123\n", + printf("Send a WhoIs request to Device 123:\n" + "%s 123\n", filename); - printf( - "Send a WhoIs request to Devices from 1000 to 9000:\n" - "%s 1000 9000\n", + printf("Send a WhoIs request to Devices from 1000 to 9000:\n" + "%s 1000 9000\n", filename); - printf( - "Send a WhoIs request to Devices from 1000 to 9000 on DNET 123:\n" - "%s 1000 9000 --dnet 123\n", + printf("Send a WhoIs request to Devices from 1000 to 9000 on DNET 123:\n" + "%s 1000 9000 --dnet 123\n", filename); - printf( - "Send a WhoIs request to all devices:\n" - "%s\n", + printf("Send a WhoIs request to all devices:\n" + "%s\n", filename); } int main(int argc, char *argv[]) { - BACNET_ADDRESS src = {0}; /* address where message came from */ + BACNET_ADDRESS src = { 0 }; /* address where message came from */ uint16_t pdu_len = 0; unsigned timeout = 100; /* milliseconds */ time_t total_seconds = 0; @@ -355,9 +334,9 @@ int main(int argc, char *argv[]) time_t current_seconds = 0; time_t timeout_seconds = 0; long dnet = -1; - BACNET_MAC_ADDRESS mac = {0}; - BACNET_MAC_ADDRESS adr = {0}; - BACNET_ADDRESS dest = {0}; + BACNET_MAC_ADDRESS mac = { 0 }; + BACNET_MAC_ADDRESS adr = { 0 }; + BACNET_ADDRESS dest = { 0 }; bool global_broadcast = true; int argi = 0; unsigned int target_args = 0; @@ -373,12 +352,11 @@ int main(int argc, char *argv[]) } if (strcmp(argv[argi], "--version") == 0) { printf("%s %s\n", filename, BACNET_VERSION_TEXT); - printf( - "Copyright (C) 2014 by Steve Karg and others.\n" - "This is free software; see the source for copying " - "conditions.\n" - "There is NO warranty; not even for MERCHANTABILITY or\n" - "FITNESS FOR A PARTICULAR PURPOSE.\n"); + printf("Copyright (C) 2014 by Steve Karg and others.\n" + "This is free software; see the source for copying " + "conditions.\n" + "There is NO warranty; not even for MERCHANTABILITY or\n" + "FITNESS FOR A PARTICULAR PURPOSE.\n"); return 0; } if (strcmp(argv[argi], "--mac") == 0) { @@ -448,12 +426,12 @@ int main(int argc, char *argv[]) } if (Target_Object_Instance_Min > BACNET_MAX_INSTANCE) { fprintf(stderr, "device-instance-min=%u - it must be less than %u\n", - Target_Object_Instance_Min, BACNET_MAX_INSTANCE + 1); + Target_Object_Instance_Min, BACNET_MAX_INSTANCE + 1); return 1; } if (Target_Object_Instance_Max > BACNET_MAX_INSTANCE) { fprintf(stderr, "device-instance-max=%u - it must be less than %u\n", - Target_Object_Instance_Max, BACNET_MAX_INSTANCE + 1); + Target_Object_Instance_Max, BACNET_MAX_INSTANCE + 1); return 1; } /* setup my info */ @@ -466,8 +444,8 @@ int main(int argc, char *argv[]) last_seconds = time(NULL); timeout_seconds = apdu_timeout() / 1000; /* send the request */ - Send_WhoIs_To_Network(&dest, Target_Object_Instance_Min, - Target_Object_Instance_Max); + Send_WhoIs_To_Network( + &dest, Target_Object_Instance_Min, Target_Object_Instance_Max); /* loop forever */ for (;;) { /* increment timer - exit if timed out */ @@ -488,8 +466,9 @@ int main(int argc, char *argv[]) #endif } total_seconds += elapsed_seconds; - if (total_seconds > timeout_seconds) + if (total_seconds > timeout_seconds) { break; + } /* keep track of time for next check */ last_seconds = current_seconds; } diff --git a/apps/whoisrouter/Makefile b/apps/whoisrouter/Makefile new file mode 100644 index 00000000..519ca754 --- /dev/null +++ b/apps/whoisrouter/Makefile @@ -0,0 +1,47 @@ +#Makefile to build BACnet Application for the Linux Port + +TARGET = bacwir +# BACnet objects that are used with this app +BACNET_OBJECT_DIR = $(BACNET_SRC_DIR)/bacnet/basic/object +SRC = main.c \ + $(BACNET_OBJECT_DIR)/client/device-client.c \ + $(BACNET_OBJECT_DIR)/netport.c +BACNET_BASIC_SRC += \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_apdu.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_iam.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_noserv.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_rp.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_whois.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/s_iam.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/s_whois.c + +# TARGET_EXT is defined in apps/Makefile as .exe or nothing +TARGET_BIN = ${TARGET}$(TARGET_EXT) + +SRCS = $(SRC) $(BACNET_SRC) $(BACNET_BASIC_SRC) $(BACNET_PORT_SRC) + +OBJS += ${SRCS:.c=.o} + +.PHONY: all +all: Makefile ${TARGET_BIN} + +${TARGET_BIN}: ${OBJS} + ${CC} ${PFLAGS} ${OBJS} ${LFLAGS} -o $@ + size $@ + cp $@ ../../bin + +.c.o: + ${CC} -c ${CFLAGS} $*.c -o $@ + +.PHONY: depend +depend: + rm -f .depend + ${CC} -MM ${CFLAGS} *.c >> .depend + +.PHONY: clean +clean: + rm -f core ${TARGET_BIN} ${OBJS} $(TARGET).map + +.PHONY: include +include: .depend + diff --git a/demo/whoisrouter/main.c b/apps/whoisrouter/main.c similarity index 77% rename from demo/whoisrouter/main.c rename to apps/whoisrouter/main.c index d9c34e96..db048968 100644 --- a/demo/whoisrouter/main.c +++ b/apps/whoisrouter/main.c @@ -30,31 +30,24 @@ #include #include /* for time */ #include -#include "bactext.h" -#include "iam.h" -#include "address.h" -#include "config.h" -#include "bacdef.h" -#include "npdu.h" -#include "apdu.h" -#include "device.h" -#include "datalink.h" +#include "bacnet/bactext.h" +#include "bacnet/iam.h" +#include "bacnet/config.h" +#include "bacnet/bacdef.h" +#include "bacnet/npdu.h" +#include "bacnet/apdu.h" /* some demo stuff needed */ -#ifndef DEBUG_ENABLED -#define DEBUG_ENABLED 0 -#endif -#include "debug.h" -#include "filename.h" -#include "handlers.h" -#include "client.h" -#include "txbuf.h" -#if defined(BACDL_MSTP) -#include "rs485.h" -#endif -#include "dlenv.h" +#include "bacnet/basic/sys/debug.h" +#include "bacnet/basic/binding/address.h" +#include "bacnet/basic/object/device.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/sys/filename.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/datalink/datalink.h" +#include "bacnet/datalink/dlenv.h" /* buffer used for receive */ -static uint8_t Rx_Buf[MAX_MPDU] = {0}; +static uint8_t Rx_Buf[MAX_MPDU] = { 0 }; /* global variables used in this file */ static int32_t Target_Router_Network = 0; @@ -62,8 +55,8 @@ static BACNET_ADDRESS Target_Router_Address; static bool Error_Detected = false; -static void MyAbortHandler(BACNET_ADDRESS *src, uint8_t invoke_id, - uint8_t abort_reason, bool server) +static void MyAbortHandler( + BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t abort_reason, bool server) { /* FIXME: verify src and invoke id */ (void)src; @@ -73,8 +66,8 @@ static void MyAbortHandler(BACNET_ADDRESS *src, uint8_t invoke_id, Error_Detected = true; } -static void MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, - uint8_t reject_reason) +static void MyRejectHandler( + BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason) { /* FIXME: verify src and invoke id */ (void)src; @@ -83,9 +76,10 @@ static void MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, Error_Detected = true; } -static void My_Router_Handler(BACNET_ADDRESS *src, BACNET_NPDU_DATA *npdu_data, - uint8_t *npdu, /* PDU data */ - uint16_t npdu_len) +static void My_Router_Handler(BACNET_ADDRESS *src, + BACNET_NPDU_DATA *npdu_data, + uint8_t *npdu, /* PDU data */ + uint16_t npdu_len) { uint16_t npdu_offset = 0; uint16_t dnet = 0; @@ -130,32 +124,32 @@ static void My_Router_Handler(BACNET_ADDRESS *src, BACNET_NPDU_DATA *npdu_data, } } -void My_NPDU_Handler(BACNET_ADDRESS *src, /* source address */ - uint8_t *pdu, /* PDU data */ - uint16_t pdu_len) +static void My_NPDU_Handler(BACNET_ADDRESS *src, /* source address */ + uint8_t *pdu, /* PDU data */ + uint16_t pdu_len) { /* length PDU */ int apdu_offset = 0; - BACNET_ADDRESS dest = {0}; - BACNET_NPDU_DATA npdu_data = {0}; + BACNET_ADDRESS dest = { 0 }; + BACNET_NPDU_DATA npdu_data = { 0 }; apdu_offset = npdu_decode(&pdu[0], &dest, src, &npdu_data); if (npdu_data.network_layer_message) { My_Router_Handler(src, &npdu_data, &pdu[apdu_offset], - (uint16_t)(pdu_len - apdu_offset)); + (uint16_t)(pdu_len - apdu_offset)); } else if ((apdu_offset > 0) && (apdu_offset <= pdu_len)) { if ((npdu_data.protocol_version == BACNET_PROTOCOL_VERSION) && ((dest.net == 0) || (dest.net == BACNET_BROADCAST_NETWORK))) { /* only handle the version that we know how to handle */ /* and we are not a router, so ignore messages with routing information cause they are not for us */ - apdu_handler(src, &pdu[apdu_offset], - (uint16_t)(pdu_len - apdu_offset)); + apdu_handler( + src, &pdu[apdu_offset], (uint16_t)(pdu_len - apdu_offset)); } else { if (dest.net) { debug_printf("NPDU: DNET=%d. Discarded!\n", dest.net); } else { debug_printf("NPDU: BACnet Protocol Version=%d. Discarded!\n", - npdu_data.protocol_version); + npdu_data.protocol_version); } } } @@ -173,8 +167,8 @@ static void Init_Service_Handlers(void) It is required to send the proper reject message... */ apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service); /* we must implement read property - it's required! */ - apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY, - handler_read_property); + apdu_set_confirmed_handler( + SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property); /* handle the reply (request) coming back */ apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_I_AM, handler_i_am_add); /* handle any errors coming back */ @@ -191,7 +185,7 @@ static void address_parse(BACNET_ADDRESS *dst, int argc, char *argv[]) if (argc > 0) { count = sscanf(argv[0], "%x:%x:%x:%x:%x:%x", &mac[0], &mac[1], &mac[2], - &mac[3], &mac[4], &mac[5]); + &mac[3], &mac[4], &mac[5]); dst->mac_len = count; for (index = 0; index < MAX_MAC_LEN; index++) { if (index < count) { @@ -208,7 +202,7 @@ static void address_parse(BACNET_ADDRESS *dst, int argc, char *argv[]) if (dnet) { if (argc > 2) { count = sscanf(argv[2], "%x:%x:%x:%x:%x:%x", &mac[0], &mac[1], - &mac[2], &mac[3], &mac[4], &mac[5]); + &mac[2], &mac[3], &mac[4], &mac[5]); dst->len = count; for (index = 0; index < MAX_MAC_LEN; index++) { if (index < count) { @@ -230,7 +224,7 @@ static void address_parse(BACNET_ADDRESS *dst, int argc, char *argv[]) int main(int argc, char *argv[]) { - BACNET_ADDRESS src = {0}; /* address where message came from */ + BACNET_ADDRESS src = { 0 }; /* address where message came from */ uint16_t pdu_len = 0; unsigned timeout = 100; /* milliseconds */ time_t total_seconds = 0; @@ -244,21 +238,20 @@ int main(int argc, char *argv[]) return 0; } if ((argc > 1) && (strcmp(argv[1], "--help") == 0)) { - printf( - "Send BACnet Who-Is-Router-To-Network message to a network.\r\n" - "\r\n" - "DNET:\r\n" - "BACnet destination network number 0-65535\r\n" - "To omit the BACnet destination network number, use -1.\r\n" - "MAC:\r\n" - "Optional MAC address of router for unicast message\r\n" - "Format: xx[:xx:xx:xx:xx:xx] [dnet xx[:xx:xx:xx:xx:xx]]\r\n" - "Use hexidecimal MAC addresses.\r\n" - "\r\n" - "To send a Who-Is-Router-To-Network request to DNET 86:\r\n" - "%s 86\r\n" - "To send a Who-Is-Router-To-Network request to all devices:\r\n" - "%s -1\r\n", + printf("Send BACnet Who-Is-Router-To-Network message to a network.\r\n" + "\r\n" + "DNET:\r\n" + "BACnet destination network number 0-65535\r\n" + "To omit the BACnet destination network number, use -1.\r\n" + "MAC:\r\n" + "Optional MAC address of router for unicast message\r\n" + "Format: xx[:xx:xx:xx:xx:xx] [dnet xx[:xx:xx:xx:xx:xx]]\r\n" + "Use hexidecimal MAC addresses.\r\n" + "\r\n" + "To send a Who-Is-Router-To-Network request to DNET 86:\r\n" + "%s 86\r\n" + "To send a Who-Is-Router-To-Network request to all devices:\r\n" + "%s -1\r\n", filename_remove_path(argv[0]), filename_remove_path(argv[0])); return 0; } @@ -267,7 +260,7 @@ int main(int argc, char *argv[]) Target_Router_Network = strtol(argv[1], NULL, 0); if (Target_Router_Network > 65535) { fprintf(stderr, "DNET=%u - it must be 0 to 65535\r\n", - Target_Router_Network); + Target_Router_Network); return 1; } } @@ -286,8 +279,8 @@ int main(int argc, char *argv[]) last_seconds = time(NULL); timeout_seconds = apdu_timeout() / 1000; /* send the request */ - Send_Who_Is_Router_To_Network(&Target_Router_Address, - Target_Router_Network); + Send_Who_Is_Router_To_Network( + &Target_Router_Address, Target_Router_Network); /* loop forever */ for (;;) { /* increment timer - exit if timed out */ @@ -308,8 +301,9 @@ int main(int argc, char *argv[]) #endif } total_seconds += elapsed_seconds; - if (total_seconds > timeout_seconds) + if (total_seconds > timeout_seconds) { break; + } /* keep track of time for next check */ last_seconds = current_seconds; } diff --git a/apps/writefile/Makefile b/apps/writefile/Makefile new file mode 100644 index 00000000..b296ab8f --- /dev/null +++ b/apps/writefile/Makefile @@ -0,0 +1,54 @@ +#Makefile to build BACnet Application for the Linux Port + +# tools - only if you need them. +# Most platforms have this already defined +# CC = gcc + +# Executable file name +TARGET = bacawf + +# BACnet objects that are used with this app +BACNET_OBJECT_DIR = $(BACNET_SRC_DIR)/bacnet/basic/object +SRC = main.c \ + $(BACNET_OBJECT_DIR)/client/device-client.c \ + $(BACNET_OBJECT_DIR)/netport.c +BACNET_BASIC_SRC += \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_apdu.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_iam.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_noserv.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_rp.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_whois.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/s_iam.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/s_awfs.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/s_whois.c + +# TARGET_EXT is defined in apps/Makefile as .exe or nothing +TARGET_BIN = ${TARGET}$(TARGET_EXT) + +SRCS = $(SRC) $(BACNET_SRC) $(BACNET_BASIC_SRC) $(BACNET_PORT_SRC) + +OBJS += ${SRCS:.c=.o} + +.PHONY: all +all: Makefile ${TARGET_BIN} + +${TARGET_BIN}: ${OBJS} + ${CC} ${PFLAGS} ${OBJS} ${LFLAGS} -o $@ + size $@ + cp $@ ../../bin + +.c.o: + ${CC} -c ${CFLAGS} $*.c -o $@ + +.PHONY: depend +depend: + rm -f .depend + ${CC} -MM ${CFLAGS} *.c >> .depend + +.PHONY: clean +clean: + rm -f core ${TARGET_BIN} ${OBJS} $(TARGET).map + +.PHONY: include +include: .depend + diff --git a/demo/writefile/main.c b/apps/writefile/main.c similarity index 80% rename from demo/writefile/main.c rename to apps/writefile/main.c index e2ff85fe..bff55ab7 100644 --- a/demo/writefile/main.c +++ b/apps/writefile/main.c @@ -30,28 +30,28 @@ #include #include /* for time */ #include -#include "bactext.h" -#include "iam.h" -#include "awf.h" -#include "tsm.h" -#include "address.h" -#include "config.h" -#include "bacdef.h" -#include "npdu.h" -#include "apdu.h" -#include "device.h" -#include "net.h" -#include "datalink.h" -#include "whois.h" +#include "bacnet/bactext.h" +#include "bacnet/iam.h" +#include "bacnet/awf.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/basic/binding/address.h" +#include "bacnet/config.h" +#include "bacnet/bacdef.h" +#include "bacnet/npdu.h" +#include "bacnet/apdu.h" +#include "bacnet/basic/object/device.h" +#include "bacport.h" +#include "bacnet/datalink/datalink.h" +#include "bacnet/whois.h" /* some demo stuff needed */ -#include "filename.h" -#include "handlers.h" -#include "client.h" -#include "txbuf.h" -#include "dlenv.h" +#include "bacnet/basic/sys/filename.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/datalink/dlenv.h" /* buffer used for receive */ -static uint8_t Rx_Buf[MAX_MPDU] = {0}; +static uint8_t Rx_Buf[MAX_MPDU] = { 0 }; /* global variables used in this file */ static uint32_t Target_File_Object_Instance = 4194303; @@ -65,9 +65,9 @@ static bool Error_Detected = false; static uint8_t Current_Invoke_ID = 0; static void Atomic_Write_File_Error_Handler(BACNET_ADDRESS *src, - uint8_t invoke_id, - BACNET_ERROR_CLASS error_class, - BACNET_ERROR_CODE error_code) + uint8_t invoke_id, + BACNET_ERROR_CLASS error_class, + BACNET_ERROR_CODE error_code) { if (address_match(&Target_Address, src) && (invoke_id == Current_Invoke_ID)) { @@ -78,31 +78,31 @@ static void Atomic_Write_File_Error_Handler(BACNET_ADDRESS *src, } } -void MyAbortHandler(BACNET_ADDRESS *src, uint8_t invoke_id, - uint8_t abort_reason, bool server) +static void MyAbortHandler( + BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t abort_reason, bool server) { (void)server; if (address_match(&Target_Address, src) && (invoke_id == Current_Invoke_ID)) { printf("BACnet Abort: %s\r\n", - bactext_abort_reason_name((int)abort_reason)); + bactext_abort_reason_name((int)abort_reason)); Error_Detected = true; } } -void MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, - uint8_t reject_reason) +static void MyRejectHandler( + BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason) { if (address_match(&Target_Address, src) && (invoke_id == Current_Invoke_ID)) { printf("BACnet Reject: %s\r\n", - bactext_reject_reason_name((int)reject_reason)); + bactext_reject_reason_name((int)reject_reason)); Error_Detected = true; } } -static void LocalIAmHandler(uint8_t *service_request, uint16_t service_len, - BACNET_ADDRESS *src) +static void LocalIAmHandler( + uint8_t *service_request, uint16_t service_len, BACNET_ADDRESS *src) { int len = 0; uint32_t device_id = 0; @@ -112,12 +112,13 @@ static void LocalIAmHandler(uint8_t *service_request, uint16_t service_len, (void)src; (void)service_len; - len = iam_decode_service_request(service_request, &device_id, &max_apdu, - &segmentation, &vendor_id); + len = iam_decode_service_request( + service_request, &device_id, &max_apdu, &segmentation, &vendor_id); if (len != -1) { address_add(device_id, max_apdu, src); - } else + } else { fprintf(stderr, "!\n"); + } return; } @@ -134,18 +135,18 @@ static void Init_Service_Handlers(void) It is required to send the proper reject message... */ apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service); /* we must implement read property - it's required! */ - apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY, - handler_read_property); + apdu_set_confirmed_handler( + SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property); /* handle any errors coming back */ - apdu_set_error_handler(SERVICE_CONFIRMED_ATOMIC_WRITE_FILE, - Atomic_Write_File_Error_Handler); + apdu_set_error_handler( + SERVICE_CONFIRMED_ATOMIC_WRITE_FILE, Atomic_Write_File_Error_Handler); apdu_set_abort_handler(MyAbortHandler); apdu_set_reject_handler(MyRejectHandler); } int main(int argc, char *argv[]) { - BACNET_ADDRESS src = {0}; /* address where message came from */ + BACNET_ADDRESS src = { 0 }; /* address where message came from */ uint16_t pdu_len = 0; unsigned timeout = 100; /* milliseconds */ unsigned max_apdu = 0; @@ -165,9 +166,8 @@ int main(int argc, char *argv[]) if (argc < 4) { /* FIXME: what about access method - record or stream? */ - printf( - "%s device-instance file-instance local-name [octet count] [pad " - "value]\r\n", + printf("%s device-instance file-instance local-name [octet count] [pad " + "value]\r\n", filename_remove_path(argv[0])); return 0; } @@ -177,12 +177,12 @@ int main(int argc, char *argv[]) Local_File_Name = argv[3]; if (Target_Device_Object_Instance >= BACNET_MAX_INSTANCE) { fprintf(stderr, "device-instance=%u - it must be less than %u\r\n", - Target_Device_Object_Instance, BACNET_MAX_INSTANCE); + Target_Device_Object_Instance, BACNET_MAX_INSTANCE); return 1; } if (Target_File_Object_Instance >= BACNET_MAX_INSTANCE) { fprintf(stderr, "file-instance=%u - it must be less than %u\r\n", - Target_File_Object_Instance, BACNET_MAX_INSTANCE + 1); + Target_File_Object_Instance, BACNET_MAX_INSTANCE + 1); return 1; } if (argc > 4) { @@ -202,11 +202,11 @@ int main(int argc, char *argv[]) last_seconds = time(NULL); timeout_seconds = (apdu_timeout() / 1000) * apdu_retries(); /* try to bind with the device */ - found = address_bind_request(Target_Device_Object_Instance, &max_apdu, - &Target_Address); + found = address_bind_request( + Target_Device_Object_Instance, &max_apdu, &Target_Address); if (!found) { - Send_WhoIs(Target_Device_Object_Instance, - Target_Device_Object_Instance); + Send_WhoIs( + Target_Device_Object_Instance, Target_Device_Object_Instance); } /* loop forever */ for (;;) { @@ -226,8 +226,8 @@ int main(int argc, char *argv[]) } /* wait until the device is bound, or timeout and quit */ if (!found) { - found = address_bind_request(Target_Device_Object_Instance, - &max_apdu, &Target_Address); + found = address_bind_request( + Target_Device_Object_Instance, &max_apdu, &Target_Address); } if (found) { if (Target_File_Requested_Octet_Count) { @@ -269,13 +269,13 @@ int main(int argc, char *argv[]) if (pFile) { (void)fseek(pFile, fileStartPosition, SEEK_SET); len = fread(octetstring_value(&fileData), 1, - requestedOctetCount, pFile); + requestedOctetCount, pFile); if (len < requestedOctetCount) { End_Of_File_Detected = true; if (pad_byte) { memset(octetstring_value(&fileData) + len + 1, - (int)Target_File_Requested_Octet_Pad_Byte, - requestedOctetCount - len); + (int)Target_File_Requested_Octet_Pad_Byte, + requestedOctetCount - len); len = requestedOctetCount; } } diff --git a/demo/writefile/main.ide b/apps/writefile/main.ide similarity index 100% rename from demo/writefile/main.ide rename to apps/writefile/main.ide diff --git a/apps/writeprop/Makefile b/apps/writeprop/Makefile new file mode 100644 index 00000000..e740241e --- /dev/null +++ b/apps/writeprop/Makefile @@ -0,0 +1,49 @@ +#Makefile to build BACnet Application for the Linux Port + +# Executable file name +TARGET = bacwp +# BACnet objects that are used with this app +BACNET_OBJECT_DIR = $(BACNET_SRC_DIR)/bacnet/basic/object +SRC = main.c \ + $(BACNET_OBJECT_DIR)/client/device-client.c \ + $(BACNET_OBJECT_DIR)/netport.c +BACNET_BASIC_SRC += \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_apdu.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_iam.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_noserv.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_rp.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_whois.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/s_iam.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/s_wp.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/s_whois.c + +# TARGET_EXT is defined in apps/Makefile as .exe or nothing +TARGET_BIN = ${TARGET}$(TARGET_EXT) + +SRCS = $(SRC) $(BACNET_SRC) $(BACNET_BASIC_SRC) $(BACNET_PORT_SRC) + +OBJS += ${SRCS:.c=.o} + +.PHONY: all +all: Makefile ${TARGET_BIN} + +${TARGET_BIN}: ${OBJS} + ${CC} ${PFLAGS} ${OBJS} ${LFLAGS} -o $@ + size $@ + cp $@ ../../bin + +.c.o: + ${CC} -c ${CFLAGS} $*.c -o $@ + +.PHONY: depend +depend: + rm -f .depend + ${CC} -MM ${CFLAGS} *.c >> .depend + +.PHONY: clean +clean: + rm -f core ${TARGET_BIN} ${OBJS} $(TARGET).map + +.PHONY: include +include: .depend + diff --git a/demo/writeprop/main.c b/apps/writeprop/main.c similarity index 82% rename from demo/writeprop/main.c rename to apps/writeprop/main.c index 69f61a41..023afa7b 100644 --- a/demo/writeprop/main.c +++ b/apps/writeprop/main.c @@ -32,33 +32,33 @@ #include #include #include /* toupper */ -#include "bactext.h" -#include "iam.h" -#include "arf.h" -#include "tsm.h" -#include "address.h" -#include "config.h" -#include "bacdef.h" -#include "npdu.h" -#include "apdu.h" -#include "device.h" -#include "net.h" -#include "datalink.h" -#include "whois.h" -#include "version.h" +#include "bacnet/bactext.h" +#include "bacnet/iam.h" +#include "bacnet/arf.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/basic/binding/address.h" +#include "bacnet/config.h" +#include "bacnet/bacdef.h" +#include "bacnet/npdu.h" +#include "bacnet/apdu.h" +#include "bacnet/basic/object/device.h" +#include "bacport.h" +#include "bacnet/datalink/datalink.h" +#include "bacnet/whois.h" +#include "bacnet/version.h" /* some demo stuff needed */ -#include "filename.h" -#include "handlers.h" -#include "client.h" -#include "txbuf.h" -#include "dlenv.h" +#include "bacnet/basic/sys/filename.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/datalink/dlenv.h" #ifndef MAX_PROPERTY_VALUES #define MAX_PROPERTY_VALUES 64 #endif /* buffer used for receive */ -static uint8_t Rx_Buf[MAX_MPDU] = {0}; +static uint8_t Rx_Buf[MAX_MPDU] = { 0 }; /* global variables used in this file */ static uint32_t Target_Device_Object_Instance = BACNET_MAX_INSTANCE; @@ -79,43 +79,45 @@ static BACNET_ADDRESS Target_Address; /* needed for return value of main application */ static bool Error_Detected = false; -static void MyErrorHandler(BACNET_ADDRESS *src, uint8_t invoke_id, - BACNET_ERROR_CLASS error_class, - BACNET_ERROR_CODE error_code) +static void MyErrorHandler(BACNET_ADDRESS *src, + uint8_t invoke_id, + BACNET_ERROR_CLASS error_class, + BACNET_ERROR_CODE error_code) { if (address_match(&Target_Address, src) && (invoke_id == Request_Invoke_ID)) { printf("BACnet Error: %s: %s\n", - bactext_error_class_name((int)error_class), - bactext_error_code_name((int)error_code)); + bactext_error_class_name((int)error_class), + bactext_error_code_name((int)error_code)); Error_Detected = true; } } -void MyAbortHandler(BACNET_ADDRESS *src, uint8_t invoke_id, - uint8_t abort_reason, bool server) +static void MyAbortHandler( + BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t abort_reason, bool server) { (void)server; if (address_match(&Target_Address, src) && (invoke_id == Request_Invoke_ID)) { - printf("BACnet Abort: %s\n", - bactext_abort_reason_name((int)abort_reason)); + printf( + "BACnet Abort: %s\n", bactext_abort_reason_name((int)abort_reason)); Error_Detected = true; } } -void MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, - uint8_t reject_reason) +static void MyRejectHandler( + BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason) { if (address_match(&Target_Address, src) && (invoke_id == Request_Invoke_ID)) { printf("BACnet Reject: %s\n", - bactext_reject_reason_name((int)reject_reason)); + bactext_reject_reason_name((int)reject_reason)); Error_Detected = true; } } -void MyWritePropertySimpleAckHandler(BACNET_ADDRESS *src, uint8_t invoke_id) +static void MyWritePropertySimpleAckHandler( + BACNET_ADDRESS *src, uint8_t invoke_id) { if (address_match(&Target_Address, src) && (invoke_id == Request_Invoke_ID)) { @@ -135,11 +137,11 @@ static void Init_Service_Handlers(void) It is required to send the proper reject message... */ apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service); /* we must implement read property - it's required! */ - apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY, - handler_read_property); + apdu_set_confirmed_handler( + SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property); /* handle the ack coming back */ - apdu_set_confirmed_simple_ack_handler(SERVICE_CONFIRMED_WRITE_PROPERTY, - MyWritePropertySimpleAckHandler); + apdu_set_confirmed_simple_ack_handler( + SERVICE_CONFIRMED_WRITE_PROPERTY, MyWritePropertySimpleAckHandler); /* handle any errors coming back */ apdu_set_error_handler(SERVICE_CONFIRMED_WRITE_PROPERTY, MyErrorHandler); apdu_set_abort_handler(MyAbortHandler); @@ -148,9 +150,8 @@ static void Init_Service_Handlers(void) static void print_usage(char *filename) { - printf( - "Usage: %s device-instance object-type object-instance " - "property priority index tag value [tag value...]\n", + printf("Usage: %s device-instance object-type object-instance " + "property priority index tag value [tag value...]\n", filename); } @@ -229,7 +230,7 @@ static void print_help(char *filename) int main(int argc, char *argv[]) { - BACNET_ADDRESS src = {0}; /* address where message came from */ + BACNET_ADDRESS src = { 0 }; /* address where message came from */ uint16_t pdu_len = 0; unsigned timeout = 100; /* milliseconds */ unsigned max_apdu = 0; @@ -253,14 +254,13 @@ int main(int argc, char *argv[]) return 0; } if (strcmp(argv[argi], "--version") == 0) { - printf("%s %s\n", filename_remove_path(argv[0]), - BACNET_VERSION_TEXT); printf( - "Copyright (C) 2014 by Steve Karg\n" - "This is free software; see the source for copying " - "conditions.\n" - "There is NO warranty; not even for MERCHANTABILITY or\n" - "FITNESS FOR A PARTICULAR PURPOSE.\n"); + "%s %s\n", filename_remove_path(argv[0]), BACNET_VERSION_TEXT); + printf("Copyright (C) 2014 by Steve Karg\n" + "This is free software; see the source for copying " + "conditions.\n" + "There is NO warranty; not even for MERCHANTABILITY or\n" + "FITNESS FOR A PARTICULAR PURPOSE.\n"); return 0; } } @@ -279,22 +279,22 @@ int main(int argc, char *argv[]) Target_Object_Property_Index = BACNET_ARRAY_ALL; if (Target_Device_Object_Instance > BACNET_MAX_INSTANCE) { fprintf(stderr, "device-instance=%u - it must be less than %u\n", - Target_Device_Object_Instance, BACNET_MAX_INSTANCE + 1); + Target_Device_Object_Instance, BACNET_MAX_INSTANCE + 1); return 1; } if (Target_Object_Type > MAX_BACNET_OBJECT_TYPE) { fprintf(stderr, "object-type=%u - it must be less than %u\n", - Target_Object_Type, MAX_BACNET_OBJECT_TYPE + 1); + Target_Object_Type, MAX_BACNET_OBJECT_TYPE + 1); return 1; } if (Target_Object_Instance > BACNET_MAX_INSTANCE) { fprintf(stderr, "object-instance=%u - it must be less than %u\n", - Target_Object_Instance, BACNET_MAX_INSTANCE + 1); + Target_Object_Instance, BACNET_MAX_INSTANCE + 1); return 1; } if (Target_Object_Property > MAX_BACNET_PROPERTY_ID) { fprintf(stderr, "property=%u - it must be less than %u\n", - Target_Object_Property, MAX_BACNET_PROPERTY_ID + 1); + Target_Object_Property, MAX_BACNET_PROPERTY_ID + 1); return 1; } args_remaining = (argc - 7); @@ -325,7 +325,7 @@ int main(int argc, char *argv[]) i, property_tag, i, value_string); */ if (property_tag >= MAX_BACNET_APPLICATION_TAG) { fprintf(stderr, "Error: tag=%u - it must be less than %u\n", - property_tag, MAX_BACNET_APPLICATION_TAG); + property_tag, MAX_BACNET_APPLICATION_TAG); return 1; } status = bacapp_parse_application_data( @@ -346,7 +346,7 @@ int main(int argc, char *argv[]) } if (args_remaining > 0) { fprintf(stderr, "Error: Exceeded %d tag-value pairs.\n", - MAX_PROPERTY_VALUES); + MAX_PROPERTY_VALUES); return 1; } /* setup my info */ @@ -359,11 +359,11 @@ int main(int argc, char *argv[]) last_seconds = time(NULL); timeout_seconds = (apdu_timeout() / 1000) * apdu_retries(); /* try to bind with the device */ - found = address_bind_request(Target_Device_Object_Instance, &max_apdu, - &Target_Address); + found = address_bind_request( + Target_Device_Object_Instance, &max_apdu, &Target_Address); if (!found) { - Send_WhoIs(Target_Device_Object_Instance, - Target_Device_Object_Instance); + Send_WhoIs( + Target_Device_Object_Instance, Target_Device_Object_Instance); } /* loop forever */ for (;;) { @@ -371,15 +371,16 @@ int main(int argc, char *argv[]) current_seconds = time(NULL); /* at least one second has passed */ - if (current_seconds != last_seconds) + if (current_seconds != last_seconds) { tsm_timer_milliseconds( (uint16_t)((current_seconds - last_seconds) * 1000)); + } if (Error_Detected) break; /* wait until the device is bound, or timeout and quit */ if (!found) { - found = address_bind_request(Target_Device_Object_Instance, - &max_apdu, &Target_Address); + found = address_bind_request( + Target_Device_Object_Instance, &max_apdu, &Target_Address); } if (found) { if (Request_Invoke_ID == 0) { @@ -389,9 +390,9 @@ int main(int argc, char *argv[]) &Target_Object_Property_Value[0], Target_Object_Property_Priority, Target_Object_Property_Index); - } else if (tsm_invoke_id_free(Request_Invoke_ID)) + } else if (tsm_invoke_id_free(Request_Invoke_ID)) { break; - else if (tsm_invoke_id_failed(Request_Invoke_ID)) { + } else if (tsm_invoke_id_failed(Request_Invoke_ID)) { fprintf(stderr, "\rError: TSM Timeout!\n"); tsm_free_invoke_id(Request_Invoke_ID); Error_Detected = true; diff --git a/apps/writepropm/Makefile b/apps/writepropm/Makefile new file mode 100644 index 00000000..c7ea5a0e --- /dev/null +++ b/apps/writepropm/Makefile @@ -0,0 +1,55 @@ +#Makefile to build BACnet Application for the Linux Port + +# tools - only if you need them. +# Most platforms have this already defined +# CC = gcc + +# Executable file name +TARGET = bacwpm + +# BACnet objects that are used with this app +BACNET_OBJECT_DIR = $(BACNET_SRC_DIR)/bacnet/basic/object +SRC = main.c \ + $(BACNET_OBJECT_DIR)/client/device-client.c \ + $(BACNET_OBJECT_DIR)/netport.c +BACNET_BASIC_SRC += \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_apdu.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_iam.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_noserv.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_rp.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/h_whois.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/s_iam.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/s_rp.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/s_wpm.c \ + $(BACNET_SRC_DIR)/bacnet/basic/service/s_whois.c + +# TARGET_EXT is defined in apps/Makefile as .exe or nothing +TARGET_BIN = ${TARGET}$(TARGET_EXT) + +SRCS = $(SRC) $(BACNET_SRC) $(BACNET_BASIC_SRC) $(BACNET_PORT_SRC) + +OBJS += ${SRCS:.c=.o} + +.PHONY: all +all: Makefile ${TARGET_BIN} + +${TARGET_BIN}: ${OBJS} + ${CC} ${PFLAGS} ${OBJS} ${LFLAGS} -o $@ + size $@ + cp $@ ../../bin + +.c.o: + ${CC} -c ${CFLAGS} $*.c -o $@ + +.PHONY: depend +depend: + rm -f .depend + ${CC} -MM ${CFLAGS} *.c >> .depend + +.PHONY: clean +clean: + rm -f core ${TARGET_BIN} ${OBJS} $(TARGET).map + +.PHONY: include +include: .depend + diff --git a/demo/writepropm/main.c b/apps/writepropm/main.c similarity index 82% rename from demo/writepropm/main.c rename to apps/writepropm/main.c index 55286e5b..8d2b8db4 100644 --- a/demo/writepropm/main.c +++ b/apps/writepropm/main.c @@ -33,31 +33,31 @@ #define PRINT_ENABLED 1 -#include "bacdef.h" -#include "config.h" -#include "bactext.h" -#include "bacerror.h" -#include "iam.h" -#include "arf.h" -#include "tsm.h" -#include "address.h" -#include "npdu.h" -#include "apdu.h" -#include "device.h" -#include "net.h" -#include "datalink.h" -#include "whois.h" -#include "version.h" +#include "bacnet/bacdef.h" +#include "bacnet/config.h" +#include "bacnet/bactext.h" +#include "bacnet/bacerror.h" +#include "bacnet/iam.h" +#include "bacnet/arf.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/basic/binding/address.h" +#include "bacnet/npdu.h" +#include "bacnet/apdu.h" +#include "bacnet/basic/object/device.h" +#include "bacport.h" +#include "bacnet/datalink/datalink.h" +#include "bacnet/whois.h" +#include "bacnet/version.h" /* some demo stuff needed */ -#include "rpm.h" -#include "filename.h" -#include "handlers.h" -#include "client.h" -#include "txbuf.h" -#include "dlenv.h" +#include "bacnet/rpm.h" +#include "bacnet/basic/sys/filename.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/datalink/dlenv.h" /* buffer used for receive */ -static uint8_t Rx_Buf[MAX_MPDU] = {0}; +static uint8_t Rx_Buf[MAX_MPDU] = { 0 }; /* global variables used in this file */ static uint32_t Target_Device_Object_Instance = BACNET_MAX_INSTANCE; @@ -70,46 +70,47 @@ static bool Error_Detected = false; /* Used for verbose */ static bool Verbose = false; -static void MyErrorHandler(BACNET_ADDRESS *src, uint8_t invoke_id, - BACNET_ERROR_CLASS error_class, - BACNET_ERROR_CODE error_code) +static void MyErrorHandler(BACNET_ADDRESS *src, + uint8_t invoke_id, + BACNET_ERROR_CLASS error_class, + BACNET_ERROR_CODE error_code) { if (address_match(&Target_Address, src) && (invoke_id == Request_Invoke_ID)) { printf("BACnet Error: %s: %s\n", - bactext_error_class_name((int)error_class), - bactext_error_code_name((int)error_code)); + bactext_error_class_name((int)error_class), + bactext_error_code_name((int)error_code)); Error_Detected = true; /* FIXME: WPM error has extra data for first failed write. */ } } -void MyAbortHandler(BACNET_ADDRESS *src, uint8_t invoke_id, - uint8_t abort_reason, bool server) +static void MyAbortHandler( + BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t abort_reason, bool server) { (void)server; if (address_match(&Target_Address, src) && (invoke_id == Request_Invoke_ID)) { - printf("BACnet Abort: %s\n", - bactext_abort_reason_name((int)abort_reason)); + printf( + "BACnet Abort: %s\n", bactext_abort_reason_name((int)abort_reason)); Error_Detected = true; } } -void MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, - uint8_t reject_reason) +static void MyRejectHandler( + BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason) { /* FIXME: verify src and invoke id */ if (address_match(&Target_Address, src) && (invoke_id == Request_Invoke_ID)) { printf("BACnet Reject: %s\n", - bactext_reject_reason_name((int)reject_reason)); + bactext_reject_reason_name((int)reject_reason)); Error_Detected = true; } } -void MyWritePropertyMultipleSimpleAckHandler(BACNET_ADDRESS *src, - uint8_t invoke_id) +static void MyWritePropertyMultipleSimpleAckHandler( + BACNET_ADDRESS *src, uint8_t invoke_id) { if (address_match(&Target_Address, src) && (invoke_id == Request_Invoke_ID)) { @@ -129,11 +130,10 @@ static void Init_Service_Handlers(void) It is required to send the proper reject message... */ apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service); /* we must implement read property - it's required! */ - apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY, - handler_read_property); + apdu_set_confirmed_handler( + SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property); /* handle the data coming back from confirmed requests */ - apdu_set_confirmed_simple_ack_handler( - SERVICE_CONFIRMED_WRITE_PROP_MULTIPLE, + apdu_set_confirmed_simple_ack_handler(SERVICE_CONFIRMED_WRITE_PROP_MULTIPLE, MyWritePropertyMultipleSimpleAckHandler); /* handle any errors coming back */ apdu_set_error_handler(SERVICE_CONFIRMED_READ_PROPERTY, MyErrorHandler); @@ -141,7 +141,7 @@ static void Init_Service_Handlers(void) apdu_set_reject_handler(MyRejectHandler); } -void cleanup(void) +static void cleanup(void) { BACNET_WRITE_ACCESS_DATA *wpm_object; BACNET_WRITE_ACCESS_DATA *old_wpm_object; @@ -165,10 +165,9 @@ void cleanup(void) static void print_usage(char *filename) { - printf( - "Usage: %s device-instance object-type object-instance " - "property[index] priority tag value [property[index] priority tag " - "value]\n", + printf("Usage: %s device-instance object-type object-instance " + "property[index] priority tag value [property[index] priority tag " + "value]\n", filename); printf(" [--version][--help]\n"); } @@ -235,18 +234,17 @@ static void print_help(char *filename) "the demo to use this kind of table - but I also wanted to be able\n" "to do negative testing by passing the wrong tag and have the server\n" "return a reject message.\n\n"); - printf( - "Example:\n" - "If you want send a value of 100 to the Present-Value in\n" - "Analog Output 44 and 45 of Device 123 at priority 16,\n" - "send the following command:\n" - "%s 123 1 44 85 16 4 100 1 45 85 16 4 100\n", + printf("Example:\n" + "If you want send a value of 100 to the Present-Value in\n" + "Analog Output 44 and 45 of Device 123 at priority 16,\n" + "send the following command:\n" + "%s 123 1 44 85 16 4 100 1 45 85 16 4 100\n", filename); } int main(int argc, char *argv[]) { - BACNET_ADDRESS src = {0}; /* address where message came from */ + BACNET_ADDRESS src = { 0 }; /* address where message came from */ uint16_t pdu_len = 0; unsigned timeout = 100; /* milliseconds */ unsigned max_apdu = 0; @@ -256,7 +254,7 @@ int main(int argc, char *argv[]) time_t current_seconds = 0; time_t timeout_seconds = 0; bool found = false; - uint8_t buffer[MAX_PDU] = {0}; + uint8_t buffer[MAX_PDU] = { 0 }; BACNET_WRITE_ACCESS_DATA *wpm_object; BACNET_PROPERTY_VALUE *wpm_property; char *value_string = NULL; @@ -278,12 +276,11 @@ int main(int argc, char *argv[]) } if (strcmp(argv[argi], "--version") == 0) { printf("%s %s\n", filename, BACNET_VERSION_TEXT); - printf( - "Copyright (C) 2017 by Steve Karg and others.\n" - "This is free software; see the source for copying " - "conditions.\n" - "There is NO warranty; not even for MERCHANTABILITY or\n" - "FITNESS FOR A PARTICULAR PURPOSE.\n"); + printf("Copyright (C) 2017 by Steve Karg and others.\n" + "This is free software; see the source for copying " + "conditions.\n" + "There is NO warranty; not even for MERCHANTABILITY or\n" + "FITNESS FOR A PARTICULAR PURPOSE.\n"); return 0; } } @@ -295,7 +292,7 @@ int main(int argc, char *argv[]) Target_Device_Object_Instance = strtol(argv[1], NULL, 0); if (Target_Device_Object_Instance >= BACNET_MAX_INSTANCE) { fprintf(stderr, "device-instance=%u - it must be less than %u\n", - Target_Device_Object_Instance, BACNET_MAX_INSTANCE); + Target_Device_Object_Instance, BACNET_MAX_INSTANCE); return 1; } atexit(cleanup); @@ -317,7 +314,7 @@ int main(int argc, char *argv[]) } if (wpm_object->object_type >= MAX_BACNET_OBJECT_TYPE) { fprintf(stderr, "object-type=%u - it must be less than %u\n", - wpm_object->object_type, MAX_BACNET_OBJECT_TYPE); + wpm_object->object_type, MAX_BACNET_OBJECT_TYPE); return 1; } wpm_object->object_instance = strtol(argv[tag_value_arg], NULL, 0); @@ -332,7 +329,7 @@ int main(int argc, char *argv[]) } if (wpm_object->object_instance > BACNET_MAX_INSTANCE) { fprintf(stderr, "object-instance=%u - it must be less than %u\n", - wpm_object->object_instance, BACNET_MAX_INSTANCE + 1); + wpm_object->object_instance, BACNET_MAX_INSTANCE + 1); return 1; } do { @@ -341,21 +338,21 @@ int main(int argc, char *argv[]) if (wpm_property) { /* Property[index] */ scan_count = sscanf(argv[tag_value_arg], "%u[%u]", &property_id, - &property_array_index); + &property_array_index); tag_value_arg++; args_remaining--; if (scan_count > 0) { wpm_property->propertyIdentifier = property_id; if (Verbose) { printf("property-identifier=%u, array-index=%u\n", - property_id, property_array_index); + property_id, property_array_index); } if (wpm_property->propertyIdentifier > MAX_BACNET_PROPERTY_ID) { fprintf(stderr, - "property=%u - it must be less than %u\n", - wpm_property->propertyIdentifier, - MAX_BACNET_PROPERTY_ID + 1); + "property=%u - it must be less than %u\n", + wpm_property->propertyIdentifier, + MAX_BACNET_PROPERTY_ID + 1); return 1; } } @@ -366,7 +363,7 @@ int main(int argc, char *argv[]) } if (args_remaining <= 0) { fprintf(stderr, - "Error: missing priority and tag value pair.\n"); + "Error: missing priority and tag value pair.\n"); return 1; } /* Priority */ @@ -397,8 +394,8 @@ int main(int argc, char *argv[]) tag_value_arg++; args_remaining--; if (args_remaining <= 0) { - fprintf(stderr, - "Error: missing value for tag-value pair\n"); + fprintf( + stderr, "Error: missing value for tag-value pair\n"); return 1; } value_string = argv[tag_value_arg]; @@ -409,7 +406,7 @@ int main(int argc, char *argv[]) } if (property_tag >= MAX_BACNET_APPLICATION_TAG) { fprintf(stderr, "Error: tag=%u - it must be less than %u\n", - property_tag, MAX_BACNET_APPLICATION_TAG); + property_tag, MAX_BACNET_APPLICATION_TAG); return 1; } status = bacapp_parse_application_data( @@ -442,16 +439,16 @@ int main(int argc, char *argv[]) last_seconds = time(NULL); timeout_seconds = (apdu_timeout() / 1000) * apdu_retries(); /* try to bind with the device */ - found = address_bind_request(Target_Device_Object_Instance, &max_apdu, - &Target_Address); + found = address_bind_request( + Target_Device_Object_Instance, &max_apdu, &Target_Address); if (found) { if (Verbose) { printf("Found Device %u in address_cache.\n", - Target_Device_Object_Instance); + Target_Device_Object_Instance); } } else { - Send_WhoIs(Target_Device_Object_Instance, - Target_Device_Object_Instance); + Send_WhoIs( + Target_Device_Object_Instance, Target_Device_Object_Instance); } /* loop forever */ for (;;) { @@ -459,20 +456,21 @@ int main(int argc, char *argv[]) current_seconds = time(NULL); /* at least one second has passed */ - if (current_seconds != last_seconds) + if (current_seconds != last_seconds) { tsm_timer_milliseconds(((current_seconds - last_seconds) * 1000)); + } if (Error_Detected) break; /* wait until the device is bound, or timeout and quit */ if (!found) { - found = address_bind_request(Target_Device_Object_Instance, - &max_apdu, &Target_Address); + found = address_bind_request( + Target_Device_Object_Instance, &max_apdu, &Target_Address); } if (found) { if (Request_Invoke_ID == 0) { if (Verbose) { printf("Sending WritePropertyMultiple to Device %u.\n", - Target_Device_Object_Instance); + Target_Device_Object_Instance); } Request_Invoke_ID = Send_Write_Property_Multiple_Request( &buffer[0], sizeof(buffer), Target_Device_Object_Instance, diff --git a/bin/bacroute.sh b/bin/bacroute.sh index cc16156e..bd0074fb 100644 --- a/bin/bacroute.sh +++ b/bin/bacroute.sh @@ -1,19 +1,19 @@ -#!/bin/bash -echo Setting parameters for Router -BACNET_IP_PORT=47808 -export BACNET_IP_PORT -#BACNET_BBMD_PORT=47809 -#export BACNET_BBMD_PORT -BACNET_IFACE=${1} -export BACNET_IFACE -BACNET_IP6_PORT=47808 -export BACNET_IP6_PORT -BACNET_BIP6_BROADCAST=FF05::BAC0 -export BACNET_BIP6_BROADCAST -BACNET_BIP6_IFACE=${1} -export BACNET_BIP6_IFACE -# Network Numbers -BACNET_IP_NET=1 -export BACNET_IP_NET -BACNET_IP6_NET=2 -export BACNET_IP6_NET +#!/bin/bash +echo Setting parameters for Router +BACNET_IP_PORT=47808 +export BACNET_IP_PORT +#BACNET_BBMD_PORT=47809 +#export BACNET_BBMD_PORT +BACNET_IFACE=${1} +export BACNET_IFACE +BACNET_IP6_PORT=47808 +export BACNET_IP6_PORT +BACNET_BIP6_BROADCAST=FF05::BAC0 +export BACNET_BIP6_BROADCAST +BACNET_BIP6_IFACE=${1} +export BACNET_BIP6_IFACE +# Network Numbers +BACNET_IP_NET=1 +export BACNET_IP_NET +BACNET_IP6_NET=2 +export BACNET_IP6_NET diff --git a/borland.bat b/borland.bat deleted file mode 100644 index a7f94a66..00000000 --- a/borland.bat +++ /dev/null @@ -1,7 +0,0 @@ -@echo off -echo Build for Borland 5.5 tools -set BORLAND_DIR=c:\borland\bcc55 -%BORLAND_DIR%\bin\make -f makefile.b32 clean -%BORLAND_DIR%\bin\make -f makefile.b32 all - - diff --git a/build.sh b/build.sh deleted file mode 100755 index 0f35d939..00000000 --- a/build.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/sh -# Build script for MinGW -echo "Build with MinGW and MSYS: mingw.sourceforge.net" -# set PATH=C:\MinGW\msys\1.0\bin;C:\MinGW\bin -# assumes rm, cp, size are already in path -CC=gcc -AR=ar -MAKE=make -export CC AR MAKE -make BACNET_PORT=win32 BUILD=release clean all > /dev/null - -# Build for MinGW debug -# make BACNET_PORT=win32 BUILD=debug clean all - -# Build for MinGW MS/TP -# make BACNET_PORT=win32 BACDL_DEFINE=-DBACDL_MSTP=1 clean all -# make BACNET_PORT=win32 BACDL_DEFINE=-DBACDL_BIP6=1 clean all -# make BACDL_DEFINE=-DBACDL_BIP6=1 BUILD=debug clean all - -# On Linux, install mingw32 and use this: -# make BACNET_PORT=win32 CC=i586-mingw32msvc-gcc AR=i586-mingw32msvc-ar clean all - -echo "Complete!" diff --git a/comment.sh b/comment.sh deleted file mode 100755 index 09aef9bd..00000000 --- a/comment.sh +++ /dev/null @@ -1,25 +0,0 @@ -#!/bin/bash -# This script converts any C++ comments to C comments -# using the ccmtcnvt tool from the liwc package - -CONVERTER=/usr/bin/ccmtcnvt -# silent fail if the tool is not installed -[ -x ${CONVERTER} ] || exit 0 - -directory=${1-`pwd`} -for filename in $( find ${directory} -name '*.c' ) -do - echo Converting ${filename} - TEMPFILE="/tmp/ccmtcnvt.$RANDOM.txt" - ${CONVERTER} ${filename} > ${TEMPFILE} - mv ${TEMPFILE} ${filename} -done - -for filename in $( find ${directory} -name '*.h' ) -do - echo Converting ${filename} - TEMPFILE="/tmp/ccmtcnvt.$RANDOM.txt" - ${CONVERTER} ${filename} > ${TEMPFILE} - mv ${TEMPFILE} ${filename} -done - diff --git a/demo/BACnetDemo.workspace b/demo/BACnetDemo.workspace deleted file mode 100644 index e329a2e6..00000000 --- a/demo/BACnetDemo.workspace +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/demo/Makefile b/demo/Makefile deleted file mode 100644 index 9fff0730..00000000 --- a/demo/Makefile +++ /dev/null @@ -1,116 +0,0 @@ -# tools - only if you need them. -# Most platforms have this already defined -# CC = gcc -# AR = ar -# MAKE = make -# SIZE = size -# -# Assumes rm and cp are available - -# Directories -BACNET_PORT ?= linux -BACNET_PORT_DIR = ../../ports/${BACNET_PORT} -BACNET_INCLUDE = ../../include -BACNET_OBJECT = ../../demo/object -BACNET_HANDLER = ../../demo/handler -# BACnet Library -BACNET_LIB_DIR = ../../lib -BACNET_LIB_NAME = bacnet -BACNET_LIB_TARGET = $(BACNET_LIB_DIR)/lib$(BACNET_LIB_NAME).a -# Compiler Setup -INCLUDE1 = -I$(BACNET_PORT_DIR) -I$(BACNET_OBJECT) -I$(BACNET_HANDLER) -INCLUDE2 = -I$(BACNET_INCLUDE) -INCLUDES = $(INCLUDE1) $(INCLUDE2) -BACNET_LIB := -L$(BACNET_LIB_DIR),-l$(BACNET_LIB_NAME) -# build for UCI -ifneq (,$(findstring -DBAC_UCI,$(BACNET_DEFINES))) -BACNET_LIB = $(BACNET_LIB),-L$(UCI_LIB_DIR),-luci -endif -# OS specific builds -ifeq (${BACNET_PORT},linux) -PFLAGS = -pthread -TARGET_EXT = -SYSTEM_LIB=-lc,-lgcc,-lrt,-lm -endif -ifeq (${BACNET_PORT},bsd) -PFLAGS = -pthread -TARGET_EXT = -SYSTEM_LIB=-lc,-lm -endif -ifeq (${BACNET_PORT},win32) -TARGET_EXT = .exe -SYSTEM_LIB=-lws2_32,-lgcc,-lm,-liphlpapi,-lwinmm -DEFINES += -D_NO_OLDNAMES -endif -#build for release (default) or debug -DEBUGGING = -OPTIMIZATION = -Os -ifeq (${BUILD},debug) -OPTIMIZATION = -O0 -DEBUGGING = -g -DDEBUG_ENABLED=1 -endif -# put all the flags together -CFLAGS := -Wall $(DEBUGGING) $(OPTIMIZATION) $(INCLUDES) $(DEFINES) -LFLAGS := -Wl,$(BACNET_LIB),$(SYSTEM_LIB) - -.EXPORT_ALL_VARIABLES: - -SUBDIRS = readprop writeprop readfile writefile reinit server dcc \ - whohas whois iam ucov scov timesync epics readpropm readrange \ - writepropm uptransfer getevent uevent abort error - -ifeq (${BACDL_DEFINE},-DBACDL_BIP=1) - SUBDIRS += whoisrouter iamrouter initrouter readbdt -endif - -ifeq (${BACNET_PORT},linux) -ifneq (${OSTYPE},cygwin) - SUBDIRS += mstpcap mstpcrc -endif -endif - -ifeq (${BACNET_PORT},win32) - SUBDIRS += ptransfer mstpcap mstpcrc -endif - -.PHONY : all gateway router clean - -TARGETS = all clean - -$(TARGETS): %: $(patsubst %, %.%, $(SUBDIRS)) - -$(foreach TGT, $(TARGETS), $(patsubst %, %.$(TGT), $(SUBDIRS))): - $(MAKE) -s -b -C $(subst ., , $@) - -gateway: - $(MAKE) -s -b -C gateway - -server: - $(MAKE) -b -C server - -mstpcap: - $(MAKE) -b -C mstpcap - -mstpcrc: - $(MAKE) -b -C mstpcrc - -iam: - $(MAKE) -b -C iam - -uevent: - $(MAKE) -b -C uevent - -abort: - $(MAKE) -b -C abort - -error: - $(MAKE) -b -C error - -router: - $(MAKE) -s -b -C router - -router-ipv6: - $(MAKE) -b -C router-ipv6 - -writepropm: - $(MAKE) -b -C writepropm diff --git a/demo/abort/Makefile b/demo/abort/Makefile deleted file mode 100644 index 439a185d..00000000 --- a/demo/abort/Makefile +++ /dev/null @@ -1,39 +0,0 @@ -#Makefile to build BACnet Application for the Linux Port - -# tools - only if you need them. -# Most platforms have this already defined -# CC = gcc - -TARGET = bacabort - -TARGET_BIN = ${TARGET}$(TARGET_EXT) - -SRCS = main.c \ - ../object/netport.c \ - ../object/device-client.c - -OBJS = ${SRCS:.c=.o} - -all: ${BACNET_LIB_TARGET} Makefile ${TARGET_BIN} - -${TARGET_BIN}: ${OBJS} Makefile ${BACNET_LIB_TARGET} - ${CC} ${PFLAGS} ${OBJS} ${LFLAGS} -o $@ - size $@ - cp $@ ../../bin - -lib: ${BACNET_LIB_TARGET} - -${BACNET_LIB_TARGET}: - ( cd ${BACNET_LIB_DIR} ; $(MAKE) clean ; $(MAKE) ) - -.c.o: - ${CC} -c ${CFLAGS} $*.c -o $@ - -depend: - rm -f .depend - ${CC} -MM ${CFLAGS} *.c >> .depend - -clean: - rm -f core ${TARGET_BIN} ${OBJS} ${BACNET_LIB_TARGET} $(TARGET).map - -include: .depend diff --git a/demo/dcc/Makefile b/demo/dcc/Makefile deleted file mode 100644 index a2e8a3b1..00000000 --- a/demo/dcc/Makefile +++ /dev/null @@ -1,40 +0,0 @@ -#Makefile to build BACnet Application for GCC compiler - -# tools - only if you need them. -# Most platforms have this already defined -# CC = gcc - -TARGET = bacdcc - -TARGET_BIN = ${TARGET}$(TARGET_EXT) - -SRCS = main.c \ - ../object/netport.c \ - ../object/device-client.c - -OBJS = ${SRCS:.c=.o} - -all: ${BACNET_LIB_TARGET} Makefile ${TARGET_BIN} - -${TARGET_BIN}: ${OBJS} Makefile ${BACNET_LIB_TARGET} - ${CC} ${PFLAGS} ${OBJS} ${LFLAGS} -o $@ - size $@ - cp $@ ../../bin - -lib: ${BACNET_LIB_TARGET} - -${BACNET_LIB_TARGET}: - ( cd ${BACNET_LIB_DIR} ; $(MAKE) clean ; $(MAKE) ) - -.c.o: - ${CC} -c ${CFLAGS} $*.c -o $@ - -depend: - rm -f .depend - ${CC} -MM ${CFLAGS} *.c >> .depend - -clean: - rm -f core ${TARGET_BIN} ${OBJS} ${BACNET_LIB_TARGET} $(TARGET).map - -include: .depend - diff --git a/demo/dcc/makefile.b32 b/demo/dcc/makefile.b32 deleted file mode 100644 index c68059bb..00000000 --- a/demo/dcc/makefile.b32 +++ /dev/null @@ -1,140 +0,0 @@ -# -# Simple makefile to build an executable for Win32 -# -# This makefile assumes Borland bcc32 development environment -# on Windows NT/9x/2000/XP -# - -!ifndef BORLAND_DIR -BORLAND_DIR_Not_Defined: - @echo . - @echo You must define environment variable BORLAND_DIR to compile. -!endif - -# target -PRODUCT = bacdcc -PRODUCT_EXE = $(PRODUCT).exe - -# tools -CC = $(BORLAND_DIR)\bin\bcc32 -MAKE=$(BORLAND_DIR)\bin\make.exe -#LINK = $(BORLAND_DIR)\bin\tlink32 -LINK = $(BORLAND_DIR)\bin\ilink32 - -BACNET_LIB_DIR = ..\..\lib -BACNET_LIB = $(BACNET_LIB_DIR)\bacnet.lib - -# directories -BACNET_PORT = ..\..\ports\win32 -BACNET_INCLUDE = ..\..\include -BACNET_OBJECT = ..\object -BACNET_HANDLER = ..\handler -INCLUDES = \ - -I$(BACNET_INCLUDE) \ - -I$(BACNET_PORT) \ - -I$(BACNET_OBJECT) \ - -I$(BACNET_HANDLER) \ - -I$(BORLAND_DIR)\include - -# -BACNET_DEFINES = -DPRINT_ENABLED=1 -DBACAPP_ALL -#BACDL_DEFINE=-DBACDL_MSTP=1 -BACDL_DEFINE=-DBACDL_BIP=1 -DUSE_INADDR=1 -DEFINES = $(BACNET_DEFINES) $(BACDL_DEFINE) - -SRCS = main.c \ - $(BACNET_OBJECT)\device-client.c - -OBJS = $(SRCS:.c=.obj) - -# -# Compiler definitions -# -BCC_CFG = bcc32.cfg - -# -# Include directories -# -CFLAGS = $(INCLUDES) $(DEFINES) - -# -# Libraries -# -C_LIB_DIR = $(BORLAND_DIR)\lib - -LIBS = $(BACNET_LIB) \ - $(C_LIB_DIR)\IMPORT32.lib \ - $(C_LIB_DIR)\CW32MT.lib \ - -# -# Main target -# -# This should be the first one in the makefile - -all : $(BACNET_LIB) $(BCC_CFG) $(OBJS) $(PRODUCT_EXE) - del $(BCC_CFG) - -install: $(PRODUCT_EXE) - copy $(PRODUCT_EXE) ..\..\bin\$(PRODUCT_EXE) - -# Linker specific: the link below is for BCC linker/compiler. If you link -# with a different linker - please change accordingly. -# - -# need a temp response file (@&&| ... |) because command line is too long -# $** lists each dependency -# $< target name -# $* target name without extension -$(PRODUCT_EXE) : $(OBJS) - @echo Running Linker for $(PRODUCT_EXE) - $(LINK) -L$(C_LIB_DIR) -L$(BACNET_LIB_DIR) -m -c -s -v @&&| - $(BORLAND_DIR)\lib\c0x32.obj $** - $< - $*.map - $(LIBS) -| - -# -# Utilities - -clean : - del $(OBJS) - del $(PRODUCT_EXE) - del $(PRODUCT).map - del $(PRODUCT).ilc - del $(PRODUCT).ild - del $(PRODUCT).ilf - del $(PRODUCT).ils - del $(PRODUCT).tds - del $(BCC_CFG) - -# -# Generic rules -# -.SUFFIXES: .cpp .c .sbr .obj - -# -# cc generic rule -# -.c.obj: - $(CC) +$(BCC_CFG) -o$@ $< - -# Compiler configuration file -$(BCC_CFG) : - Copy &&| - $(CFLAGS) - -c - -y #include line numbers in OBJ's - -v #include debug info - -w+ #turn on all warnings - -Od #disable all optimizations - #-a4 #32 bit data alignment - #-M # generate link map - #-ls # linker options - #-WM- #not multithread - -WM #multithread - -w-aus # ignore warning assigned a value that is never used - -w-sig # ignore warning conversion may lose sig digits -| $@ - -# EOF: makefile diff --git a/demo/dcc/makefile.g++ b/demo/dcc/makefile.g++ deleted file mode 100644 index d8a63f55..00000000 --- a/demo/dcc/makefile.g++ +++ /dev/null @@ -1,506 +0,0 @@ -############################################################################# - -# Makefile for building bacdcc -# Generated by tmake at 11:27, 2006/05/10 -# Project: tmake -# Template: app -############################################################################# - -####### Compiler, tools and options - -QTDIR = /usr -CC = gcc -CXX = g++ -CFLAGS = -pipe -Wall -W -g -DBACDL_BIP=1 -DTSM_ENABLED=1 -DUSE_INADDR=1 -DBIP_DEBUG -CXXFLAGS= -pipe -Wall -W -g -DBACDL_BIP=1 -DTSM_ENABLED=1 -DUSE_INADDR=1 -DBIP_DEBUG -INCPATH = -I. -I../.. -I../../demo/object -I../../demo/handler -I../../ports/linux -LINK = g++ -LFLAGS = -LIBS = $(SUBLIBS) -MOC = $(QTDIR)/bin/moc -UIC = $(QTDIR)/bin/uic - -TAR = tar -cf -GZIP = gzip -9f - -####### Files - -HEADERS = -SOURCES = main.c \ - ../../filename.c \ - ../../bip.c \ - ../../demo/handler/txbuf.c \ - ../../demo/handler/noserv.c \ - ../../demo/handler/h_whois.c \ - ../../demo/handler/h_iam.c \ - ../../demo/handler/h_rp.c \ - ../../demo/handler/h_dcc.c \ - ../../demo/handler/s_whois.c \ - ../../demo/handler/s_dcc.c \ - ../../bacdcode.c \ - ../../bacapp.c \ - ../../bacstr.c \ - ../../bactext.c \ - ../../indtext.c \ - ../../bigend.c \ - ../../whois.c \ - ../../iam.c \ - ../../rp.c \ - ../../wp.c \ - ../../arf.c \ - ../../awf.c \ - ../../dcc.c \ - ../../demo/object/bacfile.c \ - ../../demo/object/device.c \ - ../../demo/object/ai.c \ - ../../demo/object/ao.c \ - ../../demo/object/bi.c \ - ../../demo/object/bo.c \ - ../../demo/object/lsp.c \ - ../../datalink.c \ - ../../tsm.c \ - ../../address.c \ - ../../abort.c \ - ../../reject.c \ - ../../bacerror.c \ - ../../apdu.c \ - ../../npdu.c \ - ../../ports/linux/bip-init.c -OBJECTS = main.o \ - ../../filename.o \ - ../../bip.o \ - ../../demo/handler/txbuf.o \ - ../../demo/handler/noserv.o \ - ../../demo/handler/h_whois.o \ - ../../demo/handler/h_iam.o \ - ../../demo/handler/h_rp.o \ - ../../demo/handler/h_dcc.o \ - ../../demo/handler/s_whois.o \ - ../../demo/handler/s_dcc.o \ - ../../bacdcode.o \ - ../../bacapp.o \ - ../../bacstr.o \ - ../../bactext.o \ - ../../indtext.o \ - ../../bigend.o \ - ../../whois.o \ - ../../iam.o \ - ../../rp.o \ - ../../wp.o \ - ../../arf.o \ - ../../awf.o \ - ../../dcc.o \ - ../../demo/object/bacfile.o \ - ../../demo/object/device.o \ - ../../demo/object/ai.o \ - ../../demo/object/ao.o \ - ../../demo/object/bi.o \ - ../../demo/object/bo.o \ - ../../demo/object/lsp.o \ - ../../datalink.o \ - ../../tsm.o \ - ../../address.o \ - ../../abort.o \ - ../../reject.o \ - ../../bacerror.o \ - ../../apdu.o \ - ../../npdu.o \ - ../../ports/linux/bip-init.o -INTERFACES = -UICDECLS = -UICIMPLS = -SRCMOC = -OBJMOC = -DIST = -TARGET = bacdcc -INTERFACE_DECL_PATH = . - -####### Implicit rules - -.SUFFIXES: .cpp .cxx .cc .C .c - -.cpp.o: - $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< - -.cxx.o: - $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< - -.cc.o: - $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< - -.C.o: - $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< - -.c.o: - $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $< - -####### Build rules - - -all: $(TARGET) - -$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) - $(LINK) $(LFLAGS) -o $(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS) - -moc: $(SRCMOC) - -tmake: makefile.g++ - -makefile.g++: tmake.pro - tmake tmake.pro -o makefile.g++ - -dist: - $(TAR) tmake.tar tmake.pro $(SOURCES) $(HEADERS) $(INTERFACES) $(DIST) - $(GZIP) tmake.tar - -clean: - -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS) $(TARGET) - -rm -f *~ core - -rm -f core *~ - -####### Sub-libraries - - -###### Combined headers - - -####### Compile - -main.o: main.c - -../../filename.o: ../../filename.c - -../../bip.o: ../../bip.c \ - ../../bacdcode.h \ - ../../bacdef.h \ - ../../bacenum.h \ - ../../config.h \ - ../../bacstr.h \ - ../../bip.h - -../../demo/handler/txbuf.o: ../../demo/handler/txbuf.c \ - ../../config.h - -../../demo/handler/noserv.o: ../../demo/handler/noserv.c \ - ../../demo/handler/txbuf.h \ - ../../config.h \ - ../../bacdef.h \ - ../../bacenum.h \ - ../../bacdcode.h \ - ../../bacstr.h - -../../demo/handler/h_whois.o: ../../demo/handler/h_whois.c \ - ../../config.h \ - ../../demo/handler/txbuf.h \ - ../../bacdef.h \ - ../../bacenum.h \ - ../../bacdcode.h \ - ../../bacstr.h \ - ../../demo/handler/client.h - -../../demo/handler/h_iam.o: ../../demo/handler/h_iam.c \ - ../../config.h \ - ../../demo/handler/txbuf.h \ - ../../bacdef.h \ - ../../bacenum.h \ - ../../bacdcode.h \ - ../../bacstr.h - -../../demo/handler/h_rp.o: ../../demo/handler/h_rp.c \ - ../../config.h \ - ../../demo/handler/txbuf.h \ - ../../bacdef.h \ - ../../bacenum.h \ - ../../bacdcode.h \ - ../../bacstr.h - -../../demo/handler/h_dcc.o: ../../demo/handler/h_dcc.c \ - ../../config.h \ - ../../demo/handler/txbuf.h \ - ../../bacdef.h \ - ../../bacenum.h \ - ../../bacdcode.h \ - ../../bacstr.h - -../../demo/handler/s_whois.o: ../../demo/handler/s_whois.c \ - ../../config.h \ - ../../demo/handler/txbuf.h \ - ../../bacdef.h \ - ../../bacenum.h \ - ../../bacdcode.h \ - ../../bacstr.h \ - ../../demo/handler/handlers.h - -../../demo/handler/s_dcc.o: ../../demo/handler/s_dcc.c \ - ../../config.h \ - ../../demo/handler/txbuf.h \ - ../../bacdef.h \ - ../../bacenum.h \ - ../../bacdcode.h \ - ../../bacstr.h \ - ../../demo/handler/handlers.h - -../../bacdcode.o: ../../bacdcode.c \ - ../../bacdef.h \ - ../../bacenum.h \ - ../../config.h \ - ../../bacdcode.h \ - ../../bacstr.h \ - ../../bits.h \ - ../../bigend.h - -../../bacapp.o: ../../bacapp.c \ - ../../bacenum.h \ - ../../bacdcode.h \ - ../../bacdef.h \ - ../../config.h \ - ../../bacstr.h \ - ../../bacapp.h \ - ../../bactext.h \ - ../../indtext.h - -../../bacstr.o: ../../bacstr.c \ - ../../bacstr.h \ - ../../bacdef.h \ - ../../bacenum.h \ - ../../config.h \ - ../../bits.h - -../../bactext.o: ../../bactext.c \ - ../../indtext.h \ - ../../bacenum.h - -../../indtext.o: ../../indtext.c \ - ../../indtext.h - -../../bigend.o: ../../bigend.c - -../../whois.o: ../../whois.c \ - ../../bacenum.h \ - ../../bacdcode.h \ - ../../bacdef.h \ - ../../config.h \ - ../../bacstr.h - -../../iam.o: ../../iam.c \ - ../../bacenum.h \ - ../../bacdef.h \ - ../../config.h \ - ../../npdu.h \ - ../../datalink.h \ - ../../ethernet.h \ - ../../arcnet.h \ - ../../dlmstp.h \ - ../../bip.h \ - ../../bacdcode.h \ - ../../bacstr.h \ - ../../address.h - -../../rp.o: ../../rp.c \ - ../../bacenum.h \ - ../../bacdcode.h \ - ../../bacdef.h \ - ../../config.h \ - ../../bacstr.h \ - ../../rp.h - -../../wp.o: ../../wp.c \ - ../../bacenum.h \ - ../../bacdcode.h \ - ../../bacdef.h \ - ../../config.h \ - ../../bacstr.h \ - ../../wp.h \ - ../../bacapp.h - -../../arf.o: ../../arf.c \ - ../../bacenum.h \ - ../../bacdcode.h \ - ../../bacdef.h \ - ../../config.h \ - ../../bacstr.h \ - ../../arf.h - -../../awf.o: ../../awf.c \ - ../../bacenum.h \ - ../../bacdcode.h \ - ../../bacdef.h \ - ../../config.h \ - ../../bacstr.h \ - ../../awf.h - -../../dcc.o: ../../dcc.c \ - ../../bacenum.h \ - ../../bacdcode.h \ - ../../bacdef.h \ - ../../config.h \ - ../../bacstr.h \ - ../../dcc.h - -../../demo/object/bacfile.o: ../../demo/object/bacfile.c \ - ../../config.h \ - ../../address.h \ - ../../bacdef.h \ - ../../bacenum.h \ - ../../datalink.h \ - ../../ethernet.h \ - ../../arcnet.h \ - ../../dlmstp.h \ - ../../bip.h \ - ../../bacdcode.h \ - ../../bacstr.h \ - ../../npdu.h \ - ../../demo/object/device.h \ - ../../wp.h \ - ../../bacapp.h \ - ../../arf.h \ - ../../awf.h - -../../demo/object/device.o: ../../demo/object/device.c \ - ../../bacdef.h \ - ../../bacenum.h \ - ../../config.h \ - ../../bacdcode.h \ - ../../bacstr.h \ - ../../demo/object/ai.h \ - ../../demo/object/bi.h \ - ../../demo/object/bo.h \ - ../../wp.h \ - ../../bacapp.h \ - ../../demo/object/ao.h \ - ../../demo/object/lsp.h \ - ../../demo/object/device.h \ - ../../demo/object/bacfile.h \ - ../../arf.h - -../../demo/object/ai.o: ../../demo/object/ai.c \ - ../../bacdef.h \ - ../../bacenum.h \ - ../../config.h \ - ../../bacdcode.h \ - ../../bacstr.h - -../../demo/object/ao.o: ../../demo/object/ao.c \ - ../../bacdef.h \ - ../../bacenum.h \ - ../../config.h \ - ../../bacdcode.h \ - ../../bacstr.h \ - ../../wp.h \ - ../../bacapp.h - -../../demo/object/bi.o: ../../demo/object/bi.c \ - ../../bacdef.h \ - ../../bacenum.h \ - ../../config.h \ - ../../bacdcode.h \ - ../../bacstr.h - -../../demo/object/bo.o: ../../demo/object/bo.c \ - ../../bacdef.h \ - ../../bacenum.h \ - ../../config.h \ - ../../bacdcode.h \ - ../../bacstr.h \ - ../../wp.h \ - ../../bacapp.h - -../../demo/object/lsp.o: ../../demo/object/lsp.c \ - ../../bacdef.h \ - ../../bacenum.h \ - ../../config.h \ - ../../bacdcode.h \ - ../../bacstr.h \ - ../../wp.h \ - ../../bacapp.h - -../../datalink.o: ../../datalink.c \ - ../../datalink.h \ - ../../bacdef.h \ - ../../bacenum.h \ - ../../config.h \ - ../../ethernet.h \ - ../../arcnet.h \ - ../../dlmstp.h \ - ../../bip.h - -../../tsm.o: ../../tsm.c \ - ../../bits.h \ - ../../apdu.h \ - ../../bacdef.h \ - ../../bacenum.h \ - ../../config.h \ - ../../bacdcode.h \ - ../../bacstr.h \ - ../../tsm.h \ - ../../demo/object/device.h \ - ../../wp.h \ - ../../bacapp.h \ - ../../datalink.h \ - ../../ethernet.h \ - ../../arcnet.h \ - ../../dlmstp.h \ - ../../bip.h \ - ../../demo/handler/handlers.h \ - ../../address.h - -../../address.o: ../../address.c \ - ../../config.h \ - ../../address.h \ - ../../bacdef.h \ - ../../bacenum.h \ - ../../bacdcode.h \ - ../../bacstr.h - -../../abort.o: ../../abort.c \ - ../../bacenum.h \ - ../../bacdcode.h \ - ../../bacdef.h \ - ../../config.h \ - ../../bacstr.h - -../../reject.o: ../../reject.c \ - ../../bacenum.h \ - ../../bacdcode.h \ - ../../bacdef.h \ - ../../config.h \ - ../../bacstr.h - -../../bacerror.o: ../../bacerror.c \ - ../../bacenum.h \ - ../../bacdcode.h \ - ../../bacdef.h \ - ../../config.h \ - ../../bacstr.h - -../../apdu.o: ../../apdu.c \ - ../../bits.h \ - ../../apdu.h \ - ../../bacdef.h \ - ../../bacenum.h \ - ../../config.h \ - ../../bacdcode.h \ - ../../bacstr.h \ - ../../tsm.h \ - ../../dcc.h \ - ../../iam.h - -../../npdu.o: ../../npdu.c \ - ../../bacdef.h \ - ../../bacenum.h \ - ../../config.h \ - ../../bacdcode.h \ - ../../bacstr.h \ - ../../bits.h \ - ../../npdu.h \ - ../../apdu.h - -../../ports/linux/bip-init.o: ../../ports/linux/bip-init.c \ - ../../bacdcode.h \ - ../../bacdef.h \ - ../../bacenum.h \ - ../../config.h \ - ../../bacstr.h \ - ../../bip.h \ - ../../ports/linux/net.h - diff --git a/demo/dcc/tmake.pro b/demo/dcc/tmake.pro deleted file mode 100644 index 1cb88954..00000000 --- a/demo/dcc/tmake.pro +++ /dev/null @@ -1,59 +0,0 @@ -TEMPLATE = app -CONFIG = warn_on debug console -CLEAN_FILES = core *~ -TARGET = bacdcc -DEFINES = BACDL_BIP=1 TSM_ENABLED=1 USE_INADDR=1 BIP_DEBUG -SOURCES = main.c \ - ../../filename.c \ - ../../bip.c \ - ../../demo/handler/txbuf.c \ - ../../demo/handler/noserv.c \ - ../../demo/handler/h_whois.c \ - ../../demo/handler/h_iam.c \ - ../../demo/handler/h_rp.c \ - ../../demo/handler/h_dcc.c \ - ../../demo/handler/s_whois.c \ - ../../demo/handler/s_dcc.c \ - ../../bacdcode.c \ - ../../bacapp.c \ - ../../bacstr.c \ - ../../bactext.c \ - ../../indtext.c \ - ../../bigend.c \ - ../../whois.c \ - ../../iam.c \ - ../../rp.c \ - ../../wp.c \ - ../../arf.c \ - ../../awf.c \ - ../../dcc.c \ - ../../demo/object/bacfile.c \ - ../../demo/object/device.c \ - ../../demo/object/ai.c \ - ../../demo/object/ao.c \ - ../../demo/object/bi.c \ - ../../demo/object/bo.c \ - ../../demo/object/lsp.c \ - ../../datalink.c \ - ../../tsm.c \ - ../../address.c \ - ../../abort.c \ - ../../reject.c \ - ../../bacerror.c \ - ../../apdu.c \ - ../../npdu.c -unix:SOURCES += ../../ports/linux/bip-init.c -win32:SOURCES += ../../ports/win32/bip-init.c - -INCLUDEPATH = . \ - ../../ \ - ../../demo/object \ - ../../demo/handler - -unix:INCLUDEPATH += ../../ports/linux -win32:INCLUDEPATH += ../../ports/win32 - -#unix:HEADERS += ../../ports/linux/net.h -#win32:HEADERS += ../../ports/win32/stdint.h -#win32:HEADERS += ../../ports/win32/net.h -#win32:HEADERS += ../../ports/win32/stdbool.h diff --git a/demo/epics/Makefile b/demo/epics/Makefile deleted file mode 100644 index 09910060..00000000 --- a/demo/epics/Makefile +++ /dev/null @@ -1,39 +0,0 @@ -#Makefile to build BACnet Application for the Linux Port - -# tools - only if you need them. -# Most platforms have this already defined -# CC = gcc - -TARGET = bacepics - -TARGET_BIN = ${TARGET}$(TARGET_EXT) - -SRCS = main.c \ - ../object/netport.c \ - ../object/device-client.c - -OBJS = ${SRCS:.c=.o} - -all: ${BACNET_LIB_TARGET} Makefile ${TARGET_BIN} - -${TARGET_BIN}: ${OBJS} Makefile ${BACNET_LIB_TARGET} - ${CC} ${PFLAGS} ${OBJS} ${LFLAGS} -o $@ - size $@ - cp $@ ../../bin - -lib: ${BACNET_LIB_TARGET} - -${BACNET_LIB_TARGET}: - ( cd ${BACNET_LIB_DIR} ; $(MAKE) clean ; $(MAKE) ) - -.c.o: - ${CC} -c ${CFLAGS} $*.c -o $@ - -depend: - rm -f .depend - ${CC} -MM ${CFLAGS} *.c >> .depend - -clean: - rm -f core ${TARGET_BIN} ${OBJS} ${BACNET_LIB_TARGET} $(TARGET).map - -include: .depend diff --git a/demo/epics/bacepics.cbp b/demo/epics/bacepics.cbp deleted file mode 100644 index 35feaf9d..00000000 --- a/demo/epics/bacepics.cbp +++ /dev/null @@ -1,60 +0,0 @@ - - - - - - diff --git a/demo/epics/makefile.b32 b/demo/epics/makefile.b32 deleted file mode 100644 index a990688f..00000000 --- a/demo/epics/makefile.b32 +++ /dev/null @@ -1,139 +0,0 @@ -# -# Simple makefile to build an executable for Win32 -# -# This makefile assumes Borland bcc32 development environment -# on Windows NT/9x/2000/XP -# - -!ifndef BORLAND_DIR -BORLAND_DIR_Not_Defined: - @echo . - @echo You must define environment variable BORLAND_DIR to compile. -!endif - -PRODUCT = bacepics -PRODUCT_EXE = $(PRODUCT).exe - -# tools -CC = $(BORLAND_DIR)\bin\bcc32 -MAKE=$(BORLAND_DIR)\bin\make.exe -#LINK = $(BORLAND_DIR)\bin\tlink32 -LINK = $(BORLAND_DIR)\bin\ilink32 - -BACNET_LIB_DIR = ..\..\lib -BACNET_LIB = $(BACNET_LIB_DIR)\bacnet.lib - -# directories -BACNET_SOURCE = ..\..\src -BACNET_PORT = ..\..\ports\win32 -BACNET_INCLUDE = ..\..\include -BACNET_OBJECT = ..\object -BACNET_HANDLER = ..\handler -INCLUDES = \ - -I$(BACNET_INCLUDE) \ - -I$(BACNET_PORT) \ - -I$(BACNET_OBJECT) \ - -I$(BACNET_HANDLER) \ - -I$(BORLAND_DIR)\include - -# -BACNET_DEFINES = -DPRINT_ENABLED=1 -DBACAPP_ALL -#BACDL_DEFINE=-DBACDL_MSTP=1 -BACDL_DEFINE=-DBACDL_BIP=1 -DUSE_INADDR=1 -DEFINES = $(BACNET_DEFINES) $(BACDL_DEFINE) - -SRCS = main.c - -OBJS = $(SRCS:.c=.obj) - -# -# Compiler definitions -# -BCC_CFG = bcc32.cfg - -# -# Include directories -# -CFLAGS = $(INCLUDES) $(DEFINES) - -# -# Libraries -# -C_LIB_DIR = $(BORLAND_DIR)\lib - -LIBS = $(BACNET_LIB) \ - $(C_LIB_DIR)\IMPORT32.lib \ - $(C_LIB_DIR)\CW32MT.lib \ - -# -# Main target -# -# This should be the first one in the makefile - -all : $(BACNET_LIB) $(BCC_CFG) $(OBJS) $(PRODUCT_EXE) - del $(BCC_CFG) - -install: $(PRODUCT_EXE) - copy $(PRODUCT_EXE) ..\..\bin\$(PRODUCT_EXE) - -# Linker specific: the link below is for BCC linker/compiler. If you link -# with a different linker - please change accordingly. -# - -# need a temp response file (@&&| ... |) because command line is too long -# $** lists each dependency -# $< target name -# $* target name without extension -$(PRODUCT_EXE) : $(OBJS) - @echo Running Linker for $(PRODUCT_EXE) - $(LINK) -L$(C_LIB_DIR) -L$(BACNET_LIB_DIR) -m -c -s -v @&&| - $(BORLAND_DIR)\lib\c0x32.obj $** - $< - $*.map - $(LIBS) -| - -# -# Utilities - -clean : - del $(OBJS) - del $(PRODUCT_EXE) - del $(PRODUCT).map - del $(PRODUCT).ilc - del $(PRODUCT).ild - del $(PRODUCT).ilf - del $(PRODUCT).ils - del $(PRODUCT).tds - del $(BCC_CFG) - -# -# Generic rules -# -.SUFFIXES: .cpp .c .sbr .obj - -# -# cc generic rule -# -.c.obj: - $(CC) +$(BCC_CFG) -o$@ $< - -# Compiler configuration file -$(BCC_CFG) : - Copy &&| - $(CFLAGS) - -c - -y #include line numbers in OBJ's - -v #include debug info - -w+ #turn on all warnings - -Od #disable all optimizations - #-a4 #32 bit data alignment - #-M # generate link map - #-ls # linker options - #-WM- #not multithread - -WM #multithread - -w-aus # ignore warning assigned a value that is never used - -w-sig # ignore warning conversion may lose sig digits -| $@ - -# EOF: makefile diff --git a/demo/error/Makefile b/demo/error/Makefile deleted file mode 100644 index 9088a4b1..00000000 --- a/demo/error/Makefile +++ /dev/null @@ -1,39 +0,0 @@ -#Makefile to build BACnet Application for the Linux Port - -# tools - only if you need them. -# Most platforms have this already defined -# CC = gcc - -TARGET = bacerror - -TARGET_BIN = ${TARGET}$(TARGET_EXT) - -SRCS = main.c \ - ../object/netport.c \ - ../object/device-client.c - -OBJS = ${SRCS:.c=.o} - -all: ${BACNET_LIB_TARGET} Makefile ${TARGET_BIN} - -${TARGET_BIN}: ${OBJS} Makefile ${BACNET_LIB_TARGET} - ${CC} ${PFLAGS} ${OBJS} ${LFLAGS} -o $@ - size $@ - cp $@ ../../bin - -lib: ${BACNET_LIB_TARGET} - -${BACNET_LIB_TARGET}: - ( cd ${BACNET_LIB_DIR} ; $(MAKE) clean ; $(MAKE) ) - -.c.o: - ${CC} -c ${CFLAGS} $*.c -o $@ - -depend: - rm -f .depend - ${CC} -MM ${CFLAGS} *.c >> .depend - -clean: - rm -f core ${TARGET_BIN} ${OBJS} ${BACNET_LIB_TARGET} $(TARGET).map - -include: .depend diff --git a/demo/gateway/makefile.b32 b/demo/gateway/makefile.b32 deleted file mode 100644 index 47644066..00000000 --- a/demo/gateway/makefile.b32 +++ /dev/null @@ -1,148 +0,0 @@ -# -# Simple makefile to build an executable for Win32 -# -# This makefile assumes Borland bcc32 development environment -# on Windows NT/9x/2000/XP -# - -!ifndef BORLAND_DIR -BORLAND_DIR_Not_Defined: - @echo . - @echo You must define environment variable BORLAND_DIR to compile. -!endif - -# target -PRODUCT = bacgateway -PRODUCT_EXE = $(PRODUCT).exe - -# tools -CC = $(BORLAND_DIR)\bin\bcc32 -MAKE=$(BORLAND_DIR)\bin\make.exe -#LINK = $(BORLAND_DIR)\bin\tlink32 -LINK = $(BORLAND_DIR)\bin\ilink32 - -BACNET_LIB_DIR = ..\..\lib -BACNET_LIB = $(BACNET_LIB_DIR)\bacnet.lib -# getting back from the library -BACNET_DEMO_DIR = ..\demo\gateway - -# directories -BACNET_PORT = ..\..\ports\win32 -BACNET_INCLUDE = ..\..\include -BACNET_OBJECT = ..\object -BACNET_HANDLER = ..\handler -INCLUDES = \ - -I$(BACNET_INCLUDE) \ - -I$(BACNET_PORT) \ - -I$(BACNET_OBJECT) \ - -I$(BACNET_HANDLER) \ - -I$(BORLAND_DIR)\include - -# -BACNET_DEFINES = -DPRINT_ENABLED=1 -DBACFILE -DBACAPP_ALL -#BACDL_DEFINE=-DBACDL_MSTP -DCRC_USE_TABLE -BACDL_DEFINE=-DBACDL_BIP=1 -DUSE_INADDR=1 -DEFINES = $(BACNET_DEFINES) $(BACDL_DEFINE) - -SRCS = main.c device.c - -OBJS = $(SRCS:.c=.obj) - -# -# Compiler definitions -# -BCC_CFG = bcc32.cfg - -# -# Include directories -# -CFLAGS = $(INCLUDES) $(DEFINES) - -# -# Libraries -# -C_LIB_DIR = $(BORLAND_DIR)\lib - -LIBS = $(BACNET_LIB) \ - $(C_LIB_DIR)\IMPORT32.lib \ - $(C_LIB_DIR)\CW32MT.lib \ - -# -# Main target -# -# This should be the first one in the makefile - -all : $(BACNET_LIB) $(BCC_CFG) $(OBJS) $(PRODUCT_EXE) - del $(BCC_CFG) - -install: $(PRODUCT_EXE) - copy $(PRODUCT_EXE) ..\..\bin\$(PRODUCT_EXE) - -$(BACNET_LIB): - cd $(BACNET_LIB_DIR) - $(MAKE) -i -f makefile.b32 clean - $(MAKE) -f makefile.b32 all - cd $(BACNET_DEMO_DIR) - -# Linker specific: the link below is for BCC linker/compiler. If you link -# with a different linker - please change accordingly. -# - -# need a temp response file (@&&| ... |) because command line is too long -# $** lists each dependency -# $< target name -# $* target name without extension -$(PRODUCT_EXE) : $(OBJS) - @echo Running Linker for $(PRODUCT_EXE) - $(LINK) -L$(C_LIB_DIR) -L$(BACNET_LIB_DIR) -m -c -s -v @&&| - $(BORLAND_DIR)\lib\c0x32.obj $** - $< - $*.map - $(LIBS) -| - -# -# Utilities - -clean : - del $(OBJS) - del $(PRODUCT_EXE) - del $(PRODUCT).map - del $(PRODUCT).ilc - del $(PRODUCT).ild - del $(PRODUCT).ilf - del $(PRODUCT).ils - del $(PRODUCT).tds - del $(BCC_CFG) - -# -# Generic rules -# -.SUFFIXES: .cpp .c .sbr .obj - -# -# cc generic rule -# -.c.obj: - $(CC) +$(BCC_CFG) -o$@ $< - -# Compiler configuration file -$(BCC_CFG) : - Copy &&| - $(CFLAGS) - -c - -y #include line numbers in OBJ's - -v #include debug info - -w+ #turn on all warnings - #-Od #disable all optimizations - -O2 #disable all optimizations - -WM #multithread - #-WM- #not multithread - -w-aus # ignore warning assigned a value that is never used - -w-sig # ignore warning conversion may lose sig digits - #-a4 #32 bit data alignment - #-M # generate link map - #-ls # linker options -| $@ - -# EOF: makefile diff --git a/demo/getevent/Makefile b/demo/getevent/Makefile deleted file mode 100644 index a85a4638..00000000 --- a/demo/getevent/Makefile +++ /dev/null @@ -1,45 +0,0 @@ -#Makefile to build BACnet Application using GCC compiler - -# tools - only if you need them. -# Most platforms have this already defined -# CC = gcc -# AR = ar -# MAKE = make -# SIZE = size -# -# Assumes rm and cp are available - -# Executable file name -TARGET = bacge - -TARGET_BIN = ${TARGET}$(TARGET_EXT) - -SRCS = main.c \ - ../object/netport.c \ - ../object/device-client.c - -OBJS = ${SRCS:.c=.o} - -all: ${BACNET_LIB_TARGET} Makefile ${TARGET_BIN} - -${TARGET_BIN}: ${OBJS} Makefile ${BACNET_LIB_TARGET} - ${CC} ${PFLAGS} ${OBJS} ${LFLAGS} -o $@ - size $@ - cp $@ ../../bin - -lib: ${BACNET_LIB_TARGET} - -${BACNET_LIB_TARGET}: - ( cd ${BACNET_LIB_DIR} ; $(MAKE) clean ; $(MAKE) ) - -.c.o: - ${CC} -c ${CFLAGS} $*.c -o $@ - -depend: - rm -f .depend - ${CC} -MM ${CFLAGS} *.c >> .depend - -clean: - rm -rf core ${TARGET_BIN} ${OBJS} ${BACNET_LIB_TARGET} - -include: .depend diff --git a/demo/handler/s_ptransfer.c b/demo/handler/s_ptransfer.c deleted file mode 100644 index c96c1e13..00000000 --- a/demo/handler/s_ptransfer.c +++ /dev/null @@ -1,146 +0,0 @@ -/************************************************************************** - * - * Copyright (C) 2006 Steve Karg - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - *********************************************************************/ -#include -#include -#include -#include -#include -#include "config.h" -#include "txbuf.h" -#include "bacdef.h" -#include "bacdcode.h" -#include "address.h" -#include "tsm.h" -#include "npdu.h" -#include "apdu.h" -#include "device.h" -#include "datalink.h" -#include "dcc.h" -#include "ptransfer.h" -/* some demo stuff needed */ -#include "handlers.h" -#include "txbuf.h" -#include "mydata.h" -#include "client.h" - -/** @file s_ptransfer.c Send a Private Transfer request. */ - -/* This function is exported. Hence this unnecessary prototype. */ -uint8_t Send_Private_Transfer_Request(uint32_t device_id, uint16_t vendor_id, - uint32_t service_number, - char block_number, DATABLOCK *block); - -uint8_t Send_Private_Transfer_Request(uint32_t device_id, uint16_t vendor_id, - uint32_t service_number, - char block_number, DATABLOCK *block) -{ /* NULL=optional */ - BACNET_ADDRESS dest; - BACNET_ADDRESS my_address; - unsigned max_apdu = 0; - uint8_t invoke_id = 0; - bool status = false; - int len = 0; - int pdu_len = 0; - int bytes_sent = 0; - BACNET_NPDU_DATA npdu_data; - static uint8_t - pt_req_buffer[300]; /* Somewhere to build the request packet */ - BACNET_PRIVATE_TRANSFER_DATA pt_block; - BACNET_CHARACTER_STRING bsTemp; - - /* if we are forbidden to send, don't send! */ - if (!dcc_communication_enabled()) - return 0; - - /* is the device bound? */ - status = address_get_by_device(device_id, &max_apdu, &dest); - /* is there a tsm available? */ - if (status) - invoke_id = tsm_next_free_invokeID(); - if (invoke_id) { - /* encode the NPDU portion of the packet */ - datalink_get_my_address(&my_address); - npdu_encode_npdu_data(&npdu_data, true, MESSAGE_PRIORITY_NORMAL); - pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest, - &my_address, &npdu_data); - /* encode the APDU portion of the packet */ - - pt_block.vendorID = vendor_id; - pt_block.serviceNumber = service_number; - if (service_number == MY_SVC_READ) { - len += encode_application_unsigned( - &pt_req_buffer[len], - block_number); /* The block number we want to retrieve */ - } else { - len += encode_application_unsigned( - &pt_req_buffer[len], block_number); /* The block number */ - len += encode_application_unsigned( - &pt_req_buffer[len], - block->cMyByte1); /* And Then the block contents */ - len += encode_application_unsigned(&pt_req_buffer[len], - block->cMyByte2); - len += encode_application_real(&pt_req_buffer[len], block->fMyReal); - characterstring_init_ansi(&bsTemp, (char *)block->sMyString); - len += encode_application_character_string(&pt_req_buffer[len], - &bsTemp); - } - - pt_block.serviceParameters = &pt_req_buffer[0]; - pt_block.serviceParametersLen = len; - len = ptransfer_encode_apdu(&Handler_Transmit_Buffer[pdu_len], - invoke_id, &pt_block); - pdu_len += len; - - /* will it fit in the sender? - note: if there is a bottleneck router in between - us and the destination, we won't know unless - we have a way to check for that and update the - max_apdu in the address binding table. */ - - if ((unsigned)pdu_len < max_apdu) { - tsm_set_confirmed_unsegmented_transaction( - invoke_id, &dest, &npdu_data, &Handler_Transmit_Buffer[0], - (uint16_t)pdu_len); - bytes_sent = datalink_send_pdu( - &dest, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len); -#if PRINT_ENABLED - if (bytes_sent <= 0) - fprintf(stderr, - "Failed to Send Private Transfer Request (%s)!\n", - strerror(errno)); -#endif - } else { - tsm_free_invoke_id(invoke_id); - invoke_id = 0; -#if PRINT_ENABLED - fprintf(stderr, - "Failed to Send Private Transfer Request " - "(exceeds destination maximum APDU)!\n"); -#endif - } - } - - return invoke_id; -} diff --git a/demo/handler/txbuf.c b/demo/handler/txbuf.c deleted file mode 100644 index 7d36eed3..00000000 --- a/demo/handler/txbuf.c +++ /dev/null @@ -1,32 +0,0 @@ -/************************************************************************** - * - * Copyright (C) 2005 Steve Karg - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - *********************************************************************/ -#include -#include -#include "config.h" -#include "datalink.h" - -/** @file txbuf.c Declare the global Transmit Buffer for handler functions. */ - -uint8_t Handler_Transmit_Buffer[MAX_PDU] = {0}; diff --git a/demo/iam/Makefile b/demo/iam/Makefile deleted file mode 100644 index 45d37514..00000000 --- a/demo/iam/Makefile +++ /dev/null @@ -1,39 +0,0 @@ -#Makefile to build BACnet Application for the Linux Port - -# tools - only if you need them. -# Most platforms have this already defined -# CC = gcc - -TARGET = baciam - -TARGET_BIN = ${TARGET}$(TARGET_EXT) - -SRCS = main.c \ - ../object/netport.c \ - ../object/device-client.c - -OBJS = ${SRCS:.c=.o} - -all: ${BACNET_LIB_TARGET} Makefile ${TARGET_BIN} - -${TARGET_BIN}: ${OBJS} Makefile ${BACNET_LIB_TARGET} - ${CC} ${PFLAGS} ${OBJS} ${LFLAGS} -o $@ - size $@ - cp $@ ../../bin - -lib: ${BACNET_LIB_TARGET} - -${BACNET_LIB_TARGET}: - ( cd ${BACNET_LIB_DIR} ; $(MAKE) clean ; $(MAKE) ) - -.c.o: - ${CC} -c ${CFLAGS} $*.c -o $@ - -depend: - rm -f .depend - ${CC} -MM ${CFLAGS} *.c >> .depend - -clean: - rm -f core ${TARGET_BIN} ${OBJS} ${BACNET_LIB_TARGET} $(TARGET).map - -include: .depend diff --git a/demo/iam/makefile.b32 b/demo/iam/makefile.b32 deleted file mode 100644 index 22fb517b..00000000 --- a/demo/iam/makefile.b32 +++ /dev/null @@ -1,140 +0,0 @@ -# -# Simple makefile to build an executable for Win32 -# -# This makefile assumes Borland bcc32 development environment -# on Windows NT/9x/2000/XP -# - -!ifndef BORLAND_DIR -BORLAND_DIR_Not_Defined: - @echo . - @echo You must define environment variable BORLAND_DIR to compile. -!endif - -# target -PRODUCT = baciam -PRODUCT_EXE = $(PRODUCT).exe - -# tools -CC = $(BORLAND_DIR)\bin\bcc32 -MAKE=$(BORLAND_DIR)\bin\make.exe -#LINK = $(BORLAND_DIR)\bin\tlink32 -LINK = $(BORLAND_DIR)\bin\ilink32 - -BACNET_LIB_DIR = ..\..\lib -BACNET_LIB = $(BACNET_LIB_DIR)\bacnet.lib - -# directories -BACNET_PORT = ..\..\ports\win32 -BACNET_INCLUDE = ..\..\include -BACNET_OBJECT = ..\object -BACNET_HANDLER = ..\handler -INCLUDES = \ - -I$(BACNET_INCLUDE) \ - -I$(BACNET_PORT) \ - -I$(BACNET_OBJECT) \ - -I$(BACNET_HANDLER) \ - -I$(BORLAND_DIR)\include - -# -BACNET_DEFINES = -DPRINT_ENABLED=1 -DBACAPP_ALL -#BACDL_DEFINE=-DBACDL_MSTP=1 -BACDL_DEFINE=-DBACDL_BIP=1 -DUSE_INADDR=1 -DEFINES = $(BACNET_DEFINES) $(BACDL_DEFINE) - -SRCS = main.c \ - $(BACNET_OBJECT)\device-client.c - -OBJS = $(SRCS:.c=.obj) - -# -# Compiler definitions -# -BCC_CFG = bcc32.cfg - -# -# Include directories -# -CFLAGS = $(INCLUDES) $(DEFINES) - -# -# Libraries -# -C_LIB_DIR = $(BORLAND_DIR)\lib - -LIBS = $(BACNET_LIB) \ - $(C_LIB_DIR)\IMPORT32.lib \ - $(C_LIB_DIR)\CW32MT.lib \ - -# -# Main target -# -# This should be the first one in the makefile - -all : $(BACNET_LIB) $(BCC_CFG) $(OBJS) $(PRODUCT_EXE) - del $(BCC_CFG) - -install: $(PRODUCT_EXE) - copy $(PRODUCT_EXE) ..\..\bin\$(PRODUCT_EXE) - -# Linker specific: the link below is for BCC linker/compiler. If you link -# with a different linker - please change accordingly. -# - -# need a temp response file (@&&| ... |) because command line is too long -# $** lists each dependency -# $< target name -# $* target name without extension -$(PRODUCT_EXE) : $(OBJS) - @echo Running Linker for $(PRODUCT_EXE) - $(LINK) -L$(C_LIB_DIR) -L$(BACNET_LIB_DIR) -m -c -s -v @&&| - $(BORLAND_DIR)\lib\c0x32.obj $** - $< - $*.map - $(LIBS) -| - -# -# Utilities - -clean : - del $(OBJS) - del $(PRODUCT_EXE) - del $(PRODUCT).map - del $(PRODUCT).ilc - del $(PRODUCT).ild - del $(PRODUCT).ilf - del $(PRODUCT).ils - del $(PRODUCT).tds - del $(BCC_CFG) - -# -# Generic rules -# -.SUFFIXES: .cpp .c .sbr .obj - -# -# cc generic rule -# -.c.obj: - $(CC) +$(BCC_CFG) -o$@ $< - -# Compiler configuration file -$(BCC_CFG) : - Copy &&| - $(CFLAGS) - -c - -y #include line numbers in OBJ's - -v #include debug info - -w+ #turn on all warnings - -Od #disable all optimizations - #-a4 #32 bit data alignment - #-M # generate link map - #-ls # linker options - #-WM- #not multithread - -WM #multithread - -w-aus # ignore warning assigned a value that is never used - -w-sig # ignore warning conversion may lose sig digits -| $@ - -# EOF: makefile diff --git a/demo/iamrouter/Makefile b/demo/iamrouter/Makefile deleted file mode 100644 index a73a1f45..00000000 --- a/demo/iamrouter/Makefile +++ /dev/null @@ -1,39 +0,0 @@ -#Makefile to build BACnet Application for the Linux Port - -# tools - only if you need them. -# Most platforms have this already defined -# CC = gcc - -TARGET = baciamr - -TARGET_BIN = ${TARGET}$(TARGET_EXT) - -SRCS = main.c \ - ../object/netport.c \ - ../object/device-client.c - -OBJS = ${SRCS:.c=.o} - -all: ${BACNET_LIB_TARGET} Makefile ${TARGET_BIN} - -${TARGET_BIN}: ${OBJS} Makefile ${BACNET_LIB_TARGET} - ${CC} ${PFLAGS} ${OBJS} ${LFLAGS} -o $@ - size $@ - cp $@ ../../bin - -lib: ${BACNET_LIB_TARGET} - -${BACNET_LIB_TARGET}: - ( cd ${BACNET_LIB_DIR} ; $(MAKE) clean ; $(MAKE) ) - -.c.o: - ${CC} -c ${CFLAGS} $*.c -o $@ - -depend: - rm -f .depend - ${CC} -MM ${CFLAGS} *.c >> .depend - -clean: - rm -f core ${TARGET_BIN} ${OBJS} ${BACNET_LIB_TARGET} $(TARGET).map - -include: .depend diff --git a/demo/iamrouter/makefile.b32 b/demo/iamrouter/makefile.b32 deleted file mode 100644 index 72cc4b15..00000000 --- a/demo/iamrouter/makefile.b32 +++ /dev/null @@ -1,140 +0,0 @@ -# -# Simple makefile to build an executable for Win32 -# -# This makefile assumes Borland bcc32 development environment -# on Windows NT/9x/2000/XP -# - -!ifndef BORLAND_DIR -BORLAND_DIR_Not_Defined: - @echo . - @echo You must define environment variable BORLAND_DIR to compile. -!endif - -# target -PRODUCT = baciamr -PRODUCT_EXE = $(PRODUCT).exe - -# tools -CC = $(BORLAND_DIR)\bin\bcc32 -MAKE=$(BORLAND_DIR)\bin\make.exe -#LINK = $(BORLAND_DIR)\bin\tlink32 -LINK = $(BORLAND_DIR)\bin\ilink32 - -BACNET_LIB_DIR = ..\..\lib -BACNET_LIB = $(BACNET_LIB_DIR)\bacnet.lib - -# directories -BACNET_PORT = ..\..\ports\win32 -BACNET_INCLUDE = ..\..\include -BACNET_OBJECT = ..\object -BACNET_HANDLER = ..\handler -INCLUDES = \ - -I$(BACNET_INCLUDE) \ - -I$(BACNET_PORT) \ - -I$(BACNET_OBJECT) \ - -I$(BACNET_HANDLER) \ - -I$(BORLAND_DIR)\include - -# -BACNET_DEFINES = -DPRINT_ENABLED=1 -DBACAPP_ALL -#BACDL_DEFINE=-DBACDL_MSTP=1 -BACDL_DEFINE=-DBACDL_BIP=1 -DUSE_INADDR=1 -DEFINES = $(BACNET_DEFINES) $(BACDL_DEFINE) - -SRCS = main.c \ - $(BACNET_OBJECT)\device-client.c - -OBJS = $(SRCS:.c=.obj) - -# -# Compiler definitions -# -BCC_CFG = bcc32.cfg - -# -# Include directories -# -CFLAGS = $(INCLUDES) $(DEFINES) - -# -# Libraries -# -C_LIB_DIR = $(BORLAND_DIR)\lib - -LIBS = $(BACNET_LIB) \ - $(C_LIB_DIR)\IMPORT32.lib \ - $(C_LIB_DIR)\CW32MT.lib \ - -# -# Main target -# -# This should be the first one in the makefile - -all : $(BACNET_LIB) $(BCC_CFG) $(OBJS) $(PRODUCT_EXE) - del $(BCC_CFG) - -install: $(PRODUCT_EXE) - copy $(PRODUCT_EXE) ..\..\bin\$(PRODUCT_EXE) - -# Linker specific: the link below is for BCC linker/compiler. If you link -# with a different linker - please change accordingly. -# - -# need a temp response file (@&&| ... |) because command line is too long -# $** lists each dependency -# $< target name -# $* target name without extension -$(PRODUCT_EXE) : $(OBJS) - @echo Running Linker for $(PRODUCT_EXE) - $(LINK) -L$(C_LIB_DIR) -L$(BACNET_LIB_DIR) -m -c -s -v @&&| - $(BORLAND_DIR)\lib\c0x32.obj $** - $< - $*.map - $(LIBS) -| - -# -# Utilities - -clean : - del $(OBJS) - del $(PRODUCT_EXE) - del $(PRODUCT).map - del $(PRODUCT).ilc - del $(PRODUCT).ild - del $(PRODUCT).ilf - del $(PRODUCT).ils - del $(PRODUCT).tds - del $(BCC_CFG) - -# -# Generic rules -# -.SUFFIXES: .cpp .c .sbr .obj - -# -# cc generic rule -# -.c.obj: - $(CC) +$(BCC_CFG) -o$@ $< - -# Compiler configuration file -$(BCC_CFG) : - Copy &&| - $(CFLAGS) - -c - -y #include line numbers in OBJ's - -v #include debug info - -w+ #turn on all warnings - -Od #disable all optimizations - #-a4 #32 bit data alignment - #-M # generate link map - #-ls # linker options - #-WM- #not multithread - -WM #multithread - -w-aus # ignore warning assigned a value that is never used - -w-sig # ignore warning conversion may lose sig digits -| $@ - -# EOF: makefile diff --git a/demo/initrouter/Makefile b/demo/initrouter/Makefile deleted file mode 100644 index 0046787d..00000000 --- a/demo/initrouter/Makefile +++ /dev/null @@ -1,39 +0,0 @@ -#Makefile to build BACnet Application for the Linux Port - -# tools - only if you need them. -# Most platforms have this already defined -# CC = gcc - -TARGET = bacinitr - -TARGET_BIN = ${TARGET}$(TARGET_EXT) - -SRCS = main.c \ - ../object/netport.c \ - ../object/device-client.c - -OBJS = ${SRCS:.c=.o} - -all: ${BACNET_LIB_TARGET} Makefile ${TARGET_BIN} - -${TARGET_BIN}: ${OBJS} Makefile ${BACNET_LIB_TARGET} - ${CC} ${PFLAGS} ${OBJS} ${LFLAGS} -o $@ - size $@ - cp $@ ../../bin - -lib: ${BACNET_LIB_TARGET} - -${BACNET_LIB_TARGET}: - ( cd ${BACNET_LIB_DIR} ; $(MAKE) clean ; $(MAKE) ) - -.c.o: - ${CC} -c ${CFLAGS} $*.c -o $@ - -depend: - rm -f .depend - ${CC} -MM ${CFLAGS} *.c >> .depend - -clean: - rm -f core ${TARGET_BIN} ${OBJS} ${BACNET_LIB_TARGET} $(TARGET).map - -include: .depend diff --git a/demo/initrouter/makefile.b32 b/demo/initrouter/makefile.b32 deleted file mode 100644 index 8c7b7871..00000000 --- a/demo/initrouter/makefile.b32 +++ /dev/null @@ -1,140 +0,0 @@ -# -# Simple makefile to build an executable for Win32 -# -# This makefile assumes Borland bcc32 development environment -# on Windows NT/9x/2000/XP -# - -!ifndef BORLAND_DIR -BORLAND_DIR_Not_Defined: - @echo . - @echo You must define environment variable BORLAND_DIR to compile. -!endif - -# target -PRODUCT = bacinitr -PRODUCT_EXE = $(PRODUCT).exe - -# tools -CC = $(BORLAND_DIR)\bin\bcc32 -MAKE=$(BORLAND_DIR)\bin\make.exe -#LINK = $(BORLAND_DIR)\bin\tlink32 -LINK = $(BORLAND_DIR)\bin\ilink32 - -BACNET_LIB_DIR = ..\..\lib -BACNET_LIB = $(BACNET_LIB_DIR)\bacnet.lib - -# directories -BACNET_PORT = ..\..\ports\win32 -BACNET_INCLUDE = ..\..\include -BACNET_OBJECT = ..\object -BACNET_HANDLER = ..\handler -INCLUDES = \ - -I$(BACNET_INCLUDE) \ - -I$(BACNET_PORT) \ - -I$(BACNET_OBJECT) \ - -I$(BACNET_HANDLER) \ - -I$(BORLAND_DIR)\include - -# -BACNET_DEFINES = -DPRINT_ENABLED=1 -DBACAPP_ALL -#BACDL_DEFINE=-DBACDL_MSTP=1 -BACDL_DEFINE=-DBACDL_BIP=1 -DUSE_INADDR=1 -DEFINES = $(BACNET_DEFINES) $(BACDL_DEFINE) - -SRCS = main.c \ - $(BACNET_OBJECT)\device-client.c - -OBJS = $(SRCS:.c=.obj) - -# -# Compiler definitions -# -BCC_CFG = bcc32.cfg - -# -# Include directories -# -CFLAGS = $(INCLUDES) $(DEFINES) - -# -# Libraries -# -C_LIB_DIR = $(BORLAND_DIR)\lib - -LIBS = $(BACNET_LIB) \ - $(C_LIB_DIR)\IMPORT32.lib \ - $(C_LIB_DIR)\CW32MT.lib \ - -# -# Main target -# -# This should be the first one in the makefile - -all : $(BACNET_LIB) $(BCC_CFG) $(OBJS) $(PRODUCT_EXE) - del $(BCC_CFG) - -install: $(PRODUCT_EXE) - copy $(PRODUCT_EXE) ..\..\bin\$(PRODUCT_EXE) - -# Linker specific: the link below is for BCC linker/compiler. If you link -# with a different linker - please change accordingly. -# - -# need a temp response file (@&&| ... |) because command line is too long -# $** lists each dependency -# $< target name -# $* target name without extension -$(PRODUCT_EXE) : $(OBJS) - @echo Running Linker for $(PRODUCT_EXE) - $(LINK) -L$(C_LIB_DIR) -L$(BACNET_LIB_DIR) -m -c -s -v @&&| - $(BORLAND_DIR)\lib\c0x32.obj $** - $< - $*.map - $(LIBS) -| - -# -# Utilities - -clean : - del $(OBJS) - del $(PRODUCT_EXE) - del $(PRODUCT).map - del $(PRODUCT).ilc - del $(PRODUCT).ild - del $(PRODUCT).ilf - del $(PRODUCT).ils - del $(PRODUCT).tds - del $(BCC_CFG) - -# -# Generic rules -# -.SUFFIXES: .cpp .c .sbr .obj - -# -# cc generic rule -# -.c.obj: - $(CC) +$(BCC_CFG) -o$@ $< - -# Compiler configuration file -$(BCC_CFG) : - Copy &&| - $(CFLAGS) - -c - -y #include line numbers in OBJ's - -v #include debug info - -w+ #turn on all warnings - -Od #disable all optimizations - #-a4 #32 bit data alignment - #-M # generate link map - #-ls # linker options - #-WM- #not multithread - -WM #multithread - -w-aus # ignore warning assigned a value that is never used - -w-sig # ignore warning conversion may lose sig digits -| $@ - -# EOF: makefile diff --git a/demo/mstpcap/Makefile b/demo/mstpcap/Makefile deleted file mode 100644 index 49904934..00000000 --- a/demo/mstpcap/Makefile +++ /dev/null @@ -1,48 +0,0 @@ -#Makefile to build BACnet Application for the Linux Port - -# tools - only if you need them. -# Most platforms have this already defined -# CC = gcc - -# Executable file name -TARGET = mstpcap - -TARGET_BIN = ${TARGET}$(TARGET_EXT) - -# This demo seems to be a little unique -DEFINES = $(BACNET_DEFINES) -DBACDL_MSTP -BACNET_SOURCE_DIR = ../../src - -SRCS = main.c \ - ${BACNET_PORT_DIR}/rs485.c \ - ${BACNET_PORT_DIR}/timer.c \ - ${BACNET_SOURCE_DIR}/fifo.c \ - ${BACNET_SOURCE_DIR}/mstp.c \ - ${BACNET_SOURCE_DIR}/mstptext.c \ - ${BACNET_SOURCE_DIR}/debug.c \ - ${BACNET_SOURCE_DIR}/indtext.c \ - ${BACNET_SOURCE_DIR}/ringbuf.c \ - ${BACNET_SOURCE_DIR}/bacdcode.c \ - ${BACNET_SOURCE_DIR}/iam.c \ - ${BACNET_SOURCE_DIR}/crc.c - -OBJS = ${SRCS:.c=.o} - -all: Makefile ${TARGET_BIN} - -${TARGET_BIN}: ${OBJS} Makefile - ${CC} ${PFLAGS} ${OBJS} ${LFLAGS} -o $@ - size $@ - cp $@ ../../bin - -.c.o: - ${CC} -c ${CFLAGS} $*.c -o $@ - -depend: - rm -f .depend - ${CC} -MM ${CFLAGS} *.c >> .depend - -clean: - rm -f core ${TARGET_BIN} ${OBJS} $(TARGET).map - -include: .depend diff --git a/demo/mstpcap/makefile.b32 b/demo/mstpcap/makefile.b32 deleted file mode 100644 index a027da25..00000000 --- a/demo/mstpcap/makefile.b32 +++ /dev/null @@ -1,139 +0,0 @@ -# -# Simple makefile to build an executable for Win32 -# -# This makefile assumes Borland bcc32 development environment -# on Windows NT/9x/2000/XP -# - -!ifndef BORLAND_DIR -BORLAND_DIR_Not_Defined: - @echo . - @echo You must define environment variable BORLAND_DIR to compile. -!endif - -# target -PRODUCT = mstpcap -PRODUCT_EXE = $(PRODUCT).exe - -# tools -CC = $(BORLAND_DIR)\bin\bcc32 -MAKE=$(BORLAND_DIR)\bin\make.exe -#LINK = $(BORLAND_DIR)\bin\tlink32 -LINK = $(BORLAND_DIR)\bin\ilink32 - -BACNET_LIB_DIR = ..\..\lib -BACNET_LIB = $(BACNET_LIB_DIR)\bacnet.lib - -# directories -BACNET_PORT = ..\..\ports\win32 -BACNET_INCLUDE = ..\..\include -BACNET_OBJECT = ..\object -BACNET_HANDLER = ..\handler -INCLUDES = \ - -I$(BACNET_INCLUDE) \ - -I$(BACNET_PORT) \ - -I$(BACNET_OBJECT) \ - -I$(BACNET_HANDLER) \ - -I$(BORLAND_DIR)\include - -# -BACNET_DEFINES = -DPRINT_ENABLED=1 -DBACAPP_ALL -#BACDL_DEFINE=-DBACDL_MSTP=1 -BACDL_DEFINE=-DBACDL_BIP=1 -DUSE_INADDR=1 -DEFINES = $(BACNET_DEFINES) $(BACDL_DEFINE) - -SRCS = main.c \ - -OBJS = $(SRCS:.c=.obj) - -# -# Compiler definitions -# -BCC_CFG = bcc32.cfg - -# -# Include directories -# -CFLAGS = $(INCLUDES) $(DEFINES) - -# -# Libraries -# -C_LIB_DIR = $(BORLAND_DIR)\lib - -LIBS = $(BACNET_LIB) \ - $(C_LIB_DIR)\IMPORT32.lib \ - $(C_LIB_DIR)\CW32MT.lib \ - -# -# Main target -# -# This should be the first one in the makefile - -all : $(BACNET_LIB) $(BCC_CFG) $(OBJS) $(PRODUCT_EXE) - del $(BCC_CFG) - -install: $(PRODUCT_EXE) - copy $(PRODUCT_EXE) ..\..\bin\$(PRODUCT_EXE) - -# Linker specific: the link below is for BCC linker/compiler. If you link -# with a different linker - please change accordingly. -# - -# need a temp response file (@&&| ... |) because command line is too long -# $** lists each dependency -# $< target name -# $* target name without extension -$(PRODUCT_EXE) : $(OBJS) - @echo Running Linker for $(PRODUCT_EXE) - $(LINK) -L$(C_LIB_DIR) -L$(BACNET_LIB_DIR) -m -c -s -v @&&| - $(BORLAND_DIR)\lib\c0x32.obj $** - $< - $*.map - $(LIBS) -| - -# -# Utilities - -clean : - del $(OBJS) - del $(PRODUCT_EXE) - del $(PRODUCT).map - del $(PRODUCT).ilc - del $(PRODUCT).ild - del $(PRODUCT).ilf - del $(PRODUCT).ils - del $(PRODUCT).tds - del $(BCC_CFG) - -# -# Generic rules -# -.SUFFIXES: .cpp .c .sbr .obj - -# -# cc generic rule -# -.c.obj: - $(CC) +$(BCC_CFG) -o$@ $< - -# Compiler configuration file -$(BCC_CFG) : - Copy &&| - $(CFLAGS) - -c - -y #include line numbers in OBJ's - -v #include debug info - -w+ #turn on all warnings - -Od #disable all optimizations - #-a4 #32 bit data alignment - #-M # generate link map - #-ls # linker options - #-WM- #not multithread - -WM #multithread - -w-aus # ignore warning assigned a value that is never used - -w-sig # ignore warning conversion may lose sig digits -| $@ - -# EOF: makefile diff --git a/demo/mstpcrc/Makefile b/demo/mstpcrc/Makefile deleted file mode 100644 index 05e00114..00000000 --- a/demo/mstpcrc/Makefile +++ /dev/null @@ -1,53 +0,0 @@ -#Makefile to build BACnet Application for the Linux Port - -# tools - only if you need them. -# Most platforms have this already defined -# CC = gcc - -# Executable file name -TARGET = mstpcrc - -TARGET_BIN = ${TARGET}$(TARGET_EXT) - -# This demo seems to be a little unique -DEFINES = $(BACNET_DEFINES) -BACNET_SOURCE_DIR = ../../src - -#libraries used -LIBRARIES=-lgcc,-lm - -#build for release (default) or debug -DEBUGGING = -OPTIMIZATION = -Os -ifeq (${BUILD},debug) -OPTIMIZATION = -O0 -DEBUGGING = -g -endif - -# search order for included libraries -INCLUDES = -I$(BACNET_INCLUDE_DIR) - -SRCS = main.c \ - ${BACNET_PORT_DIR}/timer.c \ - ${BACNET_SOURCE_DIR}/crc.c - -OBJS = ${SRCS:.c=.o} - -all: Makefile ${TARGET_BIN} - -${TARGET_BIN}: ${OBJS} Makefile - ${CC} ${PFLAGS} ${OBJS} ${LFLAGS} -o $@ - size $@ - cp $@ ../../bin - -.c.o: - ${CC} -c ${CFLAGS} $*.c -o $@ - -depend: - rm -f .depend - ${CC} -MM ${CFLAGS} *.c >> .depend - -clean: - rm -f core ${TARGET_BIN} ${OBJS} $(TARGET).map - -include: .depend diff --git a/demo/mstpcrc/makefile.b32 b/demo/mstpcrc/makefile.b32 deleted file mode 100644 index b80c1b1b..00000000 --- a/demo/mstpcrc/makefile.b32 +++ /dev/null @@ -1,139 +0,0 @@ -# -# Simple makefile to build an executable for Win32 -# -# This makefile assumes Borland bcc32 development environment -# on Windows NT/9x/2000/XP -# - -!ifndef BORLAND_DIR -BORLAND_DIR_Not_Defined: - @echo . - @echo You must define environment variable BORLAND_DIR to compile. -!endif - -# target -PRODUCT = mstpcrc -PRODUCT_EXE = $(PRODUCT).exe - -# tools -CC = $(BORLAND_DIR)\bin\bcc32 -MAKE=$(BORLAND_DIR)\bin\make.exe -#LINK = $(BORLAND_DIR)\bin\tlink32 -LINK = $(BORLAND_DIR)\bin\ilink32 - -BACNET_LIB_DIR = ..\..\lib -BACNET_LIB = $(BACNET_LIB_DIR)\bacnet.lib - -# directories -BACNET_PORT = ..\..\ports\win32 -BACNET_INCLUDE = ..\..\include -BACNET_OBJECT = ..\object -BACNET_HANDLER = ..\handler -INCLUDES = \ - -I$(BACNET_INCLUDE) \ - -I$(BACNET_PORT) \ - -I$(BACNET_OBJECT) \ - -I$(BACNET_HANDLER) \ - -I$(BORLAND_DIR)\include - -# -BACNET_DEFINES = -DPRINT_ENABLED=1 -DBACAPP_ALL -#BACDL_DEFINE=-DBACDL_MSTP=1 -BACDL_DEFINE=-DBACDL_BIP=1 -DUSE_INADDR=1 -DEFINES = $(BACNET_DEFINES) $(BACDL_DEFINE) - -SRCS = main.c \ - -OBJS = $(SRCS:.c=.obj) - -# -# Compiler definitions -# -BCC_CFG = bcc32.cfg - -# -# Include directories -# -CFLAGS = $(INCLUDES) $(DEFINES) - -# -# Libraries -# -C_LIB_DIR = $(BORLAND_DIR)\lib - -LIBS = $(BACNET_LIB) \ - $(C_LIB_DIR)\IMPORT32.lib \ - $(C_LIB_DIR)\CW32MT.lib \ - -# -# Main target -# -# This should be the first one in the makefile - -all : $(BACNET_LIB) $(BCC_CFG) $(OBJS) $(PRODUCT_EXE) - del $(BCC_CFG) - -install: $(PRODUCT_EXE) - copy $(PRODUCT_EXE) ..\..\bin\$(PRODUCT_EXE) - -# Linker specific: the link below is for BCC linker/compiler. If you link -# with a different linker - please change accordingly. -# - -# need a temp response file (@&&| ... |) because command line is too long -# $** lists each dependency -# $< target name -# $* target name without extension -$(PRODUCT_EXE) : $(OBJS) - @echo Running Linker for $(PRODUCT_EXE) - $(LINK) -L$(C_LIB_DIR) -L$(BACNET_LIB_DIR) -m -c -s -v @&&| - $(BORLAND_DIR)\lib\c0x32.obj $** - $< - $*.map - $(LIBS) -| - -# -# Utilities - -clean : - del $(OBJS) - del $(PRODUCT_EXE) - del $(PRODUCT).map - del $(PRODUCT).ilc - del $(PRODUCT).ild - del $(PRODUCT).ilf - del $(PRODUCT).ils - del $(PRODUCT).tds - del $(BCC_CFG) - -# -# Generic rules -# -.SUFFIXES: .cpp .c .sbr .obj - -# -# cc generic rule -# -.c.obj: - $(CC) +$(BCC_CFG) -o$@ $< - -# Compiler configuration file -$(BCC_CFG) : - Copy &&| - $(CFLAGS) - -c - -y #include line numbers in OBJ's - -v #include debug info - -w+ #turn on all warnings - -Od #disable all optimizations - #-a4 #32 bit data alignment - #-M # generate link map - #-ls # linker options - #-WM- #not multithread - -WM #multithread - -w-aus # ignore warning assigned a value that is never used - -w-sig # ignore warning conversion may lose sig digits -| $@ - -# EOF: makefile diff --git a/demo/ptransfer/makefile.b32 b/demo/ptransfer/makefile.b32 deleted file mode 100644 index 6153f422..00000000 --- a/demo/ptransfer/makefile.b32 +++ /dev/null @@ -1,139 +0,0 @@ -# -# Simple makefile to build an executable for Win32 -# -# This makefile assumes Borland bcc32 development environment -# on Windows NT/9x/2000/XP -# - -!ifndef BORLAND_DIR -BORLAND_DIR_Not_Defined: - @echo . - @echo You must define environment variable BORLAND_DIR to compile. -!endif - -PRODUCT = ptransfer -PRODUCT_EXE = $(PRODUCT).exe - -# tools -CC = $(BORLAND_DIR)\bin\bcc32 -MAKE=$(BORLAND_DIR)\bin\make.exe -#LINK = $(BORLAND_DIR)\bin\tlink32 -LINK = $(BORLAND_DIR)\bin\ilink32 - -BACNET_LIB_DIR = ..\..\lib -BACNET_LIB = $(BACNET_LIB_DIR)\bacnet.lib - -# directories -BACNET_PORT = ..\..\ports\win32 -BACNET_INCLUDE = ..\..\include -BACNET_OBJECT = ..\object -BACNET_HANDLER = ..\handler -INCLUDES = \ - -I$(BACNET_INCLUDE) \ - -I$(BACNET_PORT) \ - -I$(BACNET_OBJECT) \ - -I$(BACNET_HANDLER) \ - -I$(BORLAND_DIR)\include - -# -BACNET_DEFINES = -DPRINT_ENABLED=1 -DBACAPP_ALL -#BACDL_DEFINE=-DBACDL_MSTP=1 -BACDL_DEFINE=-DBACDL_BIP=1 -DUSE_INADDR=1 -DEFINES = $(BACNET_DEFINES) $(BACDL_DEFINE) - -SRCS = main.c \ - $(BACNET_OBJECT)\device-client.c - -OBJS = $(SRCS:.c=.obj) - -# -# Compiler definitions -# -BCC_CFG = bcc32.cfg - -# -# Include directories -# -CFLAGS = $(INCLUDES) $(DEFINES) - -# -# Libraries -# -C_LIB_DIR = $(BORLAND_DIR)\lib - -LIBS = $(BACNET_LIB) \ - $(C_LIB_DIR)\IMPORT32.lib \ - $(C_LIB_DIR)\CW32MT.lib \ - -# -# Main target -# -# This should be the first one in the makefile - -all : $(BACNET_LIB) $(BCC_CFG) $(OBJS) $(PRODUCT_EXE) - del $(BCC_CFG) - -install: $(PRODUCT_EXE) - copy $(PRODUCT_EXE) ..\..\bin\$(PRODUCT_EXE) - -# Linker specific: the link below is for BCC linker/compiler. If you link -# with a different linker - please change accordingly. -# - -# need a temp response file (@&&| ... |) because command line is too long -# $** lists each dependency -# $< target name -# $* target name without extension -$(PRODUCT_EXE) : $(OBJS) - @echo Running Linker for $(PRODUCT_EXE) - $(LINK) -L$(C_LIB_DIR) -L$(BACNET_LIB_DIR) -m -c -s -v @&&| - $(BORLAND_DIR)\lib\c0x32.obj $** - $< - $*.map - $(LIBS) -| - -# -# Utilities - -clean : - del $(OBJS) - del $(PRODUCT_EXE) - del $(PRODUCT).map - del $(PRODUCT).ilc - del $(PRODUCT).ild - del $(PRODUCT).ilf - del $(PRODUCT).ils - del $(PRODUCT).tds - del $(BCC_CFG) - -# -# Generic rules -# -.SUFFIXES: .cpp .c .sbr .obj - -# -# cc generic rule -# -.c.obj: - $(CC) +$(BCC_CFG) -o$@ $< - -# Compiler configuration file -$(BCC_CFG) : - Copy &&| - $(CFLAGS) - -c - -y #include line numbers in OBJ's - -v #include debug info - -w+ #turn on all warnings - -Od #disable all optimizations - #-a4 #32 bit data alignment - #-M # generate link map - #-ls # linker options - #-WM- #not multithread - -WM #multithread - -w-aus # ignore warning assigned a value that is never used - -w-sig # ignore warning conversion may lose sig digits -| $@ - -# EOF: makefile diff --git a/demo/ptransfer/rdproperty.vcproj b/demo/ptransfer/rdproperty.vcproj deleted file mode 100644 index 19a8be7f..00000000 --- a/demo/ptransfer/rdproperty.vcproj +++ /dev/null @@ -1,975 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/demo/readbdt/Makefile b/demo/readbdt/Makefile deleted file mode 100644 index 929864e5..00000000 --- a/demo/readbdt/Makefile +++ /dev/null @@ -1,39 +0,0 @@ -#Makefile to build BACnet Application for the GCC Port - -# tools - only if you need them. -# Most platforms have this already defined -# CC = gcc - -TARGET = bacrbdt - -TARGET_BIN = ${TARGET}$(TARGET_EXT) - -SRCS = main.c \ - ../object/netport.c \ - ../object/device-client.c - -OBJS = ${SRCS:.c=.o} - -all: ${BACNET_LIB_TARGET} Makefile ${TARGET_BIN} - -${TARGET_BIN}: ${OBJS} Makefile ${BACNET_LIB_TARGET} - ${CC} ${PFLAGS} ${OBJS} ${LFLAGS} -o $@ - size $@ - cp $@ ../../bin - -lib: ${BACNET_LIB_TARGET} - -${BACNET_LIB_TARGET}: - ( cd ${BACNET_LIB_DIR} ; $(MAKE) clean ; $(MAKE) ) - -.c.o: - ${CC} -c ${CFLAGS} $*.c -o $@ - -depend: - rm -f .depend - ${CC} -MM ${CFLAGS} *.c >> .depend - -clean: - rm -f core ${TARGET_BIN} ${OBJS} ${BACNET_LIB_TARGET} $(TARGET).map - -include: .depend diff --git a/demo/readbdt/makefile.b32 b/demo/readbdt/makefile.b32 deleted file mode 100644 index 28a307ed..00000000 --- a/demo/readbdt/makefile.b32 +++ /dev/null @@ -1,140 +0,0 @@ -# -# Simple makefile to build an executable for Win32 -# -# This makefile assumes Borland bcc32 development environment -# on Windows NT/9x/2000/XP -# - -!ifndef BORLAND_DIR -BORLAND_DIR_Not_Defined: - @echo . - @echo You must define environment variable BORLAND_DIR to compile. -!endif - -# target -PRODUCT = bacrbdt -PRODUCT_EXE = $(PRODUCT).exe - -# tools -CC = $(BORLAND_DIR)\bin\bcc32 -MAKE=$(BORLAND_DIR)\bin\make.exe -#LINK = $(BORLAND_DIR)\bin\tlink32 -LINK = $(BORLAND_DIR)\bin\ilink32 - -BACNET_LIB_DIR = ..\..\lib -BACNET_LIB = $(BACNET_LIB_DIR)\bacnet.lib - -# directories -BACNET_PORT = ..\..\ports\win32 -BACNET_INCLUDE = ..\..\include -BACNET_OBJECT = ..\object -BACNET_HANDLER = ..\handler -INCLUDES = \ - -I$(BACNET_INCLUDE) \ - -I$(BACNET_PORT) \ - -I$(BACNET_OBJECT) \ - -I$(BACNET_HANDLER) \ - -I$(BORLAND_DIR)\include - -# -BACNET_DEFINES = -DPRINT_ENABLED=1 -DBACAPP_ALL -#BACDL_DEFINE=-DBACDL_MSTP=1 -BACDL_DEFINE=-DBACDL_BIP=1 -DUSE_INADDR=1 -DEFINES = $(BACNET_DEFINES) $(BACDL_DEFINE) - -SRCS = main.c \ - $(BACNET_OBJECT)\device-client.c - -OBJS = $(SRCS:.c=.obj) - -# -# Compiler definitions -# -BCC_CFG = bcc32.cfg - -# -# Include directories -# -CFLAGS = $(INCLUDES) $(DEFINES) - -# -# Libraries -# -C_LIB_DIR = $(BORLAND_DIR)\lib - -LIBS = $(BACNET_LIB) \ - $(C_LIB_DIR)\IMPORT32.lib \ - $(C_LIB_DIR)\CW32MT.lib \ - -# -# Main target -# -# This should be the first one in the makefile - -all : $(BACNET_LIB) $(BCC_CFG) $(OBJS) $(PRODUCT_EXE) - del $(BCC_CFG) - -install: $(PRODUCT_EXE) - copy $(PRODUCT_EXE) ..\..\bin\$(PRODUCT_EXE) - -# Linker specific: the link below is for BCC linker/compiler. If you link -# with a different linker - please change accordingly. -# - -# need a temp response file (@&&| ... |) because command line is too long -# $** lists each dependency -# $< target name -# $* target name without extension -$(PRODUCT_EXE) : $(OBJS) - @echo Running Linker for $(PRODUCT_EXE) - $(LINK) -L$(C_LIB_DIR) -L$(BACNET_LIB_DIR) -m -c -s -v @&&| - $(BORLAND_DIR)\lib\c0x32.obj $** - $< - $*.map - $(LIBS) -| - -# -# Utilities - -clean : - del $(OBJS) - del $(PRODUCT_EXE) - del $(PRODUCT).map - del $(PRODUCT).ilc - del $(PRODUCT).ild - del $(PRODUCT).ilf - del $(PRODUCT).ils - del $(PRODUCT).tds - del $(BCC_CFG) - -# -# Generic rules -# -.SUFFIXES: .cpp .c .sbr .obj - -# -# cc generic rule -# -.c.obj: - $(CC) +$(BCC_CFG) -o$@ $< - -# Compiler configuration file -$(BCC_CFG) : - Copy &&| - $(CFLAGS) - -c - -y #include line numbers in OBJ's - -v #include debug info - -w+ #turn on all warnings - -Od #disable all optimizations - #-a4 #32 bit data alignment - #-M # generate link map - #-ls # linker options - #-WM- #not multithread - -WM #multithread - -w-aus # ignore warning assigned a value that is never used - -w-sig # ignore warning conversion may lose sig digits -| $@ - -# EOF: makefile diff --git a/demo/readfile/Makefile b/demo/readfile/Makefile deleted file mode 100644 index 3548774a..00000000 --- a/demo/readfile/Makefile +++ /dev/null @@ -1,39 +0,0 @@ -#Makefile to build BACnet Application for the Linux Port - -# tools - only if you need them. -# Most platforms have this already defined -# CC = gcc - -TARGET = bacarf - -TARGET_BIN = ${TARGET}$(TARGET_EXT) - -SRCS = main.c \ - ../object/netport.c \ - ../object/device-client.c - -OBJS = ${SRCS:.c=.o} - -all: ${BACNET_LIB_TARGET} Makefile ${TARGET_BIN} - -${TARGET_BIN}: ${OBJS} Makefile ${BACNET_LIB_TARGET} - ${CC} ${PFLAGS} ${OBJS} ${LFLAGS} -o $@ - size $@ - cp $@ ../../bin - -lib: ${BACNET_LIB_TARGET} - -${BACNET_LIB_TARGET}: - ( cd ${BACNET_LIB_DIR} ; $(MAKE) clean ; $(MAKE) ) - -.c.o: - ${CC} -c ${CFLAGS} $*.c -o $@ - -depend: - rm -f .depend - ${CC} -MM ${CFLAGS} *.c >> .depend - -clean: - rm -f core ${TARGET_BIN} ${OBJS} ${BACNET_LIB_TARGET} $(TARGET).map - -include: .depend diff --git a/demo/readfile/makefile.b32 b/demo/readfile/makefile.b32 deleted file mode 100644 index 12591afc..00000000 --- a/demo/readfile/makefile.b32 +++ /dev/null @@ -1,139 +0,0 @@ -# -# Simple makefile to build an executable for Win32 -# -# This makefile assumes Borland bcc32 development environment -# on Windows NT/9x/2000/XP -# - -!ifndef BORLAND_DIR -BORLAND_DIR_Not_Defined: - @echo . - @echo You must define environment variable BORLAND_DIR to compile. -!endif - -PRODUCT = bacarf -PRODUCT_EXE = $(PRODUCT).exe - -# tools -CC = $(BORLAND_DIR)\bin\bcc32 -MAKE=$(BORLAND_DIR)\bin\make.exe -#LINK = $(BORLAND_DIR)\bin\tlink32 -LINK = $(BORLAND_DIR)\bin\ilink32 - -BACNET_LIB_DIR = ..\..\lib -BACNET_LIB = $(BACNET_LIB_DIR)\bacnet.lib - -# directories -BACNET_PORT = ..\..\ports\win32 -BACNET_INCLUDE = ..\..\include -BACNET_OBJECT = ..\object -BACNET_HANDLER = ..\handler -INCLUDES = \ - -I$(BACNET_INCLUDE) \ - -I$(BACNET_PORT) \ - -I$(BACNET_OBJECT) \ - -I$(BACNET_HANDLER) \ - -I$(BORLAND_DIR)\include - -# -BACNET_DEFINES = -DPRINT_ENABLED=1 -DBACAPP_ALL -#BACDL_DEFINE=-DBACDL_MSTP=1 -BACDL_DEFINE=-DBACDL_BIP=1 -DUSE_INADDR=1 -DEFINES = $(BACNET_DEFINES) $(BACDL_DEFINE) - -SRCS = main.c \ - $(BACNET_OBJECT)\device-client.c - -OBJS = $(SRCS:.c=.obj) - -# -# Compiler definitions -# -BCC_CFG = bcc32.cfg - -# -# Include directories -# -CFLAGS = $(INCLUDES) $(DEFINES) - -# -# Libraries -# -C_LIB_DIR = $(BORLAND_DIR)\lib - -LIBS = $(BACNET_LIB) \ - $(C_LIB_DIR)\IMPORT32.lib \ - $(C_LIB_DIR)\CW32MT.lib \ - -# -# Main target -# -# This should be the first one in the makefile - -all : $(BACNET_LIB) $(BCC_CFG) $(OBJS) $(PRODUCT_EXE) - del $(BCC_CFG) - -install: $(PRODUCT_EXE) - copy $(PRODUCT_EXE) ..\..\bin\$(PRODUCT_EXE) - -# Linker specific: the link below is for BCC linker/compiler. If you link -# with a different linker - please change accordingly. -# - -# need a temp response file (@&&| ... |) because command line is too long -# $** lists each dependency -# $< target name -# $* target name without extension -$(PRODUCT_EXE) : $(OBJS) - @echo Running Linker for $(PRODUCT_EXE) - $(LINK) -L$(C_LIB_DIR) -L$(BACNET_LIB_DIR) -m -c -s -v @&&| - $(BORLAND_DIR)\lib\c0x32.obj $** - $< - $*.map - $(LIBS) -| - -# -# Utilities - -clean : - del $(OBJS) - del $(PRODUCT_EXE) - del $(PRODUCT).map - del $(PRODUCT).ilc - del $(PRODUCT).ild - del $(PRODUCT).ilf - del $(PRODUCT).ils - del $(PRODUCT).tds - del $(BCC_CFG) - -# -# Generic rules -# -.SUFFIXES: .cpp .c .sbr .obj - -# -# cc generic rule -# -.c.obj: - $(CC) +$(BCC_CFG) -o$@ $< - -# Compiler configuration file -$(BCC_CFG) : - Copy &&| - $(CFLAGS) - -c - -y #include line numbers in OBJ's - -v #include debug info - -w+ #turn on all warnings - -Od #disable all optimizations - #-a4 #32 bit data alignment - #-M # generate link map - #-ls # linker options - #-WM- #not multithread - -WM #multithread - -w-aus # ignore warning assigned a value that is never used - -w-sig # ignore warning conversion may lose sig digits -| $@ - -# EOF: makefile diff --git a/demo/readprop/Makefile b/demo/readprop/Makefile deleted file mode 100644 index 4aab27a5..00000000 --- a/demo/readprop/Makefile +++ /dev/null @@ -1,45 +0,0 @@ -#Makefile to build BACnet Application using GCC compiler - -# tools - only if you need them. -# Most platforms have this already defined -# CC = gcc -# AR = ar -# MAKE = make -# SIZE = size -# -# Assumes rm and cp are available - -# Executable file name -TARGET = bacrp - -TARGET_BIN = ${TARGET}$(TARGET_EXT) - -SRCS = main.c \ - ../object/netport.c \ - ../object/device-client.c - -OBJS = ${SRCS:.c=.o} - -all: ${BACNET_LIB_TARGET} Makefile ${TARGET_BIN} - -${TARGET_BIN}: ${OBJS} Makefile ${BACNET_LIB_TARGET} - ${CC} ${PFLAGS} ${OBJS} ${LFLAGS} -o $@ - size $@ - cp $@ ../../bin - -lib: ${BACNET_LIB_TARGET} - -${BACNET_LIB_TARGET}: - ( cd ${BACNET_LIB_DIR} ; $(MAKE) clean ; $(MAKE) ) - -.c.o: - ${CC} -c ${CFLAGS} $*.c -o $@ - -depend: - rm -f .depend - ${CC} -MM ${CFLAGS} *.c >> .depend - -clean: - rm -rf core ${TARGET_BIN} ${OBJS} ${BACNET_LIB_TARGET} - -include: .depend diff --git a/demo/readprop/makefile.b32 b/demo/readprop/makefile.b32 deleted file mode 100644 index 83181339..00000000 --- a/demo/readprop/makefile.b32 +++ /dev/null @@ -1,139 +0,0 @@ -# -# Simple makefile to build an executable for Win32 -# -# This makefile assumes Borland bcc32 development environment -# on Windows NT/9x/2000/XP -# - -!ifndef BORLAND_DIR -BORLAND_DIR_Not_Defined: - @echo . - @echo You must define environment variable BORLAND_DIR to compile. -!endif - -PRODUCT = bacrp -PRODUCT_EXE = $(PRODUCT).exe - -# tools -CC = $(BORLAND_DIR)\bin\bcc32 -MAKE=$(BORLAND_DIR)\bin\make.exe -#LINK = $(BORLAND_DIR)\bin\tlink32 -LINK = $(BORLAND_DIR)\bin\ilink32 - -BACNET_LIB_DIR = ..\..\lib -BACNET_LIB = $(BACNET_LIB_DIR)\bacnet.lib - -# directories -BACNET_PORT = ..\..\ports\win32 -BACNET_INCLUDE = ..\..\include -BACNET_OBJECT = ..\object -BACNET_HANDLER = ..\handler -INCLUDES = \ - -I$(BACNET_INCLUDE) \ - -I$(BACNET_PORT) \ - -I$(BACNET_OBJECT) \ - -I$(BACNET_HANDLER) \ - -I$(BORLAND_DIR)\include - -# -BACNET_DEFINES = -DPRINT_ENABLED=1 -DBACAPP_ALL -#BACDL_DEFINE=-DBACDL_MSTP=1 -BACDL_DEFINE=-DBACDL_BIP=1 -DUSE_INADDR=1 -DEFINES = $(BACNET_DEFINES) $(BACDL_DEFINE) - -SRCS = main.c \ - $(BACNET_OBJECT)\device-client.c - -OBJS = $(SRCS:.c=.obj) - -# -# Compiler definitions -# -BCC_CFG = bcc32.cfg - -# -# Include directories -# -CFLAGS = $(INCLUDES) $(DEFINES) - -# -# Libraries -# -C_LIB_DIR = $(BORLAND_DIR)\lib - -LIBS = $(BACNET_LIB) \ - $(C_LIB_DIR)\IMPORT32.lib \ - $(C_LIB_DIR)\CW32MT.lib \ - -# -# Main target -# -# This should be the first one in the makefile - -all : $(BACNET_LIB) $(BCC_CFG) $(OBJS) $(PRODUCT_EXE) - del $(BCC_CFG) - -install: $(PRODUCT_EXE) - copy $(PRODUCT_EXE) ..\..\bin\$(PRODUCT_EXE) - -# Linker specific: the link below is for BCC linker/compiler. If you link -# with a different linker - please change accordingly. -# - -# need a temp response file (@&&| ... |) because command line is too long -# $** lists each dependency -# $< target name -# $* target name without extension -$(PRODUCT_EXE) : $(OBJS) - @echo Running Linker for $(PRODUCT_EXE) - $(LINK) -L$(C_LIB_DIR) -L$(BACNET_LIB_DIR) -m -c -s -v @&&| - $(BORLAND_DIR)\lib\c0x32.obj $** - $< - $*.map - $(LIBS) -| - -# -# Utilities - -clean : - del $(OBJS) - del $(PRODUCT_EXE) - del $(PRODUCT).map - del $(PRODUCT).ilc - del $(PRODUCT).ild - del $(PRODUCT).ilf - del $(PRODUCT).ils - del $(PRODUCT).tds - del $(BCC_CFG) - -# -# Generic rules -# -.SUFFIXES: .cpp .c .sbr .obj - -# -# cc generic rule -# -.c.obj: - $(CC) +$(BCC_CFG) -o$@ $< - -# Compiler configuration file -$(BCC_CFG): - Copy &&| - $(CFLAGS) - -c - -y #include line numbers in OBJ's - -v #include debug info - -w+ #turn on all warnings - -Od #disable all optimizations - #-a4 #32 bit data alignment - #-M # generate link map - #-ls # linker options - #-WM- #not multithread - -WM #multithread - -w-aus # ignore warning assigned a value that is never used - -w-sig # ignore warning conversion may lose sig digits -| $@ - -# EOF: makefile diff --git a/demo/readpropm/Makefile b/demo/readpropm/Makefile deleted file mode 100644 index 12630050..00000000 --- a/demo/readpropm/Makefile +++ /dev/null @@ -1,40 +0,0 @@ -#Makefile to build BACnet Application for the Linux Port - -# tools - only if you need them. -# Most platforms have this already defined -# CC = gcc - -# Executable file name -TARGET = bacrpm - -TARGET_BIN = ${TARGET}$(TARGET_EXT) - -SRCS = main.c \ - ../object/netport.c \ - ../object/device-client.c - -OBJS = ${SRCS:.c=.o} - -all: ${BACNET_LIB_TARGET} Makefile ${TARGET_BIN} - -${TARGET_BIN}: ${OBJS} Makefile ${BACNET_LIB_TARGET} - ${CC} ${PFLAGS} ${OBJS} ${LFLAGS} -o $@ - size $@ - cp $@ ../../bin - -lib: ${BACNET_LIB_TARGET} - -${BACNET_LIB_TARGET}: - ( cd ${BACNET_LIB_DIR} ; $(MAKE) clean ; $(MAKE) ) - -.c.o: - ${CC} -c ${CFLAGS} $*.c -o $@ - -depend: - rm -f .depend - ${CC} -MM ${CFLAGS} *.c >> .depend - -clean: - rm -f core ${TARGET_BIN} ${OBJS} ${BACNET_LIB_TARGET} $(TARGET).map - -include: .depend diff --git a/demo/readpropm/makefile.b32 b/demo/readpropm/makefile.b32 deleted file mode 100644 index 99dc89f0..00000000 --- a/demo/readpropm/makefile.b32 +++ /dev/null @@ -1,139 +0,0 @@ -# -# Simple makefile to build an executable for Win32 -# -# This makefile assumes Borland bcc32 development environment -# on Windows NT/9x/2000/XP -# - -!ifndef BORLAND_DIR -BORLAND_DIR_Not_Defined: - @echo . - @echo You must define environment variable BORLAND_DIR to compile. -!endif - -PRODUCT = bacrpm -PRODUCT_EXE = $(PRODUCT).exe - -# tools -CC = $(BORLAND_DIR)\bin\bcc32 -MAKE=$(BORLAND_DIR)\bin\make.exe -#LINK = $(BORLAND_DIR)\bin\tlink32 -LINK = $(BORLAND_DIR)\bin\ilink32 - -BACNET_LIB_DIR = ..\..\lib -BACNET_LIB = $(BACNET_LIB_DIR)\bacnet.lib - -# directories -BACNET_PORT = ..\..\ports\win32 -BACNET_INCLUDE = ..\..\include -BACNET_OBJECT = ..\object -BACNET_HANDLER = ..\handler -INCLUDES = \ - -I$(BACNET_INCLUDE) \ - -I$(BACNET_PORT) \ - -I$(BACNET_OBJECT) \ - -I$(BACNET_HANDLER) \ - -I$(BORLAND_DIR)\include - -# -BACNET_DEFINES = -DPRINT_ENABLED=1 -DBACAPP_ALL -#BACDL_DEFINE=-DBACDL_MSTP=1 -BACDL_DEFINE=-DBACDL_BIP=1 -DUSE_INADDR=1 -DEFINES = $(BACNET_DEFINES) $(BACDL_DEFINE) - -SRCS = main.c \ - $(BACNET_OBJECT)\device-client.c - -OBJS = $(SRCS:.c=.obj) - -# -# Compiler definitions -# -BCC_CFG = bcc32.cfg - -# -# Include directories -# -CFLAGS = $(INCLUDES) $(DEFINES) - -# -# Libraries -# -C_LIB_DIR = $(BORLAND_DIR)\lib - -LIBS = $(BACNET_LIB) \ - $(C_LIB_DIR)\IMPORT32.lib \ - $(C_LIB_DIR)\CW32MT.lib \ - -# -# Main target -# -# This should be the first one in the makefile - -all : $(BACNET_LIB) $(BCC_CFG) $(OBJS) $(PRODUCT_EXE) - del $(BCC_CFG) - -install: $(PRODUCT_EXE) - copy $(PRODUCT_EXE) ..\..\bin\$(PRODUCT_EXE) - -# Linker specific: the link below is for BCC linker/compiler. If you link -# with a different linker - please change accordingly. -# - -# need a temp response file (@&&| ... |) because command line is too long -# $** lists each dependency -# $< target name -# $* target name without extension -$(PRODUCT_EXE) : $(OBJS) - @echo Running Linker for $(PRODUCT_EXE) - $(LINK) -L$(C_LIB_DIR) -L$(BACNET_LIB_DIR) -m -c -s -v @&&| - $(BORLAND_DIR)\lib\c0x32.obj $** - $< - $*.map - $(LIBS) -| - -# -# Utilities - -clean : - del $(OBJS) - del $(PRODUCT_EXE) - del $(PRODUCT).map - del $(PRODUCT).ilc - del $(PRODUCT).ild - del $(PRODUCT).ilf - del $(PRODUCT).ils - del $(PRODUCT).tds - del $(BCC_CFG) - -# -# Generic rules -# -.SUFFIXES: .cpp .c .sbr .obj - -# -# cc generic rule -# -.c.obj: - $(CC) +$(BCC_CFG) -o$@ $< - -# Compiler configuration file -$(BCC_CFG) : - Copy &&| - $(CFLAGS) - -c - -y #include line numbers in OBJ's - -v #include debug info - -w+ #turn on all warnings - -Od #disable all optimizations - #-a4 #32 bit data alignment - #-M # generate link map - #-ls # linker options - #-WM- #not multithread - -WM #multithread - -w-aus # ignore warning assigned a value that is never used - -w-sig # ignore warning conversion may lose sig digits -| $@ - -# EOF: makefile diff --git a/demo/readrange/Makefile b/demo/readrange/Makefile deleted file mode 100644 index 67b3b435..00000000 --- a/demo/readrange/Makefile +++ /dev/null @@ -1,45 +0,0 @@ -#Makefile to build BACnet Application using GCC compiler - -# tools - only if you need them. -# Most platforms have this already defined -# CC = gcc -# AR = ar -# MAKE = make -# SIZE = size -# -# Assumes rm and cp are available - -# Executable file name -TARGET = bacrr - -TARGET_BIN = ${TARGET}$(TARGET_EXT) - -SRCS = main.c \ - ../object/netport.c \ - ../object/device-client.c - -OBJS = ${SRCS:.c=.o} - -all: ${BACNET_LIB_TARGET} Makefile ${TARGET_BIN} - -${TARGET_BIN}: ${OBJS} Makefile ${BACNET_LIB_TARGET} - ${CC} ${PFLAGS} ${OBJS} ${LFLAGS} -o $@ - size $@ - cp $@ ../../bin - -lib: ${BACNET_LIB_TARGET} - -${BACNET_LIB_TARGET}: - ( cd ${BACNET_LIB_DIR} ; $(MAKE) clean ; $(MAKE) ) - -.c.o: - ${CC} -c ${CFLAGS} $*.c -o $@ - -depend: - rm -f .depend - ${CC} -MM ${CFLAGS} *.c >> .depend - -clean: - rm -rf core ${TARGET_BIN} ${OBJS} ${BACNET_LIB_TARGET} - -include: .depend diff --git a/demo/reinit/Makefile b/demo/reinit/Makefile deleted file mode 100644 index 52e64950..00000000 --- a/demo/reinit/Makefile +++ /dev/null @@ -1,40 +0,0 @@ -#Makefile to build BACnet Application for the Linux Port - -# tools - only if you need them. -# Most platforms have this already defined -# CC = gcc - -# Executable file name -TARGET = bacrd - -TARGET_BIN = ${TARGET}$(TARGET_EXT) - -SRCS = main.c \ - ../object/netport.c \ - ../object/device-client.c - -OBJS = ${SRCS:.c=.o} - -all: ${BACNET_LIB_TARGET} Makefile ${TARGET_BIN} - -${TARGET_BIN}: ${OBJS} Makefile ${BACNET_LIB_TARGET} - ${CC} ${PFLAGS} ${OBJS} ${LFLAGS} -o $@ - size $@ - cp $@ ../../bin - -lib: ${BACNET_LIB_TARGET} - -${BACNET_LIB_TARGET}: - ( cd ${BACNET_LIB_DIR} ; $(MAKE) clean ; $(MAKE) ) - -.c.o: - ${CC} -c ${CFLAGS} $*.c -o $@ - -depend: - rm -f .depend - ${CC} -MM ${CFLAGS} *.c >> .depend - -clean: - rm -f core ${TARGET_BIN} ${OBJS} ${BACNET_LIB_TARGET} $(TARGET).map - -include: .depend diff --git a/demo/reinit/makefile.b32 b/demo/reinit/makefile.b32 deleted file mode 100644 index f32dc1c8..00000000 --- a/demo/reinit/makefile.b32 +++ /dev/null @@ -1,139 +0,0 @@ -# -# Simple makefile to build an executable for Win32 -# -# This makefile assumes Borland bcc32 development environment -# on Windows NT/9x/2000/XP -# - -!ifndef BORLAND_DIR -BORLAND_DIR_Not_Defined: - @echo . - @echo You must define environment variable BORLAND_DIR to compile. -!endif - -PRODUCT = bacrd -PRODUCT_EXE = $(PRODUCT).exe - -# tools -CC = $(BORLAND_DIR)\bin\bcc32 -MAKE=$(BORLAND_DIR)\bin\make.exe -#LINK = $(BORLAND_DIR)\bin\tlink32 -LINK = $(BORLAND_DIR)\bin\ilink32 - -BACNET_LIB_DIR = ..\..\lib -BACNET_LIB = $(BACNET_LIB_DIR)\bacnet.lib - -# directories -BACNET_PORT = ..\..\ports\win32 -BACNET_INCLUDE = ..\..\include -BACNET_OBJECT = ..\object -BACNET_HANDLER = ..\handler -INCLUDES = \ - -I$(BACNET_INCLUDE) \ - -I$(BACNET_PORT) \ - -I$(BACNET_OBJECT) \ - -I$(BACNET_HANDLER) \ - -I$(BORLAND_DIR)\include - -# -BACNET_DEFINES = -DPRINT_ENABLED=1 -DBACAPP_ALL -#BACDL_DEFINE=-DBACDL_MSTP=1 -BACDL_DEFINE=-DBACDL_BIP=1 -DUSE_INADDR=1 -DEFINES = $(BACNET_DEFINES) $(BACDL_DEFINE) - -SRCS = main.c \ - $(BACNET_OBJECT)\device-client.c - -OBJS = $(SRCS:.c=.obj) - -# -# Compiler definitions -# -BCC_CFG = bcc32.cfg - -# -# Include directories -# -CFLAGS = $(INCLUDES) $(DEFINES) - -# -# Libraries -# -C_LIB_DIR = $(BORLAND_DIR)\lib - -LIBS = $(BACNET_LIB) \ - $(C_LIB_DIR)\IMPORT32.lib \ - $(C_LIB_DIR)\CW32MT.lib \ - -# -# Main target -# -# This should be the first one in the makefile - -all : $(BACNET_LIB) $(BCC_CFG) $(OBJS) $(PRODUCT_EXE) - del $(BCC_CFG) - -install: $(PRODUCT_EXE) - copy $(PRODUCT_EXE) ..\..\bin\$(PRODUCT_EXE) - -# Linker specific: the link below is for BCC linker/compiler. If you link -# with a different linker - please change accordingly. -# - -# need a temp response file (@&&| ... |) because command line is too long -# $** lists each dependency -# $< target name -# $* target name without extension -$(PRODUCT_EXE) : $(OBJS) - @echo Running Linker for $(PRODUCT_EXE) - $(LINK) -L$(C_LIB_DIR) -L$(BACNET_LIB_DIR) -m -c -s -v @&&| - $(BORLAND_DIR)\lib\c0x32.obj $** - $< - $*.map - $(LIBS) -| - -# -# Utilities - -clean : - del $(OBJS) - del $(PRODUCT_EXE) - del $(PRODUCT).map - del $(PRODUCT).ilc - del $(PRODUCT).ild - del $(PRODUCT).ilf - del $(PRODUCT).ils - del $(PRODUCT).tds - del $(BCC_CFG) - -# -# Generic rules -# -.SUFFIXES: .cpp .c .sbr .obj - -# -# cc generic rule -# -.c.obj: - $(CC) +$(BCC_CFG) -o$@ $< - -# Compiler configuration file -$(BCC_CFG) : - Copy &&| - $(CFLAGS) - -c - -y #include line numbers in OBJ's - -v #include debug info - -w+ #turn on all warnings - -Od #disable all optimizations - #-a4 #32 bit data alignment - #-M # generate link map - #-ls # linker options - #-WM- #not multithread - -WM #multithread - -w-aus # ignore warning assigned a value that is never used - -w-sig # ignore warning conversion may lose sig digits -| $@ - -# EOF: makefile diff --git a/demo/router-ipv6/Makefile b/demo/router-ipv6/Makefile deleted file mode 100644 index cc51df2a..00000000 --- a/demo/router-ipv6/Makefile +++ /dev/null @@ -1,59 +0,0 @@ -#Makefile to build BACnet Application for the GCC port - -# tools - only if you need them. -# Most platforms have this already defined -# CC = gcc - -# Executable file name -TARGET = bacroute - -TARGET_BIN = ${TARGET}$(TARGET_EXT) - -CFLAGS += -DPRINT_ENABLED=1 - -BACNET_SOURCE_DIR = ../../src -BACNET_HANDLER_DIR = ../handler -BACNET_OBJECT_DIR = ../object - -SRC = main.c \ - $(BACNET_OBJECT_DIR)/netport.c \ - $(BACNET_OBJECT_DIR)/device-client.c - -PORT_BIP6_SRC = \ - $(BACNET_PORT_DIR)/bip6.c \ - $(BACNET_SOURCE_DIR)/bvlc6.c \ - $(BACNET_HANDLER_DIR)/h_bbmd6.c \ - $(BACNET_SOURCE_DIR)/vmac.c - -PORT_BIP_SRC = \ - $(BACNET_PORT_DIR)/bip-init.c \ - $(BACNET_SOURCE_DIR)/bvlc.c \ - $(BACNET_SOURCE_DIR)/bip.c - -SRCS = ${SRC} ${PORT_BIP6_SRC} ${PORT_BIP_SRC} - -OBJS = ${SRCS:.c=.o} - -all: ${BACNET_LIB_TARGET} Makefile ${TARGET_BIN} - -${TARGET_BIN}: ${OBJS} Makefile ${BACNET_LIB_TARGET} - ${CC} ${PFLAGS} ${OBJS} ${LFLAGS} -o $@ - size $@ - cp $@ ../../bin - -lib: ${BACNET_LIB_TARGET} - -${BACNET_LIB_TARGET}: - ( cd ${BACNET_LIB_DIR} ; $(MAKE) clean ; $(MAKE) ) - -.c.o: - ${CC} -c ${CFLAGS} $*.c -o $@ - -depend: - rm -f .depend - ${CC} -MM ${CFLAGS} *.c >> .depend - -clean: - rm -f core ${TARGET_BIN} ${OBJS} ${BACNET_LIB_TARGET} $(TARGET).map - -include: .depend diff --git a/demo/scov/Makefile b/demo/scov/Makefile deleted file mode 100644 index 9349f6b0..00000000 --- a/demo/scov/Makefile +++ /dev/null @@ -1,45 +0,0 @@ -#Makefile to build BACnet Application using GCC compiler - -# tools - only if you need them. -# Most platforms have this already defined -# CC = gcc -# AR = ar -# MAKE = make -# SIZE = size -# -# Assumes rm and cp are available - -# Executable file name -TARGET = bacscov - -TARGET_BIN = ${TARGET}$(TARGET_EXT) - -SRCS = main.c \ - ../object/netport.c \ - ../object/device-client.c - -OBJS = ${SRCS:.c=.o} - -all: ${BACNET_LIB_TARGET} Makefile ${TARGET_BIN} - -${TARGET_BIN}: ${OBJS} Makefile ${BACNET_LIB_TARGET} - ${CC} ${PFLAGS} ${OBJS} ${LFLAGS} -o $@ - size $@ - cp $@ ../../bin - -lib: ${BACNET_LIB_TARGET} - -${BACNET_LIB_TARGET}: - ( cd ${BACNET_LIB_DIR} ; $(MAKE) clean ; $(MAKE) ) - -.c.o: - ${CC} -c ${CFLAGS} $*.c -o $@ - -depend: - rm -f .depend - ${CC} -MM ${CFLAGS} *.c >> .depend - -clean: - rm -rf core ${TARGET_BIN} ${OBJS} ${BACNET_LIB_TARGET} - -include: .depend diff --git a/demo/scov/makefile.b32 b/demo/scov/makefile.b32 deleted file mode 100644 index 84cfd818..00000000 --- a/demo/scov/makefile.b32 +++ /dev/null @@ -1,143 +0,0 @@ -# -# Simple makefile to build an executable for Win32 -# -# This makefile assumes Borland bcc32 development environment -# on Windows NT/9x/2000/XP -# - -!ifndef BORLAND_DIR -BORLAND_DIR_Not_Defined: - @echo . - @echo You must define environment variable BORLAND_DIR to compile. -!endif - -PRODUCT = bacscov -PRODUCT_EXE = $(PRODUCT).exe - -# tools -CC = $(BORLAND_DIR)\bin\bcc32 -MAKE=$(BORLAND_DIR)\bin\make.exe -#LINK = $(BORLAND_DIR)\bin\tlink32 -LINK = $(BORLAND_DIR)\bin\ilink32 - -BACNET_LIB_DIR = ..\..\lib -BACNET_LIB = $(BACNET_LIB_DIR)\bacnet.lib - -# directories -BACNET_PORT = ..\..\ports\win32 -BACNET_INCLUDE = ..\..\include -BACNET_OBJECT = ..\object -BACNET_HANDLER = ..\handler -INCLUDES = \ - -I$(BACNET_INCLUDE) \ - -I$(BACNET_PORT) \ - -I$(BACNET_OBJECT) \ - -I$(BACNET_HANDLER) \ - -I$(BORLAND_DIR)\include - -# -BACNET_DEFINES = -DPRINT_ENABLED=1 -DBACAPP_ALL -#BACDL_DEFINE=-DBACDL_MSTP=1 -BACDL_DEFINE=-DBACDL_BIP=1 -DUSE_INADDR=1 - -# by default bacupt can handle 64 tag/value pairs -BUILD_DEFINE = -DMAX_PROPERTY_VALUES=64 - -DEFINES = $(BACNET_DEFINES) $(BACDL_DEFINE) $(BUILD_DEFINE) - -SRCS = main.c \ - $(BACNET_OBJECT)\device-client.c - -OBJS = $(SRCS:.c=.obj) - -# -# Compiler definitions -# -BCC_CFG = bcc32.cfg - -# -# Include directories -# -CFLAGS = $(INCLUDES) $(DEFINES) - -# -# Libraries -# -C_LIB_DIR = $(BORLAND_DIR)\lib - -LIBS = $(BACNET_LIB) \ - $(C_LIB_DIR)\IMPORT32.lib \ - $(C_LIB_DIR)\CW32MT.lib \ - -# -# Main target -# -# This should be the first one in the makefile - -all : $(BACNET_LIB) $(BCC_CFG) $(OBJS) $(PRODUCT_EXE) - del $(BCC_CFG) - -install: $(PRODUCT_EXE) - copy $(PRODUCT_EXE) ..\..\bin\$(PRODUCT_EXE) - -# Linker specific: the link below is for BCC linker/compiler. If you link -# with a different linker - please change accordingly. -# - -# need a temp response file (@&&| ... |) because command line is too long -# $** lists each dependency -# $< target name -# $* target name without extension -$(PRODUCT_EXE) : $(OBJS) - @echo Running Linker for $(PRODUCT_EXE) - $(LINK) -L$(C_LIB_DIR) -L$(BACNET_LIB_DIR) -m -c -s -v @&&| - $(BORLAND_DIR)\lib\c0x32.obj $** - $< - $*.map - $(LIBS) -| - -# -# Utilities - -clean : - del $(OBJS) - del $(PRODUCT_EXE) - del $(PRODUCT).map - del $(PRODUCT).ilc - del $(PRODUCT).ild - del $(PRODUCT).ilf - del $(PRODUCT).ils - del $(PRODUCT).tds - del $(BCC_CFG) - -# -# Generic rules -# -.SUFFIXES: .cpp .c .sbr .obj - -# -# cc generic rule -# -.c.obj: - $(CC) +$(BCC_CFG) -o$@ $< - -# Compiler configuration file -$(BCC_CFG) : - Copy &&| - $(CFLAGS) - -c - -y #include line numbers in OBJ's - -v #include debug info - -w+ #turn on all warnings - -Od #disable all optimizations - #-a4 #32 bit data alignment - #-M # generate link map - #-ls # linker options - #-WM- #not multithread - -WM #multithread - -w-aus # ignore warning assigned a value that is never used - -w-sig # ignore warning conversion may lose sig digits -| $@ - -# EOF: makefile diff --git a/demo/server/Makefile b/demo/server/Makefile deleted file mode 100644 index 43e768a0..00000000 --- a/demo/server/Makefile +++ /dev/null @@ -1,73 +0,0 @@ -#Makefile to build BACnet Application for the GCC port - -# tools - only if you need them. -# Most platforms have this already defined -# CC = gcc - -# Executable file name -TARGET = bacserv - -TARGET_BIN = ${TARGET}$(TARGET_EXT) - -SRC = main.c - -OBJECT_SRC = \ - $(BACNET_OBJECT)/device.c \ - $(BACNET_OBJECT)/ai.c \ - $(BACNET_OBJECT)/ao.c \ - $(BACNET_OBJECT)/av.c \ - $(BACNET_OBJECT)/bi.c \ - $(BACNET_OBJECT)/bo.c \ - $(BACNET_OBJECT)/bv.c \ - $(BACNET_OBJECT)/channel.c \ - $(BACNET_OBJECT)/command.c \ - $(BACNET_OBJECT)/csv.c \ - $(BACNET_OBJECT)/iv.c \ - $(BACNET_OBJECT)/lc.c \ - $(BACNET_OBJECT)/lo.c \ - $(BACNET_OBJECT)/lsp.c \ - $(BACNET_OBJECT)/ms-input.c \ - $(BACNET_OBJECT)/mso.c \ - $(BACNET_OBJECT)/msv.c \ - $(BACNET_OBJECT)/osv.c \ - $(BACNET_OBJECT)/piv.c \ - $(BACNET_OBJECT)/nc.c \ - $(BACNET_OBJECT)/netport.c \ - $(BACNET_OBJECT)/trendlog.c \ - $(BACNET_OBJECT)/schedule.c \ - $(BACNET_OBJECT)/access_credential.c \ - $(BACNET_OBJECT)/access_door.c \ - $(BACNET_OBJECT)/access_point.c \ - $(BACNET_OBJECT)/access_rights.c \ - $(BACNET_OBJECT)/access_user.c \ - $(BACNET_OBJECT)/access_zone.c \ - $(BACNET_OBJECT)/credential_data_input.c \ - $(BACNET_OBJECT)/bacfile.c - -SRCS = ${SRC} ${OBJECT_SRC} - -OBJS = ${SRCS:.c=.o} - -all: ${BACNET_LIB_TARGET} Makefile ${TARGET_BIN} - -${TARGET_BIN}: ${OBJS} Makefile ${BACNET_LIB_TARGET} - ${CC} ${PFLAGS} ${OBJS} ${LFLAGS} -o $@ - size $@ - cp $@ ../../bin - -lib: ${BACNET_LIB_TARGET} - -${BACNET_LIB_TARGET}: - ( cd ${BACNET_LIB_DIR} ; $(MAKE) clean ; $(MAKE) ) - -.c.o: - ${CC} -c ${CFLAGS} $*.c -o $@ - -depend: - rm -f .depend - ${CC} -MM ${CFLAGS} *.c >> .depend - -clean: - rm -f core ${TARGET_BIN} ${OBJS} ${BACNET_LIB_TARGET} $(TARGET).map - -include: .depend diff --git a/demo/server/bacserv.cbp b/demo/server/bacserv.cbp deleted file mode 100644 index 9b0020f4..00000000 --- a/demo/server/bacserv.cbp +++ /dev/null @@ -1,134 +0,0 @@ - - - - - - diff --git a/demo/server/makefile.b32 b/demo/server/makefile.b32 deleted file mode 100644 index 9a645b36..00000000 --- a/demo/server/makefile.b32 +++ /dev/null @@ -1,148 +0,0 @@ -# -# Simple makefile to build an executable for Win32 -# -# This makefile assumes Borland bcc32 development environment -# on Windows NT/9x/2000/XP -# - -!ifndef BORLAND_DIR -BORLAND_DIR_Not_Defined: - @echo . - @echo You must define environment variable BORLAND_DIR to compile. -!endif - -# target -PRODUCT = bacserv -PRODUCT_EXE = $(PRODUCT).exe - -# tools -CC = $(BORLAND_DIR)\bin\bcc32 -MAKE=$(BORLAND_DIR)\bin\make.exe -#LINK = $(BORLAND_DIR)\bin\tlink32 -LINK = $(BORLAND_DIR)\bin\ilink32 - -BACNET_LIB_DIR = ..\..\lib -BACNET_LIB = $(BACNET_LIB_DIR)\bacnet.lib -# getting back from the library -BACNET_DEMO_DIR = ..\demo\server - -# directories -BACNET_PORT = ..\..\ports\win32 -BACNET_INCLUDE = ..\..\include -BACNET_OBJECT = ..\object -BACNET_HANDLER = ..\handler -INCLUDES = \ - -I$(BACNET_INCLUDE) \ - -I$(BACNET_PORT) \ - -I$(BACNET_OBJECT) \ - -I$(BACNET_HANDLER) \ - -I$(BORLAND_DIR)\include - -# -BACNET_DEFINES = -DPRINT_ENABLED=1 -DBACFILE -DBACAPP_ALL -#BACDL_DEFINE=-DBACDL_MSTP -DCRC_USE_TABLE -BACDL_DEFINE=-DBACDL_BIP=1 -DUSE_INADDR=1 -DEFINES = $(BACNET_DEFINES) $(BACDL_DEFINE) - -SRCS = main.c - -OBJS = $(SRCS:.c=.obj) - -# -# Compiler definitions -# -BCC_CFG = bcc32.cfg - -# -# Include directories -# -CFLAGS = $(INCLUDES) $(DEFINES) - -# -# Libraries -# -C_LIB_DIR = $(BORLAND_DIR)\lib - -LIBS = $(BACNET_LIB) \ - $(C_LIB_DIR)\IMPORT32.lib \ - $(C_LIB_DIR)\CW32MT.lib \ - -# -# Main target -# -# This should be the first one in the makefile - -all : $(BACNET_LIB) $(BCC_CFG) $(OBJS) $(PRODUCT_EXE) - del $(BCC_CFG) - -install: $(PRODUCT_EXE) - copy $(PRODUCT_EXE) ..\..\bin\$(PRODUCT_EXE) - -$(BACNET_LIB): - cd $(BACNET_LIB_DIR) - $(MAKE) -i -f makefile.b32 clean - $(MAKE) -f makefile.b32 all - cd $(BACNET_DEMO_DIR) - -# Linker specific: the link below is for BCC linker/compiler. If you link -# with a different linker - please change accordingly. -# - -# need a temp response file (@&&| ... |) because command line is too long -# $** lists each dependency -# $< target name -# $* target name without extension -$(PRODUCT_EXE) : $(OBJS) - @echo Running Linker for $(PRODUCT_EXE) - $(LINK) -L$(C_LIB_DIR) -L$(BACNET_LIB_DIR) -m -c -s -v @&&| - $(BORLAND_DIR)\lib\c0x32.obj $** - $< - $*.map - $(LIBS) -| - -# -# Utilities - -clean : - del $(OBJS) - del $(PRODUCT_EXE) - del $(PRODUCT).map - del $(PRODUCT).ilc - del $(PRODUCT).ild - del $(PRODUCT).ilf - del $(PRODUCT).ils - del $(PRODUCT).tds - del $(BCC_CFG) - -# -# Generic rules -# -.SUFFIXES: .cpp .c .sbr .obj - -# -# cc generic rule -# -.c.obj: - $(CC) +$(BCC_CFG) -o$@ $< - -# Compiler configuration file -$(BCC_CFG) : - Copy &&| - $(CFLAGS) - -c - -y #include line numbers in OBJ's - -v #include debug info - -w+ #turn on all warnings - #-Od #disable all optimizations - -O2 #disable all optimizations - -WM #multithread - #-WM- #not multithread - -w-aus # ignore warning assigned a value that is never used - -w-sig # ignore warning conversion may lose sig digits - #-a4 #32 bit data alignment - #-M # generate link map - #-ls # linker options -| $@ - -# EOF: makefile diff --git a/demo/server/server.h b/demo/server/server.h deleted file mode 100644 index 492f4268..00000000 --- a/demo/server/server.h +++ /dev/null @@ -1,48 +0,0 @@ -/************************************************************************** -* -* Copyright (C) 2006 Steve Karg -* -* Permission is hereby granted, free of charge, to any person obtaining -* a copy of this software and associated documentation files (the -* "Software"), to deal in the Software without restriction, including -* without limitation the rights to use, copy, modify, merge, publish, -* distribute, sublicense, and/or sell copies of the Software, and to -* permit persons to whom the Software is furnished to do so, subject to -* the following conditions: -* -* The above copyright notice and this permission notice shall be included -* in all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -* -*********************************************************************/ - -#ifndef SERVER_H_ -#define SERVER_H_ - -/** @file server/server.h Header for example server (ie, BACnet Device) - * using the BACnet Stack. */ - -/** @defgroup Demos Demos of Servers and Clients - * Most of the folders under the /demo folder contain demonstration (ie, sample) - * code that implements the name functionality. - * - * The exceptions to this general rule, /handler and /object folders, are - * described in the various BIBBs and Object Framework modules. - */ - -/** @defgroup ServerDemo Demo of a BACnet Server (Device). - * @ingroup Demos - * This is a basic demonstration of a simple BACnet Device consisting of - * the services and properties shown in its EPICS - * (see file demo/server/epics_vts3.tpi) - */ - - -#endif /* SERVER_H_ */ diff --git a/demo/timesync/Makefile b/demo/timesync/Makefile deleted file mode 100644 index 99c09b34..00000000 --- a/demo/timesync/Makefile +++ /dev/null @@ -1,40 +0,0 @@ -#Makefile to build BACnet Application for the Linux Port - -# tools - only if you need them. -# Most platforms have this already defined -# CC = gcc - -# Executable file name -TARGET = bacts - -TARGET_BIN = ${TARGET}$(TARGET_EXT) - -SRCS = main.c \ - ../object/netport.c \ - ../object/device-client.c - -OBJS = ${SRCS:.c=.o} - -all: ${BACNET_LIB_TARGET} Makefile ${TARGET_BIN} - -${TARGET_BIN}: ${OBJS} Makefile ${BACNET_LIB_TARGET} - ${CC} ${PFLAGS} ${OBJS} ${LFLAGS} -o $@ - size $@ - cp $@ ../../bin - -lib: ${BACNET_LIB_TARGET} - -${BACNET_LIB_TARGET}: - ( cd ${BACNET_LIB_DIR} ; $(MAKE) clean ; $(MAKE) ) - -.c.o: - ${CC} -c ${CFLAGS} $*.c -o $@ - -depend: - rm -f .depend - ${CC} -MM ${CFLAGS} *.c >> .depend - -clean: - rm -f core ${TARGET_BIN} ${OBJS} ${BACNET_LIB_TARGET} $(TARGET).map - -include: .depend diff --git a/demo/timesync/makefile.b32 b/demo/timesync/makefile.b32 deleted file mode 100644 index 2b676438..00000000 --- a/demo/timesync/makefile.b32 +++ /dev/null @@ -1,139 +0,0 @@ -# -# Simple makefile to build an executable for Win32 -# -# This makefile assumes Borland bcc32 development environment -# on Windows NT/9x/2000/XP -# - -!ifndef BORLAND_DIR -BORLAND_DIR_Not_Defined: - @echo . - @echo You must define environment variable BORLAND_DIR to compile. -!endif - -PRODUCT = bacts -PRODUCT_EXE = $(PRODUCT).exe - -# tools -CC = $(BORLAND_DIR)\bin\bcc32 -MAKE=$(BORLAND_DIR)\bin\make.exe -#LINK = $(BORLAND_DIR)\bin\tlink32 -LINK = $(BORLAND_DIR)\bin\ilink32 - -BACNET_LIB_DIR = ..\..\lib -BACNET_LIB = $(BACNET_LIB_DIR)\bacnet.lib - -# directories -BACNET_PORT = ..\..\ports\win32 -BACNET_INCLUDE = ..\..\include -BACNET_OBJECT = ..\object -BACNET_HANDLER = ..\handler -INCLUDES = \ - -I$(BACNET_INCLUDE) \ - -I$(BACNET_PORT) \ - -I$(BACNET_OBJECT) \ - -I$(BACNET_HANDLER) \ - -I$(BORLAND_DIR)\include - -# -BACNET_DEFINES = -DPRINT_ENABLED=1 -DBACAPP_ALL -#BACDL_DEFINE=-DBACDL_MSTP=1 -BACDL_DEFINE=-DBACDL_BIP=1 -DUSE_INADDR=1 -DEFINES = $(BACNET_DEFINES) $(BACDL_DEFINE) - -SRCS = main.c \ - $(BACNET_OBJECT)\device-client.c - -OBJS = $(SRCS:.c=.obj) - -# -# Compiler definitions -# -BCC_CFG = bcc32.cfg - -# -# Include directories -# -CFLAGS = $(INCLUDES) $(DEFINES) - -# -# Libraries -# -C_LIB_DIR = $(BORLAND_DIR)\lib - -LIBS = $(BACNET_LIB) \ - $(C_LIB_DIR)\IMPORT32.lib \ - $(C_LIB_DIR)\CW32MT.lib \ - -# -# Main target -# -# This should be the first one in the makefile - -all : $(BACNET_LIB) $(BCC_CFG) $(OBJS) $(PRODUCT_EXE) - del $(BCC_CFG) - -install: $(PRODUCT_EXE) - copy $(PRODUCT_EXE) ..\..\bin\$(PRODUCT_EXE) - -# Linker specific: the link below is for BCC linker/compiler. If you link -# with a different linker - please change accordingly. -# - -# need a temp response file (@&&| ... |) because command line is too long -# $** lists each dependency -# $< target name -# $* target name without extension -$(PRODUCT_EXE) : $(OBJS) - @echo Running Linker for $(PRODUCT_EXE) - $(LINK) -L$(C_LIB_DIR) -L$(BACNET_LIB_DIR) -m -c -s -v @&&| - $(BORLAND_DIR)\lib\c0x32.obj $** - $< - $*.map - $(LIBS) -| - -# -# Utilities - -clean : - del $(OBJS) - del $(PRODUCT_EXE) - del $(PRODUCT).map - del $(PRODUCT).ilc - del $(PRODUCT).ild - del $(PRODUCT).ilf - del $(PRODUCT).ils - del $(PRODUCT).tds - del $(BCC_CFG) - -# -# Generic rules -# -.SUFFIXES: .cpp .c .sbr .obj - -# -# cc generic rule -# -.c.obj: - $(CC) +$(BCC_CFG) -o$@ $< - -# Compiler configuration file -$(BCC_CFG) : - Copy &&| - $(CFLAGS) - -c - -y #include line numbers in OBJ's - -v #include debug info - -w+ #turn on all warnings - -Od #disable all optimizations - #-a4 #32 bit data alignment - #-M # generate link map - #-ls # linker options - #-WM- #not multithread - -WM #multithread - -w-aus # ignore warning assigned a value that is never used - -w-sig # ignore warning conversion may lose sig digits -| $@ - -# EOF: makefile diff --git a/demo/ucov/Makefile b/demo/ucov/Makefile deleted file mode 100644 index 806e30b7..00000000 --- a/demo/ucov/Makefile +++ /dev/null @@ -1,40 +0,0 @@ -#Makefile to build BACnet Application for the Linux Port - -# tools - only if you need them. -# Most platforms have this already defined -# CC = gcc - -# Executable file name -TARGET = bacucov - -TARGET_BIN = ${TARGET}$(TARGET_EXT) - -SRCS = main.c \ - ../object/netport.c \ - ../object/device-client.c - -OBJS = ${SRCS:.c=.o} - -all: ${BACNET_LIB_TARGET} Makefile ${TARGET_BIN} - -${TARGET_BIN}: ${OBJS} Makefile ${BACNET_LIB_TARGET} - ${CC} ${PFLAGS} ${OBJS} ${LFLAGS} -o $@ - size $@ - cp $@ ../../bin - -lib: ${BACNET_LIB_TARGET} - -${BACNET_LIB_TARGET}: - ( cd ${BACNET_LIB_DIR} ; $(MAKE) clean ; $(MAKE) ) - -.c.o: - ${CC} -c ${CFLAGS} $*.c -o $@ - -depend: - rm -f .depend - ${CC} -MM ${CFLAGS} *.c >> .depend - -clean: - rm -f core ${TARGET_BIN} ${OBJS} ${BACNET_LIB_TARGET} $(TARGET).map - -include: .depend diff --git a/demo/ucov/makefile.b32 b/demo/ucov/makefile.b32 deleted file mode 100644 index c590cbb0..00000000 --- a/demo/ucov/makefile.b32 +++ /dev/null @@ -1,139 +0,0 @@ -# -# Simple makefile to build an executable for Win32 -# -# This makefile assumes Borland bcc32 development environment -# on Windows NT/9x/2000/XP -# - -!ifndef BORLAND_DIR -BORLAND_DIR_Not_Defined: - @echo . - @echo You must define environment variable BORLAND_DIR to compile. -!endif - -PRODUCT = bacucov -PRODUCT_EXE = $(PRODUCT).exe - -# tools -CC = $(BORLAND_DIR)\bin\bcc32 -MAKE=$(BORLAND_DIR)\bin\make.exe -#LINK = $(BORLAND_DIR)\bin\tlink32 -LINK = $(BORLAND_DIR)\bin\ilink32 - -BACNET_LIB_DIR = ..\..\lib -BACNET_LIB = $(BACNET_LIB_DIR)\bacnet.lib - -# directories -BACNET_PORT = ..\..\ports\win32 -BACNET_INCLUDE = ..\..\include -BACNET_OBJECT = ..\object -BACNET_HANDLER = ..\handler -INCLUDES = \ - -I$(BACNET_INCLUDE) \ - -I$(BACNET_PORT) \ - -I$(BACNET_OBJECT) \ - -I$(BACNET_HANDLER) \ - -I$(BORLAND_DIR)\include - -# -BACNET_DEFINES = -DPRINT_ENABLED=1 -DBACAPP_ALL -#BACDL_DEFINE=-DBACDL_MSTP=1 -BACDL_DEFINE=-DBACDL_BIP=1 -DUSE_INADDR=1 -DEFINES = $(BACNET_DEFINES) $(BACDL_DEFINE) - -SRCS = main.c \ - $(BACNET_OBJECT)\device-client.c - -OBJS = $(SRCS:.c=.obj) - -# -# Compiler definitions -# -BCC_CFG = bcc32.cfg - -# -# Include directories -# -CFLAGS = $(INCLUDES) $(DEFINES) - -# -# Libraries -# -C_LIB_DIR = $(BORLAND_DIR)\lib - -LIBS = $(BACNET_LIB) \ - $(C_LIB_DIR)\IMPORT32.lib \ - $(C_LIB_DIR)\CW32MT.lib \ - -# -# Main target -# -# This should be the first one in the makefile - -all : $(BACNET_LIB) $(BCC_CFG) $(OBJS) $(PRODUCT_EXE) - del $(BCC_CFG) - -install: $(PRODUCT_EXE) - copy $(PRODUCT_EXE) ..\..\bin\$(PRODUCT_EXE) - -# Linker specific: the link below is for BCC linker/compiler. If you link -# with a different linker - please change accordingly. -# - -# need a temp response file (@&&| ... |) because command line is too long -# $** lists each dependency -# $< target name -# $* target name without extension -$(PRODUCT_EXE) : $(OBJS) - @echo Running Linker for $(PRODUCT_EXE) - $(LINK) -L$(C_LIB_DIR) -L$(BACNET_LIB_DIR) -m -c -s -v @&&| - $(BORLAND_DIR)\lib\c0x32.obj $** - $< - $*.map - $(LIBS) -| - -# -# Utilities - -clean : - del $(OBJS) - del $(PRODUCT_EXE) - del $(PRODUCT).map - del $(PRODUCT).ilc - del $(PRODUCT).ild - del $(PRODUCT).ilf - del $(PRODUCT).ils - del $(PRODUCT).tds - del $(BCC_CFG) - -# -# Generic rules -# -.SUFFIXES: .cpp .c .sbr .obj - -# -# cc generic rule -# -.c.obj: - $(CC) +$(BCC_CFG) -o$@ $< - -# Compiler configuration file -$(BCC_CFG) : - Copy &&| - $(CFLAGS) - -c - -y #include line numbers in OBJ's - -v #include debug info - -w+ #turn on all warnings - -Od #disable all optimizations - #-a4 #32 bit data alignment - #-M # generate link map - #-ls # linker options - #-WM- #not multithread - -WM #multithread - -w-aus # ignore warning assigned a value that is never used - -w-sig # ignore warning conversion may lose sig digits -| $@ - -# EOF: makefile diff --git a/demo/uevent/Makefile b/demo/uevent/Makefile deleted file mode 100644 index 3f96cc07..00000000 --- a/demo/uevent/Makefile +++ /dev/null @@ -1,40 +0,0 @@ -#Makefile to build BACnet Application with GNU Make - -# tools - only if you need them. -# Most platforms have this already defined -# CC = gcc - -# Executable file name -TARGET = bacuevent - -TARGET_BIN = ${TARGET}$(TARGET_EXT) - -SRCS = main.c \ - ../object/netport.c \ - ../object/device-client.c - -OBJS = ${SRCS:.c=.o} - -all: ${BACNET_LIB_TARGET} Makefile ${TARGET_BIN} - -${TARGET_BIN}: ${OBJS} Makefile ${BACNET_LIB_TARGET} - ${CC} ${PFLAGS} ${OBJS} ${LFLAGS} -o $@ - size $@ - cp $@ ../../bin - -lib: ${BACNET_LIB_TARGET} - -${BACNET_LIB_TARGET}: - ( cd ${BACNET_LIB_DIR} ; $(MAKE) clean ; $(MAKE) ) - -.c.o: - ${CC} -c ${CFLAGS} $*.c -o $@ - -depend: - rm -f .depend - ${CC} -MM ${CFLAGS} *.c >> .depend - -clean: - rm -f core ${TARGET_BIN} ${OBJS} ${BACNET_LIB_TARGET} $(TARGET).map - -include: .depend diff --git a/demo/uptransfer/Makefile b/demo/uptransfer/Makefile deleted file mode 100644 index 4c1b6d1a..00000000 --- a/demo/uptransfer/Makefile +++ /dev/null @@ -1,45 +0,0 @@ -#Makefile to build BACnet Application using GCC compiler - -# tools - only if you need them. -# Most platforms have this already defined -# CC = gcc -# AR = ar -# MAKE = make -# SIZE = size -# -# Assumes rm and cp are available - -# Executable file name -TARGET = bacupt - -TARGET_BIN = ${TARGET}$(TARGET_EXT) - -SRCS = main.c \ - ../object/netport.c \ - ../object/device-client.c - -OBJS = ${SRCS:.c=.o} - -all: ${BACNET_LIB_TARGET} Makefile ${TARGET_BIN} - -${TARGET_BIN}: ${OBJS} Makefile ${BACNET_LIB_TARGET} - ${CC} ${PFLAGS} ${OBJS} ${LFLAGS} -o $@ - size $@ - cp $@ ../../bin - -lib: ${BACNET_LIB_TARGET} - -${BACNET_LIB_TARGET}: - ( cd ${BACNET_LIB_DIR} ; $(MAKE) clean ; $(MAKE) ) - -.c.o: - ${CC} -c ${CFLAGS} $*.c -o $@ - -depend: - rm -f .depend - ${CC} -MM ${CFLAGS} *.c >> .depend - -clean: - rm -rf core ${TARGET_BIN} ${OBJS} ${BACNET_LIB_TARGET} - -include: .depend diff --git a/demo/uptransfer/makefile.b32 b/demo/uptransfer/makefile.b32 deleted file mode 100644 index f0c10cc1..00000000 --- a/demo/uptransfer/makefile.b32 +++ /dev/null @@ -1,143 +0,0 @@ -# -# Simple makefile to build an executable for Win32 -# -# This makefile assumes Borland bcc32 development environment -# on Windows NT/9x/2000/XP -# - -!ifndef BORLAND_DIR -BORLAND_DIR_Not_Defined: - @echo . - @echo You must define environment variable BORLAND_DIR to compile. -!endif - -PRODUCT = bacupt -PRODUCT_EXE = $(PRODUCT).exe - -# tools -CC = $(BORLAND_DIR)\bin\bcc32 -MAKE=$(BORLAND_DIR)\bin\make.exe -#LINK = $(BORLAND_DIR)\bin\tlink32 -LINK = $(BORLAND_DIR)\bin\ilink32 - -BACNET_LIB_DIR = ..\..\lib -BACNET_LIB = $(BACNET_LIB_DIR)\bacnet.lib - -# directories -BACNET_PORT = ..\..\ports\win32 -BACNET_INCLUDE = ..\..\include -BACNET_OBJECT = ..\object -BACNET_HANDLER = ..\handler -INCLUDES = \ - -I$(BACNET_INCLUDE) \ - -I$(BACNET_PORT) \ - -I$(BACNET_OBJECT) \ - -I$(BACNET_HANDLER) \ - -I$(BORLAND_DIR)\include - -# -BACNET_DEFINES = -DPRINT_ENABLED=1 -DBACAPP_ALL -#BACDL_DEFINE=-DBACDL_MSTP=1 -BACDL_DEFINE=-DBACDL_BIP=1 -DUSE_INADDR=1 - -# by default bacupt can handle 64 tag/value pairs -BUILD_DEFINE = -DMAX_PROPERTY_VALUES=64 - -DEFINES = $(BACNET_DEFINES) $(BACDL_DEFINE) $(BUILD_DEFINE) - -SRCS = main.c \ - $(BACNET_OBJECT)\device-client.c - -OBJS = $(SRCS:.c=.obj) - -# -# Compiler definitions -# -BCC_CFG = bcc32.cfg - -# -# Include directories -# -CFLAGS = $(INCLUDES) $(DEFINES) - -# -# Libraries -# -C_LIB_DIR = $(BORLAND_DIR)\lib - -LIBS = $(BACNET_LIB) \ - $(C_LIB_DIR)\IMPORT32.lib \ - $(C_LIB_DIR)\CW32MT.lib \ - -# -# Main target -# -# This should be the first one in the makefile - -all : $(BACNET_LIB) $(BCC_CFG) $(OBJS) $(PRODUCT_EXE) - del $(BCC_CFG) - -install: $(PRODUCT_EXE) - copy $(PRODUCT_EXE) ..\..\bin\$(PRODUCT_EXE) - -# Linker specific: the link below is for BCC linker/compiler. If you link -# with a different linker - please change accordingly. -# - -# need a temp response file (@&&| ... |) because command line is too long -# $** lists each dependency -# $< target name -# $* target name without extension -$(PRODUCT_EXE) : $(OBJS) - @echo Running Linker for $(PRODUCT_EXE) - $(LINK) -L$(C_LIB_DIR) -L$(BACNET_LIB_DIR) -m -c -s -v @&&| - $(BORLAND_DIR)\lib\c0x32.obj $** - $< - $*.map - $(LIBS) -| - -# -# Utilities - -clean : - del $(OBJS) - del $(PRODUCT_EXE) - del $(PRODUCT).map - del $(PRODUCT).ilc - del $(PRODUCT).ild - del $(PRODUCT).ilf - del $(PRODUCT).ils - del $(PRODUCT).tds - del $(BCC_CFG) - -# -# Generic rules -# -.SUFFIXES: .cpp .c .sbr .obj - -# -# cc generic rule -# -.c.obj: - $(CC) +$(BCC_CFG) -o$@ $< - -# Compiler configuration file -$(BCC_CFG) : - Copy &&| - $(CFLAGS) - -c - -y #include line numbers in OBJ's - -v #include debug info - -w+ #turn on all warnings - -Od #disable all optimizations - #-a4 #32 bit data alignment - #-M # generate link map - #-ls # linker options - #-WM- #not multithread - -WM #multithread - -w-aus # ignore warning assigned a value that is never used - -w-sig # ignore warning conversion may lose sig digits -| $@ - -# EOF: makefile diff --git a/demo/whohas/Makefile b/demo/whohas/Makefile deleted file mode 100644 index 39dd148e..00000000 --- a/demo/whohas/Makefile +++ /dev/null @@ -1,40 +0,0 @@ -#Makefile to build BACnet Application for the Linux Port - -# tools - only if you need them. -# Most platforms have this already defined -# CC = gcc - -# Executable file name -TARGET = bacwh - -TARGET_BIN = ${TARGET}$(TARGET_EXT) - -SRCS = main.c \ - ../object/netport.c \ - ../object/device-client.c - -OBJS = ${SRCS:.c=.o} - -all: ${BACNET_LIB_TARGET} Makefile ${TARGET_BIN} - -${TARGET_BIN}: ${OBJS} Makefile ${BACNET_LIB_TARGET} - ${CC} ${PFLAGS} ${OBJS} ${LFLAGS} -o $@ - size $@ - cp $@ ../../bin - -lib: ${BACNET_LIB_TARGET} - -${BACNET_LIB_TARGET}: - ( cd ${BACNET_LIB_DIR} ; $(MAKE) clean ; $(MAKE) ) - -.c.o: - ${CC} -c ${CFLAGS} $*.c -o $@ - -depend: - rm -f .depend - ${CC} -MM ${CFLAGS} *.c >> .depend - -clean: - rm -f core ${TARGET_BIN} ${OBJS} ${BACNET_LIB_TARGET} $(TARGET).map - -include: .depend diff --git a/demo/whohas/makefile.b32 b/demo/whohas/makefile.b32 deleted file mode 100644 index c0f93de9..00000000 --- a/demo/whohas/makefile.b32 +++ /dev/null @@ -1,139 +0,0 @@ -# -# Simple makefile to build an executable for Win32 -# -# This makefile assumes Borland bcc32 development environment -# on Windows NT/9x/2000/XP -# - -!ifndef BORLAND_DIR -BORLAND_DIR_Not_Defined: - @echo . - @echo You must define environment variable BORLAND_DIR to compile. -!endif - -PRODUCT = bacwh -PRODUCT_EXE = $(PRODUCT).exe - -# tools -CC = $(BORLAND_DIR)\bin\bcc32 -MAKE=$(BORLAND_DIR)\bin\make.exe -#LINK = $(BORLAND_DIR)\bin\tlink32 -LINK = $(BORLAND_DIR)\bin\ilink32 - -BACNET_LIB_DIR = ..\..\lib -BACNET_LIB = $(BACNET_LIB_DIR)\bacnet.lib - -# directories -BACNET_PORT = ..\..\ports\win32 -BACNET_INCLUDE = ..\..\include -BACNET_OBJECT = ..\object -BACNET_HANDLER = ..\handler -INCLUDES = \ - -I$(BACNET_INCLUDE) \ - -I$(BACNET_PORT) \ - -I$(BACNET_OBJECT) \ - -I$(BACNET_HANDLER) \ - -I$(BORLAND_DIR)\include - -# -BACNET_DEFINES = -DPRINT_ENABLED=1 -DBACAPP_ALL -#BACDL_DEFINE=-DBACDL_MSTP=1 -BACDL_DEFINE=-DBACDL_BIP=1 -DUSE_INADDR=1 -DEFINES = $(BACNET_DEFINES) $(BACDL_DEFINE) - -SRCS = main.c \ - $(BACNET_OBJECT)\device-client.c - -OBJS = $(SRCS:.c=.obj) - -# -# Compiler definitions -# -BCC_CFG = bcc32.cfg - -# -# Include directories -# -CFLAGS = $(INCLUDES) $(DEFINES) - -# -# Libraries -# -C_LIB_DIR = $(BORLAND_DIR)\lib - -LIBS = $(BACNET_LIB) \ - $(C_LIB_DIR)\IMPORT32.lib \ - $(C_LIB_DIR)\CW32MT.lib \ - -# -# Main target -# -# This should be the first one in the makefile - -all : $(BACNET_LIB) $(BCC_CFG) $(OBJS) $(PRODUCT_EXE) - del $(BCC_CFG) - -install: $(PRODUCT_EXE) - copy $(PRODUCT_EXE) ..\..\bin\$(PRODUCT_EXE) - -# Linker specific: the link below is for BCC linker/compiler. If you link -# with a different linker - please change accordingly. -# - -# need a temp response file (@&&| ... |) because command line is too long -# $** lists each dependency -# $< target name -# $* target name without extension -$(PRODUCT_EXE) : $(OBJS) - @echo Running Linker for $(PRODUCT_EXE) - $(LINK) -L$(C_LIB_DIR) -L$(BACNET_LIB_DIR) -m -c -s -v @&&| - $(BORLAND_DIR)\lib\c0x32.obj $** - $< - $*.map - $(LIBS) -| - -# -# Utilities - -clean : - del $(OBJS) - del $(PRODUCT_EXE) - del $(PRODUCT).map - del $(PRODUCT).ilc - del $(PRODUCT).ild - del $(PRODUCT).ilf - del $(PRODUCT).ils - del $(PRODUCT).tds - del $(BCC_CFG) - -# -# Generic rules -# -.SUFFIXES: .cpp .c .sbr .obj - -# -# cc generic rule -# -.c.obj: - $(CC) +$(BCC_CFG) -o$@ $< - -# Compiler configuration file -$(BCC_CFG) : - Copy &&| - $(CFLAGS) - -c - -y #include line numbers in OBJ's - -v #include debug info - -w+ #turn on all warnings - -Od #disable all optimizations - #-a4 #32 bit data alignment - #-M # generate link map - #-ls # linker options - #-WM- #not multithread - -WM #multithread - -w-aus # ignore warning assigned a value that is never used - -w-sig # ignore warning conversion may lose sig digits -| $@ - -# EOF: makefile diff --git a/demo/whois/Makefile b/demo/whois/Makefile deleted file mode 100644 index 640313bd..00000000 --- a/demo/whois/Makefile +++ /dev/null @@ -1,39 +0,0 @@ -#Makefile to build BACnet Application for the Linux Port - -# tools - only if you need them. -# Most platforms have this already defined -# CC = gcc - -TARGET = bacwi - -TARGET_BIN = ${TARGET}$(TARGET_EXT) - -SRCS = main.c \ - ../object/netport.c \ - ../object/device-client.c - -OBJS = ${SRCS:.c=.o} - -all: ${BACNET_LIB_TARGET} Makefile ${TARGET_BIN} - -${TARGET_BIN}: ${OBJS} Makefile ${BACNET_LIB_TARGET} - ${CC} ${PFLAGS} ${OBJS} ${LFLAGS} -o $@ - size $@ - cp $@ ../../bin - -lib: ${BACNET_LIB_TARGET} - -${BACNET_LIB_TARGET}: - ( cd ${BACNET_LIB_DIR} ; $(MAKE) clean ; $(MAKE) ) - -.c.o: - ${CC} -c ${CFLAGS} $*.c -o $@ - -depend: - rm -f .depend - ${CC} -MM ${CFLAGS} *.c >> .depend - -clean: - rm -f core ${TARGET_BIN} ${OBJS} ${BACNET_LIB_TARGET} $(TARGET).map - -include: .depend diff --git a/demo/whois/bacwi.dsp b/demo/whois/bacwi.dsp deleted file mode 100644 index a1d3fb33..00000000 --- a/demo/whois/bacwi.dsp +++ /dev/null @@ -1,492 +0,0 @@ -# Microsoft Developer Studio Project File - Name="bacwi" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Console Application" 0x0103 - -CFG=bacwi - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "bacwi.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "bacwi.mak" CFG="bacwi - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "bacwi - Win32 Release" (based on "Win32 (x86) Console Application") -!MESSAGE "bacwi - Win32 Debug" (based on "Win32 (x86) Console Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "bacwi - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /W3 /GX /O2 /I "..\..\include" /I "..\..\win32" /D "NDEBUG" /D "BACDL_BIP" /D TSM_ENABLED=0 /D BACDL_BIP=1 /D USE_INADDR=1 /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D PRINT_ENABLED=1 /D BIG_ENDIAN=0 /FD /c -# SUBTRACT CPP /YX -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /subsystem:console /machine:I386 - -!ELSEIF "$(CFG)" == "bacwi - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "..\..\ports\win32" /I "..\..\include" /I "..\..\win32" /D "_DEBUG" /D TSM_ENABLED=1 /D USE_INADDR=0 /D BACDL_BIP=1 /D USE_INADDR=1 /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D PRINT_ENABLED=1 /D BIG_ENDIAN=0 /FR /FD /GZ /c -# SUBTRACT CPP /YX -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept - -!ENDIF - -# Begin Target - -# Name "bacwi - Win32 Release" -# Name "bacwi - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=..\..\src\abort.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\address.c -# End Source File -# Begin Source File - -SOURCE=..\object\ai.c -# End Source File -# Begin Source File - -SOURCE=..\object\ao.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\apdu.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\arf.c -# End Source File -# Begin Source File - -SOURCE=..\object\av.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\bacaddr.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\bacapp.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\bacdcode.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\bacerror.c -# End Source File -# Begin Source File - -SOURCE=..\object\bacfile.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\bacint.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\bacreal.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\bacstr.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\bactext.c -# End Source File -# Begin Source File - -SOURCE=..\object\bi.c -# End Source File -# Begin Source File - -SOURCE="..\..\ports\win32\bip-init.c" -# End Source File -# Begin Source File - -SOURCE=..\..\src\bip.c -# End Source File -# Begin Source File - -SOURCE=..\object\bo.c -# End Source File -# Begin Source File - -SOURCE=..\object\bv.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\bvlc.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\cov.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\crc.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\datetime.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\dcc.c -# End Source File -# Begin Source File - -SOURCE=..\object\device.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\filename.c -# End Source File -# Begin Source File - -SOURCE=..\handler\h_arf.c -# End Source File -# Begin Source File - -SOURCE=..\handler\h_arf_a.c -# End Source File -# Begin Source File - -SOURCE=..\handler\h_cov.c -# End Source File -# Begin Source File - -SOURCE=..\handler\h_iam.c -# End Source File -# Begin Source File - -SOURCE=..\handler\h_rp.c -# End Source File -# Begin Source File - -SOURCE=..\handler\h_rp_a.c -# End Source File -# Begin Source File - -SOURCE=..\handler\h_whois.c -# End Source File -# Begin Source File - -SOURCE=..\handler\h_wp.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\iam.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\indtext.c -# End Source File -# Begin Source File - -SOURCE=..\object\lc.c -# End Source File -# Begin Source File - -SOURCE=..\object\lc.h -# End Source File -# Begin Source File - -SOURCE=..\object\lsp.c -# End Source File -# Begin Source File - -SOURCE=..\object\lsp.h -# End Source File -# Begin Source File - -SOURCE=main.c -# End Source File -# Begin Source File - -SOURCE=..\object\mso.c -# End Source File -# Begin Source File - -SOURCE=..\handler\noserv.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\npdu.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\reject.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\ringbuf.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\rp.c -# End Source File -# Begin Source File - -SOURCE=..\handler\s_rp.c -# End Source File -# Begin Source File - -SOURCE=..\handler\s_whois.c -# End Source File -# Begin Source File - -SOURCE=..\handler\s_wp.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\tsm.c -# End Source File -# Begin Source File - -SOURCE=..\handler\txbuf.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\version.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\whois.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\wp.c -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# Begin Source File - -SOURCE=..\..\include\abort.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\address.h -# End Source File -# Begin Source File - -SOURCE=..\object\ai.h -# End Source File -# Begin Source File - -SOURCE=..\object\ao.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\apdu.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\arcnet.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\bacapp.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\bacdcode.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\bacdef.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\bacenum.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\bacerror.h -# End Source File -# Begin Source File - -SOURCE=..\object\bacfile.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\bacstr.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\bactext.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\bigend.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\bip.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\bits.h -# End Source File -# Begin Source File - -SOURCE=..\object\bo.h -# End Source File -# Begin Source File - -SOURCE=..\object\bv.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\bytes.h -# End Source File -# Begin Source File - -SOURCE=..\handler\client.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\config.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\crc.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\datalink.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\datetime.h -# End Source File -# Begin Source File - -SOURCE=..\object\device.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\ethernet.h -# End Source File -# Begin Source File - -SOURCE=..\handler\handlers.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\iam.h -# End Source File -# Begin Source File - -SOURCE=..\object\mso.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\mstp.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\npdu.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\reject.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\ringbuf.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\rp.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\rs485.h -# End Source File -# Begin Source File - -SOURCE=..\stdbool.h -# End Source File -# Begin Source File - -SOURCE=..\stdint.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\tsm.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\whois.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\wp.h -# End Source File -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# End Group -# End Target -# End Project diff --git a/demo/whois/makefile.b32 b/demo/whois/makefile.b32 deleted file mode 100644 index 468ffda6..00000000 --- a/demo/whois/makefile.b32 +++ /dev/null @@ -1,139 +0,0 @@ -# -# Simple makefile to build an executable for Win32 -# -# This makefile assumes Borland bcc32 development environment -# on Windows NT/9x/2000/XP -# - -!ifndef BORLAND_DIR -BORLAND_DIR_Not_Defined: - @echo . - @echo You must define environment variable BORLAND_DIR to compile. -!endif - -PRODUCT = bacwi -PRODUCT_EXE = $(PRODUCT).exe - -# tools -CC = $(BORLAND_DIR)\bin\bcc32 -MAKE=$(BORLAND_DIR)\bin\make.exe -#LINK = $(BORLAND_DIR)\bin\tlink32 -LINK = $(BORLAND_DIR)\bin\ilink32 - -BACNET_LIB_DIR = ..\..\lib -BACNET_LIB = $(BACNET_LIB_DIR)\bacnet.lib - -# directories -BACNET_PORT = ..\..\ports\win32 -BACNET_INCLUDE = ..\..\include -BACNET_OBJECT = ..\object -BACNET_HANDLER = ..\handler -INCLUDES = \ - -I$(BACNET_INCLUDE) \ - -I$(BACNET_PORT) \ - -I$(BACNET_OBJECT) \ - -I$(BACNET_HANDLER) \ - -I$(BORLAND_DIR)\include - -# -BACNET_DEFINES = -DPRINT_ENABLED=1 -DBACAPP_ALL -#BACDL_DEFINE=-DBACDL_MSTP=1 -BACDL_DEFINE=-DBACDL_BIP=1 -DUSE_INADDR=1 -DEFINES = $(BACNET_DEFINES) $(BACDL_DEFINE) - -SRCS = main.c \ - $(BACNET_OBJECT)\device-client.c - -OBJS = $(SRCS:.c=.obj) - -# -# Compiler definitions -# -BCC_CFG = bcc32.cfg - -# -# Include directories -# -CFLAGS = $(INCLUDES) $(DEFINES) - -# -# Libraries -# -C_LIB_DIR = $(BORLAND_DIR)\lib - -LIBS = $(BACNET_LIB) \ - $(C_LIB_DIR)\IMPORT32.lib \ - $(C_LIB_DIR)\CW32MT.lib \ - -# -# Main target -# -# This should be the first one in the makefile - -all : $(BACNET_LIB) $(BCC_CFG) $(OBJS) $(PRODUCT_EXE) - del $(BCC_CFG) - -install: $(PRODUCT_EXE) - copy $(PRODUCT_EXE) ..\..\bin\$(PRODUCT_EXE) - -# Linker specific: the link below is for BCC linker/compiler. If you link -# with a different linker - please change accordingly. -# - -# need a temp response file (@&&| ... |) because command line is too long -# $** lists each dependency -# $< target name -# $* target name without extension -$(PRODUCT_EXE) : $(OBJS) - @echo Running Linker for $(PRODUCT_EXE) - $(LINK) -L$(C_LIB_DIR) -L$(BACNET_LIB_DIR) -m -c -s -v @&&| - $(BORLAND_DIR)\lib\c0x32.obj $** - $< - $*.map - $(LIBS) -| - -# -# Utilities - -clean : - del $(OBJS) - del $(PRODUCT_EXE) - del $(PRODUCT).map - del $(PRODUCT).ilc - del $(PRODUCT).ild - del $(PRODUCT).ilf - del $(PRODUCT).ils - del $(PRODUCT).tds - del $(BCC_CFG) - -# -# Generic rules -# -.SUFFIXES: .cpp .c .sbr .obj - -# -# cc generic rule -# -.c.obj: - $(CC) +$(BCC_CFG) -o$@ $< - -# Compiler configuration file -$(BCC_CFG) : - Copy &&| - $(CFLAGS) - -c - -y #include line numbers in OBJ's - -v #include debug info - -w+ #turn on all warnings - -Od #disable all optimizations - #-a4 #32 bit data alignment - #-M # generate link map - #-ls # linker options - #-WM- #not multithread - -WM #multithread - -w-aus # ignore warning assigned a value that is never used - -w-sig # ignore warning conversion may lose sig digits -| $@ - -# EOF: makefile diff --git a/demo/whoisrouter/Makefile b/demo/whoisrouter/Makefile deleted file mode 100644 index b48220c1..00000000 --- a/demo/whoisrouter/Makefile +++ /dev/null @@ -1,39 +0,0 @@ -#Makefile to build BACnet Application for the Linux Port - -# tools - only if you need them. -# Most platforms have this already defined -# CC = gcc - -TARGET = bacwir - -TARGET_BIN = ${TARGET}$(TARGET_EXT) - -SRCS = main.c \ - ../object/netport.c \ - ../object/device-client.c - -OBJS = ${SRCS:.c=.o} - -all: ${BACNET_LIB_TARGET} Makefile ${TARGET_BIN} - -${TARGET_BIN}: ${OBJS} Makefile ${BACNET_LIB_TARGET} - ${CC} ${PFLAGS} ${OBJS} ${LFLAGS} -o $@ - size $@ - cp $@ ../../bin - -lib: ${BACNET_LIB_TARGET} - -${BACNET_LIB_TARGET}: - ( cd ${BACNET_LIB_DIR} ; $(MAKE) clean ; $(MAKE) ) - -.c.o: - ${CC} -c ${CFLAGS} $*.c -o $@ - -depend: - rm -f .depend - ${CC} -MM ${CFLAGS} *.c >> .depend - -clean: - rm -f core ${TARGET_BIN} ${OBJS} ${BACNET_LIB_TARGET} $(TARGET).map - -include: .depend diff --git a/demo/whoisrouter/makefile.b32 b/demo/whoisrouter/makefile.b32 deleted file mode 100644 index 18be31d4..00000000 --- a/demo/whoisrouter/makefile.b32 +++ /dev/null @@ -1,140 +0,0 @@ -# -# Simple makefile to build an executable for Win32 -# -# This makefile assumes Borland bcc32 development environment -# on Windows NT/9x/2000/XP -# - -!ifndef BORLAND_DIR -BORLAND_DIR_Not_Defined: - @echo . - @echo You must define environment variable BORLAND_DIR to compile. -!endif - -# target -PRODUCT = bacwir -PRODUCT_EXE = $(PRODUCT).exe - -# tools -CC = $(BORLAND_DIR)\bin\bcc32 -MAKE=$(BORLAND_DIR)\bin\make.exe -#LINK = $(BORLAND_DIR)\bin\tlink32 -LINK = $(BORLAND_DIR)\bin\ilink32 - -BACNET_LIB_DIR = ..\..\lib -BACNET_LIB = $(BACNET_LIB_DIR)\bacnet.lib - -# directories -BACNET_PORT = ..\..\ports\win32 -BACNET_INCLUDE = ..\..\include -BACNET_OBJECT = ..\object -BACNET_HANDLER = ..\handler -INCLUDES = \ - -I$(BACNET_INCLUDE) \ - -I$(BACNET_PORT) \ - -I$(BACNET_OBJECT) \ - -I$(BACNET_HANDLER) \ - -I$(BORLAND_DIR)\include - -# -BACNET_DEFINES = -DPRINT_ENABLED=1 -DBACAPP_ALL -#BACDL_DEFINE=-DBACDL_MSTP=1 -BACDL_DEFINE=-DBACDL_BIP=1 -DUSE_INADDR=1 -DEFINES = $(BACNET_DEFINES) $(BACDL_DEFINE) - -SRCS = main.c \ - $(BACNET_OBJECT)\device-client.c - -OBJS = $(SRCS:.c=.obj) - -# -# Compiler definitions -# -BCC_CFG = bcc32.cfg - -# -# Include directories -# -CFLAGS = $(INCLUDES) $(DEFINES) - -# -# Libraries -# -C_LIB_DIR = $(BORLAND_DIR)\lib - -LIBS = $(BACNET_LIB) \ - $(C_LIB_DIR)\IMPORT32.lib \ - $(C_LIB_DIR)\CW32MT.lib \ - -# -# Main target -# -# This should be the first one in the makefile - -all : $(BACNET_LIB) $(BCC_CFG) $(OBJS) $(PRODUCT_EXE) - del $(BCC_CFG) - -install: $(PRODUCT_EXE) - copy $(PRODUCT_EXE) ..\..\bin\$(PRODUCT_EXE) - -# Linker specific: the link below is for BCC linker/compiler. If you link -# with a different linker - please change accordingly. -# - -# need a temp response file (@&&| ... |) because command line is too long -# $** lists each dependency -# $< target name -# $* target name without extension -$(PRODUCT_EXE) : $(OBJS) - @echo Running Linker for $(PRODUCT_EXE) - $(LINK) -L$(C_LIB_DIR) -L$(BACNET_LIB_DIR) -m -c -s -v @&&| - $(BORLAND_DIR)\lib\c0x32.obj $** - $< - $*.map - $(LIBS) -| - -# -# Utilities - -clean : - del $(OBJS) - del $(PRODUCT_EXE) - del $(PRODUCT).map - del $(PRODUCT).ilc - del $(PRODUCT).ild - del $(PRODUCT).ilf - del $(PRODUCT).ils - del $(PRODUCT).tds - del $(BCC_CFG) - -# -# Generic rules -# -.SUFFIXES: .cpp .c .sbr .obj - -# -# cc generic rule -# -.c.obj: - $(CC) +$(BCC_CFG) -o$@ $< - -# Compiler configuration file -$(BCC_CFG) : - Copy &&| - $(CFLAGS) - -c - -y #include line numbers in OBJ's - -v #include debug info - -w+ #turn on all warnings - -Od #disable all optimizations - #-a4 #32 bit data alignment - #-M # generate link map - #-ls # linker options - #-WM- #not multithread - -WM #multithread - -w-aus # ignore warning assigned a value that is never used - -w-sig # ignore warning conversion may lose sig digits -| $@ - -# EOF: makefile diff --git a/demo/writefile/Makefile b/demo/writefile/Makefile deleted file mode 100644 index a2cee74e..00000000 --- a/demo/writefile/Makefile +++ /dev/null @@ -1,40 +0,0 @@ -#Makefile to build BACnet Application for the Linux Port - -# tools - only if you need them. -# Most platforms have this already defined -# CC = gcc - -# Executable file name -TARGET = bacawf - -TARGET_BIN = ${TARGET}$(TARGET_EXT) - -SRCS = main.c \ - ../object/netport.c \ - ../object/device-client.c - -OBJS = ${SRCS:.c=.o} - -all: ${BACNET_LIB_TARGET} Makefile ${TARGET_BIN} - -${TARGET_BIN}: ${OBJS} Makefile ${BACNET_LIB_TARGET} - ${CC} ${PFLAGS} ${OBJS} ${LFLAGS} -o $@ - size $@ - cp $@ ../../bin - -lib: ${BACNET_LIB_TARGET} - -${BACNET_LIB_TARGET}: - ( cd ${BACNET_LIB_DIR} ; $(MAKE) clean ; $(MAKE) ) - -.c.o: - ${CC} -c ${CFLAGS} $*.c -o $@ - -depend: - rm -f .depend - ${CC} -MM ${CFLAGS} *.c >> .depend - -clean: - rm -f core ${TARGET_BIN} ${OBJS} ${BACNET_LIB_TARGET} $(TARGET).map - -include: .depend diff --git a/demo/writefile/makefile.b32 b/demo/writefile/makefile.b32 deleted file mode 100644 index 61f92549..00000000 --- a/demo/writefile/makefile.b32 +++ /dev/null @@ -1,139 +0,0 @@ -# -# Simple makefile to build an executable for Win32 -# -# This makefile assumes Borland bcc32 development environment -# on Windows NT/9x/2000/XP -# - -!ifndef BORLAND_DIR -BORLAND_DIR_Not_Defined: - @echo . - @echo You must define environment variable BORLAND_DIR to compile. -!endif - -PRODUCT = bacawf -PRODUCT_EXE = $(PRODUCT).exe - -# tools -CC = $(BORLAND_DIR)\bin\bcc32 -MAKE=$(BORLAND_DIR)\bin\make.exe -#LINK = $(BORLAND_DIR)\bin\tlink32 -LINK = $(BORLAND_DIR)\bin\ilink32 - -BACNET_LIB_DIR = ..\..\lib -BACNET_LIB = $(BACNET_LIB_DIR)\bacnet.lib - -# directories -BACNET_PORT = ..\..\ports\win32 -BACNET_INCLUDE = ..\..\include -BACNET_OBJECT = ..\object -BACNET_HANDLER = ..\handler -INCLUDES = \ - -I$(BACNET_INCLUDE) \ - -I$(BACNET_PORT) \ - -I$(BACNET_OBJECT) \ - -I$(BACNET_HANDLER) \ - -I$(BORLAND_DIR)\include - -# -BACNET_DEFINES = -DPRINT_ENABLED=1 -DBACAPP_ALL -#BACDL_DEFINE=-DBACDL_MSTP=1 -BACDL_DEFINE=-DBACDL_BIP=1 -DUSE_INADDR=1 -DEFINES = $(BACNET_DEFINES) $(BACDL_DEFINE) - -SRCS = main.c \ - $(BACNET_OBJECT)\device-client.c - -OBJS = $(SRCS:.c=.obj) - -# -# Compiler definitions -# -BCC_CFG = bcc32.cfg - -# -# Include directories -# -CFLAGS = $(INCLUDES) $(DEFINES) - -# -# Libraries -# -C_LIB_DIR = $(BORLAND_DIR)\lib - -LIBS = $(BACNET_LIB) \ - $(C_LIB_DIR)\IMPORT32.lib \ - $(C_LIB_DIR)\CW32MT.lib \ - -# -# Main target -# -# This should be the first one in the makefile - -all : $(BACNET_LIB) $(BCC_CFG) $(OBJS) $(PRODUCT_EXE) - del $(BCC_CFG) - -install: $(PRODUCT_EXE) - copy $(PRODUCT_EXE) ..\..\bin\$(PRODUCT_EXE) - -# Linker specific: the link below is for BCC linker/compiler. If you link -# with a different linker - please change accordingly. -# - -# need a temp response file (@&&| ... |) because command line is too long -# $** lists each dependency -# $< target name -# $* target name without extension -$(PRODUCT_EXE) : $(OBJS) - @echo Running Linker for $(PRODUCT_EXE) - $(LINK) -L$(C_LIB_DIR) -L$(BACNET_LIB_DIR) -m -c -s -v @&&| - $(BORLAND_DIR)\lib\c0x32.obj $** - $< - $*.map - $(LIBS) -| - -# -# Utilities - -clean : - del $(OBJS) - del $(PRODUCT_EXE) - del $(PRODUCT).map - del $(PRODUCT).ilc - del $(PRODUCT).ild - del $(PRODUCT).ilf - del $(PRODUCT).ils - del $(PRODUCT).tds - del $(BCC_CFG) - -# -# Generic rules -# -.SUFFIXES: .cpp .c .sbr .obj - -# -# cc generic rule -# -.c.obj: - $(CC) +$(BCC_CFG) -o$@ $< - -# Compiler configuration file -$(BCC_CFG) : - Copy &&| - $(CFLAGS) - -c - -y #include line numbers in OBJ's - -v #include debug info - -w+ #turn on all warnings - -Od #disable all optimizations - #-a4 #32 bit data alignment - #-M # generate link map - #-ls # linker options - #-WM- #not multithread - -WM #multithread - -w-aus # ignore warning assigned a value that is never used - -w-sig # ignore warning conversion may lose sig digits -| $@ - -# EOF: makefile diff --git a/demo/writeprop/Makefile b/demo/writeprop/Makefile deleted file mode 100644 index e3890331..00000000 --- a/demo/writeprop/Makefile +++ /dev/null @@ -1,40 +0,0 @@ -#Makefile to build BACnet Application for the Linux Port - -# tools - only if you need them. -# Most platforms have this already defined -# CC = gcc - -# Executable file name -TARGET = bacwp - -TARGET_BIN = ${TARGET}$(TARGET_EXT) - -SRCS = main.c \ - ../object/netport.c \ - ../object/device-client.c - -OBJS = ${SRCS:.c=.o} - -all: ${BACNET_LIB_TARGET} Makefile ${TARGET_BIN} - -${TARGET_BIN}: ${OBJS} Makefile ${BACNET_LIB_TARGET} - ${CC} ${PFLAGS} ${OBJS} ${LFLAGS} -o $@ - size $@ - cp $@ ../../bin - -lib: ${BACNET_LIB_TARGET} - -${BACNET_LIB_TARGET}: - ( cd ${BACNET_LIB_DIR} ; $(MAKE) clean ; $(MAKE) ) - -.c.o: - ${CC} -c ${CFLAGS} $*.c -o $@ - -depend: - rm -f .depend - ${CC} -MM ${CFLAGS} *.c >> .depend - -clean: - rm -f core ${TARGET_BIN} ${OBJS} ${BACNET_LIB_TARGET} $(TARGET).map - -include: .depend diff --git a/demo/writeprop/makefile.b32 b/demo/writeprop/makefile.b32 deleted file mode 100644 index 2ce1d2f5..00000000 --- a/demo/writeprop/makefile.b32 +++ /dev/null @@ -1,143 +0,0 @@ -# -# Simple makefile to build an executable for Win32 -# -# This makefile assumes Borland bcc32 development environment -# on Windows NT/9x/2000/XP -# - -!ifndef BORLAND_DIR -BORLAND_DIR_Not_Defined: - @echo . - @echo You must define environment variable BORLAND_DIR to compile. -!endif - -PRODUCT = bacwp -PRODUCT_EXE = $(PRODUCT).exe - -# tools -CC = $(BORLAND_DIR)\bin\bcc32 -MAKE=$(BORLAND_DIR)\bin\make.exe -#LINK = $(BORLAND_DIR)\bin\tlink32 -LINK = $(BORLAND_DIR)\bin\ilink32 - -BACNET_LIB_DIR = ..\..\lib -BACNET_LIB = $(BACNET_LIB_DIR)\bacnet.lib - -# directories -BACNET_PORT = ..\..\ports\win32 -BACNET_INCLUDE = ..\..\include -BACNET_OBJECT = ..\object -BACNET_HANDLER = ..\handler -INCLUDES = \ - -I$(BACNET_INCLUDE) \ - -I$(BACNET_PORT) \ - -I$(BACNET_OBJECT) \ - -I$(BACNET_HANDLER) \ - -I$(BORLAND_DIR)\include - -# -BACNET_DEFINES = -DPRINT_ENABLED=1 -DBACAPP_ALL -#BACDL_DEFINE=-DBACDL_MSTP=1 -BACDL_DEFINE=-DBACDL_BIP=1 -DUSE_INADDR=1 - -# by default bacwp can handle 64 tag/value pairs -WRITEPROPS_DEFINE = -DMAX_PROPERTY_VALUES=64 - -DEFINES = $(BACNET_DEFINES) $(BACDL_DEFINE) $(WRITEPROPS_DEFINE) - -SRCS = main.c \ - $(BACNET_OBJECT)\device-client.c - -OBJS = $(SRCS:.c=.obj) - -# -# Compiler definitions -# -BCC_CFG = bcc32.cfg - -# -# Include directories -# -CFLAGS = $(INCLUDES) $(DEFINES) - -# -# Libraries -# -C_LIB_DIR = $(BORLAND_DIR)\lib - -LIBS = $(BACNET_LIB) \ - $(C_LIB_DIR)\IMPORT32.lib \ - $(C_LIB_DIR)\CW32MT.lib \ - -# -# Main target -# -# This should be the first one in the makefile - -all : $(BACNET_LIB) $(BCC_CFG) $(OBJS) $(PRODUCT_EXE) - del $(BCC_CFG) - -install: $(PRODUCT_EXE) - copy $(PRODUCT_EXE) ..\..\bin\$(PRODUCT_EXE) - -# Linker specific: the link below is for BCC linker/compiler. If you link -# with a different linker - please change accordingly. -# - -# need a temp response file (@&&| ... |) because command line is too long -# $** lists each dependency -# $< target name -# $* target name without extension -$(PRODUCT_EXE) : $(OBJS) - @echo Running Linker for $(PRODUCT_EXE) - $(LINK) -L$(C_LIB_DIR) -L$(BACNET_LIB_DIR) -m -c -s -v @&&| - $(BORLAND_DIR)\lib\c0x32.obj $** - $< - $*.map - $(LIBS) -| - -# -# Utilities - -clean : - del $(OBJS) - del $(PRODUCT_EXE) - del $(PRODUCT).map - del $(PRODUCT).ilc - del $(PRODUCT).ild - del $(PRODUCT).ilf - del $(PRODUCT).ils - del $(PRODUCT).tds - del $(BCC_CFG) - -# -# Generic rules -# -.SUFFIXES: .cpp .c .sbr .obj - -# -# cc generic rule -# -.c.obj: - $(CC) +$(BCC_CFG) -o$@ $< - -# Compiler configuration file -$(BCC_CFG) : - Copy &&| - $(CFLAGS) - -c - -y #include line numbers in OBJ's - -v #include debug info - -w+ #turn on all warnings - -Od #disable all optimizations - #-a4 #32 bit data alignment - #-M # generate link map - #-ls # linker options - #-WM- #not multithread - -WM #multithread - -w-aus # ignore warning assigned a value that is never used - -w-sig # ignore warning conversion may lose sig digits -| $@ - -# EOF: makefile diff --git a/demo/writepropm/Makefile b/demo/writepropm/Makefile deleted file mode 100644 index 1b6739d4..00000000 --- a/demo/writepropm/Makefile +++ /dev/null @@ -1,40 +0,0 @@ -#Makefile to build BACnet Application for the Linux Port - -# tools - only if you need them. -# Most platforms have this already defined -# CC = gcc - -# Executable file name -TARGET = bacwpm - -TARGET_BIN = ${TARGET}$(TARGET_EXT) - -SRCS = main.c \ - ../object/netport.c \ - ../object/device-client.c - -OBJS = ${SRCS:.c=.o} - -all: ${BACNET_LIB_TARGET} Makefile ${TARGET_BIN} - -${TARGET_BIN}: ${OBJS} Makefile ${BACNET_LIB_TARGET} - ${CC} ${PFLAGS} ${OBJS} ${LFLAGS} -o $@ - size $@ - cp $@ ../../bin - -lib: ${BACNET_LIB_TARGET} - -${BACNET_LIB_TARGET}: - ( cd ${BACNET_LIB_DIR} ; $(MAKE) clean ; $(MAKE) ) - -.c.o: - ${CC} -c ${CFLAGS} $*.c -o $@ - -depend: - rm -f .depend - ${CC} -MM ${CFLAGS} *.c >> .depend - -clean: - rm -f core ${TARGET_BIN} ${OBJS} ${BACNET_LIB_TARGET} $(TARGET).map - -include: .depend diff --git a/doc/README.ubuntu b/doc/README.ubuntu index 512b08df..ff7e6286 100644 --- a/doc/README.ubuntu +++ b/doc/README.ubuntu @@ -1,17 +1,17 @@ -Add the ability to compile, edit, and maintain code - -Here are the compilers and their documents -$ sudo apt-get install build-essential subversion-tools gcc-4.2-doc glibc-doc manpages-dev -$ sudo apt-get install mingw32 mingw32-binutils mingw32-runtime -I need access to subversion and XSLT ChangeLog tools -$ sudo apt-get install subversion-tools -$ sudo apt-get install xsltproc -I install a couple of editors, useful for various things. Kate is already installed. -$ sudo apt-get install scite -$ sudo apt-get install vim-full -Useful tools for cleaning up code, converting comments and line endings, and code statistics: -$ sudo apt-get install splint -$ sudo apt-get install sloccount -$ sudo apt-get install indent -$ sudo apt-get install liwc +Add the ability to compile, edit, and maintain code + +Here are the compilers and their documents +$ sudo apt-get install build-essential subversion-tools gcc-4.2-doc glibc-doc manpages-dev +$ sudo apt-get install mingw32 mingw32-binutils mingw32-runtime +I need access to subversion and XSLT ChangeLog tools +$ sudo apt-get install subversion-tools +$ sudo apt-get install xsltproc +I install a couple of editors, useful for various things. Kate is already installed. +$ sudo apt-get install scite +$ sudo apt-get install vim-full +Useful tools for cleaning up code, converting comments and line endings, and code statistics: +$ sudo apt-get install splint +$ sudo apt-get install sloccount +$ sudo apt-get install indent +$ sudo apt-get install liwc $ sudo apt-get install tofrodos \ No newline at end of file diff --git a/doc/README.utils b/doc/README.utils index 0c6365d4..a3fe5dd2 100644 --- a/doc/README.utils +++ b/doc/README.utils @@ -1,48 +1,48 @@ -There are a dozen or so demo applications that are built -with the default makefiles. These demo applications are -copied to the bin/ directory. They can be used in -scripts and batch files to test BACnet devices or query -information on the BACnet network, as well as simulate -a BACnet device. - -The demo applications make use of Environment Variables -to configure the network. -BACNET_IFACE - interface to use for the datalink layer - For Linux, this is something like eth0 or /dev/ttyS0. - For Windows, this is something like 192.168.0.1 or COM4 - Defaults to NULL. - -BACNET_IP_PORT - BACnet/IP port number. - Defaults to 47808. - -BACNET_BBMD_PORT - BACnet/IP BBMD port number. - Defaults to 47808. - -BACNET_BBMD_TIMETOLIVE - BACnet/IP BBMD time-to-live seconds. - Defaults to 0xFFFF. - -BACNET_BBMD_ADDRESS - dotted IP address or domain name of BBMD. - Attempts to register with the BBMD if this variable is present. - -BACNET_MAX_INFO_FRAMES - BACnet MS/TP max-info-frames parameter. - Defaults to 127. - -BACNET_MSTP_BAUD - BACnet MS/TP baud rate. - Defaults to 38400. - -BACNET_MSTP_MAC - BACnet MS/TP MAC address. - Defaults to 127. - -The demo client applications can also perform static -address binding using the file "address_cache" in the -directory where the application is called (defined -in src/address.c file). The format of the address_cache -is a line by line of device ids and addresses: -55555 AC:10:56:06:BA:C0 26001 19 50 -where: -55555=device id in decimal -AC:10:56:06:BA:C0=MAC address (router address) in hex -26001=DNET network number in decimal -19=DADR MAC address in hex. Use colon to separate multibyte address. -50=Max APDU - +There are a dozen or so demo applications that are built +with the default makefiles. These demo applications are +copied to the bin/ directory. They can be used in +scripts and batch files to test BACnet devices or query +information on the BACnet network, as well as simulate +a BACnet device. + +The demo applications make use of Environment Variables +to configure the network. +BACNET_IFACE - interface to use for the datalink layer + For Linux, this is something like eth0 or /dev/ttyS0. + For Windows, this is something like 192.168.0.1 or COM4 + Defaults to NULL. + +BACNET_IP_PORT - BACnet/IP port number. + Defaults to 47808. + +BACNET_BBMD_PORT - BACnet/IP BBMD port number. + Defaults to 47808. + +BACNET_BBMD_TIMETOLIVE - BACnet/IP BBMD time-to-live seconds. + Defaults to 0xFFFF. + +BACNET_BBMD_ADDRESS - dotted IP address or domain name of BBMD. + Attempts to register with the BBMD if this variable is present. + +BACNET_MAX_INFO_FRAMES - BACnet MS/TP max-info-frames parameter. + Defaults to 127. + +BACNET_MSTP_BAUD - BACnet MS/TP baud rate. + Defaults to 38400. + +BACNET_MSTP_MAC - BACnet MS/TP MAC address. + Defaults to 127. + +The demo client applications can also perform static +address binding using the file "address_cache" in the +directory where the application is called (defined +in src/address.c file). The format of the address_cache +is a line by line of device ids and addresses: +55555 AC:10:56:06:BA:C0 26001 19 50 +where: +55555=device id in decimal +AC:10:56:06:BA:C0=MAC address (router address) in hex +26001=DNET network number in decimal +19=DADR MAC address in hex. Use colon to separate multibyte address. +50=Max APDU + diff --git a/doc/indent/README.md b/doc/indent/README.md index 5fd76fe3..22af135e 100644 --- a/doc/indent/README.md +++ b/doc/indent/README.md @@ -22,15 +22,17 @@ Add the line to `~/.emacs.d/init.el`. Format a source file with `M-x clang-format-region`. ### CLion -* Add the .clang-format file to the Kratos root directory as - explained aboveGo to File->Settings->Tools->External Tools +* Add the .clang-format file to the root directory as + explained above. Go to File->Settings->Tools->External Tools and click on the plus sign. A window should pop up. Choose a name, for example "clang-format" -* For the Tool settings tab I'm using this configuration: - - Program: clang-format (you should use the name of your executable here) - - Parameters: --style=file -i $FileName$ - - Working directory: $FileDir$ -Now, with your file open, you can go to Tools->External tools and run the config above. It basically calls clang-format and does inplace formatting using the style define in the first .clang-format file found in a parent directory. +* For the Tool settings tab use this configuration: + - Program: `clang-format` (use the name of your executable here) + - Parameters: `--style=file -i $FileName$` + - Working directory: `$FileDir$` +With your file open, go to `Tools->External tools` and run the config above. +This calls `clang-format` and does in-place formatting using the style +defined in the first `.clang-format` file found in a parent directory. ### .clang-format file diff --git a/export.sh b/export.sh deleted file mode 100755 index cf0e57c7..00000000 --- a/export.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/sh -# Release helper for this project - -SVN_PROJECT=trunk/bacnet-stack -SVN_BASE_URL=https://svn.code.sf.net/p/bacnet/code/ -SVN_TRUNK_NAME=${SVN_BASE_URL}${SVN_PROJECT} - -if [ -z "$1" ] -then - echo "Usage: `basename $0` export-directory" - echo "Exports HEAD of ${SVN_PROJECT} in Windows CRLF format" - exit 1 -fi - -echo "Getting another clean version out of subversion for Windows zip" -svn export --native-eol CRLF ${SVN_TRUNK_NAME} ${1} -echo "done." - -echo "Complete!" diff --git a/include/bacnet.h b/include/bacnet.h deleted file mode 100644 index ebc77de5..00000000 --- a/include/bacnet.h +++ /dev/null @@ -1,109 +0,0 @@ -/************************************************************************** -* -* Copyright (C) 2012 Steve Karg -* -* Permission is hereby granted, free of charge, to any person obtaining -* a copy of this software and associated documentation files (the -* "Software"), to deal in the Software without restriction, including -* without limitation the rights to use, copy, modify, merge, publish, -* distribute, sublicense, and/or sell copies of the Software, and to -* permit persons to whom the Software is furnished to do so, subject to -* the following conditions: -* -* The above copyright notice and this permission notice shall be included -* in all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*********************************************************************/ -#ifndef BACNET_H -#define BACNET_H - -/** @file bacnet.h This file is designed to reference the entire BACnet stack library */ - -/* core files */ -#include "version.h" -#include "config.h" -#include "address.h" -#include "apdu.h" -#include "bacapp.h" -#include "bacdcode.h" -#include "bacint.h" -#include "bacreal.h" -#include "bacstr.h" -#include "bacdef.h" -#include "bacenum.h" -#include "bacerror.h" -#include "bactext.h" -#include "datalink.h" -#include "indtext.h" -#include "npdu.h" -#include "reject.h" -#include "tsm.h" - -/* services */ -#include "arf.h" -#include "awf.h" -#include "cov.h" -#include "dcc.h" -#include "iam.h" -#include "ihave.h" -#include "rd.h" -#include "rp.h" -#include "rpm.h" -#include "timesync.h" -#include "whohas.h" -#include "whois.h" -#include "wp.h" -#include "event.h" -#include "lso.h" -#include "alarm_ack.h" - -/* required object - note: developer must supply the device.c file - since it is not included in the library. However, the library - references the device.c members via the device.h API. */ -#include "device.h" - -/* demo objects */ -#include "ai.h" -#include "ao.h" -#include "av.h" -#include "bacfile.h" -#include "bi.h" -#include "bo.h" -#include "bv.h" -#include "lc.h" -#include "lsp.h" -#include "mso.h" - -/* demo handlers */ -#include "txbuf.h" -#include "client.h" -#include "handlers.h" - -/* Additions for Doxygen documenting */ -/** - * @mainpage BACnet-stack API Documentation - * This documents the BACnet-Stack API, OS ports, and sample applications.
- * - * - The high-level handler interface can be found in the Modules tab. - * - Specifics for each file can be found in the Files tab. - * - A full list of all functions is provided in the index of the - * Files->Globals subtab. - * - * While all the central files are included in the file list, not all important - * functions have been given the javadoc treatment, nor have Modules (chapters) - * been created yet for all groupings. If you are doing work in an under- - * documented area, please add the javadoc comments at least to the API calls, - * and consider adding doxygen's module grouping for your area of interest. - * - * See doc/README.doxygen for notes on building and extending this document.
- * In particular, if you have graphviz installed, you can enhance this - * documentation by turning on the function call graphs feature. - */ -#endif diff --git a/include/client.h b/include/client.h deleted file mode 100644 index d11734cc..00000000 --- a/include/client.h +++ /dev/null @@ -1,307 +0,0 @@ -/************************************************************************** -* -* Copyright (C) 2006 Steve Karg -* -* Permission is hereby granted, free of charge, to any person obtaining -* a copy of this software and associated documentation files (the -* "Software"), to deal in the Software without restriction, including -* without limitation the rights to use, copy, modify, merge, publish, -* distribute, sublicense, and/or sell copies of the Software, and to -* permit persons to whom the Software is furnished to do so, subject to -* the following conditions: -* -* The above copyright notice and this permission notice shall be included -* in all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -* -*********************************************************************/ -#ifndef CLIENT_H -#define CLIENT_H - -#include -#include -#include -#include "bacdef.h" -#include "apdu.h" -#include "npdu.h" -#include "bacapp.h" -#include "bacenum.h" -#include "rpm.h" -#include "wpm.h" -#include "cov.h" -#include "event.h" -#include "lso.h" -#include "alarm_ack.h" -#include "ptransfer.h" - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/* unconfirmed requests */ - void Send_I_Am( - uint8_t * buffer); - void Send_I_Am_To_Network( - BACNET_ADDRESS * target_address, - uint32_t device_id, - unsigned int max_apdu, - int segmentation, - uint16_t vendor_id); - int iam_encode_pdu( - uint8_t * buffer, - BACNET_ADDRESS * dest, - BACNET_NPDU_DATA * npdu_data); - void Send_I_Am_Unicast( - uint8_t * buffer, - BACNET_ADDRESS * src); - int iam_unicast_encode_pdu( - uint8_t * buffer, - BACNET_ADDRESS * src, - BACNET_ADDRESS * dest, - BACNET_NPDU_DATA * npdu_data); - - void Send_WhoIs( - int32_t low_limit, - int32_t high_limit); - - void Send_WhoIs_Global( - int32_t low_limit, - int32_t high_limit); - - void Send_WhoIs_Local( - int32_t low_limit, - int32_t high_limit); - - void Send_WhoIs_Remote( - BACNET_ADDRESS * target_address, - int32_t low_limit, - int32_t high_limit); - - void Send_WhoIs_To_Network( - BACNET_ADDRESS * target_address, - int32_t low_limit, - int32_t high_limit); - - void Send_WhoHas_Object( - int32_t low_limit, - int32_t high_limit, - BACNET_OBJECT_TYPE object_type, - uint32_t object_instance); - - void Send_WhoHas_Name( - int32_t low_limit, - int32_t high_limit, - const char *object_name); - - void Send_I_Have( - uint32_t device_id, - BACNET_OBJECT_TYPE object_type, - uint32_t object_instance, - BACNET_CHARACTER_STRING * object_name); - - int Send_UCOV_Notify( - uint8_t * buffer, - unsigned buffer_len, - BACNET_COV_DATA * cov_data); - int ucov_notify_encode_pdu( - uint8_t * buffer, - unsigned buffer_len, - BACNET_ADDRESS * dest, - BACNET_NPDU_DATA * npdu_data, - BACNET_COV_DATA * cov_data); - uint8_t Send_COV_Subscribe( - uint32_t device_id, - BACNET_SUBSCRIBE_COV_DATA * cov_data); - -/* returns the invoke ID for confirmed request, or 0 if failed */ - uint8_t Send_GetEvent( - BACNET_ADDRESS * target_address, - BACNET_OBJECT_ID *lastReceivedObjectIdentifier); - uint8_t Send_GetEvent_Global(void); - -/* returns the invoke ID for confirmed request, or 0 if failed */ - uint8_t Send_Read_Property_Request_Address( - BACNET_ADDRESS * dest, - uint16_t max_apdu, - BACNET_OBJECT_TYPE object_type, - uint32_t object_instance, - BACNET_PROPERTY_ID object_property, - uint32_t array_index); - uint8_t Send_Read_Property_Request( - uint32_t device_id, /* destination device */ - BACNET_OBJECT_TYPE object_type, - uint32_t object_instance, - BACNET_PROPERTY_ID object_property, - uint32_t array_index); - uint8_t Send_Read_Property_Multiple_Request( - uint8_t * pdu, - size_t max_pdu, - uint32_t device_id, /* destination device */ - BACNET_READ_ACCESS_DATA * read_access_data); - -/* returns the invoke ID for confirmed request, or 0 if failed */ - uint8_t Send_Write_Property_Request( - uint32_t device_id, /* destination device */ - BACNET_OBJECT_TYPE object_type, - uint32_t object_instance, - BACNET_PROPERTY_ID object_property, - BACNET_APPLICATION_DATA_VALUE * object_value, - uint8_t priority, - uint32_t array_index); - uint8_t Send_Write_Property_Request_Data( - uint32_t device_id, - BACNET_OBJECT_TYPE object_type, - uint32_t object_instance, - BACNET_PROPERTY_ID object_property, - uint8_t * application_data, - int application_data_len, - uint8_t priority, - uint32_t array_index); - uint8_t Send_Write_Property_Multiple_Request( - uint8_t * pdu, - size_t max_pdu, - uint32_t device_id, - BACNET_WRITE_ACCESS_DATA * write_access_data); - -/* returns the invoke ID for confirmed request, or 0 if failed */ - uint8_t Send_Reinitialize_Device_Request( - uint32_t device_id, - BACNET_REINITIALIZED_STATE state, - char *password); - -/* returns the invoke ID for confirmed request, or 0 if failed */ - uint8_t Send_Device_Communication_Control_Request( - uint32_t device_id, - uint16_t timeDuration, /* 0=optional */ - BACNET_COMMUNICATION_ENABLE_DISABLE state, - char *password); /* NULL=optional */ - - void Send_TimeSync( - BACNET_DATE * bdate, - BACNET_TIME * btime); - void Send_TimeSync_Remote( - BACNET_ADDRESS * dest, - BACNET_DATE * bdate, - BACNET_TIME * btime); - void Send_TimeSyncUTC( - BACNET_DATE * bdate, - BACNET_TIME * btime); - void Send_TimeSyncUTC_Remote( - BACNET_ADDRESS * dest, - BACNET_DATE * bdate, - BACNET_TIME * btime); - void Send_TimeSyncUTC_Device(void); - void Send_TimeSync_Device(void); - - uint8_t Send_Atomic_Read_File_Stream( - uint32_t device_id, - uint32_t file_instance, - int fileStartPosition, - unsigned requestedOctetCount); - uint8_t Send_Atomic_Write_File_Stream( - uint32_t device_id, - uint32_t file_instance, - int fileStartPosition, - BACNET_OCTET_STRING * fileData); - - int Send_UEvent_Notify( - uint8_t * buffer, - BACNET_EVENT_NOTIFICATION_DATA * data, - BACNET_ADDRESS * dest); - - uint8_t Send_CEvent_Notify( - uint32_t device_id, - BACNET_EVENT_NOTIFICATION_DATA * data); - - int Send_Network_Layer_Message( - BACNET_NETWORK_MESSAGE_TYPE network_message_type, - BACNET_ADDRESS * dst, - int *iArgs); - void Send_Who_Is_Router_To_Network( - BACNET_ADDRESS * dst, - int dnet); - void Send_I_Am_Router_To_Network( - const int DNET_list[]); - void Send_Reject_Message_To_Network( - BACNET_ADDRESS * dst, - uint8_t reject_reason, - int dnet); - void Send_Initialize_Routing_Table( - BACNET_ADDRESS * dst, - const int DNET_list[]); - void Send_Initialize_Routing_Table_Ack( - BACNET_ADDRESS * dst, - const int DNET_list[]); - - uint8_t Send_Life_Safety_Operation_Data( - uint32_t device_id, - BACNET_LSO_DATA * data); - uint8_t Send_Alarm_Acknowledgement( - uint32_t device_id, - BACNET_ALARM_ACK_DATA * data); - - int Send_UnconfirmedPrivateTransfer( - BACNET_ADDRESS * dest, - BACNET_PRIVATE_TRANSFER_DATA * private_data); - - uint8_t Send_Get_Alarm_Summary_Address( - BACNET_ADDRESS *dest, - uint16_t max_apdu); - - uint8_t Send_Get_Alarm_Summary( - uint32_t device_id); - - uint8_t Send_Get_Event_Information_Address( - BACNET_ADDRESS *dest, - uint16_t max_apdu, - BACNET_OBJECT_ID * lastReceivedObjectIdentifier); - - uint8_t Send_Get_Event_Information( - uint32_t device_id, - BACNET_OBJECT_ID * lastReceivedObjectIdentifier); - - int Send_Abort_To_Network( - uint8_t * buffer, - BACNET_ADDRESS *dest, - uint8_t invoke_id, - BACNET_ABORT_REASON reason, - bool server); - - int abort_encode_pdu( - uint8_t * buffer, - BACNET_ADDRESS * dest, - BACNET_ADDRESS * src, - BACNET_NPDU_DATA * npdu_data, - uint8_t invoke_id, - BACNET_ABORT_REASON reason, - bool server); - - int Send_Error_To_Network( - uint8_t * buffer, - BACNET_ADDRESS *dest, - uint8_t invoke_id, - BACNET_CONFIRMED_SERVICE service, - BACNET_ERROR_CLASS error_class, - BACNET_ERROR_CODE error_code); - - int error_encode_pdu( - uint8_t * buffer, - BACNET_ADDRESS * dest, - BACNET_ADDRESS * src, - BACNET_NPDU_DATA * npdu_data, - uint8_t invoke_id, - BACNET_CONFIRMED_SERVICE service, - BACNET_ERROR_CLASS error_class, - BACNET_ERROR_CODE error_code); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ -#endif diff --git a/include/handlers.h b/include/handlers.h deleted file mode 100644 index d873153e..00000000 --- a/include/handlers.h +++ /dev/null @@ -1,368 +0,0 @@ -/************************************************************************** -* -* Copyright (C) 2005-2006 Steve Karg -* -* Permission is hereby granted, free of charge, to any person obtaining -* a copy of this software and associated documentation files (the -* "Software"), to deal in the Software without restriction, including -* without limitation the rights to use, copy, modify, merge, publish, -* distribute, sublicense, and/or sell copies of the Software, and to -* permit persons to whom the Software is furnished to do so, subject to -* the following conditions: -* -* The above copyright notice and this permission notice shall be included -* in all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -* -*********************************************************************/ -#ifndef HANDLERS_H -#define HANDLERS_H - -#include -#include -#include -#include "bacdef.h" -#include "apdu.h" -#include "bacapp.h" -#include "ptransfer.h" -#include "npdu.h" -#include "rd.h" -#include "rp.h" -#include "rpm.h" -#include "wp.h" -#include "readrange.h" -#include "getevent.h" -#include "get_alarm_sum.h" -#include "alarm_ack.h" - - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - - void handler_unrecognized_service( - uint8_t * service_request, - uint16_t service_len, - BACNET_ADDRESS * dest, - BACNET_CONFIRMED_SERVICE_DATA * service_data); - - void npdu_handler( - BACNET_ADDRESS * src, /* source address */ - uint8_t * pdu, /* PDU data */ - uint16_t pdu_len); /* length PDU */ - - void npdu_handler_cleanup(void); - void npdu_handler_init( - uint16_t bip_net, - uint16_t mstp_net); - void npdu_router_handler( - uint16_t snet, - BACNET_ADDRESS * src, - uint8_t * pdu, - uint16_t pdu_len); - int npdu_router_send_pdu( - uint16_t dnet, - BACNET_ADDRESS * dest, - BACNET_NPDU_DATA * npdu_data, - uint8_t * pdu, - unsigned int pdu_len); - void npdu_router_get_my_address( - uint16_t dnet, - BACNET_ADDRESS * my_address); - - void routing_npdu_handler( - BACNET_ADDRESS * src, - int *DNET_list, - uint8_t * pdu, - uint16_t pdu_len); - - void handler_who_is( - uint8_t * service_request, - uint16_t service_len, - BACNET_ADDRESS * src); - - void handler_who_is_unicast( - uint8_t * service_request, - uint16_t service_len, - BACNET_ADDRESS * src); - - void handler_who_is_bcast_for_routing( - uint8_t * service_request, - uint16_t service_len, - BACNET_ADDRESS * src); - - void handler_who_is_unicast_for_routing( - uint8_t * service_request, - uint16_t service_len, - BACNET_ADDRESS * src); - - void handler_who_has( - uint8_t * service_request, - uint16_t service_len, - BACNET_ADDRESS * src); - - void handler_who_has_for_routing( - uint8_t * service_request, - uint16_t service_len, - BACNET_ADDRESS * src); - - void handler_i_am_add( - uint8_t * service_request, - uint16_t service_len, - BACNET_ADDRESS * src); - - void handler_i_am_bind( - uint8_t * service_request, - uint16_t service_len, - BACNET_ADDRESS * src); - - void handler_read_property( - uint8_t * service_request, - uint16_t service_len, - BACNET_ADDRESS * src, - BACNET_CONFIRMED_SERVICE_DATA * service_data); - - void handler_read_property_ack( - uint8_t * service_request, - uint16_t service_len, - BACNET_ADDRESS * src, - BACNET_CONFIRMED_SERVICE_ACK_DATA * service_data); - - void handler_write_property( - uint8_t * service_request, - uint16_t service_len, - BACNET_ADDRESS * src, - BACNET_CONFIRMED_SERVICE_DATA * service_data); - - void handler_write_property_multiple( - uint8_t * service_request, - uint16_t service_len, - BACNET_ADDRESS * src, - BACNET_CONFIRMED_SERVICE_DATA * service_data); - - bool WPValidateString( - BACNET_APPLICATION_DATA_VALUE * pValue, - int iMaxLen, - bool bEmptyAllowed, - BACNET_ERROR_CLASS * pErrorClass, - BACNET_ERROR_CODE * pErrorCode); - - bool WPValidateArgType( - BACNET_APPLICATION_DATA_VALUE * pValue, - uint8_t ucExpectedType, - BACNET_ERROR_CLASS * pErrorClass, - BACNET_ERROR_CODE * pErrorCode); - - void handler_atomic_read_file( - uint8_t * service_request, - uint16_t service_len, - BACNET_ADDRESS * src, - BACNET_CONFIRMED_SERVICE_DATA * service_data); - - void handler_atomic_read_file_ack( - uint8_t * service_request, - uint16_t service_len, - BACNET_ADDRESS * src, - BACNET_CONFIRMED_SERVICE_ACK_DATA * service_data); - - void handler_atomic_write_file( - uint8_t * service_request, - uint16_t service_len, - BACNET_ADDRESS * src, - BACNET_CONFIRMED_SERVICE_DATA * service_data); - - void handler_reinitialize_device( - uint8_t * service_request, - uint16_t service_len, - BACNET_ADDRESS * src, - BACNET_CONFIRMED_SERVICE_DATA * service_data); - - void handler_device_communication_control( - uint8_t * service_request, - uint16_t service_len, - BACNET_ADDRESS * src, - BACNET_CONFIRMED_SERVICE_DATA * service_data); - void handler_dcc_password_set( - char *new_password); - char *handler_dcc_password(void); - - void handler_i_have( - uint8_t * service_request, - uint16_t service_len, - BACNET_ADDRESS * src); - - /* time synchronization handlers */ - void handler_timesync( - uint8_t * service_request, - uint16_t service_len, - BACNET_ADDRESS * src); - void handler_timesync_utc( - uint8_t * service_request, - uint16_t service_len, - BACNET_ADDRESS * src); - /* time sync master features */ - int handler_timesync_encode_recipients( - uint8_t * apdu, - int max_apdu); - void handler_timesync_task(BACNET_DATE_TIME *bdatetime); - void handler_timesync_init(void); - bool handler_timesync_recipient_write( - BACNET_WRITE_PROPERTY_DATA * wp_data); - uint32_t handler_timesync_interval(void); - bool handler_timesync_interval_set(uint32_t minutes); - uint32_t handler_timesync_interval_offset(void); - bool handler_timesync_interval_offset_set(uint32_t minutes); - bool handler_timesync_interval_align(void); - bool handler_timesync_interval_align_set(bool flag); - bool handler_timesync_recipient_address_set( - unsigned index, - BACNET_ADDRESS * address); - - void handler_read_property_multiple( - uint8_t * service_request, - uint16_t service_len, - BACNET_ADDRESS * src, - BACNET_CONFIRMED_SERVICE_DATA * service_data); - - void handler_read_property_multiple_ack( - uint8_t * service_request, - uint16_t service_len, - BACNET_ADDRESS * src, - BACNET_CONFIRMED_SERVICE_ACK_DATA * service_data); - - /* Decode the received RPM data and make a linked list of the results. */ - int rpm_ack_decode_service_request( - uint8_t * apdu, - int apdu_len, - BACNET_READ_ACCESS_DATA * read_access_data); - /* print the RP Ack data to stdout */ - void rp_ack_print_data( - BACNET_READ_PROPERTY_DATA * data); - /* print the GE Ack data to stdout */ - void ge_ack_print_data(BACNET_GET_EVENT_INFORMATION_DATA * data, uint32_t device_id); - /* print the RPM Ack data to stdout */ - void rpm_ack_print_data( - BACNET_READ_ACCESS_DATA * rpm_data); - - void handler_cov_subscribe( - uint8_t * service_request, - uint16_t service_len, - BACNET_ADDRESS * src, - BACNET_CONFIRMED_SERVICE_DATA * service_data); - bool handler_cov_fsm( - void); - void handler_cov_task( - void); - void handler_cov_timer_seconds( - uint32_t elapsed_seconds); - void handler_cov_init( - void); - int handler_cov_encode_subscriptions( - uint8_t * apdu, - int max_apdu); - - void handler_ucov_notification( - uint8_t * service_request, - uint16_t service_len, - BACNET_ADDRESS * src); - void handler_ccov_notification( - uint8_t * service_request, - uint16_t service_len, - BACNET_ADDRESS * src, - BACNET_CONFIRMED_SERVICE_DATA * service_data); - - void handler_lso( - uint8_t * service_request, - uint16_t service_len, - BACNET_ADDRESS * src, - BACNET_CONFIRMED_SERVICE_DATA * service_data); - - void handler_alarm_ack( - uint8_t * service_request, - uint16_t service_len, - BACNET_ADDRESS * src, - BACNET_CONFIRMED_SERVICE_DATA * service_data); - - void handler_alarm_ack_set( - BACNET_OBJECT_TYPE object_type, - alarm_ack_function pFunction); - - void handler_conf_private_trans( - uint8_t * service_request, - uint16_t service_len, - BACNET_ADDRESS * src, - BACNET_CONFIRMED_SERVICE_DATA * service_data); - - void handler_conf_private_trans_ack( - uint8_t * service_request, - uint16_t service_len, - BACNET_ADDRESS * src, - BACNET_CONFIRMED_SERVICE_ACK_DATA * service_data); - - void handler_unconfirmed_private_transfer( - uint8_t * service_request, - uint16_t service_len, - BACNET_ADDRESS * src); - - void private_transfer_print_data( - BACNET_PRIVATE_TRANSFER_DATA *private_data); - - void handler_read_range( - uint8_t * service_request, - uint16_t service_len, - BACNET_ADDRESS * src, - BACNET_CONFIRMED_SERVICE_DATA * service_data); - - void handler_read_range_ack( - uint8_t * service_request, - uint16_t service_len, - BACNET_ADDRESS * src, - BACNET_CONFIRMED_SERVICE_ACK_DATA * service_data); - - void handler_get_event_information_set( - BACNET_OBJECT_TYPE object_type, - get_event_info_function pFunction); - - void handler_get_event_information( - uint8_t * service_request, - uint16_t service_len, - BACNET_ADDRESS * src, - BACNET_CONFIRMED_SERVICE_DATA * service_data); - - void handler_get_alarm_summary_set( - BACNET_OBJECT_TYPE object_type, - get_alarm_summary_function pFunction); - - void handler_get_alarm_summary( - uint8_t * service_request, - uint16_t service_len, - BACNET_ADDRESS * src, - BACNET_CONFIRMED_SERVICE_DATA * service_data); - - void get_alarm_summary_ack_handler( - uint8_t * service_request, - uint16_t service_len, - BACNET_ADDRESS * src, - BACNET_CONFIRMED_SERVICE_ACK_DATA * service_data); - - void get_event_ack_handler( - uint8_t *service_request, - uint16_t service_len, - BACNET_ADDRESS *src, - BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data); - - -#ifdef __cplusplus -} -#endif /* __cplusplus */ -/** @defgroup MISCHNDLR Miscellaneous Handler Utilities - * Various utilities and functions to support the Handlers. - */ -#endif diff --git a/include/mydata.h b/include/mydata.h deleted file mode 100644 index c81bda6a..00000000 --- a/include/mydata.h +++ /dev/null @@ -1,21 +0,0 @@ -/* Sample data structure for confirmed private transfer - We have a simple data structure which can be written to - and read from by sending a confirmed private transfer - request with the appropriate parameters. - */ - -#define MY_MAX_STR 32 -#define MY_MAX_BLOCK 8 - -#define MY_SVC_READ 0 -#define MY_SVC_WRITE 1 - -#define MY_ERR_OK 0 -#define MY_ERR_BAD_INDEX 1 - -typedef struct MyData { - uint8_t cMyByte1; - uint8_t cMyByte2; - float fMyReal; - int8_t sMyString[MY_MAX_STR + 1]; /* A little extra for the nul */ -} DATABLOCK; diff --git a/lib/Makefile b/lib/Makefile deleted file mode 100644 index 918f78f7..00000000 --- a/lib/Makefile +++ /dev/null @@ -1,225 +0,0 @@ -#Makefile to build BACnet Library with GCC - -# tools - only if you need them. -# Most platforms have this already defined -# CC = gcc -# AR = ar -# MAKE = make -# SIZE = size -# -# Assumes rm and cp are available - -BACNET_PORT_DIR = ../ports/${BACNET_PORT} -BACNET_OBJECT = ../demo/object -BACNET_HANDLER = ../demo/handler -BACNET_CORE = ../src -BACNET_INCLUDE = ../include -# compiler configuration -#STANDARDS = -std=c99 -INCLUDE1 = -I$(BACNET_PORT_DIR) -I$(BACNET_OBJECT) -I$(BACNET_HANDLER) -INCLUDE2 = -I$(BACNET_INCLUDE) -INCLUDES = $(INCLUDE1) $(INCLUDE2) - -# target -TARGET = bacnet -LIBRARY = lib$(TARGET).a - -CORE_SRC = \ - $(BACNET_CORE)/apdu.c \ - $(BACNET_CORE)/npdu.c \ - $(BACNET_CORE)/bacdcode.c \ - $(BACNET_CORE)/bacint.c \ - $(BACNET_CORE)/bacreal.c \ - $(BACNET_CORE)/bacstr.c \ - $(BACNET_CORE)/bacapp.c \ - $(BACNET_CORE)/bacprop.c \ - $(BACNET_CORE)/bactext.c \ - $(BACNET_CORE)/bactimevalue.c \ - $(BACNET_CORE)/datetime.c \ - $(BACNET_CORE)/indtext.c \ - $(BACNET_CORE)/key.c \ - $(BACNET_CORE)/keylist.c \ - $(BACNET_CORE)/proplist.c \ - $(BACNET_CORE)/debug.c \ - $(BACNET_CORE)/bigend.c \ - $(BACNET_CORE)/arf.c \ - $(BACNET_CORE)/awf.c \ - $(BACNET_CORE)/cov.c \ - $(BACNET_CORE)/dcc.c \ - $(BACNET_CORE)/iam.c \ - $(BACNET_CORE)/ihave.c \ - $(BACNET_CORE)/rd.c \ - $(BACNET_CORE)/rp.c \ - $(BACNET_CORE)/rpm.c \ - $(BACNET_CORE)/timesync.c \ - $(BACNET_CORE)/whohas.c \ - $(BACNET_CORE)/whois.c \ - $(BACNET_CORE)/wp.c \ - $(BACNET_CORE)/wpm.c \ - $(BACNET_CORE)/abort.c \ - $(BACNET_CORE)/reject.c \ - $(BACNET_CORE)/bacerror.c \ - $(BACNET_CORE)/ptransfer.c \ - $(BACNET_CORE)/memcopy.c \ - $(BACNET_CORE)/filename.c \ - $(BACNET_CORE)/tsm.c \ - $(BACNET_CORE)/bacaddr.c \ - $(BACNET_CORE)/address.c \ - $(BACNET_CORE)/bacdevobjpropref.c \ - $(BACNET_CORE)/bacpropstates.c \ - $(BACNET_CORE)/alarm_ack.c \ - $(BACNET_CORE)/event.c \ - $(BACNET_CORE)/getevent.c \ - $(BACNET_CORE)/get_alarm_sum.c \ - $(BACNET_CORE)/readrange.c \ - $(BACNET_CORE)/timestamp.c \ - $(BACNET_CORE)/lighting.c \ - $(BACNET_CORE)/bacsec.c \ - $(BACNET_CORE)/access_rule.c \ - $(BACNET_CORE)/assigned_access_rights.c \ - $(BACNET_CORE)/authentication_factor_format.c \ - $(BACNET_CORE)/authentication_factor.c \ - $(BACNET_CORE)/credential_authentication_factor.c \ - $(BACNET_CORE)/version.c - -HANDLER_SRC = \ - $(BACNET_HANDLER)/dlenv.c \ - $(BACNET_HANDLER)/txbuf.c \ - $(BACNET_HANDLER)/noserv.c \ - $(BACNET_HANDLER)/h_npdu.c \ - $(BACNET_HANDLER)/h_whois.c \ - $(BACNET_HANDLER)/h_iam.c \ - $(BACNET_HANDLER)/h_rp.c \ - $(BACNET_HANDLER)/h_rp_a.c \ - $(BACNET_HANDLER)/h_rpm.c \ - $(BACNET_HANDLER)/h_rpm_a.c \ - $(BACNET_HANDLER)/h_rr.c \ - $(BACNET_HANDLER)/h_rr_a.c \ - $(BACNET_HANDLER)/h_wp.c \ - $(BACNET_HANDLER)/h_wpm.c \ - $(BACNET_HANDLER)/h_alarm_ack.c \ - $(BACNET_HANDLER)/h_arf.c \ - $(BACNET_HANDLER)/h_arf_a.c \ - $(BACNET_HANDLER)/h_awf.c \ - $(BACNET_HANDLER)/h_rd.c \ - $(BACNET_HANDLER)/h_dcc.c \ - $(BACNET_HANDLER)/h_ts.c \ - $(BACNET_HANDLER)/h_whohas.c \ - $(BACNET_HANDLER)/h_ihave.c \ - $(BACNET_HANDLER)/h_cov.c \ - $(BACNET_HANDLER)/h_ccov.c \ - $(BACNET_HANDLER)/h_ucov.c \ - $(BACNET_HANDLER)/h_getevent.c \ - $(BACNET_HANDLER)/h_gas_a.c \ - $(BACNET_HANDLER)/h_get_alarm_sum.c \ - $(BACNET_HANDLER)/h_getevent_a.c \ - $(BACNET_HANDLER)/h_pt.c \ - $(BACNET_HANDLER)/h_pt_a.c \ - $(BACNET_HANDLER)/h_upt.c \ - $(BACNET_HANDLER)/s_abort.c \ - $(BACNET_HANDLER)/s_arfs.c \ - $(BACNET_HANDLER)/s_awfs.c \ - $(BACNET_HANDLER)/s_dcc.c \ - $(BACNET_HANDLER)/s_error.c \ - $(BACNET_HANDLER)/s_ihave.c \ - $(BACNET_HANDLER)/s_get_alarm_sum.c \ - $(BACNET_HANDLER)/s_get_event.c \ - $(BACNET_HANDLER)/s_iam.c \ - $(BACNET_HANDLER)/s_cov.c \ - $(BACNET_HANDLER)/s_ptransfer.c \ - $(BACNET_HANDLER)/s_rd.c \ - $(BACNET_HANDLER)/s_rp.c \ - $(BACNET_HANDLER)/s_readrange.c \ - $(BACNET_HANDLER)/s_rpm.c \ - $(BACNET_HANDLER)/s_ts.c \ - $(BACNET_HANDLER)/s_cevent.c \ - $(BACNET_HANDLER)/s_router.c \ - $(BACNET_HANDLER)/s_uevent.c \ - $(BACNET_HANDLER)/s_whohas.c \ - $(BACNET_HANDLER)/s_whois.c \ - $(BACNET_HANDLER)/s_wpm.c \ - $(BACNET_HANDLER)/s_upt.c \ - $(BACNET_HANDLER)/s_wp.c \ - $(BACNET_HANDLER)/s_getevent.c - -PORT_ARCNET_SRC = \ - $(BACNET_PORT_DIR)/arcnet.c - -PORT_MSTP_SRC = \ - $(BACNET_PORT_DIR)/rs485.c \ - $(BACNET_PORT_DIR)/dlmstp.c \ - $(BACNET_PORT_DIR)/timer.c \ - $(BACNET_CORE)/ringbuf.c \ - $(BACNET_CORE)/fifo.c \ - $(BACNET_CORE)/mstp.c \ - $(BACNET_CORE)/mstptext.c \ - $(BACNET_CORE)/crc.c \ - -PORT_ETHERNET_SRC = \ - $(BACNET_PORT_DIR)/ethernet.c - -PORT_BIP_SRC = \ - $(BACNET_PORT_DIR)/bip-init.c \ - $(BACNET_CORE)/bvlc.c \ - $(BACNET_CORE)/bip.c - -PORT_BIP6_SRC = \ - $(BACNET_HANDLER)/h_bbmd6.c \ - $(BACNET_PORT_DIR)/bip6.c \ - $(BACNET_CORE)/vmac.c \ - $(BACNET_CORE)/bvlc6.c - -PORT_ALL_SRC = \ - $(PORT_ARCNET_SRC) \ - $(PORT_MSTP_SRC) \ - $(PORT_ETHERNET_SRC) \ - $(PORT_BIP_SRC) \ - $(PORT_BIP6_SRC) - -ifeq (${BACDL_DEFINE},-DBACDL_BIP=1) -PORT_SRC = ${PORT_BIP_SRC} -endif -ifeq (${BACDL_DEFINE},-DBACDL_BIP6=1) -PORT_SRC = ${PORT_BIP6_SRC} -endif -ifeq (${BACDL_DEFINE},-DBACDL_MSTP=1) -PORT_SRC = ${PORT_MSTP_SRC} -endif -ifeq (${BACDL_DEFINE},-DBACDL_ARCNET=1) -PORT_SRC = ${PORT_ARCNET_SRC} -endif -ifeq (${BACDL_DEFINE},-DBACDL_ETHERNET=1) -PORT_SRC = ${PORT_ETHERNET_SRC} -endif -ifdef BACDL_ALL -PORT_SRC = ${PORT_ALL_SRC} -endif -ifneq (,$(findstring -DBAC_UCI,$(BACNET_DEFINES))) -UCI_SRC = $(BACNET_CORE)/ucix.c -endif - -SRCS = ${CORE_SRC} ${PORT_SRC} ${HANDLER_SRC} - -OBJS = ${SRCS:.c=.o} - -# use local includes, but other values from calling Makefile -CFLAGS = $(WARNINGS) $(DEBUGGING) $(OPTIMIZATION) $(STANDARDS) $(INCLUDES) $(DEFINES) - -all: $(LIBRARY) - -lib: $(LIBRARY) - -$(LIBRARY): $(OBJS) Makefile - $(AR) rcs $@ $(OBJS) - -.c.o: - ${CC} -c ${CFLAGS} $*.c -o $@ - -depend: - rm -f .depend - ${CC} -MM ${CFLAGS} *.c >> .depend - -clean: - rm -rf core $(OBJS) $(LIBRARY) - -include: .depend diff --git a/lib/bacnet.cbp b/lib/bacnet.cbp deleted file mode 100644 index a6f00b3f..00000000 --- a/lib/bacnet.cbp +++ /dev/null @@ -1,436 +0,0 @@ - - - - - - diff --git a/lib/bacnetdll.cbp b/lib/bacnetdll.cbp deleted file mode 100644 index 71978fe5..00000000 --- a/lib/bacnetdll.cbp +++ /dev/null @@ -1,267 +0,0 @@ - - - - - - diff --git a/lib/main.cpp b/lib/main.cpp deleted file mode 100644 index 11ea6ebb..00000000 --- a/lib/main.cpp +++ /dev/null @@ -1,33 +0,0 @@ -#include "main.h" - -/** @file lib/main.cpp Provides DLLMain for Win32 build of library. */ - -// a sample exported function -void SomeFunction(const LPCSTR sometext) -{ - MessageBoxA(0, sometext, "DLL Message", MB_OK | MB_ICONINFORMATION); -} - -BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) -{ - switch (fdwReason) - { - case DLL_PROCESS_ATTACH: - // attach to process - // return FALSE to fail DLL load - break; - - case DLL_PROCESS_DETACH: - // detach from process - break; - - case DLL_THREAD_ATTACH: - // attach to thread - break; - - case DLL_THREAD_DETACH: - // detach from thread - break; - } - return TRUE; // succesful -} diff --git a/lib/main.h b/lib/main.h deleted file mode 100644 index 154c2a02..00000000 --- a/lib/main.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef __MAIN_H__ -#define __MAIN_H__ - -#include - -/* To use this exported function of dll, include this header - * in your project. - */ - -#ifdef BUILD_DLL -#define DLL_EXPORT __declspec(dllexport) -#else -#define DLL_EXPORT __declspec(dllimport) -#endif - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - - void DLL_EXPORT SomeFunction( - const LPCSTR sometext); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ -#endif diff --git a/lib/makefile.b32 b/lib/makefile.b32 deleted file mode 100644 index 71c4d699..00000000 --- a/lib/makefile.b32 +++ /dev/null @@ -1,235 +0,0 @@ -# -# Simple makefile to build a library for Win32 -# -# This makefile assumes Borland bcc32 development environment -# on Windows NT/9x/2000/XP -# - -!ifndef BORLAND_DIR -BORLAND_DIR_Not_Defined: - @echo . - @echo You must define environment variable BORLAND_DIR to compile. -!endif - -TARGET = bacnet -LIBRARY = $(TARGET).lib - -CC = $(BORLAND_DIR)\bin\bcc32 -TLIB = $(BORLAND_DIR)\bin\tlib -MAKE = $(BORLAND_DIR)\bin\make - -BACNET_DEFINES = -DPRINT_ENABLED=1 -DBACFILE -DBACAPP_ALL -BACDL_DEFINE=-DBACDL_BIP=1 -DUSE_INADDR=1 -#BACDL_DEFINE=-DBACDL_MSTP=1 -DEFINES = $(BACNET_DEFINES) $(BACDL_DEFINE) - -# directories -BACNET_PORT = ..\ports\win32 -BACNET_OBJECT = ..\demo\object -BACNET_HANDLER = ..\demo\handler -BACNET_CORE = ..\src -BACNET_INCLUDE = ..\include -INCLUDES = \ - -I$(BACNET_INCLUDE) \ - -I$(BACNET_PORT) \ - -I$(BACNET_OBJECT) \ - -I$(BACNET_HANDLER) - -CORE1_SRC = $(BACNET_CORE)\indtext.c \ - $(BACNET_CORE)\key.c \ - $(BACNET_CORE)\keylist.c \ - $(BACNET_CORE)\proplist.c \ - $(BACNET_CORE)\debug.c \ - $(BACNET_CORE)\bigend.c \ - $(BACNET_CORE)\filename.c \ - $(BACNET_CORE)\memcopy.c \ - $(BACNET_CORE)\version.c - -CORE2_SRC = $(BACNET_CORE)\apdu.c \ - $(BACNET_CORE)\npdu.c \ - $(BACNET_CORE)\bacdcode.c \ - $(BACNET_CORE)\bacint.c \ - $(BACNET_CORE)\bacreal.c \ - $(BACNET_CORE)\bacstr.c \ - $(BACNET_CORE)\bacapp.c \ - $(BACNET_CORE)\bacprop.c \ - $(BACNET_CORE)\bactext.c \ - $(BACNET_CORE)\datetime.c \ - $(BACNET_CORE)\abort.c \ - $(BACNET_CORE)\reject.c \ - $(BACNET_CORE)\bacerror.c \ - $(BACNET_CORE)\tsm.c \ - $(BACNET_CORE)\bacaddr.c \ - $(BACNET_CORE)\address.c - -CORE3_SRC = $(BACNET_CORE)\arf.c \ - $(BACNET_CORE)\awf.c \ - $(BACNET_CORE)\cov.c \ - $(BACNET_CORE)\dcc.c \ - $(BACNET_CORE)\iam.c \ - $(BACNET_CORE)\ihave.c \ - $(BACNET_CORE)\ptransfer.c \ - $(BACNET_CORE)\rd.c \ - $(BACNET_CORE)\rp.c \ - $(BACNET_CORE)\rpm.c \ - $(BACNET_CORE)\timesync.c \ - $(BACNET_CORE)\whohas.c \ - $(BACNET_CORE)\whois.c \ - $(BACNET_CORE)\wp.c \ - $(BACNET_CORE)\wpm.c - -CORE4_SRC = $(BACNET_CORE)\bacdevobjpropref.c \ - $(BACNET_CORE)\bacpropstates.c \ - $(BACNET_CORE)\alarm_ack.c \ - $(BACNET_CORE)\event.c \ - $(BACNET_CORE)\getevent.c \ - $(BACNET_CORE)\readrange.c \ - $(BACNET_CORE)\timestamp.c - -HANDLER_SRC = \ - $(BACNET_HANDLER)\dlenv.c \ - $(BACNET_HANDLER)\txbuf.c \ - $(BACNET_HANDLER)\noserv.c \ - $(BACNET_HANDLER)\h_whois.c \ - $(BACNET_HANDLER)\h_npdu.c \ - $(BACNET_HANDLER)\h_iam.c \ - $(BACNET_HANDLER)\h_rp.c \ - $(BACNET_HANDLER)\h_rp_a.c \ - $(BACNET_HANDLER)\h_rpm.c \ - $(BACNET_HANDLER)\h_rpm_a.c \ - $(BACNET_HANDLER)\h_wp.c \ - $(BACNET_HANDLER)\h_wpm.c \ - $(BACNET_HANDLER)\h_arf.c \ - $(BACNET_HANDLER)\h_arf_a.c \ - $(BACNET_HANDLER)\h_awf.c \ - $(BACNET_HANDLER)\h_rd.c \ - $(BACNET_HANDLER)\h_dcc.c \ - $(BACNET_HANDLER)\h_ts.c \ - $(BACNET_HANDLER)\h_whohas.c \ - $(BACNET_HANDLER)\h_ihave.c \ - $(BACNET_HANDLER)\h_cov.c \ - $(BACNET_HANDLER)\h_ccov.c \ - $(BACNET_HANDLER)\h_ucov.c \ - $(BACNET_HANDLER)\s_arfs.c \ - $(BACNET_HANDLER)\s_awfs.c \ - $(BACNET_HANDLER)\s_dcc.c \ - $(BACNET_HANDLER)\s_ihave.c \ - $(BACNET_HANDLER)\s_iam.c \ - $(BACNET_HANDLER)\s_cov.c \ - $(BACNET_HANDLER)\s_rd.c \ - $(BACNET_HANDLER)\s_router.c \ - $(BACNET_HANDLER)\s_rp.c \ - $(BACNET_HANDLER)\s_rpm.c \ - $(BACNET_HANDLER)\s_ts.c \ - $(BACNET_HANDLER)\s_cevent.c \ - $(BACNET_HANDLER)\s_uevent.c \ - $(BACNET_HANDLER)\s_whohas.c \ - $(BACNET_HANDLER)\s_whois.c \ - $(BACNET_HANDLER)\s_wpm.c \ - $(BACNET_HANDLER)\s_ptransfer.c \ - $(BACNET_HANDLER)\h_upt.c \ - $(BACNET_HANDLER)\h_pt.c \ - $(BACNET_HANDLER)\h_pt_a.c \ - $(BACNET_HANDLER)\h_rr.c \ - $(BACNET_HANDLER)\s_upt.c \ - $(BACNET_HANDLER)\s_wp.c - -OBJECT_SRC = $(BACNET_OBJECT)\device.c \ - $(BACNET_OBJECT)\ai.c \ - $(BACNET_OBJECT)\ao.c \ - $(BACNET_OBJECT)\av.c \ - $(BACNET_OBJECT)\bi.c \ - $(BACNET_OBJECT)\bo.c \ - $(BACNET_OBJECT)\bv.c \ - $(BACNET_OBJECT)\csv.c \ - $(BACNET_OBJECT)\lc.c \ - $(BACNET_OBJECT)\lsp.c \ - $(BACNET_OBJECT)\ms-input.c \ - $(BACNET_OBJECT)\mso.c \ - $(BACNET_OBJECT)\msv.c \ - $(BACNET_OBJECT)\trendlog.c \ - $(BACNET_OBJECT)\bacfile.c - -PORT_SRC = $(BACNET_PORT)\bip-init.c \ - $(BACNET_PORT)\rs485.c \ - $(BACNET_PORT)\dlmstp.c \ - $(BACNET_PORT)\timer.c \ - $(BACNET_CORE)\crc.c \ - $(BACNET_CORE)\mstp.c \ - $(BACNET_CORE)\mstptext.c \ - $(BACNET_CORE)\bvlc.c \ - $(BACNET_CORE)\bip.c - -CORE1_OBJ = ${CORE1_SRC:.c=.obj} -CORE2_OBJ = ${CORE2_SRC:.c=.obj} -CORE3_OBJ = ${CORE3_SRC:.c=.obj} -CORE4_OBJ = ${CORE4_SRC:.c=.obj} -PORT_OBJ = ${PORT_SRC:.c=.obj} -HANDLER_OBJ = ${HANDLER_SRC:.c=.obj} -OBJECT_OBJ = ${OBJECT_SRC:.c=.obj} - -OBJS = ${CORE1_OBJ} \ - ${CORE2_OBJ} \ - ${CORE3_OBJ} \ - ${CORE4_OBJ} \ - ${PORT_OBJ} \ - ${HANDLER_OBJ} \ - ${OBJECT_OBJ} - -DEL = ${OBJS:.obj=.del} - -# Compiler definitions -# -BCC_CFG = bcc32.cfg - -# Include directories -# -INCL_DIRS = -I$(BORLAND_DIR)\include $(INCLUDES) - -CFLAGS = $(INCL_DIRS) $(CS_FLAGS) $(DEFINES) -LFLAGS = /E /P4096 - -# 'all' should be the first one in the makefile - -all: $(BCC_CFG) $(OBJS) makefile.b32 $(LIBRARY) - @echo Finished! - -clean: ${DEL} - del ${LIBRARY} - del ${BCC_CFG} -# -# Generic rules -# -.SUFFIXES: .cpp .c .sbr .obj .del - -# -# cc generic rule -# -.c.obj: - $(CC) +$(BCC_CFG) -o$@ $< - $(TLIB) $(LIBRARY) $(LFLAGS) -+"$@" - -# delete rule - to delete one at a time -.obj.del: - del $** - -# Compiler configuration file -$(BCC_CFG) : - Copy &&| - $(CFLAGS) - -c - -y #include line numbers in OBJ's - -v #include debug info - -w+ #turn on all warnings - -O2 #optimization 2 - -WM #multithread - -w-aus # ignore warning assigned a value that is never used - -w-sig # ignore warning conversion may lose sig digits - #-Od #disable all optimizations - #-a4 #32 bit data alignment - #-M # generate link map - #-ls # linker options - #-WM- #not multithread -| $@ - -# EOF: makefile diff --git a/makefile.b32 b/makefile.b32 deleted file mode 100644 index 275e822d..00000000 --- a/makefile.b32 +++ /dev/null @@ -1,341 +0,0 @@ -# Master Makefile for BACnet Stack demos -# for Borland C++ - -!ifndef BORLAND_DIR -BORLAND_DIR_Not_Defined: - @echo . - @echo You must define environment variable BORLAND_DIR to compile. - @echo Type: set BORLAND_DIR=c:\Borland\bcc55 -!endif - -MAKE=$(BORLAND_DIR)\bin\make.exe - -all: library \ - dcc epics ptransfer \ - readfile readprop readpropm readrange reinit \ - scov server timesync ucov uptransfer \ - whohas whois writefile writeprop \ - mstpcap mstpcrc \ - iamrouter initrouter whoisrouter - @echo "demo utilities are in the bin directory" - -clean: library-clean \ - dcc-clean \ - epics-clean \ - ptransfer-clean \ - readfile-clean \ - readprop-clean \ - readpropm-clean \ - readrange-clean \ - reinit-clean \ - scov-clean \ - server-clean \ - timesync-clean \ - ucov-clean \ - uptransfer-clean \ - whohas-clean \ - whois-clean \ - writefile-clean \ - writeprop-clean \ - mstpcap-clean \ - mstpcrc-clean \ - iamrouter-clean \ - initrouter-clean \ - whoisrouter-clean - @echo "Finished cleaning!" - -library: lib\makefile.b32 - cd lib - $(MAKE) -f makefile.b32 all - cd .. - -library-clean: lib\makefile.b32 - cd lib - $(MAKE) -f makefile.b32 clean - cd .. - -dcc: demo/dcc/makefile.b32 - cd demo/dcc - $(MAKE) -f makefile.b32 all - $(MAKE) -f makefile.b32 install - cd .. - cd .. - -dcc-clean: demo/dcc/makefile.b32 - cd demo/dcc - $(MAKE) -f makefile.b32 clean - cd .. - cd .. - -epics: demo/epics/makefile.b32 - cd demo/epics - $(MAKE) -f makefile.b32 all - $(MAKE) -f makefile.b32 install - cd .. - cd .. - -epics-clean: demo/epics/makefile.b32 - cd demo/epics - $(MAKE) -f makefile.b32 clean - cd .. - cd .. - -ptransfer: demo/ptransfer/makefile.b32 - cd demo/ptransfer - $(MAKE) -f makefile.b32 all - $(MAKE) -f makefile.b32 install - cd .. - cd .. - -ptransfer-clean: demo/ptransfer/makefile.b32 - cd demo/ptransfer - $(MAKE) -f makefile.b32 clean - cd .. - cd .. - -readfile: demo/readfile/makefile.b32 - cd demo/readfile - $(MAKE) -f makefile.b32 all - $(MAKE) -f makefile.b32 install - cd .. - cd .. - -readfile-clean: demo/readfile/makefile.b32 - cd demo/readfile - $(MAKE) -f makefile.b32 clean - cd .. - cd .. - -readprop: demo/readprop/makefile.b32 - cd demo/readprop - $(MAKE) -f makefile.b32 all - $(MAKE) -f makefile.b32 install - cd .. - cd .. - -readprop-clean: demo/readprop/makefile.b32 - cd demo/readprop - $(MAKE) -f makefile.b32 clean - cd .. - cd .. - -readpropm: demo/readpropm/makefile.b32 - cd demo/readpropm - $(MAKE) -f makefile.b32 all - $(MAKE) -f makefile.b32 install - cd .. - cd .. - -readpropm-clean: demo/readpropm/makefile.b32 - cd demo/readpropm - $(MAKE) -f makefile.b32 clean - cd .. - cd .. - -readrange: demo/readpropm/makefile.b32 - cd demo/readpropm - $(MAKE) -f makefile.b32 all - $(MAKE) -f makefile.b32 install - cd .. - cd .. - -readrange-clean: demo/readpropm/makefile.b32 - cd demo/readpropm - $(MAKE) -f makefile.b32 clean - cd .. - cd .. - -reinit: demo/reinit/makefile.b32 - cd demo/reinit - $(MAKE) -f makefile.b32 all - $(MAKE) -f makefile.b32 install - cd .. - cd .. - -reinit-clean: demo/reinit/makefile.b32 - cd demo/reinit - $(MAKE) -f makefile.b32 clean - cd .. - cd .. - -scov: demo/scov/makefile.b32 - cd demo/scov - $(MAKE) -f makefile.b32 all - $(MAKE) -f makefile.b32 install - cd .. - cd .. - -scov-clean: demo/scov/makefile.b32 - cd demo/scov - $(MAKE) -f makefile.b32 clean - cd .. - cd .. - -server: demo/server/makefile.b32 - cd demo/server - $(MAKE) -f makefile.b32 all - $(MAKE) -f makefile.b32 install - cd .. - cd .. - -server-clean: demo/server/makefile.b32 - cd demo/server - $(MAKE) -f makefile.b32 clean - cd .. - cd .. - -timesync: demo/timesync/makefile.b32 - cd demo/timesync - $(MAKE) -f makefile.b32 all - $(MAKE) -f makefile.b32 install - cd .. - cd .. - -timesync-clean: demo/timesync/makefile.b32 - cd demo/timesync - $(MAKE) -f makefile.b32 clean - cd .. - cd .. - -ucov: demo/ucov/makefile.b32 - cd demo/ucov - $(MAKE) -f makefile.b32 all - $(MAKE) -f makefile.b32 install - cd .. - cd .. - -ucov-clean: demo/ucov/makefile.b32 - cd demo/ucov - $(MAKE) -f makefile.b32 clean - cd .. - cd .. - -uptransfer: demo/uptransfer/makefile.b32 - cd demo/uptransfer - $(MAKE) -f makefile.b32 all - $(MAKE) -f makefile.b32 install - cd .. - cd .. - -uptransfer-clean: demo/uptransfer/makefile.b32 - cd demo/uptransfer - $(MAKE) -f makefile.b32 clean - cd .. - cd .. - -whohas: demo/whohas/makefile.b32 - cd demo/whohas - $(MAKE) -f makefile.b32 all - $(MAKE) -f makefile.b32 install - cd .. - cd .. - -whohas-clean: demo/whohas/makefile.b32 - cd demo/whohas - $(MAKE) -f makefile.b32 clean - cd .. - cd .. - -whois: demo/whois/makefile.b32 - cd demo/whois - $(MAKE) -f makefile.b32 all - $(MAKE) -f makefile.b32 install - cd .. - cd .. - -whois-clean: demo/whois/makefile.b32 - cd demo/whois - $(MAKE) -f makefile.b32 clean - cd .. - cd .. - -writefile: demo/writefile/makefile.b32 - cd demo/writefile - $(MAKE) -f makefile.b32 all - $(MAKE) -f makefile.b32 install - cd .. - cd .. - -writefile-clean: demo/writefile/makefile.b32 - cd demo/writefile - $(MAKE) -f makefile.b32 clean - cd .. - cd .. - -writeprop: demo/writeprop/makefile.b32 - cd demo/writeprop - $(MAKE) -f makefile.b32 all - $(MAKE) -f makefile.b32 install - cd .. - cd .. - -writeprop-clean: demo/writeprop/makefile.b32 - cd demo/writeprop - $(MAKE) -f makefile.b32 clean - cd .. - cd .. - -mstpcap: demo/mstpcap/makefile.b32 - cd demo/mstpcap - $(MAKE) -f makefile.b32 all - $(MAKE) -f makefile.b32 install - cd .. - cd .. - -mstpcap-clean: demo/mstpcap/makefile.b32 - cd demo/mstpcap - $(MAKE) -f makefile.b32 clean - cd .. - cd .. - -mstpcrc: demo/mstpcrc/makefile.b32 - cd demo/mstpcrc - $(MAKE) -f makefile.b32 all - $(MAKE) -f makefile.b32 install - cd .. - cd .. - -mstpcrc-clean: demo/mstpcrc/makefile.b32 - cd demo/mstpcrc - $(MAKE) -f makefile.b32 clean - cd .. - cd .. - -whoisrouter: demo/whoisrouter/makefile.b32 - cd demo/whoisrouter - $(MAKE) -f makefile.b32 all - $(MAKE) -f makefile.b32 install - cd .. - cd .. - -whoisrouter-clean: demo/whoisrouter/makefile.b32 - cd demo/whoisrouter - $(MAKE) -f makefile.b32 clean - cd .. - cd .. - -iamrouter: demo/iamrouter/makefile.b32 - cd demo/iamrouter - $(MAKE) -f makefile.b32 all - $(MAKE) -f makefile.b32 install - cd .. - cd .. - -iamrouter-clean: demo/iamrouter/makefile.b32 - cd demo/iamrouter - $(MAKE) -f makefile.b32 clean - cd .. - cd .. - -initrouter: demo/initrouter/makefile.b32 - cd demo/initrouter - $(MAKE) -f makefile.b32 all - $(MAKE) -f makefile.b32 install - cd .. - cd .. - -initrouter-clean: demo/initrouter/makefile.b32 - cd demo/initrouter - $(MAKE) -f makefile.b32 clean - cd .. - cd .. diff --git a/ports/arduino_uno/apdu.c b/ports/arduino_uno/apdu.c index b8a5b911..ec767c89 100644 --- a/ports/arduino_uno/apdu.c +++ b/ports/arduino_uno/apdu.c @@ -34,12 +34,12 @@ #include #include #include -#include "bits.h" -#include "apdu.h" -#include "bacdef.h" -#include "bacdcode.h" -#include "bacenum.h" -#include "handlers.h" +#include "bacnet/bits.h" +#include "bacnet/apdu.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacenum.h" +#include "bacnet/basic/services.h" bool apdu_service_supported(BACNET_SERVICES_SUPPORTED service_supported) { diff --git a/ports/arduino_uno/av.c b/ports/arduino_uno/av.c index e38af7e4..d7094e10 100644 --- a/ports/arduino_uno/av.c +++ b/ports/arduino_uno/av.c @@ -27,13 +27,13 @@ #include #include -#include "bacdef.h" -#include "bacdcode.h" -#include "bacenum.h" -#include "bacapp.h" -#include "config.h" /* the custom stuff */ -#include "wp.h" -#include "av.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacenum.h" +#include "bacnet/bacapp.h" +#include "bacnet/config.h" /* the custom stuff */ +#include "bacnet/wp.h" +#include "bacnet/basic/object/av.h" #if (MAX_ANALOG_VALUES > 10) #error Modify the Analog_Value_Name to handle multiple digits diff --git a/ports/arduino_uno/av.h b/ports/arduino_uno/av.h index eb21f962..a1b7c3b4 100644 --- a/ports/arduino_uno/av.h +++ b/ports/arduino_uno/av.h @@ -27,9 +27,9 @@ #include #include -#include "bacdef.h" -#include "bacerror.h" -#include "wp.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacerror.h" +#include "bacnet/wp.h" #ifndef MAX_ANALOG_VALUES #define MAX_ANALOG_VALUES 4 diff --git a/ports/arduino_uno/bip-init.c b/ports/arduino_uno/bip-init.c index 8fcf78ea..84c1cc8a 100644 --- a/ports/arduino_uno/bip-init.c +++ b/ports/arduino_uno/bip-init.c @@ -35,11 +35,11 @@ #include /* for standard integer types uint8_t etc. */ #include /* for the standard bool type. */ #include -#include "bacdcode.h" -#include "bip.h" +#include "bacnet/bacdcode.h" +#include "bacnet/datalink/bip.h" #include "socketWrapper.h" #include "w5100Wrapper.h" -//#include "net.h" +//#include "bacport.h" /** @file linux/bip-init.c Initializes BACnet/IP interface (Linux). */ diff --git a/ports/arduino_uno/bip.c b/ports/arduino_uno/bip.c index 9116378d..038331d1 100644 --- a/ports/arduino_uno/bip.c +++ b/ports/arduino_uno/bip.c @@ -35,9 +35,9 @@ #include /* for standard integer types uint8_t etc. */ #include /* for the standard bool type. */ #include -#include "bacdcode.h" -#include "bacint.h" -#include "bip.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacint.h" +#include "bacnet/datalink/bip.h" #include "bvlc-arduino.h" #include "socketWrapper.h" #include "w5100Wrapper.h" diff --git a/ports/arduino_uno/bip.h b/ports/arduino_uno/bip.h index 34b70700..7bbef39e 100644 --- a/ports/arduino_uno/bip.h +++ b/ports/arduino_uno/bip.h @@ -27,8 +27,8 @@ #include #include #include -#include "bacdef.h" -#include "npdu.h" +#include "bacnet/bacdef.h" +#include "bacnet/npdu.h" /* specific defines for BACnet/IP over Ethernet */ #define MAX_HEADER (1 + 1 + 2) diff --git a/ports/arduino_uno/bv.c b/ports/arduino_uno/bv.c index b3f57b42..3931ff52 100644 --- a/ports/arduino_uno/bv.c +++ b/ports/arduino_uno/bv.c @@ -28,12 +28,12 @@ #include #include #include -#include "bacdef.h" -#include "bacdcode.h" -#include "bacenum.h" -#include "config.h" /* the custom stuff */ -#include "wp.h" -#include "bv.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacenum.h" +#include "bacnet/config.h" /* the custom stuff */ +#include "bacnet/wp.h" +#include "bacnet/basic/object/bv.h" #if (MAX_BINARY_VALUES > 10) #error Modify the Binary_Value_Name to handle multiple digits diff --git a/ports/arduino_uno/bv.h b/ports/arduino_uno/bv.h index b5e26bad..1bb14852 100644 --- a/ports/arduino_uno/bv.h +++ b/ports/arduino_uno/bv.h @@ -27,9 +27,9 @@ #include #include -#include "bacdef.h" -#include "bacerror.h" -#include "wp.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacerror.h" +#include "bacnet/wp.h" #ifndef MAX_BINARY_VALUES #define MAX_BINARY_VALUES 10 diff --git a/ports/arduino_uno/bvlc-arduino.c b/ports/arduino_uno/bvlc-arduino.c index b3c50dcc..e7e8c60f 100644 --- a/ports/arduino_uno/bvlc-arduino.c +++ b/ports/arduino_uno/bvlc-arduino.c @@ -9,8 +9,8 @@ #include #include "bvlc-arduino.h" -#include "bip.h" -#include "bacint.h" +#include "bacnet/datalink/bip.h" +#include "bacnet/bacint.h" #include "socketWrapper.h" #include "w5100Wrapper.h" diff --git a/ports/arduino_uno/bvlc-arduino.h b/ports/arduino_uno/bvlc-arduino.h index 695f8973..9f5e592f 100644 --- a/ports/arduino_uno/bvlc-arduino.h +++ b/ports/arduino_uno/bvlc-arduino.h @@ -8,9 +8,9 @@ #define BVLCARDUINO_H_ #include -#include "bacenum.h" -#include "bacdef.h" -#include "npdu.h" +#include "bacnet/bacenum.h" +#include "bacnet/bacdef.h" +#include "bacnet/npdu.h" #ifdef __cplusplus extern "C" { diff --git a/ports/arduino_uno/datalink.h b/ports/arduino_uno/datalink.h index 23f62ac5..f5daeef2 100644 --- a/ports/arduino_uno/datalink.h +++ b/ports/arduino_uno/datalink.h @@ -24,11 +24,11 @@ #ifndef DATALINK_H #define DATALINK_H -#include "config.h" -#include "bacdef.h" +#include "bacnet/config.h" +#include "bacnet/bacdef.h" #if defined(BACDL_ETHERNET) -#include "ethernet.h" +#include "bacnet/datalink/ethernet.h" #define datalink_init ethernet_init #define datalink_send_pdu ethernet_send_pdu @@ -38,7 +38,7 @@ #define datalink_get_my_address ethernet_get_my_address #elif defined(BACDL_ARCNET) -#include "arcnet.h" +#include "bacnet/datalink/arcnet.h" #define datalink_init arcnet_init #define datalink_send_pdu arcnet_send_pdu @@ -48,7 +48,7 @@ #define datalink_get_my_address arcnet_get_my_address #elif defined(BACDL_MSTP) -#include "dlmstp.h" +#include "bacnet/datalink/dlmstp.h" #define datalink_init dlmstp_init #define datalink_send_pdu dlmstp_send_pdu @@ -58,7 +58,7 @@ #define datalink_get_my_address dlmstp_get_my_address #elif defined(BACDL_BIP) -#include "bip.h" +#include "bacnet/datalink/bip.h" #include "bvlc-arduino.h" #define datalink_init bip_init @@ -79,7 +79,7 @@ extern void routed_get_my_address(BACNET_ADDRESS * my_address); #endif #else /* Ie, BACDL_ALL */ -#include "npdu.h" +#include "bacnet/npdu.h" #define MAX_HEADER (8) #define MAX_MPDU (MAX_HEADER+MAX_PDU) diff --git a/ports/arduino_uno/device.c b/ports/arduino_uno/device.c index 815edc46..0c7d5ff7 100644 --- a/ports/arduino_uno/device.c +++ b/ports/arduino_uno/device.c @@ -25,20 +25,20 @@ #include #include -#include "bacdef.h" -#include "bacdcode.h" -#include "bacstr.h" -#include "bacenum.h" -#include "apdu.h" -#include "dcc.h" -#include "dlmstp.h" -#include "version.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacstr.h" +#include "bacnet/bacenum.h" +#include "bacnet/apdu.h" +#include "bacnet/dcc.h" +#include "bacnet/datalink/dlmstp.h" +#include "bacnet/version.h" /* objects */ -#include "device.h" -#include "av.h" -#include "bv.h" -#include "wp.h" +#include "bacnet/basic/object/device.h" +#include "bacnet/basic/object/av.h" +#include "bacnet/basic/object/bv.h" +#include "bacnet/wp.h" /* note: you really only need to define variables for properties that are writable or that may change. diff --git a/ports/arduino_uno/device.h b/ports/arduino_uno/device.h index 48b31f7b..56513612 100644 --- a/ports/arduino_uno/device.h +++ b/ports/arduino_uno/device.h @@ -36,10 +36,10 @@ #include #include -#include "bacdef.h" -#include "bacenum.h" -#include "wp.h" -#include "readrange.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacenum.h" +#include "bacnet/wp.h" +#include "bacnet/readrange.h" typedef unsigned (*object_count_function) (void); typedef uint32_t(*object_index_to_instance_function) diff --git a/ports/arduino_uno/h_rp.c b/ports/arduino_uno/h_rp.c index cc3a60f0..45d80ae9 100644 --- a/ports/arduino_uno/h_rp.c +++ b/ports/arduino_uno/h_rp.c @@ -27,19 +27,19 @@ #include #include #include -#include "config.h" -#include "txbuf.h" -#include "bacdef.h" -#include "bacdcode.h" -#include "bacerror.h" -#include "apdu.h" -#include "npdu.h" +#include "bacnet/config.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacerror.h" +#include "bacnet/apdu.h" +#include "bacnet/npdu.h" #include "abort.h" -#include "rp.h" +#include "bacnet/rp.h" /* demo objects */ -#include "device.h" -#include "av.h" -#include "bv.h" +#include "bacnet/basic/object/device.h" +#include "bacnet/basic/object/av.h" +#include "bacnet/basic/object/bv.h" /* Encodes the property APDU and returns the length, or sets the error, and returns -1 */ diff --git a/ports/arduino_uno/h_whois.c b/ports/arduino_uno/h_whois.c index 0bab386d..b4f36caf 100644 --- a/ports/arduino_uno/h_whois.c +++ b/ports/arduino_uno/h_whois.c @@ -27,15 +27,15 @@ #include #include #include -#include "config.h" -#include "txbuf.h" -#include "bacdef.h" -#include "bacdcode.h" -#include "whois.h" -#include "iam.h" -#include "device.h" -#include "client.h" -#include "txbuf.h" +#include "bacnet/config.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/whois.h" +#include "bacnet/iam.h" +#include "bacnet/basic/object/device.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/tsm/tsm.h" bool Send_I_Am_Flag = true; diff --git a/ports/arduino_uno/h_wp.c b/ports/arduino_uno/h_wp.c index 0936490f..5cfc3b56 100644 --- a/ports/arduino_uno/h_wp.c +++ b/ports/arduino_uno/h_wp.c @@ -27,19 +27,19 @@ #include #include #include -#include "config.h" -#include "txbuf.h" -#include "bacdef.h" -#include "bacdcode.h" -#include "bacerror.h" -#include "apdu.h" -#include "npdu.h" +#include "bacnet/config.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacerror.h" +#include "bacnet/apdu.h" +#include "bacnet/npdu.h" #include "abort.h" -#include "wp.h" +#include "bacnet/wp.h" /* demo objects */ -#include "device.h" -#include "av.h" -#include "bv.h" +#include "bacnet/basic/object/device.h" +#include "bacnet/basic/object/av.h" +#include "bacnet/basic/object/bv.h" /* too big to reside on stack frame for PIC */ static BACNET_WRITE_PROPERTY_DATA wp_data; diff --git a/ports/arduino_uno/main.c b/ports/arduino_uno/main.c index 455497c3..4d40b3c6 100644 --- a/ports/arduino_uno/main.c +++ b/ports/arduino_uno/main.c @@ -14,13 +14,13 @@ */ #include #include -#include "datalink.h" -#include "npdu.h" -#include "handlers.h" -#include "txbuf.h" -#include "iam.h" -#include "device.h" -#include "av.h" +#include "bacnet/datalink/datalink.h" +#include "bacnet/npdu.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/iam.h" +#include "bacnet/basic/object/device.h" +#include "bacnet/basic/object/av.h" #include "uart.h" #include "w5100Wrapper.h" #include "Arduino.h" diff --git a/ports/arduino_uno/txbuf.h b/ports/arduino_uno/txbuf.h index bb7d8955..7c474cb0 100644 --- a/ports/arduino_uno/txbuf.h +++ b/ports/arduino_uno/txbuf.h @@ -27,8 +27,8 @@ #include #include -#include "config.h" -#include "datalink.h" +#include "bacnet/config.h" +#include "bacnet/datalink/datalink.h" extern uint8_t Handler_Transmit_Buffer[MAX_PDU]; diff --git a/ports/at91sam7s/.gdbinit b/ports/at91sam7s/.gdbinit index 6b6f0d8d..c4ada8f8 100644 --- a/ports/at91sam7s/.gdbinit +++ b/ports/at91sam7s/.gdbinit @@ -1,16 +1,16 @@ -# gdb setup for J-Link - start JLinkGDBServer first -target remote localhost:2331 -monitor reset -monitor speed 5 -monitor speed auto -monitor long 0xffffff60 0x00320100 -monitor long 0xfffffd44 0xa0008000 -monitor long 0xfffffc20 0xa0000601 -monitor sleep 100 -monitor long 0xfffffc2c 0x00480a0e -monitor sleep 200 -monitor long 0xfffffc30 0x7 -monitor sleep 100 -monitor long 0xfffffd08 0xa5000401 -monitor sleep 100 - +# gdb setup for J-Link - start JLinkGDBServer first +target remote localhost:2331 +monitor reset +monitor speed 5 +monitor speed auto +monitor long 0xffffff60 0x00320100 +monitor long 0xfffffd44 0xa0008000 +monitor long 0xfffffc20 0xa0000601 +monitor sleep 100 +monitor long 0xfffffc2c 0x00480a0e +monitor sleep 200 +monitor long 0xfffffc30 0x7 +monitor sleep 100 +monitor long 0xfffffd08 0xa5000401 +monitor sleep 100 + diff --git a/ports/at91sam7s/Makefile b/ports/at91sam7s/Makefile index 45a4fd3a..3d6fd6fd 100644 --- a/ports/at91sam7s/Makefile +++ b/ports/at91sam7s/Makefile @@ -25,10 +25,8 @@ BACNET_FLAGS += -DCRC_USE_TABLE #BACNET_FLAGS += -DDLMSTP_TEST BACNET_CORE = ../../src -BACNET_DEMO = ../../demo -BACNET_INCLUDE = ../../include -BACNET_OBJECT = ../../demo/object -BACNET_HANDLER = ../../demo/handler +BACNET_BASIC = $(BACNET_CORE)/basic +BACNET_INCLUDE = $(BACNET_CORE) INCLUDES = -I. INCLUDES += -I$(BACNET_INCLUDE) INCLUDES += -I$(BACNET_OBJECT) @@ -66,21 +64,22 @@ DEMOSRC = ai.c \ bi.c \ bv.c \ device.c \ - $(BACNET_DEMO)/handler/txbuf.c \ - $(BACNET_DEMO)/handler/noserv.c \ - $(BACNET_DEMO)/handler/h_npdu.c \ - $(BACNET_DEMO)/handler/h_whohas.c \ - $(BACNET_DEMO)/handler/h_whois.c \ - $(BACNET_DEMO)/handler/h_rd.c \ - $(BACNET_DEMO)/handler/h_rp.c \ - $(BACNET_DEMO)/handler/h_rpm.c \ - $(BACNET_DEMO)/handler/h_wp.c \ - $(BACNET_DEMO)/handler/h_dcc.c \ - $(BACNET_DEMO)/handler/s_iam.c \ - $(BACNET_DEMO)/handler/s_ihave.c + $(BACNET_BASIC)/tsm/tsm.c \ + $(BACNET_BASIC)/sys/ringbuf.c \ + $(BACNET_BASIC)/npdu/h_npdu.c \ + $(BACNET_BASIC)/service/h_noserv.c \ + $(BACNET_BASIC)/service/h_apdu.c \ + $(BACNET_BASIC)/service/h_whohas.c \ + $(BACNET_BASIC)/service/h_whois.c \ + $(BACNET_BASIC)/service/h_rd.c \ + $(BACNET_BASIC)/service/h_rp.c \ + $(BACNET_BASIC)/service/h_rpm.c \ + $(BACNET_BASIC)/service/h_wp.c \ + $(BACNET_BASIC)/service/h_dcc.c \ + $(BACNET_BASIC)/service/s_iam.c \ + $(BACNET_BASIC)/service/s_ihave.c CORESRC = $(BACNET_CORE)/abort.c \ - $(BACNET_CORE)/apdu.c \ $(BACNET_CORE)/bacaddr.c \ $(BACNET_CORE)/bacapp.c \ $(BACNET_CORE)/bacdcode.c \ @@ -88,7 +87,7 @@ CORESRC = $(BACNET_CORE)/abort.c \ $(BACNET_CORE)/bacint.c \ $(BACNET_CORE)/bacreal.c \ $(BACNET_CORE)/bacstr.c \ - $(BACNET_CORE)/crc.c \ + $(BACNET_CORE)/datalink/crc.c \ $(BACNET_CORE)/datetime.c \ $(BACNET_CORE)/dcc.c \ $(BACNET_CORE)/iam.c \ @@ -99,7 +98,6 @@ CORESRC = $(BACNET_CORE)/abort.c \ $(BACNET_CORE)/proplist.c \ $(BACNET_CORE)/rd.c \ $(BACNET_CORE)/reject.c \ - $(BACNET_CORE)/ringbuf.c \ $(BACNET_CORE)/rp.c \ $(BACNET_CORE)/rpm.c \ $(BACNET_CORE)/version.c \ diff --git a/ports/at91sam7s/ai.c b/ports/at91sam7s/ai.c index 9eff02a5..c426a95d 100644 --- a/ports/at91sam7s/ai.c +++ b/ports/at91sam7s/ai.c @@ -28,12 +28,12 @@ #include #include #include -#include "bacdef.h" -#include "bacdcode.h" -#include "bacenum.h" -#include "config.h" -#include "ai.h" -#include "handlers.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacenum.h" +#include "bacnet/config.h" +#include "bacnet/basic/object/ai.h" +#include "bacnet/basic/services.h" #ifndef MAX_ANALOG_INPUTS #define MAX_ANALOG_INPUTS 2 diff --git a/ports/at91sam7s/at91sam7s256.ld b/ports/at91sam7s/at91sam7s256.ld index f9d6cb10..e49a36b7 100644 --- a/ports/at91sam7s/at91sam7s256.ld +++ b/ports/at91sam7s/at91sam7s256.ld @@ -1,156 +1,156 @@ -/* ****************************************************************************************************** */ -/* LINKER SCRIPT */ -/* */ -/* */ -/* The Linker Script defines how the code and data emitted by the GNU C compiler and assembler are */ -/* to be loaded into memory (code goes into FLASH, variables go into RAM). */ -/* */ -/* Any symbols defined in the Linker Script are automatically global and available to the rest of the */ -/* program. */ -/* */ -/* To force the linker to use this LINKER SCRIPT, just add the -T AT91SAM7S256.LD */ -/* directive to the linker flags in the makefile. For example, */ -/* */ -/* LFLAGS = -Map main.map -nostartfiles -T AT91SAM7S256.LD */ -/* */ -/* */ -/* The order that the object files are listed in the makefile determines what .text section is */ -/* placed first. */ -/* */ -/* For example: $(LD) $(LFLAGS) -o main.out crt.o main.o lowlevelinit.o */ -/* */ -/* crt.o is first in the list of objects, so it will be placed at address 0x00000000 */ -/* */ -/* */ -/* The top of the stack (_stack_end) is (last_byte_of_ram +1) - 4 */ -/* */ -/* Therefore: _stack_end = (0x00020FFFF + 1) - 4 = 0x00210000 - 4 = 0x0020FFFC */ -/* Therefore: _stack_end = (0x000203FFF + 1) - 4 = 0x00204000 - 4 = 0x00203FFC */ -/* */ -/* Note that this symbol (_stack_end) is automatically GLOBAL and will be used by the crt.s */ -/* startup assembler routine to specify all stacks for the various ARM modes */ -/* */ -/* MEMORY MAP */ -/* | | */ -/* .-------->|---------------------------------|0x00210000 */ -/* . | |0x0020FFFC <---------- _stack_end */ -/* . | UDF Stack 16 bytes | */ -/* . | | */ -/* . |---------------------------------|0x0020FFEC */ -/* . | | */ -/* . | ABT Stack 16 bytes | */ -/* . | | */ -/* . |---------------------------------|0x0020FFDC */ -/* . | | */ -/* . | | */ -/* . | FIQ Stack 128 bytes | */ -/* . | | */ -/* . | | */ -/* RAM |---------------------------------|0x0020FF5C */ -/* . | | */ -/* . | | */ -/* . | IRQ Stack 128 bytes | */ -/* . | | */ -/* . | | */ -/* . |---------------------------------|0x0020FEDC */ -/* . | | */ -/* . | SVC Stack 16 bytes | */ -/* . | | */ -/* . |---------------------------------|0x0020FECC */ -/* . | | */ -/* . | stack area for user program | */ -/* . | | */ -/* . | | */ -/* . | | */ -/* . | free ram | */ -/* . | | */ -/* . |.................................|0x002006D8 <---------- _bss_end */ -/* . | | */ -/* . | .bss uninitialized variables | */ -/* . |.................................|0x002006D0 <---------- _bss_start, _edata */ -/* . | | */ -/* . | .data initialized variables | */ -/* . | | */ -/* .-------->|_________________________________|0x00200000 */ -/* */ -/* */ -/* .-------->|---------------------------------|0x00100000 */ -/* . | | */ -/* . | | */ -/* . | free flash | */ -/* . | | */ -/* . | | */ -/* . |.................................|0x000006D0 <---------- _bss_start, _edata */ -/* . | | */ -/* . | .data initialized variables | */ -/* . | | */ -/* . |---------------------------------|0x000006C4 <----------- _etext */ -/* . | | */ -/* . | C code | */ -/* . | | */ -/* . | | */ -/* . |---------------------------------|0x00000118 main() */ -/* . | | */ -/* . | Startup Code (crt.s) | */ -/* . | (assembler) | */ -/* . | | */ -/* . |---------------------------------|0x00000020 */ -/* . | | */ -/* . | Interrupt Vector Table | */ -/* . | 32 bytes | */ -/* .-------->|---------------------------------|0x00000000 _vec_reset */ -/* */ -/* */ -/* Author: James P. Lynch May 12, 2007 */ -/* */ -/* ****************************************************************************************************** */ - - -/* identify the Entry Point (_vec_reset is defined in file crt.s) */ -ENTRY(_vec_reset) - -/* specify the AT91SAM7S64 memory areas */ -MEMORY -{ - flash : ORIGIN = 0, LENGTH = 64K /* FLASH EPROM */ - ram : ORIGIN = 0x00200000, LENGTH = 16K /* static RAM area */ -} - - -/* define a global symbol _stack_end (see analysis in annotation above) */ -/*_stack_end = 0x20FFFC;*/ -_stack_end = 0x203FFC; - -/* now define the output sections */ -SECTIONS -{ - . = 0; /* set location counter to address zero */ - - .text : /* collect all sections that should go into FLASH after startup */ - { - *(.text*) /* all .text sections (code) */ - *(.rodata) /* all .rodata sections (constants, strings, etc.) */ - *(.rodata*) /* all .rodata* sections (constants, strings, etc.) */ - *(.glue_7) /* all .glue_7 sections (no idea what these are) */ - *(.glue_7t) /* all .glue_7t sections (no idea what these are) */ - _etext = .; /* define a global symbol _etext just after the last code byte */ - } >flash /* put all the above into FLASH */ - - .data : /* collect all initialized .data sections that go into RAM */ - { - _data = .; /* create a global symbol marking the start of the .data section */ - *(.data*) /* all .data sections */ - _edata = .; /* define a global symbol marking the end of the .data section */ - } >ram AT >flash /* put all the above into RAM (but load the LMA initializer copy into FLASH) */ - - .bss : /* collect all uninitialized .bss sections that go into RAM */ - { - _bss_start = .; /* define a global symbol marking the start of the .bss section */ - *(.bss*) /* all .bss sections */ - } >ram /* put all the above in RAM (it will be cleared in the startup code */ - - . = ALIGN(4); /* advance location counter to the next 32-bit boundary */ - _bss_end = . ; /* define a global symbol marking the end of the .bss section */ -} - _end = .; /* define a global symbol marking the end of application RAM */ - +/* ****************************************************************************************************** */ +/* LINKER SCRIPT */ +/* */ +/* */ +/* The Linker Script defines how the code and data emitted by the GNU C compiler and assembler are */ +/* to be loaded into memory (code goes into FLASH, variables go into RAM). */ +/* */ +/* Any symbols defined in the Linker Script are automatically global and available to the rest of the */ +/* program. */ +/* */ +/* To force the linker to use this LINKER SCRIPT, just add the -T AT91SAM7S256.LD */ +/* directive to the linker flags in the makefile. For example, */ +/* */ +/* LFLAGS = -Map main.map -nostartfiles -T AT91SAM7S256.LD */ +/* */ +/* */ +/* The order that the object files are listed in the makefile determines what .text section is */ +/* placed first. */ +/* */ +/* For example: $(LD) $(LFLAGS) -o main.out crt.o main.o lowlevelinit.o */ +/* */ +/* crt.o is first in the list of objects, so it will be placed at address 0x00000000 */ +/* */ +/* */ +/* The top of the stack (_stack_end) is (last_byte_of_ram +1) - 4 */ +/* */ +/* Therefore: _stack_end = (0x00020FFFF + 1) - 4 = 0x00210000 - 4 = 0x0020FFFC */ +/* Therefore: _stack_end = (0x000203FFF + 1) - 4 = 0x00204000 - 4 = 0x00203FFC */ +/* */ +/* Note that this symbol (_stack_end) is automatically GLOBAL and will be used by the crt.s */ +/* startup assembler routine to specify all stacks for the various ARM modes */ +/* */ +/* MEMORY MAP */ +/* | | */ +/* .-------->|---------------------------------|0x00210000 */ +/* . | |0x0020FFFC <---------- _stack_end */ +/* . | UDF Stack 16 bytes | */ +/* . | | */ +/* . |---------------------------------|0x0020FFEC */ +/* . | | */ +/* . | ABT Stack 16 bytes | */ +/* . | | */ +/* . |---------------------------------|0x0020FFDC */ +/* . | | */ +/* . | | */ +/* . | FIQ Stack 128 bytes | */ +/* . | | */ +/* . | | */ +/* RAM |---------------------------------|0x0020FF5C */ +/* . | | */ +/* . | | */ +/* . | IRQ Stack 128 bytes | */ +/* . | | */ +/* . | | */ +/* . |---------------------------------|0x0020FEDC */ +/* . | | */ +/* . | SVC Stack 16 bytes | */ +/* . | | */ +/* . |---------------------------------|0x0020FECC */ +/* . | | */ +/* . | stack area for user program | */ +/* . | | */ +/* . | | */ +/* . | | */ +/* . | free ram | */ +/* . | | */ +/* . |.................................|0x002006D8 <---------- _bss_end */ +/* . | | */ +/* . | .bss uninitialized variables | */ +/* . |.................................|0x002006D0 <---------- _bss_start, _edata */ +/* . | | */ +/* . | .data initialized variables | */ +/* . | | */ +/* .-------->|_________________________________|0x00200000 */ +/* */ +/* */ +/* .-------->|---------------------------------|0x00100000 */ +/* . | | */ +/* . | | */ +/* . | free flash | */ +/* . | | */ +/* . | | */ +/* . |.................................|0x000006D0 <---------- _bss_start, _edata */ +/* . | | */ +/* . | .data initialized variables | */ +/* . | | */ +/* . |---------------------------------|0x000006C4 <----------- _etext */ +/* . | | */ +/* . | C code | */ +/* . | | */ +/* . | | */ +/* . |---------------------------------|0x00000118 main() */ +/* . | | */ +/* . | Startup Code (crt.s) | */ +/* . | (assembler) | */ +/* . | | */ +/* . |---------------------------------|0x00000020 */ +/* . | | */ +/* . | Interrupt Vector Table | */ +/* . | 32 bytes | */ +/* .-------->|---------------------------------|0x00000000 _vec_reset */ +/* */ +/* */ +/* Author: James P. Lynch May 12, 2007 */ +/* */ +/* ****************************************************************************************************** */ + + +/* identify the Entry Point (_vec_reset is defined in file crt.s) */ +ENTRY(_vec_reset) + +/* specify the AT91SAM7S64 memory areas */ +MEMORY +{ + flash : ORIGIN = 0, LENGTH = 64K /* FLASH EPROM */ + ram : ORIGIN = 0x00200000, LENGTH = 16K /* static RAM area */ +} + + +/* define a global symbol _stack_end (see analysis in annotation above) */ +/*_stack_end = 0x20FFFC;*/ +_stack_end = 0x203FFC; + +/* now define the output sections */ +SECTIONS +{ + . = 0; /* set location counter to address zero */ + + .text : /* collect all sections that should go into FLASH after startup */ + { + *(.text*) /* all .text sections (code) */ + *(.rodata) /* all .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* all .rodata* sections (constants, strings, etc.) */ + *(.glue_7) /* all .glue_7 sections (no idea what these are) */ + *(.glue_7t) /* all .glue_7t sections (no idea what these are) */ + _etext = .; /* define a global symbol _etext just after the last code byte */ + } >flash /* put all the above into FLASH */ + + .data : /* collect all initialized .data sections that go into RAM */ + { + _data = .; /* create a global symbol marking the start of the .data section */ + *(.data*) /* all .data sections */ + _edata = .; /* define a global symbol marking the end of the .data section */ + } >ram AT >flash /* put all the above into RAM (but load the LMA initializer copy into FLASH) */ + + .bss : /* collect all uninitialized .bss sections that go into RAM */ + { + _bss_start = .; /* define a global symbol marking the start of the .bss section */ + *(.bss*) /* all .bss sections */ + } >ram /* put all the above in RAM (it will be cleared in the startup code */ + + . = ALIGN(4); /* advance location counter to the next 32-bit boundary */ + _bss_end = . ; /* define a global symbol marking the end of the .bss section */ +} + _end = .; /* define a global symbol marking the end of application RAM */ + diff --git a/ports/at91sam7s/av.c b/ports/at91sam7s/av.c index 87240ae3..e3b99799 100644 --- a/ports/at91sam7s/av.c +++ b/ports/at91sam7s/av.c @@ -27,13 +27,13 @@ #include #include -#include "bacdef.h" -#include "bacdcode.h" -#include "bacenum.h" -#include "bacapp.h" -#include "config.h" /* the custom stuff */ -#include "av.h" -#include "handlers.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacenum.h" +#include "bacnet/bacapp.h" +#include "bacnet/config.h" /* the custom stuff */ +#include "bacnet/basic/object/av.h" +#include "bacnet/basic/services.h" #ifndef MAX_ANALOG_VALUES #define MAX_ANALOG_VALUES 4 diff --git a/ports/at91sam7s/bacnet.ewp b/ports/at91sam7s/bacnet.ewp index fdcc52fe..0bc6556b 100644 --- a/ports/at91sam7s/bacnet.ewp +++ b/ports/at91sam7s/bacnet.ewp @@ -12,7 +12,7 @@ General 3 - 21 + 24 1 1 - - - + + + + + + + ICCARM 2 - 28 + 31 1 1 + + + + AARM 2 - 8 + 9 1 1 + @@ -567,7 +603,7 @@ 1 @@ -613,7 +650,7 @@ ILINK 0 - 15 + 17 1 1 + + @@ -922,1042 +967,127 @@ - - Release - - ARM - - 0 - - General - 3 - - 21 - 1 - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ICCARM - 2 - - 28 - 1 - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - AARM - 2 - - 8 - 1 - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - OBJCOPY - 0 - - 1 - 1 - 0 - - - - - - - - - CUSTOM - 3 - - - - - - - BICOMP - 0 - - - - BUILDACTION - 1 - - - - - - - ILINK - 0 - - 15 - 1 - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - IARCHIVE - 0 - - 0 - 1 - 0 - - - - - - - BILINK - 0 - - - - BACnet-Core + BACnet-Basic - $PROJ_DIR$\..\..\src\abort.c + $PROJ_DIR$\..\..\src\bacnet\basic\service\h_apdu.c - $PROJ_DIR$\..\..\src\apdu.c + $PROJ_DIR$\..\..\src\bacnet\basic\service\h_dcc.c - $PROJ_DIR$\..\..\src\bacaddr.c + $PROJ_DIR$\..\..\src\bacnet\basic\service\h_noserv.c - $PROJ_DIR$\..\..\src\bacapp.c + $PROJ_DIR$\..\..\src\bacnet\basic\npdu\h_npdu.c - $PROJ_DIR$\..\..\src\bacdcode.c + $PROJ_DIR$\..\..\src\bacnet\basic\service\h_rd.c - $PROJ_DIR$\..\..\src\bacdevobjpropref.c + $PROJ_DIR$\..\..\src\bacnet\basic\service\h_rp.c - $PROJ_DIR$\..\..\src\bacerror.c + $PROJ_DIR$\..\..\src\bacnet\basic\service\h_rpm.c - $PROJ_DIR$\..\..\src\bacint.c + $PROJ_DIR$\..\..\src\bacnet\basic\service\h_whohas.c - $PROJ_DIR$\..\..\src\bacreal.c + $PROJ_DIR$\..\..\src\bacnet\basic\service\h_whois.c - $PROJ_DIR$\..\..\src\bacstr.c + $PROJ_DIR$\..\..\src\bacnet\basic\service\h_wp.c - $PROJ_DIR$\..\..\src\crc.c + $PROJ_DIR$\..\..\src\bacnet\basic\sys\ringbuf.c - $PROJ_DIR$\..\..\src\datetime.c + $PROJ_DIR$\..\..\src\bacnet\basic\service\s_iam.c - $PROJ_DIR$\..\..\src\dcc.c + $PROJ_DIR$\..\..\src\bacnet\basic\service\s_ihave.c - $PROJ_DIR$\..\..\src\iam.c - - - $PROJ_DIR$\..\..\src\ihave.c - - - $PROJ_DIR$\..\..\src\lighting.c - - - $PROJ_DIR$\..\..\src\memcopy.c - - - $PROJ_DIR$\..\..\src\npdu.c - - - $PROJ_DIR$\..\..\src\proplist.c - - - $PROJ_DIR$\..\..\src\rd.c - - - $PROJ_DIR$\..\..\src\reject.c - - - $PROJ_DIR$\..\..\src\ringbuf.c - - - $PROJ_DIR$\..\..\src\rp.c - - - $PROJ_DIR$\..\..\src\rpm.c - - - $PROJ_DIR$\..\..\src\version.c - - - $PROJ_DIR$\..\..\src\whohas.c - - - $PROJ_DIR$\..\..\src\whois.c - - - $PROJ_DIR$\..\..\src\wp.c + $PROJ_DIR$\..\..\src\bacnet\basic\tsm\tsm.c - BACnet-Demo + BACnet-Core - $PROJ_DIR$\..\..\demo\handler\h_dcc.c + $PROJ_DIR$\..\..\src\bacnet\abort.c - $PROJ_DIR$\..\..\demo\handler\h_npdu.c + $PROJ_DIR$\..\..\src\bacnet\bacaddr.c - $PROJ_DIR$\..\..\demo\handler\h_rd.c + $PROJ_DIR$\..\..\src\bacnet\bacapp.c - $PROJ_DIR$\..\..\demo\handler\h_rp.c + $PROJ_DIR$\..\..\src\bacnet\bacdcode.c - $PROJ_DIR$\..\..\demo\handler\h_rpm.c + $PROJ_DIR$\..\..\src\bacnet\bacdevobjpropref.c - $PROJ_DIR$\..\..\demo\handler\h_whohas.c + $PROJ_DIR$\..\..\src\bacnet\bacerror.c - $PROJ_DIR$\..\..\demo\handler\h_whois.c + $PROJ_DIR$\..\..\src\bacnet\bacint.c - $PROJ_DIR$\..\..\demo\handler\h_wp.c + $PROJ_DIR$\..\..\src\bacnet\bacreal.c - $PROJ_DIR$\..\..\demo\handler\noserv.c + $PROJ_DIR$\..\..\src\bacnet\bacstr.c - $PROJ_DIR$\..\..\demo\handler\s_iam.c + $PROJ_DIR$\..\..\src\bacnet\datalink\crc.c - $PROJ_DIR$\..\..\demo\handler\s_ihave.c + $PROJ_DIR$\..\..\src\bacnet\datetime.c - $PROJ_DIR$\..\..\demo\handler\txbuf.c + $PROJ_DIR$\..\..\src\bacnet\dcc.c + + + $PROJ_DIR$\..\..\src\bacnet\iam.c + + + $PROJ_DIR$\..\..\src\bacnet\ihave.c + + + $PROJ_DIR$\..\..\src\bacnet\lighting.c + + + $PROJ_DIR$\..\..\src\bacnet\memcopy.c + + + $PROJ_DIR$\..\..\src\bacnet\npdu.c + + + $PROJ_DIR$\..\..\src\bacnet\proplist.c + + + $PROJ_DIR$\..\..\src\bacnet\rd.c + + + $PROJ_DIR$\..\..\src\bacnet\reject.c + + + $PROJ_DIR$\..\..\src\bacnet\rp.c + + + $PROJ_DIR$\..\..\src\bacnet\rpm.c + + + $PROJ_DIR$\..\..\src\bacnet\whohas.c + + + $PROJ_DIR$\..\..\src\bacnet\whois.c + + + $PROJ_DIR$\..\..\src\bacnet\wp.c diff --git a/ports/at91sam7s/bi.c b/ports/at91sam7s/bi.c index 4e79c527..9f90eeda 100644 --- a/ports/at91sam7s/bi.c +++ b/ports/at91sam7s/bi.c @@ -28,12 +28,12 @@ #include #include #include -#include "bacdef.h" -#include "bacdcode.h" -#include "bacenum.h" -#include "config.h" -#include "bi.h" -#include "handlers.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacenum.h" +#include "bacnet/config.h" +#include "bacnet/basic/object/bi.h" +#include "bacnet/basic/services.h" #define MAX_BINARY_INPUTS 8 #if (MAX_BINARY_INPUTS > 9) diff --git a/ports/at91sam7s/bv.c b/ports/at91sam7s/bv.c index 3f24b308..8478603c 100644 --- a/ports/at91sam7s/bv.c +++ b/ports/at91sam7s/bv.c @@ -28,12 +28,12 @@ #include #include #include -#include "bacdef.h" -#include "bacdcode.h" -#include "bacenum.h" -#include "config.h" /* the custom stuff */ -#include "bv.h" -#include "handlers.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacenum.h" +#include "bacnet/config.h" /* the custom stuff */ +#include "bacnet/basic/object/bv.h" +#include "bacnet/basic/services.h" #ifndef MAX_BINARY_VALUES #define MAX_BINARY_VALUES 8 diff --git a/ports/at91sam7s/crt.s b/ports/at91sam7s/crt.s index 70ad3d81..d4dd7c94 100644 --- a/ports/at91sam7s/crt.s +++ b/ports/at91sam7s/crt.s @@ -1,319 +1,319 @@ -/* ****************************************************************************************************** */ -/* crt.s */ -/* */ -/* Assembly Language Startup Code for Atmel AT91SAM7S256 */ -/* */ -/* */ -/* */ -/* */ -/* Author: James P Lynch May 12, 2007 */ -/* ****************************************************************************************************** */ - -/* Stack Sizes */ -.set UND_STACK_SIZE, 0x00000010 /* stack for "undefined instruction" interrupts is 16 bytes */ -.set ABT_STACK_SIZE, 0x00000010 /* stack for "abort" interrupts is 16 bytes */ -.set FIQ_STACK_SIZE, 0x00000080 /* stack for "FIQ" interrupts is 128 bytes */ -.set IRQ_STACK_SIZE, 0X00000080 /* stack for "IRQ" normal interrupts is 128 bytes */ -.set SVC_STACK_SIZE, 0x00000080 /* stack for "SVC" supervisor mode is 128 bytes */ - -/* Standard definitions of Mode bits and Interrupt (I & F) flags in PSRs (program status registers) */ -.set ARM_MODE_USR, 0x10 /* Normal User Mode */ -.set ARM_MODE_FIQ, 0x11 /* FIQ Processing Fast Interrupts Mode */ -.set ARM_MODE_IRQ, 0x12 /* IRQ Processing Standard Interrupts Mode */ -.set ARM_MODE_SVC, 0x13 /* Supervisor Processing Software Interrupts Mode */ -.set ARM_MODE_ABT, 0x17 /* Abort Processing memory Faults Mode */ -.set ARM_MODE_UND, 0x1B /* Undefined Processing Undefined Instructions Mode */ -.set ARM_MODE_SYS, 0x1F /* System Running Priviledged Operating System Tasks Mode */ -.set I_BIT, 0x80 /* when I bit is set, IRQ is disabled (program status registers) */ -.set F_BIT, 0x40 /* when F bit is set, FIQ is disabled (program status registers) */ - -/* Addresses and offsets of AIC and PIO */ -.set AT91C_BASE_AIC, 0xFFFFF000 /* (AIC) Base Address */ -.set AT91C_PIOA_CODR, 0xFFFFF434 /* (PIO) Clear Output Data Register */ -.set AT91C_AIC_IVR, 0xFFFFF100 /* (AIC) IRQ Interrupt Vector Register */ -.set AT91C_AIC_FVR, 0xFFFFF104 /* (AIC) FIQ Interrupt Vector Register */ -.set AIC_IVR, 256 /* IRQ Vector Register offset from base above */ -.set AIC_FVR, 260 /* FIQ Vector Register offset from base above */ -.set AIC_EOICR, 304 /* End of Interrupt Command Register */ - -/* identify all GLOBAL symbols */ -.global _vec_reset -.global _vec_undef -.global _vec_swi -.global _vec_pabt -.global _vec_dabt -.global _vec_rsv -.global _vec_irq -.global _vec_fiq -.global AT91F_Irq_Handler -.global AT91F_Fiq_Handler -.global AT91F_Default_FIQ_handler -.global AT91F_Default_IRQ_handler -.global AT91F_Spurious_handler -.global AT91F_Dabt_Handler -.global AT91F_Pabt_Handler -.global AT91F_Undef_Handler - - -/* GNU assembler controls */ -.text /* all assembler code that follows will go into .text section */ -.arm /* compile for 32-bit ARM instruction set */ -.align /* align section on 32-bit boundary */ - -/* ============================================================ */ -/* VECTOR TABLE */ -/* */ -/* Must be located in FLASH at address 0x00000000 */ -/* */ -/* Easy to do if this file crt.s is first in the list */ -/* for the linker step in the makefile, e.g. */ -/* */ -/* $(LD) $(LFLAGS) -o main.out crt.o main.o */ -/* */ -/* ============================================================ */ - -_vec_reset: b _init_reset /* RESET vector - must be at 0x00000000 */ -_vec_undef: b AT91F_Undef_Handler /* Undefined Instruction vector */ -_vec_swi: b _vec_swi /* Software Interrupt vector */ -_vec_pabt: b AT91F_Pabt_Handler /* Prefetch abort vector */ -_vec_dabt: b AT91F_Dabt_Handler /* Data abort vector */ -_vec_rsv: nop /* Reserved vector */ -_vec_irq: b AT91F_Irq_Handler /* Interrupt Request (IRQ) vector */ -_vec_fiq: /* Fast interrupt request (FIQ) vector */ - -/* ======================================================================== */ -/* Function: AT91F_Fiq_Handler */ -/* */ -/* The FIQ interrupt asserts when switch SW1 is pressed. */ -/* */ -/* This simple FIQ handler turns on LED3 (Port PA2). The LED3 will be */ -/* turned off by the background loop in main() thus giving a visual */ -/* indication that the interrupt has occurred. */ -/* */ -/* This FIQ_Handler supports non-nested FIQ interrupts (a FIQ interrupt */ -/* cannot itself be interrupted). */ -/* */ -/* The Fast Interrupt Vector Register (AIC_FVR) is read to clear the */ -/* interrupt. */ -/* */ -/* A global variable FiqCount is also incremented. */ -/* */ -/* Remember that switch SW1 is not debounced, so the FIQ interrupt may */ -/* occur more than once for a single button push. */ -/* */ -/* Programmer: James P Lynch */ -/* ======================================================================== */ -AT91F_Fiq_Handler: - -/* Adjust LR_irq */ - sub lr, lr, #4 - -/* Read the AIC Fast Interrupt Vector register to clear the interrupt */ - ldr r12, =AT91C_AIC_FVR - ldr r11, [r12] - -/* Return from Fiq interrupt */ - movs pc, lr - - -/* ======================================================================== */ -/* _init_reset Handler */ -/* */ -/* RESET vector 0x00000000 branches to here. */ -/* */ -/* ARM microprocessor begins execution after RESET at address 0x00000000 */ -/* in Supervisor mode with interrupts disabled! */ -/* */ -/* _init_reset handler: creates a stack for each ARM mode. */ -/* sets up a stack pointer for each ARM mode. */ -/* turns off interrupts in each mode. */ -/* leaves CPU in SYS (System) mode. */ -/* */ -/* block copies the initializers to .data section */ -/* clears the .bss section to zero */ -/* */ -/* branches to main( ) */ -/* ======================================================================== */ -.text /* all assembler code that follows will go into .text section */ -.align /* align section on 32-bit boundary */ -_init_reset: - /* Setup a stack for each mode with interrupts initially disabled. */ - ldr r0, =_stack_end /* r0 = top-of-stack */ - - msr CPSR_c, #ARM_MODE_UND|I_BIT|F_BIT /* switch to Undefined Instruction Mode */ - mov sp, r0 /* set stack pointer for UND mode */ - sub r0, r0, #UND_STACK_SIZE /* adjust r0 past UND stack */ - - msr CPSR_c, #ARM_MODE_ABT|I_BIT|F_BIT /* switch to Abort Mode */ - mov sp, r0 /* set stack pointer for ABT mode */ - sub r0, r0, #ABT_STACK_SIZE /* adjust r0 past ABT stack */ - - msr CPSR_c, #ARM_MODE_FIQ|I_BIT|F_BIT /* switch to FIQ Mode */ - mov sp, r0 /* set stack pointer for FIQ mode */ - sub r0, r0, #FIQ_STACK_SIZE /* adjust r0 past FIQ stack */ - - msr CPSR_c, #ARM_MODE_IRQ|I_BIT|F_BIT /* switch to IRQ Mode */ - mov sp, r0 /* set stack pointer for IRQ mode */ - sub r0, r0, #IRQ_STACK_SIZE /* adjust r0 past IRQ stack */ - - msr CPSR_c, #ARM_MODE_SVC|I_BIT|F_BIT /* switch to Supervisor Mode */ - mov sp, r0 /* set stack pointer for SVC mode */ - sub r0, r0, #SVC_STACK_SIZE /* adjust r0 past SVC stack */ - - msr CPSR_c, #ARM_MODE_SYS|I_BIT|F_BIT /* switch to System Mode */ - mov sp, r0 /* set stack pointer for SYS mode */ - /* we now start execution in SYSTEM mode */ - /* This is exactly like USER mode (same stack) */ - /* but SYSTEM mode has more privileges */ - - /* copy initialized variables .data section (Copy from ROM to RAM) */ - ldr R1, =_etext - ldr R2, =_data - ldr R3, =_edata -1: cmp R2, R3 - ldrlo R0, [R1], #4 - strlo R0, [R2], #4 - blo 1b - - /* Clear uninitialized variables .bss section (Zero init) */ - mov R0, #0 - ldr R1, =_bss_start - ldr R2, =_bss_end -2: cmp R1, R2 - strlo R0, [R1], #4 - blo 2b - - /* Enter the C code */ - b main - - - - -/* ======================================================================== */ -/* Function: AT91F_Irq_Handler */ -/* */ -/* This IRQ_Handler supports nested interrupts (an IRQ interrupt can itself */ -/* be interrupted). */ -/* */ -/* This handler re-enables interrupts and switches to "Supervisor" mode to */ -/* prevent any corruption to the link and IP registers. */ -/* */ -/* The Interrupt Vector Register (AIC_IVR) is read to determine the address */ -/* of the required interrupt service routine. The ISR routine can be a */ -/* standard C function since this handler minds all the save/restore */ -/* protocols. */ -/* */ -/* */ -/* Programmers: */ -/*--------------------------------------------------------------------------*/ -/* ATMEL Microcontroller Software Support - ROUSSET - */ -/*--------------------------------------------------------------------------*/ -/* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS */ -/* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED */ -/* WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND */ -/* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR */ -/* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR */ -/* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT */ -/* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR */ -/* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, */ -/* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE */ -/* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, */ -/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* File source : Cstartup.s79 */ -/* Object : Generic CStartup to AT91SAM7S256 */ -/* 1.0 09/May/06 JPP : Creation */ -/* */ -/* */ -/* Note: taken from Atmel web site (www.at91.com) */ -/* Keil example project: AT91SAM7S-Interrupt_SAM7S */ -/* ======================================================================== */ -AT91F_Irq_Handler: - -/* Manage Exception Entry */ -/* Adjust and save LR_irq in IRQ stack */ - sub lr, lr, #4 - stmfd sp!, {lr} - -/* Save r0 and SPSR (need to be saved for nested interrupt) */ - mrs r14, SPSR - stmfd sp!, {r0,r14} - -/* Write in the IVR to support Protect Mode */ -/* No effect in Normal Mode */ -/* De-assert the NIRQ and clear the source in Protect Mode */ - ldr r14, =AT91C_BASE_AIC - ldr r0 , [r14, #AIC_IVR] - str r14, [r14, #AIC_IVR] - -/* Enable Interrupt and Switch in Supervisor Mode */ - msr CPSR_c, #ARM_MODE_SVC - -/* Save scratch/used registers and LR in User Stack */ - stmfd sp!, { r1-r3, r12, r14} - -/* Branch to the routine pointed by the AIC_IVR */ - mov r14, pc - bx r0 - -/* Manage Exception Exit */ -/* Restore scratch/used registers and LR from User Stack */ - ldmia sp!, { r1-r3, r12, r14} - -/* Disable Interrupt and switch back in IRQ mode */ - msr CPSR_c, #I_BIT | ARM_MODE_IRQ - -/* Mark the End of Interrupt on the AIC */ - ldr r14, =AT91C_BASE_AIC - str r14, [r14, #AIC_EOICR] - -/* Restore SPSR_irq and r0 from IRQ stack */ - ldmia sp!, {r0,r14} - msr SPSR_cxsf, r14 - -/* Restore adjusted LR_irq from IRQ stack directly in the PC */ - ldmia sp!, {pc}^ - - - -/* ======================================================================== */ -/* Function: AT91F_Dabt_Handler */ -/* */ -/* Entered on Data Abort exception. */ -/* Enters blink routine (3 blinks followed by a pause) */ -/* processor hangs in the blink loop forever */ -/* */ -/* ======================================================================== */ -AT91F_Dabt_Handler: mov R0, #3 - b blinker - - -/* ======================================================================== */ -/* Function: AT91F_Pabt_Handler */ -/* */ -/* Entered on Prefetch Abort exception. */ -/* Enters blink routine (2 blinks followed by a pause) */ -/* processor hangs in the blink loop forever */ -/* */ -/* ======================================================================== */ -AT91F_Pabt_Handler: mov R0, #2 - b blinker - - -/* ======================================================================== */ -/* Function: AT91F_Undef_Handler */ -/* */ -/* Entered on Undefined Instruction exception. */ -/* Enters blink routine (1 blinks followed by a pause) */ -/* processor hangs in the blink loop forever */ -/* */ -/* ======================================================================== */ -AT91F_Undef_Handler: mov R0, #1 - b blinker - - -AT91F_Default_FIQ_handler: b AT91F_Default_FIQ_handler - -AT91F_Default_IRQ_handler: b AT91F_Default_IRQ_handler - -AT91F_Spurious_handler: b AT91F_Spurious_handler -.end +/* ****************************************************************************************************** */ +/* crt.s */ +/* */ +/* Assembly Language Startup Code for Atmel AT91SAM7S256 */ +/* */ +/* */ +/* */ +/* */ +/* Author: James P Lynch May 12, 2007 */ +/* ****************************************************************************************************** */ + +/* Stack Sizes */ +.set UND_STACK_SIZE, 0x00000010 /* stack for "undefined instruction" interrupts is 16 bytes */ +.set ABT_STACK_SIZE, 0x00000010 /* stack for "abort" interrupts is 16 bytes */ +.set FIQ_STACK_SIZE, 0x00000080 /* stack for "FIQ" interrupts is 128 bytes */ +.set IRQ_STACK_SIZE, 0X00000080 /* stack for "IRQ" normal interrupts is 128 bytes */ +.set SVC_STACK_SIZE, 0x00000080 /* stack for "SVC" supervisor mode is 128 bytes */ + +/* Standard definitions of Mode bits and Interrupt (I & F) flags in PSRs (program status registers) */ +.set ARM_MODE_USR, 0x10 /* Normal User Mode */ +.set ARM_MODE_FIQ, 0x11 /* FIQ Processing Fast Interrupts Mode */ +.set ARM_MODE_IRQ, 0x12 /* IRQ Processing Standard Interrupts Mode */ +.set ARM_MODE_SVC, 0x13 /* Supervisor Processing Software Interrupts Mode */ +.set ARM_MODE_ABT, 0x17 /* Abort Processing memory Faults Mode */ +.set ARM_MODE_UND, 0x1B /* Undefined Processing Undefined Instructions Mode */ +.set ARM_MODE_SYS, 0x1F /* System Running Priviledged Operating System Tasks Mode */ +.set I_BIT, 0x80 /* when I bit is set, IRQ is disabled (program status registers) */ +.set F_BIT, 0x40 /* when F bit is set, FIQ is disabled (program status registers) */ + +/* Addresses and offsets of AIC and PIO */ +.set AT91C_BASE_AIC, 0xFFFFF000 /* (AIC) Base Address */ +.set AT91C_PIOA_CODR, 0xFFFFF434 /* (PIO) Clear Output Data Register */ +.set AT91C_AIC_IVR, 0xFFFFF100 /* (AIC) IRQ Interrupt Vector Register */ +.set AT91C_AIC_FVR, 0xFFFFF104 /* (AIC) FIQ Interrupt Vector Register */ +.set AIC_IVR, 256 /* IRQ Vector Register offset from base above */ +.set AIC_FVR, 260 /* FIQ Vector Register offset from base above */ +.set AIC_EOICR, 304 /* End of Interrupt Command Register */ + +/* identify all GLOBAL symbols */ +.global _vec_reset +.global _vec_undef +.global _vec_swi +.global _vec_pabt +.global _vec_dabt +.global _vec_rsv +.global _vec_irq +.global _vec_fiq +.global AT91F_Irq_Handler +.global AT91F_Fiq_Handler +.global AT91F_Default_FIQ_handler +.global AT91F_Default_IRQ_handler +.global AT91F_Spurious_handler +.global AT91F_Dabt_Handler +.global AT91F_Pabt_Handler +.global AT91F_Undef_Handler + + +/* GNU assembler controls */ +.text /* all assembler code that follows will go into .text section */ +.arm /* compile for 32-bit ARM instruction set */ +.align /* align section on 32-bit boundary */ + +/* ============================================================ */ +/* VECTOR TABLE */ +/* */ +/* Must be located in FLASH at address 0x00000000 */ +/* */ +/* Easy to do if this file crt.s is first in the list */ +/* for the linker step in the makefile, e.g. */ +/* */ +/* $(LD) $(LFLAGS) -o main.out crt.o main.o */ +/* */ +/* ============================================================ */ + +_vec_reset: b _init_reset /* RESET vector - must be at 0x00000000 */ +_vec_undef: b AT91F_Undef_Handler /* Undefined Instruction vector */ +_vec_swi: b _vec_swi /* Software Interrupt vector */ +_vec_pabt: b AT91F_Pabt_Handler /* Prefetch abort vector */ +_vec_dabt: b AT91F_Dabt_Handler /* Data abort vector */ +_vec_rsv: nop /* Reserved vector */ +_vec_irq: b AT91F_Irq_Handler /* Interrupt Request (IRQ) vector */ +_vec_fiq: /* Fast interrupt request (FIQ) vector */ + +/* ======================================================================== */ +/* Function: AT91F_Fiq_Handler */ +/* */ +/* The FIQ interrupt asserts when switch SW1 is pressed. */ +/* */ +/* This simple FIQ handler turns on LED3 (Port PA2). The LED3 will be */ +/* turned off by the background loop in main() thus giving a visual */ +/* indication that the interrupt has occurred. */ +/* */ +/* This FIQ_Handler supports non-nested FIQ interrupts (a FIQ interrupt */ +/* cannot itself be interrupted). */ +/* */ +/* The Fast Interrupt Vector Register (AIC_FVR) is read to clear the */ +/* interrupt. */ +/* */ +/* A global variable FiqCount is also incremented. */ +/* */ +/* Remember that switch SW1 is not debounced, so the FIQ interrupt may */ +/* occur more than once for a single button push. */ +/* */ +/* Programmer: James P Lynch */ +/* ======================================================================== */ +AT91F_Fiq_Handler: + +/* Adjust LR_irq */ + sub lr, lr, #4 + +/* Read the AIC Fast Interrupt Vector register to clear the interrupt */ + ldr r12, =AT91C_AIC_FVR + ldr r11, [r12] + +/* Return from Fiq interrupt */ + movs pc, lr + + +/* ======================================================================== */ +/* _init_reset Handler */ +/* */ +/* RESET vector 0x00000000 branches to here. */ +/* */ +/* ARM microprocessor begins execution after RESET at address 0x00000000 */ +/* in Supervisor mode with interrupts disabled! */ +/* */ +/* _init_reset handler: creates a stack for each ARM mode. */ +/* sets up a stack pointer for each ARM mode. */ +/* turns off interrupts in each mode. */ +/* leaves CPU in SYS (System) mode. */ +/* */ +/* block copies the initializers to .data section */ +/* clears the .bss section to zero */ +/* */ +/* branches to main( ) */ +/* ======================================================================== */ +.text /* all assembler code that follows will go into .text section */ +.align /* align section on 32-bit boundary */ +_init_reset: + /* Setup a stack for each mode with interrupts initially disabled. */ + ldr r0, =_stack_end /* r0 = top-of-stack */ + + msr CPSR_c, #ARM_MODE_UND|I_BIT|F_BIT /* switch to Undefined Instruction Mode */ + mov sp, r0 /* set stack pointer for UND mode */ + sub r0, r0, #UND_STACK_SIZE /* adjust r0 past UND stack */ + + msr CPSR_c, #ARM_MODE_ABT|I_BIT|F_BIT /* switch to Abort Mode */ + mov sp, r0 /* set stack pointer for ABT mode */ + sub r0, r0, #ABT_STACK_SIZE /* adjust r0 past ABT stack */ + + msr CPSR_c, #ARM_MODE_FIQ|I_BIT|F_BIT /* switch to FIQ Mode */ + mov sp, r0 /* set stack pointer for FIQ mode */ + sub r0, r0, #FIQ_STACK_SIZE /* adjust r0 past FIQ stack */ + + msr CPSR_c, #ARM_MODE_IRQ|I_BIT|F_BIT /* switch to IRQ Mode */ + mov sp, r0 /* set stack pointer for IRQ mode */ + sub r0, r0, #IRQ_STACK_SIZE /* adjust r0 past IRQ stack */ + + msr CPSR_c, #ARM_MODE_SVC|I_BIT|F_BIT /* switch to Supervisor Mode */ + mov sp, r0 /* set stack pointer for SVC mode */ + sub r0, r0, #SVC_STACK_SIZE /* adjust r0 past SVC stack */ + + msr CPSR_c, #ARM_MODE_SYS|I_BIT|F_BIT /* switch to System Mode */ + mov sp, r0 /* set stack pointer for SYS mode */ + /* we now start execution in SYSTEM mode */ + /* This is exactly like USER mode (same stack) */ + /* but SYSTEM mode has more privileges */ + + /* copy initialized variables .data section (Copy from ROM to RAM) */ + ldr R1, =_etext + ldr R2, =_data + ldr R3, =_edata +1: cmp R2, R3 + ldrlo R0, [R1], #4 + strlo R0, [R2], #4 + blo 1b + + /* Clear uninitialized variables .bss section (Zero init) */ + mov R0, #0 + ldr R1, =_bss_start + ldr R2, =_bss_end +2: cmp R1, R2 + strlo R0, [R1], #4 + blo 2b + + /* Enter the C code */ + b main + + + + +/* ======================================================================== */ +/* Function: AT91F_Irq_Handler */ +/* */ +/* This IRQ_Handler supports nested interrupts (an IRQ interrupt can itself */ +/* be interrupted). */ +/* */ +/* This handler re-enables interrupts and switches to "Supervisor" mode to */ +/* prevent any corruption to the link and IP registers. */ +/* */ +/* The Interrupt Vector Register (AIC_IVR) is read to determine the address */ +/* of the required interrupt service routine. The ISR routine can be a */ +/* standard C function since this handler minds all the save/restore */ +/* protocols. */ +/* */ +/* */ +/* Programmers: */ +/*--------------------------------------------------------------------------*/ +/* ATMEL Microcontroller Software Support - ROUSSET - */ +/*--------------------------------------------------------------------------*/ +/* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS */ +/* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED */ +/* WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND */ +/* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR */ +/* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR */ +/* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT */ +/* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR */ +/* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, */ +/* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE */ +/* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, */ +/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/* File source : Cstartup.s79 */ +/* Object : Generic CStartup to AT91SAM7S256 */ +/* 1.0 09/May/06 JPP : Creation */ +/* */ +/* */ +/* Note: taken from Atmel web site (www.at91.com) */ +/* Keil example project: AT91SAM7S-Interrupt_SAM7S */ +/* ======================================================================== */ +AT91F_Irq_Handler: + +/* Manage Exception Entry */ +/* Adjust and save LR_irq in IRQ stack */ + sub lr, lr, #4 + stmfd sp!, {lr} + +/* Save r0 and SPSR (need to be saved for nested interrupt) */ + mrs r14, SPSR + stmfd sp!, {r0,r14} + +/* Write in the IVR to support Protect Mode */ +/* No effect in Normal Mode */ +/* De-assert the NIRQ and clear the source in Protect Mode */ + ldr r14, =AT91C_BASE_AIC + ldr r0 , [r14, #AIC_IVR] + str r14, [r14, #AIC_IVR] + +/* Enable Interrupt and Switch in Supervisor Mode */ + msr CPSR_c, #ARM_MODE_SVC + +/* Save scratch/used registers and LR in User Stack */ + stmfd sp!, { r1-r3, r12, r14} + +/* Branch to the routine pointed by the AIC_IVR */ + mov r14, pc + bx r0 + +/* Manage Exception Exit */ +/* Restore scratch/used registers and LR from User Stack */ + ldmia sp!, { r1-r3, r12, r14} + +/* Disable Interrupt and switch back in IRQ mode */ + msr CPSR_c, #I_BIT | ARM_MODE_IRQ + +/* Mark the End of Interrupt on the AIC */ + ldr r14, =AT91C_BASE_AIC + str r14, [r14, #AIC_EOICR] + +/* Restore SPSR_irq and r0 from IRQ stack */ + ldmia sp!, {r0,r14} + msr SPSR_cxsf, r14 + +/* Restore adjusted LR_irq from IRQ stack directly in the PC */ + ldmia sp!, {pc}^ + + + +/* ======================================================================== */ +/* Function: AT91F_Dabt_Handler */ +/* */ +/* Entered on Data Abort exception. */ +/* Enters blink routine (3 blinks followed by a pause) */ +/* processor hangs in the blink loop forever */ +/* */ +/* ======================================================================== */ +AT91F_Dabt_Handler: mov R0, #3 + b blinker + + +/* ======================================================================== */ +/* Function: AT91F_Pabt_Handler */ +/* */ +/* Entered on Prefetch Abort exception. */ +/* Enters blink routine (2 blinks followed by a pause) */ +/* processor hangs in the blink loop forever */ +/* */ +/* ======================================================================== */ +AT91F_Pabt_Handler: mov R0, #2 + b blinker + + +/* ======================================================================== */ +/* Function: AT91F_Undef_Handler */ +/* */ +/* Entered on Undefined Instruction exception. */ +/* Enters blink routine (1 blinks followed by a pause) */ +/* processor hangs in the blink loop forever */ +/* */ +/* ======================================================================== */ +AT91F_Undef_Handler: mov R0, #1 + b blinker + + +AT91F_Default_FIQ_handler: b AT91F_Default_FIQ_handler + +AT91F_Default_IRQ_handler: b AT91F_Default_IRQ_handler + +AT91F_Spurious_handler: b AT91F_Spurious_handler +.end diff --git a/ports/at91sam7s/device.c b/ports/at91sam7s/device.c index da6263f9..38f7606c 100644 --- a/ports/at91sam7s/device.c +++ b/ports/at91sam7s/device.c @@ -27,24 +27,27 @@ #include #include #include -#include "bacdef.h" -#include "bacdcode.h" -#include "bacstr.h" -#include "bacenum.h" -#include "apdu.h" -#include "dcc.h" -#include "datalink.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacstr.h" +#include "bacnet/bacenum.h" +#include "bacnet/apdu.h" +#include "bacnet/dcc.h" +#include "bacnet/datalink/datalink.h" #include "rs485.h" -#include "version.h" -#include "handlers.h" +#include "bacnet/version.h" +#include "bacnet/basic/services.h" /* objects */ -#include "device.h" -#include "ai.h" -#include "av.h" -#include "bi.h" -#include "bv.h" -#include "wp.h" -#include "dcc.h" +#include "bacnet/basic/object/device.h" +#include "bacnet/basic/object/ai.h" +#include "bacnet/basic/object/av.h" +#include "bacnet/basic/object/bi.h" +#include "bacnet/basic/object/bv.h" +#include "bacnet/wp.h" +#include "bacnet/dcc.h" + +/* current version of the BACnet stack */ +static const char *BACnet_Version = BACNET_VERSION_TEXT; /* forward prototype */ int Device_Read_Property_Local( diff --git a/ports/at91sam7s/dlmstp.c b/ports/at91sam7s/dlmstp.c index 1794f1de..7b4ac891 100644 --- a/ports/at91sam7s/dlmstp.c +++ b/ports/at91sam7s/dlmstp.c @@ -36,16 +36,16 @@ #include #include #include -#include "bacdef.h" -#include "dlmstp.h" -#include "mstpdef.h" +#include "bacnet/bacdef.h" +#include "bacnet/datalink/dlmstp.h" +#include "bacnet/datalink/mstpdef.h" +#include "bacnet/npdu.h" +#include "bacnet/bits.h" +#include "bacnet/bytes.h" +#include "bacnet/bacaddr.h" +#include "bacnet/basic/sys/ringbuf.h" +#include "bacnet/datalink/crc.h" #include "rs485.h" -#include "crc.h" -#include "npdu.h" -#include "bits.h" -#include "bytes.h" -#include "bacaddr.h" -#include "ringbuf.h" #include "timer.h" #include "board.h" diff --git a/ports/at91sam7s/isr.c b/ports/at91sam7s/isr.c index c782b33f..3ac7bcee 100644 --- a/ports/at91sam7s/isr.c +++ b/ports/at91sam7s/isr.c @@ -16,6 +16,7 @@ /* Taken from the Yahoo LPC2000 User's Group - Files Section 'UT050418A.ZIP' */ /* Specifically, the module armVIC.c with the include file references removed */ /* ********************************************************************************************** */ +#include "at91sam7s256.h" #include "isr.h" #define IRQ_MASK 0x00000080 diff --git a/ports/at91sam7s/main.c b/ports/at91sam7s/main.c index 95cf3943..58e906dd 100644 --- a/ports/at91sam7s/main.c +++ b/ports/at91sam7s/main.c @@ -33,17 +33,17 @@ #include /* BACnet */ #include "rs485.h" -#include "datalink.h" -#include "npdu.h" -#include "apdu.h" -#include "dcc.h" -#include "iam.h" -#include "handlers.h" -#include "client.h" -#include "device.h" -#include "dcc.h" -#include "iam.h" -#include "txbuf.h" +#include "bacnet/datalink/datalink.h" +#include "bacnet/npdu.h" +#include "bacnet/apdu.h" +#include "bacnet/dcc.h" +#include "bacnet/iam.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/object/device.h" +#include "bacnet/dcc.h" +#include "bacnet/iam.h" +#include "bacnet/basic/tsm/tsm.h" /* ******************************************************* */ /* FIXME: use header files? External References */ diff --git a/ports/at91sam7s/rs485.c b/ports/at91sam7s/rs485.c index a67e2278..95e1495d 100644 --- a/ports/at91sam7s/rs485.c +++ b/ports/at91sam7s/rs485.c @@ -32,7 +32,7 @@ #include #include #include -#include "timer.h" +#include "bacnet/basic/sys/mstimer.h" /* This file has been customized for use with UART0 on the AT91SAM7S-EK */ diff --git a/ports/at91sam7s/timer.c b/ports/at91sam7s/timer.c index bd91ef90..5af11020 100644 --- a/ports/at91sam7s/timer.c +++ b/ports/at91sam7s/timer.c @@ -42,7 +42,7 @@ **********************************************************/ #include #include "board.h" -#include "dlmstp.h" +#include "bacnet/datalink/dlmstp.h" /* global variable counts interrupts */ volatile unsigned long Timer_Milliseconds; diff --git a/ports/atmega168/.splintrc b/ports/atmega168/.splintrc index 2a42301b..7215ec71 100644 --- a/ports/atmega168/.splintrc +++ b/ports/atmega168/.splintrc @@ -1,13 +1,13 @@ --sysdirs C:\WinAVR~1\avr\include;C:\WinAVR~1\lib\gcc\avr\4.2.2\include;C:\WinAVR~1\avr\include\avr;C:\WinAVR~1\avr\include\compat;C:\WinAVR~1\avr\include\util --IC:\WinAVR~1\avr\include --IC:\WinAVR~1\avr\include\avr --IC:\WinAVR~1\avr\include\compat --IC:\WinAVR~1\avr\include\util --IC:\WinAVR~1\lib\gcc\avr\4.2.2\include --I../../include --I. --castfcnptr --fullinitblock --weak --D__AVR_ATmega168__ --D__GNUC__ +-sysdirs C:\WinAVR~1\avr\include;C:\WinAVR~1\lib\gcc\avr\4.2.2\include;C:\WinAVR~1\avr\include\avr;C:\WinAVR~1\avr\include\compat;C:\WinAVR~1\avr\include\util +-IC:\WinAVR~1\avr\include +-IC:\WinAVR~1\avr\include\avr +-IC:\WinAVR~1\avr\include\compat +-IC:\WinAVR~1\avr\include\util +-IC:\WinAVR~1\lib\gcc\avr\4.2.2\include +-I../../include +-I. +-castfcnptr +-fullinitblock +-weak +-D__AVR_ATmega168__ +-D__GNUC__ diff --git a/ports/atmega168/Makefile b/ports/atmega168/Makefile index fe109cb9..5055bd8c 100644 --- a/ports/atmega168/Makefile +++ b/ports/atmega168/Makefile @@ -30,10 +30,8 @@ AVRDUDE_PORT = /dev/ttyUSB0 # Source locations BACNET_CORE = ../../src -BACNET_INCLUDE = ../../include -BACNET_HANDLER = ../../demo/handler -BACNET_OBJECT = ../../demo/object -BACNET_DEMO = ../../demo +BACNET_INCLUDE = $(BACNET_CORE) +BACNET_BASIC = $(BACNET_CORE)/basic # local files for this project CSRC = main.c \ @@ -50,14 +48,14 @@ CSRC = main.c \ h_wp.c # common demo files needed -DEMOSRC = $(BACNET_DEMO)/handler/txbuf.c \ - $(BACNET_DEMO)/handler/h_npdu.c \ - $(BACNET_DEMO)/handler/s_iam.c \ - $(BACNET_DEMO)/handler/noserv.c +BASICSRC = $(BACNET_BASIC)/tsm/tsm.c \ + $(BACNET_BASIC)/npdu/h_npdu.c \ + $(BACNET_BASIC)/service/s_iam.c \ + $(BACNET_BASIC)/service/h_noserv.c # core BACnet stack files CORESRC = \ - $(BACNET_CORE)/crc.c \ + $(BACNET_CORE)/datalink/crc.c \ $(BACNET_CORE)/npdu.c \ $(BACNET_CORE)/bacdcode.c \ $(BACNET_CORE)/bacint.c \ @@ -73,34 +71,12 @@ CORESRC = \ $(BACNET_CORE)/bacerror.c \ $(BACNET_CORE)/bacapp.c -# $(BACNET_CORE)/version.c -# $(BACNET_CORE)/bacprop.c \ -# $(BACNET_CORE)/bactext.c \ -# $(BACNET_CORE)/datetime.c \ -# $(BACNET_CORE)/indtext.c \ -# $(BACNET_CORE)/bigend.c \ -# $(BACNET_CORE)/arf.c \ -# $(BACNET_CORE)/awf.c \ -# $(BACNET_CORE)/cov.c \ -# $(BACNET_CORE)/dcc.c \ -# $(BACNET_CORE)/iam/iam_client.c \ -# $(BACNET_CORE)/ihave.c \ -# $(BACNET_CORE)/rd.c \ -# $(BACNET_CORE)/rpm.c \ -# $(BACNET_CORE)/timesync.c \ -# $(BACNET_CORE)/whohas.c \ -# $(BACNET_CORE)/filename.c \ -# $(BACNET_CORE)/tsm.c \ -# $(BACNET_CORE)/address.c \ - ## Include Directories INCLUDES = -I. -I$(BACNET_INCLUDE) -INCLUDES += -I$(BACNET_OBJECT) -INCLUDES += -I$(BACNET_HANDLER) # Source to Object conversion COBJ = $(CSRC:.c=.o) -DEMOOBJ = $(DEMOSRC:.c=.o) +BASICOBJ = $(BASICSRC:.c=.o) COREOBJ = $(CORESRC:.c=.o) LIBRARY = lib$(TARGET).a @@ -156,7 +132,7 @@ HEX_EEPROM_FLAGS += --set-section-flags=.eeprom="alloc,load" HEX_EEPROM_FLAGS += --change-section-lma .eeprom=0 --no-change-warnings ## Objects that must be built in order to link -OBJECTS = $(COBJ) $(DEMOOBJ) +OBJECTS = $(COBJ) $(BASICOBJ) #OBJECTS = $(COBJ) ## Build diff --git a/ports/atmega168/ai.c b/ports/atmega168/ai.c index c11b7ccb..7a3d3581 100644 --- a/ports/atmega168/ai.c +++ b/ports/atmega168/ai.c @@ -28,10 +28,10 @@ #include #include #include -#include "bacdef.h" -#include "bacdcode.h" -#include "bacenum.h" -#include "config.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacenum.h" +#include "bacnet/config.h" /* Analog Input = Photocell */ #define MAX_ANALOG_INPUTS 9 diff --git a/ports/atmega168/ai.h b/ports/atmega168/ai.h index fec425f2..83a6110a 100644 --- a/ports/atmega168/ai.h +++ b/ports/atmega168/ai.h @@ -27,9 +27,9 @@ #include #include -#include "bacdef.h" -#include "rp.h" -#include "wp.h" +#include "bacnet/bacdef.h" +#include "bacnet/rp.h" +#include "bacnet/wp.h" #ifdef __cplusplus extern "C" { diff --git a/ports/atmega168/apdu.c b/ports/atmega168/apdu.c index 3cc2469e..ec36b041 100644 --- a/ports/atmega168/apdu.c +++ b/ports/atmega168/apdu.c @@ -34,12 +34,12 @@ #include #include #include -#include "bits.h" -#include "apdu.h" -#include "bacdef.h" -#include "bacdcode.h" -#include "bacenum.h" -#include "handlers.h" +#include "bacnet/bits.h" +#include "bacnet/apdu.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacenum.h" +#include "bacnet/basic/services.h" bool apdu_service_supported( BACNET_SERVICES_SUPPORTED service_supported) diff --git a/ports/atmega168/av.c b/ports/atmega168/av.c index 308c3550..8ebc1ead 100644 --- a/ports/atmega168/av.c +++ b/ports/atmega168/av.c @@ -28,13 +28,17 @@ #include #include #include "hardware.h" -#include "bacdef.h" -#include "bacdcode.h" -#include "bacenum.h" -#include "bacapp.h" -#include "config.h" /* the custom stuff */ -#include "wp.h" -#include "av.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacenum.h" +#include "bacnet/bacapp.h" +#include "bacnet/config.h" /* the custom stuff */ +#include "bacnet/wp.h" +#include "bacnet/basic/object/av.h" + +#ifndef MAX_ANALOG_VALUES +#define MAX_ANALOG_VALUES 10 +#endif #if (MAX_ANALOG_VALUES > 10) #error Modify the Analog_Value_Name to handle multiple digits @@ -92,28 +96,25 @@ char *Analog_Value_Name( } /* return apdu len, or -1 on error */ -int Analog_Value_Encode_Property_APDU( - uint8_t * apdu, - uint32_t object_instance, - BACNET_PROPERTY_ID property, - uint32_t array_index, - BACNET_ERROR_CLASS * error_class, - BACNET_ERROR_CODE * error_code) +int Analog_Value_Read_Property( + BACNET_READ_PROPERTY_DATA * rpdata) { int apdu_len = 0; /* return value */ BACNET_BIT_STRING bit_string; BACNET_CHARACTER_STRING char_string; unsigned object_index; + uint8_t *apdu; - switch (property) { + apdu = rpdata->application_data; + switch (rpdata->object_property) { case PROP_OBJECT_IDENTIFIER: apdu_len = encode_application_object_id(&apdu[0], OBJECT_ANALOG_VALUE, - object_instance); + rpdata->object_instance); break; case PROP_OBJECT_NAME: characterstring_init_ansi(&char_string, - Analog_Value_Name(object_instance)); + Analog_Value_Name(rpdata->object_instance)); apdu_len = encode_application_character_string(&apdu[0], &char_string); break; @@ -122,7 +123,8 @@ int Analog_Value_Encode_Property_APDU( encode_application_enumerated(&apdu[0], OBJECT_ANALOG_VALUE); break; case PROP_PRESENT_VALUE: - object_index = Analog_Value_Instance_To_Index(object_instance); + object_index = Analog_Value_Instance_To_Index( + rpdata->object_instance); apdu_len = encode_application_real(&apdu[0], AV_Present_Value[object_index]); @@ -146,16 +148,17 @@ int Analog_Value_Encode_Property_APDU( apdu_len = encode_application_enumerated(&apdu[0], UNITS_PERCENT); break; default: - *error_class = ERROR_CLASS_PROPERTY; - *error_code = ERROR_CODE_UNKNOWN_PROPERTY; - apdu_len = -1; + rpdata->error_class = ERROR_CLASS_PROPERTY; + rpdata->error_code = ERROR_CODE_UNKNOWN_PROPERTY; + apdu_len = BACNET_STATUS_ERROR; break; } /* only array properties can have array options */ - if ((apdu_len >= 0) && (array_index != BACNET_ARRAY_ALL)) { - *error_class = ERROR_CLASS_PROPERTY; - *error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY; - apdu_len = -1; + if ((apdu_len >= 0) && + (rpdata->array_index != BACNET_ARRAY_ALL)) { + rpdata->error_class = ERROR_CLASS_PROPERTY; + rpdata->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY; + apdu_len = BACNET_STATUS_ERROR; } return apdu_len; @@ -163,9 +166,7 @@ int Analog_Value_Encode_Property_APDU( /* returns true if successful */ bool Analog_Value_Write_Property( - BACNET_WRITE_PROPERTY_DATA * wp_data, - BACNET_ERROR_CLASS * error_class, - BACNET_ERROR_CODE * error_code) + BACNET_WRITE_PROPERTY_DATA * wp_data) { bool status = false; /* return value */ unsigned int object_index = 0; @@ -173,8 +174,8 @@ bool Analog_Value_Write_Property( BACNET_APPLICATION_DATA_VALUE value; if (!Analog_Value_Valid_Instance(wp_data->object_instance)) { - *error_class = ERROR_CLASS_OBJECT; - *error_code = ERROR_CODE_UNKNOWN_OBJECT; + wp_data->error_class = ERROR_CLASS_OBJECT; + wp_data->error_code = ERROR_CODE_UNKNOWN_OBJECT; return false; } /* decode the some of the request */ @@ -184,15 +185,15 @@ bool Analog_Value_Write_Property( /* FIXME: len < application_data_len: more data? */ if (len < 0) { /* error while decoding - a value larger than we can handle */ - *error_class = ERROR_CLASS_PROPERTY; - *error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; + wp_data->error_class = ERROR_CLASS_PROPERTY; + wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; return false; } if ((wp_data->object_property != PROP_PRIORITY_ARRAY) && (wp_data->array_index != BACNET_ARRAY_ALL)) { /* only array properties can have array options */ - *error_class = ERROR_CLASS_PROPERTY; - *error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY; + wp_data->error_class = ERROR_CLASS_PROPERTY; + wp_data->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY; return false; } switch (wp_data->object_property) { @@ -203,8 +204,8 @@ bool Analog_Value_Write_Property( AV_Present_Value[object_index] = value.type.Real; status = true; } else { - *error_class = ERROR_CLASS_PROPERTY; - *error_code = ERROR_CODE_INVALID_DATA_TYPE; + wp_data->error_class = ERROR_CLASS_PROPERTY; + wp_data->error_code = ERROR_CODE_INVALID_DATA_TYPE; } break; case PROP_OBJECT_IDENTIFIER: @@ -215,12 +216,12 @@ bool Analog_Value_Write_Property( case PROP_OUT_OF_SERVICE: case PROP_DESCRIPTION: case PROP_PRIORITY_ARRAY: - *error_class = ERROR_CLASS_PROPERTY; - *error_code = ERROR_CODE_WRITE_ACCESS_DENIED; + wp_data->error_class = ERROR_CLASS_PROPERTY; + wp_data->error_code = ERROR_CODE_WRITE_ACCESS_DENIED; break; default: - *error_class = ERROR_CLASS_PROPERTY; - *error_code = ERROR_CODE_UNKNOWN_PROPERTY; + wp_data->error_class = ERROR_CLASS_PROPERTY; + wp_data->error_code = ERROR_CODE_UNKNOWN_PROPERTY; break; } diff --git a/ports/atmega168/av.h b/ports/atmega168/av.h index 40f84fe8..68aae2b2 100644 --- a/ports/atmega168/av.h +++ b/ports/atmega168/av.h @@ -27,9 +27,9 @@ #include #include -#include "bacdef.h" -#include "bacerror.h" -#include "wp.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacerror.h" +#include "bacnet/wp.h" #ifndef MAX_ANALOG_VALUES #define MAX_ANALOG_VALUES 4 diff --git a/ports/atmega168/bacnet.aps b/ports/atmega168/bacnet.aps index 8af9deef..5cc49d2d 100644 --- a/ports/atmega168/bacnet.aps +++ b/ports/atmega168/bacnet.aps @@ -1 +1 @@ -13-Aug-2007 15:08:2714-Nov-2008 08:40:02013-Aug-2007 15:08:2744, 13, 0, 528AVR GCC241bacnet13-Aug-2007 15:11:0713-Aug-2007 15:11:07241013-Aug-2007 15:11:0744, 13, 0, 528AVR GCCbacnet.elfATMEGA168falseR00R01R02R03R04R05R06R07R08R09R10R11R12R13R14R15R16R17R18R19R20R21R22R23R24R25R26R27R28R29R30R31AVR DragonAVR SimulatorATmega168.xmlAuto00property_lenobject_indexPresent_Valuevalue0main.crs485.ctimer.cdlmstp.c..\..\demo\handler\txbuf.cdevice.cstack.c..\..\src\crc.c..\..\src\npdu.capdu.ch_rp.c..\..\src\iam.cav.ch_wp.c..\..\src\bacapp.c..\..\src\bacstr.cbv.ch_whois.c..\..\src\whois.cavr035.hhardware.hrs485.htimer.hstack.h..\..\include\crc.h..\..\include\dlmstp.h..\..\include\iam.h..\..\include\npdu.h..\..\include\txbuf.h..\..\include\bacenum.h..\..\include\bacdcode.h..\..\include\bacapp.h..\..\include\bacstr.hMakefiledefaultYESMakefileatmega168100bacnet.elfdefault\0..\..\demo\handler\.\..\..\..\..\demo\object\-Wall -gdwarf-2 -DMAX_APDU=50 -DBACDL_MSTP -DBIG_ENDIAN=0 -DF_CPU=7372800UL -O0 -fsigned-chardefault1C:\WinAVR-20071221rc1\bin\avr-gcc.exeC:\WinAVR-20071221rc1\utils\bin\make.exe0282161937372800011000001920010000000001011main100000main.c25900001dlmstp.c25900003bv.c25800005apdu.c25800006h_whois.c25700007h_wp.c257 +13-Aug-2007 15:08:2714-Nov-2008 08:40:02013-Aug-2007 15:08:2744, 13, 0, 528AVR GCC241bacnet13-Aug-2007 15:11:0713-Aug-2007 15:11:07241013-Aug-2007 15:11:0744, 13, 0, 528AVR GCCbacnet.elfATMEGA168falseR00R01R02R03R04R05R06R07R08R09R10R11R12R13R14R15R16R17R18R19R20R21R22R23R24R25R26R27R28R29R30R31AVR DragonAVR SimulatorATmega168.xmlAuto00property_lenobject_indexPresent_Valuevalue0main.crs485.ctimer.cdlmstp.c..\..\demo\handler\txbuf.cdevice.cstack.c..\..\src\crc.c..\..\src\npdu.capdu.ch_rp.c..\..\src\iam.cav.ch_wp.c..\..\src\bacapp.c..\..\src\bacstr.cbv.ch_whois.c..\..\src\whois.cavr035.hhardware.hrs485.htimer.hstack.h..\..\include\crc.h..\..\include\dlmstp.h..\..\include\iam.h..\..\include\npdu.h..\..\include\txbuf.h..\..\include\bacenum.h..\..\include\bacdcode.h..\..\include\bacapp.h..\..\include\bacstr.hMakefiledefaultYESMakefileatmega168100bacnet.elfdefault\0..\..\demo\handler\.\..\..\..\..\demo\object\-Wall -gdwarf-2 -DMAX_APDU=50 -DBACDL_MSTP -DBIG_ENDIAN=0 -DF_CPU=7372800UL -O0 -fsigned-chardefault1C:\WinAVR-20071221rc1\bin\avr-gcc.exeC:\WinAVR-20071221rc1\utils\bin\make.exe0282161937372800011000001920010000000001011main100000main.c25900001dlmstp.c25900003bv.c25800005apdu.c25800006h_whois.c25700007h_wp.c257 diff --git a/ports/atmega168/bacnet.ewp b/ports/atmega168/bacnet.ewp index aba2c7e0..2517d36f 100644 --- a/ports/atmega168/bacnet.ewp +++ b/ports/atmega168/bacnet.ewp @@ -10,9 +10,9 @@ 1 General - 11 + 12 - 9 + 10 1 1 + + @@ -246,7 +254,7 @@ @@ -719,9 +728,9 @@ XLINK - 2 + 3 - 14 + 16 1 1 + + + + + + + + + + @@ -1022,9 +1071,9 @@ 0 General - 11 + 12 - 9 + 10 1 0 + + @@ -1424,7 +1481,7 @@ @@ -1732,9 +1790,9 @@ XLINK - 2 + 3 - 14 + 16 1 0 + + + + + + + + + + @@ -2030,63 +2128,63 @@ - BACnet-Core + BACnet-Basic - $PROJ_DIR$\..\..\src\abort.c + $PROJ_DIR$\..\..\src\bacnet\datalink\crc.c - $PROJ_DIR$\..\..\src\bacapp.c + $PROJ_DIR$\..\..\src\bacnet\basic\service\h_noserv.c - $PROJ_DIR$\..\..\src\bacdcode.c + $PROJ_DIR$\..\..\src\bacnet\basic\npdu\h_npdu.c - $PROJ_DIR$\..\..\src\bacerror.c + $PROJ_DIR$\..\..\src\bacnet\basic\service\s_iam.c - $PROJ_DIR$\..\..\src\bacint.c - - - $PROJ_DIR$\..\..\src\bacreal.c - - - $PROJ_DIR$\..\..\src\bacstr.c - - - $PROJ_DIR$\..\..\src\crc.c - - - $PROJ_DIR$\..\..\src\iam.c - - - $PROJ_DIR$\..\..\src\npdu.c - - - $PROJ_DIR$\..\..\src\reject.c - - - $PROJ_DIR$\..\..\src\rp.c - - - $PROJ_DIR$\..\..\src\whois.c - - - $PROJ_DIR$\..\..\src\wp.c + $PROJ_DIR$\..\..\src\bacnet\basic\tsm\tsm.c - BACnet-Handlers + BACnet-Core - $PROJ_DIR$\..\..\demo\handler\h_npdu.c + $PROJ_DIR$\..\..\src\bacnet\abort.c - $PROJ_DIR$\..\..\demo\handler\noserv.c + $PROJ_DIR$\..\..\src\bacnet\bacapp.c - $PROJ_DIR$\..\..\demo\handler\s_iam.c + $PROJ_DIR$\..\..\src\bacnet\bacdcode.c - $PROJ_DIR$\..\..\demo\handler\txbuf.c + $PROJ_DIR$\..\..\src\bacnet\bacerror.c + + + $PROJ_DIR$\..\..\src\bacnet\bacint.c + + + $PROJ_DIR$\..\..\src\bacnet\bacreal.c + + + $PROJ_DIR$\..\..\src\bacnet\bacstr.c + + + $PROJ_DIR$\..\..\src\bacnet\iam.c + + + $PROJ_DIR$\..\..\src\bacnet\npdu.c + + + $PROJ_DIR$\..\..\src\bacnet\reject.c + + + $PROJ_DIR$\..\..\src\bacnet\rp.c + + + $PROJ_DIR$\..\..\src\bacnet\whois.c + + + $PROJ_DIR$\..\..\src\bacnet\wp.c @@ -2095,9 +2193,6 @@ $PROJ_DIR$\av.c - - $PROJ_DIR$\avr035.h - $PROJ_DIR$\bv.c diff --git a/ports/atmega168/bv.c b/ports/atmega168/bv.c index e7493b39..416033fe 100644 --- a/ports/atmega168/bv.c +++ b/ports/atmega168/bv.c @@ -29,12 +29,16 @@ #include #include #include "hardware.h" -#include "bacdef.h" -#include "bacdcode.h" -#include "bacenum.h" -#include "config.h" /* the custom stuff */ -#include "wp.h" -#include "bv.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacenum.h" +#include "bacnet/config.h" /* the custom stuff */ +#include "bacnet/wp.h" +#include "bacnet/basic/object/bv.h" + +#ifndef MAX_BINARY_VALUES +#define MAX_BINARY_VALUES 10 +#endif #if (MAX_BINARY_VALUES > 10) #error Modify the Binary_Value_Name to handle multiple digits @@ -105,31 +109,28 @@ char *Binary_Value_Name( } /* return apdu len, or -1 on error */ -int Binary_Value_Encode_Property_APDU( - uint8_t * apdu, - uint32_t object_instance, - BACNET_PROPERTY_ID property, - uint32_t array_index, - BACNET_ERROR_CLASS * error_class, - BACNET_ERROR_CODE * error_code) +int Binary_Value_Read_Property( + BACNET_READ_PROPERTY_DATA * rpdata) { int apdu_len = 0; /* return value */ BACNET_BIT_STRING bit_string; BACNET_CHARACTER_STRING char_string; BACNET_BINARY_PV present_value = BINARY_INACTIVE; BACNET_POLARITY polarity = POLARITY_NORMAL; + uint8_t *apdu; - switch (property) { + apdu = rpdata->application_data; + switch (rpdata->object_property) { case PROP_OBJECT_IDENTIFIER: apdu_len = encode_application_object_id(&apdu[0], OBJECT_BINARY_VALUE, - object_instance); + rpdata->object_instance); break; /* note: Name and Description don't have to be the same. You could make Description writable and different */ case PROP_OBJECT_NAME: characterstring_init_ansi(&char_string, - Binary_Value_Name(object_instance)); + Binary_Value_Name(rpdata->object_instance)); apdu_len = encode_application_character_string(&apdu[0], &char_string); break; @@ -138,7 +139,7 @@ int Binary_Value_Encode_Property_APDU( encode_application_enumerated(&apdu[0], OBJECT_BINARY_VALUE); break; case PROP_PRESENT_VALUE: - present_value = Binary_Value_Present_Value(object_instance); + present_value = Binary_Value_Present_Value(rpdata->object_instance); apdu_len = encode_application_enumerated(&apdu[0], present_value); break; case PROP_STATUS_FLAGS: @@ -163,16 +164,16 @@ int Binary_Value_Encode_Property_APDU( apdu_len = encode_application_enumerated(&apdu[0], polarity); break; default: - *error_class = ERROR_CLASS_PROPERTY; - *error_code = ERROR_CODE_UNKNOWN_PROPERTY; - apdu_len = -1; + rpdata->error_class = ERROR_CLASS_PROPERTY; + rpdata->error_code = ERROR_CODE_UNKNOWN_PROPERTY; + apdu_len = BACNET_STATUS_ERROR; break; } /* only array properties can have array options */ - if ((apdu_len >= 0) && (array_index != BACNET_ARRAY_ALL)) { - *error_class = ERROR_CLASS_PROPERTY; - *error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY; - apdu_len = -1; + if ((apdu_len >= 0) && (rpdata->array_index != BACNET_ARRAY_ALL)) { + rpdata->error_class = ERROR_CLASS_PROPERTY; + rpdata->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY; + apdu_len = BACNET_STATUS_ERROR; } return apdu_len; @@ -180,9 +181,7 @@ int Binary_Value_Encode_Property_APDU( /* returns true if successful */ bool Binary_Value_Write_Property( - BACNET_WRITE_PROPERTY_DATA * wp_data, - BACNET_ERROR_CLASS * error_class, - BACNET_ERROR_CODE * error_code) + BACNET_WRITE_PROPERTY_DATA * wp_data) { bool status = false; /* return value */ unsigned int object_index = 0; @@ -190,8 +189,8 @@ bool Binary_Value_Write_Property( BACNET_APPLICATION_DATA_VALUE value; if (!Binary_Value_Valid_Instance(wp_data->object_instance)) { - *error_class = ERROR_CLASS_OBJECT; - *error_code = ERROR_CODE_UNKNOWN_OBJECT; + wp_data->error_class = ERROR_CLASS_OBJECT; + wp_data->error_code = ERROR_CODE_UNKNOWN_OBJECT; return false; } /* decode the some of the request */ @@ -201,15 +200,15 @@ bool Binary_Value_Write_Property( /* FIXME: len < application_data_len: more data? */ if (len < 0) { /* error while decoding - a value larger than we can handle */ - *error_class = ERROR_CLASS_PROPERTY; - *error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; + wp_data->error_class = ERROR_CLASS_PROPERTY; + wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; return false; } if ((wp_data->object_property != PROP_PRIORITY_ARRAY) && (wp_data->array_index != BACNET_ARRAY_ALL)) { /* only array properties can have array options */ - *error_class = ERROR_CLASS_PROPERTY; - *error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY; + wp_data->error_class = ERROR_CLASS_PROPERTY; + wp_data->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY; return false; } switch (wp_data->object_property) { @@ -234,12 +233,12 @@ bool Binary_Value_Write_Property( } status = true; } else { - *error_class = ERROR_CLASS_PROPERTY; - *error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; + wp_data->error_class = ERROR_CLASS_PROPERTY; + wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; } } else { - *error_class = ERROR_CLASS_PROPERTY; - *error_code = ERROR_CODE_INVALID_DATA_TYPE; + wp_data->error_class = ERROR_CLASS_PROPERTY; + wp_data->error_code = ERROR_CODE_INVALID_DATA_TYPE; } break; case PROP_OUT_OF_SERVICE: @@ -250,8 +249,8 @@ bool Binary_Value_Write_Property( Binary_Value_Out_Of_Service[object_index] = value.type.Boolean; status = true; } else { - *error_class = ERROR_CLASS_PROPERTY; - *error_code = ERROR_CODE_INVALID_DATA_TYPE; + wp_data->error_class = ERROR_CLASS_PROPERTY; + wp_data->error_code = ERROR_CODE_INVALID_DATA_TYPE; } break; #endif @@ -261,12 +260,12 @@ bool Binary_Value_Write_Property( case PROP_STATUS_FLAGS: case PROP_EVENT_STATE: case PROP_POLARITY: - *error_class = ERROR_CLASS_PROPERTY; - *error_code = ERROR_CODE_WRITE_ACCESS_DENIED; + wp_data->error_class = ERROR_CLASS_PROPERTY; + wp_data->error_code = ERROR_CODE_WRITE_ACCESS_DENIED; break; default: - *error_class = ERROR_CLASS_PROPERTY; - *error_code = ERROR_CODE_UNKNOWN_PROPERTY; + wp_data->error_class = ERROR_CLASS_PROPERTY; + wp_data->error_code = ERROR_CODE_UNKNOWN_PROPERTY; break; } diff --git a/ports/atmega168/bv.h b/ports/atmega168/bv.h index 731f3e48..ae4c5a50 100644 --- a/ports/atmega168/bv.h +++ b/ports/atmega168/bv.h @@ -27,9 +27,9 @@ #include #include -#include "bacdef.h" -#include "bacerror.h" -#include "wp.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacerror.h" +#include "bacnet/wp.h" #ifndef MAX_BINARY_VALUES #define MAX_BINARY_VALUES 10 diff --git a/ports/atmega168/device.c b/ports/atmega168/device.c index aaaeb622..849d0508 100644 --- a/ports/atmega168/device.c +++ b/ports/atmega168/device.c @@ -25,21 +25,22 @@ #include #include -#include "bacdef.h" -#include "bacdcode.h" -#include "bacstr.h" -#include "bacenum.h" -#include "apdu.h" -#include "dcc.h" -#include "dlmstp.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacstr.h" +#include "bacnet/bacenum.h" +#include "bacnet/apdu.h" +#include "bacnet/dcc.h" +#include "bacnet/datalink/dlmstp.h" #include "rs485.h" -#include "version.h" +#include "bacnet/version.h" #include "stack.h" /* objects */ -#include "device.h" -#include "av.h" -#include "bv.h" -#include "wp.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/object/device.h" +#include "bacnet/basic/object/av.h" +#include "bacnet/basic/object/bv.h" +#include "bacnet/wp.h" /* note: you really only need to define variables for properties that are writable or that may change. @@ -50,8 +51,9 @@ static char Object_Name[20] = "My Device"; static BACNET_DEVICE_STATUS System_Status = STATUS_OPERATIONAL; void Device_Init( - void) + object_functions_t * object_table) { + (void)object_table; /* Reinitialize_State = BACNET_REINIT_IDLE; */ /* dcc_set_status_duration(COMMUNICATION_ENABLE, 0); */ /* FIXME: Get the data from the eeprom */ @@ -161,14 +163,10 @@ bool Device_Object_List_Identifier( } /* return the length of the apdu encoded or -1 for error */ -int Device_Encode_Property_APDU( - uint8_t * apdu, - uint32_t object_instance, - BACNET_PROPERTY_ID property, - uint32_t array_index, - BACNET_ERROR_CLASS * error_class, - BACNET_ERROR_CODE * error_code) +int Device_Read_Property( + BACNET_READ_PROPERTY_DATA * rpdata) { + uint8_t * apdu; int apdu_len = 0; /* return value */ int len = 0; /* apdu len intermediate value */ BACNET_BIT_STRING bit_string; @@ -178,9 +176,8 @@ int Device_Encode_Property_APDU( uint32_t instance = 0; uint32_t count = 0; - object_instance = object_instance; - /* FIXME: change the hardcoded names to suit your application */ - switch (property) { + apdu = rpdata->application_data; + switch (rpdata->object_property) { case PROP_OBJECT_IDENTIFIER: apdu_len = encode_application_object_id(&apdu[0], OBJECT_DEVICE, @@ -259,13 +256,13 @@ int Device_Encode_Property_APDU( case PROP_OBJECT_LIST: count = Device_Object_List_Count(); /* Array element zero is the number of objects in the list */ - if (array_index == 0) + if (rpdata->array_index == 0) apdu_len = encode_application_unsigned(&apdu[0], count); /* if no index was specified, then try to encode the entire list */ /* into one packet. Note that more than likely you will have */ /* to return an error if the number of encoded objects exceeds */ /* your maximum APDU size. */ - else if (array_index == BACNET_ARRAY_ALL) { + else if (rpdata->array_index == BACNET_ARRAY_ALL) { for (i = 1; i <= count; i++) { Device_Object_List_Identifier(i, &object_type, &instance); len = @@ -276,21 +273,21 @@ int Device_Encode_Property_APDU( /* can we all fit into the APDU? */ if ((apdu_len + len) >= MAX_APDU) { /* Abort response */ - *error_code = + rpdata->error_code = ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED; apdu_len = BACNET_STATUS_ABORT; break; } } } else { - if (Device_Object_List_Identifier(array_index, &object_type, - &instance)) + if (Device_Object_List_Identifier(rpdata->array_index, + &object_type, &instance)) apdu_len = encode_application_object_id(&apdu[0], object_type, instance); else { - *error_class = ERROR_CLASS_PROPERTY; - *error_code = ERROR_CODE_INVALID_ARRAY_INDEX; + rpdata->error_class = ERROR_CLASS_PROPERTY; + rpdata->error_code = ERROR_CODE_INVALID_ARRAY_INDEX; apdu_len = BACNET_STATUS_ERROR; } } @@ -323,27 +320,27 @@ int Device_Encode_Property_APDU( apdu_len = encode_application_unsigned(&apdu[0], dlmstp_max_master()); break; - case 9600: + case (BACNET_PROPERTY_ID)9600: apdu_len = encode_application_unsigned(&apdu[0], RS485_Get_Baud_Rate()); break; - case 512: + case (BACNET_PROPERTY_ID)512: apdu_len = encode_application_unsigned(&apdu[0], stack_size()); break; - case 513: + case (BACNET_PROPERTY_ID)513: apdu_len = encode_application_unsigned(&apdu[0], stack_unused()); break; default: - *error_class = ERROR_CLASS_PROPERTY; - *error_code = ERROR_CODE_UNKNOWN_PROPERTY; + rpdata->error_class = ERROR_CLASS_PROPERTY; + rpdata->error_code = ERROR_CODE_UNKNOWN_PROPERTY; apdu_len = -1; break; } /* only array properties can have array options */ - if ((apdu_len >= 0) && (property != PROP_OBJECT_LIST) && - (array_index != BACNET_ARRAY_ALL)) { - *error_class = ERROR_CLASS_PROPERTY; - *error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY; + if ((apdu_len >= 0) && (rpdata->object_property != PROP_OBJECT_LIST) && + (rpdata->array_index != BACNET_ARRAY_ALL)) { + rpdata->error_class = ERROR_CLASS_PROPERTY; + rpdata->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY; apdu_len = BACNET_STATUS_ERROR; } @@ -351,17 +348,15 @@ int Device_Encode_Property_APDU( } bool Device_Write_Property( - BACNET_WRITE_PROPERTY_DATA * wp_data, - BACNET_ERROR_CLASS * error_class, - BACNET_ERROR_CODE * error_code) + BACNET_WRITE_PROPERTY_DATA * wp_data) { bool status = false; /* return value */ int len = 0; BACNET_APPLICATION_DATA_VALUE value; if (!Device_Valid_Object_Instance_Number(wp_data->object_instance)) { - *error_class = ERROR_CLASS_OBJECT; - *error_code = ERROR_CODE_UNKNOWN_OBJECT; + wp_data->error_class = ERROR_CLASS_OBJECT; + wp_data->error_code = ERROR_CODE_UNKNOWN_OBJECT; return false; } /* decode the some of the request */ @@ -371,15 +366,15 @@ bool Device_Write_Property( /* FIXME: len < application_data_len: more data? */ if (len < 0) { /* error while decoding - a value larger than we can handle */ - *error_class = ERROR_CLASS_PROPERTY; - *error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; + wp_data->error_class = ERROR_CLASS_PROPERTY; + wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; return false; } if ((wp_data->object_property != PROP_OBJECT_LIST) && (wp_data->array_index != BACNET_ARRAY_ALL)) { /* only array properties can have array options */ - *error_class = ERROR_CLASS_PROPERTY; - *error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY; + wp_data->error_class = ERROR_CLASS_PROPERTY; + wp_data->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY; return false; } switch (wp_data->object_property) { @@ -391,12 +386,12 @@ bool Device_Write_Property( /* we could send an I-Am broadcast to let the world know */ status = true; } else { - *error_class = ERROR_CLASS_PROPERTY; - *error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; + wp_data->error_class = ERROR_CLASS_PROPERTY; + wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; } } else { - *error_class = ERROR_CLASS_PROPERTY; - *error_code = ERROR_CODE_INVALID_DATA_TYPE; + wp_data->error_class = ERROR_CLASS_PROPERTY; + wp_data->error_code = ERROR_CODE_INVALID_DATA_TYPE; } break; case PROP_MAX_INFO_FRAMES: @@ -405,12 +400,12 @@ bool Device_Write_Property( dlmstp_set_max_info_frames(value.type.Unsigned_Int); status = true; } else { - *error_class = ERROR_CLASS_PROPERTY; - *error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; + wp_data->error_class = ERROR_CLASS_PROPERTY; + wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; } } else { - *error_class = ERROR_CLASS_PROPERTY; - *error_code = ERROR_CODE_INVALID_DATA_TYPE; + wp_data->error_class = ERROR_CLASS_PROPERTY; + wp_data->error_code = ERROR_CODE_INVALID_DATA_TYPE; } break; case PROP_MAX_MASTER: @@ -420,12 +415,12 @@ bool Device_Write_Property( dlmstp_set_max_master(value.type.Unsigned_Int); status = true; } else { - *error_class = ERROR_CLASS_PROPERTY; - *error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; + wp_data->error_class = ERROR_CLASS_PROPERTY; + wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; } } else { - *error_class = ERROR_CLASS_PROPERTY; - *error_code = ERROR_CODE_INVALID_DATA_TYPE; + wp_data->error_class = ERROR_CLASS_PROPERTY; + wp_data->error_code = ERROR_CODE_INVALID_DATA_TYPE; } break; case PROP_OBJECT_NAME: @@ -440,30 +435,30 @@ bool Device_Write_Property( &value.type.Character_String)) { status = true; } else { - *error_class = ERROR_CLASS_PROPERTY; - *error_code = ERROR_CODE_NO_SPACE_TO_WRITE_PROPERTY; + wp_data->error_class = ERROR_CLASS_PROPERTY; + wp_data->error_code = ERROR_CODE_NO_SPACE_TO_WRITE_PROPERTY; } } else { - *error_class = ERROR_CLASS_PROPERTY; - *error_code = ERROR_CODE_CHARACTER_SET_NOT_SUPPORTED; + wp_data->error_class = ERROR_CLASS_PROPERTY; + wp_data->error_code = ERROR_CODE_CHARACTER_SET_NOT_SUPPORTED; } } else { - *error_class = ERROR_CLASS_PROPERTY; - *error_code = ERROR_CODE_INVALID_DATA_TYPE; + wp_data->error_class = ERROR_CLASS_PROPERTY; + wp_data->error_code = ERROR_CODE_INVALID_DATA_TYPE; } break; - case 9600: + case (BACNET_PROPERTY_ID)9600: if (value.tag == BACNET_APPLICATION_TAG_UNSIGNED_INT) { if (value.type.Unsigned_Int > 115200) { RS485_Set_Baud_Rate(value.type.Unsigned_Int); status = true; } else { - *error_class = ERROR_CLASS_PROPERTY; - *error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; + wp_data->error_class = ERROR_CLASS_PROPERTY; + wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; } } else { - *error_class = ERROR_CLASS_PROPERTY; - *error_code = ERROR_CODE_INVALID_DATA_TYPE; + wp_data->error_class = ERROR_CLASS_PROPERTY; + wp_data->error_code = ERROR_CODE_INVALID_DATA_TYPE; } break; case PROP_NUMBER_OF_APDU_RETRIES: @@ -490,12 +485,12 @@ bool Device_Write_Property( case PROP_DEVICE_ADDRESS_BINDING: case PROP_DATABASE_REVISION: case PROP_ACTIVE_COV_SUBSCRIPTIONS: - *error_class = ERROR_CLASS_PROPERTY; - *error_code = ERROR_CODE_WRITE_ACCESS_DENIED; + wp_data->error_class = ERROR_CLASS_PROPERTY; + wp_data->error_code = ERROR_CODE_WRITE_ACCESS_DENIED; break; default: - *error_class = ERROR_CLASS_PROPERTY; - *error_code = ERROR_CODE_UNKNOWN_PROPERTY; + wp_data->error_class = ERROR_CLASS_PROPERTY; + wp_data->error_code = ERROR_CODE_UNKNOWN_PROPERTY; break; } diff --git a/ports/atmega168/device.h b/ports/atmega168/device.h index 189b015d..f347bc27 100644 --- a/ports/atmega168/device.h +++ b/ports/atmega168/device.h @@ -36,10 +36,10 @@ #include #include -#include "bacdef.h" -#include "bacenum.h" -#include "wp.h" -#include "readrange.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacenum.h" +#include "bacnet/wp.h" +#include "bacnet/readrange.h" typedef unsigned ( *object_count_function) ( diff --git a/ports/atmega168/dlmstp.c b/ports/atmega168/dlmstp.c index db3205db..52171ee0 100644 --- a/ports/atmega168/dlmstp.c +++ b/ports/atmega168/dlmstp.c @@ -36,18 +36,18 @@ #include #include #include -#include "bacdef.h" -#include "mstpdef.h" -#include "dlmstp.h" +#include "bacnet/bacdef.h" +#include "bacnet/datalink/mstpdef.h" +#include "bacnet/datalink/dlmstp.h" #include "rs485.h" -#include "crc.h" -#include "npdu.h" -#include "bits.h" -#include "bytes.h" -#include "bacaddr.h" +#include "bacnet/datalink/crc.h" +#include "bacnet/npdu.h" +#include "bacnet/bits.h" +#include "bacnet/bytes.h" +#include "bacnet/bacaddr.h" /* special optimization - I-Am response in this module */ -#include "client.h" -#include "txbuf.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/tsm/tsm.h" /* This file has been customized for use with small microprocessors */ /* Assumptions: diff --git a/ports/atmega168/h_rp.c b/ports/atmega168/h_rp.c index c6efee86..b6ba0c8a 100644 --- a/ports/atmega168/h_rp.c +++ b/ports/atmega168/h_rp.c @@ -27,63 +27,53 @@ #include #include #include -#include "config.h" -#include "txbuf.h" -#include "bacdef.h" -#include "bacdcode.h" -#include "bacerror.h" -#include "apdu.h" -#include "npdu.h" -#include "abort.h" -#include "rp.h" +#include "bacnet/config.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/datalink/datalink.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacerror.h" +#include "bacnet/apdu.h" +#include "bacnet/npdu.h" +#include "bacnet/abort.h" +#include "bacnet/rp.h" /* demo objects */ -#include "device.h" -#include "av.h" -#include "bv.h" +#include "bacnet/basic/object/device.h" +#include "bacnet/basic/object/av.h" +#include "bacnet/basic/object/bv.h" /* Encodes the property APDU and returns the length, or sets the error, and returns -1 */ int Encode_Property_APDU( uint8_t * apdu, - BACNET_READ_PROPERTY_DATA * rp_data, - BACNET_ERROR_CLASS * error_class, - BACNET_ERROR_CODE * error_code) + BACNET_READ_PROPERTY_DATA * rpdata) { int apdu_len = -1; /* handle each object type */ - switch (rp_data->object_type) { + switch (rpdata->object_type) { case OBJECT_DEVICE: /* Test for case of indefinite Device object instance */ - if (rp_data->object_instance == BACNET_MAX_INSTANCE) { - rp_data->object_instance = Device_Object_Instance_Number(); + if (rpdata->object_instance == BACNET_MAX_INSTANCE) { + rpdata->object_instance = Device_Object_Instance_Number(); } - if (Device_Valid_Object_Instance_Number(rp_data->object_instance)) { - apdu_len = - Device_Encode_Property_APDU(&apdu[0], - rp_data->object_instance, rp_data->object_property, - rp_data->array_index, error_class, error_code); + if (Device_Valid_Object_Instance_Number(rpdata->object_instance)) { + apdu_len = Device_Read_Property(rpdata); } break; case OBJECT_ANALOG_VALUE: - if (Analog_Value_Valid_Instance(rp_data->object_instance)) { - apdu_len = - Analog_Value_Encode_Property_APDU(&apdu[0], - rp_data->object_instance, rp_data->object_property, - rp_data->array_index, error_class, error_code); + if (Analog_Value_Valid_Instance(rpdata->object_instance)) { + apdu_len = Analog_Value_Read_Property(rpdata); } break; case OBJECT_BINARY_VALUE: - if (Binary_Value_Valid_Instance(rp_data->object_instance)) { - apdu_len = - Binary_Value_Encode_Property_APDU(&apdu[0], - rp_data->object_instance, rp_data->object_property, - rp_data->array_index, error_class, error_code); + if (Binary_Value_Valid_Instance(rpdata->object_instance)) { + apdu_len = Binary_Value_Read_Property(rpdata); } break; default: - *error_class = ERROR_CLASS_OBJECT; - *error_code = ERROR_CODE_UNKNOWN_OBJECT; + rpdata->error_class = ERROR_CLASS_OBJECT; + rpdata->error_code = ERROR_CODE_UNKNOWN_OBJECT; break; } @@ -103,8 +93,6 @@ void handler_read_property( int pdu_len = 0; BACNET_NPDU_DATA npdu_data; int bytes_sent = 0; - BACNET_ERROR_CLASS error_class = ERROR_CLASS_OBJECT; - BACNET_ERROR_CODE error_code = ERROR_CODE_UNKNOWN_OBJECT; BACNET_ADDRESS my_address; /* encode the NPDU portion of the packet */ @@ -134,9 +122,11 @@ void handler_read_property( rp_ack_encode_apdu_init(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, &data); /* FIXME: add buffer len as passed into function or use smart buffer */ + data.error_class = ERROR_CLASS_OBJECT; + data.error_code = ERROR_CODE_UNKNOWN_OBJECT; property_len = Encode_Property_APDU(&Handler_Transmit_Buffer[pdu_len + ack_len], - &data, &error_class, &error_code); + &data); if (property_len >= 0) { len = rp_ack_encode_apdu_object_property_end(&Handler_Transmit_Buffer @@ -155,7 +145,7 @@ void handler_read_property( len = bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, SERVICE_CONFIRMED_READ_PROPERTY, - error_class, error_code); + data.error_class, data.error_code); break; } } diff --git a/ports/atmega168/h_whois.c b/ports/atmega168/h_whois.c index 8e5a4c0e..f84a2e3b 100644 --- a/ports/atmega168/h_whois.c +++ b/ports/atmega168/h_whois.c @@ -27,15 +27,15 @@ #include #include #include -#include "config.h" -#include "txbuf.h" -#include "bacdef.h" -#include "bacdcode.h" -#include "whois.h" -#include "iam.h" -#include "device.h" -#include "client.h" -#include "txbuf.h" +#include "bacnet/config.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/whois.h" +#include "bacnet/iam.h" +#include "bacnet/basic/object/device.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/tsm/tsm.h" bool Send_I_Am_Flag = true; diff --git a/ports/atmega168/h_wp.c b/ports/atmega168/h_wp.c index 879bcb5c..2ffa3afa 100644 --- a/ports/atmega168/h_wp.c +++ b/ports/atmega168/h_wp.c @@ -27,19 +27,20 @@ #include #include #include -#include "config.h" -#include "txbuf.h" -#include "bacdef.h" -#include "bacdcode.h" -#include "bacerror.h" -#include "apdu.h" -#include "npdu.h" -#include "abort.h" -#include "wp.h" +#include "bacnet/config.h" +#include "bacnet/datalink/datalink.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacerror.h" +#include "bacnet/apdu.h" +#include "bacnet/npdu.h" +#include "bacnet/abort.h" +#include "bacnet/wp.h" /* demo objects */ -#include "device.h" -#include "av.h" -#include "bv.h" +#include "bacnet/basic/object/device.h" +#include "bacnet/basic/object/av.h" +#include "bacnet/basic/object/bv.h" /* too big to reside on stack frame for PIC */ static BACNET_WRITE_PROPERTY_DATA wp_data; @@ -53,8 +54,6 @@ void handler_write_property( int len = 0; int pdu_len = 0; BACNET_NPDU_DATA npdu_data; - BACNET_ERROR_CLASS error_class = ERROR_CLASS_OBJECT; - BACNET_ERROR_CODE error_code = ERROR_CODE_UNKNOWN_OBJECT; int bytes_sent = 0; BACNET_ADDRESS my_address; @@ -77,9 +76,11 @@ void handler_write_property( service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true); } else { + wp_data.error_class = ERROR_CLASS_OBJECT; + wp_data.error_code = ERROR_CODE_UNKNOWN_OBJECT; switch (wp_data.object_type) { case OBJECT_DEVICE: - if (Device_Write_Property(&wp_data, &error_class, &error_code)) { + if (Device_Write_Property(&wp_data)) { len = encode_simple_ack(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, @@ -88,13 +89,12 @@ void handler_write_property( len = bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, - SERVICE_CONFIRMED_WRITE_PROPERTY, error_class, - error_code); + SERVICE_CONFIRMED_WRITE_PROPERTY, wp_data.error_class, + wp_data.error_code); } break; case OBJECT_ANALOG_VALUE: - if (Analog_Value_Write_Property(&wp_data, &error_class, - &error_code)) { + if (Analog_Value_Write_Property(&wp_data)) { len = encode_simple_ack(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, @@ -103,13 +103,12 @@ void handler_write_property( len = bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, - SERVICE_CONFIRMED_WRITE_PROPERTY, error_class, - error_code); + SERVICE_CONFIRMED_WRITE_PROPERTY, wp_data.error_class, + wp_data.error_code); } break; case OBJECT_BINARY_VALUE: - if (Binary_Value_Write_Property(&wp_data, &error_class, - &error_code)) { + if (Binary_Value_Write_Property(&wp_data)) { len = encode_simple_ack(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, @@ -118,15 +117,15 @@ void handler_write_property( len = bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, - SERVICE_CONFIRMED_WRITE_PROPERTY, error_class, - error_code); + SERVICE_CONFIRMED_WRITE_PROPERTY, wp_data.error_class, + wp_data.error_code); } break; default: len = bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY, - error_class, error_code); + wp_data.error_class, wp_data.error_code); break; } } diff --git a/ports/atmega168/hardware.h b/ports/atmega168/hardware.h index 19bf3364..d69f2f23 100644 --- a/ports/atmega168/hardware.h +++ b/ports/atmega168/hardware.h @@ -38,7 +38,7 @@ #endif #endif #include "iar2gcc.h" -#include "avr035.h" +#include "bacnet/bits.h" #define LED_NPDU_INIT() BIT_SET(DDRD, DDD5) #define LED_NPDU_ON() BIT_CLEAR(PORTD, PD5) diff --git a/ports/atmega168/main.c b/ports/atmega168/main.c index 8672f4e2..69048cd0 100644 --- a/ports/atmega168/main.c +++ b/ports/atmega168/main.c @@ -28,13 +28,13 @@ #include "hardware.h" #include "timer.h" #include "rs485.h" -#include "datalink.h" -#include "npdu.h" -#include "handlers.h" -#include "txbuf.h" -#include "iam.h" -#include "device.h" -#include "av.h" +#include "bacnet/datalink/datalink.h" +#include "bacnet/npdu.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/iam.h" +#include "bacnet/basic/object/device.h" +#include "bacnet/basic/object/av.h" /* From the WhoIs hander - performed by the DLMSTP module */ extern bool Send_I_Am_Flag; diff --git a/ports/atmega168/rs485.c b/ports/atmega168/rs485.c index 1386c7ab..0c8925ac 100644 --- a/ports/atmega168/rs485.c +++ b/ports/atmega168/rs485.c @@ -31,7 +31,7 @@ #include #include #include -/*#include "mstp.h" */ +/*#include "bacnet/datalink/mstp.h" */ /* This file has been customized for use with ATMEGA168 */ #include "hardware.h" diff --git a/ports/atmega8/Makefile b/ports/atmega8/Makefile deleted file mode 100644 index a53c8374..00000000 --- a/ports/atmega8/Makefile +++ /dev/null @@ -1,180 +0,0 @@ -############################################################################### -# Makefile for BACnet -############################################################################### - -## General Flags -PROJECT = bacnet -MCU = atmega168 -TARGET = bacnet -## Tools -CC = avr-gcc -AR = avr-ar -OBJCOPY = avr-objcopy -OBJDUMP = avr-objdump -SIZE = avr-size - -# Source locations -BACNET_CORE = ../../src -BACNET_INCLUDE = ../../include -BACNET_OBJECT_INCLUDE = ../../demo/object -BACNET_DEMO = ../../demo - -# local files for this project -CSRC = apdu.c \ - device.c \ - dlmstp.c \ - main.c \ - rs485.c \ - timer.c - -# common demo files needed -DEMOSRC = \ - $(BACNET_DEMO)/handler/h_rp.c \ - $(BACNET_DEMO)/handler/txbuf.c \ - $(BACNET_DEMO)/handler/h_npdu.c \ - $(BACNET_DEMO)/handler/noserv.c - -# core BACnet stack files - place into library -CORESRC = \ - $(BACNET_CORE)/crc.c \ - $(BACNET_CORE)/abort.c \ - $(BACNET_CORE)/apdu.c \ - $(BACNET_CORE)/bacapp.c \ - $(BACNET_CORE)/bacdcode.c \ - $(BACNET_CORE)/bacerror.c \ - $(BACNET_CORE)/bacint.c \ - $(BACNET_CORE)/bacreal.c \ - $(BACNET_CORE)/bacstr.c \ - $(BACNET_CORE)/bacaddr.c \ - $(BACNET_CORE)/npdu.c \ - $(BACNET_CORE)/reject.c \ - $(BACNET_CORE)/rp.c - -# $(BACNET_CORE)/iam.c \ -# $(BACNET_CORE)/whois.c \ -# $(BACNET_CORE)/wp.c \ -# $(BACNET_CORE)/version.c -# $(BACNET_CORE)/bacprop.c \ -# $(BACNET_CORE)/bactext.c \ -# $(BACNET_CORE)/datetime.c \ -# $(BACNET_CORE)/indtext.c \ -# $(BACNET_CORE)/bigend.c \ -# $(BACNET_CORE)/arf.c \ -# $(BACNET_CORE)/awf.c \ -# $(BACNET_CORE)/cov.c \ -# $(BACNET_CORE)/dcc.c \ -# $(BACNET_CORE)/iam/iam_client.c \ -# $(BACNET_CORE)/ihave.c \ -# $(BACNET_CORE)/rd.c \ -# $(BACNET_CORE)/rpm.c \ -# $(BACNET_CORE)/timesync.c \ -# $(BACNET_CORE)/whohas.c \ -# $(BACNET_CORE)/filename.c \ -# $(BACNET_CORE)/tsm.c \ -# $(BACNET_CORE)/address.c \ - -## Include Directories -INCLUDES = -I. -I$(BACNET_INCLUDE) -I$(BACNET_OBJECT_INCLUDE) - -# Source to Object conversion -COBJ = $(CSRC:.c=.o) -DEMOOBJ = $(DEMOSRC:.c=.o) -COREOBJ = $(CORESRC:.c=.o) - -LIBRARY = lib$(TARGET).a - -## Options common to compile, link and assembly rules -COMMON = -mmcu=$(MCU) - -OPTIMIZE_FLAGS = -mcall-prologues -#OPTIMIZE_FLAGS += -finline-functions -OPTIMIZE_FLAGS += -finline-functions-called-once -#OPTIMIZATION = -O0 -#OPTIMIZATION = -Os -OPTIMIZATION = -Os $(OPTIMIZE_FLAGS) -#OPTIMIZATION = -O3 $(OPTIMIZE_FLAGS) - -## Compile options common for all C compilation units. -BFLAGS = -DBACDL_MSTP -BFLAGS += -DMAX_APDU=50 -BFLAGS += -DBIG_ENDIAN=0 -BFLAGS += -DMAX_TSM_TRANSACTIONS=0 -#BFLAGS += -DCRC_USE_TABLE -#BFLAGS += -DBACAPP_REAL -#BFLAGS += -DBACAPP_OBJECT_ID -#BFLAGS += -DBACAPP_UNSIGNED -#BFLAGS += -DBACAPP_ENUMERATED -#BFLAGS += -DBACAPP_CHARACTER_STRING -#BFLAGS += -DWRITE_PROPERTY -BFLAGS += -DMAX_ANALOG_VALUES=0 -BFLAGS += -DMAX_BINARY_VALUES=0 -CFLAGS = $(COMMON) -# dead code removal -CFLAGS += -ffunction-sections -fdata-sections -CFLAGS += -Wall -gdwarf-2 $(BFLAGS) $(OPTIMIZATION) -fsigned-char -CFLAGS += -MD -MP -MT $(*F).o -MF dep/$(@F).d - -## Assembly specific flags -ASMFLAGS = $(COMMON) -ASMFLAGS += $(CFLAGS) -ASMFLAGS += -x assembler-with-cpp -Wa,-gdwarf2 - -## Linker flags -LDFLAGS = $(COMMON) -#dead code removal -#LDFLAGS += -Wl,-nostartfiles,-nostdlib -LDFLAGS += -Wl,--gc-sections,-static -LDFLAGS += -Wl,-Map=$(TARGET).map,-L.,-l$(TARGET) -#LDFLAGS += -Wl,-Map=$(TARGET).map - -## Intel Hex file production flags -HEX_FLASH_FLAGS = -R .eeprom -HEX_EEPROM_FLAGS = -j .eeprom -HEX_EEPROM_FLAGS += --set-section-flags=.eeprom="alloc,load" -HEX_EEPROM_FLAGS += --change-section-lma .eeprom=0 --no-change-warnings - -## Objects that must be built in order to link -OBJECTS = $(COBJ) $(DEMOOBJ) -#OBJECTS = $(COBJ) - -## Build -TARGET_ELF=$(TARGET).elf - -all: $(LIBRARY) $(TARGET_ELF) $(TARGET).hex $(TARGET).eep $(TARGET).lst \ - size Makefile - -##Link -$(TARGET_ELF): $(OBJECTS) $(LIBRARY) - $(CC) $(OBJECTS) $(LDFLAGS) -o $@ - -%.hex: $(TARGET_ELF) - $(OBJCOPY) -O ihex $(HEX_FLASH_FLAGS) $< $@ - -%.eep: $(TARGET_ELF) - -$(OBJCOPY) $(HEX_EEPROM_FLAGS) -O ihex $< $@ || exit 0 - -%.lst: $(TARGET_ELF) - $(OBJDUMP) -h -S $< > $@ - -lib: $(LIBRARY) - -$(LIBRARY): $(COREOBJ) Makefile - $(AR) rcs $@ $(COREOBJ) - $(OBJDUMP) --syms $@ > $(LIBRARY:.a=.lst) - -.c.o: - $(CC) -c $(INCLUDES) $(CFLAGS) $*.c -o $@ - -size: ${TARGET_ELF} - @echo - @${SIZE} -C --mcu=${MCU} ${TARGET_ELF} - -## Clean target -.PHONY: clean -clean: - -rm -rf $(OBJECTS) $(TARGET_ELF) dep/* - -rm -rf $(LIBRARY) $(COREOBJ) $(LIBRARY:.a=.lst) - -rm -rf $(TARGET).hex $(TARGET).eep $(TARGET).lst $(TARGET).map - -## Other dependencies --include $(shell mkdir dep 2>/dev/null) $(wildcard dep/*) diff --git a/ports/atmega8/apdu.c b/ports/atmega8/apdu.c deleted file mode 100644 index 5f31d046..00000000 --- a/ports/atmega8/apdu.c +++ /dev/null @@ -1,123 +0,0 @@ -/*####COPYRIGHTBEGIN#### - ------------------------------------------- - Copyright (C) 2007 Steve Karg - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to: - The Free Software Foundation, Inc. - 59 Temple Place - Suite 330 - Boston, MA 02111-1307, USA. - - As a special exception, if other files instantiate templates or - use macros or inline functions from this file, or you compile - this file and link it with other works to produce a work based - on this file, this file does not by itself cause the resulting - work to be covered by the GNU General Public License. However - the source code for this file must still be made available in - accordance with section (3) of the GNU General Public License. - - This exception does not invalidate any other reasons why a work - based on this file might be covered by the GNU General Public - License. - ------------------------------------------- -####COPYRIGHTEND####*/ -#include -#include -#include -#include "bits.h" -#include "apdu.h" -#include "bacdef.h" -#include "bacdcode.h" -#include "bacenum.h" -#include "handlers.h" - -bool apdu_service_supported( - BACNET_SERVICES_SUPPORTED service_supported) -{ - bool status = false; - - if (service_supported == SERVICE_SUPPORTED_READ_PROPERTY) { - status = true; - } - - return status; -} - -uint16_t apdu_decode_confirmed_service_request( - uint8_t * apdu, /* APDU data */ - uint16_t apdu_len, - BACNET_CONFIRMED_SERVICE_DATA * service_data, - uint8_t * service_choice, - uint8_t ** service_request, - uint16_t * service_request_len) -{ - uint16_t len = 0; /* counts where we are in PDU */ - - service_data->segmented_message = (apdu[0] & BIT3) ? true : false; - service_data->more_follows = (apdu[0] & BIT2) ? true : false; - service_data->segmented_response_accepted = - (apdu[0] & BIT1) ? true : false; - service_data->max_segs = decode_max_segs(apdu[1]); - service_data->max_resp = decode_max_apdu(apdu[1]); - service_data->invoke_id = apdu[2]; - len = 3; - if (service_data->segmented_message) { - service_data->sequence_number = apdu[len++]; - service_data->proposed_window_number = apdu[len++]; - } - *service_choice = apdu[len++]; - *service_request = &apdu[len]; - *service_request_len = apdu_len - len; - - return len; -} - -void apdu_handler( - BACNET_ADDRESS * src, - uint8_t * apdu, /* APDU data */ - uint16_t apdu_len) -{ - BACNET_CONFIRMED_SERVICE_DATA service_data = { 0 }; - uint8_t service_choice = 0; - uint8_t *service_request = NULL; - uint16_t service_request_len = 0; - uint16_t len = 0; /* counts where we are in PDU */ - - if (apdu) { - /* PDU Type */ - switch (apdu[0] & 0xF0) { - case PDU_TYPE_CONFIRMED_SERVICE_REQUEST: - len = apdu_decode_confirmed_service_request(&apdu[0], /* APDU data */ - apdu_len, &service_data, &service_choice, &service_request, - &service_request_len); - if (service_choice == SERVICE_CONFIRMED_READ_PROPERTY) { - handler_read_property(service_request, service_request_len, - src, &service_data); - } else { - handler_unrecognized_service(service_request, - service_request_len, src, &service_data); - } - break; - case PDU_TYPE_UNCONFIRMED_SERVICE_REQUEST: - case PDU_TYPE_SIMPLE_ACK: - case PDU_TYPE_COMPLEX_ACK: - case PDU_TYPE_SEGMENT_ACK: - case PDU_TYPE_ERROR: - case PDU_TYPE_REJECT: - case PDU_TYPE_ABORT: - default: - break; - } - } - return; -} diff --git a/ports/atmega8/avr035.h b/ports/atmega8/avr035.h deleted file mode 100644 index d53db995..00000000 --- a/ports/atmega8/avr035.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef AVR035_H -#define AVR035_H - -/* from AVR035: Efficient C Coding for AVR */ - -/* a=register, b=bit number to act upon */ -#define BIT_SET(a,b) ((a) |= (1<<(b))) -#define BIT_CLEAR(a,b) ((a) &= ~(1<<(b))) -#define BIT_FLIP(a,b) ((a) ^= (1<<(b))) -#define BIT_CHECK(a,b) ((a) & (1<<(b))) - -/* x=target variable, y=mask */ -#define BITMASK_SET(x,y) ((x) |= (y)) -#define BITMASK_CLEAR(x,y) ((x) &= (~(y))) -#define BITMASK_FLIP(x,y) ((x) ^= (y)) -#define BITMASK_CHECK(x,y) ((x) & (y)) - -#endif diff --git a/ports/atmega8/bacnet.ewp b/ports/atmega8/bacnet.ewp deleted file mode 100644 index 2191864a..00000000 --- a/ports/atmega8/bacnet.ewp +++ /dev/null @@ -1,2108 +0,0 @@ - - - - 2 - - Debug - - AVR - - 1 - - General - 11 - - 9 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ICCAVR - 6 - - 17 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - AAVR - 5 - - 11 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CUSTOM - 3 - - - - - - - BICOMP - 0 - - - - BUILDACTION - 1 - - - - - - - XLINK - 2 - - 14 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - XAR - 2 - - 0 - 1 - 1 - - - - - - - BILINK - 0 - - - - - Release - - AVR - - 0 - - General - 11 - - 9 - 1 - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ICCAVR - 6 - - 17 - 1 - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - AAVR - 5 - - 11 - 1 - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CUSTOM - 3 - - - - - - - BICOMP - 0 - - - - BUILDACTION - 1 - - - - - - - XLINK - 2 - - 14 - 1 - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - XAR - 2 - - 0 - 1 - 0 - - - - - - - BILINK - 0 - - - - - BACnet-Core - - $PROJ_DIR$\..\..\src\abort.c - - - $PROJ_DIR$\..\..\src\bacapp.c - - - $PROJ_DIR$\..\..\src\bacdcode.c - - - $PROJ_DIR$\..\..\src\bacerror.c - - - $PROJ_DIR$\..\..\src\bacint.c - - - $PROJ_DIR$\..\..\src\bacreal.c - - - $PROJ_DIR$\..\..\src\bacstr.c - - - $PROJ_DIR$\..\..\src\crc.c - - - $PROJ_DIR$\..\..\src\iam.c - - - $PROJ_DIR$\..\..\src\npdu.c - - - $PROJ_DIR$\..\..\src\reject.c - - - $PROJ_DIR$\..\..\src\rp.c - - - $PROJ_DIR$\..\..\src\whois.c - - - - BACnet-Handlers - - $PROJ_DIR$\..\..\demo\handler\h_npdu.c - - - $PROJ_DIR$\..\..\demo\handler\h_rp.c - - - $PROJ_DIR$\..\..\demo\handler\noserv.c - - - $PROJ_DIR$\..\..\demo\handler\txbuf.c - - - - $PROJ_DIR$\apdu.c - - - $PROJ_DIR$\device.c - - - $PROJ_DIR$\dlmstp.c - - - $PROJ_DIR$\main.c - - - $PROJ_DIR$\rs485.c - - - $PROJ_DIR$\timer.c - - - - diff --git a/ports/atmega8/bacnet.eww b/ports/atmega8/bacnet.eww deleted file mode 100644 index 2bf0a54b..00000000 --- a/ports/atmega8/bacnet.eww +++ /dev/null @@ -1,10 +0,0 @@ - - - - - $WS_DIR$\bacnet.ewp - - - - - diff --git a/ports/atmega8/device.c b/ports/atmega8/device.c deleted file mode 100644 index 79c41a53..00000000 --- a/ports/atmega8/device.c +++ /dev/null @@ -1,343 +0,0 @@ -/************************************************************************** -* -* Copyright (C) 2007 Steve Karg -* -* Permission is hereby granted, free of charge, to any person obtaining -* a copy of this software and associated documentation files (the -* "Software"), to deal in the Software without restriction, including -* without limitation the rights to use, copy, modify, merge, publish, -* distribute, sublicense, and/or sell copies of the Software, and to -* permit persons to whom the Software is furnished to do so, subject to -* the following conditions: -* -* The above copyright notice and this permission notice shall be included -* in all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -* -*********************************************************************/ - -#include -#include -#include "bacdef.h" -#include "bacdcode.h" -#include "bacstr.h" -#include "bacenum.h" -#include "apdu.h" -#include "dcc.h" -#include "dlmstp.h" -#include "rs485.h" -#include "version.h" -/* objects */ -#include "device.h" -#include "av.h" - -/* note: you really only need to define variables for - properties that are writable or that may change. - The properties that are constant can be hard coded - into the read-property encoding. */ -static uint32_t Object_Instance_Number = 260001; -static char *Object_Name = "My Device"; -static BACNET_DEVICE_STATUS System_Status = STATUS_OPERATIONAL; - -void Device_Init( - object_functions_t * object_table) -{ - (void) object_table; - /* Reinitialize_State = BACNET_REINIT_IDLE; */ - /* dcc_set_status_duration(COMMUNICATION_ENABLE, 0); */ - /* FIXME: Get the data from the eeprom */ - /* I2C_Read_Block(EEPROM_DEVICE_ADDRESS, - (char *)&Object_Instance_Number, - sizeof(Object_Instance_Number), - EEPROM_BACNET_ID_ADDR); */ -} - -/* methods to manipulate the data */ -uint32_t Device_Object_Instance_Number( - void) -{ - return Object_Instance_Number; -} - -bool Device_Set_Object_Instance_Number( - uint32_t object_id) -{ - bool status = true; /* return value */ - - if (object_id <= BACNET_MAX_INSTANCE) { - Object_Instance_Number = object_id; - /* FIXME: Write the data to the eeprom */ - /* I2C_Write_Block( - EEPROM_DEVICE_ADDRESS, - (char *)&Object_Instance_Number, - sizeof(Object_Instance_Number), - EEPROM_BACNET_ID_ADDR); */ - } else - status = false; - - return status; -} - -bool Device_Valid_Object_Instance_Number( - uint32_t object_id) -{ - /* BACnet allows for a wildcard instance number */ - return ((Object_Instance_Number == object_id) || - (object_id == BACNET_MAX_INSTANCE)); -} - -uint16_t Device_Vendor_Identifier( - void) -{ - return BACNET_VENDOR_ID; -} - -unsigned Device_Object_List_Count( - void) -{ - unsigned count = 1; /* at least 1 for device object */ - -#if MAX_ANALOG_VALUES - /* FIXME: add objects as needed */ - count += Analog_Value_Count(); -#endif -#if MAX_BINARY_VALUES - /* FIXME: add objects as needed */ - count += Binary_Value_Count(); -#endif - - return count; -} - -bool Device_Object_List_Identifier( - uint32_t array_index, - int *object_type, - uint32_t * instance) -{ - bool status = false; - uint32_t object_index = 0; - uint32_t object_count = 0; - - /* device object */ - if (array_index == 1) { - *object_type = OBJECT_DEVICE; - *instance = Object_Instance_Number; - status = true; - } - /* normalize the index since - we know it is not the previous objects */ - /* array index starts at 1 */ - object_index = array_index - 1; - /* 1 for the device object */ - object_count = 1; - /* FIXME: add objects as needed */ -#if MAX_ANALOG_VALUES - /* analog value objects */ - if (!status) { - /* array index starts at 1, and 1 for the device object */ - object_index -= object_count; - object_count = Analog_Value_Count(); - if (object_index < object_count) { - *object_type = OBJECT_ANALOG_VALUE; - *instance = Analog_Value_Index_To_Instance(object_index); - status = true; - } - } -#endif -#if MAX_BINARY_VALUES - /* binary value objects */ - if (!status) { - object_index -= object_count; - object_count = Binary_Value_Count(); - /* is it a valid index for this object? */ - if (object_index < object_count) { - *object_type = OBJECT_BINARY_VALUE; - *instance = Binary_Value_Index_To_Instance(object_index); - status = true; - } - } -#endif - - return status; -} - -/* return the length of the apdu encoded or -1 for error */ -int Device_Read_Property( - BACNET_READ_PROPERTY_DATA * rpdata) -{ - int apdu_len = 0; /* return value */ - int len = 0; /* apdu len intermediate value */ - BACNET_BIT_STRING bit_string; - BACNET_CHARACTER_STRING char_string; - uint32_t i = 0; - int object_type = 0; - uint32_t instance = 0; - uint32_t count = 0; - uint8_t *apdu = NULL; - - if ((rpdata->application_data == NULL) || - (rpdata->application_data_len == 0)) { - return 0; - } - apdu = rpdata->application_data; - /* FIXME: change the hardcoded names to suit your application */ - switch ((int) rpdata->object_property) { - case PROP_OBJECT_IDENTIFIER: - apdu_len = - encode_application_object_id(&apdu[0], rpdata->object_type, - rpdata->object_instance); - break; - case PROP_OBJECT_NAME: - characterstring_init_ansi(&char_string, Object_Name); - apdu_len = - encode_application_character_string(&apdu[0], &char_string); - break; - case PROP_OBJECT_TYPE: - apdu_len = encode_application_enumerated(&apdu[0], OBJECT_DEVICE); - break; - case PROP_SYSTEM_STATUS: - apdu_len = encode_application_enumerated(&apdu[0], System_Status); - break; - case PROP_VENDOR_NAME: - characterstring_init_ansi(&char_string, BACNET_VENDOR_NAME); - apdu_len = - encode_application_character_string(&apdu[0], &char_string); - break; - case PROP_VENDOR_IDENTIFIER: - apdu_len = - encode_application_unsigned(&apdu[0], - Device_Vendor_Identifier()); - break; - case PROP_MODEL_NAME: - characterstring_init_ansi(&char_string, "GNU Demo"); - apdu_len = - encode_application_character_string(&apdu[0], &char_string); - break; - case PROP_FIRMWARE_REVISION: - characterstring_init_ansi(&char_string, BACNET_VERSION_TEXT); - apdu_len = - encode_application_character_string(&apdu[0], &char_string); - break; - case PROP_APPLICATION_SOFTWARE_VERSION: - characterstring_init_ansi(&char_string, "1.0"); - apdu_len = - encode_application_character_string(&apdu[0], &char_string); - break; - case PROP_PROTOCOL_VERSION: - apdu_len = - encode_application_unsigned(&apdu[0], BACNET_PROTOCOL_VERSION); - break; - case PROP_PROTOCOL_REVISION: - apdu_len = - encode_application_unsigned(&apdu[0], - BACNET_PROTOCOL_REVISION); - break; - case PROP_PROTOCOL_SERVICES_SUPPORTED: - /* Note: list of services that are executed, not initiated. */ - bitstring_init(&bit_string); - for (i = 0; i < MAX_BACNET_SERVICES_SUPPORTED; i++) { - /* automatic lookup based on handlers set */ - bitstring_set_bit(&bit_string, (uint8_t) i, - apdu_service_supported((BACNET_SERVICES_SUPPORTED) i)); - } - apdu_len = encode_application_bitstring(&apdu[0], &bit_string); - break; - case PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED: - /* Note: this is the list of objects that can be in this device, - not a list of objects that this device can access */ - bitstring_init(&bit_string); - /* must have the bit string as big as it can be */ - for (i = 0; i < MAX_ASHRAE_OBJECT_TYPE; i++) { - /* initialize all the object types to not-supported */ - bitstring_set_bit(&bit_string, (uint8_t) i, false); - } - /* FIXME: indicate the objects that YOU support */ - bitstring_set_bit(&bit_string, OBJECT_DEVICE, true); -#if MAX_ANALOG_VALUES - bitstring_set_bit(&bit_string, OBJECT_ANALOG_VALUE, true); -#endif -#if MAX_BINARY_VALUES - bitstring_set_bit(&bit_string, OBJECT_BINARY_VALUE, true); -#endif - apdu_len = encode_application_bitstring(&apdu[0], &bit_string); - break; - case PROP_OBJECT_LIST: - count = Device_Object_List_Count(); - /* Array element zero is the number of objects in the list */ - if (rpdata->array_index == 0) - apdu_len = encode_application_unsigned(&apdu[0], count); - /* if no index was specified, then try to encode the entire list */ - /* into one packet. Note that more than likely you will have */ - /* to return an error if the number of encoded objects exceeds */ - /* your maximum APDU size. */ - else if (rpdata->array_index == BACNET_ARRAY_ALL) { - for (i = 1; i <= count; i++) { - Device_Object_List_Identifier(i, &object_type, &instance); - len = - encode_application_object_id(&apdu[apdu_len], - object_type, instance); - apdu_len += len; - /* assume next one is the same size as this one */ - /* can we all fit into the APDU? */ - if ((apdu_len + len) >= MAX_APDU) { - rpdata->error_code = - ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED; - apdu_len = BACNET_STATUS_ABORT; - break; - } - } - } else { - if (Device_Object_List_Identifier(rpdata->array_index, - &object_type, &instance)) - apdu_len = - encode_application_object_id(&apdu[0], object_type, - instance); - else { - rpdata->error_class = ERROR_CLASS_PROPERTY; - rpdata->error_code = ERROR_CODE_INVALID_ARRAY_INDEX; - apdu_len = BACNET_STATUS_ERROR; - } - } - break; - case PROP_MAX_APDU_LENGTH_ACCEPTED: - apdu_len = encode_application_unsigned(&apdu[0], MAX_APDU); - break; - case PROP_SEGMENTATION_SUPPORTED: - apdu_len = - encode_application_enumerated(&apdu[0], SEGMENTATION_NONE); - break; - case PROP_APDU_TIMEOUT: - apdu_len = encode_application_unsigned(&apdu[0], 60000); - break; - case PROP_NUMBER_OF_APDU_RETRIES: - apdu_len = encode_application_unsigned(&apdu[0], 0); - break; - case PROP_DEVICE_ADDRESS_BINDING: - /* FIXME: encode the list here, if it exists */ - break; - case PROP_DATABASE_REVISION: - apdu_len = encode_application_unsigned(&apdu[0], 0); - break; - default: - rpdata->error_class = ERROR_CLASS_PROPERTY; - rpdata->error_code = ERROR_CODE_UNKNOWN_PROPERTY; - apdu_len = -1; - break; - } - /* only array properties can have array options */ - if ((apdu_len >= 0) && (rpdata->object_property != PROP_OBJECT_LIST) && - (rpdata->array_index != BACNET_ARRAY_ALL)) { - rpdata->error_class = ERROR_CLASS_PROPERTY; - rpdata->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY; - apdu_len = BACNET_STATUS_ERROR; - } - - return apdu_len; -} diff --git a/ports/atmega8/dlmstp.c b/ports/atmega8/dlmstp.c deleted file mode 100644 index 2e32f79a..00000000 --- a/ports/atmega8/dlmstp.c +++ /dev/null @@ -1,607 +0,0 @@ -/*####COPYRIGHTBEGIN#### - ------------------------------------------- - Copyright (C) 2008 Steve Karg - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to: - The Free Software Foundation, Inc. - 59 Temple Place - Suite 330 - Boston, MA 02111-1307 - USA. - - As a special exception, if other files instantiate templates or - use macros or inline functions from this file, or you compile - this file and link it with other works to produce a work based - on this file, this file does not by itself cause the resulting - work to be covered by the GNU General Public License. However - the source code for this file must still be made available in - accordance with section (3) of the GNU General Public License. - - This exception does not invalidate any other reasons why a work - based on this file might be covered by the GNU General Public - License. - ------------------------------------------- -####COPYRIGHTEND####*/ -#include -#include -#include -#include -#include "bacdef.h" -#include "mstpdef.h" -#include "dlmstp.h" -#include "rs485.h" -#include "crc.h" -#include "npdu.h" -#include "bits.h" -#include "bytes.h" -#include "bacaddr.h" -/* special optimization - I-Am response in this module */ -#include "client.h" -#include "txbuf.h" - -/* This file has been customized for use with small microprocessors */ -/* Assumptions: - Only one slave node MS/TP datalink layer -*/ -#include "hardware.h" -#include "timer.h" - -/* The state of the Receive State Machine */ -static MSTP_RECEIVE_STATE Receive_State; -static struct mstp_flag_t { - /* A Boolean flag set to TRUE by the Receive State Machine */ - /* if an invalid frame is received. */ - /* Set to FALSE by the main state machine. */ - unsigned ReceivedInvalidFrame:1; - /* A Boolean flag set to TRUE by the Receive State Machine */ - /* if a valid frame is received. */ - /* Set to FALSE by the main state machine. */ - unsigned ReceivedValidFrame:1; - /* A Boolean flag set TRUE by the datalink transmit if a - frame is pending */ - unsigned TransmitPacketPending:1; - /* A Boolean flag set TRUE by the datalink transmit if a - pending packet is DataExpectingReply */ - unsigned TransmitPacketDER:1; - /* A Boolean flag set TRUE by the datalink if a - packet has been received, but not processed. */ - unsigned ReceivePacketPending:1; -} MSTP_Flag; - -/* Used to store the data length of a received frame. */ -static uint16_t DataLength; -/* Used to store the destination address of a received frame. */ -static uint8_t DestinationAddress; -/* Used to store the frame type of a received frame. */ -static uint8_t FrameType; -/* An array of octets, used to store octets as they are received. */ -/* InputBuffer is indexed from 0 to InputBufferSize-1. */ -/* FIXME: assign this to an actual array of bytes! */ -/* Note: the buffer is designed as a pointer since some compilers - and microcontroller architectures have limits as to places to - hold contiguous memory. */ -static uint8_t *InputBuffer; -static uint16_t InputBufferSize; -/* Used to store the Source Address of a received frame. */ -static uint8_t SourceAddress; -/* "This Station," the MAC address of this node. TS is generally read from a */ -/* hardware DIP switch, or from nonvolatile memory. Valid values for TS are */ -/* 0 to 254. The value 255 is used to denote broadcast when used as a */ -/* destination address but is not allowed as a value for TS. */ -static uint8_t This_Station; -/* An array of octets, used to store octets for transmitting */ -/* OutputBuffer is indexed from 0 to OutputBufferSize-1. */ -/* The MAX_PDU size of a frame is MAX_APDU + MAX_NPDU octets. */ -/* FIXME: assign this to an actual array of bytes! */ -/* Note: the buffer is designed as a pointer since some compilers - and microcontroller architectures have limits as to places to - hold contiguous memory. */ -static uint8_t *TransmitPacket; -static uint16_t TransmitPacketLen; -static uint8_t TransmitPacketDest; - -/* The minimum time without a DataAvailable or ReceiveError event within */ -/* a frame before a receiving node may discard the frame: 60 bit times. */ -/* (Implementations may use larger values for this timeout, */ -/* not to exceed 100 milliseconds.) */ -/* At 9600 baud, 60 bit times would be about 6.25 milliseconds */ -/* const uint16_t Tframe_abort = 1 + ((1000 * 60) / 9600); */ -#define Tframe_abort 30 - -/* The maximum time a node may wait after reception of a frame that expects */ -/* a reply before sending the first octet of a reply or Reply Postponed */ -/* frame: 250 milliseconds. */ -#define Treply_delay 250 - -/* we need to be able to increment without rolling over */ -#define INCREMENT_AND_LIMIT_UINT8(x) {if (x < 0xFF) x++;} - -bool dlmstp_init( - char *ifname) -{ - ifname = ifname; - /* initialize hardware */ - RS485_Initialize(); - - return true; -} - -void dlmstp_cleanup( - void) -{ - /* nothing to do for static buffers */ -} - -void dlmstp_fill_bacnet_address( - BACNET_ADDRESS * src, - uint8_t mstp_address) -{ - int i = 0; - - if (mstp_address == MSTP_BROADCAST_ADDRESS) { - /* mac_len = 0 if broadcast address */ - src->mac_len = 0; - src->mac[0] = 0; - } else { - src->mac_len = 1; - src->mac[0] = mstp_address; - } - /* fill with 0's starting with index 1; index 0 filled above */ - for (i = 1; i < MAX_MAC_LEN; i++) { - src->mac[i] = 0; - } - src->net = 0; - src->len = 0; - for (i = 0; i < MAX_MAC_LEN; i++) { - src->adr[i] = 0; - } -} - -/* MS/TP Frame Format */ -/* All frames are of the following format: */ -/* */ -/* Preamble: two octet preamble: X`55', X`FF' */ -/* Frame Type: one octet */ -/* Destination Address: one octet address */ -/* Source Address: one octet address */ -/* Length: two octets, most significant octet first, of the Data field */ -/* Header CRC: one octet */ -/* Data: (present only if Length is non-zero) */ -/* Data CRC: (present only if Length is non-zero) two octets, */ -/* least significant octet first */ -/* (pad): (optional) at most one octet of padding: X'FF' */ -static void MSTP_Send_Frame( - uint8_t frame_type, /* type of frame to send - see defines */ - uint8_t destination, /* destination address */ - uint8_t source, /* source address */ - uint8_t * pdu, /* any data to be sent - may be null */ - uint16_t pdu_len) -{ /* number of bytes of data (up to 501) */ - uint8_t crc8 = 0xFF; /* used to calculate the crc value */ - uint16_t crc16 = 0xFFFF; /* used to calculate the crc value */ - uint8_t buffer[8]; /* stores the header and crc */ - uint8_t datacrc[2]; /* stores the data crc */ - uint16_t i = 0; /* used to calculate CRC for data */ - - /* create the MS/TP header */ - buffer[0] = 0x55; - buffer[1] = 0xFF; - buffer[2] = frame_type; - crc8 = CRC_Calc_Header(buffer[2], crc8); - buffer[3] = destination; - crc8 = CRC_Calc_Header(buffer[3], crc8); - buffer[4] = source; - crc8 = CRC_Calc_Header(buffer[4], crc8); - - buffer[5] = HI_BYTE(pdu_len); - crc8 = CRC_Calc_Header(buffer[5], crc8); - buffer[6] = LO_BYTE(pdu_len); - crc8 = CRC_Calc_Header(buffer[6], crc8); - buffer[7] = ~crc8; - if (pdu_len) { - /* calculate CRC for any data */ - for (i = 0; i < pdu_len; i++) { - crc16 = CRC_Calc_Data(pdu[i], crc16); - } - crc16 = ~crc16; - datacrc[0] = (crc16 & 0x00FF); - datacrc[1] = ((crc16 & 0xFF00) >> 8); - } - /* now transmit the frame */ - RS485_Turnaround_Delay(); - RS485_Transmitter_Enable(true); - RS485_Send_Data(buffer, 8); - /* send any data */ - if (pdu_len) { - RS485_Send_Data(pdu, pdu_len); - RS485_Send_Data(datacrc, 2); - } - RS485_Transmitter_Enable(false); -} - -static void MSTP_Receive_Frame_FSM( - void) -{ - /* stores the latest received data octet */ - uint8_t DataRegister = 0; - /* Used to accumulate the CRC on the data field of a frame. */ - static uint16_t DataCRC = 0; - /* Used to accumulate the CRC on the header of a frame. */ - static uint8_t HeaderCRC = 0; - /* Used as an index by the Receive State Machine, - up to a maximum value of the MPDU */ - static uint16_t Index = 0; - - switch (Receive_State) { - case MSTP_RECEIVE_STATE_IDLE: - /* In the IDLE state, the node waits for the beginning of a frame. */ - if (RS485_ReceiveError()) { - /* EatAnError */ - timer_silence_reset(); - } else if (RS485_DataAvailable(&DataRegister)) { - timer_silence_reset(); - if (DataRegister == 0x55) { - /* Preamble1 */ - /* receive the remainder of the frame. */ - Receive_State = MSTP_RECEIVE_STATE_PREAMBLE; - } - } - break; - case MSTP_RECEIVE_STATE_PREAMBLE: - /* In the PREAMBLE state, the node waits for the - second octet of the preamble. */ - if (timer_silence_elapsed(Tframe_abort)) { - /* Timeout */ - /* a correct preamble has not been received */ - /* wait for the start of a frame. */ - Receive_State = MSTP_RECEIVE_STATE_IDLE; - } else if (RS485_ReceiveError()) { - /* Error */ - timer_silence_reset(); - /* wait for the start of a frame. */ - Receive_State = MSTP_RECEIVE_STATE_IDLE; - } else if (RS485_DataAvailable(&DataRegister)) { - timer_silence_reset(); - if (DataRegister == 0xFF) { - /* Preamble2 */ - Index = 0; - HeaderCRC = 0xFF; - /* receive the remainder of the frame. */ - Receive_State = MSTP_RECEIVE_STATE_HEADER; - } else if (DataRegister == 0x55) { - /* ignore RepeatedPreamble1 */ - /* wait for the second preamble octet. */ - Receive_State = MSTP_RECEIVE_STATE_PREAMBLE; - } else { - /* NotPreamble */ - /* wait for the start of a frame. */ - Receive_State = MSTP_RECEIVE_STATE_IDLE; - } - } - break; - case MSTP_RECEIVE_STATE_HEADER: - /* In the HEADER state, the node waits for the fixed message header. */ - if (timer_silence_elapsed(Tframe_abort)) { - /* Timeout */ - /* indicate that an error has occurred during the reception of a frame */ - MSTP_Flag.ReceivedInvalidFrame = true; - /* wait for the start of a frame. */ - Receive_State = MSTP_RECEIVE_STATE_IDLE; - } else if (RS485_ReceiveError()) { - /* Error */ - timer_silence_reset(); - /* indicate that an error has occurred during the reception of a frame */ - MSTP_Flag.ReceivedInvalidFrame = true; - /* wait for the start of a frame. */ - Receive_State = MSTP_RECEIVE_STATE_IDLE; - } else if (RS485_DataAvailable(&DataRegister)) { - timer_silence_reset(); - if (Index == 0) { - /* FrameType */ - HeaderCRC = CRC_Calc_Header(DataRegister, HeaderCRC); - FrameType = DataRegister; - Index = 1; - } else if (Index == 1) { - /* Destination */ - HeaderCRC = CRC_Calc_Header(DataRegister, HeaderCRC); - DestinationAddress = DataRegister; - Index = 2; - } else if (Index == 2) { - /* Source */ - HeaderCRC = CRC_Calc_Header(DataRegister, HeaderCRC); - SourceAddress = DataRegister; - Index = 3; - } else if (Index == 3) { - /* Length1 */ - HeaderCRC = CRC_Calc_Header(DataRegister, HeaderCRC); - DataLength = DataRegister * 256; - Index = 4; - } else if (Index == 4) { - /* Length2 */ - HeaderCRC = CRC_Calc_Header(DataRegister, HeaderCRC); - DataLength += DataRegister; - Index = 5; - } else if (Index == 5) { - /* HeaderCRC */ - HeaderCRC = CRC_Calc_Header(DataRegister, HeaderCRC); - /* In the HEADER_CRC state, the node validates the CRC - on the fixed message header. */ - if (HeaderCRC != 0x55) { - /* BadCRC */ - /* indicate that an error has occurred during - the reception of a frame */ - MSTP_Flag.ReceivedInvalidFrame = true; - /* wait for the start of the next frame. */ - Receive_State = MSTP_RECEIVE_STATE_IDLE; - } else { - /* Note: proposed change to BACnet MSTP state machine! - If we don't decode data that is not for us, we could - get confused about the start if the Preamble 55 FF - is part of the data. */ - if ((DataLength) && (DataLength <= InputBufferSize)) { - /* Data */ - Index = 0; - DataCRC = 0xFFFF; - /* receive the data portion of the frame. */ - Receive_State = MSTP_RECEIVE_STATE_DATA; - } else { - if (DataLength == 0) { - /* NoData */ - if ((DestinationAddress == This_Station) || - (DestinationAddress == - MSTP_BROADCAST_ADDRESS)) { - /* ForUs */ - /* indicate that a frame with - no data has been received */ - MSTP_Flag.ReceivedValidFrame = true; - } else { - /* NotForUs - drop */ - } - } else { - /* FrameTooLong */ - /* indicate that a frame with an illegal or */ - /* unacceptable data length has been received */ - MSTP_Flag.ReceivedInvalidFrame = true; - } - /* wait for the start of the next frame. */ - Receive_State = MSTP_RECEIVE_STATE_IDLE; - } - } - } else { - /* indicate that an error has occurred during */ - /* the reception of a frame */ - MSTP_Flag.ReceivedInvalidFrame = true; - /* wait for the start of a frame. */ - Receive_State = MSTP_RECEIVE_STATE_IDLE; - } - } - break; - case MSTP_RECEIVE_STATE_DATA: - /* In the DATA state, the node waits for the data portion of a frame. */ - if (timer_silence_elapsed(Tframe_abort)) { - /* Timeout */ - /* indicate that an error has occurred during the reception of a frame */ - MSTP_Flag.ReceivedInvalidFrame = true; - /* wait for the start of the next frame. */ - Receive_State = MSTP_RECEIVE_STATE_IDLE; - } else if (RS485_ReceiveError()) { - /* Error */ - timer_silence_reset(); - /* indicate that an error has occurred during - the reception of a frame */ - MSTP_Flag.ReceivedInvalidFrame = true; - /* wait for the start of the next frame. */ - Receive_State = MSTP_RECEIVE_STATE_IDLE; - } else if (RS485_DataAvailable(&DataRegister)) { - timer_silence_reset(); - if (Index < DataLength) { - /* DataOctet */ - DataCRC = CRC_Calc_Data(DataRegister, DataCRC); - InputBuffer[Index] = DataRegister; - Index++; - } else if (Index == DataLength) { - /* CRC1 */ - DataCRC = CRC_Calc_Data(DataRegister, DataCRC); - Index++; - } else if (Index == (DataLength + 1)) { - /* CRC2 */ - DataCRC = CRC_Calc_Data(DataRegister, DataCRC); - /* STATE DATA CRC - no need for new state */ - /* indicate the complete reception of a valid frame */ - if (DataCRC == 0xF0B8) { - if ((DestinationAddress == This_Station) || - (DestinationAddress == MSTP_BROADCAST_ADDRESS)) { - /* ForUs */ - /* indicate that a frame with no data - has been received */ - MSTP_Flag.ReceivedValidFrame = true; - } - } else { - MSTP_Flag.ReceivedInvalidFrame = true; - } - Receive_State = MSTP_RECEIVE_STATE_IDLE; - } - } - break; - default: - /* shouldn't get here - but if we do... */ - Receive_State = MSTP_RECEIVE_STATE_IDLE; - break; - } - - return; -} - -static void MSTP_Slave_Node_FSM( - void) -{ - if (MSTP_Flag.ReceivedValidFrame) { - MSTP_Flag.ReceivedValidFrame = false; - switch (FrameType) { - case FRAME_TYPE_TOKEN: - break; - case FRAME_TYPE_POLL_FOR_MASTER: - break; - case FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY: - break; - case FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY: - /* indicate successful reception to the higher layers */ - MSTP_Flag.ReceivePacketPending = true; - break; - case FRAME_TYPE_TEST_REQUEST: - MSTP_Send_Frame(FRAME_TYPE_TEST_RESPONSE, SourceAddress, - This_Station, &InputBuffer[0], DataLength); - break; - case FRAME_TYPE_TEST_RESPONSE: - default: - break; - } - } else if (MSTP_Flag.TransmitPacketPending) { - /* Reply */ - /* If a reply is available from the higher layers */ - /* within Treply_delay after the reception of the */ - /* final octet of the requesting frame */ - /* (the mechanism used to determine this is a local matter), */ - /* then call MSTP_Send_Frame to transmit the reply frame */ - /* and enter the IDLE state to wait for the next frame. */ - /* Note: optimized such that we are never a client */ - MSTP_Send_Frame(FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY, - TransmitPacketDest, This_Station, (uint8_t *) & TransmitPacket[0], - TransmitPacketLen); - MSTP_Flag.TransmitPacketPending = false; - MSTP_Flag.ReceivePacketPending = false; - } -} - -/* returns number of bytes sent on success, zero on failure */ -int dlmstp_send_pdu( - BACNET_ADDRESS * dest, /* destination address */ - BACNET_NPDU_DATA * npdu_data, /* network information */ - uint8_t * pdu, /* any data to be sent - may be null */ - unsigned pdu_len) -{ /* number of bytes of data */ - int bytes_sent = 0; - - if (MSTP_Flag.TransmitPacketPending == false) { - MSTP_Flag.TransmitPacketDER = npdu_data->data_expecting_reply; - TransmitPacket = pdu; - TransmitPacketLen = pdu_len; - bytes_sent = pdu_len; - TransmitPacketDest = dest->mac[0]; - MSTP_Flag.TransmitPacketPending = true; - } - - return bytes_sent; -} - -/* Return the length of the packet */ -uint16_t dlmstp_receive( - BACNET_ADDRESS * src, /* source address */ - uint8_t * pdu, /* PDU data */ - uint16_t max_pdu, /* amount of space available in the PDU */ - unsigned timeout) -{ /* milliseconds to wait for a packet */ - uint16_t pdu_len = 0; /* return value */ - - /* dummy - unused parameter */ - timeout = timeout; - /* set the input buffer to the same data storage for zero copy */ - if (!InputBuffer) { - InputBuffer = pdu; - InputBufferSize = max_pdu; - } - /* only do receive state machine while we don't have a frame */ - if ((MSTP_Flag.ReceivedValidFrame == false) && - (MSTP_Flag.ReceivedInvalidFrame == false) && - (MSTP_Flag.ReceivePacketPending == false)) { - for (;;) { - MSTP_Receive_Frame_FSM(); - if (MSTP_Flag.ReceivedValidFrame || MSTP_Flag.ReceivedInvalidFrame) - break; - /* if we are not idle, then we are - receiving a frame or timing out */ - if (Receive_State == MSTP_RECEIVE_STATE_IDLE) - break; - } - } - /* only do master state machine while rx is idle */ - if (Receive_State == MSTP_RECEIVE_STATE_IDLE) { - MSTP_Slave_Node_FSM(); - } - /* if there is a packet that needs processed, do it now. */ - if (MSTP_Flag.ReceivePacketPending) { - MSTP_Flag.ReceivePacketPending = false; - pdu_len = DataLength; - src->mac_len = 1; - src->mac[0] = SourceAddress; - /* data is already in the pdu pointer */ - } - - return pdu_len; -} - -void dlmstp_set_mac_address( - uint8_t mac_address) -{ - /* Master Nodes can only have address 0-127 */ - if (mac_address <= 127) { - This_Station = mac_address; - /* FIXME: implement your data storage */ - /* I2C_Write_Byte( - EEPROM_DEVICE_ADDRESS, - mac_address, - EEPROM_MSTP_MAC_ADDR); */ - } - - return; -} - -uint8_t dlmstp_mac_address( - void) -{ - return This_Station; -} - -void dlmstp_get_my_address( - BACNET_ADDRESS * my_address) -{ - int i = 0; /* counter */ - - my_address->mac_len = 1; - my_address->mac[0] = This_Station; - my_address->net = 0; /* local only, no routing */ - my_address->len = 0; - for (i = 0; i < MAX_MAC_LEN; i++) { - my_address->adr[i] = 0; - } - - return; -} - -void dlmstp_get_broadcast_address( - BACNET_ADDRESS * dest) -{ /* destination address */ - int i = 0; /* counter */ - - if (dest) { - dest->mac_len = 1; - dest->mac[0] = MSTP_BROADCAST_ADDRESS; - dest->net = BACNET_BROADCAST_NETWORK; - dest->len = 0; /* always zero when DNET is broadcast */ - for (i = 0; i < MAX_MAC_LEN; i++) { - dest->adr[i] = 0; - } - } - - return; -} diff --git a/ports/atmega8/hardware.h b/ports/atmega8/hardware.h deleted file mode 100644 index 0e8fdfdf..00000000 --- a/ports/atmega8/hardware.h +++ /dev/null @@ -1,65 +0,0 @@ -/************************************************************************** -* -* Copyright (C) 2007 Steve Karg -* -* Permission is hereby granted, free of charge, to any person obtaining -* a copy of this software and associated documentation files (the -* "Software"), to deal in the Software without restriction, including -* without limitation the rights to use, copy, modify, merge, publish, -* distribute, sublicense, and/or sell copies of the Software, and to -* permit persons to whom the Software is furnished to do so, subject to -* the following conditions: -* -* The above copyright notice and this permission notice shall be included -* in all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -* -*********************************************************************/ -#ifndef HARDWARE_H -#define HARDWARE_H - -#if !defined(F_CPU) - /* The processor clock frequency */ -#define F_CPU 7372800UL -#endif - -#if defined(__IAR_SYSTEMS_ICC__) || defined(__IAR_SYSTEMS_ASM__) - #include - #if defined(__ATmega168__) - #define WATCHDOG_INIT() {BIT_CLEAR(MCUSR, WDRF); WDTCSR = 0;} - #else - #define WATCHDOG_INIT() - #endif -#else - #if !defined(__AVR_ATmega168__) - #error Firmware is configured for ATmega168 only (-mmcu=atmega168) - #endif - #if defined(__AVR_ATmega168__) - #define WATCHDOG_INIT() {BIT_CLEAR(MCUSR, WDRF); WDTCSR = 0;} - #else - #define WATCHDOG_INIT() {BIT_CLEAR(MCUCSR, WDRF); WDTCR = 0;} - #endif -#endif - -#include "iar2gcc.h" -#include "bits.h" - -#define LED_NPDU_INIT() BIT_SET(DDRD, DDD5) -#define LED_NPDU_ON() BIT_CLEAR(PORTD, PD5) -#define LED_NPDU_OFF() BIT_SET(PORTD, PD5) -/* #define LED_NPDU PORTD_Bit5 */ -/* #define LED_NPDU_OFF() {LED_NPDU = false;} */ -/* #define LED_NPDU_ON() {LED_NPDU = true;} */ - -#define LED_GREEN_INIT() BIT_SET(DDRD, DDD4) -#define LED_GREEN_ON() BIT_CLEAR(PORTD, PD4) -#define LED_GREEN_OFF() BIT_SET(PORTD, PD4) - -#endif diff --git a/ports/atmega8/hardware.ods b/ports/atmega8/hardware.ods deleted file mode 100644 index 6d06047c5c4306055b0f15988229b9c0b5fba778..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19823 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 -* -* Permission is hereby granted, free of charge, to any person obtaining -* a copy of this software and associated documentation files (the -* "Software"), to deal in the Software without restriction, including -* without limitation the rights to use, copy, modify, merge, publish, -* distribute, sublicense, and/or sell copies of the Software, and to -* permit persons to whom the Software is furnished to do so, subject to -* the following conditions: -* -* The above copyright notice and this permission notice shall be included -* in all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*********************************************************************/ -#ifndef IAR2GCC_H -#define IAR2GCC_H - -/* common embedded extensions for different compilers */ - -#if !defined(F_CPU) -#error You must define F_CPU - clock frequency! -#endif - -#if defined (__CROSSWORKS_AVR) -#include -#include -#endif - -/* IAR */ -#if defined(__ICCAVR__) -#include -#include -#include - -/* inline function */ -static inline void _delay_us( - uint8_t microseconds) -{ - do { - __delay_cycles(F_CPU / 1000000UL); - } while (microseconds--); -} -#endif - -#if defined(__GNUC__) -#include -#endif - -/* adjust some definitions to common versions */ -#if defined (__CROSSWORKS_AVR) -#if (__TARGET_PROCESSOR == ATmega644P) -#define PRR PRR0 -#define UBRR0 UBRR0W -#define UBRR1 UBRR1W - -#define PA0 PORTA0 -#define PA1 PORTA1 -#define PA2 PORTA2 -#define PA3 PORTA3 -#define PA4 PORTA4 -#define PA5 PORTA5 -#define PA6 PORTA6 -#define PA7 PORTA7 - -#define PB0 PORTB0 -#define PB1 PORTB1 -#define PB2 PORTB2 -#define PB3 PORTB3 -#define PB4 PORTB4 -#define PB5 PORTB5 -#define PB6 PORTB6 -#define PB7 PORTB7 - -#define PC0 PORTC0 -#define PC1 PORTC1 -#define PC2 PORTC2 -#define PC3 PORTC3 -#define PC4 PORTC4 -#define PC5 PORTC5 -#define PC6 PORTC6 -#define PC7 PORTC7 - -#define PD0 PORTD0 -#define PD1 PORTD1 -#define PD2 PORTD2 -#define PD3 PORTD3 -#define PD4 PORTD4 -#define PD5 PORTD5 -#define PD6 PORTD6 -#define PD7 PORTD7 - -#endif -#endif - -/* Input/Output Registers */ -#if defined(__GNUC__) -#include - -typedef struct { - unsigned char bit0:1; - unsigned char bit1:1; - unsigned char bit2:1; - unsigned char bit3:1; - unsigned char bit4:1; - unsigned char bit5:1; - unsigned char bit6:1; - unsigned char bit7:1; -} BitRegisterType; - -#ifndef true -#define true 1 -#endif - -#ifndef false -#define false 0 -#endif - -#define GPIO_BITREG(port,bitnum) \ - ((volatile BitRegisterType*)_SFR_MEM_ADDR(port) \ - )->bit ## bitnum - -#define PINA_Bit0 GPIO_BITREG(PINA,0) -#define PINA_Bit1 GPIO_BITREG(PINA,1) -#define PINA_Bit2 GPIO_BITREG(PINA,2) -#define PINA_Bit3 GPIO_BITREG(PINA,3) -#define PINA_Bit4 GPIO_BITREG(PINA,4) -#define PINA_Bit5 GPIO_BITREG(PINA,5) -#define PINA_Bit6 GPIO_BITREG(PINA,6) -#define PINA_Bit7 GPIO_BITREG(PINA,7) - -#define PORTA_Bit0 GPIO_BITREG(PORTA,0) -#define PORTA_Bit1 GPIO_BITREG(PORTA,1) -#define PORTA_Bit2 GPIO_BITREG(PORTA,2) -#define PORTA_Bit3 GPIO_BITREG(PORTA,3) -#define PORTA_Bit4 GPIO_BITREG(PORTA,4) -#define PORTA_Bit5 GPIO_BITREG(PORTA,5) -#define PORTA_Bit6 GPIO_BITREG(PORTA,6) -#define PORTA_Bit7 GPIO_BITREG(PORTA,7) - -#define PINB_Bit0 GPIO_BITREG(PINB,0) -#define PINB_Bit1 GPIO_BITREG(PINB,1) -#define PINB_Bit2 GPIO_BITREG(PINB,2) -#define PINB_Bit3 GPIO_BITREG(PINB,3) -#define PINB_Bit4 GPIO_BITREG(PINB,4) -#define PINB_Bit5 GPIO_BITREG(PINB,5) -#define PINB_Bit6 GPIO_BITREG(PINB,6) -#define PINB_Bit7 GPIO_BITREG(PINB,7) - -#define PORTB_Bit0 GPIO_BITREG(PORTB,0) -#define PORTB_Bit1 GPIO_BITREG(PORTB,1) -#define PORTB_Bit2 GPIO_BITREG(PORTB,2) -#define PORTB_Bit3 GPIO_BITREG(PORTB,3) -#define PORTB_Bit4 GPIO_BITREG(PORTB,4) -#define PORTB_Bit5 GPIO_BITREG(PORTB,5) -#define PORTB_Bit6 GPIO_BITREG(PORTB,6) -#define PORTB_Bit7 GPIO_BITREG(PORTB,7) - -#define PINC_Bit0 GPIO_BITREG(PINC,0) -#define PINC_Bit1 GPIO_BITREG(PINC,1) -#define PINC_Bit2 GPIO_BITREG(PINC,2) -#define PINC_Bit3 GPIO_BITREG(PINC,3) -#define PINC_Bit4 GPIO_BITREG(PINC,4) -#define PINC_Bit5 GPIO_BITREG(PINC,5) -#define PINC_Bit6 GPIO_BITREG(PINC,6) -#define PINC_Bit7 GPIO_BITREG(PINC,7) - -#define PORTC_Bit0 GPIO_BITREG(PORTC,0) -#define PORTC_Bit1 GPIO_BITREG(PORTC,1) -#define PORTC_Bit2 GPIO_BITREG(PORTC,2) -#define PORTC_Bit3 GPIO_BITREG(PORTC,3) -#define PORTC_Bit4 GPIO_BITREG(PORTC,4) -#define PORTC_Bit5 GPIO_BITREG(PORTC,5) -#define PORTC_Bit6 GPIO_BITREG(PORTC,6) -#define PORTC_Bit7 GPIO_BITREG(PORTC,7) - -#define PIND_Bit0 GPIO_BITREG(PIND,0) -#define PIND_Bit1 GPIO_BITREG(PIND,1) -#define PIND_Bit2 GPIO_BITREG(PIND,2) -#define PIND_Bit3 GPIO_BITREG(PIND,3) -#define PIND_Bit4 GPIO_BITREG(PIND,4) -#define PIND_Bit5 GPIO_BITREG(PIND,5) -#define PIND_Bit6 GPIO_BITREG(PIND,6) -#define PIND_Bit7 GPIO_BITREG(PIND,7) - -#define PORTD_Bit0 GPIO_BITREG(PORTD,0) -#define PORTD_Bit1 GPIO_BITREG(PORTD,1) -#define PORTD_Bit2 GPIO_BITREG(PORTD,2) -#define PORTD_Bit3 GPIO_BITREG(PORTD,3) -#define PORTD_Bit4 GPIO_BITREG(PORTD,4) -#define PORTD_Bit5 GPIO_BITREG(PORTD,5) -#define PORTD_Bit6 GPIO_BITREG(PORTD,6) -#define PORTD_Bit7 GPIO_BITREG(PORTD,7) - -#define GPIOR0_Bit0 GPIO_BITREG(GPIOR0,0) -#define GPIOR0_Bit1 GPIO_BITREG(GPIOR0,1) -#define GPIOR0_Bit2 GPIO_BITREG(GPIOR0,2) -#define GPIOR0_Bit3 GPIO_BITREG(GPIOR0,3) -#define GPIOR0_Bit4 GPIO_BITREG(GPIOR0,4) -#define GPIOR0_Bit5 GPIO_BITREG(GPIOR0,5) -#define GPIOR0_Bit6 GPIO_BITREG(GPIOR0,6) -#define GPIOR0_Bit7 GPIO_BITREG(GPIOR0,7) - -#define GPIOR1_Bit0 GPIO_BITREG(GPIOR1,0) -#define GPIOR1_Bit1 GPIO_BITREG(GPIOR1,1) -#define GPIOR1_Bit2 GPIO_BITREG(GPIOR1,2) -#define GPIOR1_Bit3 GPIO_BITREG(GPIOR1,3) -#define GPIOR1_Bit4 GPIO_BITREG(GPIOR1,4) -#define GPIOR1_Bit5 GPIO_BITREG(GPIOR1,5) -#define GPIOR1_Bit6 GPIO_BITREG(GPIOR1,6) -#define GPIOR1_Bit7 GPIO_BITREG(GPIOR1,7) - -#define GPIOR2_Bit0 GPIO_BITREG(GPIOR2,0) -#define GPIOR2_Bit1 GPIO_BITREG(GPIOR2,1) -#define GPIOR2_Bit2 GPIO_BITREG(GPIOR2,2) -#define GPIOR2_Bit3 GPIO_BITREG(GPIOR2,3) -#define GPIOR2_Bit4 GPIO_BITREG(GPIOR2,4) -#define GPIOR2_Bit5 GPIO_BITREG(GPIOR2,5) -#define GPIOR2_Bit6 GPIO_BITREG(GPIOR2,6) -#define GPIOR2_Bit7 GPIO_BITREG(GPIOR2,7) - -#endif - -/* Global Interrupts */ -#if defined(__GNUC__) -#define __enable_interrupt() sei() -#define __disable_interrupt() cli() -#endif - -/* Interrupts */ -#if defined(__ICCAVR__) -#define PRAGMA(x) _Pragma( #x ) -#define ISR(vec) \ - /* function prototype for use with "require protoptypes" option. */ \ - PRAGMA( vector=vec ) __interrupt void handler_##vec(void); \ - PRAGMA( vector=vec ) __interrupt void handler_##vec(void) -#elif defined(__GNUC__) -#include -#elif defined (__CROSSWORKS_AVR) -#define ISR(vec) void handler_##vec(void) __interrupt[vec] -#else -#error ISR() not defined! -#endif - -/* Flash */ -#if defined(__ICCAVR__) -#define FLASH_DECLARE(x) __flash x -#elif defined(__GNUC__) -#define FLASH_DECLARE(x) x __attribute__((__progmem__)) -#elif defined (__CROSSWORKS_AVR) -#define FLASH_DECLARE (x) const __code x -#endif - -/* EEPROM */ -#if defined(__ICCAVR__) -#define EEPROM_DECLARE(x) __eeprom x -#elif defined(__GNUC__) -#include -#define EEPROM_DECLARE(x) x __attribute__((section (".eeprom"))) -#if ((__GNUC__ < 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ < 3)) || \ - ((__GNUC__ == 4) && (__GNUC_MINOR__ == 3) && (__GNUC_PATCHLEVEL__ <= 3))) - /* bug in WinAVR - not quite IAR compatible */ -#ifndef __EEPUT -#define __EEPUT _EEPUT -#endif -#ifndef __EEGET -#define __EEGET _EEGET -#endif -#endif -#elif defined (__CROSSWORKS_AVR) -/* use functions defined in crt0.s to mimic IAR macros */ -void __uint8_eeprom_store( - unsigned char byte, - unsigned addr); -unsigned char __uint8_eeprom_load( - unsigned addr); -#define __EEPUT(addr, var) \ - __uint8_eeprom_store((unsigned char)(var), (unsigned)(addr)) -#define __EEGET(var, addr) \ - (var) = __uint8_eeprom_load((unsigned)(addr)) -#endif - -/* IAR intrinsic routines */ -#if defined(__GNUC__) - /* FIXME: intrinsic routines: map to assembler for size/speed */ -#define __multiply_unsigned(x,y) ((x)*(y)) - /* FIXME: __root means to not optimize or strip */ -#define __root -#endif - -/* watchdog defines in GCC */ -#if defined(__ICCAVR__) || defined(__CROSSWORKS_AVR) -#define WDTO_15MS 0 -#define WDTO_30MS 1 -#define WDTO_60MS 2 -#define WDTO_120MS 3 -#define WDTO_250MS 4 -#define WDTO_500MS 5 -#define WDTO_1S 6 -#define WDTO_2S 7 -#endif - -/* power macros in GCC-AVR */ -#if (defined(__ICCAVR__) && (defined(__ATmega644P__))) || \ - (defined(__CROSSWORKS_AVR) && (__TARGET_PROCESSOR == ATmega644P)) -#define power_adc_enable() (PRR &= (uint8_t)~(1 << PRADC)) -#define power_spi_enable() (PRR &= (uint8_t)~(1 << PRSPI)) -#define power_usart0_enable() (PRR &= (uint8_t)~(1 << PRUSART0)) -#define power_usart1_enable() (PRR &= (uint8_t)~(1 << PRUSART1)) -#define power_timer0_enable() (PRR &= (uint8_t)~(1 << PRTIM0)) -#define power_timer1_enable() (PRR &= (uint8_t)~(1 << PRTIM1)) -#define power_timer2_enable() (PRR &= (uint8_t)~(1 << PRTIM2)) -#endif -#if (defined(__ICCAVR__) && (defined(__ATmega1284P__))) || \ - (defined(__CROSSWORKS_AVR) && (__TARGET_PROCESSOR == ATmega1284P)) -#define power_adc_enable() (PRR0 &= (uint8_t)~(1 << PRADC)) -#define power_spi_enable() (PRR0 &= (uint8_t)~(1 << PRSPI)) -#define power_usart0_enable() (PRR0 &= (uint8_t)~(1 << PRUSART0)) -#define power_usart1_enable() (PRR0 &= (uint8_t)~(1 << PRUSART1)) -#define power_timer0_enable() (PRR0 &= (uint8_t)~(1 << PRTIM0)) -#define power_timer1_enable() (PRR0 &= (uint8_t)~(1 << PRTIM1)) -#define power_timer2_enable() (PRR0 &= (uint8_t)~(1 << PRTIM2)) -#endif -#if (defined(__GNUC__) && ((__GNUC__ == 4) && (__GNUC_MINOR__ < 5))) -#if defined(__AVR_ATmega644P__) - /* bug in WinAVR - fixed in later versions */ -#define power_usart1_enable() (PRR &= (uint8_t)~(1 << PRUSART1)) -#elif defined(__AVR_ATmega1284P__) -#define power_usart1_enable() (PRR0 &= (uint8_t)~(1 << PRUSART1)) -#endif -#endif - -#if defined(__CROSSWORKS_AVR) -#define inline -#endif - -#endif diff --git a/ports/atmega8/main.c b/ports/atmega8/main.c deleted file mode 100644 index 61b5c0de..00000000 --- a/ports/atmega8/main.c +++ /dev/null @@ -1,116 +0,0 @@ -/************************************************************************** -* -* Copyright (C) 2007 Steve Karg -* -* Permission is hereby granted, free of charge, to any person obtaining -* a copy of this software and associated documentation files (the -* "Software"), to deal in the Software without restriction, including -* without limitation the rights to use, copy, modify, merge, publish, -* distribute, sublicense, and/or sell copies of the Software, and to -* permit persons to whom the Software is furnished to do so, subject to -* the following conditions: -* -* The above copyright notice and this permission notice shall be included -* in all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -* -*********************************************************************/ - -#include -#include -#include "hardware.h" -#include "timer.h" -#include "rs485.h" -#include "datalink.h" -#include "npdu.h" -#include "txbuf.h" -#include "iam.h" -#include "device.h" -#include "av.h" -#include "handlers.h" - -/* local version override */ -const char *BACnet_Version = "1.0"; - -/* For porting to IAR, see: - http://www.avrfreaks.net/wiki/index.php/Documentation:AVR_GCC/IarToAvrgcc*/ - -/* dummy function - so we can use default demo handlers */ -bool dcc_communication_enabled( - void) -{ - return true; -} - -static void init( - void) -{ - /* FIXME: Initialize the Clock Prescaler for ATmega8 */ -#if defined(__AVR_ATmega168__) - /* The default CLKPSx bits are factory set to 0011 */ - /* Enbable the Clock Prescaler */ - CLKPR = _BV(CLKPCE); - /* CLKPS3 CLKPS2 CLKPS1 CLKPS0 Clock Division Factor - ------ ------ ------ ------ --------------------- - 0 0 0 0 1 - 0 0 0 1 2 - 0 0 1 0 4 - 0 0 1 1 8 - 0 1 0 0 16 - 0 1 0 1 32 - 0 1 1 0 64 - 0 1 1 1 128 - 1 0 0 0 256 - 1 x x x Reserved - */ - /* Set the CLKPS3..0 bits to Prescaler of 1 */ - CLKPR = 0; -#endif - /* Initialize I/O ports */ - /* For Port DDRx (Data Direction) Input=0, Output=1 */ - /* For Port PORTx (Bit Value) TriState=0, High=1 */ - DDRB = 0; - PORTB = 0; - DDRC = 0; - PORTC = 0; - DDRD = 0; - PORTD = 0; - - /* Configure the watchdog timer - Disabled for testing */ - WATCHDOG_INIT(); - - /* Configure Specialized Hardware */ - RS485_Initialize(); - RS485_Set_Baud_Rate(38400); - /* Configure Timer0 for millisecond timer */ - timer_init(); - /* Enable global interrupts */ - __enable_interrupt(); -} - -static uint8_t PDUBuffer[MAX_MPDU]; - -int main( - void) -{ - uint16_t pdu_len = 0; - BACNET_ADDRESS src; /* source address */ - - init(); - datalink_init(NULL); - for (;;) { - /* other tasks */ - /* BACnet handling */ - pdu_len = datalink_receive(&src, &PDUBuffer[0], sizeof(PDUBuffer), 0); - if (pdu_len) { - npdu_handler(&src, &PDUBuffer[0], pdu_len); - } - } -} diff --git a/ports/atmega8/readme.txt b/ports/atmega8/readme.txt deleted file mode 100644 index 0a968ef3..00000000 --- a/ports/atmega8/readme.txt +++ /dev/null @@ -1,45 +0,0 @@ -This port was originally done with the Atmel ATmega168 -I used the following tools: -1. The WinAVR compiler avr-gcc (GCC) 4.1.2 (WinAVR 20070525) -and tools from , hints and -sample code from and -. -"avr-binutils, avr-gcc, and avr-libc form the heart of the -Free Software toolchain for the Atmel AVR microcontrollers." -2. AVR Studio 4 from Atmel - -The hardware is expected to utilize the signals as defined -in the spreadsheet hardware.ods (OpenOffice.org calc). -Attach a DS75176 RS-485 transceiver (or similar) to the USART. -DS75176 ATmega168 ------- --------- - RO RXD - /RE --choice of I/O - DE --choice of I/O - DI TXD - GND GND - DO --to RS-485 wire - DO --to RS-485 wire - +5V From 5V Regulator - -The makefile allows you to build a simple server. -dlmstp is the datalink layer for MS/TP over RS-485. -This project uses an MS/TP Slave Node. - -I used the makefile from the command line on Windows: -C:\code\bacnet-stack\ports\atmega168> make clean all - -The BACnet Capabilities include ReadProperty support. -The BACnet objects include only a Device object. -All required object properties can be retrieved using ReadProperty. - -With full optimization, the statistics on the demo are: - -avr-gcc (GCC) 4.2.2 (WinAVR 20071221rc1) -Device: atmega168 -Program: 8734 bytes (53.3% Full) -Data: 254 bytes (24.8% Full) (does not include CStack) - -Hopefully you find this code useful! - -Steve Karg diff --git a/ports/atmega8/rs485.c b/ports/atmega8/rs485.c deleted file mode 100644 index 1902365a..00000000 --- a/ports/atmega8/rs485.c +++ /dev/null @@ -1,302 +0,0 @@ -/************************************************************************** -* -* Copyright (C) 2007 Steve Karg -* -* Permission is hereby granted, free of charge, to any person obtaining -* a copy of this software and associated documentation files (the -* "Software"), to deal in the Software without restriction, including -* without limitation the rights to use, copy, modify, merge, publish, -* distribute, sublicense, and/or sell copies of the Software, and to -* permit persons to whom the Software is furnished to do so, subject to -* the following conditions: -* -* The above copyright notice and this permission notice shall be included -* in all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -* -*********************************************************************/ - -/* The module handles sending data out the RS-485 port */ -/* and handles receiving data from the RS-485 port. */ -/* Customize this file for your specific hardware */ -#include -#include -#include -#include -#include -#include "bits.h" - -/* This file has been customized for use with ATMEGA168 */ -#if (defined(__ICCAVR__) && (defined(__ATmega168__))) || \ - (defined(__GNUC__) && defined(__AVR_ATmega168__)) - /* USART defines for RS-485 port */ -#define UCSRB UCSR0B -#define TXEN TXEN0 -#define RXEN RXEN0 -#define UCSRC UCSR0C -#define UCSZ1 UCSZ01 -#define UCSZ0 UCSZ00 -#define UCSRA UCSR0A -#define U2X U2X0 -#define UBRRL UBRR0 -#define UCSRA UCSR0A -#define UDRE UDRE0 -#define UDR UDR0 -#define TXC TXC0 -#define FE FE0 -#define DOR DOR0 -#define UPE UPE0 -#define DOR DOR0 -#define RXC RXC0 -#endif - -#include "hardware.h" -#include "timer.h" - -/* baud rate */ -static uint32_t RS485_Baud; - -/* The minimum time after the end of the stop bit of the final octet of a */ -/* received frame before a node may enable its EIA-485 driver: 40 bit times. */ -/* At 9600 baud, 40 bit times would be about 4.166 milliseconds */ -/* At 19200 baud, 40 bit times would be about 2.083 milliseconds */ -/* At 38400 baud, 40 bit times would be about 1.041 milliseconds */ -/* At 57600 baud, 40 bit times would be about 0.694 milliseconds */ -/* At 76800 baud, 40 bit times would be about 0.520 milliseconds */ -/* At 115200 baud, 40 bit times would be about 0.347 milliseconds */ -/* 40 bits is 4 octets including a start and stop bit with each octet */ -#define Tturnaround (40UL) -/* turnaround_time_milliseconds = (Tturnaround*1000UL)/RS485_Baud; */ - -/**************************************************************************** -* DESCRIPTION: Initializes the RS485 hardware and variables, and starts in -* receive mode. -* RETURN: none -* ALGORITHM: none -* NOTES: none -*****************************************************************************/ -void RS485_Initialize( - void) -{ - /* enable Transmit and Receive */ - UCSRB = _BV(TXEN) | _BV(RXEN); - - /* Set USART Control and Status Register n C */ - /* Asynchronous USART 8-bit data, No parity, 1 stop */ - /* Set USART Mode Select: UMSELn1 UMSELn0 = 00 for Asynchronous USART */ - /* Set Parity Mode: UPMn1 UPMn0 = 00 for Parity Disabled */ - /* Set Stop Bit Select: USBSn = 0 for 1 stop bit */ - /* Set Character Size: UCSZn2 UCSZn1 UCSZn0 = 011 for 8-bit */ - /* Clock Polarity: UCPOLn = 0 when asynchronous mode is used. */ - UCSRC = _BV(UCSZ1) | _BV(UCSZ0); -#if defined(__AVR_ATmega168__) - /* Clear Power Reduction USART0 */ - BIT_CLEAR(PRR, PRUSART0); -#endif - /* Use port PD2 for RTS - enable and disable of Transceiver Tx/Rx */ - /* Set port bit as Output - initially receiving */ - BIT_CLEAR(PORTD, PD2); - BIT_SET(DDRD, DDD2); - - return; -} - -/**************************************************************************** -* DESCRIPTION: Returns the baud rate that we are currently running at -* RETURN: none -* ALGORITHM: none -* NOTES: none -*****************************************************************************/ -uint32_t RS485_Get_Baud_Rate( - void) -{ - return RS485_Baud; -} - -/**************************************************************************** -* DESCRIPTION: Sets the baud rate for the chip USART -* RETURN: true if valid baud rate -* ALGORITHM: none -* NOTES: none -*****************************************************************************/ -bool RS485_Set_Baud_Rate( - uint32_t baud) -{ - bool valid = true; - - switch (baud) { - case 9600: - case 19200: - case 38400: - case 57600: - case 76800: - case 115200: - RS485_Baud = baud; - /* 2x speed mode */ - BIT_SET(UCSRA, U2X); - /* configure baud rate */ - UBRRL = (F_CPU / (8UL * RS485_Baud)) - 1; - /* FIXME: store the baud rate */ - break; - default: - valid = false; - break; - } - - return valid; -} - -/**************************************************************************** -* DESCRIPTION: Enable or disable the transmitter -* RETURN: none -* ALGORITHM: none -* NOTES: none -*****************************************************************************/ -void RS485_Transmitter_Enable( - bool enable) -{ - if (enable) { - BIT_SET(PORTD, PD2); - } else { - BIT_CLEAR(PORTD, PD2); - } -} - -/**************************************************************************** -* DESCRIPTION: Waits on the SilenceTimer for 40 bits. -* RETURN: none -* ALGORITHM: none -* NOTES: none -*****************************************************************************/ -void RS485_Turnaround_Delay( - void) -{ - uint8_t nbytes = 4; - - RS485_Transmitter_Enable(false); - while (nbytes) { - while (!BIT_CHECK(UCSRA, UDRE)) { - /* do nothing - wait until Tx buffer is empty */ - } - /* Send the data byte */ - UDR = 0xff; - nbytes--; - } - /* was the frame sent? */ - while (!BIT_CHECK(UCSRA, TXC)) { - /* do nothing - wait until the entire frame in the - Transmit Shift Register has been shifted out */ - } - /* Clear the Transmit Complete flag by writing a one to it. */ - BIT_SET(UCSRA, TXC); -} - -/**************************************************************************** -* DESCRIPTION: Send some data and wait until it is sent -* RETURN: none -* ALGORITHM: none -* NOTES: none -*****************************************************************************/ -void RS485_Send_Data( - uint8_t * buffer, /* data to send */ - uint16_t nbytes) -{ /* number of bytes of data */ - while (nbytes) { - while (!BIT_CHECK(UCSRA, UDRE)) { - /* do nothing - wait until Tx buffer is empty */ - } - /* Send the data byte */ - UDR = *buffer; - buffer++; - nbytes--; - } - /* was the frame sent? */ - while (!BIT_CHECK(UCSRA, TXC)) { - /* do nothing - wait until the entire frame in the - Transmit Shift Register has been shifted out */ - } - /* Clear the Transmit Complete flag by writing a one to it. */ - BIT_SET(UCSRA, TXC); - /* per MSTP spec, sort of */ - timer_silence_reset(); -} - - -/**************************************************************************** -* DESCRIPTION: Return true if a framing or overrun error is present -* RETURN: true if error -* ALGORITHM: autobaud - if there are a lot of errors, switch baud rate -* NOTES: Clears any error flags. -*****************************************************************************/ -bool RS485_ReceiveError( - void) -{ - bool ReceiveError = false; - uint8_t dummy_data; - - /* check for framing error */ -#if 0 - if (BIT_CHECK(UCSRA, FE0)) { - /* FIXME: how do I clear the error flags? */ - BITMASK_CLEAR(UCSRA, (_BV(FE) | _BV(DOR) | _BV(UPE))); - ReceiveError = true; - } -#endif - /* check for overrun error */ - if (BIT_CHECK(UCSRA, DOR)) { - /* flush the receive buffer */ - do { - dummy_data = UDR; - } while (BIT_CHECK(UCSRA, RXC)); - ReceiveError = true; - } - - return ReceiveError; -} - -/**************************************************************************** -* DESCRIPTION: Return true if data is available -* RETURN: true if data is available, with the data in the parameter set -* ALGORITHM: none -* NOTES: none -*****************************************************************************/ -bool RS485_DataAvailable( - uint8_t * data) -{ - bool DataAvailable = false; - - /* check for data */ - if (BIT_CHECK(UCSRA, RXC)) { - *data = UDR; - DataAvailable = true; - } - - return DataAvailable; -} - -#ifdef TEST_RS485 -int main( - void) -{ - unsigned i = 0; - uint8_t DataRegister; - - RS485_Set_Baud_Rate(38400); - RS485_Initialize(); - /* receive task */ - for (;;) { - if (RS485_ReceiveError()) { - fprintf(stderr, "ERROR "); - } else if (RS485_DataAvailable(&DataRegister)) { - fprintf(stderr, "%02X ", DataRegister); - } - } -} -#endif /* TEST_RS485 */ diff --git a/ports/atmega8/rs485.h b/ports/atmega8/rs485.h deleted file mode 100644 index 9657c01d..00000000 --- a/ports/atmega8/rs485.h +++ /dev/null @@ -1,70 +0,0 @@ -/*####COPYRIGHTBEGIN#### - ------------------------------------------- - Copyright (C) 2004 Steve Karg - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to: - The Free Software Foundation, Inc. - 59 Temple Place - Suite 330 - Boston, MA 02111-1307 - USA. - - As a special exception, if other files instantiate templates or - use macros or inline functions from this file, or you compile - this file and link it with other works to produce a work based - on this file, this file does not by itself cause the resulting - work to be covered by the GNU General Public License. However - the source code for this file must still be made available in - accordance with section (3) of the GNU General Public License. - - This exception does not invalidate any other reasons why a work - based on this file might be covered by the GNU General Public - License. - ------------------------------------------- -####COPYRIGHTEND####*/ - -#ifndef RS485_H -#define RS485_H - -#include - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - - void RS485_Initialize( - void); - - void RS485_Transmitter_Enable( - bool enable); - - void RS485_Send_Data( - uint8_t * buffer, /* data to send */ - uint16_t nbytes); /* number of bytes of data */ - - bool RS485_ReceiveError( - void); - bool RS485_DataAvailable( - uint8_t * data); - - void RS485_Turnaround_Delay( - void); - uint32_t RS485_Get_Baud_Rate( - void); - bool RS485_Set_Baud_Rate( - uint32_t baud); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ -#endif diff --git a/ports/atmega8/stdbool.h b/ports/atmega8/stdbool.h deleted file mode 100644 index 39c1c286..00000000 --- a/ports/atmega8/stdbool.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef STDBOOL_H -#define STDBOOL_H - -/* C99 Boolean types for compilers without C99 support */ - -#ifndef __cplusplus -/* typedef char _Bool; */ -#ifndef bool -#define bool _Bool -#endif -#ifndef true -#define true 1 -#endif -#ifndef false -#define false 0 -#endif -#define __bool_true_false_are_defined 1 -#endif - -#ifndef FALSE -#define FALSE 0 -#endif - -#ifndef TRUE -#define TRUE 1 -#endif - -#endif diff --git a/ports/atmega8/stdint.h b/ports/atmega8/stdint.h deleted file mode 100644 index 874f309d..00000000 --- a/ports/atmega8/stdint.h +++ /dev/null @@ -1,15 +0,0 @@ -/* Defines the standard integer types that are used in code */ - -#ifndef STDINT_H -#define STDINT_H 1 - -#include - -typedef unsigned char uint8_t; /* 1 byte 0 to 255 */ -typedef signed char int8_t; /* 1 byte -127 to 127 */ -typedef unsigned short uint16_t; /* 2 bytes 0 to 65535 */ -typedef signed short int16_t; /* 2 bytes -32767 to 32767 */ -typedef unsigned long uint32_t; /* 4 bytes 0 to 4294967295 */ -typedef signed long int32_t; /* 4 bytes -2147483647 to 2147483647 */ - -#endif /* STDINT_H */ diff --git a/ports/atmega8/timer.c b/ports/atmega8/timer.c deleted file mode 100644 index 26ea10b3..00000000 --- a/ports/atmega8/timer.c +++ /dev/null @@ -1,110 +0,0 @@ -/************************************************************************** -* -* Copyright (C) 2007 Steve Karg -* -* Permission is hereby granted, free of charge, to any person obtaining -* a copy of this software and associated documentation files (the -* "Software"), to deal in the Software without restriction, including -* without limitation the rights to use, copy, modify, merge, publish, -* distribute, sublicense, and/or sell copies of the Software, and to -* permit persons to whom the Software is furnished to do so, subject to -* the following conditions: -* -* The above copyright notice and this permission notice shall be included -* in all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -* -*********************************************************************/ -#include -#include -#include "hardware.h" - -/* This module is a 1 millisecond timer */ - -/* Prescaling: 1, 8, 64, 256, 1024 */ -#define TIMER_PRESCALER 64 -/* Count: Timer0 counts up to 0xFF and then signals overflow */ -#define TIMER_TICKS (F_CPU/TIMER_PRESCALER/1000) -#if (TIMER_TICKS > 0xFF) -#error Timer Prescaler value is too small -#endif -#define TIMER_COUNT (0xFF-TIMER_TICKS) -/* millisecond timer count */ -static volatile uint16_t Timer_Silence; - -/* FIXME: Configure the Timer */ -void timer_init( - void) -{ - /* Normal Operation */ - TCCR1A = 0; - /* CSn2 CSn1 CSn0 Description - ---- ---- ---- ----------- - 0 0 0 No Clock Source - 0 0 1 No prescaling - 0 1 0 CLKio/8 - 0 1 1 CLKio/64 - 1 0 0 CLKio/256 - 1 0 1 CLKio/1024 - 1 1 0 Falling Edge of T0 (external) - 1 1 1 Rising Edge of T0 (external) - */ -#if defined(__AVR_ATmega168__) - TCCR0B = _BV(CS01) | _BV(CS00); - /* Clear any TOV1 Flag set when the timer overflowed */ - BIT_CLEAR(TIFR0, TOV0); - /* Initial value */ - TCNT0 = TIMER_COUNT; - /* Enable the overflow interrupt */ - BIT_SET(TIMSK0, TOIE0); - /* Clear the Power Reduction Timer/Counter0 */ - BIT_CLEAR(PRR, PRTIM0); -#endif -} - -/* Timer interupt */ -/* note: Global interupts must be enabled - sei() */ -/* Timer Overflowed! Increment the time. */ -ISR(TIMER0_OVF_vect) -{ - /* Set the counter for the next interrupt */ - TCNT0 = TIMER_COUNT; - /* Overflow Flag is automatically cleared */ - /* Update the global timer */ - Timer_Silence++; -} - -/* return true if time has expired */ -bool timer_silence_elapsed( - uint16_t value) -{ - bool status = false; - uint8_t sreg; - - sreg = SREG; - __disable_interrupt(); - if (Timer_Silence >= value) { - status = true; - } - SREG = sreg; - - return status; -} - -void timer_silence_reset( - void) -{ - uint8_t sreg; - - sreg = SREG; - __disable_interrupt(); - Timer_Silence = 0; - SREG = sreg; -} diff --git a/ports/bdk-atxx4-mstp/Makefile b/ports/bdk-atxx4-mstp/Makefile index 49945535..e44fe7bb 100644 --- a/ports/bdk-atxx4-mstp/Makefile +++ b/ports/bdk-atxx4-mstp/Makefile @@ -68,13 +68,11 @@ endif # Source locations BACNET_CORE = ../../src -BACNET_INCLUDE = ../../include -BACNET_HANDLER = ../../demo/handler -BACNET_OBJECT = ../../demo/object -BACNET_DEMO = ../../demo +BACNET_INCLUDE = $(BACNET_CORE) +BACNET_BASIC = $(BACNET_CORE)/basic # local files for this project -CSRC = main.c \ +HALSRC = main.c \ fuses.c \ init.c \ stack.c \ @@ -82,8 +80,7 @@ CSRC = main.c \ input.c \ serial.c \ rs485.c \ - timer2.c \ - timer.c \ + mstimer-init.c \ led.c \ eeprom.c \ seeprom.c \ @@ -99,23 +96,27 @@ CSRC = main.c \ bo.c # common demo files needed -DEMOSRC = $(BACNET_DEMO)/handler/h_dcc.c \ - $(BACNET_DEMO)/handler/h_npdu.c \ - $(BACNET_DEMO)/handler/h_rd.c \ - $(BACNET_DEMO)/handler/h_rp.c \ - $(BACNET_DEMO)/handler/h_rpm.c \ - $(BACNET_DEMO)/handler/h_whohas.c \ - $(BACNET_DEMO)/handler/h_whois.c \ - $(BACNET_DEMO)/handler/h_wp.c \ - $(BACNET_DEMO)/handler/noserv.c \ - $(BACNET_DEMO)/handler/s_iam.c \ - $(BACNET_DEMO)/handler/s_ihave.c \ - $(BACNET_DEMO)/handler/txbuf.c +BASICSRC = $(BACNET_BASIC)/service/h_dcc.c \ + $(BACNET_BASIC)/service/h_apdu.c \ + $(BACNET_BASIC)/service/h_rd.c \ + $(BACNET_BASIC)/service/h_rp.c \ + $(BACNET_BASIC)/service/h_rpm.c \ + $(BACNET_BASIC)/service/h_whohas.c \ + $(BACNET_BASIC)/service/h_whois.c \ + $(BACNET_BASIC)/service/h_wp.c \ + $(BACNET_BASIC)/service/h_noserv.c \ + $(BACNET_BASIC)/service/s_iam.c \ + $(BACNET_BASIC)/service/s_ihave.c \ + $(BACNET_BASIC)/sys/fifo.c \ + $(BACNET_BASIC)/sys/mstimer.c \ + $(BACNET_BASIC)/sys/ringbuf.c \ + $(BACNET_BASIC)/npdu/h_npdu.c \ + $(BACNET_BASIC)/tsm/tsm.c # core BACnet stack files CORESRC = \ + $(BACNET_CORE)/datalink/crc.c \ $(BACNET_CORE)/abort.c \ - $(BACNET_CORE)/apdu.c \ $(BACNET_CORE)/bacaddr.c \ $(BACNET_CORE)/bacapp.c \ $(BACNET_CORE)/bacdcode.c \ @@ -123,16 +124,13 @@ CORESRC = \ $(BACNET_CORE)/bacint.c \ $(BACNET_CORE)/bacreal.c \ $(BACNET_CORE)/bacstr.c \ - $(BACNET_CORE)/crc.c \ $(BACNET_CORE)/dcc.c \ - $(BACNET_CORE)/fifo.c \ $(BACNET_CORE)/iam.c \ $(BACNET_CORE)/ihave.c \ $(BACNET_CORE)/memcopy.c \ $(BACNET_CORE)/npdu.c \ $(BACNET_CORE)/rd.c \ $(BACNET_CORE)/reject.c \ - $(BACNET_CORE)/ringbuf.c \ $(BACNET_CORE)/rp.c \ $(BACNET_CORE)/rpm.c \ $(BACNET_CORE)/whohas.c \ @@ -157,11 +155,11 @@ CORESRC = \ # $(BACNET_CORE)/address.c \ ## Include Directories -INCLUDES = -I. -I$(BACNET_INCLUDE) -I$(BACNET_HANDLER) -I$(BACNET_OBJECT) +INCLUDES = -I. -I$(BACNET_INCLUDE) # Source to Object conversion -COBJ = $(CSRC:%.c=%.o) -DEMOOBJ = $(DEMOSRC:.c=.o) +HALOBJ = $(HALSRC:%.c=%.o) +BASICOBJ = $(BASICSRC:.c=.o) COREOBJ = $(CORESRC:.c=.o) LIBRARY = lib$(TARGET).a @@ -327,7 +325,7 @@ AVRDUDE_INSTALL = $(AVRDUDE_WRITE_FLASH) #AVRDUDE_INSTALL += $(AVRDUDE_WRITE_FUSES) ## Objects not in library that must be built in order to link -OBJECTS = $(COBJ) $(DEMOOBJ) +OBJECTS = $(HALOBJ) $(BASICOBJ) ## Build TARGET_ELF=$(TARGET).elf @@ -370,7 +368,7 @@ size: ${TARGET_ELF} @${SIZE} ${SIZE_OPTIONS} ${TARGET_ELF} lint: - $(LINT) -exportlocal -D$(LINT_MCU) $(BFLAGS) $(CSRC) + $(LINT) -exportlocal -D$(LINT_MCU) $(BFLAGS) $(HALSRC) install: $(TARGET_ELF) $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_INSTALL) diff --git a/ports/bdk-atxx4-mstp/ai.c b/ports/bdk-atxx4-mstp/ai.c index 65605517..77345118 100644 --- a/ports/bdk-atxx4-mstp/ai.c +++ b/ports/bdk-atxx4-mstp/ai.c @@ -28,12 +28,12 @@ #include #include #include -#include "bacdef.h" -#include "bacdcode.h" -#include "bacenum.h" -#include "config.h" -#include "ai.h" -#include "handlers.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacenum.h" +#include "bacnet/config.h" +#include "bacnet/basic/object/ai.h" +#include "bacnet/basic/services.h" #ifndef MAX_ANALOG_INPUTS #define MAX_ANALOG_INPUTS 2 diff --git a/ports/bdk-atxx4-mstp/av.c b/ports/bdk-atxx4-mstp/av.c index 2b956c80..b3005f12 100644 --- a/ports/bdk-atxx4-mstp/av.c +++ b/ports/bdk-atxx4-mstp/av.c @@ -29,14 +29,14 @@ #include #include -#include "bacdef.h" -#include "bacdcode.h" -#include "bacenum.h" -#include "bacapp.h" -#include "config.h" /* the custom stuff */ -#include "wp.h" -#include "av.h" -#include "handlers.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacenum.h" +#include "bacnet/bacapp.h" +#include "bacnet/config.h" /* the custom stuff */ +#include "bacnet/wp.h" +#include "bacnet/basic/object/av.h" +#include "bacnet/basic/services.h" #include "hardware.h" #ifndef MAX_ANALOG_VALUES diff --git a/ports/bdk-atxx4-mstp/avrosp/AVRBootloader.cpp b/ports/bdk-atxx4-mstp/avrosp/AVRBootloader.cpp index ae0fa6d7..0ff2be6d 100644 --- a/ports/bdk-atxx4-mstp/avrosp/AVRBootloader.cpp +++ b/ports/bdk-atxx4-mstp/avrosp/AVRBootloader.cpp @@ -1,976 +1,976 @@ -/***************************************************************************** - * - * Atmel Corporation - * - * File : AVRBootloader.cpp - * Compiler : Dev-C++ 4.9.8.0 - http://bloodshed.net/dev/ - * Revision : $Revision: 1163 $ - * Date : $Date: 2006-08-02 15:38:16 +0200 (on, 02 aug 2006) $ - * Updated by : $Author: ohlia $ - * - * Support mail : avr@atmel.com - * - * Target platform : Win32 - * - * AppNote : AVR911 - AVR Open-source Programmer - * - * Description : A class providing an interface to the AVR bootloader - * described in Application Note AVR109. - * This class is derived from AVRPRogrammer. - * - * - ****************************************************************************/ -#include "AVRBootloader.hpp" - -#include -#include - -#define MEM_PROGRESS_GRANULARITY 256 // For use with progress indicator. - - -/* Constructor */ -AVRBootloader::AVRBootloader( CommChannel * _comm ) : - AVRProgrammer::AVRProgrammer( _comm ) -{ - /* No code here */ -} - - -/* Destructor */ -AVRBootloader::~AVRBootloader() -{ - /* No code here */ -} - - -bool AVRBootloader::enterProgrammingMode() -{ - return true; // Always OK for bootloader. -} - - -bool AVRBootloader::leaveProgrammingMode() -{ - return true; // Always OK for bootloader. -} - - -bool AVRBootloader::chipErase() -{ - /* Send command 'e' */ - comm->sendByte( 'e' ); - comm->flushTX(); - - /* Should return CR */ - if( comm->getByte() != '\r' ) - throw new ErrorMsg( "Chip erase failed! " - "Programmer did not return CR after 'e'-command." ); - - return true; // Indicate supported command. -} - - -bool AVRBootloader::readOSCCAL( long pos, long * value ) -{ - return false; // Indicate unsupported command. -} - - -bool AVRBootloader::readSignature( long * sig0, long * sig1, long * sig2 ) -{ - /* Send command 's' */ - comm->sendByte( 's' ); - comm->flushTX(); - - /* Get actual signature */ - *sig2 = comm->getByte(); - *sig1 = comm->getByte(); - *sig0 = comm->getByte(); -} - - -bool AVRBootloader::checkSignature( long sig0, long sig1, long sig2 ) -{ - long sig[3]; - - /* Get signature */ - readSignature( sig, sig+1, sig+2 ); - - /* Compare signature */ - if( sig[0] != sig0 || sig[1] != sig1 || sig[2] != sig2 ) - { - ostringstream msg; - msg << "Signature does not match selected device! "; - msg << "Actual signature: (" << hex - << "0x" << setw(2) << sig[0] << " " - << "0x" << setw(2) << sig[1] << " " - << "0x" << setw(2) << sig[2] << ") " - << "Signature from XML-file: (" << hex - << "0x" << setw(2) << sig0 << " " - << "0x" << setw(2) << sig1 << " " - << "0x" << setw(2) << sig2 << ")."; - - throw new ErrorMsg( msg.str() ); - } - - return true; // Indicate supported command. -} - - -bool AVRBootloader::writeFlashByte( long address, long value ) -{ - setAddress( address >> 1 ); // Flash operations use word addresses. - - /* Move data if at odd address */ - if( address & 0x01 ) // Odd address? - value = (value << 8) | 0x00ff; // Move to high byte of one flash word. - else - value |= 0xff00; // Ensure no-write for high byte. - - /* Send low and high byte */ - writeFlashLowByte( value & 0xff ); - writeFlashHighByte( value >> 8 ); - - /* Issue page write */ - setAddress( address >> 1 ); // The address could be autoincremented. - writeFlashPage(); - - return true; // Indicate supported command. -} - - -bool AVRBootloader::writeEEPROMByte( long address, long value ) -{ - if( address >= 0x10000 ) - throw new ErrorMsg( "EEPROM addresses above 64k are currently not supported!" ); - - setAddress( address ); - - /* Send data */ - comm->sendByte( 'D' ); - comm->sendByte( value ); - comm->flushTX(); - - /* Should return CR */ - if( comm->getByte() != '\r' ) - throw new ErrorMsg( "Writing byte to EEPROM failed! " - "Programmer did not return CR after 'D'-command." ); - - return true; // Indicate supported command. -} - - -bool AVRBootloader::writeFlash( HEXFile * data ) -{ - long start, end; // Data address range. - bool autoincrement; // Bootloader supports address autoincrement? - long address; - - /* Check that pagesize is set */ - if( pagesize == -1 ) - throw new ErrorMsg( "Programmer pagesize is not set!" ); - - /* Check block write support */ - comm->sendByte( 'b' ); - comm->flushTX(); - - if( comm->getByte() == 'Y' ) - { - Util.log( "Using block mode...\r\n" ); - return writeFlashBlock( data ); // Finished writing. - } - - /* Get range from HEX file */ - start = data->getRangeStart(); - end = data->getRangeEnd(); - - /* Check autoincrement support */ - comm->sendByte( 'a' ); - comm->flushTX(); - - if( comm->getByte() == 'Y' ) - autoincrement = true; - else - autoincrement = false; - - /* Set initial address */ - setAddress( start >> 1 ); // Flash operations use word addresses. - - /* Need to write one odd byte first? */ - address = start; - if( address & 1 ) - { - /* Use only high byte */ - writeFlashLowByte( 0xff ); // No-write in low byte. - writeFlashHighByte( data->getData( address ) ); - address++; - - /* Need to write page? */ - if( (address % pagesize) == 0 || - address > end ) // Just passed page limit or no more bytes to write? - { - setAddress( (address-2) >> 1 ); // Set to an address inside the page. - writeFlashPage(); - setAddress( address >> 1 ); - } - } - - /* Write words */ - while( (end-address+1) >= 2 ) // More words left? - { - /* Need to set address again? */ - if( !autoincrement ) - setAddress( address >> 1 ); - - /* Write words */ - writeFlashLowByte( data->getData( address ) ); - writeFlashHighByte( data->getData( address+1 ) ); - address += 2; - - if( (address % MEM_PROGRESS_GRANULARITY) == 0 ) - Util.progress( "#" ); // Advance progress indicator. - - /* Need to write page? */ - if( (address % pagesize) == 0 || - address > end ) // Just passed a page limit or no more bytes to write? - { - setAddress( (address-2) >> 1 ); // Set to an address inside the page. - writeFlashPage(); - setAddress( address >> 1 ); - } - } - - /* Need to write one even byte before finished? */ - if( address == end ) - { - /* Use only low byte */ - writeFlashLowByte( data->getData( address ) ); - writeFlashHighByte( 0xff ); // No-write in high byte. - address+=2; - - /* Write page */ - setAddress( (address-2) >> 1 ); // Set to an address inside the page. - writeFlashPage(); - } - - Util.progress( "\r\n" ); // Finish progress indicator. - return true; // Indicate supported command. -} - - -bool AVRBootloader::writeFlashBlock( HEXFile * data ) -{ - long start, end; // Data address range. - long blocksize; // Bootloader block size. - long bytecount; - long address; - - /* Get block size, assuming command 'b' just issued and 'Y' has been read */ - blocksize = (comm->getByte() << 8) | comm->getByte(); - - /* Get range from HEX file */ - start = data->getRangeStart(); - end = data->getRangeEnd(); - - /* Need to write one odd byte first? */ - address = start; - if( address & 1 ) - { - setAddress( address >> 1 ); // Flash operations use word addresses. - - /* Use only high byte */ - writeFlashLowByte( 0xff ); // No-write in low byte. - writeFlashHighByte( data->getData( address ) ); - address++; - - /* Need to write page? */ - if( (address % pagesize) == 0 || - address > end ) // Just passed page limit or no more bytes to write? - { - setAddress( (address-2) >> 1 ); // Set to an address inside the page. - writeFlashPage(); - setAddress( address >> 1 ); - } - } - - /* Need to write from middle to end of block first? */ - if( (address % blocksize) > 0 ) // In the middle of a block? - { - bytecount = blocksize - (address % blocksize); // Bytes left in block. - - if( (address+bytecount-1) > end ) // Is that past the write range? - { - bytecount = end-address+1; // Bytes left in write range. - bytecount &= ~0x01; // Adjust to word count. - } - - if( bytecount > 0 ) - { - setAddress( address >> 1 ); // Flash operations use word addresses. - - /* Start Flash block write */ - comm->sendByte( 'B' ); - comm->sendByte( (bytecount>>8) & 0xff ); // Size, MSB first. - comm->sendByte( bytecount & 0xff ); - comm->sendByte( 'F' ); // Flash memory. - - while( bytecount > 0 ) - { - comm->sendByte( data->getData( address ) ); - address++; - bytecount--; - } - - if( comm->getByte() != '\r' ) - throw new ErrorMsg( "Writing Flash block failed! " - "Programmer did not return CR after 'BxxF'-command." ); - - Util.progress( "#" ); // Advance progress indicator. - } - } - - /* More complete blocks to write? */ - while( (end-address+1) >= blocksize ) - { - bytecount = blocksize; - - setAddress( address >> 1 ); // Flash operations use word addresses. - - /* Start Flash block write */ - comm->sendByte( 'B' ); - comm->sendByte( (bytecount>>8) & 0xff ); // Size, MSB first. - comm->sendByte( bytecount & 0xff ); - comm->sendByte( 'F' ); // Flash memory. - - while( bytecount > 0 ) - { - comm->sendByte( data->getData( address ) ); - address++; - bytecount--; - } - - if( comm->getByte() != '\r' ) - throw new ErrorMsg( "Writing Flash block failed! " - "Programmer did not return CR after 'BxxF'-command." ); - - Util.progress( "#" ); // Advance progress indicator. - } - - /* Any bytes left in last block */ - if( (end-address+1) >= 1 ) - { - bytecount = (end-address+1); // Get bytes left to write. - if( bytecount & 1 ) - bytecount++; // Align to next word boundary. - - setAddress( address >> 1 ); // Flash operations use word addresses. - - /* Start Flash block write */ - comm->sendByte( 'B' ); - comm->sendByte( (bytecount>>8) & 0xff ); // Size, MSB first. - comm->sendByte( bytecount & 0xff ); - comm->sendByte( 'F' ); // Flash memory. - - while( bytecount > 0 ) - { - if( address > end ) - comm->sendByte( 0xff ); // Don't write outside write range. - else - comm->sendByte( data->getData( address ) ); - - address++; - bytecount--; - } - - if( comm->getByte() != '\r' ) - throw new ErrorMsg( "Writing Flash block failed! " - "Programmer did not return CR after 'BxxF'-command." ); - - Util.progress( "#" ); // Advance progress indicator. - } - - Util.progress( "\r\n" ); // Finish progress indicator. - return true; // Indicate supported command. -} - - -bool AVRBootloader::readFlash( HEXFile * data ) -{ - long start, end; // Data address range. - bool autoincrement; // Bootloader supports address autoincrement? - long address; - - if( pagesize == -1 ) - throw new ErrorMsg( "Programmer pagesize is not set!" ); - - /* Check block read support */ - comm->sendByte( 'b' ); - comm->flushTX(); - - if( comm->getByte() == 'Y' ) - { - Util.log( "Using block mode...\r\n" ); - return readFlashBlock( data ); // Finished writing. - } - - /* Get range from HEX file */ - start = data->getRangeStart(); - end = data->getRangeEnd(); - - /* Check autoincrement support */ - comm->sendByte( 'a' ); - comm->flushTX(); - - if( comm->getByte() == 'Y' ) - autoincrement = true; - else - autoincrement = false; - - /* Set initial address */ - setAddress( start >> 1 ); // Flash operations use word addresses. - - /* Need to read one odd byte first? */ - address = start; - if( address & 1 ) - { - /* Read both, but use only high byte */ - comm->sendByte( 'R' ); - comm->flushTX(); - - data->setData( address, comm->getByte() ); // High byte. - comm->getByte(); // Dont use low byte. - address++; - } - - /* Get words */ - while( (end-address+1) >= 2 ) - { - /* Need to set address again? */ - if( !autoincrement ) - setAddress( address >> 1 ); - - /* Get words */ - comm->sendByte( 'R' ); - comm->flushTX(); - - data->setData( address+1, comm->getByte() ); // High byte. - data->setData( address, comm->getByte() ); // Low byte. - address += 2; - - if( (address % MEM_PROGRESS_GRANULARITY) == 0 ) - Util.progress( "#" ); // Advance progress indicator. - - }; - - /* Need to read one even byte before finished? */ - if( address == end ) - { - /* Read both, but use only low byte */ - comm->sendByte( 'R' ); - comm->flushTX(); - - comm->getByte(); // Dont use high byte. - data->setData( address, comm->getByte() ); // Low byte. - } - - Util.progress( "\r\n" ); // Finish progress indicator. - return true; // Indicate supported command. -} - - -bool AVRBootloader::readFlashBlock( HEXFile * data ) -{ - long start, end; // Data address range. - long blocksize; // Bootloader block size. - long bytecount; - long address; - - /* Get block size, assuming command 'b' just issued and 'Y' has been read */ - blocksize = (comm->getByte() << 8) | comm->getByte(); - - /* Get range from HEX file */ - start = data->getRangeStart(); - end = data->getRangeEnd(); - - /* Need to read one odd byte first? */ - address = start; - if( address & 1 ) - { - setAddress( address >> 1 ); // Flash operations use word addresses. - - /* Use only high word */ - comm->sendByte( 'R' ); - comm->flushTX(); - - data->setData( address, comm->getByte() ); // High byte. - comm->getByte(); // Low byte. - address++; - } - - /* Need to read from middle to end of block first? */ - if( (address % blocksize) > 0 ) // In the middle of a block? - { - bytecount = blocksize - (address % blocksize); // Bytes left in block. - - if( (address+bytecount-1) > end ) // Is that past the read range? - { - bytecount = end-address+1; // Bytes left in read range. - bytecount &= ~0x01; // Adjust to word count. - } - - if( bytecount > 0 ) - { - setAddress( address >> 1 ); // Flash operations use word addresses. - - /* Start Flash block read */ - comm->sendByte( 'g' ); - comm->sendByte( (bytecount>>8) & 0xff ); // Size, MSB first. - comm->sendByte( bytecount & 0xff ); - comm->sendByte( 'F' ); // Flash memory. - - while( bytecount > 0 ) - { - data->setData( address, comm->getByte() ); - address++; - bytecount--; - } - - Util.progress( "#" ); // Advance progress indicator. - } - } - - /* More complete blocks to read? */ - while( (end-address+1) >= blocksize ) - { - bytecount = blocksize; - - setAddress( address >> 1 ); // Flash operations use word addresses. - - /* Start Flash block read */ - comm->sendByte( 'g' ); - comm->sendByte( (bytecount>>8) & 0xff ); // Size, MSB first. - comm->sendByte( bytecount & 0xff ); - comm->sendByte( 'F' ); // Flash memory. - - while( bytecount > 0 ) - { - data->setData( address, comm->getByte() ); - address++; - bytecount--; - } - - Util.progress( "#" ); // Advance progress indicator. - } - - /* Any bytes left in last block */ - if( (end-address+1) >= 1 ) - { - bytecount = (end-address+1); // Get bytes left to read. - if( bytecount & 1 ) - bytecount++; // Align to next word boundary. - - setAddress( address >> 1 ); // Flash operations use word addresses. - - /* Start Flash block read */ - comm->sendByte( 'g' ); - comm->sendByte( (bytecount>>8) & 0xff ); // Size, MSB first. - comm->sendByte( bytecount & 0xff ); - comm->sendByte( 'F' ); // Flash memory. - - while( bytecount > 0 ) - { - if( address > end ) - comm->getByte(); // Don't read outside write range. - else - data->setData( address, comm->getByte() ); - - address++; - bytecount--; - } - - Util.progress( "#" ); // Advance progress indicator. - } - - Util.progress( "\r\n" ); // Finish progress indicator. - return true; // Indicate supported command. -} - - -bool AVRBootloader::writeEEPROM( HEXFile * data ) -{ - long start, end; // Data address range. - bool autoincrement; // Bootloader supports address autoincrement? - long address; - - /* Check block write support */ - comm->sendByte( 'b' ); - comm->flushTX(); - - if( comm->getByte() == 'Y' ) - { - Util.log( "Using block mode...\r\n" ); - return writeEEPROMBlock( data ); // Finished writing. - } - - /* Get range from HEX file */ - start = data->getRangeStart(); - end = data->getRangeEnd(); - - /* Check autoincrement support */ - comm->sendByte( 'a' ); - comm->flushTX(); - - if( comm->getByte() == 'Y' ) - autoincrement = true; - else - autoincrement = false; - - /* Set initial address */ - setAddress( start ); - - /* Send data */ - address = start; - do - { - /* Need to set address again? */ - if( !autoincrement ) - setAddress( address ); - - /* Send byte */ - comm->sendByte( 'D' ); - comm->sendByte( data->getData( address ) ); - comm->flushTX(); - - if( comm->getByte() != '\r' ) - throw new ErrorMsg( "Writing byte to EEPROM failed! " - "Programmer did not return CR after 'D'-command." ); - - if( (address % MEM_PROGRESS_GRANULARITY) == 0 ) - Util.progress( "#" ); // Advance progress indicator. - - address++; - } while( address <= end ); - - Util.progress( "\r\n" ); // Finish progress indicator. - return true; // Indicate supported command. -} - - -bool AVRBootloader::writeEEPROMBlock( HEXFile * data ) -{ - long start, end; // Data address range. - long blocksize; // Bootloader block size. - long bytecount; - long address; - - /* Get block size, assuming command 'b' just issued and 'Y' has been read */ - blocksize = (comm->getByte() << 8) | comm->getByte(); - - /* Get range from HEX file */ - start = data->getRangeStart(); - end = data->getRangeEnd(); - - /* Send data */ - address = start; - while( address <= end ) // More bytes to write? - { - bytecount = blocksize; // Try a full block. - - if( (address+bytecount-1) > end ) // Is that past the write range? - { - bytecount = end-address+1; // Bytes left in write range. - } - - setAddress( address ); - - /* Start EEPROM block write */ - comm->sendByte( 'B' ); - comm->sendByte( (bytecount>>8) & 0xff ); // Size, MSB first. - comm->sendByte( bytecount & 0xff ); - comm->sendByte( 'E' ); // EEPROM memory. - - while( bytecount > 0 ) - { - comm->sendByte( data->getData( address ) ); - comm->flushTX(); - - address++; - bytecount--; - } - - if( comm->getByte() != '\r' ) - throw new ErrorMsg( "Writing EEPROM block failed! " - "Programmer did not return CR after 'BxxE'-command." ); - - Util.progress( "#" ); // Advance progress indicator. - } - - Util.progress( "\r\n" ); // Finish progress indicator. - return true; // Indicate supported command. -} - - -bool AVRBootloader::readEEPROM( HEXFile * data ) -{ - long start, end; // Data address range. - bool autoincrement; // Bootloader supports address autoincrement? - long address; - - /* Check block write support */ - comm->sendByte( 'b' ); - comm->flushTX(); - - if( comm->getByte() == 'Y' ) - { - Util.log( "Using block mode...\r\n" ); - return readEEPROMBlock( data ); // Finished writing. - } - - /* Get range from HEX file */ - start = data->getRangeStart(); - end = data->getRangeEnd(); - - /* Check autoincrement support */ - comm->sendByte( 'a' ); - comm->flushTX(); - - if( comm->getByte() == 'Y' ) - autoincrement = true; - else - autoincrement = false; - - /* Set initial address */ - setAddress( start ); - - /* Read data */ - address = start; - do - { - /* Need to set address again? */ - if( !autoincrement ) - setAddress( address ); - - /* Get byte */ - comm->sendByte( 'd' ); - comm->flushTX(); - - data->setData( address, comm->getByte() ); - - if( (address % MEM_PROGRESS_GRANULARITY) == 0 ) - Util.progress( "#" ); // Advance progress indicator. - - address++; - } while( address <= end ); - - Util.progress( "\r\n" ); // Finish progress indicator. - return true; // Indicate supported command. -} - - -bool AVRBootloader::readEEPROMBlock( HEXFile * data ) -{ - long start, end; // Data address range. - long blocksize; // Bootloader block size. - long bytecount; - long address; - - /* Get block size, assuming command 'b' just issued and 'Y' has been read */ - blocksize = (comm->getByte() << 8) | comm->getByte(); - - /* Get range from HEX file */ - start = data->getRangeStart(); - end = data->getRangeEnd(); - - /* Read data */ - address = start; - while( address <= end ) // More bytes to read? - { - bytecount = blocksize; // Try a full block. - - if( (address+bytecount-1) > end ) // Is that past the read range? - { - bytecount = end-address+1; // Bytes left in read range. - } - - setAddress( address ); - - /* Start EEPROM block read */ - comm->sendByte( 'g' ); - comm->sendByte( (bytecount>>8) & 0xff ); // Size, MSB first. - comm->sendByte( bytecount & 0xff ); - comm->sendByte( 'E' ); // EEPROM memory. - - while( bytecount > 0 ) - { - data->setData( address, comm->getByte() ); - address++; - bytecount--; - } - - Util.progress( "#" ); // Advance progress indicator. - } - - Util.progress( "\r\n" ); // Finish progress indicator. - return true; // Indicate supported command. -} - - -bool AVRBootloader::writeLockBits( long bits ) -{ - /* Send command 'l' */ - comm->sendByte( 'l' ); - comm->sendByte( bits & 0xff ); - comm->flushTX(); - - /* Should return CR */ - if( comm->getByte() != '\r' ) - throw new ErrorMsg( "Writing lock bits failed! " - "Programmer did not return CR after 'l'-command." ); - - return true; // Indicate supported command. -} - - -bool AVRBootloader::readLockBits( long * bits ) -{ - /* Send command 'r' */ - comm->sendByte( 'r' ); - comm->flushTX(); - - /* Get data */ - *bits = comm->getByte(); - - return true; // Indicate supported command. -} - - -bool AVRBootloader::writeFuseBits( long bits ) -{ - return false; // Indicate unsupported command. -} - - -bool AVRBootloader::readFuseBits( long * bits ) -{ - long lowfuse, highfuse; - - /* Send command 'N' */ - comm->sendByte( 'N' ); - comm->flushTX(); - - /* Get high fuse bits */ - highfuse = comm->getByte(); - - /* Send command 'F' */ - comm->sendByte( 'F' ); - comm->flushTX(); - - /* Get low fuse bits */ - lowfuse = comm->getByte(); - - *bits = (highfuse << 8) | lowfuse; - - return true; // Indicate supported command. -} - - -bool AVRBootloader::writeExtendedFuseBits( long bits ) -{ - return false; // Indicate unsupported command. -} - - -bool AVRBootloader::readExtendedFuseBits( long * bits ) -{ - /* Send command 'Q' */ - comm->sendByte( 'Q' ); - comm->flushTX(); - - /* Get data */ - *bits = comm->getByte(); - - return true; // Indicate supported command. -} - - -bool AVRBootloader::programmerSoftwareVersion( long * major, long * minor ) -{ - /* Send command 'V' to get software version */ - comm->sendByte( 'V' ); - comm->flushTX(); - - /* Get data */ - *major = comm->getByte(); - *minor = comm->getByte(); - - return true; // Indicate supported command. -} - - -bool AVRBootloader::programmerHardwareVersion( long * major, long * minor ) -{ - return false; // Indicate unsupported command. -} - - -void AVRBootloader::setAddress( long address ) -{ - /* Set current address */ - if( address < 0x10000 ) { - comm->sendByte( 'A' ); - comm->sendByte( (address >> 8) & 0xff ); - comm->sendByte( address & 0xff ); - comm->flushTX(); - } else { - comm->sendByte( 'H' ); - comm->sendByte( (address >> 16) & 0xff ); - comm->sendByte( (address >> 8) & 0xff ); - comm->sendByte( address & 0xff ); - comm->flushTX(); - } - - /* Should return CR */ - if( comm->getByte() != '\r' ) { - throw new ErrorMsg( "Setting address for programming operations failed! " - "Programmer did not return CR after 'A'-command." ); - } -} - - -void AVRBootloader::writeFlashLowByte( long value ) -{ - comm->sendByte( 'c' ); - comm->sendByte( value ); - comm->flushTX(); - - if( comm->getByte() != '\r' ) - throw new ErrorMsg( "Writing Flash low byte failed! " - "Programmer did not return CR after 'c'-command." ); -} - - -void AVRBootloader::writeFlashHighByte( long value ) -{ - comm->sendByte( 'C' ); - comm->sendByte( value ); - comm->flushTX(); - - if( comm->getByte() != '\r' ) - throw new ErrorMsg( "Writing Flash high byte failed! " - "Programmer did not return CR after 'C'-command." ); -} - - -void AVRBootloader::writeFlashPage() -{ - comm->sendByte( 'm' ); - comm->flushTX(); - - if( comm->getByte() != '\r' ) - throw new ErrorMsg( "Writing Flash page failed! " - "Programmer did not return CR after 'm'-command." ); -} - - -/* end of file */ - +/***************************************************************************** + * + * Atmel Corporation + * + * File : AVRBootloader.cpp + * Compiler : Dev-C++ 4.9.8.0 - http://bloodshed.net/dev/ + * Revision : $Revision: 1163 $ + * Date : $Date: 2006-08-02 15:38:16 +0200 (on, 02 aug 2006) $ + * Updated by : $Author: ohlia $ + * + * Support mail : avr@atmel.com + * + * Target platform : Win32 + * + * AppNote : AVR911 - AVR Open-source Programmer + * + * Description : A class providing an interface to the AVR bootloader + * described in Application Note AVR109. + * This class is derived from AVRPRogrammer. + * + * + ****************************************************************************/ +#include "AVRBootloader.hpp" + +#include +#include + +#define MEM_PROGRESS_GRANULARITY 256 // For use with progress indicator. + + +/* Constructor */ +AVRBootloader::AVRBootloader( CommChannel * _comm ) : + AVRProgrammer::AVRProgrammer( _comm ) +{ + /* No code here */ +} + + +/* Destructor */ +AVRBootloader::~AVRBootloader() +{ + /* No code here */ +} + + +bool AVRBootloader::enterProgrammingMode() +{ + return true; // Always OK for bootloader. +} + + +bool AVRBootloader::leaveProgrammingMode() +{ + return true; // Always OK for bootloader. +} + + +bool AVRBootloader::chipErase() +{ + /* Send command 'e' */ + comm->sendByte( 'e' ); + comm->flushTX(); + + /* Should return CR */ + if( comm->getByte() != '\r' ) + throw new ErrorMsg( "Chip erase failed! " + "Programmer did not return CR after 'e'-command." ); + + return true; // Indicate supported command. +} + + +bool AVRBootloader::readOSCCAL( long pos, long * value ) +{ + return false; // Indicate unsupported command. +} + + +bool AVRBootloader::readSignature( long * sig0, long * sig1, long * sig2 ) +{ + /* Send command 's' */ + comm->sendByte( 's' ); + comm->flushTX(); + + /* Get actual signature */ + *sig2 = comm->getByte(); + *sig1 = comm->getByte(); + *sig0 = comm->getByte(); +} + + +bool AVRBootloader::checkSignature( long sig0, long sig1, long sig2 ) +{ + long sig[3]; + + /* Get signature */ + readSignature( sig, sig+1, sig+2 ); + + /* Compare signature */ + if( sig[0] != sig0 || sig[1] != sig1 || sig[2] != sig2 ) + { + ostringstream msg; + msg << "Signature does not match selected device! "; + msg << "Actual signature: (" << hex + << "0x" << setw(2) << sig[0] << " " + << "0x" << setw(2) << sig[1] << " " + << "0x" << setw(2) << sig[2] << ") " + << "Signature from XML-file: (" << hex + << "0x" << setw(2) << sig0 << " " + << "0x" << setw(2) << sig1 << " " + << "0x" << setw(2) << sig2 << ")."; + + throw new ErrorMsg( msg.str() ); + } + + return true; // Indicate supported command. +} + + +bool AVRBootloader::writeFlashByte( long address, long value ) +{ + setAddress( address >> 1 ); // Flash operations use word addresses. + + /* Move data if at odd address */ + if( address & 0x01 ) // Odd address? + value = (value << 8) | 0x00ff; // Move to high byte of one flash word. + else + value |= 0xff00; // Ensure no-write for high byte. + + /* Send low and high byte */ + writeFlashLowByte( value & 0xff ); + writeFlashHighByte( value >> 8 ); + + /* Issue page write */ + setAddress( address >> 1 ); // The address could be autoincremented. + writeFlashPage(); + + return true; // Indicate supported command. +} + + +bool AVRBootloader::writeEEPROMByte( long address, long value ) +{ + if( address >= 0x10000 ) + throw new ErrorMsg( "EEPROM addresses above 64k are currently not supported!" ); + + setAddress( address ); + + /* Send data */ + comm->sendByte( 'D' ); + comm->sendByte( value ); + comm->flushTX(); + + /* Should return CR */ + if( comm->getByte() != '\r' ) + throw new ErrorMsg( "Writing byte to EEPROM failed! " + "Programmer did not return CR after 'D'-command." ); + + return true; // Indicate supported command. +} + + +bool AVRBootloader::writeFlash( HEXFile * data ) +{ + long start, end; // Data address range. + bool autoincrement; // Bootloader supports address autoincrement? + long address; + + /* Check that pagesize is set */ + if( pagesize == -1 ) + throw new ErrorMsg( "Programmer pagesize is not set!" ); + + /* Check block write support */ + comm->sendByte( 'b' ); + comm->flushTX(); + + if( comm->getByte() == 'Y' ) + { + Util.log( "Using block mode...\r\n" ); + return writeFlashBlock( data ); // Finished writing. + } + + /* Get range from HEX file */ + start = data->getRangeStart(); + end = data->getRangeEnd(); + + /* Check autoincrement support */ + comm->sendByte( 'a' ); + comm->flushTX(); + + if( comm->getByte() == 'Y' ) + autoincrement = true; + else + autoincrement = false; + + /* Set initial address */ + setAddress( start >> 1 ); // Flash operations use word addresses. + + /* Need to write one odd byte first? */ + address = start; + if( address & 1 ) + { + /* Use only high byte */ + writeFlashLowByte( 0xff ); // No-write in low byte. + writeFlashHighByte( data->getData( address ) ); + address++; + + /* Need to write page? */ + if( (address % pagesize) == 0 || + address > end ) // Just passed page limit or no more bytes to write? + { + setAddress( (address-2) >> 1 ); // Set to an address inside the page. + writeFlashPage(); + setAddress( address >> 1 ); + } + } + + /* Write words */ + while( (end-address+1) >= 2 ) // More words left? + { + /* Need to set address again? */ + if( !autoincrement ) + setAddress( address >> 1 ); + + /* Write words */ + writeFlashLowByte( data->getData( address ) ); + writeFlashHighByte( data->getData( address+1 ) ); + address += 2; + + if( (address % MEM_PROGRESS_GRANULARITY) == 0 ) + Util.progress( "#" ); // Advance progress indicator. + + /* Need to write page? */ + if( (address % pagesize) == 0 || + address > end ) // Just passed a page limit or no more bytes to write? + { + setAddress( (address-2) >> 1 ); // Set to an address inside the page. + writeFlashPage(); + setAddress( address >> 1 ); + } + } + + /* Need to write one even byte before finished? */ + if( address == end ) + { + /* Use only low byte */ + writeFlashLowByte( data->getData( address ) ); + writeFlashHighByte( 0xff ); // No-write in high byte. + address+=2; + + /* Write page */ + setAddress( (address-2) >> 1 ); // Set to an address inside the page. + writeFlashPage(); + } + + Util.progress( "\r\n" ); // Finish progress indicator. + return true; // Indicate supported command. +} + + +bool AVRBootloader::writeFlashBlock( HEXFile * data ) +{ + long start, end; // Data address range. + long blocksize; // Bootloader block size. + long bytecount; + long address; + + /* Get block size, assuming command 'b' just issued and 'Y' has been read */ + blocksize = (comm->getByte() << 8) | comm->getByte(); + + /* Get range from HEX file */ + start = data->getRangeStart(); + end = data->getRangeEnd(); + + /* Need to write one odd byte first? */ + address = start; + if( address & 1 ) + { + setAddress( address >> 1 ); // Flash operations use word addresses. + + /* Use only high byte */ + writeFlashLowByte( 0xff ); // No-write in low byte. + writeFlashHighByte( data->getData( address ) ); + address++; + + /* Need to write page? */ + if( (address % pagesize) == 0 || + address > end ) // Just passed page limit or no more bytes to write? + { + setAddress( (address-2) >> 1 ); // Set to an address inside the page. + writeFlashPage(); + setAddress( address >> 1 ); + } + } + + /* Need to write from middle to end of block first? */ + if( (address % blocksize) > 0 ) // In the middle of a block? + { + bytecount = blocksize - (address % blocksize); // Bytes left in block. + + if( (address+bytecount-1) > end ) // Is that past the write range? + { + bytecount = end-address+1; // Bytes left in write range. + bytecount &= ~0x01; // Adjust to word count. + } + + if( bytecount > 0 ) + { + setAddress( address >> 1 ); // Flash operations use word addresses. + + /* Start Flash block write */ + comm->sendByte( 'B' ); + comm->sendByte( (bytecount>>8) & 0xff ); // Size, MSB first. + comm->sendByte( bytecount & 0xff ); + comm->sendByte( 'F' ); // Flash memory. + + while( bytecount > 0 ) + { + comm->sendByte( data->getData( address ) ); + address++; + bytecount--; + } + + if( comm->getByte() != '\r' ) + throw new ErrorMsg( "Writing Flash block failed! " + "Programmer did not return CR after 'BxxF'-command." ); + + Util.progress( "#" ); // Advance progress indicator. + } + } + + /* More complete blocks to write? */ + while( (end-address+1) >= blocksize ) + { + bytecount = blocksize; + + setAddress( address >> 1 ); // Flash operations use word addresses. + + /* Start Flash block write */ + comm->sendByte( 'B' ); + comm->sendByte( (bytecount>>8) & 0xff ); // Size, MSB first. + comm->sendByte( bytecount & 0xff ); + comm->sendByte( 'F' ); // Flash memory. + + while( bytecount > 0 ) + { + comm->sendByte( data->getData( address ) ); + address++; + bytecount--; + } + + if( comm->getByte() != '\r' ) + throw new ErrorMsg( "Writing Flash block failed! " + "Programmer did not return CR after 'BxxF'-command." ); + + Util.progress( "#" ); // Advance progress indicator. + } + + /* Any bytes left in last block */ + if( (end-address+1) >= 1 ) + { + bytecount = (end-address+1); // Get bytes left to write. + if( bytecount & 1 ) + bytecount++; // Align to next word boundary. + + setAddress( address >> 1 ); // Flash operations use word addresses. + + /* Start Flash block write */ + comm->sendByte( 'B' ); + comm->sendByte( (bytecount>>8) & 0xff ); // Size, MSB first. + comm->sendByte( bytecount & 0xff ); + comm->sendByte( 'F' ); // Flash memory. + + while( bytecount > 0 ) + { + if( address > end ) + comm->sendByte( 0xff ); // Don't write outside write range. + else + comm->sendByte( data->getData( address ) ); + + address++; + bytecount--; + } + + if( comm->getByte() != '\r' ) + throw new ErrorMsg( "Writing Flash block failed! " + "Programmer did not return CR after 'BxxF'-command." ); + + Util.progress( "#" ); // Advance progress indicator. + } + + Util.progress( "\r\n" ); // Finish progress indicator. + return true; // Indicate supported command. +} + + +bool AVRBootloader::readFlash( HEXFile * data ) +{ + long start, end; // Data address range. + bool autoincrement; // Bootloader supports address autoincrement? + long address; + + if( pagesize == -1 ) + throw new ErrorMsg( "Programmer pagesize is not set!" ); + + /* Check block read support */ + comm->sendByte( 'b' ); + comm->flushTX(); + + if( comm->getByte() == 'Y' ) + { + Util.log( "Using block mode...\r\n" ); + return readFlashBlock( data ); // Finished writing. + } + + /* Get range from HEX file */ + start = data->getRangeStart(); + end = data->getRangeEnd(); + + /* Check autoincrement support */ + comm->sendByte( 'a' ); + comm->flushTX(); + + if( comm->getByte() == 'Y' ) + autoincrement = true; + else + autoincrement = false; + + /* Set initial address */ + setAddress( start >> 1 ); // Flash operations use word addresses. + + /* Need to read one odd byte first? */ + address = start; + if( address & 1 ) + { + /* Read both, but use only high byte */ + comm->sendByte( 'R' ); + comm->flushTX(); + + data->setData( address, comm->getByte() ); // High byte. + comm->getByte(); // Dont use low byte. + address++; + } + + /* Get words */ + while( (end-address+1) >= 2 ) + { + /* Need to set address again? */ + if( !autoincrement ) + setAddress( address >> 1 ); + + /* Get words */ + comm->sendByte( 'R' ); + comm->flushTX(); + + data->setData( address+1, comm->getByte() ); // High byte. + data->setData( address, comm->getByte() ); // Low byte. + address += 2; + + if( (address % MEM_PROGRESS_GRANULARITY) == 0 ) + Util.progress( "#" ); // Advance progress indicator. + + }; + + /* Need to read one even byte before finished? */ + if( address == end ) + { + /* Read both, but use only low byte */ + comm->sendByte( 'R' ); + comm->flushTX(); + + comm->getByte(); // Dont use high byte. + data->setData( address, comm->getByte() ); // Low byte. + } + + Util.progress( "\r\n" ); // Finish progress indicator. + return true; // Indicate supported command. +} + + +bool AVRBootloader::readFlashBlock( HEXFile * data ) +{ + long start, end; // Data address range. + long blocksize; // Bootloader block size. + long bytecount; + long address; + + /* Get block size, assuming command 'b' just issued and 'Y' has been read */ + blocksize = (comm->getByte() << 8) | comm->getByte(); + + /* Get range from HEX file */ + start = data->getRangeStart(); + end = data->getRangeEnd(); + + /* Need to read one odd byte first? */ + address = start; + if( address & 1 ) + { + setAddress( address >> 1 ); // Flash operations use word addresses. + + /* Use only high word */ + comm->sendByte( 'R' ); + comm->flushTX(); + + data->setData( address, comm->getByte() ); // High byte. + comm->getByte(); // Low byte. + address++; + } + + /* Need to read from middle to end of block first? */ + if( (address % blocksize) > 0 ) // In the middle of a block? + { + bytecount = blocksize - (address % blocksize); // Bytes left in block. + + if( (address+bytecount-1) > end ) // Is that past the read range? + { + bytecount = end-address+1; // Bytes left in read range. + bytecount &= ~0x01; // Adjust to word count. + } + + if( bytecount > 0 ) + { + setAddress( address >> 1 ); // Flash operations use word addresses. + + /* Start Flash block read */ + comm->sendByte( 'g' ); + comm->sendByte( (bytecount>>8) & 0xff ); // Size, MSB first. + comm->sendByte( bytecount & 0xff ); + comm->sendByte( 'F' ); // Flash memory. + + while( bytecount > 0 ) + { + data->setData( address, comm->getByte() ); + address++; + bytecount--; + } + + Util.progress( "#" ); // Advance progress indicator. + } + } + + /* More complete blocks to read? */ + while( (end-address+1) >= blocksize ) + { + bytecount = blocksize; + + setAddress( address >> 1 ); // Flash operations use word addresses. + + /* Start Flash block read */ + comm->sendByte( 'g' ); + comm->sendByte( (bytecount>>8) & 0xff ); // Size, MSB first. + comm->sendByte( bytecount & 0xff ); + comm->sendByte( 'F' ); // Flash memory. + + while( bytecount > 0 ) + { + data->setData( address, comm->getByte() ); + address++; + bytecount--; + } + + Util.progress( "#" ); // Advance progress indicator. + } + + /* Any bytes left in last block */ + if( (end-address+1) >= 1 ) + { + bytecount = (end-address+1); // Get bytes left to read. + if( bytecount & 1 ) + bytecount++; // Align to next word boundary. + + setAddress( address >> 1 ); // Flash operations use word addresses. + + /* Start Flash block read */ + comm->sendByte( 'g' ); + comm->sendByte( (bytecount>>8) & 0xff ); // Size, MSB first. + comm->sendByte( bytecount & 0xff ); + comm->sendByte( 'F' ); // Flash memory. + + while( bytecount > 0 ) + { + if( address > end ) + comm->getByte(); // Don't read outside write range. + else + data->setData( address, comm->getByte() ); + + address++; + bytecount--; + } + + Util.progress( "#" ); // Advance progress indicator. + } + + Util.progress( "\r\n" ); // Finish progress indicator. + return true; // Indicate supported command. +} + + +bool AVRBootloader::writeEEPROM( HEXFile * data ) +{ + long start, end; // Data address range. + bool autoincrement; // Bootloader supports address autoincrement? + long address; + + /* Check block write support */ + comm->sendByte( 'b' ); + comm->flushTX(); + + if( comm->getByte() == 'Y' ) + { + Util.log( "Using block mode...\r\n" ); + return writeEEPROMBlock( data ); // Finished writing. + } + + /* Get range from HEX file */ + start = data->getRangeStart(); + end = data->getRangeEnd(); + + /* Check autoincrement support */ + comm->sendByte( 'a' ); + comm->flushTX(); + + if( comm->getByte() == 'Y' ) + autoincrement = true; + else + autoincrement = false; + + /* Set initial address */ + setAddress( start ); + + /* Send data */ + address = start; + do + { + /* Need to set address again? */ + if( !autoincrement ) + setAddress( address ); + + /* Send byte */ + comm->sendByte( 'D' ); + comm->sendByte( data->getData( address ) ); + comm->flushTX(); + + if( comm->getByte() != '\r' ) + throw new ErrorMsg( "Writing byte to EEPROM failed! " + "Programmer did not return CR after 'D'-command." ); + + if( (address % MEM_PROGRESS_GRANULARITY) == 0 ) + Util.progress( "#" ); // Advance progress indicator. + + address++; + } while( address <= end ); + + Util.progress( "\r\n" ); // Finish progress indicator. + return true; // Indicate supported command. +} + + +bool AVRBootloader::writeEEPROMBlock( HEXFile * data ) +{ + long start, end; // Data address range. + long blocksize; // Bootloader block size. + long bytecount; + long address; + + /* Get block size, assuming command 'b' just issued and 'Y' has been read */ + blocksize = (comm->getByte() << 8) | comm->getByte(); + + /* Get range from HEX file */ + start = data->getRangeStart(); + end = data->getRangeEnd(); + + /* Send data */ + address = start; + while( address <= end ) // More bytes to write? + { + bytecount = blocksize; // Try a full block. + + if( (address+bytecount-1) > end ) // Is that past the write range? + { + bytecount = end-address+1; // Bytes left in write range. + } + + setAddress( address ); + + /* Start EEPROM block write */ + comm->sendByte( 'B' ); + comm->sendByte( (bytecount>>8) & 0xff ); // Size, MSB first. + comm->sendByte( bytecount & 0xff ); + comm->sendByte( 'E' ); // EEPROM memory. + + while( bytecount > 0 ) + { + comm->sendByte( data->getData( address ) ); + comm->flushTX(); + + address++; + bytecount--; + } + + if( comm->getByte() != '\r' ) + throw new ErrorMsg( "Writing EEPROM block failed! " + "Programmer did not return CR after 'BxxE'-command." ); + + Util.progress( "#" ); // Advance progress indicator. + } + + Util.progress( "\r\n" ); // Finish progress indicator. + return true; // Indicate supported command. +} + + +bool AVRBootloader::readEEPROM( HEXFile * data ) +{ + long start, end; // Data address range. + bool autoincrement; // Bootloader supports address autoincrement? + long address; + + /* Check block write support */ + comm->sendByte( 'b' ); + comm->flushTX(); + + if( comm->getByte() == 'Y' ) + { + Util.log( "Using block mode...\r\n" ); + return readEEPROMBlock( data ); // Finished writing. + } + + /* Get range from HEX file */ + start = data->getRangeStart(); + end = data->getRangeEnd(); + + /* Check autoincrement support */ + comm->sendByte( 'a' ); + comm->flushTX(); + + if( comm->getByte() == 'Y' ) + autoincrement = true; + else + autoincrement = false; + + /* Set initial address */ + setAddress( start ); + + /* Read data */ + address = start; + do + { + /* Need to set address again? */ + if( !autoincrement ) + setAddress( address ); + + /* Get byte */ + comm->sendByte( 'd' ); + comm->flushTX(); + + data->setData( address, comm->getByte() ); + + if( (address % MEM_PROGRESS_GRANULARITY) == 0 ) + Util.progress( "#" ); // Advance progress indicator. + + address++; + } while( address <= end ); + + Util.progress( "\r\n" ); // Finish progress indicator. + return true; // Indicate supported command. +} + + +bool AVRBootloader::readEEPROMBlock( HEXFile * data ) +{ + long start, end; // Data address range. + long blocksize; // Bootloader block size. + long bytecount; + long address; + + /* Get block size, assuming command 'b' just issued and 'Y' has been read */ + blocksize = (comm->getByte() << 8) | comm->getByte(); + + /* Get range from HEX file */ + start = data->getRangeStart(); + end = data->getRangeEnd(); + + /* Read data */ + address = start; + while( address <= end ) // More bytes to read? + { + bytecount = blocksize; // Try a full block. + + if( (address+bytecount-1) > end ) // Is that past the read range? + { + bytecount = end-address+1; // Bytes left in read range. + } + + setAddress( address ); + + /* Start EEPROM block read */ + comm->sendByte( 'g' ); + comm->sendByte( (bytecount>>8) & 0xff ); // Size, MSB first. + comm->sendByte( bytecount & 0xff ); + comm->sendByte( 'E' ); // EEPROM memory. + + while( bytecount > 0 ) + { + data->setData( address, comm->getByte() ); + address++; + bytecount--; + } + + Util.progress( "#" ); // Advance progress indicator. + } + + Util.progress( "\r\n" ); // Finish progress indicator. + return true; // Indicate supported command. +} + + +bool AVRBootloader::writeLockBits( long bits ) +{ + /* Send command 'l' */ + comm->sendByte( 'l' ); + comm->sendByte( bits & 0xff ); + comm->flushTX(); + + /* Should return CR */ + if( comm->getByte() != '\r' ) + throw new ErrorMsg( "Writing lock bits failed! " + "Programmer did not return CR after 'l'-command." ); + + return true; // Indicate supported command. +} + + +bool AVRBootloader::readLockBits( long * bits ) +{ + /* Send command 'r' */ + comm->sendByte( 'r' ); + comm->flushTX(); + + /* Get data */ + *bits = comm->getByte(); + + return true; // Indicate supported command. +} + + +bool AVRBootloader::writeFuseBits( long bits ) +{ + return false; // Indicate unsupported command. +} + + +bool AVRBootloader::readFuseBits( long * bits ) +{ + long lowfuse, highfuse; + + /* Send command 'N' */ + comm->sendByte( 'N' ); + comm->flushTX(); + + /* Get high fuse bits */ + highfuse = comm->getByte(); + + /* Send command 'F' */ + comm->sendByte( 'F' ); + comm->flushTX(); + + /* Get low fuse bits */ + lowfuse = comm->getByte(); + + *bits = (highfuse << 8) | lowfuse; + + return true; // Indicate supported command. +} + + +bool AVRBootloader::writeExtendedFuseBits( long bits ) +{ + return false; // Indicate unsupported command. +} + + +bool AVRBootloader::readExtendedFuseBits( long * bits ) +{ + /* Send command 'Q' */ + comm->sendByte( 'Q' ); + comm->flushTX(); + + /* Get data */ + *bits = comm->getByte(); + + return true; // Indicate supported command. +} + + +bool AVRBootloader::programmerSoftwareVersion( long * major, long * minor ) +{ + /* Send command 'V' to get software version */ + comm->sendByte( 'V' ); + comm->flushTX(); + + /* Get data */ + *major = comm->getByte(); + *minor = comm->getByte(); + + return true; // Indicate supported command. +} + + +bool AVRBootloader::programmerHardwareVersion( long * major, long * minor ) +{ + return false; // Indicate unsupported command. +} + + +void AVRBootloader::setAddress( long address ) +{ + /* Set current address */ + if( address < 0x10000 ) { + comm->sendByte( 'A' ); + comm->sendByte( (address >> 8) & 0xff ); + comm->sendByte( address & 0xff ); + comm->flushTX(); + } else { + comm->sendByte( 'H' ); + comm->sendByte( (address >> 16) & 0xff ); + comm->sendByte( (address >> 8) & 0xff ); + comm->sendByte( address & 0xff ); + comm->flushTX(); + } + + /* Should return CR */ + if( comm->getByte() != '\r' ) { + throw new ErrorMsg( "Setting address for programming operations failed! " + "Programmer did not return CR after 'A'-command." ); + } +} + + +void AVRBootloader::writeFlashLowByte( long value ) +{ + comm->sendByte( 'c' ); + comm->sendByte( value ); + comm->flushTX(); + + if( comm->getByte() != '\r' ) + throw new ErrorMsg( "Writing Flash low byte failed! " + "Programmer did not return CR after 'c'-command." ); +} + + +void AVRBootloader::writeFlashHighByte( long value ) +{ + comm->sendByte( 'C' ); + comm->sendByte( value ); + comm->flushTX(); + + if( comm->getByte() != '\r' ) + throw new ErrorMsg( "Writing Flash high byte failed! " + "Programmer did not return CR after 'C'-command." ); +} + + +void AVRBootloader::writeFlashPage() +{ + comm->sendByte( 'm' ); + comm->flushTX(); + + if( comm->getByte() != '\r' ) + throw new ErrorMsg( "Writing Flash page failed! " + "Programmer did not return CR after 'm'-command." ); +} + + +/* end of file */ + diff --git a/ports/bdk-atxx4-mstp/avrosp/AVRBootloader.hpp b/ports/bdk-atxx4-mstp/avrosp/AVRBootloader.hpp index df7bfa88..785d9da4 100644 --- a/ports/bdk-atxx4-mstp/avrosp/AVRBootloader.hpp +++ b/ports/bdk-atxx4-mstp/avrosp/AVRBootloader.hpp @@ -1,84 +1,84 @@ -/***************************************************************************** - * - * Atmel Corporation - * - * File : AVRBootloader.hpp - * Compiler : Dev-C++ 4.9.8.0 - http://bloodshed.net/dev/ - * Revision : $Revision: 1163 $ - * Date : $Date: 2006-08-02 15:38:16 +0200 (on, 02 aug 2006) $ - * Updated by : $Author: ohlia $ - * - * Support mail : avr@atmel.com - * - * Target platform : Win32 - * - * AppNote : AVR911 - AVR Open-source Programmer - * - * Description : A class providing an interface to the AVR bootloader - * described in Application Note AVR109. - * This class is derived from AVRPRogrammer. - * - * - ****************************************************************************/ -#ifndef AVRBOOTLOADER_HPP -#define AVRBOOTLOADER_HPP - -using namespace std; - -#include "AVRProgrammer.hpp" -#include "Utility.hpp" - -class AVRBootloader : public AVRProgrammer -{ - protected: - virtual void setAddress( long address ); - virtual void writeFlashLowByte( long value ); // Alwyas low byte first... - virtual void writeFlashHighByte( long value ); // ...then high byte. - virtual void writeFlashPage(); - - virtual bool writeFlashBlock( HEXFile * data ); - virtual bool readFlashBlock( HEXFile * data ); - virtual bool writeEEPROMBlock( HEXFile * data ); - virtual bool readEEPROMBlock( HEXFile * data ); - - public: - /* Constructor */ - AVRBootloader( CommChannel * _comm ); - - /* Destructor */ - ~AVRBootloader(); - - /* Methods */ - virtual bool enterProgrammingMode(); - virtual bool leaveProgrammingMode(); - - virtual bool chipErase(); - - virtual bool readOSCCAL( long pos, long * value ); - virtual bool readSignature( long * sig0, long * sig1, long * sig2 ); - virtual bool checkSignature( long sig0, long sig1, long sig2 ); - - virtual bool writeFlashByte( long address, long value ); - virtual bool writeEEPROMByte( long address, long value ); - - virtual bool writeFlash( HEXFile * data ); - virtual bool readFlash( HEXFile * data ); - - virtual bool writeEEPROM( HEXFile * data ); - virtual bool readEEPROM( HEXFile * data ); - - virtual bool writeLockBits( long bits ); - virtual bool readLockBits( long * bits ); - - virtual bool writeFuseBits( long bits ); - virtual bool readFuseBits( long * bits ); - virtual bool writeExtendedFuseBits( long bits ); - virtual bool readExtendedFuseBits( long * bits ); - - virtual bool programmerSoftwareVersion( long * major, long * minor ); - virtual bool programmerHardwareVersion( long * major, long * minor ); -}; - - -#endif - +/***************************************************************************** + * + * Atmel Corporation + * + * File : AVRBootloader.hpp + * Compiler : Dev-C++ 4.9.8.0 - http://bloodshed.net/dev/ + * Revision : $Revision: 1163 $ + * Date : $Date: 2006-08-02 15:38:16 +0200 (on, 02 aug 2006) $ + * Updated by : $Author: ohlia $ + * + * Support mail : avr@atmel.com + * + * Target platform : Win32 + * + * AppNote : AVR911 - AVR Open-source Programmer + * + * Description : A class providing an interface to the AVR bootloader + * described in Application Note AVR109. + * This class is derived from AVRPRogrammer. + * + * + ****************************************************************************/ +#ifndef AVRBOOTLOADER_HPP +#define AVRBOOTLOADER_HPP + +using namespace std; + +#include "AVRProgrammer.hpp" +#include "Utility.hpp" + +class AVRBootloader : public AVRProgrammer +{ + protected: + virtual void setAddress( long address ); + virtual void writeFlashLowByte( long value ); // Alwyas low byte first... + virtual void writeFlashHighByte( long value ); // ...then high byte. + virtual void writeFlashPage(); + + virtual bool writeFlashBlock( HEXFile * data ); + virtual bool readFlashBlock( HEXFile * data ); + virtual bool writeEEPROMBlock( HEXFile * data ); + virtual bool readEEPROMBlock( HEXFile * data ); + + public: + /* Constructor */ + AVRBootloader( CommChannel * _comm ); + + /* Destructor */ + ~AVRBootloader(); + + /* Methods */ + virtual bool enterProgrammingMode(); + virtual bool leaveProgrammingMode(); + + virtual bool chipErase(); + + virtual bool readOSCCAL( long pos, long * value ); + virtual bool readSignature( long * sig0, long * sig1, long * sig2 ); + virtual bool checkSignature( long sig0, long sig1, long sig2 ); + + virtual bool writeFlashByte( long address, long value ); + virtual bool writeEEPROMByte( long address, long value ); + + virtual bool writeFlash( HEXFile * data ); + virtual bool readFlash( HEXFile * data ); + + virtual bool writeEEPROM( HEXFile * data ); + virtual bool readEEPROM( HEXFile * data ); + + virtual bool writeLockBits( long bits ); + virtual bool readLockBits( long * bits ); + + virtual bool writeFuseBits( long bits ); + virtual bool readFuseBits( long * bits ); + virtual bool writeExtendedFuseBits( long bits ); + virtual bool readExtendedFuseBits( long * bits ); + + virtual bool programmerSoftwareVersion( long * major, long * minor ); + virtual bool programmerHardwareVersion( long * major, long * minor ); +}; + + +#endif + diff --git a/ports/bdk-atxx4-mstp/avrosp/AVRDevice.cpp b/ports/bdk-atxx4-mstp/avrosp/AVRDevice.cpp index c7aa8852..72361a06 100644 --- a/ports/bdk-atxx4-mstp/avrosp/AVRDevice.cpp +++ b/ports/bdk-atxx4-mstp/avrosp/AVRDevice.cpp @@ -1,157 +1,157 @@ -/***************************************************************************** - * - * Atmel Corporation - * - * File : AVRDevice.cpp - * Compiler : Dev-C++ 4.9.8.0 - http://bloodshed.net/dev/ - * Revision : $Revision: 4017 $ - * Date : $Date: 2008-06-02 14:26:03 +0200 (ma, 02 jun 2008) $ - * Updated by : $Author: khole $ - * - * Support mail : avr@atmel.com - * - * Target platform : Win32 - * - * AppNote : AVR911 - AVR Open-source Programmer - * - * Description : A class containing information of device memory sizes etc. - * It also provides funcitons for reading these parameters from - * the PartDescriptionFiles supplied with AVR Studio 4. - * - * - ****************************************************************************/ -#include "AVRDevice.hpp" - - -/* Constructor */ -AVRDevice::AVRDevice( const string & _deviceName ) : - deviceName( _deviceName ) -{ - flashSize = - eepromSize = 0; - hasFuseBits = false; - hasExtendedFuseBits = false; - signature0 = - signature1 = - signature2 = 0; - pagesize = -1; -} - - -/* Destructor */ -AVRDevice::~AVRDevice() -{ - /* no code here */ -} - -/* Read parameters from AVR Studio XML files */ -void AVRDevice::readParametersFromAVRStudio( vector & searchpath ) -{ - string path; - string signature; - string cache; - -#ifndef NOREGISTRY - /* Locate the directory containing the XML files from the Windows registry database */ - try - { - path = Util.getRegistryValue( "SOFTWARE\\Atmel\\AVRTools\\", "AVRToolsPath" ); - path += "\\PartDescriptionFiles"; - searchpath.push_back( path ); - } catch( ErrorMsg * e ) - { - delete e; - } -#endif - - /* Search for file */ - path.erase(); - int i; - for( i = 0; i < searchpath.size(); i++ ) - { - path = searchpath[i] + "\\" + deviceName + ".xml"; - if( Util.fileExists( path ) ) - break; - } - - if( i == searchpath.size() ) - throw new ErrorMsg( "Device XML file not found in search path!" ); - - /* Parse the file for required info */ - Util.log( "Parsing '" + path + "'...\r\n" ); - XMLFile f( path ); // Load XML info - - flashSize = atoi( f.getValue( "AVRPART\\MEMORY\\PROG_FLASH" ).c_str() ); - eepromSize = atoi( f.getValue( "AVRPART\\MEMORY\\EEPROM" ).c_str() ); - - cache += ""; - cache += f.getValue( "AVRPART\\MEMORY\\PROG_FLASH" ); - cache += ""; - cache += f.getValue( "AVRPART\\MEMORY\\EEPROM" ); - cache += ""; - - if( f.exists( "AVRPART\\MEMORY\\BOOT_CONFIG" ) ) - { - pagesize = atoi( f.getValue( "AVRPART\\MEMORY\\BOOT_CONFIG\\PAGESIZE" ).c_str() ); - pagesize <<= 1; // We want pagesize in bytes. - - cache += ""; - cache += f.getValue( "AVRPART\\MEMORY\\BOOT_CONFIG\\PAGESIZE" ); - cache += ""; - } - - cache += ""; - - if( f.exists( "AVRPART\\FUSE" ) ) - { - hasFuseBits = true; - - cache += ""; - - if( f.exists( "AVRPART\\FUSE\\EXTENDED" ) ) - { - hasExtendedFuseBits = true; - cache += ""; - } - - cache += ""; - } - - signature = f.getValue( "AVRPART\\ADMIN\\SIGNATURE\\ADDR000" ); - signature.erase( 0, 1 ); // Remove the $ character. - signature0 = Util.convertHex( signature ); - - signature = f.getValue( "AVRPART\\ADMIN\\SIGNATURE\\ADDR001" ); - signature.erase( 0, 1 ); // Remove the $ character. - signature1 = Util.convertHex( signature ); - - signature = f.getValue( "AVRPART\\ADMIN\\SIGNATURE\\ADDR002" ); - signature.erase( 0, 1 ); // Remove the $ character. - signature2 = Util.convertHex( signature ); - - cache += ""; - cache += f.getValue( "AVRPART\\ADMIN\\SIGNATURE\\ADDR000" ); - cache += ""; - cache += f.getValue( "AVRPART\\ADMIN\\SIGNATURE\\ADDR001" ); - cache += ""; - cache += f.getValue( "AVRPART\\ADMIN\\SIGNATURE\\ADDR002" ); - cache += "\r\n"; - - /* Save cached file to application directory */ - Util.log( "Saving cached XML parameters...\r\n" ); - Util.saveString( cache, searchpath[1] + "\\" + deviceName + ".xml" ); -} - - -void AVRDevice::getSignature( long * sig0, long * sig1, long * sig2 ) -{ - if( sig0 == NULL || sig1 == NULL || sig2 == NULL ) - throw new ErrorMsg( "Cannot copy signature bytes to NULL-pointers!" ); - - *sig0 = signature0; - *sig1 = signature1; - *sig2 = signature2; -} - - -/* end of file */ +/***************************************************************************** + * + * Atmel Corporation + * + * File : AVRDevice.cpp + * Compiler : Dev-C++ 4.9.8.0 - http://bloodshed.net/dev/ + * Revision : $Revision: 4017 $ + * Date : $Date: 2008-06-02 14:26:03 +0200 (ma, 02 jun 2008) $ + * Updated by : $Author: khole $ + * + * Support mail : avr@atmel.com + * + * Target platform : Win32 + * + * AppNote : AVR911 - AVR Open-source Programmer + * + * Description : A class containing information of device memory sizes etc. + * It also provides funcitons for reading these parameters from + * the PartDescriptionFiles supplied with AVR Studio 4. + * + * + ****************************************************************************/ +#include "AVRDevice.hpp" + + +/* Constructor */ +AVRDevice::AVRDevice( const string & _deviceName ) : + deviceName( _deviceName ) +{ + flashSize = + eepromSize = 0; + hasFuseBits = false; + hasExtendedFuseBits = false; + signature0 = + signature1 = + signature2 = 0; + pagesize = -1; +} + + +/* Destructor */ +AVRDevice::~AVRDevice() +{ + /* no code here */ +} + +/* Read parameters from AVR Studio XML files */ +void AVRDevice::readParametersFromAVRStudio( vector & searchpath ) +{ + string path; + string signature; + string cache; + +#ifndef NOREGISTRY + /* Locate the directory containing the XML files from the Windows registry database */ + try + { + path = Util.getRegistryValue( "SOFTWARE\\Atmel\\AVRTools\\", "AVRToolsPath" ); + path += "\\PartDescriptionFiles"; + searchpath.push_back( path ); + } catch( ErrorMsg * e ) + { + delete e; + } +#endif + + /* Search for file */ + path.erase(); + int i; + for( i = 0; i < searchpath.size(); i++ ) + { + path = searchpath[i] + "\\" + deviceName + ".xml"; + if( Util.fileExists( path ) ) + break; + } + + if( i == searchpath.size() ) + throw new ErrorMsg( "Device XML file not found in search path!" ); + + /* Parse the file for required info */ + Util.log( "Parsing '" + path + "'...\r\n" ); + XMLFile f( path ); // Load XML info + + flashSize = atoi( f.getValue( "AVRPART\\MEMORY\\PROG_FLASH" ).c_str() ); + eepromSize = atoi( f.getValue( "AVRPART\\MEMORY\\EEPROM" ).c_str() ); + + cache += ""; + cache += f.getValue( "AVRPART\\MEMORY\\PROG_FLASH" ); + cache += ""; + cache += f.getValue( "AVRPART\\MEMORY\\EEPROM" ); + cache += ""; + + if( f.exists( "AVRPART\\MEMORY\\BOOT_CONFIG" ) ) + { + pagesize = atoi( f.getValue( "AVRPART\\MEMORY\\BOOT_CONFIG\\PAGESIZE" ).c_str() ); + pagesize <<= 1; // We want pagesize in bytes. + + cache += ""; + cache += f.getValue( "AVRPART\\MEMORY\\BOOT_CONFIG\\PAGESIZE" ); + cache += ""; + } + + cache += ""; + + if( f.exists( "AVRPART\\FUSE" ) ) + { + hasFuseBits = true; + + cache += ""; + + if( f.exists( "AVRPART\\FUSE\\EXTENDED" ) ) + { + hasExtendedFuseBits = true; + cache += ""; + } + + cache += ""; + } + + signature = f.getValue( "AVRPART\\ADMIN\\SIGNATURE\\ADDR000" ); + signature.erase( 0, 1 ); // Remove the $ character. + signature0 = Util.convertHex( signature ); + + signature = f.getValue( "AVRPART\\ADMIN\\SIGNATURE\\ADDR001" ); + signature.erase( 0, 1 ); // Remove the $ character. + signature1 = Util.convertHex( signature ); + + signature = f.getValue( "AVRPART\\ADMIN\\SIGNATURE\\ADDR002" ); + signature.erase( 0, 1 ); // Remove the $ character. + signature2 = Util.convertHex( signature ); + + cache += ""; + cache += f.getValue( "AVRPART\\ADMIN\\SIGNATURE\\ADDR000" ); + cache += ""; + cache += f.getValue( "AVRPART\\ADMIN\\SIGNATURE\\ADDR001" ); + cache += ""; + cache += f.getValue( "AVRPART\\ADMIN\\SIGNATURE\\ADDR002" ); + cache += "\r\n"; + + /* Save cached file to application directory */ + Util.log( "Saving cached XML parameters...\r\n" ); + Util.saveString( cache, searchpath[1] + "\\" + deviceName + ".xml" ); +} + + +void AVRDevice::getSignature( long * sig0, long * sig1, long * sig2 ) +{ + if( sig0 == NULL || sig1 == NULL || sig2 == NULL ) + throw new ErrorMsg( "Cannot copy signature bytes to NULL-pointers!" ); + + *sig0 = signature0; + *sig1 = signature1; + *sig2 = signature2; +} + + +/* end of file */ diff --git a/ports/bdk-atxx4-mstp/avrosp/AVRDevice.hpp b/ports/bdk-atxx4-mstp/avrosp/AVRDevice.hpp index 7d5a8390..835d5bab 100644 --- a/ports/bdk-atxx4-mstp/avrosp/AVRDevice.hpp +++ b/ports/bdk-atxx4-mstp/avrosp/AVRDevice.hpp @@ -1,69 +1,69 @@ -/***************************************************************************** - * - * Atmel Corporation - * - * File : AVRDevice.hpp - * Compiler : Dev-C++ 4.9.8.0 - http://bloodshed.net/dev/ - * Revision : $Revision: 1163 $ - * Date : $Date: 2006-08-02 15:38:16 +0200 (on, 02 aug 2006) $ - * Updated by : $Author: ohlia $ - * - * Support mail : avr@atmel.com - * - * Target platform : Win32 - * - * AppNote : AVR911 - AVR Open-source Programmer - * - * Description : A class containing information of device memory sizes etc. - * It also provides funcitons for reading these parameters from - * the PartDescriptionFiles supplied with AVR Studio 4. - * - * - ****************************************************************************/ -#ifndef AVRDEVICE_HPP -#define AVRDEVICE_HPP - -using namespace std; - - -#include -#include -#include "Utility.hpp" -#include "XMLParser.hpp" -#include "ErrorMsg.hpp" - -class AVRDevice -{ - protected: - string deviceName; // The name of the device, eg. ATmega128. - - long flashSize; // Size of Flash memory in bytes. - long eepromSize; // Size of EEPROM memory in bytes. - bool hasFuseBits; // Does this device have fuse bits at all? - bool hasExtendedFuseBits; // Does this device have extended fuses? - long signature0; - long signature1; - long signature2; // The three signature bytes, read from XML PartDescriptionFiles. - long pagesize; // Flash page size. - - public: - /* Constructor */ - AVRDevice( const string & _deviceName ); - - /* Destructor */ - ~AVRDevice(); - - /* Methods */ - void readParametersFromAVRStudio( vector & searchpath ); - - long getFlashSize() { return flashSize; } - long getEEPROMSize() { return eepromSize; } - long getPageSize() { return pagesize; } - bool getFuseStatus() { return hasFuseBits; } - bool getXFuseStatus() { return hasExtendedFuseBits; } - - void getSignature( long * sig0, long * sig1, long * sig2 ); -}; - -#endif - +/***************************************************************************** + * + * Atmel Corporation + * + * File : AVRDevice.hpp + * Compiler : Dev-C++ 4.9.8.0 - http://bloodshed.net/dev/ + * Revision : $Revision: 1163 $ + * Date : $Date: 2006-08-02 15:38:16 +0200 (on, 02 aug 2006) $ + * Updated by : $Author: ohlia $ + * + * Support mail : avr@atmel.com + * + * Target platform : Win32 + * + * AppNote : AVR911 - AVR Open-source Programmer + * + * Description : A class containing information of device memory sizes etc. + * It also provides funcitons for reading these parameters from + * the PartDescriptionFiles supplied with AVR Studio 4. + * + * + ****************************************************************************/ +#ifndef AVRDEVICE_HPP +#define AVRDEVICE_HPP + +using namespace std; + + +#include +#include +#include "Utility.hpp" +#include "XMLParser.hpp" +#include "ErrorMsg.hpp" + +class AVRDevice +{ + protected: + string deviceName; // The name of the device, eg. ATmega128. + + long flashSize; // Size of Flash memory in bytes. + long eepromSize; // Size of EEPROM memory in bytes. + bool hasFuseBits; // Does this device have fuse bits at all? + bool hasExtendedFuseBits; // Does this device have extended fuses? + long signature0; + long signature1; + long signature2; // The three signature bytes, read from XML PartDescriptionFiles. + long pagesize; // Flash page size. + + public: + /* Constructor */ + AVRDevice( const string & _deviceName ); + + /* Destructor */ + ~AVRDevice(); + + /* Methods */ + void readParametersFromAVRStudio( vector & searchpath ); + + long getFlashSize() { return flashSize; } + long getEEPROMSize() { return eepromSize; } + long getPageSize() { return pagesize; } + bool getFuseStatus() { return hasFuseBits; } + bool getXFuseStatus() { return hasExtendedFuseBits; } + + void getSignature( long * sig0, long * sig1, long * sig2 ); +}; + +#endif + diff --git a/ports/bdk-atxx4-mstp/avrosp/AVRInSystemProg.cpp b/ports/bdk-atxx4-mstp/avrosp/AVRInSystemProg.cpp index 3104cbb0..18d012bf 100644 --- a/ports/bdk-atxx4-mstp/avrosp/AVRInSystemProg.cpp +++ b/ports/bdk-atxx4-mstp/avrosp/AVRInSystemProg.cpp @@ -1,714 +1,714 @@ -/***************************************************************************** - * - * Atmel Corporation - * - * File : AVRInSystemProg.cpp - * Compiler : Dev-C++ 4.9.8.0 - http://bloodshed.net/dev/ - * Revision : $Revision: 1163 $ - * Date : $Date: 2006-08-02 15:38:16 +0200 (on, 02 aug 2006) $ - * Updated by : $Author: ohlia $ - * - * Support mail : avr@atmel.com - * - * Target platform : Win32 - * - * AppNote : AVR911 - AVR Open-source Programmer - * - * Description : A class providing an interface to the AVR ISP described - * in Application Note AVR910. This class is derived from AVRPRogrammer. - * - * - ****************************************************************************/ -#include "AVRInSystemProg.hpp" - -#include -#include - -#define MEM_PROGRESS_GRANULARITY 256 // For use with progress indicator. - - -/* Constructor */ -AVRInSystemProg::AVRInSystemProg( CommChannel * _comm ) : - AVRProgrammer::AVRProgrammer( _comm ) -{ - /* No code here */ -} - - -/* Destructor */ -AVRInSystemProg::~AVRInSystemProg() -{ - /* No code here */ -} - - -bool AVRInSystemProg::enterProgrammingMode() -{ - /* Must select a device from the AVRISP device code table first */ - comm->sendByte( 'T' ); - comm->sendByte( 0x64 ); // Select ATmega163, any device in the table will do. - comm->flushTX(); - - /* Should return CR */ - if( comm->getByte() != '\r' ) - throw new ErrorMsg( "Entering programming mode failed! " - "Programmer did not return CR after 'T'-command." ); - - /* Send command 'P' */ - comm->sendByte( 'P' ); - comm->flushTX(); - - /* Should return CR */ - if( comm->getByte() != '\r' ) - throw new ErrorMsg( "Entering programming mode failed! " - "Programmer did not return CR after 'P'-command." ); - - return true; // Indicate supported command. -} - - -bool AVRInSystemProg::leaveProgrammingMode() -{ - /* Send command 'L' */ - comm->sendByte( 'L' ); - comm->flushTX(); - - /* Should return CR */ - if( comm->getByte() != '\r' ) - throw new ErrorMsg( "Leaving programming mode failed! " - "Programmer did not return CR after 'L'-command." ); - - return true; // Indicate supported command. -} - - -bool AVRInSystemProg::chipErase() -{ - /* Send command 'e' */ - comm->sendByte( 'e' ); - comm->flushTX(); - - if( comm->getByte() != '\r' ) - throw new ErrorMsg( "Chip erase failed! " - "Programmer did not return CR after 'e'-command." ); - - return true; // Indicate supported command. -} - - -bool AVRInSystemProg::readOSCCAL( long pos, long * value ) -{ - /* Use AVRISP's 4-byte universal command */ - comm->sendByte( '.' ); - comm->sendByte( 0x38 ); - comm->sendByte( 0x00 ); - comm->sendByte( pos ); - comm->sendByte( 0x00 ); // Dummy. - comm->flushTX(); - - *value = comm->getByte(); - - if( comm->getByte() != '\r' ) // Check return code from command. - throw new ErrorMsg( "OSCCAL value readout failed! " - "Programmer did not return CR after '.'-command." ); - - return true; // Indicate supported command. -} - - -bool AVRInSystemProg::readSignature( long * sig0, long * sig1, long * sig2 ) -{ - /* Send command 's' */ - comm->sendByte( 's' ); - comm->flushTX(); - - /* Get actual signature */ - *sig2 = comm->getByte(); - *sig1 = comm->getByte(); - *sig0 = comm->getByte(); -} - - -bool AVRInSystemProg::checkSignature( long sig0, long sig1, long sig2 ) -{ - long sig[3]; - - /* Get signature */ - readSignature( sig, sig+1, sig+2 ); - - /* Compare signature */ - if( sig[0] != sig0 || sig[1] != sig1 || sig[2] != sig2 ) - { - ostringstream msg; - msg << "Signature does not match selected device! "; - msg << "Actual signature: (" << hex - << "0x" << setw(2) << sig[0] << " " - << "0x" << setw(2) << sig[1] << " " - << "0x" << setw(2) << sig[2] << ") " - << "Signature from XML-file: (" << hex - << "0x" << setw(2) << sig0 << " " - << "0x" << setw(2) << sig1 << " " - << "0x" << setw(2) << sig2 << ")."; - - throw new ErrorMsg( msg.str() ); - } - - return true; // Indicate supported command. -} - - -bool AVRInSystemProg::writeFlashByte( long address, long value ) -{ - if( address >= 0x20000 ) - throw new ErrorMsg( "Flash addresses above 128k are currently not supported!" ); - - setAddress( address >> 1 ); // Flash operations use word addresses. - - /* Move data if at odd address */ - if( address & 0x01 ) // Odd address? - value = (value << 8) | 0x00ff; // Move to high byte of one flash word. - else - value |= 0xff00; // Ensure no-write for high byte. - - /* Send low and high byte */ - writeFlashLowByte( value & 0xff ); - writeFlashHighByte( value >> 8 ); - - /* Issue page write if required */ - if( pagesize != -1 ) - { - setAddress( address >> 1 ); // The address could be autoincremented. - writeFlashPage(); - } - - return true; // Indicate supported command. -} - - -bool AVRInSystemProg::writeEEPROMByte( long address, long value ) -{ - if( address >= 0x10000 ) - throw new ErrorMsg( "EEPROM addresses above 64k are currently not supported!" ); - - setAddress( address ); - - /* Send data */ - comm->sendByte( 'D' ); - comm->sendByte( value ); - comm->flushTX(); - - /* Should return CR */ - if( comm->getByte() != '\r' ) - throw new ErrorMsg( "Writing byte to EEPROM failed! " - "Programmer did not return CR after 'D'-command." ); - - return true; // Indicate supported command. -} - - -bool AVRInSystemProg::writeFlash( HEXFile * data ) -{ - long start, end; // Data address range. - bool autoincrement; // Bootloader supports address autoincrement? - long address; - - /* Check that pagesize is set */ - if( pagesize == -1 ) - throw new ErrorMsg( "Programmer pagesize is not set!" ); - - /* Get range from HEX file */ - start = data->getRangeStart(); - end = data->getRangeEnd(); - - /* Check autoincrement support */ - comm->sendByte( 'a' ); - comm->flushTX(); - - if( comm->getByte() == 'Y' ) - autoincrement = true; - else - autoincrement = false; - - /* Set initial address */ - setAddress( start >> 1 ); // Flash operations use word addresses. - - /* Need to write one odd byte first? */ - address = start; - if( address & 1 ) - { - /* Use only high byte */ - writeFlashLowByte( 0xff ); // No-write in low byte. - writeFlashHighByte( data->getData( address ) ); - - address++; - - /* Need to write page? */ - if( pagesize != -1 ) - { - if( !(address % pagesize) ) // Just passed page limit? - { - setAddress( (address-1) >> 1 ); // Set to an address inside the page. - writeFlashPage(); - setAddress( address >> 1 ); - } - } - } - - /* Write words */ - do - { - /* Need to set address again? */ - if( !autoincrement ) - setAddress( address >> 1 ); - - /* Write words */ - writeFlashLowByte( data->getData( address ) ); - writeFlashHighByte( data->getData( address+1 ) ); - - address += 2; - - if( (address % MEM_PROGRESS_GRANULARITY) == 0 ) - Util.progress( "#" ); // Advance progress indicator. - - /* Need to write page? */ - if( pagesize != -1 ) - { - if( (address % pagesize) == 0 ) // Just passed a page boundary? - { - setAddress( (address-2) >> 1 ); // Set to an address inside the page. - writeFlashPage(); - setAddress( address >> 1 ); - } - } - } while( address < end ); - - /* Need to write one even byte before finished? */ - if( address == end ) - { - /* Use only low byte */ - writeFlashLowByte( data->getData( address ) ); - writeFlashHighByte( 0xff ); // No-write in high byte. - } - - /* Need to write page? */ - if( pagesize != -1 ) - { - if( address == end || // One extra byte written... - (end+1)%pagesize != 0 ) // ...or end is not on page boundary. - { - setAddress( (address-2) >> 1 ); // Set to an address inside the page. - writeFlashPage(); - } - } - - Util.progress( "\r\n" ); // Finish progress indicator. - return true; // Indicate supported command. -} - - -bool AVRInSystemProg::readFlash( HEXFile * data ) -{ - long start, end; // Data address range. - bool autoincrement; // Bootloader supports address autoincrement? - long address; - - if( pagesize == -1 ) - throw new ErrorMsg( "Programmer pagesize is not set!" ); - - /* Get range from HEX file */ - start = data->getRangeStart(); - end = data->getRangeEnd(); - - /* Check autoincrement support */ - comm->sendByte( 'a' ); - comm->flushTX(); - - if( comm->getByte() == 'Y' ) - autoincrement = true; - else - autoincrement = false; - - /* Set initial address */ - setAddress( start >> 1 ); // Flash operations use word addresses. - - /* Need to read one odd byte first? */ - address = start; - if( address & 1 ) - { - /* Read both, but use only high byte */ - comm->sendByte( 'R' ); - comm->flushTX(); - - data->setData( address, comm->getByte() ); // High byte. - comm->getByte(); // Dont use low byte. - - address++; - } - - /* Get words */ - do - { - /* Need to set address again? */ - if( !autoincrement ) - setAddress( address >> 1 ); - - /* Get words */ - comm->sendByte( 'R' ); - comm->flushTX(); - - data->setData( address+1, comm->getByte() ); // High byte. - data->setData( address, comm->getByte() ); // Low byte. - - address += 2; - - if( (address % MEM_PROGRESS_GRANULARITY) == 0 ) - Util.progress( "#" ); // Advance progress indicator. - - } while( address < end ); - - /* Need to read one even byte before finished? */ - if( address == end ) - { - /* Read both, but use only low byte */ - comm->sendByte( 'R' ); - comm->flushTX(); - - comm->getByte(); // Dont use high byte. - data->setData( address-1, comm->getByte() ); // Low byte. - } - - Util.progress( "\r\n" ); // Finish progress indicator. - return true; // Indicate supported command. -} - - -bool AVRInSystemProg::writeEEPROM( HEXFile * data ) -{ - long start, end; // Data address range. - bool autoincrement; // Bootloader supports address autoincrement? - long address; - - /* Get range from HEX file */ - start = data->getRangeStart(); - end = data->getRangeEnd(); - - /* Check autoincrement support */ - comm->sendByte( 'a' ); - comm->flushTX(); - - if( comm->getByte() == 'Y' ) - autoincrement = true; - else - autoincrement = false; - - /* Set initial address */ - setAddress( start ); - - /* Send data */ - address = start; - do - { - /* Need to set address again? */ - if( !autoincrement ) - setAddress( address ); - - /* Send byte */ - comm->sendByte( 'D' ); - comm->sendByte( data->getData( address ) ); - comm->flushTX(); - - if( comm->getByte() != '\r' ) - throw new ErrorMsg( "Writing byte to EEPROM failed! " - "Programmer did not return CR after 'D'-command." ); - - if( (address % MEM_PROGRESS_GRANULARITY) == 0 ) - Util.progress( "#" ); // Advance progress indicator. - - address++; - } while( address <= end ); - - Util.progress( "\r\n" ); // Finish progress indicator. - return true; // Indicate supported command. -} - - -bool AVRInSystemProg::readEEPROM( HEXFile * data ) -{ - long start, end; // Data address range. - bool autoincrement; // Bootloader supports address autoincrement? - long address; - - /* Get range from HEX file */ - start = data->getRangeStart(); - end = data->getRangeEnd(); - - /* Check autoincrement support */ - comm->sendByte( 'a' ); - comm->flushTX(); - - if( comm->getByte() == 'Y' ) - autoincrement = true; - else - autoincrement = false; - - /* Set initial address */ - setAddress( start ); - - /* Send data */ - address = start; - do - { - /* Need to set address again? */ - if( !autoincrement ) - setAddress( address ); - - /* Get byte */ - comm->sendByte( 'd' ); - comm->flushTX(); - - data->setData( address, comm->getByte() ); - - if( (address % MEM_PROGRESS_GRANULARITY) == 0 ) - Util.progress( "#" ); // Advance progress indicator. - - address++; - } while( address <= end ); - - Util.progress( "\r\n" ); // Finish progress indicator. - return true; // Indicate supported command. -} - - -bool AVRInSystemProg::writeLockBits( long bits ) -{ - /* Use AVRISP's 4-byte universal command */ - comm->sendByte( '.' ); - comm->sendByte( 0xac ); - comm->sendByte( 0xe0 ); - comm->sendByte( 0x00 ); // Dummy. - comm->sendByte( bits ); - - comm->flushTX(); - comm->getByte(); // Ignore return code from SPI communication. - - if( comm->getByte() != '\r' ) // Check return code from command. - throw new ErrorMsg( "Writing lock bits failed! " - "Programmer did not return CR after '.'-command." ); - - return true; // Indicate supported command. -} - - -bool AVRInSystemProg::readLockBits( long * bits ) -{ - /* Use AVRISP's 4-byte universal command */ - comm->sendByte( '.' ); - comm->sendByte( 0x58 ); - comm->sendByte( 0x00 ); - comm->sendByte( 0x00 ); // Dummy. - comm->sendByte( 0x00 ); // Dummy. - comm->flushTX(); - - *bits = comm->getByte(); - - if( comm->getByte() != '\r' ) // Check return code from command. - throw new ErrorMsg( "Lock byte readout failed! " - "Programmer did not return CR after '.'-command." ); - - return true; // Indicate supported command. -} - - -bool AVRInSystemProg::writeFuseBits( long bits ) -{ - /* Use AVRISP's 4-byte universal command */ - comm->sendByte( '.' ); - comm->sendByte( 0xac ); - comm->sendByte( 0xa0 ); - comm->sendByte( 0x00 ); // Dummy. - comm->sendByte( bits & 0xff ); - comm->flushTX(); - - comm->getByte(); // Ignore return code from SPI communication. - - if( comm->getByte() != '\r' ) // Check return code from command. - throw new ErrorMsg( "Low fuse byte programming failed! " - "Programmer did not return CR after '.'-command." ); - - /* Use AVRISP's 4-byte universal command */ - comm->sendByte( '.' ); - comm->sendByte( 0xac ); - comm->sendByte( 0xa8 ); - comm->sendByte( 0x00 ); // Dummy. - comm->sendByte( bits >> 8 ); - comm->flushTX(); - - comm->getByte(); // Ignore return code from SPI communication. - - if( comm->getByte() != '\r' ) // Check return code from command. - throw new ErrorMsg( "High fuse byte programming failed! " - "Programmer did not return CR after '.'-command." ); - - return true; // Indicate supported command. -} - - -bool AVRInSystemProg::readFuseBits( long * bits ) -{ - long low, high; - - /* Use AVRISP's 4-byte universal command */ - comm->sendByte( '.' ); - comm->sendByte( 0x50 ); - comm->sendByte( 0x00 ); - comm->sendByte( 0x00 ); // Dummy. - comm->sendByte( 0x00 ); // Dummy. - comm->flushTX(); - - low = comm->getByte(); - - if( comm->getByte() != '\r' ) // Check return code from command. - throw new ErrorMsg( "Low fuse byte readout failed! " - "Programmer did not return CR after '.'-command." ); - - /* Use AVRISP's 4-byte universal command */ - comm->sendByte( '.' ); - comm->sendByte( 0x58 ); - comm->sendByte( 0x08 ); - comm->sendByte( 0x00 ); // Dummy. - comm->sendByte( 0x00 ); // Dummy. - comm->flushTX(); - - high = comm->getByte(); - - if( comm->getByte() != '\r' ) // Check return code from command. - throw new ErrorMsg( "Low fuse byte readout failed! " - "Programmer did not return CR adter '.'-command." ); - - /* Put low and high together */ - *bits = (high << 8) | low; - - return true; // Indicate supported command. -} - - -bool AVRInSystemProg::writeExtendedFuseBits( long bits ) -{ - /* Use AVRISP's 4-byte universal command */ - comm->sendByte( '.' ); - comm->sendByte( 0xac ); - comm->sendByte( 0xa4 ); - comm->sendByte( 0x00 ); // Dummy. - comm->sendByte( bits ); - comm->flushTX(); - - comm->getByte(); // Ignore return code from SPI communication. - - if( comm->getByte() != '\r' ) // Check return code from command. - throw new ErrorMsg( "Extended fuse byte programming failed! " - "Programmer did not return CR after '.'-command." ); - - return true; // Indicate supported command. -} - - -bool AVRInSystemProg::readExtendedFuseBits( long * bits ) -{ - /* Use AVRISP's 4-byte universal command */ - comm->sendByte( '.' ); - comm->sendByte( 0x50 ); - comm->sendByte( 0x08 ); - comm->sendByte( 0x00 ); // Dummy. - comm->sendByte( 0x00 ); // Dummy. - comm->flushTX(); - - *bits = comm->getByte(); - - if( comm->getByte() != '\r' ) // Check return code from command. - throw new ErrorMsg( "Extended fuse byte readout failed! " - "Programmer did not return CR after '.'-command." ); - - return true; // Indicate supported command. -} - - -bool AVRInSystemProg::programmerSoftwareVersion( long * major, long * minor ) -{ - /* Send command 'V' to get software version */ - comm->sendByte( 'V' ); - comm->flushTX(); - - /* Get data */ - *major = comm->getByte(); - *minor = comm->getByte(); - - return true; // Indicate supported command. -} - - -bool AVRInSystemProg::programmerHardwareVersion( long * major, long * minor ) -{ - /* Send command 'v' to get hardware version */ - comm->sendByte( 'v' ); - comm->flushTX(); - - /* Get data */ - *major = comm->getByte(); - *minor = comm->getByte(); - - return true; // Indicate supported command. -} - - -void AVRInSystemProg::setAddress( long address ) -{ - /* Set current address */ - comm->sendByte( 'A' ); - comm->sendByte( address >> 8 ); // High byte of address. - comm->sendByte( address & 0xff ); // Low byte. - comm->flushTX(); - - /* Should return CR */ - if( comm->getByte() != '\r' ) - throw new ErrorMsg( "Setting address for programming operations failed! " - "Programmer did not return CR after 'A'-command." ); -} - - -void AVRInSystemProg::writeFlashLowByte( long value ) -{ - comm->sendByte( 'c' ); - comm->sendByte( value ); - comm->flushTX(); - - if( comm->getByte() != '\r' ) - throw new ErrorMsg( "Writing Flash low byte failed! " - "Programmer did not return CR after 'c'-command." ); -} - - -void AVRInSystemProg::writeFlashHighByte( long value ) -{ - comm->sendByte( 'C' ); - comm->sendByte( value ); - comm->flushTX(); - - if( comm->getByte() != '\r' ) - throw new ErrorMsg( "Writing Flash high byte failed! " - "Programmer did not return CR after 'C'-command." ); -} - - -void AVRInSystemProg::writeFlashPage() -{ - comm->sendByte( 'm' ); - comm->flushTX(); - - if( comm->getByte() != '\r' ) - throw new ErrorMsg( "Writing Flash page failed! " - "Programmer did not return CR after 'm'-command." ); -} - - -/* end of file */ - +/***************************************************************************** + * + * Atmel Corporation + * + * File : AVRInSystemProg.cpp + * Compiler : Dev-C++ 4.9.8.0 - http://bloodshed.net/dev/ + * Revision : $Revision: 1163 $ + * Date : $Date: 2006-08-02 15:38:16 +0200 (on, 02 aug 2006) $ + * Updated by : $Author: ohlia $ + * + * Support mail : avr@atmel.com + * + * Target platform : Win32 + * + * AppNote : AVR911 - AVR Open-source Programmer + * + * Description : A class providing an interface to the AVR ISP described + * in Application Note AVR910. This class is derived from AVRPRogrammer. + * + * + ****************************************************************************/ +#include "AVRInSystemProg.hpp" + +#include +#include + +#define MEM_PROGRESS_GRANULARITY 256 // For use with progress indicator. + + +/* Constructor */ +AVRInSystemProg::AVRInSystemProg( CommChannel * _comm ) : + AVRProgrammer::AVRProgrammer( _comm ) +{ + /* No code here */ +} + + +/* Destructor */ +AVRInSystemProg::~AVRInSystemProg() +{ + /* No code here */ +} + + +bool AVRInSystemProg::enterProgrammingMode() +{ + /* Must select a device from the AVRISP device code table first */ + comm->sendByte( 'T' ); + comm->sendByte( 0x64 ); // Select ATmega163, any device in the table will do. + comm->flushTX(); + + /* Should return CR */ + if( comm->getByte() != '\r' ) + throw new ErrorMsg( "Entering programming mode failed! " + "Programmer did not return CR after 'T'-command." ); + + /* Send command 'P' */ + comm->sendByte( 'P' ); + comm->flushTX(); + + /* Should return CR */ + if( comm->getByte() != '\r' ) + throw new ErrorMsg( "Entering programming mode failed! " + "Programmer did not return CR after 'P'-command." ); + + return true; // Indicate supported command. +} + + +bool AVRInSystemProg::leaveProgrammingMode() +{ + /* Send command 'L' */ + comm->sendByte( 'L' ); + comm->flushTX(); + + /* Should return CR */ + if( comm->getByte() != '\r' ) + throw new ErrorMsg( "Leaving programming mode failed! " + "Programmer did not return CR after 'L'-command." ); + + return true; // Indicate supported command. +} + + +bool AVRInSystemProg::chipErase() +{ + /* Send command 'e' */ + comm->sendByte( 'e' ); + comm->flushTX(); + + if( comm->getByte() != '\r' ) + throw new ErrorMsg( "Chip erase failed! " + "Programmer did not return CR after 'e'-command." ); + + return true; // Indicate supported command. +} + + +bool AVRInSystemProg::readOSCCAL( long pos, long * value ) +{ + /* Use AVRISP's 4-byte universal command */ + comm->sendByte( '.' ); + comm->sendByte( 0x38 ); + comm->sendByte( 0x00 ); + comm->sendByte( pos ); + comm->sendByte( 0x00 ); // Dummy. + comm->flushTX(); + + *value = comm->getByte(); + + if( comm->getByte() != '\r' ) // Check return code from command. + throw new ErrorMsg( "OSCCAL value readout failed! " + "Programmer did not return CR after '.'-command." ); + + return true; // Indicate supported command. +} + + +bool AVRInSystemProg::readSignature( long * sig0, long * sig1, long * sig2 ) +{ + /* Send command 's' */ + comm->sendByte( 's' ); + comm->flushTX(); + + /* Get actual signature */ + *sig2 = comm->getByte(); + *sig1 = comm->getByte(); + *sig0 = comm->getByte(); +} + + +bool AVRInSystemProg::checkSignature( long sig0, long sig1, long sig2 ) +{ + long sig[3]; + + /* Get signature */ + readSignature( sig, sig+1, sig+2 ); + + /* Compare signature */ + if( sig[0] != sig0 || sig[1] != sig1 || sig[2] != sig2 ) + { + ostringstream msg; + msg << "Signature does not match selected device! "; + msg << "Actual signature: (" << hex + << "0x" << setw(2) << sig[0] << " " + << "0x" << setw(2) << sig[1] << " " + << "0x" << setw(2) << sig[2] << ") " + << "Signature from XML-file: (" << hex + << "0x" << setw(2) << sig0 << " " + << "0x" << setw(2) << sig1 << " " + << "0x" << setw(2) << sig2 << ")."; + + throw new ErrorMsg( msg.str() ); + } + + return true; // Indicate supported command. +} + + +bool AVRInSystemProg::writeFlashByte( long address, long value ) +{ + if( address >= 0x20000 ) + throw new ErrorMsg( "Flash addresses above 128k are currently not supported!" ); + + setAddress( address >> 1 ); // Flash operations use word addresses. + + /* Move data if at odd address */ + if( address & 0x01 ) // Odd address? + value = (value << 8) | 0x00ff; // Move to high byte of one flash word. + else + value |= 0xff00; // Ensure no-write for high byte. + + /* Send low and high byte */ + writeFlashLowByte( value & 0xff ); + writeFlashHighByte( value >> 8 ); + + /* Issue page write if required */ + if( pagesize != -1 ) + { + setAddress( address >> 1 ); // The address could be autoincremented. + writeFlashPage(); + } + + return true; // Indicate supported command. +} + + +bool AVRInSystemProg::writeEEPROMByte( long address, long value ) +{ + if( address >= 0x10000 ) + throw new ErrorMsg( "EEPROM addresses above 64k are currently not supported!" ); + + setAddress( address ); + + /* Send data */ + comm->sendByte( 'D' ); + comm->sendByte( value ); + comm->flushTX(); + + /* Should return CR */ + if( comm->getByte() != '\r' ) + throw new ErrorMsg( "Writing byte to EEPROM failed! " + "Programmer did not return CR after 'D'-command." ); + + return true; // Indicate supported command. +} + + +bool AVRInSystemProg::writeFlash( HEXFile * data ) +{ + long start, end; // Data address range. + bool autoincrement; // Bootloader supports address autoincrement? + long address; + + /* Check that pagesize is set */ + if( pagesize == -1 ) + throw new ErrorMsg( "Programmer pagesize is not set!" ); + + /* Get range from HEX file */ + start = data->getRangeStart(); + end = data->getRangeEnd(); + + /* Check autoincrement support */ + comm->sendByte( 'a' ); + comm->flushTX(); + + if( comm->getByte() == 'Y' ) + autoincrement = true; + else + autoincrement = false; + + /* Set initial address */ + setAddress( start >> 1 ); // Flash operations use word addresses. + + /* Need to write one odd byte first? */ + address = start; + if( address & 1 ) + { + /* Use only high byte */ + writeFlashLowByte( 0xff ); // No-write in low byte. + writeFlashHighByte( data->getData( address ) ); + + address++; + + /* Need to write page? */ + if( pagesize != -1 ) + { + if( !(address % pagesize) ) // Just passed page limit? + { + setAddress( (address-1) >> 1 ); // Set to an address inside the page. + writeFlashPage(); + setAddress( address >> 1 ); + } + } + } + + /* Write words */ + do + { + /* Need to set address again? */ + if( !autoincrement ) + setAddress( address >> 1 ); + + /* Write words */ + writeFlashLowByte( data->getData( address ) ); + writeFlashHighByte( data->getData( address+1 ) ); + + address += 2; + + if( (address % MEM_PROGRESS_GRANULARITY) == 0 ) + Util.progress( "#" ); // Advance progress indicator. + + /* Need to write page? */ + if( pagesize != -1 ) + { + if( (address % pagesize) == 0 ) // Just passed a page boundary? + { + setAddress( (address-2) >> 1 ); // Set to an address inside the page. + writeFlashPage(); + setAddress( address >> 1 ); + } + } + } while( address < end ); + + /* Need to write one even byte before finished? */ + if( address == end ) + { + /* Use only low byte */ + writeFlashLowByte( data->getData( address ) ); + writeFlashHighByte( 0xff ); // No-write in high byte. + } + + /* Need to write page? */ + if( pagesize != -1 ) + { + if( address == end || // One extra byte written... + (end+1)%pagesize != 0 ) // ...or end is not on page boundary. + { + setAddress( (address-2) >> 1 ); // Set to an address inside the page. + writeFlashPage(); + } + } + + Util.progress( "\r\n" ); // Finish progress indicator. + return true; // Indicate supported command. +} + + +bool AVRInSystemProg::readFlash( HEXFile * data ) +{ + long start, end; // Data address range. + bool autoincrement; // Bootloader supports address autoincrement? + long address; + + if( pagesize == -1 ) + throw new ErrorMsg( "Programmer pagesize is not set!" ); + + /* Get range from HEX file */ + start = data->getRangeStart(); + end = data->getRangeEnd(); + + /* Check autoincrement support */ + comm->sendByte( 'a' ); + comm->flushTX(); + + if( comm->getByte() == 'Y' ) + autoincrement = true; + else + autoincrement = false; + + /* Set initial address */ + setAddress( start >> 1 ); // Flash operations use word addresses. + + /* Need to read one odd byte first? */ + address = start; + if( address & 1 ) + { + /* Read both, but use only high byte */ + comm->sendByte( 'R' ); + comm->flushTX(); + + data->setData( address, comm->getByte() ); // High byte. + comm->getByte(); // Dont use low byte. + + address++; + } + + /* Get words */ + do + { + /* Need to set address again? */ + if( !autoincrement ) + setAddress( address >> 1 ); + + /* Get words */ + comm->sendByte( 'R' ); + comm->flushTX(); + + data->setData( address+1, comm->getByte() ); // High byte. + data->setData( address, comm->getByte() ); // Low byte. + + address += 2; + + if( (address % MEM_PROGRESS_GRANULARITY) == 0 ) + Util.progress( "#" ); // Advance progress indicator. + + } while( address < end ); + + /* Need to read one even byte before finished? */ + if( address == end ) + { + /* Read both, but use only low byte */ + comm->sendByte( 'R' ); + comm->flushTX(); + + comm->getByte(); // Dont use high byte. + data->setData( address-1, comm->getByte() ); // Low byte. + } + + Util.progress( "\r\n" ); // Finish progress indicator. + return true; // Indicate supported command. +} + + +bool AVRInSystemProg::writeEEPROM( HEXFile * data ) +{ + long start, end; // Data address range. + bool autoincrement; // Bootloader supports address autoincrement? + long address; + + /* Get range from HEX file */ + start = data->getRangeStart(); + end = data->getRangeEnd(); + + /* Check autoincrement support */ + comm->sendByte( 'a' ); + comm->flushTX(); + + if( comm->getByte() == 'Y' ) + autoincrement = true; + else + autoincrement = false; + + /* Set initial address */ + setAddress( start ); + + /* Send data */ + address = start; + do + { + /* Need to set address again? */ + if( !autoincrement ) + setAddress( address ); + + /* Send byte */ + comm->sendByte( 'D' ); + comm->sendByte( data->getData( address ) ); + comm->flushTX(); + + if( comm->getByte() != '\r' ) + throw new ErrorMsg( "Writing byte to EEPROM failed! " + "Programmer did not return CR after 'D'-command." ); + + if( (address % MEM_PROGRESS_GRANULARITY) == 0 ) + Util.progress( "#" ); // Advance progress indicator. + + address++; + } while( address <= end ); + + Util.progress( "\r\n" ); // Finish progress indicator. + return true; // Indicate supported command. +} + + +bool AVRInSystemProg::readEEPROM( HEXFile * data ) +{ + long start, end; // Data address range. + bool autoincrement; // Bootloader supports address autoincrement? + long address; + + /* Get range from HEX file */ + start = data->getRangeStart(); + end = data->getRangeEnd(); + + /* Check autoincrement support */ + comm->sendByte( 'a' ); + comm->flushTX(); + + if( comm->getByte() == 'Y' ) + autoincrement = true; + else + autoincrement = false; + + /* Set initial address */ + setAddress( start ); + + /* Send data */ + address = start; + do + { + /* Need to set address again? */ + if( !autoincrement ) + setAddress( address ); + + /* Get byte */ + comm->sendByte( 'd' ); + comm->flushTX(); + + data->setData( address, comm->getByte() ); + + if( (address % MEM_PROGRESS_GRANULARITY) == 0 ) + Util.progress( "#" ); // Advance progress indicator. + + address++; + } while( address <= end ); + + Util.progress( "\r\n" ); // Finish progress indicator. + return true; // Indicate supported command. +} + + +bool AVRInSystemProg::writeLockBits( long bits ) +{ + /* Use AVRISP's 4-byte universal command */ + comm->sendByte( '.' ); + comm->sendByte( 0xac ); + comm->sendByte( 0xe0 ); + comm->sendByte( 0x00 ); // Dummy. + comm->sendByte( bits ); + + comm->flushTX(); + comm->getByte(); // Ignore return code from SPI communication. + + if( comm->getByte() != '\r' ) // Check return code from command. + throw new ErrorMsg( "Writing lock bits failed! " + "Programmer did not return CR after '.'-command." ); + + return true; // Indicate supported command. +} + + +bool AVRInSystemProg::readLockBits( long * bits ) +{ + /* Use AVRISP's 4-byte universal command */ + comm->sendByte( '.' ); + comm->sendByte( 0x58 ); + comm->sendByte( 0x00 ); + comm->sendByte( 0x00 ); // Dummy. + comm->sendByte( 0x00 ); // Dummy. + comm->flushTX(); + + *bits = comm->getByte(); + + if( comm->getByte() != '\r' ) // Check return code from command. + throw new ErrorMsg( "Lock byte readout failed! " + "Programmer did not return CR after '.'-command." ); + + return true; // Indicate supported command. +} + + +bool AVRInSystemProg::writeFuseBits( long bits ) +{ + /* Use AVRISP's 4-byte universal command */ + comm->sendByte( '.' ); + comm->sendByte( 0xac ); + comm->sendByte( 0xa0 ); + comm->sendByte( 0x00 ); // Dummy. + comm->sendByte( bits & 0xff ); + comm->flushTX(); + + comm->getByte(); // Ignore return code from SPI communication. + + if( comm->getByte() != '\r' ) // Check return code from command. + throw new ErrorMsg( "Low fuse byte programming failed! " + "Programmer did not return CR after '.'-command." ); + + /* Use AVRISP's 4-byte universal command */ + comm->sendByte( '.' ); + comm->sendByte( 0xac ); + comm->sendByte( 0xa8 ); + comm->sendByte( 0x00 ); // Dummy. + comm->sendByte( bits >> 8 ); + comm->flushTX(); + + comm->getByte(); // Ignore return code from SPI communication. + + if( comm->getByte() != '\r' ) // Check return code from command. + throw new ErrorMsg( "High fuse byte programming failed! " + "Programmer did not return CR after '.'-command." ); + + return true; // Indicate supported command. +} + + +bool AVRInSystemProg::readFuseBits( long * bits ) +{ + long low, high; + + /* Use AVRISP's 4-byte universal command */ + comm->sendByte( '.' ); + comm->sendByte( 0x50 ); + comm->sendByte( 0x00 ); + comm->sendByte( 0x00 ); // Dummy. + comm->sendByte( 0x00 ); // Dummy. + comm->flushTX(); + + low = comm->getByte(); + + if( comm->getByte() != '\r' ) // Check return code from command. + throw new ErrorMsg( "Low fuse byte readout failed! " + "Programmer did not return CR after '.'-command." ); + + /* Use AVRISP's 4-byte universal command */ + comm->sendByte( '.' ); + comm->sendByte( 0x58 ); + comm->sendByte( 0x08 ); + comm->sendByte( 0x00 ); // Dummy. + comm->sendByte( 0x00 ); // Dummy. + comm->flushTX(); + + high = comm->getByte(); + + if( comm->getByte() != '\r' ) // Check return code from command. + throw new ErrorMsg( "Low fuse byte readout failed! " + "Programmer did not return CR adter '.'-command." ); + + /* Put low and high together */ + *bits = (high << 8) | low; + + return true; // Indicate supported command. +} + + +bool AVRInSystemProg::writeExtendedFuseBits( long bits ) +{ + /* Use AVRISP's 4-byte universal command */ + comm->sendByte( '.' ); + comm->sendByte( 0xac ); + comm->sendByte( 0xa4 ); + comm->sendByte( 0x00 ); // Dummy. + comm->sendByte( bits ); + comm->flushTX(); + + comm->getByte(); // Ignore return code from SPI communication. + + if( comm->getByte() != '\r' ) // Check return code from command. + throw new ErrorMsg( "Extended fuse byte programming failed! " + "Programmer did not return CR after '.'-command." ); + + return true; // Indicate supported command. +} + + +bool AVRInSystemProg::readExtendedFuseBits( long * bits ) +{ + /* Use AVRISP's 4-byte universal command */ + comm->sendByte( '.' ); + comm->sendByte( 0x50 ); + comm->sendByte( 0x08 ); + comm->sendByte( 0x00 ); // Dummy. + comm->sendByte( 0x00 ); // Dummy. + comm->flushTX(); + + *bits = comm->getByte(); + + if( comm->getByte() != '\r' ) // Check return code from command. + throw new ErrorMsg( "Extended fuse byte readout failed! " + "Programmer did not return CR after '.'-command." ); + + return true; // Indicate supported command. +} + + +bool AVRInSystemProg::programmerSoftwareVersion( long * major, long * minor ) +{ + /* Send command 'V' to get software version */ + comm->sendByte( 'V' ); + comm->flushTX(); + + /* Get data */ + *major = comm->getByte(); + *minor = comm->getByte(); + + return true; // Indicate supported command. +} + + +bool AVRInSystemProg::programmerHardwareVersion( long * major, long * minor ) +{ + /* Send command 'v' to get hardware version */ + comm->sendByte( 'v' ); + comm->flushTX(); + + /* Get data */ + *major = comm->getByte(); + *minor = comm->getByte(); + + return true; // Indicate supported command. +} + + +void AVRInSystemProg::setAddress( long address ) +{ + /* Set current address */ + comm->sendByte( 'A' ); + comm->sendByte( address >> 8 ); // High byte of address. + comm->sendByte( address & 0xff ); // Low byte. + comm->flushTX(); + + /* Should return CR */ + if( comm->getByte() != '\r' ) + throw new ErrorMsg( "Setting address for programming operations failed! " + "Programmer did not return CR after 'A'-command." ); +} + + +void AVRInSystemProg::writeFlashLowByte( long value ) +{ + comm->sendByte( 'c' ); + comm->sendByte( value ); + comm->flushTX(); + + if( comm->getByte() != '\r' ) + throw new ErrorMsg( "Writing Flash low byte failed! " + "Programmer did not return CR after 'c'-command." ); +} + + +void AVRInSystemProg::writeFlashHighByte( long value ) +{ + comm->sendByte( 'C' ); + comm->sendByte( value ); + comm->flushTX(); + + if( comm->getByte() != '\r' ) + throw new ErrorMsg( "Writing Flash high byte failed! " + "Programmer did not return CR after 'C'-command." ); +} + + +void AVRInSystemProg::writeFlashPage() +{ + comm->sendByte( 'm' ); + comm->flushTX(); + + if( comm->getByte() != '\r' ) + throw new ErrorMsg( "Writing Flash page failed! " + "Programmer did not return CR after 'm'-command." ); +} + + +/* end of file */ + diff --git a/ports/bdk-atxx4-mstp/avrosp/AVRInSystemProg.hpp b/ports/bdk-atxx4-mstp/avrosp/AVRInSystemProg.hpp index ba94cf42..b74c80c9 100644 --- a/ports/bdk-atxx4-mstp/avrosp/AVRInSystemProg.hpp +++ b/ports/bdk-atxx4-mstp/avrosp/AVRInSystemProg.hpp @@ -1,78 +1,78 @@ -/***************************************************************************** - * - * Atmel Corporation - * - * File : AVRInSystemProg.hpp - * Compiler : Dev-C++ 4.9.8.0 - http://bloodshed.net/dev/ - * Revision : $Revision: 1163 $ - * Date : $Date: 2006-08-02 15:38:16 +0200 (on, 02 aug 2006) $ - * Updated by : $Author: ohlia $ - * - * Support mail : avr@atmel.com - * - * Target platform : Win32 - * - * AppNote : AVR911 - AVR Open-source Programmer - * - * Description : A class providing an interface to the AVR ISP described - * in Application Note AVR910. This class is derived from AVRPRogrammer. - * - * - ****************************************************************************/ -#ifndef AVRINSYSTEMPROG_HPP -#define AVRINSYSTEMPROG_HPP - -using namespace std; - -#include "AVRProgrammer.hpp" -#include "Utility.hpp" - -class AVRInSystemProg : public AVRProgrammer -{ - protected: - void setAddress( long address ); - void writeFlashLowByte( long value ); // Alwyas low byte first... - void writeFlashHighByte( long value ); // ...then high byte. - void writeFlashPage(); - - public: - /* Constructor */ - AVRInSystemProg( CommChannel * _comm ); - - /* Destructor */ - ~AVRInSystemProg(); - - /* Methods */ - virtual bool enterProgrammingMode(); - virtual bool leaveProgrammingMode(); - - virtual bool chipErase(); - - virtual bool readOSCCAL( long pos, long * value ); - virtual bool readSignature( long * sig0, long * sig1, long * sig2 ); - virtual bool checkSignature( long sig0, long sig1, long sig2 ); - - virtual bool writeFlashByte( long address, long value ); - virtual bool writeEEPROMByte( long address, long value ); - - virtual bool writeFlash( HEXFile * data ); - virtual bool readFlash( HEXFile * data ); - - virtual bool writeEEPROM( HEXFile * data ); - virtual bool readEEPROM( HEXFile * data ); - - virtual bool writeLockBits( long bits ); - virtual bool readLockBits( long * bits ); - - virtual bool writeFuseBits( long bits ); - virtual bool readFuseBits( long * bits ); - virtual bool writeExtendedFuseBits( long bits ); - virtual bool readExtendedFuseBits( long * bits ); - - virtual bool programmerSoftwareVersion( long * major, long * minor ); - virtual bool programmerHardwareVersion( long * major, long * minor ); -}; - - -#endif - +/***************************************************************************** + * + * Atmel Corporation + * + * File : AVRInSystemProg.hpp + * Compiler : Dev-C++ 4.9.8.0 - http://bloodshed.net/dev/ + * Revision : $Revision: 1163 $ + * Date : $Date: 2006-08-02 15:38:16 +0200 (on, 02 aug 2006) $ + * Updated by : $Author: ohlia $ + * + * Support mail : avr@atmel.com + * + * Target platform : Win32 + * + * AppNote : AVR911 - AVR Open-source Programmer + * + * Description : A class providing an interface to the AVR ISP described + * in Application Note AVR910. This class is derived from AVRPRogrammer. + * + * + ****************************************************************************/ +#ifndef AVRINSYSTEMPROG_HPP +#define AVRINSYSTEMPROG_HPP + +using namespace std; + +#include "AVRProgrammer.hpp" +#include "Utility.hpp" + +class AVRInSystemProg : public AVRProgrammer +{ + protected: + void setAddress( long address ); + void writeFlashLowByte( long value ); // Alwyas low byte first... + void writeFlashHighByte( long value ); // ...then high byte. + void writeFlashPage(); + + public: + /* Constructor */ + AVRInSystemProg( CommChannel * _comm ); + + /* Destructor */ + ~AVRInSystemProg(); + + /* Methods */ + virtual bool enterProgrammingMode(); + virtual bool leaveProgrammingMode(); + + virtual bool chipErase(); + + virtual bool readOSCCAL( long pos, long * value ); + virtual bool readSignature( long * sig0, long * sig1, long * sig2 ); + virtual bool checkSignature( long sig0, long sig1, long sig2 ); + + virtual bool writeFlashByte( long address, long value ); + virtual bool writeEEPROMByte( long address, long value ); + + virtual bool writeFlash( HEXFile * data ); + virtual bool readFlash( HEXFile * data ); + + virtual bool writeEEPROM( HEXFile * data ); + virtual bool readEEPROM( HEXFile * data ); + + virtual bool writeLockBits( long bits ); + virtual bool readLockBits( long * bits ); + + virtual bool writeFuseBits( long bits ); + virtual bool readFuseBits( long * bits ); + virtual bool writeExtendedFuseBits( long bits ); + virtual bool readExtendedFuseBits( long * bits ); + + virtual bool programmerSoftwareVersion( long * major, long * minor ); + virtual bool programmerHardwareVersion( long * major, long * minor ); +}; + + +#endif + diff --git a/ports/bdk-atxx4-mstp/avrosp/AVROSP.dev b/ports/bdk-atxx4-mstp/avrosp/AVROSP.dev index 753e61f7..cb9e5407 100644 --- a/ports/bdk-atxx4-mstp/avrosp/AVROSP.dev +++ b/ports/bdk-atxx4-mstp/avrosp/AVROSP.dev @@ -1,169 +1,169 @@ -[Project] -FileName=AVROSP.dev -Name=AVROSP -UnitCount=12 -Type=1 -Ver=1 -ObjFiles= -Includes= -Libs= -PrivateResource= -ResourceIncludes= -MakeIncludes= -Compiler= -CppCompiler= -Linker= -IsCpp=1 -Icon= -ExeOutput= -ObjectOutput= -OverrideOutput=0 -OverrideOutputName=AVROSP.exe -HostApplication= -Folders= -CommandLine= -dATmega16 -if\temp\rnd8KB.hex -pf -IncludeVersionInfo=0 -SupportXPThemes=0 -CompilerSet=0 -CompilerSettings=000000000000000100 -UseCustomMakefile=0 -CustomMakefile= - -[Unit1] -FileName=main.cpp -CompileCpp=1 -Folder= -Compile=1 -Link=1 -Priority=1000 -OverrideBuildCmd=0 -BuildCmd= - -[VersionInfo] -Major=0 -Minor=1 -Release=1 -Build=1 -LanguageID=1033 -CharsetID=1252 -CompanyName= -FileVersion= -FileDescription=Developed using the Dev-C++ IDE -InternalName= -LegalCopyright= -LegalTrademarks= -OriginalFilename= -ProductName= -ProductVersion= -AutoIncBuildNr=0 - -[Unit2] -FileName=CommChannel.cpp -CompileCpp=1 -Folder=Serialtest -Compile=1 -Link=1 -Priority=1000 -OverrideBuildCmd=0 -BuildCmd= - -[Unit3] -FileName=ErrorMsg.cpp -CompileCpp=1 -Folder=Serialtest -Compile=1 -Link=1 -Priority=1000 -OverrideBuildCmd=0 -BuildCmd= - -[Unit4] -FileName=JobInfo.cpp -CompileCpp=1 -Folder=AVROSP -Compile=1 -Link=1 -Priority=1000 -OverrideBuildCmd=0 -BuildCmd= - -[Unit5] -FileName=AVRDevice.cpp -CompileCpp=1 -Folder=AVROSP -Compile=1 -Link=1 -Priority=1000 -OverrideBuildCmd=0 -BuildCmd= - -[Unit6] -FileName=HEXParser.cpp -CompileCpp=1 -Folder=AVROSP -Compile=1 -Link=1 -Priority=1000 -OverrideBuildCmd=0 -BuildCmd= - -[Unit7] -FileName=XMLParser.cpp -CompileCpp=1 -Folder=AVROSP -Compile=1 -Link=1 -Priority=1000 -OverrideBuildCmd=0 -BuildCmd= - -[Unit8] -FileName=AVRBootloader.cpp -CompileCpp=1 -Folder=AVROSP -Compile=1 -Link=1 -Priority=1000 -OverrideBuildCmd=0 -BuildCmd= - -[Unit9] -FileName=AVRProgrammer.cpp -CompileCpp=1 -Folder=AVROSP -Compile=1 -Link=1 -Priority=1000 -OverrideBuildCmd=0 -BuildCmd= - -[Unit10] -FileName=Utility.cpp -CompileCpp=1 -Folder= -Compile=1 -Link=1 -Priority=1000 -OverrideBuildCmd=0 -BuildCmd= - -[Unit11] -FileName=SerialPort.cpp -CompileCpp=1 -Folder=AVROSP -Compile=1 -Link=1 -Priority=1000 -OverrideBuildCmd=0 -BuildCmd= - -[Unit12] -FileName=AVRInSystemProg.cpp -CompileCpp=1 -Folder=AVROSP -Compile=1 -Link=1 -Priority=1000 -OverrideBuildCmd=0 -BuildCmd= - +[Project] +FileName=AVROSP.dev +Name=AVROSP +UnitCount=12 +Type=1 +Ver=1 +ObjFiles= +Includes= +Libs= +PrivateResource= +ResourceIncludes= +MakeIncludes= +Compiler= +CppCompiler= +Linker= +IsCpp=1 +Icon= +ExeOutput= +ObjectOutput= +OverrideOutput=0 +OverrideOutputName=AVROSP.exe +HostApplication= +Folders= +CommandLine= -dATmega16 -if\temp\rnd8KB.hex -pf +IncludeVersionInfo=0 +SupportXPThemes=0 +CompilerSet=0 +CompilerSettings=000000000000000100 +UseCustomMakefile=0 +CustomMakefile= + +[Unit1] +FileName=main.cpp +CompileCpp=1 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[VersionInfo] +Major=0 +Minor=1 +Release=1 +Build=1 +LanguageID=1033 +CharsetID=1252 +CompanyName= +FileVersion= +FileDescription=Developed using the Dev-C++ IDE +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion= +AutoIncBuildNr=0 + +[Unit2] +FileName=CommChannel.cpp +CompileCpp=1 +Folder=Serialtest +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit3] +FileName=ErrorMsg.cpp +CompileCpp=1 +Folder=Serialtest +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit4] +FileName=JobInfo.cpp +CompileCpp=1 +Folder=AVROSP +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit5] +FileName=AVRDevice.cpp +CompileCpp=1 +Folder=AVROSP +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit6] +FileName=HEXParser.cpp +CompileCpp=1 +Folder=AVROSP +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit7] +FileName=XMLParser.cpp +CompileCpp=1 +Folder=AVROSP +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit8] +FileName=AVRBootloader.cpp +CompileCpp=1 +Folder=AVROSP +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit9] +FileName=AVRProgrammer.cpp +CompileCpp=1 +Folder=AVROSP +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit10] +FileName=Utility.cpp +CompileCpp=1 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit11] +FileName=SerialPort.cpp +CompileCpp=1 +Folder=AVROSP +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit12] +FileName=AVRInSystemProg.cpp +CompileCpp=1 +Folder=AVROSP +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/ports/bdk-atxx4-mstp/avrosp/AVRProgrammer.cpp b/ports/bdk-atxx4-mstp/avrosp/AVRProgrammer.cpp index e4e851a9..c9530a60 100644 --- a/ports/bdk-atxx4-mstp/avrosp/AVRProgrammer.cpp +++ b/ports/bdk-atxx4-mstp/avrosp/AVRProgrammer.cpp @@ -1,70 +1,70 @@ -/***************************************************************************** - * - * Atmel Corporation - * - * File : AVRProgrammer.cpp - * Compiler : Dev-C++ 4.9.8.0 - http://bloodshed.net/dev/ - * Revision : $Revision: 1163 $ - * Date : $Date: 2006-08-02 15:38:16 +0200 (on, 02 aug 2006) $ - * Updated by : $Author: ohlia $ - * - * Support mail : avr@atmel.com - * - * Target platform : Win32 - * - * AppNote : AVR911 - AVR Open-source Programmer - * - * Description : An abstract class containing a framework for a generic - * programmer for AVR parts. Reading and writing Flash, EEPROM - * lock bits and all fuse bits and reading OSCCAL and reading - * signature bytes are supported. - * - * - ****************************************************************************/ -#include "AVRProgrammer.hpp" - - -/* Constructor */ -AVRProgrammer::AVRProgrammer( CommChannel * _comm ) : - pagesize( -1 ) -{ - if( _comm == NULL ) - throw new ErrorMsg( "NULL pointer provided for communication channel!" ); - - comm = _comm; -} - - -/* Destructor */ -AVRProgrammer::~AVRProgrammer() -{ - /* No code here */ -} - - -string AVRProgrammer::readProgrammerID( CommChannel * _comm ) -{ - string id( "1234567" ); // Reserve 7 characters. - - if( _comm == NULL ) - throw new ErrorMsg( "NULL pointer provided for communication channel!" ); - - /* Synchonize with programmer */ - for( int i = 0; i < 10; i++ ) - _comm->sendByte( 27 ); // Send ESC - - /* Send 'S' command to programmer */ - _comm->sendByte( 'S' ); - _comm->flushTX(); - - /* Read 7 characters */ - for( long i = 0; i < id.size(); i++ ) - { - id[i] = _comm->getByte(); - } - - return id; -} - -/* end of file */ - +/***************************************************************************** + * + * Atmel Corporation + * + * File : AVRProgrammer.cpp + * Compiler : Dev-C++ 4.9.8.0 - http://bloodshed.net/dev/ + * Revision : $Revision: 1163 $ + * Date : $Date: 2006-08-02 15:38:16 +0200 (on, 02 aug 2006) $ + * Updated by : $Author: ohlia $ + * + * Support mail : avr@atmel.com + * + * Target platform : Win32 + * + * AppNote : AVR911 - AVR Open-source Programmer + * + * Description : An abstract class containing a framework for a generic + * programmer for AVR parts. Reading and writing Flash, EEPROM + * lock bits and all fuse bits and reading OSCCAL and reading + * signature bytes are supported. + * + * + ****************************************************************************/ +#include "AVRProgrammer.hpp" + + +/* Constructor */ +AVRProgrammer::AVRProgrammer( CommChannel * _comm ) : + pagesize( -1 ) +{ + if( _comm == NULL ) + throw new ErrorMsg( "NULL pointer provided for communication channel!" ); + + comm = _comm; +} + + +/* Destructor */ +AVRProgrammer::~AVRProgrammer() +{ + /* No code here */ +} + + +string AVRProgrammer::readProgrammerID( CommChannel * _comm ) +{ + string id( "1234567" ); // Reserve 7 characters. + + if( _comm == NULL ) + throw new ErrorMsg( "NULL pointer provided for communication channel!" ); + + /* Synchonize with programmer */ + for( int i = 0; i < 10; i++ ) + _comm->sendByte( 27 ); // Send ESC + + /* Send 'S' command to programmer */ + _comm->sendByte( 'S' ); + _comm->flushTX(); + + /* Read 7 characters */ + for( long i = 0; i < id.size(); i++ ) + { + id[i] = _comm->getByte(); + } + + return id; +} + +/* end of file */ + diff --git a/ports/bdk-atxx4-mstp/avrosp/AVRProgrammer.hpp b/ports/bdk-atxx4-mstp/avrosp/AVRProgrammer.hpp index 8921e589..a237a110 100644 --- a/ports/bdk-atxx4-mstp/avrosp/AVRProgrammer.hpp +++ b/ports/bdk-atxx4-mstp/avrosp/AVRProgrammer.hpp @@ -1,84 +1,84 @@ -/***************************************************************************** - * - * Atmel Corporation - * - * File : AVRProgrammer.hpp - * Compiler : Dev-C++ 4.9.8.0 - http://bloodshed.net/dev/ - * Revision : $Revision: 1163 $ - * Date : $Date: 2006-08-02 15:38:16 +0200 (on, 02 aug 2006) $ - * Updated by : $Author: ohlia $ - * - * Support mail : avr@atmel.com - * - * Target platform : Win32 - * - * AppNote : AVR911 - AVR Open-source Programmer - * - * Description : An abstract class containing a framework for a generic - * programmer for AVR parts. Reading and writing Flash, EEPROM - * lock bits and all fuse bits and reading OSCCAL and reading - * signature bytes are supported. - * - * - ****************************************************************************/ -#ifndef AVRPROGRAMMER_HPP -#define AVRPROGRAMMER_HPP - -using namespace std; - -#include "ErrorMsg.hpp" -#include "HEXParser.hpp" -#include "CommChannel.hpp" - -class AVRProgrammer -{ - protected: - long pagesize; // Flash page size. - CommChannel * comm; - - public: - /* Constructor */ - AVRProgrammer( CommChannel * _comm ); - - /* Destructor */ - ~AVRProgrammer(); - - /* Static member */ - static string readProgrammerID( CommChannel * _comm ); // Reads 7-character ID. - - /* Methods */ - void setPagesize( long _pagesize ) { pagesize = _pagesize; } - - virtual bool enterProgrammingMode() = 0; - virtual bool leaveProgrammingMode() = 0; - - virtual bool chipErase() = 0; - - virtual bool readOSCCAL( long pos, long * value ) = 0; - virtual bool readSignature( long * sig0, long * sig1, long * sig2 ) = 0; - virtual bool checkSignature( long sig0, long sig1, long sig2 ) = 0; - - virtual bool writeFlashByte( long address, long value ) = 0; - virtual bool writeEEPROMByte( long address, long value ) = 0; - - virtual bool writeFlash( HEXFile * data ) = 0; - virtual bool readFlash( HEXFile * data ) = 0; - - virtual bool writeEEPROM( HEXFile * data ) = 0; - virtual bool readEEPROM( HEXFile * data ) = 0; - - virtual bool writeLockBits( long bits ) = 0; - virtual bool readLockBits( long * bits ) = 0; - - virtual bool writeFuseBits( long bits ) = 0; - virtual bool readFuseBits( long * bits ) = 0; - virtual bool writeExtendedFuseBits( long bits ) = 0; - virtual bool readExtendedFuseBits( long * bits ) = 0; - - virtual bool programmerSoftwareVersion( long * major, long * minor ) = 0; - virtual bool programmerHardwareVersion( long * major, long * minor ) = 0; -}; - - -#endif - +/***************************************************************************** + * + * Atmel Corporation + * + * File : AVRProgrammer.hpp + * Compiler : Dev-C++ 4.9.8.0 - http://bloodshed.net/dev/ + * Revision : $Revision: 1163 $ + * Date : $Date: 2006-08-02 15:38:16 +0200 (on, 02 aug 2006) $ + * Updated by : $Author: ohlia $ + * + * Support mail : avr@atmel.com + * + * Target platform : Win32 + * + * AppNote : AVR911 - AVR Open-source Programmer + * + * Description : An abstract class containing a framework for a generic + * programmer for AVR parts. Reading and writing Flash, EEPROM + * lock bits and all fuse bits and reading OSCCAL and reading + * signature bytes are supported. + * + * + ****************************************************************************/ +#ifndef AVRPROGRAMMER_HPP +#define AVRPROGRAMMER_HPP + +using namespace std; + +#include "ErrorMsg.hpp" +#include "HEXParser.hpp" +#include "CommChannel.hpp" + +class AVRProgrammer +{ + protected: + long pagesize; // Flash page size. + CommChannel * comm; + + public: + /* Constructor */ + AVRProgrammer( CommChannel * _comm ); + + /* Destructor */ + ~AVRProgrammer(); + + /* Static member */ + static string readProgrammerID( CommChannel * _comm ); // Reads 7-character ID. + + /* Methods */ + void setPagesize( long _pagesize ) { pagesize = _pagesize; } + + virtual bool enterProgrammingMode() = 0; + virtual bool leaveProgrammingMode() = 0; + + virtual bool chipErase() = 0; + + virtual bool readOSCCAL( long pos, long * value ) = 0; + virtual bool readSignature( long * sig0, long * sig1, long * sig2 ) = 0; + virtual bool checkSignature( long sig0, long sig1, long sig2 ) = 0; + + virtual bool writeFlashByte( long address, long value ) = 0; + virtual bool writeEEPROMByte( long address, long value ) = 0; + + virtual bool writeFlash( HEXFile * data ) = 0; + virtual bool readFlash( HEXFile * data ) = 0; + + virtual bool writeEEPROM( HEXFile * data ) = 0; + virtual bool readEEPROM( HEXFile * data ) = 0; + + virtual bool writeLockBits( long bits ) = 0; + virtual bool readLockBits( long * bits ) = 0; + + virtual bool writeFuseBits( long bits ) = 0; + virtual bool readFuseBits( long * bits ) = 0; + virtual bool writeExtendedFuseBits( long bits ) = 0; + virtual bool readExtendedFuseBits( long * bits ) = 0; + + virtual bool programmerSoftwareVersion( long * major, long * minor ) = 0; + virtual bool programmerHardwareVersion( long * major, long * minor ) = 0; +}; + + +#endif + diff --git a/ports/bdk-atxx4-mstp/avrosp/CommChannel.cpp b/ports/bdk-atxx4-mstp/avrosp/CommChannel.cpp index 091b69f7..828ee846 100644 --- a/ports/bdk-atxx4-mstp/avrosp/CommChannel.cpp +++ b/ports/bdk-atxx4-mstp/avrosp/CommChannel.cpp @@ -1,38 +1,38 @@ -/***************************************************************************** - * - * Atmel Corporation - * - * File : CommChannel.cpp - * Compiler : Dev-C++ 4.9.8.0 - http://bloodshed.net/dev/ - * Revision : $Revision: 1163 $ - * Date : $Date: 2006-08-02 15:38:16 +0200 (on, 02 aug 2006) $ - * Updated by : $Author: ohlia $ - * - * Support mail : avr@atmel.com - * - * Target platform : Win32 - * - * AppNote : AVR911 - AVR Open-source Programmer - * - * Description : An abstract class for general byte-by-byte communication. - * Serialport, USB, TCP/IP or similar implementations can be derived - * from this class to create a technology-independent - * communication interface. - * - * This abstract class does not provide any constructor as it is - * too specific for this generalized class. Derived classes should - * implement their own constructors for specific communication devices. - * - * - ****************************************************************************/ -#include "CommChannel.hpp" - - -/* Destructor */ -CommChannel::~CommChannel() -{ - /* no code here */ -} - -/* end of file */ - +/***************************************************************************** + * + * Atmel Corporation + * + * File : CommChannel.cpp + * Compiler : Dev-C++ 4.9.8.0 - http://bloodshed.net/dev/ + * Revision : $Revision: 1163 $ + * Date : $Date: 2006-08-02 15:38:16 +0200 (on, 02 aug 2006) $ + * Updated by : $Author: ohlia $ + * + * Support mail : avr@atmel.com + * + * Target platform : Win32 + * + * AppNote : AVR911 - AVR Open-source Programmer + * + * Description : An abstract class for general byte-by-byte communication. + * Serialport, USB, TCP/IP or similar implementations can be derived + * from this class to create a technology-independent + * communication interface. + * + * This abstract class does not provide any constructor as it is + * too specific for this generalized class. Derived classes should + * implement their own constructors for specific communication devices. + * + * + ****************************************************************************/ +#include "CommChannel.hpp" + + +/* Destructor */ +CommChannel::~CommChannel() +{ + /* no code here */ +} + +/* end of file */ + diff --git a/ports/bdk-atxx4-mstp/avrosp/CommChannel.hpp b/ports/bdk-atxx4-mstp/avrosp/CommChannel.hpp index 6f48f756..905dfd4d 100644 --- a/ports/bdk-atxx4-mstp/avrosp/CommChannel.hpp +++ b/ports/bdk-atxx4-mstp/avrosp/CommChannel.hpp @@ -1,61 +1,61 @@ -/***************************************************************************** - * - * Atmel Corporation - * - * File : CommChannel.hpp - * Compiler : Dev-C++ 4.9.8.0 - http://bloodshed.net/dev/ - * Revision : $Revision: 1163 $ - * Date : $Date: 2006-08-02 15:38:16 +0200 (on, 02 aug 2006) $ - * Updated by : $Author: ohlia $ - * - * Support mail : avr@atmel.com - * - * Target platform : Win32 - * - * AppNote : AVR911 - AVR Open-source Programmer - * - * Description : An abstract class for general byte-by-byte communication. - * Serialport, USB, TCP/IP or similar implementations can be derived - * from this class to create a technology-independent - * communication interface. - * - * This abstract class does not provide any constructor as it is - * too specific for this generalized class. Derived classes should - * implement their own constructors for specific communication devices. - * - * - ****************************************************************************/ -#ifndef COMMCHANNEL_HPP -#define COMMCHANNEL_HPP - -using namespace std; - -class CommChannel -{ - public: - // Destructor - virtual ~CommChannel() = 0; - - // Open the communication channel. - virtual void openChannel() = 0; - - // Close the communication channel. - virtual void closeChannel() = 0; - - // Transmit a single byte. - virtual void sendByte( long data ) = 0; - - // Receive a single byte. - virtual long getByte() = 0; - - // Flush the transmit buffer. - virtual void flushTX() = 0; - - // Flush the receive buffer. - virtual void flushRX() = 0; - - // Transmit multiple bytes. - virtual void sendMultiple( unsigned char * data, long bufsize ) = 0; -}; - -#endif +/***************************************************************************** + * + * Atmel Corporation + * + * File : CommChannel.hpp + * Compiler : Dev-C++ 4.9.8.0 - http://bloodshed.net/dev/ + * Revision : $Revision: 1163 $ + * Date : $Date: 2006-08-02 15:38:16 +0200 (on, 02 aug 2006) $ + * Updated by : $Author: ohlia $ + * + * Support mail : avr@atmel.com + * + * Target platform : Win32 + * + * AppNote : AVR911 - AVR Open-source Programmer + * + * Description : An abstract class for general byte-by-byte communication. + * Serialport, USB, TCP/IP or similar implementations can be derived + * from this class to create a technology-independent + * communication interface. + * + * This abstract class does not provide any constructor as it is + * too specific for this generalized class. Derived classes should + * implement their own constructors for specific communication devices. + * + * + ****************************************************************************/ +#ifndef COMMCHANNEL_HPP +#define COMMCHANNEL_HPP + +using namespace std; + +class CommChannel +{ + public: + // Destructor + virtual ~CommChannel() = 0; + + // Open the communication channel. + virtual void openChannel() = 0; + + // Close the communication channel. + virtual void closeChannel() = 0; + + // Transmit a single byte. + virtual void sendByte( long data ) = 0; + + // Receive a single byte. + virtual long getByte() = 0; + + // Flush the transmit buffer. + virtual void flushTX() = 0; + + // Flush the receive buffer. + virtual void flushRX() = 0; + + // Transmit multiple bytes. + virtual void sendMultiple( unsigned char * data, long bufsize ) = 0; +}; + +#endif diff --git a/ports/bdk-atxx4-mstp/avrosp/ErrorMsg.cpp b/ports/bdk-atxx4-mstp/avrosp/ErrorMsg.cpp index 957f574c..335a7040 100644 --- a/ports/bdk-atxx4-mstp/avrosp/ErrorMsg.cpp +++ b/ports/bdk-atxx4-mstp/avrosp/ErrorMsg.cpp @@ -1,46 +1,46 @@ -/***************************************************************************** - * - * Atmel Corporation - * - * File : ErrorMsg.cpp - * Compiler : Dev-C++ 4.9.8.0 - http://bloodshed.net/dev/ - * Revision : $Revision: 1163 $ - * Date : $Date: 2006-08-02 15:38:16 +0200 (on, 02 aug 2006) $ - * Updated by : $Author: ohlia $ - * - * Support mail : avr@atmel.com - * - * Target platform : Win32 - * - * AppNote : AVR911 - AVR Open-source Programmer - * - * Description : A class providing a container for general error messages. This - * class can be thrown as an exception. - * - * - ****************************************************************************/ -#include "ErrorMsg.hpp" - - -ErrorMsg::ErrorMsg( const string & _message ) : - message( _message ) -{ - // No code here. -} - - -/* Destructor */ -ErrorMsg::~ErrorMsg() -{ - // No code here. -} - - -/* Get message */ -const string & ErrorMsg::What() -{ - return message; -} - -/* end of file */ - +/***************************************************************************** + * + * Atmel Corporation + * + * File : ErrorMsg.cpp + * Compiler : Dev-C++ 4.9.8.0 - http://bloodshed.net/dev/ + * Revision : $Revision: 1163 $ + * Date : $Date: 2006-08-02 15:38:16 +0200 (on, 02 aug 2006) $ + * Updated by : $Author: ohlia $ + * + * Support mail : avr@atmel.com + * + * Target platform : Win32 + * + * AppNote : AVR911 - AVR Open-source Programmer + * + * Description : A class providing a container for general error messages. This + * class can be thrown as an exception. + * + * + ****************************************************************************/ +#include "ErrorMsg.hpp" + + +ErrorMsg::ErrorMsg( const string & _message ) : + message( _message ) +{ + // No code here. +} + + +/* Destructor */ +ErrorMsg::~ErrorMsg() +{ + // No code here. +} + + +/* Get message */ +const string & ErrorMsg::What() +{ + return message; +} + +/* end of file */ + diff --git a/ports/bdk-atxx4-mstp/avrosp/ErrorMsg.hpp b/ports/bdk-atxx4-mstp/avrosp/ErrorMsg.hpp index f38da763..a511f2ce 100644 --- a/ports/bdk-atxx4-mstp/avrosp/ErrorMsg.hpp +++ b/ports/bdk-atxx4-mstp/avrosp/ErrorMsg.hpp @@ -1,49 +1,49 @@ -/***************************************************************************** - * - * Atmel Corporation - * - * File : ErrorMsg.hpp - * Compiler : Dev-C++ 4.9.8.0 - http://bloodshed.net/dev/ - * Revision : $Revision: 1163 $ - * Date : $Date: 2006-08-02 15:38:16 +0200 (on, 02 aug 2006) $ - * Updated by : $Author: ohlia $ - * - * Support mail : avr@atmel.com - * - * Target platform : Win32 - * - * AppNote : AVR911 - AVR Open-source Programmer - * - * Description : A class providing a container for general error messages. This - * class can be thrown as an exception. - * - * - ****************************************************************************/ -#ifndef ERRORMSG_HPP -#define ERRORMSG_HPP - -using namespace std; - -#include -#include -#include - - -class ErrorMsg -{ - protected: - string message; // Contains the error message. - - public: - // Constructors taking the string as parameter. - ErrorMsg( const string & _message ); - - // Destructor - ~ErrorMsg(); - - // Function returning the error msg. - virtual const string & What(); -}; - -#endif - +/***************************************************************************** + * + * Atmel Corporation + * + * File : ErrorMsg.hpp + * Compiler : Dev-C++ 4.9.8.0 - http://bloodshed.net/dev/ + * Revision : $Revision: 1163 $ + * Date : $Date: 2006-08-02 15:38:16 +0200 (on, 02 aug 2006) $ + * Updated by : $Author: ohlia $ + * + * Support mail : avr@atmel.com + * + * Target platform : Win32 + * + * AppNote : AVR911 - AVR Open-source Programmer + * + * Description : A class providing a container for general error messages. This + * class can be thrown as an exception. + * + * + ****************************************************************************/ +#ifndef ERRORMSG_HPP +#define ERRORMSG_HPP + +using namespace std; + +#include +#include +#include + + +class ErrorMsg +{ + protected: + string message; // Contains the error message. + + public: + // Constructors taking the string as parameter. + ErrorMsg( const string & _message ); + + // Destructor + ~ErrorMsg(); + + // Function returning the error msg. + virtual const string & What(); +}; + +#endif + diff --git a/ports/bdk-atxx4-mstp/avrosp/HEXParser.cpp b/ports/bdk-atxx4-mstp/avrosp/HEXParser.cpp index 1dd2a2a8..071e4bab 100644 --- a/ports/bdk-atxx4-mstp/avrosp/HEXParser.cpp +++ b/ports/bdk-atxx4-mstp/avrosp/HEXParser.cpp @@ -1,364 +1,364 @@ -/***************************************************************************** - * - * Atmel Corporation - * - * File : HEXParser.cpp - * Compiler : Dev-C++ 4.9.8.0 - http://bloodshed.net/dev/ - * Revision : $Revision: 1163 $ - * Date : $Date: 2006-08-02 15:38:16 +0200 (on, 02 aug 2006) $ - * Updated by : $Author: ohlia $ - * - * Support mail : avr@atmel.com - * - * Target platform : Win32 - * - * AppNote : AVR911 - AVR Open-source Programmer - * - * Description : A simple Intel HEX file format reader/writer. - * - * - ****************************************************************************/ -#include "HEXParser.hpp" - - -/* Internal struct for managing HEX records */ -struct HEXRecord // Intel HEX file record -{ - unsigned char length; // Record length in number of data bytes. - unsigned long offset; // Offset address. - unsigned char type; // Record type. - unsigned char * data; // Optional data bytes. -}; - - -void HEXFile::writeRecord( ofstream & f, HEXRecord * recp ) -{ - unsigned char checksum; - long recordPos; // Position inside record data field - - /* Calculate checksum */ - checksum = recp->length; - checksum += (unsigned char) ((recp->offset >> 8) & 0xff); - checksum += (unsigned char) (recp->offset & 0xff); - checksum += recp->type; - - /* Write record header */ - f.fill('0'); - f << ":" << hex - << setw(2) << (long) recp->length - << setw(4) << (long) recp->offset - << setw(2) << (long) recp->type; - - /* Write data bytes */ - for( recordPos = 0; recordPos < recp->length; recordPos++ ) - { - checksum += recp->data[ recordPos ]; // Further checksum calculation - f << hex << setw(2) << (long) recp->data[ recordPos ]; - } - - /* Write checksum */ - checksum = 0 - checksum; // Final checksum preparation - f << setw(2) << (long) checksum << endl; - - /* Check for errors */ - if( !f.good() ) - throw new ErrorMsg( "Error writing HEX record to file!" ); -} - - -void HEXFile::parseRecord( const string & hexLine, HEXRecord * recp ) -{ - unsigned char checksum; - long recordPos; // Position inside record data fields. - - if( hexLine.size() < 11 ) // At least 11 characters. - throw new ErrorMsg( "Wrong HEX file format, missing fields! " - "Line from file was: (" + hexLine + ")." ); - - /* Check format for line */ - if( hexLine[0] != ':' ) // Always start with colon. - throw new ErrorMsg( "Wrong HEX file format, does not start with colon! " - "Line from file was: (" + hexLine + ")." ); - - /* Parse length, offset and type */ - recp->length = Util.convertHex( hexLine.substr( 1, 2 ) ); - recp->offset = Util.convertHex( hexLine.substr( 3, 4 ) ); - recp->type = Util.convertHex( hexLine.substr( 7, 2 ) ); - - /* We now know how long the record should be */ - if( hexLine.size() < (11+recp->length*2) ) - throw new ErrorMsg( "Wrong HEX file format, missing fields! " - "Line from file was: (" + hexLine + ")." ); - - /* Process checksum */ - checksum = recp->length; - checksum += (unsigned char) ((recp->offset >> 8) & 0xff); - checksum += (unsigned char) (recp->offset & 0xff); - checksum += recp->type; - - /* Parse data fields */ - if( recp->length ) - { - recp->data = new unsigned char[ recp->length ]; - - /* Read data from record */ - for( recordPos = 0; recordPos < recp->length; recordPos++ ) - { - recp->data[ recordPos ] = Util.convertHex( hexLine.substr( 9 + recordPos*2, 2 ) ); - checksum += recp->data[ recordPos ]; - } - } - - /* Correct checksum? */ - checksum += Util.convertHex( hexLine.substr( 9 + recp->length*2, 2 ) ); - if( checksum != 0 ) - { - throw new ErrorMsg( "Wrong checksum for HEX record! " - "Line from file was: (" + hexLine + ")." ); - } -} - - - -/* Constructor */ -HEXFile::HEXFile( long buffersize, long value ) -{ - if( buffersize <= 0 ) - throw new ErrorMsg( "Cannot have zero-size HEX buffer!" ); - - data = new unsigned char[ buffersize ]; - - if( !data ) - throw new ErrorMsg( "Memory allocation failed for HEX-line-buffer!" ); - - size = buffersize; - - clearAll( value ); -} - - -/* Destructor */ -HEXFile::~HEXFile() -{ - if( data ) delete data; -} - - -void HEXFile::readFile( const string & _filename ) -{ - ifstream f; - string hexLine; // Contains one line of the HEX file. - HEXRecord rec; // Temp record. - - long baseAddress; // Base address for extended addressing modes. - long dataPos; // Data position in record. - - /* Attempt to open file */ - f.open( _filename.c_str(), ios::in ); - if( !f ) - throw new ErrorMsg( "Error opening HEX file for input!" ); - - /* Prepare */ - baseAddress = 0; - start = size; - end = 0; - - /* Parse records */ - f >> hexLine; // Read one line. - while( !f.eof() ) - { - Util.progress( "#" ); // Advance progress indicator. - - /* Process record according to type */ - parseRecord( hexLine, &rec ); - - switch( rec.type ) - { - case 0x00 : // Data record ? - /* Copy data */ - if( baseAddress + rec.offset + rec.length > size ) - throw new ErrorMsg( "HEX file defines data outside buffer limits! " - "Make sure file does not contain data outside device " - "memory limits. " - "Line from file was: (" + hexLine + ")." ); - - for( dataPos = 0; dataPos < rec.length; dataPos++ ) - data[ baseAddress + rec.offset + dataPos ] = rec.data[ dataPos ]; - - /* Update byte usage */ - if( baseAddress + rec.offset < start ) - start = baseAddress + rec.offset; - - if( baseAddress + rec.offset + rec.length - 1 > end ) - end = baseAddress + rec.offset + rec.length - 1; - - break; - - - case 0x02 : // Extended segment address record ? - baseAddress = (rec.data[0] << 8) | rec.data[1]; - baseAddress <<= 4; - break; - - case 0x03 : // Start segment address record ? - break; // Ignore it, since we have no influence on execution start address. - - case 0x04 : // Extended linear address record ? - baseAddress = (rec.data[0] << 8) | rec.data[1]; - baseAddress <<= 16; - break; - - case 0x05 : // Start linear address record ? - break; // Ignore it, since we have no influence on exectuion start address. - - case 0x01 : // End of file record ? - f.close(); - Util.progress( "\r\n" ); // Finish progress indicator. - return; - - default: - throw new ErrorMsg( "Unsupported HEX record format! " - "Line from file was: (" + hexLine + ")." ); - } - - f >> hexLine; // Read next line. - } - - - /* We should not end up here */ - throw new ErrorMsg( "Premature end of file encountered! Make sure file " - "contains an EOF-record." ); -} - - -void HEXFile::writeFile( const string & _filename ) -{ - ofstream f; - HEXRecord rec; // Temp record. - - long baseAddress; // Absolute data position. - long offset; // Offset from base address. - long dataPos; // Position inside data record. - - enum - { - _first, - _writing, - _passed64k - } status; // Write status, see usage below. - - /* Attempt to create file */ - f.open( _filename.c_str(), ios::out ); - if( !f ) - throw new ErrorMsg( "Error opening HEX file for output!" ); - - /* Prepare */ - status = _first; - rec.data = new unsigned char[ 16 ]; // Use only 16 byte records. - - baseAddress = start & ~0xffff; // 64K aligned address. - offset = start & 0xffff; // Offset from the aligned address. - dataPos = 0; - - /* Write first base address record to HEX file */ - rec.length = 2; - rec.offset = 0; - rec.type = 0x02; - rec.data[1] = 0x00; - rec.data[0] = baseAddress >> 12; // Give 4k page index. - writeRecord( f, &rec ); // Write the HEX record to file. - - - /* Write all bytes in used range */ - do - { - /* Put data into record */ - rec.data[ dataPos ] = data[ baseAddress + offset + dataPos ]; - dataPos++; - - /* Check if we need to write out the current data record */ - if( offset + dataPos >= 0x10000 || // Reached 64k boundary? - dataPos >= 16 || // Data record full? - baseAddress + offset + dataPos > end ) // End of used range reached? - { - /* Write current data record */ - rec.length = dataPos; - rec.offset = offset; - rec.type = 0x00; // Data record. - - Util.progress( "#" ); // Advance progress indicator. - writeRecord( f, &rec ); - - offset += dataPos; - dataPos = 0; - } - - /* Check if we have passed a 64k boundary */ - if( offset + dataPos >= 0x10000 ) - { - /* Update address pointers */ - offset -= 0x10000; - baseAddress += 0x10000; - - /* Write new base address record to HEX file */ - rec.length = 2; - rec.offset = 0; - rec.type = 0x02; - rec.data[0] = baseAddress >> 12; // Give 4k page index. - rec.data[1] = 0x00; - - writeRecord( f, &rec ); // Write the HEX record to file. - } - } while( baseAddress + offset + dataPos <= end ); - - - /* Write EOF record */ - rec.length = 0; - rec.offset = 0; - rec.type = 0x01; - - writeRecord( f, &rec ); - - f.close(); - Util.progress( "\r\n" ); // Finish progress indicator. -} - - -void HEXFile::setUsedRange( long _start, long _end ) -{ - if( _start < 0 || _end >= size || _start > _end ) - throw new ErrorMsg( "Invalid range! Start must be 0 or larger, end must be " - "inside allowed memory range." ); - - start = _start; - end = _end; -} - - -void HEXFile::clearAll( long value ) -{ - for( long i = 0; i < size; i++ ) - data[i] = (unsigned char) (value & 0xff); -} - - -long HEXFile::getData( long address ) -{ - if( address < 0 || address >= size ) - throw new ErrorMsg( "Address outside legal range!" ); - - return data[ address ]; -} - - -void HEXFile::setData( long address, long value ) -{ - if( address < 0 || address >= size ) - throw new ErrorMsg( "Address outside legal range!" ); - - data[ address ] = (unsigned char) (value & 0xff); -} - - -/* end of file */ - +/***************************************************************************** + * + * Atmel Corporation + * + * File : HEXParser.cpp + * Compiler : Dev-C++ 4.9.8.0 - http://bloodshed.net/dev/ + * Revision : $Revision: 1163 $ + * Date : $Date: 2006-08-02 15:38:16 +0200 (on, 02 aug 2006) $ + * Updated by : $Author: ohlia $ + * + * Support mail : avr@atmel.com + * + * Target platform : Win32 + * + * AppNote : AVR911 - AVR Open-source Programmer + * + * Description : A simple Intel HEX file format reader/writer. + * + * + ****************************************************************************/ +#include "HEXParser.hpp" + + +/* Internal struct for managing HEX records */ +struct HEXRecord // Intel HEX file record +{ + unsigned char length; // Record length in number of data bytes. + unsigned long offset; // Offset address. + unsigned char type; // Record type. + unsigned char * data; // Optional data bytes. +}; + + +void HEXFile::writeRecord( ofstream & f, HEXRecord * recp ) +{ + unsigned char checksum; + long recordPos; // Position inside record data field + + /* Calculate checksum */ + checksum = recp->length; + checksum += (unsigned char) ((recp->offset >> 8) & 0xff); + checksum += (unsigned char) (recp->offset & 0xff); + checksum += recp->type; + + /* Write record header */ + f.fill('0'); + f << ":" << hex + << setw(2) << (long) recp->length + << setw(4) << (long) recp->offset + << setw(2) << (long) recp->type; + + /* Write data bytes */ + for( recordPos = 0; recordPos < recp->length; recordPos++ ) + { + checksum += recp->data[ recordPos ]; // Further checksum calculation + f << hex << setw(2) << (long) recp->data[ recordPos ]; + } + + /* Write checksum */ + checksum = 0 - checksum; // Final checksum preparation + f << setw(2) << (long) checksum << endl; + + /* Check for errors */ + if( !f.good() ) + throw new ErrorMsg( "Error writing HEX record to file!" ); +} + + +void HEXFile::parseRecord( const string & hexLine, HEXRecord * recp ) +{ + unsigned char checksum; + long recordPos; // Position inside record data fields. + + if( hexLine.size() < 11 ) // At least 11 characters. + throw new ErrorMsg( "Wrong HEX file format, missing fields! " + "Line from file was: (" + hexLine + ")." ); + + /* Check format for line */ + if( hexLine[0] != ':' ) // Always start with colon. + throw new ErrorMsg( "Wrong HEX file format, does not start with colon! " + "Line from file was: (" + hexLine + ")." ); + + /* Parse length, offset and type */ + recp->length = Util.convertHex( hexLine.substr( 1, 2 ) ); + recp->offset = Util.convertHex( hexLine.substr( 3, 4 ) ); + recp->type = Util.convertHex( hexLine.substr( 7, 2 ) ); + + /* We now know how long the record should be */ + if( hexLine.size() < (11+recp->length*2) ) + throw new ErrorMsg( "Wrong HEX file format, missing fields! " + "Line from file was: (" + hexLine + ")." ); + + /* Process checksum */ + checksum = recp->length; + checksum += (unsigned char) ((recp->offset >> 8) & 0xff); + checksum += (unsigned char) (recp->offset & 0xff); + checksum += recp->type; + + /* Parse data fields */ + if( recp->length ) + { + recp->data = new unsigned char[ recp->length ]; + + /* Read data from record */ + for( recordPos = 0; recordPos < recp->length; recordPos++ ) + { + recp->data[ recordPos ] = Util.convertHex( hexLine.substr( 9 + recordPos*2, 2 ) ); + checksum += recp->data[ recordPos ]; + } + } + + /* Correct checksum? */ + checksum += Util.convertHex( hexLine.substr( 9 + recp->length*2, 2 ) ); + if( checksum != 0 ) + { + throw new ErrorMsg( "Wrong checksum for HEX record! " + "Line from file was: (" + hexLine + ")." ); + } +} + + + +/* Constructor */ +HEXFile::HEXFile( long buffersize, long value ) +{ + if( buffersize <= 0 ) + throw new ErrorMsg( "Cannot have zero-size HEX buffer!" ); + + data = new unsigned char[ buffersize ]; + + if( !data ) + throw new ErrorMsg( "Memory allocation failed for HEX-line-buffer!" ); + + size = buffersize; + + clearAll( value ); +} + + +/* Destructor */ +HEXFile::~HEXFile() +{ + if( data ) delete data; +} + + +void HEXFile::readFile( const string & _filename ) +{ + ifstream f; + string hexLine; // Contains one line of the HEX file. + HEXRecord rec; // Temp record. + + long baseAddress; // Base address for extended addressing modes. + long dataPos; // Data position in record. + + /* Attempt to open file */ + f.open( _filename.c_str(), ios::in ); + if( !f ) + throw new ErrorMsg( "Error opening HEX file for input!" ); + + /* Prepare */ + baseAddress = 0; + start = size; + end = 0; + + /* Parse records */ + f >> hexLine; // Read one line. + while( !f.eof() ) + { + Util.progress( "#" ); // Advance progress indicator. + + /* Process record according to type */ + parseRecord( hexLine, &rec ); + + switch( rec.type ) + { + case 0x00 : // Data record ? + /* Copy data */ + if( baseAddress + rec.offset + rec.length > size ) + throw new ErrorMsg( "HEX file defines data outside buffer limits! " + "Make sure file does not contain data outside device " + "memory limits. " + "Line from file was: (" + hexLine + ")." ); + + for( dataPos = 0; dataPos < rec.length; dataPos++ ) + data[ baseAddress + rec.offset + dataPos ] = rec.data[ dataPos ]; + + /* Update byte usage */ + if( baseAddress + rec.offset < start ) + start = baseAddress + rec.offset; + + if( baseAddress + rec.offset + rec.length - 1 > end ) + end = baseAddress + rec.offset + rec.length - 1; + + break; + + + case 0x02 : // Extended segment address record ? + baseAddress = (rec.data[0] << 8) | rec.data[1]; + baseAddress <<= 4; + break; + + case 0x03 : // Start segment address record ? + break; // Ignore it, since we have no influence on execution start address. + + case 0x04 : // Extended linear address record ? + baseAddress = (rec.data[0] << 8) | rec.data[1]; + baseAddress <<= 16; + break; + + case 0x05 : // Start linear address record ? + break; // Ignore it, since we have no influence on exectuion start address. + + case 0x01 : // End of file record ? + f.close(); + Util.progress( "\r\n" ); // Finish progress indicator. + return; + + default: + throw new ErrorMsg( "Unsupported HEX record format! " + "Line from file was: (" + hexLine + ")." ); + } + + f >> hexLine; // Read next line. + } + + + /* We should not end up here */ + throw new ErrorMsg( "Premature end of file encountered! Make sure file " + "contains an EOF-record." ); +} + + +void HEXFile::writeFile( const string & _filename ) +{ + ofstream f; + HEXRecord rec; // Temp record. + + long baseAddress; // Absolute data position. + long offset; // Offset from base address. + long dataPos; // Position inside data record. + + enum + { + _first, + _writing, + _passed64k + } status; // Write status, see usage below. + + /* Attempt to create file */ + f.open( _filename.c_str(), ios::out ); + if( !f ) + throw new ErrorMsg( "Error opening HEX file for output!" ); + + /* Prepare */ + status = _first; + rec.data = new unsigned char[ 16 ]; // Use only 16 byte records. + + baseAddress = start & ~0xffff; // 64K aligned address. + offset = start & 0xffff; // Offset from the aligned address. + dataPos = 0; + + /* Write first base address record to HEX file */ + rec.length = 2; + rec.offset = 0; + rec.type = 0x02; + rec.data[1] = 0x00; + rec.data[0] = baseAddress >> 12; // Give 4k page index. + writeRecord( f, &rec ); // Write the HEX record to file. + + + /* Write all bytes in used range */ + do + { + /* Put data into record */ + rec.data[ dataPos ] = data[ baseAddress + offset + dataPos ]; + dataPos++; + + /* Check if we need to write out the current data record */ + if( offset + dataPos >= 0x10000 || // Reached 64k boundary? + dataPos >= 16 || // Data record full? + baseAddress + offset + dataPos > end ) // End of used range reached? + { + /* Write current data record */ + rec.length = dataPos; + rec.offset = offset; + rec.type = 0x00; // Data record. + + Util.progress( "#" ); // Advance progress indicator. + writeRecord( f, &rec ); + + offset += dataPos; + dataPos = 0; + } + + /* Check if we have passed a 64k boundary */ + if( offset + dataPos >= 0x10000 ) + { + /* Update address pointers */ + offset -= 0x10000; + baseAddress += 0x10000; + + /* Write new base address record to HEX file */ + rec.length = 2; + rec.offset = 0; + rec.type = 0x02; + rec.data[0] = baseAddress >> 12; // Give 4k page index. + rec.data[1] = 0x00; + + writeRecord( f, &rec ); // Write the HEX record to file. + } + } while( baseAddress + offset + dataPos <= end ); + + + /* Write EOF record */ + rec.length = 0; + rec.offset = 0; + rec.type = 0x01; + + writeRecord( f, &rec ); + + f.close(); + Util.progress( "\r\n" ); // Finish progress indicator. +} + + +void HEXFile::setUsedRange( long _start, long _end ) +{ + if( _start < 0 || _end >= size || _start > _end ) + throw new ErrorMsg( "Invalid range! Start must be 0 or larger, end must be " + "inside allowed memory range." ); + + start = _start; + end = _end; +} + + +void HEXFile::clearAll( long value ) +{ + for( long i = 0; i < size; i++ ) + data[i] = (unsigned char) (value & 0xff); +} + + +long HEXFile::getData( long address ) +{ + if( address < 0 || address >= size ) + throw new ErrorMsg( "Address outside legal range!" ); + + return data[ address ]; +} + + +void HEXFile::setData( long address, long value ) +{ + if( address < 0 || address >= size ) + throw new ErrorMsg( "Address outside legal range!" ); + + data[ address ] = (unsigned char) (value & 0xff); +} + + +/* end of file */ + diff --git a/ports/bdk-atxx4-mstp/avrosp/HEXParser.hpp b/ports/bdk-atxx4-mstp/avrosp/HEXParser.hpp index 46406c6e..8f2a023b 100644 --- a/ports/bdk-atxx4-mstp/avrosp/HEXParser.hpp +++ b/ports/bdk-atxx4-mstp/avrosp/HEXParser.hpp @@ -1,67 +1,67 @@ -/***************************************************************************** - * - * Atmel Corporation - * - * File : HEXParser.hpp - * Compiler : Dev-C++ 4.9.8.0 - http://bloodshed.net/dev/ - * Revision : $Revision: 1163 $ - * Date : $Date: 2006-08-02 15:38:16 +0200 (on, 02 aug 2006) $ - * Updated by : $Author: ohlia $ - * - * Support mail : avr@atmel.com - * - * Target platform : Win32 - * - * AppNote : AVR911 - AVR Open-source Programmer - * - * Description : A simple Intel HEX file format reader/writer. - * - * - ****************************************************************************/ -#ifndef HEXPARSER_HPP -#define HEXPARSER_HPP - -using namespace std; - -#include "ErrorMsg.hpp" -#include "Utility.hpp" -#include -#include -#include - -struct HEXRecord; // Preliminary definition. - -class HEXFile -{ - protected: - unsigned char * data; // Holds the data bytes. - long start, end; // Used data range. - long size; // Size of databuffer. - - void writeRecord( ofstream & f, HEXRecord * recp ); - void parseRecord( const string & hexLine, HEXRecord * recp ); - - public: - /* Constructor */ - HEXFile( long buffersize, long value = 0xff ); - - /* Destructor */ - ~HEXFile(); - - /* Methods */ - void readFile( const string & _filename ); // Read data from HEX file. - void writeFile( const string & _filename ); // Write data to HEX file. - - void setUsedRange( long _start, long _end ); // Sets the used range. - void clearAll( long value = 0xff ); // Set databuffer to this value. - - long getRangeStart() { return start; } - long getRangeEnd() { return end; } - long getData( long address ); - void setData( long address, long value ); - long getSize() { return size; } -}; - - -#endif - +/***************************************************************************** + * + * Atmel Corporation + * + * File : HEXParser.hpp + * Compiler : Dev-C++ 4.9.8.0 - http://bloodshed.net/dev/ + * Revision : $Revision: 1163 $ + * Date : $Date: 2006-08-02 15:38:16 +0200 (on, 02 aug 2006) $ + * Updated by : $Author: ohlia $ + * + * Support mail : avr@atmel.com + * + * Target platform : Win32 + * + * AppNote : AVR911 - AVR Open-source Programmer + * + * Description : A simple Intel HEX file format reader/writer. + * + * + ****************************************************************************/ +#ifndef HEXPARSER_HPP +#define HEXPARSER_HPP + +using namespace std; + +#include "ErrorMsg.hpp" +#include "Utility.hpp" +#include +#include +#include + +struct HEXRecord; // Preliminary definition. + +class HEXFile +{ + protected: + unsigned char * data; // Holds the data bytes. + long start, end; // Used data range. + long size; // Size of databuffer. + + void writeRecord( ofstream & f, HEXRecord * recp ); + void parseRecord( const string & hexLine, HEXRecord * recp ); + + public: + /* Constructor */ + HEXFile( long buffersize, long value = 0xff ); + + /* Destructor */ + ~HEXFile(); + + /* Methods */ + void readFile( const string & _filename ); // Read data from HEX file. + void writeFile( const string & _filename ); // Write data to HEX file. + + void setUsedRange( long _start, long _end ); // Sets the used range. + void clearAll( long value = 0xff ); // Set databuffer to this value. + + long getRangeStart() { return start; } + long getRangeEnd() { return end; } + long getData( long address ); + void setData( long address, long value ); + long getSize() { return size; } +}; + + +#endif + diff --git a/ports/bdk-atxx4-mstp/avrosp/JobInfo.cpp b/ports/bdk-atxx4-mstp/avrosp/JobInfo.cpp index 82de6a77..1d4d4af9 100644 --- a/ports/bdk-atxx4-mstp/avrosp/JobInfo.cpp +++ b/ports/bdk-atxx4-mstp/avrosp/JobInfo.cpp @@ -1,1296 +1,1296 @@ -/***************************************************************************** - * - * Atmel Corporation - * - * File : JobInfo.cpp - * Compiler : Dev-C++ 4.9.8.0 - http://bloodshed.net/dev/ - * Revision : $Revision: 1163 $ - * Date : $Date: 2006-08-02 15:38:16 +0200 (on, 02 aug 2006) $ - * Updated by : $Author: ohlia $ - * - * Support mail : avr@atmel.com - * - * Target platform : Win32 - * - * AppNote : AVR911 - AVR Open-source Programmer - * - * Description : A class holding information on what the AVR Open-Source Programmer - * should do. The information is derived from the command-line. - * - * - ****************************************************************************/ -#include "JobInfo.hpp" - -#include - -#define VERSIONSTRING "$Revision: 1163 $" // For use in later text output. - -#define TIMEOUT 5 -#define TIMEOUTSTRING "5" - - -JobInfo::JobInfo() -{ - /* Initialize variables */ - showHelp = false; - silentMode = false; - noProgressIndicator = false; - readSignature = false; - chipErase = false; - getHWrevision = false; - getSWrevision = false; - programFlash = false; - programEEPROM = false; - readFlash = false; - readEEPROM = false; - verifyFlash = false; - verifyEEPROM = false; - readLockBits = false; - readFuseBits = false; - readOSCCAL = false; - - deviceName.erase(); - inputFileFlash.erase(); - inputFileEEPROM.erase(); - outputFileFlash.erase(); - outputFileEEPROM.erase(); - - OSCCAL_Parameter = -1; - OSCCAL_FlashAddress = -1; - OSCCAL_EEPROMAddress = -1; - - programLockBits = -1; - verifyLockBits = -1; - - programFuseBits = -1; - programExtendedFuseBits = -1; - verifyFuseBits = -1; - verifyExtendedFuseBits = -1; - - memoryFillPattern = -1; - - flashStartAddress = -1; - flashEndAddress = -1; - - eepromStartAddress = -1; - eepromEndAddress = -1; - - comPort = -1; -} - - - -void JobInfo::parseCommandline( int argc, char *argv[] ) -{ - char * param; // Temp string ptr for holding current parsed parameter. - int comma; // Temp position for comma separator in address ranges. - - /* Get application directory */ - string ownpath = argv[0]; - int slash_pos = ownpath.find_last_of( "\\/" ); // Search for last og / or \. - if( slash_pos == string::npos ) // Not found? - { - ownpath.assign( "." ); // The current directory is the AVROSP EXE path also. - } else - { - ownpath.erase( slash_pos ); // Remove from and including the last slash separator. - } - - searchpath.push_back( "." ); // Add current directory also. - searchpath.push_back( ownpath ); // Save for later. - - if( argc <= 1 ) - { - showHelp = true; - return; - } - - /* Iterate through cmdline parameters */ - for( int i = 1; i < argc; i++ ) - { - param = argv[i]; - - /* Allow parameters to start with '-' */ - if( param[0] != '-' ) - throw new ErrorMsg( "All parameters must start with '-'!" ); - - if( strlen( param ) <= 1 ) - throw new ErrorMsg( "Parameters cannot be just the minus without any characters!" ); - - /* Now for the parsing... */ - switch( param[1] ) - { - case 'a' : // Address range specified. - if( strlen( param ) <= 2 ) - throw new ErrorMsg( "Cannot use -a without memory type!" ); - - if( strlen( param ) <= 5 ) - throw new ErrorMsg( "Cannot use -a without start and end address!" ); - - /* Find comma position and set it to '0' to help hex conversion */ - comma = 2; - while( (param[comma] != 0) && (param[comma] != ',') ) - comma++; - - if( comma == strlen( param ) ) // No comma found? - throw new ErrorMsg( "No comma separator found in -a parameter!" ); - - param[comma] = 0; // It is now two separate strings for hex conversion. - - /* Convert limits */ - switch( param[2] ) - { - case 'f' : // Flash address range. - try - { - flashStartAddress = convertHex( param + 3 ); - } - catch( ErrorMsg * e ) - { - delete e; - throw new ErrorMsg( "Number format error in start limit for -af parameter!" ); - } - - try - { - flashEndAddress = convertHex( param + comma + 1 ); - } - catch( ErrorMsg * e ) - { - delete e; - throw new ErrorMsg( "Number format error in end limit for -af parameter!" ); - } - - if( flashEndAddress < flashStartAddress ) - throw new ErrorMsg( "Cannot have Flash end limit less than start limit!" ); - - break; - - case 'e' : // EEPROM address range. - try - { - eepromStartAddress = convertHex( param + 3 ); - } - catch( ErrorMsg * e ) - { - delete e; - throw new ErrorMsg( "Number format error in start limit for -ae parameter!" ); - } - - try - { - eepromEndAddress = convertHex( param + comma + 1 ); - } - catch( ErrorMsg * e ) - { - delete e; - throw new ErrorMsg( "Number format error in end limit for -ae parameter!" ); - } - - if( eepromEndAddress < eepromStartAddress ) - throw new ErrorMsg( "Cannot have EEPROM end limit less than start limit!" ); - - break; - - default: - throw new ErrorMsg( "Unknown choice for -a, use -af or -ae!" ); - - } - - break; - - - case 'b' : // Get revision. - if( strlen( param ) != 3 ) - throw new ErrorMsg( "Specify SW og HW revision, not just -b!" ); - - switch( param[2] ) - { - case 'h' : // Hardware revision. - getHWrevision = true; - break; - - case 's' : // Software revision. - getSWrevision = true; - break; - - default: - throw new ErrorMsg( "Unknown choice for -b, use -bs or -bh!" ); - } - - break; - - - case 'c' : // Specify COM port. - if (( strlen( param ) < 6 ) || (strlen( param ) > 7) || - (param[2] != 'C' || param[3] != 'O' || param[4] != 'M' ) || - (param[5] < '1' || param[5] > '9')) { - throw new ErrorMsg( "COM port parameter syntax is -cCOM1 to -cCOM99" ); - } - comPort = param[5] - '0'; // Convert COM port digit to number. - if (param[6] != 0) { - comPort = (comPort * 10) + param[6] - '0'; - } - break; - - - case 'd' : // Device name specified. - if( strlen( param ) <= 2 ) - throw new ErrorMsg( "Cannot use -d without the device name!" ); - - /* Copy device name string to class variable */ - deviceName.assign( param + 2 ); - break; - - - case 'e' : // Chip erase before programming. - if( strlen( param ) != 2 ) - throw new ErrorMsg( "Parameter -e needs no extra arguments!" ); - - chipErase = true; - break; - - - case 'E' : // Set extended fuse bits. - if( strlen( param ) != 4 ) - throw new ErrorMsg( "Use two hex digits for the -E parameter!" ); - - try - { - programExtendedFuseBits = convertHex( param + 2 ); - } - catch( ErrorMsg * e ) - { - delete e; - throw new ErrorMsg( "Hex number format error for -E parameter!" ); - } - - break; - - - case 'f' : // Set fuse bits. - if( strlen( param ) != 6 ) - throw new ErrorMsg( "Use four hex digits for the -f parameter!" ); - - try - { - programFuseBits = convertHex( param + 2 ); - } - catch( ErrorMsg * e ) - { - delete e; - throw new ErrorMsg( "Hex number format error for -f parameter!" ); - } - - break; - - - case 'F' : // Verify fuse bits. - if( strlen( param ) != 6 ) - throw new ErrorMsg( "Use four hex digits for the -F parameter!" ); - - try - { - verifyFuseBits = convertHex( param + 2 ); - } - catch( ErrorMsg * e ) - { - delete e; - throw new ErrorMsg( "Hex number format error for -F parameter!" ); - } - - break; - - - case 'g' : // Silent operation. - if( strlen( param ) != 2 ) - throw new ErrorMsg( "Parameter -g needs no extra arguments!" ); - - silentMode = true; - break; - - - case 'G' : // Verify extended fuse bits. - if( strlen( param ) != 4 ) - throw new ErrorMsg( "Use two hex digits for the -G parameter!" ); - - try - { - verifyExtendedFuseBits = convertHex( param + 2 ); - } - catch( ErrorMsg * e ) - { - delete e; - throw new ErrorMsg( "Hex number format error for -G parameter!" ); - } - - break; - - - case 'h' : // Help screen. - case '?' : // Help screen. - if( strlen( param ) != 2 ) - throw new ErrorMsg( "Parameter -h and -? needs no extra arguments!" ); - - showHelp = true; - break; - - - case 'i' : // Input file specified. - if( strlen( param ) <= 2 ) - throw new ErrorMsg( "Cannot use -i without memory type!" ); - - if( strlen( param ) <= 3 ) - throw new ErrorMsg( "Cannot use -i without file name!" ); - - /* Copy file name string to correct class variable */ - switch( param[2] ) - { - case 'f' : // Flash input file. - inputFileFlash.assign( param + 3 ); - break; - - case 'e' : // EEPROM input file. - inputFileEEPROM.assign( param + 3 ); - break; - - default: - throw new ErrorMsg( "Unknown choice for -i, use -if or -ie!" ); - } - - break; - - - case 'l' : // Set lock bits. - if( strlen( param ) != 4 ) - throw new ErrorMsg( "Use two hex digits for the -l parameter!" ); - - try - { - programLockBits = convertHex( param + 2 ); - } - catch( ErrorMsg * e ) - { - delete e; - throw new ErrorMsg( "Hex number format error for -l parameter!" ); - } - - break; - - - case 'L' : // Verify lock bits. - if( strlen( param ) != 4 ) - throw new ErrorMsg( "Use two hex digits for the -l parameter!" ); - - try - { - verifyLockBits = convertHex( param + 2 ); - } - catch( ErrorMsg * e ) - { - delete e; - throw new ErrorMsg( "Hex number format error for -L parameter!" ); - } - - break; - - - case 'o' : // Output file specified. - if( strlen( param ) <= 2 ) - throw new ErrorMsg( "Cannot use -o without memory type!" ); - - if( strlen( param ) <= 3 ) - throw new ErrorMsg( "Cannot use -o without file name!" ); - - /* Copy file name string to correct class variable */ - switch( param[2] ) - { - case 'f' : // Flash output file. - outputFileFlash.assign( param + 3 ); - break; - - case 'e' : // EEPROM output file. - outputFileEEPROM.assign( param + 3 ); - break; - - default: - throw new ErrorMsg( "Unknown choice for -o, use -of or -oe!" ); - } - - break; - - - case 'O' : // Read OSCCAL byte. - switch( strlen( param ) ) - { - case 2 : // No value specified, use first OSCCAL byte. - readOSCCAL = true; - OSCCAL_Parameter = 0; // First OSCCAL byte. - break; - - case 3 : // Byte index specified. - case 4 : - readOSCCAL = true; - try - { - OSCCAL_Parameter = convertHex( param + 2 ); - } - catch( ErrorMsg * e ) - { - delete e; - throw new ErrorMsg( "Hex number format error for -O parameter!" ); - } - - break; - - - case 5 : // Direct value specified. - if( param[2] != '#' ) - throw new ErrorMsg( "Use one or two hex digits for -O and two for -O#!" ); - - readOSCCAL = false; - try - { - OSCCAL_Parameter = convertHex( param + 3 ); - } - catch( ErrorMsg * e ) - { - delete e; - throw new ErrorMsg( "Hex number format error for -O# parameter!" ); - } - - break; - - default: - throw new ErrorMsg( "Invalid use of -O or -O# parameter!" ); - } - - break; - - - case 'p' : // Program data. - if( strlen( param ) != 3 ) - throw new ErrorMsg( "Specify memory type, not just -p!" ); - - switch( param[2] ) - { - case 'f' : // Program Flash memory. - programFlash = true; - break; - - case 'e' : // Program EEPROM memory. - programEEPROM = true; - break; - - case 'b' : // Both. - programFlash = true; - programEEPROM = true; - break; - - default: - throw new ErrorMsg( "Unknown choice for -p, use -pf, -pe or -pb!" ); - } - - break; - - - case 'q' : // Read all fuse bits. - if( strlen( param ) != 2 ) - throw new ErrorMsg( "Parameter -q needs no extra arguments!" ); - - readFuseBits = true; - break; - - - case 'r' : // Read data. - if( strlen( param ) != 3 ) - throw new ErrorMsg( "Specify memory type, not just -r!" ); - - switch( param[2] ) - { - case 'f' : // Read Flash memory. - readFlash = true; - break; - - case 'e' : // Read EEPROM memory. - readEEPROM = true; - break; - - case 'b' : // Both. - readFlash = true; - readEEPROM = true; - break; - - default: - throw new ErrorMsg( "Unknown choice for -r, use -rf, -re or -rb!" ); - } - - break; - - - case 's' : // Read signature byte. - if( strlen( param ) != 2 ) - throw new ErrorMsg( "Parameter -s needs no extra arguments!" ); - - readSignature = true; - break; - - - case 'S' : // Write OSCCAL byte to memory. - if( strlen( param ) <= 2 ) - throw new ErrorMsg( "Cannot use -S without memory type!" ); - - if( strlen( param ) <= 3 ) - throw new ErrorMsg( "Cannot use -S without byte address!" ); - - switch( param[2] ) - { - case 'f' : // Write to Flash address. - try - { - OSCCAL_FlashAddress = convertHex( param + 3 ); - } - catch( ErrorMsg * e ) - { - delete e; - throw new ErrorMsg( "Cannot convert hex number for -Sf parameter!" ); - } - break; - - case 'e' : // Write to EEPROM address. - try - { - OSCCAL_EEPROMAddress = convertHex( param + 3 ); - } - catch( ErrorMsg * e ) - { - delete e; - throw new ErrorMsg( "Cannot convert hex number for -Se parameter!" ); - } - break; - - default: - throw new ErrorMsg( "Unknown choice for -S, use -Sf or -Se!" ); - } - - break; - - - case 'v' : // Verify data. - if( strlen( param ) != 3 ) - throw new ErrorMsg( "Specify memory type, not just -v!" ); - - switch( param[2] ) - { - case 'f' : // Verify Flash memory. - verifyFlash = true; - break; - - case 'e' : // Verify EEPROM memory. - verifyEEPROM = true; - break; - - case 'b' : // Both. - verifyFlash = true; - verifyEEPROM = true; - break; - - default: - throw new ErrorMsg( "Unknown choice for -v, use -vf, -ve or -vb!" ); - } - - break; - - - case 'x' : // Fill unspecified memory. - if( strlen( param ) != 4 ) - throw new ErrorMsg( "Use two hex digits for the -x parameter!" ); - - try - { - memoryFillPattern = convertHex( param + 2 ); - } - catch( ErrorMsg * e ) - { - delete e; - throw new ErrorMsg( "Hex number format error for -x parameter!" ); - } - - break; - - - case 'y' : // Read lock bits. - if( strlen( param ) != 2 ) - throw new ErrorMsg( "Parameter -y needs no extra arguments!" ); - - readLockBits = true; - break; - - - case 'z' : // No progress indicator? - if( strlen( param ) != 2 ) - throw new ErrorMsg( "Parameter -z needs no extra arguments!" ); - - noProgressIndicator = true; - break; - - - default: - throw new ErrorMsg( "Unknow parameter!" ); - } - } -} - - -void JobInfo::help() -{ - cout - << "Command Line Switches:" << endl - << " [-d device name] [-if infile] [-ie infile] [-of outfile] [-oe outfile]" << endl - << " [-s] [-O index] [-O#value] [-Sf addr] [-Se addr] [-e] [-p f|e|b]" << endl - << " [-r f|e|b] [-v f|e|b] [-l value] [-L value] [-y] [-f value] [-E value]" << endl - << " [-F value] [-G value] [-q] [-x value] [-af start,stop] [-ae start,stop]" << endl - << " [-c port] [-b h|s] [-g] [-z] [-h|?]" << endl - << endl - << "Parameters:" << endl - << "d Device name. Must be applied when programming the device." << endl - << "if Name of FLASH input file. Required for programming or verification" << endl - << " of the FLASH memory. The file format is Intel Extended HEX." << endl - << "ie Name of EEPROM input file. Required for programming or verification" << endl - << " of the EEPROM memory. The file format is Intel Extended HEX." << endl - << "of Name of FLASH output file. Required for readout of the FLASH memory." << endl - << " The file format is Intel Extended HEX." << endl - << "oe Name of EEPROM output file. Required for readout of the EEPROM" << endl - << " memory. The file format is Intel Extended HEX." << endl - << "s Read signature bytes." << endl; - getch(); - cout - << "O Read oscillator calibration byte. 'index' is optional." << endl - << "O# User-defined oscillator calibration value." << endl - << "Sf Write oscillator cal. byte to FLASH memory. 'addr' is byte address." << endl - << "Se Write oscillator cal. byte to EEPROM memory. 'addr' is byte address." << endl - << "e Erase device. If applied with another programming parameter, the" << endl - << " device will be erased before any other programming takes place." << endl - << "p Program device; FLASH (f), EEPROM (e) or both (b). Corresponding" << endl - << " input files are required." << endl - << "r Read out device; FLASH (f), EEPROM (e) or both (b). Corresponding" << endl - << " output files are required" << endl - << "v Verify device; FLASH (f), EEPROM (e) or both (b). Can be used with" << endl - << " -p or alone. Corresponding input files are required." << endl - << "l Set lock byte. 'value' is an 8-bit hex. value." << endl - << "L Verify lock byte. 'value' is an 8-bit hex. value to verify against." << endl - << "y Read back lock byte." << endl - << "f Set fuse bytes. 'value' is a 16-bit hex. value describing the" << endl - << " settings for the upper and lower fuse bytes." << endl - << "E Set extended fuse byte. 'value' is an 8-bit hex. value describing the" << endl - << " extend fuse settings." << endl - << "F Verify fuse bytes. 'value' is a 16-bit hex. value to verify against." << endl; - getch(); - cout - << "G Verify extended fuse byte. 'value' is an 8-bit hex. value to" << endl - << " verify against." << endl - << "q Read back fuse bytes." << endl - << "x Fill unspecified locations with a value (00-ff). The default is" << endl - << " to not program locations not specified in the input files." << endl - << "af FLASH address range. Specifies the address range of operations. The" << endl - << " default is the entire FLASH. Byte addresses in hex." << endl - << "ae EEPROM address range. Specifies the address range of operations." << endl - << " The default is the entire EEPROM. Byte addresses in hex." << endl - << "c Select communication port; 'COM1' to 'COM99'. If this parameter is" << endl - << " omitted the program will scan the COM ports for a programmer." << endl - << "b Get revisions; hardware revision (h) and software revision (s)." << endl - << "g Silent operation." << endl - << "z No progress indicator. E.g. if piping to a file for log purposes, use" << endl - << " this option to avoid the characters used for the indicator." << endl - << "h|? Help information (overrides all other settings)." << endl - << endl - << "Example:" << endl - << " AVROSP -dATmega128 -ifmyapp.hex -pf" << endl; -} - - -long JobInfo::convertHex( char * txt ) -{ - string t( txt ); - return Util.convertHex( t ); -} - - -void JobInfo::doJob() -{ - long scanCOM; - SerialPort * com; - AVRProgrammer * prog; - AVRDevice * avr; - string programmerID; - long sig0, sig1, sig2; // Signature bytes. - - /* Set correct silent and progress indicator status */ - if( silentMode ) - { - Util.muteLog(); - Util.muteProgress(); // Silent also includes progress indicator. - } - - if( noProgressIndicator ) - Util.muteProgress(); - - /* Application header text */ - Util.log( "AVR Open-source Programmer " VERSIONSTRING " (C) 2004 Atmel Corp.\n\r\n\r" ); - - /* Show help screen? */ - if( showHelp ) - { - help(); - return; - } - - Util.log( "Serial port timeout set to " TIMEOUTSTRING " sec.\r\n" ); - - /* Need to scan for COM port? */ - if( comPort == -1 ) - { - Util.log( "Scanning COM ports for supported programmer...\n\r" ); - - for( scanCOM = 1; scanCOM <= 99; scanCOM++ ) - { - Util.progress( "COM" + Util.convertLong( scanCOM ) + "...\r\n" ); - - try - { - /* Try to communicate */ - com = NULL; - com = new SerialPort( scanCOM, TIMEOUT ); - com->openChannel(); - programmerID = AVRProgrammer::readProgrammerID( com ); - - /* Contact! Check ID... Add custom handler signatures here */ - if( programmerID == "AVRBOOT" || programmerID == "AVR ISP" ) - { - break; - } - - delete com; - Util.progress( programmerID + " found - not supported!\r\n" ); - } - catch( ErrorMsg * e ) - { - /* No contact on COM port, skip to next */ - if( com != NULL ) delete com; - delete e; - } - } - - /* Exit if no supported programmers found */ - if( scanCOM > 99 ) - { - Util.log( "No supported programmers found!\r\n" ); - return; - } - - comPort = scanCOM; - - } else // ... COM port is specified - { - /* Try to communicate, errors will propagate to caller */ - com = new SerialPort( comPort, TIMEOUT ); - com->openChannel(); - programmerID = AVRProgrammer::readProgrammerID( com ); - - /* Contact! Check ID */ - if( programmerID != "AVRBOOT" && programmerID != "AVR ISP" ) - throw new ErrorMsg( "Programmer not supported!" ); - } - - Util.log( "Found " + programmerID + " on COM" + Util.convertLong( comPort ) + "!\r\n" ); - - /* Create programmer interface object, add custom handlers here */ - if( programmerID == "AVRBOOT" ) - { - prog = new AVRBootloader( com ); - } - - if( programmerID == "AVR ISP" ) - { - prog = new AVRInSystemProg( com ); - } - - Util.log( "Entering programming mode...\r\n" ); - prog->enterProgrammingMode(); // Ignore return code. - - /* Do device independent operations */ - doDeviceIndependent( prog ); - - /* Finished if no device name is specified */ - if( deviceName.size() == 0 ) - { - Util.log( "Device name not specified!\r\n" ); - return; - } - - /* Parse XML part description file */ - avr = new AVRDevice( deviceName ); - Util.log( "Parsing XML file for device parameters...\r\n" ); - Util.parsePath( searchpath ); - avr->readParametersFromAVRStudio( searchpath ); - - /* Verify that the device signature matches the signature from the XML file */ - avr->getSignature( &sig0, &sig1, &sig2 ); - if( prog->checkSignature( sig0, sig1, sig2 ) ) - Util.log( "Signature matches device!\r\n" ); - - /* Do device dependent operations */ - doDeviceDependent( prog, avr ); - - /* Clean up */ - Util.log( "Leaving programming mode...\r\n" ); - prog->leaveProgrammingMode(); // Ignore return code. - - delete avr; - delete prog; - delete com; -} - - -void JobInfo::doDeviceIndependent( AVRProgrammer * prog ) -{ - long sig0, sig1, sig2; // Signature bytes. - long minor, major; // Minor and major programmer revision. - - /* Read signature? */ - if( readSignature ) - { - Util.log( "Reading signature bytes: " ); - if( !prog->readSignature( &sig0, &sig1, &sig2 ) ) - throw new ErrorMsg( "Signature readout is not supported by this programmer!" ); - - /* No pass through Util, since user wants the info */ - cout.fill( '0' ); - cout << hex - << "0x" << setw(2) << sig0 << " " - << "0x" << setw(2) << sig1 << " " - << "0x" << setw(2) << sig2 << endl; - } - - /* Get software version? */ - if( getSWrevision ) - { - Util.log( "Reading programmer software revision: " ); - if( !prog->programmerSoftwareVersion( &major, &minor ) ) - throw new ErrorMsg( "Software revision readout is not supported by this programmer!" ); - - /* No pass through Util, since user wants the info */ - cout << (char) (major & 0xff) << "." << (char) (minor & 0xff) << endl; - } - - /* Get software version? */ - if( getHWrevision ) - { - Util.log( "Reading programmer hardware revision: " ); - if( !prog->programmerHardwareVersion( &major, &minor ) ) - throw new ErrorMsg( "Hardware revision readout is not supported by this programmer!" ); - - /* No pass through Util, since user wants the info */ - cout << (char) (major & 0xff) << "." << (char) (minor & 0xff) << endl; - } -} - - -void JobInfo::doDeviceDependent( AVRProgrammer * prog, AVRDevice * avr ) -{ - HEXFile * hex; - HEXFile * hex_v; // Used for verifying memory contents. - long pos; // Used when comparing data. - long bits; // Used for lock and fuse bits. - - /* Set programmer pagesize */ - prog->setPagesize( avr->getPageSize() ); - - /* Check if specified address limits are within device range */ - if( flashEndAddress != -1 ) - { - if( flashEndAddress >= avr->getFlashSize() ) - throw new ErrorMsg( "Specified Flash address range is outside device address space!" ); - } else - { - flashStartAddress = 0; - flashEndAddress = avr->getFlashSize() - 1; - } - - if( eepromEndAddress != -1 ) - { - if( eepromEndAddress >= avr->getEEPROMSize() ) - throw new ErrorMsg( "Specified EEPROM address range is outside device address space!" ); - } else - { - eepromStartAddress = 0; - eepromEndAddress = avr->getEEPROMSize() - 1; - } - - - /* Read out Flash contents? */ - if( readFlash ) - { - /* Check that filename has been specified */ - if( outputFileFlash.size() == 0 ) - throw new ErrorMsg( "Cannot read Flash without output file specified!" ); - - /* Prepare the file */ - hex = new HEXFile( avr->getFlashSize() ); - hex->setUsedRange( flashStartAddress, flashEndAddress ); - - /* Read data and save file */ - Util.log( "Reading Flash contents...\r\n" ); - if( !prog->readFlash( hex ) ) - throw new ErrorMsg( "Flash readout is not supported by this programmer!" ); - Util.log( "Writing HEX output file...\r\n" ); - hex->writeFile( outputFileFlash ); - - delete hex; - } - - - /* Read out EEPROM contents? */ - if( readEEPROM ) - { - /* Check that filename has been specified */ - if( outputFileEEPROM.size() == 0 ) - throw new ErrorMsg( "Cannot read EEPROM without output file specified!" ); - - /* Prepare the file */ - hex = new HEXFile( avr->getEEPROMSize() ); - hex->setUsedRange( eepromStartAddress, eepromEndAddress ); - - /* Read data and save file */ - Util.log( "Reading EEPROM contents...\r\n" ); - if( !prog->readEEPROM( hex ) ) - throw new ErrorMsg( "EEPROM readout is not supported by this programmer!" ); - Util.log( "Writing HEX output file...\r\n" ); - hex->writeFile( outputFileEEPROM ); - - delete hex; - } - - - /* Read lock bits? */ - if( readLockBits ) - { - Util.log( "Reading lock bits...\r\n" ); - if( !prog->readLockBits( &bits ) ) - throw new ErrorMsg( "Lock bit readout is not supported by this programmer!" ); - cout << "0x" << std::hex << setw(2) << bits << endl; - } - - - /* Read fuse bits (both ordinary and extended)? */ - if( readFuseBits ) - { - if( !avr->getFuseStatus() ) - throw new ErrorMsg( "Selected device has no fuse bits!" ); - - Util.log( "Reading fuse bits...\r\n" ); - if( !prog->readFuseBits( &bits ) ) - throw new ErrorMsg( "Fuse bit readout is not supported by this programmer!" ); - cout << "0x" << std::hex << setw(4) << bits << endl; - - if( avr->getXFuseStatus() ) - { - if( !prog->readExtendedFuseBits( &bits ) ) - throw new ErrorMsg( "Extended fuse bit readout is not supported by this programmer!" ); - cout << "0x" << std::hex << setw(2) << bits << endl; - } - } - - - /* Erase chip before programming anything? */ - if( chipErase ) - { - Util.log( "Erasing chip contents...\r\n" ); - if( !prog->chipErase() ) - throw new ErrorMsg( "Chip erase is not supported by this programmer!" ); - } - - - /* Prepare input hex file for flash */ - if( programFlash || verifyFlash ) - { - /* Check that filename has been specified */ - if( inputFileFlash.size() == 0 ) - throw new ErrorMsg( "Cannot program or verify Flash without input file specified!" ); - - /* Prepare the file */ - hex = new HEXFile( avr->getFlashSize() ); - - /* Fill if wanted */ - if( memoryFillPattern != -1 ) - hex->clearAll( memoryFillPattern ); - - /* Read file */ - Util.log( "Reading HEX input file for flash operations...\r\n" ); - hex->readFile( inputFileFlash ); - - /* Check limits */ - if( hex->getRangeStart() > flashEndAddress || - hex->getRangeEnd() < flashStartAddress ) - throw new ErrorMsg( "HEX file defines data outside specified range!" ); - - if( memoryFillPattern == -1 ) - { - if( hex->getRangeStart() > flashStartAddress ) - flashStartAddress = hex->getRangeStart(); - - if( hex->getRangeEnd() < flashEndAddress ) - flashEndAddress = hex->getRangeEnd(); - } - - hex->setUsedRange( flashStartAddress, flashEndAddress ); - } - - - /* Program new Flash contents? */ - if( programFlash ) - { - /* Program data */ - Util.log( "Programming Flash contents...\r\n" ); - if( !prog->writeFlash( hex ) ) - throw new ErrorMsg( "Flash programming is not supported by this programmer!" ); - } - - - /* Verify Flash contents? */ - if( verifyFlash ) - { - /* Prepare HEX file for comparision */ - hex_v = new HEXFile( avr->getFlashSize() ); - - /* Compare to Flash */ - Util.log( "Reading Flash contents...\r\n" ); - hex_v->setUsedRange( hex->getRangeStart(), hex->getRangeEnd() ); - if( !prog->readFlash( hex_v ) ) - throw new ErrorMsg( "Flash readout is not supported by this programmer!" ); - - /* Compare data */ - Util.log( "Comparing Flash data...\r\n" ); - - for( pos = hex->getRangeStart(); pos <= hex->getRangeEnd(); pos++ ) - { - if( hex->getData( pos ) != hex_v->getData( pos ) ) - { - cout << "Unequal at address 0x" << std::hex << pos << "!" << endl; - break; - } - } - - if( pos > hex->getRangeEnd() ) // All equal? - { - cout << "Equal!" << endl; - } - - delete hex_v; - } - - if( programFlash || verifyFlash ) - delete hex; - - - /* Prepare input hex file for EEPROM */ - if( programEEPROM || verifyEEPROM ) - { - /* Check that filename has been specified */ - if( inputFileEEPROM.size() == 0 ) - throw new ErrorMsg( "Cannot program or verify EEPROM without input file specified!" ); - - /* Prepare the file */ - hex = new HEXFile( avr->getEEPROMSize() ); - - /* Fill if wanted */ - if( memoryFillPattern != -1 ) - hex->clearAll( memoryFillPattern ); - - /* Read file and program contents */ - Util.log( "Reading HEX input file for EEPROM operations...\r\n" ); - hex->readFile( inputFileEEPROM ); - - /* Check limits */ - if( hex->getRangeStart() > eepromEndAddress || - hex->getRangeEnd() < eepromStartAddress ) - throw new ErrorMsg( "HEX file defines data outside specified range!" ); - - if( memoryFillPattern == -1 ) - { - if( hex->getRangeStart() > eepromStartAddress ) - eepromStartAddress = hex->getRangeStart(); - - if( hex->getRangeEnd() < eepromEndAddress ) - eepromEndAddress = hex->getRangeEnd(); - } - - hex->setUsedRange( eepromStartAddress, eepromEndAddress ); - } - - - /* Program new EEPROM contents? */ - if( programEEPROM ) - { - /* Program data */ - Util.log( "Programming EEPROM contents...\r\n" ); - if( !prog->writeEEPROM( hex ) ) - throw new ErrorMsg( "EEPROM programming is not supported by this programmer!" ); - } - - /* Verify EEPROM contents? */ - if( verifyEEPROM ) - { - /* Prepare HEX file for comparision */ - hex_v = new HEXFile( avr->getEEPROMSize() ); - - /* Compare to EEPROM */ - Util.log( "Reading EEPROM contents...\r\n" ); - hex_v->setUsedRange( hex->getRangeStart(), hex->getRangeEnd() ); - if( !prog->readEEPROM( hex_v ) ) - throw new ErrorMsg( "EEPROM readout is not supported by this programmer!" ); - - /* Compare data */ - Util.log( "Comparing EEPROM data...\r\n" ); - for( pos = hex->getRangeStart(); pos <= hex->getRangeEnd(); pos++ ) - { - if( hex->getData( pos ) != hex_v->getData( pos ) ) - { - cout << "Unequal at address 0x" << std::hex << pos << "!" << endl; - break; - } - } - - if( pos > hex->getRangeEnd() ) // All equal? - { - cout << "Equal!" << endl; - } - - delete hex_v; - } - - if( programEEPROM || verifyEEPROM ) - delete hex; - - - /* Program lock bits */ - if( programLockBits != -1 ) - { - Util.log( "Programming lock bits...\r\n" ); - if( !prog->writeLockBits( programLockBits ) ) - throw new ErrorMsg( "Lock bit programming is not supported by this programmer!" ); - } - - - /* Program fuse bits */ - if( programFuseBits != -1 ) - { - if( !avr->getFuseStatus() ) - throw new ErrorMsg( "Selected device has no fuse bits!" ); - - Util.log( "Programming fuse bits...\r\n" ); - if( !prog->writeFuseBits( programFuseBits ) ) - throw new ErrorMsg( "Fuse bit programming is not supported by this programmer!" ); - } - - - /* Program extended fuse bits */ - if( programExtendedFuseBits != -1 ) - { - if( !avr->getXFuseStatus() ) - throw new ErrorMsg( "Selected device has no extended fuse bits!" ); - - Util.log( "Programming extended fuse bits...\r\n" ); - if( !prog->writeExtendedFuseBits( programExtendedFuseBits ) ) - throw new ErrorMsg( "Extended fuse bit programming is not supported by this programmer!" ); - } - - - /* Verify lock bits */ - if( verifyLockBits != -1 ) - { - Util.log( "Verifying lock bits...\r\n" ); - if( !prog->readLockBits( &bits ) ) - throw new ErrorMsg( "Lock bit readout is not supported by this programmer!" ); - if( bits == verifyLockBits ) - cout << "Equal!" << endl; - else - cout << "Unequal!" << endl; - } - - - /* Verify fuse bits */ - if( verifyFuseBits != -1 ) - { - if( !avr->getFuseStatus() ) - throw new ErrorMsg( "Selected device has no fuse bits!" ); - - Util.log( "Verifying fuse bits...\r\n" ); - if( !prog->readFuseBits( &bits ) ) - throw new ErrorMsg( "Fuse bit readout is not supported by this programmer!" ); - if( bits == verifyFuseBits ) - cout << "Equal!" << endl; - else - cout << "Unequal!" << endl; - } - - - /* Verify extended fuse bits */ - if( verifyExtendedFuseBits != -1 ) - { - if( !avr->getXFuseStatus() ) - throw new ErrorMsg( "Selected device has no extended fuse bits!" ); - - Util.log( "Verifying extended fuse bits...\r\n" ); - if( !prog->readExtendedFuseBits( &bits ) ) - throw new ErrorMsg( "Extended fuse bit readout is not supported by this programmer!" ); - if( bits == verifyExtendedFuseBits ) - cout << "Equal!" << endl; - else - cout << "Unequal!" << endl; - } - - - /* Read osccal value? */ - if( OSCCAL_Parameter != -1 ) - { - /* Output to log if read from device */ - if( readOSCCAL ) - { - Util.log( "Reading OSCCAL from device...\r\n" ); - pos = OSCCAL_Parameter; - if( !prog->readOSCCAL( pos, &OSCCAL_Parameter ) ) - throw new ErrorMsg( "OSCCAL parameter readout is not supported by this programmer!" ); - cout << "0x" << std::hex << setw(2) << OSCCAL_Parameter << endl; - } - } - - - /* Write OSCCAL to Flash? */ - if( OSCCAL_FlashAddress != -1 ) - { - if( OSCCAL_Parameter == -1 ) - throw new ErrorMsg( "OSCCAL value not specified!" ); - - Util.log( "Programming OSCCAL value to Flash...\r\n" ); - if( !prog->writeFlashByte( OSCCAL_FlashAddress, OSCCAL_Parameter ) ) - throw new ErrorMsg( "Flash programming is not supported by this programmer!" ); - } - - - /* Write OSCCAL to EEPROM? */ - if( OSCCAL_EEPROMAddress != -1 ) - { - if( OSCCAL_Parameter == -1 ) - throw new ErrorMsg( "OSCCAL value not specified!" ); - - Util.log( "Programming OSCCAL value to EEPROM...\r\n" ); - if( !prog->writeEEPROMByte( OSCCAL_EEPROMAddress, OSCCAL_Parameter ) ) - throw new ErrorMsg( "EEPROM programming is not supported by this programmer!" ); - } - -} - - -/* end of file */ - +/***************************************************************************** + * + * Atmel Corporation + * + * File : JobInfo.cpp + * Compiler : Dev-C++ 4.9.8.0 - http://bloodshed.net/dev/ + * Revision : $Revision: 1163 $ + * Date : $Date: 2006-08-02 15:38:16 +0200 (on, 02 aug 2006) $ + * Updated by : $Author: ohlia $ + * + * Support mail : avr@atmel.com + * + * Target platform : Win32 + * + * AppNote : AVR911 - AVR Open-source Programmer + * + * Description : A class holding information on what the AVR Open-Source Programmer + * should do. The information is derived from the command-line. + * + * + ****************************************************************************/ +#include "JobInfo.hpp" + +#include + +#define VERSIONSTRING "$Revision: 1163 $" // For use in later text output. + +#define TIMEOUT 5 +#define TIMEOUTSTRING "5" + + +JobInfo::JobInfo() +{ + /* Initialize variables */ + showHelp = false; + silentMode = false; + noProgressIndicator = false; + readSignature = false; + chipErase = false; + getHWrevision = false; + getSWrevision = false; + programFlash = false; + programEEPROM = false; + readFlash = false; + readEEPROM = false; + verifyFlash = false; + verifyEEPROM = false; + readLockBits = false; + readFuseBits = false; + readOSCCAL = false; + + deviceName.erase(); + inputFileFlash.erase(); + inputFileEEPROM.erase(); + outputFileFlash.erase(); + outputFileEEPROM.erase(); + + OSCCAL_Parameter = -1; + OSCCAL_FlashAddress = -1; + OSCCAL_EEPROMAddress = -1; + + programLockBits = -1; + verifyLockBits = -1; + + programFuseBits = -1; + programExtendedFuseBits = -1; + verifyFuseBits = -1; + verifyExtendedFuseBits = -1; + + memoryFillPattern = -1; + + flashStartAddress = -1; + flashEndAddress = -1; + + eepromStartAddress = -1; + eepromEndAddress = -1; + + comPort = -1; +} + + + +void JobInfo::parseCommandline( int argc, char *argv[] ) +{ + char * param; // Temp string ptr for holding current parsed parameter. + int comma; // Temp position for comma separator in address ranges. + + /* Get application directory */ + string ownpath = argv[0]; + int slash_pos = ownpath.find_last_of( "\\/" ); // Search for last og / or \. + if( slash_pos == string::npos ) // Not found? + { + ownpath.assign( "." ); // The current directory is the AVROSP EXE path also. + } else + { + ownpath.erase( slash_pos ); // Remove from and including the last slash separator. + } + + searchpath.push_back( "." ); // Add current directory also. + searchpath.push_back( ownpath ); // Save for later. + + if( argc <= 1 ) + { + showHelp = true; + return; + } + + /* Iterate through cmdline parameters */ + for( int i = 1; i < argc; i++ ) + { + param = argv[i]; + + /* Allow parameters to start with '-' */ + if( param[0] != '-' ) + throw new ErrorMsg( "All parameters must start with '-'!" ); + + if( strlen( param ) <= 1 ) + throw new ErrorMsg( "Parameters cannot be just the minus without any characters!" ); + + /* Now for the parsing... */ + switch( param[1] ) + { + case 'a' : // Address range specified. + if( strlen( param ) <= 2 ) + throw new ErrorMsg( "Cannot use -a without memory type!" ); + + if( strlen( param ) <= 5 ) + throw new ErrorMsg( "Cannot use -a without start and end address!" ); + + /* Find comma position and set it to '0' to help hex conversion */ + comma = 2; + while( (param[comma] != 0) && (param[comma] != ',') ) + comma++; + + if( comma == strlen( param ) ) // No comma found? + throw new ErrorMsg( "No comma separator found in -a parameter!" ); + + param[comma] = 0; // It is now two separate strings for hex conversion. + + /* Convert limits */ + switch( param[2] ) + { + case 'f' : // Flash address range. + try + { + flashStartAddress = convertHex( param + 3 ); + } + catch( ErrorMsg * e ) + { + delete e; + throw new ErrorMsg( "Number format error in start limit for -af parameter!" ); + } + + try + { + flashEndAddress = convertHex( param + comma + 1 ); + } + catch( ErrorMsg * e ) + { + delete e; + throw new ErrorMsg( "Number format error in end limit for -af parameter!" ); + } + + if( flashEndAddress < flashStartAddress ) + throw new ErrorMsg( "Cannot have Flash end limit less than start limit!" ); + + break; + + case 'e' : // EEPROM address range. + try + { + eepromStartAddress = convertHex( param + 3 ); + } + catch( ErrorMsg * e ) + { + delete e; + throw new ErrorMsg( "Number format error in start limit for -ae parameter!" ); + } + + try + { + eepromEndAddress = convertHex( param + comma + 1 ); + } + catch( ErrorMsg * e ) + { + delete e; + throw new ErrorMsg( "Number format error in end limit for -ae parameter!" ); + } + + if( eepromEndAddress < eepromStartAddress ) + throw new ErrorMsg( "Cannot have EEPROM end limit less than start limit!" ); + + break; + + default: + throw new ErrorMsg( "Unknown choice for -a, use -af or -ae!" ); + + } + + break; + + + case 'b' : // Get revision. + if( strlen( param ) != 3 ) + throw new ErrorMsg( "Specify SW og HW revision, not just -b!" ); + + switch( param[2] ) + { + case 'h' : // Hardware revision. + getHWrevision = true; + break; + + case 's' : // Software revision. + getSWrevision = true; + break; + + default: + throw new ErrorMsg( "Unknown choice for -b, use -bs or -bh!" ); + } + + break; + + + case 'c' : // Specify COM port. + if (( strlen( param ) < 6 ) || (strlen( param ) > 7) || + (param[2] != 'C' || param[3] != 'O' || param[4] != 'M' ) || + (param[5] < '1' || param[5] > '9')) { + throw new ErrorMsg( "COM port parameter syntax is -cCOM1 to -cCOM99" ); + } + comPort = param[5] - '0'; // Convert COM port digit to number. + if (param[6] != 0) { + comPort = (comPort * 10) + param[6] - '0'; + } + break; + + + case 'd' : // Device name specified. + if( strlen( param ) <= 2 ) + throw new ErrorMsg( "Cannot use -d without the device name!" ); + + /* Copy device name string to class variable */ + deviceName.assign( param + 2 ); + break; + + + case 'e' : // Chip erase before programming. + if( strlen( param ) != 2 ) + throw new ErrorMsg( "Parameter -e needs no extra arguments!" ); + + chipErase = true; + break; + + + case 'E' : // Set extended fuse bits. + if( strlen( param ) != 4 ) + throw new ErrorMsg( "Use two hex digits for the -E parameter!" ); + + try + { + programExtendedFuseBits = convertHex( param + 2 ); + } + catch( ErrorMsg * e ) + { + delete e; + throw new ErrorMsg( "Hex number format error for -E parameter!" ); + } + + break; + + + case 'f' : // Set fuse bits. + if( strlen( param ) != 6 ) + throw new ErrorMsg( "Use four hex digits for the -f parameter!" ); + + try + { + programFuseBits = convertHex( param + 2 ); + } + catch( ErrorMsg * e ) + { + delete e; + throw new ErrorMsg( "Hex number format error for -f parameter!" ); + } + + break; + + + case 'F' : // Verify fuse bits. + if( strlen( param ) != 6 ) + throw new ErrorMsg( "Use four hex digits for the -F parameter!" ); + + try + { + verifyFuseBits = convertHex( param + 2 ); + } + catch( ErrorMsg * e ) + { + delete e; + throw new ErrorMsg( "Hex number format error for -F parameter!" ); + } + + break; + + + case 'g' : // Silent operation. + if( strlen( param ) != 2 ) + throw new ErrorMsg( "Parameter -g needs no extra arguments!" ); + + silentMode = true; + break; + + + case 'G' : // Verify extended fuse bits. + if( strlen( param ) != 4 ) + throw new ErrorMsg( "Use two hex digits for the -G parameter!" ); + + try + { + verifyExtendedFuseBits = convertHex( param + 2 ); + } + catch( ErrorMsg * e ) + { + delete e; + throw new ErrorMsg( "Hex number format error for -G parameter!" ); + } + + break; + + + case 'h' : // Help screen. + case '?' : // Help screen. + if( strlen( param ) != 2 ) + throw new ErrorMsg( "Parameter -h and -? needs no extra arguments!" ); + + showHelp = true; + break; + + + case 'i' : // Input file specified. + if( strlen( param ) <= 2 ) + throw new ErrorMsg( "Cannot use -i without memory type!" ); + + if( strlen( param ) <= 3 ) + throw new ErrorMsg( "Cannot use -i without file name!" ); + + /* Copy file name string to correct class variable */ + switch( param[2] ) + { + case 'f' : // Flash input file. + inputFileFlash.assign( param + 3 ); + break; + + case 'e' : // EEPROM input file. + inputFileEEPROM.assign( param + 3 ); + break; + + default: + throw new ErrorMsg( "Unknown choice for -i, use -if or -ie!" ); + } + + break; + + + case 'l' : // Set lock bits. + if( strlen( param ) != 4 ) + throw new ErrorMsg( "Use two hex digits for the -l parameter!" ); + + try + { + programLockBits = convertHex( param + 2 ); + } + catch( ErrorMsg * e ) + { + delete e; + throw new ErrorMsg( "Hex number format error for -l parameter!" ); + } + + break; + + + case 'L' : // Verify lock bits. + if( strlen( param ) != 4 ) + throw new ErrorMsg( "Use two hex digits for the -l parameter!" ); + + try + { + verifyLockBits = convertHex( param + 2 ); + } + catch( ErrorMsg * e ) + { + delete e; + throw new ErrorMsg( "Hex number format error for -L parameter!" ); + } + + break; + + + case 'o' : // Output file specified. + if( strlen( param ) <= 2 ) + throw new ErrorMsg( "Cannot use -o without memory type!" ); + + if( strlen( param ) <= 3 ) + throw new ErrorMsg( "Cannot use -o without file name!" ); + + /* Copy file name string to correct class variable */ + switch( param[2] ) + { + case 'f' : // Flash output file. + outputFileFlash.assign( param + 3 ); + break; + + case 'e' : // EEPROM output file. + outputFileEEPROM.assign( param + 3 ); + break; + + default: + throw new ErrorMsg( "Unknown choice for -o, use -of or -oe!" ); + } + + break; + + + case 'O' : // Read OSCCAL byte. + switch( strlen( param ) ) + { + case 2 : // No value specified, use first OSCCAL byte. + readOSCCAL = true; + OSCCAL_Parameter = 0; // First OSCCAL byte. + break; + + case 3 : // Byte index specified. + case 4 : + readOSCCAL = true; + try + { + OSCCAL_Parameter = convertHex( param + 2 ); + } + catch( ErrorMsg * e ) + { + delete e; + throw new ErrorMsg( "Hex number format error for -O parameter!" ); + } + + break; + + + case 5 : // Direct value specified. + if( param[2] != '#' ) + throw new ErrorMsg( "Use one or two hex digits for -O and two for -O#!" ); + + readOSCCAL = false; + try + { + OSCCAL_Parameter = convertHex( param + 3 ); + } + catch( ErrorMsg * e ) + { + delete e; + throw new ErrorMsg( "Hex number format error for -O# parameter!" ); + } + + break; + + default: + throw new ErrorMsg( "Invalid use of -O or -O# parameter!" ); + } + + break; + + + case 'p' : // Program data. + if( strlen( param ) != 3 ) + throw new ErrorMsg( "Specify memory type, not just -p!" ); + + switch( param[2] ) + { + case 'f' : // Program Flash memory. + programFlash = true; + break; + + case 'e' : // Program EEPROM memory. + programEEPROM = true; + break; + + case 'b' : // Both. + programFlash = true; + programEEPROM = true; + break; + + default: + throw new ErrorMsg( "Unknown choice for -p, use -pf, -pe or -pb!" ); + } + + break; + + + case 'q' : // Read all fuse bits. + if( strlen( param ) != 2 ) + throw new ErrorMsg( "Parameter -q needs no extra arguments!" ); + + readFuseBits = true; + break; + + + case 'r' : // Read data. + if( strlen( param ) != 3 ) + throw new ErrorMsg( "Specify memory type, not just -r!" ); + + switch( param[2] ) + { + case 'f' : // Read Flash memory. + readFlash = true; + break; + + case 'e' : // Read EEPROM memory. + readEEPROM = true; + break; + + case 'b' : // Both. + readFlash = true; + readEEPROM = true; + break; + + default: + throw new ErrorMsg( "Unknown choice for -r, use -rf, -re or -rb!" ); + } + + break; + + + case 's' : // Read signature byte. + if( strlen( param ) != 2 ) + throw new ErrorMsg( "Parameter -s needs no extra arguments!" ); + + readSignature = true; + break; + + + case 'S' : // Write OSCCAL byte to memory. + if( strlen( param ) <= 2 ) + throw new ErrorMsg( "Cannot use -S without memory type!" ); + + if( strlen( param ) <= 3 ) + throw new ErrorMsg( "Cannot use -S without byte address!" ); + + switch( param[2] ) + { + case 'f' : // Write to Flash address. + try + { + OSCCAL_FlashAddress = convertHex( param + 3 ); + } + catch( ErrorMsg * e ) + { + delete e; + throw new ErrorMsg( "Cannot convert hex number for -Sf parameter!" ); + } + break; + + case 'e' : // Write to EEPROM address. + try + { + OSCCAL_EEPROMAddress = convertHex( param + 3 ); + } + catch( ErrorMsg * e ) + { + delete e; + throw new ErrorMsg( "Cannot convert hex number for -Se parameter!" ); + } + break; + + default: + throw new ErrorMsg( "Unknown choice for -S, use -Sf or -Se!" ); + } + + break; + + + case 'v' : // Verify data. + if( strlen( param ) != 3 ) + throw new ErrorMsg( "Specify memory type, not just -v!" ); + + switch( param[2] ) + { + case 'f' : // Verify Flash memory. + verifyFlash = true; + break; + + case 'e' : // Verify EEPROM memory. + verifyEEPROM = true; + break; + + case 'b' : // Both. + verifyFlash = true; + verifyEEPROM = true; + break; + + default: + throw new ErrorMsg( "Unknown choice for -v, use -vf, -ve or -vb!" ); + } + + break; + + + case 'x' : // Fill unspecified memory. + if( strlen( param ) != 4 ) + throw new ErrorMsg( "Use two hex digits for the -x parameter!" ); + + try + { + memoryFillPattern = convertHex( param + 2 ); + } + catch( ErrorMsg * e ) + { + delete e; + throw new ErrorMsg( "Hex number format error for -x parameter!" ); + } + + break; + + + case 'y' : // Read lock bits. + if( strlen( param ) != 2 ) + throw new ErrorMsg( "Parameter -y needs no extra arguments!" ); + + readLockBits = true; + break; + + + case 'z' : // No progress indicator? + if( strlen( param ) != 2 ) + throw new ErrorMsg( "Parameter -z needs no extra arguments!" ); + + noProgressIndicator = true; + break; + + + default: + throw new ErrorMsg( "Unknow parameter!" ); + } + } +} + + +void JobInfo::help() +{ + cout + << "Command Line Switches:" << endl + << " [-d device name] [-if infile] [-ie infile] [-of outfile] [-oe outfile]" << endl + << " [-s] [-O index] [-O#value] [-Sf addr] [-Se addr] [-e] [-p f|e|b]" << endl + << " [-r f|e|b] [-v f|e|b] [-l value] [-L value] [-y] [-f value] [-E value]" << endl + << " [-F value] [-G value] [-q] [-x value] [-af start,stop] [-ae start,stop]" << endl + << " [-c port] [-b h|s] [-g] [-z] [-h|?]" << endl + << endl + << "Parameters:" << endl + << "d Device name. Must be applied when programming the device." << endl + << "if Name of FLASH input file. Required for programming or verification" << endl + << " of the FLASH memory. The file format is Intel Extended HEX." << endl + << "ie Name of EEPROM input file. Required for programming or verification" << endl + << " of the EEPROM memory. The file format is Intel Extended HEX." << endl + << "of Name of FLASH output file. Required for readout of the FLASH memory." << endl + << " The file format is Intel Extended HEX." << endl + << "oe Name of EEPROM output file. Required for readout of the EEPROM" << endl + << " memory. The file format is Intel Extended HEX." << endl + << "s Read signature bytes." << endl; + getch(); + cout + << "O Read oscillator calibration byte. 'index' is optional." << endl + << "O# User-defined oscillator calibration value." << endl + << "Sf Write oscillator cal. byte to FLASH memory. 'addr' is byte address." << endl + << "Se Write oscillator cal. byte to EEPROM memory. 'addr' is byte address." << endl + << "e Erase device. If applied with another programming parameter, the" << endl + << " device will be erased before any other programming takes place." << endl + << "p Program device; FLASH (f), EEPROM (e) or both (b). Corresponding" << endl + << " input files are required." << endl + << "r Read out device; FLASH (f), EEPROM (e) or both (b). Corresponding" << endl + << " output files are required" << endl + << "v Verify device; FLASH (f), EEPROM (e) or both (b). Can be used with" << endl + << " -p or alone. Corresponding input files are required." << endl + << "l Set lock byte. 'value' is an 8-bit hex. value." << endl + << "L Verify lock byte. 'value' is an 8-bit hex. value to verify against." << endl + << "y Read back lock byte." << endl + << "f Set fuse bytes. 'value' is a 16-bit hex. value describing the" << endl + << " settings for the upper and lower fuse bytes." << endl + << "E Set extended fuse byte. 'value' is an 8-bit hex. value describing the" << endl + << " extend fuse settings." << endl + << "F Verify fuse bytes. 'value' is a 16-bit hex. value to verify against." << endl; + getch(); + cout + << "G Verify extended fuse byte. 'value' is an 8-bit hex. value to" << endl + << " verify against." << endl + << "q Read back fuse bytes." << endl + << "x Fill unspecified locations with a value (00-ff). The default is" << endl + << " to not program locations not specified in the input files." << endl + << "af FLASH address range. Specifies the address range of operations. The" << endl + << " default is the entire FLASH. Byte addresses in hex." << endl + << "ae EEPROM address range. Specifies the address range of operations." << endl + << " The default is the entire EEPROM. Byte addresses in hex." << endl + << "c Select communication port; 'COM1' to 'COM99'. If this parameter is" << endl + << " omitted the program will scan the COM ports for a programmer." << endl + << "b Get revisions; hardware revision (h) and software revision (s)." << endl + << "g Silent operation." << endl + << "z No progress indicator. E.g. if piping to a file for log purposes, use" << endl + << " this option to avoid the characters used for the indicator." << endl + << "h|? Help information (overrides all other settings)." << endl + << endl + << "Example:" << endl + << " AVROSP -dATmega128 -ifmyapp.hex -pf" << endl; +} + + +long JobInfo::convertHex( char * txt ) +{ + string t( txt ); + return Util.convertHex( t ); +} + + +void JobInfo::doJob() +{ + long scanCOM; + SerialPort * com; + AVRProgrammer * prog; + AVRDevice * avr; + string programmerID; + long sig0, sig1, sig2; // Signature bytes. + + /* Set correct silent and progress indicator status */ + if( silentMode ) + { + Util.muteLog(); + Util.muteProgress(); // Silent also includes progress indicator. + } + + if( noProgressIndicator ) + Util.muteProgress(); + + /* Application header text */ + Util.log( "AVR Open-source Programmer " VERSIONSTRING " (C) 2004 Atmel Corp.\n\r\n\r" ); + + /* Show help screen? */ + if( showHelp ) + { + help(); + return; + } + + Util.log( "Serial port timeout set to " TIMEOUTSTRING " sec.\r\n" ); + + /* Need to scan for COM port? */ + if( comPort == -1 ) + { + Util.log( "Scanning COM ports for supported programmer...\n\r" ); + + for( scanCOM = 1; scanCOM <= 99; scanCOM++ ) + { + Util.progress( "COM" + Util.convertLong( scanCOM ) + "...\r\n" ); + + try + { + /* Try to communicate */ + com = NULL; + com = new SerialPort( scanCOM, TIMEOUT ); + com->openChannel(); + programmerID = AVRProgrammer::readProgrammerID( com ); + + /* Contact! Check ID... Add custom handler signatures here */ + if( programmerID == "AVRBOOT" || programmerID == "AVR ISP" ) + { + break; + } + + delete com; + Util.progress( programmerID + " found - not supported!\r\n" ); + } + catch( ErrorMsg * e ) + { + /* No contact on COM port, skip to next */ + if( com != NULL ) delete com; + delete e; + } + } + + /* Exit if no supported programmers found */ + if( scanCOM > 99 ) + { + Util.log( "No supported programmers found!\r\n" ); + return; + } + + comPort = scanCOM; + + } else // ... COM port is specified + { + /* Try to communicate, errors will propagate to caller */ + com = new SerialPort( comPort, TIMEOUT ); + com->openChannel(); + programmerID = AVRProgrammer::readProgrammerID( com ); + + /* Contact! Check ID */ + if( programmerID != "AVRBOOT" && programmerID != "AVR ISP" ) + throw new ErrorMsg( "Programmer not supported!" ); + } + + Util.log( "Found " + programmerID + " on COM" + Util.convertLong( comPort ) + "!\r\n" ); + + /* Create programmer interface object, add custom handlers here */ + if( programmerID == "AVRBOOT" ) + { + prog = new AVRBootloader( com ); + } + + if( programmerID == "AVR ISP" ) + { + prog = new AVRInSystemProg( com ); + } + + Util.log( "Entering programming mode...\r\n" ); + prog->enterProgrammingMode(); // Ignore return code. + + /* Do device independent operations */ + doDeviceIndependent( prog ); + + /* Finished if no device name is specified */ + if( deviceName.size() == 0 ) + { + Util.log( "Device name not specified!\r\n" ); + return; + } + + /* Parse XML part description file */ + avr = new AVRDevice( deviceName ); + Util.log( "Parsing XML file for device parameters...\r\n" ); + Util.parsePath( searchpath ); + avr->readParametersFromAVRStudio( searchpath ); + + /* Verify that the device signature matches the signature from the XML file */ + avr->getSignature( &sig0, &sig1, &sig2 ); + if( prog->checkSignature( sig0, sig1, sig2 ) ) + Util.log( "Signature matches device!\r\n" ); + + /* Do device dependent operations */ + doDeviceDependent( prog, avr ); + + /* Clean up */ + Util.log( "Leaving programming mode...\r\n" ); + prog->leaveProgrammingMode(); // Ignore return code. + + delete avr; + delete prog; + delete com; +} + + +void JobInfo::doDeviceIndependent( AVRProgrammer * prog ) +{ + long sig0, sig1, sig2; // Signature bytes. + long minor, major; // Minor and major programmer revision. + + /* Read signature? */ + if( readSignature ) + { + Util.log( "Reading signature bytes: " ); + if( !prog->readSignature( &sig0, &sig1, &sig2 ) ) + throw new ErrorMsg( "Signature readout is not supported by this programmer!" ); + + /* No pass through Util, since user wants the info */ + cout.fill( '0' ); + cout << hex + << "0x" << setw(2) << sig0 << " " + << "0x" << setw(2) << sig1 << " " + << "0x" << setw(2) << sig2 << endl; + } + + /* Get software version? */ + if( getSWrevision ) + { + Util.log( "Reading programmer software revision: " ); + if( !prog->programmerSoftwareVersion( &major, &minor ) ) + throw new ErrorMsg( "Software revision readout is not supported by this programmer!" ); + + /* No pass through Util, since user wants the info */ + cout << (char) (major & 0xff) << "." << (char) (minor & 0xff) << endl; + } + + /* Get software version? */ + if( getHWrevision ) + { + Util.log( "Reading programmer hardware revision: " ); + if( !prog->programmerHardwareVersion( &major, &minor ) ) + throw new ErrorMsg( "Hardware revision readout is not supported by this programmer!" ); + + /* No pass through Util, since user wants the info */ + cout << (char) (major & 0xff) << "." << (char) (minor & 0xff) << endl; + } +} + + +void JobInfo::doDeviceDependent( AVRProgrammer * prog, AVRDevice * avr ) +{ + HEXFile * hex; + HEXFile * hex_v; // Used for verifying memory contents. + long pos; // Used when comparing data. + long bits; // Used for lock and fuse bits. + + /* Set programmer pagesize */ + prog->setPagesize( avr->getPageSize() ); + + /* Check if specified address limits are within device range */ + if( flashEndAddress != -1 ) + { + if( flashEndAddress >= avr->getFlashSize() ) + throw new ErrorMsg( "Specified Flash address range is outside device address space!" ); + } else + { + flashStartAddress = 0; + flashEndAddress = avr->getFlashSize() - 1; + } + + if( eepromEndAddress != -1 ) + { + if( eepromEndAddress >= avr->getEEPROMSize() ) + throw new ErrorMsg( "Specified EEPROM address range is outside device address space!" ); + } else + { + eepromStartAddress = 0; + eepromEndAddress = avr->getEEPROMSize() - 1; + } + + + /* Read out Flash contents? */ + if( readFlash ) + { + /* Check that filename has been specified */ + if( outputFileFlash.size() == 0 ) + throw new ErrorMsg( "Cannot read Flash without output file specified!" ); + + /* Prepare the file */ + hex = new HEXFile( avr->getFlashSize() ); + hex->setUsedRange( flashStartAddress, flashEndAddress ); + + /* Read data and save file */ + Util.log( "Reading Flash contents...\r\n" ); + if( !prog->readFlash( hex ) ) + throw new ErrorMsg( "Flash readout is not supported by this programmer!" ); + Util.log( "Writing HEX output file...\r\n" ); + hex->writeFile( outputFileFlash ); + + delete hex; + } + + + /* Read out EEPROM contents? */ + if( readEEPROM ) + { + /* Check that filename has been specified */ + if( outputFileEEPROM.size() == 0 ) + throw new ErrorMsg( "Cannot read EEPROM without output file specified!" ); + + /* Prepare the file */ + hex = new HEXFile( avr->getEEPROMSize() ); + hex->setUsedRange( eepromStartAddress, eepromEndAddress ); + + /* Read data and save file */ + Util.log( "Reading EEPROM contents...\r\n" ); + if( !prog->readEEPROM( hex ) ) + throw new ErrorMsg( "EEPROM readout is not supported by this programmer!" ); + Util.log( "Writing HEX output file...\r\n" ); + hex->writeFile( outputFileEEPROM ); + + delete hex; + } + + + /* Read lock bits? */ + if( readLockBits ) + { + Util.log( "Reading lock bits...\r\n" ); + if( !prog->readLockBits( &bits ) ) + throw new ErrorMsg( "Lock bit readout is not supported by this programmer!" ); + cout << "0x" << std::hex << setw(2) << bits << endl; + } + + + /* Read fuse bits (both ordinary and extended)? */ + if( readFuseBits ) + { + if( !avr->getFuseStatus() ) + throw new ErrorMsg( "Selected device has no fuse bits!" ); + + Util.log( "Reading fuse bits...\r\n" ); + if( !prog->readFuseBits( &bits ) ) + throw new ErrorMsg( "Fuse bit readout is not supported by this programmer!" ); + cout << "0x" << std::hex << setw(4) << bits << endl; + + if( avr->getXFuseStatus() ) + { + if( !prog->readExtendedFuseBits( &bits ) ) + throw new ErrorMsg( "Extended fuse bit readout is not supported by this programmer!" ); + cout << "0x" << std::hex << setw(2) << bits << endl; + } + } + + + /* Erase chip before programming anything? */ + if( chipErase ) + { + Util.log( "Erasing chip contents...\r\n" ); + if( !prog->chipErase() ) + throw new ErrorMsg( "Chip erase is not supported by this programmer!" ); + } + + + /* Prepare input hex file for flash */ + if( programFlash || verifyFlash ) + { + /* Check that filename has been specified */ + if( inputFileFlash.size() == 0 ) + throw new ErrorMsg( "Cannot program or verify Flash without input file specified!" ); + + /* Prepare the file */ + hex = new HEXFile( avr->getFlashSize() ); + + /* Fill if wanted */ + if( memoryFillPattern != -1 ) + hex->clearAll( memoryFillPattern ); + + /* Read file */ + Util.log( "Reading HEX input file for flash operations...\r\n" ); + hex->readFile( inputFileFlash ); + + /* Check limits */ + if( hex->getRangeStart() > flashEndAddress || + hex->getRangeEnd() < flashStartAddress ) + throw new ErrorMsg( "HEX file defines data outside specified range!" ); + + if( memoryFillPattern == -1 ) + { + if( hex->getRangeStart() > flashStartAddress ) + flashStartAddress = hex->getRangeStart(); + + if( hex->getRangeEnd() < flashEndAddress ) + flashEndAddress = hex->getRangeEnd(); + } + + hex->setUsedRange( flashStartAddress, flashEndAddress ); + } + + + /* Program new Flash contents? */ + if( programFlash ) + { + /* Program data */ + Util.log( "Programming Flash contents...\r\n" ); + if( !prog->writeFlash( hex ) ) + throw new ErrorMsg( "Flash programming is not supported by this programmer!" ); + } + + + /* Verify Flash contents? */ + if( verifyFlash ) + { + /* Prepare HEX file for comparision */ + hex_v = new HEXFile( avr->getFlashSize() ); + + /* Compare to Flash */ + Util.log( "Reading Flash contents...\r\n" ); + hex_v->setUsedRange( hex->getRangeStart(), hex->getRangeEnd() ); + if( !prog->readFlash( hex_v ) ) + throw new ErrorMsg( "Flash readout is not supported by this programmer!" ); + + /* Compare data */ + Util.log( "Comparing Flash data...\r\n" ); + + for( pos = hex->getRangeStart(); pos <= hex->getRangeEnd(); pos++ ) + { + if( hex->getData( pos ) != hex_v->getData( pos ) ) + { + cout << "Unequal at address 0x" << std::hex << pos << "!" << endl; + break; + } + } + + if( pos > hex->getRangeEnd() ) // All equal? + { + cout << "Equal!" << endl; + } + + delete hex_v; + } + + if( programFlash || verifyFlash ) + delete hex; + + + /* Prepare input hex file for EEPROM */ + if( programEEPROM || verifyEEPROM ) + { + /* Check that filename has been specified */ + if( inputFileEEPROM.size() == 0 ) + throw new ErrorMsg( "Cannot program or verify EEPROM without input file specified!" ); + + /* Prepare the file */ + hex = new HEXFile( avr->getEEPROMSize() ); + + /* Fill if wanted */ + if( memoryFillPattern != -1 ) + hex->clearAll( memoryFillPattern ); + + /* Read file and program contents */ + Util.log( "Reading HEX input file for EEPROM operations...\r\n" ); + hex->readFile( inputFileEEPROM ); + + /* Check limits */ + if( hex->getRangeStart() > eepromEndAddress || + hex->getRangeEnd() < eepromStartAddress ) + throw new ErrorMsg( "HEX file defines data outside specified range!" ); + + if( memoryFillPattern == -1 ) + { + if( hex->getRangeStart() > eepromStartAddress ) + eepromStartAddress = hex->getRangeStart(); + + if( hex->getRangeEnd() < eepromEndAddress ) + eepromEndAddress = hex->getRangeEnd(); + } + + hex->setUsedRange( eepromStartAddress, eepromEndAddress ); + } + + + /* Program new EEPROM contents? */ + if( programEEPROM ) + { + /* Program data */ + Util.log( "Programming EEPROM contents...\r\n" ); + if( !prog->writeEEPROM( hex ) ) + throw new ErrorMsg( "EEPROM programming is not supported by this programmer!" ); + } + + /* Verify EEPROM contents? */ + if( verifyEEPROM ) + { + /* Prepare HEX file for comparision */ + hex_v = new HEXFile( avr->getEEPROMSize() ); + + /* Compare to EEPROM */ + Util.log( "Reading EEPROM contents...\r\n" ); + hex_v->setUsedRange( hex->getRangeStart(), hex->getRangeEnd() ); + if( !prog->readEEPROM( hex_v ) ) + throw new ErrorMsg( "EEPROM readout is not supported by this programmer!" ); + + /* Compare data */ + Util.log( "Comparing EEPROM data...\r\n" ); + for( pos = hex->getRangeStart(); pos <= hex->getRangeEnd(); pos++ ) + { + if( hex->getData( pos ) != hex_v->getData( pos ) ) + { + cout << "Unequal at address 0x" << std::hex << pos << "!" << endl; + break; + } + } + + if( pos > hex->getRangeEnd() ) // All equal? + { + cout << "Equal!" << endl; + } + + delete hex_v; + } + + if( programEEPROM || verifyEEPROM ) + delete hex; + + + /* Program lock bits */ + if( programLockBits != -1 ) + { + Util.log( "Programming lock bits...\r\n" ); + if( !prog->writeLockBits( programLockBits ) ) + throw new ErrorMsg( "Lock bit programming is not supported by this programmer!" ); + } + + + /* Program fuse bits */ + if( programFuseBits != -1 ) + { + if( !avr->getFuseStatus() ) + throw new ErrorMsg( "Selected device has no fuse bits!" ); + + Util.log( "Programming fuse bits...\r\n" ); + if( !prog->writeFuseBits( programFuseBits ) ) + throw new ErrorMsg( "Fuse bit programming is not supported by this programmer!" ); + } + + + /* Program extended fuse bits */ + if( programExtendedFuseBits != -1 ) + { + if( !avr->getXFuseStatus() ) + throw new ErrorMsg( "Selected device has no extended fuse bits!" ); + + Util.log( "Programming extended fuse bits...\r\n" ); + if( !prog->writeExtendedFuseBits( programExtendedFuseBits ) ) + throw new ErrorMsg( "Extended fuse bit programming is not supported by this programmer!" ); + } + + + /* Verify lock bits */ + if( verifyLockBits != -1 ) + { + Util.log( "Verifying lock bits...\r\n" ); + if( !prog->readLockBits( &bits ) ) + throw new ErrorMsg( "Lock bit readout is not supported by this programmer!" ); + if( bits == verifyLockBits ) + cout << "Equal!" << endl; + else + cout << "Unequal!" << endl; + } + + + /* Verify fuse bits */ + if( verifyFuseBits != -1 ) + { + if( !avr->getFuseStatus() ) + throw new ErrorMsg( "Selected device has no fuse bits!" ); + + Util.log( "Verifying fuse bits...\r\n" ); + if( !prog->readFuseBits( &bits ) ) + throw new ErrorMsg( "Fuse bit readout is not supported by this programmer!" ); + if( bits == verifyFuseBits ) + cout << "Equal!" << endl; + else + cout << "Unequal!" << endl; + } + + + /* Verify extended fuse bits */ + if( verifyExtendedFuseBits != -1 ) + { + if( !avr->getXFuseStatus() ) + throw new ErrorMsg( "Selected device has no extended fuse bits!" ); + + Util.log( "Verifying extended fuse bits...\r\n" ); + if( !prog->readExtendedFuseBits( &bits ) ) + throw new ErrorMsg( "Extended fuse bit readout is not supported by this programmer!" ); + if( bits == verifyExtendedFuseBits ) + cout << "Equal!" << endl; + else + cout << "Unequal!" << endl; + } + + + /* Read osccal value? */ + if( OSCCAL_Parameter != -1 ) + { + /* Output to log if read from device */ + if( readOSCCAL ) + { + Util.log( "Reading OSCCAL from device...\r\n" ); + pos = OSCCAL_Parameter; + if( !prog->readOSCCAL( pos, &OSCCAL_Parameter ) ) + throw new ErrorMsg( "OSCCAL parameter readout is not supported by this programmer!" ); + cout << "0x" << std::hex << setw(2) << OSCCAL_Parameter << endl; + } + } + + + /* Write OSCCAL to Flash? */ + if( OSCCAL_FlashAddress != -1 ) + { + if( OSCCAL_Parameter == -1 ) + throw new ErrorMsg( "OSCCAL value not specified!" ); + + Util.log( "Programming OSCCAL value to Flash...\r\n" ); + if( !prog->writeFlashByte( OSCCAL_FlashAddress, OSCCAL_Parameter ) ) + throw new ErrorMsg( "Flash programming is not supported by this programmer!" ); + } + + + /* Write OSCCAL to EEPROM? */ + if( OSCCAL_EEPROMAddress != -1 ) + { + if( OSCCAL_Parameter == -1 ) + throw new ErrorMsg( "OSCCAL value not specified!" ); + + Util.log( "Programming OSCCAL value to EEPROM...\r\n" ); + if( !prog->writeEEPROMByte( OSCCAL_EEPROMAddress, OSCCAL_Parameter ) ) + throw new ErrorMsg( "EEPROM programming is not supported by this programmer!" ); + } + +} + + +/* end of file */ + diff --git a/ports/bdk-atxx4-mstp/avrosp/JobInfo.hpp b/ports/bdk-atxx4-mstp/avrosp/JobInfo.hpp index 0ad5ea45..2130d597 100644 --- a/ports/bdk-atxx4-mstp/avrosp/JobInfo.hpp +++ b/ports/bdk-atxx4-mstp/avrosp/JobInfo.hpp @@ -1,105 +1,105 @@ -/***************************************************************************** - * - * Atmel Corporation - * - * File : JobInfo.hpp - * Compiler : Dev-C++ 4.9.8.0 - http://bloodshed.net/dev/ - * Revision : $Revision: 1163 $ - * Date : $Date: 2006-08-02 15:38:16 +0200 (on, 02 aug 2006) $ - * Updated by : $Author: ohlia $ - * - * Support mail : avr@atmel.com - * - * Target platform : Win32 - * - * AppNote : AVR911 - AVR Open-source Programmer - * - * Description : A class holding information on what the AVR Open-Source Programmer - * should do. The information is derived from the command-line. - * - * - ****************************************************************************/ -#ifndef JOBINFO_HPP -#define JOBINFO_HPP - -using namespace std; - -#include -#include -#include -#include -#include "ErrorMsg.hpp" -#include "AVRProgrammer.hpp" -#include "AVRBootloader.hpp" -#include "AVRInSystemProg.hpp" -#include "AVRDevice.hpp" -#include "SerialPort.hpp" -#include "Utility.hpp" - - -class JobInfo -{ - protected: - long convertHex( char * txt ); - void help(); - void doDeviceIndependent( AVRProgrammer * prog ); - void doDeviceDependent( AVRProgrammer * prog, AVRDevice * avr ); - - - bool showHelp; // Show help screen? - bool silentMode; // No text output? - bool noProgressIndicator; // Do not show progress indicators? - bool readSignature; // Output signature bytes to screen? - bool chipErase; // Erase chip before any programming operations? - bool getHWrevision; // Get hardware revision of programmer? - bool getSWrevision; // Get software revision of programmer? - bool programFlash; // Flash programming desired? - bool programEEPROM; // E2 programming desired? - bool readFlash; // Flash readout desired? - bool readEEPROM; // E2 readout desired? - bool verifyFlash; // Flash verification desired? - bool verifyEEPROM; // E2 verification desired? - bool readLockBits; // Lock bit readout desired? - bool readFuseBits; // Fuse bit readout desired? - bool readOSCCAL; // Read or use specified OSCCAL value, if -O is used? - - string deviceName; // Specified device name. - string inputFileFlash; // Input file for Flash writing and verification. - string inputFileEEPROM; // Input file for E2 writing and verification. - string outputFileFlash; // Output file for Flash readout. - string outputFileEEPROM; // Output file for E2 readout. - - long OSCCAL_Parameter; // Value of the -O parameter, -1 if unspecified. - - long OSCCAL_FlashAddress; // Where to put OSCCAL value in flash, -1 if not. - long OSCCAL_EEPROMAddress; // Where to put OSCCAL value in E2, -1 if not. - - long programLockBits; // Change lock bits to this value, -1 if not. - long verifyLockBits; // Verify lock bits against this value, -1 if not. - - long programFuseBits; // Change fuse bits to this value, -1 if not. - long programExtendedFuseBits; // Same as above for extended fuse bits. - long verifyFuseBits; // Verify fuse bits against this value, -1 if not. - long verifyExtendedFuseBits; // Same as above for extended fuse bits. - - long memoryFillPattern; // Fill unspecified locations, -1 if not. - - long flashStartAddress; // Limit Flash operations, -1 if not. - long flashEndAddress; // ...to this address, inclusive, -1 if not. - - long eepromStartAddress; // Same as above for E2. - long eepromEndAddress; // ... - - long comPort; // Desired COM port to use, -1 if unspecified. - - vector searchpath; // Search path for XML-files. - - public: - JobInfo(); // Constructor - - void parseCommandline( int argc, char *argv[] ); - void doJob(); -}; - -#endif - +/***************************************************************************** + * + * Atmel Corporation + * + * File : JobInfo.hpp + * Compiler : Dev-C++ 4.9.8.0 - http://bloodshed.net/dev/ + * Revision : $Revision: 1163 $ + * Date : $Date: 2006-08-02 15:38:16 +0200 (on, 02 aug 2006) $ + * Updated by : $Author: ohlia $ + * + * Support mail : avr@atmel.com + * + * Target platform : Win32 + * + * AppNote : AVR911 - AVR Open-source Programmer + * + * Description : A class holding information on what the AVR Open-Source Programmer + * should do. The information is derived from the command-line. + * + * + ****************************************************************************/ +#ifndef JOBINFO_HPP +#define JOBINFO_HPP + +using namespace std; + +#include +#include +#include +#include +#include "ErrorMsg.hpp" +#include "AVRProgrammer.hpp" +#include "AVRBootloader.hpp" +#include "AVRInSystemProg.hpp" +#include "AVRDevice.hpp" +#include "SerialPort.hpp" +#include "Utility.hpp" + + +class JobInfo +{ + protected: + long convertHex( char * txt ); + void help(); + void doDeviceIndependent( AVRProgrammer * prog ); + void doDeviceDependent( AVRProgrammer * prog, AVRDevice * avr ); + + + bool showHelp; // Show help screen? + bool silentMode; // No text output? + bool noProgressIndicator; // Do not show progress indicators? + bool readSignature; // Output signature bytes to screen? + bool chipErase; // Erase chip before any programming operations? + bool getHWrevision; // Get hardware revision of programmer? + bool getSWrevision; // Get software revision of programmer? + bool programFlash; // Flash programming desired? + bool programEEPROM; // E2 programming desired? + bool readFlash; // Flash readout desired? + bool readEEPROM; // E2 readout desired? + bool verifyFlash; // Flash verification desired? + bool verifyEEPROM; // E2 verification desired? + bool readLockBits; // Lock bit readout desired? + bool readFuseBits; // Fuse bit readout desired? + bool readOSCCAL; // Read or use specified OSCCAL value, if -O is used? + + string deviceName; // Specified device name. + string inputFileFlash; // Input file for Flash writing and verification. + string inputFileEEPROM; // Input file for E2 writing and verification. + string outputFileFlash; // Output file for Flash readout. + string outputFileEEPROM; // Output file for E2 readout. + + long OSCCAL_Parameter; // Value of the -O parameter, -1 if unspecified. + + long OSCCAL_FlashAddress; // Where to put OSCCAL value in flash, -1 if not. + long OSCCAL_EEPROMAddress; // Where to put OSCCAL value in E2, -1 if not. + + long programLockBits; // Change lock bits to this value, -1 if not. + long verifyLockBits; // Verify lock bits against this value, -1 if not. + + long programFuseBits; // Change fuse bits to this value, -1 if not. + long programExtendedFuseBits; // Same as above for extended fuse bits. + long verifyFuseBits; // Verify fuse bits against this value, -1 if not. + long verifyExtendedFuseBits; // Same as above for extended fuse bits. + + long memoryFillPattern; // Fill unspecified locations, -1 if not. + + long flashStartAddress; // Limit Flash operations, -1 if not. + long flashEndAddress; // ...to this address, inclusive, -1 if not. + + long eepromStartAddress; // Same as above for E2. + long eepromEndAddress; // ... + + long comPort; // Desired COM port to use, -1 if unspecified. + + vector searchpath; // Search path for XML-files. + + public: + JobInfo(); // Constructor + + void parseCommandline( int argc, char *argv[] ); + void doJob(); +}; + +#endif + diff --git a/ports/bdk-atxx4-mstp/avrosp/SerialPort.cpp b/ports/bdk-atxx4-mstp/avrosp/SerialPort.cpp index 2579f393..9668a951 100644 --- a/ports/bdk-atxx4-mstp/avrosp/SerialPort.cpp +++ b/ports/bdk-atxx4-mstp/avrosp/SerialPort.cpp @@ -1,203 +1,203 @@ -/***************************************************************************** - * - * Atmel Corporation - * - * File : SerialPort.cpp - * Compiler : Dev-C++ 4.9.8.0 - http://bloodshed.net/dev/ - * Revision : $Revision: 1163 $ - * Date : $Date: 2006-08-02 15:38:16 +0200 (on, 02 aug 2006) $ - * Updated by : $Author: ohlia $ - * - * Support mail : avr@atmel.com - * - * Target platform : Win32 - * - * AppNote : AVR911 - AVR Open-source Programmer - * - * Description : A class providing serial communication through the PC COM port. - * This class is derived from the CommChannel abstract class. - * - * - ****************************************************************************/ -#include "SerialPort.hpp" - - -/* Constructor */ -SerialPort::SerialPort( long _portNumber, long _timeout ) -{ - if( _timeout < 0 ) - throw new ErrorMsg( "Negative COM-port timeout not allowed!" ); - - if( _portNumber < 1 || _portNumber > 99 ) - throw new ErrorMsg( "Only COM1 to COM99 is supported!" ); - - /* Initialize internal parameters */ - portNumber = _portNumber; - timeout = _timeout; - channelOpen = false; -} - - -/* Destructor */ -SerialPort::~SerialPort() -{ - closeChannel(); -} - - -/* Open the communication channel */ -void SerialPort::openChannel() -{ - /* CreateFile expects a constant char, or char from the heap */ - static char comName[64] = "COM1"; - - COMMTIMEOUTS comTimeouts; - - /* Check if channel already open */ - if( channelOpen ) - throw new ErrorMsg( "Channel already open! Cannot open port twice." ); - - /* Generate COM filename and attempt open */ - if (portNumber < 10) { - comName[3] = '0' + portNumber; - } else if (portNumber < 100) { - /* For COM ports greater than 9 you have to use a special syntax - for CreateFile. The syntax also works for COM ports 1-9. */ - /* http://support.microsoft.com/kb/115831 */ - sprintf(comName, "\\\\.\\COM%ld", portNumber); - } - serialHandle = CreateFile( comName, GENERIC_READ | GENERIC_WRITE, 0, NULL, - OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); - - /* Print error and return if failed opening port */ - if( serialHandle == INVALID_HANDLE_VALUE ) - throw new ErrorMsg( "Error opening COM port!" ); - - channelOpen = true; - - /* Store old COM port settings */ - if( !GetCommTimeouts( serialHandle, &oldComTimeouts ) ) - throw new ErrorMsg( "Error reading COM port settings!" ); - - /* Get another copy of the COM settings, and change them */ - if( !GetCommTimeouts( serialHandle, &comTimeouts ) ) - throw new ErrorMsg( "Error reading COM port settings!" ); - - comTimeouts.ReadIntervalTimeout = MAXDWORD; - comTimeouts.ReadTotalTimeoutConstant = 0; - comTimeouts.ReadTotalTimeoutMultiplier = 0; - - /* Apply new settings */ - if( !SetCommTimeouts( serialHandle, &comTimeouts ) ) - throw new ErrorMsg( "Error changing COM port settings!" ); -} - - -/* Close the communication channel */ -void SerialPort::closeChannel() -{ - if( !channelOpen ) - return; - - /* Restore old COM parameters */ - if( !SetCommTimeouts( serialHandle, &oldComTimeouts ) ) - throw new ErrorMsg( "Error changing COM port settings!" ); - - /* Release port */ - if( serialHandle != INVALID_HANDLE_VALUE ) - if( !CloseHandle( serialHandle ) ) - throw new ErrorMsg( "Error closing COM port!" ); - - channelOpen = false; -} - - - -/* Transmit a single byte */ -void SerialPort::sendByte( long data ) -{ - DWORD written; - - /* Check if channel is open */ - if( !channelOpen ) - throw new ErrorMsg( "Channel not open! Cannot send to unopened channel." ); - - /* Attempt writing */ - if( !WriteFile( serialHandle, &data, 1, &written, NULL ) ) - throw new ErrorMsg( "Error writing byte to COM port!" ); -} - - -/* Receive a single byte */ -long SerialPort::getByte() -{ - time_t startTime; - startTime = time( NULL ); // Read current time in seconds - DWORD readnum; - unsigned char data; - - /* Check if channel is open */ - if( !channelOpen ) - throw new ErrorMsg( "Channel not open! Cannot read from unopened channel." ); - - /* Attempt receiving byte until timeout limit exceeded */ - do - { - /* Read byte from port */ - if( !ReadFile( serialHandle, &data, 1, &readnum, NULL ) ) - { - throw new ErrorMsg( "Error reading byte from COM port!" ); - } - - if( readnum == 1 ) - return ((long) data) & 0xff; - - } while( time(NULL) - startTime < timeout ); - - /* Timeout */ - throw new ErrorMsg( "Timeout during COM-port read operation!" ); -} - - -/* Flush the transmit buffer */ -void SerialPort::flushTX() -{ - /* Check if channel is open */ - if( !channelOpen ) - throw new ErrorMsg( "Channel not open! Cannot flush an unopened channel." ); - - /* Purge data from write buffer */ - if( !PurgeComm( serialHandle, PURGE_TXCLEAR ) ) - throw new ErrorMsg( "Error flushing COM port TX buffer!" ); -} - - -/* Flush the receive buffer */ -void SerialPort::flushRX() -{ - /* Check if channel is open */ - if( !channelOpen ) - throw new ErrorMsg( "Channel not open! Cannot flush an unopened channel." ); - - /* Purge data from write buffer */ - if( !PurgeComm( serialHandle, PURGE_RXCLEAR ) ) - throw new ErrorMsg( "Error flushing COM port RX buffer!" ); -} - - -/* Transmit multiple bytes */ -void SerialPort::sendMultiple( unsigned char * data, long bufsize ) -{ - DWORD written; - - /* Check if channel is open */ - if( !channelOpen ) - throw new ErrorMsg( "Channel not open! Cannot write to unopened channel." ); - - /* Attempt writing */ - if( !WriteFile( serialHandle, data, bufsize, &written, NULL ) ) - throw new ErrorMsg( "Error writing multiple bytes to COM port!" ); -} - -/* end of file */ - +/***************************************************************************** + * + * Atmel Corporation + * + * File : SerialPort.cpp + * Compiler : Dev-C++ 4.9.8.0 - http://bloodshed.net/dev/ + * Revision : $Revision: 1163 $ + * Date : $Date: 2006-08-02 15:38:16 +0200 (on, 02 aug 2006) $ + * Updated by : $Author: ohlia $ + * + * Support mail : avr@atmel.com + * + * Target platform : Win32 + * + * AppNote : AVR911 - AVR Open-source Programmer + * + * Description : A class providing serial communication through the PC COM port. + * This class is derived from the CommChannel abstract class. + * + * + ****************************************************************************/ +#include "SerialPort.hpp" + + +/* Constructor */ +SerialPort::SerialPort( long _portNumber, long _timeout ) +{ + if( _timeout < 0 ) + throw new ErrorMsg( "Negative COM-port timeout not allowed!" ); + + if( _portNumber < 1 || _portNumber > 99 ) + throw new ErrorMsg( "Only COM1 to COM99 is supported!" ); + + /* Initialize internal parameters */ + portNumber = _portNumber; + timeout = _timeout; + channelOpen = false; +} + + +/* Destructor */ +SerialPort::~SerialPort() +{ + closeChannel(); +} + + +/* Open the communication channel */ +void SerialPort::openChannel() +{ + /* CreateFile expects a constant char, or char from the heap */ + static char comName[64] = "COM1"; + + COMMTIMEOUTS comTimeouts; + + /* Check if channel already open */ + if( channelOpen ) + throw new ErrorMsg( "Channel already open! Cannot open port twice." ); + + /* Generate COM filename and attempt open */ + if (portNumber < 10) { + comName[3] = '0' + portNumber; + } else if (portNumber < 100) { + /* For COM ports greater than 9 you have to use a special syntax + for CreateFile. The syntax also works for COM ports 1-9. */ + /* http://support.microsoft.com/kb/115831 */ + sprintf(comName, "\\\\.\\COM%ld", portNumber); + } + serialHandle = CreateFile( comName, GENERIC_READ | GENERIC_WRITE, 0, NULL, + OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); + + /* Print error and return if failed opening port */ + if( serialHandle == INVALID_HANDLE_VALUE ) + throw new ErrorMsg( "Error opening COM port!" ); + + channelOpen = true; + + /* Store old COM port settings */ + if( !GetCommTimeouts( serialHandle, &oldComTimeouts ) ) + throw new ErrorMsg( "Error reading COM port settings!" ); + + /* Get another copy of the COM settings, and change them */ + if( !GetCommTimeouts( serialHandle, &comTimeouts ) ) + throw new ErrorMsg( "Error reading COM port settings!" ); + + comTimeouts.ReadIntervalTimeout = MAXDWORD; + comTimeouts.ReadTotalTimeoutConstant = 0; + comTimeouts.ReadTotalTimeoutMultiplier = 0; + + /* Apply new settings */ + if( !SetCommTimeouts( serialHandle, &comTimeouts ) ) + throw new ErrorMsg( "Error changing COM port settings!" ); +} + + +/* Close the communication channel */ +void SerialPort::closeChannel() +{ + if( !channelOpen ) + return; + + /* Restore old COM parameters */ + if( !SetCommTimeouts( serialHandle, &oldComTimeouts ) ) + throw new ErrorMsg( "Error changing COM port settings!" ); + + /* Release port */ + if( serialHandle != INVALID_HANDLE_VALUE ) + if( !CloseHandle( serialHandle ) ) + throw new ErrorMsg( "Error closing COM port!" ); + + channelOpen = false; +} + + + +/* Transmit a single byte */ +void SerialPort::sendByte( long data ) +{ + DWORD written; + + /* Check if channel is open */ + if( !channelOpen ) + throw new ErrorMsg( "Channel not open! Cannot send to unopened channel." ); + + /* Attempt writing */ + if( !WriteFile( serialHandle, &data, 1, &written, NULL ) ) + throw new ErrorMsg( "Error writing byte to COM port!" ); +} + + +/* Receive a single byte */ +long SerialPort::getByte() +{ + time_t startTime; + startTime = time( NULL ); // Read current time in seconds + DWORD readnum; + unsigned char data; + + /* Check if channel is open */ + if( !channelOpen ) + throw new ErrorMsg( "Channel not open! Cannot read from unopened channel." ); + + /* Attempt receiving byte until timeout limit exceeded */ + do + { + /* Read byte from port */ + if( !ReadFile( serialHandle, &data, 1, &readnum, NULL ) ) + { + throw new ErrorMsg( "Error reading byte from COM port!" ); + } + + if( readnum == 1 ) + return ((long) data) & 0xff; + + } while( time(NULL) - startTime < timeout ); + + /* Timeout */ + throw new ErrorMsg( "Timeout during COM-port read operation!" ); +} + + +/* Flush the transmit buffer */ +void SerialPort::flushTX() +{ + /* Check if channel is open */ + if( !channelOpen ) + throw new ErrorMsg( "Channel not open! Cannot flush an unopened channel." ); + + /* Purge data from write buffer */ + if( !PurgeComm( serialHandle, PURGE_TXCLEAR ) ) + throw new ErrorMsg( "Error flushing COM port TX buffer!" ); +} + + +/* Flush the receive buffer */ +void SerialPort::flushRX() +{ + /* Check if channel is open */ + if( !channelOpen ) + throw new ErrorMsg( "Channel not open! Cannot flush an unopened channel." ); + + /* Purge data from write buffer */ + if( !PurgeComm( serialHandle, PURGE_RXCLEAR ) ) + throw new ErrorMsg( "Error flushing COM port RX buffer!" ); +} + + +/* Transmit multiple bytes */ +void SerialPort::sendMultiple( unsigned char * data, long bufsize ) +{ + DWORD written; + + /* Check if channel is open */ + if( !channelOpen ) + throw new ErrorMsg( "Channel not open! Cannot write to unopened channel." ); + + /* Attempt writing */ + if( !WriteFile( serialHandle, data, bufsize, &written, NULL ) ) + throw new ErrorMsg( "Error writing multiple bytes to COM port!" ); +} + +/* end of file */ + diff --git a/ports/bdk-atxx4-mstp/avrosp/SerialPort.hpp b/ports/bdk-atxx4-mstp/avrosp/SerialPort.hpp index 5d4d99af..4370266b 100644 --- a/ports/bdk-atxx4-mstp/avrosp/SerialPort.hpp +++ b/ports/bdk-atxx4-mstp/avrosp/SerialPort.hpp @@ -1,75 +1,75 @@ -/***************************************************************************** - * - * Atmel Corporation - * - * File : SerialPort.hpp - * Compiler : Dev-C++ 4.9.8.0 - http://bloodshed.net/dev/ - * Revision : $Revision: 1163 $ - * Date : $Date: 2006-08-02 15:38:16 +0200 (on, 02 aug 2006) $ - * Updated by : $Author: ohlia $ - * - * Support mail : avr@atmel.com - * - * Target platform : Win32 - * - * AppNote : AVR911 - AVR Open-source Programmer - * - * Description : A class providing serial communication through the PC COM port. - * This class is derived from the CommChannel abstract class. - * - * - ****************************************************************************/ -#ifndef SERIALPORT_HPP -#define SERIALPORT_HPP - -using namespace std; - -#define WIN32_LEAN_AND_MEAN -#include -#include -#include -#include "CommChannel.hpp" -#include "ErrorMsg.hpp" - - -class SerialPort : public CommChannel -{ - protected: - long portNumber; // COMx port number. - long timeout; // Desired timeout limit when receiving data. - HANDLE serialHandle; // Win32 device handle for the com port. - COMMTIMEOUTS oldComTimeouts; // Store old serial port timeout parameters. - bool channelOpen; // Is channel open? - - public: - // Constructor taking port number, baudrate and - // timeout limit as parameters. - SerialPort( long portnumber, long timeout ); - - // Destructor. - ~SerialPort(); - - // Open the communication channel. - virtual void openChannel(); - - // Close the communication channel. - virtual void closeChannel(); - - // Transmit a single byte. - virtual void sendByte( long data ); - - // Receive a single byte. - virtual long getByte(); - - // Flush the transmit buffer. - virtual void flushTX(); - - // Flush the receive buffer. - virtual void flushRX(); - - // Transmit multiple bytes. - virtual void sendMultiple( unsigned char * data, long bufsize ); -}; - -#endif - +/***************************************************************************** + * + * Atmel Corporation + * + * File : SerialPort.hpp + * Compiler : Dev-C++ 4.9.8.0 - http://bloodshed.net/dev/ + * Revision : $Revision: 1163 $ + * Date : $Date: 2006-08-02 15:38:16 +0200 (on, 02 aug 2006) $ + * Updated by : $Author: ohlia $ + * + * Support mail : avr@atmel.com + * + * Target platform : Win32 + * + * AppNote : AVR911 - AVR Open-source Programmer + * + * Description : A class providing serial communication through the PC COM port. + * This class is derived from the CommChannel abstract class. + * + * + ****************************************************************************/ +#ifndef SERIALPORT_HPP +#define SERIALPORT_HPP + +using namespace std; + +#define WIN32_LEAN_AND_MEAN +#include +#include +#include +#include "CommChannel.hpp" +#include "ErrorMsg.hpp" + + +class SerialPort : public CommChannel +{ + protected: + long portNumber; // COMx port number. + long timeout; // Desired timeout limit when receiving data. + HANDLE serialHandle; // Win32 device handle for the com port. + COMMTIMEOUTS oldComTimeouts; // Store old serial port timeout parameters. + bool channelOpen; // Is channel open? + + public: + // Constructor taking port number, baudrate and + // timeout limit as parameters. + SerialPort( long portnumber, long timeout ); + + // Destructor. + ~SerialPort(); + + // Open the communication channel. + virtual void openChannel(); + + // Close the communication channel. + virtual void closeChannel(); + + // Transmit a single byte. + virtual void sendByte( long data ); + + // Receive a single byte. + virtual long getByte(); + + // Flush the transmit buffer. + virtual void flushTX(); + + // Flush the receive buffer. + virtual void flushRX(); + + // Transmit multiple bytes. + virtual void sendMultiple( unsigned char * data, long bufsize ); +}; + +#endif + diff --git a/ports/bdk-atxx4-mstp/avrosp/Utility.cpp b/ports/bdk-atxx4-mstp/avrosp/Utility.cpp index d1916184..29cb0151 100644 --- a/ports/bdk-atxx4-mstp/avrosp/Utility.cpp +++ b/ports/bdk-atxx4-mstp/avrosp/Utility.cpp @@ -1,181 +1,181 @@ -/***************************************************************************** - * - * Atmel Corporation - * - * File : Utility.cpp - * Compiler : Dev-C++ 4.9.8.0 - http://bloodshed.net/dev/ - * Revision : $Revision: 1163 $ - * Date : $Date: 2006-08-02 15:38:16 +0200 (on, 02 aug 2006) $ - * Updated by : $Author: ohlia $ - * - * Support mail : avr@atmel.com - * - * Target platform : Win32 - * - * AppNote : AVR911 - AVR Open-source Programmer - * - * Description : A class holding misc. utility methods used in AVROSP. - * - * - ****************************************************************************/ -#include "Utility.hpp" - -#include -#include -#include - -/* Global object */ -Utility Util; - - -/* Constructor */ -Utility::Utility() : - noLog( false ), - noProgress( false ) -{ - /* No code here */ -} - - -/* Destructor */ -Utility::~Utility() -{ - /* No code here */ -} - - - -void Utility::log( const string & txt ) -{ - if( !noLog ) - cout << txt; -} - - -void Utility::progress( const string & txt ) -{ - if( !noProgress ) - cout << txt; -} - - -long Utility::convertHex( const string & txt ) -{ - long result = 0; - long digit; - long i; - - if( txt.size() == 0 ) - throw new ErrorMsg( "Cannot convert zero-length hex-string to number!" ); - - if( txt.size() > 8 ) - throw new ErrorMsg( "Hex conversion overflow! Too many hex digits in string." ); - - - for( i = 0; i < txt.size(); i++ ) - { - /* Convert hex digit */ - if( txt[i] >= '0' && txt[i] <= '9' ) - digit = txt[i] - '0'; - else if( txt[i] >= 'a' && txt[i] <= 'f' ) - digit = txt[i] - 'a' + 10; - else if( txt[i] >= 'A' && txt[i] <= 'F' ) - digit = txt[i] - 'A' + 10; - else - throw new ErrorMsg( "Invalid hex digit found!" ); - - /* Add digit as least significant 4 bits of result */ - result = (result << 4) | digit; - } - - return result; -} - - -string Utility::convertLong( long num, long radix ) -{ - char buf[18]; - string res; - - itoa( num, buf, radix ); - res = buf; - return res; -} - - -void Utility::parsePath( vector & list ) -{ - /* Get environment variable and parse if it exists */ - char * pathptr = getenv( "PATH" ); - if( pathptr != NULL && pathptr[0] != 0 ) { - string path = pathptr; - int pos; - - while( (pos = path.find_first_of( ";" )) < path.length() ) { - list.push_back( path.substr( 0, pos ) ); - path.erase( 0, pos+1 ); - } - - list.push_back( path ); // Last directory. - } -} - - -bool Utility::fileExists( string filename ) -{ - /* Attempt to open file */ - ifstream f; - f.open( filename.c_str(), ios::in ); - if( !f ) { - return false; - } else { - f.close(); - return true; - } -} - - -void Utility::saveString( string txt, string filename ) -{ - ofstream f; - - f.open( filename.c_str(), ios::out ); - if( !f ) - throw new ErrorMsg( "Error opening HEX file for output!" ); - - f << txt; - - f.close(); -} - - -#ifndef NOREGISTRY -string Utility::getRegistryValue( const string & path, const string & value ) -{ - /* Code modified from MSDN */ - const long BUFSIZE=1000; - string result; - HKEY hKey; - char szAVRPath[BUFSIZE]; - DWORD dwBufLen=BUFSIZE; - LONG lRet; - - /* Open key */ - lRet = RegOpenKeyEx( HKEY_LOCAL_MACHINE, path.c_str(), 0, KEY_QUERY_VALUE, &hKey ); - if( lRet != ERROR_SUCCESS ) - throw new ErrorMsg( "Error when opening registry key: (" + path + ")!" ); - - /* Get value */ - lRet = RegQueryValueEx( hKey, value.c_str(), NULL, NULL, (LPBYTE) szAVRPath, &dwBufLen); - if( (lRet != ERROR_SUCCESS) || (dwBufLen > BUFSIZE) ) - throw new ErrorMsg( "Error when reading key value: (" + value + ")!" ); - - /* Clean up and return result */ - RegCloseKey( hKey ); - result = szAVRPath; - return result; -} -#endif - -/* end of file */ - +/***************************************************************************** + * + * Atmel Corporation + * + * File : Utility.cpp + * Compiler : Dev-C++ 4.9.8.0 - http://bloodshed.net/dev/ + * Revision : $Revision: 1163 $ + * Date : $Date: 2006-08-02 15:38:16 +0200 (on, 02 aug 2006) $ + * Updated by : $Author: ohlia $ + * + * Support mail : avr@atmel.com + * + * Target platform : Win32 + * + * AppNote : AVR911 - AVR Open-source Programmer + * + * Description : A class holding misc. utility methods used in AVROSP. + * + * + ****************************************************************************/ +#include "Utility.hpp" + +#include +#include +#include + +/* Global object */ +Utility Util; + + +/* Constructor */ +Utility::Utility() : + noLog( false ), + noProgress( false ) +{ + /* No code here */ +} + + +/* Destructor */ +Utility::~Utility() +{ + /* No code here */ +} + + + +void Utility::log( const string & txt ) +{ + if( !noLog ) + cout << txt; +} + + +void Utility::progress( const string & txt ) +{ + if( !noProgress ) + cout << txt; +} + + +long Utility::convertHex( const string & txt ) +{ + long result = 0; + long digit; + long i; + + if( txt.size() == 0 ) + throw new ErrorMsg( "Cannot convert zero-length hex-string to number!" ); + + if( txt.size() > 8 ) + throw new ErrorMsg( "Hex conversion overflow! Too many hex digits in string." ); + + + for( i = 0; i < txt.size(); i++ ) + { + /* Convert hex digit */ + if( txt[i] >= '0' && txt[i] <= '9' ) + digit = txt[i] - '0'; + else if( txt[i] >= 'a' && txt[i] <= 'f' ) + digit = txt[i] - 'a' + 10; + else if( txt[i] >= 'A' && txt[i] <= 'F' ) + digit = txt[i] - 'A' + 10; + else + throw new ErrorMsg( "Invalid hex digit found!" ); + + /* Add digit as least significant 4 bits of result */ + result = (result << 4) | digit; + } + + return result; +} + + +string Utility::convertLong( long num, long radix ) +{ + char buf[18]; + string res; + + itoa( num, buf, radix ); + res = buf; + return res; +} + + +void Utility::parsePath( vector & list ) +{ + /* Get environment variable and parse if it exists */ + char * pathptr = getenv( "PATH" ); + if( pathptr != NULL && pathptr[0] != 0 ) { + string path = pathptr; + int pos; + + while( (pos = path.find_first_of( ";" )) < path.length() ) { + list.push_back( path.substr( 0, pos ) ); + path.erase( 0, pos+1 ); + } + + list.push_back( path ); // Last directory. + } +} + + +bool Utility::fileExists( string filename ) +{ + /* Attempt to open file */ + ifstream f; + f.open( filename.c_str(), ios::in ); + if( !f ) { + return false; + } else { + f.close(); + return true; + } +} + + +void Utility::saveString( string txt, string filename ) +{ + ofstream f; + + f.open( filename.c_str(), ios::out ); + if( !f ) + throw new ErrorMsg( "Error opening HEX file for output!" ); + + f << txt; + + f.close(); +} + + +#ifndef NOREGISTRY +string Utility::getRegistryValue( const string & path, const string & value ) +{ + /* Code modified from MSDN */ + const long BUFSIZE=1000; + string result; + HKEY hKey; + char szAVRPath[BUFSIZE]; + DWORD dwBufLen=BUFSIZE; + LONG lRet; + + /* Open key */ + lRet = RegOpenKeyEx( HKEY_LOCAL_MACHINE, path.c_str(), 0, KEY_QUERY_VALUE, &hKey ); + if( lRet != ERROR_SUCCESS ) + throw new ErrorMsg( "Error when opening registry key: (" + path + ")!" ); + + /* Get value */ + lRet = RegQueryValueEx( hKey, value.c_str(), NULL, NULL, (LPBYTE) szAVRPath, &dwBufLen); + if( (lRet != ERROR_SUCCESS) || (dwBufLen > BUFSIZE) ) + throw new ErrorMsg( "Error when reading key value: (" + value + ")!" ); + + /* Clean up and return result */ + RegCloseKey( hKey ); + result = szAVRPath; + return result; +} +#endif + +/* end of file */ + diff --git a/ports/bdk-atxx4-mstp/avrosp/Utility.hpp b/ports/bdk-atxx4-mstp/avrosp/Utility.hpp index 68520100..b9032425 100644 --- a/ports/bdk-atxx4-mstp/avrosp/Utility.hpp +++ b/ports/bdk-atxx4-mstp/avrosp/Utility.hpp @@ -1,70 +1,70 @@ -/***************************************************************************** - * - * Atmel Corporation - * - * File : Utility.hpp - * Compiler : Dev-C++ 4.9.8.0 - http://bloodshed.net/dev/ - * Revision : $Revision: 1163 $ - * Date : $Date: 2006-08-02 15:38:16 +0200 (on, 02 aug 2006) $ - * Updated by : $Author: ohlia $ - * - * Support mail : avr@atmel.com - * - * Target platform : Win32 - * - * AppNote : AVR911 - AVR Open-source Programmer - * - * Description : A class holding misc. utility methods used in AVROSP. - * - * - ****************************************************************************/ -#ifndef UTILITY_HPP -#define UTILITY_HPP - -using namespace std; - -#ifndef NOREGISTRY -#define WIN32_LEAN_AND_MEAN -#include -#endif - -#include -#include -#include "ErrorMsg.hpp" - -class Utility -{ - protected: - bool noLog; - bool noProgress; - - public: - /* Constructor */ - Utility(); - - /* Destructor */ - ~Utility(); - - /* Methods */ - void muteLog() { noLog = true; } - void muteProgress() { noProgress = true; } - - void log( const string & txt ); - void progress( const string & txt ); - - long convertHex( const string & txt ); - string convertLong( long num, long radix = 10 ); - - void parsePath( vector & list ); - bool fileExists( string filename ); - void saveString( string txt, string filename ); - -#ifndef NOREGISTRY - string getRegistryValue( const string & path, const string & value ); -#endif -}; - -extern Utility Util; - -#endif - +/***************************************************************************** + * + * Atmel Corporation + * + * File : Utility.hpp + * Compiler : Dev-C++ 4.9.8.0 - http://bloodshed.net/dev/ + * Revision : $Revision: 1163 $ + * Date : $Date: 2006-08-02 15:38:16 +0200 (on, 02 aug 2006) $ + * Updated by : $Author: ohlia $ + * + * Support mail : avr@atmel.com + * + * Target platform : Win32 + * + * AppNote : AVR911 - AVR Open-source Programmer + * + * Description : A class holding misc. utility methods used in AVROSP. + * + * + ****************************************************************************/ +#ifndef UTILITY_HPP +#define UTILITY_HPP + +using namespace std; + +#ifndef NOREGISTRY +#define WIN32_LEAN_AND_MEAN +#include +#endif + +#include +#include +#include "ErrorMsg.hpp" + +class Utility +{ + protected: + bool noLog; + bool noProgress; + + public: + /* Constructor */ + Utility(); + + /* Destructor */ + ~Utility(); + + /* Methods */ + void muteLog() { noLog = true; } + void muteProgress() { noProgress = true; } + + void log( const string & txt ); + void progress( const string & txt ); + + long convertHex( const string & txt ); + string convertLong( long num, long radix = 10 ); + + void parsePath( vector & list ); + bool fileExists( string filename ); + void saveString( string txt, string filename ); + +#ifndef NOREGISTRY + string getRegistryValue( const string & path, const string & value ); +#endif +}; + +extern Utility Util; + +#endif + diff --git a/ports/bdk-atxx4-mstp/avrosp/XMLParser.cpp b/ports/bdk-atxx4-mstp/avrosp/XMLParser.cpp index 85ff124b..d39754d4 100644 --- a/ports/bdk-atxx4-mstp/avrosp/XMLParser.cpp +++ b/ports/bdk-atxx4-mstp/avrosp/XMLParser.cpp @@ -1,637 +1,637 @@ -/***************************************************************************** - * - * Atmel Corporation - * - * File : XMLParser.cpp - * Compiler : Dev-C++ 4.9.8.0 - http://bloodshed.net/dev/ - * Revision : $Revision: 3419 $ - * Date : $Date: 2008-02-22 09:56:34 +0100 (fr, 22 feb 2008) $ - * Updated by : $Author: khole $ - * - * Support mail : avr@atmel.com - * - * Target platform : Win32 - * - * AppNote : AVR911 - AVR Open-source Programmer - * - * Description : A simple XML DOM-like parser. It builds a complete tree from - * the XML file. IT supports

tags, but not tag attributes. - * - * - ****************************************************************************/ -#include "XMLParser.hpp" - -/* Private classes */ - -enum XMLNodeType -{ - xml_node, - xml_subtree -}; - -/* Abstract class. XMLTree and XMLNode is derived from this class */ -class XMLAbstractNode -{ - protected: - string name; // Name of this node. - XMLNodeType type; - - public: - /* Constructor */ - XMLAbstractNode( const string & _name, XMLNodeType _type ); - - /* Destructor */ - ~XMLAbstractNode(); - - /* Methods */ - const string & getName(); - XMLNodeType getType(); - - bool isName( const string & _name ); // Compare name to _name. - - virtual void print() = 0; -}; - - -/* Class describing a subtree, derived from XMLAbstractNode */ -class XMLTree : public XMLAbstractNode -{ - protected: - list nodes; // Nodes contained in this tree. - - public: - /* Constructor */ - XMLTree( const string & _name ); - - /* Destructor */ - ~XMLTree(); - - /* Methods */ - void addNode( XMLAbstractNode * newnode ); - bool containsNode( const string & _name ); // Searches for name in list. - XMLAbstractNode * getNode( const string & _name ); - - void print(); -}; - - -/* Class describing an ordinary string-valued node, derived from XMLAbstractNode */ -class XMLNode : public XMLAbstractNode -{ - protected: - string value; // String value. - - public: - /* Constructor */ - XMLNode( const string & _name, const string & _value ); - - /* Destructor */ - ~XMLNode(); - - /* Methods */ - bool isEmpty(); // Contains an empty string? - const string & getValue(); - - void print(); -}; - - - - -void XMLFile::removeComments( string & txt ) -{ - long pos = 0; // Everything up to this point is clean. - - long startFoundAt; // Comment start and end found at these positions. - long endFoundAt; - - /* Search and remove all comment tags */ - do - { - /* Search for comment start */ - startFoundAt = txt.find( "", startFoundAt ); - - /* Error if start but no end is found */ - if( endFoundAt == string::npos ) - throw new ErrorMsg( "Unclosed comment tag encountered! " - "Comment start-tag ''." ); - - /* Remove comment tag */ - txt.erase( startFoundAt, endFoundAt - startFoundAt + 3 ); - - pos = startFoundAt; // Prepare for next search. - - } while( pos < txt.size() ); -} - -void XMLFile::removeStartXML( string & txt ) -{ - long pos = 0; // Everything up to this point is clean. - - long startFoundAt; // Comment start and end found at these positions. - long endFoundAt; - - /* Search and remove the ", startFoundAt ); - - /* Remove tag */ - txt.erase( startFoundAt, endFoundAt - startFoundAt ); -} - - -void XMLFile::removeAttributes( string & txt ) -{ - long pos; // Everything up to this point is clean. - - long startFoundAt; // Tag start and end found at these positions. - long endFoundAt; - - long spaceFoundAt; // Space before attribute found at this position. - long slashFoundAt; // Ending slash found at this position. - - - /* Convert all whitespace to plain spaces, just to make things easier */ - for( pos = 0; pos < txt.size(); pos++ ) - { - if( txt[pos] == '\n' || txt[pos] == '\r' || txt[pos] == '\t' ) - txt.replace( pos, 1, " " ); - } - - pos = 0; - - /* Search and clean all tags */ - do - { - /* Search for tag start */ - startFoundAt = txt.find( "<", pos ); - - /* Exit loop if no tag is found */ - if( startFoundAt == string::npos ) - break; - - /* Search for comment end */ - endFoundAt = txt.find( ">", startFoundAt ); - - /* Error if start but no end is found */ - if( endFoundAt == string::npos ) - throw new ErrorMsg( "Unclosed tag encountered! " - "Tag start token '<' found, but not " - "closing '>'." ); - - /* Remove whitespace before tag name */ - while( txt[startFoundAt+1] == ' ' ) - { - txt.erase( startFoundAt+1, 1 ); // Remove. - endFoundAt--; // String has now shrunk. - } - - /* Search for space before attributes */ - spaceFoundAt = txt.find( " ", startFoundAt ); - if( spaceFoundAt < endFoundAt && spaceFoundAt != string::npos ) // Space found inside tag? - { - // If empty tag, we dont want to remove the / in /> - if ( txt.at(endFoundAt-1) == '/' ) - { - endFoundAt--; - } - - /* Remove attributes */ - txt.erase( spaceFoundAt, endFoundAt - spaceFoundAt ); - endFoundAt -= endFoundAt - spaceFoundAt; // String has now shrunk. - } - - - pos = endFoundAt + 1; // Prepare for next search. - - } while( pos < txt.size() ); -} - - -void XMLFile::readFile( const string & _filename ) -{ - ifstream f; // XML file stream. - string contents; // XML file contents. - string templine; - - /* Attempt to open file */ - f.open( _filename.c_str(), ios::in ); - if( !f ) - throw new ErrorMsg( "Error opening XML file for input!" ); - - /* Read everything into the contents string */ - contents.erase(); - templine.erase(); - do - { - contents += templine + " "; - f >> templine; // This will cause EOF only when reading from the end. - } while( !f.eof() ); - - f.close(); - - /* Remove comments and tag attributes */ - removeComments( contents ); - removeAttributes( contents ); - removeStartXML ( contents ); - - /* Create root node */ - root = new XMLTree( "root" ); - parseFragment( contents, root ); - - Util.progress( "\r\n" ); // Finish progress indicator. -} - - -void XMLFile::parseFragment( string & fragment, XMLTree * parent ) -{ - long startFoundAt; // Tag start and end found at these positions. - long endFoundAt; - - string closingString; // Search string used for finding closing tag. - long closingFoundAt; // Closing tag found at this position. - - string tagName; // These are for recently created nodes. - string tagValue; - - XMLTree * newTree; - XMLNode * newNode; - - long nestedFoundAt; // Nested tags found at this position. - - /* Find top level tags */ - Util.progress( "#" ); // Advance progress indicator. - - while( true ) // Wait for break from inside. - { - /* Find start of tag */ - startFoundAt = fragment.find( "<", 0 ); - if( startFoundAt == string::npos ) // Exit loop if no tags found. - break; - - /* Check if this is a closing tag for a higher level tag pair */ - if( fragment[startFoundAt+1] == '/' ) - break; // Exit loop. - - /* Find end of tag */ - endFoundAt = fragment.find( ">", startFoundAt ); - if( endFoundAt == string::npos ) // Error if end not found. - throw new ErrorMsg( "Unclosed tag encountered! " - "Tag start token '<' found, but no " - "closing '>'." ); - - /* Extract name of tag */ - tagName = fragment.substr( startFoundAt+1, endFoundAt-startFoundAt-1 ); - if( tagName.size() == 0 ) // Error if zero-length tag name. - throw new ErrorMsg( "Unnamed tag encountered! " - "No text between '<' and '>'." ); - - /* Remove tag from fragment */ - fragment.erase( 0, startFoundAt+tagName.size()+2 ); - - /* Check if it is an empty tag */ - if( tagName[tagName.size()-1] == '/' ) - { - /* Create a new empty ordinary node */ - tagName.erase( tagName.size()-1 ); // Remove the slash. - tagValue.erase(); // This tag has no value. - newNode = new XMLNode( tagName, tagValue ); - parent->addNode( newNode ); - } else - { - /* Find the matching closing tag for this pair */ - closingString.erase(); - closingString += ""; - closingFoundAt = fragment.find( closingString, 0 ); - if( closingFoundAt == string::npos ) // Error if not found. - throw new ErrorMsg( "Closing tag not found! " - "Opening tag '<" + tagName + ">' found, " - "but not closing '" + closingString + "'." ); - - /* Check for tags inside this tag pair, indicating a subtree */ - nestedFoundAt = fragment.find( "<", 0 ); - if( nestedFoundAt == closingFoundAt ) // No other tags inside? - { - /* Extract contents within tag pair */ - tagValue = fragment.substr( 0, closingFoundAt ); - - /* Create new ordinary node */ - newNode = new XMLNode( tagName, tagValue ); - parent->addNode( newNode ); - } else - { - /* Create new subtree and parse it's fragment */ - newTree = new XMLTree( tagName ); - parent->addNode( newTree ); - parseFragment( fragment, newTree ); - - /* Check that we can still find the closing tag */ - closingFoundAt = fragment.find( closingString, 0 ); - if( closingFoundAt == string::npos ) - throw new ErrorMsg( "Closing tag not found! " - "Opening tag '<" + tagName + ">' found, " - "but not closing '" + closingString + "'." ); - } - - /* Remove value and closing tag from fragment */ - fragment.erase( 0, closingFoundAt + closingString.size() ); - } - }; -} - - -/* Constructor */ -XMLFile::XMLFile( const string & _filename ) -{ - readFile( _filename ); -} - - -/* Destructor */ -XMLFile::~XMLFile() -{ - if( root != NULL ) - delete root; -} - - -bool XMLFile::exists( const string & path ) -{ - XMLAbstractNode * currentNode = root; - XMLTree * currentTree; - long namePos; // Position for current tag name in path. - long separatorPos; // Position for #-separator following tag name. - string tagName; // Current tag name. - - namePos = 0; - - while( true ) // This will break out from the inside. - { - /* Find separator or set pos to end of text */ - separatorPos = path.find( "\\", namePos ); - if( separatorPos == string::npos ) - separatorPos = path.size(); - - /* Extract tag name and check if it exists */ - tagName = path.substr( namePos, separatorPos-namePos ); - currentTree = (XMLTree *) currentNode; // It is indeed a tree. - if( !currentTree->containsNode( tagName ) ) - return false; // Not found. - - currentNode = currentTree->getNode( tagName ); - - /* Are there more tags in the path? */ - if( separatorPos < path.size() ) - { - /* Now, the current node better be a tree */ - if( currentNode->getType() != xml_subtree ) - { - return false; // Not found. - } else - { - namePos = separatorPos + 1; // Advance position in path. - } - } else - { - break; // Found, exit loop. - } - } - - return true; // Found! -} - - -const string & XMLFile::getValue( const string & path ) -{ - XMLAbstractNode * currentNode = root; - XMLTree * currentTree; - long namePos; // Position for current tag name in path. - long separatorPos; // Position for #-separator following tag name. - string tagName; // Current tag name. - - namePos = 0; - - while( true ) // This will break out from the inside. - { - /* Find separator or set pos to end of text */ - separatorPos = path.find( "\\", namePos ); - if( separatorPos == string::npos ) - separatorPos = path.size(); - - /* Extract tag name and check if it exists */ - tagName = path.substr( namePos, separatorPos-namePos ); - currentTree = (XMLTree *) currentNode; // It is indeed a tree. - if( !currentTree->containsNode( tagName ) ) - throw new ErrorMsg( "Node '" + tagName + "' not found!" ); - - currentNode = currentTree->getNode( tagName ); - - /* Are there more tags in the path? */ - if( separatorPos < path.size() ) - { - /* Now, the current node better be a tree */ - if( currentNode->getType() != xml_subtree ) - { - throw new ErrorMsg( "Illegal path: (" + path + ")!" ); - } else - { - namePos = separatorPos + 1; // Advance position in path. - } - } else - { - break; // Found, exit loop. - } - } - - /* Check that the current node is an ordinary node */ - if( currentNode->getType() != xml_node ) - throw new ErrorMsg( "Node '" + tagName + "' is not an element!" ); - - return ((XMLNode *) currentNode)->getValue(); -} - - -void XMLFile::print() -{ - root->print(); -} - - -/* Constructor */ -XMLAbstractNode::XMLAbstractNode( const string & _name, XMLNodeType _type ) : - name( _name ), - type( _type ) -{ - // Node code here. -} - - -/* Destructor */ -XMLAbstractNode::~XMLAbstractNode() -{ - // No code here. -} - - -const string & XMLAbstractNode::getName() -{ - return name; -} - - -XMLNodeType XMLAbstractNode::getType() -{ - return type; -} - - -bool XMLAbstractNode::isName( const string & _name ) -{ - return (name == _name); -} - - -/* Constructor */ -XMLTree::XMLTree( const string & _name ) : - XMLAbstractNode::XMLAbstractNode( _name, xml_subtree ) -{ - // No code here. -} - - -/* Destructor */ -XMLTree::~XMLTree() -{ - /* Create an iterator for the list */ - list::iterator i; - - /* Destruct all contained nodes */ - for( i = nodes.begin(); i != nodes.end(); i++ ) - { - delete (*i); - } -} - - -void XMLTree::addNode( XMLAbstractNode * newnode ) -{ - nodes.push_back( newnode ); -} - - -bool XMLTree::containsNode( const string & _name ) -{ - /* Create an iterator for the list */ - list::iterator i; - - /* Search for the node with name _name */ - i = nodes.begin(); - - while( i != nodes.end() ) - { - if( (*i)->isName( _name ) ) - return true; - - i++; - } - - return false; -} - - -XMLAbstractNode * XMLTree::getNode( const string & _name ) -{ - /* Create an iterator for the list */ - list::iterator i; - - /* Search for the node with name _name */ - i = nodes.begin(); - - while( i != nodes.end() ) - { - if( (*i)->isName( _name ) ) - return *i; - - i++; - } - - return NULL; -} - - -void XMLTree::print() -{ - /* Create an iterator for the list */ - list::iterator i; - - cout << "TREE[ Name: \"" << name << "\" ]:" << endl; - - /* Search for the node with name _name */ - i = nodes.begin(); - - while( i != nodes.end() ) - { - (*i)->print(); - - i++; - } - - cout << ":END[\"" << name << "\"]" << endl; -} - - -/* Constructor */ -XMLNode::XMLNode( const string & _name, const string & _value ) : - XMLAbstractNode::XMLAbstractNode( _name, xml_node ), - value( _value ) -{ - // No code here. -} - - -/* Destructor */ -XMLNode::~XMLNode() -{ - // Node code here. -} - - -bool XMLNode::isEmpty() -{ - return value.empty(); -} - - -const string & XMLNode::getValue() -{ - return value; -} - - -void XMLNode::print() -{ - cout << "NODE[ Name: \"" << name << "\" Value: \"" << value << "\" ]" << endl; -} - -/* end of file */ - +/***************************************************************************** + * + * Atmel Corporation + * + * File : XMLParser.cpp + * Compiler : Dev-C++ 4.9.8.0 - http://bloodshed.net/dev/ + * Revision : $Revision: 3419 $ + * Date : $Date: 2008-02-22 09:56:34 +0100 (fr, 22 feb 2008) $ + * Updated by : $Author: khole $ + * + * Support mail : avr@atmel.com + * + * Target platform : Win32 + * + * AppNote : AVR911 - AVR Open-source Programmer + * + * Description : A simple XML DOM-like parser. It builds a complete tree from + * the XML file. IT supports
tags, but not tag attributes. + * + * + ****************************************************************************/ +#include "XMLParser.hpp" + +/* Private classes */ + +enum XMLNodeType +{ + xml_node, + xml_subtree +}; + +/* Abstract class. XMLTree and XMLNode is derived from this class */ +class XMLAbstractNode +{ + protected: + string name; // Name of this node. + XMLNodeType type; + + public: + /* Constructor */ + XMLAbstractNode( const string & _name, XMLNodeType _type ); + + /* Destructor */ + ~XMLAbstractNode(); + + /* Methods */ + const string & getName(); + XMLNodeType getType(); + + bool isName( const string & _name ); // Compare name to _name. + + virtual void print() = 0; +}; + + +/* Class describing a subtree, derived from XMLAbstractNode */ +class XMLTree : public XMLAbstractNode +{ + protected: + list nodes; // Nodes contained in this tree. + + public: + /* Constructor */ + XMLTree( const string & _name ); + + /* Destructor */ + ~XMLTree(); + + /* Methods */ + void addNode( XMLAbstractNode * newnode ); + bool containsNode( const string & _name ); // Searches for name in list. + XMLAbstractNode * getNode( const string & _name ); + + void print(); +}; + + +/* Class describing an ordinary string-valued node, derived from XMLAbstractNode */ +class XMLNode : public XMLAbstractNode +{ + protected: + string value; // String value. + + public: + /* Constructor */ + XMLNode( const string & _name, const string & _value ); + + /* Destructor */ + ~XMLNode(); + + /* Methods */ + bool isEmpty(); // Contains an empty string? + const string & getValue(); + + void print(); +}; + + + + +void XMLFile::removeComments( string & txt ) +{ + long pos = 0; // Everything up to this point is clean. + + long startFoundAt; // Comment start and end found at these positions. + long endFoundAt; + + /* Search and remove all comment tags */ + do + { + /* Search for comment start */ + startFoundAt = txt.find( "", startFoundAt ); + + /* Error if start but no end is found */ + if( endFoundAt == string::npos ) + throw new ErrorMsg( "Unclosed comment tag encountered! " + "Comment start-tag ''." ); + + /* Remove comment tag */ + txt.erase( startFoundAt, endFoundAt - startFoundAt + 3 ); + + pos = startFoundAt; // Prepare for next search. + + } while( pos < txt.size() ); +} + +void XMLFile::removeStartXML( string & txt ) +{ + long pos = 0; // Everything up to this point is clean. + + long startFoundAt; // Comment start and end found at these positions. + long endFoundAt; + + /* Search and remove the ", startFoundAt ); + + /* Remove tag */ + txt.erase( startFoundAt, endFoundAt - startFoundAt ); +} + + +void XMLFile::removeAttributes( string & txt ) +{ + long pos; // Everything up to this point is clean. + + long startFoundAt; // Tag start and end found at these positions. + long endFoundAt; + + long spaceFoundAt; // Space before attribute found at this position. + long slashFoundAt; // Ending slash found at this position. + + + /* Convert all whitespace to plain spaces, just to make things easier */ + for( pos = 0; pos < txt.size(); pos++ ) + { + if( txt[pos] == '\n' || txt[pos] == '\r' || txt[pos] == '\t' ) + txt.replace( pos, 1, " " ); + } + + pos = 0; + + /* Search and clean all tags */ + do + { + /* Search for tag start */ + startFoundAt = txt.find( "<", pos ); + + /* Exit loop if no tag is found */ + if( startFoundAt == string::npos ) + break; + + /* Search for comment end */ + endFoundAt = txt.find( ">", startFoundAt ); + + /* Error if start but no end is found */ + if( endFoundAt == string::npos ) + throw new ErrorMsg( "Unclosed tag encountered! " + "Tag start token '<' found, but not " + "closing '>'." ); + + /* Remove whitespace before tag name */ + while( txt[startFoundAt+1] == ' ' ) + { + txt.erase( startFoundAt+1, 1 ); // Remove. + endFoundAt--; // String has now shrunk. + } + + /* Search for space before attributes */ + spaceFoundAt = txt.find( " ", startFoundAt ); + if( spaceFoundAt < endFoundAt && spaceFoundAt != string::npos ) // Space found inside tag? + { + // If empty tag, we dont want to remove the / in /> + if ( txt.at(endFoundAt-1) == '/' ) + { + endFoundAt--; + } + + /* Remove attributes */ + txt.erase( spaceFoundAt, endFoundAt - spaceFoundAt ); + endFoundAt -= endFoundAt - spaceFoundAt; // String has now shrunk. + } + + + pos = endFoundAt + 1; // Prepare for next search. + + } while( pos < txt.size() ); +} + + +void XMLFile::readFile( const string & _filename ) +{ + ifstream f; // XML file stream. + string contents; // XML file contents. + string templine; + + /* Attempt to open file */ + f.open( _filename.c_str(), ios::in ); + if( !f ) + throw new ErrorMsg( "Error opening XML file for input!" ); + + /* Read everything into the contents string */ + contents.erase(); + templine.erase(); + do + { + contents += templine + " "; + f >> templine; // This will cause EOF only when reading from the end. + } while( !f.eof() ); + + f.close(); + + /* Remove comments and tag attributes */ + removeComments( contents ); + removeAttributes( contents ); + removeStartXML ( contents ); + + /* Create root node */ + root = new XMLTree( "root" ); + parseFragment( contents, root ); + + Util.progress( "\r\n" ); // Finish progress indicator. +} + + +void XMLFile::parseFragment( string & fragment, XMLTree * parent ) +{ + long startFoundAt; // Tag start and end found at these positions. + long endFoundAt; + + string closingString; // Search string used for finding closing tag. + long closingFoundAt; // Closing tag found at this position. + + string tagName; // These are for recently created nodes. + string tagValue; + + XMLTree * newTree; + XMLNode * newNode; + + long nestedFoundAt; // Nested tags found at this position. + + /* Find top level tags */ + Util.progress( "#" ); // Advance progress indicator. + + while( true ) // Wait for break from inside. + { + /* Find start of tag */ + startFoundAt = fragment.find( "<", 0 ); + if( startFoundAt == string::npos ) // Exit loop if no tags found. + break; + + /* Check if this is a closing tag for a higher level tag pair */ + if( fragment[startFoundAt+1] == '/' ) + break; // Exit loop. + + /* Find end of tag */ + endFoundAt = fragment.find( ">", startFoundAt ); + if( endFoundAt == string::npos ) // Error if end not found. + throw new ErrorMsg( "Unclosed tag encountered! " + "Tag start token '<' found, but no " + "closing '>'." ); + + /* Extract name of tag */ + tagName = fragment.substr( startFoundAt+1, endFoundAt-startFoundAt-1 ); + if( tagName.size() == 0 ) // Error if zero-length tag name. + throw new ErrorMsg( "Unnamed tag encountered! " + "No text between '<' and '>'." ); + + /* Remove tag from fragment */ + fragment.erase( 0, startFoundAt+tagName.size()+2 ); + + /* Check if it is an empty tag */ + if( tagName[tagName.size()-1] == '/' ) + { + /* Create a new empty ordinary node */ + tagName.erase( tagName.size()-1 ); // Remove the slash. + tagValue.erase(); // This tag has no value. + newNode = new XMLNode( tagName, tagValue ); + parent->addNode( newNode ); + } else + { + /* Find the matching closing tag for this pair */ + closingString.erase(); + closingString += ""; + closingFoundAt = fragment.find( closingString, 0 ); + if( closingFoundAt == string::npos ) // Error if not found. + throw new ErrorMsg( "Closing tag not found! " + "Opening tag '<" + tagName + ">' found, " + "but not closing '" + closingString + "'." ); + + /* Check for tags inside this tag pair, indicating a subtree */ + nestedFoundAt = fragment.find( "<", 0 ); + if( nestedFoundAt == closingFoundAt ) // No other tags inside? + { + /* Extract contents within tag pair */ + tagValue = fragment.substr( 0, closingFoundAt ); + + /* Create new ordinary node */ + newNode = new XMLNode( tagName, tagValue ); + parent->addNode( newNode ); + } else + { + /* Create new subtree and parse it's fragment */ + newTree = new XMLTree( tagName ); + parent->addNode( newTree ); + parseFragment( fragment, newTree ); + + /* Check that we can still find the closing tag */ + closingFoundAt = fragment.find( closingString, 0 ); + if( closingFoundAt == string::npos ) + throw new ErrorMsg( "Closing tag not found! " + "Opening tag '<" + tagName + ">' found, " + "but not closing '" + closingString + "'." ); + } + + /* Remove value and closing tag from fragment */ + fragment.erase( 0, closingFoundAt + closingString.size() ); + } + }; +} + + +/* Constructor */ +XMLFile::XMLFile( const string & _filename ) +{ + readFile( _filename ); +} + + +/* Destructor */ +XMLFile::~XMLFile() +{ + if( root != NULL ) + delete root; +} + + +bool XMLFile::exists( const string & path ) +{ + XMLAbstractNode * currentNode = root; + XMLTree * currentTree; + long namePos; // Position for current tag name in path. + long separatorPos; // Position for #-separator following tag name. + string tagName; // Current tag name. + + namePos = 0; + + while( true ) // This will break out from the inside. + { + /* Find separator or set pos to end of text */ + separatorPos = path.find( "\\", namePos ); + if( separatorPos == string::npos ) + separatorPos = path.size(); + + /* Extract tag name and check if it exists */ + tagName = path.substr( namePos, separatorPos-namePos ); + currentTree = (XMLTree *) currentNode; // It is indeed a tree. + if( !currentTree->containsNode( tagName ) ) + return false; // Not found. + + currentNode = currentTree->getNode( tagName ); + + /* Are there more tags in the path? */ + if( separatorPos < path.size() ) + { + /* Now, the current node better be a tree */ + if( currentNode->getType() != xml_subtree ) + { + return false; // Not found. + } else + { + namePos = separatorPos + 1; // Advance position in path. + } + } else + { + break; // Found, exit loop. + } + } + + return true; // Found! +} + + +const string & XMLFile::getValue( const string & path ) +{ + XMLAbstractNode * currentNode = root; + XMLTree * currentTree; + long namePos; // Position for current tag name in path. + long separatorPos; // Position for #-separator following tag name. + string tagName; // Current tag name. + + namePos = 0; + + while( true ) // This will break out from the inside. + { + /* Find separator or set pos to end of text */ + separatorPos = path.find( "\\", namePos ); + if( separatorPos == string::npos ) + separatorPos = path.size(); + + /* Extract tag name and check if it exists */ + tagName = path.substr( namePos, separatorPos-namePos ); + currentTree = (XMLTree *) currentNode; // It is indeed a tree. + if( !currentTree->containsNode( tagName ) ) + throw new ErrorMsg( "Node '" + tagName + "' not found!" ); + + currentNode = currentTree->getNode( tagName ); + + /* Are there more tags in the path? */ + if( separatorPos < path.size() ) + { + /* Now, the current node better be a tree */ + if( currentNode->getType() != xml_subtree ) + { + throw new ErrorMsg( "Illegal path: (" + path + ")!" ); + } else + { + namePos = separatorPos + 1; // Advance position in path. + } + } else + { + break; // Found, exit loop. + } + } + + /* Check that the current node is an ordinary node */ + if( currentNode->getType() != xml_node ) + throw new ErrorMsg( "Node '" + tagName + "' is not an element!" ); + + return ((XMLNode *) currentNode)->getValue(); +} + + +void XMLFile::print() +{ + root->print(); +} + + +/* Constructor */ +XMLAbstractNode::XMLAbstractNode( const string & _name, XMLNodeType _type ) : + name( _name ), + type( _type ) +{ + // Node code here. +} + + +/* Destructor */ +XMLAbstractNode::~XMLAbstractNode() +{ + // No code here. +} + + +const string & XMLAbstractNode::getName() +{ + return name; +} + + +XMLNodeType XMLAbstractNode::getType() +{ + return type; +} + + +bool XMLAbstractNode::isName( const string & _name ) +{ + return (name == _name); +} + + +/* Constructor */ +XMLTree::XMLTree( const string & _name ) : + XMLAbstractNode::XMLAbstractNode( _name, xml_subtree ) +{ + // No code here. +} + + +/* Destructor */ +XMLTree::~XMLTree() +{ + /* Create an iterator for the list */ + list::iterator i; + + /* Destruct all contained nodes */ + for( i = nodes.begin(); i != nodes.end(); i++ ) + { + delete (*i); + } +} + + +void XMLTree::addNode( XMLAbstractNode * newnode ) +{ + nodes.push_back( newnode ); +} + + +bool XMLTree::containsNode( const string & _name ) +{ + /* Create an iterator for the list */ + list::iterator i; + + /* Search for the node with name _name */ + i = nodes.begin(); + + while( i != nodes.end() ) + { + if( (*i)->isName( _name ) ) + return true; + + i++; + } + + return false; +} + + +XMLAbstractNode * XMLTree::getNode( const string & _name ) +{ + /* Create an iterator for the list */ + list::iterator i; + + /* Search for the node with name _name */ + i = nodes.begin(); + + while( i != nodes.end() ) + { + if( (*i)->isName( _name ) ) + return *i; + + i++; + } + + return NULL; +} + + +void XMLTree::print() +{ + /* Create an iterator for the list */ + list::iterator i; + + cout << "TREE[ Name: \"" << name << "\" ]:" << endl; + + /* Search for the node with name _name */ + i = nodes.begin(); + + while( i != nodes.end() ) + { + (*i)->print(); + + i++; + } + + cout << ":END[\"" << name << "\"]" << endl; +} + + +/* Constructor */ +XMLNode::XMLNode( const string & _name, const string & _value ) : + XMLAbstractNode::XMLAbstractNode( _name, xml_node ), + value( _value ) +{ + // No code here. +} + + +/* Destructor */ +XMLNode::~XMLNode() +{ + // Node code here. +} + + +bool XMLNode::isEmpty() +{ + return value.empty(); +} + + +const string & XMLNode::getValue() +{ + return value; +} + + +void XMLNode::print() +{ + cout << "NODE[ Name: \"" << name << "\" Value: \"" << value << "\" ]" << endl; +} + +/* end of file */ + diff --git a/ports/bdk-atxx4-mstp/avrosp/XMLParser.hpp b/ports/bdk-atxx4-mstp/avrosp/XMLParser.hpp index 5cb2ed92..7340c4fc 100644 --- a/ports/bdk-atxx4-mstp/avrosp/XMLParser.hpp +++ b/ports/bdk-atxx4-mstp/avrosp/XMLParser.hpp @@ -1,65 +1,65 @@ -/***************************************************************************** - * - * Atmel Corporation - * - * File : XMLParser.hpp - * Compiler : Dev-C++ 4.9.8.0 - http://bloodshed.net/dev/ - * Revision : $Revision: 3419 $ - * Date : $Date: 2008-02-22 09:56:34 +0100 (fr, 22 feb 2008) $ - * Updated by : $Author: khole $ - * - * Support mail : avr@atmel.com - * - * Target platform : Win32 - * - * AppNote : AVR911 - AVR Open-source Programmer - * - * Description : A simple XML DOM-like parser. It builds a complete tree from - * the XML file. IT supports
tags, but not tag attributes. - * - * - ****************************************************************************/ -#ifndef XMLPARSER_HPP -#define XMLPARSER_HPP - -using namespace std; - -#include "ErrorMsg.hpp" -#include "Utility.hpp" -#include -#include -#include - -class XMLAbstractNode; // Preliminary definitions. -class XMLTree; -class XMLNode; - - -/* Main XML file class. Contains search methods and entire XML tree */ -class XMLFile -{ - protected: - XMLTree * root; // The root node, either a subtree or an ordinary node. - - void XMLFile::removeStartXML( string & txt ); // Remove the start xml tag. - void removeComments( string & txt ); // Remove comment tags. - void removeAttributes( string & txt ); // Remove attributes from tags. - void readFile( const string & _filename ); // Read XML file. - void parseFragment( string & fragment, XMLTree * parent ); - - public: - /* Constructors */ - XMLFile( const string & _filename ); - - /* Destructor */ - ~XMLFile(); - - /* Methods */ - bool exists( const string & path ); // Checks if node exists. - const string & getValue( const string & path ); // Get node value. - - void print(); -}; - -#endif - +/***************************************************************************** + * + * Atmel Corporation + * + * File : XMLParser.hpp + * Compiler : Dev-C++ 4.9.8.0 - http://bloodshed.net/dev/ + * Revision : $Revision: 3419 $ + * Date : $Date: 2008-02-22 09:56:34 +0100 (fr, 22 feb 2008) $ + * Updated by : $Author: khole $ + * + * Support mail : avr@atmel.com + * + * Target platform : Win32 + * + * AppNote : AVR911 - AVR Open-source Programmer + * + * Description : A simple XML DOM-like parser. It builds a complete tree from + * the XML file. IT supports
tags, but not tag attributes. + * + * + ****************************************************************************/ +#ifndef XMLPARSER_HPP +#define XMLPARSER_HPP + +using namespace std; + +#include "ErrorMsg.hpp" +#include "Utility.hpp" +#include +#include +#include + +class XMLAbstractNode; // Preliminary definitions. +class XMLTree; +class XMLNode; + + +/* Main XML file class. Contains search methods and entire XML tree */ +class XMLFile +{ + protected: + XMLTree * root; // The root node, either a subtree or an ordinary node. + + void XMLFile::removeStartXML( string & txt ); // Remove the start xml tag. + void removeComments( string & txt ); // Remove comment tags. + void removeAttributes( string & txt ); // Remove attributes from tags. + void readFile( const string & _filename ); // Read XML file. + void parseFragment( string & fragment, XMLTree * parent ); + + public: + /* Constructors */ + XMLFile( const string & _filename ); + + /* Destructor */ + ~XMLFile(); + + /* Methods */ + bool exists( const string & path ); // Checks if node exists. + const string & getValue( const string & path ); // Get node value. + + void print(); +}; + +#endif + diff --git a/ports/bdk-atxx4-mstp/avrosp/main.cpp b/ports/bdk-atxx4-mstp/avrosp/main.cpp index 561176ef..e78ffbd9 100644 --- a/ports/bdk-atxx4-mstp/avrosp/main.cpp +++ b/ports/bdk-atxx4-mstp/avrosp/main.cpp @@ -1,47 +1,47 @@ -/***************************************************************************** - * - * Atmel Corporation - * - * File : main.cpp - * Compiler : Dev-C++ 4.9.8.0 - http://bloodshed.net/dev/ - * Revision : $Revision: 1163 $ - * Date : $Date: 2006-08-02 15:38:16 +0200 (on, 02 aug 2006) $ - * Updated by : $Author: ohlia $ - * - * Support mail : avr@atmel.com - * - * Target platform : Win32 - * - * AppNote : AVR911 - AVR Open-source Programmer - * - * Description : AVROSP main entry function. - * - * - ****************************************************************************/ -#include "JobInfo.hpp" -#include -#include - -using namespace std; - - -int main(int argc, char *argv[]) -{ - JobInfo j; - - try - { - j.parseCommandline( argc, argv ); - j.doJob(); - } - catch( ErrorMsg * e ) - { - cout << endl << "An error occurred:" << endl; - cout << " [" << e->What() << "]" << endl; - - delete e; - } - - return 0; -} - +/***************************************************************************** + * + * Atmel Corporation + * + * File : main.cpp + * Compiler : Dev-C++ 4.9.8.0 - http://bloodshed.net/dev/ + * Revision : $Revision: 1163 $ + * Date : $Date: 2006-08-02 15:38:16 +0200 (on, 02 aug 2006) $ + * Updated by : $Author: ohlia $ + * + * Support mail : avr@atmel.com + * + * Target platform : Win32 + * + * AppNote : AVR911 - AVR Open-source Programmer + * + * Description : AVROSP main entry function. + * + * + ****************************************************************************/ +#include "JobInfo.hpp" +#include +#include + +using namespace std; + + +int main(int argc, char *argv[]) +{ + JobInfo j; + + try + { + j.parseCommandline( argc, argv ); + j.doJob(); + } + catch( ErrorMsg * e ) + { + cout << endl << "An error occurred:" << endl; + cout << " [" << e->What() << "]" << endl; + + delete e; + } + + return 0; +} + diff --git a/ports/bdk-atxx4-mstp/bacnet.aps b/ports/bdk-atxx4-mstp/bacnet.aps index 11fa6d07..cabb7d24 100644 --- a/ports/bdk-atxx4-mstp/bacnet.aps +++ b/ports/bdk-atxx4-mstp/bacnet.aps @@ -1 +1 @@ -bacnet29-Apr-2009 08:16:5307-Oct-2010 10:30:19241029-Apr-2009 08:16:5344, 15, 0, 623AVR GCCbacnet.elfC:\code\bacnet-stack\ports\bdk-atxx4-mstp\JTAGICE mkIIATmega644P.xmlfalseR00R01R02R03R04R05R06R07R08R09R10R11R12R13R14R15R16R17R18R19R20R21R22R23R24R25R26R27R28R29R30R31Auto00char_stringapdupkt0main.ctimer2.ceeprom.cinit.cinput.cled.crs485.cseeprom.cserial.cstack.cdlmstp.cbo.cbi.cai.cdevice.cwatchdog.cadc.cbacnet.cfuses.ctest.ctimer.cC:\code\bacnet-stack\demo\handler\noserv.cC:\code\bacnet-stack\demo\handler\s_iam.cC:\code\bacnet-stack\demo\handler\s_ihave.cC:\code\bacnet-stack\demo\handler\txbuf.cC:\code\bacnet-stack\demo\handler\h_dcc.cC:\code\bacnet-stack\demo\handler\h_npdu.cC:\code\bacnet-stack\demo\handler\h_rd.cC:\code\bacnet-stack\demo\handler\h_rp.cC:\code\bacnet-stack\demo\handler\h_rpm.cC:\code\bacnet-stack\demo\handler\h_whohas.cC:\code\bacnet-stack\demo\handler\h_whois.cC:\code\bacnet-stack\demo\handler\h_wp.cC:\code\bacnet-stack\src\reject.cC:\code\bacnet-stack\src\ringbuf.cC:\code\bacnet-stack\src\rp.cC:\code\bacnet-stack\src\rpm.cC:\code\bacnet-stack\src\whohas.cC:\code\bacnet-stack\src\whois.cC:\code\bacnet-stack\src\wp.cC:\code\bacnet-stack\src\abort.cC:\code\bacnet-stack\src\apdu.cC:\code\bacnet-stack\src\bacaddr.cC:\code\bacnet-stack\src\bacapp.cC:\code\bacnet-stack\src\bacdcode.cC:\code\bacnet-stack\src\bacerror.cC:\code\bacnet-stack\src\bacint.cC:\code\bacnet-stack\src\bacreal.cC:\code\bacnet-stack\src\bacstr.cC:\code\bacnet-stack\src\crc.cC:\code\bacnet-stack\src\dcc.cC:\code\bacnet-stack\src\fifo.cC:\code\bacnet-stack\src\iam.cC:\code\bacnet-stack\src\ihave.cC:\code\bacnet-stack\src\npdu.cC:\code\bacnet-stack\src\rd.cC:\code\bacnet-stack\src\memcopy.cav.ctimer.heeprom.hhardware.hiar2gcc.hinit.hinput.hled.hnvdata.hrs485.hseeprom.hserial.hwatchdog.hadc.hbacnet.hstack.htest.hdefault\bacnet.lssdefault\bacnet.mapdefaultYESMakefileatmega644p111bacnet.elfdefault\0.\..\..\include\-Wall -gdwarf-2 -std=gnu99 -mcall-prologues -finline-functions-called-once -ffunction-sections -fdata-sections -Wstrict-prototypes -Wmissing-prototypes -DBACDL_MSTP -DMAX_APDU=128 -DBIG_ENDIAN=0 -DMAX_TSM_TRANSACTIONS=0 -DBACAPP_BOOLEAN -DBACAPP_REAL -DBACAPP_OBJECT_ID -DBACAPP_UNSIGNED -DBACAPP_ENUMERATED -DBACAPP_CHARACTER_STRING -DWRITE_PROPERTY -g -DF_CPU=18432000UL -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums-Wl,--gc-sections,-staticdefault1C:\WinAVR-20090313\bin\avr-gcc.exeC:\WinAVR-20090313\utils\bin\make.exe00000main.c25900001rs485.c25800002bacnet.c25800003device.c25800004C:\code\bacnet-stack\src\fifo.c25800005timer.c25800006timer2.c25800007hardware.h100008adc.c259 +bacnet29-Apr-2009 08:16:5307-Oct-2010 10:30:19241029-Apr-2009 08:16:5344, 15, 0, 623AVR GCCbacnet.elfC:\code\bacnet-stack\ports\bdk-atxx4-mstp\JTAGICE mkIIATmega644P.xmlfalseR00R01R02R03R04R05R06R07R08R09R10R11R12R13R14R15R16R17R18R19R20R21R22R23R24R25R26R27R28R29R30R31Auto00char_stringapdupkt0main.ctimer2.ceeprom.cinit.cinput.cled.crs485.cseeprom.cserial.cstack.cdlmstp.cbo.cbi.cai.cdevice.cwatchdog.cadc.cbacnet.cfuses.ctest.ctimer.cC:\code\bacnet-stack\demo\handler\noserv.cC:\code\bacnet-stack\demo\handler\s_iam.cC:\code\bacnet-stack\demo\handler\s_ihave.cC:\code\bacnet-stack\demo\handler\txbuf.cC:\code\bacnet-stack\demo\handler\h_dcc.cC:\code\bacnet-stack\demo\handler\h_npdu.cC:\code\bacnet-stack\demo\handler\h_rd.cC:\code\bacnet-stack\demo\handler\h_rp.cC:\code\bacnet-stack\demo\handler\h_rpm.cC:\code\bacnet-stack\demo\handler\h_whohas.cC:\code\bacnet-stack\demo\handler\h_whois.cC:\code\bacnet-stack\demo\handler\h_wp.cC:\code\bacnet-stack\src\reject.cC:\code\bacnet-stack\src\ringbuf.cC:\code\bacnet-stack\src\rp.cC:\code\bacnet-stack\src\rpm.cC:\code\bacnet-stack\src\whohas.cC:\code\bacnet-stack\src\whois.cC:\code\bacnet-stack\src\wp.cC:\code\bacnet-stack\src\abort.cC:\code\bacnet-stack\src\apdu.cC:\code\bacnet-stack\src\bacaddr.cC:\code\bacnet-stack\src\bacapp.cC:\code\bacnet-stack\src\bacdcode.cC:\code\bacnet-stack\src\bacerror.cC:\code\bacnet-stack\src\bacint.cC:\code\bacnet-stack\src\bacreal.cC:\code\bacnet-stack\src\bacstr.cC:\code\bacnet-stack\src\crc.cC:\code\bacnet-stack\src\dcc.cC:\code\bacnet-stack\src\fifo.cC:\code\bacnet-stack\src\iam.cC:\code\bacnet-stack\src\ihave.cC:\code\bacnet-stack\src\npdu.cC:\code\bacnet-stack\src\rd.cC:\code\bacnet-stack\src\memcopy.cav.ctimer.heeprom.hhardware.hiar2gcc.hinit.hinput.hled.hnvdata.hrs485.hseeprom.hserial.hwatchdog.hadc.hbacnet.hstack.htest.hdefault\bacnet.lssdefault\bacnet.mapdefaultYESMakefileatmega644p111bacnet.elfdefault\0.\..\..\include\-Wall -gdwarf-2 -std=gnu99 -mcall-prologues -finline-functions-called-once -ffunction-sections -fdata-sections -Wstrict-prototypes -Wmissing-prototypes -DBACDL_MSTP -DMAX_APDU=128 -DBIG_ENDIAN=0 -DMAX_TSM_TRANSACTIONS=0 -DBACAPP_BOOLEAN -DBACAPP_REAL -DBACAPP_OBJECT_ID -DBACAPP_UNSIGNED -DBACAPP_ENUMERATED -DBACAPP_CHARACTER_STRING -DWRITE_PROPERTY -g -DF_CPU=18432000UL -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums-Wl,--gc-sections,-staticdefault1C:\WinAVR-20090313\bin\avr-gcc.exeC:\WinAVR-20090313\utils\bin\make.exe00000main.c25900001rs485.c25800002bacnet.c25800003device.c25800004C:\code\bacnet-stack\src\fifo.c25800005timer.c25800006timer2.c25800007hardware.h100008adc.c259 diff --git a/ports/bdk-atxx4-mstp/bacnet.atsln b/ports/bdk-atxx4-mstp/bacnet.atsln index b1c89701..458602e2 100644 --- a/ports/bdk-atxx4-mstp/bacnet.atsln +++ b/ports/bdk-atxx4-mstp/bacnet.atsln @@ -1,20 +1,20 @@ - -Microsoft Visual Studio Solution File, Format Version 11.00 -# Atmel Studio Solution File, Format Version 11.00 -Project("{54F91283-7BC4-4236-8FF9-10F437C3AD48}") = "BACnet Development Kit", "bacnet.cproj", "{1CEFD571-4B50-48FD-B75E-0E968EBBD698}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|AVR = Debug|AVR - Release|AVR = Release|AVR - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {1CEFD571-4B50-48FD-B75E-0E968EBBD698}.Debug|AVR.ActiveCfg = Debug|AVR - {1CEFD571-4B50-48FD-B75E-0E968EBBD698}.Debug|AVR.Build.0 = Debug|AVR - {1CEFD571-4B50-48FD-B75E-0E968EBBD698}.Release|AVR.ActiveCfg = Release|AVR - {1CEFD571-4B50-48FD-B75E-0E968EBBD698}.Release|AVR.Build.0 = Release|AVR - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Atmel Studio Solution File, Format Version 11.00 +Project("{54F91283-7BC4-4236-8FF9-10F437C3AD48}") = "BACnet Development Kit", "bacnet.cproj", "{1CEFD571-4B50-48FD-B75E-0E968EBBD698}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|AVR = Debug|AVR + Release|AVR = Release|AVR + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {1CEFD571-4B50-48FD-B75E-0E968EBBD698}.Debug|AVR.ActiveCfg = Debug|AVR + {1CEFD571-4B50-48FD-B75E-0E968EBBD698}.Debug|AVR.Build.0 = Debug|AVR + {1CEFD571-4B50-48FD-B75E-0E968EBBD698}.Release|AVR.ActiveCfg = Release|AVR + {1CEFD571-4B50-48FD-B75E-0E968EBBD698}.Release|AVR.Build.0 = Release|AVR + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/ports/bdk-atxx4-mstp/bacnet.c b/ports/bdk-atxx4-mstp/bacnet.c index fb44d061..01ea1eaf 100644 --- a/ports/bdk-atxx4-mstp/bacnet.c +++ b/ports/bdk-atxx4-mstp/bacnet.c @@ -26,7 +26,7 @@ #include /* hardware layer includes */ #include "hardware.h" -#include "timer.h" +#include "bacnet/basic/sys/mstimer.h" #include "seeprom.h" #include "nvdata.h" #include "rs485.h" @@ -34,25 +34,25 @@ #include "adc.h" #include "led.h" /* BACnet Stack includes */ -#include "datalink.h" -#include "npdu.h" -#include "handlers.h" -#include "client.h" -#include "txbuf.h" -#include "dcc.h" -#include "iam.h" -#include "device.h" -#include "ai.h" -#include "av.h" -#include "bi.h" -#include "bo.h" +#include "bacnet/datalink/datalink.h" +#include "bacnet/npdu.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/dcc.h" +#include "bacnet/iam.h" +#include "bacnet/basic/object/device.h" +#include "bacnet/basic/object/ai.h" +#include "bacnet/basic/object/av.h" +#include "bacnet/basic/object/bi.h" +#include "bacnet/basic/object/bo.h" /* me */ #include "bacnet.h" /* MAC Address of MS/TP */ static uint8_t MSTP_MAC_Address; /* timer for device communications control */ -static struct itimer DCC_Timer; +static struct mstimer DCC_Timer; #define DCC_CYCLE_SECONDS 1 static bool seeprom_version_test( @@ -140,7 +140,7 @@ void bacnet_init( apdu_set_confirmed_handler(SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL, handler_device_communication_control); /* start the cyclic 1 second timer for DCC */ - timer_interval_start_seconds(&DCC_Timer, DCC_CYCLE_SECONDS); + mstimer_set(&DCC_Timer, DCC_CYCLE_SECONDS*1000); /* Hello World! */ Send_I_Am(&Handler_Transmit_Buffer[0]); } @@ -208,8 +208,8 @@ void bacnet_task( } } /* handle the communication timer */ - if (timer_interval_expired(&DCC_Timer)) { - timer_interval_reset(&DCC_Timer); + if (mstimer_expired(&DCC_Timer)) { + mstimer_reset(&DCC_Timer); dcc_timer_seconds(DCC_CYCLE_SECONDS); } /* handle the messaging */ diff --git a/ports/bdk-atxx4-mstp/bacnet.cproj b/ports/bdk-atxx4-mstp/bacnet.cproj index efcdb607..f3dfd7a2 100644 --- a/ports/bdk-atxx4-mstp/bacnet.cproj +++ b/ports/bdk-atxx4-mstp/bacnet.cproj @@ -1,355 +1,398 @@ - - - - 2.0 - 6.1 - com.Atmel.AVRGCC8.C - {1cefd571-4b50-48fd-b75e-0e968ebbd698} - ATmega644P - none - Executable - C - $(MSBuildProjectName) - .elf - $(MSBuildProjectDirectory)\$(Configuration) - BACnet Development Kit - BACnet Development Kit - BACnet Development Kit - Native - true - false - - 0 - true - 0x20000000 - true - - 2 - - - - - - - - - - - - - - - - - True - True - True - True - True - True - - BACDL_MSTP - MAX_APDU=128 - BIG_ENDIAN=0 - MAX_TSM_TRANSACTIONS=0 - MSTP_PDU_PACKET_COUNT=2 - MAX_CHARACTER_STRING_BYTES=64 - MAX_OCTET_STRING_BYTES=64 - NDEBUG - - - .. - ../../../demo/object - ../../../include - ../../../ports/bdk-atxx4-mstp - - True - True - True - libm - Optimize for size (-Os) - - - False - all - clean - D:\code\bacnet-stack\ports\bdk-atxx4-mstp\Makefile - - - - - True - True - True - True - True - True - - BACDL_MSTP - MAX_APDU=128 - BIG_ENDIAN=0 - MAX_TSM_TRANSACTIONS=0 - MSTP_PDU_PACKET_COUNT=2 - MAX_CHARACTER_STRING_BYTES=64 - MAX_OCTET_STRING_BYTES=64 - DEBUG - - ..../../../demo/object../../../include - True - True - True - libm - Optimize (-O1) - Default (-g2) - Default (-Wa,-g) - - - False - all - clean - D:\code\bacnet-stack\ports\bdk-atxx4-mstp\Makefile - - - - compile - BACnet Handlers\h_dcc.c - - - compile - BACnet Handlers\h_npdu.c - - - compile - BACnet Handlers\h_rd.c - - - compile - BACnet Handlers\h_rp.c - - - compile - BACnet Handlers\h_rpm.c - - - compile - BACnet Handlers\h_whohas.c - - - compile - BACnet Handlers\h_whois.c - - - compile - BACnet Handlers\h_wp.c - - - compile - BACnet Handlers\noserv.c - - - compile - BACnet Handlers\s_iam.c - - - compile - BACnet Handlers\s_ihave.c - - - compile - BACnet Handlers\txbuf.c - - - compile - adc.c - - - compile - ai.c - - - compile - av.c - - - compile - bacnet.c - - - compile - bi.c - - - compile - bname.c - - - compile - bo.c - - - compile - device.c - - - compile - dlmstp.c - - - compile - eeprom.c - - - compile - fuses.c - - - compile - init.c - - - compile - input.c - - - compile - led.c - - - compile - main.c - - - compile - rs485.c - - - compile - seeprom.c - - - compile - serial.c - - - compile - stack.c - - - compile - test.c - - - compile - timer.c - - - compile - timer2.c - - - compile - watchdog.c - - - compile - BACnet Core\abort.c - - - compile - BACnet Core\apdu.c - - - compile - BACnet Core\bacaddr.c - - - compile - BACnet Core\bacapp.c - - - compile - BACnet Core\bacdcode.c - - - compile - BACnet Core\bacerror.c - - - compile - BACnet Core\bacint.c - - - compile - BACnet Core\bacreal.c - - - compile - BACnet Core\bacstr.c - - - compile - BACnet Core\crc.c - - - compile - BACnet Core\dcc.c - - - compile - BACnet Core\fifo.c - - - compile - BACnet Core\iam.c - - - compile - BACnet Core\ihave.c - - - compile - BACnet Core\memcopy.c - - - compile - BACnet Core\npdu.c - - - compile - BACnet Core\rd.c - - - compile - BACnet Core\reject.c - - - compile - BACnet Core\ringbuf.c - - - compile - BACnet Core\rp.c - - - compile - BACnet Core\rpm.c - - - compile - BACnet Core\whohas.c - - - compile - BACnet Core\whois.c - - - compile - BACnet Core\wp.c - - - - - - - + + + + 2.0 + 7.0 + com.Atmel.AVRGCC8.C + {1cefd571-4b50-48fd-b75e-0e968ebbd698} + ATmega644P + none + Executable + C + $(MSBuildProjectName) + .elf + $(MSBuildProjectDirectory)\$(Configuration) + BACnet Development Kit + BACnet Development Kit + BACnet Development Kit + Native + true + false + + 0 + true + 0x20000000 + true + + 2 + + + + + + + + + + + + + true + 0 + + + + + + -mmcu=atmega644p -B "%24(PackRepoDir)\atmel\ATmega_DFP\1.3.300\gcc\dev\atmega644p" + True + True + True + True + False + True + True + + + BACDL_MSTP + MAX_APDU=128 + BIG_ENDIAN=0 + MAX_TSM_TRANSACTIONS=0 + MSTP_PDU_PACKET_COUNT=2 + MAX_CHARACTER_STRING_BYTES=64 + MAX_OCTET_STRING_BYTES=64 + NDEBUG + + + + + .. + ../../../src + %24(PackRepoDir)\atmel\ATmega_DFP\1.3.300\include + ../../../ports/bdk-atxx4-mstp + + + True + True + True + + + libm + + + + + %24(PackRepoDir)\atmel\ATmega_DFP\1.3.300\include + + + Optimize for size (-Os) + + + False + all + clean + D:\code\bacnet-stack\ports\bdk-atxx4-mstp\Makefile + + + + + -mmcu=atmega644p -B "%24(PackRepoDir)\atmel\ATmega_DFP\1.3.300\gcc\dev\atmega644p" + True + True + True + True + False + True + True + + + BACDL_MSTP + MAX_APDU=128 + BIG_ENDIAN=0 + MAX_TSM_TRANSACTIONS=0 + MSTP_PDU_PACKET_COUNT=2 + MAX_CHARACTER_STRING_BYTES=64 + MAX_OCTET_STRING_BYTES=64 + DEBUG + + + + + .. + ../../../src + %24(PackRepoDir)\atmel\ATmega_DFP\1.3.300\include + ../../../demo/object + ../../../include + + + True + True + True + + + libm + + + + + %24(PackRepoDir)\atmel\ATmega_DFP\1.3.300\include + + + Optimize (-O1) + Default (-g2) + Default (-Wa,-g) + + + False + all + clean + D:\code\bacnet-stack\ports\bdk-atxx4-mstp\Makefile + + + + compile + BACnet Handlers\h_dcc.c + + + compile + BACnet Handlers\h_npdu.c + + + compile + BACnet Handlers\h_apdu.c + + + compile + BACnet Handlers\h_rd.c + + + compile + BACnet Handlers\h_rp.c + + + compile + BACnet Handlers\h_rpm.c + + + compile + BACnet Handlers\h_whohas.c + + + compile + BACnet Handlers\h_whois.c + + + compile + BACnet Handlers\h_wp.c + + + compile + BACnet Handlers\h_noserv.c + + + compile + BACnet Handlers\s_iam.c + + + compile + BACnet Handlers\s_ihave.c + + + compile + BACnet Handlers\tsm.c + + + compile + adc.c + + + compile + ai.c + + + compile + av.c + + + compile + bacnet.c + + + compile + bi.c + + + compile + bname.c + + + compile + bo.c + + + compile + device.c + + + compile + dlmstp.c + + + compile + eeprom.c + + + compile + fuses.c + + + compile + init.c + + + compile + input.c + + + compile + led.c + + + compile + main.c + + + compile + rs485.c + + + compile + seeprom.c + + + compile + serial.c + + + compile + stack.c + + + compile + test.c + + + compile + mstimer-init.c + + + compile + watchdog.c + + + compile + BACnet Core\abort.c + + + compile + BACnet Core\bacaddr.c + + + compile + BACnet Core\bacapp.c + + + compile + BACnet Core\bacdcode.c + + + compile + BACnet Core\bacerror.c + + + compile + BACnet Core\bacint.c + + + compile + BACnet Core\bacreal.c + + + compile + BACnet Core\bacstr.c + + + compile + BACnet Core\crc.c + + + compile + BACnet Core\dcc.c + + + compile + BACnet Core\fifo.c + + + compile + BACnet Core\iam.c + + + compile + BACnet Core\ihave.c + + + compile + BACnet Core\lighting.c + + + compile + BACnet Core\memcopy.c + + + compile + BACnet Core\npdu.c + + + compile + BACnet Core\rd.c + + + compile + BACnet Core\reject.c + + + compile + BACnet Core\mstimer.c + + + compile + BACnet Core\ringbuf.c + + + compile + BACnet Core\rp.c + + + compile + BACnet Core\rpm.c + + + compile + BACnet Core\whohas.c + + + compile + BACnet Core\whois.c + + + compile + BACnet Core\wp.c + + + + + + + \ No newline at end of file diff --git a/ports/bdk-atxx4-mstp/bacnet.ewp b/ports/bdk-atxx4-mstp/bacnet.ewp index 31b246d2..ae9bde2b 100644 --- a/ports/bdk-atxx4-mstp/bacnet.ewp +++ b/ports/bdk-atxx4-mstp/bacnet.ewp @@ -10,9 +10,9 @@ 1 General - 11 + 12 - 9 + 10 1 1 + + @@ -416,8 +424,7 @@ @@ -725,9 +733,9 @@ XLINK - 2 + 3 - 13 + 16 1 1 + + + + + + + + + + + @@ -1023,9 +1076,9 @@ 0 General - 11 + 12 - 9 + 10 1 0 + + @@ -1429,8 +1490,7 @@ @@ -1738,9 +1799,9 @@ XLINK - 2 + 3 - 13 + 16 1 0 + + + + + + + + + + + @@ -2029,117 +2135,126 @@ - BACnet-Core + BACnet Basic - $PROJ_DIR$\..\..\src\abort.c + $PROJ_DIR$\..\..\src\bacnet\basic\service\h_apdu.c - $PROJ_DIR$\..\..\src\apdu.c + $PROJ_DIR$\..\..\src\bacnet\basic\service\h_dcc.c - $PROJ_DIR$\..\..\src\bacaddr.c + $PROJ_DIR$\..\..\src\bacnet\basic\service\h_noserv.c - $PROJ_DIR$\..\..\src\bacapp.c + $PROJ_DIR$\..\..\src\bacnet\basic\npdu\h_npdu.c - $PROJ_DIR$\..\..\src\bacdcode.c + $PROJ_DIR$\..\..\src\bacnet\basic\service\h_rd.c - $PROJ_DIR$\..\..\src\bacerror.c + $PROJ_DIR$\..\..\src\bacnet\basic\service\h_rp.c - $PROJ_DIR$\..\..\src\bacint.c + $PROJ_DIR$\..\..\src\bacnet\basic\service\h_rpm.c - $PROJ_DIR$\..\..\src\bacreal.c + $PROJ_DIR$\..\..\src\bacnet\basic\service\h_whohas.c - $PROJ_DIR$\..\..\src\bacstr.c + $PROJ_DIR$\..\..\src\bacnet\basic\service\h_whois.c - $PROJ_DIR$\..\..\src\crc.c + $PROJ_DIR$\..\..\src\bacnet\basic\service\h_wp.c - $PROJ_DIR$\..\..\src\dcc.c + $PROJ_DIR$\..\..\src\bacnet\basic\service\s_iam.c - $PROJ_DIR$\..\..\src\fifo.c + $PROJ_DIR$\..\..\src\bacnet\basic\service\s_ihave.c - $PROJ_DIR$\..\..\src\iam.c - - - $PROJ_DIR$\..\..\src\ihave.c - - - $PROJ_DIR$\..\..\src\memcopy.c - - - $PROJ_DIR$\..\..\src\npdu.c - - - $PROJ_DIR$\..\..\src\rd.c - - - $PROJ_DIR$\..\..\src\reject.c - - - $PROJ_DIR$\..\..\src\ringbuf.c - - - $PROJ_DIR$\..\..\src\rp.c - - - $PROJ_DIR$\..\..\src\rpm.c - - - $PROJ_DIR$\..\..\src\whohas.c - - - $PROJ_DIR$\..\..\src\whois.c - - - $PROJ_DIR$\..\..\src\wp.c + $PROJ_DIR$\..\..\src\bacnet\basic\tsm\tsm.c - BACnet-Demo + BACnet Basic Sys - $PROJ_DIR$\..\..\demo\handler\h_dcc.c + $PROJ_DIR$\..\..\src\bacnet\basic\sys\fifo.c - $PROJ_DIR$\..\..\demo\handler\h_npdu.c + $PROJ_DIR$\..\..\src\bacnet\basic\sys\mstimer.c - $PROJ_DIR$\..\..\demo\handler\h_rd.c + $PROJ_DIR$\..\..\src\bacnet\basic\sys\ringbuf.c + + + + BACnet Datalink + + $PROJ_DIR$\..\..\src\bacnet\datalink\crc.c + + + + BACnet-Core + + $PROJ_DIR$\..\..\src\bacnet\abort.c - $PROJ_DIR$\..\..\demo\handler\h_rp.c + $PROJ_DIR$\..\..\src\bacnet\bacaddr.c - $PROJ_DIR$\..\..\demo\handler\h_rpm.c + $PROJ_DIR$\..\..\src\bacnet\bacapp.c - $PROJ_DIR$\..\..\demo\handler\h_whohas.c + $PROJ_DIR$\..\..\src\bacnet\bacdcode.c - $PROJ_DIR$\..\..\demo\handler\h_whois.c + $PROJ_DIR$\..\..\src\bacnet\bacerror.c - $PROJ_DIR$\..\..\demo\handler\h_wp.c + $PROJ_DIR$\..\..\src\bacnet\bacint.c - $PROJ_DIR$\..\..\demo\handler\noserv.c + $PROJ_DIR$\..\..\src\bacnet\bacreal.c - $PROJ_DIR$\..\..\demo\handler\s_iam.c + $PROJ_DIR$\..\..\src\bacnet\bacstr.c - $PROJ_DIR$\..\..\demo\handler\s_ihave.c + $PROJ_DIR$\..\..\src\bacnet\dcc.c - $PROJ_DIR$\..\..\demo\handler\txbuf.c + $PROJ_DIR$\..\..\src\bacnet\iam.c + + + $PROJ_DIR$\..\..\src\bacnet\ihave.c + + + $PROJ_DIR$\..\..\src\bacnet\memcopy.c + + + $PROJ_DIR$\..\..\src\bacnet\npdu.c + + + $PROJ_DIR$\..\..\src\bacnet\rd.c + + + $PROJ_DIR$\..\..\src\bacnet\reject.c + + + $PROJ_DIR$\..\..\src\bacnet\rp.c + + + $PROJ_DIR$\..\..\src\bacnet\rpm.c + + + $PROJ_DIR$\..\..\src\bacnet\whohas.c + + + $PROJ_DIR$\..\..\src\bacnet\whois.c + + + $PROJ_DIR$\..\..\src\bacnet\wp.c @@ -2187,6 +2302,9 @@ $PROJ_DIR$\main.c + + $PROJ_DIR$\mstimer-init.c + $PROJ_DIR$\rs485.c @@ -2202,12 +2320,6 @@ $PROJ_DIR$\test.c - - $PROJ_DIR$\timer.c - - - $PROJ_DIR$\timer2.c - $PROJ_DIR$\watchdog.c diff --git a/ports/bdk-atxx4-mstp/bacnet.hzp b/ports/bdk-atxx4-mstp/bacnet.hzp index fad8f64a..6f1f7a1a 100644 --- a/ports/bdk-atxx4-mstp/bacnet.hzp +++ b/ports/bdk-atxx4-mstp/bacnet.hzp @@ -1,7 +1,7 @@ - + @@ -25,8 +25,7 @@ - - + @@ -34,44 +33,47 @@ - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + diff --git a/ports/bdk-atxx4-mstp/bi.c b/ports/bdk-atxx4-mstp/bi.c index 23eb9779..551d7985 100644 --- a/ports/bdk-atxx4-mstp/bi.c +++ b/ports/bdk-atxx4-mstp/bi.c @@ -28,12 +28,12 @@ #include #include #include -#include "bacdef.h" -#include "bacdcode.h" -#include "bacenum.h" -#include "config.h" -#include "bi.h" -#include "handlers.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacenum.h" +#include "bacnet/config.h" +#include "bacnet/basic/object/bi.h" +#include "bacnet/basic/services.h" #ifndef MAX_BINARY_INPUTS #define MAX_BINARY_INPUTS 5 diff --git a/ports/bdk-atxx4-mstp/bname.c b/ports/bdk-atxx4-mstp/bname.c index 45742596..fca9a383 100644 --- a/ports/bdk-atxx4-mstp/bname.c +++ b/ports/bdk-atxx4-mstp/bname.c @@ -27,12 +27,12 @@ #include #include #include "hardware.h" -#include "bacdef.h" -#include "bacdcode.h" -#include "bacstr.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacstr.h" #include "nvdata.h" #include "seeprom.h" -#include "device.h" +#include "bacnet/basic/object/device.h" #include "bname.h" static bool bacnet_name_isvalid( diff --git a/ports/bdk-atxx4-mstp/bname.h b/ports/bdk-atxx4-mstp/bname.h index 37d3be80..a9cb08b0 100644 --- a/ports/bdk-atxx4-mstp/bname.h +++ b/ports/bdk-atxx4-mstp/bname.h @@ -25,7 +25,7 @@ #define BACNET_NAME_H #include -#include "bacstr.h" +#include "bacnet/bacstr.h" #ifdef __cplusplus extern "C" { diff --git a/ports/bdk-atxx4-mstp/bo.c b/ports/bdk-atxx4-mstp/bo.c index edfcc85d..dd8bf612 100644 --- a/ports/bdk-atxx4-mstp/bo.c +++ b/ports/bdk-atxx4-mstp/bo.c @@ -28,16 +28,16 @@ #include #include #include -#include "bacdef.h" -#include "bacdcode.h" -#include "bacenum.h" -#include "config.h" /* the custom stuff */ -#include "wp.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacenum.h" +#include "bacnet/config.h" /* the custom stuff */ +#include "bacnet/wp.h" #include "hardware.h" #include "led.h" #include "nvdata.h" -#include "bo.h" -#include "handlers.h" +#include "bacnet/basic/object/bo.h" +#include "bacnet/basic/services.h" #ifndef MAX_BINARY_OUTPUTS #define MAX_BINARY_OUTPUTS 2 diff --git a/ports/bdk-atxx4-mstp/bootloader/bootloader.aps b/ports/bdk-atxx4-mstp/bootloader/bootloader.aps index 38d614c3..55728bbf 100644 --- a/ports/bdk-atxx4-mstp/bootloader/bootloader.aps +++ b/ports/bdk-atxx4-mstp/bootloader/bootloader.aps @@ -1 +1 @@ -bootloader27-May-2009 06:28:5627-May-2009 06:28:56241027-May-2009 06:28:5644, 15, 0, 623AVR GCCD:\code\bacnet-stack\ports\bdk-atxx4-mstp\bootloader\JTAGICE mkIIATmega644P.xmlfalseR00R01R02R03R04R05R06R07R08R09R10R11R12R13R14R15R16R17R18R19R20R21R22R23R24R25R26R27R28R29R30R31Auto000defaultNOatmega128111bootloader.elfdefault\0-Wall -gdwarf-2 -Os -std=gnu99 -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enumsdefault +bootloader27-May-2009 06:28:5627-May-2009 06:28:56241027-May-2009 06:28:5644, 15, 0, 623AVR GCCD:\code\bacnet-stack\ports\bdk-atxx4-mstp\bootloader\JTAGICE mkIIATmega644P.xmlfalseR00R01R02R03R04R05R06R07R08R09R10R11R12R13R14R15R16R17R18R19R20R21R22R23R24R25R26R27R28R29R30R31Auto000defaultNOatmega128111bootloader.elfdefault\0-Wall -gdwarf-2 -Os -std=gnu99 -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enumsdefault diff --git a/ports/bdk-atxx4-mstp/device.c b/ports/bdk-atxx4-mstp/device.c index e3aa8b5c..2419d4e7 100644 --- a/ports/bdk-atxx4-mstp/device.c +++ b/ports/bdk-atxx4-mstp/device.c @@ -26,25 +26,28 @@ #include #include #include -#include "bacdef.h" -#include "bacdcode.h" -#include "bacstr.h" -#include "bacenum.h" -#include "apdu.h" -#include "dcc.h" -#include "datalink.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacstr.h" +#include "bacnet/bacenum.h" +#include "bacnet/apdu.h" +#include "bacnet/dcc.h" +#include "bacnet/datalink/datalink.h" #include "rs485.h" -#include "version.h" +#include "bacnet/version.h" #include "nvdata.h" #include "stack.h" -#include "handlers.h" +#include "bacnet/basic/services.h" #include "bname.h" /* objects */ -#include "device.h" -#include "ai.h" -#include "av.h" -#include "bi.h" -#include "bo.h" +#include "bacnet/basic/object/device.h" +#include "bacnet/basic/object/ai.h" +#include "bacnet/basic/object/av.h" +#include "bacnet/basic/object/bi.h" +#include "bacnet/basic/object/bo.h" + +/* current version of the BACnet stack */ +static const char *BACnet_Version = BACNET_VERSION_TEXT; /* forward prototype */ int Device_Read_Property_Local( diff --git a/ports/bdk-atxx4-mstp/dlmstp.c b/ports/bdk-atxx4-mstp/dlmstp.c index bb4b9d4a..42930a3d 100644 --- a/ports/bdk-atxx4-mstp/dlmstp.c +++ b/ports/bdk-atxx4-mstp/dlmstp.c @@ -36,17 +36,17 @@ #include #include #include -#include "bacdef.h" -#include "dlmstp.h" -#include "mstpdef.h" +#include "bacnet/bacdef.h" +#include "bacnet/datalink/dlmstp.h" +#include "bacnet/datalink/mstpdef.h" +#include "bacnet/datalink/crc.h" #include "rs485.h" -#include "crc.h" -#include "npdu.h" -#include "bits.h" -#include "bytes.h" -#include "bacaddr.h" -#include "ringbuf.h" -#include "timer.h" +#include "bacnet/npdu.h" +#include "bacnet/bits.h" +#include "bacnet/bytes.h" +#include "bacnet/bacaddr.h" +#include "bacnet/basic/sys/ringbuf.h" +#include "bacnet/basic/sys/mstimer.h" /* This file has been customized for use with small microprocessors */ /* Assumptions: diff --git a/ports/bdk-atxx4-mstp/epics_vts3.tpi b/ports/bdk-atxx4-mstp/epics_vts3.tpi index ca000234..132371b5 100644 --- a/ports/bdk-atxx4-mstp/epics_vts3.tpi +++ b/ports/bdk-atxx4-mstp/epics_vts3.tpi @@ -1,354 +1,354 @@ -PICS 0 -BACnet Protocol Implementation Conformance Statement - --- --- --- BACnet Development Kit --- bacnetdevelopmentkit.com --- Author: Steve Karg --- --- - -Vendor Name: "BACnet Stack at SourceForge" -Product Name: "bdk-atxx4-mstp" -Product Model Number: "bdk-atxx4-mstp" -Product Description: "BACnet Development Kit" - -BIBBs Supported: -{ --- The BIBBs may be any of: --- DS-RP-A - DS-RP-B - DS-RPM-B --- DS-RPM-A --- DS-RPC-A DS-RPC-B --- DS-WP-A - DS-WP-B --- DS-WPM-A DS-WPM-B --- DS-COV-A DS-COV-B --- DS-COVP-A DS-COVP-B --- DS-COVU-A DS-COVU-B --- AE-N-A AE-N-I-B AE-N-E-B --- AE-ACK-A AE-ACK-B --- AE-ASUM-A AE-ASUM-B --- AE-ESUM-A AE-ESUM-B --- AE-INFO-A AE-INFO-B --- AE-LS-A AE-LS-B --- SCHED-A SCHED-I-B SCHED-E-B --- T-VMT-A T-VMT-I-B T-VMT-E-B --- T-ATR-A T-ATR-B --- DM-DDB-A - DM-DDB-B --- DM-DOB-A - DM-DOB-B --- DM-DCC-A - DM-DCC-B --- DM-PT-A DM-PT-B --- DM-TM-A DM-TM-B --- DM-TS-A --- DM-TS-B --- DM-UTC-A --- DM-UTC-B --- DM-RD-A - DM-RD-B --- DM-BR-A DM-BR-B --- DM-R-A DM-R-B --- DM-LM-A DM-LM-B --- DM-OCD-A DM-OCD-B --- DM-VT-A DM-VT-B --- NM-CE-A NM-CE-B --- NM-RC-A NM-RC-B -} - -BACnet Standard Application Services Supported: -{ --- AcknowledgeAlarm Initiate Execute --- ConfirmedCOVNotification Initiate Execute --- UnconfirmedCOVNotification Initiate Execute --- ConfirmedEventNotification Initiate Execute --- UnconfirmedEventNotification Initiate Execute --- GetAlarmSummary Initiate Execute --- GetEnrollmentSummary Initiate Execute --- AtomicReadFile Initiate Execute --- AtomicWriteFile Initiate Execute --- AddListElement Initiate Execute --- RemoveListElement Initiate Execute --- CreateObject Initiate Execute --- DeleteObject Initiate Execute - ReadProperty Execute --- ReadpropertyConditional Initiate Execute -ReadPropertyMultiple Execute --- SubscribeCOV Initiate Execute - WriteProperty Execute --- WritePropertyMultiple Initiate Execute - DeviceCommunicationControl Execute --- ConfirmedPrivateTransfer Initiate Execute --- UnconfirmedPrivateTransfer Initiate Execute --- TimeSynchronization Initiate Execute - Who-Has Execute - I-Have Initiate - Who-Is Execute - I-Am Initiate --- VT-Open Initiate Execute --- VT-Close Initiate Execute --- VT-Data Initiate Execute --- ConfirmedTextMessage Initiate Execute --- UnconfirmedTextMessage Initiate Execute - ReinitializeDevice Execute --- RequestKey Initiate Execute --- Authenticate Initiate Execute --- UTCTimeSynchronization Initiate Execute --- ReadRange Initiate Execute --- GetEventInformation Initiate Execute --- LifeSafetyOperation Initiate Execute --- SubscribeCOVProperty Initiate Execute --- RequestKey Initiate Execute --- Authenticate Initiate Execute -} - -Standard Object-Types Supported: -{ - Analog Input --- Analog Output Createable Deleteable - Analog Value --- Averaging Createable Deleteable - Binary Input - Binary Output --- Binary Value Createable Deleteable --- Calendar Createable Deleteable --- Command Createable Deleteable - Device --- Event Enrollment Createable Deleteable --- File Createable Deleteable --- Group Createable Deleteable --- Loop Createable Deleteable --- Multi-state Input Createable Deleteable --- Multi-state Output Createable Deleteable --- Multi-state Value Createable Deleteable --- Notification Class Createable Deleteable --- Program Createable Deleteable --- Schedule Createable Deleteable --- Life Safety Point Createable Deleteable --- Life Safety Zone Createable Deleteable --- Trend Log Createable Deleteable --- Load Control Createable Deleteable -} - -Data Link Layer Option: -{ --- ISO 8802-3, 10BASE5 --- ISO 8802-3, 10BASE2 --- ISO 8802-3, 10BASET --- ISO 8802-3, Fiber --- ARCNET, coax star --- ARCNET, coax bus --- ARCNET, twisted pair star --- ARCNET, twisted pair bus --- ARCNET, fiber star - MS/TP master. Baud rate(s): 9600, 19200, 38400, 57600, 76800, 115200 --- MS/TP slave. Baud rate(s): 9600 --- Point-To-Point. Modem, Baud rate(s): 14.4k --- Point-To-Point. Modem, Autobaud range: 9600 to 28.8k --- BACnet/IP, 'DIX' Ethernet --- BACnet/IP, PPP --- Other -} - -Character Sets Supported: -{ - ANSI X3.4 --- Other Character Sets not supported --- IBM/Microsoft DBCS --- JIS C 6226 --- ISO 10646 (ICS-4) --- ISO 10646 (UCS2) -} - -Special Functionality: -{ - Maximum APDU size in octets: 128 -- MS/TP Maximum 501 less NL Header --- Maximum APDU size in octets: 480 --- Segmented Requests Supported, window size: 1 --- Segmented Responses Supported, window size: 1 --- Router -} - -List of Objects in Test Device: -{ - { - object-identifier: (Device, 90) Writable - object-name: "DEVICE-90" Writable - object-type: Device - system-status: operational - vendor-name: "BACnet Stack at SourceForge" - vendor-identifier: 260 - model-name: "bdk-atxx4-mstp" - firmware-revision: "1.0" - application-software-version: "1.0" - protocol-version: 1 - protocol-revision: 10 - protocol-services-supported: ( - F,F,F,F, -- ,,,, - F,F,F,F, -- ,,,, - F,F,F,F, -- ,,,, - T,F,T,T, -- Read-Property,, Read-Property-Multiple, Write-Property, - F,T,F,F, -- , Device-Communication-Control,,, - T,F,F,F, -- Reinitialize-Device,,,, - F,F,F,F, -- ,,,, - F,F,F,F, -- ,,,, - F,T,T,F, -- , Who-Has, Who-Is,, - F,F,F,F -- ,,,, - ) - protocol-object-types-supported: ( - T,F,T,T, -- Analog Input,, Analog Value, Binary Input, - T,F,F,F, -- Binary Output,,,, - T,F,F,F, -- Device,,,, - F,F,F,F, -- ,,,, - F,F,F,F, -- ,,,, - F,F,F,F, -- ,,,, - F,F,F,F, -- ,,,, - F,F,F,F, -- ,,,, - F,F,F,F, -- ,,,, - F,F,F,F, -- ,,,, - F,F,F,F, -- ,,,, - F,F,F,F, -- ,,,, - F,F,F -- ,,, - ) - object-list: { - (Device, 90), (Analog Input, 0), (Analog Input, 1), (Analog Value, 0), - (Analog Value, 1), (Binary Input, 0), (Binary Input, 1), - (Binary Input, 2), - (Binary Input, 3), (Binary Input, 4), (Binary Output, 0), - (Binary Output, 1) } - max-apdu-length-accepted: 128 - segmentation-supported: no-segmentation - apdu-timeout: 3000 - number-of-APDU-retries: 3 - device-address-binding: ? - database-revision: ? - max-master: 127 Writable - max-info-frames: 1 Writable - description: "BACnet Development Kit" Writable - location: "default location" Writable - -- Found 12 Objects - }, - { - object-identifier: (Analog Input, 0) - object-name: "AI-0" - object-type: Analog Input - present-value: ? - status-flags: {false,false,false,false} - event-state: normal - out-of-service: FALSE - units: percent - }, - { - object-identifier: (Analog Input, 1) - object-name: "AI-1" - object-type: Analog Input - present-value: ? - status-flags: {false,false,false,false} - event-state: normal - out-of-service: FALSE - units: percent - }, - { - object-identifier: (Analog Value, 0) - object-name: "AV-0" - object-type: Analog Value - present-value: ? - status-flags: {false,false,false,false} - event-state: normal - out-of-service: FALSE - units: percent - }, - { - object-identifier: (Analog Value, 1) - object-name: "AV-1" - object-type: Analog Value - present-value: ? - status-flags: {false,false,false,false} - event-state: normal - out-of-service: FALSE - units: percent - }, - { - object-identifier: (Binary Input, 0) - object-name: "BI-0" - object-type: Binary Input - present-value: ? - status-flags: {false,false,false,false} - event-state: normal - out-of-service: FALSE - polarity: normal - }, - { - object-identifier: (Binary Input, 1) - object-name: "BI-1" - object-type: Binary Input - present-value: ? - status-flags: {false,false,false,false} - event-state: normal - out-of-service: FALSE - polarity: normal - }, - { - object-identifier: (Binary Input, 2) - object-name: "BI-2" - object-type: Binary Input - present-value: ? - status-flags: {false,false,false,false} - event-state: normal - out-of-service: FALSE - polarity: normal - }, - { - object-identifier: (Binary Input, 3) - object-name: "BI-3" - object-type: Binary Input - present-value: ? - status-flags: {false,false,false,false} - event-state: normal - out-of-service: FALSE - polarity: normal - }, - { - object-identifier: (Binary Input, 4) - object-name: "BI-4" - object-type: Binary Input - present-value: ? - status-flags: {false,false,false,false} - event-state: normal - out-of-service: FALSE - polarity: normal - }, - { - object-identifier: (Binary Output, 0) - object-name: "BO-0" - object-type: Binary Output - present-value: ? - status-flags: {false,false,false,false} - event-state: normal - out-of-service: FALSE - polarity: normal - priority-array: ? - relinquish-default: inactive - active-text: "on" - inactive-text: "off" - }, - { - object-identifier: (Binary Output, 1) - object-name: "BO-1" - object-type: Binary Output - present-value: ? - status-flags: {false,false,false,false} - event-state: normal - out-of-service: FALSE - polarity: normal - priority-array: ? - relinquish-default: inactive - active-text: "on" - inactive-text: "off" - } -} -End of BACnet Protocol Implementation Conformance Statement +PICS 0 +BACnet Protocol Implementation Conformance Statement + +-- +-- +-- BACnet Development Kit +-- bacnetdevelopmentkit.com +-- Author: Steve Karg +-- +-- + +Vendor Name: "BACnet Stack at SourceForge" +Product Name: "bdk-atxx4-mstp" +Product Model Number: "bdk-atxx4-mstp" +Product Description: "BACnet Development Kit" + +BIBBs Supported: +{ +-- The BIBBs may be any of: +-- DS-RP-A + DS-RP-B + DS-RPM-B +-- DS-RPM-A +-- DS-RPC-A DS-RPC-B +-- DS-WP-A + DS-WP-B +-- DS-WPM-A DS-WPM-B +-- DS-COV-A DS-COV-B +-- DS-COVP-A DS-COVP-B +-- DS-COVU-A DS-COVU-B +-- AE-N-A AE-N-I-B AE-N-E-B +-- AE-ACK-A AE-ACK-B +-- AE-ASUM-A AE-ASUM-B +-- AE-ESUM-A AE-ESUM-B +-- AE-INFO-A AE-INFO-B +-- AE-LS-A AE-LS-B +-- SCHED-A SCHED-I-B SCHED-E-B +-- T-VMT-A T-VMT-I-B T-VMT-E-B +-- T-ATR-A T-ATR-B +-- DM-DDB-A + DM-DDB-B +-- DM-DOB-A + DM-DOB-B +-- DM-DCC-A + DM-DCC-B +-- DM-PT-A DM-PT-B +-- DM-TM-A DM-TM-B +-- DM-TS-A +-- DM-TS-B +-- DM-UTC-A +-- DM-UTC-B +-- DM-RD-A + DM-RD-B +-- DM-BR-A DM-BR-B +-- DM-R-A DM-R-B +-- DM-LM-A DM-LM-B +-- DM-OCD-A DM-OCD-B +-- DM-VT-A DM-VT-B +-- NM-CE-A NM-CE-B +-- NM-RC-A NM-RC-B +} + +BACnet Standard Application Services Supported: +{ +-- AcknowledgeAlarm Initiate Execute +-- ConfirmedCOVNotification Initiate Execute +-- UnconfirmedCOVNotification Initiate Execute +-- ConfirmedEventNotification Initiate Execute +-- UnconfirmedEventNotification Initiate Execute +-- GetAlarmSummary Initiate Execute +-- GetEnrollmentSummary Initiate Execute +-- AtomicReadFile Initiate Execute +-- AtomicWriteFile Initiate Execute +-- AddListElement Initiate Execute +-- RemoveListElement Initiate Execute +-- CreateObject Initiate Execute +-- DeleteObject Initiate Execute + ReadProperty Execute +-- ReadpropertyConditional Initiate Execute +ReadPropertyMultiple Execute +-- SubscribeCOV Initiate Execute + WriteProperty Execute +-- WritePropertyMultiple Initiate Execute + DeviceCommunicationControl Execute +-- ConfirmedPrivateTransfer Initiate Execute +-- UnconfirmedPrivateTransfer Initiate Execute +-- TimeSynchronization Initiate Execute + Who-Has Execute + I-Have Initiate + Who-Is Execute + I-Am Initiate +-- VT-Open Initiate Execute +-- VT-Close Initiate Execute +-- VT-Data Initiate Execute +-- ConfirmedTextMessage Initiate Execute +-- UnconfirmedTextMessage Initiate Execute + ReinitializeDevice Execute +-- RequestKey Initiate Execute +-- Authenticate Initiate Execute +-- UTCTimeSynchronization Initiate Execute +-- ReadRange Initiate Execute +-- GetEventInformation Initiate Execute +-- LifeSafetyOperation Initiate Execute +-- SubscribeCOVProperty Initiate Execute +-- RequestKey Initiate Execute +-- Authenticate Initiate Execute +} + +Standard Object-Types Supported: +{ + Analog Input +-- Analog Output Createable Deleteable + Analog Value +-- Averaging Createable Deleteable + Binary Input + Binary Output +-- Binary Value Createable Deleteable +-- Calendar Createable Deleteable +-- Command Createable Deleteable + Device +-- Event Enrollment Createable Deleteable +-- File Createable Deleteable +-- Group Createable Deleteable +-- Loop Createable Deleteable +-- Multi-state Input Createable Deleteable +-- Multi-state Output Createable Deleteable +-- Multi-state Value Createable Deleteable +-- Notification Class Createable Deleteable +-- Program Createable Deleteable +-- Schedule Createable Deleteable +-- Life Safety Point Createable Deleteable +-- Life Safety Zone Createable Deleteable +-- Trend Log Createable Deleteable +-- Load Control Createable Deleteable +} + +Data Link Layer Option: +{ +-- ISO 8802-3, 10BASE5 +-- ISO 8802-3, 10BASE2 +-- ISO 8802-3, 10BASET +-- ISO 8802-3, Fiber +-- ARCNET, coax star +-- ARCNET, coax bus +-- ARCNET, twisted pair star +-- ARCNET, twisted pair bus +-- ARCNET, fiber star + MS/TP master. Baud rate(s): 9600, 19200, 38400, 57600, 76800, 115200 +-- MS/TP slave. Baud rate(s): 9600 +-- Point-To-Point. Modem, Baud rate(s): 14.4k +-- Point-To-Point. Modem, Autobaud range: 9600 to 28.8k +-- BACnet/IP, 'DIX' Ethernet +-- BACnet/IP, PPP +-- Other +} + +Character Sets Supported: +{ + ANSI X3.4 +-- Other Character Sets not supported +-- IBM/Microsoft DBCS +-- JIS C 6226 +-- ISO 10646 (ICS-4) +-- ISO 10646 (UCS2) +} + +Special Functionality: +{ + Maximum APDU size in octets: 128 -- MS/TP Maximum 501 less NL Header +-- Maximum APDU size in octets: 480 +-- Segmented Requests Supported, window size: 1 +-- Segmented Responses Supported, window size: 1 +-- Router +} + +List of Objects in Test Device: +{ + { + object-identifier: (Device, 90) Writable + object-name: "DEVICE-90" Writable + object-type: Device + system-status: operational + vendor-name: "BACnet Stack at SourceForge" + vendor-identifier: 260 + model-name: "bdk-atxx4-mstp" + firmware-revision: "1.0" + application-software-version: "1.0" + protocol-version: 1 + protocol-revision: 10 + protocol-services-supported: ( + F,F,F,F, -- ,,,, + F,F,F,F, -- ,,,, + F,F,F,F, -- ,,,, + T,F,T,T, -- Read-Property,, Read-Property-Multiple, Write-Property, + F,T,F,F, -- , Device-Communication-Control,,, + T,F,F,F, -- Reinitialize-Device,,,, + F,F,F,F, -- ,,,, + F,F,F,F, -- ,,,, + F,T,T,F, -- , Who-Has, Who-Is,, + F,F,F,F -- ,,,, + ) + protocol-object-types-supported: ( + T,F,T,T, -- Analog Input,, Analog Value, Binary Input, + T,F,F,F, -- Binary Output,,,, + T,F,F,F, -- Device,,,, + F,F,F,F, -- ,,,, + F,F,F,F, -- ,,,, + F,F,F,F, -- ,,,, + F,F,F,F, -- ,,,, + F,F,F,F, -- ,,,, + F,F,F,F, -- ,,,, + F,F,F,F, -- ,,,, + F,F,F,F, -- ,,,, + F,F,F,F, -- ,,,, + F,F,F -- ,,, + ) + object-list: { + (Device, 90), (Analog Input, 0), (Analog Input, 1), (Analog Value, 0), + (Analog Value, 1), (Binary Input, 0), (Binary Input, 1), + (Binary Input, 2), + (Binary Input, 3), (Binary Input, 4), (Binary Output, 0), + (Binary Output, 1) } + max-apdu-length-accepted: 128 + segmentation-supported: no-segmentation + apdu-timeout: 3000 + number-of-APDU-retries: 3 + device-address-binding: ? + database-revision: ? + max-master: 127 Writable + max-info-frames: 1 Writable + description: "BACnet Development Kit" Writable + location: "default location" Writable + -- Found 12 Objects + }, + { + object-identifier: (Analog Input, 0) + object-name: "AI-0" + object-type: Analog Input + present-value: ? + status-flags: {false,false,false,false} + event-state: normal + out-of-service: FALSE + units: percent + }, + { + object-identifier: (Analog Input, 1) + object-name: "AI-1" + object-type: Analog Input + present-value: ? + status-flags: {false,false,false,false} + event-state: normal + out-of-service: FALSE + units: percent + }, + { + object-identifier: (Analog Value, 0) + object-name: "AV-0" + object-type: Analog Value + present-value: ? + status-flags: {false,false,false,false} + event-state: normal + out-of-service: FALSE + units: percent + }, + { + object-identifier: (Analog Value, 1) + object-name: "AV-1" + object-type: Analog Value + present-value: ? + status-flags: {false,false,false,false} + event-state: normal + out-of-service: FALSE + units: percent + }, + { + object-identifier: (Binary Input, 0) + object-name: "BI-0" + object-type: Binary Input + present-value: ? + status-flags: {false,false,false,false} + event-state: normal + out-of-service: FALSE + polarity: normal + }, + { + object-identifier: (Binary Input, 1) + object-name: "BI-1" + object-type: Binary Input + present-value: ? + status-flags: {false,false,false,false} + event-state: normal + out-of-service: FALSE + polarity: normal + }, + { + object-identifier: (Binary Input, 2) + object-name: "BI-2" + object-type: Binary Input + present-value: ? + status-flags: {false,false,false,false} + event-state: normal + out-of-service: FALSE + polarity: normal + }, + { + object-identifier: (Binary Input, 3) + object-name: "BI-3" + object-type: Binary Input + present-value: ? + status-flags: {false,false,false,false} + event-state: normal + out-of-service: FALSE + polarity: normal + }, + { + object-identifier: (Binary Input, 4) + object-name: "BI-4" + object-type: Binary Input + present-value: ? + status-flags: {false,false,false,false} + event-state: normal + out-of-service: FALSE + polarity: normal + }, + { + object-identifier: (Binary Output, 0) + object-name: "BO-0" + object-type: Binary Output + present-value: ? + status-flags: {false,false,false,false} + event-state: normal + out-of-service: FALSE + polarity: normal + priority-array: ? + relinquish-default: inactive + active-text: "on" + inactive-text: "off" + }, + { + object-identifier: (Binary Output, 1) + object-name: "BO-1" + object-type: Binary Output + present-value: ? + status-flags: {false,false,false,false} + event-state: normal + out-of-service: FALSE + polarity: normal + priority-array: ? + relinquish-default: inactive + active-text: "on" + inactive-text: "off" + } +} +End of BACnet Protocol Implementation Conformance Statement diff --git a/ports/bdk-atxx4-mstp/hardware.h b/ports/bdk-atxx4-mstp/hardware.h index be86f8d7..ba1cebaa 100644 --- a/ports/bdk-atxx4-mstp/hardware.h +++ b/ports/bdk-atxx4-mstp/hardware.h @@ -62,7 +62,7 @@ #endif #include "iar2gcc.h" -#include "bits.h" +#include "bacnet/bits.h" /* SEEPROM is 24LC128 */ /*#define SEEPROM_PAGE_SIZE 64 */ diff --git a/ports/bdk-atxx4-mstp/input.c b/ports/bdk-atxx4-mstp/input.c index 5389cabf..bec8a6eb 100644 --- a/ports/bdk-atxx4-mstp/input.c +++ b/ports/bdk-atxx4-mstp/input.c @@ -25,7 +25,7 @@ #include #include #include "hardware.h" -#include "timer.h" +#include "bacnet/basic/sys/mstimer.h" /* me */ #include "input.h" @@ -35,7 +35,7 @@ static uint8_t Address_Switch; static uint8_t Buttons; -static struct itimer Debounce_Timer; +static struct mstimer Debounce_Timer; #ifndef BDK_V1_HACK #define BDK_V1_HACK 0 @@ -84,8 +84,8 @@ void input_task( static uint8_t old_buttons = 0; /* only check the inputs every debounce time */ - if (timer_interval_expired(&Debounce_Timer)) { - timer_interval_reset(&Debounce_Timer); + if (mstimer_expired(&Debounce_Timer)) { + mstimer_reset(&Debounce_Timer); /* pins used are PA6, PA5, PA4, PA3, PA2, PA1, PA0 */ #if BDK_V1_HACK /* version 1 BDK - workaround */ @@ -199,5 +199,5 @@ void input_init( BIT_SET(PORTB, PORTB3); BIT_SET(PORTB, PORTB4); #endif - timer_interval_start(&Debounce_Timer, 30); + mstimer_set(&Debounce_Timer, 30); } diff --git a/ports/bdk-atxx4-mstp/led.c b/ports/bdk-atxx4-mstp/led.c index 29e6b55e..3e7c71ca 100644 --- a/ports/bdk-atxx4-mstp/led.c +++ b/ports/bdk-atxx4-mstp/led.c @@ -23,14 +23,14 @@ *********************************************************************/ #include #include "hardware.h" -#include "timer.h" +#include "bacnet/basic/sys/mstimer.h" #include "led.h" #ifndef BDK_VERSION #define BDK_VERSION 4 #endif -static struct itimer Off_Delay_Timer[MAX_LEDS]; +static struct mstimer Off_Delay_Timer[MAX_LEDS]; /************************************************************************* * Description: Turn on an LED @@ -65,7 +65,7 @@ void led_on( break; } if (index < MAX_LEDS) { - timer_interval_no_expire(&Off_Delay_Timer[index]); + mstimer_set(&Off_Delay_Timer[index], 0); } } @@ -102,7 +102,7 @@ void led_off( break; } if (index < MAX_LEDS) { - timer_interval_no_expire(&Off_Delay_Timer[index]); + mstimer_set(&Off_Delay_Timer[index], 0); } } @@ -163,7 +163,7 @@ void led_off_delay( uint32_t delay_ms) { if (index < MAX_LEDS) { - timer_interval_start(&Off_Delay_Timer[index], delay_ms); + mstimer_set(&Off_Delay_Timer[index], delay_ms); } } @@ -178,7 +178,7 @@ void led_on_interval( { if (index < MAX_LEDS) { led_on(index); - timer_interval_start(&Off_Delay_Timer[index], interval_ms); + mstimer_set(&Off_Delay_Timer[index], interval_ms); } } @@ -193,8 +193,8 @@ void led_task( uint8_t i; /* loop counter */ for (i = 0; i < MAX_LEDS; i++) { - if (timer_interval_expired(&Off_Delay_Timer[i])) { - timer_interval_no_expire(&Off_Delay_Timer[i]); + if (mstimer_expired(&Off_Delay_Timer[i])) { + mstimer_set(&Off_Delay_Timer[i], 0); led_off(i); } } diff --git a/ports/bdk-atxx4-mstp/main.c b/ports/bdk-atxx4-mstp/main.c index c45fb2fe..52c305b3 100644 --- a/ports/bdk-atxx4-mstp/main.c +++ b/ports/bdk-atxx4-mstp/main.c @@ -28,18 +28,18 @@ #include "hardware.h" #include "init.h" #include "stack.h" -#include "timer.h" +#include "bacnet/basic/sys/mstimer.h" #include "input.h" #include "led.h" #include "adc.h" #include "nvdata.h" -#include "timer.h" +#include "bacnet/basic/sys/mstimer.h" #include "rs485.h" #include "serial.h" #include "bacnet.h" #include "test.h" #include "watchdog.h" -#include "version.h" +#include "bacnet/version.h" /* global - currently the version of the stack */ char *BACnet_Version = BACNET_VERSION_TEXT; @@ -57,7 +57,7 @@ int main( #else watchdog_init(0); #endif - timer_init(); + mstimer_init(); adc_init(); input_init(); seeprom_init(); diff --git a/ports/bdk-atxx4-mstp/timer2.c b/ports/bdk-atxx4-mstp/mstimer-init.c similarity index 90% rename from ports/bdk-atxx4-mstp/timer2.c rename to ports/bdk-atxx4-mstp/mstimer-init.c index c25375fe..87ff92f0 100644 --- a/ports/bdk-atxx4-mstp/timer2.c +++ b/ports/bdk-atxx4-mstp/mstimer-init.c @@ -24,7 +24,7 @@ #include #include #include "hardware.h" -#include "timer.h" +#include "bacnet/basic/sys/mstimer.h" #ifndef F_CPU #error "F_CPU must be defined for Timer configuration." @@ -59,7 +59,6 @@ /* counter for the the timer which wraps every 49.7 days */ static volatile uint32_t Millisecond_Counter; -static volatile uint8_t Millisecond_Counter_Byte; /************************************************************************* * Description: Timer Interrupt Handler @@ -72,7 +71,6 @@ static inline void timer_interrupt_handler( /* Set the counter for the next interrupt */ TCNT2 = TIMER2_COUNT; Millisecond_Counter++; - Millisecond_Counter_Byte++; } /************************************************************************* @@ -90,10 +88,10 @@ ISR(TIMER2_OVF_vect) * Returns: none * Notes: This method only disables the timer overflow interrupt. *************************************************************************/ -uint32_t timer_milliseconds( +unsigned long mstimer_now( void) { - uint32_t timer_value; /* return value */ + unsigned long timer_value; /* return value */ /* Disable the overflow interrupt. Prevents value corruption that would happen if interrupted */ @@ -105,23 +103,12 @@ uint32_t timer_milliseconds( return timer_value; } -/************************************************************************* -* Description: returns the current millisecond count -* Returns: none -* Notes: This method only disables the timer overflow interrupt. -*************************************************************************/ -uint8_t timer_milliseconds_byte( - void) -{ - return Millisecond_Counter; -} - /************************************************************************* * Description: Initialization for Timer * Returns: none * Notes: none *************************************************************************/ -void timer_init( +void mstimer_init( void) { /* Normal Operation */ diff --git a/ports/bdk-atxx4-mstp/rs485.c b/ports/bdk-atxx4-mstp/rs485.c index b1a6239f..b0b372b7 100644 --- a/ports/bdk-atxx4-mstp/rs485.c +++ b/ports/bdk-atxx4-mstp/rs485.c @@ -25,8 +25,8 @@ #include #include #include "hardware.h" -#include "fifo.h" -#include "timer.h" +#include "bacnet/basic/sys/fifo.h" +#include "bacnet/basic/sys/mstimer.h" #include "led.h" #include "nvdata.h" /* me */ @@ -51,7 +51,7 @@ static uint32_t Baud_Rate = 9600; static uint8_t Receive_Buffer_Data[128]; static FIFO_BUFFER Receive_Buffer; -static struct etimer Silence_Timer; +static struct mstimer Silence_Timer; /**************************************************************************** * DESCRIPTION: Determines the amount of silence time elapsed @@ -61,7 +61,7 @@ static struct etimer Silence_Timer; bool rs485_silence_time_elapsed( uint16_t milliseconds) { - return timer_elapsed_milliseconds_short(&Silence_Timer, milliseconds); + return (mstimer_remaining(&Silence_Timer) > milliseconds); } /**************************************************************************** @@ -72,7 +72,7 @@ bool rs485_silence_time_elapsed( void rs485_silence_time_reset( void) { - timer_elapsed_start(&Silence_Timer); + mstimer_set(&Silence_Timer, 0); } /**************************************************************************** @@ -226,7 +226,7 @@ void rs485_bytes_send( } /* Clear the Transmit Complete flag by writing a one to it. */ BIT_SET(UCSR0A, TXC0); - timer_elapsed_start(&Silence_Timer); + rs485_silence_time_reset(); led_off_delay(LED_5, 1); return; @@ -363,7 +363,7 @@ void rs485_init( { FIFO_Init(&Receive_Buffer, &Receive_Buffer_Data[0], (unsigned) sizeof(Receive_Buffer_Data)); - timer_elapsed_start(&Silence_Timer); + rs485_silence_time_reset(); rs485_rts_init(); rs485_usart_init(); rs485_init_nvdata(); diff --git a/ports/bdk-atxx4-mstp/serial.c b/ports/bdk-atxx4-mstp/serial.c index f18bdd57..4836c986 100644 --- a/ports/bdk-atxx4-mstp/serial.c +++ b/ports/bdk-atxx4-mstp/serial.c @@ -25,7 +25,7 @@ #include #include #include "hardware.h" -#include "fifo.h" +#include "bacnet/basic/sys/fifo.h" #include "serial.h" /* baud rate */ diff --git a/ports/bdk-atxx4-mstp/test.c b/ports/bdk-atxx4-mstp/test.c index 8fa7fcb0..b7b2cc00 100644 --- a/ports/bdk-atxx4-mstp/test.c +++ b/ports/bdk-atxx4-mstp/test.c @@ -26,12 +26,12 @@ #include #include #include "hardware.h" -#include "timer.h" +#include "bacnet/basic/sys/mstimer.h" #include "serial.h" #include "input.h" -#include "bo.h" +#include "bacnet/basic/object/bo.h" #include "rs485.h" -#include "dlmstp.h" +#include "bacnet/datalink/dlmstp.h" #include "seeprom.h" #include "nvdata.h" /* me */ @@ -47,7 +47,7 @@ const char * const binary_string[BINARY_STRING_MAX] = { }; /* timer for test task */ -static struct itimer Test_Timer; +static struct mstimer Test_Timer; /* MAC Address of MS/TP */ static uint8_t MSTP_MAC_Address; @@ -59,7 +59,7 @@ void test_init( #else serial_baud_rate_set(9600); #endif - timer_interval_start_seconds(&Test_Timer, 1); + mstimer_set(&Test_Timer, 1*1000); /* configure a port pin as output */ #if (BDK_VERSION==4) BIT_SET(DDRD, DDB5); @@ -147,8 +147,8 @@ static inline void test_pin_toggle( void test_task( void) { - if (timer_interval_expired(&Test_Timer)) { - timer_interval_reset(&Test_Timer); + if (mstimer_expired(&Test_Timer)) { + mstimer_reset(&Test_Timer); MSTP_MAC_Address = MSTP_MAC_Address; } } @@ -161,8 +161,8 @@ void test_task( uint8_t data_register = 0; uint16_t id = 0; - if (timer_interval_expired(&Test_Timer)) { - timer_interval_reset(&Test_Timer); + if (mstimer_expired(&Test_Timer)) { + mstimer_reset(&Test_Timer); sprintf(Send_Buffer, "BACnet: 0000000\r\n"); MSTP_MAC_Address = input_address(); Send_Buffer[8] = (MSTP_MAC_Address & BIT0) ? '1' : '0'; diff --git a/ports/bdk-atxx4-mstp/timer.c b/ports/bdk-atxx4-mstp/timer.c deleted file mode 100644 index 679529e0..00000000 --- a/ports/bdk-atxx4-mstp/timer.c +++ /dev/null @@ -1,431 +0,0 @@ -/************************************************************************** -* -* Copyright (C) 2009 Steve Karg -* -* Permission is hereby granted, free of charge, to any person obtaining -* a copy of this software and associated documentation files (the -* "Software"), to deal in the Software without restriction, including -* without limitation the rights to use, copy, modify, merge, publish, -* distribute, sublicense, and/or sell copies of the Software, and to -* permit persons to whom the Software is furnished to do so, subject to -* the following conditions: -* -* The above copyright notice and this permission notice shall be included -* in all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*********************************************************************/ -#include -#include -#include "timer.h" - -/* generic elapsed timer handling */ -/* interval not to exceed 49.7 days */ -/* interval of 1ms may be 0 to 1ms */ - -/************************************************************************* -* Description: Sets the start time for an elapsed timer -* Returns: the value of the start timer -* Notes: none -*************************************************************************/ -void timer_elapsed_start( - struct etimer *t) -{ - uint32_t now = timer_milliseconds(); - - if (t) { - t->start = now; - } -} - -/************************************************************************* -* Description: Gets the amount of elapsed time in milliseconds -* Returns: elapsed time in milliseconds -* Notes: none -*************************************************************************/ -uint32_t timer_elapsed_time( - struct etimer *t) -{ - uint32_t now = timer_milliseconds(); - uint32_t delta = 0; - - if (t) { - delta = now - t->start; - } - - return delta; -} - -/************************************************************************* -* Description: Sets the start time with an offset -* Returns: elapsed time in milliseconds -* Notes: none -*************************************************************************/ -void timer_elapsed_start_offset( - struct etimer *t, - uint32_t offset) -{ - uint32_t now = timer_milliseconds(); - - if (t) { - t->start = now + offset; - } -} - -/************************************************************************* -* Description: Tests to see if time has elapsed -* Returns: true if time has elapsed -* Notes: none -*************************************************************************/ -bool timer_elapsed_milliseconds( - struct etimer *t, - uint32_t milliseconds) -{ - return (timer_elapsed_time(t) >= milliseconds); -} - -/************************************************************************* -* Description: Tests to see if time has elapsed -* Returns: true if time has elapsed -* Notes: none -*************************************************************************/ -bool timer_elapsed_seconds( - struct etimer * t, - uint32_t seconds) -{ - uint32_t milliseconds = seconds; - - milliseconds *= 1000L; - - return timer_elapsed_milliseconds(t, milliseconds); -} - -/************************************************************************* -* Description: Tests to see if time has elapsed -* Returns: true if time has elapsed -* Notes: none -*************************************************************************/ -bool timer_elapsed_minutes( - struct etimer * t, - uint32_t minutes) -{ - uint32_t milliseconds = minutes; - - milliseconds *= 1000L; - milliseconds *= 60L; - - return timer_elapsed_milliseconds(t, milliseconds); -} - -/************************************************************************* -* Description: Tests to see if time has elapsed -* Returns: true if time has elapsed -* Notes: none -*************************************************************************/ -bool timer_elapsed_milliseconds_short( - struct etimer * t, - uint16_t value) -{ - uint32_t milliseconds; - - milliseconds = value; - - return (timer_elapsed_time(t) >= milliseconds); -} - -/************************************************************************* -* Description: Tests to see if time has elapsed -* Returns: true if time has elapsed -* Notes: none -*************************************************************************/ -bool timer_elapsed_seconds_short( - struct etimer * t, - uint16_t value) -{ - return timer_elapsed_seconds(t, value); -} - -/************************************************************************* -* Description: Tests to see if time has elapsed -* Returns: true if time has elapsed -* Notes: none -*************************************************************************/ -bool timer_elapsed_minutes_short( - struct etimer * t, - uint16_t value) -{ - return timer_elapsed_minutes(t, value); -} - -/************************************************************************* -* Description: Starts an interval timer -* Returns: nothing -* Notes: none -*************************************************************************/ -void timer_interval_start( - struct itimer *t, - uint32_t interval) -{ - if (t) { - t->start = timer_milliseconds(); - t->interval = interval; - } -} - -/************************************************************************* -* Description: Starts an interval timer -* Returns: nothing -* Notes: none -*************************************************************************/ -void timer_interval_start_seconds( - struct itimer *t, - uint32_t seconds) -{ - uint32_t interval = seconds; - - interval *= 1000L; - timer_interval_start(t, interval); -} - -/************************************************************************* -* Description: Starts an interval timer -* Returns: nothing -* Notes: none -*************************************************************************/ -void timer_interval_start_minutes( - struct itimer *t, - uint32_t minutes) -{ - uint32_t interval = minutes; - - interval *= 1000L; - interval *= 60L; - timer_interval_start(t, interval); -} - -/************************************************************************* -* Description: Determines the amount of time that has elapsed -* Returns: elapsed milliseconds -* Notes: none -*************************************************************************/ -uint32_t timer_interval_elapsed( - struct itimer *t) -{ - uint32_t now = timer_milliseconds(); - uint32_t delta = 0; - - if (t) { - delta = now - t->start; - } - - return delta; -} - -/************************************************************************* -* Description: Determines the amount of time that has elapsed -* Returns: elapsed milliseconds -* Notes: none -*************************************************************************/ -uint32_t timer_interval( - struct itimer * t) -{ - uint32_t interval = 0; - - if (t) { - interval = t->interval; - } - - return interval; -} - -/************************************************************************* -* Description: Tests to see if time has elapsed -* Returns: true if time has elapsed -* Notes: none -*************************************************************************/ -bool timer_interval_expired( - struct itimer * t) -{ - bool expired = false; - - if (t) { - if (t->interval) { - expired = timer_interval_elapsed(t) >= t->interval; - } - } - - return expired; -} - -/************************************************************************* -* Description: Sets the interval value to zero so it never expires -* Returns: nothing -* Notes: none -*************************************************************************/ -void timer_interval_no_expire( - struct itimer *t) -{ - if (t) { - t->interval = 0; - } -} - -/************************************************************************* -* Description: Adds another interval to the start time. Used for cyclic -* timers that won't lose ticks. -* Returns: nothing -* Notes: none -*************************************************************************/ -void timer_interval_reset( - struct itimer *t) -{ - if (t) { - t->start += t->interval; - } -} - -/************************************************************************* -* Description: Restarts the timer with the same interval -* Returns: nothing -* Notes: none -*************************************************************************/ -void timer_interval_restart( - struct itimer *t) -{ - if (t) { - t->start = timer_milliseconds(); - } -} - -/************************************************************************* -* Description: Return the elapsed time -* Returns: number of milliseconds elapsed -* Notes: only up to 255ms elapsed -**************************************************************************/ -uint8_t timer_milliseconds_delta( - uint8_t start) -{ - return (timer_milliseconds_byte() - start); -} - -/************************************************************************* -* Description: Mark the start of a delta timer -* Returns: mark timer starting tick -* Notes: only up to 255ms elapsed -**************************************************************************/ -uint8_t timer_milliseconds_mark( - void) -{ - return timer_milliseconds_byte(); -} - -#ifdef TEST -#include -#include - -#include "ctest.h" - -static uint32_t Milliseconds; - -uint32_t timer_milliseconds( - void) -{ - return Milliseconds; -} - -uint32_t timer_milliseconds_set( - uint32_t value) -{ - uint32_t old_value = Milliseconds; - - Milliseconds = value; - - return old_value; -} - -void testElapsedTimer( - Test * pTest) -{ - struct etimer t; - uint32_t test_time = 0; - - timer_milliseconds_set(test_time); - timer_elapsed_start(&t); - ct_test(pTest, timer_elapsed_time(&t) == test_time); - test_time = 0xffff; - timer_milliseconds_set(test_time); - ct_test(pTest, timer_elapsed_time(&t) == test_time); - test_time = 0xffffffff; - timer_milliseconds_set(test_time); - ct_test(pTest, timer_elapsed_time(&t) == test_time); -} - -void testIntervalTimer( - Test * pTest) -{ - struct itimer t; - uint32_t interval = 0; - uint32_t test_time = 0; - - timer_milliseconds_set(test_time); - timer_interval_start(&t, interval); - test_time = 0xffff; - timer_milliseconds_set(test_time); - ct_test(pTest, timer_interval(&t) == interval); - ct_test(pTest, timer_interval_elapsed(&t) == test_time); - test_time = 0xffffffff; - timer_milliseconds_set(test_time); - ct_test(pTest, timer_interval(&t) == interval); - ct_test(pTest, timer_interval_elapsed(&t) == test_time); - test_time = 0; - timer_milliseconds_set(test_time); - interval = 0xffff; - timer_interval_start(&t, interval); - ct_test(pTest, timer_interval(&t) == interval); - interval = 0xffffffff; - timer_interval_start(&t, interval); - ct_test(pTest, timer_interval(&t) == interval); - - interval = 0; - timer_interval_start_seconds(&t, interval); - ct_test(pTest, timer_interval(&t) == interval); - interval = 60L; - timer_interval_start_seconds(&t, interval); - interval *= 1000L; - ct_test(pTest, timer_interval(&t) == interval); - -} - - -#ifdef TEST_TIMER -int main( - void) -{ - Test *pTest; - bool rc; - - pTest = ct_create("Timer", NULL); - - /* individual tests */ - rc = ct_addTestFunction(pTest, testElapsedTimer); - assert(rc); - rc = ct_addTestFunction(pTest, testIntervalTimer); - assert(rc); - - - ct_setStream(pTest, stdout); - ct_run(pTest); - (void) ct_report(pTest); - - ct_destroy(pTest); - - return 0; -} -#endif -#endif diff --git a/ports/bdk-atxx4-mstp/timer.h b/ports/bdk-atxx4-mstp/timer.h deleted file mode 100644 index dac54d47..00000000 --- a/ports/bdk-atxx4-mstp/timer.h +++ /dev/null @@ -1,115 +0,0 @@ -/************************************************************************** -* -* Copyright (C) 2009 Steve Karg -* -* Permission is hereby granted, free of charge, to any person obtaining -* a copy of this software and associated documentation files (the -* "Software"), to deal in the Software without restriction, including -* without limitation the rights to use, copy, modify, merge, publish, -* distribute, sublicense, and/or sell copies of the Software, and to -* permit persons to whom the Software is furnished to do so, subject to -* the following conditions: -* -* The above copyright notice and this permission notice shall be included -* in all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*********************************************************************/ -#ifndef TIMER_H -#define TIMER_H - -#include -#include - -/* Timer Module */ - -/* elapsed timer structure */ -struct etimer { - uint32_t start; -}; -/* interval timer structure */ -struct itimer { - uint32_t start; - uint32_t interval; -}; - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - - /* these 3 functions are created in the hardware specific module */ - void timer_init( - void); - uint32_t timer_milliseconds( - void); - uint8_t timer_milliseconds_byte( - void); - - /* these functions are in the generic timer.c module */ - - /* elapsed timer */ - void timer_elapsed_start( - struct etimer *t); - void timer_elapsed_start_offset( - struct etimer *t, - uint32_t offset); - uint32_t timer_elapsed_time( - struct etimer *t); - bool timer_elapsed_milliseconds( - struct etimer *t, - uint32_t value); - bool timer_elapsed_seconds( - struct etimer *t, - uint32_t value); - bool timer_elapsed_minutes( - struct etimer *t, - uint32_t value); - bool timer_elapsed_milliseconds_short( - struct etimer *t, - uint16_t value); - bool timer_elapsed_seconds_short( - struct etimer *t, - uint16_t value); - bool timer_elapsed_minutes_short( - struct etimer *t, - uint16_t value); - - /* interval timer */ - void timer_interval_start( - struct itimer *t, - uint32_t interval); - void timer_interval_start_seconds( - struct itimer *t, - uint32_t interval); - void timer_interval_start_minutes( - struct itimer *t, - uint32_t interval); - bool timer_interval_expired( - struct itimer *t); - uint32_t timer_interval( - struct itimer *t); - uint32_t timer_interval_elapsed( - struct itimer *t); - void timer_interval_no_expire( - struct itimer *t); - void timer_interval_reset( - struct itimer *t); - void timer_interval_restart( - struct itimer *t); - - /* special for 8-bit microcontrollers - limited to 255ms */ - uint8_t timer_milliseconds_delta( - uint8_t start); - uint8_t timer_milliseconds_mark( - void); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ -#endif diff --git a/ports/bsd/net.h b/ports/bsd/bacport.h similarity index 100% rename from ports/bsd/net.h rename to ports/bsd/bacport.h diff --git a/ports/bsd/bip-init.c b/ports/bsd/bip-init.c index 5241d9ee..ff8bc8b4 100644 --- a/ports/bsd/bip-init.c +++ b/ports/bsd/bip-init.c @@ -34,9 +34,9 @@ #include /* for standard integer types uint8_t etc. */ #include /* for the standard bool type. */ -#include "bacdcode.h" -#include "bip.h" -#include "net.h" +#include "bacnet/bacdcode.h" +#include "bacnet/datalink/bip.h" +#include "bacport.h" #include /** @file linux/bip-init.c Initializes BACnet/IP interface (BSD/MAC OS X). */ diff --git a/ports/bsd/datetime-init.c b/ports/bsd/datetime-init.c new file mode 100644 index 00000000..65d7c4bd --- /dev/null +++ b/ports/bsd/datetime-init.c @@ -0,0 +1,91 @@ +/** + * @file + * @author Steve Karg + * @date 2009 + * @brief System time library header file. + * + * @section DESCRIPTION + * + * This library provides functions for getting and setting the system time. + */ +#include +#include +#include +#include +#include +#include +#include +#include "bacport.h" +#include "bacnet/datetime.h" + +/** + * @brief Get the date, time, timezone, and UTC offset from system + * @param utc_time - the BACnet Date and Time structure to hold UTC time + * @param local_time - the BACnet Date and Time structure to hold local time + * @param utc_offset_minutes - number of minutes offset from UTC + * For example, -6*60 represents 6.00 hours behind UTC/GMT + * @param true if DST is enabled and active + * @return true if local time was retrieved + */ +bool datetime_local( + BACNET_DATE * bdate, + BACNET_TIME * btime, + int16_t * utc_offset_minutes, + bool * dst_active) +{ + bool status = false; + struct tm *tblock = NULL; + struct timeval tv; + + if (gettimeofday(&tv, NULL) == 0) { + tblock = (struct tm *)localtime((const time_t *)&tv.tv_sec); + } + if (tblock) { + status = true; + /** struct tm + * int tm_sec Seconds [0,60]. + * int tm_min Minutes [0,59]. + * int tm_hour Hour [0,23]. + * int tm_mday Day of month [1,31]. + * int tm_mon Month of year [0,11]. + * int tm_year Years since 1900. + * int tm_wday Day of week [0,6] (Sunday =0). + * int tm_yday Day of year [0,365]. + * int tm_isdst Daylight Savings flag. + */ + datetime_set_date(bdate, (uint16_t)tblock->tm_year + 1900, + (uint8_t)tblock->tm_mon + 1, + (uint8_t)tblock->tm_mday); + datetime_set_time(btime, (uint8_t)tblock->tm_hour, + (uint8_t)tblock->tm_min, (uint8_t)tblock->tm_sec, + (uint8_t)(tv.tv_usec / 10000)); + if (dst_active) { + /* The value of tm_isdst is: + - positive if Daylight Saving Time is in effect, + - 0 if Daylight Saving Time is not in effect, and + - negative if the information is not available. */ + if (tblock->tm_isdst > 0) { + *dst_active = true; + } else { + *dst_active = false; + } + } + /* note: timezone is declared in stdlib. */ + if (utc_offset_minutes) { + /* timezone is set to the difference, in seconds, + between Coordinated Universal Time (UTC) and + local standard time */ + *utc_offset_minutes = timezone / 60; + } + } + + return status; +} + +/** + * initialize the date time + */ +void datetime_init(void) +{ + /* nothing to do */ +} diff --git a/ports/bsd/main.c b/ports/bsd/main.c index a72d192b..9ed03ca5 100644 --- a/ports/bsd/main.c +++ b/ports/bsd/main.c @@ -29,22 +29,22 @@ #include #include #include -#include "config.h" -#include "address.h" -#include "bacdef.h" -#include "handlers.h" -#include "client.h" -#include "bacdcode.h" -#include "npdu.h" -#include "apdu.h" -#include "iam.h" -#include "tsm.h" -#include "device.h" -#include "bacfile.h" -#include "datalink.h" -#include "net.h" -#include "txbuf.h" -#include "dlenv.h" +#include "bacnet/config.h" +#include "bacnet/basic/binding/address.h" +#include "bacnet/bacdef.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/services.h" +#include "bacnet/bacdcode.h" +#include "bacnet/npdu.h" +#include "bacnet/apdu.h" +#include "bacnet/iam.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/basic/object/device.h" +#include "bacnet/basic/object/bacfile.h" +#include "bacnet/datalink/datalink.h" +#include "bacport.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/datalink/dlenv.h" /** @file bsd/main.c Example application using the BACnet Stack on BSD/MAC OS X. */ diff --git a/ports/bsd/mstimer-init.c b/ports/bsd/mstimer-init.c new file mode 100644 index 00000000..93bbffc4 --- /dev/null +++ b/ports/bsd/mstimer-init.c @@ -0,0 +1,94 @@ +/************************************************************************** +* +* Copyright (C) 2009 Steve Karg +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +* +*********************************************************************/ +#include +#include +#include +#include +#include "mstimer.h" +#include +#include + +/** @file bsd/timer.c Provides BSD-specific time and timer functions. */ + +/* counter for the various timers */ +static volatile unsigned long Millisecond_Counter; + +/* start time for the clock */ +static struct timespec start; +/* The timeGetTime function retrieves the system time, in milliseconds. + The system time is the time elapsed since the OS was started. */ +unsigned long timeGetTime( + void) +{ + struct timespec now; + unsigned long ticks; + + clock_serv_t cclock; + mach_timespec_t mts; + host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock); + clock_get_time(cclock, &mts); + mach_port_deallocate(mach_task_self(), cclock); + now.tv_sec = mts.tv_sec; + now.tv_nsec = mts.tv_nsec; + + ticks = + (now.tv_sec - start.tv_sec) * 1000 + (now.tv_nsec - + start.tv_nsec) / 1000000; + + return ticks; +} + +/** +* @brief returns the current millisecond count +* @return millisecond counter +*/ +unsigned long mstimer_now(void) +{ + unsigned long now = timeGetTime(); + unsigned long delta_time = 0; + + if (Millisecond_Counter <= now) { + delta_time = now - Millisecond_Counter; + } else { + delta_time = (ULONG_MAX - Millisecond_Counter) + now + 1; + } + + return delta_time; +} + +/** +* @brief Initialization for timer +*/ +void timer_init( + void) +{ + clock_serv_t cclock; + mach_timespec_t mts; + host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock); + clock_get_time(cclock, &mts); + mach_port_deallocate(mach_task_self(), cclock); + start.tv_sec = mts.tv_sec; + start.tv_nsec = mts.tv_nsec; +} diff --git a/ports/bsd/readme.txt b/ports/bsd/readme.txt index fb7e766f..202cff60 100644 --- a/ports/bsd/readme.txt +++ b/ports/bsd/readme.txt @@ -1,2 +1 @@ This is a port to MAC OS X for testing. -The unit tests can be run via the test.sh script. diff --git a/ports/bsd/timer.c b/ports/bsd/timer.c deleted file mode 100644 index 7d73dbd7..00000000 --- a/ports/bsd/timer.c +++ /dev/null @@ -1,156 +0,0 @@ -/************************************************************************** -* -* Copyright (C) 2009 Steve Karg -* -* Permission is hereby granted, free of charge, to any person obtaining -* a copy of this software and associated documentation files (the -* "Software"), to deal in the Software without restriction, including -* without limitation the rights to use, copy, modify, merge, publish, -* distribute, sublicense, and/or sell copies of the Software, and to -* permit persons to whom the Software is furnished to do so, subject to -* the following conditions: -* -* The above copyright notice and this permission notice shall be included -* in all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -* -*********************************************************************/ -#include -#include -#include -#include -#include "timer.h" -#include -#include - -/** @file bsd/timer.c Provides BSD-specific time and timer functions. */ - -/* counter for the various timers */ -static volatile uint32_t Millisecond_Counter[MAX_MILLISECOND_TIMERS]; - -/* start time for the clock */ -static struct timespec start; -/* The timeGetTime function retrieves the system time, in milliseconds. - The system time is the time elapsed since Windows was started. */ -uint32_t timeGetTime( - void) -{ - struct timespec now; - uint32_t ticks; - - /* clock_gettime(CLOCK_MONOTONIC, &now); */ - clock_serv_t cclock; - mach_timespec_t mts; - host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock); - clock_get_time(cclock, &mts); - mach_port_deallocate(mach_task_self(), cclock); - now.tv_sec = mts.tv_sec; - now.tv_nsec = mts.tv_nsec; - - ticks = - (now.tv_sec - start.tv_sec) * 1000 + (now.tv_nsec - - start.tv_nsec) / 1000000; - - return ticks; -} - -/************************************************************************* -* Description: returns the current millisecond count -* Returns: none -* Notes: none -*************************************************************************/ -uint32_t timer_milliseconds( - unsigned index) -{ - uint32_t now = timeGetTime(); - uint32_t delta_time = 0; - - if (index < MAX_MILLISECOND_TIMERS) { - if (Millisecond_Counter[index] <= now) { - delta_time = now - Millisecond_Counter[index]; - } else { - delta_time = (UINT32_MAX - Millisecond_Counter[index]) + now + 1; - } - } - - return delta_time; -} - -/************************************************************************* -* Description: compares the current time count with a value -* Returns: true if the time has elapsed -* Notes: none -*************************************************************************/ -bool timer_elapsed_milliseconds( - unsigned index, - uint32_t value) -{ - return (timer_milliseconds(index) >= value); -} - -/************************************************************************* -* Description: compares the current time count with a value -* Returns: true if the time has elapsed -* Notes: none -*************************************************************************/ -bool timer_elapsed_seconds( - unsigned index, - uint32_t seconds) -{ - return ((timer_milliseconds(index) / 1000) >= seconds); -} - -/************************************************************************* -* Description: compares the current time count with a value -* Returns: true if the time has elapsed -* Notes: none -*************************************************************************/ -bool timer_elapsed_minutes( - unsigned index, - uint32_t minutes) -{ - return ((timer_milliseconds(index) / (1000 * 60)) >= minutes); -} - -/************************************************************************* -* Description: Sets the timer counter to zero. -* Returns: none -* Notes: none -*************************************************************************/ -uint32_t timer_reset( - unsigned index) -{ - uint32_t timer_value = 0; - - if (index < MAX_MILLISECOND_TIMERS) { - timer_value = timer_milliseconds(index); - Millisecond_Counter[index] = timeGetTime(); - } - - return timer_value; -} - -/************************************************************************* -* Description: Initialization for timer -* Returns: none -* Notes: none -*************************************************************************/ -void timer_init( - void) -{ - /*clock_gettime(CLOCK_MONOTONIC, &start); */ - clock_serv_t cclock; - mach_timespec_t mts; - host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock); - clock_get_time(cclock, &mts); - mach_port_deallocate(mach_task_self(), cclock); - start.tv_sec = mts.tv_sec; - start.tv_nsec = mts.tv_nsec; -} diff --git a/ports/dos/bacnet.prj b/ports/dos/bacnet.prj deleted file mode 100644 index ce2a1677177fe31434e2f4e846887f9187515860..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4610 zcmeH~-*XdH6vxlqCj9{|ziCTpVF#j63TYc!5{k}{?rtDMek{pmC>TXcLoF0qOA9E{ zB4QDL%Y$$J1Q#bB{iAEmch~Sw)y0od%x$NyEk`t z@3khz`bShvHOEGdWsZ!ip`qc7+C-vmMT2M}s`Al{`z9$Q=oXXcwzNNx{7}|>B<+ux zw*86Zr;?w^`a6=JGb`u|=5G3i`=W1w?||3d_Gq8RKY=8udxsa$} zkPC1Fm8h#?tf^)U)G*XV3|b7-0(HO=hFA(~8L%8!0jva8F~n-19&Q8B2&@5`fVDs~ zL$ttJ$Ea8jSB2XqFh>U!_K!2@5UfXlH1H_!7;qSP9C!lg2aW&(Kn6Gp3<6IwXb9FY za02d0UjhvM?q%RbxL1IefR}++fLDRnfj59Rfvdnaq4N|iym-Y0(t6UCmJY|XNJ=+$dDFYR z-ZcN`Di)rjR1fX5V~B)%37`94I)sb1`-nP)n|$4z-^WI0M+eb%F?Iiklb^9mtfMXY zRdc-Vl8PNA75j z^Rdx-dSqxo-Qqo>mYv`}3E#KHq$S_E!BeL)C;EpoW5qIC!DO^p+kEQVqkU@op|IK> zS3UQ-@A-^pzA-m#%Ff`Vp6Q<$94tPAG(IrjB!%NtkI`quf>EPz^S`F{*6bAWzV9e+ z`HC(=8XslFJ-o30$`szV@pSyZENBM0X&rBv*VFQS-oVvmM4P#{RyUCzi6$+R-$6kw zW>}M*X)~U%l4(88AE)W>B*y8(#V<16u*+OdY>Ew2+j}4!FPLk#$vcIzQd=&nsfHHul{tmiq%80g$*w?m;apCW6IRyuVydM& zo=2zLohxZ1!of(vIh<{B;>!76LQ82GpBCxD4%%3;fkUo~_r%v?M${`Cm4}ss%7k)N zxu)DvepV_gR##vw?})d>IdNQs#7<$`TlqBj3x%kk-r{YHZHKrI7d27s*~|X5q*kZv zo26~rJn9~zYFa7%Rg$ZvqF&k!(r(PDZ?wE?qYtBxkC6Q5F{k}Y>B_Nl{v}dTC)Kr* zi|H%#Ja3!UPHhU*P@}dXP)*nOw+5zb<_8o{P zbjL3e#CM~k$lWNp^s~2(%x{IGM#2$hyUHEV(tH~Pb-h^QT_eg5(-NA~Uv?$u&5hG} z%+ynkEI&T?2q_q)#bcrHp2BfFTqBl>7H!mxP<~rBZQjq62*>91UO=Shdcs2EUp5@G z&@UDld%f{^1TI$I?8DH{`}F0!#C_CB9n?-<+D2QcjSpX~{7~IQ57GnV;lDWrudqJ= DT4@JA diff --git a/ports/dos/dlmstp.c b/ports/dos/dlmstp.c deleted file mode 100644 index 5337fba9..00000000 --- a/ports/dos/dlmstp.c +++ /dev/null @@ -1,1328 +0,0 @@ -/*####COPYRIGHTBEGIN#### - ------------------------------------------- - Copyright (C) 2007 Steve Karg - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to: - The Free Software Foundation, Inc. - 59 Temple Place - Suite 330 - Boston, MA 02111-1307 - USA. - - As a special exception, if other files instantiate templates or - use macros or inline functions from this file, or you compile - this file and link it with other works to produce a work based - on this file, this file does not by itself cause the resulting - work to be covered by the GNU General Public License. However - the source code for this file must still be made available in - accordance with section (3) of the GNU General Public License. - - This exception does not invalidate any other reasons why a work - based on this file might be covered by the GNU General Public - License. - ------------------------------------------- -####COPYRIGHTEND####*/ -#include -#include -#include -#include -#include "bacdef.h" -#include "dlmstp.h" -#include "rs485.h" -#include "crc.h" -#include "npdu.h" -#include "bits.h" -#include "bytes.h" -#include "bacaddr.h" - -/* This file has been customized for use with small microprocessors */ -/* Assumptions: - Only one MS/TP datalink layer -*/ -#include "timer.h" - -/* The value 255 is used to denote broadcast when used as a */ -/* destination address but is not allowed as a value for a station. */ -/* Station addresses for master nodes can be 0-127. */ -/* Station addresses for slave nodes can be 127-254. */ -#define MSTP_BROADCAST_ADDRESS 255 - -/* MS/TP Frame Type */ -/* Frame Types 8 through 127 are reserved by ASHRAE. */ -#define FRAME_TYPE_TOKEN 0 -#define FRAME_TYPE_POLL_FOR_MASTER 1 -#define FRAME_TYPE_REPLY_TO_POLL_FOR_MASTER 2 -#define FRAME_TYPE_TEST_REQUEST 3 -#define FRAME_TYPE_TEST_RESPONSE 4 -#define FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY 5 -#define FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY 6 -#define FRAME_TYPE_REPLY_POSTPONED 7 -/* Frame Types 128 through 255: Proprietary Frames */ -/* These frames are available to vendors as proprietary (non-BACnet) frames. */ -/* The first two octets of the Data field shall specify the unique vendor */ -/* identification code, most significant octet first, for the type of */ -/* vendor-proprietary frame to be conveyed. The length of the data portion */ -/* of a Proprietary frame shall be in the range of 2 to 501 octets. */ -#define FRAME_TYPE_PROPRIETARY_MIN 128 -#define FRAME_TYPE_PROPRIETARY_MAX 255 - -/* receive FSM states */ -typedef enum { - MSTP_RECEIVE_STATE_IDLE = 0, - MSTP_RECEIVE_STATE_PREAMBLE = 1, - MSTP_RECEIVE_STATE_HEADER = 2, - MSTP_RECEIVE_STATE_DATA = 3 -} MSTP_RECEIVE_STATE; - -/* master node FSM states */ -typedef enum { - MSTP_MASTER_STATE_INITIALIZE = 0, - MSTP_MASTER_STATE_IDLE = 1, - MSTP_MASTER_STATE_USE_TOKEN = 2, - MSTP_MASTER_STATE_WAIT_FOR_REPLY = 3, - MSTP_MASTER_STATE_DONE_WITH_TOKEN = 4, - MSTP_MASTER_STATE_PASS_TOKEN = 5, - MSTP_MASTER_STATE_NO_TOKEN = 6, - MSTP_MASTER_STATE_POLL_FOR_MASTER = 7, - MSTP_MASTER_STATE_ANSWER_DATA_REQUEST = 8 -} MSTP_MASTER_STATE; - -/* The state of the Receive State Machine */ -static MSTP_RECEIVE_STATE Receive_State; -/* When a master node is powered up or reset, */ -/* it shall unconditionally enter the INITIALIZE state. */ -static MSTP_MASTER_STATE Master_State; -/* bit-sized boolean flags */ -static struct mstp_flag_t { - /* A Boolean flag set to TRUE by the Receive State Machine */ - /* if an invalid frame is received. */ - /* Set to FALSE by the main state machine. */ - unsigned ReceivedInvalidFrame:1; - /* A Boolean flag set to TRUE by the Receive State Machine */ - /* if a valid frame is received. */ - /* Set to FALSE by the main state machine. */ - unsigned ReceivedValidFrame:1; - /* A Boolean flag set to TRUE by the master machine if this node is the */ - /* only known master node. */ - unsigned SoleMaster:1; - /* A Boolean flag set TRUE by the datalink transmit if a - frame is pending */ - unsigned TransmitPacketPending:1; - /* A Boolean flag set TRUE by the datalink transmit if a - pending packet is DataExpectingReply */ - unsigned TransmitPacketDER:1; - /* A Boolean flag set TRUE by the datalink if a - packet has been received, but not processed. */ - unsigned ReceivePacketPending:1; -} MSTP_Flag; - -/* Used to store the data length of a received frame. */ -static uint16_t DataLength; -/* Used to store the destination address of a received frame. */ -static uint8_t DestinationAddress; -/* Used to count the number of received octets or errors. */ -/* This is used in the detection of link activity. */ -/* Compared to Nmin_octets */ -static uint8_t EventCount; -/* Used to store the frame type of a received frame. */ -static uint8_t FrameType; -/* An array of octets, used to store octets as they are received. */ -/* InputBuffer is indexed from 0 to InputBufferSize-1. */ -/* FIXME: assign this to an actual array of bytes! */ -/* Note: the buffer is designed as a pointer since some compilers - and microcontroller architectures have limits as to places to - hold contiguous memory. */ -static uint8_t *InputBuffer; -static uint8_t InputBufferSize; -/* Used to store the Source Address of a received frame. */ -static uint8_t SourceAddress; -/* "This Station," the MAC address of this node. TS is generally read from a */ -/* hardware DIP switch, or from nonvolatile memory. Valid values for TS are */ -/* 0 to 254. The value 255 is used to denote broadcast when used as a */ -/* destination address but is not allowed as a value for TS. */ -static uint8_t This_Station; -/* This parameter represents the value of the Max_Info_Frames property of */ -/* the node's Device object. The value of Max_Info_Frames specifies the */ -/* maximum number of information frames the node may send before it must */ -/* pass the token. Max_Info_Frames may have different values on different */ -/* nodes. This may be used to allocate more or less of the available link */ -/* bandwidth to particular nodes. If Max_Info_Frames is not writable in a */ -/* node, its value shall be 1. */ -static uint8_t Nmax_info_frames; -/* This parameter represents the value of the Max_Master property of the */ -/* node's Device object. The value of Max_Master specifies the highest */ -/* allowable address for master nodes. The value of Max_Master shall be */ -/* less than or equal to 127. If Max_Master is not writable in a node, */ -/* its value shall be 127. */ -static uint8_t Nmax_master; -/* An array of octets, used to store octets for transmitting */ -/* OutputBuffer is indexed from 0 to OutputBufferSize-1. */ -/* The MAX_PDU size of a frame is MAX_APDU + MAX_NPDU octets. */ -/* FIXME: assign this to an actual array of bytes! */ -/* Note: the buffer is designed as a pointer since some compilers - and microcontroller architectures have limits as to places to - hold contiguous memory. */ -static uint8_t *TransmitPacket; -static uint16_t TransmitPacketLen; -static uint8_t TransmitPacketDest; - -/* The time without a DataAvailable or ReceiveError event before declaration */ -/* of loss of token: 500 milliseconds. */ -#define Tno_token 500 - -/* The minimum time without a DataAvailable or ReceiveError event */ -/* that a node must wait for a station to begin replying to a */ -/* confirmed request: 255 milliseconds. (Implementations may use */ -/* larger values for this timeout, not to exceed 300 milliseconds.) */ -#define Treply_timeout 260 - -/* The minimum time without a DataAvailable or ReceiveError event that a */ -/* node must wait for a remote node to begin using a token or replying to */ -/* a Poll For Master frame: 20 milliseconds. (Implementations may use */ -/* larger values for this timeout, not to exceed 100 milliseconds.) */ -#define Tusage_timeout 25 - -/* The number of tokens received or used before a Poll For Master cycle */ -/* is executed: 50. */ -#define Npoll 50 - -/* The number of retries on sending Token: 1. */ -#define Nretry_token 1 - -/* The minimum number of DataAvailable or ReceiveError events that must be */ -/* seen by a receiving node in order to declare the line "active": 4. */ -#define Nmin_octets 4 - -/* The minimum time without a DataAvailable or ReceiveError event within */ -/* a frame before a receiving node may discard the frame: 60 bit times. */ -/* (Implementations may use larger values for this timeout, */ -/* not to exceed 100 milliseconds.) */ -/* At 9600 baud, 60 bit times would be about 6.25 milliseconds */ -/* const uint16_t Tframe_abort = 1 + ((1000 * 60) / 9600); */ -#define Tframe_abort 30 - -/* The maximum idle time a sending node may allow to elapse between octets */ -/* of a frame the node is transmitting: 20 bit times. */ -#define Tframe_gap 20 - -/* The maximum time after the end of the stop bit of the final */ -/* octet of a transmitted frame before a node must disable its */ -/* EIA-485 driver: 15 bit times. */ -#define Tpostdrive 15 - -/* The maximum time a node may wait after reception of a frame that expects */ -/* a reply before sending the first octet of a reply or Reply Postponed */ -/* frame: 250 milliseconds. */ -#define Treply_delay 250 - -/* The width of the time slot within which a node may generate a token: */ -/* 10 milliseconds. */ -#define Tslot 10 - -/* The maximum time a node may wait after reception of the token or */ -/* a Poll For Master frame before sending the first octet of a frame: */ -/* 15 milliseconds. */ -#define Tusage_delay 15 - -/* we need to be able to increment without rolling over */ -#define INCREMENT_AND_LIMIT_UINT8(x) {if (x < 0xFF) x++;} - -bool dlmstp_init( - char *ifname) -{ - (void) ifname; - /* initialize hardware */ - RS485_Initialize(); - - return true; -} - -void dlmstp_cleanup( - void) -{ - /* nothing to do for static buffers */ -} - -void dlmstp_fill_bacnet_address( - BACNET_ADDRESS * src, - uint8_t mstp_address) -{ - int i = 0; - - if (mstp_address == MSTP_BROADCAST_ADDRESS) { - /* mac_len = 0 if broadcast address */ - src->mac_len = 0; - src->mac[0] = 0; - } else { - src->mac_len = 1; - src->mac[0] = mstp_address; - } - /* fill with 0's starting with index 1; index 0 filled above */ - for (i = 1; i < MAX_MAC_LEN; i++) { - src->mac[i] = 0; - } - src->net = 0; - src->len = 0; - for (i = 0; i < MAX_MAC_LEN; i++) { - src->adr[i] = 0; - } -} - -static bool dlmstp_compare_data_expecting_reply( - uint8_t * request_pdu, - uint16_t request_pdu_len, - uint8_t src_address, - uint8_t * reply_pdu, - uint16_t reply_pdu_len, - uint8_t dest_address) -{ - uint16_t offset; - /* One way to check the message is to compare NPDU - src, dest, along with the APDU type, invoke id. - Seems a bit overkill */ - struct DER_compare_t { - BACNET_NPDU_DATA npdu_data; - BACNET_ADDRESS address; - uint8_t pdu_type; - uint8_t invoke_id; - uint8_t service_choice; - }; - struct DER_compare_t request; - struct DER_compare_t reply; - - /* decode the request data */ - request.address.mac[0] = src_address; - request.address.mac_len = 1; - offset = - npdu_decode(&request_pdu[0], NULL, &request.address, - &request.npdu_data); - if (request.npdu_data.network_layer_message) { - return false; - } - request.pdu_type = request_pdu[offset] & 0xF0; - if (request.pdu_type != PDU_TYPE_CONFIRMED_SERVICE_REQUEST) { - return false; - } - request.invoke_id = request_pdu[offset + 2]; - /* segmented message? */ - if (request_pdu[offset] & BIT3) - request.service_choice = request_pdu[offset + 5]; - else - request.service_choice = request_pdu[offset + 3]; - /* decode the reply data */ - reply.address.mac[0] = dest_address; - reply.address.mac_len = 1; - offset = - npdu_decode(&reply_pdu[0], &reply.address, NULL, &reply.npdu_data); - if (reply.npdu_data.network_layer_message) { - return false; - } - /* reply could be a lot of things: - confirmed, simple ack, abort, reject, error */ - reply.pdu_type = reply_pdu[offset] & 0xF0; - switch (reply.pdu_type) { - case PDU_TYPE_SIMPLE_ACK: - reply.invoke_id = reply_pdu[offset + 1]; - reply.service_choice = reply_pdu[offset + 2]; - break; - case PDU_TYPE_COMPLEX_ACK: - reply.invoke_id = reply_pdu[offset + 1]; - /* segmented message? */ - if (reply_pdu[offset] & BIT3) - reply.service_choice = reply_pdu[offset + 4]; - else - reply.service_choice = reply_pdu[offset + 2]; - break; - case PDU_TYPE_ERROR: - reply.invoke_id = reply_pdu[offset + 1]; - reply.service_choice = reply_pdu[offset + 2]; - break; - case PDU_TYPE_REJECT: - case PDU_TYPE_ABORT: - reply.invoke_id = reply_pdu[offset + 1]; - break; - default: - return false; - } - if (request.invoke_id != reply.invoke_id) { - return false; - } - /* these services don't have service choice included */ - if ((reply.pdu_type != PDU_TYPE_REJECT) && - (reply.pdu_type != PDU_TYPE_ABORT)) { - if (request.service_choice != reply.service_choice) { - return false; - } - } - if (request.npdu_data.protocol_version != reply.npdu_data.protocol_version) { - return false; - } - if (request.npdu_data.priority != reply.npdu_data.priority) { - return false; - } - if (!bacnet_address_same(&request.address, &reply.address)) { - return false; - } - - return true; -} - -/* MS/TP Frame Format */ -/* All frames are of the following format: */ -/* */ -/* Preamble: two octet preamble: X`55', X`FF' */ -/* Frame Type: one octet */ -/* Destination Address: one octet address */ -/* Source Address: one octet address */ -/* Length: two octets, most significant octet first, of the Data field */ -/* Header CRC: one octet */ -/* Data: (present only if Length is non-zero) */ -/* Data CRC: (present only if Length is non-zero) two octets, */ -/* least significant octet first */ -/* (pad): (optional) at most one octet of padding: X'FF' */ -static void MSTP_Send_Frame( - uint8_t frame_type, /* type of frame to send - see defines */ - uint8_t destination, /* destination address */ - uint8_t source, /* source address */ - uint8_t * data, /* any data to be sent - may be null */ - uint16_t data_len) -{ /* number of bytes of data (up to 501) */ - uint8_t crc8 = 0xFF; /* used to calculate the crc value */ - uint16_t crc16 = 0xFFFF; /* used to calculate the crc value */ - uint8_t buffer[8]; /* stores the header and data crc */ - uint16_t i = 0; /* used to calculate CRC for data */ - - /* create the MS/TP header */ - buffer[0] = 0x55; - buffer[1] = 0xFF; - buffer[2] = frame_type; - crc8 = CRC_Calc_Header(buffer[2], crc8); - buffer[3] = destination; - crc8 = CRC_Calc_Header(buffer[3], crc8); - buffer[4] = source; - crc8 = CRC_Calc_Header(buffer[4], crc8); - buffer[5] = HI_BYTE(data_len); - crc8 = CRC_Calc_Header(buffer[5], crc8); - buffer[6] = LO_BYTE(data_len); - crc8 = CRC_Calc_Header(buffer[6], crc8); - buffer[7] = ~crc8; - RS485_Turnaround_Delay(); - RS485_Transmitter_Enable(true); - RS485_Send_Data(buffer, 8); - /* send any data */ - if (data_len) { - /* calculate CRC for any data */ - for (i = 0; i < data_len; i++) { - crc16 = CRC_Calc_Data(data[i], crc16); - } - crc16 = ~crc16; - buffer[0] = (crc16 & 0x00FF); - buffer[1] = ((crc16 & 0xFF00) >> 8); - RS485_Send_Data(data, data_len); - RS485_Send_Data(buffer, 2); - } - RS485_Transmitter_Enable(false); -} - -static void MSTP_Receive_Frame_FSM( - void) -{ - /* stores the latest received data octet */ - uint8_t DataRegister = 0; - /* Used to accumulate the CRC on the data field of a frame. */ - static uint16_t DataCRC = 0; - /* Used to accumulate the CRC on the header of a frame. */ - static uint8_t HeaderCRC = 0; - /* Used as an index by the Receive State Machine, - up to a maximum value of the MPDU */ - static uint8_t Index = 0; - - switch (Receive_State) { - case MSTP_RECEIVE_STATE_IDLE: - /* In the IDLE state, the node waits for the beginning of a frame. */ - if (RS485_ReceiveError()) { - /* EatAnError */ - Timer_Silence_Reset(); - INCREMENT_AND_LIMIT_UINT8(EventCount); - } else if (RS485_DataAvailable(&DataRegister)) { - Timer_Silence_Reset(); - INCREMENT_AND_LIMIT_UINT8(EventCount); - if (DataRegister == 0x55) { - /* Preamble1 */ - /* receive the remainder of the frame. */ - Receive_State = MSTP_RECEIVE_STATE_PREAMBLE; - } - } - break; - case MSTP_RECEIVE_STATE_PREAMBLE: - /* In the PREAMBLE state, the node waits for the - second octet of the preamble. */ - if (Timer_Silence() > Tframe_abort) { - /* Timeout */ - /* a correct preamble has not been received */ - /* wait for the start of a frame. */ - Receive_State = MSTP_RECEIVE_STATE_IDLE; - } else if (RS485_ReceiveError()) { - /* Error */ - Timer_Silence_Reset(); - INCREMENT_AND_LIMIT_UINT8(EventCount); - /* wait for the start of a frame. */ - Receive_State = MSTP_RECEIVE_STATE_IDLE; - } else if (RS485_DataAvailable(&DataRegister)) { - Timer_Silence_Reset(); - INCREMENT_AND_LIMIT_UINT8(EventCount); - if (DataRegister == 0xFF) { - /* Preamble2 */ - Index = 0; - HeaderCRC = 0xFF; - /* receive the remainder of the frame. */ - Receive_State = MSTP_RECEIVE_STATE_HEADER; - } else if (DataRegister == 0x55) { - /* ignore RepeatedPreamble1 */ - /* wait for the second preamble octet. */ - Receive_State = MSTP_RECEIVE_STATE_PREAMBLE; - } else { - /* NotPreamble */ - /* wait for the start of a frame. */ - Receive_State = MSTP_RECEIVE_STATE_IDLE; - } - } - break; - case MSTP_RECEIVE_STATE_HEADER: - /* In the HEADER state, the node waits for the fixed message header. */ - if (Timer_Silence() > Tframe_abort) { - /* Timeout */ - /* indicate that an error has occurred during the reception of a frame */ - MSTP_Flag.ReceivedInvalidFrame = true; - /* wait for the start of a frame. */ - Receive_State = MSTP_RECEIVE_STATE_IDLE; - } else if (RS485_ReceiveError()) { - /* Error */ - Timer_Silence_Reset(); - INCREMENT_AND_LIMIT_UINT8(EventCount); - /* indicate that an error has occurred during the reception of a frame */ - MSTP_Flag.ReceivedInvalidFrame = true; - /* wait for the start of a frame. */ - Receive_State = MSTP_RECEIVE_STATE_IDLE; - } else if (RS485_DataAvailable(&DataRegister)) { - Timer_Silence_Reset(); - INCREMENT_AND_LIMIT_UINT8(EventCount); - if (Index == 0) { - /* FrameType */ - HeaderCRC = CRC_Calc_Header(DataRegister, HeaderCRC); - FrameType = DataRegister; - Index = 1; - } else if (Index == 1) { - /* Destination */ - HeaderCRC = CRC_Calc_Header(DataRegister, HeaderCRC); - DestinationAddress = DataRegister; - Index = 2; - } else if (Index == 2) { - /* Source */ - HeaderCRC = CRC_Calc_Header(DataRegister, HeaderCRC); - SourceAddress = DataRegister; - Index = 3; - } else if (Index == 3) { - /* Length1 */ - HeaderCRC = CRC_Calc_Header(DataRegister, HeaderCRC); - DataLength = DataRegister * 256; - Index = 4; - } else if (Index == 4) { - /* Length2 */ - HeaderCRC = CRC_Calc_Header(DataRegister, HeaderCRC); - DataLength += DataRegister; - Index = 5; - } else if (Index == 5) { - /* HeaderCRC */ - HeaderCRC = CRC_Calc_Header(DataRegister, HeaderCRC); - /* In the HEADER_CRC state, the node validates the CRC - on the fixed message header. */ - if (HeaderCRC != 0x55) { - /* BadCRC */ - /* indicate that an error has occurred during - the reception of a frame */ - MSTP_Flag.ReceivedInvalidFrame = true; - /* wait for the start of the next frame. */ - Receive_State = MSTP_RECEIVE_STATE_IDLE; - } else { - /* Note: proposed change to BACnet MSTP state machine! - If we don't decode data that is not for us, we could - get confused about the start if the Preamble 55 FF - is part of the data. */ - if ((DataLength) && (DataLength <= InputBufferSize)) { - /* Data */ - Index = 0; - DataCRC = 0xFFFF; - /* receive the data portion of the frame. */ - Receive_State = MSTP_RECEIVE_STATE_DATA; - } else { - if (DataLength == 0) { - /* NoData */ - if ((DestinationAddress == This_Station) || - (DestinationAddress == - MSTP_BROADCAST_ADDRESS)) { - /* ForUs */ - /* indicate that a frame with - no data has been received */ - MSTP_Flag.ReceivedValidFrame = true; - } else { - /* NotForUs - drop */ - } - } else { - /* FrameTooLong */ - /* indicate that a frame with an illegal or */ - /* unacceptable data length has been received */ - MSTP_Flag.ReceivedInvalidFrame = true; - } - /* wait for the start of the next frame. */ - Receive_State = MSTP_RECEIVE_STATE_IDLE; - } - } - } else { - /* indicate that an error has occurred during */ - /* the reception of a frame */ - MSTP_Flag.ReceivedInvalidFrame = true; - /* wait for the start of a frame. */ - Receive_State = MSTP_RECEIVE_STATE_IDLE; - } - } - break; - case MSTP_RECEIVE_STATE_DATA: - /* In the DATA state, the node waits for the data portion of a frame. */ - if (Timer_Silence() > Tframe_abort) { - /* Timeout */ - /* indicate that an error has occurred during the reception of a frame */ - MSTP_Flag.ReceivedInvalidFrame = true; - /* wait for the start of the next frame. */ - Receive_State = MSTP_RECEIVE_STATE_IDLE; - } else if (RS485_ReceiveError()) { - /* Error */ - Timer_Silence_Reset(); - INCREMENT_AND_LIMIT_UINT8(EventCount); - /* indicate that an error has occurred during - the reception of a frame */ - MSTP_Flag.ReceivedInvalidFrame = true; - /* wait for the start of the next frame. */ - Receive_State = MSTP_RECEIVE_STATE_IDLE; - } else if (RS485_DataAvailable(&DataRegister)) { - Timer_Silence_Reset(); - INCREMENT_AND_LIMIT_UINT8(EventCount); - if (Index < DataLength) { - /* DataOctet */ - DataCRC = CRC_Calc_Data(DataRegister, DataCRC); - InputBuffer[Index] = DataRegister; - Index++; - } else if (Index == DataLength) { - /* CRC1 */ - DataCRC = CRC_Calc_Data(DataRegister, DataCRC); - Index++; - } else if (Index == (DataLength + 1)) { - /* CRC2 */ - DataCRC = CRC_Calc_Data(DataRegister, DataCRC); - /* STATE DATA CRC - no need for new state */ - /* indicate the complete reception of a valid frame */ - if (DataCRC == 0xF0B8) { - if ((DestinationAddress == This_Station) || - (DestinationAddress == MSTP_BROADCAST_ADDRESS)) { - /* ForUs */ - /* indicate that a frame with no data - has been received */ - MSTP_Flag.ReceivedValidFrame = true; - } - } else { - MSTP_Flag.ReceivedInvalidFrame = true; - } - Receive_State = MSTP_RECEIVE_STATE_IDLE; - } - } - break; - default: - /* shouldn't get here - but if we do... */ - Receive_State = MSTP_RECEIVE_STATE_IDLE; - break; - } - - return; -} - -/* returns true if we need to transition immediately */ -static bool MSTP_Master_Node_FSM( - void) -{ - /* The number of frames sent by this node during a single token hold. */ - /* When this counter reaches the value Nmax_info_frames, the node must */ - /* pass the token. */ - static uint8_t FrameCount; - /* "Next Station," the MAC address of the node to which This Station passes */ - /* the token. If the Next_Station is unknown, Next_Station shall be equal to */ - /* This_Station. */ - static uint8_t Next_Station; - /* "Poll Station," the MAC address of the node to which This Station last */ - /* sent a Poll For Master. This is used during token maintenance. */ - static uint8_t Poll_Station; - /* A counter of transmission retries used for Token and Poll For Master */ - /* transmission. */ - static unsigned RetryCount; - /* The number of tokens received by this node. When this counter reaches the */ - /* value Npoll, the node polls the address range between TS and NS for */ - /* additional master nodes. TokenCount is set to zero at the end of the */ - /* polling process. */ - static unsigned TokenCount; - /* next-x-station calculations */ - uint8_t next_poll_station = 0; - uint8_t next_this_station = 0; - uint8_t next_next_station = 0; - /* timeout values */ - uint16_t my_timeout = 10, ns_timeout = 0; - bool matched; - /* transition immediately to the next state */ - bool transition_now = false; - - /* some calculations that several states need */ - next_poll_station = (Poll_Station + 1) % (Nmax_master + 1); - next_this_station = (This_Station + 1) % (Nmax_master + 1); - next_next_station = (Next_Station + 1) % (Nmax_master + 1); - switch (Master_State) { - case MSTP_MASTER_STATE_INITIALIZE: - /* DoneInitializing */ - /* indicate that the next station is unknown */ - Next_Station = This_Station; - Poll_Station = This_Station; - /* cause a Poll For Master to be sent when this node first */ - /* receives the token */ - TokenCount = Npoll; - MSTP_Flag.SoleMaster = false; - Master_State = MSTP_MASTER_STATE_IDLE; - transition_now = true; - break; - case MSTP_MASTER_STATE_IDLE: - /* In the IDLE state, the node waits for a frame. */ - if (Timer_Silence() >= Tno_token) { - /* LostToken */ - /* assume that the token has been lost */ - EventCount = 0; /* Addendum 135-2004d-8 */ - Master_State = MSTP_MASTER_STATE_NO_TOKEN; - transition_now = true; - } else if (MSTP_Flag.ReceivedInvalidFrame == true) { - /* ReceivedInvalidFrame */ - /* invalid frame was received */ - MSTP_Flag.ReceivedInvalidFrame = false; - /* wait for the next frame - remain in IDLE */ - } else if (MSTP_Flag.ReceivedValidFrame == true) { - switch (FrameType) { - case FRAME_TYPE_TOKEN: - /* ReceivedToken */ - /* tokens can't be broadcast */ - if (DestinationAddress == MSTP_BROADCAST_ADDRESS) - break; - MSTP_Flag.ReceivedValidFrame = false; - FrameCount = 0; - MSTP_Flag.SoleMaster = false; - Master_State = MSTP_MASTER_STATE_USE_TOKEN; - transition_now = true; - break; - case FRAME_TYPE_POLL_FOR_MASTER: - /* ReceivedPFM */ - /* DestinationAddress is equal to TS */ - if (DestinationAddress == This_Station) { - MSTP_Send_Frame(FRAME_TYPE_REPLY_TO_POLL_FOR_MASTER, - SourceAddress, This_Station, NULL, 0); - } - break; - case FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY: - /* indicate successful reception to the higher layers */ - MSTP_Flag.ReceivePacketPending = true; - break; - case FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY: - /* indicate successful reception to the higher layers */ - MSTP_Flag.ReceivePacketPending = true; - /* broadcast DER just remains IDLE */ - if (DestinationAddress != MSTP_BROADCAST_ADDRESS) { - Master_State = - MSTP_MASTER_STATE_ANSWER_DATA_REQUEST; - } - break; - case FRAME_TYPE_TEST_REQUEST: - MSTP_Send_Frame(FRAME_TYPE_TEST_RESPONSE, - SourceAddress, This_Station, &InputBuffer[0], - DataLength); - break; - case FRAME_TYPE_TEST_RESPONSE: - default: - break; - } - /* For DATA_EXPECTING_REPLY, we will keep the Rx Frame for - reference, and the flag will be cleared in the next state */ - if (Master_State != MSTP_MASTER_STATE_ANSWER_DATA_REQUEST) { - MSTP_Flag.ReceivedValidFrame = false; - } - } - break; - /* In the USE_TOKEN state, the node is allowed to send one or */ - /* more data frames. These may be BACnet Data frames or */ - /* proprietary frames. */ - case MSTP_MASTER_STATE_USE_TOKEN: - /* Note: We could wait for up to Tusage_delay */ - if (!MSTP_Flag.TransmitPacketPending) { - /* NothingToSend */ - FrameCount = Nmax_info_frames; - Master_State = MSTP_MASTER_STATE_DONE_WITH_TOKEN; - transition_now = true; - } else { - uint8_t frame_type; - if (MSTP_Flag.TransmitPacketDER) { - frame_type = FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY; - } else { - frame_type = FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY; - } - MSTP_Send_Frame(frame_type, TransmitPacketDest, This_Station, - (uint8_t *) & TransmitPacket[0], TransmitPacketLen); - MSTP_Flag.TransmitPacketPending = false; - FrameCount++; - switch (frame_type) { - case FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY: - /* SendAndWait */ - if (TransmitPacketDest == MSTP_BROADCAST_ADDRESS) - Master_State = MSTP_MASTER_STATE_DONE_WITH_TOKEN; - else - Master_State = MSTP_MASTER_STATE_WAIT_FOR_REPLY; - break; - case FRAME_TYPE_TEST_REQUEST: - Master_State = MSTP_MASTER_STATE_WAIT_FOR_REPLY; - break; - case FRAME_TYPE_TEST_RESPONSE: - case FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY: - default: - /* SendNoWait */ - Master_State = MSTP_MASTER_STATE_DONE_WITH_TOKEN; - break; - } - } - break; - case MSTP_MASTER_STATE_WAIT_FOR_REPLY: - /* In the WAIT_FOR_REPLY state, the node waits for */ - /* a reply from another node. */ - if (Timer_Silence() >= Treply_timeout) { - /* ReplyTimeout */ - /* assume that the request has failed */ - FrameCount = Nmax_info_frames; - Master_State = MSTP_MASTER_STATE_DONE_WITH_TOKEN; - /* Any retry of the data frame shall await the next entry */ - /* to the USE_TOKEN state. (Because of the length of the timeout, */ - /* this transition will cause the token to be passed regardless */ - /* of the initial value of FrameCount.) */ - transition_now = true; - } else { - if (MSTP_Flag.ReceivedInvalidFrame == true) { - /* InvalidFrame */ - /* error in frame reception */ - MSTP_Flag.ReceivedInvalidFrame = false; - Master_State = MSTP_MASTER_STATE_DONE_WITH_TOKEN; - transition_now = true; - } else if (MSTP_Flag.ReceivedValidFrame == true) { - if (DestinationAddress == This_Station) { - /* What did we receive? */ - switch (FrameType) { - case FRAME_TYPE_REPLY_POSTPONED: - /* ReceivedReplyPostponed */ - Master_State = - MSTP_MASTER_STATE_DONE_WITH_TOKEN; - break; - case FRAME_TYPE_TEST_RESPONSE: - Master_State = - MSTP_MASTER_STATE_DONE_WITH_TOKEN; - break; - case FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY: - /* ReceivedReply */ - /* or a proprietary type that indicates a reply */ - /* indicate successful reception to the higher layers */ - MSTP_Flag.ReceivePacketPending = true; - Master_State = - MSTP_MASTER_STATE_DONE_WITH_TOKEN; - break; - default: - /* if proprietary frame was expected, you might - need to transition to DONE WITH TOKEN */ - Master_State = MSTP_MASTER_STATE_IDLE; - break; - } - } else { - /* ReceivedUnexpectedFrame */ - /* an unexpected frame was received */ - /* This may indicate the presence of multiple tokens */ - /* or a device that didn't see activity after passing */ - /* a token (how lame!). */ - /* Synchronize with the network. */ - /* This action drops the token. */ - Master_State = MSTP_MASTER_STATE_IDLE; - } - MSTP_Flag.ReceivedValidFrame = false; - transition_now = true; - } - } - break; - /* The DONE_WITH_TOKEN state either sends another data frame, */ - /* passes the token, or initiates a Poll For Master cycle. */ - case MSTP_MASTER_STATE_DONE_WITH_TOKEN: - /* SendAnotherFrame */ - if (FrameCount < Nmax_info_frames) { - /* then this node may send another information frame */ - /* before passing the token. */ - Master_State = MSTP_MASTER_STATE_USE_TOKEN; - transition_now = true; - } else if ((MSTP_Flag.SoleMaster == false) && - (Next_Station == This_Station)) { - /* NextStationUnknown - added in Addendum 135-2008v-1 */ - /* then the next station to which the token - should be sent is unknown - so PollForMaster */ - Poll_Station = next_this_station; - MSTP_Send_Frame(FRAME_TYPE_POLL_FOR_MASTER, Poll_Station, - This_Station, NULL, 0); - RetryCount = 0; - Master_State = MSTP_MASTER_STATE_POLL_FOR_MASTER; - } - /* Npoll changed in Errata SSPC-135-2004 */ - else if (TokenCount < (Npoll - 1)) { - if ((MSTP_Flag.SoleMaster == true) && - (Next_Station != next_this_station)) { - /* SoleMaster */ - /* there are no other known master nodes to */ - /* which the token may be sent (true master-slave operation). */ - FrameCount = 0; - TokenCount++; - Master_State = MSTP_MASTER_STATE_USE_TOKEN; - transition_now = true; - } else { - /* SendToken */ - /* Npoll changed in Errata SSPC-135-2004 */ - /* The comparison of NS and TS+1 eliminates the Poll For Master */ - /* if there are no addresses between TS and NS, since there is no */ - /* address at which a new master node may be found in that case. */ - TokenCount++; - /* transmit a Token frame to NS */ - MSTP_Send_Frame(FRAME_TYPE_TOKEN, Next_Station, - This_Station, NULL, 0); - RetryCount = 0; - EventCount = 0; - Master_State = MSTP_MASTER_STATE_PASS_TOKEN; - } - } else if (next_poll_station == Next_Station) { - if (MSTP_Flag.SoleMaster == true) { - /* SoleMasterRestartMaintenancePFM */ - Poll_Station = next_next_station; - MSTP_Send_Frame(FRAME_TYPE_POLL_FOR_MASTER, Poll_Station, - This_Station, NULL, 0); - /* no known successor node */ - Next_Station = This_Station; - RetryCount = 0; - TokenCount = 1; /* changed in Errata SSPC-135-2004 */ - /* EventCount = 0; removed in Addendum 135-2004d-8 */ - /* find a new successor to TS */ - Master_State = MSTP_MASTER_STATE_POLL_FOR_MASTER; - } else { - /* ResetMaintenancePFM */ - Poll_Station = This_Station; - /* transmit a Token frame to NS */ - MSTP_Send_Frame(FRAME_TYPE_TOKEN, Next_Station, - This_Station, NULL, 0); - RetryCount = 0; - TokenCount = 1; /* changed in Errata SSPC-135-2004 */ - EventCount = 0; - Master_State = MSTP_MASTER_STATE_PASS_TOKEN; - } - } else { - /* SendMaintenancePFM */ - Poll_Station = next_poll_station; - MSTP_Send_Frame(FRAME_TYPE_POLL_FOR_MASTER, Poll_Station, - This_Station, NULL, 0); - RetryCount = 0; - Master_State = MSTP_MASTER_STATE_POLL_FOR_MASTER; - } - break; - /* The PASS_TOKEN state listens for a successor to begin using */ - /* the token that this node has just attempted to pass. */ - case MSTP_MASTER_STATE_PASS_TOKEN: - if (Timer_Silence() <= Tusage_timeout) { - if (EventCount > Nmin_octets) { - /* SawTokenUser */ - /* Assume that a frame has been sent by the new token user. */ - /* Enter the IDLE state to process the frame. */ - Master_State = MSTP_MASTER_STATE_IDLE; - transition_now = true; - } - } else { - if (RetryCount < Nretry_token) { - /* RetrySendToken */ - RetryCount++; - /* Transmit a Token frame to NS */ - MSTP_Send_Frame(FRAME_TYPE_TOKEN, Next_Station, - This_Station, NULL, 0); - EventCount = 0; - /* re-enter the current state to listen for NS */ - /* to begin using the token. */ - } else { - /* FindNewSuccessor */ - /* Assume that NS has failed. */ - /* note: if NS=TS-1, this node could send PFM to self! */ - Poll_Station = next_next_station; - /* Transmit a Poll For Master frame to PS. */ - MSTP_Send_Frame(FRAME_TYPE_POLL_FOR_MASTER, Poll_Station, - This_Station, NULL, 0); - /* no known successor node */ - Next_Station = This_Station; - RetryCount = 0; - TokenCount = 0; - /* EventCount = 0; removed in Addendum 135-2004d-8 */ - /* find a new successor to TS */ - Master_State = MSTP_MASTER_STATE_POLL_FOR_MASTER; - } - } - break; - /* The NO_TOKEN state is entered if Timer_Silence() becomes greater */ - /* than Tno_token, indicating that there has been no network activity */ - /* for that period of time. The timeout is continued to determine */ - /* whether or not this node may create a token. */ - case MSTP_MASTER_STATE_NO_TOKEN: - my_timeout = Tno_token + (Tslot * This_Station); - if (Timer_Silence() < my_timeout) { - if (EventCount > Nmin_octets) { - /* SawFrame */ - /* Some other node exists at a lower address. */ - /* Enter the IDLE state to receive and process the incoming frame. */ - Master_State = MSTP_MASTER_STATE_IDLE; - transition_now = true; - } - } else { - ns_timeout = Tno_token + (Tslot * (This_Station + 1)); - if (Timer_Silence() < ns_timeout) { - /* GenerateToken */ - /* Assume that this node is the lowest numerical address */ - /* on the network and is empowered to create a token. */ - Poll_Station = next_this_station; - /* Transmit a Poll For Master frame to PS. */ - MSTP_Send_Frame(FRAME_TYPE_POLL_FOR_MASTER, Poll_Station, - This_Station, NULL, 0); - /* indicate that the next station is unknown */ - Next_Station = This_Station; - RetryCount = 0; - TokenCount = 0; - /* EventCount = 0; removed Addendum 135-2004d-8 */ - /* enter the POLL_FOR_MASTER state to find a new successor to TS. */ - Master_State = MSTP_MASTER_STATE_POLL_FOR_MASTER; - } - } - break; - /* In the POLL_FOR_MASTER state, the node listens for a reply to */ - /* a previously sent Poll For Master frame in order to find */ - /* a successor node. */ - case MSTP_MASTER_STATE_POLL_FOR_MASTER: - if (MSTP_Flag.ReceivedValidFrame == true) { - if ((DestinationAddress == This_Station) - && (FrameType == FRAME_TYPE_REPLY_TO_POLL_FOR_MASTER)) { - /* ReceivedReplyToPFM */ - MSTP_Flag.SoleMaster = false; - Next_Station = SourceAddress; - EventCount = 0; - /* Transmit a Token frame to NS */ - MSTP_Send_Frame(FRAME_TYPE_TOKEN, Next_Station, - This_Station, NULL, 0); - Poll_Station = This_Station; - TokenCount = 0; - RetryCount = 0; - Master_State = MSTP_MASTER_STATE_PASS_TOKEN; - } else { - /* ReceivedUnexpectedFrame */ - /* An unexpected frame was received. */ - /* This may indicate the presence of multiple tokens. */ - /* enter the IDLE state to synchronize with the network. */ - /* This action drops the token. */ - Master_State = MSTP_MASTER_STATE_IDLE; - transition_now = true; - } - MSTP_Flag.ReceivedValidFrame = false; - } else if ((Timer_Silence() > Tusage_timeout) || - (MSTP_Flag.ReceivedInvalidFrame == true)) { - if (MSTP_Flag.SoleMaster == true) { - /* SoleMaster */ - /* There was no valid reply to the periodic poll */ - /* by the sole known master for other masters. */ - FrameCount = 0; - /* TokenCount++; removed in 2004 */ - Master_State = MSTP_MASTER_STATE_USE_TOKEN; - transition_now = true; - } else { - if (Next_Station != This_Station) { - /* DoneWithPFM */ - /* There was no valid reply to the maintenance */ - /* poll for a master at address PS. */ - EventCount = 0; - /* transmit a Token frame to NS */ - MSTP_Send_Frame(FRAME_TYPE_TOKEN, Next_Station, - This_Station, NULL, 0); - RetryCount = 0; - Master_State = MSTP_MASTER_STATE_PASS_TOKEN; - } else { - if (next_poll_station != This_Station) { - /* SendNextPFM */ - Poll_Station = next_poll_station; - /* Transmit a Poll For Master frame to PS. */ - MSTP_Send_Frame(FRAME_TYPE_POLL_FOR_MASTER, - Poll_Station, This_Station, NULL, 0); - RetryCount = 0; - /* Re-enter the current state. */ - } else { - /* DeclareSoleMaster */ - /* to indicate that this station is the only master */ - MSTP_Flag.SoleMaster = true; - FrameCount = 0; - Master_State = MSTP_MASTER_STATE_USE_TOKEN; - transition_now = true; - } - } - } - MSTP_Flag.ReceivedInvalidFrame = false; - } - break; - /* The ANSWER_DATA_REQUEST state is entered when a */ - /* BACnet Data Expecting Reply, a Test_Request, or */ - /* a proprietary frame that expects a reply is received. */ - case MSTP_MASTER_STATE_ANSWER_DATA_REQUEST: - /* Note: we could wait for up to Treply_delay */ - if (MSTP_Flag.TransmitPacketPending) { - matched = - dlmstp_compare_data_expecting_reply(&InputBuffer[0], - DataLength, SourceAddress, &TransmitPacket[0], - TransmitPacketLen, TransmitPacketDest); - } - if (MSTP_Flag.TransmitPacketPending && matched) { - /* Reply */ - /* If a reply is available from the higher layers */ - /* within Treply_delay after the reception of the */ - /* final octet of the requesting frame */ - /* (the mechanism used to determine this is a local matter), */ - /* then call MSTP_Send_Frame to transmit the reply frame */ - /* and enter the IDLE state to wait for the next frame. */ - uint8_t frame_type; - if (MSTP_Flag.TransmitPacketDER) { - frame_type = FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY; - } else { - frame_type = FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY; - } - MSTP_Send_Frame(frame_type, TransmitPacketDest, This_Station, - (uint8_t *) & TransmitPacket[0], TransmitPacketLen); - MSTP_Flag.TransmitPacketPending = false; - Master_State = MSTP_MASTER_STATE_IDLE; - } else { - /* DeferredReply */ - /* If no reply will be available from the higher layers */ - /* within Treply_delay after the reception of the */ - /* final octet of the requesting frame (the mechanism */ - /* used to determine this is a local matter), */ - /* then an immediate reply is not possible. */ - /* Any reply shall wait until this node receives the token. */ - /* Call MSTP_Send_Frame to transmit a Reply Postponed frame, */ - /* and enter the IDLE state. */ - MSTP_Send_Frame(FRAME_TYPE_REPLY_POSTPONED, SourceAddress, - This_Station, NULL, 0); - Master_State = MSTP_MASTER_STATE_IDLE; - } - /* clear our flag we were holding for comparison */ - MSTP_Flag.ReceivedValidFrame = false; - break; - default: - Master_State = MSTP_MASTER_STATE_IDLE; - break; - } - - return transition_now; -} - -/* returns number of bytes sent on success, zero on failure */ -int dlmstp_send_pdu( - BACNET_ADDRESS * dest, /* destination address */ - BACNET_NPDU_DATA * npdu_data, /* network information */ - uint8_t * pdu, /* any data to be sent - may be null */ - unsigned pdu_len) -{ /* number of bytes of data */ - int bytes_sent = 0; - - if (MSTP_Flag.TransmitPacketPending == false) { - MSTP_Flag.TransmitPacketDER = npdu_data->data_expecting_reply; - TransmitPacket = pdu; - TransmitPacketLen = pdu_len; - bytes_sent = pdu_len; - TransmitPacketDest = dest->mac[0]; - MSTP_Flag.TransmitPacketPending = true; - } - - return bytes_sent; -} - -/* Return the length of the packet */ -uint16_t dlmstp_receive( - BACNET_ADDRESS * src, /* source address */ - uint8_t * pdu, /* PDU data */ - uint16_t max_pdu, /* amount of space available in the PDU */ - unsigned timeout) -{ /* milliseconds to wait for a packet */ - uint16_t pdu_len = 0; /* return value */ - - /* set the input buffer to the same data storage for zero copy */ - if (!InputBuffer) { - InputBuffer = pdu; - InputBufferSize = max_pdu; - } - /* only do receive state machine while we don't have a frame */ - if ((MSTP_Flag.ReceivedValidFrame == false) && - (MSTP_Flag.ReceivedInvalidFrame == false)) { - for (;;) { - MSTP_Receive_Frame_FSM(); - if (MSTP_Flag.ReceivedValidFrame || MSTP_Flag.ReceivedInvalidFrame) - break; - /* if we are not idle, then we are - receiving a frame or timing out */ - if (Receive_State == MSTP_RECEIVE_STATE_IDLE) - break; - } - } - /* only do master state machine while rx is idle */ - if (Receive_State == MSTP_RECEIVE_STATE_IDLE) { - while (MSTP_Master_Node_FSM()) { - /* do nothing while some states fast transition */ - }; - } - /* if there is a packet that needs processed, do it now. */ - if (MSTP_Flag.ReceivePacketPending) { - MSTP_Flag.ReceivePacketPending = false; - pdu_len = DataLength; - src->mac_len = 1; - src->mac[0] = SourceAddress; - /* data is already in the pdu pointer */ - } - - return pdu_len; -} - -void dlmstp_set_mac_address( - uint8_t mac_address) -{ - /* Master Nodes can only have address 0-127 */ - if (mac_address <= 127) { - This_Station = mac_address; - /* FIXME: implement your data storage */ - /* I2C_Write_Byte( - EEPROM_DEVICE_ADDRESS, - mac_address, - EEPROM_MSTP_MAC_ADDR); */ - if (mac_address > Nmax_master) - dlmstp_set_max_master(mac_address); - } - - return; -} - -uint8_t dlmstp_mac_address( - void) -{ - return This_Station; -} - -/* This parameter represents the value of the Max_Info_Frames property of */ -/* the node's Device object. The value of Max_Info_Frames specifies the */ -/* maximum number of information frames the node may send before it must */ -/* pass the token. Max_Info_Frames may have different values on different */ -/* nodes. This may be used to allocate more or less of the available link */ -/* bandwidth to particular nodes. If Max_Info_Frames is not writable in a */ -/* node, its value shall be 1. */ -void dlmstp_set_max_info_frames( - uint8_t max_info_frames) -{ - if (max_info_frames >= 1) { - Nmax_info_frames = max_info_frames; - /* FIXME: implement your data storage */ - /* I2C_Write_Byte( - EEPROM_DEVICE_ADDRESS, - (uint8_t)max_info_frames, - EEPROM_MSTP_MAX_INFO_FRAMES_ADDR); */ - } - - return; -} - -uint8_t dlmstp_max_info_frames( - void) -{ - return Nmax_info_frames; -} - -/* This parameter represents the value of the Max_Master property of the */ -/* node's Device object. The value of Max_Master specifies the highest */ -/* allowable address for master nodes. The value of Max_Master shall be */ -/* less than or equal to 127. If Max_Master is not writable in a node, */ -/* its value shall be 127. */ -void dlmstp_set_max_master( - uint8_t max_master) -{ - if (max_master <= 127) { - if (This_Station <= max_master) { - Nmax_master = max_master; - /* FIXME: implement your data storage */ - /* I2C_Write_Byte( - EEPROM_DEVICE_ADDRESS, - max_master, - EEPROM_MSTP_MAX_MASTER_ADDR); */ - } - } - - return; -} - -uint8_t dlmstp_max_master( - void) -{ - return Nmax_master; -} - -void dlmstp_get_my_address( - BACNET_ADDRESS * my_address) -{ - int i = 0; /* counter */ - - my_address->mac_len = 1; - my_address->mac[0] = This_Station; - my_address->net = 0; /* local only, no routing */ - my_address->len = 0; - for (i = 0; i < MAX_MAC_LEN; i++) { - my_address->adr[i] = 0; - } - - return; -} - -void dlmstp_get_broadcast_address( - BACNET_ADDRESS * dest) -{ /* destination address */ - int i = 0; /* counter */ - - if (dest) { - dest->mac_len = 1; - dest->mac[0] = MSTP_BROADCAST_ADDRESS; - dest->net = BACNET_BROADCAST_NETWORK; - dest->len = 0; /* always zero when DNET is broadcast */ - for (i = 0; i < MAX_MAC_LEN; i++) { - dest->adr[i] = 0; - } - } - - return; -} diff --git a/ports/dos/extkword.h b/ports/dos/extkword.h deleted file mode 100644 index 994c959a..00000000 --- a/ports/dos/extkword.h +++ /dev/null @@ -1,131 +0,0 @@ -/*==================================================================== - - _MSC_VER Microsoft C 6.0 and later - _QC Microsoft Quick C 2.51 and later - __TURBOC__ Borland Turbo C, Turbo C++ and BC++ - __BORLANDC__ Borland C++ - __ZTC__ Zortech C and C++ - __SC__ Symantec C++ - __WATCOMC__ WATCOM C - __POWERC Mix Power C - __GNUC__ Gnu C - - Revised: - - 25-Sep-95 Bob Stout Original from PC-PORT.H - 30-Mar-96 Ed Blackman OS/2 mods for OS/2 ver 2.0 and up - 30-May-96 Andrew Clarke Added support for WATCOM C/C++ __NT__ macro. - 17-Jun-96 Bob Stout Added __FLAT__ macros support - 20-Aug-96 Bob Stout Eliminate Win32 conflicts -======================================================================*/ - - -/* prevent multiple inclusions of this header file */ - -#ifndef EXTKWORD__H -#define EXTKWORD__H - -#include /* For INT_MAX, LONG_MAX */ - -/* -** Watcom defines __FLAT__ for 32-bit environments and so will we -*/ - -#if !defined(__FLAT__) && !defined(__WATCOMC__) && !defined(_MSC_VER) -#if defined(__GNUC__) -#define __FLAT__ 1 -#elif defined (_WIN32) || defined(WIN32) || defined(__NT__) -#define __FLAT__ 1 -#elif defined(__INTSIZE) -#if (4 == __INTSIZE) -#define __FLAT__ 1 -#endif -#elif (defined(__ZTC__) && !defined(__SC__)) || defined(__TURBOC__) -#if ((INT_MAX != SHRT_MAX) && (SHRT_MAX == 32767)) -#define __FLAT__ 1 -#endif -#endif -#endif - -/* -** Correct extended keywords syntax -*/ - -#if defined(__unix__) -#if !defined(FAR) -#define FAR -#endif -#if !defined(NEAR) -#define NEAR -#endif -#if !defined(HUGE) -#define HUGE -#endif -#if !defined(PASCAL) -#define PASCAL -#endif -#if !defined(CDECL) -#define CDECL -#endif -#if !defined(INTERRUPT) -#define INTERRUPT -#endif -#elif defined(__OS2__) /* EBB: not sure this works for OS/2 1.x */ -#include -#define INTERRUPT -#ifndef HUGE -#define HUGE -#endif -#elif defined(_WIN32) || defined(WIN32) || defined(__NT__) -#define WIN32_LEAN_AND_MEAN -#define NOGDI -#define NOSERVICE -#undef INC_OLE1 -#undef INC_OLE2 -#include -#define INTERRUPT -#ifndef HUGE -#define HUGE -#endif -#else /* ! Win 32 or OS/2 */ -#if (defined(__POWERC) || (defined(__TURBOC__) && !defined(__BORLANDC__)) \ - || (defined(__ZTC__) && !defined(__SC__))) && !defined(__FLAT__) -#define FAR far -#define NEAR near -#define PASCAL pascal -#define CDECL cdecl -#if (defined(__ZTC__) && !defined(__SC__)) || (defined(__SC__) && \ - (__SC__ < 0x700)) -#ifndef HUGE -#define HUGE far -#endif -#define INTERRUPT -#else -#ifndef HUGE -#define HUGE huge -#endif -#define INTERRUPT interrupt -#endif -#else -#if (defined(__MSDOS__) || defined(MSDOS)) && !defined(__FLAT__) -#define FAR _far -#define NEAR _near -#ifndef HUGE -#define HUGE _huge -#endif -#define PASCAL _pascal -#define CDECL _cdecl -#define INTERRUPT _interrupt -#else -#define FAR -#define NEAR -#ifndef HUGE -#define HUGE -#endif -#define PASCAL -#define CDECL -#endif -#endif -#endif - -#endif /* EXTKWORD__H */ diff --git a/ports/dos/main.c b/ports/dos/main.c deleted file mode 100644 index edceb182..00000000 --- a/ports/dos/main.c +++ /dev/null @@ -1,112 +0,0 @@ -/************************************************************************** -* -* Copyright (C) 2007 Steve Karg -* -* Permission is hereby granted, free of charge, to any person obtaining -* a copy of this software and associated documentation files (the -* "Software"), to deal in the Software without restriction, including -* without limitation the rights to use, copy, modify, merge, publish, -* distribute, sublicense, and/or sell copies of the Software, and to -* permit persons to whom the Software is furnished to do so, subject to -* the following conditions: -* -* The above copyright notice and this permission notice shall be included -* in all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -* -*********************************************************************/ -/* hardware specific */ -#include "timer.h" -/* standard libraries */ -#include -#include -#include -#include -/* BACnet */ -#include "rs485.h" -#include "datalink.h" -#include "npdu.h" -#include "apdu.h" -#include "dcc.h" -#include "iam.h" -#include "handlers.h" -#include "device.h" -#include "dcc.h" -#include "iam.h" -#include "txbuf.h" - -static unsigned long DCC_Timer = 1000; - -static void millisecond_timer( - void) -{ - while (Timer_Milliseconds) { - Timer_Milliseconds--; - if (DCC_Timer) { - DCC_Timer--; - } - } - /* note: MS/TP silence timer is updated in ISR */ -} - -static void bacnet_init( - void) -{ -#if defined(BACDL_MSTP) - RS485_Set_Baud_Rate(38400); - dlmstp_set_mac_address(57); - dlmstp_set_max_master(127); - dlmstp_set_max_info_frames(1); - dlmstp_init(NULL); -#endif - Device_Set_Object_Instance_Number(11111); -#ifndef DLMSTP_TEST - /* we need to handle who-is to support dynamic device binding */ - apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is); - /* Set the handlers for any confirmed services that we support. */ - /* We must implement read property - it's required! */ - apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY, - handler_read_property); - apdu_set_confirmed_handler(SERVICE_CONFIRMED_REINITIALIZE_DEVICE, - handler_reinitialize_device); - apdu_set_confirmed_handler(SERVICE_CONFIRMED_WRITE_PROPERTY, - handler_write_property); - /* handle communication so we can shutup when asked */ - apdu_set_confirmed_handler(SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL, - handler_device_communication_control); -#endif -} - -int main( - void) -{ - uint16_t pdu_len = 0; - BACNET_ADDRESS src; /* source address */ - uint8_t pdu[MAX_MPDU]; /* PDU data */ - - Timer_Init(); - bacnet_init(); - /* broadcast an I-Am on startup */ - Send_I_Am(&Handler_Transmit_Buffer[0]); - for (;;) { - millisecond_timer(); - if (!DCC_Timer) { - dcc_timer_seconds(1); - DCC_Timer = 1000; - } - /* BACnet handling */ - pdu_len = datalink_receive(&src, &pdu[0], MAX_MPDU, 0); - if (pdu_len) { -#ifndef DLMSTP_TEST - npdu_handler(&src, &pdu[0], pdu_len); -#endif - } - } -} diff --git a/ports/dos/mk_fp.h b/ports/dos/mk_fp.h deleted file mode 100644 index 88142c5b..00000000 --- a/ports/dos/mk_fp.h +++ /dev/null @@ -1,23 +0,0 @@ -/* -** MK_FP.H -** -** Standard header file making sure this pesky Intel macro is defined! -*/ - -#ifndef MK_FP__H -#define MK_FP__H - -#include "extkword.h" - -#if defined(__WATCOMC__) -#include -#elif !defined(__PACIFIC__) -#include -#endif - -#if !defined(MK_FP) -#define MK_FP(seg,off) \ - ((void FAR *)(((unsigned long)(seg) << 16)|(unsigned)(off))) -#endif - -#endif /* MK_FP__H */ diff --git a/ports/dos/pchwio.c b/ports/dos/pchwio.c deleted file mode 100644 index 44cb28ee..00000000 --- a/ports/dos/pchwio.c +++ /dev/null @@ -1,83 +0,0 @@ -/* -** PCHWIO.C - SNIPPETS portable hardware I/O access under DOS -** -** public domain by Bob Stout -*/ - -#include "pchwio.h" -#include "mk_fp.h" - -#if defined(__ZTC__) && !defined(__SC__) - -void FAR *getvect( - unsigned intnum) -{ - unsigned seg, off; - - int_getvector(intnum, &off, &seg); - return MK_FP(seg, off); -} - -void setvect( - unsigned intnum, - void (INTERRUPT FAR * handler) ()) -{ - unsigned seg = FP_SEG(handler), off = FP_OFF(handler); - - int_setvector(intnum, off, seg); -} - -#endif /* ZTC getvect(), setvect() */ - - - -#if defined(_MSC_VER) || defined(__WATCOMC__) || \ - defined(__ZTC__) || defined(__SC__) - -#if !defined(MK_FP) -#define MK_FP(seg,off) ((void far *)(((long)(seg) << 16)|(unsigned)(off))) -#endif - -unsigned char Peekb( - unsigned seg, - unsigned ofs) -{ - unsigned char FAR *ptr; - - ptr = MK_FP(seg, ofs); - return *ptr; -} - -unsigned short Peekw( - unsigned seg, - unsigned ofs) -{ - unsigned FAR *ptr; - - ptr = MK_FP(seg, ofs); - return *ptr; -} - -void Pokeb( - unsigned seg, - unsigned ofs, - unsigned char ch) -{ - unsigned char FAR *ptr; - - ptr = MK_FP(seg, ofs); - *ptr = ch; -} - -void Pokew( - unsigned seg, - unsigned ofs, - unsigned short num) -{ - unsigned FAR *ptr; - - ptr = MK_FP(seg, ofs); - *ptr = num; -} - -#endif /* MSC/ZTC/WC Peek(), poke() */ diff --git a/ports/dos/pchwio.h b/ports/dos/pchwio.h deleted file mode 100644 index cacd8c5d..00000000 --- a/ports/dos/pchwio.h +++ /dev/null @@ -1,78 +0,0 @@ -/* -** PCHWIO.H - SNIPPETS header file for portable hardware I/O access under DOS -** -** public domain by Bob Stout -*/ - -#ifndef PCHWIO__H -#define PCHWIO__H - -#include -#include "extkword.h" - - -#if defined(__TURBOC__) || defined(__POWERC) -#ifndef inp -#define inp inportb -#endif -#ifndef outp -#define outp outportb -#endif -#ifndef inpw -#define inpw inport -#endif -#ifndef outpw -#define outpw outport -#endif -#elif defined(__ZTC__) -#include -#define enable int_on -#define disable int_off -#if !defined(__SC__) -void FAR *getvect( - unsigned intnum); -void setvect( - unsigned intnum, - void (INTERRUPT FAR * handler) ()); -#else -#define getvect _dos_getvect -#define setvect _dos_setvect -#endif -#else /* assume MSC/QC/WC */ -#include -#if defined(__WATCOMC__) -#include -#endif -#define enable _enable -#define disable _disable -#define getvect _dos_getvect -#define setvect _dos_setvect -#endif - - -#if defined(_MSC_VER) || defined(__WATCOMC__) || \ - defined(__ZTC__) || defined(__SC__) - -unsigned char Peekb( - unsigned seg, - unsigned ofs); /* PCHWIO.C */ -unsigned short Peekw( - unsigned seg, - unsigned ofs); /* PCHWIO.C */ -void Pokeb( - unsigned seg, - unsigned ofs, - unsigned char ch); /* PCHWIO.C */ -void Pokew( - unsigned seg, - unsigned ofs, - unsigned short num); /* PCHWIO.C */ - -#elif defined(__TURBOC__) -#define Peekw peek -#define Pokew poke -#define Peekb peekb -#define Pokeb pokeb -#endif /* peek(), poke() */ - -#endif /* PCHWIO__H */ diff --git a/ports/dos/queue.c b/ports/dos/queue.c deleted file mode 100644 index 5d38f5ef..00000000 --- a/ports/dos/queue.c +++ /dev/null @@ -1,68 +0,0 @@ -/* -+----------------------------------------------------+ -| Thunderbird Software | -+----------------------------------------------------+ -| Filespec : Queue.c | -| Date : September 29, 1994 | -| Time : 10:16AM | -| Revision : 1.0 | -+----------------------------------------------------+ -| Programmer: Scott Andrews | -| Address : 5358 Summit RD SW | -| City/State: Pataskala, Ohio | -| Zip : 43062 | -+----------------------------------------------------+ -| Released to the Public Domain | -+----------------------------------------------------+ -*/ - -#include - -#include "queue.h" - -QUEUE *alloc_queue( - int size) -{ - QUEUE *retval; - retval = (QUEUE *) malloc(sizeof(QUEUE) + (size_t) size); - if ((QUEUE *) 0 != retval) { - retval->size = size; - retval->head = 0; - retval->tail = 0; - retval->avail = size; - retval->buffer = ((char *) retval) + sizeof(QUEUE); - } - return retval; -} - -int en_queue( - QUEUE * queue, - char data) -{ - int retval = -1; - if (0 != queue->avail) { - *(queue->buffer + queue->head) = data; - queue->head += 1; - if (queue->head == queue->size) - queue->head = 0; - queue->avail -= 1; - retval = queue->avail; - } - return retval; -} - -int de_queue( - QUEUE * queue) -{ - int retval = -1; - if (queue->avail != queue->size) { - retval = *(queue->buffer + queue->tail); - queue->tail += 1; - if (queue->tail == queue->size) - queue->tail = 0; - queue->avail += 1; - } - return retval; -} - -/* End of Queue.c */ diff --git a/ports/dos/queue.h b/ports/dos/queue.h deleted file mode 100644 index c700d8ab..00000000 --- a/ports/dos/queue.h +++ /dev/null @@ -1,45 +0,0 @@ -/* -+----------------------------------------------------+ -| Thunderbird Software | -+----------------------------------------------------+ -| Filespec : QUEUE.H | -| Date : August 30, 1994 | -| Time : 5:40 PM | -| Revision : 0.0 | -+----------------------------------------------------+ -| Programmer: Scott Andrews | -| Address : 5358 Summit RD SW | -| City/State: Pataskala, Ohio | -| Zip : 43062 | -+----------------------------------------------------+ -| Released to the Public Domain | -+----------------------------------------------------+ -*/ - -#ifndef QUEUE__H -#define QUEUE__H - -/* Needed by Serial.C */ - -typedef struct { - int size; - int head; - int tail; - int avail; - char *buffer; -} QUEUE; - -#define queue_empty(queue) (queue)->head == (queue)->tail -#define queue_avail(queue) (queue)->avail - -QUEUE *alloc_queue( - int size); -int en_queue( - QUEUE * queue_ptr, - char data); -int de_queue( - QUEUE * queue_ptr); - -/* End of Queue.H */ - -#endif /* QUEUE__H */ diff --git a/ports/dos/readme.txt b/ports/dos/readme.txt deleted file mode 100644 index 2ce90d17..00000000 --- a/ports/dos/readme.txt +++ /dev/null @@ -1,5 +0,0 @@ -This is a port to DOS using the BACnet MS/TP datalink layer. -It utilizes some serial routines from snippets.org. -It was tested and compiled with Turbo C++ 1.01 which is -freely available from http://dn.codegear.com/article/21751 -It was targeting the TS-3100 from Technologic Systems. diff --git a/ports/dos/rs485.c b/ports/dos/rs485.c deleted file mode 100644 index ded4628f..00000000 --- a/ports/dos/rs485.c +++ /dev/null @@ -1,241 +0,0 @@ -/************************************************************************** -* -* Copyright (C) 2007 Steve Karg -* RS-485 initialization on AT91SAM7S inspired by Keil Eletronik serial.c -* -* Permission is hereby granted, free of charge, to any person obtaining -* a copy of this software and associated documentation files (the -* "Software"), to deal in the Software without restriction, including -* without limitation the rights to use, copy, modify, merge, publish, -* distribute, sublicense, and/or sell copies of the Software, and to -* permit persons to whom the Software is furnished to do so, subject to -* the following conditions: -* -* The above copyright notice and this permission notice shall be included -* in all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -* -*********************************************************************/ - -/* The module handles sending data out the RS-485 port */ -/* and handles receiving data from the RS-485 port. */ -/* Customize this file for your specific hardware */ -#include -#include -#include -#include -#include -#include "timer.h" - -/* This file has been customized for use with DOS */ -#include -#include "serial.h" - -/* UART */ -static char RS485_Port = '2'; -/* baud rate */ -static int RS485_Baud = 38400; - -/* The minimum time after the end of the stop bit of the final octet of a */ -/* received frame before a node may enable its EIA-485 driver: 40 bit times. */ -/* At 9600 baud, 40 bit times would be about 4.166 milliseconds */ -/* At 19200 baud, 40 bit times would be about 2.083 milliseconds */ -/* At 38400 baud, 40 bit times would be about 1.041 milliseconds */ -/* At 57600 baud, 40 bit times would be about 0.694 milliseconds */ -/* At 76800 baud, 40 bit times would be about 0.520 milliseconds */ -/* At 115200 baud, 40 bit times would be about 0.347 milliseconds */ -/* 40 bits is 4 octets including a start and stop bit with each octet */ -#define Tturnaround (40UL) -/* turnaround_time_milliseconds = (Tturnaround*1000UL)/RS485_Baud; */ - -/**************************************************************************** -* DESCRIPTION: Initializes the RS485 hardware and variables, and starts in -* receive mode. -* RETURN: none -* ALGORITHM: none -* NOTES: none -*****************************************************************************/ -void RS485_Initialize( - void) -{ - /* baud rate */ - OpenComPort(RS485_Port); - /* FIXME: change to numeric parameters */ - InitComPort("38400", '8', 'N', '1'); - - return; -} - -void RS485_Cleanup( - void) -{ - -} - -/**************************************************************************** -* DESCRIPTION: Returns the baud rate that we are currently running at -* RETURN: none -* ALGORITHM: none -* NOTES: none -*****************************************************************************/ -uint32_t RS485_Get_Baud_Rate( - void) -{ - return RS485_Baud; -} - -/**************************************************************************** -* DESCRIPTION: Sets the baud rate for the chip USART -* RETURN: none -* ALGORITHM: none -* NOTES: none -*****************************************************************************/ -bool RS485_Set_Baud_Rate( - uint32_t baud) -{ - bool valid = true; - - switch (baud) { - case 9600: - case 19200: - case 38400: - case 57600: - case 76800: - case 115200: - RS485_Baud = baud; - /* FIXME: store the baud rate */ - break; - default: - valid = false; - break; - } - - return valid; -} - -/**************************************************************************** -* DESCRIPTION: Waits on the SilenceTimer for 40 bits. -* RETURN: none -* ALGORITHM: none -* NOTES: none -*****************************************************************************/ -void RS485_Turnaround_Delay( - void) -{ - uint16_t turnaround_time; - - /* delay after reception before trasmitting - per MS/TP spec */ - /* wait a minimum 40 bit times since reception */ - /* at least 1 ms for errors: rounding, clock tick */ - turnaround_time = 1 + ((Tturnaround * 1000UL) / RS485_Baud); - while (Timer_Silence() < turnaround_time) { - /* do nothing - wait for timer to increment */ - }; -} - -/**************************************************************************** -* DESCRIPTION: Enable or disable the transmitter -* RETURN: none -* ALGORITHM: none -* NOTES: none -*****************************************************************************/ -void RS485_Transmitter_Enable( - bool enable) -{ - (void) enable; -} - -/**************************************************************************** -* DESCRIPTION: Send some data and wait until it is sent -* RETURN: none -* ALGORITHM: none -* NOTES: none -*****************************************************************************/ -void RS485_Send_Data( - uint8_t * buffer, /* data to send */ - uint16_t nbytes) -{ /* number of bytes of data */ - /* send all the bytes */ - ComSendData(buffer, nbytes); - while (!(RS485_Interface->US_CSR & AT91C_US_TXRDY)) { - /* do nothing - wait until Tx buffer is empty */ - } - /* per MSTP spec */ - Timer_Silence_Reset(); -} - -/**************************************************************************** -* DESCRIPTION: Return true if a framing or overrun error is present -* RETURN: true if error -* ALGORITHM: none -* NOTES: Clears any error flags. -*****************************************************************************/ -bool RS485_ReceiveError( - void) -{ - bool ReceiveError = false; - /* LED on send */ - volatile AT91PS_PIO pPIO = AT91C_BASE_PIOA; - - /* check for data or error */ - if (RS485_Interface->US_CSR & (AT91C_US_OVRE | AT91C_US_FRAME)) { - /* clear the error flag */ - RS485_Interface->US_CR = AT91C_US_RSTSTA; - ReceiveError = true; - /* LED ON */ - pPIO->PIO_CODR = LED2; - } - - return ReceiveError; -} - -/**************************************************************************** -* DESCRIPTION: Return true if data is available -* RETURN: true if data is available, with the data in the parameter set -* ALGORITHM: none -* NOTES: none -*****************************************************************************/ -bool RS485_DataAvailable( - uint8_t * DataRegister) -{ - bool DataAvailable = false; - /* LED on send */ - volatile AT91PS_PIO pPIO = AT91C_BASE_PIOA; - - if (RS485_Interface->US_CSR & AT91C_US_RXRDY) { - /* data is available */ - *DataRegister = RS485_Interface->US_RHR; - DataAvailable = true; - /* LED ON */ - pPIO->PIO_CODR = LED2; - } - - return DataAvailable; -} - -#ifdef TEST_RS485 -int main( - void) -{ - unsigned i = 0; - uint8_t DataRegister; - - RS485_Set_Baud_Rate(38400); - RS485_Initialize(); - /* receive task */ - for (;;) { - if (RS485_ReceiveError()) { - fprintf(stderr, "ERROR "); - } else if (RS485_DataAvailable(&DataRegister)) { - fprintf(stderr, "%02X ", DataRegister); - } - } -} -#endif diff --git a/ports/dos/serial.c b/ports/dos/serial.c deleted file mode 100644 index 4f4c73c1..00000000 --- a/ports/dos/serial.c +++ /dev/null @@ -1,382 +0,0 @@ -/* -+----------------------------------------------------+ -| Thunderbird Software | -+----------------------------------------------------+ -| Filespec : Serial.c | -| Date : October 24, 1991 | -| Time : 15:03 | -| Revision : 1.1 | -| Update: August 29, 1994 | -+----------------------------------------------------+ -| Programmer: Scott Andrews | -| Address : 5358 Summit RD SW | -| City/State: Pataskala, Ohio | -| Zip : 43062 | -+----------------------------------------------------+ -| Released to the Public Domain | -+----------------------------------------------------+ -*/ - -/* -+----------------------------------------------------------+ -| Call open_serial to install the interrupt handler | -| You must call close_serial before exiting your program | -| or a machine crash will occur! | -+----------------------------------------------------------+ -*/ - -#include -#include -#include -#include "serial.h" -#include "queue.h" - -QUEUE *Serial_In_Queue; -QUEUE *Serial_Out_Queue; - -OLD_COMM_PARAMS old_comm_params; -COMM_STATUS comm_status; - -void ( - INTERRUPT FAR * oldvector_serial) ( - ); -/* save addr for intr handler */ - -int ComBase; /* Comm port address */ -int IrqNum; /* Comm interrupt request */ - -void CloseComPort( - void) -{ - int status; - - /* restore UART to previous state */ - - outp(ComBase + INT_EN, (unsigned char) 0); - outp(ComBase + MODEM_CNTRL, (unsigned char) old_comm_params.modem); - status = inp(ComBase + LINE_CNTRL); - outp(ComBase + LINE_CNTRL, (unsigned char) status | 0x80); - outp(ComBase + BAUD_LSB, (unsigned char) old_comm_params.baud_lsb); - outp(ComBase + BAUD_MSB, (unsigned char) old_comm_params.baud_msb); - outp(ComBase + LINE_CNTRL, (unsigned char) old_comm_params.line); - outp(0x21, (unsigned char) old_comm_params.int_cntrl); - - /* restore old interrupt handler */ - - setvect(IrqNum + 8, oldvector_serial); - - /* free input and output queues */ - - free(Serial_In_Queue); - free(Serial_Out_Queue); - return; -} - -int OpenComPort( - char Port) -{ /* install int. handler */ - unsigned status; - int retval = -1; - - /* allocate input and output queues */ - - Serial_In_Queue = alloc_queue(SerInBufSize); - if ((QUEUE *) 0 == Serial_In_Queue) - return retval; - Serial_Out_Queue = alloc_queue(SerOutBufSize); - if ((QUEUE *) 0 == Serial_Out_Queue) { - free(Serial_In_Queue); - return retval; - } - retval = 0; - - /* Setup Comm base port address and IRQ number */ - - switch (Port) { - case '1': - ComBase = 0x3F8; - IrqNum = 4; - break; - case '2': - ComBase = 0x2F8; - IrqNum = 3; - break; - case '3': - ComBase = 0x3E8; - IrqNum = 4; - break; - case '4': - ComBase = 0x2E8; - IrqNum = 3; - break; - default: - ComBase = 0x3F8; - IrqNum = 4; - break; - } - old_comm_params.int_enable = inp(ComBase + INT_EN); - outp(ComBase + INT_EN, 0); /* turn off comm interrupts */ - - /* save old comm parameters */ - - old_comm_params.line = inp(ComBase + LINE_CNTRL); - old_comm_params.modem = inp(ComBase + MODEM_CNTRL); - status = inp(ComBase + LINE_CNTRL); - outp(ComBase + LINE_CNTRL, (unsigned char) status | 0x80); - old_comm_params.baud_lsb = inp(ComBase + BAUD_LSB); - old_comm_params.baud_msb = inp(ComBase + BAUD_MSB); - status = inp(ComBase + LINE_CNTRL); - outp(ComBase + LINE_CNTRL, (unsigned char) status | 0x7F); - status = OUT2 | DTR; /* DTR/OUT2 must be set! */ - outp(ComBase + MODEM_CNTRL, (unsigned char) status); - - /* get serial port address/vector */ - - oldvector_serial = (void (INTERRUPT FAR *) (void)) getvect(IrqNum + 8); - - /* set our interrupt handler */ - - setvect(IrqNum + 8, serial); - - /* save the PIC */ - - old_comm_params.int_cntrl = inp(0x21); - status = (1 << IrqNum); /* calculate int enable bit */ - status = ~status; - - /* ok enable comm ints */ - - outp(0x21, - (unsigned char) old_comm_params.int_cntrl & (unsigned char) status); - - atexit(CloseComPort); - - return retval; -} - -void InitComPort( - char Baud[], - char Databits, - char Parity, - char Stopbits) -{ - int status; - unsigned divisor; - long baudrate; - - /* set baud rate */ - - status = inp(ComBase + LINE_CNTRL); - outp(ComBase + LINE_CNTRL, (unsigned char) status | 0x80); - baudrate = atol(Baud); - if (baudrate == 0) - baudrate = 2400L; - divisor = (unsigned) (115200L / baudrate); - outp(ComBase + BAUD_LSB, (unsigned char) (divisor & 0x00FF)); - outp(ComBase + BAUD_MSB, (unsigned char) ((divisor >> 8) & 0x00FF)); - status = 0x00; - - /* set parity */ - - switch (Parity) { /* set parity value */ - case 'O': /* odd parity */ - case 'o': - status = 0x08; - break; - - case 'E': /* even parity */ - case 'e': - status = 0x18; - break; - - case 'S': /* stick parity */ - case 's': - status = 0x28; - break; - - case 'N': /* no parity */ - case 'n': - default: - status = 0x00; - } - - /* set number data bits */ - - switch (Databits) { - case '5': - break; - - case '6': - status = status | 0x01; - break; - - case '7': - status = status | 0x02; - break; - - case '8': - default: - status = status | 0x03; - } - - /* set number stop bits */ - - switch (Stopbits) { - case '2': - status = status | 0x04; - break; - - case '1': - default: - ; - } - outp(ComBase + LINE_CNTRL, (unsigned char) status); - status = OUT2 | DTR; /* DTR/OUT2 must be set! */ - outp(ComBase + MODEM_CNTRL, (unsigned char) status); - - /* enable serial interrupts */ - - outp(ComBase + INT_EN, RX_INT | ERR_INT | RS_INT); - return; -} - -void DropDtr( - void) -{ - int status; - - status = inp(ComBase + MODEM_CNTRL); - status &= 0xFE; /* turn off DTR bit */ - outp(ComBase + MODEM_CNTRL, (unsigned char) status); - return; -} - -void RaiseDtr( - void) -{ - int status; - - status = inp(ComBase + MODEM_CNTRL); - status |= 0x01; /* turn on DTR bit */ - outp(ComBase + MODEM_CNTRL, (unsigned char) status); - return; -} - -int ComRecChar( - void) -{ - return de_queue(Serial_In_Queue); -} - -int ComSendString( - char *string) -{ - int retval; - char *pointer; - pointer = string; - - while (*pointer) { - retval = en_queue(Serial_Out_Queue, *pointer); - pointer++; - } - if (0x0 == (comm_status.modem & 0x40)) - RaiseDtr(); - outp(ComBase + INT_EN, RX_INT | TBE_INT | ERR_INT | RS_INT); - return retval; -} - -int ComSendData( - char *buffer, - unsigned buffer_length) -{ - int retval; - char *pointer; - pointer = buffer; - unsigned i; - - for (i = 0; i < buffer_length; i++) { - retval = en_queue(Serial_Out_Queue, *pointer); - pointer++; - } - if (0x0 == (comm_status.modem & 0x40)) - RaiseDtr(); - outp(ComBase + INT_EN, RX_INT | TBE_INT | ERR_INT | RS_INT); - return retval; -} - -int ComSendChar( - char character) -{ - int retval; - - /* interrupt driven send */ - - if (0x0 == (comm_status.modem & 0x40)) - RaiseDtr(); - retval = en_queue(Serial_Out_Queue, character); - if (-1 != retval) - outp(ComBase + INT_EN, RX_INT | TBE_INT | ERR_INT | RS_INT); - return retval; -} - -int ComStatus( - void) -{ - unsigned status; - unsigned retval; - - retval = inp(ComBase + LINE_STATUS); - retval = retval << 8; - status = inp(ComBase + MODEM_STATUS); - retval = retval | status; - if (queue_empty(Serial_In_Queue)) - retval &= 0xFEFF; - else - retval |= 0x0100; - return (int) retval; -} - -void INTERRUPT FAR serial( - void) -{ /* interrupt handler */ - int temp; - - disable(); - while (1) { - comm_status.intrupt = inp(ComBase + INT_ID); - comm_status.intrupt &= 0x0f; - switch (comm_status.intrupt) { - case 0x00: /* modem interrupt */ - comm_status.modem = inp(ComBase + MODEM_STATUS); - break; - - case 0x02: /* xmit interrupt */ - if (queue_empty(Serial_Out_Queue)) - outp(ComBase + INT_EN, RX_INT | ERR_INT | RS_INT); - else { - temp = de_queue(Serial_Out_Queue); - if (-1 != temp) - outp(ComBase + XMIT, temp); - } - break; - - case 0x04: /* receive interrupt */ - en_queue(Serial_In_Queue, (char) inp(ComBase + REC)); - break; - - case 0x06: /* line interrupt */ - comm_status.line = inp(ComBase + LINE_STATUS); - (void) inp(ComBase + REC); - en_queue(Serial_In_Queue, '!'); - break; - - default: /* No Mo` Left */ - comm_status.modem = inp(ComBase + MODEM_STATUS); - outp(0x20, 0x20); - enable(); - return; - } /* switch */ - } /* while */ -} - -/* End of Serial.C */ diff --git a/ports/dos/serial.h b/ports/dos/serial.h deleted file mode 100644 index cf5f1729..00000000 --- a/ports/dos/serial.h +++ /dev/null @@ -1,124 +0,0 @@ -/* -+----------------------------------------------------+ -| Thunderbird Software | -+----------------------------------------------------+ -| Filespec : Serial.c | -| Date : October 24, 1991 | -| Time : 15:03 | -| Revision : 1.1 | -| Update : August 29, 1994 | -| Update : March 12, 1995 by Bob Stout | -+----------------------------------------------------+ -| Programmer: Scott Andrews | -| Address : 5358 Summit RD SW | -| City/State: Pataskala, Ohio | -| Zip : 43062 | -+----------------------------------------------------+ -| Released to the Public Domain | -+----------------------------------------------------+ -*/ - -#ifndef SERIAL__H -#define SERIAL__H - -#include "extkword.h" -#include "pchwio.h" - -#define SerInBufSize 4096 /* Size of input buffer */ -#define SerOutBufSize 512 /* Size of output buffer */ - -/* 8250 registers */ - -#define REC 0 /* Uart receive reg. */ -#define XMIT 0 /* Uart transmit reg. */ -#define INT_EN 1 /* Uart int. enable reg. */ -#define INT_ID 2 /* Uart int. ident. reg. */ -#define LINE_CNTRL 3 /* Uart line control reg. */ -#define MODEM_CNTRL 4 /* Uart modem control reg. */ -#define LINE_STATUS 5 /* Uart line status reg. */ -#define MODEM_STATUS 6 /* Uart modem status reg. */ -#define BAUD_LSB 0 /* Uart baud divisor reg. */ -#define BAUD_MSB 1 /* Uart baud divisor reg. */ - -#define NONE 0 /* Handshake param none */ -#define HDW 1 /* Handshake param hardware */ -#define XON 2 /* Handshake param software */ - -/* Interrupt enable register */ - -#define RX_INT 0x01 /* Receive interrupt mask */ -#define TBE_INT 0x02 /* Transmit buffer empty mask */ -#define ERR_INT 0x04 /* Error interrupt mask */ -#define RS_INT 0x08 /* Line interrupt mask */ - -/* Interrupt id register */ - -#define OUT2 0x08 /* Out 2 line */ -#define DTR 0x01 /* DTR high */ -#define RTS 0x02 /* RTS high */ -#define CTS 0x10 -#define DSR 0x20 -#define XMTRDY 0x20 -#define TXR 0 /* Transmit register (WRITE) */ - -#if !defined TRUE /* Define boolean true/false */ -#define FALSE 0 -#define TRUE !FALSE -#endif - -extern void ( - INTERRUPT FAR * oldvector_serial) ( - void); - -extern int ComBase; /* Comm port address */ -extern int IrqNum; /* Comm interrupt request */ - -typedef struct { /* Save existing comm params */ - int int_enable; /* old interrupt enable reg value */ - int line; /* " line control " " */ - int modem; /* old modem control " " */ - int baud_lsb; /* old baud rate divisor LSD */ - int baud_msb; /* " " " " MSD */ - int int_cntrl; /* old PIC interrupt reg value */ -} OLD_COMM_PARAMS; -extern OLD_COMM_PARAMS old_comm_params; - -typedef struct { - int line; /* Uart line status reg. */ - int modem; /* Uart mode status reg. */ - int intrupt; /* Uart interrupt reg. */ - int handshake; /* Handshake status */ -} COMM_STATUS; /* status, updated, handler */ -extern COMM_STATUS comm_status; - -int OpenComPort( - char Port); /*setup comm for usage */ -void InitComPort( - char Baud[], - char Databits, - char Parity, - char Stop); -void CloseComPort( - void); /* Restore comm port */ -void DropDtr( - void); /* Lower DTR */ -void RaiseDtr( - void); /* Raise DTR */ -int ComRecChar( - void); /* Fetch character from rcv buf */ - -int ComSendChar( - char character); /* Put char into xmit buffer */ -int ComSendString( - char *string); -int ComSendData( - char *buffer, - unsigned buffer_length); -int ComStatus( - void); /* Fetch comm status */ -void INTERRUPT FAR serial( - void); /* interrupt handler */ - -/* End of Serial.H */ - -#endif /* SERIAL__H */ diff --git a/ports/dos/stdbool.h b/ports/dos/stdbool.h deleted file mode 100644 index badcfd0a..00000000 --- a/ports/dos/stdbool.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef _STDBOOL_H -#define _STDBOOL_H - -/* C99 Boolean types for compilers without C99 support */ -/* http://www.opengroup.org/onlinepubs/009695399/basedefs/stdbool.h.html */ -#if !defined(__cplusplus) - -#if !defined(__GNUC__) -/* _Bool builtin type is included in GCC */ -typedef enum { _Bool_must_promote_to_int = -1, false = 0, true = 1 } _Bool; -#endif - -#define bool _Bool -#define true 1 -#define false 0 -#define __bool_true_false_are_defined 1 - -#endif - -#endif diff --git a/ports/dos/stdint.h b/ports/dos/stdint.h deleted file mode 100644 index 75d50dcd..00000000 --- a/ports/dos/stdint.h +++ /dev/null @@ -1,31 +0,0 @@ -/* Defines the standard integer types that are used in code */ -/* for the x86 processor and Borland Compiler */ - -#ifndef _STDINT_H -#define _STDINT_H - -#include - -typedef unsigned char uint8_t; /* 1 byte 0 to 255 */ -typedef signed char int8_t; /* 1 byte -127 to 127 */ -typedef unsigned short uint16_t; /* 2 bytes 0 to 65535 */ -typedef signed short int16_t; /* 2 bytes -32767 to 32767 */ -/*typedef unsigned short long uint24_t; // 3 bytes 0 to 16777215 */ -typedef unsigned long uint32_t; /* 4 bytes 0 to 4294967295 */ -typedef signed long int32_t; /* 4 bytes -2147483647 to 2147483647 */ -/* typedef signed long long int64_t; */ -/* typedef unsigned long long uint64_t; */ - -#define INT8_MIN (-128) -#define INT16_MIN (-32768) -#define INT32_MIN (-2147483647 - 1) - -#define INT8_MAX 127 -#define INT16_MAX 32767 -#define INT32_MAX 2147483647 - -#define UINT8_MAX 0xff /* 255U */ -#define UINT16_MAX 0xffff /* 65535U */ -#define UINT32_MAX 0xffffffff /* 4294967295U */ - -#endif /* STDINT_H */ diff --git a/ports/dos/timer.c b/ports/dos/timer.c deleted file mode 100644 index f92bb2a8..00000000 --- a/ports/dos/timer.c +++ /dev/null @@ -1,201 +0,0 @@ -/************************************************************************** -* -* Copyright (C) 2007 Steve Karg -* -* Permission is hereby granted, free of charge, to any person obtaining -* a copy of this software and associated documentation files (the -* "Software"), to deal in the Software without restriction, including -* without limitation the rights to use, copy, modify, merge, publish, -* distribute, sublicense, and/or sell copies of the Software, and to -* permit persons to whom the Software is furnished to do so, subject to -* the following conditions: -* -* The above copyright notice and this permission notice shall be included -* in all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -* -*********************************************************************/ -#include -#include -#include - -/* global variable counts milliseconds */ -volatile unsigned long Timer_Milliseconds; -/* MS/TP Silence Timer */ -static volatile int SilenceTime; -/* counts ticks */ -volatile unsigned long Timer_Milliseconds; - -#define RTC_CMD_ADDR 0x70 /* RTC internal register offset goes here */ -#define RTC_DAT_ADDR 0x71 /* RTC internal register R/W access here */ - -static uint8_t RTC_RS_Convert( - uint16_t hertz) -{ - uint8_t RS = 0; - /* from DS12887A datasheet - SELECT BITS tPI PERIODIC - REGISTER A INTERRUPT SQW OUTPUT - RS3 RS2 RS1 RS0 RATE FREQUENCY - --- --- --- --- ------------ ---------- - 0 0 0 0 None 0Hz - 0 0 0 1 3.90625ms 256Hz - 0 0 1 0 7.8125ms 128Hz - 0 0 1 1 122.070µs 8192Hz - 0 1 0 0 244.141µs 4096Hz - 0 1 0 1 488.281µs 2048Hz - 0 1 1 0 976.5625µs 1024Hz - 0 1 1 1 1.953125ms 512Hz - 1 0 0 0 3.90625ms 256Hz - 1 0 0 1 7.8125ms 128Hz - 1 0 1 0 15.625ms 64Hz - 1 0 1 1 31.25ms 32Hz - 1 1 0 0 62.5ms 16Hz - 1 1 0 1 125ms 8Hz - 1 1 1 0 250ms 4Hz - 1 1 1 1 500ms 2Hz - */ - /* FIXME: create a clever formula to replace switch */ - switch (hertz) { - case 8192: - RS = 3; - break; - case 4096: - RS = 4; - break; - case 2048: - RS = 5; - break; - case 1024: - RS = 6; - break; - case 512: - RS = 7; - break; - case 256: - RS = 8; - break; - case 128: - RS = 9; - break; - case 64: - RS = 10; - break; - case 32: - RS = 11; - break; - case 16: - RS = 12; - break; - case 8: - RS = 13; - break; - case 4: - RS = 14; - break; - case 2: - RS = 15; - break; - default: - break; - } - - return RS; -} - -/* setting for 8192 interrupts per second - which is an interrupt every 122uS. */ -#define INT_FREQ 8192 - -static void interrupt Timer_Interrupt_Handler( - void) -{ - static uint16_t Timer_Ticks = 0; - static uint16_t Elapsed_Milliseconds = 0; - uint16_t milliseconds = 0; - uint16_t diff = 0; - uint8_t temp_reg; - - Timer_Ticks++; - milliseconds = (Timer_Ticks * 1000) / INT_FREQ; - diff = milliseconds - Elapsed_Milliseconds; - if (diff >= 1) { - Elapsed_Milliseconds = milliseconds; - Timer_Milliseconds++; - if (SilenceTime < 60000) - SilenceTime++; - } - /* max resolution */ - if (Timer_Ticks >= INT_FREQ) { - Timer_Ticks = 0; - Elapsed_Milliseconds = 0; - } - - /* clear interrupt */ - outportb(RTC_CMD_ADDR, 0x0C); /* select RTC register C */ - temp_reg = inportb(RTC_DAT_ADDR); /* read RTC register C */ - /* signal end of interrupt to slave PIC */ - outportb(0xA0, 0x20); - /* signal end of interrupt to master PIC */ - outportb(0x20, 0x20); -} - -/* previous interrrupt vector */ -static void interrupt( - *OldVector) ( - ); - -void Timer_Cleanup( - void) -{ - setvect(0x70, OldVector); -} - -void Timer_Init( - void) -{ - uint8_t RC = RTC_RS_Convert(INT_FREQ); - - /* get old interrupt vector to re-install on exit */ - OldVector = getvect(0x70); - /* disable interrupts */ - disable(); - /* set RTC int. vector for our routine */ - setvect(0x70, Timer_Interrupt_Handler); - /* set register B with PIE enabled */ - outportb(RTC_CMD_ADDR, 0x0B); - outportb(RTC_DAT_ADDR, 0x42); - /* set register A to our frequency */ - outportb(RTC_CMD_ADDR, 0x0A); - outportb(RTC_DAT_ADDR, (0x20 | (RC & 0x0F))); - /* re-enable system interrupts */ - enable(); - atexit(Timer_Cleanup); -} - -int Timer_Silence( - void) -{ - uint16_t time_value; - - disable(); - time_value = SilenceTime; - enable(); - - return time_value; -} - -void Timer_Silence_Reset( - void) -{ - disable(); - SilenceTime = 0; - enable(); -} diff --git a/ports/esp32/lib/readme.txt b/ports/esp32/lib/readme.txt index 9c196e28..dbadc3d6 100644 --- a/ports/esp32/lib/readme.txt +++ b/ports/esp32/lib/readme.txt @@ -1,36 +1,36 @@ - -This directory is intended for the project specific (private) libraries. -PlatformIO will compile them to static libraries and link to executable file. - -The source code of each library should be placed in separate directory, like -"lib/private_lib/[here are source files]". - -For example, see how can be organized `Foo` and `Bar` libraries: - -|--lib -| |--Bar -| | |--docs -| | |--examples -| | |--src -| | |- Bar.c -| | |- Bar.h -| |--Foo -| | |- Foo.c -| | |- Foo.h -| |- readme.txt --> THIS FILE -|- platformio.ini -|--src - |- main.c - -Then in `src/main.c` you should use: - -#include -#include - -// rest H/C/CPP code - -PlatformIO will find your libraries automatically, configure preprocessor's -include paths and build them. - -More information about PlatformIO Library Dependency Finder -- http://docs.platformio.org/page/librarymanager/ldf.html + +This directory is intended for the project specific (private) libraries. +PlatformIO will compile them to static libraries and link to executable file. + +The source code of each library should be placed in separate directory, like +"lib/private_lib/[here are source files]". + +For example, see how can be organized `Foo` and `Bar` libraries: + +|--lib +| |--Bar +| | |--docs +| | |--examples +| | |--src +| | |- Bar.c +| | |- Bar.h +| |--Foo +| | |- Foo.c +| | |- Foo.h +| |- readme.txt --> THIS FILE +|- platformio.ini +|--src + |- main.c + +Then in `src/main.c` you should use: + +#include +#include + +// rest H/C/CPP code + +PlatformIO will find your libraries automatically, configure preprocessor's +include paths and build them. + +More information about PlatformIO Library Dependency Finder +- http://docs.platformio.org/page/librarymanager/ldf.html diff --git a/ports/esp32/readme.txt b/ports/esp32/readme.txt index 3023acba..05ba58cb 100644 --- a/ports/esp32/readme.txt +++ b/ports/esp32/readme.txt @@ -1,66 +1,66 @@ -Bacnet Server for Espressif ESP32 - Steve Karg Bacnet stack using PlatformIO open source ecosystem for IoT development on VSCode or Atom - F. Chaxel 2017 - -TODO list : - -(Install VSCode or Atom and add the PlatformIO extension) - -Edit platformio.ini to adjust board, Com Port, ... - -Goto lib/stack and copy the requested files from Steve code : - - all .h from include directory (not all required by it's simple) - - these .c files from src or demo/handlers - abort.c - address.c - apdu.c - bacaddr.c - bacapp.c - bacdcode.c - bacerror.c - bacint.c - bacreal.c - bacstr.c - bip.c - bvlc.c - cov.c - datetime.c - bacdevobjpropref.c - dcc.c - debug.c - h_cov.c - h_ucov.c - h_npdu.c - h_rp.c - h_rpm.c - h_whois.c - h_wp.c - iam.c - lighting.c - memcopy.c - noserv.c - npdu.c - proplist.c - reject.c - rp.c - rpm.c - s_iam.c - tsm.c - whois.c - wp.c - -Modify - in config.h - MAX_TSM_TRANSACTIONS 255, set the value to 10 for instances - in main.c - wifi_config to fit your wifi network - BACNET_LED 5, set another IO number depending of your board - -A lot of Warning will be issued at compile time due to the redefinition of BIT macros. -Could be removes by placing a #ifndef #BIT0 .. #endif arround the BIT macro in bits.h, -and moving to the top of include list - #include "datalink.h" in tsm.c, s_iam and in device.c - #include "net.h" in bip.c and in bip.h (redondant include in bip.c) - #include "bvlc.h" in bvlc.c \ No newline at end of file +Bacnet Server for Espressif ESP32 + Steve Karg Bacnet stack using PlatformIO open source ecosystem for IoT development on VSCode or Atom + F. Chaxel 2017 + +TODO list : + +(Install VSCode or Atom and add the PlatformIO extension) + +Edit platformio.ini to adjust board, Com Port, ... + +Goto lib/stack and copy the requested files from Steve code : + + all .h from include directory (not all required by it's simple) + + these .c files from src or demo/handlers + abort.c + address.c + apdu.c + bacaddr.c + bacapp.c + bacdcode.c + bacerror.c + bacint.c + bacreal.c + bacstr.c + bip.c + bvlc.c + cov.c + datetime.c + bacdevobjpropref.c + dcc.c + debug.c + h_cov.c + h_ucov.c + h_npdu.c + h_rp.c + h_rpm.c + h_whois.c + h_wp.c + iam.c + lighting.c + memcopy.c + noserv.c + npdu.c + proplist.c + reject.c + rp.c + rpm.c + s_iam.c + tsm.c + whois.c + wp.c + +Modify + in config.h + MAX_TSM_TRANSACTIONS 255, set the value to 10 for instances + in main.c + wifi_config to fit your wifi network + BACNET_LED 5, set another IO number depending of your board + +A lot of Warning will be issued at compile time due to the redefinition of BIT macros. +Could be removes by placing a #ifndef #BIT0 .. #endif arround the BIT macro in bits.h, +and moving to the top of include list + #include "bacnet/datalink/datalink.h" in tsm.c, s_iam and in device.c + #include "bacport.h" in bip.c and in bip.h (redondant include in bip.c) + #include "bacnet/datalink/bvlc.h" in bvlc.c \ No newline at end of file diff --git a/ports/esp32/src/ai.c b/ports/esp32/src/ai.c index b861831e..f18fbdd2 100644 --- a/ports/esp32/src/ai.c +++ b/ports/esp32/src/ai.c @@ -30,16 +30,16 @@ #include #include -#include "bacdef.h" -#include "bacdcode.h" -#include "bacenum.h" -#include "bactext.h" -#include "config.h" /* the custom stuff */ -#include "device.h" -#include "handlers.h" -#include "proplist.h" -#include "timestamp.h" -#include "ai.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacenum.h" +#include "bacnet/bactext.h" +#include "bacnet/config.h" /* the custom stuff */ +#include "bacnet/basic/object/device.h" +#include "bacnet/basic/services.h" +#include "bacnet/proplist.h" +#include "bacnet/timestamp.h" +#include "bacnet/basic/object/ai.h" #ifndef MAX_ANALOG_INPUTS diff --git a/ports/esp32/src/ai.h b/ports/esp32/src/ai.h index 1ed75c92..511312d8 100644 --- a/ports/esp32/src/ai.h +++ b/ports/esp32/src/ai.h @@ -28,14 +28,14 @@ #include #include -#include "bacdef.h" -#include "rp.h" -#include "wp.h" +#include "bacnet/bacdef.h" +#include "bacnet/rp.h" +#include "bacnet/wp.h" #if defined(INTRINSIC_REPORTING) -#include "nc.h" -#include "getevent.h" -#include "alarm_ack.h" -#include "get_alarm_sum.h" +#include "bacnet/basic/object/nc.h" +#include "bacnet/getevent.h" +#include "bacnet/alarm_ack.h" +#include "bacnet/get_alarm_sum.h" #endif #ifdef __cplusplus diff --git a/ports/esp32/src/bip_init.c b/ports/esp32/src/bip_init.c index dda1765b..76e2ed25 100644 --- a/ports/esp32/src/bip_init.c +++ b/ports/esp32/src/bip_init.c @@ -8,7 +8,7 @@ #include "lwip/sockets.h" #include "lwip/netdb.h" -#include "bip.h" +#include "bacnet/datalink/bip.h" long bip_getaddrbyname( const char *host_name) diff --git a/ports/esp32/src/bo.c b/ports/esp32/src/bo.c index 60f3b029..94de931f 100644 --- a/ports/esp32/src/bo.c +++ b/ports/esp32/src/bo.c @@ -28,15 +28,15 @@ #include #include #include -#include "bacdef.h" -#include "bacdcode.h" -#include "bacenum.h" -#include "bacapp.h" -#include "config.h" /* the custom stuff */ -#include "rp.h" -#include "wp.h" -#include "bo.h" -#include "handlers.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacenum.h" +#include "bacnet/bacapp.h" +#include "bacnet/config.h" /* the custom stuff */ +#include "bacnet/rp.h" +#include "bacnet/wp.h" +#include "bacnet/basic/object/bo.h" +#include "bacnet/basic/services.h" #ifndef MAX_BINARY_OUTPUTS #define MAX_BINARY_OUTPUTS 1 diff --git a/ports/esp32/src/bo.h b/ports/esp32/src/bo.h index 3b0cf2e9..6b9b58c0 100644 --- a/ports/esp32/src/bo.h +++ b/ports/esp32/src/bo.h @@ -27,10 +27,10 @@ #include #include -#include "bacdef.h" -#include "bacerror.h" -#include "rp.h" -#include "wp.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacerror.h" +#include "bacnet/rp.h" +#include "bacnet/wp.h" #ifdef __cplusplus extern "C" { diff --git a/ports/esp32/src/device.c b/ports/esp32/src/device.c index 0bdca207..53062b1c 100644 --- a/ports/esp32/src/device.c +++ b/ports/esp32/src/device.c @@ -30,35 +30,35 @@ #include #include /* for memmove */ #include /* for timezone, localtime */ -#include "datalink.h" -#include "bacdef.h" -#include "bacdcode.h" -#include "bacenum.h" -#include "bacapp.h" -#include "config.h" /* the custom stuff */ -#include "apdu.h" -#include "wp.h" /* WriteProperty handling */ -#include "rp.h" /* ReadProperty handling */ -#include "dcc.h" /* DeviceCommunicationControl handling */ -#include "version.h" -#include "device.h" /* me */ -#include "handlers.h" +#include "bacnet/datalink/datalink.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacenum.h" +#include "bacnet/bacapp.h" +#include "bacnet/config.h" /* the custom stuff */ +#include "bacnet/apdu.h" +#include "bacnet/wp.h" /* WriteProperty handling */ +#include "bacnet/rp.h" /* ReadProperty handling */ +#include "bacnet/dcc.h" /* DeviceCommunicationControl handling */ +#include "bacnet/version.h" +#include "bacnet/basic/object/device.h" /* me */ +#include "bacnet/basic/services.h" #include "../lib/stack/address.h" /* os specfic includes */ -#include "timer.h" +#include "bacnet/basic/sys/mstimer.h" /* include the device object */ -#include "device.h" -#include "ai.h" -#include "bo.h" +#include "bacnet/basic/object/device.h" +#include "bacnet/basic/object/ai.h" +#include "bacnet/basic/object/bo.h" #if defined(INTRINSIC_REPORTING) -#include "nc.h" +#include "bacnet/basic/object/nc.h" #endif /* defined(INTRINSIC_REPORTING) */ #if defined(BACFILE) -#include "bacfile.h" +#include "bacnet/basic/object/bacfile.h" #endif /* defined(BACFILE) */ #if defined(BAC_UCI) -#include "ucix.h" +#include "bacnet/basic/ucix/ucix.h" #endif /* defined(BAC_UCI) */ diff --git a/ports/esp32/src/device.h b/ports/esp32/src/device.h index 77dbaab7..714a89c0 100644 --- a/ports/esp32/src/device.h +++ b/ports/esp32/src/device.h @@ -31,13 +31,13 @@ #include #include -#include "bacdef.h" -#include "bacenum.h" -#include "wp.h" -#include "rd.h" -#include "rp.h" -#include "rpm.h" -#include "readrange.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacenum.h" +#include "bacnet/wp.h" +#include "bacnet/rd.h" +#include "bacnet/rp.h" +#include "bacnet/rpm.h" +#include "bacnet/readrange.h" /** Called so a BACnet object can perform any necessary initialization. * @ingroup ObjHelpers diff --git a/ports/esp32/src/main.c b/ports/esp32/src/main.c index 4909234c..e8c6fbc4 100644 --- a/ports/esp32/src/main.c +++ b/ports/esp32/src/main.c @@ -2,21 +2,21 @@ // Copyleft F.Chaxel 2017 // -#include "config.h" -#include "txbuf.h" -#include "client.h" +#include "bacnet/config.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/basic/services.h" -#include "handlers.h" -#include "datalink.h" -#include "dcc.h" -#include "tsm.h" +#include "bacnet/basic/services.h" +#include "bacnet/datalink/datalink.h" +#include "bacnet/dcc.h" +#include "bacnet/basic/tsm/tsm.h" // conflict filename address.h with another file in default include paths #include "../lib/stack/address.h" -#include "bip.h" +#include "bacnet/datalink/bip.h" -#include "device.h" -#include "ai.h" -#include "bo.h" +#include "bacnet/basic/object/device.h" +#include "bacnet/basic/object/ai.h" +#include "bacnet/basic/object/bo.h" #include "esp_log.h" #include "esp_wifi.h" diff --git a/ports/linux/arcnet.c b/ports/linux/arcnet.c index 324dce31..f56ae9dd 100644 --- a/ports/linux/arcnet.c +++ b/ports/linux/arcnet.c @@ -33,10 +33,10 @@ ####COPYRIGHTEND####*/ #include -#include "bacdef.h" -#include "npdu.h" -#include "arcnet.h" -#include "net.h" +#include "bacnet/bacdef.h" +#include "bacnet/npdu.h" +#include "bacnet/datalink/arcnet.h" +#include "bacport.h" /** @file linux/arcnet.c Provides Linux-specific functions for Arcnet. */ diff --git a/ports/linux/bacnet_ipv6.lua b/ports/linux/bacnet_ipv6.lua index 30d93e97..26561c52 100644 --- a/ports/linux/bacnet_ipv6.lua +++ b/ports/linux/bacnet_ipv6.lua @@ -1,281 +1,281 @@ --- bacnet_BIPV6.lua --- --- Dissector for BACnet/IPv6 [135-2016 Annex X] --- --- Copyright 2011, Siemens Building Technolgies --- Maintainer Philippe Goetz --- Updated by Steve Karg --- --- This program is free software; you can redistribute it and/or --- modify it under the terms of the GNU General Public License --- as published by the Free Software Foundation; either version 2 --- of the License, or (at your option) any later version. --- --- This program 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 General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program; if not, write to the Free Software --- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - - --- Add the following to the end of init.lua in the Wireshark install directory: --- dofile("bacnet_ipv6.lua") - - --- [in] tree,pf,buffer,offset,len --- [out] offset, value, ti, bf -function uint_dissector(tree,pf,buffer,offset,len) - if (offset + len) <= buffer:len() then - local bf = buffer(offset,len) - local ti = nil - if tree ~= nil then - ti = tree:add(pf,bf) - end - return offset + len, bf:uint(), ti, bf - end - local ti = tree:add(pf,buffer(offset)) - ti:add_expert_info(PI_MALFORMED, PI_ERROR, "Data shortage") - error("Data shortage") -end - -function bytes_dissector(tree,pf,buffer,offset,len) - if (offset + len) <= buffer:len() then - local bf = buffer(offset,len) - local ti = nil - if tree ~= nil then - ti = tree:add(pf,bf) - end - return offset + len, bf:bytes(), ti, bf - end - local ti = tree:add(pf,buffer(offset)) - ti:add_expert_info(PI_MALFORMED, PI_ERROR, "Data shortage") - error("Data shortage") -end - -p_BACnetBIPV6 = Proto("lua_BACnetBIPV6", "B/IPv6 BACnet Virtual Link Control"); -p_BACnet_Port = Proto("BACnet-Port", "BACnet UDP Port Handoff") -p_dissector_bacnet = Dissector.get("bacnet") -p_dissector_bipv4 = Dissector.get("bvlc") - -do - p_BACnetBIPV6.init = function() - debug("p_BACnetBIPV6.init") - end - - local t_BACnetBIPV6_Types = { - [0x82]="B/IPv6 (Annex X)" - } - local t_BACnetBIPV6_Functions = { - -- Annex X, PPR3 Draft 22 - [0x00]="BVLC-Result", - [0x01]="Original-Unicast-NPDU", - [0x02]="Original-Broadcast-NPDU", - [0x03]="Address-Resolution", - [0x04]="Forwarded-Address-Resolution", - [0x05]="Address-Resolution-Ack", - [0x06]="Virtual-Address-Resolution", - [0x07]="Virtual-Address-Resolution-Ack", - [0x08]="Forwarded-NPDU", - [0x09]="Register-Foreign-Device", - [0x0A]="Delete-Foreign-Device", - [0x0B]="Secure-BVLL", - [0x0C]="Distribute-Broadcast-To-Network" - } - - local pf_BIPV6Data = ProtoField.bytes ("BIPV6.data", "B/IPV6 Data") - - p_BACnetBIPV6.fields = { - pf_BIPV6Data - } - - local t_BACnetBIPV6_dissectors = {} - - -- local dt_BIPV6_npdu = DissectorTable.new("lua_BACnetBIPV6.npdu","BIPV6 NPDU",ftypes.UINT8,base.HEX) - -- BIPV6 header fields - local pf_BIPV6 = {} - pf_BIPV6.Type = ProtoField.uint8 ("BIPV6.type","Type",base.HEX,t_BACnetBIPV6_Types) - table.insert(p_BACnetBIPV6.fields,pf_BIPV6.Type) - pf_BIPV6.Function = ProtoField.uint8 ("BIPV6.function","Function",base.HEX,t_BACnetBIPV6_Functions,0,"BIPV6 Function") - table.insert(p_BACnetBIPV6.fields,pf_BIPV6.Function) - pf_BIPV6.Length = ProtoField.uint16("BIPV6.length","BIPV6-Length",base.DEC,nil,0,"Length of BIPV6") - table.insert(p_BACnetBIPV6.fields,pf_BIPV6.Length) - pf_BIPV6.ResultCode = ProtoField.uint16("BIPV6.resultCode","Result-Code",base.DEC,nil,0,"Result Code") - table.insert(p_BACnetBIPV6.fields,pf_BIPV6.ResultCode) - pf_BIPV6.SourceVirtualAddress = ProtoField.uint24 ("BIPV6.sourceVirtualAddress","Source-Virtual-Address") - table.insert(p_BACnetBIPV6.fields,pf_BIPV6.SourceVirtualAddress) - pf_BIPV6.DestinationVirtualAddress = ProtoField.uint24 ("BIPV6.destinationVirtualAddress","Destination-Virtual-Address") - table.insert(p_BACnetBIPV6.fields,pf_BIPV6.DestinationVirtualAddress) - pf_BIPV6.OriginalSourceEffectiveAddress = ProtoField.bytes ("BIPV6.originalSourceEffectiveAddress","Original-Source-B/IPv6-Address") - table.insert(p_BACnetBIPV6.fields,pf_BIPV6.OriginalSourceEffectiveAddress) - pf_BIPV6.OriginalSourceEffectiveAddress_ip = ProtoField.ipv6 ("BIPV6.originalSourceEffectiveAddress.ip","Original-Source-B/IPv6-Address (ip)") - table.insert(p_BACnetBIPV6.fields,pf_BIPV6.OriginalSourceEffectiveAddress_ip) - pf_BIPV6.OriginalSourceEffectiveAddress_port = ProtoField.uint16 ("BIPV6.originalSourceEffectiveAddress.port","Original-Source-B/IPv6-Address (port)") - table.insert(p_BACnetBIPV6.fields,pf_BIPV6.OriginalSourceEffectiveAddress_port) - pf_BIPV6.OriginalSourceVirtualAddress = ProtoField.uint24 ("BIPV6.originalSourceVirtualAddress","Original-Source-Virtual-Address") - table.insert(p_BACnetBIPV6.fields,pf_BIPV6.OriginalSourceVirtualAddress) - pf_BIPV6.DestinationEffectiveAddress = ProtoField.bytes ("BIPV6.destinationEffectiveAddress","Original-Source-B/IPv6-Address") - table.insert(p_BACnetBIPV6.fields,pf_BIPV6.DestinationEffectiveAddress) - pf_BIPV6.DestinationEffectiveAddress_ip = ProtoField.ipv6 ("BIPV6.destinationEffectiveAddress.ip","Original-Source-B/IPv6-Address (ip)") - table.insert(p_BACnetBIPV6.fields,pf_BIPV6.DestinationEffectiveAddress_ip) - pf_BIPV6.DestinationEffectiveAddress_port = ProtoField.uint16 ("BIPV6.destinationEffectiveAddress.port","Original-Source-B/IPv6-Address (port)") - table.insert(p_BACnetBIPV6.fields,pf_BIPV6.DestinationEffectiveAddress_port) - pf_BIPV6.TimeToLive = ProtoField.uint16 ("BIPV6.timeToLive","Time-To-Live") - table.insert(p_BACnetBIPV6.fields,pf_BIPV6.TimeToLive) - - function p_BACnetBIPV6.dissector(buffer,pkt,tree) - - pkt.cols["protocol"] = "B/IPv6" - pkt.cols["info"] = "BACnet Building Automation and Control Network" - local offset = 0 - local v_BIPV6 = {} - local ti_BIPV6 = {} - ti_BIPV6.ti = tree:add(p_BACnetBIPV6,buffer(0)) - offset, v_BIPV6.Type, ti_BIPV6.Type = uint_dissector(ti_BIPV6.ti, pf_BIPV6.Type, buffer, offset, 1) - --if v_BIPV6.Type == 0x81 then - -- p_dissector_bipv4:call(buffer, pkt, tree) - -- elseif v_BIPV6 ~= 0x82 then - -- ti_BIPV6.Type:add_expert_info(PI_MALFORMED, PI_WARN, "Unknown BVLC Type") - -- return - --end - if v_BIPV6.Type ~= 0x82 then - ti_BIPV6.Type:add_expert_info(PI_MALFORMED, PI_WARN, "Unknown BVLC Type") - return - end - offset, v_BIPV6.Function, ti_BIPV6.Function = uint_dissector(ti_BIPV6.ti, pf_BIPV6.Function, buffer, offset, 1) - offset, v_BIPV6.Length, ti_BIPV6.Length = uint_dissector(ti_BIPV6.ti, pf_BIPV6.Length, buffer, offset, 2) - local BIPV6Dissector = t_BACnetBIPV6_dissectors[v_BIPV6.Function] - local npduData = nil - if BIPV6Dissector ~= nil then - pkt.cols["info"] = t_BACnetBIPV6_Functions[v_BIPV6.Function] - offset, npduData = BIPV6Dissector(buffer,pkt,ti_BIPV6.ti,offset,v_BIPV6,tree) - end - if npduData ~= nil then - if p_BACnetNPDU ~= nil then - ti_BIPV6.ti:set_len(offset) - p_BACnetNPDU.dissector:call(npduData:tvb(), pkt, tree) - offset = offset + npduData:len() - else - p_dissector_bacnet:call(npduData:tvb(), pkt, tree) - end - end - -- CLB don't show the raw data - -- if offset ~= buffer:len() then - -- ti_BIPV6.ti:add(pf_BIPV6Data,buffer(offset)) - -- end - ti_BIPV6 = nil - collectgarbage("collect") - end - - -- [0x00] BVLC-Result - t_BACnetBIPV6_dissectors[0x00] = function(buffer,pkt,tree,offset,npdu) - offset = bytes_dissector(tree,pf_BIPV6.SourceVirtualAddress,buffer,offset,3) - offset = bytes_dissector(tree,pf_BIPV6.ResultCode,buffer,offset,2) - return offset - end - - -- [0x01] Original-Unicast-NPDU - t_BACnetBIPV6_dissectors[0x01] = function(buffer,pkt,tree,offset,npdu) - offset = bytes_dissector(tree,pf_BIPV6.SourceVirtualAddress,buffer,offset,3) - offset = bytes_dissector(tree,pf_BIPV6.DestinationVirtualAddress,buffer,offset,3) - return offset, buffer(offset) - end - - -- [0x02] Original-Broadcast-NPDU - t_BACnetBIPV6_dissectors[0x02] = function(buffer,pkt,tree,offset,npdu) - offset = bytes_dissector(tree,pf_BIPV6.SourceVirtualAddress,buffer,offset,3) - return offset, buffer(offset) - end - - -- [0x03] Address-Resolution - t_BACnetBIPV6_dissectors[0x03] = function(buffer,pkt,tree,offset,npdu) - offset = bytes_dissector(tree,pf_BIPV6.SourceVirtualAddress,buffer,offset,3) - offset = bytes_dissector(tree,pf_BIPV6.DestinationVirtualAddress,buffer,offset,3) - return offset - end - - -- [0x04] Forwarded-Address-Resolution - t_BACnetBIPV6_dissectors[0x04] = function(buffer,pkt,tree,offset,npdu) - offset = bytes_dissector(tree,pf_BIPV6.OriginalSourceVirtualAddress,buffer,offset,3) - offset = bytes_dissector(tree,pf_BIPV6.DestinationVirtualAddress,buffer,offset,3) - local subtree = tree:add(pf_BIPV6.OriginalSourceEffectiveAddress,buffer(offset,18)) - offset = bytes_dissector(subtree,pf_BIPV6.OriginalSourceEffectiveAddress_ip,buffer,offset,16) - offset = uint_dissector(subtree,pf_BIPV6.OriginalSourceEffectiveAddress_port,buffer,offset,2) - return offset - end - - -- [0x05] Address-Resolution-Ack - t_BACnetBIPV6_dissectors[0x05] = function(buffer,pkt,tree,offset,npdu) - offset = bytes_dissector(tree,pf_BIPV6.SourceVirtualAddress,buffer,offset,3) - offset = bytes_dissector(tree,pf_BIPV6.DestinationVirtualAddress,buffer,offset,3) - return offset - end - - -- [0x06] Virtual-Address-Resolution - t_BACnetBIPV6_dissectors[0x06] = function(buffer,pkt,tree,offset,npdu) - offset = bytes_dissector(tree,pf_BIPV6.SourceVirtualAddress,buffer,offset,3) - return offset - end - - -- [0x07] Virtual-Address-Resolution-Ack - t_BACnetBIPV6_dissectors[0x07] = function(buffer,pkt,tree,offset,npdu) - offset = bytes_dissector(tree,pf_BIPV6.SourceVirtualAddress,buffer,offset,3) - return offset - end - - -- [0x08] Forwarded-NPDU - t_BACnetBIPV6_dissectors[0x08] = function(buffer,pkt,tree,offset,npdu) - offset = bytes_dissector(tree,pf_BIPV6.OriginalSourceVirtualAddress,buffer,offset,3) - local subtree = tree:add(pf_BIPV6.OriginalSourceEffectiveAddress,buffer(offset,18)) - offset = bytes_dissector(subtree,pf_BIPV6.OriginalSourceEffectiveAddress_ip,buffer,offset,16) - offset = uint_dissector(subtree,pf_BIPV6.OriginalSourceEffectiveAddress_port,buffer,offset,2) - return offset, buffer(offset) - end - - -- [0x09] Register-Foreign-Device - t_BACnetBIPV6_dissectors[0x09] = function(buffer,pkt,tree,offset,npdu) - offset = bytes_dissector(tree,pf_BIPV6.SourceVirtualAddress,buffer,offset,3) - offset = uint_dissector(tree,pf_BIPV6.TimeToLive,buffer,offset,2) - return offset - end - - -- [0x0A] Delete-Foreign-Device - t_BACnetBIPV6_dissectors[0x0A] = function(buffer,pkt,tree,offset,npdu) - offset = bytes_dissector(tree,pf_BIPV6.SourceVirtualAddress,buffer,offset,3) - -- FDT Entry decoding - return offset - end - - -- [0x0B] Secure-BVLL - t_BACnetBIPV6_dissectors[0x0B] = function(buffer,pkt,tree,offset,npdu) - return offset - end - - -- [0x0C] Distribute-Broadcast-To-Network - t_BACnetBIPV6_dissectors[0x0C] = function(buffer,pkt,tree,offset,npdu) - offset = bytes_dissector(tree,pf_BIPV6.OriginalSourceVirtualAddress,buffer,offset,3) - local subtree = tree:add(pf_BIPV6.OriginalSourceEffectiveAddress,buffer(offset,18)) - offset = bytes_dissector(subtree,pf_BIPV6.OriginalSourceEffectiveAddress_ip,buffer,offset,16) - offset = uint_dissector(subtree,pf_BIPV6.OriginalSourceEffectiveAddress_port,buffer,offset,2) - return offset, buffer(offset) - end - - function p_BACnet_Port.dissector(tvb, pinfo, tree) - local BIP_Type = tvb(0,1):uint() - if BIP_Type == 0x81 then - p_dissector_bipv4:call(tvb, pinfo, tree) - elseif BIP_Type == 0x82 then - p_BACnetBIPV6.dissector(tvb, pinfo, tree) - end - end - - -- load the udp.port table - local dt_udp_port = DissectorTable.get("udp.port") - -- p_dissector_bvlc = dt_udp_port:get_dissector(47808) - -- dt_udp_port:remove(47808, p_dissector_bvlc) - -- dt_udp_port:add(47808, p_BACnetBIPV6) - dt_udp_port:add(47808, p_BACnet_Port) - -end +-- bacnet_BIPV6.lua +-- +-- Dissector for BACnet/IPv6 [135-2016 Annex X] +-- +-- Copyright 2011, Siemens Building Technolgies +-- Maintainer Philippe Goetz +-- Updated by Steve Karg +-- +-- This program is free software; you can redistribute it and/or +-- modify it under the terms of the GNU General Public License +-- as published by the Free Software Foundation; either version 2 +-- of the License, or (at your option) any later version. +-- +-- This program 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 General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + +-- Add the following to the end of init.lua in the Wireshark install directory: +-- dofile("bacnet_ipv6.lua") + + +-- [in] tree,pf,buffer,offset,len +-- [out] offset, value, ti, bf +function uint_dissector(tree,pf,buffer,offset,len) + if (offset + len) <= buffer:len() then + local bf = buffer(offset,len) + local ti = nil + if tree ~= nil then + ti = tree:add(pf,bf) + end + return offset + len, bf:uint(), ti, bf + end + local ti = tree:add(pf,buffer(offset)) + ti:add_expert_info(PI_MALFORMED, PI_ERROR, "Data shortage") + error("Data shortage") +end + +function bytes_dissector(tree,pf,buffer,offset,len) + if (offset + len) <= buffer:len() then + local bf = buffer(offset,len) + local ti = nil + if tree ~= nil then + ti = tree:add(pf,bf) + end + return offset + len, bf:bytes(), ti, bf + end + local ti = tree:add(pf,buffer(offset)) + ti:add_expert_info(PI_MALFORMED, PI_ERROR, "Data shortage") + error("Data shortage") +end + +p_BACnetBIPV6 = Proto("lua_BACnetBIPV6", "B/IPv6 BACnet Virtual Link Control"); +p_BACnet_Port = Proto("BACnet-Port", "BACnet UDP Port Handoff") +p_dissector_bacnet = Dissector.get("bacnet") +p_dissector_bipv4 = Dissector.get("bvlc") + +do + p_BACnetBIPV6.init = function() + debug("p_BACnetBIPV6.init") + end + + local t_BACnetBIPV6_Types = { + [0x82]="B/IPv6 (Annex X)" + } + local t_BACnetBIPV6_Functions = { + -- Annex X, PPR3 Draft 22 + [0x00]="BVLC-Result", + [0x01]="Original-Unicast-NPDU", + [0x02]="Original-Broadcast-NPDU", + [0x03]="Address-Resolution", + [0x04]="Forwarded-Address-Resolution", + [0x05]="Address-Resolution-Ack", + [0x06]="Virtual-Address-Resolution", + [0x07]="Virtual-Address-Resolution-Ack", + [0x08]="Forwarded-NPDU", + [0x09]="Register-Foreign-Device", + [0x0A]="Delete-Foreign-Device", + [0x0B]="Secure-BVLL", + [0x0C]="Distribute-Broadcast-To-Network" + } + + local pf_BIPV6Data = ProtoField.bytes ("BIPV6.data", "B/IPV6 Data") + + p_BACnetBIPV6.fields = { + pf_BIPV6Data + } + + local t_BACnetBIPV6_dissectors = {} + + -- local dt_BIPV6_npdu = DissectorTable.new("lua_BACnetBIPV6.npdu","BIPV6 NPDU",ftypes.UINT8,base.HEX) + -- BIPV6 header fields + local pf_BIPV6 = {} + pf_BIPV6.Type = ProtoField.uint8 ("BIPV6.type","Type",base.HEX,t_BACnetBIPV6_Types) + table.insert(p_BACnetBIPV6.fields,pf_BIPV6.Type) + pf_BIPV6.Function = ProtoField.uint8 ("BIPV6.function","Function",base.HEX,t_BACnetBIPV6_Functions,0,"BIPV6 Function") + table.insert(p_BACnetBIPV6.fields,pf_BIPV6.Function) + pf_BIPV6.Length = ProtoField.uint16("BIPV6.length","BIPV6-Length",base.DEC,nil,0,"Length of BIPV6") + table.insert(p_BACnetBIPV6.fields,pf_BIPV6.Length) + pf_BIPV6.ResultCode = ProtoField.uint16("BIPV6.resultCode","Result-Code",base.DEC,nil,0,"Result Code") + table.insert(p_BACnetBIPV6.fields,pf_BIPV6.ResultCode) + pf_BIPV6.SourceVirtualAddress = ProtoField.uint24 ("BIPV6.sourceVirtualAddress","Source-Virtual-Address") + table.insert(p_BACnetBIPV6.fields,pf_BIPV6.SourceVirtualAddress) + pf_BIPV6.DestinationVirtualAddress = ProtoField.uint24 ("BIPV6.destinationVirtualAddress","Destination-Virtual-Address") + table.insert(p_BACnetBIPV6.fields,pf_BIPV6.DestinationVirtualAddress) + pf_BIPV6.OriginalSourceEffectiveAddress = ProtoField.bytes ("BIPV6.originalSourceEffectiveAddress","Original-Source-B/IPv6-Address") + table.insert(p_BACnetBIPV6.fields,pf_BIPV6.OriginalSourceEffectiveAddress) + pf_BIPV6.OriginalSourceEffectiveAddress_ip = ProtoField.ipv6 ("BIPV6.originalSourceEffectiveAddress.ip","Original-Source-B/IPv6-Address (ip)") + table.insert(p_BACnetBIPV6.fields,pf_BIPV6.OriginalSourceEffectiveAddress_ip) + pf_BIPV6.OriginalSourceEffectiveAddress_port = ProtoField.uint16 ("BIPV6.originalSourceEffectiveAddress.port","Original-Source-B/IPv6-Address (port)") + table.insert(p_BACnetBIPV6.fields,pf_BIPV6.OriginalSourceEffectiveAddress_port) + pf_BIPV6.OriginalSourceVirtualAddress = ProtoField.uint24 ("BIPV6.originalSourceVirtualAddress","Original-Source-Virtual-Address") + table.insert(p_BACnetBIPV6.fields,pf_BIPV6.OriginalSourceVirtualAddress) + pf_BIPV6.DestinationEffectiveAddress = ProtoField.bytes ("BIPV6.destinationEffectiveAddress","Original-Source-B/IPv6-Address") + table.insert(p_BACnetBIPV6.fields,pf_BIPV6.DestinationEffectiveAddress) + pf_BIPV6.DestinationEffectiveAddress_ip = ProtoField.ipv6 ("BIPV6.destinationEffectiveAddress.ip","Original-Source-B/IPv6-Address (ip)") + table.insert(p_BACnetBIPV6.fields,pf_BIPV6.DestinationEffectiveAddress_ip) + pf_BIPV6.DestinationEffectiveAddress_port = ProtoField.uint16 ("BIPV6.destinationEffectiveAddress.port","Original-Source-B/IPv6-Address (port)") + table.insert(p_BACnetBIPV6.fields,pf_BIPV6.DestinationEffectiveAddress_port) + pf_BIPV6.TimeToLive = ProtoField.uint16 ("BIPV6.timeToLive","Time-To-Live") + table.insert(p_BACnetBIPV6.fields,pf_BIPV6.TimeToLive) + + function p_BACnetBIPV6.dissector(buffer,pkt,tree) + + pkt.cols["protocol"] = "B/IPv6" + pkt.cols["info"] = "BACnet Building Automation and Control Network" + local offset = 0 + local v_BIPV6 = {} + local ti_BIPV6 = {} + ti_BIPV6.ti = tree:add(p_BACnetBIPV6,buffer(0)) + offset, v_BIPV6.Type, ti_BIPV6.Type = uint_dissector(ti_BIPV6.ti, pf_BIPV6.Type, buffer, offset, 1) + --if v_BIPV6.Type == 0x81 then + -- p_dissector_bipv4:call(buffer, pkt, tree) + -- elseif v_BIPV6 ~= 0x82 then + -- ti_BIPV6.Type:add_expert_info(PI_MALFORMED, PI_WARN, "Unknown BVLC Type") + -- return + --end + if v_BIPV6.Type ~= 0x82 then + ti_BIPV6.Type:add_expert_info(PI_MALFORMED, PI_WARN, "Unknown BVLC Type") + return + end + offset, v_BIPV6.Function, ti_BIPV6.Function = uint_dissector(ti_BIPV6.ti, pf_BIPV6.Function, buffer, offset, 1) + offset, v_BIPV6.Length, ti_BIPV6.Length = uint_dissector(ti_BIPV6.ti, pf_BIPV6.Length, buffer, offset, 2) + local BIPV6Dissector = t_BACnetBIPV6_dissectors[v_BIPV6.Function] + local npduData = nil + if BIPV6Dissector ~= nil then + pkt.cols["info"] = t_BACnetBIPV6_Functions[v_BIPV6.Function] + offset, npduData = BIPV6Dissector(buffer,pkt,ti_BIPV6.ti,offset,v_BIPV6,tree) + end + if npduData ~= nil then + if p_BACnetNPDU ~= nil then + ti_BIPV6.ti:set_len(offset) + p_BACnetNPDU.dissector:call(npduData:tvb(), pkt, tree) + offset = offset + npduData:len() + else + p_dissector_bacnet:call(npduData:tvb(), pkt, tree) + end + end + -- CLB don't show the raw data + -- if offset ~= buffer:len() then + -- ti_BIPV6.ti:add(pf_BIPV6Data,buffer(offset)) + -- end + ti_BIPV6 = nil + collectgarbage("collect") + end + + -- [0x00] BVLC-Result + t_BACnetBIPV6_dissectors[0x00] = function(buffer,pkt,tree,offset,npdu) + offset = bytes_dissector(tree,pf_BIPV6.SourceVirtualAddress,buffer,offset,3) + offset = bytes_dissector(tree,pf_BIPV6.ResultCode,buffer,offset,2) + return offset + end + + -- [0x01] Original-Unicast-NPDU + t_BACnetBIPV6_dissectors[0x01] = function(buffer,pkt,tree,offset,npdu) + offset = bytes_dissector(tree,pf_BIPV6.SourceVirtualAddress,buffer,offset,3) + offset = bytes_dissector(tree,pf_BIPV6.DestinationVirtualAddress,buffer,offset,3) + return offset, buffer(offset) + end + + -- [0x02] Original-Broadcast-NPDU + t_BACnetBIPV6_dissectors[0x02] = function(buffer,pkt,tree,offset,npdu) + offset = bytes_dissector(tree,pf_BIPV6.SourceVirtualAddress,buffer,offset,3) + return offset, buffer(offset) + end + + -- [0x03] Address-Resolution + t_BACnetBIPV6_dissectors[0x03] = function(buffer,pkt,tree,offset,npdu) + offset = bytes_dissector(tree,pf_BIPV6.SourceVirtualAddress,buffer,offset,3) + offset = bytes_dissector(tree,pf_BIPV6.DestinationVirtualAddress,buffer,offset,3) + return offset + end + + -- [0x04] Forwarded-Address-Resolution + t_BACnetBIPV6_dissectors[0x04] = function(buffer,pkt,tree,offset,npdu) + offset = bytes_dissector(tree,pf_BIPV6.OriginalSourceVirtualAddress,buffer,offset,3) + offset = bytes_dissector(tree,pf_BIPV6.DestinationVirtualAddress,buffer,offset,3) + local subtree = tree:add(pf_BIPV6.OriginalSourceEffectiveAddress,buffer(offset,18)) + offset = bytes_dissector(subtree,pf_BIPV6.OriginalSourceEffectiveAddress_ip,buffer,offset,16) + offset = uint_dissector(subtree,pf_BIPV6.OriginalSourceEffectiveAddress_port,buffer,offset,2) + return offset + end + + -- [0x05] Address-Resolution-Ack + t_BACnetBIPV6_dissectors[0x05] = function(buffer,pkt,tree,offset,npdu) + offset = bytes_dissector(tree,pf_BIPV6.SourceVirtualAddress,buffer,offset,3) + offset = bytes_dissector(tree,pf_BIPV6.DestinationVirtualAddress,buffer,offset,3) + return offset + end + + -- [0x06] Virtual-Address-Resolution + t_BACnetBIPV6_dissectors[0x06] = function(buffer,pkt,tree,offset,npdu) + offset = bytes_dissector(tree,pf_BIPV6.SourceVirtualAddress,buffer,offset,3) + return offset + end + + -- [0x07] Virtual-Address-Resolution-Ack + t_BACnetBIPV6_dissectors[0x07] = function(buffer,pkt,tree,offset,npdu) + offset = bytes_dissector(tree,pf_BIPV6.SourceVirtualAddress,buffer,offset,3) + return offset + end + + -- [0x08] Forwarded-NPDU + t_BACnetBIPV6_dissectors[0x08] = function(buffer,pkt,tree,offset,npdu) + offset = bytes_dissector(tree,pf_BIPV6.OriginalSourceVirtualAddress,buffer,offset,3) + local subtree = tree:add(pf_BIPV6.OriginalSourceEffectiveAddress,buffer(offset,18)) + offset = bytes_dissector(subtree,pf_BIPV6.OriginalSourceEffectiveAddress_ip,buffer,offset,16) + offset = uint_dissector(subtree,pf_BIPV6.OriginalSourceEffectiveAddress_port,buffer,offset,2) + return offset, buffer(offset) + end + + -- [0x09] Register-Foreign-Device + t_BACnetBIPV6_dissectors[0x09] = function(buffer,pkt,tree,offset,npdu) + offset = bytes_dissector(tree,pf_BIPV6.SourceVirtualAddress,buffer,offset,3) + offset = uint_dissector(tree,pf_BIPV6.TimeToLive,buffer,offset,2) + return offset + end + + -- [0x0A] Delete-Foreign-Device + t_BACnetBIPV6_dissectors[0x0A] = function(buffer,pkt,tree,offset,npdu) + offset = bytes_dissector(tree,pf_BIPV6.SourceVirtualAddress,buffer,offset,3) + -- FDT Entry decoding + return offset + end + + -- [0x0B] Secure-BVLL + t_BACnetBIPV6_dissectors[0x0B] = function(buffer,pkt,tree,offset,npdu) + return offset + end + + -- [0x0C] Distribute-Broadcast-To-Network + t_BACnetBIPV6_dissectors[0x0C] = function(buffer,pkt,tree,offset,npdu) + offset = bytes_dissector(tree,pf_BIPV6.OriginalSourceVirtualAddress,buffer,offset,3) + local subtree = tree:add(pf_BIPV6.OriginalSourceEffectiveAddress,buffer(offset,18)) + offset = bytes_dissector(subtree,pf_BIPV6.OriginalSourceEffectiveAddress_ip,buffer,offset,16) + offset = uint_dissector(subtree,pf_BIPV6.OriginalSourceEffectiveAddress_port,buffer,offset,2) + return offset, buffer(offset) + end + + function p_BACnet_Port.dissector(tvb, pinfo, tree) + local BIP_Type = tvb(0,1):uint() + if BIP_Type == 0x81 then + p_dissector_bipv4:call(tvb, pinfo, tree) + elseif BIP_Type == 0x82 then + p_BACnetBIPV6.dissector(tvb, pinfo, tree) + end + end + + -- load the udp.port table + local dt_udp_port = DissectorTable.get("udp.port") + -- p_dissector_bvlc = dt_udp_port:get_dissector(47808) + -- dt_udp_port:remove(47808, p_dissector_bvlc) + -- dt_udp_port:add(47808, p_BACnetBIPV6) + dt_udp_port:add(47808, p_BACnet_Port) + +end diff --git a/ports/linux/net.h b/ports/linux/bacport.h similarity index 100% rename from ports/linux/net.h rename to ports/linux/bacport.h diff --git a/ports/linux/bip-init.c b/ports/linux/bip-init.c index 193d2451..ac929cd0 100644 --- a/ports/linux/bip-init.c +++ b/ports/linux/bip-init.c @@ -34,9 +34,9 @@ #include /* for standard integer types uint8_t etc. */ #include /* for the standard bool type. */ -#include "bacdcode.h" -#include "bip.h" -#include "net.h" +#include "bacnet/bacdcode.h" +#include "bacnet/datalink/bip.h" +#include "bacport.h" /** @file linux/bip-init.c Initializes BACnet/IP interface (Linux). */ diff --git a/ports/linux/bip6.c b/ports/linux/bip6.c index 1f0e4d67..c70ab760 100644 --- a/ports/linux/bip6.c +++ b/ports/linux/bip6.c @@ -32,17 +32,18 @@ ------------------------------------------- ####COPYRIGHTEND####*/ +#include #include #include #include /* for standard integer types uint8_t etc. */ #include /* for the standard bool type. */ -#include "bacdcode.h" -#include "config.h" -#include "bip6.h" -#include "debug.h" -#include "device.h" -#include "net.h" -#include +#include "bacnet/bacdcode.h" +#include "bacnet/config.h" +#include "bacnet/datalink/bip6.h" +#include "bacnet/basic/sys/debug.h" +#include "bacnet/basic/object/device.h" +#include "bacnet/basic/bbmd6/h_bbmd6.h" +#include "bacport.h" static void debug_print_ipv6(const char *str, const struct in6_addr * addr) { debug_printf( "BIP6: %s %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x\n", diff --git a/ports/linux/datetime-init.c b/ports/linux/datetime-init.c new file mode 100644 index 00000000..65d7c4bd --- /dev/null +++ b/ports/linux/datetime-init.c @@ -0,0 +1,91 @@ +/** + * @file + * @author Steve Karg + * @date 2009 + * @brief System time library header file. + * + * @section DESCRIPTION + * + * This library provides functions for getting and setting the system time. + */ +#include +#include +#include +#include +#include +#include +#include +#include "bacport.h" +#include "bacnet/datetime.h" + +/** + * @brief Get the date, time, timezone, and UTC offset from system + * @param utc_time - the BACnet Date and Time structure to hold UTC time + * @param local_time - the BACnet Date and Time structure to hold local time + * @param utc_offset_minutes - number of minutes offset from UTC + * For example, -6*60 represents 6.00 hours behind UTC/GMT + * @param true if DST is enabled and active + * @return true if local time was retrieved + */ +bool datetime_local( + BACNET_DATE * bdate, + BACNET_TIME * btime, + int16_t * utc_offset_minutes, + bool * dst_active) +{ + bool status = false; + struct tm *tblock = NULL; + struct timeval tv; + + if (gettimeofday(&tv, NULL) == 0) { + tblock = (struct tm *)localtime((const time_t *)&tv.tv_sec); + } + if (tblock) { + status = true; + /** struct tm + * int tm_sec Seconds [0,60]. + * int tm_min Minutes [0,59]. + * int tm_hour Hour [0,23]. + * int tm_mday Day of month [1,31]. + * int tm_mon Month of year [0,11]. + * int tm_year Years since 1900. + * int tm_wday Day of week [0,6] (Sunday =0). + * int tm_yday Day of year [0,365]. + * int tm_isdst Daylight Savings flag. + */ + datetime_set_date(bdate, (uint16_t)tblock->tm_year + 1900, + (uint8_t)tblock->tm_mon + 1, + (uint8_t)tblock->tm_mday); + datetime_set_time(btime, (uint8_t)tblock->tm_hour, + (uint8_t)tblock->tm_min, (uint8_t)tblock->tm_sec, + (uint8_t)(tv.tv_usec / 10000)); + if (dst_active) { + /* The value of tm_isdst is: + - positive if Daylight Saving Time is in effect, + - 0 if Daylight Saving Time is not in effect, and + - negative if the information is not available. */ + if (tblock->tm_isdst > 0) { + *dst_active = true; + } else { + *dst_active = false; + } + } + /* note: timezone is declared in stdlib. */ + if (utc_offset_minutes) { + /* timezone is set to the difference, in seconds, + between Coordinated Universal Time (UTC) and + local standard time */ + *utc_offset_minutes = timezone / 60; + } + } + + return status; +} + +/** + * initialize the date time + */ +void datetime_init(void) +{ + /* nothing to do */ +} diff --git a/ports/linux/dlmstp.c b/ports/linux/dlmstp.c index 9b1664fc..87fbe8eb 100644 --- a/ports/linux/dlmstp.c +++ b/ports/linux/dlmstp.c @@ -30,17 +30,17 @@ #include #include #include -#include "bacdef.h" -#include "bacaddr.h" -#include "mstp.h" -#include "dlmstp.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacaddr.h" +#include "bacnet/datalink/mstp.h" +#include "bacnet/datalink/dlmstp.h" #include "rs485.h" -#include "npdu.h" -#include "bits.h" -#include "ringbuf.h" -#include "debug.h" +#include "bacnet/npdu.h" +#include "bacnet/bits.h" +#include "bacnet/basic/sys/ringbuf.h" +#include "bacnet/basic/sys/debug.h" /* OS Specific include */ -#include "net.h" +#include "bacport.h" /** @file linux/dlmstp.c Provides Linux-specific DataLink functions for MS/TP. */ diff --git a/ports/linux/dlmstp_linux.c b/ports/linux/dlmstp_linux.c index a2ccca6e..bbdad1ab 100644 --- a/ports/linux/dlmstp_linux.c +++ b/ports/linux/dlmstp_linux.c @@ -29,17 +29,17 @@ #include #include #include -#include "bacdef.h" -#include "bacaddr.h" -#include "mstp.h" -/*#include "dlmstp.h" */ +#include "bacnet/bacdef.h" +#include "bacnet/bacaddr.h" +#include "bacnet/datalink/mstp.h" +/*#include "bacnet/datalink/dlmstp.h" */ #include "dlmstp_linux.h" #include "rs485.h" -#include "npdu.h" -#include "bits.h" +#include "bacnet/npdu.h" +#include "bacnet/bits.h" /* OS Specific include */ -#include "net.h" -#include "ringbuf.h" +#include "bacport.h" +#include "bacnet/basic/sys/ringbuf.h" /** @file linux/dlmstp.c Provides Linux-specific DataLink functions for MS/TP. */ diff --git a/ports/linux/dlmstp_linux.h b/ports/linux/dlmstp_linux.h index e662e305..29b9d958 100644 --- a/ports/linux/dlmstp_linux.h +++ b/ports/linux/dlmstp_linux.h @@ -24,19 +24,19 @@ #ifndef DLMSTP_LINUX_H #define DLMSTP_LINUX_H -#include "mstp.h" -/*#include "dlmstp.h" */ +#include "bacnet/datalink/mstp.h" +/*#include "bacnet/datalink/dlmstp.h" */ #include "bits/pthreadtypes.h" #include #include #include #include -#include "bacdef.h" -#include "npdu.h" +#include "bacnet/bacdef.h" +#include "bacnet/npdu.h" #include -#include "fifo.h" -#include "ringbuf.h" +#include "bacnet/basic/sys/fifo.h" +#include "bacnet/basic/sys/ringbuf.h" /* defines specific to MS/TP */ /* preamble+type+dest+src+len+crc8+crc16 */ #define MAX_HEADER (2+1+1+1+2+1+2) diff --git a/ports/linux/ethernet.c b/ports/linux/ethernet.c index a909eec5..006352e9 100644 --- a/ports/linux/ethernet.c +++ b/ports/linux/ethernet.c @@ -35,10 +35,10 @@ #include /* for standard integer types uint8_t etc. */ #include /* for the standard bool type. */ -#include "net.h" -#include "bacdef.h" -#include "ethernet.h" -#include "bacint.h" +#include "bacport.h" +#include "bacnet/bacdef.h" +#include "bacnet/datalink/ethernet.h" +#include "bacnet/bacint.h" /** @file linux/ethernet.c Provides Linux-specific functions for BACnet/Ethernet. */ diff --git a/ports/win32/timer.h b/ports/linux/mstimer-init.c similarity index 50% rename from ports/win32/timer.h rename to ports/linux/mstimer-init.c index 44cf23b4..1e6920e8 100644 --- a/ports/win32/timer.h +++ b/ports/linux/mstimer-init.c @@ -20,63 +20,65 @@ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +* *********************************************************************/ -#ifndef TIMER_H -#define TIMER_H - +#include #include #include +#include +#include +#include "bacport.h" +#include "bacnet/basic/sys/mstimer.h" -#define WIN32_LEAN_AND_MEAN -#define STRICT 1 -#include -#if defined(__BORLANDC__) -#include -#else -#if !defined(_MSC_VER) -#include -#endif -#endif -#include -#if defined(__BORLANDC__) -#define _timeb timeb -#define _ftime(param) ftime(param) -#endif +/** @file linux/mstimer.c Provides Linux-specific time and timer functions. */ -/* Timer Module */ -#ifndef MAX_MILLISECOND_TIMERS -#define TIMER_SILENCE 0 -#define MAX_MILLISECOND_TIMERS 1 -#endif +/* counter for the various timers */ +static volatile unsigned long Millisecond_Counter; -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ +/* start time for the clock */ +static struct timespec start; - int gettimeofday( - struct timeval *tp, - void *tzp); +/** @brief The timeGetTime function retrieves the system time, in milliseconds. + * The system time is the time elapsed since Windows was started. + */ +static unsigned long timeGetTime( + void) +{ + struct timespec now; + unsigned long ticks; - void timer_init( - void); - uint32_t timer_milliseconds( - unsigned index); - bool timer_elapsed_milliseconds( - unsigned index, - uint32_t value); - bool timer_elapsed_seconds( - unsigned index, - uint32_t value); - bool timer_elapsed_minutes( - unsigned index, - uint32_t seconds); - uint32_t timer_milliseconds_set( - unsigned index, - uint32_t value); - uint32_t timer_reset( - unsigned index); + clock_gettime(CLOCK_MONOTONIC, &now); -#ifdef __cplusplus + ticks = + (now.tv_sec - start.tv_sec) * 1000 + (now.tv_nsec - + start.tv_nsec) / 1000000; + + return ticks; +} + +/** +* @brief returns the current millisecond count +* @return millisecond counter +*/ +unsigned long mstimer_now(void) +{ + unsigned long now = timeGetTime(); + unsigned long delta_time = 0; + + if (Millisecond_Counter <= now) { + delta_time = now - Millisecond_Counter; + } else { + delta_time = (ULONG_MAX - Millisecond_Counter) + now + 1; + } + + return delta_time; +} + +/** +* @brief Initialization for timer +*/ +void mstimer_init( + void) +{ + clock_gettime(CLOCK_MONOTONIC, &start); } -#endif /* __cplusplus */ -#endif diff --git a/ports/linux/mstpsnap.c b/ports/linux/mstpsnap.c index 46b54560..aecdd5a3 100644 --- a/ports/linux/mstpsnap.c +++ b/ports/linux/mstpsnap.c @@ -39,16 +39,16 @@ #include #include /* OS specific include*/ -#include "net.h" -#include "timer.h" +#include "bacport.h" +#include "bacnet/basic/sys/mstimer.h" /* local includes */ -#include "bytes.h" +#include "bacnet/bytes.h" #include "rs485.h" #include "crc.h" -#include "mstp.h" -#include "dlmstp.h" -#include "mstptext.h" -#include "bacint.h" +#include "bacnet/datalink/mstp.h" +#include "bacnet/datalink/dlmstp.h" +#include "bacnet/datalink/mstptext.h" +#include "bacnet/bacint.h" /** @file linux/mstpsnap.c Example application testing BACnet MS/TP on Linux. */ diff --git a/ports/linux/rs485.c b/ports/linux/rs485.c index 0afa3493..717103bb 100644 --- a/ports/linux/rs485.c +++ b/ports/linux/rs485.c @@ -63,9 +63,9 @@ #include /* Local includes */ -#include "mstp.h" +#include "bacnet/datalink/mstp.h" #include "rs485.h" -#include "fifo.h" +#include "bacnet/basic/sys/fifo.h" #include #include diff --git a/ports/linux/rs485.h b/ports/linux/rs485.h index 84a06df6..d7fa9db9 100644 --- a/ports/linux/rs485.h +++ b/ports/linux/rs485.h @@ -37,7 +37,7 @@ #define RS485_H #include -#include "mstp.h" +#include "bacnet/datalink/mstp.h" #ifdef __cplusplus extern "C" { diff --git a/ports/linux/rx_fsm.c b/ports/linux/rx_fsm.c index d60a8545..07c58e9e 100644 --- a/ports/linux/rx_fsm.c +++ b/ports/linux/rx_fsm.c @@ -48,11 +48,11 @@ #include /* signal handling functions */ /* local includes */ -#include "bytes.h" +#include "bacnet/bytes.h" #include "rs485.h" #include "crc.h" -#include "mstp.h" -#include "mstptext.h" +#include "bacnet/datalink/mstp.h" +#include "bacnet/datalink/mstptext.h" /** @file linux/rx_fsm.c Example app testing MS/TP Rx State Machine on Linux. */ diff --git a/ports/linux/timer.c b/ports/linux/timer.c deleted file mode 100644 index 773ac941..00000000 --- a/ports/linux/timer.c +++ /dev/null @@ -1,140 +0,0 @@ -/************************************************************************** -* -* Copyright (C) 2009 Steve Karg -* -* Permission is hereby granted, free of charge, to any person obtaining -* a copy of this software and associated documentation files (the -* "Software"), to deal in the Software without restriction, including -* without limitation the rights to use, copy, modify, merge, publish, -* distribute, sublicense, and/or sell copies of the Software, and to -* permit persons to whom the Software is furnished to do so, subject to -* the following conditions: -* -* The above copyright notice and this permission notice shall be included -* in all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -* -*********************************************************************/ -#include -#include -#include -#include -#include "timer.h" - -/** @file linux/timer.c Provides Linux-specific time and timer functions. */ - -/* counter for the various timers */ -static volatile uint32_t Millisecond_Counter[MAX_MILLISECOND_TIMERS]; - -/* start time for the clock */ -static struct timespec start; -/* The timeGetTime function retrieves the system time, in milliseconds. - The system time is the time elapsed since Windows was started. */ -uint32_t timeGetTime( - void) -{ - struct timespec now; - uint32_t ticks; - - clock_gettime(CLOCK_MONOTONIC, &now); - - ticks = - (now.tv_sec - start.tv_sec) * 1000 + (now.tv_nsec - - start.tv_nsec) / 1000000; - - return ticks; -} - -/************************************************************************* -* Description: returns the current millisecond count -* Returns: none -* Notes: none -*************************************************************************/ -uint32_t timer_milliseconds( - unsigned index) -{ - uint32_t now = timeGetTime(); - uint32_t delta_time = 0; - - if (index < MAX_MILLISECOND_TIMERS) { - if (Millisecond_Counter[index] <= now) { - delta_time = now - Millisecond_Counter[index]; - } else { - delta_time = (UINT32_MAX - Millisecond_Counter[index]) + now + 1; - } - } - - return delta_time; -} - -/************************************************************************* -* Description: compares the current time count with a value -* Returns: true if the time has elapsed -* Notes: none -*************************************************************************/ -bool timer_elapsed_milliseconds( - unsigned index, - uint32_t value) -{ - return (timer_milliseconds(index) >= value); -} - -/************************************************************************* -* Description: compares the current time count with a value -* Returns: true if the time has elapsed -* Notes: none -*************************************************************************/ -bool timer_elapsed_seconds( - unsigned index, - uint32_t seconds) -{ - return ((timer_milliseconds(index) / 1000) >= seconds); -} - -/************************************************************************* -* Description: compares the current time count with a value -* Returns: true if the time has elapsed -* Notes: none -*************************************************************************/ -bool timer_elapsed_minutes( - unsigned index, - uint32_t minutes) -{ - return ((timer_milliseconds(index) / (1000 * 60)) >= minutes); -} - -/************************************************************************* -* Description: Sets the timer counter to zero. -* Returns: none -* Notes: none -*************************************************************************/ -uint32_t timer_reset( - unsigned index) -{ - uint32_t timer_value = 0; - - if (index < MAX_MILLISECOND_TIMERS) { - timer_value = timer_milliseconds(index); - Millisecond_Counter[index] = timeGetTime(); - } - - return timer_value; -} - -/************************************************************************* -* Description: Initialization for timer -* Returns: none -* Notes: none -*************************************************************************/ -void timer_init( - void) -{ - clock_gettime(CLOCK_MONOTONIC, &start); -} diff --git a/ports/lwip/bip.c b/ports/lwip/bip.c index d583c27d..0e76391e 100644 --- a/ports/lwip/bip.c +++ b/ports/lwip/bip.c @@ -33,13 +33,13 @@ ####COPYRIGHTEND####*/ #include /* for standard integer types uint8_t etc. */ #include /* for the standard bool type. */ -#include "bacdef.h" -#include "bacdcode.h" -#include "bacint.h" -#include "bip.h" -#include "bvlc.h" -#include "handlers.h" -#include "net.h" /* custom per port */ +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacint.h" +#include "bacnet/datalink/bip.h" +#include "bacnet/datalink/bvlc.h" +#include "bacnet/basic/services.h" +#include "bacport.h" /* custom per port */ /** @file bip.c Configuration and Operations for BACnet/IP */ diff --git a/ports/pic18f6720/18F6720.lkr b/ports/pic18f6720/18F6720.lkr index a3922646..18c3fd41 100644 --- a/ports/pic18f6720/18F6720.lkr +++ b/ports/pic18f6720/18F6720.lkr @@ -1,41 +1,41 @@ -// $Id: 18f6720.lkr,v 1.1 2003/12/16 14:53:08 GrosbaJ Exp $ -// File: 18f6720.lkr -// Sample linker script for the PIC18F6720 processor - -LIBPATH . - -FILES c018i.o -FILES clib.lib -FILES p18F6720.lib - -CODEPAGE NAME=vectors START=0x0 END=0x29 PROTECTED -CODEPAGE NAME=page START=0x2A END=0x1FFFF -CODEPAGE NAME=idlocs START=0x200000 END=0x200007 PROTECTED -CODEPAGE NAME=config START=0x300000 END=0x30000D PROTECTED -CODEPAGE NAME=devid START=0x3FFFFE END=0x3FFFFF PROTECTED -CODEPAGE NAME=eedata START=0xF00000 END=0xF003FF PROTECTED - -ACCESSBANK NAME=accessram START=0x0 END=0x5F -DATABANK NAME=gpr0 START=0x60 END=0xFF -DATABANK NAME=gpr1 START=0x100 END=0x1FF -DATABANK NAME=gpr2 START=0x200 END=0x2FF -DATABANK NAME=gpr3 START=0x300 END=0x3FF -DATABANK NAME=gpr4 START=0x400 END=0x4FF -DATABANK NAME=gpr5 START=0x500 END=0x5FF -DATABANK NAME=gpr6 START=0x600 END=0x6FF -DATABANK NAME=gpr7 START=0x700 END=0x7FF -DATABANK NAME=gpr8 START=0x800 END=0x8FF -DATABANK NAME=gpr9 START=0x900 END=0x9FF -DATABANK NAME=gpr10 START=0xA00 END=0xAFF -DATABANK NAME=gpr11 START=0xB00 END=0xBFF -//DATABANK NAME=gpr12 START=0xC00 END=0xCFF -//DATABANK NAME=gpr13 START=0xD00 END=0xDFF -DATABANK NAME=stackreg START=0xC00 END=0xDFF PROTECTED -DATABANK NAME=gpr14 START=0xE00 END=0xEF3 -DATABANK NAME=dbgspr START=0xEF4 END=0xEFF PROTECTED -ACCESSBANK NAME=accesssfr START=0xF60 END=0xFFF PROTECTED - -SECTION NAME=CONFIG ROM=config - -//STACK SIZE=0x100 RAM=gpr13 -STACK SIZE=0x200 RAM=stackreg +// $Id: 18f6720.lkr,v 1.1 2003/12/16 14:53:08 GrosbaJ Exp $ +// File: 18f6720.lkr +// Sample linker script for the PIC18F6720 processor + +LIBPATH . + +FILES c018i.o +FILES clib.lib +FILES p18F6720.lib + +CODEPAGE NAME=vectors START=0x0 END=0x29 PROTECTED +CODEPAGE NAME=page START=0x2A END=0x1FFFF +CODEPAGE NAME=idlocs START=0x200000 END=0x200007 PROTECTED +CODEPAGE NAME=config START=0x300000 END=0x30000D PROTECTED +CODEPAGE NAME=devid START=0x3FFFFE END=0x3FFFFF PROTECTED +CODEPAGE NAME=eedata START=0xF00000 END=0xF003FF PROTECTED + +ACCESSBANK NAME=accessram START=0x0 END=0x5F +DATABANK NAME=gpr0 START=0x60 END=0xFF +DATABANK NAME=gpr1 START=0x100 END=0x1FF +DATABANK NAME=gpr2 START=0x200 END=0x2FF +DATABANK NAME=gpr3 START=0x300 END=0x3FF +DATABANK NAME=gpr4 START=0x400 END=0x4FF +DATABANK NAME=gpr5 START=0x500 END=0x5FF +DATABANK NAME=gpr6 START=0x600 END=0x6FF +DATABANK NAME=gpr7 START=0x700 END=0x7FF +DATABANK NAME=gpr8 START=0x800 END=0x8FF +DATABANK NAME=gpr9 START=0x900 END=0x9FF +DATABANK NAME=gpr10 START=0xA00 END=0xAFF +DATABANK NAME=gpr11 START=0xB00 END=0xBFF +//DATABANK NAME=gpr12 START=0xC00 END=0xCFF +//DATABANK NAME=gpr13 START=0xD00 END=0xDFF +DATABANK NAME=stackreg START=0xC00 END=0xDFF PROTECTED +DATABANK NAME=gpr14 START=0xE00 END=0xEF3 +DATABANK NAME=dbgspr START=0xEF4 END=0xEFF PROTECTED +ACCESSBANK NAME=accesssfr START=0xF60 END=0xFFF PROTECTED + +SECTION NAME=CONFIG ROM=config + +//STACK SIZE=0x100 RAM=gpr13 +STACK SIZE=0x200 RAM=stackreg diff --git a/ports/pic18f6720/BACnet-Server.X/nbproject/Makefile-genesis.properties b/ports/pic18f6720/BACnet-Server.X/nbproject/Makefile-genesis.properties index 73831ec1..f3e0aab6 100644 --- a/ports/pic18f6720/BACnet-Server.X/nbproject/Makefile-genesis.properties +++ b/ports/pic18f6720/BACnet-Server.X/nbproject/Makefile-genesis.properties @@ -1,8 +1,8 @@ -# -#Mon May 30 09:47:38 CDT 2016 -default.com-microchip-mplab-nbide-toolchainC18-C18LanguageToolchain.md5=21ae92f54c0f89bc027339aedc19b7f9 -default.languagetoolchain.dir=C\:\\Program Files (x86)\\Microchip\\mplabc18\\v3.40\\bin -com-microchip-mplab-nbide-embedded-makeproject-MakeProject.md5=ef199adcc8f049579a105cca20571dcb -default.languagetoolchain.version=3.40 -host.platform=windows -conf.ids=default +# +#Mon May 30 09:47:38 CDT 2016 +default.com-microchip-mplab-nbide-toolchainC18-C18LanguageToolchain.md5=21ae92f54c0f89bc027339aedc19b7f9 +default.languagetoolchain.dir=C\:\\Program Files (x86)\\Microchip\\mplabc18\\v3.40\\bin +com-microchip-mplab-nbide-embedded-makeproject-MakeProject.md5=ef199adcc8f049579a105cca20571dcb +default.languagetoolchain.version=3.40 +host.platform=windows +conf.ids=default diff --git a/ports/pic18f6720/BACnet-Server.X/nbproject/configurations.xml b/ports/pic18f6720/BACnet-Server.X/nbproject/configurations.xml index e1de7d50..9f900ef6 100644 --- a/ports/pic18f6720/BACnet-Server.X/nbproject/configurations.xml +++ b/ports/pic18f6720/BACnet-Server.X/nbproject/configurations.xml @@ -1,174 +1,174 @@ - - - - - ../stdbool.h - ../stdint.h - ../rs485.h - ../mstp.h - ../../../include/bits.h - ../../../include/abort.h - ../../../include/apdu.h - ../../../include/bacaddr.h - ../../../include/bacapp.h - ../../../include/bacdcode.h - ../../../include/bacdef.h - ../../../include/bacenum.h - ../../../include/bacerror.h - ../../../include/bacint.h - ../../../include/bacprop.h - ../../../include/bacreal.h - ../../../include/bacstr.h - ../../../include/bigend.h - ../../../include/config.h - ../hardware.h - - - - - ../../../src/abort.c - ../../../src/bacapp.c - ../../../src/bacdcode.c - ../../../src/bacerror.c - ../../../src/bacstr.c - ../../../src/crc.c - ../../../src/dcc.c - ../../../src/iam.c - ../../../src/rd.c - ../../../src/reject.c - ../../../src/rp.c - ../../../src/whois.c - ../../../demo/handler/h_dcc.c - ../../../demo/handler/h_rd.c - ../main.c - ../dlmstp.c - ../device.c - ../rs485.c - ../isr.c - ../../../src/datetime.c - ../../../demo/handler/txbuf.c - ../../../demo/handler/h_whois.c - ../mstp.c - ../bv.c - ../ai.c - ../bi.c - ../av.c - ../../../src/wp.c - ../../../demo/handler/h_npdu.c - ../../../demo/handler/s_iam.c - ../../../src/bacreal.c - ../../../src/bacint.c - ../../../src/npdu.c - ../apdu.c - ../../../demo/handler/noserv.c - ../../../src/fifo.c - ../../../demo/handler/h_rp.c - ../../../demo/handler/h_wp.c - ../../../src/bacaddr.c - - - Makefile - - - - ../ - - Makefile - - - - localhost - PIC18F6720 - - - ICD3PlatformTool - C18 - 3.40 - 3 - - - - - - - - false - - - - - false - - false - - false - false - false - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + ../stdbool.h + ../stdint.h + ../rs485.h + ../mstp.h + ../../../include/bits.h + ../../../include/abort.h + ../../../include/apdu.h + ../../../include/bacaddr.h + ../../../include/bacapp.h + ../../../include/bacdcode.h + ../../../include/bacdef.h + ../../../include/bacenum.h + ../../../include/bacerror.h + ../../../include/bacint.h + ../../../include/bacprop.h + ../../../include/bacreal.h + ../../../include/bacstr.h + ../../../include/bigend.h + ../../../include/config.h + ../hardware.h + + + + + ../../../src/abort.c + ../../../src/bacapp.c + ../../../src/bacdcode.c + ../../../src/bacerror.c + ../../../src/bacstr.c + ../../../src/crc.c + ../../../src/dcc.c + ../../../src/iam.c + ../../../src/rd.c + ../../../src/reject.c + ../../../src/rp.c + ../../../src/whois.c + ../../../demo/handler/h_dcc.c + ../../../demo/handler/h_rd.c + ../main.c + ../dlmstp.c + ../device.c + ../rs485.c + ../isr.c + ../../../src/datetime.c + ../../../demo/handler/txbuf.c + ../../../demo/handler/h_whois.c + ../mstp.c + ../bv.c + ../ai.c + ../bi.c + ../av.c + ../../../src/wp.c + ../../../demo/handler/h_npdu.c + ../../../demo/handler/s_iam.c + ../../../src/bacreal.c + ../../../src/bacint.c + ../../../src/npdu.c + ../apdu.c + ../../../demo/handler/noserv.c + ../../../src/fifo.c + ../../../demo/handler/h_rp.c + ../../../demo/handler/h_wp.c + ../../../src/bacaddr.c + + + Makefile + + + + ../ + + Makefile + + + + localhost + PIC18F6720 + + + ICD3PlatformTool + C18 + 3.40 + 3 + + + + + + + + false + + + + + false + + false + + false + false + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ports/pic18f6720/BACnet-Server.X/nbproject/project.xml b/ports/pic18f6720/BACnet-Server.X/nbproject/project.xml index 6c3e07d6..b7fe3eff 100644 --- a/ports/pic18f6720/BACnet-Server.X/nbproject/project.xml +++ b/ports/pic18f6720/BACnet-Server.X/nbproject/project.xml @@ -1,16 +1,16 @@ - - - com.microchip.mplab.nbide.embedded.makeproject - - - BACnet-Server - e54ca906-513b-4f74-a23b-6b0204c4509a - 0 - c - - h - ISO-8859-1 - - - - + + + com.microchip.mplab.nbide.embedded.makeproject + + + BACnet-Server + e54ca906-513b-4f74-a23b-6b0204c4509a + 0 + c + + h + ISO-8859-1 + + + + diff --git a/ports/pic18f6720/BACnet-Server.mcp b/ports/pic18f6720/BACnet-Server.mcp index eb4e5e8b..2b4a169e 100644 --- a/ports/pic18f6720/BACnet-Server.mcp +++ b/ports/pic18f6720/BACnet-Server.mcp @@ -1,282 +1,282 @@ -[HEADER] -magic_cookie={66E99B07-E706-4689-9E80-9B2582898A13} -file_version=1.0 -device=PIC18F6720 -[PATH_INFO] -BuildDirPolicy=BuildDirIsSourceDir -dir_src= -dir_bin= -dir_tmp= -dir_sin= -dir_inc=C:\code\bacnet-stack\include;C:\code\bacnet-stack\demo\object;C:\code\bacnet-stack\ports\pic18f6720 -dir_lib=C:\mcc18\lib -dir_lkr= -[CAT_FILTERS] -filter_src=*.asm;*.c -filter_inc=*.h;*.inc -filter_obj=*.o -filter_lib=*.lib -filter_lkr=*.lkr -[CAT_SUBFOLDERS] -subfolder_src= -subfolder_inc= -subfolder_obj= -subfolder_lib= -subfolder_lkr= -[FILE_SUBFOLDERS] -file_000=. -file_001=. -file_002=. -file_003=. -file_004=. -file_005=. -file_006=. -file_007=. -file_008=. -file_009=. -file_010=. -file_011=. -file_012=. -file_013=. -file_014=. -file_015=. -file_016=. -file_017=. -file_018=. -file_019=. -file_020=. -file_021=. -file_022=. -file_023=. -file_024=. -file_025=. -file_026=. -file_027=. -file_028=. -file_029=. -file_030=. -file_031=. -file_032=. -file_033=. -file_034=. -file_035=. -file_036=. -file_037=. -file_038=. -file_039=. -file_040=. -file_041=. -file_042=. -file_043=. -file_044=. -file_045=. -file_046=. -file_047=. -file_048=. -file_049=. -file_050=. -file_051=. -file_052=. -file_053=. -file_054=. -file_055=. -file_056=. -file_057=. -file_058=. -[GENERATED_FILES] -file_000=no -file_001=no -file_002=no -file_003=no -file_004=no -file_005=no -file_006=no -file_007=no -file_008=no -file_009=no -file_010=no -file_011=no -file_012=no -file_013=no -file_014=no -file_015=no -file_016=no -file_017=no -file_018=no -file_019=no -file_020=no -file_021=no -file_022=no -file_023=no -file_024=no -file_025=no -file_026=no -file_027=no -file_028=no -file_029=no -file_030=no -file_031=no -file_032=no -file_033=no -file_034=no -file_035=no -file_036=no -file_037=no -file_038=no -file_039=no -file_040=no -file_041=no -file_042=no -file_043=no -file_044=no -file_045=no -file_046=no -file_047=no -file_048=no -file_049=no -file_050=no -file_051=no -file_052=no -file_053=no -file_054=no -file_055=no -file_056=no -file_057=no -file_058=no -[OTHER_FILES] -file_000=no -file_001=no -file_002=no -file_003=no -file_004=no -file_005=no -file_006=no -file_007=no -file_008=no -file_009=no -file_010=no -file_011=no -file_012=no -file_013=no -file_014=no -file_015=no -file_016=no -file_017=no -file_018=no -file_019=no -file_020=no -file_021=no -file_022=no -file_023=no -file_024=no -file_025=no -file_026=no -file_027=no -file_028=no -file_029=no -file_030=no -file_031=no -file_032=no -file_033=no -file_034=no -file_035=no -file_036=no -file_037=no -file_038=no -file_039=no -file_040=no -file_041=no -file_042=no -file_043=no -file_044=no -file_045=no -file_046=no -file_047=no -file_048=no -file_049=no -file_050=no -file_051=no -file_052=no -file_053=no -file_054=no -file_055=no -file_056=no -file_057=no -file_058=no -[FILE_INFO] -file_000=C:\code\bacnet-stack\src\abort.c -file_001=C:\code\bacnet-stack\src\bacapp.c -file_002=C:\code\bacnet-stack\src\bacdcode.c -file_003=C:\code\bacnet-stack\src\bacerror.c -file_004=C:\code\bacnet-stack\src\bacstr.c -file_005=C:\code\bacnet-stack\src\crc.c -file_006=C:\code\bacnet-stack\src\dcc.c -file_007=C:\code\bacnet-stack\src\iam.c -file_008=C:\code\bacnet-stack\src\rd.c -file_009=C:\code\bacnet-stack\src\reject.c -file_010=C:\code\bacnet-stack\src\rp.c -file_011=C:\code\bacnet-stack\src\whois.c -file_012=C:\code\bacnet-stack\demo\handler\h_dcc.c -file_013=C:\code\bacnet-stack\demo\handler\h_rd.c -file_014=main.c -file_015=dlmstp.c -file_016=device.c -file_017=rs485.c -file_018=isr.c -file_019=C:\code\bacnet-stack\src\datetime.c -file_020=C:\code\bacnet-stack\demo\handler\txbuf.c -file_021=C:\code\bacnet-stack\demo\handler\h_whois.c -file_022=mstp.c -file_023=bv.c -file_024=ai.c -file_025=bi.c -file_026=av.c -file_027=C:\code\bacnet-stack\src\wp.c -file_028=C:\code\bacnet-stack\demo\handler\h_npdu.c -file_029=C:\code\bacnet-stack\demo\handler\s_iam.c -file_030=C:\code\bacnet-stack\src\bacreal.c -file_031=C:\code\bacnet-stack\src\bacint.c -file_032=C:\code\bacnet-stack\src\npdu.c -file_033=apdu.c -file_034=C:\code\bacnet-stack\demo\handler\noserv.c -file_035=C:\code\bacnet-stack\src\fifo.c -file_036=C:\code\bacnet-stack\demo\handler\h_wp.c -file_037=C:\code\bacnet-stack\demo\handler\h_rp.c -file_038=C:\code\bacnet-stack\src\bacaddr.c -file_039=stdbool.h -file_040=stdint.h -file_041=rs485.h -file_042=mstp.h -file_043=C:\code\bacnet-stack\include\bits.h -file_044=C:\code\bacnet-stack\include\abort.h -file_045=C:\code\bacnet-stack\include\apdu.h -file_046=C:\code\bacnet-stack\include\bacaddr.h -file_047=C:\code\bacnet-stack\include\bacapp.h -file_048=C:\code\bacnet-stack\include\bacdcode.h -file_049=C:\code\bacnet-stack\include\bacdef.h -file_050=C:\code\bacnet-stack\include\bacenum.h -file_051=C:\code\bacnet-stack\include\bacerror.h -file_052=C:\code\bacnet-stack\include\bacint.h -file_053=C:\code\bacnet-stack\include\bacprop.h -file_054=C:\code\bacnet-stack\include\bacreal.h -file_055=C:\code\bacnet-stack\include\bacstr.h -file_056=C:\code\bacnet-stack\include\bigend.h -file_057=C:\code\bacnet-stack\include\config.h -file_058=18F6720.lkr -[SUITE_INFO] -suite_guid={5B7D72DD-9861-47BD-9F60-2BE967BF8416} -suite_state= -[TOOL_SETTINGS] -TS{DD2213A8-6310-47B1-8376-9430CDFC013F}= -TS{BFD27FBA-4A02-4C0E-A5E5-B812F3E7707C}=/m"$(BINDIR_)$(TARGETBASE).map" /o"$(TARGETBASE).cof" -TS{C2AF05E7-1416-4625-923D-E114DB6E2B96}=-DPRINT_ENABLED=0 -DBACDL_MSTP=1 -DBIG_ENDIAN=0 -DMAX_APDU=50 -DMAX_TSM_TRANSACTIONS=0 -mL -Ls -Ou- -Ot- -Ob- -Op- -Or- -Od- -Opa- -TS{ADE93A55-C7C7-4D4D-A4BA-59305F7D0391}= -[INSTRUMENTED_TRACE] -enable=0 -transport=0 -format=0 -[CUSTOM_BUILD] -Pre-Build= -Pre-BuildEnabled=1 -Post-Build= -Post-BuildEnabled=1 +[HEADER] +magic_cookie={66E99B07-E706-4689-9E80-9B2582898A13} +file_version=1.0 +device=PIC18F6720 +[PATH_INFO] +BuildDirPolicy=BuildDirIsSourceDir +dir_src= +dir_bin= +dir_tmp= +dir_sin= +dir_inc=C:\code\bacnet-stack\include;C:\code\bacnet-stack\demo\object;C:\code\bacnet-stack\ports\pic18f6720 +dir_lib=C:\mcc18\lib +dir_lkr= +[CAT_FILTERS] +filter_src=*.asm;*.c +filter_inc=*.h;*.inc +filter_obj=*.o +filter_lib=*.lib +filter_lkr=*.lkr +[CAT_SUBFOLDERS] +subfolder_src= +subfolder_inc= +subfolder_obj= +subfolder_lib= +subfolder_lkr= +[FILE_SUBFOLDERS] +file_000=. +file_001=. +file_002=. +file_003=. +file_004=. +file_005=. +file_006=. +file_007=. +file_008=. +file_009=. +file_010=. +file_011=. +file_012=. +file_013=. +file_014=. +file_015=. +file_016=. +file_017=. +file_018=. +file_019=. +file_020=. +file_021=. +file_022=. +file_023=. +file_024=. +file_025=. +file_026=. +file_027=. +file_028=. +file_029=. +file_030=. +file_031=. +file_032=. +file_033=. +file_034=. +file_035=. +file_036=. +file_037=. +file_038=. +file_039=. +file_040=. +file_041=. +file_042=. +file_043=. +file_044=. +file_045=. +file_046=. +file_047=. +file_048=. +file_049=. +file_050=. +file_051=. +file_052=. +file_053=. +file_054=. +file_055=. +file_056=. +file_057=. +file_058=. +[GENERATED_FILES] +file_000=no +file_001=no +file_002=no +file_003=no +file_004=no +file_005=no +file_006=no +file_007=no +file_008=no +file_009=no +file_010=no +file_011=no +file_012=no +file_013=no +file_014=no +file_015=no +file_016=no +file_017=no +file_018=no +file_019=no +file_020=no +file_021=no +file_022=no +file_023=no +file_024=no +file_025=no +file_026=no +file_027=no +file_028=no +file_029=no +file_030=no +file_031=no +file_032=no +file_033=no +file_034=no +file_035=no +file_036=no +file_037=no +file_038=no +file_039=no +file_040=no +file_041=no +file_042=no +file_043=no +file_044=no +file_045=no +file_046=no +file_047=no +file_048=no +file_049=no +file_050=no +file_051=no +file_052=no +file_053=no +file_054=no +file_055=no +file_056=no +file_057=no +file_058=no +[OTHER_FILES] +file_000=no +file_001=no +file_002=no +file_003=no +file_004=no +file_005=no +file_006=no +file_007=no +file_008=no +file_009=no +file_010=no +file_011=no +file_012=no +file_013=no +file_014=no +file_015=no +file_016=no +file_017=no +file_018=no +file_019=no +file_020=no +file_021=no +file_022=no +file_023=no +file_024=no +file_025=no +file_026=no +file_027=no +file_028=no +file_029=no +file_030=no +file_031=no +file_032=no +file_033=no +file_034=no +file_035=no +file_036=no +file_037=no +file_038=no +file_039=no +file_040=no +file_041=no +file_042=no +file_043=no +file_044=no +file_045=no +file_046=no +file_047=no +file_048=no +file_049=no +file_050=no +file_051=no +file_052=no +file_053=no +file_054=no +file_055=no +file_056=no +file_057=no +file_058=no +[FILE_INFO] +file_000=C:\code\bacnet-stack\src\abort.c +file_001=C:\code\bacnet-stack\src\bacapp.c +file_002=C:\code\bacnet-stack\src\bacdcode.c +file_003=C:\code\bacnet-stack\src\bacerror.c +file_004=C:\code\bacnet-stack\src\bacstr.c +file_005=C:\code\bacnet-stack\src\crc.c +file_006=C:\code\bacnet-stack\src\dcc.c +file_007=C:\code\bacnet-stack\src\iam.c +file_008=C:\code\bacnet-stack\src\rd.c +file_009=C:\code\bacnet-stack\src\reject.c +file_010=C:\code\bacnet-stack\src\rp.c +file_011=C:\code\bacnet-stack\src\whois.c +file_012=C:\code\bacnet-stack\demo\handler\h_dcc.c +file_013=C:\code\bacnet-stack\demo\handler\h_rd.c +file_014=main.c +file_015=dlmstp.c +file_016=device.c +file_017=rs485.c +file_018=isr.c +file_019=C:\code\bacnet-stack\src\datetime.c +file_020=C:\code\bacnet-stack\demo\handler\txbuf.c +file_021=C:\code\bacnet-stack\demo\handler\h_whois.c +file_022=mstp.c +file_023=bv.c +file_024=ai.c +file_025=bi.c +file_026=av.c +file_027=C:\code\bacnet-stack\src\wp.c +file_028=C:\code\bacnet-stack\demo\handler\h_npdu.c +file_029=C:\code\bacnet-stack\demo\handler\s_iam.c +file_030=C:\code\bacnet-stack\src\bacreal.c +file_031=C:\code\bacnet-stack\src\bacint.c +file_032=C:\code\bacnet-stack\src\npdu.c +file_033=apdu.c +file_034=C:\code\bacnet-stack\demo\handler\noserv.c +file_035=C:\code\bacnet-stack\src\fifo.c +file_036=C:\code\bacnet-stack\demo\handler\h_wp.c +file_037=C:\code\bacnet-stack\demo\handler\h_rp.c +file_038=C:\code\bacnet-stack\src\bacaddr.c +file_039=stdbool.h +file_040=stdint.h +file_041=rs485.h +file_042=mstp.h +file_043=C:\code\bacnet-stack\include\bits.h +file_044=C:\code\bacnet-stack\include\abort.h +file_045=C:\code\bacnet-stack\include\apdu.h +file_046=C:\code\bacnet-stack\include\bacaddr.h +file_047=C:\code\bacnet-stack\include\bacapp.h +file_048=C:\code\bacnet-stack\include\bacdcode.h +file_049=C:\code\bacnet-stack\include\bacdef.h +file_050=C:\code\bacnet-stack\include\bacenum.h +file_051=C:\code\bacnet-stack\include\bacerror.h +file_052=C:\code\bacnet-stack\include\bacint.h +file_053=C:\code\bacnet-stack\include\bacprop.h +file_054=C:\code\bacnet-stack\include\bacreal.h +file_055=C:\code\bacnet-stack\include\bacstr.h +file_056=C:\code\bacnet-stack\include\bigend.h +file_057=C:\code\bacnet-stack\include\config.h +file_058=18F6720.lkr +[SUITE_INFO] +suite_guid={5B7D72DD-9861-47BD-9F60-2BE967BF8416} +suite_state= +[TOOL_SETTINGS] +TS{DD2213A8-6310-47B1-8376-9430CDFC013F}= +TS{BFD27FBA-4A02-4C0E-A5E5-B812F3E7707C}=/m"$(BINDIR_)$(TARGETBASE).map" /o"$(TARGETBASE).cof" +TS{C2AF05E7-1416-4625-923D-E114DB6E2B96}=-DPRINT_ENABLED=0 -DBACDL_MSTP=1 -DBIG_ENDIAN=0 -DMAX_APDU=50 -DMAX_TSM_TRANSACTIONS=0 -mL -Ls -Ou- -Ot- -Ob- -Op- -Or- -Od- -Opa- +TS{ADE93A55-C7C7-4D4D-A4BA-59305F7D0391}= +[INSTRUMENTED_TRACE] +enable=0 +transport=0 +format=0 +[CUSTOM_BUILD] +Pre-Build= +Pre-BuildEnabled=1 +Post-Build= +Post-BuildEnabled=1 diff --git a/ports/pic18f6720/ai.c b/ports/pic18f6720/ai.c index 35f5cea1..2d73e9e1 100644 --- a/ports/pic18f6720/ai.c +++ b/ports/pic18f6720/ai.c @@ -28,13 +28,13 @@ #include #include #include -#include "bacdef.h" -#include "bacdcode.h" -#include "bacenum.h" -#include "config.h" -#include "wp.h" -#include "rp.h" -#include "ai.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacenum.h" +#include "bacnet/config.h" +#include "bacnet/wp.h" +#include "bacnet/rp.h" +#include "bacnet/basic/object/ai.h" /* Analog Input = Photocell */ #define MAX_ANALOG_INPUTS 2 diff --git a/ports/pic18f6720/apdu.c b/ports/pic18f6720/apdu.c index 4e739e87..004ca63a 100644 --- a/ports/pic18f6720/apdu.c +++ b/ports/pic18f6720/apdu.c @@ -34,14 +34,14 @@ #include #include #include -#include "bits.h" -#include "bacdef.h" -#include "bacdcode.h" -#include "bacenum.h" -#include "dcc.h" -#include "handlers.h" +#include "bacnet/bits.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacenum.h" +#include "bacnet/dcc.h" +#include "bacnet/basic/services.h" /* me */ -#include "apdu.h" +#include "bacnet/apdu.h" uint16_t apdu_timeout( void) diff --git a/ports/pic18f6720/av.c b/ports/pic18f6720/av.c index 71885270..c77677df 100644 --- a/ports/pic18f6720/av.c +++ b/ports/pic18f6720/av.c @@ -28,14 +28,14 @@ #include #include #include -#include "bacdef.h" -#include "bacdcode.h" -#include "bacenum.h" -#include "bacapp.h" -#include "config.h" /* the custom stuff */ -#include "wp.h" -#include "rp.h" -#include "av.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacenum.h" +#include "bacnet/bacapp.h" +#include "bacnet/config.h" /* the custom stuff */ +#include "bacnet/wp.h" +#include "bacnet/rp.h" +#include "bacnet/basic/object/av.h" #define MAX_ANALOG_VALUES 4 diff --git a/ports/pic18f6720/bi.c b/ports/pic18f6720/bi.c index c389952c..86fe747e 100644 --- a/ports/pic18f6720/bi.c +++ b/ports/pic18f6720/bi.c @@ -28,13 +28,13 @@ #include #include #include -#include "bacdef.h" -#include "bacdcode.h" -#include "bacenum.h" -#include "config.h" -#include "wp.h" -#include "rp.h" -#include "bi.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacenum.h" +#include "bacnet/config.h" +#include "bacnet/wp.h" +#include "bacnet/rp.h" +#include "bacnet/basic/object/bi.h" #define MAX_BINARY_INPUTS 8 diff --git a/ports/pic18f6720/bv.c b/ports/pic18f6720/bv.c index 5c567774..a57f57e4 100644 --- a/ports/pic18f6720/bv.c +++ b/ports/pic18f6720/bv.c @@ -28,13 +28,13 @@ #include #include #include -#include "bacdef.h" -#include "bacdcode.h" -#include "bacenum.h" -#include "config.h" /* the custom stuff */ -#include "wp.h" -#include "rp.h" -#include "bv.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacenum.h" +#include "bacnet/config.h" /* the custom stuff */ +#include "bacnet/wp.h" +#include "bacnet/rp.h" +#include "bacnet/basic/object/bv.h" #define MAX_BINARY_VALUES 8 diff --git a/ports/pic18f6720/device.c b/ports/pic18f6720/device.c index 0b560c39..4856c5c4 100644 --- a/ports/pic18f6720/device.c +++ b/ports/pic18f6720/device.c @@ -26,23 +26,23 @@ #include #include #include /* for memmove */ -#include "bacdef.h" -#include "bacdcode.h" -#include "bacstr.h" -#include "bacenum.h" -#include "config.h" /* the custom stuff */ -#include "apdu.h" -#include "dlmstp.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacstr.h" +#include "bacnet/bacenum.h" +#include "bacnet/config.h" /* the custom stuff */ +#include "bacnet/apdu.h" +#include "bacnet/datalink/dlmstp.h" #include "rs485.h" -#include "ai.h" -#include "av.h" -#include "bi.h" -#include "bv.h" -#include "rp.h" -#include "wp.h" -#include "dcc.h" -#include "version.h" -#include "device.h" /* me */ +#include "bacnet/basic/object/ai.h" +#include "bacnet/basic/object/av.h" +#include "bacnet/basic/object/bi.h" +#include "bacnet/basic/object/bv.h" +#include "bacnet/rp.h" +#include "bacnet/wp.h" +#include "bacnet/dcc.h" +#include "bacnet/version.h" +#include "bacnet/basic/object/device.h" /* me */ /* note: you really only need to define variables for properties that are writable or that may change. diff --git a/ports/pic18f6720/dlmstp.c b/ports/pic18f6720/dlmstp.c index 7877617c..1bf15ffd 100644 --- a/ports/pic18f6720/dlmstp.c +++ b/ports/pic18f6720/dlmstp.c @@ -29,12 +29,12 @@ #if PRINT_ENABLED #include #endif -#include "bacdef.h" -#include "mstp.h" -#include "dlmstp.h" +#include "bacnet/bacdef.h" +#include "bacnet/datalink/mstp.h" +#include "bacnet/datalink/dlmstp.h" #include "rs485.h" -#include "npdu.h" -#include "handlers.h" +#include "bacnet/npdu.h" +#include "bacnet/basic/services.h" /* Number of MS/TP Packets Rx/Tx */ uint16_t MSTP_Packets = 0; diff --git a/ports/pic18f6720/dlmstp.h b/ports/pic18f6720/dlmstp.h index 418d7d34..fc4e420f 100644 --- a/ports/pic18f6720/dlmstp.h +++ b/ports/pic18f6720/dlmstp.h @@ -38,8 +38,8 @@ #include #include #include -#include "bacdef.h" -#include "npdu.h" +#include "bacnet/bacdef.h" +#include "bacnet/npdu.h" /* defines specific to MS/TP */ #define MAX_HEADER (2+1+1+1+2+1) diff --git a/ports/pic18f6720/isr.c b/ports/pic18f6720/isr.c index 1b62e3fd..23554963 100644 --- a/ports/pic18f6720/isr.c +++ b/ports/pic18f6720/isr.c @@ -25,7 +25,7 @@ #include "stdint.h" #include "hardware.h" #include "rs485.h" -#include "dlmstp.h" +#include "bacnet/datalink/dlmstp.h" /* from main.c */ extern volatile uint8_t Milliseconds; diff --git a/ports/pic18f6720/main.c b/ports/pic18f6720/main.c index 41a016ec..009b5815 100644 --- a/ports/pic18f6720/main.c +++ b/ports/pic18f6720/main.c @@ -31,12 +31,12 @@ #include "stdint.h" #include "hardware.h" /* BACnet */ -#include "apdu.h" -#include "datalink.h" -#include "dcc.h" -#include "handlers.h" -#include "client.h" -#include "txbuf.h" +#include "bacnet/apdu.h" +#include "bacnet/datalink/datalink.h" +#include "bacnet/dcc.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/tsm/tsm.h" #include "rs485.h" /* chip configuration data */ diff --git a/ports/pic18f6720/mstp.c b/ports/pic18f6720/mstp.c index 0d353349..13d41792 100644 --- a/ports/pic18f6720/mstp.c +++ b/ports/pic18f6720/mstp.c @@ -49,14 +49,14 @@ #if PRINT_ENABLED #include #endif -#include "mstp.h" -#include "bytes.h" -#include "bits.h" +#include "bacnet/datalink/mstp.h" +#include "bacnet/bytes.h" +#include "bacnet/bits.h" #include "crc.h" -#include "bacaddr.h" +#include "bacnet/bacaddr.h" #include "rs485.h" #if PRINT_ENABLED -#include "mstptext.h" +#include "bacnet/datalink/mstptext.h" #endif /* debug print statements */ diff --git a/ports/pic18f6720/mstp.h b/ports/pic18f6720/mstp.h index 905cad51..a664f1b9 100644 --- a/ports/pic18f6720/mstp.h +++ b/ports/pic18f6720/mstp.h @@ -39,9 +39,9 @@ #include #include #include -#include "bacdef.h" -#include "mstpdef.h" -#include "dlmstp.h" +#include "bacnet/bacdef.h" +#include "bacnet/datalink/mstpdef.h" +#include "bacnet/datalink/dlmstp.h" struct mstp_port_struct_t { MSTP_RECEIVE_STATE receive_state; diff --git a/ports/pic18f6720/rs485.c b/ports/pic18f6720/rs485.c index 67e0d405..86fa51b7 100644 --- a/ports/pic18f6720/rs485.c +++ b/ports/pic18f6720/rs485.c @@ -31,9 +31,9 @@ #include #include #include "hardware.h" -#include "mstp.h" +#include "bacnet/datalink/mstp.h" #include "rs485.h" -#include "fifo.h" +#include "bacnet/basic/sys/fifo.h" /* public port info */ extern volatile struct mstp_port_struct_t MSTP_Port; diff --git a/ports/pic18f6720/rs485.h b/ports/pic18f6720/rs485.h index f0827deb..e8f064be 100644 --- a/ports/pic18f6720/rs485.h +++ b/ports/pic18f6720/rs485.h @@ -37,7 +37,7 @@ #define RS485_H #include -#include "mstp.h" +#include "bacnet/datalink/mstp.h" extern uint32_t RS485_Baud_Rate; diff --git a/ports/pic18f97j60/BACnet-Server.X/nbproject/Makefile-genesis.properties b/ports/pic18f97j60/BACnet-Server.X/nbproject/Makefile-genesis.properties index db24bb04..c635b02f 100644 --- a/ports/pic18f97j60/BACnet-Server.X/nbproject/Makefile-genesis.properties +++ b/ports/pic18f97j60/BACnet-Server.X/nbproject/Makefile-genesis.properties @@ -1,8 +1,8 @@ -# -#Mon May 30 09:28:30 CDT 2016 -default.com-microchip-mplab-nbide-toolchainC18-C18LanguageToolchain.md5=21ae92f54c0f89bc027339aedc19b7f9 -default.languagetoolchain.dir=C\:\\Program Files (x86)\\Microchip\\mplabc18\\v3.40\\bin -com-microchip-mplab-nbide-embedded-makeproject-MakeProject.md5=ef199adcc8f049579a105cca20571dcb -default.languagetoolchain.version=3.40 -host.platform=windows -conf.ids=default +# +#Mon May 30 09:28:30 CDT 2016 +default.com-microchip-mplab-nbide-toolchainC18-C18LanguageToolchain.md5=21ae92f54c0f89bc027339aedc19b7f9 +default.languagetoolchain.dir=C\:\\Program Files (x86)\\Microchip\\mplabc18\\v3.40\\bin +com-microchip-mplab-nbide-embedded-makeproject-MakeProject.md5=ef199adcc8f049579a105cca20571dcb +default.languagetoolchain.version=3.40 +host.platform=windows +conf.ids=default diff --git a/ports/pic18f97j60/BACnet-Server.X/nbproject/configurations.xml b/ports/pic18f97j60/BACnet-Server.X/nbproject/configurations.xml index 18b0ec6a..a3dbe89c 100644 --- a/ports/pic18f97j60/BACnet-Server.X/nbproject/configurations.xml +++ b/ports/pic18f97j60/BACnet-Server.X/nbproject/configurations.xml @@ -1,198 +1,198 @@ - - - - - ../stdbool.h - ../stdint.h - ../rs485.h - ../mstp.h - ../../../include/bits.h - ../../../include/abort.h - ../../../include/apdu.h - ../../../include/bacaddr.h - ../../../include/bacapp.h - ../../../include/bacdcode.h - ../../../include/bacdef.h - ../../../include/bacenum.h - ../../../include/bacerror.h - ../../../include/bacint.h - ../../../include/bacprop.h - ../../../include/bacreal.h - ../../../include/bacstr.h - ../../../include/bigend.h - ../../../include/config.h - ../hardware.h - - - - - ../../../src/abort.c - ../../../src/bacapp.c - ../../../src/bacdcode.c - ../../../src/bacerror.c - ../../../src/bacstr.c - ../../../src/crc.c - ../../../src/dcc.c - ../../../src/iam.c - ../../../src/rd.c - ../../../src/reject.c - ../../../src/rp.c - ../../../src/whois.c - ../../../demo/handler/h_dcc.c - ../../../demo/handler/h_rd.c - ../main.c - ../dlmstp.c - ../device.c - ../rs485.c - ../isr.c - ../../../src/datetime.c - ../../../demo/handler/txbuf.c - ../../../demo/handler/h_whois.c - ../mstp.c - ../bv.c - ../ai.c - ../bi.c - ../av.c - ../../../src/wp.c - ../../../demo/handler/h_npdu.c - ../../../demo/handler/s_iam.c - ../../../src/bacreal.c - ../../../src/bacint.c - ../../../src/npdu.c - ../apdu.c - ../../../demo/handler/noserv.c - ../../../src/fifo.c - ../../../demo/handler/h_rp.c - ../../../demo/handler/h_wp.c - ../../../src/bacaddr.c - - - Makefile - - - - ../ - - Makefile - - - - localhost - PIC18F97J60 - - - ICD3PlatformTool - C18 - - 3 - - - - - - - - false - - - - - false - - false - - false - false - false - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + ../stdbool.h + ../stdint.h + ../rs485.h + ../mstp.h + ../../../include/bits.h + ../../../include/abort.h + ../../../include/apdu.h + ../../../include/bacaddr.h + ../../../include/bacapp.h + ../../../include/bacdcode.h + ../../../include/bacdef.h + ../../../include/bacenum.h + ../../../include/bacerror.h + ../../../include/bacint.h + ../../../include/bacprop.h + ../../../include/bacreal.h + ../../../include/bacstr.h + ../../../include/bigend.h + ../../../include/config.h + ../hardware.h + + + + + ../../../src/abort.c + ../../../src/bacapp.c + ../../../src/bacdcode.c + ../../../src/bacerror.c + ../../../src/bacstr.c + ../../../src/crc.c + ../../../src/dcc.c + ../../../src/iam.c + ../../../src/rd.c + ../../../src/reject.c + ../../../src/rp.c + ../../../src/whois.c + ../../../demo/handler/h_dcc.c + ../../../demo/handler/h_rd.c + ../main.c + ../dlmstp.c + ../device.c + ../rs485.c + ../isr.c + ../../../src/datetime.c + ../../../demo/handler/txbuf.c + ../../../demo/handler/h_whois.c + ../mstp.c + ../bv.c + ../ai.c + ../bi.c + ../av.c + ../../../src/wp.c + ../../../demo/handler/h_npdu.c + ../../../demo/handler/s_iam.c + ../../../src/bacreal.c + ../../../src/bacint.c + ../../../src/npdu.c + ../apdu.c + ../../../demo/handler/noserv.c + ../../../src/fifo.c + ../../../demo/handler/h_rp.c + ../../../demo/handler/h_wp.c + ../../../src/bacaddr.c + + + Makefile + + + + ../ + + Makefile + + + + localhost + PIC18F97J60 + + + ICD3PlatformTool + C18 + + 3 + + + + + + + + false + + + + + false + + false + + false + false + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ports/pic18f97j60/BACnet-Server.X/nbproject/private/configurations.xml b/ports/pic18f97j60/BACnet-Server.X/nbproject/private/configurations.xml index 5fcfb04f..1102937f 100644 --- a/ports/pic18f97j60/BACnet-Server.X/nbproject/private/configurations.xml +++ b/ports/pic18f97j60/BACnet-Server.X/nbproject/private/configurations.xml @@ -1,25 +1,25 @@ - - - Makefile - 0 - - - - - - place holder 1 - place holder 2 - - - - - true - 0 - 0 - 0 - - - - - - + + + Makefile + 0 + + + + + + place holder 1 + place holder 2 + + + + + true + 0 + 0 + 0 + + + + + + diff --git a/ports/pic18f97j60/BACnet-Server.X/nbproject/private/private.xml b/ports/pic18f97j60/BACnet-Server.X/nbproject/private/private.xml index bf1ea206..b1a89dfe 100644 --- a/ports/pic18f97j60/BACnet-Server.X/nbproject/private/private.xml +++ b/ports/pic18f97j60/BACnet-Server.X/nbproject/private/private.xml @@ -1,11 +1,11 @@ - - - - - file:/D:/code/bacnet-stack/ports/pic18f97j60/main.c - file:/D:/code/bacnet-stack/ports/pic18f97j60/isr.c - file:/D:/code/bacnet-stack/ports/pic18f97j60/rs485.h - file:/D:/code/bacnet-stack/ports/pic18f97j60/rs485.c - file:/D:/code/bacnet-stack/ports/pic18f97j60/hardware.h - - + + + + + file:/D:/code/bacnet-stack/ports/pic18f97j60/main.c + file:/D:/code/bacnet-stack/ports/pic18f97j60/isr.c + file:/D:/code/bacnet-stack/ports/pic18f97j60/rs485.h + file:/D:/code/bacnet-stack/ports/pic18f97j60/rs485.c + file:/D:/code/bacnet-stack/ports/pic18f97j60/hardware.h + + diff --git a/ports/pic18f97j60/BACnet-Server.X/nbproject/project.xml b/ports/pic18f97j60/BACnet-Server.X/nbproject/project.xml index 6c3e07d6..b7fe3eff 100644 --- a/ports/pic18f97j60/BACnet-Server.X/nbproject/project.xml +++ b/ports/pic18f97j60/BACnet-Server.X/nbproject/project.xml @@ -1,16 +1,16 @@ - - - com.microchip.mplab.nbide.embedded.makeproject - - - BACnet-Server - e54ca906-513b-4f74-a23b-6b0204c4509a - 0 - c - - h - ISO-8859-1 - - - - + + + com.microchip.mplab.nbide.embedded.makeproject + + + BACnet-Server + e54ca906-513b-4f74-a23b-6b0204c4509a + 0 + c + + h + ISO-8859-1 + + + + diff --git a/ports/pic18f97j60/ai.c b/ports/pic18f97j60/ai.c index 35f5cea1..2d73e9e1 100644 --- a/ports/pic18f97j60/ai.c +++ b/ports/pic18f97j60/ai.c @@ -28,13 +28,13 @@ #include #include #include -#include "bacdef.h" -#include "bacdcode.h" -#include "bacenum.h" -#include "config.h" -#include "wp.h" -#include "rp.h" -#include "ai.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacenum.h" +#include "bacnet/config.h" +#include "bacnet/wp.h" +#include "bacnet/rp.h" +#include "bacnet/basic/object/ai.h" /* Analog Input = Photocell */ #define MAX_ANALOG_INPUTS 2 diff --git a/ports/pic18f97j60/apdu.c b/ports/pic18f97j60/apdu.c index 4e739e87..004ca63a 100644 --- a/ports/pic18f97j60/apdu.c +++ b/ports/pic18f97j60/apdu.c @@ -34,14 +34,14 @@ #include #include #include -#include "bits.h" -#include "bacdef.h" -#include "bacdcode.h" -#include "bacenum.h" -#include "dcc.h" -#include "handlers.h" +#include "bacnet/bits.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacenum.h" +#include "bacnet/dcc.h" +#include "bacnet/basic/services.h" /* me */ -#include "apdu.h" +#include "bacnet/apdu.h" uint16_t apdu_timeout( void) diff --git a/ports/pic18f97j60/av.c b/ports/pic18f97j60/av.c index 71885270..c77677df 100644 --- a/ports/pic18f97j60/av.c +++ b/ports/pic18f97j60/av.c @@ -28,14 +28,14 @@ #include #include #include -#include "bacdef.h" -#include "bacdcode.h" -#include "bacenum.h" -#include "bacapp.h" -#include "config.h" /* the custom stuff */ -#include "wp.h" -#include "rp.h" -#include "av.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacenum.h" +#include "bacnet/bacapp.h" +#include "bacnet/config.h" /* the custom stuff */ +#include "bacnet/wp.h" +#include "bacnet/rp.h" +#include "bacnet/basic/object/av.h" #define MAX_ANALOG_VALUES 4 diff --git a/ports/pic18f97j60/bi.c b/ports/pic18f97j60/bi.c index c389952c..86fe747e 100644 --- a/ports/pic18f97j60/bi.c +++ b/ports/pic18f97j60/bi.c @@ -28,13 +28,13 @@ #include #include #include -#include "bacdef.h" -#include "bacdcode.h" -#include "bacenum.h" -#include "config.h" -#include "wp.h" -#include "rp.h" -#include "bi.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacenum.h" +#include "bacnet/config.h" +#include "bacnet/wp.h" +#include "bacnet/rp.h" +#include "bacnet/basic/object/bi.h" #define MAX_BINARY_INPUTS 8 diff --git a/ports/pic18f97j60/bv.c b/ports/pic18f97j60/bv.c index 5c567774..a57f57e4 100644 --- a/ports/pic18f97j60/bv.c +++ b/ports/pic18f97j60/bv.c @@ -28,13 +28,13 @@ #include #include #include -#include "bacdef.h" -#include "bacdcode.h" -#include "bacenum.h" -#include "config.h" /* the custom stuff */ -#include "wp.h" -#include "rp.h" -#include "bv.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacenum.h" +#include "bacnet/config.h" /* the custom stuff */ +#include "bacnet/wp.h" +#include "bacnet/rp.h" +#include "bacnet/basic/object/bv.h" #define MAX_BINARY_VALUES 8 diff --git a/ports/pic18f97j60/device.c b/ports/pic18f97j60/device.c index 89f507b6..1e6f91ec 100644 --- a/ports/pic18f97j60/device.c +++ b/ports/pic18f97j60/device.c @@ -26,23 +26,23 @@ #include #include #include /* for memmove */ -#include "bacdef.h" -#include "bacdcode.h" -#include "bacstr.h" -#include "bacenum.h" -#include "config.h" /* the custom stuff */ -#include "apdu.h" -#include "dlmstp.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacstr.h" +#include "bacnet/bacenum.h" +#include "bacnet/config.h" /* the custom stuff */ +#include "bacnet/apdu.h" +#include "bacnet/datalink/dlmstp.h" #include "rs485.h" -#include "ai.h" -#include "av.h" -#include "bi.h" -#include "bv.h" -#include "rp.h" -#include "wp.h" -#include "dcc.h" -#include "version.h" -#include "device.h" /* me */ +#include "bacnet/basic/object/ai.h" +#include "bacnet/basic/object/av.h" +#include "bacnet/basic/object/bi.h" +#include "bacnet/basic/object/bv.h" +#include "bacnet/rp.h" +#include "bacnet/wp.h" +#include "bacnet/dcc.h" +#include "bacnet/version.h" +#include "bacnet/basic/object/device.h" /* me */ /* note: you really only need to define variables for properties that are writable or that may change. diff --git a/ports/pic18f97j60/dlmstp.c b/ports/pic18f97j60/dlmstp.c index 7877617c..1bf15ffd 100644 --- a/ports/pic18f97j60/dlmstp.c +++ b/ports/pic18f97j60/dlmstp.c @@ -29,12 +29,12 @@ #if PRINT_ENABLED #include #endif -#include "bacdef.h" -#include "mstp.h" -#include "dlmstp.h" +#include "bacnet/bacdef.h" +#include "bacnet/datalink/mstp.h" +#include "bacnet/datalink/dlmstp.h" #include "rs485.h" -#include "npdu.h" -#include "handlers.h" +#include "bacnet/npdu.h" +#include "bacnet/basic/services.h" /* Number of MS/TP Packets Rx/Tx */ uint16_t MSTP_Packets = 0; diff --git a/ports/pic18f97j60/dlmstp.h b/ports/pic18f97j60/dlmstp.h index 418d7d34..fc4e420f 100644 --- a/ports/pic18f97j60/dlmstp.h +++ b/ports/pic18f97j60/dlmstp.h @@ -38,8 +38,8 @@ #include #include #include -#include "bacdef.h" -#include "npdu.h" +#include "bacnet/bacdef.h" +#include "bacnet/npdu.h" /* defines specific to MS/TP */ #define MAX_HEADER (2+1+1+1+2+1) diff --git a/ports/pic18f97j60/isr.c b/ports/pic18f97j60/isr.c index 1b62e3fd..23554963 100644 --- a/ports/pic18f97j60/isr.c +++ b/ports/pic18f97j60/isr.c @@ -25,7 +25,7 @@ #include "stdint.h" #include "hardware.h" #include "rs485.h" -#include "dlmstp.h" +#include "bacnet/datalink/dlmstp.h" /* from main.c */ extern volatile uint8_t Milliseconds; diff --git a/ports/pic18f97j60/main.c b/ports/pic18f97j60/main.c index 73e865e9..41dce3a8 100644 --- a/ports/pic18f97j60/main.c +++ b/ports/pic18f97j60/main.c @@ -31,12 +31,12 @@ #include "stdint.h" #include "hardware.h" /* BACnet */ -#include "apdu.h" -#include "datalink.h" -#include "dcc.h" -#include "handlers.h" -#include "client.h" -#include "txbuf.h" +#include "bacnet/apdu.h" +#include "bacnet/datalink/datalink.h" +#include "bacnet/dcc.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/tsm/tsm.h" #include "rs485.h" /* chip configuration data */ diff --git a/ports/pic18f97j60/mstp.c b/ports/pic18f97j60/mstp.c index c36b9d1a..87f14752 100644 --- a/ports/pic18f97j60/mstp.c +++ b/ports/pic18f97j60/mstp.c @@ -49,14 +49,14 @@ #if PRINT_ENABLED #include #endif -#include "mstp.h" -#include "bytes.h" -#include "bits.h" +#include "bacnet/datalink/mstp.h" +#include "bacnet/bytes.h" +#include "bacnet/bits.h" #include "crc.h" -#include "bacaddr.h" +#include "bacnet/bacaddr.h" #include "rs485.h" #if PRINT_ENABLED -#include "mstptext.h" +#include "bacnet/datalink/mstptext.h" #endif /* debug print statements */ diff --git a/ports/pic18f97j60/mstp.h b/ports/pic18f97j60/mstp.h index 905cad51..a664f1b9 100644 --- a/ports/pic18f97j60/mstp.h +++ b/ports/pic18f97j60/mstp.h @@ -39,9 +39,9 @@ #include #include #include -#include "bacdef.h" -#include "mstpdef.h" -#include "dlmstp.h" +#include "bacnet/bacdef.h" +#include "bacnet/datalink/mstpdef.h" +#include "bacnet/datalink/dlmstp.h" struct mstp_port_struct_t { MSTP_RECEIVE_STATE receive_state; diff --git a/ports/pic18f97j60/rs485.c b/ports/pic18f97j60/rs485.c index 67e0d405..86fa51b7 100644 --- a/ports/pic18f97j60/rs485.c +++ b/ports/pic18f97j60/rs485.c @@ -31,9 +31,9 @@ #include #include #include "hardware.h" -#include "mstp.h" +#include "bacnet/datalink/mstp.h" #include "rs485.h" -#include "fifo.h" +#include "bacnet/basic/sys/fifo.h" /* public port info */ extern volatile struct mstp_port_struct_t MSTP_Port; diff --git a/ports/pic18f97j60/rs485.h b/ports/pic18f97j60/rs485.h index f0827deb..e8f064be 100644 --- a/ports/pic18f97j60/rs485.h +++ b/ports/pic18f97j60/rs485.h @@ -37,7 +37,7 @@ #define RS485_H #include -#include "mstp.h" +#include "bacnet/datalink/mstp.h" extern uint32_t RS485_Baud_Rate; diff --git a/ports/rtos32/bip-init.c b/ports/rtos32/bip-init.c deleted file mode 100644 index c8bd98d4..00000000 --- a/ports/rtos32/bip-init.c +++ /dev/null @@ -1,275 +0,0 @@ -/*####COPYRIGHTBEGIN#### - ------------------------------------------- - Copyright (C) 2005 Steve Karg - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to: - The Free Software Foundation, Inc. - 59 Temple Place - Suite 330 - Boston, MA 02111-1307, USA. - - As a special exception, if other files instantiate templates or - use macros or inline functions from this file, or you compile - this file and link it with other works to produce a work based - on this file, this file does not by itself cause the resulting - work to be covered by the GNU General Public License. However - the source code for this file must still be made available in - accordance with section (3) of the GNU General Public License. - - This exception does not invalidate any other reasons why a work - based on this file might be covered by the GNU General Public - License. - ------------------------------------------- -####COPYRIGHTEND####*/ - -#include /* for standard integer types uint8_t etc. */ -#include /* for the standard bool type. */ -#include "bacdcode.h" -#include "bip.h" - -static int interface = SOCKET_ERROR; /* SOCKET_ERROR means no open interface */ - -/*-----------------------------------*/ -static void Error( - const char *Msg) -{ - int Code = WSAGetLastError(); -#ifdef HOST - printf("%s, error code: %i\n", Msg, Code); -#else - printf("%s, error code: %s\n", Msg, xn_geterror_string(Code)); -#endif - exit(1); -} - -#ifndef HOST -/*-----------------------------------*/ -void InterfaceCleanup( - void) -{ - if (interface != SOCKET_ERROR) { - xn_interface_close(interface); - interface = SOCKET_ERROR; -#if DEVICE_ID == PRISM_PCMCIA_DEVICE - RTPCShutDown(); -#endif - } -} - -static void NetInitialize( - void) -/* initialize the TCP/IP stack */ -{ - int Result; - -#ifndef HOST - if (!RTKDebugVersion()) /* switch of all diagnostics and error messages of RTIP-32 */ - xn_callbacks()->cb_wr_screen_string_fnc = NULL; - -#ifdef RTUSB_VER - RTURegisterCallback(USBAX172); /* ax172 and ax772 drivers */ - RTURegisterCallback(USBAX772); - RTURegisterCallback(USBKeyboard); /* support USB keyboards */ - FindUSBControllers(); /* install USB host controllers */ - Sleep(2000); /* give the USB stack time to enumerate devices */ -#endif - -#ifdef DHCP - XN_REGISTER_DHCP_CLI() /* and optionally the DHCP client */ -#endif - Result = xn_rtip_init(); /* Initialize the RTIP stack */ - if (Result != 0) - Error("xn_rtip_init failed"); - - atexit(InterfaceCleanup); /* make sure the driver is shut down properly */ - RTCallDebugger(RT_DBG_CALLRESET, (DWORD) exit, 0); /* even if we get restarted by the debugger */ - - Result = BIND_DRIVER(MINOR_0); /* tell RTIP what Ethernet driver we want (see netcfg.h) */ - if (Result != 0) - Error("driver initialization failed"); - -#if DEVICE_ID == PRISM_PCMCIA_DEVICE - /* if this is a PCMCIA device, start the PCMCIA driver */ - if (RTPCInit(-1, 0, 2, NULL) == 0) - Error("No PCMCIA controller found"); -#endif - - /* Open the interface */ - interface = - xn_interface_open_config(DEVICE_ID, MINOR_0, ED_IO_ADD, ED_IRQ, - ED_MEM_ADD); - if (interface == SOCKET_ERROR) - Error("xn_interface_open_config failed"); - else { - struct _iface_info ii; -#ifdef BACDL_ETHERNET - BACNET_ADDRESS my_address; - unsigned i; -#endif - xn_interface_info(interface, &ii); - printf - ("Interface opened, MAC address: %02x-%02x-%02x-%02x-%02x-%02x\n", - ii.my_ethernet_address[0], ii.my_ethernet_address[1], - ii.my_ethernet_address[2], ii.my_ethernet_address[3], - ii.my_ethernet_address[4], ii.my_ethernet_address[5]); -#ifdef BACDL_ETHERNET - for (i = 0; i < 6; i++) { - my_address.mac[i] = ii.my_ethernet_address[i]; - } - ethernet_set_my_address(&my_address); -#endif - } - -#if DEVICE_ID == PRISM_PCMCIA_DEVICE || DEVICE_ID == PRISM_DEVICE - xn_wlan_setup(interface, /* iface_no: value returned by xn_interface_open_config() */ - "network name", /* SSID : network name set in the access point */ - "station name", /* Name : name of this node */ - 0, /* Channel : 0 for access points, 1..14 for ad-hoc */ - 0, /* KeyIndex: 0 .. 3 */ - "12345", /* WEP Key : key to use (5 or 13 bytes) */ - 0); /* Flags : see manual and Wlanapi.h for details */ - Sleep(1000); /* wireless devices need a little time before they can be used */ -#endif /* WLAN device */ - -#if defined(AUTO_IP) /* use xn_autoip() to get an IP address */ - Result = xn_autoip(interface, MinIP, MaxIP, NetMask, TargetIP); - if (Result == SOCKET_ERROR) - Error("xn_autoip failed"); - else { - printf("Auto-assigned IP address %i.%i.%i.%i\n", TargetIP[0], - TargetIP[1], TargetIP[2], TargetIP[3]); - /* define default gateway and DNS server */ - xn_rt_add(RT_DEFAULT, ip_ffaddr, DefaultGateway, 1, interface, RT_INF); - xn_set_server_list((DWORD *) DNSServer, 1); - } -#elif defined(DHCP) /* use DHCP */ - { - DHCP_param param[] = { {SUBNET_MASK, 1} - , {DNS_OP, 1} - , {ROUTER_OPTION, 1} - }; - DHCP_session DS; - DHCP_conf DC; - - xn_init_dhcp_conf(&DC); /* load default DHCP options */ - DC.plist = param; /* add MASK, DNS, and gateway options */ - DC.plist_entries = sizeof(param) / sizeof(param[0]); - printf("Contacting DHCP server, please wait...\n"); - Result = xn_dhcp(interface, &DS, &DC); /* contact DHCP server */ - if (Result == SOCKET_ERROR) - Error("xn_dhcp failed"); - memcpy(TargetIP, DS.client_ip, 4); - printf("My IP address is: %i.%i.%i.%i\n", TargetIP[0], TargetIP[1], - TargetIP[2], TargetIP[3]); - } -#else - /* Set the IP address and interface */ - printf("Using static IP address %i.%i.%i.%i\n", TargetIP[0], TargetIP[1], - TargetIP[2], TargetIP[3]); - Result = xn_set_ip(interface, TargetIP, NetMask); - /* define default gateway and DNS server */ - xn_rt_add(RT_DEFAULT, ip_ffaddr, DefaultGateway, 1, interface, RT_INF); - xn_set_server_list((DWORD *) DNSServer, 1); -#endif - -#else /* HOST defined, run on Windows */ - - WSADATA wd; - Result = WSAStartup(0x0101, &wd); - -#endif - - if (Result != 0) - Error("TCP/IP stack initialization failed"); -} -#endif - -/****************************************************************** -* DESCRIPTION: Converts the byte stored address to an inet address -* RETURN: none -* ALGORITHM: none -* NOTES: none -******************************************************************/ -static void RTIP_To_Network_Address( - BYTE * octet_address, - struct in_addr *addr) -{ - uint32_t ip_address = 0; /* for decoding the subnet mask */ - - decode_unsigned32(octet_address, &ip_address); - addr->s_addr = htonl(ip_address); - - return; -} - -static void set_broadcast_address( - uint32_t net_address) -{ - long broadcast_address = 0; - long mask = 0; - - /* Note: sometimes INADDR_BROADCAST does not let me get - any unicast messages. Not sure why... */ -#if USE_INADDR - (void) net_address; - bip_set_broadcast_addr(INADDR_BROADCAST); -#else - if (IN_CLASSA(ntohl(net_address))) - broadcast_address = - (ntohl(net_address) & ~IN_CLASSA_HOST) | IN_CLASSA_HOST; - else if (IN_CLASSB(ntohl(net_address))) - broadcast_address = - (ntohl(net_address) & ~IN_CLASSB_HOST) | IN_CLASSB_HOST; - else if (IN_CLASSC(ntohl(net_address))) - broadcast_address = - (ntohl(net_address) & ~IN_CLASSC_HOST) | IN_CLASSC_HOST; - else if (IN_CLASSD(ntohl(net_address))) - broadcast_address = - (ntohl(net_address) & ~IN_CLASSD_HOST) | IN_CLASSD_HOST; - else - broadcast_address = INADDR_BROADCAST; - bip_set_broadcast_addr(htonl(broadcast_address)); -#endif -} - -bool bip_init( - char *ifname) -{ - int rv = 0; /* return from socket lib calls */ - struct sockaddr_in sin = { -1 }; - int value = 1; - int sock_fd = -1; - struct in_addr my_addr; - - (void) ifname; - - NetInitialize(); - - RTIP_To_Network_Address(TargetIP, &my_addr); - bip_set_addr(my_addr.s_addr); - set_broadcast_address(my_addr.s_addr); - bip_set_port(htons((0xBAC0)); - /* assumes that the driver has already been initialized */ - sock_fd = socket(AF_INET, SOCK_DGRAM, IPROTO_UDP); - bip_set_socket(sock_fd); - if (sock_fd < 0) - return false; - /* bind the socket to the local port number and IP address */ - sin.sin_family = AF_INET; sin.sin_addr.s_addr = htonl(INADDR_ANY); - sin.sin_port = bip_get_port(); memset(&(sin.sin_zero), '\0', 8); - rv = - bind(sock_fd, (const struct sockaddr *) &sin, sizeof(struct sockaddr)); - if (rv < 0) { - close(sock_fd); bip_set_socket(-1); return false;} - - return true;} diff --git a/ports/rtos32/dlmstp.c b/ports/rtos32/dlmstp.c deleted file mode 100644 index 9108a7ac..00000000 --- a/ports/rtos32/dlmstp.c +++ /dev/null @@ -1,280 +0,0 @@ -/************************************************************************** -* -* Copyright (C) 2006 Steve Karg -* -* Permission is hereby granted, free of charge, to any person obtaining -* a copy of this software and associated documentation files (the -* "Software"), to deal in the Software without restriction, including -* without limitation the rights to use, copy, modify, merge, publish, -* distribute, sublicense, and/or sell copies of the Software, and to -* permit persons to whom the Software is furnished to do so, subject to -* the following conditions: -* -* The above copyright notice and this permission notice shall be included -* in all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -* -*********************************************************************/ -#include -#include -#include -#include -#if PRINT_ENABLED -#include -#endif -#include "bacdef.h" -#include "mstp.h" -#include "dlmstp.h" -#include "rs485.h" -#include "npdu.h" - -/* receive buffer */ -static DLMSTP_PACKET Receive_Buffer; -/* temp buffer for NPDU insertion */ -static uint8_t PDU_Buffer[MAX_MPDU]; -/* local MS/TP port data */ -static volatile struct mstp_port_struct_t MSTP_Port; - -void dlmstp_init( - char *ifname) -{ - (void) ifname; - /* initialize buffer */ - Receive_Buffer.ready = false; - Receive_Buffer.pdu_len = 0; - /* initialize hardware */ - RS485_Initialize(); - MSTP_Init(&MSTP_Port, MSTP_Port.This_Station); -} - -void dlmstp_cleanup( - void) -{ - /* nothing to do for static buffers */ -} - -/* returns number of bytes sent on success, zero on failure */ -int dlmstp_send_pdu( - BACNET_ADDRESS * dest, /* destination address */ - BACNET_NPDU_DATA * npdu_data, /* network information */ - uint8_t * pdu, /* any data to be sent - may be null */ - unsigned pdu_len) -{ /* number of bytes of data */ - int bytes_sent = 0; - uint8_t frame_type = 0; - uint8_t destination = 0; /* destination address */ - BACNET_ADDRESS src; - unsigned mtu_len = 0; - - if (MSTP_Port.TxReady == false) { - if (npdu_data->confirmed_message) { - MSTP_Port.TxFrameType = FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY; - } else { - MSTP_Port.TxFrameType = FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY; - } - /* load destination MAC address */ - if (dest->mac_len) { - destination = dest->mac[0]; - } else { - /* mac_len = 0 is a broadcast address */ - destination = MSTP_BROADCAST_ADDRESS; - } - /* header len */ - mtu_len = MAX_HEADER - 2 /* data crc */ ; - if ((MAX_HEADER + pdu_len) > MAX_MPDU) { -#if PRINT_ENABLED - fprintf(stderr, "mstp: PDU is too big to send!\n"); -#endif - return -4; - } - memmove(&PDU_Buffer[mtu_len], pdu, pdu_len); - mtu_len += pdu_len; - bytes_sent = - MSTP_Create_Frame((uint8_t *) & MSTP_Port.TxBuffer[0], - sizeof(MSTP_Port.TxBuffer), MSTP_Port.TxFrameType, destination, - MSTP_Port.This_Station, &PDU_Buffer[0], mtu_len); - MSTP_Port.TxLength = bytes_sent; - MSTP_Port.TxReady = true; - } - - return bytes_sent; -} - -/* called about once a millisecond */ -void dlmstp_millisecond_timer( - void) -{ - MSTP_Millisecond_Timer(&MSTP_Port); -} - -/* returns the number of octets in the PDU, or zero on failure */ -/* This function is expecting to be polled. */ -uint16_t dlmstp_receive( - BACNET_ADDRESS * src, /* source address */ - uint8_t * pdu, /* PDU data */ - uint16_t max_pdu, /* amount of space available in the PDU */ - unsigned timeout) -{ - uint16_t pdu_len = 0; - - (void) timeout; - /* only do receive state machine while we don't have a frame */ - if ((MSTP_Port.ReceivedValidFrame == false) && - (MSTP_Port.ReceivedInvalidFrame == false)) { - RS485_Check_UART_Data(&MSTP_Port); - MSTP_Receive_Frame_FSM(&MSTP_Port); - } - /* only do master state machine while rx is idle */ - if (MSTP_Port.receive_state == MSTP_RECEIVE_STATE_IDLE) { - if (This_Station <= DEFAULT_MAX_MASTER) { - while (MSTP_Master_Node_FSM(&MSTP_Port)) { - }; - } - } - /* see if there is a packet available */ - if (Receive_Buffer.ready) { - memmove(src, &Receive_Buffer.address, sizeof(Receive_Buffer.address)); - pdu_len = Receive_Buffer.pdu_len; - memmove(&pdu[0], &Receive_Buffer.pdu[0], max_pdu); - Receive_Buffer.ready = false; - } - - return pdu_len; -} - -void dlmstp_fill_bacnet_address( - BACNET_ADDRESS * src, - uint8_t mstp_address) -{ - int i = 0; - - if (mstp_address == MSTP_BROADCAST_ADDRESS) { - /* mac_len = 0 if broadcast address */ - src->mac_len = 0; - src->mac[0] = 0; - } else { - src->mac_len = 1; - src->mac[0] = mstp_address; - } - /* fill with 0's starting with index 1; index 0 filled above */ - for (i = 1; i < MAX_MAC_LEN; i++) { - src->mac[i] = 0; - } - src->net = 0; - src->len = 0; - for (i = 0; i < MAX_MAC_LEN; i++) { - src->adr[i] = 0; - } -} - -/* for the MS/TP state machine to use for putting received data */ -uint16_t dlmstp_put_receive( - uint8_t src, /* source MS/TP address */ - uint8_t * pdu, /* PDU data */ - uint16_t pdu_len) -{ - if (Receive_Buffer.ready) { - /* FIXME: what to do when we miss a message? */ - pdu_len = 0; - } else if (pdu_len < sizeof(Receive_Buffer.pdu)) { - dlmstp_fill_bacnet_address(&Receive_Buffer.address, src); - Receive_Buffer.pdu_len = pdu_len; - memmove(Receive_Buffer.pdu, pdu, pdu_len); - Receive_Buffer.ready = true; - } else { - /* FIXME: message too large? */ - pdu_len = 0; - } - - return pdu_len; -} - -void dlmstp_set_my_address( - uint8_t mac_address) -{ - /* FIXME: Master Nodes can only have address 1-127 */ - MSTP_Port.This_Station = mac_address; - - return; -} - -/* This parameter represents the value of the Max_Info_Frames property of */ -/* the node's Device object. The value of Max_Info_Frames specifies the */ -/* maximum number of information frames the node may send before it must */ -/* pass the token. Max_Info_Frames may have different values on different */ -/* nodes. This may be used to allocate more or less of the available link */ -/* bandwidth to particular nodes. If Max_Info_Frames is not writable in a */ -/* node, its value shall be 1. */ -void dlmstp_set_max_info_frames( - unsigned max_info_frames) -{ - MSTP_Port.Nmax_info_frames = max_info_frames; - - return; -} - -unsigned dlmstp_max_info_frames( - void) -{ - return MSTP_Port.Nmax_info_frames; -} - -/* This parameter represents the value of the Max_Master property of the */ -/* node's Device object. The value of Max_Master specifies the highest */ -/* allowable address for master nodes. The value of Max_Master shall be */ -/* less than or equal to 127. If Max_Master is not writable in a node, */ -/* its value shall be 127. */ -void dlmstp_set_max_master( - uint8_t max_master) -{ - MSTP_Port.Nmax_master = max_master; - - return; -} - -uint8_t dlmstp_max_master( - void) -{ - return MSTP_Port.Nmax_master; -} - -void dlmstp_get_my_address( - BACNET_ADDRESS * my_address) -{ - int i = 0; /* counter */ - - my_address->mac_len = 1; - my_address->mac[0] = MSTP_Port.This_Station; - my_address->net = 0; /* local only, no routing */ - my_address->len = 0; - for (i = 0; i < MAX_MAC_LEN; i++) { - my_address->adr[i] = 0; - } - - return; -} - -void dlmstp_get_broadcast_address( - BACNET_ADDRESS * dest) -{ /* destination address */ - int i = 0; /* counter */ - - if (dest) { - dest->mac_len = 1; - dest->mac[0] = MSTP_BROADCAST_ADDRESS; - dest->net = BACNET_BROADCAST_NETWORK; - dest->len = 0; /* len=0 denotes broadcast address */ - for (i = 0; i < MAX_MAC_LEN; i++) { - dest->adr[i] = 0; - } - } - - return; -} diff --git a/ports/rtos32/ethernet.c b/ports/rtos32/ethernet.c deleted file mode 100644 index bba30f45..00000000 --- a/ports/rtos32/ethernet.c +++ /dev/null @@ -1,345 +0,0 @@ -/************************************************************************** -* -* Copyright (C) 2005 Steve Karg -* -* Permission is hereby granted, free of charge, to any person obtaining -* a copy of this software and associated documentation files (the -* "Software"), to deal in the Software without restriction, including -* without limitation the rights to use, copy, modify, merge, publish, -* distribute, sublicense, and/or sell copies of the Software, and to -* permit persons to whom the Software is furnished to do so, subject to -* the following conditions: -* -* The above copyright notice and this permission notice shall be included -* in all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -* -*********************************************************************/ - -#include /* for standard integer types uint8_t etc. */ -#include /* for the standard bool type. */ -#include /* for the standard bool type. */ -#include /* for the standard bool type. */ -#include -#include -#include -#include -#include -#include "ethernet.h" -#include "bacdcode.h" -#include "npdu.h" - -/* commonly used comparison address for ethernet */ -uint8_t Ethernet_Broadcast[MAX_MAC_LEN] = - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; -/* commonly used empty address for ethernet quick compare */ -uint8_t Ethernet_Empty_MAC[MAX_MAC_LEN] = { 0, 0, 0, 0, 0, 0 }; - -/* my local device data - MAC address */ -uint8_t Ethernet_MAC_Address[MAX_MAC_LEN] = { 0, 0, 0, 0, 0, 0 }; - -static SOCKET Ethernet_Socket = -1; -/* used for binding 802.2 */ -static struct sockaddr Ethernet_Address = { 0 }; - -bool ethernet_valid( - void) -{ - return (Ethernet_Socket != -1); -} - -void ethernet_cleanup( - void) -{ - if (ethernet_valid()) - closesocket(Ethernet_Socket); - Ethernet_Socket = -1; - - return; -} - -bool ethernet_init( - char *interface_name) -{ - int value = 1; - - (void) interface_name; - /* setup the socket */ - Ethernet_Socket = socket(AF_INET, SOCK_RAW, 0); - /*Ethernet_Socket = socket(AF_INET, SOCK_STREAM, 0); */ - if (Ethernet_Socket < 0) - fprintf(stderr, "ethernet: failed to bind to socket!\r\n"); - Ethernet_Address.sa_family = AF_INET; - memset(Ethernet_Address.sa_data, 0, sizeof(Ethernet_Address.sa_data)); - if (bind(Ethernet_Socket, &Ethernet_Address, - sizeof(Ethernet_Address)) == SOCKET_ERROR) - fprintf(stderr, "ethernet: failed to bind to socket!\r\n"); - /*setsockopt(Ethernet_Socket,SOL_SOCKET,SO_802_2,(char *)&value,sizeof(value)); */ - - return ethernet_valid(); -} - -/* function to send a packet out the 802.2 socket */ -/* returns bytes sent on success, negative number on failure */ -int ethernet_send( - BACNET_ADDRESS * dest, /* destination address */ - BACNET_ADDRESS * src, /* source address */ - BACNET_NPDU_DATA * npdu_data, /* network information */ - uint8_t * pdu, /* any data to be sent - may be null */ - unsigned pdu_len) -{ /* number of bytes of data */ - int bytes = 0; - uint8_t mtu[MAX_MPDU] = { 0 }; - int mtu_len = 0; - int i = 0; - - (void) npdu_data; - /* don't waste time if the socket is not valid */ - if (Ethernet_Socket < 0) { - fprintf(stderr, "ethernet: 802.2 socket is invalid!\n"); - return -1; - } - /* load destination ethernet MAC address */ - if (dest->mac_len == 6) { - for (i = 0; i < 6; i++) { - mtu[mtu_len] = dest->mac[i]; - mtu_len++; - } - } else { - fprintf(stderr, "ethernet: invalid destination MAC address!\n"); - return -2; - } - - /* load source ethernet MAC address */ - if (src->mac_len == 6) { - for (i = 0; i < 6; i++) { - mtu[mtu_len] = src->mac[i]; - mtu_len++; - } - } else { - fprintf(stderr, "ethernet: invalid source MAC address!\n"); - return -3; - } - if ((14 + 3 + pdu_len) > MAX_MPDU) { - fprintf(stderr, "ethernet: PDU is too big to send!\n"); - return -4; - } - /* packet length */ - mtu_len += encode_unsigned16(&mtu[12], 3 /*DSAP,SSAP,LLC */ + pdu_len); - /* Logical PDU portion */ - mtu[mtu_len++] = 0x82; /* DSAP for BACnet */ - mtu[mtu_len++] = 0x82; /* SSAP for BACnet */ - mtu[mtu_len++] = 0x03; /* Control byte in header */ - mtu_len = 17; - if ((mtu_len + pdu_len) > MAX_MPDU) { - fprintf(stderr, "ethernet: PDU is too big to send!\n"); - return -4; - } - memcpy(&mtu[mtu_len], pdu, pdu_len); - mtu_len += pdu_len; - /* packet length - only the logical portion, not the address */ - encode_unsigned16(&mtu[12], 3 + pdu_len); - - /* Send the packet */ - bytes = send(Ethernet_Socket, (const char *) &mtu, mtu_len, 0); - /* did it get sent? */ - if (bytes < 0) - fprintf(stderr, "ethernet: Error sending packet: %s\n", - strerror(errno)); - - return bytes; -} - -/* function to send a packet out the 802.2 socket */ -/* returns bytes sent on success, negative number on failure */ -int ethernet_send_pdu( - BACNET_ADDRESS * dest, /* destination address */ - BACNET_NPDU_DATA * npdu_data, /* network information */ - uint8_t * pdu, /* any data to be sent - may be null */ - unsigned pdu_len) -{ /* number of bytes of data */ - int i = 0; /* counter */ - BACNET_ADDRESS src = { 0 }; /* source address */ - - for (i = 0; i < 6; i++) { - src.mac[i] = Ethernet_MAC_Address[i]; - src.mac_len++; - } - - /* FIXME: npdu_data? */ - /* function to send a packet out the 802.2 socket */ - /* returns 1 on success, 0 on failure */ - return ethernet_send(dest, /* destination address */ - &src, /* source address */ - npdu_data, pdu, /* any data to be sent - may be null */ - pdu_len); /* number of bytes of data */ -} - -/* receives an 802.2 framed packet */ -/* returns the number of octets in the PDU, or zero on failure */ -uint16_t ethernet_receive( - BACNET_ADDRESS * src, /* source address */ - uint8_t * pdu, /* PDU data */ - uint16_t max_pdu, /* amount of space available in the PDU */ - unsigned timeout) -{ /* number of milliseconds to wait for a packet */ - int received_bytes; - uint8_t buf[MAX_MPDU] = { 0 }; /* data */ - uint16_t pdu_len = 0; /* return value */ - fd_set read_fds; - int max; - struct timeval select_timeout; - - /* Make sure the socket is open */ - if (Ethernet_Socket <= 0) - return 0; - - /* we could just use a non-blocking socket, but that consumes all - the CPU time. We can use a timeout; it is only supported as - a select. */ - if (timeout >= 1000) { - select_timeout.tv_sec = timeout / 1000; - select_timeout.tv_usec = - 1000 * (timeout - select_timeout.tv_sec * 1000); - } else { - select_timeout.tv_sec = 0; - select_timeout.tv_usec = 1000 * timeout; - } - FD_ZERO(&read_fds); - FD_SET(Ethernet_Socket, &read_fds); - max = Ethernet_Socket; - - if (select(max + 1, &read_fds, NULL, NULL, &select_timeout) > 0) - received_bytes = recv(Ethernet_Socket, (char *) &buf[0], MAX_MPDU, 0); - else - return 0; - - /* See if there is a problem */ - if (received_bytes < 0) { - /* EAGAIN Non-blocking I/O has been selected */ - /* using O_NONBLOCK and no data */ - /* was immediately available for reading. */ - if (errno != EAGAIN) - fprintf(stderr, "ethernet: Read error in receiving packet: %s\n", - strerror(errno)); - return 0; - } - - if (received_bytes == 0) - return 0; - - /* the signature of an 802.2 BACnet packet */ - if ((buf[14] != 0x82) && (buf[15] != 0x82)) { - /*fprintf(stderr,"ethernet: Non-BACnet packet\n"); */ - return 0; - } - /* copy the source address */ - src->mac_len = 6; - memmove(src->mac, &buf[6], 6); - - /* check destination address for when */ - /* the Ethernet card is in promiscious mode */ - if ((memcmp(&buf[0], Ethernet_MAC_Address, 6) != 0) - && (memcmp(&buf[0], Ethernet_Broadcast, 6) != 0)) { - /*fprintf(stderr, "ethernet: This packet isn't for us\n"); */ - return 0; - } - - (void) decode_unsigned16(&buf[12], &pdu_len); - pdu_len -= 3 /* DSAP, SSAP, LLC Control */ ; - /* copy the buffer into the PDU */ - if (pdu_len < max_pdu) - memmove(&pdu[0], &buf[17], pdu_len); - /* ignore packets that are too large */ - /* client should check my max apdu first */ - else - pdu_len = 0; - - return pdu_len; -} - -void ethernet_get_my_address( - BACNET_ADDRESS * my_address) -{ - int i = 0; - - my_address->mac_len = 0; - for (i = 0; i < 6; i++) { - my_address->mac[i] = Ethernet_MAC_Address[i]; - my_address->mac_len++; - } - my_address->net = 0; /* local only, no routing */ - my_address->len = 0; - for (i = 0; i < MAX_MAC_LEN; i++) { - my_address->adr[i] = 0; - } - - return; -} - -void ethernet_set_my_address( - BACNET_ADDRESS * my_address) -{ - int i = 0; - - for (i = 0; i < 6; i++) { - Ethernet_MAC_Address[i] = my_address->mac[i]; - } - - return; -} - -void ethernet_get_broadcast_address( - BACNET_ADDRESS * dest) -{ /* destination address */ - int i = 0; /* counter */ - - if (dest) { - for (i = 0; i < 6; i++) { - dest->mac[i] = Ethernet_Broadcast[i]; - } - dest->mac_len = 6; - dest->net = BACNET_BROADCAST_NETWORK; - dest->len = 0; /* denotes broadcast address */ - for (i = 0; i < MAX_MAC_LEN; i++) { - dest->adr[i] = 0; - } - } - - return; -} - -void ethernet_debug_address( - const char *info, - BACNET_ADDRESS * dest) -{ - int i = 0; /* counter */ - - if (info) - fprintf(stderr, "%s", info); - if (dest) { - fprintf(stderr, "Address:\n"); - fprintf(stderr, " MAC Length=%d\n", dest->mac_len); - fprintf(stderr, " MAC Address="); - for (i = 0; i < MAX_MAC_LEN; i++) { - fprintf(stderr, "%02X ", (unsigned) dest->mac[i]); - } - fprintf(stderr, "\n"); - fprintf(stderr, " Net=%hu\n", dest->net); - fprintf(stderr, " Len=%d\n", dest->len); - fprintf(stderr, " Adr="); - for (i = 0; i < MAX_MAC_LEN; i++) { - fprintf(stderr, "%02X ", (unsigned) dest->adr[i]); - } - fprintf(stderr, "\n"); - } - - return; -} diff --git a/ports/rtos32/hardware.cfg b/ports/rtos32/hardware.cfg deleted file mode 100644 index f85c1eb9..00000000 --- a/ports/rtos32/hardware.cfg +++ /dev/null @@ -1,24 +0,0 @@ -// * The target computer is IBM-PC-AT compatible. -// * There is a minimum of 4 MB of RAM installed. - -#ifdef DEBUGDOS - Region RealModeVectors 0 1k RAM NoAccess // interrupt vectors - Region BIOSDataArea 1k 3k RAM ReadOnly // BIOS data area - Region DOSMem 4k 252k RAM - Region LowMem 256k 256k RAM -#else - Region = RealModeVectors 0, 4k, RAM, NoAccess // interrupt vectors -// note: locate only has 4k granularity so the 0-1k will be readonly -// Region = RealModeVectors 0, 1k, RAM, NoAccess // interrupt vectors -// Region = BIOSDataArea 1k, 3k, RAM, ReadOnly // BIOS data area - Region = LowMem 4k, 508k, RAM, Assign // Conventional memory -#endif -Region = MoreLowMem 512k, 128k, RAM, Assign // Reserved BIOS ext -Region = MonoText B0000h 4k, Device, ReadWrite // Mono text video mem -Region = ColorText B8000h, 4k, Device, ReadWrite // Text mode video ram -Region = DiskOnChip D0000h, 8k, Device, ReadWrite // Driver Ampro Card -Region = DiskOnChip1 E8000h, 32k, Device, ReadWrite // Driver WinSys Card -Region = HighMem 1M, 3M, RAM, Assign // 3mb ext mem on target -Virtual HeapMem 1G -Virtual StackMem 2G -Virtual ProgMem 3G diff --git a/ports/rtos32/init.c b/ports/rtos32/init.c deleted file mode 100644 index d4319d71..00000000 --- a/ports/rtos32/init.c +++ /dev/null @@ -1,128 +0,0 @@ -/************************************************************************** -* -* Copyright (C) 2005 Steve Karg -* -* Permission is hereby granted, free of charge, to any person obtaining -* a copy of this software and associated documentation files (the -* "Software"), to deal in the Software without restriction, including -* without limitation the rights to use, copy, modify, merge, publish, -* distribute, sublicense, and/or sell copies of the Software, and to -* permit persons to whom the Software is furnished to do so, subject to -* the following conditions: -* -* The above copyright notice and this permission notice shall be included -* in all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -* -*********************************************************************/ - -#include -#include -#include - -extern void RTEmuInit( - void); - -#ifdef _MSC_VER -#define VOIDEXPORT _declspec(dllexport) void __cdecl -#else -#define VOIDEXPORT void __export __cdecl -#endif - -/* DISK SYSTEM */ -#ifdef DOC /* include DiskOnChip driver */ -#include -#define RTF_MAX_FILES 16 /* support for more open files (default is 8) */ -#define RTF_BUFFERS_IN_BSS /* we do not need file I/O before the run-time */ -#include /* system is initialized */ - - /*#define READ_HEAD_BUFFER_SIZE 2048+4 */ - - /*static BYTE ReadAheadBuffer[READ_HEAD_BUFFER_SIZE]; */ - -static RTFDrvFLPYData FLPYDriveAData = { 0 }; -static RTFDrvDOCData DOCDriveData = { 0 }; -static RTFDrvIDEData IDEDriveData = { 0 }; - -RTFDevice RTFDeviceList[] = { - /* type,number,flags,driver,driverdata */ - {RTF_DEVICE_FLOPPY, 0, 0, &RTFDrvFloppy, &FLPYDriveAData}, - {RTF_DEVICE_FDISK, 0, 0, &RTFDrvDOC, &DOCDriveData}, - {RTF_DEVICE_FDISK, 0, 0, &RTFDrvIDE, &IDEDriveData}, - {0, 0, 0, NULL, NULL} -}; -#endif -/* END OF DISK SYSTEM */ - -/* RTTarget only defines 64 Win32 handles, which are not enough for BACstac */ -/* the following code is from the RTTarget manual, page 106 */ -#define MAXHANDLES 1024 -#define MAXOBJECTS 1024 -#define MAXTYPES 32 - -RTW32Handle RTHandleTable[MAXHANDLES] = { {0} }; - -int RTHandleCount = MAXHANDLES; - -RTW32Object RTObjectTable[MAXOBJECTS] = { {0} }; - -int RTObjectCount = MAXOBJECTS; - -RTW32Types RTTypeTable[MAXTYPES] = { {0} }; - -int RTTypeCount = MAXTYPES; - -#if 0 -/* We can embed some files in the RTB file, like a binary - file used for configuring a remote device, using - 'Locate File filename HighMem' in the config (.CFG) file. - However, the default setup for RTFiles and RTTarget - doesn't include the RAM files, so we need to specify - that here, as well as the LPT, console, and FAT. - From RTFiles-32 manual, ch. 7, "Using RTFiles-32 with - RTTarget-32" */ -RTFileSystem Console = { RT_FS_CONSOLE, 0, 0, &RTConsoleFileSystem }; - -RTFileSystem LPTFiles = { RT_FS_LPT_DEVICE, 0, 0, &RTLPTFileSystem }; - -/* logical drive Z: can be used to access the RAM drive */ -RTFileSystem RAMFiles = { RT_FS_FILE, 1 << ('Z' - 'A'), 0, &RTRAMFileSystem }; - -/* logical drive A: through D: are reserved for FAT */ -RTFileSystem FATFiles = - { RT_FS_FILE | RT_FS_IS_DEFAULT, 0x0F, 0x03, &RTFilesFileSystem }; - -RTFileSystem *RTFileSystemList[] = { - &Console, - &LPTFiles, - &RAMFiles, - &FATFiles, - NULL, -}; -#endif - -/*-----------------------------------*/ -VOIDEXPORT Init( - void) -{ - (void) RTSetFlags(RT_MM_VIRTUAL, 1); /* this is the better method */ - (void) RTCMOSExtendHeap(); /* get as much memory as we can */ - RTCMOSSetSystemTime(); /* get the right date and time */ - RTEmuInit(); /* set up floating point emulation */ - /* pizza - RTHaltCPL3 appears to cause problems with file handling */ - /*RTIdleHandler = (void RTTAPI *)RTHaltCPL3; // low power when idle */ - /* not needed with pre-emptive */ - /*RTKTimeSlice(2); // allow same priority task switch */ - RTKConfig.Flags |= RF_PREEMPTIVE; /* preemptive multitasking */ - RTKConfig.Flags |= RF_WIN32MUTEX_MUTEX; /* Win32 mutexes are RTK32 mutexes */ - RTKConfig.Flags |= RF_FPCONTEXT; /* saves floating point context for tasks */ - RTKConfig.HookedIRQs |= 1 << 1; /* hook the keyboard IRQ */ - RTKConfig.DefaultTaskStackSize = 1024 * 8; /* for Win32 task stacks req = 0 */ -} diff --git a/ports/rtos32/main.c b/ports/rtos32/main.c deleted file mode 100644 index ae452279..00000000 --- a/ports/rtos32/main.c +++ /dev/null @@ -1,168 +0,0 @@ -/************************************************************************** -* -* Copyright (C) 2005 Steve Karg -* -* Permission is hereby granted, free of charge, to any person obtaining -* a copy of this software and associated documentation files (the -* "Software"), to deal in the Software without restriction, including -* without limitation the rights to use, copy, modify, merge, publish, -* distribute, sublicense, and/or sell copies of the Software, and to -* permit persons to whom the Software is furnished to do so, subject to -* the following conditions: -* -* The above copyright notice and this permission notice shall be included -* in all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -* -*********************************************************************/ - -/* This is one way to use the embedded BACnet stack under RTOS-32 */ -/* compiled with Borland C++ 5.02 */ -#include -#include -#include -#include /* for kbhit */ -#include "config.h" -#include "bacdef.h" -#include "npdu.h" -#include "apdu.h" -#include "device.h" -#include "handlers.h" -#include "datalink.h" -#include "iam.h" -#include "txbuf.h" - -/* RTOS-32 */ -#include "rtkernel.h" -#if defined(RTK32_VER) -#define _USER32_ -#define _KERNEL32_ -#include -#include /* for RTCMOSSetSystemTime */ -#include /* file system */ -#include /* file system */ -#include -#endif -#include /* serial port driver */ -#include /* time measurement & timer interrupt rate control */ -#include /* interrupt handler for the keyboard */ - -/* buffers used for transmit and receive */ -static uint8_t Rx_Buf[MAX_MPDU] = { 0 }; - -static void Init_Service_Handlers( - void) -{ - /* we need to handle who-is to support dynamic device binding */ - apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is); - /* set the handler for all the services we don't implement */ - /* It is required to send the proper reject message... */ - apdu_set_unrecognized_service_handler_handler - (handler_unrecognized_service); - /* we must implement read property - it's required! */ - apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY, - handler_read_property); - apdu_set_confirmed_handler(SERVICE_CONFIRMED_WRITE_PROPERTY, - handler_write_property); -} - -void millisecond_task( - void) -{ - Time ticks = 0; /* task cycle */ - int i = 0; /* loop counter */ - - ticks = RTKGetTime() + MilliSecsToTicks(1); - while (TRUE) { - RTKDelayUntil(ticks); - dlmstp_millisecond_timer(); - ticks += MilliSecsToTicks(1); - } -} - -void RTOS_Initialize( - void) -{ - /* allow OS to setup IRQ 1 by using a dummy call */ - (void) kbhit(); - RTKernelInit(5); /* get the kernel going */ - RTKeybrdInit(); - /*(void)CPUMoniInit(); /* not needed - just monitor idle task */ */ - RTComInit(); - ITimerInit(); - - if (RTCallDebugger(RT_DBG_MONITOR, 0, 0) != -1) { - /* Win32 structured exception - if no handler is - installed, TerminateProcess() will be called, - which will reboot - a good thing in our case. */ - RTRaiseCPUException(0); /* Divide Error DIV and IDIV instructions. */ - RTRaiseCPUException(1); /* Debug Any code or data reference. */ - RTRaiseCPUException(2); /* NMI */ - RTRaiseCPUException(3); /* Breakpoint INT 3 instruction. */ - RTRaiseCPUException(4); /* Overflow INTO instruction. */ - RTRaiseCPUException(5); /* BOUND Range Exceeded BOUND instruction. */ - RTRaiseCPUException(6); /* Invalid Opcode (Undefined Opcode) */ - /* RTRaiseCPUException(7); // Device Not Available (No Math Coprocessor) */ - RTRaiseCPUException(8); /* Double Fault any exception instruction,NMI,INTR. */ - RTRaiseCPUException(9); /* Co-Processor overrun */ - RTRaiseCPUException(10); /* Invalid TSS Task switch or TSS access. */ - RTRaiseCPUException(11); /* Segment Not Present Loading segment registers */ - RTRaiseCPUException(12); /* Stack Seg Fault Stack ops /SS reg loads. */ - RTRaiseCPUException(13); /* General Protection Any memory reference */ - RTRaiseCPUException(14); /* Page Fault Any memory reference. */ - RTRaiseCPUException(15); /* reserved */ - RTRaiseCPUException(16); /* Floating-Point Error (Math Fault) */ - } - /* setup 1ms timer tick */ - SetTimerIntVal(1000); - /* per recommendation in manual */ - RTKDelay(1); - RTCMOSSetSystemTime(); /* get the right time-of-day */ - - /* create timer tick task */ - RTKCreateTask(millisecond_task, 16, 1024 * 8, "millisec task"); -} - -int main( - int argc, - char *argv[]) -{ - BACNET_ADDRESS src = { 0 }; /* address where message came from */ - uint16_t pdu_len = 0; - unsigned timeout = 100; /* milliseconds */ - - (void) argc; - (void) argv; - Device_Set_Object_Instance_Number(126); - Init_Service_Handlers(); - RTOS_Initialize(); - /* init the physical layer */ -#ifdef BACDL_MSTP - dlmstp_set_my_address(0x05); -#endif - datalink_init(NULL); - Send_I_Am(&Handler_Transmit_Buffer[0]); - /* loop forever */ - for (;;) { - /* input */ - - /* returns 0 bytes on timeout */ - pdu_len = datalink_receive(&src, &Rx_Buf[0], MAX_MPDU, timeout); - /* process */ - if (pdu_len) { - npdu_handler(&src, &Rx_Buf[0], pdu_len); - } - /* output */ - - - - /* blink LEDs, Turn on or off outputs, etc */ - } -} diff --git a/ports/rtos32/makefile.mak b/ports/rtos32/makefile.mak deleted file mode 100644 index 51279459..00000000 --- a/ports/rtos32/makefile.mak +++ /dev/null @@ -1,199 +0,0 @@ -# -# Simple makefile to build an RTB executable for RTOS-32 -# -# This makefile assumes Borland bcc32 development environment -# on Windows NT/9x/2000/XP -# - -!ifndef RTOS32_DIR -RTOS32_DIR_Not_Defined: - @echo . - @echo You must define environment variable RTOS32_DIR to compile. -!endif - -!ifndef BORLAND_DIR -BORLAND_DIR_Not_Defined: - @echo . - @echo You must define environment variable BORLAND_DIR to compile. -!endif - -PRODUCT = bacnet -PRODUCT_RTB = $(PRODUCT).rtb -PRODUCT_EXE = $(PRODUCT).exe - -# Choose the Data Link Layer to Enable -#DEFINES = -DDOC;BIG_ENDIAN=0;TSM_ENABLED=1;PRINT_ENABLED=1;BACDL_BIP=1 -#DEFINES = -DDOC;BIG_ENDIAN=0;TSM_ENABLED=1;PRINT_ENABLED=1;BACDL_ETHERNET=1 -#DEFINES = -DDOC;BIG_ENDIAN=0;TSM_ENABLED=1;PRINT_ENABLED=1;BACDL_ARCNET=1 -DEFINES = -DDOC;BIG_ENDIAN=0;TSM_ENABLED=1;PRINT_ENABLED=0;BACDL_MSTP=1 - -SRCS = main.c \ - ethernet.c \ - bip-init.c \ - dlmstp.c \ - rs485.c \ - init.c \ - ..\..\bip.c \ - ..\..\mstp.c \ - ..\..\crc.c \ - ..\..\demo\handler\h_iam.c \ - ..\..\demo\handler\h_npdu.c \ - ..\..\demo\handler\h_whois.c \ - ..\..\demo\handler\h_wp.c \ - ..\..\demo\handler\h_rp.c \ - ..\..\demo\handler\noserv.c \ - ..\..\demo\handler\txbuf.c \ - ..\..\demo\handler\s_iam.c \ - ..\..\demo\handler\s_rp.c \ - ..\..\demo\handler\s_whois.c \ - ..\..\bacdcode.c \ - ..\..\bacstr.c \ - ..\..\bactext.c \ - ..\..\indtext.c \ - ..\..\bacapp.c \ - ..\..\bigend.c \ - ..\..\whois.c \ - ..\..\dcc.c \ - ..\..\iam.c \ - ..\..\rp.c \ - ..\..\wp.c \ - ..\..\arf.c \ - ..\..\awf.c \ - ..\..\demo\object\bacfile.c \ - ..\..\demo\object\device.c \ - ..\..\demo\object\ai.c \ - ..\..\demo\object\ao.c \ - ..\..\demo\object\av.c \ - ..\..\demo\object\bi.c \ - ..\..\demo\object\bo.c \ - ..\..\demo\object\bv.c \ - ..\..\demo\object\lsp.c \ - ..\..\demo\object\mso.c \ - ..\..\datalink.c \ - ..\..\tsm.c \ - ..\..\address.c \ - ..\..\abort.c \ - ..\..\reject.c \ - ..\..\bacerror.c \ - ..\..\apdu.c \ - ..\..\npdu.c - -OBJS = $(SRCS:.c=.obj) - -# Compiler definitions -# -CC = $(BORLAND_DIR)\bin\bcc32 +bcc32.cfg -LINK = $(BORLAND_DIR)\bin\tlink32 -#LINK = $(BORLAND_DIR)\bin\ilink32 -TLIB = $(BORLAND_DIR)\bin\tlib -LOCATE = $(RTOS32_DIR)\bin\rtloc - -# -# Include directories -# -CC_DIR = $(BORLAND_DIR)\BIN -INCL_DIRS = -I$(BORLAND_DIR)\include;$(RTOS32_DIR)\include;..\..\include;..\..\demo\handler\;..\..\demo\object\;. - -CFLAGS = $(INCL_DIRS) $(CS_FLAGS) $(DEFINES) - -# Libraries -# -RTOS32_LIB_DIR = $(RTOS32_DIR)\libbc -C_LIB_DIR = $(BORLAND_DIR)\lib - -LIBDIR = $(RTOS32_LIB_DIR);$(C_LIB_DIR) - -LIBS = $(RTOS32_LIB_DIR)\RTFILES.LIB \ -$(RTOS32_LIB_DIR)\RTFSK32.LIB \ -$(RTOS32_LIB_DIR)\DRVDOC.LIB \ -$(RTOS32_LIB_DIR)\RTIP.LIB \ -$(RTOS32_LIB_DIR)\RTK32.LIB \ -$(RTOS32_LIB_DIR)\FLTEMUMT.LIB \ -$(RTOS32_LIB_DIR)\DRVRT32.LIB \ -$(RTOS32_LIB_DIR)\RTEMUMT.LIB \ -$(RTOS32_LIB_DIR)\RTT32.LIB \ -$(RTOS32_LIB_DIR)\RTTHEAP.LIB \ -#$(C_LIB_DIR)\DPMI32.lib \ -$(C_LIB_DIR)\IMPORT32.lib \ -$(C_LIB_DIR)\CW32MT.lib - -# -# Main target -# -# This should be the first one in the makefile - -all : $(PRODUCT_RTB) monitor.rtb - -monitor.rtb: monitor.cfg hardware.cfg - $(LOCATE) monitor - -# debug using COM3 (ISA Card) as the debug port -# boot from floppy -debugcom3: hardware.cfg software.cfg $(PRODUCT_RTB) monitor.rtb - $(LOCATE) -DDEBUGCOM3 monitor - $(LOCATE) -d- -DMONITOR -DDEBUGCOM3 $(PRODUCT) software.cfg - -$(PRODUCT_RTB): bcc32.cfg hardware.cfg software.cfg $(PRODUCT_EXE) - @echo Running Locate on $(PRODUCT) - $(LOCATE) $(PRODUCT) software.cfg - -# Linker specific: the link below is for BCC linker/compiler. If you link -# with a different linker - please change accordingly. -# - -# need a temp response file (@&&) because command line is too long -$(PRODUCT_EXE) : $(OBJS) - @echo Running Linker for $(PRODUCT_EXE) - $(LINK) -L$(LINKER_LIB) -m -c -s -v @&&| # temp response file, starts with | - $(BORLAND_DIR)\lib\c0x32.obj $** # $** lists each dependency - $< - $*.map - $(LIBS) -| # end of temp response file - -# -# Utilities - -clean : - @echo Deleting obj files, $(PRODUCT_EXE), $(PRODUCT_RTB) and map files. - del *.obj - del ..\..\*.obj - del $(PRODUCT_EXE) - del $(PRODUCT_RTB) - del *.map - del bcc32.cfg - -install : $(PRODUCT) - copy $(PRODUCT) ..\bin - -# -# Generic rules -# -.SUFFIXES: .cpp .c .sbr .obj - -# -# cc generic rule -# -.c.obj: - $(CC) -o$@ $< - -# Compiler configuration file -bcc32.cfg : - Copy &&| -$(CFLAGS) --c -#-g2 #stop after gN warnings --y #include line numbers in OBJ's --v #include debug info --w+ #turn on all warnings --Od #disable all optimizations -#-a4 #32 bit data alignment -#-M # generate link map -#-ls # linker options -#-WM- #not multithread --WM #multithread --w-aus # ignore warning assigned a value that is never used --w-sig # ignore warning conversion may lose sig digits -| $@ - -# EOF: makefile diff --git a/ports/rtos32/monitor.cfg b/ports/rtos32/monitor.cfg deleted file mode 100644 index 68417102..00000000 --- a/ports/rtos32/monitor.cfg +++ /dev/null @@ -1,47 +0,0 @@ -// Configuration files for the RTTarget-32 Debug Monitor and Borland C/C++. - -// Some general parameters for this file are: -// -// * The default disk boot code is used to boot the system from -// a floppy disk, hard disk, or ROM disk. -// * Pageing is enabled. -// * The program privilege level is set to 3 for maximum protection. -// * Boot code and the Monitor are placed in low (conventional) memory. -// * The target PC is assumed to have a color display. -// * The target PC uses COM1 to communicated with the host. -// * 115200 baud is used for host - target communication. - - -@HARDWARE.CFG // pull in hardware definitions - -Locate BootCode BIOSBOOT.EXE LowMem // boot from disk -Locate BootData BootData LowMem 0 16 // boot stuff must be in conventional memory -Locate DiskBuffer DiskIO LowMem 16k 16k // needed by disk boot code -CPL = 0 - -Locate Section CODE LowMem 1 // Monitor's code section -Locate Header Monitor LowMem 0 4 // and header -Locate Section DATA LowMem 2 // data section -Locate Stack Stack LowMem 1k 4 // and a small stack, no heap -Locate PageTable Pages LowMem - -Locate DecompCode Expand LowMem // include decompression stuff -Locate DecompData ExBuffer LowMem - -Locate Copy CODE LowMem // compress everything -Locate Copy DATA LowMem // ditto -Locate Copy Pages LowMem // ditto - -#ifdef DEBUGCOM1 -COMPort COM1 115200 // use COM1 with 115200 baud -VideoRAM = None // program output sent to debugger - clrscr() crashes it. -#elifdef DEBUGCOM3 -COMPort COM3 115200 9 // use COM3 IRQ9 115200 baud - Everex EV170 serial card -//VideoRAM = ColorText // program output sent to Graphic Card -VideoRAM = None // program output sent to debugger - clrscr() crashes it. -#else -COMPort COM3 115200 9 // use COM3 IRQ9 115200 baud - Everex EV170 serial card -VideoRAM = ColorText // program output sent to Graphic Card -#endif - -IgnoreMsg "No heap" // the monitor does not need a heap diff --git a/ports/rtos32/mstp.c b/ports/rtos32/mstp.c deleted file mode 100644 index e6420f8e..00000000 --- a/ports/rtos32/mstp.c +++ /dev/null @@ -1,1278 +0,0 @@ -/*####COPYRIGHTBEGIN#### - ------------------------------------------- - Copyright (C) 2003 Steve Karg - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to: - The Free Software Foundation, Inc. - 59 Temple Place - Suite 330 - Boston, MA 02111-1307 - USA. - - As a special exception, if other files instantiate templates or - use macros or inline functions from this file, or you compile - this file and link it with other works to produce a work based - on this file, this file does not by itself cause the resulting - work to be covered by the GNU General Public License. However - the source code for this file must still be made available in - accordance with section (3) of the GNU General Public License. - - This exception does not invalidate any other reasons why a work - based on this file might be covered by the GNU General Public - License. - ------------------------------------------- -####COPYRIGHTEND####*/ - -/* This clause describes a Master-Slave/Token-Passing (MS/TP) data link */ -/* protocol, which provides the same services to the network layer as */ -/* ISO 8802-2 Logical Link Control. It uses services provided by the */ -/* EIA-485 physical layer. Relevant clauses of EIA-485 are deemed to be */ -/* included in this standard by reference. The following hardware is assumed: */ -/* (a) A UART (Universal Asynchronous Receiver/Transmitter) capable of */ -/* transmitting and receiving eight data bits with one stop bit */ -/* and no parity. */ -/* (b) An EIA-485 transceiver whose driver may be disabled. */ -/* (c) A timer with a resolution of five milliseconds or less */ - -#include -#include -#if PRINT_ENABLED -#include -#endif -#include "mstp.h" -#include "bytes.h" -#include "crc.h" -#include "rs485.h" - -/* debug print statements */ -#if PRINT_ENABLED -#define PRINT_ENABLED_RECEIVE 0 -#define PRINT_ENABLED_RECEIVE_DATA 1 -#define PRINT_ENABLED_MASTER 0 -#else -#define PRINT_ENABLED_RECEIVE 0 -#define PRINT_ENABLED_RECEIVE_DATA 0 -#define PRINT_ENABLED_MASTER 0 -#endif - -/* MS/TP Frame Format */ -/* All frames are of the following format: */ -/* */ -/* Preamble: two octet preamble: X`55', X`FF' */ -/* Frame Type: one octet */ -/* Destination Address: one octet address */ -/* Source Address: one octet address */ -/* Length: two octets, most significant octet first, of the Data field */ -/* Header CRC: one octet */ -/* Data: (present only if Length is non-zero) */ -/* Data CRC: (present only if Length is non-zero) two octets, */ -/* least significant octet first */ -/* (pad): (optional) at most one octet of padding: X'FF' */ - -/* The number of tokens received or used before a Poll For Master cycle */ -/* is executed: 50. */ -const unsigned Npoll = 50; - -/* The number of retries on sending Token: 1. */ -const unsigned Nretry_token = 1; - -/* The minimum number of DataAvailable or ReceiveError events that must be */ -/* seen by a receiving node in order to declare the line "active": 4. */ -const uint8_t Nmin_octets = 4; - -/* The minimum time without a DataAvailable or ReceiveError event within */ -/* a frame before a receiving node may discard the frame: 60 bit times. */ -/* (Implementations may use larger values for this timeout, */ -/* not to exceed 100 milliseconds.) */ -/* At 9600 baud, 60 bit times would be about 6.25 milliseconds */ -/* const uint16_t Tframe_abort = 1 + ((1000 * 60) / 9600); */ -const uint16_t Tframe_abort = 30; - -/* The maximum idle time a sending node may allow to elapse between octets */ -/* of a frame the node is transmitting: 20 bit times. */ -const unsigned Tframe_gap = 20; - -/* The time without a DataAvailable or ReceiveError event before declaration */ -/* of loss of token: 500 milliseconds. */ -const uint16_t Tno_token = 500; - -/* The maximum time after the end of the stop bit of the final */ -/* octet of a transmitted frame before a node must disable its */ -/* EIA-485 driver: 15 bit times. */ -const unsigned Tpostdrive = 15; - -/* The maximum time a node may wait after reception of a frame that expects */ -/* a reply before sending the first octet of a reply or Reply Postponed */ -/* frame: 250 milliseconds. */ -const uint16_t Treply_delay = 250; - -/* The minimum time without a DataAvailable or ReceiveError event */ -/* that a node must wait for a station to begin replying to a */ -/* confirmed request: 255 milliseconds. (Implementations may use */ -/* larger values for this timeout, not to exceed 300 milliseconds.) */ -const uint16_t Treply_timeout = 255; - -/* Repeater turnoff delay. The duration of a continuous logical one state */ -/* at the active input port of an MS/TP repeater after which the repeater */ -/* will enter the IDLE state: 29 bit times < Troff < 40 bit times. */ -const unsigned Troff = 30; - -/* The width of the time slot within which a node may generate a token: */ -/* 10 milliseconds. */ -const uint16_t Tslot = 10; - -/* The maximum time a node may wait after reception of the token or */ -/* a Poll For Master frame before sending the first octet of a frame: */ -/* 15 milliseconds. */ -const uint16_t Tusage_delay = 15; - -/* The minimum time without a DataAvailable or ReceiveError event that a */ -/* node must wait for a remote node to begin using a token or replying to */ -/* a Poll For Master frame: 20 milliseconds. (Implementations may use */ -/* larger values for this timeout, not to exceed 100 milliseconds.) */ -const uint16_t Tusage_timeout = 30; - -/* we need to be able to increment without rolling over */ -#define INCREMENT_AND_LIMIT_UINT8(x) {if (x < 0xFF) x++;} -#define INCREMENT_AND_LIMIT_UINT16(x) {if (x < 0xFFFF) x++;} - - -bool MSTP_Line_Active( - volatile struct mstp_port_struct_t *mstp_port) -{ - return (mstp_port->EventCount > Nmin_octets); -} - -unsigned MSTP_Create_Frame( - uint8_t * buffer, /* where frame is loaded */ - unsigned buffer_len, /* amount of space available */ - uint8_t frame_type, /* type of frame to send - see defines */ - uint8_t destination, /* destination address */ - uint8_t source, /* source address */ - uint8_t * data, /* any data to be sent - may be null */ - unsigned data_len) -{ /* number of bytes of data (up to 501) */ - uint8_t crc8 = 0xFF; /* used to calculate the crc value */ - uint16_t crc16 = 0xFFFF; /* used to calculate the crc value */ - unsigned index = 0; /* used to load the data portion of the frame */ - - /* not enough to do a header */ - if (buffer_len < 8) - return 0; - - buffer[0] = 0x55; - buffer[1] = 0xFF; - buffer[2] = frame_type; - crc8 = CRC_Calc_Header(buffer[2], crc8); - buffer[3] = destination; - crc8 = CRC_Calc_Header(buffer[3], crc8); - buffer[4] = source; - crc8 = CRC_Calc_Header(buffer[4], crc8); - buffer[5] = HI_BYTE(data_len); - crc8 = CRC_Calc_Header(buffer[5], crc8); - buffer[6] = LO_BYTE(data_len); - crc8 = CRC_Calc_Header(buffer[6], crc8); - buffer[7] = ~crc8; - - index = 8; - while (data_len && data && (index < buffer_len)) { - buffer[index] = *data; - crc16 = CRC_Calc_Data(buffer[index], crc16); - data++; - index++; - data_len--; - } - /* append the data CRC if necessary */ - if (index > 8) { - if ((index + 2) <= buffer_len) { - crc16 = ~crc16; - buffer[index] = LO_BYTE(crc16); - index++; - buffer[index] = HI_BYTE(crc16); - index++; - } else - return 0; - } - - return index; /* returns the frame length */ -} - -void MSTP_Create_And_Send_Frame( - volatile struct mstp_port_struct_t *mstp_port, /* port to send from */ - uint8_t frame_type, /* type of frame to send - see defines */ - uint8_t destination, /* destination address */ - uint8_t source, /* source address */ - uint8_t * data, /* any data to be sent - may be null */ - unsigned data_len) -{ /* number of bytes of data (up to 501) */ - uint8_t buffer[MAX_MPDU] = { 0 }; /* buffer for sending */ - uint16_t len = 0; /* number of bytes to send */ - - len = (uint16_t) MSTP_Create_Frame(&buffer[0], /* where frame is loaded */ - sizeof(buffer), /* amount of space available */ - frame_type, /* type of frame to send - see defines */ - destination, /* destination address */ - source, /* source address */ - data, /* any data to be sent - may be null */ - data_len); /* number of bytes of data (up to 501) */ - - RS485_Send_Frame(mstp_port, &buffer[0], len); - /* FIXME: be sure to reset SilenceTimer after each octet is sent! */ -} - -/* Millisecond Timer - called every millisecond */ -void MSTP_Millisecond_Timer( - volatile struct mstp_port_struct_t *mstp_port) -{ - INCREMENT_AND_LIMIT_UINT16(mstp_port->SilenceTimer); - INCREMENT_AND_LIMIT_UINT16(mstp_port->ReplyPostponedTimer); - return; -} - -#if PRINT_ENABLED_RECEIVE -char *mstp_receive_state_text( - int state) -{ - char *text = "unknown"; - - switch (state) { - case MSTP_RECEIVE_STATE_IDLE: - text = "IDLE"; - break; - case MSTP_RECEIVE_STATE_PREAMBLE: - text = "PREAMBLE"; - break; - case MSTP_RECEIVE_STATE_HEADER: - text = "HEADER"; - break; - case MSTP_RECEIVE_STATE_DATA: - text = "DATA"; - break; - default: - break; - } - - return text; -} -#endif - -void MSTP_Receive_Frame_FSM( - volatile struct mstp_port_struct_t *mstp_port) -{ -#if PRINT_ENABLED_RECEIVE_DATA - static MSTP_RECEIVE_STATE receive_state = MSTP_RECEIVE_STATE_IDLE; -#endif -#if PRINT_ENABLED_RECEIVE - fprintf(stderr, - "MSTP Rx: State=%s Data=%02X hCRC=%02X Index=%u EC=%u DateLen=%u Silence=%u\n", - mstp_receive_state_text(mstp_port->receive_state), - mstp_port->DataRegister, mstp_port->HeaderCRC, mstp_port->Index, - mstp_port->EventCount, mstp_port->DataLength, mstp_port->SilenceTimer); -#endif - switch (mstp_port->receive_state) { - /* In the IDLE state, the node waits for the beginning of a frame. */ - case MSTP_RECEIVE_STATE_IDLE: - /* EatAnError */ - if (mstp_port->ReceiveError == true) { - mstp_port->ReceiveError = false; - mstp_port->SilenceTimer = 0; - INCREMENT_AND_LIMIT_UINT8(mstp_port->EventCount); - /* wait for the start of a frame. */ - mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; - } else if (mstp_port->DataAvailable == true) { -#if PRINT_ENABLED_RECEIVE_DATA - fprintf(stderr, "MSTP Rx: %02X ", mstp_port->DataRegister); -#endif - /* Preamble1 */ - if (mstp_port->DataRegister == 0x55) { - mstp_port->DataAvailable = false; - mstp_port->SilenceTimer = 0; - INCREMENT_AND_LIMIT_UINT8(mstp_port->EventCount); - /* receive the remainder of the frame. */ - mstp_port->receive_state = MSTP_RECEIVE_STATE_PREAMBLE; - } - /* EatAnOctet */ - else { -#if PRINT_ENABLED_RECEIVE_DATA - fprintf(stderr, "\n"); -#endif - mstp_port->DataAvailable = false; - mstp_port->SilenceTimer = 0; - INCREMENT_AND_LIMIT_UINT8(mstp_port->EventCount); - /* wait for the start of a frame. */ - mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; - } - } - break; - /* In the PREAMBLE state, the node waits for the second octet of the preamble. */ - case MSTP_RECEIVE_STATE_PREAMBLE: - /* Timeout */ - if (mstp_port->SilenceTimer > Tframe_abort) { - /* a correct preamble has not been received */ - /* wait for the start of a frame. */ - mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; - } - /* Error */ - else if (mstp_port->ReceiveError == true) { - mstp_port->ReceiveError = false; - mstp_port->SilenceTimer = 0; - INCREMENT_AND_LIMIT_UINT8(mstp_port->EventCount); - /* wait for the start of a frame. */ - mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; - } else if (mstp_port->DataAvailable == true) { -#if PRINT_ENABLED_RECEIVE_DATA - fprintf(stderr, "%02X ", mstp_port->DataRegister); -#endif - /* Preamble2 */ - if (mstp_port->DataRegister == 0xFF) { - mstp_port->DataAvailable = false; - mstp_port->SilenceTimer = 0; - INCREMENT_AND_LIMIT_UINT8(mstp_port->EventCount); - mstp_port->Index = 0; - mstp_port->HeaderCRC = 0xFF; - /* receive the remainder of the frame. */ - mstp_port->receive_state = MSTP_RECEIVE_STATE_HEADER; - } - /* ignore RepeatedPreamble1 */ - else if (mstp_port->DataRegister == 0x55) { - mstp_port->DataAvailable = false; - mstp_port->SilenceTimer = 0; - INCREMENT_AND_LIMIT_UINT8(mstp_port->EventCount); - /* wait for the second preamble octet. */ - mstp_port->receive_state = MSTP_RECEIVE_STATE_PREAMBLE; - } - /* NotPreamble */ - else { - mstp_port->DataAvailable = false; - mstp_port->SilenceTimer = 0; - INCREMENT_AND_LIMIT_UINT8(mstp_port->EventCount); - /* wait for the start of a frame. */ - mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; - } - } - break; - /* In the HEADER state, the node waits for the fixed message header. */ - case MSTP_RECEIVE_STATE_HEADER: - /* Timeout */ - if (mstp_port->SilenceTimer > Tframe_abort) { - /* indicate that an error has occurred during the reception of a frame */ - mstp_port->ReceivedInvalidFrame = true; - /* wait for the start of a frame. */ - mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; - } - /* Error */ - else if (mstp_port->ReceiveError == true) { - mstp_port->ReceiveError = false; - mstp_port->SilenceTimer = 0; - INCREMENT_AND_LIMIT_UINT8(mstp_port->EventCount); - /* indicate that an error has occurred during the reception of a frame */ - mstp_port->ReceivedInvalidFrame = true; - /* wait for the start of a frame. */ - mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; - } else if (mstp_port->DataAvailable == true) { -#if PRINT_ENABLED_RECEIVE_DATA - fprintf(stderr, "%02X ", mstp_port->DataRegister); -#endif - /* FrameType */ - if (mstp_port->Index == 0) { - mstp_port->SilenceTimer = 0; - INCREMENT_AND_LIMIT_UINT8(mstp_port->EventCount); - mstp_port->HeaderCRC = - CRC_Calc_Header(mstp_port->DataRegister, - mstp_port->HeaderCRC); - mstp_port->FrameType = mstp_port->DataRegister; - mstp_port->DataAvailable = false; - mstp_port->Index = 1; - mstp_port->receive_state = MSTP_RECEIVE_STATE_HEADER; - } - /* Destination */ - else if (mstp_port->Index == 1) { - mstp_port->SilenceTimer = 0; - INCREMENT_AND_LIMIT_UINT8(mstp_port->EventCount); - mstp_port->HeaderCRC = - CRC_Calc_Header(mstp_port->DataRegister, - mstp_port->HeaderCRC); - mstp_port->DestinationAddress = mstp_port->DataRegister; - mstp_port->DataAvailable = false; - mstp_port->Index = 2; - mstp_port->receive_state = MSTP_RECEIVE_STATE_HEADER; - } - /* Source */ - else if (mstp_port->Index == 2) { - mstp_port->SilenceTimer = 0; - INCREMENT_AND_LIMIT_UINT8(mstp_port->EventCount); - mstp_port->HeaderCRC = - CRC_Calc_Header(mstp_port->DataRegister, - mstp_port->HeaderCRC); - mstp_port->SourceAddress = mstp_port->DataRegister; - mstp_port->DataAvailable = false; - mstp_port->Index = 3; - mstp_port->receive_state = MSTP_RECEIVE_STATE_HEADER; - } - /* Length1 */ - else if (mstp_port->Index == 3) { - mstp_port->SilenceTimer = 0; - INCREMENT_AND_LIMIT_UINT8(mstp_port->EventCount); - mstp_port->HeaderCRC = - CRC_Calc_Header(mstp_port->DataRegister, - mstp_port->HeaderCRC); - mstp_port->DataLength = mstp_port->DataRegister * 256; - mstp_port->DataAvailable = false; - mstp_port->Index = 4; - mstp_port->receive_state = MSTP_RECEIVE_STATE_HEADER; - } - /* Length2 */ - else if (mstp_port->Index == 4) { - mstp_port->SilenceTimer = 0; - INCREMENT_AND_LIMIT_UINT8(mstp_port->EventCount); - mstp_port->HeaderCRC = - CRC_Calc_Header(mstp_port->DataRegister, - mstp_port->HeaderCRC); - mstp_port->DataLength += mstp_port->DataRegister; - mstp_port->DataAvailable = false; - mstp_port->Index = 5; - mstp_port->receive_state = MSTP_RECEIVE_STATE_HEADER; - } - /* HeaderCRC */ - else if (mstp_port->Index == 5) { - mstp_port->SilenceTimer = 0; - INCREMENT_AND_LIMIT_UINT8(mstp_port->EventCount); - mstp_port->HeaderCRC = - CRC_Calc_Header(mstp_port->DataRegister, - mstp_port->HeaderCRC); - mstp_port->DataAvailable = false; - /* don't wait for next state - do it here */ - if (mstp_port->HeaderCRC != 0x55) { - /* BadCRC */ - /* indicate that an error has occurred during the reception of a frame */ - mstp_port->ReceivedInvalidFrame = true; - /* wait for the start of the next frame. */ - mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; - } else { - if ((mstp_port->DestinationAddress == - mstp_port->This_Station) - || (mstp_port->DestinationAddress == - MSTP_BROADCAST_ADDRESS)) { - /* FrameTooLong */ - if (mstp_port->DataLength > MAX_MPDU) { - /* indicate that a frame with an illegal or */ - /* unacceptable data length has been received */ - mstp_port->ReceivedInvalidFrame = true; - /* wait for the start of the next frame. */ - mstp_port->receive_state = - MSTP_RECEIVE_STATE_IDLE; - } - /* NoData */ - else if (mstp_port->DataLength == 0) { - /* CHEAT: it is very difficult to respond to - poll for master in the Master Node state machine - before Tusage_timeout, so we will do it here. */ - if ((mstp_port->FrameType == - FRAME_TYPE_POLL_FOR_MASTER) - && (mstp_port->DestinationAddress == - mstp_port->This_Station) - && (mstp_port->master_state == - MSTP_MASTER_STATE_IDLE)) { - MSTP_Create_And_Send_Frame(mstp_port, - FRAME_TYPE_REPLY_TO_POLL_FOR_MASTER, - mstp_port->SourceAddress, - mstp_port->This_Station, NULL, 0); - /* don't indicate that a frame has been received */ - mstp_port->ReceivedInvalidFrame = false; - mstp_port->ReceivedValidFrame = false; - } else { - /* indicate that a frame with no data has been received */ - mstp_port->ReceivedValidFrame = true; - } - /* wait for the start of the next frame. */ - mstp_port->receive_state = - MSTP_RECEIVE_STATE_IDLE; - } - /* Data */ - else { - mstp_port->Index = 0; - mstp_port->DataCRC = 0xFFFF; - /* receive the data portion of the frame. */ - mstp_port->receive_state = - MSTP_RECEIVE_STATE_DATA; - } - } - /* NotForUs */ - else { - /* wait for the start of the next frame. */ - mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; - } - } - - - } - /* not per MS/TP standard, but it is a case not covered */ - else { - mstp_port->ReceiveError = false; - mstp_port->SilenceTimer = 0; - INCREMENT_AND_LIMIT_UINT8(mstp_port->EventCount); - /* indicate that an error has occurred during */ - /* the reception of a frame */ - mstp_port->ReceivedInvalidFrame = true; - /* wait for the start of a frame. */ - mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; - } - } - break; - /* In the DATA state, the node waits for the data portion of a frame. */ - case MSTP_RECEIVE_STATE_DATA: - /* Timeout */ - if (mstp_port->SilenceTimer > Tframe_abort) { - /* indicate that an error has occurred during the reception of a frame */ - mstp_port->ReceivedInvalidFrame = true; - /* wait for the start of the next frame. */ - mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; - } - /* Error */ - else if (mstp_port->ReceiveError == true) { - mstp_port->ReceiveError = false; - mstp_port->SilenceTimer = 0; - /* indicate that an error has occurred during the reception of a frame */ - mstp_port->ReceivedInvalidFrame = true; - /* wait for the start of the next frame. */ - mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; - } else if (mstp_port->DataAvailable == true) { -#if PRINT_ENABLED_RECEIVE_DATA - fprintf(stderr, "%02X ", mstp_port->DataRegister); -#endif - /* DataOctet */ - if (mstp_port->Index < mstp_port->DataLength) { - mstp_port->DataCRC = - CRC_Calc_Data(mstp_port->DataRegister, - mstp_port->DataCRC); - mstp_port->InputBuffer[mstp_port->Index] = - mstp_port->DataRegister; - mstp_port->Index++; - mstp_port->receive_state = MSTP_RECEIVE_STATE_DATA; - } - /* CRC1 */ - else if (mstp_port->Index == mstp_port->DataLength) { - mstp_port->DataCRC = - CRC_Calc_Data(mstp_port->DataRegister, - mstp_port->DataCRC); - mstp_port->Index++; - mstp_port->receive_state = MSTP_RECEIVE_STATE_DATA; - } - /* CRC2 */ - else if (mstp_port->Index == (mstp_port->DataLength + 1)) { - mstp_port->DataCRC = - CRC_Calc_Data(mstp_port->DataRegister, - mstp_port->DataCRC); - /* STATE DATA CRC - no need for new state */ - /* indicate the complete reception of a valid frame */ - if (mstp_port->DataCRC == 0xF0B8) - mstp_port->ReceivedValidFrame = true; - else - mstp_port->ReceivedInvalidFrame = true; - mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; - } - mstp_port->DataAvailable = false; - mstp_port->SilenceTimer = 0; - } - break; - default: - /* shouldn't get here - but if we do... */ - mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; - break; - } -#if PRINT_ENABLED_RECEIVE_DATA - if ((receive_state != MSTP_RECEIVE_STATE_IDLE) && - (mstp_port->receive_state == MSTP_RECEIVE_STATE_IDLE)) { - fprintf(stderr, "\n"); - fflush(stderr); - } - receive_state = mstp_port->receive_state; -#endif - - return; -} - -#if PRINT_ENABLED -char *mstp_master_state_text( - int state) -{ - char *text = "unknown"; - - switch (state) { - case MSTP_MASTER_STATE_INITIALIZE: - text = "INITIALIZE"; - break; - case MSTP_MASTER_STATE_IDLE: - text = "IDLE"; - break; - case MSTP_MASTER_STATE_USE_TOKEN: - text = "USE_TOKEN"; - break; - case MSTP_MASTER_STATE_WAIT_FOR_REPLY: - text = "WAIT_FOR_REPLY"; - break; - case MSTP_MASTER_STATE_DONE_WITH_TOKEN: - text = "IDLE"; - break; - case MSTP_MASTER_STATE_PASS_TOKEN: - text = "DONE_WITH_TOKEN"; - break; - case MSTP_MASTER_STATE_NO_TOKEN: - text = "NO_TOKEN"; - break; - case MSTP_MASTER_STATE_POLL_FOR_MASTER: - text = "POLL_FOR_MASTER"; - break; - case MSTP_MASTER_STATE_ANSWER_DATA_REQUEST: - text = "ANSWER_DATA_REQUEST"; - break; - default: - break; - } - - return text; -} -#endif - -#if PRINT_ENABLED -char *mstp_frame_type_text( - int type) -{ - char *text = "unknown"; - - switch (type) { - case FRAME_TYPE_TOKEN: - text = "TOKEN"; - break; - case FRAME_TYPE_POLL_FOR_MASTER: - text = "POLL_FOR_MASTER"; - break; - case FRAME_TYPE_REPLY_TO_POLL_FOR_MASTER: - text = "REPLY_TO_POLL_FOR_MASTER"; - break; - case FRAME_TYPE_TEST_REQUEST: - text = "TEST_REQUEST"; - break; - case FRAME_TYPE_TEST_RESPONSE: - text = "TEST_RESPONSE"; - break; - case FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY: - text = "BACNET_DATA_EXPECTING_REPLY"; - break; - case FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY: - text = "BACNET_DATA_NOT_EXPECTING_REPLY"; - break; - case FRAME_TYPE_REPLY_POSTPONED: - text = "REPLY_POSTPONED"; - break; - default: - if ((type >= FRAME_TYPE_PROPRIETARY_MIN) && - (type <= FRAME_TYPE_PROPRIETARY_MAX)) - text = "PROPRIETARY"; - break; - } - - return text; -} -#endif - -/* returns true if we need to transition immediately */ -bool MSTP_Master_Node_FSM( - volatile struct mstp_port_struct_t * mstp_port) -{ - int mtu_len = 0; - int frame_type = 0; - uint8_t next_poll_station = 0; - uint8_t next_this_station = 0; - uint8_t next_next_station = 0; - uint16_t my_timeout = 10, ns_timeout = 0; - /* transition immediately to the next state */ - bool transition_now = false; -#if PRINT_ENABLED_MASTER - static MSTP_MASTER_STATE master_state = MSTP_MASTER_STATE_INITIALIZE; -#endif - - /* some calculations that several states need */ - next_poll_station = - (mstp_port->Poll_Station + 1) % (mstp_port->Nmax_master + 1); - next_this_station = - (mstp_port->This_Station + 1) % (mstp_port->Nmax_master + 1); - next_next_station = - (mstp_port->Next_Station + 1) % (mstp_port->Nmax_master + 1); -#if PRINT_ENABLED_MASTER - if (mstp_port->master_state != master_state) { - master_state = mstp_port->master_state; - fprintf(stderr, - "MSTP: TS=%02X[%02X] NS=%02X[%02X] PS=%02X[%02X] EC=%u TC=%u ST=%u %s\n", - mstp_port->This_Station, next_this_station, - mstp_port->Next_Station, next_next_station, - mstp_port->Poll_Station, next_poll_station, mstp_port->EventCount, - mstp_port->TokenCount, mstp_port->SilenceTimer, - mstp_master_state_text(mstp_port->master_state)); - } -#endif - - switch (mstp_port->master_state) { - case MSTP_MASTER_STATE_INITIALIZE: - /* DoneInitializing */ - /* indicate that the next station is unknown */ - mstp_port->Next_Station = mstp_port->This_Station; - mstp_port->Poll_Station = mstp_port->This_Station; - /* cause a Poll For Master to be sent when this node first */ - /* receives the token */ - mstp_port->TokenCount = Npoll; - mstp_port->SoleMaster = false; - mstp_port->master_state = MSTP_MASTER_STATE_IDLE; - transition_now = true; - break; - /* In the IDLE state, the node waits for a frame. */ - case MSTP_MASTER_STATE_IDLE: - /* LostToken */ - if (mstp_port->SilenceTimer >= Tno_token) { - /* assume that the token has been lost */ - mstp_port->EventCount = 0; /* Addendum 135-2004d-8 */ - mstp_port->master_state = MSTP_MASTER_STATE_NO_TOKEN; - /* set the receive frame flags to false in case we received - some bytes and had a timeout for some reason */ - mstp_port->ReceivedInvalidFrame = false; - mstp_port->ReceivedValidFrame = false; - transition_now = true; - } - /* ReceivedInvalidFrame */ - else if (mstp_port->ReceivedInvalidFrame == true) { - /* invalid frame was received */ - mstp_port->ReceivedInvalidFrame = false; - /* wait for the next frame - remain in IDLE */ - } else if (mstp_port->ReceivedValidFrame == true) { -#if PRINT_ENABLED_MASTER - fprintf(stderr, - "MSTP: ReceivedValidFrame Src=%02X Dest=%02X DataLen=%u FC=%u ST=%u Type=%s\n", - mstp_port->SourceAddress, mstp_port->DestinationAddress, - mstp_port->DataLength, mstp_port->FrameCount, - mstp_port->SilenceTimer, - mstp_frame_type_text(mstp_port->FrameType)); -#endif - /* destined for me! */ - if ((mstp_port->DestinationAddress == mstp_port->This_Station) - || (mstp_port->DestinationAddress == - MSTP_BROADCAST_ADDRESS)) { - switch (mstp_port->FrameType) { - /* ReceivedToken */ - case FRAME_TYPE_TOKEN: - /* tokens can't be broadcast */ - if (mstp_port->DestinationAddress == - MSTP_BROADCAST_ADDRESS) - break; - mstp_port->ReceivedValidFrame = false; - mstp_port->FrameCount = 0; - mstp_port->SoleMaster = false; - mstp_port->master_state = - MSTP_MASTER_STATE_USE_TOKEN; - transition_now = true; - break; - /* ReceivedPFM */ - case FRAME_TYPE_POLL_FOR_MASTER: - /* CHEAT: we cheat a little and this is really handled in the - receive state machine since it is difficult to respond - quick enough (i.e. faster than Tusage_timeout of the - other node which could be 20ms). */ - MSTP_Create_And_Send_Frame(mstp_port, - FRAME_TYPE_REPLY_TO_POLL_FOR_MASTER, - mstp_port->SourceAddress, - mstp_port->This_Station, NULL, 0); - break; - case FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY: - /* indicate successful reception to the higher layers */ - dlmstp_put_receive(mstp_port->SourceAddress, - (uint8_t *) & mstp_port->InputBuffer[0], - mstp_port->DataLength); - break; - case FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY: - mstp_port->ReplyPostponedTimer = 0; - /* indicate successful reception to the higher layers */ - dlmstp_put_receive(mstp_port->SourceAddress, /* source MS/TP address */ - (uint8_t *) & mstp_port->InputBuffer[0], - mstp_port->DataLength); - /* broadcast DER just remains IDLE */ - if (mstp_port->DestinationAddress != - MSTP_BROADCAST_ADDRESS) { - mstp_port->master_state = - MSTP_MASTER_STATE_ANSWER_DATA_REQUEST; - transition_now = true; - } - break; - case FRAME_TYPE_TEST_REQUEST: - MSTP_Create_And_Send_Frame(mstp_port, - FRAME_TYPE_TEST_RESPONSE, - mstp_port->SourceAddress, - mstp_port->This_Station, - (uint8_t *) & mstp_port->InputBuffer[0], - mstp_port->DataLength); - break; - case FRAME_TYPE_TEST_RESPONSE: - default: - break; - } - } - mstp_port->ReceivedValidFrame = false; - } - break; - /* In the USE_TOKEN state, the node is allowed to send one or */ - /* more data frames. These may be BACnet Data frames or */ - /* proprietary frames. */ - case MSTP_MASTER_STATE_USE_TOKEN: - if (!mstp_port->TxReady) { - /* NothingToSend */ - mstp_port->FrameCount = mstp_port->Nmax_info_frames; - mstp_port->master_state = MSTP_MASTER_STATE_DONE_WITH_TOKEN; - } else { - uint8_t destination = mstp_port->TxBuffer[3]; - RS485_Send_Frame(mstp_port, - (uint8_t *) & mstp_port->TxBuffer[0], mstp_port->TxLength); - mstp_port->FrameCount++; - switch (mstp_port->TxFrameType) { - case FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY: - /* SendAndWait */ - if (destination == MSTP_BROADCAST_ADDRESS) - mstp_port->master_state = - MSTP_MASTER_STATE_DONE_WITH_TOKEN; - else - mstp_port->master_state = - MSTP_MASTER_STATE_WAIT_FOR_REPLY; - break; - case FRAME_TYPE_TEST_REQUEST: - mstp_port->master_state = - MSTP_MASTER_STATE_WAIT_FOR_REPLY; - break; - case FRAME_TYPE_TEST_RESPONSE: - case FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY: - default: - /* SendNoWait */ - mstp_port->master_state = - MSTP_MASTER_STATE_DONE_WITH_TOKEN; - break; - } - mstp_port->TxReady = false; - } - transition_now = true; - break; - /* In the WAIT_FOR_REPLY state, the node waits for */ - /* a reply from another node. */ - case MSTP_MASTER_STATE_WAIT_FOR_REPLY: - if (mstp_port->SilenceTimer >= Treply_timeout) { - /* ReplyTimeout */ - /* assume that the request has failed */ - mstp_port->FrameCount = mstp_port->Nmax_info_frames; - mstp_port->master_state = MSTP_MASTER_STATE_DONE_WITH_TOKEN; - /* Any retry of the data frame shall await the next entry */ - /* to the USE_TOKEN state. (Because of the length of the timeout, */ - /* this transition will cause the token to be passed regardless */ - /* of the initial value of FrameCount.) */ - transition_now = true; - } else { - if (mstp_port->ReceivedInvalidFrame == true) { - /* InvalidFrame */ - /* error in frame reception */ - mstp_port->ReceivedInvalidFrame = false; - mstp_port->master_state = - MSTP_MASTER_STATE_DONE_WITH_TOKEN; - transition_now = true; - } else if (mstp_port->ReceivedValidFrame == true) { - if (mstp_port->DestinationAddress == - mstp_port->This_Station) { - switch (mstp_port->TxFrameType) { - case FRAME_TYPE_REPLY_POSTPONED: - /* ReceivedReplyPostponed */ - mstp_port->master_state = - MSTP_MASTER_STATE_DONE_WITH_TOKEN; - break; - case FRAME_TYPE_TEST_RESPONSE: - mstp_port->master_state = - MSTP_MASTER_STATE_DONE_WITH_TOKEN; - break; - case FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY: - /* ReceivedReply */ - /* or a proprietary type that indicates a reply */ - /* indicate successful reception to the higher layers */ - dlmstp_put_receive(mstp_port->SourceAddress, /* source MS/TP address */ - (uint8_t *) & mstp_port->InputBuffer[0], - mstp_port->DataLength); - mstp_port->master_state = - MSTP_MASTER_STATE_DONE_WITH_TOKEN; - break; - default: - /* if proprietary frame was expected, you might - need to transition to DONE WITH TOKEN */ - mstp_port->master_state = - MSTP_MASTER_STATE_IDLE; - break; - } - } else { - /* ReceivedUnexpectedFrame */ - /* an unexpected frame was received */ - /* This may indicate the presence of multiple tokens. */ - /* Synchronize with the network. */ - /* This action drops the token. */ - mstp_port->master_state = MSTP_MASTER_STATE_IDLE; - } - mstp_port->ReceivedValidFrame = false; - transition_now = true; - } - } - break; - /* The DONE_WITH_TOKEN state either sends another data frame, */ - /* passes the token, or initiates a Poll For Master cycle. */ - case MSTP_MASTER_STATE_DONE_WITH_TOKEN: - /* SendAnotherFrame */ - if (mstp_port->FrameCount < mstp_port->Nmax_info_frames) { - /* then this node may send another information frame */ - /* before passing the token. */ - mstp_port->master_state = MSTP_MASTER_STATE_USE_TOKEN; - } else if ((mstp_port->SoleMaster == false) && - (mstp_port->Next_Station == mstp_port->This_Station)) { - /* NextStationUnknown - added in Addendum 135-2008v-1 */ - /* then the next station to which the token - should be sent is unknown - so PollForMaster */ - mstp_port->Poll_Station = next_this_station; - MSTP_Create_And_Send_Frame(mstp_port, - FRAME_TYPE_POLL_FOR_MASTER, mstp_port->Poll_Station, - mstp_port->This_Station, NULL, 0); - mstp_port->RetryCount = 0; - mstp_port->master_state = MSTP_MASTER_STATE_POLL_FOR_MASTER; - } - /* Npoll changed in Errata SSPC-135-2004 */ - else if (mstp_port->TokenCount < (Npoll - 1)) { - if ((mstp_port->SoleMaster == true) && - (mstp_port->Next_Station != next_this_station)) { - /* SoleMaster */ - /* there are no other known master nodes to */ - /* which the token may be sent (true master-slave operation). */ - mstp_port->FrameCount = 0; - mstp_port->TokenCount++; - mstp_port->master_state = MSTP_MASTER_STATE_USE_TOKEN; - } else { - /* SendToken */ - /* Npoll changed in Errata SSPC-135-2004 */ - /* The comparison of NS and TS+1 eliminates the Poll For Master */ - /* if there are no addresses between TS and NS, since there is no */ - /* address at which a new master node may be found in that case. */ - mstp_port->TokenCount++; - /* transmit a Token frame to NS */ - MSTP_Create_And_Send_Frame(mstp_port, FRAME_TYPE_TOKEN, - mstp_port->Next_Station, mstp_port->This_Station, NULL, - 0); - mstp_port->RetryCount = 0; - mstp_port->EventCount = 0; - mstp_port->master_state = MSTP_MASTER_STATE_PASS_TOKEN; - } - } else if (next_poll_station == mstp_port->Next_Station) { - if (mstp_port->SoleMaster == true) { - /* SoleMasterRestartMaintenancePFM */ - mstp_port->Poll_Station = next_next_station; - MSTP_Create_And_Send_Frame(mstp_port, - FRAME_TYPE_POLL_FOR_MASTER, mstp_port->Poll_Station, - mstp_port->This_Station, NULL, 0); - /* no known successor node */ - mstp_port->Next_Station = mstp_port->This_Station; - mstp_port->RetryCount = 0; - mstp_port->TokenCount = 1; /* changed in Errata SSPC-135-2004 */ - /* mstp_port->EventCount = 0; removed in Addendum 135-2004d-8 */ - /* find a new successor to TS */ - mstp_port->master_state = - MSTP_MASTER_STATE_POLL_FOR_MASTER; - } else { - /* ResetMaintenancePFM */ - mstp_port->Poll_Station = mstp_port->This_Station; - /* transmit a Token frame to NS */ - MSTP_Create_And_Send_Frame(mstp_port, FRAME_TYPE_TOKEN, - mstp_port->Next_Station, mstp_port->This_Station, NULL, - 0); - mstp_port->RetryCount = 0; - mstp_port->TokenCount = 1; /* changed in Errata SSPC-135-2004 */ - mstp_port->EventCount = 0; - mstp_port->master_state = MSTP_MASTER_STATE_PASS_TOKEN; - } - } else { - /* SendMaintenancePFM */ - mstp_port->Poll_Station = next_poll_station; - MSTP_Create_And_Send_Frame(mstp_port, - FRAME_TYPE_POLL_FOR_MASTER, mstp_port->Poll_Station, - mstp_port->This_Station, NULL, 0); - mstp_port->RetryCount = 0; - mstp_port->master_state = MSTP_MASTER_STATE_POLL_FOR_MASTER; - } - transition_now = true; - break; - /* The PASS_TOKEN state listens for a successor to begin using */ - /* the token that this node has just attempted to pass. */ - case MSTP_MASTER_STATE_PASS_TOKEN: - if (mstp_port->SilenceTimer < Tusage_timeout) { - if (mstp_port->EventCount > Nmin_octets) { - /* SawTokenUser */ - /* Assume that a frame has been sent by the new token user. */ - /* Enter the IDLE state to process the frame. */ - mstp_port->master_state = MSTP_MASTER_STATE_IDLE; - transition_now = true; - } - } else { - if (mstp_port->RetryCount < Nretry_token) { - /* RetrySendToken */ - mstp_port->RetryCount++; - /* Transmit a Token frame to NS */ - MSTP_Create_And_Send_Frame(mstp_port, FRAME_TYPE_TOKEN, - mstp_port->Next_Station, mstp_port->This_Station, NULL, - 0); - mstp_port->EventCount = 0; - /* re-enter the current state to listen for NS */ - /* to begin using the token. */ - } else { - /* FindNewSuccessor */ - /* Assume that NS has failed. */ - /* note: if NS=TS-1, this node could send PFM to self! */ - mstp_port->Poll_Station = next_next_station; - /* Transmit a Poll For Master frame to PS. */ - MSTP_Create_And_Send_Frame(mstp_port, - FRAME_TYPE_POLL_FOR_MASTER, mstp_port->Poll_Station, - mstp_port->This_Station, NULL, 0); - /* no known successor node */ - mstp_port->Next_Station = mstp_port->This_Station; - mstp_port->RetryCount = 0; - mstp_port->TokenCount = 0; - /* mstp_port->EventCount = 0; removed in Addendum 135-2004d-8 */ - /* find a new successor to TS */ - mstp_port->master_state = - MSTP_MASTER_STATE_POLL_FOR_MASTER; - transition_now = true; - } - } - break; - /* The NO_TOKEN state is entered if mstp_port->SilenceTimer becomes greater */ - /* than Tno_token, indicating that there has been no network activity */ - /* for that period of time. The timeout is continued to determine */ - /* whether or not this node may create a token. */ - case MSTP_MASTER_STATE_NO_TOKEN: - my_timeout = Tno_token + (Tslot * mstp_port->This_Station); - if (mstp_port->SilenceTimer < my_timeout) { - if (mstp_port->EventCount > Nmin_octets) { - /* SawFrame */ - /* Some other node exists at a lower address. */ - /* Enter the IDLE state to receive and process the incoming frame. */ - mstp_port->master_state = MSTP_MASTER_STATE_IDLE; - transition_now = true; - } - } else { - ns_timeout = - Tno_token + (Tslot * (mstp_port->This_Station + 1)); - if (mstp_port->SilenceTimer < ns_timeout) { - /* GenerateToken */ - /* Assume that this node is the lowest numerical address */ - /* on the network and is empowered to create a token. */ - mstp_port->Poll_Station = next_this_station; - /* Transmit a Poll For Master frame to PS. */ - MSTP_Create_And_Send_Frame(mstp_port, - FRAME_TYPE_POLL_FOR_MASTER, mstp_port->Poll_Station, - mstp_port->This_Station, NULL, 0); - /* indicate that the next station is unknown */ - mstp_port->Next_Station = mstp_port->This_Station; - mstp_port->RetryCount = 0; - mstp_port->TokenCount = 0; - /* mstp_port->EventCount = 0; removed Addendum 135-2004d-8 */ - /* enter the POLL_FOR_MASTER state to find a new successor to TS. */ - mstp_port->master_state = - MSTP_MASTER_STATE_POLL_FOR_MASTER; - transition_now = true; - } - } - break; - /* In the POLL_FOR_MASTER state, the node listens for a reply to */ - /* a previously sent Poll For Master frame in order to find */ - /* a successor node. */ - case MSTP_MASTER_STATE_POLL_FOR_MASTER: - if (mstp_port->ReceivedValidFrame == true) { - if ((mstp_port->DestinationAddress == mstp_port->This_Station) - && (mstp_port->FrameType == - FRAME_TYPE_REPLY_TO_POLL_FOR_MASTER)) { - /* ReceivedReplyToPFM */ - mstp_port->SoleMaster = false; - mstp_port->Next_Station = mstp_port->SourceAddress; - mstp_port->EventCount = 0; - /* Transmit a Token frame to NS */ - MSTP_Create_And_Send_Frame(mstp_port, FRAME_TYPE_TOKEN, - mstp_port->Next_Station, mstp_port->This_Station, NULL, - 0); - mstp_port->Poll_Station = mstp_port->This_Station; - mstp_port->TokenCount = 0; - mstp_port->RetryCount = 0; - mstp_port->master_state = MSTP_MASTER_STATE_PASS_TOKEN; - } else { - /* ReceivedUnexpectedFrame */ - /* An unexpected frame was received. */ - /* This may indicate the presence of multiple tokens. */ - /* enter the IDLE state to synchronize with the network. */ - /* This action drops the token. */ - mstp_port->master_state = MSTP_MASTER_STATE_IDLE; - } - mstp_port->ReceivedValidFrame = false; - transition_now = true; - } else if ((mstp_port->SilenceTimer >= Tusage_timeout) || - (mstp_port->ReceivedInvalidFrame == true)) { - if (mstp_port->SoleMaster == true) { - /* SoleMaster */ - /* There was no valid reply to the periodic poll */ - /* by the sole known master for other masters. */ - mstp_port->FrameCount = 0; - /* mstp_port->TokenCount++; removed in 2004 */ - mstp_port->master_state = MSTP_MASTER_STATE_USE_TOKEN; - } else { - if (mstp_port->Next_Station != mstp_port->This_Station) { - /* DoneWithPFM */ - /* There was no valid reply to the maintenance */ - /* poll for a master at address PS. */ - mstp_port->EventCount = 0; - /* transmit a Token frame to NS */ - MSTP_Create_And_Send_Frame(mstp_port, FRAME_TYPE_TOKEN, - mstp_port->Next_Station, mstp_port->This_Station, - NULL, 0); - mstp_port->RetryCount = 0; - mstp_port->master_state = MSTP_MASTER_STATE_PASS_TOKEN; - } else { - if (next_poll_station != mstp_port->This_Station) { - /* SendNextPFM */ - mstp_port->Poll_Station = next_poll_station; - /* Transmit a Poll For Master frame to PS. */ - MSTP_Create_And_Send_Frame(mstp_port, - FRAME_TYPE_POLL_FOR_MASTER, - mstp_port->Poll_Station, - mstp_port->This_Station, NULL, 0); - mstp_port->RetryCount = 0; - /* Re-enter the current state. */ - } else { - /* DeclareSoleMaster */ - /* to indicate that this station is the only master */ - mstp_port->SoleMaster = true; - mstp_port->FrameCount = 0; - mstp_port->master_state = - MSTP_MASTER_STATE_USE_TOKEN; - } - } - } - mstp_port->ReceivedInvalidFrame = false; - transition_now = true; - } - break; - /* The ANSWER_DATA_REQUEST state is entered when a */ - /* BACnet Data Expecting Reply, a Test_Request, or */ - /* a proprietary frame that expects a reply is received. */ - case MSTP_MASTER_STATE_ANSWER_DATA_REQUEST: -#if 0 - if (mstp_port->ReplyPostponedTimer <= Treply_delay) { - /* FIXME: we always defer the reply to be safe */ - /* FIXME: if we knew the APDU type received, we could - see if the next message was that same APDU type - along with the matching src/dest and invoke ID */ - if ((mstp_port->FrameType == - FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY) - && (mstp_port->TxReady)) { - /* Reply */ - /* If a reply is available from the higher layers */ - /* within Treply_delay after the reception of the */ - /* final octet of the requesting frame */ - /* (the mechanism used to determine this is a local matter), */ - /* then call MSTP_Create_And_Send_Frame to transmit the reply frame */ - /* and enter the IDLE state to wait for the next frame. */ - RS485_Send_Frame(mstp_port, - (uint8_t *) & mstp_port->TxBuffer[0], - mstp_port->TxLength); - mstp_port->TxReady = false; - mstp_port->master_state = MSTP_MASTER_STATE_IDLE; - transition_now = true; - } else { - /* Test Request - handled directly in IDLE state */ - } - } else -#endif - /* DeferredReply */ - /* If no reply will be available from the higher layers */ - /* within Treply_delay after the reception of the */ - /* final octet of the requesting frame (the mechanism */ - /* used to determine this is a local matter), */ - /* then an immediate reply is not possible. */ - /* Any reply shall wait until this node receives the token. */ - /* Call MSTP_Create_And_Send_Frame to transmit a Reply Postponed frame, */ - /* and enter the IDLE state. */ - { - MSTP_Create_And_Send_Frame(mstp_port, - FRAME_TYPE_REPLY_POSTPONED, mstp_port->SourceAddress, - mstp_port->This_Station, NULL, 0); - mstp_port->master_state = MSTP_MASTER_STATE_IDLE; - transition_now = true; - } - break; - default: - mstp_port->master_state = MSTP_MASTER_STATE_IDLE; - break; - } - - return transition_now; -} - -void MSTP_Init( - volatile struct mstp_port_struct_t *mstp_port, - uint8_t this_station_mac) -{ - int i; /*loop counter */ - - if (mstp_port) { - mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; - mstp_port->master_state = MSTP_MASTER_STATE_INITIALIZE; - mstp_port->ReceiveError = false; - mstp_port->DataAvailable = false; - mstp_port->DataRegister = 0; - mstp_port->DataCRC = 0; - mstp_port->DataCRC = 0; - mstp_port->DataLength = 0; - mstp_port->DestinationAddress = 0; - mstp_port->EventCount = 0; - mstp_port->FrameType = FRAME_TYPE_TOKEN; - mstp_port->FrameCount = 0; - mstp_port->HeaderCRC = 0; - mstp_port->Index = 0; - mstp_port->Index = 0; - for (i = 0; i < sizeof(mstp_port->InputBuffer); i++) { - mstp_port->InputBuffer[i] = 0; - } - mstp_port->Next_Station = this_station_mac; - mstp_port->Poll_Station = this_station_mac; - mstp_port->ReceivedInvalidFrame = false; - mstp_port->ReceivedValidFrame = false; - mstp_port->RetryCount = 0; - mstp_port->SilenceTimer = 0; - mstp_port->ReplyPostponedTimer = 0; - mstp_port->SoleMaster = false; - mstp_port->SourceAddress = 0; - mstp_port->TokenCount = 0; - mstp_port->This_Station = this_station_mac; - mstp_port->Nmax_info_frames = DEFAULT_MAX_INFO_FRAMES; - mstp_port->Nmax_master = DEFAULT_MAX_MASTER; - - /* An array of octets, used to store PDU octets prior to being transmitted. */ - /* This array is only used for APDU messages */ - for (i = 0; i < sizeof(mstp_port->TxBuffer); i++) { - mstp_port->TxBuffer[i] = 0; - } - mstp_port->TxLength = 0; - mstp_port->TxReady = false; - mstp_port->TxFrameType = 0; - - } -} diff --git a/ports/rtos32/mstp.h b/ports/rtos32/mstp.h deleted file mode 100644 index 2c28ddb7..00000000 --- a/ports/rtos32/mstp.h +++ /dev/null @@ -1,193 +0,0 @@ -/*####COPYRIGHTBEGIN#### - ------------------------------------------- - Copyright (C) 2004 Steve Karg - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to: - The Free Software Foundation, Inc. - 59 Temple Place - Suite 330 - Boston, MA 02111-1307 - USA. - - As a special exception, if other files instantiate templates or - use macros or inline functions from this file, or you compile - this file and link it with other works to produce a work based - on this file, this file does not by itself cause the resulting - work to be covered by the GNU General Public License. However - the source code for this file must still be made available in - accordance with section (3) of the GNU General Public License. - - This exception does not invalidate any other reasons why a work - based on this file might be covered by the GNU General Public - License. - ------------------------------------------- -####COPYRIGHTEND####*/ - -#ifndef MSTP_H -#define MSTP_H - -#include -#include -#include -#include "bacdef.h" -#include "mstpdef.h" -#include "dlmstp.h" - -struct mstp_port_struct_t { - MSTP_RECEIVE_STATE receive_state; - /* When a master node is powered up or reset, */ - /* it shall unconditionally enter the INITIALIZE state. */ - MSTP_MASTER_STATE master_state; - /* A Boolean flag set to TRUE by the Receive State Machine */ - /* if an error is detected during the reception of a frame. */ - /* Set to FALSE by the main state machine. */ - unsigned ReceiveError:1; - /* There is data in the buffer */ - unsigned DataAvailable:1; - unsigned FramingError:1; /* TRUE if we got a framing error */ - unsigned ReceivedInvalidFrame:1; - /* A Boolean flag set to TRUE by the Receive State Machine */ - /* if a valid frame is received. */ - /* Set to FALSE by the main state machine. */ - unsigned ReceivedValidFrame:1; - /* A Boolean flag set to TRUE by the master machine if this node is the */ - /* only known master node. */ - unsigned SoleMaster:1; - /* After receiving a frame this value will be TRUE until Tturnaround */ - /* has expired */ - unsigned Turn_Around_Waiting:1; - /* stores the latest received data */ - uint8_t DataRegister; - /* Used to accumulate the CRC on the data field of a frame. */ - uint16_t DataCRC; - /* Used to store the data length of a received frame. */ - unsigned DataLength; - /* Used to store the destination address of a received frame. */ - uint8_t DestinationAddress; - /* Used to count the number of received octets or errors. */ - /* This is used in the detection of link activity. */ - /* Compared to Nmin_octets */ - uint8_t EventCount; - /* Used to store the frame type of a received frame. */ - uint8_t FrameType; - /* The number of frames sent by this node during a single token hold. */ - /* When this counter reaches the value Nmax_info_frames, the node must */ - /* pass the token. */ - unsigned FrameCount; - /* Used to accumulate the CRC on the header of a frame. */ - uint8_t HeaderCRC; - /* Used as an index by the Receive State Machine, up to a maximum value of */ - /* InputBufferSize. */ - unsigned Index; - /* An array of octets, used to store octets as they are received. */ - /* InputBuffer is indexed from 0 to InputBufferSize-1. */ - /* The maximum size of a frame is 501 octets. */ - uint8_t InputBuffer[MAX_MPDU]; - /* "Next Station," the MAC address of the node to which This Station passes */ - /* the token. If the Next_Station is unknown, Next_Station shall be equal to */ - /* This_Station. */ - uint8_t Next_Station; - /* "Poll Station," the MAC address of the node to which This Station last */ - /* sent a Poll For Master. This is used during token maintenance. */ - uint8_t Poll_Station; - /* A counter of transmission retries used for Token and Poll For Master */ - /* transmission. */ - unsigned RetryCount; - /* A timer with nominal 5 millisecond resolution used to measure and */ - /* generate silence on the medium between octets. It is incremented by a */ - /* timer process and is cleared by the Receive State Machine when activity */ - /* is detected and by the SendFrame procedure as each octet is transmitted. */ - /* Since the timer resolution is limited and the timer is not necessarily */ - /* synchronized to other machine events, a timer value of N will actually */ - /* denote intervals between N-1 and N */ - uint16_t SilenceTimer; - - /* A timer used to measure and generate Reply Postponed frames. It is */ - /* incremented by a timer process and is cleared by the Master Node State */ - /* Machine when a Data Expecting Reply Answer activity is completed. */ - uint16_t ReplyPostponedTimer; - - /* Used to store the Source Address of a received frame. */ - uint8_t SourceAddress; - - /* The number of tokens received by this node. When this counter reaches the */ - /* value Npoll, the node polls the address range between TS and NS for */ - /* additional master nodes. TokenCount is set to zero at the end of the */ - /* polling process. */ - unsigned TokenCount; - - /* "This Station," the MAC address of this node. TS is generally read from a */ - /* hardware DIP switch, or from nonvolatile memory. Valid values for TS are */ - /* 0 to 254. The value 255 is used to denote broadcast when used as a */ - /* destination address but is not allowed as a value for TS. */ - uint8_t This_Station; - - /* This parameter represents the value of the Max_Info_Frames property of */ - /* the node's Device object. The value of Max_Info_Frames specifies the */ - /* maximum number of information frames the node may send before it must */ - /* pass the token. Max_Info_Frames may have different values on different */ - /* nodes. This may be used to allocate more or less of the available link */ - /* bandwidth to particular nodes. If Max_Info_Frames is not writable in a */ - /* node, its value shall be 1. */ - unsigned Nmax_info_frames; - - /* This parameter represents the value of the Max_Master property of the */ - /* node's Device object. The value of Max_Master specifies the highest */ - /* allowable address for master nodes. The value of Max_Master shall be */ - /* less than or equal to 127. If Max_Master is not writable in a node, */ - /* its value shall be 127. */ - unsigned Nmax_master; - - /* An array of octets, used to store PDU octets prior to being transmitted. */ - /* This array is only used for APDU messages */ - uint8_t TxBuffer[MAX_MPDU]; - unsigned TxLength; - bool TxReady; /* true if ready to be sent or received */ - uint8_t TxFrameType; /* type of message - needed by MS/TP */ -}; - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - - void MSTP_Init( - volatile struct mstp_port_struct_t *mstp_port, - uint8_t this_station_mac); - void MSTP_Millisecond_Timer( - volatile struct mstp_port_struct_t - *mstp_port); - void MSTP_Receive_Frame_FSM( - volatile struct mstp_port_struct_t - *mstp_port); - bool MSTP_Master_Node_FSM( - volatile struct mstp_port_struct_t - *mstp_port); - - /* returns true if line is active */ - bool MSTP_Line_Active( - volatile struct mstp_port_struct_t *mstp_port); - - unsigned MSTP_Create_Frame( - uint8_t * buffer, /* where frame is loaded */ - unsigned buffer_len, /* amount of space available */ - uint8_t frame_type, /* type of frame to send - see defines */ - uint8_t destination, /* destination address */ - uint8_t source, /* source address */ - uint8_t * data, /* any data to be sent - may be null */ - unsigned data_len); /* number of bytes of data (up to 501) */ - - -#ifdef __cplusplus -} -#endif /* __cplusplus */ -#endif diff --git a/ports/rtos32/net.h b/ports/rtos32/net.h deleted file mode 100644 index 5f6b680d..00000000 --- a/ports/rtos32/net.h +++ /dev/null @@ -1,80 +0,0 @@ -/************************************************************************** -* -* Copyright (C) 2005 Steve Karg -* -* Permission is hereby granted, free of charge, to any person obtaining -* a copy of this software and associated documentation files (the -* "Software"), to deal in the Software without restriction, including -* without limitation the rights to use, copy, modify, merge, publish, -* distribute, sublicense, and/or sell copies of the Software, and to -* permit persons to whom the Software is furnished to do so, subject to -* the following conditions: -* -* The above copyright notice and this permission notice shall be included -* in all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -* -*********************************************************************/ -#ifndef NET_H -#define NET_H - -/* network file for RTOS-32 from On-Time */ -#define WIN32_LEAN_AND_MEAN -#define STRICT - -#include -#include -#include -#include - -#include "bip.h" -#ifndef HOST -#include -#include "netcfg.h" -#include -#include -#include -#include - -/* - * Definitions of bits in internet address integers. - * On subnets, the decomposition of addresses to host and net parts - * is done according to subnet mask, not the masks here. - */ -#define IN_CLASSA(i) (((long)(i) & 0x80000000) == 0) -#define IN_CLASSA_NET 0xff000000 -#define IN_CLASSA_NSHIFT 24 -#define IN_CLASSA_HOST 0x00ffffff -#define IN_CLASSA_MAX 128 - -#define IN_CLASSB(i) (((long)(i) & 0xc0000000) == 0x80000000) -#define IN_CLASSB_NET 0xffff0000 -#define IN_CLASSB_NSHIFT 16 -#define IN_CLASSB_HOST 0x0000ffff -#define IN_CLASSB_MAX 65536 - -#define IN_CLASSC(i) (((long)(i) & 0xe0000000) == 0xc0000000) -#define IN_CLASSC_NET 0xffffff00 -#define IN_CLASSC_NSHIFT 8 -#define IN_CLASSC_HOST 0x000000ff - -#define IN_CLASSD(i) (((long)(i) & 0xf0000000) == 0xe0000000) -#define IN_CLASSD_NET 0xf0000000 /* These ones aren't really */ -#define IN_CLASSD_NSHIFT 28 /* net and host fields, but */ -#define IN_CLASSD_HOST 0x0fffffff /* routing needn't know. */ -#define IN_MULTICAST(i) IN_CLASSD(i) - -#else -#include -#endif -#define close closesocket -typedef size_t socklen_t; - -#endif diff --git a/ports/rtos32/netcfg.h b/ports/rtos32/netcfg.h deleted file mode 100644 index 304ddea1..00000000 --- a/ports/rtos32/netcfg.h +++ /dev/null @@ -1,104 +0,0 @@ -/**************************************************************************/ -/* */ -/* File: NetCfg.h Copyright (c) 1996,2004 */ -/* Version: 4.0 On Time Informatik GmbH */ -/* */ -/* */ -/* On Time /////////////----- */ -/* Informatik GmbH ///////////// */ -/* --------------------------------------------------///////////// */ -/* Real-Time and System Software */ -/* */ -/**************************************************************************/ - -/* Network environment configuration file for the On Time RTOS-32 RTIP-32 - demos. - - By default, the RTIP-32 demos use static IP address assignment. If this is - not what you want, uncomment either #define AUTO_IP or #define DHCP. In all - cases, make sure the IP addresses (NetMask, TargetIP, DefaultGateway, - DNSServer, etc) given in the respective section below are all correct for - your select and LAN configuration. If you choose to use DHCP, the library - Dhcpc.lib must also be linked. - - Please define symbol DEVICE_ID to match your target's ethernet - card and make sure that the card's hardware resource assigments are - correct (for PCI cards, the drivers will determine this information - automatically). - -*/ - -/* #define AUTO_IP // use xn_autoip() to get an IP address */ -/* #define DHCP // if you enable this, you must also link library dhcpc.lib */ - -#if defined(AUTO_IP) /* use xn_autoip() to get an IP address */ -static BYTE TargetIP[] = { 0, 0, 0, 0 }; /* will be filled at run-time */ -static BYTE NetMask[] = { 255, 255, 255, 0 }; -static BYTE MinIP[] = { 192, 168, 0, 128 }; -static BYTE MaxIP[] = { 192, 168, 0, 255 }; -static BYTE DefaultGateway[] = { 192, 168, 0, 1 }; /* set to zero if not available or required */ -static BYTE DNSServer[] = { 192, 168, 0, 1 }; /* ditto */ -#elif defined(DHCP) /* use DHCP */ -#include -static BYTE TargetIP[] = { 0, 0, 0, 0 }; /* will be filled at run-time */ -#else /* static IP address assignment (default) */ -static BYTE TargetIP[] = { 192, 168, 0, 50 }; -static BYTE NetMask[] = { 255, 255, 255, 0 }; -static BYTE DefaultGateway[] = { 192, 168, 0, 1 }; /* set to zero if not available or required */ -static BYTE DNSServer[] = { 192, 168, 0, 1 }; /* ditto */ -#endif - -#define DEVICE_ID DAVICOM_DEVICE /* define your device type here */ - -#ifndef DEVICE_ID -#error You must define Ethernet driver/resources and IP address/net mask here -#endif - -/* The following values are ignored for PCI devices (the BIOS supplies */ -/* them), but they must be set correctly for ISA/PCMCIA systems and for */ -/* PCI devices if you do not have a BIOS */ - -#define ED_IO_ADD 0x300 /* I/O address of the device */ -#define ED_IRQ 5 /* IRQ of the device */ -#define ED_MEM_ADD 0 /* Memory Window (only some devices) */ - -/* Define function to pull in the required driver */ - -#if DEVICE_ID == NE2000_DEVICE -#define BIND_DRIVER xn_bind_ne2000 -#elif DEVICE_ID == N83815_DEVICE -#define BIND_DRIVER xn_bind_n83815 -#elif DEVICE_ID == TC90X_DEVICE -#define BIND_DRIVER xn_bind_tc90x -#elif DEVICE_ID == SMC91C9X_DEVICE -#define BIND_DRIVER xn_bind_smc91c9x -#elif DEVICE_ID == LANCE_DEVICE -#define BIND_DRIVER xn_bind_rtlance -#elif DEVICE_ID == LANCE_ISA_DEVICE -#define BIND_DRIVER xn_bind_lance_isa -#elif DEVICE_ID == LAN_CS89X0_DEVICE -#define BIND_DRIVER xn_bind_cs -#elif DEVICE_ID == I82559_DEVICE -#define BIND_DRIVER xn_bind_i82559 -#elif DEVICE_ID == R8139_DEVICE -#define BIND_DRIVER xn_bind_r8139 -#elif DEVICE_ID == DAVICOM_DEVICE -#define BIND_DRIVER xn_bind_davicom -#elif DEVICE_ID == RHINE_DEVICE -#define BIND_DRIVER xn_bind_rhine -#elif DEVICE_ID == AX172_DEVICE -#include /* must also link Rtusb.lib and UsbInit.cpp */ -#define BIND_DRIVER xn_bind_ax172 -#elif DEVICE_ID == AX772_DEVICE -#include /* must also link Rtusb.lib and UsbInit.cpp */ -#define BIND_DRIVER xn_bind_ax772 -#elif DEVICE_ID == PRISM_DEVICE -#include /* must also link Wlan.lib */ -#define BIND_DRIVER xn_bind_prism -#elif DEVICE_ID == PRISM_PCMCIA_DEVICE -#include -#include /* must also link Wlan.lib */ -#define BIND_DRIVER xn_bind_prism_pcmcia -#else -#error Invalid DEVICE_ID value -#endif diff --git a/ports/rtos32/rs485.c b/ports/rtos32/rs485.c deleted file mode 100644 index 0d1da09b..00000000 --- a/ports/rtos32/rs485.c +++ /dev/null @@ -1,228 +0,0 @@ -/************************************************************************** -* -* Copyright (C) 2005 Steve Karg -* -* Permission is hereby granted, free of charge, to any person obtaining -* a copy of this software and associated documentation files (the -* "Software"), to deal in the Software without restriction, including -* without limitation the rights to use, copy, modify, merge, publish, -* distribute, sublicense, and/or sell copies of the Software, and to -* permit persons to whom the Software is furnished to do so, subject to -* the following conditions: -* -* The above copyright notice and this permission notice shall be included -* in all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -* -*********************************************************************/ -#if PRINT_ENABLED -#define PRINT_ENABLED_RS485 1 -#else -#define PRINT_ENABLED_RS485 0 -#endif - -#include -#include -#include -#include -#if PRINT_ENABLED_RS485 -#include -#endif -#include "mstp.h" - -/* note: use the RTKernel-C API so that it can use this library */ - -#define RS485_IO_ENABLE(p) ModemControl(p,0,DTR); -#define RS485_TRANSMIT_ENABLE(p) ModemControl(p,1,RTS); -#define RS485_RECEIVE_ENABLE(p) ModemControl(p,0,RTS); - -/* COM port number - COM1 = 0 */ -static int RS485_Port = COM2; -/* baud rate */ -static long RS485_Baud = 9600; -/* io base address */ -static long RS485_Base = 0; -/* hardware IRQ number */ -static long RS485_IRQ_Number = 0; - -#if PRINT_ENABLED_RS485 -static FineTime RS485_Debug_Transmit_Timer; -#endif - -#if PRINT_ENABLED_RS485 -void RS485_Print_Frame( - int port, - FineTime timer, - uint8_t * buffer, /* frame to send (up to 501 bytes of data) */ - uint16_t nbytes) -{ - uint16_t i; /* byte counter */ - unsigned long duration; /* measures the time from last output to this one */ - unsigned long seconds; - unsigned long milliseconds; - - duration = ElapsedMilliSecs(timer); - seconds = duration / 1000U; - milliseconds = duration - (seconds * 1000U); - fprintf(stderr, "%0lu.%03lu: COM%d:", seconds, milliseconds, port + 1); - for (i = 0; i < nbytes; i++) { - unsigned value; - value = buffer[i]; - fprintf(stderr, " %02X", value); - } - fprintf(stderr, "\n"); - fflush(stderr); -} -#endif - -static void RS485_Standard_Port_Settings( - long port, - long *pIRQ, - long *pBase) -{ - switch (port) { - case COM1: - *pBase = (long) 0x3F8; - *pIRQ = 4L; - break; - case COM2: - *pBase = (long) 0x2F8; - *pIRQ = 3L; - break; - case COM3: - *pBase = (long) 0x3E8; - *pIRQ = 4L; - break; - case COM4: - *pBase = (long) 0x2E8; - *pIRQ = 3L; - break; - default: - break; - } -} - -static int TestCOMPort( - int Base) -{ /* base address of UART */ - int i; - - for (i = 0; i < 256; i++) { - RTOut(Base + 7, (BYTE) i); /* write scratch register */ - RTOut(Base + 1, RTIn(Base + 1)); /* read/write IER */ - if (RTIn(Base + 7) != i) /* check scratch register */ - return FALSE; - } - return TRUE; -} - -static RS485_Open_Port( - int port, /* COM port number - COM1 = 0 */ - long baud, /* baud rate */ - unsigned base, /* io base address */ - int irq) -{ /* hardware IRQ number */ - if (!TestCOMPort(base)) - return; - - /* setup the COM IO */ - SetIOBase(port, base); - SetIRQ(port, irq); - - if (irq < 8) - RTKIRQTopPriority(irq, 9); - - InitPort(port, baud, PARITY_NONE, 1, 8); - - if (HasFIFO(port)) - EnableFIFO(port, 8); - EnableCOMInterrupt(port, 1024 * 4); - - /* enable the 485 via the DTR pin */ - RS485_IO_ENABLE(port); - RS485_RECEIVE_ENABLE(port); -#if PRINT_ENABLED_RS485 - fprintf(stderr, "RS485: COM%d Enabled\r\n", port + 1); -#endif - - return; -} - -void RS485_Initialize( - void) -{ -#if PRINT_ENABLED_RS485 - MarkTime(&RS485_Debug_Transmit_Timer); -#endif - RS485_Standard_Port_Settings(RS485_Port, &RS485_IRQ_Number, &RS485_Base); - RS485_Open_Port(RS485_Port, RS485_Baud, RS485_Base, RS485_IRQ_Number); -} - -void RS485_Send_Frame( - volatile struct mstp_port_struct_t *mstp_port, /* port specific data */ - uint8_t * buffer, /* frame to send (up to 501 bytes of data) */ - uint16_t nbytes) -{ /* number of bytes of data (up to 501) */ - bool status = true; /* return value */ - - /* fixme: wait turnaround time */ - RS485_TRANSMIT_ENABLE(RS485_Port); - SendBlock(RS485_Port, (char *) buffer, nbytes); - /* need to wait at least 9600 baud * 512 bytes = 54mS */ - (void) WaitSendBufferEmpty(RS485_Port, MilliSecsToTicks(200)); - while (!(LineStatus(RS485_Port) & TX_SHIFT_EMPTY)) - RTKScheduler(); - RS485_RECEIVE_ENABLE(RS485_Port); - /* SilenceTimer is cleared by the Receive State Machine when - activity is detected and by the SendFrame procedure as each - octet is transmitted. */ - mstp_port->SilenceTimer = 0; -#if PRINT_ENABLED_RS485 - RS485_Print_Frame(RS485_Port, RS485_Debug_Transmit_Timer, buffer, /* frame to send (up to 501 bytes of data) */ - nbytes); - MarkTime(&RS485_Debug_Transmit_Timer); -#endif - - return; -} - -void RS485_Check_UART_Data( - volatile struct mstp_port_struct_t *mstp_port) -{ /* port specific data */ - COMData com_data = 0; /* byte from COM driver */ - unsigned timeout = 1; /* milliseconds to wait for a character */ - static Duration ticks = 0; /* duration to wait for data */ - - if (mstp_port->ReceiveError) { - /* wait for state machine to clear this */ - RTKScheduler(); - } - /* wait for state machine to read from the DataRegister */ - else if (!mstp_port->DataAvailable) { - if (!ticks) { - ticks = MilliSecsToTicks(timeout); - if (!ticks) - ticks = 1; - } - /* check for data */ - if (RTKGetTimed(ReceiveBuffer[RS485_Port], &com_data, ticks)) { - /* if error, */ - if (com_data & (COM_OVERRUN << 8)) - mstp_port->ReceiveError = true; - else if (com_data & (COM_FRAME << 8)) - mstp_port->ReceiveError = true; - else { - mstp_port->DataRegister = com_data & 0x00FF; - mstp_port->DataAvailable = true; - } - } - } else - RTKScheduler(); -} diff --git a/ports/rtos32/rs485.h b/ports/rtos32/rs485.h deleted file mode 100644 index 40a3fd3b..00000000 --- a/ports/rtos32/rs485.h +++ /dev/null @@ -1,60 +0,0 @@ -/*####COPYRIGHTBEGIN#### - ------------------------------------------- - Copyright (C) 2004 Steve Karg - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to: - The Free Software Foundation, Inc. - 59 Temple Place - Suite 330 - Boston, MA 02111-1307 - USA. - - As a special exception, if other files instantiate templates or - use macros or inline functions from this file, or you compile - this file and link it with other works to produce a work based - on this file, this file does not by itself cause the resulting - work to be covered by the GNU General Public License. However - the source code for this file must still be made available in - accordance with section (3) of the GNU General Public License. - - This exception does not invalidate any other reasons why a work - based on this file might be covered by the GNU General Public - License. - ------------------------------------------- -####COPYRIGHTEND####*/ - -#ifndef RS485_H -#define RS485_H - -#include -#include "mstp.h" - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - - void RS485_Initialize( - void); - - void RS485_Send_Frame( - volatile struct mstp_port_struct_t *mstp_port, /* port specific data */ - uint8_t * buffer, /* frame to send (up to 501 bytes of data) */ - uint16_t nbytes); /* number of bytes of data (up to 501) */ - - void RS485_Check_UART_Data( - volatile struct mstp_port_struct_t *mstp_port); /* port specific data */ - -#ifdef __cplusplus -} -#endif /* __cplusplus */ -#endif diff --git a/ports/rtos32/setvars.bat b/ports/rtos32/setvars.bat deleted file mode 100644 index 404c1998..00000000 --- a/ports/rtos32/setvars.bat +++ /dev/null @@ -1,3 +0,0 @@ -set BORLAND_DIR=\bc5 -set RTOS32_DIR=\code\rtos32 - diff --git a/ports/rtos32/software.cfg b/ports/rtos32/software.cfg deleted file mode 100644 index 9bde4528..00000000 --- a/ports/rtos32/software.cfg +++ /dev/null @@ -1,61 +0,0 @@ -// Configuration files for the application and Borland C/C++. - -// Some general parameters for this file are: - -// * The program will run under the control of the debugger or is -// downloaded using RTRun. -// * Paging is enabled. -// * The program privilege level is set to 3 for maximum protection. -// * Boot code and the Monitor are placed in low (conventional) memory. -// * The program is placed in high (extended) memory. -// * Unused low memory is remapped and appended to the high memory area. -// * The Turbo Debugger symbol tables are pulled in to support -// task positions at source level. - -@HARDWARE.CFG - -// Either use the monitor, or create bootable code. -#ifdef MONITOR - Reserve Monitor // leave room for Debug Monitor -#elifdef DEBUGDOS - Locate BootCode BIOSBOOT.EXE LowMem // boot from disk - Locate BootData BootData LowMem // must be in conventional mem - Locate DiskBuffer DiskIO LowMem 16k 16k // needed by disk boot code - NoFPU=0 // Check FPU - CPL = 3 // normal priveleges - VideoRAM ColorText // program output sent to Graphic Card -#else - Locate BootCode BIOSBOOT.EXE LowMem // boot from disk - Locate BootData BootData LowMem 0 16 // must be in conventional mem - Locate DiskBuffer DiskIO LowMem 16k 16k // needed by disk boot code - NoFPU=0 // Check FPU - CPL = 3 // normal priveleges -// VideoRAM ColorText // program output sent to Graphic Card - VideoRAM None // program output sent to file and host -#endif - -FillRAM HeapMem // remap unused RAM - -Locate Header Header LowMem // application header -Locate PageTable Paging LowMem 20k // paging to use this -Locate NTSection CODE ProgMem->HighMem // code section -Locate NTSection DATA ProgMem->HighMem // data section -Locate NTSection .tls ProgMem->HighMem // TLS data section -Locate NTSection .rdata ProgMem->HighMem // TLS directory -Locate Stack Stack StackMem->LowMem 6k // stack space for main() -Locate Heap Heap HeapMem // and the rest for the heap - -// Compression needed if we are short on disk space - but shortens download -// Note that this is discardable, unless we use -d- option of RTLoc -Locate DecompCode Expand LowMem // include decompression stuff -Locate DecompData ExBuffer LowMem - -Locate Copy Paging LowMem // compress Paging -Locate Copy CODE HighMem // compress CODE -Locate Copy DATA HighMem // compress DATA - -Locate Nothing FloppyDMA MoreLowMem 18k 64k ReadWrite // floppy driver - -Init _Init // do some standard initializations (see init.c) - -CommandLine "bacnet.exe" \ No newline at end of file diff --git a/ports/rtos32/stdbool.h b/ports/rtos32/stdbool.h deleted file mode 100644 index 696ffd85..00000000 --- a/ports/rtos32/stdbool.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef STDBOOL_H -#define STDBOOL_H - -/* C99 Boolean types for compilers without C99 support */ - -#ifndef __cplusplus -typedef char _Bool; -#ifndef bool -#define bool _Bool -#endif -#ifndef true -#define true 1 -#endif -#ifndef false -#define false 0 -#endif -#define __bool_true_false_are_defined 1 -#endif - -#ifndef FALSE -#define FALSE 0 -#endif - -#ifndef TRUE -#define TRUE 1 -#endif - -#endif diff --git a/ports/rtos32/stdint.h b/ports/rtos32/stdint.h deleted file mode 100644 index c094e202..00000000 --- a/ports/rtos32/stdint.h +++ /dev/null @@ -1,19 +0,0 @@ -/* Defines the standard integer types that are used in code */ -/* for the x86 processor and Borland Compiler */ - -#ifndef STDINT_H -#define STDINT_H - -#include - -typedef unsigned char uint8_t; /* 1 byte 0 to 255 */ -typedef signed char int8_t; /* 1 byte -127 to 127 */ -typedef unsigned short uint16_t; /* 2 bytes 0 to 65535 */ -typedef signed short int16_t; /* 2 bytes -32767 to 32767 */ -/*typedef unsigned short long uint24_t; // 3 bytes 0 to 16777215 */ -typedef unsigned long uint32_t; /* 4 bytes 0 to 4294967295 */ -typedef signed long int32_t; /* 4 bytes -2147483647 to 2147483647 */ -/* typedef signed long long int64_t; */ -/* typedef unsigned long long uint64_t; */ - -#endif /* STDINT_H */ diff --git a/ports/rx62n/BACnet_Ethernet_RX62N.hwp b/ports/rx62n/BACnet_Ethernet_RX62N.hwp deleted file mode 100644 index 574f6573..00000000 --- a/ports/rx62n/BACnet_Ethernet_RX62N.hwp +++ /dev/null @@ -1,310 +0,0 @@ -[HIMDBVersion] -2.0 -[DATABASE_VERSION] -"2.8" -[PROJECT_DETAILS] -"BACnet_Ethernet_RX62N" "C:\Documents and Settings\VMWare\My Documents\bacnet-stack\ports\rx62n\BACnet_Ethernet_RX62N\BACnet_Ethernet_RX62N" "C:\Documents and Settings\VMWare\My Documents\bacnet-stack\ports\rx62n\BACnet_Ethernet_RX62N\BACnet_Ethernet_RX62N\BACnet_Ethernet_RX62N.hwp" "RX" "Renesas RX Standard" "Application" "" "" -[INFORMATION] -"No project information available" -[TOOL_CHAIN] -"Renesas RX Standard Toolchain" "1.0.1.0" -[CONFIGURATIONS] -"Debug" "C:\Documents and Settings\VMWare\My Documents\bacnet-stack\ports\rx62n\BACnet_Ethernet_RX62N\BACnet_Ethernet_RX62N\Debug" -[BUILD_PHASES] -"Renesas OptLinker" 1 -"Renesas RX Assembler" 1 -"Renesas RX C/C++ Compiler" 1 -"Renesas RX C/C++ Library Generator" 1 -"Renesas RX Configurator" 1 -[TOOL_ENVIRONMENT] -[EXTENSIONS] -"Absolute file" "ABS" -"Assembly include file" "INC" -"Assembly list file" "LST" -"Assembly source file" "S" -"Assembly source file" "SRC" -"Binary file" "BIN" -"C header file" "H" -"C source file" "C" -"C++ header file" "HPP" -"C++ source file" "CC" -"C++ source file" "CP" -"C++ source file" "CPP" -"CPU information file" "CPU" -"Calling information file" "CAL" -"Configuration file" "CFG" -"Debug information file" "DBG" -"Hex file" "HEX" -"Library file" "LIB" -"Library information file" "LBP" -"Linkage map file" "MAP" -"Linkage symbol file" "FSY" -"Object file" "OBJ" -"Optimize map file" "bls" -"Preprocessed C source file" "P" -"Preprocessed C++ source file" "PP" -"Relocatable file" "REL" -"Rts information file" "RTS" -"S-Record file" "MOT" -"Stack information file" "SNI" -"TD include object file" "RTI" -[FILE_GROUPS] -"Absolute file" "BIN" "NONE" "" -"Assembly include file" "TEXT" "EDITOR" "" -"Assembly list file" "TEXT" "EDITOR" "" -"Assembly source file" "TEXT" "EDITOR" "" -"Binary file" "BIN" "NONE" "" -"C header file" "TEXT" "EDITOR" "" -"C source file" "TEXT" "EDITOR" "" -"C++ header file" "TEXT" "EDITOR" "" -"C++ source file" "TEXT" "EDITOR" "" -"CPU information file" "BIN" "NONE" "" -"Calling information file" "BIN" "NONE" "" -"Configuration file" "TEXT" "EDITOR" "" -"Debug information file" "BIN" "NONE" "" -"Hex file" "TEXT" "EDITOR" "" -"Library file" "BIN" "NONE" "" -"Library information file" "TEXT" "EDITOR" "" -"Linkage map file" "TEXT" "EDITOR" "" -"Linkage symbol file" "TEXT" "EDITOR" "" -"Object file" "BIN" "NONE" "" -"Optimize map file" "BIN" "NONE" "" -"Preprocessed C source file" "TEXT" "EDITOR" "" -"Preprocessed C++ source file" "TEXT" "EDITOR" "" -"Relocatable file" "BIN" "NONE" "" -"Rts information file" "BIN" "NONE" "" -"S-Record file" "TEXT" "EDITOR" "" -"Stack information file" "BIN" "NONE" "" -"TD include object file" "BIN" "NONE" "" -[ASSOCIATED_APPLICATIONS] -[TOOLCHAIN_PHASE] -"Renesas OptLinker" -"Renesas RX Assembler" -"Renesas RX C/C++ Compiler" -"Renesas RX C/C++ Library Generator" -"Renesas RX Configurator" -[UTILITY_PHASE] -[CUSTOM_PHASES] -[CUSTOM_PHASE_INPUT_GROUP] -[CUSTOM_PHASE_OUTPUT_SYNTAX] -[BUILD_ORDER] -"Renesas RX C/C++ Library Generator" 1 -"Renesas RX C/C++ Compiler" 1 -"Renesas RX Assembler" 1 -"Renesas OptLinker" 1 -"Renesas RX Configurator" 0 -[BUILD_PHASE_DETAILS] -"Renesas OptLinker" "Object file|Library file|Relocatable file" 0 -"Renesas RX Assembler" "Assembly source file|Linkage symbol file" 1 -"Renesas RX C/C++ Compiler" "C source file|C++ source file" 1 -"Renesas RX C/C++ Library Generator" "" 0 -"Renesas RX Configurator" "Configuration file" 0 -[BUILD_FILE_ORDER_Assembly source file] -"Renesas RX Assembler" 1 -[BUILD_FILE_ORDER_C source file] -"Renesas RX C/C++ Compiler" 1 -[BUILD_FILE_ORDER_C++ source file] -"Renesas RX C/C++ Compiler" 1 -[BUILD_FILE_ORDER_Linkage symbol file] -"Renesas RX Assembler" 1 -[SCRAP] -"Project Generator Setup File" "" -[MAPPINGS] -"Assembly source file" "Renesas RX Assembler" "Renesas RX C/C++ Compiler" -"Library file" "Renesas OptLinker" "Renesas RX C/C++ Library Generator" -"Object file" "Renesas OptLinker" "Renesas RX Assembler" -"Object file" "Renesas OptLinker" "Renesas RX C/C++ Compiler" -[PROJECT_FILES] -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\demo\handler\h_dcc.c" "User" "C source file|BACnet|Handler" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\demo\handler\h_npdu.c" "User" "C source file|BACnet|Handler" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\demo\handler\h_rd.c" "User" "C source file|BACnet|Handler" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\demo\handler\h_rp.c" "User" "C source file|BACnet|Handler" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\demo\handler\h_rpm.c" "User" "C source file|BACnet|Handler" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\demo\handler\h_whohas.c" "User" "C source file|BACnet|Handler" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\demo\handler\h_whois.c" "User" "C source file|BACnet|Handler" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\demo\handler\h_wp.c" "User" "C source file|BACnet|Handler" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\demo\handler\noserv.c" "User" "C source file|BACnet|Handler" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\demo\handler\s_iam.c" "User" "C source file|BACnet|Handler" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\demo\handler\s_ihave.c" "User" "C source file|BACnet|Handler" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\demo\handler\txbuf.c" "User" "C source file|BACnet|Handler" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\ports\rx62n\BACnet_Ethernet_RX62N\BACnet_Ethernet_RX62N\src\RPDL\Interrupt_ADC_10.c" "User" "C source file|RPDL" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\ports\rx62n\BACnet_Ethernet_RX62N\BACnet_Ethernet_RX62N\src\RPDL\Interrupt_ADC_12.c" "User" "C source file|RPDL" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\ports\rx62n\BACnet_Ethernet_RX62N\BACnet_Ethernet_RX62N\src\RPDL\Interrupt_BSC.c" "User" "C source file|RPDL" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\ports\rx62n\BACnet_Ethernet_RX62N\BACnet_Ethernet_RX62N\src\RPDL\Interrupt_CMT.c" "User" "C source file|RPDL" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\ports\rx62n\BACnet_Ethernet_RX62N\BACnet_Ethernet_RX62N\src\RPDL\Interrupt_DMAC.c" "User" "C source file|RPDL" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\ports\rx62n\BACnet_Ethernet_RX62N\BACnet_Ethernet_RX62N\src\RPDL\Interrupt_IIC.c" "User" "C source file|RPDL" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\ports\rx62n\BACnet_Ethernet_RX62N\BACnet_Ethernet_RX62N\src\RPDL\Interrupt_INTC.c" "User" "C source file|RPDL" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\ports\rx62n\BACnet_Ethernet_RX62N\BACnet_Ethernet_RX62N\src\RPDL\Interrupt_MTU.c" "User" "C source file|RPDL" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\ports\rx62n\BACnet_Ethernet_RX62N\BACnet_Ethernet_RX62N\src\RPDL\Interrupt_POE.c" "User" "C source file|RPDL" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\ports\rx62n\BACnet_Ethernet_RX62N\BACnet_Ethernet_RX62N\src\RPDL\Interrupt_SCI.c" "User" "C source file|RPDL" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\ports\rx62n\BACnet_Ethernet_RX62N\BACnet_Ethernet_RX62N\src\RPDL\Interrupt_SPI.c" "User" "C source file|RPDL" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\ports\rx62n\BACnet_Ethernet_RX62N\BACnet_Ethernet_RX62N\src\RPDL\Interrupt_TMR.c" "User" "C source file|RPDL" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\ports\rx62n\BACnet_Ethernet_RX62N\BACnet_Ethernet_RX62N\src\RPDL\Interrupt_WDT.c" "User" "C source file|RPDL" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\ports\rx62n\BACnet_Ethernet_RX62N\BACnet_Ethernet_RX62N\src\RPDL\Interrupt_not_RPDL.c" "User" "C source file|RPDL" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\ports\rx62n\BACnet_Ethernet_RX62N\BACnet_Ethernet_RX62N\src\bacnet\bacnet.c" "User" "C source file" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\ports\rx62n\BACnet_Ethernet_RX62N\BACnet_Ethernet_RX62N\src\bacnet\bacnet.h" "User" "C header file" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\ports\rx62n\BACnet_Ethernet_RX62N\BACnet_Ethernet_RX62N\src\bacnet\bo.c" "User" "C source file" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\ports\rx62n\BACnet_Ethernet_RX62N\BACnet_Ethernet_RX62N\src\bacnet\device.c" "User" "C source file" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\ports\rx62n\BACnet_Ethernet_RX62N\BACnet_Ethernet_RX62N\src\bacnet\ethernet.c" "User" "C source file" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\ports\rx62n\BACnet_Ethernet_RX62N\BACnet_Ethernet_RX62N\src\bacnet\hardware.h" "User" "C header file" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\ports\rx62n\BACnet_Ethernet_RX62N\BACnet_Ethernet_RX62N\src\bacnet\led.c" "User" "C source file" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\ports\rx62n\BACnet_Ethernet_RX62N\BACnet_Ethernet_RX62N\src\bacnet\led.h" "User" "C header file" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\ports\rx62n\BACnet_Ethernet_RX62N\BACnet_Ethernet_RX62N\src\bacnet\main.c" "User" "C source file" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\ports\rx62n\BACnet_Ethernet_RX62N\BACnet_Ethernet_RX62N\src\bacnet\timer-hdw.c" "User" "C source file" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\ports\rx62n\BACnet_Ethernet_RX62N\BACnet_Ethernet_RX62N\src\bacnet\timer.c" "User" "C source file" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\ports\rx62n\BACnet_Ethernet_RX62N\BACnet_Ethernet_RX62N\src\bacnet\timer.h" "User" "C header file" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\ports\rx62n\BACnet_Ethernet_RX62N\BACnet_Ethernet_RX62N\src\bsp\GlyphLib_v2.lib" "User" "Library file" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\ports\rx62n\BACnet_Ethernet_RX62N\BACnet_Ethernet_RX62N\src\bsp\YRDKRX62N_RSPI_API.c" "User" "C source file|bsp" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\ports\rx62n\BACnet_Ethernet_RX62N\BACnet_Ethernet_RX62N\src\bsp\dbsct.c" "User" "C source file|bsp" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\ports\rx62n\BACnet_Ethernet_RX62N\BACnet_Ethernet_RX62N\src\bsp\hwsetup.c" "User" "C source file|bsp" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\ports\rx62n\BACnet_Ethernet_RX62N\BACnet_Ethernet_RX62N\src\bsp\lcd.c" "User" "C source file|bsp" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\ports\rx62n\BACnet_Ethernet_RX62N\BACnet_Ethernet_RX62N\src\bsp\resetprg.c" "User" "C source file|bsp" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\ports\rx62n\BACnet_Ethernet_RX62N\BACnet_Ethernet_RX62N\src\bsp\sbrk.c" "User" "C source file|bsp" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\ports\rx62n\BACnet_Ethernet_RX62N\BACnet_Ethernet_RX62N\src\bsp\switch.c" "User" "C source file|bsp" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\ports\rx62n\BACnet_Ethernet_RX62N\BACnet_Ethernet_RX62N\src\driver\phy.c" "User" "C source file|driver" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\ports\rx62n\BACnet_Ethernet_RX62N\BACnet_Ethernet_RX62N\src\driver\r_ether.c" "User" "C source file|driver" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\src\abort.c" "User" "C source file|BACnet|Core" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\src\apdu.c" "User" "C source file|BACnet|Core" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\src\bacapp.c" "User" "C source file" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\src\bacdcode.c" "User" "C source file|BACnet|Core" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\src\bacerror.c" "User" "C source file|BACnet|Core" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\src\bacint.c" "User" "C source file|BACnet|Core" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\src\bacprop.c" "User" "C source file|BACnet|Core" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\src\bacreal.c" "User" "C source file|BACnet|Core" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\src\bacstr.c" "User" "C source file|BACnet|Core" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\src\datetime.c" "User" "C source file|BACnet|Core" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\src\dcc.c" "User" "C source file|BACnet|Core" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\src\iam.c" "User" "C source file|BACnet|Core" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\src\ihave.c" "User" "C source file|BACnet|Core" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\src\memcopy.c" "User" "C source file|BACnet|Core" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\src\npdu.c" "User" "C source file|BACnet|Core" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\src\rd.c" "User" "C source file|BACnet|Core" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\src\reject.c" "User" "C source file|BACnet|Core" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\src\rp.c" "User" "C source file|BACnet|Core" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\src\rpm.c" "User" "C source file|BACnet|Core" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\src\version.c" "User" "C source file|BACnet|Core" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\src\whohas.c" "User" "C source file|BACnet|Core" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\src\whois.c" "User" "C source file|BACnet|Core" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\src\wp.c" "User" "C source file|BACnet|Core" 2 -[FOLDER] -"C header file" "C header file" -"C source file" "C source file" -"C source file|BACnet" "" -"C source file|BACnet|Core" "" -"C source file|BACnet|Handler" "" -"C source file|RPDL" "" -"C source file|bsp" "" -"C source file|driver" "" -"C source file|user-app" "" -"Library file" "Library file" -[GENERAL_DATA_PROJECT] -"USE_CUSTOM_LINKAGE_ORDER" "0" -[ON_DEMAND_COMPONENTS_LOADED] -[SYNC_SESSION_NAMES] -[SESSIONS] -"DefaultSession" "C:\Documents and Settings\VMWare\My Documents\bacnet-stack\ports\rx62n\BACnet_Ethernet_RX62N\BACnet_Ethernet_RX62N\DefaultSession.hsf" 0 -"JLink" "C:\Documents and Settings\VMWare\My Documents\bacnet-stack\ports\rx62n\BACnet_Ethernet_RX62N\BACnet_Ethernet_RX62N\JLink.hsf" 0 -[GENERAL_DATA_SESSION_DefaultSession] -[GENERAL_DATA_SESSION_JLink] -[OPTIONS_Debug_Renesas OptLinker] -"Single Shot" "0c5147307f9dbc10" 5 -[OPTIONS_Debug_Renesas RX Assembler] -"Assembly source file" "091c6ad95f42bc10" 4 -"Linkage symbol file" "091c6ad95f42bc10" 4 -[OPTIONS_Debug_Renesas RX C/C++ Compiler] -"C source file" "0e4b370aaf9dbc10" 2 -"C++ source file" "0e4b370aaf9dbc10" 3 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\demo\handler\h_dcc.c" "0e4b370aaf9dbc10" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\demo\handler\h_npdu.c" "0e4b370aaf9dbc10" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\demo\handler\h_rd.c" "0e4b370aaf9dbc10" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\demo\handler\h_rp.c" "0e4b370aaf9dbc10" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\demo\handler\h_rpm.c" "0e4b370aaf9dbc10" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\demo\handler\h_whohas.c" "0e4b370aaf9dbc10" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\demo\handler\h_whois.c" "0e4b370aaf9dbc10" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\demo\handler\h_wp.c" "0e4b370aaf9dbc10" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\demo\handler\noserv.c" "0e4b370aaf9dbc10" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\demo\handler\s_iam.c" "0e4b370aaf9dbc10" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\demo\handler\s_ihave.c" "0e4b370aaf9dbc10" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\demo\handler\txbuf.c" "0e4b370aaf9dbc10" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\ports\rx62n\BACnet_Ethernet_RX62N\BACnet_Ethernet_RX62N\src\RPDL\Interrupt_ADC_10.c" "0e4b370aaf9dbc10" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\ports\rx62n\BACnet_Ethernet_RX62N\BACnet_Ethernet_RX62N\src\RPDL\Interrupt_ADC_12.c" "0e4b370aaf9dbc10" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\ports\rx62n\BACnet_Ethernet_RX62N\BACnet_Ethernet_RX62N\src\RPDL\Interrupt_BSC.c" "0e4b370aaf9dbc10" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\ports\rx62n\BACnet_Ethernet_RX62N\BACnet_Ethernet_RX62N\src\RPDL\Interrupt_CMT.c" "0e4b370aaf9dbc10" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\ports\rx62n\BACnet_Ethernet_RX62N\BACnet_Ethernet_RX62N\src\RPDL\Interrupt_DMAC.c" "0e4b370aaf9dbc10" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\ports\rx62n\BACnet_Ethernet_RX62N\BACnet_Ethernet_RX62N\src\RPDL\Interrupt_IIC.c" "0e4b370aaf9dbc10" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\ports\rx62n\BACnet_Ethernet_RX62N\BACnet_Ethernet_RX62N\src\RPDL\Interrupt_INTC.c" "0e4b370aaf9dbc10" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\ports\rx62n\BACnet_Ethernet_RX62N\BACnet_Ethernet_RX62N\src\RPDL\Interrupt_MTU.c" "0e4b370aaf9dbc10" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\ports\rx62n\BACnet_Ethernet_RX62N\BACnet_Ethernet_RX62N\src\RPDL\Interrupt_POE.c" "0e4b370aaf9dbc10" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\ports\rx62n\BACnet_Ethernet_RX62N\BACnet_Ethernet_RX62N\src\RPDL\Interrupt_SCI.c" "0e4b370aaf9dbc10" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\ports\rx62n\BACnet_Ethernet_RX62N\BACnet_Ethernet_RX62N\src\RPDL\Interrupt_SPI.c" "0e4b370aaf9dbc10" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\ports\rx62n\BACnet_Ethernet_RX62N\BACnet_Ethernet_RX62N\src\RPDL\Interrupt_TMR.c" "0e4b370aaf9dbc10" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\ports\rx62n\BACnet_Ethernet_RX62N\BACnet_Ethernet_RX62N\src\RPDL\Interrupt_WDT.c" "0e4b370aaf9dbc10" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\ports\rx62n\BACnet_Ethernet_RX62N\BACnet_Ethernet_RX62N\src\RPDL\Interrupt_not_RPDL.c" "0e4b370aaf9dbc10" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\ports\rx62n\BACnet_Ethernet_RX62N\BACnet_Ethernet_RX62N\src\bacnet\bacnet.c" "0e4b370aaf9dbc10" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\ports\rx62n\BACnet_Ethernet_RX62N\BACnet_Ethernet_RX62N\src\bacnet\bo.c" "0e4b370aaf9dbc10" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\ports\rx62n\BACnet_Ethernet_RX62N\BACnet_Ethernet_RX62N\src\bacnet\device.c" "0e4b370aaf9dbc10" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\ports\rx62n\BACnet_Ethernet_RX62N\BACnet_Ethernet_RX62N\src\bacnet\ethernet.c" "0e4b370aaf9dbc10" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\ports\rx62n\BACnet_Ethernet_RX62N\BACnet_Ethernet_RX62N\src\bacnet\led.c" "0e4b370aaf9dbc10" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\ports\rx62n\BACnet_Ethernet_RX62N\BACnet_Ethernet_RX62N\src\bacnet\main.c" "0e4b370aaf9dbc10" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\ports\rx62n\BACnet_Ethernet_RX62N\BACnet_Ethernet_RX62N\src\bacnet\timer-hdw.c" "0e4b370aaf9dbc10" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\ports\rx62n\BACnet_Ethernet_RX62N\BACnet_Ethernet_RX62N\src\bacnet\timer.c" "0e4b370aaf9dbc10" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\ports\rx62n\BACnet_Ethernet_RX62N\BACnet_Ethernet_RX62N\src\bsp\YRDKRX62N_RSPI_API.c" "0e4b370aaf9dbc10" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\ports\rx62n\BACnet_Ethernet_RX62N\BACnet_Ethernet_RX62N\src\bsp\dbsct.c" "0e4b370aaf9dbc10" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\ports\rx62n\BACnet_Ethernet_RX62N\BACnet_Ethernet_RX62N\src\bsp\hwsetup.c" "0e4b370aaf9dbc10" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\ports\rx62n\BACnet_Ethernet_RX62N\BACnet_Ethernet_RX62N\src\bsp\lcd.c" "0e4b370aaf9dbc10" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\ports\rx62n\BACnet_Ethernet_RX62N\BACnet_Ethernet_RX62N\src\bsp\resetprg.c" "0e4b370aaf9dbc10" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\ports\rx62n\BACnet_Ethernet_RX62N\BACnet_Ethernet_RX62N\src\bsp\sbrk.c" "0e4b370aaf9dbc10" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\ports\rx62n\BACnet_Ethernet_RX62N\BACnet_Ethernet_RX62N\src\bsp\switch.c" "0e4b370aaf9dbc10" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\ports\rx62n\BACnet_Ethernet_RX62N\BACnet_Ethernet_RX62N\src\driver\phy.c" "0e4b370aaf9dbc10" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\ports\rx62n\BACnet_Ethernet_RX62N\BACnet_Ethernet_RX62N\src\driver\r_ether.c" "0e4b370aaf9dbc10" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\src\abort.c" "0e4b370aaf9dbc10" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\src\apdu.c" "0e4b370aaf9dbc10" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\src\bacapp.c" "0e4b370aaf9dbc10" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\src\bacdcode.c" "0e4b370aaf9dbc10" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\src\bacerror.c" "0e4b370aaf9dbc10" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\src\bacint.c" "0e4b370aaf9dbc10" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\src\bacprop.c" "0e4b370aaf9dbc10" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\src\bacreal.c" "0e4b370aaf9dbc10" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\src\bacstr.c" "0e4b370aaf9dbc10" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\src\datetime.c" "0e4b370aaf9dbc10" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\src\dcc.c" "0e4b370aaf9dbc10" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\src\iam.c" "0e4b370aaf9dbc10" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\src\ihave.c" "0e4b370aaf9dbc10" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\src\memcopy.c" "0e4b370aaf9dbc10" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\src\npdu.c" "0e4b370aaf9dbc10" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\src\rd.c" "0e4b370aaf9dbc10" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\src\reject.c" "0e4b370aaf9dbc10" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\src\rp.c" "0e4b370aaf9dbc10" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\src\rpm.c" "0e4b370aaf9dbc10" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\src\version.c" "0e4b370aaf9dbc10" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\src\whohas.c" "0e4b370aaf9dbc10" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\src\whois.c" "0e4b370aaf9dbc10" 2 -"C:\Documents and Settings\VMWare\My Documents\bacnet-stack\src\wp.c" "0e4b370aaf9dbc10" 2 -[OPTIONS_Debug_Renesas RX C/C++ Library Generator] -"Single Shot" "0bffac16d909bc10" 1 -[OPTIONS_Debug_Renesas RX Configurator] -"Single Shot" "0f2016307f9dbc10" 6 -[OPTIONS_Debug] -"" 0 -"[V|VERSION|1] [B|COMMAND|1] [S|SPEC|UITRON4] [S|OUTPUTPATH|^"$(CONFIGDIR)^"] [S|CPU|RX600] [S|ENDIAN|LITTLE] [S|FINT_REGISTER|0] [S|PATCH|RX610]" 6 -"[V|VERSION|1] [B|DEBUG|1] [S|OUTPUTPATH|^"$(CONFIGDIR)\$(FILELEAF).obj^"] [B|LISTFILE|0] [S|CPU|RX600] [S|ENDIAN|LITTLE] [S|FINT_REGISTER|0] [S|PATCH|RX610]" 4 -"[V|VERSION|1] [S|LANG|CPP] [B|SJIS|1] [S|INCLUDE|^"$(PROJDIR)\src\bacnet^"|^"$(PROJDIR)\..\..\..\..\include^"|^"$(PROJDIR)\src\bsp^"|^"$(PROJDIR)\src\driver^"|^"$(PROJDIR)\src\RPDL^"] [S|DEFINE|BACDL_ETHERNET|MAX_TSM_TRANSACTIONS=0|MAX_CHARACTER_STRING_BYTES=64|MAX_OCTET_STRING_BYTES=64] [S|OUTPUTPATH|^"$(CONFIGDIR)\$(FILELEAF).obj^"] [B|DEBUG|1] [S|OPTIMIZE|0] [B|SIZE|1] [B|MAP|0] [I|INLINE|100] [I|LOOP|2] [S|MISRA2004_CHECK_RULE|ALL] [S|MISRA2004_RULE|1.1|3.4|4.1|5.2|5.3|5.4|5.5|5.6|5.7|6.1|6.2|6.3|6.4|6.5|7.1|8.1|8.2|8.3|8.5|8.6|8.7|8.8|8.11|8.12|9.2|9.3|10.1|10.2|10.3|10.4|10.5|10.6|11.1|11.2|11.3|11.4|11.5|12.1|12.2|12.3|12.4|12.5|12.6|12.7|12.8|12.9|12.10|12.11|12.12|12.13|13.1|13.2|13.3|13.4|13.7|14.1|14.2|14.3|14.4|14.5|14.6|14.7|14.8|14.9|14.10|15.1|15.2|15.3|15.4|15.5|16.1|16.2|16.3|16.4|16.5|16.6|16.8|16.9|17.3|17.4|17.5|17.6|18.1|18.2|18.4|19.1|20.2|20.4|20.5|20.7|20.8|20.9|20.10|20.11|20.12] [S|MISRA1998_CHECK_RULE|ALL] [S|MISRA1998_RULE|1|5|8|12|13|14|17|18|19|20|21|22|24|28|29|31|32|33|34|35|36|37|38|39|40|42|43|44|45|46|48|49|50|51|53|54|55|56|57|58|59|60|61|62|63|64|65|68|69|70|71|72|73|74|75|76|77|78|79|80|82|83|84|85|99|101|102|103|104|105|106|108|110|111|112|113|115|118|119|121|122|123|124|125|126|127] [S|MISRA_GROUP_FILE_PATH|^"$(PROJDIR)\$(PROJECTNAME).rde^"] [S|CPU|RX600] [S|BASE|00000000=NONE] [S|PATCH|RX610] -" 3 -"[V|VERSION|1] [S|LANG|C] [B|SJIS|1] [S|INCLUDE|^"$(PROJDIR)\src\bacnet^"|^"$(PROJDIR)\..\..\..\..\include^"|^"$(PROJDIR)\src\bsp^"|^"$(PROJDIR)\src\driver^"|^"$(PROJDIR)\src\RPDL^"] [S|DEFINE|BACDL_ETHERNET|MAX_TSM_TRANSACTIONS=0] [S|OUTPUTPATH|^"$(CONFIGDIR)\$(FILELEAF).obj^"] [B|DEBUG|1] [S|OPTIMIZE|0] [B|SIZE|1] [B|MAP|0] [I|INLINE|100] [I|LOOP|2] [S|MISRA2004_CHECK_RULE|ALL] [S|MISRA2004_RULE|1.1|3.4|4.1|5.2|5.3|5.4|5.5|5.6|5.7|6.1|6.2|6.3|6.4|6.5|7.1|8.1|8.2|8.3|8.5|8.6|8.7|8.8|8.11|8.12|9.2|9.3|10.1|10.2|10.3|10.4|10.5|10.6|11.1|11.2|11.3|11.4|11.5|12.1|12.2|12.3|12.4|12.5|12.6|12.7|12.8|12.9|12.10|12.11|12.12|12.13|13.1|13.2|13.3|13.4|13.7|14.1|14.2|14.3|14.4|14.5|14.6|14.7|14.8|14.9|14.10|15.1|15.2|15.3|15.4|15.5|16.1|16.2|16.3|16.4|16.5|16.6|16.8|16.9|17.3|17.4|17.5|17.6|18.1|18.2|18.4|19.1|20.2|20.4|20.5|20.7|20.8|20.9|20.10|20.11|20.12] [S|MISRA1998_CHECK_RULE|ALL] [S|MISRA1998_RULE|1|5|8|12|13|14|17|18|19|20|21|22|24|28|29|31|32|33|34|35|36|37|38|39|40|42|43|44|45|46|48|49|50|51|53|54|55|56|57|58|59|60|61|62|63|64|65|68|69|70|71|72|73|74|75|76|77|78|79|80|82|83|84|85|99|101|102|103|104|105|106|108|110|111|112|113|115|118|119|121|122|123|124|125|126|127] [S|MISRA_GROUP_FILE_PATH|^"$(PROJDIR)\$(PROJECTNAME).rde^"] [S|CPU|RX600] [S|BASE|00000000=NONE] [S|PATCH|RX610] -" 2 -"[V|VERSION|1] [S|MODE|BUILD/CHANGED] [S|EXISTOUTPUTPATH|^"$(CONFIGDIR)\$(PROJECTNAME).lib^"] [B|RUNTIME|1] [B|STDIO|1] [B|STDLIB|1] [B|STRING|1] [B|NEW|1] [S|OUTPUTPATH|^"$(CONFIGDIR)\$(PROJECTNAME).lib^"] [B|SIZE|1] [I|INLINE|100] [I|LOOP|2] [S|CPU|RX600] [S|BASE|00000000=NONE] [S|PATCH|RX610] -" 1 -"[V|VERSION|6] [S|INPUTLIBRARY|^"$(PROJDIR)\src\RPDL\RX62N_library.lib^"] [S|PRELINK|SKIP] [S|FORM|STYPE] [S|BYTE_COUNT_VALUE|FF] [B|DEBUG|1] [S|ROM|(D,R)|(D_1,R_1)|(D_2,R_2)] [S|CRC|NONE|DEFAULT|00000000] [S|SHOW|METHODCUSTOM|] [S|OUTPUT|^"$(CONFIGDIR)\$(PROJECTNAME).mot^"] [I|SPACE|^"FF^"] [B|OPTIMIZE|0] [S|START|B_RX_DESC,B_TX_DESC,B_RX_BUFF_1,B_TX_BUFF_1,B_1,R_1,B_2,R_2,B,R,SU,SI(01000)|PResetPRG,C_1,C_2,C,C$*,D*,P,W*(0FFF80000)|C_FLASH_CONFIG_PARAMS_1(0FFFFFF00)|FIXEDVECT(0FFFFFFD0)] -" 5 -[EXCLUDED_FILES_Debug] -[LINKAGE_ORDER_Debug] -[GENERAL_DATA_CONFIGURATION_Debug] -[GENERAL_DATA_CONFIGURATION_SESSION_Debug_DefaultSession] -[SESSION_DATA_CONFIGURATION_SESSION_Debug_DefaultSession] -"MEMORY_MAPPING_OPTIONS" "" -[GENERAL_DATA_CONFIGURATION_SESSION_Debug_JLink] -[SESSION_DATA_CONFIGURATION_SESSION_Debug_JLink] -"MEMORY_MAPPING_OPTIONS" "" -[EXT_DEBUGGER_INFO] -0 "" "" "" "" -[END] diff --git a/ports/rx62n/bacnet.c b/ports/rx62n/bacnet.c index 37963700..cbfad060 100644 --- a/ports/rx62n/bacnet.c +++ b/ports/rx62n/bacnet.c @@ -26,23 +26,23 @@ #include /* hardware layer includes */ #include "hardware.h" -#include "timer.h" +#include "bacnet/basic/sys/mstimer.h" #include "led.h" /* BACnet Stack includes */ -#include "datalink.h" -#include "npdu.h" -#include "handlers.h" -#include "client.h" -#include "txbuf.h" -#include "dcc.h" -#include "iam.h" -#include "device.h" -#include "bo.h" +#include "bacnet/datalink/datalink.h" +#include "bacnet/npdu.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/dcc.h" +#include "bacnet/iam.h" +#include "bacnet/basic/object/device.h" +#include "bacnet/basic/object/bo.h" /* me */ #include "bacnet.h" /* timer for device communications control */ -static struct itimer DCC_Timer; +static struct mstimer DCC_Timer; #define DCC_CYCLE_SECONDS 1 void bacnet_init( @@ -71,7 +71,7 @@ void bacnet_init( apdu_set_confirmed_handler(SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL, handler_device_communication_control); /* start the cyclic 1 second timer for DCC */ - timer_interval_start_seconds(&DCC_Timer, DCC_CYCLE_SECONDS); + mstimer_set(&DCC_Timer, DCC_CYCLE_SECONDS*1000); /* Hello World! */ Send_I_Am(&Handler_Transmit_Buffer[0]); } @@ -108,8 +108,8 @@ void bacnet_task( } } /* handle the communication timer */ - if (timer_interval_expired(&DCC_Timer)) { - timer_interval_reset(&DCC_Timer); + if (mstimer_expired(&DCC_Timer)) { + mstimer_reset(&DCC_Timer); dcc_timer_seconds(DCC_CYCLE_SECONDS); } /* handle the messaging */ diff --git a/ports/rx62n/bo.c b/ports/rx62n/bo.c index 96d60ae0..02b656e5 100644 --- a/ports/rx62n/bo.c +++ b/ports/rx62n/bo.c @@ -28,15 +28,15 @@ #include #include #include -#include "bacdef.h" -#include "bacdcode.h" -#include "bacenum.h" -#include "config.h" /* the custom stuff */ -#include "wp.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacenum.h" +#include "bacnet/config.h" /* the custom stuff */ +#include "bacnet/wp.h" #include "hardware.h" #include "led.h" -#include "bo.h" -#include "handlers.h" +#include "bacnet/basic/object/bo.h" +#include "bacnet/basic/services.h" #ifndef MAX_BINARY_OUTPUTS #define MAX_BINARY_OUTPUTS 2 diff --git a/ports/rx62n/device.c b/ports/rx62n/device.c index 137fb1da..8d20e90a 100644 --- a/ports/rx62n/device.c +++ b/ports/rx62n/device.c @@ -26,26 +26,26 @@ #include #include #include /* for memmove */ -#include "bacdef.h" -#include "bacdcode.h" -#include "bacstr.h" -#include "bacenum.h" -#include "bacapp.h" -#include "config.h" /* the custom stuff */ -#include "apdu.h" -#include "wp.h" /* WriteProperty handling */ -#include "rp.h" /* ReadProperty handling */ -#include "dcc.h" /* DeviceCommunicationControl handling */ -#include "version.h" -#include "device.h" /* me */ -#include "handlers.h" -#include "datalink.h" -#include "address.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacstr.h" +#include "bacnet/bacenum.h" +#include "bacnet/bacapp.h" +#include "bacnet/config.h" /* the custom stuff */ +#include "bacnet/apdu.h" +#include "bacnet/wp.h" /* WriteProperty handling */ +#include "bacnet/rp.h" /* ReadProperty handling */ +#include "bacnet/dcc.h" /* DeviceCommunicationControl handling */ +#include "bacnet/version.h" +#include "bacnet/basic/object/device.h" /* me */ +#include "bacnet/basic/services.h" +#include "bacnet/datalink/datalink.h" +#include "bacnet/basic/binding/address.h" /* os specfic includes */ -#include "timer.h" +#include "bacnet/basic/sys/mstimer.h" /* objects */ -#include "device.h" -#include "bo.h" +#include "bacnet/basic/object/device.h" +#include "bacnet/basic/object/bo.h" /* forward prototype */ int Device_Read_Property_Local( @@ -88,6 +88,7 @@ static const char *Reinit_Password = "filister"; static char My_Object_Name[MAX_DEV_NAME_LEN + 1] = "SimpleServer"; static char Model_Name[MAX_DEV_MOD_LEN + 1] = "RX62N"; static char Application_Software_Version[MAX_DEV_VER_LEN + 1] = "1.0"; +static const char *BACnet_Version = BACNET_VERSION_TEXT; static char Location[MAX_DEV_LOC_LEN + 1] = "USA"; static char Description[MAX_DEV_DESC_LEN + 1] = "Renesas Rulz!"; static uint32_t Database_Revision = 0; diff --git a/ports/rx62n/ethernet.c b/ports/rx62n/ethernet.c index 082cd6c9..8ec6f5ac 100644 --- a/ports/rx62n/ethernet.c +++ b/ports/rx62n/ethernet.c @@ -24,9 +24,9 @@ *********************************************************************/ #include /* for standard integer types uint8_t etc. */ #include /* for the standard bool type. */ -#include "bacdef.h" -#include "ethernet.h" -#include "bacint.h" +#include "bacnet/bacdef.h" +#include "bacnet/datalink/ethernet.h" +#include "bacnet/bacint.h" #include "hardware.h" /** @file rx62n/ethernet.c Provides Renesas RX62N-specific functions diff --git a/ports/rx62n/led.c b/ports/rx62n/led.c index 9b7e9539..36804d02 100644 --- a/ports/rx62n/led.c +++ b/ports/rx62n/led.c @@ -23,10 +23,10 @@ *********************************************************************/ #include #include "hardware.h" -#include "timer.h" +#include "bacnet/basic/sys/mstimer.h" #include "led.h" -static struct itimer Off_Delay_Timer[MAX_LEDS]; +static struct mstimer Off_Delay_Timer[MAX_LEDS]; static bool LED_Status[MAX_LEDS]; #define LED_OFF (0) @@ -82,7 +82,7 @@ void led_on( } if (index < MAX_LEDS) { LED_Status[index] = LED_ON; - timer_interval_no_expire(&Off_Delay_Timer[index]); + mstimer_set(&Off_Delay_Timer[index], 0); } } @@ -136,7 +136,7 @@ void led_off( } if (index < MAX_LEDS) { LED_Status[index] = LED_OFF; - timer_interval_no_expire(&Off_Delay_Timer[index]); + mstimer_set(&Off_Delay_Timer[index], 0); } } @@ -182,7 +182,7 @@ void led_off_delay( uint32_t delay_ms) { if (index < MAX_LEDS) { - timer_interval_start(&Off_Delay_Timer[index], delay_ms); + mstimer_set(&Off_Delay_Timer[index], delay_ms); } } @@ -197,7 +197,7 @@ void led_on_interval( { if (index < MAX_LEDS) { led_on(index); - timer_interval_start(&Off_Delay_Timer[index], interval_ms); + mstimer_set(&Off_Delay_Timer[index], interval_ms); } } @@ -212,9 +212,11 @@ void led_task( uint8_t i; /* loop counter */ for (i = 0; i < MAX_LEDS; i++) { - if (timer_interval_expired(&Off_Delay_Timer[i])) { - timer_interval_no_expire(&Off_Delay_Timer[i]); - led_off(i); + if (mstimer_interval(&Off_Delay_Timer[i]) > 0) { + if (mstimer_expired(&Off_Delay_Timer[i])) { + mstimer_set(&Off_Delay_Timer[i], 0); + led_off(i); + } } } } diff --git a/ports/rx62n/main.c b/ports/rx62n/main.c index 46288df5..8d3ba751 100644 --- a/ports/rx62n/main.c +++ b/ports/rx62n/main.c @@ -25,8 +25,8 @@ #include #include #include "hardware.h" -#include "ethernet.h" -#include "timer.h" +#include "bacnet/datalink/ethernet.h" +#include "bacnet/basic/sys/mstimer.h" #include "led.h" /** Main function of BACnet demo for RX62N evaluation board */ diff --git a/ports/rx62n/timer-hdw.c b/ports/rx62n/mstimer-init.c similarity index 84% rename from ports/rx62n/timer-hdw.c rename to ports/rx62n/mstimer-init.c index 37513125..44a7d780 100644 --- a/ports/rx62n/timer-hdw.c +++ b/ports/rx62n/mstimer-init.c @@ -24,11 +24,10 @@ #include #include #include "hardware.h" -#include "timer.h" +#include "bacnet/basic/sys/mstimer.h" /* counter for the the timer which wraps every 49.7 days */ static volatile uint32_t Millisecond_Counter; -static volatile uint8_t Millisecond_Counter_Byte; /* forward prototype for interrupt service routine */ void int_cmt0_isr( void); @@ -42,7 +41,6 @@ static void timer_interrupt_handler( void) { Millisecond_Counter++; - Millisecond_Counter_Byte++; } /************************************************************************* @@ -61,27 +59,16 @@ void int_cmt0_isr( * Returns: none * Notes: This method only disables the timer overflow interrupt. *************************************************************************/ -uint32_t timer_milliseconds( +unsigned long mstimer_now( void) { - uint32_t timer_value; /* return value */ + unsigned long timer_value; /* return value */ timer_value = Millisecond_Counter; return timer_value; } -/************************************************************************* -* Description: returns the current millisecond count -* Returns: none -* Notes: This method only disables the timer overflow interrupt. -*************************************************************************/ -uint8_t timer_milliseconds_byte( - void) -{ - return Millisecond_Counter; -} - /************************************************************************* * Description: Initialization for Timer * Returns: none diff --git a/ports/rx62n/readme.txt b/ports/rx62n/readme.txt index 28af2fed..97c424f8 100644 --- a/ports/rx62n/readme.txt +++ b/ports/rx62n/readme.txt @@ -1,8 +1,9 @@ BACnet Etherent Demonstrates the Ethernet peripheral by implmenting BACnet over Ethernet -on the RX62N Development Kit. The project is compiled with the RX Standard +on the RX62N Development Kit. The project is compiled with the RX Standard Toolchain, and the default drivers included with the RX62N kit.   The project does not use any additional hardware.   -The project was tested using a BACnet/IP to BACnet Ethernet router, using the bacnet-tools from the BACnet Protocol Stack site. +The project was tested using a BACnet/IP to BACnet Ethernet router, +using the bacnet-tools from the BACnet Protocol Stack site. diff --git a/ports/rx62n/timer.c b/ports/rx62n/timer.c deleted file mode 100644 index 679529e0..00000000 --- a/ports/rx62n/timer.c +++ /dev/null @@ -1,431 +0,0 @@ -/************************************************************************** -* -* Copyright (C) 2009 Steve Karg -* -* Permission is hereby granted, free of charge, to any person obtaining -* a copy of this software and associated documentation files (the -* "Software"), to deal in the Software without restriction, including -* without limitation the rights to use, copy, modify, merge, publish, -* distribute, sublicense, and/or sell copies of the Software, and to -* permit persons to whom the Software is furnished to do so, subject to -* the following conditions: -* -* The above copyright notice and this permission notice shall be included -* in all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*********************************************************************/ -#include -#include -#include "timer.h" - -/* generic elapsed timer handling */ -/* interval not to exceed 49.7 days */ -/* interval of 1ms may be 0 to 1ms */ - -/************************************************************************* -* Description: Sets the start time for an elapsed timer -* Returns: the value of the start timer -* Notes: none -*************************************************************************/ -void timer_elapsed_start( - struct etimer *t) -{ - uint32_t now = timer_milliseconds(); - - if (t) { - t->start = now; - } -} - -/************************************************************************* -* Description: Gets the amount of elapsed time in milliseconds -* Returns: elapsed time in milliseconds -* Notes: none -*************************************************************************/ -uint32_t timer_elapsed_time( - struct etimer *t) -{ - uint32_t now = timer_milliseconds(); - uint32_t delta = 0; - - if (t) { - delta = now - t->start; - } - - return delta; -} - -/************************************************************************* -* Description: Sets the start time with an offset -* Returns: elapsed time in milliseconds -* Notes: none -*************************************************************************/ -void timer_elapsed_start_offset( - struct etimer *t, - uint32_t offset) -{ - uint32_t now = timer_milliseconds(); - - if (t) { - t->start = now + offset; - } -} - -/************************************************************************* -* Description: Tests to see if time has elapsed -* Returns: true if time has elapsed -* Notes: none -*************************************************************************/ -bool timer_elapsed_milliseconds( - struct etimer *t, - uint32_t milliseconds) -{ - return (timer_elapsed_time(t) >= milliseconds); -} - -/************************************************************************* -* Description: Tests to see if time has elapsed -* Returns: true if time has elapsed -* Notes: none -*************************************************************************/ -bool timer_elapsed_seconds( - struct etimer * t, - uint32_t seconds) -{ - uint32_t milliseconds = seconds; - - milliseconds *= 1000L; - - return timer_elapsed_milliseconds(t, milliseconds); -} - -/************************************************************************* -* Description: Tests to see if time has elapsed -* Returns: true if time has elapsed -* Notes: none -*************************************************************************/ -bool timer_elapsed_minutes( - struct etimer * t, - uint32_t minutes) -{ - uint32_t milliseconds = minutes; - - milliseconds *= 1000L; - milliseconds *= 60L; - - return timer_elapsed_milliseconds(t, milliseconds); -} - -/************************************************************************* -* Description: Tests to see if time has elapsed -* Returns: true if time has elapsed -* Notes: none -*************************************************************************/ -bool timer_elapsed_milliseconds_short( - struct etimer * t, - uint16_t value) -{ - uint32_t milliseconds; - - milliseconds = value; - - return (timer_elapsed_time(t) >= milliseconds); -} - -/************************************************************************* -* Description: Tests to see if time has elapsed -* Returns: true if time has elapsed -* Notes: none -*************************************************************************/ -bool timer_elapsed_seconds_short( - struct etimer * t, - uint16_t value) -{ - return timer_elapsed_seconds(t, value); -} - -/************************************************************************* -* Description: Tests to see if time has elapsed -* Returns: true if time has elapsed -* Notes: none -*************************************************************************/ -bool timer_elapsed_minutes_short( - struct etimer * t, - uint16_t value) -{ - return timer_elapsed_minutes(t, value); -} - -/************************************************************************* -* Description: Starts an interval timer -* Returns: nothing -* Notes: none -*************************************************************************/ -void timer_interval_start( - struct itimer *t, - uint32_t interval) -{ - if (t) { - t->start = timer_milliseconds(); - t->interval = interval; - } -} - -/************************************************************************* -* Description: Starts an interval timer -* Returns: nothing -* Notes: none -*************************************************************************/ -void timer_interval_start_seconds( - struct itimer *t, - uint32_t seconds) -{ - uint32_t interval = seconds; - - interval *= 1000L; - timer_interval_start(t, interval); -} - -/************************************************************************* -* Description: Starts an interval timer -* Returns: nothing -* Notes: none -*************************************************************************/ -void timer_interval_start_minutes( - struct itimer *t, - uint32_t minutes) -{ - uint32_t interval = minutes; - - interval *= 1000L; - interval *= 60L; - timer_interval_start(t, interval); -} - -/************************************************************************* -* Description: Determines the amount of time that has elapsed -* Returns: elapsed milliseconds -* Notes: none -*************************************************************************/ -uint32_t timer_interval_elapsed( - struct itimer *t) -{ - uint32_t now = timer_milliseconds(); - uint32_t delta = 0; - - if (t) { - delta = now - t->start; - } - - return delta; -} - -/************************************************************************* -* Description: Determines the amount of time that has elapsed -* Returns: elapsed milliseconds -* Notes: none -*************************************************************************/ -uint32_t timer_interval( - struct itimer * t) -{ - uint32_t interval = 0; - - if (t) { - interval = t->interval; - } - - return interval; -} - -/************************************************************************* -* Description: Tests to see if time has elapsed -* Returns: true if time has elapsed -* Notes: none -*************************************************************************/ -bool timer_interval_expired( - struct itimer * t) -{ - bool expired = false; - - if (t) { - if (t->interval) { - expired = timer_interval_elapsed(t) >= t->interval; - } - } - - return expired; -} - -/************************************************************************* -* Description: Sets the interval value to zero so it never expires -* Returns: nothing -* Notes: none -*************************************************************************/ -void timer_interval_no_expire( - struct itimer *t) -{ - if (t) { - t->interval = 0; - } -} - -/************************************************************************* -* Description: Adds another interval to the start time. Used for cyclic -* timers that won't lose ticks. -* Returns: nothing -* Notes: none -*************************************************************************/ -void timer_interval_reset( - struct itimer *t) -{ - if (t) { - t->start += t->interval; - } -} - -/************************************************************************* -* Description: Restarts the timer with the same interval -* Returns: nothing -* Notes: none -*************************************************************************/ -void timer_interval_restart( - struct itimer *t) -{ - if (t) { - t->start = timer_milliseconds(); - } -} - -/************************************************************************* -* Description: Return the elapsed time -* Returns: number of milliseconds elapsed -* Notes: only up to 255ms elapsed -**************************************************************************/ -uint8_t timer_milliseconds_delta( - uint8_t start) -{ - return (timer_milliseconds_byte() - start); -} - -/************************************************************************* -* Description: Mark the start of a delta timer -* Returns: mark timer starting tick -* Notes: only up to 255ms elapsed -**************************************************************************/ -uint8_t timer_milliseconds_mark( - void) -{ - return timer_milliseconds_byte(); -} - -#ifdef TEST -#include -#include - -#include "ctest.h" - -static uint32_t Milliseconds; - -uint32_t timer_milliseconds( - void) -{ - return Milliseconds; -} - -uint32_t timer_milliseconds_set( - uint32_t value) -{ - uint32_t old_value = Milliseconds; - - Milliseconds = value; - - return old_value; -} - -void testElapsedTimer( - Test * pTest) -{ - struct etimer t; - uint32_t test_time = 0; - - timer_milliseconds_set(test_time); - timer_elapsed_start(&t); - ct_test(pTest, timer_elapsed_time(&t) == test_time); - test_time = 0xffff; - timer_milliseconds_set(test_time); - ct_test(pTest, timer_elapsed_time(&t) == test_time); - test_time = 0xffffffff; - timer_milliseconds_set(test_time); - ct_test(pTest, timer_elapsed_time(&t) == test_time); -} - -void testIntervalTimer( - Test * pTest) -{ - struct itimer t; - uint32_t interval = 0; - uint32_t test_time = 0; - - timer_milliseconds_set(test_time); - timer_interval_start(&t, interval); - test_time = 0xffff; - timer_milliseconds_set(test_time); - ct_test(pTest, timer_interval(&t) == interval); - ct_test(pTest, timer_interval_elapsed(&t) == test_time); - test_time = 0xffffffff; - timer_milliseconds_set(test_time); - ct_test(pTest, timer_interval(&t) == interval); - ct_test(pTest, timer_interval_elapsed(&t) == test_time); - test_time = 0; - timer_milliseconds_set(test_time); - interval = 0xffff; - timer_interval_start(&t, interval); - ct_test(pTest, timer_interval(&t) == interval); - interval = 0xffffffff; - timer_interval_start(&t, interval); - ct_test(pTest, timer_interval(&t) == interval); - - interval = 0; - timer_interval_start_seconds(&t, interval); - ct_test(pTest, timer_interval(&t) == interval); - interval = 60L; - timer_interval_start_seconds(&t, interval); - interval *= 1000L; - ct_test(pTest, timer_interval(&t) == interval); - -} - - -#ifdef TEST_TIMER -int main( - void) -{ - Test *pTest; - bool rc; - - pTest = ct_create("Timer", NULL); - - /* individual tests */ - rc = ct_addTestFunction(pTest, testElapsedTimer); - assert(rc); - rc = ct_addTestFunction(pTest, testIntervalTimer); - assert(rc); - - - ct_setStream(pTest, stdout); - ct_run(pTest); - (void) ct_report(pTest); - - ct_destroy(pTest); - - return 0; -} -#endif -#endif diff --git a/ports/rx62n/timer.h b/ports/rx62n/timer.h deleted file mode 100644 index dac54d47..00000000 --- a/ports/rx62n/timer.h +++ /dev/null @@ -1,115 +0,0 @@ -/************************************************************************** -* -* Copyright (C) 2009 Steve Karg -* -* Permission is hereby granted, free of charge, to any person obtaining -* a copy of this software and associated documentation files (the -* "Software"), to deal in the Software without restriction, including -* without limitation the rights to use, copy, modify, merge, publish, -* distribute, sublicense, and/or sell copies of the Software, and to -* permit persons to whom the Software is furnished to do so, subject to -* the following conditions: -* -* The above copyright notice and this permission notice shall be included -* in all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*********************************************************************/ -#ifndef TIMER_H -#define TIMER_H - -#include -#include - -/* Timer Module */ - -/* elapsed timer structure */ -struct etimer { - uint32_t start; -}; -/* interval timer structure */ -struct itimer { - uint32_t start; - uint32_t interval; -}; - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - - /* these 3 functions are created in the hardware specific module */ - void timer_init( - void); - uint32_t timer_milliseconds( - void); - uint8_t timer_milliseconds_byte( - void); - - /* these functions are in the generic timer.c module */ - - /* elapsed timer */ - void timer_elapsed_start( - struct etimer *t); - void timer_elapsed_start_offset( - struct etimer *t, - uint32_t offset); - uint32_t timer_elapsed_time( - struct etimer *t); - bool timer_elapsed_milliseconds( - struct etimer *t, - uint32_t value); - bool timer_elapsed_seconds( - struct etimer *t, - uint32_t value); - bool timer_elapsed_minutes( - struct etimer *t, - uint32_t value); - bool timer_elapsed_milliseconds_short( - struct etimer *t, - uint16_t value); - bool timer_elapsed_seconds_short( - struct etimer *t, - uint16_t value); - bool timer_elapsed_minutes_short( - struct etimer *t, - uint16_t value); - - /* interval timer */ - void timer_interval_start( - struct itimer *t, - uint32_t interval); - void timer_interval_start_seconds( - struct itimer *t, - uint32_t interval); - void timer_interval_start_minutes( - struct itimer *t, - uint32_t interval); - bool timer_interval_expired( - struct itimer *t); - uint32_t timer_interval( - struct itimer *t); - uint32_t timer_interval_elapsed( - struct itimer *t); - void timer_interval_no_expire( - struct itimer *t); - void timer_interval_reset( - struct itimer *t); - void timer_interval_restart( - struct itimer *t); - - /* special for 8-bit microcontrollers - limited to 255ms */ - uint8_t timer_milliseconds_delta( - uint8_t start); - uint8_t timer_milliseconds_mark( - void); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ -#endif diff --git a/ports/stm32f10x/CMSIS/CMSIS debug support.htm b/ports/stm32f10x/CMSIS/CMSIS debug support.htm index efda685b..36e0446c 100644 --- a/ports/stm32f10x/CMSIS/CMSIS debug support.htm +++ b/ports/stm32f10x/CMSIS/CMSIS debug support.htm @@ -1,243 +1,243 @@ - - - -CMSIS Debug Support - - - - - - - - -

CMSIS Debug Support

- -
- -

Cortex-M3 ITM Debug Access

-

- The Cortex-M3 incorporates the Instrumented Trace Macrocell (ITM) that provides together with - the Serial Viewer Output trace capabilities for the microcontroller system. The ITM has - 32 communication channels which are able to transmit 32 / 16 / 8 bit values; two ITM - communication channels are used by CMSIS to output the following information: -

-
    -
  • ITM Channel 0: used for printf-style output via the debug interface.
  • -
  • ITM Channel 31: is reserved for RTOS kernel awareness debugging.
  • -
- -

Debug IN / OUT functions

-

CMSIS provides following debug functions:

-
    -
  • ITM_SendChar (uses ITM channel 0)
  • -
  • ITM_ReceiveChar (uses global variable)
  • -
  • ITM_CheckChar (uses global variable)
  • -
- -

ITM_SendChar

-

- ITM_SendChar is used to transmit a character over ITM channel 0 from - the microcontroller system to the debug system.
- Only a 8 bit value is transmitted. -

-
-static __INLINE uint32_t ITM_SendChar (uint32_t ch)
-{
-  /* check if debugger connected and ITM channel enabled for tracing */
-  if ((CoreDebug->DEMCR & CoreDebug_DEMCR_TRCENA)  &&
-      (ITM->TCR & ITM_TCR_ITMENA)                  &&
-      (ITM->TER & (1UL << 0))  ) 
-  {
-    while (ITM->PORT[0].u32 == 0);
-    ITM->PORT[0].u8 = (uint8_t)ch;
-  }  
-  return (ch);
-}
- -

ITM_ReceiveChar

-

- ITM communication channel is only capable for OUT direction. For IN direction - a globel variable is used. A simple mechansim detects if a character is received. - The project to test need to be build with debug information. -

- -

- The globale variable ITM_RxBuffer is used to transmit a 8 bit value from debug system - to microcontroller system. ITM_RxBuffer is 32 bit wide to enshure a proper handshake. -

-
-extern volatile int ITM_RxBuffer;                    /* variable to receive characters                             */
-
-

- A dedicated bit pattern is used to determin if ITM_RxBuffer is empty - or contains a valid value. -

-
-#define             ITM_RXBUFFER_EMPTY    0x5AA55AA5 /* value identifying ITM_RxBuffer is ready for next character */
-
-

- ITM_ReceiveChar is used to receive a 8 bit value from the debug system. The function is nonblocking. - It returns the received character or '-1' if no character was available. -

-
-static __INLINE int ITM_ReceiveChar (void) {
-  int ch = -1;                               /* no character available */
-
-  if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) {
-    ch = ITM_RxBuffer;
-    ITM_RxBuffer = ITM_RXBUFFER_EMPTY;       /* ready for next character */
-  }
-  
-  return (ch); 
-}
-
- -

ITM_CheckChar

-

- ITM_CheckChar is used to check if a character is received. -

-
-static __INLINE int ITM_CheckChar (void) {
-
-  if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) {
-    return (0);                                 /* no character available */
-  } else {
-    return (1);                                 /*    character available */
-  }
-}
- - -

ITM Debug Support in uVision

-

- uVision uses in a debug session the Debug (printf) Viewer window to - display the debug data. -

-

Direction microcontroller system -> uVision:

-
    -
  • - Characters received via ITM communication channel 0 are written in a printf style - to Debug (printf) Viewer window. -
  • -
- -

Direction uVision -> microcontroller system:

-
    -
  • Check if ITM_RxBuffer variable is available (only performed once).
  • -
  • Read character from Debug (printf) Viewer window.
  • -
  • If ITM_RxBuffer empty write character to ITM_RxBuffer.
  • -
- -

Note

-
    -
  • Current solution does not use a buffer machanism for trasmitting the characters.

    -
  • -
- -

RTX Kernel awareness in uVision

-

- uVision / RTX are using a simple and efficient solution for RTX Kernel awareness. - No format overhead is necessary.
- uVsion debugger decodes the RTX events via the 32 / 16 / 8 bit ITM write access - to ITM communication channel 31. -

- -

Following RTX events are traced:

-
    -
  • Task Create / Delete event -
      -
    1. 32 bit access. Task start address is transmitted
    2. -
    3. 16 bit access. Task ID and Create/Delete flag are transmitted
      - High byte holds Create/Delete flag, Low byte holds TASK ID. -
    4. -
    -
  • -
  • Task switch event -
      -
    1. 8 bit access. Task ID of current task is transmitted
    2. -
    -
  • -
- -

Note

-
    -
  • Other RTOS information could be retrieved via memory read access in a polling mode manner.

    -
  • -
- - -

 

- -
- -

Copyright © KEIL - An ARM Company.
-All rights reserved.
-Visit our web site at
www.keil.com. -

- - - + + + +CMSIS Debug Support + + + + + + + + +

CMSIS Debug Support

+ +
+ +

Cortex-M3 ITM Debug Access

+

+ The Cortex-M3 incorporates the Instrumented Trace Macrocell (ITM) that provides together with + the Serial Viewer Output trace capabilities for the microcontroller system. The ITM has + 32 communication channels which are able to transmit 32 / 16 / 8 bit values; two ITM + communication channels are used by CMSIS to output the following information: +

+
    +
  • ITM Channel 0: used for printf-style output via the debug interface.
  • +
  • ITM Channel 31: is reserved for RTOS kernel awareness debugging.
  • +
+ +

Debug IN / OUT functions

+

CMSIS provides following debug functions:

+
    +
  • ITM_SendChar (uses ITM channel 0)
  • +
  • ITM_ReceiveChar (uses global variable)
  • +
  • ITM_CheckChar (uses global variable)
  • +
+ +

ITM_SendChar

+

+ ITM_SendChar is used to transmit a character over ITM channel 0 from + the microcontroller system to the debug system.
+ Only a 8 bit value is transmitted. +

+
+static __INLINE uint32_t ITM_SendChar (uint32_t ch)
+{
+  /* check if debugger connected and ITM channel enabled for tracing */
+  if ((CoreDebug->DEMCR & CoreDebug_DEMCR_TRCENA)  &&
+      (ITM->TCR & ITM_TCR_ITMENA)                  &&
+      (ITM->TER & (1UL << 0))  ) 
+  {
+    while (ITM->PORT[0].u32 == 0);
+    ITM->PORT[0].u8 = (uint8_t)ch;
+  }  
+  return (ch);
+}
+ +

ITM_ReceiveChar

+

+ ITM communication channel is only capable for OUT direction. For IN direction + a globel variable is used. A simple mechansim detects if a character is received. + The project to test need to be build with debug information. +

+ +

+ The globale variable ITM_RxBuffer is used to transmit a 8 bit value from debug system + to microcontroller system. ITM_RxBuffer is 32 bit wide to enshure a proper handshake. +

+
+extern volatile int ITM_RxBuffer;                    /* variable to receive characters                             */
+
+

+ A dedicated bit pattern is used to determin if ITM_RxBuffer is empty + or contains a valid value. +

+
+#define             ITM_RXBUFFER_EMPTY    0x5AA55AA5 /* value identifying ITM_RxBuffer is ready for next character */
+
+

+ ITM_ReceiveChar is used to receive a 8 bit value from the debug system. The function is nonblocking. + It returns the received character or '-1' if no character was available. +

+
+static __INLINE int ITM_ReceiveChar (void) {
+  int ch = -1;                               /* no character available */
+
+  if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) {
+    ch = ITM_RxBuffer;
+    ITM_RxBuffer = ITM_RXBUFFER_EMPTY;       /* ready for next character */
+  }
+  
+  return (ch); 
+}
+
+ +

ITM_CheckChar

+

+ ITM_CheckChar is used to check if a character is received. +

+
+static __INLINE int ITM_CheckChar (void) {
+
+  if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) {
+    return (0);                                 /* no character available */
+  } else {
+    return (1);                                 /*    character available */
+  }
+}
+ + +

ITM Debug Support in uVision

+

+ uVision uses in a debug session the Debug (printf) Viewer window to + display the debug data. +

+

Direction microcontroller system -> uVision:

+
    +
  • + Characters received via ITM communication channel 0 are written in a printf style + to Debug (printf) Viewer window. +
  • +
+ +

Direction uVision -> microcontroller system:

+
    +
  • Check if ITM_RxBuffer variable is available (only performed once).
  • +
  • Read character from Debug (printf) Viewer window.
  • +
  • If ITM_RxBuffer empty write character to ITM_RxBuffer.
  • +
+ +

Note

+
    +
  • Current solution does not use a buffer machanism for trasmitting the characters.

    +
  • +
+ +

RTX Kernel awareness in uVision

+

+ uVision / RTX are using a simple and efficient solution for RTX Kernel awareness. + No format overhead is necessary.
+ uVsion debugger decodes the RTX events via the 32 / 16 / 8 bit ITM write access + to ITM communication channel 31. +

+ +

Following RTX events are traced:

+
    +
  • Task Create / Delete event +
      +
    1. 32 bit access. Task start address is transmitted
    2. +
    3. 16 bit access. Task ID and Create/Delete flag are transmitted
      + High byte holds Create/Delete flag, Low byte holds TASK ID. +
    4. +
    +
  • +
  • Task switch event +
      +
    1. 8 bit access. Task ID of current task is transmitted
    2. +
    +
  • +
+ +

Note

+
    +
  • Other RTOS information could be retrieved via memory read access in a polling mode manner.

    +
  • +
+ + +

 

+ +
+ +

Copyright © KEIL - An ARM Company.
+All rights reserved.
+Visit our web site at www.keil.com. +

+ + + \ No newline at end of file diff --git a/ports/stm32f10x/Makefile b/ports/stm32f10x/Makefile index d488f107..d547d4d8 100644 --- a/ports/stm32f10x/Makefile +++ b/ports/stm32f10x/Makefile @@ -5,10 +5,8 @@ TARGET=bacnet BACNET_DIR = ../.. BACNET_CORE = $(BACNET_DIR)/src -BACNET_DEMO = $(BACNET_DIR)/demo -BACNET_INCLUDE = $(BACNET_DIR)/include -BACNET_OBJECT = $(BACNET_DIR)/demo/object -BACNET_HANDLER = $(BACNET_DIR)/demo/handler +BACNET_BASIC = $(BACNET_DIR)/basic +BACNET_INCLUDE = $(BACNET_CORE) PLATFORM_DIR = . LIBRARY_STM32 = ./drivers/src LIBRARY_STM32_INCLUDES = ./drivers/inc @@ -18,8 +16,6 @@ INCLUDES = -I$(PLATFORM_DIR) INCLUDES += -I$(LIBRARY_STM32_INCLUDES) INCLUDES += -I$(LIBRARY_CMSIS) INCLUDES += -I$(BACNET_INCLUDE) -INCLUDES += -I$(BACNET_OBJECT) -INCLUDES += -I$(BACNET_HANDLER) PLATFORM_SRC = \ $(PLATFORM_DIR)/main.c \ @@ -32,26 +28,27 @@ PLATFORM_SRC = \ $(PLATFORM_DIR)/rs485.c \ $(PLATFORM_DIR)/stm32f10x_it.c \ $(PLATFORM_DIR)/system_stm32f10x.c \ - $(PLATFORM_DIR)/timer.c \ - $(PLATFORM_DIR)/timer_sys.c + $(PLATFORM_DIR)/timer-init.c -DEMO_SRC = \ - $(BACNET_DEMO)/handler/h_dcc.c \ - $(BACNET_DEMO)/handler/h_npdu.c \ - $(BACNET_DEMO)/handler/h_rd.c \ - $(BACNET_DEMO)/handler/h_rp.c \ - $(BACNET_DEMO)/handler/h_rpm.c \ - $(BACNET_DEMO)/handler/h_whohas.c \ - $(BACNET_DEMO)/handler/h_whois.c \ - $(BACNET_DEMO)/handler/h_wp.c \ - $(BACNET_DEMO)/handler/noserv.c \ - $(BACNET_DEMO)/handler/s_iam.c \ - $(BACNET_DEMO)/handler/s_ihave.c \ - $(BACNET_DEMO)/handler/txbuf.c +BASIC_SRC = \ + $(BACNET_BASIC)/service/h_dcc.c \ + $(BACNET_BASIC)/service/h_apdu.c \ + $(BACNET_BASIC)/service/h_npdu.c \ + $(BACNET_BASIC)/service/h_rd.c \ + $(BACNET_BASIC)/service/h_rp.c \ + $(BACNET_BASIC)/service/h_rpm.c \ + $(BACNET_BASIC)/service/h_whohas.c \ + $(BACNET_BASIC)/service/h_whois.c \ + $(BACNET_BASIC)/service/h_wp.c \ + $(BACNET_BASIC)/service/h_noserv.c \ + $(BACNET_BASIC)/service/s_iam.c \ + $(BACNET_BASIC)/service/s_ihave.c \ + $(BACNET_BASIC)/tsm/tsm.c \ + $(BACNET_BASIC)/sys/ringbuf.c \ + $(BACNET_BASIC)/sys/fifo.c BACNET_SRC = \ $(BACNET_CORE)/abort.c \ - $(BACNET_CORE)/apdu.c \ $(BACNET_CORE)/bacaddr.c \ $(BACNET_CORE)/bacapp.c \ $(BACNET_CORE)/bacdcode.c \ @@ -59,9 +56,8 @@ BACNET_SRC = \ $(BACNET_CORE)/bacint.c \ $(BACNET_CORE)/bacreal.c \ $(BACNET_CORE)/bacstr.c \ - $(BACNET_CORE)/crc.c \ + $(BACNET_BASIC)/datalink/crc.c \ $(BACNET_CORE)/dcc.c \ - $(BACNET_CORE)/fifo.c \ $(BACNET_CORE)/iam.c \ $(BACNET_CORE)/ihave.c \ $(BACNET_CORE)/lighting.c \ @@ -70,7 +66,6 @@ BACNET_SRC = \ $(BACNET_CORE)/proplist.c \ $(BACNET_CORE)/rd.c \ $(BACNET_CORE)/reject.c \ - $(BACNET_CORE)/ringbuf.c \ $(BACNET_CORE)/rp.c \ $(BACNET_CORE)/rpm.c \ $(BACNET_CORE)/whohas.c \ @@ -104,7 +99,7 @@ STM32_SRC = \ $(LIBRARY_STM32)/syscalls.c CSRC = $(PLATFORM_SRC) -CSRC += $(DEMO_SRC) +CSRC += $(BASIC_SRC) CSRC += $(BACNET_SRC) CSRC += $(STM32_SRC) diff --git a/ports/stm32f10x/automac.c b/ports/stm32f10x/automac.c index adb28ac7..a6cb4fe8 100644 --- a/ports/stm32f10x/automac.c +++ b/ports/stm32f10x/automac.c @@ -25,11 +25,11 @@ #include #include #include -#include "bacdef.h" -#include "bacdcode.h" -#include "bacenum.h" -#include "config.h" -#include "mstpdef.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacenum.h" +#include "bacnet/config.h" +#include "bacnet/datalink/mstpdef.h" #include "automac.h" /* MS/TP Auto MAC address functionality */ diff --git a/ports/stm32f10x/bacnet.c b/ports/stm32f10x/bacnet.c index 0c922bba..11a92941 100644 --- a/ports/stm32f10x/bacnet.c +++ b/ports/stm32f10x/bacnet.c @@ -26,24 +26,24 @@ #include /* hardware layer includes */ #include "hardware.h" -#include "timer.h" +#include "bacnet/basic/sys/mstimer.h" #include "rs485.h" /* BACnet Stack includes */ -#include "datalink.h" -#include "npdu.h" -#include "handlers.h" -#include "client.h" -#include "txbuf.h" -#include "dcc.h" -#include "iam.h" +#include "bacnet/datalink/datalink.h" +#include "bacnet/npdu.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/dcc.h" +#include "bacnet/iam.h" /* BACnet objects */ -#include "device.h" -#include "bo.h" +#include "bacnet/basic/object/device.h" +#include "bacnet/basic/object/bo.h" /* me */ #include "bacnet.h" /* timer for device communications control */ -static struct itimer DCC_Timer; +static struct mstimer DCC_Timer; #define DCC_CYCLE_SECONDS 1 void bacnet_init( @@ -76,7 +76,7 @@ void bacnet_init( apdu_set_confirmed_handler(SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL, handler_device_communication_control); /* start the cyclic 1 second timer for DCC */ - timer_interval_start_seconds(&DCC_Timer, DCC_CYCLE_SECONDS); + mstimer_set(&DCC_Timer, DCC_CYCLE_SECONDS*1000); /* Hello World! */ Send_I_Am(&Handler_Transmit_Buffer[0]); } @@ -121,8 +121,8 @@ void bacnet_task( } } /* handle the communication timer */ - if (timer_interval_expired(&DCC_Timer)) { - timer_interval_reset(&DCC_Timer); + if (mstimer_expired(&DCC_Timer)) { + mstimer_reset(&DCC_Timer); dcc_timer_seconds(DCC_CYCLE_SECONDS); } /* handle the messaging */ diff --git a/ports/stm32f10x/bacnet.ewp b/ports/stm32f10x/bacnet.ewp index e3378ce4..d2c3ff5e 100644 --- a/ports/stm32f10x/bacnet.ewp +++ b/ports/stm32f10x/bacnet.ewp @@ -11,7 +11,7 @@ General 3 - 29 + 31 1 1 + + ICCARM 2 - 34 + 35 1 1 @@ -470,6 +478,10 @@ IccRTTI2 0 + @@ -690,7 +702,7 @@ ILINK 0 - 20 + 22 1 1 + + @@ -1034,118 +1054,121 @@ BACnet - $PROJ_DIR$\..\..\src\abort.c + $PROJ_DIR$\..\..\src\bacnet\abort.c - $PROJ_DIR$\..\..\src\apdu.c + $PROJ_DIR$\..\..\src\bacnet\bacaddr.c - $PROJ_DIR$\..\..\src\bacaddr.c + $PROJ_DIR$\..\..\src\bacnet\bacapp.c - $PROJ_DIR$\..\..\src\bacapp.c + $PROJ_DIR$\..\..\src\bacnet\bacdcode.c - $PROJ_DIR$\..\..\src\bacdcode.c + $PROJ_DIR$\..\..\src\bacnet\bacerror.c - $PROJ_DIR$\..\..\src\bacerror.c + $PROJ_DIR$\..\..\src\bacnet\bacint.c - $PROJ_DIR$\..\..\src\bacint.c + $PROJ_DIR$\..\..\src\bacnet\bacreal.c - $PROJ_DIR$\..\..\src\bacreal.c + $PROJ_DIR$\..\..\src\bacnet\bacstr.c - $PROJ_DIR$\..\..\src\bacstr.c + $PROJ_DIR$\..\..\src\bacnet\datalink\crc.c - $PROJ_DIR$\..\..\src\crc.c + $PROJ_DIR$\..\..\src\bacnet\dcc.c - $PROJ_DIR$\..\..\src\dcc.c + $PROJ_DIR$\..\..\src\bacnet\basic\sys\fifo.c - $PROJ_DIR$\..\..\src\fifo.c + $PROJ_DIR$\..\..\src\bacnet\iam.c - $PROJ_DIR$\..\..\src\iam.c + $PROJ_DIR$\..\..\src\bacnet\ihave.c - $PROJ_DIR$\..\..\src\ihave.c + $PROJ_DIR$\..\..\src\bacnet\memcopy.c - $PROJ_DIR$\..\..\src\memcopy.c + $PROJ_DIR$\..\..\src\bacnet\npdu.c - $PROJ_DIR$\..\..\src\npdu.c + $PROJ_DIR$\..\..\src\bacnet\proplist.c - $PROJ_DIR$\..\..\src\proplist.c + $PROJ_DIR$\..\..\src\bacnet\rd.c - $PROJ_DIR$\..\..\src\rd.c + $PROJ_DIR$\..\..\src\bacnet\reject.c - $PROJ_DIR$\..\..\src\reject.c + $PROJ_DIR$\..\..\src\bacnet\rp.c - $PROJ_DIR$\..\..\src\ringbuf.c + $PROJ_DIR$\..\..\src\bacnet\rpm.c - $PROJ_DIR$\..\..\src\rp.c + $PROJ_DIR$\..\..\src\bacnet\whohas.c - $PROJ_DIR$\..\..\src\rpm.c + $PROJ_DIR$\..\..\src\bacnet\whois.c - $PROJ_DIR$\..\..\src\whohas.c - - - $PROJ_DIR$\..\..\src\whois.c - - - $PROJ_DIR$\..\..\src\wp.c + $PROJ_DIR$\..\..\src\bacnet\wp.c BACnet-Handlers - $PROJ_DIR$\..\..\demo\handler\h_dcc.c + $PROJ_DIR$\..\..\src\bacnet\basic\service\h_apdu.c - $PROJ_DIR$\..\..\demo\handler\h_npdu.c + $PROJ_DIR$\..\..\src\bacnet\basic\service\h_dcc.c - $PROJ_DIR$\..\..\demo\handler\h_rd.c + $PROJ_DIR$\..\..\src\bacnet\basic\service\h_noserv.c - $PROJ_DIR$\..\..\demo\handler\h_rp.c + $PROJ_DIR$\..\..\src\bacnet\basic\npdu\h_npdu.c - $PROJ_DIR$\..\..\demo\handler\h_rpm.c + $PROJ_DIR$\..\..\src\bacnet\basic\service\h_rd.c - $PROJ_DIR$\..\..\demo\handler\h_whohas.c + $PROJ_DIR$\..\..\src\bacnet\basic\service\h_rp.c - $PROJ_DIR$\..\..\demo\handler\h_whois.c + $PROJ_DIR$\..\..\src\bacnet\basic\service\h_rpm.c - $PROJ_DIR$\..\..\demo\handler\h_wp.c + $PROJ_DIR$\..\..\src\bacnet\basic\service\h_whohas.c - $PROJ_DIR$\..\..\demo\handler\noserv.c + $PROJ_DIR$\..\..\src\bacnet\basic\service\h_whois.c - $PROJ_DIR$\..\..\demo\handler\s_iam.c + $PROJ_DIR$\..\..\src\bacnet\basic\service\h_wp.c - $PROJ_DIR$\..\..\demo\handler\s_ihave.c + $PROJ_DIR$\..\..\src\bacnet\basic\sys\mstimer.c - $PROJ_DIR$\..\..\demo\handler\txbuf.c + $PROJ_DIR$\..\..\src\bacnet\basic\sys\ringbuf.c + + + $PROJ_DIR$\..\..\src\bacnet\basic\service\s_iam.c + + + $PROJ_DIR$\..\..\src\bacnet\basic\service\s_ihave.c + + + $PROJ_DIR$\..\..\src\bacnet\basic\tsm\tsm.c @@ -1247,6 +1270,9 @@ $PROJ_DIR$\main.c + + $PROJ_DIR$\mstimer-init.c + $PROJ_DIR$\rs485.c @@ -1256,10 +1282,4 @@ $PROJ_DIR$\system_stm32f10x.c - - $PROJ_DIR$\timer.c - - - $PROJ_DIR$\timer_sys.c - diff --git a/ports/stm32f10x/bo.c b/ports/stm32f10x/bo.c index f4596df5..49c0d3d4 100644 --- a/ports/stm32f10x/bo.c +++ b/ports/stm32f10x/bo.c @@ -28,14 +28,14 @@ #include #include #include -#include "bacdef.h" -#include "bacdcode.h" -#include "bacenum.h" -#include "config.h" -#include "wp.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacenum.h" +#include "bacnet/config.h" +#include "bacnet/wp.h" #include "hardware.h" -#include "handlers.h" -#include "bo.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/object/bo.h" #ifndef MAX_BINARY_OUTPUTS #error Please define MAX_BINARY_OUTPUTS diff --git a/ports/stm32f10x/device.c b/ports/stm32f10x/device.c index d7481af9..40c6f66a 100644 --- a/ports/stm32f10x/device.c +++ b/ports/stm32f10x/device.c @@ -27,19 +27,19 @@ #include #include #include -#include "bacdef.h" -#include "bacdcode.h" -#include "bacstr.h" -#include "bacenum.h" -#include "apdu.h" -#include "dcc.h" -#include "datalink.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacstr.h" +#include "bacnet/bacenum.h" +#include "bacnet/apdu.h" +#include "bacnet/dcc.h" +#include "bacnet/datalink/datalink.h" #include "rs485.h" -#include "version.h" -#include "handlers.h" +#include "bacnet/version.h" +#include "bacnet/basic/services.h" /* objects */ -#include "device.h" -#include "bo.h" +#include "bacnet/basic/object/device.h" +#include "bacnet/basic/object/bo.h" /* forward prototype */ int Device_Read_Property_Local( @@ -81,6 +81,7 @@ static BACNET_CHARACTER_STRING My_Object_Name; static uint32_t Database_Revision; static BACNET_REINITIALIZED_STATE Reinitialize_State = BACNET_REINIT_IDLE; static const char *Reinit_Password = "stm32-challenge"; +static const char *BACnet_Version = BACNET_VERSION_TEXT; /* These three arrays are used by the ReadPropertyMultiple handler */ static const int Device_Properties_Required[] = { diff --git a/ports/stm32f10x/dlmstp.c b/ports/stm32f10x/dlmstp.c index 9cc74484..bc18460f 100644 --- a/ports/stm32f10x/dlmstp.c +++ b/ports/stm32f10x/dlmstp.c @@ -36,18 +36,18 @@ #include #include #include -#include "bacdef.h" -#include "dlmstp.h" +#include "bacnet/bacdef.h" +#include "bacnet/datalink/dlmstp.h" #include "rs485.h" -#include "crc.h" -#include "npdu.h" -#include "bits.h" -#include "bacaddr.h" -#include "timer.h" -#include "ringbuf.h" -#include "mstpdef.h" +#include "bacnet/npdu.h" +#include "bacnet/bits.h" +#include "bacnet/bacaddr.h" +#include "bacnet/basic/sys/mstimer.h" +#include "bacnet/basic/sys/ringbuf.h" +#include "bacnet/datalink/crc.h" +#include "bacnet/datalink/mstpdef.h" #include "automac.h" -#include "device.h" +#include "bacnet/basic/object/device.h" /* This file has been customized for use with small microprocessors */ /* Assumptions: diff --git a/ports/stm32f10x/drivers/Release_Notes_for_STM32F10x_StdPeriph_Driver.html b/ports/stm32f10x/drivers/Release_Notes_for_STM32F10x_StdPeriph_Driver.html index 32c266b3..e58d1f06 100644 --- a/ports/stm32f10x/drivers/Release_Notes_for_STM32F10x_StdPeriph_Driver.html +++ b/ports/stm32f10x/drivers/Release_Notes_for_STM32F10x_StdPeriph_Driver.html @@ -1,295 +1,295 @@ - - - - - - - - -Release Notes for STM32F10x Standard Peripherals Library Drivers - - - - -
-


-

-
- - - - - - -
- - - - - - - - - -
Back to Release page
-

Release -Notes for STM32F10x Standard Peripherals Library Drivers -(StdPeriph_Driver)

-

Copyright 2010 STMicroelectronics

-

-
-

 

- - - - - - -
-

Contents

-
    -
  1. STM32F10x Standard Peripherals Library -Drivers update History
  2. -
  3. License
  4. -
- - -

STM32F10x Standard -Peripherals Library Drivers  update History

-

3.4.0 -- 10/15/2010

- -
    -
  1. General
  2. -
- -
    -
  • Add support for STM32F10x High-density value line devices.
  • -
- -
    -
  1. STM32F10x_StdPeriph_Driver
  2. -
- - -
    - -
  • stm32f10x_bkp.h/.c
  • -
      -
    • Delete BKP registers definition from stm32f10x_bkp.c and use defines within stm32f10x.h file.
    • -
    -
  • stm32f10x_can.h/.c
  • -
      -
    • Delete CAN registers definition from stm32f10x_can.c and use defines within stm32f10x.h file.
      -
    • -
    • Update the wording of some defines and Asserts macro.
      -
    • -
    • CAN_GetFlagStatus() -and CAN_ClearFlag() functions: updated to support new flags (were not -supported in previous version). These flags are:  CAN_FLAG_RQCP0, -CAN_FLAG_RQCP1, CAN_FLAG_RQCP2, CAN_FLAG_FMP1, CAN_FLAG_FF1, -CAN_FLAG_FOV1, CAN_FLAG_FMP0, CAN_FLAG_FF0,   CAN_FLAG_FOV0, -CAN_FLAG_WKU, CAN_FLAG_SLAK and CAN_FLAG_LEC.
      -
    • -
    • CAN_GetITStatus() -function: add a check of the interrupt enable bit before getting the -status of corresponding interrupt pending bit.
      -
    • -
    • CAN_ClearITPendingBit() function: correct the procedure to clear the interrupt pending bit.
      -
    • -
    -
  • stm32f10x_crc.h/.c
  • -
      -
    • Delete CRC registers definition from stm32f10x_crc.c and use defines within stm32f10x.h file.
    • -
    -
  • stm32f10x_dac.h/.c
  • -
      -
    • Delete DAC registers definition from stm32f10x_dac.c and use defines within stm32f10x.h file.
    • -
    -
  • stm32f10x_dbgmcu.h/.c
  • -
      -
    • Delete DBGMCU registers definition from stm32f10x_dbgmcu.c and use defines within stm32f10x.h file.
    • -
    -
  • stm32f10x_dma.h/.c
  • -
      -
    • Delete DMA registers definition from stm32f10x_dma.c and use defines within stm32f10x.h file.
    • -
    • Add new function "void DMA_SetCurrDataCounter(DMA_Channel_TypeDef* DMAy_Channelx, uint16_t DataNumber);"
      -
    • -
    -
  • stm32f10x_flash.h/.c
  • -
      -
    • FLASH functions (Erase and Program) updated to always clear the "PG", "MER" and "PER" bits even in case of TimeOut Error.
    • -
    -
  • stm32f10x_fsmc.h/.c
  • -
      -
    • Add new member "FSMC_AsynchronousWait" in "FSMC_NORSRAMInitTypeDef" structure.
    • -
    -
  • stm32f10x_gpio.h/.c
  • -
      -
    • GPIO_PinRemapConfig() function: add new values for GPIO_Remap parameter, to support new remap for TIM6, TIM7 and DAC DMA requests, TIM12 and DAC Triggers / DMA2_Channel5 Interrupt mapping.
    • -
    -
  • stm32f10x_pwr.h/.c
  • -
      -
    • Delete PWR registers definition from stm32f10x_pwr.c and use defines within stm32f10x.h and core_cm3.h files.
    • -
    -
  • stm32f10x_rtc.h/.c
  • -
      -
    • Delete RTC registers definition from stm32f10x_rtc.c and use defines within stm32f10x.h file.
    • -
    -
  • stm32f10x_spi.h/.c
  • -
      -
    • Add new definition for I2S Audio Clock frequencies "I2S_AudioFreq_192k".
    • -
    -
  • stm32f10x_tim.h/.c
  • -
    • Add new definition for TIM Input Capture Polarity "TIM_ICPolarity_BothEdge".
    - -
- -

3.3.0 -- 04/16/2010

- -
  1. General
-
  • Add support for STM32F10x XL-density devices.
  • I2C driver: events description and management enhancement.
-
  1. STM32F10x_StdPeriph_Driver
-
  • stm32f10x_dbgmcu.h/.c
    • DBGMCU_Config() function: add new values DBGMCU_TIMx_STOP (x: 9..14) for DBGMCU_Periph parameter.
  • stm32f10x_flash.h/.c: -updated to support Bank2 of XL-density devices (up to 1MByte of Flash -memory). For more details, refer to the description provided within -stm32f10x_flash.c file.
  • stm32f10x_gpio.h/.c
    • GPIO_PinRemapConfig() function: add new values for GPIO_Remap parameter, to support new remap for FSMC_NADV pin and TIM9..11,13,14.
  • stm32f10x_i2c.h/.c: I2C events description and management enhancement.
    • I2C_CheckEvent() -function: updated to check whether the last event contains the -I2C_EVENT  (instead of check whether the last event is equal to -I2C_EVENT)
    • Add -detailed description of I2C events and how to manage them using the -functions provided by this driver. For more information, refer to -stm32f10x_i2c.h and stm32f10x_i2c.c files.
  • stm32f10x_rcc.h/.c: updated to support TIM9..TIM14 APB clock and reset configuration
  • stm32f10x_tim.h/.c: updated to support new Timers TIM9..TIM14.
  • stm32f10x_sdio.h: 
    • SDIO_SetSDIOReadWaitMode() function: correct values of SDIO_ReadWaitMode parameter
      change
        -#define -SDIO_ReadWaitMode_CLK               -  ((uint32_t)0x00000000)
        #define -SDIO_ReadWaitMode_DATA2             -((uint32_t)0x00000001)
      by
        #define -SDIO_ReadWaitMode_CLK               -  ((uint32_t)0x00000001)
        #define -SDIO_ReadWaitMode_DATA2             -((uint32_t)0x00000000)
-

3.2.0 -- 03/01/2010

-
    -
  1. General
  2. -
-
    - -
  • Add support -for STM32 Low-density Value line (STM32F100x4/6) and -Medium-density Value line (STM32F100x8/B) devices.
  • -
  • Almost -peripherals drivers were updated to support Value -line devices features
  • -
  • Drivers limitations fix and enhancements.
  • - -
-
    -
  1. STM32F10x_StdPeriph_Driver
  2. -
-
    -
  • Add new -firmware driver for CEC peripheral: stm32f10x_cec.h and stm32f10x_cec.c
  • -
  • Timers drivers stm32f10x_tim.h/.c: add support for new General Purpose Timers: TIM15, TIM16 and TIM17.
  • -
  • RCC driver: add support for new Value peripherals: HDMI-CEC, TIM15, TIM16 and TIM17.
  • -
  • GPIO driver: add new remap parameters for TIM1, TIM15, TIM16, TIM17 and HDMI-CEC: GPIO_Remap_TIM1_DMA, GPIO_Remap_TIM15, GPIO_Remap_TIM16, GPIO_Remap_TIM17, GPIO_Remap_CEC.
  • -
  • USART -driver: add support for Oversampling by 8 mode and onebit method. 2 -functions has been added: USART_OverSampling8Cmd() and -USART_OneBitMethodCmd().
    -
  • -
  • DAC -driver: add new functions handling the DAC under run feature: -DAC_ITConfig(), DAC_GetFlagStatus(), DAC_ClearFlag(), DAC_GetITStatus() -and DAC_ClearITPendingBit().
  • -
  • DBGMCU driver: add new parameters for TIM15, TIM16 and TIM17: DBGMCU_TIM15_STOP, DBGMCU_TIM16_STOP, DBGMCU_TIM17_STOP.
    -
  • -
  • FLASH -driver: the FLASH_EraseOptionBytes() function updated. This is now just -erasing the option bytes without modifying the RDP status either -enabled or disabled.
  • -
  • PWR -driver: the PWR_EnterSTOPMode() function updated. When woken up from -STOP mode, this function resets again the SLEEPDEEP bit in the -Cortex-M3 System Control register to allow Sleep mode entering.
  • - - -
-

License

-

The -enclosed firmware and all the related documentation are not covered by -a License Agreement, if you need such License you can contact your -local STMicroelectronics office.

-

THE -PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS -WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO -SAVE TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR -ANY DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY -CLAIMS ARISING FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY -CUSTOMERS OF THE CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH -THEIR PRODUCTS.

-

 

-
-
-

For -complete documentation on STM32(CORTEX M3) 32-Bit Microcontrollers -visit www.st.com/STM32

-
-

-
-
-

 

-
+ + + + + + + + +Release Notes for STM32F10x Standard Peripherals Library Drivers + + + + +
+


+

+
+ + + + + + +
+ + + + + + + + + +
Back to Release page
+

Release +Notes for STM32F10x Standard Peripherals Library Drivers +(StdPeriph_Driver)

+

Copyright 2010 STMicroelectronics

+

+
+

 

+ + + + + + +
+

Contents

+
    +
  1. STM32F10x Standard Peripherals Library +Drivers update History
  2. +
  3. License
  4. +
+ + +

STM32F10x Standard +Peripherals Library Drivers  update History

+

3.4.0 +- 10/15/2010

+ +
    +
  1. General
  2. +
+ +
    +
  • Add support for STM32F10x High-density value line devices.
  • +
+ +
    +
  1. STM32F10x_StdPeriph_Driver
  2. +
+ + +
    + +
  • stm32f10x_bkp.h/.c
  • +
      +
    • Delete BKP registers definition from stm32f10x_bkp.c and use defines within stm32f10x.h file.
    • +
    +
  • stm32f10x_can.h/.c
  • +
      +
    • Delete CAN registers definition from stm32f10x_can.c and use defines within stm32f10x.h file.
      +
    • +
    • Update the wording of some defines and Asserts macro.
      +
    • +
    • CAN_GetFlagStatus() +and CAN_ClearFlag() functions: updated to support new flags (were not +supported in previous version). These flags are:  CAN_FLAG_RQCP0, +CAN_FLAG_RQCP1, CAN_FLAG_RQCP2, CAN_FLAG_FMP1, CAN_FLAG_FF1, +CAN_FLAG_FOV1, CAN_FLAG_FMP0, CAN_FLAG_FF0,   CAN_FLAG_FOV0, +CAN_FLAG_WKU, CAN_FLAG_SLAK and CAN_FLAG_LEC.
      +
    • +
    • CAN_GetITStatus() +function: add a check of the interrupt enable bit before getting the +status of corresponding interrupt pending bit.
      +
    • +
    • CAN_ClearITPendingBit() function: correct the procedure to clear the interrupt pending bit.
      +
    • +
    +
  • stm32f10x_crc.h/.c
  • +
      +
    • Delete CRC registers definition from stm32f10x_crc.c and use defines within stm32f10x.h file.
    • +
    +
  • stm32f10x_dac.h/.c
  • +
      +
    • Delete DAC registers definition from stm32f10x_dac.c and use defines within stm32f10x.h file.
    • +
    +
  • stm32f10x_dbgmcu.h/.c
  • +
      +
    • Delete DBGMCU registers definition from stm32f10x_dbgmcu.c and use defines within stm32f10x.h file.
    • +
    +
  • stm32f10x_dma.h/.c
  • +
      +
    • Delete DMA registers definition from stm32f10x_dma.c and use defines within stm32f10x.h file.
    • +
    • Add new function "void DMA_SetCurrDataCounter(DMA_Channel_TypeDef* DMAy_Channelx, uint16_t DataNumber);"
      +
    • +
    +
  • stm32f10x_flash.h/.c
  • +
      +
    • FLASH functions (Erase and Program) updated to always clear the "PG", "MER" and "PER" bits even in case of TimeOut Error.
    • +
    +
  • stm32f10x_fsmc.h/.c
  • +
      +
    • Add new member "FSMC_AsynchronousWait" in "FSMC_NORSRAMInitTypeDef" structure.
    • +
    +
  • stm32f10x_gpio.h/.c
  • +
      +
    • GPIO_PinRemapConfig() function: add new values for GPIO_Remap parameter, to support new remap for TIM6, TIM7 and DAC DMA requests, TIM12 and DAC Triggers / DMA2_Channel5 Interrupt mapping.
    • +
    +
  • stm32f10x_pwr.h/.c
  • +
      +
    • Delete PWR registers definition from stm32f10x_pwr.c and use defines within stm32f10x.h and core_cm3.h files.
    • +
    +
  • stm32f10x_rtc.h/.c
  • +
      +
    • Delete RTC registers definition from stm32f10x_rtc.c and use defines within stm32f10x.h file.
    • +
    +
  • stm32f10x_spi.h/.c
  • +
      +
    • Add new definition for I2S Audio Clock frequencies "I2S_AudioFreq_192k".
    • +
    +
  • stm32f10x_tim.h/.c
  • +
    • Add new definition for TIM Input Capture Polarity "TIM_ICPolarity_BothEdge".
    + +
+ +

3.3.0 +- 04/16/2010

+ +
  1. General
+
  • Add support for STM32F10x XL-density devices.
  • I2C driver: events description and management enhancement.
+
  1. STM32F10x_StdPeriph_Driver
+
  • stm32f10x_dbgmcu.h/.c
    • DBGMCU_Config() function: add new values DBGMCU_TIMx_STOP (x: 9..14) for DBGMCU_Periph parameter.
  • stm32f10x_flash.h/.c: +updated to support Bank2 of XL-density devices (up to 1MByte of Flash +memory). For more details, refer to the description provided within +stm32f10x_flash.c file.
  • stm32f10x_gpio.h/.c
    • GPIO_PinRemapConfig() function: add new values for GPIO_Remap parameter, to support new remap for FSMC_NADV pin and TIM9..11,13,14.
  • stm32f10x_i2c.h/.c: I2C events description and management enhancement.
    • I2C_CheckEvent() +function: updated to check whether the last event contains the +I2C_EVENT  (instead of check whether the last event is equal to +I2C_EVENT)
    • Add +detailed description of I2C events and how to manage them using the +functions provided by this driver. For more information, refer to +stm32f10x_i2c.h and stm32f10x_i2c.c files.
  • stm32f10x_rcc.h/.c: updated to support TIM9..TIM14 APB clock and reset configuration
  • stm32f10x_tim.h/.c: updated to support new Timers TIM9..TIM14.
  • stm32f10x_sdio.h: 
    • SDIO_SetSDIOReadWaitMode() function: correct values of SDIO_ReadWaitMode parameter
      change
        +#define +SDIO_ReadWaitMode_CLK               +  ((uint32_t)0x00000000)
        #define +SDIO_ReadWaitMode_DATA2             +((uint32_t)0x00000001)
      by
        #define +SDIO_ReadWaitMode_CLK               +  ((uint32_t)0x00000001)
        #define +SDIO_ReadWaitMode_DATA2             +((uint32_t)0x00000000)
+

3.2.0 +- 03/01/2010

+
    +
  1. General
  2. +
+
    + +
  • Add support +for STM32 Low-density Value line (STM32F100x4/6) and +Medium-density Value line (STM32F100x8/B) devices.
  • +
  • Almost +peripherals drivers were updated to support Value +line devices features
  • +
  • Drivers limitations fix and enhancements.
  • + +
+
    +
  1. STM32F10x_StdPeriph_Driver
  2. +
+
    +
  • Add new +firmware driver for CEC peripheral: stm32f10x_cec.h and stm32f10x_cec.c
  • +
  • Timers drivers stm32f10x_tim.h/.c: add support for new General Purpose Timers: TIM15, TIM16 and TIM17.
  • +
  • RCC driver: add support for new Value peripherals: HDMI-CEC, TIM15, TIM16 and TIM17.
  • +
  • GPIO driver: add new remap parameters for TIM1, TIM15, TIM16, TIM17 and HDMI-CEC: GPIO_Remap_TIM1_DMA, GPIO_Remap_TIM15, GPIO_Remap_TIM16, GPIO_Remap_TIM17, GPIO_Remap_CEC.
  • +
  • USART +driver: add support for Oversampling by 8 mode and onebit method. 2 +functions has been added: USART_OverSampling8Cmd() and +USART_OneBitMethodCmd().
    +
  • +
  • DAC +driver: add new functions handling the DAC under run feature: +DAC_ITConfig(), DAC_GetFlagStatus(), DAC_ClearFlag(), DAC_GetITStatus() +and DAC_ClearITPendingBit().
  • +
  • DBGMCU driver: add new parameters for TIM15, TIM16 and TIM17: DBGMCU_TIM15_STOP, DBGMCU_TIM16_STOP, DBGMCU_TIM17_STOP.
    +
  • +
  • FLASH +driver: the FLASH_EraseOptionBytes() function updated. This is now just +erasing the option bytes without modifying the RDP status either +enabled or disabled.
  • +
  • PWR +driver: the PWR_EnterSTOPMode() function updated. When woken up from +STOP mode, this function resets again the SLEEPDEEP bit in the +Cortex-M3 System Control register to allow Sleep mode entering.
  • + + +
+

License

+

The +enclosed firmware and all the related documentation are not covered by +a License Agreement, if you need such License you can contact your +local STMicroelectronics office.

+

THE +PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO +SAVE TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR +ANY DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY +CLAIMS ARISING FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY +CUSTOMERS OF THE CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH +THEIR PRODUCTS.

+

 

+
+
+

For +complete documentation on STM32(CORTEX M3) 32-Bit Microcontrollers +visit www.st.com/STM32

+
+

+
+
+

 

+
\ No newline at end of file diff --git a/ports/stm32f10x/led.c b/ports/stm32f10x/led.c index a692c12f..8e3a7e19 100644 --- a/ports/stm32f10x/led.c +++ b/ports/stm32f10x/led.c @@ -23,11 +23,11 @@ *********************************************************************/ #include #include "hardware.h" -#include "timer.h" +#include "bacnet/basic/sys/mstimer.h" #include "led.h" -static struct itimer Off_Delay_Timer_Rx; -static struct itimer Off_Delay_Timer_Tx; +static struct mstimer Off_Delay_Timer_Rx; +static struct mstimer Off_Delay_Timer_Tx; static bool Rx_State; static bool Tx_State; static bool LD3_State; @@ -41,7 +41,7 @@ void led_tx_on( void) { GPIO_WriteBit(GPIOB, GPIO_Pin_15, Bit_SET); - timer_interval_no_expire(&Off_Delay_Timer_Tx); + mstimer_set(&Off_Delay_Timer_Tx, 0); Tx_State = true; } @@ -54,7 +54,7 @@ void led_rx_on( void) { GPIO_WriteBit(GPIOB, GPIO_Pin_14, Bit_SET); - timer_interval_no_expire(&Off_Delay_Timer_Rx); + mstimer_set(&Off_Delay_Timer_Rx, 0); Rx_State = true; } @@ -67,7 +67,7 @@ void led_tx_off( void) { GPIO_WriteBit(GPIOB, GPIO_Pin_15, Bit_RESET); - timer_interval_no_expire(&Off_Delay_Timer_Tx); + mstimer_set(&Off_Delay_Timer_Tx, 0); Tx_State = false; } @@ -80,7 +80,7 @@ void led_rx_off( void) { GPIO_WriteBit(GPIOB, GPIO_Pin_14, Bit_RESET); - timer_interval_no_expire(&Off_Delay_Timer_Rx); + mstimer_set(&Off_Delay_Timer_Rx, 0); Rx_State = false; } @@ -144,7 +144,7 @@ void led_rx_toggle( void led_rx_off_delay( uint32_t delay_ms) { - timer_interval_start(&Off_Delay_Timer_Rx, delay_ms); + mstimer_set(&Off_Delay_Timer_Rx, delay_ms); } /************************************************************************* @@ -155,7 +155,7 @@ void led_rx_off_delay( void led_tx_off_delay( uint32_t delay_ms) { - timer_interval_start(&Off_Delay_Timer_Tx, delay_ms); + mstimer_set(&Off_Delay_Timer_Tx, delay_ms); } /************************************************************************* @@ -167,7 +167,7 @@ void led_rx_on_interval( uint16_t interval_ms) { led_rx_on(); - timer_interval_start(&Off_Delay_Timer_Rx, interval_ms); + mstimer_set(&Off_Delay_Timer_Rx, interval_ms); } /************************************************************************* @@ -179,7 +179,7 @@ void led_tx_on_interval( uint16_t interval_ms) { led_tx_on(); - timer_interval_start(&Off_Delay_Timer_Tx, interval_ms); + mstimer_set(&Off_Delay_Timer_Tx, interval_ms); } /************************************************************************* @@ -190,12 +190,12 @@ void led_tx_on_interval( void led_task( void) { - if (timer_interval_expired(&Off_Delay_Timer_Rx)) { - timer_interval_no_expire(&Off_Delay_Timer_Rx); + if (mstimer_expired(&Off_Delay_Timer_Rx)) { + mstimer_set(&Off_Delay_Timer_Rx, 0); led_rx_off(); } - if (timer_interval_expired(&Off_Delay_Timer_Tx)) { - timer_interval_no_expire(&Off_Delay_Timer_Tx); + if (mstimer_expired(&Off_Delay_Timer_Tx)) { + mstimer_set(&Off_Delay_Timer_Tx, 0); led_tx_off(); } } diff --git a/ports/stm32f10x/main.c b/ports/stm32f10x/main.c index b49c9bd2..56602329 100644 --- a/ports/stm32f10x/main.c +++ b/ports/stm32f10x/main.c @@ -26,8 +26,8 @@ #include #include #include "hardware.h" -#include "timer.h" -#include "timer.h" +#include "bacnet/basic/sys/mstimer.h" +#include "bacnet/basic/sys/mstimer.h" #include "rs485.h" #include "led.h" #include "bacnet.h" @@ -65,7 +65,7 @@ void lse_init( void) { uint32_t LSE_Delay = 0; - struct etimer Delay_Timer; + struct mstimer Delay_Timer; /* Enable access to the backup register => LSE can be enabled */ PWR_BackupAccessCmd(ENABLE); @@ -75,8 +75,8 @@ void lse_init( /* Check the LSE Status */ while (1) { if (LSE_Delay < LSE_FAIL_FLAG) { - timer_elapsed_start(&Delay_Timer); - while (!timer_elapsed_milliseconds(&Delay_Timer, 500)) { + mstimer_set(&Delay_Timer, 0); + while (mstimer_remaining(&Delay_Timer) < 500) { /* do nothing */ } /* check whether LSE is ready, with 4 seconds timeout */ @@ -108,7 +108,7 @@ void lse_init( int main( void) { - struct itimer Blink_Timer; + struct mstimer Blink_Timer; /*At this stage the microcontroller clock setting is already configured, this is done through SystemInit() function which is called from startup @@ -120,14 +120,14 @@ int main( RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE, ENABLE); - timer_init(); + mstimer_init(); lse_init(); led_init(); bacnet_init(); - timer_interval_start(&Blink_Timer, 125); + mstimer_set(&Blink_Timer, 125); for (;;) { - if (timer_interval_expired(&Blink_Timer)) { - timer_interval_reset(&Blink_Timer); + if (mstimer_expired(&Blink_Timer)) { + mstimer_reset(&Blink_Timer); led_ld3_toggle(); } led_task(); diff --git a/ports/stm32f10x/timer_sys.c b/ports/stm32f10x/mstimer-init.c similarity index 57% rename from ports/stm32f10x/timer_sys.c rename to ports/stm32f10x/mstimer-init.c index 46a30aa8..61b67409 100644 --- a/ports/stm32f10x/timer_sys.c +++ b/ports/stm32f10x/mstimer-init.c @@ -28,40 +28,35 @@ #include #include #include "hardware.h" -#include "timer.h" -#include "debug.h" +#include "bacnet/basic/sys/mstimer.h" +#include "bacnet/basic/sys/debug.h" /* counter for the various timers */ -static volatile uint32_t Millisecond_Counter; +static volatile unsigned long Millisecond_Counter; +static volatile struct mstimer_callback_data_t *Callback_Head; -/************************************************************************* -* Description: Activate the LED -* Returns: nothing -* Notes: none -**************************************************************************/ +/** + * Activate the LED + */ static void timer_debug_on( void) { GPIO_WriteBit(GPIOB, GPIO_Pin_13, Bit_SET); } -/************************************************************************* -* Description: Activate the LED -* Returns: nothing -* Notes: none -**************************************************************************/ +/** + * Deactivate the LED + */ static void timer_debug_off( void) { GPIO_WriteBit(GPIOB, GPIO_Pin_13, Bit_RESET); } -/************************************************************************* -* Description: Toggle the state of the setup LED -* Returns: none -* Notes: none -*************************************************************************/ -void timer_debug_toggle( +/** + * Toggle the state of the debug LED + */ +static void timer_debug_toggle( void) { static bool state = false; @@ -75,36 +70,79 @@ void timer_debug_toggle( } } -/************************************************************************* -* Description: Interrupt Service Routine -* Returns: nothing -* Notes: reserved name for ISR handlers -*************************************************************************/ +/** + * Handles the interrupt from the timer + */ void SysTick_Handler( void) { + struct mstimer_callback_data_t *cb; + /* increment the tick count */ Millisecond_Counter++; + cb = (struct mstimer_callback_data_t *)Callback_Head; + while (cb) { + if (mstimer_expired(&cb->timer)) { + cb->callback(); + if (mstimer_interval(&cb->timer) > 0) { + mstimer_reset(&cb->timer); + } + } + cb = cb->next; + } timer_debug_toggle(); } -/************************************************************************* -* Description: returns the current millisecond count -* Returns: none -* Notes: none -*************************************************************************/ -uint32_t timer_milliseconds( +/** + * Returns the continuous milliseconds count, which rolls over + * + * @return the current milliseconds count + */ +unsigned long mstimer_now( void) { return Millisecond_Counter; } -/************************************************************************* -* Description: Timer setup for 1 millisecond timer -* Returns: none -* Notes: peripheral frequency defined in hardware.h -*************************************************************************/ -void timer_init( +/** + * Configures and enables a repeating callback function + * + * @param cb - pointer to a #mstimer_callback_data_t + * @param callback - pointer to a #timer_callback_function function + * @param milliseconds - how often to call the function + * + * @return true if successfully added and enabled + */ +void mstimer_callback( + struct mstimer_callback_data_t *new_cb, + mstimer_callback_function callback, + unsigned long milliseconds) +{ + struct mstimer_callback_data_t *cb; + + if (new_cb) { + new_cb->callback = callback; + mstimer_set(&new_cb->timer, milliseconds); + } + if (Callback_Head) { + cb = (struct mstimer_callback_data_t *)Callback_Head; + while (cb) { + if (!cb->next) { + cb->next = new_cb; + break; + } else { + cb = cb->next; + } + } + } else { + Callback_Head = new_cb; + } +} + +/** + * Timer setup for 1 millisecond timer + */ +void mstimer_init( void) { GPIO_InitTypeDef GPIO_InitStructure; diff --git a/ports/stm32f10x/rs485.c b/ports/stm32f10x/rs485.c index 0475586f..1b055123 100644 --- a/ports/stm32f10x/rs485.c +++ b/ports/stm32f10x/rs485.c @@ -28,9 +28,9 @@ #include #include #include "hardware.h" -#include "timer.h" -#include "bits.h" -#include "fifo.h" +#include "bacnet/basic/sys/mstimer.h" +#include "bacnet/bits.h" +#include "bacnet/basic/sys/fifo.h" #include "led.h" #include "rs485.h" @@ -38,7 +38,7 @@ static uint8_t Receive_Buffer_Data[512]; static FIFO_BUFFER Receive_Buffer; /* amount of silence on the wire */ -static struct etimer Silence_Timer; +static struct mstimer Silence_Timer; /* baud rate */ static uint32_t Baud_Rate = 38400; @@ -61,7 +61,7 @@ static uint32_t Baud_Rate = 38400; void rs485_silence_reset( void) { - timer_elapsed_start(&Silence_Timer); + mstimer_set(&Silence_Timer, 0); } /************************************************************************* @@ -72,7 +72,7 @@ void rs485_silence_reset( bool rs485_silence_elapsed( uint32_t interval) { - return timer_elapsed_milliseconds(&Silence_Timer, interval); + return (mstimer_remaining(&Silence_Timer) > interval); } /************************************************************************* @@ -101,7 +101,7 @@ static uint16_t rs485_turnaround_time( bool rs485_turnaround_elapsed( void) { - return timer_elapsed_milliseconds(&Silence_Timer, rs485_turnaround_time()); + return (mstimer_remaining(&Silence_Timer) > rs485_turnaround_time()); } @@ -148,7 +148,7 @@ bool rs485_byte_available( if (data_register) { *data_register = FIFO_Get(&Receive_Buffer); } - timer_elapsed_start(&Silence_Timer); + rs485_silence_reset(); data_available = true; led_rx_on_interval(10); } @@ -166,7 +166,7 @@ void rs485_byte_send( { led_tx_on_interval(10); USART_SendData(USART2, tx_byte); - timer_elapsed_start(&Silence_Timer); + rs485_silence_reset(); } /************************************************************************* @@ -219,7 +219,7 @@ void rs485_bytes_send( /* do nothing - wait until the entire frame in the Transmit Shift Register has been shifted out */ } - timer_elapsed_start(&Silence_Timer); + rs485_silence_reset(); return; } @@ -352,5 +352,5 @@ void rs485_init( FIFO_Init(&Receive_Buffer, &Receive_Buffer_Data[0], (unsigned) sizeof(Receive_Buffer_Data)); - timer_elapsed_start(&Silence_Timer); + rs485_silence_reset(); } diff --git a/ports/stm32f10x/timer.c b/ports/stm32f10x/timer.c deleted file mode 100644 index 679529e0..00000000 --- a/ports/stm32f10x/timer.c +++ /dev/null @@ -1,431 +0,0 @@ -/************************************************************************** -* -* Copyright (C) 2009 Steve Karg -* -* Permission is hereby granted, free of charge, to any person obtaining -* a copy of this software and associated documentation files (the -* "Software"), to deal in the Software without restriction, including -* without limitation the rights to use, copy, modify, merge, publish, -* distribute, sublicense, and/or sell copies of the Software, and to -* permit persons to whom the Software is furnished to do so, subject to -* the following conditions: -* -* The above copyright notice and this permission notice shall be included -* in all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*********************************************************************/ -#include -#include -#include "timer.h" - -/* generic elapsed timer handling */ -/* interval not to exceed 49.7 days */ -/* interval of 1ms may be 0 to 1ms */ - -/************************************************************************* -* Description: Sets the start time for an elapsed timer -* Returns: the value of the start timer -* Notes: none -*************************************************************************/ -void timer_elapsed_start( - struct etimer *t) -{ - uint32_t now = timer_milliseconds(); - - if (t) { - t->start = now; - } -} - -/************************************************************************* -* Description: Gets the amount of elapsed time in milliseconds -* Returns: elapsed time in milliseconds -* Notes: none -*************************************************************************/ -uint32_t timer_elapsed_time( - struct etimer *t) -{ - uint32_t now = timer_milliseconds(); - uint32_t delta = 0; - - if (t) { - delta = now - t->start; - } - - return delta; -} - -/************************************************************************* -* Description: Sets the start time with an offset -* Returns: elapsed time in milliseconds -* Notes: none -*************************************************************************/ -void timer_elapsed_start_offset( - struct etimer *t, - uint32_t offset) -{ - uint32_t now = timer_milliseconds(); - - if (t) { - t->start = now + offset; - } -} - -/************************************************************************* -* Description: Tests to see if time has elapsed -* Returns: true if time has elapsed -* Notes: none -*************************************************************************/ -bool timer_elapsed_milliseconds( - struct etimer *t, - uint32_t milliseconds) -{ - return (timer_elapsed_time(t) >= milliseconds); -} - -/************************************************************************* -* Description: Tests to see if time has elapsed -* Returns: true if time has elapsed -* Notes: none -*************************************************************************/ -bool timer_elapsed_seconds( - struct etimer * t, - uint32_t seconds) -{ - uint32_t milliseconds = seconds; - - milliseconds *= 1000L; - - return timer_elapsed_milliseconds(t, milliseconds); -} - -/************************************************************************* -* Description: Tests to see if time has elapsed -* Returns: true if time has elapsed -* Notes: none -*************************************************************************/ -bool timer_elapsed_minutes( - struct etimer * t, - uint32_t minutes) -{ - uint32_t milliseconds = minutes; - - milliseconds *= 1000L; - milliseconds *= 60L; - - return timer_elapsed_milliseconds(t, milliseconds); -} - -/************************************************************************* -* Description: Tests to see if time has elapsed -* Returns: true if time has elapsed -* Notes: none -*************************************************************************/ -bool timer_elapsed_milliseconds_short( - struct etimer * t, - uint16_t value) -{ - uint32_t milliseconds; - - milliseconds = value; - - return (timer_elapsed_time(t) >= milliseconds); -} - -/************************************************************************* -* Description: Tests to see if time has elapsed -* Returns: true if time has elapsed -* Notes: none -*************************************************************************/ -bool timer_elapsed_seconds_short( - struct etimer * t, - uint16_t value) -{ - return timer_elapsed_seconds(t, value); -} - -/************************************************************************* -* Description: Tests to see if time has elapsed -* Returns: true if time has elapsed -* Notes: none -*************************************************************************/ -bool timer_elapsed_minutes_short( - struct etimer * t, - uint16_t value) -{ - return timer_elapsed_minutes(t, value); -} - -/************************************************************************* -* Description: Starts an interval timer -* Returns: nothing -* Notes: none -*************************************************************************/ -void timer_interval_start( - struct itimer *t, - uint32_t interval) -{ - if (t) { - t->start = timer_milliseconds(); - t->interval = interval; - } -} - -/************************************************************************* -* Description: Starts an interval timer -* Returns: nothing -* Notes: none -*************************************************************************/ -void timer_interval_start_seconds( - struct itimer *t, - uint32_t seconds) -{ - uint32_t interval = seconds; - - interval *= 1000L; - timer_interval_start(t, interval); -} - -/************************************************************************* -* Description: Starts an interval timer -* Returns: nothing -* Notes: none -*************************************************************************/ -void timer_interval_start_minutes( - struct itimer *t, - uint32_t minutes) -{ - uint32_t interval = minutes; - - interval *= 1000L; - interval *= 60L; - timer_interval_start(t, interval); -} - -/************************************************************************* -* Description: Determines the amount of time that has elapsed -* Returns: elapsed milliseconds -* Notes: none -*************************************************************************/ -uint32_t timer_interval_elapsed( - struct itimer *t) -{ - uint32_t now = timer_milliseconds(); - uint32_t delta = 0; - - if (t) { - delta = now - t->start; - } - - return delta; -} - -/************************************************************************* -* Description: Determines the amount of time that has elapsed -* Returns: elapsed milliseconds -* Notes: none -*************************************************************************/ -uint32_t timer_interval( - struct itimer * t) -{ - uint32_t interval = 0; - - if (t) { - interval = t->interval; - } - - return interval; -} - -/************************************************************************* -* Description: Tests to see if time has elapsed -* Returns: true if time has elapsed -* Notes: none -*************************************************************************/ -bool timer_interval_expired( - struct itimer * t) -{ - bool expired = false; - - if (t) { - if (t->interval) { - expired = timer_interval_elapsed(t) >= t->interval; - } - } - - return expired; -} - -/************************************************************************* -* Description: Sets the interval value to zero so it never expires -* Returns: nothing -* Notes: none -*************************************************************************/ -void timer_interval_no_expire( - struct itimer *t) -{ - if (t) { - t->interval = 0; - } -} - -/************************************************************************* -* Description: Adds another interval to the start time. Used for cyclic -* timers that won't lose ticks. -* Returns: nothing -* Notes: none -*************************************************************************/ -void timer_interval_reset( - struct itimer *t) -{ - if (t) { - t->start += t->interval; - } -} - -/************************************************************************* -* Description: Restarts the timer with the same interval -* Returns: nothing -* Notes: none -*************************************************************************/ -void timer_interval_restart( - struct itimer *t) -{ - if (t) { - t->start = timer_milliseconds(); - } -} - -/************************************************************************* -* Description: Return the elapsed time -* Returns: number of milliseconds elapsed -* Notes: only up to 255ms elapsed -**************************************************************************/ -uint8_t timer_milliseconds_delta( - uint8_t start) -{ - return (timer_milliseconds_byte() - start); -} - -/************************************************************************* -* Description: Mark the start of a delta timer -* Returns: mark timer starting tick -* Notes: only up to 255ms elapsed -**************************************************************************/ -uint8_t timer_milliseconds_mark( - void) -{ - return timer_milliseconds_byte(); -} - -#ifdef TEST -#include -#include - -#include "ctest.h" - -static uint32_t Milliseconds; - -uint32_t timer_milliseconds( - void) -{ - return Milliseconds; -} - -uint32_t timer_milliseconds_set( - uint32_t value) -{ - uint32_t old_value = Milliseconds; - - Milliseconds = value; - - return old_value; -} - -void testElapsedTimer( - Test * pTest) -{ - struct etimer t; - uint32_t test_time = 0; - - timer_milliseconds_set(test_time); - timer_elapsed_start(&t); - ct_test(pTest, timer_elapsed_time(&t) == test_time); - test_time = 0xffff; - timer_milliseconds_set(test_time); - ct_test(pTest, timer_elapsed_time(&t) == test_time); - test_time = 0xffffffff; - timer_milliseconds_set(test_time); - ct_test(pTest, timer_elapsed_time(&t) == test_time); -} - -void testIntervalTimer( - Test * pTest) -{ - struct itimer t; - uint32_t interval = 0; - uint32_t test_time = 0; - - timer_milliseconds_set(test_time); - timer_interval_start(&t, interval); - test_time = 0xffff; - timer_milliseconds_set(test_time); - ct_test(pTest, timer_interval(&t) == interval); - ct_test(pTest, timer_interval_elapsed(&t) == test_time); - test_time = 0xffffffff; - timer_milliseconds_set(test_time); - ct_test(pTest, timer_interval(&t) == interval); - ct_test(pTest, timer_interval_elapsed(&t) == test_time); - test_time = 0; - timer_milliseconds_set(test_time); - interval = 0xffff; - timer_interval_start(&t, interval); - ct_test(pTest, timer_interval(&t) == interval); - interval = 0xffffffff; - timer_interval_start(&t, interval); - ct_test(pTest, timer_interval(&t) == interval); - - interval = 0; - timer_interval_start_seconds(&t, interval); - ct_test(pTest, timer_interval(&t) == interval); - interval = 60L; - timer_interval_start_seconds(&t, interval); - interval *= 1000L; - ct_test(pTest, timer_interval(&t) == interval); - -} - - -#ifdef TEST_TIMER -int main( - void) -{ - Test *pTest; - bool rc; - - pTest = ct_create("Timer", NULL); - - /* individual tests */ - rc = ct_addTestFunction(pTest, testElapsedTimer); - assert(rc); - rc = ct_addTestFunction(pTest, testIntervalTimer); - assert(rc); - - - ct_setStream(pTest, stdout); - ct_run(pTest); - (void) ct_report(pTest); - - ct_destroy(pTest); - - return 0; -} -#endif -#endif diff --git a/ports/stm32f10x/timer.h b/ports/stm32f10x/timer.h deleted file mode 100644 index dac54d47..00000000 --- a/ports/stm32f10x/timer.h +++ /dev/null @@ -1,115 +0,0 @@ -/************************************************************************** -* -* Copyright (C) 2009 Steve Karg -* -* Permission is hereby granted, free of charge, to any person obtaining -* a copy of this software and associated documentation files (the -* "Software"), to deal in the Software without restriction, including -* without limitation the rights to use, copy, modify, merge, publish, -* distribute, sublicense, and/or sell copies of the Software, and to -* permit persons to whom the Software is furnished to do so, subject to -* the following conditions: -* -* The above copyright notice and this permission notice shall be included -* in all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*********************************************************************/ -#ifndef TIMER_H -#define TIMER_H - -#include -#include - -/* Timer Module */ - -/* elapsed timer structure */ -struct etimer { - uint32_t start; -}; -/* interval timer structure */ -struct itimer { - uint32_t start; - uint32_t interval; -}; - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - - /* these 3 functions are created in the hardware specific module */ - void timer_init( - void); - uint32_t timer_milliseconds( - void); - uint8_t timer_milliseconds_byte( - void); - - /* these functions are in the generic timer.c module */ - - /* elapsed timer */ - void timer_elapsed_start( - struct etimer *t); - void timer_elapsed_start_offset( - struct etimer *t, - uint32_t offset); - uint32_t timer_elapsed_time( - struct etimer *t); - bool timer_elapsed_milliseconds( - struct etimer *t, - uint32_t value); - bool timer_elapsed_seconds( - struct etimer *t, - uint32_t value); - bool timer_elapsed_minutes( - struct etimer *t, - uint32_t value); - bool timer_elapsed_milliseconds_short( - struct etimer *t, - uint16_t value); - bool timer_elapsed_seconds_short( - struct etimer *t, - uint16_t value); - bool timer_elapsed_minutes_short( - struct etimer *t, - uint16_t value); - - /* interval timer */ - void timer_interval_start( - struct itimer *t, - uint32_t interval); - void timer_interval_start_seconds( - struct itimer *t, - uint32_t interval); - void timer_interval_start_minutes( - struct itimer *t, - uint32_t interval); - bool timer_interval_expired( - struct itimer *t); - uint32_t timer_interval( - struct itimer *t); - uint32_t timer_interval_elapsed( - struct itimer *t); - void timer_interval_no_expire( - struct itimer *t); - void timer_interval_reset( - struct itimer *t); - void timer_interval_restart( - struct itimer *t); - - /* special for 8-bit microcontrollers - limited to 255ms */ - uint8_t timer_milliseconds_delta( - uint8_t start); - uint8_t timer_milliseconds_mark( - void); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ -#endif diff --git a/ports/arm7/_stdint.h b/ports/uip/_stdint.h similarity index 100% rename from ports/arm7/_stdint.h rename to ports/uip/_stdint.h diff --git a/ports/arm7/bip.c b/ports/uip/bip.c similarity index 98% rename from ports/arm7/bip.c rename to ports/uip/bip.c index d5a0f429..058078e2 100644 --- a/ports/arm7/bip.c +++ b/ports/uip/bip.c @@ -34,10 +34,10 @@ #include /* for standard integer types uint8_t etc. */ #include /* for the standard bool type. */ -#include "bacdcode.h" -#include "bip.h" +#include "bacnet/bacdcode.h" +#include "bacnet/datalink/bip.h" #include "eth.h" -#include "net.h" /* custom per port */ +#include "bacport.h" /* custom per port */ static int BIP_Socket = -1; /* port to use - stored in host byte order */ diff --git a/ports/arm7/net.h b/ports/uip/net.h similarity index 100% rename from ports/arm7/net.h rename to ports/uip/net.h diff --git a/ports/arm7/stdbool.h b/ports/uip/stdbool.h similarity index 100% rename from ports/arm7/stdbool.h rename to ports/uip/stdbool.h diff --git a/ports/win32/net.h b/ports/win32/bacport.h similarity index 72% rename from ports/win32/net.h rename to ports/win32/bacport.h index 5543362e..2e856e41 100644 --- a/ports/win32/net.h +++ b/ports/win32/bacport.h @@ -23,47 +23,53 @@ * *********************************************************************/ -#ifndef NET_H -#define NET_H +#ifndef BACPORT_H +#define BACPORT_H #define WIN32_LEAN_AND_MEAN #define STRICT 1 /* Windows XP minimum */ -#if (_WIN32_WINNT < 0x0501) +#if (_WIN32_WINNT < _WIN32_WINNT_WINXP) #undef _WIN32_WINNT - #define _WIN32_WINNT 0x0501 + #define _WIN32_WINNT _WIN32_WINNT_WINXP #undef NTDDI_VERSION - #define NTDDI_VERSION 0x05010000 + #define NTDDI_VERSION NTDDI_WINXP #endif - #include #if (!defined(USE_INADDR) || (USE_INADDR == 0)) && \ (!defined(USE_CLASSADDR) || (USE_CLASSADDR == 0)) #include #endif -#include #include #include -#ifndef IPPROTO_IPV6 - // If the version of winsock does not by default include IPV6 then - // use the tech preview if it is avaliable. - #include -#endif #include #include #ifdef __MINGW32__ #include #else #include +/* Microsoft has deprecated some CRT and C++ Standard Library functions +and globals in favor of more secure versions. */ +#pragma warning(disable : 4996) +/* add winmm.lib to our build */ +#pragma comment(lib, "winmm.lib") #endif +#include +#if !defined(_MSC_VER) +#include +#endif #include +#if defined(__BORLANDC__) || defined(_WIN32) +/* seems to not be defined in time.h as specified by The Open Group */ +/* difference from UTC and local standard time */ +extern long int timezone; +#endif #ifdef _MSC_VER #define inline __inline #endif - #ifdef __BORLANDC__ #define inline __inline #endif @@ -72,4 +78,8 @@ typedef int socklen_t; +#ifdef _WIN32 +#define strncasecmp(x, y, z) _strnicmp(x, y, z) +#endif + #endif diff --git a/ports/win32/bip-init.c b/ports/win32/bip-init.c index d42c2b2f..0ebced82 100644 --- a/ports/win32/bip-init.c +++ b/ports/win32/bip-init.c @@ -37,10 +37,10 @@ #include #include /* for standard integer types uint8_t etc. */ #include /* for the standard bool type. */ -#include "bacdcode.h" -#include "config.h" -#include "bip.h" -#include "net.h" +#include "bacnet/bacdcode.h" +#include "bacnet/config.h" +#include "bacnet/datalink/bip.h" +#include "bacport.h" #if defined(_MSC_VER) #pragma comment(lib, "Ws2_32.lib") diff --git a/ports/win32/bip6.c b/ports/win32/bip6.c index 682ea200..83fb52ce 100644 --- a/ports/win32/bip6.c +++ b/ports/win32/bip6.c @@ -36,12 +36,13 @@ #include #include /* for standard integer types uint8_t etc. */ #include /* for the standard bool type. */ -#include "bacdcode.h" -#include "config.h" -#include "debug.h" -#include "device.h" -#include "bip6.h" -#include "net.h" +#include "bacnet/bacdcode.h" +#include "bacnet/config.h" +#include "bacnet/basic/sys/debug.h" +#include "bacnet/basic/object/device.h" +#include "bacnet/basic/bbmd6/h_bbmd6.h" +#include "bacnet/datalink/bip6.h" +#include "bacport.h" /* Win32 Socket */ static SOCKET BIP6_Socket = INVALID_SOCKET; diff --git a/ports/win32/datetime-init.c b/ports/win32/datetime-init.c new file mode 100644 index 00000000..76825a1e --- /dev/null +++ b/ports/win32/datetime-init.c @@ -0,0 +1,183 @@ +/** + * @file + * @author Steve Karg + * @date 2009 + * @brief System time library header file. + * + * @section DESCRIPTION + * + * This library provides functions for getting and setting the system time. + */ +#include +#include +#include +#include +#include +#include +#include +#include "bacport.h" +#include "bacnet/datetime.h" + +/* Offset between Windows epoch 1/1/1601 and + Unix epoch 1/1/1970 in 100 nanosec units */ +#if defined(_MSC_VER) || defined(_MSC_EXTENSIONS) || defined(__BORLANDC__) +#define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64 +#else +#define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL +#endif + +#if defined(__BORLANDC__) || defined(_WIN32) +/* seems to not be defined in time.h as specified by The Open Group */ +/* difference from UTC and local standard time */ +long int timezone; +#endif + +#if defined(_MSC_VER) || defined(__BORLANDC__) +struct timezone { + int tz_minuteswest; /* minutes W of Greenwich */ + int tz_dsttime; /* type of dst correction */ +}; + +/************************************************************************* +* Description: simulate the gettimeofday Linux function +* Returns: zero +* Note: The resolution of GetSystemTimeAsFileTime() is 15625 microseconds. +* The resolution of _ftime() is about 16 milliseconds. +* To get microseconds accuracy we need to use QueryPerformanceCounter or +* timeGetTime for the elapsed time. +*************************************************************************/ + +int gettimeofday( + struct timeval *tp, + void *tzp) +{ + static int tzflag = 0; + struct timezone *tz; + /* start calendar time in microseconds */ + static LONGLONG usec_timer = 0; + LONGLONG usec_elapsed = 0; + /* elapsed time in milliseconds */ + static uint32_t time_start = 0; + /* semi-accurate time from File Timer */ + FILETIME ft; + uint32_t elapsed_milliseconds = 0; + + tzp = tzp; + if (usec_timer == 0) { + /* a 64-bit value representing the number of + 100-nanosecond intervals since January 1, 1601 (UTC). */ + GetSystemTimeAsFileTime(&ft); + usec_timer = ft.dwHighDateTime; + usec_timer <<= 32; + usec_timer |= ft.dwLowDateTime; + /*converting file time to unix epoch 1970 */ + usec_timer /= 10; /*convert into microseconds */ + usec_timer -= DELTA_EPOCH_IN_MICROSECS; + tp->tv_sec = (long) (usec_timer / 1000000UL); + tp->tv_usec = (long) (usec_timer % 1000000UL); + time_start = timeGetTime(); + } else { + elapsed_milliseconds = timeGetTime() - time_start; + usec_elapsed = usec_timer + ((LONGLONG) elapsed_milliseconds * 1000UL); + tp->tv_sec = (long) (usec_elapsed / 1000000UL); + tp->tv_usec = (long) (usec_elapsed % 1000000UL); + } + if (tzp) { + if (!tzflag) { + _tzset(); + tzflag++; + } + tz = tzp; + tz->tz_minuteswest = _timezone / 60; + tz->tz_dsttime = _daylight; + } + + return 0; +} +#endif + +/** + * @brief Get the date, time, timezone, and UTC offset from system + * @param utc_time - the BACnet Date and Time structure to hold UTC time + * @param local_time - the BACnet Date and Time structure to hold local time + * @param utc_offset_minutes - number of minutes offset from UTC + * For example, -6*60 represents 6.00 hours behind UTC/GMT + * @param true if DST is enabled and active + * @return true if local time was retrieved + */ +bool datetime_local( + BACNET_DATE * bdate, + BACNET_TIME * btime, + int16_t * utc_offset_minutes, + bool * dst_active) +{ + bool status = false; + struct tm *tblock = NULL; +#if defined(_MSC_VER) + time_t tTemp; +#else + struct timeval tv; +#endif +#if defined(_MSC_VER) + time(&tTemp); + tblock = (struct tm *)localtime(&tTemp); +#else + if (gettimeofday(&tv, NULL) == 0) { + tblock = (struct tm *)localtime((const time_t *)&tv.tv_sec); + } +#endif + + if (tblock) { + status = true; + /** struct tm + * int tm_sec Seconds [0,60]. + * int tm_min Minutes [0,59]. + * int tm_hour Hour [0,23]. + * int tm_mday Day of month [1,31]. + * int tm_mon Month of year [0,11]. + * int tm_year Years since 1900. + * int tm_wday Day of week [0,6] (Sunday =0). + * int tm_yday Day of year [0,365]. + * int tm_isdst Daylight Savings flag. + */ + datetime_set_date(bdate, (uint16_t)tblock->tm_year + 1900, + (uint8_t)tblock->tm_mon + 1, + (uint8_t)tblock->tm_mday); +#if !defined(_MSC_VER) + datetime_set_time(btime, (uint8_t)tblock->tm_hour, + (uint8_t)tblock->tm_min, (uint8_t)tblock->tm_sec, + (uint8_t)(tv.tv_usec / 10000)); +#else + datetime_set_time(btime, (uint8_t)tblock->tm_hour, + (uint8_t)tblock->tm_min, (uint8_t)tblock->tm_sec, 0); +#endif + if (dst_active) { + /* The value of tm_isdst is: + - positive if Daylight Saving Time is in effect, + - 0 if Daylight Saving Time is not in effect, and + - negative if the information is not available. */ + if (tblock->tm_isdst > 0) { + *dst_active = true; + } else { + *dst_active = false; + } + } + /* note: timezone is declared in stdlib. */ + if (utc_offset_minutes) { + /* timezone is set to the difference, in seconds, + between Coordinated Universal Time (UTC) and + local standard time */ + *utc_offset_minutes = timezone / 60; + } + } + + return status; +} + +/** + * initialize the date time + */ +void datetime_init(void) +{ + /* nothing to do */ +} diff --git a/ports/win32/dlmstp-mm.c b/ports/win32/dlmstp-mm.c index 6acea9e1..1cfd5543 100644 --- a/ports/win32/dlmstp-mm.c +++ b/ports/win32/dlmstp-mm.c @@ -29,13 +29,13 @@ #include #include #include -#include "bacdef.h" -#include "bacaddr.h" -#include "mstp.h" -#include "dlmstp.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacaddr.h" +#include "bacnet/datalink/mstp.h" +#include "bacnet/datalink/dlmstp.h" #include "rs485.h" -#include "npdu.h" -#include "bits.h" +#include "bacnet/npdu.h" +#include "bacnet/bits.h" #define WIN32_LEAN_AND_MEAN #define STRICT 1 diff --git a/ports/win32/dlmstp.c b/ports/win32/dlmstp.c index c24ee3ba..cef0c59c 100644 --- a/ports/win32/dlmstp.c +++ b/ports/win32/dlmstp.c @@ -23,28 +23,23 @@ * *********************************************************************/ +#include #include #include #include #include -#include #include -#ifdef __BORLANDC__ -#include -#endif -#include "bacdef.h" -#include "bacaddr.h" -#include "mstp.h" -#include "dlmstp.h" +#include +#include "bacnet/bacdef.h" +#include "bacnet/bacaddr.h" +#include "bacnet/bits.h" +#include "bacnet/npdu.h" +#include "bacnet/basic/sys/ringbuf.h" +#include "bacnet/basic/sys/mstimer.h" +#include "bacnet/datalink/mstp.h" +#include "bacnet/datalink/dlmstp.h" +#include "bacport.h" #include "rs485.h" -#include "npdu.h" -#include "bits.h" -#include "ringbuf.h" -#include "timer.h" - -#define WIN32_LEAN_AND_MEAN -#define STRICT 1 -#include /* Number of MS/TP Packets Rx/Tx */ uint16_t MSTP_Packets = 0; @@ -70,18 +65,20 @@ static uint16_t Treply_timeout = 260; /* a Poll For Master frame: 20 milliseconds. (Implementations may use */ /* larger values for this timeout, not to exceed 100 milliseconds.) */ static uint8_t Tusage_timeout = 50; +/* local timer for tracking silence on the wire */ +static struct mstimer Silence_Timer; /* Timer that indicates line silence - and functions */ static uint32_t Timer_Silence( void *pArg) { - return timer_milliseconds(TIMER_SILENCE); + return mstimer_remaining(&Silence_Timer); } static void Timer_Silence_Reset( void *pArg) { - timer_reset(TIMER_SILENCE); + mstimer_set(&Silence_Timer, 0); } void dlmstp_cleanup( @@ -592,7 +589,7 @@ bool dlmstp_init( exit(1); } /* initialize hardware */ - timer_init(); + mstimer_set(&Silence_Timer, 0); if (ifname) { RS485_Set_Interface(ifname); } diff --git a/ports/win32/ethernet.c b/ports/win32/ethernet.c index c8cab7f9..ab4253a6 100644 --- a/ports/win32/ethernet.c +++ b/ports/win32/ethernet.c @@ -38,9 +38,9 @@ #include #include -#include "bacdef.h" -#include "ethernet.h" -#include "bacdcode.h" +#include "bacnet/bacdef.h" +#include "bacnet/datalink/ethernet.h" +#include "bacnet/bacdcode.h" /* Uses WinPCap to access raw ethernet */ diff --git a/ports/win32/main.c b/ports/win32/main.c index 24bf9333..8dde5455 100644 --- a/ports/win32/main.c +++ b/ports/win32/main.c @@ -30,33 +30,33 @@ #include #include #include /* for kbhit and getch */ -#include "iam.h" -#include "address.h" -#include "config.h" -#include "bacdef.h" -#include "npdu.h" -#include "apdu.h" -#include "device.h" -#include "handlers.h" -#include "client.h" -#include "datalink.h" -#include "txbuf.h" -#include "dlenv.h" +#include "bacnet/iam.h" +#include "bacnet/basic/binding/address.h" +#include "bacnet/config.h" +#include "bacnet/bacdef.h" +#include "bacnet/npdu.h" +#include "bacnet/apdu.h" +#include "bacnet/basic/object/device.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/services.h" +#include "bacnet/datalink/datalink.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/datalink/dlenv.h" /* include the objects */ -#include "device.h" -#include "ai.h" -#include "ao.h" -#include "av.h" -#include "bi.h" -#include "bo.h" -#include "bv.h" -#include "lc.h" -#include "lsp.h" -#include "mso.h" -#include "ms-input.h" -#include "trendlog.h" +#include "bacnet/basic/object/device.h" +#include "bacnet/basic/object/ai.h" +#include "bacnet/basic/object/ao.h" +#include "bacnet/basic/object/av.h" +#include "bacnet/basic/object/bi.h" +#include "bacnet/basic/object/bo.h" +#include "bacnet/basic/object/bv.h" +#include "bacnet/basic/object/lc.h" +#include "bacnet/basic/object/lsp.h" +#include "bacnet/basic/object/mso.h" +#include "bacnet/basic/object/ms-input.h" +#include "bacnet/basic/object/trendlog.h" #if defined(BACFILE) -#include "bacfile.h" +#include "bacnet/basic/object/bacfile.h" #endif /* buffer used for receive */ diff --git a/ports/win32/mstimer-init.c b/ports/win32/mstimer-init.c new file mode 100644 index 00000000..87c85b90 --- /dev/null +++ b/ports/win32/mstimer-init.c @@ -0,0 +1,89 @@ +/************************************************************************** +* +* Copyright (C) 2009 Steve Karg +* Multimedia Timer contribution by Cameron Crothers, 2008 +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +* +*********************************************************************/ +#include +#include +#include +#include +#include +#include +#include "bacport.h" +#include "bacnet/basic/sys/mstimer.h" + +/* counter for the various timers */ +static volatile unsigned long Millisecond_Counter; + +/* Windows timer period - in milliseconds */ +static unsigned long Timer_Period = 1; + +/** +* @brief returns the current millisecond count +* @return millisecond counter +*/ +unsigned long mstimer_now(void) +{ + unsigned long now = timeGetTime(); + unsigned long delta_time = 0; + + + if (Millisecond_Counter <= now) { + delta_time = now - Millisecond_Counter; + } else { + delta_time = (ULONG_MAX - Millisecond_Counter) + now + 1; + } + + return delta_time; +} + +/** +* @brief Shut down for timer +*/ +static void timer_cleanup( + void) +{ + timeEndPeriod(Timer_Period); +} + +/** +* @brief Initialization for timer +*/ +void mstimer_init(void) +{ + TIMECAPS tc; + + /* set timer resolution */ + if (timeGetDevCaps(&tc, sizeof(TIMECAPS)) != TIMERR_NOERROR) { + fprintf(stderr, "Failed to get timer resolution parameters\n"); + } + /* configure for 1ms resolution - if possible */ + Timer_Period = min(max(tc.wPeriodMin, 1L), tc.wPeriodMax); + if (Timer_Period != 1L) { + fprintf(stderr, + "Failed to set timer to 1ms. " "Time period set to %ums\n", + (unsigned) Timer_Period); + } + timeBeginPeriod(Timer_Period); + atexit(timer_cleanup); +} diff --git a/ports/win32/rs485.c b/ports/win32/rs485.c index e3f0a1cf..c1e1ff08 100644 --- a/ports/win32/rs485.c +++ b/ports/win32/rs485.c @@ -48,13 +48,13 @@ #include #include #include -#include "mstp.h" -#include "dlmstp.h" +#include "bacnet/datalink/mstp.h" +#include "bacnet/datalink/dlmstp.h" #define WIN32_LEAN_AND_MEAN #define STRICT 1 #include #include "rs485.h" -#include "fifo.h" +#include "bacnet/basic/sys/fifo.h" /* details from Serial Communications in Win32 at MSDN */ @@ -511,7 +511,7 @@ void RS485_Print_Ports( #ifdef TEST_RS485 -#include "mstpdef.h" +#include "bacnet/datalink/mstpdef.h" static void test_transmit_task( diff --git a/ports/win32/rs485.h b/ports/win32/rs485.h index 1867b3f4..64ef6494 100644 --- a/ports/win32/rs485.h +++ b/ports/win32/rs485.h @@ -37,8 +37,8 @@ #define RS485_H #include -#include "mstp.h" -#include "net.h" +#include "bacnet/datalink/mstp.h" +#include "bacport.h" #ifdef __cplusplus extern "C" { diff --git a/ports/win32/rx_fsm.c b/ports/win32/rx_fsm.c index 0f54ca9e..be3e625a 100644 --- a/ports/win32/rx_fsm.c +++ b/ports/win32/rx_fsm.c @@ -46,10 +46,10 @@ #include /* local includes */ -#include "bytes.h" +#include "bacnet/bytes.h" #include "rs485.h" -#include "mstp.h" -#include "mstptext.h" +#include "bacnet/datalink/mstp.h" +#include "bacnet/datalink/mstptext.h" #include "crc.h" #ifndef max diff --git a/ports/win32/timer.c b/ports/win32/timer.c deleted file mode 100644 index b7eaa984..00000000 --- a/ports/win32/timer.c +++ /dev/null @@ -1,281 +0,0 @@ -/************************************************************************** -* -* Copyright (C) 2009 Steve Karg -* Multimedia Timer contribution by Cameron Crothers, 2008 -* -* Permission is hereby granted, free of charge, to any person obtaining -* a copy of this software and associated documentation files (the -* "Software"), to deal in the Software without restriction, including -* without limitation the rights to use, copy, modify, merge, publish, -* distribute, sublicense, and/or sell copies of the Software, and to -* permit persons to whom the Software is furnished to do so, subject to -* the following conditions: -* -* The above copyright notice and this permission notice shall be included -* in all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -* -*********************************************************************/ -#include -#include -#include -#include -#include -#define WIN32_LEAN_AND_MEAN -#define STRICT 1 -#include -#include "net.h" -#include -#include "timer.h" - -/* Offset between Windows epoch 1/1/1601 and - Unix epoch 1/1/1970 in 100 nanosec units */ -#if defined(_MSC_VER) || defined(_MSC_EXTENSIONS) || defined(__BORLANDC__) -#define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64 -#else -#define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL -#endif - -/* counter for the various timers */ -static volatile uint32_t Millisecond_Counter[MAX_MILLISECOND_TIMERS]; - -/* Windows timer period - in milliseconds */ -static uint32_t Timer_Period = 1; - -#if defined(_MSC_VER) || defined(__BORLANDC__) -struct timezone { - int tz_minuteswest; /* minutes W of Greenwich */ - int tz_dsttime; /* type of dst correction */ -}; - -/************************************************************************* -* Description: simulate the gettimeofday Linux function -* Returns: zero -* Note: The resolution of GetSystemTimeAsFileTime() is 15625 microseconds. -* The resolution of _ftime() is about 16 milliseconds. -* To get microseconds accuracy we need to use QueryPerformanceCounter or -* timeGetTime for the elapsed time. -*************************************************************************/ - -int gettimeofday( - struct timeval *tp, - void *tzp) -{ - static int tzflag = 0; - struct timezone *tz; - /* start calendar time in microseconds */ - static LONGLONG usec_timer = 0; - LONGLONG usec_elapsed = 0; - /* elapsed time in milliseconds */ - static uint32_t time_start = 0; - /* semi-accurate time from File Timer */ - FILETIME ft; - uint32_t elapsed_milliseconds = 0; - - tzp = tzp; - if (usec_timer == 0) { - /* a 64-bit value representing the number of - 100-nanosecond intervals since January 1, 1601 (UTC). */ - GetSystemTimeAsFileTime(&ft); - usec_timer = ft.dwHighDateTime; - usec_timer <<= 32; - usec_timer |= ft.dwLowDateTime; - /*converting file time to unix epoch 1970 */ - usec_timer /= 10; /*convert into microseconds */ - usec_timer -= DELTA_EPOCH_IN_MICROSECS; - tp->tv_sec = (long) (usec_timer / 1000000UL); - tp->tv_usec = (long) (usec_timer % 1000000UL); - time_start = timeGetTime(); - } else { - elapsed_milliseconds = timeGetTime() - time_start; - usec_elapsed = usec_timer + ((LONGLONG) elapsed_milliseconds * 1000UL); - tp->tv_sec = (long) (usec_elapsed / 1000000UL); - tp->tv_usec = (long) (usec_elapsed % 1000000UL); - } - if (tzp) { - if (!tzflag) { - _tzset(); - tzflag++; - } - tz = tzp; - tz->tz_minuteswest = _timezone / 60; - tz->tz_dsttime = _daylight; - } - - return 0; -} -#endif - -/************************************************************************* -* Description: returns the current millisecond count -* Returns: none -* Notes: none -*************************************************************************/ -uint32_t timer_milliseconds( - unsigned index) -{ - uint32_t now = timeGetTime(); - uint32_t delta_time = 0; - - - if (index < MAX_MILLISECOND_TIMERS) { - if (Millisecond_Counter[index] <= now) { - delta_time = now - Millisecond_Counter[index]; - } else { - delta_time = (UINT32_MAX - Millisecond_Counter[index]) + now + 1; - } - } - - return delta_time; -} - -/************************************************************************* -* Description: compares the current time count with a value -* Returns: true if the time has elapsed -* Notes: none -*************************************************************************/ -bool timer_elapsed_milliseconds( - unsigned index, - uint32_t value) -{ - return (timer_milliseconds(index) >= value); -} - -/************************************************************************* -* Description: compares the current time count with a value -* Returns: true if the time has elapsed -* Notes: none -*************************************************************************/ -bool timer_elapsed_seconds( - unsigned index, - uint32_t seconds) -{ - return ((timer_milliseconds(index) / 1000) >= seconds); -} - -/************************************************************************* -* Description: compares the current time count with a value -* Returns: true if the time has elapsed -* Notes: none -*************************************************************************/ -bool timer_elapsed_minutes( - unsigned index, - uint32_t minutes) -{ - return ((timer_milliseconds(index) / (1000 * 60)) >= minutes); -} - -/************************************************************************* -* Description: Sets the timer counter to zero. -* Returns: none -* Notes: none -*************************************************************************/ -uint32_t timer_reset( - unsigned index) -{ - uint32_t timer_value = timer_milliseconds(index); - if (index < MAX_MILLISECOND_TIMERS) { - Millisecond_Counter[index] = timeGetTime(); - } - return timer_value; -} - -/************************************************************************* -* Description: Shut down for timer -* Returns: none -* Notes: none -*************************************************************************/ -static void timer_cleanup( - void) -{ - timeEndPeriod(Timer_Period); -} - -/************************************************************************* -* Description: Initialization for timer -* Returns: none -* Notes: none -*************************************************************************/ -void timer_init( - void) -{ - TIMECAPS tc; - - /* set timer resolution */ - if (timeGetDevCaps(&tc, sizeof(TIMECAPS)) != TIMERR_NOERROR) { - fprintf(stderr, "Failed to get timer resolution parameters\n"); - } - /* configure for 1ms resolution - if possible */ - Timer_Period = min(max(tc.wPeriodMin, 1L), tc.wPeriodMax); - if (Timer_Period != 1L) { - fprintf(stderr, - "Failed to set timer to 1ms. " "Time period set to %ums\n", - (unsigned) Timer_Period); - } - timeBeginPeriod(Timer_Period); - atexit(timer_cleanup); -} - -#ifdef TEST_TIMER_WIN -static uint32_t timeval_diff_ms( - struct timeval *old, - struct timeval *now) -{ - uint32_t ms = 0; - - /* convert to milliseconds */ - ms = (now->tv_sec - old->tv_sec) * 1000 + (now->tv_usec - - old->tv_usec) / 1000; - - return ms; -} - -int main( - int argc, - char *argv[]) -{ - long now = 0, last = 0, delta = 0; - struct timeval tv; - struct timeval old_tv = { 0 }; - - timer_init(); - printf("Testing granularity of timeGetTime()...\n"); - timer_reset(0); - for (;;) { - now = timeGetTime(); - delta = now - last; - if (delta) { - if (delta > 1) { - printf("Delta is %ld.\n", delta); - } - last = now; - } - if (timer_elapsed_milliseconds(0, 5000)) { - break; - } - } - printf("Testing granularity of gettimeofday()...\n"); - for (;;) { - gettimeofday(&tv, NULL); - delta = timeval_diff_ms(&old_tv, &tv); - if (delta) { - if (delta > 1) { - printf("Delta is %ld.\n", delta); - } - old_tv.tv_sec = tv.tv_sec; - old_tv.tv_usec = tv.tv_usec; - } - if (timer_elapsed_milliseconds(0, 10000)) { - break; - } - } - -} -#endif diff --git a/ports/xplained/ai.c b/ports/xplained/ai.c index e5ad4935..0671e3af 100644 --- a/ports/xplained/ai.c +++ b/ports/xplained/ai.c @@ -28,12 +28,12 @@ #include #include #include -#include "bacdef.h" -#include "bacdcode.h" -#include "bacenum.h" -#include "config.h" -#include "ai.h" -#include "handlers.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacenum.h" +#include "bacnet/config.h" +#include "bacnet/basic/object/ai.h" +#include "bacnet/basic/services.h" #ifndef MAX_ANALOG_INPUTS #define MAX_ANALOG_INPUTS 2 diff --git a/ports/xplained/bacnet.c b/ports/xplained/bacnet.c index 92d6a2d4..ed543d29 100644 --- a/ports/xplained/bacnet.c +++ b/ports/xplained/bacnet.c @@ -32,19 +32,19 @@ #include "led.h" #include "adc-hdw.h" /* BACnet Stack includes */ -#include "datalink.h" -#include "npdu.h" -#include "handlers.h" -#include "client.h" -#include "txbuf.h" -#include "dcc.h" -#include "iam.h" -#include "timer.h" -#include "tsm.h" -#include "ringbuf.h" +#include "bacnet/npdu.h" +#include "bacnet/dcc.h" +#include "bacnet/iam.h" +#include "bacnet/datalink/datalink.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/basic/sys/mstimer.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/basic/sys/ringbuf.h" /* BACnet objects */ -#include "device.h" -#include "ai.h" +#include "bacnet/basic/object/device.h" +#include "bacnet/basic/object/ai.h" /* me */ #include "bacnet.h" @@ -63,16 +63,16 @@ static RING_BUFFER Receive_Queue; /* Device ID to track changes */ static uint32_t Device_ID = 0xFFFFFFFF; /* timer for device communications control */ -static struct itimer DCC_Timer; +static struct mstimer DCC_Timer; #define DCC_CYCLE_SECONDS 1 /* timer for COV */ -static struct itimer COV_Timer; +static struct mstimer COV_Timer; #define COV_CYCLE_SECONDS 1 /* timer for TSM */ -static struct itimer TSM_Timer; +static struct mstimer TSM_Timer; #define TSM_CYCLE_SECONDS 1 /* timer for Reinit */ -static struct itimer Reinit_Timer; +static struct mstimer Reinit_Timer; /* buffer for incoming packets */ static uint8_t PDUBuffer[MAX_MPDU]; @@ -88,14 +88,14 @@ static void reinit_task(void) state = Device_Reinitialized_State(); if (state == BACNET_REINIT_IDLE) { /* set timer to never expire */ - timer_interval_infinity(&Reinit_Timer); - } else if (timer_interval_active(&Reinit_Timer)) { - if (timer_interval_expired(&Reinit_Timer)) { + mstimer_set(&Reinit_Timer, 0); + } else if (mstimer_interval(&Reinit_Timer) > 0) { + if (mstimer_expired(&Reinit_Timer)) { /* reset MCU via watchdog timeout */ wdt_reset_mcu(); } } else { - timer_interval_start_seconds(&Reinit_Timer, 3); + mstimer_set(&Reinit_Timer, 3000); } } @@ -164,14 +164,14 @@ void bacnet_task(void) Send_I_Am(&Handler_Transmit_Buffer[0]); } /* handle the timers */ - if (timer_interval_expired(&DCC_Timer)) { - timer_interval_reset(&DCC_Timer); + if (mstimer_expired(&DCC_Timer)) { + mstimer_reset(&DCC_Timer); dcc_timer_seconds(DCC_CYCLE_SECONDS); led_on_interval(LED_DEBUG,500); } - if (timer_interval_expired(&TSM_Timer)) { - timer_interval_reset(&TSM_Timer); - tsm_timer_milliseconds(timer_interval(&TSM_Timer)); + if (mstimer_expired(&TSM_Timer)) { + mstimer_reset(&TSM_Timer); + tsm_timer_milliseconds(mstimer_interval(&TSM_Timer)); } reinit_task(); bacnet_test_task(); @@ -221,11 +221,11 @@ void bacnet_init(void) apdu_set_confirmed_handler(SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL, handler_device_communication_control); /* start the cyclic 1 second timer for DCC */ - timer_interval_start_seconds(&DCC_Timer, DCC_CYCLE_SECONDS); + mstimer_set(&DCC_Timer, DCC_CYCLE_SECONDS*1000); /* start the cyclic 1 second timer for COV */ - timer_interval_start_seconds(&COV_Timer, COV_CYCLE_SECONDS); + mstimer_set(&COV_Timer, COV_CYCLE_SECONDS*1000); /* start the cyclic 1 second timer for TSM */ - timer_interval_start_seconds(&TSM_Timer, TSM_CYCLE_SECONDS); + mstimer_set(&TSM_Timer, TSM_CYCLE_SECONDS*1000); for (i = 0; i < MAX_ANALOG_INPUTS; i++) { Analog_Input_Units_Set( Analog_Input_Index_To_Instance(i), diff --git a/ports/xplained/bacnet.cproj b/ports/xplained/bacnet.cproj index 75591199..c0d840b1 100644 --- a/ports/xplained/bacnet.cproj +++ b/ports/xplained/bacnet.cproj @@ -27,144 +27,144 @@ 2 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + com.atmel.avrdbg.tool.jtagice3plus JTAG @@ -209,328 +209,328 @@ J30200019449 JTAGICE3 + 0 + - -mmcu=atxmega256a3bu -B "%24(PackRepoDir)\atmel\XMEGAA_DFP\1.0.36\gcc\dev\atxmega256a3bu" - True - True - True - True - True - False - - - IOPORT_XMEGA_COMPAT - BACDL_MSTP - MAX_APDU=128 - MAX_TSM_TRANSACTIONS=1 - MSTP_PDU_PACKET_COUNT=2 - BACNET_VENDOR_ID=293 - MAX_ADDRESS_CACHE=32 - MAX_ANALOG_INPUTS=8 - BOARD=XMEGA_A3BU_XPLAINED - NDEBUG - - - - - .. - ../config - ../ASF/xmega/drivers/rtc32 - ../ASF/xmega/drivers/pmic - ../ASF/xmega/boards/xmega_a3bu_xplained - ../ASF/xmega/utils/preprocessor - ../ASF/common/utils - ../ASF/common/services/sleepmgr - ../ASF/xmega/drivers/sleep - ../ASF/common/services/gpio - ../ASF/xmega/drivers/tc - ../ASF/xmega/drivers/adc - ../ASF/xmega/drivers/cpu - ../ASF/common/boards - ../ASF/common/services/ioport - ../ASF/xmega/drivers/nvm - ../ASF/xmega/boards - ../ASF/xmega/utils - ../ASF/xmega/drivers/wdt - ../ASF/common/services/clock - ../ASF/common/services/delay - ../ASF/xmega/drivers/usart - ../ASF/xmega/services/pwm - ../ASF/common/drivers/nvm - ../ASF/common/services/serial/xmega_usart - ../ASF/common/services/serial - ../ASF/common/utils/stdio/stdio_serial - ../ASF/xmega/services/timeout - ../../../include - ../../../demo/object - %24(PackRepoDir)\atmel\XMEGAA_DFP\1.0.36\include - - - Optimize for size (-Os) - -fdata-sections - True - True - True - -std=gnu99 -fno-strict-aliasing -Wstrict-prototypes -Wmissing-prototypes -Werror-implicit-function-declaration -Wpointer-arith -mrelax - - - libm - - - -Wl,--relax -Wl,--section-start=.BOOT=0x40000 - -mrelax -DBOARD=XMEGA_A3BU_XPLAINED -DIOPORT_XMEGA_COMPAT - - - ../ASF/xmega/drivers/rtc32 - ../ASF/xmega/drivers/pmic - ../ASF/xmega/boards/xmega_a3bu_xplained - ../ASF/xmega/drivers/nvm - ../ASF/xmega/utils/preprocessor - ../ASF/common/utils - ../ASF/common/services/sleepmgr - ../ASF/xmega/drivers/sleep - ../ASF/common/services/gpio - ../ASF/xmega/drivers/tc - ../ASF/xmega/drivers/adc - ../ASF/xmega/drivers/cpu - ../ASF/common/boards - ../ASF/common/services/ioport - ../ASF/xmega/boards - ../ASF/xmega/utils - ../ASF/common/services/clock - ../ASF/common/services/delay - ../ASF/xmega/drivers/wdt - ../ASF/xmega/drivers/usart - ../config - . - ../ASF/xmega/services/pwm - ../ASF/common/drivers/nvm - ../ASF/common/services/serial/xmega_usart - ../ASF/common/services/serial - ../ASF/common/utils/stdio/stdio_serial - ../ASF/xmega/services/timeout - - - + -mmcu=atxmega256a3bu -B "%24(PackRepoDir)\atmel\XMEGAA_DFP\1.0.36\gcc\dev\atxmega256a3bu" + True + True + True + True + True + False + + + IOPORT_XMEGA_COMPAT + BACDL_MSTP + MAX_APDU=128 + MAX_TSM_TRANSACTIONS=1 + MSTP_PDU_PACKET_COUNT=2 + MAX_ADDRESS_CACHE=32 + MAX_ANALOG_INPUTS=8 + BACNET_PROTOCOL_REVISION=9 + BOARD=XMEGA_A3BU_XPLAINED + NDEBUG + + + + + .. + ../config + ../ASF/xmega/drivers/rtc32 + ../ASF/xmega/drivers/pmic + ../ASF/xmega/boards/xmega_a3bu_xplained + ../ASF/xmega/utils/preprocessor + ../ASF/common/utils + ../ASF/common/services/sleepmgr + ../ASF/xmega/drivers/sleep + ../ASF/common/services/gpio + ../ASF/xmega/drivers/tc + ../ASF/xmega/drivers/adc + ../ASF/xmega/drivers/cpu + ../ASF/common/boards + ../ASF/common/services/ioport + ../ASF/xmega/drivers/nvm + ../ASF/xmega/boards + ../ASF/xmega/utils + ../ASF/xmega/drivers/wdt + ../ASF/common/services/clock + ../ASF/common/services/delay + ../ASF/xmega/drivers/usart + ../ASF/xmega/services/pwm + ../ASF/common/drivers/nvm + ../ASF/common/services/serial/xmega_usart + ../ASF/common/services/serial + ../ASF/common/utils/stdio/stdio_serial + ../ASF/xmega/services/timeout + ../../../src + %24(PackRepoDir)\atmel\XMEGAA_DFP\1.0.36\include + + + -fdata-sections + True + True + True + -std=gnu99 -fno-strict-aliasing -Wstrict-prototypes -Wmissing-prototypes -Werror-implicit-function-declaration -Wpointer-arith -mrelax + + + libm + + + -Wl,--relax -Wl,--section-start=.BOOT=0x40000 + -mrelax -DBOARD=XMEGA_A3BU_XPLAINED -DIOPORT_XMEGA_COMPAT + + + ../ASF/xmega/drivers/rtc32 + ../ASF/xmega/drivers/pmic + ../ASF/xmega/boards/xmega_a3bu_xplained + ../ASF/xmega/drivers/nvm + ../ASF/xmega/utils/preprocessor + ../ASF/common/utils + ../ASF/common/services/sleepmgr + ../ASF/xmega/drivers/sleep + ../ASF/common/services/gpio + ../ASF/xmega/drivers/tc + ../ASF/xmega/drivers/adc + ../ASF/xmega/drivers/cpu + ../ASF/common/boards + ../ASF/common/services/ioport + ../ASF/xmega/boards + ../ASF/xmega/utils + ../ASF/common/services/clock + ../ASF/common/services/delay + ../ASF/xmega/drivers/wdt + ../ASF/xmega/drivers/usart + ../config + . + ../ASF/xmega/services/pwm + ../ASF/common/drivers/nvm + ../ASF/common/services/serial/xmega_usart + ../ASF/common/services/serial + ../ASF/common/utils/stdio/stdio_serial + ../ASF/xmega/services/timeout + + + Optimize for size (-Os) + - -mmcu=atxmega256a3bu -B "%24(PackRepoDir)\atmel\XMEGAA_DFP\1.0.36\gcc\dev\atxmega256a3bu" - True - True - True - True - True - False - - - IOPORT_XMEGA_COMPAT - BACDL_MSTP - MAX_APDU=128 - MAX_TSM_TRANSACTIONS=1 - MSTP_PDU_PACKET_COUNT=2 - BACNET_VENDOR_ID=293 - MAX_ADDRESS_CACHE=32 - MAX_ANALOG_INPUTS=8 - DEBUG - - - - - .. - ../config - ../ASF/xmega/drivers/rtc32 - ../ASF/xmega/drivers/pmic - ../ASF/xmega/boards/xmega_a3bu_xplained - ../ASF/xmega/utils/preprocessor - ../ASF/common/utils - ../ASF/common/services/sleepmgr - ../ASF/xmega/drivers/sleep - ../ASF/common/services/gpio - ../ASF/xmega/drivers/tc - ../ASF/xmega/drivers/adc - ../ASF/xmega/drivers/cpu - ../ASF/common/boards - ../ASF/common/services/ioport - ../ASF/xmega/drivers/nvm - ../ASF/xmega/boards - ../ASF/xmega/utils - ../ASF/xmega/drivers/wdt - ../ASF/common/services/clock - ../ASF/common/services/delay - ../ASF/xmega/drivers/usart - ../ASF/xmega/services/pwm - ../ASF/common/drivers/nvm - ../ASF/common/services/serial/xmega_usart - ../ASF/common/services/serial - ../ASF/common/utils/stdio/stdio_serial - ../ASF/xmega/services/timeout - ../../../include - ../../../demo/object - %24(PackRepoDir)\atmel\XMEGAA_DFP\1.0.36\include - - - -fdata-sections - True - True - Maximum (-g3) - True - -std=gnu99 -fno-strict-aliasing -Wstrict-prototypes -Wmissing-prototypes -Werror-implicit-function-declaration -Wpointer-arith -mrelax - - - libm - - - -Wl,--relax -Wl,--section-start=.BOOT=0x40000 - -mrelax -DBOARD=XMEGA_A3BU_XPLAINED -DIOPORT_XMEGA_COMPAT - - - ../ASF/xmega/drivers/rtc32 - ../ASF/xmega/drivers/pmic - ../ASF/xmega/boards/xmega_a3bu_xplained - ../ASF/xmega/drivers/nvm - ../ASF/xmega/utils/preprocessor - ../ASF/common/utils - ../ASF/common/services/sleepmgr - ../ASF/xmega/drivers/sleep - ../ASF/common/services/gpio - ../ASF/xmega/drivers/tc - ../ASF/xmega/drivers/adc - ../ASF/xmega/drivers/cpu - ../ASF/common/boards - ../ASF/common/services/ioport - ../ASF/xmega/boards - ../ASF/xmega/utils - ../ASF/common/services/clock - ../ASF/common/services/delay - ../ASF/xmega/drivers/wdt - ../ASF/xmega/drivers/usart - ../config - . - ../ASF/xmega/services/pwm - ../ASF/common/drivers/nvm - ../ASF/common/services/serial/xmega_usart - ../ASF/common/services/serial - ../ASF/common/utils/stdio/stdio_serial - ../ASF/xmega/services/timeout - - - Default (-Wa,-g) - + -mmcu=atxmega256a3bu -B "%24(PackRepoDir)\atmel\XMEGAA_DFP\1.0.36\gcc\dev\atxmega256a3bu" + True + True + True + True + True + False + + + IOPORT_XMEGA_COMPAT + BACDL_MSTP + MAX_APDU=128 + MAX_TSM_TRANSACTIONS=1 + MSTP_PDU_PACKET_COUNT=2 + MAX_ADDRESS_CACHE=32 + MAX_ANALOG_INPUTS=8 + BACNET_PROTOCOL_REVISION=9 + DEBUG + + + + + .. + ../config + ../ASF/xmega/drivers/rtc32 + ../ASF/xmega/drivers/pmic + ../ASF/xmega/boards/xmega_a3bu_xplained + ../ASF/xmega/utils/preprocessor + ../ASF/common/utils + ../ASF/common/services/sleepmgr + ../ASF/xmega/drivers/sleep + ../ASF/common/services/gpio + ../ASF/xmega/drivers/tc + ../ASF/xmega/drivers/adc + ../ASF/xmega/drivers/cpu + ../ASF/common/boards + ../ASF/common/services/ioport + ../ASF/xmega/drivers/nvm + ../ASF/xmega/boards + ../ASF/xmega/utils + ../ASF/xmega/drivers/wdt + ../ASF/common/services/clock + ../ASF/common/services/delay + ../ASF/xmega/drivers/usart + ../ASF/xmega/services/pwm + ../ASF/common/drivers/nvm + ../ASF/common/services/serial/xmega_usart + ../ASF/common/services/serial + ../ASF/common/utils/stdio/stdio_serial + ../ASF/xmega/services/timeout + ../../../src + %24(PackRepoDir)\atmel\XMEGAA_DFP\1.0.36\include + + + -fdata-sections + True + True + True + -std=gnu99 -fno-strict-aliasing -Wstrict-prototypes -Wmissing-prototypes -Werror-implicit-function-declaration -Wpointer-arith -mrelax + + + libm + + + -Wl,--relax -Wl,--section-start=.BOOT=0x40000 + -mrelax -DBOARD=XMEGA_A3BU_XPLAINED -DIOPORT_XMEGA_COMPAT + + + ../ASF/xmega/drivers/rtc32 + ../ASF/xmega/drivers/pmic + ../ASF/xmega/boards/xmega_a3bu_xplained + ../ASF/xmega/drivers/nvm + ../ASF/xmega/utils/preprocessor + ../ASF/common/utils + ../ASF/common/services/sleepmgr + ../ASF/xmega/drivers/sleep + ../ASF/common/services/gpio + ../ASF/xmega/drivers/tc + ../ASF/xmega/drivers/adc + ../ASF/xmega/drivers/cpu + ../ASF/common/boards + ../ASF/common/services/ioport + ../ASF/xmega/boards + ../ASF/xmega/utils + ../ASF/common/services/clock + ../ASF/common/services/delay + ../ASF/xmega/drivers/wdt + ../ASF/xmega/drivers/usart + ../config + . + ../ASF/xmega/services/pwm + ../ASF/common/drivers/nvm + ../ASF/common/services/serial/xmega_usart + ../ASF/common/services/serial + ../ASF/common/utils/stdio/stdio_serial + ../ASF/xmega/services/timeout + + + Maximum (-g3) + Default (-Wa,-g) + bin\Debug-XPLAINED\ - -mmcu=atxmega256a3bu -B "%24(PackRepoDir)\atmel\XMEGAA_DFP\1.0.36\gcc\dev\atxmega256a3bu" - True - True - True - True - False - - - IOPORT_XMEGA_COMPAT - BACDL_MSTP - MAX_APDU=128 - MAX_TSM_TRANSACTIONS=1 - MSTP_PDU_PACKET_COUNT=2 - BACNET_VENDOR_ID=293 - MAX_ADDRESS_CACHE=32 - MAX_ANALOG_INPUTS=8 - BOARD=XMEGA_A3BU_XPLAINED - CONF_BOARD_ENABLE_RS485_XPLAINED - DEBUG - - - - - .. - ../config - ../ASF/xmega/drivers/rtc32 - ../ASF/xmega/drivers/pmic - ../ASF/xmega/boards/xmega_a3bu_xplained - ../ASF/xmega/utils/preprocessor - ../ASF/common/utils - ../ASF/common/services/sleepmgr - ../ASF/xmega/drivers/sleep - ../ASF/common/services/gpio - ../ASF/xmega/drivers/tc - ../ASF/xmega/drivers/adc - ../ASF/xmega/drivers/cpu - ../ASF/common/boards - ../ASF/common/services/ioport - ../ASF/xmega/drivers/nvm - ../ASF/xmega/boards - ../ASF/xmega/utils - ../ASF/xmega/drivers/wdt - ../ASF/common/services/clock - ../ASF/common/services/delay - ../ASF/xmega/drivers/usart - ../ASF/xmega/services/pwm - ../ASF/common/drivers/nvm - ../ASF/common/services/serial/xmega_usart - ../ASF/common/services/serial - ../ASF/common/utils/stdio/stdio_serial - ../ASF/xmega/services/timeout - ../../../include - ../../../demo/object - %24(PackRepoDir)\atmel\XMEGAA_DFP\1.0.36\include - - - -fdata-sections - True - True - Maximum (-g3) - True - -std=gnu99 -fno-strict-aliasing -Wstrict-prototypes -Wmissing-prototypes -Werror-implicit-function-declaration -Wpointer-arith -mrelax - - - libm - - - -Wl,--relax -Wl,--section-start=.BOOT=0x40000 - -mrelax -DBOARD=XMEGA_A3BU_XPLAINED -DIOPORT_XMEGA_COMPAT - - - ../ASF/xmega/drivers/rtc32 - ../ASF/xmega/drivers/pmic - ../ASF/xmega/boards/xmega_a3bu_xplained - ../ASF/xmega/drivers/nvm - ../ASF/xmega/utils/preprocessor - ../ASF/common/utils - ../ASF/common/services/sleepmgr - ../ASF/xmega/drivers/sleep - ../ASF/common/services/gpio - ../ASF/xmega/drivers/tc - ../ASF/xmega/drivers/adc - ../ASF/xmega/drivers/cpu - ../ASF/common/boards - ../ASF/common/services/ioport - ../ASF/xmega/boards - ../ASF/xmega/utils - ../ASF/common/services/clock - ../ASF/common/services/delay - ../ASF/xmega/drivers/wdt - ../ASF/xmega/drivers/usart - ../config - . - ../ASF/xmega/services/pwm - ../ASF/common/drivers/nvm - ../ASF/common/services/serial/xmega_usart - ../ASF/common/services/serial - ../ASF/common/utils/stdio/stdio_serial - ../ASF/xmega/services/timeout - - - Default (-Wa,-g) - + -mmcu=atxmega256a3bu -B "%24(PackRepoDir)\atmel\XMEGAA_DFP\1.0.36\gcc\dev\atxmega256a3bu" + False + True + True + True + True + False + + + IOPORT_XMEGA_COMPAT + BACDL_MSTP + MAX_APDU=128 + MAX_TSM_TRANSACTIONS=1 + MSTP_PDU_PACKET_COUNT=2 + MAX_ADDRESS_CACHE=32 + MAX_ANALOG_INPUTS=8 + BACNET_PROTOCOL_REVISION=9 + BOARD=XMEGA_A3BU_XPLAINED + CONF_BOARD_ENABLE_RS485_XPLAINED + DEBUG + + + + + .. + ../config + ../ASF/xmega/drivers/rtc32 + ../ASF/xmega/drivers/pmic + ../ASF/xmega/boards/xmega_a3bu_xplained + ../ASF/xmega/utils/preprocessor + ../ASF/common/utils + ../ASF/common/services/sleepmgr + ../ASF/xmega/drivers/sleep + ../ASF/common/services/gpio + ../ASF/xmega/drivers/tc + ../ASF/xmega/drivers/adc + ../ASF/xmega/drivers/cpu + ../ASF/common/boards + ../ASF/common/services/ioport + ../ASF/xmega/drivers/nvm + ../ASF/xmega/boards + ../ASF/xmega/utils + ../ASF/xmega/drivers/wdt + ../ASF/common/services/clock + ../ASF/common/services/delay + ../ASF/xmega/drivers/usart + ../ASF/xmega/services/pwm + ../ASF/common/drivers/nvm + ../ASF/common/services/serial/xmega_usart + ../ASF/common/services/serial + ../ASF/common/utils/stdio/stdio_serial + ../ASF/xmega/services/timeout + ../../../src + %24(PackRepoDir)\atmel\XMEGAA_DFP\1.0.36\include + + + -fdata-sections + True + True + True + -std=gnu99 -fno-strict-aliasing -Wstrict-prototypes -Wmissing-prototypes -Werror-implicit-function-declaration -Wpointer-arith -mrelax + + + libm + + + -Wl,--relax -Wl,--section-start=.BOOT=0x40000 + -mrelax -DBOARD=XMEGA_A3BU_XPLAINED -DIOPORT_XMEGA_COMPAT + + + ../ASF/xmega/drivers/rtc32 + ../ASF/xmega/drivers/pmic + ../ASF/xmega/boards/xmega_a3bu_xplained + ../ASF/xmega/drivers/nvm + ../ASF/xmega/utils/preprocessor + ../ASF/common/utils + ../ASF/common/services/sleepmgr + ../ASF/xmega/drivers/sleep + ../ASF/common/services/gpio + ../ASF/xmega/drivers/tc + ../ASF/xmega/drivers/adc + ../ASF/xmega/drivers/cpu + ../ASF/common/boards + ../ASF/common/services/ioport + ../ASF/xmega/boards + ../ASF/xmega/utils + ../ASF/common/services/clock + ../ASF/common/services/delay + ../ASF/xmega/drivers/wdt + ../ASF/xmega/drivers/usart + ../config + . + ../ASF/xmega/services/pwm + ../ASF/common/drivers/nvm + ../ASF/common/services/serial/xmega_usart + ../ASF/common/services/serial + ../ASF/common/utils/stdio/stdio_serial + ../ASF/xmega/services/timeout + + + Maximum (-g3) + Default (-Wa,-g) + @@ -586,11 +586,11 @@ compile - + compile bacnet-stack\lighting.c - + compile bacnet-stack\proplist.c @@ -654,27 +654,27 @@ compile - + compile bacnet-stack\s_cov.c - + compile bacnet-stack\s_rp.c - + compile bacnet-stack\s_whois.c - + compile bacnet-stack\s_wp.c - + compile bacnet-stack\cov.c - + compile bacnet-stack\tsm.c @@ -701,151 +701,147 @@ - + compile bacnet-stack\h_dcc.c - + compile bacnet-stack\h_npdu.c - + compile bacnet-stack\h_rd.c - + compile bacnet-stack\h_rp.c - + compile bacnet-stack\h_rpm.c - + compile bacnet-stack\h_whohas.c - + compile bacnet-stack\h_whois.c - + compile bacnet-stack\h_wp.c - + compile - bacnet-stack\noserv.c + bacnet-stack\h_noserv.c - + compile bacnet-stack\s_iam.c - + compile bacnet-stack\s_ihave.c - - compile - bacnet-stack\txbuf.c - - + compile bacnet-stack\abort.c - + compile - bacnet-stack\apdu.c + bacnet-stack\h_apdu.c - + compile bacnet-stack\bacaddr.c - + compile bacnet-stack\bacapp.c - + compile bacnet-stack\bacdcode.c - + compile bacnet-stack\bacerror.c - + compile bacnet-stack\bacint.c - + compile bacnet-stack\bacreal.c - + compile bacnet-stack\bacstr.c - + compile bacnet-stack\crc.c - + compile bacnet-stack\dcc.c - + compile bacnet-stack\fifo.c - + compile bacnet-stack\iam.c - + compile bacnet-stack\ihave.c - + compile bacnet-stack\memcopy.c - + + compile + bacnet-stack\mstimer.c + + compile bacnet-stack\npdu.c - + compile bacnet-stack\rd.c - + compile bacnet-stack\reject.c - + compile bacnet-stack\ringbuf.c - + compile bacnet-stack\rp.c - + compile bacnet-stack\rpm.c - - compile - bacnet-stack\version.c - - + compile bacnet-stack\whohas.c - + compile bacnet-stack\whois.c - + compile bacnet-stack\wp.c @@ -1029,10 +1025,7 @@ compile - - compile - - + compile diff --git a/ports/xplained/bname.c b/ports/xplained/bname.c index 8f767748..f27d3110 100644 --- a/ports/xplained/bname.c +++ b/ports/xplained/bname.c @@ -26,11 +26,11 @@ #include #include #include -#include "bacdef.h" -#include "bacdcode.h" -#include "bacstr.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacstr.h" #include "nvmdata.h" -#include "device.h" +#include "bacnet/basic/object/device.h" #include "bname.h" /************************************************************************* diff --git a/ports/xplained/bname.h b/ports/xplained/bname.h index 08dedf2e..70ae63ec 100644 --- a/ports/xplained/bname.h +++ b/ports/xplained/bname.h @@ -25,7 +25,7 @@ #define BACNET_NAME_H #include -#include "bacstr.h" +#include "bacnet/bacstr.h" #ifdef __cplusplus extern "C" { diff --git a/ports/xplained/device.c b/ports/xplained/device.c index 9f6a066a..04d43be9 100644 --- a/ports/xplained/device.c +++ b/ports/xplained/device.c @@ -26,23 +26,23 @@ #include #include #include -#include "bacdef.h" -#include "bacdcode.h" -#include "bacstr.h" -#include "bacenum.h" -#include "apdu.h" -#include "dcc.h" -#include "datalink.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacstr.h" +#include "bacnet/bacenum.h" +#include "bacnet/apdu.h" +#include "bacnet/dcc.h" +#include "bacnet/datalink/datalink.h" #include "rs485.h" -#include "version.h" +#include "bacnet/version.h" #include "nvmdata.h" -#include "handlers.h" +#include "bacnet/basic/services.h" #include "bname.h" #include "stack.h" #include "nvmdata.h" /* objects */ -#include "device.h" -#include "ai.h" +#include "bacnet/basic/object/device.h" +#include "bacnet/basic/object/ai.h" /* forward prototype */ int Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA * rpdata); diff --git a/ports/xplained/dlmstp.c b/ports/xplained/dlmstp.c index 894f7b92..c56152c7 100644 --- a/ports/xplained/dlmstp.c +++ b/ports/xplained/dlmstp.c @@ -36,17 +36,17 @@ #include #include #include -#include "bacdef.h" -#include "dlmstp.h" -#include "mstpdef.h" +#include "bacnet/bacdef.h" +#include "bacnet/datalink/dlmstp.h" +#include "bacnet/datalink/mstpdef.h" #include "rs485.h" -#include "crc.h" -#include "npdu.h" -#include "bits.h" -#include "bytes.h" -#include "bacaddr.h" -#include "ringbuf.h" -#include "timer.h" +#include "bacnet/datalink/crc.h" +#include "bacnet/npdu.h" +#include "bacnet/bits.h" +#include "bacnet/bytes.h" +#include "bacnet/bacaddr.h" +#include "bacnet/basic/sys/ringbuf.h" +#include "bacnet/basic/sys/mstimer.h" /* This file has been customized for use with small microprocessors */ /* Assumptions: diff --git a/ports/xplained/led.c b/ports/xplained/led.c index 39ceb079..39d1bb5a 100644 --- a/ports/xplained/led.c +++ b/ports/xplained/led.c @@ -24,7 +24,7 @@ #include #include "board.h" #include "ioport.h" -#include "timer.h" +#include "bacnet/basic/sys/mstimer.h" #include "led.h" #ifdef CONF_BOARD_ENABLE_RS485_XPLAINED diff --git a/ports/xplained/main.c b/ports/xplained/main.c index 55e63269..2a18f4b8 100644 --- a/ports/xplained/main.c +++ b/ports/xplained/main.c @@ -5,13 +5,15 @@ * */ #include -#include "timer.h" +#include "bacnet/basic/sys/mstimer.h" #include "rs485.h" #include "led.h" #include "adc-hdw.h" -#include "dlmstp.h" +#include "bacnet/datalink/dlmstp.h" #include "bacnet.h" +static struct mstimer_callback_data_t BACnet_Callback; + /** * \brief Main function. * @@ -23,7 +25,7 @@ int main(void) sysclk_init(); board_init(); pmic_init(); - timer_init(); + mstimer_init(); rs485_init(); led_init(); adc_init(); @@ -41,7 +43,7 @@ int main(void) rs485_baud_rate_set(38400); bacnet_init(); /* run forever - timed tasks */ - timer_callback(bacnet_task_timed, 5); + mstimer_callback(&BACnet_Callback, bacnet_task_timed, 5); for (;;) { bacnet_task(); led_task(); diff --git a/ports/xplained/timer1.c b/ports/xplained/mstimer-init.c similarity index 52% rename from ports/xplained/timer1.c rename to ports/xplained/mstimer-init.c index 39a73bb7..e164c9c4 100644 --- a/ports/xplained/timer1.c +++ b/ports/xplained/mstimer-init.c @@ -33,52 +33,34 @@ #include #include #include "tc.h" -#include "timer.h" +#include "bacnet/basic/sys/mstimer.h" /* define which timer counter we are using */ #define MY_TIMER TCE0 -/* number of callbacks supported */ -#ifndef TIMER_CALLBACK_MAX -#define TIMER_CALLBACK_MAX 8 -#endif - /* counter for the base timer */ static volatile uint32_t Millisecond_Counter; - -/* callback data structure */ -struct timer_data_t { - volatile uint32_t interval; - volatile uint32_t milliseconds; - timer_callback_function callback; -}; -static volatile struct timer_data_t Callback_Data[TIMER_CALLBACK_MAX]; +/* callback data head of list */ +static volatile struct mstimer_callback_data_t *Callback_Head; /** * Handles the interrupt from the timer */ static void my_callback(void) { - uint32_t now, t, interval, i; + struct mstimer_callback_data_t *cb; Millisecond_Counter++; - now = Millisecond_Counter; - for (i = 0; i < TIMER_CALLBACK_MAX; i++) { - /* check for callback */ - if (Callback_Data[i].callback) { - t = Callback_Data[i].milliseconds; - if (now >= t) { - Callback_Data[i].callback(); - interval = Callback_Data[i].interval; - if (interval) { - Callback_Data[i].milliseconds = now + interval; - } else { - /* disable any one-shot timers */ - Callback_Data[i].callback = NULL; - } - } + cb = (struct mstimer_callback_data_t *)Callback_Head; + while (cb) { + if (mstimer_expired(&cb->timer)) { + cb->callback(); + if (mstimer_interval(&cb->timer) > 0) { + mstimer_reset(&cb->timer); + } } - } + cb = cb->next; + } } /** @@ -86,7 +68,7 @@ static void my_callback(void) * * @return the current milliseconds count */ -uint32_t timer_milliseconds(void) +unsigned long mstimer_now(void) { uint32_t timer_value; /* return value */ @@ -100,71 +82,44 @@ uint32_t timer_milliseconds(void) /** * Configures and enables a repeating callback function * + * @param new_cb - pointer to #mstimer_callback_data_t * @param callback - pointer to a #timer_callback_function function * @param milliseconds - how often to call the function * * @return true if successfully added and enabled */ -bool timer_callback( - timer_callback_function callback, - uint32_t milliseconds) +void mstimer_callback( + struct mstimer_callback_data_t *new_cb, + mstimer_callback_function callback, + unsigned long milliseconds) { - bool status = false; - uint32_t now, i; + struct mstimer_callback_data_t *cb; tc_set_overflow_interrupt_level(&MY_TIMER, TC_INT_LVL_OFF); - now = Millisecond_Counter; - for (i = 0; i < TIMER_CALLBACK_MAX; i++) { - if (Callback_Data[i].callback == NULL) { - Callback_Data[i].interval = milliseconds; - /* set the first expiration time */ - Callback_Data[i].milliseconds = now + milliseconds; - Callback_Data[i].callback = callback; - status = true; - break; + if (new_cb) { + new_cb->callback = callback; + mstimer_set(&new_cb->timer, milliseconds); + } + if (Callback_Head) { + cb = (struct mstimer_callback_data_t *)Callback_Head; + while (cb) { + if (!cb->next) { + cb->next = new_cb; + break; + } else { + cb = cb->next; + } } - } + } else { + Callback_Head = new_cb; + } tc_set_overflow_interrupt_level(&MY_TIMER, TC_INT_LVL_LO); - - return status; -} - -/** - * Configures and enables a one-shot callback function - * - * @param callback - pointer to a #timer_callback_function function - * @param milliseconds - how long to wait before calling the function - * - * @return true if successfully added and enabled - */ -bool timer_callback_oneshot( - timer_callback_function callback, - uint32_t milliseconds) -{ - bool status = false; - uint32_t now, i; - - tc_set_overflow_interrupt_level(&MY_TIMER, TC_INT_LVL_OFF); - now = Millisecond_Counter; - for (i = 0; i < TIMER_CALLBACK_MAX; i++) { - if (Callback_Data[i].callback == NULL) { - /* set the first expiration time */ - Callback_Data[i].milliseconds = now + milliseconds; - Callback_Data[i].interval = 0; - Callback_Data[i].callback = callback; - status = true; - break; - } - } - tc_set_overflow_interrupt_level(&MY_TIMER, TC_INT_LVL_LO); - - return status; } /** * Timer setup for 1 millisecond timer */ -void timer_init(void) +void mstimer_init(void) { unsigned long period; diff --git a/ports/xplained/nvmdata.c b/ports/xplained/nvmdata.c index 9f470d51..339c577d 100644 --- a/ports/xplained/nvmdata.c +++ b/ports/xplained/nvmdata.c @@ -8,8 +8,8 @@ #include #include #include "nvmdata.h" -#include "dlmstp.h" -#include "device.h" +#include "bacnet/datalink/dlmstp.h" +#include "bacnet/basic/object/device.h" /** * Initializes the non-volatile memory module diff --git a/ports/xplained/rs485.c b/ports/xplained/rs485.c index 68374845..b01d6630 100644 --- a/ports/xplained/rs485.c +++ b/ports/xplained/rs485.c @@ -33,10 +33,10 @@ #include "usart.h" #include "ioport.h" #include "sysclk.h" -#include "fifo.h" -#include "timer.h" +#include "bacnet/basic/sys/fifo.h" +#include "bacnet/basic/sys/mstimer.h" #include "led.h" -#include "mstpdef.h" +#include "bacnet/datalink/mstpdef.h" /* me! */ #include "rs485.h" @@ -69,7 +69,7 @@ static FIFO_BUFFER Transmit_Queue; /* baud rate of the UART interface */ static uint32_t Baud_Rate; /* timer for measuring line silence */ -static struct etimer Silence_Timer; +static struct mstimer Silence_Timer; /* flag to track RTS status */ static volatile bool RTS_Status; @@ -78,7 +78,7 @@ static volatile bool RTS_Status; */ void rs485_silence_reset(void) { - timer_elapsed_start(&Silence_Timer); + mstimer_set(&Silence_Timer, 0); } /** @@ -90,7 +90,7 @@ void rs485_silence_reset(void) */ bool rs485_silence_elapsed(uint32_t interval) { - return timer_elapsed_milliseconds(&Silence_Timer, interval); + return (mstimer_remaining(&Silence_Timer) > interval); } /** @@ -154,7 +154,7 @@ static uint16_t rs485_turnaround_time(void) */ bool rs485_turnaround_elapsed(void) { - return timer_elapsed_milliseconds(&Silence_Timer, rs485_turnaround_time()); + return (mstimer_remaining(&Silence_Timer) > rs485_turnaround_time()); } /** @@ -222,7 +222,7 @@ bool rs485_bytes_send(uint8_t * buffer, status = FIFO_Add(&Transmit_Queue, buffer, nbytes); if (start_required && status) { rs485_rts_enable(true); - timer_elapsed_start(&Silence_Timer); + rs485_silence_reset(); ch = FIFO_Get(&Transmit_Queue); usart_clear_tx_complete(&RS485_USART); usart_set_tx_interrupt_level(&RS485_USART, USART_INT_LVL_LO); @@ -322,12 +322,12 @@ void rs485_init(void) FIFO_Init(&Transmit_Queue, &Transmit_Queue_Data[0], (unsigned) sizeof(Transmit_Queue_Data)); /* initialize the silence timer */ - timer_elapsed_start(&Silence_Timer); + rs485_silence_reset(); /* configure the TX pin */ ioport_configure_pin(RS485_TXD, IOPORT_DIR_OUTPUT | IOPORT_INIT_HIGH); /* configure the RX pin */ - ioport_configure_pin(RS485_RXD, + ioport_configure_pin(RS485_RXD, IOPORT_DIR_INPUT); /* configure the RTS pins */ ioport_configure_pin(RS485_RE, diff --git a/ports/xplained/timer.c b/ports/xplained/timer.c deleted file mode 100644 index 50a917ec..00000000 --- a/ports/xplained/timer.c +++ /dev/null @@ -1,338 +0,0 @@ -/************************************************************************** -* -* Copyright (C) 2007 Steve Karg -* -* Permission is hereby granted, free of charge, to any person obtaining -* a copy of this software and associated documentation files (the -* "Software"), to deal in the Software without restriction, including -* without limitation the rights to use, copy, modify, merge, publish, -* distribute, sublicense, and/or sell copies of the Software, and to -* permit persons to whom the Software is furnished to do so, subject to -* the following conditions: -* -* The above copyright notice and this permission notice shall be included -* in all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*********************************************************************/ -#include -#include -#include "timer.h" - -/* interval and elapsed millisecond timer */ -/* interval not to exceed 49.7 days */ -/* minimum interval of 1ms may be 0 to 1ms */ - -/************************************************************************* -* Description: Start a timer from now. -* Returns: elapsed milliseconds since last set -* Notes: none -**************************************************************************/ -uint32_t timer_interval_start(struct itimer *t, uint32_t interval) -{ - uint32_t now = 0; - uint32_t elapsed = 0; - - now = timer_milliseconds(); - elapsed = now - t->start; - t->start = now; - t->interval = interval; - - return elapsed; -} - -/************************************************************************* -* Description: Start a timer from now. -* Returns: elapsed seconds since last set -* Notes: none -**************************************************************************/ -uint32_t timer_interval_start_seconds(struct itimer *t, uint32_t interval) -{ - uint32_t elapsed = 0; - - interval *= 1000L; - elapsed = timer_interval_start(t, interval); - elapsed /= 1000L; - - return elapsed; -} - -/************************************************************************* -* Description: Start a timer from now. -* Returns: elapsed minutes since last set -* Notes: none -**************************************************************************/ -uint32_t timer_interval_start_minutes(struct itimer *t, uint32_t interval) -{ - uint32_t elapsed = 0; - - interval *= 60L; - interval *= 1000L; - - elapsed = timer_interval_start(t, interval); - elapsed /= 1000L; - elapsed /= 60L; - - return elapsed; -} - -/************************************************************************* -* Description: Change the timer interval without restart -* Returns: previous interval value -* Notes: none -**************************************************************************/ -uint32_t timer_interval_adjust(struct itimer *t, uint32_t interval) -{ - uint32_t previous_interval = t->interval; - - t->interval = interval; - - return previous_interval; -} - -/************************************************************************* -* Description: Reset the timer with the same interval -* Returns: none -* Notes: none -**************************************************************************/ -void timer_interval_reset(struct itimer *t) -{ - t->start += t->interval; -} - -/************************************************************************* -* Description: Restart the timer from now, syncing on existing interval -* Returns: elapsed milliseconds since last reset -* Notes: none -**************************************************************************/ -uint32_t timer_interval_resync(struct itimer *t) -{ - uint32_t elapsed; - uint32_t intervals; - uint32_t gap; - uint32_t now; - - now = timer_milliseconds(); - elapsed = now - t->start; - if ((t->interval != TIMER_INTERVAL_MAX) && (t->interval != 0)) { - if (elapsed >= t->interval) { - /* catch up to now */ - intervals = elapsed / t->interval; - gap = intervals * t->interval; - t->start += gap; - } - } - - return elapsed; -} - -/************************************************************************* -* Description: Restart the timer from now -* Returns: elapsed milliseconds since last set -* Notes: none -**************************************************************************/ -uint32_t timer_interval_restart(struct itimer *t) -{ - uint32_t now; - uint32_t elapsed; - - now = timer_milliseconds(); - elapsed = now - t->start; - t->start = now; - - return elapsed; -} - -/************************************************************************* -* Description: Reset the timer with the zero interval - always expired -* Returns: none -* Notes: none -**************************************************************************/ -void timer_interval_none(struct itimer *t) -{ - t->interval = 0; -} - -/************************************************************************* -* Description: Reset the timer with the max interval - never expires -* Returns: none -* Notes: none -**************************************************************************/ -void timer_interval_infinity(struct itimer *t) -{ - t->interval = TIMER_INTERVAL_MAX; -} - -/************************************************************************* -* Description: Determines if the timer has an active interval -* Returns: true if active -* Notes: none -**************************************************************************/ -bool timer_interval_active(struct itimer *t) -{ - return ((t->interval != TIMER_INTERVAL_MAX) && (t->interval != 0)); -} - -/************************************************************************* -* Description: Check to see if the time interval has elapsed -* Returns: true if expired -* Notes: Setting the interval to max never expires, to zero always expires -**************************************************************************/ -bool timer_interval_expired(struct itimer *t) -{ - uint32_t elapsed = 0; - bool status = false; - uint32_t now; - - if (t->interval == 0) { - status = true; - } else if (t->interval == TIMER_INTERVAL_MAX) { - status = false; - } else { - now = timer_milliseconds(); - elapsed = now - t->start; - if (elapsed >= t->interval) { - status = true; - } - } - - return status; -} - -/************************************************************************* -* Description: Return the elapsed time -* Returns: number of milliseconds elapsed -* Notes: none -**************************************************************************/ -uint32_t timer_interval_elapsed(struct itimer *t) -{ - uint32_t now; - uint32_t elapsed; - - now = timer_milliseconds(); - elapsed = now - t->start; - - return elapsed; -} - -/************************************************************************* -* Description: Return the interval time -* Returns: number of milliseconds for which the interval is set -* Notes: none -**************************************************************************/ -uint32_t timer_interval(struct itimer *t) -{ - return t->interval; -} - -/************************************************************************* -* Description: Return the interval time -* Returns: number of seconds for which the interval is set -* Notes: none -**************************************************************************/ -uint32_t timer_interval_seconds(struct itimer *t) -{ - return (t->interval/1000); -} - -/* Elapsed Timer */ - -/************************************************************************* -* Description: Restart the timer from now -* Returns: elapsed milliseconds since last set -* Notes: none -**************************************************************************/ -uint32_t timer_elapsed_start_offset(struct etimer *t, uint32_t offset) -{ - uint32_t now; - uint32_t elapsed; - - now = timer_milliseconds(); - elapsed = now - t->start; - if (offset) { - t->start = now + offset; - } else { - t->start = now; - } - - return elapsed; -} - -/************************************************************************* -* Description: Start a timer from now. -* Returns: elapsed milliseconds since last set -* Notes: none -**************************************************************************/ -uint32_t timer_elapsed_start(struct etimer *t) -{ - return timer_elapsed_start_offset(t, 0); -} - -/************************************************************************* -* Description: Return the elapsed time -* Returns: true if interval has elapsed -* Notes: none -**************************************************************************/ -bool timer_elapsed_milliseconds(struct etimer *t, uint32_t interval) -{ - bool status = false; - uint32_t delta; - - delta = timer_milliseconds() - t->start; - if (delta >= interval) { - status = true; - } - - return status; -} - -/************************************************************************* -* Description: Return the elapsed time -* Returns: true if interval has elapsed -* Notes: none -**************************************************************************/ -bool timer_elapsed_seconds(struct etimer *t, uint32_t interval) -{ - /* convert to seconds */ - interval *= 1000L; - - return timer_elapsed_milliseconds(t, interval); -} - -/************************************************************************* -* Description: Return the elapsed time -* Returns: true if interval has elapsed -* Notes: none -**************************************************************************/ -bool timer_elapsed_minutes(struct etimer *t, uint32_t interval) -{ - /* convert to seconds */ - interval *= 1000L; - /* convert to minutes */ - interval *= 60L; - - return timer_elapsed_milliseconds(t, interval); -} - -/************************************************************************* -* Description: Return the elapsed time -* Returns: number of milliseconds elapsed -* Notes: none -**************************************************************************/ -uint32_t timer_elapsed_time(struct etimer *t) -{ - uint32_t now; - uint32_t elapsed; - - now = timer_milliseconds(); - elapsed = now - t->start; - - return elapsed; -} - diff --git a/ports/xplained/timer.h b/ports/xplained/timer.h deleted file mode 100644 index e3d95175..00000000 --- a/ports/xplained/timer.h +++ /dev/null @@ -1,96 +0,0 @@ -/************************************************************************** -* -* Copyright (C) 2007 Steve Karg -* -* Permission is hereby granted, free of charge, to any person obtaining -* a copy of this software and associated documentation files (the -* "Software"), to deal in the Software without restriction, including -* without limitation the rights to use, copy, modify, merge, publish, -* distribute, sublicense, and/or sell copies of the Software, and to -* permit persons to whom the Software is furnished to do so, subject to -* the following conditions: -* -* The above copyright notice and this permission notice shall be included -* in all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*********************************************************************/ -#ifndef TIMER_H -#define TIMER_H - -#include -#include - -/* interval and elapsed millisecond timer */ -/* interval not to exceed 49.7 days */ -#define TIMER_INTERVAL_MAX UINT32_MAX - -/* structure for elapsed timer */ -struct etimer { - uint32_t start; -}; - -/* structure for interval timer */ -struct itimer { - uint32_t start; - uint32_t interval; -}; - -typedef void (*timer_callback_function) (void); - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - - /* -- Interval Timer library -- */ - /* defined in generic timer module */ - uint32_t timer_interval_start(struct itimer *t, uint32_t interval); - uint32_t timer_interval_start_seconds(struct itimer *t, uint32_t interval); - uint32_t timer_interval_start_minutes(struct itimer *t, uint32_t interval); - /* adjust interval without restarting */ - uint32_t timer_interval_adjust(struct itimer *t, uint32_t interval); - /* adds interval to start - good for cyclic timers */ - void timer_interval_reset(struct itimer *t); - /* sets interval to zero - always expired */ - void timer_interval_none(struct itimer *t); - /* sets interval to max - never expires */ - void timer_interval_infinity(struct itimer *t); - /* syncs the start time to the next interval */ - uint32_t timer_interval_resync(struct itimer *t); - /* restarts the interval timer */ - uint32_t timer_interval_restart(struct itimer *t); - bool timer_interval_expired(struct itimer *t); - uint32_t timer_interval(struct itimer *t); - bool timer_interval_active(struct itimer *t); - uint32_t timer_interval_seconds(struct itimer *t); - uint32_t timer_interval_elapsed(struct itimer *t); - /* -- Elapsed Timer library - lower RAM usage or alternate functional usage -- */ - uint32_t timer_elapsed_start(struct etimer *t); - uint32_t timer_elapsed_start_offset(struct etimer *t, uint32_t offset); - bool timer_elapsed_milliseconds(struct etimer *t, uint32_t interval); - bool timer_elapsed_seconds(struct etimer *t, uint32_t interval); - bool timer_elapsed_minutes(struct etimer *t, uint32_t interval); - uint32_t timer_elapsed_time(struct etimer *t); - - /* define these functions in hardware specific timer module */ - void timer_init(void); - /* Raw API is used only by the elapsed and interval timer library. - Do not use it directly in your code. */ - uint32_t timer_milliseconds(void); - bool timer_callback( - timer_callback_function callback, - uint32_t milliseconds); - bool timer_callback_oneshot( - timer_callback_function callback, - uint32_t milliseconds); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ -#endif diff --git a/rebuild.sh b/rebuild.sh deleted file mode 100755 index 80028791..00000000 --- a/rebuild.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/sh -# Re-Build script for MinGW (Make only, no clean first) -echo "Re-Build with MinGW and MSYS: mingw.sourceforge.net" -# set PATH=C:\MinGW\msys\1.0\bin;C:\MinGW\bin -# assumes rm, cp, size are already in path -CC=gcc -AR=ar -MAKE=make -export CC AR MAKE -make BACNET_PORT=win32 BUILD=release all - -# Build for MinGW debug -# make BACNET_PORT=win32 BUILD=debug all - -# Build for MinGW MS/TP -# make BACNET_PORT=win32 BACDL_DEFINE=-DBACDL_MSTP=1 all - -# On Linux, install mingw32 and use this: -# make BACNET_PORT=win32 CC=i586-mingw32msvc-gcc AR=i586-mingw32msvc-ar all - -echo "Complete!" diff --git a/release.sh b/release.sh deleted file mode 100755 index 734edf94..00000000 --- a/release.sh +++ /dev/null @@ -1,115 +0,0 @@ -#!/bin/sh -# Release helper for this project - -USERNAME=skarg -PROJECT=bacnet -SVN_BASE_URL=https://svn.code.sf.net/p/${PROJECT}/code -SVN_MODULE=bacnet-stack -FRS_URL=${USERNAME},${PROJECT}@frs.sourceforge.net:/home/frs/project/b/ba/bacnet/bacnet-stack - -if [ -z "$1" ] -then - echo "Usage: `basename $0` 0.0.0" - echo "Creates the ChangeLog." - echo "Creates the release files." - echo "Tags the current version in subversion." - exit 1 -fi - -DOTTED_VERSION="$1" -echo "Creating the release files for version ${DOTTED_VERSION}" - -CHANGELOG=ChangeLog-${DOTTED_VERSION} -echo "Creating the ${PROJECT} change log ${CHANGELOG}" -if [ -e "${CHANGELOG}" ] -then -rm ${CHANGELOG} -fi -svn update -svn log --xml --verbose | xsltproc svn2cl.xsl - > ${CHANGELOG} -if [ -e "${CHANGELOG}" ] -then - echo "${CHANGELOG} created." -else - echo "Failed to create ${CHANGELOG}" - exit 1 -fi - -ARCHIVE_NAME=${SVN_MODULE}-${DOTTED_VERSION} - -SVN_TRUNK_NAME=${SVN_BASE_URL}/trunk/${SVN_MODULE} -SVN_TAGGED_NAME=${SVN_BASE_URL}/tags/${ARCHIVE_NAME} -echo "Setting a tag on the ${SVN_MODULE} module called ${ARCHIVE_NAME}" -TAG_COMMENT="Created version ${ARCHIVE_NAME}" -svn copy --username=${USERNAME} ${SVN_TRUNK_NAME} ${SVN_TAGGED_NAME} -m "${TAG_COMMENT}" -echo "done." - -if [ -d "${ARCHIVE_NAME}" ] -then - echo "removing old ${ARCHIVE_NAME}..." - rm -rf ${ARCHIVE_NAME} - echo "done." -fi - -echo "Getting a clean version out of subversion for Linux gzip" -svn export --username=${USERNAME} ${SVN_TAGGED_NAME} ${ARCHIVE_NAME} > /dev/null -echo "done." - -GZIP_FILENAME=${ARCHIVE_NAME}.tgz -echo "tar and gzip the clean directory" -if [ -e "${GZIP_FILENAME}" ] -then - echo "removing old ${GZIP_FILENAME}..." - rm ${GZIP_FILENAME} - echo "done." -fi -tar -cvvzf ${GZIP_FILENAME} ${ARCHIVE_NAME}/ > /dev/null -echo "done." -if [ -e "${GZIP_FILENAME}" ] -then - echo "${GZIP_FILENAME} created." -else - echo "Failed to create ${GZIP_FILENAME}" - exit 1 -fi - -if [ -d "${ARCHIVE_NAME}" ] -then - echo "removing old ${ARCHIVE_NAME}..." - rm -rf ${ARCHIVE_NAME} - echo "done." -fi -echo "Getting another clean version out of subversion for Windows zip" -svn export --username=${USERNAME} --native-eol CRLF ${SVN_TAGGED_NAME} ${ARCHIVE_NAME} > /dev/null -ZIP_FILENAME=${ARCHIVE_NAME}.zip -echo "done." -echo "Zipping the directory exported for Windows." -zip -r ${ZIP_FILENAME} ${ARCHIVE_NAME} > /dev/null - -if [ -e "${ZIP_FILENAME}" ] -then - echo "${ZIP_FILENAME} created." -else - echo "Failed to create ${ZIP_FILENAME}" - exit 1 -fi - -# remove SVN files -if [ -d "${ARCHIVE_NAME}" ] -then - echo "removing ${ARCHIVE_NAME}..." - rm -rf ${ARCHIVE_NAME} - echo "done." -fi - -echo "Creating ${ARCHIVE_NAME}" -mkdir ${ARCHIVE_NAME} -mv ${ZIP_FILENAME} ${ARCHIVE_NAME} -mv ${GZIP_FILENAME} ${ARCHIVE_NAME} -mv ${CHANGELOG} ${ARCHIVE_NAME} -cp readme.txt ${ARCHIVE_NAME} - -echo "Sending ${ARCHIVE_NAME} to SourceForge using scp..." -scp -r ${ARCHIVE_NAME} ${FRS_URL} - -echo "Complete!" diff --git a/splint.sh b/splint.sh deleted file mode 100755 index f91ebb42..00000000 --- a/splint.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/bin/sh -# splint is a static code checker - -SPLINT=/usr/bin/splint - -[ -x ${SPLINT} ] || exit 0 - -DEFINES="-D__signed__=signed -D__gnuc_va_list=va_list" -INCLUDES="-Iinclude -Idemo/object -Iports/linux" -SETTINGS="-castfcnptr -fullinitblock -initallelements -weak -warnposixheaders" -SPLINT_LOGFILE=splint_output.txt - -if [ ! -e .splintrc ] -then - echo ${DEFINES} ${INCLUDES} ${SETTINGS} > .splintrc -fi - -directory=${1-`pwd`}/src -rm -f splint_output.txt -touch splint_output.txt -for filename in $( find $directory -name '*.c' ) -do - echo splinting ${filename} - echo splinting ${filename} >> ${SPLINT_LOGFILE} - ${SPLINT} ${filename} >> ${SPLINT_LOGFILE} 2>&1 -done - diff --git a/src/Makefile b/src/Makefile new file mode 100644 index 00000000..0e5059a4 --- /dev/null +++ b/src/Makefile @@ -0,0 +1,50 @@ +#Makefile to build BACnet Library with GCC + +# tools - only if you need them. +# Most platforms have this already defined +# CC = gcc +# AR = ar +# MAKE = make +# SIZE = size +# +# Assumes rm and cp are available + +# These might be already defined in an previous Makefile +BACNET_PORT ?= linux +BACNET_SRC_DIR ?= $(realpath .) +BACNET_PORT_DIR ?= $(realpath ../ports/$(BACNET_PORT)) +BACNET_PORT_SRC ?= \ + $(BACNET_PORT_DIR)/bip-init.c \ + $(BACNET_SRC_DIR)/bacnet/datalink/bvlc.c \ + $(BACNET_SRC_DIR)/bacnet/datalink/bip.c + +# include file search paths +BACNET_INCLUDES = -I$(BACNET_SRC_DIR) -I$(BACNET_PORT_DIR) +CFLAGS += $(BACNET_INCLUDES) + +BACNET_SRC ?= main.c \ + $(wildcard $(BACNET_SRC_DIR)/bacnet/*.c) \ + $(wildcard $(BACNET_SRC_DIR)/bacnet/basic/*.c) \ + $(wildcard $(BACNET_SRC_DIR)/bacnet/basic/binding/*.c) \ + $(wildcard $(BACNET_SRC_DIR)/bacnet/basic/service/*.c) \ + $(wildcard $(BACNET_SRC_DIR)/bacnet/basic/npdu/*.c) \ + $(wildcard $(BACNET_SRC_DIR)/bacnet/basic/sys/*.c) \ + $(wildcard $(BACNET_SRC_DIR)/bacnet/basic/tsm/*.c) + +ifneq (,$(findstring -DBAC_UCI,$(BACNET_DEFINES))) +OBJS += $(patsubst %.c,%.o,$(wildcard basic/ucix/*.c)) +endif + +all: $(OBJS) Makefile + +.c.o: + ${CC} -c ${CFLAGS} $*.c -o $@ + +depend: + rm -f .depend + ${CC} -MM ${CFLAGS} *.c >> .depend + +clean: + rm -rf core $(OBJS) $(LIBRARY) + +include: .depend diff --git a/src/abort.c b/src/bacnet/abort.c similarity index 79% rename from src/abort.c rename to src/bacnet/abort.c index 199b5650..41f9d6d4 100644 --- a/src/abort.c +++ b/src/bacnet/abort.c @@ -32,10 +32,10 @@ ------------------------------------------- ####COPYRIGHTEND####*/ #include -#include "bacenum.h" -#include "bacdcode.h" -#include "bacdef.h" -#include "abort.h" +#include "bacnet/bacenum.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacdef.h" +#include "bacnet/abort.h" /** @file abort.c Abort Encoding/Decoding */ /* Helper function to avoid needing additional entries in service data @@ -73,16 +73,17 @@ BACNET_ABORT_REASON abort_convert_error_code(BACNET_ERROR_CODE error_code) } /* encode service */ -int abort_encode_apdu(uint8_t *apdu, uint8_t invoke_id, uint8_t abort_reason, - bool server) +int abort_encode_apdu( + uint8_t *apdu, uint8_t invoke_id, uint8_t abort_reason, bool server) { int apdu_len = 0; /* total length of the apdu, return value */ if (apdu) { - if (server) + if (server) { apdu[0] = PDU_TYPE_ABORT | 1; - else + } else { apdu[0] = PDU_TYPE_ABORT; + } apdu[1] = invoke_id; apdu[2] = abort_reason; apdu_len = 3; @@ -93,16 +94,18 @@ int abort_encode_apdu(uint8_t *apdu, uint8_t invoke_id, uint8_t abort_reason, #if !BACNET_SVC_SERVER /* decode the service request only */ -int abort_decode_service_request(uint8_t *apdu, unsigned apdu_len, - uint8_t *invoke_id, uint8_t *abort_reason) +int abort_decode_service_request( + uint8_t *apdu, unsigned apdu_len, uint8_t *invoke_id, uint8_t *abort_reason) { int len = 0; if (apdu_len > 0) { - if (invoke_id) + if (invoke_id) { *invoke_id = apdu[0]; - if (abort_reason) + } + if (abort_reason) { *abort_reason = apdu[1]; + } } return len; @@ -115,8 +118,11 @@ int abort_decode_service_request(uint8_t *apdu, unsigned apdu_len, #include "ctest.h" /* decode the whole APDU - mainly used for unit testing */ -int abort_decode_apdu(uint8_t *apdu, unsigned apdu_len, uint8_t *invoke_id, - uint8_t *abort_reason, bool *server) +int abort_decode_apdu(uint8_t *apdu, + unsigned apdu_len, + uint8_t *invoke_id, + uint8_t *abort_reason, + bool *server) { int len = 0; @@ -131,18 +137,18 @@ int abort_decode_apdu(uint8_t *apdu, unsigned apdu_len, uint8_t *invoke_id, else *server = false; if (apdu_len > 1) { - len = abort_decode_service_request(&apdu[1], apdu_len - 1, - invoke_id, abort_reason); + len = abort_decode_service_request( + &apdu[1], apdu_len - 1, invoke_id, abort_reason); } } return len; } -void testAbortAPDU(Test *pTest, uint8_t invoke_id, uint8_t abort_reason, - bool server) +void testAbortAPDU( + Test *pTest, uint8_t invoke_id, uint8_t abort_reason, bool server) { - uint8_t apdu[480] = {0}; + uint8_t apdu[480] = { 0 }; int len = 0; int apdu_len = 0; uint8_t test_invoke_id = 0; @@ -152,8 +158,8 @@ void testAbortAPDU(Test *pTest, uint8_t invoke_id, uint8_t abort_reason, len = abort_encode_apdu(&apdu[0], invoke_id, abort_reason, server); apdu_len = len; ct_test(pTest, len != 0); - len = abort_decode_apdu(&apdu[0], apdu_len, &test_invoke_id, - &test_abort_reason, &test_server); + len = abort_decode_apdu( + &apdu[0], apdu_len, &test_invoke_id, &test_abort_reason, &test_server); ct_test(pTest, len != -1); ct_test(pTest, test_invoke_id == invoke_id); ct_test(pTest, test_abort_reason == abort_reason); @@ -164,7 +170,7 @@ void testAbortAPDU(Test *pTest, uint8_t invoke_id, uint8_t abort_reason, void testAbort(Test *pTest) { - uint8_t apdu[480] = {0}; + uint8_t apdu[480] = { 0 }; int len = 0; int apdu_len = 0; uint8_t invoke_id = 0; @@ -177,8 +183,8 @@ void testAbort(Test *pTest) len = abort_encode_apdu(&apdu[0], invoke_id, abort_reason, server); ct_test(pTest, len != 0); apdu_len = len; - len = abort_decode_apdu(&apdu[0], apdu_len, &test_invoke_id, - &test_abort_reason, &test_server); + len = abort_decode_apdu( + &apdu[0], apdu_len, &test_invoke_id, &test_abort_reason, &test_server); ct_test(pTest, len != -1); ct_test(pTest, test_invoke_id == invoke_id); ct_test(pTest, test_abort_reason == abort_reason); @@ -186,18 +192,18 @@ void testAbort(Test *pTest) /* change type to get negative response */ apdu[0] = PDU_TYPE_REJECT; - len = abort_decode_apdu(&apdu[0], apdu_len, &test_invoke_id, - &test_abort_reason, &test_server); + len = abort_decode_apdu( + &apdu[0], apdu_len, &test_invoke_id, &test_abort_reason, &test_server); ct_test(pTest, len == -1); /* test NULL APDU */ - len = abort_decode_apdu(NULL, apdu_len, &test_invoke_id, &test_abort_reason, - &test_server); + len = abort_decode_apdu( + NULL, apdu_len, &test_invoke_id, &test_abort_reason, &test_server); ct_test(pTest, len == -1); /* force a zero length */ - len = abort_decode_apdu(&apdu[0], 0, &test_invoke_id, &test_abort_reason, - &test_server); + len = abort_decode_apdu( + &apdu[0], 0, &test_invoke_id, &test_abort_reason, &test_server); ct_test(pTest, len == 0); /* check them all... */ diff --git a/include/abort.h b/src/bacnet/abort.h similarity index 98% rename from include/abort.h rename to src/bacnet/abort.h index cfae56ea..fc797b71 100644 --- a/include/abort.h +++ b/src/bacnet/abort.h @@ -26,6 +26,7 @@ #include #include +#include "bacnet/bacenum.h" #ifdef __cplusplus extern "C" { diff --git a/src/access_rule.c b/src/bacnet/access_rule.c similarity index 74% rename from src/access_rule.c rename to src/bacnet/access_rule.c index b5957a19..b0f06efe 100644 --- a/src/access_rule.c +++ b/src/bacnet/access_rule.c @@ -25,10 +25,10 @@ #include #include -#include "access_rule.h" -#include "bacdcode.h" +#include "bacnet/access_rule.h" +#include "bacnet/bacdcode.h" -int bacapp_encode_access_rule(uint8_t* apdu, BACNET_ACCESS_RULE* rule) +int bacapp_encode_access_rule(uint8_t *apdu, BACNET_ACCESS_RULE *rule) { int len; int apdu_len = 0; @@ -37,12 +37,13 @@ int bacapp_encode_access_rule(uint8_t* apdu, BACNET_ACCESS_RULE* rule) apdu_len += len; if (rule->time_range_specifier == TIME_RANGE_SPECIFIER_SPECIFIED) { - len = bacapp_encode_context_device_obj_property_ref(&apdu[apdu_len], 1, - &rule->time_range); - if (len > 0) + len = bacapp_encode_context_device_obj_property_ref( + &apdu[apdu_len], 1, &rule->time_range); + if (len > 0) { apdu_len += len; - else + } else { return -1; + } } len = @@ -50,12 +51,13 @@ int bacapp_encode_access_rule(uint8_t* apdu, BACNET_ACCESS_RULE* rule) apdu_len += len; if (rule->location_specifier == LOCATION_SPECIFIER_SPECIFIED) { - len = bacapp_encode_context_device_obj_property_ref(&apdu[apdu_len], 3, - &rule->location); - if (len > 0) + len = bacapp_encode_context_device_obj_property_ref( + &apdu[apdu_len], 3, &rule->location); + if (len > 0) { apdu_len += len; - else + } else { return -1; + } } len = encode_context_boolean(&apdu[apdu_len], 4, rule->enable); @@ -64,8 +66,8 @@ int bacapp_encode_access_rule(uint8_t* apdu, BACNET_ACCESS_RULE* rule) return apdu_len; } -int bacapp_encode_context_access_rule(uint8_t* apdu, uint8_t tag_number, - BACNET_ACCESS_RULE* rule) +int bacapp_encode_context_access_rule( + uint8_t *apdu, uint8_t tag_number, BACNET_ACCESS_RULE *rule) { int len; int apdu_len = 0; @@ -82,69 +84,79 @@ int bacapp_encode_context_access_rule(uint8_t* apdu, uint8_t tag_number, return apdu_len; } -int bacapp_decode_access_rule(uint8_t* apdu, BACNET_ACCESS_RULE* rule) +int bacapp_decode_access_rule(uint8_t *apdu, BACNET_ACCESS_RULE *rule) { int len; int apdu_len = 0; if (decode_is_context_tag(&apdu[apdu_len], 0)) { - len = decode_context_enumerated(&apdu[apdu_len], 0, - &rule->time_range_specifier); - if (len < 0) + len = decode_context_enumerated( + &apdu[apdu_len], 0, &rule->time_range_specifier); + if (len < 0) { return -1; - else + } else { apdu_len += len; - } else + } + } else { return -1; + } if (rule->time_range_specifier == TIME_RANGE_SPECIFIER_SPECIFIED) { if (decode_is_context_tag(&apdu[apdu_len], 1)) { len = bacapp_decode_context_device_obj_property_ref( &apdu[apdu_len], 1, &rule->time_range); - if (len < 0) + if (len < 0) { return -1; - else + } else { apdu_len += len; - } else + } + } else { return -1; + } } if (decode_is_context_tag(&apdu[apdu_len], 2)) { - len = decode_context_enumerated(&apdu[apdu_len], 2, - &rule->location_specifier); - if (len < 0) + len = decode_context_enumerated( + &apdu[apdu_len], 2, &rule->location_specifier); + if (len < 0) { return -1; - else + } else { apdu_len += len; - } else + } + } else { return -1; + } if (rule->location_specifier == LOCATION_SPECIFIER_SPECIFIED) { if (decode_is_context_tag(&apdu[apdu_len], 3)) { len = bacapp_decode_context_device_obj_property_ref( &apdu[apdu_len], 3, &rule->location); - if (len < 0) + if (len < 0) { return -1; - else + } else { apdu_len += len; - } else + } + } else { return -1; + } } if (decode_is_context_tag(&apdu[apdu_len], 4)) { len = decode_context_boolean2(&apdu[apdu_len], 4, &rule->enable); - if (len < 0) + if (len < 0) { return -1; - else + } else { apdu_len += len; - } else + } + } else { return -1; + } return apdu_len; } -int bacapp_decode_context_access_rule(uint8_t* apdu, uint8_t tag_number, - BACNET_ACCESS_RULE* rule) +int bacapp_decode_context_access_rule( + uint8_t *apdu, uint8_t tag_number, BACNET_ACCESS_RULE *rule) { int len = 0; int section_length; diff --git a/include/access_rule.h b/src/bacnet/access_rule.h similarity index 96% rename from include/access_rule.h rename to src/bacnet/access_rule.h index 067bd3b3..811a53a9 100644 --- a/include/access_rule.h +++ b/src/bacnet/access_rule.h @@ -28,9 +28,9 @@ #include #include -#include "bacdef.h" -#include "bacapp.h" -#include "bacdevobjpropref.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacapp.h" +#include "bacnet/bacdevobjpropref.h" typedef enum { TIME_RANGE_SPECIFIER_SPECIFIED = 0, diff --git a/src/alarm_ack.c b/src/bacnet/alarm_ack.c similarity index 60% rename from src/alarm_ack.c rename to src/bacnet/alarm_ack.c index 57048dc0..47072b6a 100644 --- a/src/alarm_ack.c +++ b/src/bacnet/alarm_ack.c @@ -31,8 +31,9 @@ License. ------------------------------------------- ####COPYRIGHTEND####*/ - -#include "alarm_ack.h" +#include +#include +#include "bacnet/alarm_ack.h" /** @file alarm_ack.c Handles Event Notifications (ACKs) */ @@ -41,10 +42,10 @@ ** Creates an Unconfirmed Event Notification APDU ** ****************************************************/ -int alarm_ack_encode_apdu(uint8_t *apdu, uint8_t invoke_id, - BACNET_ALARM_ACK_DATA *data) +int alarm_ack_encode_apdu( + uint8_t *apdu, uint8_t invoke_id, BACNET_ALARM_ACK_DATA *data) { - int len = 0; /* length of each encoding */ + int len = 0; /* length of each encoding */ int apdu_len = 0; /* total length of the apdu, return value */ if (apdu) { @@ -68,33 +69,33 @@ int alarm_ack_encode_apdu(uint8_t *apdu, uint8_t invoke_id, ****************************************************/ int alarm_ack_encode_service_request(uint8_t *apdu, BACNET_ALARM_ACK_DATA *data) { - int len = 0; /* length of each encoding */ + int len = 0; /* length of each encoding */ int apdu_len = 0; /* total length of the apdu, return value */ if (apdu) { - len = encode_context_unsigned(&apdu[apdu_len], 0, - data->ackProcessIdentifier); + len = encode_context_unsigned( + &apdu[apdu_len], 0, data->ackProcessIdentifier); apdu_len += len; len = encode_context_object_id(&apdu[apdu_len], 1, - (int)data->eventObjectIdentifier.type, - data->eventObjectIdentifier.instance); + (int)data->eventObjectIdentifier.type, + data->eventObjectIdentifier.instance); apdu_len += len; - len = encode_context_enumerated(&apdu[apdu_len], 2, - data->eventStateAcked); + len = encode_context_enumerated( + &apdu[apdu_len], 2, data->eventStateAcked); apdu_len += len; - len = bacapp_encode_context_timestamp(&apdu[apdu_len], 3, - &data->eventTimeStamp); + len = bacapp_encode_context_timestamp( + &apdu[apdu_len], 3, &data->eventTimeStamp); apdu_len += len; - len = encode_context_character_string(&apdu[apdu_len], 4, - &data->ackSource); + len = encode_context_character_string( + &apdu[apdu_len], 4, &data->ackSource); apdu_len += len; - len = bacapp_encode_context_timestamp(&apdu[apdu_len], 5, - &data->ackTimeStamp); + len = bacapp_encode_context_timestamp( + &apdu[apdu_len], 5, &data->ackTimeStamp); apdu_len += len; } @@ -106,8 +107,8 @@ int alarm_ack_encode_service_request(uint8_t *apdu, BACNET_ALARM_ACK_DATA *data) ** Decodes the service data part of Event Notification ** ****************************************************/ -int alarm_ack_decode_service_request(uint8_t *apdu, unsigned apdu_len, - BACNET_ALARM_ACK_DATA *data) +int alarm_ack_decode_service_request( + uint8_t *apdu, unsigned apdu_len, BACNET_ALARM_ACK_DATA *data) { int len = 0; int section_len; @@ -116,15 +117,17 @@ int alarm_ack_decode_service_request(uint8_t *apdu, unsigned apdu_len, /* unused parameter */ apdu_len = apdu_len; - if (-1 == (section_len = decode_context_unsigned( - &apdu[len], 0, &data->ackProcessIdentifier))) { + if (-1 == + (section_len = decode_context_unsigned( + &apdu[len], 0, &data->ackProcessIdentifier))) { return -1; } len += section_len; - if (-1 == (section_len = decode_context_object_id( - &apdu[len], 1, &data->eventObjectIdentifier.type, - &data->eventObjectIdentifier.instance))) { + if (-1 == + (section_len = decode_context_object_id(&apdu[len], 1, + &data->eventObjectIdentifier.type, + &data->eventObjectIdentifier.instance))) { return -1; } len += section_len; @@ -136,20 +139,23 @@ int alarm_ack_decode_service_request(uint8_t *apdu, unsigned apdu_len, data->eventStateAcked = (BACNET_EVENT_STATE)enumValue; len += section_len; - if (-1 == (section_len = bacapp_decode_context_timestamp( - &apdu[len], 3, &data->eventTimeStamp))) { + if (-1 == + (section_len = bacapp_decode_context_timestamp( + &apdu[len], 3, &data->eventTimeStamp))) { return -1; } len += section_len; - if (-1 == (section_len = decode_context_character_string( - &apdu[len], 4, &data->ackSource))) { + if (-1 == + (section_len = decode_context_character_string( + &apdu[len], 4, &data->ackSource))) { return -1; } len += section_len; - if (-1 == (section_len = bacapp_decode_context_timestamp( - &apdu[len], 5, &data->ackTimeStamp))) { + if (-1 == + (section_len = bacapp_decode_context_timestamp( + &apdu[len], 5, &data->ackTimeStamp))) { return -1; } len += section_len; @@ -192,35 +198,45 @@ void testAlarmAck(Test *pTest) ct_test(pTest, inLen == outLen); - ct_test(pTest, testAlarmAckIn.ackProcessIdentifier == - testAlarmAckOut.ackProcessIdentifier); - - ct_test(pTest, testAlarmAckIn.ackTimeStamp.tag == - testAlarmAckOut.ackTimeStamp.tag); - ct_test(pTest, testAlarmAckIn.ackTimeStamp.value.sequenceNum == - testAlarmAckOut.ackTimeStamp.value.sequenceNum); - - ct_test(pTest, testAlarmAckIn.ackProcessIdentifier == - testAlarmAckOut.ackProcessIdentifier); - - ct_test(pTest, testAlarmAckIn.eventObjectIdentifier.instance == - testAlarmAckOut.eventObjectIdentifier.instance); - ct_test(pTest, testAlarmAckIn.eventObjectIdentifier.type == - testAlarmAckOut.eventObjectIdentifier.type); - - ct_test(pTest, testAlarmAckIn.eventTimeStamp.tag == - testAlarmAckOut.eventTimeStamp.tag); - ct_test(pTest, testAlarmAckIn.eventTimeStamp.value.time.hour == - testAlarmAckOut.eventTimeStamp.value.time.hour); - ct_test(pTest, testAlarmAckIn.eventTimeStamp.value.time.min == - testAlarmAckOut.eventTimeStamp.value.time.min); - ct_test(pTest, testAlarmAckIn.eventTimeStamp.value.time.sec == - testAlarmAckOut.eventTimeStamp.value.time.sec); - ct_test(pTest, testAlarmAckIn.eventTimeStamp.value.time.hundredths == - testAlarmAckOut.eventTimeStamp.value.time.hundredths); + ct_test(pTest, + testAlarmAckIn.ackProcessIdentifier == + testAlarmAckOut.ackProcessIdentifier); ct_test(pTest, - testAlarmAckIn.eventStateAcked == testAlarmAckOut.eventStateAcked); + testAlarmAckIn.ackTimeStamp.tag == testAlarmAckOut.ackTimeStamp.tag); + ct_test(pTest, + testAlarmAckIn.ackTimeStamp.value.sequenceNum == + testAlarmAckOut.ackTimeStamp.value.sequenceNum); + + ct_test(pTest, + testAlarmAckIn.ackProcessIdentifier == + testAlarmAckOut.ackProcessIdentifier); + + ct_test(pTest, + testAlarmAckIn.eventObjectIdentifier.instance == + testAlarmAckOut.eventObjectIdentifier.instance); + ct_test(pTest, + testAlarmAckIn.eventObjectIdentifier.type == + testAlarmAckOut.eventObjectIdentifier.type); + + ct_test(pTest, + testAlarmAckIn.eventTimeStamp.tag == + testAlarmAckOut.eventTimeStamp.tag); + ct_test(pTest, + testAlarmAckIn.eventTimeStamp.value.time.hour == + testAlarmAckOut.eventTimeStamp.value.time.hour); + ct_test(pTest, + testAlarmAckIn.eventTimeStamp.value.time.min == + testAlarmAckOut.eventTimeStamp.value.time.min); + ct_test(pTest, + testAlarmAckIn.eventTimeStamp.value.time.sec == + testAlarmAckOut.eventTimeStamp.value.time.sec); + ct_test(pTest, + testAlarmAckIn.eventTimeStamp.value.time.hundredths == + testAlarmAckOut.eventTimeStamp.value.time.hundredths); + + ct_test(pTest, + testAlarmAckIn.eventStateAcked == testAlarmAckOut.eventStateAcked); } #ifdef TEST_ALARM_ACK diff --git a/include/alarm_ack.h b/src/bacnet/alarm_ack.h similarity index 97% rename from include/alarm_ack.h rename to src/bacnet/alarm_ack.h index ffdbc8f9..ee391ddc 100644 --- a/include/alarm_ack.h +++ b/src/bacnet/alarm_ack.h @@ -24,11 +24,11 @@ #ifndef ALARM_ACK_H_ #define ALARM_ACK_H_ -#include "bacenum.h" #include #include -#include "bacapp.h" -#include "timestamp.h" +#include "bacnet/bacenum.h" +#include "bacnet/bacapp.h" +#include "bacnet/timestamp.h" typedef struct { uint32_t ackProcessIdentifier; diff --git a/ports/dos/rs485.h b/src/bacnet/apdu.h similarity index 64% rename from ports/dos/rs485.h rename to src/bacnet/apdu.h index ae622daa..33853bf9 100644 --- a/ports/dos/rs485.h +++ b/src/bacnet/apdu.h @@ -1,6 +1,6 @@ /************************************************************************** * -* Copyright (C) 2007 Steve Karg +* Copyright (C) 2012 Steve Karg * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the @@ -20,41 +20,32 @@ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -* *********************************************************************/ +#ifndef APDU_H +#define APDU_H -#ifndef RS485_H -#define RS485_H - +#include #include +#include "bacnet/bacdef.h" +#include "bacnet/bacenum.h" -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ +typedef struct _confirmed_service_data { + bool segmented_message; + bool more_follows; + bool segmented_response_accepted; + int max_segs; + int max_resp; + uint8_t invoke_id; + uint8_t sequence_number; + uint8_t proposed_window_number; +} BACNET_CONFIRMED_SERVICE_DATA; - void RS485_Initialize( - void); +typedef struct _confirmed_service_ack_data { + bool segmented_message; + bool more_follows; + uint8_t invoke_id; + uint8_t sequence_number; + uint8_t proposed_window_number; +} BACNET_CONFIRMED_SERVICE_ACK_DATA; - void RS485_Transmitter_Enable( - bool enable); - - void RS485_Send_Data( - uint8_t * buffer, /* data to send */ - uint16_t nbytes); /* number of bytes of data */ - - bool RS485_ReceiveError( - void); - bool RS485_DataAvailable( - uint8_t * data); - - void RS485_Turnaround_Delay( - void); - uint32_t RS485_Get_Baud_Rate( - void); - bool RS485_Set_Baud_Rate( - uint32_t baud); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ #endif diff --git a/src/arf.c b/src/bacnet/arf.c similarity index 67% rename from src/arf.c rename to src/bacnet/arf.c index eb7cc939..b0e30eaa 100644 --- a/src/arf.c +++ b/src/bacnet/arf.c @@ -32,16 +32,16 @@ ------------------------------------------- ####COPYRIGHTEND####*/ #include -#include "bacenum.h" -#include "bacdcode.h" -#include "bacdef.h" -#include "arf.h" +#include "bacnet/bacenum.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacdef.h" +#include "bacnet/arf.h" /** @file arf.c Atomic Read File */ /* encode service */ -int arf_encode_apdu(uint8_t *apdu, uint8_t invoke_id, - BACNET_ATOMIC_READ_FILE_DATA *data) +int arf_encode_apdu( + uint8_t *apdu, uint8_t invoke_id, BACNET_ATOMIC_READ_FILE_DATA *data) { int apdu_len = 0; /* total length of the apdu, return value */ @@ -79,8 +79,8 @@ int arf_encode_apdu(uint8_t *apdu, uint8_t invoke_id, } /* decode the service request only */ -int arf_decode_service_request(uint8_t *apdu, unsigned apdu_len, - BACNET_ATOMIC_READ_FILE_DATA *data) +int arf_decode_service_request( + uint8_t *apdu, unsigned apdu_len, BACNET_ATOMIC_READ_FILE_DATA *data) { int len = 0; int tag_len = 0; @@ -92,8 +92,9 @@ int arf_decode_service_request(uint8_t *apdu, unsigned apdu_len, if (apdu_len && data) { len = decode_tag_number_and_value(&apdu[0], &tag_number, &len_value_type); - if (tag_number != BACNET_APPLICATION_TAG_OBJECT_ID) + if (tag_number != BACNET_APPLICATION_TAG_OBJECT_ID) { return -1; + } len += decode_object_id(&apdu[len], &type, &data->object_instance); data->object_type = (BACNET_OBJECT_TYPE)type; if (decode_is_opening_tag_number(&apdu[len], 0)) { @@ -101,23 +102,26 @@ int arf_decode_service_request(uint8_t *apdu, unsigned apdu_len, /* a tag number is not extended so only one octet */ len++; /* fileStartPosition */ - tag_len = decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value_type); + tag_len = decode_tag_number_and_value( + &apdu[len], &tag_number, &len_value_type); len += tag_len; - if (tag_number != BACNET_APPLICATION_TAG_SIGNED_INT) + if (tag_number != BACNET_APPLICATION_TAG_SIGNED_INT) { return -1; + } len += decode_signed(&apdu[len], len_value_type, - &data->type.stream.fileStartPosition); + &data->type.stream.fileStartPosition); /* requestedOctetCount */ - tag_len = decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value_type); + tag_len = decode_tag_number_and_value( + &apdu[len], &tag_number, &len_value_type); len += tag_len; - if (tag_number != BACNET_APPLICATION_TAG_UNSIGNED_INT) + if (tag_number != BACNET_APPLICATION_TAG_UNSIGNED_INT) { return -1; + } len += decode_unsigned(&apdu[len], len_value_type, - &data->type.stream.requestedOctetCount); - if (!decode_is_closing_tag_number(&apdu[len], 0)) + &data->type.stream.requestedOctetCount); + if (!decode_is_closing_tag_number(&apdu[len], 0)) { return -1; + } /* a tag number is not extended so only one octet */ len++; } else if (decode_is_opening_tag_number(&apdu[len], 1)) { @@ -125,47 +129,56 @@ int arf_decode_service_request(uint8_t *apdu, unsigned apdu_len, /* a tag number is not extended so only one octet */ len++; /* fileStartRecord */ - tag_len = decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value_type); + tag_len = decode_tag_number_and_value( + &apdu[len], &tag_number, &len_value_type); len += tag_len; - if (tag_number != BACNET_APPLICATION_TAG_SIGNED_INT) + if (tag_number != BACNET_APPLICATION_TAG_SIGNED_INT) { return -1; - len += decode_signed(&apdu[len], len_value_type, - &data->type.record.fileStartRecord); + } + len += decode_signed( + &apdu[len], len_value_type, &data->type.record.fileStartRecord); /* RecordCount */ - tag_len = decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value_type); + tag_len = decode_tag_number_and_value( + &apdu[len], &tag_number, &len_value_type); len += tag_len; - if (tag_number != BACNET_APPLICATION_TAG_UNSIGNED_INT) + if (tag_number != BACNET_APPLICATION_TAG_UNSIGNED_INT) { return -1; - len += decode_unsigned(&apdu[len], len_value_type, - &data->type.record.RecordCount); - if (!decode_is_closing_tag_number(&apdu[len], 1)) + } + len += decode_unsigned( + &apdu[len], len_value_type, &data->type.record.RecordCount); + if (!decode_is_closing_tag_number(&apdu[len], 1)) { return -1; + } /* a tag number is not extended so only one octet */ len++; - } else + } else { return -1; + } } return len; } -int arf_decode_apdu(uint8_t *apdu, unsigned apdu_len, uint8_t *invoke_id, - BACNET_ATOMIC_READ_FILE_DATA *data) +int arf_decode_apdu(uint8_t *apdu, + unsigned apdu_len, + uint8_t *invoke_id, + BACNET_ATOMIC_READ_FILE_DATA *data) { int len = 0; unsigned offset = 0; - if (!apdu) + if (!apdu) { return -1; + } /* optional checking - most likely was already done prior to this call */ - if (apdu[0] != PDU_TYPE_CONFIRMED_SERVICE_REQUEST) + if (apdu[0] != PDU_TYPE_CONFIRMED_SERVICE_REQUEST) { return -1; + } /* apdu[1] = encode_max_segs_max_apdu(0, MAX_APDU); */ *invoke_id = apdu[2]; /* invoke id - filled in by net layer */ - if (apdu[3] != SERVICE_CONFIRMED_ATOMIC_READ_FILE) + if (apdu[3] != SERVICE_CONFIRMED_ATOMIC_READ_FILE) { return -1; + } offset = 4; if (apdu_len > offset) { @@ -177,8 +190,8 @@ int arf_decode_apdu(uint8_t *apdu, unsigned apdu_len, uint8_t *invoke_id, } /* encode service */ -int arf_ack_encode_apdu(uint8_t *apdu, uint8_t invoke_id, - BACNET_ATOMIC_READ_FILE_DATA *data) +int arf_ack_encode_apdu( + uint8_t *apdu, uint8_t invoke_id, BACNET_ATOMIC_READ_FILE_DATA *data) { int apdu_len = 0; /* total length of the apdu, return value */ uint32_t i = 0; @@ -196,8 +209,8 @@ int arf_ack_encode_apdu(uint8_t *apdu, uint8_t invoke_id, apdu_len += encode_opening_tag(&apdu[apdu_len], 0); apdu_len += encode_application_signed( &apdu[apdu_len], data->type.stream.fileStartPosition); - apdu_len += encode_application_octet_string(&apdu[apdu_len], - &data->fileData[0]); + apdu_len += encode_application_octet_string( + &apdu[apdu_len], &data->fileData[0]); apdu_len += encode_closing_tag(&apdu[apdu_len], 0); break; case FILE_RECORD_ACCESS: @@ -221,8 +234,8 @@ int arf_ack_encode_apdu(uint8_t *apdu, uint8_t invoke_id, } /* decode the service request only */ -int arf_ack_decode_service_request(uint8_t *apdu, unsigned apdu_len, - BACNET_ATOMIC_READ_FILE_DATA *data) +int arf_ack_decode_service_request( + uint8_t *apdu, unsigned apdu_len, BACNET_ATOMIC_READ_FILE_DATA *data) { int len = 0; int tag_len = 0; @@ -244,23 +257,23 @@ int arf_ack_decode_service_request(uint8_t *apdu, unsigned apdu_len, /* a tag number is not extended so only one octet */ len++; /* fileStartPosition */ - tag_len = decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value_type); + tag_len = decode_tag_number_and_value( + &apdu[len], &tag_number, &len_value_type); len += tag_len; if (tag_number != BACNET_APPLICATION_TAG_SIGNED_INT) { return -1; } len += decode_signed(&apdu[len], len_value_type, - &data->type.stream.fileStartPosition); + &data->type.stream.fileStartPosition); /* fileData */ - tag_len = decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value_type); + tag_len = decode_tag_number_and_value( + &apdu[len], &tag_number, &len_value_type); len += tag_len; if (tag_number != BACNET_APPLICATION_TAG_OCTET_STRING) { return -1; } - decoded_len = decode_octet_string(&apdu[len], len_value_type, - &data->fileData[0]); + decoded_len = decode_octet_string( + &apdu[len], len_value_type, &data->fileData[0]); if ((uint32_t)decoded_len != len_value_type) { return -1; } @@ -275,33 +288,33 @@ int arf_ack_decode_service_request(uint8_t *apdu, unsigned apdu_len, /* a tag number is not extended so only one octet */ len++; /* fileStartRecord */ - tag_len = decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value_type); + tag_len = decode_tag_number_and_value( + &apdu[len], &tag_number, &len_value_type); len += tag_len; if (tag_number != BACNET_APPLICATION_TAG_SIGNED_INT) { return -1; } - len += decode_signed(&apdu[len], len_value_type, - &data->type.record.fileStartRecord); + len += decode_signed( + &apdu[len], len_value_type, &data->type.record.fileStartRecord); /* returnedRecordCount */ - tag_len = decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value_type); + tag_len = decode_tag_number_and_value( + &apdu[len], &tag_number, &len_value_type); len += tag_len; if (tag_number != BACNET_APPLICATION_TAG_UNSIGNED_INT) { return -1; } - len += decode_unsigned(&apdu[len], len_value_type, - &data->type.record.RecordCount); + len += decode_unsigned( + &apdu[len], len_value_type, &data->type.record.RecordCount); for (i = 0; i < data->type.record.RecordCount; i++) { /* fileData */ - tag_len = decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value_type); + tag_len = decode_tag_number_and_value( + &apdu[len], &tag_number, &len_value_type); len += tag_len; if (tag_number != BACNET_APPLICATION_TAG_OCTET_STRING) { return -1; } - decoded_len = decode_octet_string(&apdu[len], len_value_type, - &data->fileData[i]); + decoded_len = decode_octet_string( + &apdu[len], len_value_type, &data->fileData[i]); if ((uint32_t)decoded_len != len_value_type) { return -1; } @@ -320,25 +333,30 @@ int arf_ack_decode_service_request(uint8_t *apdu, unsigned apdu_len, return len; } -int arf_ack_decode_apdu(uint8_t *apdu, unsigned apdu_len, uint8_t *invoke_id, - BACNET_ATOMIC_READ_FILE_DATA *data) +int arf_ack_decode_apdu(uint8_t *apdu, + unsigned apdu_len, + uint8_t *invoke_id, + BACNET_ATOMIC_READ_FILE_DATA *data) { int len = 0; unsigned offset = 0; - if (!apdu) + if (!apdu) { return -1; + } /* optional checking - most likely was already done prior to this call */ - if (apdu[0] != PDU_TYPE_COMPLEX_ACK) + if (apdu[0] != PDU_TYPE_COMPLEX_ACK) { return -1; + } *invoke_id = apdu[1]; /* invoke id - filled in by net layer */ - if (apdu[2] != SERVICE_CONFIRMED_ATOMIC_READ_FILE) + if (apdu[2] != SERVICE_CONFIRMED_ATOMIC_READ_FILE) { return -1; + } offset = 3; if (apdu_len > offset) { - len = arf_ack_decode_service_request(&apdu[offset], apdu_len - offset, - data); + len = arf_ack_decode_service_request( + &apdu[offset], apdu_len - offset, data); } return len; @@ -349,11 +367,11 @@ int arf_ack_decode_apdu(uint8_t *apdu, unsigned apdu_len, uint8_t *invoke_id, #include #include "ctest.h" -void testAtomicReadFileAckAccess(Test *pTest, - BACNET_ATOMIC_READ_FILE_DATA *data) +void testAtomicReadFileAckAccess( + Test *pTest, BACNET_ATOMIC_READ_FILE_DATA *data) { - BACNET_ATOMIC_READ_FILE_DATA test_data = {0}; - uint8_t apdu[480] = {0}; + BACNET_ATOMIC_READ_FILE_DATA test_data = { 0 }; + uint8_t apdu[480] = { 0 }; int len = 0; int apdu_len = 0; uint8_t invoke_id = 128; @@ -369,40 +387,45 @@ void testAtomicReadFileAckAccess(Test *pTest, ct_test(pTest, test_data.endOfFile == data->endOfFile); ct_test(pTest, test_data.access == data->access); if (test_data.access == FILE_STREAM_ACCESS) { - ct_test(pTest, test_data.type.stream.fileStartPosition == - data->type.stream.fileStartPosition); - ct_test(pTest, octetstring_length(&test_data.fileData[0]) == - octetstring_length(&data->fileData[0])); - ct_test(pTest, memcmp(octetstring_value(&test_data.fileData[0]), - octetstring_value(&data->fileData[0]), - octetstring_length(&test_data.fileData[0])) == 0); + ct_test(pTest, + test_data.type.stream.fileStartPosition == + data->type.stream.fileStartPosition); + ct_test(pTest, + octetstring_length(&test_data.fileData[0]) == + octetstring_length(&data->fileData[0])); + ct_test(pTest, + memcmp(octetstring_value(&test_data.fileData[0]), + octetstring_value(&data->fileData[0]), + octetstring_length(&test_data.fileData[0])) == 0); } else if (test_data.access == FILE_RECORD_ACCESS) { - ct_test(pTest, test_data.type.record.fileStartRecord == - data->type.record.fileStartRecord); - ct_test(pTest, test_data.type.record.RecordCount == - data->type.record.RecordCount); + ct_test(pTest, + test_data.type.record.fileStartRecord == + data->type.record.fileStartRecord); + ct_test(pTest, + test_data.type.record.RecordCount == data->type.record.RecordCount); for (i = 0; i < data->type.record.RecordCount; i++) { - ct_test(pTest, octetstring_length(&test_data.fileData[i]) == - octetstring_length(&data->fileData[i])); ct_test(pTest, - memcmp(octetstring_value(&test_data.fileData[i]), - octetstring_value(&data->fileData[i]), - octetstring_length(&test_data.fileData[i])) == 0); + octetstring_length(&test_data.fileData[i]) == + octetstring_length(&data->fileData[i])); + ct_test(pTest, + memcmp(octetstring_value(&test_data.fileData[i]), + octetstring_value(&data->fileData[i]), + octetstring_length(&test_data.fileData[i])) == 0); } } } void testAtomicReadFileAck(Test *pTest) { - BACNET_ATOMIC_READ_FILE_DATA data = {0}; + BACNET_ATOMIC_READ_FILE_DATA data = { 0 }; uint8_t test_octet_string[32] = "Joshua-Mary-Anna-Christopher"; unsigned int i = 0; data.endOfFile = true; data.access = FILE_STREAM_ACCESS; data.type.stream.fileStartPosition = 0; - octetstring_init(&data.fileData[0], test_octet_string, - sizeof(test_octet_string)); + octetstring_init( + &data.fileData[0], test_octet_string, sizeof(test_octet_string)); testAtomicReadFileAckAccess(pTest, &data); data.endOfFile = false; @@ -410,8 +433,8 @@ void testAtomicReadFileAck(Test *pTest) data.type.record.fileStartRecord = 1; data.type.record.RecordCount = BACNET_READ_FILE_RECORD_COUNT; for (i = 0; i < data.type.record.RecordCount; i++) { - octetstring_init(&data.fileData[i], test_octet_string, - sizeof(test_octet_string)); + octetstring_init( + &data.fileData[i], test_octet_string, sizeof(test_octet_string)); } testAtomicReadFileAckAccess(pTest, &data); @@ -420,8 +443,8 @@ void testAtomicReadFileAck(Test *pTest) void testAtomicReadFileAccess(Test *pTest, BACNET_ATOMIC_READ_FILE_DATA *data) { - BACNET_ATOMIC_READ_FILE_DATA test_data = {0}; - uint8_t apdu[480] = {0}; + BACNET_ATOMIC_READ_FILE_DATA test_data = { 0 }; + uint8_t apdu[480] = { 0 }; int len = 0; int apdu_len = 0; uint8_t invoke_id = 128; @@ -437,21 +460,24 @@ void testAtomicReadFileAccess(Test *pTest, BACNET_ATOMIC_READ_FILE_DATA *data) ct_test(pTest, test_data.object_instance == data->object_instance); ct_test(pTest, test_data.access == data->access); if (test_data.access == FILE_STREAM_ACCESS) { - ct_test(pTest, test_data.type.stream.fileStartPosition == - data->type.stream.fileStartPosition); - ct_test(pTest, test_data.type.stream.requestedOctetCount == - data->type.stream.requestedOctetCount); + ct_test(pTest, + test_data.type.stream.fileStartPosition == + data->type.stream.fileStartPosition); + ct_test(pTest, + test_data.type.stream.requestedOctetCount == + data->type.stream.requestedOctetCount); } else if (test_data.access == FILE_RECORD_ACCESS) { - ct_test(pTest, test_data.type.record.fileStartRecord == - data->type.record.fileStartRecord); - ct_test(pTest, test_data.type.record.RecordCount == - data->type.record.RecordCount); + ct_test(pTest, + test_data.type.record.fileStartRecord == + data->type.record.fileStartRecord); + ct_test(pTest, + test_data.type.record.RecordCount == data->type.record.RecordCount); } } void testAtomicReadFile(Test *pTest) { - BACNET_ATOMIC_READ_FILE_DATA data = {0}; + BACNET_ATOMIC_READ_FILE_DATA data = { 0 }; data.object_type = OBJECT_FILE; data.object_instance = 1; diff --git a/include/arf.h b/src/bacnet/arf.h similarity index 98% rename from include/arf.h rename to src/bacnet/arf.h index 1ff600f2..5ef13545 100644 --- a/include/arf.h +++ b/src/bacnet/arf.h @@ -26,8 +26,8 @@ #include #include -#include "bacdcode.h" -#include "bacstr.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacstr.h" #ifndef BACNET_READ_FILE_RECORD_COUNT #define BACNET_READ_FILE_RECORD_COUNT 1 diff --git a/src/assigned_access_rights.c b/src/bacnet/assigned_access_rights.c similarity index 79% rename from src/assigned_access_rights.c rename to src/bacnet/assigned_access_rights.c index 35495f33..a86e1c41 100644 --- a/src/assigned_access_rights.c +++ b/src/bacnet/assigned_access_rights.c @@ -22,34 +22,36 @@ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * *********************************************************************/ +#include +#include "bacnet/assigned_access_rights.h" +#include "bacnet/bacdcode.h" -#include "assigned_access_rights.h" -#include "bacdcode.h" - -int bacapp_encode_assigned_access_rights(uint8_t* apdu, - BACNET_ASSIGNED_ACCESS_RIGHTS* aar) +int bacapp_encode_assigned_access_rights( + uint8_t *apdu, BACNET_ASSIGNED_ACCESS_RIGHTS *aar) { int len; int apdu_len = 0; - len = bacapp_encode_context_device_obj_ref(&apdu[apdu_len], 0, - &aar->assigned_access_rights); - if (len < 0) + len = bacapp_encode_context_device_obj_ref( + &apdu[apdu_len], 0, &aar->assigned_access_rights); + if (len < 0) { return -1; - else + } else { apdu_len += len; + } len = encode_context_boolean(&apdu[apdu_len], 1, aar->enable); - if (len < 0) + if (len < 0) { return -1; - else + } else { apdu_len += len; + } return apdu_len; } int bacapp_encode_context_assigned_access_rights( - uint8_t* apdu, uint8_t tag, BACNET_ASSIGNED_ACCESS_RIGHTS* aar) + uint8_t *apdu, uint8_t tag, BACNET_ASSIGNED_ACCESS_RIGHTS *aar) { int len; int apdu_len = 0; @@ -66,8 +68,8 @@ int bacapp_encode_context_assigned_access_rights( return apdu_len; } -int bacapp_decode_assigned_access_rights(uint8_t* apdu, - BACNET_ASSIGNED_ACCESS_RIGHTS* aar) +int bacapp_decode_assigned_access_rights( + uint8_t *apdu, BACNET_ASSIGNED_ACCESS_RIGHTS *aar) { int len; int apdu_len = 0; @@ -75,27 +77,31 @@ int bacapp_decode_assigned_access_rights(uint8_t* apdu, if (decode_is_context_tag(&apdu[apdu_len], 0)) { len = bacapp_decode_context_device_obj_ref( &apdu[apdu_len], 0, &aar->assigned_access_rights); - if (len < 0) + if (len < 0) { return -1; - else + } else { apdu_len += len; - } else + } + } else { return -1; + } if (decode_is_context_tag(&apdu[apdu_len], 1)) { len = decode_context_boolean2(&apdu[apdu_len], 1, &aar->enable); - if (len < 0) + if (len < 0) { return -1; - else + } else { apdu_len += len; - } else + } + } else { return -1; + } return apdu_len; } int bacapp_decode_context_assigned_access_rights( - uint8_t* apdu, uint8_t tag, BACNET_ASSIGNED_ACCESS_RIGHTS* aar) + uint8_t *apdu, uint8_t tag, BACNET_ASSIGNED_ACCESS_RIGHTS *aar) { int len = 0; int section_length; diff --git a/include/assigned_access_rights.h b/src/bacnet/assigned_access_rights.h similarity index 95% rename from include/assigned_access_rights.h rename to src/bacnet/assigned_access_rights.h index 37bd9532..0a1d97ec 100644 --- a/include/assigned_access_rights.h +++ b/src/bacnet/assigned_access_rights.h @@ -28,9 +28,9 @@ #include #include -#include "bacdef.h" -#include "bacapp.h" -#include "bacdevobjpropref.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacapp.h" +#include "bacnet/bacdevobjpropref.h" typedef struct { BACNET_DEVICE_OBJECT_REFERENCE assigned_access_rights; diff --git a/src/authentication_factor.c b/src/bacnet/authentication_factor.c similarity index 81% rename from src/authentication_factor.c rename to src/bacnet/authentication_factor.c index 28b6ac0e..81ecb7ff 100644 --- a/src/authentication_factor.c +++ b/src/bacnet/authentication_factor.c @@ -22,39 +22,42 @@ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * *********************************************************************/ +#include +#include "bacnet/authentication_factor.h" +#include "bacnet/bacdcode.h" -#include "authentication_factor.h" -#include "bacdcode.h" - -int bacapp_encode_authentication_factor(uint8_t* apdu, - BACNET_AUTHENTICATION_FACTOR* af) +int bacapp_encode_authentication_factor( + uint8_t *apdu, BACNET_AUTHENTICATION_FACTOR *af) { int len; int apdu_len = 0; len = encode_context_enumerated(&apdu[apdu_len], 0, af->format_type); - if (len < 0) + if (len < 0) { return -1; - else + } else { apdu_len += len; + } len = encode_context_unsigned(&apdu[apdu_len], 1, af->format_class); - if (len < 0) + if (len < 0) { return -1; - else + } else { apdu_len += len; + } len = encode_context_octet_string(&apdu[apdu_len], 2, &af->value); - if (len < 0) + if (len < 0) { return -1; - else + } else { apdu_len += len; + } return apdu_len; } int bacapp_encode_context_authentication_factor( - uint8_t* apdu, uint8_t tag, BACNET_AUTHENTICATION_FACTOR* af) + uint8_t *apdu, uint8_t tag, BACNET_AUTHENTICATION_FACTOR *af) { int len; int apdu_len = 0; @@ -71,44 +74,50 @@ int bacapp_encode_context_authentication_factor( return apdu_len; } -int bacapp_decode_authentication_factor(uint8_t* apdu, - BACNET_AUTHENTICATION_FACTOR* af) +int bacapp_decode_authentication_factor( + uint8_t *apdu, BACNET_AUTHENTICATION_FACTOR *af) { int len; int apdu_len = 0; if (decode_is_context_tag(&apdu[apdu_len], 0)) { len = decode_context_enumerated(&apdu[apdu_len], 0, &af->format_type); - if (len < 0) + if (len < 0) { return -1; - else + } else { apdu_len += len; - } else + } + } else { return -1; + } if (decode_is_context_tag(&apdu[apdu_len], 1)) { len = decode_context_unsigned(&apdu[apdu_len], 1, &af->format_class); - if (len < 0) + if (len < 0) { return -1; - else + } else { apdu_len += len; - } else + } + } else { return -1; + } if (decode_is_context_tag(&apdu[apdu_len], 2)) { len = decode_context_octet_string(&apdu[apdu_len], 2, &af->value); - if (len < 0) + if (len < 0) { return -1; - else + } else { apdu_len += len; - } else + } + } else { return -1; + } return apdu_len; } int bacapp_decode_context_authentication_factor( - uint8_t* apdu, uint8_t tag, BACNET_AUTHENTICATION_FACTOR* af) + uint8_t *apdu, uint8_t tag, BACNET_AUTHENTICATION_FACTOR *af) { int len = 0; int section_length; diff --git a/include/authentication_factor.h b/src/bacnet/authentication_factor.h similarity index 97% rename from include/authentication_factor.h rename to src/bacnet/authentication_factor.h index b7d5e1c3..bc5409c5 100644 --- a/include/authentication_factor.h +++ b/src/bacnet/authentication_factor.h @@ -28,8 +28,8 @@ #include #include -#include "bacdef.h" -#include "bacapp.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacapp.h" typedef struct { BACNET_AUTHENTICATION_FACTOR_TYPE format_type; diff --git a/src/authentication_factor_format.c b/src/bacnet/authentication_factor_format.c similarity index 82% rename from src/authentication_factor_format.c rename to src/bacnet/authentication_factor_format.c index 69edb404..0c3ea724 100644 --- a/src/authentication_factor_format.c +++ b/src/bacnet/authentication_factor_format.c @@ -22,40 +22,43 @@ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * *********************************************************************/ - -#include "bacdcode.h" -#include "authentication_factor_format.h" +#include +#include "bacnet/bacdcode.h" +#include "bacnet/authentication_factor_format.h" int bacapp_encode_authentication_factor_format( - uint8_t* apdu, BACNET_AUTHENTICATION_FACTOR_FORMAT* aff) + uint8_t *apdu, BACNET_AUTHENTICATION_FACTOR_FORMAT *aff) { int len; int apdu_len = 0; len = encode_context_enumerated(&apdu[apdu_len], 0, aff->format_type); - if (len < 0) + if (len < 0) { return -1; - else + } else { apdu_len += len; + } if (aff->format_type == AUTHENTICATION_FACTOR_CUSTOM) { len = encode_context_unsigned(&apdu[apdu_len], 1, aff->vendor_id); - if (len < 0) + if (len < 0) { return -1; - else + } else { apdu_len += len; + } len = encode_context_unsigned(&apdu[apdu_len], 2, aff->vendor_format); - if (len < 0) + if (len < 0) { return -1; - else + } else { apdu_len += len; + } } return apdu_len; } int bacapp_encode_context_authentication_factor_format( - uint8_t* apdu, uint8_t tag, BACNET_AUTHENTICATION_FACTOR_FORMAT* aff) + uint8_t *apdu, uint8_t tag, BACNET_AUTHENTICATION_FACTOR_FORMAT *aff) { int len; int apdu_len = 0; @@ -73,47 +76,53 @@ int bacapp_encode_context_authentication_factor_format( } int bacapp_decode_authentication_factor_format( - uint8_t* apdu, BACNET_AUTHENTICATION_FACTOR_FORMAT* aff) + uint8_t *apdu, BACNET_AUTHENTICATION_FACTOR_FORMAT *aff) { int len; int apdu_len = 0; if (decode_is_context_tag(&apdu[apdu_len], 0)) { len = decode_context_enumerated(&apdu[apdu_len], 0, &aff->format_type); - if (len < 0) + if (len < 0) { return -1; - else + } else { apdu_len += len; - } else + } + } else { return -1; + } if (decode_is_context_tag(&apdu[apdu_len], 1)) { len = decode_context_unsigned(&apdu[apdu_len], 1, &aff->vendor_id); - if (len < 0) + if (len < 0) { return -1; - else + } else { apdu_len += len; + } if ((aff->format_type != AUTHENTICATION_FACTOR_CUSTOM) && - (aff->vendor_id != 0)) + (aff->vendor_id != 0)) { return -1; + } } if (decode_is_context_tag(&apdu[apdu_len], 2)) { len = decode_context_unsigned(&apdu[apdu_len], 2, &aff->vendor_format); - if (len < 0) + if (len < 0) { return -1; - else + } else { apdu_len += len; + } if ((aff->format_type != AUTHENTICATION_FACTOR_CUSTOM) && - (aff->vendor_format != 0)) + (aff->vendor_format != 0)) { return -1; + } } return apdu_len; } int bacapp_decode_context_authentication_factor_format( - uint8_t* apdu, uint8_t tag, BACNET_AUTHENTICATION_FACTOR_FORMAT* aff) + uint8_t *apdu, uint8_t tag, BACNET_AUTHENTICATION_FACTOR_FORMAT *aff) { int len = 0; int section_length; diff --git a/include/authentication_factor_format.h b/src/bacnet/authentication_factor_format.h similarity index 98% rename from include/authentication_factor_format.h rename to src/bacnet/authentication_factor_format.h index 74227608..92b65b02 100644 --- a/include/authentication_factor_format.h +++ b/src/bacnet/authentication_factor_format.h @@ -28,7 +28,7 @@ #include #include -#include "bacdef.h" +#include "bacnet/bacdef.h" typedef struct { BACNET_AUTHENTICATION_FACTOR_TYPE format_type; diff --git a/src/awf.c b/src/bacnet/awf.c similarity index 70% rename from src/awf.c rename to src/bacnet/awf.c index 4d7e1bfd..91d8834d 100644 --- a/src/awf.c +++ b/src/bacnet/awf.c @@ -32,16 +32,16 @@ ------------------------------------------- ####COPYRIGHTEND####*/ #include -#include "bacenum.h" -#include "bacdcode.h" -#include "bacdef.h" -#include "awf.h" +#include "bacnet/bacenum.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacdef.h" +#include "bacnet/awf.h" /** @file awf.c Atomic Write File */ /* encode service */ -int awf_encode_apdu(uint8_t *apdu, uint8_t invoke_id, - BACNET_ATOMIC_WRITE_FILE_DATA *data) +int awf_encode_apdu( + uint8_t *apdu, uint8_t invoke_id, BACNET_ATOMIC_WRITE_FILE_DATA *data) { int apdu_len = 0; /* total length of the apdu, return value */ uint32_t i = 0; @@ -59,8 +59,8 @@ int awf_encode_apdu(uint8_t *apdu, uint8_t invoke_id, apdu_len += encode_opening_tag(&apdu[apdu_len], 0); apdu_len += encode_application_signed( &apdu[apdu_len], data->type.stream.fileStartPosition); - apdu_len += encode_application_octet_string(&apdu[apdu_len], - &data->fileData[0]); + apdu_len += encode_application_octet_string( + &apdu[apdu_len], &data->fileData[0]); apdu_len += encode_closing_tag(&apdu[apdu_len], 0); break; case FILE_RECORD_ACCESS: @@ -84,8 +84,8 @@ int awf_encode_apdu(uint8_t *apdu, uint8_t invoke_id, } /* decode the service request only */ -int awf_decode_service_request(uint8_t *apdu, unsigned apdu_len, - BACNET_ATOMIC_WRITE_FILE_DATA *data) +int awf_decode_service_request( + uint8_t *apdu, unsigned apdu_len, BACNET_ATOMIC_WRITE_FILE_DATA *data) { int len = 0; int tag_len = 0; @@ -101,8 +101,9 @@ int awf_decode_service_request(uint8_t *apdu, unsigned apdu_len, if (apdu_len && data) { len = decode_tag_number_and_value(&apdu[0], &tag_number, &len_value_type); - if (tag_number != BACNET_APPLICATION_TAG_OBJECT_ID) + if (tag_number != BACNET_APPLICATION_TAG_OBJECT_ID) { return -1; + } len += decode_object_id(&apdu[len], &type, &data->object_instance); data->object_type = (BACNET_OBJECT_TYPE)type; if (decode_is_opening_tag_number(&apdu[len], 0)) { @@ -110,27 +111,30 @@ int awf_decode_service_request(uint8_t *apdu, unsigned apdu_len, /* a tag number of 2 is not extended so only one octet */ len++; /* fileStartPosition */ - tag_len = decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value_type); + tag_len = decode_tag_number_and_value( + &apdu[len], &tag_number, &len_value_type); len += tag_len; - if (tag_number != BACNET_APPLICATION_TAG_SIGNED_INT) + if (tag_number != BACNET_APPLICATION_TAG_SIGNED_INT) { return -1; + } len += decode_signed(&apdu[len], len_value_type, &signed_value); data->type.stream.fileStartPosition = signed_value; /* fileData */ - tag_len = decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value_type); + tag_len = decode_tag_number_and_value( + &apdu[len], &tag_number, &len_value_type); len += tag_len; - if (tag_number != BACNET_APPLICATION_TAG_OCTET_STRING) + if (tag_number != BACNET_APPLICATION_TAG_OCTET_STRING) { return -1; - decoded_len = decode_octet_string(&apdu[len], len_value_type, - &data->fileData[0]); + } + decoded_len = decode_octet_string( + &apdu[len], len_value_type, &data->fileData[0]); if ((uint32_t)decoded_len != len_value_type) { return -1; } len += decoded_len; - if (!decode_is_closing_tag_number(&apdu[len], 0)) + if (!decode_is_closing_tag_number(&apdu[len], 0)) { return -1; + } /* a tag number is not extended so only one octet */ len++; } else if (decode_is_opening_tag_number(&apdu[len], 1)) { @@ -138,61 +142,71 @@ int awf_decode_service_request(uint8_t *apdu, unsigned apdu_len, /* a tag number is not extended so only one octet */ len++; /* fileStartRecord */ - tag_len = decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value_type); + tag_len = decode_tag_number_and_value( + &apdu[len], &tag_number, &len_value_type); len += tag_len; - if (tag_number != BACNET_APPLICATION_TAG_SIGNED_INT) + if (tag_number != BACNET_APPLICATION_TAG_SIGNED_INT) { return -1; + } len += decode_signed(&apdu[len], len_value_type, &signed_value); data->type.record.fileStartRecord = signed_value; /* returnedRecordCount */ - tag_len = decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value_type); + tag_len = decode_tag_number_and_value( + &apdu[len], &tag_number, &len_value_type); len += tag_len; - if (tag_number != BACNET_APPLICATION_TAG_UNSIGNED_INT) + if (tag_number != BACNET_APPLICATION_TAG_UNSIGNED_INT) { return -1; + } len += decode_unsigned(&apdu[len], len_value_type, &unsigned_value); data->type.record.returnedRecordCount = unsigned_value; /* fileData */ for (i = 0; i < data->type.record.returnedRecordCount; i++) { - tag_len = decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value_type); + tag_len = decode_tag_number_and_value( + &apdu[len], &tag_number, &len_value_type); len += tag_len; - if (tag_number != BACNET_APPLICATION_TAG_OCTET_STRING) + if (tag_number != BACNET_APPLICATION_TAG_OCTET_STRING) { return -1; - decoded_len = decode_octet_string(&apdu[len], len_value_type, - &data->fileData[i]); + } + decoded_len = decode_octet_string( + &apdu[len], len_value_type, &data->fileData[i]); if ((uint32_t)decoded_len != len_value_type) { return -1; } len += decoded_len; } - if (!decode_is_closing_tag_number(&apdu[len], 1)) + if (!decode_is_closing_tag_number(&apdu[len], 1)) { return -1; + } /* a tag number is not extended so only one octet */ len++; - } else + } else { return -1; + } } return len; } -int awf_decode_apdu(uint8_t *apdu, unsigned apdu_len, uint8_t *invoke_id, - BACNET_ATOMIC_WRITE_FILE_DATA *data) +int awf_decode_apdu(uint8_t *apdu, + unsigned apdu_len, + uint8_t *invoke_id, + BACNET_ATOMIC_WRITE_FILE_DATA *data) { int len = 0; unsigned offset = 0; - if (!apdu) + if (!apdu) { return -1; + } /* optional checking - most likely was already done prior to this call */ - if (apdu[0] != PDU_TYPE_CONFIRMED_SERVICE_REQUEST) + if (apdu[0] != PDU_TYPE_CONFIRMED_SERVICE_REQUEST) { return -1; + } /* apdu[1] = encode_max_segs_max_apdu(0, MAX_APDU); */ *invoke_id = apdu[2]; /* invoke id - filled in by net layer */ - if (apdu[3] != SERVICE_CONFIRMED_ATOMIC_WRITE_FILE) + if (apdu[3] != SERVICE_CONFIRMED_ATOMIC_WRITE_FILE) { return -1; + } offset = 4; if (apdu_len > offset) { @@ -203,8 +217,8 @@ int awf_decode_apdu(uint8_t *apdu, unsigned apdu_len, uint8_t *invoke_id, return len; } -int awf_ack_encode_apdu(uint8_t *apdu, uint8_t invoke_id, - BACNET_ATOMIC_WRITE_FILE_DATA *data) +int awf_ack_encode_apdu( + uint8_t *apdu, uint8_t invoke_id, BACNET_ATOMIC_WRITE_FILE_DATA *data) { int apdu_len = 0; /* total length of the apdu, return value */ @@ -231,8 +245,8 @@ int awf_ack_encode_apdu(uint8_t *apdu, uint8_t invoke_id, } /* decode the service request only */ -int awf_ack_decode_service_request(uint8_t *apdu, unsigned apdu_len, - BACNET_ATOMIC_WRITE_FILE_DATA *data) +int awf_ack_decode_service_request( + uint8_t *apdu, unsigned apdu_len, BACNET_ATOMIC_WRITE_FILE_DATA *data) { int len = 0; uint8_t tag_number = 0; @@ -245,37 +259,43 @@ int awf_ack_decode_service_request(uint8_t *apdu, unsigned apdu_len, if (tag_number == 0) { data->access = FILE_STREAM_ACCESS; len += decode_signed(&apdu[len], len_value_type, - &data->type.stream.fileStartPosition); + &data->type.stream.fileStartPosition); } else if (tag_number == 1) { data->access = FILE_RECORD_ACCESS; - len += decode_signed(&apdu[len], len_value_type, - &data->type.record.fileStartRecord); - } else + len += decode_signed( + &apdu[len], len_value_type, &data->type.record.fileStartRecord); + } else { return -1; + } } return len; } -int awf_ack_decode_apdu(uint8_t *apdu, unsigned apdu_len, uint8_t *invoke_id, - BACNET_ATOMIC_WRITE_FILE_DATA *data) +int awf_ack_decode_apdu(uint8_t *apdu, + unsigned apdu_len, + uint8_t *invoke_id, + BACNET_ATOMIC_WRITE_FILE_DATA *data) { int len = 0; unsigned offset = 0; - if (!apdu) + if (!apdu) { return -1; + } /* optional checking - most likely was already done prior to this call */ - if (apdu[0] != PDU_TYPE_COMPLEX_ACK) + if (apdu[0] != PDU_TYPE_COMPLEX_ACK) { return -1; + } *invoke_id = apdu[1]; /* invoke id - filled in by net layer */ - if (apdu[2] != SERVICE_CONFIRMED_ATOMIC_WRITE_FILE) + if (apdu[2] != SERVICE_CONFIRMED_ATOMIC_WRITE_FILE) { return -1; + } offset = 3; if (apdu_len > offset) { - len = awf_ack_decode_service_request(&apdu[offset], apdu_len - offset, - data); + len = awf_ack_decode_service_request( + &apdu[offset], apdu_len - offset, data); } return len; @@ -288,8 +308,8 @@ int awf_ack_decode_apdu(uint8_t *apdu, unsigned apdu_len, uint8_t *invoke_id, void testAtomicWriteFileAccess(Test *pTest, BACNET_ATOMIC_WRITE_FILE_DATA *data) { - BACNET_ATOMIC_WRITE_FILE_DATA test_data = {0}; - uint8_t apdu[480] = {0}; + BACNET_ATOMIC_WRITE_FILE_DATA test_data = { 0 }; + uint8_t apdu[480] = { 0 }; int len = 0; int apdu_len = 0; uint8_t invoke_id = 128; @@ -305,32 +325,37 @@ void testAtomicWriteFileAccess(Test *pTest, BACNET_ATOMIC_WRITE_FILE_DATA *data) ct_test(pTest, test_data.object_instance == data->object_instance); ct_test(pTest, test_data.access == data->access); if (test_data.access == FILE_STREAM_ACCESS) { - ct_test(pTest, test_data.type.stream.fileStartPosition == - data->type.stream.fileStartPosition); + ct_test(pTest, + test_data.type.stream.fileStartPosition == + data->type.stream.fileStartPosition); } else if (test_data.access == FILE_RECORD_ACCESS) { - ct_test(pTest, test_data.type.record.fileStartRecord == - data->type.record.fileStartRecord); - ct_test(pTest, test_data.type.record.returnedRecordCount == - data->type.record.returnedRecordCount); + ct_test(pTest, + test_data.type.record.fileStartRecord == + data->type.record.fileStartRecord); + ct_test(pTest, + test_data.type.record.returnedRecordCount == + data->type.record.returnedRecordCount); } - ct_test(pTest, octetstring_length(&test_data.fileData[0]) == - octetstring_length(&data->fileData[0])); - ct_test(pTest, memcmp(octetstring_value(&test_data.fileData[0]), - octetstring_value(&data->fileData[0]), - octetstring_length(&test_data.fileData[0])) == 0); + ct_test(pTest, + octetstring_length(&test_data.fileData[0]) == + octetstring_length(&data->fileData[0])); + ct_test(pTest, + memcmp(octetstring_value(&test_data.fileData[0]), + octetstring_value(&data->fileData[0]), + octetstring_length(&test_data.fileData[0])) == 0); } void testAtomicWriteFile(Test *pTest) { - BACNET_ATOMIC_WRITE_FILE_DATA data = {0}; + BACNET_ATOMIC_WRITE_FILE_DATA data = { 0 }; uint8_t test_octet_string[32] = "Joshua-Mary-Anna-Christopher"; data.object_type = OBJECT_FILE; data.object_instance = 1; data.access = FILE_STREAM_ACCESS; data.type.stream.fileStartPosition = 0; - octetstring_init(&data.fileData[0], test_octet_string, - sizeof(test_octet_string)); + octetstring_init( + &data.fileData[0], test_octet_string, sizeof(test_octet_string)); testAtomicWriteFileAccess(pTest, &data); data.object_type = OBJECT_FILE; @@ -338,18 +363,18 @@ void testAtomicWriteFile(Test *pTest) data.access = FILE_RECORD_ACCESS; data.type.record.fileStartRecord = 1; data.type.record.returnedRecordCount = 1; - octetstring_init(&data.fileData[0], test_octet_string, - sizeof(test_octet_string)); + octetstring_init( + &data.fileData[0], test_octet_string, sizeof(test_octet_string)); testAtomicWriteFileAccess(pTest, &data); return; } -void testAtomicWriteFileAckAccess(Test *pTest, - BACNET_ATOMIC_WRITE_FILE_DATA *data) +void testAtomicWriteFileAckAccess( + Test *pTest, BACNET_ATOMIC_WRITE_FILE_DATA *data) { - BACNET_ATOMIC_WRITE_FILE_DATA test_data = {0}; - uint8_t apdu[480] = {0}; + BACNET_ATOMIC_WRITE_FILE_DATA test_data = { 0 }; + uint8_t apdu[480] = { 0 }; int len = 0; int apdu_len = 0; uint8_t invoke_id = 128; @@ -363,17 +388,19 @@ void testAtomicWriteFileAckAccess(Test *pTest, ct_test(pTest, len != -1); ct_test(pTest, test_data.access == data->access); if (test_data.access == FILE_STREAM_ACCESS) { - ct_test(pTest, test_data.type.stream.fileStartPosition == - data->type.stream.fileStartPosition); + ct_test(pTest, + test_data.type.stream.fileStartPosition == + data->type.stream.fileStartPosition); } else if (test_data.access == FILE_RECORD_ACCESS) { - ct_test(pTest, test_data.type.record.fileStartRecord == - data->type.record.fileStartRecord); + ct_test(pTest, + test_data.type.record.fileStartRecord == + data->type.record.fileStartRecord); } } void testAtomicWriteFileAck(Test *pTest) { - BACNET_ATOMIC_WRITE_FILE_DATA data = {0}; + BACNET_ATOMIC_WRITE_FILE_DATA data = { 0 }; data.access = FILE_STREAM_ACCESS; data.type.stream.fileStartPosition = 42; diff --git a/include/awf.h b/src/bacnet/awf.h similarity index 99% rename from include/awf.h rename to src/bacnet/awf.h index 971e9fa0..ccdfc803 100644 --- a/include/awf.h +++ b/src/bacnet/awf.h @@ -26,7 +26,7 @@ #include #include -#include "bacdcode.h" +#include "bacnet/bacdcode.h" #ifndef BACNET_WRITE_FILE_RECORD_COUNT #define BACNET_WRITE_FILE_RECORD_COUNT 1 diff --git a/src/bacaddr.c b/src/bacnet/bacaddr.c similarity index 79% rename from src/bacaddr.c rename to src/bacnet/bacaddr.c index dce11874..b3c72a34 100644 --- a/src/bacaddr.c +++ b/src/bacnet/bacaddr.c @@ -34,13 +34,13 @@ #include #include #include -#include "config.h" -#include "bacdef.h" -#include "bacaddr.h" +#include "bacnet/config.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacaddr.h" /** @file bacaddr.c BACnet Address structure utilities */ -void bacnet_address_copy(BACNET_ADDRESS* dest, BACNET_ADDRESS* src) +void bacnet_address_copy(BACNET_ADDRESS *dest, BACNET_ADDRESS *src) { int i = 0; @@ -57,36 +57,44 @@ void bacnet_address_copy(BACNET_ADDRESS* dest, BACNET_ADDRESS* src) } } -bool bacnet_address_same(BACNET_ADDRESS* dest, BACNET_ADDRESS* src) +bool bacnet_address_same(BACNET_ADDRESS *dest, BACNET_ADDRESS *src) { - uint8_t i = 0; /* loop counter */ + uint8_t i = 0; /* loop counter */ uint8_t max_len = 0; /* used for dynamic max */ - if (dest == src) /* same ? */ + if (dest == src) { /* same ? */ return true; + } - if (dest->net != src->net) + if (dest->net != src->net) { return false; + } - if (dest->len != src->len) + if (dest->len != src->len) { return false; + } max_len = dest->len; - if (max_len > MAX_MAC_LEN) + if (max_len > MAX_MAC_LEN) { max_len = MAX_MAC_LEN; + } for (i = 0; i < max_len; i++) { - if (dest->adr[i] != src->adr[i]) + if (dest->adr[i] != src->adr[i]) { return false; + } } if (dest->net == 0) { - if (dest->mac_len != src->mac_len) + if (dest->mac_len != src->mac_len) { return false; + } max_len = dest->mac_len; - if (max_len > MAX_MAC_LEN) + if (max_len > MAX_MAC_LEN) { max_len = MAX_MAC_LEN; + } for (i = 0; i < max_len; i++) { - if (dest->mac[i] != src->mac[i]) + if (dest->mac[i] != src->mac[i]) { return false; + } } } return true; diff --git a/include/bacaddr.h b/src/bacnet/bacaddr.h similarity index 98% rename from include/bacaddr.h rename to src/bacnet/bacaddr.h index 6f43c48f..8da43c9e 100644 --- a/include/bacaddr.h +++ b/src/bacnet/bacaddr.h @@ -27,7 +27,7 @@ #include #include #include -#include "bacdef.h" +#include "bacnet/bacdef.h" #ifdef __cplusplus extern "C" { diff --git a/src/bacapp.c b/src/bacnet/bacapp.c similarity index 79% rename from src/bacapp.c rename to src/bacnet/bacapp.c index a457c884..d6ad88a0 100644 --- a/src/bacapp.c +++ b/src/bacnet/bacapp.c @@ -37,16 +37,16 @@ #include #include #include -#include "bacenum.h" -#include "bacdcode.h" -#include "bacint.h" -#include "bacreal.h" -#include "bacdef.h" -#include "bacapp.h" -#include "bactext.h" -#include "datetime.h" -#include "bacstr.h" -#include "lighting.h" +#include "bacnet/bacenum.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacint.h" +#include "bacnet/bacreal.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacapp.h" +#include "bacnet/bactext.h" +#include "bacnet/datetime.h" +#include "bacnet/bacstr.h" +#include "bacnet/lighting.h" /** @file bacapp.c Utilities for the BACnet_Application_Data_Value */ @@ -54,8 +54,8 @@ #define snprintf _snprintf #endif -int bacapp_encode_application_data(uint8_t *apdu, - BACNET_APPLICATION_DATA_VALUE *value) +int bacapp_encode_application_data( + uint8_t *apdu, BACNET_APPLICATION_DATA_VALUE *value) { int apdu_len = 0; /* total length of the apdu, return value */ @@ -132,8 +132,8 @@ int bacapp_encode_application_data(uint8_t *apdu, #endif #if defined(BACAPP_OBJECT_ID) case BACNET_APPLICATION_TAG_OBJECT_ID: - apdu_len = encode_application_object_id( - &apdu[0], (int)value->type.Object_Id.type, + apdu_len = encode_application_object_id(&apdu[0], + (int)value->type.Object_Id.type, value->type.Object_Id.instance); break; #endif @@ -160,9 +160,10 @@ int bacapp_encode_application_data(uint8_t *apdu, /* decode the data and store it into value. Return the number of octets consumed. */ -int bacapp_decode_data(uint8_t *apdu, uint8_t tag_data_type, - uint32_t len_value_type, - BACNET_APPLICATION_DATA_VALUE *value) +int bacapp_decode_data(uint8_t *apdu, + uint8_t tag_data_type, + uint32_t len_value_type, + BACNET_APPLICATION_DATA_VALUE *value) { int len = 0; @@ -180,78 +181,78 @@ int bacapp_decode_data(uint8_t *apdu, uint8_t tag_data_type, #endif #if defined(BACAPP_UNSIGNED) case BACNET_APPLICATION_TAG_UNSIGNED_INT: - len = decode_unsigned(&apdu[0], len_value_type, - &value->type.Unsigned_Int); + len = decode_unsigned( + &apdu[0], len_value_type, &value->type.Unsigned_Int); break; #endif #if defined(BACAPP_SIGNED) case BACNET_APPLICATION_TAG_SIGNED_INT: - len = decode_signed(&apdu[0], len_value_type, - &value->type.Signed_Int); + len = decode_signed( + &apdu[0], len_value_type, &value->type.Signed_Int); break; #endif #if defined(BACAPP_REAL) case BACNET_APPLICATION_TAG_REAL: - len = decode_real_safe(&apdu[0], len_value_type, - &(value->type.Real)); + len = decode_real_safe( + &apdu[0], len_value_type, &(value->type.Real)); break; #endif #if defined(BACAPP_DOUBLE) case BACNET_APPLICATION_TAG_DOUBLE: - len = decode_double_safe(&apdu[0], len_value_type, - &(value->type.Double)); + len = decode_double_safe( + &apdu[0], len_value_type, &(value->type.Double)); break; #endif #if defined(BACAPP_OCTET_STRING) case BACNET_APPLICATION_TAG_OCTET_STRING: - len = decode_octet_string(&apdu[0], len_value_type, - &value->type.Octet_String); + len = decode_octet_string( + &apdu[0], len_value_type, &value->type.Octet_String); break; #endif #if defined(BACAPP_CHARACTER_STRING) case BACNET_APPLICATION_TAG_CHARACTER_STRING: - len = decode_character_string(&apdu[0], len_value_type, - &value->type.Character_String); + len = decode_character_string( + &apdu[0], len_value_type, &value->type.Character_String); break; #endif #if defined(BACAPP_BIT_STRING) case BACNET_APPLICATION_TAG_BIT_STRING: - len = decode_bitstring(&apdu[0], len_value_type, - &value->type.Bit_String); + len = decode_bitstring( + &apdu[0], len_value_type, &value->type.Bit_String); break; #endif #if defined(BACAPP_ENUMERATED) case BACNET_APPLICATION_TAG_ENUMERATED: - len = decode_enumerated(&apdu[0], len_value_type, - &value->type.Enumerated); + len = decode_enumerated( + &apdu[0], len_value_type, &value->type.Enumerated); break; #endif #if defined(BACAPP_DATE) case BACNET_APPLICATION_TAG_DATE: - len = decode_date_safe(&apdu[0], len_value_type, - &value->type.Date); + len = decode_date_safe( + &apdu[0], len_value_type, &value->type.Date); break; #endif #if defined(BACAPP_TIME) case BACNET_APPLICATION_TAG_TIME: - len = decode_bacnet_time_safe(&apdu[0], len_value_type, - &value->type.Time); + len = decode_bacnet_time_safe( + &apdu[0], len_value_type, &value->type.Time); break; #endif #if defined(BACAPP_OBJECT_ID) case BACNET_APPLICATION_TAG_OBJECT_ID: { uint16_t object_type = 0; uint32_t instance = 0; - len = decode_object_id_safe(&apdu[0], len_value_type, - &object_type, &instance); + len = decode_object_id_safe( + &apdu[0], len_value_type, &object_type, &instance); value->type.Object_Id.type = object_type; value->type.Object_Id.instance = instance; } break; #endif #if defined(BACAPP_LIGHTING_COMMAND) case BACNET_APPLICATION_TAG_LIGHTING_COMMAND: - len = lighting_command_decode(&apdu[0], len_value_type, - &value->type.Lighting_Command); + len = lighting_command_decode( + &apdu[0], len_value_type, &value->type.Lighting_Command); break; #endif default: @@ -270,8 +271,8 @@ int bacapp_decode_data(uint8_t *apdu, uint8_t tag_data_type, return len; } -int bacapp_decode_application_data(uint8_t *apdu, unsigned max_apdu_len, - BACNET_APPLICATION_DATA_VALUE *value) +int bacapp_decode_application_data( + uint8_t *apdu, unsigned max_apdu_len, BACNET_APPLICATION_DATA_VALUE *value) { int len = 0; int tag_len = 0; @@ -288,8 +289,8 @@ int bacapp_decode_application_data(uint8_t *apdu, unsigned max_apdu_len, if (tag_len) { len += tag_len; value->tag = tag_number; - decode_len = bacapp_decode_data(&apdu[len], tag_number, - len_value_type, value); + decode_len = bacapp_decode_data( + &apdu[len], tag_number, len_value_type, value); if (value->tag != MAX_BACNET_APPLICATION_TAG) { len += decode_len; } else { @@ -318,8 +319,8 @@ int bacapp_decode_application_data(uint8_t *apdu, unsigned max_apdu_len, */ bool bacapp_decode_application_data_safe(uint8_t *new_apdu, - uint32_t new_apdu_len, - BACNET_APPLICATION_DATA_VALUE *value) + uint32_t new_apdu_len, + BACNET_APPLICATION_DATA_VALUE *value) { /* The static variables that store the apdu buffer between function calls */ static uint8_t *apdu = NULL; @@ -353,8 +354,8 @@ bool bacapp_decode_application_data_safe(uint8_t *new_apdu, if (tag_number == BACNET_APPLICATION_TAG_BOOLEAN || len_value_type <= apdu_len_remaining) { value->tag = tag_number; - len = bacapp_decode_data(&apdu[apdu_len], tag_number, - len_value_type, value); + len = bacapp_decode_data( + &apdu[apdu_len], tag_number, len_value_type, value); apdu_len += len; apdu_len_remaining -= len; @@ -369,8 +370,8 @@ bool bacapp_decode_application_data_safe(uint8_t *new_apdu, /* Decode the data and return the number of octets consumed. */ -int bacapp_decode_data_len(uint8_t *apdu, uint8_t tag_data_type, - uint32_t len_value_type) +int bacapp_decode_data_len( + uint8_t *apdu, uint8_t tag_data_type, uint32_t len_value_type) { int len = 0; @@ -425,8 +426,9 @@ int bacapp_decode_application_data_len(uint8_t *apdu, unsigned max_apdu_len) return len; } -int bacapp_encode_context_data_value(uint8_t *apdu, uint8_t context_tag_number, - BACNET_APPLICATION_DATA_VALUE *value) +int bacapp_encode_context_data_value(uint8_t *apdu, + uint8_t context_tag_number, + BACNET_APPLICATION_DATA_VALUE *value) { int apdu_len = 0; /* total length of the apdu, return value */ @@ -439,32 +441,32 @@ int bacapp_encode_context_data_value(uint8_t *apdu, uint8_t context_tag_number, #endif #if defined(BACAPP_BOOLEAN) case BACNET_APPLICATION_TAG_BOOLEAN: - apdu_len = encode_context_boolean(&apdu[0], context_tag_number, - value->type.Boolean); + apdu_len = encode_context_boolean( + &apdu[0], context_tag_number, value->type.Boolean); break; #endif #if defined(BACAPP_UNSIGNED) case BACNET_APPLICATION_TAG_UNSIGNED_INT: - apdu_len = encode_context_unsigned(&apdu[0], context_tag_number, - value->type.Unsigned_Int); + apdu_len = encode_context_unsigned( + &apdu[0], context_tag_number, value->type.Unsigned_Int); break; #endif #if defined(BACAPP_SIGNED) case BACNET_APPLICATION_TAG_SIGNED_INT: - apdu_len = encode_context_signed(&apdu[0], context_tag_number, - value->type.Signed_Int); + apdu_len = encode_context_signed( + &apdu[0], context_tag_number, value->type.Signed_Int); break; #endif #if defined(BACAPP_REAL) case BACNET_APPLICATION_TAG_REAL: - apdu_len = encode_context_real(&apdu[0], context_tag_number, - value->type.Real); + apdu_len = encode_context_real( + &apdu[0], context_tag_number, value->type.Real); break; #endif #if defined(BACAPP_DOUBLE) case BACNET_APPLICATION_TAG_DOUBLE: - apdu_len = encode_context_double(&apdu[0], context_tag_number, - value->type.Double); + apdu_len = encode_context_double( + &apdu[0], context_tag_number, value->type.Double); break; #endif #if defined(BACAPP_OCTET_STRING) @@ -475,9 +477,8 @@ int bacapp_encode_context_data_value(uint8_t *apdu, uint8_t context_tag_number, #endif #if defined(BACAPP_CHARACTER_STRING) case BACNET_APPLICATION_TAG_CHARACTER_STRING: - apdu_len = encode_context_character_string( - &apdu[0], context_tag_number, - &value->type.Character_String); + apdu_len = encode_context_character_string(&apdu[0], + context_tag_number, &value->type.Character_String); break; #endif #if defined(BACAPP_BIT_STRING) @@ -494,29 +495,27 @@ int bacapp_encode_context_data_value(uint8_t *apdu, uint8_t context_tag_number, #endif #if defined(BACAPP_DATE) case BACNET_APPLICATION_TAG_DATE: - apdu_len = encode_context_date(&apdu[0], context_tag_number, - &value->type.Date); + apdu_len = encode_context_date( + &apdu[0], context_tag_number, &value->type.Date); break; #endif #if defined(BACAPP_TIME) case BACNET_APPLICATION_TAG_TIME: - apdu_len = encode_context_time(&apdu[0], context_tag_number, - &value->type.Time); + apdu_len = encode_context_time( + &apdu[0], context_tag_number, &value->type.Time); break; #endif #if defined(BACAPP_OBJECT_ID) case BACNET_APPLICATION_TAG_OBJECT_ID: - apdu_len = - encode_context_object_id(&apdu[0], context_tag_number, - (int)value->type.Object_Id.type, - value->type.Object_Id.instance); + apdu_len = encode_context_object_id(&apdu[0], + context_tag_number, (int)value->type.Object_Id.type, + value->type.Object_Id.instance); break; #endif #if defined(BACAPP_LIGHTING_COMMAND) case BACNET_APPLICATION_TAG_LIGHTING_COMMAND: - apdu_len = lighting_command_encode_context( - &apdu[0], context_tag_number, - &value->type.Lighting_Command); + apdu_len = lighting_command_encode_context(&apdu[0], + context_tag_number, &value->type.Lighting_Command); break; #endif default: @@ -528,8 +527,8 @@ int bacapp_encode_context_data_value(uint8_t *apdu, uint8_t context_tag_number, } /* returns the fixed tag type for certain context tagged properties */ -BACNET_APPLICATION_TAG bacapp_context_tag_type(BACNET_PROPERTY_ID property, - uint8_t tag_number) +BACNET_APPLICATION_TAG bacapp_context_tag_type( + BACNET_PROPERTY_ID property, uint8_t tag_number) { BACNET_APPLICATION_TAG tag = MAX_BACNET_APPLICATION_TAG; @@ -669,8 +668,8 @@ BACNET_APPLICATION_TAG bacapp_context_tag_type(BACNET_PROPERTY_ID property, } int bacapp_encode_context_data(uint8_t *apdu, - BACNET_APPLICATION_DATA_VALUE *value, - BACNET_PROPERTY_ID property) + BACNET_APPLICATION_DATA_VALUE *value, + BACNET_PROPERTY_ID property) { int apdu_len = 0; BACNET_APPLICATION_TAG tag_data_type; @@ -690,9 +689,10 @@ int bacapp_encode_context_data(uint8_t *apdu, return apdu_len; } -int bacapp_decode_context_data(uint8_t *apdu, unsigned max_apdu_len, - BACNET_APPLICATION_DATA_VALUE *value, - BACNET_PROPERTY_ID property) +int bacapp_decode_context_data(uint8_t *apdu, + unsigned max_apdu_len, + BACNET_APPLICATION_DATA_VALUE *value, + BACNET_PROPERTY_ID property) { int apdu_len = 0, len = 0; int tag_len = 0; @@ -711,8 +711,8 @@ int bacapp_decode_context_data(uint8_t *apdu, unsigned max_apdu_len, value->context_tag = tag_number; value->tag = bacapp_context_tag_type(property, tag_number); if (value->tag < MAX_BACNET_APPLICATION_TAG) { - len = bacapp_decode_data(&apdu[apdu_len], value->tag, - len_value_type, value); + len = bacapp_decode_data( + &apdu[apdu_len], value->tag, len_value_type, value); apdu_len += len; } else if (len_value_type) { /* Unknown value : non null size (elementary type) */ @@ -722,15 +722,16 @@ int bacapp_decode_context_data(uint8_t *apdu, unsigned max_apdu_len, } else { apdu_len = BACNET_STATUS_ERROR; } - } else if (tag_len == 1) /* and is a Closing tag */ - apdu_len = 0; /* Don't advance over that closing tag. */ + } else if (tag_len == 1) { /* and is a Closing tag */ + apdu_len = 0; /* Don't advance over that closing tag. */ + } } return apdu_len; } -int bacapp_decode_context_data_len(uint8_t *apdu, unsigned max_apdu_len, - BACNET_PROPERTY_ID property) +int bacapp_decode_context_data_len( + uint8_t *apdu, unsigned max_apdu_len, BACNET_PROPERTY_ID property) { int apdu_len = 0, len = 0; int tag_len = 0; @@ -747,8 +748,8 @@ int bacapp_decode_context_data_len(uint8_t *apdu, unsigned max_apdu_len, apdu_len = tag_len; tag = bacapp_context_tag_type(property, tag_number); if (tag < MAX_BACNET_APPLICATION_TAG) { - len = bacapp_decode_data_len(&apdu[apdu_len], tag, - len_value_type); + len = bacapp_decode_data_len( + &apdu[apdu_len], tag, len_value_type); apdu_len += len; } else { apdu_len += len_value_type; @@ -776,7 +777,7 @@ int bacapp_encode_data(uint8_t *apdu, BACNET_APPLICATION_DATA_VALUE *value) } bool bacapp_copy(BACNET_APPLICATION_DATA_VALUE *dest_value, - BACNET_APPLICATION_DATA_VALUE *src_value) + BACNET_APPLICATION_DATA_VALUE *src_value) { bool status = true; /*return value */ @@ -815,19 +816,19 @@ bool bacapp_copy(BACNET_APPLICATION_DATA_VALUE *dest_value, #if defined(BACAPP_OCTET_STRING) case BACNET_APPLICATION_TAG_OCTET_STRING: octetstring_copy(&dest_value->type.Octet_String, - &src_value->type.Octet_String); + &src_value->type.Octet_String); break; #endif #if defined(BACAPP_CHARACTER_STRING) case BACNET_APPLICATION_TAG_CHARACTER_STRING: characterstring_copy(&dest_value->type.Character_String, - &src_value->type.Character_String); + &src_value->type.Character_String); break; #endif #if defined(BACAPP_BIT_STRING) case BACNET_APPLICATION_TAG_BIT_STRING: - bitstring_copy(&dest_value->type.Bit_String, - &src_value->type.Bit_String); + bitstring_copy( + &dest_value->type.Bit_String, &src_value->type.Bit_String); break; #endif #if defined(BACAPP_ENUMERATED) @@ -837,14 +838,14 @@ bool bacapp_copy(BACNET_APPLICATION_DATA_VALUE *dest_value, #endif #if defined(BACAPP_DATE) case BACNET_APPLICATION_TAG_DATE: - datetime_copy_date(&dest_value->type.Date, - &src_value->type.Date); + datetime_copy_date( + &dest_value->type.Date, &src_value->type.Date); break; #endif #if defined(BACAPP_TIME) case BACNET_APPLICATION_TAG_TIME: - datetime_copy_time(&dest_value->type.Time, - &src_value->type.Time); + datetime_copy_time( + &dest_value->type.Time, &src_value->type.Time); break; #endif #if defined(BACAPP_OBJECT_ID) @@ -859,7 +860,7 @@ bool bacapp_copy(BACNET_APPLICATION_DATA_VALUE *dest_value, case BACNET_APPLICATION_TAG_LIGHTING_COMMAND: status = lighting_command_copy(&dest_value->type.Lighting_Command, - &src_value->type.Lighting_Command); + &src_value->type.Lighting_Command); break; #endif default: @@ -876,8 +877,8 @@ bool bacapp_copy(BACNET_APPLICATION_DATA_VALUE *dest_value, Expects that the first octet contain the opening tag. Include a value property identifier for context specific data such as the value received in a WriteProperty request */ -int bacapp_data_len(uint8_t *apdu, unsigned max_apdu_len, - BACNET_PROPERTY_ID property) +int bacapp_data_len( + uint8_t *apdu, unsigned max_apdu_len, BACNET_PROPERTY_ID property) { int len = 0; int total_len = 0; @@ -894,15 +895,17 @@ int bacapp_data_len(uint8_t *apdu, unsigned max_apdu_len, opening_tag_number_counter = 1; while (opening_tag_number_counter) { if (IS_OPENING_TAG(apdu[apdu_len])) { - len = decode_tag_number_and_value(&apdu[apdu_len], &tag_number, - &value); - if (tag_number == opening_tag_number) + len = decode_tag_number_and_value( + &apdu[apdu_len], &tag_number, &value); + if (tag_number == opening_tag_number) { opening_tag_number_counter++; + } } else if (IS_CLOSING_TAG(apdu[apdu_len])) { - len = decode_tag_number_and_value(&apdu[apdu_len], &tag_number, - &value); - if (tag_number == opening_tag_number) + len = decode_tag_number_and_value( + &apdu[apdu_len], &tag_number, &value); + if (tag_number == opening_tag_number) { opening_tag_number_counter--; + } } else if (IS_CONTEXT_SPECIFIC(apdu[apdu_len])) { /* context-specific tagged data */ len = bacapp_decode_context_data_len( @@ -962,8 +965,8 @@ static bool append_str(char **str, size_t *rem_str_len, const char *add_str) * to the output string. If output was truncated due to string size, * then the returned value is greater than str_len (a la snprintf() ). */ -int bacapp_snprintf_value(char *str, size_t str_len, - BACNET_OBJECT_PROPERTY_VALUE *object_value) +int bacapp_snprintf_value( + char *str, size_t str_len, BACNET_OBJECT_PROPERTY_VALUE *object_value) { size_t len = 0, i = 0; char *char_str; @@ -986,12 +989,12 @@ int bacapp_snprintf_value(char *str, size_t str_len, break; case BACNET_APPLICATION_TAG_BOOLEAN: ret_val = (value->type.Boolean) - ? snprintf(str, str_len, "TRUE") - : snprintf(str, str_len, "FALSE"); + ? snprintf(str, str_len, "TRUE") + : snprintf(str, str_len, "FALSE"); break; case BACNET_APPLICATION_TAG_UNSIGNED_INT: ret_val = snprintf(str, str_len, "%lu", - (unsigned long)value->type.Unsigned_Int); + (unsigned long)value->type.Unsigned_Int); break; case BACNET_APPLICATION_TAG_SIGNED_INT: ret_val = @@ -1047,9 +1050,9 @@ int bacapp_snprintf_value(char *str, size_t str_len, break; for (i = 0; i < len; i++) { snprintf(temp_str, sizeof(temp_str), "%s", - bitstring_bit(&value->type.Bit_String, (uint8_t)i) - ? "true" - : "false"); + bitstring_bit(&value->type.Bit_String, (uint8_t)i) + ? "true" + : "false"); if (!append_str(&p_str, &rem_str_len, temp_str)) break; if (i < len - 1) { @@ -1071,104 +1074,91 @@ int bacapp_snprintf_value(char *str, size_t str_len, if (char_str) { ret_val = snprintf(str, str_len, "%s", char_str); } else { - ret_val = - snprintf(str, str_len, "%lu", - (unsigned long)value->type.Enumerated); + ret_val = snprintf(str, str_len, "%lu", + (unsigned long)value->type.Enumerated); } break; case PROP_OBJECT_TYPE: if (value->type.Enumerated < MAX_ASHRAE_OBJECT_TYPE) { ret_val = snprintf(str, str_len, "%s", - bactext_object_type_name( - value->type.Enumerated)); + bactext_object_type_name( + value->type.Enumerated)); } else if (value->type.Enumerated < 128) { - ret_val = - snprintf(str, str_len, "reserved %lu", - (unsigned long)value->type.Enumerated); + ret_val = snprintf(str, str_len, "reserved %lu", + (unsigned long)value->type.Enumerated); } else { - ret_val = - snprintf(str, str_len, "proprietary %lu", - (unsigned long)value->type.Enumerated); + ret_val = snprintf(str, str_len, "proprietary %lu", + (unsigned long)value->type.Enumerated); } break; case PROP_EVENT_STATE: - ret_val = snprintf( - str, str_len, "%s", + ret_val = snprintf(str, str_len, "%s", bactext_event_state_name(value->type.Enumerated)); break; case PROP_UNITS: if (value->type.Enumerated < 256) { ret_val = snprintf(str, str_len, "%s", - bactext_engineering_unit_name( - value->type.Enumerated)); + bactext_engineering_unit_name( + value->type.Enumerated)); } else { - ret_val = - snprintf(str, str_len, "proprietary %lu", - (unsigned long)value->type.Enumerated); + ret_val = snprintf(str, str_len, "proprietary %lu", + (unsigned long)value->type.Enumerated); } break; case PROP_POLARITY: ret_val = snprintf(str, str_len, "%s", - bactext_binary_polarity_name( - value->type.Enumerated)); + bactext_binary_polarity_name( + value->type.Enumerated)); break; case PROP_PRESENT_VALUE: case PROP_RELINQUISH_DEFAULT: if (object_type < OBJECT_PROPRIETARY_MIN) { - ret_val = - snprintf(str, str_len, "%s", - bactext_binary_present_value_name( - value->type.Enumerated)); + ret_val = snprintf(str, str_len, "%s", + bactext_binary_present_value_name( + value->type.Enumerated)); } else { - ret_val = - snprintf(str, str_len, "%lu", - (unsigned long)value->type.Enumerated); + ret_val = snprintf(str, str_len, "%lu", + (unsigned long)value->type.Enumerated); } break; case PROP_RELIABILITY: - ret_val = snprintf( - str, str_len, "%s", + ret_val = snprintf(str, str_len, "%s", bactext_reliability_name(value->type.Enumerated)); break; case PROP_SYSTEM_STATUS: - ret_val = snprintf( - str, str_len, "%s", + ret_val = snprintf(str, str_len, "%s", bactext_device_status_name(value->type.Enumerated)); break; case PROP_SEGMENTATION_SUPPORTED: - ret_val = snprintf( - str, str_len, "%s", + ret_val = snprintf(str, str_len, "%s", bactext_segmentation_name(value->type.Enumerated)); break; case PROP_NODE_TYPE: - ret_val = snprintf( - str, str_len, "%s", + ret_val = snprintf(str, str_len, "%s", bactext_node_type_name(value->type.Enumerated)); break; default: - ret_val = - snprintf(str, str_len, "%lu", - (unsigned long)value->type.Enumerated); + ret_val = snprintf(str, str_len, "%lu", + (unsigned long)value->type.Enumerated); break; } break; case BACNET_APPLICATION_TAG_DATE: - if (!append_str( - &p_str, &rem_str_len, + if (!append_str(&p_str, &rem_str_len, bactext_day_of_week_name(value->type.Date.wday))) break; if (!append_str(&p_str, &rem_str_len, ", ")) break; if (!append_str(&p_str, &rem_str_len, - bactext_month_name(value->type.Date.month))) + bactext_month_name(value->type.Date.month))) break; if (value->type.Date.day == 255) { if (!append_str(&p_str, &rem_str_len, " (unspecified), ")) break; } else { snprintf(temp_str, sizeof(temp_str), " %u, ", - (unsigned)value->type.Date.day); + (unsigned)value->type.Date.day); if (!append_str(&p_str, &rem_str_len, temp_str)) break; } @@ -1177,7 +1167,7 @@ int bacapp_snprintf_value(char *str, size_t str_len, break; } else { snprintf(temp_str, sizeof(temp_str), "%u", - (unsigned)value->type.Date.year); + (unsigned)value->type.Date.year); if (!append_str(&p_str, &rem_str_len, temp_str)) break; } @@ -1191,7 +1181,7 @@ int bacapp_snprintf_value(char *str, size_t str_len, break; } else { snprintf(temp_str, sizeof(temp_str), - "%02u:", (unsigned)value->type.Time.hour); + "%02u:", (unsigned)value->type.Time.hour); if (!append_str(&p_str, &rem_str_len, temp_str)) break; } @@ -1200,7 +1190,7 @@ int bacapp_snprintf_value(char *str, size_t str_len, break; } else { snprintf(temp_str, sizeof(temp_str), - "%02u:", (unsigned)value->type.Time.min); + "%02u:", (unsigned)value->type.Time.min); if (!append_str(&p_str, &rem_str_len, temp_str)) break; } @@ -1209,7 +1199,7 @@ int bacapp_snprintf_value(char *str, size_t str_len, break; } else { snprintf(temp_str, sizeof(temp_str), "%02u.", - (unsigned)value->type.Time.sec); + (unsigned)value->type.Time.sec); if (!append_str(&p_str, &rem_str_len, temp_str)) break; } @@ -1218,7 +1208,7 @@ int bacapp_snprintf_value(char *str, size_t str_len, break; } else { snprintf(temp_str, sizeof(temp_str), "%02u", - (unsigned)value->type.Time.hundredths); + (unsigned)value->type.Time.hundredths); if (!append_str(&p_str, &rem_str_len, temp_str)) break; } @@ -1231,33 +1221,33 @@ int bacapp_snprintf_value(char *str, size_t str_len, break; if (value->type.Object_Id.type < MAX_ASHRAE_OBJECT_TYPE) { if (!append_str(&p_str, &rem_str_len, - bactext_object_type_name( - value->type.Object_Id.type))) + bactext_object_type_name( + value->type.Object_Id.type))) break; snprintf(temp_str, sizeof(temp_str), ", %lu", - (unsigned long)value->type.Object_Id.instance); + (unsigned long)value->type.Object_Id.instance); if (!append_str(&p_str, &rem_str_len, temp_str)) break; } else if (value->type.Object_Id.type < 128) { if (!append_str(&p_str, &rem_str_len, "reserved ")) break; snprintf(temp_str, sizeof(temp_str), "%u, ", - (unsigned)value->type.Object_Id.type); + (unsigned)value->type.Object_Id.type); if (!append_str(&p_str, &rem_str_len, temp_str)) break; snprintf(temp_str, sizeof(temp_str), "%lu", - (unsigned long)value->type.Object_Id.instance); + (unsigned long)value->type.Object_Id.instance); if (!append_str(&p_str, &rem_str_len, temp_str)) break; } else { if (!append_str(&p_str, &rem_str_len, "proprietary ")) break; snprintf(temp_str, sizeof(temp_str), "%u, ", - (unsigned)value->type.Object_Id.type); + (unsigned)value->type.Object_Id.type); if (!append_str(&p_str, &rem_str_len, temp_str)) break; snprintf(temp_str, sizeof(temp_str), "%lu", - (unsigned long)value->type.Object_Id.instance); + (unsigned long)value->type.Object_Id.instance); if (!append_str(&p_str, &rem_str_len, temp_str)) break; } @@ -1271,8 +1261,8 @@ int bacapp_snprintf_value(char *str, size_t str_len, if (!append_str(&p_str, &rem_str_len, "(")) break; if (!append_str(&p_str, &rem_str_len, - bactext_lighting_operation_name( - value->type.Lighting_Command.operation))) { + bactext_lighting_operation_name( + value->type.Lighting_Command.operation))) { break; } /* FIXME: add the Lighting Command optional values */ @@ -1297,8 +1287,8 @@ int bacapp_snprintf_value(char *str, size_t str_len, * specified stream. If stream is NULL, do not print anything. If extraction * failed, do not print anything. Return the status of the extraction. */ -bool bacapp_print_value(FILE *stream, - BACNET_OBJECT_PROPERTY_VALUE *object_value) +bool bacapp_print_value( + FILE *stream, BACNET_OBJECT_PROPERTY_VALUE *object_value) { char *str; bool retval = false; @@ -1337,8 +1327,8 @@ bool bacapp_print_value(FILE *stream, /* used to load the app data struct with the proper data converted from a command line argument */ bool bacapp_parse_application_data(BACNET_APPLICATION_TAG tag_number, - const char *argv, - BACNET_APPLICATION_DATA_VALUE *value) + const char *argv, + BACNET_APPLICATION_DATA_VALUE *value) { int hour, min, sec, hundredths; int year, month, day, wday; @@ -1403,7 +1393,7 @@ bool bacapp_parse_application_data(BACNET_APPLICATION_TAG tag_number, sscanf(argv, "%4d/%3d/%3d:%3d", &year, &month, &day, &wday); if (count == 3) { datetime_set_date(&value->type.Date, (uint16_t)year, - (uint8_t)month, (uint8_t)day); + (uint8_t)month, (uint8_t)day); } else if (count == 4) { value->type.Date.year = (uint16_t)year; value->type.Date.month = (uint8_t)month; @@ -1414,8 +1404,8 @@ bool bacapp_parse_application_data(BACNET_APPLICATION_TAG tag_number, } break; case BACNET_APPLICATION_TAG_TIME: - count = sscanf(argv, "%3d:%3d:%3d.%3d", &hour, &min, &sec, - &hundredths); + count = sscanf( + argv, "%3d:%3d:%3d.%3d", &hour, &min, &sec, &hundredths); if (count == 4) { value->type.Time.hour = (uint8_t)hour; value->type.Time.min = (uint8_t)min; @@ -1518,7 +1508,7 @@ void bacapp_property_value_list_init(BACNET_PROPERTY_VALUE *value, size_t count) /* generic - can be used by other unit tests returns true if matching or same, false if different */ bool bacapp_same_value(BACNET_APPLICATION_DATA_VALUE *value, - BACNET_APPLICATION_DATA_VALUE *test_value) + BACNET_APPLICATION_DATA_VALUE *test_value) { bool status = false; /*return value */ @@ -1573,52 +1563,50 @@ bool bacapp_same_value(BACNET_APPLICATION_DATA_VALUE *value, #endif #if defined(BACAPP_DATE) case BACNET_APPLICATION_TAG_DATE: - if (datetime_compare_date(&test_value->type.Date, - &value->type.Date) == 0) + if (datetime_compare_date( + &test_value->type.Date, &value->type.Date) == 0) status = true; break; #endif #if defined(BACAPP_TIME) case BACNET_APPLICATION_TAG_TIME: - if (datetime_compare_time(&test_value->type.Time, - &value->type.Time) == 0) + if (datetime_compare_time( + &test_value->type.Time, &value->type.Time) == 0) status = true; break; #endif #if defined(BACAPP_OBJECT_ID) case BACNET_APPLICATION_TAG_OBJECT_ID: if ((test_value->type.Object_Id.type == - value->type.Object_Id.type) && + value->type.Object_Id.type) && (test_value->type.Object_Id.instance == - value->type.Object_Id.instance)) { + value->type.Object_Id.instance)) { status = true; } break; #endif #if defined(BACAPP_CHARACTER_STRING) case BACNET_APPLICATION_TAG_CHARACTER_STRING: - status = - characterstring_same(&value->type.Character_String, - &test_value->type.Character_String); + status = characterstring_same(&value->type.Character_String, + &test_value->type.Character_String); break; #endif #if defined(BACAPP_OCTET_STRING) case BACNET_APPLICATION_TAG_OCTET_STRING: - status = octetstring_value_same(&value->type.Octet_String, - &test_value->type.Octet_String); + status = octetstring_value_same( + &value->type.Octet_String, &test_value->type.Octet_String); break; #endif #if defined(BACAPP_BIT_STRING) case BACNET_APPLICATION_TAG_BIT_STRING: - status = bitstring_same(&value->type.Bit_String, - &test_value->type.Bit_String); + status = bitstring_same( + &value->type.Bit_String, &test_value->type.Bit_String); break; #endif #if defined(BACAPP_LIGHTING_COMMAND) case BACNET_APPLICATION_TAG_LIGHTING_COMMAND: - status = - lighting_command_same(&value->type.Lighting_Command, - &test_value->type.Lighting_Command); + status = lighting_command_same(&value->type.Lighting_Command, + &test_value->type.Lighting_Command); break; #endif default: @@ -1669,14 +1657,14 @@ void testBACnetApplicationData_Safe(Test *pTest) break; case BACNET_APPLICATION_TAG_OCTET_STRING: { - uint8_t test_octet[5] = {"Karg"}; + uint8_t test_octet[5] = { "Karg" }; octetstring_init(&input_value[i].type.Octet_String, test_octet, - sizeof(test_octet)); + sizeof(test_octet)); } break; case BACNET_APPLICATION_TAG_CHARACTER_STRING: - characterstring_init_ansi(&input_value[i].type.Character_String, - "Hello There!"); + characterstring_init_ansi( + &input_value[i].type.Character_String, "Hello There!"); break; case BACNET_APPLICATION_TAG_BIT_STRING: @@ -1744,8 +1732,8 @@ void testBACnetApplicationData_Safe(Test *pTest) expected_status = true; } } - status = bacapp_decode_application_data_safe(i == 0 ? apdu : NULL, - apdu_len, &value); + status = bacapp_decode_application_data_safe( + i == 0 ? apdu : NULL, apdu_len, &value); ct_test(pTest, status == expected_status); if (status) { @@ -1763,9 +1751,9 @@ void testBACnetApplicationData_Safe(Test *pTest) void testBACnetApplicationDataLength(Test *pTest) { int apdu_len = 0; /* total length of the apdu, return value */ - int len = 0; /* total length of the apdu, return value */ + int len = 0; /* total length of the apdu, return value */ int test_len = 0; /* length of the data */ - uint8_t apdu[480] = {0}; + uint8_t apdu[480] = { 0 }; BACNET_TIME local_time; BACNET_DATE local_date; @@ -1778,8 +1766,8 @@ void testBACnetApplicationDataLength(Test *pTest) len = encode_closing_tag(&apdu[apdu_len], 3); apdu_len += len; /* verify the length of the data inside the opening/closing tags */ - len = bacapp_data_len(&apdu[0], apdu_len, - PROP_LIST_OF_OBJECT_PROPERTY_REFERENCES); + len = bacapp_data_len( + &apdu[0], apdu_len, PROP_LIST_OF_OBJECT_PROPERTY_REFERENCES); ct_test(pTest, test_len == len); /* 2. application tagged data, one element */ @@ -1864,9 +1852,9 @@ void testBACnetApplicationDataLength(Test *pTest) test_len += len; apdu_len += len; local_date.year = 2006; /* AD */ - local_date.month = 4; /* 1=Jan */ - local_date.day = 1; /* 1..31 */ - local_date.wday = 6; /* 1=Monday */ + local_date.month = 4; /* 1=Jan */ + local_date.day = 1; /* 1..31 */ + local_date.wday = 6; /* 1=Monday */ len = encode_application_date(&apdu[apdu_len], &local_date); test_len += len; apdu_len += len; @@ -1905,7 +1893,7 @@ void testBACnetApplicationDataLength(Test *pTest) static bool testBACnetApplicationDataValue(BACNET_APPLICATION_DATA_VALUE *value) { - uint8_t apdu[480] = {0}; + uint8_t apdu[480] = { 0 }; int apdu_len = 0; BACNET_APPLICATION_DATA_VALUE test_value; @@ -1920,100 +1908,100 @@ void testBACnetApplicationData(Test *pTest) BACNET_APPLICATION_DATA_VALUE value; bool status = false; - status = bacapp_parse_application_data(BACNET_APPLICATION_TAG_NULL, NULL, - &value); + status = bacapp_parse_application_data( + BACNET_APPLICATION_TAG_NULL, NULL, &value); ct_test(pTest, status == true); status = testBACnetApplicationDataValue(&value); ct_test(pTest, status == true); - status = bacapp_parse_application_data(BACNET_APPLICATION_TAG_BOOLEAN, "1", - &value); + status = bacapp_parse_application_data( + BACNET_APPLICATION_TAG_BOOLEAN, "1", &value); ct_test(pTest, status == true); ct_test(pTest, value.type.Boolean == true); ct_test(pTest, testBACnetApplicationDataValue(&value)); - status = bacapp_parse_application_data(BACNET_APPLICATION_TAG_BOOLEAN, "0", - &value); + status = bacapp_parse_application_data( + BACNET_APPLICATION_TAG_BOOLEAN, "0", &value); ct_test(pTest, status == true); ct_test(pTest, value.type.Boolean == false); ct_test(pTest, testBACnetApplicationDataValue(&value)); - status = bacapp_parse_application_data(BACNET_APPLICATION_TAG_UNSIGNED_INT, - "0", &value); + status = bacapp_parse_application_data( + BACNET_APPLICATION_TAG_UNSIGNED_INT, "0", &value); ct_test(pTest, status == true); ct_test(pTest, value.type.Unsigned_Int == 0); ct_test(pTest, testBACnetApplicationDataValue(&value)); - status = bacapp_parse_application_data(BACNET_APPLICATION_TAG_UNSIGNED_INT, - "0xFFFF", &value); + status = bacapp_parse_application_data( + BACNET_APPLICATION_TAG_UNSIGNED_INT, "0xFFFF", &value); ct_test(pTest, status == true); ct_test(pTest, value.type.Unsigned_Int == 0xFFFF); ct_test(pTest, testBACnetApplicationDataValue(&value)); - status = bacapp_parse_application_data(BACNET_APPLICATION_TAG_UNSIGNED_INT, - "0xFFFFFFFF", &value); + status = bacapp_parse_application_data( + BACNET_APPLICATION_TAG_UNSIGNED_INT, "0xFFFFFFFF", &value); ct_test(pTest, status == true); ct_test(pTest, value.type.Unsigned_Int == 0xFFFFFFFF); ct_test(pTest, testBACnetApplicationDataValue(&value)); - status = bacapp_parse_application_data(BACNET_APPLICATION_TAG_SIGNED_INT, - "0", &value); + status = bacapp_parse_application_data( + BACNET_APPLICATION_TAG_SIGNED_INT, "0", &value); ct_test(pTest, status == true); ct_test(pTest, value.type.Signed_Int == 0); ct_test(pTest, testBACnetApplicationDataValue(&value)); - status = bacapp_parse_application_data(BACNET_APPLICATION_TAG_SIGNED_INT, - "-1", &value); + status = bacapp_parse_application_data( + BACNET_APPLICATION_TAG_SIGNED_INT, "-1", &value); ct_test(pTest, status == true); ct_test(pTest, value.type.Signed_Int == -1); ct_test(pTest, testBACnetApplicationDataValue(&value)); - status = bacapp_parse_application_data(BACNET_APPLICATION_TAG_SIGNED_INT, - "32768", &value); + status = bacapp_parse_application_data( + BACNET_APPLICATION_TAG_SIGNED_INT, "32768", &value); ct_test(pTest, status == true); ct_test(pTest, value.type.Signed_Int == 32768); ct_test(pTest, testBACnetApplicationDataValue(&value)); - status = bacapp_parse_application_data(BACNET_APPLICATION_TAG_SIGNED_INT, - "-32768", &value); + status = bacapp_parse_application_data( + BACNET_APPLICATION_TAG_SIGNED_INT, "-32768", &value); ct_test(pTest, status == true); ct_test(pTest, value.type.Signed_Int == -32768); ct_test(pTest, testBACnetApplicationDataValue(&value)); - status = bacapp_parse_application_data(BACNET_APPLICATION_TAG_REAL, "0.0", - &value); + status = bacapp_parse_application_data( + BACNET_APPLICATION_TAG_REAL, "0.0", &value); ct_test(pTest, status == true); ct_test(pTest, testBACnetApplicationDataValue(&value)); - status = bacapp_parse_application_data(BACNET_APPLICATION_TAG_REAL, "-1.0", - &value); + status = bacapp_parse_application_data( + BACNET_APPLICATION_TAG_REAL, "-1.0", &value); ct_test(pTest, status == true); ct_test(pTest, testBACnetApplicationDataValue(&value)); - status = bacapp_parse_application_data(BACNET_APPLICATION_TAG_REAL, "1.0", - &value); + status = bacapp_parse_application_data( + BACNET_APPLICATION_TAG_REAL, "1.0", &value); ct_test(pTest, status == true); ct_test(pTest, testBACnetApplicationDataValue(&value)); - status = bacapp_parse_application_data(BACNET_APPLICATION_TAG_REAL, - "3.14159", &value); + status = bacapp_parse_application_data( + BACNET_APPLICATION_TAG_REAL, "3.14159", &value); ct_test(pTest, status == true); ct_test(pTest, testBACnetApplicationDataValue(&value)); - status = bacapp_parse_application_data(BACNET_APPLICATION_TAG_REAL, - "-3.14159", &value); + status = bacapp_parse_application_data( + BACNET_APPLICATION_TAG_REAL, "-3.14159", &value); ct_test(pTest, status == true); ct_test(pTest, testBACnetApplicationDataValue(&value)); - status = bacapp_parse_application_data(BACNET_APPLICATION_TAG_ENUMERATED, - "0", &value); + status = bacapp_parse_application_data( + BACNET_APPLICATION_TAG_ENUMERATED, "0", &value); ct_test(pTest, status == true); ct_test(pTest, value.type.Enumerated == 0); ct_test(pTest, testBACnetApplicationDataValue(&value)); - status = bacapp_parse_application_data(BACNET_APPLICATION_TAG_ENUMERATED, - "0xFFFF", &value); + status = bacapp_parse_application_data( + BACNET_APPLICATION_TAG_ENUMERATED, "0xFFFF", &value); ct_test(pTest, status == true); ct_test(pTest, value.type.Enumerated == 0xFFFF); ct_test(pTest, testBACnetApplicationDataValue(&value)); - status = bacapp_parse_application_data(BACNET_APPLICATION_TAG_ENUMERATED, - "0xFFFFFFFF", &value); + status = bacapp_parse_application_data( + BACNET_APPLICATION_TAG_ENUMERATED, "0xFFFFFFFF", &value); ct_test(pTest, status == true); ct_test(pTest, value.type.Enumerated == 0xFFFFFFFF); ct_test(pTest, testBACnetApplicationDataValue(&value)); - status = bacapp_parse_application_data(BACNET_APPLICATION_TAG_DATE, - "2005/5/22:1", &value); + status = bacapp_parse_application_data( + BACNET_APPLICATION_TAG_DATE, "2005/5/22:1", &value); ct_test(pTest, status == true); ct_test(pTest, value.type.Date.year == 2005); ct_test(pTest, value.type.Date.month == 5); @@ -2022,8 +2010,8 @@ void testBACnetApplicationData(Test *pTest) ct_test(pTest, testBACnetApplicationDataValue(&value)); /* Happy Valentines Day! */ - status = bacapp_parse_application_data(BACNET_APPLICATION_TAG_DATE, - "2007/2/14", &value); + status = bacapp_parse_application_data( + BACNET_APPLICATION_TAG_DATE, "2007/2/14", &value); ct_test(pTest, status == true); ct_test(pTest, value.type.Date.year == 2007); ct_test(pTest, value.type.Date.month == 2); @@ -2032,8 +2020,8 @@ void testBACnetApplicationData(Test *pTest) ct_test(pTest, testBACnetApplicationDataValue(&value)); /* Wildcard Values */ - status = bacapp_parse_application_data(BACNET_APPLICATION_TAG_DATE, - "2155/255/255:255", &value); + status = bacapp_parse_application_data( + BACNET_APPLICATION_TAG_DATE, "2155/255/255:255", &value); ct_test(pTest, status == true); ct_test(pTest, value.type.Date.year == 2155); ct_test(pTest, value.type.Date.month == 255); @@ -2041,8 +2029,8 @@ void testBACnetApplicationData(Test *pTest) ct_test(pTest, value.type.Date.wday == 255); ct_test(pTest, testBACnetApplicationDataValue(&value)); - status = bacapp_parse_application_data(BACNET_APPLICATION_TAG_TIME, - "23:59:59.12", &value); + status = bacapp_parse_application_data( + BACNET_APPLICATION_TAG_TIME, "23:59:59.12", &value); ct_test(pTest, status == true); ct_test(pTest, value.type.Time.hour == 23); ct_test(pTest, value.type.Time.min == 59); @@ -2050,8 +2038,8 @@ void testBACnetApplicationData(Test *pTest) ct_test(pTest, value.type.Time.hundredths == 12); ct_test(pTest, testBACnetApplicationDataValue(&value)); - status = bacapp_parse_application_data(BACNET_APPLICATION_TAG_TIME, - "23:59:59", &value); + status = bacapp_parse_application_data( + BACNET_APPLICATION_TAG_TIME, "23:59:59", &value); ct_test(pTest, status == true); ct_test(pTest, value.type.Time.hour == 23); ct_test(pTest, value.type.Time.min == 59); @@ -2059,8 +2047,8 @@ void testBACnetApplicationData(Test *pTest) ct_test(pTest, value.type.Time.hundredths == 0); ct_test(pTest, testBACnetApplicationDataValue(&value)); - status = bacapp_parse_application_data(BACNET_APPLICATION_TAG_TIME, "23:59", - &value); + status = bacapp_parse_application_data( + BACNET_APPLICATION_TAG_TIME, "23:59", &value); ct_test(pTest, status == true); ct_test(pTest, value.type.Time.hour == 23); ct_test(pTest, value.type.Time.min == 59); @@ -2069,8 +2057,8 @@ void testBACnetApplicationData(Test *pTest) ct_test(pTest, testBACnetApplicationDataValue(&value)); /* Wildcard Values */ - status = bacapp_parse_application_data(BACNET_APPLICATION_TAG_TIME, - "255:255:255.255", &value); + status = bacapp_parse_application_data( + BACNET_APPLICATION_TAG_TIME, "255:255:255.255", &value); ct_test(pTest, status == true); ct_test(pTest, value.type.Time.hour == 255); ct_test(pTest, value.type.Time.min == 255); @@ -2078,8 +2066,8 @@ void testBACnetApplicationData(Test *pTest) ct_test(pTest, value.type.Time.hundredths == 255); ct_test(pTest, testBACnetApplicationDataValue(&value)); - status = bacapp_parse_application_data(BACNET_APPLICATION_TAG_OBJECT_ID, - "0:100", &value); + status = bacapp_parse_application_data( + BACNET_APPLICATION_TAG_OBJECT_ID, "0:100", &value); ct_test(pTest, status == true); ct_test(pTest, value.type.Object_Id.type == 0); ct_test(pTest, value.type.Object_Id.instance == 100); @@ -2095,21 +2083,21 @@ void testBACnetApplicationData(Test *pTest) ct_test(pTest, status == true); ct_test(pTest, testBACnetApplicationDataValue(&value)); - status = bacapp_parse_application_data(BACNET_APPLICATION_TAG_OCTET_STRING, - "1234567890ABCDEF", &value); + status = bacapp_parse_application_data( + BACNET_APPLICATION_TAG_OCTET_STRING, "1234567890ABCDEF", &value); ct_test(pTest, status == true); ct_test(pTest, testBACnetApplicationDataValue(&value)); - status = bacapp_parse_application_data(BACNET_APPLICATION_TAG_OCTET_STRING, - "12-34-56-78-90-AB-CD-EF", &value); + status = bacapp_parse_application_data( + BACNET_APPLICATION_TAG_OCTET_STRING, "12-34-56-78-90-AB-CD-EF", &value); ct_test(pTest, status == true); ct_test(pTest, testBACnetApplicationDataValue(&value)); - status = bacapp_parse_application_data(BACNET_APPLICATION_TAG_OCTET_STRING, - "12 34 56 78 90 AB CD EF", &value); + status = bacapp_parse_application_data( + BACNET_APPLICATION_TAG_OCTET_STRING, "12 34 56 78 90 AB CD EF", &value); ct_test(pTest, status == true); ct_test(pTest, testBACnetApplicationDataValue(&value)); /* test empty string */ - status = bacapp_parse_application_data(BACNET_APPLICATION_TAG_OCTET_STRING, - "", &value); + status = bacapp_parse_application_data( + BACNET_APPLICATION_TAG_OCTET_STRING, "", &value); ct_test(pTest, status == true); ct_test(pTest, testBACnetApplicationDataValue(&value)); diff --git a/include/bacapp.h b/src/bacnet/bacapp.h similarity index 97% rename from include/bacapp.h rename to src/bacnet/bacapp.h index cad7456b..5052789b 100644 --- a/include/bacapp.h +++ b/src/bacnet/bacapp.h @@ -27,14 +27,14 @@ #include #include #include -#include "bacdef.h" -#include "bacstr.h" -#include "datetime.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacstr.h" +#include "bacnet/datetime.h" #if defined (BACAPP_LIGHTING_COMMAND) -#include "lighting.h" +#include "bacnet/lighting.h" #endif #if defined (BACAPP_DEVICE_OBJECT_PROP_REF) -#include "bacdevobjpropref.h" +#include "bacnet/bacdevobjpropref.h" #endif @@ -239,7 +239,7 @@ extern "C" { #ifdef TEST #include "ctest.h" -#include "datetime.h" +#include "bacnet/datetime.h" bool bacapp_same_value( BACNET_APPLICATION_DATA_VALUE * value, BACNET_APPLICATION_DATA_VALUE * test_value); diff --git a/src/bacdcode.c b/src/bacnet/bacdcode.c similarity index 89% rename from src/bacdcode.c rename to src/bacnet/bacdcode.c index 60c6a8c7..37495bef 100644 --- a/src/bacdcode.c +++ b/src/bacnet/bacdcode.c @@ -34,13 +34,13 @@ #include -#include "bacdef.h" -#include "bacdcode.h" -#include "bacenum.h" -#include "bits.h" -#include "bacstr.h" -#include "bacint.h" -#include "bacreal.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacenum.h" +#include "bacnet/bits.h" +#include "bacnet/bacstr.h" +#include "bacnet/bacint.h" +#include "bacnet/bacreal.h" /** @file bacdcode.c Functions to encode/decode BACnet data types */ @@ -97,39 +97,41 @@ uint8_t encode_max_segs_max_apdu(int max_segs, int max_apdu) { uint8_t octet = 0; - if (max_segs < 2) + if (max_segs < 2) { octet = 0; - else if (max_segs < 4) + } else if (max_segs < 4) { octet = 0x10; - else if (max_segs < 8) + } else if (max_segs < 8) { octet = 0x20; - else if (max_segs < 16) + } else if (max_segs < 16) { octet = 0x30; - else if (max_segs < 32) + } else if (max_segs < 32) { octet = 0x40; - else if (max_segs < 64) + } else if (max_segs < 64) { octet = 0x50; - else if (max_segs == 64) + } else if (max_segs == 64) { octet = 0x60; - else + } else { octet = 0x70; + } /* max_apdu must be 50 octets minimum */ - if (max_apdu <= 50) + if (max_apdu <= 50) { octet |= 0x00; - else if (max_apdu <= 128) + } else if (max_apdu <= 128) { octet |= 0x01; - /*fits in a LonTalk frame */ - else if (max_apdu <= 206) + /*fits in a LonTalk frame */ + } else if (max_apdu <= 206) { octet |= 0x02; - /*fits in an ARCNET or MS/TP frame */ - else if (max_apdu <= 480) + /*fits in an ARCNET or MS/TP frame */ + } else if (max_apdu <= 480) { octet |= 0x03; - else if (max_apdu <= 1024) + } else if (max_apdu <= 1024) { octet |= 0x04; - /* fits in an ISO 8802-3 frame */ - else if (max_apdu <= 1476) + /* fits in an ISO 8802-3 frame */ + } else if (max_apdu <= 1476) { octet |= 0x05; + } return octet; } @@ -205,14 +207,17 @@ int decode_max_apdu(uint8_t octet) /* from clause 20.2.1 General Rules for Encoding BACnet Tags */ /* returns the number of apdu bytes consumed */ -int encode_tag(uint8_t *apdu, uint8_t tag_number, bool context_specific, - uint32_t len_value_type) +int encode_tag(uint8_t *apdu, + uint8_t tag_number, + bool context_specific, + uint32_t len_value_type) { int len = 1; /* return value */ apdu[0] = 0; - if (context_specific) + if (context_specific) { apdu[0] = BIT3; + } /* additional tag byte after this byte */ /* for extended tag byte */ @@ -309,8 +314,8 @@ int decode_tag_number(uint8_t *apdu, uint8_t *tag_number) } /* Same as function above, but will safely fail if packet has been truncated */ -int decode_tag_number_safe(uint8_t *apdu, uint32_t apdu_len_remaining, - uint8_t *tag_number) +int decode_tag_number_safe( + uint8_t *apdu, uint32_t apdu_len_remaining, uint8_t *tag_number) { int len = 0; /* return value */ @@ -346,8 +351,8 @@ bool decode_is_closing_tag(uint8_t *apdu) /* from clause 20.2.1.3.2 Constructed Data */ /* returns the number of apdu bytes consumed */ -int decode_tag_number_and_value(uint8_t *apdu, uint8_t *tag_number, - uint32_t *value) +int decode_tag_number_and_value( + uint8_t *apdu, uint8_t *tag_number, uint32_t *value) { int len = 1; uint16_t value16; @@ -392,8 +397,10 @@ int decode_tag_number_and_value(uint8_t *apdu, uint8_t *tag_number, } /* Same as function above, but will safely fail is packet has been truncated */ -int decode_tag_number_and_value_safe(uint8_t *apdu, uint32_t apdu_len_remaining, - uint8_t *tag_number, uint32_t *value) +int decode_tag_number_and_value_safe(uint8_t *apdu, + uint32_t apdu_len_remaining, + uint8_t *tag_number, + uint32_t *value) { int len = 0; @@ -453,8 +460,8 @@ bool decode_is_context_tag(uint8_t *apdu, uint8_t tag_number) return (bool)(IS_CONTEXT_SPECIFIC(*apdu) && (my_tag_number == tag_number)); } -bool decode_is_context_tag_with_length(uint8_t *apdu, uint8_t tag_number, - int *tag_length) +bool decode_is_context_tag_with_length( + uint8_t *apdu, uint8_t tag_number, int *tag_length) { uint8_t my_tag_number = 0; @@ -501,8 +508,8 @@ int encode_application_boolean(uint8_t *apdu, bool boolean_value) } /* context tagged is encoded differently */ -int encode_context_boolean(uint8_t *apdu, uint8_t tag_number, - bool boolean_value) +int encode_context_boolean( + uint8_t *apdu, uint8_t tag_number, bool boolean_value) { int len = 0; /* return value */ @@ -524,8 +531,8 @@ bool decode_context_boolean(uint8_t *apdu) return boolean_value; } -int decode_context_boolean2(uint8_t *apdu, uint8_t tag_number, - bool *boolean_value) +int decode_context_boolean2( + uint8_t *apdu, uint8_t tag_number, bool *boolean_value) { int len = 0; if (decode_is_context_tag_with_length(&apdu[len], tag_number, &len)) { @@ -602,8 +609,8 @@ static uint8_t byte_reverse_bits(uint8_t in_byte) /* from clause 20.2.10 Encoding of a Bit String Value */ /* returns the number of apdu bytes consumed */ -int decode_bitstring(uint8_t *apdu, uint32_t len_value, - BACNET_BIT_STRING *bit_string) +int decode_bitstring( + uint8_t *apdu, uint32_t len_value, BACNET_BIT_STRING *bit_string) { int len = 0; uint8_t unused_bits = 0; @@ -617,20 +624,20 @@ int decode_bitstring(uint8_t *apdu, uint32_t len_value, if (bytes_used <= MAX_BITSTRING_BYTES) { len = 1; for (i = 0; i < bytes_used; i++) { - bitstring_set_octet(bit_string, (uint8_t)i, - byte_reverse_bits(apdu[len++])); + bitstring_set_octet( + bit_string, (uint8_t)i, byte_reverse_bits(apdu[len++])); } unused_bits = (uint8_t)(apdu[0] & 0x07); - bitstring_set_bits_used(bit_string, (uint8_t)bytes_used, - unused_bits); + bitstring_set_bits_used( + bit_string, (uint8_t)bytes_used, unused_bits); } } return len; } -int decode_context_bitstring(uint8_t *apdu, uint8_t tag_number, - BACNET_BIT_STRING *bit_string) +int decode_context_bitstring( + uint8_t *apdu, uint8_t tag_number, BACNET_BIT_STRING *bit_string) { uint32_t len_value; int len = 0; @@ -679,14 +686,14 @@ int encode_application_bitstring(uint8_t *apdu, BACNET_BIT_STRING *bit_string) /* bit string may use more than 1 octet for the tag, so find out how many */ bit_string_encoded_length += bitstring_bytes_used(bit_string); len = encode_tag(&apdu[0], BACNET_APPLICATION_TAG_BIT_STRING, false, - bit_string_encoded_length); + bit_string_encoded_length); len += encode_bitstring(&apdu[len], bit_string); return len; } -int encode_context_bitstring(uint8_t *apdu, uint8_t tag_number, - BACNET_BIT_STRING *bit_string) +int encode_context_bitstring( + uint8_t *apdu, uint8_t tag_number, BACNET_BIT_STRING *bit_string) { int len = 0; uint32_t bit_string_encoded_length = 1; /* 1 for the bits remaining octet */ @@ -714,8 +721,10 @@ int decode_object_id(uint8_t *apdu, uint16_t *object_type, uint32_t *instance) return len; } -int decode_object_id_safe(uint8_t *apdu, uint32_t len_value, - uint16_t *object_type, uint32_t *instance) +int decode_object_id_safe(uint8_t *apdu, + uint32_t len_value, + uint16_t *object_type, + uint32_t *instance) { if (len_value != 4) { return 0; @@ -724,8 +733,10 @@ int decode_object_id_safe(uint8_t *apdu, uint32_t len_value, } } -int decode_context_object_id(uint8_t *apdu, uint8_t tag_number, - uint16_t *object_type, uint32_t *instance) +int decode_context_object_id(uint8_t *apdu, + uint8_t tag_number, + uint16_t *object_type, + uint32_t *instance) { int len = 0; @@ -748,7 +759,7 @@ int encode_bacnet_object_id(uint8_t *apdu, int object_type, uint32_t instance) type = (uint32_t)object_type; value = ((type & BACNET_MAX_OBJECT) << BACNET_INSTANCE_BITS) | - (instance & BACNET_MAX_INSTANCE); + (instance & BACNET_MAX_INSTANCE); len = encode_unsigned32(apdu, value); return len; @@ -757,8 +768,8 @@ int encode_bacnet_object_id(uint8_t *apdu, int object_type, uint32_t instance) /* from clause 20.2.14 Encoding of an Object Identifier Value */ /* and 20.2.1 General Rules for Encoding BACnet Tags */ /* returns the number of apdu bytes consumed */ -int encode_context_object_id(uint8_t *apdu, uint8_t tag_number, int object_type, - uint32_t instance) +int encode_context_object_id( + uint8_t *apdu, uint8_t tag_number, int object_type, uint32_t instance) { int len = 0; @@ -773,15 +784,15 @@ int encode_context_object_id(uint8_t *apdu, uint8_t tag_number, int object_type, /* from clause 20.2.14 Encoding of an Object Identifier Value */ /* and 20.2.1 General Rules for Encoding BACnet Tags */ /* returns the number of apdu bytes consumed */ -int encode_application_object_id(uint8_t *apdu, int object_type, - uint32_t instance) +int encode_application_object_id( + uint8_t *apdu, int object_type, uint32_t instance) { int len = 0; /* assumes that the tag only consumes 1 octet */ len = encode_bacnet_object_id(&apdu[1], object_type, instance); - len += encode_tag(&apdu[0], BACNET_APPLICATION_TAG_OBJECT_ID, false, - (uint32_t)len); + len += encode_tag( + &apdu[0], BACNET_APPLICATION_TAG_OBJECT_ID, false, (uint32_t)len); return len; } @@ -814,14 +825,14 @@ int encode_octet_string(uint8_t *apdu, BACNET_OCTET_STRING *octet_string) /* from clause 20.2.8 Encoding of an Octet String Value */ /* and 20.2.1 General Rules for Encoding BACnet Tags */ /* returns the number of apdu bytes consumed */ -int encode_application_octet_string(uint8_t *apdu, - BACNET_OCTET_STRING *octet_string) +int encode_application_octet_string( + uint8_t *apdu, BACNET_OCTET_STRING *octet_string) { int apdu_len = 0; if (octet_string) { apdu_len = encode_tag(&apdu[0], BACNET_APPLICATION_TAG_OCTET_STRING, - false, octetstring_length(octet_string)); + false, octetstring_length(octet_string)); /* FIXME: probably need to pass in the length of the APDU to bounds check since it might not be the only data chunk */ if ((apdu_len + octetstring_length(octet_string)) < MAX_APDU) { @@ -837,14 +848,14 @@ int encode_application_octet_string(uint8_t *apdu, /* from clause 20.2.8 Encoding of an Octet String Value */ /* and 20.2.1 General Rules for Encoding BACnet Tags */ /* returns the number of apdu bytes consumed */ -int encode_context_octet_string(uint8_t *apdu, uint8_t tag_number, - BACNET_OCTET_STRING *octet_string) +int encode_context_octet_string( + uint8_t *apdu, uint8_t tag_number, BACNET_OCTET_STRING *octet_string) { int apdu_len = 0; if (apdu && octet_string) { - apdu_len = encode_tag(&apdu[0], tag_number, true, - octetstring_length(octet_string)); + apdu_len = encode_tag( + &apdu[0], tag_number, true, octetstring_length(octet_string)); if ((apdu_len + octetstring_length(octet_string)) < MAX_APDU) { apdu_len += encode_octet_string(&apdu[apdu_len], octet_string); } else { @@ -858,8 +869,8 @@ int encode_context_octet_string(uint8_t *apdu, uint8_t tag_number, /* from clause 20.2.8 Encoding of an Octet String Value */ /* and 20.2.1 General Rules for Encoding BACnet Tags */ /* returns the number of apdu bytes consumed */ -int decode_octet_string(uint8_t *apdu, uint32_t len_value, - BACNET_OCTET_STRING *octet_string) +int decode_octet_string( + uint8_t *apdu, uint32_t len_value, BACNET_OCTET_STRING *octet_string) { int len = 0; /* return value */ bool status = false; @@ -872,8 +883,8 @@ int decode_octet_string(uint8_t *apdu, uint32_t len_value, return len; } -int decode_context_octet_string(uint8_t *apdu, uint8_t tag_number, - BACNET_OCTET_STRING *octet_string) +int decode_context_octet_string( + uint8_t *apdu, uint8_t tag_number, BACNET_OCTET_STRING *octet_string) { int len = 0; /* return value */ bool status = false; @@ -898,9 +909,11 @@ int decode_context_octet_string(uint8_t *apdu, uint8_t tag_number, /* from clause 20.2.9 Encoding of a Character String Value */ /* returns the number of apdu bytes consumed, or zero if failed */ -uint32_t encode_bacnet_character_string_safe(uint8_t *apdu, uint32_t max_apdu, - uint8_t encoding, char *pString, - uint32_t length) +uint32_t encode_bacnet_character_string_safe(uint8_t *apdu, + uint32_t max_apdu, + uint8_t encoding, + char *pString, + uint32_t length) { uint32_t apdu_len = 1 /*encoding */; uint32_t i; @@ -918,11 +931,11 @@ uint32_t encode_bacnet_character_string_safe(uint8_t *apdu, uint32_t max_apdu, return apdu_len; } -int encode_bacnet_character_string(uint8_t *apdu, - BACNET_CHARACTER_STRING *char_string) +int encode_bacnet_character_string( + uint8_t *apdu, BACNET_CHARACTER_STRING *char_string) { - return (int)encode_bacnet_character_string_safe( - apdu, MAX_APDU, characterstring_encoding(char_string), + return (int)encode_bacnet_character_string_safe(apdu, MAX_APDU, + characterstring_encoding(char_string), characterstring_value(char_string), characterstring_length(char_string)); } @@ -930,8 +943,8 @@ int encode_bacnet_character_string(uint8_t *apdu, /* from clause 20.2.9 Encoding of a Character String Value */ /* and 20.2.1 General Rules for Encoding BACnet Tags */ /* returns the number of apdu bytes consumed */ -int encode_application_character_string(uint8_t *apdu, - BACNET_CHARACTER_STRING *char_string) +int encode_application_character_string( + uint8_t *apdu, BACNET_CHARACTER_STRING *char_string) { int len = 0; int string_len = 0; @@ -939,7 +952,7 @@ int encode_application_character_string(uint8_t *apdu, string_len = (int)characterstring_length(char_string) + 1 /* for encoding */; len = encode_tag(&apdu[0], BACNET_APPLICATION_TAG_CHARACTER_STRING, false, - (uint32_t)string_len); + (uint32_t)string_len); if ((len + string_len) < MAX_APDU) { len += encode_bacnet_character_string(&apdu[len], char_string); } else { @@ -949,8 +962,8 @@ int encode_application_character_string(uint8_t *apdu, return len; } -int encode_context_character_string(uint8_t *apdu, uint8_t tag_number, - BACNET_CHARACTER_STRING *char_string) +int encode_context_character_string( + uint8_t *apdu, uint8_t tag_number, BACNET_CHARACTER_STRING *char_string) { int len = 0; int string_len = 0; @@ -970,14 +983,14 @@ int encode_context_character_string(uint8_t *apdu, uint8_t tag_number, /* from clause 20.2.9 Encoding of a Character String Value */ /* and 20.2.1 General Rules for Encoding BACnet Tags */ /* returns the number of apdu bytes consumed */ -int decode_character_string(uint8_t *apdu, uint32_t len_value, - BACNET_CHARACTER_STRING *char_string) +int decode_character_string( + uint8_t *apdu, uint32_t len_value, BACNET_CHARACTER_STRING *char_string) { int len = 0; /* return value */ bool status = false; - status = characterstring_init(char_string, apdu[0], (char *)&apdu[1], - len_value - 1); + status = characterstring_init( + char_string, apdu[0], (char *)&apdu[1], len_value - 1); if (status) { len = (int)len_value; } @@ -985,8 +998,8 @@ int decode_character_string(uint8_t *apdu, uint32_t len_value, return len; } -int decode_context_character_string(uint8_t *apdu, uint8_t tag_number, - BACNET_CHARACTER_STRING *char_string) +int decode_context_character_string( + uint8_t *apdu, uint8_t tag_number, BACNET_CHARACTER_STRING *char_string) { int len = 0; /* return value */ bool status = false; @@ -996,8 +1009,8 @@ int decode_context_character_string(uint8_t *apdu, uint8_t tag_number, !decode_is_closing_tag(&apdu[len])) { len += decode_tag_number_and_value(&apdu[len], &tag_number, &len_value); - status = characterstring_init(char_string, apdu[len], - (char *)&apdu[len + 1], len_value - 1); + status = characterstring_init( + char_string, apdu[len], (char *)&apdu[len + 1], len_value - 1); if (status) { len += len_value; } @@ -1107,8 +1120,8 @@ int encode_application_unsigned(uint8_t *apdu, uint32_t value) int len = 0; len = encode_bacnet_unsigned(&apdu[1], value); - len += encode_tag(&apdu[0], BACNET_APPLICATION_TAG_UNSIGNED_INT, false, - (uint32_t)len); + len += encode_tag( + &apdu[0], BACNET_APPLICATION_TAG_UNSIGNED_INT, false, (uint32_t)len); return len; } @@ -1162,8 +1175,8 @@ int encode_application_enumerated(uint8_t *apdu, uint32_t value) /* assumes that the tag only consumes 1 octet */ len = encode_bacnet_enumerated(&apdu[1], value); - len += encode_tag(&apdu[0], BACNET_APPLICATION_TAG_ENUMERATED, false, - (uint32_t)len); + len += encode_tag( + &apdu[0], BACNET_APPLICATION_TAG_ENUMERATED, false, (uint32_t)len); return len; } @@ -1270,8 +1283,8 @@ int encode_application_signed(uint8_t *apdu, int32_t value) /* assumes that the tag only consumes 1 octet */ len = encode_bacnet_signed(&apdu[1], value); - len += encode_tag(&apdu[0], BACNET_APPLICATION_TAG_SIGNED_INT, false, - (uint32_t)len); + len += encode_tag( + &apdu[0], BACNET_APPLICATION_TAG_SIGNED_INT, false, (uint32_t)len); return len; } @@ -1337,8 +1350,8 @@ int encode_application_double(uint8_t *apdu, double value) /* assumes that the tag only consumes 2 octet */ len = encode_bacnet_double(value, &apdu[2]); - len += encode_tag(&apdu[0], BACNET_APPLICATION_TAG_DOUBLE, false, - (uint32_t)len); + len += encode_tag( + &apdu[0], BACNET_APPLICATION_TAG_DOUBLE, false, (uint32_t)len); return len; } @@ -1407,8 +1420,8 @@ int decode_bacnet_time(uint8_t *apdu, BACNET_TIME *btime) return 4; } -int decode_bacnet_time_safe(uint8_t *apdu, uint32_t len_value, - BACNET_TIME *btime) +int decode_bacnet_time_safe( + uint8_t *apdu, uint32_t len_value, BACNET_TIME *btime) { if (len_value != 4) { btime->hour = 0; @@ -1437,8 +1450,8 @@ int decode_application_time(uint8_t *apdu, BACNET_TIME *btime) return len; } -int decode_context_bacnet_time(uint8_t *apdu, uint8_t tag_number, - BACNET_TIME *btime) +int decode_context_bacnet_time( + uint8_t *apdu, uint8_t tag_number, BACNET_TIME *btime) { int len = 0; @@ -1578,10 +1591,11 @@ int encode_bacnet_address(uint8_t *apdu, BACNET_ADDRESS *destination) /* network number */ apdu_len += encode_application_unsigned(&apdu[apdu_len], destination->net); /* encode mac address as an octet-string */ - if (destination->len != 0) + if (destination->len != 0) { octetstring_init(&mac_addr, destination->adr, destination->len); - else + } else { octetstring_init(&mac_addr, destination->mac, destination->mac_len); + } apdu_len += encode_application_octet_string(&apdu[apdu_len], &mac_addr); return apdu_len; } @@ -1595,7 +1609,7 @@ int decode_bacnet_address(uint8_t *apdu, BACNET_ADDRESS *destination) uint8_t i = 0; uint32_t data_unsigned = 0; uint8_t tag_number = 0; - BACNET_OCTET_STRING mac_addr = {0}; + BACNET_OCTET_STRING mac_addr = { 0 }; /* network number */ tag_len = @@ -1628,8 +1642,8 @@ int decode_bacnet_address(uint8_t *apdu, BACNET_ADDRESS *destination) } /* BACnetAddress */ -int encode_context_bacnet_address(uint8_t *apdu, uint8_t tag_number, - BACNET_ADDRESS *destination) +int encode_context_bacnet_address( + uint8_t *apdu, uint8_t tag_number, BACNET_ADDRESS *destination) { int apdu_len = 0; apdu_len += encode_opening_tag(&apdu[apdu_len], tag_number); @@ -1639,8 +1653,8 @@ int encode_context_bacnet_address(uint8_t *apdu, uint8_t tag_number, } /* BACnetAddress */ -int decode_context_bacnet_address(uint8_t *apdu, uint8_t tag_number, - BACNET_ADDRESS *destination) +int decode_context_bacnet_address( + uint8_t *apdu, uint8_t tag_number, BACNET_ADDRESS *destination) { int len = 0; int section_length; @@ -1693,11 +1707,11 @@ static int get_apdu_len(bool extended_tag, uint32_t value) static void print_apdu(uint8_t *pBlock, uint32_t num) { - size_t lines = 0; /* number of lines to print */ - size_t line = 0; /* line of text counter */ - size_t last_line = 0; /* line on which the last text resided */ + size_t lines = 0; /* number of lines to print */ + size_t line = 0; /* line of text counter */ + size_t last_line = 0; /* line on which the last text resided */ unsigned long count = 0; /* address to print */ - unsigned int i = 0; /* counter */ + unsigned int i = 0; /* counter */ if (pBlock && num) { /* how many lines to print? */ @@ -1743,7 +1757,7 @@ static void print_apdu(uint8_t *pBlock, uint32_t num) static void testBACDCodeTags(Test *pTest) { - uint8_t apdu[MAX_APDU] = {0}; + uint8_t apdu[MAX_APDU] = { 0 }; uint8_t tag_number = 0, test_tag_number = 0; int len = 0, test_len = 0; uint32_t value = 0, test_value = 0; @@ -1769,8 +1783,8 @@ static void testBACDCodeTags(Test *pTest) /* test the len-value-type portion */ for (value = 1;; value = value << 1) { len = encode_tag(&apdu[0], tag_number, false, value); - len = decode_tag_number_and_value(&apdu[0], &test_tag_number, - &test_value); + len = decode_tag_number_and_value( + &apdu[0], &test_tag_number, &test_value); ct_test(pTest, tag_number == test_tag_number); ct_test(pTest, value == test_value); test_len = get_apdu_len(IS_EXTENDED_TAG_NUMBER(apdu[0]), value); @@ -1791,13 +1805,13 @@ static void testBACDCodeTags(Test *pTest) static void testBACDCodeEnumerated(Test *pTest) { - uint8_t array[5] = {0}; - uint8_t encoded_array[5] = {0}; + uint8_t array[5] = { 0 }; + uint8_t encoded_array[5] = { 0 }; uint32_t value = 1; uint32_t decoded_value = 0; int i = 0, apdu_len = 0; int len = 0; - uint8_t apdu[MAX_APDU] = {0}; + uint8_t apdu[MAX_APDU] = { 0 }; uint8_t tag_number = 0; uint32_t len_value = 0; @@ -1810,8 +1824,8 @@ static void testBACDCodeEnumerated(Test *pTest) ct_test(pTest, len == apdu_len); /* encode back the value */ encode_application_enumerated(&encoded_array[0], decoded_value); - ct_test(pTest, - memcmp(&array[0], &encoded_array[0], sizeof(array)) == 0); + ct_test( + pTest, memcmp(&array[0], &encoded_array[0], sizeof(array)) == 0); /* an enumerated will take up to 4 octects */ /* plus a one octet for the tag */ apdu_len = encode_application_enumerated(&apdu[0], value); @@ -1834,11 +1848,11 @@ static void testBACDCodeEnumerated(Test *pTest) static void testBACDCodeReal(Test *pTest) { - uint8_t real_array[4] = {0}; - uint8_t encoded_array[4] = {0}; + uint8_t real_array[4] = { 0 }; + uint8_t encoded_array[4] = { 0 }; float value = 42.123F; float decoded_value = 0.0F; - uint8_t apdu[MAX_APDU] = {0}; + uint8_t apdu[MAX_APDU] = { 0 }; int len = 0, apdu_len = 0; uint8_t tag_number = 0; uint32_t long_value = 0; @@ -1847,8 +1861,8 @@ static void testBACDCodeReal(Test *pTest) decode_real(&real_array[0], &decoded_value); ct_test(pTest, decoded_value == value); encode_bacnet_real(value, &encoded_array[0]); - ct_test(pTest, - memcmp(&real_array, &encoded_array, sizeof(real_array)) == 0); + ct_test( + pTest, memcmp(&real_array, &encoded_array, sizeof(real_array)) == 0); /* a real will take up 4 octects plus a one octet tag */ apdu_len = encode_application_real(&apdu[0], value); @@ -1867,11 +1881,11 @@ static void testBACDCodeReal(Test *pTest) static void testBACDCodeDouble(Test *pTest) { - uint8_t double_array[8] = {0}; - uint8_t encoded_array[8] = {0}; + uint8_t double_array[8] = { 0 }; + uint8_t encoded_array[8] = { 0 }; double value = 42.123; double decoded_value = 0.0; - uint8_t apdu[MAX_APDU] = {0}; + uint8_t apdu[MAX_APDU] = { 0 }; int len = 0, apdu_len = 0; uint8_t tag_number = 0; uint32_t long_value = 0; @@ -1881,7 +1895,7 @@ static void testBACDCodeDouble(Test *pTest) ct_test(pTest, decoded_value == value); encode_bacnet_double(value, &encoded_array[0]); ct_test(pTest, - memcmp(&double_array, &encoded_array, sizeof(double_array)) == 0); + memcmp(&double_array, &encoded_array, sizeof(double_array)) == 0); /* a real will take up 4 octects plus a one octet tag */ apdu_len = encode_application_double(&apdu[0], value); @@ -1900,11 +1914,11 @@ static void testBACDCodeDouble(Test *pTest) static void testBACDCodeUnsignedValue(Test *pTest, uint32_t value) { - uint8_t array[5] = {0}; - uint8_t encoded_array[5] = {0}; + uint8_t array[5] = { 0 }; + uint8_t encoded_array[5] = { 0 }; uint32_t decoded_value = 0; int len; - uint8_t apdu[MAX_APDU] = {0}; + uint8_t apdu[MAX_APDU] = { 0 }; uint8_t tag_number = 0; uint32_t len_value = 0; @@ -1914,7 +1928,7 @@ static void testBACDCodeUnsignedValue(Test *pTest, uint32_t value) ct_test(pTest, decoded_value == value); if (decoded_value != value) { printf("value=%lu decoded_value=%lu\n", (unsigned long)value, - (unsigned long)decoded_value); + (unsigned long)decoded_value); print_apdu(&array[0], sizeof(array)); } encode_application_unsigned(&encoded_array[0], decoded_value); @@ -1946,7 +1960,7 @@ static void testBACDCodeUnsigned(Test *pTest) static void testBACnetUnsigned(Test *pTest) { - uint8_t apdu[32] = {0}; + uint8_t apdu[32] = { 0 }; uint32_t value = 0, test_value = 0; int len = 0, test_len = 0; @@ -1962,11 +1976,11 @@ static void testBACnetUnsigned(Test *pTest) static void testBACDCodeSignedValue(Test *pTest, int32_t value) { - uint8_t array[5] = {0}; - uint8_t encoded_array[5] = {0}; + uint8_t array[5] = { 0 }; + uint8_t encoded_array[5] = { 0 }; int32_t decoded_value = 0; int len = 0; - uint8_t apdu[MAX_APDU] = {0}; + uint8_t apdu[MAX_APDU] = { 0 }; uint8_t tag_number = 0; uint32_t len_value = 0; int diff = 0; @@ -1977,16 +1991,16 @@ static void testBACDCodeSignedValue(Test *pTest, int32_t value) ct_test(pTest, tag_number == BACNET_APPLICATION_TAG_SIGNED_INT); ct_test(pTest, decoded_value == value); if (decoded_value != value) { - printf("value=%ld decoded_value=%ld\n", (long)value, - (long)decoded_value); + printf( + "value=%ld decoded_value=%ld\n", (long)value, (long)decoded_value); print_apdu(&array[0], sizeof(array)); } encode_application_signed(&encoded_array[0], decoded_value); diff = memcmp(&array[0], &encoded_array[0], sizeof(array)); ct_test(pTest, diff == 0); if (diff) { - printf("value=%ld decoded_value=%ld\n", (long)value, - (long)decoded_value); + printf( + "value=%ld decoded_value=%ld\n", (long)value, (long)decoded_value); print_apdu(&array[0], sizeof(array)); print_apdu(&encoded_array[0], sizeof(array)); } @@ -2026,7 +2040,7 @@ static void testBACDCodeSigned(Test *pTest) static void testBACnetSigned(Test *pTest) { - uint8_t apdu[32] = {0}; + uint8_t apdu[32] = { 0 }; int32_t value = 0, test_value = 0; int len = 0, test_len = 0; @@ -2046,11 +2060,11 @@ static void testBACnetSigned(Test *pTest) static void testBACDCodeOctetString(Test *pTest) { - uint8_t array[MAX_APDU] = {0}; - uint8_t encoded_array[MAX_APDU] = {0}; + uint8_t array[MAX_APDU] = { 0 }; + uint8_t encoded_array[MAX_APDU] = { 0 }; BACNET_OCTET_STRING octet_string; BACNET_OCTET_STRING test_octet_string; - uint8_t test_value[MAX_APDU] = {""}; + uint8_t test_value[MAX_APDU] = { "" }; int i; /* for loop counter */ int apdu_len; int len; @@ -2067,7 +2081,7 @@ static void testBACDCodeOctetString(Test *pTest) len += decode_octet_string(&array[len], len_value, &test_octet_string); ct_test(pTest, apdu_len == len); diff = memcmp(octetstring_value(&octet_string), &test_value[0], - octetstring_length(&octet_string)); + octetstring_length(&octet_string)); ct_test(pTest, diff == 0); for (i = 0; i < (MAX_APDU - 6); i++) { @@ -2076,17 +2090,17 @@ static void testBACDCodeOctetString(Test *pTest) ct_test(pTest, status == true); apdu_len = encode_application_octet_string(&encoded_array[0], &octet_string); - len = decode_tag_number_and_value(&encoded_array[0], &tag_number, - &len_value); + len = decode_tag_number_and_value( + &encoded_array[0], &tag_number, &len_value); ct_test(pTest, tag_number == BACNET_APPLICATION_TAG_OCTET_STRING); - len += decode_octet_string(&encoded_array[len], len_value, - &test_octet_string); + len += decode_octet_string( + &encoded_array[len], len_value, &test_octet_string); if (apdu_len != len) { printf("test octet string=#%d\n", i); } ct_test(pTest, apdu_len == len); diff = memcmp(octetstring_value(&octet_string), &test_value[0], - octetstring_length(&octet_string)); + octetstring_length(&octet_string)); if (diff) { printf("test octet string=#%d\n", i); } @@ -2098,11 +2112,11 @@ static void testBACDCodeOctetString(Test *pTest) static void testBACDCodeCharacterString(Test *pTest) { - uint8_t array[MAX_APDU] = {0}; - uint8_t encoded_array[MAX_APDU] = {0}; + uint8_t array[MAX_APDU] = { 0 }; + uint8_t encoded_array[MAX_APDU] = { 0 }; BACNET_CHARACTER_STRING char_string; BACNET_CHARACTER_STRING test_char_string; - char test_value[MAX_APDU] = {""}; + char test_value[MAX_APDU] = { "" }; int i; /* for loop counter */ int apdu_len; int len; @@ -2119,26 +2133,26 @@ static void testBACDCodeCharacterString(Test *pTest) len += decode_character_string(&array[len], len_value, &test_char_string); ct_test(pTest, apdu_len == len); diff = memcmp(characterstring_value(&char_string), &test_value[0], - characterstring_length(&char_string)); + characterstring_length(&char_string)); ct_test(pTest, diff == 0); for (i = 0; i < MAX_CHARACTER_STRING_BYTES - 1; i++) { test_value[i] = 'S'; test_value[i + 1] = '\0'; status = characterstring_init_ansi(&char_string, test_value); ct_test(pTest, status == true); - apdu_len = encode_application_character_string(&encoded_array[0], - &char_string); - len = decode_tag_number_and_value(&encoded_array[0], &tag_number, - &len_value); + apdu_len = encode_application_character_string( + &encoded_array[0], &char_string); + len = decode_tag_number_and_value( + &encoded_array[0], &tag_number, &len_value); ct_test(pTest, tag_number == BACNET_APPLICATION_TAG_CHARACTER_STRING); - len += decode_character_string(&encoded_array[len], len_value, - &test_char_string); + len += decode_character_string( + &encoded_array[len], len_value, &test_char_string); if (apdu_len != len) { printf("test string=#%d apdu_len=%d len=%d\n", i, apdu_len, len); } ct_test(pTest, apdu_len == len); diff = memcmp(characterstring_value(&char_string), &test_value[0], - characterstring_length(&char_string)); + characterstring_length(&char_string)); if (diff) { printf("test string=#%d\n", i); } @@ -2150,8 +2164,8 @@ static void testBACDCodeCharacterString(Test *pTest) static void testBACDCodeObject(Test *pTest) { - uint8_t object_array[4] = {0}; - uint8_t encoded_array[4] = {0}; + uint8_t object_array[4] = { 0 }; + uint8_t encoded_array[4] = { 0 }; uint16_t type = OBJECT_BINARY_INPUT; uint16_t decoded_type = OBJECT_ANALOG_OUTPUT; uint32_t instance = 123; @@ -2162,18 +2176,19 @@ static void testBACDCodeObject(Test *pTest) ct_test(pTest, decoded_type == type); ct_test(pTest, decoded_instance == instance); encode_bacnet_object_id(&object_array[0], type, instance); - ct_test(pTest, memcmp(&object_array[0], &encoded_array[0], - sizeof(object_array)) == 0); + ct_test(pTest, + memcmp(&object_array[0], &encoded_array[0], sizeof(object_array)) == 0); for (type = 0; type < 1024; type++) { for (instance = 0; instance <= BACNET_MAX_INSTANCE; instance += 1024) { encode_bacnet_object_id(&encoded_array[0], type, instance); - decode_object_id(&encoded_array[0], &decoded_type, - &decoded_instance); + decode_object_id( + &encoded_array[0], &decoded_type, &decoded_instance); ct_test(pTest, decoded_type == type); ct_test(pTest, decoded_instance == instance); encode_bacnet_object_id(&object_array[0], type, instance); - ct_test(pTest, memcmp(&object_array[0], &encoded_array[0], - sizeof(object_array)) == 0); + ct_test(pTest, + memcmp(&object_array[0], &encoded_array[0], + sizeof(object_array)) == 0); } } @@ -2182,8 +2197,8 @@ static void testBACDCodeObject(Test *pTest) static void testBACDCodeMaxSegsApdu(Test *pTest) { - int max_segs[8] = {0, 2, 4, 8, 16, 32, 64, 65}; - int max_apdu[6] = {50, 128, 206, 480, 1024, 1476}; + int max_segs[8] = { 0, 2, 4, 8, 16, 32, 64, 65 }; + int max_apdu[6] = { 50, 128, 206, 480, 1024, 1476 }; int i = 0; int j = 0; uint8_t octet = 0; @@ -2203,7 +2218,7 @@ static void testBACDCodeBitString(Test *pTest) uint8_t bit = 0; BACNET_BIT_STRING bit_string; BACNET_BIT_STRING decoded_bit_string; - uint8_t apdu[MAX_APDU] = {0}; + uint8_t apdu[MAX_APDU] = { 0 }; uint32_t len_value = 0; uint8_t tag_number = 0; int len = 0; @@ -2646,8 +2661,8 @@ static void testObjectIDContextDecodes(Test *pTest) inLen = encode_context_object_id(apdu, large_context_tag, in_type, in_id); outLen = decode_context_object_id(apdu, large_context_tag, &out_type, &out_id); - outLen2 = decode_context_object_id(apdu, large_context_tag - 1, &out_type, - &out_id); + outLen2 = decode_context_object_id( + apdu, large_context_tag - 1, &out_type, &out_id); ct_test(pTest, inLen == outLen); ct_test(pTest, in_type == out_type); @@ -2739,7 +2754,7 @@ static void testOctetStringContextDecodes(Test *pTest) BACNET_OCTET_STRING in; BACNET_OCTET_STRING out; - uint8_t initData[] = {0xde, 0xad, 0xbe, 0xef}; + uint8_t initData[] = { 0xde, 0xad, 0xbe, 0xef }; octetstring_init(&in, initData, sizeof(initData)); diff --git a/include/bacdcode.h b/src/bacnet/bacdcode.h similarity index 98% rename from include/bacdcode.h rename to src/bacnet/bacdcode.h index 3eec17a9..a18996c7 100644 --- a/include/bacdcode.h +++ b/src/bacnet/bacdcode.h @@ -27,12 +27,12 @@ #include #include #include -#include "bacdef.h" -#include "datetime.h" -#include "bacstr.h" -#include "bacint.h" -#include "bacreal.h" -#include "bits.h" +#include "bacnet/bacdef.h" +#include "bacnet/datetime.h" +#include "bacnet/bacstr.h" +#include "bacnet/bacint.h" +#include "bacnet/bacreal.h" +#include "bacnet/bits.h" #ifdef __cplusplus extern "C" { diff --git a/include/bacdef.h b/src/bacnet/bacdef.h similarity index 99% rename from include/bacdef.h rename to src/bacnet/bacdef.h index 57fae14f..d240f619 100644 --- a/include/bacdef.h +++ b/src/bacnet/bacdef.h @@ -26,8 +26,8 @@ #include #include -#include "bacenum.h" -#include "config.h" +#include "bacnet/bacenum.h" +#include "bacnet/config.h" #if defined(_MSC_VER) /* Silence the warnings about unsafe versions of library functions */ diff --git a/src/bacdevobjpropref.c b/src/bacnet/bacdevobjpropref.c similarity index 78% rename from src/bacdevobjpropref.c rename to src/bacnet/bacdevobjpropref.c index 2ef221f1..4420e606 100644 --- a/src/bacdevobjpropref.c +++ b/src/bacnet/bacdevobjpropref.c @@ -33,16 +33,16 @@ ####COPYRIGHTEND####*/ #include #include -#include "bacdcode.h" -#include "npdu.h" -#include "timestamp.h" -#include "bacdevobjpropref.h" +#include "bacnet/bacdcode.h" +#include "bacnet/npdu.h" +#include "bacnet/timestamp.h" +#include "bacnet/bacdevobjpropref.h" /** @file bacdevobjpropref.c BACnet Application Device Object (Property) * Reference */ -int bacapp_encode_context_device_obj_property_ref( - uint8_t *apdu, uint8_t tag_number, +int bacapp_encode_context_device_obj_property_ref(uint8_t *apdu, + uint8_t tag_number, BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE *value) { int len; @@ -78,12 +78,11 @@ int bacapp_encode_device_obj_property_ref( /* object-identifier [0] BACnetObjectIdentifier */ len = encode_context_object_id(&apdu[apdu_len], 0, - (int)value->objectIdentifier.type, - value->objectIdentifier.instance); + (int)value->objectIdentifier.type, value->objectIdentifier.instance); apdu_len += len; /* property-identifier [1] BACnetPropertyIdentifier */ - len = encode_context_enumerated(&apdu[apdu_len], 1, - value->propertyIdentifier); + len = encode_context_enumerated( + &apdu[apdu_len], 1, value->propertyIdentifier); apdu_len += len; /* property-array-index [2] Unsigned OPTIONAL */ /* Check if needed before inserting */ @@ -97,8 +96,8 @@ int bacapp_encode_device_obj_property_ref( * omit */ if (value->deviceIdentifier.type == OBJECT_DEVICE) { len = encode_context_object_id(&apdu[apdu_len], 3, - (int)value->deviceIdentifier.type, - value->deviceIdentifier.instance); + (int)value->deviceIdentifier.type, + value->deviceIdentifier.instance); apdu_len += len; } return apdu_len; @@ -122,9 +121,10 @@ int bacapp_decode_device_obj_property_ref( uint32_t enumValue; /* object-identifier [0] BACnetObjectIdentifier */ - if (-1 == (len = decode_context_object_id( - &apdu[apdu_len], 0, &value->objectIdentifier.type, - &value->objectIdentifier.instance))) { + if (-1 == + (len = decode_context_object_id(&apdu[apdu_len], 0, + &value->objectIdentifier.type, + &value->objectIdentifier.instance))) { return -1; } apdu_len += len; @@ -138,8 +138,9 @@ int bacapp_decode_device_obj_property_ref( /* property-array-index [2] Unsigned OPTIONAL */ if (decode_is_context_tag(&apdu[apdu_len], 2) && !decode_is_closing_tag(&apdu[apdu_len])) { - if (-1 == (len = decode_context_unsigned(&apdu[apdu_len], 2, - &value->arrayIndex))) { + if (-1 == + (len = decode_context_unsigned( + &apdu[apdu_len], 2, &value->arrayIndex))) { return -1; } apdu_len += len; @@ -149,9 +150,10 @@ int bacapp_decode_device_obj_property_ref( /* device-identifier [3] BACnetObjectIdentifier OPTIONAL */ if (decode_is_context_tag(&apdu[apdu_len], 3) && !decode_is_closing_tag(&apdu[apdu_len])) { - if (-1 == (len = decode_context_object_id( - &apdu[apdu_len], 3, &value->deviceIdentifier.type, - &value->deviceIdentifier.instance))) { + if (-1 == + (len = decode_context_object_id(&apdu[apdu_len], 3, + &value->deviceIdentifier.type, + &value->deviceIdentifier.instance))) { return -1; } apdu_len += len; @@ -163,8 +165,8 @@ int bacapp_decode_device_obj_property_ref( return apdu_len; } -int bacapp_decode_context_device_obj_property_ref( - uint8_t *apdu, uint8_t tag_number, +int bacapp_decode_context_device_obj_property_ref(uint8_t *apdu, + uint8_t tag_number, BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE *value) { int len = 0; @@ -195,8 +197,8 @@ int bacapp_decode_context_device_obj_property_ref( device-identifier [0] BACnetObjectIdentifier OPTIONAL, object-identifier [1] BACnetObjectIdentifier }*/ -int bacapp_encode_context_device_obj_ref(uint8_t *apdu, uint8_t tag_number, - BACNET_DEVICE_OBJECT_REFERENCE *value) +int bacapp_encode_context_device_obj_ref( + uint8_t *apdu, uint8_t tag_number, BACNET_DEVICE_OBJECT_REFERENCE *value) { int len; int apdu_len = 0; @@ -217,8 +219,8 @@ int bacapp_encode_context_device_obj_ref(uint8_t *apdu, uint8_t tag_number, device-identifier [0] BACnetObjectIdentifier OPTIONAL, object-identifier [1] BACnetObjectIdentifier }*/ -int bacapp_encode_device_obj_ref(uint8_t *apdu, - BACNET_DEVICE_OBJECT_REFERENCE *value) +int bacapp_encode_device_obj_ref( + uint8_t *apdu, BACNET_DEVICE_OBJECT_REFERENCE *value) { int len; int apdu_len = 0; @@ -229,14 +231,13 @@ int bacapp_encode_device_obj_ref(uint8_t *apdu, * omit */ if (value->deviceIdentifier.type == OBJECT_DEVICE) { len = encode_context_object_id(&apdu[apdu_len], 0, - (int)value->deviceIdentifier.type, - value->deviceIdentifier.instance); + (int)value->deviceIdentifier.type, + value->deviceIdentifier.instance); apdu_len += len; } /* object-identifier [1] BACnetObjectIdentifier */ len = encode_context_object_id(&apdu[apdu_len], 1, - (int)value->objectIdentifier.type, - value->objectIdentifier.instance); + (int)value->objectIdentifier.type, value->objectIdentifier.instance); apdu_len += len; return apdu_len; @@ -246,8 +247,8 @@ int bacapp_encode_device_obj_ref(uint8_t *apdu, device-identifier [0] BACnetObjectIdentifier OPTIONAL, object-identifier [1] BACnetObjectIdentifier }*/ -int bacapp_decode_device_obj_ref(uint8_t *apdu, - BACNET_DEVICE_OBJECT_REFERENCE *value) +int bacapp_decode_device_obj_ref( + uint8_t *apdu, BACNET_DEVICE_OBJECT_REFERENCE *value) { int len; int apdu_len = 0; @@ -255,9 +256,10 @@ int bacapp_decode_device_obj_ref(uint8_t *apdu, /* device-identifier [0] BACnetObjectIdentifier OPTIONAL */ if (decode_is_context_tag(&apdu[apdu_len], 0) && !decode_is_closing_tag(&apdu[apdu_len])) { - if (-1 == (len = decode_context_object_id( - &apdu[apdu_len], 0, &value->deviceIdentifier.type, - &value->deviceIdentifier.instance))) { + if (-1 == + (len = decode_context_object_id(&apdu[apdu_len], 0, + &value->deviceIdentifier.type, + &value->deviceIdentifier.instance))) { return -1; } apdu_len += len; @@ -266,9 +268,10 @@ int bacapp_decode_device_obj_ref(uint8_t *apdu, value->deviceIdentifier.instance = BACNET_NO_DEV_ID; } /* object-identifier [1] BACnetObjectIdentifier */ - if (-1 == (len = decode_context_object_id( - &apdu[apdu_len], 1, &value->objectIdentifier.type, - &value->objectIdentifier.instance))) { + if (-1 == + (len = decode_context_object_id(&apdu[apdu_len], 1, + &value->objectIdentifier.type, + &value->objectIdentifier.instance))) { return -1; } apdu_len += len; @@ -276,8 +279,8 @@ int bacapp_decode_device_obj_ref(uint8_t *apdu, return apdu_len; } -int bacapp_decode_context_device_obj_ref(uint8_t *apdu, uint8_t tag_number, - BACNET_DEVICE_OBJECT_REFERENCE *value) +int bacapp_decode_context_device_obj_ref( + uint8_t *apdu, uint8_t tag_number, BACNET_DEVICE_OBJECT_REFERENCE *value) { int len = 0; int section_length; @@ -306,11 +309,11 @@ int bacapp_decode_context_device_obj_ref(uint8_t *apdu, uint8_t tag_number, #include #include #include "ctest.h" -static void testDevObjPropRef(Test *pTest, - BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE *inData) +static void testDevObjPropRef( + Test *pTest, BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE *inData) { BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE outData; - uint8_t buffer[MAX_APDU] = {0}; + uint8_t buffer[MAX_APDU] = { 0 }; int inLen = 0; int outLen = 0; @@ -322,10 +325,10 @@ static void testDevObjPropRef(Test *pTest, /* decode */ outLen = bacapp_decode_device_obj_property_ref(buffer, &outData); ct_test(pTest, outLen == inLen); - ct_test(pTest, inData->objectIdentifier.instance == - outData.objectIdentifier.instance); ct_test(pTest, - inData->objectIdentifier.type == outData.objectIdentifier.type); + inData->objectIdentifier.instance == outData.objectIdentifier.instance); + ct_test( + pTest, inData->objectIdentifier.type == outData.objectIdentifier.type); ct_test(pTest, inData->propertyIdentifier == outData.propertyIdentifier); if (inData->arrayIndex != BACNET_ARRAY_ALL) { ct_test(pTest, inData->arrayIndex == outData.arrayIndex); @@ -333,10 +336,11 @@ static void testDevObjPropRef(Test *pTest, ct_test(pTest, outData.arrayIndex == BACNET_ARRAY_ALL); } if (inData->deviceIdentifier.type == OBJECT_DEVICE) { - ct_test(pTest, inData->deviceIdentifier.instance == - outData.deviceIdentifier.instance); ct_test(pTest, - inData->deviceIdentifier.type == outData.deviceIdentifier.type); + inData->deviceIdentifier.instance == + outData.deviceIdentifier.instance); + ct_test(pTest, + inData->deviceIdentifier.type == outData.deviceIdentifier.type); } else { ct_test(pTest, outData.deviceIdentifier.instance == BACNET_NO_DEV_ID); ct_test(pTest, outData.deviceIdentifier.type == BACNET_NO_DEV_TYPE); @@ -394,10 +398,10 @@ static void testDevIdRef(Test *pTest) inLen = bacapp_encode_device_obj_ref(buffer, &inData); outLen = bacapp_decode_device_obj_ref(buffer, &outData); ct_test(pTest, outLen == inLen); - ct_test(pTest, inData.deviceIdentifier.instance == - outData.deviceIdentifier.instance); ct_test(pTest, - inData.deviceIdentifier.type == outData.deviceIdentifier.type); + inData.deviceIdentifier.instance == outData.deviceIdentifier.instance); + ct_test( + pTest, inData.deviceIdentifier.type == outData.deviceIdentifier.type); } void testBACnetDeviceObjectPropertyReference(Test *pTest) diff --git a/include/bacdevobjpropref.h b/src/bacnet/bacdevobjpropref.h similarity index 98% rename from include/bacdevobjpropref.h rename to src/bacnet/bacdevobjpropref.h index d68dcb13..3ac73649 100644 --- a/include/bacdevobjpropref.h +++ b/src/bacnet/bacdevobjpropref.h @@ -27,8 +27,8 @@ #include #include #include -#include "bacdef.h" -#include "bacenum.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacenum.h" typedef struct BACnetDeviceObjectPropertyReference { BACNET_OBJECT_ID objectIdentifier; diff --git a/include/bacenum.h b/src/bacnet/bacenum.h similarity index 100% rename from include/bacenum.h rename to src/bacnet/bacenum.h diff --git a/src/bacerror.c b/src/bacnet/bacerror.c similarity index 66% rename from src/bacerror.c rename to src/bacnet/bacerror.c index 65be30f6..0f70868c 100644 --- a/src/bacerror.c +++ b/src/bacnet/bacerror.c @@ -32,18 +32,19 @@ ------------------------------------------- ####COPYRIGHTEND####*/ #include -#include "bacenum.h" -#include "bacdcode.h" -#include "bacdef.h" -#include "bacerror.h" +#include "bacnet/bacenum.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacerror.h" /** @file bacerror.c Encode/Decode BACnet Errors */ /* encode service */ -int bacerror_encode_apdu(uint8_t *apdu, uint8_t invoke_id, - BACNET_CONFIRMED_SERVICE service, - BACNET_ERROR_CLASS error_class, - BACNET_ERROR_CODE error_code) +int bacerror_encode_apdu(uint8_t *apdu, + uint8_t invoke_id, + BACNET_CONFIRMED_SERVICE service, + BACNET_ERROR_CLASS error_class, + BACNET_ERROR_CODE error_code) { int apdu_len = 0; /* total length of the apdu, return value */ @@ -62,9 +63,10 @@ int bacerror_encode_apdu(uint8_t *apdu, uint8_t invoke_id, #if !BACNET_SVC_SERVER /* decode the application class and code */ -int bacerror_decode_error_class_and_code(uint8_t *apdu, unsigned apdu_len, - BACNET_ERROR_CLASS *error_class, - BACNET_ERROR_CODE *error_code) +int bacerror_decode_error_class_and_code(uint8_t *apdu, + unsigned apdu_len, + BACNET_ERROR_CLASS *error_class, + BACNET_ERROR_CODE *error_code) { int len = 0; uint8_t tag_number = 0; @@ -73,43 +75,50 @@ int bacerror_decode_error_class_and_code(uint8_t *apdu, unsigned apdu_len, if (apdu_len) { /* error class */ - len += decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value_type); - if (tag_number != BACNET_APPLICATION_TAG_ENUMERATED) + len += decode_tag_number_and_value( + &apdu[len], &tag_number, &len_value_type); + if (tag_number != BACNET_APPLICATION_TAG_ENUMERATED) { return 0; + } len += decode_enumerated(&apdu[len], len_value_type, &decoded_value); - if (error_class) + if (error_class) { *error_class = (BACNET_ERROR_CLASS)decoded_value; + } /* error code */ - len += decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value_type); - if (tag_number != BACNET_APPLICATION_TAG_ENUMERATED) + len += decode_tag_number_and_value( + &apdu[len], &tag_number, &len_value_type); + if (tag_number != BACNET_APPLICATION_TAG_ENUMERATED) { return 0; + } len += decode_enumerated(&apdu[len], len_value_type, &decoded_value); - if (error_code) + if (error_code) { *error_code = (BACNET_ERROR_CODE)decoded_value; + } } return len; } /* decode the service request only */ -int bacerror_decode_service_request(uint8_t *apdu, unsigned apdu_len, - uint8_t *invoke_id, - BACNET_CONFIRMED_SERVICE *service, - BACNET_ERROR_CLASS *error_class, - BACNET_ERROR_CODE *error_code) +int bacerror_decode_service_request(uint8_t *apdu, + unsigned apdu_len, + uint8_t *invoke_id, + BACNET_CONFIRMED_SERVICE *service, + BACNET_ERROR_CLASS *error_class, + BACNET_ERROR_CODE *error_code) { int len = 0; if (apdu_len > 2) { - if (invoke_id) + if (invoke_id) { *invoke_id = apdu[0]; - if (service) + } + if (service) { *service = (BACNET_CONFIRMED_SERVICE)apdu[1]; + } /* decode the application class and code */ - len = bacerror_decode_error_class_and_code(&apdu[2], apdu_len - 2, - error_class, error_code); + len = bacerror_decode_error_class_and_code( + &apdu[2], apdu_len - 2, error_class, error_code); } return len; @@ -122,10 +131,12 @@ int bacerror_decode_service_request(uint8_t *apdu, unsigned apdu_len, #include "ctest.h" /* decode the whole APDU - mainly used for unit testing */ -int bacerror_decode_apdu(uint8_t *apdu, unsigned apdu_len, uint8_t *invoke_id, - BACNET_CONFIRMED_SERVICE *service, - BACNET_ERROR_CLASS *error_class, - BACNET_ERROR_CODE *error_code) +int bacerror_decode_apdu(uint8_t *apdu, + unsigned apdu_len, + uint8_t *invoke_id, + BACNET_CONFIRMED_SERVICE *service, + BACNET_ERROR_CLASS *error_class, + BACNET_ERROR_CODE *error_code) { int len = 0; @@ -137,8 +148,7 @@ int bacerror_decode_apdu(uint8_t *apdu, unsigned apdu_len, uint8_t *invoke_id, return -1; if (apdu_len > 1) { len = bacerror_decode_service_request(&apdu[1], apdu_len - 1, - invoke_id, service, - error_class, error_code); + invoke_id, service, error_class, error_code); } } @@ -147,7 +157,7 @@ int bacerror_decode_apdu(uint8_t *apdu, unsigned apdu_len, uint8_t *invoke_id, void testBACError(Test *pTest) { - uint8_t apdu[480] = {0}; + uint8_t apdu[480] = { 0 }; int len = 0; int apdu_len = 0; uint8_t invoke_id = 0; @@ -159,14 +169,13 @@ void testBACError(Test *pTest) BACNET_ERROR_CLASS test_error_class = 0; BACNET_ERROR_CODE test_error_code = 0; - len = bacerror_encode_apdu(&apdu[0], invoke_id, service, error_class, - error_code); + len = bacerror_encode_apdu( + &apdu[0], invoke_id, service, error_class, error_code); ct_test(pTest, len != 0); apdu_len = len; - len = - bacerror_decode_apdu(&apdu[0], apdu_len, &test_invoke_id, &test_service, - &test_error_class, &test_error_code); + len = bacerror_decode_apdu(&apdu[0], apdu_len, &test_invoke_id, + &test_service, &test_error_class, &test_error_code); ct_test(pTest, len != -1); ct_test(pTest, test_invoke_id == invoke_id); ct_test(pTest, test_service == service); @@ -175,19 +184,18 @@ void testBACError(Test *pTest) /* change type to get negative response */ apdu[0] = PDU_TYPE_ABORT; - len = - bacerror_decode_apdu(&apdu[0], apdu_len, &test_invoke_id, &test_service, - &test_error_class, &test_error_code); + len = bacerror_decode_apdu(&apdu[0], apdu_len, &test_invoke_id, + &test_service, &test_error_class, &test_error_code); ct_test(pTest, len == -1); /* test NULL APDU */ len = bacerror_decode_apdu(NULL, apdu_len, &test_invoke_id, &test_service, - &test_error_class, &test_error_code); + &test_error_class, &test_error_code); ct_test(pTest, len == -1); /* force a zero length */ len = bacerror_decode_apdu(&apdu[0], 0, &test_invoke_id, &test_service, - &test_error_class, &test_error_code); + &test_error_class, &test_error_code); ct_test(pTest, len == 0); /* check them all... */ @@ -196,13 +204,12 @@ void testBACError(Test *pTest) error_class++) { for (error_code = 0; error_code < ERROR_CODE_PROPRIETARY_FIRST; error_code++) { - len = bacerror_encode_apdu(&apdu[0], invoke_id, service, - error_class, error_code); + len = bacerror_encode_apdu( + &apdu[0], invoke_id, service, error_class, error_code); apdu_len = len; ct_test(pTest, len != 0); len = bacerror_decode_apdu(&apdu[0], apdu_len, &test_invoke_id, - &test_service, &test_error_class, - &test_error_code); + &test_service, &test_error_class, &test_error_code); ct_test(pTest, len != -1); ct_test(pTest, test_invoke_id == invoke_id); ct_test(pTest, test_service == service); @@ -216,13 +223,12 @@ void testBACError(Test *pTest) service = 255; error_class = ERROR_CLASS_PROPRIETARY_LAST; error_code = ERROR_CODE_PROPRIETARY_LAST; - len = bacerror_encode_apdu(&apdu[0], invoke_id, service, error_class, - error_code); + len = bacerror_encode_apdu( + &apdu[0], invoke_id, service, error_class, error_code); apdu_len = len; ct_test(pTest, len != 0); - len = - bacerror_decode_apdu(&apdu[0], apdu_len, &test_invoke_id, &test_service, - &test_error_class, &test_error_code); + len = bacerror_decode_apdu(&apdu[0], apdu_len, &test_invoke_id, + &test_service, &test_error_class, &test_error_code); ct_test(pTest, len != -1); ct_test(pTest, test_invoke_id == invoke_id); ct_test(pTest, test_service == service); diff --git a/include/bacerror.h b/src/bacnet/bacerror.h similarity index 98% rename from include/bacerror.h rename to src/bacnet/bacerror.h index 9853bcf5..34d21f18 100644 --- a/include/bacerror.h +++ b/src/bacnet/bacerror.h @@ -26,7 +26,7 @@ #include #include -#include "bacenum.h" +#include "bacnet/bacenum.h" #ifdef __cplusplus extern "C" { diff --git a/src/bacint.c b/src/bacnet/bacint.c similarity index 96% rename from src/bacint.c rename to src/bacnet/bacint.c index a7256968..cbd31ba6 100644 --- a/src/bacint.c +++ b/src/bacnet/bacint.c @@ -36,8 +36,8 @@ #include #include -#include "config.h" -#include "bacint.h" +#include "bacnet/config.h" +#include "bacnet/bacint.h" /** @file bacint.c Encode/Decode Integer Types */ @@ -164,10 +164,11 @@ int decode_signed8(uint8_t *apdu, int32_t *value) { if (value) { /* negative - bit 7 is set */ - if (apdu[0] & 0x80) + if (apdu[0] & 0x80) { *value = 0xFFFFFF00; - else + } else { *value = 0; + } *value |= ((int32_t)(((int32_t)apdu[0]) & 0x000000ff)); } @@ -186,10 +187,11 @@ int decode_signed16(uint8_t *apdu, int32_t *value) { if (value) { /* negative - bit 7 is set */ - if (apdu[0] & 0x80) + if (apdu[0] & 0x80) { *value = 0xFFFF0000; - else + } else { *value = 0; + } *value |= ((int32_t)((((int32_t)apdu[0]) << 8) & 0x0000ff00)); *value |= ((int32_t)(((int32_t)apdu[1]) & 0x000000ff)); } @@ -210,10 +212,11 @@ int decode_signed24(uint8_t *apdu, int32_t *value) { if (value) { /* negative - bit 7 is set */ - if (apdu[0] & 0x80) + if (apdu[0] & 0x80) { *value = 0xFF000000; - else + } else { *value = 0; + } *value |= ((int32_t)((((int32_t)apdu[0]) << 16) & 0x00ff0000)); *value |= ((int32_t)((((int32_t)apdu[1]) << 8) & 0x0000ff00)); *value |= ((int32_t)(((int32_t)apdu[2]) & 0x000000ff)); @@ -253,7 +256,7 @@ int decode_signed32(uint8_t *apdu, int32_t *value) static void testBACnetUnsigned16(Test *pTest) { - uint8_t apdu[32] = {0}; + uint8_t apdu[32] = { 0 }; uint16_t value = 0, test_value = 0; int len = 0; @@ -269,7 +272,7 @@ static void testBACnetUnsigned16(Test *pTest) static void testBACnetUnsigned24(Test *pTest) { - uint8_t apdu[32] = {0}; + uint8_t apdu[32] = { 0 }; uint32_t value = 0, test_value = 0; int len = 0; @@ -285,7 +288,7 @@ static void testBACnetUnsigned24(Test *pTest) static void testBACnetUnsigned32(Test *pTest) { - uint8_t apdu[32] = {0}; + uint8_t apdu[32] = { 0 }; uint32_t value = 0, test_value = 0; int len = 0; @@ -301,7 +304,7 @@ static void testBACnetUnsigned32(Test *pTest) static void testBACnetSigned8(Test *pTest) { - uint8_t apdu[32] = {0}; + uint8_t apdu[32] = { 0 }; int32_t value = 0, test_value = 0; int len = 0; @@ -317,7 +320,7 @@ static void testBACnetSigned8(Test *pTest) static void testBACnetSigned16(Test *pTest) { - uint8_t apdu[32] = {0}; + uint8_t apdu[32] = { 0 }; int32_t value = 0, test_value = 0; int len = 0; @@ -333,7 +336,7 @@ static void testBACnetSigned16(Test *pTest) static void testBACnetSigned24(Test *pTest) { - uint8_t apdu[32] = {0}; + uint8_t apdu[32] = { 0 }; int32_t value = 0, test_value = 0; int len = 0; @@ -347,7 +350,7 @@ static void testBACnetSigned24(Test *pTest) static void testBACnetSigned32(Test *pTest) { - uint8_t apdu[32] = {0}; + uint8_t apdu[32] = { 0 }; int32_t value = 0, test_value = 0; int len = 0; diff --git a/include/bacint.h b/src/bacnet/bacint.h similarity index 100% rename from include/bacint.h rename to src/bacnet/bacint.h diff --git a/src/bacprop.c b/src/bacnet/bacprop.c similarity index 63% rename from src/bacprop.c rename to src/bacnet/bacprop.c index 01e77385..f826d23f 100644 --- a/src/bacprop.c +++ b/src/bacnet/bacprop.c @@ -36,33 +36,34 @@ #if PRINT_ENABLED #include #endif -#include "bacprop.h" +#include "bacnet/bacprop.h" /** @file bacprop.c Lookup BACnet Property Tags */ PROP_TAG_DATA bacnet_object_device_property_tag_map[] = { - {PROP_OBJECT_IDENTIFIER, BACNET_APPLICATION_TAG_OBJECT_ID}, - {PROP_OBJECT_NAME, BACNET_APPLICATION_TAG_CHARACTER_STRING}, - {PROP_OBJECT_TYPE, BACNET_APPLICATION_TAG_ENUMERATED}, - {PROP_SYSTEM_STATUS, BACNET_APPLICATION_TAG_ENUMERATED}, - {PROP_VENDOR_NAME, BACNET_APPLICATION_TAG_CHARACTER_STRING}, - {PROP_VENDOR_IDENTIFIER, BACNET_APPLICATION_TAG_UNSIGNED_INT}, - {PROP_MODEL_NAME, BACNET_APPLICATION_TAG_CHARACTER_STRING}, - {PROP_FIRMWARE_REVISION, BACNET_APPLICATION_TAG_CHARACTER_STRING}, - {PROP_APPLICATION_SOFTWARE_VERSION, - BACNET_APPLICATION_TAG_CHARACTER_STRING}, - {PROP_PROTOCOL_VERSION, BACNET_APPLICATION_TAG_UNSIGNED_INT}, - {PROP_PROTOCOL_CONFORMANCE_CLASS, BACNET_APPLICATION_TAG_UNSIGNED_INT}, - {PROP_PROTOCOL_SERVICES_SUPPORTED, BACNET_APPLICATION_TAG_BIT_STRING}, - {PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED, BACNET_APPLICATION_TAG_BIT_STRING}, - {PROP_MAX_APDU_LENGTH_ACCEPTED, BACNET_APPLICATION_TAG_UNSIGNED_INT}, - {PROP_SEGMENTATION_SUPPORTED, BACNET_APPLICATION_TAG_ENUMERATED}, - {PROP_APDU_TIMEOUT, BACNET_APPLICATION_TAG_UNSIGNED_INT}, - {PROP_NUMBER_OF_APDU_RETRIES, BACNET_APPLICATION_TAG_UNSIGNED_INT}, - {-1, -1}}; + { PROP_OBJECT_IDENTIFIER, BACNET_APPLICATION_TAG_OBJECT_ID }, + { PROP_OBJECT_NAME, BACNET_APPLICATION_TAG_CHARACTER_STRING }, + { PROP_OBJECT_TYPE, BACNET_APPLICATION_TAG_ENUMERATED }, + { PROP_SYSTEM_STATUS, BACNET_APPLICATION_TAG_ENUMERATED }, + { PROP_VENDOR_NAME, BACNET_APPLICATION_TAG_CHARACTER_STRING }, + { PROP_VENDOR_IDENTIFIER, BACNET_APPLICATION_TAG_UNSIGNED_INT }, + { PROP_MODEL_NAME, BACNET_APPLICATION_TAG_CHARACTER_STRING }, + { PROP_FIRMWARE_REVISION, BACNET_APPLICATION_TAG_CHARACTER_STRING }, + { PROP_APPLICATION_SOFTWARE_VERSION, + BACNET_APPLICATION_TAG_CHARACTER_STRING }, + { PROP_PROTOCOL_VERSION, BACNET_APPLICATION_TAG_UNSIGNED_INT }, + { PROP_PROTOCOL_CONFORMANCE_CLASS, BACNET_APPLICATION_TAG_UNSIGNED_INT }, + { PROP_PROTOCOL_SERVICES_SUPPORTED, BACNET_APPLICATION_TAG_BIT_STRING }, + { PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED, BACNET_APPLICATION_TAG_BIT_STRING }, + { PROP_MAX_APDU_LENGTH_ACCEPTED, BACNET_APPLICATION_TAG_UNSIGNED_INT }, + { PROP_SEGMENTATION_SUPPORTED, BACNET_APPLICATION_TAG_ENUMERATED }, + { PROP_APDU_TIMEOUT, BACNET_APPLICATION_TAG_UNSIGNED_INT }, + { PROP_NUMBER_OF_APDU_RETRIES, BACNET_APPLICATION_TAG_UNSIGNED_INT }, + { -1, -1 } +}; -signed bacprop_tag_by_index_default(PROP_TAG_DATA* data_list, signed index, - signed default_ret) +signed bacprop_tag_by_index_default( + PROP_TAG_DATA *data_list, signed index, signed default_ret) { signed pUnsigned = 0; diff --git a/include/bacprop.h b/src/bacnet/bacprop.h similarity index 98% rename from include/bacprop.h rename to src/bacnet/bacprop.h index 3af7b5c3..2fba7358 100644 --- a/include/bacprop.h +++ b/src/bacnet/bacprop.h @@ -26,7 +26,7 @@ #include #include -#include "bacenum.h" +#include "bacnet/bacenum.h" typedef struct { signed prop_id; /* index number that matches the text */ diff --git a/src/bacpropstates.c b/src/bacnet/bacpropstates.c similarity index 72% rename from src/bacpropstates.c rename to src/bacnet/bacpropstates.c index 43c7b410..28d09507 100644 --- a/src/bacpropstates.c +++ b/src/bacnet/bacpropstates.c @@ -31,11 +31,11 @@ License. ------------------------------------------- ####COPYRIGHTEND####*/ - -#include "bacdcode.h" -#include "npdu.h" -#include "timestamp.h" -#include "bacpropstates.h" +#include +#include "bacnet/bacdcode.h" +#include "bacnet/npdu.h" +#include "bacnet/timestamp.h" +#include "bacnet/bacpropstates.h" /** @file bacpropstates.c Encode/Decode BACnet Application Property States */ @@ -61,104 +61,116 @@ int bacapp_decode_property_state(uint8_t *apdu, BACNET_PROPERTY_STATE *value) break; case BINARY_VALUE: - if (-1 == (section_length = decode_enumerated( - &apdu[len], len_value_type, &enumValue))) { + if (-1 == + (section_length = decode_enumerated( + &apdu[len], len_value_type, &enumValue))) { return -1; } value->state.binaryValue = (BACNET_BINARY_PV)enumValue; break; case EVENT_TYPE: - if (-1 == (section_length = decode_enumerated( - &apdu[len], len_value_type, &enumValue))) { + if (-1 == + (section_length = decode_enumerated( + &apdu[len], len_value_type, &enumValue))) { return -1; } value->state.eventType = (BACNET_EVENT_TYPE)enumValue; break; case POLARITY: - if (-1 == (section_length = decode_enumerated( - &apdu[len], len_value_type, &enumValue))) { + if (-1 == + (section_length = decode_enumerated( + &apdu[len], len_value_type, &enumValue))) { return -1; } value->state.polarity = (BACNET_POLARITY)enumValue; break; case PROGRAM_CHANGE: - if (-1 == (section_length = decode_enumerated( - &apdu[len], len_value_type, &enumValue))) { + if (-1 == + (section_length = decode_enumerated( + &apdu[len], len_value_type, &enumValue))) { return -1; } value->state.programChange = (BACNET_PROGRAM_REQUEST)enumValue; break; case PROGRAM_STATE: - if (-1 == (section_length = decode_enumerated( - &apdu[len], len_value_type, &enumValue))) { + if (-1 == + (section_length = decode_enumerated( + &apdu[len], len_value_type, &enumValue))) { return -1; } value->state.programState = (BACNET_PROGRAM_STATE)enumValue; break; case REASON_FOR_HALT: - if (-1 == (section_length = decode_enumerated( - &apdu[len], len_value_type, &enumValue))) { + if (-1 == + (section_length = decode_enumerated( + &apdu[len], len_value_type, &enumValue))) { return -1; } value->state.programError = (BACNET_PROGRAM_ERROR)enumValue; break; case RELIABILITY: - if (-1 == (section_length = decode_enumerated( - &apdu[len], len_value_type, &enumValue))) { + if (-1 == + (section_length = decode_enumerated( + &apdu[len], len_value_type, &enumValue))) { return -1; } value->state.reliability = (BACNET_RELIABILITY)enumValue; break; case STATE: - if (-1 == (section_length = decode_enumerated( - &apdu[len], len_value_type, &enumValue))) { + if (-1 == + (section_length = decode_enumerated( + &apdu[len], len_value_type, &enumValue))) { return -1; } value->state.state = (BACNET_EVENT_STATE)enumValue; break; case SYSTEM_STATUS: - if (-1 == (section_length = decode_enumerated( - &apdu[len], len_value_type, &enumValue))) { + if (-1 == + (section_length = decode_enumerated( + &apdu[len], len_value_type, &enumValue))) { return -1; } value->state.systemStatus = (BACNET_DEVICE_STATUS)enumValue; break; case UNITS: - if (-1 == (section_length = decode_enumerated( - &apdu[len], len_value_type, &enumValue))) { + if (-1 == + (section_length = decode_enumerated( + &apdu[len], len_value_type, &enumValue))) { return -1; } value->state.units = (BACNET_ENGINEERING_UNITS)enumValue; break; case UNSIGNED_VALUE: - if (-1 == (section_length = - decode_unsigned(&apdu[len], len_value_type, - &value->state.unsignedValue))) { + if (-1 == + (section_length = decode_unsigned(&apdu[len], len_value_type, + &value->state.unsignedValue))) { return -1; } break; case LIFE_SAFETY_MODE: - if (-1 == (section_length = decode_enumerated( - &apdu[len], len_value_type, &enumValue))) { + if (-1 == + (section_length = decode_enumerated( + &apdu[len], len_value_type, &enumValue))) { return -1; } value->state.lifeSafetyMode = (BACNET_LIFE_SAFETY_MODE)enumValue; break; case LIFE_SAFETY_STATE: - if (-1 == (section_length = decode_enumerated( - &apdu[len], len_value_type, &enumValue))) { + if (-1 == + (section_length = decode_enumerated( + &apdu[len], len_value_type, &enumValue))) { return -1; } value->state.lifeSafetyState = (BACNET_LIFE_SAFETY_STATE)enumValue; @@ -172,8 +184,8 @@ int bacapp_decode_property_state(uint8_t *apdu, BACNET_PROPERTY_STATE *value) return len; } -int bacapp_decode_context_property_state(uint8_t *apdu, uint8_t tag_number, - BACNET_PROPERTY_STATE *value) +int bacapp_decode_context_property_state( + uint8_t *apdu, uint8_t tag_number, BACNET_PROPERTY_STATE *value) { int len = 0; int section_length; @@ -204,43 +216,43 @@ int bacapp_encode_property_state(uint8_t *apdu, BACNET_PROPERTY_STATE *value) if (value && apdu) { switch (value->tag) { case BOOLEAN_VALUE: - len = encode_context_boolean(&apdu[0], 0, - value->state.booleanValue); + len = encode_context_boolean( + &apdu[0], 0, value->state.booleanValue); break; case BINARY_VALUE: - len = encode_context_enumerated(&apdu[0], 1, - value->state.binaryValue); + len = encode_context_enumerated( + &apdu[0], 1, value->state.binaryValue); break; case EVENT_TYPE: - len = encode_context_enumerated(&apdu[0], 2, - value->state.eventType); + len = encode_context_enumerated( + &apdu[0], 2, value->state.eventType); break; case POLARITY: - len = encode_context_enumerated(&apdu[0], 3, - value->state.polarity); + len = encode_context_enumerated( + &apdu[0], 3, value->state.polarity); break; case PROGRAM_CHANGE: - len = encode_context_enumerated(&apdu[0], 4, - value->state.programChange); + len = encode_context_enumerated( + &apdu[0], 4, value->state.programChange); break; case PROGRAM_STATE: - len = encode_context_enumerated(&apdu[0], 5, - value->state.programState); + len = encode_context_enumerated( + &apdu[0], 5, value->state.programState); break; case REASON_FOR_HALT: - len = encode_context_enumerated(&apdu[0], 6, - value->state.programError); + len = encode_context_enumerated( + &apdu[0], 6, value->state.programError); break; case RELIABILITY: - len = encode_context_enumerated(&apdu[0], 7, - value->state.reliability); + len = encode_context_enumerated( + &apdu[0], 7, value->state.reliability); break; case STATE: @@ -249,8 +261,8 @@ int bacapp_encode_property_state(uint8_t *apdu, BACNET_PROPERTY_STATE *value) break; case SYSTEM_STATUS: - len = encode_context_enumerated(&apdu[0], 9, - value->state.systemStatus); + len = encode_context_enumerated( + &apdu[0], 9, value->state.systemStatus); break; case UNITS: @@ -259,18 +271,18 @@ int bacapp_encode_property_state(uint8_t *apdu, BACNET_PROPERTY_STATE *value) break; case UNSIGNED_VALUE: - len = encode_context_unsigned(&apdu[0], 11, - value->state.unsignedValue); + len = encode_context_unsigned( + &apdu[0], 11, value->state.unsignedValue); break; case LIFE_SAFETY_MODE: - len = encode_context_enumerated(&apdu[0], 12, - value->state.lifeSafetyMode); + len = encode_context_enumerated( + &apdu[0], 12, value->state.lifeSafetyMode); break; case LIFE_SAFETY_STATE: - len = encode_context_enumerated(&apdu[0], 13, - value->state.lifeSafetyState); + len = encode_context_enumerated( + &apdu[0], 13, value->state.lifeSafetyState); break; default: diff --git a/include/bacpropstates.h b/src/bacnet/bacpropstates.h similarity index 97% rename from include/bacpropstates.h rename to src/bacnet/bacpropstates.h index 564d0a82..0cabe120 100644 --- a/include/bacpropstates.h +++ b/src/bacnet/bacpropstates.h @@ -26,9 +26,9 @@ #include #include -#include "bacenum.h" -#include "bacapp.h" -#include "timestamp.h" +#include "bacnet/bacenum.h" +#include "bacnet/bacapp.h" +#include "bacnet/timestamp.h" typedef enum { BOOLEAN_VALUE, diff --git a/src/bacreal.c b/src/bacnet/bacreal.c similarity index 95% rename from src/bacreal.c rename to src/bacnet/bacreal.c index 17df92ee..9a172a86 100644 --- a/src/bacreal.c +++ b/src/bacnet/bacreal.c @@ -34,13 +34,13 @@ #include -#include "bacdef.h" -#include "bacdcode.h" -#include "bacenum.h" -#include "bits.h" -#include "bacstr.h" -#include "bacint.h" -#include "bacreal.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacenum.h" +#include "bacnet/bits.h" +#include "bacnet/bacstr.h" +#include "bacnet/bacint.h" +#include "bacnet/bacreal.h" /** @file bacreal.c Encode/Decode Floating Point (Real) Types */ @@ -208,8 +208,8 @@ int encode_bacnet_double(double value, uint8_t *apdu) return 8; } -int decode_context_double(uint8_t *apdu, uint8_t tag_number, - double *double_value) +int decode_context_double( + uint8_t *apdu, uint8_t tag_number, double *double_value) { uint32_t len_value; int len = 0; @@ -234,7 +234,7 @@ int decode_context_double(uint8_t *apdu, uint8_t tag_number, void testBACreal(Test *pTest) { float real_value = 3.14159F, test_real_value = 0.0; - uint8_t apdu[MAX_APDU] = {0}; + uint8_t apdu[MAX_APDU] = { 0 }; int len = 0, test_len = 0; len = encode_bacnet_real(real_value, &apdu[0]); @@ -247,7 +247,7 @@ void testBACreal(Test *pTest) void testBACdouble(Test *pTest) { double double_value = 3.1415927, test_double_value = 0.0; - uint8_t apdu[MAX_APDU] = {0}; + uint8_t apdu[MAX_APDU] = { 0 }; int len = 0, test_len = 0; len = encode_bacnet_double(double_value, &apdu[0]); diff --git a/include/bacreal.h b/src/bacnet/bacreal.h similarity index 100% rename from include/bacreal.h rename to src/bacnet/bacreal.h diff --git a/src/bacstr.c b/src/bacnet/bacstr.c similarity index 86% rename from src/bacstr.c rename to src/bacnet/bacstr.c index e5ed0e07..aadd8332 100644 --- a/src/bacstr.c +++ b/src/bacnet/bacstr.c @@ -35,12 +35,12 @@ #include #include #include /* for strlen */ -#include "config.h" -#include "bacstr.h" -#include "bits.h" +#include "bacnet/config.h" +#include "bacnet/bacstr.h" +#include "bacnet/bits.h" #if PRINT_ENABLED #include /* for strtol */ -#include /* for isalnum */ +#include /* for isalnum */ #endif /** @file bacstr.c Manipulate Bit/Char/Octet Strings */ @@ -55,8 +55,8 @@ void bitstring_init(BACNET_BIT_STRING *bit_string) } } -void bitstring_set_bit(BACNET_BIT_STRING *bit_string, uint8_t bit_number, - bool value) +void bitstring_set_bit( + BACNET_BIT_STRING *bit_string, uint8_t bit_number, bool value) { uint8_t byte_number = bit_number / 8; uint8_t bit_mask = 1; @@ -127,8 +127,8 @@ uint8_t bitstring_octet(BACNET_BIT_STRING *bit_string, uint8_t octet_index) return octet; } -bool bitstring_set_octet(BACNET_BIT_STRING *bit_string, uint8_t index, - uint8_t octet) +bool bitstring_set_octet( + BACNET_BIT_STRING *bit_string, uint8_t index, uint8_t octet) { bool status = false; @@ -142,8 +142,8 @@ bool bitstring_set_octet(BACNET_BIT_STRING *bit_string, uint8_t index, return status; } -bool bitstring_set_bits_used(BACNET_BIT_STRING *bit_string, uint8_t bytes_used, - uint8_t unused_bits) +bool bitstring_set_bits_used( + BACNET_BIT_STRING *bit_string, uint8_t bytes_used, uint8_t unused_bits) { bool status = false; @@ -183,8 +183,8 @@ bool bitstring_copy(BACNET_BIT_STRING *dest, BACNET_BIT_STRING *src) } /* returns true if the same length and contents */ -bool bitstring_same(BACNET_BIT_STRING *bitstring1, - BACNET_BIT_STRING *bitstring2) +bool bitstring_same( + BACNET_BIT_STRING *bitstring1, BACNET_BIT_STRING *bitstring2) { int i = 0; /* loop counter */ int bytes_used = 0; @@ -220,7 +220,7 @@ bool bitstring_same(BACNET_BIT_STRING *bitstring1, bool bitstring_init_ascii(BACNET_BIT_STRING *bit_string, const char *ascii) { bool status = false; /* return value */ - unsigned index = 0; /* offset into buffer */ + unsigned index = 0; /* offset into buffer */ uint8_t bit_number = 0; if (bit_string) { @@ -262,10 +262,12 @@ bool bitstring_init_ascii(BACNET_BIT_STRING *bit_string, const char *ascii) /* returns false if the string exceeds capacity initialize by using value=NULL */ bool characterstring_init(BACNET_CHARACTER_STRING *char_string, - uint8_t encoding, const char *value, size_t length) + uint8_t encoding, + const char *value, + size_t length) { bool status = false; /* return value */ - size_t i; /* counter */ + size_t i; /* counter */ if (char_string) { char_string->length = 0; @@ -294,23 +296,22 @@ bool characterstring_init(BACNET_CHARACTER_STRING *char_string, return status; } -bool characterstring_init_ansi(BACNET_CHARACTER_STRING *char_string, - const char *value) +bool characterstring_init_ansi( + BACNET_CHARACTER_STRING *char_string, const char *value) { - return characterstring_init(char_string, CHARACTER_ANSI_X34, value, - value ? strlen(value) : 0); + return characterstring_init( + char_string, CHARACTER_ANSI_X34, value, value ? strlen(value) : 0); } -bool characterstring_copy(BACNET_CHARACTER_STRING *dest, - BACNET_CHARACTER_STRING *src) +bool characterstring_copy( + BACNET_CHARACTER_STRING *dest, BACNET_CHARACTER_STRING *src) { return characterstring_init(dest, characterstring_encoding(src), - characterstring_value(src), - characterstring_length(src)); + characterstring_value(src), characterstring_length(src)); } -bool characterstring_ansi_copy(char *dest, size_t dest_max_len, - BACNET_CHARACTER_STRING *src) +bool characterstring_ansi_copy( + char *dest, size_t dest_max_len, BACNET_CHARACTER_STRING *src) { size_t i; /* counter */ @@ -330,8 +331,8 @@ bool characterstring_ansi_copy(char *dest, size_t dest_max_len, } /* returns true if the character encoding and string contents are the same */ -bool characterstring_same(BACNET_CHARACTER_STRING *dest, - BACNET_CHARACTER_STRING *src) +bool characterstring_same( + BACNET_CHARACTER_STRING *dest, BACNET_CHARACTER_STRING *src) { size_t i; /* counter */ bool same_status = false; @@ -390,10 +391,10 @@ bool characterstring_ansi_same(BACNET_CHARACTER_STRING *dest, const char *src) } /* returns false if the string exceeds capacity */ -bool characterstring_append(BACNET_CHARACTER_STRING *char_string, - const char *value, size_t length) +bool characterstring_append( + BACNET_CHARACTER_STRING *char_string, const char *value, size_t length) { - size_t i; /* counter */ + size_t i; /* counter */ bool status = false; /* return value */ if (char_string) { @@ -412,8 +413,8 @@ bool characterstring_append(BACNET_CHARACTER_STRING *char_string, /* This function sets a new length without changing the value. If length exceeds capacity, no modification happens and function returns false. */ -bool characterstring_truncate(BACNET_CHARACTER_STRING *char_string, - size_t length) +bool characterstring_truncate( + BACNET_CHARACTER_STRING *char_string, size_t length) { bool status = false; /* return value */ @@ -476,8 +477,8 @@ uint8_t characterstring_encoding(BACNET_CHARACTER_STRING *char_string) } /* returns the encoding. */ -bool characterstring_set_encoding(BACNET_CHARACTER_STRING *char_string, - uint8_t encoding) +bool characterstring_set_encoding( + BACNET_CHARACTER_STRING *char_string, uint8_t encoding) { bool status = false; @@ -503,7 +504,7 @@ X'20' - X'7E'.*/ bool characterstring_printable(BACNET_CHARACTER_STRING *char_string) { bool status = false; /* return value */ - size_t i; /* counter */ + size_t i; /* counter */ if (char_string) { if (char_string->encoding == CHARACTER_ANSI_X34) { @@ -529,18 +530,17 @@ bool characterstring_printable(BACNET_CHARACTER_STRING *char_string) /* Basic UTF-8 manipulation routines by Jeff Bezanson placed in the public domain Fall 2005 */ -static const char trailingBytesForUTF8[256] = { - 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, 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, 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, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5}; +static const char trailingBytesForUTF8[256] = { 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, 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, 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, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5 }; /* based on the valid_utf8 routine from the PCRE library by Philip Hazel length is in bytes, since without knowing whether the string is valid @@ -583,40 +583,46 @@ bool utf8_isvalid(const char *str, size_t length) switch (ab) { /* Check for xx00 000x */ case 1: - if ((c & 0x3e) == 0) + if ((c & 0x3e) == 0) { return false; + } continue; /* We know there aren't any more bytes to check */ /* Check for 1110 0000, xx0x xxxx */ case 2: - if (c == 0xe0 && (*p & 0x20) == 0) + if (c == 0xe0 && (*p & 0x20) == 0) { return false; + } break; /* Check for 1111 0000, xx00 xxxx */ case 3: - if (c == 0xf0 && (*p & 0x30) == 0) + if (c == 0xf0 && (*p & 0x30) == 0) { return false; + } break; /* Check for 1111 1000, xx00 0xxx */ case 4: - if (c == 0xf8 && (*p & 0x38) == 0) + if (c == 0xf8 && (*p & 0x38) == 0) { return false; + } break; /* Check for leading 0xfe or 0xff, and then for 1111 1100, xx00 00xx */ case 5: - if (c == 0xfe || c == 0xff || (c == 0xfc && (*p & 0x3c) == 0)) + if (c == 0xfe || c == 0xff || (c == 0xfc && (*p & 0x3c) == 0)) { return false; + } break; } /* Check for valid bytes after the 2nd, if any; all must start 10 */ while (--ab > 0) { - if ((*(++p) & 0xc0) != 0x80) + if ((*(++p) & 0xc0) != 0x80) { return false; + } } } @@ -643,11 +649,11 @@ bool characterstring_valid(BACNET_CHARACTER_STRING *char_string) #if BACNET_USE_OCTETSTRING /* returns false if the string exceeds capacity initialize by using value=NULL */ -bool octetstring_init(BACNET_OCTET_STRING *octet_string, uint8_t *value, - size_t length) +bool octetstring_init( + BACNET_OCTET_STRING *octet_string, uint8_t *value, size_t length) { bool status = false; /* return value */ - size_t i; /* counter */ + size_t i; /* counter */ if (octet_string && (length <= MAX_OCTET_STRING_BYTES)) { octet_string->length = 0; @@ -674,11 +680,11 @@ bool octetstring_init(BACNET_OCTET_STRING *octet_string, uint8_t *value, #if PRINT_ENABLED /* converts an null terminated ASCII Hex string to an octet string. returns true if successfully converted and fits; false if too long */ -bool octetstring_init_ascii_hex(BACNET_OCTET_STRING *octet_string, - const char *ascii_hex) +bool octetstring_init_ascii_hex( + BACNET_OCTET_STRING *octet_string, const char *ascii_hex) { bool status = false; /* return value */ - unsigned index = 0; /* offset into buffer */ + unsigned index = 0; /* offset into buffer */ uint8_t value = 0; char hex_pair_string[3] = ""; @@ -721,14 +727,14 @@ bool octetstring_init_ascii_hex(BACNET_OCTET_STRING *octet_string, bool octetstring_copy(BACNET_OCTET_STRING *dest, BACNET_OCTET_STRING *src) { - return octetstring_init(dest, octetstring_value(src), - octetstring_length(src)); + return octetstring_init( + dest, octetstring_value(src), octetstring_length(src)); } /* returns the number of bytes copied, or 0 if the dest cannot hold entire octetstring value */ -size_t octetstring_copy_value(uint8_t *dest, size_t length, - BACNET_OCTET_STRING *src) +size_t octetstring_copy_value( + uint8_t *dest, size_t length, BACNET_OCTET_STRING *src) { size_t bytes_copied = 0; size_t i; /* counter */ @@ -746,10 +752,10 @@ size_t octetstring_copy_value(uint8_t *dest, size_t length, } /* returns false if the string exceeds capacity */ -bool octetstring_append(BACNET_OCTET_STRING *octet_string, uint8_t *value, - size_t length) +bool octetstring_append( + BACNET_OCTET_STRING *octet_string, uint8_t *value, size_t length) { - size_t i; /* counter */ + size_t i; /* counter */ bool status = false; /* return value */ if (octet_string) { @@ -821,8 +827,8 @@ size_t octetstring_capacity(BACNET_OCTET_STRING *octet_string) } /* returns true if the same length and contents */ -bool octetstring_value_same(BACNET_OCTET_STRING *octet_string1, - BACNET_OCTET_STRING *octet_string2) +bool octetstring_value_same( + BACNET_OCTET_STRING *octet_string1, BACNET_OCTET_STRING *octet_string2) { size_t i = 0; /* loop counter */ @@ -905,7 +911,7 @@ void testBitString(Test *pTest) * be different */ bitstring_set_bit(&bit_string2, 0, !bitstring_bit(&bit_string, 0)); bitstring_set_bit(&bit_string3, max_bit - 1, - !bitstring_bit(&bit_string, max_bit - 1)); + !bitstring_bit(&bit_string, max_bit - 1)); ct_test(pTest, !bitstring_same(&bit_string, &bit_string2)); ct_test(pTest, !bitstring_same(&bit_string, &bit_string3)); } @@ -927,22 +933,22 @@ void testCharacterString(Test *pTest) status = characterstring_init(&bacnet_string, CHARACTER_ANSI_X34, NULL, 0); ct_test(pTest, status == true); ct_test(pTest, characterstring_length(&bacnet_string) == 0); - ct_test(pTest, - characterstring_encoding(&bacnet_string) == CHARACTER_ANSI_X34); + ct_test( + pTest, characterstring_encoding(&bacnet_string) == CHARACTER_ANSI_X34); /* bounds check */ status = characterstring_init(&bacnet_string, CHARACTER_ANSI_X34, NULL, - characterstring_capacity(&bacnet_string) + 1); + characterstring_capacity(&bacnet_string) + 1); ct_test(pTest, status == false); status = characterstring_truncate( &bacnet_string, characterstring_capacity(&bacnet_string) + 1); ct_test(pTest, status == false); - status = characterstring_truncate(&bacnet_string, - characterstring_capacity(&bacnet_string)); + status = characterstring_truncate( + &bacnet_string, characterstring_capacity(&bacnet_string)); ct_test(pTest, status == true); test_length = strlen(test_value); - status = characterstring_init(&bacnet_string, CHARACTER_ANSI_X34, - &test_value[0], test_length); + status = characterstring_init( + &bacnet_string, CHARACTER_ANSI_X34, &test_value[0], test_length); ct_test(pTest, status == true); value = characterstring_value(&bacnet_string); length = characterstring_length(&bacnet_string); @@ -951,8 +957,8 @@ void testCharacterString(Test *pTest) ct_test(pTest, value[i] == test_value[i]); } test_length = strlen(test_append_value); - status = characterstring_append(&bacnet_string, &test_append_value[0], - test_length); + status = characterstring_append( + &bacnet_string, &test_append_value[0], test_length); strcat(test_append_string, test_value); strcat(test_append_string, test_append_value); test_length = strlen(test_append_string); @@ -986,17 +992,17 @@ void testOctetString(Test *pTest) ct_test(pTest, value[i] == 0); } /* bounds check */ - status = octetstring_init(&bacnet_string, NULL, - octetstring_capacity(&bacnet_string) + 1); + status = octetstring_init( + &bacnet_string, NULL, octetstring_capacity(&bacnet_string) + 1); ct_test(pTest, status == false); - status = octetstring_init(&bacnet_string, NULL, - octetstring_capacity(&bacnet_string)); + status = octetstring_init( + &bacnet_string, NULL, octetstring_capacity(&bacnet_string)); ct_test(pTest, status == true); - status = octetstring_truncate(&bacnet_string, - octetstring_capacity(&bacnet_string) + 1); + status = octetstring_truncate( + &bacnet_string, octetstring_capacity(&bacnet_string) + 1); ct_test(pTest, status == false); - status = octetstring_truncate(&bacnet_string, - octetstring_capacity(&bacnet_string)); + status = octetstring_truncate( + &bacnet_string, octetstring_capacity(&bacnet_string)); ct_test(pTest, status == true); test_length = strlen((char *)test_value); diff --git a/include/bacstr.h b/src/bacnet/bacstr.h similarity index 99% rename from include/bacstr.h rename to src/bacnet/bacstr.h index 6166929e..8d683c17 100644 --- a/include/bacstr.h +++ b/src/bacnet/bacstr.h @@ -27,8 +27,8 @@ #include #include #include -#include "bacdef.h" -#include "config.h" +#include "bacnet/bacdef.h" +#include "bacnet/config.h" /* bit strings They could be as large as 256/8=32 octets */ diff --git a/src/bacnet/bactext.c b/src/bacnet/bactext.c new file mode 100644 index 00000000..059cd5d9 --- /dev/null +++ b/src/bacnet/bactext.c @@ -0,0 +1,1413 @@ +/*####COPYRIGHTBEGIN#### + ------------------------------------------- + Copyright (C) 2005-2006 Steve Karg + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to: + The Free Software Foundation, Inc. + 59 Temple Place - Suite 330 + Boston, MA 02111-1307, USA. + + As a special exception, if other files instantiate templates or + use macros or inline functions from this file, or you compile + this file and link it with other works to produce a work based + on this file, this file does not by itself cause the resulting + work to be covered by the GNU General Public License. However + the source code for this file must still be made available in + accordance with section (3) of the GNU General Public License. + + This exception does not invalidate any other reasons why a work + based on this file might be covered by the GNU General Public + License. + ------------------------------------------- +####COPYRIGHTEND####*/ + +#include +#include "bacnet/indtext.h" +#include "bacnet/bacenum.h" +#include "bacnet/bactext.h" + +/** @file bactext.c Lookup or Translate BACnet Name Text */ + +static const char *ASHRAE_Reserved_String = "Reserved for Use by ASHRAE"; +static const char *Vendor_Proprietary_String = "Vendor Proprietary Value"; + +INDTEXT_DATA bacnet_confirmed_service_names[] = { + { SERVICE_CONFIRMED_ACKNOWLEDGE_ALARM, "Acknowledge-Alarm" }, + { SERVICE_CONFIRMED_COV_NOTIFICATION, "COV-Notification" }, + { SERVICE_CONFIRMED_EVENT_NOTIFICATION, "Event-Notification" }, + { SERVICE_CONFIRMED_GET_ALARM_SUMMARY, "Get-Alarm-Summary" }, + { SERVICE_CONFIRMED_GET_ENROLLMENT_SUMMARY, "Get-Enrollment-Summary" }, + { SERVICE_CONFIRMED_SUBSCRIBE_COV, "Subscribe-COV" }, + { SERVICE_CONFIRMED_ATOMIC_READ_FILE, "Atomic-Read-File" }, + { SERVICE_CONFIRMED_ATOMIC_WRITE_FILE, "Atomic-Write-File" }, + { SERVICE_CONFIRMED_ADD_LIST_ELEMENT, "Add-List-Element" }, + { SERVICE_CONFIRMED_REMOVE_LIST_ELEMENT, "Remove-List-Element" }, + { SERVICE_CONFIRMED_CREATE_OBJECT, "Create-Object" }, + { SERVICE_CONFIRMED_DELETE_OBJECT, "Delete-Object" }, + { SERVICE_CONFIRMED_READ_PROPERTY, "Read-Property" }, + { SERVICE_CONFIRMED_READ_PROP_CONDITIONAL, "Read-Property-Conditional" }, + { SERVICE_CONFIRMED_READ_PROP_MULTIPLE, "Read-Property-Multiple" }, + { SERVICE_CONFIRMED_WRITE_PROPERTY, "Write-Property" }, + { SERVICE_CONFIRMED_WRITE_PROP_MULTIPLE, "Write-Property-Multiple" }, + { SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL, + "Device-Communication-Control" }, + { SERVICE_CONFIRMED_PRIVATE_TRANSFER, "Private-Transfer" }, + { SERVICE_CONFIRMED_TEXT_MESSAGE, "Text-Message" }, + { SERVICE_CONFIRMED_REINITIALIZE_DEVICE, "Reinitialize-Device" }, + { SERVICE_CONFIRMED_VT_OPEN, "VT-Open" }, + { SERVICE_CONFIRMED_VT_CLOSE, "VT-Close" }, + { SERVICE_CONFIRMED_VT_DATA, "VT-Data" }, + { SERVICE_CONFIRMED_AUTHENTICATE, "Authenticate" }, + { SERVICE_CONFIRMED_REQUEST_KEY, "Request-Key" }, + { SERVICE_CONFIRMED_READ_RANGE, "Read-Range" }, + { SERVICE_CONFIRMED_LIFE_SAFETY_OPERATION, "Life-Safety_Operation" }, + { SERVICE_CONFIRMED_SUBSCRIBE_COV_PROPERTY, "Subscribe-COV-Property" }, + { SERVICE_CONFIRMED_GET_EVENT_INFORMATION, "Get-Event-Information" }, + { 0, NULL } +}; + +const char *bactext_confirmed_service_name(unsigned index) +{ + return indtext_by_index_default( + bacnet_confirmed_service_names, index, ASHRAE_Reserved_String); +} + +INDTEXT_DATA bacnet_unconfirmed_service_names[] = { { SERVICE_UNCONFIRMED_I_AM, + "I-Am" }, + { SERVICE_UNCONFIRMED_I_HAVE, "I-Have" }, + { SERVICE_UNCONFIRMED_COV_NOTIFICATION, "COV-Notification" }, + { SERVICE_UNCONFIRMED_EVENT_NOTIFICATION, "Event-Notification" }, + { SERVICE_UNCONFIRMED_PRIVATE_TRANSFER, "Private-Transfer" }, + { SERVICE_UNCONFIRMED_TEXT_MESSAGE, "Text-Message" }, + { SERVICE_UNCONFIRMED_TIME_SYNCHRONIZATION, "Time-Synchronization" }, + { SERVICE_UNCONFIRMED_WHO_HAS, "Who-Has" }, + { SERVICE_UNCONFIRMED_WHO_IS, "Who-Is" }, + { SERVICE_UNCONFIRMED_UTC_TIME_SYNCHRONIZATION, + "UTC-Time-Synchronization" }, + { SERVICE_UNCONFIRMED_WRITE_GROUP, "Write-Group" }, { 0, NULL } }; + +const char *bactext_unconfirmed_service_name(unsigned index) +{ + return indtext_by_index_default( + bacnet_unconfirmed_service_names, index, ASHRAE_Reserved_String); +} + +INDTEXT_DATA bacnet_application_tag_names[] = { { BACNET_APPLICATION_TAG_NULL, + "Null" }, + { BACNET_APPLICATION_TAG_BOOLEAN, "Boolean" }, + { BACNET_APPLICATION_TAG_UNSIGNED_INT, "Unsigned Int" }, + { BACNET_APPLICATION_TAG_SIGNED_INT, "Signed Int" }, + { BACNET_APPLICATION_TAG_REAL, "Real" }, + { BACNET_APPLICATION_TAG_DOUBLE, "Double" }, + { BACNET_APPLICATION_TAG_OCTET_STRING, "Octet String" }, + { BACNET_APPLICATION_TAG_CHARACTER_STRING, "Character String" }, + { BACNET_APPLICATION_TAG_BIT_STRING, "Bit String" }, + { BACNET_APPLICATION_TAG_ENUMERATED, "Enumerated" }, + { BACNET_APPLICATION_TAG_DATE, "Date" }, + { BACNET_APPLICATION_TAG_TIME, "Time" }, + { BACNET_APPLICATION_TAG_OBJECT_ID, "Object ID" }, + { BACNET_APPLICATION_TAG_RESERVE1, "Reserved 1" }, + { BACNET_APPLICATION_TAG_RESERVE2, "Reserved 2" }, + { BACNET_APPLICATION_TAG_RESERVE3, "Reserved 3" }, { 0, NULL } }; + +const char *bactext_application_tag_name(unsigned index) +{ + return indtext_by_index_default( + bacnet_application_tag_names, index, ASHRAE_Reserved_String); +} + +bool bactext_application_tag_index( + const char *search_name, unsigned *found_index) +{ + return indtext_by_istring( + bacnet_application_tag_names, search_name, found_index); +} + +INDTEXT_DATA bacnet_object_type_names[] = { + { OBJECT_ANALOG_INPUT, "analog-input" }, + { OBJECT_ANALOG_OUTPUT, "analog-output" }, + { OBJECT_ANALOG_VALUE, "analog-value" }, + { OBJECT_BINARY_INPUT, "binary-input" }, + { OBJECT_BINARY_OUTPUT, "binary-output" }, + { OBJECT_BINARY_VALUE, "binary-value" }, { OBJECT_CALENDAR, "calendar" }, + { OBJECT_COMMAND, "command" }, { OBJECT_DEVICE, "device" }, + { OBJECT_EVENT_ENROLLMENT, "event-enrollment" }, { OBJECT_FILE, "file" }, + { OBJECT_GROUP, "group" }, { OBJECT_LOOP, "loop" }, + { OBJECT_MULTI_STATE_INPUT, "multi-state-input" }, + { OBJECT_MULTI_STATE_OUTPUT, "multi-state-output" }, + { OBJECT_NOTIFICATION_CLASS, "notification-class" }, + { OBJECT_PROGRAM, "program" }, { OBJECT_SCHEDULE, "schedule" }, + { OBJECT_AVERAGING, "averaging" }, + { OBJECT_MULTI_STATE_VALUE, "multi-state-value" }, + { OBJECT_TRENDLOG, "trend-log" }, + { OBJECT_LIFE_SAFETY_POINT, "life-safety-point" }, + { OBJECT_LIFE_SAFETY_ZONE, "life-safety-zone" }, + { OBJECT_ACCUMULATOR, "accumulator" }, + { OBJECT_PULSE_CONVERTER, "pulse-converter" }, + { OBJECT_EVENT_LOG, "event-log" }, { OBJECT_GLOBAL_GROUP, "global-group" }, + { OBJECT_TREND_LOG_MULTIPLE, "trend-log-multiple" }, + { OBJECT_LOAD_CONTROL, "load-control" }, + { OBJECT_STRUCTURED_VIEW, "structured-view" }, + { OBJECT_ACCESS_DOOR, "access-door" }, + { OBJECT_LIGHTING_OUTPUT, "lighting-output" }, + { OBJECT_ACCESS_CREDENTIAL, "access-credential" }, + { OBJECT_ACCESS_POINT, "access-point" }, + { OBJECT_ACCESS_RIGHTS, "access-rights" }, + { OBJECT_ACCESS_USER, "access-user" }, + { OBJECT_ACCESS_ZONE, "access-zone" }, + { OBJECT_CREDENTIAL_DATA_INPUT, "credential-data-input" }, + { OBJECT_NETWORK_SECURITY, "network-security" }, + { OBJECT_BITSTRING_VALUE, "bitstring-value" }, + { OBJECT_CHARACTERSTRING_VALUE, "characterstring-value" }, + { OBJECT_DATE_PATTERN_VALUE, "date-pattern-value" }, + { OBJECT_DATE_VALUE, "date-value" }, + { OBJECT_DATETIME_PATTERN_VALUE, "datetime-pattern-value" }, + { OBJECT_DATETIME_VALUE, "datetime-value" }, + { OBJECT_INTEGER_VALUE, "integer-value" }, + { OBJECT_LARGE_ANALOG_VALUE, "large-analog-value" }, + { OBJECT_OCTETSTRING_VALUE, "octetstring-value" }, + { OBJECT_POSITIVE_INTEGER_VALUE, "positive-integer-value" }, + { OBJECT_TIME_PATTERN_VALUE, "time-pattern-value" }, + { OBJECT_TIME_VALUE, "time-value" }, + { OBJECT_NOTIFICATION_FORWARDER, "notification-forwarder" }, + { OBJECT_ALERT_ENROLLMENT, "alert-enrollment" }, + { OBJECT_CHANNEL, "channel" }, + { OBJECT_LIGHTING_OUTPUT, "lighting-output" }, + { OBJECT_BINARY_LIGHTING_OUTPUT, "binary-lighting-output" }, + { OBJECT_NETWORK_PORT, "network-port" }, { 0, NULL } + /* Enumerated values 0-127 are reserved for definition by ASHRAE. + Enumerated values 128-1023 may be used by others subject to + the procedures and constraints described in Clause 23. */ +}; + +const char *bactext_object_type_name(unsigned index) +{ + return indtext_by_index_split_default(bacnet_object_type_names, index, 128, + ASHRAE_Reserved_String, Vendor_Proprietary_String); +} + +bool bactext_object_type_index(const char *search_name, unsigned *found_index) +{ + return indtext_by_istring( + bacnet_object_type_names, search_name, found_index); +} + +INDTEXT_DATA bacnet_property_names[] = { + /* FIXME: use the enumerations from bacenum.h */ + { PROP_ACKED_TRANSITIONS, "acked-transitions" }, + { PROP_ACK_REQUIRED, "ack-required" }, { PROP_ACTION, "action" }, + { PROP_ACTION_TEXT, "action-text" }, { PROP_ACTIVE_TEXT, "active-text" }, + { PROP_ACTIVE_VT_SESSIONS, "active-vt-sessions" }, + { PROP_ALARM_VALUE, "alarm-value" }, { PROP_ALARM_VALUES, "alarm-values" }, + { PROP_ALL, "all" }, + { PROP_ALL_WRITES_SUCCESSFUL, "all-writes-successful" }, + { PROP_APDU_SEGMENT_TIMEOUT, "apdu-segment-timeout" }, + { PROP_APDU_TIMEOUT, "apdu-timeout" }, + { PROP_APPLICATION_SOFTWARE_VERSION, "application-software-version" }, + { PROP_ARCHIVE, "archive" }, { PROP_BIAS, "bias" }, + { PROP_CHANGE_OF_STATE_COUNT, "change-of-state-count" }, + { PROP_CHANGE_OF_STATE_TIME, "change-of-state-time" }, + { PROP_NOTIFICATION_CLASS, "notification-class" }, + { PROP_BLANK_1, "(deleted in 135-2001)" }, + { PROP_CONTROLLED_VARIABLE_REFERENCE, "controlled-variable-reference" }, + { PROP_CONTROLLED_VARIABLE_UNITS, "controlled-variable-units" }, + { PROP_CONTROLLED_VARIABLE_VALUE, "controlled-variable-value" }, + { PROP_COV_INCREMENT, "COV-increment" }, { PROP_DATE_LIST, "datelist" }, + { PROP_DAYLIGHT_SAVINGS_STATUS, "daylight-savings-status" }, + { PROP_DEADBAND, "deadband" }, + { PROP_DERIVATIVE_CONSTANT, "derivative-constant" }, + { PROP_DERIVATIVE_CONSTANT_UNITS, "derivative-constant-units" }, + { PROP_DESCRIPTION, "description" }, + { PROP_DESCRIPTION_OF_HALT, "description-of-halt" }, + { PROP_DEVICE_ADDRESS_BINDING, "device-address-binding" }, + { PROP_DEVICE_TYPE, "device-type" }, + { PROP_EFFECTIVE_PERIOD, "effective-period" }, + { PROP_ELAPSED_ACTIVE_TIME, "elapsed-active-time" }, + { PROP_ERROR_LIMIT, "error-limit" }, { PROP_EVENT_ENABLE, "event-enable" }, + { PROP_EVENT_STATE, "event-state" }, { PROP_EVENT_TYPE, "event-type" }, + { PROP_EXCEPTION_SCHEDULE, "exception-schedule" }, + { PROP_FAULT_VALUES, "fault-values" }, + { PROP_FEEDBACK_VALUE, "feedback-value" }, + { PROP_FILE_ACCESS_METHOD, "file-access-method" }, + { PROP_FILE_SIZE, "file-size" }, { PROP_FILE_TYPE, "file-type" }, + { PROP_FIRMWARE_REVISION, + "firmware-revision" }, /* VTS wants "revision", not "version" */ + { PROP_HIGH_LIMIT, "high-limit" }, { PROP_INACTIVE_TEXT, "inactive-text" }, + { PROP_IN_PROCESS, "in-process" }, { PROP_INSTANCE_OF, "instance-of" }, + { PROP_INTEGRAL_CONSTANT, "integral-constant" }, + { PROP_INTEGRAL_CONSTANT_UNITS, "integral-constant-units" }, + { PROP_ISSUE_CONFIRMED_NOTIFICATIONS, "issue-confirmednotifications" }, + { PROP_LIMIT_ENABLE, "limit-enable" }, + { PROP_LIST_OF_GROUP_MEMBERS, "list-of-group-members" }, + { PROP_LIST_OF_OBJECT_PROPERTY_REFERENCES, + "list-of-object-property-references" }, + { PROP_LIST_OF_SESSION_KEYS, "list-of-session-keys" }, + { PROP_LOCAL_DATE, "local-date" }, { PROP_LOCAL_TIME, "local-time" }, + { PROP_LOCATION, "location" }, { PROP_LOW_LIMIT, "low-limit" }, + { PROP_MANIPULATED_VARIABLE_REFERENCE, "manipulated-variable-reference" }, + { PROP_MAXIMUM_OUTPUT, "maximum-output" }, + { PROP_MAX_APDU_LENGTH_ACCEPTED, "max-apdu-length-accepted" }, + { PROP_MAX_INFO_FRAMES, "max-info-frames" }, + { PROP_MAX_MASTER, "max-master" }, + { PROP_MAX_PRES_VALUE, "max-pres-value" }, + { PROP_MINIMUM_OFF_TIME, "minimum-off-time" }, + { PROP_MINIMUM_ON_TIME, "minimum-on-time" }, + { PROP_MINIMUM_OUTPUT, "minimum-output" }, + { PROP_MIN_PRES_VALUE, "min-pres-value" }, + { PROP_MODEL_NAME, "model-name" }, + { PROP_MODIFICATION_DATE, "modification-date" }, + { PROP_NOTIFY_TYPE, "notify-type" }, + { PROP_NUMBER_OF_APDU_RETRIES, "number-of-APDU-retries" }, + { PROP_NUMBER_OF_STATES, "number-of-states" }, + { PROP_OBJECT_IDENTIFIER, "object-identifier" }, + { PROP_OBJECT_LIST, "object-list" }, { PROP_OBJECT_NAME, "object-name" }, + { PROP_OBJECT_PROPERTY_REFERENCE, "object-property-reference" }, + { PROP_OBJECT_TYPE, "object-type" }, { PROP_OPTIONAL, "optional" }, + { PROP_OUT_OF_SERVICE, "out-of-service" }, + { PROP_OUTPUT_UNITS, "output-units" }, + { PROP_EVENT_PARAMETERS, "event-parameters" }, + { PROP_POLARITY, "polarity" }, { PROP_PRESENT_VALUE, "present-value" }, + { PROP_PRIORITY, "priority" }, { PROP_PRIORITY_ARRAY, "priority-array" }, + { PROP_PRIORITY_FOR_WRITING, "priority-for-writing" }, + { PROP_PROCESS_IDENTIFIER, "process-identifier" }, + { PROP_PROGRAM_CHANGE, "program-change" }, + { PROP_PROGRAM_LOCATION, "program-location" }, + { PROP_PROGRAM_STATE, "program-state" }, + { PROP_PROPORTIONAL_CONSTANT, "proportional-constant" }, + { PROP_PROPORTIONAL_CONSTANT_UNITS, "proportional-constant-units" }, + { PROP_PROTOCOL_CONFORMANCE_CLASS, "protocol-conformance-class" }, + { PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED, "protocol-object-types-supported" }, + { PROP_PROTOCOL_SERVICES_SUPPORTED, "protocol-services-supported" }, + { PROP_PROTOCOL_VERSION, "protocol-version" }, + { PROP_READ_ONLY, "read-only" }, + { PROP_REASON_FOR_HALT, "reason-for-halt" }, + { PROP_RECIPIENT, "recipient" }, { PROP_RECIPIENT_LIST, "recipient-list" }, + { PROP_RELIABILITY, "reliability" }, + { PROP_RELINQUISH_DEFAULT, "relinquish-default" }, + { PROP_REQUIRED, "required" }, { PROP_RESOLUTION, "resolution" }, + { PROP_SEGMENTATION_SUPPORTED, "segmentation-supported" }, + { PROP_SETPOINT, "setpoint" }, + { PROP_SETPOINT_REFERENCE, "setpoint-reference" }, + { PROP_STATE_TEXT, "state-text" }, { PROP_STATUS_FLAGS, "status-flags" }, + { PROP_SYSTEM_STATUS, "system-status" }, { PROP_TIME_DELAY, "time-delay" }, + { PROP_TIME_OF_ACTIVE_TIME_RESET, "time-of-active-time-reset" }, + { PROP_TIME_OF_STATE_COUNT_RESET, "time-of-state-count-reset" }, + { PROP_TIME_SYNCHRONIZATION_RECIPIENTS, "time-synchronization-recipients" }, + { PROP_UNITS, "units" }, { PROP_UPDATE_INTERVAL, "update-interval" }, + { PROP_UTC_OFFSET, "utc-offset" }, + { PROP_VENDOR_IDENTIFIER, "vendor-identifier" }, + { PROP_VENDOR_NAME, "vendor-name" }, + { PROP_VT_CLASSES_SUPPORTED, "vt-classes-supported" }, + { PROP_WEEKLY_SCHEDULE, "weekly-schedule" }, + { PROP_ATTEMPTED_SAMPLES, "attempted-samples" }, + { PROP_AVERAGE_VALUE, "average-value" }, + { PROP_BUFFER_SIZE, "buffer-size" }, + { PROP_CLIENT_COV_INCREMENT, "client-cov-increment" }, + { PROP_COV_RESUBSCRIPTION_INTERVAL, "cov-resubscription-interval" }, + { PROP_CURRENT_NOTIFY_TIME, "current-notify-time" }, + { PROP_EVENT_TIME_STAMPS, "event-time-stamps" }, + { PROP_LOG_BUFFER, "log-buffer" }, + { PROP_LOG_DEVICE_OBJECT_PROPERTY, "log-device-object-property" }, + { PROP_ENABLE, "enable" }, { PROP_LOG_INTERVAL, "log-interval" }, + { PROP_MAXIMUM_VALUE, "maximum-value" }, + { PROP_MINIMUM_VALUE, "minimum-value" }, + { PROP_NOTIFICATION_THRESHOLD, "notification-threshold" }, + { PROP_PREVIOUS_NOTIFY_TIME, "previous-notify-time" }, + { PROP_PROTOCOL_REVISION, "protocol-revision" }, + { PROP_RECORDS_SINCE_NOTIFICATION, "records-since-notification" }, + { PROP_RECORD_COUNT, "record-count" }, { PROP_START_TIME, "start-time" }, + { PROP_STOP_TIME, "stop-time" }, { PROP_STOP_WHEN_FULL, "stop-when-full" }, + { PROP_TOTAL_RECORD_COUNT, "total-record-count" }, + { PROP_VALID_SAMPLES, "valid-samples" }, + { PROP_WINDOW_INTERVAL, "window-interval" }, + { PROP_WINDOW_SAMPLES, "window-samples" }, + { PROP_MAXIMUM_VALUE_TIMESTAMP, "maximum-value-timestamp" }, + { PROP_MINIMUM_VALUE_TIMESTAMP, "minimum-value-timestamp" }, + { PROP_VARIANCE_VALUE, "variance-value" }, + { PROP_ACTIVE_COV_SUBSCRIPTIONS, "active-cov-subscriptions" }, + { PROP_BACKUP_FAILURE_TIMEOUT, "backup-failure-timeout" }, + { PROP_CONFIGURATION_FILES, "configuration-files" }, + { PROP_DATABASE_REVISION, "database-revision" }, + { PROP_DIRECT_READING, "direct-reading" }, + { PROP_LAST_RESTORE_TIME, "last-restore-time" }, + { PROP_MAINTENANCE_REQUIRED, "maintenance-required" }, + { PROP_MEMBER_OF, "member-of" }, { PROP_MODE, "mode" }, + { PROP_OPERATION_EXPECTED, "operation-expected" }, + { PROP_SETTING, "setting" }, { PROP_SILENCED, "silenced" }, + { PROP_TRACKING_VALUE, "tracking-value" }, + { PROP_ZONE_MEMBERS, "zone-members" }, + { PROP_LIFE_SAFETY_ALARM_VALUES, "life-safety-alarm-values" }, + { PROP_MAX_SEGMENTS_ACCEPTED, "max-segments-accepted" }, + { PROP_PROFILE_NAME, "profile-name" }, + { PROP_AUTO_SLAVE_DISCOVERY, "auto-slave-discovery" }, + { PROP_MANUAL_SLAVE_ADDRESS_BINDING, "manual-slave-address-binding" }, + { PROP_SLAVE_ADDRESS_BINDING, "slave-address-binding" }, + { PROP_SLAVE_PROXY_ENABLE, "slave-proxy-enable" }, + { PROP_LAST_NOTIFY_RECORD, "last-notify-record" }, + { PROP_SCHEDULE_DEFAULT, "schedule-default" }, + { PROP_ACCEPTED_MODES, "accepted-modes" }, + { PROP_ADJUST_VALUE, "adjust-value" }, { PROP_COUNT, "count" }, + { PROP_COUNT_BEFORE_CHANGE, "count-before-change" }, + { PROP_COUNT_CHANGE_TIME, "count-change-time" }, + { PROP_COV_PERIOD, "COV-period" }, + { PROP_INPUT_REFERENCE, "input-reference" }, + { PROP_LIMIT_MONITORING_INTERVAL, "limit-monitoring-interval" }, + { PROP_LOGGING_OBJECT, "logging-object" }, + { PROP_LOGGING_RECORD, "logging-record" }, { PROP_PRESCALE, "prescale" }, + { PROP_PULSE_RATE, "pulse-rate" }, { PROP_SCALE, "scale" }, + { PROP_SCALE_FACTOR, "scale-factor" }, { PROP_UPDATE_TIME, "update-time" }, + { PROP_VALUE_BEFORE_CHANGE, "value-before-change" }, + { PROP_VALUE_SET, "value-set" }, + { PROP_VALUE_CHANGE_TIME, "value-change-time" }, + { PROP_ALIGN_INTERVALS, "align-intervals" }, + { PROP_INTERVAL_OFFSET, "interval-offset" }, + { PROP_LAST_RESTART_REASON, "last-restart-reason" }, + { PROP_LOGGING_TYPE, "logging-type" }, + { PROP_TIME_OF_DEVICE_RESTART, "time-of-device-restart" }, + { PROP_TIME_SYNCHRONIZATION_INTERVAL, "time-synchronization-interval" }, + { PROP_TRIGGER, "trigger" }, + { PROP_UTC_TIME_SYNCHRONIZATION_RECIPIENTS, + "utc-time-synchronization-recipients" }, + { PROP_NODE_SUBTYPE, "node-subtype" }, { PROP_NODE_TYPE, "node-type" }, + { PROP_STRUCTURED_OBJECT_LIST, "structured-object-list" }, + { PROP_SUBORDINATE_ANNOTATIONS, "subordinate-annotations" }, + { PROP_SUBORDINATE_LIST, "subordinate-list" }, + { PROP_ACTUAL_SHED_LEVEL, "actual-shed-level" }, + { PROP_DUTY_WINDOW, "duty-window" }, + { PROP_EXPECTED_SHED_LEVEL, "expected-shed-level" }, + { PROP_FULL_DUTY_BASELINE, "full-duty-baseline" }, + { PROP_REQUESTED_SHED_LEVEL, "requested-shed-level" }, + { PROP_SHED_DURATION, "shed-duration" }, + { PROP_SHED_LEVEL_DESCRIPTIONS, "shed-level-descriptions" }, + { PROP_SHED_LEVELS, "shed-levels" }, + { PROP_STATE_DESCRIPTION, "state-description" }, + { PROP_DOOR_ALARM_STATE, "door-alarm-state" }, + { PROP_DOOR_EXTENDED_PULSE_TIME, "door-extended-pulse-time" }, + { PROP_DOOR_MEMBERS, "door-members" }, + { PROP_DOOR_OPEN_TOO_LONG_TIME, "door-open-too-long-time" }, + { PROP_DOOR_PULSE_TIME, "door-pulse-time" }, + { PROP_DOOR_STATUS, "door-status" }, + { PROP_DOOR_UNLOCK_DELAY_TIME, "door-unlock-delay-time" }, + { PROP_LOCK_STATUS, "lock-status" }, + { PROP_MASKED_ALARM_VALUES, "masked-alarm-values" }, + { PROP_SECURED_STATUS, "secured-status" }, + { PROP_ABSENTEE_LIMIT, "absentee-limit" }, + { PROP_ACCESS_ALARM_EVENTS, "access-alarm-events" }, + { PROP_ACCESS_DOORS, "access-doors" }, + { PROP_ACCESS_EVENT, "access-event" }, + { PROP_ACCESS_EVENT_AUTHENTICATION_FACTOR, + "access-event-authentication-factor" }, + { PROP_ACCESS_EVENT_CREDENTIAL, "access-event-credential" }, + { PROP_ACCESS_EVENT_TIME, "access-event-time" }, + { PROP_ACCESS_TRANSACTION_EVENTS, "access-transaction-events" }, + { PROP_ACCOMPANIMENT, "accompaniment" }, + { PROP_ACCOMPANIMENT_TIME, "accompaniment-time" }, + { PROP_ACTIVATION_TIME, "activation-time" }, + { PROP_ACTIVE_AUTHENTICATION_POLICY, "active-authentication-policy" }, + { PROP_ASSIGNED_ACCESS_RIGHTS, "assigned-access-rights" }, + { PROP_AUTHENTICATION_FACTORS, "authentication-factors" }, + { PROP_AUTHENTICATION_POLICY_LIST, "authentication-policy-list" }, + { PROP_AUTHENTICATION_POLICY_NAMES, "authentication-policy-names" }, + { PROP_AUTHENTICATION_STATUS, "authentication-status" }, + { PROP_AUTHORIZATION_MODE, "authorization-mode" }, + { PROP_BELONGS_TO, "belongs-to" }, + { PROP_CREDENTIAL_DISABLE, "credential-disable" }, + { PROP_CREDENTIAL_STATUS, "credential-status" }, + { PROP_CREDENTIALS, "credentials" }, + { PROP_CREDENTIALS_IN_ZONE, "credentials-in-zone" }, + { PROP_DAYS_REMAINING, "days-remaining" }, + { PROP_ENTRY_POINTS, "entry-points" }, { PROP_EXIT_POINTS, "exit-points" }, + { PROP_EXPIRATION_TIME, "expiration-time" }, + { PROP_EXTENDED_TIME_ENABLE, "extended-time-enable" }, + { PROP_FAILED_ATTEMPT_EVENTS, "failed-attempt-events" }, + { PROP_FAILED_ATTEMPTS, "failed-attempts" }, + { PROP_FAILED_ATTEMPTS_TIME, "failed-attempts-time" }, + { PROP_LAST_ACCESS_EVENT, "last-access-event" }, + { PROP_LAST_ACCESS_POINT, "last-access-point" }, + { PROP_LAST_CREDENTIAL_ADDED, "last-credential-added" }, + { PROP_LAST_CREDENTIAL_ADDED_TIME, "last-credential-added-time" }, + { PROP_LAST_CREDENTIAL_REMOVED, "last-credential-removed" }, + { PROP_LAST_CREDENTIAL_REMOVED_TIME, "last-credential-removed-time" }, + { PROP_LAST_USE_TIME, "last-use-time" }, { PROP_LOCKOUT, "lockout" }, + { PROP_LOCKOUT_RELINQUISH_TIME, "lockout-relinquish-time" }, + { PROP_MASTER_EXEMPTION, "master-exemption" }, + { PROP_MAX_FAILED_ATTEMPTS, "max-failed-attempts" }, + { PROP_MEMBERS, "members" }, { PROP_MUSTER_POINT, "muster-point" }, + { PROP_NEGATIVE_ACCESS_RULES, "negative-access-rules" }, + { PROP_NUMBER_OF_AUTHENTICATION_POLICIES, + "number-of-authentication-policies" }, + { PROP_OCCUPANCY_COUNT, "occupancy-count" }, + { PROP_OCCUPANCY_COUNT_ADJUST, "occupancy-count-adjust" }, + { PROP_OCCUPANCY_COUNT_ENABLE, "occupancy-count-enable" }, + { PROP_OCCUPANCY_EXEMPTION, "occupancy-exemption" }, + { PROP_OCCUPANCY_LOWER_LIMIT, "occupancy-lower-limit" }, + { PROP_OCCUPANCY_LOWER_LIMIT_ENFORCED, "occupancy-lower-limit-enforced" }, + { PROP_OCCUPANCY_STATE, "occupancy-state" }, + { PROP_OCCUPANCY_UPPER_LIMIT, "occupancy-upper-limit" }, + { PROP_OCCUPANCY_UPPER_LIMIT_ENFORCED, "occupancy-upper-limit-enforced" }, + { PROP_PASSBACK_EXEMPTION, "passback-exemption" }, + { PROP_PASSBACK_MODE, "passback-mode" }, + { PROP_PASSBACK_TIMEOUT, "passback-timeout" }, + { PROP_POSITIVE_ACCESS_RULES, "positive-access-rules" }, + { PROP_REASON_FOR_DISABLE, "reason-for-disable" }, + { PROP_SUPPORTED_FORMATS, "supported-formats" }, + { PROP_SUPPORTED_FORMAT_CLASSES, "supported-format-classes" }, + { PROP_THREAT_AUTHORITY, "threat-authority" }, + { PROP_THREAT_LEVEL, "threat-level" }, { PROP_TRACE_FLAG, "trace-flag" }, + { PROP_TRANSACTION_NOTIFICATION_CLASS, "transaction-notification-class" }, + { PROP_USER_EXTERNAL_IDENTIFIER, "user-external-identifier" }, + { PROP_USER_INFORMATION_REFERENCE, "user-information-reference" }, + { PROP_USER_INFORMATION_REFERENCE, "user-information-reference" }, + { PROP_USER_NAME, "user-name" }, { PROP_USER_TYPE, "user-type" }, + { PROP_USES_REMAINING, "uses-remaining" }, { PROP_ZONE_FROM, "zone-from" }, + { PROP_ZONE_TO, "zone-to" }, + { PROP_VERIFICATION_TIME, "verification-time" }, + { PROP_BASE_DEVICE_SECURITY_POLICY, "base-device-security-policy" }, + { PROP_DISTRIBUTION_KEY_REVISION, "distribution-key-revision" }, + { PROP_DO_NOT_HIDE, "do-not-hide" }, { PROP_KEY_SETS, "key-sets" }, + { PROP_LAST_KEY_SERVER, "last-key-server" }, + { PROP_NETWORK_ACCESS_SECURITY_POLICIES, + "network-access-security-policies" }, + { PROP_PACKET_REORDER_TIME, "packet-reorder-time" }, + { PROP_SECURITY_PDU_TIMEOUT, "security-pdu-timeout" }, + { PROP_SECURITY_TIME_WINDOW, "security-time-window" }, + { PROP_SUPPORTED_SECURITY_ALGORITHM, "supported-security-algorithm" }, + { PROP_UPDATE_KEY_SET_TIMEOUT, "update-key-set-timeout" }, + { PROP_BACKUP_AND_RESTORE_STATE, "backup-and-restore-state" }, + { PROP_BACKUP_PREPARATION_TIME, "backup-preparation-time" }, + { PROP_RESTORE_COMPLETION_TIME, "restore-completion-time" }, + { PROP_RESTORE_PREPARATION_TIME, "restore-preparation-time" }, + { PROP_BIT_MASK, "bit-mask" }, { PROP_BIT_TEXT, "bit-text" }, + { PROP_IS_UTC, "is-utc" }, { PROP_GROUP_MEMBERS, "group-members" }, + { PROP_GROUP_MEMBER_NAMES, "group-member-names" }, + { PROP_MEMBER_STATUS_FLAGS, "member-status-flags" }, + { PROP_REQUESTED_UPDATE_INTERVAL, "requested-update-interval" }, + { PROP_COVU_PERIOD, "covu-period" }, + { PROP_COVU_RECIPIENTS, "covu-recipients" }, + { PROP_EVENT_MESSAGE_TEXTS, "event-message-texts" }, + { PROP_EVENT_MESSAGE_TEXTS_CONFIG, "event-message-texts-config" }, + { PROP_EVENT_DETECTION_ENABLE, "event-detection-enable" }, + { PROP_EVENT_ALGORITHM_INHIBIT, "event-algorithm-inhibit" }, + { PROP_EVENT_ALGORITHM_INHIBIT_REF, "event-algorithm-inhibit-ref" }, + { PROP_TIME_DELAY_NORMAL, "time-delay-normal" }, + { PROP_RELIABILITY_EVALUATION_INHIBIT, "reliability-evaluation-inhibit" }, + { PROP_FAULT_PARAMETERS, "fault-parameters" }, + { PROP_FAULT_TYPE, "fault-type" }, + { PROP_LOCAL_FORWARDING_ONLY, "local-forwarding-only" }, + { PROP_PROCESS_IDENTIFIER_FILTER, "process-identifier-filter" }, + { PROP_SUBSCRIBED_RECIPIENTS, "subscribed-recipients" }, + { PROP_PORT_FILTER, "port-filter" }, + { PROP_AUTHORIZATION_EXEMPTIONS, "authorization-exemptions" }, + { PROP_ALLOW_GROUP_DELAY_INHIBIT, "allow-group-delay-inhibit" }, + { PROP_CHANNEL_NUMBER, "channel-number" }, + { PROP_CONTROL_GROUPS, "control-groups" }, + { PROP_EXECUTION_DELAY, "execution-delay" }, + { PROP_LAST_PRIORITY, "last-priority" }, + { PROP_WRITE_STATUS, "write-status" }, + { PROP_PROPERTY_LIST, "property-list" }, + { PROP_SERIAL_NUMBER, "serial-number" }, + { PROP_BLINK_WARN_ENABLE, "blink-warn-enable" }, + { PROP_DEFAULT_FADE_TIME, "default-fade-time" }, + { PROP_DEFAULT_RAMP_RATE, "default-ramp-rate" }, + { PROP_DEFAULT_STEP_INCREMENT, "default-step-increment" }, + { PROP_EGRESS_TIME, "egress-time" }, { PROP_IN_PROGRESS, "in-progress" }, + { PROP_INSTANTANEOUS_POWER, "instantaneous-power" }, + { PROP_LIGHTING_COMMAND, "lighting-command" }, + { PROP_LIGHTING_COMMAND_DEFAULT_PRIORITY, + "lighting-command-default-priority" }, + { PROP_MAX_ACTUAL_VALUE, "max-actual-value" }, + { PROP_MIN_ACTUAL_VALUE, "min-actual-value" }, { PROP_POWER, "power" }, + { PROP_TRANSITION, "transition" }, { PROP_EGRESS_ACTIVE, "egress-active" }, + { PROP_INTERFACE_VALUE, "inteface-value" }, + { PROP_FAULT_HIGH_LIMIT, "fault-high-limit" }, + { PROP_FAULT_LOW_LIMIT, "fault-low-limit" }, + { PROP_LOW_DIFF_LIMIT, "low-diff-limit" }, + { PROP_STRIKE_COUNT, "strike-count" }, + { PROP_TIME_OF_STRIKE_COUNT_RESET, "strike-count" }, + { PROP_DEFAULT_TIMEOUT, "default-timeout" }, + { PROP_INITIAL_TIMEOUT, "initial-timeout" }, + { PROP_LAST_STATE_CHANGE, "last-state-change" }, + { PROP_STATE_CHANGE_VALUES, "state-change-values" }, + { PROP_TIMER_RUNNING, "timer-running" }, + { PROP_TIMER_STATE, "timer-state" }, { PROP_APDU_LENGTH, "apdu-length" }, + { PROP_IP_ADDRESS, "ip-address" }, + { PROP_IP_DEFAULT_GATEWAY, "ip-default-gateway" }, + { PROP_IP_DHCP_ENABLE, "ip-dhcp-enable" }, + { PROP_IP_DHCP_LEASE_TIME, "ip-dhcp-lease-time" }, + { PROP_IP_DHCP_LEASE_TIME_REMAINING, "ip-dhcp-lease-time-remaining" }, + { PROP_IP_DHCP_SERVER, "ip-dhcp-server" }, + { PROP_IP_DNS_SERVER, "ip-dns-server" }, + { PROP_BACNET_IP_GLOBAL_ADDRESS, "bacnet-ip-global-address" }, + { PROP_BACNET_IP_MODE, "bacnet-ip-mode" }, + { PROP_BACNET_IP_MULTICAST_ADDRESS, "bacnet-ip-multicast-address" }, + { PROP_BACNET_IP_NAT_TRAVERSAL, "bacnet-ip-nat-traversal" }, + { PROP_IP_SUBNET_MASK, "ip-subnet-mask" }, + { PROP_BACNET_IP_UDP_PORT, "bacnet-ip-udp-port" }, + { PROP_BBMD_ACCEPT_FD_REGISTRATIONS, "bbmd-accept-fd-registrations" }, + { PROP_BBMD_BROADCAST_DISTRIBUTION_TABLE, + "bbmd-broadcast-distribution-table" }, + { PROP_BBMD_FOREIGN_DEVICE_TABLE, "bbmd-foreign-device-table" }, + { PROP_CHANGES_PENDING, "changes-pending" }, { PROP_COMMAND, "command" }, + { PROP_FD_BBMD_ADDRESS, "fd-bbmd-address" }, + { PROP_FD_SUBSCRIPTION_LIFETIME, "fd-subscription-lifetime" }, + { PROP_LINK_SPEED, "link-speed" }, { PROP_LINK_SPEEDS, "link-speeds" }, + { PROP_LINK_SPEED_AUTONEGOTIATE, "link-speed-autonegotiate" }, + { PROP_MAC_ADDRESS, "mac-address" }, + { PROP_NETWORK_INTERFACE_NAME, "network-interface-name" }, + { PROP_NETWORK_NUMBER, "network-number" }, + { PROP_NETWORK_NUMBER_QUALITY, "network-number-quality" }, + { PROP_NETWORK_TYPE, "network-type" }, + { PROP_ROUTING_TABLE, "routing-table" }, + { PROP_VIRTUAL_MAC_ADDRESS_TABLE, "virtual-mac-address-table" }, + { PROP_COMMAND_TIME_ARRAY, "command-time-array" }, + { PROP_CURRENT_COMMAND_PRIORITY, "current-command-priority" }, + { PROP_LAST_COMMAND_TIME, "last-command-time" }, + { PROP_VALUE_SOURCE, "value-source" }, + { PROP_VALUE_SOURCE_ARRAY, "value-source-array" }, + { PROP_BACNET_IPV6_MODE, "bacnet-ipv6-mode" }, + { PROP_IPV6_ADDRESS, "ipv6-address" }, + { PROP_IPV6_PREFIX_LENGTH, "ipv6-prefix-length" }, + { PROP_BACNET_IPV6_UDP_PORT, "bacnet-ipv6-udp-port" }, + { PROP_IPV6_DEFAULT_GATEWAY, "ipv6-default-gateway" }, + { PROP_BACNET_IPV6_MULTICAST_ADDRESS, "bacnet-ipv6-multicast-address" }, + { PROP_IPV6_DNS_SERVER, "ipv6-dns-server" }, + { PROP_IPV6_AUTO_ADDRESSING_ENABLE, "ipv6-auto-addressing-enable" }, + { PROP_IPV6_DHCP_LEASE_TIME, "ipv6-dhcp-lease-time" }, + { PROP_IPV6_DHCP_LEASE_TIME_REMAINING, "ipv6-dhcp-lease-time-remaining" }, + { PROP_IPV6_DHCP_SERVER, "ipv6-dhcp-server" }, + { PROP_IPV6_ZONE_INDEX, "ipv6-zone-index" }, + { PROP_ASSIGNED_LANDING_CALLS, "assigned-landing-calls" }, + { PROP_CAR_ASSIGNED_DIRECTION, "car-assigned-direction" }, + { PROP_CAR_DOOR_COMMAND, "car-door-command" }, + { PROP_CAR_DOOR_STATUS, "car-door-status" }, + { PROP_CAR_DOOR_TEXT, "car-door-text" }, + { PROP_CAR_DOOR_ZONE, "car-door-zone" }, + { PROP_CAR_DRIVE_STATUS, "car-drive-status" }, + { PROP_CAR_LOAD, "car-load" }, { PROP_CAR_LOAD_UNITS, "car-load-units" }, + { PROP_CAR_MODE, "car-mode" }, + { PROP_CAR_MOVING_DIRECTION, "car-moving-direction" }, + { PROP_CAR_POSITION, "car-position" }, + { PROP_ELEVATOR_GROUP, "elevator-group" }, + { PROP_ENERGY_METER, "energy-meter" }, + { PROP_ENERGY_METER_REF, "energy-meter-ref" }, + { PROP_ESCALATOR_MODE, "escalator-mode" }, + { PROP_FAULT_SIGNALS, "fault-signals" }, { PROP_FLOOR_TEXT, "floor-text" }, + { PROP_GROUP_ID, "group-id" }, { PROP_GROUP_MODE, "group-mode" }, + { PROP_HIGHER_DECK, "higher-deck" }, + { PROP_INSTALLATION_ID, "installation-id" }, + { PROP_LANDING_CALLS, "landing-calls" }, + { PROP_LANDING_CALL_CONTROL, "landing-call-control" }, + { PROP_LANDING_DOOR_STATUS, "landing-door-status" }, + { PROP_LOWER_DECK, "lower-deck" }, + { PROP_MACHINE_ROOM_ID, "machine-room-id" }, + { PROP_MAKING_CAR_CALL, "making-car-call" }, + { PROP_NEXT_STOPPING_FLOOR, "next-stopping-floor" }, + { PROP_OPERATION_DIRECTION, "operation-direction" }, + { PROP_PASSENGER_ALARM, "passenger-alarm" }, + { PROP_POWER_MODE, "power-mode" }, + { PROP_REGISTERED_CAR_CALL, "registered-car-call" }, + { PROP_ACTIVE_COV_MULTIPLE_SUBSCRIPTIONS, + "active-cov-multiple-subscriptions" }, + { PROP_PROTOCOL_LEVEL, "protocol-level" }, + { PROP_REFERENCE_PORT, "reference-port" }, + { PROP_DEPLOYED_PROFILE_LOCATION, "deployed-profile-location" }, + { PROP_PROFILE_LOCATION, "profile-location" }, { PROP_TAGS, "tags" }, + { PROP_SUBORDINATE_NODE_TYPES, "subordinate-node-types" }, + { PROP_SUBORDINATE_TAGS, "subordinate-tags" }, + { PROP_SUBORDINATE_RELATIONSHIPS, "subordinate-relationships" }, + { PROP_DEFAULT_SUBORDINATE_RELATIONSHIP, + "default-subordinate-relationship" }, + { PROP_REPRESENTS, "represents" }, { 0, NULL } + /* Enumerated values 0-511 are reserved for definition by ASHRAE. + Enumerated values 512-4194303 may be used by others subject to the + procedures and constraints described in Clause 23. */ +}; + +const char *bactext_property_name(unsigned index) +{ + return indtext_by_index_split_default(bacnet_property_names, index, 512, + ASHRAE_Reserved_String, Vendor_Proprietary_String); +} + +const char *bactext_property_name_default( + unsigned index, const char *default_string) +{ + return indtext_by_index_default( + bacnet_property_names, index, default_string); +} + +unsigned bactext_property_id(const char *name) +{ + return indtext_by_istring_default(bacnet_property_names, name, 0); +} + +bool bactext_property_index(const char *search_name, unsigned *found_index) +{ + return indtext_by_istring(bacnet_property_names, search_name, found_index); +} + +INDTEXT_DATA bacnet_engineering_unit_names[] = { + { UNITS_SQUARE_METERS, "square-meters" }, + { UNITS_SQUARE_FEET, "square-feet" }, + { UNITS_MILLIAMPERES, "milliamperes" }, { UNITS_AMPERES, "amperes" }, + { UNITS_OHMS, "ohms" }, { UNITS_VOLTS, "volts" }, + { UNITS_KILOVOLTS, "kilovolts" }, { UNITS_MEGAVOLTS, "megavolts" }, + { UNITS_VOLT_AMPERES, "volt-amperes" }, + { UNITS_KILOVOLT_AMPERES, "kilovolt-amperes" }, + { UNITS_MEGAVOLT_AMPERES, "megavolt-amperes" }, + { UNITS_VOLT_AMPERES_REACTIVE, "volt-amperes-reactive" }, + { UNITS_KILOVOLT_AMPERES_REACTIVE, "kilovolt-amperes-reactive" }, + { UNITS_MEGAVOLT_AMPERES_REACTIVE, "megavolt-amperes-reactive" }, + { UNITS_DEGREES_PHASE, "degrees-phase" }, + { UNITS_POWER_FACTOR, "power-factor" }, { UNITS_JOULES, "joules" }, + { UNITS_KILOJOULES, "kilojoules" }, { UNITS_WATT_HOURS, "watt-hours" }, + { UNITS_KILOWATT_HOURS, "kilowatt-hours" }, { UNITS_BTUS, "btus" }, + { UNITS_THERMS, "therms" }, { UNITS_TON_HOURS, "ton-hours" }, + { UNITS_JOULES_PER_KILOGRAM_DRY_AIR, "joules-per-kilogram-dry-air" }, + { UNITS_BTUS_PER_POUND_DRY_AIR, "btus-per-pound-dry-air" }, + { UNITS_CYCLES_PER_HOUR, "cycles-per-hour" }, + { UNITS_CYCLES_PER_MINUTE, "cycles-per-minute" }, { UNITS_HERTZ, "hertz" }, + { UNITS_GRAMS_OF_WATER_PER_KILOGRAM_DRY_AIR, + "grams-of-water-per-kilogram-dry-air" }, + { UNITS_PERCENT_RELATIVE_HUMIDITY, "percent-relative-humidity" }, + { UNITS_MILLIMETERS, "millimeters" }, { UNITS_METERS, "meters" }, + { UNITS_INCHES, "inches" }, { UNITS_FEET, "feet" }, + { UNITS_WATTS_PER_SQUARE_FOOT, "watts-per-square-foot" }, + { UNITS_WATTS_PER_SQUARE_METER, "watts-per-square-meter" }, + { UNITS_LUMENS, "lumens" }, { UNITS_LUXES, "luxes" }, + { UNITS_FOOT_CANDLES, "foot-candles" }, { UNITS_KILOGRAMS, "kilograms" }, + { UNITS_POUNDS_MASS, "pounds-mass" }, { UNITS_TONS, "tons" }, + { UNITS_KILOGRAMS_PER_SECOND, "kilograms-per-second" }, + { UNITS_KILOGRAMS_PER_MINUTE, "kilograms-per-minute" }, + { UNITS_KILOGRAMS_PER_HOUR, "kilograms-per-hour" }, + { UNITS_POUNDS_MASS_PER_MINUTE, "pounds-mass-per-minute" }, + { UNITS_POUNDS_MASS_PER_HOUR, "pounds-mass-per-hour" }, + { UNITS_WATTS, "watts" }, { UNITS_KILOWATTS, "kilowatts" }, + { UNITS_MEGAWATTS, "megawatts" }, { UNITS_BTUS_PER_HOUR, "btus-per-hour" }, + { UNITS_HORSEPOWER, "horsepower" }, + { UNITS_TONS_REFRIGERATION, "tons-refrigeration" }, + { UNITS_PASCALS, "pascals" }, { UNITS_KILOPASCALS, "kilopascals" }, + { UNITS_BARS, "bars" }, + { UNITS_POUNDS_FORCE_PER_SQUARE_INCH, "pounds-force-per-square-inch" }, + { UNITS_CENTIMETERS_OF_WATER, "centimeters-of-water" }, + { UNITS_INCHES_OF_WATER, "inches-of-water" }, + { UNITS_MILLIMETERS_OF_MERCURY, "millimeters-of-mercury" }, + { UNITS_CENTIMETERS_OF_MERCURY, "centimeters-of-mercury" }, + { UNITS_INCHES_OF_MERCURY, "inches-of-mercury" }, + { UNITS_DEGREES_CELSIUS, "degrees-celsius" }, + { UNITS_DEGREES_KELVIN, "degrees-kelvin" }, + { UNITS_DEGREES_FAHRENHEIT, "degrees-fahrenheit" }, + { UNITS_DEGREE_DAYS_CELSIUS, "degree-days-celsius" }, + { UNITS_DEGREE_DAYS_FAHRENHEIT, "degree-days-fahrenheit" }, + { UNITS_YEARS, "years" }, { UNITS_MONTHS, "months" }, + { UNITS_WEEKS, "weeks" }, { UNITS_DAYS, "days" }, { UNITS_HOURS, "hours" }, + { UNITS_MINUTES, "minutes" }, { UNITS_SECONDS, "seconds" }, + { UNITS_METERS_PER_SECOND, "meters-per-second" }, + { UNITS_KILOMETERS_PER_HOUR, "kilometers-per-hour" }, + { UNITS_FEET_PER_SECOND, "feet-per-second" }, + { UNITS_FEET_PER_MINUTE, "feet-per-minute" }, + { UNITS_MILES_PER_HOUR, "miles-per-hour" }, + { UNITS_CUBIC_FEET, "cubic-feet" }, { UNITS_CUBIC_METERS, "cubic-meters" }, + { UNITS_IMPERIAL_GALLONS, "imperial-gallons" }, { UNITS_LITERS, "liters" }, + { UNITS_US_GALLONS, "us-gallons" }, + { UNITS_CUBIC_FEET_PER_MINUTE, "cubic-feet-per-minute" }, + { UNITS_CUBIC_METERS_PER_SECOND, "cubic-meters-per-second" }, + { UNITS_IMPERIAL_GALLONS_PER_MINUTE, "imperial-gallons-per-minute" }, + { UNITS_LITERS_PER_SECOND, "liters-per-second" }, + { UNITS_LITERS_PER_MINUTE, "liters-per-minute" }, + { UNITS_US_GALLONS_PER_MINUTE, "us-gallons-per-minute" }, + { UNITS_DEGREES_ANGULAR, "degrees-angular" }, + { UNITS_DEGREES_CELSIUS_PER_HOUR, "degrees-celsius-per-hour" }, + { UNITS_DEGREES_CELSIUS_PER_MINUTE, "degrees-celsius-per-minute" }, + { UNITS_DEGREES_FAHRENHEIT_PER_HOUR, "degrees-fahrenheit-per-hour" }, + { UNITS_DEGREES_FAHRENHEIT_PER_MINUTE, "degrees-fahrenheit-per-minute" }, + { UNITS_NO_UNITS, "no-units" }, + { UNITS_PARTS_PER_MILLION, "parts-per-million" }, + { UNITS_PARTS_PER_BILLION, "parts-per-billion" }, + { UNITS_PERCENT, "percent" }, + { UNITS_PERCENT_PER_SECOND, "percent-per-second" }, + { UNITS_PER_MINUTE, "per-minute" }, { UNITS_PER_SECOND, "per-second" }, + { UNITS_PSI_PER_DEGREE_FAHRENHEIT, "psi-per-degree-fahrenheit" }, + { UNITS_RADIANS, "radians" }, + { UNITS_REVOLUTIONS_PER_MINUTE, "revolutions-per-minute" }, + { UNITS_CURRENCY1, "currency1" }, { UNITS_CURRENCY2, "currency2" }, + { UNITS_CURRENCY3, "currency3" }, { UNITS_CURRENCY4, "currency4" }, + { UNITS_CURRENCY5, "currency5" }, { UNITS_CURRENCY6, "currency6" }, + { UNITS_CURRENCY7, "currency7" }, { UNITS_CURRENCY8, "currency8" }, + { UNITS_CURRENCY9, "currency9" }, { UNITS_CURRENCY10, "currency10" }, + { UNITS_SQUARE_INCHES, "square-inches" }, + { UNITS_SQUARE_CENTIMETERS, "square-centimeters" }, + { UNITS_BTUS_PER_POUND, "btus_per-pound" }, + { UNITS_CENTIMETERS, "centimeters" }, + { UNITS_POUNDS_MASS_PER_SECOND, "pounds-mass-per-second" }, + { UNITS_DELTA_DEGREES_FAHRENHEIT, "delta-degrees-fahrenheit" }, + { UNITS_DELTA_DEGREES_KELVIN, "delta-degrees-kelvin" }, + { UNITS_KILOHMS, "kilohms" }, { UNITS_MEGOHMS, "megohms" }, + { UNITS_MILLIVOLTS, "millivolts" }, + { UNITS_KILOJOULES_PER_KILOGRAM, "kilojoules-per-kilogram" }, + { UNITS_MEGAJOULES, "megajoules" }, + { UNITS_JOULES_PER_DEGREE_KELVIN, "joules-per-degree-kelvin" }, + { UNITS_JOULES_PER_KILOGRAM_DEGREE_KELVIN, + "joules-per-kilogram-degree-kelvin" }, + { UNITS_KILOHERTZ, "kilohertz" }, { UNITS_MEGAHERTZ, "megahertz" }, + { UNITS_PER_HOUR, "per-hour" }, { UNITS_MILLIWATTS, "milliwatts" }, + { UNITS_HECTOPASCALS, "hectopascals" }, { UNITS_MILLIBARS, "millibars" }, + { UNITS_CUBIC_METERS_PER_HOUR, "cubic-meters-per-hour" }, + { UNITS_LITERS_PER_HOUR, "liters-per-hour" }, + { UNITS_KW_HOURS_PER_SQUARE_METER, "kilowatt-hours-per-square-meter" }, + { UNITS_KW_HOURS_PER_SQUARE_FOOT, "kilowatt-hours-per-square-foot" }, + { UNITS_MEGAJOULES_PER_SQUARE_METER, "megajoules-per-square-meter" }, + { UNITS_MEGAJOULES_PER_SQUARE_FOOT, "megajoules-per-square-foot" }, + { UNITS_CUBIC_FEET_PER_SECOND, "cubic-feet-per-second" }, + { UNITS_WATTS_PER_SQUARE_METER_DEGREE_KELVIN, + "watts-per-square-meter-degree-kelvin" }, + { UNITS_PERCENT_OBSCURATION_PER_FOOT, "percent-obscuration-per-foot" }, + { UNITS_PERCENT_OBSCURATION_PER_METER, "percent-obscuration-per-meter" }, + { UNITS_MILLIOHMS, "milliohms" }, + { UNITS_MEGAWATT_HOURS, "megawatt-hours" }, + { UNITS_KILO_BTUS, "kilo-btus" }, { UNITS_MEGA_BTUS, "mega-btus" }, + { UNITS_KILOJOULES_PER_KILOGRAM_DRY_AIR, + "kilojoules-per-kilogram-dry-air" }, + { UNITS_MEGAJOULES_PER_KILOGRAM_DRY_AIR, + "megajoules-per-kilogram-dry-air" }, + { UNITS_KILOJOULES_PER_DEGREE_KELVIN, "kilojoules-per-degree-Kelvin" }, + { UNITS_MEGAJOULES_PER_DEGREE_KELVIN, "megajoules-per-degree-Kelvin" }, + { UNITS_NEWTON, "newton" }, { UNITS_GRAMS_PER_SECOND, "grams-per-second" }, + { UNITS_GRAMS_PER_MINUTE, "grams-per-minute" }, + { UNITS_TONS_PER_HOUR, "tons-per-hour" }, + { UNITS_KILO_BTUS_PER_HOUR, "kilo-btus-per-hour" }, + { UNITS_HUNDREDTHS_SECONDS, "hundredths-seconds" }, + { UNITS_MILLISECONDS, "milliseconds" }, + { UNITS_NEWTON_METERS, "newton-meters" }, + { UNITS_MILLIMETERS_PER_SECOND, "millimeters-per-second" }, + { UNITS_MILLIMETERS_PER_MINUTE, "millimeters-per-minute" }, + { UNITS_METERS_PER_MINUTE, "meters-per-minute" }, + { UNITS_METERS_PER_HOUR, "meters-per-hour" }, + { UNITS_CUBIC_METERS_PER_MINUTE, "cubic-meters-per-minute" }, + { UNITS_METERS_PER_SECOND_PER_SECOND, "meters-per-second-per-second" }, + { UNITS_AMPERES_PER_METER, "amperes-per-meter" }, + { UNITS_AMPERES_PER_SQUARE_METER, "amperes-per-square-meter" }, + { UNITS_AMPERE_SQUARE_METERS, "ampere-square-meters" }, + { UNITS_FARADS, "farads" }, { UNITS_HENRYS, "henrys" }, + { UNITS_OHM_METERS, "ohm-meters" }, { UNITS_SIEMENS, "siemens" }, + { UNITS_SIEMENS_PER_METER, "siemens-per-meter" }, + { UNITS_TESLAS, "teslas" }, + { UNITS_VOLTS_PER_DEGREE_KELVIN, "volts-per-degree-Kelvin" }, + { UNITS_VOLTS_PER_METER, "volts-per-meter" }, { UNITS_WEBERS, "webers" }, + { UNITS_CANDELAS, "candelas" }, + { UNITS_CANDELAS_PER_SQUARE_METER, "candelas-per-square-meter" }, + { UNITS_DEGREES_KELVIN_PER_HOUR, "degrees-Kelvin-per-hour" }, + { UNITS_DEGREES_KELVIN_PER_MINUTE, "degrees-Kelvin-per-minute" }, + { UNITS_JOULE_SECONDS, "joule-seconds" }, + { UNITS_RADIANS_PER_SECOND, "radians-per-second" }, + { UNITS_SQUARE_METERS_PER_NEWTON, "square-meters-per-Newton" }, + { UNITS_KILOGRAMS_PER_CUBIC_METER, "kilograms-per-cubic-meter" }, + { UNITS_NEWTON_SECONDS, "newton-seconds" }, + { UNITS_NEWTONS_PER_METER, "newtons-per-meter" }, + { UNITS_WATTS_PER_METER_PER_DEGREE_KELVIN, + "watts-per-meter-per-degree-Kelvin" }, + { UNITS_PER_MILLE, "per-mille" }, + { UNITS_GRAMS_PER_GRAM, "grams-per-gram" }, + { UNITS_KILOGRAMS_PER_KILOGRAM, "kilograms-per-kilogram" }, + { UNITS_GRAMS_PER_KILOGRAM, "grams-per-kilogram" }, + { UNITS_MILLIGRAMS_PER_GRAM, "milligrams-per-gram" }, + { UNITS_MILLIGRAMS_PER_KILOGRAM, "milligrams-per-kilogram" }, + { UNITS_GRAMS_PER_MILLILITER, "grams-per-milliliter" }, + { UNITS_GRAMS_PER_LITER, "grams-per-liter" }, + { UNITS_MILLIGRAMS_PER_LITER, "milligrams-per-liter" }, + { UNITS_MICROGRAMS_PER_LITER, "micrograms-per-liter" }, + { UNITS_GRAMS_PER_CUBIC_METER, "grams-per-cubic-meter" }, + { UNITS_MILLIGRAMS_PER_CUBIC_METER, "milligrams-per-cubic-meter" }, + { UNITS_MICROGRAMS_PER_CUBIC_METER, "micrograms-per-cubic-meter" }, + { UNITS_NANOGRAMS_PER_CUBIC_METER, "nanograms-per-cubic-meter" }, + { UNITS_GRAMS_PER_CUBIC_CENTIMETER, "grams-per-cubic-centimeter" }, + { UNITS_BECQUERELS, "becquerels" }, + { UNITS_MEGABECQUERELS, "megabecquerels" }, { UNITS_GRAY, "gray" }, + { UNITS_MILLIGRAY, "milligray" }, { UNITS_MICROGRAY, "microgray" }, + { UNITS_SIEVERTS, "sieverts" }, { UNITS_MILLISIEVERTS, "millisieverts" }, + { UNITS_MICROSIEVERTS, "microsieverts" }, + { UNITS_MICROSIEVERTS_PER_HOUR, "microsieverts-per-hour" }, + { UNITS_DECIBELS_A, "decibels-a" }, + { UNITS_NEPHELOMETRIC_TURBIDITY_UNIT, "nephelometric-turbidity-unit" }, + { UNITS_PH, "pH" }, + { UNITS_GRAMS_PER_SQUARE_METER, "grams-per-square-meter" }, + { UNITS_MINUTES_PER_DEGREE_KELVIN, "minutes-per-degree-kelvin" }, + { UNITS_OHM_METER_SQUARED_PER_METER, "ohm-meter-squared-per-meter" }, + { UNITS_AMPERE_SECONDS, "ampere-seconds" }, + { UNITS_VOLT_AMPERE_HOURS, "volt-ampere-hours" }, + { UNITS_KILOVOLT_AMPERE_HOURS, "kilovolt-ampere-hours" }, + { UNITS_MEGAVOLT_AMPERE_HOURS, "megavolt-ampere-hours" }, + { UNITS_VOLT_AMPERE_HOURS_REACTIVE, "volt-ampere-hours-reactive" }, + { UNITS_KILOVOLT_AMPERE_HOURS_REACTIVE, "kilovolt-ampere-hours-reactive" }, + { UNITS_MEGAVOLT_AMPERE_HOURS_REACTIVE, "megavolt-ampere-hours-reactive" }, + { UNITS_VOLT_SQUARE_HOURS, "volt-square-hours" }, + { UNITS_AMPERE_SQUARE_HOURS, "ampere-square-hours" }, + { UNITS_JOULE_PER_HOURS, "joule-per-hours" }, + { UNITS_CUBIC_FEET_PER_DAY, "cubic-feet-per-day" }, + { UNITS_CUBIC_METERS_PER_DAY, "cubic-meters-per-day" }, + { UNITS_WATT_HOURS_PER_CUBIC_METER, "watt-hours-per-cubic-meter" }, + { UNITS_JOULES_PER_CUBIC_METER, "joules-per-cubic-meter" }, + { UNITS_MOLE_PERCENT, "mole-percent" }, + { UNITS_PASCAL_SECONDS, "pascal-seconds" }, + { UNITS_MILLION_STANDARD_CUBIC_FEET_PER_MINUTE, + "million-standard-cubic-feet-per-minute" }, + { UNITS_STANDARD_CUBIC_FEET_PER_DAY, "standard-cubic-feet-per-day" }, + { UNITS_MILLION_STANDARD_CUBIC_FEET_PER_DAY, + "million-standard-cubic-feet-per-day" }, + { UNITS_THOUSAND_CUBIC_FEET_PER_DAY, "thousand-cubic-feet-per-day" }, + { UNITS_THOUSAND_STANDARD_CUBIC_FEET_PER_DAY, + "thousand-standard-cubic-feet-per-day" }, + { UNITS_POUNDS_MASS_PER_DAY, "pounds-mass-per-day" }, + { UNITS_MILLIREMS, "millirems" }, + { UNITS_MILLIREMS_PER_HOUR, "millirems-per-hour" }, { 0, NULL } + /* Enumerated values 0-255 are reserved for definition by ASHRAE. + Enumerated values 256-65535 may be used by others subject to + the procedures and constraints described in Clause 23. */ +}; + +const char *bactext_engineering_unit_name(unsigned index) +{ + return indtext_by_index_split_default(bacnet_engineering_unit_names, index, + 256, ASHRAE_Reserved_String, Vendor_Proprietary_String); +} + +bool bactext_engineering_unit_index( + const char *search_name, unsigned *found_index) +{ + return indtext_by_istring( + bacnet_engineering_unit_names, search_name, found_index); +} + +INDTEXT_DATA bacnet_reject_reason_names[] = { { REJECT_REASON_OTHER, "Other" }, + { REJECT_REASON_BUFFER_OVERFLOW, "Buffer Overflow" }, + { REJECT_REASON_INCONSISTENT_PARAMETERS, "Inconsistent Parameters" }, + { REJECT_REASON_INVALID_PARAMETER_DATA_TYPE, + "Invalid Parameter Data Type" }, + { REJECT_REASON_INVALID_TAG, "Invalid Tag" }, + { REJECT_REASON_MISSING_REQUIRED_PARAMETER, "Missing Required Parameter" }, + { REJECT_REASON_PARAMETER_OUT_OF_RANGE, "Parameter Out of Range" }, + { REJECT_REASON_TOO_MANY_ARGUMENTS, "Too Many Arguments" }, + { REJECT_REASON_UNDEFINED_ENUMERATION, "Undefined Enumeration" }, + { REJECT_REASON_UNRECOGNIZED_SERVICE, "Unrecognized Service" }, + { REJECT_REASON_PROPRIETARY_FIRST, "Proprietary" }, { 0, NULL } }; + +const char *bactext_reject_reason_name(unsigned index) +{ + return indtext_by_index_split_default(bacnet_reject_reason_names, index, + REJECT_REASON_PROPRIETARY_FIRST, ASHRAE_Reserved_String, + Vendor_Proprietary_String); +} + +INDTEXT_DATA bacnet_abort_reason_names[] = { { ABORT_REASON_OTHER, "Other" }, + { ABORT_REASON_BUFFER_OVERFLOW, "Buffer Overflow" }, + { ABORT_REASON_INVALID_APDU_IN_THIS_STATE, "Invalid APDU in this State" }, + { ABORT_REASON_PREEMPTED_BY_HIGHER_PRIORITY_TASK, + "Preempted by Higher Priority Task" }, + { ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, "Segmentation Not Supported" }, + { ABORT_REASON_PROPRIETARY_FIRST, "Proprietary" }, { 0, NULL } }; + +const char *bactext_abort_reason_name(unsigned index) +{ + return indtext_by_index_split_default(bacnet_abort_reason_names, index, + ABORT_REASON_PROPRIETARY_FIRST, ASHRAE_Reserved_String, + Vendor_Proprietary_String); +} + +INDTEXT_DATA bacnet_error_class_names[] = { { ERROR_CLASS_DEVICE, "device" }, + { ERROR_CLASS_OBJECT, "object" }, { ERROR_CLASS_PROPERTY, "property" }, + { ERROR_CLASS_RESOURCES, "resources" }, + { ERROR_CLASS_SECURITY, "security" }, { ERROR_CLASS_SERVICES, "services" }, + { ERROR_CLASS_VT, "vt" }, { 0, NULL } }; + +const char *bactext_error_class_name(unsigned index) +{ + return indtext_by_index_split_default(bacnet_error_class_names, index, + ERROR_CLASS_PROPRIETARY_FIRST, ASHRAE_Reserved_String, + Vendor_Proprietary_String); +} + +INDTEXT_DATA bacnet_error_code_names[] = { { ERROR_CODE_OTHER, "other" }, + { ERROR_CODE_AUTHENTICATION_FAILED, "authentication-failed" }, + { ERROR_CODE_CHARACTER_SET_NOT_SUPPORTED, "character-set-not-supported" }, + { ERROR_CODE_CONFIGURATION_IN_PROGRESS, "configuration-in-progress" }, + { ERROR_CODE_DATATYPE_NOT_SUPPORTED, "datatype-not-supported" }, + { ERROR_CODE_DEVICE_BUSY, "device-busy" }, + { ERROR_CODE_DUPLICATE_NAME, "duplicate-name" }, + { ERROR_CODE_DUPLICATE_OBJECT_ID, "duplicate-object-id" }, + { ERROR_CODE_DYNAMIC_CREATION_NOT_SUPPORTED, + "dynamic-creation-not-supported" }, + { ERROR_CODE_FILE_ACCESS_DENIED, "file-access-denied" }, + { ERROR_CODE_INCOMPATIBLE_SECURITY_LEVELS, "incompatible-security-levels" }, + { ERROR_CODE_INCONSISTENT_PARAMETERS, "inconsistent-parameters" }, + { ERROR_CODE_INCONSISTENT_SELECTION_CRITERION, + "inconsistent-selection-criterion" }, + { ERROR_CODE_INVALID_ARRAY_INDEX, "invalid-array-index" }, + { ERROR_CODE_INVALID_CONFIGURATION_DATA, "invalid-configuration-data" }, + { ERROR_CODE_INVALID_DATA_TYPE, "invalid-data-type" }, + { ERROR_CODE_INVALID_FILE_ACCESS_METHOD, "invalid-file-access-method" }, + { ERROR_CODE_INVALID_FILE_START_POSITION, + "error-code-invalid-file-start-position" }, + { ERROR_CODE_INVALID_OPERATOR_NAME, "invalid-operator-name" }, + { ERROR_CODE_INVALID_PARAMETER_DATA_TYPE, "invalid-parameter-data-type" }, + { ERROR_CODE_INVALID_TIME_STAMP, "invalid-time-stamp" }, + { ERROR_CODE_KEY_GENERATION_ERROR, "key-generation-error" }, + { ERROR_CODE_MISSING_REQUIRED_PARAMETER, "missing-required-parameter" }, + { ERROR_CODE_NO_OBJECTS_OF_SPECIFIED_TYPE, "no-objects-of-specified-type" }, + { ERROR_CODE_NO_SPACE_FOR_OBJECT, "no-space-for-object" }, + { ERROR_CODE_NO_SPACE_TO_ADD_LIST_ELEMENT, "no-space-to-add-list-element" }, + { ERROR_CODE_NO_SPACE_TO_WRITE_PROPERTY, "no-space-to-write-property" }, + { ERROR_CODE_NO_VT_SESSIONS_AVAILABLE, "no-vt-sessions-available" }, + { ERROR_CODE_OBJECT_DELETION_NOT_PERMITTED, + "object-deletion-not-permitted" }, + { ERROR_CODE_OBJECT_IDENTIFIER_ALREADY_EXISTS, + "object-identifier-already-exists" }, + { ERROR_CODE_OPERATIONAL_PROBLEM, "operational-problem" }, + { ERROR_CODE_OPTIONAL_FUNCTIONALITY_NOT_SUPPORTED, + "optional-functionality-not-supported" }, + { ERROR_CODE_PASSWORD_FAILURE, "password-failure" }, + { ERROR_CODE_PROPERTY_IS_NOT_A_LIST, "property-is-not-a-list" }, + { ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY, "property-is-not-an-array" }, + { ERROR_CODE_READ_ACCESS_DENIED, "read-access-denied" }, + { ERROR_CODE_SECURITY_NOT_SUPPORTED, "security-not-supported" }, + { ERROR_CODE_SERVICE_REQUEST_DENIED, "service-request-denied" }, + { ERROR_CODE_TIMEOUT, "timeout" }, + { ERROR_CODE_UNKNOWN_OBJECT, "unknown-object" }, + { ERROR_CODE_UNKNOWN_PROPERTY, "unknown-property" }, + { ERROR_CODE_RESERVED1, "reserved1" }, + { ERROR_CODE_UNKNOWN_VT_CLASS, "unknown-vt-class" }, + { ERROR_CODE_UNKNOWN_VT_SESSION, "unknown-vt-session" }, + { ERROR_CODE_UNSUPPORTED_OBJECT_TYPE, "unsupported-object-type" }, + { ERROR_CODE_VALUE_OUT_OF_RANGE, "value-out-of-range" }, + { ERROR_CODE_VT_SESSION_ALREADY_CLOSED, "vt-session-already-closed" }, + { ERROR_CODE_VT_SESSION_TERMINATION_FAILURE, + "vt-session-termination-failure" }, + { ERROR_CODE_WRITE_ACCESS_DENIED, "write-access-denied" }, + { ERROR_CODE_COV_SUBSCRIPTION_FAILED, "cov-subscription-failed" }, + { ERROR_CODE_NOT_COV_PROPERTY, "not-cov-property" }, + { ERROR_CODE_ABORT_BUFFER_OVERFLOW, "abort-buffer-overflow" }, + { ERROR_CODE_ABORT_INVALID_APDU_IN_THIS_STATE, + "abort-invalid-apdu-in-this-state" }, + { ERROR_CODE_ABORT_PREEMPTED_BY_HIGHER_PRIORITY_TASK, + "abort-preempted-by-higher-priority-task" }, + { ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED, + "abort-segmentation-not-supported" }, + { ERROR_CODE_ABORT_PROPRIETARY, "abort-proprietary" }, + { ERROR_CODE_ABORT_OTHER, "abort-other" }, + { ERROR_CODE_INVALID_TAG, "invalid-tag" }, + { ERROR_CODE_NETWORK_DOWN, "network-down" }, + { ERROR_CODE_REJECT_BUFFER_OVERFLOW, "reject-buffer-overflow" }, + { ERROR_CODE_REJECT_INCONSISTENT_PARAMETERS, + "reject-inconsistent-parameters" }, + { ERROR_CODE_REJECT_INVALID_PARAMETER_DATA_TYPE, + "reject-invalid-parameter-data-type" }, + { ERROR_CODE_REJECT_INVALID_TAG, "reject-invalid-tag" }, + { ERROR_CODE_REJECT_MISSING_REQUIRED_PARAMETER, + "reject-missing-required-parameter" }, + { ERROR_CODE_REJECT_PARAMETER_OUT_OF_RANGE, + "reject-parameter-out-of-range" }, + { ERROR_CODE_REJECT_TOO_MANY_ARGUMENTS, "reject-too-many-arguments" }, + { ERROR_CODE_REJECT_UNDEFINED_ENUMERATION, "reject-undefined-enumeration" }, + { ERROR_CODE_REJECT_UNRECOGNIZED_SERVICE, "reject-unrecognized-service" }, + { ERROR_CODE_REJECT_PROPRIETARY, "reject-proprietary" }, + { ERROR_CODE_REJECT_OTHER, "reject-other" }, + { ERROR_CODE_UNKNOWN_DEVICE, "unknown-device" }, + { ERROR_CODE_UNKNOWN_ROUTE, "unknown-route" }, + { ERROR_CODE_VALUE_NOT_INITIALIZED, "value-not-initialized" }, + { ERROR_CODE_INVALID_EVENT_STATE, "invalid-event-state" }, + { ERROR_CODE_NO_ALARM_CONFIGURED, "no-alarm-configured" }, + { ERROR_CODE_LOG_BUFFER_FULL, "log-buffer-full" }, + { ERROR_CODE_LOGGED_VALUE_PURGED, "logged-value-purged" }, + { ERROR_CODE_NO_PROPERTY_SPECIFIED, "no-property-specified" }, + { ERROR_CODE_NOT_CONFIGURED_FOR_TRIGGERED_LOGGING, + "not-configured-for-triggered-logging" }, + { ERROR_CODE_UNKNOWN_SUBSCRIPTION, "unknown-subscription" }, + { ERROR_CODE_PARAMETER_OUT_OF_RANGE, "parameter-out-of-range" }, + { ERROR_CODE_LIST_ELEMENT_NOT_FOUND, "list-element-not-found" }, + { ERROR_CODE_BUSY, "busy" }, + { ERROR_CODE_COMMUNICATION_DISABLED, "communication-disabled" }, + { ERROR_CODE_COMMUNICATION_DISABLED, "access-denied" }, + { ERROR_CODE_SUCCESS, "success" }, + { ERROR_CODE_ACCESS_DENIED, "access-denied" }, + { ERROR_CODE_BAD_DESTINATION_ADDRESS, "bad-destination-address" }, + { ERROR_CODE_BAD_DESTINATION_DEVICE_ID, "bad-destination-device-id" }, + { ERROR_CODE_BAD_SIGNATURE, "bad-signature" }, + { ERROR_CODE_BAD_SOURCE_ADDRESS, "bad-source-address" }, + { ERROR_CODE_BAD_TIMESTAMP, "bad-timestamp" }, + { ERROR_CODE_CANNOT_USE_KEY, "cannot-use-key" }, + { ERROR_CODE_CANNOT_VERIFY_MESSAGE_ID, "cannot-verify-message-id" }, + { ERROR_CODE_CORRECT_KEY_REVISION, "correct-key-revision" }, + { ERROR_CODE_DESTINATION_DEVICE_ID_REQUIRED, + "destination-device-id-required" }, + { ERROR_CODE_DUPLICATE_MESSAGE, "duplicate-message" }, + { ERROR_CODE_ENCRYPTION_NOT_CONFIGURED, "encryption-not-configured" }, + { ERROR_CODE_ENCRYPTION_REQUIRED, "encryption-required" }, + { ERROR_CODE_INCORRECT_KEY, "incorrect-key" }, + { ERROR_CODE_INVALID_KEY_DATA, "invalid-key-data" }, + { ERROR_CODE_KEY_UPDATE_IN_PROGRESS, "key-update-in-progress" }, + { ERROR_CODE_MALFORMED_MESSAGE, "malformed-message" }, + { ERROR_CODE_NOT_KEY_SERVER, "not-key-server" }, + { ERROR_CODE_SECURITY_NOT_CONFIGURED, "security-not-configured" }, + { ERROR_CODE_SOURCE_SECURITY_REQUIRED, "source-security-required" }, + { ERROR_CODE_TOO_MANY_KEYS, "too-many-keys" }, + { ERROR_CODE_UNKNOWN_AUTHENTICATION_TYPE, "unknown-authentication-type" }, + { ERROR_CODE_UNKNOWN_KEY, "unknown-key" }, + { ERROR_CODE_UNKNOWN_KEY_REVISION, "unknown-key-revision" }, + { ERROR_CODE_UNKNOWN_SOURCE_MESSAGE, "unknown-source-message" }, + { ERROR_CODE_NOT_ROUTER_TO_DNET, "not-router-to-dnet" }, + { ERROR_CODE_ROUTER_BUSY, "router-busy" }, + { ERROR_CODE_UNKNOWN_NETWORK_MESSAGE, "unknown-network-message" }, + { ERROR_CODE_MESSAGE_TOO_LONG, "message-too-long" }, + { ERROR_CODE_SECURITY_ERROR, "security-error" }, + { ERROR_CODE_ADDRESSING_ERROR, "addressing-error" }, + { ERROR_CODE_WRITE_BDT_FAILED, "write-bdt-failed" }, + { ERROR_CODE_READ_BDT_FAILED, "read-bdt-failed" }, + { ERROR_CODE_REGISTER_FOREIGN_DEVICE_FAILED, + "register-foreign-device-failed" }, + { ERROR_CODE_READ_FDT_FAILED, "read-fdt-failed" }, + { ERROR_CODE_DELETE_FDT_ENTRY_FAILED, "delete-fdt-entry-failed" }, + { ERROR_CODE_DISTRIBUTE_BROADCAST_FAILED, "distribute-broadcast-failed" }, + { ERROR_CODE_UNKNOWN_FILE_SIZE, "unknown-file-size" }, + { ERROR_CODE_ABORT_APDU_TOO_LONG, "abort-apdu-too-long" }, + { ERROR_CODE_ABORT_APPLICATION_EXCEEDED_REPLY_TIME, + "abort-application-exceeded-reply-time" }, + { ERROR_CODE_ABORT_OUT_OF_RESOURCES, "abort-out-of-resources" }, + { ERROR_CODE_ABORT_TSM_TIMEOUT, "abort-tsm-timeout" }, + { ERROR_CODE_ABORT_WINDOW_SIZE_OUT_OF_RANGE, + "abort-window-size-out-of-range" }, + { ERROR_CODE_FILE_FULL, "file-full" }, + { ERROR_CODE_INCONSISTENT_CONFIGURATION, "inconsistent-configuration" }, + { ERROR_CODE_INCONSISTENT_OBJECT_TYPE, "inconsistent-object-type" }, + { ERROR_CODE_INTERNAL_ERROR, "internal-error" }, + { ERROR_CODE_NOT_CONFIGURED, "not-configured" }, + { ERROR_CODE_OUT_OF_MEMORY, "out-of-memory" }, + { ERROR_CODE_VALUE_TOO_LONG, "value-too-long" }, + { ERROR_CODE_ABORT_INSUFFICIENT_SECURITY, "abort-insufficient-security" }, + { ERROR_CODE_ABORT_SECURITY_ERROR, "abort-security-error" }, { 0, NULL } }; + +const char *bactext_error_code_name(unsigned index) +{ + return indtext_by_index_split_default(bacnet_error_code_names, index, + ERROR_CODE_PROPRIETARY_FIRST, ASHRAE_Reserved_String, + Vendor_Proprietary_String); +} + +INDTEXT_DATA bacnet_month_names[] = { { 1, "January" }, { 2, "February" }, + { 3, "March" }, { 4, "April" }, { 5, "May" }, { 6, "June" }, { 7, "July" }, + { 8, "August" }, { 9, "September" }, { 10, "October" }, { 11, "November" }, + { 12, "December" }, { 13, "Odd Months" }, { 14, "Even Months" }, + { 255, "Any Month" }, { 0, NULL } }; + +const char *bactext_month_name(unsigned index) +{ + return indtext_by_index_default( + bacnet_month_names, index, ASHRAE_Reserved_String); +} + +INDTEXT_DATA bacnet_week_of_month_names[] = { { 1, "days numbered 1-7" }, + { 2, "days numbered 8-14" }, { 3, "days numbered 15-21" }, + { 4, "days numbered 22-28" }, { 5, "days numbered 29-31" }, + { 6, "last 7 days of this month" }, { 255, "any week of this month" }, + { 0, NULL } }; + +const char *bactext_week_of_month_name(unsigned index) +{ + return indtext_by_index_default( + bacnet_week_of_month_names, index, ASHRAE_Reserved_String); +} + +/* note: different than DaysOfWeek bit string where 0=monday */ +INDTEXT_DATA bacnet_day_of_week_names[] = { { 1, "Monday" }, { 2, "Tuesday" }, + { 3, "Wednesday" }, { 4, "Thursday" }, { 5, "Friday" }, { 6, "Saturday" }, + { 7, "Sunday" }, { 255, "any day of week" }, { 0, NULL } }; + +const char *bactext_day_of_week_name(unsigned index) +{ + return indtext_by_index_default( + bacnet_day_of_week_names, index, ASHRAE_Reserved_String); +} + +/* note: different than DayOfWeek bit string where 1=monday */ +INDTEXT_DATA bacnet_days_of_week_names[] = { { BACNET_DAYS_OF_WEEK_MONDAY, + "Monday" }, + { BACNET_DAYS_OF_WEEK_TUESDAY, "Tuesday" }, + { BACNET_DAYS_OF_WEEK_WEDNESDAY, "Wednesday" }, + { BACNET_DAYS_OF_WEEK_THURSDAY, "Thursday" }, + { BACNET_DAYS_OF_WEEK_FRIDAY, "Friday" }, + { BACNET_DAYS_OF_WEEK_SATURDAY, "Saturday" }, + { BACNET_DAYS_OF_WEEK_SUNDAY, "Sunday" }, { 0, NULL } }; + +const char *bactext_days_of_week_name(unsigned index) +{ + return indtext_by_index_default( + bacnet_days_of_week_names, index, ASHRAE_Reserved_String); +} + +bool bactext_days_of_week_index(const char *search_name, unsigned *found_index) +{ + return indtext_by_istring( + bacnet_days_of_week_names, search_name, found_index); +} + +INDTEXT_DATA bacnet_event_transition_names[] = { { TRANSITION_TO_OFFNORMAL, + "offnormal" }, + { TRANSITION_TO_NORMAL, "normal" }, { TRANSITION_TO_FAULT, "fault" }, + { 0, NULL } }; + +const char *bactext_event_transition_name(unsigned index) +{ + return indtext_by_index_default( + bacnet_event_transition_names, index, ASHRAE_Reserved_String); +} + +bool bactext_event_transition_index( + const char *search_name, unsigned *found_index) +{ + return indtext_by_istring( + bacnet_event_transition_names, search_name, found_index); +} + +INDTEXT_DATA bacnet_event_state_names[] = { { EVENT_STATE_NORMAL, "normal" }, + { EVENT_STATE_FAULT, "fault" }, { EVENT_STATE_OFFNORMAL, "offnormal" }, + { EVENT_STATE_HIGH_LIMIT, "high limit" }, + { EVENT_STATE_LOW_LIMIT, "low limit" }, { 0, NULL } }; + +const char *bactext_event_state_name(unsigned index) +{ + return indtext_by_index_default( + bacnet_event_state_names, index, ASHRAE_Reserved_String); +} + +INDTEXT_DATA bacnet_binary_present_value_names[] = { + { BINARY_INACTIVE, "inactive" }, { BINARY_ACTIVE, "active" }, { 0, NULL } +}; + +const char *bactext_binary_present_value_name(unsigned index) +{ + return indtext_by_index_default( + bacnet_binary_present_value_names, index, ASHRAE_Reserved_String); +} + +bool bactext_binary_present_value_index( + const char *search_name, unsigned *found_index) +{ + return indtext_by_istring( + bacnet_binary_present_value_names, search_name, found_index); +} + +INDTEXT_DATA bacnet_binary_polarity_names[] = { { POLARITY_NORMAL, "normal" }, + { POLARITY_REVERSE, "reverse" }, { 0, NULL } }; + +const char *bactext_binary_polarity_name(unsigned index) +{ + return indtext_by_index_default( + bacnet_binary_polarity_names, index, ASHRAE_Reserved_String); +} + +INDTEXT_DATA bacnet_reliability_names[] = { { RELIABILITY_NO_FAULT_DETECTED, + "no-fault-detected" }, + { RELIABILITY_NO_SENSOR, "no-sensor" }, + { RELIABILITY_OVER_RANGE, "over-range" }, + { RELIABILITY_UNDER_RANGE, "under-range" }, + { RELIABILITY_OPEN_LOOP, "open-loop" }, + { RELIABILITY_SHORTED_LOOP, "shorted-loop" }, + { RELIABILITY_NO_OUTPUT, "no-output" }, + { RELIABILITY_UNRELIABLE_OTHER, "unreliable-other" }, + { RELIABILITY_PROCESS_ERROR, "process-error" }, + { RELIABILITY_MULTI_STATE_FAULT, "mult-state-fault" }, + { RELIABILITY_CONFIGURATION_ERROR, "configuration-error" }, + { RELIABILITY_MEMBER_FAULT, "member-fault" }, + { RELIABILITY_COMMUNICATION_FAILURE, "communication-failure" }, + { RELIABILITY_TRIPPED, "tripped" }, { 0, NULL } }; + +const char *bactext_reliability_name(unsigned index) +{ + return indtext_by_index_default( + bacnet_reliability_names, index, ASHRAE_Reserved_String); +} + +INDTEXT_DATA bacnet_device_status_names[] = { { STATUS_OPERATIONAL, + "operational" }, + { STATUS_OPERATIONAL_READ_ONLY, "operational-read-only" }, + { STATUS_DOWNLOAD_REQUIRED, "download-required" }, + { STATUS_DOWNLOAD_IN_PROGRESS, "download-in-progress" }, + { STATUS_NON_OPERATIONAL, "non-operational" }, + { STATUS_BACKUP_IN_PROGRESS, "backup-in-progress" }, { 0, NULL } }; + +const char *bactext_device_status_name(unsigned index) +{ + return indtext_by_index_default( + bacnet_device_status_names, index, ASHRAE_Reserved_String); +} + +INDTEXT_DATA bacnet_segmentation_names[] = { { SEGMENTATION_BOTH, + "segmented-both" }, + { SEGMENTATION_TRANSMIT, "segmented-transmit" }, + { SEGMENTATION_RECEIVE, "segmented-receive" }, + { SEGMENTATION_NONE, "no-segmentation" }, { 0, NULL } }; + +const char *bactext_segmentation_name(unsigned index) +{ + return indtext_by_index_default( + bacnet_segmentation_names, index, ASHRAE_Reserved_String); +} + +bool bactext_segmentation_index(const char *search_name, unsigned *found_index) +{ + return indtext_by_istring( + bacnet_segmentation_names, search_name, found_index); +} + +INDTEXT_DATA bacnet_node_type_names[] = { { BACNET_NODE_UNKNOWN, "unknown" }, + { BACNET_NODE_SYSTEM, "system" }, { BACNET_NODE_NETWORK, "network" }, + { BACNET_NODE_DEVICE, "device" }, + { BACNET_NODE_ORGANIZATIONAL, "organizational" }, + { BACNET_NODE_AREA, "area" }, { BACNET_NODE_EQUIPMENT, "equipment" }, + { BACNET_NODE_POINT, "point" }, { BACNET_NODE_COLLECTION, "collection" }, + { BACNET_NODE_PROPERTY, "property" }, + { BACNET_NODE_FUNCTIONAL, "functional" }, { BACNET_NODE_OTHER, "other" }, + { 0, NULL } }; + +const char *bactext_node_type_name(unsigned index) +{ + return indtext_by_index_default( + bacnet_node_type_names, index, ASHRAE_Reserved_String); +} + +INDTEXT_DATA network_layer_msg_names[] = { + { NETWORK_MESSAGE_WHO_IS_ROUTER_TO_NETWORK, "Who-Is-Router-To-Network" }, + { NETWORK_MESSAGE_I_AM_ROUTER_TO_NETWORK, "I-Am-Router-To-Network" }, + { NETWORK_MESSAGE_I_COULD_BE_ROUTER_TO_NETWORK, + "I-Could-Be-Router-To-Network" }, + { NETWORK_MESSAGE_REJECT_MESSAGE_TO_NETWORK, "Reject-Message-to-Network" }, + { NETWORK_MESSAGE_ROUTER_BUSY_TO_NETWORK, "Router-Busy-To-Network" }, + { NETWORK_MESSAGE_ROUTER_AVAILABLE_TO_NETWORK, + "Router-Available-To-Network" }, + { NETWORK_MESSAGE_INIT_RT_TABLE, "Initialize-Routing-Table" }, + { NETWORK_MESSAGE_INIT_RT_TABLE_ACK, "Initialize-Routing-Table-Ack" }, + { NETWORK_MESSAGE_ESTABLISH_CONNECTION_TO_NETWORK, + "Est-Conn-Ntwk" }, /* Terse since unused */ + { NETWORK_MESSAGE_DISCONNECT_CONNECTION_TO_NETWORK, "Dsc-Conn-Ntwk" }, + { 0, NULL } +}; + +const char *bactext_network_layer_msg_name(unsigned index) +{ + if (index <= 0x7F) { + return indtext_by_index_default( + network_layer_msg_names, index, ASHRAE_Reserved_String); + } else if (index < NETWORK_MESSAGE_INVALID) { + return Vendor_Proprietary_String; + } else { + return "Invalid Network Layer Message"; + } +} + +INDTEXT_DATA life_safety_state_names[] = { { LIFE_SAFETY_STATE_QUIET, "quiet" }, + { LIFE_SAFETY_STATE_PRE_ALARM, "pre-alarm" }, + { LIFE_SAFETY_STATE_ALARM, "alarm" }, { LIFE_SAFETY_STATE_FAULT, "fault" }, + { LIFE_SAFETY_STATE_FAULT_PRE_ALARM, "fault-pre-alarm" }, + { LIFE_SAFETY_STATE_FAULT_ALARM, "fault-alarm" }, + { LIFE_SAFETY_STATE_NOT_READY, "not-ready" }, + { LIFE_SAFETY_STATE_ACTIVE, "active" }, + { LIFE_SAFETY_STATE_TAMPER, "tamper" }, + { LIFE_SAFETY_STATE_TEST_ALARM, "test-alarm" }, + { LIFE_SAFETY_STATE_TEST_ACTIVE, "test-active" }, + { LIFE_SAFETY_STATE_TEST_FAULT, "test-fault" }, + { LIFE_SAFETY_STATE_TEST_FAULT_ALARM, "fault-alarm" }, + { LIFE_SAFETY_STATE_HOLDUP, "holdupt" }, + { LIFE_SAFETY_STATE_DURESS, "duress" }, + { LIFE_SAFETY_STATE_TAMPER_ALARM, "tamper-alarm" }, + { LIFE_SAFETY_STATE_ABNORMAL, "abnormal" }, + { LIFE_SAFETY_STATE_EMERGENCY_POWER, "emergency-power" }, + { LIFE_SAFETY_STATE_DELAYED, "delayed" }, + { LIFE_SAFETY_STATE_BLOCKED, "blocked" }, + { LIFE_SAFETY_STATE_LOCAL_ALARM, "local-alarm" }, + { LIFE_SAFETY_STATE_GENERAL_ALARM, "general-alarm" }, + { LIFE_SAFETY_STATE_SUPERVISORY, "supervisory" }, + { LIFE_SAFETY_STATE_TEST_SUPERVISORY, "test-supervisory" }, { 0, NULL } }; + +const char *bactext_life_safety_state_name(unsigned index) +{ + if (index < MAX_LIFE_SAFETY_STATE) { + return indtext_by_index_default( + life_safety_state_names, index, ASHRAE_Reserved_String); + } else { + return "Invalid Safety State Message"; + } +} + +INDTEXT_DATA lighting_in_progress[] = { { BACNET_LIGHTING_IDLE, "idle" }, + { BACNET_LIGHTING_FADE_ACTIVE, "fade" }, + { BACNET_LIGHTING_RAMP_ACTIVE, "ramp" }, + { BACNET_LIGHTING_NOT_CONTROLLED, "not" }, + { BACNET_LIGHTING_OTHER, "other" }, { 0, NULL } }; + +const char *bactext_lighting_in_progress(unsigned index) +{ + if (index < MAX_BACNET_LIGHTING_IN_PROGRESS) { + return indtext_by_index_default( + lighting_in_progress, index, ASHRAE_Reserved_String); + } else { + return "Invalid Lighting In Progress Message"; + } +} + +INDTEXT_DATA lighting_transition[] = { { BACNET_LIGHTING_TRANSITION_IDLE, + "idle" }, + { BACNET_LIGHTING_TRANSITION_FADE, "fade" }, + { BACNET_LIGHTING_TRANSITION_RAMP, "ramp" }, { 0, NULL } }; + +const char *bactext_lighting_transition(unsigned index) +{ + if (index < MAX_BACNET_LIGHTING_TRANSITION) { + return indtext_by_index_default( + lighting_transition, index, ASHRAE_Reserved_String); + } else { + return "Invalid Lighting Transition Message"; + } +} + +INDTEXT_DATA bacnet_lighting_operation_names[] = { + { BACNET_LIGHTS_NONE, "none" }, { BACNET_LIGHTS_FADE_TO, "fade-to" }, + { BACNET_LIGHTS_RAMP_TO, "ramp-to" }, { BACNET_LIGHTS_STEP_UP, "step-up" }, + { BACNET_LIGHTS_STEP_DOWN, "step-down" }, + { BACNET_LIGHTS_STEP_ON, "step-on" }, + { BACNET_LIGHTS_STEP_OFF, "step-off" }, { BACNET_LIGHTS_WARN, "warn" }, + { BACNET_LIGHTS_WARN_OFF, "warn-off" }, + { BACNET_LIGHTS_WARN_RELINQUISH, "warn-relinquish" }, + { BACNET_LIGHTS_STOP, "stop" }, { 0, NULL } +}; + +const char *bactext_lighting_operation_name(unsigned index) +{ + if (index < BACNET_LIGHTS_PROPRIETARY_FIRST) { + return indtext_by_index_default( + network_layer_msg_names, index, ASHRAE_Reserved_String); + } else if (index <= BACNET_LIGHTS_PROPRIETARY_LAST) { + return Vendor_Proprietary_String; + } else { + return "Invalid BACnetLightingOperation"; + } +} + +INDTEXT_DATA bacnet_device_communications_names[] = { + { COMMUNICATION_ENABLE, "enabled" }, { COMMUNICATION_DISABLE, "disabled" }, + { COMMUNICATION_DISABLE_INITIATION, "initiation disabled" }, { 0, NULL } +}; + +const char *bactext_device_communications_name(unsigned index) +{ + return indtext_by_index_default( + bacnet_device_communications_names, index, ASHRAE_Reserved_String); +} diff --git a/include/bactext.h b/src/bacnet/bactext.h similarity index 99% rename from include/bactext.h rename to src/bacnet/bactext.h index 51c3c829..4f0f887d 100644 --- a/include/bactext.h +++ b/src/bacnet/bactext.h @@ -35,7 +35,7 @@ #include #include -#include "indtext.h" +#include "bacnet/indtext.h" #ifdef __cplusplus extern "C" { diff --git a/src/bactimevalue.c b/src/bacnet/bactimevalue.c similarity index 79% rename from src/bactimevalue.c rename to src/bacnet/bactimevalue.c index e3a9d28b..93922e6b 100644 --- a/src/bactimevalue.c +++ b/src/bacnet/bactimevalue.c @@ -34,10 +34,10 @@ #include #include -#include "bacdcode.h" -#include "bactimevalue.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bactimevalue.h" -int bacapp_encode_time_value(uint8_t* apdu, BACNET_TIME_VALUE* value) +int bacapp_encode_time_value(uint8_t *apdu, BACNET_TIME_VALUE *value) { int len; int apdu_len = 0; @@ -51,8 +51,8 @@ int bacapp_encode_time_value(uint8_t* apdu, BACNET_TIME_VALUE* value) return apdu_len; } -int bacapp_encode_context_time_value(uint8_t* apdu, uint8_t tag_number, - BACNET_TIME_VALUE* value) +int bacapp_encode_context_time_value( + uint8_t *apdu, uint8_t tag_number, BACNET_TIME_VALUE *value) { int len; int apdu_len = 0; @@ -69,45 +69,50 @@ int bacapp_encode_context_time_value(uint8_t* apdu, uint8_t tag_number, return apdu_len; } -int bacapp_decode_time_value(uint8_t* apdu, BACNET_TIME_VALUE* value) +int bacapp_decode_time_value(uint8_t *apdu, BACNET_TIME_VALUE *value) { int len; int apdu_len = 0; len = decode_application_time(&apdu[apdu_len], &value->Time); - if (len <= 0) + if (len <= 0) { return -1; + } apdu_len += len; len = bacapp_decode_application_data(&apdu[apdu_len], 2048, &value->Value); - if (len <= 0) + if (len <= 0) { return -1; + } apdu_len += len; return apdu_len; } -int bacapp_decode_context_time_value(uint8_t* apdu, uint8_t tag_number, - BACNET_TIME_VALUE* value) +int bacapp_decode_context_time_value( + uint8_t *apdu, uint8_t tag_number, BACNET_TIME_VALUE *value) { int len = 0; int section_length; - if (decode_is_opening_tag_number(&apdu[len], tag_number)) + if (decode_is_opening_tag_number(&apdu[len], tag_number)) { len++; - else + } else { return -1; + } section_length = bacapp_decode_time_value(&apdu[len], value); - if (section_length > 0) + if (section_length > 0) { len += section_length; - else + } else { return -1; + } - if (decode_is_closing_tag_number(&apdu[len], tag_number)) + if (decode_is_closing_tag_number(&apdu[len], tag_number)) { len++; - else + } else { return -1; + } return len; } diff --git a/include/bactimevalue.h b/src/bacnet/bactimevalue.h similarity index 96% rename from include/bactimevalue.h rename to src/bacnet/bactimevalue.h index 2b0f0767..518a7419 100644 --- a/include/bactimevalue.h +++ b/src/bacnet/bactimevalue.h @@ -28,9 +28,9 @@ #include #include #include -#include "bacdef.h" -#include "bacenum.h" -#include "bacapp.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacenum.h" +#include "bacnet/bacapp.h" typedef struct { BACNET_TIME Time; diff --git a/demo/handler/h_bbmd6.c b/src/bacnet/basic/bbmd6/h_bbmd6.c similarity index 86% rename from demo/handler/h_bbmd6.c rename to src/bacnet/basic/bbmd6/h_bbmd6.c index 3790b522..18e9af6b 100644 --- a/demo/handler/h_bbmd6.c +++ b/src/bacnet/basic/bbmd6/h_bbmd6.c @@ -32,18 +32,18 @@ ------------------------------------------- ####COPYRIGHTEND####*/ -#include /* for standard i/o, like printing */ -#include /* for standard integer types uint8_t etc. */ +#include /* for standard i/o, like printing */ +#include /* for standard integer types uint8_t etc. */ #include /* for the standard bool type. */ -#include /* for memcpy */ -#include "bacdcode.h" -#include "bip6.h" -#include "bvlc6.h" -#include "debug.h" -#include "device.h" -#include "vmac.h" +#include /* for memcpy */ +#include "bacnet/bacdcode.h" +#include "bacnet/datalink/bip6.h" +#include "bacnet/datalink/bvlc6.h" +#include "bacnet/basic/sys/debug.h" +#include "bacnet/basic/object/device.h" +#include "bacnet/basic/bbmd6/vmac.h" #ifndef TEST -#include "net.h" +#include "bacport.h" #endif /** result from a client request */ @@ -104,8 +104,8 @@ void bbmd6_maintenance_timer(time_t seconds) * * @return true if the address was set */ -static bool bbmd6_address_from_vmac(BACNET_IP6_ADDRESS *addr, - struct vmac_data *vmac) +static bool bbmd6_address_from_vmac( + BACNET_IP6_ADDRESS *addr, struct vmac_data *vmac) { bool status = false; unsigned int i = 0; @@ -129,8 +129,8 @@ static bool bbmd6_address_from_vmac(BACNET_IP6_ADDRESS *addr, * * @return true if the address was set */ -static bool bbmd6_address_to_vmac(struct vmac_data *vmac, - BACNET_IP6_ADDRESS *addr) +static bool bbmd6_address_to_vmac( + struct vmac_data *vmac, BACNET_IP6_ADDRESS *addr) { bool status = false; unsigned int i = 0; @@ -184,7 +184,7 @@ static bool bbmd6_add_vmac(uint32_t device_id, BACNET_IP6_ADDRESS *addr) */ static bool bbmd6_address_match_self(BACNET_IP6_ADDRESS *addr) { - BACNET_IP6_ADDRESS my_addr = {{0}}; + BACNET_IP6_ADDRESS my_addr = { { 0 } }; bool status = false; if (bip6_get_addr(&my_addr)) { @@ -206,9 +206,8 @@ static bool bbmd6_address_match_self(BACNET_IP6_ADDRESS *addr) * * @return true if the address was in the VMAC table */ -static bool bbmd6_address_from_bacnet_address(BACNET_IP6_ADDRESS *addr, - uint32_t *vmac_src, - BACNET_ADDRESS *baddr) +static bool bbmd6_address_from_bacnet_address( + BACNET_IP6_ADDRESS *addr, uint32_t *vmac_src, BACNET_ADDRESS *baddr) { struct vmac_data *vmac; bool status = false; @@ -220,7 +219,7 @@ static bool bbmd6_address_from_bacnet_address(BACNET_IP6_ADDRESS *addr, vmac = VMAC_Find_By_Key(device_id); if (vmac) { debug_printf("BVLC6: Found VMAC %lu (len=%u).\n", - (unsigned long)device_id, (unsigned)vmac->mac_len); + (unsigned long)device_id, (unsigned)vmac->mac_len); status = bbmd6_address_from_vmac(addr, vmac); if (vmac_src) { *vmac_src = device_id; @@ -244,11 +243,13 @@ static bool bbmd6_address_from_bacnet_address(BACNET_IP6_ADDRESS *addr, * @return Upon successful completion, returns the number of bytes sent. * Otherwise, -1 shall be returned and errno set to indicate the error. */ -int bip6_send_pdu(BACNET_ADDRESS *dest, BACNET_NPDU_DATA *npdu_data, - uint8_t *pdu, unsigned pdu_len) +int bip6_send_pdu(BACNET_ADDRESS *dest, + BACNET_NPDU_DATA *npdu_data, + uint8_t *pdu, + unsigned pdu_len) { - BACNET_IP6_ADDRESS bvlc_dest = {{0}}; - uint8_t mtu[MAX_MPDU] = {0}; + BACNET_IP6_ADDRESS bvlc_dest = { { 0 } }; + uint8_t mtu[MAX_MPDU] = { 0 }; uint16_t mtu_len = 0; uint32_t vmac_src = 0; uint32_t vmac_dst = 0; @@ -269,8 +270,8 @@ int bip6_send_pdu(BACNET_ADDRESS *dest, BACNET_NPDU_DATA *npdu_data, } else { bip6_get_broadcast_addr(&bvlc_dest); vmac_src = Device_Object_Instance_Number(); - mtu_len = bvlc6_encode_original_broadcast(mtu, sizeof(mtu), - vmac_src, pdu, pdu_len); + mtu_len = bvlc6_encode_original_broadcast( + mtu, sizeof(mtu), vmac_src, pdu, pdu_len); debug_printf("BVLC6: Sent Original-Broadcast-NPDU.\n"); } } else if ((dest->net > 0) && (dest->len == 0)) { @@ -282,16 +283,16 @@ int bip6_send_pdu(BACNET_ADDRESS *dest, BACNET_NPDU_DATA *npdu_data, bip6_get_broadcast_addr(&bvlc_dest); } vmac_src = Device_Object_Instance_Number(); - mtu_len = bvlc6_encode_original_broadcast(mtu, sizeof(mtu), vmac_src, - pdu, pdu_len); + mtu_len = bvlc6_encode_original_broadcast( + mtu, sizeof(mtu), vmac_src, pdu, pdu_len); debug_printf("BVLC6: Sent Original-Broadcast-NPDU.\n"); } else if (dest->mac_len == 3) { /* valid unicast */ bbmd6_address_from_bacnet_address(&bvlc_dest, &vmac_dst, dest); debug_printf("BVLC6: Sending to VMAC %lu.\n", (unsigned long)vmac_dst); vmac_src = Device_Object_Instance_Number(); - mtu_len = bvlc6_encode_original_unicast(mtu, sizeof(mtu), vmac_src, - vmac_dst, pdu, pdu_len); + mtu_len = bvlc6_encode_original_unicast( + mtu, sizeof(mtu), vmac_src, vmac_dst, pdu, pdu_len); debug_printf("BVLC6: Sent Original-Unicast-NPDU.\n"); } else { debug_printf("BVLC6: Send failure. Invalid Address.\n"); @@ -313,15 +314,15 @@ int bip6_send_pdu(BACNET_ADDRESS *dest, BACNET_NPDU_DATA *npdu_data, */ static void bbmd6_send_pdu_bdt(uint8_t *mtu, unsigned int mtu_len) { - BACNET_IP6_ADDRESS my_addr = {{0}}; + BACNET_IP6_ADDRESS my_addr = { { 0 } }; unsigned i = 0; /* loop counter */ if (mtu) { bip6_get_addr(&my_addr); for (i = 0; i < MAX_BBMD_ENTRIES; i++) { if (BBMD_Table[i].valid) { - if (bvlc6_address_different(&my_addr, - &BBMD_Table[i].bip6_address)) { + if (bvlc6_address_different( + &my_addr, &BBMD_Table[i].bip6_address)) { bip6_send_mpdu(&BBMD_Table[i].bip6_address, mtu, mtu_len); } } @@ -340,15 +341,15 @@ static void bbmd6_send_pdu_bdt(uint8_t *mtu, unsigned int mtu_len) */ static void bbmd6_send_pdu_fdt(uint8_t *mtu, unsigned int mtu_len) { - BACNET_IP6_ADDRESS my_addr = {{0}}; + BACNET_IP6_ADDRESS my_addr = { { 0 } }; unsigned i = 0; /* loop counter */ if (mtu) { bip6_get_addr(&my_addr); for (i = 0; i < MAX_FD_ENTRIES; i++) { if (FD_Table[i].valid) { - if (bvlc6_address_different(&my_addr, - &FD_Table[i].bip6_address)) { + if (bvlc6_address_different( + &my_addr, &FD_Table[i].bip6_address)) { bip6_send_mpdu(&FD_Table[i].bip6_address, mtu, mtu_len); } } @@ -366,10 +367,11 @@ static void bbmd6_send_pdu_fdt(uint8_t *mtu, unsigned int mtu_len) * @param npdu_len - the number of bytes of NPDU+APDU data to send */ static void bbmd6_send_forward_npdu(BACNET_IP6_ADDRESS *address, - uint32_t vmac_src, uint8_t *npdu, - unsigned int npdu_len) + uint32_t vmac_src, + uint8_t *npdu, + unsigned int npdu_len) { - uint8_t mtu[MAX_MPDU] = {0}; + uint8_t mtu[MAX_MPDU] = { 0 }; uint16_t mtu_len = 0; unsigned i = 0; /* loop counter */ @@ -406,10 +408,10 @@ static void bbmd6_send_forward_npdu(BACNET_IP6_ADDRESS *address, * @return Upon successful completion, returns the number of bytes sent. * Otherwise, -1 shall be returned and errno set to indicate the error. */ -static int bvlc6_send_result(BACNET_IP6_ADDRESS *dest_addr, uint32_t vmac_src, - uint16_t result_code) +static int bvlc6_send_result( + BACNET_IP6_ADDRESS *dest_addr, uint32_t vmac_src, uint16_t result_code) { - uint8_t mtu[MAX_MPDU] = {0}; + uint8_t mtu[MAX_MPDU] = { 0 }; uint16_t mtu_len = 0; mtu_len = bvlc6_encode_result(&mtu[0], sizeof(mtu), vmac_src, result_code); @@ -428,15 +430,14 @@ static int bvlc6_send_result(BACNET_IP6_ADDRESS *dest_addr, uint32_t vmac_src, * @return Upon successful completion, returns the number of bytes sent. * Otherwise, -1 shall be returned and errno set to indicate the error. */ -static int bvlc6_send_address_resolution_ack(BACNET_IP6_ADDRESS *dest_addr, - uint32_t vmac_src, - uint32_t vmac_dst) +static int bvlc6_send_address_resolution_ack( + BACNET_IP6_ADDRESS *dest_addr, uint32_t vmac_src, uint32_t vmac_dst) { - uint8_t mtu[MAX_MPDU] = {0}; + uint8_t mtu[MAX_MPDU] = { 0 }; uint16_t mtu_len = 0; - mtu_len = bvlc6_encode_address_resolution_ack(&mtu[0], sizeof(mtu), - vmac_src, vmac_dst); + mtu_len = bvlc6_encode_address_resolution_ack( + &mtu[0], sizeof(mtu), vmac_src, vmac_dst); return bip6_send_mpdu(dest_addr, mtu, mtu_len); } @@ -456,11 +457,11 @@ static int bvlc6_send_address_resolution_ack(BACNET_IP6_ADDRESS *dest_addr, static int bvlc6_send_virtual_address_resolution_ack( BACNET_IP6_ADDRESS *dest_addr, uint32_t vmac_src, uint32_t vmac_dst) { - uint8_t mtu[MAX_MPDU] = {0}; + uint8_t mtu[MAX_MPDU] = { 0 }; uint16_t mtu_len = 0; - mtu_len = bvlc6_encode_virtual_address_resolution_ack(&mtu[0], sizeof(mtu), - vmac_src, vmac_dst); + mtu_len = bvlc6_encode_virtual_address_resolution_ack( + &mtu[0], sizeof(mtu), vmac_src, vmac_dst); return bip6_send_mpdu(dest_addr, mtu, mtu_len); } @@ -472,9 +473,8 @@ static int bvlc6_send_virtual_address_resolution_ack( * @param pdu - The received NPDU+APDU buffer. * @param pdu_len - How many bytes in NPDU+APDU buffer. */ -static void bbmd6_virtual_address_resolution_handler(BACNET_IP6_ADDRESS *addr, - uint8_t *pdu, - uint16_t pdu_len) +static void bbmd6_virtual_address_resolution_handler( + BACNET_IP6_ADDRESS *addr, uint8_t *pdu, uint16_t pdu_len) { int function_len = 0; uint32_t vmac_src = 0; @@ -485,16 +485,16 @@ static void bbmd6_virtual_address_resolution_handler(BACNET_IP6_ADDRESS *addr, if (bbmd6_address_match_self(addr)) { /* ignore messages from my IPv6 address */ } else { - function_len = bvlc6_decode_virtual_address_resolution(pdu, pdu_len, - &vmac_src); + function_len = bvlc6_decode_virtual_address_resolution( + pdu, pdu_len, &vmac_src); if (function_len) { bbmd6_add_vmac(vmac_src, addr); /* The Address-Resolution-ACK message is unicast to the B/IPv6 node that originally initiated the Address-Resolution message. */ vmac_me = Device_Object_Instance_Number(); - bvlc6_send_virtual_address_resolution_ack(addr, vmac_me, - vmac_src); + bvlc6_send_virtual_address_resolution_ack( + addr, vmac_me, vmac_src); } } } @@ -535,8 +535,8 @@ static void bbmd6_virtual_address_resolution_ack_handler( * @param pdu - The received NPDU+APDU buffer. * @param pdu_len - How many bytes in NPDU+APDU buffer. */ -static void bbmd6_address_resolution_handler(BACNET_IP6_ADDRESS *addr, - uint8_t *pdu, uint16_t pdu_len) +static void bbmd6_address_resolution_handler( + BACNET_IP6_ADDRESS *addr, uint8_t *pdu, uint16_t pdu_len) { int function_len = 0; uint32_t vmac_src = 0; @@ -571,8 +571,8 @@ static void bbmd6_address_resolution_handler(BACNET_IP6_ADDRESS *addr, * @param pdu - The received NPDU+APDU buffer. * @param pdu_len - How many bytes in NPDU+APDU buffer. */ -static void bbmd6_address_resolution_ack_handler(BACNET_IP6_ADDRESS *addr, - uint8_t *pdu, uint16_t pdu_len) +static void bbmd6_address_resolution_ack_handler( + BACNET_IP6_ADDRESS *addr, uint8_t *pdu, uint16_t pdu_len) { int function_len = 0; uint32_t vmac_src = 0; @@ -604,8 +604,9 @@ static void bbmd6_address_resolution_ack_handler(BACNET_IP6_ADDRESS *addr, * @return number of bytes offset into the NPDU for APDU, or 0 if handled */ static int handler_bbmd6_for_non_bbmd(BACNET_IP6_ADDRESS *addr, - BACNET_ADDRESS *src, uint8_t *mtu, - uint16_t mtu_len) + BACNET_ADDRESS *src, + uint8_t *mtu, + uint16_t mtu_len) { uint16_t result_code = BVLC6_RESULT_SUCCESSFUL_COMPLETION; uint32_t vmac_src = 0; @@ -619,7 +620,7 @@ static int handler_bbmd6_for_non_bbmd(BACNET_IP6_ADDRESS *addr, uint16_t npdu_len = 0; bool send_result = false; uint16_t offset = 0; - BACNET_IP6_ADDRESS fwd_address = {{0}}; + BACNET_IP6_ADDRESS fwd_address = { { 0 } }; header_len = bvlc6_decode_header(mtu, mtu_len, &message_type, &message_length); @@ -638,8 +639,8 @@ static int handler_bbmd6_for_non_bbmd(BACNET_IP6_ADDRESS *addr, incoming messages. */ bbmd6_add_vmac(vmac_src, addr); bvlc6_vmac_address_set(src, vmac_src); - debug_printf("BIP6: Received Result Code=%d\n", - BVLC6_Result_Code); + debug_printf( + "BIP6: Received Result Code=%d\n", BVLC6_Result_Code); } break; case BVLC6_REGISTER_FOREIGN_DEVICE: @@ -673,9 +674,8 @@ static int handler_bbmd6_for_non_bbmd(BACNET_IP6_ADDRESS *addr, bvlc6_vmac_address_set(src, vmac_src); offset = header_len + (function_len - npdu_len); } else { - debug_printf( - "BIP6: Original-Unicast-NPDU: " - "VMAC is not me!\n"); + debug_printf("BIP6: Original-Unicast-NPDU: " + "VMAC is not me!\n"); } } else { debug_printf( @@ -699,9 +699,8 @@ static int handler_bbmd6_for_non_bbmd(BACNET_IP6_ADDRESS *addr, bvlc6_vmac_address_set(src, vmac_src); offset = header_len + (function_len - npdu_len); } else { - debug_printf( - "BIP6: Original-Broadcast-NPDU: Unable to " - "decode!\n"); + debug_printf("BIP6: Original-Broadcast-NPDU: Unable to " + "decode!\n"); } } break; @@ -711,9 +710,8 @@ static int handler_bbmd6_for_non_bbmd(BACNET_IP6_ADDRESS *addr, /* ignore messages from my IPv6 address */ debug_printf("BIP6: Forwarded-NPDU is me!\n"); } else { - function_len = bvlc6_decode_forwarded_npdu( - pdu, pdu_len, &vmac_src, &fwd_address, NULL, 0, - &npdu_len); + function_len = bvlc6_decode_forwarded_npdu(pdu, pdu_len, + &vmac_src, &fwd_address, NULL, 0, &npdu_len); if (function_len) { /* The Virtual MAC address table shall be updated using the respective parameter values of the @@ -741,8 +739,8 @@ static int handler_bbmd6_for_non_bbmd(BACNET_IP6_ADDRESS *addr, bbmd6_virtual_address_resolution_handler(addr, pdu, pdu_len); break; case BVLC6_VIRTUAL_ADDRESS_RESOLUTION_ACK: - bbmd6_virtual_address_resolution_ack_handler(addr, pdu, - pdu_len); + bbmd6_virtual_address_resolution_ack_handler( + addr, pdu, pdu_len); break; case BVLC6_SECURE_BVLL: break; @@ -772,8 +770,10 @@ static int handler_bbmd6_for_non_bbmd(BACNET_IP6_ADDRESS *addr, * * @return number of bytes offset into the NPDU for APDU, or 0 if handled */ -static int handler_bbmd6_for_bbmd(BACNET_IP6_ADDRESS *addr, BACNET_ADDRESS *src, - uint8_t *mtu, uint16_t mtu_len) +static int handler_bbmd6_for_bbmd(BACNET_IP6_ADDRESS *addr, + BACNET_ADDRESS *src, + uint8_t *mtu, + uint16_t mtu_len) { uint16_t result_code = BVLC6_RESULT_SUCCESSFUL_COMPLETION; uint32_t vmac_me = 0; @@ -790,7 +790,7 @@ static int handler_bbmd6_for_bbmd(BACNET_IP6_ADDRESS *addr, BACNET_ADDRESS *src, uint16_t npdu_len = 0; bool send_result = false; uint16_t offset = 0; - BACNET_IP6_ADDRESS fwd_address = {{0}}; + BACNET_IP6_ADDRESS fwd_address = { { 0 } }; header_len = bvlc6_decode_header(mtu, mtu_len, &message_type, &message_length); @@ -809,8 +809,8 @@ static int handler_bbmd6_for_bbmd(BACNET_IP6_ADDRESS *addr, BACNET_ADDRESS *src, incoming messages. */ bbmd6_add_vmac(vmac_src, addr); bvlc6_vmac_address_set(src, vmac_src); - debug_printf("BIP6: Received Result Code=%d\n", - BVLC6_Result_Code); + debug_printf( + "BIP6: Received Result Code=%d\n", BVLC6_Result_Code); } break; case BVLC6_REGISTER_FOREIGN_DEVICE: @@ -892,8 +892,8 @@ static int handler_bbmd6_for_bbmd(BACNET_IP6_ADDRESS *addr, BACNET_ADDRESS *src, &BVLC6_Buffer[0], sizeof(BVLC6_Buffer), vmac_src, addr, npdu, npdu_len); bip6_get_broadcast_addr(&bvlc_dest); - bip6_send_mpdu(&bvlc_dest, &BVLC6_Buffer[0], - BVLC6_Buffer_Len); + bip6_send_mpdu( + &bvlc_dest, &BVLC6_Buffer[0], BVLC6_Buffer_Len); /* In addition, the constructed BVLL Forwarded-NPDU message shall be unicast to each foreign device in the BBMD's FDT. If the BBMD is unable to transmit @@ -925,8 +925,8 @@ static int handler_bbmd6_for_bbmd(BACNET_IP6_ADDRESS *addr, BACNET_ADDRESS *src, bbmd6_virtual_address_resolution_handler(addr, pdu, pdu_len); break; case BVLC6_VIRTUAL_ADDRESS_RESOLUTION_ACK: - bbmd6_virtual_address_resolution_ack_handler(addr, pdu, - pdu_len); + bbmd6_virtual_address_resolution_ack_handler( + addr, pdu, pdu_len); break; case BVLC6_SECURE_BVLL: break; @@ -954,8 +954,10 @@ static int handler_bbmd6_for_bbmd(BACNET_IP6_ADDRESS *addr, BACNET_ADDRESS *src, * * @return number of bytes offset into the NPDU for APDU, or 0 if handled */ -int bvlc6_handler(BACNET_IP6_ADDRESS *addr, BACNET_ADDRESS *src, uint8_t *npdu, - uint16_t npdu_len) +int bvlc6_handler(BACNET_IP6_ADDRESS *addr, + BACNET_ADDRESS *src, + uint8_t *npdu, + uint16_t npdu_len) { #if defined(BACDL_BIP6) && BBMD6_ENABLED return handler_bbmd6_for_bbmd(addr, src, npdu, npdu_len); @@ -973,10 +975,11 @@ int bvlc6_handler(BACNET_IP6_ADDRESS *addr, BACNET_ADDRESS *src, uint8_t *npdu, * 0 if no registration request is sent, or * -1 if registration fails. */ -int bvlc6_register_with_bbmd(BACNET_IP6_ADDRESS *bbmd_addr, uint32_t vmac_src, - uint16_t time_to_live_seconds) +int bvlc6_register_with_bbmd(BACNET_IP6_ADDRESS *bbmd_addr, + uint32_t vmac_src, + uint16_t time_to_live_seconds) { - uint8_t mtu[MAX_MPDU] = {0}; + uint8_t mtu[MAX_MPDU] = { 0 }; uint16_t mtu_len = 0; mtu_len = bvlc6_encode_register_foreign_device( @@ -1037,8 +1040,8 @@ static uint8_t BIP6_MTU_Buffer[MAX_MPDU]; * * @return Number of bytes received, or 0 if none or timeout. */ -uint16_t bip6_receive(BACNET_ADDRESS *src, uint8_t *npdu, uint16_t max_npdu, - unsigned timeout) +uint16_t bip6_receive( + BACNET_ADDRESS *src, uint8_t *npdu, uint16_t max_npdu, unsigned timeout) { return 0; } @@ -1094,23 +1097,22 @@ static void test_BBMD_Result(Test *pTest) { int result = 0; uint32_t vmac_src = 0x1234; - uint16_t result_code[6] = { - BVLC6_RESULT_SUCCESSFUL_COMPLETION, + uint16_t result_code[6] = { BVLC6_RESULT_SUCCESSFUL_COMPLETION, BVLC6_RESULT_ADDRESS_RESOLUTION_NAK, BVLC6_RESULT_VIRTUAL_ADDRESS_RESOLUTION_NAK, BVLC6_RESULT_REGISTER_FOREIGN_DEVICE_NAK, BVLC6_RESULT_DELETE_FOREIGN_DEVICE_NAK, - BVLC6_RESULT_DISTRIBUTE_BROADCAST_TO_NETWORK_NAK}; + BVLC6_RESULT_DISTRIBUTE_BROADCAST_TO_NETWORK_NAK }; uint16_t test_result_code = 0; uint8_t test_function_code = 0; BACNET_IP6_ADDRESS addr; BACNET_ADDRESS src; unsigned int i = 0; - uint8_t mtu[MAX_MPDU] = {0}; + uint8_t mtu[MAX_MPDU] = { 0 }; uint16_t mtu_len = 0; bvlc6_address_set(&addr, BIP6_MULTICAST_LINK_LOCAL, 0, 0, 0, 0, 0, 0, - BIP6_MULTICAST_GROUP_ID); + BIP6_MULTICAST_GROUP_ID); addr.port = 0xBAC0; bvlc6_vmac_address_set(&src, vmac_src); for (i = 0; i < 6; i++) { diff --git a/ports/bsd/timer.h b/src/bacnet/basic/bbmd6/h_bbmd6.h similarity index 58% rename from ports/bsd/timer.h rename to src/bacnet/basic/bbmd6/h_bbmd6.h index a2fff783..df375697 100644 --- a/ports/bsd/timer.h +++ b/src/bacnet/basic/bbmd6/h_bbmd6.h @@ -1,6 +1,10 @@ -/************************************************************************** +/** +* @file +* @author Steve Karg +* @date October 2019 +* @brief Header file for a basic BBMD for BVLC IPv6 handler * -* Copyright (C) 2009 Steve Karg +* @section LICENSE * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the @@ -20,44 +24,37 @@ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*********************************************************************/ -#ifndef TIMER_H -#define TIMER_H +*/ +#ifndef BVLC6_HANDLER_H +#define BVLC6_HANDLER_H +#include +#include #include #include -#include /* for timeval */ - -/* Timer Module */ -#ifndef MAX_MILLISECOND_TIMERS -#define TIMER_SILENCE 0 -#define MAX_MILLISECOND_TIMERS 1 -#endif +#include "bacnet/bacdef.h" +#include "bacnet/datalink/bvlc6.h" #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ - uint32_t timeGetTime( - void); - void timer_init( + /* user application function prototypes */ + int bvlc6_handler( + BACNET_IP6_ADDRESS *addr, + BACNET_ADDRESS * src, + uint8_t * npdu, + uint16_t npdu_len); + int bvlc6_register_with_bbmd( + BACNET_IP6_ADDRESS *bbmd_addr, + uint32_t vmac_src, + uint16_t time_to_live_seconds); + uint16_t bvlc6_get_last_result( void); - uint32_t timer_milliseconds( - unsigned index); - bool timer_elapsed_milliseconds( - unsigned index, - uint32_t value); - bool timer_elapsed_seconds( - unsigned index, - uint32_t value); - bool timer_elapsed_minutes( - unsigned index, - uint32_t seconds); - uint32_t timer_milliseconds_set( - unsigned index, - uint32_t value); - uint32_t timer_reset( - unsigned index); + uint8_t bvlc6_get_function_code( + void); + void bvlc6_init(void); + #ifdef __cplusplus } diff --git a/src/vmac.c b/src/bacnet/basic/bbmd6/vmac.c similarity index 98% rename from src/vmac.c rename to src/bacnet/basic/bbmd6/vmac.c index f903473e..c855a545 100644 --- a/src/vmac.c +++ b/src/bacnet/basic/bbmd6/vmac.c @@ -36,11 +36,11 @@ #include #include #include -#include "config.h" -#include "bacdef.h" -#include "keylist.h" +#include "bacnet/config.h" +#include "bacnet/bacdef.h" +#include "bacnet/basic/sys/keylist.h" /* me! */ -#include "vmac.h" +#include "bacnet/basic/bbmd6/vmac.h" /** @file Handle VMAC address binding */ diff --git a/include/vmac.h b/src/bacnet/basic/bbmd6/vmac.h similarity index 100% rename from include/vmac.h rename to src/bacnet/basic/bbmd6/vmac.h diff --git a/src/address.c b/src/bacnet/basic/binding/address.c similarity index 85% rename from src/address.c rename to src/bacnet/basic/binding/address.c index f1e30b9f..872005f5 100644 --- a/src/address.c +++ b/src/bacnet/basic/binding/address.c @@ -36,12 +36,12 @@ #include #include #include -#include "config.h" -#include "bacaddr.h" -#include "address.h" -#include "bacdef.h" -#include "bacdcode.h" -#include "readrange.h" +#include "bacnet/config.h" +#include "bacnet/bacaddr.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/readrange.h" +#include "bacnet/basic/binding/address.h" /* we are likely compiling the demo command line tools if print enabled */ #if !defined(BACNET_ADDRESS_CACHE_FILE) @@ -69,12 +69,12 @@ static struct Address_Cache_Entry { /* State flags for cache entries */ -#define BAC_ADDR_IN_USE 1 /* Address cache entry in use */ +#define BAC_ADDR_IN_USE 1 /* Address cache entry in use */ #define BAC_ADDR_BIND_REQ 2 /* Bind request outstanding for entry */ -#define BAC_ADDR_STATIC 4 /* Static address mapping - does not expire */ -#define BAC_ADDR_SHORT_TTL \ - 8 /* Oppertunistaclly added address with short TTL \ - */ +#define BAC_ADDR_STATIC 4 /* Static address mapping - does not expire */ +#define BAC_ADDR_SHORT_TTL \ + 8 /* Oppertunistaclly added address with short TTL \ + */ #define BAC_ADDR_RESERVED 128 /* Freed up but held for caller to fill */ #define BAC_ADDR_SECS_1HOUR 3600 /* 60x60 */ @@ -99,30 +99,38 @@ bool address_match(BACNET_ADDRESS *dest, BACNET_ADDRESS *src) uint8_t i = 0; uint8_t max_len = 0; - if (dest->mac_len != src->mac_len) + if (dest->mac_len != src->mac_len) { return false; - max_len = dest->mac_len; - if (max_len > MAX_MAC_LEN) - max_len = MAX_MAC_LEN; - for (i = 0; i < max_len; i++) { - if (dest->mac[i] != src->mac[i]) - return false; } - if (dest->net != src->net) + max_len = dest->mac_len; + if (max_len > MAX_MAC_LEN) { + max_len = MAX_MAC_LEN; + } + for (i = 0; i < max_len; i++) { + if (dest->mac[i] != src->mac[i]) { + return false; + } + } + if (dest->net != src->net) { return false; + } /* if local, ignore remaining fields */ - if (dest->net == 0) + if (dest->net == 0) { return true; + } - if (dest->len != src->len) + if (dest->len != src->len) { return false; + } max_len = dest->len; - if (max_len > MAX_MAC_LEN) + if (max_len > MAX_MAC_LEN) { max_len = MAX_MAC_LEN; + } for (i = 0; i < max_len; i++) { - if (dest->adr[i] != src->adr[i]) + if (dest->adr[i] != src->adr[i]) { return false; + } } return true; @@ -175,8 +183,9 @@ static struct Address_Cache_Entry *address_remove_oldest(void) pMatch = &Address_Cache[Top_Protected_Entry]; while (pMatch <= &Address_Cache[MAX_ADDRESS_CACHE - 1]) { - if ((pMatch->Flags & (BAC_ADDR_IN_USE | BAC_ADDR_BIND_REQ | - BAC_ADDR_STATIC)) == BAC_ADDR_IN_USE) { + if ((pMatch->Flags & + (BAC_ADDR_IN_USE | BAC_ADDR_BIND_REQ | BAC_ADDR_STATIC)) == + BAC_ADDR_IN_USE) { if (pMatch->TimeToLive <= ulTime) { /* Shorter lived entry found */ ulTime = pMatch->TimeToLive; pCandidate = pMatch; @@ -196,7 +205,7 @@ static struct Address_Cache_Entry *address_remove_oldest(void) pMatch = Address_Cache; while (pMatch <= &Address_Cache[MAX_ADDRESS_CACHE - 1]) { if ((pMatch->Flags & - (BAC_ADDR_IN_USE | BAC_ADDR_BIND_REQ | BAC_ADDR_STATIC)) == + (BAC_ADDR_IN_USE | BAC_ADDR_BIND_REQ | BAC_ADDR_STATIC)) == ((uint8_t)(BAC_ADDR_IN_USE | BAC_ADDR_BIND_REQ))) { if (pMatch->TimeToLive <= ulTime) { /* Shorter lived entry found */ ulTime = pMatch->TimeToLive; @@ -244,7 +253,7 @@ void address_mac_init(BACNET_MAC_ADDRESS *mac, uint8_t *adr, uint8_t len) */ bool address_mac_from_ascii(BACNET_MAC_ADDRESS *mac, char *arg) { - unsigned a[6] = {0}, p = 0; + unsigned a[6] = { 0 }, p = 0; uint16_t port = 0; int c; bool status = false; @@ -268,7 +277,7 @@ bool address_mac_from_ascii(BACNET_MAC_ADDRESS *mac, char *arg) status = true; } else { c = sscanf(arg, "%2x:%2x:%2x:%2x:%2x:%2x", &a[0], &a[1], &a[2], &a[3], - &a[4], &a[5]); + &a[4], &a[5]); if (c == 6) { mac->adr[0] = a[0]; mac->adr[1] = a[1]; @@ -301,14 +310,14 @@ static const char *Address_Cache_Filename = "address_cache"; static void address_file_init(const char *pFilename) { - FILE *pFile = NULL; /* stream pointer */ - char line[256] = {""}; /* holds line from file */ + FILE *pFile = NULL; /* stream pointer */ + char line[256] = { "" }; /* holds line from file */ long device_id = 0; unsigned snet = 0; unsigned max_apdu = 0; - char mac_string[80] = {""}, sadr_string[80] = {""}; - BACNET_ADDRESS src = {0}; - BACNET_MAC_ADDRESS mac = {0}; + char mac_string[80] = { "" }, sadr_string[80] = { "" }; + BACNET_ADDRESS src = { 0 }; + BACNET_MAC_ADDRESS mac = { 0 }; int index = 0; pFile = fopen(pFilename, "r"); @@ -317,8 +326,8 @@ static void address_file_init(const char *pFilename) /* ignore comments */ if (line[0] != ';') { if (sscanf(line, "%7ld %79s %5u %79s %4u", &device_id, - &mac_string[0], &snet, &sadr_string[0], - &max_apdu) == 5) { + &mac_string[0], &snet, &sadr_string[0], + &max_apdu) == 5) { if (address_mac_from_ascii(&mac, mac_string)) { src.mac_len = mac.len; for (index = 0; index < MAX_MAC_LEN; index++) { @@ -341,7 +350,7 @@ static void address_file_init(const char *pFilename) } address_add((uint32_t)device_id, max_apdu, &src); address_set_device_TTL((uint32_t)device_id, 0, - true); /* Mark as static entry */ + true); /* Mark as static entry */ } } } @@ -391,8 +400,9 @@ void address_init_partial(void) if ((pMatch->Flags & BAC_ADDR_IN_USE) != 0) { /* It's in use so let's check further */ if (((pMatch->Flags & BAC_ADDR_BIND_REQ) != 0) || - (pMatch->TimeToLive == 0)) + (pMatch->TimeToLive == 0)) { pMatch->Flags = 0; + } } if ((pMatch->Flags & BAC_ADDR_RESERVED) != @@ -416,8 +426,8 @@ void address_init_partial(void) * to avoid breaking the current API. * ****************************************************************************/ -void address_set_device_TTL(uint32_t device_id, uint32_t TimeOut, - bool StaticFlag) +void address_set_device_TTL( + uint32_t device_id, uint32_t TimeOut, bool StaticFlag) { struct Address_Cache_Entry *pMatch; @@ -435,8 +445,8 @@ void address_set_device_TTL(uint32_t device_id, uint32_t TimeOut, pMatch->TimeToLive = TimeOut; } } else { - pMatch->TimeToLive = - TimeOut; /* For unbound we can only set the time to live */ + pMatch->TimeToLive = TimeOut; /* For unbound we can only set the + time to live */ } break; /* Exit now if found at all - bound or unbound */ } @@ -444,8 +454,8 @@ void address_set_device_TTL(uint32_t device_id, uint32_t TimeOut, } } -bool address_get_by_device(uint32_t device_id, unsigned *max_apdu, - BACNET_ADDRESS *src) +bool address_get_by_device( + uint32_t device_id, unsigned *max_apdu, BACNET_ADDRESS *src) { struct Address_Cache_Entry *pMatch; bool found = false; /* return value */ @@ -519,20 +529,21 @@ void address_add(uint32_t device_id, unsigned max_apdu, BACNET_ADDRESS *src) /* Pick the right time to live */ if ((pMatch->Flags & BAC_ADDR_BIND_REQ) != - 0) /* Bind requested so long time */ + 0) { /* Bind requested so long time */ pMatch->TimeToLive = BAC_ADDR_LONG_TIME; - else if ((pMatch->Flags & BAC_ADDR_STATIC) != - 0) /* Static already so make sure it never expires */ + } else if ((pMatch->Flags & BAC_ADDR_STATIC) != + 0) { /* Static already so make sure it never expires */ pMatch->TimeToLive = BAC_ADDR_FOREVER; - else if ((pMatch->Flags & BAC_ADDR_SHORT_TTL) != - 0) /* Opportunistic entry so leave on short fuse */ + } else if ((pMatch->Flags & BAC_ADDR_SHORT_TTL) != + 0) { /* Opportunistic entry so leave on short fuse */ pMatch->TimeToLive = BAC_ADDR_SHORT_TIME; - else + } else { pMatch->TimeToLive = BAC_ADDR_LONG_TIME; /* Renewing existing entry */ + } - pMatch->Flags &= - ~BAC_ADDR_BIND_REQ; /* Clear bind request flag just in case */ + pMatch->Flags &= ~BAC_ADDR_BIND_REQ; /* Clear bind request flag just + in case */ found = true; break; } @@ -575,8 +586,10 @@ void address_add(uint32_t device_id, unsigned max_apdu, BACNET_ADDRESS *src) /* returns true if device is already bound */ /* also returns the address and max apdu if already bound */ -bool address_device_bind_request(uint32_t device_id, uint32_t *device_ttl, - unsigned *max_apdu, BACNET_ADDRESS *src) +bool address_device_bind_request(uint32_t device_id, + uint32_t *device_ttl, + unsigned *max_apdu, + BACNET_ADDRESS *src) { bool found = false; /* return value */ struct Address_Cache_Entry *pMatch; @@ -602,7 +615,8 @@ bool address_device_bind_request(uint32_t device_id, uint32_t *device_ttl, pMatch->Flags &= ~BAC_ADDR_SHORT_TTL; /* Convert to normal entry */ pMatch->TimeToLive = - BAC_ADDR_LONG_TIME; /* And give it a decent time to live + BAC_ADDR_LONG_TIME; /* And give it a decent time to + * live */ } } @@ -641,14 +655,14 @@ bool address_device_bind_request(uint32_t device_id, uint32_t *device_ttl, /* returns true if device is already bound */ /* also returns the address and max apdu if already bound */ -bool address_bind_request(uint32_t device_id, unsigned *max_apdu, - BACNET_ADDRESS *src) +bool address_bind_request( + uint32_t device_id, unsigned *max_apdu, BACNET_ADDRESS *src) { return address_device_bind_request(device_id, NULL, max_apdu, src); } -void address_add_binding(uint32_t device_id, unsigned max_apdu, - BACNET_ADDRESS *src) +void address_add_binding( + uint32_t device_id, unsigned max_apdu, BACNET_ADDRESS *src) { struct Address_Cache_Entry *pMatch; @@ -673,9 +687,11 @@ void address_add_binding(uint32_t device_id, unsigned max_apdu, return; } -bool address_device_get_by_index(unsigned index, uint32_t *device_id, - uint32_t *device_ttl, unsigned *max_apdu, - BACNET_ADDRESS *src) +bool address_device_get_by_index(unsigned index, + uint32_t *device_id, + uint32_t *device_ttl, + unsigned *max_apdu, + BACNET_ADDRESS *src) { struct Address_Cache_Entry *pMatch; bool found = false; /* return value */ @@ -703,8 +719,10 @@ bool address_device_get_by_index(unsigned index, uint32_t *device_id, return found; } -bool address_get_by_index(unsigned index, uint32_t *device_id, - unsigned *max_apdu, BACNET_ADDRESS *src) +bool address_get_by_index(unsigned index, + uint32_t *device_id, + unsigned *max_apdu, + BACNET_ADDRESS *src) { return address_device_get_by_index(index, device_id, NULL, max_apdu, src); } @@ -718,8 +736,9 @@ unsigned address_count(void) while (pMatch <= &Address_Cache[MAX_ADDRESS_CACHE - 1]) { /* Only count bound entries */ if ((pMatch->Flags & (BAC_ADDR_IN_USE | BAC_ADDR_BIND_REQ)) == - BAC_ADDR_IN_USE) + BAC_ADDR_IN_USE) { count++; + } pMatch++; } @@ -747,21 +766,21 @@ int address_list_encode(uint8_t *apdu, unsigned apdu_len) while (pMatch <= &Address_Cache[MAX_ADDRESS_CACHE - 1]) { if ((pMatch->Flags & (BAC_ADDR_IN_USE | BAC_ADDR_BIND_REQ)) == BAC_ADDR_IN_USE) { - iLen += encode_application_object_id(&apdu[iLen], OBJECT_DEVICE, - pMatch->device_id); + iLen += encode_application_object_id( + &apdu[iLen], OBJECT_DEVICE, pMatch->device_id); iLen += encode_application_unsigned(&apdu[iLen], pMatch->address.net); /* pick the appropriate type of entry from the cache */ if (pMatch->address.len != 0) { - octetstring_init(&MAC_Address, pMatch->address.adr, - pMatch->address.len); + octetstring_init( + &MAC_Address, pMatch->address.adr, pMatch->address.len); iLen += encode_application_octet_string(&apdu[iLen], &MAC_Address); } else { - octetstring_init(&MAC_Address, pMatch->address.mac, - pMatch->address.mac_len); + octetstring_init( + &MAC_Address, pMatch->address.mac, pMatch->address.mac_len); iLen += encode_application_octet_string(&apdu[iLen], &MAC_Address); } @@ -803,11 +822,11 @@ int rr_address_list_encode(uint8_t *apdu, BACNET_READ_RANGE_DATA *pRequest) int32_t iTemp = 0; struct Address_Cache_Entry *pMatch = NULL; BACNET_OCTET_STRING MAC_Address; - uint32_t uiTotal = 0; /* Number of bound entries in the cache */ - uint32_t uiIndex = 0; /* Current entry number */ - uint32_t uiFirst = 0; /* Entry number we started encoding from */ - uint32_t uiLast = 0; /* Entry number we finished encoding on */ - uint32_t uiTarget = 0; /* Last entry we are required to encode */ + uint32_t uiTotal = 0; /* Number of bound entries in the cache */ + uint32_t uiIndex = 0; /* Current entry number */ + uint32_t uiFirst = 0; /* Entry number we started encoding from */ + uint32_t uiLast = 0; /* Entry number we finished encoding on */ + uint32_t uiTarget = 0; /* Last entry we are required to encode */ uint32_t uiRemaining = 0; /* Amount of unused space in packet */ /* Initialise result flags to all false */ @@ -818,10 +837,11 @@ int rr_address_list_encode(uint8_t *apdu, BACNET_READ_RANGE_DATA *pRequest) /* See how much space we have */ uiRemaining = (uint32_t)(MAX_APDU - pRequest->Overhead); - pRequest->ItemCount = 0; /* Start out with nothing */ + pRequest->ItemCount = 0; /* Start out with nothing */ uiTotal = address_count(); /* What do we have to work with here ? */ - if (uiTotal == 0) /* Bail out now if nowt */ + if (uiTotal == 0) { /* Bail out now if nowt */ return (0); + } if (pRequest->RequestType == RR_READ_ALL) { /* @@ -829,7 +849,7 @@ int rr_address_list_encode(uint8_t *apdu, BACNET_READ_RANGE_DATA *pRequest) * a range that covers the whole list and falling through to the next * section of code */ - pRequest->Count = uiTotal; /* Full list */ + pRequest->Count = uiTotal; /* Full list */ pRequest->Range.RefIndex = 1; /* Starting at the beginning */ } @@ -864,19 +884,22 @@ int rr_address_list_encode(uint8_t *apdu, BACNET_READ_RANGE_DATA *pRequest) /* From here on in we only have a starting point and a positive count */ if (pRequest->Range.RefIndex > - uiTotal) /* Nothing to return as we are past the end of the list */ + uiTotal) { /* Nothing to return as we are past the end of the list */ return (0); + } uiTarget = pRequest->Range.RefIndex + pRequest->Count - - 1; /* Index of last required entry */ - if (uiTarget > uiTotal) /* Capped at end of list if necessary */ + 1; /* Index of last required entry */ + if (uiTarget > uiTotal) { /* Capped at end of list if necessary */ uiTarget = uiTotal; + } pMatch = Address_Cache; uiIndex = 1; while ((pMatch->Flags & (BAC_ADDR_IN_USE | BAC_ADDR_BIND_REQ)) != - BAC_ADDR_IN_USE) /* Find first bound entry */ + BAC_ADDR_IN_USE) { /* Find first bound entry */ pMatch++; + } /* Seek to start position */ while (uiIndex != pRequest->Range.RefIndex) { @@ -884,8 +907,9 @@ int rr_address_list_encode(uint8_t *apdu, BACNET_READ_RANGE_DATA *pRequest) BAC_ADDR_IN_USE) { /* Only count bound entries */ pMatch++; uiIndex++; - } else + } else { pMatch++; + } } uiFirst = uiIndex; /* Record where we started from */ @@ -895,49 +919,52 @@ int rr_address_list_encode(uint8_t *apdu, BACNET_READ_RANGE_DATA *pRequest) * Can't fit any more in! We just set the result flag to say there * was more and drop out of the loop early */ - bitstring_set_bit(&pRequest->ResultFlags, RESULT_FLAG_MORE_ITEMS, - true); + bitstring_set_bit( + &pRequest->ResultFlags, RESULT_FLAG_MORE_ITEMS, true); break; } iTemp = (int32_t)encode_application_object_id( &apdu[iLen], OBJECT_DEVICE, pMatch->device_id); - iTemp += encode_application_unsigned(&apdu[iLen + iTemp], - pMatch->address.net); + iTemp += encode_application_unsigned( + &apdu[iLen + iTemp], pMatch->address.net); /* pick the appropriate type of entry from the cache */ if (pMatch->address.len != 0) { - octetstring_init(&MAC_Address, pMatch->address.adr, - pMatch->address.len); - iTemp += encode_application_octet_string(&apdu[iLen + iTemp], - &MAC_Address); + octetstring_init( + &MAC_Address, pMatch->address.adr, pMatch->address.len); + iTemp += encode_application_octet_string( + &apdu[iLen + iTemp], &MAC_Address); } else { - octetstring_init(&MAC_Address, pMatch->address.mac, - pMatch->address.mac_len); - iTemp += encode_application_octet_string(&apdu[iLen + iTemp], - &MAC_Address); + octetstring_init( + &MAC_Address, pMatch->address.mac, pMatch->address.mac_len); + iTemp += encode_application_octet_string( + &apdu[iLen + iTemp], &MAC_Address); } uiRemaining -= iTemp; /* Reduce the remaining space */ - iLen += iTemp; /* and increase the length consumed */ + iLen += iTemp; /* and increase the length consumed */ uiLast = uiIndex; /* Record the last entry encoded */ - uiIndex++; /* and get ready for next one */ + uiIndex++; /* and get ready for next one */ pMatch++; pRequest->ItemCount++; /* Chalk up another one for the response count */ while ((pMatch->Flags & (BAC_ADDR_IN_USE | BAC_ADDR_BIND_REQ)) != - BAC_ADDR_IN_USE) /* Find next bound entry */ + BAC_ADDR_IN_USE) { /* Find next bound entry */ pMatch++; + } } /* Set remaining result flags if necessary */ - if (uiFirst == 1) + if (uiFirst == 1) { bitstring_set_bit(&pRequest->ResultFlags, RESULT_FLAG_FIRST_ITEM, true); + } - if (uiLast == uiTotal) + if (uiLast == uiTotal) { bitstring_set_bit(&pRequest->ResultFlags, RESULT_FLAG_LAST_ITEM, true); + } return (iLen); } @@ -957,11 +984,13 @@ void address_cache_timer(uint16_t uSeconds) while (pMatch <= &Address_Cache[MAX_ADDRESS_CACHE - 1]) { if (((pMatch->Flags & (BAC_ADDR_IN_USE | BAC_ADDR_RESERVED)) != 0) && ((pMatch->Flags & BAC_ADDR_STATIC) == - 0)) { /* Check all entries holding a slot except statics */ - if (pMatch->TimeToLive >= uSeconds) + 0)) { /* Check all entries holding a slot except statics + */ + if (pMatch->TimeToLive >= uSeconds) { pMatch->TimeToLive -= uSeconds; - else + } else { pMatch->Flags = 0; + } } pMatch++; @@ -988,8 +1017,10 @@ static void set_address(unsigned index, BACNET_ADDRESS *dest) } } -static void set_file_address(const char *pFilename, uint32_t device_id, - BACNET_ADDRESS *dest, uint16_t max_apdu) +static void set_file_address(const char *pFilename, + uint32_t device_id, + BACNET_ADDRESS *dest, + uint16_t max_apdu) { unsigned i; FILE *pFile = NULL; @@ -1023,10 +1054,10 @@ static void set_file_address(const char *pFilename, uint32_t device_id, #ifdef BACNET_ADDRESS_CACHE_FILE void testAddressFile(Test *pTest) { - BACNET_ADDRESS src = {0}; + BACNET_ADDRESS src = { 0 }; uint32_t device_id = 0; unsigned max_apdu = 480; - BACNET_ADDRESS test_address = {0}; + BACNET_ADDRESS test_address = { 0 }; unsigned test_max_apdu = 0; /* create a fake address */ @@ -1039,8 +1070,8 @@ void testAddressFile(Test *pTest) set_file_address(Address_Cache_Filename, device_id, &src, max_apdu); /* retrieve it from the file, and see if we can find it */ address_file_init(Address_Cache_Filename); - ct_test(pTest, - address_get_by_device(device_id, &test_max_apdu, &test_address)); + ct_test( + pTest, address_get_by_device(device_id, &test_max_apdu, &test_address)); ct_test(pTest, test_max_apdu == max_apdu); ct_test(pTest, bacnet_address_same(&test_address, &src)); @@ -1060,8 +1091,8 @@ void testAddressFile(Test *pTest) set_file_address(Address_Cache_Filename, device_id, &src, max_apdu); /* retrieve it from the file, and see if we can find it */ address_file_init(Address_Cache_Filename); - ct_test(pTest, - address_get_by_device(device_id, &test_max_apdu, &test_address)); + ct_test( + pTest, address_get_by_device(device_id, &test_max_apdu, &test_address)); ct_test(pTest, test_max_apdu == max_apdu); ct_test(pTest, bacnet_address_same(&test_address, &src)); } @@ -1090,12 +1121,13 @@ void testAddress(Test *pTest) device_id = i * 255; set_address(i, &src); /* test the lookup by device id */ - ct_test(pTest, address_get_by_device(device_id, &test_max_apdu, - &test_address)); + ct_test(pTest, + address_get_by_device(device_id, &test_max_apdu, &test_address)); ct_test(pTest, test_max_apdu == max_apdu); ct_test(pTest, bacnet_address_same(&test_address, &src)); - ct_test(pTest, address_get_by_index(i, &test_device_id, &test_max_apdu, - &test_address)); + ct_test(pTest, + address_get_by_index( + i, &test_device_id, &test_max_apdu, &test_address)); ct_test(pTest, test_device_id == device_id); ct_test(pTest, test_max_apdu == max_apdu); ct_test(pTest, bacnet_address_same(&test_address, &src)); @@ -1108,8 +1140,8 @@ void testAddress(Test *pTest) for (i = 0; i < MAX_ADDRESS_CACHE; i++) { device_id = i * 255; address_remove_device(device_id); - ct_test(pTest, !address_get_by_device(device_id, &test_max_apdu, - &test_address)); + ct_test(pTest, + !address_get_by_device(device_id, &test_max_apdu, &test_address)); count = address_count(); ct_test(pTest, count == (MAX_ADDRESS_CACHE - i - 1)); } diff --git a/include/address.h b/src/bacnet/basic/binding/address.h similarity index 98% rename from include/address.h rename to src/bacnet/basic/binding/address.h index 50b5aa4d..aa9581f6 100644 --- a/include/address.h +++ b/src/bacnet/basic/binding/address.h @@ -27,8 +27,8 @@ #include #include #include -#include "bacdef.h" -#include "readrange.h" +#include "bacnet/bacdef.h" +#include "bacnet/readrange.h" #ifdef __cplusplus extern "C" { diff --git a/demo/handler/h_npdu.c b/src/bacnet/basic/npdu/h_npdu.c similarity index 88% rename from demo/handler/h_npdu.c rename to src/bacnet/basic/npdu/h_npdu.c index 23281c7a..66875705 100644 --- a/demo/handler/h_npdu.c +++ b/src/bacnet/basic/npdu/h_npdu.c @@ -24,15 +24,14 @@ *********************************************************************/ #include #include -#include "bacdef.h" -#include "bacdcode.h" -#include "bacint.h" -#include "bacenum.h" -#include "bits.h" -#include "npdu.h" -#include "apdu.h" -#include "handlers.h" -#include "client.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacint.h" +#include "bacnet/bacenum.h" +#include "bacnet/bits.h" +#include "bacnet/npdu.h" +#include "bacnet/apdu.h" +#include "bacnet/basic/services.h" #if PRINT_ENABLED #include @@ -63,13 +62,13 @@ * @param pdu [in] Buffer containing the NPDU and APDU of the received packet. * @param pdu_len [in] The size of the received message in the pdu[] buffer. */ -void npdu_handler(BACNET_ADDRESS* src, /* source address */ - uint8_t* pdu, /* PDU data */ - uint16_t pdu_len) +void npdu_handler(BACNET_ADDRESS *src, /* source address */ + uint8_t *pdu, /* PDU data */ + uint16_t pdu_len) { /* length PDU */ int apdu_offset = 0; - BACNET_ADDRESS dest = {0}; - BACNET_NPDU_DATA npdu_data = {0}; + BACNET_ADDRESS dest = { 0 }; + BACNET_NPDU_DATA npdu_data = { 0 }; /* only handle the version that we know how to handle */ if (pdu[0] == BACNET_PROTOCOL_VERSION) { @@ -86,13 +85,13 @@ void npdu_handler(BACNET_ADDRESS* src, /* source address */ routing information cause they are not for us */ if ((dest.net == BACNET_BROADCAST_NETWORK) && ((pdu[apdu_offset] & 0xF0) == - PDU_TYPE_CONFIRMED_SERVICE_REQUEST)) { + PDU_TYPE_CONFIRMED_SERVICE_REQUEST)) { /* hack for 5.4.5.1 - IDLE */ /* ConfirmedBroadcastReceived */ /* then enter IDLE - ignore the PDU */ } else { apdu_handler(src, &pdu[apdu_offset], - (uint16_t)(pdu_len - apdu_offset)); + (uint16_t)(pdu_len - apdu_offset)); } } else { #if PRINT_ENABLED @@ -103,7 +102,7 @@ void npdu_handler(BACNET_ADDRESS* src, /* source address */ } else { #if PRINT_ENABLED printf("NPDU: BACnet Protocol Version=%u. Discarded!\n", - (unsigned)pdu[0]); + (unsigned)pdu[0]); #endif } diff --git a/src/bacnet/basic/npdu/h_npdu.h b/src/bacnet/basic/npdu/h_npdu.h new file mode 100644 index 00000000..3215418a --- /dev/null +++ b/src/bacnet/basic/npdu/h_npdu.h @@ -0,0 +1,70 @@ +/** +* @file +* @author Steve Karg +* @date October 2019 +* @brief Header file for a basic NPDU handler +* +* @section LICENSE +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +#ifndef NPDU_HANDLER_H +#define NPDU_HANDLER_H + +#include +#include +#include +#include +#include "bacnet/bacdef.h" +#include "bacnet/bacenum.h" +#include "bacnet/apdu.h" +#include "bacnet/npdu.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + void npdu_handler( + BACNET_ADDRESS * src, + uint8_t * pdu, + uint16_t pdu_len); + void npdu_handler_cleanup(void); + void npdu_handler_init( + uint16_t bip_net, + uint16_t mstp_net); + void npdu_router_handler( + uint16_t snet, + BACNET_ADDRESS * src, + uint8_t * pdu, + uint16_t pdu_len); + int npdu_router_send_pdu( + uint16_t dnet, + BACNET_ADDRESS * dest, + BACNET_NPDU_DATA * npdu_data, + uint8_t * pdu, + unsigned int pdu_len); + void npdu_router_get_my_address( + uint16_t dnet, + BACNET_ADDRESS * my_address); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/demo/handler/h_routed_npdu.c b/src/bacnet/basic/npdu/h_routed_npdu.c similarity index 87% rename from demo/handler/h_routed_npdu.c rename to src/bacnet/basic/npdu/h_routed_npdu.c index f3e25d69..faf9f7cb 100644 --- a/demo/handler/h_routed_npdu.c +++ b/src/bacnet/basic/npdu/h_routed_npdu.c @@ -27,24 +27,23 @@ #include #include -#include "bacdef.h" -#include "bacdcode.h" -#include "bacint.h" -#include "bacenum.h" -#include "bits.h" -#include "npdu.h" -#include "apdu.h" -#include "handlers.h" -#include "device.h" -#include "client.h" -#include "bactext.h" -#include "debug.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacint.h" +#include "bacnet/bacenum.h" +#include "bacnet/bits.h" +#include "bacnet/npdu.h" +#include "bacnet/apdu.h" +#include "bacnet/bactext.h" +#include "bacnet/basic/object/device.h" +#include "bacnet/basic/sys/debug.h" +#include "bacnet/basic/services.h" #if PRINT_ENABLED #include #endif #if defined(BACDL_BIP) -#include "bvlc.h" +#include "bacnet/datalink/bvlc.h" #endif /** @file h_routed_npdu.c Handles messages at the NPDU level of the BACnet @@ -68,9 +67,11 @@ * bytes that have already been decoded. * @param npdu_len [in] The length of the remaining NPDU message in npdu[]. */ -static void network_control_handler(BACNET_ADDRESS *src, int *DNET_list, - BACNET_NPDU_DATA *npdu_data, uint8_t *npdu, - uint16_t npdu_len) +static void network_control_handler(BACNET_ADDRESS *src, + int *DNET_list, + BACNET_NPDU_DATA *npdu_data, + uint8_t *npdu, + uint16_t npdu_len) { uint16_t npdu_offset = 0; uint16_t dnet = 0; @@ -105,8 +106,8 @@ static void network_control_handler(BACNET_ADDRESS *src, int *DNET_list, * later for congestion control - then it could matter. */ debug_printf("%s for Networks: ", - bactext_network_layer_msg_name( - NETWORK_MESSAGE_I_AM_ROUTER_TO_NETWORK)); + bactext_network_layer_msg_name( + NETWORK_MESSAGE_I_AM_ROUTER_TO_NETWORK)); while (npdu_len >= 2) { len = decode_unsigned16(&npdu[npdu_offset], &dnet); debug_printf("%hu", dnet); @@ -125,8 +126,8 @@ static void network_control_handler(BACNET_ADDRESS *src, int *DNET_list, if (npdu_len >= 3) { decode_unsigned16(&npdu[1], &dnet); debug_printf("Received %s for Network: ", - bactext_network_layer_msg_name( - NETWORK_MESSAGE_I_COULD_BE_ROUTER_TO_NETWORK)); + bactext_network_layer_msg_name( + NETWORK_MESSAGE_I_COULD_BE_ROUTER_TO_NETWORK)); debug_printf("%hu, Reason code: %d \n", dnet, npdu[0]); } break; @@ -141,9 +142,9 @@ static void network_control_handler(BACNET_ADDRESS *src, int *DNET_list, */ if (npdu_len > 0) { /* If Number of Ports is 0, broadcast our "full" table */ - if (npdu[0] == 0) + if (npdu[0] == 0) { Send_Initialize_Routing_Table_Ack(NULL, DNET_list); - else { + } else { /* If they sent us a list, just politely ACK it * with no routing list of our own. But we don't DO * anything with the info, either. @@ -187,9 +188,11 @@ static void network_control_handler(BACNET_ADDRESS *src, int *DNET_list, * @param apdu [in] The apdu portion of the request, to be processed. * @param apdu_len [in] The total (remaining) length of the apdu. */ -static void routed_apdu_handler(BACNET_ADDRESS *src, BACNET_ADDRESS *dest, - int *DNET_list, uint8_t *apdu, - uint16_t apdu_len) +static void routed_apdu_handler(BACNET_ADDRESS *src, + BACNET_ADDRESS *dest, + int *DNET_list, + uint8_t *apdu, + uint16_t apdu_len) { int cursor = 0; /* Starting hint */ bool bGotOne = false; @@ -204,16 +207,17 @@ static void routed_apdu_handler(BACNET_ADDRESS *src, BACNET_ADDRESS *dest, #if defined(BACDL_BIP) /* If wasn't unicast to us, must have been one of the bcast types. * Drop it. */ - if (bvlc_get_function_code() != BVLC_ORIGINAL_UNICAST_NPDU) + if (bvlc_get_function_code() != BVLC_ORIGINAL_UNICAST_NPDU) { return; + } #endif /* Upper level handlers knew that this was sent as a bcast, * but our only other way to guess at that here is if the dest->adr * is absent, then we know this is some sort of bcast. */ if (dest->len > 0) { - Send_Reject_Message_To_Network(src, NETWORK_REJECT_NO_ROUTE, - dest->net); + Send_Reject_Message_To_Network( + src, NETWORK_REJECT_NO_ROUTE, dest->net); } /* else, silently drop it */ return; } @@ -221,8 +225,9 @@ static void routed_apdu_handler(BACNET_ADDRESS *src, BACNET_ADDRESS *dest, while (Routed_Device_GetNext(dest, DNET_list, &cursor)) { apdu_handler(src, apdu, apdu_len); bGotOne = true; - if (cursor < 0) /* If no more matches, */ - break; /* We don't need to keep looking */ + if (cursor < 0) { /* If no more matches, */ + break; /* We don't need to keep looking */ + } } if (!bGotOne) { /* Just silently drop this packet. */ @@ -258,12 +263,12 @@ static void routed_apdu_handler(BACNET_ADDRESS *src, BACNET_ADDRESS *dest, * @param pdu [in] Buffer containing the NPDU and APDU of the received packet. * @param pdu_len [in] The size of the received message in the pdu[] buffer. */ -void routing_npdu_handler(BACNET_ADDRESS *src, int *DNET_list, uint8_t *pdu, - uint16_t pdu_len) +void routing_npdu_handler( + BACNET_ADDRESS *src, int *DNET_list, uint8_t *pdu, uint16_t pdu_len) { int apdu_offset = 0; - BACNET_ADDRESS dest = {0}; - BACNET_NPDU_DATA npdu_data = {0}; + BACNET_ADDRESS dest = { 0 }; + BACNET_NPDU_DATA npdu_data = { 0 }; /* only handle the version that we know how to handle */ if (pdu[0] == BACNET_PROTOCOL_VERSION) { @@ -273,17 +278,17 @@ void routing_npdu_handler(BACNET_ADDRESS *src, int *DNET_list, uint8_t *pdu, } else if (npdu_data.network_layer_message) { if ((dest.net == 0) || (dest.net == BACNET_BROADCAST_NETWORK)) { network_control_handler(src, DNET_list, &npdu_data, - &pdu[apdu_offset], - (uint16_t)(pdu_len - apdu_offset)); + &pdu[apdu_offset], (uint16_t)(pdu_len - apdu_offset)); } else { /* The DNET is set, but we don't support downstream routers, * so we just silently drop this network layer message, * since only routers can handle it (even if for our DNET) */ } } else if (apdu_offset <= pdu_len) { - if ((dest.net == 0) || (npdu_data.hop_count > 1)) + if ((dest.net == 0) || (npdu_data.hop_count > 1)) { routed_apdu_handler(src, &dest, DNET_list, &pdu[apdu_offset], - (uint16_t)(pdu_len - apdu_offset)); + (uint16_t)(pdu_len - apdu_offset)); + } /* Else, hop_count bottomed out and we discard this one. */ } } else { diff --git a/ports/atmega8/timer.h b/src/bacnet/basic/npdu/h_routed_npdu.h similarity index 70% rename from ports/atmega8/timer.h rename to src/bacnet/basic/npdu/h_routed_npdu.h index 7858ec56..f4aa3dae 100644 --- a/ports/atmega8/timer.h +++ b/src/bacnet/basic/npdu/h_routed_npdu.h @@ -1,6 +1,10 @@ -/************************************************************************** +/** +* @file +* @author Steve Karg +* @date October 2019 +* @brief Header file for a basic routing NPDU handler * -* Copyright (C) 2007 Steve Karg +* @section LICENSE * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the @@ -20,21 +24,27 @@ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -* -*********************************************************************/ -#ifndef TIMER_H -#define TIMER_H +*/ +#ifndef ROUTING_NPDU_HANDLER_H +#define ROUTING_NPDU_HANDLER_H + +#include +#include +#include +#include +#include "bacnet/bacdef.h" +#include "bacnet/bacenum.h" +#include "bacnet/apdu.h" #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ - void timer_init( - void); - bool timer_silence_elapsed( - uint16_t value); - void timer_silence_reset( - void); + void routing_npdu_handler( + BACNET_ADDRESS * src, + int *DNET_list, + uint8_t * pdu, + uint16_t pdu_len); #ifdef __cplusplus } diff --git a/demo/handler/s_router.c b/src/bacnet/basic/npdu/s_router.c similarity index 79% rename from demo/handler/s_router.c rename to src/bacnet/basic/npdu/s_router.c index 9e8a6b41..04729ae7 100644 --- a/demo/handler/s_router.c +++ b/src/bacnet/basic/npdu/s_router.c @@ -26,22 +26,19 @@ #include #include #include -#include "config.h" -#include "txbuf.h" -#include "bacdef.h" -#include "bacdcode.h" -#include "address.h" -#include "tsm.h" -#include "npdu.h" -#include "apdu.h" -#include "device.h" -#include "datalink.h" -#include "bactext.h" +#include "bacnet/config.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/npdu.h" +#include "bacnet/apdu.h" +#include "bacnet/bactext.h" /* some demo stuff needed */ -#include "handlers.h" -#include "txbuf.h" -#include "client.h" -#include "debug.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/basic/binding/address.h" +#include "bacnet/basic/object/device.h" +#include "bacnet/datalink/datalink.h" +#include "bacnet/basic/sys/debug.h" +#include "bacnet/basic/services.h" /** @file s_router.c Methods to send various BACnet Router Network Layer * Messages. */ @@ -60,9 +57,9 @@ * @param priority [in] One of the 4 priorities defined in section 6.2.2, * like B'11' = Life Safety message */ -static void npdu_encode_npdu_network( - BACNET_NPDU_DATA *npdu_data, - BACNET_NETWORK_MESSAGE_TYPE network_message_type, bool data_expecting_reply, +void npdu_encode_npdu_network(BACNET_NPDU_DATA *npdu_data, + BACNET_NETWORK_MESSAGE_TYPE network_message_type, + bool data_expecting_reply, BACNET_MESSAGE_PRIORITY priority) { if (npdu_data) { @@ -98,7 +95,8 @@ static void npdu_encode_npdu_network( * @return Number of bytes sent, or <=0 if no message was sent. */ int Send_Network_Layer_Message(BACNET_NETWORK_MESSAGE_TYPE network_message_type, - BACNET_ADDRESS *dst, int *iArgs) + BACNET_ADDRESS *dst, + int *iArgs) { int len = 0; int pdu_len = 0; @@ -108,8 +106,9 @@ int Send_Network_Layer_Message(BACNET_NETWORK_MESSAGE_TYPE network_message_type, BACNET_NPDU_DATA npdu_data; BACNET_ADDRESS bcastDest; - if (iArgs == NULL) + if (iArgs == NULL) { return 0; /* Can't do anything here */ + } /* If dst was NULL, get our (local net) broadcast MAC address. */ if (dst == NULL) { @@ -117,10 +116,11 @@ int Send_Network_Layer_Message(BACNET_NETWORK_MESSAGE_TYPE network_message_type, dst = &bcastDest; } - if (network_message_type == NETWORK_MESSAGE_INIT_RT_TABLE) + if (network_message_type == NETWORK_MESSAGE_INIT_RT_TABLE) { data_expecting_reply = true; /* DER in this one case */ + } npdu_encode_npdu_network(&npdu_data, network_message_type, - data_expecting_reply, MESSAGE_PRIORITY_NORMAL); + data_expecting_reply, MESSAGE_PRIORITY_NORMAL); /* We don't need src information, since a message can't originate from * our downstream BACnet network. @@ -132,8 +132,8 @@ int Send_Network_Layer_Message(BACNET_NETWORK_MESSAGE_TYPE network_message_type, switch (network_message_type) { case NETWORK_MESSAGE_WHO_IS_ROUTER_TO_NETWORK: if (*pVal >= 0) { - len = encode_unsigned16(&Handler_Transmit_Buffer[pdu_len], - (uint16_t)*pVal); + len = encode_unsigned16( + &Handler_Transmit_Buffer[pdu_len], (uint16_t)*pVal); pdu_len += len; } /* else, don't encode a DNET */ @@ -143,8 +143,8 @@ int Send_Network_Layer_Message(BACNET_NETWORK_MESSAGE_TYPE network_message_type, case NETWORK_MESSAGE_ROUTER_BUSY_TO_NETWORK: case NETWORK_MESSAGE_ROUTER_AVAILABLE_TO_NETWORK: while (*pVal >= 0) { - len = encode_unsigned16(&Handler_Transmit_Buffer[pdu_len], - (uint16_t)*pVal); + len = encode_unsigned16( + &Handler_Transmit_Buffer[pdu_len], (uint16_t)*pVal); pdu_len += len; pVal++; } @@ -154,8 +154,8 @@ int Send_Network_Layer_Message(BACNET_NETWORK_MESSAGE_TYPE network_message_type, /* Encode the Reason byte, then the DNET */ Handler_Transmit_Buffer[pdu_len++] = (uint8_t)*pVal; pVal++; - len = encode_unsigned16(&Handler_Transmit_Buffer[pdu_len], - (uint16_t)*pVal); + len = encode_unsigned16( + &Handler_Transmit_Buffer[pdu_len], (uint16_t)*pVal); pdu_len += len; break; @@ -177,13 +177,13 @@ int Send_Network_Layer_Message(BACNET_NETWORK_MESSAGE_TYPE network_message_type, * and have no PortInfo. */ while (*pVal >= 0) { - len = encode_unsigned16(&Handler_Transmit_Buffer[pdu_len], - (uint16_t)*pVal); + len = encode_unsigned16( + &Handler_Transmit_Buffer[pdu_len], (uint16_t)*pVal); pdu_len += len; Handler_Transmit_Buffer[pdu_len++] = portID++; Handler_Transmit_Buffer[pdu_len++] = 0; - debug_printf(" Sending Routing Table entry for %u \n", - *pVal); + debug_printf( + " Sending Routing Table entry for %u \n", *pVal); pVal++; } } @@ -191,28 +191,28 @@ int Send_Network_Layer_Message(BACNET_NETWORK_MESSAGE_TYPE network_message_type, default: debug_printf("Not sent: %s message unsupported \n", - bactext_network_layer_msg_name(network_message_type)); + bactext_network_layer_msg_name(network_message_type)); return 0; break; /* Will never reach this line */ } - if (dst != NULL) + if (dst != NULL) { debug_printf("Sending %s message to BACnet network %u \n", - bactext_network_layer_msg_name(network_message_type), - dst->net); - else + bactext_network_layer_msg_name(network_message_type), dst->net); + } else { debug_printf("Sending %s message to local BACnet network \n", - bactext_network_layer_msg_name(network_message_type)); + bactext_network_layer_msg_name(network_message_type)); + } /* Now send the message */ - bytes_sent = datalink_send_pdu(dst, &npdu_data, &Handler_Transmit_Buffer[0], - pdu_len); + bytes_sent = datalink_send_pdu( + dst, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len); #if PRINT_ENABLED if (bytes_sent <= 0) { int wasErrno = errno; /* preserve the errno */ debug_printf("Failed to send %s message (%s)!\n", - bactext_network_layer_msg_name(network_message_type), - strerror(wasErrno)); + bactext_network_layer_msg_name(network_message_type), + strerror(wasErrno)); } #endif return bytes_sent; @@ -231,8 +231,8 @@ int Send_Network_Layer_Message(BACNET_NETWORK_MESSAGE_TYPE network_message_type, */ void Send_Who_Is_Router_To_Network(BACNET_ADDRESS *dst, int dnet) { - Send_Network_Layer_Message(NETWORK_MESSAGE_WHO_IS_ROUTER_TO_NETWORK, dst, - &dnet); + Send_Network_Layer_Message( + NETWORK_MESSAGE_WHO_IS_ROUTER_TO_NETWORK, dst, &dnet); } /** Broadcast an I-am-router-to-network message, giving the list of networks @@ -247,8 +247,8 @@ void Send_Who_Is_Router_To_Network(BACNET_ADDRESS *dst, int dnet) void Send_I_Am_Router_To_Network(const int DNET_list[]) { /* Use a NULL dst here since we want a broadcast MAC address. */ - Send_Network_Layer_Message(NETWORK_MESSAGE_I_AM_ROUTER_TO_NETWORK, NULL, - (int *)DNET_list); + Send_Network_Layer_Message( + NETWORK_MESSAGE_I_AM_ROUTER_TO_NETWORK, NULL, (int *)DNET_list); } /** Finds a specific router, or all reachable BACnet networks. @@ -261,14 +261,14 @@ void Send_I_Am_Router_To_Network(const int DNET_list[]) * @param reject_reason [in] One of the BACNET_NETWORK_REJECT_REASONS codes. * @param dnet [in] Which BACnet network orginated the message. */ -void Send_Reject_Message_To_Network(BACNET_ADDRESS *dst, uint8_t reject_reason, - int dnet) +void Send_Reject_Message_To_Network( + BACNET_ADDRESS *dst, uint8_t reject_reason, int dnet) { int iArgs[2]; iArgs[0] = reject_reason; iArgs[1] = dnet; - Send_Network_Layer_Message(NETWORK_MESSAGE_REJECT_MESSAGE_TO_NETWORK, dst, - iArgs); + Send_Network_Layer_Message( + NETWORK_MESSAGE_REJECT_MESSAGE_TO_NETWORK, dst, iArgs); debug_printf(" Reject Reason=%d, DNET=%u\n", reject_reason, dnet); } @@ -291,8 +291,8 @@ void Send_Reject_Message_To_Network(BACNET_ADDRESS *dst, uint8_t reject_reason, void Send_Initialize_Routing_Table(BACNET_ADDRESS *dst, const int DNET_list[]) { /* Use a NULL dst here since we want a broadcast MAC address. */ - Send_Network_Layer_Message(NETWORK_MESSAGE_INIT_RT_TABLE, dst, - (int *)DNET_list); + Send_Network_Layer_Message( + NETWORK_MESSAGE_INIT_RT_TABLE, dst, (int *)DNET_list); } /** Sends our Routing Table, built from our DNET[] array, as an ACK. @@ -312,9 +312,9 @@ void Send_Initialize_Routing_Table(BACNET_ADDRESS *dst, const int DNET_list[]) * terminated with -1. May be just -1 when no table * should be sent. */ -void Send_Initialize_Routing_Table_Ack(BACNET_ADDRESS *dst, - const int DNET_list[]) +void Send_Initialize_Routing_Table_Ack( + BACNET_ADDRESS *dst, const int DNET_list[]) { - Send_Network_Layer_Message(NETWORK_MESSAGE_INIT_RT_TABLE_ACK, dst, - (int *)DNET_list); + Send_Network_Layer_Message( + NETWORK_MESSAGE_INIT_RT_TABLE_ACK, dst, (int *)DNET_list); } diff --git a/src/bacnet/basic/npdu/s_router.h b/src/bacnet/basic/npdu/s_router.h new file mode 100644 index 00000000..4689a818 --- /dev/null +++ b/src/bacnet/basic/npdu/s_router.h @@ -0,0 +1,73 @@ +/** +* @file +* @author Steve Karg +* @date October 2019 +* @brief Header file for a basic WritePropertyMultiple service send +* +* @section LICENSE +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +#ifndef SEND_ROUTER_H +#define SEND_ROUTER_H + +#include +#include +#include +#include +#include "bacnet/bacapp.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacenum.h" +#include "bacnet/apdu.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + void npdu_encode_npdu_network( + BACNET_NPDU_DATA *npdu_data, + BACNET_NETWORK_MESSAGE_TYPE network_message_type, + bool data_expecting_reply, + BACNET_MESSAGE_PRIORITY priority); + int Send_Network_Layer_Message( + BACNET_NETWORK_MESSAGE_TYPE network_message_type, + BACNET_ADDRESS * dst, + int *iArgs); + void Send_Who_Is_Router_To_Network( + BACNET_ADDRESS * dst, + int dnet); + void Send_I_Am_Router_To_Network( + const int DNET_list[]); + void Send_Reject_Message_To_Network( + BACNET_ADDRESS * dst, + uint8_t reject_reason, + int dnet); + void Send_Initialize_Routing_Table( + BACNET_ADDRESS * dst, + const int DNET_list[]); + void Send_Initialize_Routing_Table_Ack( + BACNET_ADDRESS * dst, + const int DNET_list[]); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/demo/object/Makefile b/src/bacnet/basic/object/Makefile similarity index 100% rename from demo/object/Makefile rename to src/bacnet/basic/object/Makefile diff --git a/demo/object/access_credential.c b/src/bacnet/basic/object/access_credential.c similarity index 82% rename from demo/object/access_credential.c rename to src/bacnet/basic/object/access_credential.c index 9ea5aa13..5e8fb8d7 100644 --- a/demo/object/access_credential.c +++ b/src/bacnet/basic/object/access_credential.c @@ -29,49 +29,43 @@ #include #include #include -#include "bacdef.h" -#include "bacdcode.h" -#include "bacenum.h" -#include "bacapp.h" -#include "config.h" /* the custom stuff */ -#include "wp.h" -#include "access_credential.h" -#include "handlers.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacenum.h" +#include "bacnet/bacapp.h" +#include "bacnet/config.h" /* the custom stuff */ +#include "bacnet/wp.h" +#include "bacnet/basic/object/access_credential.h" +#include "bacnet/basic/services.h" static bool Access_Credential_Initialized = false; static ACCESS_CREDENTIAL_DESCR ac_descr[MAX_ACCESS_CREDENTIALS]; /* These three arrays are used by the ReadPropertyMultiple handler */ -static const int Properties_Required[] = {PROP_OBJECT_IDENTIFIER, - PROP_OBJECT_NAME, - PROP_OBJECT_TYPE, - PROP_GLOBAL_IDENTIFIER, - PROP_STATUS_FLAGS, - PROP_RELIABILITY, - PROP_CREDENTIAL_STATUS, - PROP_REASON_FOR_DISABLE, - PROP_AUTHENTICATION_FACTORS, - PROP_ACTIVATION_TIME, - PROP_EXPIRATION_TIME, - PROP_CREDENTIAL_DISABLE, - PROP_ASSIGNED_ACCESS_RIGHTS, - -1}; +static const int Properties_Required[] = { PROP_OBJECT_IDENTIFIER, + PROP_OBJECT_NAME, PROP_OBJECT_TYPE, PROP_GLOBAL_IDENTIFIER, + PROP_STATUS_FLAGS, PROP_RELIABILITY, PROP_CREDENTIAL_STATUS, + PROP_REASON_FOR_DISABLE, PROP_AUTHENTICATION_FACTORS, PROP_ACTIVATION_TIME, + PROP_EXPIRATION_TIME, PROP_CREDENTIAL_DISABLE, PROP_ASSIGNED_ACCESS_RIGHTS, + -1 }; -static const int Properties_Optional[] = {-1}; +static const int Properties_Optional[] = { -1 }; -static const int Properties_Proprietary[] = {-1}; +static const int Properties_Proprietary[] = { -1 }; -void Access_Credential_Property_Lists(const int **pRequired, - const int **pOptional, - const int **pProprietary) +void Access_Credential_Property_Lists( + const int **pRequired, const int **pOptional, const int **pProprietary) { - if (pRequired) + if (pRequired) { *pRequired = Properties_Required; - if (pOptional) + } + if (pOptional) { *pOptional = Properties_Optional; - if (pProprietary) + } + if (pProprietary) { *pProprietary = Properties_Proprietary; + } return; } @@ -105,8 +99,9 @@ void Access_Credential_Init(void) /* given instance exists */ bool Access_Credential_Valid_Instance(uint32_t object_instance) { - if (object_instance < MAX_ACCESS_CREDENTIALS) + if (object_instance < MAX_ACCESS_CREDENTIALS) { return true; + } return false; } @@ -133,22 +128,23 @@ unsigned Access_Credential_Instance_To_Index(uint32_t object_instance) { unsigned index = MAX_ACCESS_CREDENTIALS; - if (object_instance < MAX_ACCESS_CREDENTIALS) + if (object_instance < MAX_ACCESS_CREDENTIALS) { index = object_instance; + } return index; } /* note: the object name must be unique within this device */ -bool Access_Credential_Object_Name(uint32_t object_instance, - BACNET_CHARACTER_STRING *object_name) +bool Access_Credential_Object_Name( + uint32_t object_instance, BACNET_CHARACTER_STRING *object_name) { static char text_string[32] = ""; /* okay for single thread */ bool status = false; if (object_instance < MAX_ACCESS_CREDENTIALS) { sprintf(text_string, "ACCESS CREDENTIAL %lu", - (unsigned long)object_instance); + (unsigned long)object_instance); status = characterstring_init_ansi(object_name, text_string); } @@ -178,14 +174,14 @@ int Access_Credential_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) &apdu[0], OBJECT_ACCESS_CREDENTIAL, rpdata->object_instance); break; case PROP_OBJECT_NAME: - Access_Credential_Object_Name(rpdata->object_instance, - &char_string); + Access_Credential_Object_Name( + rpdata->object_instance, &char_string); apdu_len = encode_application_character_string(&apdu[0], &char_string); break; case PROP_OBJECT_TYPE: - apdu_len = encode_application_enumerated(&apdu[0], - OBJECT_ACCESS_CREDENTIAL); + apdu_len = encode_application_enumerated( + &apdu[0], OBJECT_ACCESS_CREDENTIAL); break; case PROP_GLOBAL_IDENTIFIER: apdu_len = encode_application_unsigned( @@ -211,9 +207,9 @@ int Access_Credential_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) for (i = 0; i < ac_descr[object_index].reasons_count; i++) { len = encode_application_enumerated( &apdu[0], ac_descr[object_index].reason_for_disable[i]); - if (apdu_len + len < MAX_APDU) + if (apdu_len + len < MAX_APDU) { apdu_len += len; - else { + } else { rpdata->error_code = ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED; apdu_len = BACNET_STATUS_ABORT; @@ -230,9 +226,9 @@ int Access_Credential_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) i++) { len = bacapp_encode_credential_authentication_factor( &apdu[0], &ac_descr[object_index].auth_factors[i]); - if (apdu_len + len < MAX_APDU) + if (apdu_len + len < MAX_APDU) { apdu_len += len; - else { + } else { rpdata->error_code = ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED; apdu_len = BACNET_STATUS_ABORT; @@ -242,9 +238,10 @@ int Access_Credential_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) } else { if (rpdata->array_index <= ac_descr[object_index].auth_factors_count) { - apdu_len = bacapp_encode_credential_authentication_factor( - &apdu[0], &ac_descr[object_index] - .auth_factors[rpdata->array_index - 1]); + apdu_len = + bacapp_encode_credential_authentication_factor(&apdu[0], + &ac_descr[object_index] + .auth_factors[rpdata->array_index - 1]); } else { rpdata->error_class = ERROR_CLASS_PROPERTY; rpdata->error_code = ERROR_CODE_INVALID_ARRAY_INDEX; @@ -266,19 +263,17 @@ int Access_Credential_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) break; case PROP_ASSIGNED_ACCESS_RIGHTS: if (rpdata->array_index == 0) { - apdu_len = encode_application_unsigned( - &apdu[0], + apdu_len = encode_application_unsigned(&apdu[0], ac_descr[object_index].assigned_access_rights_count); } else if (rpdata->array_index == BACNET_ARRAY_ALL) { for (i = 0; i < ac_descr[object_index].assigned_access_rights_count; i++) { - len = bacapp_encode_assigned_access_rights( - &apdu[0], + len = bacapp_encode_assigned_access_rights(&apdu[0], &ac_descr[object_index].assigned_access_rights[i]); - if (apdu_len + len < MAX_APDU) + if (apdu_len + len < MAX_APDU) { apdu_len += len; - else { + } else { rpdata->error_code = ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED; apdu_len = BACNET_STATUS_ABORT; @@ -288,8 +283,7 @@ int Access_Credential_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) } else { if (rpdata->array_index <= ac_descr[object_index].assigned_access_rights_count) { - apdu_len = bacapp_encode_assigned_access_rights( - &apdu[0], + apdu_len = bacapp_encode_assigned_access_rights(&apdu[0], &ac_descr[object_index] .assigned_access_rights[rpdata->array_index - 1]); } else { @@ -327,8 +321,8 @@ bool Access_Credential_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) unsigned object_index = 0; /* decode the some of the request */ - len = bacapp_decode_application_data(wp_data->application_data, - wp_data->application_data_len, &value); + len = bacapp_decode_application_data( + wp_data->application_data, wp_data->application_data_len, &value); /* FIXME: len < application_data_len: more data? */ if (len < 0) { /* error while decoding - a value larger than we can handle */ @@ -350,7 +344,7 @@ bool Access_Credential_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) case PROP_GLOBAL_IDENTIFIER: status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_UNSIGNED_INT, - &wp_data->error_class, &wp_data->error_code); + &wp_data->error_class, &wp_data->error_code); if (status) { ac_descr[object_index].global_identifier = value.type.Unsigned_Int; @@ -386,8 +380,9 @@ bool Access_Credential_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) #include "ctest.h" bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue, - uint8_t ucExpectedTag, BACNET_ERROR_CLASS *pErrorClass, - BACNET_ERROR_CODE *pErrorCode) + uint8_t ucExpectedTag, + BACNET_ERROR_CLASS *pErrorClass, + BACNET_ERROR_CODE *pErrorCode) { pValue = pValue; ucExpectedTag = ucExpectedTag; @@ -399,7 +394,7 @@ bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue, void testAccessCredential(Test *pTest) { - uint8_t apdu[MAX_APDU] = {0}; + uint8_t apdu[MAX_APDU] = { 0 }; int len = 0; uint32_t len_value = 0; uint8_t tag_number = 0; diff --git a/demo/object/access_credential.h b/src/bacnet/basic/object/access_credential.h similarity index 92% rename from demo/object/access_credential.h rename to src/bacnet/basic/object/access_credential.h index 1bb36e44..b6c81afc 100644 --- a/demo/object/access_credential.h +++ b/src/bacnet/basic/object/access_credential.h @@ -27,15 +27,15 @@ #include #include -#include "bacdef.h" -#include "bacerror.h" -#include "datetime.h" -#include "timestamp.h" -#include "bacdevobjpropref.h" -#include "assigned_access_rights.h" -#include "credential_authentication_factor.h" -#include "rp.h" -#include "wp.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacerror.h" +#include "bacnet/datetime.h" +#include "bacnet/timestamp.h" +#include "bacnet/bacdevobjpropref.h" +#include "bacnet/assigned_access_rights.h" +#include "bacnet/credential_authentication_factor.h" +#include "bacnet/rp.h" +#include "bacnet/wp.h" #ifndef MAX_ACCESS_CREDENTIALS diff --git a/demo/object/access_credential.mak b/src/bacnet/basic/object/access_credential.mak similarity index 54% rename from demo/object/access_credential.mak rename to src/bacnet/basic/object/access_credential.mak index 40f819c2..a1e852dd 100644 --- a/demo/object/access_credential.mak +++ b/src/bacnet/basic/object/access_credential.mak @@ -8,19 +8,19 @@ DEFINES = -DBIG_ENDIAN=0 -DTEST -DBACAPP_ALL -DTEST_ACCESS_CREDENTIAL CFLAGS = -Wall $(INCLUDES) $(DEFINES) -g SRCS = access_credential.c \ - $(SRC_DIR)/bacdcode.c \ - $(SRC_DIR)/bacint.c \ - $(SRC_DIR)/bacstr.c \ - $(SRC_DIR)/bacreal.c \ - $(SRC_DIR)/datetime.c \ - $(SRC_DIR)/lighting.c \ - $(SRC_DIR)/bacapp.c \ - $(SRC_DIR)/bacdevobjpropref.c \ - $(SRC_DIR)/assigned_access_rights.c \ - $(SRC_DIR)/authentication_factor.c \ - $(SRC_DIR)/credential_authentication_factor.c \ - $(SRC_DIR)/bactext.c \ - $(SRC_DIR)/indtext.c \ + $(SRC_DIR)/bacnet/bacdcode.c \ + $(SRC_DIR)/bacnet/bacint.c \ + $(SRC_DIR)/bacnet/bacstr.c \ + $(SRC_DIR)/bacnet/bacreal.c \ + $(SRC_DIR)/bacnet/datetime.c \ + $(SRC_DIR)/bacnet/lighting.c \ + $(SRC_DIR)/bacnet/bacapp.c \ + $(SRC_DIR)/bacnet/bacdevobjpropref.c \ + $(SRC_DIR)/bacnet/assigned_access_rights.c \ + $(SRC_DIR)/bacnet/authentication_factor.c \ + $(SRC_DIR)/bacnet/credential_authentication_factor.c \ + $(SRC_DIR)/bacnet/bactext.c \ + $(SRC_DIR)/bacnet/indtext.c \ $(TEST_DIR)/ctest.c TARGET = access_credential diff --git a/demo/object/access_door.c b/src/bacnet/basic/object/access_door.c similarity index 81% rename from demo/object/access_door.c rename to src/bacnet/basic/object/access_door.c index 87f99920..b9cd341e 100644 --- a/demo/object/access_door.c +++ b/src/bacnet/basic/object/access_door.c @@ -28,51 +28,44 @@ #include #include #include -#include "bacdef.h" -#include "bacdcode.h" -#include "bacenum.h" -#include "bacapp.h" -#include "config.h" /* the custom stuff */ -#include "wp.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacenum.h" +#include "bacnet/bacapp.h" +#include "bacnet/config.h" /* the custom stuff */ +#include "bacnet/wp.h" #include "access_door.h" -#include "handlers.h" +#include "bacnet/basic/services.h" static bool Access_Door_Initialized = false; static ACCESS_DOOR_DESCR ad_descr[MAX_ACCESS_DOORS]; /* These three arrays are used by the ReadPropertyMultiple handler */ -static const int Properties_Required[] = {PROP_OBJECT_IDENTIFIER, - PROP_OBJECT_NAME, - PROP_OBJECT_TYPE, - PROP_PRESENT_VALUE, - PROP_STATUS_FLAGS, - PROP_EVENT_STATE, - PROP_RELIABILITY, - PROP_OUT_OF_SERVICE, - PROP_PRIORITY_ARRAY, - PROP_RELINQUISH_DEFAULT, - PROP_DOOR_PULSE_TIME, - PROP_DOOR_EXTENDED_PULSE_TIME, - PROP_DOOR_OPEN_TOO_LONG_TIME, - -1}; +static const int Properties_Required[] = { PROP_OBJECT_IDENTIFIER, + PROP_OBJECT_NAME, PROP_OBJECT_TYPE, PROP_PRESENT_VALUE, PROP_STATUS_FLAGS, + PROP_EVENT_STATE, PROP_RELIABILITY, PROP_OUT_OF_SERVICE, + PROP_PRIORITY_ARRAY, PROP_RELINQUISH_DEFAULT, PROP_DOOR_PULSE_TIME, + PROP_DOOR_EXTENDED_PULSE_TIME, PROP_DOOR_OPEN_TOO_LONG_TIME, -1 }; -static const int Properties_Optional[] = { - PROP_DOOR_STATUS, PROP_LOCK_STATUS, - PROP_SECURED_STATUS, PROP_DOOR_UNLOCK_DELAY_TIME, - PROP_DOOR_ALARM_STATE, -1}; +static const int Properties_Optional[] = { PROP_DOOR_STATUS, PROP_LOCK_STATUS, + PROP_SECURED_STATUS, PROP_DOOR_UNLOCK_DELAY_TIME, PROP_DOOR_ALARM_STATE, + -1 }; -static const int Properties_Proprietary[] = {-1}; +static const int Properties_Proprietary[] = { -1 }; -void Access_Door_Property_Lists(const int **pRequired, const int **pOptional, - const int **pProprietary) +void Access_Door_Property_Lists( + const int **pRequired, const int **pOptional, const int **pProprietary) { - if (pRequired) + if (pRequired) { *pRequired = Properties_Required; - if (pOptional) + } + if (pOptional) { *pOptional = Properties_Optional; - if (pProprietary) + } + if (pProprietary) { *pProprietary = Properties_Proprietary; + } return; } @@ -93,9 +86,9 @@ void Access_Door_Init(void) ad_descr[i].door_status = DOOR_STATUS_CLOSED; ad_descr[i].lock_status = LOCK_STATUS_LOCKED; ad_descr[i].secured_status = DOOR_SECURED_STATUS_SECURED; - ad_descr[i].door_pulse_time = 30; /* 3s */ + ad_descr[i].door_pulse_time = 30; /* 3s */ ad_descr[i].door_extended_pulse_time = 50; /* 5s */ - ad_descr[i].door_unlock_delay_time = 0; /* 0s */ + ad_descr[i].door_unlock_delay_time = 0; /* 0s */ ad_descr[i].door_open_too_long_time = 300; /* 30s */ ad_descr[i].door_alarm_state = DOOR_ALARM_STATE_NORMAL; for (j = 0; j < BACNET_MAX_PRIORITY; j++) { @@ -114,8 +107,9 @@ void Access_Door_Init(void) /* given instance exists */ bool Access_Door_Valid_Instance(uint32_t object_instance) { - if (object_instance < MAX_ACCESS_DOORS) + if (object_instance < MAX_ACCESS_DOORS) { return true; + } return false; } @@ -142,8 +136,9 @@ unsigned Access_Door_Instance_To_Index(uint32_t object_instance) { unsigned index = MAX_ACCESS_DOORS; - if (object_instance < MAX_ACCESS_DOORS) + if (object_instance < MAX_ACCESS_DOORS) { index = object_instance; + } return index; } @@ -169,8 +164,8 @@ BACNET_DOOR_VALUE Access_Door_Present_Value(uint32_t object_instance) unsigned Access_Door_Present_Value_Priority(uint32_t object_instance) { - unsigned index = 0; /* instance to index conversion */ - unsigned i = 0; /* loop counter */ + unsigned index = 0; /* instance to index conversion */ + unsigned i = 0; /* loop counter */ unsigned priority = 0; /* return value */ index = Access_Door_Instance_To_Index(object_instance); @@ -186,8 +181,8 @@ unsigned Access_Door_Present_Value_Priority(uint32_t object_instance) return priority; } -bool Access_Door_Present_Value_Set(uint32_t object_instance, - BACNET_DOOR_VALUE value, unsigned priority) +bool Access_Door_Present_Value_Set( + uint32_t object_instance, BACNET_DOOR_VALUE value, unsigned priority) { unsigned index = 0; bool status = false; @@ -212,8 +207,8 @@ bool Access_Door_Present_Value_Set(uint32_t object_instance, return status; } -bool Access_Door_Present_Value_Relinquish(uint32_t object_instance, - unsigned priority) +bool Access_Door_Present_Value_Relinquish( + uint32_t object_instance, unsigned priority) { unsigned index = 0; bool status = false; @@ -249,8 +244,8 @@ BACNET_DOOR_VALUE Access_Door_Relinquish_Default(uint32_t object_instance) } /* note: the object name must be unique within this device */ -bool Access_Door_Object_Name(uint32_t object_instance, - BACNET_CHARACTER_STRING *object_name) +bool Access_Door_Object_Name( + uint32_t object_instance, BACNET_CHARACTER_STRING *object_name) { static char text_string[32] = ""; /* okay for single thread */ bool status = false; @@ -345,24 +340,25 @@ int Access_Door_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) break; case PROP_PRIORITY_ARRAY: /* Array element zero is the number of elements in the array */ - if (rpdata->array_index == 0) + if (rpdata->array_index == 0) { apdu_len = encode_application_unsigned(&apdu[0], BACNET_MAX_PRIORITY); - /* if no index was specified, then try to encode the entire list */ - /* into one packet. */ - else if (rpdata->array_index == BACNET_ARRAY_ALL) { + /* if no index was specified, then try to encode the entire list + */ + /* into one packet. */ + } else if (rpdata->array_index == BACNET_ARRAY_ALL) { for (i = 0; i < BACNET_MAX_PRIORITY; i++) { /* FIXME: check if we have room before adding it to APDU */ - if (ad_descr[object_index].value_active[i]) + if (ad_descr[object_index].value_active[i]) { len = encode_application_null(&apdu[apdu_len]); - else - len = encode_application_enumerated( - &apdu[apdu_len], + } else { + len = encode_application_enumerated(&apdu[apdu_len], ad_descr[object_index].priority_array[i]); + } /* add it if we have room */ - if ((apdu_len + len) < MAX_APDU) + if ((apdu_len + len) < MAX_APDU) { apdu_len += len; - else { + } else { rpdata->error_code = ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED; apdu_len = BACNET_STATUS_ABORT; @@ -371,12 +367,12 @@ int Access_Door_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) } } else { if (rpdata->array_index <= BACNET_MAX_PRIORITY) { - if (ad_descr[object_index].value_active[i]) + if (ad_descr[object_index].value_active[i]) { apdu_len = encode_application_null(&apdu[0]); - else { - apdu_len = encode_application_enumerated( - &apdu[apdu_len], - ad_descr[object_index].priority_array[i]); + } else { + apdu_len = + encode_application_enumerated(&apdu[apdu_len], + ad_descr[object_index].priority_array[i]); } } else { rpdata->error_class = ERROR_CLASS_PROPERTY; @@ -386,8 +382,7 @@ int Access_Door_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) } break; case PROP_RELINQUISH_DEFAULT: - apdu_len = encode_application_enumerated( - &apdu[0], + apdu_len = encode_application_enumerated(&apdu[0], Access_Door_Relinquish_Default(rpdata->object_instance)); break; case PROP_DOOR_STATUS: @@ -448,8 +443,8 @@ bool Access_Door_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) unsigned object_index = 0; /* decode the some of the request */ - len = bacapp_decode_application_data(wp_data->application_data, - wp_data->application_data_len, &value); + len = bacapp_decode_application_data( + wp_data->application_data, wp_data->application_data_len, &value); /* FIXME: len < application_data_len: more data? */ if (len < 0) { /* error while decoding - a value larger than we can handle */ @@ -472,8 +467,7 @@ bool Access_Door_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) algorithm and may not be used for other purposes in any object. */ status = Access_Door_Present_Value_Set(wp_data->object_instance, - value.type.Enumerated, - wp_data->priority); + value.type.Enumerated, wp_data->priority); if (wp_data->priority == 6) { /* Command priority 6 is reserved for use by Minimum On/Off algorithm and may not be used for other purposes in any @@ -486,8 +480,7 @@ bool Access_Door_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) } } else { status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_NULL, - &wp_data->error_class, - &wp_data->error_code); + &wp_data->error_class, &wp_data->error_code); if (status) { status = Access_Door_Present_Value_Relinquish( wp_data->object_instance, wp_data->priority); @@ -499,19 +492,18 @@ bool Access_Door_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) } break; case PROP_OUT_OF_SERVICE: - status = - WPValidateArgType(&value, BACNET_APPLICATION_TAG_BOOLEAN, - &wp_data->error_class, &wp_data->error_code); + status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_BOOLEAN, + &wp_data->error_class, &wp_data->error_code); if (status) { - Access_Door_Out_Of_Service_Set(wp_data->object_instance, - value.type.Boolean); + Access_Door_Out_Of_Service_Set( + wp_data->object_instance, value.type.Boolean); } break; case PROP_DOOR_STATUS: if (Access_Door_Out_Of_Service(wp_data->object_instance)) { - status = WPValidateArgType( - &value, BACNET_APPLICATION_TAG_ENUMERATED, - &wp_data->error_class, &wp_data->error_code); + status = + WPValidateArgType(&value, BACNET_APPLICATION_TAG_ENUMERATED, + &wp_data->error_class, &wp_data->error_code); if (status) { ad_descr[object_index].door_status = value.type.Enumerated; } @@ -522,9 +514,9 @@ bool Access_Door_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) break; case PROP_LOCK_STATUS: if (Access_Door_Out_Of_Service(wp_data->object_instance)) { - status = WPValidateArgType( - &value, BACNET_APPLICATION_TAG_ENUMERATED, - &wp_data->error_class, &wp_data->error_code); + status = + WPValidateArgType(&value, BACNET_APPLICATION_TAG_ENUMERATED, + &wp_data->error_class, &wp_data->error_code); if (status) { ad_descr[object_index].lock_status = value.type.Enumerated; } @@ -535,9 +527,9 @@ bool Access_Door_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) break; case PROP_DOOR_ALARM_STATE: if (Access_Door_Out_Of_Service(wp_data->object_instance)) { - status = WPValidateArgType( - &value, BACNET_APPLICATION_TAG_ENUMERATED, - &wp_data->error_class, &wp_data->error_code); + status = + WPValidateArgType(&value, BACNET_APPLICATION_TAG_ENUMERATED, + &wp_data->error_class, &wp_data->error_code); if (status) { ad_descr[object_index].door_alarm_state = value.type.Enumerated; @@ -578,8 +570,9 @@ bool Access_Door_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) #include "ctest.h" bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue, - uint8_t ucExpectedTag, BACNET_ERROR_CLASS *pErrorClass, - BACNET_ERROR_CODE *pErrorCode) + uint8_t ucExpectedTag, + BACNET_ERROR_CLASS *pErrorClass, + BACNET_ERROR_CODE *pErrorCode) { pValue = pValue; ucExpectedTag = ucExpectedTag; @@ -591,7 +584,7 @@ bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue, void testAccessDoor(Test *pTest) { - uint8_t apdu[MAX_APDU] = {0}; + uint8_t apdu[MAX_APDU] = { 0 }; int len = 0; uint32_t len_value = 0; uint8_t tag_number = 0; diff --git a/demo/object/access_door.h b/src/bacnet/basic/object/access_door.h similarity index 97% rename from demo/object/access_door.h rename to src/bacnet/basic/object/access_door.h index 26d8111b..42b1e955 100644 --- a/demo/object/access_door.h +++ b/src/bacnet/basic/object/access_door.h @@ -27,10 +27,10 @@ #include #include -#include "bacdef.h" -#include "bacerror.h" -#include "rp.h" -#include "wp.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacerror.h" +#include "bacnet/rp.h" +#include "bacnet/wp.h" #ifndef MAX_ACCESS_DOORS diff --git a/demo/object/access_door.mak b/src/bacnet/basic/object/access_door.mak similarity index 62% rename from demo/object/access_door.mak rename to src/bacnet/basic/object/access_door.mak index 0643d3ed..eaf59450 100644 --- a/demo/object/access_door.mak +++ b/src/bacnet/basic/object/access_door.mak @@ -8,16 +8,16 @@ DEFINES = -DBIG_ENDIAN=0 -DTEST -DBACAPP_ALL -DTEST_ACCESS_DOOR CFLAGS = -Wall $(INCLUDES) $(DEFINES) -g SRCS = access_door.c \ - $(SRC_DIR)/bacdcode.c \ - $(SRC_DIR)/bacint.c \ - $(SRC_DIR)/bacstr.c \ - $(SRC_DIR)/bacreal.c \ - $(SRC_DIR)/datetime.c \ - $(SRC_DIR)/lighting.c \ - $(SRC_DIR)/bacapp.c \ - $(SRC_DIR)/bacdevobjpropref.c \ - $(SRC_DIR)/bactext.c \ - $(SRC_DIR)/indtext.c \ + $(SRC_DIR)/bacnet/bacdcode.c \ + $(SRC_DIR)/bacnet/bacint.c \ + $(SRC_DIR)/bacnet/bacstr.c \ + $(SRC_DIR)/bacnet/bacreal.c \ + $(SRC_DIR)/bacnet/datetime.c \ + $(SRC_DIR)/bacnet/lighting.c \ + $(SRC_DIR)/bacnet/bacapp.c \ + $(SRC_DIR)/bacnet/bacdevobjpropref.c \ + $(SRC_DIR)/bacnet/bactext.c \ + $(SRC_DIR)/bacnet/indtext.c \ $(TEST_DIR)/ctest.c TARGET = access_door diff --git a/demo/object/access_point.c b/src/bacnet/basic/object/access_point.c similarity index 87% rename from demo/object/access_point.c rename to src/bacnet/basic/object/access_point.c index c8f1102c..1925c22f 100644 --- a/demo/object/access_point.c +++ b/src/bacnet/basic/object/access_point.c @@ -28,53 +28,44 @@ #include #include #include -#include "bacdef.h" -#include "bacdcode.h" -#include "bacenum.h" -#include "bacapp.h" -#include "config.h" /* the custom stuff */ -#include "wp.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacenum.h" +#include "bacnet/bacapp.h" +#include "bacnet/config.h" /* the custom stuff */ +#include "bacnet/wp.h" #include "access_point.h" -#include "handlers.h" +#include "bacnet/basic/services.h" static bool Access_Point_Initialized = false; static ACCESS_POINT_DESCR ap_descr[MAX_ACCESS_POINTS]; /* These three arrays are used by the ReadPropertyMultiple handler */ -static const int Properties_Required[] = { - PROP_OBJECT_IDENTIFIER, - PROP_OBJECT_NAME, - PROP_OBJECT_TYPE, - PROP_STATUS_FLAGS, - PROP_EVENT_STATE, - PROP_RELIABILITY, - PROP_OUT_OF_SERVICE, - PROP_AUTHENTICATION_STATUS, - PROP_ACTIVE_AUTHENTICATION_POLICY, - PROP_NUMBER_OF_AUTHENTICATION_POLICIES, - PROP_AUTHORIZATION_MODE, - PROP_ACCESS_EVENT, - PROP_ACCESS_EVENT_TAG, - PROP_ACCESS_EVENT_TIME, - PROP_ACCESS_EVENT_CREDENTIAL, - PROP_ACCESS_DOORS, - PROP_PRIORITY_FOR_WRITING, - -1}; +static const int Properties_Required[] = { PROP_OBJECT_IDENTIFIER, + PROP_OBJECT_NAME, PROP_OBJECT_TYPE, PROP_STATUS_FLAGS, PROP_EVENT_STATE, + PROP_RELIABILITY, PROP_OUT_OF_SERVICE, PROP_AUTHENTICATION_STATUS, + PROP_ACTIVE_AUTHENTICATION_POLICY, PROP_NUMBER_OF_AUTHENTICATION_POLICIES, + PROP_AUTHORIZATION_MODE, PROP_ACCESS_EVENT, PROP_ACCESS_EVENT_TAG, + PROP_ACCESS_EVENT_TIME, PROP_ACCESS_EVENT_CREDENTIAL, PROP_ACCESS_DOORS, + PROP_PRIORITY_FOR_WRITING, -1 }; -static const int Properties_Optional[] = {-1}; +static const int Properties_Optional[] = { -1 }; -static const int Properties_Proprietary[] = {-1}; +static const int Properties_Proprietary[] = { -1 }; -void Access_Point_Property_Lists(const int **pRequired, const int **pOptional, - const int **pProprietary) +void Access_Point_Property_Lists( + const int **pRequired, const int **pOptional, const int **pProprietary) { - if (pRequired) + if (pRequired) { *pRequired = Properties_Required; - if (pOptional) + } + if (pOptional) { *pOptional = Properties_Optional; - if (pProprietary) + } + if (pProprietary) { *pProprietary = Properties_Proprietary; + } return; } @@ -111,8 +102,9 @@ void Access_Point_Init(void) /* given instance exists */ bool Access_Point_Valid_Instance(uint32_t object_instance) { - if (object_instance < MAX_ACCESS_POINTS) + if (object_instance < MAX_ACCESS_POINTS) { return true; + } return false; } @@ -139,22 +131,23 @@ unsigned Access_Point_Instance_To_Index(uint32_t object_instance) { unsigned index = MAX_ACCESS_POINTS; - if (object_instance < MAX_ACCESS_POINTS) + if (object_instance < MAX_ACCESS_POINTS) { index = object_instance; + } return index; } /* note: the object name must be unique within this device */ -bool Access_Point_Object_Name(uint32_t object_instance, - BACNET_CHARACTER_STRING *object_name) +bool Access_Point_Object_Name( + uint32_t object_instance, BACNET_CHARACTER_STRING *object_name) { static char text_string[32] = ""; /* okay for single thread */ bool status = false; if (object_instance < MAX_ACCESS_POINTS) { - sprintf(text_string, "ACCESS POINT %lu", - (unsigned long)object_instance); + sprintf( + text_string, "ACCESS POINT %lu", (unsigned long)object_instance); status = characterstring_init_ansi(object_name, text_string); } @@ -246,8 +239,7 @@ int Access_Point_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) &apdu[0], ap_descr[object_index].active_authentication_policy); break; case PROP_NUMBER_OF_AUTHENTICATION_POLICIES: - apdu_len = encode_application_unsigned( - &apdu[0], + apdu_len = encode_application_unsigned(&apdu[0], ap_descr[object_index].number_of_authentication_policies); break; case PROP_AUTHORIZATION_MODE: @@ -278,9 +270,9 @@ int Access_Point_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) for (i = 0; i < ap_descr[object_index].num_doors; i++) { len = bacapp_encode_device_obj_ref( &apdu[0], &ap_descr[object_index].access_doors[i]); - if (apdu_len + len < MAX_APDU) + if (apdu_len + len < MAX_APDU) { apdu_len += len; - else { + } else { rpdata->error_code = ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED; apdu_len = BACNET_STATUS_ABORT; @@ -289,9 +281,9 @@ int Access_Point_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) } } else { if (rpdata->array_index <= ap_descr[object_index].num_doors) { - apdu_len = bacapp_encode_device_obj_ref( - &apdu[0], &ap_descr[object_index] - .access_doors[rpdata->array_index - 1]); + apdu_len = bacapp_encode_device_obj_ref(&apdu[0], + &ap_descr[object_index] + .access_doors[rpdata->array_index - 1]); } else { rpdata->error_class = ERROR_CLASS_PROPERTY; rpdata->error_code = ERROR_CODE_INVALID_ARRAY_INDEX; @@ -324,8 +316,8 @@ bool Access_Point_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) BACNET_APPLICATION_DATA_VALUE value; /* decode the some of the request */ - len = bacapp_decode_application_data(wp_data->application_data, - wp_data->application_data_len, &value); + len = bacapp_decode_application_data( + wp_data->application_data, wp_data->application_data_len, &value); /* FIXME: len < application_data_len: more data? */ if (len < 0) { /* error while decoding - a value larger than we can handle */ @@ -377,8 +369,9 @@ bool Access_Point_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) #include "ctest.h" bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue, - uint8_t ucExpectedTag, BACNET_ERROR_CLASS *pErrorClass, - BACNET_ERROR_CODE *pErrorCode) + uint8_t ucExpectedTag, + BACNET_ERROR_CLASS *pErrorClass, + BACNET_ERROR_CODE *pErrorCode) { pValue = pValue; ucExpectedTag = ucExpectedTag; @@ -390,7 +383,7 @@ bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue, void testAccessPoint(Test *pTest) { - uint8_t apdu[MAX_APDU] = {0}; + uint8_t apdu[MAX_APDU] = { 0 }; int len = 0; uint32_t len_value = 0; uint8_t tag_number = 0; diff --git a/demo/object/access_point.h b/src/bacnet/basic/object/access_point.h similarity index 95% rename from demo/object/access_point.h rename to src/bacnet/basic/object/access_point.h index d9857108..99ff9e00 100644 --- a/demo/object/access_point.h +++ b/src/bacnet/basic/object/access_point.h @@ -27,12 +27,12 @@ #include #include -#include "bacdef.h" -#include "bacerror.h" -#include "timestamp.h" -#include "bacdevobjpropref.h" -#include "rp.h" -#include "wp.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacerror.h" +#include "bacnet/timestamp.h" +#include "bacnet/bacdevobjpropref.h" +#include "bacnet/rp.h" +#include "bacnet/wp.h" #ifndef MAX_ACCESS_POINTS diff --git a/demo/object/access_point.mak b/src/bacnet/basic/object/access_point.mak similarity index 60% rename from demo/object/access_point.mak rename to src/bacnet/basic/object/access_point.mak index aa285dc3..93f7de12 100644 --- a/demo/object/access_point.mak +++ b/src/bacnet/basic/object/access_point.mak @@ -8,17 +8,17 @@ DEFINES = -DBIG_ENDIAN=0 -DTEST -DBACAPP_ALL -DTEST_ACCESS_POINT CFLAGS = -Wall $(INCLUDES) $(DEFINES) -g SRCS = access_point.c \ - $(SRC_DIR)/bacdcode.c \ - $(SRC_DIR)/bacint.c \ - $(SRC_DIR)/bacstr.c \ - $(SRC_DIR)/bacreal.c \ - $(SRC_DIR)/datetime.c \ - $(SRC_DIR)/lighting.c \ - $(SRC_DIR)/bacapp.c \ - $(SRC_DIR)/bacdevobjpropref.c \ - $(SRC_DIR)/bactext.c \ - $(SRC_DIR)/indtext.c \ - $(SRC_DIR)/timestamp.c \ + $(SRC_DIR)/bacnet/bacdcode.c \ + $(SRC_DIR)/bacnet/bacint.c \ + $(SRC_DIR)/bacnet/bacstr.c \ + $(SRC_DIR)/bacnet/bacreal.c \ + $(SRC_DIR)/bacnet/datetime.c \ + $(SRC_DIR)/bacnet/lighting.c \ + $(SRC_DIR)/bacnet/bacapp.c \ + $(SRC_DIR)/bacnet/bacdevobjpropref.c \ + $(SRC_DIR)/bacnet/bactext.c \ + $(SRC_DIR)/bacnet/indtext.c \ + $(SRC_DIR)/bacnet/timestamp.c \ $(TEST_DIR)/ctest.c TARGET = access_point diff --git a/demo/object/access_rights.c b/src/bacnet/basic/object/access_rights.c similarity index 83% rename from demo/object/access_rights.c rename to src/bacnet/basic/object/access_rights.c index f2e82439..31aee68d 100644 --- a/demo/object/access_rights.c +++ b/src/bacnet/basic/object/access_rights.c @@ -28,44 +28,41 @@ #include #include #include -#include "bacdef.h" -#include "bacdcode.h" -#include "bacenum.h" -#include "bacapp.h" -#include "config.h" /* the custom stuff */ -#include "wp.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacenum.h" +#include "bacnet/bacapp.h" +#include "bacnet/config.h" /* the custom stuff */ +#include "bacnet/wp.h" #include "access_rights.h" -#include "handlers.h" +#include "bacnet/basic/services.h" static bool Access_Rights_Initialized = false; static ACCESS_RIGHTS_DESCR ar_descr[MAX_ACCESS_RIGHTSS]; /* These three arrays are used by the ReadPropertyMultiple handler */ -static const int Properties_Required[] = {PROP_OBJECT_IDENTIFIER, - PROP_OBJECT_NAME, - PROP_OBJECT_TYPE, - PROP_GLOBAL_IDENTIFIER, - PROP_STATUS_FLAGS, - PROP_RELIABILITY, - PROP_ENABLE, - PROP_NEGATIVE_ACCESS_RULES, - PROP_POSITIVE_ACCESS_RULES, - -1}; +static const int Properties_Required[] = { PROP_OBJECT_IDENTIFIER, + PROP_OBJECT_NAME, PROP_OBJECT_TYPE, PROP_GLOBAL_IDENTIFIER, + PROP_STATUS_FLAGS, PROP_RELIABILITY, PROP_ENABLE, + PROP_NEGATIVE_ACCESS_RULES, PROP_POSITIVE_ACCESS_RULES, -1 }; -static const int Properties_Optional[] = {-1}; +static const int Properties_Optional[] = { -1 }; -static const int Properties_Proprietary[] = {-1}; +static const int Properties_Proprietary[] = { -1 }; -void Access_Rights_Property_Lists(const int **pRequired, const int **pOptional, - const int **pProprietary) +void Access_Rights_Property_Lists( + const int **pRequired, const int **pOptional, const int **pProprietary) { - if (pRequired) + if (pRequired) { *pRequired = Properties_Required; - if (pOptional) + } + if (pOptional) { *pOptional = Properties_Optional; - if (pProprietary) + } + if (pProprietary) { *pProprietary = Properties_Proprietary; + } return; } @@ -96,8 +93,9 @@ void Access_Rights_Init(void) /* given instance exists */ bool Access_Rights_Valid_Instance(uint32_t object_instance) { - if (object_instance < MAX_ACCESS_RIGHTSS) + if (object_instance < MAX_ACCESS_RIGHTSS) { return true; + } return false; } @@ -124,22 +122,23 @@ unsigned Access_Rights_Instance_To_Index(uint32_t object_instance) { unsigned index = MAX_ACCESS_RIGHTSS; - if (object_instance < MAX_ACCESS_RIGHTSS) + if (object_instance < MAX_ACCESS_RIGHTSS) { index = object_instance; + } return index; } /* note: the object name must be unique within this device */ -bool Access_Rights_Object_Name(uint32_t object_instance, - BACNET_CHARACTER_STRING *object_name) +bool Access_Rights_Object_Name( + uint32_t object_instance, BACNET_CHARACTER_STRING *object_name) { static char text_string[32] = ""; /* okay for single thread */ bool status = false; if (object_instance < MAX_ACCESS_RIGHTSS) { - sprintf(text_string, "ACCESS RIGHTS %lu", - (unsigned long)object_instance); + sprintf( + text_string, "ACCESS RIGHTS %lu", (unsigned long)object_instance); status = characterstring_init_ansi(object_name, text_string); } @@ -199,19 +198,17 @@ int Access_Rights_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) break; case PROP_NEGATIVE_ACCESS_RULES: if (rpdata->array_index == 0) { - apdu_len = encode_application_unsigned( - &apdu[0], + apdu_len = encode_application_unsigned(&apdu[0], ar_descr[object_index].negative_access_rules_count); } else if (rpdata->array_index == BACNET_ARRAY_ALL) { for (i = 0; i < ar_descr[object_index].negative_access_rules_count; i++) { - len = bacapp_encode_access_rule( - &apdu[0], + len = bacapp_encode_access_rule(&apdu[0], &ar_descr[object_index].negative_access_rules[i]); - if (apdu_len + len < MAX_APDU) + if (apdu_len + len < MAX_APDU) { apdu_len += len; - else { + } else { rpdata->error_code = ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED; apdu_len = BACNET_STATUS_ABORT; @@ -221,8 +218,7 @@ int Access_Rights_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) } else { if (rpdata->array_index <= ar_descr[object_index].negative_access_rules_count) { - apdu_len = bacapp_encode_access_rule( - &apdu[0], + apdu_len = bacapp_encode_access_rule(&apdu[0], &ar_descr[object_index] .negative_access_rules[rpdata->array_index - 1]); } else { @@ -234,19 +230,17 @@ int Access_Rights_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) break; case PROP_POSITIVE_ACCESS_RULES: if (rpdata->array_index == 0) { - apdu_len = encode_application_unsigned( - &apdu[0], + apdu_len = encode_application_unsigned(&apdu[0], ar_descr[object_index].positive_access_rules_count); } else if (rpdata->array_index == BACNET_ARRAY_ALL) { for (i = 0; i < ar_descr[object_index].positive_access_rules_count; i++) { - len = bacapp_encode_access_rule( - &apdu[0], + len = bacapp_encode_access_rule(&apdu[0], &ar_descr[object_index].positive_access_rules[i]); - if (apdu_len + len < MAX_APDU) + if (apdu_len + len < MAX_APDU) { apdu_len += len; - else { + } else { rpdata->error_code = ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED; apdu_len = BACNET_STATUS_ABORT; @@ -256,8 +250,7 @@ int Access_Rights_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) } else { if (rpdata->array_index <= ar_descr[object_index].positive_access_rules_count) { - apdu_len = bacapp_encode_access_rule( - &apdu[0], + apdu_len = bacapp_encode_access_rule(&apdu[0], &ar_descr[object_index] .positive_access_rules[rpdata->array_index - 1]); } else { @@ -295,8 +288,8 @@ bool Access_Rights_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) unsigned object_index = 0; /* decode the some of the request */ - len = bacapp_decode_application_data(wp_data->application_data, - wp_data->application_data_len, &value); + len = bacapp_decode_application_data( + wp_data->application_data, wp_data->application_data_len, &value); /* FIXME: len < application_data_len: more data? */ if (len < 0) { /* error while decoding - a value larger than we can handle */ @@ -317,7 +310,7 @@ bool Access_Rights_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) case PROP_GLOBAL_IDENTIFIER: status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_UNSIGNED_INT, - &wp_data->error_class, &wp_data->error_code); + &wp_data->error_class, &wp_data->error_code); if (status) { ar_descr[object_index].global_identifier = value.type.Unsigned_Int; @@ -349,8 +342,9 @@ bool Access_Rights_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) #include "ctest.h" bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue, - uint8_t ucExpectedTag, BACNET_ERROR_CLASS *pErrorClass, - BACNET_ERROR_CODE *pErrorCode) + uint8_t ucExpectedTag, + BACNET_ERROR_CLASS *pErrorClass, + BACNET_ERROR_CODE *pErrorCode) { pValue = pValue; ucExpectedTag = ucExpectedTag; @@ -362,7 +356,7 @@ bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue, void testAccessRights(Test *pTest) { - uint8_t apdu[MAX_APDU] = {0}; + uint8_t apdu[MAX_APDU] = { 0 }; int len = 0; uint32_t len_value = 0; uint8_t tag_number = 0; diff --git a/demo/object/access_rights.h b/src/bacnet/basic/object/access_rights.h similarity index 95% rename from demo/object/access_rights.h rename to src/bacnet/basic/object/access_rights.h index a0b49c22..db1e8778 100644 --- a/demo/object/access_rights.h +++ b/src/bacnet/basic/object/access_rights.h @@ -27,12 +27,12 @@ #include #include -#include "bacdef.h" -#include "bacerror.h" -#include "bacdevobjpropref.h" -#include "access_rule.h" -#include "rp.h" -#include "wp.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacerror.h" +#include "bacnet/bacdevobjpropref.h" +#include "bacnet/access_rule.h" +#include "bacnet/rp.h" +#include "bacnet/wp.h" #ifndef MAX_ACCESS_RIGHTSS diff --git a/demo/object/access_rights.mak b/src/bacnet/basic/object/access_rights.mak similarity index 60% rename from demo/object/access_rights.mak rename to src/bacnet/basic/object/access_rights.mak index a0d37e0c..85ed1bfa 100644 --- a/demo/object/access_rights.mak +++ b/src/bacnet/basic/object/access_rights.mak @@ -8,17 +8,17 @@ DEFINES = -DBIG_ENDIAN=0 -DTEST -DBACAPP_ALL -DTEST_ACCESS_RIGHTS CFLAGS = -Wall $(INCLUDES) $(DEFINES) -g SRCS = access_rights.c \ - $(SRC_DIR)/access_rule.c \ - $(SRC_DIR)/bacdcode.c \ - $(SRC_DIR)/bacint.c \ - $(SRC_DIR)/bacstr.c \ - $(SRC_DIR)/bacreal.c \ - $(SRC_DIR)/datetime.c \ - $(SRC_DIR)/lighting.c \ - $(SRC_DIR)/bacapp.c \ - $(SRC_DIR)/bacdevobjpropref.c \ - $(SRC_DIR)/bactext.c \ - $(SRC_DIR)/indtext.c \ + $(SRC_DIR)/bacnet/access_rule.c \ + $(SRC_DIR)/bacnet/bacdcode.c \ + $(SRC_DIR)/bacnet/bacint.c \ + $(SRC_DIR)/bacnet/bacstr.c \ + $(SRC_DIR)/bacnet/bacreal.c \ + $(SRC_DIR)/bacnet/datetime.c \ + $(SRC_DIR)/bacnet/lighting.c \ + $(SRC_DIR)/bacnet/bacapp.c \ + $(SRC_DIR)/bacnet/bacdevobjpropref.c \ + $(SRC_DIR)/bacnet/bactext.c \ + $(SRC_DIR)/bacnet/indtext.c \ $(TEST_DIR)/ctest.c TARGET = access_rights diff --git a/demo/object/access_user.c b/src/bacnet/basic/object/access_user.c similarity index 88% rename from demo/object/access_user.c rename to src/bacnet/basic/object/access_user.c index b0f8012d..8d44b3bd 100644 --- a/demo/object/access_user.c +++ b/src/bacnet/basic/object/access_user.c @@ -28,38 +28,40 @@ #include #include #include -#include "bacdef.h" -#include "bacdcode.h" -#include "bacenum.h" -#include "bacapp.h" -#include "config.h" /* the custom stuff */ -#include "wp.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacenum.h" +#include "bacnet/bacapp.h" +#include "bacnet/config.h" /* the custom stuff */ +#include "bacnet/wp.h" #include "access_user.h" -#include "handlers.h" +#include "bacnet/basic/services.h" static bool Access_User_Initialized = false; static ACCESS_USER_DESCR au_descr[MAX_ACCESS_USERS]; /* These three arrays are used by the ReadPropertyMultiple handler */ -static const int Properties_Required[] = { - PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME, PROP_OBJECT_TYPE, - PROP_GLOBAL_IDENTIFIER, PROP_STATUS_FLAGS, PROP_RELIABILITY, - PROP_USER_TYPE, PROP_CREDENTIALS, -1}; +static const int Properties_Required[] = { PROP_OBJECT_IDENTIFIER, + PROP_OBJECT_NAME, PROP_OBJECT_TYPE, PROP_GLOBAL_IDENTIFIER, + PROP_STATUS_FLAGS, PROP_RELIABILITY, PROP_USER_TYPE, PROP_CREDENTIALS, -1 }; -static const int Properties_Optional[] = {-1}; +static const int Properties_Optional[] = { -1 }; -static const int Properties_Proprietary[] = {-1}; +static const int Properties_Proprietary[] = { -1 }; -void Access_User_Property_Lists(const int **pRequired, const int **pOptional, - const int **pProprietary) +void Access_User_Property_Lists( + const int **pRequired, const int **pOptional, const int **pProprietary) { - if (pRequired) + if (pRequired) { *pRequired = Properties_Required; - if (pOptional) + } + if (pOptional) { *pOptional = Properties_Optional; - if (pProprietary) + } + if (pProprietary) { *pProprietary = Properties_Proprietary; + } return; } @@ -89,8 +91,9 @@ void Access_User_Init(void) /* given instance exists */ bool Access_User_Valid_Instance(uint32_t object_instance) { - if (object_instance < MAX_ACCESS_USERS) + if (object_instance < MAX_ACCESS_USERS) { return true; + } return false; } @@ -117,15 +120,16 @@ unsigned Access_User_Instance_To_Index(uint32_t object_instance) { unsigned index = MAX_ACCESS_USERS; - if (object_instance < MAX_ACCESS_USERS) + if (object_instance < MAX_ACCESS_USERS) { index = object_instance; + } return index; } /* note: the object name must be unique within this device */ -bool Access_User_Object_Name(uint32_t object_instance, - BACNET_CHARACTER_STRING *object_name) +bool Access_User_Object_Name( + uint32_t object_instance, BACNET_CHARACTER_STRING *object_name) { static char text_string[32] = ""; /* okay for single thread */ bool status = false; @@ -193,9 +197,9 @@ int Access_User_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) for (i = 0; i < au_descr[object_index].credentials_count; i++) { len = bacapp_encode_device_obj_ref( &apdu[0], &au_descr[object_index].credentials[i]); - if (apdu_len + len < MAX_APDU) + if (apdu_len + len < MAX_APDU) { apdu_len += len; - else { + } else { rpdata->error_code = ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED; apdu_len = BACNET_STATUS_ABORT; @@ -228,8 +232,8 @@ bool Access_User_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) unsigned object_index = 0; /* decode the some of the request */ - len = bacapp_decode_application_data(wp_data->application_data, - wp_data->application_data_len, &value); + len = bacapp_decode_application_data( + wp_data->application_data, wp_data->application_data_len, &value); /* FIXME: len < application_data_len: more data? */ if (len < 0) { /* error while decoding - a value larger than we can handle */ @@ -248,7 +252,7 @@ bool Access_User_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) case PROP_GLOBAL_IDENTIFIER: status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_UNSIGNED_INT, - &wp_data->error_class, &wp_data->error_code); + &wp_data->error_class, &wp_data->error_code); if (status) { au_descr[object_index].global_identifier = value.type.Unsigned_Int; @@ -280,8 +284,9 @@ bool Access_User_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) #include "ctest.h" bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue, - uint8_t ucExpectedTag, BACNET_ERROR_CLASS *pErrorClass, - BACNET_ERROR_CODE *pErrorCode) + uint8_t ucExpectedTag, + BACNET_ERROR_CLASS *pErrorClass, + BACNET_ERROR_CODE *pErrorCode) { pValue = pValue; ucExpectedTag = ucExpectedTag; @@ -293,7 +298,7 @@ bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue, void testAccessUser(Test *pTest) { - uint8_t apdu[MAX_APDU] = {0}; + uint8_t apdu[MAX_APDU] = { 0 }; int len = 0; uint32_t len_value = 0; uint8_t tag_number = 0; diff --git a/demo/object/access_user.h b/src/bacnet/basic/object/access_user.h similarity index 95% rename from demo/object/access_user.h rename to src/bacnet/basic/object/access_user.h index 3338b8b5..0f50ea81 100644 --- a/demo/object/access_user.h +++ b/src/bacnet/basic/object/access_user.h @@ -27,11 +27,11 @@ #include #include -#include "bacdef.h" -#include "bacerror.h" -#include "bacdevobjpropref.h" -#include "rp.h" -#include "wp.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacerror.h" +#include "bacnet/bacdevobjpropref.h" +#include "bacnet/rp.h" +#include "bacnet/wp.h" #ifndef MAX_ACCESS_USERS diff --git a/demo/object/access_user.mak b/src/bacnet/basic/object/access_user.mak similarity index 62% rename from demo/object/access_user.mak rename to src/bacnet/basic/object/access_user.mak index 9b0f7c27..2864f6f5 100644 --- a/demo/object/access_user.mak +++ b/src/bacnet/basic/object/access_user.mak @@ -8,16 +8,16 @@ DEFINES = -DBIG_ENDIAN=0 -DTEST -DBACAPP_ALL -DTEST_ACCESS_USER CFLAGS = -Wall $(INCLUDES) $(DEFINES) -g SRCS = access_user.c \ - $(SRC_DIR)/bacdcode.c \ - $(SRC_DIR)/bacint.c \ - $(SRC_DIR)/bacstr.c \ - $(SRC_DIR)/bacreal.c \ - $(SRC_DIR)/datetime.c \ - $(SRC_DIR)/lighting.c \ - $(SRC_DIR)/bacapp.c \ - $(SRC_DIR)/bacdevobjpropref.c \ - $(SRC_DIR)/bactext.c \ - $(SRC_DIR)/indtext.c \ + $(SRC_DIR)/bacnet/bacdcode.c \ + $(SRC_DIR)/bacnet/bacint.c \ + $(SRC_DIR)/bacnet/bacstr.c \ + $(SRC_DIR)/bacnet/bacreal.c \ + $(SRC_DIR)/bacnet/datetime.c \ + $(SRC_DIR)/bacnet/lighting.c \ + $(SRC_DIR)/bacnet/bacapp.c \ + $(SRC_DIR)/bacnet/bacdevobjpropref.c \ + $(SRC_DIR)/bacnet/bactext.c \ + $(SRC_DIR)/bacnet/indtext.c \ $(TEST_DIR)/ctest.c TARGET = access_user diff --git a/demo/object/access_zone.c b/src/bacnet/basic/object/access_zone.c similarity index 88% rename from demo/object/access_zone.c rename to src/bacnet/basic/object/access_zone.c index 6a4ab832..701087f4 100644 --- a/demo/object/access_zone.c +++ b/src/bacnet/basic/object/access_zone.c @@ -28,39 +28,41 @@ #include #include #include -#include "bacdef.h" -#include "bacdcode.h" -#include "bacenum.h" -#include "bacapp.h" -#include "config.h" /* the custom stuff */ -#include "wp.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacenum.h" +#include "bacnet/bacapp.h" +#include "bacnet/config.h" /* the custom stuff */ +#include "bacnet/wp.h" #include "access_zone.h" -#include "handlers.h" +#include "bacnet/basic/services.h" static bool Access_Zone_Initialized = false; static ACCESS_ZONE_DESCR az_descr[MAX_ACCESS_ZONES]; /* These three arrays are used by the ReadPropertyMultiple handler */ -static const int Properties_Required[] = { - PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME, PROP_OBJECT_TYPE, - PROP_GLOBAL_IDENTIFIER, PROP_OCCUPANCY_STATE, PROP_STATUS_FLAGS, - PROP_EVENT_STATE, PROP_RELIABILITY, PROP_OUT_OF_SERVICE, - PROP_ENTRY_POINTS, PROP_EXIT_POINTS, -1}; +static const int Properties_Required[] = { PROP_OBJECT_IDENTIFIER, + PROP_OBJECT_NAME, PROP_OBJECT_TYPE, PROP_GLOBAL_IDENTIFIER, + PROP_OCCUPANCY_STATE, PROP_STATUS_FLAGS, PROP_EVENT_STATE, PROP_RELIABILITY, + PROP_OUT_OF_SERVICE, PROP_ENTRY_POINTS, PROP_EXIT_POINTS, -1 }; -static const int Properties_Optional[] = {-1}; +static const int Properties_Optional[] = { -1 }; -static const int Properties_Proprietary[] = {-1}; +static const int Properties_Proprietary[] = { -1 }; -void Access_Zone_Property_Lists(const int **pRequired, const int **pOptional, - const int **pProprietary) +void Access_Zone_Property_Lists( + const int **pRequired, const int **pOptional, const int **pProprietary) { - if (pRequired) + if (pRequired) { *pRequired = Properties_Required; - if (pOptional) + } + if (pOptional) { *pOptional = Properties_Optional; - if (pProprietary) + } + if (pProprietary) { *pProprietary = Properties_Proprietary; + } return; } @@ -93,8 +95,9 @@ void Access_Zone_Init(void) /* given instance exists */ bool Access_Zone_Valid_Instance(uint32_t object_instance) { - if (object_instance < MAX_ACCESS_ZONES) + if (object_instance < MAX_ACCESS_ZONES) { return true; + } return false; } @@ -121,15 +124,16 @@ unsigned Access_Zone_Instance_To_Index(uint32_t object_instance) { unsigned index = MAX_ACCESS_ZONES; - if (object_instance < MAX_ACCESS_ZONES) + if (object_instance < MAX_ACCESS_ZONES) { index = object_instance; + } return index; } /* note: the object name must be unique within this device */ -bool Access_Zone_Object_Name(uint32_t object_instance, - BACNET_CHARACTER_STRING *object_name) +bool Access_Zone_Object_Name( + uint32_t object_instance, BACNET_CHARACTER_STRING *object_name) { static char text_string[32] = ""; /* okay for single thread */ bool status = false; @@ -230,9 +234,9 @@ int Access_Zone_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) for (i = 0; i < az_descr[object_index].entry_points_count; i++) { len = bacapp_encode_device_obj_ref( &apdu[0], &az_descr[object_index].entry_points[i]); - if (apdu_len + len < MAX_APDU) + if (apdu_len + len < MAX_APDU) { apdu_len += len; - else { + } else { rpdata->error_code = ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED; apdu_len = BACNET_STATUS_ABORT; @@ -244,9 +248,9 @@ int Access_Zone_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) for (i = 0; i < az_descr[object_index].exit_points_count; i++) { len = bacapp_encode_device_obj_ref( &apdu[0], &az_descr[object_index].exit_points[i]); - if (apdu_len + len < MAX_APDU) + if (apdu_len + len < MAX_APDU) { apdu_len += len; - else { + } else { rpdata->error_code = ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED; apdu_len = BACNET_STATUS_ABORT; @@ -279,8 +283,8 @@ bool Access_Zone_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) unsigned object_index = 0; /* decode the some of the request */ - len = bacapp_decode_application_data(wp_data->application_data, - wp_data->application_data_len, &value); + len = bacapp_decode_application_data( + wp_data->application_data, wp_data->application_data_len, &value); /* FIXME: len < application_data_len: more data? */ if (len < 0) { /* error while decoding - a value larger than we can handle */ @@ -299,7 +303,7 @@ bool Access_Zone_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) case PROP_GLOBAL_IDENTIFIER: status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_UNSIGNED_INT, - &wp_data->error_class, &wp_data->error_code); + &wp_data->error_class, &wp_data->error_code); if (status) { az_descr[object_index].global_identifier = value.type.Unsigned_Int; @@ -307,9 +311,9 @@ bool Access_Zone_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) break; case PROP_RELIABILITY: if (Access_Zone_Out_Of_Service(wp_data->object_instance)) { - status = WPValidateArgType( - &value, BACNET_APPLICATION_TAG_ENUMERATED, - &wp_data->error_class, &wp_data->error_code); + status = + WPValidateArgType(&value, BACNET_APPLICATION_TAG_ENUMERATED, + &wp_data->error_class, &wp_data->error_code); if (status) { az_descr[object_index].reliability = value.type.Enumerated; } @@ -345,8 +349,9 @@ bool Access_Zone_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) #include "ctest.h" bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue, - uint8_t ucExpectedTag, BACNET_ERROR_CLASS *pErrorClass, - BACNET_ERROR_CODE *pErrorCode) + uint8_t ucExpectedTag, + BACNET_ERROR_CLASS *pErrorClass, + BACNET_ERROR_CODE *pErrorCode) { pValue = pValue; ucExpectedTag = ucExpectedTag; @@ -358,7 +363,7 @@ bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue, void testAccessZone(Test *pTest) { - uint8_t apdu[MAX_APDU] = {0}; + uint8_t apdu[MAX_APDU] = { 0 }; int len = 0; uint32_t len_value = 0; uint8_t tag_number = 0; diff --git a/demo/object/access_zone.h b/src/bacnet/basic/object/access_zone.h similarity index 96% rename from demo/object/access_zone.h rename to src/bacnet/basic/object/access_zone.h index cd72fbff..063e1885 100644 --- a/demo/object/access_zone.h +++ b/src/bacnet/basic/object/access_zone.h @@ -27,11 +27,11 @@ #include #include -#include "bacdef.h" -#include "bacerror.h" -#include "bacdevobjpropref.h" -#include "rp.h" -#include "wp.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacerror.h" +#include "bacnet/bacdevobjpropref.h" +#include "bacnet/rp.h" +#include "bacnet/wp.h" #ifndef MAX_ACCESS_ZONES diff --git a/demo/object/access_zone.mak b/src/bacnet/basic/object/access_zone.mak similarity index 62% rename from demo/object/access_zone.mak rename to src/bacnet/basic/object/access_zone.mak index e280b30d..a99a01bb 100644 --- a/demo/object/access_zone.mak +++ b/src/bacnet/basic/object/access_zone.mak @@ -8,16 +8,16 @@ DEFINES = -DBIG_ENDIAN=0 -DTEST -DBACAPP_ALL -DTEST_ACCESS_ZONE CFLAGS = -Wall $(INCLUDES) $(DEFINES) -g SRCS = access_zone.c \ - $(SRC_DIR)/bacdcode.c \ - $(SRC_DIR)/bacint.c \ - $(SRC_DIR)/bacstr.c \ - $(SRC_DIR)/bacreal.c \ - $(SRC_DIR)/datetime.c \ - $(SRC_DIR)/lighting.c \ - $(SRC_DIR)/bacapp.c \ - $(SRC_DIR)/bacdevobjpropref.c \ - $(SRC_DIR)/bactext.c \ - $(SRC_DIR)/indtext.c \ + $(SRC_DIR)/bacnet/bacdcode.c \ + $(SRC_DIR)/bacnet/bacint.c \ + $(SRC_DIR)/bacnet/bacstr.c \ + $(SRC_DIR)/bacnet/bacreal.c \ + $(SRC_DIR)/bacnet/datetime.c \ + $(SRC_DIR)/bacnet/lighting.c \ + $(SRC_DIR)/bacnet/bacapp.c \ + $(SRC_DIR)/bacnet/bacdevobjpropref.c \ + $(SRC_DIR)/bacnet/bactext.c \ + $(SRC_DIR)/bacnet/indtext.c \ $(TEST_DIR)/ctest.c TARGET = access_zone diff --git a/demo/object/ai.c b/src/bacnet/basic/object/ai.c similarity index 83% rename from demo/object/ai.c rename to src/bacnet/basic/object/ai.c index 15059743..5b444bf1 100644 --- a/demo/object/ai.c +++ b/src/bacnet/basic/object/ai.c @@ -30,16 +30,16 @@ #include #include -#include "bacdef.h" -#include "bacdcode.h" -#include "bacenum.h" -#include "bactext.h" -#include "config.h" /* the custom stuff */ -#include "device.h" -#include "handlers.h" -#include "proplist.h" -#include "timestamp.h" -#include "ai.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacenum.h" +#include "bacnet/bactext.h" +#include "bacnet/config.h" /* the custom stuff */ +#include "bacnet/basic/object/device.h" +#include "bacnet/basic/services.h" +#include "bacnet/proplist.h" +#include "bacnet/timestamp.h" +#include "bacnet/basic/object/ai.h" #ifndef MAX_ANALOG_INPUTS #define MAX_ANALOG_INPUTS 4 @@ -48,39 +48,33 @@ ANALOG_INPUT_DESCR AI_Descr[MAX_ANALOG_INPUTS]; /* These three arrays are used by the ReadPropertyMultiple handler */ -static const int Properties_Required[] = { - PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME, PROP_OBJECT_TYPE, - PROP_PRESENT_VALUE, PROP_STATUS_FLAGS, PROP_EVENT_STATE, - PROP_OUT_OF_SERVICE, PROP_UNITS, -1}; +static const int Properties_Required[] = { PROP_OBJECT_IDENTIFIER, + PROP_OBJECT_NAME, PROP_OBJECT_TYPE, PROP_PRESENT_VALUE, PROP_STATUS_FLAGS, + PROP_EVENT_STATE, PROP_OUT_OF_SERVICE, PROP_UNITS, -1 }; -static const int Properties_Optional[] = {PROP_DESCRIPTION, - PROP_RELIABILITY, - PROP_COV_INCREMENT, +static const int Properties_Optional[] = { PROP_DESCRIPTION, PROP_RELIABILITY, + PROP_COV_INCREMENT, #if defined(INTRINSIC_REPORTING) - PROP_TIME_DELAY, - PROP_NOTIFICATION_CLASS, - PROP_HIGH_LIMIT, - PROP_LOW_LIMIT, - PROP_DEADBAND, - PROP_LIMIT_ENABLE, - PROP_EVENT_ENABLE, - PROP_ACKED_TRANSITIONS, - PROP_NOTIFY_TYPE, - PROP_EVENT_TIME_STAMPS, + PROP_TIME_DELAY, PROP_NOTIFICATION_CLASS, PROP_HIGH_LIMIT, PROP_LOW_LIMIT, + PROP_DEADBAND, PROP_LIMIT_ENABLE, PROP_EVENT_ENABLE, PROP_ACKED_TRANSITIONS, + PROP_NOTIFY_TYPE, PROP_EVENT_TIME_STAMPS, #endif - -1}; + -1 }; -static const int Properties_Proprietary[] = {9997, 9998, 9999, -1}; +static const int Properties_Proprietary[] = { 9997, 9998, 9999, -1 }; -void Analog_Input_Property_Lists(const int **pRequired, const int **pOptional, - const int **pProprietary) +void Analog_Input_Property_Lists( + const int **pRequired, const int **pOptional, const int **pProprietary) { - if (pRequired) + if (pRequired) { *pRequired = Properties_Required; - if (pOptional) + } + if (pOptional) { *pOptional = Properties_Optional; - if (pProprietary) + } + if (pProprietary) { *pProprietary = Properties_Proprietary; + } return; } @@ -112,13 +106,13 @@ void Analog_Input_Init(void) } /* Set handler for GetEventInformation function */ - handler_get_event_information_set(OBJECT_ANALOG_INPUT, - Analog_Input_Event_Information); + handler_get_event_information_set( + OBJECT_ANALOG_INPUT, Analog_Input_Event_Information); /* Set handler for AcknowledgeAlarm function */ handler_alarm_ack_set(OBJECT_ANALOG_INPUT, Analog_Input_Alarm_Ack); /* Set handler for GetAlarmSummary Service */ - handler_get_alarm_summary_set(OBJECT_ANALOG_INPUT, - Analog_Input_Alarm_Summary); + handler_get_alarm_summary_set( + OBJECT_ANALOG_INPUT, Analog_Input_Alarm_Summary); #endif } } @@ -131,8 +125,9 @@ bool Analog_Input_Valid_Instance(uint32_t object_instance) unsigned int index; index = Analog_Input_Instance_To_Index(object_instance); - if (index < MAX_ANALOG_INPUTS) + if (index < MAX_ANALOG_INPUTS) { return true; + } return false; } @@ -159,8 +154,9 @@ unsigned Analog_Input_Instance_To_Index(uint32_t object_instance) { unsigned index = MAX_ANALOG_INPUTS; - if (object_instance < MAX_ANALOG_INPUTS) + if (object_instance < MAX_ANALOG_INPUTS) { index = object_instance; + } return index; } @@ -210,8 +206,8 @@ void Analog_Input_Present_Value_Set(uint32_t object_instance, float value) } } -bool Analog_Input_Object_Name(uint32_t object_instance, - BACNET_CHARACTER_STRING *object_name) +bool Analog_Input_Object_Name( + uint32_t object_instance, BACNET_CHARACTER_STRING *object_name) { static char text_string[32] = ""; /* okay for single thread */ unsigned int index; @@ -257,8 +253,8 @@ void Analog_Input_Change_Of_Value_Clear(uint32_t object_instance) * * @return true if the value list is encoded */ -bool Analog_Input_Encode_Value_List(uint32_t object_instance, - BACNET_PROPERTY_VALUE *value_list) +bool Analog_Input_Encode_Value_List( + uint32_t object_instance, BACNET_PROPERTY_VALUE *value_list) { bool status = false; @@ -279,18 +275,18 @@ bool Analog_Input_Encode_Value_List(uint32_t object_instance, value_list->value.context_specific = false; value_list->value.tag = BACNET_APPLICATION_TAG_BIT_STRING; bitstring_init(&value_list->value.type.Bit_String); - bitstring_set_bit(&value_list->value.type.Bit_String, - STATUS_FLAG_IN_ALARM, false); - bitstring_set_bit(&value_list->value.type.Bit_String, STATUS_FLAG_FAULT, - false); - bitstring_set_bit(&value_list->value.type.Bit_String, - STATUS_FLAG_OVERRIDDEN, false); + bitstring_set_bit( + &value_list->value.type.Bit_String, STATUS_FLAG_IN_ALARM, false); + bitstring_set_bit( + &value_list->value.type.Bit_String, STATUS_FLAG_FAULT, false); + bitstring_set_bit( + &value_list->value.type.Bit_String, STATUS_FLAG_OVERRIDDEN, false); if (Analog_Input_Out_Of_Service(object_instance)) { bitstring_set_bit(&value_list->value.type.Bit_String, - STATUS_FLAG_OUT_OF_SERVICE, true); + STATUS_FLAG_OUT_OF_SERVICE, true); } else { bitstring_set_bit(&value_list->value.type.Bit_String, - STATUS_FLAG_OUT_OF_SERVICE, false); + STATUS_FLAG_OUT_OF_SERVICE, false); } value_list->value.next = NULL; value_list->priority = BACNET_NO_PRIORITY; @@ -380,10 +376,11 @@ int Analog_Input_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) } object_index = Analog_Input_Instance_To_Index(rpdata->object_instance); - if (object_index < MAX_ANALOG_INPUTS) + if (object_index < MAX_ANALOG_INPUTS) { CurrentAI = &AI_Descr[object_index]; - else + } else { return BACNET_STATUS_ERROR; + } apdu = rpdata->application_data; switch ((int)rpdata->object_property) { @@ -413,14 +410,14 @@ int Analog_Input_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) bitstring_init(&bit_string); #if defined(INTRINSIC_REPORTING) bitstring_set_bit(&bit_string, STATUS_FLAG_IN_ALARM, - CurrentAI->Event_State ? true : false); + CurrentAI->Event_State ? true : false); #else bitstring_set_bit(&bit_string, STATUS_FLAG_IN_ALARM, false); #endif bitstring_set_bit(&bit_string, STATUS_FLAG_FAULT, false); bitstring_set_bit(&bit_string, STATUS_FLAG_OVERRIDDEN, false); bitstring_set_bit(&bit_string, STATUS_FLAG_OUT_OF_SERVICE, - CurrentAI->Out_Of_Service); + CurrentAI->Out_Of_Service); apdu_len = encode_application_bitstring(&apdu[0], &bit_string); break; @@ -481,11 +478,9 @@ int Analog_Input_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) case PROP_LIMIT_ENABLE: bitstring_init(&bit_string); bitstring_set_bit(&bit_string, 0, - (CurrentAI->Limit_Enable & EVENT_LOW_LIMIT_ENABLE) - ? true - : false); - bitstring_set_bit( - &bit_string, 1, + (CurrentAI->Limit_Enable & EVENT_LOW_LIMIT_ENABLE) ? true + : false); + bitstring_set_bit(&bit_string, 1, (CurrentAI->Limit_Enable & EVENT_HIGH_LIMIT_ENABLE) ? true : false); @@ -494,32 +489,26 @@ int Analog_Input_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) case PROP_EVENT_ENABLE: bitstring_init(&bit_string); - bitstring_set_bit( - &bit_string, TRANSITION_TO_OFFNORMAL, + bitstring_set_bit(&bit_string, TRANSITION_TO_OFFNORMAL, (CurrentAI->Event_Enable & EVENT_ENABLE_TO_OFFNORMAL) ? true : false); bitstring_set_bit(&bit_string, TRANSITION_TO_FAULT, - (CurrentAI->Event_Enable & EVENT_ENABLE_TO_FAULT) - ? true - : false); + (CurrentAI->Event_Enable & EVENT_ENABLE_TO_FAULT) ? true + : false); bitstring_set_bit(&bit_string, TRANSITION_TO_NORMAL, - (CurrentAI->Event_Enable & EVENT_ENABLE_TO_NORMAL) - ? true - : false); + (CurrentAI->Event_Enable & EVENT_ENABLE_TO_NORMAL) ? true + : false); apdu_len = encode_application_bitstring(&apdu[0], &bit_string); break; case PROP_ACKED_TRANSITIONS: bitstring_init(&bit_string); - bitstring_set_bit( - &bit_string, TRANSITION_TO_OFFNORMAL, + bitstring_set_bit(&bit_string, TRANSITION_TO_OFFNORMAL, CurrentAI->Acked_Transitions[TRANSITION_TO_OFFNORMAL].bIsAcked); - bitstring_set_bit( - &bit_string, TRANSITION_TO_FAULT, + bitstring_set_bit(&bit_string, TRANSITION_TO_FAULT, CurrentAI->Acked_Transitions[TRANSITION_TO_FAULT].bIsAcked); - bitstring_set_bit( - &bit_string, TRANSITION_TO_NORMAL, + bitstring_set_bit(&bit_string, TRANSITION_TO_NORMAL, CurrentAI->Acked_Transitions[TRANSITION_TO_NORMAL].bIsAcked); apdu_len = encode_application_bitstring(&apdu[0], &bit_string); @@ -539,16 +528,14 @@ int Analog_Input_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) /* into one packet. */ else if (rpdata->array_index == BACNET_ARRAY_ALL) { for (i = 0; i < MAX_BACNET_EVENT_TRANSITION; i++) { - len = encode_opening_tag(&apdu[apdu_len], - TIME_STAMP_DATETIME); - len += encode_application_date( - &apdu[apdu_len + len], + len = encode_opening_tag( + &apdu[apdu_len], TIME_STAMP_DATETIME); + len += encode_application_date(&apdu[apdu_len + len], &CurrentAI->Event_Time_Stamps[i].date); - len += encode_application_time( - &apdu[apdu_len + len], + len += encode_application_time(&apdu[apdu_len + len], &CurrentAI->Event_Time_Stamps[i].time); - len += encode_closing_tag(&apdu[apdu_len + len], - TIME_STAMP_DATETIME); + len += encode_closing_tag( + &apdu[apdu_len + len], TIME_STAMP_DATETIME); /* add it if we have room */ if ((apdu_len + len) < MAX_APDU) @@ -563,11 +550,9 @@ int Analog_Input_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) } else if (rpdata->array_index <= MAX_BACNET_EVENT_TRANSITION) { apdu_len = encode_opening_tag(&apdu[apdu_len], TIME_STAMP_DATETIME); - apdu_len += encode_application_date( - &apdu[apdu_len], + apdu_len += encode_application_date(&apdu[apdu_len], &CurrentAI->Event_Time_Stamps[rpdata->array_index].date); - apdu_len += encode_application_time( - &apdu[apdu_len], + apdu_len += encode_application_time(&apdu[apdu_len], &CurrentAI->Event_Time_Stamps[rpdata->array_index].time); apdu_len += encode_closing_tag(&apdu[apdu_len], TIME_STAMP_DATETIME); @@ -620,8 +605,8 @@ bool Analog_Input_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) ANALOG_INPUT_DESCR *CurrentAI; /* decode the some of the request */ - len = bacapp_decode_application_data(wp_data->application_data, - wp_data->application_data_len, &value); + len = bacapp_decode_application_data( + wp_data->application_data, wp_data->application_data_len, &value); /* FIXME: len < application_data_len: more data? */ if (len < 0) { /* error while decoding - a value larger than we can handle */ @@ -645,14 +630,13 @@ bool Analog_Input_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) switch ((int)wp_data->object_property) { case PROP_PRESENT_VALUE: - status = - WPValidateArgType(&value, BACNET_APPLICATION_TAG_REAL, - &wp_data->error_class, &wp_data->error_code); + status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_REAL, + &wp_data->error_class, &wp_data->error_code); if (status) { if (CurrentAI->Out_Of_Service == true) { - Analog_Input_Present_Value_Set(wp_data->object_instance, - value.type.Real); + Analog_Input_Present_Value_Set( + wp_data->object_instance, value.type.Real); } else { wp_data->error_class = ERROR_CLASS_PROPERTY; wp_data->error_code = ERROR_CODE_WRITE_ACCESS_DENIED; @@ -662,32 +646,30 @@ bool Analog_Input_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) break; case PROP_OUT_OF_SERVICE: - status = - WPValidateArgType(&value, BACNET_APPLICATION_TAG_BOOLEAN, - &wp_data->error_class, &wp_data->error_code); + status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_BOOLEAN, + &wp_data->error_class, &wp_data->error_code); if (status) { - Analog_Input_Out_Of_Service_Set(wp_data->object_instance, - value.type.Boolean); + Analog_Input_Out_Of_Service_Set( + wp_data->object_instance, value.type.Boolean); } break; case PROP_UNITS: status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_ENUMERATED, - &wp_data->error_class, &wp_data->error_code); + &wp_data->error_class, &wp_data->error_code); if (status) { CurrentAI->Units = value.type.Enumerated; } break; case PROP_COV_INCREMENT: - status = - WPValidateArgType(&value, BACNET_APPLICATION_TAG_REAL, - &wp_data->error_class, &wp_data->error_code); + status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_REAL, + &wp_data->error_class, &wp_data->error_code); if (status) { if (value.type.Real >= 0.0) { - Analog_Input_COV_Increment_Set(wp_data->object_instance, - value.type.Real); + Analog_Input_COV_Increment_Set( + wp_data->object_instance, value.type.Real); } else { status = false; wp_data->error_class = ERROR_CLASS_PROPERTY; @@ -700,7 +682,7 @@ bool Analog_Input_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) case PROP_TIME_DELAY: status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_UNSIGNED_INT, - &wp_data->error_class, &wp_data->error_code); + &wp_data->error_class, &wp_data->error_code); if (status) { CurrentAI->Time_Delay = value.type.Unsigned_Int; @@ -711,7 +693,7 @@ bool Analog_Input_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) case PROP_NOTIFICATION_CLASS: status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_UNSIGNED_INT, - &wp_data->error_class, &wp_data->error_code); + &wp_data->error_class, &wp_data->error_code); if (status) { CurrentAI->Notification_Class = value.type.Unsigned_Int; @@ -719,9 +701,8 @@ bool Analog_Input_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) break; case PROP_HIGH_LIMIT: - status = - WPValidateArgType(&value, BACNET_APPLICATION_TAG_REAL, - &wp_data->error_class, &wp_data->error_code); + status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_REAL, + &wp_data->error_class, &wp_data->error_code); if (status) { CurrentAI->High_Limit = value.type.Real; @@ -729,9 +710,8 @@ bool Analog_Input_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) break; case PROP_LOW_LIMIT: - status = - WPValidateArgType(&value, BACNET_APPLICATION_TAG_REAL, - &wp_data->error_class, &wp_data->error_code); + status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_REAL, + &wp_data->error_class, &wp_data->error_code); if (status) { CurrentAI->Low_Limit = value.type.Real; @@ -739,9 +719,8 @@ bool Analog_Input_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) break; case PROP_DEADBAND: - status = - WPValidateArgType(&value, BACNET_APPLICATION_TAG_REAL, - &wp_data->error_class, &wp_data->error_code); + status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_REAL, + &wp_data->error_class, &wp_data->error_code); if (status) { CurrentAI->Deadband = value.type.Real; @@ -751,7 +730,7 @@ bool Analog_Input_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) case PROP_LIMIT_ENABLE: status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_BIT_STRING, - &wp_data->error_class, &wp_data->error_code); + &wp_data->error_class, &wp_data->error_code); if (status) { if (value.type.Bit_String.bits_used == 2) { @@ -767,7 +746,7 @@ bool Analog_Input_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) case PROP_EVENT_ENABLE: status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_BIT_STRING, - &wp_data->error_class, &wp_data->error_code); + &wp_data->error_class, &wp_data->error_code); if (status) { if (value.type.Bit_String.bits_used == 3) { @@ -783,7 +762,7 @@ bool Analog_Input_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) case PROP_NOTIFY_TYPE: status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_ENUMERATED, - &wp_data->error_class, &wp_data->error_code); + &wp_data->error_class, &wp_data->error_code); if (status) { switch ((BACNET_NOTIFY_TYPE)value.type.Enumerated) { @@ -859,7 +838,7 @@ void Analog_Input_Intrinsic_Reporting(uint32_t object_instance) #if PRINT_ENABLED fprintf(stderr, "Send Acknotification for (%s,%d).\n", - bactext_object_type_name(OBJECT_ANALOG_INPUT), object_instance); + bactext_object_type_name(OBJECT_ANALOG_INPUT), object_instance); #endif /* PRINT_ENABLED */ characterstring_init_ansi(&msgText, "AckNotification"); @@ -884,9 +863,9 @@ void Analog_Input_Intrinsic_Reporting(uint32_t object_instance) property. */ if ((PresentVal > CurrentAI->High_Limit) && ((CurrentAI->Limit_Enable & EVENT_HIGH_LIMIT_ENABLE) == - EVENT_HIGH_LIMIT_ENABLE) && + EVENT_HIGH_LIMIT_ENABLE) && ((CurrentAI->Event_Enable & EVENT_ENABLE_TO_OFFNORMAL) == - EVENT_ENABLE_TO_OFFNORMAL)) { + EVENT_ENABLE_TO_OFFNORMAL)) { if (!CurrentAI->Remaining_Time_Delay) CurrentAI->Event_State = EVENT_STATE_HIGH_LIMIT; else @@ -903,9 +882,9 @@ void Analog_Input_Intrinsic_Reporting(uint32_t object_instance) property. */ if ((PresentVal < CurrentAI->Low_Limit) && ((CurrentAI->Limit_Enable & EVENT_LOW_LIMIT_ENABLE) == - EVENT_LOW_LIMIT_ENABLE) && + EVENT_LOW_LIMIT_ENABLE) && ((CurrentAI->Event_Enable & EVENT_ENABLE_TO_OFFNORMAL) == - EVENT_ENABLE_TO_OFFNORMAL)) { + EVENT_ENABLE_TO_OFFNORMAL)) { if (!CurrentAI->Remaining_Time_Delay) CurrentAI->Event_State = EVENT_STATE_LOW_LIMIT; else @@ -926,11 +905,11 @@ void Analog_Input_Intrinsic_Reporting(uint32_t object_instance) property, and (c) the TO-NORMAL flag must be set in the Event_Enable property. */ if ((PresentVal < - CurrentAI->High_Limit - CurrentAI->Deadband) && + CurrentAI->High_Limit - CurrentAI->Deadband) && ((CurrentAI->Limit_Enable & EVENT_HIGH_LIMIT_ENABLE) == - EVENT_HIGH_LIMIT_ENABLE) && + EVENT_HIGH_LIMIT_ENABLE) && ((CurrentAI->Event_Enable & EVENT_ENABLE_TO_NORMAL) == - EVENT_ENABLE_TO_NORMAL)) { + EVENT_ENABLE_TO_NORMAL)) { if (!CurrentAI->Remaining_Time_Delay) CurrentAI->Event_State = EVENT_STATE_NORMAL; else @@ -953,9 +932,9 @@ void Analog_Input_Intrinsic_Reporting(uint32_t object_instance) property. */ if ((PresentVal > CurrentAI->Low_Limit + CurrentAI->Deadband) && ((CurrentAI->Limit_Enable & EVENT_LOW_LIMIT_ENABLE) == - EVENT_LOW_LIMIT_ENABLE) && + EVENT_LOW_LIMIT_ENABLE) && ((CurrentAI->Event_Enable & EVENT_ENABLE_TO_NORMAL) == - EVENT_ENABLE_TO_NORMAL)) { + EVENT_ENABLE_TO_NORMAL)) { if (!CurrentAI->Remaining_Time_Delay) CurrentAI->Event_State = EVENT_STATE_NORMAL; else @@ -968,7 +947,7 @@ void Analog_Input_Intrinsic_Reporting(uint32_t object_instance) default: return; /* shouldn't happen */ - } /* switch (FromState) */ + } /* switch (FromState) */ ToState = CurrentAI->Event_State; @@ -1007,9 +986,9 @@ void Analog_Input_Intrinsic_Reporting(uint32_t object_instance) #if PRINT_ENABLED fprintf(stderr, "Event_State for (%s,%d) goes from %s to %s.\n", - bactext_object_type_name(OBJECT_ANALOG_INPUT), - object_instance, bactext_event_state_name(FromState), - bactext_event_state_name(ToState)); + bactext_object_type_name(OBJECT_ANALOG_INPUT), object_instance, + bactext_event_state_name(FromState), + bactext_event_state_name(ToState)); #endif /* PRINT_ENABLED */ /* Notify Type */ @@ -1149,12 +1128,12 @@ int Analog_Input_Event_Information( (TO-OFFNORMAL, TO-FAULT, TONORMAL) set to FALSE. */ IsNotAckedTransitions = (AI_Descr[index] - .Acked_Transitions[TRANSITION_TO_OFFNORMAL] - .bIsAcked == false) | + .Acked_Transitions[TRANSITION_TO_OFFNORMAL] + .bIsAcked == false) | (AI_Descr[index].Acked_Transitions[TRANSITION_TO_FAULT].bIsAcked == - false) | + false) | (AI_Descr[index].Acked_Transitions[TRANSITION_TO_NORMAL].bIsAcked == - false); + false); } else return -1; /* end of list */ @@ -1168,15 +1147,15 @@ int Analog_Input_Event_Information( /* Acknowledged Transitions */ bitstring_init(&getevent_data->acknowledgedTransitions); bitstring_set_bit(&getevent_data->acknowledgedTransitions, - TRANSITION_TO_OFFNORMAL, - AI_Descr[index] - .Acked_Transitions[TRANSITION_TO_OFFNORMAL] - .bIsAcked); - bitstring_set_bit( - &getevent_data->acknowledgedTransitions, TRANSITION_TO_FAULT, + TRANSITION_TO_OFFNORMAL, + AI_Descr[index] + .Acked_Transitions[TRANSITION_TO_OFFNORMAL] + .bIsAcked); + bitstring_set_bit(&getevent_data->acknowledgedTransitions, + TRANSITION_TO_FAULT, AI_Descr[index].Acked_Transitions[TRANSITION_TO_FAULT].bIsAcked); - bitstring_set_bit( - &getevent_data->acknowledgedTransitions, TRANSITION_TO_NORMAL, + bitstring_set_bit(&getevent_data->acknowledgedTransitions, + TRANSITION_TO_NORMAL, AI_Descr[index].Acked_Transitions[TRANSITION_TO_NORMAL].bIsAcked); /* Event Time Stamps */ for (i = 0; i < 3; i++) { @@ -1188,29 +1167,26 @@ int Analog_Input_Event_Information( getevent_data->notifyType = AI_Descr[index].Notify_Type; /* Event Enable */ bitstring_init(&getevent_data->eventEnable); - bitstring_set_bit( - &getevent_data->eventEnable, TRANSITION_TO_OFFNORMAL, + bitstring_set_bit(&getevent_data->eventEnable, TRANSITION_TO_OFFNORMAL, (AI_Descr[index].Event_Enable & EVENT_ENABLE_TO_OFFNORMAL) ? true : false); bitstring_set_bit(&getevent_data->eventEnable, TRANSITION_TO_FAULT, - (AI_Descr[index].Event_Enable & EVENT_ENABLE_TO_FAULT) - ? true - : false); - bitstring_set_bit( - &getevent_data->eventEnable, TRANSITION_TO_NORMAL, + (AI_Descr[index].Event_Enable & EVENT_ENABLE_TO_FAULT) ? true + : false); + bitstring_set_bit(&getevent_data->eventEnable, TRANSITION_TO_NORMAL, (AI_Descr[index].Event_Enable & EVENT_ENABLE_TO_NORMAL) ? true : false); /* Event Priorities */ - Notification_Class_Get_Priorities(AI_Descr[index].Notification_Class, - getevent_data->eventPriorities); + Notification_Class_Get_Priorities( + AI_Descr[index].Notification_Class, getevent_data->eventPriorities); return 1; /* active event */ } else return 0; /* no active event at this index */ } -int Analog_Input_Alarm_Ack(BACNET_ALARM_ACK_DATA *alarmack_data, - BACNET_ERROR_CODE *error_code) +int Analog_Input_Alarm_Ack( + BACNET_ALARM_ACK_DATA *alarmack_data, BACNET_ERROR_CODE *error_code) { ANALOG_INPUT_DESCR *CurrentAI; unsigned int object_index; @@ -1309,8 +1285,8 @@ int Analog_Input_Alarm_Ack(BACNET_ALARM_ACK_DATA *alarmack_data, return 1; } -int Analog_Input_Alarm_Summary(unsigned index, - BACNET_GET_ALARM_SUMMARY_DATA *getalarm_data) +int Analog_Input_Alarm_Summary( + unsigned index, BACNET_GET_ALARM_SUMMARY_DATA *getalarm_data) { /* check index */ if (index < MAX_ANALOG_INPUTS) { @@ -1327,20 +1303,20 @@ int Analog_Input_Alarm_Summary(unsigned index, /* Acknowledged Transitions */ bitstring_init(&getalarm_data->acknowledgedTransitions); bitstring_set_bit(&getalarm_data->acknowledgedTransitions, - TRANSITION_TO_OFFNORMAL, - AI_Descr[index] - .Acked_Transitions[TRANSITION_TO_OFFNORMAL] - .bIsAcked); + TRANSITION_TO_OFFNORMAL, + AI_Descr[index] + .Acked_Transitions[TRANSITION_TO_OFFNORMAL] + .bIsAcked); bitstring_set_bit(&getalarm_data->acknowledgedTransitions, - TRANSITION_TO_FAULT, - AI_Descr[index] - .Acked_Transitions[TRANSITION_TO_FAULT] - .bIsAcked); + TRANSITION_TO_FAULT, + AI_Descr[index] + .Acked_Transitions[TRANSITION_TO_FAULT] + .bIsAcked); bitstring_set_bit(&getalarm_data->acknowledgedTransitions, - TRANSITION_TO_NORMAL, - AI_Descr[index] - .Acked_Transitions[TRANSITION_TO_NORMAL] - .bIsAcked); + TRANSITION_TO_NORMAL, + AI_Descr[index] + .Acked_Transitions[TRANSITION_TO_NORMAL] + .bIsAcked); return 1; /* active alarm */ } else @@ -1356,8 +1332,9 @@ int Analog_Input_Alarm_Summary(unsigned index, #include "ctest.h" bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue, - uint8_t ucExpectedTag, BACNET_ERROR_CLASS *pErrorClass, - BACNET_ERROR_CODE *pErrorCode) + uint8_t ucExpectedTag, + BACNET_ERROR_CLASS *pErrorClass, + BACNET_ERROR_CODE *pErrorCode) { bool bResult; @@ -1377,7 +1354,7 @@ bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue, void testAnalogInput(Test *pTest) { - uint8_t apdu[MAX_APDU] = {0}; + uint8_t apdu[MAX_APDU] = { 0 }; int len = 0; uint32_t len_value = 0; uint8_t tag_number = 0; diff --git a/demo/object/ai.h b/src/bacnet/basic/object/ai.h similarity index 96% rename from demo/object/ai.h rename to src/bacnet/basic/object/ai.h index 1ed75c92..511312d8 100644 --- a/demo/object/ai.h +++ b/src/bacnet/basic/object/ai.h @@ -28,14 +28,14 @@ #include #include -#include "bacdef.h" -#include "rp.h" -#include "wp.h" +#include "bacnet/bacdef.h" +#include "bacnet/rp.h" +#include "bacnet/wp.h" #if defined(INTRINSIC_REPORTING) -#include "nc.h" -#include "getevent.h" -#include "alarm_ack.h" -#include "get_alarm_sum.h" +#include "bacnet/basic/object/nc.h" +#include "bacnet/getevent.h" +#include "bacnet/alarm_ack.h" +#include "bacnet/get_alarm_sum.h" #endif #ifdef __cplusplus diff --git a/demo/object/ai.mak b/src/bacnet/basic/object/ai.mak old mode 100755 new mode 100644 similarity index 64% rename from demo/object/ai.mak rename to src/bacnet/basic/object/ai.mak index 613d001a..7f15b7a2 --- a/demo/object/ai.mak +++ b/src/bacnet/basic/object/ai.mak @@ -9,16 +9,16 @@ DEFINES = -DBIG_ENDIAN=0 -DBACDL_ALL -DTEST -DTEST_ANALOG_INPUT CFLAGS = -Wall $(INCLUDES) $(DEFINES) -g SRCS = ai.c \ - $(SRC_DIR)/bacdcode.c \ - $(SRC_DIR)/bacint.c \ - $(SRC_DIR)/bacstr.c \ - $(SRC_DIR)/bacreal.c \ - $(SRC_DIR)/bacapp.c \ - $(SRC_DIR)/bacdevobjpropref.c \ - $(SRC_DIR)/bactext.c \ - $(SRC_DIR)/indtext.c \ - $(SRC_DIR)/datetime.c \ - $(SRC_DIR)/lighting.c \ + $(SRC_DIR)/bacnet/bacdcode.c \ + $(SRC_DIR)/bacnet/bacint.c \ + $(SRC_DIR)/bacnet/bacstr.c \ + $(SRC_DIR)/bacnet/bacreal.c \ + $(SRC_DIR)/bacnet/bacapp.c \ + $(SRC_DIR)/bacnet/bacdevobjpropref.c \ + $(SRC_DIR)/bacnet/bactext.c \ + $(SRC_DIR)/bacnet/indtext.c \ + $(SRC_DIR)/bacnet/datetime.c \ + $(SRC_DIR)/bacnet/lighting.c \ $(TEST_DIR)/ctest.c TARGET = analog_input diff --git a/demo/object/ao.c b/src/bacnet/basic/object/ao.c similarity index 83% rename from demo/object/ao.c rename to src/bacnet/basic/object/ao.c index f377fe77..0dd94a90 100644 --- a/demo/object/ao.c +++ b/src/bacnet/basic/object/ao.c @@ -28,14 +28,14 @@ #include #include #include -#include "bacdef.h" -#include "bacdcode.h" -#include "bacenum.h" -#include "bacapp.h" -#include "config.h" /* the custom stuff */ -#include "wp.h" -#include "ao.h" -#include "handlers.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacenum.h" +#include "bacnet/bacapp.h" +#include "bacnet/config.h" /* the custom stuff */ +#include "bacnet/wp.h" +#include "bacnet/basic/object/ao.h" +#include "bacnet/basic/services.h" #ifndef MAX_ANALOG_OUTPUTS #define MAX_ANALOG_OUTPUTS 4 @@ -60,31 +60,27 @@ static bool Out_Of_Service[MAX_ANALOG_OUTPUTS]; static bool Analog_Output_Initialized = false; /* These three arrays are used by the ReadPropertyMultiple handler */ -static const int Properties_Required[] = {PROP_OBJECT_IDENTIFIER, - PROP_OBJECT_NAME, - PROP_OBJECT_TYPE, - PROP_PRESENT_VALUE, - PROP_STATUS_FLAGS, - PROP_EVENT_STATE, - PROP_OUT_OF_SERVICE, - PROP_UNITS, - PROP_PRIORITY_ARRAY, - PROP_RELINQUISH_DEFAULT, - -1}; +static const int Properties_Required[] = { PROP_OBJECT_IDENTIFIER, + PROP_OBJECT_NAME, PROP_OBJECT_TYPE, PROP_PRESENT_VALUE, PROP_STATUS_FLAGS, + PROP_EVENT_STATE, PROP_OUT_OF_SERVICE, PROP_UNITS, PROP_PRIORITY_ARRAY, + PROP_RELINQUISH_DEFAULT, -1 }; -static const int Properties_Optional[] = {-1}; +static const int Properties_Optional[] = { -1 }; -static const int Properties_Proprietary[] = {-1}; +static const int Properties_Proprietary[] = { -1 }; -void Analog_Output_Property_Lists(const int **pRequired, const int **pOptional, - const int **pProprietary) +void Analog_Output_Property_Lists( + const int **pRequired, const int **pOptional, const int **pProprietary) { - if (pRequired) + if (pRequired) { *pRequired = Properties_Required; - if (pOptional) + } + if (pOptional) { *pOptional = Properties_Optional; - if (pProprietary) + } + if (pProprietary) { *pProprietary = Properties_Proprietary; + } return; } @@ -112,8 +108,9 @@ void Analog_Output_Init(void) /* given instance exists */ bool Analog_Output_Valid_Instance(uint32_t object_instance) { - if (object_instance < MAX_ANALOG_OUTPUTS) + if (object_instance < MAX_ANALOG_OUTPUTS) { return true; + } return false; } @@ -140,8 +137,9 @@ unsigned Analog_Output_Instance_To_Index(uint32_t object_instance) { unsigned index = MAX_ANALOG_OUTPUTS; - if (object_instance < MAX_ANALOG_OUTPUTS) + if (object_instance < MAX_ANALOG_OUTPUTS) { index = object_instance; + } return index; } @@ -167,8 +165,8 @@ float Analog_Output_Present_Value(uint32_t object_instance) unsigned Analog_Output_Present_Value_Priority(uint32_t object_instance) { - unsigned index = 0; /* instance to index conversion */ - unsigned i = 0; /* loop counter */ + unsigned index = 0; /* instance to index conversion */ + unsigned i = 0; /* loop counter */ unsigned priority = 0; /* return value */ index = Analog_Output_Instance_To_Index(object_instance); @@ -184,8 +182,8 @@ unsigned Analog_Output_Present_Value_Priority(uint32_t object_instance) return priority; } -bool Analog_Output_Present_Value_Set(uint32_t object_instance, float value, - unsigned priority) +bool Analog_Output_Present_Value_Set( + uint32_t object_instance, float value, unsigned priority) { unsigned index = 0; bool status = false; @@ -209,8 +207,8 @@ bool Analog_Output_Present_Value_Set(uint32_t object_instance, float value, return status; } -bool Analog_Output_Present_Value_Relinquish(uint32_t object_instance, - unsigned priority) +bool Analog_Output_Present_Value_Relinquish( + uint32_t object_instance, unsigned priority) { unsigned index = 0; bool status = false; @@ -234,15 +232,15 @@ bool Analog_Output_Present_Value_Relinquish(uint32_t object_instance, } /* note: the object name must be unique within this device */ -bool Analog_Output_Object_Name(uint32_t object_instance, - BACNET_CHARACTER_STRING *object_name) +bool Analog_Output_Object_Name( + uint32_t object_instance, BACNET_CHARACTER_STRING *object_name) { static char text_string[32] = ""; /* okay for single thread */ bool status = false; if (object_instance < MAX_ANALOG_OUTPUTS) { - sprintf(text_string, "ANALOG OUTPUT %lu", - (unsigned long)object_instance); + sprintf( + text_string, "ANALOG OUTPUT %lu", (unsigned long)object_instance); status = characterstring_init_ansi(object_name, text_string); } @@ -330,27 +328,28 @@ int Analog_Output_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) break; case PROP_PRIORITY_ARRAY: /* Array element zero is the number of elements in the array */ - if (rpdata->array_index == 0) + if (rpdata->array_index == 0) { apdu_len = encode_application_unsigned(&apdu[0], BACNET_MAX_PRIORITY); - /* if no index was specified, then try to encode the entire list */ - /* into one packet. */ - else if (rpdata->array_index == BACNET_ARRAY_ALL) { + /* if no index was specified, then try to encode the entire list + */ + /* into one packet. */ + } else if (rpdata->array_index == BACNET_ARRAY_ALL) { object_index = Analog_Output_Instance_To_Index(rpdata->object_instance); for (i = 0; i < BACNET_MAX_PRIORITY; i++) { /* FIXME: check if we have room before adding it to APDU */ - if (Analog_Output_Level[object_index][i] == AO_LEVEL_NULL) + if (Analog_Output_Level[object_index][i] == AO_LEVEL_NULL) { len = encode_application_null(&apdu[apdu_len]); - else { + } else { real_value = Analog_Output_Level[object_index][i]; - len = encode_application_real(&apdu[apdu_len], - real_value); + len = encode_application_real( + &apdu[apdu_len], real_value); } /* add it if we have room */ - if ((apdu_len + len) < MAX_APDU) + if ((apdu_len + len) < MAX_APDU) { apdu_len += len; - else { + } else { rpdata->error_code = ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED; apdu_len = BACNET_STATUS_ABORT; @@ -362,9 +361,9 @@ int Analog_Output_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) Analog_Output_Instance_To_Index(rpdata->object_instance); if (rpdata->array_index <= BACNET_MAX_PRIORITY) { if (Analog_Output_Level[object_index][rpdata->array_index - - 1] == AO_LEVEL_NULL) + 1] == AO_LEVEL_NULL) { apdu_len = encode_application_null(&apdu[0]); - else { + } else { real_value = Analog_Output_Level[object_index] [rpdata->array_index - 1]; @@ -407,8 +406,8 @@ bool Analog_Output_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) BACNET_APPLICATION_DATA_VALUE value; /* decode the some of the request */ - len = bacapp_decode_application_data(wp_data->application_data, - wp_data->application_data_len, &value); + len = bacapp_decode_application_data( + wp_data->application_data, wp_data->application_data_len, &value); /* FIXME: len < application_data_len: more data? */ if (len < 0) { /* error while decoding - a value larger than we can handle */ @@ -429,9 +428,9 @@ bool Analog_Output_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) /* Command priority 6 is reserved for use by Minimum On/Off algorithm and may not be used for other purposes in any object. */ - status = Analog_Output_Present_Value_Set( - wp_data->object_instance, value.type.Real, - wp_data->priority); + status = + Analog_Output_Present_Value_Set(wp_data->object_instance, + value.type.Real, wp_data->priority); if (wp_data->priority == 6) { /* Command priority 6 is reserved for use by Minimum On/Off algorithm and may not be used for other purposes in any @@ -444,8 +443,7 @@ bool Analog_Output_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) } } else { status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_NULL, - &wp_data->error_class, - &wp_data->error_code); + &wp_data->error_class, &wp_data->error_code); if (status) { status = Analog_Output_Present_Value_Relinquish( wp_data->object_instance, wp_data->priority); @@ -457,12 +455,11 @@ bool Analog_Output_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) } break; case PROP_OUT_OF_SERVICE: - status = - WPValidateArgType(&value, BACNET_APPLICATION_TAG_BOOLEAN, - &wp_data->error_class, &wp_data->error_code); + status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_BOOLEAN, + &wp_data->error_class, &wp_data->error_code); if (status) { - Analog_Output_Out_Of_Service_Set(wp_data->object_instance, - value.type.Boolean); + Analog_Output_Out_Of_Service_Set( + wp_data->object_instance, value.type.Boolean); } break; case PROP_OBJECT_IDENTIFIER: @@ -491,8 +488,9 @@ bool Analog_Output_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) #include "ctest.h" bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue, - uint8_t ucExpectedTag, BACNET_ERROR_CLASS *pErrorClass, - BACNET_ERROR_CODE *pErrorCode) + uint8_t ucExpectedTag, + BACNET_ERROR_CLASS *pErrorClass, + BACNET_ERROR_CODE *pErrorCode) { bool bResult; @@ -512,7 +510,7 @@ bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue, void testAnalogOutput(Test *pTest) { - uint8_t apdu[MAX_APDU] = {0}; + uint8_t apdu[MAX_APDU] = { 0 }; int len = 0; uint32_t len_value = 0; uint8_t tag_number = 0; diff --git a/demo/object/ao.h b/src/bacnet/basic/object/ao.h similarity index 97% rename from demo/object/ao.h rename to src/bacnet/basic/object/ao.h index faf09496..4982facd 100644 --- a/demo/object/ao.h +++ b/src/bacnet/basic/object/ao.h @@ -27,10 +27,10 @@ #include #include -#include "bacdef.h" -#include "bacerror.h" -#include "rp.h" -#include "wp.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacerror.h" +#include "bacnet/rp.h" +#include "bacnet/wp.h" #ifdef __cplusplus extern "C" { diff --git a/demo/object/ao.mak b/src/bacnet/basic/object/ao.mak old mode 100755 new mode 100644 similarity index 62% rename from demo/object/ao.mak rename to src/bacnet/basic/object/ao.mak index b0a79a4e..f75731e4 --- a/demo/object/ao.mak +++ b/src/bacnet/basic/object/ao.mak @@ -8,16 +8,16 @@ DEFINES = -DBIG_ENDIAN=0 -DTEST -DBACAPP_ALL -DTEST_ANALOG_OUTPUT CFLAGS = -Wall $(INCLUDES) $(DEFINES) -g SRCS = ao.c \ - $(SRC_DIR)/bacdcode.c \ - $(SRC_DIR)/bacint.c \ - $(SRC_DIR)/bacstr.c \ - $(SRC_DIR)/bacreal.c \ - $(SRC_DIR)/datetime.c \ - $(SRC_DIR)/lighting.c \ - $(SRC_DIR)/bacapp.c \ - $(SRC_DIR)/bacdevobjpropref.c \ - $(SRC_DIR)/bactext.c \ - $(SRC_DIR)/indtext.c \ + $(SRC_DIR)/bacnet/bacdcode.c \ + $(SRC_DIR)/bacnet/bacint.c \ + $(SRC_DIR)/bacnet/bacstr.c \ + $(SRC_DIR)/bacnet/bacreal.c \ + $(SRC_DIR)/bacnet/datetime.c \ + $(SRC_DIR)/bacnet/lighting.c \ + $(SRC_DIR)/bacnet/bacapp.c \ + $(SRC_DIR)/bacnet/bacdevobjpropref.c \ + $(SRC_DIR)/bacnet/bactext.c \ + $(SRC_DIR)/bacnet/indtext.c \ $(TEST_DIR)/ctest.c TARGET = analog_output diff --git a/demo/object/av.c b/src/bacnet/basic/object/av.c similarity index 82% rename from demo/object/av.c rename to src/bacnet/basic/object/av.c index 091b12b9..fc1fbd19 100644 --- a/demo/object/av.c +++ b/src/bacnet/basic/object/av.c @@ -31,15 +31,15 @@ #include #include -#include "bacdef.h" -#include "bacdcode.h" -#include "bacenum.h" -#include "bacapp.h" -#include "bactext.h" -#include "config.h" /* the custom stuff */ -#include "device.h" -#include "handlers.h" -#include "av.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacenum.h" +#include "bacnet/bacapp.h" +#include "bacnet/bactext.h" +#include "bacnet/config.h" /* the custom stuff */ +#include "bacnet/basic/object/device.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/object/av.h" #ifndef MAX_ANALOG_VALUES #define MAX_ANALOG_VALUES 4 @@ -48,38 +48,33 @@ ANALOG_VALUE_DESCR AV_Descr[MAX_ANALOG_VALUES]; /* These three arrays are used by the ReadPropertyMultiple handler */ -static const int Analog_Value_Properties_Required[] = { - PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME, PROP_OBJECT_TYPE, - PROP_PRESENT_VALUE, PROP_STATUS_FLAGS, PROP_EVENT_STATE, - PROP_OUT_OF_SERVICE, PROP_UNITS, -1}; +static const int Analog_Value_Properties_Required[] = { PROP_OBJECT_IDENTIFIER, + PROP_OBJECT_NAME, PROP_OBJECT_TYPE, PROP_PRESENT_VALUE, PROP_STATUS_FLAGS, + PROP_EVENT_STATE, PROP_OUT_OF_SERVICE, PROP_UNITS, -1 }; -static const int Analog_Value_Properties_Optional[] = {PROP_DESCRIPTION, - PROP_COV_INCREMENT, +static const int Analog_Value_Properties_Optional[] = { PROP_DESCRIPTION, + PROP_COV_INCREMENT, #if defined(INTRINSIC_REPORTING) - PROP_TIME_DELAY, - PROP_NOTIFICATION_CLASS, - PROP_HIGH_LIMIT, - PROP_LOW_LIMIT, - PROP_DEADBAND, - PROP_LIMIT_ENABLE, - PROP_EVENT_ENABLE, - PROP_ACKED_TRANSITIONS, - PROP_NOTIFY_TYPE, - PROP_EVENT_TIME_STAMPS, + PROP_TIME_DELAY, PROP_NOTIFICATION_CLASS, PROP_HIGH_LIMIT, PROP_LOW_LIMIT, + PROP_DEADBAND, PROP_LIMIT_ENABLE, PROP_EVENT_ENABLE, PROP_ACKED_TRANSITIONS, + PROP_NOTIFY_TYPE, PROP_EVENT_TIME_STAMPS, #endif - -1}; + -1 }; -static const int Analog_Value_Properties_Proprietary[] = {-1}; +static const int Analog_Value_Properties_Proprietary[] = { -1 }; -void Analog_Value_Property_Lists(const int **pRequired, const int **pOptional, - const int **pProprietary) +void Analog_Value_Property_Lists( + const int **pRequired, const int **pOptional, const int **pProprietary) { - if (pRequired) + if (pRequired) { *pRequired = Analog_Value_Properties_Required; - if (pOptional) + } + if (pOptional) { *pOptional = Analog_Value_Properties_Optional; - if (pProprietary) + } + if (pProprietary) { *pProprietary = Analog_Value_Properties_Proprietary; + } return; } @@ -110,13 +105,13 @@ void Analog_Value_Init(void) } /* Set handler for GetEventInformation function */ - handler_get_event_information_set(OBJECT_ANALOG_VALUE, - Analog_Value_Event_Information); + handler_get_event_information_set( + OBJECT_ANALOG_VALUE, Analog_Value_Event_Information); /* Set handler for AcknowledgeAlarm function */ handler_alarm_ack_set(OBJECT_ANALOG_VALUE, Analog_Value_Alarm_Ack); /* Set handler for GetAlarmSummary Service */ - handler_get_alarm_summary_set(OBJECT_ANALOG_VALUE, - Analog_Value_Alarm_Summary); + handler_get_alarm_summary_set( + OBJECT_ANALOG_VALUE, Analog_Value_Alarm_Summary); #endif } } @@ -126,8 +121,9 @@ void Analog_Value_Init(void) /* given instance exists */ bool Analog_Value_Valid_Instance(uint32_t object_instance) { - if (object_instance < MAX_ANALOG_VALUES) + if (object_instance < MAX_ANALOG_VALUES) { return true; + } return false; } @@ -154,8 +150,9 @@ unsigned Analog_Value_Instance_To_Index(uint32_t object_instance) { unsigned index = MAX_ANALOG_VALUES; - if (object_instance < MAX_ANALOG_VALUES) + if (object_instance < MAX_ANALOG_VALUES) { index = object_instance; + } return index; } @@ -191,8 +188,8 @@ static void Analog_Value_COV_Detect(unsigned int index, float value) * * @return true if values are within range and present-value is set. */ -bool Analog_Value_Present_Value_Set(uint32_t object_instance, float value, - uint8_t priority) +bool Analog_Value_Present_Value_Set( + uint32_t object_instance, float value, uint8_t priority) { unsigned index = 0; bool status = false; @@ -220,15 +217,15 @@ float Analog_Value_Present_Value(uint32_t object_instance) } /* note: the object name must be unique within this device */ -bool Analog_Value_Object_Name(uint32_t object_instance, - BACNET_CHARACTER_STRING *object_name) +bool Analog_Value_Object_Name( + uint32_t object_instance, BACNET_CHARACTER_STRING *object_name) { static char text_string[32] = ""; /* okay for single thread */ bool status = false; if (object_instance < MAX_ANALOG_VALUES) { - sprintf(text_string, "ANALOG VALUE %lu", - (unsigned long)object_instance); + sprintf( + text_string, "ANALOG VALUE %lu", (unsigned long)object_instance); status = characterstring_init_ansi(object_name, text_string); } @@ -279,8 +276,8 @@ void Analog_Value_Change_Of_Value_Clear(uint32_t object_instance) * * @return true if the value list is encoded */ -bool Analog_Value_Encode_Value_List(uint32_t object_instance, - BACNET_PROPERTY_VALUE *value_list) +bool Analog_Value_Encode_Value_List( + uint32_t object_instance, BACNET_PROPERTY_VALUE *value_list) { bool status = false; @@ -301,18 +298,18 @@ bool Analog_Value_Encode_Value_List(uint32_t object_instance, value_list->value.context_specific = false; value_list->value.tag = BACNET_APPLICATION_TAG_BIT_STRING; bitstring_init(&value_list->value.type.Bit_String); - bitstring_set_bit(&value_list->value.type.Bit_String, - STATUS_FLAG_IN_ALARM, false); - bitstring_set_bit(&value_list->value.type.Bit_String, STATUS_FLAG_FAULT, - false); - bitstring_set_bit(&value_list->value.type.Bit_String, - STATUS_FLAG_OVERRIDDEN, false); + bitstring_set_bit( + &value_list->value.type.Bit_String, STATUS_FLAG_IN_ALARM, false); + bitstring_set_bit( + &value_list->value.type.Bit_String, STATUS_FLAG_FAULT, false); + bitstring_set_bit( + &value_list->value.type.Bit_String, STATUS_FLAG_OVERRIDDEN, false); if (Analog_Value_Out_Of_Service(object_instance)) { bitstring_set_bit(&value_list->value.type.Bit_String, - STATUS_FLAG_OUT_OF_SERVICE, true); + STATUS_FLAG_OUT_OF_SERVICE, true); } else { bitstring_set_bit(&value_list->value.type.Bit_String, - STATUS_FLAG_OUT_OF_SERVICE, false); + STATUS_FLAG_OUT_OF_SERVICE, false); } value_list->value.next = NULL; value_list->priority = BACNET_NO_PRIORITY; @@ -397,10 +394,11 @@ int Analog_Value_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) apdu = rpdata->application_data; object_index = Analog_Value_Instance_To_Index(rpdata->object_instance); - if (object_index < MAX_ANALOG_VALUES) + if (object_index < MAX_ANALOG_VALUES) { CurrentAV = &AV_Descr[object_index]; - else + } else { return BACNET_STATUS_ERROR; + } switch (rpdata->object_property) { case PROP_OBJECT_IDENTIFIER: @@ -429,14 +427,14 @@ int Analog_Value_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) bitstring_init(&bit_string); #if defined(INTRINSIC_REPORTING) bitstring_set_bit(&bit_string, STATUS_FLAG_IN_ALARM, - CurrentAV->Event_State ? true : false); + CurrentAV->Event_State ? true : false); #else bitstring_set_bit(&bit_string, STATUS_FLAG_IN_ALARM, false); #endif bitstring_set_bit(&bit_string, STATUS_FLAG_FAULT, false); bitstring_set_bit(&bit_string, STATUS_FLAG_OVERRIDDEN, false); bitstring_set_bit(&bit_string, STATUS_FLAG_OUT_OF_SERVICE, - CurrentAV->Out_Of_Service); + CurrentAV->Out_Of_Service); apdu_len = encode_application_bitstring(&apdu[0], &bit_string); break; @@ -492,11 +490,9 @@ int Analog_Value_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) case PROP_LIMIT_ENABLE: bitstring_init(&bit_string); bitstring_set_bit(&bit_string, 0, - (CurrentAV->Limit_Enable & EVENT_LOW_LIMIT_ENABLE) - ? true - : false); - bitstring_set_bit( - &bit_string, 1, + (CurrentAV->Limit_Enable & EVENT_LOW_LIMIT_ENABLE) ? true + : false); + bitstring_set_bit(&bit_string, 1, (CurrentAV->Limit_Enable & EVENT_HIGH_LIMIT_ENABLE) ? true : false); @@ -505,32 +501,26 @@ int Analog_Value_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) case PROP_EVENT_ENABLE: bitstring_init(&bit_string); - bitstring_set_bit( - &bit_string, TRANSITION_TO_OFFNORMAL, + bitstring_set_bit(&bit_string, TRANSITION_TO_OFFNORMAL, (CurrentAV->Event_Enable & EVENT_ENABLE_TO_OFFNORMAL) ? true : false); bitstring_set_bit(&bit_string, TRANSITION_TO_FAULT, - (CurrentAV->Event_Enable & EVENT_ENABLE_TO_FAULT) - ? true - : false); + (CurrentAV->Event_Enable & EVENT_ENABLE_TO_FAULT) ? true + : false); bitstring_set_bit(&bit_string, TRANSITION_TO_NORMAL, - (CurrentAV->Event_Enable & EVENT_ENABLE_TO_NORMAL) - ? true - : false); + (CurrentAV->Event_Enable & EVENT_ENABLE_TO_NORMAL) ? true + : false); apdu_len = encode_application_bitstring(&apdu[0], &bit_string); break; case PROP_ACKED_TRANSITIONS: bitstring_init(&bit_string); - bitstring_set_bit( - &bit_string, TRANSITION_TO_OFFNORMAL, + bitstring_set_bit(&bit_string, TRANSITION_TO_OFFNORMAL, CurrentAV->Acked_Transitions[TRANSITION_TO_OFFNORMAL].bIsAcked); - bitstring_set_bit( - &bit_string, TRANSITION_TO_FAULT, + bitstring_set_bit(&bit_string, TRANSITION_TO_FAULT, CurrentAV->Acked_Transitions[TRANSITION_TO_FAULT].bIsAcked); - bitstring_set_bit( - &bit_string, TRANSITION_TO_NORMAL, + bitstring_set_bit(&bit_string, TRANSITION_TO_NORMAL, CurrentAV->Acked_Transitions[TRANSITION_TO_NORMAL].bIsAcked); apdu_len = encode_application_bitstring(&apdu[0], &bit_string); @@ -550,16 +540,14 @@ int Analog_Value_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) /* into one packet. */ else if (rpdata->array_index == BACNET_ARRAY_ALL) { for (i = 0; i < MAX_BACNET_EVENT_TRANSITION; i++) { - len = encode_opening_tag(&apdu[apdu_len], - TIME_STAMP_DATETIME); - len += encode_application_date( - &apdu[apdu_len + len], + len = encode_opening_tag( + &apdu[apdu_len], TIME_STAMP_DATETIME); + len += encode_application_date(&apdu[apdu_len + len], &CurrentAV->Event_Time_Stamps[i].date); - len += encode_application_time( - &apdu[apdu_len + len], + len += encode_application_time(&apdu[apdu_len + len], &CurrentAV->Event_Time_Stamps[i].time); - len += encode_closing_tag(&apdu[apdu_len + len], - TIME_STAMP_DATETIME); + len += encode_closing_tag( + &apdu[apdu_len + len], TIME_STAMP_DATETIME); /* add it if we have room */ if ((apdu_len + len) < MAX_APDU) @@ -574,11 +562,9 @@ int Analog_Value_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) } else if (rpdata->array_index <= MAX_BACNET_EVENT_TRANSITION) { apdu_len = encode_opening_tag(&apdu[apdu_len], TIME_STAMP_DATETIME); - apdu_len += encode_application_date( - &apdu[apdu_len], + apdu_len += encode_application_date(&apdu[apdu_len], &CurrentAV->Event_Time_Stamps[rpdata->array_index].date); - apdu_len += encode_application_time( - &apdu[apdu_len], + apdu_len += encode_application_time(&apdu[apdu_len], &CurrentAV->Event_Time_Stamps[rpdata->array_index].time); apdu_len += encode_closing_tag(&apdu[apdu_len], TIME_STAMP_DATETIME); @@ -618,8 +604,8 @@ bool Analog_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) ANALOG_VALUE_DESCR *CurrentAV; /* decode the some of the request */ - len = bacapp_decode_application_data(wp_data->application_data, - wp_data->application_data_len, &value); + len = bacapp_decode_application_data( + wp_data->application_data, wp_data->application_data_len, &value); /* FIXME: len < application_data_len: more data? */ if (len < 0) { /* error while decoding - a value larger than we can handle */ @@ -636,10 +622,11 @@ bool Analog_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) return false; } object_index = Analog_Value_Instance_To_Index(wp_data->object_instance); - if (object_index < MAX_ANALOG_VALUES) + if (object_index < MAX_ANALOG_VALUES) { CurrentAV = &AV_Descr[object_index]; - else + } else { return false; + } switch (wp_data->object_property) { case PROP_PRESENT_VALUE: @@ -648,8 +635,7 @@ bool Analog_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) algorithm and may not be used for other purposes in any object. */ if (Analog_Value_Present_Value_Set(wp_data->object_instance, - value.type.Real, - wp_data->priority)) { + value.type.Real, wp_data->priority)) { status = true; } else if (wp_data->priority == 6) { /* Command priority 6 is reserved for use by Minimum On/Off @@ -669,9 +655,8 @@ bool Analog_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) break; case PROP_OUT_OF_SERVICE: - status = - WPValidateArgType(&value, BACNET_APPLICATION_TAG_BOOLEAN, - &wp_data->error_class, &wp_data->error_code); + status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_BOOLEAN, + &wp_data->error_class, &wp_data->error_code); if (status) { CurrentAV->Out_Of_Service = value.type.Boolean; } @@ -680,20 +665,19 @@ bool Analog_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) case PROP_UNITS: status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_ENUMERATED, - &wp_data->error_class, &wp_data->error_code); + &wp_data->error_class, &wp_data->error_code); if (status) { CurrentAV->Units = value.type.Enumerated; } break; case PROP_COV_INCREMENT: - status = - WPValidateArgType(&value, BACNET_APPLICATION_TAG_REAL, - &wp_data->error_class, &wp_data->error_code); + status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_REAL, + &wp_data->error_class, &wp_data->error_code); if (status) { if (value.type.Real >= 0.0) { - Analog_Value_COV_Increment_Set(wp_data->object_instance, - value.type.Real); + Analog_Value_COV_Increment_Set( + wp_data->object_instance, value.type.Real); } else { status = false; wp_data->error_class = ERROR_CLASS_PROPERTY; @@ -706,7 +690,7 @@ bool Analog_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) case PROP_TIME_DELAY: status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_UNSIGNED_INT, - &wp_data->error_class, &wp_data->error_code); + &wp_data->error_class, &wp_data->error_code); if (status) { CurrentAV->Time_Delay = value.type.Unsigned_Int; @@ -717,7 +701,7 @@ bool Analog_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) case PROP_NOTIFICATION_CLASS: status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_UNSIGNED_INT, - &wp_data->error_class, &wp_data->error_code); + &wp_data->error_class, &wp_data->error_code); if (status) { CurrentAV->Notification_Class = value.type.Unsigned_Int; @@ -725,9 +709,8 @@ bool Analog_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) break; case PROP_HIGH_LIMIT: - status = - WPValidateArgType(&value, BACNET_APPLICATION_TAG_REAL, - &wp_data->error_class, &wp_data->error_code); + status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_REAL, + &wp_data->error_class, &wp_data->error_code); if (status) { CurrentAV->High_Limit = value.type.Real; @@ -735,9 +718,8 @@ bool Analog_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) break; case PROP_LOW_LIMIT: - status = - WPValidateArgType(&value, BACNET_APPLICATION_TAG_REAL, - &wp_data->error_class, &wp_data->error_code); + status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_REAL, + &wp_data->error_class, &wp_data->error_code); if (status) { CurrentAV->Low_Limit = value.type.Real; @@ -745,9 +727,8 @@ bool Analog_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) break; case PROP_DEADBAND: - status = - WPValidateArgType(&value, BACNET_APPLICATION_TAG_REAL, - &wp_data->error_class, &wp_data->error_code); + status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_REAL, + &wp_data->error_class, &wp_data->error_code); if (status) { CurrentAV->Deadband = value.type.Real; @@ -757,7 +738,7 @@ bool Analog_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) case PROP_LIMIT_ENABLE: status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_BIT_STRING, - &wp_data->error_class, &wp_data->error_code); + &wp_data->error_class, &wp_data->error_code); if (status) { if (value.type.Bit_String.bits_used == 2) { @@ -773,7 +754,7 @@ bool Analog_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) case PROP_EVENT_ENABLE: status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_BIT_STRING, - &wp_data->error_class, &wp_data->error_code); + &wp_data->error_class, &wp_data->error_code); if (status) { if (value.type.Bit_String.bits_used == 3) { @@ -789,7 +770,7 @@ bool Analog_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) case PROP_NOTIFY_TYPE: status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_ENUMERATED, - &wp_data->error_class, &wp_data->error_code); + &wp_data->error_class, &wp_data->error_code); if (status) { switch ((BACNET_NOTIFY_TYPE)value.type.Enumerated) { @@ -863,7 +844,7 @@ void Analog_Value_Intrinsic_Reporting(uint32_t object_instance) #if PRINT_ENABLED fprintf(stderr, "Send Acknotification for (%s,%d).\n", - bactext_object_type_name(OBJECT_ANALOG_VALUE), object_instance); + bactext_object_type_name(OBJECT_ANALOG_VALUE), object_instance); #endif /* PRINT_ENABLED */ characterstring_init_ansi(&msgText, "AckNotification"); @@ -888,9 +869,9 @@ void Analog_Value_Intrinsic_Reporting(uint32_t object_instance) property. */ if ((PresentVal > CurrentAV->High_Limit) && ((CurrentAV->Limit_Enable & EVENT_HIGH_LIMIT_ENABLE) == - EVENT_HIGH_LIMIT_ENABLE) && + EVENT_HIGH_LIMIT_ENABLE) && ((CurrentAV->Event_Enable & EVENT_ENABLE_TO_OFFNORMAL) == - EVENT_ENABLE_TO_OFFNORMAL)) { + EVENT_ENABLE_TO_OFFNORMAL)) { if (!CurrentAV->Remaining_Time_Delay) CurrentAV->Event_State = EVENT_STATE_HIGH_LIMIT; else @@ -907,9 +888,9 @@ void Analog_Value_Intrinsic_Reporting(uint32_t object_instance) property. */ if ((PresentVal < CurrentAV->Low_Limit) && ((CurrentAV->Limit_Enable & EVENT_LOW_LIMIT_ENABLE) == - EVENT_LOW_LIMIT_ENABLE) && + EVENT_LOW_LIMIT_ENABLE) && ((CurrentAV->Event_Enable & EVENT_ENABLE_TO_OFFNORMAL) == - EVENT_ENABLE_TO_OFFNORMAL)) { + EVENT_ENABLE_TO_OFFNORMAL)) { if (!CurrentAV->Remaining_Time_Delay) CurrentAV->Event_State = EVENT_STATE_LOW_LIMIT; else @@ -930,11 +911,11 @@ void Analog_Value_Intrinsic_Reporting(uint32_t object_instance) property, and (c) the TO-NORMAL flag must be set in the Event_Enable property. */ if ((PresentVal < - CurrentAV->High_Limit - CurrentAV->Deadband) && + CurrentAV->High_Limit - CurrentAV->Deadband) && ((CurrentAV->Limit_Enable & EVENT_HIGH_LIMIT_ENABLE) == - EVENT_HIGH_LIMIT_ENABLE) && + EVENT_HIGH_LIMIT_ENABLE) && ((CurrentAV->Event_Enable & EVENT_ENABLE_TO_NORMAL) == - EVENT_ENABLE_TO_NORMAL)) { + EVENT_ENABLE_TO_NORMAL)) { if (!CurrentAV->Remaining_Time_Delay) CurrentAV->Event_State = EVENT_STATE_NORMAL; else @@ -957,9 +938,9 @@ void Analog_Value_Intrinsic_Reporting(uint32_t object_instance) property. */ if ((PresentVal > CurrentAV->Low_Limit + CurrentAV->Deadband) && ((CurrentAV->Limit_Enable & EVENT_LOW_LIMIT_ENABLE) == - EVENT_LOW_LIMIT_ENABLE) && + EVENT_LOW_LIMIT_ENABLE) && ((CurrentAV->Event_Enable & EVENT_ENABLE_TO_NORMAL) == - EVENT_ENABLE_TO_NORMAL)) { + EVENT_ENABLE_TO_NORMAL)) { if (!CurrentAV->Remaining_Time_Delay) CurrentAV->Event_State = EVENT_STATE_NORMAL; else @@ -972,7 +953,7 @@ void Analog_Value_Intrinsic_Reporting(uint32_t object_instance) default: return; /* shouldn't happen */ - } /* switch (FromState) */ + } /* switch (FromState) */ ToState = CurrentAV->Event_State; @@ -1011,9 +992,9 @@ void Analog_Value_Intrinsic_Reporting(uint32_t object_instance) #if PRINT_ENABLED fprintf(stderr, "Event_State for (%s,%d) goes from %s to %s.\n", - bactext_object_type_name(OBJECT_ANALOG_VALUE), - object_instance, bactext_event_state_name(FromState), - bactext_event_state_name(ToState)); + bactext_object_type_name(OBJECT_ANALOG_VALUE), object_instance, + bactext_event_state_name(FromState), + bactext_event_state_name(ToState)); #endif /* PRINT_ENABLED */ /* Notify Type */ @@ -1153,12 +1134,12 @@ int Analog_Value_Event_Information( (TO-OFFNORMAL, TO-FAULT, TONORMAL) set to FALSE. */ IsNotAckedTransitions = (AV_Descr[index] - .Acked_Transitions[TRANSITION_TO_OFFNORMAL] - .bIsAcked == false) | + .Acked_Transitions[TRANSITION_TO_OFFNORMAL] + .bIsAcked == false) | (AV_Descr[index].Acked_Transitions[TRANSITION_TO_FAULT].bIsAcked == - false) | + false) | (AV_Descr[index].Acked_Transitions[TRANSITION_TO_NORMAL].bIsAcked == - false); + false); } else return -1; /* end of list */ @@ -1172,15 +1153,15 @@ int Analog_Value_Event_Information( /* Acknowledged Transitions */ bitstring_init(&getevent_data->acknowledgedTransitions); bitstring_set_bit(&getevent_data->acknowledgedTransitions, - TRANSITION_TO_OFFNORMAL, - AV_Descr[index] - .Acked_Transitions[TRANSITION_TO_OFFNORMAL] - .bIsAcked); - bitstring_set_bit( - &getevent_data->acknowledgedTransitions, TRANSITION_TO_FAULT, + TRANSITION_TO_OFFNORMAL, + AV_Descr[index] + .Acked_Transitions[TRANSITION_TO_OFFNORMAL] + .bIsAcked); + bitstring_set_bit(&getevent_data->acknowledgedTransitions, + TRANSITION_TO_FAULT, AV_Descr[index].Acked_Transitions[TRANSITION_TO_FAULT].bIsAcked); - bitstring_set_bit( - &getevent_data->acknowledgedTransitions, TRANSITION_TO_NORMAL, + bitstring_set_bit(&getevent_data->acknowledgedTransitions, + TRANSITION_TO_NORMAL, AV_Descr[index].Acked_Transitions[TRANSITION_TO_NORMAL].bIsAcked); /* Event Time Stamps */ for (i = 0; i < 3; i++) { @@ -1192,29 +1173,26 @@ int Analog_Value_Event_Information( getevent_data->notifyType = AV_Descr[index].Notify_Type; /* Event Enable */ bitstring_init(&getevent_data->eventEnable); - bitstring_set_bit( - &getevent_data->eventEnable, TRANSITION_TO_OFFNORMAL, + bitstring_set_bit(&getevent_data->eventEnable, TRANSITION_TO_OFFNORMAL, (AV_Descr[index].Event_Enable & EVENT_ENABLE_TO_OFFNORMAL) ? true : false); bitstring_set_bit(&getevent_data->eventEnable, TRANSITION_TO_FAULT, - (AV_Descr[index].Event_Enable & EVENT_ENABLE_TO_FAULT) - ? true - : false); - bitstring_set_bit( - &getevent_data->eventEnable, TRANSITION_TO_NORMAL, + (AV_Descr[index].Event_Enable & EVENT_ENABLE_TO_FAULT) ? true + : false); + bitstring_set_bit(&getevent_data->eventEnable, TRANSITION_TO_NORMAL, (AV_Descr[index].Event_Enable & EVENT_ENABLE_TO_NORMAL) ? true : false); /* Event Priorities */ - Notification_Class_Get_Priorities(AV_Descr[index].Notification_Class, - getevent_data->eventPriorities); + Notification_Class_Get_Priorities( + AV_Descr[index].Notification_Class, getevent_data->eventPriorities); return 1; /* active event */ } else return 0; /* no active event at this index */ } -int Analog_Value_Alarm_Ack(BACNET_ALARM_ACK_DATA *alarmack_data, - BACNET_ERROR_CODE *error_code) +int Analog_Value_Alarm_Ack( + BACNET_ALARM_ACK_DATA *alarmack_data, BACNET_ERROR_CODE *error_code) { ANALOG_VALUE_DESCR *CurrentAV; unsigned int object_index; @@ -1316,8 +1294,8 @@ int Analog_Value_Alarm_Ack(BACNET_ALARM_ACK_DATA *alarmack_data, return 1; } -int Analog_Value_Alarm_Summary(unsigned index, - BACNET_GET_ALARM_SUMMARY_DATA *getalarm_data) +int Analog_Value_Alarm_Summary( + unsigned index, BACNET_GET_ALARM_SUMMARY_DATA *getalarm_data) { /* check index */ if (index < MAX_ANALOG_VALUES) { @@ -1334,20 +1312,20 @@ int Analog_Value_Alarm_Summary(unsigned index, /* Acknowledged Transitions */ bitstring_init(&getalarm_data->acknowledgedTransitions); bitstring_set_bit(&getalarm_data->acknowledgedTransitions, - TRANSITION_TO_OFFNORMAL, - AV_Descr[index] - .Acked_Transitions[TRANSITION_TO_OFFNORMAL] - .bIsAcked); + TRANSITION_TO_OFFNORMAL, + AV_Descr[index] + .Acked_Transitions[TRANSITION_TO_OFFNORMAL] + .bIsAcked); bitstring_set_bit(&getalarm_data->acknowledgedTransitions, - TRANSITION_TO_FAULT, - AV_Descr[index] - .Acked_Transitions[TRANSITION_TO_FAULT] - .bIsAcked); + TRANSITION_TO_FAULT, + AV_Descr[index] + .Acked_Transitions[TRANSITION_TO_FAULT] + .bIsAcked); bitstring_set_bit(&getalarm_data->acknowledgedTransitions, - TRANSITION_TO_NORMAL, - AV_Descr[index] - .Acked_Transitions[TRANSITION_TO_NORMAL] - .bIsAcked); + TRANSITION_TO_NORMAL, + AV_Descr[index] + .Acked_Transitions[TRANSITION_TO_NORMAL] + .bIsAcked); return 1; /* active alarm */ } else @@ -1363,8 +1341,9 @@ int Analog_Value_Alarm_Summary(unsigned index, #include "ctest.h" bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue, - uint8_t ucExpectedTag, BACNET_ERROR_CLASS *pErrorClass, - BACNET_ERROR_CODE *pErrorCode) + uint8_t ucExpectedTag, + BACNET_ERROR_CLASS *pErrorClass, + BACNET_ERROR_CODE *pErrorCode) { pValue = pValue; ucExpectedTag = ucExpectedTag; @@ -1377,7 +1356,7 @@ bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue, void testAnalog_Value(Test *pTest) { BACNET_READ_PROPERTY_DATA rpdata; - uint8_t apdu[MAX_APDU] = {0}; + uint8_t apdu[MAX_APDU] = { 0 }; int len = 0; uint32_t len_value = 0; uint8_t tag_number = 0; diff --git a/demo/object/av.h b/src/bacnet/basic/object/av.h similarity index 95% rename from demo/object/av.h rename to src/bacnet/basic/object/av.h index 78a5fa23..6932a74f 100644 --- a/demo/object/av.h +++ b/src/bacnet/basic/object/av.h @@ -28,15 +28,15 @@ #include #include -#include "bacdef.h" -#include "bacerror.h" -#include "wp.h" -#include "rp.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacerror.h" +#include "bacnet/wp.h" +#include "bacnet/rp.h" #if defined(INTRINSIC_REPORTING) -#include "nc.h" -#include "alarm_ack.h" -#include "getevent.h" -#include "get_alarm_sum.h" +#include "bacnet/basic/object/nc.h" +#include "bacnet/alarm_ack.h" +#include "bacnet/getevent.h" +#include "bacnet/get_alarm_sum.h" #endif #ifdef __cplusplus diff --git a/demo/object/av.mak b/src/bacnet/basic/object/av.mak similarity index 62% rename from demo/object/av.mak rename to src/bacnet/basic/object/av.mak index aa7e19ee..a3c3285c 100644 --- a/demo/object/av.mak +++ b/src/bacnet/basic/object/av.mak @@ -8,16 +8,16 @@ DEFINES = -DBIG_ENDIAN=0 -DTEST -DBACAPP_ALL -DTEST_ANALOG_VALUE CFLAGS = -Wall $(INCLUDES) $(DEFINES) -g SRCS = av.c \ - $(SRC_DIR)/bacdcode.c \ - $(SRC_DIR)/bacint.c \ - $(SRC_DIR)/bacstr.c \ - $(SRC_DIR)/bacreal.c \ - $(SRC_DIR)/datetime.c \ - $(SRC_DIR)/lighting.c \ - $(SRC_DIR)/bacapp.c \ - $(SRC_DIR)/bacdevobjpropref.c \ - $(SRC_DIR)/bactext.c \ - $(SRC_DIR)/indtext.c \ + $(SRC_DIR)/bacnet/bacdcode.c \ + $(SRC_DIR)/bacnet/bacint.c \ + $(SRC_DIR)/bacnet/bacstr.c \ + $(SRC_DIR)/bacnet/bacreal.c \ + $(SRC_DIR)/bacnet/datetime.c \ + $(SRC_DIR)/bacnet/lighting.c \ + $(SRC_DIR)/bacnet/bacapp.c \ + $(SRC_DIR)/bacnet/bacdevobjpropref.c \ + $(SRC_DIR)/bacnet/bactext.c \ + $(SRC_DIR)/bacnet/indtext.c \ $(TEST_DIR)/ctest.c TARGET = analog_value diff --git a/demo/object/bacfile.c b/src/bacnet/basic/object/bacfile.c similarity index 78% rename from demo/object/bacfile.c rename to src/bacnet/basic/object/bacfile.c index 8255677a..647a9ff5 100644 --- a/demo/object/bacfile.c +++ b/src/bacnet/basic/object/bacfile.c @@ -27,22 +27,22 @@ #include #include #include -#include "config.h" -#include "address.h" -#include "bacdef.h" -#include "bacapp.h" -#include "datalink.h" -#include "bacdcode.h" -#include "npdu.h" -#include "apdu.h" -#include "tsm.h" -#include "device.h" -#include "arf.h" -#include "awf.h" -#include "rp.h" -#include "wp.h" -#include "handlers.h" -#include "bacfile.h" +#include "bacnet/config.h" +#include "bacnet/basic/binding/address.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacapp.h" +#include "bacnet/datalink/datalink.h" +#include "bacnet/bacdcode.h" +#include "bacnet/npdu.h" +#include "bacnet/apdu.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/basic/object/device.h" +#include "bacnet/arf.h" +#include "bacnet/awf.h" +#include "bacnet/rp.h" +#include "bacnet/wp.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/object/bacfile.h" typedef struct { uint32_t instance; @@ -54,37 +54,32 @@ typedef struct { #endif static BACNET_FILE_LISTING BACnet_File_Listing[] = { - {0, "temp_0.txt"}, - {1, "temp_1.txt"}, - {2, "temp_2.txt"}, - {0, NULL} /* last file indication */ + { 0, "temp_0.txt" }, { 1, "temp_1.txt" }, { 2, "temp_2.txt" }, + { 0, NULL } /* last file indication */ }; /* These three arrays are used by the ReadPropertyMultiple handler */ -static const int bacfile_Properties_Required[] = {PROP_OBJECT_IDENTIFIER, - PROP_OBJECT_NAME, - PROP_OBJECT_TYPE, - PROP_FILE_TYPE, - PROP_FILE_SIZE, - PROP_MODIFICATION_DATE, - PROP_ARCHIVE, - PROP_READ_ONLY, - PROP_FILE_ACCESS_METHOD, - -1}; +static const int bacfile_Properties_Required[] = { PROP_OBJECT_IDENTIFIER, + PROP_OBJECT_NAME, PROP_OBJECT_TYPE, PROP_FILE_TYPE, PROP_FILE_SIZE, + PROP_MODIFICATION_DATE, PROP_ARCHIVE, PROP_READ_ONLY, + PROP_FILE_ACCESS_METHOD, -1 }; -static const int bacfile_Properties_Optional[] = {PROP_DESCRIPTION, -1}; +static const int bacfile_Properties_Optional[] = { PROP_DESCRIPTION, -1 }; -static const int bacfile_Properties_Proprietary[] = {-1}; +static const int bacfile_Properties_Proprietary[] = { -1 }; -void BACfile_Property_Lists(const int **pRequired, const int **pOptional, - const int **pProprietary) +void BACfile_Property_Lists( + const int **pRequired, const int **pOptional, const int **pProprietary) { - if (pRequired) + if (pRequired) { *pRequired = bacfile_Properties_Required; - if (pOptional) + } + if (pOptional) { *pOptional = bacfile_Properties_Optional; - if (pProprietary) + } + if (pProprietary) { *pProprietary = bacfile_Properties_Proprietary; + } return; } @@ -106,8 +101,8 @@ static char *bacfile_name(uint32_t instance) return filename; } -bool bacfile_object_name(uint32_t instance, - BACNET_CHARACTER_STRING *object_name) +bool bacfile_object_name( + uint32_t instance, BACNET_CHARACTER_STRING *object_name) { bool status = false; char *filename = NULL; @@ -190,7 +185,7 @@ unsigned bacfile_file_size(uint32_t object_instance) int bacfile_read_property(BACNET_READ_PROPERTY_DATA *rpdata) { int apdu_len = 0; /* return value */ - char text_string[32] = {""}; + char text_string[32] = { "" }; BACNET_CHARACTER_STRING char_string; BACNET_DATE bdate; BACNET_TIME btime; @@ -203,12 +198,12 @@ int bacfile_read_property(BACNET_READ_PROPERTY_DATA *rpdata) apdu = rpdata->application_data; switch (rpdata->object_property) { case PROP_OBJECT_IDENTIFIER: - apdu_len = encode_application_object_id(&apdu[0], OBJECT_FILE, - rpdata->object_instance); + apdu_len = encode_application_object_id( + &apdu[0], OBJECT_FILE, rpdata->object_instance); break; case PROP_OBJECT_NAME: sprintf(text_string, "FILE %lu", - (unsigned long)rpdata->object_instance); + (unsigned long)rpdata->object_instance); characterstring_init_ansi(&char_string, text_string); apdu_len = encode_application_character_string(&apdu[0], &char_string); @@ -217,8 +212,8 @@ int bacfile_read_property(BACNET_READ_PROPERTY_DATA *rpdata) apdu_len = encode_application_enumerated(&apdu[0], OBJECT_FILE); break; case PROP_DESCRIPTION: - characterstring_init_ansi(&char_string, - bacfile_name(rpdata->object_instance)); + characterstring_init_ansi( + &char_string, bacfile_name(rpdata->object_instance)); apdu_len = encode_application_character_string(&apdu[0], &char_string); break; @@ -234,9 +229,9 @@ int bacfile_read_property(BACNET_READ_PROPERTY_DATA *rpdata) case PROP_MODIFICATION_DATE: /* FIXME: get the actual value instead of April Fool's Day */ bdate.year = 2006; /* AD */ - bdate.month = 4; /* 1=Jan */ - bdate.day = 1; /* 1..31 */ - bdate.wday = 6; /* 1=Monday */ + bdate.month = 4; /* 1=Jan */ + bdate.day = 1; /* 1..31 */ + bdate.wday = 6; /* 1=Monday */ apdu_len = encode_application_date(&apdu[0], &bdate); /* FIXME: get the actual value */ btime.hour = 7; @@ -293,8 +288,8 @@ bool bacfile_write_property(BACNET_WRITE_PROPERTY_DATA *wp_data) return false; } /* decode the some of the request */ - len = bacapp_decode_application_data(wp_data->application_data, - wp_data->application_data_len, &value); + len = bacapp_decode_application_data( + wp_data->application_data, wp_data->application_data_len, &value); if (len < 0) { /* error while decoding - a value larger than we can handle */ wp_data->error_class = ERROR_CLASS_PROPERTY; @@ -310,9 +305,8 @@ bool bacfile_write_property(BACNET_WRITE_PROPERTY_DATA *wp_data) property shall be logical TRUE only if no changes have been made to the file data by internal processes or through File Access Services since the last time the object was archived. */ - status = - WPValidateArgType(&value, BACNET_APPLICATION_TAG_BOOLEAN, - &wp_data->error_class, &wp_data->error_code); + status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_BOOLEAN, + &wp_data->error_class, &wp_data->error_code); if (status) { if (value.type.Boolean) { /* FIXME: do something to wp_data->object_instance */ @@ -327,7 +321,7 @@ bool bacfile_write_property(BACNET_WRITE_PROPERTY_DATA *wp_data) shall be writable. */ status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_UNSIGNED_INT, - &wp_data->error_class, &wp_data->error_code); + &wp_data->error_class, &wp_data->error_code); if (status) { /* FIXME: do something with value.type.Unsigned to wp_data->object_instance */ @@ -378,34 +372,35 @@ uint32_t bacfile_instance(char *filename) /* when the request was sent */ uint32_t bacfile_instance_from_tsm(uint8_t invokeID) { - BACNET_NPDU_DATA npdu_data = {0}; /* dummy for getting npdu length */ - BACNET_CONFIRMED_SERVICE_DATA service_data = {0}; + BACNET_NPDU_DATA npdu_data = { 0 }; /* dummy for getting npdu length */ + BACNET_CONFIRMED_SERVICE_DATA service_data = { 0 }; uint8_t service_choice = 0; uint8_t *service_request = NULL; uint16_t service_request_len = 0; - BACNET_ADDRESS dest; /* where the original packet was destined */ - uint8_t apdu[MAX_PDU] = {0}; /* original APDU packet */ - uint16_t apdu_len = 0; /* original APDU packet length */ - int len = 0; /* apdu header length */ - BACNET_ATOMIC_READ_FILE_DATA data = {0}; + BACNET_ADDRESS dest; /* where the original packet was destined */ + uint8_t apdu[MAX_PDU] = { 0 }; /* original APDU packet */ + uint16_t apdu_len = 0; /* original APDU packet length */ + int len = 0; /* apdu header length */ + BACNET_ATOMIC_READ_FILE_DATA data = { 0 }; uint32_t object_instance = BACNET_MAX_INSTANCE + 1; /* return value */ bool found = false; - found = tsm_get_transaction_pdu(invokeID, &dest, &npdu_data, &apdu[0], - &apdu_len); + found = tsm_get_transaction_pdu( + invokeID, &dest, &npdu_data, &apdu[0], &apdu_len); if (found) { if (!npdu_data.network_layer_message && npdu_data.data_expecting_reply && (apdu[0] == PDU_TYPE_CONFIRMED_SERVICE_REQUEST)) { - len = apdu_decode_confirmed_service_request( - &apdu[0], apdu_len, &service_data, &service_choice, - &service_request, &service_request_len); + len = apdu_decode_confirmed_service_request(&apdu[0], apdu_len, + &service_data, &service_choice, &service_request, + &service_request_len); if (service_choice == SERVICE_CONFIRMED_ATOMIC_READ_FILE) { - len = arf_decode_service_request(service_request, - service_request_len, &data); + len = arf_decode_service_request( + service_request, service_request_len, &data); if (len > 0) { - if (data.object_type == OBJECT_FILE) + if (data.object_type == OBJECT_FILE) { object_instance = data.object_instance; + } } } } @@ -429,11 +424,12 @@ bool bacfile_read_stream_data(BACNET_ATOMIC_READ_FILE_DATA *data) if (pFile) { (void)fseek(pFile, data->type.stream.fileStartPosition, SEEK_SET); len = fread(octetstring_value(&data->fileData[0]), 1, - data->type.stream.requestedOctetCount, pFile); - if (len < data->type.stream.requestedOctetCount) + data->type.stream.requestedOctetCount, pFile); + if (len < data->type.stream.requestedOctetCount) { data->endOfFile = true; - else + } else { data->endOfFile = false; + } octetstring_truncate(&data->fileData[0], len); fclose(pFile); } else { @@ -471,11 +467,11 @@ bool bacfile_write_stream_data(BACNET_ATOMIC_WRITE_FILE_DATA *data) } if (pFile) { if (data->type.stream.fileStartPosition != -1) { - (void)fseek(pFile, data->type.stream.fileStartPosition, - SEEK_SET); + (void)fseek( + pFile, data->type.stream.fileStartPosition, SEEK_SET); } if (fwrite(octetstring_value(&data->fileData[0]), - octetstring_length(&data->fileData[0]), 1, pFile) != 1) { + octetstring_length(&data->fileData[0]), 1, pFile) != 1) { /* do something if it fails? */ } fclose(pFile); @@ -522,8 +518,8 @@ bool bacfile_write_record_data(BACNET_ATOMIC_WRITE_FILE_DATA *data) } for (i = 0; i < data->type.record.returnedRecordCount; i++) { if (fwrite(octetstring_value(&data->fileData[i]), - octetstring_length(&data->fileData[i]), 1, - pFile) != 1) { + octetstring_length(&data->fileData[i]), 1, + pFile) != 1) { /* do something if it fails? */ } } @@ -534,8 +530,8 @@ bool bacfile_write_record_data(BACNET_ATOMIC_WRITE_FILE_DATA *data) return found; } -bool bacfile_read_ack_stream_data(uint32_t instance, - BACNET_ATOMIC_READ_FILE_DATA *data) +bool bacfile_read_ack_stream_data( + uint32_t instance, BACNET_ATOMIC_READ_FILE_DATA *data) { bool found = false; FILE *pFile = NULL; @@ -548,10 +544,10 @@ bool bacfile_read_ack_stream_data(uint32_t instance, if (pFile) { (void)fseek(pFile, data->type.stream.fileStartPosition, SEEK_SET); if (fwrite(octetstring_value(&data->fileData[0]), - octetstring_length(&data->fileData[0]), 1, pFile) != 1) { + octetstring_length(&data->fileData[0]), 1, pFile) != 1) { #if PRINT_ENABLED fprintf(stderr, "Failed to write to %s (%lu)!\n", pFilename, - (unsigned long)instance); + (unsigned long)instance); #endif } fclose(pFile); @@ -561,14 +557,14 @@ bool bacfile_read_ack_stream_data(uint32_t instance, return found; } -bool bacfile_read_ack_record_data(uint32_t instance, - BACNET_ATOMIC_READ_FILE_DATA *data) +bool bacfile_read_ack_record_data( + uint32_t instance, BACNET_ATOMIC_READ_FILE_DATA *data) { bool found = false; FILE *pFile = NULL; char *pFilename = NULL; uint32_t i = 0; - char dummy_data[MAX_OCTET_STRING_BYTES] = {0}; + char dummy_data[MAX_OCTET_STRING_BYTES] = { 0 }; char *pData = NULL; pFilename = bacfile_name(instance); @@ -587,11 +583,11 @@ bool bacfile_read_ack_record_data(uint32_t instance, } for (i = 0; i < data->type.record.RecordCount; i++) { if (fwrite(octetstring_value(&data->fileData[i]), - octetstring_length(&data->fileData[i]), 1, - pFile) != 1) { + octetstring_length(&data->fileData[i]), 1, + pFile) != 1) { #if PRINT_ENABLED fprintf(stderr, "Failed to write to %s (%lu)!\n", pFilename, - (unsigned long)instance); + (unsigned long)instance); #endif } } diff --git a/demo/object/bacfile.h b/src/bacnet/basic/object/bacfile.h similarity index 95% rename from demo/object/bacfile.h rename to src/bacnet/basic/object/bacfile.h index 6248acb9..ad1883b9 100644 --- a/demo/object/bacfile.h +++ b/src/bacnet/basic/object/bacfile.h @@ -36,13 +36,13 @@ #include #include -#include "bacdef.h" -#include "bacenum.h" -#include "apdu.h" -#include "arf.h" -#include "awf.h" -#include "rp.h" -#include "wp.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacenum.h" +#include "bacnet/apdu.h" +#include "bacnet/arf.h" +#include "bacnet/awf.h" +#include "bacnet/rp.h" +#include "bacnet/wp.h" #ifdef __cplusplus extern "C" { diff --git a/demo/object/bi.c b/src/bacnet/basic/object/bi.c similarity index 84% rename from demo/object/bi.c rename to src/bacnet/basic/object/bi.c index b2f1a259..74332d4c 100644 --- a/demo/object/bi.c +++ b/src/bacnet/basic/object/bi.c @@ -28,16 +28,16 @@ #include #include #include -#include "bacdef.h" -#include "bacdcode.h" -#include "bacenum.h" -#include "bacapp.h" -#include "rp.h" -#include "wp.h" -#include "cov.h" -#include "config.h" /* the custom stuff */ -#include "bi.h" -#include "handlers.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacenum.h" +#include "bacnet/bacapp.h" +#include "bacnet/rp.h" +#include "bacnet/wp.h" +#include "bacnet/cov.h" +#include "bacnet/config.h" /* the custom stuff */ +#include "bacnet/basic/object/bi.h" +#include "bacnet/basic/services.h" #ifndef MAX_BINARY_INPUTS #define MAX_BINARY_INPUTS 5 @@ -53,17 +53,16 @@ static bool Change_Of_Value[MAX_BINARY_INPUTS]; static BACNET_POLARITY Polarity[MAX_BINARY_INPUTS]; /* These three arrays are used by the ReadPropertyMultiple handler */ -static const int Binary_Input_Properties_Required[] = { - PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME, PROP_OBJECT_TYPE, - PROP_PRESENT_VALUE, PROP_STATUS_FLAGS, PROP_EVENT_STATE, - PROP_OUT_OF_SERVICE, PROP_POLARITY, -1}; +static const int Binary_Input_Properties_Required[] = { PROP_OBJECT_IDENTIFIER, + PROP_OBJECT_NAME, PROP_OBJECT_TYPE, PROP_PRESENT_VALUE, PROP_STATUS_FLAGS, + PROP_EVENT_STATE, PROP_OUT_OF_SERVICE, PROP_POLARITY, -1 }; -static const int Binary_Input_Properties_Optional[] = {PROP_DESCRIPTION, -1}; +static const int Binary_Input_Properties_Optional[] = { PROP_DESCRIPTION, -1 }; -static const int Binary_Input_Properties_Proprietary[] = {-1}; +static const int Binary_Input_Properties_Proprietary[] = { -1 }; -void Binary_Input_Property_Lists(const int **pRequired, const int **pOptional, - const int **pProprietary) +void Binary_Input_Property_Lists( + const int **pRequired, const int **pOptional, const int **pProprietary) { if (pRequired) { *pRequired = Binary_Input_Properties_Required; @@ -202,8 +201,8 @@ void Binary_Input_Change_Of_Value_Clear(uint32_t object_instance) * * @return true if the value list is encoded */ -bool Binary_Input_Encode_Value_List(uint32_t object_instance, - BACNET_PROPERTY_VALUE *value_list) +bool Binary_Input_Encode_Value_List( + uint32_t object_instance, BACNET_PROPERTY_VALUE *value_list) { bool status = false; @@ -225,18 +224,18 @@ bool Binary_Input_Encode_Value_List(uint32_t object_instance, value_list->value.tag = BACNET_APPLICATION_TAG_BIT_STRING; value_list->value.next = NULL; bitstring_init(&value_list->value.type.Bit_String); - bitstring_set_bit(&value_list->value.type.Bit_String, - STATUS_FLAG_IN_ALARM, false); - bitstring_set_bit(&value_list->value.type.Bit_String, STATUS_FLAG_FAULT, - false); - bitstring_set_bit(&value_list->value.type.Bit_String, - STATUS_FLAG_OVERRIDDEN, false); + bitstring_set_bit( + &value_list->value.type.Bit_String, STATUS_FLAG_IN_ALARM, false); + bitstring_set_bit( + &value_list->value.type.Bit_String, STATUS_FLAG_FAULT, false); + bitstring_set_bit( + &value_list->value.type.Bit_String, STATUS_FLAG_OVERRIDDEN, false); if (Binary_Input_Out_Of_Service(object_instance)) { bitstring_set_bit(&value_list->value.type.Bit_String, - STATUS_FLAG_OUT_OF_SERVICE, true); + STATUS_FLAG_OUT_OF_SERVICE, true); } else { bitstring_set_bit(&value_list->value.type.Bit_String, - STATUS_FLAG_OUT_OF_SERVICE, false); + STATUS_FLAG_OUT_OF_SERVICE, false); } value_list->priority = BACNET_NO_PRIORITY; value_list->next = NULL; @@ -246,8 +245,8 @@ bool Binary_Input_Encode_Value_List(uint32_t object_instance, return status; } -bool Binary_Input_Present_Value_Set(uint32_t object_instance, - BACNET_BINARY_PV value) +bool Binary_Input_Present_Value_Set( + uint32_t object_instance, BACNET_BINARY_PV value) { unsigned index = 0; bool status = false; @@ -286,8 +285,8 @@ void Binary_Input_Out_Of_Service_Set(uint32_t object_instance, bool value) return; } -bool Binary_Input_Object_Name(uint32_t object_instance, - BACNET_CHARACTER_STRING *object_name) +bool Binary_Input_Object_Name( + uint32_t object_instance, BACNET_CHARACTER_STRING *object_name) { static char text_string[32] = ""; /* okay for single thread */ bool status = false; @@ -295,8 +294,8 @@ bool Binary_Input_Object_Name(uint32_t object_instance, index = Binary_Input_Instance_To_Index(object_instance); if (index < MAX_BINARY_INPUTS) { - sprintf(text_string, "BINARY INPUT %lu", - (unsigned long)object_instance); + sprintf( + text_string, "BINARY INPUT %lu", (unsigned long)object_instance); status = characterstring_init_ansi(object_name, text_string); } @@ -316,8 +315,8 @@ BACNET_POLARITY Binary_Input_Polarity(uint32_t object_instance) return polarity; } -bool Binary_Input_Polarity_Set(uint32_t object_instance, - BACNET_POLARITY polarity) +bool Binary_Input_Polarity_Set( + uint32_t object_instance, BACNET_POLARITY polarity) { bool status = false; unsigned index = 0; @@ -413,8 +412,8 @@ bool Binary_Input_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) BACNET_APPLICATION_DATA_VALUE value; /* decode the some of the request */ - len = bacapp_decode_application_data(wp_data->application_data, - wp_data->application_data_len, &value); + len = bacapp_decode_application_data( + wp_data->application_data, wp_data->application_data_len, &value); /* FIXME: len < application_data_len: more data? */ if (len < 0) { /* error while decoding - a value larger than we can handle */ @@ -432,11 +431,10 @@ bool Binary_Input_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) case PROP_PRESENT_VALUE: status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_ENUMERATED, - &wp_data->error_class, &wp_data->error_code); + &wp_data->error_class, &wp_data->error_code); if (status) { if (value.type.Enumerated <= MAX_BINARY_PV) { - Binary_Input_Present_Value_Set( - wp_data->object_instance, + Binary_Input_Present_Value_Set(wp_data->object_instance, (BACNET_BINARY_PV)value.type.Enumerated); } else { status = false; @@ -446,22 +444,20 @@ bool Binary_Input_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) } break; case PROP_OUT_OF_SERVICE: - status = - WPValidateArgType(&value, BACNET_APPLICATION_TAG_BOOLEAN, - &wp_data->error_class, &wp_data->error_code); + status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_BOOLEAN, + &wp_data->error_class, &wp_data->error_code); if (status) { - Binary_Input_Out_Of_Service_Set(wp_data->object_instance, - value.type.Boolean); + Binary_Input_Out_Of_Service_Set( + wp_data->object_instance, value.type.Boolean); } break; case PROP_POLARITY: status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_ENUMERATED, - &wp_data->error_class, &wp_data->error_code); + &wp_data->error_class, &wp_data->error_code); if (status) { if (value.type.Enumerated < MAX_POLARITY) { - Binary_Input_Polarity_Set( - wp_data->object_instance, + Binary_Input_Polarity_Set(wp_data->object_instance, (BACNET_POLARITY)value.type.Enumerated); } else { status = false; @@ -494,8 +490,9 @@ bool Binary_Input_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) #include "ctest.h" bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue, - uint8_t ucExpectedTag, BACNET_ERROR_CLASS *pErrorClass, - BACNET_ERROR_CODE *pErrorCode) + uint8_t ucExpectedTag, + BACNET_ERROR_CLASS *pErrorClass, + BACNET_ERROR_CODE *pErrorCode) { pValue = pValue; ucExpectedTag = ucExpectedTag; @@ -508,7 +505,7 @@ bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue, void testBinaryInput(Test *pTest) { BACNET_READ_PROPERTY_DATA rpdata; - uint8_t apdu[MAX_APDU] = {0}; + uint8_t apdu[MAX_APDU] = { 0 }; int len = 0; uint32_t len_value = 0; uint8_t tag_number = 0; diff --git a/demo/object/bi.h b/src/bacnet/basic/object/bi.h similarity index 97% rename from demo/object/bi.h rename to src/bacnet/basic/object/bi.h index 9b6b29b1..3f22da6e 100644 --- a/demo/object/bi.h +++ b/src/bacnet/basic/object/bi.h @@ -27,10 +27,10 @@ #include #include -#include "bacdef.h" -#include "cov.h" -#include "rp.h" -#include "wp.h" +#include "bacnet/bacdef.h" +#include "bacnet/cov.h" +#include "bacnet/rp.h" +#include "bacnet/wp.h" #ifdef __cplusplus extern "C" { diff --git a/demo/object/bi.mak b/src/bacnet/basic/object/bi.mak similarity index 61% rename from demo/object/bi.mak rename to src/bacnet/basic/object/bi.mak index 2d4c8a54..75c1622e 100644 --- a/demo/object/bi.mak +++ b/src/bacnet/basic/object/bi.mak @@ -8,16 +8,16 @@ DEFINES = -DBIG_ENDIAN=0 -DTEST -DTEST_BINARY_INPUT CFLAGS = -Wall $(INCLUDES) $(DEFINES) -g SRCS = bi.c \ - $(SRC_DIR)/bacdcode.c \ - $(SRC_DIR)/bacint.c \ - $(SRC_DIR)/bacstr.c \ - $(SRC_DIR)/bacreal.c \ - $(SRC_DIR)/bacapp.c \ - $(SRC_DIR)/bacdevobjpropref.c \ - $(SRC_DIR)/bactext.c \ - $(SRC_DIR)/indtext.c \ - $(SRC_DIR)/datetime.c \ - $(SRC_DIR)/lighting.c \ + $(SRC_DIR)/bacnet/bacdcode.c \ + $(SRC_DIR)/bacnet/bacint.c \ + $(SRC_DIR)/bacnet/bacstr.c \ + $(SRC_DIR)/bacnet/bacreal.c \ + $(SRC_DIR)/bacnet/bacapp.c \ + $(SRC_DIR)/bacnet/bacdevobjpropref.c \ + $(SRC_DIR)/bacnet/bactext.c \ + $(SRC_DIR)/bacnet/indtext.c \ + $(SRC_DIR)/bacnet/datetime.c \ + $(SRC_DIR)/bacnet/lighting.c \ $(TEST_DIR)/ctest.c TARGET = binary_input diff --git a/demo/object/bo.c b/src/bacnet/basic/object/bo.c similarity index 85% rename from demo/object/bo.c rename to src/bacnet/basic/object/bo.c index 17cda406..36988785 100644 --- a/demo/object/bo.c +++ b/src/bacnet/basic/object/bo.c @@ -28,15 +28,15 @@ #include #include #include -#include "bacdef.h" -#include "bacdcode.h" -#include "bacenum.h" -#include "bacapp.h" -#include "config.h" /* the custom stuff */ -#include "rp.h" -#include "wp.h" -#include "bo.h" -#include "handlers.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacenum.h" +#include "bacnet/bacapp.h" +#include "bacnet/config.h" /* the custom stuff */ +#include "bacnet/rp.h" +#include "bacnet/wp.h" +#include "bacnet/basic/object/bo.h" +#include "bacnet/basic/services.h" #ifndef MAX_BINARY_OUTPUTS #define MAX_BINARY_OUTPUTS 4 @@ -53,32 +53,28 @@ static BACNET_BINARY_PV Binary_Output_Level[MAX_BINARY_OUTPUTS] static bool Out_Of_Service[MAX_BINARY_OUTPUTS]; /* These three arrays are used by the ReadPropertyMultiple handler */ -static const int Binary_Output_Properties_Required[] = {PROP_OBJECT_IDENTIFIER, - PROP_OBJECT_NAME, - PROP_OBJECT_TYPE, - PROP_PRESENT_VALUE, - PROP_STATUS_FLAGS, - PROP_EVENT_STATE, - PROP_OUT_OF_SERVICE, - PROP_POLARITY, - PROP_PRIORITY_ARRAY, - PROP_RELINQUISH_DEFAULT, - -1}; +static const int Binary_Output_Properties_Required[] = { PROP_OBJECT_IDENTIFIER, + PROP_OBJECT_NAME, PROP_OBJECT_TYPE, PROP_PRESENT_VALUE, PROP_STATUS_FLAGS, + PROP_EVENT_STATE, PROP_OUT_OF_SERVICE, PROP_POLARITY, PROP_PRIORITY_ARRAY, + PROP_RELINQUISH_DEFAULT, -1 }; -static const int Binary_Output_Properties_Optional[] = { - PROP_DESCRIPTION, PROP_ACTIVE_TEXT, PROP_INACTIVE_TEXT, -1}; +static const int Binary_Output_Properties_Optional[] = { PROP_DESCRIPTION, + PROP_ACTIVE_TEXT, PROP_INACTIVE_TEXT, -1 }; -static const int Binary_Output_Properties_Proprietary[] = {-1}; +static const int Binary_Output_Properties_Proprietary[] = { -1 }; -void Binary_Output_Property_Lists(const int **pRequired, const int **pOptional, - const int **pProprietary) +void Binary_Output_Property_Lists( + const int **pRequired, const int **pOptional, const int **pProprietary) { - if (pRequired) + if (pRequired) { *pRequired = Binary_Output_Properties_Required; - if (pOptional) + } + if (pOptional) { *pOptional = Binary_Output_Properties_Optional; - if (pProprietary) + } + if (pProprietary) { *pProprietary = Binary_Output_Properties_Proprietary; + } return; } @@ -107,8 +103,9 @@ void Binary_Output_Init(void) /* given instance exists */ bool Binary_Output_Valid_Instance(uint32_t object_instance) { - if (object_instance < MAX_BINARY_OUTPUTS) + if (object_instance < MAX_BINARY_OUTPUTS) { return true; + } return false; } @@ -135,8 +132,9 @@ unsigned Binary_Output_Instance_To_Index(uint32_t object_instance) { unsigned index = MAX_BINARY_OUTPUTS; - if (object_instance < MAX_BINARY_OUTPUTS) + if (object_instance < MAX_BINARY_OUTPUTS) { index = object_instance; + } return index; } @@ -174,15 +172,15 @@ bool Binary_Output_Out_Of_Service(uint32_t object_instance) } /* note: the object name must be unique within this device */ -bool Binary_Output_Object_Name(uint32_t object_instance, - BACNET_CHARACTER_STRING *object_name) +bool Binary_Output_Object_Name( + uint32_t object_instance, BACNET_CHARACTER_STRING *object_name) { static char text_string[32] = ""; /* okay for single thread */ bool status = false; if (object_instance < MAX_BINARY_OUTPUTS) { - sprintf(text_string, "BINARY OUTPUT %lu", - (unsigned long)object_instance); + sprintf( + text_string, "BINARY OUTPUT %lu", (unsigned long)object_instance); status = characterstring_init_ansi(object_name, text_string); } @@ -255,27 +253,28 @@ int Binary_Output_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) break; case PROP_PRIORITY_ARRAY: /* Array element zero is the number of elements in the array */ - if (rpdata->array_index == 0) + if (rpdata->array_index == 0) { apdu_len = encode_application_unsigned(&apdu[0], BACNET_MAX_PRIORITY); - /* if no index was specified, then try to encode the entire list */ - /* into one packet. */ - else if (rpdata->array_index == BACNET_ARRAY_ALL) { + /* if no index was specified, then try to encode the entire list + */ + /* into one packet. */ + } else if (rpdata->array_index == BACNET_ARRAY_ALL) { object_index = Binary_Output_Instance_To_Index(rpdata->object_instance); for (i = 0; i < BACNET_MAX_PRIORITY; i++) { /* FIXME: check if we have room before adding it to APDU */ - if (Binary_Output_Level[object_index][i] == BINARY_NULL) + if (Binary_Output_Level[object_index][i] == BINARY_NULL) { len = encode_application_null(&apdu[apdu_len]); - else { + } else { present_value = Binary_Output_Level[object_index][i]; - len = encode_application_enumerated(&apdu[apdu_len], - present_value); + len = encode_application_enumerated( + &apdu[apdu_len], present_value); } /* add it if we have room */ - if ((apdu_len + len) < MAX_APDU) + if ((apdu_len + len) < MAX_APDU) { apdu_len += len; - else { + } else { rpdata->error_code = ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED; apdu_len = BACNET_STATUS_ABORT; @@ -287,9 +286,9 @@ int Binary_Output_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) Binary_Output_Instance_To_Index(rpdata->object_instance); if (rpdata->array_index <= BACNET_MAX_PRIORITY) { if (Binary_Output_Level[object_index][rpdata->array_index - - 1] == BINARY_NULL) + 1] == BINARY_NULL) { apdu_len = encode_application_null(&apdu[apdu_len]); - else { + } else { present_value = Binary_Output_Level[object_index] [rpdata->array_index - 1]; @@ -346,8 +345,8 @@ bool Binary_Output_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) BACNET_APPLICATION_DATA_VALUE value; /* decode the some of the request */ - len = bacapp_decode_application_data(wp_data->application_data, - wp_data->application_data_len, &value); + len = bacapp_decode_application_data( + wp_data->application_data, wp_data->application_data_len, &value); /* FIXME: len < application_data_len: more data? */ if (len < 0) { /* error while decoding - a value larger than we can handle */ @@ -396,8 +395,7 @@ bool Binary_Output_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) } } else { status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_NULL, - &wp_data->error_class, - &wp_data->error_code); + &wp_data->error_class, &wp_data->error_code); if (status) { level = BINARY_NULL; object_index = Binary_Output_Instance_To_Index( @@ -422,9 +420,8 @@ bool Binary_Output_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) } break; case PROP_OUT_OF_SERVICE: - status = - WPValidateArgType(&value, BACNET_APPLICATION_TAG_BOOLEAN, - &wp_data->error_class, &wp_data->error_code); + status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_BOOLEAN, + &wp_data->error_class, &wp_data->error_code); if (status) { object_index = Binary_Output_Instance_To_Index(wp_data->object_instance); @@ -460,8 +457,9 @@ bool Binary_Output_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) #include "ctest.h" bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue, - uint8_t ucExpectedTag, BACNET_ERROR_CLASS *pErrorClass, - BACNET_ERROR_CODE *pErrorCode) + uint8_t ucExpectedTag, + BACNET_ERROR_CLASS *pErrorClass, + BACNET_ERROR_CODE *pErrorCode) { pValue = pValue; ucExpectedTag = ucExpectedTag; @@ -473,7 +471,7 @@ bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue, void testBinaryOutput(Test *pTest) { - uint8_t apdu[MAX_APDU] = {0}; + uint8_t apdu[MAX_APDU] = { 0 }; int len = 0; uint32_t len_value = 0; uint8_t tag_number = 0; diff --git a/demo/object/bo.h b/src/bacnet/basic/object/bo.h similarity index 97% rename from demo/object/bo.h rename to src/bacnet/basic/object/bo.h index 3b0cf2e9..6b9b58c0 100644 --- a/demo/object/bo.h +++ b/src/bacnet/basic/object/bo.h @@ -27,10 +27,10 @@ #include #include -#include "bacdef.h" -#include "bacerror.h" -#include "rp.h" -#include "wp.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacerror.h" +#include "bacnet/rp.h" +#include "bacnet/wp.h" #ifdef __cplusplus extern "C" { diff --git a/demo/object/bo.mak b/src/bacnet/basic/object/bo.mak old mode 100755 new mode 100644 similarity index 62% rename from demo/object/bo.mak rename to src/bacnet/basic/object/bo.mak index 06c45c47..0d64492a --- a/demo/object/bo.mak +++ b/src/bacnet/basic/object/bo.mak @@ -8,16 +8,16 @@ DEFINES = -DBIG_ENDIAN=0 -DTEST -DBACAPP_ALL -DTEST_BINARY_OUTPUT CFLAGS = -Wall $(INCLUDES) $(DEFINES) -g SRCS = bo.c \ - $(SRC_DIR)/bacdcode.c \ - $(SRC_DIR)/bacint.c \ - $(SRC_DIR)/bacstr.c \ - $(SRC_DIR)/bacreal.c \ - $(SRC_DIR)/datetime.c \ - $(SRC_DIR)/bacapp.c \ - $(SRC_DIR)/bacdevobjpropref.c \ - $(SRC_DIR)/bactext.c \ - $(SRC_DIR)/lighting.c \ - $(SRC_DIR)/indtext.c \ + $(SRC_DIR)/bacnet/bacdcode.c \ + $(SRC_DIR)/bacnet/bacint.c \ + $(SRC_DIR)/bacnet/bacstr.c \ + $(SRC_DIR)/bacnet/bacreal.c \ + $(SRC_DIR)/bacnet/datetime.c \ + $(SRC_DIR)/bacnet/bacapp.c \ + $(SRC_DIR)/bacnet/bacdevobjpropref.c \ + $(SRC_DIR)/bacnet/bactext.c \ + $(SRC_DIR)/bacnet/lighting.c \ + $(SRC_DIR)/bacnet/indtext.c \ $(TEST_DIR)/ctest.c TARGET = binary_output diff --git a/demo/object/bv.c b/src/bacnet/basic/object/bv.c similarity index 87% rename from demo/object/bv.c rename to src/bacnet/basic/object/bv.c index 40ad3fd3..aa8262d8 100644 --- a/demo/object/bv.c +++ b/src/bacnet/basic/object/bv.c @@ -28,15 +28,15 @@ #include #include #include -#include "bacdef.h" -#include "bacdcode.h" -#include "bacenum.h" -#include "bacapp.h" -#include "config.h" /* the custom stuff */ -#include "wp.h" -#include "rp.h" -#include "bv.h" -#include "handlers.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacenum.h" +#include "bacnet/bacapp.h" +#include "bacnet/config.h" /* the custom stuff */ +#include "bacnet/wp.h" +#include "bacnet/rp.h" +#include "bacnet/basic/object/bv.h" +#include "bacnet/basic/services.h" #ifndef MAX_BINARY_VALUES #define MAX_BINARY_VALUES 10 @@ -53,26 +53,27 @@ static BACNET_BINARY_PV Binary_Value_Level[MAX_BINARY_VALUES] static bool Out_Of_Service[MAX_BINARY_VALUES]; /* These three arrays are used by the ReadPropertyMultiple handler */ -static const int Binary_Value_Properties_Required[] = { - PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME, - PROP_OBJECT_TYPE, PROP_PRESENT_VALUE, - PROP_STATUS_FLAGS, PROP_EVENT_STATE, - PROP_OUT_OF_SERVICE, -1}; +static const int Binary_Value_Properties_Required[] = { PROP_OBJECT_IDENTIFIER, + PROP_OBJECT_NAME, PROP_OBJECT_TYPE, PROP_PRESENT_VALUE, PROP_STATUS_FLAGS, + PROP_EVENT_STATE, PROP_OUT_OF_SERVICE, -1 }; -static const int Binary_Value_Properties_Optional[] = { - PROP_DESCRIPTION, PROP_PRIORITY_ARRAY, PROP_RELINQUISH_DEFAULT, -1}; +static const int Binary_Value_Properties_Optional[] = { PROP_DESCRIPTION, + PROP_PRIORITY_ARRAY, PROP_RELINQUISH_DEFAULT, -1 }; -static const int Binary_Value_Properties_Proprietary[] = {-1}; +static const int Binary_Value_Properties_Proprietary[] = { -1 }; -void Binary_Value_Property_Lists(const int **pRequired, const int **pOptional, - const int **pProprietary) +void Binary_Value_Property_Lists( + const int **pRequired, const int **pOptional, const int **pProprietary) { - if (pRequired) + if (pRequired) { *pRequired = Binary_Value_Properties_Required; - if (pOptional) + } + if (pOptional) { *pOptional = Binary_Value_Properties_Optional; - if (pProprietary) + } + if (pProprietary) { *pProprietary = Binary_Value_Properties_Proprietary; + } return; } @@ -101,8 +102,9 @@ void Binary_Value_Init(void) /* given instance exists */ bool Binary_Value_Valid_Instance(uint32_t object_instance) { - if (object_instance < MAX_BINARY_VALUES) + if (object_instance < MAX_BINARY_VALUES) { return true; + } return false; } @@ -129,8 +131,9 @@ unsigned Binary_Value_Instance_To_Index(uint32_t object_instance) { unsigned index = MAX_BINARY_VALUES; - if (object_instance < MAX_BINARY_VALUES) + if (object_instance < MAX_BINARY_VALUES) { index = object_instance; + } return index; } @@ -155,15 +158,15 @@ BACNET_BINARY_PV Binary_Value_Present_Value(uint32_t object_instance) } /* note: the object name must be unique within this device */ -bool Binary_Value_Object_Name(uint32_t object_instance, - BACNET_CHARACTER_STRING *object_name) +bool Binary_Value_Object_Name( + uint32_t object_instance, BACNET_CHARACTER_STRING *object_name) { static char text_string[32] = ""; /* okay for single thread */ bool status = false; if (object_instance < MAX_BINARY_VALUES) { - sprintf(text_string, "BINARY VALUE %lu", - (unsigned long)object_instance); + sprintf( + text_string, "BINARY VALUE %lu", (unsigned long)object_instance); status = characterstring_init_ansi(object_name, text_string); } @@ -253,27 +256,28 @@ int Binary_Value_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) break; case PROP_PRIORITY_ARRAY: /* Array element zero is the number of elements in the array */ - if (rpdata->array_index == 0) + if (rpdata->array_index == 0) { apdu_len = encode_application_unsigned(&apdu[0], BACNET_MAX_PRIORITY); - /* if no index was specified, then try to encode the entire list */ - /* into one packet. */ - else if (rpdata->array_index == BACNET_ARRAY_ALL) { + /* if no index was specified, then try to encode the entire list + */ + /* into one packet. */ + } else if (rpdata->array_index == BACNET_ARRAY_ALL) { object_index = Binary_Value_Instance_To_Index(rpdata->object_instance); for (i = 0; i < BACNET_MAX_PRIORITY; i++) { /* FIXME: check if we have room before adding it to APDU */ - if (Binary_Value_Level[object_index][i] == BINARY_NULL) + if (Binary_Value_Level[object_index][i] == BINARY_NULL) { len = encode_application_null(&apdu[apdu_len]); - else { + } else { present_value = Binary_Value_Level[object_index][i]; - len = encode_application_enumerated(&apdu[apdu_len], - present_value); + len = encode_application_enumerated( + &apdu[apdu_len], present_value); } /* add it if we have room */ - if ((apdu_len + len) < MAX_APDU) + if ((apdu_len + len) < MAX_APDU) { apdu_len += len; - else { + } else { rpdata->error_code = ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED; apdu_len = BACNET_STATUS_ABORT; @@ -285,9 +289,9 @@ int Binary_Value_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) Binary_Value_Instance_To_Index(rpdata->object_instance); if (rpdata->array_index <= BACNET_MAX_PRIORITY) { if (Binary_Value_Level[object_index][rpdata->array_index] == - BINARY_NULL) + BINARY_NULL) { apdu_len = encode_application_null(&apdu[apdu_len]); - else { + } else { present_value = Binary_Value_Level[object_index] [rpdata->array_index]; apdu_len = encode_application_enumerated( @@ -332,8 +336,8 @@ bool Binary_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) BACNET_APPLICATION_DATA_VALUE value; /* decode the some of the request */ - len = bacapp_decode_application_data(wp_data->application_data, - wp_data->application_data_len, &value); + len = bacapp_decode_application_data( + wp_data->application_data, wp_data->application_data_len, &value); /* FIXME: len < application_data_len: more data? */ if (len < 0) { /* error while decoding - a value larger than we can handle */ @@ -382,8 +386,7 @@ bool Binary_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) } } else { status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_NULL, - &wp_data->error_class, - &wp_data->error_code); + &wp_data->error_class, &wp_data->error_code); if (status) { level = BINARY_NULL; object_index = Binary_Value_Instance_To_Index( @@ -408,12 +411,11 @@ bool Binary_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) } break; case PROP_OUT_OF_SERVICE: - status = - WPValidateArgType(&value, BACNET_APPLICATION_TAG_BOOLEAN, - &wp_data->error_class, &wp_data->error_code); + status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_BOOLEAN, + &wp_data->error_class, &wp_data->error_code); if (status) { - Binary_Value_Out_Of_Service_Set(wp_data->object_instance, - value.type.Boolean); + Binary_Value_Out_Of_Service_Set( + wp_data->object_instance, value.type.Boolean); } break; case PROP_OBJECT_IDENTIFIER: @@ -442,8 +444,9 @@ bool Binary_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) #include "ctest.h" bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue, - uint8_t ucExpectedTag, BACNET_ERROR_CLASS *pErrorClass, - BACNET_ERROR_CODE *pErrorCode) + uint8_t ucExpectedTag, + BACNET_ERROR_CLASS *pErrorClass, + BACNET_ERROR_CODE *pErrorCode) { pValue = pValue; ucExpectedTag = ucExpectedTag; @@ -455,7 +458,7 @@ bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue, void testBinary_Value(Test *pTest) { - uint8_t apdu[MAX_APDU] = {0}; + uint8_t apdu[MAX_APDU] = { 0 }; int len = 0; uint32_t len_value = 0; uint8_t tag_number = 0; diff --git a/demo/object/bv.h b/src/bacnet/basic/object/bv.h similarity index 97% rename from demo/object/bv.h rename to src/bacnet/basic/object/bv.h index d6488f7d..f560ebbe 100644 --- a/demo/object/bv.h +++ b/src/bacnet/basic/object/bv.h @@ -27,10 +27,10 @@ #include #include -#include "bacdef.h" -#include "bacerror.h" -#include "rp.h" -#include "wp.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacerror.h" +#include "bacnet/rp.h" +#include "bacnet/wp.h" #ifdef __cplusplus extern "C" { diff --git a/demo/object/bv.mak b/src/bacnet/basic/object/bv.mak similarity index 62% rename from demo/object/bv.mak rename to src/bacnet/basic/object/bv.mak index 9daee511..75a3af0b 100644 --- a/demo/object/bv.mak +++ b/src/bacnet/basic/object/bv.mak @@ -8,16 +8,16 @@ DEFINES = -DBIG_ENDIAN=0 -DTEST -DBACAPP_ALL -DTEST_BINARY_VALUE CFLAGS = -Wall $(INCLUDES) $(DEFINES) -g SRCS = bv.c \ - $(SRC_DIR)/bacdcode.c \ - $(SRC_DIR)/bacint.c \ - $(SRC_DIR)/bacstr.c \ - $(SRC_DIR)/bacreal.c \ - $(SRC_DIR)/datetime.c \ - $(SRC_DIR)/bacapp.c \ - $(SRC_DIR)/bacdevobjpropref.c \ - $(SRC_DIR)/bactext.c \ - $(SRC_DIR)/indtext.c \ - $(SRC_DIR)/lighting.c \ + $(SRC_DIR)/bacnet/bacdcode.c \ + $(SRC_DIR)/bacnet/bacint.c \ + $(SRC_DIR)/bacnet/bacstr.c \ + $(SRC_DIR)/bacnet/bacreal.c \ + $(SRC_DIR)/bacnet/datetime.c \ + $(SRC_DIR)/bacnet/bacapp.c \ + $(SRC_DIR)/bacnet/bacdevobjpropref.c \ + $(SRC_DIR)/bacnet/bactext.c \ + $(SRC_DIR)/bacnet/indtext.c \ + $(SRC_DIR)/bacnet/lighting.c \ $(TEST_DIR)/ctest.c TARGET = binary_value diff --git a/demo/object/channel.c b/src/bacnet/basic/object/channel.c similarity index 88% rename from demo/object/channel.c rename to src/bacnet/basic/object/channel.c index 7e27ae7c..de7f5dd4 100644 --- a/demo/object/channel.c +++ b/src/bacnet/basic/object/channel.c @@ -35,21 +35,21 @@ #include #include #include -#include "bacdef.h" -#include "bacdcode.h" -#include "bacenum.h" -#include "bacapp.h" -#include "config.h" /* the custom stuff */ -#include "wp.h" -#include "handlers.h" -#include "proplist.h" -#include "lighting.h" -#include "device.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacenum.h" +#include "bacnet/bacapp.h" +#include "bacnet/config.h" /* the custom stuff */ +#include "bacnet/wp.h" +#include "bacnet/basic/services.h" +#include "bacnet/proplist.h" +#include "bacnet/lighting.h" +#include "bacnet/basic/object/device.h" #if defined(CHANNEL_LIGHTING_COMMAND) || defined(BACAPP_LIGHTING_COMMAND) -#include "lo.h" +#include "bacnet/basic/object/lo.h" #endif /* me! */ -#include "channel.h" +#include "bacnet/basic/object/channel.h" #ifndef BACNET_CHANNELS_MAX #define BACNET_CHANNELS_MAX 1 @@ -77,23 +77,15 @@ struct bacnet_channel_object Channel[BACNET_CHANNELS_MAX]; /* These arrays are used by the ReadPropertyMultiple handler property-list property (as of protocol-revision 14) */ -static const int Channel_Properties_Required[] = { - PROP_OBJECT_IDENTIFIER, - PROP_OBJECT_NAME, - PROP_OBJECT_TYPE, - PROP_PRESENT_VALUE, - PROP_LAST_PRIORITY, - PROP_WRITE_STATUS, - PROP_STATUS_FLAGS, - PROP_OUT_OF_SERVICE, - PROP_LIST_OF_OBJECT_PROPERTY_REFERENCES, - PROP_CHANNEL_NUMBER, - PROP_CONTROL_GROUPS, - -1}; +static const int Channel_Properties_Required[] = { PROP_OBJECT_IDENTIFIER, + PROP_OBJECT_NAME, PROP_OBJECT_TYPE, PROP_PRESENT_VALUE, PROP_LAST_PRIORITY, + PROP_WRITE_STATUS, PROP_STATUS_FLAGS, PROP_OUT_OF_SERVICE, + PROP_LIST_OF_OBJECT_PROPERTY_REFERENCES, PROP_CHANNEL_NUMBER, + PROP_CONTROL_GROUPS, -1 }; -static const int Channel_Properties_Optional[] = {-1}; +static const int Channel_Properties_Optional[] = { -1 }; -static const int Channel_Properties_Proprietary[] = {-1}; +static const int Channel_Properties_Proprietary[] = { -1 }; /** * Returns the list of required, optional, and proprietary properties. @@ -106,15 +98,18 @@ static const int Channel_Properties_Proprietary[] = {-1}; * @param pProprietary - pointer to list of int terminated by -1, of * BACnet proprietary properties for this object. */ -void Channel_Property_Lists(const int **pRequired, const int **pOptional, - const int **pProprietary) +void Channel_Property_Lists( + const int **pRequired, const int **pOptional, const int **pProprietary) { - if (pRequired) + if (pRequired) { *pRequired = Channel_Properties_Required; - if (pOptional) + } + if (pOptional) { *pOptional = Channel_Properties_Optional; - if (pProprietary) + } + if (pProprietary) { *pProprietary = Channel_Properties_Proprietary; + } return; } @@ -378,8 +373,8 @@ BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE *Channel_Reference_List_Member_Element( * * @return pointer to member element or NULL if not found */ -bool Channel_Reference_List_Member_Element_Set( - uint32_t object_instance, unsigned array_index, +bool Channel_Reference_List_Member_Element_Set(uint32_t object_instance, + unsigned array_index, BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE *pMemberSrc) { BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE *pMember = NULL; @@ -396,7 +391,7 @@ bool Channel_Reference_List_Member_Element_Set( count++; if (count == array_index) { memcpy(pMember, pMemberSrc, - sizeof(BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE)); + sizeof(BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE)); status = true; break; } @@ -416,8 +411,7 @@ bool Channel_Reference_List_Member_Element_Set( * @return array_index - 1-based array index value for added element, or * zero if not added */ -unsigned Channel_Reference_List_Member_Element_Add( - uint32_t object_instance, +unsigned Channel_Reference_List_Member_Element_Add(uint32_t object_instance, BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE *pMemberSrc) { BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE *pMember = NULL; @@ -435,7 +429,7 @@ unsigned Channel_Reference_List_Member_Element_Add( /* first empty slot */ count++; memcpy(pMember, pMemberSrc, - sizeof(BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE)); + sizeof(BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE)); break; } } @@ -456,11 +450,13 @@ unsigned Channel_Reference_List_Member_Element_Add( * @return array_index - 1-based array index value for added element, or * zero if not added */ -unsigned Channel_Reference_List_Member_Local_Add( - uint32_t object_instance, uint16_t type, uint32_t instance, - BACNET_PROPERTY_ID propertyIdentifier, uint32_t arrayIndex) +unsigned Channel_Reference_List_Member_Local_Add(uint32_t object_instance, + uint16_t type, + uint32_t instance, + BACNET_PROPERTY_ID propertyIdentifier, + uint32_t arrayIndex) { - BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE member = {{0}}; + BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE member = { { 0 } }; member.objectIdentifier.type = type; member.objectIdentifier.instance = instance; @@ -480,8 +476,8 @@ unsigned Channel_Reference_List_Member_Local_Add( * * @return group number in the array */ -uint16_t Channel_Control_Groups_Element(uint32_t object_instance, - int32_t array_index) +uint16_t Channel_Control_Groups_Element( + uint32_t object_instance, int32_t array_index) { unsigned index = 0; uint16_t value = 0; @@ -505,8 +501,8 @@ uint16_t Channel_Control_Groups_Element(uint32_t object_instance, * * @return true if parameters are value and control group is set */ -bool Channel_Control_Groups_Element_Set(uint32_t object_instance, - int32_t array_index, uint16_t value) +bool Channel_Control_Groups_Element_Set( + uint32_t object_instance, int32_t array_index, uint16_t value) { bool status = false; unsigned index = 0; @@ -530,8 +526,8 @@ bool Channel_Control_Groups_Element_Set(uint32_t object_instance, * * @return true if values are able to be copied */ -bool Channel_Value_Copy(BACNET_CHANNEL_VALUE *cvalue, - BACNET_APPLICATION_DATA_VALUE *value) +bool Channel_Value_Copy( + BACNET_CHANNEL_VALUE *cvalue, BACNET_APPLICATION_DATA_VALUE *value) { bool status = false; @@ -583,16 +579,16 @@ bool Channel_Value_Copy(BACNET_CHANNEL_VALUE *cvalue, #if defined(BACAPP_OCTET_STRING) && defined(CHANNEL_OCTET_STRING) case BACNET_APPLICATION_TAG_OCTET_STRING: cvalue->tag = value->tag; - octetstring_copy(&cvalue->type.Octet_String, - &value->type.Octet_String); + octetstring_copy( + &cvalue->type.Octet_String, &value->type.Octet_String); status = true; break; #endif #if defined(BACAPP_CHARACTER_STRING) && defined(CHANNEL_CHARACTER_STRING) case BACNET_APPLICATION_TAG_CHARACTER_STRING: cvalue->tag = value->tag; - characterstring_copy(&cvalue->type.Character_String, - &value->type.Character_String); + characterstring_copy( + &cvalue->type.Character_String, &value->type.Character_String); status = true; break; #endif @@ -635,8 +631,8 @@ bool Channel_Value_Copy(BACNET_CHANNEL_VALUE *cvalue, #if defined(BACAPP_LIGHTING_COMMAND) && defined(CHANNEL_LIGHTING_COMMAND) case BACNET_APPLICATION_TAG_LIGHTING_COMMAND: cvalue->tag = value->tag; - lighting_command_copy(&cvalue->type.Lighting_Command, - &value->type.Lighting_Command); + lighting_command_copy( + &cvalue->type.Lighting_Command, &value->type.Lighting_Command); status = true; break; #endif @@ -656,8 +652,8 @@ bool Channel_Value_Copy(BACNET_CHANNEL_VALUE *cvalue, * * @return number of bytes in the APDU, or BACNET_STATUS_ERROR */ -int Channel_Value_Encode(uint8_t *apdu, int apdu_max, - BACNET_CHANNEL_VALUE *value) +int Channel_Value_Encode( + uint8_t *apdu, int apdu_max, BACNET_CHANNEL_VALUE *value) { int apdu_len = BACNET_STATUS_ERROR; @@ -732,15 +728,15 @@ int Channel_Value_Encode(uint8_t *apdu, int apdu_max, #endif #if defined(CHANNEL_OBJECT_ID) case BACNET_APPLICATION_TAG_OBJECT_ID: - apdu_len = encode_application_object_id( - &apdu[0], (int)value->type.Object_Id.type, + apdu_len = encode_application_object_id(&apdu[0], + (int)value->type.Object_Id.type, value->type.Object_Id.instance); break; #endif #if defined(CHANNEL_LIGHTING_COMMAND) case BACNET_APPLICATION_TAG_LIGHTING_COMMAND: - apdu_len = lighting_command_encode(&apdu[0], - &value->type.Lighting_Command); + apdu_len = lighting_command_encode( + &apdu[0], &value->type.Lighting_Command); break; #endif default: @@ -760,9 +756,10 @@ int Channel_Value_Encode(uint8_t *apdu, int apdu_max, * * @return number of bytes in the APDU, or BACNET_STATUS_ERROR if error. */ -int Channel_Coerce_Data_Encode(uint8_t *apdu, unsigned max_apdu, - BACNET_APPLICATION_DATA_VALUE *value, - BACNET_APPLICATION_TAG tag) +int Channel_Coerce_Data_Encode(uint8_t *apdu, + unsigned max_apdu, + BACNET_APPLICATION_DATA_VALUE *value, + BACNET_APPLICATION_TAG tag) { int apdu_len = 0; /* total length of the apdu, return value */ float float_value = 0.0; @@ -788,8 +785,8 @@ int Channel_Coerce_Data_Encode(uint8_t *apdu, unsigned max_apdu, #if defined(BACAPP_BOOLEAN) case BACNET_APPLICATION_TAG_BOOLEAN: if (tag == BACNET_APPLICATION_TAG_BOOLEAN) { - apdu_len = encode_application_boolean(&apdu[0], - value->type.Boolean); + apdu_len = encode_application_boolean( + &apdu[0], value->type.Boolean); } else if (tag == BACNET_APPLICATION_TAG_UNSIGNED_INT) { if (value->type.Boolean) { unsigned_value = 1; @@ -877,8 +874,8 @@ int Channel_Coerce_Data_Encode(uint8_t *apdu, unsigned max_apdu, if ((value->type.Signed_Int >= 0) && (value->type.Signed_Int <= 2147483647)) { unsigned_value = value->type.Signed_Int; - apdu_len = encode_application_unsigned(&apdu[0], - unsigned_value); + apdu_len = encode_application_unsigned( + &apdu[0], unsigned_value); } else { apdu_len = BACNET_STATUS_ERROR; } @@ -919,8 +916,8 @@ int Channel_Coerce_Data_Encode(uint8_t *apdu, unsigned max_apdu, if ((value->type.Real >= 0.0) && (value->type.Real <= 2147483000.0)) { unsigned_value = (uint32_t)value->type.Real; - apdu_len = encode_application_unsigned(&apdu[0], - unsigned_value); + apdu_len = encode_application_unsigned( + &apdu[0], unsigned_value); } else { apdu_len = BACNET_STATUS_ERROR; } @@ -966,8 +963,8 @@ int Channel_Coerce_Data_Encode(uint8_t *apdu, unsigned max_apdu, if ((value->type.Double >= 0.0) && (value->type.Double <= 2147483000.0)) { unsigned_value = (uint32_t)value->type.Double; - apdu_len = encode_application_unsigned(&apdu[0], - unsigned_value); + apdu_len = encode_application_unsigned( + &apdu[0], unsigned_value); } else { apdu_len = BACNET_STATUS_ERROR; } @@ -1075,44 +1072,44 @@ int Channel_Coerce_Data_Encode(uint8_t *apdu, unsigned max_apdu, * * @return true if values are within range and present-value is sent. */ -bool Channel_Write_Member_Value(BACNET_WRITE_PROPERTY_DATA *wp_data, - BACNET_APPLICATION_DATA_VALUE *value) +bool Channel_Write_Member_Value( + BACNET_WRITE_PROPERTY_DATA *wp_data, BACNET_APPLICATION_DATA_VALUE *value) { bool status = false; int apdu_len = 0; if (wp_data && value) { if (((wp_data->object_type == OBJECT_ANALOG_INPUT) || - (wp_data->object_type == OBJECT_ANALOG_OUTPUT) || - (wp_data->object_type == OBJECT_ANALOG_VALUE)) && + (wp_data->object_type == OBJECT_ANALOG_OUTPUT) || + (wp_data->object_type == OBJECT_ANALOG_VALUE)) && (wp_data->object_property == PROP_PRESENT_VALUE) && (wp_data->array_index == BACNET_ARRAY_ALL)) { - apdu_len = Channel_Coerce_Data_Encode( - wp_data->application_data, wp_data->application_data_len, value, + apdu_len = Channel_Coerce_Data_Encode(wp_data->application_data, + wp_data->application_data_len, value, BACNET_APPLICATION_TAG_REAL); if (apdu_len != BACNET_STATUS_ERROR) { wp_data->application_data_len = apdu_len; status = true; } } else if (((wp_data->object_type == OBJECT_BINARY_INPUT) || - (wp_data->object_type == OBJECT_BINARY_OUTPUT) || - (wp_data->object_type == OBJECT_BINARY_VALUE)) && - (wp_data->object_property == PROP_PRESENT_VALUE) && - (wp_data->array_index == BACNET_ARRAY_ALL)) { - apdu_len = Channel_Coerce_Data_Encode( - wp_data->application_data, wp_data->application_data_len, value, + (wp_data->object_type == OBJECT_BINARY_OUTPUT) || + (wp_data->object_type == OBJECT_BINARY_VALUE)) && + (wp_data->object_property == PROP_PRESENT_VALUE) && + (wp_data->array_index == BACNET_ARRAY_ALL)) { + apdu_len = Channel_Coerce_Data_Encode(wp_data->application_data, + wp_data->application_data_len, value, BACNET_APPLICATION_TAG_ENUMERATED); if (apdu_len != BACNET_STATUS_ERROR) { wp_data->application_data_len = apdu_len; status = true; } } else if (((wp_data->object_type == OBJECT_MULTI_STATE_INPUT) || - (wp_data->object_type == OBJECT_MULTI_STATE_OUTPUT) || - (wp_data->object_type == OBJECT_MULTI_STATE_VALUE)) && - (wp_data->object_property == PROP_PRESENT_VALUE) && - (wp_data->array_index == BACNET_ARRAY_ALL)) { - apdu_len = Channel_Coerce_Data_Encode( - wp_data->application_data, wp_data->application_data_len, value, + (wp_data->object_type == OBJECT_MULTI_STATE_OUTPUT) || + (wp_data->object_type == OBJECT_MULTI_STATE_VALUE)) && + (wp_data->object_property == PROP_PRESENT_VALUE) && + (wp_data->array_index == BACNET_ARRAY_ALL)) { + apdu_len = Channel_Coerce_Data_Encode(wp_data->application_data, + wp_data->application_data_len, value, BACNET_APPLICATION_TAG_UNSIGNED_INT); if (apdu_len != BACNET_STATUS_ERROR) { wp_data->application_data_len = apdu_len; @@ -1121,18 +1118,18 @@ bool Channel_Write_Member_Value(BACNET_WRITE_PROPERTY_DATA *wp_data, } else if (wp_data->object_type == OBJECT_LIGHTING_OUTPUT) { if ((wp_data->object_property == PROP_PRESENT_VALUE) && (wp_data->array_index == BACNET_ARRAY_ALL)) { - apdu_len = Channel_Coerce_Data_Encode( - wp_data->application_data, wp_data->application_data_len, - value, BACNET_APPLICATION_TAG_REAL); + apdu_len = Channel_Coerce_Data_Encode(wp_data->application_data, + wp_data->application_data_len, value, + BACNET_APPLICATION_TAG_REAL); if (apdu_len != BACNET_STATUS_ERROR) { wp_data->application_data_len = apdu_len; status = true; } } else if ((wp_data->object_property == PROP_LIGHTING_COMMAND) && - (wp_data->array_index == BACNET_ARRAY_ALL)) { - apdu_len = Channel_Coerce_Data_Encode( - wp_data->application_data, wp_data->application_data_len, - value, BACNET_APPLICATION_TAG_LIGHTING_COMMAND); + (wp_data->array_index == BACNET_ARRAY_ALL)) { + apdu_len = Channel_Coerce_Data_Encode(wp_data->application_data, + wp_data->application_data_len, value, + BACNET_APPLICATION_TAG_LIGHTING_COMMAND); if (apdu_len != BACNET_STATUS_ERROR) { wp_data->application_data_len = apdu_len; status = true; @@ -1153,10 +1150,10 @@ bool Channel_Write_Member_Value(BACNET_WRITE_PROPERTY_DATA *wp_data, * @return true if values are within range and present-value is sent. */ static bool Channel_Write_Members(struct bacnet_channel_object *pChannel, - BACNET_APPLICATION_DATA_VALUE *value, - uint8_t priority) + BACNET_APPLICATION_DATA_VALUE *value, + uint8_t priority) { - BACNET_WRITE_PROPERTY_DATA wp_data = {0}; + BACNET_WRITE_PROPERTY_DATA wp_data = { 0 }; bool status = false; unsigned m = 0; BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE *pMember = NULL; @@ -1203,8 +1200,8 @@ static bool Channel_Write_Members(struct bacnet_channel_object *pChannel, * * @return true if values are within range and present-value is sent. */ -bool Channel_Present_Value_Set(BACNET_WRITE_PROPERTY_DATA *wp_data, - BACNET_APPLICATION_DATA_VALUE *value) +bool Channel_Present_Value_Set( + BACNET_WRITE_PROPERTY_DATA *wp_data, BACNET_APPLICATION_DATA_VALUE *value) { unsigned index = 0; bool status = false; @@ -1216,8 +1213,8 @@ bool Channel_Present_Value_Set(BACNET_WRITE_PROPERTY_DATA *wp_data, if (wp_data->priority != 6 /* reserved */) { status = Channel_Value_Copy(&Channel[index].Present_Value, value); - status = Channel_Write_Members(&Channel[index], value, - wp_data->priority); + status = Channel_Write_Members( + &Channel[index], value, wp_data->priority); status = true; } else { /* Command priority 6 is reserved for use by Minimum On/Off @@ -1245,8 +1242,8 @@ bool Channel_Present_Value_Set(BACNET_WRITE_PROPERTY_DATA *wp_data, * * @return true if object-name was retrieved */ -bool Channel_Object_Name(uint32_t object_instance, - BACNET_CHARACTER_STRING *object_name) +bool Channel_Object_Name( + uint32_t object_instance, BACNET_CHARACTER_STRING *object_name) { char text_string[32] = ""; bool status = false; @@ -1331,8 +1328,8 @@ int Channel_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) apdu = rpdata->application_data; switch (rpdata->object_property) { case PROP_OBJECT_IDENTIFIER: - apdu_len = encode_application_object_id(&apdu[0], OBJECT_CHANNEL, - rpdata->object_instance); + apdu_len = encode_application_object_id( + &apdu[0], OBJECT_CHANNEL, rpdata->object_instance); break; case PROP_OBJECT_NAME: Channel_Object_Name(rpdata->object_instance, &char_string); @@ -1386,8 +1383,8 @@ int Channel_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) for (i = 1; i <= count; i++) { pMember = Channel_Reference_List_Member_Element( rpdata->object_instance, i); - len = bacapp_encode_device_obj_property_ref(&apdu[apdu_len], - pMember); + len = bacapp_encode_device_obj_property_ref( + &apdu[apdu_len], pMember); /* add it if we have room */ if ((apdu_len + len) < MAX_APDU) { apdu_len += len; @@ -1405,8 +1402,8 @@ int Channel_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) if (rpdata->array_index <= count) { pMember = Channel_Reference_List_Member_Element( rpdata->object_instance, rpdata->array_index); - apdu_len += bacapp_encode_device_obj_property_ref(&apdu[0], - pMember); + apdu_len += bacapp_encode_device_obj_property_ref( + &apdu[0], pMember); } else { rpdata->error_class = ERROR_CLASS_PROPERTY; rpdata->error_code = ERROR_CODE_INVALID_ARRAY_INDEX; @@ -1430,8 +1427,8 @@ int Channel_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) for (i = 1; i <= CONTROL_GROUPS_MAX; i++) { unsigned_value = Channel_Control_Groups_Element( rpdata->object_instance, i); - len = encode_application_unsigned(&apdu[apdu_len], - unsigned_value); + len = encode_application_unsigned( + &apdu[apdu_len], unsigned_value); /* add it if we have room */ if ((apdu_len + len) < MAX_APDU) { apdu_len += len; @@ -1447,8 +1444,8 @@ int Channel_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) if (rpdata->array_index <= CONTROL_GROUPS_MAX) { unsigned_value = Channel_Control_Groups_Element( rpdata->object_instance, rpdata->array_index); - apdu_len = encode_application_unsigned(&apdu[apdu_len], - unsigned_value); + apdu_len = encode_application_unsigned( + &apdu[apdu_len], unsigned_value); } else { rpdata->error_class = ERROR_CLASS_PROPERTY; rpdata->error_code = ERROR_CODE_INVALID_ARRAY_INDEX; @@ -1493,8 +1490,8 @@ bool Channel_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) uint32_t array_index = 0; /* decode the some of the request */ - len = bacapp_decode_application_data(wp_data->application_data, - wp_data->application_data_len, &value); + len = bacapp_decode_application_data( + wp_data->application_data, wp_data->application_data_len, &value); /* FIXME: len < application_data_len: more data? */ if (len < 0) { /* error while decoding - a value larger than we can handle */ @@ -1514,12 +1511,11 @@ bool Channel_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) status = Channel_Present_Value_Set(wp_data, &value); break; case PROP_OUT_OF_SERVICE: - status = - WPValidateArgType(&value, BACNET_APPLICATION_TAG_BOOLEAN, - &wp_data->error_class, &wp_data->error_code); + status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_BOOLEAN, + &wp_data->error_class, &wp_data->error_code); if (status) { - Channel_Out_Of_Service_Set(wp_data->object_instance, - value.type.Boolean); + Channel_Out_Of_Service_Set( + wp_data->object_instance, value.type.Boolean); } break; case PROP_LIST_OF_OBJECT_PROPERTY_REFERENCES: @@ -1535,10 +1531,10 @@ bool Channel_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) case PROP_CHANNEL_NUMBER: status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_UNSIGNED_INT, - &wp_data->error_class, &wp_data->error_code); + &wp_data->error_class, &wp_data->error_code); if (status) { - Channel_Number_Set(wp_data->object_instance, - value.type.Unsigned_Int); + Channel_Number_Set( + wp_data->object_instance, value.type.Unsigned_Int); } break; case PROP_CONTROL_GROUPS: @@ -1556,7 +1552,7 @@ bool Channel_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) do { if ((element_len > 0) && (value.tag == - BACNET_APPLICATION_TAG_UNSIGNED_INT)) { + BACNET_APPLICATION_TAG_UNSIGNED_INT)) { if ((wp_data->array_index <= CONTROL_GROUPS_MAX) && (value.type.Unsigned_Int <= 65535)) { status = Channel_Control_Groups_Element_Set( diff --git a/demo/object/channel.h b/src/bacnet/basic/object/channel.h similarity index 98% rename from demo/object/channel.h rename to src/bacnet/basic/object/channel.h index ed2612ff..d8a87f09 100644 --- a/demo/object/channel.h +++ b/src/bacnet/basic/object/channel.h @@ -36,10 +36,10 @@ #include #include -#include "bacdef.h" -#include "rp.h" -#include "wp.h" -#include "lo.h" +#include "bacnet/bacdef.h" +#include "bacnet/rp.h" +#include "bacnet/wp.h" +#include "bacnet/basic/object/lo.h" #ifdef __cplusplus extern "C" { diff --git a/demo/object/device-client.c b/src/bacnet/basic/object/client/device-client.c similarity index 81% rename from demo/object/device-client.c rename to src/bacnet/basic/object/client/device-client.c index dc2916c2..f20f70ef 100644 --- a/demo/object/device-client.c +++ b/src/bacnet/basic/object/client/device-client.c @@ -31,27 +31,27 @@ #include #include #include /* for memmove */ -#include /* for timezone, localtime */ +#include /* for timezone, localtime */ /* OS specific include*/ -#include "net.h" -#include "timer.h" +#include "bacport.h" +#include "bacnet/basic/sys/mstimer.h" /* BACnet includes */ -#include "bacdef.h" -#include "bacdcode.h" -#include "bacenum.h" -#include "bacapp.h" -#include "config.h" /* the custom stuff */ -#include "apdu.h" -#include "rp.h" /* ReadProperty handling */ -#include "version.h" -#include "handlers.h" -#include "datalink.h" -#include "address.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacenum.h" +#include "bacnet/bacapp.h" +#include "bacnet/config.h" /* the custom stuff */ +#include "bacnet/apdu.h" +#include "bacnet/rp.h" /* ReadProperty handling */ +#include "bacnet/version.h" +#include "bacnet/basic/services.h" +#include "bacnet/datalink/datalink.h" +#include "bacnet/basic/binding/address.h" #if (BACNET_PROTOCOL_REVISION >= 17) -#include "netport.h" +#include "bacnet/basic/object/netport.h" #endif /* include the device object */ -#include "device.h" /* me */ +#include "bacnet/basic/object/device.h" /* me */ #if defined(__BORLANDC__) || defined(_WIN32) /* seems to not be defined in time.h as specified by The Open Group */ @@ -71,6 +71,7 @@ static char *Vendor_Name = BACNET_VENDOR_NAME; static uint16_t Vendor_Identifier = BACNET_VENDOR_ID; static char *Model_Name = "GNU"; static char *Application_Software_Version = "1.0"; +static const char *BACnet_Version = BACNET_VERSION_TEXT; static char *Location = "USA"; static char *Description = "command line client"; /* static uint8_t Protocol_Version = 1; - constant, not settable */ @@ -119,27 +120,29 @@ extern bool Routed_Device_Write_Property_Local( /* All included BACnet objects */ static object_functions_t Object_Table[] = { - {OBJECT_DEVICE, NULL /* Init - don't init Device or it will recourse! */, - Device_Count, Device_Index_To_Instance, - Device_Valid_Object_Instance_Number, Device_Object_Name, - Device_Read_Property_Local, NULL /* Write_Property */, - NULL /* Property_Lists */, NULL /* ReadRangeInfo */, NULL /* Iterator */, - NULL /* Value_Lists */, NULL /* COV */, NULL /* COV Clear */, - NULL /* Intrinsic Reporting */}, + { OBJECT_DEVICE, NULL /* Init - don't init Device or it will recourse! */, + Device_Count, Device_Index_To_Instance, + Device_Valid_Object_Instance_Number, Device_Object_Name, + Device_Read_Property_Local, NULL /* Write_Property */, + NULL /* Property_Lists */, NULL /* ReadRangeInfo */, + NULL /* Iterator */, NULL /* Value_Lists */, NULL /* COV */, + NULL /* COV Clear */, NULL /* Intrinsic Reporting */ }, #if (BACNET_PROTOCOL_REVISION >= 17) - {OBJECT_NETWORK_PORT, Network_Port_Init, Network_Port_Count, - Network_Port_Index_To_Instance, Network_Port_Valid_Instance, - Network_Port_Object_Name, Network_Port_Read_Property, - Network_Port_Write_Property, Network_Port_Property_Lists, - NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */, - NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */}, + { OBJECT_NETWORK_PORT, Network_Port_Init, Network_Port_Count, + Network_Port_Index_To_Instance, Network_Port_Valid_Instance, + Network_Port_Object_Name, Network_Port_Read_Property, + Network_Port_Write_Property, Network_Port_Property_Lists, + NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */, + NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */ }, #endif - {MAX_BACNET_OBJECT_TYPE, NULL /* Init */, NULL /* Count */, - NULL /* Index_To_Instance */, NULL /* Valid_Instance */, - NULL /* Object_Name */, NULL /* Read_Property */, - NULL /* Write_Property */, NULL /* Property_Lists */, - NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */, - NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */}}; + { MAX_BACNET_OBJECT_TYPE, NULL /* Init */, NULL /* Count */, + NULL /* Index_To_Instance */, NULL /* Valid_Instance */, + NULL /* Object_Name */, NULL /* Read_Property */, + NULL /* Write_Property */, NULL /* Property_Lists */, + NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */, + NULL /* COV */, NULL /* COV Clear */, + NULL /* Intrinsic Reporting */ } +}; /** Glue function to let the Device object, when called by a handler, * lookup which Object type needs to be invoked. @@ -167,6 +170,92 @@ static struct object_functions *Device_Objects_Find_Functions( return (NULL); } +/** For a given object type, returns the special property list. + * This function is used for ReadPropertyMultiple calls which want + * just Required, just Optional, or All properties. + * @ingroup ObjIntf + * + * @param object_type [in] The desired BACNET_OBJECT_TYPE whose properties + * are to be listed. + * @param pPropertyList [out] Reference to the structure which will, on return, + * list, separately, the Required, Optional, and Proprietary object + * properties with their counts. + */ +void Device_Objects_Property_List(BACNET_OBJECT_TYPE object_type, + uint32_t object_instance, + struct special_property_list_t *pPropertyList) +{ + struct object_functions *pObject = NULL; + + (void)object_instance; + pPropertyList->Required.pList = NULL; + pPropertyList->Optional.pList = NULL; + pPropertyList->Proprietary.pList = NULL; + + /* If we can find an entry for the required object type + * and there is an Object_List_RPM fn ptr then call it + * to populate the pointers to the individual list counters. + */ + + pObject = Device_Objects_Find_Functions(object_type); + if ((pObject != NULL) && (pObject->Object_RPM_List != NULL)) { + pObject->Object_RPM_List(&pPropertyList->Required.pList, + &pPropertyList->Optional.pList, &pPropertyList->Proprietary.pList); + } + + /* Fetch the counts if available otherwise zero them */ + pPropertyList->Required.count = pPropertyList->Required.pList == NULL + ? 0 + : property_list_count(pPropertyList->Required.pList); + + pPropertyList->Optional.count = pPropertyList->Optional.pList == NULL + ? 0 + : property_list_count(pPropertyList->Optional.pList); + + pPropertyList->Proprietary.count = pPropertyList->Proprietary.pList == NULL + ? 0 + : property_list_count(pPropertyList->Proprietary.pList); + + return; +} + +/* These three arrays are used by the ReadPropertyMultiple handler */ +static const int Device_Properties_Required[] = { PROP_OBJECT_IDENTIFIER, + PROP_OBJECT_NAME, PROP_OBJECT_TYPE, PROP_SYSTEM_STATUS, PROP_VENDOR_NAME, + PROP_VENDOR_IDENTIFIER, PROP_MODEL_NAME, PROP_FIRMWARE_REVISION, + PROP_APPLICATION_SOFTWARE_VERSION, PROP_PROTOCOL_VERSION, + PROP_PROTOCOL_REVISION, PROP_PROTOCOL_SERVICES_SUPPORTED, + PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED, PROP_OBJECT_LIST, + PROP_MAX_APDU_LENGTH_ACCEPTED, PROP_SEGMENTATION_SUPPORTED, + PROP_APDU_TIMEOUT, PROP_NUMBER_OF_APDU_RETRIES, PROP_DEVICE_ADDRESS_BINDING, + PROP_DATABASE_REVISION, -1 }; + +static const int Device_Properties_Optional[] = { +#if defined(BACDL_MSTP) + PROP_MAX_MASTER, PROP_MAX_INFO_FRAMES, +#endif + PROP_DESCRIPTION, PROP_LOCATION, PROP_ACTIVE_COV_SUBSCRIPTIONS, + -1 +}; + +static const int Device_Properties_Proprietary[] = { -1 }; + +void Device_Property_Lists( + const int **pRequired, const int **pOptional, const int **pProprietary) +{ + if (pRequired) { + *pRequired = Device_Properties_Required; + } + if (pOptional) { + *pOptional = Device_Properties_Optional; + } + if (pProprietary) { + *pProprietary = Device_Properties_Proprietary; + } + + return; +} + unsigned Device_Count(void) { return 1; @@ -203,8 +292,9 @@ bool Device_Set_Object_Instance_Number(uint32_t object_id) /* Make the change and update the database revision */ Object_Instance_Number = object_id; Device_Inc_Database_Revision(); - } else + } else { status = false; + } return status; } @@ -214,8 +304,8 @@ bool Device_Valid_Object_Instance_Number(uint32_t object_id) return (Object_Instance_Number == object_id); } -bool Device_Object_Name(uint32_t object_instance, - BACNET_CHARACTER_STRING *object_name) +bool Device_Object_Name( + uint32_t object_instance, BACNET_CHARACTER_STRING *object_name) { bool status = false; @@ -471,8 +561,8 @@ unsigned Device_Object_List_Count(void) * @param instance [out] The object's instance number, if found. * @return True if found, else false. */ -bool Device_Object_List_Identifier(uint32_t array_index, int *object_type, - uint32_t *instance) +bool Device_Object_List_Identifier( + uint32_t array_index, int *object_type, uint32_t *instance) { bool status = false; unsigned count = 0; @@ -530,7 +620,8 @@ bool Device_Object_List_Identifier(uint32_t array_index, int *object_type, * @return True on success or else False if not found. */ bool Device_Valid_Object_Name(BACNET_CHARACTER_STRING *object_name1, - int *object_type, uint32_t *object_instance) + int *object_type, + uint32_t *object_instance) { bool found = false; int type = 0; @@ -547,7 +638,7 @@ bool Device_Valid_Object_Name(BACNET_CHARACTER_STRING *object_name1, pObject = Device_Objects_Find_Functions(type); if ((pObject != NULL) && (pObject->Object_Name != NULL) && (pObject->Object_Name(instance, &object_name2) && - characterstring_same(object_name1, &object_name2))) { + characterstring_same(object_name1, &object_name2))) { found = true; if (object_type) { *object_type = type; @@ -588,8 +679,8 @@ bool Device_Valid_Object_Id(int object_type, uint32_t object_instance) * @return True on success or else False if not found. */ bool Device_Object_Name_Copy(BACNET_OBJECT_TYPE object_type, - uint32_t object_instance, - BACNET_CHARACTER_STRING *object_name) + uint32_t object_instance, + BACNET_CHARACTER_STRING *object_name) { struct object_functions *pObject = NULL; bool found = false; @@ -634,15 +725,14 @@ int tm_isdst Daylight Savings flag. if (tblock) { datetime_set_date(&Local_Date, (uint16_t)tblock->tm_year + 1900, - (uint8_t)tblock->tm_mon + 1, - (uint8_t)tblock->tm_mday); + (uint8_t)tblock->tm_mon + 1, (uint8_t)tblock->tm_mday); #if !defined(_MSC_VER) datetime_set_time(&Local_Time, (uint8_t)tblock->tm_hour, - (uint8_t)tblock->tm_min, (uint8_t)tblock->tm_sec, - (uint8_t)(tv.tv_usec / 10000)); + (uint8_t)tblock->tm_min, (uint8_t)tblock->tm_sec, + (uint8_t)(tv.tv_usec / 10000)); #else datetime_set_time(&Local_Time, (uint8_t)tblock->tm_hour, - (uint8_t)tblock->tm_min, (uint8_t)tblock->tm_sec, 0); + (uint8_t)tblock->tm_min, (uint8_t)tblock->tm_sec, 0); #endif if (tblock->tm_isdst) { Daylight_Savings_Status = true; @@ -757,7 +847,7 @@ uint32_t Device_Interval_Offset(void) int Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA *rpdata) { int apdu_len = 0; /* return value */ - int len = 0; /* apdu len intermediate value */ + int len = 0; /* apdu len intermediate value */ BACNET_BIT_STRING bit_string; BACNET_CHARACTER_STRING char_string; uint32_t i = 0; @@ -775,8 +865,8 @@ int Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA *rpdata) apdu = rpdata->application_data; switch (rpdata->object_property) { case PROP_OBJECT_IDENTIFIER: - apdu_len = encode_application_object_id(&apdu[0], OBJECT_DEVICE, - Object_Instance_Number); + apdu_len = encode_application_object_id( + &apdu[0], OBJECT_DEVICE, Object_Instance_Number); break; case PROP_OBJECT_NAME: apdu_len = @@ -812,8 +902,8 @@ int Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA *rpdata) encode_application_character_string(&apdu[0], &char_string); break; case PROP_APPLICATION_SOFTWARE_VERSION: - characterstring_init_ansi(&char_string, - Application_Software_Version); + characterstring_init_ansi( + &char_string, Application_Software_Version); apdu_len = encode_application_character_string(&apdu[0], &char_string); break; @@ -823,20 +913,19 @@ int Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA *rpdata) encode_application_character_string(&apdu[0], &char_string); break; case PROP_PROTOCOL_VERSION: - apdu_len = encode_application_unsigned(&apdu[0], - Device_Protocol_Version()); + apdu_len = encode_application_unsigned( + &apdu[0], Device_Protocol_Version()); break; case PROP_PROTOCOL_REVISION: - apdu_len = encode_application_unsigned(&apdu[0], - Device_Protocol_Revision()); + apdu_len = encode_application_unsigned( + &apdu[0], Device_Protocol_Revision()); break; case PROP_PROTOCOL_SERVICES_SUPPORTED: /* Note: list of services that are executed, not initiated. */ bitstring_init(&bit_string); for (i = 0; i < MAX_BACNET_SERVICES_SUPPORTED; i++) { /* automatic lookup based on handlers set */ - bitstring_set_bit( - &bit_string, (uint8_t)i, + bitstring_set_bit(&bit_string, (uint8_t)i, apdu_service_supported((BACNET_SERVICES_SUPPORTED)i)); } apdu_len = encode_application_bitstring(&apdu[0], &bit_string); @@ -863,16 +952,18 @@ int Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA *rpdata) case PROP_OBJECT_LIST: count = Device_Object_List_Count(); /* Array element zero is the number of objects in the list */ - if (rpdata->array_index == 0) + if (rpdata->array_index == 0) { apdu_len = encode_application_unsigned(&apdu[0], count); - /* if no index was specified, then try to encode the entire list */ - /* into one packet. Note that more than likely you will have */ - /* to return an error if the number of encoded objects exceeds */ - /* your maximum APDU size. */ - else if (rpdata->array_index == BACNET_ARRAY_ALL) { + /* if no index was specified, then try to encode the entire list + */ + /* into one packet. Note that more than likely you will have */ + /* to return an error if the number of encoded objects exceeds + */ + /* your maximum APDU size. */ + } else if (rpdata->array_index == BACNET_ARRAY_ALL) { for (i = 1; i <= count; i++) { - found = Device_Object_List_Identifier(i, &object_type, - &instance); + found = Device_Object_List_Identifier( + i, &object_type, &instance); if (found) { len = encode_application_object_id( &apdu[apdu_len], object_type, instance); @@ -896,8 +987,8 @@ int Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA *rpdata) } } } else { - found = Device_Object_List_Identifier(rpdata->array_index, - &object_type, &instance); + found = Device_Object_List_Identifier( + rpdata->array_index, &object_type, &instance); if (found) { apdu_len = encode_application_object_id( &apdu[0], object_type, instance); diff --git a/demo/object/command.c b/src/bacnet/basic/object/command.c similarity index 81% rename from demo/object/command.c rename to src/bacnet/basic/object/command.c index 30ce1c2d..d223acc1 100644 --- a/demo/object/command.c +++ b/src/bacnet/basic/object/command.c @@ -43,16 +43,16 @@ #include #include -#include "bacdef.h" -#include "bacdcode.h" -#include "bacenum.h" -#include "bactext.h" -#include "config.h" /* the custom stuff */ -#include "device.h" -#include "handlers.h" -#include "proplist.h" -#include "timestamp.h" -#include "command.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacenum.h" +#include "bacnet/bactext.h" +#include "bacnet/config.h" /* the custom stuff */ +#include "bacnet/basic/object/device.h" +#include "bacnet/basic/services.h" +#include "bacnet/proplist.h" +#include "bacnet/timestamp.h" +#include "bacnet/basic/object/command.h" /*BACnetActionCommand ::= SEQUENCE { deviceIdentifier [0] BACnetObjectIdentifier OPTIONAL, @@ -73,28 +73,32 @@ int cl_encode_apdu(uint8_t *apdu, BACNET_ACTION_LIST *bcl) if (bcl->Device_Id.instance >= 0 && bcl->Device_Id.instance <= BACNET_MAX_INSTANCE) { - len = encode_context_object_id(&apdu[apdu_len], 0, bcl->Device_Id.type, - bcl->Device_Id.instance); - if (len < 0) + len = encode_context_object_id( + &apdu[apdu_len], 0, bcl->Device_Id.type, bcl->Device_Id.instance); + if (len < 0) { return BACNET_STATUS_REJECT; + } apdu_len += len; } /* TODO: Check for object type and instance limits */ - len = encode_context_object_id(&apdu[apdu_len], 1, bcl->Object_Id.type, - bcl->Object_Id.instance); - if (len < 0) + len = encode_context_object_id( + &apdu[apdu_len], 1, bcl->Object_Id.type, bcl->Object_Id.instance); + if (len < 0) { return BACNET_STATUS_REJECT; + } apdu_len += len; len = encode_context_enumerated(&apdu[apdu_len], 2, bcl->Property_Identifier); - if (len < 0) + if (len < 0) { return BACNET_STATUS_REJECT; + } apdu_len += len; if (bcl->Property_Array_Index != BACNET_ARRAY_ALL) { - len = encode_context_unsigned(&apdu[apdu_len], 3, - bcl->Property_Array_Index); - if (len < 0) + len = encode_context_unsigned( + &apdu[apdu_len], 3, bcl->Property_Array_Index); + if (len < 0) { return BACNET_STATUS_REJECT; + } apdu_len += len; } @@ -108,44 +112,53 @@ int cl_encode_apdu(uint8_t *apdu, BACNET_ACTION_LIST *bcl) September 2016 */ len = encode_opening_tag(&apdu[apdu_len], 4); - if (len < 0) + if (len < 0) { return BACNET_STATUS_REJECT; + } apdu_len += len; len = bacapp_encode_application_data(&apdu[apdu_len], &bcl->Value); - if (len < 0) + if (len < 0) { return BACNET_STATUS_REJECT; + } apdu_len += len; len = encode_closing_tag(&apdu[apdu_len], 4); - if (len < 0) + if (len < 0) { return BACNET_STATUS_REJECT; + } apdu_len += len; if (bcl->Priority != BACNET_NO_PRIORITY) { len = encode_context_unsigned(&apdu[apdu_len], 5, bcl->Priority); - if (len < 0) + if (len < 0) { return BACNET_STATUS_REJECT; + } apdu_len += len; } if (bcl->Post_Delay != 0xFFFFFFFFU) { len = encode_context_unsigned(&apdu[apdu_len], 6, bcl->Post_Delay); - if (len < 0) + if (len < 0) { return BACNET_STATUS_REJECT; + } apdu_len += len; } len = encode_context_boolean(&apdu[apdu_len], 7, bcl->Quit_On_Failure); - if (len < 0) + if (len < 0) { return BACNET_STATUS_REJECT; + } apdu_len += len; len = encode_context_boolean(&apdu[apdu_len], 8, bcl->Write_Successful); - if (len < 0) + if (len < 0) { return BACNET_STATUS_REJECT; + } apdu_len += len; return apdu_len; } -int cl_decode_apdu(uint8_t *apdu, unsigned apdu_len, BACNET_APPLICATION_TAG tag, - BACNET_ACTION_LIST *bcl) +int cl_decode_apdu(uint8_t *apdu, + unsigned apdu_len, + BACNET_APPLICATION_TAG tag, + BACNET_ACTION_LIST *bcl) { int len = 0; int dec_len = 0; @@ -155,45 +168,53 @@ int cl_decode_apdu(uint8_t *apdu, unsigned apdu_len, BACNET_APPLICATION_TAG tag, if (decode_is_context_tag(&apdu[dec_len], 0)) { /* Tag 0: Device ID */ dec_len++; - len = decode_object_id(&apdu[dec_len], &bcl->Device_Id.type, - &bcl->Device_Id.instance); - if (len < 0) + len = decode_object_id( + &apdu[dec_len], &bcl->Device_Id.type, &bcl->Device_Id.instance); + if (len < 0) { return BACNET_STATUS_REJECT; + } dec_len += len; } - if (!decode_is_context_tag(&apdu[dec_len++], 1)) + if (!decode_is_context_tag(&apdu[dec_len++], 1)) { return BACNET_STATUS_REJECT; - len = decode_object_id(&apdu[dec_len], &bcl->Object_Id.type, - &bcl->Object_Id.instance); - if (len < 0) + } + len = decode_object_id( + &apdu[dec_len], &bcl->Object_Id.type, &bcl->Object_Id.instance); + if (len < 0) { return BACNET_STATUS_REJECT; + } dec_len += len; - len = decode_tag_number_and_value(&apdu[dec_len], &tag_number, - &len_value_type); - if (len < 0) + len = decode_tag_number_and_value( + &apdu[dec_len], &tag_number, &len_value_type); + if (len < 0) { return BACNET_STATUS_REJECT; + } dec_len += len; - if (tag_number != 2) + if (tag_number != 2) { return BACNET_STATUS_REJECT; - len = decode_enumerated(&apdu[dec_len], len_value_type, - &bcl->Property_Identifier); - if (len < 0) + } + len = decode_enumerated( + &apdu[dec_len], len_value_type, &bcl->Property_Identifier); + if (len < 0) { return BACNET_STATUS_REJECT; + } dec_len += len; if (decode_is_context_tag(&apdu[dec_len], 3)) { - len = decode_tag_number_and_value(&apdu[dec_len], &tag_number, - &len_value_type); + len = decode_tag_number_and_value( + &apdu[dec_len], &tag_number, &len_value_type); dec_len += len; - len = decode_unsigned(&apdu[dec_len], len_value_type, - &bcl->Property_Array_Index); - if (len < 0) + len = decode_unsigned( + &apdu[dec_len], len_value_type, &bcl->Property_Array_Index); + if (len < 0) { return BACNET_STATUS_REJECT; + } dec_len += len; } else { bcl->Property_Array_Index = BACNET_ARRAY_ALL; } - if (!decode_is_context_tag(&apdu[dec_len], 4)) + if (!decode_is_context_tag(&apdu[dec_len], 4)) { return BACNET_STATUS_REJECT; + } bcl->Value.context_specific = true; bcl->Value.context_tag = 4; bcl->Value.tag = tag; @@ -202,82 +223,85 @@ int cl_decode_apdu(uint8_t *apdu, unsigned apdu_len, BACNET_APPLICATION_TAG tag, len = 1; break; case BACNET_APPLICATION_TAG_BOOLEAN: - len = decode_context_boolean2(&apdu[dec_len], 4, - &bcl->Value.type.Boolean); + len = decode_context_boolean2( + &apdu[dec_len], 4, &bcl->Value.type.Boolean); break; case BACNET_APPLICATION_TAG_UNSIGNED_INT: - len = decode_context_unsigned(&apdu[dec_len], 4, - &bcl->Value.type.Unsigned_Int); + len = decode_context_unsigned( + &apdu[dec_len], 4, &bcl->Value.type.Unsigned_Int); break; case BACNET_APPLICATION_TAG_SIGNED_INT: - len = decode_context_signed(&apdu[dec_len], 4, - &bcl->Value.type.Signed_Int); + len = decode_context_signed( + &apdu[dec_len], 4, &bcl->Value.type.Signed_Int); break; case BACNET_APPLICATION_TAG_REAL: len = decode_context_real(&apdu[dec_len], 4, &bcl->Value.type.Real); break; case BACNET_APPLICATION_TAG_DOUBLE: - len = decode_context_double(&apdu[dec_len], 4, - &bcl->Value.type.Double); + len = decode_context_double( + &apdu[dec_len], 4, &bcl->Value.type.Double); break; case BACNET_APPLICATION_TAG_OCTET_STRING: - len = decode_context_octet_string(&apdu[dec_len], 4, - &bcl->Value.type.Octet_String); + len = decode_context_octet_string( + &apdu[dec_len], 4, &bcl->Value.type.Octet_String); break; case BACNET_APPLICATION_TAG_CHARACTER_STRING: len = decode_context_character_string( &apdu[dec_len], 4, &bcl->Value.type.Character_String); break; case BACNET_APPLICATION_TAG_BIT_STRING: - len = decode_context_bitstring(&apdu[dec_len], 4, - &bcl->Value.type.Bit_String); + len = decode_context_bitstring( + &apdu[dec_len], 4, &bcl->Value.type.Bit_String); break; case BACNET_APPLICATION_TAG_ENUMERATED: - len = decode_context_enumerated(&apdu[dec_len], 4, - &bcl->Value.type.Enumerated); + len = decode_context_enumerated( + &apdu[dec_len], 4, &bcl->Value.type.Enumerated); break; case BACNET_APPLICATION_TAG_DATE: len = decode_context_date(&apdu[dec_len], 4, &bcl->Value.type.Date); break; case BACNET_APPLICATION_TAG_TIME: - len = decode_context_bacnet_time(&apdu[dec_len], 4, - &bcl->Value.type.Time); + len = decode_context_bacnet_time( + &apdu[dec_len], 4, &bcl->Value.type.Time); break; case BACNET_APPLICATION_TAG_OBJECT_ID: len = decode_context_object_id(&apdu[dec_len], 4, - &bcl->Value.type.Object_Id.type, - &bcl->Value.type.Object_Id.instance); + &bcl->Value.type.Object_Id.type, + &bcl->Value.type.Object_Id.instance); break; case BACNET_APPLICATION_TAG_LIGHTING_COMMAND: len = lighting_command_decode(&apdu[dec_len], apdu_len - dec_len, - &bcl->Value.type.Lighting_Command); + &bcl->Value.type.Lighting_Command); break; default: return BACNET_STATUS_REJECT; break; } - if (len > 0) + if (len > 0) { dec_len += len; + } if (decode_is_context_tag(&apdu[dec_len], 5)) { uint32_t priority_dec; - len = decode_tag_number_and_value(&apdu[dec_len], &tag_number, - &len_value_type); + len = decode_tag_number_and_value( + &apdu[dec_len], &tag_number, &len_value_type); dec_len += len; len = decode_unsigned(&apdu[dec_len], len_value_type, &priority_dec); - if (len < 0) + if (len < 0) { return BACNET_STATUS_REJECT; + } bcl->Priority = (uint8_t)priority_dec; dec_len += len; } else { bcl->Priority = BACNET_NO_PRIORITY; } if (decode_is_context_tag(&apdu[dec_len], 6)) { - len = decode_tag_number_and_value(&apdu[dec_len], &tag_number, - &len_value_type); + len = decode_tag_number_and_value( + &apdu[dec_len], &tag_number, &len_value_type); dec_len += len; len = decode_unsigned(&apdu[dec_len], len_value_type, &bcl->Post_Delay); - if (len < 0) + if (len < 0) { return BACNET_STATUS_REJECT; + } dec_len += len; } else { bcl->Post_Delay = 0xFFFFFFFFU; @@ -286,15 +310,17 @@ int cl_decode_apdu(uint8_t *apdu, unsigned apdu_len, BACNET_APPLICATION_TAG tag, return BACNET_STATUS_REJECT; } len = decode_context_boolean2(&apdu[dec_len], 7, &bcl->Quit_On_Failure); - if (len < 0) + if (len < 0) { return BACNET_STATUS_REJECT; + } dec_len += len; if (!decode_is_context_tag(&apdu[dec_len], 8)) { return BACNET_STATUS_REJECT; } len = decode_context_boolean2(&apdu[dec_len], 8, &bcl->Write_Successful); - if (len < 0) + if (len < 0) { return BACNET_STATUS_REJECT; + } dec_len += len; if (dec_len < apdu_len) { return BACNET_STATUS_REJECT; @@ -306,18 +332,13 @@ int cl_decode_apdu(uint8_t *apdu, unsigned apdu_len, BACNET_APPLICATION_TAG tag, COMMAND_DESCR Command_Descr[MAX_COMMANDS]; /* These arrays are used by the ReadPropertyMultiple handler */ -static const int Command_Properties_Required[] = {PROP_OBJECT_IDENTIFIER, - PROP_OBJECT_NAME, - PROP_OBJECT_TYPE, - PROP_PRESENT_VALUE, - PROP_IN_PROCESS, - PROP_ALL_WRITES_SUCCESSFUL, - PROP_ACTION, - -1}; +static const int Command_Properties_Required[] = { PROP_OBJECT_IDENTIFIER, + PROP_OBJECT_NAME, PROP_OBJECT_TYPE, PROP_PRESENT_VALUE, PROP_IN_PROCESS, + PROP_ALL_WRITES_SUCCESSFUL, PROP_ACTION, -1 }; -static const int Command_Properties_Optional[] = {PROP_DESCRIPTION, -1}; +static const int Command_Properties_Optional[] = { PROP_DESCRIPTION, -1 }; -static const int Command_Properties_Proprietary[] = {-1}; +static const int Command_Properties_Proprietary[] = { -1 }; /** * Returns the list of required, optional, and proprietary properties. @@ -330,15 +351,18 @@ static const int Command_Properties_Proprietary[] = {-1}; * @param pProprietary - pointer to list of int terminated by -1, of * BACnet proprietary properties for this object. */ -void Command_Property_Lists(const int **pRequired, const int **pOptional, - const int **pProprietary) +void Command_Property_Lists( + const int **pRequired, const int **pOptional, const int **pProprietary) { - if (pRequired) + if (pRequired) { *pRequired = Command_Properties_Required; - if (pOptional) + } + if (pOptional) { *pOptional = Command_Properties_Optional; - if (pProprietary) + } + if (pProprietary) { *pProprietary = Command_Properties_Proprietary; + } return; } @@ -368,8 +392,9 @@ bool Command_Valid_Instance(uint32_t object_instance) unsigned int index; index = Command_Instance_To_Index(object_instance); - if (index < MAX_COMMANDS) + if (index < MAX_COMMANDS) { return true; + } return false; } @@ -410,8 +435,9 @@ unsigned Command_Instance_To_Index(uint32_t object_instance) { unsigned index = MAX_COMMANDS; - if (object_instance < MAX_COMMANDS) + if (object_instance < MAX_COMMANDS) { index = object_instance; + } return index; } @@ -557,8 +583,8 @@ bool Command_All_Writes_Successful_Set(uint32_t object_instance, bool value) * * @return true if object-name was retrieved */ -bool Command_Object_Name(uint32_t object_instance, - BACNET_CHARACTER_STRING *object_name) +bool Command_Object_Name( + uint32_t object_instance, BACNET_CHARACTER_STRING *object_name) { static char text_string[32] = ""; /* okay for single thread */ unsigned int index; @@ -608,8 +634,8 @@ int Command_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) apdu = rpdata->application_data; switch ((int)rpdata->object_property) { case PROP_OBJECT_IDENTIFIER: - apdu_len = encode_application_object_id(&apdu[0], OBJECT_COMMAND, - rpdata->object_instance); + apdu_len = encode_application_object_id( + &apdu[0], OBJECT_COMMAND, rpdata->object_instance); break; case PROP_OBJECT_NAME: @@ -632,16 +658,15 @@ int Command_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) &apdu[0], Command_In_Process(rpdata->object_instance)); break; case PROP_ALL_WRITES_SUCCESSFUL: - apdu_len = encode_application_boolean( - &apdu[0], + apdu_len = encode_application_boolean(&apdu[0], Command_All_Writes_Successful(rpdata->object_instance)); break; case PROP_ACTION: /* TODO */ - if (rpdata->array_index == 0) + if (rpdata->array_index == 0) { apdu_len = encode_application_unsigned(&apdu[0], MAX_COMMAND_ACTIONS); - else if (rpdata->array_index == BACNET_ARRAY_ALL) { + } else if (rpdata->array_index == BACNET_ARRAY_ALL) { int i; for (i = 0; i < MAX_COMMAND_ACTIONS; i++) { BACNET_ACTION_LIST *Curr_CL_Member = @@ -649,8 +674,8 @@ int Command_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) /* another loop, for aditional actions in the list */ for (; Curr_CL_Member != NULL; Curr_CL_Member = Curr_CL_Member->next) { - len = cl_encode_apdu(&apdu[apdu_len], - &CurrentCommand->Action[0]); + len = cl_encode_apdu( + &apdu[apdu_len], &CurrentCommand->Action[0]); apdu_len += len; /* assume the next one is of the same length, which need * not be the case */ @@ -670,8 +695,8 @@ int Command_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) /* another loop, for aditional actions in the list */ for (; Curr_CL_Member != NULL; Curr_CL_Member = Curr_CL_Member->next) { - len = cl_encode_apdu(&apdu[apdu_len], - &CurrentCommand->Action[0]); + len = cl_encode_apdu( + &apdu[apdu_len], &CurrentCommand->Action[0]); apdu_len += len; /* assume the next one is of the same length, which need * not be the case */ @@ -722,8 +747,8 @@ bool Command_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) int len = 0; BACNET_APPLICATION_DATA_VALUE value; /* decode the some of the request */ - len = bacapp_decode_application_data(wp_data->application_data, - wp_data->application_data_len, &value); + len = bacapp_decode_application_data( + wp_data->application_data, wp_data->application_data_len, &value); /* FIXME: len < application_data_len: more data? */ if (len < 0) { /* error while decoding - a value larger than we can handle */ @@ -747,15 +772,15 @@ bool Command_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) case PROP_PRESENT_VALUE: status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_UNSIGNED_INT, - &wp_data->error_class, &wp_data->error_code); + &wp_data->error_class, &wp_data->error_code); if (status) { if (value.type.Unsigned_Int >= MAX_COMMAND_ACTIONS) { wp_data->error_class = ERROR_CLASS_PROPERTY; wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; return false; } - Command_Present_Value_Set(wp_data->object_instance, - value.type.Unsigned_Int); + Command_Present_Value_Set( + wp_data->object_instance, value.type.Unsigned_Int); } else { wp_data->error_class = ERROR_CLASS_PROPERTY; wp_data->error_code = ERROR_CODE_WRITE_ACCESS_DENIED; @@ -792,8 +817,9 @@ void Command_Intrinsic_Reporting(uint32_t object_instance) #include "ctest.h" bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue, - uint8_t ucExpectedTag, BACNET_ERROR_CLASS *pErrorClass, - BACNET_ERROR_CODE *pErrorCode) + uint8_t ucExpectedTag, + BACNET_ERROR_CLASS *pErrorClass, + BACNET_ERROR_CODE *pErrorCode) { bool bResult; @@ -813,7 +839,7 @@ bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue, void testCommand(Test *pTest) { - uint8_t apdu[MAX_APDU] = {0}; + uint8_t apdu[MAX_APDU] = { 0 }; int len = 0; uint32_t len_value = 0; uint8_t tag_number = 0; @@ -859,8 +885,8 @@ void testCommand(Test *pTest) ct_test(pTest, clist.Object_Id.type == clist_test.Object_Id.type); ct_test(pTest, clist.Object_Id.instance == clist_test.Object_Id.instance); ct_test(pTest, clist.Property_Identifier == clist_test.Property_Identifier); - ct_test(pTest, - clist.Property_Array_Index == clist_test.Property_Array_Index); + ct_test( + pTest, clist.Property_Array_Index == clist_test.Property_Array_Index); ct_test(pTest, clist.Value.tag == clist_test.Value.tag); ct_test(pTest, clist.Value.type.Real == clist_test.Value.type.Real); ct_test(pTest, clist.Priority == clist_test.Priority); diff --git a/demo/object/command.h b/src/bacnet/basic/object/command.h similarity index 98% rename from demo/object/command.h rename to src/bacnet/basic/object/command.h index 0c4fe6c5..7e4d6519 100644 --- a/demo/object/command.h +++ b/src/bacnet/basic/object/command.h @@ -44,9 +44,9 @@ #include #include -#include "bacdef.h" -#include "rp.h" -#include "wp.h" +#include "bacnet/bacdef.h" +#include "bacnet/rp.h" +#include "bacnet/wp.h" #ifndef MAX_COMMANDS #define MAX_COMMANDS 4 diff --git a/demo/object/command.mak b/src/bacnet/basic/object/command.mak similarity index 63% rename from demo/object/command.mak rename to src/bacnet/basic/object/command.mak index 0ef15a77..ffe247cb 100644 --- a/demo/object/command.mak +++ b/src/bacnet/basic/object/command.mak @@ -9,16 +9,16 @@ DEFINES = -DBIG_ENDIAN=0 -DBACDL_ALL -DTEST -DTEST_COMMAND CFLAGS = -Wall $(INCLUDES) $(DEFINES) -g SRCS = command.c \ - $(SRC_DIR)/bacdcode.c \ - $(SRC_DIR)/bacint.c \ - $(SRC_DIR)/bacstr.c \ - $(SRC_DIR)/bacreal.c \ - $(SRC_DIR)/bacapp.c \ - $(SRC_DIR)/bacdevobjpropref.c \ - $(SRC_DIR)/bactext.c \ - $(SRC_DIR)/indtext.c \ - $(SRC_DIR)/datetime.c \ - $(SRC_DIR)/lighting.c \ + $(SRC_DIR)/bacnet/bacdcode.c \ + $(SRC_DIR)/bacnet/bacint.c \ + $(SRC_DIR)/bacnet/bacstr.c \ + $(SRC_DIR)/bacnet/bacreal.c \ + $(SRC_DIR)/bacnet/bacapp.c \ + $(SRC_DIR)/bacnet/bacdevobjpropref.c \ + $(SRC_DIR)/bacnet/bactext.c \ + $(SRC_DIR)/bacnet/indtext.c \ + $(SRC_DIR)/bacnet/datetime.c \ + $(SRC_DIR)/bacnet/lighting.c \ $(TEST_DIR)/ctest.c TARGET = command diff --git a/demo/object/credential_data_input.c b/src/bacnet/basic/object/credential_data_input.c similarity index 85% rename from demo/object/credential_data_input.c rename to src/bacnet/basic/object/credential_data_input.c index 85ff8289..91b49d42 100644 --- a/demo/object/credential_data_input.c +++ b/src/bacnet/basic/object/credential_data_input.c @@ -29,41 +29,41 @@ #include #include #include -#include "bacdef.h" -#include "bacdcode.h" -#include "bacenum.h" -#include "bacapp.h" -#include "config.h" /* the custom stuff */ -#include "wp.h" -#include "credential_data_input.h" -#include "handlers.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacenum.h" +#include "bacnet/bacapp.h" +#include "bacnet/config.h" /* the custom stuff */ +#include "bacnet/wp.h" +#include "bacnet/basic/object/credential_data_input.h" +#include "bacnet/basic/services.h" static bool Credential_Data_Input_Initialized = false; static CREDENTIAL_DATA_INPUT_DESCR cdi_descr[MAX_CREDENTIAL_DATA_INPUTS]; /* These three arrays are used by the ReadPropertyMultiple handler */ -static const int Properties_Required[] = { - PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME, - PROP_OBJECT_TYPE, PROP_PRESENT_VALUE, - PROP_STATUS_FLAGS, PROP_RELIABILITY, - PROP_OUT_OF_SERVICE, PROP_SUPPORTED_FORMATS, - PROP_UPDATE_TIME, -1}; +static const int Properties_Required[] = { PROP_OBJECT_IDENTIFIER, + PROP_OBJECT_NAME, PROP_OBJECT_TYPE, PROP_PRESENT_VALUE, PROP_STATUS_FLAGS, + PROP_RELIABILITY, PROP_OUT_OF_SERVICE, PROP_SUPPORTED_FORMATS, + PROP_UPDATE_TIME, -1 }; -static const int Properties_Optional[] = {-1}; +static const int Properties_Optional[] = { -1 }; -static const int Properties_Proprietary[] = {-1}; +static const int Properties_Proprietary[] = { -1 }; -void Credential_Data_Input_Property_Lists(const int **pRequired, - const int **pOptional, - const int **pProprietary) +void Credential_Data_Input_Property_Lists( + const int **pRequired, const int **pOptional, const int **pProprietary) { - if (pRequired) + if (pRequired) { *pRequired = Properties_Required; - if (pOptional) + } + if (pOptional) { *pOptional = Properties_Optional; - if (pProprietary) + } + if (pProprietary) { *pProprietary = Properties_Proprietary; + } return; } @@ -97,8 +97,9 @@ void Credential_Data_Input_Init(void) /* given instance exists */ bool Credential_Data_Input_Valid_Instance(uint32_t object_instance) { - if (object_instance < MAX_CREDENTIAL_DATA_INPUTS) + if (object_instance < MAX_CREDENTIAL_DATA_INPUTS) { return true; + } return false; } @@ -125,22 +126,23 @@ unsigned Credential_Data_Input_Instance_To_Index(uint32_t object_instance) { unsigned index = MAX_CREDENTIAL_DATA_INPUTS; - if (object_instance < MAX_CREDENTIAL_DATA_INPUTS) + if (object_instance < MAX_CREDENTIAL_DATA_INPUTS) { index = object_instance; + } return index; } /* note: the object name must be unique within this device */ -bool Credential_Data_Input_Object_Name(uint32_t object_instance, - BACNET_CHARACTER_STRING *object_name) +bool Credential_Data_Input_Object_Name( + uint32_t object_instance, BACNET_CHARACTER_STRING *object_name) { static char text_string[32] = ""; /* okay for single thread */ bool status = false; if (object_instance < MAX_CREDENTIAL_DATA_INPUTS) { sprintf(text_string, "CREDENTIAL DATA INPUT %lu", - (unsigned long)object_instance); + (unsigned long)object_instance); status = characterstring_init_ansi(object_name, text_string); } @@ -191,13 +193,12 @@ int Credential_Data_Input_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) Credential_Data_Input_Instance_To_Index(rpdata->object_instance); switch (rpdata->object_property) { case PROP_OBJECT_IDENTIFIER: - apdu_len = encode_application_object_id( - &apdu[0], OBJECT_CREDENTIAL_DATA_INPUT, - rpdata->object_instance); + apdu_len = encode_application_object_id(&apdu[0], + OBJECT_CREDENTIAL_DATA_INPUT, rpdata->object_instance); break; case PROP_OBJECT_NAME: - Credential_Data_Input_Object_Name(rpdata->object_instance, - &char_string); + Credential_Data_Input_Object_Name( + rpdata->object_instance, &char_string); apdu_len = encode_application_character_string(&apdu[0], &char_string); break; @@ -235,12 +236,11 @@ int Credential_Data_Input_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) } else if (rpdata->array_index == BACNET_ARRAY_ALL) { for (i = 0; i < cdi_descr[object_index].supported_formats_count; i++) { - len = bacapp_encode_authentication_factor_format( - &apdu[0], + len = bacapp_encode_authentication_factor_format(&apdu[0], &cdi_descr[object_index].supported_formats[i]); - if (apdu_len + len < MAX_APDU) + if (apdu_len + len < MAX_APDU) { apdu_len += len; - else { + } else { rpdata->error_code = ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED; apdu_len = BACNET_STATUS_ABORT; @@ -250,10 +250,10 @@ int Credential_Data_Input_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) } else { if (rpdata->array_index <= cdi_descr[object_index].supported_formats_count) { - apdu_len = bacapp_encode_authentication_factor_format( - &apdu[0], - &cdi_descr[object_index] - .supported_formats[rpdata->array_index - 1]); + apdu_len = + bacapp_encode_authentication_factor_format(&apdu[0], + &cdi_descr[object_index] + .supported_formats[rpdata->array_index - 1]); } else { rpdata->error_class = ERROR_CLASS_PROPERTY; rpdata->error_code = ERROR_CODE_INVALID_ARRAY_INDEX; @@ -293,8 +293,8 @@ bool Credential_Data_Input_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) unsigned object_index = 0; /* decode the some of the request */ - len = bacapp_decode_application_data(wp_data->application_data, - wp_data->application_data_len, &value); + len = bacapp_decode_application_data( + wp_data->application_data, wp_data->application_data_len, &value); /* FIXME: len < application_data_len: more data? */ if (len < 0) { /* error while decoding - a value larger than we can handle */ @@ -320,7 +320,7 @@ bool Credential_Data_Input_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) wp_data->application_data, &tmp); if (len > 0) { memcpy(&cdi_descr[object_index].present_value, &tmp, - sizeof(BACNET_AUTHENTICATION_FACTOR)); + sizeof(BACNET_AUTHENTICATION_FACTOR)); } else { wp_data->error_class = ERROR_CLASS_PROPERTY; wp_data->error_code = ERROR_CODE_INVALID_DATA_TYPE; @@ -333,9 +333,9 @@ bool Credential_Data_Input_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) case PROP_RELIABILITY: if (Credential_Data_Input_Out_Of_Service( wp_data->object_instance)) { - status = WPValidateArgType( - &value, BACNET_APPLICATION_TAG_ENUMERATED, - &wp_data->error_class, &wp_data->error_code); + status = + WPValidateArgType(&value, BACNET_APPLICATION_TAG_ENUMERATED, + &wp_data->error_class, &wp_data->error_code); if (status) { cdi_descr[object_index].reliability = value.type.Enumerated; } @@ -369,8 +369,9 @@ bool Credential_Data_Input_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) #include "ctest.h" bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue, - uint8_t ucExpectedTag, BACNET_ERROR_CLASS *pErrorClass, - BACNET_ERROR_CODE *pErrorCode) + uint8_t ucExpectedTag, + BACNET_ERROR_CLASS *pErrorClass, + BACNET_ERROR_CODE *pErrorCode) { pValue = pValue; ucExpectedTag = ucExpectedTag; @@ -382,7 +383,7 @@ bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue, void testCredentialDataInput(Test *pTest) { - uint8_t apdu[MAX_APDU] = {0}; + uint8_t apdu[MAX_APDU] = { 0 }; int len = 0; uint32_t len_value = 0; uint8_t tag_number = 0; diff --git a/demo/object/credential_data_input.h b/src/bacnet/basic/object/credential_data_input.h similarity index 92% rename from demo/object/credential_data_input.h rename to src/bacnet/basic/object/credential_data_input.h index 0e53b680..6083a267 100644 --- a/demo/object/credential_data_input.h +++ b/src/bacnet/basic/object/credential_data_input.h @@ -27,15 +27,15 @@ #include #include -#include "bacdef.h" -#include "bacerror.h" -#include "timestamp.h" -#include "bacdevobjpropref.h" -#include "authentication_factor.h" -#include "authentication_factor_format.h" -#include "timestamp.h" -#include "rp.h" -#include "wp.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacerror.h" +#include "bacnet/timestamp.h" +#include "bacnet/bacdevobjpropref.h" +#include "bacnet/authentication_factor.h" +#include "bacnet/authentication_factor_format.h" +#include "bacnet/timestamp.h" +#include "bacnet/rp.h" +#include "bacnet/wp.h" #ifndef MAX_CREDENTIAL_DATA_INPUTS diff --git a/demo/object/credential_data_input.mak b/src/bacnet/basic/object/credential_data_input.mak similarity index 55% rename from demo/object/credential_data_input.mak rename to src/bacnet/basic/object/credential_data_input.mak index de6a38f1..0fa867a4 100644 --- a/demo/object/credential_data_input.mak +++ b/src/bacnet/basic/object/credential_data_input.mak @@ -8,19 +8,19 @@ DEFINES = -DBIG_ENDIAN=0 -DTEST -DBACAPP_ALL -DTEST_CREDENTIAL_DATA_INPUT CFLAGS = -Wall $(INCLUDES) $(DEFINES) -g SRCS = credential_data_input.c \ - $(SRC_DIR)/bacdcode.c \ - $(SRC_DIR)/bacint.c \ - $(SRC_DIR)/bacstr.c \ - $(SRC_DIR)/bacreal.c \ - $(SRC_DIR)/datetime.c \ - $(SRC_DIR)/lighting.c \ - $(SRC_DIR)/bacapp.c \ - $(SRC_DIR)/bacdevobjpropref.c \ - $(SRC_DIR)/bactext.c \ - $(SRC_DIR)/indtext.c \ - $(SRC_DIR)/authentication_factor.c \ - $(SRC_DIR)/authentication_factor_format.c \ - $(SRC_DIR)/timestamp.c \ + $(SRC_DIR)/bacnet/bacdcode.c \ + $(SRC_DIR)/bacnet/bacint.c \ + $(SRC_DIR)/bacnet/bacstr.c \ + $(SRC_DIR)/bacnet/bacreal.c \ + $(SRC_DIR)/bacnet/datetime.c \ + $(SRC_DIR)/bacnet/lighting.c \ + $(SRC_DIR)/bacnet/bacapp.c \ + $(SRC_DIR)/bacnet/bacdevobjpropref.c \ + $(SRC_DIR)/bacnet/bactext.c \ + $(SRC_DIR)/bacnet/indtext.c \ + $(SRC_DIR)/bacnet/authentication_factor.c \ + $(SRC_DIR)/bacnet/authentication_factor_format.c \ + $(SRC_DIR)/bacnet/timestamp.c \ $(TEST_DIR)/ctest.c TARGET = credential_data_input diff --git a/demo/object/csv.c b/src/bacnet/basic/object/csv.c similarity index 81% rename from demo/object/csv.c rename to src/bacnet/basic/object/csv.c index 404303cc..353ee78a 100644 --- a/demo/object/csv.c +++ b/src/bacnet/basic/object/csv.c @@ -28,15 +28,15 @@ #include #include #include -#include "bacdef.h" -#include "bacdcode.h" -#include "bacenum.h" -#include "bacapp.h" -#include "config.h" /* the custom stuff */ -#include "rp.h" -#include "wp.h" -#include "csv.h" -#include "handlers.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacenum.h" +#include "bacnet/bacapp.h" +#include "bacnet/config.h" /* the custom stuff */ +#include "bacnet/rp.h" +#include "bacnet/wp.h" +#include "bacnet/basic/object/csv.h" +#include "bacnet/basic/services.h" /* number of demo objects */ #ifndef MAX_CHARACTERSTRING_VALUES @@ -51,25 +51,27 @@ static char Object_Name[MAX_CHARACTERSTRING_VALUES][64]; static char Object_Description[MAX_CHARACTERSTRING_VALUES][64]; /* These three arrays are used by the ReadPropertyMultiple handler */ -static const int Properties_Required[] = { - PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME, PROP_OBJECT_TYPE, - PROP_PRESENT_VALUE, PROP_STATUS_FLAGS, -1}; +static const int Properties_Required[] = { PROP_OBJECT_IDENTIFIER, + PROP_OBJECT_NAME, PROP_OBJECT_TYPE, PROP_PRESENT_VALUE, PROP_STATUS_FLAGS, + -1 }; -static const int Properties_Optional[] = {PROP_EVENT_STATE, PROP_OUT_OF_SERVICE, - PROP_DESCRIPTION, -1}; +static const int Properties_Optional[] = { PROP_EVENT_STATE, + PROP_OUT_OF_SERVICE, PROP_DESCRIPTION, -1 }; -static const int Properties_Proprietary[] = {-1}; +static const int Properties_Proprietary[] = { -1 }; -void CharacterString_Value_Property_Lists(const int **pRequired, - const int **pOptional, - const int **pProprietary) +void CharacterString_Value_Property_Lists( + const int **pRequired, const int **pOptional, const int **pProprietary) { - if (pRequired) + if (pRequired) { *pRequired = Properties_Required; - if (pOptional) + } + if (pOptional) { *pOptional = Properties_Optional; - if (pProprietary) + } + if (pProprietary) { *pProprietary = Properties_Proprietary; + } return; } @@ -81,9 +83,9 @@ void CharacterString_Value_Init(void) /* initialize all Present Values */ for (i = 0; i < MAX_CHARACTERSTRING_VALUES; i++) { snprintf(&Object_Name[i][0], sizeof(Object_Name[i]), - "CHARACTER STRING VALUE %u", i + 1); + "CHARACTER STRING VALUE %u", i + 1); snprintf(&Object_Description[i][0], sizeof(Object_Description[i]), - "A Character String Value Example"); + "A Character String Value Example"); characterstring_init_ansi(&Present_Value[i], ""); } @@ -131,8 +133,8 @@ bool CharacterString_Value_Valid_Instance(uint32_t object_instance) return false; } -bool CharacterString_Value_Present_Value(uint32_t object_instance, - BACNET_CHARACTER_STRING *object_name) +bool CharacterString_Value_Present_Value( + uint32_t object_instance, BACNET_CHARACTER_STRING *object_name) { bool status = false; unsigned index = 0; /* offset from instance lookup */ @@ -172,8 +174,8 @@ bool CharacterString_Value_Out_Of_Service(uint32_t object_instance) return value; } -static void CharacterString_Value_Out_Of_Service_Set(uint32_t object_instance, - bool value) +static void CharacterString_Value_Out_Of_Service_Set( + uint32_t object_instance, bool value) { unsigned index = 0; @@ -198,11 +200,11 @@ static char *CharacterString_Value_Description(uint32_t object_instance) return pName; } -bool CharacterString_Value_Description_Set(uint32_t object_instance, - char *new_name) +bool CharacterString_Value_Description_Set( + uint32_t object_instance, char *new_name) { - unsigned index = 0; /* offset from instance lookup */ - size_t i = 0; /* loop counter */ + unsigned index = 0; /* offset from instance lookup */ + size_t i = 0; /* loop counter */ bool status = false; /* return value */ index = CharacterString_Value_Instance_To_Index(object_instance); @@ -225,8 +227,8 @@ bool CharacterString_Value_Description_Set(uint32_t object_instance, return status; } -bool CharacterString_Value_Object_Name(uint32_t object_instance, - BACNET_CHARACTER_STRING *object_name) +bool CharacterString_Value_Object_Name( + uint32_t object_instance, BACNET_CHARACTER_STRING *object_name) { unsigned index = 0; /* offset from instance lookup */ bool status = false; @@ -242,8 +244,8 @@ bool CharacterString_Value_Object_Name(uint32_t object_instance, /* note: the object name must be unique within this device */ bool CharacterString_Value_Name_Set(uint32_t object_instance, char *new_name) { - unsigned index = 0; /* offset from instance lookup */ - size_t i = 0; /* loop counter */ + unsigned index = 0; /* offset from instance lookup */ + size_t i = 0; /* loop counter */ bool status = false; /* return value */ index = CharacterString_Value_Instance_To_Index(object_instance); @@ -284,21 +286,19 @@ int CharacterString_Value_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) apdu = rpdata->application_data; switch (rpdata->object_property) { case PROP_OBJECT_IDENTIFIER: - apdu_len = encode_application_object_id( - &apdu[0], OBJECT_CHARACTERSTRING_VALUE, - rpdata->object_instance); + apdu_len = encode_application_object_id(&apdu[0], + OBJECT_CHARACTERSTRING_VALUE, rpdata->object_instance); break; /* note: Name and Description don't have to be the same. You could make Description writable and different */ case PROP_OBJECT_NAME: - CharacterString_Value_Object_Name(rpdata->object_instance, - &char_string); + CharacterString_Value_Object_Name( + rpdata->object_instance, &char_string); apdu_len = encode_application_character_string(&apdu[0], &char_string); break; case PROP_DESCRIPTION: - characterstring_init_ansi( - &char_string, + characterstring_init_ansi(&char_string, CharacterString_Value_Description(rpdata->object_instance)); apdu_len = encode_application_character_string(&apdu[0], &char_string); @@ -308,8 +308,8 @@ int CharacterString_Value_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) &apdu[0], OBJECT_CHARACTERSTRING_VALUE); break; case PROP_PRESENT_VALUE: - CharacterString_Value_Present_Value(rpdata->object_instance, - &char_string); + CharacterString_Value_Present_Value( + rpdata->object_instance, &char_string); apdu_len = encode_application_character_string(&apdu[0], &char_string); break; @@ -320,11 +320,11 @@ int CharacterString_Value_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) bitstring_set_bit(&bit_string, STATUS_FLAG_FAULT, false); bitstring_set_bit(&bit_string, STATUS_FLAG_OVERRIDDEN, false); if (CharacterString_Value_Out_Of_Service(rpdata->object_instance)) { - bitstring_set_bit(&bit_string, STATUS_FLAG_OUT_OF_SERVICE, - true); + bitstring_set_bit( + &bit_string, STATUS_FLAG_OUT_OF_SERVICE, true); } else { - bitstring_set_bit(&bit_string, STATUS_FLAG_OUT_OF_SERVICE, - false); + bitstring_set_bit( + &bit_string, STATUS_FLAG_OUT_OF_SERVICE, false); } apdu_len = encode_application_bitstring(&apdu[0], &bit_string); break; @@ -364,8 +364,8 @@ bool CharacterString_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) BACNET_APPLICATION_DATA_VALUE value; /* decode the some of the request */ - len = bacapp_decode_application_data(wp_data->application_data, - wp_data->application_data_len, &value); + len = bacapp_decode_application_data( + wp_data->application_data, wp_data->application_data_len, &value); /* FIXME: len < application_data_len: more data? */ if (len < 0) { /* error while decoding - a value larger than we can handle */ @@ -375,9 +375,9 @@ bool CharacterString_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) } switch (wp_data->object_property) { case PROP_PRESENT_VALUE: - status = WPValidateArgType( - &value, BACNET_APPLICATION_TAG_CHARACTER_STRING, - &wp_data->error_class, &wp_data->error_code); + status = WPValidateArgType(&value, + BACNET_APPLICATION_TAG_CHARACTER_STRING, &wp_data->error_class, + &wp_data->error_code); if (status) { status = CharacterString_Value_Present_Value_Set( wp_data->object_instance, &value.type.Character_String); @@ -388,9 +388,8 @@ bool CharacterString_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) } break; case PROP_OUT_OF_SERVICE: - status = - WPValidateArgType(&value, BACNET_APPLICATION_TAG_BOOLEAN, - &wp_data->error_class, &wp_data->error_code); + status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_BOOLEAN, + &wp_data->error_class, &wp_data->error_code); if (status) { CharacterString_Value_Out_Of_Service_Set( wp_data->object_instance, value.type.Boolean); @@ -420,8 +419,9 @@ bool CharacterString_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) #include "ctest.h" bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue, - uint8_t ucExpectedTag, BACNET_ERROR_CLASS *pErrorClass, - BACNET_ERROR_CODE *pErrorCode) + uint8_t ucExpectedTag, + BACNET_ERROR_CLASS *pErrorClass, + BACNET_ERROR_CODE *pErrorCode) { pValue = pValue; ucExpectedTag = ucExpectedTag; @@ -433,7 +433,7 @@ bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue, void testCharacterStringValue(Test *pTest) { - uint8_t apdu[MAX_APDU] = {0}; + uint8_t apdu[MAX_APDU] = { 0 }; int len = 0; uint32_t len_value = 0; uint8_t tag_number = 0; diff --git a/demo/object/csv.h b/src/bacnet/basic/object/csv.h similarity index 96% rename from demo/object/csv.h rename to src/bacnet/basic/object/csv.h index 5813496c..326e5f88 100644 --- a/demo/object/csv.h +++ b/src/bacnet/basic/object/csv.h @@ -27,10 +27,10 @@ #include #include -#include "bacdef.h" -#include "bacerror.h" -#include "rp.h" -#include "wp.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacerror.h" +#include "bacnet/rp.h" +#include "bacnet/wp.h" #ifdef __cplusplus extern "C" { diff --git a/demo/object/csv.mak b/src/bacnet/basic/object/csv.mak similarity index 63% rename from demo/object/csv.mak rename to src/bacnet/basic/object/csv.mak index cfe7e87f..600ea471 100644 --- a/demo/object/csv.mak +++ b/src/bacnet/basic/object/csv.mak @@ -8,16 +8,16 @@ DEFINES = -DBIG_ENDIAN=0 -DTEST -DBACAPP_ALL -DTEST_CHARACTERSTRING_VALUE CFLAGS = -Wall $(INCLUDES) $(DEFINES) -g SRCS = csv.c \ - $(SRC_DIR)/bacdcode.c \ - $(SRC_DIR)/bacint.c \ - $(SRC_DIR)/bacstr.c \ - $(SRC_DIR)/bacreal.c \ - $(SRC_DIR)/datetime.c \ - $(SRC_DIR)/bacapp.c \ - $(SRC_DIR)/bacdevobjpropref.c \ - $(SRC_DIR)/bactext.c \ - $(SRC_DIR)/indtext.c \ - $(SRC_DIR)/lighting.c \ + $(SRC_DIR)/bacnet/bacdcode.c \ + $(SRC_DIR)/bacnet/bacint.c \ + $(SRC_DIR)/bacnet/bacstr.c \ + $(SRC_DIR)/bacnet/bacreal.c \ + $(SRC_DIR)/bacnet/datetime.c \ + $(SRC_DIR)/bacnet/bacapp.c \ + $(SRC_DIR)/bacnet/bacdevobjpropref.c \ + $(SRC_DIR)/bacnet/bactext.c \ + $(SRC_DIR)/bacnet/indtext.c \ + $(SRC_DIR)/bacnet/lighting.c \ $(TEST_DIR)/ctest.c TARGET = characterstring_value diff --git a/demo/object/device.c b/src/bacnet/basic/object/device.c similarity index 74% rename from demo/object/device.c rename to src/bacnet/basic/object/device.c index 1d5993ad..666d97e3 100644 --- a/demo/object/device.c +++ b/src/bacnet/basic/object/device.c @@ -29,55 +29,53 @@ #include #include #include /* for memmove */ -#include /* for timezone, localtime */ -#include "bacdef.h" -#include "bacdcode.h" -#include "bacenum.h" -#include "bacapp.h" -#include "config.h" /* the custom stuff */ -#include "apdu.h" -#include "wp.h" /* WriteProperty handling */ -#include "rp.h" /* ReadProperty handling */ -#include "dcc.h" /* DeviceCommunicationControl handling */ -#include "version.h" -#include "device.h" /* me */ -#include "handlers.h" -#include "datalink.h" -#include "address.h" -/* os specfic includes */ -#include "timer.h" +#include /* for timezone, localtime */ +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacenum.h" +#include "bacnet/bacapp.h" +#include "bacnet/config.h" /* the custom stuff */ +#include "bacnet/apdu.h" +#include "bacnet/wp.h" /* WriteProperty handling */ +#include "bacnet/rp.h" /* ReadProperty handling */ +#include "bacnet/dcc.h" /* DeviceCommunicationControl handling */ +#include "bacnet/version.h" +#include "bacnet/basic/object/device.h" /* me */ +#include "bacnet/basic/services.h" +#include "bacnet/datalink/datalink.h" +#include "bacnet/basic/binding/address.h" /* include the device object */ -#include "device.h" -#include "ai.h" -#include "ao.h" -#include "av.h" -#include "bi.h" -#include "bo.h" -#include "bv.h" -#include "channel.h" -#include "command.h" -#include "csv.h" -#include "iv.h" -#include "lc.h" -#include "lsp.h" -#include "ms-input.h" -#include "mso.h" -#include "msv.h" +#include "bacnet/basic/object/device.h" +#include "bacnet/basic/object/ai.h" +#include "bacnet/basic/object/ao.h" +#include "bacnet/basic/object/av.h" +#include "bacnet/basic/object/bi.h" +#include "bacnet/basic/object/bo.h" +#include "bacnet/basic/object/bv.h" +#include "bacnet/basic/object/channel.h" +#include "bacnet/basic/object/command.h" +#include "bacnet/basic/object/csv.h" +#include "bacnet/basic/object/iv.h" +#include "bacnet/basic/object/lc.h" +#include "bacnet/basic/object/lsp.h" +#include "bacnet/basic/object/ms-input.h" +#include "bacnet/basic/object/mso.h" +#include "bacnet/basic/object/msv.h" #if (BACNET_PROTOCOL_REVISION >= 17) -#include "netport.h" +#include "bacnet/basic/object/netport.h" #endif -#include "osv.h" -#include "piv.h" -#include "schedule.h" -#include "trendlog.h" +#include "bacnet/basic/object/osv.h" +#include "bacnet/basic/object/piv.h" +#include "bacnet/basic/object/schedule.h" +#include "bacnet/basic/object/trendlog.h" #if defined(INTRINSIC_REPORTING) -#include "nc.h" +#include "bacnet/basic/object/nc.h" #endif /* defined(INTRINSIC_REPORTING) */ #if defined(BACFILE) -#include "bacfile.h" +#include "bacnet/basic/object/bacfile.h" #endif /* defined(BACFILE) */ #if defined(BAC_UCI) -#include "ucix.h" +#include "bacnet/basic/ucix/ucix.h" #endif /* defined(BAC_UCI) */ #if defined(__BORLANDC__) || defined(_WIN32) @@ -97,168 +95,175 @@ extern bool Routed_Device_Write_Property_Local( static object_functions_t *Object_Table; static object_functions_t My_Object_Table[] = { - {OBJECT_DEVICE, NULL /* Init - don't init Device or it will recourse! */, - Device_Count, Device_Index_To_Instance, - Device_Valid_Object_Instance_Number, Device_Object_Name, - Device_Read_Property_Local, Device_Write_Property_Local, - Device_Property_Lists, DeviceGetRRInfo, NULL /* Iterator */, - NULL /* Value_Lists */, NULL /* COV */, NULL /* COV Clear */, - NULL /* Intrinsic Reporting */}, + { OBJECT_DEVICE, NULL /* Init - don't init Device or it will recourse! */, + Device_Count, Device_Index_To_Instance, + Device_Valid_Object_Instance_Number, Device_Object_Name, + Device_Read_Property_Local, Device_Write_Property_Local, + Device_Property_Lists, DeviceGetRRInfo, NULL /* Iterator */, + NULL /* Value_Lists */, NULL /* COV */, NULL /* COV Clear */, + NULL /* Intrinsic Reporting */ }, #if (BACNET_PROTOCOL_REVISION >= 17) - {OBJECT_NETWORK_PORT, Network_Port_Init, Network_Port_Count, - Network_Port_Index_To_Instance, Network_Port_Valid_Instance, - Network_Port_Object_Name, Network_Port_Read_Property, - Network_Port_Write_Property, Network_Port_Property_Lists, - NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */, - NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */}, + { OBJECT_NETWORK_PORT, Network_Port_Init, Network_Port_Count, + Network_Port_Index_To_Instance, Network_Port_Valid_Instance, + Network_Port_Object_Name, Network_Port_Read_Property, + Network_Port_Write_Property, Network_Port_Property_Lists, + NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */, + NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */ }, #endif - {OBJECT_ANALOG_INPUT, Analog_Input_Init, Analog_Input_Count, - Analog_Input_Index_To_Instance, Analog_Input_Valid_Instance, - Analog_Input_Object_Name, Analog_Input_Read_Property, - Analog_Input_Write_Property, Analog_Input_Property_Lists, - NULL /* ReadRangeInfo */, NULL /* Iterator */, - Analog_Input_Encode_Value_List, Analog_Input_Change_Of_Value, - Analog_Input_Change_Of_Value_Clear, Analog_Input_Intrinsic_Reporting}, - {OBJECT_ANALOG_OUTPUT, Analog_Output_Init, Analog_Output_Count, - Analog_Output_Index_To_Instance, Analog_Output_Valid_Instance, - Analog_Output_Object_Name, Analog_Output_Read_Property, - Analog_Output_Write_Property, Analog_Output_Property_Lists, - NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */, - NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */}, - {OBJECT_ANALOG_VALUE, Analog_Value_Init, Analog_Value_Count, - Analog_Value_Index_To_Instance, Analog_Value_Valid_Instance, - Analog_Value_Object_Name, Analog_Value_Read_Property, - Analog_Value_Write_Property, Analog_Value_Property_Lists, - NULL /* ReadRangeInfo */, NULL /* Iterator */, - Analog_Value_Encode_Value_List, Analog_Value_Change_Of_Value, - Analog_Value_Change_Of_Value_Clear, Analog_Value_Intrinsic_Reporting}, - {OBJECT_BINARY_INPUT, Binary_Input_Init, Binary_Input_Count, - Binary_Input_Index_To_Instance, Binary_Input_Valid_Instance, - Binary_Input_Object_Name, Binary_Input_Read_Property, - Binary_Input_Write_Property, Binary_Input_Property_Lists, - NULL /* ReadRangeInfo */, NULL /* Iterator */, - Binary_Input_Encode_Value_List, Binary_Input_Change_Of_Value, - Binary_Input_Change_Of_Value_Clear, NULL /* Intrinsic Reporting */}, - {OBJECT_BINARY_OUTPUT, Binary_Output_Init, Binary_Output_Count, - Binary_Output_Index_To_Instance, Binary_Output_Valid_Instance, - Binary_Output_Object_Name, Binary_Output_Read_Property, - Binary_Output_Write_Property, Binary_Output_Property_Lists, - NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */, - NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */}, - {OBJECT_BINARY_VALUE, Binary_Value_Init, Binary_Value_Count, - Binary_Value_Index_To_Instance, Binary_Value_Valid_Instance, - Binary_Value_Object_Name, Binary_Value_Read_Property, - Binary_Value_Write_Property, Binary_Value_Property_Lists, - NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */, - NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */}, - {OBJECT_CHARACTERSTRING_VALUE, CharacterString_Value_Init, - CharacterString_Value_Count, CharacterString_Value_Index_To_Instance, - CharacterString_Value_Valid_Instance, CharacterString_Value_Object_Name, - CharacterString_Value_Read_Property, CharacterString_Value_Write_Property, - CharacterString_Value_Property_Lists, NULL /* ReadRangeInfo */, - NULL /* Iterator */, NULL /* Value_Lists */, NULL /* COV */, - NULL /* COV Clear */, NULL /* Intrinsic Reporting */}, - {OBJECT_COMMAND, Command_Init, Command_Count, Command_Index_To_Instance, - Command_Valid_Instance, Command_Object_Name, Command_Read_Property, - Command_Write_Property, Command_Property_Lists, NULL /* ReadRangeInfo */, - NULL /* Iterator */, NULL /* Value_Lists */, NULL /* COV */, - NULL /* COV Clear */, NULL /* Intrinsic Reporting */}, - {OBJECT_INTEGER_VALUE, Integer_Value_Init, Integer_Value_Count, - Integer_Value_Index_To_Instance, Integer_Value_Valid_Instance, - Integer_Value_Object_Name, Integer_Value_Read_Property, - Integer_Value_Write_Property, Integer_Value_Property_Lists, - NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */, - NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */}, + { OBJECT_ANALOG_INPUT, Analog_Input_Init, Analog_Input_Count, + Analog_Input_Index_To_Instance, Analog_Input_Valid_Instance, + Analog_Input_Object_Name, Analog_Input_Read_Property, + Analog_Input_Write_Property, Analog_Input_Property_Lists, + NULL /* ReadRangeInfo */, NULL /* Iterator */, + Analog_Input_Encode_Value_List, Analog_Input_Change_Of_Value, + Analog_Input_Change_Of_Value_Clear, Analog_Input_Intrinsic_Reporting }, + { OBJECT_ANALOG_OUTPUT, Analog_Output_Init, Analog_Output_Count, + Analog_Output_Index_To_Instance, Analog_Output_Valid_Instance, + Analog_Output_Object_Name, Analog_Output_Read_Property, + Analog_Output_Write_Property, Analog_Output_Property_Lists, + NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */, + NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */ }, + { OBJECT_ANALOG_VALUE, Analog_Value_Init, Analog_Value_Count, + Analog_Value_Index_To_Instance, Analog_Value_Valid_Instance, + Analog_Value_Object_Name, Analog_Value_Read_Property, + Analog_Value_Write_Property, Analog_Value_Property_Lists, + NULL /* ReadRangeInfo */, NULL /* Iterator */, + Analog_Value_Encode_Value_List, Analog_Value_Change_Of_Value, + Analog_Value_Change_Of_Value_Clear, Analog_Value_Intrinsic_Reporting }, + { OBJECT_BINARY_INPUT, Binary_Input_Init, Binary_Input_Count, + Binary_Input_Index_To_Instance, Binary_Input_Valid_Instance, + Binary_Input_Object_Name, Binary_Input_Read_Property, + Binary_Input_Write_Property, Binary_Input_Property_Lists, + NULL /* ReadRangeInfo */, NULL /* Iterator */, + Binary_Input_Encode_Value_List, Binary_Input_Change_Of_Value, + Binary_Input_Change_Of_Value_Clear, NULL /* Intrinsic Reporting */ }, + { OBJECT_BINARY_OUTPUT, Binary_Output_Init, Binary_Output_Count, + Binary_Output_Index_To_Instance, Binary_Output_Valid_Instance, + Binary_Output_Object_Name, Binary_Output_Read_Property, + Binary_Output_Write_Property, Binary_Output_Property_Lists, + NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */, + NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */ }, + { OBJECT_BINARY_VALUE, Binary_Value_Init, Binary_Value_Count, + Binary_Value_Index_To_Instance, Binary_Value_Valid_Instance, + Binary_Value_Object_Name, Binary_Value_Read_Property, + Binary_Value_Write_Property, Binary_Value_Property_Lists, + NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */, + NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */ }, + { OBJECT_CHARACTERSTRING_VALUE, CharacterString_Value_Init, + CharacterString_Value_Count, CharacterString_Value_Index_To_Instance, + CharacterString_Value_Valid_Instance, CharacterString_Value_Object_Name, + CharacterString_Value_Read_Property, + CharacterString_Value_Write_Property, + CharacterString_Value_Property_Lists, NULL /* ReadRangeInfo */, + NULL /* Iterator */, NULL /* Value_Lists */, NULL /* COV */, + NULL /* COV Clear */, NULL /* Intrinsic Reporting */ }, + { OBJECT_COMMAND, Command_Init, Command_Count, Command_Index_To_Instance, + Command_Valid_Instance, Command_Object_Name, Command_Read_Property, + Command_Write_Property, Command_Property_Lists, + NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */, + NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */ }, + { OBJECT_INTEGER_VALUE, Integer_Value_Init, Integer_Value_Count, + Integer_Value_Index_To_Instance, Integer_Value_Valid_Instance, + Integer_Value_Object_Name, Integer_Value_Read_Property, + Integer_Value_Write_Property, Integer_Value_Property_Lists, + NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */, + NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */ }, #if defined(INTRINSIC_REPORTING) - {OBJECT_NOTIFICATION_CLASS, Notification_Class_Init, - Notification_Class_Count, Notification_Class_Index_To_Instance, - Notification_Class_Valid_Instance, Notification_Class_Object_Name, - Notification_Class_Read_Property, Notification_Class_Write_Property, - Notification_Class_Property_Lists, NULL /* ReadRangeInfo */, - NULL /* Iterator */, NULL /* Value_Lists */, NULL /* COV */, - NULL /* COV Clear */, NULL /* Intrinsic Reporting */}, + { OBJECT_NOTIFICATION_CLASS, Notification_Class_Init, + Notification_Class_Count, Notification_Class_Index_To_Instance, + Notification_Class_Valid_Instance, Notification_Class_Object_Name, + Notification_Class_Read_Property, Notification_Class_Write_Property, + Notification_Class_Property_Lists, NULL /* ReadRangeInfo */, + NULL /* Iterator */, NULL /* Value_Lists */, NULL /* COV */, + NULL /* COV Clear */, NULL /* Intrinsic Reporting */ }, #endif - {OBJECT_LIFE_SAFETY_POINT, Life_Safety_Point_Init, Life_Safety_Point_Count, - Life_Safety_Point_Index_To_Instance, Life_Safety_Point_Valid_Instance, - Life_Safety_Point_Object_Name, Life_Safety_Point_Read_Property, - Life_Safety_Point_Write_Property, Life_Safety_Point_Property_Lists, - NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */, - NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */}, - {OBJECT_LOAD_CONTROL, Load_Control_Init, Load_Control_Count, - Load_Control_Index_To_Instance, Load_Control_Valid_Instance, - Load_Control_Object_Name, Load_Control_Read_Property, - Load_Control_Write_Property, Load_Control_Property_Lists, - NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */, - NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */}, - {OBJECT_MULTI_STATE_INPUT, Multistate_Input_Init, Multistate_Input_Count, - Multistate_Input_Index_To_Instance, Multistate_Input_Valid_Instance, - Multistate_Input_Object_Name, Multistate_Input_Read_Property, - Multistate_Input_Write_Property, Multistate_Input_Property_Lists, - NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */, - NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */}, - {OBJECT_MULTI_STATE_OUTPUT, Multistate_Output_Init, Multistate_Output_Count, - Multistate_Output_Index_To_Instance, Multistate_Output_Valid_Instance, - Multistate_Output_Object_Name, Multistate_Output_Read_Property, - Multistate_Output_Write_Property, Multistate_Output_Property_Lists, - NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */, - NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */}, - {OBJECT_MULTI_STATE_VALUE, Multistate_Value_Init, Multistate_Value_Count, - Multistate_Value_Index_To_Instance, Multistate_Value_Valid_Instance, - Multistate_Value_Object_Name, Multistate_Value_Read_Property, - Multistate_Value_Write_Property, Multistate_Value_Property_Lists, - NULL /* ReadRangeInfo */, NULL /* Iterator */, - Multistate_Value_Encode_Value_List, Multistate_Value_Change_Of_Value, - Multistate_Value_Change_Of_Value_Clear, NULL /* Intrinsic Reporting */}, - {OBJECT_TRENDLOG, Trend_Log_Init, Trend_Log_Count, - Trend_Log_Index_To_Instance, Trend_Log_Valid_Instance, - Trend_Log_Object_Name, Trend_Log_Read_Property, Trend_Log_Write_Property, - Trend_Log_Property_Lists, TrendLogGetRRInfo, NULL /* Iterator */, - NULL /* Value_Lists */, NULL /* COV */, NULL /* COV Clear */, - NULL /* Intrinsic Reporting */}, + { OBJECT_LIFE_SAFETY_POINT, Life_Safety_Point_Init, Life_Safety_Point_Count, + Life_Safety_Point_Index_To_Instance, Life_Safety_Point_Valid_Instance, + Life_Safety_Point_Object_Name, Life_Safety_Point_Read_Property, + Life_Safety_Point_Write_Property, Life_Safety_Point_Property_Lists, + NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */, + NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */ }, + { OBJECT_LOAD_CONTROL, Load_Control_Init, Load_Control_Count, + Load_Control_Index_To_Instance, Load_Control_Valid_Instance, + Load_Control_Object_Name, Load_Control_Read_Property, + Load_Control_Write_Property, Load_Control_Property_Lists, + NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */, + NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */ }, + { OBJECT_MULTI_STATE_INPUT, Multistate_Input_Init, Multistate_Input_Count, + Multistate_Input_Index_To_Instance, Multistate_Input_Valid_Instance, + Multistate_Input_Object_Name, Multistate_Input_Read_Property, + Multistate_Input_Write_Property, Multistate_Input_Property_Lists, + NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */, + NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */ }, + { OBJECT_MULTI_STATE_OUTPUT, Multistate_Output_Init, + Multistate_Output_Count, Multistate_Output_Index_To_Instance, + Multistate_Output_Valid_Instance, Multistate_Output_Object_Name, + Multistate_Output_Read_Property, Multistate_Output_Write_Property, + Multistate_Output_Property_Lists, NULL /* ReadRangeInfo */, + NULL /* Iterator */, NULL /* Value_Lists */, NULL /* COV */, + NULL /* COV Clear */, NULL /* Intrinsic Reporting */ }, + { OBJECT_MULTI_STATE_VALUE, Multistate_Value_Init, Multistate_Value_Count, + Multistate_Value_Index_To_Instance, Multistate_Value_Valid_Instance, + Multistate_Value_Object_Name, Multistate_Value_Read_Property, + Multistate_Value_Write_Property, Multistate_Value_Property_Lists, + NULL /* ReadRangeInfo */, NULL /* Iterator */, + Multistate_Value_Encode_Value_List, Multistate_Value_Change_Of_Value, + Multistate_Value_Change_Of_Value_Clear, + NULL /* Intrinsic Reporting */ }, + { OBJECT_TRENDLOG, Trend_Log_Init, Trend_Log_Count, + Trend_Log_Index_To_Instance, Trend_Log_Valid_Instance, + Trend_Log_Object_Name, Trend_Log_Read_Property, + Trend_Log_Write_Property, Trend_Log_Property_Lists, TrendLogGetRRInfo, + NULL /* Iterator */, NULL /* Value_Lists */, NULL /* COV */, + NULL /* COV Clear */, NULL /* Intrinsic Reporting */ }, #if (BACNET_PROTOCOL_REVISION >= 14) - {OBJECT_LIGHTING_OUTPUT, Lighting_Output_Init, Lighting_Output_Count, - Lighting_Output_Index_To_Instance, Lighting_Output_Valid_Instance, - Lighting_Output_Object_Name, Lighting_Output_Read_Property, - Lighting_Output_Write_Property, Lighting_Output_Property_Lists, - NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */, - NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */}, - {OBJECT_CHANNEL, Channel_Init, Channel_Count, Channel_Index_To_Instance, - Channel_Valid_Instance, Channel_Object_Name, Channel_Read_Property, - Channel_Write_Property, Channel_Property_Lists, NULL /* ReadRangeInfo */, - NULL /* Iterator */, NULL /* Value_Lists */, NULL /* COV */, - NULL /* COV Clear */, NULL /* Intrinsic Reporting */}, + { OBJECT_LIGHTING_OUTPUT, Lighting_Output_Init, Lighting_Output_Count, + Lighting_Output_Index_To_Instance, Lighting_Output_Valid_Instance, + Lighting_Output_Object_Name, Lighting_Output_Read_Property, + Lighting_Output_Write_Property, Lighting_Output_Property_Lists, + NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */, + NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */ }, + { OBJECT_CHANNEL, Channel_Init, Channel_Count, Channel_Index_To_Instance, + Channel_Valid_Instance, Channel_Object_Name, Channel_Read_Property, + Channel_Write_Property, Channel_Property_Lists, + NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */, + NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */ }, #endif #if defined(BACFILE) - {OBJECT_FILE, bacfile_init, bacfile_count, bacfile_index_to_instance, - bacfile_valid_instance, bacfile_object_name, bacfile_read_property, - bacfile_write_property, BACfile_Property_Lists, NULL /* ReadRangeInfo */, - NULL /* Iterator */, NULL /* Value_Lists */, NULL /* COV */, - NULL /* COV Clear */, NULL /* Intrinsic Reporting */}, + { OBJECT_FILE, bacfile_init, bacfile_count, bacfile_index_to_instance, + bacfile_valid_instance, bacfile_object_name, bacfile_read_property, + bacfile_write_property, BACfile_Property_Lists, + NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */, + NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */ }, #endif - {OBJECT_OCTETSTRING_VALUE, OctetString_Value_Init, OctetString_Value_Count, - OctetString_Value_Index_To_Instance, OctetString_Value_Valid_Instance, - OctetString_Value_Object_Name, OctetString_Value_Read_Property, - OctetString_Value_Write_Property, OctetString_Value_Property_Lists, - NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */, - NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */}, - {OBJECT_POSITIVE_INTEGER_VALUE, PositiveInteger_Value_Init, - PositiveInteger_Value_Count, PositiveInteger_Value_Index_To_Instance, - PositiveInteger_Value_Valid_Instance, PositiveInteger_Value_Object_Name, - PositiveInteger_Value_Read_Property, PositiveInteger_Value_Write_Property, - PositiveInteger_Value_Property_Lists, NULL /* ReadRangeInfo */, - NULL /* Iterator */, NULL /* Value_Lists */, NULL /* COV */, - NULL /* COV Clear */, NULL /* Intrinsic Reporting */}, - {OBJECT_SCHEDULE, Schedule_Init, Schedule_Count, Schedule_Index_To_Instance, - Schedule_Valid_Instance, Schedule_Object_Name, Schedule_Read_Property, - Schedule_Write_Property, Schedule_Property_Lists, NULL /* ReadRangeInfo */, - NULL /* Iterator */, NULL /* Value_Lists */, NULL /* COV */, - NULL /* COV Clear */, NULL /* Intrinsic Reporting */}, - {MAX_BACNET_OBJECT_TYPE, NULL /* Init */, NULL /* Count */, - NULL /* Index_To_Instance */, NULL /* Valid_Instance */, - NULL /* Object_Name */, NULL /* Read_Property */, - NULL /* Write_Property */, NULL /* Property_Lists */, - NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */, - NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */}}; + { OBJECT_OCTETSTRING_VALUE, OctetString_Value_Init, OctetString_Value_Count, + OctetString_Value_Index_To_Instance, OctetString_Value_Valid_Instance, + OctetString_Value_Object_Name, OctetString_Value_Read_Property, + OctetString_Value_Write_Property, OctetString_Value_Property_Lists, + NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */, + NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */ }, + { OBJECT_POSITIVE_INTEGER_VALUE, PositiveInteger_Value_Init, + PositiveInteger_Value_Count, PositiveInteger_Value_Index_To_Instance, + PositiveInteger_Value_Valid_Instance, PositiveInteger_Value_Object_Name, + PositiveInteger_Value_Read_Property, + PositiveInteger_Value_Write_Property, + PositiveInteger_Value_Property_Lists, NULL /* ReadRangeInfo */, + NULL /* Iterator */, NULL /* Value_Lists */, NULL /* COV */, + NULL /* COV Clear */, NULL /* Intrinsic Reporting */ }, + { OBJECT_SCHEDULE, Schedule_Init, Schedule_Count, + Schedule_Index_To_Instance, Schedule_Valid_Instance, + Schedule_Object_Name, Schedule_Read_Property, Schedule_Write_Property, + Schedule_Property_Lists, NULL /* ReadRangeInfo */, NULL /* Iterator */, + NULL /* Value_Lists */, NULL /* COV */, NULL /* COV Clear */, + NULL /* Intrinsic Reporting */ }, + { MAX_BACNET_OBJECT_TYPE, NULL /* Init */, NULL /* Count */, + NULL /* Index_To_Instance */, NULL /* Valid_Instance */, + NULL /* Object_Name */, NULL /* Read_Property */, + NULL /* Write_Property */, NULL /* Property_Lists */, + NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */, + NULL /* COV */, NULL /* COV Clear */, + NULL /* Intrinsic Reporting */ } +}; /** Glue function to let the Device object, when called by a handler, * lookup which Object type needs to be invoked. @@ -316,8 +321,8 @@ rr_info_function Device_Objects_RR_Info(BACNET_OBJECT_TYPE object_type) * properties with their counts. */ void Device_Objects_Property_List(BACNET_OBJECT_TYPE object_type, - uint32_t object_instance, - struct special_property_list_t *pPropertyList) + uint32_t object_instance, + struct special_property_list_t *pPropertyList) { struct object_functions *pObject = NULL; @@ -334,84 +339,63 @@ void Device_Objects_Property_List(BACNET_OBJECT_TYPE object_type, pObject = Device_Objects_Find_Functions(object_type); if ((pObject != NULL) && (pObject->Object_RPM_List != NULL)) { pObject->Object_RPM_List(&pPropertyList->Required.pList, - &pPropertyList->Optional.pList, - &pPropertyList->Proprietary.pList); + &pPropertyList->Optional.pList, &pPropertyList->Proprietary.pList); } /* Fetch the counts if available otherwise zero them */ - pPropertyList->Required.count = - pPropertyList->Required.pList == NULL - ? 0 - : property_list_count(pPropertyList->Required.pList); + pPropertyList->Required.count = pPropertyList->Required.pList == NULL + ? 0 + : property_list_count(pPropertyList->Required.pList); - pPropertyList->Optional.count = - pPropertyList->Optional.pList == NULL - ? 0 - : property_list_count(pPropertyList->Optional.pList); + pPropertyList->Optional.count = pPropertyList->Optional.pList == NULL + ? 0 + : property_list_count(pPropertyList->Optional.pList); - pPropertyList->Proprietary.count = - pPropertyList->Proprietary.pList == NULL - ? 0 - : property_list_count(pPropertyList->Proprietary.pList); + pPropertyList->Proprietary.count = pPropertyList->Proprietary.pList == NULL + ? 0 + : property_list_count(pPropertyList->Proprietary.pList); return; } /* These three arrays are used by the ReadPropertyMultiple handler */ -static const int Device_Properties_Required[] = { - PROP_OBJECT_IDENTIFIER, - PROP_OBJECT_NAME, - PROP_OBJECT_TYPE, - PROP_SYSTEM_STATUS, - PROP_VENDOR_NAME, - PROP_VENDOR_IDENTIFIER, - PROP_MODEL_NAME, - PROP_FIRMWARE_REVISION, - PROP_APPLICATION_SOFTWARE_VERSION, - PROP_PROTOCOL_VERSION, - PROP_PROTOCOL_REVISION, - PROP_PROTOCOL_SERVICES_SUPPORTED, - PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED, - PROP_OBJECT_LIST, - PROP_MAX_APDU_LENGTH_ACCEPTED, - PROP_SEGMENTATION_SUPPORTED, - PROP_APDU_TIMEOUT, - PROP_NUMBER_OF_APDU_RETRIES, - PROP_DEVICE_ADDRESS_BINDING, - PROP_DATABASE_REVISION, - -1}; +static const int Device_Properties_Required[] = { PROP_OBJECT_IDENTIFIER, + PROP_OBJECT_NAME, PROP_OBJECT_TYPE, PROP_SYSTEM_STATUS, PROP_VENDOR_NAME, + PROP_VENDOR_IDENTIFIER, PROP_MODEL_NAME, PROP_FIRMWARE_REVISION, + PROP_APPLICATION_SOFTWARE_VERSION, PROP_PROTOCOL_VERSION, + PROP_PROTOCOL_REVISION, PROP_PROTOCOL_SERVICES_SUPPORTED, + PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED, PROP_OBJECT_LIST, + PROP_MAX_APDU_LENGTH_ACCEPTED, PROP_SEGMENTATION_SUPPORTED, + PROP_APDU_TIMEOUT, PROP_NUMBER_OF_APDU_RETRIES, PROP_DEVICE_ADDRESS_BINDING, + PROP_DATABASE_REVISION, -1 }; static const int Device_Properties_Optional[] = { #if defined(BACDL_MSTP) - PROP_MAX_MASTER, - PROP_MAX_INFO_FRAMES, + PROP_MAX_MASTER, PROP_MAX_INFO_FRAMES, #endif - PROP_DESCRIPTION, - PROP_LOCAL_TIME, - PROP_UTC_OFFSET, - PROP_LOCAL_DATE, - PROP_DAYLIGHT_SAVINGS_STATUS, - PROP_LOCATION, - PROP_ACTIVE_COV_SUBSCRIPTIONS, + PROP_DESCRIPTION, PROP_LOCAL_TIME, PROP_UTC_OFFSET, PROP_LOCAL_DATE, + PROP_DAYLIGHT_SAVINGS_STATUS, PROP_LOCATION, PROP_ACTIVE_COV_SUBSCRIPTIONS, #if defined(BACNET_TIME_MASTER) - PROP_TIME_SYNCHRONIZATION_RECIPIENTS, - PROP_TIME_SYNCHRONIZATION_INTERVAL, - PROP_ALIGN_INTERVALS, - PROP_INTERVAL_OFFSET, + PROP_TIME_SYNCHRONIZATION_RECIPIENTS, PROP_TIME_SYNCHRONIZATION_INTERVAL, + PROP_ALIGN_INTERVALS, PROP_INTERVAL_OFFSET, #endif - -1}; + -1 +}; -static const int Device_Properties_Proprietary[] = {-1}; +static const int Device_Properties_Proprietary[] = { -1 }; -void Device_Property_Lists(const int **pRequired, const int **pOptional, - const int **pProprietary) +void Device_Property_Lists( + const int **pRequired, const int **pOptional, const int **pProprietary) { - if (pRequired) + if (pRequired) { *pRequired = Device_Properties_Required; - if (pOptional) + } + if (pOptional) { *pOptional = Device_Properties_Optional; - if (pProprietary) + } + if (pProprietary) { *pProprietary = Device_Properties_Proprietary; + } return; } @@ -428,6 +412,7 @@ static char *Vendor_Name = BACNET_VENDOR_NAME; static uint16_t Vendor_Identifier = BACNET_VENDOR_ID; static char Model_Name[MAX_DEV_MOD_LEN + 1] = "GNU"; static char Application_Software_Version[MAX_DEV_VER_LEN + 1] = "1.0"; +static const char *BACnet_Version = BACNET_VERSION_TEXT; static char Location[MAX_DEV_LOC_LEN + 1] = "USA"; static char Description[MAX_DEV_DESC_LEN + 1] = "server"; /* static uint8_t Protocol_Version = 1; - constant, not settable */ @@ -445,7 +430,7 @@ static BACNET_DATE Local_Date; /* rely on OS, if there is one */ If your UTC offset is -5hours of GMT, then BACnet UTC offset is +5hours. BACnet UTC offset is expressed in minutes. */ -static int32_t UTC_Offset = 5 * 60; +static int16_t UTC_Offset = 5 * 60; static bool Daylight_Savings_Status = false; /* rely on OS */ #if defined(BACNET_TIME_MASTER) static bool Align_Intervals; @@ -567,8 +552,9 @@ bool Device_Set_Object_Instance_Number(uint32_t object_id) /* Make the change and update the database revision */ Object_Instance_Number = object_id; Device_Inc_Database_Revision(); - } else + } else { status = false; + } return status; } @@ -578,8 +564,8 @@ bool Device_Valid_Object_Instance_Number(uint32_t object_id) return (Object_Instance_Number == object_id); } -bool Device_Object_Name(uint32_t object_instance, - BACNET_CHARACTER_STRING *object_name) +bool Device_Object_Name( + uint32_t object_instance, BACNET_CHARACTER_STRING *object_name) { bool status = false; @@ -840,8 +826,8 @@ unsigned Device_Object_List_Count(void) * @param instance [out] The object's instance number, if found. * @return True if found, else false. */ -bool Device_Object_List_Identifier(uint32_t array_index, int *object_type, - uint32_t *instance) +bool Device_Object_List_Identifier( + uint32_t array_index, int *object_type, uint32_t *instance) { bool status = false; uint32_t count = 0; @@ -899,7 +885,8 @@ bool Device_Object_List_Identifier(uint32_t array_index, int *object_type, * @return True on success or else False if not found. */ bool Device_Valid_Object_Name(BACNET_CHARACTER_STRING *object_name1, - int *object_type, uint32_t *object_instance) + int *object_type, + uint32_t *object_instance) { bool found = false; int type = 0; @@ -916,7 +903,7 @@ bool Device_Valid_Object_Name(BACNET_CHARACTER_STRING *object_name1, pObject = Device_Objects_Find_Functions(type); if ((pObject != NULL) && (pObject->Object_Name != NULL) && (pObject->Object_Name(instance, &object_name2) && - characterstring_same(object_name1, &object_name2))) { + characterstring_same(object_name1, &object_name2))) { found = true; if (object_type) { *object_type = type; @@ -957,8 +944,8 @@ bool Device_Valid_Object_Id(int object_type, uint32_t object_instance) * @return True on success or else False if not found. */ bool Device_Object_Name_Copy(BACNET_OBJECT_TYPE object_type, - uint32_t object_instance, - BACNET_CHARACTER_STRING *object_name) + uint32_t object_instance, + BACNET_CHARACTER_STRING *object_name) { struct object_functions *pObject = NULL; bool found = false; @@ -973,58 +960,8 @@ bool Device_Object_Name_Copy(BACNET_OBJECT_TYPE object_type, static void Update_Current_Time(void) { - struct tm *tblock = NULL; -#if defined(_MSC_VER) - time_t tTemp; -#else - struct timeval tv; -#endif -/* -struct tm - -int tm_sec Seconds [0,60]. -int tm_min Minutes [0,59]. -int tm_hour Hour [0,23]. -int tm_mday Day of month [1,31]. -int tm_mon Month of year [0,11]. -int tm_year Years since 1900. -int tm_wday Day of week [0,6] (Sunday =0). -int tm_yday Day of year [0,365]. -int tm_isdst Daylight Savings flag. -*/ -#if defined(_MSC_VER) - time(&tTemp); - tblock = (struct tm *)localtime(&tTemp); -#else - if (gettimeofday(&tv, NULL) == 0) { - tblock = (struct tm *)localtime((const time_t *)&tv.tv_sec); - } -#endif - - if (tblock) { - datetime_set_date(&Local_Date, (uint16_t)tblock->tm_year + 1900, - (uint8_t)tblock->tm_mon + 1, - (uint8_t)tblock->tm_mday); -#if !defined(_MSC_VER) - datetime_set_time(&Local_Time, (uint8_t)tblock->tm_hour, - (uint8_t)tblock->tm_min, (uint8_t)tblock->tm_sec, - (uint8_t)(tv.tv_usec / 10000)); -#else - datetime_set_time(&Local_Time, (uint8_t)tblock->tm_hour, - (uint8_t)tblock->tm_min, (uint8_t)tblock->tm_sec, 0); -#endif - if (tblock->tm_isdst) { - Daylight_Savings_Status = true; - } else { - Daylight_Savings_Status = false; - } - /* note: timezone is declared in stdlib. */ - UTC_Offset = timezone / 60; - } else { - datetime_date_wildcard_set(&Local_Date); - datetime_time_wildcard_set(&Local_Time); - Daylight_Savings_Status = false; - } + datetime_local( + &Local_Date, &Local_Time, &UTC_Offset, &Daylight_Savings_Status); } void Device_getCurrentDateTime(BACNET_DATE_TIME *DateTime) @@ -1131,9 +1068,9 @@ uint32_t Device_Interval_Offset(void) int Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA *rpdata) { int apdu_len = 0; /* return value */ - int len = 0; /* apdu len intermediate value */ - BACNET_BIT_STRING bit_string = {0}; - BACNET_CHARACTER_STRING char_string = {0}; + int len = 0; /* apdu len intermediate value */ + BACNET_BIT_STRING bit_string = { 0 }; + BACNET_CHARACTER_STRING char_string = { 0 }; uint32_t i = 0; int object_type = 0; uint32_t instance = 0; @@ -1151,8 +1088,8 @@ int Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA *rpdata) apdu_max = rpdata->application_data_len; switch (rpdata->object_property) { case PROP_OBJECT_IDENTIFIER: - apdu_len = encode_application_object_id(&apdu[0], OBJECT_DEVICE, - Object_Instance_Number); + apdu_len = encode_application_object_id( + &apdu[0], OBJECT_DEVICE, Object_Instance_Number); break; case PROP_OBJECT_NAME: apdu_len = @@ -1188,8 +1125,8 @@ int Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA *rpdata) encode_application_character_string(&apdu[0], &char_string); break; case PROP_APPLICATION_SOFTWARE_VERSION: - characterstring_init_ansi(&char_string, - Application_Software_Version); + characterstring_init_ansi( + &char_string, Application_Software_Version); apdu_len = encode_application_character_string(&apdu[0], &char_string); break; @@ -1216,20 +1153,19 @@ int Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA *rpdata) encode_application_boolean(&apdu[0], Daylight_Savings_Status); break; case PROP_PROTOCOL_VERSION: - apdu_len = encode_application_unsigned(&apdu[0], - Device_Protocol_Version()); + apdu_len = encode_application_unsigned( + &apdu[0], Device_Protocol_Version()); break; case PROP_PROTOCOL_REVISION: - apdu_len = encode_application_unsigned(&apdu[0], - Device_Protocol_Revision()); + apdu_len = encode_application_unsigned( + &apdu[0], Device_Protocol_Revision()); break; case PROP_PROTOCOL_SERVICES_SUPPORTED: /* Note: list of services that are executed, not initiated. */ bitstring_init(&bit_string); for (i = 0; i < MAX_BACNET_SERVICES_SUPPORTED; i++) { /* automatic lookup based on handlers set */ - bitstring_set_bit( - &bit_string, (uint8_t)i, + bitstring_set_bit(&bit_string, (uint8_t)i, apdu_service_supported((BACNET_SERVICES_SUPPORTED)i)); } apdu_len = encode_application_bitstring(&apdu[0], &bit_string); @@ -1256,16 +1192,18 @@ int Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA *rpdata) case PROP_OBJECT_LIST: count = Device_Object_List_Count(); /* Array element zero is the number of objects in the list */ - if (rpdata->array_index == 0) + if (rpdata->array_index == 0) { apdu_len = encode_application_unsigned(&apdu[0], count); - /* if no index was specified, then try to encode the entire list */ - /* into one packet. Note that more than likely you will have */ - /* to return an error if the number of encoded objects exceeds */ - /* your maximum APDU size. */ - else if (rpdata->array_index == BACNET_ARRAY_ALL) { + /* if no index was specified, then try to encode the entire list + */ + /* into one packet. Note that more than likely you will have */ + /* to return an error if the number of encoded objects exceeds + */ + /* your maximum APDU size. */ + } else if (rpdata->array_index == BACNET_ARRAY_ALL) { for (i = 1; i <= count; i++) { - found = Device_Object_List_Identifier(i, &object_type, - &instance); + found = Device_Object_List_Identifier( + i, &object_type, &instance); if (found) { len = encode_application_object_id( &apdu[apdu_len], object_type, instance); @@ -1289,8 +1227,8 @@ int Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA *rpdata) } } } else { - found = Device_Object_List_Identifier(rpdata->array_index, - &object_type, &instance); + found = Device_Object_List_Identifier( + rpdata->array_index, &object_type, &instance); if (found) { apdu_len = encode_application_object_id( &apdu[0], object_type, instance); @@ -1340,8 +1278,8 @@ int Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA *rpdata) } break; case PROP_TIME_SYNCHRONIZATION_INTERVAL: - apdu_len = encode_application_unsigned(&apdu[0], - Device_Time_Sync_Interval()); + apdu_len = encode_application_unsigned( + &apdu[0], Device_Time_Sync_Interval()); break; case PROP_ALIGN_INTERVALS: apdu_len = @@ -1400,10 +1338,9 @@ int Device_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) #if (BACNET_PROTOCOL_REVISION >= 14) if ((int)rpdata->object_property == PROP_PROPERTY_LIST) { Device_Objects_Property_List(rpdata->object_type, - rpdata->object_instance, - &property_list); - apdu_len = property_list_encode( - rpdata, property_list.Required.pList, + rpdata->object_instance, &property_list); + apdu_len = property_list_encode(rpdata, + property_list.Required.pList, property_list.Optional.pList, property_list.Proprietary.pList); } else @@ -1426,12 +1363,14 @@ bool Device_Write_Property_Local(BACNET_WRITE_PROPERTY_DATA *wp_data) BACNET_APPLICATION_DATA_VALUE value; int object_type = 0; uint32_t object_instance = 0; + int result = 0; +#if defined(BACNET_TIME_MASTER) uint32_t minutes = 0; - int temp; +#endif /* decode the some of the request */ - len = bacapp_decode_application_data(wp_data->application_data, - wp_data->application_data_len, &value); + len = bacapp_decode_application_data( + wp_data->application_data, wp_data->application_data_len, &value); if (len < 0) { /* error while decoding - a value larger than we can handle */ wp_data->error_class = ERROR_CLASS_PROPERTY; @@ -1448,9 +1387,8 @@ bool Device_Write_Property_Local(BACNET_WRITE_PROPERTY_DATA *wp_data) /* FIXME: len < application_data_len: more data? */ switch (wp_data->object_property) { case PROP_OBJECT_IDENTIFIER: - status = - WPValidateArgType(&value, BACNET_APPLICATION_TAG_OBJECT_ID, - &wp_data->error_class, &wp_data->error_code); + status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_OBJECT_ID, + &wp_data->error_class, &wp_data->error_code); if (status) { if ((value.type.Object_Id.type == OBJECT_DEVICE) && (Device_Set_Object_Instance_Number( @@ -1467,7 +1405,7 @@ bool Device_Write_Property_Local(BACNET_WRITE_PROPERTY_DATA *wp_data) case PROP_NUMBER_OF_APDU_RETRIES: status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_UNSIGNED_INT, - &wp_data->error_class, &wp_data->error_code); + &wp_data->error_class, &wp_data->error_code); if (status) { /* FIXME: bounds check? */ apdu_retries_set((uint8_t)value.type.Unsigned_Int); @@ -1476,7 +1414,7 @@ bool Device_Write_Property_Local(BACNET_WRITE_PROPERTY_DATA *wp_data) case PROP_APDU_TIMEOUT: status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_UNSIGNED_INT, - &wp_data->error_class, &wp_data->error_code); + &wp_data->error_class, &wp_data->error_code); if (status) { /* FIXME: bounds check? */ apdu_timeout_set((uint16_t)value.type.Unsigned_Int); @@ -1485,7 +1423,7 @@ bool Device_Write_Property_Local(BACNET_WRITE_PROPERTY_DATA *wp_data) case PROP_VENDOR_IDENTIFIER: status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_UNSIGNED_INT, - &wp_data->error_class, &wp_data->error_code); + &wp_data->error_class, &wp_data->error_code); if (status) { /* FIXME: bounds check? */ Device_Set_Vendor_Identifier((uint16_t)value.type.Unsigned_Int); @@ -1494,14 +1432,15 @@ bool Device_Write_Property_Local(BACNET_WRITE_PROPERTY_DATA *wp_data) case PROP_SYSTEM_STATUS: status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_ENUMERATED, - &wp_data->error_class, &wp_data->error_code); + &wp_data->error_class, &wp_data->error_code); if (status) { - temp = Device_Set_System_Status( + result = Device_Set_System_Status( (BACNET_DEVICE_STATUS)value.type.Enumerated, false); - if (temp != 0) { + if (result != 0) { + /* result: - 0 = ok, -1 = bad value, -2 = not allowed */ status = false; wp_data->error_class = ERROR_CLASS_PROPERTY; - if (temp == -1) { + if (result == -1) { wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; } else { wp_data->error_code = @@ -1511,13 +1450,13 @@ bool Device_Write_Property_Local(BACNET_WRITE_PROPERTY_DATA *wp_data) } break; case PROP_OBJECT_NAME: - status = WPValidateString( - &value, characterstring_capacity(&My_Object_Name), false, + status = WPValidateString(&value, + characterstring_capacity(&My_Object_Name), false, &wp_data->error_class, &wp_data->error_code); if (status) { /* All the object names in a device must be unique */ if (Device_Valid_Object_Name(&value.type.Character_String, - &object_type, &object_instance)) { + &object_type, &object_instance)) { if ((object_type == wp_data->object_type) && (object_instance == wp_data->object_instance)) { /* writing same name to same object */ @@ -1533,9 +1472,8 @@ bool Device_Write_Property_Local(BACNET_WRITE_PROPERTY_DATA *wp_data) } break; case PROP_LOCATION: - status = - WPValidateString(&value, MAX_DEV_LOC_LEN, true, - &wp_data->error_class, &wp_data->error_code); + status = WPValidateString(&value, MAX_DEV_LOC_LEN, true, + &wp_data->error_class, &wp_data->error_code); if (status) { Device_Set_Location( characterstring_value(&value.type.Character_String), @@ -1544,9 +1482,8 @@ bool Device_Write_Property_Local(BACNET_WRITE_PROPERTY_DATA *wp_data) break; case PROP_DESCRIPTION: - status = - WPValidateString(&value, MAX_DEV_DESC_LEN, true, - &wp_data->error_class, &wp_data->error_code); + status = WPValidateString(&value, MAX_DEV_DESC_LEN, true, + &wp_data->error_class, &wp_data->error_code); if (status) { Device_Set_Description( characterstring_value(&value.type.Character_String), @@ -1554,9 +1491,8 @@ bool Device_Write_Property_Local(BACNET_WRITE_PROPERTY_DATA *wp_data) } break; case PROP_MODEL_NAME: - status = - WPValidateString(&value, MAX_DEV_MOD_LEN, true, - &wp_data->error_class, &wp_data->error_code); + status = WPValidateString(&value, MAX_DEV_MOD_LEN, true, + &wp_data->error_class, &wp_data->error_code); if (status) { Device_Set_Model_Name( characterstring_value(&value.type.Character_String), @@ -1630,7 +1566,7 @@ bool Device_Write_Property_Local(BACNET_WRITE_PROPERTY_DATA *wp_data) case PROP_MAX_INFO_FRAMES: status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_UNSIGNED_INT, - &wp_data->error_class, &wp_data->error_code); + &wp_data->error_class, &wp_data->error_code); if (status) { if (value.type.Unsigned_Int <= 255) { dlmstp_set_max_info_frames( @@ -1645,7 +1581,7 @@ bool Device_Write_Property_Local(BACNET_WRITE_PROPERTY_DATA *wp_data) case PROP_MAX_MASTER: status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_UNSIGNED_INT, - &wp_data->error_class, &wp_data->error_code); + &wp_data->error_class, &wp_data->error_code); if (status) { if ((value.type.Unsigned_Int > 0) && (value.type.Unsigned_Int <= 127)) { @@ -1752,8 +1688,8 @@ bool Device_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) * @return True if the object instance supports this feature and value changed. */ bool Device_Encode_Value_List(BACNET_OBJECT_TYPE object_type, - uint32_t object_instance, - BACNET_PROPERTY_VALUE *value_list) + uint32_t object_instance, + BACNET_PROPERTY_VALUE *value_list) { bool status = false; /* Ever the pessamist! */ struct object_functions *pObject = NULL; @@ -1908,8 +1844,8 @@ void Device_Init(object_functions_t *object_table) } bool DeviceGetRRInfo(BACNET_READ_RANGE_DATA *pRequest, /* Info on the request */ - RR_PROP_INFO *pInfo) -{ /* Where to put the response */ + RR_PROP_INFO *pInfo) +{ /* Where to put the response */ bool status = false; /* return value */ switch (pRequest->object_property) { @@ -1986,8 +1922,9 @@ void Routing_Device_Init(uint32_t first_object_instance) #include "ctest.h" bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue, - uint8_t ucExpectedTag, BACNET_ERROR_CLASS *pErrorClass, - BACNET_ERROR_CODE *pErrorCode) + uint8_t ucExpectedTag, + BACNET_ERROR_CLASS *pErrorClass, + BACNET_ERROR_CODE *pErrorCode) { pValue = pValue; ucExpectedTag = ucExpectedTag; @@ -1997,9 +1934,11 @@ bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue, return false; } -bool WPValidateString(BACNET_APPLICATION_DATA_VALUE *pValue, int iMaxLen, - bool bEmptyAllowed, BACNET_ERROR_CLASS *pErrorClass, - BACNET_ERROR_CODE *pErrorCode) +bool WPValidateString(BACNET_APPLICATION_DATA_VALUE *pValue, + int iMaxLen, + bool bEmptyAllowed, + BACNET_ERROR_CLASS *pErrorClass, + BACNET_ERROR_CODE *pErrorCode) { pValue = pValue; iMaxLen = iMaxLen; @@ -2030,12 +1969,12 @@ void testDevice(Test *pTest) ct_test(pTest, Device_Object_Instance_Number() == BACNET_MAX_INSTANCE); ct_test(pTest, status == true); status = Device_Set_Object_Instance_Number(BACNET_MAX_INSTANCE / 2); - ct_test(pTest, - Device_Object_Instance_Number() == (BACNET_MAX_INSTANCE / 2)); + ct_test( + pTest, Device_Object_Instance_Number() == (BACNET_MAX_INSTANCE / 2)); ct_test(pTest, status == true); status = Device_Set_Object_Instance_Number(BACNET_MAX_INSTANCE + 1); - ct_test(pTest, - Device_Object_Instance_Number() != (BACNET_MAX_INSTANCE + 1)); + ct_test( + pTest, Device_Object_Instance_Number() != (BACNET_MAX_INSTANCE + 1)); ct_test(pTest, status == false); Device_Set_System_Status(STATUS_NON_OPERATIONAL, true); diff --git a/demo/object/device.h b/src/bacnet/basic/object/device.h similarity index 98% rename from demo/object/device.h rename to src/bacnet/basic/object/device.h index 77dbaab7..714a89c0 100644 --- a/demo/object/device.h +++ b/src/bacnet/basic/object/device.h @@ -31,13 +31,13 @@ #include #include -#include "bacdef.h" -#include "bacenum.h" -#include "wp.h" -#include "rd.h" -#include "rp.h" -#include "rpm.h" -#include "readrange.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacenum.h" +#include "bacnet/wp.h" +#include "bacnet/rd.h" +#include "bacnet/rp.h" +#include "bacnet/rpm.h" +#include "bacnet/readrange.h" /** Called so a BACnet object can perform any necessary initialization. * @ingroup ObjHelpers diff --git a/demo/object/device.mak b/src/bacnet/basic/object/device.mak similarity index 57% rename from demo/object/device.mak rename to src/bacnet/basic/object/device.mak index 7107614c..b6fdf0bb 100644 --- a/demo/object/device.mak +++ b/src/bacnet/basic/object/device.mak @@ -14,22 +14,22 @@ DEFINES += -DBACNET_PROPERTY_LISTS=1 CFLAGS = -Wall $(INCLUDES) $(DEFINES) -g SRCS = device.c \ - $(SRC_DIR)/bacdcode.c \ - $(SRC_DIR)/bacint.c \ - $(SRC_DIR)/bacstr.c \ - $(SRC_DIR)/bacreal.c \ - $(SRC_DIR)/datetime.c \ - $(SRC_DIR)/bacapp.c \ - $(SRC_DIR)/bacdevobjpropref.c \ - $(SRC_DIR)/bactext.c \ - $(SRC_DIR)/indtext.c \ - $(SRC_DIR)/proplist.c \ - $(SRC_DIR)/lighting.c \ - $(SRC_DIR)/apdu.c \ - $(SRC_DIR)/address.c \ - $(SRC_DIR)/bacaddr.c \ - $(SRC_DIR)/dcc.c \ - $(SRC_DIR)/version.c \ + $(SRC_DIR)/bacnet/bacdcode.c \ + $(SRC_DIR)/bacnet/bacint.c \ + $(SRC_DIR)/bacnet/bacstr.c \ + $(SRC_DIR)/bacnet/bacreal.c \ + $(SRC_DIR)/bacnet/datetime.c \ + $(SRC_DIR)/bacnet/bacapp.c \ + $(SRC_DIR)/bacnet/bacdevobjpropref.c \ + $(SRC_DIR)/bacnet/bactext.c \ + $(SRC_DIR)/bacnet/indtext.c \ + $(SRC_DIR)/bacnet/proplist.c \ + $(SRC_DIR)/bacnet/lighting.c \ + $(SRC_DIR)/bacnet/basic/service/h_apdu.c \ + $(SRC_DIR)/bacnet/address.c \ + $(SRC_DIR)/bacnet/bacaddr.c \ + $(SRC_DIR)/bacnet/dcc.c \ + $(SRC_DIR)/bacnet/version.c \ $(TEST_DIR)/ctest.c TARGET = device diff --git a/demo/object/gw_device.c b/src/bacnet/basic/object/gateway/gw_device.c similarity index 84% rename from demo/object/gw_device.c rename to src/bacnet/basic/object/gateway/gw_device.c index 39c0b53e..2f180c9d 100644 --- a/demo/object/gw_device.c +++ b/src/bacnet/basic/object/gateway/gw_device.c @@ -29,38 +29,38 @@ #include #include #include /* for memmove */ -#include /* for timezone, localtime */ -#include "bacdef.h" -#include "bacdcode.h" -#include "bacenum.h" -#include "bacapp.h" -#include "config.h" /* the custom stuff */ -#include "apdu.h" -#include "wp.h" /* write property handling */ -#include "rp.h" /* read property handling */ -#include "version.h" -#include "device.h" /* me */ -#include "handlers.h" -#include "datalink.h" -#include "address.h" +#include /* for timezone, localtime */ +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacenum.h" +#include "bacnet/bacapp.h" +#include "bacnet/config.h" /* the custom stuff */ +#include "bacnet/apdu.h" +#include "bacnet/wp.h" /* write property handling */ +#include "bacnet/rp.h" /* read property handling */ +#include "bacnet/version.h" +#include "bacnet/basic/object/device.h" /* me */ +#include "bacnet/basic/services.h" +#include "bacnet/datalink/datalink.h" +#include "bacnet/basic/binding/address.h" #include "reject.h" /* include the objects */ -#include "ai.h" -#include "ao.h" -#include "av.h" -#include "bi.h" -#include "bo.h" -#include "bv.h" -#include "lc.h" -#include "lsp.h" -#include "mso.h" -#include "ms-input.h" -#include "trendlog.h" +#include "bacnet/basic/object/ai.h" +#include "bacnet/basic/object/ao.h" +#include "bacnet/basic/object/av.h" +#include "bacnet/basic/object/bi.h" +#include "bacnet/basic/object/bo.h" +#include "bacnet/basic/object/bv.h" +#include "bacnet/basic/object/lc.h" +#include "bacnet/basic/object/lsp.h" +#include "bacnet/basic/object/mso.h" +#include "bacnet/basic/object/ms-input.h" +#include "bacnet/basic/object/trendlog.h" #if defined(BACFILE) -#include "bacfile.h" /* object list dependency */ +#include "bacnet/basic/object/bacfile.h" /* object list dependency */ #endif /* os specfic includes */ -#include "timer.h" +#include "bacnet/basic/sys/mstimer.h" #if defined(__BORLANDC__) || defined(_WIN32) /* seems to not be defined in time.h as specified by The Open Group */ @@ -116,8 +116,8 @@ uint16_t iCurrent_Device_Idx = 0; * or -1 if there isn't enough room to add this Device. */ uint16_t Add_Routed_Device(uint32_t Object_Instance, - BACNET_CHARACTER_STRING *sObject_Name, - const char *sDescription) + BACNET_CHARACTER_STRING *sObject_Name, + const char *sDescription) { int i = Num_Managed_Devices; if (i < MAX_NUM_DEVICES) { @@ -126,21 +126,23 @@ uint16_t Add_Routed_Device(uint32_t Object_Instance, iCurrent_Device_Idx = i; pDev->bacObj.mObject_Type = OBJECT_DEVICE; pDev->bacObj.Object_Instance_Number = Object_Instance; - if (sObject_Name != NULL) + if (sObject_Name != NULL) { Routed_Device_Set_Object_Name(sObject_Name->encoding, - sObject_Name->value, - sObject_Name->length); - else - Routed_Device_Set_Object_Name(CHARACTER_UTF8, "No Name", - strlen("No Name")); - if (sDescription != NULL) + sObject_Name->value, sObject_Name->length); + } else { + Routed_Device_Set_Object_Name( + CHARACTER_UTF8, "No Name", strlen("No Name")); + } + if (sDescription != NULL) { Routed_Device_Set_Description(sDescription, strlen(sDescription)); - else + } else { Routed_Device_Set_Description("No Descr", strlen("No Descr")); + } pDev->Database_Revision = 0; /* Reset/Initialize now */ return i; - } else + } else { return -1; + } } /** Return the Device Object descriptive data for the indicated entry. @@ -154,13 +156,14 @@ uint16_t Add_Routed_Device(uint32_t Object_Instance, */ DEVICE_OBJECT_DATA *Get_Routed_Device_Object(int idx) { - if (idx == -1) + if (idx == -1) { return &Devices[iCurrent_Device_Idx]; - else if ((idx >= 0) && (idx < MAX_NUM_DEVICES)) { + } else if ((idx >= 0) && (idx < MAX_NUM_DEVICES)) { iCurrent_Device_Idx = idx; return &Devices[idx]; - } else + } else { return NULL; + } } /** Return the BACnet address for the indicated entry. @@ -174,13 +177,14 @@ DEVICE_OBJECT_DATA *Get_Routed_Device_Object(int idx) */ BACNET_ADDRESS *Get_Routed_Device_Address(int idx) { - if (idx == -1) + if (idx == -1) { return &Devices[iCurrent_Device_Idx].bacDevAddr; - else if ((idx >= 0) && (idx < MAX_NUM_DEVICES)) { + } else if ((idx >= 0) && (idx < MAX_NUM_DEVICES)) { iCurrent_Device_Idx = idx; return &Devices[idx].bacDevAddr; - } else + } else { return NULL; + } } /** Get the currently active BACnet address. @@ -194,7 +198,7 @@ void routed_get_my_address(BACNET_ADDRESS *my_address) { if (my_address) { memcpy(my_address, &Devices[iCurrent_Device_Idx].bacDevAddr, - sizeof(BACNET_ADDRESS)); + sizeof(BACNET_ADDRESS)); } } @@ -215,8 +219,8 @@ void routed_get_my_address(BACNET_ADDRESS *my_address) * meaning MAC broadcast, so it's an automatic match). * Else False if no match or invalid idx is given. */ -bool Routed_Device_Address_Lookup(int idx, uint8_t address_len, - uint8_t *mac_adress) +bool Routed_Device_Address_Lookup( + int idx, uint8_t address_len, uint8_t *mac_adress) { bool result = false; DEVICE_OBJECT_DATA *pDev = &Devices[idx]; @@ -229,8 +233,9 @@ bool Routed_Device_Address_Lookup(int idx, uint8_t address_len, result = true; } else if (mac_adress != NULL) { for (i = 0; i < address_len; i++) { - if (pDev->bacDevAddr.mac[i] != mac_adress[i]) + if (pDev->bacDevAddr.mac[i] != mac_adress[i]) { break; + } } if (i == address_len) { /* Success! */ iCurrent_Device_Idx = idx; @@ -275,13 +280,13 @@ bool Routed_Device_GetNext(BACNET_ADDRESS *dest, int *DNET_list, int *cursor) /* First, see if the index is out of range. * Eg, last call to GetNext may have been the last successful one. */ - if ((idx < 0) || (idx >= MAX_NUM_DEVICES)) + if ((idx < 0) || (idx >= MAX_NUM_DEVICES)) { idx = -1; - /* Next, see if it's a BACnet broadcast. - * For broadcasts, all Devices get a chance at it. - */ - else if (dest->net == BACNET_BROADCAST_NETWORK) { + /* Next, see if it's a BACnet broadcast. + * For broadcasts, all Devices get a chance at it. + */ + } else if (dest->net == BACNET_BROADCAST_NETWORK) { /* Just take the entry indexed by the cursor */ bSuccess = Routed_Device_Address_Lookup(idx++, dest->len, dest->adr); } @@ -302,22 +307,25 @@ bool Routed_Device_GetNext(BACNET_ADDRESS *dest, int *DNET_list, int *cursor) * For broadcasts, all Devices get a chance at it. */ else if (dest->net == dnet) { - if (idx == 0) /* Step over this case (starting point) */ + if (idx == 0) { /* Step over this case (starting point) */ idx = 1; + } while (idx < MAX_NUM_DEVICES) { bSuccess = Routed_Device_Address_Lookup(idx++, dest->len, dest->adr); - if (bSuccess) + if (bSuccess) { break; /* We don't need to keep looking */ + } } } - if (!bSuccess) + if (!bSuccess) { *cursor = -1; - else if (idx == MAX_NUM_DEVICES) /* No more to GetNext */ + } else if (idx == MAX_NUM_DEVICES) { /* No more to GetNext */ *cursor = -1; - else + } else { *cursor = idx; + } return bSuccess; } @@ -339,16 +347,17 @@ bool Routed_Device_Is_Valid_Network(uint16_t dest_net, int *DNET_list) bool bSuccess = false; /* First, see if it's a BACnet broadcast (automatic pass). */ - if (dest_net == BACNET_BROADCAST_NETWORK) + if (dest_net == BACNET_BROADCAST_NETWORK) { bSuccess = true; - /* Or see if it's for the main Gateway Device, because - * there's no routing info. - */ - else if (dest_net == 0) + /* Or see if it's for the main Gateway Device, because + * there's no routing info. + */ + } else if (dest_net == 0) { bSuccess = true; - /* Or see if matches our virtual DNET */ - else if (dest_net == dnet) + /* Or see if matches our virtual DNET */ + } else if (dest_net == dnet) { bSuccess = true; + } return bSuccess; } @@ -375,14 +384,15 @@ bool Routed_Device_Valid_Object_Instance_Number(uint32_t object_id) bool bResult = false; DEVICE_OBJECT_DATA *pDev = &Devices[iCurrent_Device_Idx]; - if (pDev->bacObj.Object_Instance_Number == object_id) + if (pDev->bacObj.Object_Instance_Number == object_id) { bResult = true; + } return bResult; } -bool Routed_Device_Name(uint32_t object_instance, - BACNET_CHARACTER_STRING *object_name) +bool Routed_Device_Name( + uint32_t object_instance, BACNET_CHARACTER_STRING *object_name) { DEVICE_OBJECT_DATA *pDev = &Devices[iCurrent_Device_Idx]; if (object_instance == pDev->bacObj.Object_Instance_Number) { @@ -444,8 +454,8 @@ bool Routed_Device_Write_Property_Local(BACNET_WRITE_PROPERTY_DATA *wp_data) BACNET_APPLICATION_DATA_VALUE value; /* decode the some of the request */ - len = bacapp_decode_application_data(wp_data->application_data, - wp_data->application_data_len, &value); + len = bacapp_decode_application_data( + wp_data->application_data, wp_data->application_data_len, &value); if (len < 0) { /* error while decoding - a value larger than we can handle */ wp_data->error_class = ERROR_CLASS_PROPERTY; @@ -462,9 +472,8 @@ bool Routed_Device_Write_Property_Local(BACNET_WRITE_PROPERTY_DATA *wp_data) /* FIXME: len < application_data_len: more data? */ switch (wp_data->object_property) { case PROP_OBJECT_IDENTIFIER: - status = - WPValidateArgType(&value, BACNET_APPLICATION_TAG_OBJECT_ID, - &wp_data->error_class, &wp_data->error_code); + status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_OBJECT_ID, + &wp_data->error_class, &wp_data->error_code); if (status) { if ((value.type.Object_Id.type == OBJECT_DEVICE) && (Routed_Device_Set_Object_Instance_Number( @@ -479,9 +488,8 @@ bool Routed_Device_Write_Property_Local(BACNET_WRITE_PROPERTY_DATA *wp_data) } break; case PROP_OBJECT_NAME: - status = - WPValidateString(&value, MAX_DEV_NAME_LEN, false, - &wp_data->error_class, &wp_data->error_code); + status = WPValidateString(&value, MAX_DEV_NAME_LEN, false, + &wp_data->error_class, &wp_data->error_code); if (status) { Routed_Device_Set_Object_Name( characterstring_encoding(&value.type.Character_String), @@ -517,8 +525,9 @@ bool Routed_Device_Set_Object_Instance_Number(uint32_t object_id) /* Make the change and update the database revision */ Devices[iCurrent_Device_Idx].bacObj.Object_Instance_Number = object_id; Routed_Device_Inc_Database_Revision(); - } else + } else { status = false; + } return status; } @@ -529,8 +538,8 @@ bool Routed_Device_Set_Object_Instance_Number(uint32_t object_id) * @param object_name [in] Character String for the new Object Name. * @return True if succeed in updating Object Name, else False. */ -bool Routed_Device_Set_Object_Name(uint8_t encoding, const char *value, - size_t length) +bool Routed_Device_Set_Object_Name( + uint8_t encoding, const char *value, size_t length) { bool status = false; /*return value */ DEVICE_OBJECT_DATA *pDev = &Devices[iCurrent_Device_Idx]; @@ -585,31 +594,32 @@ void Routed_Device_Inc_Database_Revision(void) * else 0 if service is approved for the current device. */ int Routed_Device_Service_Approval(BACNET_CONFIRMED_SERVICE service, - int service_argument, uint8_t *apdu_buff, - uint8_t invoke_id) + int service_argument, + uint8_t *apdu_buff, + uint8_t invoke_id) { int len = 0; switch (service) { case SERVICE_CONFIRMED_REINITIALIZE_DEVICE: /* If not the gateway device, we don't support RD */ if (iCurrent_Device_Idx > 0) { - if (apdu_buff != NULL) - len = - reject_encode_apdu(apdu_buff, invoke_id, - REJECT_REASON_UNRECOGNIZED_SERVICE); - else + if (apdu_buff != NULL) { + len = reject_encode_apdu(apdu_buff, invoke_id, + REJECT_REASON_UNRECOGNIZED_SERVICE); + } else { len = 1; /* Non-zero return */ + } } break; case SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL: /* If not the gateway device, we don't support DCC */ if (iCurrent_Device_Idx > 0) { - if (apdu_buff != NULL) - len = - reject_encode_apdu(apdu_buff, invoke_id, - REJECT_REASON_UNRECOGNIZED_SERVICE); - else + if (apdu_buff != NULL) { + len = reject_encode_apdu(apdu_buff, invoke_id, + REJECT_REASON_UNRECOGNIZED_SERVICE); + } else { len = 1; /* Non-zero return */ + } } break; default: diff --git a/demo/object/iv.c b/src/bacnet/basic/object/iv.c similarity index 85% rename from demo/object/iv.c rename to src/bacnet/basic/object/iv.c index 3df00aeb..416f9577 100644 --- a/demo/object/iv.c +++ b/src/bacnet/basic/object/iv.c @@ -36,16 +36,16 @@ #include #include -#include "bacdef.h" -#include "bacdcode.h" -#include "bacenum.h" -#include "bacapp.h" -#include "bactext.h" -#include "config.h" /* the custom stuff */ -#include "device.h" -#include "handlers.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacenum.h" +#include "bacnet/bacapp.h" +#include "bacnet/bactext.h" +#include "bacnet/config.h" /* the custom stuff */ +#include "bacnet/basic/object/device.h" +#include "bacnet/basic/services.h" /* me! */ -#include "iv.h" +#include "bacnet/basic/object/iv.h" #ifndef MAX_INTEGER_VALUES #define MAX_INTEGER_VALUES 1 @@ -59,18 +59,14 @@ struct integer_object { struct integer_object Integer_Value[MAX_INTEGER_VALUES]; /* These three arrays are used by the ReadPropertyMultiple handler */ -static const int Integer_Value_Properties_Required[] = {PROP_OBJECT_IDENTIFIER, - PROP_OBJECT_NAME, - PROP_OBJECT_TYPE, - PROP_PRESENT_VALUE, - PROP_STATUS_FLAGS, - PROP_UNITS, - -1}; +static const int Integer_Value_Properties_Required[] = { PROP_OBJECT_IDENTIFIER, + PROP_OBJECT_NAME, PROP_OBJECT_TYPE, PROP_PRESENT_VALUE, PROP_STATUS_FLAGS, + PROP_UNITS, -1 }; -static const int Integer_Value_Properties_Optional[] = {PROP_OUT_OF_SERVICE, - -1}; +static const int Integer_Value_Properties_Optional[] = { PROP_OUT_OF_SERVICE, + -1 }; -static const int Integer_Value_Properties_Proprietary[] = {-1}; +static const int Integer_Value_Properties_Proprietary[] = { -1 }; /** * Returns the list of required, optional, and proprietary properties. @@ -83,15 +79,18 @@ static const int Integer_Value_Properties_Proprietary[] = {-1}; * @param pProprietary - pointer to list of int terminated by -1, of * BACnet proprietary properties for this object. */ -void Integer_Value_Property_Lists(const int **pRequired, const int **pOptional, - const int **pProprietary) +void Integer_Value_Property_Lists( + const int **pRequired, const int **pOptional, const int **pProprietary) { - if (pRequired) + if (pRequired) { *pRequired = Integer_Value_Properties_Required; - if (pOptional) + } + if (pOptional) { *pOptional = Integer_Value_Properties_Optional; - if (pProprietary) + } + if (pProprietary) { *pProprietary = Integer_Value_Properties_Proprietary; + } return; } @@ -193,8 +192,8 @@ int32_t Integer_Value_Present_Value(uint32_t object_instance) * * @return true if values are within range and present-value is set. */ -bool Integer_Value_Present_Value_Set(uint32_t object_instance, int32_t value, - uint8_t priority) +bool Integer_Value_Present_Value_Set( + uint32_t object_instance, int32_t value, uint8_t priority) { bool status = false; unsigned int index; @@ -219,8 +218,8 @@ bool Integer_Value_Present_Value_Set(uint32_t object_instance, int32_t value, * * @return true if object-name was retrieved */ -bool Integer_Value_Object_Name(uint32_t object_instance, - BACNET_CHARACTER_STRING *object_name) +bool Integer_Value_Object_Name( + uint32_t object_instance, BACNET_CHARACTER_STRING *object_name) { char text_string[32] = ""; unsigned int index; @@ -228,8 +227,8 @@ bool Integer_Value_Object_Name(uint32_t object_instance, index = Integer_Value_Instance_To_Index(object_instance); if (index < MAX_INTEGER_VALUES) { - sprintf(text_string, "ANALOG VALUE %lu", - (unsigned long)object_instance); + sprintf( + text_string, "ANALOG VALUE %lu", (unsigned long)object_instance); status = characterstring_init_ansi(object_name, text_string); } @@ -413,8 +412,8 @@ bool Integer_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) BACNET_APPLICATION_DATA_VALUE value; /* decode the some of the request */ - len = bacapp_decode_application_data(wp_data->application_data, - wp_data->application_data_len, &value); + len = bacapp_decode_application_data( + wp_data->application_data, wp_data->application_data_len, &value); /* FIXME: len < application_data_len: more data? */ if (len < 0) { /* error while decoding - a value larger than we can handle */ @@ -434,20 +433,18 @@ bool Integer_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) case PROP_PRESENT_VALUE: status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_SIGNED_INT, - &wp_data->error_class, &wp_data->error_code); + &wp_data->error_class, &wp_data->error_code); if (status) { Integer_Value_Present_Value_Set(wp_data->object_instance, - value.type.Signed_Int, - wp_data->priority); + value.type.Signed_Int, wp_data->priority); } break; case PROP_OUT_OF_SERVICE: - status = - WPValidateArgType(&value, BACNET_APPLICATION_TAG_BOOLEAN, - &wp_data->error_class, &wp_data->error_code); + status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_BOOLEAN, + &wp_data->error_class, &wp_data->error_code); if (status) { - Integer_Value_Out_Of_Service_Set(wp_data->object_instance, - value.type.Boolean); + Integer_Value_Out_Of_Service_Set( + wp_data->object_instance, value.type.Boolean); } break; case PROP_OBJECT_IDENTIFIER: diff --git a/demo/object/iv.h b/src/bacnet/basic/object/iv.h similarity index 97% rename from demo/object/iv.h rename to src/bacnet/basic/object/iv.h index 85cba2d1..bb6c2d52 100644 --- a/demo/object/iv.h +++ b/src/bacnet/basic/object/iv.h @@ -35,10 +35,10 @@ #include #include -#include "bacdef.h" -#include "bacerror.h" -#include "wp.h" -#include "rp.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacerror.h" +#include "bacnet/wp.h" +#include "bacnet/rp.h" #ifdef __cplusplus extern "C" { diff --git a/demo/object/lc.c b/src/bacnet/basic/object/lc.c similarity index 84% rename from demo/object/lc.c rename to src/bacnet/basic/object/lc.c index 59cc67c5..1bc4ba6a 100644 --- a/demo/object/lc.c +++ b/src/bacnet/basic/object/lc.c @@ -31,15 +31,15 @@ #include #include /* for memcpy */ #include -#include "bacdef.h" -#include "bacdcode.h" -#include "datetime.h" -#include "bacenum.h" -#include "config.h" /* the custom stuff */ -#include "lc.h" -#include "ao.h" -#include "wp.h" -#include "handlers.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/datetime.h" +#include "bacnet/bacenum.h" +#include "bacnet/config.h" /* the custom stuff */ +#include "bacnet/basic/object/lc.h" +#include "bacnet/basic/object/ao.h" +#include "bacnet/wp.h" +#include "bacnet/basic/services.h" /* number of demo objects */ #ifndef MAX_LOAD_CONTROLS @@ -52,8 +52,8 @@ static BACNET_SHED_STATE Present_Value[MAX_LOAD_CONTROLS]; /* load control objects are required to support LEVEL */ typedef enum BACnetShedLevelType { BACNET_SHED_TYPE_PERCENT, /* Unsigned */ - BACNET_SHED_TYPE_LEVEL, /* Unsigned */ - BACNET_SHED_TYPE_AMOUNT /* REAL */ + BACNET_SHED_TYPE_LEVEL, /* Unsigned */ + BACNET_SHED_TYPE_AMOUNT /* REAL */ } BACNET_SHED_LEVEL_TYPE; #define DEFAULT_VALUE_PERCENT 100 @@ -125,44 +125,36 @@ static unsigned Shed_Levels[MAX_LOAD_CONTROLS][MAX_SHED_LEVELS]; /* represents a description of the shed levels that the Load Control object can take on. It is the same for all the load control objects in this example device. */ -static char *Shed_Level_Descriptions[MAX_SHED_LEVELS] = { - "dim lights 10%", "dim lights 20%", "dim lights 30%"}; +static char *Shed_Level_Descriptions[MAX_SHED_LEVELS] = { "dim lights 10%", + "dim lights 20%", "dim lights 30%" }; -static float Shed_Level_Values[MAX_SHED_LEVELS] = {90.0, 80.0, 70.0}; +static float Shed_Level_Values[MAX_SHED_LEVELS] = { 90.0, 80.0, 70.0 }; /* These three arrays are used by the ReadPropertyMultiple handler */ -static const int Load_Control_Properties_Required[] = { - PROP_OBJECT_IDENTIFIER, - PROP_OBJECT_NAME, - PROP_OBJECT_TYPE, - PROP_PRESENT_VALUE, - PROP_STATUS_FLAGS, - PROP_EVENT_STATE, - PROP_REQUESTED_SHED_LEVEL, - PROP_START_TIME, - PROP_SHED_DURATION, - PROP_DUTY_WINDOW, - PROP_ENABLE, - PROP_EXPECTED_SHED_LEVEL, - PROP_ACTUAL_SHED_LEVEL, - PROP_SHED_LEVELS, - PROP_SHED_LEVEL_DESCRIPTIONS, - -1}; +static const int Load_Control_Properties_Required[] = { PROP_OBJECT_IDENTIFIER, + PROP_OBJECT_NAME, PROP_OBJECT_TYPE, PROP_PRESENT_VALUE, PROP_STATUS_FLAGS, + PROP_EVENT_STATE, PROP_REQUESTED_SHED_LEVEL, PROP_START_TIME, + PROP_SHED_DURATION, PROP_DUTY_WINDOW, PROP_ENABLE, PROP_EXPECTED_SHED_LEVEL, + PROP_ACTUAL_SHED_LEVEL, PROP_SHED_LEVELS, PROP_SHED_LEVEL_DESCRIPTIONS, + -1 }; -static const int Load_Control_Properties_Optional[] = { - PROP_DESCRIPTION, PROP_FULL_DUTY_BASELINE, -1}; +static const int Load_Control_Properties_Optional[] = { PROP_DESCRIPTION, + PROP_FULL_DUTY_BASELINE, -1 }; -static const int Load_Control_Properties_Proprietary[] = {-1}; +static const int Load_Control_Properties_Proprietary[] = { -1 }; -void Load_Control_Property_Lists(const int **pRequired, const int **pOptional, - const int **pProprietary) +void Load_Control_Property_Lists( + const int **pRequired, const int **pOptional, const int **pProprietary) { - if (pRequired) + if (pRequired) { *pRequired = Load_Control_Properties_Required; - if (pOptional) + } + if (pOptional) { *pOptional = Load_Control_Properties_Optional; - if (pProprietary) + } + if (pProprietary) { *pProprietary = Load_Control_Properties_Proprietary; + } return; } @@ -202,8 +194,9 @@ void Load_Control_Init(void) /* given instance exists */ bool Load_Control_Valid_Instance(uint32_t object_instance) { - if (object_instance < MAX_LOAD_CONTROLS) + if (object_instance < MAX_LOAD_CONTROLS) { return true; + } return false; } @@ -230,8 +223,9 @@ unsigned Load_Control_Instance_To_Index(uint32_t object_instance) { unsigned index = MAX_LOAD_CONTROLS; - if (object_instance < MAX_LOAD_CONTROLS) + if (object_instance < MAX_LOAD_CONTROLS) { index = object_instance; + } return index; } @@ -250,8 +244,8 @@ static BACNET_SHED_STATE Load_Control_Present_Value(uint32_t object_instance) } /* note: the object name must be unique within this device */ -bool Load_Control_Object_Name(uint32_t object_instance, - BACNET_CHARACTER_STRING *object_name) +bool Load_Control_Object_Name( + uint32_t object_instance, BACNET_CHARACTER_STRING *object_name) { static char text_string[32] = ""; /* okay for single thread */ bool status = false; @@ -286,9 +280,9 @@ static void Update_Current_Time(BACNET_DATE_TIME *bdatetime) timer = time(NULL); tblock = localtime(&timer); datetime_set_values(bdatetime, (uint16_t)tblock->tm_year, - (uint8_t)tblock->tm_mon, (uint8_t)tblock->tm_mday, - (uint8_t)tblock->tm_hour, (uint8_t)tblock->tm_min, - (uint8_t)tblock->tm_sec, 0); + (uint8_t)tblock->tm_mon, (uint8_t)tblock->tm_mday, + (uint8_t)tblock->tm_hour, (uint8_t)tblock->tm_min, + (uint8_t)tblock->tm_sec, 0); } /* convert the shed level request into an Analog Output Present_Value */ @@ -306,7 +300,7 @@ static float Requested_Shed_Level_Value(int object_index) case BACNET_SHED_TYPE_AMOUNT: /* Assumptions: wattage is linear with analog output level */ requested_level = Full_Duty_Baseline[object_index] - - Requested_Shed_Level[object_index].value.amount; + Requested_Shed_Level[object_index].value.amount; requested_level /= Full_Duty_Baseline[object_index]; requested_level *= 100.0; break; @@ -314,8 +308,9 @@ static float Requested_Shed_Level_Value(int object_index) default: for (i = 0; i < MAX_SHED_LEVELS; i++) { if (Shed_Levels[object_index][i] <= - Requested_Shed_Level[object_index].value.level) + Requested_Shed_Level[object_index].value.level) { shed_level_index = i; + } } requested_level = Shed_Level_Values[shed_level_index]; break; @@ -343,8 +338,8 @@ static void Shed_Level_Copy(BACNET_SHED_LEVEL *dest, BACNET_SHED_LEVEL *src) } } -static void Shed_Level_Default_Set(BACNET_SHED_LEVEL *dest, - BACNET_SHED_LEVEL_TYPE type) +static void Shed_Level_Default_Set( + BACNET_SHED_LEVEL *dest, BACNET_SHED_LEVEL_TYPE type) { if (dest) { dest->type = type; @@ -400,14 +395,13 @@ static LOAD_CONTROL_STATE Load_Control_State_Previously[MAX_LOAD_CONTROLS]; #if PRINT_ENABLED_DEBUG static void Print_Load_Control_State(int object_index) { - char *Load_Control_State_Text[MAX_LOAD_CONTROLS] = { - "SHED_INACTIVE", "SHED_REQUEST_PENDING", "SHED_NON_COMPLIANT", - "SHED_COMPLIANT"}; + char *Load_Control_State_Text[MAX_LOAD_CONTROLS] = { "SHED_INACTIVE", + "SHED_REQUEST_PENDING", "SHED_NON_COMPLIANT", "SHED_COMPLIANT" }; if (object_index < MAX_LOAD_CONTROLS) { if (Load_Control_State[object_index] < MAX_LOAD_CONTROL_STATE) { printf("Load Control[%d]=%s\n", object_index, - Load_Control_State_Text[Load_Control_State[object_index]]); + Load_Control_State_Text[Load_Control_State[object_index]]); } } } @@ -416,7 +410,7 @@ static void Print_Load_Control_State(int object_index) void Load_Control_State_Machine(int object_index) { unsigned i = 0; /* loop counter */ - int diff = 0; /* used for datetime comparison */ + int diff = 0; /* used for datetime comparison */ /* is the state machine enabled? */ if (!Load_Control_Enable[object_index]) { @@ -432,25 +426,28 @@ void Load_Control_State_Machine(int object_index) switch (Requested_Shed_Level[object_index].type) { case BACNET_SHED_TYPE_PERCENT: if (Requested_Shed_Level[object_index].value.percent == - DEFAULT_VALUE_PERCENT) + DEFAULT_VALUE_PERCENT) { Load_Control_State[object_index] = SHED_INACTIVE; + } break; case BACNET_SHED_TYPE_AMOUNT: if (Requested_Shed_Level[object_index].value.amount == - DEFAULT_VALUE_AMOUNT) + DEFAULT_VALUE_AMOUNT) { Load_Control_State[object_index] = SHED_INACTIVE; + } break; case BACNET_SHED_TYPE_LEVEL: default: if (Requested_Shed_Level[object_index].value.level == - DEFAULT_VALUE_LEVEL) + DEFAULT_VALUE_LEVEL) { Load_Control_State[object_index] = SHED_INACTIVE; + } break; } if (Load_Control_State[object_index] == SHED_INACTIVE) { #if PRINT_ENABLED_DEBUG printf("Load Control[%d]:Requested Shed Level=Default\n", - object_index); + object_index); #endif break; } @@ -462,24 +459,23 @@ void Load_Control_State_Machine(int object_index) if (datetime_wildcard(&Start_Time[object_index])) { Load_Control_State[object_index] = SHED_INACTIVE; #if PRINT_ENABLED_DEBUG - printf("Load Control[%d]:Start Time=Wildcard\n", - object_index); + printf( + "Load Control[%d]:Start Time=Wildcard\n", object_index); #endif break; } } /* cancel because current time is after start time + duration? */ datetime_copy(&End_Time[object_index], &Start_Time[object_index]); - datetime_add_minutes(&End_Time[object_index], - Shed_Duration[object_index]); + datetime_add_minutes( + &End_Time[object_index], Shed_Duration[object_index]); diff = datetime_compare(&End_Time[object_index], &Current_Time); if (diff < 0) { /* CancelShed */ /* FIXME: stop shedding! i.e. relinquish */ #if PRINT_ENABLED_DEBUG - printf( - "Load Control[%d]:Current Time" - " is after Start Time + Duration\n", + printf("Load Control[%d]:Current Time" + " is after Start Time + Duration\n", object_index); #endif Load_Control_State[object_index] = SHED_INACTIVE; @@ -490,34 +486,30 @@ void Load_Control_State_Machine(int object_index) /* current time prior to start time */ /* ReconfigurePending */ Shed_Level_Copy(&Expected_Shed_Level[object_index], - &Requested_Shed_Level[object_index]); + &Requested_Shed_Level[object_index]); Shed_Level_Default_Set(&Actual_Shed_Level[object_index], - Requested_Shed_Level[object_index].type); + Requested_Shed_Level[object_index].type); } else if (diff > 0) { /* current time after to start time */ #if PRINT_ENABLED_DEBUG - printf( - "Load Control[%d]:Current Time" - " is after Start Time\n", + printf("Load Control[%d]:Current Time" + " is after Start Time\n", object_index); #endif /* AbleToMeetShed */ if (Able_To_Meet_Shed_Request(object_index)) { Shed_Level_Copy(&Expected_Shed_Level[object_index], - &Requested_Shed_Level[object_index]); - Analog_Output_Present_Value_Set( - object_index, Requested_Shed_Level_Value(object_index), - 4); + &Requested_Shed_Level[object_index]); + Analog_Output_Present_Value_Set(object_index, + Requested_Shed_Level_Value(object_index), 4); Shed_Level_Copy(&Actual_Shed_Level[object_index], - &Requested_Shed_Level[object_index]); + &Requested_Shed_Level[object_index]); Load_Control_State[object_index] = SHED_COMPLIANT; } else { /* CannotMeetShed */ - Shed_Level_Default_Set( - &Expected_Shed_Level[object_index], + Shed_Level_Default_Set(&Expected_Shed_Level[object_index], Requested_Shed_Level[object_index].type); - Shed_Level_Default_Set( - &Actual_Shed_Level[object_index], + Shed_Level_Default_Set(&Actual_Shed_Level[object_index], Requested_Shed_Level[object_index].type); Load_Control_State[object_index] = SHED_NON_COMPLIANT; } @@ -525,15 +517,14 @@ void Load_Control_State_Machine(int object_index) break; case SHED_NON_COMPLIANT: datetime_copy(&End_Time[object_index], &Start_Time[object_index]); - datetime_add_minutes(&End_Time[object_index], - Shed_Duration[object_index]); + datetime_add_minutes( + &End_Time[object_index], Shed_Duration[object_index]); diff = datetime_compare(&End_Time[object_index], &Current_Time); if (diff < 0) { /* FinishedUnsuccessfulShed */ #if PRINT_ENABLED_DEBUG - printf( - "Load Control[%d]:Current Time is after Start Time + " - "Duration\n", + printf("Load Control[%d]:Current Time is after Start Time + " + "Duration\n", object_index); #endif Load_Control_State[object_index] = SHED_INACTIVE; @@ -544,7 +535,7 @@ void Load_Control_State_Machine(int object_index) /* UnsuccessfulShedReconfigured */ #if PRINT_ENABLED_DEBUG printf("Load Control[%d]:Control Property written\n", - object_index); + object_index); #endif /* The Written flags will cleared in the next state */ Load_Control_State[object_index] = SHED_REQUEST_PENDING; @@ -554,28 +545,27 @@ void Load_Control_State_Machine(int object_index) /* CanNowComplyWithShed */ #if PRINT_ENABLED_DEBUG printf("Load Control[%d]:Able to meet Shed Request\n", - object_index); + object_index); #endif Shed_Level_Copy(&Expected_Shed_Level[object_index], - &Requested_Shed_Level[object_index]); + &Requested_Shed_Level[object_index]); Analog_Output_Present_Value_Set( object_index, Requested_Shed_Level_Value(object_index), 4); Shed_Level_Copy(&Actual_Shed_Level[object_index], - &Requested_Shed_Level[object_index]); + &Requested_Shed_Level[object_index]); Load_Control_State[object_index] = SHED_COMPLIANT; } break; case SHED_COMPLIANT: datetime_copy(&End_Time[object_index], &Start_Time[object_index]); - datetime_add_minutes(&End_Time[object_index], - Shed_Duration[object_index]); + datetime_add_minutes( + &End_Time[object_index], Shed_Duration[object_index]); diff = datetime_compare(&End_Time[object_index], &Current_Time); if (diff < 0) { /* FinishedSuccessfulShed */ #if PRINT_ENABLED_DEBUG - printf( - "Load Control[%d]:Current Time is after Start Time + " - "Duration\n", + printf("Load Control[%d]:Current Time is after Start Time + " + "Duration\n", object_index); #endif datetime_wildcard_set(&Start_Time[i]); @@ -588,7 +578,7 @@ void Load_Control_State_Machine(int object_index) /* UnsuccessfulShedReconfigured */ #if PRINT_ENABLED_DEBUG printf("Load Control[%d]:Control Property written\n", - object_index); + object_index); #endif /* The Written flags will cleared in the next state */ Load_Control_State[object_index] = SHED_REQUEST_PENDING; @@ -598,12 +588,12 @@ void Load_Control_State_Machine(int object_index) /* CanNoLongerComplyWithShed */ #if PRINT_ENABLED_DEBUG printf("Load Control[%d]:Not able to meet Shed Request\n", - object_index); + object_index); #endif Shed_Level_Default_Set(&Expected_Shed_Level[object_index], - Requested_Shed_Level[object_index].type); + Requested_Shed_Level[object_index].type); Shed_Level_Default_Set(&Actual_Shed_Level[object_index], - Requested_Shed_Level[object_index].type); + Requested_Shed_Level[object_index].type); Load_Control_State[object_index] = SHED_NON_COMPLIANT; } break; @@ -615,9 +605,9 @@ void Load_Control_State_Machine(int object_index) #endif /* The Written flag will cleared in the next state */ Shed_Level_Copy(&Expected_Shed_Level[object_index], - &Requested_Shed_Level[object_index]); + &Requested_Shed_Level[object_index]); Shed_Level_Default_Set(&Actual_Shed_Level[object_index], - Requested_Shed_Level[object_index].type); + Requested_Shed_Level[object_index].type); Load_Control_State[object_index] = SHED_REQUEST_PENDING; } break; @@ -713,38 +703,35 @@ int Load_Control_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) case PROP_REQUESTED_SHED_LEVEL: switch (Requested_Shed_Level[object_index].type) { case BACNET_SHED_TYPE_PERCENT: - apdu_len = encode_context_unsigned( - &apdu[0], 0, + apdu_len = encode_context_unsigned(&apdu[0], 0, Requested_Shed_Level[object_index].value.percent); break; case BACNET_SHED_TYPE_AMOUNT: - apdu_len = encode_context_real( - &apdu[0], 2, + apdu_len = encode_context_real(&apdu[0], 2, Requested_Shed_Level[object_index].value.amount); break; case BACNET_SHED_TYPE_LEVEL: default: - apdu_len = encode_context_unsigned( - &apdu[0], 1, + apdu_len = encode_context_unsigned(&apdu[0], 1, Requested_Shed_Level[object_index].value.level); break; } break; case PROP_START_TIME: - len = encode_application_date(&apdu[0], - &Start_Time[object_index].date); + len = encode_application_date( + &apdu[0], &Start_Time[object_index].date); apdu_len = len; - len = encode_application_time(&apdu[apdu_len], - &Start_Time[object_index].time); + len = encode_application_time( + &apdu[apdu_len], &Start_Time[object_index].time); apdu_len += len; break; case PROP_SHED_DURATION: - apdu_len = encode_application_unsigned(&apdu[0], - Shed_Duration[object_index]); + apdu_len = encode_application_unsigned( + &apdu[0], Shed_Duration[object_index]); break; case PROP_DUTY_WINDOW: - apdu_len = encode_application_unsigned(&apdu[0], - Duty_Window[object_index]); + apdu_len = encode_application_unsigned( + &apdu[0], Duty_Window[object_index]); break; case PROP_ENABLE: state = Load_Control_Enable[object_index]; @@ -757,19 +744,16 @@ int Load_Control_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) case PROP_EXPECTED_SHED_LEVEL: switch (Expected_Shed_Level[object_index].type) { case BACNET_SHED_TYPE_PERCENT: - apdu_len = encode_context_unsigned( - &apdu[0], 0, + apdu_len = encode_context_unsigned(&apdu[0], 0, Expected_Shed_Level[object_index].value.percent); break; case BACNET_SHED_TYPE_AMOUNT: - apdu_len = encode_context_real( - &apdu[0], 2, + apdu_len = encode_context_real(&apdu[0], 2, Expected_Shed_Level[object_index].value.amount); break; case BACNET_SHED_TYPE_LEVEL: default: - apdu_len = encode_context_unsigned( - &apdu[0], 1, + apdu_len = encode_context_unsigned(&apdu[0], 1, Expected_Shed_Level[object_index].value.level); break; } @@ -777,40 +761,38 @@ int Load_Control_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) case PROP_ACTUAL_SHED_LEVEL: switch (Actual_Shed_Level[object_index].type) { case BACNET_SHED_TYPE_PERCENT: - apdu_len = encode_context_unsigned( - &apdu[0], 0, + apdu_len = encode_context_unsigned(&apdu[0], 0, Actual_Shed_Level[object_index].value.percent); break; case BACNET_SHED_TYPE_AMOUNT: - apdu_len = encode_context_real( - &apdu[0], 2, + apdu_len = encode_context_real(&apdu[0], 2, Actual_Shed_Level[object_index].value.amount); break; case BACNET_SHED_TYPE_LEVEL: default: - apdu_len = encode_context_unsigned( - &apdu[0], 1, + apdu_len = encode_context_unsigned(&apdu[0], 1, Actual_Shed_Level[object_index].value.level); break; } break; case PROP_SHED_LEVELS: /* Array element zero is the number of elements in the array */ - if (rpdata->array_index == 0) + if (rpdata->array_index == 0) { apdu_len = encode_application_unsigned(&apdu[0], MAX_SHED_LEVELS); - /* if no index was specified, then try to encode the entire list */ - /* into one packet. */ - else if (rpdata->array_index == BACNET_ARRAY_ALL) { + /* if no index was specified, then try to encode the entire list + */ + /* into one packet. */ + } else if (rpdata->array_index == BACNET_ARRAY_ALL) { apdu_len = 0; for (i = 0; i < MAX_SHED_LEVELS; i++) { /* FIXME: check if we have room before adding it to APDU */ len = encode_application_unsigned( &apdu[apdu_len], Shed_Levels[object_index][i]); /* add it if we have room */ - if ((apdu_len + len) < MAX_APDU) + if ((apdu_len + len) < MAX_APDU) { apdu_len += len; - else { + } else { rpdata->error_code = ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED; apdu_len = BACNET_STATUS_ABORT; @@ -819,8 +801,7 @@ int Load_Control_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) } } else { if (rpdata->array_index <= MAX_SHED_LEVELS) { - apdu_len = encode_application_unsigned( - &apdu[0], + apdu_len = encode_application_unsigned(&apdu[0], Shed_Levels[object_index][rpdata->array_index - 1]); } else { rpdata->error_class = ERROR_CLASS_PROPERTY; @@ -831,23 +812,24 @@ int Load_Control_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) break; case PROP_SHED_LEVEL_DESCRIPTIONS: /* Array element zero is the number of elements in the array */ - if (rpdata->array_index == 0) + if (rpdata->array_index == 0) { apdu_len = encode_application_unsigned(&apdu[0], MAX_SHED_LEVELS); - /* if no index was specified, then try to encode the entire list */ - /* into one packet. */ - else if (rpdata->array_index == BACNET_ARRAY_ALL) { + /* if no index was specified, then try to encode the entire list + */ + /* into one packet. */ + } else if (rpdata->array_index == BACNET_ARRAY_ALL) { apdu_len = 0; for (i = 0; i < MAX_SHED_LEVELS; i++) { /* FIXME: check if we have room before adding it to APDU */ - characterstring_init_ansi(&char_string, - Shed_Level_Descriptions[i]); - len = encode_application_character_string(&apdu[apdu_len], - &char_string); + characterstring_init_ansi( + &char_string, Shed_Level_Descriptions[i]); + len = encode_application_character_string( + &apdu[apdu_len], &char_string); /* add it if we have room */ - if ((apdu_len + len) < MAX_APDU) + if ((apdu_len + len) < MAX_APDU) { apdu_len += len; - else { + } else { rpdata->error_code = ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED; apdu_len = BACNET_STATUS_ABORT; @@ -856,8 +838,7 @@ int Load_Control_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) } } else { if (rpdata->array_index <= MAX_SHED_LEVELS) { - characterstring_init_ansi( - &char_string, + characterstring_init_ansi(&char_string, Shed_Level_Descriptions[rpdata->array_index - 1]); apdu_len = encode_application_character_string( &apdu[0], &char_string); @@ -898,8 +879,8 @@ bool Load_Control_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) TempDate; /* build here in case of error in time half of datetime */ /* decode the some of the request */ - len = bacapp_decode_application_data(wp_data->application_data, - wp_data->application_data_len, &value); + len = bacapp_decode_application_data( + wp_data->application_data, wp_data->application_data_len, &value); /* FIXME: len < application_data_len: more data? */ if (len < 0) { /* error while decoding - a value larger than we can handle */ @@ -918,8 +899,8 @@ bool Load_Control_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) switch (wp_data->object_property) { case PROP_REQUESTED_SHED_LEVEL: len = bacapp_decode_context_data(wp_data->application_data, - wp_data->application_data_len, - &value, PROP_REQUESTED_SHED_LEVEL); + wp_data->application_data_len, &value, + PROP_REQUESTED_SHED_LEVEL); if (value.context_tag == 0) { /* percent - Unsigned */ Requested_Shed_Level[object_index].type = @@ -952,22 +933,20 @@ bool Load_Control_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) break; case PROP_START_TIME: - status = - WPValidateArgType(&value, BACNET_APPLICATION_TAG_DATE, - &wp_data->error_class, &wp_data->error_code); + status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_DATE, + &wp_data->error_class, &wp_data->error_code); if (!status) { /* don't continue if we don't have a valid date */ break; } /* Hold the date until we are sure the time is also there */ TempDate = value.type.Date; - len = bacapp_decode_application_data( - wp_data->application_data + len, - wp_data->application_data_len - len, &value); + len = + bacapp_decode_application_data(wp_data->application_data + len, + wp_data->application_data_len - len, &value); if (len) { status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_TIME, - &wp_data->error_class, - &wp_data->error_code); + &wp_data->error_class, &wp_data->error_code); if (status) { /* Write time and date and set written flag */ Start_Time[object_index].date = TempDate; @@ -984,7 +963,7 @@ bool Load_Control_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) case PROP_SHED_DURATION: status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_UNSIGNED_INT, - &wp_data->error_class, &wp_data->error_code); + &wp_data->error_class, &wp_data->error_code); if (status) { Shed_Duration[object_index] = value.type.Unsigned_Int; Load_Control_Request_Written[object_index] = true; @@ -994,7 +973,7 @@ bool Load_Control_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) case PROP_DUTY_WINDOW: status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_UNSIGNED_INT, - &wp_data->error_class, &wp_data->error_code); + &wp_data->error_class, &wp_data->error_code); if (status) { Duty_Window[object_index] = value.type.Unsigned_Int; Load_Control_Request_Written[object_index] = true; @@ -1004,7 +983,7 @@ bool Load_Control_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) case PROP_SHED_LEVELS: status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_UNSIGNED_INT, - &wp_data->error_class, &wp_data->error_code); + &wp_data->error_class, &wp_data->error_code); if (status) { /* re-write the size of the array? */ if (wp_data->array_index == 0) { @@ -1027,9 +1006,8 @@ bool Load_Control_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) break; case PROP_ENABLE: - status = - WPValidateArgType(&value, BACNET_APPLICATION_TAG_BOOLEAN, - &wp_data->error_class, &wp_data->error_code); + status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_BOOLEAN, + &wp_data->error_class, &wp_data->error_code); if (status) { Load_Control_Enable[object_index] = value.type.Boolean; } @@ -1077,9 +1055,8 @@ static void Load_Control_WriteProperty_Request_Shed_Percent( } #endif -static void Load_Control_WriteProperty_Request_Shed_Level(Test *pTest, - int instance, - unsigned level) +static void Load_Control_WriteProperty_Request_Shed_Level( + Test *pTest, int instance, unsigned level) { bool status = false; BACNET_APPLICATION_DATA_VALUE value; @@ -1128,8 +1105,8 @@ static void Load_Control_WriteProperty_Request_Shed_Amount( } #endif -static void Load_Control_WriteProperty_Enable(Test *pTest, int instance, - bool enable) +static void Load_Control_WriteProperty_Enable( + Test *pTest, int instance, bool enable) { bool status = false; BACNET_APPLICATION_DATA_VALUE value; @@ -1152,8 +1129,8 @@ static void Load_Control_WriteProperty_Enable(Test *pTest, int instance, ct_test(pTest, status == true); } -static void Load_Control_WriteProperty_Shed_Duration(Test *pTest, int instance, - unsigned duration) +static void Load_Control_WriteProperty_Shed_Duration( + Test *pTest, int instance, unsigned duration) { bool status = false; BACNET_APPLICATION_DATA_VALUE value; @@ -1175,8 +1152,8 @@ static void Load_Control_WriteProperty_Shed_Duration(Test *pTest, int instance, ct_test(pTest, status == true); } -static void Load_Control_WriteProperty_Duty_Window(Test *pTest, int instance, - unsigned duration) +static void Load_Control_WriteProperty_Duty_Window( + Test *pTest, int instance, unsigned duration) { bool status = false; BACNET_APPLICATION_DATA_VALUE value; @@ -1198,8 +1175,8 @@ static void Load_Control_WriteProperty_Duty_Window(Test *pTest, int instance, ct_test(pTest, status == true); } -static void Load_Control_WriteProperty_Start_Time_Wildcards(Test *pTest, - int instance) +static void Load_Control_WriteProperty_Start_Time_Wildcards( + Test *pTest, int instance) { int len = 0; bool status = false; @@ -1229,9 +1206,15 @@ static void Load_Control_WriteProperty_Start_Time_Wildcards(Test *pTest, ct_test(pTest, status == true); } -static void Load_Control_WriteProperty_Start_Time( - Test *pTest, int instance, uint16_t year, uint8_t month, uint8_t day, - uint8_t hour, uint8_t minute, uint8_t seconds, uint8_t hundredths) +static void Load_Control_WriteProperty_Start_Time(Test *pTest, + int instance, + uint16_t year, + uint8_t month, + uint8_t day, + uint8_t hour, + uint8_t minute, + uint8_t seconds, + uint8_t hundredths) { int len = 0; bool status = false; @@ -1402,7 +1385,7 @@ void testLoadControlStateMachine(Test *pTest) void testLoadControl(Test *pTest) { - uint8_t apdu[MAX_APDU] = {0}; + uint8_t apdu[MAX_APDU] = { 0 }; int len = 0; uint32_t len_value = 0; uint8_t tag_number = 0; diff --git a/demo/object/lc.h b/src/bacnet/basic/object/lc.h similarity index 95% rename from demo/object/lc.h rename to src/bacnet/basic/object/lc.h index c1d199b4..1a447f1e 100644 --- a/demo/object/lc.h +++ b/src/bacnet/basic/object/lc.h @@ -27,10 +27,10 @@ #include #include -#include "bacdef.h" -#include "bacerror.h" -#include "rp.h" -#include "wp.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacerror.h" +#include "bacnet/rp.h" +#include "bacnet/wp.h" #ifdef __cplusplus extern "C" { diff --git a/demo/object/lc.ide b/src/bacnet/basic/object/lc.ide similarity index 100% rename from demo/object/lc.ide rename to src/bacnet/basic/object/lc.ide diff --git a/demo/object/lc.mak b/src/bacnet/basic/object/lc.mak similarity index 62% rename from demo/object/lc.mak rename to src/bacnet/basic/object/lc.mak index 669172e7..c353eea0 100644 --- a/demo/object/lc.mak +++ b/src/bacnet/basic/object/lc.mak @@ -8,16 +8,16 @@ DEFINES = -DBIG_ENDIAN=0 -DTEST -DBACAPP_ALL -DTEST_LOAD_CONTROL CFLAGS = -Wall $(INCLUDES) $(DEFINES) -g SRCS = lc.c ao.c \ - $(SRC_DIR)/bacdcode.c \ - $(SRC_DIR)/bacint.c \ - $(SRC_DIR)/bacstr.c \ - $(SRC_DIR)/bacreal.c \ - $(SRC_DIR)/datetime.c \ - $(SRC_DIR)/bacapp.c \ - $(SRC_DIR)/bacdevobjpropref.c \ - $(SRC_DIR)/bactext.c \ - $(SRC_DIR)/indtext.c \ - $(SRC_DIR)/lighting.c \ + $(SRC_DIR)/bacnet/bacdcode.c \ + $(SRC_DIR)/bacnet/bacint.c \ + $(SRC_DIR)/bacnet/bacstr.c \ + $(SRC_DIR)/bacnet/bacreal.c \ + $(SRC_DIR)/bacnet/datetime.c \ + $(SRC_DIR)/bacnet/bacapp.c \ + $(SRC_DIR)/bacnet/bacdevobjpropref.c \ + $(SRC_DIR)/bacnet/bactext.c \ + $(SRC_DIR)/bacnet/indtext.c \ + $(SRC_DIR)/bacnet/lighting.c \ $(TEST_DIR)/ctest.c TARGET = load_control diff --git a/demo/object/lo.c b/src/bacnet/basic/object/lo.c similarity index 88% rename from demo/object/lo.c rename to src/bacnet/basic/object/lo.c index a431aa69..7caca213 100644 --- a/demo/object/lo.c +++ b/src/bacnet/basic/object/lo.c @@ -30,18 +30,18 @@ #include #include #include -#include "bacdef.h" -#include "bacdcode.h" -#include "bacenum.h" -#include "bacapp.h" -#include "config.h" /* the custom stuff */ -#include "rp.h" -#include "wp.h" -#include "lighting.h" -#include "handlers.h" -#include "proplist.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacenum.h" +#include "bacnet/bacapp.h" +#include "bacnet/config.h" /* the custom stuff */ +#include "bacnet/rp.h" +#include "bacnet/wp.h" +#include "bacnet/lighting.h" +#include "bacnet/basic/services.h" +#include "bacnet/proplist.h" /* me! */ -#include "lo.h" +#include "bacnet/basic/object/lo.h" #ifndef MAX_LIGHTING_OUTPUTS #define MAX_LIGHTING_OUTPUTS 8 @@ -76,28 +76,17 @@ struct lighting_output_object Lighting_Output[MAX_LIGHTING_OUTPUTS]; /* These arrays are used by the ReadPropertyMultiple handler and property-list property (as of protocol-revision 14) */ static const int Lighting_Output_Properties_Required[] = { - PROP_OBJECT_IDENTIFIER, - PROP_OBJECT_NAME, - PROP_OBJECT_TYPE, - PROP_PRESENT_VALUE, - PROP_TRACKING_VALUE, - PROP_LIGHTING_COMMAND, - PROP_IN_PROGRESS, - PROP_STATUS_FLAGS, - PROP_OUT_OF_SERVICE, - PROP_BLINK_WARN_ENABLE, - PROP_EGRESS_TIME, - PROP_EGRESS_ACTIVE, - PROP_DEFAULT_FADE_TIME, - PROP_DEFAULT_RAMP_RATE, - PROP_DEFAULT_STEP_INCREMENT, - PROP_PRIORITY_ARRAY, - PROP_RELINQUISH_DEFAULT, - PROP_LIGHTING_COMMAND_DEFAULT_PRIORITY, - -1}; -static const int Lighting_Output_Properties_Optional[] = {-1}; + PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME, PROP_OBJECT_TYPE, + PROP_PRESENT_VALUE, PROP_TRACKING_VALUE, PROP_LIGHTING_COMMAND, + PROP_IN_PROGRESS, PROP_STATUS_FLAGS, PROP_OUT_OF_SERVICE, + PROP_BLINK_WARN_ENABLE, PROP_EGRESS_TIME, PROP_EGRESS_ACTIVE, + PROP_DEFAULT_FADE_TIME, PROP_DEFAULT_RAMP_RATE, PROP_DEFAULT_STEP_INCREMENT, + PROP_PRIORITY_ARRAY, PROP_RELINQUISH_DEFAULT, + PROP_LIGHTING_COMMAND_DEFAULT_PRIORITY, -1 +}; +static const int Lighting_Output_Properties_Optional[] = { -1 }; -static const int Lighting_Output_Properties_Proprietary[] = {-1}; +static const int Lighting_Output_Properties_Proprietary[] = { -1 }; /** * Returns the list of required, optional, and proprietary properties. @@ -110,16 +99,18 @@ static const int Lighting_Output_Properties_Proprietary[] = {-1}; * @param pProprietary - pointer to list of int terminated by -1, of * BACnet proprietary properties for this object. */ -void Lighting_Output_Property_Lists(const int **pRequired, - const int **pOptional, - const int **pProprietary) +void Lighting_Output_Property_Lists( + const int **pRequired, const int **pOptional, const int **pProprietary) { - if (pRequired) + if (pRequired) { *pRequired = Lighting_Output_Properties_Required; - if (pOptional) + } + if (pOptional) { *pOptional = Lighting_Output_Properties_Optional; - if (pProprietary) + } + if (pProprietary) { *pProprietary = Lighting_Output_Properties_Proprietary; + } return; } @@ -229,8 +220,8 @@ float Lighting_Output_Present_Value(uint32_t object_instance) * * @return priority-value of the object */ -static float Lighting_Output_Priority_Value(uint32_t object_instance, - unsigned priority) +static float Lighting_Output_Priority_Value( + uint32_t object_instance, unsigned priority) { float value = 0.0; unsigned index = 0; @@ -255,8 +246,8 @@ static float Lighting_Output_Priority_Value(uint32_t object_instance, * * @return true if the priority slot is active */ -static bool Lighting_Output_Priority_Active(uint32_t object_instance, - unsigned priority) +static bool Lighting_Output_Priority_Active( + uint32_t object_instance, unsigned priority) { bool status = false; unsigned index = 0; @@ -265,8 +256,8 @@ static bool Lighting_Output_Priority_Active(uint32_t object_instance, if (index < MAX_LIGHTING_OUTPUTS) { if (priority && (priority <= BACNET_MAX_PRIORITY)) { priority--; - if (BIT_CHECK(Lighting_Output[index].Priority_Active_Bits, - priority)) { + if (BIT_CHECK( + Lighting_Output[index].Priority_Active_Bits, priority)) { status = true; } } @@ -284,8 +275,8 @@ static bool Lighting_Output_Priority_Active(uint32_t object_instance, */ unsigned Lighting_Output_Present_Value_Priority(uint32_t object_instance) { - unsigned index = 0; /* instance to index conversion */ - unsigned p = 0; /* loop counter */ + unsigned index = 0; /* instance to index conversion */ + unsigned p = 0; /* loop counter */ unsigned priority = 0; /* return value */ index = Lighting_Output_Instance_To_Index(object_instance); @@ -311,8 +302,8 @@ unsigned Lighting_Output_Present_Value_Priority(uint32_t object_instance) * * @return true if values are within range and present-value is set. */ -bool Lighting_Output_Present_Value_Set(uint32_t object_instance, float value, - unsigned priority) +bool Lighting_Output_Present_Value_Set( + uint32_t object_instance, float value, unsigned priority) { unsigned index = 0; bool status = false; @@ -340,8 +331,8 @@ bool Lighting_Output_Present_Value_Set(uint32_t object_instance, float value, * * @return true if values are within range and present-value is set. */ -bool Lighting_Output_Present_Value_Relinquish(uint32_t object_instance, - unsigned priority) +bool Lighting_Output_Present_Value_Relinquish( + uint32_t object_instance, unsigned priority) { unsigned index = 0; bool status = false; @@ -370,8 +361,8 @@ bool Lighting_Output_Present_Value_Relinquish(uint32_t object_instance, * * @return true if object-name was retrieved */ -bool Lighting_Output_Object_Name(uint32_t object_instance, - BACNET_CHARACTER_STRING *object_name) +bool Lighting_Output_Object_Name( + uint32_t object_instance, BACNET_CHARACTER_STRING *object_name) { char text_string[32] = ""; bool status = false; @@ -379,8 +370,8 @@ bool Lighting_Output_Object_Name(uint32_t object_instance, index = Lighting_Output_Instance_To_Index(object_instance); if (index < MAX_LIGHTING_OUTPUTS) { - sprintf(text_string, "LIGHTING OUTPUT %lu", - (unsigned long)object_instance); + sprintf( + text_string, "LIGHTING OUTPUT %lu", (unsigned long)object_instance); status = characterstring_init_ansi(object_name, text_string); } @@ -395,8 +386,8 @@ bool Lighting_Output_Object_Name(uint32_t object_instance, * * @return true if lighting command was set */ -bool Lighting_Output_Lighting_Command_Set(uint32_t object_instance, - BACNET_LIGHTING_COMMAND *value) +bool Lighting_Output_Lighting_Command_Set( + uint32_t object_instance, BACNET_LIGHTING_COMMAND *value) { bool status = false; unsigned index = 0; @@ -404,8 +395,8 @@ bool Lighting_Output_Lighting_Command_Set(uint32_t object_instance, index = Lighting_Output_Instance_To_Index(object_instance); if (index < MAX_LIGHTING_OUTPUTS) { // FIXME: check lighting command member values - status = lighting_command_copy(&Lighting_Output[index].Lighting_Command, - value); + status = lighting_command_copy( + &Lighting_Output[index].Lighting_Command, value); // FIXME: set all the other values, and get the light levels moving } @@ -420,8 +411,8 @@ bool Lighting_Output_Lighting_Command_Set(uint32_t object_instance, * * @return true if lighting command was retrieved */ -bool Lighting_Output_Lighting_Command(uint32_t object_instance, - BACNET_LIGHTING_COMMAND *value) +bool Lighting_Output_Lighting_Command( + uint32_t object_instance, BACNET_LIGHTING_COMMAND *value) { bool status = false; unsigned index = 0; @@ -465,8 +456,8 @@ BACNET_LIGHTING_IN_PROGRESS Lighting_Output_In_Progress( * * @return true if value was set */ -bool Lighting_Output_In_Progress_Set(uint32_t object_instance, - BACNET_LIGHTING_IN_PROGRESS in_progress) +bool Lighting_Output_In_Progress_Set( + uint32_t object_instance, BACNET_LIGHTING_IN_PROGRESS in_progress) { bool status = false; unsigned index = 0; @@ -552,8 +543,8 @@ bool Lighting_Output_Blink_Warn_Enable(uint32_t object_instance) * * @return true if value was set */ -bool Lighting_Output_Blink_Warn_Enable_Set(uint32_t object_instance, - bool enable) +bool Lighting_Output_Blink_Warn_Enable_Set( + uint32_t object_instance, bool enable) { bool status = false; unsigned int index = 0; @@ -662,8 +653,8 @@ uint32_t Lighting_Output_Default_Fade_Time(uint32_t object_instance) * * @return true if value was set */ -bool Lighting_Output_Default_Fade_Time_Set(uint32_t object_instance, - uint32_t milliseconds) +bool Lighting_Output_Default_Fade_Time_Set( + uint32_t object_instance, uint32_t milliseconds) { bool status = false; unsigned int index = 0; @@ -708,8 +699,8 @@ float Lighting_Output_Default_Ramp_Rate(uint32_t object_instance) * * @return true if value was set */ -bool Lighting_Output_Default_Ramp_Rate_Set(uint32_t object_instance, - float percent_per_second) +bool Lighting_Output_Default_Ramp_Rate_Set( + uint32_t object_instance, float percent_per_second) { bool status = false; unsigned int index = 0; @@ -754,8 +745,8 @@ float Lighting_Output_Default_Step_Increment(uint32_t object_instance) * * @return true if value was set */ -bool Lighting_Output_Default_Step_Increment_Set(uint32_t object_instance, - float step_increment) +bool Lighting_Output_Default_Step_Increment_Set( + uint32_t object_instance, float step_increment) { bool status = false; unsigned int index = 0; @@ -802,8 +793,8 @@ unsigned Lighting_Output_Default_Priority(uint32_t object_instance) * * @return true if value was set */ -bool Lighting_Output_Default_Priority_Set(uint32_t object_instance, - unsigned priority) +bool Lighting_Output_Default_Priority_Set( + uint32_t object_instance, unsigned priority) { bool status = false; unsigned int index = 0; @@ -887,8 +878,8 @@ float Lighting_Output_Relinquish_Default(uint32_t object_instance) * * @return true if the relinquish-default property value was set */ -bool Lighting_Output_Relinquish_Default_Set(uint32_t object_instance, - float value) +bool Lighting_Output_Relinquish_Default_Set( + uint32_t object_instance, float value) { bool status = false; unsigned int index = 0; @@ -953,8 +944,8 @@ int Lighting_Output_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) apdu_len = encode_application_real(&apdu[0], real_value); break; case PROP_LIGHTING_COMMAND: - Lighting_Output_Lighting_Command(rpdata->object_instance, - &lighting_command); + Lighting_Output_Lighting_Command( + rpdata->object_instance, &lighting_command); apdu_len = lighting_command_encode(&apdu[0], &lighting_command); break; case PROP_IN_PROGRESS: @@ -1013,19 +1004,19 @@ int Lighting_Output_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) /* into one packet. */ } else if (rpdata->array_index == BACNET_ARRAY_ALL) { for (i = 1; i <= BACNET_MAX_PRIORITY; i++) { - if (Lighting_Output_Priority_Active(rpdata->object_instance, - i)) { + if (Lighting_Output_Priority_Active( + rpdata->object_instance, i)) { real_value = Lighting_Output_Priority_Value( rpdata->object_instance, i); - len = encode_application_real(&apdu[apdu_len], - real_value); + len = encode_application_real( + &apdu[apdu_len], real_value); } else { len = encode_application_null(&apdu[apdu_len]); } /* add it if we have room */ - if ((apdu_len + len) < MAX_APDU) + if ((apdu_len + len) < MAX_APDU) { apdu_len += len; - else { + } else { rpdata->error_code = ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED; apdu_len = BACNET_STATUS_ABORT; @@ -1034,12 +1025,12 @@ int Lighting_Output_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) } } else { if (rpdata->array_index <= BACNET_MAX_PRIORITY) { - if (Lighting_Output_Priority_Active(rpdata->object_instance, - rpdata->array_index)) { + if (Lighting_Output_Priority_Active( + rpdata->object_instance, rpdata->array_index)) { real_value = Lighting_Output_Priority_Value( rpdata->object_instance, rpdata->array_index); - len = encode_application_real(&apdu[apdu_len], - real_value); + len = encode_application_real( + &apdu[apdu_len], real_value); } else { len = encode_application_null(&apdu[apdu_len]); } @@ -1093,8 +1084,8 @@ bool Lighting_Output_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) BACNET_APPLICATION_DATA_VALUE value; /* decode the some of the request */ - len = bacapp_decode_application_data(wp_data->application_data, - wp_data->application_data_len, &value); + len = bacapp_decode_application_data( + wp_data->application_data, wp_data->application_data_len, &value); /* FIXME: len < application_data_len: more data? */ if (len < 0) { /* error while decoding - a value larger than we can handle */ @@ -1115,9 +1106,9 @@ bool Lighting_Output_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) /* Command priority 6 is reserved for use by Minimum On/Off algorithm and may not be used for other purposes in any object. */ - status = Lighting_Output_Present_Value_Set( - wp_data->object_instance, value.type.Real, - wp_data->priority); + status = + Lighting_Output_Present_Value_Set(wp_data->object_instance, + value.type.Real, wp_data->priority); if (wp_data->priority == 6) { /* Command priority 6 is reserved for use by Minimum On/Off algorithm and may not be used for other purposes in any @@ -1130,8 +1121,7 @@ bool Lighting_Output_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) } } else { status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_NULL, - &wp_data->error_class, - &wp_data->error_code); + &wp_data->error_class, &wp_data->error_code); if (status) { if (wp_data->priority == 6) { /* Command priority 6 is reserved for use by Minimum @@ -1166,12 +1156,11 @@ bool Lighting_Output_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) } break; case PROP_OUT_OF_SERVICE: - status = - WPValidateArgType(&value, BACNET_APPLICATION_TAG_BOOLEAN, - &wp_data->error_class, &wp_data->error_code); + status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_BOOLEAN, + &wp_data->error_class, &wp_data->error_code); if (status) { - Lighting_Output_Out_Of_Service_Set(wp_data->object_instance, - value.type.Boolean); + Lighting_Output_Out_Of_Service_Set( + wp_data->object_instance, value.type.Boolean); } break; case PROP_OBJECT_IDENTIFIER: @@ -1209,8 +1198,8 @@ bool Lighting_Output_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) * called. Works best when called about every 10 milliseconds. */ static void Lighting_Output_Ramp_Handler(struct lighting_output_object *pLight, - BACNET_LIGHTING_COMMAND *pCommand, - uint16_t milliseconds) + BACNET_LIGHTING_COMMAND *pCommand, + uint16_t milliseconds) { if (pLight && pCommand) { } @@ -1225,8 +1214,8 @@ static void Lighting_Output_Ramp_Handler(struct lighting_output_object *pLight, * called. Works best when called about every 10 milliseconds. */ static void Lighting_Output_Fade_Handler(struct lighting_output_object *pLight, - BACNET_LIGHTING_COMMAND *pCommand, - uint16_t milliseconds) + BACNET_LIGHTING_COMMAND *pCommand, + uint16_t milliseconds) { if (pLight && pCommand) { } @@ -1341,8 +1330,9 @@ void Lighting_Output_Init(void) #include "ctest.h" bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue, - uint8_t ucExpectedTag, BACNET_ERROR_CLASS *pErrorClass, - BACNET_ERROR_CODE *pErrorCode) + uint8_t ucExpectedTag, + BACNET_ERROR_CLASS *pErrorClass, + BACNET_ERROR_CODE *pErrorCode) { pValue = pValue; ucExpectedTag = ucExpectedTag; @@ -1354,7 +1344,7 @@ bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue, void testLightingOutput(Test *pTest) { - uint8_t apdu[MAX_APDU] = {0}; + uint8_t apdu[MAX_APDU] = { 0 }; int len = 0; uint32_t len_value = 0; uint8_t tag_number = 0; diff --git a/demo/object/lo.h b/src/bacnet/basic/object/lo.h similarity index 98% rename from demo/object/lo.h rename to src/bacnet/basic/object/lo.h index 1bfcb1b7..44915c67 100644 --- a/demo/object/lo.h +++ b/src/bacnet/basic/object/lo.h @@ -27,10 +27,10 @@ #include #include -#include "bacdef.h" -#include "bacerror.h" -#include "rp.h" -#include "wp.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacerror.h" +#include "bacnet/rp.h" +#include "bacnet/wp.h" #ifdef __cplusplus extern "C" { diff --git a/demo/object/lo.mak b/src/bacnet/basic/object/lo.mak old mode 100755 new mode 100644 similarity index 62% rename from demo/object/lo.mak rename to src/bacnet/basic/object/lo.mak index d3872b9b..a9c50a17 --- a/demo/object/lo.mak +++ b/src/bacnet/basic/object/lo.mak @@ -8,16 +8,16 @@ DEFINES = -DBIG_ENDIAN=0 -DTEST -DBACAPP_ALL -DTEST_LIGHTING_OUTPUT CFLAGS = -Wall $(INCLUDES) $(DEFINES) -g SRCS = lo.c \ - $(SRC_DIR)/bacdcode.c \ - $(SRC_DIR)/bacint.c \ - $(SRC_DIR)/bacstr.c \ - $(SRC_DIR)/bacreal.c \ - $(SRC_DIR)/datetime.c \ - $(SRC_DIR)/bacapp.c \ - $(SRC_DIR)/bacdevobjpropref.c \ - $(SRC_DIR)/bactext.c \ - $(SRC_DIR)/indtext.c \ - $(SRC_DIR)/lighting.c \ + $(SRC_DIR)/bacnet/bacdcode.c \ + $(SRC_DIR)/bacnet/bacint.c \ + $(SRC_DIR)/bacnet/bacstr.c \ + $(SRC_DIR)/bacnet/bacreal.c \ + $(SRC_DIR)/bacnet/datetime.c \ + $(SRC_DIR)/bacnet/bacapp.c \ + $(SRC_DIR)/bacnet/bacdevobjpropref.c \ + $(SRC_DIR)/bacnet/bactext.c \ + $(SRC_DIR)/bacnet/indtext.c \ + $(SRC_DIR)/bacnet/lighting.c \ $(TEST_DIR)/ctest.c TARGET = lighting_output diff --git a/demo/object/lsp.c b/src/bacnet/basic/object/lsp.c similarity index 87% rename from demo/object/lsp.c rename to src/bacnet/basic/object/lsp.c index 0f26882b..b66ea8aa 100644 --- a/demo/object/lsp.c +++ b/src/bacnet/basic/object/lsp.c @@ -28,16 +28,16 @@ #include #include #include -#include "bacdef.h" -#include "bacdcode.h" -#include "bacenum.h" -#include "bacapp.h" -#include "config.h" /* the custom stuff */ -#include "rp.h" -#include "wp.h" -#include "lsp.h" -#include "handlers.h" -#include "proplist.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacenum.h" +#include "bacnet/bacapp.h" +#include "bacnet/config.h" /* the custom stuff */ +#include "bacnet/rp.h" +#include "bacnet/wp.h" +#include "bacnet/basic/object/lsp.h" +#include "bacnet/basic/services.h" +#include "bacnet/proplist.h" #ifndef MAX_LIFE_SAFETY_POINTS #define MAX_LIFE_SAFETY_POINTS 7 @@ -56,18 +56,16 @@ static bool Life_Safety_Point_Out_Of_Service[MAX_LIFE_SAFETY_POINTS]; /* These three arrays are used by the ReadPropertyMultiple handler */ static const int Life_Safety_Point_Properties_Required[] = { - PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME, - PROP_OBJECT_TYPE, PROP_PRESENT_VALUE, - PROP_TRACKING_VALUE, PROP_STATUS_FLAGS, - PROP_EVENT_STATE, PROP_OUT_OF_SERVICE, - PROP_RELIABILITY, PROP_MODE, - PROP_ACCEPTED_MODES, PROP_SILENCED, - PROP_OPERATION_EXPECTED, -1}; + PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME, PROP_OBJECT_TYPE, + PROP_PRESENT_VALUE, PROP_TRACKING_VALUE, PROP_STATUS_FLAGS, + PROP_EVENT_STATE, PROP_OUT_OF_SERVICE, PROP_RELIABILITY, PROP_MODE, + PROP_ACCEPTED_MODES, PROP_SILENCED, PROP_OPERATION_EXPECTED, -1 +}; -static const int Life_Safety_Point_Properties_Optional[] = {PROP_DESCRIPTION, - -1}; +static const int Life_Safety_Point_Properties_Optional[] = { PROP_DESCRIPTION, + -1 }; -static const int Life_Safety_Point_Properties_Proprietary[] = {-1}; +static const int Life_Safety_Point_Properties_Proprietary[] = { -1 }; /** * Returns the list of required, optional, and proprietary properties. @@ -80,9 +78,8 @@ static const int Life_Safety_Point_Properties_Proprietary[] = {-1}; * @param pProprietary - pointer to list of int terminated by -1, of * BACnet proprietary properties for this object. */ -void Life_Safety_Point_Property_Lists(const int **pRequired, - const int **pOptional, - const int **pProprietary) +void Life_Safety_Point_Property_Lists( + const int **pRequired, const int **pOptional, const int **pProprietary) { if (pRequired) { *pRequired = Life_Safety_Point_Properties_Required; @@ -122,8 +119,9 @@ void Life_Safety_Point_Init(void) /* given instance exists */ bool Life_Safety_Point_Valid_Instance(uint32_t object_instance) { - if (object_instance < MAX_LIFE_SAFETY_POINTS) + if (object_instance < MAX_LIFE_SAFETY_POINTS) { return true; + } return false; } @@ -150,8 +148,9 @@ unsigned Life_Safety_Point_Instance_To_Index(uint32_t object_instance) { unsigned index = MAX_LIFE_SAFETY_POINTS; - if (object_instance < MAX_LIFE_SAFETY_POINTS) + if (object_instance < MAX_LIFE_SAFETY_POINTS) { index = object_instance; + } return index; } @@ -163,15 +162,16 @@ static BACNET_LIFE_SAFETY_STATE Life_Safety_Point_Present_Value( unsigned index = 0; index = Life_Safety_Point_Instance_To_Index(object_instance); - if (index < MAX_LIFE_SAFETY_POINTS) + if (index < MAX_LIFE_SAFETY_POINTS) { present_value = Life_Safety_Point_State[index]; + } return present_value; } /* note: the object name must be unique within this device */ -bool Life_Safety_Point_Object_Name(uint32_t object_instance, - BACNET_CHARACTER_STRING *object_name) +bool Life_Safety_Point_Object_Name( + uint32_t object_instance, BACNET_CHARACTER_STRING *object_name) { static char text_string[32] = ""; /* okay for single thread */ bool status = false; @@ -212,14 +212,14 @@ int Life_Safety_Point_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) break; case PROP_OBJECT_NAME: case PROP_DESCRIPTION: - Life_Safety_Point_Object_Name(rpdata->object_instance, - &char_string); + Life_Safety_Point_Object_Name( + rpdata->object_instance, &char_string); apdu_len = encode_application_character_string(&apdu[0], &char_string); break; case PROP_OBJECT_TYPE: - apdu_len = encode_application_enumerated(&apdu[0], - OBJECT_LIFE_SAFETY_POINT); + apdu_len = encode_application_enumerated( + &apdu[0], OBJECT_LIFE_SAFETY_POINT); break; case PROP_PRESENT_VALUE: present_value = @@ -305,8 +305,8 @@ bool Life_Safety_Point_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) BACNET_APPLICATION_DATA_VALUE value; /* decode the some of the request */ - len = bacapp_decode_application_data(wp_data->application_data, - wp_data->application_data_len, &value); + len = bacapp_decode_application_data( + wp_data->application_data, wp_data->application_data_len, &value); /* FIXME: len < application_data_len: more data? */ if (len < 0) { /* error while decoding - a value larger than we can handle */ @@ -324,7 +324,7 @@ bool Life_Safety_Point_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) case PROP_MODE: status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_ENUMERATED, - &wp_data->error_class, &wp_data->error_code); + &wp_data->error_class, &wp_data->error_code); if (status) { if (value.type.Enumerated <= MAX_LIFE_SAFETY_MODE) { object_index = Life_Safety_Point_Instance_To_Index( @@ -339,9 +339,8 @@ bool Life_Safety_Point_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) } break; case PROP_OUT_OF_SERVICE: - status = - WPValidateArgType(&value, BACNET_APPLICATION_TAG_BOOLEAN, - &wp_data->error_class, &wp_data->error_code); + status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_BOOLEAN, + &wp_data->error_class, &wp_data->error_code); if (status) { object_index = Life_Safety_Point_Instance_To_Index( wp_data->object_instance); @@ -380,8 +379,9 @@ bool Life_Safety_Point_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) #include "ctest.h" bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue, - uint8_t ucExpectedTag, BACNET_ERROR_CLASS *pErrorClass, - BACNET_ERROR_CODE *pErrorCode) + uint8_t ucExpectedTag, + BACNET_ERROR_CLASS *pErrorClass, + BACNET_ERROR_CODE *pErrorCode) { pValue = pValue; ucExpectedTag = ucExpectedTag; @@ -393,7 +393,7 @@ bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue, void testLifeSafetyPoint(Test *pTest) { - uint8_t apdu[MAX_APDU] = {0}; + uint8_t apdu[MAX_APDU] = { 0 }; int len = 0; uint32_t len_value = 0; uint8_t tag_number = 0; diff --git a/demo/object/lsp.h b/src/bacnet/basic/object/lsp.h similarity index 95% rename from demo/object/lsp.h rename to src/bacnet/basic/object/lsp.h index ff7a0953..893f45ab 100644 --- a/demo/object/lsp.h +++ b/src/bacnet/basic/object/lsp.h @@ -27,10 +27,10 @@ #include #include -#include "bacdef.h" -#include "bacerror.h" -#include "rp.h" -#include "wp.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacerror.h" +#include "bacnet/rp.h" +#include "bacnet/wp.h" #ifdef __cplusplus extern "C" { diff --git a/demo/object/lsp.mak b/src/bacnet/basic/object/lsp.mak old mode 100755 new mode 100644 similarity index 62% rename from demo/object/lsp.mak rename to src/bacnet/basic/object/lsp.mak index 4235f4f3..47cfb85e --- a/demo/object/lsp.mak +++ b/src/bacnet/basic/object/lsp.mak @@ -8,16 +8,16 @@ DEFINES = -DBIG_ENDIAN=0 -DTEST -DBACAPP_ALL -DTEST_LIFE_SAFETY_POINT CFLAGS = -Wall $(INCLUDES) $(DEFINES) -g SRCS = lsp.c \ - $(SRC_DIR)/bacdcode.c \ - $(SRC_DIR)/bacint.c \ - $(SRC_DIR)/bacstr.c \ - $(SRC_DIR)/bacreal.c \ - $(SRC_DIR)/datetime.c \ - $(SRC_DIR)/bacapp.c \ - $(SRC_DIR)/bacdevobjpropref.c \ - $(SRC_DIR)/bactext.c \ - $(SRC_DIR)/indtext.c \ - $(SRC_DIR)/lighting.c \ + $(SRC_DIR)/bacnet/bacdcode.c \ + $(SRC_DIR)/bacnet/bacint.c \ + $(SRC_DIR)/bacnet/bacstr.c \ + $(SRC_DIR)/bacnet/bacreal.c \ + $(SRC_DIR)/bacnet/datetime.c \ + $(SRC_DIR)/bacnet/bacapp.c \ + $(SRC_DIR)/bacnet/bacdevobjpropref.c \ + $(SRC_DIR)/bacnet/bactext.c \ + $(SRC_DIR)/bacnet/indtext.c \ + $(SRC_DIR)/bacnet/lighting.c \ $(TEST_DIR)/ctest.c TARGET = life_safety_point diff --git a/demo/object/ms-input.c b/src/bacnet/basic/object/ms-input.c similarity index 84% rename from demo/object/ms-input.c rename to src/bacnet/basic/object/ms-input.c index 269825d8..c0944512 100644 --- a/demo/object/ms-input.c +++ b/src/bacnet/basic/object/ms-input.c @@ -28,16 +28,16 @@ #include #include #include -#include "bacdef.h" -#include "bacdcode.h" -#include "bacenum.h" -#include "bacapp.h" -#include "config.h" /* the custom stuff */ -#include "rp.h" -#include "wp.h" -#include "device.h" -#include "ms-input.h" -#include "handlers.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacenum.h" +#include "bacnet/bacapp.h" +#include "bacnet/config.h" /* the custom stuff */ +#include "bacnet/rp.h" +#include "bacnet/wp.h" +#include "bacnet/basic/object/device.h" +#include "bacnet/basic/object/ms-input.h" +#include "bacnet/basic/services.h" /* number of demo objects */ #ifndef MAX_MULTISTATE_INPUTS @@ -58,26 +58,27 @@ static char Object_Description[MAX_MULTISTATE_INPUTS][64]; static char State_Text[MAX_MULTISTATE_INPUTS][MULTISTATE_NUMBER_OF_STATES][64]; /* These three arrays are used by the ReadPropertyMultiple handler */ -static const int Properties_Required[] = { - PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME, PROP_OBJECT_TYPE, - PROP_PRESENT_VALUE, PROP_STATUS_FLAGS, PROP_EVENT_STATE, - PROP_OUT_OF_SERVICE, PROP_NUMBER_OF_STATES, -1}; +static const int Properties_Required[] = { PROP_OBJECT_IDENTIFIER, + PROP_OBJECT_NAME, PROP_OBJECT_TYPE, PROP_PRESENT_VALUE, PROP_STATUS_FLAGS, + PROP_EVENT_STATE, PROP_OUT_OF_SERVICE, PROP_NUMBER_OF_STATES, -1 }; -static const int Properties_Optional[] = {PROP_DESCRIPTION, PROP_STATE_TEXT, - -1}; +static const int Properties_Optional[] = { PROP_DESCRIPTION, PROP_STATE_TEXT, + -1 }; -static const int Properties_Proprietary[] = {-1}; +static const int Properties_Proprietary[] = { -1 }; -void Multistate_Input_Property_Lists(const int **pRequired, - const int **pOptional, - const int **pProprietary) +void Multistate_Input_Property_Lists( + const int **pRequired, const int **pOptional, const int **pProprietary) { - if (pRequired) + if (pRequired) { *pRequired = Properties_Required; - if (pOptional) + } + if (pOptional) { *pOptional = Properties_Optional; - if (pProprietary) + } + if (pProprietary) { *pProprietary = Properties_Proprietary; + } return; } @@ -103,8 +104,9 @@ unsigned Multistate_Input_Instance_To_Index(uint32_t object_instance) { unsigned index = MAX_MULTISTATE_INPUTS; - if (object_instance < MAX_MULTISTATE_INPUTS) + if (object_instance < MAX_MULTISTATE_INPUTS) { index = object_instance; + } return index; } @@ -154,8 +156,8 @@ uint32_t Multistate_Input_Present_Value(uint32_t object_instance) return value; } -bool Multistate_Input_Present_Value_Set(uint32_t object_instance, - uint32_t value) +bool Multistate_Input_Present_Value_Set( + uint32_t object_instance, uint32_t value) { bool status = false; unsigned index = 0; /* offset from instance lookup */ @@ -211,8 +213,8 @@ char *Multistate_Input_Description(uint32_t object_instance) bool Multistate_Input_Description_Set(uint32_t object_instance, char *new_name) { - unsigned index = 0; /* offset from instance lookup */ - size_t i = 0; /* loop counter */ + unsigned index = 0; /* offset from instance lookup */ + size_t i = 0; /* loop counter */ bool status = false; /* return value */ index = Multistate_Input_Instance_To_Index(object_instance); @@ -235,9 +237,10 @@ bool Multistate_Input_Description_Set(uint32_t object_instance, char *new_name) return status; } -static bool Multistate_Input_Description_Write( - uint32_t object_instance, BACNET_CHARACTER_STRING *char_string, - BACNET_ERROR_CLASS *error_class, BACNET_ERROR_CODE *error_code) +static bool Multistate_Input_Description_Write(uint32_t object_instance, + BACNET_CHARACTER_STRING *char_string, + BACNET_ERROR_CLASS *error_class, + BACNET_ERROR_CODE *error_code) { unsigned index = 0; /* offset from instance lookup */ size_t length = 0; @@ -250,8 +253,7 @@ static bool Multistate_Input_Description_Write( if (length <= sizeof(Object_Description[index])) { encoding = characterstring_encoding(char_string); if (encoding == CHARACTER_UTF8) { - status = characterstring_ansi_copy( - Object_Description[index], + status = characterstring_ansi_copy(Object_Description[index], sizeof(Object_Description[index]), char_string); if (!status) { *error_class = ERROR_CLASS_PROPERTY; @@ -270,8 +272,8 @@ static bool Multistate_Input_Description_Write( return status; } -bool Multistate_Input_Object_Name(uint32_t object_instance, - BACNET_CHARACTER_STRING *object_name) +bool Multistate_Input_Object_Name( + uint32_t object_instance, BACNET_CHARACTER_STRING *object_name) { unsigned index = 0; /* offset from instance lookup */ bool status = false; @@ -287,8 +289,8 @@ bool Multistate_Input_Object_Name(uint32_t object_instance, /* note: the object name must be unique within this device */ bool Multistate_Input_Name_Set(uint32_t object_instance, char *new_name) { - unsigned index = 0; /* offset from instance lookup */ - size_t i = 0; /* loop counter */ + unsigned index = 0; /* offset from instance lookup */ + size_t i = 0; /* loop counter */ bool status = false; /* return value */ index = Multistate_Input_Instance_To_Index(object_instance); @@ -312,9 +314,10 @@ bool Multistate_Input_Name_Set(uint32_t object_instance, char *new_name) return status; } -static bool Multistate_Input_Object_Name_Write( - uint32_t object_instance, BACNET_CHARACTER_STRING *char_string, - BACNET_ERROR_CLASS *error_class, BACNET_ERROR_CODE *error_code) +static bool Multistate_Input_Object_Name_Write(uint32_t object_instance, + BACNET_CHARACTER_STRING *char_string, + BACNET_ERROR_CLASS *error_class, + BACNET_ERROR_CODE *error_code) { unsigned index = 0; /* offset from instance lookup */ size_t length = 0; @@ -328,8 +331,7 @@ static bool Multistate_Input_Object_Name_Write( encoding = characterstring_encoding(char_string); if (encoding == CHARACTER_UTF8) { status = characterstring_ansi_copy(Object_Name[index], - sizeof(Object_Name[index]), - char_string); + sizeof(Object_Name[index]), char_string); if (!status) { *error_class = ERROR_CLASS_PROPERTY; *error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; @@ -347,8 +349,8 @@ static bool Multistate_Input_Object_Name_Write( return status; } -char *Multistate_Input_State_Text(uint32_t object_instance, - uint32_t state_index) +char *Multistate_Input_State_Text( + uint32_t object_instance, uint32_t state_index) { unsigned index = 0; /* offset from instance lookup */ char *pName = NULL; /* return value */ @@ -364,11 +366,11 @@ char *Multistate_Input_State_Text(uint32_t object_instance, } /* note: the object name must be unique within this device */ -bool Multistate_Input_State_Text_Set(uint32_t object_instance, - uint32_t state_index, char *new_name) +bool Multistate_Input_State_Text_Set( + uint32_t object_instance, uint32_t state_index, char *new_name) { - unsigned index = 0; /* offset from instance lookup */ - size_t i = 0; /* loop counter */ + unsigned index = 0; /* offset from instance lookup */ + size_t i = 0; /* loop counter */ bool status = false; /* return value */ index = Multistate_Input_Instance_To_Index(object_instance); @@ -394,9 +396,10 @@ bool Multistate_Input_State_Text_Set(uint32_t object_instance, ; } -static bool Multistate_Input_State_Text_Write( - uint32_t object_instance, uint32_t state_index, - BACNET_CHARACTER_STRING *char_string, BACNET_ERROR_CLASS *error_class, +static bool Multistate_Input_State_Text_Write(uint32_t object_instance, + uint32_t state_index, + BACNET_CHARACTER_STRING *char_string, + BACNET_ERROR_CLASS *error_class, BACNET_ERROR_CODE *error_code) { unsigned index = 0; /* offset from instance lookup */ @@ -412,9 +415,9 @@ static bool Multistate_Input_State_Text_Write( if (length <= sizeof(State_Text[index][state_index])) { encoding = characterstring_encoding(char_string); if (encoding == CHARACTER_UTF8) { - status = characterstring_ansi_copy( - State_Text[index][state_index], - sizeof(State_Text[index][state_index]), char_string); + status = + characterstring_ansi_copy(State_Text[index][state_index], + sizeof(State_Text[index][state_index]), char_string); if (!status) { *error_class = ERROR_CLASS_PROPERTY; *error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; @@ -466,15 +469,14 @@ int Multistate_Input_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) encode_application_character_string(&apdu[0], &char_string); break; case PROP_DESCRIPTION: - characterstring_init_ansi( - &char_string, + characterstring_init_ansi(&char_string, Multistate_Input_Description(rpdata->object_instance)); apdu_len = encode_application_character_string(&apdu[0], &char_string); break; case PROP_OBJECT_TYPE: - apdu_len = encode_application_enumerated(&apdu[0], - OBJECT_MULTI_STATE_INPUT); + apdu_len = encode_application_enumerated( + &apdu[0], OBJECT_MULTI_STATE_INPUT); break; case PROP_PRESENT_VALUE: present_value = @@ -488,11 +490,11 @@ int Multistate_Input_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) bitstring_set_bit(&bit_string, STATUS_FLAG_FAULT, false); bitstring_set_bit(&bit_string, STATUS_FLAG_OVERRIDDEN, false); if (Multistate_Input_Out_Of_Service(rpdata->object_instance)) { - bitstring_set_bit(&bit_string, STATUS_FLAG_OUT_OF_SERVICE, - true); + bitstring_set_bit( + &bit_string, STATUS_FLAG_OUT_OF_SERVICE, true); } else { - bitstring_set_bit(&bit_string, STATUS_FLAG_OUT_OF_SERVICE, - false); + bitstring_set_bit( + &bit_string, STATUS_FLAG_OUT_OF_SERVICE, false); } apdu_len = encode_application_bitstring(&apdu[0], &bit_string); break; @@ -506,15 +508,13 @@ int Multistate_Input_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) apdu_len = encode_application_boolean(&apdu[0], state); break; case PROP_NUMBER_OF_STATES: - apdu_len = encode_application_unsigned( - &apdu[apdu_len], + apdu_len = encode_application_unsigned(&apdu[apdu_len], Multistate_Input_Max_States(rpdata->object_instance)); break; case PROP_STATE_TEXT: if (rpdata->array_index == 0) { /* Array element zero is the number of elements in the array */ - apdu_len = encode_application_unsigned( - &apdu[0], + apdu_len = encode_application_unsigned(&apdu[0], Multistate_Input_Max_States(rpdata->object_instance)); } else if (rpdata->array_index == BACNET_ARRAY_ALL) { /* if no index was specified, then try to encode the entire list @@ -524,11 +524,11 @@ int Multistate_Input_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) Multistate_Input_Max_States(rpdata->object_instance); for (i = 1; i <= max_states; i++) { characterstring_init_ansi(&char_string, - Multistate_Input_State_Text( - rpdata->object_instance, i)); + Multistate_Input_State_Text( + rpdata->object_instance, i)); /* FIXME: this might go beyond MAX_APDU length! */ - len = encode_application_character_string(&apdu[apdu_len], - &char_string); + len = encode_application_character_string( + &apdu[apdu_len], &char_string); /* add it if we have room */ if ((apdu_len + len) < MAX_APDU) { apdu_len += len; @@ -543,10 +543,9 @@ int Multistate_Input_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) max_states = Multistate_Input_Max_States(rpdata->object_instance); if (rpdata->array_index <= max_states) { - characterstring_init_ansi( - &char_string, - Multistate_Input_State_Text(rpdata->object_instance, - rpdata->array_index)); + characterstring_init_ansi(&char_string, + Multistate_Input_State_Text( + rpdata->object_instance, rpdata->array_index)); apdu_len = encode_application_character_string( &apdu[0], &char_string); } else { @@ -586,8 +585,8 @@ bool Multistate_Input_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) uint32_t object_instance = 0; /* decode the first chunk of the request */ - len = bacapp_decode_application_data(wp_data->application_data, - wp_data->application_data_len, &value); + len = bacapp_decode_application_data( + wp_data->application_data, wp_data->application_data_len, &value); /* len < application_data_len: extra data for arrays only */ if (len < 0) { /* error while decoding - a value larger than we can handle */ @@ -607,7 +606,7 @@ bool Multistate_Input_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) if (value.tag == BACNET_APPLICATION_TAG_CHARACTER_STRING) { /* All the object names in a device must be unique */ if (Device_Valid_Object_Name(&value.type.Character_String, - &object_type, &object_instance)) { + &object_type, &object_instance)) { if ((object_type == wp_data->object_type) && (object_instance == wp_data->object_instance)) { /* writing same name to same object */ @@ -640,7 +639,7 @@ bool Multistate_Input_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) case PROP_PRESENT_VALUE: status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_UNSIGNED_INT, - &wp_data->error_class, &wp_data->error_code); + &wp_data->error_class, &wp_data->error_code); if (status) { status = Multistate_Input_Present_Value_Set( wp_data->object_instance, value.type.Unsigned_Int); @@ -651,12 +650,11 @@ bool Multistate_Input_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) } break; case PROP_OUT_OF_SERVICE: - status = - WPValidateArgType(&value, BACNET_APPLICATION_TAG_BOOLEAN, - &wp_data->error_class, &wp_data->error_code); + status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_BOOLEAN, + &wp_data->error_class, &wp_data->error_code); if (status) { - Multistate_Input_Out_Of_Service_Set(wp_data->object_instance, - value.type.Boolean); + Multistate_Input_Out_Of_Service_Set( + wp_data->object_instance, value.type.Boolean); } break; case PROP_STATE_TEXT: @@ -735,14 +733,16 @@ bool Multistate_Input_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) #include "ctest.h" bool Device_Valid_Object_Name(BACNET_CHARACTER_STRING *object_name, - int *object_type, uint32_t *object_instance) + int *object_type, + uint32_t *object_instance) { return true; } bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue, - uint8_t ucExpectedTag, BACNET_ERROR_CLASS *pErrorClass, - BACNET_ERROR_CODE *pErrorCode) + uint8_t ucExpectedTag, + BACNET_ERROR_CLASS *pErrorClass, + BACNET_ERROR_CODE *pErrorCode) { pValue = pValue; ucExpectedTag = ucExpectedTag; @@ -754,7 +754,7 @@ bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue, void testMultistateInput(Test *pTest) { - uint8_t apdu[MAX_APDU] = {0}; + uint8_t apdu[MAX_APDU] = { 0 }; int len = 0; uint32_t len_value = 0; uint8_t tag_number = 0; diff --git a/demo/object/ms-input.h b/src/bacnet/basic/object/ms-input.h similarity index 97% rename from demo/object/ms-input.h rename to src/bacnet/basic/object/ms-input.h index ac654016..f3f8f3ae 100644 --- a/demo/object/ms-input.h +++ b/src/bacnet/basic/object/ms-input.h @@ -27,10 +27,10 @@ #include #include -#include "bacdef.h" -#include "bacerror.h" -#include "rp.h" -#include "wp.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacerror.h" +#include "bacnet/rp.h" +#include "bacnet/wp.h" #ifdef __cplusplus extern "C" { diff --git a/demo/object/ms-input.mak b/src/bacnet/basic/object/ms-input.mak similarity index 63% rename from demo/object/ms-input.mak rename to src/bacnet/basic/object/ms-input.mak index 54d0971d..6668f42b 100644 --- a/demo/object/ms-input.mak +++ b/src/bacnet/basic/object/ms-input.mak @@ -8,16 +8,16 @@ DEFINES = -DBIG_ENDIAN=0 -DTEST -DBACAPP_ALL -DTEST_MULTISTATE_INPUT CFLAGS = -Wall $(INCLUDES) $(DEFINES) -g SRCS = ms-input.c \ - $(SRC_DIR)/bacdcode.c \ - $(SRC_DIR)/bacint.c \ - $(SRC_DIR)/bacstr.c \ - $(SRC_DIR)/bacreal.c \ - $(SRC_DIR)/datetime.c \ - $(SRC_DIR)/bacapp.c \ - $(SRC_DIR)/bacdevobjpropref.c \ - $(SRC_DIR)/bactext.c \ - $(SRC_DIR)/indtext.c \ - $(SRC_DIR)/lighting.c \ + $(SRC_DIR)/bacnet/bacdcode.c \ + $(SRC_DIR)/bacnet/bacint.c \ + $(SRC_DIR)/bacnet/bacstr.c \ + $(SRC_DIR)/bacnet/bacreal.c \ + $(SRC_DIR)/bacnet/datetime.c \ + $(SRC_DIR)/bacnet/bacapp.c \ + $(SRC_DIR)/bacnet/bacdevobjpropref.c \ + $(SRC_DIR)/bacnet/bactext.c \ + $(SRC_DIR)/bacnet/indtext.c \ + $(SRC_DIR)/bacnet/lighting.c \ $(TEST_DIR)/ctest.c TARGET = multistate_input diff --git a/demo/object/mso.c b/src/bacnet/basic/object/mso.c similarity index 84% rename from demo/object/mso.c rename to src/bacnet/basic/object/mso.c index ff170751..a3a3de5c 100644 --- a/demo/object/mso.c +++ b/src/bacnet/basic/object/mso.c @@ -28,15 +28,15 @@ #include #include #include -#include "bacdef.h" -#include "bacdcode.h" -#include "bacenum.h" -#include "bacapp.h" -#include "config.h" /* the custom stuff */ -#include "rp.h" -#include "wp.h" -#include "mso.h" -#include "handlers.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacenum.h" +#include "bacnet/bacapp.h" +#include "bacnet/config.h" /* the custom stuff */ +#include "bacnet/rp.h" +#include "bacnet/wp.h" +#include "bacnet/basic/object/mso.h" +#include "bacnet/basic/services.h" #ifndef MAX_MULTISTATE_OUTPUTS #define MAX_MULTISTATE_OUTPUTS 4 @@ -59,33 +59,29 @@ static bool Out_Of_Service[MAX_MULTISTATE_OUTPUTS]; /* These three arrays are used by the ReadPropertyMultiple handler */ static const int Multistate_Output_Properties_Required[] = { - PROP_OBJECT_IDENTIFIER, - PROP_OBJECT_NAME, - PROP_OBJECT_TYPE, - PROP_PRESENT_VALUE, - PROP_STATUS_FLAGS, - PROP_EVENT_STATE, - PROP_OUT_OF_SERVICE, - PROP_NUMBER_OF_STATES, - PROP_PRIORITY_ARRAY, - PROP_RELINQUISH_DEFAULT, - -1}; + PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME, PROP_OBJECT_TYPE, + PROP_PRESENT_VALUE, PROP_STATUS_FLAGS, PROP_EVENT_STATE, + PROP_OUT_OF_SERVICE, PROP_NUMBER_OF_STATES, PROP_PRIORITY_ARRAY, + PROP_RELINQUISH_DEFAULT, -1 +}; -static const int Multistate_Output_Properties_Optional[] = {PROP_DESCRIPTION, - -1}; +static const int Multistate_Output_Properties_Optional[] = { PROP_DESCRIPTION, + -1 }; -static const int Multistate_Output_Properties_Proprietary[] = {-1}; +static const int Multistate_Output_Properties_Proprietary[] = { -1 }; -void Multistate_Output_Property_Lists(const int **pRequired, - const int **pOptional, - const int **pProprietary) +void Multistate_Output_Property_Lists( + const int **pRequired, const int **pOptional, const int **pProprietary) { - if (pRequired) + if (pRequired) { *pRequired = Multistate_Output_Properties_Required; - if (pOptional) + } + if (pOptional) { *pOptional = Multistate_Output_Properties_Optional; - if (pProprietary) + } + if (pProprietary) { *pProprietary = Multistate_Output_Properties_Proprietary; + } return; } @@ -114,8 +110,9 @@ void Multistate_Output_Init(void) /* given instance exists */ bool Multistate_Output_Valid_Instance(uint32_t object_instance) { - if (object_instance < MAX_MULTISTATE_OUTPUTS) + if (object_instance < MAX_MULTISTATE_OUTPUTS) { return true; + } return false; } @@ -142,8 +139,9 @@ unsigned Multistate_Output_Instance_To_Index(uint32_t object_instance) { unsigned index = MAX_MULTISTATE_OUTPUTS; - if (object_instance < MAX_MULTISTATE_OUTPUTS) + if (object_instance < MAX_MULTISTATE_OUTPUTS) { index = object_instance; + } return index; } @@ -168,8 +166,8 @@ uint32_t Multistate_Output_Present_Value(uint32_t object_instance) } /* note: the object name must be unique within this device */ -bool Multistate_Output_Object_Name(uint32_t object_instance, - BACNET_CHARACTER_STRING *object_name) +bool Multistate_Output_Object_Name( + uint32_t object_instance, BACNET_CHARACTER_STRING *object_name) { static char text_string[32] = ""; /* okay for single thread */ bool status = false; @@ -232,14 +230,14 @@ int Multistate_Output_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) You could make Description writable and different */ case PROP_OBJECT_NAME: case PROP_DESCRIPTION: - Multistate_Output_Object_Name(rpdata->object_instance, - &char_string); + Multistate_Output_Object_Name( + rpdata->object_instance, &char_string); apdu_len = encode_application_character_string(&apdu[0], &char_string); break; case PROP_OBJECT_TYPE: - apdu_len = encode_application_enumerated(&apdu[0], - OBJECT_MULTI_STATE_OUTPUT); + apdu_len = encode_application_enumerated( + &apdu[0], OBJECT_MULTI_STATE_OUTPUT); break; case PROP_PRESENT_VALUE: present_value = @@ -267,29 +265,30 @@ int Multistate_Output_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) break; case PROP_PRIORITY_ARRAY: /* Array element zero is the number of elements in the array */ - if (rpdata->array_index == 0) + if (rpdata->array_index == 0) { apdu_len = encode_application_unsigned(&apdu[0], BACNET_MAX_PRIORITY); - /* if no index was specified, then try to encode the entire list */ - /* into one packet. */ - else if (rpdata->array_index == BACNET_ARRAY_ALL) { + /* if no index was specified, then try to encode the entire list + */ + /* into one packet. */ + } else if (rpdata->array_index == BACNET_ARRAY_ALL) { object_index = Multistate_Output_Instance_To_Index( rpdata->object_instance); for (i = 0; i < BACNET_MAX_PRIORITY; i++) { /* FIXME: check if we have room before adding it to APDU */ if (Multistate_Output_Level[object_index][i] == - MULTISTATE_NULL) + MULTISTATE_NULL) { len = encode_application_null(&apdu[apdu_len]); - else { + } else { present_value = Multistate_Output_Level[object_index][i]; - len = encode_application_unsigned(&apdu[apdu_len], - present_value); + len = encode_application_unsigned( + &apdu[apdu_len], present_value); } /* add it if we have room */ - if ((apdu_len + len) < MAX_APDU) + if ((apdu_len + len) < MAX_APDU) { apdu_len += len; - else { + } else { rpdata->error_code = ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED; apdu_len = BACNET_STATUS_ABORT; @@ -302,14 +301,14 @@ int Multistate_Output_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) if (rpdata->array_index <= BACNET_MAX_PRIORITY) { if (Multistate_Output_Level[object_index] [rpdata->array_index - 1] == - MULTISTATE_NULL) + MULTISTATE_NULL) { apdu_len = encode_application_null(&apdu[0]); - else { + } else { present_value = Multistate_Output_Level[object_index] [rpdata->array_index - 1]; - apdu_len = encode_application_unsigned(&apdu[0], - present_value); + apdu_len = encode_application_unsigned( + &apdu[0], present_value); } } else { rpdata->error_class = ERROR_CLASS_PROPERTY; @@ -324,8 +323,8 @@ int Multistate_Output_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) apdu_len = encode_application_unsigned(&apdu[0], present_value); break; case PROP_NUMBER_OF_STATES: - apdu_len = encode_application_unsigned(&apdu[apdu_len], - MULTISTATE_NUMBER_OF_STATES); + apdu_len = encode_application_unsigned( + &apdu[apdu_len], MULTISTATE_NUMBER_OF_STATES); break; default: @@ -357,8 +356,8 @@ bool Multistate_Output_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) BACNET_APPLICATION_DATA_VALUE value; /* decode the some of the request */ - len = bacapp_decode_application_data(wp_data->application_data, - wp_data->application_data_len, &value); + len = bacapp_decode_application_data( + wp_data->application_data, wp_data->application_data_len, &value); /* FIXME: len < application_data_len: more data? */ if (len < 0) { /* error while decoding - a value larger than we can handle */ @@ -410,8 +409,7 @@ bool Multistate_Output_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) } } else { status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_NULL, - &wp_data->error_class, - &wp_data->error_code); + &wp_data->error_class, &wp_data->error_code); if (status) { level = MULTISTATE_NULL; object_index = Multistate_Output_Instance_To_Index( @@ -437,12 +435,11 @@ bool Multistate_Output_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) } break; case PROP_OUT_OF_SERVICE: - status = - WPValidateArgType(&value, BACNET_APPLICATION_TAG_BOOLEAN, - &wp_data->error_class, &wp_data->error_code); + status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_BOOLEAN, + &wp_data->error_class, &wp_data->error_code); if (status) { - Multistate_Output_Out_Of_Service_Set(wp_data->object_instance, - value.type.Boolean); + Multistate_Output_Out_Of_Service_Set( + wp_data->object_instance, value.type.Boolean); } break; case PROP_OBJECT_IDENTIFIER: @@ -472,8 +469,9 @@ bool Multistate_Output_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) #include "ctest.h" bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue, - uint8_t ucExpectedTag, BACNET_ERROR_CLASS *pErrorClass, - BACNET_ERROR_CODE *pErrorCode) + uint8_t ucExpectedTag, + BACNET_ERROR_CLASS *pErrorClass, + BACNET_ERROR_CODE *pErrorCode) { pValue = pValue; ucExpectedTag = ucExpectedTag; @@ -485,7 +483,7 @@ bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue, void testMultistateOutput(Test *pTest) { - uint8_t apdu[MAX_APDU] = {0}; + uint8_t apdu[MAX_APDU] = { 0 }; int len = 0; uint32_t len_value = 0; uint8_t tag_number = 0; diff --git a/demo/object/mso.h b/src/bacnet/basic/object/mso.h similarity index 97% rename from demo/object/mso.h rename to src/bacnet/basic/object/mso.h index ae008be0..9636b390 100644 --- a/demo/object/mso.h +++ b/src/bacnet/basic/object/mso.h @@ -27,10 +27,10 @@ #include #include -#include "bacdef.h" -#include "bacerror.h" -#include "rp.h" -#include "wp.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacerror.h" +#include "bacnet/rp.h" +#include "bacnet/wp.h" #ifdef __cplusplus extern "C" { diff --git a/demo/object/mso.mak b/src/bacnet/basic/object/mso.mak similarity index 62% rename from demo/object/mso.mak rename to src/bacnet/basic/object/mso.mak index c39ecde0..0ff54b7f 100644 --- a/demo/object/mso.mak +++ b/src/bacnet/basic/object/mso.mak @@ -8,16 +8,16 @@ DEFINES = -DBIG_ENDIAN=0 -DTEST -DBACAPP_ALL -DTEST_MULTISTATE_OUTPUT CFLAGS = -Wall $(INCLUDES) $(DEFINES) -g SRCS = mso.c \ - $(SRC_DIR)/bacdcode.c \ - $(SRC_DIR)/bacint.c \ - $(SRC_DIR)/bacstr.c \ - $(SRC_DIR)/bacreal.c \ - $(SRC_DIR)/datetime.c \ - $(SRC_DIR)/bacapp.c \ - $(SRC_DIR)/bacdevobjpropref.c \ - $(SRC_DIR)/bactext.c \ - $(SRC_DIR)/indtext.c \ - $(SRC_DIR)/lighting.c \ + $(SRC_DIR)/bacnet/bacdcode.c \ + $(SRC_DIR)/bacnet/bacint.c \ + $(SRC_DIR)/bacnet/bacstr.c \ + $(SRC_DIR)/bacnet/bacreal.c \ + $(SRC_DIR)/bacnet/datetime.c \ + $(SRC_DIR)/bacnet/bacapp.c \ + $(SRC_DIR)/bacnet/bacdevobjpropref.c \ + $(SRC_DIR)/bacnet/bactext.c \ + $(SRC_DIR)/bacnet/indtext.c \ + $(SRC_DIR)/bacnet/lighting.c \ $(TEST_DIR)/ctest.c TARGET = multistate_output diff --git a/demo/object/msv.c b/src/bacnet/basic/object/msv.c similarity index 83% rename from demo/object/msv.c rename to src/bacnet/basic/object/msv.c index 665b3159..1a5e88c3 100644 --- a/demo/object/msv.c +++ b/src/bacnet/basic/object/msv.c @@ -28,15 +28,15 @@ #include #include #include -#include "bacdef.h" -#include "bacdcode.h" -#include "bacenum.h" -#include "bacapp.h" -#include "config.h" /* the custom stuff */ -#include "rp.h" -#include "wp.h" -#include "msv.h" -#include "handlers.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacenum.h" +#include "bacnet/bacapp.h" +#include "bacnet/config.h" /* the custom stuff */ +#include "bacnet/rp.h" +#include "bacnet/wp.h" +#include "bacnet/basic/object/msv.h" +#include "bacnet/basic/services.h" /* number of demo objects */ #ifndef MAX_MULTISTATE_VALUES @@ -62,26 +62,27 @@ static char Object_Description[MAX_MULTISTATE_VALUES][64]; static char State_Text[MAX_MULTISTATE_VALUES][MULTISTATE_NUMBER_OF_STATES][64]; /* These three arrays are used by the ReadPropertyMultiple handler */ -static const int Properties_Required[] = { - PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME, PROP_OBJECT_TYPE, - PROP_PRESENT_VALUE, PROP_STATUS_FLAGS, PROP_EVENT_STATE, - PROP_OUT_OF_SERVICE, PROP_NUMBER_OF_STATES, -1}; +static const int Properties_Required[] = { PROP_OBJECT_IDENTIFIER, + PROP_OBJECT_NAME, PROP_OBJECT_TYPE, PROP_PRESENT_VALUE, PROP_STATUS_FLAGS, + PROP_EVENT_STATE, PROP_OUT_OF_SERVICE, PROP_NUMBER_OF_STATES, -1 }; -static const int Properties_Optional[] = {PROP_DESCRIPTION, PROP_STATE_TEXT, - -1}; +static const int Properties_Optional[] = { PROP_DESCRIPTION, PROP_STATE_TEXT, + -1 }; -static const int Properties_Proprietary[] = {-1}; +static const int Properties_Proprietary[] = { -1 }; -void Multistate_Value_Property_Lists(const int **pRequired, - const int **pOptional, - const int **pProprietary) +void Multistate_Value_Property_Lists( + const int **pRequired, const int **pOptional, const int **pProprietary) { - if (pRequired) + if (pRequired) { *pRequired = Properties_Required; - if (pOptional) + } + if (pOptional) { *pOptional = Properties_Optional; - if (pProprietary) + } + if (pProprietary) { *pProprietary = Properties_Proprietary; + } return; } @@ -107,8 +108,9 @@ unsigned Multistate_Value_Instance_To_Index(uint32_t object_instance) { unsigned index = MAX_MULTISTATE_VALUES; - if (object_instance < MAX_MULTISTATE_VALUES) + if (object_instance < MAX_MULTISTATE_VALUES) { index = object_instance; + } return index; } @@ -153,8 +155,8 @@ uint32_t Multistate_Value_Present_Value(uint32_t object_instance) return value; } -bool Multistate_Value_Present_Value_Set(uint32_t object_instance, - uint32_t value) +bool Multistate_Value_Present_Value_Set( + uint32_t object_instance, uint32_t value) { bool status = false; unsigned index = 0; /* offset from instance lookup */ @@ -216,8 +218,8 @@ char *Multistate_Value_Description(uint32_t object_instance) bool Multistate_Value_Description_Set(uint32_t object_instance, char *new_name) { - unsigned index = 0; /* offset from instance lookup */ - size_t i = 0; /* loop counter */ + unsigned index = 0; /* offset from instance lookup */ + size_t i = 0; /* loop counter */ bool status = false; /* return value */ index = Multistate_Value_Instance_To_Index(object_instance); @@ -240,8 +242,8 @@ bool Multistate_Value_Description_Set(uint32_t object_instance, char *new_name) return status; } -bool Multistate_Value_Object_Name(uint32_t object_instance, - BACNET_CHARACTER_STRING *object_name) +bool Multistate_Value_Object_Name( + uint32_t object_instance, BACNET_CHARACTER_STRING *object_name) { unsigned index = 0; /* offset from instance lookup */ bool status = false; @@ -257,8 +259,8 @@ bool Multistate_Value_Object_Name(uint32_t object_instance, /* note: the object name must be unique within this device */ bool Multistate_Value_Name_Set(uint32_t object_instance, char *new_name) { - unsigned index = 0; /* offset from instance lookup */ - size_t i = 0; /* loop counter */ + unsigned index = 0; /* offset from instance lookup */ + size_t i = 0; /* loop counter */ bool status = false; /* return value */ index = Multistate_Value_Instance_To_Index(object_instance); @@ -282,8 +284,8 @@ bool Multistate_Value_Name_Set(uint32_t object_instance, char *new_name) return status; } -char *Multistate_Value_State_Text(uint32_t object_instance, - uint32_t state_index) +char *Multistate_Value_State_Text( + uint32_t object_instance, uint32_t state_index) { unsigned index = 0; /* offset from instance lookup */ char *pName = NULL; /* return value */ @@ -299,11 +301,11 @@ char *Multistate_Value_State_Text(uint32_t object_instance, } /* note: the object name must be unique within this device */ -bool Multistate_Value_State_Text_Set(uint32_t object_instance, - uint32_t state_index, char *new_name) +bool Multistate_Value_State_Text_Set( + uint32_t object_instance, uint32_t state_index, char *new_name) { - unsigned index = 0; /* offset from instance lookup */ - size_t i = 0; /* loop counter */ + unsigned index = 0; /* offset from instance lookup */ + size_t i = 0; /* loop counter */ bool status = false; /* return value */ index = Multistate_Value_Instance_To_Index(object_instance); @@ -362,8 +364,8 @@ void Multistate_Value_Change_Of_Value_Clear(uint32_t object_instance) * * @return true if the value list is encoded */ -bool Multistate_Value_Encode_Value_List(uint32_t object_instance, - BACNET_PROPERTY_VALUE *value_list) +bool Multistate_Value_Encode_Value_List( + uint32_t object_instance, BACNET_PROPERTY_VALUE *value_list) { bool status = false; @@ -385,18 +387,18 @@ bool Multistate_Value_Encode_Value_List(uint32_t object_instance, value_list->value.tag = BACNET_APPLICATION_TAG_BIT_STRING; value_list->value.next = NULL; bitstring_init(&value_list->value.type.Bit_String); - bitstring_set_bit(&value_list->value.type.Bit_String, - STATUS_FLAG_IN_ALARM, false); - bitstring_set_bit(&value_list->value.type.Bit_String, STATUS_FLAG_FAULT, - false); - bitstring_set_bit(&value_list->value.type.Bit_String, - STATUS_FLAG_OVERRIDDEN, false); + bitstring_set_bit( + &value_list->value.type.Bit_String, STATUS_FLAG_IN_ALARM, false); + bitstring_set_bit( + &value_list->value.type.Bit_String, STATUS_FLAG_FAULT, false); + bitstring_set_bit( + &value_list->value.type.Bit_String, STATUS_FLAG_OVERRIDDEN, false); if (Multistate_Value_Out_Of_Service(object_instance)) { bitstring_set_bit(&value_list->value.type.Bit_String, - STATUS_FLAG_OUT_OF_SERVICE, true); + STATUS_FLAG_OUT_OF_SERVICE, true); } else { bitstring_set_bit(&value_list->value.type.Bit_String, - STATUS_FLAG_OUT_OF_SERVICE, false); + STATUS_FLAG_OUT_OF_SERVICE, false); } value_list->priority = BACNET_NO_PRIORITY; value_list->next = NULL; @@ -436,15 +438,14 @@ int Multistate_Value_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) encode_application_character_string(&apdu[0], &char_string); break; case PROP_DESCRIPTION: - characterstring_init_ansi( - &char_string, + characterstring_init_ansi(&char_string, Multistate_Value_Description(rpdata->object_instance)); apdu_len = encode_application_character_string(&apdu[0], &char_string); break; case PROP_OBJECT_TYPE: - apdu_len = encode_application_enumerated(&apdu[0], - OBJECT_MULTI_STATE_VALUE); + apdu_len = encode_application_enumerated( + &apdu[0], OBJECT_MULTI_STATE_VALUE); break; case PROP_PRESENT_VALUE: present_value = @@ -471,8 +472,8 @@ int Multistate_Value_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) apdu_len = encode_application_boolean(&apdu[0], state); break; case PROP_NUMBER_OF_STATES: - apdu_len = encode_application_unsigned(&apdu[apdu_len], - MULTISTATE_NUMBER_OF_STATES); + apdu_len = encode_application_unsigned( + &apdu[apdu_len], MULTISTATE_NUMBER_OF_STATES); break; case PROP_STATE_TEXT: if (rpdata->array_index == 0) { @@ -485,11 +486,11 @@ int Multistate_Value_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) /* into one packet. */ for (i = 1; i <= MULTISTATE_NUMBER_OF_STATES; i++) { characterstring_init_ansi(&char_string, - Multistate_Value_State_Text( - rpdata->object_instance, i)); + Multistate_Value_State_Text( + rpdata->object_instance, i)); /* FIXME: this might go beyond MAX_APDU length! */ - len = encode_application_character_string(&apdu[apdu_len], - &char_string); + len = encode_application_character_string( + &apdu[apdu_len], &char_string); /* add it if we have room */ if ((apdu_len + len) < MAX_APDU) { apdu_len += len; @@ -502,10 +503,9 @@ int Multistate_Value_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) } } else { if (rpdata->array_index <= MULTISTATE_NUMBER_OF_STATES) { - characterstring_init_ansi( - &char_string, - Multistate_Value_State_Text(rpdata->object_instance, - rpdata->array_index)); + characterstring_init_ansi(&char_string, + Multistate_Value_State_Text( + rpdata->object_instance, rpdata->array_index)); apdu_len = encode_application_character_string( &apdu[0], &char_string); } else { @@ -541,8 +541,8 @@ bool Multistate_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) BACNET_APPLICATION_DATA_VALUE value; /* decode the some of the request */ - len = bacapp_decode_application_data(wp_data->application_data, - wp_data->application_data_len, &value); + len = bacapp_decode_application_data( + wp_data->application_data, wp_data->application_data_len, &value); /* FIXME: len < application_data_len: more data? */ if (len < 0) { /* error while decoding - a value larger than we can handle */ @@ -562,7 +562,7 @@ bool Multistate_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) case PROP_PRESENT_VALUE: status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_UNSIGNED_INT, - &wp_data->error_class, &wp_data->error_code); + &wp_data->error_class, &wp_data->error_code); if (status) { status = Multistate_Value_Present_Value_Set( wp_data->object_instance, value.type.Unsigned_Int); @@ -573,12 +573,11 @@ bool Multistate_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) } break; case PROP_OUT_OF_SERVICE: - status = - WPValidateArgType(&value, BACNET_APPLICATION_TAG_BOOLEAN, - &wp_data->error_class, &wp_data->error_code); + status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_BOOLEAN, + &wp_data->error_class, &wp_data->error_code); if (status) { - Multistate_Value_Out_Of_Service_Set(wp_data->object_instance, - value.type.Boolean); + Multistate_Value_Out_Of_Service_Set( + wp_data->object_instance, value.type.Boolean); } break; case PROP_OBJECT_IDENTIFIER: @@ -607,8 +606,9 @@ bool Multistate_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) #include "ctest.h" bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue, - uint8_t ucExpectedTag, BACNET_ERROR_CLASS *pErrorClass, - BACNET_ERROR_CODE *pErrorCode) + uint8_t ucExpectedTag, + BACNET_ERROR_CLASS *pErrorClass, + BACNET_ERROR_CODE *pErrorCode) { pValue = pValue; ucExpectedTag = ucExpectedTag; @@ -620,7 +620,7 @@ bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue, void testMultistateInput(Test *pTest) { - uint8_t apdu[MAX_APDU] = {0}; + uint8_t apdu[MAX_APDU] = { 0 }; int len = 0; uint32_t len_value = 0; uint8_t tag_number = 0; diff --git a/demo/object/msv.h b/src/bacnet/basic/object/msv.h similarity index 97% rename from demo/object/msv.h rename to src/bacnet/basic/object/msv.h index eef317fc..5e81d22d 100644 --- a/demo/object/msv.h +++ b/src/bacnet/basic/object/msv.h @@ -27,10 +27,10 @@ #include #include -#include "bacdef.h" -#include "bacerror.h" -#include "rp.h" -#include "wp.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacerror.h" +#include "bacnet/rp.h" +#include "bacnet/wp.h" #ifdef __cplusplus extern "C" { diff --git a/demo/object/msv.mak b/src/bacnet/basic/object/msv.mak similarity index 62% rename from demo/object/msv.mak rename to src/bacnet/basic/object/msv.mak index e8c9155f..e4c9ec9a 100644 --- a/demo/object/msv.mak +++ b/src/bacnet/basic/object/msv.mak @@ -8,16 +8,16 @@ DEFINES = -DBIG_ENDIAN=0 -DTEST -DBACAPP_ALL -DTEST_MULTISTATE_VALUE CFLAGS = -Wall $(INCLUDES) $(DEFINES) -g SRCS = msv.c \ - $(SRC_DIR)/bacdcode.c \ - $(SRC_DIR)/bacint.c \ - $(SRC_DIR)/bacstr.c \ - $(SRC_DIR)/bacreal.c \ - $(SRC_DIR)/datetime.c \ - $(SRC_DIR)/bacapp.c \ - $(SRC_DIR)/bacdevobjpropref.c \ - $(SRC_DIR)/bactext.c \ - $(SRC_DIR)/lighting.c \ - $(SRC_DIR)/indtext.c \ + $(SRC_DIR)/bacnet/bacdcode.c \ + $(SRC_DIR)/bacnet/bacint.c \ + $(SRC_DIR)/bacnet/bacstr.c \ + $(SRC_DIR)/bacnet/bacreal.c \ + $(SRC_DIR)/bacnet/datetime.c \ + $(SRC_DIR)/bacnet/bacapp.c \ + $(SRC_DIR)/bacnet/bacdevobjpropref.c \ + $(SRC_DIR)/bacnet/bactext.c \ + $(SRC_DIR)/bacnet/lighting.c \ + $(SRC_DIR)/bacnet/indtext.c \ $(TEST_DIR)/ctest.c TARGET = multistate_value diff --git a/demo/object/nc.c b/src/bacnet/basic/object/nc.c similarity index 88% rename from demo/object/nc.c rename to src/bacnet/basic/object/nc.c index f69ea0df..59c5b2a8 100644 --- a/demo/object/nc.c +++ b/src/bacnet/basic/object/nc.c @@ -33,19 +33,19 @@ #include #include -#include "address.h" -#include "bacdef.h" -#include "bacdcode.h" -#include "bacenum.h" -#include "bacapp.h" -#include "client.h" -#include "config.h" -#include "device.h" -#include "event.h" -#include "handlers.h" -#include "txbuf.h" -#include "wp.h" -#include "nc.h" +#include "bacnet/basic/binding/address.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacenum.h" +#include "bacnet/bacapp.h" +#include "bacnet/basic/services.h" +#include "bacnet/config.h" +#include "bacnet/basic/object/device.h" +#include "bacnet/event.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/wp.h" +#include "bacnet/basic/object/nc.h" #ifndef MAX_NOTIFICATION_CLASSES #define MAX_NOTIFICATION_CLASSES 2 @@ -55,19 +55,16 @@ static NOTIFICATION_CLASS_INFO NC_Info[MAX_NOTIFICATION_CLASSES]; /* These three arrays are used by the ReadPropertyMultiple handler */ -static const int Notification_Properties_Required[] = { - PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME, - PROP_OBJECT_TYPE, PROP_NOTIFICATION_CLASS, - PROP_PRIORITY, PROP_ACK_REQUIRED, - PROP_RECIPIENT_LIST, -1}; +static const int Notification_Properties_Required[] = { PROP_OBJECT_IDENTIFIER, + PROP_OBJECT_NAME, PROP_OBJECT_TYPE, PROP_NOTIFICATION_CLASS, PROP_PRIORITY, + PROP_ACK_REQUIRED, PROP_RECIPIENT_LIST, -1 }; -static const int Notification_Properties_Optional[] = {PROP_DESCRIPTION, -1}; +static const int Notification_Properties_Optional[] = { PROP_DESCRIPTION, -1 }; -static const int Notification_Properties_Proprietary[] = {-1}; +static const int Notification_Properties_Proprietary[] = { -1 }; -void Notification_Class_Property_Lists(const int **pRequired, - const int **pOptional, - const int **pProprietary) +void Notification_Class_Property_Lists( + const int **pRequired, const int **pOptional, const int **pProprietary) { if (pRequired) *pRequired = Notification_Properties_Required; @@ -140,8 +137,8 @@ unsigned Notification_Class_Instance_To_Index(uint32_t object_instance) return index; } -bool Notification_Class_Object_Name(uint32_t object_instance, - BACNET_CHARACTER_STRING *object_name) +bool Notification_Class_Object_Name( + uint32_t object_instance, BACNET_CHARACTER_STRING *object_name) { static char text_string[32] = ""; /* okay for single thread */ unsigned int index; @@ -184,15 +181,15 @@ int Notification_Class_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) case PROP_OBJECT_NAME: case PROP_DESCRIPTION: - Notification_Class_Object_Name(rpdata->object_instance, - &char_string); + Notification_Class_Object_Name( + rpdata->object_instance, &char_string); apdu_len = encode_application_character_string(&apdu[0], &char_string); break; case PROP_OBJECT_TYPE: - apdu_len = encode_application_enumerated(&apdu[0], - OBJECT_NOTIFICATION_CLASS); + apdu_len = encode_application_enumerated( + &apdu[0], OBJECT_NOTIFICATION_CLASS); break; case PROP_NOTIFICATION_CLASS: @@ -205,18 +202,14 @@ int Notification_Class_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) apdu_len += encode_application_unsigned(&apdu[0], 3); else { if (rpdata->array_index == BACNET_ARRAY_ALL) { - apdu_len += encode_application_unsigned( - &apdu[apdu_len], + apdu_len += encode_application_unsigned(&apdu[apdu_len], CurrentNotify->Priority[TRANSITION_TO_OFFNORMAL]); - apdu_len += encode_application_unsigned( - &apdu[apdu_len], + apdu_len += encode_application_unsigned(&apdu[apdu_len], CurrentNotify->Priority[TRANSITION_TO_FAULT]); - apdu_len += encode_application_unsigned( - &apdu[apdu_len], + apdu_len += encode_application_unsigned(&apdu[apdu_len], CurrentNotify->Priority[TRANSITION_TO_NORMAL]); } else if (rpdata->array_index <= MAX_BACNET_EVENT_TRANSITION) { - apdu_len += encode_application_unsigned( - &apdu[apdu_len], + apdu_len += encode_application_unsigned(&apdu[apdu_len], CurrentNotify->Priority[rpdata->array_index - 1]); } else { rpdata->error_class = ERROR_CLASS_PROPERTY; @@ -230,14 +223,11 @@ int Notification_Class_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) u8Val = CurrentNotify->Ack_Required; bitstring_init(&bit_string); - bitstring_set_bit( - &bit_string, TRANSITION_TO_OFFNORMAL, + bitstring_set_bit(&bit_string, TRANSITION_TO_OFFNORMAL, (u8Val & TRANSITION_TO_OFFNORMAL_MASKED) ? true : false); - bitstring_set_bit( - &bit_string, TRANSITION_TO_FAULT, + bitstring_set_bit(&bit_string, TRANSITION_TO_FAULT, (u8Val & TRANSITION_TO_FAULT_MASKED) ? true : false); - bitstring_set_bit( - &bit_string, TRANSITION_TO_NORMAL, + bitstring_set_bit(&bit_string, TRANSITION_TO_NORMAL, (u8Val & TRANSITION_TO_NORMAL_MASKED) ? true : false); /* encode bitstring */ apdu_len += @@ -267,8 +257,8 @@ int Notification_Class_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) bitstring_set_bit(&bit_string, i, false); u8Val <<= 1; /* next day */ } - apdu_len += encode_application_bitstring(&apdu[apdu_len], - &bit_string); + apdu_len += encode_application_bitstring( + &apdu[apdu_len], &bit_string); /* From Time */ apdu_len += encode_application_time( @@ -287,29 +277,26 @@ int Notification_Class_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) /* CHOICE - device [0] BACnetObjectIdentifier */ if (RecipientEntry->Recipient.RecipientType == RECIPIENT_TYPE_DEVICE) { - apdu_len += encode_context_object_id( - &apdu[apdu_len], 0, OBJECT_DEVICE, + apdu_len += encode_context_object_id(&apdu[apdu_len], 0, + OBJECT_DEVICE, RecipientEntry->Recipient._.DeviceIdentifier); } /* CHOICE - address [1] BACnetAddress */ else if (RecipientEntry->Recipient.RecipientType == - RECIPIENT_TYPE_ADDRESS) { + RECIPIENT_TYPE_ADDRESS) { /* opening tag 1 */ apdu_len += encode_opening_tag(&apdu[apdu_len], 1); /* network-number Unsigned16, */ - apdu_len += encode_application_unsigned( - &apdu[apdu_len], + apdu_len += encode_application_unsigned(&apdu[apdu_len], RecipientEntry->Recipient._.Address.net); /* mac-address OCTET STRING */ if (RecipientEntry->Recipient._.Address.net) { - octetstring_init( - &octet_string, + octetstring_init(&octet_string, RecipientEntry->Recipient._.Address.adr, RecipientEntry->Recipient._.Address.len); } else { - octetstring_init( - &octet_string, + octetstring_init(&octet_string, RecipientEntry->Recipient._.Address.mac, RecipientEntry->Recipient._.Address.mac_len); } @@ -336,18 +323,15 @@ int Notification_Class_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) bitstring_init(&bit_string); bitstring_set_bit(&bit_string, TRANSITION_TO_OFFNORMAL, - (u8Val & TRANSITION_TO_OFFNORMAL_MASKED) - ? true - : false); - bitstring_set_bit( - &bit_string, TRANSITION_TO_FAULT, + (u8Val & TRANSITION_TO_OFFNORMAL_MASKED) ? true + : false); + bitstring_set_bit(&bit_string, TRANSITION_TO_FAULT, (u8Val & TRANSITION_TO_FAULT_MASKED) ? true : false); - bitstring_set_bit( - &bit_string, TRANSITION_TO_NORMAL, + bitstring_set_bit(&bit_string, TRANSITION_TO_NORMAL, (u8Val & TRANSITION_TO_NORMAL_MASKED) ? true : false); - apdu_len += encode_application_bitstring(&apdu[apdu_len], - &bit_string); + apdu_len += encode_application_bitstring( + &apdu[apdu_len], &bit_string); } } break; @@ -386,8 +370,8 @@ bool Notification_Class_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) wp_data->object_instance)]; /* decode some of the request */ - len = bacapp_decode_application_data(wp_data->application_data, - wp_data->application_data_len, &value); + len = bacapp_decode_application_data( + wp_data->application_data, wp_data->application_data_len, &value); if (len < 0) { /* error while decoding - a value larger than we can handle */ wp_data->error_class = ERROR_CLASS_PROPERTY; @@ -405,7 +389,7 @@ bool Notification_Class_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) case PROP_PRIORITY: status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_UNSIGNED_INT, - &wp_data->error_class, &wp_data->error_code); + &wp_data->error_class, &wp_data->error_code); if (status) { if (wp_data->array_index == 0) { @@ -420,7 +404,7 @@ bool Notification_Class_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) wp_data->application_data_len, &value); if ((len == 0) || (value.tag != - BACNET_APPLICATION_TAG_UNSIGNED_INT)) { + BACNET_APPLICATION_TAG_UNSIGNED_INT)) { /* Bad decode, wrong tag or following required * parameter missing */ wp_data->error_class = ERROR_CLASS_PROPERTY; @@ -460,7 +444,7 @@ bool Notification_Class_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) case PROP_ACK_REQUIRED: status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_BIT_STRING, - &wp_data->error_class, &wp_data->error_code); + &wp_data->error_class, &wp_data->error_code); if (status) { if (value.type.Bit_String.bits_used == 3) { @@ -538,8 +522,8 @@ bool Notification_Class_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) iOffset += len; /* context tag [0] - Device */ - if (decode_is_context_tag(&wp_data->application_data[iOffset], - 0)) { + if (decode_is_context_tag( + &wp_data->application_data[iOffset], 0)) { TmpNotify.Recipient_List[idx].Recipient.RecipientType = RECIPIENT_TYPE_DEVICE; /* Decode Network Number */ @@ -604,16 +588,16 @@ bool Notification_Class_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) 0) { memcpy(TmpNotify.Recipient_List[idx] .Recipient._.Address.mac, - value.type.Octet_String.value, - value.type.Octet_String.length); + value.type.Octet_String.value, + value.type.Octet_String.length); TmpNotify.Recipient_List[idx] .Recipient._.Address.mac_len = value.type.Octet_String.length; } else { memcpy(TmpNotify.Recipient_List[idx] .Recipient._.Address.adr, - value.type.Octet_String.value, - value.type.Octet_String.length); + value.type.Octet_String.value, + value.type.Octet_String.length); TmpNotify.Recipient_List[idx].Recipient._.Address.len = value.type.Octet_String.length; } @@ -711,7 +695,7 @@ bool Notification_Class_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) /* Decoded all recipient list */ /* copy elements from temporary object */ for (idx = 0; idx < NC_MAX_RECIPIENTS; idx++) { - BACNET_ADDRESS src = {0}; + BACNET_ADDRESS src = { 0 }; unsigned max_apdu = 0; int32_t DeviceID; @@ -727,7 +711,7 @@ bool Notification_Class_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) } else if (CurrentNotify->Recipient_List[idx] .Recipient.RecipientType == - RECIPIENT_TYPE_ADDRESS) { + RECIPIENT_TYPE_ADDRESS) { /* copy Address */ /* src = * CurrentNotify->Recipient_List[idx].Recipient._.Address; @@ -753,8 +737,8 @@ bool Notification_Class_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) return status; } -void Notification_Class_Get_Priorities(uint32_t Object_Instance, - uint32_t *pPriorityArray) +void Notification_Class_Get_Priorities( + uint32_t Object_Instance, uint32_t *pPriorityArray) { NOTIFICATION_CLASS_INFO *CurrentNotify; uint32_t object_index; @@ -774,8 +758,8 @@ void Notification_Class_Get_Priorities(uint32_t Object_Instance, pPriorityArray[i] = CurrentNotify->Priority[i]; } -static bool IsRecipientActive(BACNET_DESTINATION *pBacDest, - uint8_t EventToState) +static bool IsRecipientActive( + BACNET_DESTINATION *pBacDest, uint8_t EventToState) { BACNET_DATE_TIME DateTime; @@ -850,16 +834,16 @@ void Notification_Class_common_reporting_function( CurrentNotify->Priority[TRANSITION_TO_NORMAL]; event_data->ackRequired = (CurrentNotify->Ack_Required & TRANSITION_TO_NORMAL_MASKED) - ? true - : false; + ? true + : false; break; case EVENT_STATE_FAULT: event_data->priority = CurrentNotify->Priority[TRANSITION_TO_FAULT]; event_data->ackRequired = (CurrentNotify->Ack_Required & TRANSITION_TO_FAULT_MASKED) - ? true - : false; + ? true + : false; break; case EVENT_STATE_OFFNORMAL: @@ -869,8 +853,8 @@ void Notification_Class_common_reporting_function( CurrentNotify->Priority[TRANSITION_TO_OFFNORMAL]; event_data->ackRequired = (CurrentNotify->Ack_Required & TRANSITION_TO_OFFNORMAL_MASKED) - ? true - : false; + ? true + : false; break; default: /* shouldn't happen */ @@ -901,18 +885,18 @@ void Notification_Class_common_reporting_function( if (pBacDest->ConfirmedNotify == true) Send_CEvent_Notify(device_id, event_data); else if (address_get_by_device(device_id, &max_apdu, &dest)) - Send_UEvent_Notify(Handler_Transmit_Buffer, event_data, - &dest); + Send_UEvent_Notify( + Handler_Transmit_Buffer, event_data, &dest); } else if (pBacDest->Recipient.RecipientType == - RECIPIENT_TYPE_ADDRESS) { + RECIPIENT_TYPE_ADDRESS) { /* send notification to the address indicated */ if (pBacDest->ConfirmedNotify == true) { if (address_get_device_id(&dest, &device_id)) Send_CEvent_Notify(device_id, event_data); } else { dest = pBacDest->Recipient._.Address; - Send_UEvent_Notify(Handler_Transmit_Buffer, event_data, - &dest); + Send_UEvent_Notify( + Handler_Transmit_Buffer, event_data, &dest); } } } @@ -925,7 +909,7 @@ void Notification_Class_find_recipient(void) { NOTIFICATION_CLASS_INFO *CurrentNotify; BACNET_DESTINATION *pBacDest; - BACNET_ADDRESS src = {0}; + BACNET_ADDRESS src = { 0 }; unsigned max_apdu = 0; uint32_t notify_index; uint32_t DeviceID; diff --git a/demo/object/nc.h b/src/bacnet/basic/object/nc.h similarity index 99% rename from demo/object/nc.h rename to src/bacnet/basic/object/nc.h index 243e644d..fab321a3 100644 --- a/demo/object/nc.h +++ b/src/bacnet/basic/object/nc.h @@ -25,7 +25,7 @@ #ifndef NC_H #define NC_H -#include "event.h" +#include "bacnet/event.h" #ifdef __cplusplus diff --git a/demo/object/netport.c b/src/bacnet/basic/object/netport.c similarity index 87% rename from demo/object/netport.c rename to src/bacnet/basic/object/netport.c index b812ca22..310ab06a 100644 --- a/demo/object/netport.c +++ b/src/bacnet/basic/object/netport.c @@ -36,16 +36,16 @@ #include #include #include -#include "config.h" -#include "address.h" -#include "bacdef.h" -#include "bacapp.h" -#include "bacdcode.h" -#include "npdu.h" -#include "apdu.h" -#include "device.h" +#include "bacnet/config.h" +#include "bacnet/basic/binding/address.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacapp.h" +#include "bacnet/bacdcode.h" +#include "bacnet/npdu.h" +#include "bacnet/apdu.h" +#include "bacnet/basic/object/device.h" /* me */ -#include "netport.h" +#include "bacnet/basic/object/netport.h" #define BIP_DNS_MAX 3 struct bacnet_ipv4_port { @@ -113,56 +113,37 @@ struct object_data { struct object_data Object_List[BACNET_NETWORK_PORTS_MAX]; /* These three arrays are used by the ReadPropertyMultiple handler */ -static const int Network_Port_Properties_Required[] = { - PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME, - PROP_OBJECT_TYPE, PROP_STATUS_FLAGS, - PROP_RELIABILITY, PROP_OUT_OF_SERVICE, - PROP_NETWORK_TYPE, PROP_PROTOCOL_LEVEL, - PROP_NETWORK_NUMBER, PROP_NETWORK_NUMBER_QUALITY, - PROP_CHANGES_PENDING, PROP_APDU_LENGTH, - PROP_LINK_SPEED, -1}; +static const int Network_Port_Properties_Required[] = { PROP_OBJECT_IDENTIFIER, + PROP_OBJECT_NAME, PROP_OBJECT_TYPE, PROP_STATUS_FLAGS, PROP_RELIABILITY, + PROP_OUT_OF_SERVICE, PROP_NETWORK_TYPE, PROP_PROTOCOL_LEVEL, + PROP_NETWORK_NUMBER, PROP_NETWORK_NUMBER_QUALITY, PROP_CHANGES_PENDING, + PROP_APDU_LENGTH, PROP_LINK_SPEED, -1 }; -static const int Ethernet_Port_Properties_Optional[] = { - PROP_MAC_ADDRESS, PROP_MAX_APDU_LENGTH_ACCEPTED, -1}; +static const int Ethernet_Port_Properties_Optional[] = { PROP_MAC_ADDRESS, + PROP_MAX_APDU_LENGTH_ACCEPTED, -1 }; -static const int MSTP_Port_Properties_Optional[] = { - PROP_MAC_ADDRESS, PROP_MAX_APDU_LENGTH_ACCEPTED, PROP_MAX_MASTER, - PROP_MAX_INFO_FRAMES, -1}; +static const int MSTP_Port_Properties_Optional[] = { PROP_MAC_ADDRESS, + PROP_MAX_APDU_LENGTH_ACCEPTED, PROP_MAX_MASTER, PROP_MAX_INFO_FRAMES, -1 }; -static const int BIP_Port_Properties_Optional[] = { - PROP_MAC_ADDRESS, - PROP_MAX_APDU_LENGTH_ACCEPTED, - PROP_BACNET_IP_MODE, - PROP_IP_ADDRESS, - PROP_BACNET_IP_UDP_PORT, - PROP_IP_SUBNET_MASK, - PROP_IP_DEFAULT_GATEWAY, +static const int BIP_Port_Properties_Optional[] = { PROP_MAC_ADDRESS, + PROP_MAX_APDU_LENGTH_ACCEPTED, PROP_BACNET_IP_MODE, PROP_IP_ADDRESS, + PROP_BACNET_IP_UDP_PORT, PROP_IP_SUBNET_MASK, PROP_IP_DEFAULT_GATEWAY, PROP_IP_DNS_SERVER, #if defined(BBMD_ENABLED) - PROP_BBMD_ACCEPT_FD_REGISTRATIONS, - PROP_BBMD_BROADCAST_DISTRIBUTION_TABLE, + PROP_BBMD_ACCEPT_FD_REGISTRATIONS, PROP_BBMD_BROADCAST_DISTRIBUTION_TABLE, PROP_BBMD_FOREIGN_DEVICE_TABLE, #endif - -1}; + -1 }; -static const int BIP6_Port_Properties_Optional[] = { - PROP_MAC_ADDRESS, - PROP_MAX_APDU_LENGTH_ACCEPTED, - PROP_BACNET_IPV6_MODE, - PROP_IPV6_ADDRESS, - PROP_IPV6_PREFIX_LENGTH, - PROP_BACNET_IPV6_UDP_PORT, - PROP_IPV6_DEFAULT_GATEWAY, - PROP_BACNET_IPV6_MULTICAST_ADDRESS, - PROP_IPV6_DNS_SERVER, - PROP_IPV6_AUTO_ADDRESSING_ENABLE, - PROP_IPV6_DHCP_LEASE_TIME, - PROP_IPV6_DHCP_LEASE_TIME_REMAINING, - PROP_IPV6_DHCP_SERVER, - PROP_IPV6_ZONE_INDEX, - -1}; +static const int BIP6_Port_Properties_Optional[] = { PROP_MAC_ADDRESS, + PROP_MAX_APDU_LENGTH_ACCEPTED, PROP_BACNET_IPV6_MODE, PROP_IPV6_ADDRESS, + PROP_IPV6_PREFIX_LENGTH, PROP_BACNET_IPV6_UDP_PORT, + PROP_IPV6_DEFAULT_GATEWAY, PROP_BACNET_IPV6_MULTICAST_ADDRESS, + PROP_IPV6_DNS_SERVER, PROP_IPV6_AUTO_ADDRESSING_ENABLE, + PROP_IPV6_DHCP_LEASE_TIME, PROP_IPV6_DHCP_LEASE_TIME_REMAINING, + PROP_IPV6_DHCP_SERVER, PROP_IPV6_ZONE_INDEX, -1 }; -static const int Network_Port_Properties_Proprietary[] = {-1}; +static const int Network_Port_Properties_Proprietary[] = { -1 }; /** * Returns the list of required, optional, and proprietary properties. @@ -176,8 +157,10 @@ static const int Network_Port_Properties_Proprietary[] = {-1}; * @param pProprietary - pointer to list of int terminated by -1, of * BACnet proprietary properties for this object. */ -void Network_Port_Property_List(uint32_t object_instance, const int **pRequired, - const int **pOptional, const int **pProprietary) +void Network_Port_Property_List(uint32_t object_instance, + const int **pRequired, + const int **pOptional, + const int **pProprietary) { unsigned index = 0; @@ -222,11 +205,11 @@ void Network_Port_Property_List(uint32_t object_instance, const int **pRequired, * @param pProprietary - pointer to list of int terminated by -1, of * BACnet proprietary properties for this object. */ -void Network_Port_Property_Lists(const int **pRequired, const int **pOptional, - const int **pProprietary) +void Network_Port_Property_Lists( + const int **pRequired, const int **pOptional, const int **pProprietary) { - Network_Port_Property_List(Object_List[0].Instance_Number, pRequired, - pOptional, pProprietary); + Network_Port_Property_List( + Object_List[0].Instance_Number, pRequired, pOptional, pProprietary); } /** @@ -239,16 +222,16 @@ void Network_Port_Property_Lists(const int **pRequired, const int **pOptional, * * @return true if object-name was retrieved */ -bool Network_Port_Object_Name(uint32_t object_instance, - BACNET_CHARACTER_STRING *object_name) +bool Network_Port_Object_Name( + uint32_t object_instance, BACNET_CHARACTER_STRING *object_name) { unsigned index = 0; /* offset from instance lookup */ bool status = false; index = Network_Port_Instance_To_Index(object_instance); if (index < BACNET_NETWORK_PORTS_MAX) { - status = characterstring_init_ansi(object_name, - Object_List[index].Object_Name); + status = characterstring_init_ansi( + object_name, Object_List[index].Object_Name); } return status; @@ -354,8 +337,8 @@ unsigned Network_Port_Instance_To_Index(uint32_t object_instance) * * @return true if values are within range and property is set. */ -bool Network_Port_Object_Instance_Number_Set(unsigned index, - uint32_t object_instance) +bool Network_Port_Object_Instance_Number_Set( + unsigned index, uint32_t object_instance) { bool status = false; /* return value */ @@ -440,8 +423,8 @@ BACNET_RELIABILITY Network_Port_Reliability(uint32_t object_instance) * * @return true if values are within range and property is set. */ -bool Network_Port_Reliability_Set(uint32_t object_instance, - BACNET_RELIABILITY value) +bool Network_Port_Reliability_Set( + uint32_t object_instance, BACNET_RELIABILITY value) { bool status = false; unsigned index = 0; @@ -569,8 +552,8 @@ BACNET_PORT_QUALITY Network_Port_Quality(uint32_t object_instance) * * @return true if values are within range and property is set. */ -bool Network_Port_Quality_Set(uint32_t object_instance, - BACNET_PORT_QUALITY value) +bool Network_Port_Quality_Set( + uint32_t object_instance, BACNET_PORT_QUALITY value) { bool status = false; unsigned index = 0; @@ -594,13 +577,13 @@ bool Network_Port_Quality_Set(uint32_t object_instance, * * @return true if mac-address was retrieved */ -bool Network_Port_MAC_Address(uint32_t object_instance, - BACNET_OCTET_STRING *mac_address) +bool Network_Port_MAC_Address( + uint32_t object_instance, BACNET_OCTET_STRING *mac_address) { unsigned index = 0; /* offset from instance lookup */ bool status = false; uint8_t *mac = NULL; - uint8_t ip_mac[4 + 2] = {0}; + uint8_t ip_mac[4 + 2] = { 0 }; size_t mac_len = 0; index = Network_Port_Instance_To_Index(object_instance); @@ -616,8 +599,8 @@ bool Network_Port_MAC_Address(uint32_t object_instance, mac_len = sizeof(Object_List[index].Network.MSTP.MAC_Address); break; case PORT_TYPE_BIP: - memcpy(&ip_mac[0], &Object_List[index].Network.IPv4.IP_Address, - 4); + memcpy( + &ip_mac[0], &Object_List[index].Network.IPv4.IP_Address, 4); memcpy(&ip_mac[4], &Object_List[index].Network.IPv4.Port, 2); mac = &ip_mac[0]; mac_len = sizeof(ip_mac); @@ -647,8 +630,8 @@ bool Network_Port_MAC_Address(uint32_t object_instance, * * @return true if object-name was set */ -bool Network_Port_MAC_Address_Set(uint32_t object_instance, uint8_t *mac_src, - uint8_t mac_len) +bool Network_Port_MAC_Address_Set( + uint32_t object_instance, uint8_t *mac_src, uint8_t mac_len) { unsigned index = 0; /* offset from instance lookup */ bool status = false; @@ -878,8 +861,8 @@ bool Network_Port_MSTP_Max_Master_Set(uint32_t object_instance, uint8_t value) * * @return true if ip-address was retrieved */ -bool Network_Port_IP_Address(uint32_t object_instance, - BACNET_OCTET_STRING *ip_address) +bool Network_Port_IP_Address( + uint32_t object_instance, BACNET_OCTET_STRING *ip_address) { unsigned index = 0; /* offset from instance lookup */ bool status = false; @@ -907,8 +890,8 @@ bool Network_Port_IP_Address(uint32_t object_instance, * * @return true if ip-address was set */ -bool Network_Port_IP_Address_Set(uint32_t object_instance, uint8_t a, uint8_t b, - uint8_t c, uint8_t d) +bool Network_Port_IP_Address_Set( + uint32_t object_instance, uint8_t a, uint8_t b, uint8_t c, uint8_t d) { unsigned index = 0; /* offset from instance lookup */ bool status = false; @@ -936,14 +919,14 @@ bool Network_Port_IP_Address_Set(uint32_t object_instance, uint8_t a, uint8_t b, * * @return true if ip-address was retrieved */ -bool Network_Port_IP_Subnet(uint32_t object_instance, - BACNET_OCTET_STRING *subnet_mask) +bool Network_Port_IP_Subnet( + uint32_t object_instance, BACNET_OCTET_STRING *subnet_mask) { unsigned index = 0; /* offset from instance lookup */ bool status = false; uint32_t mask = 0; uint32_t prefix = 0; - uint8_t ip_mask[4] = {0}; + uint8_t ip_mask[4] = { 0 }; index = Network_Port_Instance_To_Index(object_instance); if (index < BACNET_NETWORK_PORTS_MAX) { @@ -1021,8 +1004,8 @@ bool Network_Port_IP_Subnet_Prefix_Set(uint32_t object_instance, uint8_t value) * * @return true if ip-address was retrieved */ -bool Network_Port_IP_Gateway(uint32_t object_instance, - BACNET_OCTET_STRING *ip_address) +bool Network_Port_IP_Gateway( + uint32_t object_instance, BACNET_OCTET_STRING *ip_address) { unsigned index = 0; /* offset from instance lookup */ bool status = false; @@ -1050,8 +1033,8 @@ bool Network_Port_IP_Gateway(uint32_t object_instance, * * @return true if ip-address was set */ -bool Network_Port_IP_Gateway_Set(uint32_t object_instance, uint8_t a, uint8_t b, - uint8_t c, uint8_t d) +bool Network_Port_IP_Gateway_Set( + uint32_t object_instance, uint8_t a, uint8_t b, uint8_t c, uint8_t d) { unsigned index = 0; /* offset from instance lookup */ bool status = false; @@ -1080,8 +1063,9 @@ bool Network_Port_IP_Gateway_Set(uint32_t object_instance, uint8_t a, uint8_t b, * * @return true if ip-address was retrieved */ -bool Network_Port_IP_DNS_Server(uint32_t object_instance, unsigned dns_index, - BACNET_OCTET_STRING *ip_address) +bool Network_Port_IP_DNS_Server(uint32_t object_instance, + unsigned dns_index, + BACNET_OCTET_STRING *ip_address) { unsigned index = 0; /* offset from instance lookup */ bool status = false; @@ -1090,8 +1074,7 @@ bool Network_Port_IP_DNS_Server(uint32_t object_instance, unsigned dns_index, if (index < BACNET_NETWORK_PORTS_MAX) { if (Object_List[index].Network_Type == PORT_TYPE_BIP) { if (dns_index < BIP_DNS_MAX) { - status = octetstring_init( - ip_address, + status = octetstring_init(ip_address, &Object_List[index] .Network.IPv4.IP_DNS_Server[dns_index][0], 4); @@ -1116,8 +1099,11 @@ bool Network_Port_IP_DNS_Server(uint32_t object_instance, unsigned dns_index, * @return true if ip-address was set */ bool Network_Port_IP_DNS_Server_Set(uint32_t object_instance, - unsigned dns_index, uint8_t a, uint8_t b, - uint8_t c, uint8_t d) + unsigned dns_index, + uint8_t a, + uint8_t b, + uint8_t c, + uint8_t d) { unsigned index = 0; /* offset from instance lookup */ bool status = false; @@ -1273,8 +1259,8 @@ bool Network_Port_BBMD_Accept_FD_Registrations(uint32_t object_instance) * * @return true if the BBMD-Accept-FD-Registrations property value was set */ -bool Network_Port_BBMD_Accept_FD_Registrations_Set(uint32_t object_instance, - bool flag) +bool Network_Port_BBMD_Accept_FD_Registrations_Set( + uint32_t object_instance, bool flag) { bool status = false; unsigned index = 0; @@ -1356,8 +1342,8 @@ bool Network_Port_BIP6_Mode_Set(uint32_t object_instance, BACNET_IP_MODE value) * * @return true if ip-address was retrieved */ -bool Network_Port_IPv6_Address(uint32_t object_instance, - BACNET_OCTET_STRING *ip_address) +bool Network_Port_IPv6_Address( + uint32_t object_instance, BACNET_OCTET_STRING *ip_address) { unsigned index = 0; /* offset from instance lookup */ bool status = false; @@ -1365,9 +1351,8 @@ bool Network_Port_IPv6_Address(uint32_t object_instance, index = Network_Port_Instance_To_Index(object_instance); if (index < BACNET_NETWORK_PORTS_MAX) { if (Object_List[index].Network_Type == PORT_TYPE_BIP6) { - status = octetstring_init( - ip_address, &Object_List[index].Network.IPv6.IP_Address[0], - IPV6_ADDR_SIZE); + status = octetstring_init(ip_address, + &Object_List[index].Network.IPv6.IP_Address[0], IPV6_ADDR_SIZE); } } @@ -1383,8 +1368,8 @@ bool Network_Port_IPv6_Address(uint32_t object_instance, * * @return true if ip-address was set */ -bool Network_Port_IPv6_Address_Set(uint32_t object_instance, - uint8_t *ip_address) +bool Network_Port_IPv6_Address_Set( + uint32_t object_instance, uint8_t *ip_address) { unsigned index = 0; /* offset from instance lookup */ bool status = false; @@ -1435,8 +1420,8 @@ uint8_t Network_Port_IPv6_Subnet_Prefix(uint32_t object_instance) * * @return true if values are within range and property is set. */ -bool Network_Port_IPv6_Subnet_Prefix_Set(uint32_t object_instance, - uint8_t value) +bool Network_Port_IPv6_Subnet_Prefix_Set( + uint32_t object_instance, uint8_t value) { bool status = false; unsigned index = 0; @@ -1467,8 +1452,8 @@ bool Network_Port_IPv6_Subnet_Prefix_Set(uint32_t object_instance, * * @return true if ip-address was retrieved */ -bool Network_Port_IPv6_Gateway(uint32_t object_instance, - BACNET_OCTET_STRING *ip_address) +bool Network_Port_IPv6_Gateway( + uint32_t object_instance, BACNET_OCTET_STRING *ip_address) { unsigned index = 0; /* offset from instance lookup */ bool status = false; @@ -1476,9 +1461,8 @@ bool Network_Port_IPv6_Gateway(uint32_t object_instance, index = Network_Port_Instance_To_Index(object_instance); if (index < BACNET_NETWORK_PORTS_MAX) { if (Object_List[index].Network_Type == PORT_TYPE_BIP6) { - status = octetstring_init( - ip_address, &Object_List[index].Network.IPv6.IP_Gateway[0], - IPV6_ADDR_SIZE); + status = octetstring_init(ip_address, + &Object_List[index].Network.IPv6.IP_Gateway[0], IPV6_ADDR_SIZE); } } @@ -1494,8 +1478,8 @@ bool Network_Port_IPv6_Gateway(uint32_t object_instance, * * @return true if ip-address was set */ -bool Network_Port_IPv6_Gateway_Set(uint32_t object_instance, - uint8_t *ip_address) +bool Network_Port_IPv6_Gateway_Set( + uint32_t object_instance, uint8_t *ip_address) { unsigned index = 0; /* offset from instance lookup */ bool status = false; @@ -1525,8 +1509,9 @@ bool Network_Port_IPv6_Gateway_Set(uint32_t object_instance, * * @return true if ip-address was retrieved */ -bool Network_Port_IPv6_DNS_Server(uint32_t object_instance, unsigned dns_index, - BACNET_OCTET_STRING *ip_address) +bool Network_Port_IPv6_DNS_Server(uint32_t object_instance, + unsigned dns_index, + BACNET_OCTET_STRING *ip_address) { unsigned index = 0; /* offset from instance lookup */ bool status = false; @@ -1535,8 +1520,7 @@ bool Network_Port_IPv6_DNS_Server(uint32_t object_instance, unsigned dns_index, if (index < BACNET_NETWORK_PORTS_MAX) { if (Object_List[index].Network_Type == PORT_TYPE_BIP6) { if (dns_index < BIP_DNS_MAX) { - status = octetstring_init( - ip_address, + status = octetstring_init(ip_address, &Object_List[index] .Network.IPv6.IP_DNS_Server[dns_index][0], IPV6_ADDR_SIZE); @@ -1557,8 +1541,8 @@ bool Network_Port_IPv6_DNS_Server(uint32_t object_instance, unsigned dns_index, * * @return true if ip-address was set */ -bool Network_Port_IPv6_DNS_Server_Set(uint32_t object_instance, - unsigned dns_index, uint8_t *ip_address) +bool Network_Port_IPv6_DNS_Server_Set( + uint32_t object_instance, unsigned dns_index, uint8_t *ip_address) { unsigned index = 0; /* offset from instance lookup */ bool status = false; @@ -1588,8 +1572,8 @@ bool Network_Port_IPv6_DNS_Server_Set(uint32_t object_instance, * * @return true if ip-address was retrieved */ -bool Network_Port_IPv6_Multicast_Address(uint32_t object_instance, - BACNET_OCTET_STRING *ip_address) +bool Network_Port_IPv6_Multicast_Address( + uint32_t object_instance, BACNET_OCTET_STRING *ip_address) { unsigned index = 0; /* offset from instance lookup */ bool status = false; @@ -1597,8 +1581,7 @@ bool Network_Port_IPv6_Multicast_Address(uint32_t object_instance, index = Network_Port_Instance_To_Index(object_instance); if (index < BACNET_NETWORK_PORTS_MAX) { if (Object_List[index].Network_Type == PORT_TYPE_BIP6) { - status = octetstring_init( - ip_address, + status = octetstring_init(ip_address, &Object_List[index].Network.IPv6.IP_Multicast_Address[0], IPV6_ADDR_SIZE); } @@ -1616,8 +1599,8 @@ bool Network_Port_IPv6_Multicast_Address(uint32_t object_instance, * * @return true if ip-address was set */ -bool Network_Port_IPv6_Multicast_Address_Set(uint32_t object_instance, - uint8_t *ip_address) +bool Network_Port_IPv6_Multicast_Address_Set( + uint32_t object_instance, uint8_t *ip_address) { unsigned index = 0; /* offset from instance lookup */ bool status = false; @@ -1647,8 +1630,8 @@ bool Network_Port_IPv6_Multicast_Address_Set(uint32_t object_instance, * * @return true if ip-address was retrieved */ -bool Network_Port_IPv6_DHCP_Server(uint32_t object_instance, - BACNET_OCTET_STRING *ip_address) +bool Network_Port_IPv6_DHCP_Server( + uint32_t object_instance, BACNET_OCTET_STRING *ip_address) { unsigned index = 0; /* offset from instance lookup */ bool status = false; @@ -1656,8 +1639,8 @@ bool Network_Port_IPv6_DHCP_Server(uint32_t object_instance, index = Network_Port_Instance_To_Index(object_instance); if (index < BACNET_NETWORK_PORTS_MAX) { if (Object_List[index].Network_Type == PORT_TYPE_BIP6) { - status = octetstring_init( - ip_address, &Object_List[index].Network.IPv6.IP_DHCP_Server[0], + status = octetstring_init(ip_address, + &Object_List[index].Network.IPv6.IP_DHCP_Server[0], IPV6_ADDR_SIZE); } } @@ -1674,8 +1657,8 @@ bool Network_Port_IPv6_DHCP_Server(uint32_t object_instance, * * @return true if ip-address was set */ -bool Network_Port_IPv6_DHCP_Server_Set(uint32_t object_instance, - uint8_t *ip_address) +bool Network_Port_IPv6_DHCP_Server_Set( + uint32_t object_instance, uint8_t *ip_address) { unsigned index = 0; /* offset from instance lookup */ bool status = false; @@ -1756,8 +1739,8 @@ bool Network_Port_BIP6_Port_Set(uint32_t object_instance, uint16_t value) * * @return true if zone_index was retrieved */ -bool Network_Port_IPv6_Zone_Index(uint32_t object_instance, - BACNET_CHARACTER_STRING *zone_index) +bool Network_Port_IPv6_Zone_Index( + uint32_t object_instance, BACNET_CHARACTER_STRING *zone_index) { unsigned index = 0; /* offset from instance lookup */ bool status = false; @@ -1782,8 +1765,8 @@ bool Network_Port_IPv6_Zone_Index(uint32_t object_instance, * * @return true if ip-address was set */ -bool Network_Port_IPv6_Gateway_Zone_Index_Set(uint32_t object_instance, - char *zone_index) +bool Network_Port_IPv6_Gateway_Zone_Index_Set( + uint32_t object_instance, char *zone_index) { unsigned index = 0; /* offset from instance lookup */ bool status = false; @@ -1793,7 +1776,7 @@ bool Network_Port_IPv6_Gateway_Zone_Index_Set(uint32_t object_instance, if ((Object_List[index].Network_Type == PORT_TYPE_BIP6) && (zone_index)) { snprintf(&Object_List[index].Network.IPv6.Zone_Index[0], - ZONE_INDEX_SIZE, "%s", zone_index); + ZONE_INDEX_SIZE, "%s", zone_index); } } @@ -1832,8 +1815,8 @@ uint8_t Network_Port_MSTP_Max_Info_Frames(uint32_t object_instance) * * @return true if values are within range and property is set. */ -bool Network_Port_MSTP_Max_Info_Frames_Set(uint32_t object_instance, - uint8_t value) +bool Network_Port_MSTP_Max_Info_Frames_Set( + uint32_t object_instance, uint8_t value) { bool status = false; unsigned index = 0; @@ -1875,22 +1858,22 @@ int Network_Port_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) return 0; } if ((Network_Port_Type(rpdata->object_instance) != PORT_TYPE_MSTP) && - property_list_member(MSTP_Port_Properties_Optional, - rpdata->object_property)) { + property_list_member( + MSTP_Port_Properties_Optional, rpdata->object_property)) { rpdata->error_class = ERROR_CLASS_PROPERTY; rpdata->error_code = ERROR_CODE_UNKNOWN_PROPERTY; return BACNET_STATUS_ERROR; } if ((Network_Port_Type(rpdata->object_instance) != PORT_TYPE_BIP) && - property_list_member(BIP_Port_Properties_Optional, - rpdata->object_property)) { + property_list_member( + BIP_Port_Properties_Optional, rpdata->object_property)) { rpdata->error_class = ERROR_CLASS_PROPERTY; rpdata->error_code = ERROR_CODE_UNKNOWN_PROPERTY; return BACNET_STATUS_ERROR; } if ((Network_Port_Type(rpdata->object_instance) != PORT_TYPE_BIP6) && - property_list_member(BIP6_Port_Properties_Optional, - rpdata->object_property)) { + property_list_member( + BIP6_Port_Properties_Optional, rpdata->object_property)) { rpdata->error_class = ERROR_CLASS_PROPERTY; rpdata->error_code = ERROR_CODE_UNKNOWN_PROPERTY; return BACNET_STATUS_ERROR; @@ -1921,11 +1904,11 @@ int Network_Port_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) } bitstring_set_bit(&bit_string, STATUS_FLAG_OVERRIDDEN, false); if (Network_Port_Out_Of_Service(rpdata->object_instance)) { - bitstring_set_bit(&bit_string, STATUS_FLAG_OUT_OF_SERVICE, - true); + bitstring_set_bit( + &bit_string, STATUS_FLAG_OUT_OF_SERVICE, true); } else { - bitstring_set_bit(&bit_string, STATUS_FLAG_OUT_OF_SERVICE, - false); + bitstring_set_bit( + &bit_string, STATUS_FLAG_OUT_OF_SERVICE, false); } apdu_len = encode_application_bitstring(&apdu[0], &bit_string); break; @@ -1966,8 +1949,7 @@ int Network_Port_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) &apdu[0], Network_Port_Link_Speed(rpdata->object_instance)); break; case PROP_CHANGES_PENDING: - apdu_len = encode_application_boolean( - &apdu[0], + apdu_len = encode_application_boolean(&apdu[0], Network_Port_Changes_Pending(rpdata->object_instance)); break; case PROP_APDU_LENGTH: @@ -1975,13 +1957,11 @@ int Network_Port_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) &apdu[0], Network_Port_APDU_Length(rpdata->object_instance)); break; case PROP_MAX_MASTER: - apdu_len = encode_application_unsigned( - &apdu[0], + apdu_len = encode_application_unsigned(&apdu[0], Network_Port_MSTP_Max_Master(rpdata->object_instance)); break; case PROP_MAX_INFO_FRAMES: - apdu_len = encode_application_unsigned( - &apdu[0], + apdu_len = encode_application_unsigned(&apdu[0], Network_Port_MSTP_Max_Info_Frames(rpdata->object_instance)); break; case PROP_BACNET_IP_MODE: @@ -2005,28 +1985,28 @@ int Network_Port_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) apdu_len = encode_application_octet_string(&apdu[0], &octet_string); break; case PROP_IP_DNS_SERVER: - if (rpdata->array_index == 0) + if (rpdata->array_index == 0) { /* Array element zero is the number of objects in the list */ apdu_len = encode_application_unsigned(&apdu[0], BIP_DNS_MAX); - else if (rpdata->array_index == BACNET_ARRAY_ALL) { + } else if (rpdata->array_index == BACNET_ARRAY_ALL) { /* if no index was specified, then try to encode the entire list */ /* into one packet. */ int len; unsigned index; for (index = 0; index < BIP_DNS_MAX; index++) { - Network_Port_IP_DNS_Server(rpdata->object_instance, index, - &octet_string); - len = encode_application_octet_string(&apdu[apdu_len], - &octet_string); + Network_Port_IP_DNS_Server( + rpdata->object_instance, index, &octet_string); + len = encode_application_octet_string( + &apdu[apdu_len], &octet_string); apdu_len += len; } } else if (rpdata->array_index <= BIP_DNS_MAX) { /* index was specified; encode a single array element */ unsigned index; index = rpdata->array_index - 1; - Network_Port_IP_DNS_Server(rpdata->object_instance, index, - &octet_string); + Network_Port_IP_DNS_Server( + rpdata->object_instance, index, &octet_string); apdu_len = encode_application_octet_string(&apdu[0], &octet_string); } else { @@ -2038,9 +2018,9 @@ int Network_Port_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) break; #if defined(BBMD_ENABLED) case PROP_BBMD_ACCEPT_FD_REGISTRATIONS: - apdu_len = encode_application_boolean( - &apdu[0], Network_Port_BBMD_Accept_FD_Registrations( - rpdata->object_instance)); + apdu_len = encode_application_boolean(&apdu[0], + Network_Port_BBMD_Accept_FD_Registrations( + rpdata->object_instance)); break; case PROP_BBMD_BROADCAST_DISTRIBUTION_TABLE: case PROP_BBMD_FOREIGN_DEVICE_TABLE: @@ -2058,8 +2038,7 @@ int Network_Port_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) apdu_len = encode_application_octet_string(&apdu[0], &octet_string); break; case PROP_IPV6_PREFIX_LENGTH: - apdu_len = encode_application_unsigned( - &apdu[0], + apdu_len = encode_application_unsigned(&apdu[0], Network_Port_IPv6_Subnet_Prefix(rpdata->object_instance)); break; case PROP_BACNET_IPV6_UDP_PORT: @@ -2071,33 +2050,33 @@ int Network_Port_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) apdu_len = encode_application_octet_string(&apdu[0], &octet_string); break; case PROP_BACNET_IPV6_MULTICAST_ADDRESS: - Network_Port_IPv6_Multicast_Address(rpdata->object_instance, - &octet_string); + Network_Port_IPv6_Multicast_Address( + rpdata->object_instance, &octet_string); apdu_len = encode_application_octet_string(&apdu[0], &octet_string); break; case PROP_IPV6_DNS_SERVER: - if (rpdata->array_index == 0) + if (rpdata->array_index == 0) { /* Array element zero is the number of objects in the list */ apdu_len = encode_application_unsigned(&apdu[0], BIP_DNS_MAX); - else if (rpdata->array_index == BACNET_ARRAY_ALL) { + } else if (rpdata->array_index == BACNET_ARRAY_ALL) { /* if no index was specified, then try to encode the entire list */ /* into one packet. */ int len; unsigned index; for (index = 0; index < BIP_DNS_MAX; index++) { - Network_Port_IPv6_DNS_Server(rpdata->object_instance, index, - &octet_string); - len = encode_application_octet_string(&apdu[apdu_len], - &octet_string); + Network_Port_IPv6_DNS_Server( + rpdata->object_instance, index, &octet_string); + len = encode_application_octet_string( + &apdu[apdu_len], &octet_string); apdu_len += len; } } else if (rpdata->array_index <= BIP_DNS_MAX) { /* index was specified; encode a single array element */ unsigned index; index = rpdata->array_index - 1; - Network_Port_IPv6_DNS_Server(rpdata->object_instance, index, - &octet_string); + Network_Port_IPv6_DNS_Server( + rpdata->object_instance, index, &octet_string); apdu_len = encode_application_octet_string(&apdu[0], &octet_string); } else { @@ -2117,8 +2096,8 @@ int Network_Port_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) apdu_len = encode_application_unsigned(&apdu[0], 0); break; case PROP_IPV6_DHCP_SERVER: - Network_Port_IPv6_DHCP_Server(rpdata->object_instance, - &octet_string); + Network_Port_IPv6_DHCP_Server( + rpdata->object_instance, &octet_string); apdu_len = encode_application_octet_string(&apdu[0], &octet_string); break; case PROP_IPV6_ZONE_INDEX: @@ -2157,8 +2136,8 @@ bool Network_Port_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) return false; } /* decode the some of the request */ - len = bacapp_decode_application_data(wp_data->application_data, - wp_data->application_data_len, &value); + len = bacapp_decode_application_data( + wp_data->application_data, wp_data->application_data_len, &value); if (len < 0) { /* error while decoding - a value larger than we can handle */ wp_data->error_class = ERROR_CLASS_PROPERTY; @@ -2269,8 +2248,8 @@ int Network_Port_Read_Range_FDT(uint8_t *apdu, BACNET_READ_RANGE_DATA *pRequest) return 0; } -bool Network_Port_Read_Range(BACNET_READ_RANGE_DATA *pRequest, - RR_PROP_INFO *pInfo) +bool Network_Port_Read_Range( + BACNET_READ_RANGE_DATA *pRequest, RR_PROP_INFO *pInfo) { /* return value */ bool status = false; @@ -2353,8 +2332,9 @@ void Network_Port_Init(void) #include "ctest.h" bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue, - uint8_t ucExpectedTag, BACNET_ERROR_CLASS *pErrorClass, - BACNET_ERROR_CODE *pErrorCode) + uint8_t ucExpectedTag, + BACNET_ERROR_CLASS *pErrorClass, + BACNET_ERROR_CODE *pErrorCode) { pValue = pValue; ucExpectedTag = ucExpectedTag; @@ -2366,7 +2346,7 @@ bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue, void test_network_port(Test *pTest) { - uint8_t apdu[MAX_APDU] = {0}; + uint8_t apdu[MAX_APDU] = { 0 }; int len = 0; int test_len = 0; BACNET_READ_PROPERTY_DATA rpdata; @@ -2379,11 +2359,10 @@ void test_network_port(Test *pTest) unsigned count = 0; uint32_t object_instance = 0; bool status = false; - uint8_t port_type[] = { - PORT_TYPE_ETHERNET, PORT_TYPE_ARCNET, PORT_TYPE_MSTP, - PORT_TYPE_PTP, PORT_TYPE_LONTALK, PORT_TYPE_BIP, - PORT_TYPE_ZIGBEE, PORT_TYPE_VIRTUAL, PORT_TYPE_NON_BACNET, - PORT_TYPE_BIP6, PORT_TYPE_MAX}; + uint8_t port_type[] = { PORT_TYPE_ETHERNET, PORT_TYPE_ARCNET, + PORT_TYPE_MSTP, PORT_TYPE_PTP, PORT_TYPE_LONTALK, PORT_TYPE_BIP, + PORT_TYPE_ZIGBEE, PORT_TYPE_VIRTUAL, PORT_TYPE_NON_BACNET, + PORT_TYPE_BIP6, PORT_TYPE_MAX }; while (port_type[port] != PORT_TYPE_MAX) { object_instance = 1234; @@ -2404,9 +2383,8 @@ void test_network_port(Test *pTest) rpdata.array_index = BACNET_ARRAY_ALL; len = Network_Port_Read_Property(&rpdata); ct_test(pTest, len != 0); - test_len = bacapp_decode_application_data( - rpdata.application_data, (uint8_t)rpdata.application_data_len, - &value); + test_len = bacapp_decode_application_data(rpdata.application_data, + (uint8_t)rpdata.application_data_len, &value); ct_test(pTest, test_len >= 0); if (test_len < 0) { printf("\n"); @@ -2418,9 +2396,8 @@ void test_network_port(Test *pTest) rpdata.array_index = BACNET_ARRAY_ALL; len = Network_Port_Read_Property(&rpdata); ct_test(pTest, len != 0); - test_len = bacapp_decode_application_data( - rpdata.application_data, (uint8_t)rpdata.application_data_len, - &value); + test_len = bacapp_decode_application_data(rpdata.application_data, + (uint8_t)rpdata.application_data_len, &value); ct_test(pTest, test_len >= 0); if (test_len < 0) { printf("\n"); diff --git a/demo/object/netport.h b/src/bacnet/basic/object/netport.h similarity index 93% rename from demo/object/netport.h rename to src/bacnet/basic/object/netport.h index af246455..315fa612 100644 --- a/demo/object/netport.h +++ b/src/bacnet/basic/object/netport.h @@ -36,11 +36,11 @@ #include #include -#include "bacdef.h" -#include "bacenum.h" -#include "apdu.h" -#include "rp.h" -#include "wp.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacenum.h" +#include "bacnet/apdu.h" +#include "bacnet/rp.h" +#include "bacnet/wp.h" #ifdef __cplusplus extern "C" { @@ -240,6 +240,20 @@ extern "C" { unsigned dns_index, uint8_t *ip_address); + bool Network_Port_IPv6_DHCP_Server( + uint32_t object_instance, + BACNET_OCTET_STRING *ip_address); + bool Network_Port_IPv6_DHCP_Server_Set( + uint32_t object_instance, + uint8_t *ip_address); + + bool Network_Port_IPv6_Zone_Index( + uint32_t object_instance, + BACNET_CHARACTER_STRING *zone_index); + bool Network_Port_IPv6_Gateway_Zone_Index_Set( + uint32_t object_instance, + char *zone_index); + uint16_t Network_Port_BIP6_Port( uint32_t object_instance); bool Network_Port_BIP6_Port_Set( diff --git a/demo/object/netport.mak b/src/bacnet/basic/object/netport.mak similarity index 60% rename from demo/object/netport.mak rename to src/bacnet/basic/object/netport.mak index 1cbc1d50..d4a4cda9 100644 --- a/demo/object/netport.mak +++ b/src/bacnet/basic/object/netport.mak @@ -8,17 +8,17 @@ DEFINES = -DBIG_ENDIAN=0 -DBACNET_UNIT_TEST -DTEST_NETWORK_PORT CFLAGS = -Wall $(INCLUDES) $(DEFINES) -g SRCS = netport.c \ - $(SRC_DIR)/bacdcode.c \ - $(SRC_DIR)/bacint.c \ - $(SRC_DIR)/bacstr.c \ - $(SRC_DIR)/bacreal.c \ - $(SRC_DIR)/datetime.c \ - $(SRC_DIR)/bacapp.c \ - $(SRC_DIR)/bacdevobjpropref.c \ - $(SRC_DIR)/bactext.c \ - $(SRC_DIR)/lighting.c \ - $(SRC_DIR)/proplist.c \ - $(SRC_DIR)/indtext.c \ + $(SRC_DIR)/bacnet/bacdcode.c \ + $(SRC_DIR)/bacnet/bacint.c \ + $(SRC_DIR)/bacnet/bacstr.c \ + $(SRC_DIR)/bacnet/bacreal.c \ + $(SRC_DIR)/bacnet/datetime.c \ + $(SRC_DIR)/bacnet/bacapp.c \ + $(SRC_DIR)/bacnet/bacdevobjpropref.c \ + $(SRC_DIR)/bacnet/bactext.c \ + $(SRC_DIR)/bacnet/lighting.c \ + $(SRC_DIR)/bacnet/proplist.c \ + $(SRC_DIR)/bacnet/indtext.c \ $(TEST_DIR)/ctest.c TARGET = network_port diff --git a/demo/handler/objects.c b/src/bacnet/basic/object/objects.c similarity index 91% rename from demo/handler/objects.c rename to src/bacnet/basic/object/objects.c index 3ccc5453..20f4bbb6 100644 --- a/demo/handler/objects.c +++ b/src/bacnet/basic/object/objects.c @@ -36,8 +36,8 @@ #include #include #include -#include "keylist.h" -#include "objects.h" +#include "bacnet/basic/sys/keylist.h" +#include "bacnet/basic/object/objects.h" /** @file objects.c Manage Device Objects. */ @@ -46,8 +46,9 @@ static OS_Keylist Device_List = NULL; void objects_init(void) { - if (!Device_List) + if (!Device_List) { Device_List = Keylist_Create(); + } } int objects_device_count(void) @@ -88,8 +89,8 @@ OBJECT_DEVICE_T *objects_device_new(uint32_t device_instance) Keylist_Data_Add(Device_List, key, pDevice); } else { fprintf(stderr, - "Objects: Unable to allocate device %lu buffer\n", - (unsigned long)device_instance); + "Objects: Unable to allocate device %lu buffer\n", + (unsigned long)device_instance); } } } @@ -106,7 +107,7 @@ OBJECT_DEVICE_T *objects_device_delete(int index) pDevice = Keylist_Data_Delete_By_Index(Device_List, index); if (pDevice) { fprintf(stderr, "Objects: removing device %lu", - (unsigned long)pDevice->Object_Identifier.instance); + (unsigned long)pDevice->Object_Identifier.instance); if (pDevice->Object_List) { do { pObject = @@ -131,8 +132,8 @@ OBJECT_DEVICE_T *objects_device_delete(int index) #include "ctest.h" /* test the object creation and deletion */ -void testBACnetObjectsCompare(Test *pTest, OBJECT_DEVICE_T *pDevice, - uint32_t device_id) +void testBACnetObjectsCompare( + Test *pTest, OBJECT_DEVICE_T *pDevice, uint32_t device_id) { ct_test(pTest, pDevice != NULL); if (pDevice) { @@ -166,8 +167,8 @@ void testBACnetObjects(Test *pTest) for (test_point = 0; test_point < max_test_points; test_point++) { device_id = test_point * (BACNET_MAX_INSTANCE / max_test_points); pDevice = objects_device_data(test_point); - testBACnetObjectsCompare(pTest, pDevice, - Keylist_Key(Device_List, test_point)); + testBACnetObjectsCompare( + pTest, pDevice, Keylist_Key(Device_List, test_point)); } for (test_point = 0; test_point < max_test_points; test_point++) { pDevice = objects_device_delete(0); diff --git a/include/objects.h b/src/bacnet/basic/object/objects.h similarity index 97% rename from include/objects.h rename to src/bacnet/basic/object/objects.h index bf8dd4c5..290dc140 100644 --- a/include/objects.h +++ b/src/bacnet/basic/object/objects.h @@ -27,9 +27,9 @@ #include #include #include -#include "bacdef.h" -#include "bacstr.h" -#include "bacenum.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacstr.h" +#include "bacnet/bacenum.h" typedef union BACnetScale_t { float Float; diff --git a/demo/object/osv.c b/src/bacnet/basic/object/osv.c similarity index 84% rename from demo/object/osv.c rename to src/bacnet/basic/object/osv.c index adba4d08..0cc2d124 100644 --- a/demo/object/osv.c +++ b/src/bacnet/basic/object/osv.c @@ -30,15 +30,15 @@ #include #include -#include "bacdef.h" -#include "bacdcode.h" -#include "bacenum.h" -#include "bacapp.h" -#include "bactext.h" -#include "config.h" /* the custom stuff */ -#include "device.h" -#include "handlers.h" -#include "osv.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacenum.h" +#include "bacnet/bacapp.h" +#include "bacnet/bactext.h" +#include "bacnet/config.h" /* the custom stuff */ +#include "bacnet/basic/object/device.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/object/osv.h" #ifndef MAX_OCTETSTRING_VALUES #define MAX_OCTETSTRING_VALUES 4 @@ -48,24 +48,27 @@ OCTETSTRING_VALUE_DESCR AV_Descr[MAX_OCTETSTRING_VALUES]; /* These three arrays are used by the ReadPropertyMultiple handler */ static const int OctetString_Value_Properties_Required[] = { - PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME, PROP_OBJECT_TYPE, - PROP_PRESENT_VALUE, PROP_STATUS_FLAGS, -1}; + PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME, PROP_OBJECT_TYPE, + PROP_PRESENT_VALUE, PROP_STATUS_FLAGS, -1 +}; -static const int OctetString_Value_Properties_Optional[] = { - PROP_EVENT_STATE, PROP_OUT_OF_SERVICE, PROP_DESCRIPTION, -1}; +static const int OctetString_Value_Properties_Optional[] = { PROP_EVENT_STATE, + PROP_OUT_OF_SERVICE, PROP_DESCRIPTION, -1 }; -static const int OctetString_Value_Properties_Proprietary[] = {-1}; +static const int OctetString_Value_Properties_Proprietary[] = { -1 }; -void OctetString_Value_Property_Lists(const int **pRequired, - const int **pOptional, - const int **pProprietary) +void OctetString_Value_Property_Lists( + const int **pRequired, const int **pOptional, const int **pProprietary) { - if (pRequired) + if (pRequired) { *pRequired = OctetString_Value_Properties_Required; - if (pOptional) + } + if (pOptional) { *pOptional = OctetString_Value_Properties_Optional; - if (pProprietary) + } + if (pProprietary) { *pProprietary = OctetString_Value_Properties_Proprietary; + } return; } @@ -85,8 +88,9 @@ void OctetString_Value_Init(void) /* given instance exists */ bool OctetString_Value_Valid_Instance(uint32_t object_instance) { - if (object_instance < MAX_OCTETSTRING_VALUES) + if (object_instance < MAX_OCTETSTRING_VALUES) { return true; + } return false; } @@ -113,8 +117,9 @@ unsigned OctetString_Value_Instance_To_Index(uint32_t object_instance) { unsigned index = MAX_OCTETSTRING_VALUES; - if (object_instance < MAX_OCTETSTRING_VALUES) + if (object_instance < MAX_OCTETSTRING_VALUES) { index = object_instance; + } return index; } @@ -129,9 +134,8 @@ unsigned OctetString_Value_Instance_To_Index(uint32_t object_instance) * * @return true if values are within range and present-value is set. */ -bool OctetString_Value_Present_Value_Set(uint32_t object_instance, - BACNET_OCTET_STRING *value, - uint8_t priority) +bool OctetString_Value_Present_Value_Set( + uint32_t object_instance, BACNET_OCTET_STRING *value, uint8_t priority) { unsigned index = 0; bool status = false; @@ -158,15 +162,15 @@ BACNET_OCTET_STRING *OctetString_Value_Present_Value(uint32_t object_instance) } /* note: the object name must be unique within this device */ -bool OctetString_Value_Object_Name(uint32_t object_instance, - BACNET_CHARACTER_STRING *object_name) +bool OctetString_Value_Object_Name( + uint32_t object_instance, BACNET_CHARACTER_STRING *object_name) { static char text_string[32] = ""; /* okay for single thread */ bool status = false; if (object_instance < MAX_OCTETSTRING_VALUES) { sprintf(text_string, "OCTETSTRING VALUE %lu", - (unsigned long)object_instance); + (unsigned long)object_instance); status = characterstring_init_ansi(object_name, text_string); } @@ -193,10 +197,11 @@ int OctetString_Value_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) apdu = rpdata->application_data; object_index = OctetString_Value_Instance_To_Index(rpdata->object_instance); - if (object_index < MAX_OCTETSTRING_VALUES) + if (object_index < MAX_OCTETSTRING_VALUES) { CurrentAV = &AV_Descr[object_index]; - else + } else { return BACNET_STATUS_ERROR; + } switch (rpdata->object_property) { case PROP_OBJECT_IDENTIFIER: @@ -206,15 +211,15 @@ int OctetString_Value_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) case PROP_OBJECT_NAME: case PROP_DESCRIPTION: - OctetString_Value_Object_Name(rpdata->object_instance, - &char_string); + OctetString_Value_Object_Name( + rpdata->object_instance, &char_string); apdu_len = encode_application_character_string(&apdu[0], &char_string); break; case PROP_OBJECT_TYPE: - apdu_len = encode_application_enumerated(&apdu[0], - OBJECT_OCTETSTRING_VALUE); + apdu_len = encode_application_enumerated( + &apdu[0], OBJECT_OCTETSTRING_VALUE); break; case PROP_PRESENT_VALUE: @@ -229,7 +234,7 @@ int OctetString_Value_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) bitstring_set_bit(&bit_string, STATUS_FLAG_FAULT, false); bitstring_set_bit(&bit_string, STATUS_FLAG_OVERRIDDEN, false); bitstring_set_bit(&bit_string, STATUS_FLAG_OUT_OF_SERVICE, - CurrentAV->Out_Of_Service); + CurrentAV->Out_Of_Service); apdu_len = encode_application_bitstring(&apdu[0], &bit_string); break; @@ -271,8 +276,8 @@ bool OctetString_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) OCTETSTRING_VALUE_DESCR *CurrentAV; /* decode the some of the request */ - len = bacapp_decode_application_data(wp_data->application_data, - wp_data->application_data_len, &value); + len = bacapp_decode_application_data( + wp_data->application_data, wp_data->application_data_len, &value); /* FIXME: len < application_data_len: more data? */ if (len < 0) { /* error while decoding - a value larger than we can handle */ @@ -290,10 +295,11 @@ bool OctetString_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) } object_index = OctetString_Value_Instance_To_Index(wp_data->object_instance); - if (object_index < MAX_OCTETSTRING_VALUES) + if (object_index < MAX_OCTETSTRING_VALUES) { CurrentAV = &AV_Descr[object_index]; - else + } else { return false; + } switch (wp_data->object_property) { case PROP_PRESENT_VALUE: @@ -323,9 +329,8 @@ bool OctetString_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) break; case PROP_OUT_OF_SERVICE: - status = - WPValidateArgType(&value, BACNET_APPLICATION_TAG_BOOLEAN, - &wp_data->error_class, &wp_data->error_code); + status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_BOOLEAN, + &wp_data->error_class, &wp_data->error_code); if (status) { CurrentAV->Out_Of_Service = value.type.Boolean; } @@ -359,8 +364,9 @@ void OctetString_Value_Intrinsic_Reporting(uint32_t object_instance) #include "ctest.h" bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue, - uint8_t ucExpectedTag, BACNET_ERROR_CLASS *pErrorClass, - BACNET_ERROR_CODE *pErrorCode) + uint8_t ucExpectedTag, + BACNET_ERROR_CLASS *pErrorClass, + BACNET_ERROR_CODE *pErrorCode) { pValue = pValue; ucExpectedTag = ucExpectedTag; @@ -373,7 +379,7 @@ bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue, void testOctetString_Value(Test *pTest) { BACNET_READ_PROPERTY_DATA rpdata; - uint8_t apdu[MAX_APDU] = {0}; + uint8_t apdu[MAX_APDU] = { 0 }; int len = 0; uint32_t len_value = 0; uint8_t tag_number = 0; diff --git a/demo/object/osv.h b/src/bacnet/basic/object/osv.h similarity index 97% rename from demo/object/osv.h rename to src/bacnet/basic/object/osv.h index 55a439ea..5f005c57 100644 --- a/demo/object/osv.h +++ b/src/bacnet/basic/object/osv.h @@ -27,10 +27,10 @@ #include #include -#include "bacdef.h" -#include "bacerror.h" -#include "wp.h" -#include "rp.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacerror.h" +#include "bacnet/wp.h" +#include "bacnet/rp.h" #ifdef __cplusplus extern "C" { diff --git a/demo/object/osv.mak b/src/bacnet/basic/object/osv.mak similarity index 61% rename from demo/object/osv.mak rename to src/bacnet/basic/object/osv.mak index 262346e4..83f4b06b 100644 --- a/demo/object/osv.mak +++ b/src/bacnet/basic/object/osv.mak @@ -8,17 +8,17 @@ DEFINES = -DBIG_ENDIAN=0 -DTEST -DBACAPP_ALL -DBACNET_PROPERTY_LISTS -DTEST_OCTE CFLAGS = -Wall $(INCLUDES) $(DEFINES) -g SRCS = osv.c \ - $(SRC_DIR)/bacdcode.c \ - $(SRC_DIR)/bacint.c \ - $(SRC_DIR)/bacstr.c \ - $(SRC_DIR)/bacreal.c \ - $(SRC_DIR)/bacdevobjpropref.c \ - $(SRC_DIR)/datetime.c \ - $(SRC_DIR)/proplist.c \ - $(SRC_DIR)/lighting.c \ - $(SRC_DIR)/bacapp.c \ - $(SRC_DIR)/bactext.c \ - $(SRC_DIR)/indtext.c \ + $(SRC_DIR)/bacnet/bacdcode.c \ + $(SRC_DIR)/bacnet/bacint.c \ + $(SRC_DIR)/bacnet/bacstr.c \ + $(SRC_DIR)/bacnet/bacreal.c \ + $(SRC_DIR)/bacnet/bacdevobjpropref.c \ + $(SRC_DIR)/bacnet/datetime.c \ + $(SRC_DIR)/bacnet/proplist.c \ + $(SRC_DIR)/bacnet/lighting.c \ + $(SRC_DIR)/bacnet/bacapp.c \ + $(SRC_DIR)/bacnet/bactext.c \ + $(SRC_DIR)/bacnet/indtext.c \ $(TEST_DIR)/ctest.c TARGET = octetstring_value diff --git a/demo/object/piv.c b/src/bacnet/basic/object/piv.c similarity index 85% rename from demo/object/piv.c rename to src/bacnet/basic/object/piv.c index 15d78845..0b556adf 100644 --- a/demo/object/piv.c +++ b/src/bacnet/basic/object/piv.c @@ -30,15 +30,15 @@ #include #include -#include "bacdef.h" -#include "bacdcode.h" -#include "bacenum.h" -#include "bacapp.h" -#include "bactext.h" -#include "config.h" /* the custom stuff */ -#include "device.h" -#include "handlers.h" -#include "piv.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacenum.h" +#include "bacnet/bacapp.h" +#include "bacnet/bactext.h" +#include "bacnet/config.h" /* the custom stuff */ +#include "bacnet/basic/object/device.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/object/piv.h" #ifndef MAX_POSITIVEINTEGER_VALUES #define MAX_POSITIVEINTEGER_VALUES 4 @@ -48,29 +48,28 @@ POSITIVEINTEGER_VALUE_DESCR PIV_Descr[MAX_POSITIVEINTEGER_VALUES]; /* These three arrays are used by the ReadPropertyMultiple handler */ static const int PositiveInteger_Value_Properties_Required[] = { - PROP_OBJECT_IDENTIFIER, - PROP_OBJECT_NAME, - PROP_OBJECT_TYPE, - PROP_PRESENT_VALUE, - PROP_STATUS_FLAGS, - PROP_UNITS, - -1}; + PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME, PROP_OBJECT_TYPE, + PROP_PRESENT_VALUE, PROP_STATUS_FLAGS, PROP_UNITS, -1 +}; static const int PositiveInteger_Value_Properties_Optional[] = { - PROP_OUT_OF_SERVICE, -1}; + PROP_OUT_OF_SERVICE, -1 +}; -static const int PositiveInteger_Value_Properties_Proprietary[] = {-1}; +static const int PositiveInteger_Value_Properties_Proprietary[] = { -1 }; -void PositiveInteger_Value_Property_Lists(const int **pRequired, - const int **pOptional, - const int **pProprietary) +void PositiveInteger_Value_Property_Lists( + const int **pRequired, const int **pOptional, const int **pProprietary) { - if (pRequired) + if (pRequired) { *pRequired = PositiveInteger_Value_Properties_Required; - if (pOptional) + } + if (pOptional) { *pOptional = PositiveInteger_Value_Properties_Optional; - if (pProprietary) + } + if (pProprietary) { *pProprietary = PositiveInteger_Value_Properties_Proprietary; + } return; } @@ -89,8 +88,9 @@ void PositiveInteger_Value_Init(void) /* given instance exists */ bool PositiveInteger_Value_Valid_Instance(uint32_t object_instance) { - if (object_instance < MAX_POSITIVEINTEGER_VALUES) + if (object_instance < MAX_POSITIVEINTEGER_VALUES) { return true; + } return false; } @@ -117,8 +117,9 @@ unsigned PositiveInteger_Value_Instance_To_Index(uint32_t object_instance) { unsigned index = MAX_POSITIVEINTEGER_VALUES; - if (object_instance < MAX_POSITIVEINTEGER_VALUES) + if (object_instance < MAX_POSITIVEINTEGER_VALUES) { index = object_instance; + } return index; } @@ -133,8 +134,8 @@ unsigned PositiveInteger_Value_Instance_To_Index(uint32_t object_instance) * * @return true if values are within range and present-value is set. */ -bool PositiveInteger_Value_Present_Value_Set(uint32_t object_instance, - uint32_t value, uint8_t priority) +bool PositiveInteger_Value_Present_Value_Set( + uint32_t object_instance, uint32_t value, uint8_t priority) { unsigned index = 0; bool status = false; @@ -161,15 +162,15 @@ uint32_t PositiveInteger_Value_Present_Value(uint32_t object_instance) } /* note: the object name must be unique within this device */ -bool PositiveInteger_Value_Object_Name(uint32_t object_instance, - BACNET_CHARACTER_STRING *object_name) +bool PositiveInteger_Value_Object_Name( + uint32_t object_instance, BACNET_CHARACTER_STRING *object_name) { static char text_string[32] = ""; /* okay for single thread */ bool status = false; if (object_instance < MAX_POSITIVEINTEGER_VALUES) { sprintf(text_string, "POSITIVEINTEGER VALUE %lu", - (unsigned long)object_instance); + (unsigned long)object_instance); status = characterstring_init_ansi(object_name, text_string); } @@ -196,21 +197,21 @@ int PositiveInteger_Value_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) object_index = PositiveInteger_Value_Instance_To_Index(rpdata->object_instance); - if (object_index < MAX_POSITIVEINTEGER_VALUES) + if (object_index < MAX_POSITIVEINTEGER_VALUES) { CurrentAV = &PIV_Descr[object_index]; - else + } else { return BACNET_STATUS_ERROR; + } switch (rpdata->object_property) { case PROP_OBJECT_IDENTIFIER: - apdu_len = encode_application_object_id( - &apdu[0], OBJECT_POSITIVE_INTEGER_VALUE, - rpdata->object_instance); + apdu_len = encode_application_object_id(&apdu[0], + OBJECT_POSITIVE_INTEGER_VALUE, rpdata->object_instance); break; case PROP_OBJECT_NAME: - PositiveInteger_Value_Object_Name(rpdata->object_instance, - &char_string); + PositiveInteger_Value_Object_Name( + rpdata->object_instance, &char_string); apdu_len = encode_application_character_string(&apdu[0], &char_string); break; @@ -221,8 +222,7 @@ int PositiveInteger_Value_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) break; case PROP_PRESENT_VALUE: - apdu_len = encode_application_unsigned( - &apdu[0], + apdu_len = encode_application_unsigned(&apdu[0], PositiveInteger_Value_Present_Value(rpdata->object_instance)); break; @@ -232,7 +232,7 @@ int PositiveInteger_Value_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) bitstring_set_bit(&bit_string, STATUS_FLAG_FAULT, false); bitstring_set_bit(&bit_string, STATUS_FLAG_OVERRIDDEN, false); bitstring_set_bit(&bit_string, STATUS_FLAG_OUT_OF_SERVICE, - CurrentAV->Out_Of_Service); + CurrentAV->Out_Of_Service); apdu_len = encode_application_bitstring(&apdu[0], &bit_string); break; @@ -282,8 +282,8 @@ bool PositiveInteger_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) POSITIVEINTEGER_VALUE_DESCR *CurrentAV; /* decode the some of the request */ - len = bacapp_decode_application_data(wp_data->application_data, - wp_data->application_data_len, &value); + len = bacapp_decode_application_data( + wp_data->application_data, wp_data->application_data_len, &value); /* FIXME: len < application_data_len: more data? */ if (len < 0) { /* error while decoding - a value larger than we can handle */ @@ -301,10 +301,11 @@ bool PositiveInteger_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) } object_index = PositiveInteger_Value_Instance_To_Index(wp_data->object_instance); - if (object_index < MAX_POSITIVEINTEGER_VALUES) + if (object_index < MAX_POSITIVEINTEGER_VALUES) { CurrentAV = &PIV_Descr[object_index]; - else + } else { return false; + } switch (wp_data->object_property) { case PROP_PRESENT_VALUE: @@ -334,9 +335,8 @@ bool PositiveInteger_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) break; case PROP_OUT_OF_SERVICE: - status = - WPValidateArgType(&value, BACNET_APPLICATION_TAG_BOOLEAN, - &wp_data->error_class, &wp_data->error_code); + status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_BOOLEAN, + &wp_data->error_class, &wp_data->error_code); if (status) { CurrentAV->Out_Of_Service = value.type.Boolean; } @@ -369,8 +369,9 @@ void PositiveInteger_Value_Intrinsic_Reporting(uint32_t object_instance) #include "ctest.h" bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue, - uint8_t ucExpectedTag, BACNET_ERROR_CLASS *pErrorClass, - BACNET_ERROR_CODE *pErrorCode) + uint8_t ucExpectedTag, + BACNET_ERROR_CLASS *pErrorClass, + BACNET_ERROR_CODE *pErrorCode) { pValue = pValue; ucExpectedTag = ucExpectedTag; @@ -383,7 +384,7 @@ bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue, void testPositiveInteger_Value(Test *pTest) { BACNET_READ_PROPERTY_DATA rpdata; - uint8_t apdu[MAX_APDU] = {0}; + uint8_t apdu[MAX_APDU] = { 0 }; int len = 0; uint32_t len_value = 0; uint8_t tag_number = 0; diff --git a/demo/object/piv.h b/src/bacnet/basic/object/piv.h similarity index 97% rename from demo/object/piv.h rename to src/bacnet/basic/object/piv.h index 76cef97b..4929a59a 100644 --- a/demo/object/piv.h +++ b/src/bacnet/basic/object/piv.h @@ -27,10 +27,10 @@ #include #include -#include "bacdef.h" -#include "bacerror.h" -#include "wp.h" -#include "rp.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacerror.h" +#include "bacnet/wp.h" +#include "bacnet/rp.h" #ifdef __cplusplus extern "C" { diff --git a/demo/object/piv.mak b/src/bacnet/basic/object/piv.mak similarity index 63% rename from demo/object/piv.mak rename to src/bacnet/basic/object/piv.mak index 17dffc52..69a70057 100644 --- a/demo/object/piv.mak +++ b/src/bacnet/basic/object/piv.mak @@ -8,16 +8,16 @@ DEFINES = -DBIG_ENDIAN=0 -DTEST -DBACAPP_ALL -DTEST_POSITIVEINTEGER_VALUE CFLAGS = -Wall $(INCLUDES) $(DEFINES) -g SRCS = piv.c \ - $(SRC_DIR)/bacdcode.c \ - $(SRC_DIR)/bacint.c \ - $(SRC_DIR)/bacstr.c \ - $(SRC_DIR)/bacreal.c \ - $(SRC_DIR)/bacdevobjpropref.c \ - $(SRC_DIR)/datetime.c \ - $(SRC_DIR)/lighting.c \ - $(SRC_DIR)/bacapp.c \ - $(SRC_DIR)/bactext.c \ - $(SRC_DIR)/indtext.c \ + $(SRC_DIR)/bacnet/bacdcode.c \ + $(SRC_DIR)/bacnet/bacint.c \ + $(SRC_DIR)/bacnet/bacstr.c \ + $(SRC_DIR)/bacnet/bacreal.c \ + $(SRC_DIR)/bacnet/bacdevobjpropref.c \ + $(SRC_DIR)/bacnet/datetime.c \ + $(SRC_DIR)/bacnet/lighting.c \ + $(SRC_DIR)/bacnet/bacapp.c \ + $(SRC_DIR)/bacnet/bactext.c \ + $(SRC_DIR)/bacnet/indtext.c \ $(TEST_DIR)/ctest.c TARGET = positiveinteger_value diff --git a/demo/object/schedule.c b/src/bacnet/basic/object/schedule.c similarity index 87% rename from demo/object/schedule.c rename to src/bacnet/basic/object/schedule.c index 30dcfdbc..33586a19 100644 --- a/demo/object/schedule.c +++ b/src/bacnet/basic/object/schedule.c @@ -26,16 +26,16 @@ #include #include -#include "bacdef.h" -#include "bacdcode.h" -#include "bacenum.h" -#include "bactext.h" -#include "config.h" -#include "device.h" -#include "handlers.h" -#include "proplist.h" -#include "timestamp.h" -#include "schedule.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacenum.h" +#include "bacnet/bactext.h" +#include "bacnet/config.h" +#include "bacnet/basic/object/device.h" +#include "bacnet/basic/services.h" +#include "bacnet/proplist.h" +#include "bacnet/timestamp.h" +#include "bacnet/basic/object/schedule.h" #ifndef MAX_SCHEDULES #define MAX_SCHEDULES 4 @@ -43,33 +43,28 @@ SCHEDULE_DESCR Schedule_Descr[MAX_SCHEDULES]; -static const int Schedule_Properties_Required[] = { - PROP_OBJECT_IDENTIFIER, - PROP_OBJECT_NAME, - PROP_OBJECT_TYPE, - PROP_PRESENT_VALUE, - PROP_EFFECTIVE_PERIOD, - PROP_SCHEDULE_DEFAULT, - PROP_LIST_OF_OBJECT_PROPERTY_REFERENCES, - PROP_PRIORITY_FOR_WRITING, - PROP_STATUS_FLAGS, - PROP_RELIABILITY, - PROP_OUT_OF_SERVICE, - -1}; +static const int Schedule_Properties_Required[] = { PROP_OBJECT_IDENTIFIER, + PROP_OBJECT_NAME, PROP_OBJECT_TYPE, PROP_PRESENT_VALUE, + PROP_EFFECTIVE_PERIOD, PROP_SCHEDULE_DEFAULT, + PROP_LIST_OF_OBJECT_PROPERTY_REFERENCES, PROP_PRIORITY_FOR_WRITING, + PROP_STATUS_FLAGS, PROP_RELIABILITY, PROP_OUT_OF_SERVICE, -1 }; -static const int Schedule_Properties_Optional[] = {PROP_WEEKLY_SCHEDULE, -1}; +static const int Schedule_Properties_Optional[] = { PROP_WEEKLY_SCHEDULE, -1 }; -static const int Schedule_Properties_Proprietary[] = {-1}; +static const int Schedule_Properties_Proprietary[] = { -1 }; -void Schedule_Property_Lists(const int **pRequired, const int **pOptional, - const int **pProprietary) +void Schedule_Property_Lists( + const int **pRequired, const int **pOptional, const int **pProprietary) { - if (pRequired) + if (pRequired) { *pRequired = Schedule_Properties_Required; - if (pOptional) + } + if (pOptional) { *pOptional = Schedule_Properties_Optional; - if (pProprietary) + } + if (pProprietary) { *pProprietary = Schedule_Properties_Proprietary; + } } void Schedule_Init(void) @@ -103,10 +98,11 @@ void Schedule_Init(void) bool Schedule_Valid_Instance(uint32_t object_instance) { unsigned int index = Schedule_Instance_To_Index(object_instance); - if (index < MAX_SCHEDULES) + if (index < MAX_SCHEDULES) { return true; - else + } else { return false; + } } unsigned Schedule_Count(void) @@ -123,14 +119,15 @@ unsigned Schedule_Instance_To_Index(uint32_t instance) { unsigned index = MAX_SCHEDULES; - if (instance < MAX_SCHEDULES) + if (instance < MAX_SCHEDULES) { index = instance; + } return index; } -bool Schedule_Object_Name(uint32_t object_instance, - BACNET_CHARACTER_STRING *object_name) +bool Schedule_Object_Name( + uint32_t object_instance, BACNET_CHARACTER_STRING *object_name) { static char text_string[32] = ""; /* okay for single thread */ unsigned int index; @@ -178,16 +175,17 @@ int Schedule_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) } object_index = Schedule_Instance_To_Index(rpdata->object_instance); - if (object_index < MAX_SCHEDULES) + if (object_index < MAX_SCHEDULES) { CurrentSC = &Schedule_Descr[object_index]; - else + } else { return BACNET_STATUS_ERROR; + } apdu = rpdata->application_data; switch ((int)rpdata->object_property) { case PROP_OBJECT_IDENTIFIER: - apdu_len = encode_application_object_id(&apdu[0], OBJECT_SCHEDULE, - rpdata->object_instance); + apdu_len = encode_application_object_id( + &apdu[0], OBJECT_SCHEDULE, rpdata->object_instance); break; case PROP_OBJECT_NAME: Schedule_Object_Name(rpdata->object_instance, &char_string); @@ -216,16 +214,16 @@ int Schedule_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) encode_application_date(&apdu[apdu_len], &CurrentSC->End_Date); break; case PROP_WEEKLY_SCHEDULE: - if (rpdata->array_index == 0) /* count, always 7 */ + if (rpdata->array_index == 0) { /* count, always 7 */ apdu_len = encode_application_unsigned(&apdu[0], 7); - else if (rpdata->array_index == BACNET_ARRAY_ALL) { /* full array */ + } else if (rpdata->array_index == + BACNET_ARRAY_ALL) { /* full array */ int day; for (day = 0; day < 7; day++) { apdu_len += encode_opening_tag(&apdu[apdu_len], 0); for (i = 0; i < CurrentSC->Weekly_Schedule[day].TV_Count; i++) { - apdu_len += bacapp_encode_time_value( - &apdu[apdu_len], + apdu_len += bacapp_encode_time_value(&apdu[apdu_len], &CurrentSC->Weekly_Schedule[day].Time_Values[i]); } apdu_len += encode_closing_tag(&apdu[apdu_len], 0); @@ -234,8 +232,7 @@ int Schedule_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) int day = rpdata->array_index - 1; apdu_len += encode_opening_tag(&apdu[apdu_len], 0); for (i = 0; i < CurrentSC->Weekly_Schedule[day].TV_Count; i++) { - apdu_len += bacapp_encode_time_value( - &apdu[apdu_len], + apdu_len += bacapp_encode_time_value(&apdu[apdu_len], &CurrentSC->Weekly_Schedule[day].Time_Values[i]); } apdu_len += encode_closing_tag(&apdu[apdu_len], 0); @@ -323,8 +320,8 @@ bool Schedule_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) remove this comment when my changes accepted after suitable time for review by all interested parties. Say 6 months -> September 2016 */ /* decode the some of the request */ - len = bacapp_decode_application_data(wp_data->application_data, - wp_data->application_data_len, &value); + len = bacapp_decode_application_data( + wp_data->application_data, wp_data->application_data_len, &value); /* FIXME: len < application_data_len: more data? */ if (len < 0) { /* error while decoding - a value larger than we can handle */ @@ -349,12 +346,11 @@ bool Schedule_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) suitable time for review by all interested parties. Say 6 months -> September 2016 */ - status = - WPValidateArgType(&value, BACNET_APPLICATION_TAG_BOOLEAN, - &wp_data->error_class, &wp_data->error_code); + status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_BOOLEAN, + &wp_data->error_class, &wp_data->error_code); if (status) { - Schedule_Out_Of_Service_Set(wp_data->object_instance, - value.type.Boolean); + Schedule_Out_Of_Service_Set( + wp_data->object_instance, value.type.Boolean); } break; @@ -387,15 +383,16 @@ bool Schedule_In_Effective_Period(SCHEDULE_DESCR *desc, BACNET_DATE *date) if (desc && date) { if (datetime_wildcard_compare_date(&desc->Start_Date, date) <= 0 && - datetime_wildcard_compare_date(&desc->End_Date, date) >= 0) + datetime_wildcard_compare_date(&desc->End_Date, date) >= 0) { res = true; + } } return res; } -void Schedule_Recalculate_PV(SCHEDULE_DESCR *desc, BACNET_WEEKDAY wday, - BACNET_TIME *time) +void Schedule_Recalculate_PV( + SCHEDULE_DESCR *desc, BACNET_WEEKDAY wday, BACNET_TIME *time) { int i; desc->Present_Value = NULL; @@ -410,7 +407,7 @@ void Schedule_Recalculate_PV(SCHEDULE_DESCR *desc, BACNET_WEEKDAY wday, broker an early release on a case-by-case basis. */ for (i = 0; i < desc->Weekly_Schedule[wday - 1].TV_Count && - desc->Present_Value == NULL; + desc->Present_Value == NULL; i++) { int diff = datetime_wildcard_compare_time( time, &desc->Weekly_Schedule[wday - 1].Time_Values[i].Time); @@ -422,8 +419,9 @@ void Schedule_Recalculate_PV(SCHEDULE_DESCR *desc, BACNET_WEEKDAY wday, } } - if (desc->Present_Value == NULL) + if (desc->Present_Value == NULL) { desc->Present_Value = &desc->Schedule_Default; + } } #ifdef TEST @@ -434,7 +432,7 @@ void Schedule_Recalculate_PV(SCHEDULE_DESCR *desc, BACNET_WEEKDAY wday, void testSchedule(Test *pTest) { BACNET_READ_PROPERTY_DATA rpdata; - uint8_t apdu[MAX_APDU] = {0}; + uint8_t apdu[MAX_APDU] = { 0 }; int len = 0; uint32_t len_value = 0; uint8_t tag_number = 0; diff --git a/demo/object/schedule.h b/src/bacnet/basic/object/schedule.h similarity index 94% rename from demo/object/schedule.h rename to src/bacnet/basic/object/schedule.h index 3cb12d6a..a82d2a95 100644 --- a/demo/object/schedule.h +++ b/src/bacnet/basic/object/schedule.h @@ -28,14 +28,14 @@ #include #include -#include "bacdef.h" -#include "bacapp.h" -#include "datetime.h" -#include "bacerror.h" -#include "wp.h" -#include "rp.h" -#include "bacdevobjpropref.h" -#include "bactimevalue.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacapp.h" +#include "bacnet/datetime.h" +#include "bacnet/bacerror.h" +#include "bacnet/wp.h" +#include "bacnet/rp.h" +#include "bacnet/bacdevobjpropref.h" +#include "bacnet/bactimevalue.h" #ifndef BACNET_WEEKLY_SCHEDULE_SIZE #define BACNET_WEEKLY_SCHEDULE_SIZE 8 /* maximum number of data points for each day */ diff --git a/demo/object/schedule.mak b/src/bacnet/basic/object/schedule.mak similarity index 60% rename from demo/object/schedule.mak rename to src/bacnet/basic/object/schedule.mak index dea50d1e..4b9a9aca 100644 --- a/demo/object/schedule.mak +++ b/src/bacnet/basic/object/schedule.mak @@ -8,17 +8,17 @@ DEFINES = -DBIG_ENDIAN=0 -DTEST -DBACAPP_ALL -DTEST_SCHEDULE CFLAGS = -Wall $(INCLUDES) $(DEFINES) -g SRCS = schedule.c \ - $(SRC_DIR)/bacdcode.c \ - $(SRC_DIR)/bacint.c \ - $(SRC_DIR)/bacstr.c \ - $(SRC_DIR)/bacreal.c \ - $(SRC_DIR)/bacdevobjpropref.c \ - $(SRC_DIR)/bactimevalue.c \ - $(SRC_DIR)/datetime.c \ - $(SRC_DIR)/lighting.c \ - $(SRC_DIR)/bacapp.c \ - $(SRC_DIR)/bactext.c \ - $(SRC_DIR)/indtext.c \ + $(SRC_DIR)/bacnet/bacdcode.c \ + $(SRC_DIR)/bacnet/bacint.c \ + $(SRC_DIR)/bacnet/bacstr.c \ + $(SRC_DIR)/bacnet/bacreal.c \ + $(SRC_DIR)/bacnet/bacdevobjpropref.c \ + $(SRC_DIR)/bacnet/bactimevalue.c \ + $(SRC_DIR)/bacnet/datetime.c \ + $(SRC_DIR)/bacnet/lighting.c \ + $(SRC_DIR)/bacnet/bacapp.c \ + $(SRC_DIR)/bacnet/bactext.c \ + $(SRC_DIR)/bacnet/indtext.c \ $(TEST_DIR)/ctest.c TARGET = schedule diff --git a/demo/object/trendlog.c b/src/bacnet/basic/object/trendlog.c similarity index 80% rename from demo/object/trendlog.c rename to src/bacnet/basic/object/trendlog.c index 526774a8..b18888a6 100644 --- a/demo/object/trendlog.c +++ b/src/bacnet/basic/object/trendlog.c @@ -26,22 +26,22 @@ #include #include #include /* for memmove */ -#include "bacdef.h" -#include "bacdcode.h" -#include "bacenum.h" -#include "bacapp.h" -#include "config.h" /* the custom stuff */ -#include "apdu.h" -#include "wp.h" /* write property handling */ -#include "version.h" -#include "device.h" /* me */ -#include "handlers.h" -#include "datalink.h" -#include "address.h" -#include "bacdevobjpropref.h" -#include "trendlog.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacenum.h" +#include "bacnet/bacapp.h" +#include "bacnet/config.h" /* the custom stuff */ +#include "bacnet/apdu.h" +#include "bacnet/wp.h" /* write property handling */ +#include "bacnet/version.h" +#include "bacnet/basic/object/device.h" /* me */ +#include "bacnet/basic/services.h" +#include "bacnet/datalink/datalink.h" +#include "bacnet/basic/binding/address.h" +#include "bacnet/bacdevobjpropref.h" +#include "bacnet/basic/object/trendlog.h" #if defined(BACFILE) -#include "bacfile.h" /* object list dependency */ +#include "bacnet/basic/object/bacfile.h" /* object list dependency */ #endif /* number of demo objects */ @@ -53,23 +53,15 @@ TL_DATA_REC Logs[MAX_TREND_LOGS][TL_MAX_ENTRIES]; static TL_LOG_INFO LogInfo[MAX_TREND_LOGS]; /* These three arrays are used by the ReadPropertyMultiple handler */ -static const int Trend_Log_Properties_Required[] = {PROP_OBJECT_IDENTIFIER, - PROP_OBJECT_NAME, - PROP_OBJECT_TYPE, - PROP_ENABLE, - PROP_STOP_WHEN_FULL, - PROP_BUFFER_SIZE, - PROP_LOG_BUFFER, - PROP_RECORD_COUNT, - PROP_TOTAL_RECORD_COUNT, - PROP_EVENT_STATE, - PROP_LOGGING_TYPE, - PROP_STATUS_FLAGS, - -1}; +static const int Trend_Log_Properties_Required[] = { PROP_OBJECT_IDENTIFIER, + PROP_OBJECT_NAME, PROP_OBJECT_TYPE, PROP_ENABLE, PROP_STOP_WHEN_FULL, + PROP_BUFFER_SIZE, PROP_LOG_BUFFER, PROP_RECORD_COUNT, + PROP_TOTAL_RECORD_COUNT, PROP_EVENT_STATE, PROP_LOGGING_TYPE, + PROP_STATUS_FLAGS, -1 }; -static const int Trend_Log_Properties_Optional[] = { - PROP_DESCRIPTION, PROP_START_TIME, PROP_STOP_TIME, - PROP_LOG_DEVICE_OBJECT_PROPERTY, PROP_LOG_INTERVAL, +static const int Trend_Log_Properties_Optional[] = { PROP_DESCRIPTION, + PROP_START_TIME, PROP_STOP_TIME, PROP_LOG_DEVICE_OBJECT_PROPERTY, + PROP_LOG_INTERVAL, /* Required if COV logging supported PROP_COV_RESUBSCRIPTION_INTERVAL, @@ -85,19 +77,22 @@ static const int Trend_Log_Properties_Optional[] = { PROP_NOTIFY_TYPE, PROP_EVENT_TIME_STAMPS, */ - PROP_ALIGN_INTERVALS, PROP_INTERVAL_OFFSET, PROP_TRIGGER, -1}; + PROP_ALIGN_INTERVALS, PROP_INTERVAL_OFFSET, PROP_TRIGGER, -1 }; -static const int Trend_Log_Properties_Proprietary[] = {-1}; +static const int Trend_Log_Properties_Proprietary[] = { -1 }; -void Trend_Log_Property_Lists(const int **pRequired, const int **pOptional, - const int **pProprietary) +void Trend_Log_Property_Lists( + const int **pRequired, const int **pOptional, const int **pProprietary) { - if (pRequired) + if (pRequired) { *pRequired = Trend_Log_Properties_Required; - if (pOptional) + } + if (pOptional) { *pOptional = Trend_Log_Properties_Optional; - if (pProprietary) + } + if (pProprietary) { *pProprietary = Trend_Log_Properties_Proprietary; + } return; } @@ -190,10 +185,11 @@ void Trend_Log_Init(void) Logs[iLog][iEntry].Datum.fReal = (float)(iEntry + (iLog * TL_MAX_ENTRIES)); /* Put status flags with every second log */ - if ((iLog & 1) == 0) + if ((iLog & 1) == 0) { Logs[iLog][iEntry].ucStatus = 128; - else + } else { Logs[iLog][iEntry].ucStatus = 0; + } tClock += 900; /* advance 15 minutes */ } @@ -219,12 +215,12 @@ void Trend_Log_Init(void) LogInfo[iLog].Source.arrayIndex = BACNET_ARRAY_ALL; LogInfo[iLog].Source.propertyIdentifier = PROP_PRESENT_VALUE; - datetime_set_values(&LogInfo[iLog].StartTime, 2009, 1, 1, 0, 0, 0, - 0); + datetime_set_values( + &LogInfo[iLog].StartTime, 2009, 1, 1, 0, 0, 0, 0); LogInfo[iLog].tStartTime = TL_BAC_Time_To_Local(&LogInfo[iLog].StartTime); - datetime_set_values(&LogInfo[iLog].StopTime, 2020, 12, 22, 23, 59, - 59, 99); + datetime_set_values( + &LogInfo[iLog].StopTime, 2020, 12, 22, 23, 59, 59, 99); LogInfo[iLog].tStopTime = TL_BAC_Time_To_Local(&LogInfo[iLog].StopTime); } @@ -238,8 +234,8 @@ void Trend_Log_Init(void) * on the assumption that there is a 1 to 1 correspondance. If there * is not we need to convert to index before proceeding. */ -bool Trend_Log_Object_Name(uint32_t object_instance, - BACNET_CHARACTER_STRING *object_name) +bool Trend_Log_Object_Name( + uint32_t object_instance, BACNET_CHARACTER_STRING *object_name) { static char text_string[32] = ""; /* okay for single thread */ bool status = false; @@ -257,7 +253,7 @@ bool Trend_Log_Object_Name(uint32_t object_instance, int Trend_Log_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) { int apdu_len = 0; /* return value */ - int len = 0; /* apdu len intermediate value */ + int len = 0; /* apdu len intermediate value */ BACNET_BIT_STRING bit_string; BACNET_CHARACTER_STRING char_string; TL_LOG_INFO *CurrentLog; @@ -272,8 +268,8 @@ int Trend_Log_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) rpdata->object_instance)]; /* Pin down which log to look at */ switch (rpdata->object_property) { case PROP_OBJECT_IDENTIFIER: - apdu_len = encode_application_object_id(&apdu[0], OBJECT_TRENDLOG, - rpdata->object_instance); + apdu_len = encode_application_object_id( + &apdu[0], OBJECT_TRENDLOG, rpdata->object_instance); break; case PROP_DESCRIPTION: @@ -309,8 +305,8 @@ int Trend_Log_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) break; case PROP_RECORD_COUNT: - apdu_len += encode_application_unsigned(&apdu[0], - CurrentLog->ulRecordCount); + apdu_len += encode_application_unsigned( + &apdu[0], CurrentLog->ulRecordCount); break; case PROP_TOTAL_RECORD_COUNT: @@ -325,8 +321,8 @@ int Trend_Log_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) break; case PROP_LOGGING_TYPE: - apdu_len = encode_application_enumerated(&apdu[0], - CurrentLog->LoggingType); + apdu_len = encode_application_enumerated( + &apdu[0], CurrentLog->LoggingType); break; case PROP_STATUS_FLAGS: @@ -343,16 +339,16 @@ int Trend_Log_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) len = encode_application_date(&apdu[0], &CurrentLog->StartTime.date); apdu_len = len; - len = encode_application_time(&apdu[apdu_len], - &CurrentLog->StartTime.time); + len = encode_application_time( + &apdu[apdu_len], &CurrentLog->StartTime.time); apdu_len += len; break; case PROP_STOP_TIME: len = encode_application_date(&apdu[0], &CurrentLog->StopTime.date); apdu_len = len; - len = encode_application_time(&apdu[apdu_len], - &CurrentLog->StopTime.time); + len = encode_application_time( + &apdu[apdu_len], &CurrentLog->StopTime.time); apdu_len += len; break; @@ -382,8 +378,8 @@ int Trend_Log_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) break; case PROP_ALIGN_INTERVALS: - apdu_len = encode_application_boolean(&apdu[0], - CurrentLog->bAlignIntervals); + apdu_len = encode_application_boolean( + &apdu[0], CurrentLog->bAlignIntervals); break; case PROP_INTERVAL_OFFSET: @@ -434,8 +430,8 @@ bool Trend_Log_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) CurrentLog = &LogInfo[log_index]; /* decode the some of the request */ - len = bacapp_decode_application_data(wp_data->application_data, - wp_data->application_data_len, &value); + len = bacapp_decode_application_data( + wp_data->application_data, wp_data->application_data_len, &value); /* FIXME: len < application_data_len: more data? */ if (len < 0) { /* error while decoding - a value larger than we can handle */ @@ -452,9 +448,8 @@ bool Trend_Log_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) } switch (wp_data->object_property) { case PROP_ENABLE: - status = - WPValidateArgType(&value, BACNET_APPLICATION_TAG_BOOLEAN, - &wp_data->error_class, &wp_data->error_code); + status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_BOOLEAN, + &wp_data->error_class, &wp_data->error_code); if (status) { /* Section 12.25.5 can't enable a full log with stop when full * set */ @@ -478,8 +473,8 @@ bool Trend_Log_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) if (bEffectiveEnable == true) { /* Only insert record if we really were enabled i.e. times and enable flags */ - TL_Insert_Status_Rec(log_index, - LOG_STATUS_LOG_DISABLED, true); + TL_Insert_Status_Rec( + log_index, LOG_STATUS_LOG_DISABLED, true); } } else { if (TL_Is_Enabled(log_index)) { @@ -495,9 +490,8 @@ bool Trend_Log_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) break; case PROP_STOP_WHEN_FULL: - status = - WPValidateArgType(&value, BACNET_APPLICATION_TAG_BOOLEAN, - &wp_data->error_class, &wp_data->error_code); + status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_BOOLEAN, + &wp_data->error_class, &wp_data->error_code); if (status) { /* Only trigger this on a change of state */ if (CurrentLog->bStopWhenFull != value.type.Boolean) { @@ -511,8 +505,8 @@ bool Trend_Log_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) * 135-2008 12.25.12 */ CurrentLog->bEnable = false; - TL_Insert_Status_Rec(log_index, LOG_STATUS_LOG_DISABLED, - true); + TL_Insert_Status_Rec( + log_index, LOG_STATUS_LOG_DISABLED, true); } } } @@ -530,14 +524,14 @@ bool Trend_Log_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) case PROP_RECORD_COUNT: status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_UNSIGNED_INT, - &wp_data->error_class, &wp_data->error_code); + &wp_data->error_class, &wp_data->error_code); if (status) { if (value.type.Unsigned_Int == 0) { /* Time to clear down the log */ CurrentLog->ulRecordCount = 0; CurrentLog->iIndex = 0; - TL_Insert_Status_Rec(log_index, LOG_STATUS_BUFFER_PURGED, - true); + TL_Insert_Status_Rec( + log_index, LOG_STATUS_BUFFER_PURGED, true); } } break; @@ -548,7 +542,7 @@ bool Trend_Log_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) */ status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_ENUMERATED, - &wp_data->error_class, &wp_data->error_code); + &wp_data->error_class, &wp_data->error_code); if (status) { if (value.type.Enumerated != LOGGING_TYPE_COV) { CurrentLog->LoggingType = value.type.Enumerated; @@ -576,22 +570,20 @@ bool Trend_Log_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) case PROP_START_TIME: /* Copy the date part to safe place */ - status = - WPValidateArgType(&value, BACNET_APPLICATION_TAG_DATE, - &wp_data->error_class, &wp_data->error_code); + status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_DATE, + &wp_data->error_class, &wp_data->error_code); if (!status) { break; } TempDate = value.type.Date; /* Then decode the time part */ - len = bacapp_decode_application_data( - wp_data->application_data + len, - wp_data->application_data_len - len, &value); + len = + bacapp_decode_application_data(wp_data->application_data + len, + wp_data->application_data_len - len, &value); if (len) { status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_TIME, - &wp_data->error_class, - &wp_data->error_code); + &wp_data->error_class, &wp_data->error_code); if (!status) { break; } @@ -616,12 +608,12 @@ bool Trend_Log_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) /* Enable status has changed because of time update */ if (bEffectiveEnable == true) { /* Say we went from enabled to disabled */ - TL_Insert_Status_Rec(log_index, LOG_STATUS_LOG_DISABLED, - true); + TL_Insert_Status_Rec( + log_index, LOG_STATUS_LOG_DISABLED, true); } else { /* Say we went from disabled to enabled */ - TL_Insert_Status_Rec(log_index, LOG_STATUS_LOG_DISABLED, - false); + TL_Insert_Status_Rec( + log_index, LOG_STATUS_LOG_DISABLED, false); } } } @@ -629,22 +621,20 @@ bool Trend_Log_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) case PROP_STOP_TIME: /* Copy the date part to safe place */ - status = - WPValidateArgType(&value, BACNET_APPLICATION_TAG_DATE, - &wp_data->error_class, &wp_data->error_code); + status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_DATE, + &wp_data->error_class, &wp_data->error_code); if (!status) { break; } TempDate = value.type.Date; /* Then decode the time part */ - len = bacapp_decode_application_data( - wp_data->application_data + len, - wp_data->application_data_len - len, &value); + len = + bacapp_decode_application_data(wp_data->application_data + len, + wp_data->application_data_len - len, &value); if (len) { status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_TIME, - &wp_data->error_class, - &wp_data->error_code); + &wp_data->error_class, &wp_data->error_code); if (!status) { break; } @@ -671,12 +661,12 @@ bool Trend_Log_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) /* Enable status has changed because of time update */ if (bEffectiveEnable == true) { /* Say we went from enabled to disabled */ - TL_Insert_Status_Rec(log_index, LOG_STATUS_LOG_DISABLED, - true); + TL_Insert_Status_Rec( + log_index, LOG_STATUS_LOG_DISABLED, true); } else { /* Say we went from disabled to enabled */ - TL_Insert_Status_Rec(log_index, LOG_STATUS_LOG_DISABLED, - false); + TL_Insert_Status_Rec( + log_index, LOG_STATUS_LOG_DISABLED, false); } } } @@ -686,8 +676,8 @@ bool Trend_Log_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) len = bacapp_decode_device_obj_property_ref( wp_data->application_data, &TempSource); if ((len < 0) || - (len > wp_data->application_data_len)) // Hmm, that didn't go - // as planned... + (len > wp_data->application_data_len)) // Hmm, that didn't go + // as planned... { wp_data->error_class = ERROR_CLASS_PROPERTY; wp_data->error_code = ERROR_CODE_OTHER; @@ -697,7 +687,7 @@ bool Trend_Log_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) // We only support references to objects in ourself for now if ((TempSource.deviceIdentifier.type == OBJECT_DEVICE) && (TempSource.deviceIdentifier.instance != - Device_Object_Instance_Number())) { + Device_Object_Instance_Number())) { wp_data->error_class = ERROR_CLASS_PROPERTY; wp_data->error_code = ERROR_CODE_OPTIONAL_FUNCTIONALITY_NOT_SUPPORTED; @@ -706,7 +696,7 @@ bool Trend_Log_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) /* Quick comparison if structures are packed ... */ if (memcmp(&TempSource, &CurrentLog->Source, - sizeof(BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE)) != 0) { + sizeof(BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE)) != 0) { /* Clear buffer if property being logged is changed */ CurrentLog->ulRecordCount = 0; CurrentLog->iIndex = 0; @@ -725,7 +715,7 @@ bool Trend_Log_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) } status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_UNSIGNED_INT, - &wp_data->error_class, &wp_data->error_code); + &wp_data->error_class, &wp_data->error_code); if (status) { if ((CurrentLog->LoggingType == LOGGING_TYPE_POLLED) && (value.type.Unsigned_Int == 0)) { @@ -740,17 +730,17 @@ bool Trend_Log_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) /* We only log to 1 sec accuracy so must divide by 100 * before passing it on */ CurrentLog->ulLogInterval = value.type.Unsigned_Int / 100; - if (0 == CurrentLog->ulLogInterval) + if (0 == CurrentLog->ulLogInterval) { CurrentLog->ulLogInterval = 1; /* Interval of 0 is not a good idea */ + } } } break; case PROP_ALIGN_INTERVALS: - status = - WPValidateArgType(&value, BACNET_APPLICATION_TAG_BOOLEAN, - &wp_data->error_class, &wp_data->error_code); + status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_BOOLEAN, + &wp_data->error_class, &wp_data->error_code); if (status) { CurrentLog->bAlignIntervals = value.type.Boolean; } @@ -761,16 +751,15 @@ bool Trend_Log_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) * passing it on */ status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_UNSIGNED_INT, - &wp_data->error_class, &wp_data->error_code); + &wp_data->error_class, &wp_data->error_code); if (status) { CurrentLog->ulIntervalOffset = value.type.Unsigned_Int / 100; } break; case PROP_TRIGGER: - status = - WPValidateArgType(&value, BACNET_APPLICATION_TAG_BOOLEAN, - &wp_data->error_class, &wp_data->error_code); + status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_BOOLEAN, + &wp_data->error_class, &wp_data->error_code); if (status) { /* We will not allow triggered operation if polling with * aligning to the clock as that will produce non aligned @@ -842,12 +831,14 @@ void TL_Insert_Status_Rec(int iLog, BACNET_LOG_STATUS eStatus, bool bState) * into the bitstring structure later on when we have to encode them */ switch (eStatus) { case LOG_STATUS_LOG_DISABLED: - if (bState) + if (bState) { TempRec.Datum.ucLogStatus = 1 << LOG_STATUS_LOG_DISABLED; + } break; case LOG_STATUS_BUFFER_PURGED: - if (bState) + if (bState) { TempRec.Datum.ucLogStatus = 1 << LOG_STATUS_BUFFER_PURGED; + } break; case LOG_STATUS_LOG_INTERRUPTED: TempRec.Datum.ucLogStatus = 1 << LOG_STATUS_LOG_INTERRUPTED; @@ -857,13 +848,15 @@ void TL_Insert_Status_Rec(int iLog, BACNET_LOG_STATUS eStatus, bool bState) } Logs[iLog][CurrentLog->iIndex++] = TempRec; - if (CurrentLog->iIndex >= TL_MAX_ENTRIES) + if (CurrentLog->iIndex >= TL_MAX_ENTRIES) { CurrentLog->iIndex = 0; + } CurrentLog->ulTotalRecordCount++; - if (CurrentLog->ulRecordCount < TL_MAX_ENTRIES) + if (CurrentLog->ulRecordCount < TL_MAX_ENTRIES) { CurrentLog->ulRecordCount++; + } } /***************************************************************************** @@ -889,7 +882,7 @@ bool TL_Is_Enabled(int iLog) /* Not enabled so time is irrelevant */ bStatus = false; } else if ((CurrentLog->ucTimeFlags == 0) && - (CurrentLog->tStopTime < CurrentLog->tStartTime)) { + (CurrentLog->tStopTime < CurrentLog->tStartTime)) { /* Start time was after stop time as per 12.25.6 and 12.25.7 */ bStatus = false; } else if (CurrentLog->ucTimeFlags != (TL_T_START_WILD | TL_T_STOP_WILD)) { @@ -903,12 +896,14 @@ bool TL_Is_Enabled(int iLog) #endif if ((CurrentLog->ucTimeFlags & TL_T_START_WILD) != 0) { /* wild card start time */ - if (tNow > CurrentLog->tStopTime) + if (tNow > CurrentLog->tStopTime) { bStatus = false; + } } else if ((CurrentLog->ucTimeFlags & TL_T_STOP_WILD) != 0) { /* wild card stop time */ - if (tNow < CurrentLog->tStartTime) + if (tNow < CurrentLog->tStartTime) { bStatus = false; + } } else { #if 0 printf("\nCurrent - %u, Start - %u, Stop - %u\n", @@ -917,8 +912,9 @@ bool TL_Is_Enabled(int iLog) #endif /* No wildcards so use both times */ if ((tNow < CurrentLog->tStartTime) || - (tNow > CurrentLog->tStopTime)) + (tNow > CurrentLog->tStopTime)) { bStatus = false; + } } } @@ -973,10 +969,11 @@ void TL_Local_Time_To_BAC(BACNET_DATE_TIME *DestTime, time_t SourceTime) /* BACnet is 1 to 7 = Monday to Sunday * Windows is days from Sunday 0 - 6 so we * have to adjust */ - if (TempTime->tm_wday == 0) + if (TempTime->tm_wday == 0) { DestTime->date.wday = 7; - else + } else { DestTime->date.wday = (uint8_t)TempTime->tm_wday; + } DestTime->time.hour = (uint8_t)TempTime->tm_hour; DestTime->time.min = (uint8_t)TempTime->tm_min; DestTime->time.sec = (uint8_t)TempTime->tm_sec; @@ -1015,14 +1012,16 @@ int rr_trend_log_encode(uint8_t *apdu, BACNET_READ_RANGE_DATA *pRequest) /* Bail out now if nowt - should never happen for a Trend Log but ... */ if (LogInfo[Trend_Log_Instance_To_Index(pRequest->object_instance)] - .ulRecordCount == 0) + .ulRecordCount == 0) { return (0); + } if ((pRequest->RequestType == RR_BY_POSITION) || - (pRequest->RequestType == RR_READ_ALL)) + (pRequest->RequestType == RR_READ_ALL)) { return (TL_encode_by_position(apdu, pRequest)); - else if (pRequest->RequestType == RR_BY_SEQUENCE) + } else if (pRequest->RequestType == RR_BY_SEQUENCE) { return (TL_encode_by_sequence(apdu, pRequest)); + } return (TL_encode_by_time(apdu, pRequest)); } @@ -1040,10 +1039,10 @@ int TL_encode_by_position(uint8_t *apdu, BACNET_READ_RANGE_DATA *pRequest) int32_t iTemp = 0; TL_LOG_INFO *CurrentLog = NULL; - uint32_t uiIndex = 0; /* Current entry number */ - uint32_t uiFirst = 0; /* Entry number we started encoding from */ - uint32_t uiLast = 0; /* Entry number we finished encoding on */ - uint32_t uiTarget = 0; /* Last entry we are required to encode */ + uint32_t uiIndex = 0; /* Current entry number */ + uint32_t uiFirst = 0; /* Entry number we started encoding from */ + uint32_t uiLast = 0; /* Entry number we finished encoding on */ + uint32_t uiTarget = 0; /* Last entry we are required to encode */ uint32_t uiRemaining = 0; /* Amount of unused space in packet */ /* See how much space we have */ @@ -1091,15 +1090,17 @@ int TL_encode_by_position(uint8_t *apdu, BACNET_READ_RANGE_DATA *pRequest) /* From here on in we only have a starting point and a positive count */ if (pRequest->Range.RefIndex > - CurrentLog->ulRecordCount) /* Nothing to return as we are past the end + CurrentLog->ulRecordCount) { /* Nothing to return as we are past the end of the list */ return (0); + } uiTarget = pRequest->Range.RefIndex + pRequest->Count - - 1; /* Index of last required entry */ + 1; /* Index of last required entry */ if (uiTarget > - CurrentLog->ulRecordCount) /* Capped at end of list if necessary */ + CurrentLog->ulRecordCount) { /* Capped at end of list if necessary */ uiTarget = CurrentLog->ulRecordCount; + } uiIndex = pRequest->Range.RefIndex; uiFirst = uiIndex; /* Record where we started from */ @@ -1109,26 +1110,28 @@ int TL_encode_by_position(uint8_t *apdu, BACNET_READ_RANGE_DATA *pRequest) * Can't fit any more in! We just set the result flag to say there * was more and drop out of the loop early */ - bitstring_set_bit(&pRequest->ResultFlags, RESULT_FLAG_MORE_ITEMS, - true); + bitstring_set_bit( + &pRequest->ResultFlags, RESULT_FLAG_MORE_ITEMS, true); break; } iTemp = TL_encode_entry(&apdu[iLen], log_index, uiIndex); - uiRemaining -= iTemp; /* Reduce the remaining space */ - iLen += iTemp; /* and increase the length consumed */ - uiLast = uiIndex; /* Record the last entry encoded */ - uiIndex++; /* and get ready for next one */ + uiRemaining -= iTemp; /* Reduce the remaining space */ + iLen += iTemp; /* and increase the length consumed */ + uiLast = uiIndex; /* Record the last entry encoded */ + uiIndex++; /* and get ready for next one */ pRequest->ItemCount++; /* Chalk up another one for the response count */ } /* Set remaining result flags if necessary */ - if (uiFirst == 1) + if (uiFirst == 1) { bitstring_set_bit(&pRequest->ResultFlags, RESULT_FLAG_FIRST_ITEM, true); + } - if (uiLast == CurrentLog->ulRecordCount) + if (uiLast == CurrentLog->ulRecordCount) { bitstring_set_bit(&pRequest->ResultFlags, RESULT_FLAG_LAST_ITEM, true); + } return (iLen); } @@ -1147,15 +1150,15 @@ int TL_encode_by_sequence(uint8_t *apdu, BACNET_READ_RANGE_DATA *pRequest) int32_t iTemp = 0; TL_LOG_INFO *CurrentLog = NULL; - uint32_t uiIndex = 0; /* Current entry number */ - uint32_t uiFirst = 0; /* Entry number we started encoding from */ - uint32_t uiLast = 0; /* Entry number we finished encoding on */ - uint32_t uiSequence = 0; /* Tracking sequenc number when encoding */ + uint32_t uiIndex = 0; /* Current entry number */ + uint32_t uiFirst = 0; /* Entry number we started encoding from */ + uint32_t uiLast = 0; /* Entry number we finished encoding on */ + uint32_t uiSequence = 0; /* Tracking sequenc number when encoding */ uint32_t uiRemaining = 0; /* Amount of unused space in packet */ - uint32_t uiFirstSeq = 0; /* Sequence number for 1st record in log */ + uint32_t uiFirstSeq = 0; /* Sequence number for 1st record in log */ uint32_t uiBegin = 0; /* Starting Sequence number for request */ - uint32_t uiEnd = 0; /* Ending Sequence number for request */ + uint32_t uiEnd = 0; /* Ending Sequence number for request */ bool bWrapReq = false; /* Has request sequence range spanned the max for uint32_t? */ bool bWrapLog = @@ -1179,54 +1182,68 @@ int TL_encode_by_sequence(uint8_t *apdu, BACNET_READ_RANGE_DATA *pRequest) uiEnd = pRequest->Range.RefSeqNum + pRequest->Count - 1; } /* See if we have any wrap around situations */ - if (uiBegin > uiEnd) + if (uiBegin > uiEnd) { bWrapReq = true; - if (uiFirstSeq > CurrentLog->ulTotalRecordCount) + } + if (uiFirstSeq > CurrentLog->ulTotalRecordCount) { bWrapLog = true; + } if ((bWrapReq == false) && (bWrapLog == false)) { /* Simple case no wraps */ /* If no overlap between request range and buffer contents bail out */ - if ((uiEnd < uiFirstSeq) || (uiBegin > CurrentLog->ulTotalRecordCount)) + if ((uiEnd < uiFirstSeq) || + (uiBegin > CurrentLog->ulTotalRecordCount)) { return (0); + } /* Truncate range if necessary so it is guaranteed to lie * between the first and last sequence numbers in the buffer * inclusive. */ - if (uiBegin < uiFirstSeq) + if (uiBegin < uiFirstSeq) { uiBegin = uiFirstSeq; + } - if (uiEnd > CurrentLog->ulTotalRecordCount) + if (uiEnd > CurrentLog->ulTotalRecordCount) { uiEnd = CurrentLog->ulTotalRecordCount; + } } else { /* There are wrap arounds to contend with */ /* First check for non overlap condition as it is common to all */ - if ((uiBegin > CurrentLog->ulTotalRecordCount) && (uiEnd < uiFirstSeq)) + if ((uiBegin > CurrentLog->ulTotalRecordCount) && + (uiEnd < uiFirstSeq)) { return (0); + } if (bWrapLog == false) { /* Only request range wraps */ if (uiEnd < uiFirstSeq) { uiEnd = CurrentLog->ulTotalRecordCount; - if (uiBegin < uiFirstSeq) + if (uiBegin < uiFirstSeq) { uiBegin = uiFirstSeq; + } } else { uiBegin = uiFirstSeq; - if (uiEnd > CurrentLog->ulTotalRecordCount) + if (uiEnd > CurrentLog->ulTotalRecordCount) { uiEnd = CurrentLog->ulTotalRecordCount; + } } } else if (bWrapReq == false) { /* Only log wraps */ if (uiBegin > CurrentLog->ulTotalRecordCount) { - if (uiBegin > uiFirstSeq) + if (uiBegin > uiFirstSeq) { uiBegin = uiFirstSeq; + } } else { - if (uiEnd > CurrentLog->ulTotalRecordCount) + if (uiEnd > CurrentLog->ulTotalRecordCount) { uiEnd = CurrentLog->ulTotalRecordCount; + } } } else { /* Both wrap */ - if (uiBegin < uiFirstSeq) + if (uiBegin < uiFirstSeq) { uiBegin = uiFirstSeq; + } - if (uiEnd > CurrentLog->ulTotalRecordCount) + if (uiEnd > CurrentLog->ulTotalRecordCount) { uiEnd = CurrentLog->ulTotalRecordCount; + } } } @@ -1242,27 +1259,29 @@ int TL_encode_by_sequence(uint8_t *apdu, BACNET_READ_RANGE_DATA *pRequest) * Can't fit any more in! We just set the result flag to say there * was more and drop out of the loop early */ - bitstring_set_bit(&pRequest->ResultFlags, RESULT_FLAG_MORE_ITEMS, - true); + bitstring_set_bit( + &pRequest->ResultFlags, RESULT_FLAG_MORE_ITEMS, true); break; } iTemp = TL_encode_entry(&apdu[iLen], log_index, uiIndex); uiRemaining -= iTemp; /* Reduce the remaining space */ - iLen += iTemp; /* and increase the length consumed */ - uiLast = uiIndex; /* Record the last entry encoded */ - uiIndex++; /* and get ready for next one */ + iLen += iTemp; /* and increase the length consumed */ + uiLast = uiIndex; /* Record the last entry encoded */ + uiIndex++; /* and get ready for next one */ uiSequence++; pRequest->ItemCount++; /* Chalk up another one for the response count */ } /* Set remaining result flags if necessary */ - if (uiFirst == 1) + if (uiFirst == 1) { bitstring_set_bit(&pRequest->ResultFlags, RESULT_FLAG_FIRST_ITEM, true); + } - if (uiLast == CurrentLog->ulRecordCount) + if (uiLast == CurrentLog->ulRecordCount) { bitstring_set_bit(&pRequest->ResultFlags, RESULT_FLAG_LAST_ITEM, true); + } pRequest->FirstSequence = uiBegin; @@ -1284,12 +1303,12 @@ int TL_encode_by_time(uint8_t *apdu, BACNET_READ_RANGE_DATA *pRequest) int iCount = 0; TL_LOG_INFO *CurrentLog = NULL; - uint32_t uiIndex = 0; /* Current entry number */ - uint32_t uiFirst = 0; /* Entry number we started encoding from */ - uint32_t uiLast = 0; /* Entry number we finished encoding on */ + uint32_t uiIndex = 0; /* Current entry number */ + uint32_t uiFirst = 0; /* Entry number we started encoding from */ + uint32_t uiLast = 0; /* Entry number we finished encoding on */ uint32_t uiRemaining = 0; /* Amount of unused space in packet */ - uint32_t uiFirstSeq = 0; /* Sequence number for 1st record in log */ - time_t tRefTime = 0; /* The time from the request in local format */ + uint32_t uiFirstSeq = 0; /* Sequence number for 1st record in log */ + time_t tRefTime = 0; /* The time from the request in local format */ /* See how much space we have */ uiRemaining = MAX_APDU - pRequest->Overhead; @@ -1298,10 +1317,11 @@ int TL_encode_by_time(uint8_t *apdu, BACNET_READ_RANGE_DATA *pRequest) tRefTime = TL_BAC_Time_To_Local(&pRequest->Range.RefTime); /* Find correct position for oldest entry in log */ - if (CurrentLog->ulRecordCount < TL_MAX_ENTRIES) + if (CurrentLog->ulRecordCount < TL_MAX_ENTRIES) { uiIndex = 0; - else + } else { uiIndex = CurrentLog->iIndex; + } if (pRequest->Count < 0) { /* Start at end of log and look for record which has @@ -1313,13 +1333,15 @@ int TL_encode_by_time(uint8_t *apdu, BACNET_READ_RANGE_DATA *pRequest) for (;;) { if (Logs[pRequest->object_instance] [(uiIndex + iCount) % TL_MAX_ENTRIES] - .tTimeStamp < tRefTime) + .tTimeStamp < tRefTime) { break; + } uiFirstSeq--; iCount--; - if (iCount < 0) + if (iCount < 0) { return (0); + } } /* We have an and point for our request, @@ -1353,20 +1375,22 @@ int TL_encode_by_time(uint8_t *apdu, BACNET_READ_RANGE_DATA *pRequest) for (;;) { if (Logs[pRequest->object_instance] [(uiIndex + iCount) % TL_MAX_ENTRIES] - .tTimeStamp > tRefTime) + .tTimeStamp > tRefTime) { break; + } uiFirstSeq++; iCount++; - if ((uint32_t)iCount == CurrentLog->ulRecordCount) + if ((uint32_t)iCount == CurrentLog->ulRecordCount) { return (0); + } } } /* We now have a starting point for the operation and a +ve count */ uiIndex = iCount + 1; /* Convert to BACnet 1 based reference */ - uiFirst = uiIndex; /* Record where we started from */ + uiFirst = uiIndex; /* Record where we started from */ iCount = pRequest->Count; while (iCount != 0) { if (uiRemaining < TL_MAX_ENC) { @@ -1374,32 +1398,35 @@ int TL_encode_by_time(uint8_t *apdu, BACNET_READ_RANGE_DATA *pRequest) * Can't fit any more in! We just set the result flag to say there * was more and drop out of the loop early */ - bitstring_set_bit(&pRequest->ResultFlags, RESULT_FLAG_MORE_ITEMS, - true); + bitstring_set_bit( + &pRequest->ResultFlags, RESULT_FLAG_MORE_ITEMS, true); break; } iTemp = TL_encode_entry(&apdu[iLen], log_index, uiIndex); - uiRemaining -= iTemp; /* Reduce the remaining space */ - iLen += iTemp; /* and increase the length consumed */ - uiLast = uiIndex; /* Record the last entry encoded */ - uiIndex++; /* and get ready for next one */ + uiRemaining -= iTemp; /* Reduce the remaining space */ + iLen += iTemp; /* and increase the length consumed */ + uiLast = uiIndex; /* Record the last entry encoded */ + uiIndex++; /* and get ready for next one */ pRequest->ItemCount++; /* Chalk up another one for the response count */ iCount--; /* And finally cross another one off the requested count */ if (uiIndex > CurrentLog - ->ulRecordCount) /* Finish up if we hit the end of the log */ + ->ulRecordCount) { /* Finish up if we hit the end of the log */ break; + } } /* Set remaining result flags if necessary */ - if (uiFirst == 1) + if (uiFirst == 1) { bitstring_set_bit(&pRequest->ResultFlags, RESULT_FLAG_FIRST_ITEM, true); + } - if (uiLast == CurrentLog->ulRecordCount) + if (uiLast == CurrentLog->ulRecordCount) { bitstring_set_bit(&pRequest->ResultFlags, RESULT_FLAG_LAST_ITEM, true); + } pRequest->FirstSequence = uiFirstSeq; @@ -1417,11 +1444,12 @@ int TL_encode_entry(uint8_t *apdu, int iLog, int iEntry) /* Convert from BACnet 1 based to 0 based array index and then * handle wrap around of the circular buffer */ - if (LogInfo[iLog].ulRecordCount < TL_MAX_ENTRIES) + if (LogInfo[iLog].ulRecordCount < TL_MAX_ENTRIES) { pSource = &Logs[iLog][(iEntry - 1) % TL_MAX_ENTRIES]; - else + } else { pSource = &Logs[iLog][(LogInfo[iLog].iIndex + iEntry - 1) % TL_MAX_ENTRIES]; + } iLen = 0; /* First stick the time stamp in with tag [0] */ @@ -1438,33 +1466,33 @@ int TL_encode_entry(uint8_t *apdu, int iLog, int iEntry) bitstring_init(&TempBits); bitstring_set_bits_used(&TempBits, 1, 5); bitstring_set_octet(&TempBits, 0, pSource->Datum.ucLogStatus); - iLen += encode_context_bitstring(&apdu[iLen], pSource->ucRecType, - &TempBits); + iLen += encode_context_bitstring( + &apdu[iLen], pSource->ucRecType, &TempBits); break; case TL_TYPE_BOOL: - iLen += encode_context_boolean(&apdu[iLen], pSource->ucRecType, - pSource->Datum.ucBoolean); + iLen += encode_context_boolean( + &apdu[iLen], pSource->ucRecType, pSource->Datum.ucBoolean); break; case TL_TYPE_REAL: - iLen += encode_context_real(&apdu[iLen], pSource->ucRecType, - pSource->Datum.fReal); + iLen += encode_context_real( + &apdu[iLen], pSource->ucRecType, pSource->Datum.fReal); break; case TL_TYPE_ENUM: - iLen += encode_context_enumerated(&apdu[iLen], pSource->ucRecType, - pSource->Datum.ulEnum); + iLen += encode_context_enumerated( + &apdu[iLen], pSource->ucRecType, pSource->Datum.ulEnum); break; case TL_TYPE_UNSIGN: - iLen += encode_context_unsigned(&apdu[iLen], pSource->ucRecType, - pSource->Datum.ulUValue); + iLen += encode_context_unsigned( + &apdu[iLen], pSource->ucRecType, pSource->Datum.ulUValue); break; case TL_TYPE_SIGN: - iLen += encode_context_signed(&apdu[iLen], pSource->ucRecType, - pSource->Datum.lSValue); + iLen += encode_context_signed( + &apdu[iLen], pSource->ucRecType, pSource->Datum.lSValue); break; case TL_TYPE_BITS: @@ -1473,15 +1501,16 @@ int TL_encode_entry(uint8_t *apdu, int iLog, int iEntry) */ bitstring_init(&TempBits); bitstring_set_bits_used(&TempBits, - (pSource->Datum.Bits.ucLen >> 4) & 0x0F, - pSource->Datum.Bits.ucLen & 0x0F); + (pSource->Datum.Bits.ucLen >> 4) & 0x0F, + pSource->Datum.Bits.ucLen & 0x0F); for (ucCount = pSource->Datum.Bits.ucLen >> 4; ucCount > 0; - ucCount--) + ucCount--) { bitstring_set_octet(&TempBits, ucCount - 1, - pSource->Datum.Bits.ucStore[ucCount - 1]); + pSource->Datum.Bits.ucStore[ucCount - 1]); + } - iLen += encode_context_bitstring(&apdu[iLen], pSource->ucRecType, - &TempBits); + iLen += encode_context_bitstring( + &apdu[iLen], pSource->ucRecType, &TempBits); break; case TL_TYPE_NULL: @@ -1490,16 +1519,16 @@ int TL_encode_entry(uint8_t *apdu, int iLog, int iEntry) case TL_TYPE_ERROR: iLen += encode_opening_tag(&apdu[iLen], TL_TYPE_ERROR); - iLen += encode_application_enumerated(&apdu[iLen], - pSource->Datum.Error.usClass); - iLen += encode_application_enumerated(&apdu[iLen], - pSource->Datum.Error.usCode); + iLen += encode_application_enumerated( + &apdu[iLen], pSource->Datum.Error.usClass); + iLen += encode_application_enumerated( + &apdu[iLen], pSource->Datum.Error.usCode); iLen += encode_closing_tag(&apdu[iLen], TL_TYPE_ERROR); break; case TL_TYPE_DELTA: - iLen += encode_context_real(&apdu[iLen], pSource->ucRecType, - pSource->Datum.fTime); + iLen += encode_context_real( + &apdu[iLen], pSource->ucRecType, pSource->Datum.fTime); break; case TL_TYPE_ANY: @@ -1520,10 +1549,11 @@ int TL_encode_entry(uint8_t *apdu, int iLog, int iEntry) return (iLen); } -static int local_read_property(uint8_t *value, uint8_t *status, - BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE *Source, - BACNET_ERROR_CLASS *error_class, - BACNET_ERROR_CODE *error_code) +static int local_read_property(uint8_t *value, + uint8_t *status, + BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE *Source, + BACNET_ERROR_CLASS *error_class, + BACNET_ERROR_CODE *error_code) { int len = 0; BACNET_READ_PROPERTY_DATA rpdata; @@ -1588,8 +1618,8 @@ static void TL_fetch_property(int iLog) CurrentLog->tLastDataTime = TempRec.tTimeStamp; TempRec.ucStatus = 0; - iLen = local_read_property(ValueBuf, StatusBuf, &LogInfo[iLog].Source, - &error_class, &error_code); + iLen = local_read_property( + ValueBuf, StatusBuf, &LogInfo[iLog].Source, &error_class, &error_code); if (iLen < 0) { /* Insert error code into log */ TempRec.Datum.Error.usClass = error_class; @@ -1611,20 +1641,20 @@ static void TL_fetch_property(int iLog) case BACNET_APPLICATION_TAG_UNSIGNED_INT: TempRec.ucRecType = TL_TYPE_UNSIGN; - decode_unsigned(&ValueBuf[iLen], len_value_type, - &TempRec.Datum.ulUValue); + decode_unsigned( + &ValueBuf[iLen], len_value_type, &TempRec.Datum.ulUValue); break; case BACNET_APPLICATION_TAG_SIGNED_INT: TempRec.ucRecType = TL_TYPE_SIGN; - decode_signed(&ValueBuf[iLen], len_value_type, - &TempRec.Datum.lSValue); + decode_signed( + &ValueBuf[iLen], len_value_type, &TempRec.Datum.lSValue); break; case BACNET_APPLICATION_TAG_REAL: TempRec.ucRecType = TL_TYPE_REAL; - decode_real_safe(&ValueBuf[iLen], len_value_type, - &TempRec.Datum.fReal); + decode_real_safe( + &ValueBuf[iLen], len_value_type, &TempRec.Datum.fReal); break; case BACNET_APPLICATION_TAG_BIT_STRING: @@ -1635,27 +1665,29 @@ static void TL_fetch_property(int iLog) /* Store the bytes used and the bits free in the last byte */ TempRec.Datum.Bits.ucLen = bitstring_bytes_used(&TempBits) - << 4; + << 4; TempRec.Datum.Bits.ucLen |= (8 - (bitstring_bits_used(&TempBits) % 8)) & 7; /* Fetch the octets with the bits directly */ for (ucCount = 0; ucCount < bitstring_bytes_used(&TempBits); - ucCount++) + ucCount++) { TempRec.Datum.Bits.ucStore[ucCount] = bitstring_octet(&TempBits, ucCount); + } } else { /* We will only use the first 4 octets to save space */ TempRec.Datum.Bits.ucLen = 4 << 4; - for (ucCount = 0; ucCount < 4; ucCount++) + for (ucCount = 0; ucCount < 4; ucCount++) { TempRec.Datum.Bits.ucStore[ucCount] = bitstring_octet(&TempBits, ucCount); + } } break; case BACNET_APPLICATION_TAG_ENUMERATED: TempRec.ucRecType = TL_TYPE_ENUM; - decode_enumerated(&ValueBuf[iLen], len_value_type, - &TempRec.Datum.ulEnum); + decode_enumerated( + &ValueBuf[iLen], len_value_type, &TempRec.Datum.ulEnum); break; default: @@ -1666,20 +1698,22 @@ static void TL_fetch_property(int iLog) break; } /* Finally insert the status flags into the record */ - iLen = decode_tag_number_and_value(StatusBuf, &tag_number, - &len_value_type); + iLen = decode_tag_number_and_value( + StatusBuf, &tag_number, &len_value_type); decode_bitstring(&StatusBuf[iLen], len_value_type, &TempBits); TempRec.ucStatus = 128 | bitstring_octet(&TempBits, 0); } Logs[iLog][CurrentLog->iIndex++] = TempRec; - if (CurrentLog->iIndex >= TL_MAX_ENTRIES) + if (CurrentLog->iIndex >= TL_MAX_ENTRIES) { CurrentLog->iIndex = 0; + } CurrentLog->ulTotalRecordCount++; - if (CurrentLog->ulRecordCount < TL_MAX_ENTRIES) + if (CurrentLog->ulRecordCount < TL_MAX_ENTRIES) { CurrentLog->ulRecordCount++; + } } /**************************************************************************** @@ -1717,13 +1751,13 @@ void trend_log_timer(uint16_t uSeconds) * CurrentLog->ulLogInterval)) { */ if ((tNow % CurrentLog->ulLogInterval) == (CurrentLog->ulIntervalOffset % - CurrentLog->ulLogInterval)) { + CurrentLog->ulLogInterval)) { /* Record value if time synchronised trigger condition * is met and at least one period has elapsed. */ TL_fetch_property(iCount); } else if ((tNow - CurrentLog->tLastDataTime) > - CurrentLog->ulLogInterval) { + CurrentLog->ulLogInterval) { /* Also record value if we have waited more than a * period since the last reading. This ensures we take a * reading as soon as possible after a power down if we @@ -1732,8 +1766,8 @@ void trend_log_timer(uint16_t uSeconds) TL_fetch_property(iCount); } } else if (((tNow - CurrentLog->tLastDataTime) >= - CurrentLog->ulLogInterval) || - (CurrentLog->bTrigger == true)) { + CurrentLog->ulLogInterval) || + (CurrentLog->bTrigger == true)) { /* If not aligned take a reading when we have either waited * long enough or a trigger is set. */ diff --git a/demo/object/trendlog.h b/src/bacnet/basic/object/trendlog.h similarity index 98% rename from demo/object/trendlog.h rename to src/bacnet/basic/object/trendlog.h index b2d16659..cef76c1a 100644 --- a/demo/object/trendlog.h +++ b/src/bacnet/basic/object/trendlog.h @@ -28,10 +28,10 @@ #include #include #include /* for time_t */ -#include "bacdef.h" -#include "cov.h" -#include "rp.h" -#include "wp.h" +#include "bacnet/bacdef.h" +#include "bacnet/cov.h" +#include "bacnet/rp.h" +#include "bacnet/wp.h" #ifdef __cplusplus extern "C" { diff --git a/demo/handler/h_alarm_ack.c b/src/bacnet/basic/service/h_alarm_ack.c similarity index 64% rename from demo/handler/h_alarm_ack.c rename to src/bacnet/basic/service/h_alarm_ack.c index 6f96a696..18ac0619 100644 --- a/demo/handler/h_alarm_ack.c +++ b/src/bacnet/basic/service/h_alarm_ack.c @@ -29,25 +29,27 @@ #include #include -#include "config.h" -#include "txbuf.h" -#include "bacdef.h" -#include "bacdcode.h" -#include "bacerror.h" -#include "bactext.h" -#include "apdu.h" -#include "npdu.h" -#include "abort.h" -#include "alarm_ack.h" -#include "handlers.h" -#include "device.h" +#include "bacnet/config.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacerror.h" +#include "bacnet/bactext.h" +#include "bacnet/apdu.h" +#include "bacnet/npdu.h" +#include "bacnet/abort.h" +#include "bacnet/alarm_ack.h" +/* basic objects, services, TSM, and datalink */ +#include "bacnet/basic/object/device.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/basic/services.h" +#include "bacnet/datalink/datalink.h" /** @file h_alarm_ack.c Handles Alarm Acknowledgment. */ static alarm_ack_function Alarm_Ack[MAX_BACNET_OBJECT_TYPE]; -void handler_alarm_ack_set(BACNET_OBJECT_TYPE object_type, - alarm_ack_function pFunction) +void handler_alarm_ack_set( + BACNET_OBJECT_TYPE object_type, alarm_ack_function pFunction) { if (object_type < MAX_BACNET_OBJECT_TYPE) { Alarm_Ack[object_type] = pFunction; @@ -70,9 +72,10 @@ void handler_alarm_ack_set(BACNET_OBJECT_TYPE object_type, * @param service_data [in] The BACNET_CONFIRMED_SERVICE_DATA information * decoded from the APDU header of this message. */ -void handler_alarm_ack(uint8_t* service_request, uint16_t service_len, - BACNET_ADDRESS* src, - BACNET_CONFIRMED_SERVICE_DATA* service_data) +void handler_alarm_ack(uint8_t *service_request, + uint16_t service_len, + BACNET_ADDRESS *src, + BACNET_CONFIRMED_SERVICE_DATA *service_data) { int len = 0; int pdu_len = 0; @@ -86,13 +89,13 @@ void handler_alarm_ack(uint8_t* service_request, uint16_t service_len, /* encode the NPDU portion of the packet */ datalink_get_my_address(&my_address); npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL); - pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address, - &npdu_data); + pdu_len = npdu_encode_pdu( + &Handler_Transmit_Buffer[0], src, &my_address, &npdu_data); if (service_data->segmented_message) { /* we don't support segmentation - send an abort */ len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], - service_data->invoke_id, - ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true); + service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, + true); #if PRINT_ENABLED fprintf(stderr, "Alarm Ack: Segmented message. Sending Abort!\n"); #endif @@ -107,8 +110,7 @@ void handler_alarm_ack(uint8_t* service_request, uint16_t service_len, if (len < 0) { /* bad decoding - send an abort */ len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], - service_data->invoke_id, ABORT_REASON_OTHER, - true); + service_data->invoke_id, ABORT_REASON_OTHER, true); #if PRINT_ENABLED fprintf(stderr, "Alarm Ack: Bad Encoding. Sending Abort!\n"); #endif @@ -116,11 +118,11 @@ void handler_alarm_ack(uint8_t* service_request, uint16_t service_len, } #if PRINT_ENABLED fprintf(stderr, - "Alarm Ack Operation: Received acknowledge for object id (%d, %lu) " - "from %s for process id %lu \n", - data.eventObjectIdentifier.type, - (unsigned long)data.eventObjectIdentifier.instance, - data.ackSource.value, (unsigned long)data.ackProcessIdentifier); + "Alarm Ack Operation: Received acknowledge for object id (%d, %lu) " + "from %s for process id %lu \n", + data.eventObjectIdentifier.type, + (unsigned long)data.eventObjectIdentifier.instance, + data.ackSource.value, (unsigned long)data.ackProcessIdentifier); #endif /* BACnet Testing Observed Incident oi00105 @@ -129,11 +131,10 @@ void handler_alarm_ack(uint8_t* service_request, uint16_t service_len, www.bac-test.com/bacnet-test-client-download ) BC 135.1: 9.1.3.3-A Any discussions can be directed to edward@bac-test.com */ if (!Device_Valid_Object_Id(data.eventObjectIdentifier.type, - data.eventObjectIdentifier.instance)) { - len = bacerror_encode_apdu( - &Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, - SERVICE_CONFIRMED_ACKNOWLEDGE_ALARM, ERROR_CLASS_OBJECT, - ERROR_CODE_UNKNOWN_OBJECT); + data.eventObjectIdentifier.instance)) { + len = bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], + service_data->invoke_id, SERVICE_CONFIRMED_ACKNOWLEDGE_ALARM, + ERROR_CLASS_OBJECT, ERROR_CODE_UNKNOWN_OBJECT); } else if (Alarm_Ack[data.eventObjectIdentifier.type]) { ack_result = Alarm_Ack[data.eventObjectIdentifier.type](&data, &error_code); @@ -141,56 +142,54 @@ void handler_alarm_ack(uint8_t* service_request, uint16_t service_len, switch (ack_result) { case 1: len = encode_simple_ack(&Handler_Transmit_Buffer[pdu_len], - service_data->invoke_id, - SERVICE_CONFIRMED_ACKNOWLEDGE_ALARM); + service_data->invoke_id, + SERVICE_CONFIRMED_ACKNOWLEDGE_ALARM); #if PRINT_ENABLED fprintf(stderr, - "Alarm Acknowledge: " - "Sending Simple Ack!\n"); + "Alarm Acknowledge: " + "Sending Simple Ack!\n"); #endif break; case -1: len = bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], - service_data->invoke_id, - SERVICE_CONFIRMED_ACKNOWLEDGE_ALARM, - ERROR_CLASS_OBJECT, error_code); + service_data->invoke_id, + SERVICE_CONFIRMED_ACKNOWLEDGE_ALARM, ERROR_CLASS_OBJECT, + error_code); #if PRINT_ENABLED fprintf(stderr, "Alarm Acknowledge: error %s!\n", - bactext_error_code_name(error_code)); + bactext_error_code_name(error_code)); #endif break; default: len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], - service_data->invoke_id, - ABORT_REASON_OTHER, true); + service_data->invoke_id, ABORT_REASON_OTHER, true); #if PRINT_ENABLED fprintf(stderr, "Alarm Acknowledge: abort other!\n"); #endif break; } } else { - len = bacerror_encode_apdu( - &Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, - SERVICE_CONFIRMED_ACKNOWLEDGE_ALARM, ERROR_CLASS_OBJECT, - ERROR_CODE_NO_ALARM_CONFIGURED); + len = bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], + service_data->invoke_id, SERVICE_CONFIRMED_ACKNOWLEDGE_ALARM, + ERROR_CLASS_OBJECT, ERROR_CODE_NO_ALARM_CONFIGURED); #if PRINT_ENABLED fprintf(stderr, "Alarm Acknowledge: error %s!\n", - bactext_error_code_name(ERROR_CODE_NO_ALARM_CONFIGURED)); + bactext_error_code_name(ERROR_CODE_NO_ALARM_CONFIGURED)); #endif } AA_ABORT: pdu_len += len; - bytes_sent = datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0], - pdu_len); + bytes_sent = datalink_send_pdu( + src, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len); #if PRINT_ENABLED if (bytes_sent <= 0) fprintf(stderr, - "Alarm Acknowledge: " - "Failed to send PDU (%s)!\n", - strerror(errno)); + "Alarm Acknowledge: " + "Failed to send PDU (%s)!\n", + strerror(errno)); #endif return; diff --git a/src/bacnet/basic/service/h_alarm_ack.h b/src/bacnet/basic/service/h_alarm_ack.h new file mode 100644 index 00000000..f2c35ca3 --- /dev/null +++ b/src/bacnet/basic/service/h_alarm_ack.h @@ -0,0 +1,55 @@ +/** +* @file +* @author Steve Karg +* @date 2019 +* @brief Header file a basic Alarm Acknowledgment Handler +* +* @section LICENSE +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +#ifndef HANDLER_ALARM_ACK_H +#define HANDLER_ALARM_ACK_H + +#include +#include +#include "bacnet/bacdef.h" +#include "bacnet/bacenum.h" +#include "bacnet/apdu.h" +#include "bacnet/alarm_ack.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + void handler_alarm_ack( + uint8_t * service_request, + uint16_t service_len, + BACNET_ADDRESS * src, + BACNET_CONFIRMED_SERVICE_DATA * service_data); + + void handler_alarm_ack_set( + BACNET_OBJECT_TYPE object_type, + alarm_ack_function pFunction); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/src/apdu.c b/src/bacnet/basic/service/h_apdu.c similarity index 82% rename from src/apdu.c rename to src/bacnet/basic/service/h_apdu.c index ef3bfe4f..0027bf2b 100644 --- a/src/apdu.c +++ b/src/bacnet/basic/service/h_apdu.c @@ -34,21 +34,24 @@ #include #include #include -#include "bits.h" -#include "apdu.h" -#include "bacdef.h" -#include "bacdcode.h" -#include "bacenum.h" -#include "tsm.h" -#include "dcc.h" -#include "iam.h" +#include "bacnet/bits.h" +#include "bacnet/apdu.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacenum.h" +#include "bacnet/dcc.h" +#include "bacnet/iam.h" +/* basic objects, services, TSM */ +#include "bacnet/basic/object/device.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/basic/services.h" /** @file apdu.c Handles APDU services */ extern int Routed_Device_Service_Approval(BACNET_CONFIRMED_SERVICE service, - int service_argument, - uint8_t *apdu_buff, - uint8_t invoke_id); + int service_argument, + uint8_t *apdu_buff, + uint8_t invoke_id); /* APDU Timeout in Milliseconds */ static uint16_t Timeout_Milliseconds = 3000; @@ -63,55 +66,45 @@ static BACNET_SERVICES_SUPPORTED SERVICE_SUPPORTED_CONFIRMED_EVENT_NOTIFICATION, SERVICE_SUPPORTED_GET_ALARM_SUMMARY, SERVICE_SUPPORTED_GET_ENROLLMENT_SUMMARY, - SERVICE_SUPPORTED_SUBSCRIBE_COV, - SERVICE_SUPPORTED_ATOMIC_READ_FILE, - SERVICE_SUPPORTED_ATOMIC_WRITE_FILE, - SERVICE_SUPPORTED_ADD_LIST_ELEMENT, - SERVICE_SUPPORTED_REMOVE_LIST_ELEMENT, - SERVICE_SUPPORTED_CREATE_OBJECT, - SERVICE_SUPPORTED_DELETE_OBJECT, - SERVICE_SUPPORTED_READ_PROPERTY, + SERVICE_SUPPORTED_SUBSCRIBE_COV, SERVICE_SUPPORTED_ATOMIC_READ_FILE, + SERVICE_SUPPORTED_ATOMIC_WRITE_FILE, SERVICE_SUPPORTED_ADD_LIST_ELEMENT, + SERVICE_SUPPORTED_REMOVE_LIST_ELEMENT, SERVICE_SUPPORTED_CREATE_OBJECT, + SERVICE_SUPPORTED_DELETE_OBJECT, SERVICE_SUPPORTED_READ_PROPERTY, SERVICE_SUPPORTED_READ_PROP_CONDITIONAL, - SERVICE_SUPPORTED_READ_PROP_MULTIPLE, - SERVICE_SUPPORTED_WRITE_PROPERTY, + SERVICE_SUPPORTED_READ_PROP_MULTIPLE, SERVICE_SUPPORTED_WRITE_PROPERTY, SERVICE_SUPPORTED_WRITE_PROP_MULTIPLE, SERVICE_SUPPORTED_DEVICE_COMMUNICATION_CONTROL, - SERVICE_SUPPORTED_PRIVATE_TRANSFER, - SERVICE_SUPPORTED_TEXT_MESSAGE, - SERVICE_SUPPORTED_REINITIALIZE_DEVICE, - SERVICE_SUPPORTED_VT_OPEN, - SERVICE_SUPPORTED_VT_CLOSE, - SERVICE_SUPPORTED_VT_DATA, - SERVICE_SUPPORTED_AUTHENTICATE, - SERVICE_SUPPORTED_REQUEST_KEY, - SERVICE_SUPPORTED_READ_RANGE, - SERVICE_SUPPORTED_LIFE_SAFETY_OPERATION, + SERVICE_SUPPORTED_PRIVATE_TRANSFER, SERVICE_SUPPORTED_TEXT_MESSAGE, + SERVICE_SUPPORTED_REINITIALIZE_DEVICE, SERVICE_SUPPORTED_VT_OPEN, + SERVICE_SUPPORTED_VT_CLOSE, SERVICE_SUPPORTED_VT_DATA, + SERVICE_SUPPORTED_AUTHENTICATE, SERVICE_SUPPORTED_REQUEST_KEY, + SERVICE_SUPPORTED_READ_RANGE, SERVICE_SUPPORTED_LIFE_SAFETY_OPERATION, SERVICE_SUPPORTED_SUBSCRIBE_COV_PROPERTY, - SERVICE_SUPPORTED_GET_EVENT_INFORMATION}; + SERVICE_SUPPORTED_GET_EVENT_INFORMATION + }; /* a simple table for crossing the services supported */ static BACNET_SERVICES_SUPPORTED unconfirmed_service_supported[MAX_BACNET_UNCONFIRMED_SERVICE] = { - SERVICE_SUPPORTED_I_AM, - SERVICE_SUPPORTED_I_HAVE, + SERVICE_SUPPORTED_I_AM, SERVICE_SUPPORTED_I_HAVE, SERVICE_SUPPORTED_UNCONFIRMED_COV_NOTIFICATION, SERVICE_SUPPORTED_UNCONFIRMED_EVENT_NOTIFICATION, SERVICE_SUPPORTED_UNCONFIRMED_PRIVATE_TRANSFER, SERVICE_SUPPORTED_UNCONFIRMED_TEXT_MESSAGE, - SERVICE_SUPPORTED_TIME_SYNCHRONIZATION, - SERVICE_SUPPORTED_WHO_HAS, - SERVICE_SUPPORTED_WHO_IS, - SERVICE_SUPPORTED_UTC_TIME_SYNCHRONIZATION}; + SERVICE_SUPPORTED_TIME_SYNCHRONIZATION, SERVICE_SUPPORTED_WHO_HAS, + SERVICE_SUPPORTED_WHO_IS, SERVICE_SUPPORTED_UTC_TIME_SYNCHRONIZATION + }; /* Confirmed Function Handlers */ /* If they are not set, they are handled by a reject message */ static confirmed_function Confirmed_Function[MAX_BACNET_CONFIRMED_SERVICE]; -void apdu_set_confirmed_handler(BACNET_CONFIRMED_SERVICE service_choice, - confirmed_function pFunction) +void apdu_set_confirmed_handler( + BACNET_CONFIRMED_SERVICE service_choice, confirmed_function pFunction) { - if (service_choice < MAX_BACNET_CONFIRMED_SERVICE) + if (service_choice < MAX_BACNET_CONFIRMED_SERVICE) { Confirmed_Function[service_choice] = pFunction; + } } /* Allow the APDU handler to automatically reject */ @@ -127,11 +120,12 @@ void apdu_set_unrecognized_service_handler_handler(confirmed_function pFunction) static unconfirmed_function Unconfirmed_Function[MAX_BACNET_UNCONFIRMED_SERVICE]; -void apdu_set_unconfirmed_handler(BACNET_UNCONFIRMED_SERVICE service_choice, - unconfirmed_function pFunction) +void apdu_set_unconfirmed_handler( + BACNET_UNCONFIRMED_SERVICE service_choice, unconfirmed_function pFunction) { - if (service_choice < MAX_BACNET_UNCONFIRMED_SERVICE) + if (service_choice < MAX_BACNET_UNCONFIRMED_SERVICE) { Unconfirmed_Function[service_choice] = pFunction; + } } bool apdu_service_supported(BACNET_SERVICES_SUPPORTED service_supported) @@ -149,8 +143,8 @@ bool apdu_service_supported(BACNET_SERVICES_SUPPORTED service_supported) #if BAC_ROUTING /* Check to see if the current Device supports this service. */ - int len = Routed_Device_Service_Approval(service_supported, - 0, NULL, 0); + int len = Routed_Device_Service_Approval( + service_supported, 0, NULL, 0); if (len > 0) break; /* Not supported - return false */ #endif @@ -165,8 +159,9 @@ bool apdu_service_supported(BACNET_SERVICES_SUPPORTED service_supported) /* is it an unconfirmed service? */ for (i = 0; i < MAX_BACNET_UNCONFIRMED_SERVICE; i++) { if (unconfirmed_service_supported[i] == service_supported) { - if (Unconfirmed_Function[i] != NULL) + if (Unconfirmed_Function[i] != NULL) { status = true; + } break; } } @@ -186,7 +181,8 @@ bool apdu_service_supported(BACNET_SERVICES_SUPPORTED service_supported) * @return True if a match was found and index and bIsConfirmed are valid. */ bool apdu_service_supported_to_index( - BACNET_SERVICES_SUPPORTED service_supported, size_t *index, + BACNET_SERVICES_SUPPORTED service_supported, + size_t *index, bool *bIsConfirmed) { int i = 0; @@ -255,8 +251,8 @@ void apdu_set_confirmed_simple_ack_handler( } } -void apdu_set_confirmed_ack_handler(BACNET_CONFIRMED_SERVICE service_choice, - confirmed_ack_function pFunction) +void apdu_set_confirmed_ack_handler( + BACNET_CONFIRMED_SERVICE service_choice, confirmed_ack_function pFunction) { switch (service_choice) { case SERVICE_CONFIRMED_GET_ALARM_SUMMARY: @@ -287,11 +283,12 @@ void apdu_set_confirmed_ack_handler(BACNET_CONFIRMED_SERVICE service_choice, static error_function Error_Function[MAX_BACNET_CONFIRMED_SERVICE]; -void apdu_set_error_handler(BACNET_CONFIRMED_SERVICE service_choice, - error_function pFunction) +void apdu_set_error_handler( + BACNET_CONFIRMED_SERVICE service_choice, error_function pFunction) { - if (service_choice < MAX_BACNET_CONFIRMED_SERVICE) + if (service_choice < MAX_BACNET_CONFIRMED_SERVICE) { Error_Function[service_choice] = pFunction; + } } static abort_function Abort_Function; @@ -308,10 +305,11 @@ void apdu_set_reject_handler(reject_function pFunction) Reject_Function = pFunction; } -uint16_t apdu_decode_confirmed_service_request( - uint8_t *apdu, /* APDU data */ - uint16_t apdu_len, BACNET_CONFIRMED_SERVICE_DATA *service_data, - uint8_t *service_choice, uint8_t **service_request, +uint16_t apdu_decode_confirmed_service_request(uint8_t *apdu, /* APDU data */ + uint16_t apdu_len, + BACNET_CONFIRMED_SERVICE_DATA *service_data, + uint8_t *service_choice, + uint8_t **service_request, uint16_t *service_request_len) { uint16_t len = 0; /* counts where we are in PDU */ @@ -417,11 +415,12 @@ static bool apdu_unconfirmed_dcc_disabled(uint8_t service_choice) * @param apdu [in] The apdu portion of the request, to be processed. * @param apdu_len [in] The total (remaining) length of the apdu. */ -void apdu_handler(BACNET_ADDRESS *src, uint8_t *apdu, /* APDU data */ - uint16_t apdu_len) +void apdu_handler(BACNET_ADDRESS *src, + uint8_t *apdu, /* APDU data */ + uint16_t apdu_len) { - BACNET_CONFIRMED_SERVICE_DATA service_data = {0}; - BACNET_CONFIRMED_SERVICE_ACK_DATA service_ack_data = {0}; + BACNET_CONFIRMED_SERVICE_DATA service_data = { 0 }; + BACNET_CONFIRMED_SERVICE_ACK_DATA service_ack_data = { 0 }; uint8_t invoke_id = 0; uint8_t service_choice = 0; uint8_t *service_request = NULL; @@ -438,9 +437,9 @@ void apdu_handler(BACNET_ADDRESS *src, uint8_t *apdu, /* APDU data */ /* PDU Type */ switch (apdu[0] & 0xF0) { case PDU_TYPE_CONFIRMED_SERVICE_REQUEST: - (void)apdu_decode_confirmed_service_request( - &apdu[0], apdu_len, &service_data, &service_choice, - &service_request, &service_request_len); + (void)apdu_decode_confirmed_service_request(&apdu[0], apdu_len, + &service_data, &service_choice, &service_request, + &service_request_len); if (apdu_confirmed_dcc_disabled(service_choice)) { /* When network communications are completely disabled, only DeviceCommunicationControl and ReinitializeDevice @@ -449,14 +448,13 @@ void apdu_handler(BACNET_ADDRESS *src, uint8_t *apdu, /* APDU data */ break; } if ((service_choice < MAX_BACNET_CONFIRMED_SERVICE) && - (Confirmed_Function[service_choice])) + (Confirmed_Function[service_choice])) { Confirmed_Function[service_choice](service_request, - service_request_len, src, - &service_data); - else if (Unrecognized_Service_Handler) + service_request_len, src, &service_data); + } else if (Unrecognized_Service_Handler) { Unrecognized_Service_Handler(service_request, - service_request_len, src, - &service_data); + service_request_len, src, &service_data); + } break; case PDU_TYPE_UNCONFIRMED_SERVICE_REQUEST: service_choice = apdu[1]; @@ -471,9 +469,10 @@ void apdu_handler(BACNET_ADDRESS *src, uint8_t *apdu, /* APDU data */ break; } if (service_choice < MAX_BACNET_UNCONFIRMED_SERVICE) { - if (Unconfirmed_Function[service_choice]) + if (Unconfirmed_Function[service_choice]) { Unconfirmed_Function[service_choice]( service_request, service_request_len, src); + } } break; case PDU_TYPE_SIMPLE_ACK: @@ -502,7 +501,7 @@ void apdu_handler(BACNET_ADDRESS *src, uint8_t *apdu, /* APDU data */ case SERVICE_CONFIRMED_REQUEST_KEY: if (Confirmed_ACK_Function[service_choice] != NULL) { ((confirmed_simple_ack_function) - Confirmed_ACK_Function[service_choice])( + Confirmed_ACK_Function[service_choice])( src, invoke_id); } tsm_free_invoke_id(invoke_id); @@ -572,51 +571,54 @@ void apdu_handler(BACNET_ADDRESS *src, uint8_t *apdu, /* APDU data */ support for these services is added */ if (service_choice == - SERVICE_CONFIRMED_PRIVATE_TRANSFER) { /* skip over opening - tag 0 */ + SERVICE_CONFIRMED_PRIVATE_TRANSFER) { /* skip over + opening tag 0 */ if (decode_is_opening_tag_number(&apdu[len], 0)) { len++; /* a tag number of 0 is not extended so only one octet */ } } - len += decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value); + len += decode_tag_number_and_value( + &apdu[len], &tag_number, &len_value); /* FIXME: we could validate that the tag is enumerated... */ len += decode_enumerated(&apdu[len], len_value, &error_class); - len += decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value); + len += decode_tag_number_and_value( + &apdu[len], &tag_number, &len_value); /* FIXME: we could validate that the tag is enumerated... */ len += decode_enumerated(&apdu[len], len_value, &error_code); if (service_choice == - SERVICE_CONFIRMED_PRIVATE_TRANSFER) { /* skip over closing - tag 0 */ + SERVICE_CONFIRMED_PRIVATE_TRANSFER) { /* skip over + closing tag 0 */ if (decode_is_closing_tag_number(&apdu[len], 0)) { len++; /* a tag number of 0 is not extended so only one octet */ } } if (service_choice < MAX_BACNET_CONFIRMED_SERVICE) { - if (Error_Function[service_choice]) - Error_Function[service_choice]( - src, invoke_id, (BACNET_ERROR_CLASS)error_class, + if (Error_Function[service_choice]) { + Error_Function[service_choice](src, invoke_id, + (BACNET_ERROR_CLASS)error_class, (BACNET_ERROR_CODE)error_code); + } } tsm_free_invoke_id(invoke_id); break; case PDU_TYPE_REJECT: invoke_id = apdu[1]; reason = apdu[2]; - if (Reject_Function) + if (Reject_Function) { Reject_Function(src, invoke_id, reason); + } tsm_free_invoke_id(invoke_id); break; case PDU_TYPE_ABORT: server = apdu[0] & 0x01; invoke_id = apdu[1]; reason = apdu[2]; - if (Abort_Function) + if (Abort_Function) { Abort_Function(src, invoke_id, reason, server); + } tsm_free_invoke_id(invoke_id); break; default: diff --git a/include/apdu.h b/src/bacnet/basic/service/h_apdu.h similarity index 87% rename from include/apdu.h rename to src/bacnet/basic/service/h_apdu.h index b59d8fac..25aa048c 100644 --- a/include/apdu.h +++ b/src/bacnet/basic/service/h_apdu.h @@ -1,6 +1,10 @@ -/************************************************************************** +/** +* @file +* @author Steve Karg +* @date 2019 +* @brief Header file for a basic APDU Handler * -* Copyright (C) 2012 Steve Karg +* @section LICENSE * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the @@ -20,33 +24,15 @@ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*********************************************************************/ -#ifndef APDU_H -#define APDU_H +*/ +#ifndef BACNET_APDU_HANDLER_H +#define BACNET_APDU_HANDLER_H #include #include -#include "bacdef.h" -#include "bacenum.h" - -typedef struct _confirmed_service_data { - bool segmented_message; - bool more_follows; - bool segmented_response_accepted; - int max_segs; - int max_resp; - uint8_t invoke_id; - uint8_t sequence_number; - uint8_t proposed_window_number; -} BACNET_CONFIRMED_SERVICE_DATA; - -typedef struct _confirmed_service_ack_data { - bool segmented_message; - bool more_follows; - uint8_t invoke_id; - uint8_t sequence_number; - uint8_t proposed_window_number; -} BACNET_CONFIRMED_SERVICE_ACK_DATA; +#include "bacnet/bacdef.h" +#include "bacnet/bacenum.h" +#include "bacnet/apdu.h" #ifdef __cplusplus extern "C" { diff --git a/demo/handler/h_arf.c b/src/bacnet/basic/service/h_arf.c similarity index 80% rename from demo/handler/h_arf.c rename to src/bacnet/basic/service/h_arf.c index 65830ba6..27c94e17 100644 --- a/demo/handler/h_arf.c +++ b/src/bacnet/basic/service/h_arf.c @@ -27,20 +27,21 @@ #include #include #include -#include "config.h" -#include "txbuf.h" -#include "bacdef.h" -#include "bacerror.h" -#include "bacdcode.h" -#include "apdu.h" -#include "npdu.h" -#include "abort.h" -#include "arf.h" -/* demo objects */ +#include "bacnet/config.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacerror.h" +#include "bacnet/bacdcode.h" +#include "bacnet/apdu.h" +#include "bacnet/npdu.h" +#include "bacnet/abort.h" +#include "bacnet/arf.h" +/* basic objects, services, TSM, and datalink */ #if defined(BACFILE) -#include "bacfile.h" +#include "bacnet/basic/object/bacfile.h" #endif -#include "handlers.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/basic/services.h" +#include "bacnet/datalink/datalink.h" /** @file h_arf.c Handles Atomic Read File request. */ @@ -96,9 +97,10 @@ shall be TRUE, otherwise FALSE. */ #if defined(BACFILE) -void handler_atomic_read_file(uint8_t* service_request, uint16_t service_len, - BACNET_ADDRESS* src, - BACNET_CONFIRMED_SERVICE_DATA* service_data) +void handler_atomic_read_file(uint8_t *service_request, + uint16_t service_len, + BACNET_ADDRESS *src, + BACNET_CONFIRMED_SERVICE_DATA *service_data) { BACNET_ATOMIC_READ_FILE_DATA data; int len = 0; @@ -116,12 +118,12 @@ void handler_atomic_read_file(uint8_t* service_request, uint16_t service_len, /* encode the NPDU portion of the packet */ datalink_get_my_address(&my_address); npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL); - pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address, - &npdu_data); + pdu_len = npdu_encode_pdu( + &Handler_Transmit_Buffer[0], src, &my_address, &npdu_data); if (service_data->segmented_message) { len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], - service_data->invoke_id, - ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true); + service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, + true); #if PRINT_ENABLED fprintf(stderr, "ARF: Segmented Message. Sending Abort!\n"); #endif @@ -131,8 +133,7 @@ void handler_atomic_read_file(uint8_t* service_request, uint16_t service_len, /* bad decoding - send an abort */ if (len < 0) { len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], - service_data->invoke_id, ABORT_REASON_OTHER, - true); + service_data->invoke_id, ABORT_REASON_OTHER, true); #if PRINT_ENABLED fprintf(stderr, "Bad Encoding. Sending Abort!\n"); #endif @@ -147,19 +148,19 @@ void handler_atomic_read_file(uint8_t* service_request, uint16_t service_len, bacfile_read_stream_data(&data); #if PRINT_ENABLED fprintf(stderr, "ARF: Stream offset %d, %d octets.\n", - data.type.stream.fileStartPosition, - data.type.stream.requestedOctetCount); + data.type.stream.fileStartPosition, + data.type.stream.requestedOctetCount); #endif len = arf_ack_encode_apdu(&Handler_Transmit_Buffer[pdu_len], - service_data->invoke_id, &data); + service_data->invoke_id, &data); } else { - len = abort_encode_apdu( - &Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, + len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], + service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true); #if PRINT_ENABLED fprintf(stderr, "Too Big To Send (%d >= %d). Sending Abort!\n", - data.type.stream.requestedOctetCount, - (int)octetstring_capacity(&data.fileData[0])); + data.type.stream.requestedOctetCount, + (int)octetstring_capacity(&data.fileData[0])); #endif } } else if (data.access == FILE_RECORD_ACCESS) { @@ -171,11 +172,11 @@ void handler_atomic_read_file(uint8_t* service_request, uint16_t service_len, } else if (bacfile_read_stream_data(&data)) { #if PRINT_ENABLED fprintf(stderr, "ARF: fileStartRecord %d, %u RecordCount.\n", - data.type.record.fileStartRecord, - data.type.record.RecordCount); + data.type.record.fileStartRecord, + data.type.record.RecordCount); #endif len = arf_ack_encode_apdu(&Handler_Transmit_Buffer[pdu_len], - service_data->invoke_id, &data); + service_data->invoke_id, &data); } else { error = true; error_class = ERROR_CLASS_OBJECT; @@ -195,14 +196,14 @@ void handler_atomic_read_file(uint8_t* service_request, uint16_t service_len, error_code = ERROR_CODE_INCONSISTENT_OBJECT_TYPE; } if (error) { - len = bacerror_encode_apdu( - &Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, - SERVICE_CONFIRMED_ATOMIC_READ_FILE, error_class, error_code); + len = bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], + service_data->invoke_id, SERVICE_CONFIRMED_ATOMIC_READ_FILE, + error_class, error_code); } ARF_ABORT: pdu_len += len; - bytes_sent = datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0], - pdu_len); + bytes_sent = datalink_send_pdu( + src, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len); #if PRINT_ENABLED if (bytes_sent <= 0) { fprintf(stderr, "Failed to send PDU (%s)!\n", strerror(errno)); diff --git a/src/bacnet/basic/service/h_arf.h b/src/bacnet/basic/service/h_arf.h new file mode 100644 index 00000000..bd1eb019 --- /dev/null +++ b/src/bacnet/basic/service/h_arf.h @@ -0,0 +1,50 @@ +/** +* @file +* @author Steve Karg +* @date October 2019 +* @brief Header file for a basic Atomic Read File request handler +* +* @section LICENSE +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +#ifndef HANDLER_ATOMIC_READ_FILE_H +#define HANDLER_ATOMIC_READ_FILE_H + +#include +#include +#include +#include +#include "bacnet/bacdef.h" +#include "bacnet/bacenum.h" +#include "bacnet/apdu.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +void handler_atomic_read_file(uint8_t* service_request, uint16_t service_len, + BACNET_ADDRESS* src, + BACNET_CONFIRMED_SERVICE_DATA* service_data); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/demo/handler/h_arf_a.c b/src/bacnet/basic/service/h_arf_a.c similarity index 82% rename from demo/handler/h_arf_a.c rename to src/bacnet/basic/service/h_arf_a.c index d1cd77ad..be87acd2 100644 --- a/demo/handler/h_arf_a.c +++ b/src/bacnet/basic/service/h_arf_a.c @@ -24,23 +24,19 @@ *********************************************************************/ #include #include -#include "config.h" -#include "txbuf.h" -#include "bacdef.h" -#include "bacdcode.h" -#include "address.h" -#include "tsm.h" -#include "npdu.h" -#include "apdu.h" -#include "device.h" -#include "datalink.h" -#include "arf.h" +#include "bacnet/config.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/npdu.h" +#include "bacnet/apdu.h" +#include "bacnet/arf.h" #if defined(BACFILE) -#include "bacfile.h" +#include "bacnet/basic/object/bacfile.h" #endif -/* some demo stuff needed */ -#include "handlers.h" -#include "txbuf.h" +/* basic objects, services, TSM, and datalink */ +#include "bacnet/basic/object/device.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/basic/services.h" /** @file h_arf_a.c Handles Acknowledgment of Atomic Read File response. */ @@ -50,9 +46,10 @@ /* that someone can read from us. It is common to */ /* use the description as the file name. */ #if defined(BACFILE) -void handler_atomic_read_file_ack( - uint8_t* service_request, uint16_t service_len, BACNET_ADDRESS* src, - BACNET_CONFIRMED_SERVICE_ACK_DATA* service_data) +void handler_atomic_read_file_ack(uint8_t *service_request, + uint16_t service_len, + BACNET_ADDRESS *src, + BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data) { int len = 0; BACNET_ATOMIC_READ_FILE_DATA data; diff --git a/src/bacnet/basic/service/h_arf_a.h b/src/bacnet/basic/service/h_arf_a.h new file mode 100644 index 00000000..80a8c6aa --- /dev/null +++ b/src/bacnet/basic/service/h_arf_a.h @@ -0,0 +1,50 @@ +/** +* @file +* @author Steve Karg +* @date October 2019 +* @brief Header file for a basic Atomic Read File Ack handler +* +* @section LICENSE +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +#ifndef ATOMIC_READ_FILE_ACK_HANDLER_H +#define ATOMIC_READ_FILE_ACK_HANDLER_H + +#include +#include +#include +#include +#include "bacnet/bacdef.h" +#include "bacnet/bacenum.h" +#include "bacnet/apdu.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +void handler_atomic_read_file_ack( + uint8_t* service_request, uint16_t service_len, BACNET_ADDRESS* src, + BACNET_CONFIRMED_SERVICE_ACK_DATA* service_data); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/demo/handler/h_awf.c b/src/bacnet/basic/service/h_awf.c similarity index 78% rename from demo/handler/h_awf.c rename to src/bacnet/basic/service/h_awf.c index bfa88891..94adf75c 100644 --- a/demo/handler/h_awf.c +++ b/src/bacnet/basic/service/h_awf.c @@ -27,22 +27,23 @@ #include #include #include -#include "config.h" -#include "txbuf.h" -#include "bacdef.h" -#include "bacstr.h" -#include "bacerror.h" -#include "bacdcode.h" -#include "apdu.h" -#include "npdu.h" -#include "abort.h" -#include "awf.h" -/* demo objects */ -#include "device.h" +#include "bacnet/config.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacstr.h" +#include "bacnet/bacerror.h" +#include "bacnet/bacdcode.h" +#include "bacnet/apdu.h" +#include "bacnet/npdu.h" +#include "bacnet/abort.h" +#include "bacnet/awf.h" +/* basic objects, services, TSM, and datalink */ +#include "bacnet/basic/object/device.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/basic/services.h" +#include "bacnet/datalink/datalink.h" #if defined(BACFILE) -#include "bacfile.h" +#include "bacnet/basic/object/bacfile.h" #endif -#include "handlers.h" /** @file h_awf.c Handles Atomic Write File request. */ @@ -76,9 +77,10 @@ standard. */ #if defined(BACFILE) -void handler_atomic_write_file(uint8_t* service_request, uint16_t service_len, - BACNET_ADDRESS* src, - BACNET_CONFIRMED_SERVICE_DATA* service_data) +void handler_atomic_write_file(uint8_t *service_request, + uint16_t service_len, + BACNET_ADDRESS *src, + BACNET_CONFIRMED_SERVICE_DATA *service_data) { BACNET_ATOMIC_WRITE_FILE_DATA data; int len = 0; @@ -96,12 +98,12 @@ void handler_atomic_write_file(uint8_t* service_request, uint16_t service_len, /* encode the NPDU portion of the packet */ datalink_get_my_address(&my_address); npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL); - pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address, - &npdu_data); + pdu_len = npdu_encode_pdu( + &Handler_Transmit_Buffer[0], src, &my_address, &npdu_data); if (service_data->segmented_message) { len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], - service_data->invoke_id, - ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true); + service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, + true); #if PRINT_ENABLED fprintf(stderr, "Segmented Message. Sending Abort!\n"); #endif @@ -111,8 +113,7 @@ void handler_atomic_write_file(uint8_t* service_request, uint16_t service_len, /* bad decoding - send an abort */ if (len < 0) { len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], - service_data->invoke_id, ABORT_REASON_OTHER, - true); + service_data->invoke_id, ABORT_REASON_OTHER, true); #if PRINT_ENABLED fprintf(stderr, "Bad Encoding. Sending Abort!\n"); #endif @@ -125,11 +126,11 @@ void handler_atomic_write_file(uint8_t* service_request, uint16_t service_len, if (bacfile_write_stream_data(&data)) { #if PRINT_ENABLED fprintf(stderr, "AWF: Stream offset %d, %d bytes\n", - data.type.stream.fileStartPosition, - (int)octetstring_length(&data.fileData[0])); + data.type.stream.fileStartPosition, + (int)octetstring_length(&data.fileData[0])); #endif len = awf_ack_encode_apdu(&Handler_Transmit_Buffer[pdu_len], - service_data->invoke_id, &data); + service_data->invoke_id, &data); } else { error = true; error_class = ERROR_CLASS_OBJECT; @@ -139,11 +140,11 @@ void handler_atomic_write_file(uint8_t* service_request, uint16_t service_len, if (bacfile_write_record_data(&data)) { #if PRINT_ENABLED fprintf(stderr, "AWF: StartRecord %d, RecordCount %u\n", - data.type.record.fileStartRecord, - data.type.record.returnedRecordCount); + data.type.record.fileStartRecord, + data.type.record.returnedRecordCount); #endif len = awf_ack_encode_apdu(&Handler_Transmit_Buffer[pdu_len], - service_data->invoke_id, &data); + service_data->invoke_id, &data); } else { error = true; error_class = ERROR_CLASS_OBJECT; @@ -163,14 +164,14 @@ void handler_atomic_write_file(uint8_t* service_request, uint16_t service_len, error_code = ERROR_CODE_INCONSISTENT_OBJECT_TYPE; } if (error) { - len = bacerror_encode_apdu( - &Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, - SERVICE_CONFIRMED_ATOMIC_WRITE_FILE, error_class, error_code); + len = bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], + service_data->invoke_id, SERVICE_CONFIRMED_ATOMIC_WRITE_FILE, + error_class, error_code); } AWF_ABORT: pdu_len += len; - bytes_sent = datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0], - pdu_len); + bytes_sent = datalink_send_pdu( + src, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len); #if PRINT_ENABLED if (bytes_sent <= 0) { fprintf(stderr, "Failed to send PDU (%s)!\n", strerror(errno)); diff --git a/src/bacnet/basic/service/h_awf.h b/src/bacnet/basic/service/h_awf.h new file mode 100644 index 00000000..8adb4993 --- /dev/null +++ b/src/bacnet/basic/service/h_awf.h @@ -0,0 +1,50 @@ +/** +* @file +* @author Steve Karg +* @date October 2019 +* @brief Header file for Atomic Write File request handler +* +* @section LICENSE +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +#ifndef ATOMIC_WRITE_FILE_HANDLER_H +#define ATOMIC_WRITE_FILE_HANDLER_H + +#include +#include +#include +#include +#include "bacnet/bacdef.h" +#include "bacnet/bacenum.h" +#include "bacnet/apdu.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +void handler_atomic_write_file(uint8_t* service_request, uint16_t service_len, + BACNET_ADDRESS* src, + BACNET_CONFIRMED_SERVICE_DATA* service_data); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/demo/handler/h_ccov.c b/src/bacnet/basic/service/h_ccov.c similarity index 78% rename from demo/handler/h_ccov.c rename to src/bacnet/basic/service/h_ccov.c index 14a6c133..cac22b16 100644 --- a/demo/handler/h_ccov.c +++ b/src/bacnet/basic/service/h_ccov.c @@ -27,17 +27,18 @@ #include #include #include -#include "config.h" -#include "txbuf.h" -#include "bacdef.h" -#include "bacdcode.h" -#include "apdu.h" -#include "npdu.h" -#include "abort.h" -/* special for this module */ -#include "cov.h" -#include "bactext.h" -#include "handlers.h" +#include "bacnet/config.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/apdu.h" +#include "bacnet/npdu.h" +#include "bacnet/abort.h" +#include "bacnet/cov.h" +#include "bacnet/bactext.h" +/* basic services, TSM, and datalink */ +#include "bacnet/basic/services.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/datalink/datalink.h" #ifndef MAX_COV_PROPERTIES #define MAX_COV_PROPERTIES 2 @@ -59,9 +60,10 @@ * @param service_data [in] The BACNET_CONFIRMED_SERVICE_DATA information * decoded from the APDU header of this message. */ -void handler_ccov_notification(uint8_t *service_request, uint16_t service_len, - BACNET_ADDRESS *src, - BACNET_CONFIRMED_SERVICE_DATA *service_data) +void handler_ccov_notification(uint8_t *service_request, + uint16_t service_len, + BACNET_ADDRESS *src, + BACNET_CONFIRMED_SERVICE_DATA *service_data) { BACNET_NPDU_DATA npdu_data; BACNET_COV_DATA cov_data; @@ -79,29 +81,28 @@ void handler_ccov_notification(uint8_t *service_request, uint16_t service_len, /* encode the NPDU portion of the packet */ datalink_get_my_address(&my_address); npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL); - pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address, - &npdu_data); + pdu_len = npdu_encode_pdu( + &Handler_Transmit_Buffer[0], src, &my_address, &npdu_data); #if PRINT_ENABLED fprintf(stderr, "CCOV: Received Notification!\n"); #endif if (service_data->segmented_message) { len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], - service_data->invoke_id, - ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true); + service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, + true); #if PRINT_ENABLED fprintf(stderr, "CCOV: Segmented message. Sending Abort!\n"); #endif goto CCOV_ABORT; } /* decode the service request only */ - len = cov_notify_decode_service_request(service_request, service_len, - &cov_data); + len = cov_notify_decode_service_request( + service_request, service_len, &cov_data); #if PRINT_ENABLED if (len > 0) { fprintf(stderr, "CCOV: PID=%u ", cov_data.subscriberProcessIdentifier); fprintf(stderr, "instance=%u ", cov_data.initiatingDeviceIdentifier); - fprintf( - stderr, "%s %u ", + fprintf(stderr, "%s %u ", bactext_object_type_name(cov_data.monitoredObjectIdentifier.type), cov_data.monitoredObjectIdentifier.instance); fprintf(stderr, "time remaining=%u seconds ", cov_data.timeRemaining); @@ -110,12 +111,11 @@ void handler_ccov_notification(uint8_t *service_request, uint16_t service_len, while (pProperty_value) { fprintf(stderr, "CCOV: "); if (pProperty_value->propertyIdentifier < 512) { - fprintf( - stderr, "%s ", + fprintf(stderr, "%s ", bactext_property_name(pProperty_value->propertyIdentifier)); } else { fprintf(stderr, "proprietary %u ", - pProperty_value->propertyIdentifier); + pProperty_value->propertyIdentifier); } if (pProperty_value->propertyArrayIndex != BACNET_ARRAY_ALL) { fprintf(stderr, "%u ", pProperty_value->propertyArrayIndex); @@ -128,24 +128,22 @@ void handler_ccov_notification(uint8_t *service_request, uint16_t service_len, /* bad decoding or something we didn't understand - send an abort */ if (len <= 0) { len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], - service_data->invoke_id, ABORT_REASON_OTHER, - true); + service_data->invoke_id, ABORT_REASON_OTHER, true); #if PRINT_ENABLED fprintf(stderr, "CCOV: Bad Encoding. Sending Abort!\n"); #endif goto CCOV_ABORT; } else { len = encode_simple_ack(&Handler_Transmit_Buffer[pdu_len], - service_data->invoke_id, - SERVICE_CONFIRMED_COV_NOTIFICATION); + service_data->invoke_id, SERVICE_CONFIRMED_COV_NOTIFICATION); #if PRINT_ENABLED fprintf(stderr, "CCOV: Sending Simple Ack!\n"); #endif } CCOV_ABORT: pdu_len += len; - bytes_sent = datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0], - pdu_len); + bytes_sent = datalink_send_pdu( + src, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len); #if PRINT_ENABLED if (bytes_sent <= 0) { fprintf(stderr, "CCOV: Failed to send PDU (%s)!\n", strerror(errno)); diff --git a/src/bacnet/basic/service/h_ccov.h b/src/bacnet/basic/service/h_ccov.h new file mode 100644 index 00000000..61ea5b81 --- /dev/null +++ b/src/bacnet/basic/service/h_ccov.h @@ -0,0 +1,52 @@ +/** +* @file +* @author Steve Karg +* @date October 2019 +* @brief Header file for a basic ConfirmedCOV notification handler +* +* @section LICENSE +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +#ifndef HANDLER_CCOV_NOTIFICATION_H +#define HANDLER_CCOV_NOTIFICATION_H + +#include +#include +#include +#include +#include "bacnet/bacdef.h" +#include "bacnet/bacenum.h" +#include "bacnet/apdu.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + void handler_ccov_notification( + uint8_t * service_request, + uint16_t service_len, + BACNET_ADDRESS * src, + BACNET_CONFIRMED_SERVICE_DATA * service_data); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/demo/handler/h_cov.c b/src/bacnet/basic/service/h_cov.c similarity index 87% rename from demo/handler/h_cov.c rename to src/bacnet/basic/service/h_cov.c index 76e7b7bd..111e05a8 100644 --- a/demo/handler/h_cov.c +++ b/src/bacnet/basic/service/h_cov.c @@ -27,25 +27,25 @@ #include #include #include -#include "config.h" -#include "txbuf.h" -#include "bacdef.h" -#include "bacerror.h" -#include "bacdcode.h" -#include "bacaddr.h" -#include "apdu.h" -#include "npdu.h" -#include "abort.h" -#include "reject.h" -#include "cov.h" -#include "tsm.h" -#include "dcc.h" +#include "bacnet/config.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacerror.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacaddr.h" +#include "bacnet/apdu.h" +#include "bacnet/npdu.h" +#include "bacnet/abort.h" +#include "bacnet/reject.h" +#include "bacnet/cov.h" +#include "bacnet/dcc.h" #if PRINT_ENABLED -#include "bactext.h" +#include "bacnet/bactext.h" #endif -/* demo objects */ -#include "device.h" -#include "handlers.h" +/* basic objects, services, TSM, and datalink */ +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/basic/object/device.h" +#include "bacnet/basic/services.h" +#include "bacnet/datalink/datalink.h" #ifndef MAX_COV_PROPERTIES #define MAX_COV_PROPERTIES 2 @@ -204,8 +204,8 @@ TimeRemaining [3] Unsigned, COVIncrement [4] REAL OPTIONAL */ -static int cov_encode_subscription(uint8_t *apdu, int max_apdu, - BACNET_COV_SUBSCRIPTION *cov_subscription) +static int cov_encode_subscription( + uint8_t *apdu, int max_apdu, BACNET_COV_SUBSCRIPTION *cov_subscription) { int len = 0; int apdu_len = 0; @@ -260,8 +260,8 @@ static int cov_encode_subscription(uint8_t *apdu, int max_apdu, len = encode_opening_tag(&apdu[apdu_len], 1); apdu_len += len; /* objectIdentifier [0] */ - len = encode_context_object_id( - &apdu[apdu_len], 0, cov_subscription->monitoredObjectIdentifier.type, + len = encode_context_object_id(&apdu[apdu_len], 0, + cov_subscription->monitoredObjectIdentifier.type, cov_subscription->monitoredObjectIdentifier.instance); apdu_len += len; /* propertyIdentifier [1] */ @@ -304,8 +304,7 @@ int handler_cov_encode_subscriptions(uint8_t *apdu, int max_apdu) for (index = 0; index < MAX_COV_SUBCRIPTIONS; index++) { if (COV_Subscriptions[index].flag.valid) { len = cov_encode_subscription(&apdu[apdu_len], - max_apdu - apdu_len, - &COV_Subscriptions[index]); + max_apdu - apdu_len, &COV_Subscriptions[index]); apdu_len += len; /* TODO: too late here to notice that we overran the buffer */ if (apdu_len > max_apdu) { @@ -343,9 +342,9 @@ void handler_cov_init(void) } static bool cov_list_subscribe(BACNET_ADDRESS *src, - BACNET_SUBSCRIBE_COV_DATA *cov_data, - BACNET_ERROR_CLASS *error_class, - BACNET_ERROR_CODE *error_code) + BACNET_SUBSCRIBE_COV_DATA *cov_data, + BACNET_ERROR_CLASS *error_class, + BACNET_ERROR_CODE *error_code) { bool existing_entry = false; int index; @@ -368,11 +367,11 @@ static bool cov_list_subscribe(BACNET_ADDRESS *src, address_match = true; } if ((COV_Subscriptions[index].monitoredObjectIdentifier.type == - cov_data->monitoredObjectIdentifier.type) && + cov_data->monitoredObjectIdentifier.type) && (COV_Subscriptions[index].monitoredObjectIdentifier.instance == - cov_data->monitoredObjectIdentifier.instance) && + cov_data->monitoredObjectIdentifier.instance) && (COV_Subscriptions[index].subscriberProcessIdentifier == - cov_data->subscriberProcessIdentifier) && + cov_data->subscriberProcessIdentifier) && address_match) { existing_entry = true; if (cov_data->cancellationRequest) { @@ -435,7 +434,7 @@ static bool cov_list_subscribe(BACNET_ADDRESS *src, } static bool cov_send_request(BACNET_COV_SUBSCRIPTION *cov_subscription, - BACNET_PROPERTY_VALUE *value_list) + BACNET_PROPERTY_VALUE *value_list) { int len = 0; int pdu_len = 0; @@ -465,8 +464,8 @@ static bool cov_send_request(BACNET_COV_SUBSCRIPTION *cov_subscription, } datalink_get_my_address(&my_address); npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL); - pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], dest, &my_address, - &npdu_data); + pdu_len = npdu_encode_pdu( + &Handler_Transmit_Buffer[0], dest, &my_address, &npdu_data); /* load the COV data structure for outgoing message */ cov_data.subscriberProcessIdentifier = cov_subscription->subscriberProcessIdentifier; @@ -482,8 +481,7 @@ static bool cov_send_request(BACNET_COV_SUBSCRIPTION *cov_subscription, invoke_id = tsm_next_free_invokeID(); if (invoke_id) { cov_subscription->invokeID = invoke_id; - len = ccov_notify_encode_apdu( - &Handler_Transmit_Buffer[pdu_len], + len = ccov_notify_encode_apdu(&Handler_Transmit_Buffer[pdu_len], sizeof(Handler_Transmit_Buffer) - pdu_len, invoke_id, &cov_data); } else { @@ -491,17 +489,15 @@ static bool cov_send_request(BACNET_COV_SUBSCRIPTION *cov_subscription, } } else { len = ucov_notify_encode_apdu(&Handler_Transmit_Buffer[pdu_len], - sizeof(Handler_Transmit_Buffer) - pdu_len, - &cov_data); + sizeof(Handler_Transmit_Buffer) - pdu_len, &cov_data); } pdu_len += len; if (cov_subscription->flag.issueConfirmedNotifications) { tsm_set_confirmed_unsegmented_transaction(invoke_id, dest, &npdu_data, - &Handler_Transmit_Buffer[0], - (uint16_t)pdu_len); + &Handler_Transmit_Buffer[0], (uint16_t)pdu_len); } - bytes_sent = datalink_send_pdu(dest, &npdu_data, - &Handler_Transmit_Buffer[0], pdu_len); + bytes_sent = datalink_send_pdu( + dest, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len); if (bytes_sent > 0) { status = true; #if PRINT_ENABLED @@ -514,9 +510,8 @@ COV_FAILED: return status; } -static void cov_lifetime_expiration_handler(unsigned index, - uint32_t elapsed_seconds, - uint32_t lifetime_seconds) +static void cov_lifetime_expiration_handler( + unsigned index, uint32_t elapsed_seconds, uint32_t lifetime_seconds) { if (index < MAX_COV_SUBCRIPTIONS) { /* handle lifetime expiration */ @@ -533,14 +528,13 @@ static void cov_lifetime_expiration_handler(unsigned index, /* expire the subscription */ #if PRINT_ENABLED fprintf(stderr, "COVtimer: PID=%u ", - COV_Subscriptions[index].subscriberProcessIdentifier); - fprintf( - stderr, "%s %u ", + COV_Subscriptions[index].subscriberProcessIdentifier); + fprintf(stderr, "%s %u ", bactext_object_type_name( COV_Subscriptions[index].monitoredObjectIdentifier.type), COV_Subscriptions[index].monitoredObjectIdentifier.instance); fprintf(stderr, "time remaining=%u seconds ", - COV_Subscriptions[index].lifetime); + COV_Subscriptions[index].lifetime); fprintf(stderr, "\n"); #endif COV_Subscriptions[index].flag.valid = false; @@ -589,8 +583,8 @@ void handler_cov_timer_seconds(uint32_t elapsed_seconds) lifetime_seconds = COV_Subscriptions[index].lifetime; if (lifetime_seconds) { /* only expire COV with definite lifetimes */ - cov_lifetime_expiration_handler(index, elapsed_seconds, - lifetime_seconds); + cov_lifetime_expiration_handler( + index, elapsed_seconds, lifetime_seconds); } } } @@ -699,13 +693,13 @@ bool handler_cov_fsm(void) fprintf(stderr, "COVtask: Sending...\n"); #endif /* configure the linked list for the two properties */ - bacapp_property_value_list_init(&value_list[0], - MAX_COV_PROPERTIES); + bacapp_property_value_list_init( + &value_list[0], MAX_COV_PROPERTIES); status = Device_Encode_Value_List( object_type, object_instance, &value_list[0]); if (status) { - status = cov_send_request(&COV_Subscriptions[index], - &value_list[0]); + status = cov_send_request( + &COV_Subscriptions[index], &value_list[0]); } if (status) { COV_Subscriptions[index].flag.send_requested = false; @@ -732,9 +726,9 @@ void handler_cov_task(void) } static bool cov_subscribe(BACNET_ADDRESS *src, - BACNET_SUBSCRIBE_COV_DATA *cov_data, - BACNET_ERROR_CLASS *error_class, - BACNET_ERROR_CODE *error_code) + BACNET_SUBSCRIBE_COV_DATA *cov_data, + BACNET_ERROR_CLASS *error_class, + BACNET_ERROR_CODE *error_code) { bool status = false; /* return value */ BACNET_OBJECT_TYPE object_type = MAX_BACNET_OBJECT_TYPE; @@ -776,9 +770,10 @@ static bool cov_subscribe(BACNET_ADDRESS *src, * @param service_data [in] The BACNET_CONFIRMED_SERVICE_DATA information * decoded from the APDU header of this message. */ -void handler_cov_subscribe(uint8_t *service_request, uint16_t service_len, - BACNET_ADDRESS *src, - BACNET_CONFIRMED_SERVICE_DATA *service_data) +void handler_cov_subscribe(uint8_t *service_request, + uint16_t service_len, + BACNET_ADDRESS *src, + BACNET_CONFIRMED_SERVICE_DATA *service_data) { BACNET_SUBSCRIBE_COV_DATA cov_data; int len = 0; @@ -796,8 +791,8 @@ void handler_cov_subscribe(uint8_t *service_request, uint16_t service_len, /* encode the NPDU portion of the packet */ datalink_get_my_address(&my_address); npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL); - npdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address, - &npdu_data); + npdu_len = npdu_encode_pdu( + &Handler_Transmit_Buffer[0], src, &my_address, &npdu_data); if (service_data->segmented_message) { /* we don't support segmentation - send an abort */ len = BACNET_STATUS_ABORT; @@ -807,8 +802,8 @@ void handler_cov_subscribe(uint8_t *service_request, uint16_t service_len, error = true; goto COV_ABORT; } - len = cov_subscribe_decode_service_request(service_request, service_len, - &cov_data); + len = cov_subscribe_decode_service_request( + service_request, service_len, &cov_data); #if PRINT_ENABLED if (len <= 0) fprintf(stderr, "SubscribeCOV: Unable to decode Request!\n"); @@ -819,12 +814,11 @@ void handler_cov_subscribe(uint8_t *service_request, uint16_t service_len, } cov_data.error_class = ERROR_CLASS_OBJECT; cov_data.error_code = ERROR_CODE_UNKNOWN_OBJECT; - success = cov_subscribe(src, &cov_data, &cov_data.error_class, - &cov_data.error_code); + success = cov_subscribe( + src, &cov_data, &cov_data.error_class, &cov_data.error_code); if (success) { apdu_len = encode_simple_ack(&Handler_Transmit_Buffer[npdu_len], - service_data->invoke_id, - SERVICE_CONFIRMED_SUBSCRIBE_COV); + service_data->invoke_id, SERVICE_CONFIRMED_SUBSCRIBE_COV); #if PRINT_ENABLED fprintf(stderr, "SubscribeCOV: Sending Simple Ack!\n"); #endif @@ -838,23 +832,22 @@ void handler_cov_subscribe(uint8_t *service_request, uint16_t service_len, COV_ABORT: if (error) { if (len == BACNET_STATUS_ABORT) { - apdu_len = abort_encode_apdu( - &Handler_Transmit_Buffer[npdu_len], service_data->invoke_id, + apdu_len = abort_encode_apdu(&Handler_Transmit_Buffer[npdu_len], + service_data->invoke_id, abort_convert_error_code(cov_data.error_code), true); #if PRINT_ENABLED fprintf(stderr, "SubscribeCOV: Sending Abort!\n"); #endif } else if (len == BACNET_STATUS_ERROR) { - apdu_len = bacerror_encode_apdu( - &Handler_Transmit_Buffer[npdu_len], service_data->invoke_id, - SERVICE_CONFIRMED_SUBSCRIBE_COV, cov_data.error_class, - cov_data.error_code); + apdu_len = bacerror_encode_apdu(&Handler_Transmit_Buffer[npdu_len], + service_data->invoke_id, SERVICE_CONFIRMED_SUBSCRIBE_COV, + cov_data.error_class, cov_data.error_code); #if PRINT_ENABLED fprintf(stderr, "SubscribeCOV: Sending Error!\n"); #endif } else if (len == BACNET_STATUS_REJECT) { - apdu_len = reject_encode_apdu( - &Handler_Transmit_Buffer[npdu_len], service_data->invoke_id, + apdu_len = reject_encode_apdu(&Handler_Transmit_Buffer[npdu_len], + service_data->invoke_id, reject_convert_error_code(cov_data.error_code)); #if PRINT_ENABLED fprintf(stderr, "SubscribeCOV: Sending Reject!\n"); @@ -862,12 +855,12 @@ COV_ABORT: } } pdu_len = npdu_len + apdu_len; - bytes_sent = datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0], - pdu_len); + bytes_sent = datalink_send_pdu( + src, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len); if (bytes_sent <= 0) { #if PRINT_ENABLED fprintf(stderr, "SubscribeCOV: Failed to send PDU (%s)!\n", - strerror(errno)); + strerror(errno)); #endif } diff --git a/src/bacnet/basic/service/h_cov.h b/src/bacnet/basic/service/h_cov.h new file mode 100644 index 00000000..4291ec78 --- /dev/null +++ b/src/bacnet/basic/service/h_cov.h @@ -0,0 +1,63 @@ +/** +* @file +* @author Steve Karg +* @date October 2019 +* @brief Header file for a basic SubscribeCOV request handler, FSM, & Task +* +* @section LICENSE +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +#ifndef HANDLER_COV_SUBSCRIBE_H +#define HANDLER_COV_SUBSCRIBE_H + +#include +#include +#include +#include +#include "bacnet/bacdef.h" +#include "bacnet/bacenum.h" +#include "bacnet/apdu.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + void handler_cov_subscribe( + uint8_t * service_request, + uint16_t service_len, + BACNET_ADDRESS * src, + BACNET_CONFIRMED_SERVICE_DATA * service_data); + bool handler_cov_fsm( + void); + void handler_cov_task( + void); + void handler_cov_timer_seconds( + uint32_t elapsed_seconds); + void handler_cov_init( + void); + int handler_cov_encode_subscriptions( + uint8_t * apdu, + int max_apdu); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/demo/handler/h_dcc.c b/src/bacnet/basic/service/h_dcc.c similarity index 71% rename from demo/handler/h_dcc.c rename to src/bacnet/basic/service/h_dcc.c index 80db3325..ead85de5 100644 --- a/demo/handler/h_dcc.c +++ b/src/bacnet/basic/service/h_dcc.c @@ -27,18 +27,20 @@ #include #include #include -#include "config.h" -#include "txbuf.h" -#include "bacdef.h" -#include "bacdcode.h" -#include "bacerror.h" -#include "apdu.h" -#include "npdu.h" -#include "abort.h" -#include "reject.h" -#include "dcc.h" -#include "handlers.h" -#include "device.h" +#include "bacnet/config.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacerror.h" +#include "bacnet/apdu.h" +#include "bacnet/npdu.h" +#include "bacnet/abort.h" +#include "bacnet/reject.h" +#include "bacnet/dcc.h" +/* basic objects, services, TSM, and datalink */ +#include "bacnet/basic/object/device.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/basic/services.h" +#include "bacnet/datalink/datalink.h" /** @file h_dcc.c Handles Device Communication Control request. */ @@ -93,8 +95,9 @@ char *handler_dcc_password(void) * @param service_data [in] The BACNET_CONFIRMED_SERVICE_DATA information * decoded from the APDU header of this message. */ -void handler_device_communication_control( - uint8_t *service_request, uint16_t service_len, BACNET_ADDRESS *src, +void handler_device_communication_control(uint8_t *service_request, + uint16_t service_len, + BACNET_ADDRESS *src, BACNET_CONFIRMED_SERVICE_DATA *service_data) { uint16_t timeDuration = 0; @@ -108,53 +111,51 @@ void handler_device_communication_control( /* encode the NPDU portion of the reply packet */ datalink_get_my_address(&my_address); npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL); - pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address, - &npdu_data); + pdu_len = npdu_encode_pdu( + &Handler_Transmit_Buffer[0], src, &my_address, &npdu_data); #if PRINT_ENABLED fprintf(stderr, "DeviceCommunicationControl!\n"); #endif if (service_data->segmented_message) { len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], - service_data->invoke_id, - ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true); + service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, + true); #if PRINT_ENABLED fprintf(stderr, - "DeviceCommunicationControl: " - "Sending Abort - segmented message.\n"); + "DeviceCommunicationControl: " + "Sending Abort - segmented message.\n"); #endif goto DCC_ABORT; } /* decode the service request only */ - len = dcc_decode_service_request(service_request, service_len, - &timeDuration, &state, &password); + len = dcc_decode_service_request( + service_request, service_len, &timeDuration, &state, &password); #if PRINT_ENABLED if (len > 0) fprintf(stderr, - "DeviceCommunicationControl: " - "timeout=%u state=%u password=%s\n", - (unsigned)timeDuration, (unsigned)state, - characterstring_value(&password)); + "DeviceCommunicationControl: " + "timeout=%u state=%u password=%s\n", + (unsigned)timeDuration, (unsigned)state, + characterstring_value(&password)); #endif /* bad decoding or something we didn't understand - send an abort */ if (len < 0) { len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], - service_data->invoke_id, ABORT_REASON_OTHER, - true); + service_data->invoke_id, ABORT_REASON_OTHER, true); #if PRINT_ENABLED fprintf(stderr, - "DeviceCommunicationControl: " - "Sending Abort - could not decode.\n"); + "DeviceCommunicationControl: " + "Sending Abort - could not decode.\n"); #endif goto DCC_ABORT; } if (state >= MAX_BACNET_COMMUNICATION_ENABLE_DISABLE) { len = reject_encode_apdu(&Handler_Transmit_Buffer[pdu_len], - service_data->invoke_id, - REJECT_REASON_UNDEFINED_ENUMERATION); + service_data->invoke_id, REJECT_REASON_UNDEFINED_ENUMERATION); #if PRINT_ENABLED fprintf(stderr, - "DeviceCommunicationControl: " - "Sending Reject - undefined enumeration\n"); + "DeviceCommunicationControl: " + "Sending Reject - undefined enumeration\n"); #endif } else { #if BAC_ROUTING @@ -167,37 +168,37 @@ void handler_device_communication_control( #endif if (characterstring_ansi_same(&password, My_Password)) { - len = encode_simple_ack( - &Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, + len = encode_simple_ack(&Handler_Transmit_Buffer[pdu_len], + service_data->invoke_id, SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL); #if PRINT_ENABLED fprintf(stderr, - "DeviceCommunicationControl: " - "Sending Simple Ack!\n"); + "DeviceCommunicationControl: " + "Sending Simple Ack!\n"); #endif dcc_set_status_duration(state, timeDuration); } else { - len = bacerror_encode_apdu( - &Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, + len = bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], + service_data->invoke_id, SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL, ERROR_CLASS_SECURITY, ERROR_CODE_PASSWORD_FAILURE); #if PRINT_ENABLED fprintf(stderr, - "DeviceCommunicationControl: " - "Sending Error - password failure.\n"); + "DeviceCommunicationControl: " + "Sending Error - password failure.\n"); #endif } } DCC_ABORT: pdu_len += len; - len = datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0], - pdu_len); + len = datalink_send_pdu( + src, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len); if (len <= 0) { #if PRINT_ENABLED fprintf(stderr, - "DeviceCommunicationControl: " - "Failed to send PDU (%s)!\n", - strerror(errno)); + "DeviceCommunicationControl: " + "Failed to send PDU (%s)!\n", + strerror(errno)); #endif } diff --git a/src/bacnet/basic/service/h_dcc.h b/src/bacnet/basic/service/h_dcc.h new file mode 100644 index 00000000..4c948011 --- /dev/null +++ b/src/bacnet/basic/service/h_dcc.h @@ -0,0 +1,55 @@ +/** +* @file +* @author Steve Karg +* @date October 2019 +* @brief Header file for a basic DeviceCommunicationControl request handler +* +* @section LICENSE +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +#ifndef HANDLER_DEVICE_COMMUNICATION_CONTROL_H +#define HANDLER_DEVICE_COMMUNICATION_CONTROL_H + +#include +#include +#include +#include +#include "bacnet/bacdef.h" +#include "bacnet/bacenum.h" +#include "bacnet/apdu.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + void handler_device_communication_control( + uint8_t * service_request, + uint16_t service_len, + BACNET_ADDRESS * src, + BACNET_CONFIRMED_SERVICE_DATA * service_data); + void handler_dcc_password_set( + char *new_password); + char *handler_dcc_password(void); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/demo/handler/h_gas_a.c b/src/bacnet/basic/service/h_gas_a.c similarity index 81% rename from demo/handler/h_gas_a.c rename to src/bacnet/basic/service/h_gas_a.c index df6e3b76..b4c2f123 100644 --- a/demo/handler/h_gas_a.c +++ b/src/bacnet/basic/service/h_gas_a.c @@ -35,16 +35,18 @@ * not equal to NORMAL and a Notify_Type property whose value is ALARM. */ #include -#include "config.h" -#include "txbuf.h" -#include "bacdef.h" -#include "bacdcode.h" -#include "bacerror.h" -#include "apdu.h" -#include "npdu.h" -#include "abort.h" -#include "handlers.h" -#include "get_alarm_sum.h" +#include "bacnet/config.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacerror.h" +#include "bacnet/apdu.h" +#include "bacnet/npdu.h" +#include "bacnet/abort.h" +#include "bacnet/get_alarm_sum.h" +/* basic objects, services, TSM, and datalink */ +#include "bacnet/basic/object/device.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/basic/services.h" /** Example function to handle a GetAlarmSummary ACK. * @@ -54,9 +56,10 @@ * @param service_data [in] The BACNET_CONFIRMED_SERVICE_DATA information * decoded from the APDU header of this message. */ -void get_alarm_summary_ack_handler( - uint8_t* service_request, uint16_t service_len, BACNET_ADDRESS* src, - BACNET_CONFIRMED_SERVICE_ACK_DATA* service_data) +void get_alarm_summary_ack_handler(uint8_t *service_request, + uint16_t service_len, + BACNET_ADDRESS *src, + BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data) { uint16_t apdu_len = 0; uint16_t len = 0; diff --git a/src/bacnet/basic/service/h_gas_a.h b/src/bacnet/basic/service/h_gas_a.h new file mode 100644 index 00000000..bf7cf53b --- /dev/null +++ b/src/bacnet/basic/service/h_gas_a.h @@ -0,0 +1,52 @@ +/** +* @file +* @author Steve Karg +* @date October 2019 +* @brief Header file for a basic GetAlarmSummary-Ack service handler +* +* @section LICENSE +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +#ifndef GET_ALARM_SUMMARY_ACK_HANDLER_H +#define GET_ALARM_SUMMARY_ACK_HANDLER_H + +#include +#include +#include +#include +#include "bacnet/bacdef.h" +#include "bacnet/bacenum.h" +#include "bacnet/apdu.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + void get_alarm_summary_ack_handler( + uint8_t * service_request, + uint16_t service_len, + BACNET_ADDRESS * src, + BACNET_CONFIRMED_SERVICE_ACK_DATA * service_data); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/demo/handler/h_get_alarm_sum.c b/src/bacnet/basic/service/h_get_alarm_sum.c similarity index 73% rename from demo/handler/h_get_alarm_sum.c rename to src/bacnet/basic/service/h_get_alarm_sum.c index aec7b245..fd9ff7c5 100644 --- a/demo/handler/h_get_alarm_sum.c +++ b/src/bacnet/basic/service/h_get_alarm_sum.c @@ -26,32 +26,34 @@ #include #include #include - -#include "config.h" -#include "txbuf.h" -#include "bacdef.h" -#include "bacdcode.h" -#include "bacerror.h" -#include "apdu.h" -#include "npdu.h" -#include "abort.h" -#include "handlers.h" +#include "bacnet/config.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacerror.h" +#include "bacnet/apdu.h" +#include "bacnet/npdu.h" +#include "bacnet/abort.h" +/* basic services, TSM, and datalink */ +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/basic/services.h" +#include "bacnet/datalink/datalink.h" /** @file h_alarm_sum.c Handles Get Alarm Summary request. */ static get_alarm_summary_function Get_Alarm_Summary[MAX_BACNET_OBJECT_TYPE]; -void handler_get_alarm_summary_set(BACNET_OBJECT_TYPE object_type, - get_alarm_summary_function pFunction) +void handler_get_alarm_summary_set( + BACNET_OBJECT_TYPE object_type, get_alarm_summary_function pFunction) { if (object_type < MAX_BACNET_OBJECT_TYPE) { Get_Alarm_Summary[object_type] = pFunction; } } -void handler_get_alarm_summary(uint8_t* service_request, uint16_t service_len, - BACNET_ADDRESS* src, - BACNET_CONFIRMED_SERVICE_DATA* service_data) +void handler_get_alarm_summary(uint8_t *service_request, + uint16_t service_len, + BACNET_ADDRESS *src, + BACNET_CONFIRMED_SERVICE_DATA *service_data) { int len = 0; int pdu_len = 0; @@ -68,13 +70,13 @@ void handler_get_alarm_summary(uint8_t* service_request, uint16_t service_len, /* encode the NPDU portion of the packet */ datalink_get_my_address(&my_address); npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL); - pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address, - &npdu_data); + pdu_len = npdu_encode_pdu( + &Handler_Transmit_Buffer[0], src, &my_address, &npdu_data); if (service_data->segmented_message) { /* we don't support segmentation - send an abort */ - apdu_len = abort_encode_apdu( - &Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, - ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true); + apdu_len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], + service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, + true); #if PRINT_ENABLED fprintf(stderr, "GetAlarmSummary: Segmented message. Sending Abort!\n"); #endif @@ -96,8 +98,9 @@ void handler_get_alarm_summary(uint8_t* service_request, uint16_t service_len, if (len <= 0) { error = true; goto GET_ALARM_SUMMARY_ERROR; - } else + } else { apdu_len += len; + } } else if (alarm_value < 0) { break; } @@ -113,18 +116,17 @@ GET_ALARM_SUMMARY_ERROR: if (error) { if (len == BACNET_STATUS_ABORT) { /* BACnet APDU too small to fit data, so proper response is Abort */ - apdu_len = abort_encode_apdu( - &Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, + apdu_len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], + service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true); #if PRINT_ENABLED - fprintf(stderr, - "GetAlarmSummary: Reply too big to fit into APDU!\n"); + fprintf( + stderr, "GetAlarmSummary: Reply too big to fit into APDU!\n"); #endif } else { - apdu_len = bacerror_encode_apdu( - &Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, - SERVICE_CONFIRMED_GET_ALARM_SUMMARY, ERROR_CLASS_PROPERTY, - ERROR_CODE_OTHER); + apdu_len = bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], + service_data->invoke_id, SERVICE_CONFIRMED_GET_ALARM_SUMMARY, + ERROR_CLASS_PROPERTY, ERROR_CODE_OTHER); #if PRINT_ENABLED fprintf(stderr, "GetAlarmSummary: Sending Error!\n"); #endif @@ -133,8 +135,8 @@ GET_ALARM_SUMMARY_ERROR: GET_ALARM_SUMMARY_ABORT: pdu_len += apdu_len; - bytes_sent = datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0], - pdu_len); + bytes_sent = datalink_send_pdu( + src, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len); #if PRINT_ENABLED if (bytes_sent <= 0) { /*fprintf(stderr, "Failed to send PDU (%s)!\n", strerror(errno)); */ diff --git a/src/bacnet/basic/service/h_get_alarm_sum.h b/src/bacnet/basic/service/h_get_alarm_sum.h new file mode 100644 index 00000000..f80a79c5 --- /dev/null +++ b/src/bacnet/basic/service/h_get_alarm_sum.h @@ -0,0 +1,57 @@ +/** +* @file +* @author Steve Karg +* @date October 2019 +* @brief Header file for a basic GetAlarmSummary service handler +* +* @section LICENSE +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +#ifndef HANDLER_GET_ALARM_SUMMARY_H +#define HANDLER_GET_ALARM_SUMMARY_H + +#include +#include +#include +#include +#include "bacnet/bacdef.h" +#include "bacnet/bacenum.h" +#include "bacnet/apdu.h" +#include "bacnet/get_alarm_sum.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + void handler_get_alarm_summary_set( + BACNET_OBJECT_TYPE object_type, + get_alarm_summary_function pFunction); + + void handler_get_alarm_summary( + uint8_t * service_request, + uint16_t service_len, + BACNET_ADDRESS * src, + BACNET_CONFIRMED_SERVICE_DATA * service_data); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/demo/handler/h_getevent.c b/src/bacnet/basic/service/h_getevent.c similarity index 72% rename from demo/handler/h_getevent.c rename to src/bacnet/basic/service/h_getevent.c index f1ee582f..8922dc87 100644 --- a/demo/handler/h_getevent.c +++ b/src/bacnet/basic/service/h_getevent.c @@ -27,17 +27,20 @@ #include #include #include -#include "config.h" -#include "txbuf.h" -#include "bacdef.h" -#include "bacdcode.h" -#include "bacerror.h" -#include "apdu.h" -#include "npdu.h" -#include "abort.h" -#include "event.h" -#include "getevent.h" -#include "handlers.h" +#include "bacnet/config.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacerror.h" +#include "bacnet/apdu.h" +#include "bacnet/npdu.h" +#include "bacnet/abort.h" +#include "bacnet/event.h" +#include "bacnet/getevent.h" +/* basic objects, services, TSM, and datalink */ +#include "bacnet/basic/object/device.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/basic/services.h" +#include "bacnet/datalink/datalink.h" /** @file h_getevent.c Handles Get Event Information request. */ @@ -45,17 +48,17 @@ static get_event_info_function Get_Event_Info[MAX_BACNET_OBJECT_TYPE]; /** print eventState */ -void ge_ack_print_data(BACNET_GET_EVENT_INFORMATION_DATA* data, - uint32_t device_id) +void ge_ack_print_data( + BACNET_GET_EVENT_INFORMATION_DATA *data, uint32_t device_id) { - BACNET_GET_EVENT_INFORMATION_DATA* act_data = data; - const char* state_strs[] = {"NO", "FA", "ON", "HL", "LL"}; + BACNET_GET_EVENT_INFORMATION_DATA *act_data = data; + const char *state_strs[] = { "NO", "FA", "ON", "HL", "LL" }; printf("DeviceID\tType\tInstance\teventState\n"); printf("--------------- ------- --------------- ---------------\n"); int count = 0; while (act_data) { - printf( - "%u\t\t%u\t%u\t\t%s\n", device_id, act_data->objectIdentifier.type, + printf("%u\t\t%u\t%u\t\t%s\n", device_id, + act_data->objectIdentifier.type, act_data->objectIdentifier.instance, state_strs[data->eventState]); act_data = act_data->next; count++; @@ -63,17 +66,18 @@ void ge_ack_print_data(BACNET_GET_EVENT_INFORMATION_DATA* data, printf("\n%u\t Total\n", count); } -void handler_get_event_information_set(BACNET_OBJECT_TYPE object_type, - get_event_info_function pFunction) +void handler_get_event_information_set( + BACNET_OBJECT_TYPE object_type, get_event_info_function pFunction) { if (object_type < MAX_BACNET_OBJECT_TYPE) { Get_Event_Info[object_type] = pFunction; } } -void handler_get_event_information(uint8_t* service_request, - uint16_t service_len, BACNET_ADDRESS* src, - BACNET_CONFIRMED_SERVICE_DATA* service_data) +void handler_get_event_information(uint8_t *service_request, + uint16_t service_len, + BACNET_ADDRESS *src, + BACNET_CONFIRMED_SERVICE_DATA *service_data) { int len = 0; int pdu_len = 0; @@ -96,35 +100,33 @@ void handler_get_event_information(uint8_t* service_request, /* encode the NPDU portion of the packet */ datalink_get_my_address(&my_address); npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL); - pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address, - &npdu_data); + pdu_len = npdu_encode_pdu( + &Handler_Transmit_Buffer[0], src, &my_address, &npdu_data); if (service_data->segmented_message) { /* we don't support segmentation - send an abort */ len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], - service_data->invoke_id, - ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true); + service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, + true); #if PRINT_ENABLED fprintf(stderr, - "GetEventInformation: " - "Segmented message. Sending Abort!\n"); + "GetEventInformation: " + "Segmented message. Sending Abort!\n"); #endif goto GET_EVENT_ABORT; } - len = getevent_decode_service_request(service_request, service_len, - &object_id); + len = getevent_decode_service_request( + service_request, service_len, &object_id); if (len < 0) { /* bad decoding - send an abort */ len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], - service_data->invoke_id, ABORT_REASON_OTHER, - true); + service_data->invoke_id, ABORT_REASON_OTHER, true); #if PRINT_ENABLED fprintf(stderr, "GetEventInformation: Bad Encoding. Sending Abort!\n"); #endif goto GET_EVENT_ABORT; } - len = getevent_ack_encode_apdu_init( - &Handler_Transmit_Buffer[pdu_len], + len = getevent_ack_encode_apdu_init(&Handler_Transmit_Buffer[pdu_len], sizeof(Handler_Transmit_Buffer) - pdu_len, service_data->invoke_id); if (len <= 0) { error = true; @@ -141,9 +143,9 @@ void handler_get_event_information(uint8_t* service_request, * value */ if (object_id.type != MAX_BACNET_OBJECT_TYPE) { if ((object_id.type == - getevent_data.objectIdentifier.type) && + getevent_data.objectIdentifier.type) && (object_id.instance == - getevent_data.objectIdentifier.instance)) { + getevent_data.objectIdentifier.instance)) { /* found 'Last Received Object Identifier' so should set type of object_id to max value */ object_id.type = MAX_BACNET_OBJECT_TYPE; @@ -185,8 +187,7 @@ void handler_get_event_information(uint8_t* service_request, } } } - len = getevent_ack_encode_apdu_end( - &Handler_Transmit_Buffer[pdu_len], + len = getevent_ack_encode_apdu_end(&Handler_Transmit_Buffer[pdu_len], sizeof(Handler_Transmit_Buffer) - pdu_len, more_events); if (len <= 0) { error = true; @@ -197,23 +198,23 @@ void handler_get_event_information(uint8_t* service_request, #endif GET_EVENT_ERROR: if (error) { - pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address, - &npdu_data); + pdu_len = npdu_encode_pdu( + &Handler_Transmit_Buffer[0], src, &my_address, &npdu_data); if (len == -2) { /* BACnet APDU too small to fit data, so proper response is Abort */ - len = abort_encode_apdu( - &Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, + len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], + service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true); #if PRINT_ENABLED fprintf(stderr, - "GetEventInformation: " - "Reply too big to fit into APDU!\n"); + "GetEventInformation: " + "Reply too big to fit into APDU!\n"); #endif } else { - len = bacerror_encode_apdu( - &Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, - SERVICE_CONFIRMED_READ_PROPERTY, error_class, error_code); + len = bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], + service_data->invoke_id, SERVICE_CONFIRMED_READ_PROPERTY, + error_class, error_code); #if PRINT_ENABLED fprintf(stderr, "GetEventInformation: Sending Error!\n"); #endif @@ -221,8 +222,8 @@ GET_EVENT_ERROR: } GET_EVENT_ABORT: pdu_len += len; - bytes_sent = datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0], - pdu_len); + bytes_sent = datalink_send_pdu( + src, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len); #if PRINT_ENABLED if (bytes_sent <= 0) fprintf(stderr, "Failed to send PDU (%s)!\n", strerror(errno)); diff --git a/src/bacnet/basic/service/h_getevent.h b/src/bacnet/basic/service/h_getevent.h new file mode 100644 index 00000000..39a3401b --- /dev/null +++ b/src/bacnet/basic/service/h_getevent.h @@ -0,0 +1,61 @@ +/** +* @file +* @author Steve Karg +* @date October 2019 +* @brief Header file for a basic GetEventInformation service handler +* +* @section LICENSE +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +#ifndef HANDLER_GET_EVENT_INFORMATION_H +#define HANDLER_GET_EVENT_INFORMATION_H + +#include +#include +#include +#include +#include "bacnet/bacdef.h" +#include "bacnet/bacenum.h" +#include "bacnet/apdu.h" +#include "bacnet/event.h" +#include "bacnet/getevent.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + void handler_get_event_information_set( + BACNET_OBJECT_TYPE object_type, + get_event_info_function pFunction); + + void handler_get_event_information( + uint8_t * service_request, + uint16_t service_len, + BACNET_ADDRESS * src, + BACNET_CONFIRMED_SERVICE_DATA * service_data); + + void ge_ack_print_data(BACNET_GET_EVENT_INFORMATION_DATA* data, + uint32_t device_id); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/demo/handler/h_getevent_a.c b/src/bacnet/basic/service/h_getevent_a.c similarity index 85% rename from demo/handler/h_getevent_a.c rename to src/bacnet/basic/service/h_getevent_a.c index e22c0609..ab5fc82c 100644 --- a/demo/handler/h_getevent_a.c +++ b/src/bacnet/basic/service/h_getevent_a.c @@ -37,16 +37,17 @@ * (TO-OFFNORMAL, TO-FAULT, TONORMAL) set to FALSE. */ #include -#include "config.h" -#include "txbuf.h" -#include "bacdef.h" -#include "bacdcode.h" -#include "bacerror.h" -#include "apdu.h" -#include "npdu.h" -#include "abort.h" -#include "handlers.h" -#include "getevent.h" +#include "bacnet/config.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacerror.h" +#include "bacnet/apdu.h" +#include "bacnet/npdu.h" +#include "bacnet/abort.h" +#include "bacnet/getevent.h" +/* basic services */ +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/basic/services.h" /* 40 = min size of get event data in APDU */ #define MAX_NUMBER_OF_EVENTS ((MAX_APDU / 40) + 1) @@ -59,9 +60,10 @@ * @param service_data [in] The BACNET_CONFIRMED_SERVICE_ACK_DATA information * decoded from the APDU header of this message. */ -void get_event_ack_handler(uint8_t *service_request, uint16_t service_len, - BACNET_ADDRESS *src, - BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data) +void get_event_ack_handler(uint8_t *service_request, + uint16_t service_len, + BACNET_ADDRESS *src, + BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data) { uint8_t i = 0; uint16_t apdu_len = 0; diff --git a/src/bacnet/basic/service/h_getevent_a.h b/src/bacnet/basic/service/h_getevent_a.h new file mode 100644 index 00000000..86aecbec --- /dev/null +++ b/src/bacnet/basic/service/h_getevent_a.h @@ -0,0 +1,52 @@ +/** +* @file +* @author Steve Karg +* @date October 2019 +* @brief Header file for a basic GetEventNotification-Ack service handler +* +* @section LICENSE +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +#ifndef GET_EVENT_ACK_HANDLER_H +#define GET_EVENT_ACK_HANDLER_H + +#include +#include +#include +#include +#include "bacnet/bacdef.h" +#include "bacnet/bacenum.h" +#include "bacnet/apdu.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + void get_event_ack_handler( + uint8_t *service_request, + uint16_t service_len, + BACNET_ADDRESS *src, + BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/demo/handler/h_iam.c b/src/bacnet/basic/service/h_iam.c similarity index 78% rename from demo/handler/h_iam.c rename to src/bacnet/basic/service/h_iam.c index a1d0190f..1fa228de 100644 --- a/demo/handler/h_iam.c +++ b/src/bacnet/basic/service/h_iam.c @@ -25,13 +25,13 @@ #include #include #include -#include "config.h" -#include "txbuf.h" -#include "bacdef.h" -#include "bacdcode.h" -#include "iam.h" -#include "address.h" -#include "handlers.h" +#include "bacnet/config.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/iam.h" +#include "bacnet/basic/binding/address.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/tsm/tsm.h" /** @file h_iam.c Handles I-Am requests. */ @@ -42,8 +42,8 @@ * @param service_len [in] Length of the service_request message. * @param src [in] The BACNET_ADDRESS of the message's source. */ -void handler_i_am_add(uint8_t* service_request, uint16_t service_len, - BACNET_ADDRESS* src) +void handler_i_am_add( + uint8_t *service_request, uint16_t service_len, BACNET_ADDRESS *src) { int len = 0; uint32_t device_id = 0; @@ -52,16 +52,16 @@ void handler_i_am_add(uint8_t* service_request, uint16_t service_len, uint16_t vendor_id = 0; (void)service_len; - len = iam_decode_service_request(service_request, &device_id, &max_apdu, - &segmentation, &vendor_id); + len = iam_decode_service_request( + service_request, &device_id, &max_apdu, &segmentation, &vendor_id); #if PRINT_ENABLED fprintf(stderr, "Received I-Am Request"); #endif if (len != -1) { #if PRINT_ENABLED fprintf(stderr, " from %lu, MAC = %d.%d.%d.%d.%d.%d\n", - (unsigned long)device_id, src->mac[0], src->mac[1], src->mac[2], - src->mac[3], src->mac[4], src->mac[5]); + (unsigned long)device_id, src->mac[0], src->mac[1], src->mac[2], + src->mac[3], src->mac[4], src->mac[5]); #endif address_add(device_id, max_apdu, src); } else { @@ -81,8 +81,8 @@ void handler_i_am_add(uint8_t* service_request, uint16_t service_len, * @param service_len [in] Length of the service_request message. * @param src [in] The BACNET_ADDRESS of the message's source. */ -void handler_i_am_bind(uint8_t* service_request, uint16_t service_len, - BACNET_ADDRESS* src) +void handler_i_am_bind( + uint8_t *service_request, uint16_t service_len, BACNET_ADDRESS *src) { int len = 0; uint32_t device_id = 0; @@ -91,8 +91,8 @@ void handler_i_am_bind(uint8_t* service_request, uint16_t service_len, uint16_t vendor_id = 0; (void)service_len; - len = iam_decode_service_request(service_request, &device_id, &max_apdu, - &segmentation, &vendor_id); + len = iam_decode_service_request( + service_request, &device_id, &max_apdu, &segmentation, &vendor_id); if (len > 0) { /* only add address if requested to bind */ address_add_binding(device_id, max_apdu, src); diff --git a/src/bacnet/basic/service/h_iam.h b/src/bacnet/basic/service/h_iam.h new file mode 100644 index 00000000..250458fc --- /dev/null +++ b/src/bacnet/basic/service/h_iam.h @@ -0,0 +1,56 @@ +/** +* @file +* @author Steve Karg +* @date October 2019 +* @brief Header file for a basic I-Am service handler +* +* @section LICENSE +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +#ifndef HANDLER_I_AM_H +#define HANDLER_I_AM_H + +#include +#include +#include +#include +#include "bacnet/bacdef.h" +#include "bacnet/bacenum.h" +#include "bacnet/apdu.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + void handler_i_am_add( + uint8_t * service_request, + uint16_t service_len, + BACNET_ADDRESS * src); + + void handler_i_am_bind( + uint8_t * service_request, + uint16_t service_len, + BACNET_ADDRESS * src); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/demo/handler/h_ihave.c b/src/bacnet/basic/service/h_ihave.c similarity index 80% rename from demo/handler/h_ihave.c rename to src/bacnet/basic/service/h_ihave.c index fb5db5ef..c5e4d02e 100644 --- a/demo/handler/h_ihave.c +++ b/src/bacnet/basic/service/h_ihave.c @@ -25,13 +25,13 @@ #include #include #include -#include "config.h" -#include "txbuf.h" -#include "bacdef.h" -#include "bacdcode.h" -#include "bactext.h" -#include "ihave.h" -#include "handlers.h" +#include "bacnet/config.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bactext.h" +#include "bacnet/ihave.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/tsm/tsm.h" /** @file h_ihave.c Handles incoming I-Have messages. */ @@ -41,8 +41,8 @@ * @param service_len [in] Length of the service_request message. * @param src [in] The BACNET_ADDRESS of the message's source. */ -void handler_i_have(uint8_t* service_request, uint16_t service_len, - BACNET_ADDRESS* src) +void handler_i_have( + uint8_t *service_request, uint16_t service_len, BACNET_ADDRESS *src) { int len = 0; BACNET_I_HAVE_DATA data; @@ -53,10 +53,10 @@ void handler_i_have(uint8_t* service_request, uint16_t service_len, if (len != -1) { #if PRINT_ENABLED fprintf(stderr, "I-Have: %s %lu from %s %lu!\r\n", - bactext_object_type_name(data.object_id.type), - (unsigned long)data.object_id.instance, - bactext_object_type_name(data.device_id.type), - (unsigned long)data.device_id.instance); + bactext_object_type_name(data.object_id.type), + (unsigned long)data.object_id.instance, + bactext_object_type_name(data.device_id.type), + (unsigned long)data.device_id.instance); #endif } else { #if PRINT_ENABLED diff --git a/ports/dos/timer.h b/src/bacnet/basic/service/h_ihave.h similarity index 72% rename from ports/dos/timer.h rename to src/bacnet/basic/service/h_ihave.h index 05f6beaa..e9a52f36 100644 --- a/ports/dos/timer.h +++ b/src/bacnet/basic/service/h_ihave.h @@ -1,6 +1,10 @@ -/************************************************************************** +/** +* @file +* @author Steve Karg +* @date October 2019 +* @brief Header file for a basic I-Have service handler * -* Copyright (C) 2007 Steve Karg +* @section LICENSE * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the @@ -20,26 +24,26 @@ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -* -*********************************************************************/ - -#ifndef TIMER_H -#define TIMER_H +*/ +#ifndef HANDLER_I_HAVE_H +#define HANDLER_I_HAVE_H +#include #include - -extern volatile unsigned long Timer_Milliseconds; +#include +#include +#include "bacnet/bacdef.h" +#include "bacnet/bacenum.h" +#include "bacnet/apdu.h" #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ - void Timer_Init( - void); - int Timer_Silence( - void); - void Timer_Silence_Reset( - void); + void handler_i_have( + uint8_t * service_request, + uint16_t service_len, + BACNET_ADDRESS * src); #ifdef __cplusplus } diff --git a/demo/handler/h_lso.c b/src/bacnet/basic/service/h_lso.c similarity index 67% rename from demo/handler/h_lso.c rename to src/bacnet/basic/service/h_lso.c index 0638162f..0787f209 100644 --- a/demo/handler/h_lso.c +++ b/src/bacnet/basic/service/h_lso.c @@ -27,22 +27,25 @@ #include #include #include -#include "config.h" -#include "txbuf.h" -#include "bacdef.h" -#include "bacdcode.h" -#include "apdu.h" -#include "npdu.h" -#include "abort.h" -#include "lso.h" -#include "handlers.h" -#include "device.h" +#include "bacnet/config.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/apdu.h" +#include "bacnet/npdu.h" +#include "bacnet/abort.h" +#include "bacnet/lso.h" +/* basic objects, services, TSM, and datalink */ +#include "bacnet/basic/services.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/basic/object/device.h" +#include "bacnet/datalink/datalink.h" /** @file h_lso.c Handles BACnet Life Safey Operation messages. */ -void handler_lso(uint8_t* service_request, uint16_t service_len, - BACNET_ADDRESS* src, - BACNET_CONFIRMED_SERVICE_DATA* service_data) +void handler_lso(uint8_t *service_request, + uint16_t service_len, + BACNET_ADDRESS *src, + BACNET_CONFIRMED_SERVICE_DATA *service_data) { BACNET_LSO_DATA data; int len = 0; @@ -54,13 +57,13 @@ void handler_lso(uint8_t* service_request, uint16_t service_len, /* encode the NPDU portion of the packet */ datalink_get_my_address(&my_address); npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL); - pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address, - &npdu_data); + pdu_len = npdu_encode_pdu( + &Handler_Transmit_Buffer[0], src, &my_address, &npdu_data); if (service_data->segmented_message) { /* we don't support segmentation - send an abort */ len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], - service_data->invoke_id, - ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true); + service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, + true); #if PRINT_ENABLED fprintf(stderr, "LSO: Segmented message. Sending Abort!\n"); #endif @@ -75,8 +78,7 @@ void handler_lso(uint8_t* service_request, uint16_t service_len, if (len < 0) { /* bad decoding - send an abort */ len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], - service_data->invoke_id, ABORT_REASON_OTHER, - true); + service_data->invoke_id, ABORT_REASON_OTHER, true); #if PRINT_ENABLED fprintf(stderr, "LSO: Bad Encoding. Sending Abort!\n"); #endif @@ -88,31 +90,30 @@ void handler_lso(uint8_t* service_request, uint16_t service_len, */ #if PRINT_ENABLED fprintf(stderr, - "Life Safety Operation: Received operation %d from process id %lu " - "for object %lu\n", - data.operation, (unsigned long)data.processId, - (unsigned long)data.targetObject.instance); + "Life Safety Operation: Received operation %d from process id %lu " + "for object %lu\n", + data.operation, (unsigned long)data.processId, + (unsigned long)data.targetObject.instance); #endif len = encode_simple_ack(&Handler_Transmit_Buffer[pdu_len], - service_data->invoke_id, - SERVICE_CONFIRMED_LIFE_SAFETY_OPERATION); + service_data->invoke_id, SERVICE_CONFIRMED_LIFE_SAFETY_OPERATION); #if PRINT_ENABLED fprintf(stderr, - "Life Safety Operation: " - "Sending Simple Ack!\n"); + "Life Safety Operation: " + "Sending Simple Ack!\n"); #endif LSO_ABORT: pdu_len += len; - bytes_sent = datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0], - pdu_len); + bytes_sent = datalink_send_pdu( + src, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len); #if PRINT_ENABLED if (bytes_sent <= 0) fprintf(stderr, - "Life Safety Operation: " - "Failed to send PDU (%s)!\n", - strerror(errno)); + "Life Safety Operation: " + "Failed to send PDU (%s)!\n", + strerror(errno)); #endif return; diff --git a/src/bacnet/basic/service/h_lso.h b/src/bacnet/basic/service/h_lso.h new file mode 100644 index 00000000..b3e998ee --- /dev/null +++ b/src/bacnet/basic/service/h_lso.h @@ -0,0 +1,52 @@ +/** +* @file +* @author Steve Karg +* @date October 2019 +* @brief Header file for a basic LifeSafetyOperation service handler +* +* @section LICENSE +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +#ifndef HANDLER_LIFE_SAFETY_OPERATION_H +#define HANDLER_LIFE_SAFETY_OPERATION_H + +#include +#include +#include +#include +#include "bacnet/bacdef.h" +#include "bacnet/bacenum.h" +#include "bacnet/apdu.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + void handler_lso( + uint8_t * service_request, + uint16_t service_len, + BACNET_ADDRESS * src, + BACNET_CONFIRMED_SERVICE_DATA * service_data); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/demo/handler/noserv.c b/src/bacnet/basic/service/h_noserv.c similarity index 78% rename from demo/handler/noserv.c rename to src/bacnet/basic/service/h_noserv.c index 3c75e0d2..40d0f488 100644 --- a/demo/handler/noserv.c +++ b/src/bacnet/basic/service/h_noserv.c @@ -27,14 +27,16 @@ #include #include #include -#include "txbuf.h" -#include "bacdef.h" -#include "bacdcode.h" -#include "apdu.h" -#include "npdu.h" -#include "reject.h" -#include "handlers.h" -#include "device.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/apdu.h" +#include "bacnet/npdu.h" +#include "bacnet/reject.h" +/* basic objects, services, TSM, and datalink */ +#include "bacnet/basic/object/device.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/basic/services.h" +#include "bacnet/datalink/datalink.h" /** @file noserv.c Handles an unrecognized/unsupported service. */ @@ -49,9 +51,10 @@ * @param service_data [in] The BACNET_CONFIRMED_SERVICE_DATA information * decoded from the APDU header of this message. */ -void handler_unrecognized_service(uint8_t* service_request, - uint16_t service_len, BACNET_ADDRESS* src, - BACNET_CONFIRMED_SERVICE_DATA* service_data) +void handler_unrecognized_service(uint8_t *service_request, + uint16_t service_len, + BACNET_ADDRESS *src, + BACNET_CONFIRMED_SERVICE_DATA *service_data) { int len = 0; int pdu_len = 0; @@ -65,16 +68,15 @@ void handler_unrecognized_service(uint8_t* service_request, /* encode the NPDU portion of the packet */ datalink_get_my_address(&my_address); npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL); - pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address, - &npdu_data); + pdu_len = npdu_encode_pdu( + &Handler_Transmit_Buffer[0], src, &my_address, &npdu_data); /* encode the APDU portion of the packet */ len = reject_encode_apdu(&Handler_Transmit_Buffer[pdu_len], - service_data->invoke_id, - REJECT_REASON_UNRECOGNIZED_SERVICE); + service_data->invoke_id, REJECT_REASON_UNRECOGNIZED_SERVICE); pdu_len += len; /* send the data */ - bytes_sent = datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0], - pdu_len); + bytes_sent = datalink_send_pdu( + src, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len); if (bytes_sent > 0) { #if PRINT_ENABLED fprintf(stderr, "Sent Reject!\n"); diff --git a/src/bacnet/basic/service/h_noserv.h b/src/bacnet/basic/service/h_noserv.h new file mode 100644 index 00000000..85a29c5d --- /dev/null +++ b/src/bacnet/basic/service/h_noserv.h @@ -0,0 +1,52 @@ +/** +* @file +* @author Steve Karg +* @date October 2019 +* @brief Header file for a basic unrecognized service handler +* +* @section LICENSE +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +#ifndef UNRECOGNIZED_SERVICE_HANDLER_H +#define UNRECOGNIZED_SERVICE_HANDLER_H + +#include +#include +#include +#include +#include "bacnet/bacdef.h" +#include "bacnet/bacenum.h" +#include "bacnet/apdu.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + void handler_unrecognized_service( + uint8_t * service_request, + uint16_t service_len, + BACNET_ADDRESS * dest, + BACNET_CONFIRMED_SERVICE_DATA * service_data); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/demo/handler/h_rd.c b/src/bacnet/basic/service/h_rd.c similarity index 68% rename from demo/handler/h_rd.c rename to src/bacnet/basic/service/h_rd.c index 3207c890..76fc0e21 100644 --- a/demo/handler/h_rd.c +++ b/src/bacnet/basic/service/h_rd.c @@ -27,19 +27,20 @@ #include #include #include -#include "config.h" -#include "txbuf.h" -#include "bacdef.h" -#include "bacdcode.h" -#include "bacerror.h" -#include "apdu.h" -#include "npdu.h" -#include "abort.h" -#include "reject.h" -#include "rd.h" -/* custom handling in device object */ -#include "device.h" -#include "handlers.h" +#include "bacnet/config.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacerror.h" +#include "bacnet/apdu.h" +#include "bacnet/npdu.h" +#include "bacnet/abort.h" +#include "bacnet/reject.h" +#include "bacnet/rd.h" +/* basic objects, services, TSM, and datalink */ +#include "bacnet/basic/object/device.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/basic/services.h" +#include "bacnet/datalink/datalink.h" /** @file h_rd.c Handles Reinitialize Device requests. */ @@ -63,9 +64,10 @@ * @param service_data [in] The BACNET_CONFIRMED_SERVICE_DATA information * decoded from the APDU header of this message. */ -void handler_reinitialize_device(uint8_t* service_request, uint16_t service_len, - BACNET_ADDRESS* src, - BACNET_CONFIRMED_SERVICE_DATA* service_data) +void handler_reinitialize_device(uint8_t *service_request, + uint16_t service_len, + BACNET_ADDRESS *src, + BACNET_CONFIRMED_SERVICE_DATA *service_data) { BACNET_REINITIALIZE_DEVICE_DATA rd_data; int len = 0; @@ -76,29 +78,28 @@ void handler_reinitialize_device(uint8_t* service_request, uint16_t service_len, /* encode the NPDU portion of the packet */ datalink_get_my_address(&my_address); npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL); - pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address, - &npdu_data); + pdu_len = npdu_encode_pdu( + &Handler_Transmit_Buffer[0], src, &my_address, &npdu_data); #if PRINT_ENABLED fprintf(stderr, "ReinitializeDevice!\n"); #endif if (service_data->segmented_message) { len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], - service_data->invoke_id, - ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true); + service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, + true); #if PRINT_ENABLED - fprintf(stderr, - "ReinitializeDevice: Sending Abort - segmented message.\n"); + fprintf( + stderr, "ReinitializeDevice: Sending Abort - segmented message.\n"); #endif goto RD_ABORT; } /* decode the service request only */ - len = rd_decode_service_request(service_request, service_len, - &rd_data.state, &rd_data.password); + len = rd_decode_service_request( + service_request, service_len, &rd_data.state, &rd_data.password); #if PRINT_ENABLED if (len > 0) { fprintf(stderr, "ReinitializeDevice: state=%u password=%s\n", - (unsigned)rd_data.state, - characterstring_value(&rd_data.password)); + (unsigned)rd_data.state, characterstring_value(&rd_data.password)); } else { fprintf(stderr, "ReinitializeDevice: Unable to decode request!\n"); } @@ -106,22 +107,20 @@ void handler_reinitialize_device(uint8_t* service_request, uint16_t service_len, /* bad decoding or something we didn't understand - send an abort */ if (len < 0) { len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], - service_data->invoke_id, ABORT_REASON_OTHER, - true); + service_data->invoke_id, ABORT_REASON_OTHER, true); #if PRINT_ENABLED - fprintf(stderr, - "ReinitializeDevice: Sending Abort - could not decode.\n"); + fprintf( + stderr, "ReinitializeDevice: Sending Abort - could not decode.\n"); #endif goto RD_ABORT; } /* check the data from the request */ if (rd_data.state >= BACNET_REINIT_MAX) { len = reject_encode_apdu(&Handler_Transmit_Buffer[pdu_len], - service_data->invoke_id, - REJECT_REASON_UNDEFINED_ENUMERATION); + service_data->invoke_id, REJECT_REASON_UNDEFINED_ENUMERATION); #if PRINT_ENABLED fprintf(stderr, - "ReinitializeDevice: Sending Reject - undefined enumeration\n"); + "ReinitializeDevice: Sending Reject - undefined enumeration\n"); #endif } else { #if BAC_ROUTING @@ -135,16 +134,14 @@ void handler_reinitialize_device(uint8_t* service_request, uint16_t service_len, if (Device_Reinitialize(&rd_data)) { len = encode_simple_ack(&Handler_Transmit_Buffer[pdu_len], - service_data->invoke_id, - SERVICE_CONFIRMED_REINITIALIZE_DEVICE); + service_data->invoke_id, SERVICE_CONFIRMED_REINITIALIZE_DEVICE); #if PRINT_ENABLED fprintf(stderr, "ReinitializeDevice: Sending Simple Ack!\n"); #endif } else { len = bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], - service_data->invoke_id, - SERVICE_CONFIRMED_REINITIALIZE_DEVICE, - rd_data.error_class, rd_data.error_code); + service_data->invoke_id, SERVICE_CONFIRMED_REINITIALIZE_DEVICE, + rd_data.error_class, rd_data.error_code); #if PRINT_ENABLED fprintf(stderr, "ReinitializeDevice: Sending Error.\n"); #endif @@ -152,12 +149,12 @@ void handler_reinitialize_device(uint8_t* service_request, uint16_t service_len, } RD_ABORT: pdu_len += len; - len = datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0], - pdu_len); + len = datalink_send_pdu( + src, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len); if (len <= 0) { #if PRINT_ENABLED fprintf(stderr, "ReinitializeDevice: Failed to send PDU (%s)!\n", - strerror(errno)); + strerror(errno)); #endif } diff --git a/src/bacnet/basic/service/h_rd.h b/src/bacnet/basic/service/h_rd.h new file mode 100644 index 00000000..b4ec4d58 --- /dev/null +++ b/src/bacnet/basic/service/h_rd.h @@ -0,0 +1,52 @@ +/** +* @file +* @author Steve Karg +* @date October 2019 +* @brief Header file for a basic ReinitializeDevice service handler +* +* @section LICENSE +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +#ifndef HANDLER_REINITIALIZE_DEVICE_H +#define HANDLER_REINITIALIZE_DEVICE_H + +#include +#include +#include +#include +#include "bacnet/bacdef.h" +#include "bacnet/bacenum.h" +#include "bacnet/apdu.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + void handler_reinitialize_device( + uint8_t * service_request, + uint16_t service_len, + BACNET_ADDRESS * src, + BACNET_CONFIRMED_SERVICE_DATA * service_data); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/demo/handler/h_rp.c b/src/bacnet/basic/service/h_rp.c similarity index 81% rename from demo/handler/h_rp.c rename to src/bacnet/basic/service/h_rp.c index 0a4ce0b4..f4a3f2e6 100644 --- a/demo/handler/h_rp.c +++ b/src/bacnet/basic/service/h_rp.c @@ -27,20 +27,21 @@ #include #include #include -#include "config.h" -#include "txbuf.h" -#include "bacdef.h" -#include "bacdcode.h" -#include "bacerror.h" -#include "bacdevobjpropref.h" -#include "apdu.h" -#include "npdu.h" -#include "abort.h" -#include "reject.h" -#include "rp.h" -/* device object has custom handler for all objects */ -#include "device.h" -#include "handlers.h" +#include "bacnet/config.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacerror.h" +#include "bacnet/bacdevobjpropref.h" +#include "bacnet/apdu.h" +#include "bacnet/npdu.h" +#include "bacnet/abort.h" +#include "bacnet/reject.h" +#include "bacnet/rp.h" +/* basic objects, services, TSM, and datalink */ +#include "bacnet/basic/object/device.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/basic/services.h" +#include "bacnet/datalink/datalink.h" /** @file h_rp.c Handles Read Property requests. */ @@ -63,9 +64,10 @@ * @param service_data [in] The BACNET_CONFIRMED_SERVICE_DATA information * decoded from the APDU header of this message. */ -void handler_read_property(uint8_t* service_request, uint16_t service_len, - BACNET_ADDRESS* src, - BACNET_CONFIRMED_SERVICE_DATA* service_data) +void handler_read_property(uint8_t *service_request, + uint16_t service_len, + BACNET_ADDRESS *src, + BACNET_CONFIRMED_SERVICE_DATA *service_data) { BACNET_READ_PROPERTY_DATA rpdata; int len = 0; @@ -82,8 +84,8 @@ void handler_read_property(uint8_t* service_request, uint16_t service_len, /* encode the NPDU portion of the packet */ datalink_get_my_address(&my_address); npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL); - npdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address, - &npdu_data); + npdu_len = npdu_encode_pdu( + &Handler_Transmit_Buffer[0], src, &my_address, &npdu_data); if (service_data->segmented_message) { /* we don't support segmentation - send an abort */ len = BACNET_STATUS_ABORT; @@ -112,8 +114,8 @@ void handler_read_property(uint8_t* service_request, uint16_t service_len, rpdata.object_instance = Device_Object_Instance_Number(); } - apdu_len = rp_ack_encode_apdu_init(&Handler_Transmit_Buffer[npdu_len], - service_data->invoke_id, &rpdata); + apdu_len = rp_ack_encode_apdu_init( + &Handler_Transmit_Buffer[npdu_len], service_data->invoke_id, &rpdata); /* configure our storage */ rpdata.application_data = &Handler_Transmit_Buffer[npdu_len + apdu_len]; rpdata.application_data_len = @@ -157,23 +159,22 @@ void handler_read_property(uint8_t* service_request, uint16_t service_len, RP_FAILURE: if (error) { if (len == BACNET_STATUS_ABORT) { - apdu_len = abort_encode_apdu( - &Handler_Transmit_Buffer[npdu_len], service_data->invoke_id, + apdu_len = abort_encode_apdu(&Handler_Transmit_Buffer[npdu_len], + service_data->invoke_id, abort_convert_error_code(rpdata.error_code), true); #if PRINT_ENABLED fprintf(stderr, "RP: Sending Abort!\n"); #endif } else if (len == BACNET_STATUS_ERROR) { - apdu_len = bacerror_encode_apdu( - &Handler_Transmit_Buffer[npdu_len], service_data->invoke_id, - SERVICE_CONFIRMED_READ_PROPERTY, rpdata.error_class, - rpdata.error_code); + apdu_len = bacerror_encode_apdu(&Handler_Transmit_Buffer[npdu_len], + service_data->invoke_id, SERVICE_CONFIRMED_READ_PROPERTY, + rpdata.error_class, rpdata.error_code); #if PRINT_ENABLED fprintf(stderr, "RP: Sending Error!\n"); #endif } else if (len == BACNET_STATUS_REJECT) { - apdu_len = reject_encode_apdu( - &Handler_Transmit_Buffer[npdu_len], service_data->invoke_id, + apdu_len = reject_encode_apdu(&Handler_Transmit_Buffer[npdu_len], + service_data->invoke_id, reject_convert_error_code(rpdata.error_code)); #if PRINT_ENABLED fprintf(stderr, "RP: Sending Reject!\n"); @@ -182,8 +183,8 @@ RP_FAILURE: } pdu_len = npdu_len + apdu_len; - bytes_sent = datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0], - pdu_len); + bytes_sent = datalink_send_pdu( + src, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len); if (bytes_sent <= 0) { #if PRINT_ENABLED fprintf(stderr, "Failed to send PDU (%s)!\n", strerror(errno)); diff --git a/src/bacnet/basic/service/h_rp.h b/src/bacnet/basic/service/h_rp.h new file mode 100644 index 00000000..848b9de1 --- /dev/null +++ b/src/bacnet/basic/service/h_rp.h @@ -0,0 +1,52 @@ +/** +* @file +* @author Steve Karg +* @date October 2019 +* @brief Header file for a basic ReadProperty service handler +* +* @section LICENSE +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +#ifndef HANDLER_READ_PROPERTY_H +#define HANDLER_READ_PROPERTY_H + +#include +#include +#include +#include +#include "bacnet/bacdef.h" +#include "bacnet/bacenum.h" +#include "bacnet/apdu.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + void handler_read_property( + uint8_t * service_request, + uint16_t service_len, + BACNET_ADDRESS * src, + BACNET_CONFIRMED_SERVICE_DATA * service_data); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/demo/handler/h_rp_a.c b/src/bacnet/basic/service/h_rp_a.c similarity index 93% rename from demo/handler/h_rp_a.c rename to src/bacnet/basic/service/h_rp_a.c index 44dc7050..feb730d1 100644 --- a/demo/handler/h_rp_a.c +++ b/src/bacnet/basic/service/h_rp_a.c @@ -25,21 +25,19 @@ #include #include #include -#include "config.h" -#include "txbuf.h" -#include "bacdef.h" -#include "bacdcode.h" -#include "address.h" -#include "tsm.h" -#include "npdu.h" -#include "apdu.h" -#include "device.h" -#include "datalink.h" -#include "bactext.h" -#include "rp.h" +#include "bacnet/config.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/npdu.h" +#include "bacnet/apdu.h" +#include "bacnet/datalink/datalink.h" +#include "bacnet/bactext.h" +#include "bacnet/rp.h" /* some demo stuff needed */ -#include "handlers.h" -#include "txbuf.h" +#include "bacnet/basic/binding/address.h" +#include "bacnet/basic/object/device.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/tsm/tsm.h" /** @file h_rp_a.c Handles Read Property Acknowledgments. */ @@ -49,7 +47,7 @@ void rp_ack_print_data(BACNET_READ_PROPERTY_DATA *data) { BACNET_OBJECT_PROPERTY_VALUE object_value; /* for bacapp printing */ - BACNET_APPLICATION_DATA_VALUE value; /* for decode value data */ + BACNET_APPLICATION_DATA_VALUE value; /* for decode value data */ int len = 0; uint8_t *application_data; int application_data_len; @@ -111,9 +109,10 @@ void rp_ack_print_data(BACNET_READ_PROPERTY_DATA *data) * @param service_data [in] The BACNET_CONFIRMED_SERVICE_DATA information * decoded from the APDU header of this message. */ -void handler_read_property_ack(uint8_t *service_request, uint16_t service_len, - BACNET_ADDRESS *src, - BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data) +void handler_read_property_ack(uint8_t *service_request, + uint16_t service_len, + BACNET_ADDRESS *src, + BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data) { int len = 0; BACNET_READ_PROPERTY_DATA data; @@ -124,8 +123,9 @@ void handler_read_property_ack(uint8_t *service_request, uint16_t service_len, #if 0 fprintf(stderr, "Received Read-Property Ack!\n"); #endif - if (len > 0) + if (len > 0) { rp_ack_print_data(&data); + } } /** Decode the received RP data into a linked list of the results, with the diff --git a/src/bacnet/basic/service/h_rp_a.h b/src/bacnet/basic/service/h_rp_a.h new file mode 100644 index 00000000..5f64d5e0 --- /dev/null +++ b/src/bacnet/basic/service/h_rp_a.h @@ -0,0 +1,55 @@ +/** +* @file +* @author Steve Karg +* @date October 2019 +* @brief Header file for a basic ReadProperty-Ack service handler +* +* @section LICENSE +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +#ifndef HANDLER_READ_PROPERTY_ACK_H +#define HANDLER_READ_PROPERTY_ACK_H + +#include +#include +#include +#include +#include "bacnet/bacdef.h" +#include "bacnet/bacenum.h" +#include "bacnet/apdu.h" +#include "bacnet/rp.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + void handler_read_property_ack( + uint8_t * service_request, + uint16_t service_len, + BACNET_ADDRESS * src, + BACNET_CONFIRMED_SERVICE_ACK_DATA * service_data); + void rp_ack_print_data( + BACNET_READ_PROPERTY_DATA * data); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/demo/handler/h_rpm.c b/src/bacnet/basic/service/h_rpm.c similarity index 82% rename from demo/handler/h_rpm.c rename to src/bacnet/basic/service/h_rpm.c index 249a681e..15f31e40 100644 --- a/demo/handler/h_rpm.c +++ b/src/bacnet/basic/service/h_rpm.c @@ -29,28 +29,30 @@ #include #include #include -#include "config.h" -#include "txbuf.h" -#include "memcopy.h" -#include "bacdef.h" -#include "bacdcode.h" -#include "apdu.h" -#include "npdu.h" -#include "abort.h" -#include "reject.h" -#include "bacerror.h" -#include "rpm.h" -#include "handlers.h" -/* device object has custom handler for all objects */ -#include "device.h" +#include "bacnet/config.h" +#include "bacnet/memcopy.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/apdu.h" +#include "bacnet/npdu.h" +#include "bacnet/abort.h" +#include "bacnet/reject.h" +#include "bacnet/bacerror.h" +#include "bacnet/rpm.h" +/* basic objects, services, TSM, and datalink */ +#include "bacnet/basic/object/device.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/basic/services.h" +#include "bacnet/datalink/datalink.h" /** @file h_rpm.c Handles Read Property Multiple requests. */ -static uint8_t Temp_Buf[MAX_APDU] = {0}; +static uint8_t Temp_Buf[MAX_APDU] = { 0 }; static BACNET_PROPERTY_ID RPM_Object_Property( struct special_property_list_t *pPropertyList, - BACNET_PROPERTY_ID special_property, unsigned index) + BACNET_PROPERTY_ID special_property, + unsigned index) { int property = -1; /* return value */ unsigned required, optional, proprietary; @@ -89,7 +91,7 @@ static unsigned RPM_Object_Property_Count( if (special_property == PROP_ALL) { count = pPropertyList->Required.count + pPropertyList->Optional.count + - pPropertyList->Proprietary.count; + pPropertyList->Proprietary.count; } else if (special_property == PROP_REQUIRED) { count = pPropertyList->Required.count; } else if (special_property == PROP_OPTIONAL) { @@ -101,8 +103,8 @@ static unsigned RPM_Object_Property_Count( /** Encode the RPM property returning the length of the encoding, or 0 if there is no room to fit the encoding. */ -static int RPM_Encode_Property(uint8_t *apdu, uint16_t offset, - uint16_t max_apdu, BACNET_RPM_DATA *rpmdata) +static int RPM_Encode_Property( + uint8_t *apdu, uint16_t offset, uint16_t max_apdu, BACNET_RPM_DATA *rpmdata) { int len = 0; size_t copy_len = 0; @@ -177,8 +179,9 @@ static int RPM_Encode_Property(uint8_t *apdu, uint16_t offset, * decoded from the APDU header of this message. */ void handler_read_property_multiple(uint8_t *service_request, - uint16_t service_len, BACNET_ADDRESS *src, - BACNET_CONFIRMED_SERVICE_DATA *service_data) + uint16_t service_len, + BACNET_ADDRESS *src, + BACNET_CONFIRMED_SERVICE_DATA *service_data) { int len = 0; uint16_t copy_len = 0; @@ -198,8 +201,8 @@ void handler_read_property_multiple(uint8_t *service_request, /* encode the NPDU portion of the packet */ datalink_get_my_address(&my_address); npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL); - npdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address, - &npdu_data); + npdu_len = npdu_encode_pdu( + &Handler_Transmit_Buffer[0], src, &my_address, &npdu_data); if (service_data->segmented_message) { rpmdata.error_code = ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED; error = BACNET_STATUS_ABORT; @@ -210,12 +213,12 @@ void handler_read_property_multiple(uint8_t *service_request, } /* decode apdu request & encode apdu reply encode complex ack, invoke id, service choice */ - apdu_len = rpm_ack_encode_apdu_init(&Handler_Transmit_Buffer[npdu_len], - service_data->invoke_id); + apdu_len = rpm_ack_encode_apdu_init( + &Handler_Transmit_Buffer[npdu_len], service_data->invoke_id); for (;;) { /* Start by looking for an object ID */ - len = rpm_decode_object_id(&service_request[decode_len], - service_len - decode_len, &rpmdata); + len = rpm_decode_object_id( + &service_request[decode_len], service_len - decode_len, &rpmdata); if (len >= 0) { /* Got one so skip to next stage */ decode_len += len; @@ -237,7 +240,7 @@ void handler_read_property_multiple(uint8_t *service_request, /* Stick this object id into the reply - if it will fit */ len = rpm_ack_encode_apdu_object_begin(&Temp_Buf[0], &rpmdata); copy_len = memcopy(&Handler_Transmit_Buffer[npdu_len], &Temp_Buf[0], - apdu_len, len, MAX_APDU); + apdu_len, len, MAX_APDU); if (copy_len == 0) { #if PRINT_ENABLED fprintf(stderr, "RPM: Response too big!\r\n"); @@ -251,9 +254,8 @@ void handler_read_property_multiple(uint8_t *service_request, /* do each property of this object of the RPM request */ for (;;) { /* Fetch a property */ - len = - rpm_decode_object_property(&service_request[decode_len], - service_len - decode_len, &rpmdata); + len = rpm_decode_object_property(&service_request[decode_len], + service_len - decode_len, &rpmdata); if (len < 0) { /* bad encoding - skip to error/reject/abort handling */ #if PRINT_ENABLED @@ -275,15 +277,14 @@ void handler_read_property_multiple(uint8_t *service_request, if (rpmdata.array_index != BACNET_ARRAY_ALL) { /* No array index options for this special property. Encode error for this object property response */ - len = rpm_ack_encode_apdu_object_property( - &Temp_Buf[0], rpmdata.object_property, - rpmdata.array_index); + len = rpm_ack_encode_apdu_object_property(&Temp_Buf[0], + rpmdata.object_property, rpmdata.array_index); copy_len = memcopy(&Handler_Transmit_Buffer[npdu_len], - &Temp_Buf[0], apdu_len, len, MAX_APDU); + &Temp_Buf[0], apdu_len, len, MAX_APDU); if (copy_len == 0) { #if PRINT_ENABLED - fprintf(stderr, - "RPM: Too full to encode property!\r\n"); + fprintf( + stderr, "RPM: Too full to encode property!\r\n"); #endif rpmdata.error_code = ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED; @@ -295,7 +296,7 @@ void handler_read_property_multiple(uint8_t *service_request, &Temp_Buf[0], ERROR_CLASS_PROPERTY, ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY); copy_len = memcopy(&Handler_Transmit_Buffer[npdu_len], - &Temp_Buf[0], apdu_len, len, MAX_APDU); + &Temp_Buf[0], apdu_len, len, MAX_APDU); if (copy_len == 0) { #if PRINT_ENABLED fprintf(stderr, "RPM: Too full to encode error!\r\n"); @@ -309,8 +310,7 @@ void handler_read_property_multiple(uint8_t *service_request, } else { special_object_property = rpmdata.object_property; Device_Objects_Property_List(rpmdata.object_type, - rpmdata.object_instance, - &property_list); + rpmdata.object_instance, &property_list); property_count = RPM_Object_Property_Count( &property_list, special_object_property); if (property_count == 0) { @@ -331,8 +331,8 @@ void handler_read_property_multiple(uint8_t *service_request, apdu_len += len; } else { #if PRINT_ENABLED - fprintf(stderr, - "RPM: Too full for property!\r\n"); + fprintf( + stderr, "RPM: Too full for property!\r\n"); #endif error = len; goto RPM_FAILURE; @@ -342,15 +342,14 @@ void handler_read_property_multiple(uint8_t *service_request, } } else { /* handle an individual property */ - len = - RPM_Encode_Property(&Handler_Transmit_Buffer[npdu_len], - (uint16_t)apdu_len, MAX_APDU, &rpmdata); + len = RPM_Encode_Property(&Handler_Transmit_Buffer[npdu_len], + (uint16_t)apdu_len, MAX_APDU, &rpmdata); if (len > 0) { apdu_len += len; } else { #if PRINT_ENABLED - fprintf(stderr, - "RPM: Too full for individual property!\r\n"); + fprintf( + stderr, "RPM: Too full for individual property!\r\n"); #endif error = len; goto RPM_FAILURE; @@ -361,7 +360,7 @@ void handler_read_property_multiple(uint8_t *service_request, decode_len++; len = rpm_ack_encode_apdu_object_end(&Temp_Buf[0]); copy_len = memcopy(&Handler_Transmit_Buffer[npdu_len], - &Temp_Buf[0], apdu_len, len, MAX_APDU); + &Temp_Buf[0], apdu_len, len, MAX_APDU); if (copy_len == 0) { #if PRINT_ENABLED fprintf(stderr, "RPM: Too full to encode object end!\r\n"); @@ -395,23 +394,22 @@ void handler_read_property_multiple(uint8_t *service_request, RPM_FAILURE: if (error) { if (error == BACNET_STATUS_ABORT) { - apdu_len = abort_encode_apdu( - &Handler_Transmit_Buffer[npdu_len], service_data->invoke_id, + apdu_len = abort_encode_apdu(&Handler_Transmit_Buffer[npdu_len], + service_data->invoke_id, abort_convert_error_code(rpmdata.error_code), true); #if PRINT_ENABLED fprintf(stderr, "RPM: Sending Abort!\n"); #endif } else if (error == BACNET_STATUS_ERROR) { - apdu_len = bacerror_encode_apdu( - &Handler_Transmit_Buffer[npdu_len], service_data->invoke_id, - SERVICE_CONFIRMED_READ_PROP_MULTIPLE, rpmdata.error_class, - rpmdata.error_code); + apdu_len = bacerror_encode_apdu(&Handler_Transmit_Buffer[npdu_len], + service_data->invoke_id, SERVICE_CONFIRMED_READ_PROP_MULTIPLE, + rpmdata.error_class, rpmdata.error_code); #if PRINT_ENABLED fprintf(stderr, "RPM: Sending Error!\n"); #endif } else if (error == BACNET_STATUS_REJECT) { - apdu_len = reject_encode_apdu( - &Handler_Transmit_Buffer[npdu_len], service_data->invoke_id, + apdu_len = reject_encode_apdu(&Handler_Transmit_Buffer[npdu_len], + service_data->invoke_id, reject_convert_error_code(rpmdata.error_code)); #if PRINT_ENABLED fprintf(stderr, "RPM: Sending Reject!\n"); @@ -420,8 +418,8 @@ RPM_FAILURE: } pdu_len = apdu_len + npdu_len; - bytes_sent = datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0], - pdu_len); + bytes_sent = datalink_send_pdu( + src, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len); if (bytes_sent <= 0) { #if PRINT_ENABLED fprintf(stderr, "RPM: Failed to send PDU (%s)!\n", strerror(errno)); diff --git a/src/bacnet/basic/service/h_rpm.h b/src/bacnet/basic/service/h_rpm.h new file mode 100644 index 00000000..944fc7f1 --- /dev/null +++ b/src/bacnet/basic/service/h_rpm.h @@ -0,0 +1,52 @@ +/** +* @file +* @author Steve Karg +* @date October 2019 +* @brief Header file for a basic ReadPropertyMultiple service handler +* +* @section LICENSE +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +#ifndef HANDLER_READ_PROPERTY_MULTIPLE_H +#define HANDLER_READ_PROPERTY_MULTIPLE_H + +#include +#include +#include +#include +#include "bacnet/bacdef.h" +#include "bacnet/bacenum.h" +#include "bacnet/apdu.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + void handler_read_property_multiple( + uint8_t * service_request, + uint16_t service_len, + BACNET_ADDRESS * src, + BACNET_CONFIRMED_SERVICE_DATA * service_data); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/demo/handler/h_rpm_a.c b/src/bacnet/basic/service/h_rpm_a.c similarity index 86% rename from demo/handler/h_rpm_a.c rename to src/bacnet/basic/service/h_rpm_a.c index 36709d9a..16c1b813 100644 --- a/demo/handler/h_rpm_a.c +++ b/src/bacnet/basic/service/h_rpm_a.c @@ -26,21 +26,19 @@ #include #include #include -#include "config.h" -#include "txbuf.h" -#include "bacdef.h" -#include "bacdcode.h" -#include "address.h" -#include "tsm.h" -#include "npdu.h" -#include "apdu.h" -#include "device.h" -#include "datalink.h" -#include "bactext.h" -#include "rpm.h" +#include "bacnet/config.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/basic/binding/address.h" +#include "bacnet/npdu.h" +#include "bacnet/apdu.h" +#include "bacnet/datalink/datalink.h" +#include "bacnet/bactext.h" +#include "bacnet/rpm.h" /* some demo stuff needed */ -#include "handlers.h" -#include "txbuf.h" +#include "bacnet/basic/object/device.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/tsm/tsm.h" /** @file h_rpm_a.c Handles Read Property Multiple Acknowledgments. */ @@ -53,14 +51,14 @@ * where the RPM data is to be stored. * @return The number of bytes decoded, or -1 on error */ -int rpm_ack_decode_service_request(uint8_t *apdu, int apdu_len, - BACNET_READ_ACCESS_DATA *read_access_data) +int rpm_ack_decode_service_request( + uint8_t *apdu, int apdu_len, BACNET_READ_ACCESS_DATA *read_access_data) { - int decoded_len = 0; /* return value */ + int decoded_len = 0; /* return value */ uint32_t error_value = 0; /* decoded error value */ - int len = 0; /* number of bytes returned from decoding */ - uint8_t tag_number = 0; /* decoded tag number */ - uint32_t len_value = 0; /* decoded length value */ + int len = 0; /* number of bytes returned from decoding */ + uint8_t tag_number = 0; /* decoded tag number */ + uint32_t len_value = 0; /* decoded length value */ BACNET_READ_ACCESS_DATA *rpm_object; BACNET_READ_ACCESS_DATA *old_rpm_object; BACNET_PROPERTY_REFERENCE *rpm_property; @@ -73,7 +71,7 @@ int rpm_ack_decode_service_request(uint8_t *apdu, int apdu_len, old_rpm_object = rpm_object; while (rpm_object && apdu_len) { len = rpm_ack_decode_object_id(apdu, apdu_len, &rpm_object->object_type, - &rpm_object->object_instance); + &rpm_object->object_instance); if (len <= 0) { old_rpm_object->next = NULL; free(rpm_object); @@ -86,8 +84,8 @@ int rpm_ack_decode_service_request(uint8_t *apdu, int apdu_len, rpm_object->listOfProperties = rpm_property; old_rpm_property = rpm_property; while (rpm_property && apdu_len) { - len = rpm_ack_decode_object_property( - apdu, apdu_len, &rpm_property->propertyIdentifier, + len = rpm_ack_decode_object_property(apdu, apdu_len, + &rpm_property->propertyIdentifier, &rpm_property->propertyArrayIndex); if (len <= 0) { old_rpm_property->next = NULL; @@ -113,12 +111,11 @@ int rpm_ack_decode_service_request(uint8_t *apdu, int apdu_len, old_value = value; while (value && (apdu_len > 0)) { if (IS_CONTEXT_SPECIFIC(*apdu)) { - len = bacapp_decode_context_data( - apdu, apdu_len, value, + len = bacapp_decode_context_data(apdu, apdu_len, value, rpm_property->propertyIdentifier); } else { - len = bacapp_decode_application_data(apdu, apdu_len, - value); + len = bacapp_decode_application_data( + apdu, apdu_len, value); } /* If len == 0 then it's an empty structure, which is OK. */ if (len < 0) { @@ -206,8 +203,8 @@ void rpm_ack_print_data(BACNET_READ_ACCESS_DATA *rpm_data) if (rpm_data) { #if PRINT_ENABLED fprintf(stdout, "%s #%lu\r\n", - bactext_object_type_name(rpm_data->object_type), - (unsigned long)rpm_data->object_instance); + bactext_object_type_name(rpm_data->object_type), + (unsigned long)rpm_data->object_instance); fprintf(stdout, "{\r\n"); #endif listOfProperties = rpm_data->listOfProperties; @@ -215,11 +212,11 @@ void rpm_ack_print_data(BACNET_READ_ACCESS_DATA *rpm_data) #if PRINT_ENABLED if (listOfProperties->propertyIdentifier < 512) { fprintf(stdout, " %s: ", - bactext_property_name( - listOfProperties->propertyIdentifier)); + bactext_property_name( + listOfProperties->propertyIdentifier)); } else { fprintf(stdout, " proprietary %u: ", - (unsigned)listOfProperties->propertyIdentifier); + (unsigned)listOfProperties->propertyIdentifier); } #endif if (listOfProperties->propertyArrayIndex != BACNET_ARRAY_ALL) { @@ -263,10 +260,10 @@ void rpm_ack_print_data(BACNET_READ_ACCESS_DATA *rpm_data) #if PRINT_ENABLED /* AccessError */ fprintf(stdout, "BACnet Error: %s: %s\r\n", - bactext_error_class_name( - (int)listOfProperties->error.error_class), - bactext_error_code_name( - (int)listOfProperties->error.error_code)); + bactext_error_class_name( + (int)listOfProperties->error.error_class), + bactext_error_code_name( + (int)listOfProperties->error.error_code)); #endif } listOfProperties = listOfProperties->next; @@ -288,8 +285,9 @@ void rpm_ack_print_data(BACNET_READ_ACCESS_DATA *rpm_data) * @param service_data [in] The BACNET_CONFIRMED_SERVICE_DATA information * decoded from the APDU header of this message. */ -void handler_read_property_multiple_ack( - uint8_t *service_request, uint16_t service_len, BACNET_ADDRESS *src, +void handler_read_property_multiple_ack(uint8_t *service_request, + uint16_t service_len, + BACNET_ADDRESS *src, BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data) { int len = 0; @@ -305,8 +303,8 @@ void handler_read_property_multiple_ack( rpm_data = calloc(1, sizeof(BACNET_READ_ACCESS_DATA)); if (rpm_data) { - len = rpm_ack_decode_service_request(service_request, service_len, - rpm_data); + len = rpm_ack_decode_service_request( + service_request, service_len, rpm_data); } #if 1 fprintf(stderr, "Received Read-Property-Multiple Ack!\n"); diff --git a/src/bacnet/basic/service/h_rpm_a.h b/src/bacnet/basic/service/h_rpm_a.h new file mode 100644 index 00000000..37f34440 --- /dev/null +++ b/src/bacnet/basic/service/h_rpm_a.h @@ -0,0 +1,59 @@ +/** +* @file +* @author Steve Karg +* @date October 2019 +* @brief Header file for a basic ReadPropertyMultiple-Ack service handler +* +* @section LICENSE +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +#ifndef HANDLER_READ_PROPERTY_MULTIPLE_ACK_H +#define HANDLER_READ_PROPERTY_MULTIPLE_ACK_H + +#include +#include +#include +#include +#include "bacnet/bacdef.h" +#include "bacnet/bacenum.h" +#include "bacnet/apdu.h" +#include "bacnet/rpm.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + void handler_read_property_multiple_ack( + uint8_t * service_request, + uint16_t service_len, + BACNET_ADDRESS * src, + BACNET_CONFIRMED_SERVICE_ACK_DATA * service_data); + int rpm_ack_decode_service_request( + uint8_t * apdu, + int apdu_len, + BACNET_READ_ACCESS_DATA * read_access_data); + void rpm_ack_print_data( + BACNET_READ_ACCESS_DATA * rpm_data); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/demo/handler/h_rr.c b/src/bacnet/basic/service/h_rr.c similarity index 75% rename from demo/handler/h_rr.c rename to src/bacnet/basic/service/h_rr.c index 34eae446..75fe0772 100644 --- a/demo/handler/h_rr.c +++ b/src/bacnet/basic/service/h_rr.c @@ -27,25 +27,27 @@ #include #include #include -#include "config.h" -#include "txbuf.h" -#include "bacdef.h" -#include "bacdcode.h" -#include "bacerror.h" -#include "apdu.h" -#include "npdu.h" -#include "abort.h" -#include "readrange.h" -#include "device.h" -#include "handlers.h" +#include "bacnet/config.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacerror.h" +#include "bacnet/apdu.h" +#include "bacnet/npdu.h" +#include "bacnet/abort.h" +#include "bacnet/readrange.h" +/* basic objects, services, TSM, and datalink */ +#include "bacnet/basic/object/device.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/basic/services.h" +#include "bacnet/datalink/datalink.h" /** @file h_rr.c Handles Read Range requests. */ -static uint8_t Temp_Buf[MAX_APDU] = {0}; +static uint8_t Temp_Buf[MAX_APDU] = { 0 }; /* Encodes the property APDU and returns the length, or sets the error, and returns -1 */ -static int Encode_RR_payload(uint8_t* apdu, BACNET_READ_RANGE_DATA* pRequest) +static int Encode_RR_payload(uint8_t *apdu, BACNET_READ_RANGE_DATA *pRequest) { int apdu_len = -1; rr_info_function info_fn_ptr = NULL; @@ -64,25 +66,24 @@ static int Encode_RR_payload(uint8_t* apdu, BACNET_READ_RANGE_DATA* pRequest) if ((pRequest->RequestType == RR_BY_POSITION) && (pRequest->Range.RefIndex == - 0)) { /* First index is 1 so can't accept 0 */ + 0)) { /* First index is 1 so can't accept 0 */ pRequest->error_code = ERROR_CODE_OTHER; /* I couldn't see anything more appropriate so... */ } else if (((PropInfo.RequestTypes & RR_ARRAY_OF_LISTS) == 0) && - (pRequest->array_index != 0) && - (pRequest->array_index != BACNET_ARRAY_ALL)) { + (pRequest->array_index != 0) && + (pRequest->array_index != BACNET_ARRAY_ALL)) { /* Array access attempted on a non array property */ pRequest->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY; } else if ((pRequest->RequestType != RR_READ_ALL) && - ((PropInfo.RequestTypes & pRequest->RequestType) == 0)) { + ((PropInfo.RequestTypes & pRequest->RequestType) == 0)) { /* By Time or By Sequence not supported - By Position is always * required */ pRequest->error_code = ERROR_CODE_OTHER; /* I couldn't see anything more appropriate so... */ } else if ((pRequest->Count == 0) && - (pRequest->RequestType != - RR_READ_ALL)) { /* Count cannot be zero */ + (pRequest->RequestType != RR_READ_ALL)) { /* Count cannot be zero */ pRequest->error_code = ERROR_CODE_OTHER; /* I couldn't see anything more appropriate so... */ @@ -98,9 +99,10 @@ static int Encode_RR_payload(uint8_t* apdu, BACNET_READ_RANGE_DATA* pRequest) return apdu_len; } -void handler_read_range(uint8_t* service_request, uint16_t service_len, - BACNET_ADDRESS* src, - BACNET_CONFIRMED_SERVICE_DATA* service_data) +void handler_read_range(uint8_t *service_request, + uint16_t service_len, + BACNET_ADDRESS *src, + BACNET_CONFIRMED_SERVICE_DATA *service_data) { BACNET_READ_RANGE_DATA data; int len = 0; @@ -115,13 +117,13 @@ void handler_read_range(uint8_t* service_request, uint16_t service_len, /* encode the NPDU portion of the packet */ datalink_get_my_address(&my_address); npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL); - pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address, - &npdu_data); + pdu_len = npdu_encode_pdu( + &Handler_Transmit_Buffer[0], src, &my_address, &npdu_data); if (service_data->segmented_message) { /* we don't support segmentation - send an abort */ len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], - service_data->invoke_id, - ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true); + service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, + true); #if PRINT_ENABLED fprintf(stderr, "RR: Segmented message. Sending Abort!\n"); #endif @@ -136,8 +138,7 @@ void handler_read_range(uint8_t* service_request, uint16_t service_len, if (len < 0) { /* bad decoding - send an abort */ len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], - service_data->invoke_id, ABORT_REASON_OTHER, - true); + service_data->invoke_id, ABORT_REASON_OTHER, true); #if PRINT_ENABLED fprintf(stderr, "RR: Bad Encoding. Sending Abort!\n"); #endif @@ -152,8 +153,8 @@ void handler_read_range(uint8_t* service_request, uint16_t service_len, data.application_data = &Temp_Buf[0]; data.application_data_len = len; /* FIXME: probably need a length limitation sent with encode */ - len = rr_ack_encode_apdu(&Handler_Transmit_Buffer[pdu_len], - service_data->invoke_id, &data); + len = rr_ack_encode_apdu( + &Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, &data); #if PRINT_ENABLED fprintf(stderr, "RR: Sending Ack!\n"); #endif @@ -162,17 +163,16 @@ void handler_read_range(uint8_t* service_request, uint16_t service_len, if (error) { if (len == -2) { /* BACnet APDU too small to fit data, so proper response is Abort */ - len = abort_encode_apdu( - &Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, + len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], + service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true); #if PRINT_ENABLED fprintf(stderr, "RR: Reply too big to fit into APDU!\n"); #endif } else { len = bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], - service_data->invoke_id, - SERVICE_CONFIRMED_READ_RANGE, - data.error_class, data.error_code); + service_data->invoke_id, SERVICE_CONFIRMED_READ_RANGE, + data.error_class, data.error_code); #if PRINT_ENABLED fprintf(stderr, "RR: Sending Error!\n"); #endif @@ -180,8 +180,8 @@ void handler_read_range(uint8_t* service_request, uint16_t service_len, } RR_ABORT: pdu_len += len; - bytes_sent = datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0], - pdu_len); + bytes_sent = datalink_send_pdu( + src, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len); #if PRINT_ENABLED if (bytes_sent <= 0) fprintf(stderr, "Failed to send PDU (%s)!\n", strerror(errno)); diff --git a/src/bacnet/basic/service/h_rr.h b/src/bacnet/basic/service/h_rr.h new file mode 100644 index 00000000..a8ec9dd4 --- /dev/null +++ b/src/bacnet/basic/service/h_rr.h @@ -0,0 +1,52 @@ +/** +* @file +* @author Steve Karg +* @date October 2019 +* @brief Header file for a basic ReadRange service handler +* +* @section LICENSE +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +#ifndef HANDLER_READ_RANGE_H +#define HANDLER_READ_RANGE_H + +#include +#include +#include +#include +#include "bacnet/bacdef.h" +#include "bacnet/bacenum.h" +#include "bacnet/apdu.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + void handler_read_range( + uint8_t * service_request, + uint16_t service_len, + BACNET_ADDRESS * src, + BACNET_CONFIRMED_SERVICE_DATA * service_data); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/demo/handler/h_rr_a.c b/src/bacnet/basic/service/h_rr_a.c similarity index 85% rename from demo/handler/h_rr_a.c rename to src/bacnet/basic/service/h_rr_a.c index 6be06e23..63e7de06 100644 --- a/demo/handler/h_rr_a.c +++ b/src/bacnet/basic/service/h_rr_a.c @@ -24,21 +24,18 @@ *********************************************************************/ #include #include -#include "config.h" -#include "txbuf.h" -#include "bacdef.h" -#include "bacdcode.h" -#include "address.h" -#include "tsm.h" -#include "npdu.h" -#include "apdu.h" -#include "device.h" -#include "datalink.h" -#include "bactext.h" -#include "readrange.h" +#include "bacnet/config.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/basic/binding/address.h" +#include "bacnet/npdu.h" +#include "bacnet/apdu.h" +#include "bacnet/bactext.h" +#include "bacnet/readrange.h" /* some demo stuff needed */ -#include "handlers.h" -#include "txbuf.h" +#include "bacnet/basic/object/device.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/tsm/tsm.h" /** @file h_rr_a.c Handles Read Range Acknowledgments. */ @@ -46,7 +43,7 @@ static void PrintReadRangeData(BACNET_READ_RANGE_DATA *data) { BACNET_OBJECT_PROPERTY_VALUE object_value; /* for bacapp printing */ - BACNET_APPLICATION_DATA_VALUE value; /* for decode value data */ + BACNET_APPLICATION_DATA_VALUE value; /* for decode value data */ int len = 0; uint8_t *application_data; int application_data_len; @@ -97,9 +94,10 @@ static void PrintReadRangeData(BACNET_READ_RANGE_DATA *data) } } -void handler_read_range_ack(uint8_t *service_request, uint16_t service_len, - BACNET_ADDRESS *src, - BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data) +void handler_read_range_ack(uint8_t *service_request, + uint16_t service_len, + BACNET_ADDRESS *src, + BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data) { int len = 0; BACNET_READ_RANGE_DATA data; @@ -112,6 +110,7 @@ void handler_read_range_ack(uint8_t *service_request, uint16_t service_len, fprintf(stderr, "Received ReadRange Ack!\n"); #endif - if (len > 0) + if (len > 0) { PrintReadRangeData(&data); + } } diff --git a/src/bacnet/basic/service/h_rr_a.h b/src/bacnet/basic/service/h_rr_a.h new file mode 100644 index 00000000..a2078086 --- /dev/null +++ b/src/bacnet/basic/service/h_rr_a.h @@ -0,0 +1,52 @@ +/** +* @file +* @author Steve Karg +* @date October 2019 +* @brief Header file for a basic ReadRange-Ack service handler +* +* @section LICENSE +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +#ifndef HANDLER_READ_RANGE_ACK_H +#define HANDLER_READ_RANGE_ACK_H + +#include +#include +#include +#include +#include "bacnet/bacdef.h" +#include "bacnet/bacenum.h" +#include "bacnet/apdu.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + void handler_read_range_ack( + uint8_t * service_request, + uint16_t service_len, + BACNET_ADDRESS * src, + BACNET_CONFIRMED_SERVICE_ACK_DATA * service_data); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/demo/handler/h_ts.c b/src/bacnet/basic/service/h_ts.c similarity index 86% rename from demo/handler/h_ts.c rename to src/bacnet/basic/service/h_ts.c index 47a8d023..e24443ef 100644 --- a/demo/handler/h_ts.c +++ b/src/bacnet/basic/service/h_ts.c @@ -25,15 +25,16 @@ #include #include #include -#include "config.h" -#include "device.h" -#include "datetime.h" -#include "bacdef.h" -#include "bacdcode.h" -#include "timesync.h" -#include "handlers.h" -#include "client.h" -#include "bacaddr.h" +#include "bacnet/config.h" +#include "bacnet/datetime.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/timesync.h" +#include "bacnet/bacaddr.h" +#include "bacnet/npdu.h" +#include "bacnet/basic/object/device.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/tsm/tsm.h" /** @file h_ts.c Handles TimeSync requests. */ @@ -64,17 +65,17 @@ static void show_bacnet_date_time(BACNET_DATE *bdate, BACNET_TIME *btime) } #endif -void handler_timesync(uint8_t *service_request, uint16_t service_len, - BACNET_ADDRESS *src) +void handler_timesync( + uint8_t *service_request, uint16_t service_len, BACNET_ADDRESS *src) { int len = 0; - BACNET_DATE bdate = {0}; - BACNET_TIME btime = {0}; + BACNET_DATE bdate = { 0 }; + BACNET_TIME btime = { 0 }; (void)src; (void)service_len; - len = timesync_decode_service_request(service_request, service_len, &bdate, - &btime); + len = timesync_decode_service_request( + service_request, service_len, &bdate, &btime); if (len > 0) { if (datetime_is_valid(&bdate, &btime)) { /* fixme: only set the time if off by some amount */ @@ -91,8 +92,8 @@ void handler_timesync(uint8_t *service_request, uint16_t service_len, return; } -void handler_timesync_utc(uint8_t *service_request, uint16_t service_len, - BACNET_ADDRESS *src) +void handler_timesync_utc( + uint8_t *service_request, uint16_t service_len, BACNET_ADDRESS *src) { int len = 0; BACNET_DATE bdate; @@ -100,8 +101,8 @@ void handler_timesync_utc(uint8_t *service_request, uint16_t service_len, (void)src; (void)service_len; - len = timesync_decode_service_request(service_request, service_len, &bdate, - &btime); + len = timesync_decode_service_request( + service_request, service_len, &bdate, &btime); if (len > 0) { if (datetime_is_valid(&bdate, &btime)) { #if PRINT_ENABLED @@ -132,8 +133,8 @@ void handler_timesync_utc(uint8_t *service_request, uint16_t service_len, */ int handler_timesync_encode_recipients(uint8_t *apdu, int max_apdu) { - return timesync_encode_timesync_recipients(apdu, max_apdu, - &Time_Sync_Recipients[0]); + return timesync_encode_timesync_recipients( + apdu, max_apdu, &Time_Sync_Recipients[0]); } #endif @@ -160,8 +161,7 @@ static void handler_timesync_send(BACNET_DATE_TIME *current_date_time) if (Time_Sync_Recipients[index].tag == 1) { if (status) { Send_TimeSync_Remote(&Time_Sync_Recipients[index].type.address, - ¤t_date_time->date, - ¤t_date_time->time); + ¤t_date_time->date, ¤t_date_time->time); } } } @@ -169,8 +169,8 @@ static void handler_timesync_send(BACNET_DATE_TIME *current_date_time) #endif #if defined(BACNET_TIME_MASTER) -static void handler_timesync_update(uint32_t device_interval, - BACNET_DATE_TIME *current_date_time) +static void handler_timesync_update( + uint32_t device_interval, BACNET_DATE_TIME *current_date_time) { uint32_t current_minutes = 0; uint32_t next_minutes = 0; @@ -228,8 +228,8 @@ static void handler_timesync_update(uint32_t device_interval, #endif #if defined(BACNET_TIME_MASTER) -bool handler_timesync_recipient_address_set(unsigned index, - BACNET_ADDRESS *address) +bool handler_timesync_recipient_address_set( + unsigned index, BACNET_ADDRESS *address) { bool status = false; diff --git a/src/bacnet/basic/service/h_ts.h b/src/bacnet/basic/service/h_ts.h new file mode 100644 index 00000000..789ac720 --- /dev/null +++ b/src/bacnet/basic/service/h_ts.h @@ -0,0 +1,75 @@ +/** +* @file +* @author Steve Karg +* @date October 2019 +* @brief Header file for a basic TimeSynchronization service handler +* +* @section LICENSE +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +#ifndef HANDLER_TIME_SYNCHRONIZATION_H +#define HANDLER_TIME_SYNCHRONIZATION_H + +#include +#include +#include +#include +#include "bacnet/bacdef.h" +#include "bacnet/bacenum.h" +#include "bacnet/apdu.h" +#include "bacnet/datetime.h" +#include "bacnet/wp.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + /* time synchronization handlers */ + void handler_timesync( + uint8_t * service_request, + uint16_t service_len, + BACNET_ADDRESS * src); + void handler_timesync_utc( + uint8_t * service_request, + uint16_t service_len, + BACNET_ADDRESS * src); + /* time sync master features */ + int handler_timesync_encode_recipients( + uint8_t * apdu, + int max_apdu); + void handler_timesync_task(BACNET_DATE_TIME *bdatetime); + void handler_timesync_init(void); + bool handler_timesync_recipient_write( + BACNET_WRITE_PROPERTY_DATA * wp_data); + uint32_t handler_timesync_interval(void); + bool handler_timesync_interval_set(uint32_t minutes); + uint32_t handler_timesync_interval_offset(void); + bool handler_timesync_interval_offset_set(uint32_t minutes); + bool handler_timesync_interval_align(void); + bool handler_timesync_interval_align_set(bool flag); + bool handler_timesync_recipient_address_set( + unsigned index, + BACNET_ADDRESS * address); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/demo/handler/h_ucov.c b/src/bacnet/basic/service/h_ucov.c similarity index 85% rename from demo/handler/h_ucov.c rename to src/bacnet/basic/service/h_ucov.c index 65841bd1..a890898e 100644 --- a/demo/handler/h_ucov.c +++ b/src/bacnet/basic/service/h_ucov.c @@ -27,17 +27,16 @@ #include #include #include -#include "config.h" -#include "txbuf.h" -#include "bacdef.h" -#include "bacdcode.h" -#include "apdu.h" -#include "npdu.h" -#include "abort.h" -/* special for this module */ -#include "cov.h" -#include "bactext.h" -#include "handlers.h" +#include "bacnet/config.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/apdu.h" +#include "bacnet/npdu.h" +#include "bacnet/abort.h" +#include "bacnet/cov.h" +#include "bacnet/bactext.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/tsm/tsm.h" #ifndef MAX_COV_PROPERTIES #define MAX_COV_PROPERTIES 2 @@ -57,8 +56,8 @@ * @param service_len [in] The length of the service_request. * @param src [in] BACNET_ADDRESS of the source of the message (unused) */ -void handler_ucov_notification(uint8_t *service_request, uint16_t service_len, - BACNET_ADDRESS *src) +void handler_ucov_notification( + uint8_t *service_request, uint16_t service_len, BACNET_ADDRESS *src) { BACNET_COV_DATA cov_data; BACNET_PROPERTY_VALUE property_value[MAX_COV_PROPERTIES]; @@ -75,14 +74,13 @@ void handler_ucov_notification(uint8_t *service_request, uint16_t service_len, fprintf(stderr, "UCOV: Received Notification!\n"); #endif /* decode the service request only */ - len = cov_notify_decode_service_request(service_request, service_len, - &cov_data); + len = cov_notify_decode_service_request( + service_request, service_len, &cov_data); #if PRINT_ENABLED if (len > 0) { fprintf(stderr, "UCOV: PID=%u ", cov_data.subscriberProcessIdentifier); fprintf(stderr, "instance=%u ", cov_data.initiatingDeviceIdentifier); - fprintf( - stderr, "%s %u ", + fprintf(stderr, "%s %u ", bactext_object_type_name(cov_data.monitoredObjectIdentifier.type), cov_data.monitoredObjectIdentifier.instance); fprintf(stderr, "time remaining=%u seconds ", cov_data.timeRemaining); @@ -91,12 +89,11 @@ void handler_ucov_notification(uint8_t *service_request, uint16_t service_len, while (pProperty_value) { fprintf(stderr, "UCOV: "); if (pProperty_value->propertyIdentifier < 512) { - fprintf( - stderr, "%s ", + fprintf(stderr, "%s ", bactext_property_name(pProperty_value->propertyIdentifier)); } else { fprintf(stderr, "proprietary %u ", - pProperty_value->propertyIdentifier); + pProperty_value->propertyIdentifier); } if (pProperty_value->propertyArrayIndex != BACNET_ARRAY_ALL) { fprintf(stderr, "%u ", pProperty_value->propertyArrayIndex); diff --git a/include/txbuf.h b/src/bacnet/basic/service/h_ucov.h similarity index 65% rename from include/txbuf.h rename to src/bacnet/basic/service/h_ucov.h index bb7d8955..235b2919 100644 --- a/include/txbuf.h +++ b/src/bacnet/basic/service/h_ucov.h @@ -1,6 +1,10 @@ -/************************************************************************** +/** +* @file +* @author Steve Karg +* @date October 2019 +* @brief Header file for a basic UnconfirmedCOV notification handler * -* Copyright (C) 2005 Steve Karg +* @section LICENSE * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the @@ -20,16 +24,28 @@ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -* -*********************************************************************/ -#ifndef TXBUF_H -#define TXBUF_H +*/ +#ifndef HANDLER_UCOV_NOTIFICATION_H +#define HANDLER_UCOV_NOTIFICATION_H #include #include -#include "config.h" -#include "datalink.h" +#include +#include +#include "bacnet/bacdef.h" +#include "bacnet/bacenum.h" +#include "bacnet/apdu.h" -extern uint8_t Handler_Transmit_Buffer[MAX_PDU]; +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + void handler_ucov_notification( + uint8_t * service_request, + uint16_t service_len, + BACNET_ADDRESS * src); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ #endif diff --git a/demo/handler/h_upt.c b/src/bacnet/basic/service/h_upt.c similarity index 83% rename from demo/handler/h_upt.c rename to src/bacnet/basic/service/h_upt.c index 90ede122..c7434103 100644 --- a/demo/handler/h_upt.c +++ b/src/bacnet/basic/service/h_upt.c @@ -27,22 +27,22 @@ #include #include #include -#include "config.h" -#include "txbuf.h" -#include "bacdef.h" -#include "bacdcode.h" -#include "apdu.h" -#include "npdu.h" -#include "abort.h" -#include "ptransfer.h" -#include "handlers.h" +#include "bacnet/config.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/apdu.h" +#include "bacnet/npdu.h" +#include "bacnet/abort.h" +#include "bacnet/ptransfer.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/tsm/tsm.h" /** @file h_upt.c Handles Unconfirmed Private Transfer requests. */ void private_transfer_print_data(BACNET_PRIVATE_TRANSFER_DATA *private_data) { BACNET_OBJECT_PROPERTY_VALUE object_value; /* for bacapp printing */ - BACNET_APPLICATION_DATA_VALUE value; /* for decode value data */ + BACNET_APPLICATION_DATA_VALUE value; /* for decode value data */ int len = 0; uint8_t *application_data; int application_data_len; @@ -52,9 +52,9 @@ void private_transfer_print_data(BACNET_PRIVATE_TRANSFER_DATA *private_data) if (private_data) { #if PRINT_ENABLED printf("PrivateTransfer:vendorID=%u\r\n", - (unsigned)private_data->vendorID); + (unsigned)private_data->vendorID); printf("PrivateTransfer:serviceNumber=%lu\r\n", - (unsigned long)private_data->serviceNumber); + (unsigned long)private_data->serviceNumber); #endif application_data = private_data->serviceParameters; application_data_len = private_data->serviceParametersLen; @@ -99,9 +99,8 @@ void private_transfer_print_data(BACNET_PRIVATE_TRANSFER_DATA *private_data) } } -void handler_unconfirmed_private_transfer(uint8_t *service_request, - uint16_t service_len, - BACNET_ADDRESS *src) +void handler_unconfirmed_private_transfer( + uint8_t *service_request, uint16_t service_len, BACNET_ADDRESS *src) { BACNET_PRIVATE_TRANSFER_DATA private_data; int len = 0; @@ -109,8 +108,8 @@ void handler_unconfirmed_private_transfer(uint8_t *service_request, #if PRINT_ENABLED fprintf(stderr, "Received Unconfirmed Private Transfer Request!\n"); #endif - len = ptransfer_decode_service_request(service_request, service_len, - &private_data); + len = ptransfer_decode_service_request( + service_request, service_len, &private_data); if (len >= 0) { private_transfer_print_data(&private_data); } diff --git a/src/bacnet/basic/service/h_upt.h b/src/bacnet/basic/service/h_upt.h new file mode 100644 index 00000000..3278a136 --- /dev/null +++ b/src/bacnet/basic/service/h_upt.h @@ -0,0 +1,54 @@ +/** +* @file +* @author Steve Karg +* @date October 2019 +* @brief Header file for a basic UnconfirmedPrivateTransfer service handler +* +* @section LICENSE +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +#ifndef HANDLER_UNCONFIRMED_PRIVATE_TRANSFER_H +#define HANDLER_UNCONFIRMED_PRIVATE_TRANSFER_H + +#include +#include +#include +#include +#include "bacnet/bacdef.h" +#include "bacnet/bacenum.h" +#include "bacnet/apdu.h" +#include "bacnet/ptransfer.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + void handler_unconfirmed_private_transfer( + uint8_t * service_request, + uint16_t service_len, + BACNET_ADDRESS * src); + void private_transfer_print_data( + BACNET_PRIVATE_TRANSFER_DATA *private_data); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/demo/handler/h_whohas.c b/src/bacnet/basic/service/h_whohas.c similarity index 78% rename from demo/handler/h_whohas.c rename to src/bacnet/basic/service/h_whohas.c index 7b2ab458..975773d3 100644 --- a/demo/handler/h_whohas.c +++ b/src/bacnet/basic/service/h_whohas.c @@ -27,14 +27,13 @@ #include #include #include -#include "config.h" -#include "txbuf.h" -#include "bacdef.h" -#include "bacdcode.h" -#include "whohas.h" -#include "device.h" -#include "client.h" -#include "handlers.h" +#include "bacnet/config.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/whohas.h" +#include "bacnet/basic/object/device.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/tsm/tsm.h" /** @file h_whohas.c Handles Who-Has requests. */ @@ -42,7 +41,7 @@ * or object ID, if the Device has a match. * @param data [in] The decoded who-has payload from the request. */ -static void match_name_or_object(BACNET_WHO_HAS_DATA* data) +static void match_name_or_object(BACNET_WHO_HAS_DATA *data) { int object_type = 0; uint32_t object_instance = 0; @@ -53,12 +52,12 @@ static void match_name_or_object(BACNET_WHO_HAS_DATA* data) note: we should have only 1 of such an object */ if (data->is_object_name) { /* valid name in my device? */ - found = Device_Valid_Object_Name(&data->object.name, &object_type, - &object_instance); + found = Device_Valid_Object_Name( + &data->object.name, &object_type, &object_instance); if (found) { Send_I_Have(Device_Object_Instance_Number(), - (BACNET_OBJECT_TYPE)object_type, object_instance, - &data->object.name); + (BACNET_OBJECT_TYPE)object_type, object_instance, + &data->object.name); } } else { /* valid object_name copy in my device? */ @@ -67,8 +66,8 @@ static void match_name_or_object(BACNET_WHO_HAS_DATA* data) data->object.identifier.instance, &object_name); if (found) { Send_I_Have(Device_Object_Instance_Number(), - (BACNET_OBJECT_TYPE)data->object.identifier.type, - data->object.identifier.instance, &object_name); + (BACNET_OBJECT_TYPE)data->object.identifier.type, + data->object.identifier.instance, &object_name); } } } @@ -82,8 +81,8 @@ static void match_name_or_object(BACNET_WHO_HAS_DATA* data) * @param service_len [in] Length of the service_request message. * @param src [in] The BACNET_ADDRESS of the message's source. */ -void handler_who_has(uint8_t* service_request, uint16_t service_len, - BACNET_ADDRESS* src) +void handler_who_has( + uint8_t *service_request, uint16_t service_len, BACNET_ADDRESS *src) { int len = 0; BACNET_WHO_HAS_DATA data; @@ -92,12 +91,13 @@ void handler_who_has(uint8_t* service_request, uint16_t service_len, (void)src; len = whohas_decode_service_request(service_request, service_len, &data); if (len > 0) { - if ((data.low_limit == -1) || (data.high_limit == -1)) + if ((data.low_limit == -1) || (data.high_limit == -1)) { directed_to_me = true; - else if ((Device_Object_Instance_Number() >= - (uint32_t)data.low_limit) && - (Device_Object_Instance_Number() <= (uint32_t)data.high_limit)) + } else if ((Device_Object_Instance_Number() >= + (uint32_t)data.low_limit) && + (Device_Object_Instance_Number() <= (uint32_t)data.high_limit)) { directed_to_me = true; + } if (directed_to_me) { match_name_or_object(&data); } @@ -121,14 +121,14 @@ void handler_who_has(uint8_t* service_request, uint16_t service_len, * @param service_len [in] Length of the service_request message. * @param src [in] The BACNET_ADDRESS of the message's source (ignored). */ -void handler_who_has_for_routing(uint8_t* service_request, uint16_t service_len, - BACNET_ADDRESS* src) +void handler_who_has_for_routing( + uint8_t *service_request, uint16_t service_len, BACNET_ADDRESS *src) { int len = 0; BACNET_WHO_HAS_DATA data; int32_t dev_instance; - int cursor = 0; /* Starting hint */ - int my_list[2] = {0, -1}; /* Not really used, so dummy values */ + int cursor = 0; /* Starting hint */ + int my_list[2] = { 0, -1 }; /* Not really used, so dummy values */ BACNET_ADDRESS bcast_net; (void)src; @@ -142,7 +142,7 @@ void handler_who_has_for_routing(uint8_t* service_request, uint16_t service_len, dev_instance = Device_Object_Instance_Number(); if ((data.low_limit == -1) || (data.high_limit == -1) || ((dev_instance >= data.low_limit) && - (dev_instance <= data.high_limit))) + (dev_instance <= data.high_limit))) match_name_or_object(&data); } } diff --git a/src/bacnet/basic/service/h_whohas.h b/src/bacnet/basic/service/h_whohas.h new file mode 100644 index 00000000..c78c7722 --- /dev/null +++ b/src/bacnet/basic/service/h_whohas.h @@ -0,0 +1,56 @@ +/** +* @file +* @author Steve Karg +* @date October 2019 +* @brief Header file for a basic Who-Has service handler +* +* @section LICENSE +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +#ifndef HANDLER_WHO_HAS_H +#define HANDLER_WHO_HAS_H + +#include +#include +#include +#include +#include "bacnet/bacdef.h" +#include "bacnet/bacenum.h" +#include "bacnet/apdu.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + void handler_who_has( + uint8_t * service_request, + uint16_t service_len, + BACNET_ADDRESS * src); + + void handler_who_has_for_routing( + uint8_t * service_request, + uint16_t service_len, + BACNET_ADDRESS * src); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/demo/handler/h_whois.c b/src/bacnet/basic/service/h_whois.c similarity index 80% rename from demo/handler/h_whois.c rename to src/bacnet/basic/service/h_whois.c index 33c56446..dfb11f27 100644 --- a/demo/handler/h_whois.c +++ b/src/bacnet/basic/service/h_whois.c @@ -27,17 +27,14 @@ #include #include #include -#include "config.h" -#include "txbuf.h" -#include "bacdef.h" -#include "bacdcode.h" -#include "whois.h" -#include "iam.h" -#include "device.h" - -#include "client.h" -#include "txbuf.h" -#include "handlers.h" +#include "bacnet/config.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/whois.h" +#include "bacnet/iam.h" +#include "bacnet/basic/object/device.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/tsm/tsm.h" /** @file h_whois.c Handles Who-Is requests. */ @@ -47,16 +44,16 @@ * @param service_len [in] Length of the service_request message. * @param src [in] The BACNET_ADDRESS of the message's source (ignored). */ -void handler_who_is(uint8_t* service_request, uint16_t service_len, - BACNET_ADDRESS* src) +void handler_who_is( + uint8_t *service_request, uint16_t service_len, BACNET_ADDRESS *src) { int len = 0; int32_t low_limit = 0; int32_t high_limit = 0; (void)src; - len = whois_decode_service_request(service_request, service_len, &low_limit, - &high_limit); + len = whois_decode_service_request( + service_request, service_len, &low_limit, &high_limit); if (len == 0) { Send_I_Am(&Handler_Transmit_Buffer[0]); } else if (len != BACNET_STATUS_ERROR) { @@ -78,15 +75,15 @@ void handler_who_is(uint8_t* service_request, uint16_t service_len, * @param src [in] The BACNET_ADDRESS of the message's source that the * response will be sent back to. */ -void handler_who_is_unicast(uint8_t* service_request, uint16_t service_len, - BACNET_ADDRESS* src) +void handler_who_is_unicast( + uint8_t *service_request, uint16_t service_len, BACNET_ADDRESS *src) { int len = 0; int32_t low_limit = 0; int32_t high_limit = 0; - len = whois_decode_service_request(service_request, service_len, &low_limit, - &high_limit); + len = whois_decode_service_request( + service_request, service_len, &low_limit, &high_limit); /* If no limits, then always respond */ if (len == 0) { Send_I_Am_Unicast(&Handler_Transmit_Buffer[0], src); @@ -119,20 +116,21 @@ void handler_who_is_unicast(uint8_t* service_request, uint16_t service_len, * back to the src, else False if should broadcast * response(s). */ -static void check_who_is_for_routing(uint8_t* service_request, - uint16_t service_len, BACNET_ADDRESS* src, - bool is_unicast) +static void check_who_is_for_routing(uint8_t *service_request, + uint16_t service_len, + BACNET_ADDRESS *src, + bool is_unicast) { int len = 0; int32_t low_limit = 0; int32_t high_limit = 0; int32_t dev_instance; - int cursor = 0; /* Starting hint */ - int my_list[2] = {0, -1}; /* Not really used, so dummy values */ + int cursor = 0; /* Starting hint */ + int my_list[2] = { 0, -1 }; /* Not really used, so dummy values */ BACNET_ADDRESS bcast_net; - len = whois_decode_service_request(service_request, service_len, &low_limit, - &high_limit); + len = whois_decode_service_request( + service_request, service_len, &low_limit, &high_limit); if (len == BACNET_STATUS_ERROR) { /* Invalid; just leave */ return; @@ -165,8 +163,8 @@ static void check_who_is_for_routing(uint8_t* service_request, * @param service_len [in] Length of the service_request message. * @param src [in] The BACNET_ADDRESS of the message's source (ignored). */ -void handler_who_is_bcast_for_routing(uint8_t* service_request, - uint16_t service_len, BACNET_ADDRESS* src) +void handler_who_is_bcast_for_routing( + uint8_t *service_request, uint16_t service_len, BACNET_ADDRESS *src) { check_who_is_for_routing(service_request, service_len, src, false); } @@ -182,9 +180,8 @@ void handler_who_is_bcast_for_routing(uint8_t* service_request, * @param src [in] The BACNET_ADDRESS of the message's source that the * response will be sent back to. */ -void handler_who_is_unicast_for_routing(uint8_t* service_request, - uint16_t service_len, - BACNET_ADDRESS* src) +void handler_who_is_unicast_for_routing( + uint8_t *service_request, uint16_t service_len, BACNET_ADDRESS *src) { check_who_is_for_routing(service_request, service_len, src, true); } diff --git a/src/bacnet/basic/service/h_whois.h b/src/bacnet/basic/service/h_whois.h new file mode 100644 index 00000000..9aad727b --- /dev/null +++ b/src/bacnet/basic/service/h_whois.h @@ -0,0 +1,66 @@ +/** +* @file +* @author Steve Karg +* @date October 2019 +* @brief Header file for a basic Who-Is service handler +* +* @section LICENSE +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +#ifndef HANDLER_WHO_IS_H +#define HANDLER_WHO_IS_H + +#include +#include +#include +#include +#include "bacnet/bacdef.h" +#include "bacnet/bacenum.h" +#include "bacnet/apdu.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + void handler_who_is( + uint8_t * service_request, + uint16_t service_len, + BACNET_ADDRESS * src); + + void handler_who_is_unicast( + uint8_t * service_request, + uint16_t service_len, + BACNET_ADDRESS * src); + + void handler_who_is_bcast_for_routing( + uint8_t * service_request, + uint16_t service_len, + BACNET_ADDRESS * src); + + void handler_who_is_unicast_for_routing( + uint8_t * service_request, + uint16_t service_len, + BACNET_ADDRESS * src); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/demo/handler/h_wp.c b/src/bacnet/basic/service/h_wp.c similarity index 76% rename from demo/handler/h_wp.c rename to src/bacnet/basic/service/h_wp.c index cd9143b5..6a3b1f1d 100644 --- a/demo/handler/h_wp.c +++ b/src/bacnet/basic/service/h_wp.c @@ -27,18 +27,19 @@ #include #include #include -#include "config.h" -#include "txbuf.h" -#include "bacdef.h" -#include "bacdcode.h" -#include "bacerror.h" -#include "apdu.h" -#include "npdu.h" -#include "abort.h" -#include "wp.h" -/* device object has the handling for all objects */ -#include "device.h" -#include "handlers.h" +#include "bacnet/config.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacerror.h" +#include "bacnet/apdu.h" +#include "bacnet/npdu.h" +#include "bacnet/abort.h" +#include "bacnet/wp.h" +/* basic objects, services, TSM, and datalink */ +#include "bacnet/basic/object/device.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/basic/services.h" +#include "bacnet/datalink/datalink.h" /** @file h_wp.c Handles Write Property requests. */ @@ -60,9 +61,10 @@ * @param service_data [in] The BACNET_CONFIRMED_SERVICE_DATA information * decoded from the APDU header of this message. */ -void handler_write_property(uint8_t* service_request, uint16_t service_len, - BACNET_ADDRESS* src, - BACNET_CONFIRMED_SERVICE_DATA* service_data) +void handler_write_property(uint8_t *service_request, + uint16_t service_len, + BACNET_ADDRESS *src, + BACNET_CONFIRMED_SERVICE_DATA *service_data) { BACNET_WRITE_PROPERTY_DATA wp_data; int len = 0; @@ -74,15 +76,15 @@ void handler_write_property(uint8_t* service_request, uint16_t service_len, /* encode the NPDU portion of the packet */ datalink_get_my_address(&my_address); npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL); - pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address, - &npdu_data); + pdu_len = npdu_encode_pdu( + &Handler_Transmit_Buffer[0], src, &my_address, &npdu_data); #if PRINT_ENABLED fprintf(stderr, "WP: Received Request!\n"); #endif if (service_data->segmented_message) { len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], - service_data->invoke_id, - ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true); + service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, + true); #if PRINT_ENABLED fprintf(stderr, "WP: Segmented message. Sending Abort!\n"); #endif @@ -91,8 +93,7 @@ void handler_write_property(uint8_t* service_request, uint16_t service_len, len = wp_decode_service_request(service_request, service_len, &wp_data); #if PRINT_ENABLED if (len > 0) - fprintf( - stderr, + fprintf(stderr, "WP: type=%lu instance=%lu property=%lu priority=%lu index=%ld\n", (unsigned long)wp_data.object_type, (unsigned long)wp_data.object_instance, @@ -104,8 +105,7 @@ void handler_write_property(uint8_t* service_request, uint16_t service_len, /* bad decoding or something we didn't understand - send an abort */ if (len <= 0) { len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], - service_data->invoke_id, ABORT_REASON_OTHER, - true); + service_data->invoke_id, ABORT_REASON_OTHER, true); #if PRINT_ENABLED fprintf(stderr, "WP: Bad Encoding. Sending Abort!\n"); #endif @@ -113,24 +113,22 @@ void handler_write_property(uint8_t* service_request, uint16_t service_len, } if (Device_Write_Property(&wp_data)) { len = encode_simple_ack(&Handler_Transmit_Buffer[pdu_len], - service_data->invoke_id, - SERVICE_CONFIRMED_WRITE_PROPERTY); + service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY); #if PRINT_ENABLED fprintf(stderr, "WP: Sending Simple Ack!\n"); #endif } else { len = bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], - service_data->invoke_id, - SERVICE_CONFIRMED_WRITE_PROPERTY, - wp_data.error_class, wp_data.error_code); + service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY, + wp_data.error_class, wp_data.error_code); #if PRINT_ENABLED fprintf(stderr, "WP: Sending Error!\n"); #endif } WP_ABORT: pdu_len += len; - bytes_sent = datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0], - pdu_len); + bytes_sent = datalink_send_pdu( + src, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len); if (bytes_sent <= 0) { #if PRINT_ENABLED fprintf(stderr, "WP: Failed to send PDU (%s)!\n", strerror(errno)); @@ -146,9 +144,11 @@ WP_ABORT: * finally if it is allowed to be empty. */ -bool WPValidateString(BACNET_APPLICATION_DATA_VALUE* pValue, int iMaxLen, - bool bEmptyAllowed, BACNET_ERROR_CLASS* pErrorClass, - BACNET_ERROR_CODE* pErrorCode) +bool WPValidateString(BACNET_APPLICATION_DATA_VALUE *pValue, + int iMaxLen, + bool bEmptyAllowed, + BACNET_ERROR_CLASS *pErrorClass, + BACNET_ERROR_CODE *pErrorCode) { bool bResult; @@ -166,20 +166,22 @@ bool WPValidateString(BACNET_APPLICATION_DATA_VALUE* pValue, int iMaxLen, (characterstring_length(&pValue->type.Character_String) == 0)) { *pErrorCode = ERROR_CODE_VALUE_OUT_OF_RANGE; } else if ((bEmptyAllowed == false) && - (!characterstring_printable( - &pValue->type.Character_String))) { + (!characterstring_printable(&pValue->type.Character_String))) { /* assumption: non-empty also means must be "printable" */ *pErrorCode = ERROR_CODE_VALUE_OUT_OF_RANGE; } else if (characterstring_length(&pValue->type.Character_String) > - (uint16_t)iMaxLen) { + (uint16_t)iMaxLen) { *pErrorClass = ERROR_CLASS_RESOURCES; *pErrorCode = ERROR_CODE_NO_SPACE_TO_WRITE_PROPERTY; - } else + } else { bResult = true; /* It's all good! */ - } else + } + } else { *pErrorCode = ERROR_CODE_CHARACTER_SET_NOT_SUPPORTED; - } else + } + } else { *pErrorCode = ERROR_CODE_INVALID_DATA_TYPE; + } return (bResult); } @@ -189,9 +191,10 @@ bool WPValidateString(BACNET_APPLICATION_DATA_VALUE* pValue, int iMaxLen, * validation fails. Cuts out reams of repeated code in the object code. */ -bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE* pValue, - uint8_t ucExpectedTag, BACNET_ERROR_CLASS* pErrorClass, - BACNET_ERROR_CODE* pErrorCode) +bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue, + uint8_t ucExpectedTag, + BACNET_ERROR_CLASS *pErrorClass, + BACNET_ERROR_CODE *pErrorCode) { bool bResult; diff --git a/src/bacnet/basic/service/h_wp.h b/src/bacnet/basic/service/h_wp.h new file mode 100644 index 00000000..c8b50ca5 --- /dev/null +++ b/src/bacnet/basic/service/h_wp.h @@ -0,0 +1,66 @@ +/** +* @file +* @author Steve Karg +* @date October 2019 +* @brief Header file for a basic WriteProperty service handler +* +* @section LICENSE +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +#ifndef HANDLER_WRITE_PROPERTY_H +#define HANDLER_WRITE_PROPERTY_H + +#include +#include +#include +#include +#include "bacnet/bacapp.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacenum.h" +#include "bacnet/apdu.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + void handler_write_property( + uint8_t * service_request, + uint16_t service_len, + BACNET_ADDRESS * src, + BACNET_CONFIRMED_SERVICE_DATA * service_data); + + bool WPValidateString( + BACNET_APPLICATION_DATA_VALUE * pValue, + int iMaxLen, + bool bEmptyAllowed, + BACNET_ERROR_CLASS * pErrorClass, + BACNET_ERROR_CODE * pErrorCode); + + bool WPValidateArgType( + BACNET_APPLICATION_DATA_VALUE * pValue, + uint8_t ucExpectedType, + BACNET_ERROR_CLASS * pErrorClass, + BACNET_ERROR_CODE * pErrorCode); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/demo/handler/h_wpm.c b/src/bacnet/basic/service/h_wpm.c similarity index 69% rename from demo/handler/h_wpm.c rename to src/bacnet/basic/service/h_wpm.c index 7ae635ee..de213787 100644 --- a/demo/handler/h_wpm.c +++ b/src/bacnet/basic/service/h_wpm.c @@ -27,20 +27,21 @@ #include #include #include -#include "config.h" -#include "txbuf.h" -#include "bacdef.h" -#include "bacdcode.h" -#include "bacerror.h" -#include "apdu.h" -#include "npdu.h" -#include "abort.h" -#include "wp.h" -#include "reject.h" -#include "wpm.h" -/* device object has the handling for all objects */ -#include "device.h" -#include "handlers.h" +#include "bacnet/config.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacerror.h" +#include "bacnet/apdu.h" +#include "bacnet/npdu.h" +#include "bacnet/abort.h" +#include "bacnet/wp.h" +#include "bacnet/reject.h" +#include "bacnet/wpm.h" +/* basic objects, services, TSM, and datalink */ +#include "bacnet/basic/object/device.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/basic/services.h" +#include "bacnet/datalink/datalink.h" /** @file h_wpm.c Handles Write Property Multiple requests. */ @@ -61,9 +62,10 @@ * @param service_data [in] The BACNET_CONFIRMED_SERVICE_DATA information * decoded from the APDU header of this message. */ -void handler_write_property_multiple( - uint8_t* service_request, uint16_t service_len, BACNET_ADDRESS* src, - BACNET_CONFIRMED_SERVICE_DATA* service_data) +void handler_write_property_multiple(uint8_t *service_request, + uint16_t service_len, + BACNET_ADDRESS *src, + BACNET_CONFIRMED_SERVICE_DATA *service_data) { int len = 0; int apdu_len = 0; @@ -89,34 +91,34 @@ void handler_write_property_multiple( decode_len = 0; do { /* decode Object Identifier */ - len = wpm_decode_object_id(&service_request[decode_len], - service_len - decode_len, &wp_data); + len = wpm_decode_object_id( + &service_request[decode_len], service_len - decode_len, &wp_data); if (len > 0) { uint8_t tag_number = 0; decode_len += len; /* Opening tag 1 - List of Properties */ - if (decode_is_opening_tag_number(&service_request[decode_len++], - 1)) { + if (decode_is_opening_tag_number( + &service_request[decode_len++], 1)) { do { /* decode a 'Property Identifier'; (3) an optional 'Property * Array Index' */ /* (4) a 'Property Value'; and (5) an optional 'Priority'. */ - len = wpm_decode_object_property( - &service_request[decode_len], service_len - decode_len, - &wp_data); + len = + wpm_decode_object_property(&service_request[decode_len], + service_len - decode_len, &wp_data); if (len > 0) { decode_len += len; #if PRINT_ENABLED fprintf(stderr, - "WPM: type=%lu instance=%lu property=%lu " - "priority=%lu index=%ld\n", - (unsigned long)wp_data.object_type, - (unsigned long)wp_data.object_instance, - (unsigned long)wp_data.object_property, - (unsigned long)wp_data.priority, - (long)wp_data.array_index); + "WPM: type=%lu instance=%lu property=%lu " + "priority=%lu index=%ld\n", + (unsigned long)wp_data.object_type, + (unsigned long)wp_data.object_instance, + (unsigned long)wp_data.object_property, + (unsigned long)wp_data.priority, + (long)wp_data.array_index); #endif if (Device_Write_Property(&wp_data) == false) { error = true; @@ -136,13 +138,14 @@ void handler_write_property_multiple( &service_request[decode_len], 1)) { tag_number = 1; decode_len++; - } else - tag_number = 0; /* it was not tag 1, decode next - Property Identifier ... */ + } else { + tag_number = 0; + } /* it was not tag 1, decode next + Property + Identifier ... */ - } while ( - tag_number != - 1); /* end decoding List of Properties for "that" object */ + } while (tag_number != 1); /* end decoding List of Properties + for "that" object */ if (error) { goto WPM_ABORT; @@ -161,14 +164,14 @@ WPM_ABORT: /* encode the NPDU portion of the packet */ datalink_get_my_address(&my_address); npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL); - npdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address, - &npdu_data); + npdu_len = npdu_encode_pdu( + &Handler_Transmit_Buffer[0], src, &my_address, &npdu_data); apdu_len = 0; /* handle any errors */ if (error) { if (len == BACNET_STATUS_ABORT) { - apdu_len = abort_encode_apdu( - &Handler_Transmit_Buffer[npdu_len], service_data->invoke_id, + apdu_len = abort_encode_apdu(&Handler_Transmit_Buffer[npdu_len], + service_data->invoke_id, abort_convert_error_code(wp_data.error_code), true); #if PRINT_ENABLED fprintf(stderr, "WPM: Sending Abort!\n"); @@ -176,29 +179,29 @@ WPM_ABORT: } else if (len == BACNET_STATUS_ERROR) { apdu_len = wpm_error_ack_encode_apdu(&Handler_Transmit_Buffer[npdu_len], - service_data->invoke_id, &wp_data); + service_data->invoke_id, &wp_data); #if PRINT_ENABLED fprintf(stderr, "WPM: Sending Error!\n"); #endif } else if (len == BACNET_STATUS_REJECT) { - apdu_len = reject_encode_apdu( - &Handler_Transmit_Buffer[npdu_len], service_data->invoke_id, + apdu_len = reject_encode_apdu(&Handler_Transmit_Buffer[npdu_len], + service_data->invoke_id, reject_convert_error_code(wp_data.error_code)); #if PRINT_ENABLED fprintf(stderr, "WPM: Sending Reject!\n"); #endif } } else { - apdu_len = wpm_ack_encode_apdu_init(&Handler_Transmit_Buffer[npdu_len], - service_data->invoke_id); + apdu_len = wpm_ack_encode_apdu_init( + &Handler_Transmit_Buffer[npdu_len], service_data->invoke_id); #if PRINT_ENABLED fprintf(stderr, "WPM: Sending Ack!\n"); #endif } pdu_len = npdu_len + apdu_len; - bytes_sent = datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0], - pdu_len); + bytes_sent = datalink_send_pdu( + src, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len); #if PRINT_ENABLED if (bytes_sent <= 0) { fprintf(stderr, "Failed to send PDU (%s)!\n", strerror(errno)); diff --git a/src/bacnet/basic/service/h_wpm.h b/src/bacnet/basic/service/h_wpm.h new file mode 100644 index 00000000..921c42f0 --- /dev/null +++ b/src/bacnet/basic/service/h_wpm.h @@ -0,0 +1,53 @@ +/** +* @file +* @author Steve Karg +* @date October 2019 +* @brief Header file for a basic WritePropertyMultiple service handler +* +* @section LICENSE +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +#ifndef HANDLER_WRITE_PROPERTY_MULTIPLE_H +#define HANDLER_WRITE_PROPERTY_MULTIPLE_H + +#include +#include +#include +#include +#include "bacnet/bacapp.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacenum.h" +#include "bacnet/apdu.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + void handler_write_property_multiple( + uint8_t * service_request, + uint16_t service_len, + BACNET_ADDRESS * src, + BACNET_CONFIRMED_SERVICE_DATA * service_data); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/demo/handler/s_abort.c b/src/bacnet/basic/service/s_abort.c similarity index 77% rename from demo/handler/s_abort.c rename to src/bacnet/basic/service/s_abort.c index 1e4053e2..23e48d22 100644 --- a/demo/handler/s_abort.c +++ b/src/bacnet/basic/service/s_abort.c @@ -26,22 +26,19 @@ #include #include #include -#include "config.h" -#include "bacdef.h" -#include "bacdcode.h" -#include "abort.h" -#include "address.h" -#include "tsm.h" -#include "dcc.h" -#include "npdu.h" -#include "apdu.h" -#include "device.h" -#include "datalink.h" -#include "iam.h" -#include "txbuf.h" -/* some demo stuff needed */ -#include "handlers.h" -#include "client.h" +#include "bacnet/config.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/abort.h" +#include "bacnet/dcc.h" +#include "bacnet/npdu.h" +#include "bacnet/apdu.h" +#include "bacnet/iam.h" +/* basic objects, services, TSM, and datalink */ +#include "bacnet/basic/object/device.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/basic/services.h" +#include "bacnet/datalink/datalink.h" /** Encodes an Abort message * @param buffer The buffer to build the message for sending. @@ -54,9 +51,13 @@ * * @return Size of the message sent (bytes), or a negative value on error. */ -int abort_encode_pdu(uint8_t *buffer, BACNET_ADDRESS *dest, BACNET_ADDRESS *src, - BACNET_NPDU_DATA *npdu_data, uint8_t invoke_id, - BACNET_ABORT_REASON reason, bool server) +int abort_encode_pdu(uint8_t *buffer, + BACNET_ADDRESS *dest, + BACNET_ADDRESS *src, + BACNET_NPDU_DATA *npdu_data, + uint8_t invoke_id, + BACNET_ABORT_REASON reason, + bool server) { int len = 0; int pdu_len = 0; @@ -81,9 +82,11 @@ int abort_encode_pdu(uint8_t *buffer, BACNET_ADDRESS *dest, BACNET_ADDRESS *src, * * @return Size of the message sent (bytes), or a negative value on error. */ -int Send_Abort_To_Network(uint8_t *buffer, BACNET_ADDRESS *dest, - uint8_t invoke_id, BACNET_ABORT_REASON reason, - bool server) +int Send_Abort_To_Network(uint8_t *buffer, + BACNET_ADDRESS *dest, + uint8_t invoke_id, + BACNET_ABORT_REASON reason, + bool server) { int pdu_len = 0; BACNET_ADDRESS src; @@ -91,8 +94,8 @@ int Send_Abort_To_Network(uint8_t *buffer, BACNET_ADDRESS *dest, BACNET_NPDU_DATA npdu_data; datalink_get_my_address(&src); - pdu_len = abort_encode_pdu(buffer, dest, &src, &npdu_data, invoke_id, - reason, server); + pdu_len = abort_encode_pdu( + buffer, dest, &src, &npdu_data, invoke_id, reason, server); bytes_sent = datalink_send_pdu(dest, &npdu_data, &buffer[0], pdu_len); return bytes_sent; diff --git a/src/bacnet/basic/service/s_abort.h b/src/bacnet/basic/service/s_abort.h new file mode 100644 index 00000000..2885b2ec --- /dev/null +++ b/src/bacnet/basic/service/s_abort.h @@ -0,0 +1,64 @@ +/** +* @file +* @author Steve Karg +* @date October 2019 +* @brief Header file for a basic Abort message send +* +* @section LICENSE +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +#ifndef SEND_ABORT_TO_NETWORK_H +#define SEND_ABORT_TO_NETWORK_H + +#include +#include +#include +#include +#include "bacnet/bacapp.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacenum.h" +#include "bacnet/apdu.h" +#include "bacnet/npdu.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + int Send_Abort_To_Network( + uint8_t * buffer, + BACNET_ADDRESS *dest, + uint8_t invoke_id, + BACNET_ABORT_REASON reason, + bool server); + + int abort_encode_pdu( + uint8_t * buffer, + BACNET_ADDRESS * dest, + BACNET_ADDRESS * src, + BACNET_NPDU_DATA * npdu_data, + uint8_t invoke_id, + BACNET_ABORT_REASON reason, + bool server); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/demo/handler/s_ack_alarm.c b/src/bacnet/basic/service/s_ack_alarm.c similarity index 73% rename from demo/handler/s_ack_alarm.c rename to src/bacnet/basic/service/s_ack_alarm.c index fc3cfab5..718d3d53 100644 --- a/demo/handler/s_ack_alarm.c +++ b/src/bacnet/basic/service/s_ack_alarm.c @@ -26,30 +26,27 @@ #include #include #include -#include "config.h" -#include "txbuf.h" -#include "bacdef.h" -#include "bacdcode.h" -#include "address.h" -#include "tsm.h" -#include "npdu.h" -#include "apdu.h" -#include "device.h" -#include "datalink.h" -#include "dcc.h" -#include "whois.h" +#include "bacnet/config.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/npdu.h" +#include "bacnet/apdu.h" +#include "bacnet/dcc.h" +#include "bacnet/whois.h" +#include "bacnet/alarm_ack.h" /* some demo stuff needed */ -#include "handlers.h" -#include "txbuf.h" -#include "alarm_ack.h" -#include "client.h" +#include "bacnet/basic/object/device.h" +#include "bacnet/basic/object/device.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/datalink/datalink.h" /** @file s_ack_alarm.c Send an Alarm Acknowledgment. */ /* returns the invoke ID for confirmed request, or zero on failure */ -uint8_t Send_Alarm_Acknowledgement(uint32_t device_id, - BACNET_ALARM_ACK_DATA* data) +uint8_t Send_Alarm_Acknowledgement( + uint32_t device_id, BACNET_ALARM_ACK_DATA *data) { BACNET_ADDRESS dest; BACNET_ADDRESS my_address; @@ -61,22 +58,24 @@ uint8_t Send_Alarm_Acknowledgement(uint32_t device_id, int bytes_sent = 0; BACNET_NPDU_DATA npdu_data; - if (!dcc_communication_enabled()) + if (!dcc_communication_enabled()) { return 0; + } /* is the device bound? */ status = address_get_by_device(device_id, &max_apdu, &dest); /* is there a tsm available? */ - if (status) + if (status) { invoke_id = tsm_next_free_invokeID(); + } if (invoke_id) { /* encode the NPDU portion of the packet */ datalink_get_my_address(&my_address); npdu_encode_npdu_data(&npdu_data, true, MESSAGE_PRIORITY_NORMAL); - pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest, - &my_address, &npdu_data); - len = alarm_ack_encode_apdu(&Handler_Transmit_Buffer[pdu_len], - invoke_id, data); + pdu_len = npdu_encode_pdu( + &Handler_Transmit_Buffer[0], &dest, &my_address, &npdu_data); + len = alarm_ack_encode_apdu( + &Handler_Transmit_Buffer[pdu_len], invoke_id, data); pdu_len += len; /* will it fit in the sender? note: if there is a bottleneck router in between @@ -84,23 +83,22 @@ uint8_t Send_Alarm_Acknowledgement(uint32_t device_id, we have a way to check for that and update the max_apdu in the address binding table. */ if ((unsigned)pdu_len < max_apdu) { - tsm_set_confirmed_unsegmented_transaction( - invoke_id, &dest, &npdu_data, &Handler_Transmit_Buffer[0], - (uint16_t)pdu_len); + tsm_set_confirmed_unsegmented_transaction(invoke_id, &dest, + &npdu_data, &Handler_Transmit_Buffer[0], (uint16_t)pdu_len); bytes_sent = datalink_send_pdu( &dest, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len); #if PRINT_ENABLED if (bytes_sent <= 0) fprintf(stderr, "Failed to Send Alarm Ack Request (%s)!\n", - strerror(errno)); + strerror(errno)); #endif } else { tsm_free_invoke_id(invoke_id); invoke_id = 0; #if PRINT_ENABLED fprintf(stderr, - "Failed to Send Alarm Ack Request " - "(exceeds destination maximum APDU)!\n"); + "Failed to Send Alarm Ack Request " + "(exceeds destination maximum APDU)!\n"); #endif } } diff --git a/src/bacnet/basic/service/s_ack_alarm.h b/src/bacnet/basic/service/s_ack_alarm.h new file mode 100644 index 00000000..8fa6fe81 --- /dev/null +++ b/src/bacnet/basic/service/s_ack_alarm.h @@ -0,0 +1,51 @@ +/** +* @file +* @author Steve Karg +* @date October 2019 +* @brief Header file for a basic AlarmAcknowledgement service send +* +* @section LICENSE +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +#ifndef SEND_ALARM_ACKNOWLEDGEMENT_H +#define SEND_ALARM_ACKNOWLEDGEMENT_H + +#include +#include +#include +#include +#include "bacnet/bacapp.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacenum.h" +#include "bacnet/apdu.h" +#include "bacnet/alarm_ack.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +uint8_t Send_Alarm_Acknowledgement(uint32_t device_id, + BACNET_ALARM_ACK_DATA* data); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/demo/handler/s_arfs.c b/src/bacnet/basic/service/s_arfs.c similarity index 74% rename from demo/handler/s_arfs.c rename to src/bacnet/basic/service/s_arfs.c index c471993f..f7db62fd 100644 --- a/demo/handler/s_arfs.c +++ b/src/bacnet/basic/service/s_arfs.c @@ -26,28 +26,26 @@ #include #include #include -#include "config.h" -#include "txbuf.h" -#include "bacdef.h" -#include "bacdcode.h" -#include "address.h" -#include "dcc.h" -#include "tsm.h" -#include "npdu.h" -#include "apdu.h" -#include "device.h" -#include "datalink.h" -#include "arf.h" +#include "bacnet/config.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/dcc.h" +#include "bacnet/npdu.h" +#include "bacnet/apdu.h" +#include "bacnet/arf.h" /* some demo stuff needed */ -#include "handlers.h" -#include "txbuf.h" -#include "client.h" +#include "bacnet/basic/binding/address.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/basic/object/device.h" +#include "bacnet/datalink/datalink.h" +#include "bacnet/basic/services.h" /** @file s_arfs.c Send part of an Atomic Read File Stream. */ -uint8_t Send_Atomic_Read_File_Stream(uint32_t device_id, uint32_t file_instance, - int fileStartPosition, - unsigned requestedOctetCount) +uint8_t Send_Atomic_Read_File_Stream(uint32_t device_id, + uint32_t file_instance, + int fileStartPosition, + unsigned requestedOctetCount) { BACNET_ADDRESS dest; BACNET_ADDRESS my_address; @@ -61,14 +59,16 @@ uint8_t Send_Atomic_Read_File_Stream(uint32_t device_id, uint32_t file_instance, BACNET_ATOMIC_READ_FILE_DATA data; /* if we are forbidden to send, don't send! */ - if (!dcc_communication_enabled()) + if (!dcc_communication_enabled()) { return 0; + } /* is the device bound? */ status = address_get_by_device(device_id, &max_apdu, &dest); /* is there a tsm available? */ - if (status) + if (status) { invoke_id = tsm_next_free_invokeID(); + } if (invoke_id) { /* load the data for the encoding */ data.object_type = OBJECT_FILE; @@ -79,10 +79,10 @@ uint8_t Send_Atomic_Read_File_Stream(uint32_t device_id, uint32_t file_instance, /* encode the NPDU portion of the packet */ datalink_get_my_address(&my_address); npdu_encode_npdu_data(&npdu_data, true, MESSAGE_PRIORITY_NORMAL); - pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest, - &my_address, &npdu_data); - len = arf_encode_apdu(&Handler_Transmit_Buffer[pdu_len], invoke_id, - &data); + pdu_len = npdu_encode_pdu( + &Handler_Transmit_Buffer[0], &dest, &my_address, &npdu_data); + len = arf_encode_apdu( + &Handler_Transmit_Buffer[pdu_len], invoke_id, &data); pdu_len += len; /* will the APDU fit the target device? note: if there is a bottleneck router in between @@ -90,23 +90,22 @@ uint8_t Send_Atomic_Read_File_Stream(uint32_t device_id, uint32_t file_instance, we have a way to check for that and update the max_apdu in the address binding table. */ if ((unsigned)pdu_len < max_apdu) { - tsm_set_confirmed_unsegmented_transaction( - invoke_id, &dest, &npdu_data, &Handler_Transmit_Buffer[0], - (uint16_t)pdu_len); + tsm_set_confirmed_unsegmented_transaction(invoke_id, &dest, + &npdu_data, &Handler_Transmit_Buffer[0], (uint16_t)pdu_len); bytes_sent = datalink_send_pdu( &dest, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len); #if PRINT_ENABLED if (bytes_sent <= 0) fprintf(stderr, "Failed to Send AtomicReadFile Request (%s)!\n", - strerror(errno)); + strerror(errno)); #endif } else { tsm_free_invoke_id(invoke_id); invoke_id = 0; #if PRINT_ENABLED fprintf(stderr, - "Failed to Send AtomicReadFile Request " - "(payload exceeds destination maximum APDU)!\n"); + "Failed to Send AtomicReadFile Request " + "(payload exceeds destination maximum APDU)!\n"); #endif } } diff --git a/src/bacnet/basic/service/s_arfs.h b/src/bacnet/basic/service/s_arfs.h new file mode 100644 index 00000000..3ea13ff1 --- /dev/null +++ b/src/bacnet/basic/service/s_arfs.h @@ -0,0 +1,51 @@ +/** +* @file +* @author Steve Karg +* @date October 2019 +* @brief Header file for a basic WritePropertyMultiple service send +* +* @section LICENSE +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +#ifndef SEND_ATOMIC_READ_FILE_STREAM_H +#define SEND_ATOMIC_READ_FILE_STREAM_H + +#include +#include +#include +#include +#include "bacnet/bacapp.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacenum.h" +#include "bacnet/apdu.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +uint8_t Send_Atomic_Read_File_Stream(uint32_t device_id, uint32_t file_instance, + int fileStartPosition, + unsigned requestedOctetCount); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/demo/handler/s_awfs.c b/src/bacnet/basic/service/s_awfs.c similarity index 73% rename from demo/handler/s_awfs.c rename to src/bacnet/basic/service/s_awfs.c index 36eb3b7e..86c919c3 100644 --- a/demo/handler/s_awfs.c +++ b/src/bacnet/basic/service/s_awfs.c @@ -26,29 +26,26 @@ #include #include #include -#include "config.h" -#include "txbuf.h" -#include "bacdef.h" -#include "bacdcode.h" -#include "address.h" -#include "tsm.h" -#include "dcc.h" -#include "npdu.h" -#include "apdu.h" -#include "device.h" -#include "datalink.h" -#include "awf.h" +#include "bacnet/config.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/dcc.h" +#include "bacnet/npdu.h" +#include "bacnet/apdu.h" +#include "bacnet/awf.h" /* some demo stuff needed */ -#include "handlers.h" -#include "txbuf.h" -#include "client.h" +#include "bacnet/basic/binding/address.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/basic/object/device.h" +#include "bacnet/datalink/datalink.h" +#include "bacnet/basic/services.h" /** @file s_awfs.c Send part of an Atomic Write File Stream request. */ uint8_t Send_Atomic_Write_File_Stream(uint32_t device_id, - uint32_t file_instance, - int fileStartPosition, - BACNET_OCTET_STRING* fileData) + uint32_t file_instance, + int fileStartPosition, + BACNET_OCTET_STRING *fileData) { BACNET_ADDRESS dest; BACNET_ADDRESS my_address; @@ -62,14 +59,16 @@ uint8_t Send_Atomic_Write_File_Stream(uint32_t device_id, BACNET_ATOMIC_WRITE_FILE_DATA data; /* if we are forbidden to send, don't send! */ - if (!dcc_communication_enabled()) + if (!dcc_communication_enabled()) { return 0; + } /* is the device bound? */ status = address_get_by_device(device_id, &max_apdu, &dest); /* is there a tsm available? */ - if (status) + if (status) { invoke_id = tsm_next_free_invokeID(); + } if (invoke_id) { /* load the data for the encoding */ data.object_type = OBJECT_FILE; @@ -81,11 +80,11 @@ uint8_t Send_Atomic_Write_File_Stream(uint32_t device_id, /* encode the NPDU portion of the packet */ datalink_get_my_address(&my_address); npdu_encode_npdu_data(&npdu_data, true, MESSAGE_PRIORITY_NORMAL); - pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest, - &my_address, &npdu_data); + pdu_len = npdu_encode_pdu( + &Handler_Transmit_Buffer[0], &dest, &my_address, &npdu_data); /* encode the APDU portion of the packet */ - len = awf_encode_apdu(&Handler_Transmit_Buffer[pdu_len], invoke_id, - &data); + len = awf_encode_apdu( + &Handler_Transmit_Buffer[pdu_len], invoke_id, &data); pdu_len += len; /* will the APDU fit the target device? note: if there is a bottleneck router in between @@ -93,23 +92,21 @@ uint8_t Send_Atomic_Write_File_Stream(uint32_t device_id, we have a way to check for that and update the max_apdu in the address binding table. */ if ((unsigned)pdu_len <= max_apdu) { - tsm_set_confirmed_unsegmented_transaction( - invoke_id, &dest, &npdu_data, &Handler_Transmit_Buffer[0], - (uint16_t)pdu_len); + tsm_set_confirmed_unsegmented_transaction(invoke_id, &dest, + &npdu_data, &Handler_Transmit_Buffer[0], (uint16_t)pdu_len); bytes_sent = datalink_send_pdu( &dest, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len); #if PRINT_ENABLED if (bytes_sent <= 0) fprintf(stderr, - "Failed to Send AtomicWriteFile Request (%s)!\n", - strerror(errno)); + "Failed to Send AtomicWriteFile Request (%s)!\n", + strerror(errno)); #endif } else { tsm_free_invoke_id(invoke_id); invoke_id = 0; #if PRINT_ENABLED - fprintf( - stderr, + fprintf(stderr, "Failed to Send AtomicWriteFile Request " "(payload [%d] exceeds destination maximum APDU [%u])!\n", pdu_len, max_apdu); @@ -120,9 +117,9 @@ uint8_t Send_Atomic_Write_File_Stream(uint32_t device_id, invoke_id = 0; #if PRINT_ENABLED fprintf(stderr, - "Failed to Send AtomicWriteFile Request " - "(payload [%d] exceeds octet string capacity)!\n", - pdu_len); + "Failed to Send AtomicWriteFile Request " + "(payload [%d] exceeds octet string capacity)!\n", + pdu_len); #endif } } diff --git a/src/bacnet/basic/service/s_awfs.h b/src/bacnet/basic/service/s_awfs.h new file mode 100644 index 00000000..ebfe3b7c --- /dev/null +++ b/src/bacnet/basic/service/s_awfs.h @@ -0,0 +1,52 @@ +/** +* @file +* @author Steve Karg +* @date October 2019 +* @brief Header file for a basic AtomicWriteFile stream service send +* +* @section LICENSE +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +#ifndef SEND_ATOMIC_WRITE_FILE_STREAM_H +#define SEND_ATOMIC_WRITE_FILE_STREAM_H + +#include +#include +#include +#include +#include "bacnet/bacapp.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacenum.h" +#include "bacnet/apdu.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +uint8_t Send_Atomic_Write_File_Stream(uint32_t device_id, + uint32_t file_instance, + int fileStartPosition, + BACNET_OCTET_STRING* fileData); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/demo/handler/s_cevent.c b/src/bacnet/basic/service/s_cevent.c similarity index 77% rename from demo/handler/s_cevent.c rename to src/bacnet/basic/service/s_cevent.c index e476bb56..4e99a793 100644 --- a/demo/handler/s_cevent.c +++ b/src/bacnet/basic/service/s_cevent.c @@ -26,16 +26,14 @@ #include #include #include -#include "event.h" -#include "device.h" -#include "datalink.h" -#include "tsm.h" -#include "dcc.h" -#include "address.h" +#include "bacnet/event.h" +#include "bacnet/dcc.h" /* some demo stuff needed */ -#include "handlers.h" -#include "txbuf.h" -#include "client.h" +#include "bacnet/basic/object/device.h" +#include "bacnet/datalink/datalink.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/basic/binding/address.h" +#include "bacnet/basic/services.h" /** @file s_cevent.c Send a ConfirmedEventNotification Request. */ @@ -47,8 +45,8 @@ * @return invoke id of outgoing message, or 0 if communication is disabled, * or no tsm slot is available. */ -uint8_t Send_CEvent_Notify(uint32_t device_id, - BACNET_EVENT_NOTIFICATION_DATA* data) +uint8_t Send_CEvent_Notify( + uint32_t device_id, BACNET_EVENT_NOTIFICATION_DATA *data) { int len = 0; int pdu_len = 0; @@ -60,23 +58,25 @@ uint8_t Send_CEvent_Notify(uint32_t device_id, bool status = false; uint8_t invoke_id = 0; - if (!dcc_communication_enabled()) + if (!dcc_communication_enabled()) { return 0; + } /* is the device bound? */ status = address_get_by_device(device_id, &max_apdu, &dest); /* is there a tsm available? */ - if (status) + if (status) { invoke_id = tsm_next_free_invokeID(); + } if (invoke_id) { /* encode the NPDU portion of the packet */ datalink_get_my_address(&my_address); npdu_encode_npdu_data(&npdu_data, true, MESSAGE_PRIORITY_NORMAL); - pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest, - &my_address, &npdu_data); + pdu_len = npdu_encode_pdu( + &Handler_Transmit_Buffer[0], &dest, &my_address, &npdu_data); /* encode the APDU portion of the packet */ - len = cevent_notify_encode_apdu(&Handler_Transmit_Buffer[pdu_len], - invoke_id, data); + len = cevent_notify_encode_apdu( + &Handler_Transmit_Buffer[pdu_len], invoke_id, data); pdu_len += len; /* will it fit in the sender? note: if there is a bottleneck router in between @@ -84,15 +84,13 @@ uint8_t Send_CEvent_Notify(uint32_t device_id, we have a way to check for that and update the max_apdu in the address binding table. */ if ((unsigned)pdu_len < max_apdu) { - tsm_set_confirmed_unsegmented_transaction( - invoke_id, &dest, &npdu_data, &Handler_Transmit_Buffer[0], - (uint16_t)pdu_len); + tsm_set_confirmed_unsegmented_transaction(invoke_id, &dest, + &npdu_data, &Handler_Transmit_Buffer[0], (uint16_t)pdu_len); bytes_sent = datalink_send_pdu( &dest, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len); #if PRINT_ENABLED if (bytes_sent <= 0) { - fprintf( - stderr, + fprintf(stderr, "Failed to Send ConfirmedEventNotification Request (%s)!\n", strerror(errno)); } @@ -102,8 +100,8 @@ uint8_t Send_CEvent_Notify(uint32_t device_id, invoke_id = 0; #if PRINT_ENABLED fprintf(stderr, - "Failed to Send ConfirmedEventNotification Request " - "(exceeds destination maximum APDU)!\n"); + "Failed to Send ConfirmedEventNotification Request " + "(exceeds destination maximum APDU)!\n"); #endif } } diff --git a/src/bacnet/basic/service/s_cevent.h b/src/bacnet/basic/service/s_cevent.h new file mode 100644 index 00000000..82651ea5 --- /dev/null +++ b/src/bacnet/basic/service/s_cevent.h @@ -0,0 +1,51 @@ +/** +* @file +* @author Steve Karg +* @date October 2019 +* @brief Header file for a basic ConfirmedEventNotification service send +* +* @section LICENSE +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +#ifndef SEND_CONFIRMED_EVENT_NOTIFICATION_H +#define SEND_CONFIRMED_EVENT_NOTIFICATION_H + +#include +#include +#include +#include +#include "bacnet/bacapp.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacenum.h" +#include "bacnet/apdu.h" +#include "bacnet/event.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +uint8_t Send_CEvent_Notify(uint32_t device_id, + BACNET_EVENT_NOTIFICATION_DATA* data); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/demo/handler/s_cov.c b/src/bacnet/basic/service/s_cov.c similarity index 78% rename from demo/handler/s_cov.c rename to src/bacnet/basic/service/s_cov.c index 5081a698..ccc12a81 100644 --- a/demo/handler/s_cov.c +++ b/src/bacnet/basic/service/s_cov.c @@ -26,21 +26,19 @@ #include #include #include -#include "config.h" -#include "bacdef.h" -#include "bacdcode.h" -#include "address.h" -#include "tsm.h" -#include "dcc.h" -#include "npdu.h" -#include "apdu.h" -#include "device.h" -#include "datalink.h" -#include "cov.h" +#include "bacnet/config.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/dcc.h" +#include "bacnet/npdu.h" +#include "bacnet/apdu.h" +#include "bacnet/cov.h" /* some demo stuff needed */ -#include "handlers.h" -#include "txbuf.h" -#include "client.h" +#include "bacnet/basic/binding/address.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/basic/object/device.h" +#include "bacnet/datalink/datalink.h" +#include "bacnet/basic/services.h" /** @file s_cov.c Send a Change of Value (COV) update or a Subscribe COV * request. */ @@ -55,9 +53,11 @@ * @param cov_data [in] The COV update information to be encoded. * @return Size of the message sent (bytes), or a negative value on error. */ -int ucov_notify_encode_pdu(uint8_t* buffer, unsigned buffer_len, - BACNET_ADDRESS* dest, BACNET_NPDU_DATA* npdu_data, - BACNET_COV_DATA* cov_data) +int ucov_notify_encode_pdu(uint8_t *buffer, + unsigned buffer_len, + BACNET_ADDRESS *dest, + BACNET_NPDU_DATA *npdu_data, + BACNET_COV_DATA *cov_data) { int len = 0; int pdu_len = 0; @@ -71,8 +71,8 @@ int ucov_notify_encode_pdu(uint8_t* buffer, unsigned buffer_len, pdu_len = npdu_encode_pdu(&buffer[0], dest, &my_address, npdu_data); /* encode the APDU portion of the packet */ - len = ucov_notify_encode_apdu(&buffer[pdu_len], buffer_len - pdu_len, - cov_data); + len = ucov_notify_encode_apdu( + &buffer[pdu_len], buffer_len - pdu_len, cov_data); if (len) { pdu_len += len; } else { @@ -90,8 +90,8 @@ int ucov_notify_encode_pdu(uint8_t* buffer, unsigned buffer_len, * @param cov_data [in] The COV update information to be encoded. * @return Size of the message sent (bytes), or a negative value on error. */ -int Send_UCOV_Notify(uint8_t* buffer, unsigned buffer_len, - BACNET_COV_DATA* cov_data) +int Send_UCOV_Notify( + uint8_t *buffer, unsigned buffer_len, BACNET_COV_DATA *cov_data) { int pdu_len = 0; BACNET_ADDRESS dest; @@ -113,8 +113,8 @@ int Send_UCOV_Notify(uint8_t* buffer, unsigned buffer_len, * @return invoke id of outgoing message, or 0 if communication is disabled or * no slot is available from the tsm for sending. */ -uint8_t Send_COV_Subscribe(uint32_t device_id, - BACNET_SUBSCRIBE_COV_DATA* cov_data) +uint8_t Send_COV_Subscribe( + uint32_t device_id, BACNET_SUBSCRIBE_COV_DATA *cov_data) { BACNET_ADDRESS dest; BACNET_ADDRESS my_address; @@ -126,8 +126,9 @@ uint8_t Send_COV_Subscribe(uint32_t device_id, int bytes_sent = 0; BACNET_NPDU_DATA npdu_data; - if (!dcc_communication_enabled()) + if (!dcc_communication_enabled()) { return 0; + } /* is the device bound? */ status = address_get_by_device(device_id, &max_apdu, &dest); /* is there a tsm available? */ @@ -138,11 +139,10 @@ uint8_t Send_COV_Subscribe(uint32_t device_id, /* encode the NPDU portion of the packet */ datalink_get_my_address(&my_address); npdu_encode_npdu_data(&npdu_data, true, MESSAGE_PRIORITY_NORMAL); - pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest, - &my_address, &npdu_data); + pdu_len = npdu_encode_pdu( + &Handler_Transmit_Buffer[0], &dest, &my_address, &npdu_data); /* encode the APDU portion of the packet */ - len = cov_subscribe_encode_apdu( - &Handler_Transmit_Buffer[pdu_len], + len = cov_subscribe_encode_apdu(&Handler_Transmit_Buffer[pdu_len], sizeof(Handler_Transmit_Buffer) - pdu_len, invoke_id, cov_data); pdu_len += len; /* will it fit in the sender? @@ -151,15 +151,14 @@ uint8_t Send_COV_Subscribe(uint32_t device_id, we have a way to check for that and update the max_apdu in the address binding table. */ if ((unsigned)pdu_len < max_apdu) { - tsm_set_confirmed_unsegmented_transaction( - invoke_id, &dest, &npdu_data, &Handler_Transmit_Buffer[0], - (uint16_t)pdu_len); + tsm_set_confirmed_unsegmented_transaction(invoke_id, &dest, + &npdu_data, &Handler_Transmit_Buffer[0], (uint16_t)pdu_len); bytes_sent = datalink_send_pdu( &dest, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len); if (bytes_sent <= 0) { #if PRINT_ENABLED fprintf(stderr, "Failed to Send SubscribeCOV Request (%s)!\n", - strerror(errno)); + strerror(errno)); #endif } } else { @@ -167,8 +166,8 @@ uint8_t Send_COV_Subscribe(uint32_t device_id, invoke_id = 0; #if PRINT_ENABLED fprintf(stderr, - "Failed to Send SubscribeCOV Request " - "(exceeds destination maximum APDU)!\n"); + "Failed to Send SubscribeCOV Request " + "(exceeds destination maximum APDU)!\n"); #endif } } diff --git a/src/bacnet/basic/service/s_cov.h b/src/bacnet/basic/service/s_cov.h new file mode 100644 index 00000000..f76a6ae1 --- /dev/null +++ b/src/bacnet/basic/service/s_cov.h @@ -0,0 +1,63 @@ +/** +* @file +* @author Steve Karg +* @date October 2019 +* @brief Header file for a basic UnconfirmedCOVNotification service send +* and SubscribeCOV service send +* +* @section LICENSE +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +#ifndef SERVICE_SEND_COV_H +#define SERVICE_SEND_COV_H + +#include +#include +#include +#include +#include "bacnet/bacapp.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacenum.h" +#include "bacnet/apdu.h" +#include "bacnet/cov.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + int Send_UCOV_Notify( + uint8_t * buffer, + unsigned buffer_len, + BACNET_COV_DATA * cov_data); + int ucov_notify_encode_pdu( + uint8_t * buffer, + unsigned buffer_len, + BACNET_ADDRESS * dest, + BACNET_NPDU_DATA * npdu_data, + BACNET_COV_DATA * cov_data); + uint8_t Send_COV_Subscribe( + uint32_t device_id, + BACNET_SUBSCRIBE_COV_DATA * cov_data); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/demo/handler/s_dcc.c b/src/bacnet/basic/service/s_dcc.c similarity index 77% rename from demo/handler/s_dcc.c rename to src/bacnet/basic/service/s_dcc.c index f743c191..5080bf45 100644 --- a/demo/handler/s_dcc.c +++ b/src/bacnet/basic/service/s_dcc.c @@ -26,21 +26,18 @@ #include #include #include -#include "config.h" -#include "txbuf.h" -#include "bacdef.h" -#include "bacdcode.h" -#include "address.h" -#include "tsm.h" -#include "npdu.h" -#include "apdu.h" -#include "device.h" -#include "datalink.h" -#include "dcc.h" +#include "bacnet/config.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/npdu.h" +#include "bacnet/apdu.h" +#include "bacnet/dcc.h" /* some demo stuff needed */ -#include "handlers.h" -#include "txbuf.h" -#include "client.h" +#include "bacnet/basic/binding/address.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/basic/object/device.h" +#include "bacnet/datalink/datalink.h" +#include "bacnet/basic/services.h" /** @file s_dcc.c Send a Device Communication Control (DCC) request. */ @@ -55,9 +52,10 @@ * @return The invokeID of the transmitted message, or 0 on failure. */ -uint8_t Send_Device_Communication_Control_Request( - uint32_t device_id, uint16_t timeDuration, /* 0=optional */ - BACNET_COMMUNICATION_ENABLE_DISABLE state, char *password) +uint8_t Send_Device_Communication_Control_Request(uint32_t device_id, + uint16_t timeDuration, /* 0=optional */ + BACNET_COMMUNICATION_ENABLE_DISABLE state, + char *password) { /* NULL=optional */ BACNET_ADDRESS dest; BACNET_ADDRESS my_address; @@ -71,25 +69,26 @@ uint8_t Send_Device_Communication_Control_Request( BACNET_NPDU_DATA npdu_data; /* if we are forbidden to send, don't send! */ - if (!dcc_communication_enabled()) + if (!dcc_communication_enabled()) { return 0; + } /* is the device bound? */ status = address_get_by_device(device_id, &max_apdu, &dest); /* is there a tsm available? */ - if (status) + if (status) { invoke_id = tsm_next_free_invokeID(); + } if (invoke_id) { /* encode the NPDU portion of the packet */ datalink_get_my_address(&my_address); npdu_encode_npdu_data(&npdu_data, true, MESSAGE_PRIORITY_NORMAL); - pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest, - &my_address, &npdu_data); + pdu_len = npdu_encode_pdu( + &Handler_Transmit_Buffer[0], &dest, &my_address, &npdu_data); /* encode the APDU portion of the packet */ characterstring_init_ansi(&password_string, password); len = dcc_encode_apdu(&Handler_Transmit_Buffer[pdu_len], invoke_id, - timeDuration, state, - password ? &password_string : NULL); + timeDuration, state, password ? &password_string : NULL); pdu_len += len; /* will it fit in the sender? note: if there is a bottleneck router in between @@ -97,15 +96,13 @@ uint8_t Send_Device_Communication_Control_Request( we have a way to check for that and update the max_apdu in the address binding table. */ if ((unsigned)pdu_len < max_apdu) { - tsm_set_confirmed_unsegmented_transaction( - invoke_id, &dest, &npdu_data, &Handler_Transmit_Buffer[0], - (uint16_t)pdu_len); + tsm_set_confirmed_unsegmented_transaction(invoke_id, &dest, + &npdu_data, &Handler_Transmit_Buffer[0], (uint16_t)pdu_len); bytes_sent = datalink_send_pdu( &dest, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len); #if PRINT_ENABLED if (bytes_sent <= 0) - fprintf( - stderr, + fprintf(stderr, "Failed to Send DeviceCommunicationControl Request (%s)!\n", strerror(errno)); #endif @@ -114,8 +111,8 @@ uint8_t Send_Device_Communication_Control_Request( invoke_id = 0; #if PRINT_ENABLED fprintf(stderr, - "Failed to Send DeviceCommunicationControl Request " - "(exceeds destination maximum APDU)!\n"); + "Failed to Send DeviceCommunicationControl Request " + "(exceeds destination maximum APDU)!\n"); #endif } } diff --git a/src/bacnet/basic/service/s_dcc.h b/src/bacnet/basic/service/s_dcc.h new file mode 100644 index 00000000..6795e1cd --- /dev/null +++ b/src/bacnet/basic/service/s_dcc.h @@ -0,0 +1,51 @@ +/** +* @file +* @author Steve Karg +* @date October 2019 +* @brief Header file for a basic DeviceCommunicationControl service send +* +* @section LICENSE +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +#ifndef SEND_DCC_H +#define SEND_DCC_H + +#include +#include +#include +#include +#include "bacnet/bacapp.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacenum.h" +#include "bacnet/apdu.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +uint8_t Send_Device_Communication_Control_Request( + uint32_t device_id, uint16_t timeDuration, + BACNET_COMMUNICATION_ENABLE_DISABLE state, char *password); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/demo/handler/s_error.c b/src/bacnet/basic/service/s_error.c similarity index 73% rename from demo/handler/s_error.c rename to src/bacnet/basic/service/s_error.c index 21f803d5..7a0edf56 100644 --- a/demo/handler/s_error.c +++ b/src/bacnet/basic/service/s_error.c @@ -26,21 +26,20 @@ #include #include #include -#include "config.h" -#include "bacdef.h" -#include "bacdcode.h" -#include "bacenum.h" -#include "bacerror.h" -#include "address.h" -#include "tsm.h" -#include "dcc.h" -#include "npdu.h" -#include "apdu.h" -#include "device.h" -#include "datalink.h" +#include "bacnet/config.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacenum.h" +#include "bacnet/bacerror.h" +#include "bacnet/dcc.h" +#include "bacnet/npdu.h" +#include "bacnet/apdu.h" /* some demo stuff needed */ -#include "handlers.h" -#include "client.h" +#include "bacnet/basic/binding/address.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/basic/object/device.h" +#include "bacnet/datalink/datalink.h" +#include "bacnet/basic/services.h" /** Encodes an Error message * @param buffer The buffer to build the message for sending. @@ -53,11 +52,14 @@ * * @return Size of the message sent (bytes), or a negative value on error. */ -int error_encode_pdu(uint8_t *buffer, BACNET_ADDRESS *dest, BACNET_ADDRESS *src, - BACNET_NPDU_DATA *npdu_data, uint8_t invoke_id, - BACNET_CONFIRMED_SERVICE service, - BACNET_ERROR_CLASS error_class, - BACNET_ERROR_CODE error_code) +int error_encode_pdu(uint8_t *buffer, + BACNET_ADDRESS *dest, + BACNET_ADDRESS *src, + BACNET_NPDU_DATA *npdu_data, + uint8_t invoke_id, + BACNET_CONFIRMED_SERVICE service, + BACNET_ERROR_CLASS error_class, + BACNET_ERROR_CODE error_code) { int len = 0; int pdu_len = 0; @@ -67,8 +69,8 @@ int error_encode_pdu(uint8_t *buffer, BACNET_ADDRESS *dest, BACNET_ADDRESS *src, pdu_len = npdu_encode_pdu(&buffer[0], dest, src, npdu_data); /* encode the APDU portion of the packet */ - len = bacerror_encode_apdu(&buffer[pdu_len], invoke_id, service, - error_class, error_code); + len = bacerror_encode_apdu( + &buffer[pdu_len], invoke_id, service, error_class, error_code); pdu_len += len; return pdu_len; @@ -83,10 +85,12 @@ int error_encode_pdu(uint8_t *buffer, BACNET_ADDRESS *dest, BACNET_ADDRESS *src, * * @return Size of the message sent (bytes), or a negative value on error. */ -int Send_Error_To_Network(uint8_t *buffer, BACNET_ADDRESS *dest, - uint8_t invoke_id, BACNET_CONFIRMED_SERVICE service, - BACNET_ERROR_CLASS error_class, - BACNET_ERROR_CODE error_code) +int Send_Error_To_Network(uint8_t *buffer, + BACNET_ADDRESS *dest, + uint8_t invoke_id, + BACNET_CONFIRMED_SERVICE service, + BACNET_ERROR_CLASS error_class, + BACNET_ERROR_CODE error_code) { int pdu_len = 0; BACNET_ADDRESS src; @@ -95,7 +99,7 @@ int Send_Error_To_Network(uint8_t *buffer, BACNET_ADDRESS *dest, datalink_get_my_address(&src); pdu_len = error_encode_pdu(buffer, dest, &src, &npdu_data, invoke_id, - service, error_class, error_code); + service, error_class, error_code); bytes_sent = datalink_send_pdu(dest, &npdu_data, &buffer[0], pdu_len); return bytes_sent; diff --git a/src/bacnet/basic/service/s_error.h b/src/bacnet/basic/service/s_error.h new file mode 100644 index 00000000..e3a4115d --- /dev/null +++ b/src/bacnet/basic/service/s_error.h @@ -0,0 +1,65 @@ +/** +* @file +* @author Steve Karg +* @date October 2019 +* @brief Header file for a basic Error message send +* +* @section LICENSE +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +#ifndef SEND_ERROR_MESSAGE_H +#define SEND_ERROR_MESSAGE_H + +#include +#include +#include +#include +#include "bacnet/bacapp.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacenum.h" +#include "bacnet/apdu.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + int Send_Error_To_Network( + uint8_t * buffer, + BACNET_ADDRESS *dest, + uint8_t invoke_id, + BACNET_CONFIRMED_SERVICE service, + BACNET_ERROR_CLASS error_class, + BACNET_ERROR_CODE error_code); + + int error_encode_pdu( + uint8_t * buffer, + BACNET_ADDRESS * dest, + BACNET_ADDRESS * src, + BACNET_NPDU_DATA * npdu_data, + uint8_t invoke_id, + BACNET_CONFIRMED_SERVICE service, + BACNET_ERROR_CLASS error_class, + BACNET_ERROR_CODE error_code); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/demo/handler/s_get_alarm_sum.c b/src/bacnet/basic/service/s_get_alarm_sum.c similarity index 74% rename from demo/handler/s_get_alarm_sum.c rename to src/bacnet/basic/service/s_get_alarm_sum.c index f1042803..00de6e5f 100644 --- a/demo/handler/s_get_alarm_sum.c +++ b/src/bacnet/basic/service/s_get_alarm_sum.c @@ -38,19 +38,17 @@ #include #include #include -#include "config.h" -#include "txbuf.h" -#include "bacdef.h" -#include "bacdcode.h" -#include "address.h" -#include "tsm.h" -#include "npdu.h" -#include "apdu.h" -#include "device.h" -#include "datalink.h" -#include "handlers.h" -#include "client.h" -#include "get_alarm_sum.h" +#include "bacnet/config.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/npdu.h" +#include "bacnet/apdu.h" +#include "bacnet/get_alarm_sum.h" +#include "bacnet/basic/binding/address.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/basic/object/device.h" +#include "bacnet/datalink/datalink.h" +#include "bacnet/basic/services.h" uint8_t Send_Get_Alarm_Summary_Address(BACNET_ADDRESS *dest, uint16_t max_apdu) { @@ -70,35 +68,34 @@ uint8_t Send_Get_Alarm_Summary_Address(BACNET_ADDRESS *dest, uint16_t max_apdu) /* encode the NPDU portion of the packet */ npdu_encode_npdu_data(&npdu_data, true, MESSAGE_PRIORITY_NORMAL); - pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], dest, - &my_address, &npdu_data); + pdu_len = npdu_encode_pdu( + &Handler_Transmit_Buffer[0], dest, &my_address, &npdu_data); /* encode the APDU portion of the packet */ - len = get_alarm_summary_encode_apdu(&Handler_Transmit_Buffer[pdu_len], - invoke_id); + len = get_alarm_summary_encode_apdu( + &Handler_Transmit_Buffer[pdu_len], invoke_id); pdu_len += len; if ((uint16_t)pdu_len < max_apdu) { - tsm_set_confirmed_unsegmented_transaction( - invoke_id, dest, &npdu_data, &Handler_Transmit_Buffer[0], - (uint16_t)pdu_len); + tsm_set_confirmed_unsegmented_transaction(invoke_id, dest, + &npdu_data, &Handler_Transmit_Buffer[0], (uint16_t)pdu_len); #if PRINT_ENABLED bytes_sent = #endif - datalink_send_pdu(dest, &npdu_data, &Handler_Transmit_Buffer[0], - pdu_len); + datalink_send_pdu( + dest, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len); #if PRINT_ENABLED if (bytes_sent <= 0) fprintf(stderr, - "Failed to Send Get Alarm Summary Request (%s)!\n", - strerror(errno)); + "Failed to Send Get Alarm Summary Request (%s)!\n", + strerror(errno)); #endif } else { tsm_free_invoke_id(invoke_id); invoke_id = 0; #if PRINT_ENABLED fprintf(stderr, - "Failed to Send Get Alarm Summary Request " - "(exceeds destination maximum APDU)!\n"); + "Failed to Send Get Alarm Summary Request " + "(exceeds destination maximum APDU)!\n"); #endif } } diff --git a/src/bacnet/basic/service/s_get_alarm_sum.h b/src/bacnet/basic/service/s_get_alarm_sum.h new file mode 100644 index 00000000..c8b16d99 --- /dev/null +++ b/src/bacnet/basic/service/s_get_alarm_sum.h @@ -0,0 +1,50 @@ +/** +* @file +* @author Steve Karg +* @date October 2019 +* @brief Header file for a basic GetAlarmSummary service send +* +* @section LICENSE +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +#ifndef SEND_GET_ALARM_SUMMARY_H +#define SEND_GET_ALARM_SUMMARY_H + +#include +#include +#include +#include +#include "bacnet/bacapp.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacenum.h" +#include "bacnet/apdu.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +uint8_t Send_Get_Alarm_Summary_Address(BACNET_ADDRESS *dest, uint16_t max_apdu); +uint8_t Send_Get_Alarm_Summary(uint32_t device_id); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/demo/handler/s_get_event.c b/src/bacnet/basic/service/s_get_event.c similarity index 75% rename from demo/handler/s_get_event.c rename to src/bacnet/basic/service/s_get_event.c index ce3cef07..0b38ebd1 100644 --- a/demo/handler/s_get_event.c +++ b/src/bacnet/basic/service/s_get_event.c @@ -40,22 +40,21 @@ #include #include #include -#include "config.h" -#include "txbuf.h" -#include "bacdef.h" -#include "bacdcode.h" -#include "address.h" -#include "tsm.h" -#include "npdu.h" -#include "apdu.h" -#include "device.h" -#include "datalink.h" -#include "handlers.h" -#include "client.h" -#include "getevent.h" +#include "bacnet/config.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/npdu.h" +#include "bacnet/apdu.h" +#include "bacnet/getevent.h" +/* some demo stuff needed */ +#include "bacnet/basic/binding/address.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/basic/object/device.h" +#include "bacnet/datalink/datalink.h" +#include "bacnet/basic/services.h" -uint8_t Send_Get_Event_Information_Address( - BACNET_ADDRESS *dest, uint16_t max_apdu, +uint8_t Send_Get_Event_Information_Address(BACNET_ADDRESS *dest, + uint16_t max_apdu, BACNET_OBJECT_ID *lastReceivedObjectIdentifier) { int len = 0; @@ -73,35 +72,34 @@ uint8_t Send_Get_Event_Information_Address( datalink_get_my_address(&my_address); /* encode the NPDU portion of the packet */ npdu_encode_npdu_data(&npdu_data, true, MESSAGE_PRIORITY_NORMAL); - pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], dest, - &my_address, &npdu_data); + pdu_len = npdu_encode_pdu( + &Handler_Transmit_Buffer[0], dest, &my_address, &npdu_data); /* encode the APDU portion of the packet */ len = getevent_encode_apdu(&Handler_Transmit_Buffer[pdu_len], invoke_id, - lastReceivedObjectIdentifier); + lastReceivedObjectIdentifier); pdu_len += len; if ((uint16_t)pdu_len < max_apdu) { - tsm_set_confirmed_unsegmented_transaction( - invoke_id, dest, &npdu_data, &Handler_Transmit_Buffer[0], - (uint16_t)pdu_len); + tsm_set_confirmed_unsegmented_transaction(invoke_id, dest, + &npdu_data, &Handler_Transmit_Buffer[0], (uint16_t)pdu_len); #if PRINT_ENABLED bytes_sent = #endif - datalink_send_pdu(dest, &npdu_data, &Handler_Transmit_Buffer[0], - pdu_len); + datalink_send_pdu( + dest, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len); #if PRINT_ENABLED if (bytes_sent <= 0) fprintf(stderr, - "Failed to Send Get Event Information Request (%s)!\n", - strerror(errno)); + "Failed to Send Get Event Information Request (%s)!\n", + strerror(errno)); #endif } else { tsm_free_invoke_id(invoke_id); invoke_id = 0; #if PRINT_ENABLED fprintf(stderr, - "Failed to Send Get Event Information Request " - "(exceeds destination maximum APDU)!\n"); + "Failed to Send Get Event Information Request " + "(exceeds destination maximum APDU)!\n"); #endif } } @@ -112,7 +110,7 @@ uint8_t Send_Get_Event_Information_Address( uint8_t Send_Get_Event_Information( uint32_t device_id, BACNET_OBJECT_ID *lastReceivedObjectIdentifier) { - BACNET_ADDRESS dest = {0}; + BACNET_ADDRESS dest = { 0 }; unsigned max_apdu = 0; uint8_t invoke_id = 0; bool status = false; diff --git a/src/bacnet/basic/service/s_get_event.h b/src/bacnet/basic/service/s_get_event.h new file mode 100644 index 00000000..53edcc84 --- /dev/null +++ b/src/bacnet/basic/service/s_get_event.h @@ -0,0 +1,53 @@ +/** +* @file +* @author Steve Karg +* @date October 2019 +* @brief Header file for a basic GetEventInformation service send +* +* @section LICENSE +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +#ifndef SEND_GET_EVENT_INFORMATION_H +#define SEND_GET_EVENT_INFORMATION_H + +#include +#include +#include +#include +#include "bacnet/bacapp.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacenum.h" +#include "bacnet/apdu.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +uint8_t Send_Get_Event_Information_Address( + BACNET_ADDRESS *dest, uint16_t max_apdu, + BACNET_OBJECT_ID *lastReceivedObjectIdentifier); +uint8_t Send_Get_Event_Information( + uint32_t device_id, BACNET_OBJECT_ID *lastReceivedObjectIdentifier); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/demo/handler/s_getevent.c b/src/bacnet/basic/service/s_getevent.c similarity index 71% rename from demo/handler/s_getevent.c rename to src/bacnet/basic/service/s_getevent.c index 0d967917..b2c71c72 100644 --- a/demo/handler/s_getevent.c +++ b/src/bacnet/basic/service/s_getevent.c @@ -26,23 +26,20 @@ #include #include #include -#include "config.h" -#include "txbuf.h" -#include "bacdef.h" -#include "bacdcode.h" -#include "address.h" -#include "tsm.h" -#include "npdu.h" -#include "apdu.h" -#include "device.h" -#include "datalink.h" -#include "dcc.h" -#include "getevent.h" -#include "bacenum.h" +#include "bacnet/config.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/npdu.h" +#include "bacnet/apdu.h" +#include "bacnet/dcc.h" +#include "bacnet/getevent.h" +#include "bacnet/bacenum.h" /* some demo stuff needed */ -#include "handlers.h" -#include "txbuf.h" -#include "client.h" +#include "bacnet/basic/binding/address.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/basic/object/device.h" +#include "bacnet/datalink/datalink.h" +#include "bacnet/basic/services.h" /** @file s_getevent.c Send a GetEventInformation request. */ @@ -50,8 +47,8 @@ * device, a range, or any device. * @param target_address [in] BACnet address of target or broadcast */ -uint8_t Send_GetEvent(BACNET_ADDRESS* target_address, - BACNET_OBJECT_ID* lastReceivedObjectIdentifier) +uint8_t Send_GetEvent(BACNET_ADDRESS *target_address, + BACNET_OBJECT_ID *lastReceivedObjectIdentifier) { int len = 0; int pdu_len = 0; @@ -64,30 +61,30 @@ uint8_t Send_GetEvent(BACNET_ADDRESS* target_address, /* encode the NPDU portion of the packet */ npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL); - pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], target_address, - &my_address, &npdu_data); + pdu_len = npdu_encode_pdu( + &Handler_Transmit_Buffer[0], target_address, &my_address, &npdu_data); invoke_id = tsm_next_free_invokeID(); if (invoke_id) { /* encode the APDU portion of the packet */ len = getevent_encode_apdu(&Handler_Transmit_Buffer[pdu_len], invoke_id, - lastReceivedObjectIdentifier); + lastReceivedObjectIdentifier); pdu_len += len; - bytes_sent = datalink_send_pdu(target_address, &npdu_data, - &Handler_Transmit_Buffer[0], pdu_len); + bytes_sent = datalink_send_pdu( + target_address, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len); #if PRINT_ENABLED if (bytes_sent <= 0) fprintf(stderr, - "Failed to Send GetEventInformation Request (%s)!\n", - strerror(errno)); + "Failed to Send GetEventInformation Request (%s)!\n", + strerror(errno)); #endif } else { tsm_free_invoke_id(invoke_id); invoke_id = 0; #if PRINT_ENABLED fprintf(stderr, - "Failed to Send GetEventInformation Request " - "(exceeds destination maximum APDU)!\n"); + "Failed to Send GetEventInformation Request " + "(exceeds destination maximum APDU)!\n"); #endif } return invoke_id; @@ -99,8 +96,9 @@ uint8_t Send_GetEvent_Global(void) { BACNET_ADDRESS dest; - if (!dcc_communication_enabled()) + if (!dcc_communication_enabled()) { return -1; + } datalink_get_broadcast_address(&dest); diff --git a/src/bacnet/basic/service/s_getevent.h b/src/bacnet/basic/service/s_getevent.h new file mode 100644 index 00000000..cdcf05b9 --- /dev/null +++ b/src/bacnet/basic/service/s_getevent.h @@ -0,0 +1,51 @@ +/** +* @file +* @author Steve Karg +* @date October 2019 +* @brief Header file for a basic GetEvent service send +* +* @section LICENSE +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +#ifndef SEND_GET_EVENT_H +#define SEND_GET_EVENT_H + +#include +#include +#include +#include +#include "bacnet/bacapp.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacenum.h" +#include "bacnet/apdu.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +uint8_t Send_GetEvent(BACNET_ADDRESS* target_address, + BACNET_OBJECT_ID* lastReceivedObjectIdentifier); +uint8_t Send_GetEvent_Global(void); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/demo/handler/s_iam.c b/src/bacnet/basic/service/s_iam.c similarity index 82% rename from demo/handler/s_iam.c rename to src/bacnet/basic/service/s_iam.c index 10440d22..1a069378 100644 --- a/demo/handler/s_iam.c +++ b/src/bacnet/basic/service/s_iam.c @@ -26,21 +26,19 @@ #include #include #include -#include "config.h" -#include "bacdef.h" -#include "bacdcode.h" -#include "address.h" -#include "tsm.h" -#include "dcc.h" -#include "npdu.h" -#include "apdu.h" -#include "device.h" -#include "datalink.h" -#include "iam.h" -#include "txbuf.h" +#include "bacnet/config.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/dcc.h" +#include "bacnet/npdu.h" +#include "bacnet/apdu.h" +#include "bacnet/iam.h" /* some demo stuff needed */ -#include "handlers.h" -#include "client.h" +#include "bacnet/basic/binding/address.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/basic/object/device.h" +#include "bacnet/datalink/datalink.h" +#include "bacnet/basic/services.h" /** @file s_iam.c Send an I-Am message. */ @@ -51,9 +49,11 @@ * @param segmentation [in] #BACNET_SEGMENTATION enumeration * @param vendor_id [in] BACnet vendor ID 0-65535 */ -void Send_I_Am_To_Network(BACNET_ADDRESS* target_address, uint32_t device_id, - unsigned int max_apdu, int segmentation, - uint16_t vendor_id) +void Send_I_Am_To_Network(BACNET_ADDRESS *target_address, + uint32_t device_id, + unsigned int max_apdu, + int segmentation, + uint16_t vendor_id) { int len = 0; int pdu_len = 0; @@ -65,15 +65,15 @@ void Send_I_Am_To_Network(BACNET_ADDRESS* target_address, uint32_t device_id, /* encode the NPDU portion of the packet */ npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL); - pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], target_address, - &my_address, &npdu_data); + pdu_len = npdu_encode_pdu( + &Handler_Transmit_Buffer[0], target_address, &my_address, &npdu_data); /* encode the APDU portion of the packet */ /* encode the APDU portion of the packet */ len = iam_encode_apdu(&Handler_Transmit_Buffer[pdu_len], device_id, - max_apdu, segmentation, vendor_id); + max_apdu, segmentation, vendor_id); pdu_len += len; - bytes_sent = datalink_send_pdu(target_address, &npdu_data, - &Handler_Transmit_Buffer[0], pdu_len); + bytes_sent = datalink_send_pdu( + target_address, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len); if (bytes_sent <= 0) { #if PRINT_ENABLED fprintf(stderr, "Failed to Send I-Am Request (%s)!\n", strerror(errno)); @@ -87,8 +87,8 @@ void Send_I_Am_To_Network(BACNET_ADDRESS* target_address, uint32_t device_id, * @param npdu_data [out] The NPDU structure describing the message. * @return The length of the message in buffer[]. */ -int iam_encode_pdu(uint8_t* buffer, BACNET_ADDRESS* dest, - BACNET_NPDU_DATA* npdu_data) +int iam_encode_pdu( + uint8_t *buffer, BACNET_ADDRESS *dest, BACNET_NPDU_DATA *npdu_data) { int len = 0; int pdu_len = 0; @@ -102,8 +102,7 @@ int iam_encode_pdu(uint8_t* buffer, BACNET_ADDRESS* dest, /* encode the APDU portion of the packet */ len = iam_encode_apdu(&buffer[pdu_len], Device_Object_Instance_Number(), - MAX_APDU, SEGMENTATION_NONE, - Device_Vendor_Identifier()); + MAX_APDU, SEGMENTATION_NONE, Device_Vendor_Identifier()); pdu_len += len; return pdu_len; @@ -114,7 +113,7 @@ int iam_encode_pdu(uint8_t* buffer, BACNET_ADDRESS* dest, * * @param buffer [in] The buffer to use for building and sending the message. */ -void Send_I_Am(uint8_t* buffer) +void Send_I_Am(uint8_t *buffer) { int pdu_len = 0; BACNET_ADDRESS dest; @@ -154,8 +153,10 @@ void Send_I_Am(uint8_t* buffer) * @param npdu_data [out] The NPDU structure describing the message. * @return The length of the message in buffer[]. */ -int iam_unicast_encode_pdu(uint8_t* buffer, BACNET_ADDRESS* src, - BACNET_ADDRESS* dest, BACNET_NPDU_DATA* npdu_data) +int iam_unicast_encode_pdu(uint8_t *buffer, + BACNET_ADDRESS *src, + BACNET_ADDRESS *dest, + BACNET_NPDU_DATA *npdu_data) { int npdu_len = 0; int apdu_len = 0; @@ -170,9 +171,9 @@ int iam_unicast_encode_pdu(uint8_t* buffer, BACNET_ADDRESS* src, npdu_encode_npdu_data(npdu_data, false, MESSAGE_PRIORITY_NORMAL); npdu_len = npdu_encode_pdu(&buffer[0], dest, &my_address, npdu_data); /* encode the APDU portion of the packet */ - apdu_len = iam_encode_apdu(&buffer[npdu_len], - Device_Object_Instance_Number(), MAX_APDU, - SEGMENTATION_NONE, Device_Vendor_Identifier()); + apdu_len = + iam_encode_apdu(&buffer[npdu_len], Device_Object_Instance_Number(), + MAX_APDU, SEGMENTATION_NONE, Device_Vendor_Identifier()); pdu_len = npdu_len + apdu_len; return pdu_len; @@ -189,7 +190,7 @@ int iam_unicast_encode_pdu(uint8_t* buffer, BACNET_ADDRESS* src, * @param buffer [in] The buffer to use for building and sending the message. * @param src [in] The source address information from service handler. */ -void Send_I_Am_Unicast(uint8_t* buffer, BACNET_ADDRESS* src) +void Send_I_Am_Unicast(uint8_t *buffer, BACNET_ADDRESS *src) { int pdu_len = 0; BACNET_ADDRESS dest; diff --git a/src/bacnet/basic/service/s_iam.h b/src/bacnet/basic/service/s_iam.h new file mode 100644 index 00000000..7c3028aa --- /dev/null +++ b/src/bacnet/basic/service/s_iam.h @@ -0,0 +1,58 @@ +/** +* @file +* @author Steve Karg +* @date October 2019 +* @brief Header file for a basic I-Am service send +* +* @section LICENSE +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +#ifndef SEND_I_AM_H +#define SEND_I_AM_H + +#include +#include +#include +#include +#include "bacnet/apdu.h" +#include "bacnet/bacapp.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacenum.h" +#include "bacnet/npdu.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +void Send_I_Am_To_Network(BACNET_ADDRESS* target_address, uint32_t device_id, + unsigned int max_apdu, int segmentation, + uint16_t vendor_id); +int iam_encode_pdu(uint8_t* buffer, BACNET_ADDRESS* dest, + BACNET_NPDU_DATA* npdu_data); +void Send_I_Am(uint8_t* buffer); +int iam_unicast_encode_pdu(uint8_t* buffer, BACNET_ADDRESS* src, + BACNET_ADDRESS* dest, BACNET_NPDU_DATA* npdu_data); +void Send_I_Am_Unicast(uint8_t* buffer, BACNET_ADDRESS* src); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/demo/handler/s_ihave.c b/src/bacnet/basic/service/s_ihave.c similarity index 78% rename from demo/handler/s_ihave.c rename to src/bacnet/basic/service/s_ihave.c index 11864ce5..1b78eb82 100644 --- a/demo/handler/s_ihave.c +++ b/src/bacnet/basic/service/s_ihave.c @@ -26,22 +26,19 @@ #include #include #include -#include "config.h" -#include "txbuf.h" -#include "bacdef.h" -#include "bacdcode.h" -#include "address.h" -#include "tsm.h" -#include "npdu.h" -#include "apdu.h" -#include "device.h" -#include "datalink.h" -#include "dcc.h" -#include "ihave.h" +#include "bacnet/config.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/npdu.h" +#include "bacnet/apdu.h" +#include "bacnet/dcc.h" +#include "bacnet/ihave.h" /* some demo stuff needed */ -#include "handlers.h" -#include "txbuf.h" -#include "client.h" +#include "bacnet/basic/binding/address.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/basic/object/device.h" +#include "bacnet/datalink/datalink.h" +#include "bacnet/basic/services.h" /** @file s_ihave.c Send an I-Have (property) message. */ @@ -53,8 +50,10 @@ * @param object_instance [in] The Object ID that I Have. * @param object_name [in] The Name of the Object I Have. */ -void Send_I_Have(uint32_t device_id, BACNET_OBJECT_TYPE object_type, - uint32_t object_instance, BACNET_CHARACTER_STRING* object_name) +void Send_I_Have(uint32_t device_id, + BACNET_OBJECT_TYPE object_type, + uint32_t object_instance, + BACNET_CHARACTER_STRING *object_name) { int len = 0; int pdu_len = 0; @@ -66,14 +65,15 @@ void Send_I_Have(uint32_t device_id, BACNET_OBJECT_TYPE object_type, datalink_get_my_address(&my_address); /* if we are forbidden to send, don't send! */ - if (!dcc_communication_enabled()) + if (!dcc_communication_enabled()) { return; + } /* Who-Has is a global broadcast */ datalink_get_broadcast_address(&dest); /* encode the NPDU portion of the packet */ npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL); - pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest, &my_address, - &npdu_data); + pdu_len = npdu_encode_pdu( + &Handler_Transmit_Buffer[0], &dest, &my_address, &npdu_data); /* encode the APDU portion of the packet */ data.device_id.type = OBJECT_DEVICE; @@ -84,8 +84,8 @@ void Send_I_Have(uint32_t device_id, BACNET_OBJECT_TYPE object_type, len = ihave_encode_apdu(&Handler_Transmit_Buffer[pdu_len], &data); pdu_len += len; /* send the data */ - bytes_sent = datalink_send_pdu(&dest, &npdu_data, - &Handler_Transmit_Buffer[0], pdu_len); + bytes_sent = datalink_send_pdu( + &dest, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len); if (bytes_sent <= 0) { #if PRINT_ENABLED fprintf(stderr, "Failed to Send I-Have Reply (%s)!\n", strerror(errno)); diff --git a/src/bacnet/basic/service/s_ihave.h b/src/bacnet/basic/service/s_ihave.h new file mode 100644 index 00000000..b50dcd65 --- /dev/null +++ b/src/bacnet/basic/service/s_ihave.h @@ -0,0 +1,53 @@ +/** +* @file +* @author Steve Karg +* @date October 2019 +* @brief Header file for a basic I-Have service send +* +* @section LICENSE +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +#ifndef SEND_I_HAVE_H +#define SEND_I_HAVE_H + +#include +#include +#include +#include +#include "bacnet/bacapp.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacenum.h" +#include "bacnet/apdu.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + void Send_I_Have( + uint32_t device_id, + BACNET_OBJECT_TYPE object_type, + uint32_t object_instance, + BACNET_CHARACTER_STRING * object_name); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/demo/handler/s_lso.c b/src/bacnet/basic/service/s_lso.c similarity index 75% rename from demo/handler/s_lso.c rename to src/bacnet/basic/service/s_lso.c index 3527d859..94c4a191 100644 --- a/demo/handler/s_lso.c +++ b/src/bacnet/basic/service/s_lso.c @@ -26,30 +26,27 @@ #include #include #include -#include "config.h" -#include "txbuf.h" -#include "bacdef.h" -#include "bacdcode.h" -#include "address.h" -#include "tsm.h" -#include "npdu.h" -#include "apdu.h" -#include "device.h" -#include "datalink.h" -#include "dcc.h" -#include "whois.h" +#include "bacnet/config.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/npdu.h" +#include "bacnet/apdu.h" +#include "bacnet/dcc.h" +#include "bacnet/whois.h" +#include "bacnet/lso.h" /* some demo stuff needed */ -#include "handlers.h" -#include "txbuf.h" -#include "lso.h" -#include "client.h" +#include "bacnet/basic/binding/address.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/object/device.h" +#include "bacnet/datalink/datalink.h" /** @file s_lso.c Send BACnet Life Safety Operation message. */ /* returns the invoke ID for confirmed request, or zero on failure */ -uint8_t Send_Life_Safety_Operation_Data(uint32_t device_id, - BACNET_LSO_DATA* data) +uint8_t Send_Life_Safety_Operation_Data( + uint32_t device_id, BACNET_LSO_DATA *data) { BACNET_ADDRESS dest; BACNET_ADDRESS my_address; @@ -61,20 +58,22 @@ uint8_t Send_Life_Safety_Operation_Data(uint32_t device_id, int bytes_sent = 0; BACNET_NPDU_DATA npdu_data; - if (!dcc_communication_enabled()) + if (!dcc_communication_enabled()) { return 0; + } /* is the device bound? */ status = address_get_by_device(device_id, &max_apdu, &dest); /* is there a tsm available? */ - if (status) + if (status) { invoke_id = tsm_next_free_invokeID(); + } if (invoke_id) { /* encode the NPDU portion of the packet */ datalink_get_my_address(&my_address); npdu_encode_npdu_data(&npdu_data, true, MESSAGE_PRIORITY_NORMAL); - pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest, - &my_address, &npdu_data); + pdu_len = npdu_encode_pdu( + &Handler_Transmit_Buffer[0], &dest, &my_address, &npdu_data); len = lso_encode_apdu(&Handler_Transmit_Buffer[pdu_len], invoke_id, data); pdu_len += len; @@ -84,23 +83,22 @@ uint8_t Send_Life_Safety_Operation_Data(uint32_t device_id, we have a way to check for that and update the max_apdu in the address binding table. */ if ((unsigned)pdu_len < max_apdu) { - tsm_set_confirmed_unsegmented_transaction( - invoke_id, &dest, &npdu_data, &Handler_Transmit_Buffer[0], - (uint16_t)pdu_len); + tsm_set_confirmed_unsegmented_transaction(invoke_id, &dest, + &npdu_data, &Handler_Transmit_Buffer[0], (uint16_t)pdu_len); bytes_sent = datalink_send_pdu( &dest, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len); #if PRINT_ENABLED if (bytes_sent <= 0) fprintf(stderr, "Failed to Send Life Safe Op Request (%s)!\n", - strerror(errno)); + strerror(errno)); #endif } else { tsm_free_invoke_id(invoke_id); invoke_id = 0; #if PRINT_ENABLED fprintf(stderr, - "Failed to Send Life Safe Op Request " - "(exceeds destination maximum APDU)!\n"); + "Failed to Send Life Safe Op Request " + "(exceeds destination maximum APDU)!\n"); #endif } } diff --git a/src/bacnet/basic/service/s_lso.h b/src/bacnet/basic/service/s_lso.h new file mode 100644 index 00000000..0805b0bd --- /dev/null +++ b/src/bacnet/basic/service/s_lso.h @@ -0,0 +1,51 @@ +/** +* @file +* @author Steve Karg +* @date October 2019 +* @brief Header file for a basic LifeSafetyOperation service send +* +* @section LICENSE +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +#ifndef SEND_LIFE_SAFETY_OPERATION_H +#define SEND_LIFE_SAFETY_OPERATION_H + +#include +#include +#include +#include +#include "bacnet/bacapp.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacenum.h" +#include "bacnet/apdu.h" +#include "bacnet/lso.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +uint8_t Send_Life_Safety_Operation_Data(uint32_t device_id, + BACNET_LSO_DATA* data); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/demo/handler/s_rd.c b/src/bacnet/basic/service/s_rd.c similarity index 75% rename from demo/handler/s_rd.c rename to src/bacnet/basic/service/s_rd.c index 08664ca2..c649a056 100644 --- a/demo/handler/s_rd.c +++ b/src/bacnet/basic/service/s_rd.c @@ -26,22 +26,19 @@ #include #include #include -#include "config.h" -#include "txbuf.h" -#include "bacdef.h" -#include "bacdcode.h" -#include "address.h" -#include "tsm.h" -#include "npdu.h" -#include "apdu.h" -#include "device.h" -#include "datalink.h" -#include "dcc.h" -#include "rd.h" +#include "bacnet/config.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/npdu.h" +#include "bacnet/apdu.h" +#include "bacnet/dcc.h" +#include "bacnet/rd.h" /* some demo stuff needed */ -#include "handlers.h" -#include "txbuf.h" -#include "client.h" +#include "bacnet/basic/binding/address.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/basic/object/device.h" +#include "bacnet/datalink/datalink.h" +#include "bacnet/basic/services.h" /** @file s_rd.c Send a Reinitialize Device request. */ @@ -54,9 +51,8 @@ * @param password [in] Optional password, up to 20 chars. * @return The invokeID of the transmitted message, or 0 on failure. */ -uint8_t Send_Reinitialize_Device_Request(uint32_t device_id, - BACNET_REINITIALIZED_STATE state, - char *password) +uint8_t Send_Reinitialize_Device_Request( + uint32_t device_id, BACNET_REINITIALIZED_STATE state, char *password) { BACNET_ADDRESS dest; BACNET_ADDRESS my_address; @@ -70,24 +66,26 @@ uint8_t Send_Reinitialize_Device_Request(uint32_t device_id, BACNET_NPDU_DATA npdu_data; /* if we are forbidden to send, don't send! */ - if (!dcc_communication_enabled()) + if (!dcc_communication_enabled()) { return 0; + } /* is the device bound? */ status = address_get_by_device(device_id, &max_apdu, &dest); /* is there a tsm available? */ - if (status) + if (status) { invoke_id = tsm_next_free_invokeID(); + } if (invoke_id) { /* encode the NPDU portion of the packet */ datalink_get_my_address(&my_address); npdu_encode_npdu_data(&npdu_data, true, MESSAGE_PRIORITY_NORMAL); - pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest, - &my_address, &npdu_data); + pdu_len = npdu_encode_pdu( + &Handler_Transmit_Buffer[0], &dest, &my_address, &npdu_data); /* encode the APDU portion of the packet */ characterstring_init_ansi(&password_string, password); len = rd_encode_apdu(&Handler_Transmit_Buffer[pdu_len], invoke_id, - state, password ? &password_string : NULL); + state, password ? &password_string : NULL); pdu_len += len; /* will it fit in the sender? note: if there is a bottleneck router in between @@ -95,24 +93,23 @@ uint8_t Send_Reinitialize_Device_Request(uint32_t device_id, we have a way to check for that and update the max_apdu in the address binding table. */ if ((unsigned)pdu_len < max_apdu) { - tsm_set_confirmed_unsegmented_transaction( - invoke_id, &dest, &npdu_data, &Handler_Transmit_Buffer[0], - (uint16_t)pdu_len); + tsm_set_confirmed_unsegmented_transaction(invoke_id, &dest, + &npdu_data, &Handler_Transmit_Buffer[0], (uint16_t)pdu_len); bytes_sent = datalink_send_pdu( &dest, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len); #if PRINT_ENABLED if (bytes_sent <= 0) fprintf(stderr, - "Failed to Send ReinitializeDevice Request (%s)!\n", - strerror(errno)); + "Failed to Send ReinitializeDevice Request (%s)!\n", + strerror(errno)); #endif } else { tsm_free_invoke_id(invoke_id); invoke_id = 0; #if PRINT_ENABLED fprintf(stderr, - "Failed to Send ReinitializeDevice Request " - "(exceeds destination maximum APDU)!\n"); + "Failed to Send ReinitializeDevice Request " + "(exceeds destination maximum APDU)!\n"); #endif } } diff --git a/src/bacnet/basic/service/s_rd.h b/src/bacnet/basic/service/s_rd.h new file mode 100644 index 00000000..e663de60 --- /dev/null +++ b/src/bacnet/basic/service/s_rd.h @@ -0,0 +1,51 @@ +/** +* @file +* @author Steve Karg +* @date October 2019 +* @brief Header file for a basic ReinitializeDevice service send +* +* @section LICENSE +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +#ifndef SEND_REINITIALIZE_DEVICE_H +#define SEND_REINITIALIZE_DEVICE_H + +#include +#include +#include +#include +#include "bacnet/bacapp.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacenum.h" +#include "bacnet/apdu.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +uint8_t Send_Reinitialize_Device_Request(uint32_t device_id, + BACNET_REINITIALIZED_STATE state, + char *password); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/demo/handler/s_readrange.c b/src/bacnet/basic/service/s_readrange.c similarity index 75% rename from demo/handler/s_readrange.c rename to src/bacnet/basic/service/s_readrange.c index efac05a8..f173180a 100644 --- a/demo/handler/s_readrange.c +++ b/src/bacnet/basic/service/s_readrange.c @@ -26,29 +26,26 @@ #include #include #include -#include "config.h" -#include "txbuf.h" -#include "bacdef.h" -#include "bacdcode.h" -#include "address.h" -#include "tsm.h" -#include "npdu.h" -#include "apdu.h" -#include "device.h" -#include "datalink.h" -#include "dcc.h" -#include "rpm.h" +#include "bacnet/config.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/npdu.h" +#include "bacnet/apdu.h" +#include "bacnet/dcc.h" +#include "bacnet/rpm.h" +#include "bacnet/readrange.h" /* some demo stuff needed */ -#include "handlers.h" -#include "txbuf.h" -#include "readrange.h" -#include "client.h" +#include "bacnet/basic/binding/address.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/basic/object/device.h" +#include "bacnet/datalink/datalink.h" +#include "bacnet/basic/services.h" /** @file s_readrange.c Send a ReadRange request. */ /* returns invoke id of 0 if device is not bound or no tsm available */ uint8_t Send_ReadRange_Request(uint32_t device_id, /* destination device */ - BACNET_READ_RANGE_DATA* read_access_data) + BACNET_READ_RANGE_DATA *read_access_data) { BACNET_ADDRESS dest; BACNET_ADDRESS my_address; @@ -60,25 +57,27 @@ uint8_t Send_ReadRange_Request(uint32_t device_id, /* destination device */ int bytes_sent = 0; BACNET_NPDU_DATA npdu_data; - if (!dcc_communication_enabled()) + if (!dcc_communication_enabled()) { return 0; + } /* is the device bound? */ status = address_get_by_device(device_id, &max_apdu, &dest); /* is there a tsm available? */ - if (status) + if (status) { invoke_id = tsm_next_free_invokeID(); + } if (invoke_id) { /* encode the NPDU portion of the packet */ datalink_get_my_address(&my_address); npdu_encode_npdu_data(&npdu_data, true, MESSAGE_PRIORITY_NORMAL); - pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest, - &my_address, &npdu_data); + pdu_len = npdu_encode_pdu( + &Handler_Transmit_Buffer[0], &dest, &my_address, &npdu_data); /* encode the APDU portion of the packet */ - len = rr_encode_apdu(&Handler_Transmit_Buffer[pdu_len], invoke_id, - read_access_data); + len = rr_encode_apdu( + &Handler_Transmit_Buffer[pdu_len], invoke_id, read_access_data); if (len <= 0) { return 0; } @@ -90,23 +89,22 @@ uint8_t Send_ReadRange_Request(uint32_t device_id, /* destination device */ we have a way to check for that and update the max_apdu in the address binding table. */ if ((unsigned)pdu_len < max_apdu) { - tsm_set_confirmed_unsegmented_transaction( - invoke_id, &dest, &npdu_data, &Handler_Transmit_Buffer[0], - (uint16_t)pdu_len); + tsm_set_confirmed_unsegmented_transaction(invoke_id, &dest, + &npdu_data, &Handler_Transmit_Buffer[0], (uint16_t)pdu_len); bytes_sent = datalink_send_pdu( &dest, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len); #if PRINT_ENABLED if (bytes_sent <= 0) fprintf(stderr, "Failed to Send ReadRange Request (%s)!\n", - strerror(errno)); + strerror(errno)); #endif } else { tsm_free_invoke_id(invoke_id); invoke_id = 0; #if PRINT_ENABLED fprintf(stderr, - "Failed to Send ReadRange Request (exceeds destination " - "maximum APDU)!\n"); + "Failed to Send ReadRange Request (exceeds destination " + "maximum APDU)!\n"); #endif } } diff --git a/src/bacnet/basic/service/s_readrange.h b/src/bacnet/basic/service/s_readrange.h new file mode 100644 index 00000000..4e0f95c9 --- /dev/null +++ b/src/bacnet/basic/service/s_readrange.h @@ -0,0 +1,51 @@ +/** +* @file +* @author Steve Karg +* @date October 2019 +* @brief Header file for a basic ReadRange service send +* +* @section LICENSE +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +#ifndef SEND_READ_RANGE_H +#define SEND_READ_RANGE_H + +#include +#include +#include +#include +#include "bacnet/bacapp.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacenum.h" +#include "bacnet/apdu.h" +#include "bacnet/readrange.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +uint8_t Send_ReadRange_Request(uint32_t device_id, + BACNET_READ_RANGE_DATA* read_access_data); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/demo/handler/s_rp.c b/src/bacnet/basic/service/s_rp.c similarity index 74% rename from demo/handler/s_rp.c rename to src/bacnet/basic/service/s_rp.c index 205527ba..d969e1c1 100644 --- a/demo/handler/s_rp.c +++ b/src/bacnet/basic/service/s_rp.c @@ -26,22 +26,19 @@ #include #include #include -#include "config.h" -#include "txbuf.h" -#include "bacdef.h" -#include "bacdcode.h" -#include "address.h" -#include "tsm.h" -#include "npdu.h" -#include "apdu.h" -#include "device.h" -#include "datalink.h" -#include "dcc.h" -#include "rp.h" +#include "bacnet/config.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/npdu.h" +#include "bacnet/apdu.h" +#include "bacnet/dcc.h" +#include "bacnet/rp.h" /* some demo stuff needed */ -#include "handlers.h" -#include "txbuf.h" -#include "client.h" +#include "bacnet/basic/object/device.h" +#include "bacnet/datalink/datalink.h" +#include "bacnet/basic/binding/address.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/basic/services.h" /** @file s_rp.c Send Read Property request. */ @@ -61,12 +58,12 @@ * @return invoke id of outgoing message, or 0 if device is not bound or no tsm * available */ -uint8_t Send_Read_Property_Request_Address(BACNET_ADDRESS* dest, - uint16_t max_apdu, - BACNET_OBJECT_TYPE object_type, - uint32_t object_instance, - BACNET_PROPERTY_ID object_property, - uint32_t array_index) +uint8_t Send_Read_Property_Request_Address(BACNET_ADDRESS *dest, + uint16_t max_apdu, + BACNET_OBJECT_TYPE object_type, + uint32_t object_instance, + BACNET_PROPERTY_ID object_property, + uint32_t array_index) { BACNET_ADDRESS my_address; uint8_t invoke_id = 0; @@ -88,8 +85,8 @@ uint8_t Send_Read_Property_Request_Address(BACNET_ADDRESS* dest, /* encode the NPDU portion of the packet */ datalink_get_my_address(&my_address); npdu_encode_npdu_data(&npdu_data, true, MESSAGE_PRIORITY_NORMAL); - pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], dest, - &my_address, &npdu_data); + pdu_len = npdu_encode_pdu( + &Handler_Transmit_Buffer[0], dest, &my_address, &npdu_data); /* encode the APDU portion of the packet */ data.object_type = object_type; data.object_instance = object_instance; @@ -104,15 +101,14 @@ uint8_t Send_Read_Property_Request_Address(BACNET_ADDRESS* dest, we have a way to check for that and update the max_apdu in the address binding table. */ if ((uint16_t)pdu_len < max_apdu) { - tsm_set_confirmed_unsegmented_transaction( - invoke_id, dest, &npdu_data, &Handler_Transmit_Buffer[0], - (uint16_t)pdu_len); + tsm_set_confirmed_unsegmented_transaction(invoke_id, dest, + &npdu_data, &Handler_Transmit_Buffer[0], (uint16_t)pdu_len); bytes_sent = datalink_send_pdu( dest, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len); if (bytes_sent <= 0) { #if PRINT_ENABLED fprintf(stderr, "Failed to Send ReadProperty Request (%s)!\n", - strerror(errno)); + strerror(errno)); #endif } } else { @@ -120,8 +116,8 @@ uint8_t Send_Read_Property_Request_Address(BACNET_ADDRESS* dest, invoke_id = 0; #if PRINT_ENABLED fprintf(stderr, - "Failed to Send ReadProperty Request " - "(exceeds destination maximum APDU)!\n"); + "Failed to Send ReadProperty Request " + "(exceeds destination maximum APDU)!\n"); #endif } } @@ -145,12 +141,12 @@ uint8_t Send_Read_Property_Request_Address(BACNET_ADDRESS* dest, * available */ uint8_t Send_Read_Property_Request(uint32_t device_id, /* destination device */ - BACNET_OBJECT_TYPE object_type, - uint32_t object_instance, - BACNET_PROPERTY_ID object_property, - uint32_t array_index) + BACNET_OBJECT_TYPE object_type, + uint32_t object_instance, + BACNET_PROPERTY_ID object_property, + uint32_t array_index) { - BACNET_ADDRESS dest = {0}; + BACNET_ADDRESS dest = { 0 }; unsigned max_apdu = 0; uint8_t invoke_id = 0; bool status = false; @@ -158,9 +154,8 @@ uint8_t Send_Read_Property_Request(uint32_t device_id, /* destination device */ /* is the device bound? */ status = address_get_by_device(device_id, &max_apdu, &dest); if (status) { - invoke_id = Send_Read_Property_Request_Address( - &dest, max_apdu, object_type, object_instance, object_property, - array_index); + invoke_id = Send_Read_Property_Request_Address(&dest, max_apdu, + object_type, object_instance, object_property, array_index); } return invoke_id; diff --git a/src/bacnet/basic/service/s_rp.h b/src/bacnet/basic/service/s_rp.h new file mode 100644 index 00000000..4e076557 --- /dev/null +++ b/src/bacnet/basic/service/s_rp.h @@ -0,0 +1,61 @@ +/** +* @file +* @author Steve Karg +* @date October 2019 +* @brief Header file for a basic ReadProperty service send +* +* @section LICENSE +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +#ifndef SEND_READ_PROPERTY_H +#define SEND_READ_PROPERTY_H + +#include +#include +#include +#include +#include "bacnet/bacapp.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacenum.h" +#include "bacnet/apdu.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + uint8_t Send_Read_Property_Request_Address( + BACNET_ADDRESS * dest, + uint16_t max_apdu, + BACNET_OBJECT_TYPE object_type, + uint32_t object_instance, + BACNET_PROPERTY_ID object_property, + uint32_t array_index); + uint8_t Send_Read_Property_Request( + uint32_t device_id, /* destination device */ + BACNET_OBJECT_TYPE object_type, + uint32_t object_instance, + BACNET_PROPERTY_ID object_property, + uint32_t array_index); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/demo/handler/s_rpm.c b/src/bacnet/basic/service/s_rpm.c similarity index 80% rename from demo/handler/s_rpm.c rename to src/bacnet/basic/service/s_rpm.c index f36cc6b6..d970d6e2 100644 --- a/demo/handler/s_rpm.c +++ b/src/bacnet/basic/service/s_rpm.c @@ -26,22 +26,19 @@ #include #include #include -#include "config.h" -#include "txbuf.h" -#include "bacdef.h" -#include "bacdcode.h" -#include "address.h" -#include "tsm.h" -#include "npdu.h" -#include "apdu.h" -#include "device.h" -#include "datalink.h" -#include "dcc.h" -#include "rpm.h" +#include "bacnet/config.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/npdu.h" +#include "bacnet/apdu.h" +#include "bacnet/dcc.h" +#include "bacnet/rpm.h" /* some demo stuff needed */ -#include "handlers.h" -#include "sbuf.h" -#include "client.h" +#include "bacnet/basic/object/device.h" +#include "bacnet/datalink/datalink.h" +#include "bacnet/basic/binding/address.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/basic/services.h" /** @file s_rpm.c Send Read Property Multiple request. */ @@ -56,9 +53,10 @@ * @return invoke id of outgoing message, or 0 if device is not bound or no tsm * available */ -uint8_t Send_Read_Property_Multiple_Request( - uint8_t* pdu, size_t max_pdu, uint32_t device_id, /* destination device */ - BACNET_READ_ACCESS_DATA* read_access_data) +uint8_t Send_Read_Property_Multiple_Request(uint8_t *pdu, + size_t max_pdu, + uint32_t device_id, /* destination device */ + BACNET_READ_ACCESS_DATA *read_access_data) { BACNET_ADDRESS dest; BACNET_ADDRESS my_address; @@ -70,22 +68,24 @@ uint8_t Send_Read_Property_Multiple_Request( int bytes_sent = 0; BACNET_NPDU_DATA npdu_data; - if (!dcc_communication_enabled()) + if (!dcc_communication_enabled()) { return 0; + } /* is the device bound? */ status = address_get_by_device(device_id, &max_apdu, &dest); /* is there a tsm available? */ - if (status) + if (status) { invoke_id = tsm_next_free_invokeID(); + } if (invoke_id) { /* encode the NPDU portion of the packet */ datalink_get_my_address(&my_address); npdu_encode_npdu_data(&npdu_data, true, MESSAGE_PRIORITY_NORMAL); pdu_len = npdu_encode_pdu(&pdu[0], &dest, &my_address, &npdu_data); /* encode the APDU portion of the packet */ - len = rpm_encode_apdu(&pdu[pdu_len], max_pdu - pdu_len, invoke_id, - read_access_data); + len = rpm_encode_apdu( + &pdu[pdu_len], max_pdu - pdu_len, invoke_id, read_access_data); if (len <= 0) { return 0; } @@ -102,16 +102,16 @@ uint8_t Send_Read_Property_Multiple_Request( #if PRINT_ENABLED if (bytes_sent <= 0) fprintf(stderr, - "Failed to Send ReadPropertyMultiple Request (%s)!\n", - strerror(errno)); + "Failed to Send ReadPropertyMultiple Request (%s)!\n", + strerror(errno)); #endif } else { tsm_free_invoke_id(invoke_id); invoke_id = 0; #if PRINT_ENABLED fprintf(stderr, - "Failed to Send ReadPropertyMultiple Request " - "(exceeds destination maximum APDU)!\n"); + "Failed to Send ReadPropertyMultiple Request " + "(exceeds destination maximum APDU)!\n"); #endif } } diff --git a/src/bacnet/basic/service/s_rpm.h b/src/bacnet/basic/service/s_rpm.h new file mode 100644 index 00000000..2dd22f93 --- /dev/null +++ b/src/bacnet/basic/service/s_rpm.h @@ -0,0 +1,54 @@ +/** +* @file +* @author Steve Karg +* @date October 2019 +* @brief Header file for a basic ReadPropertyMultiple service send +* +* @section LICENSE +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +#ifndef SEND_READ_PROPERTY_MULTIPLE_H +#define SEND_READ_PROPERTY_MULTIPLE_H + +#include +#include +#include +#include +#include "bacnet/bacapp.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacenum.h" +#include "bacnet/apdu.h" +#include "bacnet/rpm.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + uint8_t Send_Read_Property_Multiple_Request( + uint8_t * pdu, + size_t max_pdu, + uint32_t device_id, /* destination device */ + BACNET_READ_ACCESS_DATA * read_access_data); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/demo/handler/s_ts.c b/src/bacnet/basic/service/s_ts.c similarity index 73% rename from demo/handler/s_ts.c rename to src/bacnet/basic/service/s_ts.c index d214ac35..3f4c3b6b 100644 --- a/demo/handler/s_ts.c +++ b/src/bacnet/basic/service/s_ts.c @@ -26,22 +26,19 @@ #include #include #include -#include "config.h" -#include "txbuf.h" -#include "bacdef.h" -#include "bacdcode.h" -#include "address.h" -#include "tsm.h" -#include "npdu.h" -#include "apdu.h" -#include "device.h" -#include "datalink.h" -#include "dcc.h" -#include "timesync.h" +#include "bacnet/config.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/npdu.h" +#include "bacnet/apdu.h" +#include "bacnet/dcc.h" +#include "bacnet/timesync.h" /* some demo stuff needed */ -#include "handlers.h" -#include "txbuf.h" -#include "client.h" +#include "bacnet/basic/binding/address.h" +#include "bacnet/basic/object/device.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/datalink/datalink.h" /** @file s_ts.c Send TimeSync requests. */ @@ -52,8 +49,8 @@ * @param bdate - #BACNET_DATE * @param btime - #BACNET_TIME */ -void Send_TimeSync_Remote(BACNET_ADDRESS* dest, BACNET_DATE* bdate, - BACNET_TIME* btime) +void Send_TimeSync_Remote( + BACNET_ADDRESS *dest, BACNET_DATE *bdate, BACNET_TIME *btime) { int len = 0; int pdu_len = 0; @@ -61,24 +58,25 @@ void Send_TimeSync_Remote(BACNET_ADDRESS* dest, BACNET_DATE* bdate, BACNET_NPDU_DATA npdu_data; BACNET_ADDRESS my_address; - if (!dcc_communication_enabled()) + if (!dcc_communication_enabled()) { return; + } datalink_get_my_address(&my_address); /* encode the NPDU portion of the packet */ npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL); - pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], dest, &my_address, - &npdu_data); + pdu_len = npdu_encode_pdu( + &Handler_Transmit_Buffer[0], dest, &my_address, &npdu_data); /* encode the APDU portion of the packet */ len = timesync_encode_apdu(&Handler_Transmit_Buffer[pdu_len], bdate, btime); pdu_len += len; /* send it out the datalink */ - bytes_sent = datalink_send_pdu(dest, &npdu_data, - &Handler_Transmit_Buffer[0], pdu_len); + bytes_sent = datalink_send_pdu( + dest, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len); #if PRINT_ENABLED if (bytes_sent <= 0) fprintf(stderr, "Failed to Send Time-Synchronization Request (%s)!\n", - strerror(errno)); + strerror(errno)); #endif } @@ -88,7 +86,7 @@ void Send_TimeSync_Remote(BACNET_ADDRESS* dest, BACNET_DATE* bdate, * @param bdate - #BACNET_DATE * @param btime - #BACNET_TIME */ -void Send_TimeSync(BACNET_DATE* bdate, BACNET_TIME* btime) +void Send_TimeSync(BACNET_DATE *bdate, BACNET_TIME *btime) { BACNET_ADDRESS dest; @@ -103,8 +101,8 @@ void Send_TimeSync(BACNET_DATE* bdate, BACNET_TIME* btime) * @param bdate - #BACNET_DATE * @param btime - #BACNET_TIME */ -void Send_TimeSyncUTC_Remote(BACNET_ADDRESS* dest, BACNET_DATE* bdate, - BACNET_TIME* btime) +void Send_TimeSyncUTC_Remote( + BACNET_ADDRESS *dest, BACNET_DATE *bdate, BACNET_TIME *btime) { int len = 0; int pdu_len = 0; @@ -112,25 +110,26 @@ void Send_TimeSyncUTC_Remote(BACNET_ADDRESS* dest, BACNET_DATE* bdate, BACNET_NPDU_DATA npdu_data; BACNET_ADDRESS my_address; - if (!dcc_communication_enabled()) + if (!dcc_communication_enabled()) { return; + } datalink_get_my_address(&my_address); /* encode the NPDU portion of the packet */ npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL); - pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], dest, &my_address, - &npdu_data); + pdu_len = npdu_encode_pdu( + &Handler_Transmit_Buffer[0], dest, &my_address, &npdu_data); /* encode the APDU portion of the packet */ - len = timesync_utc_encode_apdu(&Handler_Transmit_Buffer[pdu_len], bdate, - btime); + len = timesync_utc_encode_apdu( + &Handler_Transmit_Buffer[pdu_len], bdate, btime); pdu_len += len; - bytes_sent = datalink_send_pdu(dest, &npdu_data, - &Handler_Transmit_Buffer[0], pdu_len); + bytes_sent = datalink_send_pdu( + dest, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len); #if PRINT_ENABLED if (bytes_sent <= 0) fprintf(stderr, - "Failed to Send UTC-Time-Synchronization Request (%s)!\n", - strerror(errno)); + "Failed to Send UTC-Time-Synchronization Request (%s)!\n", + strerror(errno)); #endif } @@ -140,7 +139,7 @@ void Send_TimeSyncUTC_Remote(BACNET_ADDRESS* dest, BACNET_DATE* bdate, * @param bdate - #BACNET_DATE * @param btime - #BACNET_TIME */ -void Send_TimeSyncUTC(BACNET_DATE* bdate, BACNET_TIME* btime) +void Send_TimeSyncUTC(BACNET_DATE *bdate, BACNET_TIME *btime) { BACNET_ADDRESS dest; diff --git a/src/bacnet/basic/service/s_ts.h b/src/bacnet/basic/service/s_ts.h new file mode 100644 index 00000000..b75d783c --- /dev/null +++ b/src/bacnet/basic/service/s_ts.h @@ -0,0 +1,64 @@ +/** +* @file +* @author Steve Karg +* @date October 2019 +* @brief Header file for a basic TimeSynchronization service send +* +* @section LICENSE +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +#ifndef SEND_TIME_SYNC_H +#define SEND_TIME_SYNC_H + +#include +#include +#include +#include +#include "bacnet/bacapp.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacenum.h" +#include "bacnet/apdu.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + void Send_TimeSync( + BACNET_DATE * bdate, + BACNET_TIME * btime); + void Send_TimeSync_Remote( + BACNET_ADDRESS * dest, + BACNET_DATE * bdate, + BACNET_TIME * btime); + void Send_TimeSyncUTC( + BACNET_DATE * bdate, + BACNET_TIME * btime); + void Send_TimeSyncUTC_Remote( + BACNET_ADDRESS * dest, + BACNET_DATE * bdate, + BACNET_TIME * btime); + void Send_TimeSyncUTC_Device(void); + void Send_TimeSync_Device(void); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/demo/handler/s_uevent.c b/src/bacnet/basic/service/s_uevent.c similarity index 90% rename from demo/handler/s_uevent.c rename to src/bacnet/basic/service/s_uevent.c index 6cac8322..350fff5d 100644 --- a/demo/handler/s_uevent.c +++ b/src/bacnet/basic/service/s_uevent.c @@ -25,10 +25,10 @@ #include #include #include -#include "event.h" -#include "datalink.h" -#include "client.h" -#include "device.h" +#include "bacnet/event.h" +#include "bacnet/datalink/datalink.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/object/device.h" /** @file s_uevent.c Send an Unconfirmed Event Notification. */ @@ -40,8 +40,8 @@ * @param dest [in] The destination address information (may be a broadcast). * @return Size of the message sent (bytes), or a negative value on error. */ -int Send_UEvent_Notify(uint8_t* buffer, BACNET_EVENT_NOTIFICATION_DATA* data, - BACNET_ADDRESS* dest) +int Send_UEvent_Notify( + uint8_t *buffer, BACNET_EVENT_NOTIFICATION_DATA *data, BACNET_ADDRESS *dest) { int len = 0; int pdu_len = 0; diff --git a/src/bacnet/basic/service/s_uevent.h b/src/bacnet/basic/service/s_uevent.h new file mode 100644 index 00000000..f5afc74a --- /dev/null +++ b/src/bacnet/basic/service/s_uevent.h @@ -0,0 +1,52 @@ +/** +* @file +* @author Steve Karg +* @date October 2019 +* @brief Header file for a basic UnconfirmedEventNotification service send +* +* @section LICENSE +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +#ifndef SEND_UNCONFIRMED_EVENT_NOTIFICATION_H +#define SEND_UNCONFIRMED_EVENT_NOTIFICATION_H + +#include +#include +#include +#include +#include "bacnet/bacapp.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacenum.h" +#include "bacnet/apdu.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + int Send_UEvent_Notify( + uint8_t * buffer, + BACNET_EVENT_NOTIFICATION_DATA * data, + BACNET_ADDRESS * dest); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/demo/handler/s_upt.c b/src/bacnet/basic/service/s_upt.c similarity index 71% rename from demo/handler/s_upt.c rename to src/bacnet/basic/service/s_upt.c index 3ee5be81..22524a45 100644 --- a/demo/handler/s_upt.c +++ b/src/bacnet/basic/service/s_upt.c @@ -26,27 +26,24 @@ #include #include #include -#include "config.h" -#include "txbuf.h" -#include "bacdef.h" -#include "bacdcode.h" -#include "address.h" -#include "tsm.h" -#include "npdu.h" -#include "apdu.h" -#include "device.h" -#include "datalink.h" -#include "dcc.h" -#include "ptransfer.h" +#include "bacnet/config.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/npdu.h" +#include "bacnet/apdu.h" +#include "bacnet/dcc.h" +#include "bacnet/ptransfer.h" /* some demo stuff needed */ -#include "handlers.h" -#include "txbuf.h" -#include "client.h" +#include "bacnet/basic/binding/address.h" +#include "bacnet/basic/object/device.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/datalink/datalink.h" /** @file s_upt.c Send an Unconfirmed Private Transfer request. */ -int Send_UnconfirmedPrivateTransfer(BACNET_ADDRESS* dest, - BACNET_PRIVATE_TRANSFER_DATA* private_data) +int Send_UnconfirmedPrivateTransfer( + BACNET_ADDRESS *dest, BACNET_PRIVATE_TRANSFER_DATA *private_data) { int len = 0; int pdu_len = 0; @@ -54,26 +51,27 @@ int Send_UnconfirmedPrivateTransfer(BACNET_ADDRESS* dest, BACNET_NPDU_DATA npdu_data; BACNET_ADDRESS my_address; - if (!dcc_communication_enabled()) + if (!dcc_communication_enabled()) { return bytes_sent; + } datalink_get_my_address(&my_address); /* encode the NPDU portion of the packet */ npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL); - pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], dest, &my_address, - &npdu_data); + pdu_len = npdu_encode_pdu( + &Handler_Transmit_Buffer[0], dest, &my_address, &npdu_data); /* encode the APDU portion of the packet */ len = uptransfer_encode_apdu(&Handler_Transmit_Buffer[pdu_len], private_data); pdu_len += len; - bytes_sent = datalink_send_pdu(dest, &npdu_data, - &Handler_Transmit_Buffer[0], pdu_len); + bytes_sent = datalink_send_pdu( + dest, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len); if (bytes_sent <= 0) { #if PRINT_ENABLED fprintf(stderr, - "Failed to Send UnconfirmedPrivateTransfer Request (%s)!\n", - strerror(errno)); + "Failed to Send UnconfirmedPrivateTransfer Request (%s)!\n", + strerror(errno)); #endif } diff --git a/src/bacnet/basic/service/s_upt.h b/src/bacnet/basic/service/s_upt.h new file mode 100644 index 00000000..a1f6d7c8 --- /dev/null +++ b/src/bacnet/basic/service/s_upt.h @@ -0,0 +1,51 @@ +/** +* @file +* @author Steve Karg +* @date October 2019 +* @brief Header file for a basic UnconfirmedPrivateTransfer service send +* +* @section LICENSE +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +#ifndef SEND_UNCONFIRMED_PRIVATE_TRANSFER_H +#define SEND_UNCONFIRMED_PRIVATE_TRANSFER_H + +#include +#include +#include +#include +#include "bacnet/bacapp.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacenum.h" +#include "bacnet/apdu.h" +#include "bacnet/ptransfer.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +int Send_UnconfirmedPrivateTransfer(BACNET_ADDRESS* dest, + BACNET_PRIVATE_TRANSFER_DATA* private_data); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/demo/handler/s_whohas.c b/src/bacnet/basic/service/s_whohas.c similarity index 76% rename from demo/handler/s_whohas.c rename to src/bacnet/basic/service/s_whohas.c index a5d5919b..019cfae4 100644 --- a/demo/handler/s_whohas.c +++ b/src/bacnet/basic/service/s_whohas.c @@ -26,22 +26,19 @@ #include #include #include -#include "config.h" -#include "txbuf.h" -#include "bacdef.h" -#include "bacdcode.h" -#include "address.h" -#include "tsm.h" -#include "npdu.h" -#include "apdu.h" -#include "device.h" -#include "datalink.h" -#include "dcc.h" -#include "whohas.h" +#include "bacnet/config.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/npdu.h" +#include "bacnet/apdu.h" +#include "bacnet/dcc.h" +#include "bacnet/whohas.h" /* some demo stuff needed */ -#include "handlers.h" -#include "txbuf.h" -#include "client.h" +#include "bacnet/basic/binding/address.h" +#include "bacnet/basic/object/device.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/datalink/datalink.h" /** @file s_whohas.c Send Who-Has requests. */ @@ -55,8 +52,8 @@ * @param high_limit [in] Device Instance High Range, 0 - 4,194,303 or -1 * @param object_name [in] The Name of the desired Object. */ -void Send_WhoHas_Name(int32_t low_limit, int32_t high_limit, - const char *object_name) +void Send_WhoHas_Name( + int32_t low_limit, int32_t high_limit, const char *object_name) { int len = 0; int pdu_len = 0; @@ -67,15 +64,16 @@ void Send_WhoHas_Name(int32_t low_limit, int32_t high_limit, BACNET_ADDRESS my_address; /* if we are forbidden to send, don't send! */ - if (!dcc_communication_enabled()) + if (!dcc_communication_enabled()) { return; + } /* Who-Has is a global broadcast */ datalink_get_broadcast_address(&dest); datalink_get_my_address(&my_address); /* encode the NPDU portion of the packet */ npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL); - pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest, &my_address, - &npdu_data); + pdu_len = npdu_encode_pdu( + &Handler_Transmit_Buffer[0], &dest, &my_address, &npdu_data); /* encode the APDU portion of the packet */ data.low_limit = low_limit; @@ -85,12 +83,12 @@ void Send_WhoHas_Name(int32_t low_limit, int32_t high_limit, len = whohas_encode_apdu(&Handler_Transmit_Buffer[pdu_len], &data); pdu_len += len; /* send the data */ - bytes_sent = datalink_send_pdu(&dest, &npdu_data, - &Handler_Transmit_Buffer[0], pdu_len); + bytes_sent = datalink_send_pdu( + &dest, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len); #if PRINT_ENABLED if (bytes_sent <= 0) - fprintf(stderr, "Failed to Send Who-Has Request (%s)!\n", - strerror(errno)); + fprintf( + stderr, "Failed to Send Who-Has Request (%s)!\n", strerror(errno)); #endif } @@ -105,9 +103,10 @@ void Send_WhoHas_Name(int32_t low_limit, int32_t high_limit, * @param object_type [in] The BACNET_OBJECT_TYPE of the desired Object. * @param object_instance [in] The ID of the desired Object. */ -void Send_WhoHas_Object(int32_t low_limit, int32_t high_limit, - BACNET_OBJECT_TYPE object_type, - uint32_t object_instance) +void Send_WhoHas_Object(int32_t low_limit, + int32_t high_limit, + BACNET_OBJECT_TYPE object_type, + uint32_t object_instance) { int len = 0; int pdu_len = 0; @@ -118,15 +117,16 @@ void Send_WhoHas_Object(int32_t low_limit, int32_t high_limit, BACNET_ADDRESS my_address; /* if we are forbidden to send, don't send! */ - if (!dcc_communication_enabled()) + if (!dcc_communication_enabled()) { return; + } /* Who-Has is a global broadcast */ datalink_get_broadcast_address(&dest); datalink_get_my_address(&my_address); /* encode the NPDU portion of the packet */ npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL); - pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest, &my_address, - &npdu_data); + pdu_len = npdu_encode_pdu( + &Handler_Transmit_Buffer[0], &dest, &my_address, &npdu_data); /* encode the APDU portion of the packet */ data.low_limit = low_limit; @@ -136,11 +136,11 @@ void Send_WhoHas_Object(int32_t low_limit, int32_t high_limit, data.object.identifier.instance = object_instance; len = whohas_encode_apdu(&Handler_Transmit_Buffer[pdu_len], &data); pdu_len += len; - bytes_sent = datalink_send_pdu(&dest, &npdu_data, - &Handler_Transmit_Buffer[0], pdu_len); + bytes_sent = datalink_send_pdu( + &dest, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len); #if PRINT_ENABLED if (bytes_sent <= 0) - fprintf(stderr, "Failed to Send Who-Has Request (%s)!\n", - strerror(errno)); + fprintf( + stderr, "Failed to Send Who-Has Request (%s)!\n", strerror(errno)); #endif } diff --git a/src/bacnet/basic/service/s_whohas.h b/src/bacnet/basic/service/s_whohas.h new file mode 100644 index 00000000..8a484646 --- /dev/null +++ b/src/bacnet/basic/service/s_whohas.h @@ -0,0 +1,55 @@ +/** +* @file +* @author Steve Karg +* @date October 2019 +* @brief Header file for a basic WhoHas service send +* +* @section LICENSE +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +#ifndef SEND_WHO_HAS_H +#define SEND_WHO_HAS_H + +#include +#include +#include +#include +#include "bacnet/bacapp.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacenum.h" +#include "bacnet/apdu.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + void Send_WhoHas_Name( + int32_t low_limit, + int32_t high_limit, + const char *object_name); + void Send_WhoHas_Object(int32_t low_limit, int32_t high_limit, + BACNET_OBJECT_TYPE object_type, + uint32_t object_instance); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/demo/handler/s_whois.c b/src/bacnet/basic/service/s_whois.c similarity index 81% rename from demo/handler/s_whois.c rename to src/bacnet/basic/service/s_whois.c index 8d04df84..380d740e 100644 --- a/demo/handler/s_whois.c +++ b/src/bacnet/basic/service/s_whois.c @@ -26,23 +26,23 @@ #include #include #include -#include "config.h" -#include "txbuf.h" -#include "bacdef.h" -#include "bacdcode.h" -#include "address.h" -#include "tsm.h" -#include "npdu.h" -#include "apdu.h" -#include "device.h" -#include "datalink.h" -#include "dcc.h" -#include "whois.h" -#include "bacenum.h" +#include "bacnet/config.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/basic/binding/address.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/npdu.h" +#include "bacnet/apdu.h" +#include "bacnet/basic/object/device.h" +#include "bacnet/datalink/datalink.h" +#include "bacnet/dcc.h" +#include "bacnet/whois.h" +#include "bacnet/bacenum.h" /* some demo stuff needed */ -#include "handlers.h" -#include "txbuf.h" -#include "client.h" +#include "bacnet/basic/object/device.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/datalink/datalink.h" /** @file s_whois.c Send a Who-Is request. */ @@ -56,8 +56,8 @@ * @param low_limit [in] Device Instance Low Range, 0 - 4,194,303 or -1 * @param high_limit [in] Device Instance High Range, 0 - 4,194,303 or -1 */ -void Send_WhoIs_To_Network(BACNET_ADDRESS* target_address, int32_t low_limit, - int32_t high_limit) +void Send_WhoIs_To_Network( + BACNET_ADDRESS *target_address, int32_t low_limit, int32_t high_limit) { int len = 0; int pdu_len = 0; @@ -69,18 +69,20 @@ void Send_WhoIs_To_Network(BACNET_ADDRESS* target_address, int32_t low_limit, /* encode the NPDU portion of the packet */ npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL); - pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], target_address, - &my_address, &npdu_data); + pdu_len = npdu_encode_pdu( + &Handler_Transmit_Buffer[0], target_address, &my_address, &npdu_data); /* encode the APDU portion of the packet */ - len = whois_encode_apdu(&Handler_Transmit_Buffer[pdu_len], low_limit, - high_limit); + len = whois_encode_apdu( + &Handler_Transmit_Buffer[pdu_len], low_limit, high_limit); pdu_len += len; - bytes_sent = datalink_send_pdu(target_address, &npdu_data, - &Handler_Transmit_Buffer[0], pdu_len); + bytes_sent = datalink_send_pdu( + target_address, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len); #if PRINT_ENABLED if (bytes_sent <= 0) - fprintf(stderr, "Failed to Send Who-Is Request (%s)!\n", - strerror(errno)); + fprintf( + stderr, "Failed to Send Who-Is Request (%s)!\n", strerror(errno)); +#else + (void)bytes_sent; #endif } @@ -96,8 +98,9 @@ void Send_WhoIs_Global(int32_t low_limit, int32_t high_limit) { BACNET_ADDRESS dest; - if (!dcc_communication_enabled()) + if (!dcc_communication_enabled()) { return; + } /* Who-Is is a global broadcast */ datalink_get_broadcast_address(&dest); @@ -119,8 +122,9 @@ void Send_WhoIs_Local(int32_t low_limit, int32_t high_limit) char temp[6]; int loop; - if (!dcc_communication_enabled()) + if (!dcc_communication_enabled()) { return; + } /* Who-Is is a global broadcast */ datalink_get_broadcast_address(&dest); @@ -157,11 +161,12 @@ void Send_WhoIs_Local(int32_t low_limit, int32_t high_limit) * @param low_limit [in] Device Instance Low Range, 0 - 4,194,303 or -1 * @param high_limit [in] Device Instance High Range, 0 - 4,194,303 or -1 */ -void Send_WhoIs_Remote(BACNET_ADDRESS* target_address, int32_t low_limit, - int32_t high_limit) +void Send_WhoIs_Remote( + BACNET_ADDRESS *target_address, int32_t low_limit, int32_t high_limit) { - if (!dcc_communication_enabled()) + if (!dcc_communication_enabled()) { return; + } Send_WhoIs_To_Network(target_address, low_limit, high_limit); } diff --git a/src/bacnet/basic/service/s_whois.h b/src/bacnet/basic/service/s_whois.h new file mode 100644 index 00000000..542d9839 --- /dev/null +++ b/src/bacnet/basic/service/s_whois.h @@ -0,0 +1,63 @@ +/** +* @file +* @author Steve Karg +* @date October 2019 +* @brief Header file for a basic WhoIs service send +* +* @section LICENSE +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +#ifndef SEND_WHO_IS_H +#define SEND_WHO_IS_H + +#include +#include +#include +#include +#include "bacnet/bacapp.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacenum.h" +#include "bacnet/apdu.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + void Send_WhoIs( + int32_t low_limit, + int32_t high_limit); + void Send_WhoIs_Global( + int32_t low_limit, + int32_t high_limit); + void Send_WhoIs_Local( + int32_t low_limit, + int32_t high_limit); + void Send_WhoIs_Remote( + BACNET_ADDRESS * target_address, + int32_t low_limit, + int32_t high_limit); + void Send_WhoIs_To_Network(BACNET_ADDRESS* target_address, int32_t low_limit, + int32_t high_limit); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/demo/handler/s_wp.c b/src/bacnet/basic/service/s_wp.c similarity index 67% rename from demo/handler/s_wp.c rename to src/bacnet/basic/service/s_wp.c index cadf485c..aba04616 100644 --- a/demo/handler/s_wp.c +++ b/src/bacnet/basic/service/s_wp.c @@ -26,33 +26,31 @@ #include #include #include -#include "config.h" -#include "txbuf.h" -#include "bacdef.h" -#include "bacdcode.h" -#include "address.h" -#include "tsm.h" -#include "npdu.h" -#include "apdu.h" -#include "device.h" -#include "datalink.h" -#include "dcc.h" -#include "whois.h" +#include "bacnet/config.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/npdu.h" +#include "bacnet/apdu.h" +#include "bacnet/dcc.h" +#include "bacnet/whois.h" /* some demo stuff needed */ -#include "handlers.h" -#include "txbuf.h" -#include "client.h" +#include "bacnet/basic/binding/address.h" +#include "bacnet/basic/object/device.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/datalink/datalink.h" /** @file s_wp.c Send a Write Property request. */ /** returns the invoke ID for confirmed request, or zero on failure */ uint8_t Send_Write_Property_Request_Data(uint32_t device_id, - BACNET_OBJECT_TYPE object_type, - uint32_t object_instance, - BACNET_PROPERTY_ID object_property, - uint8_t* application_data, - int application_data_len, - uint8_t priority, uint32_t array_index) + BACNET_OBJECT_TYPE object_type, + uint32_t object_instance, + BACNET_PROPERTY_ID object_property, + uint8_t *application_data, + int application_data_len, + uint8_t priority, + uint32_t array_index) { BACNET_ADDRESS dest; BACNET_ADDRESS my_address; @@ -65,20 +63,22 @@ uint8_t Send_Write_Property_Request_Data(uint32_t device_id, BACNET_WRITE_PROPERTY_DATA data; BACNET_NPDU_DATA npdu_data; - if (!dcc_communication_enabled()) + if (!dcc_communication_enabled()) { return 0; + } /* is the device bound? */ status = address_get_by_device(device_id, &max_apdu, &dest); /* is there a tsm available? */ - if (status) + if (status) { invoke_id = tsm_next_free_invokeID(); + } if (invoke_id) { /* encode the NPDU portion of the packet */ datalink_get_my_address(&my_address); npdu_encode_npdu_data(&npdu_data, true, MESSAGE_PRIORITY_NORMAL); - pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest, - &my_address, &npdu_data); + pdu_len = npdu_encode_pdu( + &Handler_Transmit_Buffer[0], &dest, &my_address, &npdu_data); /* encode the APDU portion of the packet */ data.object_type = object_type; data.object_instance = object_instance; @@ -86,7 +86,7 @@ uint8_t Send_Write_Property_Request_Data(uint32_t device_id, data.array_index = array_index; data.application_data_len = application_data_len; memcpy(&data.application_data[0], &application_data[0], - application_data_len); + application_data_len); data.priority = priority; len = wp_encode_apdu(&Handler_Transmit_Buffer[pdu_len], invoke_id, &data); @@ -97,23 +97,23 @@ uint8_t Send_Write_Property_Request_Data(uint32_t device_id, we have a way to check for that and update the max_apdu in the address binding table. */ if ((unsigned)pdu_len < max_apdu) { - tsm_set_confirmed_unsegmented_transaction( - invoke_id, &dest, &npdu_data, &Handler_Transmit_Buffer[0], - (uint16_t)pdu_len); + tsm_set_confirmed_unsegmented_transaction(invoke_id, &dest, + &npdu_data, &Handler_Transmit_Buffer[0], (uint16_t)pdu_len); bytes_sent = datalink_send_pdu( &dest, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len); + if (bytes_sent <= 0) { #if PRINT_ENABLED - if (bytes_sent <= 0) fprintf(stderr, "Failed to Send WriteProperty Request (%s)!\n", - strerror(errno)); + strerror(errno)); #endif + } } else { tsm_free_invoke_id(invoke_id); invoke_id = 0; #if PRINT_ENABLED fprintf(stderr, - "Failed to Send WriteProperty Request " - "(exceeds destination maximum APDU)!\n"); + "Failed to Send WriteProperty Request " + "(exceeds destination maximum APDU)!\n"); #endif } } @@ -137,23 +137,24 @@ uint8_t Send_Write_Property_Request_Data(uint32_t device_id, * @return invoke id of outgoing message, or 0 on failure. */ uint8_t Send_Write_Property_Request(uint32_t device_id, - BACNET_OBJECT_TYPE object_type, - uint32_t object_instance, - BACNET_PROPERTY_ID object_property, - BACNET_APPLICATION_DATA_VALUE* object_value, - uint8_t priority, uint32_t array_index) + BACNET_OBJECT_TYPE object_type, + uint32_t object_instance, + BACNET_PROPERTY_ID object_property, + BACNET_APPLICATION_DATA_VALUE *object_value, + uint8_t priority, + uint32_t array_index) { - uint8_t application_data[MAX_APDU] = {0}; + uint8_t application_data[MAX_APDU] = { 0 }; int apdu_len = 0, len = 0; while (object_value) { #if PRINT_ENABLED_DEBUG fprintf(stderr, - "WriteProperty service: " - "%s tag=%d\n", - (object_value->context_specific ? "context" : "application"), - (int)(object_value->context_specific ? object_value->context_tag - : object_value->tag)); + "WriteProperty service: " + "%s tag=%d\n", + (object_value->context_specific ? "context" : "application"), + (int)(object_value->context_specific ? object_value->context_tag + : object_value->tag)); #endif len = bacapp_encode_data(&application_data[apdu_len], object_value); if ((len + apdu_len) < MAX_APDU) { @@ -164,7 +165,7 @@ uint8_t Send_Write_Property_Request(uint32_t device_id, object_value = object_value->next; } - return Send_Write_Property_Request_Data( - device_id, object_type, object_instance, object_property, - &application_data[0], apdu_len, priority, array_index); + return Send_Write_Property_Request_Data(device_id, object_type, + object_instance, object_property, &application_data[0], apdu_len, + priority, array_index); } diff --git a/src/bacnet/basic/service/s_wp.h b/src/bacnet/basic/service/s_wp.h new file mode 100644 index 00000000..132e3803 --- /dev/null +++ b/src/bacnet/basic/service/s_wp.h @@ -0,0 +1,65 @@ +/** +* @file +* @author Steve Karg +* @date October 2019 +* @brief Header file for a basic WriteProperty service send +* +* @section LICENSE +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +#ifndef SEND_WRITE_PROPERTY_H +#define SEND_WRITE_PROPERTY_H + +#include +#include +#include +#include +#include "bacnet/bacapp.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacenum.h" +#include "bacnet/apdu.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + uint8_t Send_Write_Property_Request( + uint32_t device_id, /* destination device */ + BACNET_OBJECT_TYPE object_type, + uint32_t object_instance, + BACNET_PROPERTY_ID object_property, + BACNET_APPLICATION_DATA_VALUE * object_value, + uint8_t priority, + uint32_t array_index); + uint8_t Send_Write_Property_Request_Data( + uint32_t device_id, + BACNET_OBJECT_TYPE object_type, + uint32_t object_instance, + BACNET_PROPERTY_ID object_property, + uint8_t * application_data, + int application_data_len, + uint8_t priority, + uint32_t array_index); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/demo/handler/s_wpm.c b/src/bacnet/basic/service/s_wpm.c similarity index 82% rename from demo/handler/s_wpm.c rename to src/bacnet/basic/service/s_wpm.c index 7270f6f9..c3210f38 100644 --- a/demo/handler/s_wpm.c +++ b/src/bacnet/basic/service/s_wpm.c @@ -31,21 +31,19 @@ #include #include #include -#include "config.h" -#include "bacdef.h" -#include "bacdcode.h" -#include "address.h" -#include "tsm.h" -#include "npdu.h" -#include "apdu.h" -#include "device.h" -#include "datalink.h" -#include "dcc.h" -#include "wpm.h" +#include "bacnet/config.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/npdu.h" +#include "bacnet/apdu.h" +#include "bacnet/dcc.h" +#include "bacnet/wpm.h" /* some demo stuff needed */ -#include "handlers.h" -#include "sbuf.h" -#include "client.h" +#include "bacnet/datalink/datalink.h" +#include "bacnet/basic/binding/address.h" +#include "bacnet/basic/object/device.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/tsm/tsm.h" /** @file s_wpm.c Send Write Property Multiple request. */ @@ -58,9 +56,10 @@ * @return invoke id of outgoing message, or 0 if device is not bound or no tsm * available */ -uint8_t Send_Write_Property_Multiple_Request( - uint8_t* pdu, size_t max_pdu, uint32_t device_id, - BACNET_WRITE_ACCESS_DATA* write_access_data) +uint8_t Send_Write_Property_Multiple_Request(uint8_t *pdu, + size_t max_pdu, + uint32_t device_id, + BACNET_WRITE_ACCESS_DATA *write_access_data) { BACNET_ADDRESS dest; BACNET_ADDRESS my_address; @@ -88,8 +87,8 @@ uint8_t Send_Write_Property_Multiple_Request( npdu_encode_npdu_data(&npdu_data, true, MESSAGE_PRIORITY_NORMAL); pdu_len = npdu_encode_pdu(&pdu[0], &dest, &my_address, &npdu_data); /* encode the APDU portion of the packet */ - len = wpm_encode_apdu(&pdu[pdu_len], max_pdu - pdu_len, invoke_id, - write_access_data); + len = wpm_encode_apdu( + &pdu[pdu_len], max_pdu - pdu_len, invoke_id, write_access_data); pdu_len += len; /* will it fit in the sender? @@ -104,8 +103,8 @@ uint8_t Send_Write_Property_Multiple_Request( #if PRINT_ENABLED if (bytes_sent <= 0) { fprintf(stderr, - "Failed to Send WritePropertyMultiple Request (%s)!\n", - strerror(errno)); + "Failed to Send WritePropertyMultiple Request (%s)!\n", + strerror(errno)); } #endif } else { @@ -113,8 +112,8 @@ uint8_t Send_Write_Property_Multiple_Request( invoke_id = 0; #if PRINT_ENABLED fprintf(stderr, - "Failed to Send WritePropertyMultiple Request " - "(exceeds destination maximum APDU)!\n"); + "Failed to Send WritePropertyMultiple Request " + "(exceeds destination maximum APDU)!\n"); #endif } } diff --git a/src/bacnet/basic/service/s_wpm.h b/src/bacnet/basic/service/s_wpm.h new file mode 100644 index 00000000..8feb2829 --- /dev/null +++ b/src/bacnet/basic/service/s_wpm.h @@ -0,0 +1,54 @@ +/** +* @file +* @author Steve Karg +* @date October 2019 +* @brief Header file for a basic WritePropertyMultiple service send +* +* @section LICENSE +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +#ifndef SEND_WRITE_PROPERTY_MULTIPLE_H +#define SEND_WRITE_PROPERTY_MULTIPLE_H + +#include +#include +#include +#include +#include "bacnet/bacapp.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacenum.h" +#include "bacnet/apdu.h" +#include "bacnet/wpm.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + uint8_t Send_Write_Property_Multiple_Request( + uint8_t * pdu, + size_t max_pdu, + uint32_t device_id, + BACNET_WRITE_ACCESS_DATA * write_access_data); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/src/bacnet/basic/services.h b/src/bacnet/basic/services.h new file mode 100644 index 00000000..5da1366c --- /dev/null +++ b/src/bacnet/basic/services.h @@ -0,0 +1,98 @@ +/************************************************************************** +* +* Copyright (C) 2005-2006 Steve Karg +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +* +*********************************************************************/ +#ifndef BASIC_SERVICES_H +#define BASIC_SERVICES_H + +/* NPDU layer handlers */ +#include "bacnet/basic/npdu/h_npdu.h" +#include "bacnet/basic/npdu/h_routed_npdu.h" +#include "bacnet/basic/npdu/s_router.h" + +/* application layer binding handler */ +#include "bacnet/basic/binding/address.h" + +/* application layer service handler */ +#include "bacnet/basic/service/h_alarm_ack.h" +#include "bacnet/basic/service/h_apdu.h" +#include "bacnet/basic/service/h_arf.h" +#include "bacnet/basic/service/h_arf_a.h" +#include "bacnet/basic/service/h_awf.h" +#include "bacnet/basic/service/h_ccov.h" +#include "bacnet/basic/service/h_cov.h" +#include "bacnet/basic/service/h_dcc.h" +#include "bacnet/basic/service/h_gas_a.h" +#include "bacnet/basic/service/h_get_alarm_sum.h" +#include "bacnet/basic/service/h_getevent.h" +#include "bacnet/basic/service/h_getevent_a.h" +#include "bacnet/basic/service/h_iam.h" +#include "bacnet/basic/service/h_ihave.h" +#include "bacnet/basic/service/h_lso.h" +#include "bacnet/basic/service/h_noserv.h" +#include "bacnet/basic/service/h_rd.h" +#include "bacnet/basic/service/h_rp.h" +#include "bacnet/basic/service/h_rp_a.h" +#include "bacnet/basic/service/h_rpm.h" +#include "bacnet/basic/service/h_rpm_a.h" +#include "bacnet/basic/service/h_rr.h" +#include "bacnet/basic/service/h_rr_a.h" +#include "bacnet/basic/service/h_ts.h" +#include "bacnet/basic/service/h_ucov.h" +#include "bacnet/basic/service/h_upt.h" +#include "bacnet/basic/service/h_whohas.h" +#include "bacnet/basic/service/h_whois.h" +#include "bacnet/basic/service/h_wp.h" +#include "bacnet/basic/service/h_wpm.h" + +/* application layer service send helpers */ +#include "bacnet/basic/service/s_abort.h" +#include "bacnet/basic/service/s_ack_alarm.h" +#include "bacnet/basic/service/s_arfs.h" +#include "bacnet/basic/service/s_awfs.h" +#include "bacnet/basic/service/s_cevent.h" +#include "bacnet/basic/service/s_cov.h" +#include "bacnet/basic/service/s_dcc.h" +#include "bacnet/basic/service/s_error.h" +#include "bacnet/basic/service/s_get_alarm_sum.h" +#include "bacnet/basic/service/s_get_event.h" +#include "bacnet/basic/service/s_getevent.h" +#include "bacnet/basic/service/s_iam.h" +#include "bacnet/basic/service/s_ihave.h" +#include "bacnet/basic/service/s_lso.h" +#include "bacnet/basic/service/s_rd.h" +#include "bacnet/basic/service/s_readrange.h" +#include "bacnet/basic/service/s_rp.h" +#include "bacnet/basic/service/s_rpm.h" +#include "bacnet/basic/service/s_ts.h" +#include "bacnet/basic/service/s_uevent.h" +#include "bacnet/basic/service/s_upt.h" +#include "bacnet/basic/service/s_whohas.h" +#include "bacnet/basic/service/s_whois.h" +#include "bacnet/basic/service/s_wp.h" +#include "bacnet/basic/service/s_wpm.h" + +/** @defgroup MISCHNDLR Miscellaneous Service Handlers + * Various utilities and functions to support the service handlers + */ +#endif diff --git a/src/bigend.c b/src/bacnet/basic/sys/bigend.c similarity index 100% rename from src/bigend.c rename to src/bacnet/basic/sys/bigend.c diff --git a/include/bigend.h b/src/bacnet/basic/sys/bigend.h similarity index 100% rename from include/bigend.h rename to src/bacnet/basic/sys/bigend.h diff --git a/src/debug.c b/src/bacnet/basic/sys/debug.c similarity index 90% rename from src/debug.c rename to src/bacnet/basic/sys/debug.c index 992a80e2..0262d6d0 100644 --- a/src/debug.c +++ b/src/bacnet/basic/sys/debug.c @@ -32,12 +32,12 @@ ------------------------------------------- ####COPYRIGHTEND####*/ -#include /* for standard integer types uint8_t etc. */ +#include /* for standard integer types uint8_t etc. */ #include /* for the standard bool type. */ -#include /* Standard I/O */ -#include /* Standard Library */ +#include /* Standard I/O */ +#include /* Standard Library */ #include -#include "debug.h" +#include "bacnet/basic/sys/debug.h" /** @file debug.c Debug print function */ diff --git a/include/debug.h b/src/bacnet/basic/sys/debug.h similarity index 98% rename from include/debug.h rename to src/bacnet/basic/sys/debug.h index 94c29348..0126b390 100644 --- a/include/debug.h +++ b/src/bacnet/basic/sys/debug.h @@ -27,7 +27,7 @@ #include #include #include -#include "bacdef.h" +#include "bacnet/bacdef.h" #ifndef DEBUG_ENABLED #define DEBUG_ENABLED 0 diff --git a/src/fifo.c b/src/bacnet/basic/sys/fifo.c old mode 100755 new mode 100644 similarity index 98% rename from src/fifo.c rename to src/bacnet/basic/sys/fifo.c index f6085024..8a62d58b --- a/src/fifo.c +++ b/src/bacnet/basic/sys/fifo.c @@ -92,7 +92,7 @@ #include #include #include -#include "fifo.h" +#include "bacnet/basic/sys/fifo.h" /** * Returns the number of bytes in the FIFO @@ -342,11 +342,11 @@ void FIFO_Init(FIFO_BUFFER *b, volatile uint8_t *buffer, unsigned buffer_len) void testFIFOBuffer(Test *pTest) { /* FIFO data structure */ - FIFO_BUFFER test_buffer = {0}; + FIFO_BUFFER test_buffer = { 0 }; /* FIFO data store. Note: size must be a power of two! */ - volatile uint8_t data_store[64] = {0}; - uint8_t add_data[40] = {"RoseSteveLouPatRachelJessicaDaniAmyHerb"}; - uint8_t test_add_data[40] = {0}; + volatile uint8_t data_store[64] = { 0 }; + uint8_t add_data[40] = { "RoseSteveLouPatRachelJessicaDaniAmyHerb" }; + uint8_t test_add_data[40] = { 0 }; uint8_t test_data = 0; unsigned index = 0; unsigned count = 0; diff --git a/include/fifo.h b/src/bacnet/basic/sys/fifo.h old mode 100755 new mode 100644 similarity index 100% rename from include/fifo.h rename to src/bacnet/basic/sys/fifo.h diff --git a/src/filename.c b/src/bacnet/basic/sys/filename.c similarity index 98% rename from src/filename.c rename to src/bacnet/basic/sys/filename.c index 34dd9975..70633d9a 100644 --- a/src/filename.c +++ b/src/bacnet/basic/sys/filename.c @@ -33,7 +33,7 @@ ####COPYRIGHTEND####*/ #include #include -#include "filename.h" +#include "bacnet/basic/sys/filename.h" /** @file filename.c Function for filename manipulation */ diff --git a/include/filename.h b/src/bacnet/basic/sys/filename.h similarity index 100% rename from include/filename.h rename to src/bacnet/basic/sys/filename.h diff --git a/src/key.c b/src/bacnet/basic/sys/key.c similarity index 95% rename from src/key.c rename to src/bacnet/basic/sys/key.c index 6cec9c13..74f93860 100644 --- a/src/key.c +++ b/src/bacnet/basic/sys/key.c @@ -67,8 +67,8 @@ void testKeys(Test *pTest) void testKeySample(Test *pTest) { int type, id; - int type_list[] = {0, 1, KEY_TYPE_MAX / 2, KEY_TYPE_MAX - 1, -1}; - int id_list[] = {0, 1, KEY_ID_MAX / 2, KEY_ID_MAX - 1, -1}; + int type_list[] = { 0, 1, KEY_TYPE_MAX / 2, KEY_TYPE_MAX - 1, -1 }; + int id_list[] = { 0, 1, KEY_ID_MAX / 2, KEY_ID_MAX - 1, -1 }; int type_index = 0; int id_index = 0; int decoded_type, decoded_id; diff --git a/include/key.h b/src/bacnet/basic/sys/key.h similarity index 100% rename from include/key.h rename to src/bacnet/basic/sys/key.h diff --git a/src/keylist.c b/src/bacnet/basic/sys/keylist.c similarity index 92% rename from src/keylist.c rename to src/bacnet/basic/sys/keylist.c index bb9896be..b6dc79c9 100644 --- a/src/keylist.c +++ b/src/bacnet/basic/sys/keylist.c @@ -42,7 +42,7 @@ #include -#include "keylist.h" /* check for valid prototypes */ +#include "bacnet/basic/sys/keylist.h" /* check for valid prototypes */ #ifndef FALSE #define FALSE 0 @@ -73,27 +73,30 @@ static struct Keylist *KeylistCreate(void) /* returns TRUE if success, FALSE if failed */ static int CheckArraySize(OS_Keylist list) { - int new_size = 0; /* set it up so that no size change is the default */ + int new_size = 0; /* set it up so that no size change is the default */ const int chunk = 8; /* minimum number of nodes to allocate memory for */ struct Keylist_Node **new_array; /* new array of nodes, if needed */ - int i; /* counter */ - if (!list) + int i; /* counter */ + if (!list) { return FALSE; + } /* indicates the need for more memory allocation */ - if (list->count == list->size) + if (list->count == list->size) { new_size = list->size + chunk; - /* allow for shrinking memory */ - else if ((list->size > chunk) && (list->count < (list->size - chunk))) + /* allow for shrinking memory */ + } else if ((list->size > chunk) && (list->count < (list->size - chunk))) { new_size = list->size - chunk; + } if (new_size) { /* Allocate more room for node pointer array */ new_array = calloc((size_t)new_size, sizeof(new_array)); /* See if we got the memory we wanted */ - if (!new_array) + if (!new_array) { return FALSE; + } /* copy the nodes from the old array to the new array */ if (list->array) { @@ -118,11 +121,11 @@ static int CheckArraySize(OS_Keylist list) static int FindIndex(OS_Keylist list, KEY key, int *pIndex) { struct Keylist_Node *node; /* holds the new node */ - int left = 0; /* the left branch of tree, beginning of list */ - int right = 0; /* the right branch on the tree, end of list */ - int index = 0; /* our current search place in the array */ - KEY current_key = 0; /* place holder for current node key */ - int status = FALSE; /* return value */ + int left = 0; /* the left branch of tree, beginning of list */ + int right = 0; /* the right branch on the tree, end of list */ + int index = 0; /* our current search place in the array */ + KEY current_key = 0; /* place holder for current node key */ + int status = FALSE; /* return value */ if (!list || !list->array || !list->count) { *pIndex = 0; return (FALSE); @@ -133,14 +136,16 @@ static int FindIndex(OS_Keylist list, KEY key, int *pIndex) /* A binary search */ index = (left + right) / 2; node = list->array[index]; - if (!node) + if (!node) { break; + } current_key = node->key; - if (key < current_key) + if (key < current_key) { right = index - 1; - else + } else { left = index + 1; + } } while ((key != current_key) && (left <= right)); if (key == current_key) { status = TRUE; @@ -149,11 +154,12 @@ static int FindIndex(OS_Keylist list, KEY key, int *pIndex) else { /* where the index should be */ - if (key > current_key) + if (key > current_key) { *pIndex = index + 1; - else + } else { *pIndex = index; + } } return (status); } @@ -165,21 +171,21 @@ static int FindIndex(OS_Keylist list, KEY key, int *pIndex) int Keylist_Data_Add(OS_Keylist list, KEY key, void *data) { struct Keylist_Node *node; /* holds the new node */ - int index = -1; /* return value */ - int i; /* counts through the array */ + int index = -1; /* return value */ + int i; /* counts through the array */ if (list && CheckArraySize(list)) { /* figure out where to put the new node */ if (list->count) { (void)FindIndex(list, key, &index); - /* Add to the beginning of the list */ - if (index < 0) + if (index < 0) { + /* Add to the beginning of the list */ index = 0; - /* Add to the end of the list */ - else if (index > list->count) + } else if (index > list->count) { + /* Add to the end of the list */ index = list->count; - + } /* Move all the items up to make room for the new one */ for (i = list->count; i > index; i--) { list->array[i] = list->array[i - 1]; @@ -218,13 +224,11 @@ void *Keylist_Data_Delete_By_Index(OS_Keylist list, int index) /* move the nodes to account for the deleted one */ if (list->count == 1) { /* There is no node shifting to do */ - } - /* We are the last one */ - else if (index == (list->count - 1)) { + } else if (index == (list->count - 1)) { + /* We are the last one */ /* There is no node shifting to do */ - } - /* Move all the nodes down one */ - else { + } else { + /* Move all the nodes down one */ int i; /* counter */ int count = list->count - 1; for (i = index; i < count; i++) { @@ -232,8 +236,9 @@ void *Keylist_Data_Delete_By_Index(OS_Keylist list, int index) } } list->count--; - if (node) + if (node) { free(node); + } /* potentially reduce the size of the array */ (void)CheckArraySize(list); @@ -246,7 +251,7 @@ void *Keylist_Data_Delete_By_Index(OS_Keylist list, int index) void *Keylist_Data_Delete(OS_Keylist list, KEY key) { void *data = NULL; /* return value */ - int index; /* where the node is in the array */ + int index; /* where the node is in the array */ if (list) { if (FindIndex(list, key, &index)) @@ -260,7 +265,7 @@ void *Keylist_Data_Delete(OS_Keylist list, KEY key) void *Keylist_Data_Pop(OS_Keylist list) { void *data = NULL; /* return value */ - int index; /* position in the array */ + int index; /* position in the array */ if (list && list->count) { index = list->count - 1; diff --git a/include/keylist.h b/src/bacnet/basic/sys/keylist.h similarity index 100% rename from include/keylist.h rename to src/bacnet/basic/sys/keylist.h diff --git a/src/bacnet/basic/sys/mstimer.c b/src/bacnet/basic/sys/mstimer.c new file mode 100644 index 00000000..92a07b72 --- /dev/null +++ b/src/bacnet/basic/sys/mstimer.c @@ -0,0 +1,123 @@ +/** + * @file + * @author Steve Karg + * @date 2009 + * @brief Millisecond timer library header file. + * + * @section DESCRIPTION + * + * The mstimer library provides functions for setting, resetting and + * restarting timers, and for checking if a timer has expired. An + * application must "manually" check if its timers have expired; this + * is not done automatically. + * + * A timer is declared as a \c struct \c mstimer and all access to the + * timer is made by a pointer to the declared timer. + * + * Adapted from the Contiki operating system. + * Original Authors: Adam Dunkels , Nicolas Tsiftes + */ +#include +#include +#include +#include +#include "mstimer.h" + +/** + * @brief Set a timer for a time sometime in the future + * + * This function is used to set a timer for a time sometime in the + * future. The function mstimer_expired() will evaluate to true after + * the timer has expired. + * + * @param t A pointer to the timer + * @param interval The interval before the timer expires. + */ +void mstimer_set(struct mstimer *t, unsigned long interval) +{ + t->interval = interval; + t->start = mstimer_now(); +} + +/** + * @brief Reset the timer with the same interval. + * + * This function resets the timer with the same interval that was + * given to the mstimer_set() function. The start point of the interval + * is the exact time that the timer last expired. Therefore, this + * function will cause the timer to be stable over time, unlike the + * mstimer_restart() function. + * + * @param t A pointer to the timer. + * @sa mstimer_restart() + */ +void mstimer_reset(struct mstimer *t) +{ + t->start += t->interval; +} + +/** + * @brief Restart the timer from the current point in time + * + * This function restarts a timer with the same interval that was + * given to the mstimer_set() function. The timer will start at the + * current time. + * + * @note A periodic timer will drift if this function is used to reset + * it. For preioric timers, use the mstimer_reset() function instead. + * @param t A pointer to the timer. + * @sa mstimer_reset() + */ +void mstimer_restart(struct mstimer *t) +{ + t->start = mstimer_now(); +} + +/** + * @brief Check if a timer has expired. + * + * This function tests if a timer has expired and returns true or + * false depending on its status. + * + * @param t A pointer to the timer + * @return Non-zero if the timer has expired, zero otherwise. + */ +int mstimer_expired(struct mstimer *t) +{ + if (t->interval) { + return ((unsigned long)((mstimer_now()) - (t->start + t->interval)) < + ((unsigned long)(~((unsigned long)0)) >> 1)); + } + + return 0; +} +/*---------------------------------------------------------------------------*/ +/** + * The time until the timer expires + * + * This function returns the time until the timer expires. + * + * @param t A pointer to the timer + * + * @return The time until the timer expires + * + */ +unsigned long mstimer_remaining(struct mstimer *t) +{ + return t->start + t->interval - mstimer_now(); +} + +/** + * The value of the interval + * + * This function returns the interval value + * + * @param t A pointer to the timer + * + * @return The interval value + * + */ +unsigned long mstimer_interval(struct mstimer *t) +{ + return t->interval; +} diff --git a/src/bacnet/basic/sys/mstimer.h b/src/bacnet/basic/sys/mstimer.h new file mode 100644 index 00000000..30de565f --- /dev/null +++ b/src/bacnet/basic/sys/mstimer.h @@ -0,0 +1,66 @@ +/** + * @file + * @author Steve Karg + * @date 2009 + * @brief Millisecond timer library header file. + * + * @section DESCRIPTION + * + * The mstimer library provides functions for setting, resetting and + * restarting timers, and for checking if a timer has expired. An + * application must "manually" check if its timers have expired; this + * is not done automatically. + * + * A timer is declared as a \c struct \c mstimer and all access to the + * timer is made by a pointer to the declared timer. + * + * Adapted from the Contiki operating system. + * Original Authors: Adam Dunkels , Nicolas Tsiftes + */ +#ifndef MSTIMER_H_ +#define MSTIMER_H_ + +/** + * A timer. + * + * This structure is used for declaring a timer. The timer must be set + * with mstimer_set() before it can be used. + * + * \hideinitializer + */ +struct mstimer { + unsigned long start; + unsigned long interval; +}; + +typedef void (*mstimer_callback_function) (void); +/* callback data structure */ +struct mstimer_callback_data_t; +struct mstimer_callback_data_t { + struct mstimer timer; + mstimer_callback_function callback; + struct mstimer_callback_data_t *next; +}; + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +void mstimer_set(struct mstimer *t, unsigned long interval); +void mstimer_reset(struct mstimer *t); +void mstimer_restart(struct mstimer *t); +int mstimer_expired(struct mstimer *t); +unsigned long mstimer_remaining(struct mstimer *t); +unsigned long mstimer_interval(struct mstimer *t); +/* HAL implementation */ +unsigned long mstimer_now(void); +void mstimer_callback( + struct mstimer_callback_data_t *cb, + mstimer_callback_function callback, + unsigned long milliseconds); +void mstimer_init(void); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/src/ringbuf.c b/src/bacnet/basic/sys/ringbuf.c similarity index 91% rename from src/ringbuf.c rename to src/bacnet/basic/sys/ringbuf.c index b24a467a..f96d1517 100644 --- a/src/ringbuf.c +++ b/src/bacnet/basic/sys/ringbuf.c @@ -50,7 +50,7 @@ #include #include #include -#include "ringbuf.h" +#include "bacnet/basic/sys/ringbuf.h" /** * Returns the number of elements in the ring buffer @@ -200,8 +200,8 @@ volatile uint8_t *Ringbuf_Peek_Next(RING_BUFFER const *b, uint8_t *data_element) b->buffer + ((index % b->element_count) * b->element_size); if (data_element == this_element) { /* Found the current element, get the next one on the list */ - next_element = b->buffer + (((index + 1) % b->element_count) * - b->element_size); + next_element = b->buffer + + (((index + 1) % b->element_count) * b->element_size); break; } } @@ -219,9 +219,9 @@ volatile uint8_t *Ringbuf_Peek_Next(RING_BUFFER const *b, uint8_t *data_element) */ bool Ringbuf_Pop(RING_BUFFER *b, uint8_t *data_element) { - bool status = false; /* return value */ + bool status = false; /* return value */ volatile uint8_t *ring_data = NULL; /* used to help point ring data */ - unsigned i; /* loop counter */ + unsigned i; /* loop counter */ if (!Ringbuf_Empty(b)) { ring_data = b->buffer; @@ -247,15 +247,15 @@ bool Ringbuf_Pop(RING_BUFFER *b, uint8_t *data_element) * @param data_element - element of data that is loaded with data from ring * @return true if data was copied, false if list is empty */ -bool Ringbuf_Pop_Element(RING_BUFFER *b, uint8_t *this_element, - uint8_t *data_element) +bool Ringbuf_Pop_Element( + RING_BUFFER *b, uint8_t *this_element, uint8_t *data_element) { - bool status = false; /* return value */ + bool status = false; /* return value */ volatile uint8_t *ring_data = NULL; /* used to help point ring data */ volatile uint8_t *prev_data; - unsigned index; /* list index */ + unsigned index; /* list index */ unsigned this_index = b->head; /* index of element to remove */ - unsigned i; /* loop counter */ + unsigned i; /* loop counter */ if (!Ringbuf_Empty(b) && this_element != NULL) { for (index = b->tail; index < b->head; index++) { /* Find the specified data_element */ @@ -278,8 +278,8 @@ bool Ringbuf_Pop_Element(RING_BUFFER *b, uint8_t *this_element, /* Get pointers to current and previous data_elements */ ring_data = b->buffer + ((index % b->element_count) * b->element_size); - prev_data = b->buffer + (((index - 1) % b->element_count) * - b->element_size); + prev_data = b->buffer + + (((index - 1) % b->element_count) * b->element_size); for (i = 0; i < b->element_size; i++) { ring_data[i] = prev_data[i]; } @@ -301,9 +301,9 @@ bool Ringbuf_Pop_Element(RING_BUFFER *b, uint8_t *this_element, */ bool Ringbuf_Put(RING_BUFFER *b, uint8_t *data_element) { - bool status = false; /* return value */ + bool status = false; /* return value */ volatile uint8_t *ring_data = NULL; /* used to help point ring data */ - unsigned i; /* loop counter */ + unsigned i; /* loop counter */ if (b && data_element) { /* limit the amount of elements that we accept */ @@ -335,9 +335,9 @@ bool Ringbuf_Put(RING_BUFFER *b, uint8_t *data_element) */ bool Ringbuf_Put_Front(RING_BUFFER *b, uint8_t *data_element) { - bool status = false; /* return value */ + bool status = false; /* return value */ volatile uint8_t *ring_data = NULL; /* used to help point ring data */ - unsigned i = 0; /* loop counter */ + unsigned i = 0; /* loop counter */ if (b && data_element) { /* limit the amount of elements that we accept */ @@ -434,8 +434,10 @@ static bool isPowerOfTwo(unsigned int x) * * @return true if ring buffer was initialized */ -bool Ringbuf_Init(RING_BUFFER *b, volatile uint8_t *buffer, - unsigned element_size, unsigned element_count) +bool Ringbuf_Init(RING_BUFFER *b, + volatile uint8_t *buffer, + unsigned element_size, + unsigned element_count) { bool status = false; @@ -468,9 +470,11 @@ bool Ringbuf_Init(RING_BUFFER *b, volatile uint8_t *buffer, * @param element_size - size of one data element * @param element_count - number of data elements in the store */ -static void testRingAroundBuffer(Test *pTest, RING_BUFFER *test_buffer, - uint8_t *data_element, unsigned element_size, - unsigned element_count) +static void testRingAroundBuffer(Test *pTest, + RING_BUFFER *test_buffer, + uint8_t *data_element, + unsigned element_size, + unsigned element_count) { volatile uint8_t *test_data; unsigned index; @@ -516,8 +520,11 @@ static void testRingAroundBuffer(Test *pTest, RING_BUFFER *test_buffer, * @param element_size - size of one data element * @param element_count - number of data elements in the store */ -static bool testRingBuf(Test *pTest, uint8_t *data_store, uint8_t *data_element, - unsigned element_size, unsigned element_count) +static bool testRingBuf(Test *pTest, + uint8_t *data_store, + uint8_t *data_element, + unsigned element_size, + unsigned element_count) { RING_BUFFER test_buffer; volatile uint8_t *test_data; @@ -588,15 +595,15 @@ static bool testRingBuf(Test *pTest, uint8_t *data_store, uint8_t *data_element, Ringbuf_Depth_Reset(&test_buffer); ct_test(pTest, Ringbuf_Depth(&test_buffer) == 0); - testRingAroundBuffer(pTest, &test_buffer, data_element, element_size, - element_count); + testRingAroundBuffer( + pTest, &test_buffer, data_element, element_size, element_count); /* adjust the internal index of Ringbuf to test unsigned wrapping */ test_buffer.head = UINT_MAX - 1; test_buffer.tail = UINT_MAX - 1; - testRingAroundBuffer(pTest, &test_buffer, data_element, element_size, - element_count); + testRingAroundBuffer( + pTest, &test_buffer, data_element, element_size, element_count); return true; } @@ -613,7 +620,7 @@ void testRingBufSizeSmall(Test *pTest) uint8_t data_store[sizeof(data_element) * NEXT_POWER_OF_2(16)]; status = testRingBuf(pTest, data_store, data_element, sizeof(data_element), - sizeof(data_store) / sizeof(data_element)); + sizeof(data_store) / sizeof(data_element)); ct_test(pTest, status); } @@ -629,7 +636,7 @@ void testRingBufSizeLarge(Test *pTest) uint8_t data_store[sizeof(data_element) * NEXT_POWER_OF_2(99)]; status = testRingBuf(pTest, data_store, data_element, sizeof(data_element), - sizeof(data_store) / sizeof(data_element)); + sizeof(data_store) / sizeof(data_element)); ct_test(pTest, status); } @@ -645,7 +652,7 @@ void testRingBufSizeInvalid(Test *pTest) uint8_t data_store[sizeof(data_element) * 99]; status = testRingBuf(pTest, data_store, data_element, sizeof(data_element), - sizeof(data_store) / sizeof(data_element)); + sizeof(data_store) / sizeof(data_element)); ct_test(pTest, status == false); } @@ -669,9 +676,11 @@ void testRingBufPowerOfTwo(Test *pTest) * @param element_size - size of one data element * @param element_count - number of data elements in the store */ -static bool testRingBufNextElement(Test *pTest, uint8_t *data_store, - uint8_t *data_element, unsigned element_size, - unsigned element_count) +static bool testRingBufNextElement(Test *pTest, + uint8_t *data_store, + uint8_t *data_element, + unsigned element_size, + unsigned element_count) { RING_BUFFER test_buffer; volatile uint8_t *test_data; @@ -773,8 +782,7 @@ void testRingBufNextElementSizeSmall(Test *pTest) uint8_t data_store[sizeof(data_element) * NEXT_POWER_OF_2(16)]; status = testRingBufNextElement(pTest, data_store, data_element, - sizeof(data_element), - sizeof(data_store) / sizeof(data_element)); + sizeof(data_element), sizeof(data_store) / sizeof(data_element)); ct_test(pTest, status); } diff --git a/include/ringbuf.h b/src/bacnet/basic/sys/ringbuf.h similarity index 100% rename from include/ringbuf.h rename to src/bacnet/basic/sys/ringbuf.h diff --git a/src/sbuf.c b/src/bacnet/basic/sys/sbuf.c similarity index 92% rename from src/sbuf.c rename to src/bacnet/basic/sys/sbuf.c index 075e64d2..d149d842 100644 --- a/src/sbuf.c +++ b/src/bacnet/basic/sys/sbuf.c @@ -43,8 +43,8 @@ #include "sbuf.h" void sbuf_init(STATIC_BUFFER *b, /* static buffer structure */ - char *data, /* data block */ - unsigned size) + char *data, /* data block */ + unsigned size) { /* actual size, in bytes, of the data block or array of data */ if (b) { b->data = data; @@ -78,10 +78,10 @@ unsigned sbuf_count(STATIC_BUFFER *b) /* returns true if successful, false if not enough room to append data */ bool sbuf_put(STATIC_BUFFER *b, /* static buffer structure */ - unsigned offset, /* where to start */ - char *data, /* data to place in buffer */ - unsigned data_size) -{ /* how many bytes to add */ + unsigned offset, /* where to start */ + char *data, /* data to place in buffer */ + unsigned data_size) +{ /* how many bytes to add */ bool status = false; /* return value */ if (b && b->data) { @@ -102,8 +102,8 @@ bool sbuf_put(STATIC_BUFFER *b, /* static buffer structure */ /* returns true if successful, false if not enough room to append data */ bool sbuf_append(STATIC_BUFFER *b, /* static buffer structure */ - char *data, /* data to place in buffer */ - unsigned data_size) + char *data, /* data to place in buffer */ + unsigned data_size) { /* how many bytes to add */ unsigned count = 0; @@ -116,8 +116,8 @@ bool sbuf_append(STATIC_BUFFER *b, /* static buffer structure */ /* returns true if successful, false if not enough room to append data */ bool sbuf_truncate(STATIC_BUFFER *b, /* static buffer structure */ - unsigned count) -{ /* total number of bytes in to remove */ + unsigned count) +{ /* total number of bytes in to remove */ bool status = false; /* return value */ if (b) { diff --git a/include/sbuf.h b/src/bacnet/basic/sys/sbuf.h similarity index 100% rename from include/sbuf.h rename to src/bacnet/basic/sys/sbuf.h diff --git a/src/tsm.c b/src/bacnet/basic/tsm/tsm.c similarity index 89% rename from src/tsm.c rename to src/bacnet/basic/tsm/tsm.c index cde2d66d..e42dc7b3 100644 --- a/src/tsm.c +++ b/src/bacnet/basic/tsm/tsm.c @@ -35,19 +35,21 @@ #include #include #include -#include "bits.h" -#include "apdu.h" -#include "bacdef.h" -#include "bacdcode.h" -#include "bacenum.h" -#include "tsm.h" -#include "config.h" -#include "datalink.h" -#include "handlers.h" -#include "address.h" -#include "bacaddr.h" +#include "bacnet/bits.h" +#include "bacnet/apdu.h" +#include "bacnet/bacaddr.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacenum.h" +#include "bacnet/config.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/datalink/datalink.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/binding/address.h" /** @file tsm.c BACnet Transaction State Machine operations */ +/* FIXME: modify basic service handlers to use TSM rather than this buffer! */ +uint8_t Handler_Transmit_Buffer[MAX_PDU] = { 0 }; #if (MAX_TSM_TRANSACTIONS) /* Really only needed for segmented messages */ @@ -74,7 +76,7 @@ void tsm_set_timeout_handler(tsm_timeout_function pFunction) /* returns MAX_TSM_TRANSACTIONS if not found */ static uint8_t tsm_find_invokeID_index(uint8_t invokeID) { - unsigned i = 0; /* counter */ + unsigned i = 0; /* counter */ uint8_t index = MAX_TSM_TRANSACTIONS; /* return value */ for (i = 0; i < MAX_TSM_TRANSACTIONS; i++) { @@ -89,7 +91,7 @@ static uint8_t tsm_find_invokeID_index(uint8_t invokeID) static uint8_t tsm_find_first_free_index(void) { - unsigned i = 0; /* counter */ + unsigned i = 0; /* counter */ uint8_t index = MAX_TSM_TRANSACTIONS; /* return value */ for (i = 0; i < MAX_TSM_TRANSACTIONS; i++) { @@ -105,7 +107,7 @@ static uint8_t tsm_find_first_free_index(void) bool tsm_transaction_available(void) { bool status = false; /* return value */ - unsigned i = 0; /* counter */ + unsigned i = 0; /* counter */ for (i = 0; i < MAX_TSM_TRANSACTIONS; i++) { if (TSM_List[i].InvokeID == 0) { @@ -121,7 +123,7 @@ bool tsm_transaction_available(void) uint8_t tsm_transaction_idle_count(void) { uint8_t count = 0; /* return value */ - unsigned i = 0; /* counter */ + unsigned i = 0; /* counter */ for (i = 0; i < MAX_TSM_TRANSACTIONS; i++) { if ((TSM_List[i].InvokeID == 0) && @@ -190,9 +192,10 @@ uint8_t tsm_next_free_invokeID(void) } void tsm_set_confirmed_unsegmented_transaction(uint8_t invokeID, - BACNET_ADDRESS *dest, - BACNET_NPDU_DATA *ndpu_data, - uint8_t *apdu, uint16_t apdu_len) + BACNET_ADDRESS *dest, + BACNET_NPDU_DATA *ndpu_data, + uint8_t *apdu, + uint16_t apdu_len) { uint16_t j = 0; uint8_t index; @@ -220,9 +223,11 @@ void tsm_set_confirmed_unsegmented_transaction(uint8_t invokeID, /* used to retrieve the transaction payload */ /* if we wanted to find out what we sent (i.e. when we get an ack) */ -bool tsm_get_transaction_pdu(uint8_t invokeID, BACNET_ADDRESS *dest, - BACNET_NPDU_DATA *ndpu_data, uint8_t *apdu, - uint16_t *apdu_len) +bool tsm_get_transaction_pdu(uint8_t invokeID, + BACNET_ADDRESS *dest, + BACNET_NPDU_DATA *ndpu_data, + uint8_t *apdu, + uint16_t *apdu_len) { uint16_t j = 0; uint8_t index; @@ -256,18 +261,18 @@ void tsm_timer_milliseconds(uint16_t milliseconds) for (i = 0; i < MAX_TSM_TRANSACTIONS; i++) { if (TSM_List[i].state == TSM_STATE_AWAIT_CONFIRMATION) { - if (TSM_List[i].RequestTimer > milliseconds) + if (TSM_List[i].RequestTimer > milliseconds) { TSM_List[i].RequestTimer -= milliseconds; - else + } else { TSM_List[i].RequestTimer = 0; + } /* AWAIT_CONFIRMATION */ if (TSM_List[i].RequestTimer == 0) { if (TSM_List[i].RetryCount < apdu_retries()) { TSM_List[i].RequestTimer = apdu_timeout(); TSM_List[i].RetryCount++; datalink_send_pdu(&TSM_List[i].dest, &TSM_List[i].npdu_data, - &TSM_List[i].apdu[0], - TSM_List[i].apdu_len); + &TSM_List[i].apdu[0], TSM_List[i].apdu_len); } else { /* note: the invoke id has not been cleared yet and this indicates a failed message: @@ -307,8 +312,9 @@ bool tsm_invoke_id_free(uint8_t invokeID) uint8_t index; index = tsm_find_invokeID_index(invokeID); - if (index < MAX_TSM_TRANSACTIONS) + if (index < MAX_TSM_TRANSACTIONS) { status = false; + } return status; } @@ -329,8 +335,9 @@ bool tsm_invoke_id_failed(uint8_t invokeID) if (index < MAX_TSM_TRANSACTIONS) { /* a valid invoke ID and the state is IDLE is a message that failed to confirm */ - if (TSM_List[index].state == TSM_STATE_IDLE) + if (TSM_List[index].state == TSM_STATE_IDLE) { status = true; + } } return status; @@ -345,8 +352,10 @@ bool tsm_invoke_id_failed(uint8_t invokeID) bool I_Am_Request = true; /* dummy function stubs */ -int datalink_send_pdu(BACNET_ADDRESS *dest, BACNET_NPDU_DATA *npdu_data, - uint8_t *pdu, unsigned pdu_len) +int datalink_send_pdu(BACNET_ADDRESS *dest, + BACNET_NPDU_DATA *npdu_data, + uint8_t *pdu, + unsigned pdu_len) { (void)dest; (void)npdu_data; diff --git a/include/tsm.h b/src/bacnet/basic/tsm/tsm.h similarity index 95% rename from include/tsm.h rename to src/bacnet/basic/tsm/tsm.h index 70ca164e..184b3bcc 100644 --- a/include/tsm.h +++ b/src/bacnet/basic/tsm/tsm.h @@ -27,11 +27,16 @@ #include #include #include -#include "bacdef.h" -#include "npdu.h" +#include "bacnet/config.h" +#include "bacnet/bacdef.h" +#include "bacnet/npdu.h" /* note: TSM functionality is optional - only needed if we are doing client requests */ + +/* FIXME: modify basic service handlers to use TSM rather than this buffer! */ +extern uint8_t Handler_Transmit_Buffer[MAX_PDU]; + #if (!MAX_TSM_TRANSACTIONS) #define tsm_free_invoke_id(x) (void)x; #else diff --git a/src/ucix.c b/src/bacnet/basic/ucix/ucix.c similarity index 63% rename from src/ucix.c rename to src/bacnet/basic/ucix/ucix.c index 21d37c53..a7dac7d8 100644 --- a/src/ucix.c +++ b/src/bacnet/basic/ucix/ucix.c @@ -22,13 +22,16 @@ #include #include -#include "ucix.h" +#include "bacnet/basic/ucix/ucix.h" /*#include "log.h" */ static struct uci_ptr ptr; -static inline int ucix_get_ptr(struct uci_context *ctx, const char *p, - const char *s, const char *o, const char *t) +static inline int ucix_get_ptr(struct uci_context *ctx, + const char *p, + const char *s, + const char *o, + const char *t) { memset(&ptr, 0, sizeof(ptr)); ptr.package = p; @@ -44,8 +47,8 @@ struct uci_context *ucix_init(const char *config_file) /* uci_add_history_path(ctx, "/var/state"); */ uci_add_delta_path(ctx, "/var/state"); if (uci_load(ctx, config_file, NULL) != UCI_OK) { - fprintf(stderr, "%s/%s is missing or corrupt\n", ctx->savedir, - config_file); + fprintf( + stderr, "%s/%s is missing or corrupt\n", ctx->savedir, config_file); return NULL; } return ctx; @@ -54,11 +57,12 @@ struct uci_context *ucix_init(const char *config_file) struct uci_context *ucix_init_path(const char *path, const char *config_file) { struct uci_context *ctx = uci_alloc_context(); - if (path) + if (path) { uci_set_confdir(ctx, path); + } if (uci_load(ctx, config_file, NULL) != UCI_OK) { - fprintf(stderr, "%s/%s is missing or corrupt\n", ctx->savedir, - config_file); + fprintf( + stderr, "%s/%s is missing or corrupt\n", ctx->savedir, config_file); return NULL; } return ctx; @@ -81,13 +85,14 @@ void ucix_save_state(struct uci_context *ctx) uci_save(ctx, NULL); } -const char *ucix_get_option(struct uci_context *ctx, const char *p, - const char *s, const char *o) +const char *ucix_get_option( + struct uci_context *ctx, const char *p, const char *s, const char *o) { struct uci_element *e = NULL; const char *value = NULL; - if (ucix_get_ptr(ctx, p, s, o, NULL)) + if (ucix_get_ptr(ctx, p, s, o, NULL)) { return NULL; + } if (!(ptr.flags & UCI_LOOKUP_COMPLETE)) return NULL; e = ptr.last; @@ -112,70 +117,84 @@ const char *ucix_get_option(struct uci_context *ctx, const char *p, return value; } -int ucix_get_option_int(struct uci_context *ctx, const char *p, const char *s, - const char *o, int def) +int ucix_get_option_int(struct uci_context *ctx, + const char *p, + const char *s, + const char *o, + int def) { const char *tmp = ucix_get_option(ctx, p, s, o); int ret = def; - if (tmp) + if (tmp) { ret = atoi(tmp); + } return ret; } -void ucix_add_section(struct uci_context *ctx, const char *p, const char *s, - const char *t) +void ucix_add_section( + struct uci_context *ctx, const char *p, const char *s, const char *t) { - if (ucix_get_ptr(ctx, p, s, NULL, t)) + if (ucix_get_ptr(ctx, p, s, NULL, t)) { return; + } uci_set(ctx, &ptr); } -void ucix_add_option(struct uci_context *ctx, const char *p, const char *s, - const char *o, const char *t) +void ucix_add_option(struct uci_context *ctx, + const char *p, + const char *s, + const char *o, + const char *t) { - if (ucix_get_ptr(ctx, p, s, o, (t) ? (t) : (""))) + if (ucix_get_ptr(ctx, p, s, o, (t) ? (t) : (""))) { return; + } uci_set(ctx, &ptr); } -void ucix_add_option_int(struct uci_context *ctx, const char *p, const char *s, - const char *o, int t) +void ucix_add_option_int( + struct uci_context *ctx, const char *p, const char *s, const char *o, int t) { char tmp[64]; snprintf(tmp, 64, "%d", t); ucix_add_option(ctx, p, s, o, tmp); } -void ucix_del(struct uci_context *ctx, const char *p, const char *s, - const char *o) +void ucix_del( + struct uci_context *ctx, const char *p, const char *s, const char *o) { - if (!ucix_get_ptr(ctx, p, s, o, NULL)) + if (!ucix_get_ptr(ctx, p, s, o, NULL)) { uci_delete(ctx, &ptr); + } } -void ucix_revert(struct uci_context *ctx, const char *p, const char *s, - const char *o) +void ucix_revert( + struct uci_context *ctx, const char *p, const char *s, const char *o) { - if (!ucix_get_ptr(ctx, p, s, o, NULL)) + if (!ucix_get_ptr(ctx, p, s, o, NULL)) { uci_revert(ctx, &ptr); + } } -void ucix_for_each_section_type(struct uci_context *ctx, const char *p, - const char *t, void (*cb)(const char *, void *), - void *priv) +void ucix_for_each_section_type(struct uci_context *ctx, + const char *p, + const char *t, + void (*cb)(const char *, void *), + void *priv) { struct uci_element *e; - if (ucix_get_ptr(ctx, p, NULL, NULL, NULL)) + if (ucix_get_ptr(ctx, p, NULL, NULL, NULL)) { return; + } uci_foreach_element(&ptr.p->sections, - e) if (!strcmp(t, uci_to_section(e)->type)) - cb(e->name, priv); + e) if (!strcmp(t, uci_to_section(e)->type)) cb(e->name, priv); } int ucix_commit(struct uci_context *ctx, const char *p) { - if (ucix_get_ptr(ctx, p, NULL, NULL, NULL)) + if (ucix_get_ptr(ctx, p, NULL, NULL, NULL)) { return 1; + } return uci_commit(ctx, &ptr.p, false); } diff --git a/include/ucix.h b/src/bacnet/basic/ucix/ucix.h similarity index 100% rename from include/ucix.h rename to src/bacnet/basic/ucix/ucix.h diff --git a/include/bits.h b/src/bacnet/bits.h similarity index 100% rename from include/bits.h rename to src/bacnet/bits.h diff --git a/include/bytes.h b/src/bacnet/bytes.h similarity index 100% rename from include/bytes.h rename to src/bacnet/bytes.h diff --git a/include/config.h b/src/bacnet/config.h similarity index 98% rename from include/config.h rename to src/bacnet/config.h index d8e38d76..9a35015d 100644 --- a/include/config.h +++ b/src/bacnet/config.h @@ -25,6 +25,11 @@ #ifndef CONFIG_H #define CONFIG_H +/* Include BACnet Specific conf */ +#if defined(BACNET_CONFIG_H) +#include "bacnet-config.h" +#endif + /* Note: these defines can be defined in your makefile or project or here or not defined and defaults will be used */ diff --git a/src/cov.c b/src/bacnet/cov.c similarity index 72% rename from src/cov.c rename to src/bacnet/cov.c index 0c349c5b..78ca28ba 100644 --- a/src/cov.c +++ b/src/bacnet/cov.c @@ -32,13 +32,13 @@ ------------------------------------------- ####COPYRIGHTEND####*/ #include -#include "bacenum.h" -#include "bacdcode.h" -#include "bacdef.h" -#include "bacapp.h" -#include "memcopy.h" +#include "bacnet/bacenum.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacapp.h" +#include "bacnet/memcopy.h" /* me! */ -#include "cov.h" +#include "bacnet/cov.h" /** @file cov.c Encode/Decode Change of Value (COV) services */ @@ -48,26 +48,26 @@ COV Subscribe Property COV Notification Unconfirmed COV Notification */ -static int notify_encode_apdu(uint8_t *apdu, unsigned max_apdu_len, - BACNET_COV_DATA *data) +static int notify_encode_apdu( + uint8_t *apdu, unsigned max_apdu_len, BACNET_COV_DATA *data) { - int len = 0; /* length of each encoding */ + int len = 0; /* length of each encoding */ int apdu_len = 0; /* total length of the apdu, return value */ BACNET_PROPERTY_VALUE *value = NULL; /* value in list */ BACNET_APPLICATION_DATA_VALUE *app_data = NULL; if (apdu) { /* tag 0 - subscriberProcessIdentifier */ - len = encode_context_unsigned(&apdu[apdu_len], 0, - data->subscriberProcessIdentifier); + len = encode_context_unsigned( + &apdu[apdu_len], 0, data->subscriberProcessIdentifier); apdu_len += len; /* tag 1 - initiatingDeviceIdentifier */ len = encode_context_object_id(&apdu[apdu_len], 1, OBJECT_DEVICE, - data->initiatingDeviceIdentifier); + data->initiatingDeviceIdentifier); apdu_len += len; /* tag 2 - monitoredObjectIdentifier */ - len = encode_context_object_id( - &apdu[apdu_len], 2, (int)data->monitoredObjectIdentifier.type, + len = encode_context_object_id(&apdu[apdu_len], 2, + (int)data->monitoredObjectIdentifier.type, data->monitoredObjectIdentifier.instance); apdu_len += len; /* tag 3 - timeRemaining */ @@ -83,13 +83,13 @@ static int notify_encode_apdu(uint8_t *apdu, unsigned max_apdu_len, value = data->listOfValues; while (value != NULL) { /* tag 0 - propertyIdentifier */ - len = encode_context_enumerated(&apdu[apdu_len], 0, - value->propertyIdentifier); + len = encode_context_enumerated( + &apdu[apdu_len], 0, value->propertyIdentifier); apdu_len += len; /* tag 1 - propertyArrayIndex OPTIONAL */ if (value->propertyArrayIndex != BACNET_ARRAY_ALL) { - len = encode_context_unsigned(&apdu[apdu_len], 1, - value->propertyArrayIndex); + len = encode_context_unsigned( + &apdu[apdu_len], 1, value->propertyArrayIndex); apdu_len += len; } /* tag 2 - value */ @@ -107,8 +107,8 @@ static int notify_encode_apdu(uint8_t *apdu, unsigned max_apdu_len, apdu_len += len; /* tag 3 - priority OPTIONAL */ if (value->priority != BACNET_NO_PRIORITY) { - len = encode_context_unsigned(&apdu[apdu_len], 3, - value->priority); + len = encode_context_unsigned( + &apdu[apdu_len], 3, value->priority); apdu_len += len; } /* is there another one to encode? */ @@ -122,10 +122,12 @@ static int notify_encode_apdu(uint8_t *apdu, unsigned max_apdu_len, return apdu_len; } -int ccov_notify_encode_apdu(uint8_t *apdu, unsigned max_apdu_len, - uint8_t invoke_id, BACNET_COV_DATA *data) +int ccov_notify_encode_apdu(uint8_t *apdu, + unsigned max_apdu_len, + uint8_t invoke_id, + BACNET_COV_DATA *data) { - int len = 0; /* length of each encoding */ + int len = 0; /* length of each encoding */ int apdu_len = BACNET_STATUS_ERROR; /* return value */ if (apdu && data && memcopylen(0, max_apdu_len, 4)) { @@ -147,10 +149,10 @@ int ccov_notify_encode_apdu(uint8_t *apdu, unsigned max_apdu_len, return apdu_len; } -int ucov_notify_encode_apdu(uint8_t *apdu, unsigned max_apdu_len, - BACNET_COV_DATA *data) +int ucov_notify_encode_apdu( + uint8_t *apdu, unsigned max_apdu_len, BACNET_COV_DATA *data) { - int len = 0; /* length of each encoding */ + int len = 0; /* length of each encoding */ int apdu_len = BACNET_STATUS_ERROR; /* return value */ if (apdu && data && memcopylen(0, max_apdu_len, 2)) { @@ -172,24 +174,24 @@ int ucov_notify_encode_apdu(uint8_t *apdu, unsigned max_apdu_len, /* decode the service request only */ /* COV and Unconfirmed COV are the same */ -int cov_notify_decode_service_request(uint8_t *apdu, unsigned apdu_len, - BACNET_COV_DATA *data) +int cov_notify_decode_service_request( + uint8_t *apdu, unsigned apdu_len, BACNET_COV_DATA *data) { int len = 0; /* return value */ int app_len = 0; uint8_t tag_number = 0; uint32_t len_value = 0; - uint32_t decoded_value = 0; /* for decoding */ - uint16_t decoded_type = 0; /* for decoding */ - uint32_t property = 0; /* for decoding */ + uint32_t decoded_value = 0; /* for decoding */ + uint16_t decoded_type = 0; /* for decoding */ + uint32_t property = 0; /* for decoding */ BACNET_PROPERTY_VALUE *value = NULL; /* value in list */ BACNET_APPLICATION_DATA_VALUE *app_data = NULL; if (apdu_len && data) { /* tag 0 - subscriberProcessIdentifier */ if (decode_is_context_tag(&apdu[len], 0)) { - len += decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value); + len += decode_tag_number_and_value( + &apdu[len], &tag_number, &len_value); len += decode_unsigned(&apdu[len], len_value, &decoded_value); data->subscriberProcessIdentifier = decoded_value; } else { @@ -197,10 +199,10 @@ int cov_notify_decode_service_request(uint8_t *apdu, unsigned apdu_len, } /* tag 1 - initiatingDeviceIdentifier */ if (decode_is_context_tag(&apdu[len], 1)) { - len += decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value); - len += decode_object_id(&apdu[len], &decoded_type, - &data->initiatingDeviceIdentifier); + len += decode_tag_number_and_value( + &apdu[len], &tag_number, &len_value); + len += decode_object_id( + &apdu[len], &decoded_type, &data->initiatingDeviceIdentifier); if (decoded_type != OBJECT_DEVICE) { return BACNET_STATUS_ERROR; } @@ -209,18 +211,18 @@ int cov_notify_decode_service_request(uint8_t *apdu, unsigned apdu_len, } /* tag 2 - monitoredObjectIdentifier */ if (decode_is_context_tag(&apdu[len], 2)) { - len += decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value); + len += decode_tag_number_and_value( + &apdu[len], &tag_number, &len_value); len += decode_object_id(&apdu[len], &decoded_type, - &data->monitoredObjectIdentifier.instance); + &data->monitoredObjectIdentifier.instance); data->monitoredObjectIdentifier.type = decoded_type; } else { return BACNET_STATUS_ERROR; } /* tag 3 - timeRemaining */ if (decode_is_context_tag(&apdu[len], 3)) { - len += decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value); + len += decode_tag_number_and_value( + &apdu[len], &tag_number, &len_value); len += decode_unsigned(&apdu[len], len_value, &decoded_value); data->timeRemaining = decoded_value; } else { @@ -241,8 +243,8 @@ int cov_notify_decode_service_request(uint8_t *apdu, unsigned apdu_len, while (value != NULL) { /* tag 0 - propertyIdentifier */ if (decode_is_context_tag(&apdu[len], 0)) { - len += decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value); + len += decode_tag_number_and_value( + &apdu[len], &tag_number, &len_value); len += decode_enumerated(&apdu[len], len_value, &property); value->propertyIdentifier = (BACNET_PROPERTY_ID)property; } else { @@ -250,8 +252,8 @@ int cov_notify_decode_service_request(uint8_t *apdu, unsigned apdu_len, } /* tag 1 - propertyArrayIndex OPTIONAL */ if (decode_is_context_tag(&apdu[len], 1)) { - len += decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value); + len += decode_tag_number_and_value( + &apdu[len], &tag_number, &len_value); len += decode_unsigned(&apdu[len], len_value, &decoded_value); value->propertyArrayIndex = decoded_value; } else { @@ -282,8 +284,8 @@ int cov_notify_decode_service_request(uint8_t *apdu, unsigned apdu_len, len++; /* tag 3 - priority OPTIONAL */ if (decode_is_context_tag(&apdu[len], 3)) { - len += decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value); + len += decode_tag_number_and_value( + &apdu[len], &tag_number, &len_value); len += decode_unsigned(&apdu[len], len_value, &decoded_value); value->priority = (uint8_t)decoded_value; } else { @@ -328,11 +330,12 @@ SubscribeCOV-Request ::= SEQUENCE { } */ -int cov_subscribe_encode_apdu(uint8_t *apdu, unsigned max_apdu_len, - uint8_t invoke_id, - BACNET_SUBSCRIBE_COV_DATA *data) +int cov_subscribe_encode_apdu(uint8_t *apdu, + unsigned max_apdu_len, + uint8_t invoke_id, + BACNET_SUBSCRIBE_COV_DATA *data) { - int len = 0; /* length of each encoding */ + int len = 0; /* length of each encoding */ int apdu_len = 0; /* total length of the apdu, return value */ if (apdu && data) { @@ -342,12 +345,12 @@ int cov_subscribe_encode_apdu(uint8_t *apdu, unsigned max_apdu_len, apdu[3] = SERVICE_CONFIRMED_SUBSCRIBE_COV; apdu_len = 4; /* tag 0 - subscriberProcessIdentifier */ - len = encode_context_unsigned(&apdu[apdu_len], 0, - data->subscriberProcessIdentifier); + len = encode_context_unsigned( + &apdu[apdu_len], 0, data->subscriberProcessIdentifier); apdu_len += len; /* tag 1 - monitoredObjectIdentifier */ - len = encode_context_object_id( - &apdu[apdu_len], 1, (int)data->monitoredObjectIdentifier.type, + len = encode_context_object_id(&apdu[apdu_len], 1, + (int)data->monitoredObjectIdentifier.type, data->monitoredObjectIdentifier.instance); apdu_len += len; /* @@ -357,8 +360,8 @@ int cov_subscribe_encode_apdu(uint8_t *apdu, unsigned max_apdu_len, */ if (!data->cancellationRequest) { /* tag 2 - issueConfirmedNotifications */ - len = encode_context_boolean(&apdu[apdu_len], 2, - data->issueConfirmedNotifications); + len = encode_context_boolean( + &apdu[apdu_len], 2, data->issueConfirmedNotifications); apdu_len += len; /* tag 3 - lifetime */ len = encode_context_unsigned(&apdu[apdu_len], 3, data->lifetime); @@ -370,20 +373,20 @@ int cov_subscribe_encode_apdu(uint8_t *apdu, unsigned max_apdu_len, } /* decode the service request only */ -int cov_subscribe_decode_service_request(uint8_t *apdu, unsigned apdu_len, - BACNET_SUBSCRIBE_COV_DATA *data) +int cov_subscribe_decode_service_request( + uint8_t *apdu, unsigned apdu_len, BACNET_SUBSCRIBE_COV_DATA *data) { int len = 0; /* return value */ uint8_t tag_number = 0; uint32_t len_value = 0; uint32_t decoded_value = 0; /* for decoding */ - uint16_t decoded_type = 0; /* for decoding */ + uint16_t decoded_type = 0; /* for decoding */ if (apdu_len && data) { /* tag 0 - subscriberProcessIdentifier */ if (decode_is_context_tag(&apdu[len], 0)) { - len += decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value); + len += decode_tag_number_and_value( + &apdu[len], &tag_number, &len_value); len += decode_unsigned(&apdu[len], len_value, &decoded_value); data->subscriberProcessIdentifier = decoded_value; } else { @@ -392,10 +395,10 @@ int cov_subscribe_decode_service_request(uint8_t *apdu, unsigned apdu_len, } /* tag 1 - monitoredObjectIdentifier */ if (decode_is_context_tag(&apdu[len], 1)) { - len += decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value); + len += decode_tag_number_and_value( + &apdu[len], &tag_number, &len_value); len += decode_object_id(&apdu[len], &decoded_type, - &data->monitoredObjectIdentifier.instance); + &data->monitoredObjectIdentifier.instance); data->monitoredObjectIdentifier.type = decoded_type; } else { data->error_code = ERROR_CODE_REJECT_INVALID_TAG; @@ -406,8 +409,8 @@ int cov_subscribe_decode_service_request(uint8_t *apdu, unsigned apdu_len, /* tag 2 - issueConfirmedNotifications - optional */ if (decode_is_context_tag(&apdu[len], 2)) { data->cancellationRequest = false; - len += decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value); + len += decode_tag_number_and_value( + &apdu[len], &tag_number, &len_value); data->issueConfirmedNotifications = decode_context_boolean(&apdu[len]); len += len_value; @@ -416,8 +419,8 @@ int cov_subscribe_decode_service_request(uint8_t *apdu, unsigned apdu_len, } /* tag 3 - lifetime - optional */ if (decode_is_context_tag(&apdu[len], 3)) { - len += decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value); + len += decode_tag_number_and_value( + &apdu[len], &tag_number, &len_value); len += decode_unsigned(&apdu[len], len_value, &decoded_value); data->lifetime = decoded_value; } else { @@ -450,11 +453,12 @@ BACnetPropertyReference ::= SEQUENCE { */ -int cov_subscribe_property_encode_apdu(uint8_t *apdu, unsigned max_apdu_len, - uint8_t invoke_id, - BACNET_SUBSCRIBE_COV_DATA *data) +int cov_subscribe_property_encode_apdu(uint8_t *apdu, + unsigned max_apdu_len, + uint8_t invoke_id, + BACNET_SUBSCRIBE_COV_DATA *data) { - int len = 0; /* length of each encoding */ + int len = 0; /* length of each encoding */ int apdu_len = 0; /* total length of the apdu, return value */ if (apdu && data) { @@ -464,18 +468,18 @@ int cov_subscribe_property_encode_apdu(uint8_t *apdu, unsigned max_apdu_len, apdu[3] = SERVICE_CONFIRMED_SUBSCRIBE_COV_PROPERTY; apdu_len = 4; /* tag 0 - subscriberProcessIdentifier */ - len = encode_context_unsigned(&apdu[apdu_len], 0, - data->subscriberProcessIdentifier); + len = encode_context_unsigned( + &apdu[apdu_len], 0, data->subscriberProcessIdentifier); apdu_len += len; /* tag 1 - monitoredObjectIdentifier */ - len = encode_context_object_id( - &apdu[apdu_len], 1, (int)data->monitoredObjectIdentifier.type, + len = encode_context_object_id(&apdu[apdu_len], 1, + (int)data->monitoredObjectIdentifier.type, data->monitoredObjectIdentifier.instance); apdu_len += len; if (!data->cancellationRequest) { /* tag 2 - issueConfirmedNotifications */ - len = encode_context_boolean(&apdu[apdu_len], 2, - data->issueConfirmedNotifications); + len = encode_context_boolean( + &apdu[apdu_len], 2, data->issueConfirmedNotifications); apdu_len += len; /* tag 3 - lifetime */ len = encode_context_unsigned(&apdu[apdu_len], 3, data->lifetime); @@ -513,14 +517,14 @@ int cov_subscribe_property_decode_service_request( uint8_t tag_number = 0; uint32_t len_value = 0; uint32_t decoded_value = 0; /* for decoding */ - uint16_t decoded_type = 0; /* for decoding */ - uint32_t property = 0; /* for decoding */ + uint16_t decoded_type = 0; /* for decoding */ + uint32_t property = 0; /* for decoding */ if (apdu_len && data) { /* tag 0 - subscriberProcessIdentifier */ if (decode_is_context_tag(&apdu[len], 0)) { - len += decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value); + len += decode_tag_number_and_value( + &apdu[len], &tag_number, &len_value); len += decode_unsigned(&apdu[len], len_value, &decoded_value); data->subscriberProcessIdentifier = decoded_value; } else { @@ -529,10 +533,10 @@ int cov_subscribe_property_decode_service_request( } /* tag 1 - monitoredObjectIdentifier */ if (decode_is_context_tag(&apdu[len], 1)) { - len += decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value); + len += decode_tag_number_and_value( + &apdu[len], &tag_number, &len_value); len += decode_object_id(&apdu[len], &decoded_type, - &data->monitoredObjectIdentifier.instance); + &data->monitoredObjectIdentifier.instance); data->monitoredObjectIdentifier.type = decoded_type; } else { data->error_code = ERROR_CODE_REJECT_INVALID_TAG; @@ -541,8 +545,8 @@ int cov_subscribe_property_decode_service_request( /* tag 2 - issueConfirmedNotifications - optional */ if (decode_is_context_tag(&apdu[len], 2)) { data->cancellationRequest = false; - len += decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value); + len += decode_tag_number_and_value( + &apdu[len], &tag_number, &len_value); data->issueConfirmedNotifications = decode_context_boolean(&apdu[len]); len++; @@ -551,8 +555,8 @@ int cov_subscribe_property_decode_service_request( } /* tag 3 - lifetime - optional */ if (decode_is_context_tag(&apdu[len], 3)) { - len += decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value); + len += decode_tag_number_and_value( + &apdu[len], &tag_number, &len_value); len += decode_unsigned(&apdu[len], len_value, &decoded_value); data->lifetime = decoded_value; } else { @@ -567,8 +571,8 @@ int cov_subscribe_property_decode_service_request( len++; /* the propertyIdentifier is tag 0 */ if (decode_is_context_tag(&apdu[len], 0)) { - len += decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value); + len += decode_tag_number_and_value( + &apdu[len], &tag_number, &len_value); len += decode_enumerated(&apdu[len], len_value, &property); data->monitoredProperty.propertyIdentifier = (BACNET_PROPERTY_ID)property; @@ -578,8 +582,8 @@ int cov_subscribe_property_decode_service_request( } /* the optional array index is tag 1 */ if (decode_is_context_tag(&apdu[len], 1)) { - len += decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value); + len += decode_tag_number_and_value( + &apdu[len], &tag_number, &len_value); len += decode_unsigned(&apdu[len], len_value, &decoded_value); data->monitoredProperty.propertyArrayIndex = decoded_value; } else { @@ -595,8 +599,8 @@ int cov_subscribe_property_decode_service_request( /* tag 5 - covIncrement - optional */ if (decode_is_context_tag(&apdu[len], 5)) { data->covIncrementPresent = true; - len += decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value); + len += decode_tag_number_and_value( + &apdu[len], &tag_number, &len_value); len += decode_real(&apdu[len], &data->covIncrement); } else { data->covIncrementPresent = false; @@ -616,8 +620,8 @@ int cov_subscribe_property_decode_service_request( * a buffer or array. * @param count - number of BACNET_PROPERTY_VALUE elements */ -void cov_data_value_list_link(BACNET_COV_DATA *data, - BACNET_PROPERTY_VALUE *value_list, size_t count) +void cov_data_value_list_link( + BACNET_COV_DATA *data, BACNET_PROPERTY_VALUE *value_list, size_t count) { BACNET_PROPERTY_VALUE *current_value_list = NULL; @@ -640,10 +644,10 @@ void cov_data_value_list_link(BACNET_COV_DATA *data, #include #include #include "ctest.h" -#include "bacapp.h" +#include "bacnet/bacapp.h" -int ccov_notify_decode_apdu(uint8_t *apdu, unsigned apdu_len, - uint8_t *invoke_id, BACNET_COV_DATA *data) +int ccov_notify_decode_apdu( + uint8_t *apdu, unsigned apdu_len, uint8_t *invoke_id, BACNET_COV_DATA *data) { int len = 0; unsigned offset = 0; @@ -662,15 +666,15 @@ int ccov_notify_decode_apdu(uint8_t *apdu, unsigned apdu_len, /* optional limits - must be used as a pair */ if (apdu_len > offset) { - len = cov_notify_decode_service_request(&apdu[offset], - apdu_len - offset, data); + len = cov_notify_decode_service_request( + &apdu[offset], apdu_len - offset, data); } return len; } -int ucov_notify_decode_apdu(uint8_t *apdu, unsigned apdu_len, - BACNET_COV_DATA *data) +int ucov_notify_decode_apdu( + uint8_t *apdu, unsigned apdu_len, BACNET_COV_DATA *data) { int len = 0; unsigned offset = 0; @@ -685,16 +689,17 @@ int ucov_notify_decode_apdu(uint8_t *apdu, unsigned apdu_len, /* optional limits - must be used as a pair */ offset = 2; if (apdu_len > offset) { - len = cov_notify_decode_service_request(&apdu[offset], - apdu_len - offset, data); + len = cov_notify_decode_service_request( + &apdu[offset], apdu_len - offset, data); } return len; } -int cov_subscribe_decode_apdu(uint8_t *apdu, unsigned apdu_len, - uint8_t *invoke_id, - BACNET_SUBSCRIBE_COV_DATA *data) +int cov_subscribe_decode_apdu(uint8_t *apdu, + unsigned apdu_len, + uint8_t *invoke_id, + BACNET_SUBSCRIBE_COV_DATA *data) { int len = 0; unsigned offset = 0; @@ -712,16 +717,17 @@ int cov_subscribe_decode_apdu(uint8_t *apdu, unsigned apdu_len, /* optional limits - must be used as a pair */ if (apdu_len > offset) { - len = cov_subscribe_decode_service_request(&apdu[offset], - apdu_len - offset, data); + len = cov_subscribe_decode_service_request( + &apdu[offset], apdu_len - offset, data); } return len; } -int cov_subscribe_property_decode_apdu(uint8_t *apdu, unsigned apdu_len, - uint8_t *invoke_id, - BACNET_SUBSCRIBE_COV_DATA *data) +int cov_subscribe_property_decode_apdu(uint8_t *apdu, + unsigned apdu_len, + uint8_t *invoke_id, + BACNET_SUBSCRIBE_COV_DATA *data) { int len = 0; unsigned offset = 0; @@ -747,20 +753,24 @@ int cov_subscribe_property_decode_apdu(uint8_t *apdu, unsigned apdu_len, } /* dummy function stubs */ -void testCOVNotifyData(Test *pTest, BACNET_COV_DATA *data, - BACNET_COV_DATA *test_data) +void testCOVNotifyData( + Test *pTest, BACNET_COV_DATA *data, BACNET_COV_DATA *test_data) { BACNET_PROPERTY_VALUE *value = NULL; BACNET_PROPERTY_VALUE *test_value = NULL; - ct_test(pTest, test_data->subscriberProcessIdentifier == - data->subscriberProcessIdentifier); - ct_test(pTest, test_data->initiatingDeviceIdentifier == - data->initiatingDeviceIdentifier); - ct_test(pTest, test_data->monitoredObjectIdentifier.type == - data->monitoredObjectIdentifier.type); - ct_test(pTest, test_data->monitoredObjectIdentifier.instance == - data->monitoredObjectIdentifier.instance); + ct_test(pTest, + test_data->subscriberProcessIdentifier == + data->subscriberProcessIdentifier); + ct_test(pTest, + test_data->initiatingDeviceIdentifier == + data->initiatingDeviceIdentifier); + ct_test(pTest, + test_data->monitoredObjectIdentifier.type == + data->monitoredObjectIdentifier.type); + ct_test(pTest, + test_data->monitoredObjectIdentifier.instance == + data->monitoredObjectIdentifier.instance); ct_test(pTest, test_data->timeRemaining == data->timeRemaining); /* test the listOfValues in some clever manner */ value = data->listOfValues; @@ -768,13 +778,13 @@ void testCOVNotifyData(Test *pTest, BACNET_COV_DATA *data, while (value) { ct_test(pTest, test_value); if (test_value) { - ct_test(pTest, test_value->propertyIdentifier == - value->propertyIdentifier); - ct_test(pTest, test_value->propertyArrayIndex == - value->propertyArrayIndex); - ct_test(pTest, test_value->priority == value->priority); ct_test(pTest, - bacapp_same_value(&test_value->value, &value->value)); + test_value->propertyIdentifier == value->propertyIdentifier); + ct_test(pTest, + test_value->propertyArrayIndex == value->propertyArrayIndex); + ct_test(pTest, test_value->priority == value->priority); + ct_test( + pTest, bacapp_same_value(&test_value->value, &value->value)); test_value = test_value->next; } value = value->next; @@ -783,11 +793,11 @@ void testCOVNotifyData(Test *pTest, BACNET_COV_DATA *data, void testUCOVNotifyData(Test *pTest, BACNET_COV_DATA *data) { - uint8_t apdu[480] = {0}; + uint8_t apdu[480] = { 0 }; int len = 0; int apdu_len = 0; BACNET_COV_DATA test_data; - BACNET_PROPERTY_VALUE value_list[5] = {{0}}; + BACNET_PROPERTY_VALUE value_list[5] = { { 0 } }; len = ucov_notify_encode_apdu(&apdu[0], sizeof(apdu), data); ct_test(pTest, len > 0); @@ -801,11 +811,11 @@ void testUCOVNotifyData(Test *pTest, BACNET_COV_DATA *data) void testCCOVNotifyData(Test *pTest, uint8_t invoke_id, BACNET_COV_DATA *data) { - uint8_t apdu[480] = {0}; + uint8_t apdu[480] = { 0 }; int len = 0; int apdu_len = 0; BACNET_COV_DATA test_data; - BACNET_PROPERTY_VALUE value_list[2] = {{0}}; + BACNET_PROPERTY_VALUE value_list[2] = { { 0 } }; uint8_t test_invoke_id = 0; len = ccov_notify_encode_apdu(&apdu[0], sizeof(apdu), invoke_id, data); @@ -813,8 +823,8 @@ void testCCOVNotifyData(Test *pTest, uint8_t invoke_id, BACNET_COV_DATA *data) apdu_len = len; cov_data_value_list_link(&test_data, &value_list[0], 2); - len = ccov_notify_decode_apdu(&apdu[0], apdu_len, &test_invoke_id, - &test_data); + len = ccov_notify_decode_apdu( + &apdu[0], apdu_len, &test_invoke_id, &test_data); ct_test(pTest, len > 0); ct_test(pTest, test_invoke_id == invoke_id); testCOVNotifyData(pTest, data, &test_data); @@ -824,7 +834,7 @@ void testCOVNotify(Test *pTest) { uint8_t invoke_id = 12; BACNET_COV_DATA data; - BACNET_PROPERTY_VALUE value_list[2] = {{0}}; + BACNET_PROPERTY_VALUE value_list[2] = { { 0 } }; data.subscriberProcessIdentifier = 1; data.initiatingDeviceIdentifier = 123; @@ -836,58 +846,66 @@ void testCOVNotify(Test *pTest) /* first value */ value_list[0].propertyIdentifier = PROP_PRESENT_VALUE; value_list[0].propertyArrayIndex = BACNET_ARRAY_ALL; - bacapp_parse_application_data(BACNET_APPLICATION_TAG_REAL, "21.0", - &value_list[0].value); + bacapp_parse_application_data( + BACNET_APPLICATION_TAG_REAL, "21.0", &value_list[0].value); value_list[0].priority = 0; /* second value */ value_list[1].propertyIdentifier = PROP_STATUS_FLAGS; value_list[1].propertyArrayIndex = BACNET_ARRAY_ALL; - bacapp_parse_application_data(BACNET_APPLICATION_TAG_BIT_STRING, "0000", - &value_list[1].value); + bacapp_parse_application_data( + BACNET_APPLICATION_TAG_BIT_STRING, "0000", &value_list[1].value); value_list[1].priority = 0; testUCOVNotifyData(pTest, &data); testCCOVNotifyData(pTest, invoke_id, &data); } -void testCOVSubscribeData(Test *pTest, BACNET_SUBSCRIBE_COV_DATA *data, - BACNET_SUBSCRIBE_COV_DATA *test_data) +void testCOVSubscribeData(Test *pTest, + BACNET_SUBSCRIBE_COV_DATA *data, + BACNET_SUBSCRIBE_COV_DATA *test_data) { - ct_test(pTest, test_data->subscriberProcessIdentifier == - data->subscriberProcessIdentifier); - ct_test(pTest, test_data->monitoredObjectIdentifier.type == - data->monitoredObjectIdentifier.type); - ct_test(pTest, test_data->monitoredObjectIdentifier.instance == - data->monitoredObjectIdentifier.instance); + ct_test(pTest, + test_data->subscriberProcessIdentifier == + data->subscriberProcessIdentifier); + ct_test(pTest, + test_data->monitoredObjectIdentifier.type == + data->monitoredObjectIdentifier.type); + ct_test(pTest, + test_data->monitoredObjectIdentifier.instance == + data->monitoredObjectIdentifier.instance); ct_test(pTest, test_data->cancellationRequest == data->cancellationRequest); if (test_data->cancellationRequest != data->cancellationRequest) { printf("cancellation request failed!\n"); } if (!test_data->cancellationRequest) { - ct_test(pTest, test_data->issueConfirmedNotifications == - data->issueConfirmedNotifications); + ct_test(pTest, + test_data->issueConfirmedNotifications == + data->issueConfirmedNotifications); ct_test(pTest, test_data->lifetime == data->lifetime); } } -void testCOVSubscribePropertyData(Test *pTest, BACNET_SUBSCRIBE_COV_DATA *data, - BACNET_SUBSCRIBE_COV_DATA *test_data) +void testCOVSubscribePropertyData(Test *pTest, + BACNET_SUBSCRIBE_COV_DATA *data, + BACNET_SUBSCRIBE_COV_DATA *test_data) { testCOVSubscribeData(pTest, data, test_data); - ct_test(pTest, test_data->monitoredProperty.propertyIdentifier == - data->monitoredProperty.propertyIdentifier); - ct_test(pTest, test_data->monitoredProperty.propertyArrayIndex == - data->monitoredProperty.propertyArrayIndex); + ct_test(pTest, + test_data->monitoredProperty.propertyIdentifier == + data->monitoredProperty.propertyIdentifier); + ct_test(pTest, + test_data->monitoredProperty.propertyArrayIndex == + data->monitoredProperty.propertyArrayIndex); ct_test(pTest, test_data->covIncrementPresent == data->covIncrementPresent); if (test_data->covIncrementPresent) { ct_test(pTest, test_data->covIncrement == data->covIncrement); } } -void testCOVSubscribeEncoding(Test *pTest, uint8_t invoke_id, - BACNET_SUBSCRIBE_COV_DATA *data) +void testCOVSubscribeEncoding( + Test *pTest, uint8_t invoke_id, BACNET_SUBSCRIBE_COV_DATA *data) { - uint8_t apdu[480] = {0}; + uint8_t apdu[480] = { 0 }; int len = 0; int apdu_len = 0; BACNET_SUBSCRIBE_COV_DATA test_data; @@ -897,29 +915,29 @@ void testCOVSubscribeEncoding(Test *pTest, uint8_t invoke_id, ct_test(pTest, len != 0); apdu_len = len; - len = cov_subscribe_decode_apdu(&apdu[0], apdu_len, &test_invoke_id, - &test_data); + len = cov_subscribe_decode_apdu( + &apdu[0], apdu_len, &test_invoke_id, &test_data); ct_test(pTest, len > 0); ct_test(pTest, test_invoke_id == invoke_id); testCOVSubscribeData(pTest, data, &test_data); } -void testCOVSubscribePropertyEncoding(Test *pTest, uint8_t invoke_id, - BACNET_SUBSCRIBE_COV_DATA *data) +void testCOVSubscribePropertyEncoding( + Test *pTest, uint8_t invoke_id, BACNET_SUBSCRIBE_COV_DATA *data) { - uint8_t apdu[480] = {0}; + uint8_t apdu[480] = { 0 }; int len = 0; int apdu_len = 0; BACNET_SUBSCRIBE_COV_DATA test_data; uint8_t test_invoke_id = 0; - len = cov_subscribe_property_encode_apdu(&apdu[0], sizeof(apdu), invoke_id, - data); + len = cov_subscribe_property_encode_apdu( + &apdu[0], sizeof(apdu), invoke_id, data); ct_test(pTest, len != 0); apdu_len = len; - len = cov_subscribe_property_decode_apdu(&apdu[0], apdu_len, - &test_invoke_id, &test_data); + len = cov_subscribe_property_decode_apdu( + &apdu[0], apdu_len, &test_invoke_id, &test_data); ct_test(pTest, len > 0); ct_test(pTest, test_invoke_id == invoke_id); testCOVSubscribePropertyData(pTest, data, &test_data); diff --git a/include/cov.h b/src/bacnet/cov.h similarity index 99% rename from include/cov.h rename to src/bacnet/cov.h index 6a9b6fbe..8f3e39ae 100644 --- a/include/cov.h +++ b/src/bacnet/cov.h @@ -26,7 +26,7 @@ #include #include -#include "bacapp.h" +#include "bacnet/bacapp.h" typedef struct BACnet_COV_Data { uint32_t subscriberProcessIdentifier; diff --git a/src/credential_authentication_factor.c b/src/bacnet/credential_authentication_factor.c similarity index 84% rename from src/credential_authentication_factor.c rename to src/bacnet/credential_authentication_factor.c index 0a9b3e7b..baae8150 100644 --- a/src/credential_authentication_factor.c +++ b/src/bacnet/credential_authentication_factor.c @@ -22,34 +22,36 @@ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * *********************************************************************/ - -#include "credential_authentication_factor.h" -#include "bacdcode.h" +#include +#include "bacnet/credential_authentication_factor.h" +#include "bacnet/bacdcode.h" int bacapp_encode_credential_authentication_factor( - uint8_t* apdu, BACNET_CREDENTIAL_AUTHENTICATION_FACTOR* caf) + uint8_t *apdu, BACNET_CREDENTIAL_AUTHENTICATION_FACTOR *caf) { int len; int apdu_len = 0; len = encode_context_enumerated(&apdu[apdu_len], 0, caf->disable); - if (len < 0) + if (len < 0) { return -1; - else + } else { apdu_len += len; + } len = bacapp_encode_context_authentication_factor( &apdu[apdu_len], 1, &caf->authentication_factor); - if (len < 0) + if (len < 0) { return -1; - else + } else { apdu_len += len; + } return apdu_len; } int bacapp_encode_context_credential_authentication_factor( - uint8_t* apdu, uint8_t tag, BACNET_CREDENTIAL_AUTHENTICATION_FACTOR* caf) + uint8_t *apdu, uint8_t tag, BACNET_CREDENTIAL_AUTHENTICATION_FACTOR *caf) { int len; int apdu_len = 0; @@ -67,35 +69,39 @@ int bacapp_encode_context_credential_authentication_factor( } int bacapp_decode_credential_authentication_factor( - uint8_t* apdu, BACNET_CREDENTIAL_AUTHENTICATION_FACTOR* caf) + uint8_t *apdu, BACNET_CREDENTIAL_AUTHENTICATION_FACTOR *caf) { int len; int apdu_len = 0; if (decode_is_context_tag(&apdu[apdu_len], 0)) { len = decode_context_enumerated(&apdu[apdu_len], 0, &caf->disable); - if (len < 0) + if (len < 0) { return -1; - else + } else { apdu_len += len; - } else + } + } else { return -1; + } if (decode_is_context_tag(&apdu[apdu_len], 1)) { len = bacapp_decode_context_authentication_factor( &apdu[apdu_len], 1, &caf->authentication_factor); - if (len < 0) + if (len < 0) { return -1; - else + } else { apdu_len += len; - } else + } + } else { return -1; + } return apdu_len; } int bacapp_decode_context_credential_authentication_factor( - uint8_t* apdu, uint8_t tag, BACNET_CREDENTIAL_AUTHENTICATION_FACTOR* caf) + uint8_t *apdu, uint8_t tag, BACNET_CREDENTIAL_AUTHENTICATION_FACTOR *caf) { int len = 0; int section_length; diff --git a/include/credential_authentication_factor.h b/src/bacnet/credential_authentication_factor.h similarity index 96% rename from include/credential_authentication_factor.h rename to src/bacnet/credential_authentication_factor.h index 16f04440..21b54951 100644 --- a/include/credential_authentication_factor.h +++ b/src/bacnet/credential_authentication_factor.h @@ -28,9 +28,9 @@ #include #include -#include "bacdef.h" -#include "bacapp.h" -#include "authentication_factor.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacapp.h" +#include "bacnet/authentication_factor.h" typedef struct { BACNET_ACCESS_AUTHENTICATION_FACTOR_DISABLE disable; diff --git a/include/arcnet.h b/src/bacnet/datalink/arcnet.h similarity index 98% rename from include/arcnet.h rename to src/bacnet/datalink/arcnet.h index 20da6641..337bf633 100644 --- a/include/arcnet.h +++ b/src/bacnet/datalink/arcnet.h @@ -27,8 +27,8 @@ #include #include #include -#include "bacdef.h" -#include "npdu.h" +#include "bacnet/bacdef.h" +#include "bacnet/npdu.h" /* specific defines for ARCNET */ #define MAX_HEADER (1+1+2+2+1+1+1+1) diff --git a/src/bacsec.c b/src/bacnet/datalink/bacsec.c similarity index 82% rename from src/bacsec.c rename to src/bacnet/datalink/bacsec.c index d8565d6b..c617ca2c 100644 --- a/src/bacsec.c +++ b/src/bacnet/datalink/bacsec.c @@ -25,8 +25,8 @@ #include #include #include -#include "bacdcode.h" -#include "bacsec.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacsec.h" BACNET_KEY_IDENTIFIER_ALGORITHM key_algorithm(uint16_t id) { @@ -38,8 +38,8 @@ BACNET_KEY_IDENTIFIER_KEY_NUMBER key_number(uint16_t id) return (BACNET_KEY_IDENTIFIER_KEY_NUMBER)(id & 0xFF); } -int encode_security_wrapper(int bytes_before, uint8_t* apdu, - BACNET_SECURITY_WRAPPER* wrapper) +int encode_security_wrapper( + int bytes_before, uint8_t *apdu, BACNET_SECURITY_WRAPPER *wrapper) { int curr = 0; int enc_begin = 0; @@ -114,17 +114,17 @@ int encode_security_wrapper(int bytes_before, uint8_t* apdu, apdu[curr++] = wrapper->user_role; if ((wrapper->authentication_mechanism >= 1) && (wrapper->authentication_mechanism <= 199)) { - curr += encode_unsigned16(&apdu[curr], - wrapper->authentication_data_length + 5); + curr += encode_unsigned16( + &apdu[curr], wrapper->authentication_data_length + 5); memcpy(&apdu[curr], wrapper->authentication_data, - wrapper->authentication_data_length); + wrapper->authentication_data_length); curr += wrapper->authentication_data_length; } else if (wrapper->authentication_mechanism >= 200) { - curr += encode_unsigned16(&apdu[curr], - wrapper->authentication_data_length + 7); + curr += encode_unsigned16( + &apdu[curr], wrapper->authentication_data_length + 7); curr += encode_unsigned16(&apdu[curr], wrapper->vendor_id); memcpy(&apdu[curr], wrapper->authentication_data, - wrapper->authentication_data_length); + wrapper->authentication_data_length); curr += wrapper->authentication_data_length; } } @@ -132,14 +132,14 @@ int encode_security_wrapper(int bytes_before, uint8_t* apdu, curr += wrapper->service_data_len; /* signature calculation */ key_sign_msg(&key, &apdu[-bytes_before], (uint32_t)(bytes_before + curr), - wrapper->signature); + wrapper->signature); /* padding and encryption */ if (wrapper->encrypted_flag) { /* set encryption flag, signing is done */ apdu[0] |= 1 << 6; /* handle padding */ - key_set_padding(&key, curr - enc_begin, &wrapper->padding_len, - wrapper->padding); + key_set_padding( + &key, curr - enc_begin, &wrapper->padding_len, wrapper->padding); if (wrapper->padding_len > 2) { memcpy(&apdu[curr], wrapper->padding, wrapper->padding_len - 2); curr += wrapper->padding_len - 2; @@ -147,7 +147,7 @@ int encode_security_wrapper(int bytes_before, uint8_t* apdu, curr += encode_unsigned16(&apdu[curr], wrapper->padding_len); /* encryption */ key_encrypt_msg(&key, &apdu[enc_begin], (uint32_t)(curr - enc_begin), - wrapper->signature); + wrapper->signature); } memcpy(&apdu[curr], wrapper->signature, SIGNATURE_LEN); curr += SIGNATURE_LEN; @@ -155,7 +155,7 @@ int encode_security_wrapper(int bytes_before, uint8_t* apdu, return curr; } -int encode_challenge_request(uint8_t* apdu, BACNET_CHALLENGE_REQUEST* bc_req) +int encode_challenge_request(uint8_t *apdu, BACNET_CHALLENGE_REQUEST *bc_req) { int curr = 0; @@ -166,7 +166,7 @@ int encode_challenge_request(uint8_t* apdu, BACNET_CHALLENGE_REQUEST* bc_req) return curr; } -int encode_security_payload(uint8_t* apdu, BACNET_SECURITY_PAYLOAD* payload) +int encode_security_payload(uint8_t *apdu, BACNET_SECURITY_PAYLOAD *payload) { encode_unsigned16(&apdu[0], payload->payload_length); memcpy(&apdu[2], payload->payload, payload->payload_length); @@ -174,7 +174,7 @@ int encode_security_payload(uint8_t* apdu, BACNET_SECURITY_PAYLOAD* payload) return (int)(2 + payload->payload_length); } -int encode_security_response(uint8_t* apdu, BACNET_SECURITY_RESPONSE* resp) +int encode_security_response(uint8_t *apdu, BACNET_SECURITY_RESPONSE *resp) { int curr = 0; int i; @@ -188,27 +188,26 @@ int encode_security_response(uint8_t* apdu, BACNET_SECURITY_RESPONSE* resp) &apdu[curr], resp->response.bad_timestamp.expected_timestamp); break; case SEC_RESP_CANNOT_USE_KEY: - curr += encode_unsigned16(&apdu[curr], - resp->response.cannot_use_key.key); + curr += encode_unsigned16( + &apdu[curr], resp->response.cannot_use_key.key); break; case SEC_RESP_INCORRECT_KEY: apdu[curr++] = resp->response.incorrect_key.number_of_keys; for (i = 0; i < (int)resp->response.incorrect_key.number_of_keys; i++) { - curr += encode_unsigned16(&apdu[curr], - resp->response.incorrect_key.keys[i]); + curr += encode_unsigned16( + &apdu[curr], resp->response.incorrect_key.keys[i]); } break; case SEC_RESP_UNKNOWN_AUTHENTICATION_TYPE: apdu[curr++] = resp->response.unknown_authentication_type .original_authentication_type; - curr += encode_unsigned16( - &apdu[curr], + curr += encode_unsigned16(&apdu[curr], resp->response.unknown_authentication_type.vendor_id); break; case SEC_RESP_UNKNOWN_KEY: - curr += encode_unsigned16(&apdu[curr], - resp->response.unknown_key.original_key); + curr += encode_unsigned16( + &apdu[curr], resp->response.unknown_key.original_key); break; case SEC_RESP_UNKNOWN_KEY_REVISION: apdu[curr++] = @@ -218,8 +217,8 @@ int encode_security_response(uint8_t* apdu, BACNET_SECURITY_RESPONSE* resp) apdu[curr++] = resp->response.too_many_keys.max_num_of_keys; break; case SEC_RESP_INVALID_KEY_DATA: - curr += encode_unsigned16(&apdu[curr], - resp->response.invalid_key_data.key); + curr += encode_unsigned16( + &apdu[curr], resp->response.invalid_key_data.key); break; case SEC_RESP_SUCCESS: case SEC_RESP_ACCESS_DENIED: @@ -247,7 +246,7 @@ int encode_security_response(uint8_t* apdu, BACNET_SECURITY_RESPONSE* resp) return curr; } -int encode_request_key_update(uint8_t* apdu, BACNET_REQUEST_KEY_UPDATE* req) +int encode_request_key_update(uint8_t *apdu, BACNET_REQUEST_KEY_UPDATE *req) { int curr = 0; @@ -262,7 +261,7 @@ int encode_request_key_update(uint8_t* apdu, BACNET_REQUEST_KEY_UPDATE* req) return curr; } -int encode_key_entry(uint8_t* apdu, BACNET_KEY_ENTRY* entry) +int encode_key_entry(uint8_t *apdu, BACNET_KEY_ENTRY *entry) { int curr = 0; @@ -274,7 +273,7 @@ int encode_key_entry(uint8_t* apdu, BACNET_KEY_ENTRY* entry) return curr; } -int encode_update_key_set(uint8_t* apdu, BACNET_UPDATE_KEY_SET* key_set) +int encode_update_key_set(uint8_t *apdu, BACNET_UPDATE_KEY_SET *key_set) { int curr = 0; int i, res; @@ -344,8 +343,8 @@ int encode_update_key_set(uint8_t* apdu, BACNET_UPDATE_KEY_SET* key_set) return curr; } -int encode_update_distribution_key(uint8_t* apdu, - BACNET_UPDATE_DISTRIBUTION_KEY* dist_key) +int encode_update_distribution_key( + uint8_t *apdu, BACNET_UPDATE_DISTRIBUTION_KEY *dist_key) { int curr = 0; int res; @@ -359,26 +358,27 @@ int encode_update_distribution_key(uint8_t* apdu, return curr + res; } -int encode_request_master_key(uint8_t* apdu, - BACNET_REQUEST_MASTER_KEY* req_master_key) +int encode_request_master_key( + uint8_t *apdu, BACNET_REQUEST_MASTER_KEY *req_master_key) { int curr = 0; apdu[curr++] = req_master_key->no_supported_algorithms; memcpy(&apdu[curr], req_master_key->es_algorithms, - req_master_key->no_supported_algorithms); + req_master_key->no_supported_algorithms); return (int)(curr + req_master_key->no_supported_algorithms); } -int encode_set_master_key(uint8_t* apdu, BACNET_SET_MASTER_KEY* set_master_key) +int encode_set_master_key(uint8_t *apdu, BACNET_SET_MASTER_KEY *set_master_key) { return encode_key_entry(apdu, &set_master_key->key); } -int decode_security_wrapper_safe(int bytes_before, uint8_t* apdu, - uint32_t apdu_len_remaining, - BACNET_SECURITY_WRAPPER* wrapper) +int decode_security_wrapper_safe(int bytes_before, + uint8_t *apdu, + uint32_t apdu_len_remaining, + BACNET_SECURITY_WRAPPER *wrapper) { int curr = 0; int enc_begin = 0; @@ -427,14 +427,13 @@ int decode_security_wrapper_safe(int bytes_before, uint8_t* apdu, memcpy(wrapper->signature, &apdu[real_len], SIGNATURE_LEN); if (wrapper->encrypted_flag) { if (!key_decrypt_msg(&key, &apdu[enc_begin], - (uint32_t)(real_len - enc_begin), - wrapper->signature)) { + (uint32_t)(real_len - enc_begin), wrapper->signature)) { return -SEC_RESP_MALFORMED_MESSAGE; } curr += decode_unsigned16(&apdu[real_len - 2], &wrapper->padding_len); real_len -= wrapper->padding_len; memcpy(wrapper->padding, &apdu[wrapper->padding_len], - wrapper->padding_len - 2); + wrapper->padding_len - 2); } /* destination device instance */ curr += @@ -457,19 +456,19 @@ int decode_security_wrapper_safe(int bytes_before, uint8_t* apdu, wrapper->user_role = apdu[curr++]; if ((wrapper->authentication_mechanism >= 1) && (wrapper->authentication_mechanism <= 199)) { - curr += decode_unsigned16(&apdu[curr], - &wrapper->authentication_data_length); + curr += decode_unsigned16( + &apdu[curr], &wrapper->authentication_data_length); wrapper->authentication_data_length -= 5; memcpy(wrapper->authentication_data, &apdu[curr], - wrapper->authentication_data_length); + wrapper->authentication_data_length); curr += wrapper->authentication_data_length; } else if (wrapper->authentication_mechanism >= 200) { - curr += decode_unsigned16(&apdu[curr], - &wrapper->authentication_data_length); + curr += decode_unsigned16( + &apdu[curr], &wrapper->authentication_data_length); wrapper->authentication_data_length -= 7; curr += decode_unsigned16(&apdu[curr], &wrapper->vendor_id); memcpy(wrapper->authentication_data, &apdu[curr], - wrapper->authentication_data_length); + wrapper->authentication_data_length); curr += wrapper->authentication_data_length; } } @@ -477,16 +476,16 @@ int decode_security_wrapper_safe(int bytes_before, uint8_t* apdu, memcpy(wrapper->service_data, &apdu[curr], wrapper->service_data_len); curr += wrapper->service_data_len; if (!key_verify_sign_msg(&key, &apdu[-bytes_before], - (uint32_t)(bytes_before + real_len), - wrapper->signature)) { + (uint32_t)(bytes_before + real_len), wrapper->signature)) { return -SEC_RESP_BAD_SIGNATURE; } return curr; } -int decode_challenge_request_safe(uint8_t* apdu, uint32_t apdu_len_remaining, - BACNET_CHALLENGE_REQUEST* bc_req) +int decode_challenge_request_safe(uint8_t *apdu, + uint32_t apdu_len_remaining, + BACNET_CHALLENGE_REQUEST *bc_req) { int curr = 0; @@ -500,8 +499,9 @@ int decode_challenge_request_safe(uint8_t* apdu, uint32_t apdu_len_remaining, return curr; /* always 9! */ } -int decode_security_payload_safe(uint8_t* apdu, uint32_t apdu_len_remaining, - BACNET_SECURITY_PAYLOAD* payload) +int decode_security_payload_safe(uint8_t *apdu, + uint32_t apdu_len_remaining, + BACNET_SECURITY_PAYLOAD *payload) { if (apdu_len_remaining < 2) { return -1; @@ -514,8 +514,8 @@ int decode_security_payload_safe(uint8_t* apdu, uint32_t apdu_len_remaining, return (int)(2 + payload->payload_length); } -int decode_security_response_safe(uint8_t* apdu, uint32_t apdu_len_remaining, - BACNET_SECURITY_RESPONSE* resp) +int decode_security_response_safe( + uint8_t *apdu, uint32_t apdu_len_remaining, BACNET_SECURITY_RESPONSE *resp) { int curr = 0; int i; @@ -538,8 +538,8 @@ int decode_security_response_safe(uint8_t* apdu, uint32_t apdu_len_remaining, if (apdu_len_remaining < 11) { return -1; } - curr += decode_unsigned16(&apdu[curr], - &resp->response.cannot_use_key.key); + curr += decode_unsigned16( + &apdu[curr], &resp->response.cannot_use_key.key); break; case SEC_RESP_INCORRECT_KEY: if (apdu_len_remaining < 10) { @@ -562,8 +562,7 @@ int decode_security_response_safe(uint8_t* apdu, uint32_t apdu_len_remaining, } resp->response.unknown_authentication_type .original_authentication_type = apdu[curr++]; - curr += decode_unsigned16( - &apdu[curr], + curr += decode_unsigned16(&apdu[curr], &resp->response.unknown_authentication_type.vendor_id); if (resp->response.unknown_authentication_type .original_authentication_type < 200 && @@ -575,8 +574,8 @@ int decode_security_response_safe(uint8_t* apdu, uint32_t apdu_len_remaining, if (apdu_len_remaining < 11) { return -1; } - curr += decode_unsigned16(&apdu[curr], - &resp->response.unknown_key.original_key); + curr += decode_unsigned16( + &apdu[curr], &resp->response.unknown_key.original_key); break; case SEC_RESP_UNKNOWN_KEY_REVISION: if (apdu_len_remaining < 10) { @@ -595,8 +594,8 @@ int decode_security_response_safe(uint8_t* apdu, uint32_t apdu_len_remaining, if (apdu_len_remaining < 11) { return -1; } - curr += decode_unsigned16(&apdu[curr], - &resp->response.invalid_key_data.key); + curr += decode_unsigned16( + &apdu[curr], &resp->response.invalid_key_data.key); break; case SEC_RESP_SUCCESS: case SEC_RESP_ACCESS_DENIED: @@ -623,8 +622,8 @@ int decode_security_response_safe(uint8_t* apdu, uint32_t apdu_len_remaining, return curr; } -int decode_request_key_update_safe(uint8_t* apdu, uint32_t apdu_len_remaining, - BACNET_REQUEST_KEY_UPDATE* req) +int decode_request_key_update_safe( + uint8_t *apdu, uint32_t apdu_len_remaining, BACNET_REQUEST_KEY_UPDATE *req) { int curr = 0; @@ -642,8 +641,8 @@ int decode_request_key_update_safe(uint8_t* apdu, uint32_t apdu_len_remaining, return curr; } -int decode_key_entry_safe(uint8_t* apdu, uint32_t apdu_len_remaining, - BACNET_KEY_ENTRY* entry) +int decode_key_entry_safe( + uint8_t *apdu, uint32_t apdu_len_remaining, BACNET_KEY_ENTRY *entry) { int curr = 0; @@ -662,8 +661,8 @@ int decode_key_entry_safe(uint8_t* apdu, uint32_t apdu_len_remaining, return curr; } -int decode_update_key_set_safe(uint8_t* apdu, uint32_t apdu_len_remaining, - BACNET_UPDATE_KEY_SET* key_set) +int decode_update_key_set_safe( + uint8_t *apdu, uint32_t apdu_len_remaining, BACNET_UPDATE_KEY_SET *key_set) { int curr = 0; int i, res; @@ -716,7 +715,7 @@ int decode_update_key_set_safe(uint8_t* apdu, uint32_t apdu_len_remaining, } for (i = 0; i < (int)key_set->set_key_count[0]; i++) { res = decode_key_entry_safe(apdu + curr, apdu_len_remaining - curr, - &key_set->set_keys[0][i]); + &key_set->set_keys[0][i]); if (res < 0) { return -1; } @@ -743,7 +742,7 @@ int decode_update_key_set_safe(uint8_t* apdu, uint32_t apdu_len_remaining, } for (i = 0; i < (int)key_set->set_key_count[1]; i++) { res = decode_key_entry_safe(apdu + curr, apdu_len_remaining - curr, - &key_set->set_keys[1][i]); + &key_set->set_keys[1][i]); if (res < 0) { return -1; } @@ -754,9 +753,9 @@ int decode_update_key_set_safe(uint8_t* apdu, uint32_t apdu_len_remaining, return curr; } -int decode_update_distribution_key_safe( - uint8_t* apdu, uint32_t apdu_len_remaining, - BACNET_UPDATE_DISTRIBUTION_KEY* dist_key) +int decode_update_distribution_key_safe(uint8_t *apdu, + uint32_t apdu_len_remaining, + BACNET_UPDATE_DISTRIBUTION_KEY *dist_key) { int curr = 0; int res; @@ -764,8 +763,8 @@ int decode_update_distribution_key_safe( return -1; } dist_key->key_revision = apdu[curr++]; - res = decode_key_entry_safe(&apdu[curr], apdu_len_remaining - curr, - &dist_key->key); + res = decode_key_entry_safe( + &apdu[curr], apdu_len_remaining - curr, &dist_key->key); if (res < 0) { return -1; } @@ -773,8 +772,9 @@ int decode_update_distribution_key_safe( return curr + res; } -int decode_request_master_key_safe(uint8_t* apdu, uint32_t apdu_len_remaining, - BACNET_REQUEST_MASTER_KEY* req_master_key) +int decode_request_master_key_safe(uint8_t *apdu, + uint32_t apdu_len_remaining, + BACNET_REQUEST_MASTER_KEY *req_master_key) { uint32_t curr = 0; @@ -786,14 +786,15 @@ int decode_request_master_key_safe(uint8_t* apdu, uint32_t apdu_len_remaining, return -1; } memcpy(req_master_key->es_algorithms, &apdu[curr], - req_master_key->no_supported_algorithms); + req_master_key->no_supported_algorithms); return (int)(curr + req_master_key->no_supported_algorithms); } -int decode_set_master_key_safe(uint8_t* apdu, uint32_t apdu_len_remaining, - BACNET_SET_MASTER_KEY* set_master_key) +int decode_set_master_key_safe(uint8_t *apdu, + uint32_t apdu_len_remaining, + BACNET_SET_MASTER_KEY *set_master_key) { - return decode_key_entry_safe(apdu, apdu_len_remaining, - &set_master_key->key); + return decode_key_entry_safe( + apdu, apdu_len_remaining, &set_master_key->key); } diff --git a/include/bacsec.h b/src/bacnet/datalink/bacsec.h similarity index 99% rename from include/bacsec.h rename to src/bacnet/datalink/bacsec.h index 156147e9..93823dd7 100644 --- a/include/bacsec.h +++ b/src/bacnet/datalink/bacsec.h @@ -39,8 +39,8 @@ #include #include -#include "bacdef.h" -#include "bacenum.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacenum.h" typedef struct BACnet_Security_Wrapper { bool payload_net_or_bvll_flag; /* true if NPDU or BVLL */ diff --git a/src/bip.c b/src/bacnet/datalink/bip.c similarity index 90% rename from src/bip.c rename to src/bacnet/datalink/bip.c index f7aa8b6b..2aafdfba 100644 --- a/src/bip.c +++ b/src/bacnet/datalink/bip.c @@ -32,13 +32,13 @@ ------------------------------------------- ####COPYRIGHTEND####*/ -#include /* for standard integer types uint8_t etc. */ +#include /* for standard integer types uint8_t etc. */ #include /* for the standard bool type. */ -#include "bacdcode.h" -#include "bacint.h" -#include "bip.h" -#include "bvlc.h" -#include "net.h" /* custom per port */ +#include "bacnet/bacdcode.h" +#include "bacnet/bacint.h" +#include "bacnet/datalink/bip.h" +#include "bacnet/datalink/bvlc.h" +#include "bacport.h" /* custom per port */ #if PRINT_ENABLED #include /* for standard i/o, like printing */ #endif @@ -109,8 +109,8 @@ uint16_t bip_get_port(void) return BIP_Port; } -static int bip_decode_bip_address( - BACNET_ADDRESS *bac_addr, struct in_addr *address, /* in network format */ +static int bip_decode_bip_address(BACNET_ADDRESS *bac_addr, + struct in_addr *address, /* in network format */ uint16_t *port) { /* in network format */ int len = 0; @@ -133,13 +133,13 @@ static int bip_decode_bip_address( * @param pdu_len [in] Number of bytes in the pdu buffer. * @return Number of bytes sent on success, negative number on failure. */ -int bip_send_pdu(BACNET_ADDRESS *dest, /* destination address */ - BACNET_NPDU_DATA *npdu_data, /* network information */ - uint8_t *pdu, /* any data to be sent - may be null */ - unsigned pdu_len) +int bip_send_pdu(BACNET_ADDRESS *dest, /* destination address */ + BACNET_NPDU_DATA *npdu_data, /* network information */ + uint8_t *pdu, /* any data to be sent - may be null */ + unsigned pdu_len) { /* number of bytes of data */ struct sockaddr_in bip_dest; - uint8_t mtu[MAX_MPDU] = {0}; + uint8_t mtu[MAX_MPDU] = { 0 }; int mtu_len = 0; int bytes_sent = 0; /* addr and port in host format */ @@ -179,14 +179,14 @@ int bip_send_pdu(BACNET_ADDRESS *dest, /* destination address */ bip_dest.sin_port = port; memset(&(bip_dest.sin_zero), '\0', 8); mtu_len = 2; - mtu_len += encode_unsigned16(&mtu[mtu_len], - (uint16_t)(pdu_len + 4 /*inclusive */)); + mtu_len += encode_unsigned16( + &mtu[mtu_len], (uint16_t)(pdu_len + 4 /*inclusive */)); memcpy(&mtu[mtu_len], pdu, pdu_len); mtu_len += pdu_len; /* Send the packet */ bytes_sent = sendto(BIP_Socket, (char *)mtu, mtu_len, 0, - (struct sockaddr *)&bip_dest, sizeof(struct sockaddr)); + (struct sockaddr *)&bip_dest, sizeof(struct sockaddr)); return bytes_sent; } @@ -203,10 +203,9 @@ int bip_send_pdu(BACNET_ADDRESS *dest, /* destination address */ * @param timeout [in] The number of milliseconds to wait for a packet. * @return The number of octets (remaining) in the PDU, or zero on failure. */ -uint16_t bip_receive( - BACNET_ADDRESS *src, /* source address */ - uint8_t *pdu, /* PDU data */ - uint16_t max_pdu, /* amount of space available in the PDU */ +uint16_t bip_receive(BACNET_ADDRESS *src, /* source address */ + uint8_t *pdu, /* PDU data */ + uint16_t max_pdu, /* amount of space available in the PDU */ unsigned timeout) { int received_bytes = 0; @@ -214,14 +213,15 @@ uint16_t bip_receive( fd_set read_fds; int max = 0; struct timeval select_timeout; - struct sockaddr_in sin = {0}; + struct sockaddr_in sin = { 0 }; socklen_t sin_len = sizeof(sin); uint16_t i = 0; int function = 0; /* Make sure the socket is open */ - if (BIP_Socket < 0) + if (BIP_Socket < 0) { return 0; + } /* we could just use a non-blocking socket, but that consumes all the CPU time. We can use a timeout; it is only supported as @@ -238,11 +238,12 @@ uint16_t bip_receive( FD_SET(BIP_Socket, &read_fds); max = BIP_Socket; /* see if there is a packet for us */ - if (select(max + 1, &read_fds, NULL, NULL, &select_timeout) > 0) + if (select(max + 1, &read_fds, NULL, NULL, &select_timeout) > 0) { received_bytes = recvfrom(BIP_Socket, (char *)&pdu[0], max_pdu, 0, - (struct sockaddr *)&sin, &sin_len); - else + (struct sockaddr *)&sin, &sin_len); + } else { return 0; + } /* See if there is a problem */ if (received_bytes < 0) { @@ -250,12 +251,14 @@ uint16_t bip_receive( } /* no problem, just no bytes */ - if (received_bytes == 0) + if (received_bytes == 0) { return 0; + } /* the signature of a BACnet/IP packet */ - if (pdu[0] != BVLL_TYPE_BACNET_IP) + if (pdu[0] != BVLL_TYPE_BACNET_IP) { return 0; + } if (bvlc_for_non_bbmd(&sin, pdu, received_bytes) > 0) { /* Handled, usually with a NACK. */ @@ -364,7 +367,7 @@ void bip_get_my_address(BACNET_ADDRESS *my_address) } void bip_get_broadcast_address(BACNET_ADDRESS *dest) -{ /* destination address */ +{ /* destination address */ int i = 0; /* counter */ if (dest) { diff --git a/include/bip.h b/src/bacnet/datalink/bip.h similarity index 98% rename from include/bip.h rename to src/bacnet/datalink/bip.h index a9c4e331..dfb31d4b 100644 --- a/include/bip.h +++ b/src/bacnet/datalink/bip.h @@ -27,9 +27,9 @@ #include #include #include -#include "bacdef.h" -#include "npdu.h" -#include "net.h" +#include "bacnet/bacdef.h" +#include "bacnet/npdu.h" +#include "bacport.h" /* specific defines for BACnet/IP over Ethernet */ #define MAX_HEADER (1 + 1 + 2) diff --git a/include/bip6.h b/src/bacnet/datalink/bip6.h similarity index 96% rename from include/bip6.h rename to src/bacnet/datalink/bip6.h index 3c12f2ff..59421b6e 100644 --- a/include/bip6.h +++ b/src/bacnet/datalink/bip6.h @@ -16,9 +16,9 @@ #include #include #include -#include "bacdef.h" -#include "npdu.h" -#include "bvlc6.h" +#include "bacnet/bacdef.h" +#include "bacnet/npdu.h" +#include "bacnet/datalink/bvlc6.h" /* specific defines for BACnet/IP over Ethernet */ #define BIP6_HEADER_MAX (1 + 1 + 2) diff --git a/src/bvlc.c b/src/bacnet/datalink/bvlc.c similarity index 91% rename from src/bvlc.c rename to src/bacnet/datalink/bvlc.c index 454973b2..56a54d49 100644 --- a/src/bvlc.c +++ b/src/bacnet/datalink/bvlc.c @@ -32,17 +32,17 @@ ------------------------------------------- ####COPYRIGHTEND####*/ -#include /* for standard integer types uint8_t etc. */ +#include /* for standard integer types uint8_t etc. */ #include /* for the standard bool type. */ #include -#include "bacenum.h" -#include "bacdcode.h" -#include "bacint.h" -#include "bvlc.h" +#include "bacnet/bacenum.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacint.h" +#include "bacnet/datalink/bvlc.h" #ifndef DEBUG_ENABLED #define DEBUG_ENABLED 0 #endif -#include "debug.h" +#include "bacnet/basic/sys/debug.h" /** @file bvlc.c Handle the BACnet Virtual Link Control (BVLC), * which includes: BACnet Broadcast Management Device, @@ -124,16 +124,18 @@ void bvlc_bdt_backup_local(void) static FILE *bdt_file_ptr = NULL; /* only try opening the file if not already opened previously */ - if (!bdt_file_ptr) + if (!bdt_file_ptr) { bdt_file_ptr = fopen(tostr(BBMD_BACKUP_FILE), "wb"); + } /* if error opening file for writing -> silently abort */ - if (!bdt_file_ptr) + if (!bdt_file_ptr) { return; + } fseek(bdt_file_ptr, 0, SEEK_SET); - fwrite(BBMD_Table, sizeof(BBMD_TABLE_ENTRY), MAX_BBMD_ENTRIES, - bdt_file_ptr); + fwrite( + BBMD_Table, sizeof(BBMD_TABLE_ENTRY), MAX_BBMD_ENTRIES, bdt_file_ptr); fflush(bdt_file_ptr); } @@ -142,12 +144,14 @@ void bvlc_bdt_restore_local(void) static FILE *bdt_file_ptr = NULL; /* only try opening the file if not already opened previously */ - if (!bdt_file_ptr) + if (!bdt_file_ptr) { bdt_file_ptr = fopen(tostr(BBMD_BACKUP_FILE), "rb"); + } /* if error opening file for reading -> silently abort */ - if (!bdt_file_ptr) + if (!bdt_file_ptr) { return; + } fseek(bdt_file_ptr, 0, SEEK_SET); { @@ -155,11 +159,12 @@ void bvlc_bdt_restore_local(void) size_t entries = 0; entries = fread(BBMD_Table_tmp, sizeof(BBMD_TABLE_ENTRY), - MAX_BBMD_ENTRIES, bdt_file_ptr); - if (entries == MAX_BBMD_ENTRIES) + MAX_BBMD_ENTRIES, bdt_file_ptr); + if (entries == MAX_BBMD_ENTRIES) { /* success reading the BDT table. */ memcpy(BBMD_Table, BBMD_Table_tmp, - sizeof(BBMD_TABLE_ENTRY) * MAX_BBMD_ENTRIES); + sizeof(BBMD_TABLE_ENTRY) * MAX_BBMD_ENTRIES); + } } } #else @@ -204,8 +209,8 @@ void bvlc_maintenance_timer(time_t seconds) * * @return number of bytes decoded */ -static void bvlc_internet_to_bacnet_address(BACNET_ADDRESS *src, - struct sockaddr_in *sin) +static void bvlc_internet_to_bacnet_address( + BACNET_ADDRESS *src, struct sockaddr_in *sin) { if (src && sin) { memcpy(&src->mac[0], &sin->sin_addr.s_addr, 4); @@ -233,8 +238,8 @@ static void bvlc_internet_to_bacnet_address(BACNET_ADDRESS *src, * * @return number of bytes encoded */ -static int bvlc_encode_bip_address(uint8_t *pdu, struct in_addr *address, - uint16_t port) +static int bvlc_encode_bip_address( + uint8_t *pdu, struct in_addr *address, uint16_t port) { int len = 0; @@ -255,8 +260,8 @@ static int bvlc_encode_bip_address(uint8_t *pdu, struct in_addr *address, * * @return number of bytes decoded */ -static int bvlc_decode_bip_address(uint8_t *pdu, struct in_addr *address, - uint16_t *port) +static int bvlc_decode_bip_address( + uint8_t *pdu, struct in_addr *address, uint16_t *port) { int len = 0; @@ -278,8 +283,8 @@ static int bvlc_decode_bip_address(uint8_t *pdu, struct in_addr *address, * * @return number of bytes encoded */ -static int bvlc_encode_address_entry(uint8_t *pdu, struct in_addr *address, - uint16_t port, struct in_addr *mask) +static int bvlc_encode_address_entry( + uint8_t *pdu, struct in_addr *address, uint16_t port, struct in_addr *mask) { int len = 0; @@ -377,10 +382,10 @@ int bvlc_encode_read_bdt(uint8_t *pdu) */ int bvlc_bbmd_read_bdt(uint32_t bbmd_address, uint16_t bbmd_port) { - uint8_t mtu[MAX_MPDU] = {0}; + uint8_t mtu[MAX_MPDU] = { 0 }; uint16_t mtu_len = 0; int rv = 0; - struct sockaddr_in bbmd = {0}; + struct sockaddr_in bbmd = { 0 }; mtu_len = bvlc_encode_read_bdt(mtu); if (mtu_len > 0) { @@ -447,9 +452,9 @@ static int bvlc_encode_read_bdt_ack(uint8_t *pdu, uint16_t max_pdu) pdu_len = 0; break; } - len = bvlc_encode_address_entry( - &pdu[pdu_len], &BBMD_Table[i].dest_address, - BBMD_Table[i].dest_port, &BBMD_Table[i].broadcast_mask); + len = bvlc_encode_address_entry(&pdu[pdu_len], + &BBMD_Table[i].dest_address, BBMD_Table[i].dest_port, + &BBMD_Table[i].broadcast_mask); pdu_len += len; } } @@ -467,9 +472,11 @@ static int bvlc_encode_read_bdt_ack(uint8_t *pdu, uint16_t max_pdu) * * @return number of bytes encoded */ -static int bvlc_encode_forwarded_npdu(uint8_t *pdu, uint16_t max_pdu, - struct sockaddr_in *sin, uint8_t *npdu, - unsigned npdu_length) +static int bvlc_encode_forwarded_npdu(uint8_t *pdu, + uint16_t max_pdu, + struct sockaddr_in *sin, + uint8_t *npdu, + unsigned npdu_length) { int len = 0; @@ -485,8 +492,8 @@ static int bvlc_encode_forwarded_npdu(uint8_t *pdu, uint16_t max_pdu, encode_unsigned16(&pdu[2], (uint16_t)(4 + 6 + npdu_length)); len = 4; /* 6-octet address encoding */ - len += bvlc_encode_bip_address(&pdu[len], &sin->sin_addr, - sin->sin_port); + len += bvlc_encode_bip_address( + &pdu[len], &sin->sin_addr, sin->sin_port); for (i = 0; i < npdu_length; i++) { pdu[len] = npdu[i]; len++; @@ -580,8 +587,7 @@ static int bvlc_encode_read_fdt_ack(uint8_t *pdu, uint16_t max_pdu) break; } len = bvlc_encode_bip_address(&pdu[pdu_len], - &FD_Table[i].dest_address, - FD_Table[i].dest_port); + &FD_Table[i].dest_address, FD_Table[i].dest_port); pdu_len += len; len = encode_unsigned16(&pdu[pdu_len], FD_Table[i].time_to_live); pdu_len += len; @@ -634,10 +640,10 @@ int bvlc_encode_delete_fdt_entry(uint8_t *pdu, uint32_t address, uint16_t port) * * @return number of bytes encoded */ -int bvlc_encode_original_unicast_npdu(uint8_t *pdu, uint8_t *npdu, - unsigned npdu_length) +int bvlc_encode_original_unicast_npdu( + uint8_t *pdu, uint8_t *npdu, unsigned npdu_length) { - int len = 0; /* return value */ + int len = 0; /* return value */ unsigned i = 0; /* loop counter */ uint16_t BVLC_length = 0; @@ -668,10 +674,10 @@ int bvlc_encode_original_unicast_npdu(uint8_t *pdu, uint8_t *npdu, * * @return number of bytes encoded */ -int bvlc_encode_original_broadcast_npdu(uint8_t *pdu, uint8_t *npdu, - unsigned npdu_length) +int bvlc_encode_original_broadcast_npdu( + uint8_t *pdu, uint8_t *npdu, unsigned npdu_length) { - int len = 0; /* return value */ + int len = 0; /* return value */ unsigned i = 0; /* loop counter */ uint16_t BVLC_length = 0; @@ -742,8 +748,8 @@ static bool bvlc_create_bdt(uint8_t *npdu, uint16_t npdu_length) * * @return true if the Foreign Device was added */ -static bool bvlc_register_foreign_device(struct sockaddr_in *sin, - uint16_t time_to_live) +static bool bvlc_register_foreign_device( + struct sockaddr_in *sin, uint16_t time_to_live) { unsigned i = 0; bool status = false; @@ -789,8 +795,8 @@ static bool bvlc_register_foreign_device(struct sockaddr_in *sin, */ static bool bvlc_delete_foreign_device(uint8_t *pdu, uint16_t pdu_len) { - struct sockaddr_in sin = {0}; /* the ip address */ - bool status = false; /* return value */ + struct sockaddr_in sin = { 0 }; /* the ip address */ + bool status = false; /* return value */ unsigned i = 0; if (pdu_len < 6) { @@ -826,7 +832,7 @@ static bool bvlc_delete_foreign_device(uint8_t *pdu, uint16_t pdu_len) */ int bvlc_send_mpdu(struct sockaddr_in *dest, uint8_t *mtu, uint16_t mtu_len) { - struct sockaddr_in bvlc_dest = {0}; + struct sockaddr_in bvlc_dest = { 0 }; /* assumes that the driver has already been initialized */ if (bip_socket() < 0) { @@ -839,7 +845,7 @@ int bvlc_send_mpdu(struct sockaddr_in *dest, uint8_t *mtu, uint16_t mtu_len) memset(&(bvlc_dest.sin_zero), '\0', 8); /* Send the packet */ return sendto(bip_socket(), (char *)mtu, mtu_len, 0, - (struct sockaddr *)&bvlc_dest, sizeof(struct sockaddr)); + (struct sockaddr *)&bvlc_dest, sizeof(struct sockaddr)); } #if defined(BBMD_ENABLED) && BBMD_ENABLED @@ -851,13 +857,13 @@ int bvlc_send_mpdu(struct sockaddr_in *dest, uint8_t *mtu, uint16_t mtu_len) * @param npdu_length - length of the NPDU * @param original - was the message an original (not forwarded) */ -static void bvlc_bdt_forward_npdu(struct sockaddr_in *sin, uint8_t *npdu, - uint16_t npdu_length, bool original) +static void bvlc_bdt_forward_npdu( + struct sockaddr_in *sin, uint8_t *npdu, uint16_t npdu_length, bool original) { - uint8_t mtu[MAX_MPDU] = {0}; + uint8_t mtu[MAX_MPDU] = { 0 }; uint16_t mtu_len = 0; unsigned i = 0; /* loop counter */ - struct sockaddr_in bip_dest = {0}; + struct sockaddr_in bip_dest = { 0 }; /* If we are forwarding an original broadcast message and the NAT * handling is enabled, change the source address to NAT routers @@ -884,7 +890,7 @@ static void bvlc_bdt_forward_npdu(struct sockaddr_in *sin, uint8_t *npdu, mask in the BDT entry and logically ORing it with the BBMD address of the same entry. */ bip_dest.sin_addr.s_addr = ((~BBMD_Table[i].broadcast_mask.s_addr) | - BBMD_Table[i].dest_address.s_addr); + BBMD_Table[i].dest_address.s_addr); bip_dest.sin_port = BBMD_Table[i].dest_port; /* don't send to my broadcast address and same port */ if ((bip_dest.sin_addr.s_addr == bip_get_broadcast_addr()) && @@ -907,8 +913,7 @@ static void bvlc_bdt_forward_npdu(struct sockaddr_in *sin, uint8_t *npdu, } bvlc_send_mpdu(&bip_dest, mtu, mtu_len); debug_printf("BVLC: BDT Sent Forwarded-NPDU to %s:%04X\n", - inet_ntoa(bip_dest.sin_addr), - ntohs(bip_dest.sin_port)); + inet_ntoa(bip_dest.sin_addr), ntohs(bip_dest.sin_port)); } } @@ -923,12 +928,12 @@ static void bvlc_bdt_forward_npdu(struct sockaddr_in *sin, uint8_t *npdu, * @param max_npdu - amount of space available in the NPDU * @param npdu_length - reported length of the NPDU */ -static void bvlc_forward_npdu(struct sockaddr_in *sin, uint8_t *npdu, - uint16_t npdu_length) +static void bvlc_forward_npdu( + struct sockaddr_in *sin, uint8_t *npdu, uint16_t npdu_length) { - uint8_t mtu[MAX_MPDU] = {0}; + uint8_t mtu[MAX_MPDU] = { 0 }; uint16_t mtu_len = 0; - struct sockaddr_in bip_dest = {0}; + struct sockaddr_in bip_dest = { 0 }; mtu_len = (uint16_t)bvlc_encode_forwarded_npdu( &mtu[0], (uint16_t)sizeof(mtu), sin, npdu, npdu_length); @@ -946,13 +951,13 @@ static void bvlc_forward_npdu(struct sockaddr_in *sin, uint8_t *npdu, * @param npdu_length - reported length of the NPDU * @param original - was the message an original (not forwarded) */ -static void bvlc_fdt_forward_npdu(struct sockaddr_in *sin, uint8_t *npdu, - uint16_t npdu_length, bool original) +static void bvlc_fdt_forward_npdu( + struct sockaddr_in *sin, uint8_t *npdu, uint16_t npdu_length, bool original) { - uint8_t mtu[MAX_MPDU] = {0}; + uint8_t mtu[MAX_MPDU] = { 0 }; uint16_t mtu_len = 0; unsigned i = 0; /* loop counter */ - struct sockaddr_in bip_dest = {0}; + struct sockaddr_in bip_dest = { 0 }; /* If we are forwarding an original broadcast message and the NAT * handling is enabled, change the source address to NAT routers @@ -998,8 +1003,7 @@ static void bvlc_fdt_forward_npdu(struct sockaddr_in *sin, uint8_t *npdu, } bvlc_send_mpdu(&bip_dest, mtu, mtu_len); debug_printf("BVLC: FDT Sent Forwarded-NPDU to %s:%04X\n", - inet_ntoa(bip_dest.sin_addr), - ntohs(bip_dest.sin_port)); + inet_ntoa(bip_dest.sin_addr), ntohs(bip_dest.sin_port)); } } @@ -1018,7 +1022,7 @@ static int bvlc_send_result( struct sockaddr_in *dest, /* the destination address */ BACNET_BVLC_RESULT result_code) { - uint8_t mtu[MAX_MPDU] = {0}; + uint8_t mtu[MAX_MPDU] = { 0 }; uint16_t mtu_len = 0; mtu_len = (uint16_t)bvlc_encode_bvlc_result(&mtu[0], result_code); @@ -1038,7 +1042,7 @@ static int bvlc_send_result( */ static int bvlc_send_bdt(struct sockaddr_in *dest) { - uint8_t mtu[MAX_MPDU] = {0}; + uint8_t mtu[MAX_MPDU] = { 0 }; uint16_t mtu_len = 0; mtu_len = (uint16_t)bvlc_encode_read_bdt_ack(&mtu[0], sizeof(mtu)); @@ -1057,7 +1061,7 @@ static int bvlc_send_bdt(struct sockaddr_in *dest) */ static int bvlc_send_fdt(struct sockaddr_in *dest) { - uint8_t mtu[MAX_MPDU] = {0}; + uint8_t mtu[MAX_MPDU] = { 0 }; uint16_t mtu_len = 0; mtu_len = (uint16_t)bvlc_encode_read_fdt_ack(&mtu[0], sizeof(mtu)); @@ -1111,16 +1115,16 @@ static bool bvlc_bdt_member_mask_is_unicast(struct sockaddr_in *sin) * * @return Number of bytes received, or 0 if none or timeout. */ -uint16_t bvlc_receive(BACNET_ADDRESS *src, uint8_t *npdu, uint16_t max_npdu, - unsigned timeout) +uint16_t bvlc_receive( + BACNET_ADDRESS *src, uint8_t *npdu, uint16_t max_npdu, unsigned timeout) { uint16_t npdu_len = 0; /* return value */ fd_set read_fds; int max = 0; struct timeval select_timeout; - struct sockaddr_in sin = {0}; - struct sockaddr_in original_sin = {0}; - struct sockaddr_in dest = {0}; + struct sockaddr_in sin = { 0 }; + struct sockaddr_in original_sin = { 0 }; + struct sockaddr_in dest = { 0 }; socklen_t sin_len = sizeof(sin); int received_bytes = 0; uint16_t result_code = 0; @@ -1150,7 +1154,7 @@ uint16_t bvlc_receive(BACNET_ADDRESS *src, uint8_t *npdu, uint16_t max_npdu, /* see if there is a packet for us */ if (select(max + 1, &read_fds, NULL, NULL, &select_timeout) > 0) { received_bytes = recvfrom(bip_socket(), (char *)&npdu[0], max_npdu, 0, - (struct sockaddr *)&sin, &sin_len); + (struct sockaddr *)&sin, &sin_len); } else { return 0; } @@ -1256,11 +1260,10 @@ uint16_t bvlc_receive(BACNET_ADDRESS *src, uint8_t *npdu, uint16_t max_npdu, return 0; } /* decode the 4 byte original address and 2 byte port */ - bvlc_decode_bip_address(&npdu[4], &original_sin.sin_addr, - &original_sin.sin_port); + bvlc_decode_bip_address( + &npdu[4], &original_sin.sin_addr, &original_sin.sin_port); debug_printf("BVLC: Received Forwarded-NPDU from %s:%04X.\n", - inet_ntoa(original_sin.sin_addr), - ntohs(original_sin.sin_port)); + inet_ntoa(original_sin.sin_addr), ntohs(original_sin.sin_port)); npdu_len -= 6; /* Broadcast locally if received via unicast from a BDT member */ if (bvlc_bdt_member_mask_is_unicast(&sin)) { @@ -1277,7 +1280,7 @@ uint16_t bvlc_receive(BACNET_ADDRESS *src, uint8_t *npdu, uint16_t max_npdu, dest.sin_port = original_sin.sin_port; bvlc_fdt_forward_npdu(&dest, &npdu[4 + 6], npdu_len, false); debug_printf("BVLC: Received Forwarded-NPDU from %s:%04X.\n", - inet_ntoa(dest.sin_addr), ntohs(dest.sin_port)); + inet_ntoa(dest.sin_addr), ntohs(dest.sin_port)); bvlc_internet_to_bacnet_address(src, &dest); if (npdu_len < max_npdu) { /* shift the buffer to return a valid NPDU */ @@ -1324,8 +1327,8 @@ uint16_t bvlc_receive(BACNET_ADDRESS *src, uint8_t *npdu, uint16_t max_npdu, with a result code of X'0040' indicating that the read attempt has failed. */ if (bvlc_send_fdt(&sin) <= 0) { - bvlc_send_result(&sin, - BVLC_RESULT_READ_FOREIGN_DEVICE_TABLE_NAK); + bvlc_send_result( + &sin, BVLC_RESULT_READ_FOREIGN_DEVICE_TABLE_NAK); } /* not an NPDU */ npdu_len = 0; @@ -1356,9 +1359,8 @@ uint16_t bvlc_receive(BACNET_ADDRESS *src, uint8_t *npdu, uint16_t max_npdu, npdu_len = 0; break; case BVLC_DISTRIBUTE_BROADCAST_TO_NETWORK: - debug_printf( - "BVLC: Received Distribute-Broadcast-to-Network from " - "%s:%04X.\n", + debug_printf("BVLC: Received Distribute-Broadcast-to-Network from " + "%s:%04X.\n", inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); /* Upon receipt of a BVLL Distribute-Broadcast-To-Network message from a foreign device, the receiving BBMD shall transmit a @@ -1385,8 +1387,8 @@ uint16_t bvlc_receive(BACNET_ADDRESS *src, uint8_t *npdu, uint16_t max_npdu, /* ignore messages from me */ npdu_len = 0; } else if (BVLC_NAT_Handling && - (sin.sin_addr.s_addr == BVLC_Global_Address.s_addr) && - (sin.sin_port == bip_get_port())) { + (sin.sin_addr.s_addr == BVLC_Global_Address.s_addr) && + (sin.sin_port == bip_get_port())) { /* If the BBMD is behind a NAT router, the router forwards packets from global IP and BACnet port to us. */ npdu_len = 0; @@ -1449,11 +1451,13 @@ uint16_t bvlc_receive(BACNET_ADDRESS *src, uint8_t *npdu, uint16_t max_npdu, * * @return returns number of bytes sent on success, negative number on failure */ -int bvlc_send_pdu(BACNET_ADDRESS *dest, BACNET_NPDU_DATA *npdu_data, - uint8_t *pdu, unsigned pdu_len) +int bvlc_send_pdu(BACNET_ADDRESS *dest, + BACNET_NPDU_DATA *npdu_data, + uint8_t *pdu, + unsigned pdu_len) { - struct sockaddr_in bvlc_dest = {0}; - uint8_t mtu[MAX_MPDU] = {0}; + struct sockaddr_in bvlc_dest = { 0 }; + uint8_t mtu[MAX_MPDU] = { 0 }; uint16_t mtu_len = 0; /* addr and port in network format */ struct in_addr address; @@ -1522,8 +1526,8 @@ int bvlc_send_pdu(BACNET_ADDRESS *dest, BACNET_NPDU_DATA *npdu_data, * @return Number of bytes encoded) on success, * or 0 if no encoding occurred. */ -static int bvlc_encode_register_foreign_device(uint8_t *pdu, - uint16_t time_to_live_seconds) +static int bvlc_encode_register_foreign_device( + uint8_t *pdu, uint16_t time_to_live_seconds) { int len = 0; @@ -1550,10 +1554,10 @@ static int bvlc_encode_register_foreign_device(uint8_t *pdu, * 0 if no registration request is sent, or * -1 if registration fails. */ -int bvlc_register_with_bbmd(uint32_t bbmd_address, uint16_t bbmd_port, - uint16_t time_to_live_seconds) +int bvlc_register_with_bbmd( + uint32_t bbmd_address, uint16_t bbmd_port, uint16_t time_to_live_seconds) { - uint8_t mtu[MAX_MPDU] = {0}; + uint8_t mtu[MAX_MPDU] = { 0 }; uint16_t mtu_len = 0; int retval = 0; @@ -1581,8 +1585,8 @@ int bvlc_register_with_bbmd(uint32_t bbmd_address, uint16_t bbmd_port, * @return Non-zero BVLC_RESULT_ code if we sent a response (NAK) to this * BVLC message. If zero, may need further processing. */ -int bvlc_for_non_bbmd(struct sockaddr_in *sout, uint8_t *npdu, - uint16_t received_bytes) +int bvlc_for_non_bbmd( + struct sockaddr_in *sout, uint8_t *npdu, uint16_t received_bytes) { uint16_t result_code = 0; /* aka, BVLC_RESULT_SUCCESSFUL_COMPLETION */ @@ -1671,8 +1675,9 @@ int bvlc_get_bdt_local(const BBMD_TABLE_ENTRY **table) { int count = 0; - if (table == NULL) + if (table == NULL) { return -1; + } *table = BBMD_Table; @@ -1709,8 +1714,9 @@ bool bvlc_add_bdt_entry_local(BBMD_TABLE_ENTRY *entry) bool found = false; int i = 0; - if (entry == NULL) + if (entry == NULL) { return false; + } /* Find first empty slot */ for (i = 0; i < MAX_BBMD_ENTRIES; ++i) { @@ -1728,8 +1734,9 @@ bool bvlc_add_bdt_entry_local(BBMD_TABLE_ENTRY *entry) } } - if (!found) + if (!found) { return false; + } /* Copy new entry to the empty slot */ BBMD_Table[i] = *entry; @@ -1785,7 +1792,7 @@ static void bvlc_bacnet_to_internet_address( void testBIPAddress(Test *pTest) { - uint8_t apdu[50] = {0}; + uint8_t apdu[50] = { 0 }; uint32_t value = 0, test_value = 0; int len = 0, test_len = 0; struct in_addr address; @@ -1804,8 +1811,8 @@ void testInternetAddress(Test *pTest) { BACNET_ADDRESS src; BACNET_ADDRESS test_src; - struct sockaddr_in sin = {0}; - struct sockaddr_in test_sin = {0}; + struct sockaddr_in sin = { 0 }; + struct sockaddr_in test_sin = { 0 }; sin.sin_port = htons(0xBAC0); sin.sin_addr.s_addr = inet_addr("192.168.0.1"); diff --git a/include/bvlc.h b/src/bacnet/datalink/bvlc.h similarity index 98% rename from include/bvlc.h rename to src/bacnet/datalink/bvlc.h index 5955a225..77851927 100644 --- a/include/bvlc.h +++ b/src/bacnet/datalink/bvlc.h @@ -28,9 +28,9 @@ #include #include #include -#include "bacdef.h" -#include "npdu.h" -#include "bip.h" +#include "bacnet/bacdef.h" +#include "bacnet/npdu.h" +#include "bacnet/datalink/bip.h" struct sockaddr_in; /* Defined elsewhere, needed here. */ diff --git a/src/bvlc6.c b/src/bacnet/datalink/bvlc6.c similarity index 79% rename from src/bvlc6.c rename to src/bacnet/datalink/bvlc6.c index 14ce9a93..f99f1d51 100644 --- a/src/bvlc6.c +++ b/src/bacnet/datalink/bvlc6.c @@ -32,17 +32,13 @@ ------------------------------------------- ####COPYRIGHTEND####*/ -#include /* for standard integer types uint8_t etc. */ +#include /* for standard integer types uint8_t etc. */ #include /* for the standard bool type. */ #include -#include "bacenum.h" -#include "bacdcode.h" -#include "bacint.h" -#include "bvlc6.h" -#ifndef DEBUG_ENABLED -#define DEBUG_ENABLED 0 -#endif -#include "debug.h" +#include "bacnet/bacenum.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacint.h" +#include "bacnet/datalink/bvlc6.h" /** Encode the BVLC header * @@ -53,8 +49,8 @@ * * @return number of bytes encoded */ -int bvlc6_encode_header(uint8_t *pdu, uint16_t pdu_size, uint8_t message_type, - uint16_t length) +int bvlc6_encode_header( + uint8_t *pdu, uint16_t pdu_size, uint8_t message_type, uint16_t length) { int bytes_encoded = 0; @@ -80,8 +76,8 @@ int bvlc6_encode_header(uint8_t *pdu, uint16_t pdu_size, uint8_t message_type, * * @return number of bytes decoded */ -int bvlc6_decode_header(uint8_t *pdu, uint16_t pdu_len, uint8_t *message_type, - uint16_t *length) +int bvlc6_decode_header( + uint8_t *pdu, uint16_t pdu_len, uint8_t *message_type, uint16_t *length) { int bytes_consumed = 0; @@ -123,8 +119,8 @@ int bvlc6_decode_header(uint8_t *pdu, uint16_t pdu_len, uint8_t *message_type, * X'00A0' Delete-Foreign-Device-Table-Entry * NAK X'00C0' Distribute-Broadcast-To-Network NAK */ -int bvlc6_encode_result(uint8_t *pdu, uint16_t pdu_size, uint32_t vmac, - uint16_t result_code) +int bvlc6_encode_result( + uint8_t *pdu, uint16_t pdu_size, uint32_t vmac, uint16_t result_code) { int bytes_encoded = 0; const uint16_t length = 9; @@ -151,8 +147,8 @@ int bvlc6_encode_result(uint8_t *pdu, uint16_t pdu_size, uint32_t vmac, * * @return number of bytes decoded */ -int bvlc6_decode_result(uint8_t *pdu, uint16_t pdu_len, uint32_t *vmac, - uint16_t *result_code) +int bvlc6_decode_result( + uint8_t *pdu, uint16_t pdu_len, uint32_t *vmac, uint16_t *result_code) { int bytes_consumed = 0; @@ -190,9 +186,12 @@ int bvlc6_decode_result(uint8_t *pdu, uint16_t pdu_len, uint32_t *vmac, * Destination-Virtual-Address: 3-octets * BACnet NPDU: Variable length */ -int bvlc6_encode_original_unicast(uint8_t *pdu, uint16_t pdu_size, - uint32_t vmac_src, uint32_t vmac_dst, - uint8_t *npdu, uint16_t npdu_len) +int bvlc6_encode_original_unicast(uint8_t *pdu, + uint16_t pdu_size, + uint32_t vmac_src, + uint32_t vmac_dst, + uint8_t *npdu, + uint16_t npdu_len) { int bytes_encoded = 0; uint16_t length = 10; @@ -230,10 +229,13 @@ int bvlc6_encode_original_unicast(uint8_t *pdu, uint16_t pdu_size, * * @return number of bytes decoded */ -int bvlc6_decode_original_unicast(uint8_t *pdu, uint16_t pdu_len, - uint32_t *vmac_src, uint32_t *vmac_dst, - uint8_t *npdu, uint16_t npdu_size, - uint16_t *npdu_len) +int bvlc6_decode_original_unicast(uint8_t *pdu, + uint16_t pdu_len, + uint32_t *vmac_src, + uint32_t *vmac_dst, + uint8_t *npdu, + uint16_t npdu_size, + uint16_t *npdu_len) { int bytes_consumed = 0; uint16_t length = 0; @@ -280,9 +282,11 @@ int bvlc6_decode_original_unicast(uint8_t *pdu, uint16_t pdu_len, * Source-Virtual-Address: 3-octets * BACnet NPDU: Variable length */ -int bvlc6_encode_original_broadcast(uint8_t *pdu, uint16_t pdu_size, - uint32_t vmac, uint8_t *npdu, - uint16_t npdu_len) +int bvlc6_encode_original_broadcast(uint8_t *pdu, + uint16_t pdu_size, + uint32_t vmac, + uint8_t *npdu, + uint16_t npdu_len) { int bytes_encoded = 0; uint16_t length = 7; @@ -317,9 +321,12 @@ int bvlc6_encode_original_broadcast(uint8_t *pdu, uint16_t pdu_size, * * @return number of bytes decoded */ -int bvlc6_decode_original_broadcast(uint8_t *pdu, uint16_t pdu_len, - uint32_t *vmac, uint8_t *npdu, - uint16_t npdu_size, uint16_t *npdu_len) +int bvlc6_decode_original_broadcast(uint8_t *pdu, + uint16_t pdu_len, + uint32_t *vmac, + uint8_t *npdu, + uint16_t npdu_size, + uint16_t *npdu_len) { int bytes_consumed = 0; uint16_t length = 0; @@ -363,16 +370,16 @@ int bvlc6_decode_original_broadcast(uint8_t *pdu, uint16_t pdu_len, * Source-Virtual-Address: 3-octets * Target-Virtual-Address: 3-octets */ -int bvlc6_encode_address_resolution(uint8_t *pdu, uint16_t pdu_size, - uint32_t vmac_src, uint32_t vmac_target) +int bvlc6_encode_address_resolution( + uint8_t *pdu, uint16_t pdu_size, uint32_t vmac_src, uint32_t vmac_target) { int bytes_encoded = 0; uint16_t length = 10; if (pdu && (pdu_size >= length) && (vmac_src <= 0xFFFFFF) && (vmac_target <= 0xFFFFFF)) { - bytes_encoded = bvlc6_encode_header(pdu, pdu_size, - BVLC6_ADDRESS_RESOLUTION, length); + bytes_encoded = bvlc6_encode_header( + pdu, pdu_size, BVLC6_ADDRESS_RESOLUTION, length); if (bytes_encoded == 4) { encode_unsigned24(&pdu[4], vmac_src); encode_unsigned24(&pdu[7], vmac_target); @@ -392,8 +399,8 @@ int bvlc6_encode_address_resolution(uint8_t *pdu, uint16_t pdu_size, * * @return number of bytes decoded */ -int bvlc6_decode_address_resolution(uint8_t *pdu, uint16_t pdu_len, - uint32_t *vmac_src, uint32_t *vmac_target) +int bvlc6_decode_address_resolution( + uint8_t *pdu, uint16_t pdu_len, uint32_t *vmac_src, uint32_t *vmac_target) { int bytes_consumed = 0; @@ -423,8 +430,8 @@ int bvlc6_decode_address_resolution(uint8_t *pdu, uint16_t pdu_len, * * @return number of bytes encoded */ -int bvlc6_encode_address(uint8_t *pdu, uint16_t pdu_size, - BACNET_IP6_ADDRESS *bip6_address) +int bvlc6_encode_address( + uint8_t *pdu, uint16_t pdu_size, BACNET_IP6_ADDRESS *bip6_address) { int bytes_encoded = 0; uint16_t length = BIP6_ADDRESS_MAX; @@ -449,8 +456,8 @@ int bvlc6_encode_address(uint8_t *pdu, uint16_t pdu_size, * * @return number of bytes decoded */ -int bvlc6_decode_address(uint8_t *pdu, uint16_t pdu_len, - BACNET_IP6_ADDRESS *bip6_address) +int bvlc6_decode_address( + uint8_t *pdu, uint16_t pdu_len, BACNET_IP6_ADDRESS *bip6_address) { int bytes_consumed = 0; uint16_t length = BIP6_ADDRESS_MAX; @@ -545,9 +552,15 @@ bool bvlc6_address_different(BACNET_IP6_ADDRESS *dst, BACNET_IP6_ADDRESS *src) * * @return true if the address is set */ -bool bvlc6_address_set(BACNET_IP6_ADDRESS *addr, uint16_t addr0, uint16_t addr1, - uint16_t addr2, uint16_t addr3, uint16_t addr4, - uint16_t addr5, uint16_t addr6, uint16_t addr7) +bool bvlc6_address_set(BACNET_IP6_ADDRESS *addr, + uint16_t addr0, + uint16_t addr1, + uint16_t addr2, + uint16_t addr3, + uint16_t addr4, + uint16_t addr5, + uint16_t addr6, + uint16_t addr7) { bool status = false; @@ -585,10 +598,15 @@ bool bvlc6_address_set(BACNET_IP6_ADDRESS *addr, uint16_t addr0, uint16_t addr1, * * @return true if the address is set */ -bool bvlc6_address_get(BACNET_IP6_ADDRESS *addr, uint16_t *addr0, - uint16_t *addr1, uint16_t *addr2, uint16_t *addr3, - uint16_t *addr4, uint16_t *addr5, uint16_t *addr6, - uint16_t *addr7) +bool bvlc6_address_get(BACNET_IP6_ADDRESS *addr, + uint16_t *addr0, + uint16_t *addr1, + uint16_t *addr2, + uint16_t *addr3, + uint16_t *addr4, + uint16_t *addr5, + uint16_t *addr6, + uint16_t *addr7) { bool status = false; @@ -687,10 +705,11 @@ bool bvlc6_vmac_address_get(BACNET_ADDRESS *addr, uint32_t *device_id) * Target-Virtual-Address: 3-octets * Original-Source-B/IPv6-Address 18-octets */ -int bvlc6_encode_forwarded_address_resolution(uint8_t *pdu, uint16_t pdu_size, - uint32_t vmac_src, - uint32_t vmac_target, - BACNET_IP6_ADDRESS *bip6_address) +int bvlc6_encode_forwarded_address_resolution(uint8_t *pdu, + uint16_t pdu_size, + uint32_t vmac_src, + uint32_t vmac_target, + BACNET_IP6_ADDRESS *bip6_address) { int bytes_encoded = 0; uint16_t length = 0x001C; @@ -724,10 +743,11 @@ int bvlc6_encode_forwarded_address_resolution(uint8_t *pdu, uint16_t pdu_size, * * @return number of bytes decoded */ -int bvlc6_decode_forwarded_address_resolution(uint8_t *pdu, uint16_t pdu_len, - uint32_t *vmac_src, - uint32_t *vmac_target, - BACNET_IP6_ADDRESS *bip6_address) +int bvlc6_decode_forwarded_address_resolution(uint8_t *pdu, + uint16_t pdu_len, + uint32_t *vmac_src, + uint32_t *vmac_target, + BACNET_IP6_ADDRESS *bip6_address) { int bytes_consumed = 0; const uint16_t length = 3 + 3 + BIP6_ADDRESS_MAX; @@ -760,9 +780,11 @@ int bvlc6_decode_forwarded_address_resolution(uint8_t *pdu, uint16_t pdu_len, * * @return number of bytes encoded */ -static int bvlc6_encode_address_ack(uint8_t message_type, uint8_t *pdu, - uint16_t pdu_size, uint32_t vmac_src, - uint32_t vmac_dst) +static int bvlc6_encode_address_ack(uint8_t message_type, + uint8_t *pdu, + uint16_t pdu_size, + uint32_t vmac_src, + uint32_t vmac_dst) { int bytes_encoded = 0; const uint16_t length = 10; @@ -802,11 +824,11 @@ static int bvlc6_encode_address_ack(uint8_t message_type, uint8_t *pdu, * Source-Virtual-Address: 3-octets * Destination-Virtual-Address: 3-octets */ -int bvlc6_encode_address_resolution_ack(uint8_t *pdu, uint16_t pdu_size, - uint32_t vmac_src, uint32_t vmac_dst) +int bvlc6_encode_address_resolution_ack( + uint8_t *pdu, uint16_t pdu_size, uint32_t vmac_src, uint32_t vmac_dst) { - return bvlc6_encode_address_ack(BVLC6_ADDRESS_RESOLUTION_ACK, pdu, pdu_size, - vmac_src, vmac_dst); + return bvlc6_encode_address_ack( + BVLC6_ADDRESS_RESOLUTION_ACK, pdu, pdu_size, vmac_src, vmac_dst); } /** Decode the BVLC Address-Resolution-Ack message @@ -818,8 +840,8 @@ int bvlc6_encode_address_resolution_ack(uint8_t *pdu, uint16_t pdu_size, * * @return number of bytes decoded */ -int bvlc6_decode_address_resolution_ack(uint8_t *pdu, uint16_t pdu_len, - uint32_t *vmac_src, uint32_t *vmac_dst) +int bvlc6_decode_address_resolution_ack( + uint8_t *pdu, uint16_t pdu_len, uint32_t *vmac_src, uint32_t *vmac_dst) { int bytes_consumed = 0; const uint16_t length = 6; @@ -855,8 +877,8 @@ int bvlc6_decode_address_resolution_ack(uint8_t *pdu, uint16_t pdu_len, * BVLC Length: 2-octets X'0007' Length of the BVLL message * Source-Virtual-Address: 3-octets */ -int bvlc6_encode_virtual_address_resolution(uint8_t *pdu, uint16_t pdu_size, - uint32_t vmac_src) +int bvlc6_encode_virtual_address_resolution( + uint8_t *pdu, uint16_t pdu_size, uint32_t vmac_src) { int bytes_encoded = 0; const uint16_t length = 7; @@ -881,8 +903,8 @@ int bvlc6_encode_virtual_address_resolution(uint8_t *pdu, uint16_t pdu_size, * * @return number of bytes decoded */ -int bvlc6_decode_virtual_address_resolution(uint8_t *pdu, uint16_t pdu_len, - uint32_t *vmac_src) +int bvlc6_decode_virtual_address_resolution( + uint8_t *pdu, uint16_t pdu_len, uint32_t *vmac_src) { int bytes_consumed = 0; @@ -913,12 +935,11 @@ int bvlc6_decode_virtual_address_resolution(uint8_t *pdu, uint16_t pdu_len, * Source-Virtual-Address: 3-octets * Destination-Virtual-Address: 3-octets */ -int bvlc6_encode_virtual_address_resolution_ack(uint8_t *pdu, uint16_t pdu_size, - uint32_t vmac_src, - uint32_t vmac_dst) +int bvlc6_encode_virtual_address_resolution_ack( + uint8_t *pdu, uint16_t pdu_size, uint32_t vmac_src, uint32_t vmac_dst) { return bvlc6_encode_address_ack(BVLC6_VIRTUAL_ADDRESS_RESOLUTION_ACK, pdu, - pdu_size, vmac_src, vmac_dst); + pdu_size, vmac_src, vmac_dst); } /** Decode the BVLC Virtual-Address-Resolution-Ack message @@ -930,12 +951,11 @@ int bvlc6_encode_virtual_address_resolution_ack(uint8_t *pdu, uint16_t pdu_size, * * @return number of bytes decoded */ -int bvlc6_decode_virtual_address_resolution_ack(uint8_t *pdu, uint16_t pdu_len, - uint32_t *vmac_src, - uint32_t *vmac_dst) +int bvlc6_decode_virtual_address_resolution_ack( + uint8_t *pdu, uint16_t pdu_len, uint32_t *vmac_src, uint32_t *vmac_dst) { - return bvlc6_decode_address_resolution_ack(pdu, pdu_len, vmac_src, - vmac_dst); + return bvlc6_decode_address_resolution_ack( + pdu, pdu_len, vmac_src, vmac_dst); } /** Encode the BVLC Forwarded-NPDU message @@ -961,10 +981,12 @@ int bvlc6_decode_virtual_address_resolution_ack(uint8_t *pdu, uint16_t pdu_len, * Original-Source-B-IPv6-Address: 18-octets * BACnet NPDU from Originating Device: N-octets (N=L-25) */ -int bvlc6_encode_forwarded_npdu(uint8_t *pdu, uint16_t pdu_size, - uint32_t vmac_src, - BACNET_IP6_ADDRESS *bip6_address, uint8_t *npdu, - uint16_t npdu_len) +int bvlc6_encode_forwarded_npdu(uint8_t *pdu, + uint16_t pdu_size, + uint32_t vmac_src, + BACNET_IP6_ADDRESS *bip6_address, + uint8_t *npdu, + uint16_t npdu_len) { int bytes_encoded = 0; uint16_t length = 1 + 1 + 2 + 3 + BIP6_ADDRESS_MAX; @@ -1005,10 +1027,13 @@ int bvlc6_encode_forwarded_npdu(uint8_t *pdu, uint16_t pdu_size, * * @return number of bytes decoded */ -int bvlc6_decode_forwarded_npdu(uint8_t *pdu, uint16_t pdu_len, - uint32_t *vmac_src, - BACNET_IP6_ADDRESS *bip6_address, uint8_t *npdu, - uint16_t npdu_size, uint16_t *npdu_len) +int bvlc6_decode_forwarded_npdu(uint8_t *pdu, + uint16_t pdu_len, + uint32_t *vmac_src, + BACNET_IP6_ADDRESS *bip6_address, + uint8_t *npdu, + uint16_t npdu_size, + uint16_t *npdu_len) { int bytes_consumed = 0; uint16_t length = 0; @@ -1059,9 +1084,8 @@ int bvlc6_decode_forwarded_npdu(uint8_t *pdu, uint16_t pdu_len, * Source-Virtual-Address: 3-octets * Time-to-Live: 2-octets T Time-to-Live T, in seconds */ -int bvlc6_encode_register_foreign_device(uint8_t *pdu, uint16_t pdu_size, - uint32_t vmac_src, - uint16_t ttl_seconds) +int bvlc6_encode_register_foreign_device( + uint8_t *pdu, uint16_t pdu_size, uint32_t vmac_src, uint16_t ttl_seconds) { int bytes_encoded = 0; const uint16_t length = 9; @@ -1091,9 +1115,8 @@ int bvlc6_encode_register_foreign_device(uint8_t *pdu, uint16_t pdu_size, * * @return number of bytes decoded */ -int bvlc6_decode_register_foreign_device(uint8_t *pdu, uint16_t pdu_len, - uint32_t *vmac_src, - uint16_t *ttl_seconds) +int bvlc6_decode_register_foreign_device( + uint8_t *pdu, uint16_t pdu_len, uint32_t *vmac_src, uint16_t *ttl_seconds) { int bytes_consumed = 0; const uint16_t length = 5; @@ -1132,8 +1155,9 @@ int bvlc6_decode_register_foreign_device(uint8_t *pdu, uint16_t pdu_len, * Source-Virtual-Address: 3-octets * FDT Entry: 18-octets */ -int bvlc6_encode_delete_foreign_device( - uint8_t *pdu, uint16_t pdu_size, uint32_t vmac_src, +int bvlc6_encode_delete_foreign_device(uint8_t *pdu, + uint16_t pdu_size, + uint32_t vmac_src, BACNET_IP6_FOREIGN_DEVICE_TABLE_ENTRY *fdt_entry) { int bytes_encoded = 0; @@ -1148,13 +1172,13 @@ int bvlc6_encode_delete_foreign_device( encode_unsigned24(&pdu[offset], vmac_src); offset += 3; if (fdt_entry) { - bvlc6_encode_address(&pdu[offset], pdu_size - offset, - &fdt_entry->bip6_address); + bvlc6_encode_address( + &pdu[offset], pdu_size - offset, &fdt_entry->bip6_address); offset += BIP6_ADDRESS_MAX; encode_unsigned16(&pdu[offset], fdt_entry->ttl_seconds); offset += 2; - encode_unsigned16(&pdu[offset], - fdt_entry->ttl_seconds_remaining); + encode_unsigned16( + &pdu[offset], fdt_entry->ttl_seconds_remaining); bytes_encoded = (int)length; } } @@ -1172,8 +1196,9 @@ int bvlc6_encode_delete_foreign_device( * * @return number of bytes decoded */ -int bvlc6_decode_delete_foreign_device( - uint8_t *pdu, uint16_t pdu_len, uint32_t *vmac_src, +int bvlc6_decode_delete_foreign_device(uint8_t *pdu, + uint16_t pdu_len, + uint32_t *vmac_src, BACNET_IP6_FOREIGN_DEVICE_TABLE_ENTRY *fdt_entry) { int bytes_consumed = 0; @@ -1188,8 +1213,8 @@ int bvlc6_decode_delete_foreign_device( } offset += 3; if (fdt_entry) { - bvlc6_decode_address(&pdu[offset], pdu_len - offset, - &fdt_entry->bip6_address); + bvlc6_decode_address( + &pdu[offset], pdu_len - offset, &fdt_entry->bip6_address); offset += BIP6_ADDRESS_MAX; decode_unsigned16(&pdu[offset], &fdt_entry->ttl_seconds); offset += 2; @@ -1219,8 +1244,8 @@ int bvlc6_decode_delete_foreign_device( * BVLC Length: 2-octets L Length of the BVLL message * Security Wrapper: Variable length */ -int bvlc6_encode_secure_bvll(uint8_t *pdu, uint16_t pdu_size, uint8_t *sbuf, - uint16_t sbuf_len) +int bvlc6_encode_secure_bvll( + uint8_t *pdu, uint16_t pdu_size, uint8_t *sbuf, uint16_t sbuf_len) { int bytes_encoded = 0; uint16_t length = 4; @@ -1253,8 +1278,11 @@ int bvlc6_encode_secure_bvll(uint8_t *pdu, uint16_t pdu_size, uint8_t *sbuf, * * @return number of bytes decoded */ -int bvlc6_decode_secure_bvll(uint8_t *pdu, uint16_t pdu_len, uint8_t *sbuf, - uint16_t sbuf_size, uint16_t *sbuf_len) +int bvlc6_decode_secure_bvll(uint8_t *pdu, + uint16_t pdu_len, + uint8_t *sbuf, + uint16_t sbuf_size, + uint16_t *sbuf_len) { int bytes_consumed = 0; uint16_t i = 0; @@ -1278,9 +1306,9 @@ int bvlc6_decode_secure_bvll(uint8_t *pdu, uint16_t pdu_len, uint8_t *sbuf, * * This message provides a mechanism whereby a foreign device * shall cause a BBMD to distribute a Forwarded-NPDU - * BVLC to the local multicast domain, to all BBMD’s configured - * in the BBMD’s BDT, and to all foreign devices in the - * BBMD’s FDT. + * BVLC to the local multicast domain, to all BBMD�s configured + * in the BBMD�s BDT, and to all foreign devices in the + * BBMD�s FDT. * * @param pdu - buffer to store the encoding * @param pdu_size - size of the buffer to store encoding @@ -1297,9 +1325,10 @@ int bvlc6_decode_secure_bvll(uint8_t *pdu, uint16_t pdu_len, uint8_t *sbuf, * BACnet NPDU from Originating Device: Variable length */ int bvlc6_encode_distribute_broadcast_to_network(uint8_t *pdu, - uint16_t pdu_size, - uint32_t vmac, uint8_t *npdu, - uint16_t npdu_len) + uint16_t pdu_size, + uint32_t vmac, + uint8_t *npdu, + uint16_t npdu_len) { int bytes_encoded = 0; uint16_t length = 7; @@ -1334,10 +1363,12 @@ int bvlc6_encode_distribute_broadcast_to_network(uint8_t *pdu, * * @return number of bytes decoded */ -int bvlc6_decode_distribute_broadcast_to_network(uint8_t *pdu, uint16_t pdu_len, - uint32_t *vmac, uint8_t *npdu, - uint16_t npdu_size, - uint16_t *npdu_len) +int bvlc6_decode_distribute_broadcast_to_network(uint8_t *pdu, + uint16_t pdu_len, + uint32_t *vmac, + uint8_t *npdu, + uint16_t npdu_size, + uint16_t *npdu_len) { int bytes_consumed = 0; uint16_t length = 0; @@ -1367,8 +1398,9 @@ int bvlc6_decode_distribute_broadcast_to_network(uint8_t *pdu, uint16_t pdu_len, #include #include "ctest.h" -static void test_BVLC6_Address(Test *pTest, BACNET_IP6_ADDRESS *bip6_address_1, - BACNET_IP6_ADDRESS *bip6_address_2) +static void test_BVLC6_Address(Test *pTest, + BACNET_IP6_ADDRESS *bip6_address_1, + BACNET_IP6_ADDRESS *bip6_address_2) { unsigned i = 0; @@ -1376,15 +1408,18 @@ static void test_BVLC6_Address(Test *pTest, BACNET_IP6_ADDRESS *bip6_address_1, ct_test(pTest, bip6_address_1->port == bip6_address_2->port); for (i = 0; i < IP6_ADDRESS_MAX; i++) { ct_test(pTest, - bip6_address_1->address[i] == bip6_address_2->address[i]); + bip6_address_1->address[i] == bip6_address_2->address[i]); } } return; } -static int test_BVLC6_Header(Test *pTest, uint8_t *pdu, uint16_t pdu_len, - uint8_t *message_type, uint16_t *length) +static int test_BVLC6_Header(Test *pTest, + uint8_t *pdu, + uint16_t pdu_len, + uint8_t *message_type, + uint16_t *length) { int bytes_consumed = 0; @@ -1399,10 +1434,10 @@ static int test_BVLC6_Header(Test *pTest, uint8_t *pdu, uint16_t pdu_len, return bytes_consumed; } -static void test_BVLC6_Result_Code(Test *pTest, uint32_t vmac, - uint16_t result_code) +static void test_BVLC6_Result_Code( + Test *pTest, uint32_t vmac, uint16_t result_code) { - uint8_t pdu[50] = {0}; + uint8_t pdu[50] = { 0 }; uint32_t test_vmac = 0; uint16_t test_result_code = 0; uint8_t message_type = 0; @@ -1427,13 +1462,12 @@ static void test_BVLC6_Result_Code(Test *pTest, uint32_t vmac, static void test_BVLC6_Result(Test *pTest) { uint32_t vmac = 0; - uint16_t result_code[6] = { - BVLC6_RESULT_SUCCESSFUL_COMPLETION, + uint16_t result_code[6] = { BVLC6_RESULT_SUCCESSFUL_COMPLETION, BVLC6_RESULT_ADDRESS_RESOLUTION_NAK, BVLC6_RESULT_VIRTUAL_ADDRESS_RESOLUTION_NAK, BVLC6_RESULT_REGISTER_FOREIGN_DEVICE_NAK, BVLC6_RESULT_DELETE_FOREIGN_DEVICE_NAK, - BVLC6_RESULT_DISTRIBUTE_BROADCAST_TO_NETWORK_NAK}; + BVLC6_RESULT_DISTRIBUTE_BROADCAST_TO_NETWORK_NAK }; unsigned int i = 0; vmac = 4194303; @@ -1442,13 +1476,14 @@ static void test_BVLC6_Result(Test *pTest) } } -static void test_BVLC6_Original_Unicast_NPDU_Message(Test *pTest, uint8_t *npdu, - uint16_t npdu_len, - uint32_t vmac_src, - uint32_t vmac_dst) +static void test_BVLC6_Original_Unicast_NPDU_Message(Test *pTest, + uint8_t *npdu, + uint16_t npdu_len, + uint32_t vmac_src, + uint32_t vmac_dst) { - uint8_t test_npdu[50] = {0}; - uint8_t pdu[60] = {0}; + uint8_t test_npdu[50] = { 0 }; + uint8_t pdu[60] = { 0 }; uint32_t test_vmac_src = 0; uint32_t test_vmac_dst = 0; uint16_t test_npdu_len = 0; @@ -1457,17 +1492,17 @@ static void test_BVLC6_Original_Unicast_NPDU_Message(Test *pTest, uint8_t *npdu, int len = 0, msg_len = 0, test_len = 0; uint16_t i = 0; - len = bvlc6_encode_original_unicast(pdu, sizeof(pdu), vmac_src, vmac_dst, - npdu, npdu_len); + len = bvlc6_encode_original_unicast( + pdu, sizeof(pdu), vmac_src, vmac_dst, npdu, npdu_len); msg_len = 10 + npdu_len; ct_test(pTest, len == msg_len); test_len = test_BVLC6_Header(pTest, pdu, len, &message_type, &length); ct_test(pTest, test_len == 4); ct_test(pTest, message_type == BVLC6_ORIGINAL_UNICAST_NPDU); ct_test(pTest, length == msg_len); - test_len += bvlc6_decode_original_unicast( - &pdu[4], length - 4, &test_vmac_src, &test_vmac_dst, test_npdu, - sizeof(test_npdu), &test_npdu_len); + test_len += + bvlc6_decode_original_unicast(&pdu[4], length - 4, &test_vmac_src, + &test_vmac_dst, test_npdu, sizeof(test_npdu), &test_npdu_len); ct_test(pTest, len == test_len); ct_test(pTest, msg_len == test_len); ct_test(pTest, vmac_src == test_vmac_src); @@ -1480,14 +1515,14 @@ static void test_BVLC6_Original_Unicast_NPDU_Message(Test *pTest, uint8_t *npdu, static void test_BVLC6_Original_Unicast_NPDU(Test *pTest) { - uint8_t npdu[50] = {0}; + uint8_t npdu[50] = { 0 }; uint32_t vmac_src = 0; uint32_t vmac_dst = 0; uint16_t npdu_len = 0; uint16_t i = 0; - test_BVLC6_Original_Unicast_NPDU_Message(pTest, npdu, npdu_len, vmac_src, - vmac_dst); + test_BVLC6_Original_Unicast_NPDU_Message( + pTest, npdu, npdu_len, vmac_src, vmac_dst); /* now with some NPDU data */ for (i = 0; i < sizeof(npdu); i++) { npdu[i] = i; @@ -1495,17 +1530,15 @@ static void test_BVLC6_Original_Unicast_NPDU(Test *pTest) npdu_len = sizeof(npdu); vmac_src = 4194303; vmac_dst = 4194302; - test_BVLC6_Original_Unicast_NPDU_Message(pTest, npdu, npdu_len, vmac_src, - vmac_dst); + test_BVLC6_Original_Unicast_NPDU_Message( + pTest, npdu, npdu_len, vmac_src, vmac_dst); } -static void test_BVLC6_Original_Broadcast_NPDU_Message(Test *pTest, - uint8_t *npdu, - uint16_t npdu_len, - uint32_t vmac) +static void test_BVLC6_Original_Broadcast_NPDU_Message( + Test *pTest, uint8_t *npdu, uint16_t npdu_len, uint32_t vmac) { - uint8_t test_npdu[50] = {0}; - uint8_t pdu[60] = {0}; + uint8_t test_npdu[50] = { 0 }; + uint8_t pdu[60] = { 0 }; uint32_t test_vmac = 0; uint16_t test_npdu_len = 0; uint8_t message_type = 0; @@ -1522,8 +1555,7 @@ static void test_BVLC6_Original_Broadcast_NPDU_Message(Test *pTest, ct_test(pTest, message_type == BVLC6_ORIGINAL_BROADCAST_NPDU); ct_test(pTest, length == msg_len); test_len += bvlc6_decode_original_broadcast(&pdu[4], length - 4, &test_vmac, - test_npdu, sizeof(test_npdu), - &test_npdu_len); + test_npdu, sizeof(test_npdu), &test_npdu_len); ct_test(pTest, len == test_len); ct_test(pTest, msg_len == test_len); ct_test(pTest, vmac == test_vmac); @@ -1535,7 +1567,7 @@ static void test_BVLC6_Original_Broadcast_NPDU_Message(Test *pTest, static void test_BVLC6_Original_Broadcast_NPDU(Test *pTest) { - uint8_t npdu[50] = {0}; + uint8_t npdu[50] = { 0 }; uint32_t vmac = 0; uint16_t npdu_len = 0; uint16_t i = 0; @@ -1550,11 +1582,10 @@ static void test_BVLC6_Original_Broadcast_NPDU(Test *pTest) test_BVLC6_Original_Broadcast_NPDU_Message(pTest, npdu, npdu_len, vmac); } -static void test_BVLC6_Address_Resolution_Message(Test *pTest, - uint32_t vmac_src, - uint32_t vmac_target) +static void test_BVLC6_Address_Resolution_Message( + Test *pTest, uint32_t vmac_src, uint32_t vmac_target) { - uint8_t pdu[60] = {0}; + uint8_t pdu[60] = { 0 }; uint32_t test_vmac_src = 0; uint32_t test_vmac_target = 0; uint8_t message_type = 0; @@ -1562,8 +1593,8 @@ static void test_BVLC6_Address_Resolution_Message(Test *pTest, int len = 0, test_len = 0; const int msg_len = 10; - len = bvlc6_encode_address_resolution(pdu, sizeof(pdu), vmac_src, - vmac_target); + len = bvlc6_encode_address_resolution( + pdu, sizeof(pdu), vmac_src, vmac_target); ct_test(pTest, len == msg_len); test_len = test_BVLC6_Header(pTest, pdu, len, &message_type, &length); ct_test(pTest, test_len == 4); @@ -1588,12 +1619,13 @@ static void test_BVLC6_Address_Resolution(Test *pTest) test_BVLC6_Address_Resolution_Message(pTest, vmac_src, vmac_target); } -static void test_BVLC6_Forwarded_Address_Resolution_Message( - Test *pTest, uint32_t vmac_src, uint32_t vmac_dst, +static void test_BVLC6_Forwarded_Address_Resolution_Message(Test *pTest, + uint32_t vmac_src, + uint32_t vmac_dst, BACNET_IP6_ADDRESS *bip6_address) { - BACNET_IP6_ADDRESS test_bip6_address = {{0}}; - uint8_t pdu[60] = {0}; + BACNET_IP6_ADDRESS test_bip6_address = { { 0 } }; + uint8_t pdu[60] = { 0 }; uint32_t test_vmac_src = 0; uint32_t test_vmac_dst = 0; uint8_t message_type = 0; @@ -1601,16 +1633,15 @@ static void test_BVLC6_Forwarded_Address_Resolution_Message( int len = 0, test_len = 0; const int msg_len = 4 + 3 + 3 + BIP6_ADDRESS_MAX; - len = bvlc6_encode_forwarded_address_resolution(pdu, sizeof(pdu), vmac_src, - vmac_dst, bip6_address); + len = bvlc6_encode_forwarded_address_resolution( + pdu, sizeof(pdu), vmac_src, vmac_dst, bip6_address); ct_test(pTest, len == msg_len); test_len = test_BVLC6_Header(pTest, pdu, len, &message_type, &length); ct_test(pTest, test_len == 4); ct_test(pTest, message_type == BVLC6_FORWARDED_ADDRESS_RESOLUTION); ct_test(pTest, length == msg_len); - test_len += bvlc6_decode_forwarded_address_resolution( - &pdu[4], length - 4, &test_vmac_src, &test_vmac_dst, - &test_bip6_address); + test_len += bvlc6_decode_forwarded_address_resolution(&pdu[4], length - 4, + &test_vmac_src, &test_vmac_dst, &test_bip6_address); ct_test(pTest, len == test_len); ct_test(pTest, msg_len == test_len); ct_test(pTest, vmac_src == test_vmac_src); @@ -1620,13 +1651,13 @@ static void test_BVLC6_Forwarded_Address_Resolution_Message( static void test_BVLC6_Forwarded_Address_Resolution(Test *pTest) { - BACNET_IP6_ADDRESS bip6_address = {{0}}; + BACNET_IP6_ADDRESS bip6_address = { { 0 } }; uint32_t vmac_src = 0; uint32_t vmac_target = 0; uint16_t i = 0; - test_BVLC6_Forwarded_Address_Resolution_Message(pTest, vmac_src, - vmac_target, &bip6_address); + test_BVLC6_Forwarded_Address_Resolution_Message( + pTest, vmac_src, vmac_target, &bip6_address); /* now with some address data */ for (i = 0; i < sizeof(bip6_address.address); i++) { bip6_address.address[i] = i; @@ -1634,15 +1665,14 @@ static void test_BVLC6_Forwarded_Address_Resolution(Test *pTest) bip6_address.port = 47808; vmac_src = 4194303; vmac_target = 4194302; - test_BVLC6_Forwarded_Address_Resolution_Message(pTest, vmac_src, - vmac_target, &bip6_address); + test_BVLC6_Forwarded_Address_Resolution_Message( + pTest, vmac_src, vmac_target, &bip6_address); } -static void test_BVLC6_Address_Resolution_Ack_Message(Test *pTest, - uint32_t vmac_src, - uint32_t vmac_dst) +static void test_BVLC6_Address_Resolution_Ack_Message( + Test *pTest, uint32_t vmac_src, uint32_t vmac_dst) { - uint8_t pdu[60] = {0}; + uint8_t pdu[60] = { 0 }; uint32_t test_vmac_src = 0; uint32_t test_vmac_dst = 0; uint8_t message_type = 0; @@ -1650,8 +1680,8 @@ static void test_BVLC6_Address_Resolution_Ack_Message(Test *pTest, int len = 0, test_len = 0; const int msg_len = 10; - len = bvlc6_encode_address_resolution_ack(pdu, sizeof(pdu), vmac_src, - vmac_dst); + len = bvlc6_encode_address_resolution_ack( + pdu, sizeof(pdu), vmac_src, vmac_dst); ct_test(pTest, len == msg_len); test_len = test_BVLC6_Header(pTest, pdu, len, &message_type, &length); ct_test(pTest, test_len == 4); @@ -1676,10 +1706,10 @@ static void test_BVLC6_Address_Resolution_Ack(Test *pTest) test_BVLC6_Address_Resolution_Ack_Message(pTest, vmac_src, vmac_dst); } -static void test_BVLC6_Virtual_Address_Resolution_Message(Test *pTest, - uint32_t vmac_src) +static void test_BVLC6_Virtual_Address_Resolution_Message( + Test *pTest, uint32_t vmac_src) { - uint8_t pdu[60] = {0}; + uint8_t pdu[60] = { 0 }; uint32_t test_vmac_src = 0; uint8_t message_type = 0; uint16_t length = 0; @@ -1692,8 +1722,8 @@ static void test_BVLC6_Virtual_Address_Resolution_Message(Test *pTest, ct_test(pTest, test_len == 4); ct_test(pTest, message_type == BVLC6_VIRTUAL_ADDRESS_RESOLUTION); ct_test(pTest, length == msg_len); - test_len += bvlc6_decode_virtual_address_resolution(&pdu[4], length - 4, - &test_vmac_src); + test_len += bvlc6_decode_virtual_address_resolution( + &pdu[4], length - 4, &test_vmac_src); ct_test(pTest, len == test_len); ct_test(pTest, msg_len == test_len); ct_test(pTest, vmac_src == test_vmac_src); @@ -1708,11 +1738,10 @@ static void test_BVLC6_Virtual_Address_Resolution(Test *pTest) test_BVLC6_Virtual_Address_Resolution_Message(pTest, vmac_src); } -static void test_BVLC6_Virtual_Address_Resolution_Ack_Message(Test *pTest, - uint32_t vmac_src, - uint32_t vmac_dst) +static void test_BVLC6_Virtual_Address_Resolution_Ack_Message( + Test *pTest, uint32_t vmac_src, uint32_t vmac_dst) { - uint8_t pdu[60] = {0}; + uint8_t pdu[60] = { 0 }; uint32_t test_vmac_src = 0; uint32_t test_vmac_dst = 0; uint8_t message_type = 0; @@ -1720,8 +1749,8 @@ static void test_BVLC6_Virtual_Address_Resolution_Ack_Message(Test *pTest, int len = 0, test_len = 0; const int msg_len = 10; - len = bvlc6_encode_virtual_address_resolution_ack(pdu, sizeof(pdu), - vmac_src, vmac_dst); + len = bvlc6_encode_virtual_address_resolution_ack( + pdu, sizeof(pdu), vmac_src, vmac_dst); ct_test(pTest, len == msg_len); test_len = test_BVLC6_Header(pTest, pdu, len, &message_type, &length); ct_test(pTest, test_len == 4); @@ -1740,31 +1769,32 @@ static void test_BVLC6_Virtual_Address_Resolution_Ack(Test *pTest) uint32_t vmac_src = 0; uint32_t vmac_dst = 0; - test_BVLC6_Virtual_Address_Resolution_Ack_Message(pTest, vmac_src, - vmac_dst); + test_BVLC6_Virtual_Address_Resolution_Ack_Message( + pTest, vmac_src, vmac_dst); vmac_src = 4194303; vmac_dst = 4194302; - test_BVLC6_Virtual_Address_Resolution_Ack_Message(pTest, vmac_src, - vmac_dst); + test_BVLC6_Virtual_Address_Resolution_Ack_Message( + pTest, vmac_src, vmac_dst); } -static void test_BVLC6_Forwarded_NPDU_Message(Test *pTest, uint8_t *npdu, - uint16_t npdu_len, - uint32_t vmac_src, - BACNET_IP6_ADDRESS *bip6_address) +static void test_BVLC6_Forwarded_NPDU_Message(Test *pTest, + uint8_t *npdu, + uint16_t npdu_len, + uint32_t vmac_src, + BACNET_IP6_ADDRESS *bip6_address) { - uint8_t test_npdu[50] = {0}; - uint8_t pdu[75] = {0}; + uint8_t test_npdu[50] = { 0 }; + uint8_t pdu[75] = { 0 }; uint32_t test_vmac_src = 0; - BACNET_IP6_ADDRESS test_bip6_address = {{0}}; + BACNET_IP6_ADDRESS test_bip6_address = { { 0 } }; uint16_t test_npdu_len = 0; uint8_t message_type = 0; uint16_t length = 0; int len = 0, msg_len = 0, test_len = 0; uint16_t i = 0; - len = bvlc6_encode_forwarded_npdu(pdu, sizeof(pdu), vmac_src, bip6_address, - npdu, npdu_len); + len = bvlc6_encode_forwarded_npdu( + pdu, sizeof(pdu), vmac_src, bip6_address, npdu, npdu_len); msg_len = 1 + 1 + 2 + 3 + BIP6_ADDRESS_MAX + npdu_len; ct_test(pTest, len == msg_len); test_len = test_BVLC6_Header(pTest, pdu, len, &message_type, &length); @@ -1772,8 +1802,7 @@ static void test_BVLC6_Forwarded_NPDU_Message(Test *pTest, uint8_t *npdu, ct_test(pTest, message_type == BVLC6_FORWARDED_NPDU); ct_test(pTest, length == msg_len); test_len += bvlc6_decode_forwarded_npdu(&pdu[4], length - 4, &test_vmac_src, - &test_bip6_address, test_npdu, - sizeof(test_npdu), &test_npdu_len); + &test_bip6_address, test_npdu, sizeof(test_npdu), &test_npdu_len); ct_test(pTest, len == test_len); ct_test(pTest, msg_len == test_len); ct_test(pTest, vmac_src == test_vmac_src); @@ -1786,14 +1815,14 @@ static void test_BVLC6_Forwarded_NPDU_Message(Test *pTest, uint8_t *npdu, static void test_BVLC6_Forwarded_NPDU(Test *pTest) { - uint8_t npdu[50] = {0}; + uint8_t npdu[50] = { 0 }; uint32_t vmac_src = 0; - BACNET_IP6_ADDRESS bip6_address = {{0}}; + BACNET_IP6_ADDRESS bip6_address = { { 0 } }; uint16_t npdu_len = 0; uint16_t i = 0; - test_BVLC6_Forwarded_NPDU_Message(pTest, npdu, npdu_len, vmac_src, - &bip6_address); + test_BVLC6_Forwarded_NPDU_Message( + pTest, npdu, npdu_len, vmac_src, &bip6_address); for (i = 0; i < sizeof(bip6_address.address); i++) { bip6_address.address[i] = i; } @@ -1804,15 +1833,14 @@ static void test_BVLC6_Forwarded_NPDU(Test *pTest) } npdu_len = sizeof(npdu); vmac_src = 4194303; - test_BVLC6_Forwarded_NPDU_Message(pTest, npdu, npdu_len, vmac_src, - &bip6_address); + test_BVLC6_Forwarded_NPDU_Message( + pTest, npdu, npdu_len, vmac_src, &bip6_address); } -static void test_BVLC6_Register_Foreign_Device_Message(Test *pTest, - uint32_t vmac_src, - uint16_t ttl_seconds) +static void test_BVLC6_Register_Foreign_Device_Message( + Test *pTest, uint32_t vmac_src, uint16_t ttl_seconds) { - uint8_t pdu[60] = {0}; + uint8_t pdu[60] = { 0 }; uint32_t test_vmac_src = 0; uint16_t test_ttl_seconds = 0; uint8_t message_type = 0; @@ -1820,8 +1848,8 @@ static void test_BVLC6_Register_Foreign_Device_Message(Test *pTest, int len = 0, test_len = 0; const int msg_len = 9; - len = bvlc6_encode_register_foreign_device(pdu, sizeof(pdu), vmac_src, - ttl_seconds); + len = bvlc6_encode_register_foreign_device( + pdu, sizeof(pdu), vmac_src, ttl_seconds); ct_test(pTest, len == msg_len); test_len = test_BVLC6_Header(pTest, pdu, len, &message_type, &length); ct_test(pTest, test_len == 4); @@ -1846,20 +1874,20 @@ static void test_BVLC6_Register_Foreign_Device(Test *pTest) test_BVLC6_Register_Foreign_Device_Message(pTest, vmac_src, ttl_seconds); } -static void test_BVLC6_Delete_Foreign_Device_Message( - Test *pTest, uint32_t vmac_src, +static void test_BVLC6_Delete_Foreign_Device_Message(Test *pTest, + uint32_t vmac_src, BACNET_IP6_FOREIGN_DEVICE_TABLE_ENTRY *fdt_entry) { - uint8_t pdu[64] = {0}; + uint8_t pdu[64] = { 0 }; uint32_t test_vmac_src = 0; - BACNET_IP6_FOREIGN_DEVICE_TABLE_ENTRY test_fdt_entry = {0}; + BACNET_IP6_FOREIGN_DEVICE_TABLE_ENTRY test_fdt_entry = { 0 }; uint8_t message_type = 0; uint16_t length = 0; int len = 0, test_len = 0; const int msg_len = 0x0019; - len = bvlc6_encode_delete_foreign_device(pdu, sizeof(pdu), vmac_src, - fdt_entry); + len = bvlc6_encode_delete_foreign_device( + pdu, sizeof(pdu), vmac_src, fdt_entry); ct_test(pTest, len == msg_len); test_len = test_BVLC6_Header(pTest, pdu, len, &message_type, &length); ct_test(pTest, test_len == 4); @@ -1870,17 +1898,18 @@ static void test_BVLC6_Delete_Foreign_Device_Message( ct_test(pTest, len == test_len); ct_test(pTest, msg_len == test_len); ct_test(pTest, vmac_src == test_vmac_src); - test_BVLC6_Address(pTest, &fdt_entry->bip6_address, - &test_fdt_entry.bip6_address); + test_BVLC6_Address( + pTest, &fdt_entry->bip6_address, &test_fdt_entry.bip6_address); ct_test(pTest, fdt_entry->ttl_seconds == test_fdt_entry.ttl_seconds); - ct_test(pTest, fdt_entry->ttl_seconds_remaining == - test_fdt_entry.ttl_seconds_remaining); + ct_test(pTest, + fdt_entry->ttl_seconds_remaining == + test_fdt_entry.ttl_seconds_remaining); } static void test_BVLC6_Delete_Foreign_Device(Test *pTest) { uint32_t vmac_src = 0; - BACNET_IP6_FOREIGN_DEVICE_TABLE_ENTRY fdt_entry = {0}; + BACNET_IP6_FOREIGN_DEVICE_TABLE_ENTRY fdt_entry = { 0 }; unsigned int i = 0; /* test with zeros */ @@ -1897,11 +1926,11 @@ static void test_BVLC6_Delete_Foreign_Device(Test *pTest) test_BVLC6_Delete_Foreign_Device_Message(pTest, vmac_src, &fdt_entry); } -static void test_BVLC6_Secure_BVLL_Message(Test *pTest, uint8_t *sbuf, - uint16_t sbuf_len) +static void test_BVLC6_Secure_BVLL_Message( + Test *pTest, uint8_t *sbuf, uint16_t sbuf_len) { - uint8_t test_sbuf[50] = {0}; - uint8_t pdu[60] = {0}; + uint8_t test_sbuf[50] = { 0 }; + uint8_t pdu[60] = { 0 }; uint16_t test_sbuf_len = 0; uint8_t message_type = 0; uint16_t length = 0; @@ -1915,8 +1944,8 @@ static void test_BVLC6_Secure_BVLL_Message(Test *pTest, uint8_t *sbuf, ct_test(pTest, test_len == 4); ct_test(pTest, message_type == BVLC6_SECURE_BVLL); ct_test(pTest, length == msg_len); - test_len += bvlc6_decode_secure_bvll(&pdu[4], length - 4, test_sbuf, - sizeof(test_sbuf), &test_sbuf_len); + test_len += bvlc6_decode_secure_bvll( + &pdu[4], length - 4, test_sbuf, sizeof(test_sbuf), &test_sbuf_len); ct_test(pTest, len == test_len); ct_test(pTest, msg_len == test_len); ct_test(pTest, sbuf_len == test_sbuf_len); @@ -1927,7 +1956,7 @@ static void test_BVLC6_Secure_BVLL_Message(Test *pTest, uint8_t *sbuf, static void test_BVLC6_Secure_BVLL(Test *pTest) { - uint8_t sbuf[50] = {0}; + uint8_t sbuf[50] = { 0 }; uint16_t sbuf_len = 0; uint16_t i = 0; @@ -1943,8 +1972,8 @@ static void test_BVLC6_Secure_BVLL(Test *pTest) static void test_BVLC6_Distribute_Broadcast_To_Network_Message( Test *pTest, uint8_t *npdu, uint16_t npdu_len, uint32_t vmac) { - uint8_t test_npdu[50] = {0}; - uint8_t pdu[60] = {0}; + uint8_t test_npdu[50] = { 0 }; + uint8_t pdu[60] = { 0 }; uint32_t test_vmac = 0; uint16_t test_npdu_len = 0; uint8_t message_type = 0; @@ -1952,17 +1981,16 @@ static void test_BVLC6_Distribute_Broadcast_To_Network_Message( int len = 0, msg_len = 0, test_len = 0; uint16_t i = 0; - len = bvlc6_encode_distribute_broadcast_to_network(pdu, sizeof(pdu), vmac, - npdu, npdu_len); + len = bvlc6_encode_distribute_broadcast_to_network( + pdu, sizeof(pdu), vmac, npdu, npdu_len); msg_len = 7 + npdu_len; ct_test(pTest, len == msg_len); test_len = test_BVLC6_Header(pTest, pdu, len, &message_type, &length); ct_test(pTest, test_len == 4); ct_test(pTest, message_type == BVLC6_DISTRIBUTE_BROADCAST_TO_NETWORK); ct_test(pTest, length == msg_len); - test_len += bvlc6_decode_distribute_broadcast_to_network( - &pdu[4], length - 4, &test_vmac, test_npdu, sizeof(test_npdu), - &test_npdu_len); + test_len += bvlc6_decode_distribute_broadcast_to_network(&pdu[4], + length - 4, &test_vmac, test_npdu, sizeof(test_npdu), &test_npdu_len); ct_test(pTest, len == test_len); ct_test(pTest, msg_len == test_len); ct_test(pTest, vmac == test_vmac); @@ -1974,28 +2002,28 @@ static void test_BVLC6_Distribute_Broadcast_To_Network_Message( static void test_BVLC6_Distribute_Broadcast_To_Network(Test *pTest) { - uint8_t npdu[50] = {0}; + uint8_t npdu[50] = { 0 }; uint32_t vmac = 0; uint16_t npdu_len = 0; uint16_t i = 0; - test_BVLC6_Distribute_Broadcast_To_Network_Message(pTest, npdu, npdu_len, - vmac); + test_BVLC6_Distribute_Broadcast_To_Network_Message( + pTest, npdu, npdu_len, vmac); /* now with some NPDU data */ for (i = 0; i < sizeof(npdu); i++) { npdu[i] = i; } npdu_len = sizeof(npdu); vmac = 4194303; - test_BVLC6_Distribute_Broadcast_To_Network_Message(pTest, npdu, npdu_len, - vmac); + test_BVLC6_Distribute_Broadcast_To_Network_Message( + pTest, npdu, npdu_len, vmac); } static void test_BVLC6_Address_Copy(Test *pTest) { unsigned int i = 0; - BACNET_IP6_ADDRESS src = {{0}}; - BACNET_IP6_ADDRESS dst = {{0}}; + BACNET_IP6_ADDRESS src = { { 0 } }; + BACNET_IP6_ADDRESS dst = { { 0 } }; bool status = false; /* test with zeros */ @@ -2029,7 +2057,7 @@ static void test_BVLC6_Address_Copy(Test *pTest) static void test_BVLC6_Address_Get_Set(Test *pTest) { uint16_t i = 0; - BACNET_IP6_ADDRESS src = {{0}}; + BACNET_IP6_ADDRESS src = { { 0 } }; uint16_t group = 1; uint16_t test_group = 0; bool status = false; @@ -2037,8 +2065,8 @@ static void test_BVLC6_Address_Get_Set(Test *pTest) for (i = 0; i < 16; i++) { status = bvlc6_address_set(&src, group, 0, 0, 0, 0, 0, 0, 0); ct_test(pTest, status); - status = bvlc6_address_get(&src, &test_group, NULL, NULL, NULL, NULL, - NULL, NULL, NULL); + status = bvlc6_address_get( + &src, &test_group, NULL, NULL, NULL, NULL, NULL, NULL, NULL); ct_test(pTest, status); ct_test(pTest, group == test_group); group = group << 1; diff --git a/include/bvlc6.h b/src/bacnet/datalink/bvlc6.h similarity index 95% rename from include/bvlc6.h rename to src/bacnet/datalink/bvlc6.h index 52badfdb..c7c25ab0 100644 --- a/include/bvlc6.h +++ b/src/bacnet/datalink/bvlc6.h @@ -13,8 +13,8 @@ #include #include #include -#include "bacdef.h" -#include "npdu.h" +#include "bacnet/bacdef.h" +#include "bacnet/npdu.h" /** * BVLL for BACnet/IPv6 @@ -375,22 +375,6 @@ extern "C" { uint16_t npdu_size, uint16_t * npdu_len); - /* user application function prototypes */ - int bvlc6_handler( - BACNET_IP6_ADDRESS *addr, - BACNET_ADDRESS * src, - uint8_t * npdu, - uint16_t npdu_len); - int bvlc6_register_with_bbmd( - BACNET_IP6_ADDRESS *bbmd_addr, - uint32_t vmac_src, - uint16_t time_to_live_seconds); - uint16_t bvlc6_get_last_result( - void); - uint8_t bvlc6_get_function_code( - void); - void bvlc6_init(void); - #ifdef TEST #include "ctest.h" void test_BVLC6( diff --git a/src/crc.c b/src/bacnet/datalink/crc.c similarity index 60% rename from src/crc.c rename to src/bacnet/datalink/crc.c index 1ed2ad59..c319c247 100644 --- a/src/crc.c +++ b/src/bacnet/datalink/crc.c @@ -41,29 +41,28 @@ #if defined(CRC_USE_TABLE) /* note: table is created using unit test below */ -static const uint8_t HeaderCRC[256] = { - 0x00, 0xfe, 0xff, 0x01, 0xfd, 0x03, 0x02, 0xfc, 0xf9, 0x07, 0x06, 0xf8, - 0x04, 0xfa, 0xfb, 0x05, 0xf1, 0x0f, 0x0e, 0xf0, 0x0c, 0xf2, 0xf3, 0x0d, - 0x08, 0xf6, 0xf7, 0x09, 0xf5, 0x0b, 0x0a, 0xf4, 0xe1, 0x1f, 0x1e, 0xe0, - 0x1c, 0xe2, 0xe3, 0x1d, 0x18, 0xe6, 0xe7, 0x19, 0xe5, 0x1b, 0x1a, 0xe4, - 0x10, 0xee, 0xef, 0x11, 0xed, 0x13, 0x12, 0xec, 0xe9, 0x17, 0x16, 0xe8, - 0x14, 0xea, 0xeb, 0x15, 0xc1, 0x3f, 0x3e, 0xc0, 0x3c, 0xc2, 0xc3, 0x3d, - 0x38, 0xc6, 0xc7, 0x39, 0xc5, 0x3b, 0x3a, 0xc4, 0x30, 0xce, 0xcf, 0x31, - 0xcd, 0x33, 0x32, 0xcc, 0xc9, 0x37, 0x36, 0xc8, 0x34, 0xca, 0xcb, 0x35, - 0x20, 0xde, 0xdf, 0x21, 0xdd, 0x23, 0x22, 0xdc, 0xd9, 0x27, 0x26, 0xd8, - 0x24, 0xda, 0xdb, 0x25, 0xd1, 0x2f, 0x2e, 0xd0, 0x2c, 0xd2, 0xd3, 0x2d, - 0x28, 0xd6, 0xd7, 0x29, 0xd5, 0x2b, 0x2a, 0xd4, 0x81, 0x7f, 0x7e, 0x80, - 0x7c, 0x82, 0x83, 0x7d, 0x78, 0x86, 0x87, 0x79, 0x85, 0x7b, 0x7a, 0x84, - 0x70, 0x8e, 0x8f, 0x71, 0x8d, 0x73, 0x72, 0x8c, 0x89, 0x77, 0x76, 0x88, - 0x74, 0x8a, 0x8b, 0x75, 0x60, 0x9e, 0x9f, 0x61, 0x9d, 0x63, 0x62, 0x9c, - 0x99, 0x67, 0x66, 0x98, 0x64, 0x9a, 0x9b, 0x65, 0x91, 0x6f, 0x6e, 0x90, - 0x6c, 0x92, 0x93, 0x6d, 0x68, 0x96, 0x97, 0x69, 0x95, 0x6b, 0x6a, 0x94, - 0x40, 0xbe, 0xbf, 0x41, 0xbd, 0x43, 0x42, 0xbc, 0xb9, 0x47, 0x46, 0xb8, - 0x44, 0xba, 0xbb, 0x45, 0xb1, 0x4f, 0x4e, 0xb0, 0x4c, 0xb2, 0xb3, 0x4d, - 0x48, 0xb6, 0xb7, 0x49, 0xb5, 0x4b, 0x4a, 0xb4, 0xa1, 0x5f, 0x5e, 0xa0, - 0x5c, 0xa2, 0xa3, 0x5d, 0x58, 0xa6, 0xa7, 0x59, 0xa5, 0x5b, 0x5a, 0xa4, - 0x50, 0xae, 0xaf, 0x51, 0xad, 0x53, 0x52, 0xac, 0xa9, 0x57, 0x56, 0xa8, - 0x54, 0xaa, 0xab, 0x55}; +static const uint8_t HeaderCRC[256] = { 0x00, 0xfe, 0xff, 0x01, 0xfd, 0x03, + 0x02, 0xfc, 0xf9, 0x07, 0x06, 0xf8, 0x04, 0xfa, 0xfb, 0x05, 0xf1, 0x0f, + 0x0e, 0xf0, 0x0c, 0xf2, 0xf3, 0x0d, 0x08, 0xf6, 0xf7, 0x09, 0xf5, 0x0b, + 0x0a, 0xf4, 0xe1, 0x1f, 0x1e, 0xe0, 0x1c, 0xe2, 0xe3, 0x1d, 0x18, 0xe6, + 0xe7, 0x19, 0xe5, 0x1b, 0x1a, 0xe4, 0x10, 0xee, 0xef, 0x11, 0xed, 0x13, + 0x12, 0xec, 0xe9, 0x17, 0x16, 0xe8, 0x14, 0xea, 0xeb, 0x15, 0xc1, 0x3f, + 0x3e, 0xc0, 0x3c, 0xc2, 0xc3, 0x3d, 0x38, 0xc6, 0xc7, 0x39, 0xc5, 0x3b, + 0x3a, 0xc4, 0x30, 0xce, 0xcf, 0x31, 0xcd, 0x33, 0x32, 0xcc, 0xc9, 0x37, + 0x36, 0xc8, 0x34, 0xca, 0xcb, 0x35, 0x20, 0xde, 0xdf, 0x21, 0xdd, 0x23, + 0x22, 0xdc, 0xd9, 0x27, 0x26, 0xd8, 0x24, 0xda, 0xdb, 0x25, 0xd1, 0x2f, + 0x2e, 0xd0, 0x2c, 0xd2, 0xd3, 0x2d, 0x28, 0xd6, 0xd7, 0x29, 0xd5, 0x2b, + 0x2a, 0xd4, 0x81, 0x7f, 0x7e, 0x80, 0x7c, 0x82, 0x83, 0x7d, 0x78, 0x86, + 0x87, 0x79, 0x85, 0x7b, 0x7a, 0x84, 0x70, 0x8e, 0x8f, 0x71, 0x8d, 0x73, + 0x72, 0x8c, 0x89, 0x77, 0x76, 0x88, 0x74, 0x8a, 0x8b, 0x75, 0x60, 0x9e, + 0x9f, 0x61, 0x9d, 0x63, 0x62, 0x9c, 0x99, 0x67, 0x66, 0x98, 0x64, 0x9a, + 0x9b, 0x65, 0x91, 0x6f, 0x6e, 0x90, 0x6c, 0x92, 0x93, 0x6d, 0x68, 0x96, + 0x97, 0x69, 0x95, 0x6b, 0x6a, 0x94, 0x40, 0xbe, 0xbf, 0x41, 0xbd, 0x43, + 0x42, 0xbc, 0xb9, 0x47, 0x46, 0xb8, 0x44, 0xba, 0xbb, 0x45, 0xb1, 0x4f, + 0x4e, 0xb0, 0x4c, 0xb2, 0xb3, 0x4d, 0x48, 0xb6, 0xb7, 0x49, 0xb5, 0x4b, + 0x4a, 0xb4, 0xa1, 0x5f, 0x5e, 0xa0, 0x5c, 0xa2, 0xa3, 0x5d, 0x58, 0xa6, + 0xa7, 0x59, 0xa5, 0x5b, 0x5a, 0xa4, 0x50, 0xae, 0xaf, 0x51, 0xad, 0x53, + 0x52, 0xac, 0xa9, 0x57, 0x56, 0xa8, 0x54, 0xaa, 0xab, 0x55 }; uint8_t CRC_Calc_Header(uint8_t dataValue, uint8_t crcValue) { @@ -71,36 +70,35 @@ uint8_t CRC_Calc_Header(uint8_t dataValue, uint8_t crcValue) } /* note: table is created using unit test below */ -static const uint16_t DataCRC[256] = { - 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, 0x8c48, - 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7, 0x1081, 0x0108, - 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, 0x9cc9, 0x8d40, 0xbfdb, - 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876, 0x2102, 0x308b, 0x0210, 0x1399, - 0x6726, 0x76af, 0x4434, 0x55bd, 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, - 0xfae7, 0xc87c, 0xd9f5, 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, - 0x54b5, 0x453c, 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, - 0xc974, 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb, - 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3, 0x5285, - 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a, 0xdecd, 0xcf44, - 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72, 0x6306, 0x728f, 0x4014, - 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, 0xef4e, 0xfec7, 0xcc5c, 0xddd5, - 0xa96a, 0xb8e3, 0x8a78, 0x9bf1, 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, - 0x242a, 0x16b1, 0x0738, 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, - 0x9af9, 0x8b70, 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, - 0xf0b7, 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff, - 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, 0x18c1, - 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, 0xa50a, 0xb483, - 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5, 0x2942, 0x38cb, 0x0a50, - 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, 0xb58b, 0xa402, 0x9699, 0x8710, - 0xf3af, 0xe226, 0xd0bd, 0xc134, 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, - 0x6e6e, 0x5cf5, 0x4d7c, 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, - 0xa33a, 0xb2b3, 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, - 0x3efb, 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, - 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a, 0xe70e, - 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1, 0x6b46, 0x7acf, - 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9, 0xf78f, 0xe606, 0xd49d, - 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, 0x7bc7, 0x6a4e, 0x58d5, 0x495c, - 0x3de3, 0x2c6a, 0x1ef1, 0x0f78}; +static const uint16_t DataCRC[256] = { 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, + 0x57ad, 0x6536, 0x74bf, 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, + 0xe97e, 0xf8f7, 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, + 0x643e, 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876, + 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, 0xad4a, + 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, 0x3183, 0x200a, + 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c, 0xbdcb, 0xac42, 0x9ed9, + 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974, 0x4204, 0x538d, 0x6116, 0x709f, + 0x0420, 0x15a9, 0x2732, 0x36bb, 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, + 0x99e1, 0xab7a, 0xbaf3, 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, + 0x37b3, 0x263a, 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, + 0xaa72, 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, + 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1, 0x7387, + 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, 0xffcf, 0xee46, + 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70, 0x8408, 0x9581, 0xa71a, + 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, 0x0840, 0x19c9, 0x2b52, 0x3adb, + 0x4e64, 0x5fed, 0x6d76, 0x7cff, 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, + 0xc324, 0xf1bf, 0xe036, 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, + 0x7df7, 0x6c7e, 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, + 0xd1b5, 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, + 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134, 0x39c3, + 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c, 0xc60c, 0xd785, + 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3, 0x4a44, 0x5bcd, 0x6956, + 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb, 0xd68d, 0xc704, 0xf59f, 0xe416, + 0x90a9, 0x8120, 0xb3bb, 0xa232, 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, + 0x0d68, 0x3ff3, 0x2e7a, 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, + 0x8238, 0x93b1, 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, + 0x1ff9, 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, + 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78 }; uint16_t CRC_Calc_Data(uint8_t dataValue, uint16_t crcValue) { @@ -120,7 +118,7 @@ uint8_t CRC_Calc_Header(uint8_t dataValue, uint8_t crcValue) /* Exclusive OR the terms in the table (top down) */ crc = crc ^ (crc << 1) ^ (crc << 2) ^ (crc << 3) ^ (crc << 4) ^ (crc << 5) ^ - (crc << 6) ^ (crc << 7); + (crc << 6) ^ (crc << 7); /* Combine bits shifted out left hand end */ return (crc & 0xfe) ^ ((crc >> 8) & 1); @@ -139,7 +137,7 @@ uint16_t CRC_Calc_Data(uint8_t dataValue, uint16_t crcValue) /* Exclusive OR the terms in the table (top down) */ return (crcValue >> 8) ^ (crcLow << 8) ^ (crcLow << 3) ^ (crcLow << 12) ^ - (crcLow >> 4) ^ (crcLow & 0x0f) ^ ((crcLow & 0x0f) << 7); + (crcLow >> 4) ^ (crcLow & 0x0f) ^ ((crcLow & 0x0f) << 7); } #endif @@ -147,13 +145,13 @@ uint16_t CRC_Calc_Data(uint8_t dataValue, uint16_t crcValue) #include #include #include "ctest.h" -#include "bytes.h" +#include "bacnet/bytes.h" /* test from Annex G 1.0 of BACnet Standard */ void testCRC8(Test *pTest) { uint8_t crc = 0xff; /* accumulates the crc value */ - uint8_t frame_crc; /* appended to the end of the frame */ + uint8_t frame_crc; /* appended to the end of the frame */ crc = CRC_Calc_Header(0x00, crc); ct_test(pTest, crc == 0x55); diff --git a/include/crc.h b/src/bacnet/datalink/crc.h similarity index 100% rename from include/crc.h rename to src/bacnet/datalink/crc.h diff --git a/src/datalink.c b/src/bacnet/datalink/datalink.c similarity index 88% rename from src/datalink.c rename to src/bacnet/datalink/datalink.c index 72697b76..5c75ea7b 100644 --- a/src/datalink.c +++ b/src/bacnet/datalink/datalink.c @@ -32,15 +32,15 @@ ------------------------------------------- ####COPYRIGHTEND####*/ /** @file datalink.c Optional run-time assignment of datalink transport */ -#include "datalink.h" +#include "bacnet/datalink/datalink.h" #if defined(BACDL_ALL) || defined FOR_DOXYGEN -#include "ethernet.h" -#include "bip.h" -#include "bip6.h" -#include "bvlc.h" -#include "arcnet.h" -#include "dlmstp.h" +#include "bacnet/datalink/ethernet.h" +#include "bacnet/datalink/bip.h" +#include "bacnet/datalink/bip6.h" +#include "bacnet/datalink/bvlc.h" +#include "bacnet/datalink/arcnet.h" +#include "bacnet/datalink/dlmstp.h" #include /* Function pointers - point to your datalink */ @@ -67,11 +67,13 @@ bool (*datalink_init)(char *ifname); * @param pdu_len [in] Number of bytes in the pdu buffer. * @return Number of bytes sent on success, negative number on failure. */ -int (*datalink_send_pdu)(BACNET_ADDRESS *dest, BACNET_NPDU_DATA *npdu_data, - uint8_t *pdu, unsigned pdu_len); +int (*datalink_send_pdu)(BACNET_ADDRESS *dest, + BACNET_NPDU_DATA *npdu_data, + uint8_t *pdu, + unsigned pdu_len); -uint16_t (*datalink_receive)(BACNET_ADDRESS *src, uint8_t *pdu, - uint16_t max_pdu, unsigned timeout); +uint16_t (*datalink_receive)( + BACNET_ADDRESS *src, uint8_t *pdu, uint16_t max_pdu, unsigned timeout); /** Function template to close the DataLink services and perform any cleanup. * @ingroup DLTemplates @@ -138,14 +140,16 @@ void datalink_set(char *datalink_string) #endif #if defined(BACDL_NONE) -int datalink_send_pdu(BACNET_ADDRESS *dest, BACNET_NPDU_DATA *npdu_data, - uint8_t *pdu, unsigned pdu_len) +int datalink_send_pdu(BACNET_ADDRESS *dest, + BACNET_NPDU_DATA *npdu_data, + uint8_t *pdu, + unsigned pdu_len) { return 0; } -uint16_t datalink_receive(BACNET_ADDRESS *src, uint8_t *pdu, uint16_t max_pdu, - unsigned timeout) +uint16_t datalink_receive( + BACNET_ADDRESS *src, uint8_t *pdu, uint16_t max_pdu, unsigned timeout) { return 0; } diff --git a/include/datalink.h b/src/bacnet/datalink/datalink.h similarity index 94% rename from include/datalink.h rename to src/bacnet/datalink/datalink.h index 7d790f1a..3b19b81f 100644 --- a/include/datalink.h +++ b/src/bacnet/datalink/datalink.h @@ -24,11 +24,11 @@ #ifndef DATALINK_H #define DATALINK_H -#include "config.h" -#include "bacdef.h" +#include "bacnet/config.h" +#include "bacnet/bacdef.h" #if defined(BACDL_ETHERNET) -#include "ethernet.h" +#include "bacnet/datalink/ethernet.h" #define datalink_init ethernet_init #define datalink_send_pdu ethernet_send_pdu @@ -38,7 +38,7 @@ #define datalink_get_my_address ethernet_get_my_address #elif defined(BACDL_ARCNET) -#include "arcnet.h" +#include "bacnet/datalink/arcnet.h" #define datalink_init arcnet_init #define datalink_send_pdu arcnet_send_pdu @@ -48,7 +48,7 @@ #define datalink_get_my_address arcnet_get_my_address #elif defined(BACDL_MSTP) -#include "dlmstp.h" +#include "bacnet/datalink/dlmstp.h" #define datalink_init dlmstp_init #define datalink_send_pdu dlmstp_send_pdu @@ -58,8 +58,8 @@ #define datalink_get_my_address dlmstp_get_my_address #elif defined(BACDL_BIP) -#include "bip.h" -#include "bvlc.h" +#include "bacnet/datalink/bip.h" +#include "bacnet/datalink/bvlc.h" #define datalink_init bip_init #if defined(BBMD_ENABLED) && BBMD_ENABLED @@ -80,8 +80,8 @@ extern void routed_get_my_address( #endif #elif defined(BACDL_BIP6) -#include "bip6.h" -#include "bvlc6.h" +#include "bacnet/datalink/bip6.h" +#include "bacnet/datalink/bvlc6.h" #define datalink_init bip6_init #define datalink_send_pdu bip6_send_pdu #define datalink_receive bip6_receive @@ -90,7 +90,7 @@ extern void routed_get_my_address( #define datalink_get_my_address bip6_get_my_address #elif defined(BACDL_ALL) || defined(BACDL_NONE) -#include "npdu.h" +#include "bacnet/npdu.h" #define MAX_HEADER (8) #define MAX_MPDU (MAX_HEADER+MAX_PDU) diff --git a/demo/handler/dlenv.c b/src/bacnet/datalink/dlenv.c similarity index 94% rename from demo/handler/dlenv.c rename to src/bacnet/datalink/dlenv.c index f82a603b..8cddc4da 100644 --- a/demo/handler/dlenv.c +++ b/src/bacnet/datalink/dlenv.c @@ -28,15 +28,15 @@ #include #include #include -#include "config.h" -#include "bacdef.h" -#include "apdu.h" -#include "datalink.h" -#include "handlers.h" -#include "dlenv.h" -#include "tsm.h" +#include "bacnet/config.h" +#include "bacnet/bacdef.h" +#include "bacnet/apdu.h" +#include "bacnet/datalink/datalink.h" +#include "bacnet/basic/services.h" +#include "bacnet/datalink/dlenv.h" +#include "bacnet/basic/tsm/tsm.h" #if (BACNET_PROTOCOL_REVISION >= 17) -#include "netport.h" +#include "bacnet/basic/object/netport.h" #endif /** @file dlenv.c Initialize the DataLink configuration. */ @@ -94,8 +94,9 @@ void dlenv_bbmd_ttl_set(int ttl_secs) int dlenv_bbmd_result(void) { if ((bbmd_result > 0) && - (bvlc_get_last_result() == BVLC_RESULT_REGISTER_FOREIGN_DEVICE_NAK)) + (bvlc_get_last_result() == BVLC_RESULT_REGISTER_FOREIGN_DEVICE_NAK)) { return -1; + } /* Else, show our send: */ return bbmd_result; } @@ -120,7 +121,7 @@ int dlenv_register_as_foreign_device(void) int retval = 0; #if defined(BACDL_BIP) char *pEnv = NULL; - unsigned a[4] = {0}; + unsigned a[4] = { 0 }; char bbmd_env[32] = ""; unsigned entry_number = 0; int c; @@ -147,13 +148,13 @@ int dlenv_register_as_foreign_device(void) struct in_addr addr; addr.s_addr = bbmd_address; fprintf(stderr, "Registering with BBMD at %s:%ld for %ld seconds\n", - inet_ntoa(addr), bbmd_port, bbmd_timetolive_seconds); - retval = - bvlc_register_with_bbmd(bbmd_address, htons((uint16_t)bbmd_port), - (uint16_t)bbmd_timetolive_seconds); - if (retval < 0) + inet_ntoa(addr), bbmd_port, bbmd_timetolive_seconds); + retval = bvlc_register_with_bbmd(bbmd_address, + htons((uint16_t)bbmd_port), (uint16_t)bbmd_timetolive_seconds); + if (retval < 0) { fprintf(stderr, "FAILED to Register with BBMD at %s \n", - inet_ntoa(addr)); + inet_ntoa(addr)); + } BBMD_Timer_Seconds = (uint16_t)bbmd_timetolive_seconds; } else { for (entry_number = 1; entry_number <= 128; entry_number++) { @@ -182,12 +183,12 @@ int dlenv_register_as_foreign_device(void) sprintf(bbmd_env, "BACNET_BDT_MASK_%u", entry_number); pEnv = getenv(bbmd_env); if (pEnv) { - c = sscanf(pEnv, "%3u.%3u.%3u.%3u", &a[0], &a[1], &a[2], - &a[3]); + c = sscanf( + pEnv, "%3u.%3u.%3u.%3u", &a[0], &a[1], &a[2], &a[3]); if (c == 4) { bbmd_mask = ((a[0] & 0xFF) << 24) | - ((a[1] & 0xFF) << 16) | - ((a[2] & 0xFF) << 8) | (a[3] & 0xFF); + ((a[1] & 0xFF) << 16) | ((a[2] & 0xFF) << 8) | + (a[3] & 0xFF); } } BBMD_Table_Entry.valid = true; @@ -216,7 +217,7 @@ static void dlenv_network_port_init(void) uint32_t test_broadcast = 0; uint32_t mask = 0; uint16_t port = 0; - uint8_t mac[4 + 2] = {0}; + uint8_t mac[4 + 2] = { 0 }; uint8_t prefix = 0; Network_Port_Object_Instance_Number_Set(0, instance); @@ -255,7 +256,7 @@ static void dlenv_network_port_init(void) static void dlenv_network_port_init(void) { uint32_t instance = 1; - uint8_t mac[1] = {0}; + uint8_t mac[1] = { 0 }; Network_Port_Object_Instance_Number_Set(0, instance); Network_Port_Name_Set(instance, "MS/TP Port"); @@ -283,8 +284,8 @@ static void dlenv_network_port_init(void) { uint32_t instance = 1; uint8_t prefix = 0; - BACNET_ADDRESS addr = {0}; - BACNET_IP6_ADDRESS addr6 = {0}; + BACNET_ADDRESS addr = { 0 }; + BACNET_IP6_ADDRESS addr6 = { 0 }; Network_Port_Object_Instance_Number_Set(0, instance); Network_Port_Name_Set(instance, "BACnet/IPv6 Port"); @@ -412,11 +413,11 @@ void dlenv_init(void) pEnv = getenv("BACNET_BIP6_BROADCAST"); if (pEnv) { bvlc6_address_set(&addr, (uint16_t)strtol(pEnv, NULL, 0), 0, 0, 0, 0, 0, - 0, BIP6_MULTICAST_GROUP_ID); + 0, BIP6_MULTICAST_GROUP_ID); bip6_set_broadcast_addr(&addr); } else { bvlc6_address_set(&addr, BIP6_MULTICAST_SITE_LOCAL, 0, 0, 0, 0, 0, 0, - BIP6_MULTICAST_GROUP_ID); + BIP6_MULTICAST_GROUP_ID); bip6_set_broadcast_addr(&addr); } pEnv = getenv("BACNET_BIP6_PORT"); @@ -440,8 +441,9 @@ void dlenv_init(void) * Unless it is set below 1024, since: * "The range for well-known ports managed by the IANA is 0-1023." */ - if (ntohs(bip_get_port()) < 1024) + if (ntohs(bip_get_port()) < 1024) { bip_set_port(htons(0xBAC0)); + } } pEnv = getenv("BACNET_IP_NAT_ADDR"); if (pEnv) { diff --git a/include/dlenv.h b/src/bacnet/datalink/dlenv.h similarity index 100% rename from include/dlenv.h rename to src/bacnet/datalink/dlenv.h diff --git a/include/dlmstp.h b/src/bacnet/datalink/dlmstp.h similarity index 98% rename from include/dlmstp.h rename to src/bacnet/datalink/dlmstp.h index 6b4fc35d..05d4185e 100644 --- a/include/dlmstp.h +++ b/src/bacnet/datalink/dlmstp.h @@ -27,8 +27,8 @@ #include #include #include -#include "bacdef.h" -#include "npdu.h" +#include "bacnet/bacdef.h" +#include "bacnet/npdu.h" /* defines specific to MS/TP */ /* preamble+type+dest+src+len+crc8+crc16 */ diff --git a/include/ethernet.h b/src/bacnet/datalink/ethernet.h similarity index 98% rename from include/ethernet.h rename to src/bacnet/datalink/ethernet.h index a2c918e5..61f3be9f 100644 --- a/include/ethernet.h +++ b/src/bacnet/datalink/ethernet.h @@ -27,8 +27,8 @@ #include #include #include -#include "bacdef.h" -#include "npdu.h" +#include "bacnet/bacdef.h" +#include "bacnet/npdu.h" /* specific defines for Ethernet */ #define MAX_HEADER (6+6+2+1+1+1) diff --git a/src/mstp.c b/src/bacnet/datalink/mstp.c similarity index 91% rename from src/mstp.c rename to src/bacnet/datalink/mstp.c index b60508f1..1482b14c 100644 --- a/src/mstp.c +++ b/src/bacnet/datalink/mstp.c @@ -51,14 +51,14 @@ #if PRINT_ENABLED #include #endif -#include "mstp.h" +#include "bacnet/datalink/mstp.h" #include "crc.h" #include "rs485.h" -#include "mstptext.h" +#include "bacnet/datalink/mstptext.h" #if !defined(DEBUG_ENABLED) #define DEBUG_ENABLED 1 #endif -#include "debug.h" +#include "bacnet/basic/sys/debug.h" #if PRINT_ENABLED #undef PRINT_ENABLED_RECEIVE @@ -192,22 +192,22 @@ void MSTP_Fill_BACnet_Address(BACNET_ADDRESS *src, uint8_t mstp_address) } } -uint16_t MSTP_Create_Frame( - uint8_t *buffer, /* where frame is loaded */ +uint16_t MSTP_Create_Frame(uint8_t *buffer, /* where frame is loaded */ uint16_t buffer_len, /* amount of space available */ - uint8_t frame_type, /* type of frame to send - see defines */ + uint8_t frame_type, /* type of frame to send - see defines */ uint8_t destination, /* destination address */ - uint8_t source, /* source address */ - uint8_t *data, /* any data to be sent - may be null */ + uint8_t source, /* source address */ + uint8_t *data, /* any data to be sent - may be null */ uint16_t data_len) -{ /* number of bytes of data (up to 501) */ - uint8_t crc8 = 0xFF; /* used to calculate the crc value */ +{ /* number of bytes of data (up to 501) */ + uint8_t crc8 = 0xFF; /* used to calculate the crc value */ uint16_t crc16 = 0xFFFF; /* used to calculate the crc value */ - uint16_t index = 0; /* used to load the data portion of the frame */ + uint16_t index = 0; /* used to load the data portion of the frame */ /* not enough to do a header */ - if (buffer_len < 8) + if (buffer_len < 8) { return 0; + } buffer[0] = 0x55; buffer[1] = 0xFF; @@ -239,8 +239,9 @@ uint16_t MSTP_Create_Frame( index++; buffer[index] = crc16 >> 8; index++; - } else + } else { return 0; + } } return index; /* returns the frame length */ @@ -248,17 +249,17 @@ uint16_t MSTP_Create_Frame( void MSTP_Create_And_Send_Frame( volatile struct mstp_port_struct_t *mstp_port, /* port to send from */ - uint8_t frame_type, /* type of frame to send - see defines */ + uint8_t frame_type, /* type of frame to send - see defines */ uint8_t destination, /* destination address */ - uint8_t source, /* source address */ - uint8_t *data, /* any data to be sent - may be null */ + uint8_t source, /* source address */ + uint8_t *data, /* any data to be sent - may be null */ uint16_t data_len) -{ /* number of bytes of data (up to 501) */ +{ /* number of bytes of data (up to 501) */ uint16_t len = 0; /* number of bytes to send */ len = MSTP_Create_Frame((uint8_t *)&mstp_port->OutputBuffer[0], - mstp_port->OutputBufferSize, frame_type, - destination, source, data, data_len); + mstp_port->OutputBufferSize, frame_type, destination, source, data, + data_len); RS485_Send_Frame(mstp_port, (uint8_t *)&mstp_port->OutputBuffer[0], len); /* FIXME: be sure to reset SilenceTimer() after each octet is sent! */ @@ -350,8 +351,7 @@ void MSTP_Receive_Frame_FSM(volatile struct mstp_port_struct_t *mstp_port) mstp_port->ReceivedInvalidFrame = true; /* wait for the start of a frame. */ mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; - printf_receive_error( - "MSTP: Rx Header: SilenceTimer %u > %d\n", + printf_receive_error("MSTP: Rx Header: SilenceTimer %u > %d\n", (unsigned)mstp_port->SilenceTimer((void *)mstp_port), Tframe_abort); } @@ -415,19 +415,19 @@ void MSTP_Receive_Frame_FSM(volatile struct mstp_port_struct_t *mstp_port) the reception of a frame */ mstp_port->ReceivedInvalidFrame = true; printf_receive_error("MSTP: Rx Header: BadCRC [%02X]\n", - mstp_port->DataRegister); + mstp_port->DataRegister); /* wait for the start of the next frame. */ mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; } else { if (mstp_port->DataLength == 0) { /* NoData */ - printf_receive_data( - "%s", mstptext_frame_type( - (unsigned)mstp_port->FrameType)); + printf_receive_data("%s", + mstptext_frame_type( + (unsigned)mstp_port->FrameType)); if ((mstp_port->DestinationAddress == - mstp_port->This_Station) || + mstp_port->This_Station) || (mstp_port->DestinationAddress == - MSTP_BROADCAST_ADDRESS)) { + MSTP_BROADCAST_ADDRESS)) { /* ForUs */ /* indicate that a frame with no data has been * received */ @@ -441,9 +441,9 @@ void MSTP_Receive_Frame_FSM(volatile struct mstp_port_struct_t *mstp_port) } else { /* receive the data portion of the frame. */ if ((mstp_port->DestinationAddress == - mstp_port->This_Station) || + mstp_port->This_Station) || (mstp_port->DestinationAddress == - MSTP_BROADCAST_ADDRESS)) { + MSTP_BROADCAST_ADDRESS)) { if (mstp_port->DataLength <= mstp_port->InputBufferSize) { /* Data */ @@ -474,7 +474,7 @@ void MSTP_Receive_Frame_FSM(volatile struct mstp_port_struct_t *mstp_port) /* the reception of a frame */ mstp_port->ReceivedInvalidFrame = true; printf_receive_error("MSTP: Rx Data: BadIndex %u\n", - (unsigned)mstp_port->Index); + (unsigned)mstp_port->Index); /* wait for the start of a frame. */ mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; } @@ -513,8 +513,8 @@ void MSTP_Receive_Frame_FSM(volatile struct mstp_port_struct_t *mstp_port) printf_receive_data("%02X ", mstp_port->DataRegister); if (mstp_port->Index < mstp_port->DataLength) { /* DataOctet */ - mstp_port->DataCRC = CRC_Calc_Data(mstp_port->DataRegister, - mstp_port->DataCRC); + mstp_port->DataCRC = CRC_Calc_Data( + mstp_port->DataRegister, mstp_port->DataCRC); if (mstp_port->Index < mstp_port->InputBufferSize) { mstp_port->InputBuffer[mstp_port->Index] = mstp_port->DataRegister; @@ -523,18 +523,17 @@ void MSTP_Receive_Frame_FSM(volatile struct mstp_port_struct_t *mstp_port) mstp_port->receive_state = MSTP_RECEIVE_STATE_DATA; } else if (mstp_port->Index == mstp_port->DataLength) { /* CRC1 */ - mstp_port->DataCRC = CRC_Calc_Data(mstp_port->DataRegister, - mstp_port->DataCRC); + mstp_port->DataCRC = CRC_Calc_Data( + mstp_port->DataRegister, mstp_port->DataCRC); mstp_port->DataCRCActualMSB = mstp_port->DataRegister; mstp_port->Index++; mstp_port->receive_state = MSTP_RECEIVE_STATE_DATA; } else if (mstp_port->Index == (mstp_port->DataLength + 1)) { /* CRC2 */ - mstp_port->DataCRC = CRC_Calc_Data(mstp_port->DataRegister, - mstp_port->DataCRC); + mstp_port->DataCRC = CRC_Calc_Data( + mstp_port->DataRegister, mstp_port->DataCRC); mstp_port->DataCRCActualLSB = mstp_port->DataRegister; - printf_receive_data( - "%s", + printf_receive_data("%s", mstptext_frame_type((unsigned)mstp_port->FrameType)); /* STATE DATA CRC - no need for new state */ /* indicate the complete reception of a valid frame */ @@ -550,7 +549,7 @@ void MSTP_Receive_Frame_FSM(volatile struct mstp_port_struct_t *mstp_port) } else { mstp_port->ReceivedInvalidFrame = true; printf_receive_error("MSTP: Rx Data: BadCRC [%02X]\n", - mstp_port->DataRegister); + mstp_port->DataRegister); } mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; } else { @@ -614,16 +613,15 @@ bool MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t *mstp_port) /* wait for the next frame - remain in IDLE */ mstp_port->ReceivedInvalidFrame = false; } else if (mstp_port->ReceivedValidFrame == true) { - printf_master( - "MSTP: ReceivedValidFrame " - "Src=%02X Dest=%02X DataLen=%u " - "FC=%u ST=%u Type=%s\n", + printf_master("MSTP: ReceivedValidFrame " + "Src=%02X Dest=%02X DataLen=%u " + "FC=%u ST=%u Type=%s\n", mstp_port->SourceAddress, mstp_port->DestinationAddress, mstp_port->DataLength, mstp_port->FrameCount, mstp_port->SilenceTimer((void *)mstp_port), mstptext_frame_type((unsigned)mstp_port->FrameType)); if ((mstp_port->DestinationAddress == - mstp_port->This_Station) || + mstp_port->This_Station) || (mstp_port->DestinationAddress == MSTP_BROADCAST_ADDRESS)) { /* destined for me! */ switch (mstp_port->FrameType) { @@ -646,8 +644,7 @@ bool MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t *mstp_port) /* DestinationAddress is equal to TS */ if (mstp_port->DestinationAddress == mstp_port->This_Station) { - MSTP_Create_And_Send_Frame( - mstp_port, + MSTP_Create_And_Send_Frame(mstp_port, FRAME_TYPE_REPLY_TO_POLL_FOR_MASTER, mstp_port->SourceAddress, mstp_port->This_Station, NULL, 0); @@ -671,8 +668,8 @@ bool MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t *mstp_port) } break; case FRAME_TYPE_TEST_REQUEST: - MSTP_Create_And_Send_Frame( - mstp_port, FRAME_TYPE_TEST_RESPONSE, + MSTP_Create_And_Send_Frame(mstp_port, + FRAME_TYPE_TEST_RESPONSE, mstp_port->SourceAddress, mstp_port->This_Station, mstp_port->InputBuffer, mstp_port->DataLength); @@ -689,7 +686,7 @@ bool MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t *mstp_port) mstp_port->ReceivedValidFrame = false; } } else if (mstp_port->SilenceTimer((void *)mstp_port) >= - Tno_token) { + Tno_token) { /* LostToken */ /* assume that the token has been lost */ mstp_port->EventCount = 0; /* Addendum 135-2004d-8 */ @@ -716,8 +713,7 @@ bool MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t *mstp_port) uint8_t frame_type = mstp_port->OutputBuffer[2]; uint8_t destination = mstp_port->OutputBuffer[3]; RS485_Send_Frame(mstp_port, - (uint8_t *)&mstp_port->OutputBuffer[0], - (uint16_t)length); + (uint8_t *)&mstp_port->OutputBuffer[0], (uint16_t)length); mstp_port->FrameCount++; switch (frame_type) { case FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY: @@ -821,14 +817,14 @@ bool MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t *mstp_port) mstp_port->master_state = MSTP_MASTER_STATE_USE_TOKEN; transition_now = true; } else if ((mstp_port->SoleMaster == false) && - (mstp_port->Next_Station == mstp_port->This_Station)) { + (mstp_port->Next_Station == mstp_port->This_Station)) { /* NextStationUnknown - added in Addendum 135-2008v-1 */ /* then the next station to which the token should be sent is unknown - so PollForMaster */ mstp_port->Poll_Station = next_this_station; - MSTP_Create_And_Send_Frame( - mstp_port, FRAME_TYPE_POLL_FOR_MASTER, - mstp_port->Poll_Station, mstp_port->This_Station, NULL, 0); + MSTP_Create_And_Send_Frame(mstp_port, + FRAME_TYPE_POLL_FOR_MASTER, mstp_port->Poll_Station, + mstp_port->This_Station, NULL, 0); mstp_port->RetryCount = 0; mstp_port->master_state = MSTP_MASTER_STATE_POLL_FOR_MASTER; } else if (mstp_port->TokenCount < (Npoll - 1)) { @@ -854,9 +850,9 @@ bool MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t *mstp_port) * case. */ mstp_port->TokenCount++; /* transmit a Token frame to NS */ - MSTP_Create_And_Send_Frame( - mstp_port, FRAME_TYPE_TOKEN, mstp_port->Next_Station, - mstp_port->This_Station, NULL, 0); + MSTP_Create_And_Send_Frame(mstp_port, FRAME_TYPE_TOKEN, + mstp_port->Next_Station, mstp_port->This_Station, NULL, + 0); mstp_port->RetryCount = 0; mstp_port->EventCount = 0; mstp_port->master_state = MSTP_MASTER_STATE_PASS_TOKEN; @@ -865,10 +861,9 @@ bool MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t *mstp_port) if (mstp_port->SoleMaster == true) { /* SoleMasterRestartMaintenancePFM */ mstp_port->Poll_Station = next_next_station; - MSTP_Create_And_Send_Frame( - mstp_port, FRAME_TYPE_POLL_FOR_MASTER, - mstp_port->Poll_Station, mstp_port->This_Station, NULL, - 0); + MSTP_Create_And_Send_Frame(mstp_port, + FRAME_TYPE_POLL_FOR_MASTER, mstp_port->Poll_Station, + mstp_port->This_Station, NULL, 0); /* no known successor node */ mstp_port->Next_Station = mstp_port->This_Station; mstp_port->RetryCount = 0; @@ -882,9 +877,9 @@ bool MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t *mstp_port) /* ResetMaintenancePFM */ mstp_port->Poll_Station = mstp_port->This_Station; /* transmit a Token frame to NS */ - MSTP_Create_And_Send_Frame( - mstp_port, FRAME_TYPE_TOKEN, mstp_port->Next_Station, - mstp_port->This_Station, NULL, 0); + MSTP_Create_And_Send_Frame(mstp_port, FRAME_TYPE_TOKEN, + mstp_port->Next_Station, mstp_port->This_Station, NULL, + 0); mstp_port->RetryCount = 0; /* changed in Errata SSPC-135-2004 */ mstp_port->TokenCount = 1; @@ -894,9 +889,9 @@ bool MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t *mstp_port) } else { /* SendMaintenancePFM */ mstp_port->Poll_Station = next_poll_station; - MSTP_Create_And_Send_Frame( - mstp_port, FRAME_TYPE_POLL_FOR_MASTER, - mstp_port->Poll_Station, mstp_port->This_Station, NULL, 0); + MSTP_Create_And_Send_Frame(mstp_port, + FRAME_TYPE_POLL_FOR_MASTER, mstp_port->Poll_Station, + mstp_port->This_Station, NULL, 0); mstp_port->RetryCount = 0; mstp_port->master_state = MSTP_MASTER_STATE_POLL_FOR_MASTER; } @@ -918,9 +913,9 @@ bool MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t *mstp_port) /* RetrySendToken */ mstp_port->RetryCount++; /* Transmit a Token frame to NS */ - MSTP_Create_And_Send_Frame( - mstp_port, FRAME_TYPE_TOKEN, mstp_port->Next_Station, - mstp_port->This_Station, NULL, 0); + MSTP_Create_And_Send_Frame(mstp_port, FRAME_TYPE_TOKEN, + mstp_port->Next_Station, mstp_port->This_Station, NULL, + 0); mstp_port->EventCount = 0; /* re-enter the current state to listen for NS */ /* to begin using the token. */ @@ -930,10 +925,9 @@ bool MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t *mstp_port) /* note: if NS=TS-1, this node could send PFM to self! */ mstp_port->Poll_Station = next_next_station; /* Transmit a Poll For Master frame to PS. */ - MSTP_Create_And_Send_Frame( - mstp_port, FRAME_TYPE_POLL_FOR_MASTER, - mstp_port->Poll_Station, mstp_port->This_Station, NULL, - 0); + MSTP_Create_And_Send_Frame(mstp_port, + FRAME_TYPE_POLL_FOR_MASTER, mstp_port->Poll_Station, + mstp_port->This_Station, NULL, 0); /* no known successor node */ mstp_port->Next_Station = mstp_port->This_Station; mstp_port->RetryCount = 0; @@ -973,10 +967,9 @@ bool MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t *mstp_port) /* on the network and is empowered to create a token. */ mstp_port->Poll_Station = next_this_station; /* Transmit a Poll For Master frame to PS. */ - MSTP_Create_And_Send_Frame( - mstp_port, FRAME_TYPE_POLL_FOR_MASTER, - mstp_port->Poll_Station, mstp_port->This_Station, NULL, - 0); + MSTP_Create_And_Send_Frame(mstp_port, + FRAME_TYPE_POLL_FOR_MASTER, mstp_port->Poll_Station, + mstp_port->This_Station, NULL, 0); /* indicate that the next station is unknown */ mstp_port->Next_Station = mstp_port->This_Station; mstp_port->RetryCount = 0; @@ -1007,17 +1000,17 @@ bool MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t *mstp_port) /* a successor node. */ if (mstp_port->ReceivedValidFrame == true) { if ((mstp_port->DestinationAddress == - mstp_port->This_Station) && + mstp_port->This_Station) && (mstp_port->FrameType == - FRAME_TYPE_REPLY_TO_POLL_FOR_MASTER)) { + FRAME_TYPE_REPLY_TO_POLL_FOR_MASTER)) { /* ReceivedReplyToPFM */ mstp_port->SoleMaster = false; mstp_port->Next_Station = mstp_port->SourceAddress; mstp_port->EventCount = 0; /* Transmit a Token frame to NS */ - MSTP_Create_And_Send_Frame( - mstp_port, FRAME_TYPE_TOKEN, mstp_port->Next_Station, - mstp_port->This_Station, NULL, 0); + MSTP_Create_And_Send_Frame(mstp_port, FRAME_TYPE_TOKEN, + mstp_port->Next_Station, mstp_port->This_Station, NULL, + 0); mstp_port->Poll_Station = mstp_port->This_Station; mstp_port->TokenCount = 0; mstp_port->RetryCount = 0; @@ -1033,8 +1026,8 @@ bool MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t *mstp_port) } mstp_port->ReceivedValidFrame = false; } else if ((mstp_port->SilenceTimer((void *)mstp_port) > - Tusage_timeout) || - (mstp_port->ReceivedInvalidFrame == true)) { + Tusage_timeout) || + (mstp_port->ReceivedInvalidFrame == true)) { if (mstp_port->SoleMaster == true) { /* SoleMaster */ /* There was no valid reply to the periodic poll */ @@ -1051,9 +1044,8 @@ bool MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t *mstp_port) mstp_port->EventCount = 0; /* transmit a Token frame to NS */ MSTP_Create_And_Send_Frame(mstp_port, FRAME_TYPE_TOKEN, - mstp_port->Next_Station, - mstp_port->This_Station, - NULL, 0); + mstp_port->Next_Station, mstp_port->This_Station, + NULL, 0); mstp_port->RetryCount = 0; mstp_port->master_state = MSTP_MASTER_STATE_PASS_TOKEN; } else { @@ -1061,8 +1053,8 @@ bool MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t *mstp_port) /* SendNextPFM */ mstp_port->Poll_Station = next_poll_station; /* Transmit a Poll For Master frame to PS. */ - MSTP_Create_And_Send_Frame( - mstp_port, FRAME_TYPE_POLL_FOR_MASTER, + MSTP_Create_And_Send_Frame(mstp_port, + FRAME_TYPE_POLL_FOR_MASTER, mstp_port->Poll_Station, mstp_port->This_Station, NULL, 0); mstp_port->RetryCount = 0; @@ -1100,13 +1092,12 @@ bool MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t *mstp_port) * frame */ /* and enter the IDLE state to wait for the next frame. */ RS485_Send_Frame(mstp_port, - (uint8_t *)&mstp_port->OutputBuffer[0], - (uint16_t)length); + (uint8_t *)&mstp_port->OutputBuffer[0], (uint16_t)length); mstp_port->master_state = MSTP_MASTER_STATE_IDLE; /* clear our flag we were holding for comparison */ mstp_port->ReceivedValidFrame = false; } else if (mstp_port->SilenceTimer((void *)mstp_port) > - Treply_delay) { + Treply_delay) { /* DeferredReply */ /* If no reply will be available from the higher layers */ /* within Treply_delay after the reception of the */ @@ -1117,9 +1108,9 @@ bool MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t *mstp_port) /* Call MSTP_Create_And_Send_Frame to transmit a Reply Postponed * frame, */ /* and enter the IDLE state. */ - MSTP_Create_And_Send_Frame( - mstp_port, FRAME_TYPE_REPLY_POSTPONED, - mstp_port->SourceAddress, mstp_port->This_Station, NULL, 0); + MSTP_Create_And_Send_Frame(mstp_port, + FRAME_TYPE_REPLY_POSTPONED, mstp_port->SourceAddress, + mstp_port->This_Station, NULL, 0); mstp_port->master_state = MSTP_MASTER_STATE_IDLE; /* clear our flag we were holding for comparison */ mstp_port->ReceivedValidFrame = false; @@ -1173,12 +1164,12 @@ void MSTP_Slave_Node_FSM(volatile struct mstp_port_struct_t *mstp_port) /* and enter the IDLE state to wait for the next frame. */ RS485_Send_Frame(mstp_port, - (uint8_t *)&mstp_port->OutputBuffer[0], - (uint16_t)length); + (uint8_t *)&mstp_port->OutputBuffer[0], + (uint16_t)length); /* clear our flag we were holding for comparison */ mstp_port->ReceivedValidFrame = false; } else if (mstp_port->SilenceTimer((void *)mstp_port) > - Treply_delay) { + Treply_delay) { /* If no reply will be available from the higher layers within Treply_delay after the reception of the final octet of the requesting frame (the mechanism used to @@ -1193,8 +1184,7 @@ void MSTP_Slave_Node_FSM(volatile struct mstp_port_struct_t *mstp_port) break; case FRAME_TYPE_TEST_REQUEST: mstp_port->ReceivedValidFrame = false; - MSTP_Create_And_Send_Frame( - mstp_port, FRAME_TYPE_TEST_RESPONSE, + MSTP_Create_And_Send_Frame(mstp_port, FRAME_TYPE_TEST_RESPONSE, mstp_port->SourceAddress, mstp_port->This_Station, &mstp_port->InputBuffer[0], mstp_port->DataLength); break; @@ -1261,7 +1251,7 @@ void MSTP_Init(volatile struct mstp_port_struct_t *mstp_port) #ifdef TEST #include #include -#include "ringbuf.h" +#include "bacnet/basic/sys/ringbuf.h" #include "ctest.h" static uint8_t RxBuffer[MAX_MPDU]; @@ -1287,7 +1277,7 @@ static void Load_Input_Buffer(uint8_t *buffer, size_t len) if (!initialized) { initialized = true; Ringbuf_Init(&Test_Buffer, (char *)Test_Buffer_Data, - RING_BUFFER_DATA_SIZE, RING_BUFFER_SIZE); + RING_BUFFER_DATA_SIZE, RING_BUFFER_SIZE); } /* empty any the existing data */ while (!Ringbuf_Empty(&Test_Buffer)) { @@ -1324,14 +1314,14 @@ uint16_t MSTP_Put_Receive(volatile struct mstp_port_struct_t *mstp_port) /* for the MS/TP state machine to use for getting data to send */ /* Return: amount of PDU data */ -uint16_t MSTP_Get_Send(volatile struct mstp_port_struct_t *mstp_port, - unsigned timeout) +uint16_t MSTP_Get_Send( + volatile struct mstp_port_struct_t *mstp_port, unsigned timeout) { /* milliseconds to wait for a packet */ return 0; } -uint16_t MSTP_Get_Reply(volatile struct mstp_port_struct_t *mstp_port, - unsigned timeout) +uint16_t MSTP_Get_Reply( + volatile struct mstp_port_struct_t *mstp_port, unsigned timeout) { /* milliseconds to wait for a packet */ return 0; } @@ -1350,14 +1340,14 @@ static void Timer_Silence_Reset(void) void testReceiveNodeFSM(Test *pTest) { volatile struct mstp_port_struct_t mstp_port; /* port data */ - unsigned EventCount = 0; /* local counter */ - uint8_t my_mac = 0x05; /* local MAC address */ + unsigned EventCount = 0; /* local counter */ + uint8_t my_mac = 0x05; /* local MAC address */ uint8_t HeaderCRC = 0; /* for local CRC calculation */ uint8_t FrameType = 0; /* type of packet that was sent */ - unsigned len; /* used for the size of the message packet */ - size_t i; /* used to loop through the message bytes */ - uint8_t buffer[MAX_MPDU] = {0}; - uint8_t data[MAX_PDU] = {0}; + unsigned len; /* used for the size of the message packet */ + size_t i; /* used to loop through the message bytes */ + uint8_t buffer[MAX_MPDU] = { 0 }; + uint8_t data[MAX_PDU] = { 0 }; mstp_port.InputBuffer = &RxBuffer[0]; mstp_port.InputBufferSize = sizeof(RxBuffer); mstp_port.OutputBuffer = &TxBuffer[0]; @@ -1605,7 +1595,7 @@ void testReceiveNodeFSM(Test *pTest) ct_test(pTest, mstp_port.DataLength == 0); /* HeaderCRC */ mstp_port.DataAvailable = true; - ct_test(pTest, HeaderCRC == 0x73); /* per Annex G example */ + ct_test(pTest, HeaderCRC == 0x73); /* per Annex G example */ mstp_port.DataRegister = ~HeaderCRC; /* one's compliment of CRC is sent */ INCREMENT_AND_LIMIT_UINT8(EventCount); MSTP_Receive_Frame_FSM(&mstp_port); @@ -1619,10 +1609,10 @@ void testReceiveNodeFSM(Test *pTest) mstp_port.ReceivedInvalidFrame = false; mstp_port.ReceivedValidFrame = false; len = MSTP_Create_Frame(buffer, sizeof(buffer), FRAME_TYPE_TOKEN, - 0x10, /* destination */ - my_mac, /* source */ - NULL, /* data */ - 0); /* data size */ + 0x10, /* destination */ + my_mac, /* source */ + NULL, /* data */ + 0); /* data size */ ct_test(pTest, len > 0); /* make the header CRC bad */ buffer[7] = 0x00; @@ -1642,10 +1632,10 @@ void testReceiveNodeFSM(Test *pTest) mstp_port.ReceivedInvalidFrame = false; mstp_port.ReceivedValidFrame = false; len = MSTP_Create_Frame(buffer, sizeof(buffer), FRAME_TYPE_TOKEN, - my_mac, /* destination */ - my_mac, /* source */ - NULL, /* data */ - 0); /* data size */ + my_mac, /* destination */ + my_mac, /* source */ + NULL, /* data */ + 0); /* data size */ ct_test(pTest, len > 0); Load_Input_Buffer(buffer, len); for (i = 0; i < len; i++) { @@ -1663,10 +1653,10 @@ void testReceiveNodeFSM(Test *pTest) mstp_port.ReceivedInvalidFrame = false; mstp_port.ReceivedValidFrame = false; len = MSTP_Create_Frame(buffer, sizeof(buffer), FRAME_TYPE_TOKEN, - my_mac, /* destination */ - my_mac, /* source */ - NULL, /* data */ - 0); /* data size */ + my_mac, /* destination */ + my_mac, /* source */ + NULL, /* data */ + 0); /* data size */ ct_test(pTest, len > 0); /* make the header data length bad */ buffer[5] = 0x02; @@ -1687,7 +1677,7 @@ void testReceiveNodeFSM(Test *pTest) mstp_port.ReceivedValidFrame = false; memset(data, 0, sizeof(data)); len = MSTP_Create_Frame(buffer, sizeof(buffer), FRAME_TYPE_PROPRIETARY_MIN, - my_mac, my_mac, data, sizeof(data)); + my_mac, my_mac, data, sizeof(data)); ct_test(pTest, len > 0); Load_Input_Buffer(buffer, len); RS485_Check_UART_Data(&mstp_port); @@ -1706,7 +1696,7 @@ void testReceiveNodeFSM(Test *pTest) void testMasterNodeFSM(Test *pTest) { volatile struct mstp_port_struct_t MSTP_Port; /* port data */ - uint8_t my_mac = 0x05; /* local MAC address */ + uint8_t my_mac = 0x05; /* local MAC address */ MSTP_Port.InputBuffer = &RxBuffer[0]; MSTP_Port.InputBufferSize = sizeof(RxBuffer); MSTP_Port.OutputBuffer = &TxBuffer[0]; diff --git a/include/mstp.h b/src/bacnet/datalink/mstp.h similarity index 99% rename from include/mstp.h rename to src/bacnet/datalink/mstp.h index d8c1043c..50d30bf9 100644 --- a/include/mstp.h +++ b/src/bacnet/datalink/mstp.h @@ -28,7 +28,7 @@ #include #include #include -#include "mstpdef.h" +#include "bacnet/datalink/mstpdef.h" struct mstp_port_struct_t { MSTP_RECEIVE_STATE receive_state; diff --git a/include/mstpdef.h b/src/bacnet/datalink/mstpdef.h similarity index 99% rename from include/mstpdef.h rename to src/bacnet/datalink/mstpdef.h index 1254dcb6..569f2366 100644 --- a/include/mstpdef.h +++ b/src/bacnet/datalink/mstpdef.h @@ -27,7 +27,7 @@ #include #include #include -#include "bacdef.h" +#include "bacnet/bacdef.h" /* The value 255 is used to denote broadcast when used as a */ /* destination address but is not allowed as a value for a station. */ diff --git a/src/mstptext.c b/src/bacnet/datalink/mstptext.c similarity index 53% rename from src/mstptext.c rename to src/bacnet/datalink/mstptext.c index 4fec6a2e..e10e07b2 100644 --- a/src/mstptext.c +++ b/src/bacnet/datalink/mstptext.c @@ -32,57 +32,53 @@ ------------------------------------------- ####COPYRIGHTEND####*/ #include -#include "mstp.h" -#include "indtext.h" -#include "bacenum.h" -#include "mstptext.h" +#include "bacnet/datalink/mstp.h" +#include "bacnet/indtext.h" +#include "bacnet/bacenum.h" +#include "bacnet/datalink/mstptext.h" /** @file mstptext.c Text mapping functions for BACnet MS/TP */ -static INDTEXT_DATA mstp_receive_state_text[] = { - {MSTP_RECEIVE_STATE_IDLE, "IDLE"}, - {MSTP_RECEIVE_STATE_PREAMBLE, "PREAMBLE"}, - {MSTP_RECEIVE_STATE_HEADER, "HEADER"}, - {MSTP_RECEIVE_STATE_DATA, "DATA"}, - {0, NULL}}; +static INDTEXT_DATA mstp_receive_state_text[] = { { MSTP_RECEIVE_STATE_IDLE, + "IDLE" }, + { MSTP_RECEIVE_STATE_PREAMBLE, "PREAMBLE" }, + { MSTP_RECEIVE_STATE_HEADER, "HEADER" }, + { MSTP_RECEIVE_STATE_DATA, "DATA" }, { 0, NULL } }; const char *mstptext_receive_state(unsigned index) { return indtext_by_index_default(mstp_receive_state_text, index, "unknown"); } -static INDTEXT_DATA mstp_master_state_text[] = { - {MSTP_MASTER_STATE_INITIALIZE, "INITIALIZE"}, - {MSTP_MASTER_STATE_IDLE, "IDLE"}, - {MSTP_MASTER_STATE_USE_TOKEN, "USE_TOKEN"}, - {MSTP_MASTER_STATE_WAIT_FOR_REPLY, "WAIT_FOR_REPLY"}, - {MSTP_MASTER_STATE_DONE_WITH_TOKEN, "DONE_WITH_TOKEN"}, - {MSTP_MASTER_STATE_PASS_TOKEN, "PASS_TOKEN"}, - {MSTP_MASTER_STATE_NO_TOKEN, "NO_TOKEN"}, - {MSTP_MASTER_STATE_POLL_FOR_MASTER, "POLL_FOR_MASTER"}, - {MSTP_MASTER_STATE_ANSWER_DATA_REQUEST, "ANSWER_DATA_REQUEST"}, - {0, NULL}}; +static INDTEXT_DATA mstp_master_state_text[] = { { MSTP_MASTER_STATE_INITIALIZE, + "INITIALIZE" }, + { MSTP_MASTER_STATE_IDLE, "IDLE" }, + { MSTP_MASTER_STATE_USE_TOKEN, "USE_TOKEN" }, + { MSTP_MASTER_STATE_WAIT_FOR_REPLY, "WAIT_FOR_REPLY" }, + { MSTP_MASTER_STATE_DONE_WITH_TOKEN, "DONE_WITH_TOKEN" }, + { MSTP_MASTER_STATE_PASS_TOKEN, "PASS_TOKEN" }, + { MSTP_MASTER_STATE_NO_TOKEN, "NO_TOKEN" }, + { MSTP_MASTER_STATE_POLL_FOR_MASTER, "POLL_FOR_MASTER" }, + { MSTP_MASTER_STATE_ANSWER_DATA_REQUEST, "ANSWER_DATA_REQUEST" }, + { 0, NULL } }; const char *mstptext_master_state(unsigned index) { return indtext_by_index_default(mstp_master_state_text, index, "unknown"); } -static INDTEXT_DATA mstp_frame_type_text[] = { - {FRAME_TYPE_TOKEN, "TOKEN"}, - {FRAME_TYPE_POLL_FOR_MASTER, "POLL_FOR_MASTER"}, - {FRAME_TYPE_REPLY_TO_POLL_FOR_MASTER, "REPLY_TO_POLL_FOR_MASTER"}, - {FRAME_TYPE_TEST_REQUEST, "TEST_REQUEST"}, - {FRAME_TYPE_TEST_RESPONSE, "TEST_RESPONSE"}, - {FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY, "BACNET_DATA_EXPECTING_REPLY"}, - {FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY, - "BACNET_DATA_NOT_EXPECTING_REPLY"}, - {FRAME_TYPE_REPLY_POSTPONED, "REPLY_POSTPONED"}, - {0, NULL}}; +static INDTEXT_DATA mstp_frame_type_text[] = { { FRAME_TYPE_TOKEN, "TOKEN" }, + { FRAME_TYPE_POLL_FOR_MASTER, "POLL_FOR_MASTER" }, + { FRAME_TYPE_REPLY_TO_POLL_FOR_MASTER, "REPLY_TO_POLL_FOR_MASTER" }, + { FRAME_TYPE_TEST_REQUEST, "TEST_REQUEST" }, + { FRAME_TYPE_TEST_RESPONSE, "TEST_RESPONSE" }, + { FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY, "BACNET_DATA_EXPECTING_REPLY" }, + { FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY, + "BACNET_DATA_NOT_EXPECTING_REPLY" }, + { FRAME_TYPE_REPLY_POSTPONED, "REPLY_POSTPONED" }, { 0, NULL } }; const char *mstptext_frame_type(unsigned index) { return indtext_by_index_split_default(mstp_frame_type_text, index, - FRAME_TYPE_PROPRIETARY_MIN, "UNKNOWN", - "PROPRIETARY"); + FRAME_TYPE_PROPRIETARY_MIN, "UNKNOWN", "PROPRIETARY"); } diff --git a/include/mstptext.h b/src/bacnet/datalink/mstptext.h similarity index 100% rename from include/mstptext.h rename to src/bacnet/datalink/mstptext.h diff --git a/src/datetime.c b/src/bacnet/datetime.c similarity index 84% rename from src/datetime.c rename to src/bacnet/datetime.c index 0f26327b..92e9fcb9 100644 --- a/src/datetime.c +++ b/src/bacnet/datetime.c @@ -37,8 +37,8 @@ #include #include #include -#include "datetime.h" -#include "bacdcode.h" +#include "bacnet/datetime.h" +#include "bacnet/bacdcode.h" /** @file datetime.c Manipulate BACnet Date and Time values */ @@ -62,17 +62,18 @@ bool datetime_is_leap_year(uint16_t year) { - if ((year % 4) == 0 && ((year % 100) != 0 || (year % 400) == 0)) + if ((year % 4) == 0 && ((year % 100) != 0 || (year % 400) == 0)) { return (true); - else + } else { return (false); + } } uint8_t datetime_month_days(uint16_t year, uint8_t month) { /* note: start with a zero in the first element to save us from a month - 1 calculation in the lookup */ - int month_days[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; + int month_days[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; /* return value */ uint8_t days = 0; @@ -88,7 +89,7 @@ uint8_t datetime_month_days(uint16_t year, uint8_t month) bool datetime_ymd_is_valid(uint16_t year, uint8_t month, uint8_t day) { - bool status = false; /* true if value date */ + bool status = false; /* true if value date */ uint8_t monthdays = 0; /* days in a month */ monthdays = datetime_month_days(year, month); @@ -113,7 +114,7 @@ bool datetime_date_is_valid(BACNET_DATE *bdate) static uint32_t day_of_year(uint16_t year, uint8_t month, uint8_t day) { - uint32_t days = 0; /* return value */ + uint32_t days = 0; /* return value */ uint8_t months = 0; /* loop counter for months */ if (datetime_ymd_is_valid(year, month, day)) { @@ -126,8 +127,8 @@ static uint32_t day_of_year(uint16_t year, uint8_t month, uint8_t day) return (days); } -static void day_of_year_into_md(uint32_t days, uint16_t year, uint8_t *pMonth, - uint8_t *pDay) +static void day_of_year_into_md( + uint32_t days, uint16_t year, uint8_t *pMonth, uint8_t *pDay) { uint8_t month = 1; uint8_t day = 0; @@ -149,8 +150,8 @@ static void day_of_year_into_md(uint32_t days, uint16_t year, uint8_t *pMonth, return; } -void datetime_day_of_year_into_date(uint32_t days, uint16_t year, - BACNET_DATE *bdate) +void datetime_day_of_year_into_date( + uint32_t days, uint16_t year, BACNET_DATE *bdate) { uint8_t month = 0; uint8_t day = 0; @@ -172,14 +173,15 @@ uint32_t datetime_day_of_year(BACNET_DATE *bdate) static uint32_t days_since_epoch(uint16_t year, uint8_t month, uint8_t day) { - uint32_t days = 0; /* return value */ + uint32_t days = 0; /* return value */ uint16_t years = 0; /* loop counter for years */ if (datetime_ymd_is_valid(year, month, day)) { for (years = BACNET_EPOCH_YEAR; years < year; years++) { days += 365; - if (datetime_is_leap_year(years)) + if (datetime_is_leap_year(years)) { days++; + } } days += day_of_year(year, month, day); /* 'days since' is one less */ @@ -200,19 +202,21 @@ uint32_t datetime_days_since_epoch(BACNET_DATE *bdate) return days; } -static void days_since_epoch_into_ymd(uint32_t days, uint16_t *pYear, - uint8_t *pMonth, uint8_t *pDay) +static void days_since_epoch_into_ymd( + uint32_t days, uint16_t *pYear, uint8_t *pMonth, uint8_t *pDay) { uint16_t year = BACNET_EPOCH_YEAR; uint8_t month = 1; uint8_t day = 1; while (days >= 365) { - if ((datetime_is_leap_year(year)) && (days == 365)) + if ((datetime_is_leap_year(year)) && (days == 365)) { break; + } days -= 365; - if (datetime_is_leap_year(year)) + if (datetime_is_leap_year(year)) { --days; + } year++; } @@ -223,12 +227,15 @@ static void days_since_epoch_into_ymd(uint32_t days, uint16_t *pYear, day = (uint8_t)(day + days); - if (pYear) + if (pYear) { *pYear = year; - if (pMonth) + } + if (pMonth) { *pMonth = month; - if (pDay) + } + if (pDay) { *pDay = day; + } return; } @@ -392,8 +399,8 @@ int datetime_wildcard_compare_time(BACNET_TIME *time1, BACNET_TIME *time2) return diff; } -int datetime_wildcard_compare(BACNET_DATE_TIME *datetime1, - BACNET_DATE_TIME *datetime2) +int datetime_wildcard_compare( + BACNET_DATE_TIME *datetime1, BACNET_DATE_TIME *datetime2) { int diff = 0; @@ -426,15 +433,15 @@ void datetime_copy_time(BACNET_TIME *dest_time, BACNET_TIME *src_time) } } -void datetime_copy(BACNET_DATE_TIME *dest_datetime, - BACNET_DATE_TIME *src_datetime) +void datetime_copy( + BACNET_DATE_TIME *dest_datetime, BACNET_DATE_TIME *src_datetime) { datetime_copy_time(&dest_datetime->time, &src_datetime->time); datetime_copy_date(&dest_datetime->date, &src_datetime->date); } -void datetime_set_date(BACNET_DATE *bdate, uint16_t year, uint8_t month, - uint8_t day) +void datetime_set_date( + BACNET_DATE *bdate, uint16_t year, uint8_t month, uint8_t day) { if (bdate) { bdate->year = year; @@ -444,8 +451,11 @@ void datetime_set_date(BACNET_DATE *bdate, uint16_t year, uint8_t month, } } -void datetime_set_time(BACNET_TIME *btime, uint8_t hour, uint8_t minute, - uint8_t seconds, uint8_t hundredths) +void datetime_set_time(BACNET_TIME *btime, + uint8_t hour, + uint8_t minute, + uint8_t seconds, + uint8_t hundredths) { if (btime) { btime->hour = hour; @@ -455,8 +465,8 @@ void datetime_set_time(BACNET_TIME *btime, uint8_t hour, uint8_t minute, } } -void datetime_set(BACNET_DATE_TIME *bdatetime, BACNET_DATE *bdate, - BACNET_TIME *btime) +void datetime_set( + BACNET_DATE_TIME *bdatetime, BACNET_DATE *bdate, BACNET_TIME *btime) { if (bdate && btime && bdatetime) { bdatetime->time.hour = btime->hour; @@ -470,9 +480,14 @@ void datetime_set(BACNET_DATE_TIME *bdatetime, BACNET_DATE *bdate, } } -void datetime_set_values(BACNET_DATE_TIME *bdatetime, uint16_t year, - uint8_t month, uint8_t day, uint8_t hour, - uint8_t minute, uint8_t seconds, uint8_t hundredths) +void datetime_set_values(BACNET_DATE_TIME *bdatetime, + uint16_t year, + uint8_t month, + uint8_t day, + uint8_t hour, + uint8_t minute, + uint8_t seconds, + uint8_t hundredths) { if (bdatetime) { bdatetime->date.year = year; @@ -486,8 +501,8 @@ void datetime_set_values(BACNET_DATE_TIME *bdatetime, uint16_t year, } } -static uint32_t seconds_since_midnight(uint8_t hours, uint8_t minutes, - uint8_t seconds) +static uint32_t seconds_since_midnight( + uint8_t hours, uint8_t minutes, uint8_t seconds) { return ((hours * 60 * 60) + (minutes * 60) + seconds); } @@ -497,9 +512,8 @@ static uint16_t minutes_since_midnight(uint8_t hours, uint8_t minutes) return ((hours * 60) + minutes); } -static void seconds_since_midnight_into_hms(uint32_t seconds, uint8_t *pHours, - uint8_t *pMinutes, - uint8_t *pSeconds) +static void seconds_since_midnight_into_hms( + uint32_t seconds, uint8_t *pHours, uint8_t *pMinutes, uint8_t *pSeconds) { uint8_t hour = 0; uint8_t minute = 0; @@ -509,12 +523,15 @@ static void seconds_since_midnight_into_hms(uint32_t seconds, uint8_t *pHours, minute = (uint8_t)(seconds / 60); seconds -= (minute * 60); - if (pHours) + if (pHours) { *pHours = hour; - if (pMinutes) + } + if (pMinutes) { *pMinutes = minute; - if (pSeconds) + } + if (pSeconds) { *pSeconds = (uint8_t)seconds; + } } /** Calculates the number of seconds since midnight @@ -563,9 +580,8 @@ void datetime_add_minutes(BACNET_DATE_TIME *bdatetime, int32_t minutes) int32_t days = 0; /* convert bdatetime to seconds and days */ - bdatetime_minutes = - seconds_since_midnight(bdatetime->time.hour, bdatetime->time.min, - bdatetime->time.sec) / + bdatetime_minutes = seconds_since_midnight(bdatetime->time.hour, + bdatetime->time.min, bdatetime->time.sec) / 60; bdatetime_days = datetime_days_since_epoch(&bdatetime->date); @@ -597,8 +613,7 @@ void datetime_add_minutes(BACNET_DATE_TIME *bdatetime, int32_t minutes) /* convert bdatetime from seconds and days */ seconds_since_midnight_into_hms(bdatetime_minutes * 60, - &bdatetime->time.hour, &bdatetime->time.min, - NULL); + &bdatetime->time.hour, &bdatetime->time.min, NULL); datetime_days_since_epoch_into_date(bdatetime_days, &bdatetime->date); } @@ -848,6 +863,68 @@ void datetime_wildcard_set(BACNET_DATE_TIME *bdatetime) } } +/** + * @brief Converts UTC to local time + * @param local_time - the BACnet Date and Time structure to hold local time + * @param utc_time - the BACnet Date and Time structure to hold UTC time + * @param utc_offset_minutes - number of minutes offset from UTC + * Values are positive East of UTC and negative West of UTC + * For example, -6*60 represents 6.00 hours West of UTC + * @param dst_adjust_minutes - number of minutes to adjust local time + * Values are positive East of UTC and negative West of UTC + * @return true if the time is converted + */ +bool datetime_utc_to_local(BACNET_DATE_TIME *local_time, + BACNET_DATE_TIME *utc_time, + int16_t utc_offset_minutes, + int8_t dst_adjust_minutes) +{ + bool status = false; + + if (local_time && utc_time) { + datetime_copy(local_time, utc_time); + utc_offset_minutes *= -1; + datetime_add_minutes(local_time, utc_offset_minutes); + if (dst_adjust_minutes != 0) { + dst_adjust_minutes *= -1; + datetime_add_minutes(local_time, dst_adjust_minutes); + } + status = true; + } + + return status; +} + +/** + * @brief Converts UTC to local time + * @param utc_time - the BACnet Date and Time structure to hold UTC time + * @param local_time - the BACnet Date and Time structure to hold local time + * @param utc_offset_minutes - number of minutes offset from UTC + * Values are positive East of UTC and negative West of UTC + * For example, -6*60 represents 6.00 hours West of UTC + * @param dst_adjust_minutes - number of minutes to adjust local time + * Values are positive East of UTC and negative West of UTC + * @return true if the time is converted + */ +bool datetime_local_to_utc(BACNET_DATE_TIME *utc_time, + BACNET_DATE_TIME *local_time, + int16_t utc_offset_minutes, + int8_t dst_adjust_minutes) +{ + bool status = false; + + if (local_time && utc_time) { + datetime_copy(utc_time, local_time); + datetime_add_minutes(utc_time, utc_offset_minutes); + if (dst_adjust_minutes != 0) { + datetime_add_minutes(utc_time, dst_adjust_minutes); + } + status = true; + } + + return status; +} + int bacapp_encode_datetime(uint8_t *apdu, BACNET_DATE_TIME *value) { int len = 0; @@ -863,8 +940,8 @@ int bacapp_encode_datetime(uint8_t *apdu, BACNET_DATE_TIME *value) return apdu_len; } -int bacapp_encode_context_datetime(uint8_t *apdu, uint8_t tag_number, - BACNET_DATE_TIME *value) +int bacapp_encode_context_datetime( + uint8_t *apdu, uint8_t tag_number, BACNET_DATE_TIME *value) { int len = 0; int apdu_len = 0; @@ -903,8 +980,8 @@ int bacapp_decode_datetime(uint8_t *apdu, BACNET_DATE_TIME *value) return len; } -int bacapp_decode_context_datetime(uint8_t *apdu, uint8_t tag_number, - BACNET_DATE_TIME *value) +int bacapp_decode_context_datetime( + uint8_t *apdu, uint8_t tag_number, BACNET_DATE_TIME *value) { int apdu_len = 0; int len; @@ -1001,8 +1078,8 @@ static void testBACnetDateTimeSeconds(Test *pTest) for (minute = 0; minute < 60; minute += 3) { for (second = 0; second < 60; second += 17) { seconds = seconds_since_midnight(hour, minute, second); - seconds_since_midnight_into_hms(seconds, &test_hour, - &test_minute, &test_second); + seconds_since_midnight_into_hms( + seconds, &test_hour, &test_minute, &test_second); test_seconds = seconds_since_midnight(test_hour, test_minute, test_second); ct_test(pTest, seconds == test_seconds); @@ -1264,8 +1341,8 @@ static void testDateEpoch(Test *pTest) for (month = 1; month <= 12; month++) { for (day = 1; day <= datetime_month_days(year, month); day++) { days = days_since_epoch(year, month, day); - days_since_epoch_into_ymd(days, &test_year, &test_month, - &test_day); + days_since_epoch_into_ymd( + days, &test_year, &test_month, &test_day); ct_test(pTest, year == test_year); ct_test(pTest, month == test_month); ct_test(pTest, day == test_day); @@ -1336,6 +1413,57 @@ static void testDatetimeCodec(Test *pTest) ct_test(pTest, datetimeIn.time.hundredths == datetimeOut.time.hundredths); } +static void testDatetimeConvertUTCSpecific(Test *pTest, + BACNET_DATE_TIME *utc_time, + BACNET_DATE_TIME *local_time, + int16_t utc_offset_minutes, + int8_t dst_adjust_minutes) +{ + bool status = false; + BACNET_DATE_TIME test_local_time; + + status = datetime_local_to_utc( + utc_time, local_time, utc_offset_minutes, dst_adjust_minutes); + ct_test(pTest, status); + status = datetime_utc_to_local( + &test_local_time, utc_time, utc_offset_minutes, dst_adjust_minutes); + ct_test(pTest, status); + /* validate the conversion */ + ct_test(pTest, local_time->date.day == test_local_time.date.day); + ct_test(pTest, local_time->date.month == test_local_time.date.month); + ct_test(pTest, local_time->date.wday == test_local_time.date.wday); + ct_test(pTest, local_time->date.year == test_local_time.date.year); + ct_test(pTest, local_time->time.hour == test_local_time.time.hour); + ct_test(pTest, local_time->time.min == test_local_time.time.min); + ct_test(pTest, local_time->time.sec == test_local_time.time.sec); + ct_test( + pTest, local_time->time.hundredths == test_local_time.time.hundredths); +} + +static void testDatetimeConvertUTC(Test *pTest) +{ + BACNET_DATE_TIME local_time; + BACNET_DATE_TIME utc_time; + /* values are positive east of UTC and negative west of UTC */ + int16_t utc_offset_minutes = 0; + int8_t dst_adjust_minutes = 0; + + datetime_set_date(&local_time.date, 1999, 12, 23); + datetime_set_time(&local_time.time, 8, 30, 0, 0); + testDatetimeConvertUTCSpecific( + pTest, &utc_time, &local_time, utc_offset_minutes, dst_adjust_minutes); + /* check a timezone West of UTC */ + utc_offset_minutes = -6 * 60; + dst_adjust_minutes = -60; + testDatetimeConvertUTCSpecific( + pTest, &utc_time, &local_time, utc_offset_minutes, dst_adjust_minutes); + /* check a timezone East of UTC */ + utc_offset_minutes = 6 * 60; + dst_adjust_minutes = 60; + testDatetimeConvertUTCSpecific( + pTest, &utc_time, &local_time, utc_offset_minutes, dst_adjust_minutes); +} + void testDateTime(Test *pTest) { bool rc; @@ -1363,6 +1491,8 @@ void testDateTime(Test *pTest) assert(rc); rc = ct_addTestFunction(pTest, testWildcardDateTime); assert(rc); + rc = ct_addTestFunction(pTest, testDatetimeConvertUTC); + assert(rc); } #ifdef TEST_DATE_TIME diff --git a/include/datetime.h b/src/bacnet/datetime.h similarity index 92% rename from include/datetime.h rename to src/bacnet/datetime.h index 648189fe..1d24a4ab 100644 --- a/include/datetime.h +++ b/src/bacnet/datetime.h @@ -225,6 +225,17 @@ extern "C" { void datetime_time_wildcard_set( BACNET_TIME * btime); + bool datetime_local_to_utc( + BACNET_DATE_TIME * utc_time, + BACNET_DATE_TIME * local_time, + int16_t utc_offset_minutes, + int8_t dst_adjust_minutes); + bool datetime_utc_to_local( + BACNET_DATE_TIME * local_time, + BACNET_DATE_TIME * utc_time, + int16_t utc_offset_minutes, + int8_t dst_adjust_minutes); + int bacapp_encode_datetime( uint8_t * apdu, BACNET_DATE_TIME * value); @@ -243,6 +254,14 @@ extern "C" { uint8_t tag_number, BACNET_DATE_TIME * value); + /* implementation agnostic functions - create your own! */ + bool datetime_local( + BACNET_DATE * bdate, + BACNET_TIME * btime, + int16_t * utc_offset_minutes, + bool * dst_active); + void datetime_init(void); + #ifdef TEST #include "ctest.h" void testDateTime( diff --git a/src/dcc.c b/src/bacnet/dcc.c similarity index 79% rename from src/dcc.c rename to src/bacnet/dcc.c index ab017796..d7ea5a85 100644 --- a/src/dcc.c +++ b/src/bacnet/dcc.c @@ -32,10 +32,10 @@ ------------------------------------------- ####COPYRIGHTEND####*/ #include -#include "bacenum.h" -#include "bacdcode.h" -#include "bacdef.h" -#include "dcc.h" +#include "bacnet/bacenum.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacdef.h" +#include "bacnet/dcc.h" /** @file dcc.c Enable/Disable Device Communication Control (DCC) */ @@ -92,18 +92,20 @@ uint32_t dcc_duration_seconds(void) void dcc_timer_seconds(uint32_t seconds) { if (DCC_Time_Duration_Seconds) { - if (DCC_Time_Duration_Seconds > seconds) + if (DCC_Time_Duration_Seconds > seconds) { DCC_Time_Duration_Seconds -= seconds; - else + } else { DCC_Time_Duration_Seconds = 0; + } /* just expired - do something */ - if (DCC_Time_Duration_Seconds == 0) + if (DCC_Time_Duration_Seconds == 0) { DCC_Enable_Disable = COMMUNICATION_ENABLE; + } } } -bool dcc_set_status_duration(BACNET_COMMUNICATION_ENABLE_DISABLE status, - uint16_t minutes) +bool dcc_set_status_duration( + BACNET_COMMUNICATION_ENABLE_DISABLE status, uint16_t minutes) { bool valid = false; @@ -123,12 +125,13 @@ bool dcc_set_status_duration(BACNET_COMMUNICATION_ENABLE_DISABLE status, #if BACNET_SVC_DCC_A /* encode service */ -int dcc_encode_apdu(uint8_t *apdu, uint8_t invoke_id, - uint16_t timeDuration, /* 0=optional */ - BACNET_COMMUNICATION_ENABLE_DISABLE enable_disable, - BACNET_CHARACTER_STRING *password) -{ /* NULL=optional */ - int len = 0; /* length of each encoding */ +int dcc_encode_apdu(uint8_t *apdu, + uint8_t invoke_id, + uint16_t timeDuration, /* 0=optional */ + BACNET_COMMUNICATION_ENABLE_DISABLE enable_disable, + BACNET_CHARACTER_STRING *password) +{ /* NULL=optional */ + int len = 0; /* length of each encoding */ int apdu_len = 0; /* total length of the apdu, return value */ if (apdu) { @@ -158,8 +161,9 @@ int dcc_encode_apdu(uint8_t *apdu, uint8_t invoke_id, #endif /* decode the service request only */ -int dcc_decode_service_request( - uint8_t *apdu, unsigned apdu_len, uint16_t *timeDuration, +int dcc_decode_service_request(uint8_t *apdu, + unsigned apdu_len, + uint16_t *timeDuration, BACNET_COMMUNICATION_ENABLE_DISABLE *enable_disable, BACNET_CHARACTER_STRING *password) { @@ -174,8 +178,8 @@ int dcc_decode_service_request( * But if not included, take it as indefinite, * which we return as "very large" */ if (decode_is_context_tag(&apdu[len], 0)) { - len += decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value_type); + len += decode_tag_number_and_value( + &apdu[len], &tag_number, &len_value_type); len += decode_unsigned(&apdu[len], len_value_type, &value32); if (timeDuration) { *timeDuration = (uint16_t)value32; @@ -189,8 +193,8 @@ int dcc_decode_service_request( if (!decode_is_context_tag(&apdu[len], 1)) { return -1; } - len += decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value_type); + len += decode_tag_number_and_value( + &apdu[len], &tag_number, &len_value_type); len += decode_enumerated(&apdu[len], len_value_type, &value32); if (enable_disable) { *enable_disable = (BACNET_COMMUNICATION_ENABLE_DISABLE)value32; @@ -200,8 +204,8 @@ int dcc_decode_service_request( if (!decode_is_context_tag(&apdu[len], 2)) { return -1; } - len += decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value_type); + len += decode_tag_number_and_value( + &apdu[len], &tag_number, &len_value_type); len += decode_character_string(&apdu[len], len_value_type, password); } else if (password) { @@ -217,10 +221,12 @@ int dcc_decode_service_request( #include #include "ctest.h" -int dcc_decode_apdu(uint8_t *apdu, unsigned apdu_len, uint8_t *invoke_id, - uint16_t *timeDuration, - BACNET_COMMUNICATION_ENABLE_DISABLE *enable_disable, - BACNET_CHARACTER_STRING *password) +int dcc_decode_apdu(uint8_t *apdu, + unsigned apdu_len, + uint8_t *invoke_id, + uint16_t *timeDuration, + BACNET_COMMUNICATION_ENABLE_DISABLE *enable_disable, + BACNET_CHARACTER_STRING *password) { int len = 0; unsigned offset = 0; @@ -237,20 +243,20 @@ int dcc_decode_apdu(uint8_t *apdu, unsigned apdu_len, uint8_t *invoke_id, offset = 4; if (apdu_len > offset) { - len = - dcc_decode_service_request(&apdu[offset], apdu_len - offset, - timeDuration, enable_disable, password); + len = dcc_decode_service_request(&apdu[offset], apdu_len - offset, + timeDuration, enable_disable, password); } return len; } -void test_DeviceCommunicationControlData( - Test *pTest, uint8_t invoke_id, uint16_t timeDuration, +void test_DeviceCommunicationControlData(Test *pTest, + uint8_t invoke_id, + uint16_t timeDuration, BACNET_COMMUNICATION_ENABLE_DISABLE enable_disable, BACNET_CHARACTER_STRING *password) { - uint8_t apdu[480] = {0}; + uint8_t apdu[480] = { 0 }; int len = 0; int apdu_len = 0; uint8_t test_invoke_id = 0; @@ -258,14 +264,13 @@ void test_DeviceCommunicationControlData( BACNET_COMMUNICATION_ENABLE_DISABLE test_enable_disable; BACNET_CHARACTER_STRING test_password; - len = dcc_encode_apdu(&apdu[0], invoke_id, timeDuration, enable_disable, - password); + len = dcc_encode_apdu( + &apdu[0], invoke_id, timeDuration, enable_disable, password); ct_test(pTest, len != 0); apdu_len = len; - len = - dcc_decode_apdu(&apdu[0], apdu_len, &test_invoke_id, &test_timeDuration, - &test_enable_disable, &test_password); + len = dcc_decode_apdu(&apdu[0], apdu_len, &test_invoke_id, + &test_timeDuration, &test_enable_disable, &test_password); ct_test(pTest, len != -1); ct_test(pTest, test_invoke_id == invoke_id); ct_test(pTest, test_timeDuration == timeDuration); @@ -283,13 +288,13 @@ void test_DeviceCommunicationControl(Test *pTest) timeDuration = 0; enable_disable = COMMUNICATION_DISABLE_INITIATION; characterstring_init_ansi(&password, "John 3:16"); - test_DeviceCommunicationControlData(pTest, invoke_id, timeDuration, - enable_disable, &password); + test_DeviceCommunicationControlData( + pTest, invoke_id, timeDuration, enable_disable, &password); timeDuration = 12345; enable_disable = COMMUNICATION_DISABLE; - test_DeviceCommunicationControlData(pTest, invoke_id, timeDuration, - enable_disable, NULL); + test_DeviceCommunicationControlData( + pTest, invoke_id, timeDuration, enable_disable, NULL); return; } diff --git a/include/dcc.h b/src/bacnet/dcc.h similarity index 98% rename from include/dcc.h rename to src/bacnet/dcc.h index 0438572b..7d63f2b0 100644 --- a/include/dcc.h +++ b/src/bacnet/dcc.h @@ -26,8 +26,8 @@ #include #include -#include "bacenum.h" -#include "bacstr.h" +#include "bacnet/bacenum.h" +#include "bacnet/bacstr.h" #ifdef __cplusplus extern "C" { diff --git a/src/event.c b/src/bacnet/event.c similarity index 66% rename from src/event.c rename to src/bacnet/event.c index bc6258a4..119ee6bf 100644 --- a/src/event.c +++ b/src/bacnet/event.c @@ -32,17 +32,17 @@ ------------------------------------------- ####COPYRIGHTEND####*/ #include -#include "event.h" -#include "bacdcode.h" -#include "npdu.h" -#include "timestamp.h" +#include "bacnet/event.h" +#include "bacnet/bacdcode.h" +#include "bacnet/npdu.h" +#include "bacnet/timestamp.h" /** @file event.c Encode/Decode Event Notifications */ -int uevent_notify_encode_apdu(uint8_t *apdu, - BACNET_EVENT_NOTIFICATION_DATA *data) +int uevent_notify_encode_apdu( + uint8_t *apdu, BACNET_EVENT_NOTIFICATION_DATA *data) { - int len = 0; /* length of each encoding */ + int len = 0; /* length of each encoding */ int apdu_len = 0; /* total length of the apdu, return value */ if (apdu) { @@ -62,10 +62,10 @@ int uevent_notify_encode_apdu(uint8_t *apdu, return apdu_len; } -int cevent_notify_encode_apdu(uint8_t *apdu, uint8_t invoke_id, - BACNET_EVENT_NOTIFICATION_DATA *data) +int cevent_notify_encode_apdu( + uint8_t *apdu, uint8_t invoke_id, BACNET_EVENT_NOTIFICATION_DATA *data) { - int len = 0; /* length of each encoding */ + int len = 0; /* length of each encoding */ int apdu_len = 0; /* total length of the apdu, return value */ if (apdu) { @@ -87,39 +87,39 @@ int cevent_notify_encode_apdu(uint8_t *apdu, uint8_t invoke_id, return apdu_len; } -int event_notify_encode_service_request(uint8_t *apdu, - BACNET_EVENT_NOTIFICATION_DATA *data) +int event_notify_encode_service_request( + uint8_t *apdu, BACNET_EVENT_NOTIFICATION_DATA *data) { - int len = 0; /* length of each encoding */ + int len = 0; /* length of each encoding */ int apdu_len = 0; /* total length of the apdu, return value */ if (apdu) { /* tag 0 - processIdentifier */ - len = encode_context_unsigned(&apdu[apdu_len], 0, - data->processIdentifier); + len = encode_context_unsigned( + &apdu[apdu_len], 0, data->processIdentifier); apdu_len += len; /* tag 1 - initiatingObjectIdentifier */ - len = encode_context_object_id( - &apdu[apdu_len], 1, (int)data->initiatingObjectIdentifier.type, + len = encode_context_object_id(&apdu[apdu_len], 1, + (int)data->initiatingObjectIdentifier.type, data->initiatingObjectIdentifier.instance); apdu_len += len; /* tag 2 - eventObjectIdentifier */ len = encode_context_object_id(&apdu[apdu_len], 2, - (int)data->eventObjectIdentifier.type, - data->eventObjectIdentifier.instance); + (int)data->eventObjectIdentifier.type, + data->eventObjectIdentifier.instance); apdu_len += len; /* tag 3 - timeStamp */ - len = bacapp_encode_context_timestamp(&apdu[apdu_len], 3, - &data->timeStamp); + len = bacapp_encode_context_timestamp( + &apdu[apdu_len], 3, &data->timeStamp); apdu_len += len; /* tag 4 - noticicationClass */ - len = encode_context_unsigned(&apdu[apdu_len], 4, - data->notificationClass); + len = encode_context_unsigned( + &apdu[apdu_len], 4, data->notificationClass); apdu_len += len; /* tag 5 - priority */ @@ -133,8 +133,8 @@ int event_notify_encode_service_request(uint8_t *apdu, /* tag 7 - messageText */ if (data->messageText) { - len = encode_context_character_string(&apdu[apdu_len], 7, - data->messageText); + len = encode_context_character_string( + &apdu[apdu_len], 7, data->messageText); apdu_len += len; } /* tag 8 - notifyType */ @@ -146,13 +146,13 @@ int event_notify_encode_service_request(uint8_t *apdu, case NOTIFY_EVENT: /* tag 9 - ackRequired */ - len = encode_context_boolean(&apdu[apdu_len], 9, - data->ackRequired); + len = encode_context_boolean( + &apdu[apdu_len], 9, data->ackRequired); apdu_len += len; /* tag 10 - fromState */ - len = encode_context_enumerated(&apdu[apdu_len], 10, - data->fromState); + len = encode_context_enumerated( + &apdu[apdu_len], 10, data->fromState); apdu_len += len; break; @@ -176,14 +176,12 @@ int event_notify_encode_service_request(uint8_t *apdu, len = encode_opening_tag(&apdu[apdu_len], 0); apdu_len += len; - len = encode_context_bitstring( - &apdu[apdu_len], 0, + len = encode_context_bitstring(&apdu[apdu_len], 0, &data->notificationParams.changeOfBitstring .referencedBitString); apdu_len += len; - len = encode_context_bitstring( - &apdu[apdu_len], 1, + len = encode_context_bitstring(&apdu[apdu_len], 1, &data->notificationParams.changeOfBitstring .statusFlags); apdu_len += len; @@ -199,16 +197,14 @@ int event_notify_encode_service_request(uint8_t *apdu, len = encode_opening_tag(&apdu[apdu_len], 0); apdu_len += len; - len = bacapp_encode_property_state( - &apdu[apdu_len], + len = bacapp_encode_property_state(&apdu[apdu_len], &data->notificationParams.changeOfState.newState); apdu_len += len; len = encode_closing_tag(&apdu[apdu_len], 0); apdu_len += len; - len = encode_context_bitstring( - &apdu[apdu_len], 1, + len = encode_context_bitstring(&apdu[apdu_len], 1, &data->notificationParams.changeOfState .statusFlags); apdu_len += len; @@ -226,18 +222,17 @@ int event_notify_encode_service_request(uint8_t *apdu, switch (data->notificationParams.changeOfValue.tag) { case CHANGE_OF_VALUE_REAL: - len = encode_context_real( - &apdu[apdu_len], 1, + len = encode_context_real(&apdu[apdu_len], 1, data->notificationParams.changeOfValue .newValue.changeValue); apdu_len += len; break; case CHANGE_OF_VALUE_BITS: - len = encode_context_bitstring( - &apdu[apdu_len], 0, - &data->notificationParams.changeOfValue - .newValue.changedBits); + len = + encode_context_bitstring(&apdu[apdu_len], 0, + &data->notificationParams.changeOfValue + .newValue.changedBits); apdu_len += len; break; @@ -248,8 +243,7 @@ int event_notify_encode_service_request(uint8_t *apdu, len = encode_closing_tag(&apdu[apdu_len], 0); apdu_len += len; - len = encode_context_bitstring( - &apdu[apdu_len], 1, + len = encode_context_bitstring(&apdu[apdu_len], 1, &data->notificationParams.changeOfValue .statusFlags); apdu_len += len; @@ -262,26 +256,22 @@ int event_notify_encode_service_request(uint8_t *apdu, len = encode_opening_tag(&apdu[apdu_len], 4); apdu_len += len; - len = encode_context_real( - &apdu[apdu_len], 0, + len = encode_context_real(&apdu[apdu_len], 0, data->notificationParams.floatingLimit .referenceValue); apdu_len += len; - len = encode_context_bitstring( - &apdu[apdu_len], 1, + len = encode_context_bitstring(&apdu[apdu_len], 1, &data->notificationParams.floatingLimit .statusFlags); apdu_len += len; - len = encode_context_real( - &apdu[apdu_len], 2, + len = encode_context_real(&apdu[apdu_len], 2, data->notificationParams.floatingLimit .setPointValue); apdu_len += len; - len = encode_context_real( - &apdu[apdu_len], 3, + len = encode_context_real(&apdu[apdu_len], 3, data->notificationParams.floatingLimit.errorLimit); apdu_len += len; @@ -293,23 +283,19 @@ int event_notify_encode_service_request(uint8_t *apdu, len = encode_opening_tag(&apdu[apdu_len], 5); apdu_len += len; - len = encode_context_real( - &apdu[apdu_len], 0, + len = encode_context_real(&apdu[apdu_len], 0, data->notificationParams.outOfRange.exceedingValue); apdu_len += len; - len = encode_context_bitstring( - &apdu[apdu_len], 1, + len = encode_context_bitstring(&apdu[apdu_len], 1, &data->notificationParams.outOfRange.statusFlags); apdu_len += len; - len = encode_context_real( - &apdu[apdu_len], 2, + len = encode_context_real(&apdu[apdu_len], 2, data->notificationParams.outOfRange.deadband); apdu_len += len; - len = encode_context_real( - &apdu[apdu_len], 3, + len = encode_context_real(&apdu[apdu_len], 3, data->notificationParams.outOfRange.exceededLimit); apdu_len += len; @@ -321,26 +307,22 @@ int event_notify_encode_service_request(uint8_t *apdu, len = encode_opening_tag(&apdu[apdu_len], 8); apdu_len += len; - len = encode_context_enumerated( - &apdu[apdu_len], 0, + len = encode_context_enumerated(&apdu[apdu_len], 0, data->notificationParams.changeOfLifeSafety .newState); apdu_len += len; - len = encode_context_enumerated( - &apdu[apdu_len], 1, + len = encode_context_enumerated(&apdu[apdu_len], 1, data->notificationParams.changeOfLifeSafety .newMode); apdu_len += len; - len = encode_context_bitstring( - &apdu[apdu_len], 2, + len = encode_context_bitstring(&apdu[apdu_len], 2, &data->notificationParams.changeOfLifeSafety .statusFlags); apdu_len += len; - len = encode_context_enumerated( - &apdu[apdu_len], 3, + len = encode_context_enumerated(&apdu[apdu_len], 3, data->notificationParams.changeOfLifeSafety .operationExpected); apdu_len += len; @@ -359,14 +341,12 @@ int event_notify_encode_service_request(uint8_t *apdu, .bufferProperty); apdu_len += len; - len = encode_context_unsigned( - &apdu[apdu_len], 1, + len = encode_context_unsigned(&apdu[apdu_len], 1, data->notificationParams.bufferReady .previousNotification); apdu_len += len; - len = encode_context_unsigned( - &apdu[apdu_len], 2, + len = encode_context_unsigned(&apdu[apdu_len], 2, data->notificationParams.bufferReady .currentNotification); apdu_len += len; @@ -378,20 +358,17 @@ int event_notify_encode_service_request(uint8_t *apdu, len = encode_opening_tag(&apdu[apdu_len], 11); apdu_len += len; - len = encode_context_unsigned( - &apdu[apdu_len], 0, + len = encode_context_unsigned(&apdu[apdu_len], 0, data->notificationParams.unsignedRange .exceedingValue); apdu_len += len; - len = encode_context_bitstring( - &apdu[apdu_len], 1, + len = encode_context_bitstring(&apdu[apdu_len], 1, &data->notificationParams.unsignedRange .statusFlags); apdu_len += len; - len = encode_context_unsigned( - &apdu[apdu_len], 2, + len = encode_context_unsigned(&apdu[apdu_len], 2, data->notificationParams.unsignedRange .exceededLimit); apdu_len += len; @@ -417,8 +394,8 @@ int event_notify_encode_service_request(uint8_t *apdu, return apdu_len; } -int event_notify_decode_service_request(uint8_t *apdu, unsigned apdu_len, - BACNET_EVENT_NOTIFICATION_DATA *data) +int event_notify_decode_service_request( + uint8_t *apdu, unsigned apdu_len, BACNET_EVENT_NOTIFICATION_DATA *data) { int len = 0; /* return value */ int section_length = 0; @@ -434,16 +411,16 @@ int event_notify_decode_service_request(uint8_t *apdu, unsigned apdu_len, } /* tag 1 - initiatingObjectIdentifier */ - if ((section_length = decode_context_object_id( - &apdu[len], 1, &data->initiatingObjectIdentifier.type, + if ((section_length = decode_context_object_id(&apdu[len], 1, + &data->initiatingObjectIdentifier.type, &data->initiatingObjectIdentifier.instance)) == -1) { return -1; } else { len += section_length; } /* tag 2 - eventObjectIdentifier */ - if ((section_length = decode_context_object_id( - &apdu[len], 2, &data->eventObjectIdentifier.type, + if ((section_length = decode_context_object_id(&apdu[len], 2, + &data->eventObjectIdentifier.type, &data->eventObjectIdentifier.instance)) == -1) { return -1; } else { @@ -477,7 +454,7 @@ int event_notify_decode_service_request(uint8_t *apdu, unsigned apdu_len, } /* tag 6 - eventType */ if ((section_length = - decode_context_enumerated(&apdu[len], 6, &value)) == -1) { + decode_context_enumerated(&apdu[len], 6, &value)) == -1) { return -1; } else { data->eventType = (BACNET_EVENT_TYPE)value; @@ -505,7 +482,7 @@ int event_notify_decode_service_request(uint8_t *apdu, unsigned apdu_len, /* tag 8 - notifyType */ if ((section_length = - decode_context_enumerated(&apdu[len], 8, &value)) == -1) { + decode_context_enumerated(&apdu[len], 8, &value)) == -1) { return -1; } else { data->notifyType = (BACNET_NOTIFY_TYPE)value; @@ -540,7 +517,7 @@ int event_notify_decode_service_request(uint8_t *apdu, unsigned apdu_len, } /* tag 11 - toState */ if ((section_length = - decode_context_enumerated(&apdu[len], 11, &value)) == -1) { + decode_context_enumerated(&apdu[len], 11, &value)) == -1) { return -1; } else { data->toState = (BACNET_EVENT_STATE)value; @@ -555,8 +532,8 @@ int event_notify_decode_service_request(uint8_t *apdu, unsigned apdu_len, } else { return -1; } - if (decode_is_opening_tag_number(&apdu[len], - (uint8_t)data->eventType)) { + if (decode_is_opening_tag_number( + &apdu[len], (uint8_t)data->eventType)) { len++; } else { return -1; @@ -573,10 +550,11 @@ int event_notify_decode_service_request(uint8_t *apdu, unsigned apdu_len, } len += section_length; - if (-1 == (section_length = decode_context_bitstring( - &apdu[len], 1, - &data->notificationParams - .changeOfBitstring.statusFlags))) { + if (-1 == + (section_length = + decode_context_bitstring(&apdu[len], 1, + &data->notificationParams + .changeOfBitstring.statusFlags))) { return -1; } len += section_length; @@ -584,19 +562,21 @@ int event_notify_decode_service_request(uint8_t *apdu, unsigned apdu_len, break; case EVENT_CHANGE_OF_STATE: - if (-1 == (section_length = - bacapp_decode_context_property_state( - &apdu[len], 0, - &data->notificationParams - .changeOfState.newState))) { + if (-1 == + (section_length = + bacapp_decode_context_property_state( + &apdu[len], 0, + &data->notificationParams.changeOfState + .newState))) { return -1; } len += section_length; - if (-1 == (section_length = decode_context_bitstring( - &apdu[len], 1, - &data->notificationParams.changeOfState - .statusFlags))) { + if (-1 == + (section_length = + decode_context_bitstring(&apdu[len], 1, + &data->notificationParams.changeOfState + .statusFlags))) { return -1; } len += section_length; @@ -609,8 +589,8 @@ int event_notify_decode_service_request(uint8_t *apdu, unsigned apdu_len, } len++; - if (decode_is_context_tag(&apdu[len], - CHANGE_OF_VALUE_BITS)) { + if (decode_is_context_tag( + &apdu[len], CHANGE_OF_VALUE_BITS)) { if (-1 == (section_length = decode_context_bitstring( &apdu[len], 0, @@ -643,108 +623,115 @@ int event_notify_decode_service_request(uint8_t *apdu, unsigned apdu_len, } len++; - if (-1 == (section_length = decode_context_bitstring( - &apdu[len], 1, - &data->notificationParams.changeOfValue - .statusFlags))) { + if (-1 == + (section_length = + decode_context_bitstring(&apdu[len], 1, + &data->notificationParams.changeOfValue + .statusFlags))) { return -1; } len += section_length; break; case EVENT_FLOATING_LIMIT: - if (-1 == (section_length = decode_context_real( - &apdu[len], 0, - &data->notificationParams.floatingLimit - .referenceValue))) { + if (-1 == + (section_length = decode_context_real(&apdu[len], 0, + &data->notificationParams.floatingLimit + .referenceValue))) { return -1; } len += section_length; - if (-1 == (section_length = decode_context_bitstring( - &apdu[len], 1, - &data->notificationParams.floatingLimit - .statusFlags))) { + if (-1 == + (section_length = + decode_context_bitstring(&apdu[len], 1, + &data->notificationParams.floatingLimit + .statusFlags))) { return -1; } len += section_length; - if (-1 == (section_length = decode_context_real( - &apdu[len], 2, - &data->notificationParams.floatingLimit - .setPointValue))) { + if (-1 == + (section_length = decode_context_real(&apdu[len], 2, + &data->notificationParams.floatingLimit + .setPointValue))) { return -1; } len += section_length; - if (-1 == (section_length = decode_context_real( - &apdu[len], 3, - &data->notificationParams.floatingLimit - .errorLimit))) { + if (-1 == + (section_length = decode_context_real(&apdu[len], 3, + &data->notificationParams.floatingLimit + .errorLimit))) { return -1; } len += section_length; break; case EVENT_OUT_OF_RANGE: - if (-1 == (section_length = decode_context_real( - &apdu[len], 0, - &data->notificationParams.outOfRange - .exceedingValue))) { + if (-1 == + (section_length = decode_context_real(&apdu[len], 0, + &data->notificationParams.outOfRange + .exceedingValue))) { return -1; } len += section_length; - if (-1 == (section_length = decode_context_bitstring( - &apdu[len], 1, - &data->notificationParams.outOfRange - .statusFlags))) { + if (-1 == + (section_length = + decode_context_bitstring(&apdu[len], 1, + &data->notificationParams.outOfRange + .statusFlags))) { return -1; } len += section_length; - if (-1 == (section_length = decode_context_real( - &apdu[len], 2, - &data->notificationParams.outOfRange - .deadband))) { + if (-1 == + (section_length = decode_context_real(&apdu[len], 2, + &data->notificationParams.outOfRange + .deadband))) { return -1; } len += section_length; - if (-1 == (section_length = decode_context_real( - &apdu[len], 3, - &data->notificationParams.outOfRange - .exceededLimit))) { + if (-1 == + (section_length = decode_context_real(&apdu[len], 3, + &data->notificationParams.outOfRange + .exceededLimit))) { return -1; } len += section_length; break; case EVENT_CHANGE_OF_LIFE_SAFETY: - if (-1 == (section_length = decode_context_enumerated( - &apdu[len], 0, &value))) { + if (-1 == + (section_length = decode_context_enumerated( + &apdu[len], 0, &value))) { return -1; } data->notificationParams.changeOfLifeSafety.newState = (BACNET_LIFE_SAFETY_STATE)value; len += section_length; - if (-1 == (section_length = decode_context_enumerated( - &apdu[len], 1, &value))) { + if (-1 == + (section_length = decode_context_enumerated( + &apdu[len], 1, &value))) { return -1; } data->notificationParams.changeOfLifeSafety.newMode = (BACNET_LIFE_SAFETY_MODE)value; len += section_length; - if (-1 == (section_length = decode_context_bitstring( - &apdu[len], 2, - &data->notificationParams - .changeOfLifeSafety.statusFlags))) { + if (-1 == + (section_length = decode_context_bitstring( + &apdu[len], 2, + &data->notificationParams.changeOfLifeSafety + .statusFlags))) { return -1; } len += section_length; - if (-1 == (section_length = decode_context_enumerated( - &apdu[len], 3, &value))) { + if (-1 == + (section_length = decode_context_enumerated( + &apdu[len], 3, &value))) { return -1; } data->notificationParams.changeOfLifeSafety @@ -756,52 +743,57 @@ int event_notify_decode_service_request(uint8_t *apdu, unsigned apdu_len, case EVENT_BUFFER_READY: if (-1 == (section_length = - bacapp_decode_context_device_obj_property_ref( - &apdu[len], 0, - &data->notificationParams.bufferReady - .bufferProperty))) { + bacapp_decode_context_device_obj_property_ref( + &apdu[len], 0, + &data->notificationParams.bufferReady + .bufferProperty))) { return -1; } len += section_length; - if (-1 == (section_length = decode_context_unsigned( - &apdu[len], 1, - &data->notificationParams.bufferReady - .previousNotification))) { + if (-1 == + (section_length = + decode_context_unsigned(&apdu[len], 1, + &data->notificationParams.bufferReady + .previousNotification))) { return -1; } len += section_length; - if (-1 == (section_length = decode_context_unsigned( - &apdu[len], 2, - &data->notificationParams.bufferReady - .currentNotification))) { + if (-1 == + (section_length = + decode_context_unsigned(&apdu[len], 2, + &data->notificationParams.bufferReady + .currentNotification))) { return -1; } len += section_length; break; case EVENT_UNSIGNED_RANGE: - if (-1 == (section_length = decode_context_unsigned( - &apdu[len], 0, - &data->notificationParams.unsignedRange - .exceedingValue))) { + if (-1 == + (section_length = + decode_context_unsigned(&apdu[len], 0, + &data->notificationParams.unsignedRange + .exceedingValue))) { return -1; } len += section_length; - if (-1 == (section_length = decode_context_bitstring( - &apdu[len], 1, - &data->notificationParams.unsignedRange - .statusFlags))) { + if (-1 == + (section_length = + decode_context_bitstring(&apdu[len], 1, + &data->notificationParams.unsignedRange + .statusFlags))) { return -1; } len += section_length; - if (-1 == (section_length = decode_context_unsigned( - &apdu[len], 2, - &data->notificationParams.unsignedRange - .exceededLimit))) { + if (-1 == + (section_length = + decode_context_unsigned(&apdu[len], 2, + &data->notificationParams.unsignedRange + .exceededLimit))) { return -1; } len += section_length; @@ -810,8 +802,8 @@ int event_notify_decode_service_request(uint8_t *apdu, unsigned apdu_len, default: return -1; } - if (decode_is_closing_tag_number(&apdu[len], - (uint8_t)data->eventType)) { + if (decode_is_closing_tag_number( + &apdu[len], (uint8_t)data->eventType)) { len++; } else { return -1; @@ -846,14 +838,17 @@ BACNET_EVENT_NOTIFICATION_DATA data2; void testBaseEventState(Test *pTest) { ct_test(pTest, data.processIdentifier == data2.processIdentifier); - ct_test(pTest, data.initiatingObjectIdentifier.instance == - data2.initiatingObjectIdentifier.instance); - ct_test(pTest, data.initiatingObjectIdentifier.type == - data2.initiatingObjectIdentifier.type); - ct_test(pTest, data.eventObjectIdentifier.instance == - data2.eventObjectIdentifier.instance); - ct_test(pTest, data.eventObjectIdentifier.type == - data2.eventObjectIdentifier.type); + ct_test(pTest, + data.initiatingObjectIdentifier.instance == + data2.initiatingObjectIdentifier.instance); + ct_test(pTest, + data.initiatingObjectIdentifier.type == + data2.initiatingObjectIdentifier.type); + ct_test(pTest, + data.eventObjectIdentifier.instance == + data2.eventObjectIdentifier.instance); + ct_test(pTest, + data.eventObjectIdentifier.type == data2.eventObjectIdentifier.type); ct_test(pTest, data.notificationClass == data2.notificationClass); ct_test(pTest, data.priority == data2.priority); ct_test(pTest, data.notifyType == data2.notifyType); @@ -862,50 +857,63 @@ void testBaseEventState(Test *pTest) ct_test(pTest, data.toState == data2.toState); if (data.messageText != NULL && data2.messageText != NULL) { - ct_test(pTest, - data.messageText->encoding == data2.messageText->encoding); + ct_test( + pTest, data.messageText->encoding == data2.messageText->encoding); ct_test(pTest, data.messageText->length == data2.messageText->length); ct_test(pTest, - strcmp(data.messageText->value, data2.messageText->value) == 0); + strcmp(data.messageText->value, data2.messageText->value) == 0); } ct_test(pTest, data.timeStamp.tag == data2.timeStamp.tag); switch (data.timeStamp.tag) { case TIME_STAMP_SEQUENCE: - ct_test(pTest, data.timeStamp.value.sequenceNum == - data2.timeStamp.value.sequenceNum); + ct_test(pTest, + data.timeStamp.value.sequenceNum == + data2.timeStamp.value.sequenceNum); break; case TIME_STAMP_DATETIME: - ct_test(pTest, data.timeStamp.value.dateTime.time.hour == - data2.timeStamp.value.dateTime.time.hour); - ct_test(pTest, data.timeStamp.value.dateTime.time.min == - data2.timeStamp.value.dateTime.time.min); - ct_test(pTest, data.timeStamp.value.dateTime.time.sec == - data2.timeStamp.value.dateTime.time.sec); - ct_test(pTest, data.timeStamp.value.dateTime.time.hundredths == - data2.timeStamp.value.dateTime.time.hundredths); + ct_test(pTest, + data.timeStamp.value.dateTime.time.hour == + data2.timeStamp.value.dateTime.time.hour); + ct_test(pTest, + data.timeStamp.value.dateTime.time.min == + data2.timeStamp.value.dateTime.time.min); + ct_test(pTest, + data.timeStamp.value.dateTime.time.sec == + data2.timeStamp.value.dateTime.time.sec); + ct_test(pTest, + data.timeStamp.value.dateTime.time.hundredths == + data2.timeStamp.value.dateTime.time.hundredths); - ct_test(pTest, data.timeStamp.value.dateTime.date.day == - data2.timeStamp.value.dateTime.date.day); - ct_test(pTest, data.timeStamp.value.dateTime.date.month == - data2.timeStamp.value.dateTime.date.month); - ct_test(pTest, data.timeStamp.value.dateTime.date.wday == - data2.timeStamp.value.dateTime.date.wday); - ct_test(pTest, data.timeStamp.value.dateTime.date.year == - data2.timeStamp.value.dateTime.date.year); + ct_test(pTest, + data.timeStamp.value.dateTime.date.day == + data2.timeStamp.value.dateTime.date.day); + ct_test(pTest, + data.timeStamp.value.dateTime.date.month == + data2.timeStamp.value.dateTime.date.month); + ct_test(pTest, + data.timeStamp.value.dateTime.date.wday == + data2.timeStamp.value.dateTime.date.wday); + ct_test(pTest, + data.timeStamp.value.dateTime.date.year == + data2.timeStamp.value.dateTime.date.year); break; case TIME_STAMP_TIME: - ct_test(pTest, data.timeStamp.value.time.hour == - data2.timeStamp.value.time.hour); - ct_test(pTest, data.timeStamp.value.time.min == - data2.timeStamp.value.time.min); - ct_test(pTest, data.timeStamp.value.time.sec == - data2.timeStamp.value.time.sec); - ct_test(pTest, data.timeStamp.value.time.hundredths == - data2.timeStamp.value.time.hundredths); + ct_test(pTest, + data.timeStamp.value.time.hour == + data2.timeStamp.value.time.hour); + ct_test(pTest, + data.timeStamp.value.time.min == + data2.timeStamp.value.time.min); + ct_test(pTest, + data.timeStamp.value.time.sec == + data2.timeStamp.value.time.sec); + ct_test(pTest, + data.timeStamp.value.time.hundredths == + data2.timeStamp.value.time.hundredths); break; default: @@ -921,8 +929,8 @@ void testEventEventState(Test *pTest) int outLen; BACNET_CHARACTER_STRING messageText; BACNET_CHARACTER_STRING messageText2; - characterstring_init_ansi(&messageText, - "This is a test of the message text\n"); + characterstring_init_ansi( + &messageText, "This is a test of the message text\n"); data.messageText = &messageText; data2.messageText = &messageText2; @@ -947,13 +955,13 @@ void testEventEventState(Test *pTest) bitstring_init(&data.notificationParams.changeOfState.statusFlags); bitstring_set_bit(&data.notificationParams.changeOfState.statusFlags, - STATUS_FLAG_IN_ALARM, true); + STATUS_FLAG_IN_ALARM, true); bitstring_set_bit(&data.notificationParams.changeOfState.statusFlags, - STATUS_FLAG_FAULT, false); + STATUS_FLAG_FAULT, false); bitstring_set_bit(&data.notificationParams.changeOfState.statusFlags, - STATUS_FLAG_OVERRIDDEN, false); + STATUS_FLAG_OVERRIDDEN, false); bitstring_set_bit(&data.notificationParams.changeOfState.statusFlags, - STATUS_FLAG_OUT_OF_SERVICE, false); + STATUS_FLAG_OUT_OF_SERVICE, false); inLen = event_notify_encode_service_request(&buffer[0], &data); @@ -962,15 +970,16 @@ void testEventEventState(Test *pTest) ct_test(pTest, inLen == outLen); testBaseEventState(pTest); - ct_test(pTest, data.notificationParams.changeOfState.newState.tag == - data2.notificationParams.changeOfState.newState.tag); ct_test(pTest, - data.notificationParams.changeOfState.newState.state.units == - data2.notificationParams.changeOfState.newState.state.units); + data.notificationParams.changeOfState.newState.tag == + data2.notificationParams.changeOfState.newState.tag); + ct_test(pTest, + data.notificationParams.changeOfState.newState.state.units == + data2.notificationParams.changeOfState.newState.state.units); - ct_test(pTest, bitstring_same( - &data.notificationParams.changeOfState.statusFlags, - &data2.notificationParams.changeOfState.statusFlags)); + ct_test(pTest, + bitstring_same(&data.notificationParams.changeOfState.statusFlags, + &data2.notificationParams.changeOfState.statusFlags)); /**********************************************************************************/ /**********************************************************************************/ @@ -1003,11 +1012,12 @@ void testEventEventState(Test *pTest) ct_test(pTest, inLen == outLen); testBaseEventState(pTest); - ct_test(pTest, data.notificationParams.changeOfState.newState.tag == - data2.notificationParams.changeOfState.newState.tag); ct_test(pTest, - data.notificationParams.changeOfState.newState.state.units == - data2.notificationParams.changeOfState.newState.state.units); + data.notificationParams.changeOfState.newState.tag == + data2.notificationParams.changeOfState.newState.tag); + ct_test(pTest, + data.notificationParams.changeOfState.newState.state.units == + data2.notificationParams.changeOfState.newState.state.units); /**********************************************************************************/ /**********************************************************************************/ @@ -1043,13 +1053,13 @@ void testEventEventState(Test *pTest) bitstring_init(&data.notificationParams.changeOfBitstring.statusFlags); bitstring_set_bit(&data.notificationParams.changeOfBitstring.statusFlags, - STATUS_FLAG_IN_ALARM, true); + STATUS_FLAG_IN_ALARM, true); bitstring_set_bit(&data.notificationParams.changeOfBitstring.statusFlags, - STATUS_FLAG_FAULT, false); + STATUS_FLAG_FAULT, false); bitstring_set_bit(&data.notificationParams.changeOfBitstring.statusFlags, - STATUS_FLAG_OVERRIDDEN, false); + STATUS_FLAG_OVERRIDDEN, false); bitstring_set_bit(&data.notificationParams.changeOfBitstring.statusFlags, - STATUS_FLAG_OUT_OF_SERVICE, false); + STATUS_FLAG_OUT_OF_SERVICE, false); memset(buffer, 0, MAX_APDU); inLen = event_notify_encode_service_request(&buffer[0], &data); @@ -1061,16 +1071,14 @@ void testEventEventState(Test *pTest) ct_test(pTest, inLen == outLen); testBaseEventState(pTest); - ct_test( - pTest, + ct_test(pTest, bitstring_same( &data.notificationParams.changeOfBitstring.referencedBitString, &data2.notificationParams.changeOfBitstring.referencedBitString)); ct_test(pTest, - bitstring_same( - &data.notificationParams.changeOfBitstring.statusFlags, - &data2.notificationParams.changeOfBitstring.statusFlags)); + bitstring_same(&data.notificationParams.changeOfBitstring.statusFlags, + &data2.notificationParams.changeOfBitstring.statusFlags)); /**********************************************************************************/ /**********************************************************************************/ @@ -1090,13 +1098,13 @@ void testEventEventState(Test *pTest) bitstring_init(&data.notificationParams.changeOfValue.statusFlags); bitstring_set_bit(&data.notificationParams.changeOfValue.statusFlags, - STATUS_FLAG_IN_ALARM, true); + STATUS_FLAG_IN_ALARM, true); bitstring_set_bit(&data.notificationParams.changeOfValue.statusFlags, - STATUS_FLAG_FAULT, false); + STATUS_FLAG_FAULT, false); bitstring_set_bit(&data.notificationParams.changeOfValue.statusFlags, - STATUS_FLAG_OVERRIDDEN, false); + STATUS_FLAG_OVERRIDDEN, false); bitstring_set_bit(&data.notificationParams.changeOfValue.statusFlags, - STATUS_FLAG_OUT_OF_SERVICE, false); + STATUS_FLAG_OUT_OF_SERVICE, false); memset(buffer, 0, MAX_APDU); inLen = event_notify_encode_service_request(&buffer[0], &data); @@ -1108,16 +1116,17 @@ void testEventEventState(Test *pTest) ct_test(pTest, inLen == outLen); testBaseEventState(pTest); - ct_test(pTest, bitstring_same( - &data.notificationParams.changeOfValue.statusFlags, - &data2.notificationParams.changeOfValue.statusFlags)); - - ct_test(pTest, data.notificationParams.changeOfValue.tag == - data2.notificationParams.changeOfValue.tag); + ct_test(pTest, + bitstring_same(&data.notificationParams.changeOfValue.statusFlags, + &data2.notificationParams.changeOfValue.statusFlags)); ct_test(pTest, - data.notificationParams.changeOfValue.newValue.changeValue == - data2.notificationParams.changeOfValue.newValue.changeValue); + data.notificationParams.changeOfValue.tag == + data2.notificationParams.changeOfValue.tag); + + ct_test(pTest, + data.notificationParams.changeOfValue.newValue.changeValue == + data2.notificationParams.changeOfValue.newValue.changeValue); /* ** Event Type = EVENT_CHANGE_OF_VALUE - bitstring value @@ -1145,17 +1154,18 @@ void testEventEventState(Test *pTest) ct_test(pTest, inLen == outLen); testBaseEventState(pTest); - ct_test(pTest, bitstring_same( - &data.notificationParams.changeOfValue.statusFlags, - &data2.notificationParams.changeOfValue.statusFlags)); - - ct_test(pTest, data.notificationParams.changeOfValue.tag == - data2.notificationParams.changeOfValue.tag); + ct_test(pTest, + bitstring_same(&data.notificationParams.changeOfValue.statusFlags, + &data2.notificationParams.changeOfValue.statusFlags)); ct_test(pTest, - bitstring_same( - &data.notificationParams.changeOfValue.newValue.changedBits, - &data2.notificationParams.changeOfValue.newValue.changedBits)); + data.notificationParams.changeOfValue.tag == + data2.notificationParams.changeOfValue.tag); + + ct_test(pTest, + bitstring_same( + &data.notificationParams.changeOfValue.newValue.changedBits, + &data2.notificationParams.changeOfValue.newValue.changedBits)); /**********************************************************************************/ /**********************************************************************************/ @@ -1175,13 +1185,13 @@ void testEventEventState(Test *pTest) bitstring_init(&data.notificationParams.floatingLimit.statusFlags); bitstring_set_bit(&data.notificationParams.floatingLimit.statusFlags, - STATUS_FLAG_IN_ALARM, true); + STATUS_FLAG_IN_ALARM, true); bitstring_set_bit(&data.notificationParams.floatingLimit.statusFlags, - STATUS_FLAG_FAULT, false); + STATUS_FLAG_FAULT, false); bitstring_set_bit(&data.notificationParams.floatingLimit.statusFlags, - STATUS_FLAG_OVERRIDDEN, false); + STATUS_FLAG_OVERRIDDEN, false); bitstring_set_bit(&data.notificationParams.floatingLimit.statusFlags, - STATUS_FLAG_OUT_OF_SERVICE, false); + STATUS_FLAG_OUT_OF_SERVICE, false); memset(buffer, 0, MAX_APDU); inLen = event_notify_encode_service_request(&buffer[0], &data); @@ -1193,17 +1203,20 @@ void testEventEventState(Test *pTest) ct_test(pTest, inLen == outLen); testBaseEventState(pTest); - ct_test(pTest, data.notificationParams.floatingLimit.referenceValue == - data2.notificationParams.floatingLimit.referenceValue); + ct_test(pTest, + data.notificationParams.floatingLimit.referenceValue == + data2.notificationParams.floatingLimit.referenceValue); - ct_test(pTest, data.notificationParams.floatingLimit.setPointValue == - data2.notificationParams.floatingLimit.setPointValue); + ct_test(pTest, + data.notificationParams.floatingLimit.setPointValue == + data2.notificationParams.floatingLimit.setPointValue); - ct_test(pTest, data.notificationParams.floatingLimit.errorLimit == - data2.notificationParams.floatingLimit.errorLimit); - ct_test(pTest, bitstring_same( - &data.notificationParams.floatingLimit.statusFlags, - &data2.notificationParams.floatingLimit.statusFlags)); + ct_test(pTest, + data.notificationParams.floatingLimit.errorLimit == + data2.notificationParams.floatingLimit.errorLimit); + ct_test(pTest, + bitstring_same(&data.notificationParams.floatingLimit.statusFlags, + &data2.notificationParams.floatingLimit.statusFlags)); /**********************************************************************************/ /**********************************************************************************/ @@ -1223,13 +1236,13 @@ void testEventEventState(Test *pTest) bitstring_init(&data.notificationParams.outOfRange.statusFlags); bitstring_set_bit(&data.notificationParams.outOfRange.statusFlags, - STATUS_FLAG_IN_ALARM, true); + STATUS_FLAG_IN_ALARM, true); bitstring_set_bit(&data.notificationParams.outOfRange.statusFlags, - STATUS_FLAG_FAULT, false); + STATUS_FLAG_FAULT, false); bitstring_set_bit(&data.notificationParams.outOfRange.statusFlags, - STATUS_FLAG_OVERRIDDEN, false); + STATUS_FLAG_OVERRIDDEN, false); bitstring_set_bit(&data.notificationParams.outOfRange.statusFlags, - STATUS_FLAG_OUT_OF_SERVICE, false); + STATUS_FLAG_OUT_OF_SERVICE, false); memset(buffer, 0, MAX_APDU); inLen = event_notify_encode_service_request(&buffer[0], &data); @@ -1241,17 +1254,20 @@ void testEventEventState(Test *pTest) ct_test(pTest, inLen == outLen); testBaseEventState(pTest); - ct_test(pTest, data.notificationParams.outOfRange.deadband == - data2.notificationParams.outOfRange.deadband); - - ct_test(pTest, data.notificationParams.outOfRange.exceededLimit == - data2.notificationParams.outOfRange.exceededLimit); - - ct_test(pTest, data.notificationParams.outOfRange.exceedingValue == - data2.notificationParams.outOfRange.exceedingValue); ct_test(pTest, - bitstring_same(&data.notificationParams.outOfRange.statusFlags, - &data2.notificationParams.outOfRange.statusFlags)); + data.notificationParams.outOfRange.deadband == + data2.notificationParams.outOfRange.deadband); + + ct_test(pTest, + data.notificationParams.outOfRange.exceededLimit == + data2.notificationParams.outOfRange.exceededLimit); + + ct_test(pTest, + data.notificationParams.outOfRange.exceedingValue == + data2.notificationParams.outOfRange.exceedingValue); + ct_test(pTest, + bitstring_same(&data.notificationParams.outOfRange.statusFlags, + &data2.notificationParams.outOfRange.statusFlags)); /**********************************************************************************/ /**********************************************************************************/ @@ -1273,13 +1289,13 @@ void testEventEventState(Test *pTest) bitstring_init(&data.notificationParams.changeOfLifeSafety.statusFlags); bitstring_set_bit(&data.notificationParams.changeOfLifeSafety.statusFlags, - STATUS_FLAG_IN_ALARM, true); + STATUS_FLAG_IN_ALARM, true); bitstring_set_bit(&data.notificationParams.changeOfLifeSafety.statusFlags, - STATUS_FLAG_FAULT, false); + STATUS_FLAG_FAULT, false); bitstring_set_bit(&data.notificationParams.changeOfLifeSafety.statusFlags, - STATUS_FLAG_OVERRIDDEN, false); + STATUS_FLAG_OVERRIDDEN, false); bitstring_set_bit(&data.notificationParams.changeOfLifeSafety.statusFlags, - STATUS_FLAG_OUT_OF_SERVICE, false); + STATUS_FLAG_OUT_OF_SERVICE, false); memset(buffer, 0, MAX_APDU); inLen = event_notify_encode_service_request(&buffer[0], &data); @@ -1291,20 +1307,21 @@ void testEventEventState(Test *pTest) ct_test(pTest, inLen == outLen); testBaseEventState(pTest); - ct_test(pTest, data.notificationParams.changeOfLifeSafety.newMode == - data2.notificationParams.changeOfLifeSafety.newMode); - - ct_test(pTest, data.notificationParams.changeOfLifeSafety.newState == - data2.notificationParams.changeOfLifeSafety.newState); + ct_test(pTest, + data.notificationParams.changeOfLifeSafety.newMode == + data2.notificationParams.changeOfLifeSafety.newMode); ct_test(pTest, - data.notificationParams.changeOfLifeSafety.operationExpected == - data2.notificationParams.changeOfLifeSafety.operationExpected); + data.notificationParams.changeOfLifeSafety.newState == + data2.notificationParams.changeOfLifeSafety.newState); ct_test(pTest, - bitstring_same( - &data.notificationParams.changeOfLifeSafety.statusFlags, - &data2.notificationParams.changeOfLifeSafety.statusFlags)); + data.notificationParams.changeOfLifeSafety.operationExpected == + data2.notificationParams.changeOfLifeSafety.operationExpected); + + ct_test(pTest, + bitstring_same(&data.notificationParams.changeOfLifeSafety.statusFlags, + &data2.notificationParams.changeOfLifeSafety.statusFlags)); /**********************************************************************************/ /**********************************************************************************/ @@ -1323,13 +1340,13 @@ void testEventEventState(Test *pTest) bitstring_init(&data.notificationParams.unsignedRange.statusFlags); bitstring_set_bit(&data.notificationParams.unsignedRange.statusFlags, - STATUS_FLAG_IN_ALARM, true); + STATUS_FLAG_IN_ALARM, true); bitstring_set_bit(&data.notificationParams.unsignedRange.statusFlags, - STATUS_FLAG_FAULT, false); + STATUS_FLAG_FAULT, false); bitstring_set_bit(&data.notificationParams.unsignedRange.statusFlags, - STATUS_FLAG_OVERRIDDEN, false); + STATUS_FLAG_OVERRIDDEN, false); bitstring_set_bit(&data.notificationParams.unsignedRange.statusFlags, - STATUS_FLAG_OUT_OF_SERVICE, false); + STATUS_FLAG_OUT_OF_SERVICE, false); memset(buffer, 0, MAX_APDU); inLen = event_notify_encode_service_request(&buffer[0], &data); @@ -1341,15 +1358,17 @@ void testEventEventState(Test *pTest) ct_test(pTest, inLen == outLen); testBaseEventState(pTest); - ct_test(pTest, data.notificationParams.unsignedRange.exceedingValue == - data2.notificationParams.unsignedRange.exceedingValue); + ct_test(pTest, + data.notificationParams.unsignedRange.exceedingValue == + data2.notificationParams.unsignedRange.exceedingValue); - ct_test(pTest, data.notificationParams.unsignedRange.exceededLimit == - data2.notificationParams.unsignedRange.exceededLimit); + ct_test(pTest, + data.notificationParams.unsignedRange.exceededLimit == + data2.notificationParams.unsignedRange.exceededLimit); - ct_test(pTest, bitstring_same( - &data.notificationParams.unsignedRange.statusFlags, - &data2.notificationParams.unsignedRange.statusFlags)); + ct_test(pTest, + bitstring_same(&data.notificationParams.unsignedRange.statusFlags, + &data2.notificationParams.unsignedRange.statusFlags)); /**********************************************************************************/ /**********************************************************************************/ @@ -1387,42 +1406,45 @@ void testEventEventState(Test *pTest) testBaseEventState(pTest); ct_test(pTest, - data.notificationParams.bufferReady.previousNotification == - data2.notificationParams.bufferReady.previousNotification); + data.notificationParams.bufferReady.previousNotification == + data2.notificationParams.bufferReady.previousNotification); ct_test(pTest, - data.notificationParams.bufferReady.currentNotification == - data2.notificationParams.bufferReady.currentNotification); + data.notificationParams.bufferReady.currentNotification == + data2.notificationParams.bufferReady.currentNotification); ct_test(pTest, - data.notificationParams.bufferReady.bufferProperty.deviceIdentifier - .type == data2.notificationParams.bufferReady.bufferProperty - .deviceIdentifier.type); + data.notificationParams.bufferReady.bufferProperty.deviceIdentifier + .type == + data2.notificationParams.bufferReady.bufferProperty.deviceIdentifier + .type); ct_test(pTest, - data.notificationParams.bufferReady.bufferProperty.deviceIdentifier - .instance == data2.notificationParams.bufferReady - .bufferProperty.deviceIdentifier.instance); + data.notificationParams.bufferReady.bufferProperty.deviceIdentifier + .instance == + data2.notificationParams.bufferReady.bufferProperty.deviceIdentifier + .instance); ct_test(pTest, - data.notificationParams.bufferReady.bufferProperty.objectIdentifier - .instance == data2.notificationParams.bufferReady - .bufferProperty.objectIdentifier.instance); + data.notificationParams.bufferReady.bufferProperty.objectIdentifier + .instance == + data2.notificationParams.bufferReady.bufferProperty.objectIdentifier + .instance); ct_test(pTest, - data.notificationParams.bufferReady.bufferProperty.objectIdentifier - .type == data2.notificationParams.bufferReady.bufferProperty - .objectIdentifier.type); + data.notificationParams.bufferReady.bufferProperty.objectIdentifier + .type == + data2.notificationParams.bufferReady.bufferProperty.objectIdentifier + .type); - ct_test( - pTest, + ct_test(pTest, data.notificationParams.bufferReady.bufferProperty.propertyIdentifier == data2.notificationParams.bufferReady.bufferProperty .propertyIdentifier); ct_test(pTest, - data.notificationParams.bufferReady.bufferProperty.arrayIndex == - data2.notificationParams.bufferReady.bufferProperty.arrayIndex); + data.notificationParams.bufferReady.bufferProperty.arrayIndex == + data2.notificationParams.bufferReady.bufferProperty.arrayIndex); } #ifdef TEST_EVENT diff --git a/include/event.h b/src/bacnet/event.h similarity index 98% rename from include/event.h rename to src/bacnet/event.h index a1854aae..25e93b61 100644 --- a/include/event.h +++ b/src/bacnet/event.h @@ -24,13 +24,13 @@ #ifndef BACNET_EVENT_H_ #define BACNET_EVENT_H_ -#include "bacenum.h" #include #include -#include "bacapp.h" -#include "timestamp.h" -#include "bacpropstates.h" -#include "bacdevobjpropref.h" +#include "bacnet/bacenum.h" +#include "bacnet/bacapp.h" +#include "bacnet/timestamp.h" +#include "bacnet/bacpropstates.h" +#include "bacnet/bacdevobjpropref.h" typedef enum { CHANGE_OF_VALUE_BITS, diff --git a/src/get_alarm_sum.c b/src/bacnet/get_alarm_sum.c similarity index 86% rename from src/get_alarm_sum.c rename to src/bacnet/get_alarm_sum.c index 7277cad3..c271a371 100644 --- a/src/get_alarm_sum.c +++ b/src/bacnet/get_alarm_sum.c @@ -38,12 +38,12 @@ */ #include -#include "bacdcode.h" -#include "get_alarm_sum.h" -#include "npdu.h" +#include "bacnet/bacdcode.h" +#include "bacnet/get_alarm_sum.h" +#include "bacnet/npdu.h" /* encode service */ -int get_alarm_summary_encode_apdu(uint8_t* apdu, uint8_t invoke_id) +int get_alarm_summary_encode_apdu(uint8_t *apdu, uint8_t invoke_id) { int apdu_len = 0; /* total length of the apdu, return value */ @@ -65,13 +65,13 @@ int get_alarm_summary_encode_apdu(uint8_t* apdu, uint8_t invoke_id) * * @return number of bytes encoded */ -int get_alarm_summary_ack_encode_apdu_init(uint8_t* apdu, uint8_t invoke_id) +int get_alarm_summary_ack_encode_apdu_init(uint8_t *apdu, uint8_t invoke_id) { int apdu_len = 0; /* total length of the apdu, return value */ if (apdu) { apdu[0] = PDU_TYPE_COMPLEX_ACK; /* complex ACK service */ - apdu[1] = invoke_id; /* original invoke id from request */ + apdu[1] = invoke_id; /* original invoke id from request */ apdu[2] = SERVICE_CONFIRMED_GET_ALARM_SUMMARY; apdu_len = 3; } @@ -87,9 +87,9 @@ int get_alarm_summary_ack_encode_apdu_init(uint8_t* apdu, uint8_t invoke_id) * * @return number of bytes encoded, or BACNET_STATUS_ERROR if an error. */ -int get_alarm_summary_ack_encode_apdu_data( - uint8_t* apdu, size_t max_apdu, - BACNET_GET_ALARM_SUMMARY_DATA* get_alarm_data) +int get_alarm_summary_ack_encode_apdu_data(uint8_t *apdu, + size_t max_apdu, + BACNET_GET_ALARM_SUMMARY_DATA *get_alarm_data) { int apdu_len = 0; /* total length of the apdu, return value */ @@ -97,12 +97,12 @@ int get_alarm_summary_ack_encode_apdu_data( apdu_len = BACNET_STATUS_ERROR; } else if (max_apdu >= 10) { /* tag 0 - Object Identifier */ - apdu_len += encode_application_object_id( - &apdu[apdu_len], (int)get_alarm_data->objectIdentifier.type, + apdu_len += encode_application_object_id(&apdu[apdu_len], + (int)get_alarm_data->objectIdentifier.type, get_alarm_data->objectIdentifier.instance); /* tag 1 - Alarm State */ - apdu_len += encode_application_enumerated(&apdu[apdu_len], - get_alarm_data->alarmState); + apdu_len += encode_application_enumerated( + &apdu[apdu_len], get_alarm_data->alarmState); /* tag 2 - Acknowledged Transitions */ apdu_len += encode_application_bitstring( &apdu[apdu_len], &get_alarm_data->acknowledgedTransitions); @@ -121,9 +121,9 @@ int get_alarm_summary_ack_encode_apdu_data( * * @return number of bytes decoded, or BACNET_STATUS_ERROR if an error. */ -int get_alarm_summary_ack_decode_apdu_data( - uint8_t* apdu, size_t max_apdu, - BACNET_GET_ALARM_SUMMARY_DATA* get_alarm_data) +int get_alarm_summary_ack_decode_apdu_data(uint8_t *apdu, + size_t max_apdu, + BACNET_GET_ALARM_SUMMARY_DATA *get_alarm_data) { int apdu_len = 0; /* total length of the apdu, return value */ BACNET_APPLICATION_DATA_VALUE value; diff --git a/include/get_alarm_sum.h b/src/bacnet/get_alarm_sum.h similarity index 97% rename from include/get_alarm_sum.h rename to src/bacnet/get_alarm_sum.h index fab89548..e89d28b9 100644 --- a/include/get_alarm_sum.h +++ b/src/bacnet/get_alarm_sum.h @@ -26,11 +26,11 @@ #ifndef BACNET_GET_ALARM_SUM_H_ #define BACNET_GET_ALARM_SUM_H_ -#include "bacenum.h" #include #include -#include "bacapp.h" -#include "timestamp.h" +#include "bacnet/bacenum.h" +#include "bacnet/bacapp.h" +#include "bacnet/timestamp.h" typedef struct BACnet_Get_Alarm_Summary_Data { diff --git a/src/getevent.c b/src/bacnet/getevent.c similarity index 65% rename from src/getevent.c rename to src/bacnet/getevent.c index 2b00bc14..a95aff5c 100644 --- a/src/getevent.c +++ b/src/bacnet/getevent.c @@ -32,18 +32,19 @@ ------------------------------------------- ####COPYRIGHTEND####*/ #include -#include "bacenum.h" -#include "bacdcode.h" -#include "bacdef.h" -#include "getevent.h" +#include "bacnet/bacenum.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacdef.h" +#include "bacnet/getevent.h" /** @file getevent.c Encode/Decode GetEvent services */ /* encode service */ -int getevent_encode_apdu(uint8_t *apdu, uint8_t invoke_id, - BACNET_OBJECT_ID *lastReceivedObjectIdentifier) +int getevent_encode_apdu(uint8_t *apdu, + uint8_t invoke_id, + BACNET_OBJECT_ID *lastReceivedObjectIdentifier) { - int len = 0; /* length of each encoding */ + int len = 0; /* length of each encoding */ int apdu_len = 0; /* total length of the apdu, return value */ if (apdu) { @@ -54,8 +55,8 @@ int getevent_encode_apdu(uint8_t *apdu, uint8_t invoke_id, apdu_len = 4; /* encode optional parameter */ if (lastReceivedObjectIdentifier) { - len = encode_context_object_id( - &apdu[apdu_len], 0, (int)lastReceivedObjectIdentifier->type, + len = encode_context_object_id(&apdu[apdu_len], 0, + (int)lastReceivedObjectIdentifier->type, lastReceivedObjectIdentifier->instance); apdu_len += len; } @@ -65,8 +66,8 @@ int getevent_encode_apdu(uint8_t *apdu, uint8_t invoke_id, } /* decode the service request only */ -int getevent_decode_service_request( - uint8_t *apdu, unsigned apdu_len, +int getevent_decode_service_request(uint8_t *apdu, + unsigned apdu_len, BACNET_OBJECT_ID *lastReceivedObjectIdentifier) { unsigned len = 0; @@ -74,23 +75,24 @@ int getevent_decode_service_request( /* check for value pointers */ if (apdu_len && lastReceivedObjectIdentifier) { /* Tag 0: Object ID - optional */ - if (!decode_is_context_tag(&apdu[len++], 0)) + if (!decode_is_context_tag(&apdu[len++], 0)) { return -1; + } len += decode_object_id(&apdu[len], &lastReceivedObjectIdentifier->type, - &lastReceivedObjectIdentifier->instance); + &lastReceivedObjectIdentifier->instance); } return (int)len; } -int getevent_ack_encode_apdu_init(uint8_t *apdu, size_t max_apdu, - uint8_t invoke_id) +int getevent_ack_encode_apdu_init( + uint8_t *apdu, size_t max_apdu, uint8_t invoke_id) { int apdu_len = 0; /* total length of the apdu, return value */ if (apdu && (max_apdu >= 4)) { apdu[0] = PDU_TYPE_COMPLEX_ACK; /* complex ACK service */ - apdu[1] = invoke_id; /* original invoke id from request */ + apdu[1] = invoke_id; /* original invoke id from request */ apdu[2] = SERVICE_CONFIRMED_GET_EVENT_INFORMATION; apdu_len = 3; /* service ack follows */ @@ -101,8 +103,8 @@ int getevent_ack_encode_apdu_init(uint8_t *apdu, size_t max_apdu, return apdu_len; } -int getevent_ack_encode_apdu_data( - uint8_t *apdu, size_t max_apdu, +int getevent_ack_encode_apdu_data(uint8_t *apdu, + size_t max_apdu, BACNET_GET_EVENT_INFORMATION_DATA *get_event_data) { int apdu_len = 0; /* total length of the apdu, return value */ @@ -115,12 +117,12 @@ int getevent_ack_encode_apdu_data( event_data = get_event_data; while (event_data) { /* Tag 0: objectIdentifier */ - apdu_len += encode_context_object_id( - &apdu[apdu_len], 0, (int)event_data->objectIdentifier.type, + apdu_len += encode_context_object_id(&apdu[apdu_len], 0, + (int)event_data->objectIdentifier.type, event_data->objectIdentifier.instance); /* Tag 1: eventState */ - apdu_len += encode_context_enumerated(&apdu[apdu_len], 1, - event_data->eventState); + apdu_len += encode_context_enumerated( + &apdu[apdu_len], 1, event_data->eventState); /* Tag 2: acknowledgedTransitions */ apdu_len += encode_context_bitstring( &apdu[apdu_len], 2, &event_data->acknowledgedTransitions); @@ -132,11 +134,11 @@ int getevent_ack_encode_apdu_data( } apdu_len += encode_closing_tag(&apdu[apdu_len], 3); /* Tag 4: notifyType */ - apdu_len += encode_context_enumerated(&apdu[apdu_len], 4, - event_data->notifyType); + apdu_len += encode_context_enumerated( + &apdu[apdu_len], 4, event_data->notifyType); /* Tag 5: eventEnable */ - apdu_len += encode_context_bitstring(&apdu[apdu_len], 5, - &event_data->eventEnable); + apdu_len += encode_context_bitstring( + &apdu[apdu_len], 5, &event_data->eventEnable); /* Tag 6: eventPriorities */ apdu_len += encode_opening_tag(&apdu[apdu_len], 6); for (i = 0; i < 3; i++) { @@ -151,8 +153,8 @@ int getevent_ack_encode_apdu_data( return apdu_len; } -int getevent_ack_encode_apdu_end(uint8_t *apdu, size_t max_apdu, - bool moreEvents) +int getevent_ack_encode_apdu_end( + uint8_t *apdu, size_t max_apdu, bool moreEvents) { int apdu_len = 0; /* total length of the apdu, return value */ @@ -166,13 +168,14 @@ int getevent_ack_encode_apdu_end(uint8_t *apdu, size_t max_apdu, return apdu_len; } -int getevent_ack_decode_service_request( - uint8_t *apdu, int apdu_len, /* total length of the apdu */ - BACNET_GET_EVENT_INFORMATION_DATA *get_event_data, bool *moreEvents) +int getevent_ack_decode_service_request(uint8_t *apdu, + int apdu_len, /* total length of the apdu */ + BACNET_GET_EVENT_INFORMATION_DATA *get_event_data, + bool *moreEvents) { uint8_t tag_number = 0; uint32_t len_value = 0; - int len = 0; /* total length of decodes */ + int len = 0; /* total length of decodes */ uint32_t enum_value = 0; /* for decoding */ BACNET_GET_EVENT_INFORMATION_DATA *event_data; unsigned i = 0; /* counter */ @@ -187,18 +190,18 @@ int getevent_ack_decode_service_request( while (event_data) { /* Tag 0: objectIdentifier */ if (decode_is_context_tag(&apdu[len], 0)) { - len += decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value); + len += decode_tag_number_and_value( + &apdu[len], &tag_number, &len_value); len += decode_object_id(&apdu[len], - &event_data->objectIdentifier.type, - &event_data->objectIdentifier.instance); + &event_data->objectIdentifier.type, + &event_data->objectIdentifier.instance); } else { return -1; } /* Tag 1: eventState */ if (decode_is_context_tag(&apdu[len], 1)) { - len += decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value); + len += decode_tag_number_and_value( + &apdu[len], &tag_number, &len_value); len += decode_enumerated(&apdu[len], len_value, &enum_value); event_data->eventState = enum_value; } else { @@ -206,17 +209,17 @@ int getevent_ack_decode_service_request( } /* Tag 2: acknowledgedTransitions */ if (decode_is_context_tag(&apdu[len], 2)) { - len += decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value); + len += decode_tag_number_and_value( + &apdu[len], &tag_number, &len_value); len += decode_bitstring(&apdu[len], len_value, - &event_data->acknowledgedTransitions); + &event_data->acknowledgedTransitions); } else { return -1; } /* Tag 3: eventTimeStamps */ if (decode_is_opening_tag_number(&apdu[len], 3)) { - len += decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value); + len += decode_tag_number_and_value( + &apdu[len], &tag_number, &len_value); for (i = 0; i < 3; i++) { len += bacapp_decode_timestamp( &apdu[len], &event_data->eventTimeStamps[i]); @@ -225,15 +228,15 @@ int getevent_ack_decode_service_request( return -1; } if (decode_is_closing_tag_number(&apdu[len], 3)) { - len += decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value); + len += decode_tag_number_and_value( + &apdu[len], &tag_number, &len_value); } else { return -1; } /* Tag 4: notifyType */ if (decode_is_context_tag(&apdu[len], 4)) { - len += decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value); + len += decode_tag_number_and_value( + &apdu[len], &tag_number, &len_value); len += decode_enumerated(&apdu[len], len_value, &enum_value); event_data->notifyType = enum_value; } else { @@ -241,46 +244,47 @@ int getevent_ack_decode_service_request( } /* Tag 5: eventEnable */ if (decode_is_context_tag(&apdu[len], 5)) { - len += decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value); - len += decode_bitstring(&apdu[len], len_value, - &event_data->eventEnable); + len += decode_tag_number_and_value( + &apdu[len], &tag_number, &len_value); + len += decode_bitstring( + &apdu[len], len_value, &event_data->eventEnable); } else { return -1; } /* Tag 6: eventPriorities */ if (decode_is_opening_tag_number(&apdu[len], 6)) { - len += decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value); + len += decode_tag_number_and_value( + &apdu[len], &tag_number, &len_value); for (i = 0; i < 3; i++) { - len += decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value); - len += decode_unsigned(&apdu[len], len_value, - &event_data->eventPriorities[i]); + len += decode_tag_number_and_value( + &apdu[len], &tag_number, &len_value); + len += decode_unsigned( + &apdu[len], len_value, &event_data->eventPriorities[i]); } } else { return -1; } if (decode_is_closing_tag_number(&apdu[len], 6)) { - len += decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value); + len += decode_tag_number_and_value( + &apdu[len], &tag_number, &len_value); } else { return -1; } if (decode_is_closing_tag_number(&apdu[len], 0)) { - len += decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value); + len += decode_tag_number_and_value( + &apdu[len], &tag_number, &len_value); event_data->next = NULL; } event_data = event_data->next; } if (decode_is_context_tag(&apdu[len], 1)) { - len += decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value); - if (len_value == 1) + len += decode_tag_number_and_value( + &apdu[len], &tag_number, &len_value); + if (len_value == 1) { *moreEvents = decode_context_boolean(&apdu[len++]); - else + } else { *moreEvents = false; + } } else { return -1; } @@ -294,8 +298,10 @@ int getevent_ack_decode_service_request( #include #include "ctest.h" -int getevent_decode_apdu(uint8_t *apdu, unsigned apdu_len, uint8_t *invoke_id, - BACNET_OBJECT_ID *lastReceivedObjectIdentifier) +int getevent_decode_apdu(uint8_t *apdu, + unsigned apdu_len, + uint8_t *invoke_id, + BACNET_OBJECT_ID *lastReceivedObjectIdentifier) { int len = 0; unsigned offset = 0; @@ -312,18 +318,18 @@ int getevent_decode_apdu(uint8_t *apdu, unsigned apdu_len, uint8_t *invoke_id, offset = 4; if (apdu_len > offset) { - len = getevent_decode_service_request(&apdu[offset], apdu_len - offset, - lastReceivedObjectIdentifier); + len = getevent_decode_service_request( + &apdu[offset], apdu_len - offset, lastReceivedObjectIdentifier); } return len; } int getevent_ack_decode_apdu(uint8_t *apdu, - int apdu_len, /* total length of the apdu */ - uint8_t *invoke_id, - BACNET_GET_EVENT_INFORMATION_DATA *get_event_data, - bool *moreEvents) + int apdu_len, /* total length of the apdu */ + uint8_t *invoke_id, + BACNET_GET_EVENT_INFORMATION_DATA *get_event_data, + bool *moreEvents) { int len = 0; int offset = 0; @@ -347,7 +353,7 @@ int getevent_ack_decode_apdu(uint8_t *apdu, void testGetEventInformationAck(Test *pTest) { - uint8_t apdu[480] = {0}; + uint8_t apdu[480] = { 0 }; int len = 0; int apdu_len = 0; uint8_t invoke_id = 1; @@ -362,12 +368,12 @@ void testGetEventInformationAck(Test *pTest) event_data.objectIdentifier.instance = 1; event_data.eventState = EVENT_STATE_NORMAL; bitstring_init(&event_data.acknowledgedTransitions); - bitstring_set_bit(&event_data.acknowledgedTransitions, - TRANSITION_TO_OFFNORMAL, false); - bitstring_set_bit(&event_data.acknowledgedTransitions, TRANSITION_TO_FAULT, - false); - bitstring_set_bit(&event_data.acknowledgedTransitions, TRANSITION_TO_NORMAL, - false); + bitstring_set_bit( + &event_data.acknowledgedTransitions, TRANSITION_TO_OFFNORMAL, false); + bitstring_set_bit( + &event_data.acknowledgedTransitions, TRANSITION_TO_FAULT, false); + bitstring_set_bit( + &event_data.acknowledgedTransitions, TRANSITION_TO_NORMAL, false); for (i = 0; i < 3; i++) { event_data.eventTimeStamps[i].tag = TIME_STAMP_SEQUENCE; event_data.eventTimeStamps[i].value.sequenceNum = 0; @@ -386,33 +392,35 @@ void testGetEventInformationAck(Test *pTest) ct_test(pTest, len != 0); ct_test(pTest, len != -1); apdu_len = len; - len = getevent_ack_encode_apdu_data(&apdu[apdu_len], - sizeof(apdu) - apdu_len, &event_data); + len = getevent_ack_encode_apdu_data( + &apdu[apdu_len], sizeof(apdu) - apdu_len, &event_data); ct_test(pTest, len != 0); ct_test(pTest, len != -1); apdu_len += len; - len = getevent_ack_encode_apdu_end(&apdu[apdu_len], sizeof(apdu) - apdu_len, - moreEvents); + len = getevent_ack_encode_apdu_end( + &apdu[apdu_len], sizeof(apdu) - apdu_len, moreEvents); ct_test(pTest, len != 0); ct_test(pTest, len != -1); apdu_len += len; - len = getevent_ack_decode_apdu( - &apdu[0], apdu_len, /* total length of the apdu */ + len = getevent_ack_decode_apdu(&apdu[0], + apdu_len, /* total length of the apdu */ &test_invoke_id, &test_event_data, &test_moreEvents); ct_test(pTest, len != -1); ct_test(pTest, test_invoke_id == invoke_id); - ct_test(pTest, event_data.objectIdentifier.type == - test_event_data.objectIdentifier.type); - ct_test(pTest, event_data.objectIdentifier.instance == - test_event_data.objectIdentifier.instance); + ct_test(pTest, + event_data.objectIdentifier.type == + test_event_data.objectIdentifier.type); + ct_test(pTest, + event_data.objectIdentifier.instance == + test_event_data.objectIdentifier.instance); ct_test(pTest, event_data.eventState == test_event_data.eventState); } void testGetEventInformation(Test *pTest) { - uint8_t apdu[480] = {0}; + uint8_t apdu[480] = { 0 }; int len = 0; int apdu_len = 0; uint8_t invoke_id = 128; @@ -422,19 +430,21 @@ void testGetEventInformation(Test *pTest) lastReceivedObjectIdentifier.type = OBJECT_BINARY_INPUT; lastReceivedObjectIdentifier.instance = 12345; - len = getevent_encode_apdu(&apdu[0], invoke_id, - &lastReceivedObjectIdentifier); + len = getevent_encode_apdu( + &apdu[0], invoke_id, &lastReceivedObjectIdentifier); ct_test(pTest, len != 0); apdu_len = len; len = getevent_decode_apdu(&apdu[0], apdu_len, &test_invoke_id, - &test_lastReceivedObjectIdentifier); + &test_lastReceivedObjectIdentifier); ct_test(pTest, len != -1); ct_test(pTest, test_invoke_id == invoke_id); - ct_test(pTest, test_lastReceivedObjectIdentifier.type == - lastReceivedObjectIdentifier.type); - ct_test(pTest, test_lastReceivedObjectIdentifier.instance == - lastReceivedObjectIdentifier.instance); + ct_test(pTest, + test_lastReceivedObjectIdentifier.type == + lastReceivedObjectIdentifier.type); + ct_test(pTest, + test_lastReceivedObjectIdentifier.instance == + lastReceivedObjectIdentifier.instance); return; } diff --git a/include/getevent.h b/src/bacnet/getevent.h similarity index 96% rename from include/getevent.h rename to src/bacnet/getevent.h index eaccdf7b..3aa1edd8 100644 --- a/include/getevent.h +++ b/src/bacnet/getevent.h @@ -26,10 +26,10 @@ #include #include -#include "bacdef.h" -#include "bacenum.h" -#include "timestamp.h" -#include "event.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacenum.h" +#include "bacnet/timestamp.h" +#include "bacnet/event.h" struct BACnet_Get_Event_Information_Data; typedef struct BACnet_Get_Event_Information_Data { diff --git a/src/iam.c b/src/bacnet/iam.c old mode 100755 new mode 100644 similarity index 75% rename from src/iam.c rename to src/bacnet/iam.c index 789de093..0762ee51 --- a/src/iam.c +++ b/src/bacnet/iam.c @@ -32,34 +32,36 @@ ------------------------------------------- ####COPYRIGHTEND####*/ #include -#include "bacenum.h" -#include "bacdef.h" -#include "npdu.h" -#include "dcc.h" -#include "bacdcode.h" -#include "address.h" -#include "iam.h" +#include "bacnet/bacenum.h" +#include "bacnet/bacdef.h" +#include "bacnet/npdu.h" +#include "bacnet/dcc.h" +#include "bacnet/bacdcode.h" +#include "bacnet/iam.h" /** @file iam.c Encode/Decode I-Am service */ /* encode I-Am service */ -int iam_encode_apdu(uint8_t *apdu, uint32_t device_id, unsigned max_apdu, - int segmentation, uint16_t vendor_id) +int iam_encode_apdu(uint8_t *apdu, + uint32_t device_id, + unsigned max_apdu, + int segmentation, + uint16_t vendor_id) { - int len = 0; /* length of each encoding */ + int len = 0; /* length of each encoding */ int apdu_len = 0; /* total length of the apdu, return value */ if (apdu) { apdu[0] = PDU_TYPE_UNCONFIRMED_SERVICE_REQUEST; apdu[1] = SERVICE_UNCONFIRMED_I_AM; /* service choice */ apdu_len = 2; - len = encode_application_object_id(&apdu[apdu_len], OBJECT_DEVICE, - device_id); + len = encode_application_object_id( + &apdu[apdu_len], OBJECT_DEVICE, device_id); apdu_len += len; len = encode_application_unsigned(&apdu[apdu_len], max_apdu); apdu_len += len; - len = encode_application_enumerated(&apdu[apdu_len], - (uint32_t)segmentation); + len = encode_application_enumerated( + &apdu[apdu_len], (uint32_t)segmentation); apdu_len += len; len = encode_application_unsigned(&apdu[apdu_len], vendor_id); apdu_len += len; @@ -68,12 +70,14 @@ int iam_encode_apdu(uint8_t *apdu, uint32_t device_id, unsigned max_apdu, return apdu_len; } -int iam_decode_service_request(uint8_t *apdu, uint32_t *pDevice_id, - unsigned *pMax_apdu, int *pSegmentation, - uint16_t *pVendor_id) +int iam_decode_service_request(uint8_t *apdu, + uint32_t *pDevice_id, + unsigned *pMax_apdu, + int *pSegmentation, + uint16_t *pVendor_id) { int len = 0; - int apdu_len = 0; /* total length of the apdu, return value */ + int apdu_len = 0; /* total length of the apdu, return value */ uint16_t object_type = 0; /* should be a Device Object */ uint32_t object_instance = 0; uint8_t tag_number = 0; @@ -83,45 +87,56 @@ int iam_decode_service_request(uint8_t *apdu, uint32_t *pDevice_id, /* OBJECT ID - object id */ len = decode_tag_number_and_value(&apdu[apdu_len], &tag_number, &len_value); apdu_len += len; - if (tag_number != BACNET_APPLICATION_TAG_OBJECT_ID) + if (tag_number != BACNET_APPLICATION_TAG_OBJECT_ID) { return -1; + } len = decode_object_id(&apdu[apdu_len], &object_type, &object_instance); apdu_len += len; - if (object_type != OBJECT_DEVICE) + if (object_type != OBJECT_DEVICE) { return -1; - if (pDevice_id) + } + if (pDevice_id) { *pDevice_id = object_instance; + } /* MAX APDU - unsigned */ len = decode_tag_number_and_value(&apdu[apdu_len], &tag_number, &len_value); apdu_len += len; - if (tag_number != BACNET_APPLICATION_TAG_UNSIGNED_INT) + if (tag_number != BACNET_APPLICATION_TAG_UNSIGNED_INT) { return -1; + } len = decode_unsigned(&apdu[apdu_len], len_value, &decoded_value); apdu_len += len; - if (pMax_apdu) + if (pMax_apdu) { *pMax_apdu = (unsigned)decoded_value; + } /* Segmentation - enumerated */ len = decode_tag_number_and_value(&apdu[apdu_len], &tag_number, &len_value); apdu_len += len; - if (tag_number != BACNET_APPLICATION_TAG_ENUMERATED) + if (tag_number != BACNET_APPLICATION_TAG_ENUMERATED) { return -1; + } len = decode_enumerated(&apdu[apdu_len], len_value, &decoded_value); apdu_len += len; - if (decoded_value >= MAX_BACNET_SEGMENTATION) + if (decoded_value >= MAX_BACNET_SEGMENTATION) { return -1; - if (pSegmentation) + } + if (pSegmentation) { *pSegmentation = (int)decoded_value; + } /* Vendor ID - unsigned16 */ len = decode_tag_number_and_value(&apdu[apdu_len], &tag_number, &len_value); apdu_len += len; - if (tag_number != BACNET_APPLICATION_TAG_UNSIGNED_INT) + if (tag_number != BACNET_APPLICATION_TAG_UNSIGNED_INT) { return -1; + } len = decode_unsigned(&apdu[apdu_len], len_value, &decoded_value); apdu_len += len; - if (decoded_value > 0xFFFF) + if (decoded_value > 0xFFFF) { return -1; - if (pVendor_id) + } + if (pVendor_id) { *pVendor_id = (uint16_t)decoded_value; + } return apdu_len; } @@ -131,8 +146,11 @@ int iam_decode_service_request(uint8_t *apdu, uint32_t *pDevice_id, #include #include "ctest.h" -int iam_decode_apdu(uint8_t *apdu, uint32_t *pDevice_id, unsigned *pMax_apdu, - int *pSegmentation, uint16_t *pVendor_id) +int iam_decode_apdu(uint8_t *apdu, + uint32_t *pDevice_id, + unsigned *pMax_apdu, + int *pSegmentation, + uint16_t *pVendor_id) { int apdu_len = 0; /* total length of the apdu, return value */ @@ -144,15 +162,15 @@ int iam_decode_apdu(uint8_t *apdu, uint32_t *pDevice_id, unsigned *pMax_apdu, return -1; if (apdu[1] != SERVICE_UNCONFIRMED_I_AM) return -1; - apdu_len = iam_decode_service_request(&apdu[2], pDevice_id, pMax_apdu, - pSegmentation, pVendor_id); + apdu_len = iam_decode_service_request( + &apdu[2], pDevice_id, pMax_apdu, pSegmentation, pVendor_id); return apdu_len; } void testIAm(Test *pTest) { - uint8_t apdu[480] = {0}; + uint8_t apdu[480] = { 0 }; int len = 0; uint32_t device_id = 42; unsigned max_apdu = 480; @@ -168,7 +186,7 @@ void testIAm(Test *pTest) ct_test(pTest, len != 0); len = iam_decode_apdu(&apdu[0], &test_device_id, &test_max_apdu, - &test_segmentation, &test_vendor_id); + &test_segmentation, &test_vendor_id); ct_test(pTest, len != -1); ct_test(pTest, test_device_id == device_id); diff --git a/include/iam.h b/src/bacnet/iam.h similarity index 96% rename from include/iam.h rename to src/bacnet/iam.h index b7b73535..191201b0 100644 --- a/include/iam.h +++ b/src/bacnet/iam.h @@ -26,9 +26,9 @@ #include #include -#include "bacdef.h" -#include "bacaddr.h" -#include "npdu.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacaddr.h" +#include "bacnet/npdu.h" #ifdef __cplusplus extern "C" { diff --git a/src/ihave.c b/src/bacnet/ihave.c similarity index 77% rename from src/ihave.c rename to src/bacnet/ihave.c index 30339bee..bc61b360 100644 --- a/src/ihave.c +++ b/src/bacnet/ihave.c @@ -32,16 +32,16 @@ ------------------------------------------- ####COPYRIGHTEND####*/ #include -#include "bacenum.h" -#include "bacdcode.h" -#include "bacdef.h" -#include "ihave.h" +#include "bacnet/bacenum.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacdef.h" +#include "bacnet/ihave.h" /** @file ihave.c Encode/Decode I-Have service */ int ihave_encode_apdu(uint8_t *apdu, BACNET_I_HAVE_DATA *data) { - int len = 0; /* length of each encoding */ + int len = 0; /* length of each encoding */ int apdu_len = 0; /* total length of the apdu, return value */ if (apdu && data) { @@ -50,17 +50,15 @@ int ihave_encode_apdu(uint8_t *apdu, BACNET_I_HAVE_DATA *data) apdu_len = 2; /* deviceIdentifier */ len = encode_application_object_id(&apdu[apdu_len], - (int)data->device_id.type, - data->device_id.instance); + (int)data->device_id.type, data->device_id.instance); apdu_len += len; /* objectIdentifier */ len = encode_application_object_id(&apdu[apdu_len], - (int)data->object_id.type, - data->object_id.instance); + (int)data->object_id.type, data->object_id.instance); apdu_len += len; /* objectName */ - len = encode_application_character_string(&apdu[apdu_len], - &data->object_name); + len = encode_application_character_string( + &apdu[apdu_len], &data->object_name); apdu_len += len; } @@ -70,8 +68,8 @@ int ihave_encode_apdu(uint8_t *apdu, BACNET_I_HAVE_DATA *data) #if BACNET_SVC_I_HAVE_A /* decode the service request only */ -int ihave_decode_service_request(uint8_t *apdu, unsigned apdu_len, - BACNET_I_HAVE_DATA *data) +int ihave_decode_service_request( + uint8_t *apdu, unsigned apdu_len, BACNET_I_HAVE_DATA *data) { int len = 0; uint8_t tag_number = 0; @@ -82,44 +80,51 @@ int ihave_decode_service_request(uint8_t *apdu, unsigned apdu_len, /* deviceIdentifier */ len += decode_tag_number_and_value(&apdu[len], &tag_number, &len_value); if (tag_number == BACNET_APPLICATION_TAG_OBJECT_ID) { - len += decode_object_id(&apdu[len], &decoded_type, - &data->device_id.instance); + len += decode_object_id( + &apdu[len], &decoded_type, &data->device_id.instance); data->device_id.type = decoded_type; - } else + } else { return -1; + } /* objectIdentifier */ len += decode_tag_number_and_value(&apdu[len], &tag_number, &len_value); if (tag_number == BACNET_APPLICATION_TAG_OBJECT_ID) { - len += decode_object_id(&apdu[len], &decoded_type, - &data->object_id.instance); + len += decode_object_id( + &apdu[len], &decoded_type, &data->object_id.instance); data->object_id.type = decoded_type; - } else + } else { return -1; + } /* objectName */ len += decode_tag_number_and_value(&apdu[len], &tag_number, &len_value); if (tag_number == BACNET_APPLICATION_TAG_CHARACTER_STRING) { - len += decode_character_string(&apdu[len], len_value, - &data->object_name); - } else + len += decode_character_string( + &apdu[len], len_value, &data->object_name); + } else { return -1; - } else + } + } else { return -1; + } return len; } -int ihave_decode_apdu(uint8_t *apdu, unsigned apdu_len, - BACNET_I_HAVE_DATA *data) +int ihave_decode_apdu( + uint8_t *apdu, unsigned apdu_len, BACNET_I_HAVE_DATA *data) { int len = 0; - if (!apdu) + if (!apdu) { return -1; + } /* optional checking - most likely was already done prior to this call */ - if (apdu[0] != PDU_TYPE_UNCONFIRMED_SERVICE_REQUEST) + if (apdu[0] != PDU_TYPE_UNCONFIRMED_SERVICE_REQUEST) { return -1; - if (apdu[1] != SERVICE_UNCONFIRMED_I_HAVE) + } + if (apdu[1] != SERVICE_UNCONFIRMED_I_HAVE) { return -1; + } len = ihave_decode_service_request(&apdu[2], apdu_len - 2, data); return len; @@ -133,7 +138,7 @@ int ihave_decode_apdu(uint8_t *apdu, unsigned apdu_len, void testIHaveData(Test *pTest, BACNET_I_HAVE_DATA *data) { - uint8_t apdu[480] = {0}; + uint8_t apdu[480] = { 0 }; int len = 0; int apdu_len = 0; BACNET_I_HAVE_DATA test_data; @@ -149,7 +154,7 @@ void testIHaveData(Test *pTest, BACNET_I_HAVE_DATA *data) ct_test(pTest, test_data.object_id.type == data->object_id.type); ct_test(pTest, test_data.object_id.instance == data->object_id.instance); ct_test(pTest, - characterstring_same(&test_data.object_name, &data->object_name)); + characterstring_same(&test_data.object_name, &data->object_name)); } void testIHave(Test *pTest) diff --git a/include/ihave.h b/src/bacnet/ihave.h similarity index 98% rename from include/ihave.h rename to src/bacnet/ihave.h index c5c4a383..41ee3eb9 100644 --- a/include/ihave.h +++ b/src/bacnet/ihave.h @@ -26,7 +26,7 @@ #include #include -#include "bacstr.h" +#include "bacnet/bacstr.h" typedef struct BACnet_I_Have_Data { BACNET_OBJECT_ID device_id; diff --git a/src/indtext.c b/src/bacnet/indtext.c similarity index 75% rename from src/indtext.c rename to src/bacnet/indtext.c index 88516487..8b4290d8 100644 --- a/src/indtext.c +++ b/src/bacnet/indtext.c @@ -33,7 +33,7 @@ ####COPYRIGHTEND####*/ #include #include -#include "indtext.h" +#include "bacnet/indtext.h" /** @file indtext.c Maps text strings and indices of type INDTEXT_DATA */ @@ -59,8 +59,8 @@ int stricmp(const char *s1, const char *s2) #define stricmp _stricmp #endif -bool indtext_by_string(INDTEXT_DATA *data_list, const char *search_name, - unsigned *found_index) +bool indtext_by_string( + INDTEXT_DATA *data_list, const char *search_name, unsigned *found_index) { bool found = false; unsigned index = 0; @@ -76,15 +76,16 @@ bool indtext_by_string(INDTEXT_DATA *data_list, const char *search_name, } } - if (found && found_index) + if (found && found_index) { *found_index = index; + } return found; } /* case insensitive version */ -bool indtext_by_istring(INDTEXT_DATA *data_list, const char *search_name, - unsigned *found_index) +bool indtext_by_istring( + INDTEXT_DATA *data_list, const char *search_name, unsigned *found_index) { bool found = false; unsigned index = 0; @@ -100,38 +101,39 @@ bool indtext_by_istring(INDTEXT_DATA *data_list, const char *search_name, } } - if (found && found_index) + if (found && found_index) { *found_index = index; + } return found; } -unsigned indtext_by_string_default(INDTEXT_DATA *data_list, - const char *search_name, - unsigned default_index) +unsigned indtext_by_string_default( + INDTEXT_DATA *data_list, const char *search_name, unsigned default_index) { unsigned index = 0; - if (!indtext_by_string(data_list, search_name, &index)) + if (!indtext_by_string(data_list, search_name, &index)) { index = default_index; + } return index; } -unsigned indtext_by_istring_default(INDTEXT_DATA *data_list, - const char *search_name, - unsigned default_index) +unsigned indtext_by_istring_default( + INDTEXT_DATA *data_list, const char *search_name, unsigned default_index) { unsigned index = 0; - if (!indtext_by_istring(data_list, search_name, &index)) + if (!indtext_by_istring(data_list, search_name, &index)) { index = default_index; + } return index; } -const char *indtext_by_index_default(INDTEXT_DATA *data_list, unsigned index, - const char *default_string) +const char *indtext_by_index_default( + INDTEXT_DATA *data_list, unsigned index, const char *default_string) { const char *pString = NULL; @@ -148,15 +150,18 @@ const char *indtext_by_index_default(INDTEXT_DATA *data_list, unsigned index, return pString ? pString : default_string; } -const char *indtext_by_index_split_default( - INDTEXT_DATA *data_list, unsigned index, unsigned split_index, - const char *before_split_default_name, const char *default_name) +const char *indtext_by_index_split_default(INDTEXT_DATA *data_list, + unsigned index, + unsigned split_index, + const char *before_split_default_name, + const char *default_name) { - if (index < split_index) - return indtext_by_index_default(data_list, index, - before_split_default_name); - else + if (index < split_index) { + return indtext_by_index_default( + data_list, index, before_split_default_name); + } else { return indtext_by_index_default(data_list, index, default_name); + } } const char *indtext_by_index(INDTEXT_DATA *data_list, unsigned index) @@ -181,9 +186,8 @@ unsigned indtext_count(INDTEXT_DATA *data_list) #include #include "ctest.h" -static INDTEXT_DATA data_list[] = {{1, "Joshua"}, {2, "Mary"}, - {3, "Anna"}, {4, "Christopher"}, - {5, "Patricia"}, {0, NULL}}; +static INDTEXT_DATA data_list[] = { { 1, "Joshua" }, { 2, "Mary" }, + { 3, "Anna" }, { 4, "Christopher" }, { 5, "Patricia" }, { 0, NULL } }; void testIndexText(Test *pTest) { @@ -200,8 +204,8 @@ void testIndexText(Test *pTest) valid = indtext_by_string(data_list, pString, &index); ct_test(pTest, valid == true); ct_test(pTest, index == i); - ct_test(pTest, index == indtext_by_string_default(data_list, - pString, index)); + ct_test(pTest, + index == indtext_by_string_default(data_list, pString, index)); } } ct_test(pTest, indtext_count(data_list) == count); @@ -215,8 +219,8 @@ void testIndexText(Test *pTest) ct_test(pTest, indtext_by_istring(data_list, "JOSHUA", NULL) == true); ct_test(pTest, indtext_by_istring(data_list, "joshua", NULL) == true); valid = indtext_by_istring(data_list, "ANNA", &index); - ct_test(pTest, - index == indtext_by_istring_default(data_list, "ANNA", index)); + ct_test( + pTest, index == indtext_by_istring_default(data_list, "ANNA", index)); } #endif diff --git a/include/indtext.h b/src/bacnet/indtext.h similarity index 100% rename from include/indtext.h rename to src/bacnet/indtext.h diff --git a/src/lighting.c b/src/bacnet/lighting.c similarity index 85% rename from src/lighting.c rename to src/bacnet/lighting.c index 0fceb026..783e2571 100644 --- a/src/lighting.c +++ b/src/bacnet/lighting.c @@ -37,8 +37,8 @@ #include #include #include -#include "lighting.h" -#include "bacdcode.h" +#include "bacnet/lighting.h" +#include "bacnet/bacdcode.h" /** @file lighting.c Manipulate BACnet lighting command values */ @@ -53,7 +53,7 @@ int lighting_command_encode(uint8_t *apdu, BACNET_LIGHTING_COMMAND *data) { int apdu_len = 0; /* total length of the apdu, return value */ - int len = 0; /* total length of the apdu, return value */ + int len = 0; /* total length of the apdu, return value */ if (apdu) { len = encode_context_enumerated(&apdu[apdu_len], 0, data->operation); @@ -98,8 +98,8 @@ int lighting_command_encode(uint8_t *apdu, BACNET_LIGHTING_COMMAND *data) * * @return number of bytes encoded, or 0 if unable to encode. */ -int lighting_command_encode_context(uint8_t *apdu, uint8_t tag_number, - BACNET_LIGHTING_COMMAND *value) +int lighting_command_encode_context( + uint8_t *apdu, uint8_t tag_number, BACNET_LIGHTING_COMMAND *value) { int apdu_len = 0; @@ -119,8 +119,8 @@ int lighting_command_encode_context(uint8_t *apdu, uint8_t tag_number, * * @return number of bytes encoded */ -int lighting_command_decode(uint8_t *apdu, unsigned apdu_max_len, - BACNET_LIGHTING_COMMAND *data) +int lighting_command_decode( + uint8_t *apdu, unsigned apdu_max_len, BACNET_LIGHTING_COMMAND *data) { int len = 0; int apdu_len = 0; @@ -133,10 +133,11 @@ int lighting_command_decode(uint8_t *apdu, unsigned apdu_max_len, /* check for value pointers */ if (apdu_max_len && data) { /* Tag 0: operation */ - if (!decode_is_context_tag(&apdu[apdu_len], 0)) + if (!decode_is_context_tag(&apdu[apdu_len], 0)) { return BACNET_STATUS_ERROR; - len = decode_tag_number_and_value(&apdu[apdu_len], &tag_number, - &len_value_type); + } + len = decode_tag_number_and_value( + &apdu[apdu_len], &tag_number, &len_value_type); apdu_len += len; len = decode_enumerated(&apdu[apdu_len], len_value_type, &unsigned_value); @@ -146,8 +147,8 @@ int lighting_command_decode(uint8_t *apdu, unsigned apdu_max_len, apdu_len += len; /* Tag 1: target-level - OPTIONAL */ if (decode_is_context_tag(&apdu[apdu_len], 1)) { - len = decode_tag_number_and_value(&apdu[apdu_len], &tag_number, - &len_value_type); + len = decode_tag_number_and_value( + &apdu[apdu_len], &tag_number, &len_value_type); apdu_len += len; len = decode_real(&apdu[apdu_len], &real_value); data->target_level = real_value; @@ -158,8 +159,8 @@ int lighting_command_decode(uint8_t *apdu, unsigned apdu_max_len, } /* Tag 2: ramp-rate - OPTIONAL */ if (decode_is_context_tag(&apdu[apdu_len], 2)) { - len = decode_tag_number_and_value(&apdu[apdu_len], &tag_number, - &len_value_type); + len = decode_tag_number_and_value( + &apdu[apdu_len], &tag_number, &len_value_type); apdu_len += len; len = decode_real(&apdu[apdu_len], &real_value); data->ramp_rate = real_value; @@ -169,8 +170,8 @@ int lighting_command_decode(uint8_t *apdu, unsigned apdu_max_len, } /* Tag 3: step-increment - OPTIONAL */ if (decode_is_context_tag(&apdu[apdu_len], 3)) { - len = decode_tag_number_and_value(&apdu[apdu_len], &tag_number, - &len_value_type); + len = decode_tag_number_and_value( + &apdu[apdu_len], &tag_number, &len_value_type); apdu_len += len; len = decode_real(&apdu[apdu_len], &real_value); data->step_increment = real_value; @@ -180,11 +181,11 @@ int lighting_command_decode(uint8_t *apdu, unsigned apdu_max_len, } /* Tag 4: fade-time - OPTIONAL */ if (decode_is_context_tag(&apdu[apdu_len], 4)) { - len = decode_tag_number_and_value(&apdu[apdu_len], &tag_number, - &len_value_type); + len = decode_tag_number_and_value( + &apdu[apdu_len], &tag_number, &len_value_type); apdu_len += len; - len = decode_unsigned(&apdu[apdu_len], len_value_type, - &unsigned_value); + len = decode_unsigned( + &apdu[apdu_len], len_value_type, &unsigned_value); data->fade_time = unsigned_value; data->use_fade_time = true; } else { @@ -192,11 +193,11 @@ int lighting_command_decode(uint8_t *apdu, unsigned apdu_max_len, } /* Tag 5: priority - OPTIONAL */ if (decode_is_context_tag(&apdu[apdu_len], 4)) { - len = decode_tag_number_and_value(&apdu[apdu_len], &tag_number, - &len_value_type); + len = decode_tag_number_and_value( + &apdu[apdu_len], &tag_number, &len_value_type); apdu_len += len; - len = decode_unsigned(&apdu[apdu_len], len_value_type, - &unsigned_value); + len = decode_unsigned( + &apdu[apdu_len], len_value_type, &unsigned_value); data->priority = unsigned_value; data->use_priority = true; } else { @@ -215,8 +216,8 @@ int lighting_command_decode(uint8_t *apdu, unsigned apdu_max_len, * * @return true if copy succeeded */ -bool lighting_command_copy(BACNET_LIGHTING_COMMAND *dst, - BACNET_LIGHTING_COMMAND *src) +bool lighting_command_copy( + BACNET_LIGHTING_COMMAND *dst, BACNET_LIGHTING_COMMAND *src) { bool status = false; @@ -246,8 +247,8 @@ bool lighting_command_copy(BACNET_LIGHTING_COMMAND *dst, * * @return true if lighting-commands are the same for values in-use */ -bool lighting_command_same(BACNET_LIGHTING_COMMAND *dst, - BACNET_LIGHTING_COMMAND *src) +bool lighting_command_same( + BACNET_LIGHTING_COMMAND *dst, BACNET_LIGHTING_COMMAND *src) { bool status = false; @@ -292,7 +293,7 @@ void testBACnetLightingCommand(Test *pTest, BACNET_LIGHTING_COMMAND *data) bool status = false; BACNET_LIGHTING_COMMAND test_data; int len, apdu_len; - uint8_t apdu[MAX_APDU] = {0}; + uint8_t apdu[MAX_APDU] = { 0 }; status = lighting_command_copy(&test_data, NULL); ct_test(pTest, status == false); diff --git a/include/lighting.h b/src/bacnet/lighting.h similarity index 99% rename from include/lighting.h rename to src/bacnet/lighting.h index 56286356..2d3c43bb 100644 --- a/include/lighting.h +++ b/src/bacnet/lighting.h @@ -26,7 +26,7 @@ #include #include -#include "bacenum.h" +#include "bacnet/bacenum.h" /* BACnetLightingCommand ::= SEQUENCE { operation [0] BACnetLightingOperation, diff --git a/src/lso.c b/src/bacnet/lso.c similarity index 82% rename from src/lso.c rename to src/bacnet/lso.c index 8a77a317..cd8f215b 100644 --- a/src/lso.c +++ b/src/bacnet/lso.c @@ -31,15 +31,16 @@ License. ------------------------------------------- ####COPYRIGHTEND####*/ -#include "lso.h" -#include "bacdcode.h" -#include "apdu.h" +#include +#include "bacnet/lso.h" +#include "bacnet/bacdcode.h" +#include "bacnet/apdu.h" /** @file lso.c BACnet Life Safety Operation encode/decode */ int lso_encode_apdu(uint8_t *apdu, uint8_t invoke_id, BACNET_LSO_DATA *data) { - int len = 0; /* length of each encoding */ + int len = 0; /* length of each encoding */ int apdu_len = 0; /* total length of the apdu, return value */ if (apdu && data) { @@ -52,8 +53,8 @@ int lso_encode_apdu(uint8_t *apdu, uint8_t invoke_id, BACNET_LSO_DATA *data) len = encode_context_unsigned(&apdu[apdu_len], 0, data->processId); apdu_len += len; /* tag 1 - requestingSource */ - len = encode_context_character_string(&apdu[apdu_len], 1, - &data->requestingSrc); + len = encode_context_character_string( + &apdu[apdu_len], 1, &data->requestingSrc); apdu_len += len; /* Operation @@ -65,8 +66,7 @@ int lso_encode_apdu(uint8_t *apdu, uint8_t invoke_id, BACNET_LSO_DATA *data) */ len = encode_context_object_id(&apdu[apdu_len], 3, - (int)data->targetObject.type, - data->targetObject.instance); + (int)data->targetObject.type, data->targetObject.instance); apdu_len += len; } @@ -74,10 +74,10 @@ int lso_encode_apdu(uint8_t *apdu, uint8_t invoke_id, BACNET_LSO_DATA *data) return apdu_len; } -int lso_decode_service_request(uint8_t *apdu, unsigned apdu_len, - BACNET_LSO_DATA *data) +int lso_decode_service_request( + uint8_t *apdu, unsigned apdu_len, BACNET_LSO_DATA *data) { - int len = 0; /* return value */ + int len = 0; /* return value */ int section_length = 0; /* length returned from decoding */ uint32_t operation = 0; /* handles decoded value */ @@ -97,8 +97,8 @@ int lso_decode_service_request(uint8_t *apdu, unsigned apdu_len, } len += section_length; - if ((section_length = - decode_context_enumerated(&apdu[len], 2, &operation)) == -1) { + if ((section_length = decode_context_enumerated( + &apdu[len], 2, &operation)) == -1) { return -1; } data->operation = (BACNET_LIFE_SAFETY_OPERATION)operation; @@ -108,9 +108,9 @@ int lso_decode_service_request(uint8_t *apdu, unsigned apdu_len, ** This is an optional parameter, so dont fail if it doesnt exist */ if (decode_is_context_tag(&apdu[len], 3)) { - if ((section_length = decode_context_object_id( - &apdu[len], 3, &data->targetObject.type, - &data->targetObject.instance)) == -1) { + if ((section_length = decode_context_object_id(&apdu[len], 3, + &data->targetObject.type, &data->targetObject.instance)) == + -1) { return -1; } len += section_length; @@ -128,7 +128,7 @@ int lso_decode_service_request(uint8_t *apdu, unsigned apdu_len, #include #include #include "ctest.h" -#include "bacapp.h" +#include "bacnet/bacapp.h" void testLSO(Test *pTest) { @@ -154,8 +154,9 @@ void testLSO(Test *pTest) ct_test(pTest, data.processId == rxdata.processId); ct_test(pTest, data.targetObject.instance == rxdata.targetObject.instance); ct_test(pTest, data.targetObject.type == rxdata.targetObject.type); - ct_test(pTest, memcmp(data.requestingSrc.value, rxdata.requestingSrc.value, - rxdata.requestingSrc.length) == 0); + ct_test(pTest, + memcmp(data.requestingSrc.value, rxdata.requestingSrc.value, + rxdata.requestingSrc.length) == 0); } #ifdef TEST_LSO diff --git a/include/lso.h b/src/bacnet/lso.h similarity index 96% rename from include/lso.h rename to src/bacnet/lso.h index ccd4fd69..104e93ea 100644 --- a/include/lso.h +++ b/src/bacnet/lso.h @@ -26,9 +26,9 @@ #include #include -#include "bacenum.h" -#include "bacdef.h" -#include "bacstr.h" +#include "bacnet/bacenum.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacstr.h" #ifdef __cplusplus extern "C" { diff --git a/src/memcopy.c b/src/bacnet/memcopy.c similarity index 93% rename from src/memcopy.c rename to src/bacnet/memcopy.c index 420d8207..468b9269 100644 --- a/src/memcopy.c +++ b/src/bacnet/memcopy.c @@ -40,8 +40,8 @@ * and the number of bytes to copy to the buffer. */ #include -#include "memcopy.h" #include +#include "bacnet/memcopy.h" /** * Tests to see if the number of bytes is available from an offset @@ -105,10 +105,11 @@ size_t memcopy(void *dest, void *src, size_t offset, size_t len, size_t max) * @return returns zero if there is not enough space, or returns * the number of bytes copied. */ -size_t memcopy(void *dest, void *src, - size_t offset, /* where in dest to put the data */ - size_t len, /* amount of data to copy */ - size_t max) +size_t memcopy(void *dest, + void *src, + size_t offset, /* where in dest to put the data */ + size_t len, /* amount of data to copy */ + size_t max) { /* total size of destination */ if (memcopylen(offset, max, len)) { memcpy(&((char *)dest)[offset], src, len); @@ -138,8 +139,8 @@ void test_memcopy(Test *pTest) ct_test(pTest, memcmp(&buffer[0], &data1[0], len) == 0); len = memcopy(&buffer[0], &data2[0], len, sizeof(data2), sizeof(buffer)); ct_test(pTest, len == sizeof(data2)); - len = memcopy(&buffer[0], &big_buffer[0], 1, sizeof(big_buffer), - sizeof(buffer)); + len = memcopy( + &buffer[0], &big_buffer[0], 1, sizeof(big_buffer), sizeof(buffer)); ct_test(pTest, len == 0); } diff --git a/include/memcopy.h b/src/bacnet/memcopy.h similarity index 100% rename from include/memcopy.h rename to src/bacnet/memcopy.h diff --git a/src/npdu.c b/src/bacnet/npdu.c similarity index 92% rename from src/npdu.c rename to src/bacnet/npdu.c index b31f85fb..fb3cc6e1 100644 --- a/src/npdu.c +++ b/src/bacnet/npdu.c @@ -33,13 +33,13 @@ ####COPYRIGHTEND####*/ #include #include -#include "bacdef.h" -#include "bacdcode.h" -#include "bacint.h" -#include "bacenum.h" -#include "bits.h" -#include "npdu.h" -#include "apdu.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacint.h" +#include "bacnet/bacenum.h" +#include "bacnet/bits.h" +#include "bacnet/npdu.h" +#include "bacnet/apdu.h" /** @file npdu.c Encode/Decode NPDUs - Network Protocol Data Units */ @@ -126,10 +126,12 @@ ABORT.indication Yes Yes Yes No * NPDU section. * If 0 or negative, there were problems with the data or encoding. */ -int npdu_encode_pdu(uint8_t *npdu, BACNET_ADDRESS *dest, BACNET_ADDRESS *src, - BACNET_NPDU_DATA *npdu_data) +int npdu_encode_pdu(uint8_t *npdu, + BACNET_ADDRESS *dest, + BACNET_ADDRESS *src, + BACNET_NPDU_DATA *npdu_data) { - int len = 0; /* return value - number of octets loaded in this function */ + int len = 0; /* return value - number of octets loaded in this function */ uint8_t i = 0; /* counter */ if (npdu && npdu_data) { @@ -141,24 +143,27 @@ int npdu_encode_pdu(uint8_t *npdu, BACNET_ADDRESS *dest, BACNET_ADDRESS *src, /* Message Type field is present. */ /* 0 indicates that the NSDU contains a BACnet APDU. */ /* Message Type field is absent. */ - if (npdu_data->network_layer_message) + if (npdu_data->network_layer_message) { npdu[1] |= BIT7; + } /*Bit 6: Reserved. Shall be zero. */ /*Bit 5: Destination specifier where: */ /* 0 = DNET, DLEN, DADR, and Hop Count absent */ /* 1 = DNET, DLEN, and Hop Count present */ /* DLEN = 0 denotes broadcast MAC DADR and DADR field is absent */ /* DLEN > 0 specifies length of DADR field */ - if (dest && dest->net) + if (dest && dest->net) { npdu[1] |= BIT5; + } /* Bit 4: Reserved. Shall be zero. */ /* Bit 3: Source specifier where: */ /* 0 = SNET, SLEN, and SADR absent */ /* 1 = SNET, SLEN, and SADR present */ /* SLEN = 0 Invalid */ /* SLEN > 0 specifies length of SADR field */ - if (src && src->net && src->len) + if (src && src->net && src->len) { npdu[1] |= BIT3; + } /* Bit 2: The value of this bit corresponds to the */ /* data_expecting_reply parameter in the N-UNITDATA primitives. */ /* 1 indicates that a BACnet-Confirmed-Request-PDU, */ @@ -167,8 +172,9 @@ int npdu_encode_pdu(uint8_t *npdu, BACNET_ADDRESS *dest, BACNET_ADDRESS *src, /* 0 indicates that other than a BACnet-Confirmed-Request-PDU, */ /* a segment of a BACnet-ComplexACK-PDU, */ /* or a network layer message expecting a reply is present. */ - if (npdu_data->data_expecting_reply) + if (npdu_data->data_expecting_reply) { npdu[1] |= BIT2; + } /* Bits 1,0: Network priority where: */ /* B'11' = Life Safety message */ /* B'10' = Critical Equipment message */ @@ -210,8 +216,9 @@ int npdu_encode_pdu(uint8_t *npdu, BACNET_ADDRESS *dest, BACNET_ADDRESS *src, len++; /* Message Type field contains a value in the range 0x80 - 0xFF, */ /* then a Vendor ID field shall be present */ - if (npdu_data->network_message_type >= 0x80) + if (npdu_data->network_message_type >= 0x80) { len += encode_unsigned16(&npdu[len], npdu_data->vendor_id); + } } } @@ -264,8 +271,8 @@ is expected for the service being issued. * like B'11' = Life Safety message */ void npdu_encode_npdu_data(BACNET_NPDU_DATA *npdu_data, - bool data_expecting_reply, - BACNET_MESSAGE_PRIORITY priority) + bool data_expecting_reply, + BACNET_MESSAGE_PRIORITY priority) { if (npdu_data) { npdu_data->data_expecting_reply = data_expecting_reply; @@ -302,10 +309,12 @@ void npdu_encode_npdu_data(BACNET_NPDU_DATA *npdu_data, * be more bytes left in the NPDU; if not a network msg, the APDU follows. If 0 * or negative, there were problems with the data or arguments. */ -int npdu_decode(uint8_t *npdu, BACNET_ADDRESS *dest, BACNET_ADDRESS *src, - BACNET_NPDU_DATA *npdu_data) +int npdu_decode(uint8_t *npdu, + BACNET_ADDRESS *dest, + BACNET_ADDRESS *src, + BACNET_NPDU_DATA *npdu_data) { - int len = 0; /* return value - number of octets loaded in this function */ + int len = 0; /* return value - number of octets loaded in this function */ uint8_t i = 0; /* counter */ uint16_t src_net = 0; uint16_t dest_net = 0; @@ -363,8 +372,9 @@ int npdu_decode(uint8_t *npdu, BACNET_ADDRESS *dest, BACNET_ADDRESS *src, for (i = 0; i < dlen; i++) { mac_octet = npdu[len++]; - if (dest) + if (dest) { dest->adr[i] = mac_octet; + } } } } @@ -396,8 +406,9 @@ int npdu_decode(uint8_t *npdu, BACNET_ADDRESS *dest, BACNET_ADDRESS *src, for (i = 0; i < slen; i++) { mac_octet = npdu[len++]; - if (src) + if (src) { src->adr[i] = mac_octet; + } } } } else if (src) { @@ -405,8 +416,9 @@ int npdu_decode(uint8_t *npdu, BACNET_ADDRESS *dest, BACNET_ADDRESS *src, * function set it to BACNET_BROADCAST_NETWORK, (eg, for * BVLC_ORIGINAL_BROADCAST_NPDU) then don't stomp on that. */ - if (src->net != BACNET_BROADCAST_NETWORK) + if (src->net != BACNET_BROADCAST_NETWORK) { src->net = 0; + } src->len = 0; for (i = 0; i < MAX_MAC_LEN; i++) { src->adr[i] = 0; @@ -427,8 +439,9 @@ int npdu_decode(uint8_t *npdu, BACNET_ADDRESS *dest, BACNET_ADDRESS *src, (BACNET_NETWORK_MESSAGE_TYPE)npdu[len++]; /* Message Type field contains a value in the range 0x80 - 0xFF, */ /* then a Vendor ID field shall be present */ - if (npdu_data->network_message_type >= 0x80) + if (npdu_data->network_message_type >= 0x80) { len += decode_unsigned16(&npdu[len], &npdu_data->vendor_id); + } } else { /* Since npdu_data->network_layer_message is false, * it doesn't much matter what we set here; this is safe: */ @@ -446,18 +459,18 @@ int npdu_decode(uint8_t *npdu, BACNET_ADDRESS *dest, BACNET_ADDRESS *src, void testNPDU2(Test *pTest) { - uint8_t pdu[480] = {0}; - BACNET_ADDRESS dest = {0}; - BACNET_ADDRESS src = {0}; - BACNET_ADDRESS npdu_dest = {0}; - BACNET_ADDRESS npdu_src = {0}; + uint8_t pdu[480] = { 0 }; + BACNET_ADDRESS dest = { 0 }; + BACNET_ADDRESS src = { 0 }; + BACNET_ADDRESS npdu_dest = { 0 }; + BACNET_ADDRESS npdu_src = { 0 }; int len = 0; bool data_expecting_reply = true; BACNET_MESSAGE_PRIORITY priority = MESSAGE_PRIORITY_NORMAL; - BACNET_NPDU_DATA npdu_data = {0}; + BACNET_NPDU_DATA npdu_data = { 0 }; int i = 0; /* counter */ int npdu_len = 0; - bool network_layer_message = false; /* false if APDU */ + bool network_layer_message = false; /* false if APDU */ BACNET_NETWORK_MESSAGE_TYPE network_message_type = 0; /* optional */ uint16_t vendor_id = 0; /* optional, if net message type is > 0x80 */ @@ -510,18 +523,18 @@ void testNPDU2(Test *pTest) void testNPDU1(Test *pTest) { - uint8_t pdu[480] = {0}; - BACNET_ADDRESS dest = {0}; - BACNET_ADDRESS src = {0}; - BACNET_ADDRESS npdu_dest = {0}; - BACNET_ADDRESS npdu_src = {0}; + uint8_t pdu[480] = { 0 }; + BACNET_ADDRESS dest = { 0 }; + BACNET_ADDRESS src = { 0 }; + BACNET_ADDRESS npdu_dest = { 0 }; + BACNET_ADDRESS npdu_src = { 0 }; int len = 0; bool data_expecting_reply = false; BACNET_MESSAGE_PRIORITY priority = MESSAGE_PRIORITY_NORMAL; - BACNET_NPDU_DATA npdu_data = {0}; + BACNET_NPDU_DATA npdu_data = { 0 }; int i = 0; /* counter */ int npdu_len = 0; - bool network_layer_message = false; /* false if APDU */ + bool network_layer_message = false; /* false if APDU */ BACNET_NETWORK_MESSAGE_TYPE network_message_type = 0; /* optional */ uint16_t vendor_id = 0; /* optional, if net message type is > 0x80 */ @@ -570,8 +583,8 @@ void tsm_free_invoke_id(uint8_t invokeID) (void)invokeID; } -void iam_handler(uint8_t *service_request, uint16_t service_len, - BACNET_ADDRESS *src) +void iam_handler( + uint8_t *service_request, uint16_t service_len, BACNET_ADDRESS *src) { (void)service_request; (void)service_len; diff --git a/include/npdu.h b/src/bacnet/npdu.h similarity index 98% rename from include/npdu.h rename to src/bacnet/npdu.h index 760ee73a..b6eb098c 100644 --- a/include/npdu.h +++ b/src/bacnet/npdu.h @@ -26,8 +26,8 @@ #include #include -#include "bacdef.h" -#include "bacenum.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacenum.h" /** Hop count default is required by BTL to be maximum */ #ifndef HOP_COUNT_DEFAULT diff --git a/src/bacnet/property.c b/src/bacnet/property.c new file mode 100644 index 00000000..a41a61a0 --- /dev/null +++ b/src/bacnet/property.c @@ -0,0 +1,709 @@ +/*####COPYRIGHTBEGIN#### + ------------------------------------------- + Copyright (C) 2012 Steve Karg + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to: + The Free Software Foundation, Inc. + 59 Temple Place - Suite 330 + Boston, MA 02111-1307, USA. + + As a special exception, if other files instantiate templates or + use macros or inline functions from this file, or you compile + this file and link it with other works to produce a work based + on this file, this file does not by itself cause the resulting + work to be covered by the GNU General Public License. However + the source code for this file must still be made available in + accordance with section (3) of the GNU General Public License. + + This exception does not invalidate any other reasons why a work + based on this file might be covered by the GNU General Public + License. + ------------------------------------------- +####COPYRIGHTEND####*/ +#include +#include "bacnet/bacenum.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacenum.h" +#include "bacnet/rpm.h" +#include "bacnet/rp.h" +#include "bacnet/proplist.h" +#include "bacnet/property.h" + +#ifndef BACNET_PROPERTY_LISTS +#define BACNET_PROPERTY_LISTS 0 +#endif + +#if BACNET_PROPERTY_LISTS +/** @file proplist.c List of Required and Optional object properties */ +/* note: the PROP_PROPERTY_LIST is NOT included in these lists, on purpose */ + +static const int Default_Properties_Required[] = { PROP_OBJECT_IDENTIFIER, + PROP_OBJECT_NAME, PROP_OBJECT_TYPE, -1 }; + +static const int Device_Properties_Required[] = { PROP_OBJECT_IDENTIFIER, + PROP_OBJECT_NAME, PROP_OBJECT_TYPE, PROP_SYSTEM_STATUS, PROP_VENDOR_NAME, + PROP_VENDOR_IDENTIFIER, PROP_MODEL_NAME, PROP_FIRMWARE_REVISION, + PROP_APPLICATION_SOFTWARE_VERSION, PROP_PROTOCOL_VERSION, + PROP_PROTOCOL_REVISION, PROP_PROTOCOL_SERVICES_SUPPORTED, + PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED, PROP_OBJECT_LIST, + PROP_MAX_APDU_LENGTH_ACCEPTED, PROP_SEGMENTATION_SUPPORTED, + PROP_APDU_TIMEOUT, PROP_NUMBER_OF_APDU_RETRIES, PROP_DEVICE_ADDRESS_BINDING, + PROP_DATABASE_REVISION, -1 }; + +static const int Device_Properties_Optional[] = { PROP_LOCATION, + PROP_DESCRIPTION, PROP_STRUCTURED_OBJECT_LIST, PROP_MAX_SEGMENTS_ACCEPTED, + PROP_VT_CLASSES_SUPPORTED, PROP_ACTIVE_VT_SESSIONS, PROP_LOCAL_TIME, + PROP_LOCAL_DATE, PROP_UTC_OFFSET, PROP_DAYLIGHT_SAVINGS_STATUS, + PROP_APDU_SEGMENT_TIMEOUT, PROP_TIME_SYNCHRONIZATION_RECIPIENTS, + PROP_MAX_MASTER, PROP_MAX_INFO_FRAMES, PROP_CONFIGURATION_FILES, + PROP_LAST_RESTORE_TIME, PROP_BACKUP_FAILURE_TIMEOUT, + PROP_BACKUP_PREPARATION_TIME, PROP_RESTORE_PREPARATION_TIME, + PROP_RESTORE_COMPLETION_TIME, PROP_BACKUP_AND_RESTORE_STATE, + PROP_ACTIVE_COV_SUBSCRIPTIONS, PROP_SLAVE_PROXY_ENABLE, + PROP_MANUAL_SLAVE_ADDRESS_BINDING, PROP_AUTO_SLAVE_DISCOVERY, + PROP_SLAVE_ADDRESS_BINDING, PROP_LAST_RESTART_REASON, + PROP_TIME_OF_DEVICE_RESTART, PROP_RESTART_NOTIFICATION_RECIPIENTS, + PROP_UTC_TIME_SYNCHRONIZATION_RECIPIENTS, + PROP_TIME_SYNCHRONIZATION_INTERVAL, PROP_ALIGN_INTERVALS, + PROP_INTERVAL_OFFSET, PROP_PROFILE_NAME, -1 }; + +static const int Accumulator_Properties_Required[] = { PROP_OBJECT_IDENTIFIER, + PROP_OBJECT_NAME, PROP_OBJECT_TYPE, PROP_PRESENT_VALUE, PROP_STATUS_FLAGS, + PROP_EVENT_STATE, PROP_OUT_OF_SERVICE, PROP_SCALE, PROP_UNITS, + PROP_MAX_PRES_VALUE, -1 }; + +static const int Accumulator_Properties_Optional[] = { PROP_DESCRIPTION, + PROP_DEVICE_TYPE, PROP_RELIABILITY, PROP_PRESCALE, PROP_VALUE_CHANGE_TIME, + PROP_VALUE_BEFORE_CHANGE, PROP_VALUE_SET, PROP_LOGGING_RECORD, + PROP_LOGGING_OBJECT, PROP_PULSE_RATE, PROP_HIGH_LIMIT, PROP_LOW_LIMIT, + PROP_LIMIT_MONITORING_INTERVAL, PROP_NOTIFICATION_CLASS, PROP_TIME_DELAY, + PROP_LIMIT_ENABLE, PROP_EVENT_ENABLE, PROP_ACKED_TRANSITIONS, + PROP_NOTIFY_TYPE, PROP_EVENT_TIME_STAMPS, PROP_EVENT_MESSAGE_TEXTS, + PROP_RELIABILITY_EVALUATION_INHIBIT, PROP_PROFILE_NAME, -1 }; + +static const int Analog_Input_Properties_Required[] = { PROP_OBJECT_IDENTIFIER, + PROP_OBJECT_NAME, PROP_OBJECT_TYPE, PROP_PRESENT_VALUE, PROP_STATUS_FLAGS, + PROP_EVENT_STATE, PROP_OUT_OF_SERVICE, PROP_UNITS, -1 }; + +static const int Analog_Input_Properties_Optional[] = { PROP_DESCRIPTION, + PROP_DEVICE_TYPE, PROP_RELIABILITY, PROP_UPDATE_INTERVAL, + PROP_MIN_PRES_VALUE, PROP_MAX_PRES_VALUE, PROP_RESOLUTION, + PROP_COV_INCREMENT, PROP_TIME_DELAY, PROP_NOTIFICATION_CLASS, + PROP_HIGH_LIMIT, PROP_LOW_LIMIT, PROP_DEADBAND, PROP_LIMIT_ENABLE, + PROP_EVENT_ENABLE, PROP_ACKED_TRANSITIONS, PROP_NOTIFY_TYPE, + PROP_EVENT_TIME_STAMPS, PROP_EVENT_MESSAGE_TEXTS, + PROP_RELIABILITY_EVALUATION_INHIBIT, PROP_PROFILE_NAME, -1 }; + +static const int Analog_Output_Properties_Required[] = { PROP_OBJECT_IDENTIFIER, + PROP_OBJECT_NAME, PROP_OBJECT_TYPE, PROP_PRESENT_VALUE, PROP_STATUS_FLAGS, + PROP_EVENT_STATE, PROP_OUT_OF_SERVICE, PROP_UNITS, PROP_PRIORITY_ARRAY, + PROP_RELINQUISH_DEFAULT, -1 }; + +static const int Analog_Output_Properties_Optional[] = { PROP_DESCRIPTION, + PROP_DEVICE_TYPE, PROP_RELIABILITY, PROP_MIN_PRES_VALUE, + PROP_MAX_PRES_VALUE, PROP_RESOLUTION, PROP_COV_INCREMENT, PROP_TIME_DELAY, + PROP_NOTIFICATION_CLASS, PROP_HIGH_LIMIT, PROP_LOW_LIMIT, PROP_DEADBAND, + PROP_LIMIT_ENABLE, PROP_EVENT_ENABLE, PROP_ACKED_TRANSITIONS, + PROP_NOTIFY_TYPE, PROP_EVENT_TIME_STAMPS, PROP_EVENT_MESSAGE_TEXTS, + PROP_RELIABILITY_EVALUATION_INHIBIT, PROP_PROFILE_NAME, -1 }; + +static const int Analog_Value_Properties_Required[] = { PROP_OBJECT_IDENTIFIER, + PROP_OBJECT_NAME, PROP_OBJECT_TYPE, PROP_PRESENT_VALUE, PROP_STATUS_FLAGS, + PROP_EVENT_STATE, PROP_OUT_OF_SERVICE, PROP_UNITS, -1 }; + +static const int Analog_Value_Properties_Optional[] = { PROP_DESCRIPTION, + PROP_RELIABILITY, PROP_PRIORITY_ARRAY, PROP_RELINQUISH_DEFAULT, + PROP_COV_INCREMENT, PROP_TIME_DELAY, PROP_NOTIFICATION_CLASS, + PROP_HIGH_LIMIT, PROP_LOW_LIMIT, PROP_DEADBAND, PROP_LIMIT_ENABLE, + PROP_EVENT_ENABLE, PROP_ACKED_TRANSITIONS, PROP_NOTIFY_TYPE, + PROP_EVENT_TIME_STAMPS, PROP_EVENT_MESSAGE_TEXTS, + PROP_RELIABILITY_EVALUATION_INHIBIT, PROP_PROFILE_NAME, -1 }; + +static const int Averaging_Properties_Required[] = { PROP_OBJECT_IDENTIFIER, + PROP_OBJECT_NAME, PROP_OBJECT_TYPE, PROP_MINIMUM_VALUE, PROP_AVERAGE_VALUE, + PROP_MAXIMUM_VALUE, PROP_STATUS_FLAGS, PROP_EVENT_STATE, + PROP_OUT_OF_SERVICE, PROP_UNITS, -1 }; + +static const int Averaging_Properties_Optional[] = { PROP_PROFILE_NAME, + PROP_MINIMUM_VALUE_TIMESTAMP, PROP_VARIANCE_VALUE, + PROP_MAXIMUM_VALUE_TIMESTAMP, PROP_DESCRIPTION, PROP_ATTEMPTED_SAMPLES, + PROP_VALID_SAMPLES, PROP_OBJECT_PROPERTY_REFERENCE, PROP_WINDOW_INTERVAL, + PROP_WINDOW_SAMPLES, -1 }; + +static const int Binary_Input_Properties_Required[] = { PROP_OBJECT_IDENTIFIER, + PROP_OBJECT_NAME, PROP_OBJECT_TYPE, PROP_PRESENT_VALUE, PROP_STATUS_FLAGS, + PROP_EVENT_STATE, PROP_OUT_OF_SERVICE, PROP_POLARITY, -1 }; + +static const int Binary_Input_Properties_Optional[] = { PROP_DESCRIPTION, + PROP_DEVICE_TYPE, PROP_RELIABILITY, PROP_INACTIVE_TEXT, PROP_ACTIVE_TEXT, + PROP_CHANGE_OF_STATE_TIME, PROP_CHANGE_OF_STATE_COUNT, + PROP_TIME_OF_STATE_COUNT_RESET, PROP_ELAPSED_ACTIVE_TIME, + PROP_TIME_OF_ACTIVE_TIME_RESET, PROP_TIME_DELAY, PROP_NOTIFICATION_CLASS, + PROP_ALARM_VALUE, PROP_EVENT_ENABLE, PROP_ACKED_TRANSITIONS, + PROP_NOTIFY_TYPE, PROP_EVENT_TIME_STAMPS, PROP_EVENT_MESSAGE_TEXTS, + PROP_RELIABILITY_EVALUATION_INHIBIT, PROP_PROFILE_NAME, -1 }; + +static const int Binary_Output_Properties_Required[] = { PROP_OBJECT_IDENTIFIER, + PROP_OBJECT_NAME, PROP_OBJECT_TYPE, PROP_PRESENT_VALUE, PROP_STATUS_FLAGS, + PROP_EVENT_STATE, PROP_OUT_OF_SERVICE, PROP_POLARITY, PROP_PRIORITY_ARRAY, + PROP_RELINQUISH_DEFAULT, -1 }; + +static const int Binary_Output_Properties_Optional[] = { PROP_DESCRIPTION, + PROP_DEVICE_TYPE, PROP_RELIABILITY, PROP_INACTIVE_TEXT, PROP_ACTIVE_TEXT, + PROP_CHANGE_OF_STATE_TIME, PROP_CHANGE_OF_STATE_COUNT, + PROP_TIME_OF_STATE_COUNT_RESET, PROP_ELAPSED_ACTIVE_TIME, + PROP_TIME_OF_ACTIVE_TIME_RESET, PROP_MINIMUM_OFF_TIME, PROP_MINIMUM_ON_TIME, + PROP_TIME_DELAY, PROP_NOTIFICATION_CLASS, PROP_FEEDBACK_VALUE, + PROP_EVENT_ENABLE, PROP_ACKED_TRANSITIONS, PROP_NOTIFY_TYPE, + PROP_EVENT_TIME_STAMPS, PROP_EVENT_MESSAGE_TEXTS, + PROP_RELIABILITY_EVALUATION_INHIBIT, PROP_PROFILE_NAME, -1 }; + +static const int Binary_Value_Properties_Required[] = { PROP_OBJECT_IDENTIFIER, + PROP_OBJECT_NAME, PROP_OBJECT_TYPE, PROP_PRESENT_VALUE, PROP_STATUS_FLAGS, + PROP_EVENT_STATE, PROP_OUT_OF_SERVICE, -1 }; + +static const int Binary_Value_Properties_Optional[] = { PROP_DESCRIPTION, + PROP_RELIABILITY, PROP_INACTIVE_TEXT, PROP_ACTIVE_TEXT, + PROP_CHANGE_OF_STATE_TIME, PROP_CHANGE_OF_STATE_COUNT, + PROP_TIME_OF_STATE_COUNT_RESET, PROP_ELAPSED_ACTIVE_TIME, + PROP_TIME_OF_ACTIVE_TIME_RESET, PROP_MINIMUM_OFF_TIME, PROP_MINIMUM_ON_TIME, + PROP_PRIORITY_ARRAY, PROP_RELINQUISH_DEFAULT, PROP_TIME_DELAY, + PROP_NOTIFICATION_CLASS, PROP_ALARM_VALUE, PROP_EVENT_ENABLE, + PROP_ACKED_TRANSITIONS, PROP_NOTIFY_TYPE, PROP_EVENT_TIME_STAMPS, + PROP_EVENT_MESSAGE_TEXTS, PROP_RELIABILITY_EVALUATION_INHIBIT, + PROP_PROFILE_NAME, -1 }; + +static const int Calendar_Properties_Required[] = { PROP_OBJECT_IDENTIFIER, + PROP_OBJECT_NAME, PROP_OBJECT_TYPE, PROP_PRESENT_VALUE, PROP_DATE_LIST, + -1 }; + +static const int Calendar_Properties_Optional[] = { PROP_DESCRIPTION, + PROP_PROFILE_NAME, -1 }; + +static const int Channel_Properties_Required[] = { PROP_OBJECT_IDENTIFIER, + PROP_OBJECT_NAME, PROP_OBJECT_TYPE, PROP_PRESENT_VALUE, PROP_LAST_PRIORITY, + PROP_WRITE_STATUS, PROP_STATUS_FLAGS, PROP_OUT_OF_SERVICE, + PROP_LIST_OF_OBJECT_PROPERTY_REFERENCES, PROP_CHANNEL_NUMBER, + PROP_CONTROL_GROUPS, -1 }; + +static const int Channel_Properties_Optional[] = { PROP_DESCRIPTION, + PROP_RELIABILITY, PROP_EXECUTION_DELAY, PROP_ALLOW_GROUP_DELAY_INHIBIT, + PROP_EVENT_DETECTION_ENABLE, PROP_NOTIFICATION_CLASS, PROP_EVENT_ENABLE, + PROP_EVENT_STATE, PROP_ACKED_TRANSITIONS, PROP_NOTIFY_TYPE, + PROP_EVENT_TIME_STAMPS, PROP_EVENT_MESSAGE_TEXTS, + PROP_EVENT_MESSAGE_TEXTS_CONFIG, PROP_RELIABILITY_EVALUATION_INHIBIT, + PROP_PROFILE_NAME, -1 }; + +static const int Command_Properties_Required[] = { PROP_OBJECT_IDENTIFIER, + PROP_OBJECT_NAME, PROP_OBJECT_TYPE, PROP_PRESENT_VALUE, PROP_IN_PROCESS, + PROP_ALL_WRITES_SUCCESSFUL, PROP_ACTION, -1 }; + +static const int Command_Properties_Optional[] = { PROP_DESCRIPTION, + PROP_ACTION_TEXT, PROP_PROFILE_NAME, -1 }; + +static const int CharacterString_Value_Properties_Required[] = { + PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME, PROP_OBJECT_TYPE, + PROP_PRESENT_VALUE, PROP_STATUS_FLAGS, -1 +}; + +static const int CharacterString_Value_Properties_Optional[] = { + PROP_DESCRIPTION, PROP_EVENT_STATE, PROP_RELIABILITY, PROP_OUT_OF_SERVICE, + PROP_PRIORITY_ARRAY, PROP_RELINQUISH_DEFAULT, PROP_TIME_DELAY, + PROP_NOTIFICATION_CLASS, PROP_ALARM_VALUES, PROP_FAULT_VALUES, + PROP_EVENT_ENABLE, PROP_ACKED_TRANSITIONS, PROP_NOTIFY_TYPE, + PROP_EVENT_TIME_STAMPS, PROP_EVENT_MESSAGE_TEXTS, + PROP_RELIABILITY_EVALUATION_INHIBIT, PROP_PROFILE_NAME, -1 +}; + +static const int Lighting_Output_Properties_Required[] = { + PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME, PROP_OBJECT_TYPE, + PROP_PRESENT_VALUE, PROP_TRACKING_VALUE, PROP_LIGHTING_COMMAND, + PROP_IN_PROGRESS, PROP_STATUS_FLAGS, PROP_OUT_OF_SERVICE, + PROP_BLINK_WARN_ENABLE, PROP_EGRESS_TIME, PROP_EGRESS_ACTIVE, + PROP_DEFAULT_FADE_TIME, PROP_DEFAULT_RAMP_RATE, PROP_DEFAULT_STEP_INCREMENT, + PROP_PRIORITY_ARRAY, PROP_RELINQUISH_DEFAULT, + PROP_LIGHTING_COMMAND_DEFAULT_PRIORITY, -1 +}; + +static const int Lighting_Output_Properties_Optional[] = { PROP_DESCRIPTION, + PROP_RELIABILITY, PROP_TRANSITION, PROP_FEEDBACK_VALUE, PROP_POWER, + PROP_INSTANTANEOUS_POWER, PROP_MIN_ACTUAL_VALUE, PROP_MAX_ACTUAL_VALUE, + PROP_COV_INCREMENT, PROP_RELIABILITY_EVALUATION_INHIBIT, PROP_PROFILE_NAME, + -1 }; + +static const int Load_Control_Properties_Required[] = { PROP_OBJECT_IDENTIFIER, + PROP_OBJECT_NAME, PROP_OBJECT_TYPE, PROP_PRESENT_VALUE, PROP_STATUS_FLAGS, + PROP_EVENT_STATE, PROP_REQUESTED_SHED_LEVEL, PROP_START_TIME, + PROP_SHED_DURATION, PROP_DUTY_WINDOW, PROP_ENABLE, PROP_EXPECTED_SHED_LEVEL, + PROP_ACTUAL_SHED_LEVEL, PROP_SHED_LEVELS, PROP_SHED_LEVEL_DESCRIPTIONS, + -1 }; + +static const int Load_Control_Properties_Optional[] = { PROP_DESCRIPTION, + PROP_STATE_DESCRIPTION, PROP_RELIABILITY, PROP_FULL_DUTY_BASELINE, + PROP_NOTIFICATION_CLASS, PROP_TIME_DELAY, PROP_EVENT_ENABLE, + PROP_ACKED_TRANSITIONS, PROP_NOTIFY_TYPE, PROP_EVENT_TIME_STAMPS, + PROP_EVENT_MESSAGE_TEXTS, PROP_RELIABILITY_EVALUATION_INHIBIT, + PROP_PROFILE_NAME, -1 }; + +static const int Life_Safety_Point_Properties_Required[] = { + PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME, PROP_OBJECT_TYPE, + PROP_PRESENT_VALUE, PROP_TRACKING_VALUE, PROP_STATUS_FLAGS, + PROP_EVENT_STATE, PROP_OUT_OF_SERVICE, PROP_RELIABILITY, PROP_MODE, + PROP_ACCEPTED_MODES, PROP_SILENCED, PROP_OPERATION_EXPECTED, -1 +}; + +static const int Life_Safety_Point_Properties_Optional[] = { PROP_DESCRIPTION, + PROP_DEVICE_TYPE, PROP_NOTIFICATION_CLASS, PROP_LIFE_SAFETY_ALARM_VALUES, + PROP_ALARM_VALUES, PROP_FAULT_VALUES, PROP_EVENT_ENABLE, + PROP_ACKED_TRANSITIONS, PROP_NOTIFY_TYPE, PROP_EVENT_TIME_STAMPS, + PROP_EVENT_MESSAGE_TEXTS, PROP_MAINTENANCE_REQUIRED, PROP_SETTING, + PROP_DIRECT_READING, PROP_UNITS, PROP_MEMBER_OF, + PROP_RELIABILITY_EVALUATION_INHIBIT, PROP_PROFILE_NAME, -1 }; + +static const int Multistate_Input_Properties_Required[] = { + PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME, PROP_OBJECT_TYPE, + PROP_PRESENT_VALUE, PROP_STATUS_FLAGS, PROP_EVENT_STATE, + PROP_OUT_OF_SERVICE, PROP_NUMBER_OF_STATES, -1 +}; + +static const int Multistate_Input_Properties_Optional[] = { PROP_DESCRIPTION, + PROP_DEVICE_TYPE, PROP_RELIABILITY, PROP_STATE_TEXT, PROP_TIME_DELAY, + PROP_NOTIFICATION_CLASS, PROP_ALARM_VALUES, PROP_FAULT_VALUES, + PROP_EVENT_ENABLE, PROP_ACKED_TRANSITIONS, PROP_NOTIFY_TYPE, + PROP_EVENT_TIME_STAMPS, PROP_EVENT_MESSAGE_TEXTS, + PROP_RELIABILITY_EVALUATION_INHIBIT, PROP_PROFILE_NAME, -1 }; + +static const int Multistate_Output_Properties_Required[] = { + PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME, PROP_OBJECT_TYPE, + PROP_PRESENT_VALUE, PROP_STATUS_FLAGS, PROP_EVENT_STATE, + PROP_OUT_OF_SERVICE, PROP_NUMBER_OF_STATES, PROP_PRIORITY_ARRAY, + PROP_RELINQUISH_DEFAULT, -1 +}; + +static const int Multistate_Output_Properties_Optional[] = { PROP_DESCRIPTION, + PROP_DEVICE_TYPE, PROP_RELIABILITY, PROP_STATE_TEXT, PROP_TIME_DELAY, + PROP_NOTIFICATION_CLASS, PROP_FEEDBACK_VALUE, PROP_EVENT_ENABLE, + PROP_ACKED_TRANSITIONS, PROP_NOTIFY_TYPE, PROP_EVENT_TIME_STAMPS, + PROP_EVENT_MESSAGE_TEXTS, PROP_RELIABILITY_EVALUATION_INHIBIT, + PROP_PROFILE_NAME, -1 }; + +static const int Multistate_Value_Properties_Required[] = { + PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME, PROP_OBJECT_TYPE, + PROP_PRESENT_VALUE, PROP_STATUS_FLAGS, PROP_EVENT_STATE, + PROP_OUT_OF_SERVICE, PROP_NUMBER_OF_STATES, -1 +}; + +static const int Multistate_Value_Properties_Optional[] = { PROP_DESCRIPTION, + PROP_RELIABILITY, PROP_STATE_TEXT, PROP_PRIORITY_ARRAY, + PROP_RELINQUISH_DEFAULT, PROP_TIME_DELAY, PROP_NOTIFICATION_CLASS, + PROP_ALARM_VALUES, PROP_FAULT_VALUES, PROP_EVENT_ENABLE, + PROP_ACKED_TRANSITIONS, PROP_NOTIFY_TYPE, PROP_EVENT_TIME_STAMPS, + PROP_EVENT_MESSAGE_TEXTS, PROP_RELIABILITY_EVALUATION_INHIBIT, + PROP_PROFILE_NAME, -1 }; + +static const int Notification_Class_Properties_Required[] = { + PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME, PROP_OBJECT_TYPE, + PROP_NOTIFICATION_CLASS, PROP_PRIORITY, PROP_ACK_REQUIRED, + PROP_RECIPIENT_LIST, -1 +}; + +static const int Notification_Class_Properties_Optional[] = { PROP_DESCRIPTION, + PROP_PROFILE_NAME, -1 }; + +static const int Trend_Log_Properties_Required[] = { PROP_OBJECT_IDENTIFIER, + PROP_OBJECT_NAME, PROP_OBJECT_TYPE, PROP_ENABLE, PROP_STOP_WHEN_FULL, + PROP_BUFFER_SIZE, PROP_LOG_BUFFER, PROP_RECORD_COUNT, + PROP_TOTAL_RECORD_COUNT, PROP_EVENT_STATE, PROP_LOGGING_TYPE, + PROP_STATUS_FLAGS, -1 }; + +static const int Trend_Log_Properties_Optional[] = { PROP_DESCRIPTION, + PROP_START_TIME, PROP_STOP_TIME, PROP_LOG_DEVICE_OBJECT_PROPERTY, + PROP_LOG_INTERVAL, PROP_COV_RESUBSCRIPTION_INTERVAL, + PROP_CLIENT_COV_INCREMENT, PROP_NOTIFICATION_THRESHOLD, + PROP_RECORDS_SINCE_NOTIFICATION, PROP_LAST_NOTIFY_RECORD, + PROP_NOTIFICATION_CLASS, PROP_EVENT_ENABLE, PROP_ACKED_TRANSITIONS, + PROP_NOTIFY_TYPE, PROP_EVENT_TIME_STAMPS, PROP_EVENT_MESSAGE_TEXTS, + PROP_ALIGN_INTERVALS, PROP_INTERVAL_OFFSET, PROP_TRIGGER, PROP_RELIABILITY, + PROP_RELIABILITY_EVALUATION_INHIBIT, PROP_PROFILE_NAME, -1 }; + +static const int File_Properties_Required[] = { PROP_OBJECT_IDENTIFIER, + PROP_OBJECT_NAME, PROP_OBJECT_TYPE, PROP_FILE_TYPE, PROP_FILE_SIZE, + PROP_MODIFICATION_DATE, PROP_ARCHIVE, PROP_READ_ONLY, + PROP_FILE_ACCESS_METHOD, -1 }; + +static const int File_Properties_Optional[] = { PROP_DESCRIPTION, + PROP_RECORD_COUNT, PROP_PROFILE_NAME, -1 }; + +/* These three arrays are used by the ReadPropertyMultiple handler */ +static const int Integer_Value_Properties_Required[] = { PROP_OBJECT_IDENTIFIER, + PROP_OBJECT_NAME, PROP_OBJECT_TYPE, PROP_PRESENT_VALUE, PROP_STATUS_FLAGS, + PROP_UNITS, -1 }; + +static const int Integer_Value_Properties_Optional[] = { PROP_DESCRIPTION, + PROP_EVENT_STATE, PROP_RELIABILITY, PROP_OUT_OF_SERVICE, + PROP_PRIORITY_ARRAY, PROP_RELINQUISH_DEFAULT, PROP_COV_INCREMENT, + PROP_TIME_DELAY, PROP_NOTIFICATION_CLASS, PROP_HIGH_LIMIT, PROP_LOW_LIMIT, + PROP_DEADBAND, PROP_LIMIT_ENABLE, PROP_EVENT_ENABLE, PROP_ACKED_TRANSITIONS, + PROP_NOTIFY_TYPE, PROP_EVENT_TIME_STAMPS, PROP_EVENT_MESSAGE_TEXTS, + PROP_EVENT_MESSAGE_TEXTS_CONFIG, PROP_EVENT_DETECTION_ENABLE, + PROP_EVENT_ALGORITHM_INHIBIT_REF, PROP_EVENT_ALGORITHM_INHIBIT, + PROP_TIME_DELAY_NORMAL, PROP_RELIABILITY_EVALUATION_INHIBIT, + PROP_MIN_PRES_VALUE, PROP_MAX_PRES_VALUE, PROP_RESOLUTION, + PROP_PROFILE_NAME, -1 }; + +/** + * Function that returns the list of all Optional properties + * of known standard objects. + * + * @param object_type - enumerated BACNET_OBJECT_TYPE + * @return returns a pointer to a '-1' terminated array of + * type 'int' that contain BACnet object properties for the given object + * type. + */ +const int *property_list_optional(BACNET_OBJECT_TYPE object_type) +{ + const int *pList = NULL; + + switch (object_type) { + case OBJECT_DEVICE: + pList = Device_Properties_Optional; + break; + case OBJECT_ACCUMULATOR: + pList = Accumulator_Properties_Optional; + break; + case OBJECT_ANALOG_INPUT: + pList = Analog_Input_Properties_Optional; + break; + case OBJECT_ANALOG_OUTPUT: + pList = Analog_Output_Properties_Optional; + break; + case OBJECT_ANALOG_VALUE: + pList = Analog_Value_Properties_Optional; + break; + case OBJECT_AVERAGING: + pList = Averaging_Properties_Optional; + break; + case OBJECT_BINARY_INPUT: + pList = Binary_Input_Properties_Optional; + break; + case OBJECT_BINARY_OUTPUT: + pList = Binary_Output_Properties_Optional; + break; + case OBJECT_BINARY_VALUE: + pList = Binary_Value_Properties_Optional; + break; + case OBJECT_CALENDAR: + pList = Calendar_Properties_Optional; + break; + case OBJECT_CHANNEL: + pList = Channel_Properties_Optional; + break; + case OBJECT_COMMAND: + pList = Command_Properties_Optional; + break; + case OBJECT_CHARACTERSTRING_VALUE: + pList = CharacterString_Value_Properties_Optional; + break; + case OBJECT_LIGHTING_OUTPUT: + pList = Lighting_Output_Properties_Optional; + break; + case OBJECT_LOAD_CONTROL: + pList = Load_Control_Properties_Optional; + break; + case OBJECT_LIFE_SAFETY_POINT: + pList = Life_Safety_Point_Properties_Optional; + break; + case OBJECT_MULTI_STATE_INPUT: + pList = Multistate_Input_Properties_Optional; + break; + case OBJECT_MULTI_STATE_OUTPUT: + pList = Multistate_Output_Properties_Optional; + break; + case OBJECT_MULTI_STATE_VALUE: + pList = Multistate_Value_Properties_Optional; + break; + case OBJECT_NOTIFICATION_CLASS: + pList = Notification_Class_Properties_Optional; + break; + case OBJECT_TRENDLOG: + pList = Trend_Log_Properties_Optional; + break; + case OBJECT_FILE: + pList = File_Properties_Optional; + break; + case OBJECT_INTEGER_VALUE: + pList = Integer_Value_Properties_Optional; + break; + default: + break; + } + + return pList; +} + +/** + * Function that returns the list of Required properties + * of known standard objects. + * + * @param object_type - enumerated BACNET_OBJECT_TYPE + * @return returns a pointer to a '-1' terminated array of + * type 'int' that contain BACnet object properties for the given object + * type. + */ +const int *property_list_required(BACNET_OBJECT_TYPE object_type) +{ + const int *pList = NULL; + + switch (object_type) { + case OBJECT_DEVICE: + pList = Device_Properties_Required; + break; + case OBJECT_ACCUMULATOR: + pList = Accumulator_Properties_Required; + break; + case OBJECT_ANALOG_INPUT: + pList = Analog_Input_Properties_Required; + break; + case OBJECT_ANALOG_OUTPUT: + pList = Analog_Output_Properties_Required; + break; + case OBJECT_ANALOG_VALUE: + pList = Analog_Value_Properties_Required; + break; + case OBJECT_AVERAGING: + pList = Averaging_Properties_Required; + break; + case OBJECT_BINARY_INPUT: + pList = Binary_Input_Properties_Required; + break; + case OBJECT_BINARY_OUTPUT: + pList = Binary_Output_Properties_Required; + break; + case OBJECT_BINARY_VALUE: + pList = Binary_Value_Properties_Required; + break; + case OBJECT_CALENDAR: + pList = Calendar_Properties_Required; + break; + case OBJECT_CHANNEL: + pList = Channel_Properties_Required; + break; + case OBJECT_COMMAND: + pList = Command_Properties_Required; + break; + case OBJECT_CHARACTERSTRING_VALUE: + pList = CharacterString_Value_Properties_Required; + break; + case OBJECT_LOAD_CONTROL: + pList = Load_Control_Properties_Required; + break; + case OBJECT_LIGHTING_OUTPUT: + pList = Lighting_Output_Properties_Required; + break; + case OBJECT_LIFE_SAFETY_POINT: + pList = Life_Safety_Point_Properties_Required; + break; + case OBJECT_MULTI_STATE_INPUT: + pList = Multistate_Input_Properties_Required; + break; + case OBJECT_MULTI_STATE_OUTPUT: + pList = Multistate_Output_Properties_Required; + break; + case OBJECT_MULTI_STATE_VALUE: + pList = Multistate_Value_Properties_Required; + break; + case OBJECT_NOTIFICATION_CLASS: + pList = Notification_Class_Properties_Required; + break; + case OBJECT_TRENDLOG: + pList = Trend_Log_Properties_Required; + break; + case OBJECT_FILE: + pList = File_Properties_Required; + break; + case OBJECT_INTEGER_VALUE: + pList = Integer_Value_Properties_Required; + break; + default: + pList = Default_Properties_Required; + break; + } + + return pList; +} + +/** + * Function that returns the list of Required or Optional properties + * of known standard objects. + * + * @param object_type - enumerated BACNET_OBJECT_TYPE + * @param pPropertyList - returns a pointer to two '-1' terminated arrays of + * type 'int' that contain BACnet object properties for the given object + * type. + */ +void property_list_special(BACNET_OBJECT_TYPE object_type, + struct special_property_list_t *pPropertyList) +{ + if (pPropertyList == NULL) { + return; + } + pPropertyList->Required.pList = property_list_required(object_type); + pPropertyList->Optional.pList = property_list_optional(object_type); + pPropertyList->Proprietary.pList = NULL; + /* Fetch the counts if available otherwise zero them */ + pPropertyList->Required.count = + property_list_count(pPropertyList->Required.pList); + pPropertyList->Optional.count = + property_list_count(pPropertyList->Optional.pList); + pPropertyList->Proprietary.count = 0; + + return; +} + +BACNET_PROPERTY_ID property_list_special_property( + BACNET_OBJECT_TYPE object_type, + BACNET_PROPERTY_ID special_property, + unsigned index) +{ + int property = -1; /* return value */ + unsigned required, optional, proprietary; + struct special_property_list_t PropertyList = { { 0 } }; + + property_list_special(object_type, &PropertyList); + required = PropertyList.Required.count; + optional = PropertyList.Optional.count; + proprietary = PropertyList.Proprietary.count; + if (special_property == PROP_ALL) { + if (index < required) { + if (PropertyList.Required.pList) { + property = PropertyList.Required.pList[index]; + } + } else if (index < (required + optional)) { + if (PropertyList.Optional.pList) { + index -= required; + property = PropertyList.Optional.pList[index]; + } + } else if (index < (required + optional + proprietary)) { + if (PropertyList.Proprietary.pList) { + index -= (required + optional); + property = PropertyList.Proprietary.pList[index]; + } + } + } else if (special_property == PROP_REQUIRED) { + if (index < required) { + if (PropertyList.Required.pList) { + property = PropertyList.Required.pList[index]; + } + } + } else if (special_property == PROP_OPTIONAL) { + if (index < optional) { + if (PropertyList.Optional.pList) { + property = PropertyList.Optional.pList[index]; + } + } + } + + return (BACNET_PROPERTY_ID)property; +} + +unsigned property_list_special_count( + BACNET_OBJECT_TYPE object_type, BACNET_PROPERTY_ID special_property) +{ + unsigned count = 0; /* return value */ + struct special_property_list_t PropertyList = { { 0 } }; + + property_list_special(object_type, &PropertyList); + if (special_property == PROP_ALL) { + count = PropertyList.Required.count + PropertyList.Optional.count + + PropertyList.Proprietary.count; + } else if (special_property == PROP_REQUIRED) { + count = PropertyList.Required.count; + } else if (special_property == PROP_OPTIONAL) { + count = PropertyList.Optional.count; + } + + return count; +} +#endif + +#ifdef TEST +#include +#include +#include "ctest.h" + +void testPropList(Test *pTest) +{ + unsigned i = 0, j = 0; + unsigned count = 0; + BACNET_PROPERTY_ID property = MAX_BACNET_PROPERTY_ID; + unsigned object_id = 0, object_name = 0, object_type = 0; + struct special_property_list_t property_list = { 0 }; + + for (i = 0; i < OBJECT_PROPRIETARY_MIN; i++) { + count = property_list_special_count((BACNET_OBJECT_TYPE)i, PROP_ALL); + ct_test(pTest, count >= 3); + object_id = 0; + object_name = 0; + object_type = 0; + for (j = 0; j < count; j++) { + property = property_list_special_property( + (BACNET_OBJECT_TYPE)i, PROP_ALL, j); + if (property == PROP_OBJECT_TYPE) { + object_type++; + } + if (property == PROP_OBJECT_IDENTIFIER) { + object_id++; + } + if (property == PROP_OBJECT_NAME) { + object_name++; + } + } + ct_test(pTest, object_type == 1); + ct_test(pTest, object_id == 1); + ct_test(pTest, object_name == 1); + /* test member function */ + property_list_special((BACNET_OBJECT_TYPE)i, &property_list); + ct_test(pTest, + property_list_member( + property_list.Required.pList, PROP_OBJECT_TYPE)); + ct_test(pTest, + property_list_member( + property_list.Required.pList, PROP_OBJECT_IDENTIFIER)); + ct_test(pTest, + property_list_member( + property_list.Required.pList, PROP_OBJECT_NAME)); + } +} + +#ifdef TEST_PROPLIST +int main(void) +{ + Test *pTest; + bool rc; + + pTest = ct_create("BACnet Property List", NULL); + /* individual tests */ + rc = ct_addTestFunction(pTest, testPropList); + assert(rc); + + ct_setStream(pTest, stdout); + ct_run(pTest); + (void)ct_report(pTest); + ct_destroy(pTest); + + return 0; +} +#endif /* TEST_PROPLIST */ +#endif /* TEST */ diff --git a/include/proplist.h b/src/bacnet/property.h similarity index 76% rename from include/proplist.h rename to src/bacnet/property.h index 9dfbe765..73885244 100644 --- a/include/proplist.h +++ b/src/bacnet/property.h @@ -21,37 +21,22 @@ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *********************************************************************/ -#ifndef PROPLIST_H -#define PROPLIST_H +#ifndef PROPERTY_H +#define PROPERTY_H #include #include -#include "bacdef.h" -#include "bacenum.h" -#include "rp.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacenum.h" +#include "bacnet/rp.h" +#include "bacnet/proplist.h" /** @file proplist.h Library of all required and optional object properties */ -struct property_list_t { - const int *pList; - unsigned count; -}; - -struct special_property_list_t { - struct property_list_t Required; - struct property_list_t Optional; - struct property_list_t Proprietary; -}; - #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ - unsigned property_list_count( - const int *pList); - bool property_list_member( - const int *pList, - int object_property); const int * property_list_optional( BACNET_OBJECT_TYPE object_type); const int * property_list_required( @@ -66,11 +51,6 @@ extern "C" { unsigned property_list_special_count( BACNET_OBJECT_TYPE object_type, BACNET_PROPERTY_ID special_property); - int property_list_encode( - BACNET_READ_PROPERTY_DATA * rpdata, - const int *pListRequired, - const int *pListOptional, - const int *pListProprietary); #ifdef __cplusplus } diff --git a/src/bacnet/proplist.c b/src/bacnet/proplist.c new file mode 100644 index 00000000..8b307b12 --- /dev/null +++ b/src/bacnet/proplist.c @@ -0,0 +1,245 @@ +/*####COPYRIGHTBEGIN#### + ------------------------------------------- + Copyright (C) 2012 Steve Karg + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to: + The Free Software Foundation, Inc. + 59 Temple Place - Suite 330 + Boston, MA 02111-1307, USA. + + As a special exception, if other files instantiate templates or + use macros or inline functions from this file, or you compile + this file and link it with other works to produce a work based + on this file, this file does not by itself cause the resulting + work to be covered by the GNU General Public License. However + the source code for this file must still be made available in + accordance with section (3) of the GNU General Public License. + + This exception does not invalidate any other reasons why a work + based on this file might be covered by the GNU General Public + License. + ------------------------------------------- +####COPYRIGHTEND####*/ +#include +#include "bacnet/bacenum.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacenum.h" +#include "bacnet/rpm.h" +#include "bacnet/rp.h" +#include "bacnet/proplist.h" + +/** + * Function that returns the number of BACnet object properties in a list + * + * @param pList - array of type 'int' that is a list of BACnet object + * properties, terminated by a '-1' value. + */ +unsigned property_list_count(const int *pList) +{ + unsigned property_count = 0; + + if (pList) { + while (*pList != -1) { + property_count++; + pList++; + } + } + + return property_count; +} + +/** + * For a given object property, returns the true if in the property list + * + * @param pList - array of type 'int' that is a list of BACnet object + * @param object_property - property enumeration or propritary value + * + * @return true if object_property is a member of the property list + */ +bool property_list_member(const int *pList, int object_property) +{ + bool status = false; + + if (pList) { + while ((*pList) != -1) { + if (object_property == (*pList)) { + status = true; + break; + } + pList++; + } + } + + return status; +} + +/** + * ReadProperty handler for this property. For the given ReadProperty + * data, the application_data is loaded or the error flags are set. + * + * @param rpdata - ReadProperty data, including requested data and + * data for the reply, or error response. + * + * @return number of APDU bytes in the response, or + * BACNET_STATUS_ERROR on error. + */ +int property_list_encode(BACNET_READ_PROPERTY_DATA *rpdata, + const int *pListRequired, + const int *pListOptional, + const int *pListProprietary) +{ + int apdu_len = 0; /* return value */ + uint8_t *apdu = NULL; + int max_apdu_len = 0; + uint32_t count = 0; + unsigned required_count = 0; + unsigned optional_count = 0; + unsigned proprietary_count = 0; + int len = 0; + unsigned i = 0; /* loop index */ + + required_count = property_list_count(pListRequired); + optional_count = property_list_count(pListOptional); + proprietary_count = property_list_count(pListProprietary); + /* total of all counts */ + count = required_count + optional_count + proprietary_count; + if (required_count >= 3) { + /* less the 3 always required properties */ + count -= 3; + } + if ((rpdata == NULL) || (rpdata->application_data == NULL) || + (rpdata->application_data_len == 0)) { + return 0; + } + apdu = rpdata->application_data; + max_apdu_len = rpdata->application_data_len; + switch (rpdata->object_property) { + case PROP_PROPERTY_LIST: + if (rpdata->array_index == 0) { + /* Array element zero is the number of elements in the array */ + apdu_len = encode_application_unsigned(&apdu[0], count); + } else if (rpdata->array_index == BACNET_ARRAY_ALL) { + /* if no index was specified, then try to encode the entire list + */ + /* into one packet. */ + if (required_count > 3) { + for (i = 0; i < required_count; i++) { + if ((pListRequired[i] == PROP_OBJECT_TYPE) || + (pListRequired[i] == PROP_OBJECT_IDENTIFIER) || + (pListRequired[i] == PROP_OBJECT_NAME)) { + continue; + } else { + len = encode_application_enumerated( + &apdu[apdu_len], (uint32_t)pListRequired[i]); + } + /* add it if we have room */ + if ((apdu_len + len) < max_apdu_len) { + apdu_len += len; + } else { + rpdata->error_code = + ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED; + apdu_len = BACNET_STATUS_ABORT; + break; + } + } + } + if (optional_count) { + for (i = 0; i < optional_count; i++) { + len = encode_application_enumerated( + &apdu[apdu_len], (uint32_t)pListOptional[i]); + /* add it if we have room */ + if ((apdu_len + len) < max_apdu_len) { + apdu_len += len; + } else { + rpdata->error_code = + ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED; + apdu_len = BACNET_STATUS_ABORT; + break; + } + } + } + if (proprietary_count) { + for (i = 0; i < proprietary_count; i++) { + len = encode_application_enumerated( + &apdu[apdu_len], (uint32_t)pListProprietary[i]); + /* add it if we have room */ + if ((apdu_len + len) < max_apdu_len) { + apdu_len += len; + } else { + rpdata->error_code = + ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED; + apdu_len = BACNET_STATUS_ABORT; + break; + } + } + } + } else { + if (rpdata->array_index <= count) { + count = 0; + if (required_count > 3) { + for (i = 0; i < required_count; i++) { + if ((pListRequired[i] == PROP_OBJECT_TYPE) || + (pListRequired[i] == PROP_OBJECT_IDENTIFIER) || + (pListRequired[i] == PROP_OBJECT_NAME)) { + continue; + } else { + count++; + } + if (count == rpdata->array_index) { + apdu_len = encode_application_enumerated( + &apdu[apdu_len], + (uint32_t)pListRequired[i]); + break; + } + } + } + if ((apdu_len == 0) && (optional_count > 0)) { + for (i = 0; i < optional_count; i++) { + count++; + if (count == rpdata->array_index) { + apdu_len = encode_application_enumerated( + &apdu[apdu_len], + (uint32_t)pListOptional[i]); + break; + } + } + } + if ((apdu_len == 0) && (proprietary_count > 0)) { + for (i = 0; i < proprietary_count; i++) { + count++; + if (count == rpdata->array_index) { + apdu_len = encode_application_enumerated( + &apdu[apdu_len], + (uint32_t)pListProprietary[i]); + break; + } + } + } + } else { + rpdata->error_class = ERROR_CLASS_PROPERTY; + rpdata->error_code = ERROR_CODE_INVALID_ARRAY_INDEX; + apdu_len = BACNET_STATUS_ERROR; + } + } + break; + default: + rpdata->error_class = ERROR_CLASS_PROPERTY; + rpdata->error_code = ERROR_CODE_UNKNOWN_PROPERTY; + apdu_len = BACNET_STATUS_ERROR; + break; + } + + return apdu_len; +} diff --git a/ports/linux/timer.h b/src/bacnet/proplist.h similarity index 63% rename from ports/linux/timer.h rename to src/bacnet/proplist.h index a2fff783..a45b3824 100644 --- a/ports/linux/timer.h +++ b/src/bacnet/proplist.h @@ -1,6 +1,6 @@ /************************************************************************** * -* Copyright (C) 2009 Steve Karg +* Copyright (C) 2012 Steve Karg * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the @@ -21,43 +21,41 @@ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *********************************************************************/ -#ifndef TIMER_H -#define TIMER_H +#ifndef PROPLIST_H +#define PROPLIST_H -#include #include -#include /* for timeval */ +#include +#include "bacnet/bacdef.h" +#include "bacnet/bacenum.h" +#include "bacnet/rp.h" -/* Timer Module */ -#ifndef MAX_MILLISECOND_TIMERS -#define TIMER_SILENCE 0 -#define MAX_MILLISECOND_TIMERS 1 -#endif +/** @file Property_List property encode decode helper */ +struct property_list_t { + const int *pList; + unsigned count; +}; + +struct special_property_list_t { + struct property_list_t Required; + struct property_list_t Optional; + struct property_list_t Proprietary; +}; #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ - uint32_t timeGetTime( - void); - void timer_init( - void); - uint32_t timer_milliseconds( - unsigned index); - bool timer_elapsed_milliseconds( - unsigned index, - uint32_t value); - bool timer_elapsed_seconds( - unsigned index, - uint32_t value); - bool timer_elapsed_minutes( - unsigned index, - uint32_t seconds); - uint32_t timer_milliseconds_set( - unsigned index, - uint32_t value); - uint32_t timer_reset( - unsigned index); + unsigned property_list_count( + const int *pList); + bool property_list_member( + const int *pList, + int object_property); + int property_list_encode( + BACNET_READ_PROPERTY_DATA * rpdata, + const int *pListRequired, + const int *pListOptional, + const int *pListProprietary); #ifdef __cplusplus } diff --git a/src/ptransfer.c b/src/bacnet/ptransfer.c similarity index 71% rename from src/ptransfer.c rename to src/bacnet/ptransfer.c index 67cdb854..93aea2c0 100644 --- a/src/ptransfer.c +++ b/src/bacnet/ptransfer.c @@ -32,34 +32,35 @@ ------------------------------------------- ####COPYRIGHTEND####*/ #include -#include "bacenum.h" -#include "bacdcode.h" -#include "bacdef.h" -#include "ptransfer.h" +#include "bacnet/bacenum.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacdef.h" +#include "bacnet/ptransfer.h" /** @file ptransfer.c Encode/Decode Private Transfer data */ /* encode service */ -static int pt_encode_apdu(uint8_t *apdu, uint16_t max_apdu, - BACNET_PRIVATE_TRANSFER_DATA *private_data) +static int pt_encode_apdu(uint8_t *apdu, + uint16_t max_apdu, + BACNET_PRIVATE_TRANSFER_DATA *private_data) { - int len = 0; /* length of each encoding */ + int len = 0; /* length of each encoding */ int apdu_len = 0; /* total length of the apdu, return value */ - /* - Unconfirmed/ConfirmedPrivateTransfer-Request ::= SEQUENCE { - vendorID [0] Unsigned, - serviceNumber [1] Unsigned, - serviceParameters [2] ABSTRACT-SYNTAX.&Type OPTIONAL - } - */ + /* + Unconfirmed/ConfirmedPrivateTransfer-Request ::= SEQUENCE { + vendorID [0] Unsigned, + serviceNumber [1] Unsigned, + serviceParameters [2] ABSTRACT-SYNTAX.&Type OPTIONAL + } + */ /* unused parameter */ max_apdu = max_apdu; if (apdu) { len = encode_context_unsigned(&apdu[apdu_len], 0, private_data->vendorID); apdu_len += len; - len = encode_context_unsigned(&apdu[apdu_len], 1, - private_data->serviceNumber); + len = encode_context_unsigned( + &apdu[apdu_len], 1, private_data->serviceNumber); apdu_len += len; len = encode_opening_tag(&apdu[apdu_len], 2); apdu_len += len; @@ -74,8 +75,9 @@ static int pt_encode_apdu(uint8_t *apdu, uint16_t max_apdu, return apdu_len; } -int ptransfer_encode_apdu(uint8_t *apdu, uint8_t invoke_id, - BACNET_PRIVATE_TRANSFER_DATA *private_data) +int ptransfer_encode_apdu(uint8_t *apdu, + uint8_t invoke_id, + BACNET_PRIVATE_TRANSFER_DATA *private_data) { int apdu_len = 0; /* total length of the apdu, return value */ int len = 0; @@ -86,16 +88,16 @@ int ptransfer_encode_apdu(uint8_t *apdu, uint8_t invoke_id, apdu[2] = invoke_id; apdu[3] = SERVICE_CONFIRMED_PRIVATE_TRANSFER; apdu_len = 4; - len = pt_encode_apdu(&apdu[apdu_len], (uint16_t)(MAX_APDU - apdu_len), - private_data); + len = pt_encode_apdu( + &apdu[apdu_len], (uint16_t)(MAX_APDU - apdu_len), private_data); apdu_len += len; } return apdu_len; } -int uptransfer_encode_apdu(uint8_t *apdu, - BACNET_PRIVATE_TRANSFER_DATA *private_data) +int uptransfer_encode_apdu( + uint8_t *apdu, BACNET_PRIVATE_TRANSFER_DATA *private_data) { int apdu_len = 0; /* total length of the apdu, return value */ int len = 0; @@ -104,8 +106,8 @@ int uptransfer_encode_apdu(uint8_t *apdu, apdu[0] = PDU_TYPE_UNCONFIRMED_SERVICE_REQUEST; apdu[1] = SERVICE_UNCONFIRMED_PRIVATE_TRANSFER; apdu_len = 2; - len = pt_encode_apdu(&apdu[apdu_len], (uint16_t)(MAX_APDU - apdu_len), - private_data); + len = pt_encode_apdu( + &apdu[apdu_len], (uint16_t)(MAX_APDU - apdu_len), private_data); apdu_len += len; } @@ -113,10 +115,11 @@ int uptransfer_encode_apdu(uint8_t *apdu, } /* decode the service request only */ -int ptransfer_decode_service_request(uint8_t *apdu, unsigned apdu_len, - BACNET_PRIVATE_TRANSFER_DATA *private_data) +int ptransfer_decode_service_request(uint8_t *apdu, + unsigned apdu_len, + BACNET_PRIVATE_TRANSFER_DATA *private_data) { - int len = 0; /* return value */ + int len = 0; /* return value */ int decode_len = 0; /* return value */ uint32_t unsigned_value = 0; @@ -154,13 +157,14 @@ int ptransfer_decode_service_request(uint8_t *apdu, unsigned apdu_len, return len; } -int ptransfer_error_encode_apdu(uint8_t *apdu, uint8_t invoke_id, - BACNET_ERROR_CLASS error_class, - BACNET_ERROR_CODE error_code, - BACNET_PRIVATE_TRANSFER_DATA *private_data) +int ptransfer_error_encode_apdu(uint8_t *apdu, + uint8_t invoke_id, + BACNET_ERROR_CLASS error_class, + BACNET_ERROR_CODE error_code, + BACNET_PRIVATE_TRANSFER_DATA *private_data) { int apdu_len = 0; /* total length of the apdu, return value */ - int len = 0; /* length of the part of the encoding */ + int len = 0; /* length of the part of the encoding */ if (apdu) { apdu[0] = PDU_TYPE_ERROR; @@ -187,8 +191,8 @@ int ptransfer_error_encode_apdu(uint8_t *apdu, uint8_t invoke_id, len = encode_context_unsigned(&apdu[apdu_len], 1, private_data->vendorID); apdu_len += len; - len = encode_context_unsigned(&apdu[apdu_len], 2, - private_data->serviceNumber); + len = encode_context_unsigned( + &apdu[apdu_len], 2, private_data->serviceNumber); apdu_len += len; len = encode_opening_tag(&apdu[apdu_len], 3); apdu_len += len; @@ -204,11 +208,13 @@ int ptransfer_error_encode_apdu(uint8_t *apdu, uint8_t invoke_id, } /* decode the service request only */ -int ptransfer_error_decode_service_request( - uint8_t *apdu, unsigned apdu_len, BACNET_ERROR_CLASS *error_class, - BACNET_ERROR_CODE *error_code, BACNET_PRIVATE_TRANSFER_DATA *private_data) +int ptransfer_error_decode_service_request(uint8_t *apdu, + unsigned apdu_len, + BACNET_ERROR_CLASS *error_class, + BACNET_ERROR_CODE *error_code, + BACNET_PRIVATE_TRANSFER_DATA *private_data) { - int len = 0; /* return value */ + int len = 0; /* return value */ int decode_len = 0; /* return value */ uint8_t tag_number = 0; uint32_t len_value_type = 0; @@ -221,8 +227,8 @@ int ptransfer_error_decode_service_request( /* a tag number of 0 is not extended so only one octet */ len++; /* error class */ - decode_len = decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value_type); + decode_len = decode_tag_number_and_value( + &apdu[len], &tag_number, &len_value_type); len += decode_len; if (tag_number != BACNET_APPLICATION_TAG_ENUMERATED) { return 0; @@ -234,8 +240,8 @@ int ptransfer_error_decode_service_request( *error_class = (BACNET_ERROR_CLASS)unsigned_value; } /* error code */ - decode_len = decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value_type); + decode_len = decode_tag_number_and_value( + &apdu[len], &tag_number, &len_value_type); len += decode_len; if (tag_number != BACNET_APPLICATION_TAG_ENUMERATED) { return 0; @@ -284,15 +290,16 @@ int ptransfer_error_decode_service_request( return len; } -int ptransfer_ack_encode_apdu(uint8_t *apdu, uint8_t invoke_id, - BACNET_PRIVATE_TRANSFER_DATA *private_data) +int ptransfer_ack_encode_apdu(uint8_t *apdu, + uint8_t invoke_id, + BACNET_PRIVATE_TRANSFER_DATA *private_data) { - int len = 0; /* length of each encoding */ + int len = 0; /* length of each encoding */ int apdu_len = 0; /* total length of the apdu, return value */ if (apdu) { apdu[0] = PDU_TYPE_COMPLEX_ACK; /* complex ACK service */ - apdu[1] = invoke_id; /* original invoke id from request */ + apdu[1] = invoke_id; /* original invoke id from request */ apdu[2] = SERVICE_CONFIRMED_PRIVATE_TRANSFER; /* service choice */ apdu_len = 3; /* service ack follows */ @@ -306,8 +313,8 @@ int ptransfer_ack_encode_apdu(uint8_t *apdu, uint8_t invoke_id, len = encode_context_unsigned(&apdu[apdu_len], 0, private_data->vendorID); apdu_len += len; - len = encode_context_unsigned(&apdu[apdu_len], 1, - private_data->serviceNumber); + len = encode_context_unsigned( + &apdu[apdu_len], 1, private_data->serviceNumber); apdu_len += len; len = encode_opening_tag(&apdu[apdu_len], 2); apdu_len += len; @@ -329,10 +336,12 @@ int ptransfer_ack_encode_apdu(uint8_t *apdu, uint8_t invoke_id, #include #include #include "ctest.h" -#include "bacapp.h" +#include "bacnet/bacapp.h" -int ptransfer_decode_apdu(uint8_t *apdu, unsigned apdu_len, uint8_t *invoke_id, - BACNET_PRIVATE_TRANSFER_DATA *private_data) +int ptransfer_decode_apdu(uint8_t *apdu, + unsigned apdu_len, + uint8_t *invoke_id, + BACNET_PRIVATE_TRANSFER_DATA *private_data) { int len = 0; unsigned offset = 0; @@ -350,15 +359,16 @@ int ptransfer_decode_apdu(uint8_t *apdu, unsigned apdu_len, uint8_t *invoke_id, offset = 4; if (apdu_len > offset) { - len = ptransfer_decode_service_request(&apdu[offset], apdu_len - offset, - private_data); + len = ptransfer_decode_service_request( + &apdu[offset], apdu_len - offset, private_data); } return len; } -int uptransfer_decode_apdu(uint8_t *apdu, unsigned apdu_len, - BACNET_PRIVATE_TRANSFER_DATA *private_data) +int uptransfer_decode_apdu(uint8_t *apdu, + unsigned apdu_len, + BACNET_PRIVATE_TRANSFER_DATA *private_data) { int len = 0; unsigned offset = 0; @@ -375,17 +385,17 @@ int uptransfer_decode_apdu(uint8_t *apdu, unsigned apdu_len, } offset = 2; if (apdu_len > offset) { - len = ptransfer_decode_service_request(&apdu[offset], apdu_len - offset, - private_data); + len = ptransfer_decode_service_request( + &apdu[offset], apdu_len - offset, private_data); } return len; } int ptransfer_ack_decode_apdu(uint8_t *apdu, - int apdu_len, /* total length of the apdu */ - uint8_t *invoke_id, - BACNET_PRIVATE_TRANSFER_DATA *private_data) + int apdu_len, /* total length of the apdu */ + uint8_t *invoke_id, + BACNET_PRIVATE_TRANSFER_DATA *private_data) { int len = 0; int offset = 0; @@ -400,19 +410,19 @@ int ptransfer_ack_decode_apdu(uint8_t *apdu, return -1; offset = 3; if (apdu_len > offset) { - len = ptransfer_decode_service_request(&apdu[offset], apdu_len - offset, - private_data); + len = ptransfer_decode_service_request( + &apdu[offset], apdu_len - offset, private_data); } return len; } int ptransfer_error_decode_apdu(uint8_t *apdu, - int apdu_len, /* total length of the apdu */ - uint8_t *invoke_id, - BACNET_ERROR_CLASS *error_class, - BACNET_ERROR_CODE *error_code, - BACNET_PRIVATE_TRANSFER_DATA *private_data) + int apdu_len, /* total length of the apdu */ + uint8_t *invoke_id, + BACNET_ERROR_CLASS *error_class, + BACNET_ERROR_CODE *error_code, + BACNET_PRIVATE_TRANSFER_DATA *private_data) { int len = 0; int offset = 0; @@ -427,9 +437,8 @@ int ptransfer_error_decode_apdu(uint8_t *apdu, return -1; offset = 3; if (apdu_len > offset) { - len = ptransfer_error_decode_service_request( - &apdu[offset], apdu_len - offset, error_class, error_code, - private_data); + len = ptransfer_error_decode_service_request(&apdu[offset], + apdu_len - offset, error_class, error_code, private_data); } return len; @@ -437,16 +446,16 @@ int ptransfer_error_decode_apdu(uint8_t *apdu, void test_Private_Transfer_Ack(Test *pTest) { - uint8_t apdu[480] = {0}; + uint8_t apdu[480] = { 0 }; int len = 0; int apdu_len = 0; uint8_t invoke_id = 128; uint8_t test_invoke_id = 0; BACNET_PRIVATE_TRANSFER_DATA private_data; BACNET_PRIVATE_TRANSFER_DATA test_data; - uint8_t test_value[480] = {0}; + uint8_t test_value[480] = { 0 }; int private_data_len = 0; - char private_data_chunk[33] = {"00112233445566778899AABBCCDDEEFF"}; + char private_data_chunk[33] = { "00112233445566778899AABBCCDDEEFF" }; BACNET_APPLICATION_DATA_VALUE data_value; BACNET_APPLICATION_DATA_VALUE test_data_value; bool status = false; @@ -455,7 +464,7 @@ void test_Private_Transfer_Ack(Test *pTest) private_data.serviceNumber = 1; status = bacapp_parse_application_data(BACNET_APPLICATION_TAG_OCTET_STRING, - &private_data_chunk[0], &data_value); + &private_data_chunk[0], &data_value); ct_test(pTest, status == true); private_data_len = bacapp_encode_application_data(&test_value[0], &data_value); @@ -467,23 +476,22 @@ void test_Private_Transfer_Ack(Test *pTest) ct_test(pTest, len != 0); ct_test(pTest, len != -1); apdu_len = len; - len = ptransfer_ack_decode_apdu(&apdu[0], apdu_len, &test_invoke_id, - &test_data); + len = ptransfer_ack_decode_apdu( + &apdu[0], apdu_len, &test_invoke_id, &test_data); ct_test(pTest, len != -1); ct_test(pTest, test_invoke_id == invoke_id); ct_test(pTest, test_data.vendorID == private_data.vendorID); ct_test(pTest, test_data.serviceNumber == private_data.serviceNumber); - ct_test(pTest, test_data.serviceParametersLen == - private_data.serviceParametersLen); + ct_test(pTest, + test_data.serviceParametersLen == private_data.serviceParametersLen); len = bacapp_decode_application_data(test_data.serviceParameters, - test_data.serviceParametersLen, - &test_data_value); + test_data.serviceParametersLen, &test_data_value); ct_test(pTest, bacapp_same_value(&data_value, &test_data_value) == true); } void test_Private_Transfer_Error(Test *pTest) { - uint8_t apdu[480] = {0}; + uint8_t apdu[480] = { 0 }; int len = 0; int apdu_len = 0; uint8_t invoke_id = 128; @@ -494,9 +502,9 @@ void test_Private_Transfer_Error(Test *pTest) BACNET_ERROR_CODE test_error_code = 0; BACNET_PRIVATE_TRANSFER_DATA private_data; BACNET_PRIVATE_TRANSFER_DATA test_data; - uint8_t test_value[480] = {0}; + uint8_t test_value[480] = { 0 }; int private_data_len = 0; - char private_data_chunk[33] = {"00112233445566778899AABBCCDDEEFF"}; + char private_data_chunk[33] = { "00112233445566778899AABBCCDDEEFF" }; BACNET_APPLICATION_DATA_VALUE data_value; BACNET_APPLICATION_DATA_VALUE test_data_value; bool status = false; @@ -505,56 +513,54 @@ void test_Private_Transfer_Error(Test *pTest) private_data.serviceNumber = 1; status = bacapp_parse_application_data(BACNET_APPLICATION_TAG_OCTET_STRING, - &private_data_chunk[0], &data_value); + &private_data_chunk[0], &data_value); ct_test(pTest, status == true); private_data_len = bacapp_encode_application_data(&test_value[0], &data_value); private_data.serviceParameters = &test_value[0]; private_data.serviceParametersLen = private_data_len; - len = ptransfer_error_encode_apdu(&apdu[0], invoke_id, error_class, - error_code, &private_data); + len = ptransfer_error_encode_apdu( + &apdu[0], invoke_id, error_class, error_code, &private_data); ct_test(pTest, len != 0); ct_test(pTest, len != -1); apdu_len = len; len = ptransfer_error_decode_apdu(&apdu[0], apdu_len, &test_invoke_id, - &test_error_class, &test_error_code, - &test_data); + &test_error_class, &test_error_code, &test_data); ct_test(pTest, len != -1); ct_test(pTest, test_invoke_id == invoke_id); ct_test(pTest, test_data.vendorID == private_data.vendorID); ct_test(pTest, test_data.serviceNumber == private_data.serviceNumber); ct_test(pTest, test_error_class == error_class); ct_test(pTest, test_error_code == error_code); - ct_test(pTest, test_data.serviceParametersLen == - private_data.serviceParametersLen); + ct_test(pTest, + test_data.serviceParametersLen == private_data.serviceParametersLen); len = bacapp_decode_application_data(test_data.serviceParameters, - test_data.serviceParametersLen, - &test_data_value); + test_data.serviceParametersLen, &test_data_value); ct_test(pTest, bacapp_same_value(&data_value, &test_data_value) == true); } void test_Private_Transfer_Request(Test *pTest) { - uint8_t apdu[480] = {0}; - uint8_t test_value[480] = {0}; + uint8_t apdu[480] = { 0 }; + uint8_t test_value[480] = { 0 }; int len = 0; int apdu_len = 0; uint8_t invoke_id = 128; uint8_t test_invoke_id = 0; int private_data_len = 0; - char private_data_chunk[33] = {"00112233445566778899AABBCCDDEEFF"}; - BACNET_APPLICATION_DATA_VALUE data_value = {0}; - BACNET_APPLICATION_DATA_VALUE test_data_value = {0}; - BACNET_PRIVATE_TRANSFER_DATA private_data = {0}; - BACNET_PRIVATE_TRANSFER_DATA test_data = {0}; + char private_data_chunk[33] = { "00112233445566778899AABBCCDDEEFF" }; + BACNET_APPLICATION_DATA_VALUE data_value = { 0 }; + BACNET_APPLICATION_DATA_VALUE test_data_value = { 0 }; + BACNET_PRIVATE_TRANSFER_DATA private_data = { 0 }; + BACNET_PRIVATE_TRANSFER_DATA test_data = { 0 }; bool status = false; private_data.vendorID = BACNET_VENDOR_ID; private_data.serviceNumber = 1; status = bacapp_parse_application_data(BACNET_APPLICATION_TAG_OCTET_STRING, - &private_data_chunk[0], &data_value); + &private_data_chunk[0], &data_value); ct_test(pTest, status == true); private_data_len = bacapp_encode_application_data(&test_value[0], &data_value); @@ -569,11 +575,10 @@ void test_Private_Transfer_Request(Test *pTest) ct_test(pTest, len != -1); ct_test(pTest, test_data.vendorID == private_data.vendorID); ct_test(pTest, test_data.serviceNumber == private_data.serviceNumber); - ct_test(pTest, test_data.serviceParametersLen == - private_data.serviceParametersLen); + ct_test(pTest, + test_data.serviceParametersLen == private_data.serviceParametersLen); len = bacapp_decode_application_data(test_data.serviceParameters, - test_data.serviceParametersLen, - &test_data_value); + test_data.serviceParametersLen, &test_data_value); ct_test(pTest, bacapp_same_value(&data_value, &test_data_value) == true); return; @@ -581,12 +586,12 @@ void test_Private_Transfer_Request(Test *pTest) void test_Unconfirmed_Private_Transfer_Request(Test *pTest) { - uint8_t apdu[480] = {0}; - uint8_t test_value[480] = {0}; + uint8_t apdu[480] = { 0 }; + uint8_t test_value[480] = { 0 }; int len = 0; int apdu_len = 0; int private_data_len = 0; - char private_data_chunk[32] = {"I Love You, Patricia!"}; + char private_data_chunk[32] = { "I Love You, Patricia!" }; BACNET_APPLICATION_DATA_VALUE data_value; BACNET_APPLICATION_DATA_VALUE test_data_value; BACNET_PRIVATE_TRANSFER_DATA private_data; @@ -598,7 +603,7 @@ void test_Unconfirmed_Private_Transfer_Request(Test *pTest) status = bacapp_parse_application_data(BACNET_APPLICATION_TAG_CHARACTER_STRING, - &private_data_chunk[0], &data_value); + &private_data_chunk[0], &data_value); ct_test(pTest, status == true); private_data_len = bacapp_encode_application_data(&test_value[0], &data_value); @@ -612,11 +617,10 @@ void test_Unconfirmed_Private_Transfer_Request(Test *pTest) ct_test(pTest, len != -1); ct_test(pTest, test_data.vendorID == private_data.vendorID); ct_test(pTest, test_data.serviceNumber == private_data.serviceNumber); - ct_test(pTest, test_data.serviceParametersLen == - private_data.serviceParametersLen); + ct_test(pTest, + test_data.serviceParametersLen == private_data.serviceParametersLen); len = bacapp_decode_application_data(test_data.serviceParameters, - test_data.serviceParametersLen, - &test_data_value); + test_data.serviceParametersLen, &test_data_value); ct_test(pTest, bacapp_same_value(&data_value, &test_data_value) == true); return; diff --git a/include/ptransfer.h b/src/bacnet/ptransfer.h similarity index 100% rename from include/ptransfer.h rename to src/bacnet/ptransfer.h diff --git a/src/rd.c b/src/bacnet/rd.c similarity index 77% rename from src/rd.c rename to src/bacnet/rd.c index b622242f..20bc3808 100644 --- a/src/rd.c +++ b/src/bacnet/rd.c @@ -32,19 +32,20 @@ ------------------------------------------- ####COPYRIGHTEND####*/ #include -#include "bacenum.h" -#include "bacdcode.h" -#include "bacdef.h" -#include "rd.h" +#include "bacnet/bacenum.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacdef.h" +#include "bacnet/rd.h" /** @file rd.c Encode/Decode Reinitialize Device APDUs */ #if BACNET_SVC_RD_A /* encode service */ -int rd_encode_apdu(uint8_t *apdu, uint8_t invoke_id, - BACNET_REINITIALIZED_STATE state, - BACNET_CHARACTER_STRING *password) +int rd_encode_apdu(uint8_t *apdu, + uint8_t invoke_id, + BACNET_REINITIALIZED_STATE state, + BACNET_CHARACTER_STRING *password) { - int len = 0; /* length of each encoding */ + int len = 0; /* length of each encoding */ int apdu_len = 0; /* total length of the apdu, return value */ if (apdu) { @@ -68,9 +69,10 @@ int rd_encode_apdu(uint8_t *apdu, uint8_t invoke_id, #endif /* decode the service request only */ -int rd_decode_service_request(uint8_t *apdu, unsigned apdu_len, - BACNET_REINITIALIZED_STATE *state, - BACNET_CHARACTER_STRING *password) +int rd_decode_service_request(uint8_t *apdu, + unsigned apdu_len, + BACNET_REINITIALIZED_STATE *state, + BACNET_CHARACTER_STRING *password) { unsigned len = 0; uint8_t tag_number = 0; @@ -80,19 +82,22 @@ int rd_decode_service_request(uint8_t *apdu, unsigned apdu_len, /* check for value pointers */ if (apdu_len) { /* Tag 0: reinitializedStateOfDevice */ - if (!decode_is_context_tag(&apdu[len], 0)) + if (!decode_is_context_tag(&apdu[len], 0)) { return -1; - len += decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value_type); + } + len += decode_tag_number_and_value( + &apdu[len], &tag_number, &len_value_type); len += decode_enumerated(&apdu[len], len_value_type, &value); - if (state) + if (state) { *state = (BACNET_REINITIALIZED_STATE)value; + } /* Tag 1: password - optional */ if (len < apdu_len) { - if (!decode_is_context_tag(&apdu[len], 1)) + if (!decode_is_context_tag(&apdu[len], 1)) { return -1; - len += decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value_type); + } + len += decode_tag_number_and_value( + &apdu[len], &tag_number, &len_value_type); len += decode_character_string(&apdu[len], len_value_type, password); } @@ -106,9 +111,11 @@ int rd_decode_service_request(uint8_t *apdu, unsigned apdu_len, #include #include "ctest.h" -int rd_decode_apdu(uint8_t *apdu, unsigned apdu_len, uint8_t *invoke_id, - BACNET_REINITIALIZED_STATE *state, - BACNET_CHARACTER_STRING *password) +int rd_decode_apdu(uint8_t *apdu, + unsigned apdu_len, + uint8_t *invoke_id, + BACNET_REINITIALIZED_STATE *state, + BACNET_CHARACTER_STRING *password) { int len = 0; unsigned offset = 0; @@ -125,8 +132,8 @@ int rd_decode_apdu(uint8_t *apdu, unsigned apdu_len, uint8_t *invoke_id, offset = 4; if (apdu_len > offset) { - len = rd_decode_service_request(&apdu[offset], apdu_len - offset, state, - password); + len = rd_decode_service_request( + &apdu[offset], apdu_len - offset, state, password); } return len; @@ -134,7 +141,7 @@ int rd_decode_apdu(uint8_t *apdu, unsigned apdu_len, uint8_t *invoke_id, void test_ReinitializeDevice(Test *pTest) { - uint8_t apdu[480] = {0}; + uint8_t apdu[480] = { 0 }; int len = 0; int apdu_len = 0; uint8_t invoke_id = 128; @@ -150,8 +157,8 @@ void test_ReinitializeDevice(Test *pTest) ct_test(pTest, len != 0); apdu_len = len; - len = rd_decode_apdu(&apdu[0], apdu_len, &test_invoke_id, &test_state, - &test_password); + len = rd_decode_apdu( + &apdu[0], apdu_len, &test_invoke_id, &test_state, &test_password); ct_test(pTest, len != -1); ct_test(pTest, test_invoke_id == invoke_id); ct_test(pTest, test_state == state); diff --git a/include/rd.h b/src/bacnet/rd.h similarity index 99% rename from include/rd.h rename to src/bacnet/rd.h index 94ef41e1..e5aacc2f 100644 --- a/include/rd.h +++ b/src/bacnet/rd.h @@ -26,6 +26,7 @@ #include #include +#include "bacnet/bacenum.h" typedef struct BACnet_Reinitialize_Device_Data { BACNET_REINITIALIZED_STATE state; diff --git a/src/readrange.c b/src/bacnet/readrange.c similarity index 70% rename from src/readrange.c rename to src/bacnet/readrange.c index 47da94ed..1d0d54b0 100644 --- a/src/readrange.c +++ b/src/bacnet/readrange.c @@ -32,10 +32,10 @@ ------------------------------------------- ####COPYRIGHTEND####*/ #include -#include "bacenum.h" -#include "bacdcode.h" -#include "bacdef.h" -#include "readrange.h" +#include "bacnet/bacenum.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacdef.h" +#include "bacnet/readrange.h" /** @file readrange.c Encode/Decode ReadRange requests */ @@ -65,8 +65,8 @@ * Build a ReadRange request packet. * *****************************************************************************/ -int rr_encode_apdu(uint8_t* apdu, uint8_t invoke_id, - BACNET_READ_RANGE_DATA* rrdata) +int rr_encode_apdu( + uint8_t *apdu, uint8_t invoke_id, BACNET_READ_RANGE_DATA *rrdata) { int apdu_len = 0; /* total length of the apdu, return value */ @@ -79,14 +79,14 @@ int rr_encode_apdu(uint8_t* apdu, uint8_t invoke_id, apdu_len += encode_context_object_id( &apdu[apdu_len], 0, rrdata->object_type, rrdata->object_instance); - apdu_len += encode_context_enumerated(&apdu[apdu_len], 1, - rrdata->object_property); + apdu_len += encode_context_enumerated( + &apdu[apdu_len], 1, rrdata->object_property); /* optional array index */ if (rrdata->array_index != BACNET_ARRAY_ALL) { - apdu_len += encode_context_unsigned(&apdu[apdu_len], 2, - rrdata->array_index); + apdu_len += encode_context_unsigned( + &apdu[apdu_len], 2, rrdata->array_index); } /* Build the appropriate (optional) range parameter based on the request @@ -95,8 +95,8 @@ int rr_encode_apdu(uint8_t* apdu, uint8_t invoke_id, switch (rrdata->RequestType) { case RR_BY_POSITION: apdu_len += encode_opening_tag(&apdu[apdu_len], 3); - apdu_len += encode_application_unsigned(&apdu[apdu_len], - rrdata->Range.RefIndex); + apdu_len += encode_application_unsigned( + &apdu[apdu_len], rrdata->Range.RefIndex); apdu_len += encode_application_signed(&apdu[apdu_len], rrdata->Count); apdu_len += encode_closing_tag(&apdu[apdu_len], 3); @@ -138,8 +138,8 @@ int rr_encode_apdu(uint8_t* apdu, uint8_t invoke_id, * Decode the received ReadRange request * *****************************************************************************/ -int rr_decode_service_request(uint8_t* apdu, unsigned apdu_len, - BACNET_READ_RANGE_DATA* rrdata) +int rr_decode_service_request( + uint8_t *apdu, unsigned apdu_len, BACNET_READ_RANGE_DATA *rrdata) { unsigned len = 0; unsigned TagLen = 0; @@ -151,22 +151,24 @@ int rr_decode_service_request(uint8_t* apdu, unsigned apdu_len, /* check for value pointers */ if (apdu_len && rrdata) { /* Tag 0: Object ID */ - if (!decode_is_context_tag(&apdu[len++], 0)) + if (!decode_is_context_tag(&apdu[len++], 0)) { return -1; + } len += decode_object_id(&apdu[len], &type, &rrdata->object_instance); rrdata->object_type = (BACNET_OBJECT_TYPE)type; /* Tag 1: Property ID */ - len += decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value_type); - if (tag_number != 1) + len += decode_tag_number_and_value( + &apdu[len], &tag_number, &len_value_type); + if (tag_number != 1) { return -1; + } len += decode_enumerated(&apdu[len], len_value_type, &UnsignedTemp); rrdata->object_property = (BACNET_PROPERTY_ID)UnsignedTemp; rrdata->Overhead = RR_OVERHEAD; /* Start with the fixed overhead */ /* Tag 2: Optional Array Index - set to ALL if not present */ - rrdata->array_index = - BACNET_ARRAY_ALL; /* Assuming this is the most common outcome... */ + rrdata->array_index = BACNET_ARRAY_ALL; /* Assuming this is the most + common outcome... */ if (len < apdu_len) { TagLen = (unsigned)decode_tag_number_and_value( &apdu[len], &tag_number, &len_value_type); @@ -191,58 +193,58 @@ int rr_decode_service_request(uint8_t* apdu, unsigned apdu_len, * that if we receive a tag we don't recognise, we don't try to * decode it blindly and make a mess of it. */ - len += decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value_type); + len += decode_tag_number_and_value( + &apdu[len], &tag_number, &len_value_type); switch (tag_number) { case 3: /* ReadRange by position */ rrdata->RequestType = RR_BY_POSITION; - len += decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value_type); - len += decode_unsigned(&apdu[len], len_value_type, - &rrdata->Range.RefIndex); - len += decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value_type); - len += decode_signed(&apdu[len], len_value_type, - &rrdata->Count); - len += decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value_type); + len += decode_tag_number_and_value( + &apdu[len], &tag_number, &len_value_type); + len += decode_unsigned( + &apdu[len], len_value_type, &rrdata->Range.RefIndex); + len += decode_tag_number_and_value( + &apdu[len], &tag_number, &len_value_type); + len += decode_signed( + &apdu[len], len_value_type, &rrdata->Count); + len += decode_tag_number_and_value( + &apdu[len], &tag_number, &len_value_type); break; case 6: /* ReadRange by sequence number */ rrdata->RequestType = RR_BY_SEQUENCE; - len += decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value_type); - len += decode_unsigned(&apdu[len], len_value_type, - &rrdata->Range.RefSeqNum); - len += decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value_type); - len += decode_signed(&apdu[len], len_value_type, - &rrdata->Count); - len += decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value_type); - rrdata->Overhead += - RR_1ST_SEQ_OVERHEAD; /* Allow for this in the response - */ + len += decode_tag_number_and_value( + &apdu[len], &tag_number, &len_value_type); + len += decode_unsigned( + &apdu[len], len_value_type, &rrdata->Range.RefSeqNum); + len += decode_tag_number_and_value( + &apdu[len], &tag_number, &len_value_type); + len += decode_signed( + &apdu[len], len_value_type, &rrdata->Count); + len += decode_tag_number_and_value( + &apdu[len], &tag_number, &len_value_type); + rrdata->Overhead += RR_1ST_SEQ_OVERHEAD; /* Allow for this + * in the response + */ break; case 7: /* ReadRange by time stamp */ rrdata->RequestType = RR_BY_TIME; - len += decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value_type); + len += decode_tag_number_and_value( + &apdu[len], &tag_number, &len_value_type); len += decode_date(&apdu[len], &rrdata->Range.RefTime.date); - len += decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value_type); - len += decode_bacnet_time(&apdu[len], - &rrdata->Range.RefTime.time); - len += decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value_type); - len += decode_signed(&apdu[len], len_value_type, - &rrdata->Count); - len += decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value_type); - rrdata->Overhead += - RR_1ST_SEQ_OVERHEAD; /* Allow for this in the response - */ + len += decode_tag_number_and_value( + &apdu[len], &tag_number, &len_value_type); + len += decode_bacnet_time( + &apdu[len], &rrdata->Range.RefTime.time); + len += decode_tag_number_and_value( + &apdu[len], &tag_number, &len_value_type); + len += decode_signed( + &apdu[len], len_value_type, &rrdata->Count); + len += decode_tag_number_and_value( + &apdu[len], &tag_number, &len_value_type); + rrdata->Overhead += RR_1ST_SEQ_OVERHEAD; /* Allow for this + * in the response + */ break; default: /* If we don't recognise the tag then we do nothing @@ -273,26 +275,26 @@ int rr_decode_service_request(uint8_t* apdu, unsigned apdu_len, * Build a ReadRange response packet * *****************************************************************************/ -int rr_ack_encode_apdu(uint8_t* apdu, uint8_t invoke_id, - BACNET_READ_RANGE_DATA* rrdata) +int rr_ack_encode_apdu( + uint8_t *apdu, uint8_t invoke_id, BACNET_READ_RANGE_DATA *rrdata) { - int len = 0; /* length of each encoding */ + int len = 0; /* length of each encoding */ int apdu_len = 0; /* total length of the apdu, return value */ if (apdu) { apdu[0] = PDU_TYPE_COMPLEX_ACK; /* complex ACK service */ - apdu[1] = invoke_id; /* original invoke id from request */ + apdu[1] = invoke_id; /* original invoke id from request */ apdu[2] = SERVICE_CONFIRMED_READ_RANGE; /* service choice */ apdu_len = 3; /* service ack follows */ apdu_len += encode_context_object_id( &apdu[apdu_len], 0, rrdata->object_type, rrdata->object_instance); - apdu_len += encode_context_enumerated(&apdu[apdu_len], 1, - rrdata->object_property); + apdu_len += encode_context_enumerated( + &apdu[apdu_len], 1, rrdata->object_property); /* context 2 array index is optional */ if (rrdata->array_index != BACNET_ARRAY_ALL) { - apdu_len += encode_context_unsigned(&apdu[apdu_len], 2, - rrdata->array_index); + apdu_len += encode_context_unsigned( + &apdu[apdu_len], 2, rrdata->array_index); } /* Context 3 BACnet Result Flags */ apdu_len += @@ -316,8 +318,8 @@ int rr_ack_encode_apdu(uint8_t* apdu, uint8_t invoke_id, (rrdata->RequestType != RR_BY_POSITION) && (rrdata->RequestType != RR_READ_ALL)) { /* Context 6 Sequence number of first item */ - apdu_len += encode_context_unsigned(&apdu[apdu_len], 6, - rrdata->FirstSequence); + apdu_len += encode_context_unsigned( + &apdu[apdu_len], 6, rrdata->FirstSequence); } } @@ -328,23 +330,24 @@ int rr_ack_encode_apdu(uint8_t* apdu, uint8_t invoke_id, * Decode the received ReadRange response * *****************************************************************************/ -int rr_ack_decode_service_request(uint8_t* apdu, - int apdu_len, /* total length of the apdu */ - BACNET_READ_RANGE_DATA* rrdata) +int rr_ack_decode_service_request(uint8_t *apdu, + int apdu_len, /* total length of the apdu */ + BACNET_READ_RANGE_DATA *rrdata) { uint8_t tag_number = 0; uint32_t len_value_type = 0; int tag_len = 0; /* length of tag decode */ - int len = 0; /* total length of decodes */ + int len = 0; /* total length of decodes */ int start_len; - uint16_t object = 0; /* object type */ - uint32_t property = 0; /* for decoding */ + uint16_t object = 0; /* object type */ + uint32_t property = 0; /* for decoding */ uint32_t array_value = 0; /* for decoding */ /* FIXME: check apdu_len against the len during decode */ /* Tag 0: Object ID */ - if (!decode_is_context_tag(&apdu[0], 0)) + if (!decode_is_context_tag(&apdu[0], 0)) { return -1; + } len = 1; len += decode_object_id(&apdu[len], &object, &rrdata->object_instance); rrdata->object_type = (BACNET_OBJECT_TYPE)object; @@ -352,8 +355,9 @@ int rr_ack_decode_service_request(uint8_t* apdu, /* Tag 1: Property ID */ len += decode_tag_number_and_value(&apdu[len], &tag_number, &len_value_type); - if (tag_number != 1) + if (tag_number != 1) { return -1; + } len += decode_enumerated(&apdu[len], len_value_type, &property); rrdata->object_property = (BACNET_PROPERTY_ID)property; @@ -364,22 +368,25 @@ int rr_ack_decode_service_request(uint8_t* apdu, len += tag_len; len += decode_unsigned(&apdu[len], len_value_type, &array_value); rrdata->array_index = array_value; - } else + } else { rrdata->array_index = BACNET_ARRAY_ALL; + } /* Tag 3: Result Flags */ len += decode_tag_number_and_value(&apdu[len], &tag_number, &len_value_type); - if (tag_number != 3) + if (tag_number != 3) { return -1; + } len += decode_bitstring(&apdu[len], len_value_type, &rrdata->ResultFlags); /* Tag 4: Item count */ len += decode_tag_number_and_value(&apdu[len], &tag_number, &len_value_type); - if (tag_number != 4) + if (tag_number != 4) { return -1; + } len += decode_unsigned(&apdu[len], len_value_type, &rrdata->ItemCount); @@ -397,12 +404,13 @@ int rr_ack_decode_service_request(uint8_t* apdu, break; } else { /* Don't care about tag number, just skipping over anyway */ - len += decode_tag_number_and_value(&apdu[len], NULL, - &len_value_type); + len += decode_tag_number_and_value( + &apdu[len], NULL, &len_value_type); len += len_value_type; /* Skip over data value as well */ - if (len >= apdu_len) /* APDU is exhausted so we have failed to - find closing tag */ + if (len >= apdu_len) { /* APDU is exhausted so we have failed to + find closing tag */ return (-1); + } } } } else { @@ -410,10 +418,11 @@ int rr_ack_decode_service_request(uint8_t* apdu, } if (len < apdu_len) { /* Still something left to look at? */ /* Tag 6: Item count */ - len += decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value_type); - if (tag_number != 6) + len += decode_tag_number_and_value( + &apdu[len], &tag_number, &len_value_type); + if (tag_number != 6) { return -1; + } len += decode_unsigned(&apdu[len], len_value_type, &rrdata->FirstSequence); diff --git a/include/readrange.h b/src/bacnet/readrange.h similarity index 99% rename from include/readrange.h rename to src/bacnet/readrange.h index e002c020..97dcba26 100644 --- a/include/readrange.h +++ b/src/bacnet/readrange.h @@ -24,8 +24,8 @@ #ifndef READRANGE_H #define READRANGE_H -#include "bacstr.h" -#include "datetime.h" +#include "bacnet/bacstr.h" +#include "bacnet/datetime.h" #ifdef __cplusplus extern "C" { diff --git a/src/reject.c b/src/bacnet/reject.c similarity index 85% rename from src/reject.c rename to src/bacnet/reject.c index 4e7d8e5d..c11b3553 100644 --- a/src/reject.c +++ b/src/bacnet/reject.c @@ -32,10 +32,10 @@ ------------------------------------------- ####COPYRIGHTEND####*/ #include -#include "bacenum.h" -#include "bacdcode.h" -#include "bacdef.h" -#include "reject.h" +#include "bacnet/bacenum.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacdef.h" +#include "bacnet/reject.h" /** @file reject.c Encode/Decode Reject APDUs */ @@ -106,16 +106,20 @@ int reject_encode_apdu(uint8_t *apdu, uint8_t invoke_id, uint8_t reject_reason) #if !BACNET_SVC_SERVER /* decode the service request only */ -int reject_decode_service_request(uint8_t *apdu, unsigned apdu_len, - uint8_t *invoke_id, uint8_t *reject_reason) +int reject_decode_service_request(uint8_t *apdu, + unsigned apdu_len, + uint8_t *invoke_id, + uint8_t *reject_reason) { int len = 0; if (apdu_len) { - if (invoke_id) + if (invoke_id) { *invoke_id = apdu[0]; - if (reject_reason) + } + if (reject_reason) { *reject_reason = apdu[1]; + } } return len; @@ -128,8 +132,10 @@ int reject_decode_service_request(uint8_t *apdu, unsigned apdu_len, #include "ctest.h" /* decode the whole APDU - mainly used for unit testing */ -int reject_decode_apdu(uint8_t *apdu, unsigned apdu_len, uint8_t *invoke_id, - uint8_t *reject_reason) +int reject_decode_apdu(uint8_t *apdu, + unsigned apdu_len, + uint8_t *invoke_id, + uint8_t *reject_reason) { int len = 0; @@ -140,8 +146,8 @@ int reject_decode_apdu(uint8_t *apdu, unsigned apdu_len, uint8_t *invoke_id, if (apdu[0] != PDU_TYPE_REJECT) return -1; if (apdu_len > 1) { - len = reject_decode_service_request(&apdu[1], apdu_len - 1, - invoke_id, reject_reason); + len = reject_decode_service_request( + &apdu[1], apdu_len - 1, invoke_id, reject_reason); } } @@ -150,7 +156,7 @@ int reject_decode_apdu(uint8_t *apdu, unsigned apdu_len, uint8_t *invoke_id, void testReject(Test *pTest) { - uint8_t apdu[480] = {0}; + uint8_t apdu[480] = { 0 }; int len = 0; int apdu_len = 0; uint8_t invoke_id = 0; @@ -162,21 +168,21 @@ void testReject(Test *pTest) ct_test(pTest, len != 0); apdu_len = len; - len = reject_decode_apdu(&apdu[0], apdu_len, &test_invoke_id, - &test_reject_reason); + len = reject_decode_apdu( + &apdu[0], apdu_len, &test_invoke_id, &test_reject_reason); ct_test(pTest, len != -1); ct_test(pTest, test_invoke_id == invoke_id); ct_test(pTest, test_reject_reason == reject_reason); /* change type to get negative response */ apdu[0] = PDU_TYPE_ABORT; - len = reject_decode_apdu(&apdu[0], apdu_len, &test_invoke_id, - &test_reject_reason); + len = reject_decode_apdu( + &apdu[0], apdu_len, &test_invoke_id, &test_reject_reason); ct_test(pTest, len == -1); /* test NULL APDU */ - len = reject_decode_apdu(NULL, apdu_len, &test_invoke_id, - &test_reject_reason); + len = reject_decode_apdu( + NULL, apdu_len, &test_invoke_id, &test_reject_reason); ct_test(pTest, len == -1); /* force a zero length */ @@ -189,8 +195,8 @@ void testReject(Test *pTest) len = reject_encode_apdu(&apdu[0], invoke_id, reject_reason); apdu_len = len; ct_test(pTest, len != 0); - len = reject_decode_apdu(&apdu[0], apdu_len, &test_invoke_id, - &test_reject_reason); + len = reject_decode_apdu( + &apdu[0], apdu_len, &test_invoke_id, &test_reject_reason); ct_test(pTest, len != -1); ct_test(pTest, test_invoke_id == invoke_id); ct_test(pTest, test_reject_reason == reject_reason); diff --git a/include/reject.h b/src/bacnet/reject.h similarity index 98% rename from include/reject.h rename to src/bacnet/reject.h index 577da538..701592f8 100644 --- a/include/reject.h +++ b/src/bacnet/reject.h @@ -26,6 +26,7 @@ #include #include +#include "bacnet/bacenum.h" #ifdef __cplusplus extern "C" { diff --git a/src/rp.c b/src/bacnet/rp.c similarity index 79% rename from src/rp.c rename to src/bacnet/rp.c index fded70fb..e07852eb 100644 --- a/src/rp.c +++ b/src/bacnet/rp.c @@ -32,19 +32,19 @@ ------------------------------------------- ####COPYRIGHTEND####*/ #include -#include "bacenum.h" -#include "bacdcode.h" -#include "bacdef.h" -#include "rp.h" +#include "bacnet/bacenum.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacdef.h" +#include "bacnet/rp.h" /** @file rp.c Encode/Decode Read Property and RP ACKs */ #if BACNET_SVC_RP_A /* encode service */ -int rp_encode_apdu(uint8_t *apdu, uint8_t invoke_id, - BACNET_READ_PROPERTY_DATA *rpdata) +int rp_encode_apdu( + uint8_t *apdu, uint8_t invoke_id, BACNET_READ_PROPERTY_DATA *rpdata) { - int len = 0; /* length of each encoding */ + int len = 0; /* length of each encoding */ int apdu_len = 0; /* total length of the apdu, return value */ if (apdu) { @@ -57,21 +57,20 @@ int rp_encode_apdu(uint8_t *apdu, uint8_t invoke_id, /* check bounds so that we could create malformed messages for testing */ len = encode_context_object_id(&apdu[apdu_len], 0, - rpdata->object_type, - rpdata->object_instance); + rpdata->object_type, rpdata->object_instance); apdu_len += len; } if (rpdata->object_property <= MAX_BACNET_PROPERTY_ID) { /* check bounds so that we could create malformed messages for testing */ - len = encode_context_enumerated(&apdu[apdu_len], 1, - rpdata->object_property); + len = encode_context_enumerated( + &apdu[apdu_len], 1, rpdata->object_property); apdu_len += len; } /* optional array index */ if (rpdata->array_index != BACNET_ARRAY_ALL) { - len = encode_context_unsigned(&apdu[apdu_len], 2, - rpdata->array_index); + len = encode_context_unsigned( + &apdu[apdu_len], 2, rpdata->array_index); apdu_len += len; } } @@ -81,14 +80,14 @@ int rp_encode_apdu(uint8_t *apdu, uint8_t invoke_id, #endif /* decode the service request only */ -int rp_decode_service_request(uint8_t *apdu, unsigned apdu_len, - BACNET_READ_PROPERTY_DATA *rpdata) +int rp_decode_service_request( + uint8_t *apdu, unsigned apdu_len, BACNET_READ_PROPERTY_DATA *rpdata) { unsigned len = 0; uint8_t tag_number = 0; uint32_t len_value_type = 0; - uint16_t type = 0; /* for decoding */ - uint32_t property = 0; /* for decoding */ + uint16_t type = 0; /* for decoding */ + uint32_t property = 0; /* for decoding */ uint32_t array_value = 0; /* for decoding */ /* check for value pointers */ @@ -108,8 +107,8 @@ int rp_decode_service_request(uint8_t *apdu, unsigned apdu_len, len += decode_object_id(&apdu[len], &type, &rpdata->object_instance); rpdata->object_type = (BACNET_OBJECT_TYPE)type; /* Tag 1: Property ID */ - len += decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value_type); + len += decode_tag_number_and_value( + &apdu[len], &tag_number, &len_value_type); if (tag_number != 1) { rpdata->error_code = ERROR_CODE_REJECT_INVALID_TAG; return BACNET_STATUS_REJECT; @@ -118,8 +117,8 @@ int rp_decode_service_request(uint8_t *apdu, unsigned apdu_len, rpdata->object_property = (BACNET_PROPERTY_ID)property; /* Tag 2: Optional Array Index */ if (len < apdu_len) { - len += decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value_type); + len += decode_tag_number_and_value( + &apdu[len], &tag_number, &len_value_type); if ((tag_number == 2) && (len < apdu_len)) { len += decode_unsigned(&apdu[len], len_value_type, &array_value); @@ -128,8 +127,9 @@ int rp_decode_service_request(uint8_t *apdu, unsigned apdu_len, rpdata->error_code = ERROR_CODE_REJECT_INVALID_TAG; return BACNET_STATUS_REJECT; } - } else + } else { rpdata->array_index = BACNET_ARRAY_ALL; + } } if (len < apdu_len) { @@ -144,29 +144,29 @@ int rp_decode_service_request(uint8_t *apdu, unsigned apdu_len, } /* alternate method to encode the ack without extra buffer */ -int rp_ack_encode_apdu_init(uint8_t *apdu, uint8_t invoke_id, - BACNET_READ_PROPERTY_DATA *rpdata) +int rp_ack_encode_apdu_init( + uint8_t *apdu, uint8_t invoke_id, BACNET_READ_PROPERTY_DATA *rpdata) { - int len = 0; /* length of each encoding */ + int len = 0; /* length of each encoding */ int apdu_len = 0; /* total length of the apdu, return value */ if (apdu) { apdu[0] = PDU_TYPE_COMPLEX_ACK; /* complex ACK service */ - apdu[1] = invoke_id; /* original invoke id from request */ + apdu[1] = invoke_id; /* original invoke id from request */ apdu[2] = SERVICE_CONFIRMED_READ_PROPERTY; /* service choice */ apdu_len = 3; /* service ack follows */ - len = encode_context_object_id(&apdu[apdu_len], 0, rpdata->object_type, - rpdata->object_instance); + len = encode_context_object_id( + &apdu[apdu_len], 0, rpdata->object_type, rpdata->object_instance); apdu_len += len; - len = encode_context_enumerated(&apdu[apdu_len], 1, - rpdata->object_property); + len = encode_context_enumerated( + &apdu[apdu_len], 1, rpdata->object_property); apdu_len += len; /* context 2 array index is optional */ if (rpdata->array_index != BACNET_ARRAY_ALL) { - len = encode_context_unsigned(&apdu[apdu_len], 2, - rpdata->array_index); + len = encode_context_unsigned( + &apdu[apdu_len], 2, rpdata->array_index); apdu_len += len; } len = encode_opening_tag(&apdu[apdu_len], 3); @@ -188,10 +188,10 @@ int rp_ack_encode_apdu_object_property_end(uint8_t *apdu) return apdu_len; } -int rp_ack_encode_apdu(uint8_t *apdu, uint8_t invoke_id, - BACNET_READ_PROPERTY_DATA *rpdata) +int rp_ack_encode_apdu( + uint8_t *apdu, uint8_t invoke_id, BACNET_READ_PROPERTY_DATA *rpdata) { - int len = 0; /* length of each encoding */ + int len = 0; /* length of each encoding */ int apdu_len = 0; /* total length of the apdu, return value */ if (apdu) { @@ -220,29 +220,31 @@ int rp_ack_encode_apdu(uint8_t *apdu, uint8_t invoke_id, * or -1 on decoding error. */ int rp_ack_decode_service_request(uint8_t *apdu, - int apdu_len, /* total length of the apdu */ - BACNET_READ_PROPERTY_DATA *rpdata) + int apdu_len, /* total length of the apdu */ + BACNET_READ_PROPERTY_DATA *rpdata) { uint8_t tag_number = 0; uint32_t len_value_type = 0; - int tag_len = 0; /* length of tag decode */ - int len = 0; /* total length of decodes */ - uint16_t object = 0; /* object type */ - uint32_t property = 0; /* for decoding */ + int tag_len = 0; /* length of tag decode */ + int len = 0; /* total length of decodes */ + uint16_t object = 0; /* object type */ + uint32_t property = 0; /* for decoding */ uint32_t array_value = 0; /* for decoding */ /* FIXME: check apdu_len against the len during decode */ /* Tag 0: Object ID */ - if (!decode_is_context_tag(&apdu[0], 0)) + if (!decode_is_context_tag(&apdu[0], 0)) { return -1; + } len = 1; len += decode_object_id(&apdu[len], &object, &rpdata->object_instance); rpdata->object_type = (BACNET_OBJECT_TYPE)object; /* Tag 1: Property ID */ len += decode_tag_number_and_value(&apdu[len], &tag_number, &len_value_type); - if (tag_number != 1) + if (tag_number != 1) { return -1; + } len += decode_enumerated(&apdu[len], len_value_type, &property); rpdata->object_property = (BACNET_PROPERTY_ID)property; /* Tag 2: Optional Array Index */ @@ -252,8 +254,9 @@ int rp_ack_decode_service_request(uint8_t *apdu, len += tag_len; len += decode_unsigned(&apdu[len], len_value_type, &array_value); rpdata->array_index = array_value; - } else + } else { rpdata->array_index = BACNET_ARRAY_ALL; + } /* Tag 3: opening context tag */ if (decode_is_opening_tag_number(&apdu[len], 3)) { /* a tag number of 3 is not extended so only one octet */ @@ -276,8 +279,10 @@ int rp_ack_decode_service_request(uint8_t *apdu, #include #include "ctest.h" -int rp_decode_apdu(uint8_t *apdu, unsigned apdu_len, uint8_t *invoke_id, - BACNET_READ_PROPERTY_DATA *rpdata) +int rp_decode_apdu(uint8_t *apdu, + unsigned apdu_len, + uint8_t *invoke_id, + BACNET_READ_PROPERTY_DATA *rpdata) { int len = 0; unsigned offset = 0; @@ -302,8 +307,9 @@ int rp_decode_apdu(uint8_t *apdu, unsigned apdu_len, uint8_t *invoke_id, } int rp_ack_decode_apdu(uint8_t *apdu, - int apdu_len, /* total length of the apdu */ - uint8_t *invoke_id, BACNET_READ_PROPERTY_DATA *rpdata) + int apdu_len, /* total length of the apdu */ + uint8_t *invoke_id, + BACNET_READ_PROPERTY_DATA *rpdata) { int len = 0; int offset = 0; @@ -318,8 +324,8 @@ int rp_ack_decode_apdu(uint8_t *apdu, return -1; offset = 3; if (apdu_len > offset) { - len = rp_ack_decode_service_request(&apdu[offset], apdu_len - offset, - rpdata); + len = rp_ack_decode_service_request( + &apdu[offset], apdu_len - offset, rpdata); } return len; @@ -327,8 +333,8 @@ int rp_ack_decode_apdu(uint8_t *apdu, void testReadPropertyAck(Test *pTest) { - uint8_t apdu[480] = {0}; - uint8_t apdu2[480] = {0}; + uint8_t apdu[480] = { 0 }; + uint8_t apdu2[480] = { 0 }; int len = 0; int apdu_len = 0; uint8_t invoke_id = 1; @@ -353,7 +359,7 @@ void testReadPropertyAck(Test *pTest) ct_test(pTest, len != -1); apdu_len = len; len = rp_ack_decode_apdu(&apdu[0], apdu_len, /* total length of the apdu */ - &test_invoke_id, &test_data); + &test_invoke_id, &test_data); ct_test(pTest, len != -1); ct_test(pTest, test_invoke_id == invoke_id); @@ -361,8 +367,8 @@ void testReadPropertyAck(Test *pTest) ct_test(pTest, test_data.object_instance == rpdata.object_instance); ct_test(pTest, test_data.object_property == rpdata.object_property); ct_test(pTest, test_data.array_index == rpdata.array_index); - ct_test(pTest, - test_data.application_data_len == rpdata.application_data_len); + ct_test( + pTest, test_data.application_data_len == rpdata.application_data_len); /* since object property == object_id, decode the application data using the appropriate decode function */ @@ -375,7 +381,7 @@ void testReadPropertyAck(Test *pTest) void testReadProperty(Test *pTest) { - uint8_t apdu[480] = {0}; + uint8_t apdu[480] = { 0 }; int len = 0; int apdu_len = 0; uint8_t invoke_id = 128; diff --git a/include/rp.h b/src/bacnet/rp.h similarity index 98% rename from include/rp.h rename to src/bacnet/rp.h index 66ab0327..301e7494 100644 --- a/include/rp.h +++ b/src/bacnet/rp.h @@ -26,8 +26,8 @@ #include #include -#include "bacdef.h" -#include "bacenum.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacenum.h" typedef struct BACnet_Read_Property_Data { BACNET_OBJECT_TYPE object_type; diff --git a/src/rpm.c b/src/bacnet/rpm.c similarity index 74% rename from src/rpm.c rename to src/bacnet/rpm.c index dd9e25ba..2d67a147 100644 --- a/src/rpm.c +++ b/src/bacnet/rpm.c @@ -32,13 +32,13 @@ ------------------------------------------- ####COPYRIGHTEND####*/ #include -#include "bacenum.h" -#include "bacerror.h" -#include "bacdcode.h" -#include "bacdef.h" -#include "bacapp.h" -#include "memcopy.h" -#include "rpm.h" +#include "bacnet/bacenum.h" +#include "bacnet/bacerror.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacapp.h" +#include "bacnet/memcopy.h" +#include "bacnet/rpm.h" /** @file rpm.c Encode/Decode Read Property Multiple and RPM ACKs */ @@ -59,8 +59,8 @@ int rpm_encode_apdu_init(uint8_t *apdu, uint8_t invoke_id) return apdu_len; } -int rpm_encode_apdu_object_begin(uint8_t *apdu, BACNET_OBJECT_TYPE object_type, - uint32_t object_instance) +int rpm_encode_apdu_object_begin( + uint8_t *apdu, BACNET_OBJECT_TYPE object_type, uint32_t object_instance) { int apdu_len = 0; /* total length of the apdu, return value */ @@ -74,18 +74,18 @@ int rpm_encode_apdu_object_begin(uint8_t *apdu, BACNET_OBJECT_TYPE object_type, return apdu_len; } -int rpm_encode_apdu_object_property(uint8_t *apdu, - BACNET_PROPERTY_ID object_property, - uint32_t array_index) +int rpm_encode_apdu_object_property( + uint8_t *apdu, BACNET_PROPERTY_ID object_property, uint32_t array_index) { int apdu_len = 0; /* total length of the apdu, return value */ if (apdu) { apdu_len = encode_context_enumerated(&apdu[0], 0, object_property); /* optional array index */ - if (array_index != BACNET_ARRAY_ALL) + if (array_index != BACNET_ARRAY_ALL) { apdu_len += encode_context_unsigned(&apdu[apdu_len], 1, array_index); + } } return apdu_len; @@ -110,29 +110,30 @@ int rpm_encode_apdu_object_end(uint8_t *apdu) * @param read_access_data [in] The RPM data to be requested. * @return Length of encoded bytes, or 0 on failure. */ -int rpm_encode_apdu(uint8_t *apdu, size_t max_apdu, uint8_t invoke_id, - BACNET_READ_ACCESS_DATA *read_access_data) +int rpm_encode_apdu(uint8_t *apdu, + size_t max_apdu, + uint8_t invoke_id, + BACNET_READ_ACCESS_DATA *read_access_data) { int apdu_len = 0; /* total length of the apdu, return value */ - int len = 0; /* length of the data */ - BACNET_READ_ACCESS_DATA *rpm_object; /* current object */ - uint8_t apdu_temp[16]; /* temp for data before copy */ + int len = 0; /* length of the data */ + BACNET_READ_ACCESS_DATA *rpm_object; /* current object */ + uint8_t apdu_temp[16]; /* temp for data before copy */ BACNET_PROPERTY_REFERENCE *rpm_property; /* current property */ len = rpm_encode_apdu_init(&apdu_temp[0], invoke_id); len = (int)memcopy(&apdu[0], &apdu_temp[0], (size_t)apdu_len, (size_t)len, - (size_t)max_apdu); + (size_t)max_apdu); if (len == 0) { return 0; } apdu_len += len; rpm_object = read_access_data; while (rpm_object) { - len = - encode_context_object_id(&apdu_temp[0], 0, rpm_object->object_type, - rpm_object->object_instance); + len = encode_context_object_id(&apdu_temp[0], 0, + rpm_object->object_type, rpm_object->object_instance); len = (int)memcopy(&apdu[0], &apdu_temp[0], (size_t)apdu_len, - (size_t)len, (size_t)max_apdu); + (size_t)len, (size_t)max_apdu); if (len == 0) { return 0; } @@ -140,7 +141,7 @@ int rpm_encode_apdu(uint8_t *apdu, size_t max_apdu, uint8_t invoke_id, /* Tag 1: sequence of ReadAccessSpecification */ len = encode_opening_tag(&apdu_temp[0], 1); len = (int)memcopy(&apdu[0], &apdu_temp[0], (size_t)apdu_len, - (size_t)len, (size_t)max_apdu); + (size_t)len, (size_t)max_apdu); if (len == 0) { return 0; } @@ -148,20 +149,20 @@ int rpm_encode_apdu(uint8_t *apdu, size_t max_apdu, uint8_t invoke_id, rpm_property = rpm_object->listOfProperties; while (rpm_property) { /* stuff as many properties into it as APDU length will allow */ - len = encode_context_enumerated(&apdu_temp[0], 0, - rpm_property->propertyIdentifier); + len = encode_context_enumerated( + &apdu_temp[0], 0, rpm_property->propertyIdentifier); len = (int)memcopy(&apdu[0], &apdu_temp[0], (size_t)apdu_len, - (size_t)len, (size_t)max_apdu); + (size_t)len, (size_t)max_apdu); if (len == 0) { return 0; } apdu_len += len; /* optional array index */ if (rpm_property->propertyArrayIndex != BACNET_ARRAY_ALL) { - len = encode_context_unsigned(&apdu_temp[0], 1, - rpm_property->propertyArrayIndex); + len = encode_context_unsigned( + &apdu_temp[0], 1, rpm_property->propertyArrayIndex); len = (int)memcopy(&apdu[0], &apdu_temp[0], (size_t)apdu_len, - (size_t)len, (size_t)max_apdu); + (size_t)len, (size_t)max_apdu); if (len == 0) { return 0; } @@ -171,7 +172,7 @@ int rpm_encode_apdu(uint8_t *apdu, size_t max_apdu, uint8_t invoke_id, } len = encode_closing_tag(&apdu_temp[0], 1); len = (int)memcopy(&apdu[0], &apdu_temp[0], (size_t)apdu_len, - (size_t)len, (size_t)max_apdu); + (size_t)len, (size_t)max_apdu); if (len == 0) { return 0; } @@ -187,8 +188,8 @@ int rpm_encode_apdu(uint8_t *apdu, size_t max_apdu, uint8_t invoke_id, /* decode the object portion of the service request only. Bails out if * tags are wrong or missing/incomplete */ -int rpm_decode_object_id(uint8_t *apdu, unsigned apdu_len, - BACNET_RPM_DATA *rpmdata) +int rpm_decode_object_id( + uint8_t *apdu, unsigned apdu_len, BACNET_RPM_DATA *rpmdata) { unsigned len = 0; uint16_t type = 0; /* for decoding */ @@ -222,8 +223,9 @@ int rpm_decode_object_end(uint8_t *apdu, unsigned apdu_len) int len = 0; /* total length of the apdu, return value */ if (apdu && apdu_len) { - if (decode_is_closing_tag_number(apdu, 1) == true) + if (decode_is_closing_tag_number(apdu, 1) == true) { len = 1; + } } return len; @@ -237,14 +239,14 @@ int rpm_decode_object_end(uint8_t *apdu, unsigned apdu_len) -- if omitted with an array the entire array is referenced } */ -int rpm_decode_object_property(uint8_t *apdu, unsigned apdu_len, - BACNET_RPM_DATA *rpmdata) +int rpm_decode_object_property( + uint8_t *apdu, unsigned apdu_len, BACNET_RPM_DATA *rpmdata) { unsigned len = 0; unsigned option_len = 0; uint8_t tag_number = 0; uint32_t len_value_type = 0; - uint32_t property = 0; /* for decoding */ + uint32_t property = 0; /* for decoding */ uint32_t array_value = 0; /* for decoding */ /* check for valid pointers */ @@ -255,8 +257,8 @@ int rpm_decode_object_property(uint8_t *apdu, unsigned apdu_len, return BACNET_STATUS_REJECT; } - len += decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value_type); + len += decode_tag_number_and_value( + &apdu[len], &tag_number, &len_value_type); if (tag_number != 0) { rpmdata->error_code = ERROR_CODE_REJECT_INVALID_TAG; return BACNET_STATUS_REJECT; @@ -298,7 +300,7 @@ int rpm_ack_encode_apdu_init(uint8_t *apdu, uint8_t invoke_id) if (apdu) { apdu[0] = PDU_TYPE_COMPLEX_ACK; /* complex ACK service */ - apdu[1] = invoke_id; /* original invoke id from request */ + apdu[1] = invoke_id; /* original invoke id from request */ apdu[2] = SERVICE_CONFIRMED_READ_PROP_MULTIPLE; /* service choice */ apdu_len = 3; } @@ -312,8 +314,8 @@ int rpm_ack_encode_apdu_object_begin(uint8_t *apdu, BACNET_RPM_DATA *rpmdata) if (apdu) { /* Tag 0: objectIdentifier */ - apdu_len = encode_context_object_id(&apdu[0], 0, rpmdata->object_type, - rpmdata->object_instance); + apdu_len = encode_context_object_id( + &apdu[0], 0, rpmdata->object_type, rpmdata->object_instance); /* Tag 1: listOfResults */ apdu_len += encode_opening_tag(&apdu[apdu_len], 1); } @@ -321,9 +323,8 @@ int rpm_ack_encode_apdu_object_begin(uint8_t *apdu, BACNET_RPM_DATA *rpmdata) return apdu_len; } -int rpm_ack_encode_apdu_object_property(uint8_t *apdu, - BACNET_PROPERTY_ID object_property, - uint32_t array_index) +int rpm_ack_encode_apdu_object_property( + uint8_t *apdu, BACNET_PROPERTY_ID object_property, uint32_t array_index) { int apdu_len = 0; /* total length of the apdu, return value */ @@ -331,17 +332,17 @@ int rpm_ack_encode_apdu_object_property(uint8_t *apdu, /* Tag 2: propertyIdentifier */ apdu_len = encode_context_enumerated(&apdu[0], 2, object_property); /* Tag 3: optional propertyArrayIndex */ - if (array_index != BACNET_ARRAY_ALL) + if (array_index != BACNET_ARRAY_ALL) { apdu_len += encode_context_unsigned(&apdu[apdu_len], 3, array_index); + } } return apdu_len; } -int rpm_ack_encode_apdu_object_property_value(uint8_t *apdu, - uint8_t *application_data, - unsigned application_data_len) +int rpm_ack_encode_apdu_object_property_value( + uint8_t *apdu, uint8_t *application_data, unsigned application_data_len) { int apdu_len = 0; /* total length of the apdu, return value */ unsigned len = 0; @@ -350,9 +351,9 @@ int rpm_ack_encode_apdu_object_property_value(uint8_t *apdu, /* Tag 4: propertyValue */ apdu_len += encode_opening_tag(&apdu[apdu_len], 4); if (application_data == - &apdu[apdu_len]) { /* Is Data already in place? */ + &apdu[apdu_len]) { /* Is Data already in place? */ apdu_len += application_data_len; /* Yes, step over data */ - } else { /* No, copy data in */ + } else { /* No, copy data in */ for (len = 0; len < application_data_len; len++) { apdu[apdu_len++] = application_data[len]; } @@ -363,9 +364,8 @@ int rpm_ack_encode_apdu_object_property_value(uint8_t *apdu, return apdu_len; } -int rpm_ack_encode_apdu_object_property_error(uint8_t *apdu, - BACNET_ERROR_CLASS error_class, - BACNET_ERROR_CODE error_code) +int rpm_ack_encode_apdu_object_property_error( + uint8_t *apdu, BACNET_ERROR_CLASS error_class, BACNET_ERROR_CODE error_code) { int apdu_len = 0; /* total length of the apdu, return value */ @@ -394,9 +394,10 @@ int rpm_ack_encode_apdu_object_end(uint8_t *apdu) #if BACNET_SVC_RPM_A /* decode the object portion of the service request only */ -int rpm_ack_decode_object_id(uint8_t *apdu, unsigned apdu_len, - BACNET_OBJECT_TYPE *object_type, - uint32_t *object_instance) +int rpm_ack_decode_object_id(uint8_t *apdu, + unsigned apdu_len, + BACNET_OBJECT_TYPE *object_type, + uint32_t *object_instance) { unsigned len = 0; uint16_t type = 0; /* for decoding */ @@ -404,14 +405,17 @@ int rpm_ack_decode_object_id(uint8_t *apdu, unsigned apdu_len, /* check for value pointers */ if (apdu && apdu_len && object_type && object_instance) { /* Tag 0: objectIdentifier */ - if (!decode_is_context_tag(&apdu[len++], 0)) + if (!decode_is_context_tag(&apdu[len++], 0)) { return -1; + } len += decode_object_id(&apdu[len], &type, object_instance); - if (object_type) + if (object_type) { *object_type = (BACNET_OBJECT_TYPE)type; + } /* Tag 1: listOfResults */ - if (!decode_is_opening_tag_number(&apdu[len], 1)) + if (!decode_is_opening_tag_number(&apdu[len], 1)) { return -1; + } len++; /* opening tag is only one octet */ } @@ -424,36 +428,41 @@ int rpm_ack_decode_object_end(uint8_t *apdu, unsigned apdu_len) int len = 0; /* total length of the apdu, return value */ if (apdu && apdu_len) { - if (decode_is_closing_tag_number(apdu, 1)) + if (decode_is_closing_tag_number(apdu, 1)) { len = 1; + } } return len; } -int rpm_ack_decode_object_property(uint8_t *apdu, unsigned apdu_len, - BACNET_PROPERTY_ID *object_property, - uint32_t *array_index) +int rpm_ack_decode_object_property(uint8_t *apdu, + unsigned apdu_len, + BACNET_PROPERTY_ID *object_property, + uint32_t *array_index) { unsigned len = 0; unsigned tag_len = 0; uint8_t tag_number = 0; uint32_t len_value_type = 0; - uint32_t property = 0; /* for decoding */ + uint32_t property = 0; /* for decoding */ uint32_t array_value = 0; /* for decoding */ /* check for valid pointers */ if (apdu && apdu_len && object_property && array_index) { /* Tag 2: propertyIdentifier */ - if (!IS_CONTEXT_SPECIFIC(apdu[len])) + if (!IS_CONTEXT_SPECIFIC(apdu[len])) { return -1; - len += decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value_type); - if (tag_number != 2) + } + len += decode_tag_number_and_value( + &apdu[len], &tag_number, &len_value_type); + if (tag_number != 2) { return -1; + } len += decode_enumerated(&apdu[len], len_value_type, &property); - if (object_property) + if (object_property) { *object_property = (BACNET_PROPERTY_ID)property; + } /* Tag 3: Optional propertyArrayIndex */ if ((len < apdu_len) && IS_CONTEXT_SPECIFIC(apdu[len]) && (!IS_CLOSING_TAG(apdu[len]))) { @@ -483,9 +492,10 @@ int rpm_ack_decode_object_property(uint8_t *apdu, unsigned apdu_len, #include "ctest.h" int rpm_ack_decode_apdu(uint8_t *apdu, - int apdu_len, /* total length of the apdu */ - uint8_t *invoke_id, uint8_t **service_request, - unsigned *service_request_len) + int apdu_len, /* total length of the apdu */ + uint8_t *invoke_id, + uint8_t **service_request, + unsigned *service_request_len) { int offset = 0; @@ -508,8 +518,11 @@ int rpm_ack_decode_apdu(uint8_t *apdu, return offset; } -int rpm_decode_apdu(uint8_t *apdu, unsigned apdu_len, uint8_t *invoke_id, - uint8_t **service_request, unsigned *service_request_len) +int rpm_decode_apdu(uint8_t *apdu, + unsigned apdu_len, + uint8_t *invoke_id, + uint8_t **service_request, + unsigned *service_request_len) { unsigned offset = 0; @@ -536,7 +549,7 @@ int rpm_decode_apdu(uint8_t *apdu, unsigned apdu_len, uint8_t *invoke_id, void testReadPropertyMultiple(Test *pTest) { - uint8_t apdu[480] = {0}; + uint8_t apdu[480] = { 0 }; int len = 0; int test_len = 0; int apdu_len = 0; @@ -573,14 +586,13 @@ void testReadPropertyMultiple(Test *pTest) rpm_encode_apdu_object_begin(&apdu[apdu_len], OBJECT_ANALOG_INPUT, 33); apdu_len += rpm_encode_apdu_object_property( &apdu[apdu_len], PROP_OBJECT_IDENTIFIER, BACNET_ARRAY_ALL); - apdu_len += rpm_encode_apdu_object_property(&apdu[apdu_len], PROP_ALL, - BACNET_ARRAY_ALL); + apdu_len += rpm_encode_apdu_object_property( + &apdu[apdu_len], PROP_ALL, BACNET_ARRAY_ALL); apdu_len += rpm_encode_apdu_object_end(&apdu[apdu_len]); ct_test(pTest, apdu_len != 0); - test_len = rpm_decode_apdu( - &apdu[0], apdu_len, &test_invoke_id, + test_len = rpm_decode_apdu(&apdu[0], apdu_len, &test_invoke_id, &service_request, /* will point to the service request in the apdu */ &service_request_len); ct_test(pTest, test_len != -1); @@ -595,21 +607,21 @@ void testReadPropertyMultiple(Test *pTest) ct_test(pTest, rpmdata.object_instance == 123); len = test_len; /* decode the object property portion of the service request */ - test_len = rpm_decode_object_property(&service_request[len], - service_request_len - len, &rpmdata); + test_len = rpm_decode_object_property( + &service_request[len], service_request_len - len, &rpmdata); ct_test(pTest, test_len > 0); ct_test(pTest, rpmdata.object_property == PROP_OBJECT_IDENTIFIER); ct_test(pTest, rpmdata.array_index == BACNET_ARRAY_ALL); len += test_len; - test_len = rpm_decode_object_property(&service_request[len], - service_request_len - len, &rpmdata); + test_len = rpm_decode_object_property( + &service_request[len], service_request_len - len, &rpmdata); ct_test(pTest, test_len > 0); ct_test(pTest, rpmdata.object_property == PROP_OBJECT_NAME); ct_test(pTest, rpmdata.array_index == BACNET_ARRAY_ALL); len += test_len; /* try again - we should fail */ - test_len = rpm_decode_object_property(&service_request[len], - service_request_len - len, &rpmdata); + test_len = rpm_decode_object_property( + &service_request[len], service_request_len - len, &rpmdata); ct_test(pTest, test_len < 0); /* is it the end of this object? */ test_len = @@ -617,27 +629,27 @@ void testReadPropertyMultiple(Test *pTest) ct_test(pTest, test_len == 1); len += test_len; /* try to decode an object id */ - test_len = rpm_decode_object_id(&service_request[len], - service_request_len - len, &rpmdata); + test_len = rpm_decode_object_id( + &service_request[len], service_request_len - len, &rpmdata); ct_test(pTest, test_len > 0); ct_test(pTest, rpmdata.object_type == OBJECT_ANALOG_INPUT); ct_test(pTest, rpmdata.object_instance == 33); len += test_len; /* decode the object property portion of the service request only */ - test_len = rpm_decode_object_property(&service_request[len], - service_request_len - len, &rpmdata); + test_len = rpm_decode_object_property( + &service_request[len], service_request_len - len, &rpmdata); ct_test(pTest, test_len > 0); ct_test(pTest, rpmdata.object_property == PROP_OBJECT_IDENTIFIER); ct_test(pTest, rpmdata.array_index == BACNET_ARRAY_ALL); len += test_len; - test_len = rpm_decode_object_property(&service_request[len], - service_request_len - len, &rpmdata); + test_len = rpm_decode_object_property( + &service_request[len], service_request_len - len, &rpmdata); ct_test(pTest, test_len > 0); ct_test(pTest, rpmdata.object_property == PROP_ALL); ct_test(pTest, rpmdata.array_index == BACNET_ARRAY_ALL); len += test_len; - test_len = rpm_decode_object_property(&service_request[len], - service_request_len - len, &rpmdata); + test_len = rpm_decode_object_property( + &service_request[len], service_request_len - len, &rpmdata); ct_test(pTest, test_len < 0); /* got an error -1, is it the end of this object? */ test_len = @@ -649,7 +661,7 @@ void testReadPropertyMultiple(Test *pTest) void testReadPropertyMultipleAck(Test *pTest) { - uint8_t apdu[480] = {0}; + uint8_t apdu[480] = { 0 }; int len = 0; int test_len = 0; int apdu_len = 0; @@ -661,9 +673,9 @@ void testReadPropertyMultipleAck(Test *pTest) uint32_t object_instance = 0; BACNET_PROPERTY_ID object_property = PROP_OBJECT_IDENTIFIER; uint32_t array_index = 0; - BACNET_APPLICATION_DATA_VALUE application_data[4] = {{0}}; - BACNET_APPLICATION_DATA_VALUE test_application_data = {0}; - uint8_t application_data_buffer[MAX_APDU] = {0}; + BACNET_APPLICATION_DATA_VALUE application_data[4] = { { 0 } }; + BACNET_APPLICATION_DATA_VALUE test_application_data = { 0 }; + uint8_t application_data_buffer[MAX_APDU] = { 0 }; int application_data_buffer_len = 0; BACNET_ERROR_CLASS error_class; BACNET_ERROR_CODE error_code; @@ -692,9 +704,8 @@ void testReadPropertyMultipleAck(Test *pTest) application_data[0].type.Object_Id.instance = 123; application_data_buffer_len = bacapp_encode_application_data( &application_data_buffer[0], &application_data[0]); - apdu_len += rpm_ack_encode_apdu_object_property_value( - &apdu[apdu_len], &application_data_buffer[0], - application_data_buffer_len); + apdu_len += rpm_ack_encode_apdu_object_property_value(&apdu[apdu_len], + &application_data_buffer[0], application_data_buffer_len); /* reply property */ apdu_len += rpm_ack_encode_apdu_object_property( &apdu[apdu_len], PROP_OBJECT_TYPE, BACNET_ARRAY_ALL); @@ -703,9 +714,8 @@ void testReadPropertyMultipleAck(Test *pTest) application_data[1].type.Enumerated = OBJECT_DEVICE; application_data_buffer_len = bacapp_encode_application_data( &application_data_buffer[0], &application_data[1]); - apdu_len += rpm_ack_encode_apdu_object_property_value( - &apdu[apdu_len], &application_data_buffer[0], - application_data_buffer_len); + apdu_len += rpm_ack_encode_apdu_object_property_value(&apdu[apdu_len], + &application_data_buffer[0], application_data_buffer_len); /* object end */ apdu_len += rpm_ack_encode_apdu_object_end(&apdu[apdu_len]); @@ -721,9 +731,8 @@ void testReadPropertyMultipleAck(Test *pTest) application_data[2].type.Real = 0.0; application_data_buffer_len = bacapp_encode_application_data( &application_data_buffer[0], &application_data[2]); - apdu_len += rpm_ack_encode_apdu_object_property_value( - &apdu[apdu_len], &application_data_buffer[0], - application_data_buffer_len); + apdu_len += rpm_ack_encode_apdu_object_property_value(&apdu[apdu_len], + &application_data_buffer[0], application_data_buffer_len); /* reply property */ apdu_len += rpm_ack_encode_apdu_object_property( &apdu[apdu_len], PROP_DEADBAND, BACNET_ARRAY_ALL); @@ -735,8 +744,7 @@ void testReadPropertyMultipleAck(Test *pTest) ct_test(pTest, apdu_len != 0); /****** decode the packet ******/ - test_len = rpm_ack_decode_apdu( - &apdu[0], apdu_len, &test_invoke_id, + test_len = rpm_ack_decode_apdu(&apdu[0], apdu_len, &test_invoke_id, &service_request, /* will point to the service request in the apdu */ &service_request_len); ct_test(pTest, test_len != -1); @@ -744,16 +752,15 @@ void testReadPropertyMultipleAck(Test *pTest) ct_test(pTest, service_request != NULL); ct_test(pTest, service_request_len > 0); /* the first part should be the first object id */ - test_len = rpm_ack_decode_object_id(service_request, service_request_len, - &object_type, &object_instance); + test_len = rpm_ack_decode_object_id( + service_request, service_request_len, &object_type, &object_instance); ct_test(pTest, test_len != -1); ct_test(pTest, object_type == OBJECT_DEVICE); ct_test(pTest, object_instance == 123); len = test_len; /* extract the property */ test_len = rpm_ack_decode_object_property(&service_request[len], - service_request_len - len, - &object_property, &array_index); + service_request_len - len, &object_property, &array_index); ct_test(pTest, object_property == PROP_OBJECT_IDENTIFIER); ct_test(pTest, array_index == BACNET_ARRAY_ALL); len += test_len; @@ -764,18 +771,16 @@ void testReadPropertyMultipleAck(Test *pTest) /* note: if this was an array, there could have been more than one element to decode */ test_len = bacapp_decode_application_data(&service_request[len], - service_request_len - len, - &test_application_data); + service_request_len - len, &test_application_data); ct_test(pTest, test_len > 0); - ct_test(pTest, - bacapp_same_value(&application_data[0], &test_application_data)); + ct_test( + pTest, bacapp_same_value(&application_data[0], &test_application_data)); len += test_len; ct_test(pTest, decode_is_closing_tag_number(&service_request[len], 4)); len++; /* see if there is another property */ test_len = rpm_ack_decode_object_property(&service_request[len], - service_request_len - len, - &object_property, &array_index); + service_request_len - len, &object_property, &array_index); ct_test(pTest, test_len != -1); ct_test(pTest, object_property == PROP_OBJECT_TYPE); ct_test(pTest, array_index == BACNET_ARRAY_ALL); @@ -785,37 +790,33 @@ void testReadPropertyMultipleAck(Test *pTest) len++; /* decode the object property portion of the service request */ test_len = bacapp_decode_application_data(&service_request[len], - service_request_len - len, - &test_application_data); + service_request_len - len, &test_application_data); ct_test(pTest, test_len > 0); - ct_test(pTest, - bacapp_same_value(&application_data[1], &test_application_data)); + ct_test( + pTest, bacapp_same_value(&application_data[1], &test_application_data)); len += test_len; ct_test(pTest, decode_is_closing_tag_number(&service_request[len], 4)); len++; /* see if there is another property */ /* this time we should fail */ test_len = rpm_ack_decode_object_property(&service_request[len], - service_request_len - len, - &object_property, &array_index); + service_request_len - len, &object_property, &array_index); ct_test(pTest, test_len == -1); /* see if it is the end of this object */ - test_len = rpm_ack_decode_object_end(&service_request[len], - service_request_len - len); + test_len = rpm_ack_decode_object_end( + &service_request[len], service_request_len - len); ct_test(pTest, test_len == 1); len += test_len; /* try to decode another object id */ test_len = rpm_ack_decode_object_id(&service_request[len], - service_request_len - len, &object_type, - &object_instance); + service_request_len - len, &object_type, &object_instance); ct_test(pTest, test_len != -1); ct_test(pTest, object_type == OBJECT_ANALOG_INPUT); ct_test(pTest, object_instance == 33); len += test_len; /* decode the object property portion of the service request only */ test_len = rpm_ack_decode_object_property(&service_request[len], - service_request_len - len, - &object_property, &array_index); + service_request_len - len, &object_property, &array_index); ct_test(pTest, test_len != -1); ct_test(pTest, object_property == PROP_PRESENT_VALUE); ct_test(pTest, array_index == BACNET_ARRAY_ALL); @@ -825,18 +826,16 @@ void testReadPropertyMultipleAck(Test *pTest) len++; /* decode the object property portion of the service request */ test_len = bacapp_decode_application_data(&service_request[len], - service_request_len - len, - &test_application_data); + service_request_len - len, &test_application_data); ct_test(pTest, test_len > 0); - ct_test(pTest, - bacapp_same_value(&application_data[2], &test_application_data)); + ct_test( + pTest, bacapp_same_value(&application_data[2], &test_application_data)); len += test_len; ct_test(pTest, decode_is_closing_tag_number(&service_request[len], 4)); len++; /* see if there is another property */ test_len = rpm_ack_decode_object_property(&service_request[len], - service_request_len - len, - &object_property, &array_index); + service_request_len - len, &object_property, &array_index); ct_test(pTest, test_len != -1); ct_test(pTest, object_property == PROP_DEADBAND); ct_test(pTest, array_index == BACNET_ARRAY_ALL); @@ -846,8 +845,7 @@ void testReadPropertyMultipleAck(Test *pTest) len++; /* it was an error reply */ test_len = bacerror_decode_error_class_and_code(&service_request[len], - service_request_len - len, - &error_class, &error_code); + service_request_len - len, &error_class, &error_code); ct_test(pTest, test_len != 0); ct_test(pTest, error_class == ERROR_CLASS_PROPERTY); ct_test(pTest, error_code == ERROR_CODE_UNKNOWN_PROPERTY); @@ -856,18 +854,16 @@ void testReadPropertyMultipleAck(Test *pTest) len++; /* is there another property? */ test_len = rpm_ack_decode_object_property(&service_request[len], - service_request_len - len, - &object_property, &array_index); + service_request_len - len, &object_property, &array_index); ct_test(pTest, test_len == -1); /* got an error -1, is it the end of this object? */ - test_len = rpm_ack_decode_object_end(&service_request[len], - service_request_len - len); + test_len = rpm_ack_decode_object_end( + &service_request[len], service_request_len - len); ct_test(pTest, test_len == 1); len += test_len; /* check for another object */ test_len = rpm_ack_decode_object_id(&service_request[len], - service_request_len - len, &object_type, - &object_instance); + service_request_len - len, &object_type, &object_instance); ct_test(pTest, test_len == 0); ct_test(pTest, len == service_request_len); } diff --git a/include/rpm.h b/src/bacnet/rpm.h similarity index 98% rename from include/rpm.h rename to src/bacnet/rpm.h index 6b09bf7b..11450b40 100644 --- a/include/rpm.h +++ b/src/bacnet/rpm.h @@ -26,10 +26,10 @@ #include #include -#include "bacenum.h" -#include "bacdef.h" -#include "bacapp.h" -#include "proplist.h" +#include "bacnet/bacenum.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacapp.h" +#include "bacnet/proplist.h" /* * Bundle together commonly used data items for convenience when calling * rpm helper functions. diff --git a/src/timestamp.c b/src/bacnet/timestamp.c similarity index 73% rename from src/timestamp.c rename to src/bacnet/timestamp.c index c601632b..8fb537ed 100644 --- a/src/timestamp.c +++ b/src/bacnet/timestamp.c @@ -31,9 +31,9 @@ License. ------------------------------------------- ####COPYRIGHTEND####*/ - -#include "assert.h" -#include "timestamp.h" +#include +#include +#include "bacnet/timestamp.h" /** @file timestamp.c Encode/Decode BACnet Timestamps */ @@ -53,8 +53,8 @@ void bacapp_timestamp_time_set(BACNET_TIMESTAMP *dest, BACNET_TIME *btime) } } -void bacapp_timestamp_datetime_set(BACNET_TIMESTAMP *dest, - BACNET_DATE_TIME *bdateTime) +void bacapp_timestamp_datetime_set( + BACNET_TIMESTAMP *dest, BACNET_DATE_TIME *bdateTime) { if (dest && bdateTime) { dest->tag = TIME_STAMP_DATETIME; @@ -93,13 +93,13 @@ int bacapp_encode_timestamp(uint8_t *apdu, BACNET_TIMESTAMP *value) break; case TIME_STAMP_SEQUENCE: - len = encode_context_unsigned(&apdu[0], 1, - value->value.sequenceNum); + len = encode_context_unsigned( + &apdu[0], 1, value->value.sequenceNum); break; case TIME_STAMP_DATETIME: - len = bacapp_encode_context_datetime(&apdu[0], 2, - &value->value.dateTime); + len = bacapp_encode_context_datetime( + &apdu[0], 2, &value->value.dateTime); break; default: @@ -112,8 +112,8 @@ int bacapp_encode_timestamp(uint8_t *apdu, BACNET_TIMESTAMP *value) return len; } -int bacapp_encode_context_timestamp(uint8_t *apdu, uint8_t tag_number, - BACNET_TIMESTAMP *value) +int bacapp_encode_context_timestamp( + uint8_t *apdu, uint8_t tag_number, BACNET_TIMESTAMP *value) { int len = 0; /* length of each encoding */ int apdu_len = 0; @@ -137,17 +137,16 @@ int bacapp_decode_timestamp(uint8_t *apdu, BACNET_TIMESTAMP *value) uint32_t sequenceNum; if (apdu) { - section_len = decode_tag_number_and_value(&apdu[len], &value->tag, - &len_value_type); + section_len = decode_tag_number_and_value( + &apdu[len], &value->tag, &len_value_type); if (-1 == section_len) { return -1; } switch (value->tag) { case TIME_STAMP_TIME: - if ((section_len = decode_context_bacnet_time( - &apdu[len], TIME_STAMP_TIME, &value->value.time)) == - -1) { + if ((section_len = decode_context_bacnet_time(&apdu[len], + TIME_STAMP_TIME, &value->value.time)) == -1) { return -1; } else { len += section_len; @@ -155,9 +154,8 @@ int bacapp_decode_timestamp(uint8_t *apdu, BACNET_TIMESTAMP *value) break; case TIME_STAMP_SEQUENCE: - if ((section_len = decode_context_unsigned( - &apdu[len], TIME_STAMP_SEQUENCE, &sequenceNum)) == - -1) { + if ((section_len = decode_context_unsigned(&apdu[len], + TIME_STAMP_SEQUENCE, &sequenceNum)) == -1) { return -1; } else { if (sequenceNum <= 0xffff) { @@ -170,9 +168,8 @@ int bacapp_decode_timestamp(uint8_t *apdu, BACNET_TIMESTAMP *value) break; case TIME_STAMP_DATETIME: - if ((section_len = bacapp_decode_context_datetime( - &apdu[len], TIME_STAMP_DATETIME, - &value->value.dateTime)) == -1) { + if ((section_len = bacapp_decode_context_datetime(&apdu[len], + TIME_STAMP_DATETIME, &value->value.dateTime)) == -1) { return -1; } else { len += section_len; @@ -187,8 +184,8 @@ int bacapp_decode_timestamp(uint8_t *apdu, BACNET_TIMESTAMP *value) return len; } -int bacapp_decode_context_timestamp(uint8_t *apdu, uint8_t tag_number, - BACNET_TIMESTAMP *value) +int bacapp_decode_context_timestamp( + uint8_t *apdu, uint8_t tag_number, BACNET_TIMESTAMP *value) { int len = 0; int section_len; @@ -232,8 +229,9 @@ void testTimestampSequence(Test *pTest) ct_test(pTest, inLen == outLen); ct_test(pTest, testTimestampIn.tag == testTimestampOut.tag); - ct_test(pTest, testTimestampIn.value.sequenceNum == - testTimestampOut.value.sequenceNum); + ct_test(pTest, + testTimestampIn.value.sequenceNum == + testTimestampOut.value.sequenceNum); } void testTimestampTime(Test *pTest) @@ -257,14 +255,15 @@ void testTimestampTime(Test *pTest) ct_test(pTest, inLen == outLen); ct_test(pTest, testTimestampIn.tag == testTimestampOut.tag); - ct_test(pTest, testTimestampIn.value.time.hour == - testTimestampOut.value.time.hour); ct_test(pTest, - testTimestampIn.value.time.min == testTimestampOut.value.time.min); + testTimestampIn.value.time.hour == testTimestampOut.value.time.hour); ct_test(pTest, - testTimestampIn.value.time.sec == testTimestampOut.value.time.sec); - ct_test(pTest, testTimestampIn.value.time.hundredths == - testTimestampOut.value.time.hundredths); + testTimestampIn.value.time.min == testTimestampOut.value.time.min); + ct_test(pTest, + testTimestampIn.value.time.sec == testTimestampOut.value.time.sec); + ct_test(pTest, + testTimestampIn.value.time.hundredths == + testTimestampOut.value.time.hundredths); } void testTimestampTimeDate(Test *pTest) @@ -293,23 +292,31 @@ void testTimestampTimeDate(Test *pTest) ct_test(pTest, inLen == outLen); ct_test(pTest, testTimestampIn.tag == testTimestampOut.tag); - ct_test(pTest, testTimestampIn.value.dateTime.time.hour == - testTimestampOut.value.dateTime.time.hour); - ct_test(pTest, testTimestampIn.value.dateTime.time.min == - testTimestampOut.value.dateTime.time.min); - ct_test(pTest, testTimestampIn.value.dateTime.time.sec == - testTimestampOut.value.dateTime.time.sec); - ct_test(pTest, testTimestampIn.value.dateTime.time.hundredths == - testTimestampOut.value.dateTime.time.hundredths); + ct_test(pTest, + testTimestampIn.value.dateTime.time.hour == + testTimestampOut.value.dateTime.time.hour); + ct_test(pTest, + testTimestampIn.value.dateTime.time.min == + testTimestampOut.value.dateTime.time.min); + ct_test(pTest, + testTimestampIn.value.dateTime.time.sec == + testTimestampOut.value.dateTime.time.sec); + ct_test(pTest, + testTimestampIn.value.dateTime.time.hundredths == + testTimestampOut.value.dateTime.time.hundredths); - ct_test(pTest, testTimestampIn.value.dateTime.date.year == - testTimestampOut.value.dateTime.date.year); - ct_test(pTest, testTimestampIn.value.dateTime.date.month == - testTimestampOut.value.dateTime.date.month); - ct_test(pTest, testTimestampIn.value.dateTime.date.wday == - testTimestampOut.value.dateTime.date.wday); - ct_test(pTest, testTimestampIn.value.dateTime.date.day == - testTimestampOut.value.dateTime.date.day); + ct_test(pTest, + testTimestampIn.value.dateTime.date.year == + testTimestampOut.value.dateTime.date.year); + ct_test(pTest, + testTimestampIn.value.dateTime.date.month == + testTimestampOut.value.dateTime.date.month); + ct_test(pTest, + testTimestampIn.value.dateTime.date.wday == + testTimestampOut.value.dateTime.date.wday); + ct_test(pTest, + testTimestampIn.value.dateTime.date.day == + testTimestampOut.value.dateTime.date.day); } #ifdef TEST_TIME_STAMP diff --git a/include/timestamp.h b/src/bacnet/timestamp.h similarity index 97% rename from include/timestamp.h rename to src/bacnet/timestamp.h index 66cca531..5b8ffc20 100644 --- a/include/timestamp.h +++ b/src/bacnet/timestamp.h @@ -23,8 +23,9 @@ *********************************************************************/ #ifndef _TIMESTAMP_H_ #define _TIMESTAMP_H_ - -#include "bacdcode.h" +#include +#include "bacnet/bacenum.h" +#include "bacnet/bacdcode.h" typedef enum { TIME_STAMP_TIME = 0, diff --git a/src/timesync.c b/src/bacnet/timesync.c similarity index 71% rename from src/timesync.c rename to src/bacnet/timesync.c index 59a8f42e..faedbb86 100644 --- a/src/timesync.c +++ b/src/bacnet/timesync.c @@ -32,20 +32,21 @@ ------------------------------------------- ####COPYRIGHTEND####*/ #include -#include "bacenum.h" -#include "bacdcode.h" -#include "bacdef.h" -#include "bacapp.h" -#include "timesync.h" +#include "bacnet/bacenum.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacdef.h" +#include "bacnet/bacapp.h" +#include "bacnet/timesync.h" /** @file timesync.c Encode/Decode TimeSync APDUs */ #if BACNET_SVC_TS_A /* encode service */ int timesync_encode_apdu_service(uint8_t *apdu, - BACNET_UNCONFIRMED_SERVICE service, - BACNET_DATE *my_date, BACNET_TIME *my_time) + BACNET_UNCONFIRMED_SERVICE service, + BACNET_DATE *my_date, + BACNET_TIME *my_time) { - int len = 0; /* length of each encoding */ + int len = 0; /* length of each encoding */ int apdu_len = 0; /* total length of the apdu, return value */ if (apdu && my_date && my_time) { @@ -61,15 +62,15 @@ int timesync_encode_apdu_service(uint8_t *apdu, return apdu_len; } -int timesync_utc_encode_apdu(uint8_t *apdu, BACNET_DATE *my_date, - BACNET_TIME *my_time) +int timesync_utc_encode_apdu( + uint8_t *apdu, BACNET_DATE *my_date, BACNET_TIME *my_time) { return timesync_encode_apdu_service( apdu, SERVICE_UNCONFIRMED_UTC_TIME_SYNCHRONIZATION, my_date, my_time); } -int timesync_encode_apdu(uint8_t *apdu, BACNET_DATE *my_date, - BACNET_TIME *my_time) +int timesync_encode_apdu( + uint8_t *apdu, BACNET_DATE *my_date, BACNET_TIME *my_time) { return timesync_encode_apdu_service( apdu, SERVICE_UNCONFIRMED_TIME_SYNCHRONIZATION, my_date, my_time); @@ -77,8 +78,10 @@ int timesync_encode_apdu(uint8_t *apdu, BACNET_DATE *my_date, #endif /* decode the service request only */ -int timesync_decode_service_request(uint8_t *apdu, unsigned apdu_len, - BACNET_DATE *my_date, BACNET_TIME *my_time) +int timesync_decode_service_request(uint8_t *apdu, + unsigned apdu_len, + BACNET_DATE *my_date, + BACNET_TIME *my_time) { int len = 0; uint8_t tag_number = 0; @@ -89,14 +92,16 @@ int timesync_decode_service_request(uint8_t *apdu, unsigned apdu_len, len += decode_tag_number_and_value(&apdu[len], &tag_number, &len_value); if (tag_number == BACNET_APPLICATION_TAG_DATE) { len += decode_date(&apdu[len], my_date); - } else + } else { return -1; + } /* time */ len += decode_tag_number_and_value(&apdu[len], &tag_number, &len_value); if (tag_number == BACNET_APPLICATION_TAG_TIME) { len += decode_bacnet_time(&apdu[len], my_time); - } else + } else { return -1; + } } return len; @@ -126,8 +131,8 @@ int timesync_decode_service_request(uint8_t *apdu, unsigned apdu_len, * @return How many bytes were encoded in the buffer, or * BACNET_STATUS_ABORT if the response would not fit within the buffer. */ -int timesync_encode_timesync_recipients(uint8_t *apdu, unsigned max_apdu, - BACNET_RECIPIENT_LIST *recipient) +int timesync_encode_timesync_recipients( + uint8_t *apdu, unsigned max_apdu, BACNET_RECIPIENT_LIST *recipient) { int len = 0; int apdu_len = 0; @@ -139,8 +144,8 @@ int timesync_encode_timesync_recipients(uint8_t *apdu, unsigned max_apdu, if (pRecipient->tag == 0) { if (max_apdu >= (1 + 4)) { /* CHOICE - device [0] BACnetObjectIdentifier */ - len = encode_context_object_id( - &apdu[apdu_len], 0, (int)pRecipient->type.device.type, + len = encode_context_object_id(&apdu[apdu_len], 0, + (int)pRecipient->type.device.type, pRecipient->type.device.instance); apdu_len += len; } else { @@ -158,8 +163,8 @@ int timesync_encode_timesync_recipients(uint8_t *apdu, unsigned max_apdu, apdu_len += len; /* network-number Unsigned16, */ /* -- A value of 0 indicates the local network */ - len = encode_application_unsigned(&apdu[apdu_len], - pRecipient->type.address.net); + len = encode_application_unsigned( + &apdu[apdu_len], pRecipient->type.address.net); apdu_len += len; /* mac-address OCTET STRING */ /* -- A string of length 0 indicates a broadcast */ @@ -167,15 +172,15 @@ int timesync_encode_timesync_recipients(uint8_t *apdu, unsigned max_apdu, octetstring_init(&octet_string, NULL, 0); } else if (pRecipient->type.address.net) { octetstring_init(&octet_string, - &pRecipient->type.address.adr[0], - pRecipient->type.address.len); + &pRecipient->type.address.adr[0], + pRecipient->type.address.len); } else { octetstring_init(&octet_string, - &pRecipient->type.address.mac[0], - pRecipient->type.address.mac_len); + &pRecipient->type.address.mac[0], + pRecipient->type.address.mac_len); } - len = encode_application_octet_string(&apdu[apdu_len], - &octet_string); + len = encode_application_octet_string( + &apdu[apdu_len], &octet_string); apdu_len += len; /* CHOICE - address [1] BACnetAddress - closing */ len = encode_closing_tag(&apdu[apdu_len], 1); @@ -214,8 +219,8 @@ int timesync_encode_timesync_recipients(uint8_t *apdu, unsigned max_apdu, * @return How many bytes were decoded from the buffer, or * BACNET_STATUS_ABORT if there was a problem decoding the buffer */ -int timesync_decode_timesync_recipients(uint8_t *apdu, unsigned max_apdu, - BACNET_RECIPIENT_LIST *recipient) +int timesync_decode_timesync_recipients( + uint8_t *apdu, unsigned max_apdu, BACNET_RECIPIENT_LIST *recipient) { int len = 0; int apdu_len = 0; @@ -232,8 +237,8 @@ int timesync_decode_timesync_recipients(uint8_t *apdu, unsigned max_apdu, if (decode_is_context_tag(&apdu[apdu_len], 0)) { pRecipient->tag = 0; len = decode_context_object_id(&apdu[apdu_len], 0, - &pRecipient->type.device.type, - &pRecipient->type.device.instance); + &pRecipient->type.device.type, + &pRecipient->type.device.instance); if (len < 0) { return BACNET_STATUS_ABORT; } @@ -242,19 +247,19 @@ int timesync_decode_timesync_recipients(uint8_t *apdu, unsigned max_apdu, apdu_len += 1; pRecipient->tag = 1; /* network-number Unsigned16 */ - tag_len = decode_tag_number_and_value(&apdu[apdu_len], &tag_number, - &len_value_type); + tag_len = decode_tag_number_and_value( + &apdu[apdu_len], &tag_number, &len_value_type); apdu_len += tag_len; if (tag_number != BACNET_APPLICATION_TAG_UNSIGNED_INT) { return BACNET_STATUS_ABORT; } - len = decode_unsigned(&apdu[apdu_len], len_value_type, - &unsigned_value); + len = decode_unsigned( + &apdu[apdu_len], len_value_type, &unsigned_value); pRecipient->type.address.net = unsigned_value; apdu_len += len; /* mac-address OCTET STRING */ - tag_len = decode_tag_number_and_value(&apdu[apdu_len], &tag_number, - &len_value_type); + tag_len = decode_tag_number_and_value( + &apdu[apdu_len], &tag_number, &len_value_type); apdu_len += tag_len; if (tag_number != BACNET_APPLICATION_TAG_OCTET_STRING) { return BACNET_STATUS_ABORT; @@ -264,13 +269,13 @@ int timesync_decode_timesync_recipients(uint8_t *apdu, unsigned max_apdu, if (octetstring_length(&octet_string) == 0) { /* -- A string of length 0 indicates a broadcast */ } else if (pRecipient->type.address.net) { - pRecipient->type.address.len = octetstring_copy_value( - &pRecipient->type.address.adr[0], - sizeof(pRecipient->type.address.adr), &octet_string); + pRecipient->type.address.len = + octetstring_copy_value(&pRecipient->type.address.adr[0], + sizeof(pRecipient->type.address.adr), &octet_string); } else { - pRecipient->type.address.mac_len = octetstring_copy_value( - &pRecipient->type.address.mac[0], - sizeof(pRecipient->type.address.mac), &octet_string); + pRecipient->type.address.mac_len = + octetstring_copy_value(&pRecipient->type.address.mac[0], + sizeof(pRecipient->type.address.mac), &octet_string); } } else { return BACNET_STATUS_ABORT; @@ -286,37 +291,44 @@ int timesync_decode_timesync_recipients(uint8_t *apdu, unsigned max_apdu, #include #include "ctest.h" -void testTimeSyncRecipientData(Test *pTest, BACNET_RECIPIENT_LIST *recipient1, - BACNET_RECIPIENT_LIST *recipient2) +void testTimeSyncRecipientData(Test *pTest, + BACNET_RECIPIENT_LIST *recipient1, + BACNET_RECIPIENT_LIST *recipient2) { unsigned i = 0; if (recipient1 && recipient2) { ct_test(pTest, recipient1->tag == recipient2->tag); if (recipient1->tag == 0) { - ct_test(pTest, recipient1->type.device.type == - recipient2->type.device.type); - ct_test(pTest, recipient1->type.device.instance == - recipient2->type.device.instance); + ct_test(pTest, + recipient1->type.device.type == recipient2->type.device.type); + ct_test(pTest, + recipient1->type.device.instance == + recipient2->type.device.instance); } else if (recipient1->tag == 1) { - ct_test(pTest, recipient1->type.address.net == - recipient2->type.address.net); + ct_test(pTest, + recipient1->type.address.net == recipient2->type.address.net); if (recipient1->type.address.net == BACNET_BROADCAST_NETWORK) { - ct_test(pTest, recipient1->type.address.mac_len == - recipient2->type.address.mac_len); + ct_test(pTest, + recipient1->type.address.mac_len == + recipient2->type.address.mac_len); } else if (recipient1->type.address.net) { - ct_test(pTest, recipient1->type.address.len == - recipient2->type.address.len); + ct_test(pTest, + recipient1->type.address.len == + recipient2->type.address.len); for (i = 0; i < recipient1->type.address.len; i++) { - ct_test(pTest, recipient1->type.address.adr[i] == - recipient2->type.address.adr[i]); + ct_test(pTest, + recipient1->type.address.adr[i] == + recipient2->type.address.adr[i]); } } else { - ct_test(pTest, recipient1->type.address.mac_len == - recipient2->type.address.mac_len); + ct_test(pTest, + recipient1->type.address.mac_len == + recipient2->type.address.mac_len); for (i = 0; i < recipient1->type.address.mac_len; i++) { - ct_test(pTest, recipient1->type.address.mac[i] == - recipient2->type.address.mac[i]); + ct_test(pTest, + recipient1->type.address.mac[i] == + recipient2->type.address.mac[i]); } } } else { @@ -327,7 +339,7 @@ void testTimeSyncRecipientData(Test *pTest, BACNET_RECIPIENT_LIST *recipient1, void testTimeSyncRecipient(Test *pTest) { - uint8_t apdu[480] = {0}; + uint8_t apdu[480] = { 0 }; int len = 0; BACNET_RECIPIENT_LIST recipient[4]; BACNET_RECIPIENT_LIST test_recipient[4]; @@ -366,21 +378,22 @@ void testTimeSyncRecipient(Test *pTest) recipient[2].type.address.mac[5] = 0xC1; recipient[2].type.address.mac_len = 6; /* perform positive test */ - len = timesync_encode_timesync_recipients(&apdu[0], sizeof(apdu), - &recipient[0]); + len = timesync_encode_timesync_recipients( + &apdu[0], sizeof(apdu), &recipient[0]); ct_test(pTest, len != BACNET_STATUS_ABORT); ct_test(pTest, len > 0); - len = timesync_decode_timesync_recipients(&apdu[0], sizeof(apdu), - &test_recipient[0]); + len = timesync_decode_timesync_recipients( + &apdu[0], sizeof(apdu), &test_recipient[0]); ct_test(pTest, len != BACNET_STATUS_ABORT); ct_test(pTest, len > 0); testTimeSyncRecipientData(pTest, &recipient[0], &test_recipient[0]); } int timesync_decode_apdu_service(uint8_t *apdu, - BACNET_UNCONFIRMED_SERVICE service, - unsigned apdu_len, BACNET_DATE *my_date, - BACNET_TIME *my_time) + BACNET_UNCONFIRMED_SERVICE service, + unsigned apdu_len, + BACNET_DATE *my_date, + BACNET_TIME *my_time) { int len = 0; @@ -393,32 +406,35 @@ int timesync_decode_apdu_service(uint8_t *apdu, return -1; /* optional limits - must be used as a pair */ if (apdu_len > 2) { - len = timesync_decode_service_request(&apdu[2], apdu_len - 2, my_date, - my_time); + len = timesync_decode_service_request( + &apdu[2], apdu_len - 2, my_date, my_time); } return len; } -int timesync_utc_decode_apdu(uint8_t *apdu, unsigned apdu_len, - BACNET_DATE *my_date, BACNET_TIME *my_time) +int timesync_utc_decode_apdu(uint8_t *apdu, + unsigned apdu_len, + BACNET_DATE *my_date, + BACNET_TIME *my_time) { - return timesync_decode_apdu_service( - apdu, SERVICE_UNCONFIRMED_UTC_TIME_SYNCHRONIZATION, apdu_len, my_date, + return timesync_decode_apdu_service(apdu, + SERVICE_UNCONFIRMED_UTC_TIME_SYNCHRONIZATION, apdu_len, my_date, my_time); } -int timesync_decode_apdu(uint8_t *apdu, unsigned apdu_len, BACNET_DATE *my_date, - BACNET_TIME *my_time) +int timesync_decode_apdu(uint8_t *apdu, + unsigned apdu_len, + BACNET_DATE *my_date, + BACNET_TIME *my_time) { - return timesync_decode_apdu_service( - apdu, SERVICE_UNCONFIRMED_TIME_SYNCHRONIZATION, apdu_len, my_date, - my_time); + return timesync_decode_apdu_service(apdu, + SERVICE_UNCONFIRMED_TIME_SYNCHRONIZATION, apdu_len, my_date, my_time); } void testTimeSyncData(Test *pTest, BACNET_DATE *my_date, BACNET_TIME *my_time) { - uint8_t apdu[480] = {0}; + uint8_t apdu[480] = { 0 }; int len = 0; int apdu_len = 0; BACNET_DATE test_date; @@ -447,9 +463,9 @@ void testTimeSync(Test *pTest) BACNET_TIME btime; bdate.year = 2006; /* AD */ - bdate.month = 4; /* 1=Jan */ - bdate.day = 11; /* 1..31 */ - bdate.wday = 1; /* 1=Monday */ + bdate.month = 4; /* 1=Jan */ + bdate.day = 11; /* 1..31 */ + bdate.wday = 1; /* 1=Monday */ btime.hour = 7; btime.min = 0; diff --git a/include/timesync.h b/src/bacnet/timesync.h similarity index 99% rename from include/timesync.h rename to src/bacnet/timesync.h index b3df1d43..86d76796 100644 --- a/include/timesync.h +++ b/src/bacnet/timesync.h @@ -26,7 +26,7 @@ #include #include -#include "bacdef.h" +#include "bacnet/bacdef.h" struct BACnet_Recipient_List; typedef struct BACnet_Recipient_List { diff --git a/include/version.h b/src/bacnet/version.h similarity index 93% rename from include/version.h rename to src/bacnet/version.h index a86d4a9f..a4ee3764 100644 --- a/include/version.h +++ b/src/bacnet/version.h @@ -29,11 +29,10 @@ #define BACNET_VERSION(x,y,z) (((x)<<16)+((y)<<8)+(z)) #endif -#define BACNET_VERSION_TEXT "0.9.1" -#define BACNET_VERSION_CODE BACNET_VERSION(0,9,1) +#define BACNET_VERSION_TEXT "0.99.1" +#define BACNET_VERSION_CODE BACNET_VERSION(0,99,1) #define BACNET_VERSION_MAJOR ((BACNET_VERSION_CODE>>16)&0xFF) #define BACNET_VERSION_MINOR ((BACNET_VERSION_CODE>>8)&0xFF) #define BACNET_VERSION_MAINTENANCE (BACNET_VERSION_CODE&0xFF) -extern char *BACnet_Version; #endif diff --git a/src/whohas.c b/src/bacnet/whohas.c similarity index 75% rename from src/whohas.c rename to src/bacnet/whohas.c index 3190fc95..b72ac50f 100644 --- a/src/whohas.c +++ b/src/bacnet/whohas.c @@ -32,10 +32,10 @@ ------------------------------------------- ####COPYRIGHTEND####*/ #include -#include "bacenum.h" -#include "bacdcode.h" -#include "bacdef.h" -#include "whohas.h" +#include "bacnet/bacenum.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacdef.h" +#include "bacnet/whohas.h" /** @file whohas.c Encode/Decode Who-Has requests */ @@ -43,7 +43,7 @@ int whohas_encode_apdu(uint8_t *apdu, BACNET_WHO_HAS_DATA *data) { - int len = 0; /* length of each encoding */ + int len = 0; /* length of each encoding */ int apdu_len = 0; /* total length of the apdu, return value */ if (apdu && data) { @@ -61,13 +61,13 @@ int whohas_encode_apdu(uint8_t *apdu, BACNET_WHO_HAS_DATA *data) apdu_len += len; } if (data->is_object_name) { - len = encode_context_character_string(&apdu[apdu_len], 3, - &data->object.name); + len = encode_context_character_string( + &apdu[apdu_len], 3, &data->object.name); apdu_len += len; } else { len = encode_context_object_id(&apdu[apdu_len], 2, - (int)data->object.identifier.type, - data->object.identifier.instance); + (int)data->object.identifier.type, + data->object.identifier.instance); apdu_len += len; } } @@ -76,30 +76,33 @@ int whohas_encode_apdu(uint8_t *apdu, BACNET_WHO_HAS_DATA *data) } /* decode the service request only */ -int whohas_decode_service_request(uint8_t *apdu, unsigned apdu_len, - BACNET_WHO_HAS_DATA *data) +int whohas_decode_service_request( + uint8_t *apdu, unsigned apdu_len, BACNET_WHO_HAS_DATA *data) { int len = 0; uint8_t tag_number = 0; uint32_t len_value = 0; uint32_t decoded_value = 0; /* for decoding */ - uint16_t decoded_type = 0; /* for decoding */ + uint16_t decoded_type = 0; /* for decoding */ if (apdu_len && data) { /* optional limits - must be used as a pair */ if (decode_is_context_tag(&apdu[len], 0)) { - len += decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value); + len += decode_tag_number_and_value( + &apdu[len], &tag_number, &len_value); len += decode_unsigned(&apdu[len], len_value, &decoded_value); - if (decoded_value <= BACNET_MAX_INSTANCE) + if (decoded_value <= BACNET_MAX_INSTANCE) { data->low_limit = decoded_value; - if (!decode_is_context_tag(&apdu[len], 1)) + } + if (!decode_is_context_tag(&apdu[len], 1)) { return -1; - len += decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value); + } + len += decode_tag_number_and_value( + &apdu[len], &tag_number, &len_value); len += decode_unsigned(&apdu[len], len_value, &decoded_value); - if (decoded_value <= BACNET_MAX_INSTANCE) + if (decoded_value <= BACNET_MAX_INSTANCE) { data->high_limit = decoded_value; + } } else { data->low_limit = -1; data->high_limit = -1; @@ -107,23 +110,24 @@ int whohas_decode_service_request(uint8_t *apdu, unsigned apdu_len, /* object id */ if (decode_is_context_tag(&apdu[len], 2)) { data->is_object_name = false; - len += decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value); - len += decode_object_id(&apdu[len], &decoded_type, - &data->object.identifier.instance); + len += decode_tag_number_and_value( + &apdu[len], &tag_number, &len_value); + len += decode_object_id( + &apdu[len], &decoded_type, &data->object.identifier.instance); data->object.identifier.type = decoded_type; } /* object name */ else if (decode_is_context_tag(&apdu[len], 3)) { data->is_object_name = true; - len += decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value); - len += decode_character_string(&apdu[len], len_value, - &data->object.name); + len += decode_tag_number_and_value( + &apdu[len], &tag_number, &len_value); + len += decode_character_string( + &apdu[len], len_value, &data->object.name); } /* missing required parameters */ - else + else { return -1; + } } return len; @@ -134,8 +138,8 @@ int whohas_decode_service_request(uint8_t *apdu, unsigned apdu_len, #include #include "ctest.h" -int whohas_decode_apdu(uint8_t *apdu, unsigned apdu_len, - BACNET_WHO_HAS_DATA *data) +int whohas_decode_apdu( + uint8_t *apdu, unsigned apdu_len, BACNET_WHO_HAS_DATA *data) { int len = 0; @@ -156,7 +160,7 @@ int whohas_decode_apdu(uint8_t *apdu, unsigned apdu_len, void testWhoHasData(Test *pTest, BACNET_WHO_HAS_DATA *data) { - uint8_t apdu[480] = {0}; + uint8_t apdu[480] = { 0 }; int len = 0; int apdu_len = 0; BACNET_WHO_HAS_DATA test_data; @@ -172,15 +176,16 @@ void testWhoHasData(Test *pTest, BACNET_WHO_HAS_DATA *data) ct_test(pTest, test_data.is_object_name == data->is_object_name); /* Object ID */ if (data->is_object_name == false) { - ct_test(pTest, test_data.object.identifier.type == - data->object.identifier.type); - ct_test(pTest, test_data.object.identifier.instance == - data->object.identifier.instance); + ct_test(pTest, + test_data.object.identifier.type == data->object.identifier.type); + ct_test(pTest, + test_data.object.identifier.instance == + data->object.identifier.instance); } /* Object Name */ else { - ct_test(pTest, characterstring_same(&test_data.object.name, - &data->object.name)); + ct_test(pTest, + characterstring_same(&test_data.object.name, &data->object.name)); } } diff --git a/include/whohas.h b/src/bacnet/whohas.h similarity index 99% rename from include/whohas.h rename to src/bacnet/whohas.h index 0cf21ad4..bebcc95d 100644 --- a/include/whohas.h +++ b/src/bacnet/whohas.h @@ -26,7 +26,7 @@ #include #include -#include "bacstr.h" +#include "bacnet/bacstr.h" typedef struct BACnet_Who_Has_Data { int32_t low_limit; /* deviceInstanceRange */ diff --git a/src/whois.c b/src/bacnet/whois.c similarity index 86% rename from src/whois.c rename to src/bacnet/whois.c index 8246e913..b90c2d33 100644 --- a/src/whois.c +++ b/src/bacnet/whois.c @@ -32,17 +32,17 @@ ------------------------------------------- ####COPYRIGHTEND####*/ #include -#include "bacenum.h" -#include "bacdcode.h" -#include "bacdef.h" -#include "whois.h" +#include "bacnet/bacenum.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacdef.h" +#include "bacnet/whois.h" /** @file whois.c Encode/Decode Who-Is requests */ /* encode I-Am service - use -1 for limit if you want unlimited */ int whois_encode_apdu(uint8_t *apdu, int32_t low_limit, int32_t high_limit) { - int len = 0; /* length of each encoding */ + int len = 0; /* length of each encoding */ int apdu_len = 0; /* total length of the apdu, return value */ if (apdu) { @@ -63,8 +63,8 @@ int whois_encode_apdu(uint8_t *apdu, int32_t low_limit, int32_t high_limit) } /* decode the service request only */ -int whois_decode_service_request(uint8_t *apdu, unsigned apdu_len, - int32_t *pLow_limit, int32_t *pHigh_limit) +int whois_decode_service_request( + uint8_t *apdu, unsigned apdu_len, int32_t *pLow_limit, int32_t *pHigh_limit) { unsigned int len = 0; uint8_t tag_number = 0; @@ -85,8 +85,8 @@ int whois_decode_service_request(uint8_t *apdu, unsigned apdu_len, } } if (apdu_len > (unsigned)len) { - len += decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value); + len += decode_tag_number_and_value( + &apdu[len], &tag_number, &len_value); if (tag_number != 1) { return BACNET_STATUS_ERROR; } @@ -125,8 +125,8 @@ int whois_decode_service_request(uint8_t *apdu, unsigned apdu_len, #include #include "ctest.h" -int whois_decode_apdu(uint8_t *apdu, unsigned apdu_len, int32_t *pLow_limit, - int32_t *pHigh_limit) +int whois_decode_apdu( + uint8_t *apdu, unsigned apdu_len, int32_t *pLow_limit, int32_t *pHigh_limit) { int len = 0; @@ -143,8 +143,8 @@ int whois_decode_apdu(uint8_t *apdu, unsigned apdu_len, int32_t *pLow_limit, if (apdu[1] != SERVICE_UNCONFIRMED_WHO_IS) { return BACNET_STATUS_ERROR; } - len = whois_decode_service_request(&apdu[2], apdu_len - 2, pLow_limit, - pHigh_limit); + len = whois_decode_service_request( + &apdu[2], apdu_len - 2, pLow_limit, pHigh_limit); } return len; @@ -152,7 +152,7 @@ int whois_decode_apdu(uint8_t *apdu, unsigned apdu_len, int32_t *pLow_limit, void testWhoIs(Test *pTest) { - uint8_t apdu[480] = {0}; + uint8_t apdu[480] = { 0 }; int len = 0; int apdu_len = 0; int32_t low_limit = -1; @@ -165,8 +165,8 @@ void testWhoIs(Test *pTest) ct_test(pTest, len > 0); apdu_len = len; - len = whois_decode_apdu(&apdu[0], apdu_len, &test_low_limit, - &test_high_limit); + len = whois_decode_apdu( + &apdu[0], apdu_len, &test_low_limit, &test_high_limit); ct_test(pTest, len != BACNET_STATUS_ERROR); ct_test(pTest, test_low_limit == low_limit); ct_test(pTest, test_high_limit == high_limit); @@ -179,8 +179,8 @@ void testWhoIs(Test *pTest) len = whois_encode_apdu(&apdu[0], low_limit, high_limit); apdu_len = len; ct_test(pTest, len > 0); - len = whois_decode_apdu(&apdu[0], apdu_len, &test_low_limit, - &test_high_limit); + len = whois_decode_apdu( + &apdu[0], apdu_len, &test_low_limit, &test_high_limit); ct_test(pTest, len != BACNET_STATUS_ERROR); ct_test(pTest, test_low_limit == low_limit); ct_test(pTest, test_high_limit == high_limit); @@ -198,8 +198,8 @@ void testWhoIs(Test *pTest) len = whois_encode_apdu(&apdu[0], low_limit, high_limit); ct_test(pTest, len > 0); apdu_len = len; - len = whois_decode_apdu(&apdu[0], apdu_len, &test_low_limit, - &test_high_limit); + len = whois_decode_apdu( + &apdu[0], apdu_len, &test_low_limit, &test_high_limit); ct_test(pTest, len != BACNET_STATUS_ERROR); ct_test(pTest, test_low_limit == low_limit); ct_test(pTest, test_high_limit == high_limit); diff --git a/include/whois.h b/src/bacnet/whois.h similarity index 100% rename from include/whois.h rename to src/bacnet/whois.h diff --git a/src/wp.c b/src/bacnet/wp.c similarity index 80% rename from src/wp.c rename to src/bacnet/wp.c index e253cffb..80b067f9 100644 --- a/src/wp.c +++ b/src/bacnet/wp.c @@ -32,19 +32,19 @@ ------------------------------------------- ####COPYRIGHTEND####*/ #include -#include "bacenum.h" -#include "bacdcode.h" -#include "bacdef.h" -#include "wp.h" +#include "bacnet/bacenum.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacdef.h" +#include "bacnet/wp.h" /** @file wp.c Encode/Decode BACnet Write Property APDUs */ #if BACNET_SVC_WP_A /* encode service */ -int wp_encode_apdu(uint8_t *apdu, uint8_t invoke_id, - BACNET_WRITE_PROPERTY_DATA *wpdata) +int wp_encode_apdu( + uint8_t *apdu, uint8_t invoke_id, BACNET_WRITE_PROPERTY_DATA *wpdata) { int apdu_len = 0; /* total length of the apdu, return value */ - int len = 0; /* total length of the apdu, return value */ + int len = 0; /* total length of the apdu, return value */ if (apdu) { apdu[0] = PDU_TYPE_CONFIRMED_SERVICE_REQUEST; @@ -52,16 +52,16 @@ int wp_encode_apdu(uint8_t *apdu, uint8_t invoke_id, apdu[2] = invoke_id; apdu[3] = SERVICE_CONFIRMED_WRITE_PROPERTY; /* service choice */ apdu_len = 4; - len = encode_context_object_id(&apdu[apdu_len], 0, wpdata->object_type, - wpdata->object_instance); + len = encode_context_object_id( + &apdu[apdu_len], 0, wpdata->object_type, wpdata->object_instance); apdu_len += len; - len = encode_context_enumerated(&apdu[apdu_len], 1, - wpdata->object_property); + len = encode_context_enumerated( + &apdu[apdu_len], 1, wpdata->object_property); apdu_len += len; /* optional array index; ALL is -1 which is assumed when missing */ if (wpdata->array_index != BACNET_ARRAY_ALL) { - len = encode_context_unsigned(&apdu[apdu_len], 2, - wpdata->array_index); + len = encode_context_unsigned( + &apdu[apdu_len], 2, wpdata->array_index); apdu_len += len; } /* propertyValue */ @@ -87,14 +87,14 @@ int wp_encode_apdu(uint8_t *apdu, uint8_t invoke_id, /* decode the service request only */ /* FIXME: there could be various error messages returned using unique values less than zero */ -int wp_decode_service_request(uint8_t *apdu, unsigned apdu_len, - BACNET_WRITE_PROPERTY_DATA *wpdata) +int wp_decode_service_request( + uint8_t *apdu, unsigned apdu_len, BACNET_WRITE_PROPERTY_DATA *wpdata) { int len = 0; int tag_len = 0; uint8_t tag_number = 0; uint32_t len_value_type = 0; - uint16_t type = 0; /* for decoding */ + uint16_t type = 0; /* for decoding */ uint32_t property = 0; /* for decoding */ uint32_t unsigned_value = 0; int i = 0; /* loop counter */ @@ -102,31 +102,35 @@ int wp_decode_service_request(uint8_t *apdu, unsigned apdu_len, /* check for value pointers */ if (apdu_len && wpdata) { /* Tag 0: Object ID */ - if (!decode_is_context_tag(&apdu[len++], 0)) + if (!decode_is_context_tag(&apdu[len++], 0)) { return -1; + } len += decode_object_id(&apdu[len], &type, &wpdata->object_instance); wpdata->object_type = (BACNET_OBJECT_TYPE)type; /* Tag 1: Property ID */ - len += decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value_type); - if (tag_number != 1) + len += decode_tag_number_and_value( + &apdu[len], &tag_number, &len_value_type); + if (tag_number != 1) { return -1; + } len += decode_enumerated(&apdu[len], len_value_type, &property); wpdata->object_property = (BACNET_PROPERTY_ID)property; /* Tag 2: Optional Array Index */ /* note: decode without incrementing len so we can check for opening tag */ - tag_len = decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value_type); + tag_len = decode_tag_number_and_value( + &apdu[len], &tag_number, &len_value_type); if (tag_number == 2) { len += tag_len; len += decode_unsigned(&apdu[len], len_value_type, &unsigned_value); wpdata->array_index = unsigned_value; - } else + } else { wpdata->array_index = BACNET_ARRAY_ALL; + } /* Tag 3: opening context tag */ - if (!decode_is_opening_tag_number(&apdu[len], 3)) + if (!decode_is_opening_tag_number(&apdu[len], 3)) { return -1; + } /* determine the length of the data blob */ wpdata->application_data_len = bacapp_data_len( &apdu[len], apdu_len - len, (BACNET_PROPERTY_ID)property); @@ -138,24 +142,26 @@ int wp_decode_service_request(uint8_t *apdu, unsigned apdu_len, } /* add on the data length */ len += wpdata->application_data_len; - if (!decode_is_closing_tag_number(&apdu[len], 3)) + if (!decode_is_closing_tag_number(&apdu[len], 3)) { return -2; + } /* a tag number of 3 is not extended so only one octet */ len++; /* Tag 4: optional Priority - assumed MAX if not explicitly set */ wpdata->priority = BACNET_MAX_PRIORITY; if ((unsigned)len < apdu_len) { - tag_len = decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value_type); + tag_len = decode_tag_number_and_value( + &apdu[len], &tag_number, &len_value_type); if (tag_number == 4) { len += tag_len; - len = decode_unsigned(&apdu[len], len_value_type, - &unsigned_value); + len = decode_unsigned( + &apdu[len], len_value_type, &unsigned_value); if ((unsigned_value >= BACNET_MIN_PRIORITY) && (unsigned_value <= BACNET_MAX_PRIORITY)) { wpdata->priority = (uint8_t)unsigned_value; - } else + } else { return -5; + } } } } @@ -168,8 +174,10 @@ int wp_decode_service_request(uint8_t *apdu, unsigned apdu_len, #include #include "ctest.h" -int wp_decode_apdu(uint8_t *apdu, unsigned apdu_len, uint8_t *invoke_id, - BACNET_WRITE_PROPERTY_DATA *wpdata) +int wp_decode_apdu(uint8_t *apdu, + unsigned apdu_len, + uint8_t *invoke_id, + BACNET_WRITE_PROPERTY_DATA *wpdata) { int len = 0; unsigned offset = 0; @@ -195,10 +203,10 @@ int wp_decode_apdu(uint8_t *apdu, unsigned apdu_len, uint8_t *invoke_id, void testWritePropertyTag(Test *pTest, BACNET_APPLICATION_DATA_VALUE *value) { - BACNET_WRITE_PROPERTY_DATA wpdata = {0}; - BACNET_WRITE_PROPERTY_DATA test_data = {0}; + BACNET_WRITE_PROPERTY_DATA wpdata = { 0 }; + BACNET_WRITE_PROPERTY_DATA test_data = { 0 }; BACNET_APPLICATION_DATA_VALUE test_value; - uint8_t apdu[480] = {0}; + uint8_t apdu[480] = { 0 }; int len = 0; int apdu_len = 0; uint8_t invoke_id = 128; @@ -218,8 +226,7 @@ void testWritePropertyTag(Test *pTest, BACNET_APPLICATION_DATA_VALUE *value) ct_test(pTest, test_data.array_index == wpdata.array_index); /* decode the application value of the request */ len = bacapp_decode_application_data(test_data.application_data, - test_data.application_data_len, - &test_value); + test_data.application_data_len, &test_value); ct_test(pTest, test_value.tag == value->tag); switch (test_value.tag) { case BACNET_APPLICATION_TAG_NULL: @@ -229,23 +236,23 @@ void testWritePropertyTag(Test *pTest, BACNET_APPLICATION_DATA_VALUE *value) break; case BACNET_APPLICATION_TAG_UNSIGNED_INT: ct_test(pTest, - test_value.type.Unsigned_Int == value->type.Unsigned_Int); + test_value.type.Unsigned_Int == value->type.Unsigned_Int); break; case BACNET_APPLICATION_TAG_SIGNED_INT: - ct_test(pTest, - test_value.type.Signed_Int == value->type.Signed_Int); + ct_test( + pTest, test_value.type.Signed_Int == value->type.Signed_Int); break; case BACNET_APPLICATION_TAG_REAL: ct_test(pTest, test_value.type.Real == value->type.Real); break; case BACNET_APPLICATION_TAG_ENUMERATED: - ct_test(pTest, - test_value.type.Enumerated == value->type.Enumerated); + ct_test( + pTest, test_value.type.Enumerated == value->type.Enumerated); break; case BACNET_APPLICATION_TAG_DATE: ct_test(pTest, test_value.type.Date.year == value->type.Date.year); - ct_test(pTest, - test_value.type.Date.month == value->type.Date.month); + ct_test( + pTest, test_value.type.Date.month == value->type.Date.month); ct_test(pTest, test_value.type.Date.day == value->type.Date.day); ct_test(pTest, test_value.type.Date.wday == value->type.Date.wday); break; @@ -253,14 +260,15 @@ void testWritePropertyTag(Test *pTest, BACNET_APPLICATION_DATA_VALUE *value) ct_test(pTest, test_value.type.Time.hour == value->type.Time.hour); ct_test(pTest, test_value.type.Time.min == value->type.Time.min); ct_test(pTest, test_value.type.Time.sec == value->type.Time.sec); - ct_test(pTest, test_value.type.Time.hundredths == - value->type.Time.hundredths); + ct_test(pTest, + test_value.type.Time.hundredths == value->type.Time.hundredths); break; case BACNET_APPLICATION_TAG_OBJECT_ID: - ct_test(pTest, test_value.type.Object_Id.type == - value->type.Object_Id.type); - ct_test(pTest, test_value.type.Object_Id.instance == - value->type.Object_Id.instance); + ct_test(pTest, + test_value.type.Object_Id.type == value->type.Object_Id.type); + ct_test(pTest, + test_value.type.Object_Id.instance == + value->type.Object_Id.instance); break; default: break; diff --git a/include/wp.h b/src/bacnet/wp.h similarity index 98% rename from include/wp.h rename to src/bacnet/wp.h index 0e304919..be11242a 100644 --- a/include/wp.h +++ b/src/bacnet/wp.h @@ -26,8 +26,8 @@ #include #include -#include "bacdcode.h" -#include "bacapp.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacapp.h" /** @note: write property can have application tagged data, or context tagged data, or even complex data types (i.e. opening and closing tag around data). diff --git a/src/wpm.c b/src/bacnet/wpm.c similarity index 81% rename from src/wpm.c rename to src/bacnet/wpm.c index 1901daf0..144ff623 100644 --- a/src/wpm.c +++ b/src/bacnet/wpm.c @@ -24,13 +24,13 @@ * *********************************************************************/ #include -#include "bacapp.h" -#include "bacenum.h" -#include "bacdcode.h" -#include "bacdef.h" -#include "wp.h" -#include "wpm.h" -#include "string.h" +#include +#include "bacnet/bacapp.h" +#include "bacnet/bacenum.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacdef.h" +#include "bacnet/wp.h" +#include "bacnet/wpm.h" /** @file wpm.c Encode/Decode BACnet Write Property Multiple APDUs */ @@ -49,8 +49,8 @@ * @param data [out] The BACNET_WRITE_PROPERTY_DATA structure * which will contain the reponse values or error. */ -int wpm_decode_object_id(uint8_t *apdu, uint16_t apdu_len, - BACNET_WRITE_PROPERTY_DATA *wp_data) +int wpm_decode_object_id( + uint8_t *apdu, uint16_t apdu_len, BACNET_WRITE_PROPERTY_DATA *wp_data) { uint8_t tag_number = 0; uint32_t len_value = 0; @@ -64,8 +64,8 @@ int wpm_decode_object_id(uint8_t *apdu, uint16_t apdu_len, if ((tag_number == 0) && (apdu_len > len)) { apdu_len -= len; if (apdu_len >= 4) { - len += decode_object_id(&apdu[len], &object_type, - &object_instance); + len += decode_object_id( + &apdu[len], &object_type, &object_instance); wp_data->object_type = object_type; wp_data->object_instance = object_instance; apdu_len -= len; @@ -92,8 +92,8 @@ int wpm_decode_object_id(uint8_t *apdu, uint16_t apdu_len, return (int)len; } -int wpm_decode_object_property(uint8_t *apdu, uint16_t apdu_len, - BACNET_WRITE_PROPERTY_DATA *wp_data) +int wpm_decode_object_property( + uint8_t *apdu, uint16_t apdu_len, BACNET_WRITE_PROPERTY_DATA *wp_data) { uint8_t tag_number = 0; uint32_t len_value = 0; @@ -120,15 +120,14 @@ int wpm_decode_object_property(uint8_t *apdu, uint16_t apdu_len, len += decode_unsigned(&apdu[len], len_value, &ulVal); wp_data->array_index = ulVal; - len += decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value); + len += decode_tag_number_and_value( + &apdu[len], &tag_number, &len_value); } /* tag 2 - Property Value */ if ((tag_number == 2) && (decode_is_opening_tag(&apdu[len - 1]))) { len--; - wp_data->application_data_len = - bacapp_data_len(&apdu[len], (unsigned)(apdu_len - len), - wp_data->object_property); + wp_data->application_data_len = bacapp_data_len(&apdu[len], + (unsigned)(apdu_len - len), wp_data->object_property); len++; /* copy application data */ @@ -136,8 +135,8 @@ int wpm_decode_object_property(uint8_t *apdu, uint16_t apdu_len, wp_data->application_data[i] = apdu[len + i]; } len += wp_data->application_data_len; - len += decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value); + len += decode_tag_number_and_value( + &apdu[len], &tag_number, &len_value); /* closing tag 2 */ if ((tag_number != 2) && (decode_is_closing_tag(&apdu[len - 1]))) { wp_data->error_code = ERROR_CODE_REJECT_INVALID_TAG; @@ -153,8 +152,9 @@ int wpm_decode_object_property(uint8_t *apdu, uint16_t apdu_len, if (tag_number == 3) { len += decode_unsigned(&apdu[len], len_value, &ulVal); wp_data->priority = ulVal; - } else + } else { len--; + } } else { wp_data->error_code = ERROR_CODE_REJECT_MISSING_REQUIRED_PARAMETER; return BACNET_STATUS_REJECT; @@ -179,8 +179,8 @@ int wpm_encode_apdu_init(uint8_t *apdu, uint8_t invoke_id) return apdu_len; } -int wpm_encode_apdu_object_begin(uint8_t *apdu, BACNET_OBJECT_TYPE object_type, - uint32_t object_instance) +int wpm_encode_apdu_object_begin( + uint8_t *apdu, BACNET_OBJECT_TYPE object_type, uint32_t object_instance) { int apdu_len = 0; /* total length of the apdu, return value */ @@ -205,8 +205,8 @@ int wpm_encode_apdu_object_end(uint8_t *apdu) return apdu_len; } -int wpm_encode_apdu_object_property(uint8_t *apdu, - BACNET_WRITE_PROPERTY_DATA *wpdata) +int wpm_encode_apdu_object_property( + uint8_t *apdu, BACNET_WRITE_PROPERTY_DATA *wpdata) { int apdu_len = 0; /* total length of the apdu, return value */ int len = 0; @@ -216,8 +216,8 @@ int wpm_encode_apdu_object_property(uint8_t *apdu, encode_context_enumerated(&apdu[0], 0, wpdata->object_property); /* optional array index */ if (wpdata->array_index != BACNET_ARRAY_ALL) { - apdu_len += encode_context_unsigned(&apdu[apdu_len], 1, - wpdata->array_index); + apdu_len += encode_context_unsigned( + &apdu[apdu_len], 1, wpdata->array_index); } apdu_len += encode_opening_tag(&apdu[apdu_len], 2); for (len = 0; len < wpdata->application_data_len; len++) { @@ -234,14 +234,16 @@ int wpm_encode_apdu_object_property(uint8_t *apdu, return apdu_len; } -int wpm_encode_apdu(uint8_t *apdu, size_t max_apdu, uint8_t invoke_id, - BACNET_WRITE_ACCESS_DATA *write_access_data) +int wpm_encode_apdu(uint8_t *apdu, + size_t max_apdu, + uint8_t invoke_id, + BACNET_WRITE_ACCESS_DATA *write_access_data) { int apdu_len = 0; int len = 0; BACNET_WRITE_ACCESS_DATA *wpm_object; /* current object */ - uint8_t apdu_temp[MAX_APDU]; /* temp for data before copy */ - BACNET_PROPERTY_VALUE *wpm_property; /* current property */ + uint8_t apdu_temp[MAX_APDU]; /* temp for data before copy */ + BACNET_PROPERTY_VALUE *wpm_property; /* current property */ BACNET_WRITE_PROPERTY_DATA wpdata; /* for compatibility with wpm_encode_apdu_object_property function */ @@ -254,8 +256,7 @@ int wpm_encode_apdu(uint8_t *apdu, size_t max_apdu, uint8_t invoke_id, while (wpm_object) { len = wpm_encode_apdu_object_begin(&apdu[apdu_len], - wpm_object->object_type, - wpm_object->object_instance); + wpm_object->object_type, wpm_object->object_instance); apdu_len += len; wpm_property = wpm_object->listOfProperties; @@ -267,7 +268,7 @@ int wpm_encode_apdu(uint8_t *apdu, size_t max_apdu, uint8_t invoke_id, wpdata.application_data_len = bacapp_encode_data(&apdu_temp[0], &wpm_property->value); memcpy(&wpdata.application_data[0], &apdu_temp[0], - (size_t)wpdata.application_data_len); + (size_t)wpdata.application_data_len); len = wpm_encode_apdu_object_property(&apdu[apdu_len], &wpdata); apdu_len += len; @@ -297,8 +298,8 @@ int wpm_ack_encode_apdu_init(uint8_t *apdu, uint8_t invoke_id) return len; } -int wpm_error_ack_encode_apdu(uint8_t *apdu, uint8_t invoke_id, - BACNET_WRITE_PROPERTY_DATA *wp_data) +int wpm_error_ack_encode_apdu( + uint8_t *apdu, uint8_t invoke_id, BACNET_WRITE_PROPERTY_DATA *wp_data) { int len = 0; @@ -313,13 +314,14 @@ int wpm_error_ack_encode_apdu(uint8_t *apdu, uint8_t invoke_id, len += encode_closing_tag(&apdu[len], 0); len += encode_opening_tag(&apdu[len], 1); - len += encode_context_object_id(&apdu[len], 0, wp_data->object_type, - wp_data->object_instance); + len += encode_context_object_id( + &apdu[len], 0, wp_data->object_type, wp_data->object_instance); len += encode_context_enumerated(&apdu[len], 1, wp_data->object_property); - if (wp_data->array_index != BACNET_ARRAY_ALL) + if (wp_data->array_index != BACNET_ARRAY_ALL) { len += encode_context_unsigned(&apdu[len], 2, wp_data->array_index); + } len += encode_closing_tag(&apdu[len], 1); } return len; diff --git a/include/wpm.h b/src/bacnet/wpm.h similarity index 98% rename from include/wpm.h rename to src/bacnet/wpm.h index 6f860552..37e26633 100644 --- a/include/wpm.h +++ b/src/bacnet/wpm.h @@ -27,9 +27,9 @@ #include #include -#include "bacdcode.h" -#include "bacapp.h" -#include "wp.h" +#include "bacnet/bacdcode.h" +#include "bacnet/bacapp.h" +#include "bacnet/wp.h" #ifdef __cplusplus extern "C" { diff --git a/src/bactext.c b/src/bactext.c deleted file mode 100644 index 54524559..00000000 --- a/src/bactext.c +++ /dev/null @@ -1,1534 +0,0 @@ -/*####COPYRIGHTBEGIN#### - ------------------------------------------- - Copyright (C) 2005-2006 Steve Karg - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to: - The Free Software Foundation, Inc. - 59 Temple Place - Suite 330 - Boston, MA 02111-1307, USA. - - As a special exception, if other files instantiate templates or - use macros or inline functions from this file, or you compile - this file and link it with other works to produce a work based - on this file, this file does not by itself cause the resulting - work to be covered by the GNU General Public License. However - the source code for this file must still be made available in - accordance with section (3) of the GNU General Public License. - - This exception does not invalidate any other reasons why a work - based on this file might be covered by the GNU General Public - License. - ------------------------------------------- -####COPYRIGHTEND####*/ - -#include -#include "indtext.h" -#include "bacenum.h" -#include "bactext.h" - -/** @file bactext.c Lookup or Translate BACnet Name Text */ - -static const char *ASHRAE_Reserved_String = "Reserved for Use by ASHRAE"; -static const char *Vendor_Proprietary_String = "Vendor Proprietary Value"; - -INDTEXT_DATA bacnet_confirmed_service_names[] = { - {SERVICE_CONFIRMED_ACKNOWLEDGE_ALARM, "Acknowledge-Alarm"}, - {SERVICE_CONFIRMED_COV_NOTIFICATION, "COV-Notification"}, - {SERVICE_CONFIRMED_EVENT_NOTIFICATION, "Event-Notification"}, - {SERVICE_CONFIRMED_GET_ALARM_SUMMARY, "Get-Alarm-Summary"}, - {SERVICE_CONFIRMED_GET_ENROLLMENT_SUMMARY, "Get-Enrollment-Summary"}, - {SERVICE_CONFIRMED_SUBSCRIBE_COV, "Subscribe-COV"}, - {SERVICE_CONFIRMED_ATOMIC_READ_FILE, "Atomic-Read-File"}, - {SERVICE_CONFIRMED_ATOMIC_WRITE_FILE, "Atomic-Write-File"}, - {SERVICE_CONFIRMED_ADD_LIST_ELEMENT, "Add-List-Element"}, - {SERVICE_CONFIRMED_REMOVE_LIST_ELEMENT, "Remove-List-Element"}, - {SERVICE_CONFIRMED_CREATE_OBJECT, "Create-Object"}, - {SERVICE_CONFIRMED_DELETE_OBJECT, "Delete-Object"}, - {SERVICE_CONFIRMED_READ_PROPERTY, "Read-Property"}, - {SERVICE_CONFIRMED_READ_PROP_CONDITIONAL, "Read-Property-Conditional"}, - {SERVICE_CONFIRMED_READ_PROP_MULTIPLE, "Read-Property-Multiple"}, - {SERVICE_CONFIRMED_WRITE_PROPERTY, "Write-Property"}, - {SERVICE_CONFIRMED_WRITE_PROP_MULTIPLE, "Write-Property-Multiple"}, - {SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL, - "Device-Communication-Control"}, - {SERVICE_CONFIRMED_PRIVATE_TRANSFER, "Private-Transfer"}, - {SERVICE_CONFIRMED_TEXT_MESSAGE, "Text-Message"}, - {SERVICE_CONFIRMED_REINITIALIZE_DEVICE, "Reinitialize-Device"}, - {SERVICE_CONFIRMED_VT_OPEN, "VT-Open"}, - {SERVICE_CONFIRMED_VT_CLOSE, "VT-Close"}, - {SERVICE_CONFIRMED_VT_DATA, "VT-Data"}, - {SERVICE_CONFIRMED_AUTHENTICATE, "Authenticate"}, - {SERVICE_CONFIRMED_REQUEST_KEY, "Request-Key"}, - {SERVICE_CONFIRMED_READ_RANGE, "Read-Range"}, - {SERVICE_CONFIRMED_LIFE_SAFETY_OPERATION, "Life-Safety_Operation"}, - {SERVICE_CONFIRMED_SUBSCRIBE_COV_PROPERTY, "Subscribe-COV-Property"}, - {SERVICE_CONFIRMED_GET_EVENT_INFORMATION, "Get-Event-Information"}, - {0, NULL}}; - -const char *bactext_confirmed_service_name(unsigned index) -{ - return indtext_by_index_default(bacnet_confirmed_service_names, index, - ASHRAE_Reserved_String); -} - -INDTEXT_DATA bacnet_unconfirmed_service_names[] = { - {SERVICE_UNCONFIRMED_I_AM, "I-Am"}, - {SERVICE_UNCONFIRMED_I_HAVE, "I-Have"}, - {SERVICE_UNCONFIRMED_COV_NOTIFICATION, "COV-Notification"}, - {SERVICE_UNCONFIRMED_EVENT_NOTIFICATION, "Event-Notification"}, - {SERVICE_UNCONFIRMED_PRIVATE_TRANSFER, "Private-Transfer"}, - {SERVICE_UNCONFIRMED_TEXT_MESSAGE, "Text-Message"}, - {SERVICE_UNCONFIRMED_TIME_SYNCHRONIZATION, "Time-Synchronization"}, - {SERVICE_UNCONFIRMED_WHO_HAS, "Who-Has"}, - {SERVICE_UNCONFIRMED_WHO_IS, "Who-Is"}, - {SERVICE_UNCONFIRMED_UTC_TIME_SYNCHRONIZATION, "UTC-Time-Synchronization"}, - {SERVICE_UNCONFIRMED_WRITE_GROUP, "Write-Group"}, - {0, NULL}}; - -const char *bactext_unconfirmed_service_name(unsigned index) -{ - return indtext_by_index_default(bacnet_unconfirmed_service_names, index, - ASHRAE_Reserved_String); -} - -INDTEXT_DATA bacnet_application_tag_names[] = { - {BACNET_APPLICATION_TAG_NULL, "Null"}, - {BACNET_APPLICATION_TAG_BOOLEAN, "Boolean"}, - {BACNET_APPLICATION_TAG_UNSIGNED_INT, "Unsigned Int"}, - {BACNET_APPLICATION_TAG_SIGNED_INT, "Signed Int"}, - {BACNET_APPLICATION_TAG_REAL, "Real"}, - {BACNET_APPLICATION_TAG_DOUBLE, "Double"}, - {BACNET_APPLICATION_TAG_OCTET_STRING, "Octet String"}, - {BACNET_APPLICATION_TAG_CHARACTER_STRING, "Character String"}, - {BACNET_APPLICATION_TAG_BIT_STRING, "Bit String"}, - {BACNET_APPLICATION_TAG_ENUMERATED, "Enumerated"}, - {BACNET_APPLICATION_TAG_DATE, "Date"}, - {BACNET_APPLICATION_TAG_TIME, "Time"}, - {BACNET_APPLICATION_TAG_OBJECT_ID, "Object ID"}, - {BACNET_APPLICATION_TAG_RESERVE1, "Reserved 1"}, - {BACNET_APPLICATION_TAG_RESERVE2, "Reserved 2"}, - {BACNET_APPLICATION_TAG_RESERVE3, "Reserved 3"}, - {0, NULL}}; - -const char *bactext_application_tag_name(unsigned index) -{ - return indtext_by_index_default(bacnet_application_tag_names, index, - ASHRAE_Reserved_String); -} - -bool bactext_application_tag_index(const char *search_name, - unsigned *found_index) -{ - return indtext_by_istring(bacnet_application_tag_names, search_name, - found_index); -} - -INDTEXT_DATA bacnet_object_type_names[] = { - {OBJECT_ANALOG_INPUT, "analog-input"}, - {OBJECT_ANALOG_OUTPUT, "analog-output"}, - {OBJECT_ANALOG_VALUE, "analog-value"}, - {OBJECT_BINARY_INPUT, "binary-input"}, - {OBJECT_BINARY_OUTPUT, "binary-output"}, - {OBJECT_BINARY_VALUE, "binary-value"}, - {OBJECT_CALENDAR, "calendar"}, - {OBJECT_COMMAND, "command"}, - {OBJECT_DEVICE, "device"}, - {OBJECT_EVENT_ENROLLMENT, "event-enrollment"}, - {OBJECT_FILE, "file"}, - {OBJECT_GROUP, "group"}, - {OBJECT_LOOP, "loop"}, - {OBJECT_MULTI_STATE_INPUT, "multi-state-input"}, - {OBJECT_MULTI_STATE_OUTPUT, "multi-state-output"}, - {OBJECT_NOTIFICATION_CLASS, "notification-class"}, - {OBJECT_PROGRAM, "program"}, - {OBJECT_SCHEDULE, "schedule"}, - {OBJECT_AVERAGING, "averaging"}, - {OBJECT_MULTI_STATE_VALUE, "multi-state-value"}, - {OBJECT_TRENDLOG, "trend-log"}, - {OBJECT_LIFE_SAFETY_POINT, "life-safety-point"}, - {OBJECT_LIFE_SAFETY_ZONE, "life-safety-zone"}, - {OBJECT_ACCUMULATOR, "accumulator"}, - {OBJECT_PULSE_CONVERTER, "pulse-converter"}, - {OBJECT_EVENT_LOG, "event-log"}, - {OBJECT_GLOBAL_GROUP, "global-group"}, - {OBJECT_TREND_LOG_MULTIPLE, "trend-log-multiple"}, - {OBJECT_LOAD_CONTROL, "load-control"}, - {OBJECT_STRUCTURED_VIEW, "structured-view"}, - {OBJECT_ACCESS_DOOR, "access-door"}, - {OBJECT_LIGHTING_OUTPUT, "lighting-output"}, - {OBJECT_ACCESS_CREDENTIAL, "access-credential"}, - {OBJECT_ACCESS_POINT, "access-point"}, - {OBJECT_ACCESS_RIGHTS, "access-rights"}, - {OBJECT_ACCESS_USER, "access-user"}, - {OBJECT_ACCESS_ZONE, "access-zone"}, - {OBJECT_CREDENTIAL_DATA_INPUT, "credential-data-input"}, - {OBJECT_NETWORK_SECURITY, "network-security"}, - {OBJECT_BITSTRING_VALUE, "bitstring-value"}, - {OBJECT_CHARACTERSTRING_VALUE, "characterstring-value"}, - {OBJECT_DATE_PATTERN_VALUE, "date-pattern-value"}, - {OBJECT_DATE_VALUE, "date-value"}, - {OBJECT_DATETIME_PATTERN_VALUE, "datetime-pattern-value"}, - {OBJECT_DATETIME_VALUE, "datetime-value"}, - {OBJECT_INTEGER_VALUE, "integer-value"}, - {OBJECT_LARGE_ANALOG_VALUE, "large-analog-value"}, - {OBJECT_OCTETSTRING_VALUE, "octetstring-value"}, - {OBJECT_POSITIVE_INTEGER_VALUE, "positive-integer-value"}, - {OBJECT_TIME_PATTERN_VALUE, "time-pattern-value"}, - {OBJECT_TIME_VALUE, "time-value"}, - {OBJECT_NOTIFICATION_FORWARDER, "notification-forwarder"}, - {OBJECT_ALERT_ENROLLMENT, "alert-enrollment"}, - {OBJECT_CHANNEL, "channel"}, - {OBJECT_LIGHTING_OUTPUT, "lighting-output"}, - {OBJECT_BINARY_LIGHTING_OUTPUT, "binary-lighting-output"}, - {OBJECT_NETWORK_PORT, "network-port"}, - {0, NULL} - /* Enumerated values 0-127 are reserved for definition by ASHRAE. - Enumerated values 128-1023 may be used by others subject to - the procedures and constraints described in Clause 23. */ -}; - -const char *bactext_object_type_name(unsigned index) -{ - return indtext_by_index_split_default(bacnet_object_type_names, index, 128, - ASHRAE_Reserved_String, - Vendor_Proprietary_String); -} - -bool bactext_object_type_index(const char *search_name, unsigned *found_index) -{ - return indtext_by_istring(bacnet_object_type_names, search_name, - found_index); -} - -INDTEXT_DATA bacnet_property_names[] = { - /* FIXME: use the enumerations from bacenum.h */ - {PROP_ACKED_TRANSITIONS, "acked-transitions"}, - {PROP_ACK_REQUIRED, "ack-required"}, - {PROP_ACTION, "action"}, - {PROP_ACTION_TEXT, "action-text"}, - {PROP_ACTIVE_TEXT, "active-text"}, - {PROP_ACTIVE_VT_SESSIONS, "active-vt-sessions"}, - {PROP_ALARM_VALUE, "alarm-value"}, - {PROP_ALARM_VALUES, "alarm-values"}, - {PROP_ALL, "all"}, - {PROP_ALL_WRITES_SUCCESSFUL, "all-writes-successful"}, - {PROP_APDU_SEGMENT_TIMEOUT, "apdu-segment-timeout"}, - {PROP_APDU_TIMEOUT, "apdu-timeout"}, - {PROP_APPLICATION_SOFTWARE_VERSION, "application-software-version"}, - {PROP_ARCHIVE, "archive"}, - {PROP_BIAS, "bias"}, - {PROP_CHANGE_OF_STATE_COUNT, "change-of-state-count"}, - {PROP_CHANGE_OF_STATE_TIME, "change-of-state-time"}, - {PROP_NOTIFICATION_CLASS, "notification-class"}, - {PROP_BLANK_1, "(deleted in 135-2001)"}, - {PROP_CONTROLLED_VARIABLE_REFERENCE, "controlled-variable-reference"}, - {PROP_CONTROLLED_VARIABLE_UNITS, "controlled-variable-units"}, - {PROP_CONTROLLED_VARIABLE_VALUE, "controlled-variable-value"}, - {PROP_COV_INCREMENT, "COV-increment"}, - {PROP_DATE_LIST, "datelist"}, - {PROP_DAYLIGHT_SAVINGS_STATUS, "daylight-savings-status"}, - {PROP_DEADBAND, "deadband"}, - {PROP_DERIVATIVE_CONSTANT, "derivative-constant"}, - {PROP_DERIVATIVE_CONSTANT_UNITS, "derivative-constant-units"}, - {PROP_DESCRIPTION, "description"}, - {PROP_DESCRIPTION_OF_HALT, "description-of-halt"}, - {PROP_DEVICE_ADDRESS_BINDING, "device-address-binding"}, - {PROP_DEVICE_TYPE, "device-type"}, - {PROP_EFFECTIVE_PERIOD, "effective-period"}, - {PROP_ELAPSED_ACTIVE_TIME, "elapsed-active-time"}, - {PROP_ERROR_LIMIT, "error-limit"}, - {PROP_EVENT_ENABLE, "event-enable"}, - {PROP_EVENT_STATE, "event-state"}, - {PROP_EVENT_TYPE, "event-type"}, - {PROP_EXCEPTION_SCHEDULE, "exception-schedule"}, - {PROP_FAULT_VALUES, "fault-values"}, - {PROP_FEEDBACK_VALUE, "feedback-value"}, - {PROP_FILE_ACCESS_METHOD, "file-access-method"}, - {PROP_FILE_SIZE, "file-size"}, - {PROP_FILE_TYPE, "file-type"}, - {PROP_FIRMWARE_REVISION, - "firmware-revision"}, /* VTS wants "revision", not "version" */ - {PROP_HIGH_LIMIT, "high-limit"}, - {PROP_INACTIVE_TEXT, "inactive-text"}, - {PROP_IN_PROCESS, "in-process"}, - {PROP_INSTANCE_OF, "instance-of"}, - {PROP_INTEGRAL_CONSTANT, "integral-constant"}, - {PROP_INTEGRAL_CONSTANT_UNITS, "integral-constant-units"}, - {PROP_ISSUE_CONFIRMED_NOTIFICATIONS, "issue-confirmednotifications"}, - {PROP_LIMIT_ENABLE, "limit-enable"}, - {PROP_LIST_OF_GROUP_MEMBERS, "list-of-group-members"}, - {PROP_LIST_OF_OBJECT_PROPERTY_REFERENCES, - "list-of-object-property-references"}, - {PROP_LIST_OF_SESSION_KEYS, "list-of-session-keys"}, - {PROP_LOCAL_DATE, "local-date"}, - {PROP_LOCAL_TIME, "local-time"}, - {PROP_LOCATION, "location"}, - {PROP_LOW_LIMIT, "low-limit"}, - {PROP_MANIPULATED_VARIABLE_REFERENCE, "manipulated-variable-reference"}, - {PROP_MAXIMUM_OUTPUT, "maximum-output"}, - {PROP_MAX_APDU_LENGTH_ACCEPTED, "max-apdu-length-accepted"}, - {PROP_MAX_INFO_FRAMES, "max-info-frames"}, - {PROP_MAX_MASTER, "max-master"}, - {PROP_MAX_PRES_VALUE, "max-pres-value"}, - {PROP_MINIMUM_OFF_TIME, "minimum-off-time"}, - {PROP_MINIMUM_ON_TIME, "minimum-on-time"}, - {PROP_MINIMUM_OUTPUT, "minimum-output"}, - {PROP_MIN_PRES_VALUE, "min-pres-value"}, - {PROP_MODEL_NAME, "model-name"}, - {PROP_MODIFICATION_DATE, "modification-date"}, - {PROP_NOTIFY_TYPE, "notify-type"}, - {PROP_NUMBER_OF_APDU_RETRIES, "number-of-APDU-retries"}, - {PROP_NUMBER_OF_STATES, "number-of-states"}, - {PROP_OBJECT_IDENTIFIER, "object-identifier"}, - {PROP_OBJECT_LIST, "object-list"}, - {PROP_OBJECT_NAME, "object-name"}, - {PROP_OBJECT_PROPERTY_REFERENCE, "object-property-reference"}, - {PROP_OBJECT_TYPE, "object-type"}, - {PROP_OPTIONAL, "optional"}, - {PROP_OUT_OF_SERVICE, "out-of-service"}, - {PROP_OUTPUT_UNITS, "output-units"}, - {PROP_EVENT_PARAMETERS, "event-parameters"}, - {PROP_POLARITY, "polarity"}, - {PROP_PRESENT_VALUE, "present-value"}, - {PROP_PRIORITY, "priority"}, - {PROP_PRIORITY_ARRAY, "priority-array"}, - {PROP_PRIORITY_FOR_WRITING, "priority-for-writing"}, - {PROP_PROCESS_IDENTIFIER, "process-identifier"}, - {PROP_PROGRAM_CHANGE, "program-change"}, - {PROP_PROGRAM_LOCATION, "program-location"}, - {PROP_PROGRAM_STATE, "program-state"}, - {PROP_PROPORTIONAL_CONSTANT, "proportional-constant"}, - {PROP_PROPORTIONAL_CONSTANT_UNITS, "proportional-constant-units"}, - {PROP_PROTOCOL_CONFORMANCE_CLASS, "protocol-conformance-class"}, - {PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED, "protocol-object-types-supported"}, - {PROP_PROTOCOL_SERVICES_SUPPORTED, "protocol-services-supported"}, - {PROP_PROTOCOL_VERSION, "protocol-version"}, - {PROP_READ_ONLY, "read-only"}, - {PROP_REASON_FOR_HALT, "reason-for-halt"}, - {PROP_RECIPIENT, "recipient"}, - {PROP_RECIPIENT_LIST, "recipient-list"}, - {PROP_RELIABILITY, "reliability"}, - {PROP_RELINQUISH_DEFAULT, "relinquish-default"}, - {PROP_REQUIRED, "required"}, - {PROP_RESOLUTION, "resolution"}, - {PROP_SEGMENTATION_SUPPORTED, "segmentation-supported"}, - {PROP_SETPOINT, "setpoint"}, - {PROP_SETPOINT_REFERENCE, "setpoint-reference"}, - {PROP_STATE_TEXT, "state-text"}, - {PROP_STATUS_FLAGS, "status-flags"}, - {PROP_SYSTEM_STATUS, "system-status"}, - {PROP_TIME_DELAY, "time-delay"}, - {PROP_TIME_OF_ACTIVE_TIME_RESET, "time-of-active-time-reset"}, - {PROP_TIME_OF_STATE_COUNT_RESET, "time-of-state-count-reset"}, - {PROP_TIME_SYNCHRONIZATION_RECIPIENTS, "time-synchronization-recipients"}, - {PROP_UNITS, "units"}, - {PROP_UPDATE_INTERVAL, "update-interval"}, - {PROP_UTC_OFFSET, "utc-offset"}, - {PROP_VENDOR_IDENTIFIER, "vendor-identifier"}, - {PROP_VENDOR_NAME, "vendor-name"}, - {PROP_VT_CLASSES_SUPPORTED, "vt-classes-supported"}, - {PROP_WEEKLY_SCHEDULE, "weekly-schedule"}, - {PROP_ATTEMPTED_SAMPLES, "attempted-samples"}, - {PROP_AVERAGE_VALUE, "average-value"}, - {PROP_BUFFER_SIZE, "buffer-size"}, - {PROP_CLIENT_COV_INCREMENT, "client-cov-increment"}, - {PROP_COV_RESUBSCRIPTION_INTERVAL, "cov-resubscription-interval"}, - {PROP_CURRENT_NOTIFY_TIME, "current-notify-time"}, - {PROP_EVENT_TIME_STAMPS, "event-time-stamps"}, - {PROP_LOG_BUFFER, "log-buffer"}, - {PROP_LOG_DEVICE_OBJECT_PROPERTY, "log-device-object-property"}, - {PROP_ENABLE, "enable"}, - {PROP_LOG_INTERVAL, "log-interval"}, - {PROP_MAXIMUM_VALUE, "maximum-value"}, - {PROP_MINIMUM_VALUE, "minimum-value"}, - {PROP_NOTIFICATION_THRESHOLD, "notification-threshold"}, - {PROP_PREVIOUS_NOTIFY_TIME, "previous-notify-time"}, - {PROP_PROTOCOL_REVISION, "protocol-revision"}, - {PROP_RECORDS_SINCE_NOTIFICATION, "records-since-notification"}, - {PROP_RECORD_COUNT, "record-count"}, - {PROP_START_TIME, "start-time"}, - {PROP_STOP_TIME, "stop-time"}, - {PROP_STOP_WHEN_FULL, "stop-when-full"}, - {PROP_TOTAL_RECORD_COUNT, "total-record-count"}, - {PROP_VALID_SAMPLES, "valid-samples"}, - {PROP_WINDOW_INTERVAL, "window-interval"}, - {PROP_WINDOW_SAMPLES, "window-samples"}, - {PROP_MAXIMUM_VALUE_TIMESTAMP, "maximum-value-timestamp"}, - {PROP_MINIMUM_VALUE_TIMESTAMP, "minimum-value-timestamp"}, - {PROP_VARIANCE_VALUE, "variance-value"}, - {PROP_ACTIVE_COV_SUBSCRIPTIONS, "active-cov-subscriptions"}, - {PROP_BACKUP_FAILURE_TIMEOUT, "backup-failure-timeout"}, - {PROP_CONFIGURATION_FILES, "configuration-files"}, - {PROP_DATABASE_REVISION, "database-revision"}, - {PROP_DIRECT_READING, "direct-reading"}, - {PROP_LAST_RESTORE_TIME, "last-restore-time"}, - {PROP_MAINTENANCE_REQUIRED, "maintenance-required"}, - {PROP_MEMBER_OF, "member-of"}, - {PROP_MODE, "mode"}, - {PROP_OPERATION_EXPECTED, "operation-expected"}, - {PROP_SETTING, "setting"}, - {PROP_SILENCED, "silenced"}, - {PROP_TRACKING_VALUE, "tracking-value"}, - {PROP_ZONE_MEMBERS, "zone-members"}, - {PROP_LIFE_SAFETY_ALARM_VALUES, "life-safety-alarm-values"}, - {PROP_MAX_SEGMENTS_ACCEPTED, "max-segments-accepted"}, - {PROP_PROFILE_NAME, "profile-name"}, - {PROP_AUTO_SLAVE_DISCOVERY, "auto-slave-discovery"}, - {PROP_MANUAL_SLAVE_ADDRESS_BINDING, "manual-slave-address-binding"}, - {PROP_SLAVE_ADDRESS_BINDING, "slave-address-binding"}, - {PROP_SLAVE_PROXY_ENABLE, "slave-proxy-enable"}, - {PROP_LAST_NOTIFY_RECORD, "last-notify-record"}, - {PROP_SCHEDULE_DEFAULT, "schedule-default"}, - {PROP_ACCEPTED_MODES, "accepted-modes"}, - {PROP_ADJUST_VALUE, "adjust-value"}, - {PROP_COUNT, "count"}, - {PROP_COUNT_BEFORE_CHANGE, "count-before-change"}, - {PROP_COUNT_CHANGE_TIME, "count-change-time"}, - {PROP_COV_PERIOD, "COV-period"}, - {PROP_INPUT_REFERENCE, "input-reference"}, - {PROP_LIMIT_MONITORING_INTERVAL, "limit-monitoring-interval"}, - {PROP_LOGGING_OBJECT, "logging-object"}, - {PROP_LOGGING_RECORD, "logging-record"}, - {PROP_PRESCALE, "prescale"}, - {PROP_PULSE_RATE, "pulse-rate"}, - {PROP_SCALE, "scale"}, - {PROP_SCALE_FACTOR, "scale-factor"}, - {PROP_UPDATE_TIME, "update-time"}, - {PROP_VALUE_BEFORE_CHANGE, "value-before-change"}, - {PROP_VALUE_SET, "value-set"}, - {PROP_VALUE_CHANGE_TIME, "value-change-time"}, - {PROP_ALIGN_INTERVALS, "align-intervals"}, - {PROP_INTERVAL_OFFSET, "interval-offset"}, - {PROP_LAST_RESTART_REASON, "last-restart-reason"}, - {PROP_LOGGING_TYPE, "logging-type"}, - {PROP_TIME_OF_DEVICE_RESTART, "time-of-device-restart"}, - {PROP_TIME_SYNCHRONIZATION_INTERVAL, "time-synchronization-interval"}, - {PROP_TRIGGER, "trigger"}, - {PROP_UTC_TIME_SYNCHRONIZATION_RECIPIENTS, - "utc-time-synchronization-recipients"}, - {PROP_NODE_SUBTYPE, "node-subtype"}, - {PROP_NODE_TYPE, "node-type"}, - {PROP_STRUCTURED_OBJECT_LIST, "structured-object-list"}, - {PROP_SUBORDINATE_ANNOTATIONS, "subordinate-annotations"}, - {PROP_SUBORDINATE_LIST, "subordinate-list"}, - {PROP_ACTUAL_SHED_LEVEL, "actual-shed-level"}, - {PROP_DUTY_WINDOW, "duty-window"}, - {PROP_EXPECTED_SHED_LEVEL, "expected-shed-level"}, - {PROP_FULL_DUTY_BASELINE, "full-duty-baseline"}, - {PROP_REQUESTED_SHED_LEVEL, "requested-shed-level"}, - {PROP_SHED_DURATION, "shed-duration"}, - {PROP_SHED_LEVEL_DESCRIPTIONS, "shed-level-descriptions"}, - {PROP_SHED_LEVELS, "shed-levels"}, - {PROP_STATE_DESCRIPTION, "state-description"}, - {PROP_DOOR_ALARM_STATE, "door-alarm-state"}, - {PROP_DOOR_EXTENDED_PULSE_TIME, "door-extended-pulse-time"}, - {PROP_DOOR_MEMBERS, "door-members"}, - {PROP_DOOR_OPEN_TOO_LONG_TIME, "door-open-too-long-time"}, - {PROP_DOOR_PULSE_TIME, "door-pulse-time"}, - {PROP_DOOR_STATUS, "door-status"}, - {PROP_DOOR_UNLOCK_DELAY_TIME, "door-unlock-delay-time"}, - {PROP_LOCK_STATUS, "lock-status"}, - {PROP_MASKED_ALARM_VALUES, "masked-alarm-values"}, - {PROP_SECURED_STATUS, "secured-status"}, - {PROP_ABSENTEE_LIMIT, "absentee-limit"}, - {PROP_ACCESS_ALARM_EVENTS, "access-alarm-events"}, - {PROP_ACCESS_DOORS, "access-doors"}, - {PROP_ACCESS_EVENT, "access-event"}, - {PROP_ACCESS_EVENT_AUTHENTICATION_FACTOR, - "access-event-authentication-factor"}, - {PROP_ACCESS_EVENT_CREDENTIAL, "access-event-credential"}, - {PROP_ACCESS_EVENT_TIME, "access-event-time"}, - {PROP_ACCESS_TRANSACTION_EVENTS, "access-transaction-events"}, - {PROP_ACCOMPANIMENT, "accompaniment"}, - {PROP_ACCOMPANIMENT_TIME, "accompaniment-time"}, - {PROP_ACTIVATION_TIME, "activation-time"}, - {PROP_ACTIVE_AUTHENTICATION_POLICY, "active-authentication-policy"}, - {PROP_ASSIGNED_ACCESS_RIGHTS, "assigned-access-rights"}, - {PROP_AUTHENTICATION_FACTORS, "authentication-factors"}, - {PROP_AUTHENTICATION_POLICY_LIST, "authentication-policy-list"}, - {PROP_AUTHENTICATION_POLICY_NAMES, "authentication-policy-names"}, - {PROP_AUTHENTICATION_STATUS, "authentication-status"}, - {PROP_AUTHORIZATION_MODE, "authorization-mode"}, - {PROP_BELONGS_TO, "belongs-to"}, - {PROP_CREDENTIAL_DISABLE, "credential-disable"}, - {PROP_CREDENTIAL_STATUS, "credential-status"}, - {PROP_CREDENTIALS, "credentials"}, - {PROP_CREDENTIALS_IN_ZONE, "credentials-in-zone"}, - {PROP_DAYS_REMAINING, "days-remaining"}, - {PROP_ENTRY_POINTS, "entry-points"}, - {PROP_EXIT_POINTS, "exit-points"}, - {PROP_EXPIRATION_TIME, "expiration-time"}, - {PROP_EXTENDED_TIME_ENABLE, "extended-time-enable"}, - {PROP_FAILED_ATTEMPT_EVENTS, "failed-attempt-events"}, - {PROP_FAILED_ATTEMPTS, "failed-attempts"}, - {PROP_FAILED_ATTEMPTS_TIME, "failed-attempts-time"}, - {PROP_LAST_ACCESS_EVENT, "last-access-event"}, - {PROP_LAST_ACCESS_POINT, "last-access-point"}, - {PROP_LAST_CREDENTIAL_ADDED, "last-credential-added"}, - {PROP_LAST_CREDENTIAL_ADDED_TIME, "last-credential-added-time"}, - {PROP_LAST_CREDENTIAL_REMOVED, "last-credential-removed"}, - {PROP_LAST_CREDENTIAL_REMOVED_TIME, "last-credential-removed-time"}, - {PROP_LAST_USE_TIME, "last-use-time"}, - {PROP_LOCKOUT, "lockout"}, - {PROP_LOCKOUT_RELINQUISH_TIME, "lockout-relinquish-time"}, - {PROP_MASTER_EXEMPTION, "master-exemption"}, - {PROP_MAX_FAILED_ATTEMPTS, "max-failed-attempts"}, - {PROP_MEMBERS, "members"}, - {PROP_MUSTER_POINT, "muster-point"}, - {PROP_NEGATIVE_ACCESS_RULES, "negative-access-rules"}, - {PROP_NUMBER_OF_AUTHENTICATION_POLICIES, - "number-of-authentication-policies"}, - {PROP_OCCUPANCY_COUNT, "occupancy-count"}, - {PROP_OCCUPANCY_COUNT_ADJUST, "occupancy-count-adjust"}, - {PROP_OCCUPANCY_COUNT_ENABLE, "occupancy-count-enable"}, - {PROP_OCCUPANCY_EXEMPTION, "occupancy-exemption"}, - {PROP_OCCUPANCY_LOWER_LIMIT, "occupancy-lower-limit"}, - {PROP_OCCUPANCY_LOWER_LIMIT_ENFORCED, "occupancy-lower-limit-enforced"}, - {PROP_OCCUPANCY_STATE, "occupancy-state"}, - {PROP_OCCUPANCY_UPPER_LIMIT, "occupancy-upper-limit"}, - {PROP_OCCUPANCY_UPPER_LIMIT_ENFORCED, "occupancy-upper-limit-enforced"}, - {PROP_PASSBACK_EXEMPTION, "passback-exemption"}, - {PROP_PASSBACK_MODE, "passback-mode"}, - {PROP_PASSBACK_TIMEOUT, "passback-timeout"}, - {PROP_POSITIVE_ACCESS_RULES, "positive-access-rules"}, - {PROP_REASON_FOR_DISABLE, "reason-for-disable"}, - {PROP_SUPPORTED_FORMATS, "supported-formats"}, - {PROP_SUPPORTED_FORMAT_CLASSES, "supported-format-classes"}, - {PROP_THREAT_AUTHORITY, "threat-authority"}, - {PROP_THREAT_LEVEL, "threat-level"}, - {PROP_TRACE_FLAG, "trace-flag"}, - {PROP_TRANSACTION_NOTIFICATION_CLASS, "transaction-notification-class"}, - {PROP_USER_EXTERNAL_IDENTIFIER, "user-external-identifier"}, - {PROP_USER_INFORMATION_REFERENCE, "user-information-reference"}, - {PROP_USER_INFORMATION_REFERENCE, "user-information-reference"}, - {PROP_USER_NAME, "user-name"}, - {PROP_USER_TYPE, "user-type"}, - {PROP_USES_REMAINING, "uses-remaining"}, - {PROP_ZONE_FROM, "zone-from"}, - {PROP_ZONE_TO, "zone-to"}, - {PROP_VERIFICATION_TIME, "verification-time"}, - {PROP_BASE_DEVICE_SECURITY_POLICY, "base-device-security-policy"}, - {PROP_DISTRIBUTION_KEY_REVISION, "distribution-key-revision"}, - {PROP_DO_NOT_HIDE, "do-not-hide"}, - {PROP_KEY_SETS, "key-sets"}, - {PROP_LAST_KEY_SERVER, "last-key-server"}, - {PROP_NETWORK_ACCESS_SECURITY_POLICIES, "network-access-security-policies"}, - {PROP_PACKET_REORDER_TIME, "packet-reorder-time"}, - {PROP_SECURITY_PDU_TIMEOUT, "security-pdu-timeout"}, - {PROP_SECURITY_TIME_WINDOW, "security-time-window"}, - {PROP_SUPPORTED_SECURITY_ALGORITHM, "supported-security-algorithm"}, - {PROP_UPDATE_KEY_SET_TIMEOUT, "update-key-set-timeout"}, - {PROP_BACKUP_AND_RESTORE_STATE, "backup-and-restore-state"}, - {PROP_BACKUP_PREPARATION_TIME, "backup-preparation-time"}, - {PROP_RESTORE_COMPLETION_TIME, "restore-completion-time"}, - {PROP_RESTORE_PREPARATION_TIME, "restore-preparation-time"}, - {PROP_BIT_MASK, "bit-mask"}, - {PROP_BIT_TEXT, "bit-text"}, - {PROP_IS_UTC, "is-utc"}, - {PROP_GROUP_MEMBERS, "group-members"}, - {PROP_GROUP_MEMBER_NAMES, "group-member-names"}, - {PROP_MEMBER_STATUS_FLAGS, "member-status-flags"}, - {PROP_REQUESTED_UPDATE_INTERVAL, "requested-update-interval"}, - {PROP_COVU_PERIOD, "covu-period"}, - {PROP_COVU_RECIPIENTS, "covu-recipients"}, - {PROP_EVENT_MESSAGE_TEXTS, "event-message-texts"}, - {PROP_EVENT_MESSAGE_TEXTS_CONFIG, "event-message-texts-config"}, - {PROP_EVENT_DETECTION_ENABLE, "event-detection-enable"}, - {PROP_EVENT_ALGORITHM_INHIBIT, "event-algorithm-inhibit"}, - {PROP_EVENT_ALGORITHM_INHIBIT_REF, "event-algorithm-inhibit-ref"}, - {PROP_TIME_DELAY_NORMAL, "time-delay-normal"}, - {PROP_RELIABILITY_EVALUATION_INHIBIT, "reliability-evaluation-inhibit"}, - {PROP_FAULT_PARAMETERS, "fault-parameters"}, - {PROP_FAULT_TYPE, "fault-type"}, - {PROP_LOCAL_FORWARDING_ONLY, "local-forwarding-only"}, - {PROP_PROCESS_IDENTIFIER_FILTER, "process-identifier-filter"}, - {PROP_SUBSCRIBED_RECIPIENTS, "subscribed-recipients"}, - {PROP_PORT_FILTER, "port-filter"}, - {PROP_AUTHORIZATION_EXEMPTIONS, "authorization-exemptions"}, - {PROP_ALLOW_GROUP_DELAY_INHIBIT, "allow-group-delay-inhibit"}, - {PROP_CHANNEL_NUMBER, "channel-number"}, - {PROP_CONTROL_GROUPS, "control-groups"}, - {PROP_EXECUTION_DELAY, "execution-delay"}, - {PROP_LAST_PRIORITY, "last-priority"}, - {PROP_WRITE_STATUS, "write-status"}, - {PROP_PROPERTY_LIST, "property-list"}, - {PROP_SERIAL_NUMBER, "serial-number"}, - {PROP_BLINK_WARN_ENABLE, "blink-warn-enable"}, - {PROP_DEFAULT_FADE_TIME, "default-fade-time"}, - {PROP_DEFAULT_RAMP_RATE, "default-ramp-rate"}, - {PROP_DEFAULT_STEP_INCREMENT, "default-step-increment"}, - {PROP_EGRESS_TIME, "egress-time"}, - {PROP_IN_PROGRESS, "in-progress"}, - {PROP_INSTANTANEOUS_POWER, "instantaneous-power"}, - {PROP_LIGHTING_COMMAND, "lighting-command"}, - {PROP_LIGHTING_COMMAND_DEFAULT_PRIORITY, - "lighting-command-default-priority"}, - {PROP_MAX_ACTUAL_VALUE, "max-actual-value"}, - {PROP_MIN_ACTUAL_VALUE, "min-actual-value"}, - {PROP_POWER, "power"}, - {PROP_TRANSITION, "transition"}, - {PROP_EGRESS_ACTIVE, "egress-active"}, - {PROP_INTERFACE_VALUE, "inteface-value"}, - {PROP_FAULT_HIGH_LIMIT, "fault-high-limit"}, - {PROP_FAULT_LOW_LIMIT, "fault-low-limit"}, - {PROP_LOW_DIFF_LIMIT, "low-diff-limit"}, - {PROP_STRIKE_COUNT, "strike-count"}, - {PROP_TIME_OF_STRIKE_COUNT_RESET, "strike-count"}, - {PROP_DEFAULT_TIMEOUT, "default-timeout"}, - {PROP_INITIAL_TIMEOUT, "initial-timeout"}, - {PROP_LAST_STATE_CHANGE, "last-state-change"}, - {PROP_STATE_CHANGE_VALUES, "state-change-values"}, - {PROP_TIMER_RUNNING, "timer-running"}, - {PROP_TIMER_STATE, "timer-state"}, - {PROP_APDU_LENGTH, "apdu-length"}, - {PROP_IP_ADDRESS, "ip-address"}, - {PROP_IP_DEFAULT_GATEWAY, "ip-default-gateway"}, - {PROP_IP_DHCP_ENABLE, "ip-dhcp-enable"}, - {PROP_IP_DHCP_LEASE_TIME, "ip-dhcp-lease-time"}, - {PROP_IP_DHCP_LEASE_TIME_REMAINING, "ip-dhcp-lease-time-remaining"}, - {PROP_IP_DHCP_SERVER, "ip-dhcp-server"}, - {PROP_IP_DNS_SERVER, "ip-dns-server"}, - {PROP_BACNET_IP_GLOBAL_ADDRESS, "bacnet-ip-global-address"}, - {PROP_BACNET_IP_MODE, "bacnet-ip-mode"}, - {PROP_BACNET_IP_MULTICAST_ADDRESS, "bacnet-ip-multicast-address"}, - {PROP_BACNET_IP_NAT_TRAVERSAL, "bacnet-ip-nat-traversal"}, - {PROP_IP_SUBNET_MASK, "ip-subnet-mask"}, - {PROP_BACNET_IP_UDP_PORT, "bacnet-ip-udp-port"}, - {PROP_BBMD_ACCEPT_FD_REGISTRATIONS, "bbmd-accept-fd-registrations"}, - {PROP_BBMD_BROADCAST_DISTRIBUTION_TABLE, - "bbmd-broadcast-distribution-table"}, - {PROP_BBMD_FOREIGN_DEVICE_TABLE, "bbmd-foreign-device-table"}, - {PROP_CHANGES_PENDING, "changes-pending"}, - {PROP_COMMAND, "command"}, - {PROP_FD_BBMD_ADDRESS, "fd-bbmd-address"}, - {PROP_FD_SUBSCRIPTION_LIFETIME, "fd-subscription-lifetime"}, - {PROP_LINK_SPEED, "link-speed"}, - {PROP_LINK_SPEEDS, "link-speeds"}, - {PROP_LINK_SPEED_AUTONEGOTIATE, "link-speed-autonegotiate"}, - {PROP_MAC_ADDRESS, "mac-address"}, - {PROP_NETWORK_INTERFACE_NAME, "network-interface-name"}, - {PROP_NETWORK_NUMBER, "network-number"}, - {PROP_NETWORK_NUMBER_QUALITY, "network-number-quality"}, - {PROP_NETWORK_TYPE, "network-type"}, - {PROP_ROUTING_TABLE, "routing-table"}, - {PROP_VIRTUAL_MAC_ADDRESS_TABLE, "virtual-mac-address-table"}, - {PROP_COMMAND_TIME_ARRAY, "command-time-array"}, - {PROP_CURRENT_COMMAND_PRIORITY, "current-command-priority"}, - {PROP_LAST_COMMAND_TIME, "last-command-time"}, - {PROP_VALUE_SOURCE, "value-source"}, - {PROP_VALUE_SOURCE_ARRAY, "value-source-array"}, - {PROP_BACNET_IPV6_MODE, "bacnet-ipv6-mode"}, - {PROP_IPV6_ADDRESS, "ipv6-address"}, - {PROP_IPV6_PREFIX_LENGTH, "ipv6-prefix-length"}, - {PROP_BACNET_IPV6_UDP_PORT, "bacnet-ipv6-udp-port"}, - {PROP_IPV6_DEFAULT_GATEWAY, "ipv6-default-gateway"}, - {PROP_BACNET_IPV6_MULTICAST_ADDRESS, "bacnet-ipv6-multicast-address"}, - {PROP_IPV6_DNS_SERVER, "ipv6-dns-server"}, - {PROP_IPV6_AUTO_ADDRESSING_ENABLE, "ipv6-auto-addressing-enable"}, - {PROP_IPV6_DHCP_LEASE_TIME, "ipv6-dhcp-lease-time"}, - {PROP_IPV6_DHCP_LEASE_TIME_REMAINING, "ipv6-dhcp-lease-time-remaining"}, - {PROP_IPV6_DHCP_SERVER, "ipv6-dhcp-server"}, - {PROP_IPV6_ZONE_INDEX, "ipv6-zone-index"}, - {PROP_ASSIGNED_LANDING_CALLS, "assigned-landing-calls"}, - {PROP_CAR_ASSIGNED_DIRECTION, "car-assigned-direction"}, - {PROP_CAR_DOOR_COMMAND, "car-door-command"}, - {PROP_CAR_DOOR_STATUS, "car-door-status"}, - {PROP_CAR_DOOR_TEXT, "car-door-text"}, - {PROP_CAR_DOOR_ZONE, "car-door-zone"}, - {PROP_CAR_DRIVE_STATUS, "car-drive-status"}, - {PROP_CAR_LOAD, "car-load"}, - {PROP_CAR_LOAD_UNITS, "car-load-units"}, - {PROP_CAR_MODE, "car-mode"}, - {PROP_CAR_MOVING_DIRECTION, "car-moving-direction"}, - {PROP_CAR_POSITION, "car-position"}, - {PROP_ELEVATOR_GROUP, "elevator-group"}, - {PROP_ENERGY_METER, "energy-meter"}, - {PROP_ENERGY_METER_REF, "energy-meter-ref"}, - {PROP_ESCALATOR_MODE, "escalator-mode"}, - {PROP_FAULT_SIGNALS, "fault-signals"}, - {PROP_FLOOR_TEXT, "floor-text"}, - {PROP_GROUP_ID, "group-id"}, - {PROP_GROUP_MODE, "group-mode"}, - {PROP_HIGHER_DECK, "higher-deck"}, - {PROP_INSTALLATION_ID, "installation-id"}, - {PROP_LANDING_CALLS, "landing-calls"}, - {PROP_LANDING_CALL_CONTROL, "landing-call-control"}, - {PROP_LANDING_DOOR_STATUS, "landing-door-status"}, - {PROP_LOWER_DECK, "lower-deck"}, - {PROP_MACHINE_ROOM_ID, "machine-room-id"}, - {PROP_MAKING_CAR_CALL, "making-car-call"}, - {PROP_NEXT_STOPPING_FLOOR, "next-stopping-floor"}, - {PROP_OPERATION_DIRECTION, "operation-direction"}, - {PROP_PASSENGER_ALARM, "passenger-alarm"}, - {PROP_POWER_MODE, "power-mode"}, - {PROP_REGISTERED_CAR_CALL, "registered-car-call"}, - {PROP_ACTIVE_COV_MULTIPLE_SUBSCRIPTIONS, - "active-cov-multiple-subscriptions"}, - {PROP_PROTOCOL_LEVEL, "protocol-level"}, - {PROP_REFERENCE_PORT, "reference-port"}, - {PROP_DEPLOYED_PROFILE_LOCATION, "deployed-profile-location"}, - {PROP_PROFILE_LOCATION, "profile-location"}, - {PROP_TAGS, "tags"}, - {PROP_SUBORDINATE_NODE_TYPES, "subordinate-node-types"}, - {PROP_SUBORDINATE_TAGS, "subordinate-tags"}, - {PROP_SUBORDINATE_RELATIONSHIPS, "subordinate-relationships"}, - {PROP_DEFAULT_SUBORDINATE_RELATIONSHIP, "default-subordinate-relationship"}, - {PROP_REPRESENTS, "represents"}, - {0, NULL} - /* Enumerated values 0-511 are reserved for definition by ASHRAE. - Enumerated values 512-4194303 may be used by others subject to the - procedures and constraints described in Clause 23. */ -}; - -const char *bactext_property_name(unsigned index) -{ - return indtext_by_index_split_default(bacnet_property_names, index, 512, - ASHRAE_Reserved_String, - Vendor_Proprietary_String); -} - -const char *bactext_property_name_default(unsigned index, - const char *default_string) -{ - return indtext_by_index_default(bacnet_property_names, index, - default_string); -} - -unsigned bactext_property_id(const char *name) -{ - return indtext_by_istring_default(bacnet_property_names, name, 0); -} - -bool bactext_property_index(const char *search_name, unsigned *found_index) -{ - return indtext_by_istring(bacnet_property_names, search_name, found_index); -} - -INDTEXT_DATA bacnet_engineering_unit_names[] = { - {UNITS_SQUARE_METERS, "square-meters"}, - {UNITS_SQUARE_FEET, "square-feet"}, - {UNITS_MILLIAMPERES, "milliamperes"}, - {UNITS_AMPERES, "amperes"}, - {UNITS_OHMS, "ohms"}, - {UNITS_VOLTS, "volts"}, - {UNITS_KILOVOLTS, "kilovolts"}, - {UNITS_MEGAVOLTS, "megavolts"}, - {UNITS_VOLT_AMPERES, "volt-amperes"}, - {UNITS_KILOVOLT_AMPERES, "kilovolt-amperes"}, - {UNITS_MEGAVOLT_AMPERES, "megavolt-amperes"}, - {UNITS_VOLT_AMPERES_REACTIVE, "volt-amperes-reactive"}, - {UNITS_KILOVOLT_AMPERES_REACTIVE, "kilovolt-amperes-reactive"}, - {UNITS_MEGAVOLT_AMPERES_REACTIVE, "megavolt-amperes-reactive"}, - {UNITS_DEGREES_PHASE, "degrees-phase"}, - {UNITS_POWER_FACTOR, "power-factor"}, - {UNITS_JOULES, "joules"}, - {UNITS_KILOJOULES, "kilojoules"}, - {UNITS_WATT_HOURS, "watt-hours"}, - {UNITS_KILOWATT_HOURS, "kilowatt-hours"}, - {UNITS_BTUS, "btus"}, - {UNITS_THERMS, "therms"}, - {UNITS_TON_HOURS, "ton-hours"}, - {UNITS_JOULES_PER_KILOGRAM_DRY_AIR, "joules-per-kilogram-dry-air"}, - {UNITS_BTUS_PER_POUND_DRY_AIR, "btus-per-pound-dry-air"}, - {UNITS_CYCLES_PER_HOUR, "cycles-per-hour"}, - {UNITS_CYCLES_PER_MINUTE, "cycles-per-minute"}, - {UNITS_HERTZ, "hertz"}, - {UNITS_GRAMS_OF_WATER_PER_KILOGRAM_DRY_AIR, - "grams-of-water-per-kilogram-dry-air"}, - {UNITS_PERCENT_RELATIVE_HUMIDITY, "percent-relative-humidity"}, - {UNITS_MILLIMETERS, "millimeters"}, - {UNITS_METERS, "meters"}, - {UNITS_INCHES, "inches"}, - {UNITS_FEET, "feet"}, - {UNITS_WATTS_PER_SQUARE_FOOT, "watts-per-square-foot"}, - {UNITS_WATTS_PER_SQUARE_METER, "watts-per-square-meter"}, - {UNITS_LUMENS, "lumens"}, - {UNITS_LUXES, "luxes"}, - {UNITS_FOOT_CANDLES, "foot-candles"}, - {UNITS_KILOGRAMS, "kilograms"}, - {UNITS_POUNDS_MASS, "pounds-mass"}, - {UNITS_TONS, "tons"}, - {UNITS_KILOGRAMS_PER_SECOND, "kilograms-per-second"}, - {UNITS_KILOGRAMS_PER_MINUTE, "kilograms-per-minute"}, - {UNITS_KILOGRAMS_PER_HOUR, "kilograms-per-hour"}, - {UNITS_POUNDS_MASS_PER_MINUTE, "pounds-mass-per-minute"}, - {UNITS_POUNDS_MASS_PER_HOUR, "pounds-mass-per-hour"}, - {UNITS_WATTS, "watts"}, - {UNITS_KILOWATTS, "kilowatts"}, - {UNITS_MEGAWATTS, "megawatts"}, - {UNITS_BTUS_PER_HOUR, "btus-per-hour"}, - {UNITS_HORSEPOWER, "horsepower"}, - {UNITS_TONS_REFRIGERATION, "tons-refrigeration"}, - {UNITS_PASCALS, "pascals"}, - {UNITS_KILOPASCALS, "kilopascals"}, - {UNITS_BARS, "bars"}, - {UNITS_POUNDS_FORCE_PER_SQUARE_INCH, "pounds-force-per-square-inch"}, - {UNITS_CENTIMETERS_OF_WATER, "centimeters-of-water"}, - {UNITS_INCHES_OF_WATER, "inches-of-water"}, - {UNITS_MILLIMETERS_OF_MERCURY, "millimeters-of-mercury"}, - {UNITS_CENTIMETERS_OF_MERCURY, "centimeters-of-mercury"}, - {UNITS_INCHES_OF_MERCURY, "inches-of-mercury"}, - {UNITS_DEGREES_CELSIUS, "degrees-celsius"}, - {UNITS_DEGREES_KELVIN, "degrees-kelvin"}, - {UNITS_DEGREES_FAHRENHEIT, "degrees-fahrenheit"}, - {UNITS_DEGREE_DAYS_CELSIUS, "degree-days-celsius"}, - {UNITS_DEGREE_DAYS_FAHRENHEIT, "degree-days-fahrenheit"}, - {UNITS_YEARS, "years"}, - {UNITS_MONTHS, "months"}, - {UNITS_WEEKS, "weeks"}, - {UNITS_DAYS, "days"}, - {UNITS_HOURS, "hours"}, - {UNITS_MINUTES, "minutes"}, - {UNITS_SECONDS, "seconds"}, - {UNITS_METERS_PER_SECOND, "meters-per-second"}, - {UNITS_KILOMETERS_PER_HOUR, "kilometers-per-hour"}, - {UNITS_FEET_PER_SECOND, "feet-per-second"}, - {UNITS_FEET_PER_MINUTE, "feet-per-minute"}, - {UNITS_MILES_PER_HOUR, "miles-per-hour"}, - {UNITS_CUBIC_FEET, "cubic-feet"}, - {UNITS_CUBIC_METERS, "cubic-meters"}, - {UNITS_IMPERIAL_GALLONS, "imperial-gallons"}, - {UNITS_LITERS, "liters"}, - {UNITS_US_GALLONS, "us-gallons"}, - {UNITS_CUBIC_FEET_PER_MINUTE, "cubic-feet-per-minute"}, - {UNITS_CUBIC_METERS_PER_SECOND, "cubic-meters-per-second"}, - {UNITS_IMPERIAL_GALLONS_PER_MINUTE, "imperial-gallons-per-minute"}, - {UNITS_LITERS_PER_SECOND, "liters-per-second"}, - {UNITS_LITERS_PER_MINUTE, "liters-per-minute"}, - {UNITS_US_GALLONS_PER_MINUTE, "us-gallons-per-minute"}, - {UNITS_DEGREES_ANGULAR, "degrees-angular"}, - {UNITS_DEGREES_CELSIUS_PER_HOUR, "degrees-celsius-per-hour"}, - {UNITS_DEGREES_CELSIUS_PER_MINUTE, "degrees-celsius-per-minute"}, - {UNITS_DEGREES_FAHRENHEIT_PER_HOUR, "degrees-fahrenheit-per-hour"}, - {UNITS_DEGREES_FAHRENHEIT_PER_MINUTE, "degrees-fahrenheit-per-minute"}, - {UNITS_NO_UNITS, "no-units"}, - {UNITS_PARTS_PER_MILLION, "parts-per-million"}, - {UNITS_PARTS_PER_BILLION, "parts-per-billion"}, - {UNITS_PERCENT, "percent"}, - {UNITS_PERCENT_PER_SECOND, "percent-per-second"}, - {UNITS_PER_MINUTE, "per-minute"}, - {UNITS_PER_SECOND, "per-second"}, - {UNITS_PSI_PER_DEGREE_FAHRENHEIT, "psi-per-degree-fahrenheit"}, - {UNITS_RADIANS, "radians"}, - {UNITS_REVOLUTIONS_PER_MINUTE, "revolutions-per-minute"}, - {UNITS_CURRENCY1, "currency1"}, - {UNITS_CURRENCY2, "currency2"}, - {UNITS_CURRENCY3, "currency3"}, - {UNITS_CURRENCY4, "currency4"}, - {UNITS_CURRENCY5, "currency5"}, - {UNITS_CURRENCY6, "currency6"}, - {UNITS_CURRENCY7, "currency7"}, - {UNITS_CURRENCY8, "currency8"}, - {UNITS_CURRENCY9, "currency9"}, - {UNITS_CURRENCY10, "currency10"}, - {UNITS_SQUARE_INCHES, "square-inches"}, - {UNITS_SQUARE_CENTIMETERS, "square-centimeters"}, - {UNITS_BTUS_PER_POUND, "btus_per-pound"}, - {UNITS_CENTIMETERS, "centimeters"}, - {UNITS_POUNDS_MASS_PER_SECOND, "pounds-mass-per-second"}, - {UNITS_DELTA_DEGREES_FAHRENHEIT, "delta-degrees-fahrenheit"}, - {UNITS_DELTA_DEGREES_KELVIN, "delta-degrees-kelvin"}, - {UNITS_KILOHMS, "kilohms"}, - {UNITS_MEGOHMS, "megohms"}, - {UNITS_MILLIVOLTS, "millivolts"}, - {UNITS_KILOJOULES_PER_KILOGRAM, "kilojoules-per-kilogram"}, - {UNITS_MEGAJOULES, "megajoules"}, - {UNITS_JOULES_PER_DEGREE_KELVIN, "joules-per-degree-kelvin"}, - {UNITS_JOULES_PER_KILOGRAM_DEGREE_KELVIN, - "joules-per-kilogram-degree-kelvin"}, - {UNITS_KILOHERTZ, "kilohertz"}, - {UNITS_MEGAHERTZ, "megahertz"}, - {UNITS_PER_HOUR, "per-hour"}, - {UNITS_MILLIWATTS, "milliwatts"}, - {UNITS_HECTOPASCALS, "hectopascals"}, - {UNITS_MILLIBARS, "millibars"}, - {UNITS_CUBIC_METERS_PER_HOUR, "cubic-meters-per-hour"}, - {UNITS_LITERS_PER_HOUR, "liters-per-hour"}, - {UNITS_KW_HOURS_PER_SQUARE_METER, "kilowatt-hours-per-square-meter"}, - {UNITS_KW_HOURS_PER_SQUARE_FOOT, "kilowatt-hours-per-square-foot"}, - {UNITS_MEGAJOULES_PER_SQUARE_METER, "megajoules-per-square-meter"}, - {UNITS_MEGAJOULES_PER_SQUARE_FOOT, "megajoules-per-square-foot"}, - {UNITS_CUBIC_FEET_PER_SECOND, "cubic-feet-per-second"}, - {UNITS_WATTS_PER_SQUARE_METER_DEGREE_KELVIN, - "watts-per-square-meter-degree-kelvin"}, - {UNITS_PERCENT_OBSCURATION_PER_FOOT, "percent-obscuration-per-foot"}, - {UNITS_PERCENT_OBSCURATION_PER_METER, "percent-obscuration-per-meter"}, - {UNITS_MILLIOHMS, "milliohms"}, - {UNITS_MEGAWATT_HOURS, "megawatt-hours"}, - {UNITS_KILO_BTUS, "kilo-btus"}, - {UNITS_MEGA_BTUS, "mega-btus"}, - {UNITS_KILOJOULES_PER_KILOGRAM_DRY_AIR, "kilojoules-per-kilogram-dry-air"}, - {UNITS_MEGAJOULES_PER_KILOGRAM_DRY_AIR, "megajoules-per-kilogram-dry-air"}, - {UNITS_KILOJOULES_PER_DEGREE_KELVIN, "kilojoules-per-degree-Kelvin"}, - {UNITS_MEGAJOULES_PER_DEGREE_KELVIN, "megajoules-per-degree-Kelvin"}, - {UNITS_NEWTON, "newton"}, - {UNITS_GRAMS_PER_SECOND, "grams-per-second"}, - {UNITS_GRAMS_PER_MINUTE, "grams-per-minute"}, - {UNITS_TONS_PER_HOUR, "tons-per-hour"}, - {UNITS_KILO_BTUS_PER_HOUR, "kilo-btus-per-hour"}, - {UNITS_HUNDREDTHS_SECONDS, "hundredths-seconds"}, - {UNITS_MILLISECONDS, "milliseconds"}, - {UNITS_NEWTON_METERS, "newton-meters"}, - {UNITS_MILLIMETERS_PER_SECOND, "millimeters-per-second"}, - {UNITS_MILLIMETERS_PER_MINUTE, "millimeters-per-minute"}, - {UNITS_METERS_PER_MINUTE, "meters-per-minute"}, - {UNITS_METERS_PER_HOUR, "meters-per-hour"}, - {UNITS_CUBIC_METERS_PER_MINUTE, "cubic-meters-per-minute"}, - {UNITS_METERS_PER_SECOND_PER_SECOND, "meters-per-second-per-second"}, - {UNITS_AMPERES_PER_METER, "amperes-per-meter"}, - {UNITS_AMPERES_PER_SQUARE_METER, "amperes-per-square-meter"}, - {UNITS_AMPERE_SQUARE_METERS, "ampere-square-meters"}, - {UNITS_FARADS, "farads"}, - {UNITS_HENRYS, "henrys"}, - {UNITS_OHM_METERS, "ohm-meters"}, - {UNITS_SIEMENS, "siemens"}, - {UNITS_SIEMENS_PER_METER, "siemens-per-meter"}, - {UNITS_TESLAS, "teslas"}, - {UNITS_VOLTS_PER_DEGREE_KELVIN, "volts-per-degree-Kelvin"}, - {UNITS_VOLTS_PER_METER, "volts-per-meter"}, - {UNITS_WEBERS, "webers"}, - {UNITS_CANDELAS, "candelas"}, - {UNITS_CANDELAS_PER_SQUARE_METER, "candelas-per-square-meter"}, - {UNITS_DEGREES_KELVIN_PER_HOUR, "degrees-Kelvin-per-hour"}, - {UNITS_DEGREES_KELVIN_PER_MINUTE, "degrees-Kelvin-per-minute"}, - {UNITS_JOULE_SECONDS, "joule-seconds"}, - {UNITS_RADIANS_PER_SECOND, "radians-per-second"}, - {UNITS_SQUARE_METERS_PER_NEWTON, "square-meters-per-Newton"}, - {UNITS_KILOGRAMS_PER_CUBIC_METER, "kilograms-per-cubic-meter"}, - {UNITS_NEWTON_SECONDS, "newton-seconds"}, - {UNITS_NEWTONS_PER_METER, "newtons-per-meter"}, - {UNITS_WATTS_PER_METER_PER_DEGREE_KELVIN, - "watts-per-meter-per-degree-Kelvin"}, - {UNITS_PER_MILLE, "per-mille"}, - {UNITS_GRAMS_PER_GRAM, "grams-per-gram"}, - {UNITS_KILOGRAMS_PER_KILOGRAM, "kilograms-per-kilogram"}, - {UNITS_GRAMS_PER_KILOGRAM, "grams-per-kilogram"}, - {UNITS_MILLIGRAMS_PER_GRAM, "milligrams-per-gram"}, - {UNITS_MILLIGRAMS_PER_KILOGRAM, "milligrams-per-kilogram"}, - {UNITS_GRAMS_PER_MILLILITER, "grams-per-milliliter"}, - {UNITS_GRAMS_PER_LITER, "grams-per-liter"}, - {UNITS_MILLIGRAMS_PER_LITER, "milligrams-per-liter"}, - {UNITS_MICROGRAMS_PER_LITER, "micrograms-per-liter"}, - {UNITS_GRAMS_PER_CUBIC_METER, "grams-per-cubic-meter"}, - {UNITS_MILLIGRAMS_PER_CUBIC_METER, "milligrams-per-cubic-meter"}, - {UNITS_MICROGRAMS_PER_CUBIC_METER, "micrograms-per-cubic-meter"}, - {UNITS_NANOGRAMS_PER_CUBIC_METER, "nanograms-per-cubic-meter"}, - {UNITS_GRAMS_PER_CUBIC_CENTIMETER, "grams-per-cubic-centimeter"}, - {UNITS_BECQUERELS, "becquerels"}, - {UNITS_MEGABECQUERELS, "megabecquerels"}, - {UNITS_GRAY, "gray"}, - {UNITS_MILLIGRAY, "milligray"}, - {UNITS_MICROGRAY, "microgray"}, - {UNITS_SIEVERTS, "sieverts"}, - {UNITS_MILLISIEVERTS, "millisieverts"}, - {UNITS_MICROSIEVERTS, "microsieverts"}, - {UNITS_MICROSIEVERTS_PER_HOUR, "microsieverts-per-hour"}, - {UNITS_DECIBELS_A, "decibels-a"}, - {UNITS_NEPHELOMETRIC_TURBIDITY_UNIT, "nephelometric-turbidity-unit"}, - {UNITS_PH, "pH"}, - {UNITS_GRAMS_PER_SQUARE_METER, "grams-per-square-meter"}, - {UNITS_MINUTES_PER_DEGREE_KELVIN, "minutes-per-degree-kelvin"}, - {UNITS_OHM_METER_SQUARED_PER_METER, "ohm-meter-squared-per-meter"}, - {UNITS_AMPERE_SECONDS, "ampere-seconds"}, - {UNITS_VOLT_AMPERE_HOURS, "volt-ampere-hours"}, - {UNITS_KILOVOLT_AMPERE_HOURS, "kilovolt-ampere-hours"}, - {UNITS_MEGAVOLT_AMPERE_HOURS, "megavolt-ampere-hours"}, - {UNITS_VOLT_AMPERE_HOURS_REACTIVE, "volt-ampere-hours-reactive"}, - {UNITS_KILOVOLT_AMPERE_HOURS_REACTIVE, "kilovolt-ampere-hours-reactive"}, - {UNITS_MEGAVOLT_AMPERE_HOURS_REACTIVE, "megavolt-ampere-hours-reactive"}, - {UNITS_VOLT_SQUARE_HOURS, "volt-square-hours"}, - {UNITS_AMPERE_SQUARE_HOURS, "ampere-square-hours"}, - {UNITS_JOULE_PER_HOURS, "joule-per-hours"}, - {UNITS_CUBIC_FEET_PER_DAY, "cubic-feet-per-day"}, - {UNITS_CUBIC_METERS_PER_DAY, "cubic-meters-per-day"}, - {UNITS_WATT_HOURS_PER_CUBIC_METER, "watt-hours-per-cubic-meter"}, - {UNITS_JOULES_PER_CUBIC_METER, "joules-per-cubic-meter"}, - {UNITS_MOLE_PERCENT, "mole-percent"}, - {UNITS_PASCAL_SECONDS, "pascal-seconds"}, - {UNITS_MILLION_STANDARD_CUBIC_FEET_PER_MINUTE, - "million-standard-cubic-feet-per-minute"}, - {UNITS_STANDARD_CUBIC_FEET_PER_DAY, "standard-cubic-feet-per-day"}, - {UNITS_MILLION_STANDARD_CUBIC_FEET_PER_DAY, - "million-standard-cubic-feet-per-day"}, - {UNITS_THOUSAND_CUBIC_FEET_PER_DAY, "thousand-cubic-feet-per-day"}, - {UNITS_THOUSAND_STANDARD_CUBIC_FEET_PER_DAY, - "thousand-standard-cubic-feet-per-day"}, - {UNITS_POUNDS_MASS_PER_DAY, "pounds-mass-per-day"}, - {UNITS_MILLIREMS, "millirems"}, - {UNITS_MILLIREMS_PER_HOUR, "millirems-per-hour"}, - {0, NULL} - /* Enumerated values 0-255 are reserved for definition by ASHRAE. - Enumerated values 256-65535 may be used by others subject to - the procedures and constraints described in Clause 23. */ -}; - -const char *bactext_engineering_unit_name(unsigned index) -{ - return indtext_by_index_split_default(bacnet_engineering_unit_names, index, - 256, ASHRAE_Reserved_String, - Vendor_Proprietary_String); -} - -bool bactext_engineering_unit_index(const char *search_name, - unsigned *found_index) -{ - return indtext_by_istring(bacnet_engineering_unit_names, search_name, - found_index); -} - -INDTEXT_DATA bacnet_reject_reason_names[] = { - {REJECT_REASON_OTHER, "Other"}, - {REJECT_REASON_BUFFER_OVERFLOW, "Buffer Overflow"}, - {REJECT_REASON_INCONSISTENT_PARAMETERS, "Inconsistent Parameters"}, - {REJECT_REASON_INVALID_PARAMETER_DATA_TYPE, "Invalid Parameter Data Type"}, - {REJECT_REASON_INVALID_TAG, "Invalid Tag"}, - {REJECT_REASON_MISSING_REQUIRED_PARAMETER, "Missing Required Parameter"}, - {REJECT_REASON_PARAMETER_OUT_OF_RANGE, "Parameter Out of Range"}, - {REJECT_REASON_TOO_MANY_ARGUMENTS, "Too Many Arguments"}, - {REJECT_REASON_UNDEFINED_ENUMERATION, "Undefined Enumeration"}, - {REJECT_REASON_UNRECOGNIZED_SERVICE, "Unrecognized Service"}, - {REJECT_REASON_PROPRIETARY_FIRST, "Proprietary"}, - {0, NULL}}; - -const char *bactext_reject_reason_name(unsigned index) -{ - return indtext_by_index_split_default( - bacnet_reject_reason_names, index, REJECT_REASON_PROPRIETARY_FIRST, - ASHRAE_Reserved_String, Vendor_Proprietary_String); -} - -INDTEXT_DATA bacnet_abort_reason_names[] = { - {ABORT_REASON_OTHER, "Other"}, - {ABORT_REASON_BUFFER_OVERFLOW, "Buffer Overflow"}, - {ABORT_REASON_INVALID_APDU_IN_THIS_STATE, "Invalid APDU in this State"}, - {ABORT_REASON_PREEMPTED_BY_HIGHER_PRIORITY_TASK, - "Preempted by Higher Priority Task"}, - {ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, "Segmentation Not Supported"}, - {ABORT_REASON_PROPRIETARY_FIRST, "Proprietary"}, - {0, NULL}}; - -const char *bactext_abort_reason_name(unsigned index) -{ - return indtext_by_index_split_default( - bacnet_abort_reason_names, index, ABORT_REASON_PROPRIETARY_FIRST, - ASHRAE_Reserved_String, Vendor_Proprietary_String); -} - -INDTEXT_DATA bacnet_error_class_names[] = {{ERROR_CLASS_DEVICE, "device"}, - {ERROR_CLASS_OBJECT, "object"}, - {ERROR_CLASS_PROPERTY, "property"}, - {ERROR_CLASS_RESOURCES, "resources"}, - {ERROR_CLASS_SECURITY, "security"}, - {ERROR_CLASS_SERVICES, "services"}, - {ERROR_CLASS_VT, "vt"}, - {0, NULL}}; - -const char *bactext_error_class_name(unsigned index) -{ - return indtext_by_index_split_default( - bacnet_error_class_names, index, ERROR_CLASS_PROPRIETARY_FIRST, - ASHRAE_Reserved_String, Vendor_Proprietary_String); -} - -INDTEXT_DATA bacnet_error_code_names[] = { - {ERROR_CODE_OTHER, "other"}, - {ERROR_CODE_AUTHENTICATION_FAILED, "authentication-failed"}, - {ERROR_CODE_CHARACTER_SET_NOT_SUPPORTED, "character-set-not-supported"}, - {ERROR_CODE_CONFIGURATION_IN_PROGRESS, "configuration-in-progress"}, - {ERROR_CODE_DATATYPE_NOT_SUPPORTED, "datatype-not-supported"}, - {ERROR_CODE_DEVICE_BUSY, "device-busy"}, - {ERROR_CODE_DUPLICATE_NAME, "duplicate-name"}, - {ERROR_CODE_DUPLICATE_OBJECT_ID, "duplicate-object-id"}, - {ERROR_CODE_DYNAMIC_CREATION_NOT_SUPPORTED, - "dynamic-creation-not-supported"}, - {ERROR_CODE_FILE_ACCESS_DENIED, "file-access-denied"}, - {ERROR_CODE_INCOMPATIBLE_SECURITY_LEVELS, "incompatible-security-levels"}, - {ERROR_CODE_INCONSISTENT_PARAMETERS, "inconsistent-parameters"}, - {ERROR_CODE_INCONSISTENT_SELECTION_CRITERION, - "inconsistent-selection-criterion"}, - {ERROR_CODE_INVALID_ARRAY_INDEX, "invalid-array-index"}, - {ERROR_CODE_INVALID_CONFIGURATION_DATA, "invalid-configuration-data"}, - {ERROR_CODE_INVALID_DATA_TYPE, "invalid-data-type"}, - {ERROR_CODE_INVALID_FILE_ACCESS_METHOD, "invalid-file-access-method"}, - {ERROR_CODE_INVALID_FILE_START_POSITION, - "error-code-invalid-file-start-position"}, - {ERROR_CODE_INVALID_OPERATOR_NAME, "invalid-operator-name"}, - {ERROR_CODE_INVALID_PARAMETER_DATA_TYPE, "invalid-parameter-data-type"}, - {ERROR_CODE_INVALID_TIME_STAMP, "invalid-time-stamp"}, - {ERROR_CODE_KEY_GENERATION_ERROR, "key-generation-error"}, - {ERROR_CODE_MISSING_REQUIRED_PARAMETER, "missing-required-parameter"}, - {ERROR_CODE_NO_OBJECTS_OF_SPECIFIED_TYPE, "no-objects-of-specified-type"}, - {ERROR_CODE_NO_SPACE_FOR_OBJECT, "no-space-for-object"}, - {ERROR_CODE_NO_SPACE_TO_ADD_LIST_ELEMENT, "no-space-to-add-list-element"}, - {ERROR_CODE_NO_SPACE_TO_WRITE_PROPERTY, "no-space-to-write-property"}, - {ERROR_CODE_NO_VT_SESSIONS_AVAILABLE, "no-vt-sessions-available"}, - {ERROR_CODE_OBJECT_DELETION_NOT_PERMITTED, "object-deletion-not-permitted"}, - {ERROR_CODE_OBJECT_IDENTIFIER_ALREADY_EXISTS, - "object-identifier-already-exists"}, - {ERROR_CODE_OPERATIONAL_PROBLEM, "operational-problem"}, - {ERROR_CODE_OPTIONAL_FUNCTIONALITY_NOT_SUPPORTED, - "optional-functionality-not-supported"}, - {ERROR_CODE_PASSWORD_FAILURE, "password-failure"}, - {ERROR_CODE_PROPERTY_IS_NOT_A_LIST, "property-is-not-a-list"}, - {ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY, "property-is-not-an-array"}, - {ERROR_CODE_READ_ACCESS_DENIED, "read-access-denied"}, - {ERROR_CODE_SECURITY_NOT_SUPPORTED, "security-not-supported"}, - {ERROR_CODE_SERVICE_REQUEST_DENIED, "service-request-denied"}, - {ERROR_CODE_TIMEOUT, "timeout"}, - {ERROR_CODE_UNKNOWN_OBJECT, "unknown-object"}, - {ERROR_CODE_UNKNOWN_PROPERTY, "unknown-property"}, - {ERROR_CODE_RESERVED1, "reserved1"}, - {ERROR_CODE_UNKNOWN_VT_CLASS, "unknown-vt-class"}, - {ERROR_CODE_UNKNOWN_VT_SESSION, "unknown-vt-session"}, - {ERROR_CODE_UNSUPPORTED_OBJECT_TYPE, "unsupported-object-type"}, - {ERROR_CODE_VALUE_OUT_OF_RANGE, "value-out-of-range"}, - {ERROR_CODE_VT_SESSION_ALREADY_CLOSED, "vt-session-already-closed"}, - {ERROR_CODE_VT_SESSION_TERMINATION_FAILURE, - "vt-session-termination-failure"}, - {ERROR_CODE_WRITE_ACCESS_DENIED, "write-access-denied"}, - {ERROR_CODE_COV_SUBSCRIPTION_FAILED, "cov-subscription-failed"}, - {ERROR_CODE_NOT_COV_PROPERTY, "not-cov-property"}, - {ERROR_CODE_ABORT_BUFFER_OVERFLOW, "abort-buffer-overflow"}, - {ERROR_CODE_ABORT_INVALID_APDU_IN_THIS_STATE, - "abort-invalid-apdu-in-this-state"}, - {ERROR_CODE_ABORT_PREEMPTED_BY_HIGHER_PRIORITY_TASK, - "abort-preempted-by-higher-priority-task"}, - {ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED, - "abort-segmentation-not-supported"}, - {ERROR_CODE_ABORT_PROPRIETARY, "abort-proprietary"}, - {ERROR_CODE_ABORT_OTHER, "abort-other"}, - {ERROR_CODE_INVALID_TAG, "invalid-tag"}, - {ERROR_CODE_NETWORK_DOWN, "network-down"}, - {ERROR_CODE_REJECT_BUFFER_OVERFLOW, "reject-buffer-overflow"}, - {ERROR_CODE_REJECT_INCONSISTENT_PARAMETERS, - "reject-inconsistent-parameters"}, - {ERROR_CODE_REJECT_INVALID_PARAMETER_DATA_TYPE, - "reject-invalid-parameter-data-type"}, - {ERROR_CODE_REJECT_INVALID_TAG, "reject-invalid-tag"}, - {ERROR_CODE_REJECT_MISSING_REQUIRED_PARAMETER, - "reject-missing-required-parameter"}, - {ERROR_CODE_REJECT_PARAMETER_OUT_OF_RANGE, "reject-parameter-out-of-range"}, - {ERROR_CODE_REJECT_TOO_MANY_ARGUMENTS, "reject-too-many-arguments"}, - {ERROR_CODE_REJECT_UNDEFINED_ENUMERATION, "reject-undefined-enumeration"}, - {ERROR_CODE_REJECT_UNRECOGNIZED_SERVICE, "reject-unrecognized-service"}, - {ERROR_CODE_REJECT_PROPRIETARY, "reject-proprietary"}, - {ERROR_CODE_REJECT_OTHER, "reject-other"}, - {ERROR_CODE_UNKNOWN_DEVICE, "unknown-device"}, - {ERROR_CODE_UNKNOWN_ROUTE, "unknown-route"}, - {ERROR_CODE_VALUE_NOT_INITIALIZED, "value-not-initialized"}, - {ERROR_CODE_INVALID_EVENT_STATE, "invalid-event-state"}, - {ERROR_CODE_NO_ALARM_CONFIGURED, "no-alarm-configured"}, - {ERROR_CODE_LOG_BUFFER_FULL, "log-buffer-full"}, - {ERROR_CODE_LOGGED_VALUE_PURGED, "logged-value-purged"}, - {ERROR_CODE_NO_PROPERTY_SPECIFIED, "no-property-specified"}, - {ERROR_CODE_NOT_CONFIGURED_FOR_TRIGGERED_LOGGING, - "not-configured-for-triggered-logging"}, - {ERROR_CODE_UNKNOWN_SUBSCRIPTION, "unknown-subscription"}, - {ERROR_CODE_PARAMETER_OUT_OF_RANGE, "parameter-out-of-range"}, - {ERROR_CODE_LIST_ELEMENT_NOT_FOUND, "list-element-not-found"}, - {ERROR_CODE_BUSY, "busy"}, - {ERROR_CODE_COMMUNICATION_DISABLED, "communication-disabled"}, - {ERROR_CODE_COMMUNICATION_DISABLED, "access-denied"}, - {ERROR_CODE_SUCCESS, "success"}, - {ERROR_CODE_ACCESS_DENIED, "access-denied"}, - {ERROR_CODE_BAD_DESTINATION_ADDRESS, "bad-destination-address"}, - {ERROR_CODE_BAD_DESTINATION_DEVICE_ID, "bad-destination-device-id"}, - {ERROR_CODE_BAD_SIGNATURE, "bad-signature"}, - {ERROR_CODE_BAD_SOURCE_ADDRESS, "bad-source-address"}, - {ERROR_CODE_BAD_TIMESTAMP, "bad-timestamp"}, - {ERROR_CODE_CANNOT_USE_KEY, "cannot-use-key"}, - {ERROR_CODE_CANNOT_VERIFY_MESSAGE_ID, "cannot-verify-message-id"}, - {ERROR_CODE_CORRECT_KEY_REVISION, "correct-key-revision"}, - {ERROR_CODE_DESTINATION_DEVICE_ID_REQUIRED, - "destination-device-id-required"}, - {ERROR_CODE_DUPLICATE_MESSAGE, "duplicate-message"}, - {ERROR_CODE_ENCRYPTION_NOT_CONFIGURED, "encryption-not-configured"}, - {ERROR_CODE_ENCRYPTION_REQUIRED, "encryption-required"}, - {ERROR_CODE_INCORRECT_KEY, "incorrect-key"}, - {ERROR_CODE_INVALID_KEY_DATA, "invalid-key-data"}, - {ERROR_CODE_KEY_UPDATE_IN_PROGRESS, "key-update-in-progress"}, - {ERROR_CODE_MALFORMED_MESSAGE, "malformed-message"}, - {ERROR_CODE_NOT_KEY_SERVER, "not-key-server"}, - {ERROR_CODE_SECURITY_NOT_CONFIGURED, "security-not-configured"}, - {ERROR_CODE_SOURCE_SECURITY_REQUIRED, "source-security-required"}, - {ERROR_CODE_TOO_MANY_KEYS, "too-many-keys"}, - {ERROR_CODE_UNKNOWN_AUTHENTICATION_TYPE, "unknown-authentication-type"}, - {ERROR_CODE_UNKNOWN_KEY, "unknown-key"}, - {ERROR_CODE_UNKNOWN_KEY_REVISION, "unknown-key-revision"}, - {ERROR_CODE_UNKNOWN_SOURCE_MESSAGE, "unknown-source-message"}, - {ERROR_CODE_NOT_ROUTER_TO_DNET, "not-router-to-dnet"}, - {ERROR_CODE_ROUTER_BUSY, "router-busy"}, - {ERROR_CODE_UNKNOWN_NETWORK_MESSAGE, "unknown-network-message"}, - {ERROR_CODE_MESSAGE_TOO_LONG, "message-too-long"}, - {ERROR_CODE_SECURITY_ERROR, "security-error"}, - {ERROR_CODE_ADDRESSING_ERROR, "addressing-error"}, - {ERROR_CODE_WRITE_BDT_FAILED, "write-bdt-failed"}, - {ERROR_CODE_READ_BDT_FAILED, "read-bdt-failed"}, - {ERROR_CODE_REGISTER_FOREIGN_DEVICE_FAILED, - "register-foreign-device-failed"}, - {ERROR_CODE_READ_FDT_FAILED, "read-fdt-failed"}, - {ERROR_CODE_DELETE_FDT_ENTRY_FAILED, "delete-fdt-entry-failed"}, - {ERROR_CODE_DISTRIBUTE_BROADCAST_FAILED, "distribute-broadcast-failed"}, - {ERROR_CODE_UNKNOWN_FILE_SIZE, "unknown-file-size"}, - {ERROR_CODE_ABORT_APDU_TOO_LONG, "abort-apdu-too-long"}, - {ERROR_CODE_ABORT_APPLICATION_EXCEEDED_REPLY_TIME, - "abort-application-exceeded-reply-time"}, - {ERROR_CODE_ABORT_OUT_OF_RESOURCES, "abort-out-of-resources"}, - {ERROR_CODE_ABORT_TSM_TIMEOUT, "abort-tsm-timeout"}, - {ERROR_CODE_ABORT_WINDOW_SIZE_OUT_OF_RANGE, - "abort-window-size-out-of-range"}, - {ERROR_CODE_FILE_FULL, "file-full"}, - {ERROR_CODE_INCONSISTENT_CONFIGURATION, "inconsistent-configuration"}, - {ERROR_CODE_INCONSISTENT_OBJECT_TYPE, "inconsistent-object-type"}, - {ERROR_CODE_INTERNAL_ERROR, "internal-error"}, - {ERROR_CODE_NOT_CONFIGURED, "not-configured"}, - {ERROR_CODE_OUT_OF_MEMORY, "out-of-memory"}, - {ERROR_CODE_VALUE_TOO_LONG, "value-too-long"}, - {ERROR_CODE_ABORT_INSUFFICIENT_SECURITY, "abort-insufficient-security"}, - {ERROR_CODE_ABORT_SECURITY_ERROR, "abort-security-error"}, - {0, NULL}}; - -const char *bactext_error_code_name(unsigned index) -{ - return indtext_by_index_split_default( - bacnet_error_code_names, index, ERROR_CODE_PROPRIETARY_FIRST, - ASHRAE_Reserved_String, Vendor_Proprietary_String); -} - -INDTEXT_DATA bacnet_month_names[] = { - {1, "January"}, {2, "February"}, {3, "March"}, - {4, "April"}, {5, "May"}, {6, "June"}, - {7, "July"}, {8, "August"}, {9, "September"}, - {10, "October"}, {11, "November"}, {12, "December"}, - {13, "Odd Months"}, {14, "Even Months"}, {255, "Any Month"}, - {0, NULL}}; - -const char *bactext_month_name(unsigned index) -{ - return indtext_by_index_default(bacnet_month_names, index, - ASHRAE_Reserved_String); -} - -INDTEXT_DATA bacnet_week_of_month_names[] = { - {1, "days numbered 1-7"}, {2, "days numbered 8-14"}, - {3, "days numbered 15-21"}, {4, "days numbered 22-28"}, - {5, "days numbered 29-31"}, {6, "last 7 days of this month"}, - {255, "any week of this month"}, {0, NULL}}; - -const char *bactext_week_of_month_name(unsigned index) -{ - return indtext_by_index_default(bacnet_week_of_month_names, index, - ASHRAE_Reserved_String); -} - -/* note: different than DaysOfWeek bit string where 0=monday */ -INDTEXT_DATA bacnet_day_of_week_names[] = { - {1, "Monday"}, {2, "Tuesday"}, {3, "Wednesday"}, {4, "Thursday"}, - {5, "Friday"}, {6, "Saturday"}, {7, "Sunday"}, {255, "any day of week"}, - {0, NULL}}; - -const char *bactext_day_of_week_name(unsigned index) -{ - return indtext_by_index_default(bacnet_day_of_week_names, index, - ASHRAE_Reserved_String); -} - -/* note: different than DayOfWeek bit string where 1=monday */ -INDTEXT_DATA bacnet_days_of_week_names[] = { - {BACNET_DAYS_OF_WEEK_MONDAY, "Monday"}, - {BACNET_DAYS_OF_WEEK_TUESDAY, "Tuesday"}, - {BACNET_DAYS_OF_WEEK_WEDNESDAY, "Wednesday"}, - {BACNET_DAYS_OF_WEEK_THURSDAY, "Thursday"}, - {BACNET_DAYS_OF_WEEK_FRIDAY, "Friday"}, - {BACNET_DAYS_OF_WEEK_SATURDAY, "Saturday"}, - {BACNET_DAYS_OF_WEEK_SUNDAY, "Sunday"}, - {0, NULL}}; - -const char *bactext_days_of_week_name(unsigned index) -{ - return indtext_by_index_default(bacnet_days_of_week_names, index, - ASHRAE_Reserved_String); -} - -bool bactext_days_of_week_index(const char *search_name, unsigned *found_index) -{ - return indtext_by_istring(bacnet_days_of_week_names, search_name, - found_index); -} - -INDTEXT_DATA bacnet_event_transition_names[] = { - {TRANSITION_TO_OFFNORMAL, "offnormal"}, - {TRANSITION_TO_NORMAL, "normal"}, - {TRANSITION_TO_FAULT, "fault"}, - {0, NULL}}; - -const char *bactext_event_transition_name(unsigned index) -{ - return indtext_by_index_default(bacnet_event_transition_names, index, - ASHRAE_Reserved_String); -} - -bool bactext_event_transition_index(const char *search_name, - unsigned *found_index) -{ - return indtext_by_istring(bacnet_event_transition_names, search_name, - found_index); -} - -INDTEXT_DATA bacnet_event_state_names[] = { - {EVENT_STATE_NORMAL, "normal"}, - {EVENT_STATE_FAULT, "fault"}, - {EVENT_STATE_OFFNORMAL, "offnormal"}, - {EVENT_STATE_HIGH_LIMIT, "high limit"}, - {EVENT_STATE_LOW_LIMIT, "low limit"}, - {0, NULL}}; - -const char *bactext_event_state_name(unsigned index) -{ - return indtext_by_index_default(bacnet_event_state_names, index, - ASHRAE_Reserved_String); -} - -INDTEXT_DATA bacnet_binary_present_value_names[] = { - {BINARY_INACTIVE, "inactive"}, {BINARY_ACTIVE, "active"}, {0, NULL}}; - -const char *bactext_binary_present_value_name(unsigned index) -{ - return indtext_by_index_default(bacnet_binary_present_value_names, index, - ASHRAE_Reserved_String); -} - -bool bactext_binary_present_value_index(const char *search_name, - unsigned *found_index) -{ - return indtext_by_istring(bacnet_binary_present_value_names, search_name, - found_index); -} - -INDTEXT_DATA bacnet_binary_polarity_names[] = { - {POLARITY_NORMAL, "normal"}, {POLARITY_REVERSE, "reverse"}, {0, NULL}}; - -const char *bactext_binary_polarity_name(unsigned index) -{ - return indtext_by_index_default(bacnet_binary_polarity_names, index, - ASHRAE_Reserved_String); -} - -INDTEXT_DATA bacnet_reliability_names[] = { - {RELIABILITY_NO_FAULT_DETECTED, "no-fault-detected"}, - {RELIABILITY_NO_SENSOR, "no-sensor"}, - {RELIABILITY_OVER_RANGE, "over-range"}, - {RELIABILITY_UNDER_RANGE, "under-range"}, - {RELIABILITY_OPEN_LOOP, "open-loop"}, - {RELIABILITY_SHORTED_LOOP, "shorted-loop"}, - {RELIABILITY_NO_OUTPUT, "no-output"}, - {RELIABILITY_UNRELIABLE_OTHER, "unreliable-other"}, - {RELIABILITY_PROCESS_ERROR, "process-error"}, - {RELIABILITY_MULTI_STATE_FAULT, "mult-state-fault"}, - {RELIABILITY_CONFIGURATION_ERROR, "configuration-error"}, - {RELIABILITY_MEMBER_FAULT, "member-fault"}, - {RELIABILITY_COMMUNICATION_FAILURE, "communication-failure"}, - {RELIABILITY_TRIPPED, "tripped"}, - {0, NULL}}; - -const char *bactext_reliability_name(unsigned index) -{ - return indtext_by_index_default(bacnet_reliability_names, index, - ASHRAE_Reserved_String); -} - -INDTEXT_DATA bacnet_device_status_names[] = { - {STATUS_OPERATIONAL, "operational"}, - {STATUS_OPERATIONAL_READ_ONLY, "operational-read-only"}, - {STATUS_DOWNLOAD_REQUIRED, "download-required"}, - {STATUS_DOWNLOAD_IN_PROGRESS, "download-in-progress"}, - {STATUS_NON_OPERATIONAL, "non-operational"}, - {STATUS_BACKUP_IN_PROGRESS, "backup-in-progress"}, - {0, NULL}}; - -const char *bactext_device_status_name(unsigned index) -{ - return indtext_by_index_default(bacnet_device_status_names, index, - ASHRAE_Reserved_String); -} - -INDTEXT_DATA bacnet_segmentation_names[] = { - {SEGMENTATION_BOTH, "segmented-both"}, - {SEGMENTATION_TRANSMIT, "segmented-transmit"}, - {SEGMENTATION_RECEIVE, "segmented-receive"}, - {SEGMENTATION_NONE, "no-segmentation"}, - {0, NULL}}; - -const char *bactext_segmentation_name(unsigned index) -{ - return indtext_by_index_default(bacnet_segmentation_names, index, - ASHRAE_Reserved_String); -} - -bool bactext_segmentation_index(const char *search_name, unsigned *found_index) -{ - return indtext_by_istring(bacnet_segmentation_names, search_name, - found_index); -} - -INDTEXT_DATA bacnet_node_type_names[] = { - {BACNET_NODE_UNKNOWN, "unknown"}, - {BACNET_NODE_SYSTEM, "system"}, - {BACNET_NODE_NETWORK, "network"}, - {BACNET_NODE_DEVICE, "device"}, - {BACNET_NODE_ORGANIZATIONAL, "organizational"}, - {BACNET_NODE_AREA, "area"}, - {BACNET_NODE_EQUIPMENT, "equipment"}, - {BACNET_NODE_POINT, "point"}, - {BACNET_NODE_COLLECTION, "collection"}, - {BACNET_NODE_PROPERTY, "property"}, - {BACNET_NODE_FUNCTIONAL, "functional"}, - {BACNET_NODE_OTHER, "other"}, - {0, NULL}}; - -const char *bactext_node_type_name(unsigned index) -{ - return indtext_by_index_default(bacnet_node_type_names, index, - ASHRAE_Reserved_String); -} - -INDTEXT_DATA network_layer_msg_names[] = { - {NETWORK_MESSAGE_WHO_IS_ROUTER_TO_NETWORK, "Who-Is-Router-To-Network"}, - {NETWORK_MESSAGE_I_AM_ROUTER_TO_NETWORK, "I-Am-Router-To-Network"}, - {NETWORK_MESSAGE_I_COULD_BE_ROUTER_TO_NETWORK, - "I-Could-Be-Router-To-Network"}, - {NETWORK_MESSAGE_REJECT_MESSAGE_TO_NETWORK, "Reject-Message-to-Network"}, - {NETWORK_MESSAGE_ROUTER_BUSY_TO_NETWORK, "Router-Busy-To-Network"}, - {NETWORK_MESSAGE_ROUTER_AVAILABLE_TO_NETWORK, - "Router-Available-To-Network"}, - {NETWORK_MESSAGE_INIT_RT_TABLE, "Initialize-Routing-Table"}, - {NETWORK_MESSAGE_INIT_RT_TABLE_ACK, "Initialize-Routing-Table-Ack"}, - {NETWORK_MESSAGE_ESTABLISH_CONNECTION_TO_NETWORK, - "Est-Conn-Ntwk"}, /* Terse since unused */ - {NETWORK_MESSAGE_DISCONNECT_CONNECTION_TO_NETWORK, "Dsc-Conn-Ntwk"}, - {0, NULL}}; - -const char *bactext_network_layer_msg_name(unsigned index) -{ - if (index <= 0x7F) - return indtext_by_index_default(network_layer_msg_names, index, - ASHRAE_Reserved_String); - else if (index < NETWORK_MESSAGE_INVALID) - return Vendor_Proprietary_String; - else - return "Invalid Network Layer Message"; -} - -INDTEXT_DATA life_safety_state_names[] = { - {LIFE_SAFETY_STATE_QUIET, "quiet"}, - {LIFE_SAFETY_STATE_PRE_ALARM, "pre-alarm"}, - {LIFE_SAFETY_STATE_ALARM, "alarm"}, - {LIFE_SAFETY_STATE_FAULT, "fault"}, - {LIFE_SAFETY_STATE_FAULT_PRE_ALARM, "fault-pre-alarm"}, - {LIFE_SAFETY_STATE_FAULT_ALARM, "fault-alarm"}, - {LIFE_SAFETY_STATE_NOT_READY, "not-ready"}, - {LIFE_SAFETY_STATE_ACTIVE, "active"}, - {LIFE_SAFETY_STATE_TAMPER, "tamper"}, - {LIFE_SAFETY_STATE_TEST_ALARM, "test-alarm"}, - {LIFE_SAFETY_STATE_TEST_ACTIVE, "test-active"}, - {LIFE_SAFETY_STATE_TEST_FAULT, "test-fault"}, - {LIFE_SAFETY_STATE_TEST_FAULT_ALARM, "fault-alarm"}, - {LIFE_SAFETY_STATE_HOLDUP, "holdupt"}, - {LIFE_SAFETY_STATE_DURESS, "duress"}, - {LIFE_SAFETY_STATE_TAMPER_ALARM, "tamper-alarm"}, - {LIFE_SAFETY_STATE_ABNORMAL, "abnormal"}, - {LIFE_SAFETY_STATE_EMERGENCY_POWER, "emergency-power"}, - {LIFE_SAFETY_STATE_DELAYED, "delayed"}, - {LIFE_SAFETY_STATE_BLOCKED, "blocked"}, - {LIFE_SAFETY_STATE_LOCAL_ALARM, "local-alarm"}, - {LIFE_SAFETY_STATE_GENERAL_ALARM, "general-alarm"}, - {LIFE_SAFETY_STATE_SUPERVISORY, "supervisory"}, - {LIFE_SAFETY_STATE_TEST_SUPERVISORY, "test-supervisory"}, - {0, NULL}}; - -const char *bactext_life_safety_state_name(unsigned index) -{ - if (index < MAX_LIFE_SAFETY_STATE) - return indtext_by_index_default(life_safety_state_names, index, - ASHRAE_Reserved_String); - else - return "Invalid Safety State Message"; -} - -INDTEXT_DATA lighting_in_progress[] = {{BACNET_LIGHTING_IDLE, "idle"}, - {BACNET_LIGHTING_FADE_ACTIVE, "fade"}, - {BACNET_LIGHTING_RAMP_ACTIVE, "ramp"}, - {BACNET_LIGHTING_NOT_CONTROLLED, "not"}, - {BACNET_LIGHTING_OTHER, "other"}, - {0, NULL}}; - -const char *bactext_lighting_in_progress(unsigned index) -{ - if (index < MAX_BACNET_LIGHTING_IN_PROGRESS) - return indtext_by_index_default(lighting_in_progress, index, - ASHRAE_Reserved_String); - else - return "Invalid Lighting In Progress Message"; -} - -INDTEXT_DATA lighting_transition[] = {{BACNET_LIGHTING_TRANSITION_IDLE, "idle"}, - {BACNET_LIGHTING_TRANSITION_FADE, "fade"}, - {BACNET_LIGHTING_TRANSITION_RAMP, "ramp"}, - {0, NULL}}; - -const char *bactext_lighting_transition(unsigned index) -{ - if (index < MAX_BACNET_LIGHTING_TRANSITION) - return indtext_by_index_default(lighting_transition, index, - ASHRAE_Reserved_String); - else - return "Invalid Lighting Transition Message"; -} - -INDTEXT_DATA bacnet_lighting_operation_names[] = { - {BACNET_LIGHTS_NONE, "none"}, - {BACNET_LIGHTS_FADE_TO, "fade-to"}, - {BACNET_LIGHTS_RAMP_TO, "ramp-to"}, - {BACNET_LIGHTS_STEP_UP, "step-up"}, - {BACNET_LIGHTS_STEP_DOWN, "step-down"}, - {BACNET_LIGHTS_STEP_ON, "step-on"}, - {BACNET_LIGHTS_STEP_OFF, "step-off"}, - {BACNET_LIGHTS_WARN, "warn"}, - {BACNET_LIGHTS_WARN_OFF, "warn-off"}, - {BACNET_LIGHTS_WARN_RELINQUISH, "warn-relinquish"}, - {BACNET_LIGHTS_STOP, "stop"}, - {0, NULL}}; - -const char *bactext_lighting_operation_name(unsigned index) -{ - if (index < BACNET_LIGHTS_PROPRIETARY_FIRST) - return indtext_by_index_default(network_layer_msg_names, index, - ASHRAE_Reserved_String); - else if (index <= BACNET_LIGHTS_PROPRIETARY_LAST) - return Vendor_Proprietary_String; - else - return "Invalid BACnetLightingOperation"; -} - -INDTEXT_DATA bacnet_device_communications_names[] = { - {COMMUNICATION_ENABLE, "enabled"}, - {COMMUNICATION_DISABLE, "disabled"}, - {COMMUNICATION_DISABLE_INITIATION, "initiation disabled"}, - {0, NULL}}; - -const char *bactext_device_communications_name(unsigned index) -{ - return indtext_by_index_default(bacnet_device_communications_names, index, - ASHRAE_Reserved_String); -} diff --git a/src/proplist.c b/src/proplist.c deleted file mode 100644 index 31b2f242..00000000 --- a/src/proplist.c +++ /dev/null @@ -1,1235 +0,0 @@ -/*####COPYRIGHTBEGIN#### - ------------------------------------------- - Copyright (C) 2012 Steve Karg - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to: - The Free Software Foundation, Inc. - 59 Temple Place - Suite 330 - Boston, MA 02111-1307, USA. - - As a special exception, if other files instantiate templates or - use macros or inline functions from this file, or you compile - this file and link it with other works to produce a work based - on this file, this file does not by itself cause the resulting - work to be covered by the GNU General Public License. However - the source code for this file must still be made available in - accordance with section (3) of the GNU General Public License. - - This exception does not invalidate any other reasons why a work - based on this file might be covered by the GNU General Public - License. - ------------------------------------------- -####COPYRIGHTEND####*/ -#include -#include "bacenum.h" -#include "bacdef.h" -#include "bacdcode.h" -#include "bacenum.h" -#include "rpm.h" -#include "rp.h" -#include "proplist.h" - -#ifndef BACNET_PROPERTY_LISTS -#define BACNET_PROPERTY_LISTS 0 -#endif - -#if BACNET_PROPERTY_LISTS -/** @file proplist.c List of Required and Optional object properties */ -/* note: the PROP_PROPERTY_LIST is NOT included in these lists, on purpose */ - -static const int Default_Properties_Required[] = { - PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME, PROP_OBJECT_TYPE, -1}; - -static const int Device_Properties_Required[] = { - PROP_OBJECT_IDENTIFIER, - PROP_OBJECT_NAME, - PROP_OBJECT_TYPE, - PROP_SYSTEM_STATUS, - PROP_VENDOR_NAME, - PROP_VENDOR_IDENTIFIER, - PROP_MODEL_NAME, - PROP_FIRMWARE_REVISION, - PROP_APPLICATION_SOFTWARE_VERSION, - PROP_PROTOCOL_VERSION, - PROP_PROTOCOL_REVISION, - PROP_PROTOCOL_SERVICES_SUPPORTED, - PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED, - PROP_OBJECT_LIST, - PROP_MAX_APDU_LENGTH_ACCEPTED, - PROP_SEGMENTATION_SUPPORTED, - PROP_APDU_TIMEOUT, - PROP_NUMBER_OF_APDU_RETRIES, - PROP_DEVICE_ADDRESS_BINDING, - PROP_DATABASE_REVISION, - -1}; - -static const int Device_Properties_Optional[] = { - PROP_LOCATION, - PROP_DESCRIPTION, - PROP_STRUCTURED_OBJECT_LIST, - PROP_MAX_SEGMENTS_ACCEPTED, - PROP_VT_CLASSES_SUPPORTED, - PROP_ACTIVE_VT_SESSIONS, - PROP_LOCAL_TIME, - PROP_LOCAL_DATE, - PROP_UTC_OFFSET, - PROP_DAYLIGHT_SAVINGS_STATUS, - PROP_APDU_SEGMENT_TIMEOUT, - PROP_TIME_SYNCHRONIZATION_RECIPIENTS, - PROP_MAX_MASTER, - PROP_MAX_INFO_FRAMES, - PROP_CONFIGURATION_FILES, - PROP_LAST_RESTORE_TIME, - PROP_BACKUP_FAILURE_TIMEOUT, - PROP_BACKUP_PREPARATION_TIME, - PROP_RESTORE_PREPARATION_TIME, - PROP_RESTORE_COMPLETION_TIME, - PROP_BACKUP_AND_RESTORE_STATE, - PROP_ACTIVE_COV_SUBSCRIPTIONS, - PROP_SLAVE_PROXY_ENABLE, - PROP_MANUAL_SLAVE_ADDRESS_BINDING, - PROP_AUTO_SLAVE_DISCOVERY, - PROP_SLAVE_ADDRESS_BINDING, - PROP_LAST_RESTART_REASON, - PROP_TIME_OF_DEVICE_RESTART, - PROP_RESTART_NOTIFICATION_RECIPIENTS, - PROP_UTC_TIME_SYNCHRONIZATION_RECIPIENTS, - PROP_TIME_SYNCHRONIZATION_INTERVAL, - PROP_ALIGN_INTERVALS, - PROP_INTERVAL_OFFSET, - PROP_PROFILE_NAME, - -1}; - -static const int Accumulator_Properties_Required[] = {PROP_OBJECT_IDENTIFIER, - PROP_OBJECT_NAME, - PROP_OBJECT_TYPE, - PROP_PRESENT_VALUE, - PROP_STATUS_FLAGS, - PROP_EVENT_STATE, - PROP_OUT_OF_SERVICE, - PROP_SCALE, - PROP_UNITS, - PROP_MAX_PRES_VALUE, - -1}; - -static const int Accumulator_Properties_Optional[] = { - PROP_DESCRIPTION, - PROP_DEVICE_TYPE, - PROP_RELIABILITY, - PROP_PRESCALE, - PROP_VALUE_CHANGE_TIME, - PROP_VALUE_BEFORE_CHANGE, - PROP_VALUE_SET, - PROP_LOGGING_RECORD, - PROP_LOGGING_OBJECT, - PROP_PULSE_RATE, - PROP_HIGH_LIMIT, - PROP_LOW_LIMIT, - PROP_LIMIT_MONITORING_INTERVAL, - PROP_NOTIFICATION_CLASS, - PROP_TIME_DELAY, - PROP_LIMIT_ENABLE, - PROP_EVENT_ENABLE, - PROP_ACKED_TRANSITIONS, - PROP_NOTIFY_TYPE, - PROP_EVENT_TIME_STAMPS, - PROP_EVENT_MESSAGE_TEXTS, - PROP_RELIABILITY_EVALUATION_INHIBIT, - PROP_PROFILE_NAME, - -1}; - -static const int Analog_Input_Properties_Required[] = { - PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME, PROP_OBJECT_TYPE, - PROP_PRESENT_VALUE, PROP_STATUS_FLAGS, PROP_EVENT_STATE, - PROP_OUT_OF_SERVICE, PROP_UNITS, -1}; - -static const int Analog_Input_Properties_Optional[] = { - PROP_DESCRIPTION, - PROP_DEVICE_TYPE, - PROP_RELIABILITY, - PROP_UPDATE_INTERVAL, - PROP_MIN_PRES_VALUE, - PROP_MAX_PRES_VALUE, - PROP_RESOLUTION, - PROP_COV_INCREMENT, - PROP_TIME_DELAY, - PROP_NOTIFICATION_CLASS, - PROP_HIGH_LIMIT, - PROP_LOW_LIMIT, - PROP_DEADBAND, - PROP_LIMIT_ENABLE, - PROP_EVENT_ENABLE, - PROP_ACKED_TRANSITIONS, - PROP_NOTIFY_TYPE, - PROP_EVENT_TIME_STAMPS, - PROP_EVENT_MESSAGE_TEXTS, - PROP_RELIABILITY_EVALUATION_INHIBIT, - PROP_PROFILE_NAME, - -1}; - -static const int Analog_Output_Properties_Required[] = {PROP_OBJECT_IDENTIFIER, - PROP_OBJECT_NAME, - PROP_OBJECT_TYPE, - PROP_PRESENT_VALUE, - PROP_STATUS_FLAGS, - PROP_EVENT_STATE, - PROP_OUT_OF_SERVICE, - PROP_UNITS, - PROP_PRIORITY_ARRAY, - PROP_RELINQUISH_DEFAULT, - -1}; - -static const int Analog_Output_Properties_Optional[] = { - PROP_DESCRIPTION, - PROP_DEVICE_TYPE, - PROP_RELIABILITY, - PROP_MIN_PRES_VALUE, - PROP_MAX_PRES_VALUE, - PROP_RESOLUTION, - PROP_COV_INCREMENT, - PROP_TIME_DELAY, - PROP_NOTIFICATION_CLASS, - PROP_HIGH_LIMIT, - PROP_LOW_LIMIT, - PROP_DEADBAND, - PROP_LIMIT_ENABLE, - PROP_EVENT_ENABLE, - PROP_ACKED_TRANSITIONS, - PROP_NOTIFY_TYPE, - PROP_EVENT_TIME_STAMPS, - PROP_EVENT_MESSAGE_TEXTS, - PROP_RELIABILITY_EVALUATION_INHIBIT, - PROP_PROFILE_NAME, - -1}; - -static const int Analog_Value_Properties_Required[] = { - PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME, PROP_OBJECT_TYPE, - PROP_PRESENT_VALUE, PROP_STATUS_FLAGS, PROP_EVENT_STATE, - PROP_OUT_OF_SERVICE, PROP_UNITS, -1}; - -static const int Analog_Value_Properties_Optional[] = { - PROP_DESCRIPTION, - PROP_RELIABILITY, - PROP_PRIORITY_ARRAY, - PROP_RELINQUISH_DEFAULT, - PROP_COV_INCREMENT, - PROP_TIME_DELAY, - PROP_NOTIFICATION_CLASS, - PROP_HIGH_LIMIT, - PROP_LOW_LIMIT, - PROP_DEADBAND, - PROP_LIMIT_ENABLE, - PROP_EVENT_ENABLE, - PROP_ACKED_TRANSITIONS, - PROP_NOTIFY_TYPE, - PROP_EVENT_TIME_STAMPS, - PROP_EVENT_MESSAGE_TEXTS, - PROP_RELIABILITY_EVALUATION_INHIBIT, - PROP_PROFILE_NAME, - -1}; - -static const int Averaging_Properties_Required[] = {PROP_OBJECT_IDENTIFIER, - PROP_OBJECT_NAME, - PROP_OBJECT_TYPE, - PROP_MINIMUM_VALUE, - PROP_AVERAGE_VALUE, - PROP_MAXIMUM_VALUE, - PROP_STATUS_FLAGS, - PROP_EVENT_STATE, - PROP_OUT_OF_SERVICE, - PROP_UNITS, - -1}; - -static const int Averaging_Properties_Optional[] = { - PROP_PROFILE_NAME, - PROP_MINIMUM_VALUE_TIMESTAMP, - PROP_VARIANCE_VALUE, - PROP_MAXIMUM_VALUE_TIMESTAMP, - PROP_DESCRIPTION, - PROP_ATTEMPTED_SAMPLES, - PROP_VALID_SAMPLES, - PROP_OBJECT_PROPERTY_REFERENCE, - PROP_WINDOW_INTERVAL, - PROP_WINDOW_SAMPLES, - -1}; - -static const int Binary_Input_Properties_Required[] = { - PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME, PROP_OBJECT_TYPE, - PROP_PRESENT_VALUE, PROP_STATUS_FLAGS, PROP_EVENT_STATE, - PROP_OUT_OF_SERVICE, PROP_POLARITY, -1}; - -static const int Binary_Input_Properties_Optional[] = { - PROP_DESCRIPTION, - PROP_DEVICE_TYPE, - PROP_RELIABILITY, - PROP_INACTIVE_TEXT, - PROP_ACTIVE_TEXT, - PROP_CHANGE_OF_STATE_TIME, - PROP_CHANGE_OF_STATE_COUNT, - PROP_TIME_OF_STATE_COUNT_RESET, - PROP_ELAPSED_ACTIVE_TIME, - PROP_TIME_OF_ACTIVE_TIME_RESET, - PROP_TIME_DELAY, - PROP_NOTIFICATION_CLASS, - PROP_ALARM_VALUE, - PROP_EVENT_ENABLE, - PROP_ACKED_TRANSITIONS, - PROP_NOTIFY_TYPE, - PROP_EVENT_TIME_STAMPS, - PROP_EVENT_MESSAGE_TEXTS, - PROP_RELIABILITY_EVALUATION_INHIBIT, - PROP_PROFILE_NAME, - -1}; - -static const int Binary_Output_Properties_Required[] = {PROP_OBJECT_IDENTIFIER, - PROP_OBJECT_NAME, - PROP_OBJECT_TYPE, - PROP_PRESENT_VALUE, - PROP_STATUS_FLAGS, - PROP_EVENT_STATE, - PROP_OUT_OF_SERVICE, - PROP_POLARITY, - PROP_PRIORITY_ARRAY, - PROP_RELINQUISH_DEFAULT, - -1}; - -static const int Binary_Output_Properties_Optional[] = { - PROP_DESCRIPTION, - PROP_DEVICE_TYPE, - PROP_RELIABILITY, - PROP_INACTIVE_TEXT, - PROP_ACTIVE_TEXT, - PROP_CHANGE_OF_STATE_TIME, - PROP_CHANGE_OF_STATE_COUNT, - PROP_TIME_OF_STATE_COUNT_RESET, - PROP_ELAPSED_ACTIVE_TIME, - PROP_TIME_OF_ACTIVE_TIME_RESET, - PROP_MINIMUM_OFF_TIME, - PROP_MINIMUM_ON_TIME, - PROP_TIME_DELAY, - PROP_NOTIFICATION_CLASS, - PROP_FEEDBACK_VALUE, - PROP_EVENT_ENABLE, - PROP_ACKED_TRANSITIONS, - PROP_NOTIFY_TYPE, - PROP_EVENT_TIME_STAMPS, - PROP_EVENT_MESSAGE_TEXTS, - PROP_RELIABILITY_EVALUATION_INHIBIT, - PROP_PROFILE_NAME, - -1}; - -static const int Binary_Value_Properties_Required[] = { - PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME, - PROP_OBJECT_TYPE, PROP_PRESENT_VALUE, - PROP_STATUS_FLAGS, PROP_EVENT_STATE, - PROP_OUT_OF_SERVICE, -1}; - -static const int Binary_Value_Properties_Optional[] = { - PROP_DESCRIPTION, - PROP_RELIABILITY, - PROP_INACTIVE_TEXT, - PROP_ACTIVE_TEXT, - PROP_CHANGE_OF_STATE_TIME, - PROP_CHANGE_OF_STATE_COUNT, - PROP_TIME_OF_STATE_COUNT_RESET, - PROP_ELAPSED_ACTIVE_TIME, - PROP_TIME_OF_ACTIVE_TIME_RESET, - PROP_MINIMUM_OFF_TIME, - PROP_MINIMUM_ON_TIME, - PROP_PRIORITY_ARRAY, - PROP_RELINQUISH_DEFAULT, - PROP_TIME_DELAY, - PROP_NOTIFICATION_CLASS, - PROP_ALARM_VALUE, - PROP_EVENT_ENABLE, - PROP_ACKED_TRANSITIONS, - PROP_NOTIFY_TYPE, - PROP_EVENT_TIME_STAMPS, - PROP_EVENT_MESSAGE_TEXTS, - PROP_RELIABILITY_EVALUATION_INHIBIT, - PROP_PROFILE_NAME, - -1}; - -static const int Calendar_Properties_Required[] = { - PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME, PROP_OBJECT_TYPE, - PROP_PRESENT_VALUE, PROP_DATE_LIST, -1}; - -static const int Calendar_Properties_Optional[] = {PROP_DESCRIPTION, - PROP_PROFILE_NAME, -1}; - -static const int Channel_Properties_Required[] = { - PROP_OBJECT_IDENTIFIER, - PROP_OBJECT_NAME, - PROP_OBJECT_TYPE, - PROP_PRESENT_VALUE, - PROP_LAST_PRIORITY, - PROP_WRITE_STATUS, - PROP_STATUS_FLAGS, - PROP_OUT_OF_SERVICE, - PROP_LIST_OF_OBJECT_PROPERTY_REFERENCES, - PROP_CHANNEL_NUMBER, - PROP_CONTROL_GROUPS, - -1}; - -static const int Channel_Properties_Optional[] = { - PROP_DESCRIPTION, - PROP_RELIABILITY, - PROP_EXECUTION_DELAY, - PROP_ALLOW_GROUP_DELAY_INHIBIT, - PROP_EVENT_DETECTION_ENABLE, - PROP_NOTIFICATION_CLASS, - PROP_EVENT_ENABLE, - PROP_EVENT_STATE, - PROP_ACKED_TRANSITIONS, - PROP_NOTIFY_TYPE, - PROP_EVENT_TIME_STAMPS, - PROP_EVENT_MESSAGE_TEXTS, - PROP_EVENT_MESSAGE_TEXTS_CONFIG, - PROP_RELIABILITY_EVALUATION_INHIBIT, - PROP_PROFILE_NAME, - -1}; - -static const int Command_Properties_Required[] = {PROP_OBJECT_IDENTIFIER, - PROP_OBJECT_NAME, - PROP_OBJECT_TYPE, - PROP_PRESENT_VALUE, - PROP_IN_PROCESS, - PROP_ALL_WRITES_SUCCESSFUL, - PROP_ACTION, - -1}; - -static const int Command_Properties_Optional[] = { - PROP_DESCRIPTION, PROP_ACTION_TEXT, PROP_PROFILE_NAME, -1}; - -static const int CharacterString_Value_Properties_Required[] = { - PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME, PROP_OBJECT_TYPE, - PROP_PRESENT_VALUE, PROP_STATUS_FLAGS, -1}; - -static const int CharacterString_Value_Properties_Optional[] = { - PROP_DESCRIPTION, PROP_EVENT_STATE, - PROP_RELIABILITY, PROP_OUT_OF_SERVICE, - PROP_PRIORITY_ARRAY, PROP_RELINQUISH_DEFAULT, - PROP_TIME_DELAY, PROP_NOTIFICATION_CLASS, - PROP_ALARM_VALUES, PROP_FAULT_VALUES, - PROP_EVENT_ENABLE, PROP_ACKED_TRANSITIONS, - PROP_NOTIFY_TYPE, PROP_EVENT_TIME_STAMPS, - PROP_EVENT_MESSAGE_TEXTS, PROP_RELIABILITY_EVALUATION_INHIBIT, - PROP_PROFILE_NAME, -1}; - -static const int Lighting_Output_Properties_Required[] = { - PROP_OBJECT_IDENTIFIER, - PROP_OBJECT_NAME, - PROP_OBJECT_TYPE, - PROP_PRESENT_VALUE, - PROP_TRACKING_VALUE, - PROP_LIGHTING_COMMAND, - PROP_IN_PROGRESS, - PROP_STATUS_FLAGS, - PROP_OUT_OF_SERVICE, - PROP_BLINK_WARN_ENABLE, - PROP_EGRESS_TIME, - PROP_EGRESS_ACTIVE, - PROP_DEFAULT_FADE_TIME, - PROP_DEFAULT_RAMP_RATE, - PROP_DEFAULT_STEP_INCREMENT, - PROP_PRIORITY_ARRAY, - PROP_RELINQUISH_DEFAULT, - PROP_LIGHTING_COMMAND_DEFAULT_PRIORITY, - -1}; - -static const int Lighting_Output_Properties_Optional[] = { - PROP_DESCRIPTION, - PROP_RELIABILITY, - PROP_TRANSITION, - PROP_FEEDBACK_VALUE, - PROP_POWER, - PROP_INSTANTANEOUS_POWER, - PROP_MIN_ACTUAL_VALUE, - PROP_MAX_ACTUAL_VALUE, - PROP_COV_INCREMENT, - PROP_RELIABILITY_EVALUATION_INHIBIT, - PROP_PROFILE_NAME, - -1}; - -static const int Load_Control_Properties_Required[] = { - PROP_OBJECT_IDENTIFIER, - PROP_OBJECT_NAME, - PROP_OBJECT_TYPE, - PROP_PRESENT_VALUE, - PROP_STATUS_FLAGS, - PROP_EVENT_STATE, - PROP_REQUESTED_SHED_LEVEL, - PROP_START_TIME, - PROP_SHED_DURATION, - PROP_DUTY_WINDOW, - PROP_ENABLE, - PROP_EXPECTED_SHED_LEVEL, - PROP_ACTUAL_SHED_LEVEL, - PROP_SHED_LEVELS, - PROP_SHED_LEVEL_DESCRIPTIONS, - -1}; - -static const int Load_Control_Properties_Optional[] = { - PROP_DESCRIPTION, PROP_STATE_DESCRIPTION, - PROP_RELIABILITY, PROP_FULL_DUTY_BASELINE, - PROP_NOTIFICATION_CLASS, PROP_TIME_DELAY, - PROP_EVENT_ENABLE, PROP_ACKED_TRANSITIONS, - PROP_NOTIFY_TYPE, PROP_EVENT_TIME_STAMPS, - PROP_EVENT_MESSAGE_TEXTS, PROP_RELIABILITY_EVALUATION_INHIBIT, - PROP_PROFILE_NAME, -1}; - -static const int Life_Safety_Point_Properties_Required[] = { - PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME, - PROP_OBJECT_TYPE, PROP_PRESENT_VALUE, - PROP_TRACKING_VALUE, PROP_STATUS_FLAGS, - PROP_EVENT_STATE, PROP_OUT_OF_SERVICE, - PROP_RELIABILITY, PROP_MODE, - PROP_ACCEPTED_MODES, PROP_SILENCED, - PROP_OPERATION_EXPECTED, -1}; - -static const int Life_Safety_Point_Properties_Optional[] = { - PROP_DESCRIPTION, - PROP_DEVICE_TYPE, - PROP_NOTIFICATION_CLASS, - PROP_LIFE_SAFETY_ALARM_VALUES, - PROP_ALARM_VALUES, - PROP_FAULT_VALUES, - PROP_EVENT_ENABLE, - PROP_ACKED_TRANSITIONS, - PROP_NOTIFY_TYPE, - PROP_EVENT_TIME_STAMPS, - PROP_EVENT_MESSAGE_TEXTS, - PROP_MAINTENANCE_REQUIRED, - PROP_SETTING, - PROP_DIRECT_READING, - PROP_UNITS, - PROP_MEMBER_OF, - PROP_RELIABILITY_EVALUATION_INHIBIT, - PROP_PROFILE_NAME, - -1}; - -static const int Multistate_Input_Properties_Required[] = { - PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME, PROP_OBJECT_TYPE, - PROP_PRESENT_VALUE, PROP_STATUS_FLAGS, PROP_EVENT_STATE, - PROP_OUT_OF_SERVICE, PROP_NUMBER_OF_STATES, -1}; - -static const int Multistate_Input_Properties_Optional[] = { - PROP_DESCRIPTION, PROP_DEVICE_TYPE, - PROP_RELIABILITY, PROP_STATE_TEXT, - PROP_TIME_DELAY, PROP_NOTIFICATION_CLASS, - PROP_ALARM_VALUES, PROP_FAULT_VALUES, - PROP_EVENT_ENABLE, PROP_ACKED_TRANSITIONS, - PROP_NOTIFY_TYPE, PROP_EVENT_TIME_STAMPS, - PROP_EVENT_MESSAGE_TEXTS, PROP_RELIABILITY_EVALUATION_INHIBIT, - PROP_PROFILE_NAME, -1}; - -static const int Multistate_Output_Properties_Required[] = { - PROP_OBJECT_IDENTIFIER, - PROP_OBJECT_NAME, - PROP_OBJECT_TYPE, - PROP_PRESENT_VALUE, - PROP_STATUS_FLAGS, - PROP_EVENT_STATE, - PROP_OUT_OF_SERVICE, - PROP_NUMBER_OF_STATES, - PROP_PRIORITY_ARRAY, - PROP_RELINQUISH_DEFAULT, - -1}; - -static const int Multistate_Output_Properties_Optional[] = { - PROP_DESCRIPTION, - PROP_DEVICE_TYPE, - PROP_RELIABILITY, - PROP_STATE_TEXT, - PROP_TIME_DELAY, - PROP_NOTIFICATION_CLASS, - PROP_FEEDBACK_VALUE, - PROP_EVENT_ENABLE, - PROP_ACKED_TRANSITIONS, - PROP_NOTIFY_TYPE, - PROP_EVENT_TIME_STAMPS, - PROP_EVENT_MESSAGE_TEXTS, - PROP_RELIABILITY_EVALUATION_INHIBIT, - PROP_PROFILE_NAME, - -1}; - -static const int Multistate_Value_Properties_Required[] = { - PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME, PROP_OBJECT_TYPE, - PROP_PRESENT_VALUE, PROP_STATUS_FLAGS, PROP_EVENT_STATE, - PROP_OUT_OF_SERVICE, PROP_NUMBER_OF_STATES, -1}; - -static const int Multistate_Value_Properties_Optional[] = { - PROP_DESCRIPTION, - PROP_RELIABILITY, - PROP_STATE_TEXT, - PROP_PRIORITY_ARRAY, - PROP_RELINQUISH_DEFAULT, - PROP_TIME_DELAY, - PROP_NOTIFICATION_CLASS, - PROP_ALARM_VALUES, - PROP_FAULT_VALUES, - PROP_EVENT_ENABLE, - PROP_ACKED_TRANSITIONS, - PROP_NOTIFY_TYPE, - PROP_EVENT_TIME_STAMPS, - PROP_EVENT_MESSAGE_TEXTS, - PROP_RELIABILITY_EVALUATION_INHIBIT, - PROP_PROFILE_NAME, - -1}; - -static const int Notification_Class_Properties_Required[] = { - PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME, - PROP_OBJECT_TYPE, PROP_NOTIFICATION_CLASS, - PROP_PRIORITY, PROP_ACK_REQUIRED, - PROP_RECIPIENT_LIST, -1}; - -static const int Notification_Class_Properties_Optional[] = { - PROP_DESCRIPTION, PROP_PROFILE_NAME, -1}; - -static const int Trend_Log_Properties_Required[] = {PROP_OBJECT_IDENTIFIER, - PROP_OBJECT_NAME, - PROP_OBJECT_TYPE, - PROP_ENABLE, - PROP_STOP_WHEN_FULL, - PROP_BUFFER_SIZE, - PROP_LOG_BUFFER, - PROP_RECORD_COUNT, - PROP_TOTAL_RECORD_COUNT, - PROP_EVENT_STATE, - PROP_LOGGING_TYPE, - PROP_STATUS_FLAGS, - -1}; - -static const int Trend_Log_Properties_Optional[] = { - PROP_DESCRIPTION, - PROP_START_TIME, - PROP_STOP_TIME, - PROP_LOG_DEVICE_OBJECT_PROPERTY, - PROP_LOG_INTERVAL, - PROP_COV_RESUBSCRIPTION_INTERVAL, - PROP_CLIENT_COV_INCREMENT, - PROP_NOTIFICATION_THRESHOLD, - PROP_RECORDS_SINCE_NOTIFICATION, - PROP_LAST_NOTIFY_RECORD, - PROP_NOTIFICATION_CLASS, - PROP_EVENT_ENABLE, - PROP_ACKED_TRANSITIONS, - PROP_NOTIFY_TYPE, - PROP_EVENT_TIME_STAMPS, - PROP_EVENT_MESSAGE_TEXTS, - PROP_ALIGN_INTERVALS, - PROP_INTERVAL_OFFSET, - PROP_TRIGGER, - PROP_RELIABILITY, - PROP_RELIABILITY_EVALUATION_INHIBIT, - PROP_PROFILE_NAME, - -1}; - -static const int File_Properties_Required[] = {PROP_OBJECT_IDENTIFIER, - PROP_OBJECT_NAME, - PROP_OBJECT_TYPE, - PROP_FILE_TYPE, - PROP_FILE_SIZE, - PROP_MODIFICATION_DATE, - PROP_ARCHIVE, - PROP_READ_ONLY, - PROP_FILE_ACCESS_METHOD, - -1}; - -static const int File_Properties_Optional[] = { - PROP_DESCRIPTION, PROP_RECORD_COUNT, PROP_PROFILE_NAME, -1}; - -/* These three arrays are used by the ReadPropertyMultiple handler */ -static const int Integer_Value_Properties_Required[] = {PROP_OBJECT_IDENTIFIER, - PROP_OBJECT_NAME, - PROP_OBJECT_TYPE, - PROP_PRESENT_VALUE, - PROP_STATUS_FLAGS, - PROP_UNITS, - -1}; - -static const int Integer_Value_Properties_Optional[] = { - PROP_DESCRIPTION, - PROP_EVENT_STATE, - PROP_RELIABILITY, - PROP_OUT_OF_SERVICE, - PROP_PRIORITY_ARRAY, - PROP_RELINQUISH_DEFAULT, - PROP_COV_INCREMENT, - PROP_TIME_DELAY, - PROP_NOTIFICATION_CLASS, - PROP_HIGH_LIMIT, - PROP_LOW_LIMIT, - PROP_DEADBAND, - PROP_LIMIT_ENABLE, - PROP_EVENT_ENABLE, - PROP_ACKED_TRANSITIONS, - PROP_NOTIFY_TYPE, - PROP_EVENT_TIME_STAMPS, - PROP_EVENT_MESSAGE_TEXTS, - PROP_EVENT_MESSAGE_TEXTS_CONFIG, - PROP_EVENT_DETECTION_ENABLE, - PROP_EVENT_ALGORITHM_INHIBIT_REF, - PROP_EVENT_ALGORITHM_INHIBIT, - PROP_TIME_DELAY_NORMAL, - PROP_RELIABILITY_EVALUATION_INHIBIT, - PROP_MIN_PRES_VALUE, - PROP_MAX_PRES_VALUE, - PROP_RESOLUTION, - PROP_PROFILE_NAME, - -1}; - -/** - * Function that returns the list of all Optional properties - * of known standard objects. - * - * @param object_type - enumerated BACNET_OBJECT_TYPE - * @return returns a pointer to a '-1' terminated array of - * type 'int' that contain BACnet object properties for the given object - * type. - */ -const int *property_list_optional(BACNET_OBJECT_TYPE object_type) -{ - const int *pList = NULL; - - switch (object_type) { - case OBJECT_DEVICE: - pList = Device_Properties_Optional; - break; - case OBJECT_ACCUMULATOR: - pList = Accumulator_Properties_Optional; - break; - case OBJECT_ANALOG_INPUT: - pList = Analog_Input_Properties_Optional; - break; - case OBJECT_ANALOG_OUTPUT: - pList = Analog_Output_Properties_Optional; - break; - case OBJECT_ANALOG_VALUE: - pList = Analog_Value_Properties_Optional; - break; - case OBJECT_AVERAGING: - pList = Averaging_Properties_Optional; - break; - case OBJECT_BINARY_INPUT: - pList = Binary_Input_Properties_Optional; - break; - case OBJECT_BINARY_OUTPUT: - pList = Binary_Output_Properties_Optional; - break; - case OBJECT_BINARY_VALUE: - pList = Binary_Value_Properties_Optional; - break; - case OBJECT_CALENDAR: - pList = Calendar_Properties_Optional; - break; - case OBJECT_CHANNEL: - pList = Channel_Properties_Optional; - break; - case OBJECT_COMMAND: - pList = Command_Properties_Optional; - break; - case OBJECT_CHARACTERSTRING_VALUE: - pList = CharacterString_Value_Properties_Optional; - break; - case OBJECT_LIGHTING_OUTPUT: - pList = Lighting_Output_Properties_Optional; - break; - case OBJECT_LOAD_CONTROL: - pList = Load_Control_Properties_Optional; - break; - case OBJECT_LIFE_SAFETY_POINT: - pList = Life_Safety_Point_Properties_Optional; - break; - case OBJECT_MULTI_STATE_INPUT: - pList = Multistate_Input_Properties_Optional; - break; - case OBJECT_MULTI_STATE_OUTPUT: - pList = Multistate_Output_Properties_Optional; - break; - case OBJECT_MULTI_STATE_VALUE: - pList = Multistate_Value_Properties_Optional; - break; - case OBJECT_NOTIFICATION_CLASS: - pList = Notification_Class_Properties_Optional; - break; - case OBJECT_TRENDLOG: - pList = Trend_Log_Properties_Optional; - break; - case OBJECT_FILE: - pList = File_Properties_Optional; - break; - case OBJECT_INTEGER_VALUE: - pList = Integer_Value_Properties_Optional; - break; - default: - break; - } - - return pList; -} - -/** - * Function that returns the list of Required properties - * of known standard objects. - * - * @param object_type - enumerated BACNET_OBJECT_TYPE - * @return returns a pointer to a '-1' terminated array of - * type 'int' that contain BACnet object properties for the given object - * type. - */ -const int *property_list_required(BACNET_OBJECT_TYPE object_type) -{ - const int *pList = NULL; - - switch (object_type) { - case OBJECT_DEVICE: - pList = Device_Properties_Required; - break; - case OBJECT_ACCUMULATOR: - pList = Accumulator_Properties_Required; - break; - case OBJECT_ANALOG_INPUT: - pList = Analog_Input_Properties_Required; - break; - case OBJECT_ANALOG_OUTPUT: - pList = Analog_Output_Properties_Required; - break; - case OBJECT_ANALOG_VALUE: - pList = Analog_Value_Properties_Required; - break; - case OBJECT_AVERAGING: - pList = Averaging_Properties_Required; - break; - case OBJECT_BINARY_INPUT: - pList = Binary_Input_Properties_Required; - break; - case OBJECT_BINARY_OUTPUT: - pList = Binary_Output_Properties_Required; - break; - case OBJECT_BINARY_VALUE: - pList = Binary_Value_Properties_Required; - break; - case OBJECT_CALENDAR: - pList = Calendar_Properties_Required; - break; - case OBJECT_CHANNEL: - pList = Channel_Properties_Required; - break; - case OBJECT_COMMAND: - pList = Command_Properties_Required; - break; - case OBJECT_CHARACTERSTRING_VALUE: - pList = CharacterString_Value_Properties_Required; - break; - case OBJECT_LOAD_CONTROL: - pList = Load_Control_Properties_Required; - break; - case OBJECT_LIGHTING_OUTPUT: - pList = Lighting_Output_Properties_Required; - break; - case OBJECT_LIFE_SAFETY_POINT: - pList = Life_Safety_Point_Properties_Required; - break; - case OBJECT_MULTI_STATE_INPUT: - pList = Multistate_Input_Properties_Required; - break; - case OBJECT_MULTI_STATE_OUTPUT: - pList = Multistate_Output_Properties_Required; - break; - case OBJECT_MULTI_STATE_VALUE: - pList = Multistate_Value_Properties_Required; - break; - case OBJECT_NOTIFICATION_CLASS: - pList = Notification_Class_Properties_Required; - break; - case OBJECT_TRENDLOG: - pList = Trend_Log_Properties_Required; - break; - case OBJECT_FILE: - pList = File_Properties_Required; - break; - case OBJECT_INTEGER_VALUE: - pList = Integer_Value_Properties_Required; - break; - default: - pList = Default_Properties_Required; - break; - } - - return pList; -} - -/** - * Function that returns the list of Required or Optional properties - * of known standard objects. - * - * @param object_type - enumerated BACNET_OBJECT_TYPE - * @param pPropertyList - returns a pointer to two '-1' terminated arrays of - * type 'int' that contain BACnet object properties for the given object - * type. - */ -void property_list_special(BACNET_OBJECT_TYPE object_type, - struct special_property_list_t *pPropertyList) -{ - if (pPropertyList == NULL) { - return; - } - pPropertyList->Required.pList = property_list_required(object_type); - pPropertyList->Optional.pList = property_list_optional(object_type); - pPropertyList->Proprietary.pList = NULL; - /* Fetch the counts if available otherwise zero them */ - pPropertyList->Required.count = - property_list_count(pPropertyList->Required.pList); - pPropertyList->Optional.count = - property_list_count(pPropertyList->Optional.pList); - pPropertyList->Proprietary.count = 0; - - return; -} - -BACNET_PROPERTY_ID property_list_special_property( - BACNET_OBJECT_TYPE object_type, BACNET_PROPERTY_ID special_property, - unsigned index) -{ - int property = -1; /* return value */ - unsigned required, optional, proprietary; - struct special_property_list_t PropertyList = {{0}}; - - property_list_special(object_type, &PropertyList); - required = PropertyList.Required.count; - optional = PropertyList.Optional.count; - proprietary = PropertyList.Proprietary.count; - if (special_property == PROP_ALL) { - if (index < required) { - if (PropertyList.Required.pList) { - property = PropertyList.Required.pList[index]; - } - } else if (index < (required + optional)) { - if (PropertyList.Optional.pList) { - index -= required; - property = PropertyList.Optional.pList[index]; - } - } else if (index < (required + optional + proprietary)) { - if (PropertyList.Proprietary.pList) { - index -= (required + optional); - property = PropertyList.Proprietary.pList[index]; - } - } - } else if (special_property == PROP_REQUIRED) { - if (index < required) { - if (PropertyList.Required.pList) { - property = PropertyList.Required.pList[index]; - } - } - } else if (special_property == PROP_OPTIONAL) { - if (index < optional) { - if (PropertyList.Optional.pList) { - property = PropertyList.Optional.pList[index]; - } - } - } - - return (BACNET_PROPERTY_ID)property; -} - -unsigned property_list_special_count(BACNET_OBJECT_TYPE object_type, - BACNET_PROPERTY_ID special_property) -{ - unsigned count = 0; /* return value */ - struct special_property_list_t PropertyList = {{0}}; - - property_list_special(object_type, &PropertyList); - if (special_property == PROP_ALL) { - count = PropertyList.Required.count + PropertyList.Optional.count + - PropertyList.Proprietary.count; - } else if (special_property == PROP_REQUIRED) { - count = PropertyList.Required.count; - } else if (special_property == PROP_OPTIONAL) { - count = PropertyList.Optional.count; - } - - return count; -} -#endif - -/** - * Function that returns the number of BACnet object properties in a list - * - * @param pList - array of type 'int' that is a list of BACnet object - * properties, terminated by a '-1' value. - */ -unsigned property_list_count(const int *pList) -{ - unsigned property_count = 0; - - if (pList) { - while (*pList != -1) { - property_count++; - pList++; - } - } - - return property_count; -} - -/** - * For a given object property, returns the true if in the property list - * - * @param pList - array of type 'int' that is a list of BACnet object - * @param object_property - property enumeration or propritary value - * - * @return true if object_property is a member of the property list - */ -bool property_list_member(const int *pList, int object_property) -{ - bool status = false; - - if (pList) { - while ((*pList) != -1) { - if (object_property == (*pList)) { - status = true; - break; - } - pList++; - } - } - - return status; -} - -/** - * ReadProperty handler for this property. For the given ReadProperty - * data, the application_data is loaded or the error flags are set. - * - * @param rpdata - ReadProperty data, including requested data and - * data for the reply, or error response. - * - * @return number of APDU bytes in the response, or - * BACNET_STATUS_ERROR on error. - */ -int property_list_encode(BACNET_READ_PROPERTY_DATA *rpdata, - const int *pListRequired, const int *pListOptional, - const int *pListProprietary) -{ - int apdu_len = 0; /* return value */ - uint8_t *apdu = NULL; - int max_apdu_len = 0; - uint32_t count = 0; - unsigned required_count = 0; - unsigned optional_count = 0; - unsigned proprietary_count = 0; - int len = 0; - unsigned i = 0; /* loop index */ - - required_count = property_list_count(pListRequired); - optional_count = property_list_count(pListOptional); - proprietary_count = property_list_count(pListProprietary); - /* total of all counts */ - count = required_count + optional_count + proprietary_count; - if (required_count >= 3) { - /* less the 3 always required properties */ - count -= 3; - } - if ((rpdata == NULL) || (rpdata->application_data == NULL) || - (rpdata->application_data_len == 0)) { - return 0; - } - apdu = rpdata->application_data; - max_apdu_len = rpdata->application_data_len; - switch (rpdata->object_property) { - case PROP_PROPERTY_LIST: - if (rpdata->array_index == 0) { - /* Array element zero is the number of elements in the array */ - apdu_len = encode_application_unsigned(&apdu[0], count); - } else if (rpdata->array_index == BACNET_ARRAY_ALL) { - /* if no index was specified, then try to encode the entire list - */ - /* into one packet. */ - if (required_count > 3) { - for (i = 0; i < required_count; i++) { - if ((pListRequired[i] == PROP_OBJECT_TYPE) || - (pListRequired[i] == PROP_OBJECT_IDENTIFIER) || - (pListRequired[i] == PROP_OBJECT_NAME)) { - continue; - } else { - len = encode_application_enumerated( - &apdu[apdu_len], (uint32_t)pListRequired[i]); - } - /* add it if we have room */ - if ((apdu_len + len) < max_apdu_len) { - apdu_len += len; - } else { - rpdata->error_code = - ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED; - apdu_len = BACNET_STATUS_ABORT; - break; - } - } - } - if (optional_count) { - for (i = 0; i < optional_count; i++) { - len = encode_application_enumerated( - &apdu[apdu_len], (uint32_t)pListOptional[i]); - /* add it if we have room */ - if ((apdu_len + len) < max_apdu_len) { - apdu_len += len; - } else { - rpdata->error_code = - ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED; - apdu_len = BACNET_STATUS_ABORT; - break; - } - } - } - if (proprietary_count) { - for (i = 0; i < proprietary_count; i++) { - len = encode_application_enumerated( - &apdu[apdu_len], (uint32_t)pListProprietary[i]); - /* add it if we have room */ - if ((apdu_len + len) < max_apdu_len) { - apdu_len += len; - } else { - rpdata->error_code = - ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED; - apdu_len = BACNET_STATUS_ABORT; - break; - } - } - } - } else { - if (rpdata->array_index <= count) { - count = 0; - if (required_count > 3) { - for (i = 0; i < required_count; i++) { - if ((pListRequired[i] == PROP_OBJECT_TYPE) || - (pListRequired[i] == PROP_OBJECT_IDENTIFIER) || - (pListRequired[i] == PROP_OBJECT_NAME)) { - continue; - } else { - count++; - } - if (count == rpdata->array_index) { - apdu_len = encode_application_enumerated( - &apdu[apdu_len], - (uint32_t)pListRequired[i]); - break; - } - } - } - if ((apdu_len == 0) && (optional_count > 0)) { - for (i = 0; i < optional_count; i++) { - count++; - if (count == rpdata->array_index) { - apdu_len = encode_application_enumerated( - &apdu[apdu_len], - (uint32_t)pListOptional[i]); - break; - } - } - } - if ((apdu_len == 0) && (proprietary_count > 0)) { - for (i = 0; i < proprietary_count; i++) { - count++; - if (count == rpdata->array_index) { - apdu_len = encode_application_enumerated( - &apdu[apdu_len], - (uint32_t)pListProprietary[i]); - break; - } - } - } - } else { - rpdata->error_class = ERROR_CLASS_PROPERTY; - rpdata->error_code = ERROR_CODE_INVALID_ARRAY_INDEX; - apdu_len = BACNET_STATUS_ERROR; - } - } - break; - default: - rpdata->error_class = ERROR_CLASS_PROPERTY; - rpdata->error_code = ERROR_CODE_UNKNOWN_PROPERTY; - apdu_len = BACNET_STATUS_ERROR; - break; - } - - return apdu_len; -} - -#ifdef TEST -#include -#include -#include "ctest.h" - -void testPropList(Test *pTest) -{ - unsigned i = 0, j = 0; - unsigned count = 0; - BACNET_PROPERTY_ID property = MAX_BACNET_PROPERTY_ID; - unsigned object_id = 0, object_name = 0, object_type = 0; - struct special_property_list_t property_list = {0}; - - for (i = 0; i < OBJECT_PROPRIETARY_MIN; i++) { - count = property_list_special_count((BACNET_OBJECT_TYPE)i, PROP_ALL); - ct_test(pTest, count >= 3); - object_id = 0; - object_name = 0; - object_type = 0; - for (j = 0; j < count; j++) { - property = property_list_special_property((BACNET_OBJECT_TYPE)i, - PROP_ALL, j); - if (property == PROP_OBJECT_TYPE) { - object_type++; - } - if (property == PROP_OBJECT_IDENTIFIER) { - object_id++; - } - if (property == PROP_OBJECT_NAME) { - object_name++; - } - } - ct_test(pTest, object_type == 1); - ct_test(pTest, object_id == 1); - ct_test(pTest, object_name == 1); - /* test member function */ - property_list_special((BACNET_OBJECT_TYPE)i, &property_list); - ct_test(pTest, property_list_member(property_list.Required.pList, - PROP_OBJECT_TYPE)); - ct_test(pTest, property_list_member(property_list.Required.pList, - PROP_OBJECT_IDENTIFIER)); - ct_test(pTest, property_list_member(property_list.Required.pList, - PROP_OBJECT_NAME)); - } -} - -#ifdef TEST_PROPLIST -int main(void) -{ - Test *pTest; - bool rc; - - pTest = ct_create("BACnet Property List", NULL); - /* individual tests */ - rc = ct_addTestFunction(pTest, testPropList); - assert(rc); - - ct_setStream(pTest, stdout); - ct_run(pTest); - (void)ct_report(pTest); - ct_destroy(pTest); - - return 0; -} -#endif /* TEST_PROPLIST */ -#endif /* TEST */ diff --git a/src/version.c b/src/version.c deleted file mode 100644 index e5094837..00000000 --- a/src/version.c +++ /dev/null @@ -1,38 +0,0 @@ -/*####COPYRIGHTBEGIN#### - ------------------------------------------- - Copyright (C) 2007 Steve Karg - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to: - The Free Software Foundation, Inc. - 59 Temple Place - Suite 330 - Boston, MA 02111-1307, USA. - - As a special exception, if other files instantiate templates or - use macros or inline functions from this file, or you compile - this file and link it with other works to produce a work based - on this file, this file does not by itself cause the resulting - work to be covered by the GNU General Public License. However - the source code for this file must still be made available in - accordance with section (3) of the GNU General Public License. - - This exception does not invalidate any other reasons why a work - based on this file might be covered by the GNU General Public - License. - ------------------------------------------- -####COPYRIGHTEND####*/ -#include "version.h" - -/** @file version.c Sets the BACnet Version. */ - -char *BACnet_Version = BACNET_VERSION_TEXT; diff --git a/svn2cl.xsl b/svn2cl.xsl deleted file mode 100644 index f4226b5c..00000000 --- a/svn2cl.xsl +++ /dev/null @@ -1,215 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * - - - - - - - - - - - - - - - - , - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/test/abort.mak b/test/abort.mak index 92c41e9c..3925bc1d 100644 --- a/test/abort.mak +++ b/test/abort.mak @@ -1,16 +1,16 @@ #Makefile to build test case -CC = gcc + SRC_DIR = ../src -INCLUDES = -I../include -I. +INCLUDES = -I$(SRC_DIR) -I. DEFINES = -DBIG_ENDIAN=0 -DTEST -DTEST_ABORT CFLAGS = -Wall $(INCLUDES) $(DEFINES) -g -SRCS = $(SRC_DIR)/bacdcode.c \ - $(SRC_DIR)/bacint.c \ - $(SRC_DIR)/bacstr.c \ - $(SRC_DIR)/bacreal.c \ - $(SRC_DIR)/abort.c \ +SRCS = $(SRC_DIR)/bacnet/bacdcode.c \ + $(SRC_DIR)/bacnet/bacint.c \ + $(SRC_DIR)/bacnet/bacstr.c \ + $(SRC_DIR)/bacnet/bacreal.c \ + $(SRC_DIR)/bacnet/abort.c \ ctest.c TARGET = abort diff --git a/test/address.mak b/test/address.mak index fd97e325..7dfe0b50 100644 --- a/test/address.mak +++ b/test/address.mak @@ -1,23 +1,23 @@ #Makefile to build test case CC = gcc SRC_DIR = ../src -INCLUDES = -I../include -I. +INCLUDES = -I$(SRC_DIR) -I. DEFINES = -DBIG_ENDIAN=0 -DTEST -DTEST_ADDRESS -DBACNET_ADDRESS_CACHE_FILE CFLAGS = -Wall $(INCLUDES) $(DEFINES) -g -SRCS = $(SRC_DIR)/address.c \ - $(SRC_DIR)/bacaddr.c \ - $(SRC_DIR)/bacdcode.c \ - $(SRC_DIR)/bacint.c \ - $(SRC_DIR)/bacstr.c \ - $(SRC_DIR)/bacreal.c \ - $(SRC_DIR)/bacapp.c \ - $(SRC_DIR)/bacdevobjpropref.c \ - $(SRC_DIR)/datetime.c \ - $(SRC_DIR)/lighting.c \ - $(SRC_DIR)/bactext.c \ - $(SRC_DIR)/indtext.c \ +SRCS = $(SRC_DIR)/bacnet/basic/binding/address.c \ + $(SRC_DIR)/bacnet/bacaddr.c \ + $(SRC_DIR)/bacnet/bacdcode.c \ + $(SRC_DIR)/bacnet/bacint.c \ + $(SRC_DIR)/bacnet/bacstr.c \ + $(SRC_DIR)/bacnet/bacreal.c \ + $(SRC_DIR)/bacnet/bacapp.c \ + $(SRC_DIR)/bacnet/bacdevobjpropref.c \ + $(SRC_DIR)/bacnet/datetime.c \ + $(SRC_DIR)/bacnet/lighting.c \ + $(SRC_DIR)/bacnet/bactext.c \ + $(SRC_DIR)/bacnet/indtext.c \ ctest.c OBJS = ${SRCS:.c=.o} diff --git a/test/arf.mak b/test/arf.mak index 7bf60eb2..d60de0f3 100644 --- a/test/arf.mak +++ b/test/arf.mak @@ -1,16 +1,16 @@ #Makefile to build test case CC = gcc SRC_DIR = ../src -INCLUDES = -I../include -I. -I../demo/object +INCLUDES = -I$(SRC_DIR) -I. -I../demo/object DEFINES = -DBACFILE=1 -DBIG_ENDIAN=0 -DTEST -DTEST_ATOMIC_READ_FILE DEFINES += -DBACNET_READ_FILE_RECORD_COUNT=2 CFLAGS = -Wall $(INCLUDES) $(DEFINES) -g -SRCS = $(SRC_DIR)/bacdcode.c \ - $(SRC_DIR)/bacint.c \ - $(SRC_DIR)/bacstr.c \ - $(SRC_DIR)/bacreal.c \ - $(SRC_DIR)/arf.c \ +SRCS = $(SRC_DIR)/bacnet/bacdcode.c \ + $(SRC_DIR)/bacnet/bacint.c \ + $(SRC_DIR)/bacnet/bacstr.c \ + $(SRC_DIR)/bacnet/bacreal.c \ + $(SRC_DIR)/bacnet/arf.c \ ctest.c OBJS = ${SRCS:.c=.o} diff --git a/test/awf.mak b/test/awf.mak index c293325d..0acb1dc8 100644 --- a/test/awf.mak +++ b/test/awf.mak @@ -2,15 +2,15 @@ CC = gcc SRC_DIR = ../src -INCLUDES = -I../include -I. -I../demo/object +INCLUDES = -I$(SRC_DIR) -I. -I../demo/object DEFINES = -DBACFILE=1 -DBIG_ENDIAN=0 -DTEST -DTEST_ATOMIC_WRITE_FILE CFLAGS = -Wall $(INCLUDES) $(DEFINES) -g -SRCS = $(SRC_DIR)/bacdcode.c \ - $(SRC_DIR)/bacint.c \ - $(SRC_DIR)/bacstr.c \ - $(SRC_DIR)/bacreal.c \ - $(SRC_DIR)/awf.c \ +SRCS = $(SRC_DIR)/bacnet/bacdcode.c \ + $(SRC_DIR)/bacnet/bacint.c \ + $(SRC_DIR)/bacnet/bacstr.c \ + $(SRC_DIR)/bacnet/bacreal.c \ + $(SRC_DIR)/bacnet/awf.c \ ctest.c OBJS = ${SRCS:.c=.o} diff --git a/test/bacapp.mak b/test/bacapp.mak index e90d8a8e..be9a45db 100644 --- a/test/bacapp.mak +++ b/test/bacapp.mak @@ -2,20 +2,20 @@ CC = gcc SRC_DIR = ../src -INCLUDES = -I../include -I. +INCLUDES = -I$(SRC_DIR) -I. DEFINES = -DBIG_ENDIAN=0 -DTEST -DTEST_BACNET_APPLICATION_DATA CFLAGS = -Wall $(INCLUDES) $(DEFINES) -g -SRCS = $(SRC_DIR)/bacdcode.c \ - $(SRC_DIR)/bacint.c \ - $(SRC_DIR)/bacstr.c \ - $(SRC_DIR)/bacreal.c \ - $(SRC_DIR)/bacapp.c \ - $(SRC_DIR)/bacdevobjpropref.c \ - $(SRC_DIR)/datetime.c \ - $(SRC_DIR)/bactext.c \ - $(SRC_DIR)/lighting.c \ - $(SRC_DIR)/indtext.c \ +SRCS = $(SRC_DIR)/bacnet/bacdcode.c \ + $(SRC_DIR)/bacnet/bacint.c \ + $(SRC_DIR)/bacnet/bacstr.c \ + $(SRC_DIR)/bacnet/bacreal.c \ + $(SRC_DIR)/bacnet/bacapp.c \ + $(SRC_DIR)/bacnet/bacdevobjpropref.c \ + $(SRC_DIR)/bacnet/datetime.c \ + $(SRC_DIR)/bacnet/bactext.c \ + $(SRC_DIR)/bacnet/lighting.c \ + $(SRC_DIR)/bacnet/indtext.c \ ctest.c OBJS = ${SRCS:.c=.o} diff --git a/test/bacdcode.mak b/test/bacdcode.mak index c35390c9..76d7fb76 100644 --- a/test/bacdcode.mak +++ b/test/bacdcode.mak @@ -1,17 +1,17 @@ #Makefile to build unit tests CC = gcc SRC_DIR = ../src -INCLUDES = -I../include -I. +INCLUDES = -I$(SRC_DIR) -I. DEFINES = -DBIG_ENDIAN=0 -DTEST -DTEST_DECODE -DMAX_APDU=50 CFLAGS = -Wall $(INCLUDES) $(DEFINES) -g TARGET = bacdcode -SRCS = $(SRC_DIR)/bacdcode.c \ - $(SRC_DIR)/bacint.c \ - $(SRC_DIR)/bacstr.c \ - $(SRC_DIR)/bacreal.c \ +SRCS = $(SRC_DIR)/bacnet/bacdcode.c \ + $(SRC_DIR)/bacnet/bacint.c \ + $(SRC_DIR)/bacnet/bacstr.c \ + $(SRC_DIR)/bacnet/bacreal.c \ ctest.c OBJS = ${SRCS:.c=.o} diff --git a/test/bacdevobjpropref.mak b/test/bacdevobjpropref.mak index 12197a05..ebcf8465 100644 --- a/test/bacdevobjpropref.mak +++ b/test/bacdevobjpropref.mak @@ -2,20 +2,20 @@ CC = gcc SRC_DIR = ../src -INCLUDES = -I../include -I. +INCLUDES = -I$(SRC_DIR) -I. DEFINES = -DBIG_ENDIAN=0 -DTEST -DTEST_DEV_ID_PROP_REF CFLAGS = -Wall $(INCLUDES) $(DEFINES) -g -SRCS = $(SRC_DIR)/bacdcode.c \ - $(SRC_DIR)/bacint.c \ - $(SRC_DIR)/bacstr.c \ - $(SRC_DIR)/bacreal.c \ - $(SRC_DIR)/bacapp.c \ - $(SRC_DIR)/bacdevobjpropref.c \ - $(SRC_DIR)/datetime.c \ - $(SRC_DIR)/bactext.c \ - $(SRC_DIR)/lighting.c \ - $(SRC_DIR)/indtext.c \ +SRCS = $(SRC_DIR)/bacnet/bacdcode.c \ + $(SRC_DIR)/bacnet/bacint.c \ + $(SRC_DIR)/bacnet/bacstr.c \ + $(SRC_DIR)/bacnet/bacreal.c \ + $(SRC_DIR)/bacnet/bacapp.c \ + $(SRC_DIR)/bacnet/bacdevobjpropref.c \ + $(SRC_DIR)/bacnet/datetime.c \ + $(SRC_DIR)/bacnet/bactext.c \ + $(SRC_DIR)/bacnet/lighting.c \ + $(SRC_DIR)/bacnet/indtext.c \ ctest.c OBJS = ${SRCS:.c=.o} diff --git a/test/bacerror.mak b/test/bacerror.mak index d0c5357f..300933f0 100644 --- a/test/bacerror.mak +++ b/test/bacerror.mak @@ -1,16 +1,16 @@ #Makefile to build test case CC = gcc SRC_DIR = ../src -INCLUDES = -I../include -I. +INCLUDES = -I$(SRC_DIR) -I. DEFINES = -DBIG_ENDIAN=0 -DTEST -DTEST_BACERROR CFLAGS = -Wall $(INCLUDES) $(DEFINES) -g -SRCS = $(SRC_DIR)/bacdcode.c \ - $(SRC_DIR)/bacint.c \ - $(SRC_DIR)/bacstr.c \ - $(SRC_DIR)/bacreal.c \ - $(SRC_DIR)/bacerror.c \ +SRCS = $(SRC_DIR)/bacnet/bacdcode.c \ + $(SRC_DIR)/bacnet/bacint.c \ + $(SRC_DIR)/bacnet/bacstr.c \ + $(SRC_DIR)/bacnet/bacreal.c \ + $(SRC_DIR)/bacnet/bacerror.c \ ctest.c OBJS = ${SRCS:.c=.o} diff --git a/test/bacint.mak b/test/bacint.mak index 47e8222a..6d3c8943 100644 --- a/test/bacint.mak +++ b/test/bacint.mak @@ -1,15 +1,15 @@ #Makefile to build unit tests CC = gcc SRC_DIR = ../src -INCLUDES = -I../include -I. +INCLUDES = -I$(SRC_DIR) -I. DEFINES = -DBIG_ENDIAN=0 -DTEST -DTEST_BACINT CFLAGS = -Wall $(INCLUDES) $(DEFINES) -g TARGET = bacint -SRCS = $(SRC_DIR)/bacint.c \ - $(SRC_DIR)/bacstr.c \ +SRCS = $(SRC_DIR)/bacnet/bacint.c \ + $(SRC_DIR)/bacnet/bacstr.c \ ctest.c OBJS = ${SRCS:.c=.o} diff --git a/test/bacstr.mak b/test/bacstr.mak index a0ea8ab5..31d53abe 100644 --- a/test/bacstr.mak +++ b/test/bacstr.mak @@ -1,14 +1,14 @@ #Makefile to build unit tests CC = gcc SRC_DIR = ../src -INCLUDES = -I../include -I. +INCLUDES = -I$(SRC_DIR) -I. DEFINES = -DBIG_ENDIAN=0 -DTEST -DTEST_BACSTR CFLAGS = -Wall $(INCLUDES) $(DEFINES) -g TARGET = bacstr -SRCS = $(SRC_DIR)/bacstr.c \ +SRCS = $(SRC_DIR)/bacnet/bacstr.c \ ctest.c OBJS = ${SRCS:.c=.o} diff --git a/test/bbmd6.mak b/test/bbmd6.mak index d7d4d62f..47a5ca74 100644 --- a/test/bbmd6.mak +++ b/test/bbmd6.mak @@ -9,14 +9,14 @@ DEFINES = -DBIG_ENDIAN=0 -DTEST -DTEST_BBMD6 CFLAGS = -Wall -Wmissing-prototypes $(INCLUDES) $(DEFINES) -g -SRCS = $(SRC_DIR)/bacdcode.c \ - $(SRC_DIR)/bacint.c \ - $(SRC_DIR)/bacstr.c \ - $(SRC_DIR)/bacreal.c \ - $(SRC_DIR)/bvlc6.c \ - $(SRC_DIR)/debug.c \ - $(SRC_DIR)/keylist.c \ - $(SRC_DIR)/vmac.c \ +SRCS = $(SRC_DIR)/bacnet/bacdcode.c \ + $(SRC_DIR)/bacnet/bacint.c \ + $(SRC_DIR)/bacnet/bacstr.c \ + $(SRC_DIR)/bacnet/bacreal.c \ + $(SRC_DIR)/bacnet/bvlc6.c \ + $(SRC_DIR)/bacnet/debug.c \ + $(SRC_DIR)/bacnet/basic/sys/keylist.c \ + $(SRC_DIR)/bacnet/basic/bbmd6/vmac.c \ $(DEMO_DIR)/h_bbmd6.c \ ctest.c diff --git a/test/bvlc.mak b/test/bvlc.mak index 14b1869b..6290c39f 100644 --- a/test/bvlc.mak +++ b/test/bvlc.mak @@ -1,16 +1,16 @@ #Makefile to build test case CC = gcc SRC_DIR = ../src -INCLUDES = -I../include -I. -I../ports/linux +INCLUDES = -I$(SRC_DIR) -I. -I../ports/linux DEFINES = -DBACDL_BIP -DBIG_ENDIAN=0 -DTEST -DTEST_BVLC CFLAGS = -Wall $(INCLUDES) $(DEFINES) -g -SRCS = $(SRC_DIR)/bacdcode.c \ - $(SRC_DIR)/bacint.c \ - $(SRC_DIR)/bacstr.c \ - $(SRC_DIR)/bacreal.c \ - $(SRC_DIR)/bvlc.c \ +SRCS = $(SRC_DIR)/bacnet/bacdcode.c \ + $(SRC_DIR)/bacnet/bacint.c \ + $(SRC_DIR)/bacnet/bacstr.c \ + $(SRC_DIR)/bacnet/bacreal.c \ + $(SRC_DIR)/bacnet/bvlc.c \ ctest.c OBJS = ${SRCS:.c=.o} diff --git a/test/bvlc6.mak b/test/bvlc6.mak index 3467a93d..ef7b8807 100644 --- a/test/bvlc6.mak +++ b/test/bvlc6.mak @@ -1,16 +1,16 @@ #Makefile to build test case CC = gcc SRC_DIR = ../src -INCLUDES = -I../include -I. +INCLUDES = -I$(SRC_DIR) -I. DEFINES = -DBIG_ENDIAN=0 -DTEST -DTEST_BVLC6 CFLAGS = -Wall $(INCLUDES) $(DEFINES) -g -SRCS = $(SRC_DIR)/bacdcode.c \ - $(SRC_DIR)/bacint.c \ - $(SRC_DIR)/bacstr.c \ - $(SRC_DIR)/bacreal.c \ - $(SRC_DIR)/bvlc6.c \ +SRCS = $(SRC_DIR)/bacnet/bacdcode.c \ + $(SRC_DIR)/bacnet/bacint.c \ + $(SRC_DIR)/bacnet/bacstr.c \ + $(SRC_DIR)/bacnet/bacreal.c \ + $(SRC_DIR)/bacnet/datalink/bvlc6.c \ ctest.c TARGET = bvlc6 diff --git a/test/cov.mak b/test/cov.mak index 0cefa760..20a06c2b 100644 --- a/test/cov.mak +++ b/test/cov.mak @@ -1,23 +1,23 @@ #Makefile to build test case CC = gcc SRC_DIR = ../src -INCLUDES = -I../include -I. -I../demo/object +INCLUDES = -I$(SRC_DIR) -I. -I../demo/object DEFINES = -DBIG_ENDIAN=0 -DTEST -DTEST_COV -DBACAPP_ALL CFLAGS = -Wall $(INCLUDES) $(DEFINES) -g -SRCS = $(SRC_DIR)/bacdcode.c \ - $(SRC_DIR)/bacint.c \ - $(SRC_DIR)/bacstr.c \ - $(SRC_DIR)/bacreal.c \ - $(SRC_DIR)/datetime.c \ - $(SRC_DIR)/bacapp.c \ - $(SRC_DIR)/bacdevobjpropref.c \ - $(SRC_DIR)/lighting.c \ - $(SRC_DIR)/indtext.c \ - $(SRC_DIR)/memcopy.c \ - $(SRC_DIR)/bactext.c \ - $(SRC_DIR)/cov.c \ +SRCS = $(SRC_DIR)/bacnet/bacdcode.c \ + $(SRC_DIR)/bacnet/bacint.c \ + $(SRC_DIR)/bacnet/bacstr.c \ + $(SRC_DIR)/bacnet/bacreal.c \ + $(SRC_DIR)/bacnet/datetime.c \ + $(SRC_DIR)/bacnet/bacapp.c \ + $(SRC_DIR)/bacnet/bacdevobjpropref.c \ + $(SRC_DIR)/bacnet/lighting.c \ + $(SRC_DIR)/bacnet/indtext.c \ + $(SRC_DIR)/bacnet/memcopy.c \ + $(SRC_DIR)/bacnet/bactext.c \ + $(SRC_DIR)/bacnet/cov.c \ ctest.c OBJS = ${SRCS:.c=.o} diff --git a/test/crc.mak b/test/crc.mak index c2c113f7..93e46b25 100644 --- a/test/crc.mak +++ b/test/crc.mak @@ -1,12 +1,12 @@ #Makefile to build CRC tests CC = gcc SRC_DIR = ../src -INCLUDES = -I../include -I. -I../demo/object +INCLUDES = -I$(SRC_DIR) -I. -I../demo/object DEFINES = -DBIG_ENDIAN=0 -DTEST -DTEST_CRC CFLAGS = -Wall $(INCLUDES) $(DEFINES) -g -SRCS = $(SRC_DIR)/crc.c \ +SRCS = $(SRC_DIR)/bacnet/datalink/crc.c \ ctest.c OBJS = ${SRCS:.c=.o} diff --git a/test/datetime.cbp b/test/datetime.cbp new file mode 100644 index 00000000..0d099a48 --- /dev/null +++ b/test/datetime.cbp @@ -0,0 +1,85 @@ + + + + + + diff --git a/test/datetime.mak b/test/datetime.mak index 110a56d3..d77729c4 100644 --- a/test/datetime.mak +++ b/test/datetime.mak @@ -1,21 +1,21 @@ #Makefile to build test case CC = gcc SRC_DIR = ../src -INCLUDES = -I../include -I. +INCLUDES = -I$(SRC_DIR) -I. DEFINES = -DBIG_ENDIAN=0 -DTEST -DTEST_DATE_TIME CFLAGS = -Wall $(INCLUDES) $(DEFINES) -g -SRCS = $(SRC_DIR)/datetime.c \ - $(SRC_DIR)/bacdcode.c \ - $(SRC_DIR)/bacint.c \ - $(SRC_DIR)/bacstr.c \ - $(SRC_DIR)/bacreal.c \ - $(SRC_DIR)/bacapp.c \ - $(SRC_DIR)/bacdevobjpropref.c \ - $(SRC_DIR)/lighting.c \ - $(SRC_DIR)/bactext.c \ - $(SRC_DIR)/indtext.c \ +SRCS = $(SRC_DIR)/bacnet/datetime.c \ + $(SRC_DIR)/bacnet/bacdcode.c \ + $(SRC_DIR)/bacnet/bacint.c \ + $(SRC_DIR)/bacnet/bacstr.c \ + $(SRC_DIR)/bacnet/bacreal.c \ + $(SRC_DIR)/bacnet/bacapp.c \ + $(SRC_DIR)/bacnet/bacdevobjpropref.c \ + $(SRC_DIR)/bacnet/lighting.c \ + $(SRC_DIR)/bacnet/bactext.c \ + $(SRC_DIR)/bacnet/indtext.c \ ctest.c OBJS = ${SRCS:.c=.o} diff --git a/test/dcc.mak b/test/dcc.mak index aa04479b..4b85ad21 100644 --- a/test/dcc.mak +++ b/test/dcc.mak @@ -1,16 +1,16 @@ #Makefile to build test case CC = gcc SRC_DIR = ../src -INCLUDES = -I../include -I. +INCLUDES = -I$(SRC_DIR) -I. DEFINES = -DBIG_ENDIAN=0 -DTEST -DTEST_DEVICE_COMMUNICATION_CONTROL CFLAGS = -Wall $(INCLUDES) $(DEFINES) -g -SRCS = $(SRC_DIR)/bacdcode.c \ - $(SRC_DIR)/bacint.c \ - $(SRC_DIR)/bacstr.c \ - $(SRC_DIR)/bacreal.c \ - $(SRC_DIR)/dcc.c \ +SRCS = $(SRC_DIR)/bacnet/bacdcode.c \ + $(SRC_DIR)/bacnet/bacint.c \ + $(SRC_DIR)/bacnet/bacstr.c \ + $(SRC_DIR)/bacnet/bacreal.c \ + $(SRC_DIR)/bacnet/dcc.c \ ctest.c TARGET = dcc diff --git a/test/event.mak b/test/event.mak index ebd38d7b..e5888c45 100644 --- a/test/event.mak +++ b/test/event.mak @@ -1,26 +1,26 @@ #Makefile to build test case CC = gcc SRC_DIR = ../src -INCLUDES = -I../include -I. -I../demo/object +INCLUDES = -I$(SRC_DIR) -I. -I../demo/object DEFINES = -DBIG_ENDIAN=0 -DTEST -DBACAPP_ALL -DTEST_EVENT CFLAGS = -Wall $(INCLUDES) $(DEFINES) -g -SRCS = $(SRC_DIR)/bacdcode.c \ - $(SRC_DIR)/bacint.c \ - $(SRC_DIR)/bacstr.c \ - $(SRC_DIR)/bacreal.c \ - $(SRC_DIR)/bacerror.c \ - $(SRC_DIR)/bacapp.c \ - $(SRC_DIR)/bactext.c \ - $(SRC_DIR)/indtext.c \ - $(SRC_DIR)/datetime.c \ - $(SRC_DIR)/lighting.c \ - $(SRC_DIR)/memcopy.c \ - $(SRC_DIR)/timestamp.c \ - $(SRC_DIR)/bacpropstates.c \ - $(SRC_DIR)/bacdevobjpropref.c \ - $(SRC_DIR)/event.c \ +SRCS = $(SRC_DIR)/bacnet/bacdcode.c \ + $(SRC_DIR)/bacnet/bacint.c \ + $(SRC_DIR)/bacnet/bacstr.c \ + $(SRC_DIR)/bacnet/bacreal.c \ + $(SRC_DIR)/bacnet/bacerror.c \ + $(SRC_DIR)/bacnet/bacapp.c \ + $(SRC_DIR)/bacnet/bactext.c \ + $(SRC_DIR)/bacnet/indtext.c \ + $(SRC_DIR)/bacnet/datetime.c \ + $(SRC_DIR)/bacnet/lighting.c \ + $(SRC_DIR)/bacnet/memcopy.c \ + $(SRC_DIR)/bacnet/timestamp.c \ + $(SRC_DIR)/bacnet/bacpropstates.c \ + $(SRC_DIR)/bacnet/bacdevobjpropref.c \ + $(SRC_DIR)/bacnet/event.c \ ctest.c TARGET = event diff --git a/test/fifo.mak b/test/fifo.mak index 6404e16e..2be9b52e 100644 --- a/test/fifo.mak +++ b/test/fifo.mak @@ -1,12 +1,12 @@ #Makefile to build test case CC = gcc SRC_DIR = ../src -INCLUDES = -I../include -I. +INCLUDES = -I$(SRC_DIR) -I. DEFINES = -DBIG_ENDIAN=0 -DTEST -DTEST_FIFO_BUFFER CFLAGS = -Wall $(INCLUDES) $(DEFINES) -g -SRCS = $(SRC_DIR)/fifo.c \ +SRCS = $(SRC_DIR)/bacnet/basic/sys/fifo.c \ ctest.c TARGET = fifo diff --git a/test/filename.mak b/test/filename.mak index c798ae4d..8a040c4e 100644 --- a/test/filename.mak +++ b/test/filename.mak @@ -1,12 +1,12 @@ #Makefile to build filename tests CC = gcc SRC_DIR = ../src -INCLUDES = -I../include -I. +INCLUDES = -I$(SRC_DIR) -I. DEFINES = -DBIG_ENDIAN=0 -DTEST -DTEST_FILENAME CFLAGS = -Wall $(INCLUDES) $(DEFINES) -g -SRCS = $(SRC_DIR)/filename.c \ +SRCS = $(SRC_DIR)/bacnet/basic/sys/filename.c \ ctest.c OBJS = ${SRCS:.c=.o} diff --git a/test/getevent.mak b/test/getevent.mak index 07d10605..e1b9e97f 100644 --- a/test/getevent.mak +++ b/test/getevent.mak @@ -1,23 +1,23 @@ #Makefile to build test case CC = gcc SRC_DIR = ../src -INCLUDES = -I../include -I. +INCLUDES = -I$(SRC_DIR) -I. DEFINES = -DBIG_ENDIAN=0 -DTEST -DTEST_GET_EVENT_INFORMATION CFLAGS = -Wall $(INCLUDES) $(DEFINES) -g -SRCS = $(SRC_DIR)/bacdcode.c \ - $(SRC_DIR)/bacint.c \ - $(SRC_DIR)/bacstr.c \ - $(SRC_DIR)/bacreal.c \ - $(SRC_DIR)/bacapp.c \ - $(SRC_DIR)/bacdevobjpropref.c \ - $(SRC_DIR)/datetime.c \ - $(SRC_DIR)/lighting.c \ - $(SRC_DIR)/bactext.c \ - $(SRC_DIR)/indtext.c \ - $(SRC_DIR)/timestamp.c \ - $(SRC_DIR)/getevent.c \ +SRCS = $(SRC_DIR)/bacnet/bacdcode.c \ + $(SRC_DIR)/bacnet/bacint.c \ + $(SRC_DIR)/bacnet/bacstr.c \ + $(SRC_DIR)/bacnet/bacreal.c \ + $(SRC_DIR)/bacnet/bacapp.c \ + $(SRC_DIR)/bacnet/bacdevobjpropref.c \ + $(SRC_DIR)/bacnet/datetime.c \ + $(SRC_DIR)/bacnet/lighting.c \ + $(SRC_DIR)/bacnet/bactext.c \ + $(SRC_DIR)/bacnet/indtext.c \ + $(SRC_DIR)/bacnet/timestamp.c \ + $(SRC_DIR)/bacnet/getevent.c \ ctest.c TARGET = getevent diff --git a/test/iam.mak b/test/iam.mak index b5ce0ecb..56a09fa1 100755 --- a/test/iam.mak +++ b/test/iam.mak @@ -1,16 +1,16 @@ #Makefile to build test case CC = gcc SRC_DIR = ../src -INCLUDES = -I../include -I. -I../demo/object +INCLUDES = -I$(SRC_DIR) -I. -I../demo/object DEFINES = -DBIG_ENDIAN=0 -DTEST -DTEST_IAM CFLAGS = -Wall $(INCLUDES) $(DEFINES) -g -SRCS = $(SRC_DIR)/bacdcode.c \ - $(SRC_DIR)/bacint.c \ - $(SRC_DIR)/bacstr.c \ - $(SRC_DIR)/bacreal.c \ - $(SRC_DIR)/iam.c \ +SRCS = $(SRC_DIR)/bacnet/bacdcode.c \ + $(SRC_DIR)/bacnet/bacint.c \ + $(SRC_DIR)/bacnet/bacstr.c \ + $(SRC_DIR)/bacnet/bacreal.c \ + $(SRC_DIR)/bacnet/iam.c \ ctest.c OBJS = ${SRCS:.c=.o} diff --git a/test/ihave.mak b/test/ihave.mak index d379683e..5128585a 100644 --- a/test/ihave.mak +++ b/test/ihave.mak @@ -1,16 +1,16 @@ #Makefile to build test case CC = gcc SRC_DIR = ../src -INCLUDES = -I../include -I. +INCLUDES = -I$(SRC_DIR) -I. DEFINES = -DBIG_ENDIAN=0 -DTEST -DTEST_I_HAVE CFLAGS = -Wall $(INCLUDES) $(DEFINES) -g -SRCS = $(SRC_DIR)/bacdcode.c \ - $(SRC_DIR)/bacint.c \ - $(SRC_DIR)/bacstr.c \ - $(SRC_DIR)/bacreal.c \ - $(SRC_DIR)/ihave.c \ +SRCS = $(SRC_DIR)/bacnet/bacdcode.c \ + $(SRC_DIR)/bacnet/bacint.c \ + $(SRC_DIR)/bacnet/bacstr.c \ + $(SRC_DIR)/bacnet/bacreal.c \ + $(SRC_DIR)/bacnet/ihave.c \ ctest.c OBJS = ${SRCS:.c=.o} diff --git a/test/indtext.mak b/test/indtext.mak index 1be54506..bd69cf95 100644 --- a/test/indtext.mak +++ b/test/indtext.mak @@ -1,12 +1,12 @@ #Makefile to build unit tests CC = gcc SRC_DIR = ../src -INCLUDES = -I../include -I. +INCLUDES = -I$(SRC_DIR) -I. DEFINES = -DBIG_ENDIAN=0 -DTEST -DTEST_INDEX_TEXT CFLAGS = -Wall $(INCLUDES) $(DEFINES) -g -SRCS = $(SRC_DIR)/indtext.c \ +SRCS = $(SRC_DIR)/bacnet/indtext.c \ ctest.c OBJS = ${SRCS:.c=.o} diff --git a/test/key.mak b/test/key.mak index d569a589..997d67f6 100644 --- a/test/key.mak +++ b/test/key.mak @@ -1,12 +1,12 @@ #Makefile to build unit tests CC = gcc SRC_DIR = ../src -INCLUDES = -I../include -I. +INCLUDES = -I$(SRC_DIR) -I. DEFINES = -DBIG_ENDIAN=0 -DTEST -DTEST_KEY CFLAGS = -Wall $(INCLUDES) $(DEFINES) -g -SRCS = $(SRC_DIR)/key.c \ +SRCS = $(SRC_DIR)/bacnet/basic/sys/key.c \ ctest.c TARGET = key diff --git a/test/keylist.mak b/test/keylist.mak index a7fa7eb7..8fddc71f 100644 --- a/test/keylist.mak +++ b/test/keylist.mak @@ -1,12 +1,12 @@ #Makefile to build unit tests CC = gcc SRC_DIR = ../src -INCLUDES = -I../include -I. +INCLUDES = -I$(SRC_DIR) -I. DEFINES = -DBIG_ENDIAN=0 -DTEST -DTEST_KEYLIST CFLAGS = -Wall $(INCLUDES) $(DEFINES) -g -SRCS = $(SRC_DIR)/keylist.c \ +SRCS = $(SRC_DIR)/bacnet/basic/sys/keylist.c \ ctest.c TARGET = keylist diff --git a/test/lighting.mak b/test/lighting.mak index 9d852871..d50a54a6 100644 --- a/test/lighting.mak +++ b/test/lighting.mak @@ -1,16 +1,16 @@ #Makefile to build test case CC = gcc SRC_DIR = ../src -INCLUDES = -I../include -I. +INCLUDES = -I$(SRC_DIR) -I. DEFINES = -DBIG_ENDIAN=0 -DTEST -DTEST_LIGHTING_COMMAND CFLAGS = -Wall $(INCLUDES) $(DEFINES) -g -SRCS = $(SRC_DIR)/bacdcode.c \ - $(SRC_DIR)/bacint.c \ - $(SRC_DIR)/bacstr.c \ - $(SRC_DIR)/bacreal.c \ - $(SRC_DIR)/lighting.c \ +SRCS = $(SRC_DIR)/bacnet/bacdcode.c \ + $(SRC_DIR)/bacnet/bacint.c \ + $(SRC_DIR)/bacnet/bacstr.c \ + $(SRC_DIR)/bacnet/bacreal.c \ + $(SRC_DIR)/bacnet/lighting.c \ ctest.c TARGET = lighting diff --git a/test/lso.mak b/test/lso.mak index b161e560..1ef4d939 100644 --- a/test/lso.mak +++ b/test/lso.mak @@ -1,24 +1,24 @@ #Makefile to build test case CC = gcc SRC_DIR = ../src -INCLUDES = -I../include -I. +INCLUDES = -I$(SRC_DIR) -I. DEFINES = -DBIG_ENDIAN=0 -DTEST -DBACAPP_ALL -DTEST_LSO CFLAGS = -Wall $(INCLUDES) $(DEFINES) -g -SRCS = $(SRC_DIR)/bacdcode.c \ - $(SRC_DIR)/bacint.c \ - $(SRC_DIR)/bacstr.c \ - $(SRC_DIR)/bacreal.c \ - $(SRC_DIR)/bacerror.c \ - $(SRC_DIR)/bacapp.c \ - $(SRC_DIR)/bacdevobjpropref.c \ - $(SRC_DIR)/bactext.c \ - $(SRC_DIR)/indtext.c \ - $(SRC_DIR)/datetime.c \ - $(SRC_DIR)/lighting.c \ - $(SRC_DIR)/memcopy.c \ - $(SRC_DIR)/lso.c \ +SRCS = $(SRC_DIR)/bacnet/bacdcode.c \ + $(SRC_DIR)/bacnet/bacint.c \ + $(SRC_DIR)/bacnet/bacstr.c \ + $(SRC_DIR)/bacnet/bacreal.c \ + $(SRC_DIR)/bacnet/bacerror.c \ + $(SRC_DIR)/bacnet/bacapp.c \ + $(SRC_DIR)/bacnet/bacdevobjpropref.c \ + $(SRC_DIR)/bacnet/bactext.c \ + $(SRC_DIR)/bacnet/indtext.c \ + $(SRC_DIR)/bacnet/datetime.c \ + $(SRC_DIR)/bacnet/lighting.c \ + $(SRC_DIR)/bacnet/memcopy.c \ + $(SRC_DIR)/bacnet/lso.c \ ctest.c TARGET = lso diff --git a/test/memcopy.mak b/test/memcopy.mak index 3f336711..741e5a4a 100644 --- a/test/memcopy.mak +++ b/test/memcopy.mak @@ -1,12 +1,12 @@ #Makefile to build test case CC = gcc SRC_DIR = ../src -INCLUDES = -I../include -I. +INCLUDES = -I$(SRC_DIR) -I. DEFINES = -DBIG_ENDIAN=0 -DTEST -DTEST_MEM_COPY CFLAGS = -Wall $(INCLUDES) $(DEFINES) -g -SRCS = $(SRC_DIR)/memcopy.c \ +SRCS = $(SRC_DIR)/bacnet/memcopy.c \ ctest.c TARGET = memcopy diff --git a/test/mstp.mak b/test/mstp.mak index d1b3fd50..86caf4ee 100644 --- a/test/mstp.mak +++ b/test/mstp.mak @@ -1,16 +1,16 @@ #Makefile to build test case CC = gcc SRC_DIR = ../src -INCLUDES = -I../include -I. -I../ports/linux +INCLUDES = -I$(SRC_DIR) -I. -I../ports/linux DEFINES = -DBIG_ENDIAN=0 -DTEST -DTEST_MSTP CFLAGS = -Wall $(INCLUDES) $(DEFINES) -g -SRCS = $(SRC_DIR)/mstp.c \ - $(SRC_DIR)/mstptext.c \ - $(SRC_DIR)/indtext.c \ - $(SRC_DIR)/crc.c \ - $(SRC_DIR)/ringbuf.c \ +SRCS = $(SRC_DIR)/bacnet/datalink/mstp.c \ + $(SRC_DIR)/bacnet/datalink/mstptext.c \ + $(SRC_DIR)/bacnet/indtext.c \ + $(SRC_DIR)/bacnet/datalink/crc.c \ + $(SRC_DIR)/bacnet/basic/sys/ringbuf.c \ ctest.c TARGET = mstp diff --git a/test/npdu.mak b/test/npdu.mak index da781dd6..19bcfb9f 100644 --- a/test/npdu.mak +++ b/test/npdu.mak @@ -1,18 +1,18 @@ #Makefile to build test case CC = gcc SRC_DIR = ../src -INCLUDES = -I../include -I. +INCLUDES = -I$(SRC_DIR) -I. DEFINES = -DBIG_ENDIAN=0 -DTEST -DTEST_NPDU CFLAGS = -Wall $(INCLUDES) $(DEFINES) -g -SRCS = $(SRC_DIR)/bacdcode.c \ - $(SRC_DIR)/bacint.c \ - $(SRC_DIR)/bacstr.c \ - $(SRC_DIR)/bacreal.c \ - $(SRC_DIR)/npdu.c \ - $(SRC_DIR)/apdu.c \ - $(SRC_DIR)/dcc.c \ +SRCS = $(SRC_DIR)/bacnet/bacdcode.c \ + $(SRC_DIR)/bacnet/bacint.c \ + $(SRC_DIR)/bacnet/bacstr.c \ + $(SRC_DIR)/bacnet/bacreal.c \ + $(SRC_DIR)/bacnet/npdu.c \ + $(SRC_DIR)/bacnet/basic/service/h_apdu.c \ + $(SRC_DIR)/bacnet/dcc.c \ ctest.c TARGET = npdu diff --git a/test/objects.mak b/test/objects.mak index 9ef7c5a6..ae10fc8e 100644 --- a/test/objects.mak +++ b/test/objects.mak @@ -1,14 +1,14 @@ #Makefile to build test case CC = gcc SRC_DIR = ../src -INCLUDES = -I../include -I. +INCLUDES = -I$(SRC_DIR) -I. DEFINES = -DBIG_ENDIAN=0 -DTEST -DTEST_OBJECT_LIST CFLAGS = -Wall $(INCLUDES) $(DEFINES) -g -SRCS = $(SRC_DIR)/objects.c \ - $(SRC_DIR)/keylist.c \ - $(SRC_DIR)/key.c \ +SRCS = $(SRC_DIR)/bacnet/objects.c \ + $(SRC_DIR)/bacnet/basic/sys/keylist.c \ + $(SRC_DIR)/bacnet/basic/sys/key.c \ ctest.c TARGET = rp diff --git a/test/proplist.mak b/test/proplist.mak index 31b47fff..57c4f504 100644 --- a/test/proplist.mak +++ b/test/proplist.mak @@ -1,19 +1,20 @@ #Makefile to build unit tests CC = gcc SRC_DIR = ../src -INCLUDES = -I../include -I. +INCLUDES = -I$(SRC_DIR) -I. DEFINES = -DBIG_ENDIAN=0 -DTEST -DTEST_PROPLIST DEFINES += -DBACNET_PROPERTY_LISTS=1 CFLAGS = -Wall $(INCLUDES) $(DEFINES) -g -SRCS = $(SRC_DIR)/proplist.c \ - $(SRC_DIR)/bacdcode.c \ - $(SRC_DIR)/bacint.c \ - $(SRC_DIR)/bacreal.c \ - $(SRC_DIR)/bacstr.c \ - $(SRC_DIR)/datetime.c \ - $(SRC_DIR)/lighting.c \ +SRCS = $(SRC_DIR)/bacnet/proplist.c \ + $(SRC_DIR)/bacnet/property.c \ + $(SRC_DIR)/bacnet/bacdcode.c \ + $(SRC_DIR)/bacnet/bacint.c \ + $(SRC_DIR)/bacnet/bacreal.c \ + $(SRC_DIR)/bacnet/bacstr.c \ + $(SRC_DIR)/bacnet/datetime.c \ + $(SRC_DIR)/bacnet/lighting.c \ ctest.c TARGET = proplist diff --git a/test/ptransfer.mak b/test/ptransfer.mak index e284edab..62fbee2e 100644 --- a/test/ptransfer.mak +++ b/test/ptransfer.mak @@ -1,22 +1,22 @@ #Makefile to build test case CC = gcc SRC_DIR = ../src -INCLUDES = -I../include -I. +INCLUDES = -I$(SRC_DIR) -I. DEFINES = -DBIG_ENDIAN=0 -DPRINT_ENABLE=1 -DTEST -DTEST_PRIVATE_TRANSFER CFLAGS = -Wall $(INCLUDES) $(DEFINES) -g -SRCS = $(SRC_DIR)/bacdcode.c \ - $(SRC_DIR)/bacapp.c \ - $(SRC_DIR)/bacdevobjpropref.c \ - $(SRC_DIR)/bactext.c \ - $(SRC_DIR)/indtext.c \ - $(SRC_DIR)/bacint.c \ - $(SRC_DIR)/bacstr.c \ - $(SRC_DIR)/bacreal.c \ - $(SRC_DIR)/datetime.c \ - $(SRC_DIR)/lighting.c \ - $(SRC_DIR)/ptransfer.c \ +SRCS = $(SRC_DIR)/bacnet/bacdcode.c \ + $(SRC_DIR)/bacnet/bacapp.c \ + $(SRC_DIR)/bacnet/bacdevobjpropref.c \ + $(SRC_DIR)/bacnet/bactext.c \ + $(SRC_DIR)/bacnet/indtext.c \ + $(SRC_DIR)/bacnet/bacint.c \ + $(SRC_DIR)/bacnet/bacstr.c \ + $(SRC_DIR)/bacnet/bacreal.c \ + $(SRC_DIR)/bacnet/datetime.c \ + $(SRC_DIR)/bacnet/lighting.c \ + $(SRC_DIR)/bacnet/ptransfer.c \ ctest.c TARGET = ptransfer diff --git a/test/rd.mak b/test/rd.mak index 7fae4647..766f3366 100644 --- a/test/rd.mak +++ b/test/rd.mak @@ -1,16 +1,16 @@ #Makefile to build test case CC = gcc SRC_DIR = ../src -INCLUDES = -I../include -I. +INCLUDES = -I$(SRC_DIR) -I. DEFINES = -DBIG_ENDIAN=0 -DTEST -DTEST_REINITIALIZE_DEVICE CFLAGS = -Wall $(INCLUDES) $(DEFINES) -g -SRCS = $(SRC_DIR)/bacdcode.c \ - $(SRC_DIR)/bacint.c \ - $(SRC_DIR)/bacstr.c \ - $(SRC_DIR)/bacreal.c \ - $(SRC_DIR)/rd.c \ +SRCS = $(SRC_DIR)/bacnet/bacdcode.c \ + $(SRC_DIR)/bacnet/bacint.c \ + $(SRC_DIR)/bacnet/bacstr.c \ + $(SRC_DIR)/bacnet/bacreal.c \ + $(SRC_DIR)/bacnet/rd.c \ ctest.c TARGET = rd diff --git a/test/reject.mak b/test/reject.mak index 089df9d5..323e8e61 100644 --- a/test/reject.mak +++ b/test/reject.mak @@ -1,16 +1,16 @@ #Makefile to build test case CC = gcc SRC_DIR = ../src -INCLUDES = -I../include -I. +INCLUDES = -I$(SRC_DIR) -I. DEFINES = -DBIG_ENDIAN=0 -DTEST -DTEST_REJECT CFLAGS = -Wall $(INCLUDES) $(DEFINES) -g -SRCS = $(SRC_DIR)/bacdcode.c \ - $(SRC_DIR)/bacint.c \ - $(SRC_DIR)/bacstr.c \ - $(SRC_DIR)/bacreal.c \ - $(SRC_DIR)/reject.c \ +SRCS = $(SRC_DIR)/bacnet/bacdcode.c \ + $(SRC_DIR)/bacnet/bacint.c \ + $(SRC_DIR)/bacnet/bacstr.c \ + $(SRC_DIR)/bacnet/bacreal.c \ + $(SRC_DIR)/bacnet/reject.c \ ctest.c TARGET = reject diff --git a/test/ringbuf.mak b/test/ringbuf.mak index a091d8ce..b17db08e 100644 --- a/test/ringbuf.mak +++ b/test/ringbuf.mak @@ -1,12 +1,12 @@ #Makefile to build test case CC = gcc SRC_DIR = ../src -INCLUDES = -I../include -I. +INCLUDES = -I$(SRC_DIR) -I. DEFINES = -DBIG_ENDIAN=0 -DTEST -DTEST_RING_BUFFER CFLAGS = -Wall $(INCLUDES) $(DEFINES) -g -SRCS = $(SRC_DIR)/ringbuf.c \ +SRCS = $(SRC_DIR)/bacnet/basic/sys/ringbuf.c \ ctest.c TARGET = ringbuf diff --git a/test/rp.mak b/test/rp.mak index 7387fc14..7b721c51 100644 --- a/test/rp.mak +++ b/test/rp.mak @@ -1,16 +1,16 @@ #Makefile to build test case CC = gcc SRC_DIR = ../src -INCLUDES = -I../include -I. +INCLUDES = -I$(SRC_DIR) -I. DEFINES = -DBIG_ENDIAN=0 -DTEST -DTEST_READ_PROPERTY CFLAGS = -Wall $(INCLUDES) $(DEFINES) -g -SRCS = $(SRC_DIR)/bacdcode.c \ - $(SRC_DIR)/bacint.c \ - $(SRC_DIR)/bacstr.c \ - $(SRC_DIR)/bacreal.c \ - $(SRC_DIR)/rp.c \ +SRCS = $(SRC_DIR)/bacnet/bacdcode.c \ + $(SRC_DIR)/bacnet/bacint.c \ + $(SRC_DIR)/bacnet/bacstr.c \ + $(SRC_DIR)/bacnet/bacreal.c \ + $(SRC_DIR)/bacnet/rp.c \ ctest.c TARGET = rp diff --git a/test/rpm.mak b/test/rpm.mak index 3278d579..d94b9d06 100644 --- a/test/rpm.mak +++ b/test/rpm.mak @@ -1,24 +1,24 @@ #Makefile to build test case CC = gcc SRC_DIR = ../src -INCLUDES = -I../include -I. +INCLUDES = -I$(SRC_DIR) -I. DEFINES = -DBIG_ENDIAN=0 -DTEST -DBACAPP_ALL -DTEST_READ_PROPERTY_MULTIPLE CFLAGS = -Wall $(INCLUDES) $(DEFINES) -g -SRCS = $(SRC_DIR)/bacdcode.c \ - $(SRC_DIR)/bacint.c \ - $(SRC_DIR)/bacstr.c \ - $(SRC_DIR)/bacreal.c \ - $(SRC_DIR)/bacerror.c \ - $(SRC_DIR)/bacapp.c \ - $(SRC_DIR)/bacdevobjpropref.c \ - $(SRC_DIR)/bactext.c \ - $(SRC_DIR)/indtext.c \ - $(SRC_DIR)/datetime.c \ - $(SRC_DIR)/lighting.c \ - $(SRC_DIR)/memcopy.c \ - $(SRC_DIR)/rpm.c \ +SRCS = $(SRC_DIR)/bacnet/bacdcode.c \ + $(SRC_DIR)/bacnet/bacint.c \ + $(SRC_DIR)/bacnet/bacstr.c \ + $(SRC_DIR)/bacnet/bacreal.c \ + $(SRC_DIR)/bacnet/bacerror.c \ + $(SRC_DIR)/bacnet/bacapp.c \ + $(SRC_DIR)/bacnet/bacdevobjpropref.c \ + $(SRC_DIR)/bacnet/bactext.c \ + $(SRC_DIR)/bacnet/indtext.c \ + $(SRC_DIR)/bacnet/datetime.c \ + $(SRC_DIR)/bacnet/lighting.c \ + $(SRC_DIR)/bacnet/memcopy.c \ + $(SRC_DIR)/bacnet/rpm.c \ ctest.c TARGET = rpm diff --git a/test/sbuf.mak b/test/sbuf.mak index d61f20cb..be339ceb 100644 --- a/test/sbuf.mak +++ b/test/sbuf.mak @@ -1,12 +1,12 @@ #Makefile to build test case CC = gcc SRC_DIR = ../src -INCLUDES = -I../include -I. +INCLUDES = -I$(SRC_DIR) -I. DEFINES = -DBIG_ENDIAN=0 -DTEST -DTEST_STATIC_BUFFER CFLAGS = -Wall $(INCLUDES) $(DEFINES) -g -SRCS = $(SRC_DIR)/sbuf.c \ +SRCS = $(SRC_DIR)/bacnet/basic/sys/sbuf.c \ ctest.c TARGET = sbuf diff --git a/test/timer.mak b/test/timer.mak index 2019d6a8..1358d3c9 100644 --- a/test/timer.mak +++ b/test/timer.mak @@ -1,12 +1,12 @@ #Makefile to build test case CC = gcc SRC_DIR = ../ports/bdk-atxx4-mstp -INCLUDES = -I../include -I${SRC_DIR} -I. +INCLUDES = -I$(SRC_DIR) -I${SRC_DIR} -I. DEFINES = -DBIG_ENDIAN=0 -DTEST -DTEST_TIMER CFLAGS = -Wall $(INCLUDES) $(DEFINES) -g -SRCS = $(SRC_DIR)/timer.c \ +SRCS = $(SRC_DIR)/bacnet/timer.c \ ctest.c TARGET = timer diff --git a/test/timesync.mak b/test/timesync.mak index 24508c61..596df8af 100644 --- a/test/timesync.mak +++ b/test/timesync.mak @@ -10,7 +10,7 @@ # Assumes rm and cp are available SRC_DIR := ../src -INCLUDES := -I../include -I. +INCLUDES := -I$(SRC_DIR) -I. DEFINES := -DBIG_ENDIAN=0 -DTEST -DBACAPP_ALL -DTEST_TIMESYNC CFLAGS := $(INCLUDES) $(DEFINES) -g @@ -18,18 +18,18 @@ CFLAGS += -Wall TARGET := timesync -SRCS := $(SRC_DIR)/bacdcode.c \ - $(SRC_DIR)/bacint.c \ - $(SRC_DIR)/bacstr.c \ - $(SRC_DIR)/bacreal.c \ - $(SRC_DIR)/bacerror.c \ - $(SRC_DIR)/bacapp.c \ - $(SRC_DIR)/bacdevobjpropref.c \ - $(SRC_DIR)/bactext.c \ - $(SRC_DIR)/indtext.c \ - $(SRC_DIR)/datetime.c \ - $(SRC_DIR)/lighting.c \ - $(SRC_DIR)/timesync.c \ +SRCS := $(SRC_DIR)/bacnet/bacdcode.c \ + $(SRC_DIR)/bacnet/bacint.c \ + $(SRC_DIR)/bacnet/bacstr.c \ + $(SRC_DIR)/bacnet/bacreal.c \ + $(SRC_DIR)/bacnet/bacerror.c \ + $(SRC_DIR)/bacnet/bacapp.c \ + $(SRC_DIR)/bacnet/bacdevobjpropref.c \ + $(SRC_DIR)/bacnet/bactext.c \ + $(SRC_DIR)/bacnet/indtext.c \ + $(SRC_DIR)/bacnet/datetime.c \ + $(SRC_DIR)/bacnet/lighting.c \ + $(SRC_DIR)/bacnet/timesync.c \ ctest.c OBJS := ${SRCS:.c=.o} diff --git a/test/vmac.mak b/test/vmac.mak index 258a70f9..6b25fbd9 100644 --- a/test/vmac.mak +++ b/test/vmac.mak @@ -1,13 +1,13 @@ #Makefile to build test case CC = gcc SRC_DIR = ../src -INCLUDES = -I../include -I. +INCLUDES = -I$(SRC_DIR) -I. DEFINES = -DBIG_ENDIAN=0 -DTEST -DTEST_VMAC CFLAGS = -Wall -Wmissing-prototypes $(INCLUDES) $(DEFINES) -g -SRCS = $(SRC_DIR)/keylist.c \ - $(SRC_DIR)/vmac.c \ +SRCS = $(SRC_DIR)/bacnet/basic/sys/keylist.c \ + $(SRC_DIR)/bacnet/basic/bbmd6/vmac.c \ ctest.c TARGET = vmac diff --git a/test/whohas.mak b/test/whohas.mak index ae901682..b08a24b9 100644 --- a/test/whohas.mak +++ b/test/whohas.mak @@ -1,16 +1,16 @@ #Makefile to build test case CC = gcc SRC_DIR = ../src -INCLUDES = -I../include -I. +INCLUDES = -I$(SRC_DIR) -I. DEFINES = -DBIG_ENDIAN=0 -DTEST -DTEST_WHOHAS CFLAGS = -Wall $(INCLUDES) $(DEFINES) -g -SRCS = $(SRC_DIR)/bacdcode.c \ - $(SRC_DIR)/bacint.c \ - $(SRC_DIR)/bacstr.c \ - $(SRC_DIR)/bacreal.c \ - $(SRC_DIR)/whohas.c \ +SRCS = $(SRC_DIR)/bacnet/bacdcode.c \ + $(SRC_DIR)/bacnet/bacint.c \ + $(SRC_DIR)/bacnet/bacstr.c \ + $(SRC_DIR)/bacnet/bacreal.c \ + $(SRC_DIR)/bacnet/whohas.c \ ctest.c TARGET = whohas diff --git a/test/whois.mak b/test/whois.mak index 54d0e88f..05d69871 100644 --- a/test/whois.mak +++ b/test/whois.mak @@ -1,16 +1,16 @@ #Makefile to build test case CC = gcc SRC_DIR = ../src -INCLUDES = -I../include -I. +INCLUDES = -I$(SRC_DIR) -I. DEFINES = -DBIG_ENDIAN=0 -DTEST -DTEST_WHOIS CFLAGS = -Wall $(INCLUDES) $(DEFINES) -g -SRCS = $(SRC_DIR)/bacdcode.c \ - $(SRC_DIR)/bacint.c \ - $(SRC_DIR)/bacstr.c \ - $(SRC_DIR)/bacreal.c \ - $(SRC_DIR)/whois.c \ +SRCS = $(SRC_DIR)/bacnet/bacdcode.c \ + $(SRC_DIR)/bacnet/bacint.c \ + $(SRC_DIR)/bacnet/bacstr.c \ + $(SRC_DIR)/bacnet/bacreal.c \ + $(SRC_DIR)/bacnet/whois.c \ ctest.c TARGET = whois diff --git a/test/wp.mak b/test/wp.mak index 771ff7ee..7b00c269 100644 --- a/test/wp.mak +++ b/test/wp.mak @@ -1,22 +1,22 @@ #Makefile to build test case CC = gcc SRC_DIR = ../src -INCLUDES = -I../include -I. +INCLUDES = -I$(SRC_DIR) -I. DEFINES = -DBIG_ENDIAN=0 -DTEST -DBACAPP_ALL -DTEST_WRITE_PROPERTY CFLAGS = -Wall $(INCLUDES) $(DEFINES) -g -SRCS = $(SRC_DIR)/bacdcode.c \ - $(SRC_DIR)/bacint.c \ - $(SRC_DIR)/bacstr.c \ - $(SRC_DIR)/bacreal.c \ - $(SRC_DIR)/datetime.c \ - $(SRC_DIR)/lighting.c \ - $(SRC_DIR)/bacapp.c \ - $(SRC_DIR)/bacdevobjpropref.c \ - $(SRC_DIR)/bactext.c \ - $(SRC_DIR)/indtext.c \ - $(SRC_DIR)/wp.c \ +SRCS = $(SRC_DIR)/bacnet/bacdcode.c \ + $(SRC_DIR)/bacnet/bacint.c \ + $(SRC_DIR)/bacnet/bacstr.c \ + $(SRC_DIR)/bacnet/bacreal.c \ + $(SRC_DIR)/bacnet/datetime.c \ + $(SRC_DIR)/bacnet/lighting.c \ + $(SRC_DIR)/bacnet/bacapp.c \ + $(SRC_DIR)/bacnet/bacdevobjpropref.c \ + $(SRC_DIR)/bacnet/bactext.c \ + $(SRC_DIR)/bacnet/indtext.c \ + $(SRC_DIR)/bacnet/wp.c \ ctest.c TARGET = wp