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
This commit is contained in:
+10
-2
@@ -1,10 +1,18 @@
|
|||||||
---
|
---
|
||||||
BasedOnStyle: Google
|
BasedOnStyle: WebKit
|
||||||
|
BinPackParameters: false
|
||||||
|
AlignEscapedNewlines: Left
|
||||||
|
PointerAlignment: Right
|
||||||
AllowShortFunctionsOnASingleLine: None
|
AllowShortFunctionsOnASingleLine: None
|
||||||
AllowShortIfStatementsOnASingleLine: false
|
AllowShortIfStatementsOnASingleLine: false
|
||||||
AllowShortLoopsOnASingleLine: false
|
AllowShortLoopsOnASingleLine: false
|
||||||
AlwaysBreakAfterReturnType: None
|
|
||||||
BreakBeforeBraces: Linux
|
BreakBeforeBraces: Linux
|
||||||
|
BreakBeforeBinaryOperators: None
|
||||||
|
KeepEmptyLinesAtTheStartOfBlocks: false
|
||||||
|
PenaltyBreakBeforeFirstCallParameter: 1
|
||||||
|
IndentCaseLabels: true
|
||||||
IndentWidth: 4
|
IndentWidth: 4
|
||||||
|
UseTab: Never
|
||||||
SortIncludes: false
|
SortIncludes: false
|
||||||
|
ColumnLimit: 80
|
||||||
...
|
...
|
||||||
|
|||||||
@@ -4,19 +4,29 @@
|
|||||||
# Explicitly declare text files you want to always be normalized and converted
|
# Explicitly declare text files you want to always be normalized and converted
|
||||||
# to native line endings on checkout.
|
# to native line endings on checkout.
|
||||||
*.c text
|
*.c text
|
||||||
|
*.cpp text
|
||||||
|
*.cxx text
|
||||||
*.h text
|
*.h text
|
||||||
|
*.hpp text
|
||||||
*.s text
|
*.s text
|
||||||
Makefile.* text
|
Makefile.* text
|
||||||
Makefile text
|
Makefile text
|
||||||
*.mak text
|
*.mak text
|
||||||
*.MAK text
|
*.MAK text
|
||||||
*.xml text
|
*.xml text
|
||||||
|
*.aps text
|
||||||
*.mcp text
|
*.mcp text
|
||||||
|
*.hwp text
|
||||||
*.lkr text
|
*.lkr text
|
||||||
*.lua text
|
*.lua text
|
||||||
*.txt text
|
*.txt text
|
||||||
|
*.htm text
|
||||||
.cproject text
|
.cproject text
|
||||||
.project text
|
.project text
|
||||||
|
.gdbinit text
|
||||||
|
.slintrc text
|
||||||
|
*.sh text
|
||||||
|
README.* text
|
||||||
|
|
||||||
# Declare files that will always have CRLF line endings on checkout.
|
# Declare files that will always have CRLF line endings on checkout.
|
||||||
*.sln text eol=crlf
|
*.sln text eol=crlf
|
||||||
|
|||||||
+11
@@ -17,6 +17,7 @@
|
|||||||
*.config
|
*.config
|
||||||
*.pbd
|
*.pbd
|
||||||
*.ewd
|
*.ewd
|
||||||
|
*.ewt
|
||||||
*.d
|
*.d
|
||||||
*.r90
|
*.r90
|
||||||
*.r90
|
*.r90
|
||||||
@@ -44,5 +45,15 @@
|
|||||||
*.hex
|
*.hex
|
||||||
*.elf
|
*.elf
|
||||||
*.emSession
|
*.emSession
|
||||||
|
*.depend
|
||||||
|
*.layout
|
||||||
tags
|
tags
|
||||||
test-results.xml
|
test-results.xml
|
||||||
|
.vscode/
|
||||||
|
.vs/
|
||||||
|
Debug/
|
||||||
|
settings/
|
||||||
|
*.componentinfo.xml
|
||||||
|
bin/
|
||||||
|
Backup*
|
||||||
|
BACnet_BDT_table
|
||||||
|
|||||||
@@ -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
|
|
||||||
@@ -1,144 +1,127 @@
|
|||||||
# Main Makefile for BACnet-stack project with GCC
|
# Main Makefile for BACnet-stack applications, tests, and sample ports
|
||||||
|
|
||||||
# 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)
|
|
||||||
|
|
||||||
# Export the variables defined here to all subprocesses
|
# Export the variables defined here to all subprocesses
|
||||||
# (see http://www.gnu.org/software/automake/manual/make/Special-Targets.html)
|
# (see http://www.gnu.org/software/automake/manual/make/Special-Targets.html)
|
||||||
.EXPORT_ALL_VARIABLES:
|
.EXPORT_ALL_VARIABLES:
|
||||||
|
|
||||||
all: library demos router-ipv6 ${DEMO_LINUX}
|
# all: demos router-ipv6 ${DEMO_LINUX}
|
||||||
.PHONY : all library demos router gateway router-ipv6 clean test
|
|
||||||
|
|
||||||
library:
|
.PHONY: all
|
||||||
$(MAKE) -s -C lib all
|
all: apps
|
||||||
|
|
||||||
demos:
|
.PHONY: win32
|
||||||
$(MAKE) -C demo all
|
win32:
|
||||||
|
$(MAKE) BACNET_PORT=win32 -C apps all
|
||||||
|
|
||||||
gateway:
|
.PHONY: apps
|
||||||
$(MAKE) -B -s -C demo gateway
|
apps:
|
||||||
|
$(MAKE) -s -C apps all
|
||||||
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: abort
|
||||||
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:
|
error:
|
||||||
$(MAKE) -B -C demo error
|
$(MAKE) -s -C apps $@
|
||||||
|
|
||||||
router: library
|
.PHONY: iam
|
||||||
$(MAKE) -s -C demo router
|
iam:
|
||||||
|
$(MAKE) -s -C apps $@
|
||||||
|
|
||||||
router-ipv6: library
|
.PHONY: getevent
|
||||||
$(MAKE) -B -s -C demo router-ipv6
|
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
|
# Add "ports" to the build, if desired
|
||||||
|
.PHONY: ports
|
||||||
ports: atmega168 bdk-atxx4-mstp at91sam7s stm32f10x
|
ports: atmega168 bdk-atxx4-mstp at91sam7s stm32f10x
|
||||||
@echo "Built the ARM7 and AVR ports"
|
@echo "Built the ARM7 and AVR ports"
|
||||||
|
|
||||||
|
.PHONY: atmega168
|
||||||
atmega168: ports/atmega168/Makefile
|
atmega168: ports/atmega168/Makefile
|
||||||
$(MAKE) -s -C ports/atmega168 clean all
|
$(MAKE) -s -C ports/atmega168 clean all
|
||||||
|
|
||||||
|
.PHONY: at91sam7s
|
||||||
at91sam7s: ports/at91sam7s/Makefile
|
at91sam7s: ports/at91sam7s/Makefile
|
||||||
$(MAKE) -s -C ports/at91sam7s clean all
|
$(MAKE) -s -C ports/at91sam7s clean all
|
||||||
|
|
||||||
|
.PHONY: stm32f10x
|
||||||
stm32f10x: ports/stm32f10x/Makefile
|
stm32f10x: ports/stm32f10x/Makefile
|
||||||
$(MAKE) -s -C ports/stm32f10x clean all
|
$(MAKE) -s -C ports/stm32f10x clean all
|
||||||
|
|
||||||
|
.PHONY: mstpsnap
|
||||||
mstpsnap: ports/linux/mstpsnap.mak
|
mstpsnap: ports/linux/mstpsnap.mak
|
||||||
$(MAKE) -s -C ports/linux -f mstpsnap.mak clean all
|
$(MAKE) -s -C ports/linux -f mstpsnap.mak clean all
|
||||||
|
|
||||||
|
.PHONY: bdk-atxx4-mstp
|
||||||
bdk-atxx4-mstp: ports/bdk-atxx4-mstp/Makefile
|
bdk-atxx4-mstp: ports/bdk-atxx4-mstp/Makefile
|
||||||
$(MAKE) -s -C ports/bdk-atxx4-mstp clean all
|
$(MAKE) -s -C ports/bdk-atxx4-mstp clean all
|
||||||
|
|
||||||
|
.PHONY: pretty
|
||||||
pretty:
|
pretty:
|
||||||
find ./src -iname *.h -o -iname *.c -exec clang-format -i -style=file -fallback-style=none {} \;
|
find ./src -iname *.h -o -iname *.c -exec \
|
||||||
find ./include -iname *.h -o -iname *.c -exec clang-format -i -style=file -fallback-style=none {} \;
|
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 ./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:
|
clean:
|
||||||
$(MAKE) -s -C lib clean
|
$(MAKE) -s -C src clean
|
||||||
$(MAKE) -s -C demo clean
|
$(MAKE) -s -C apps clean
|
||||||
$(MAKE) -s -C demo/router clean
|
$(MAKE) -s -C apps/router clean
|
||||||
$(MAKE) -s -C demo/router-ipv6 clean
|
$(MAKE) -s -C apps/router-ipv6 clean
|
||||||
$(MAKE) -s -C demo/gateway clean
|
$(MAKE) -s -C apps/gateway clean
|
||||||
|
|
||||||
|
.PHONY: test
|
||||||
test:
|
test:
|
||||||
$(MAKE) -s -C test clean
|
$(MAKE) -s -C test clean
|
||||||
$(MAKE) -s -C test all
|
$(MAKE) -s -C test all
|
||||||
$(MAKE) -s -C test report
|
$(MAKE) -s -C test report
|
||||||
$(MAKE) -s -C demo/object clean
|
|
||||||
$(MAKE) -s -C demo/object all
|
|
||||||
$(MAKE) -s -C demo/object report
|
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
I hope that you get your BACnet Device working! If not, join us on the
|
||||||
mailing list and we can help.
|
mailing list and we can help.
|
||||||
|
|
||||||
Steve Karg
|
Steve Karg, Birmingham, Alabama USA
|
||||||
Birmingham, Alabama USA
|
|
||||||
skarg@users.sourceforge.net
|
skarg@users.sourceforge.net
|
||||||
|
|
||||||
ASHRAE® and BACnet® are registered trademarks of the
|
ASHRAE® and BACnet® are registered trademarks of the
|
||||||
|
|||||||
+275
@@ -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 $@
|
||||||
@@ -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
|
||||||
|
|
||||||
@@ -30,22 +30,21 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <time.h> /* for time */
|
#include <time.h> /* for time */
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include "bactext.h"
|
#include "bacnet/bactext.h"
|
||||||
#include "iam.h"
|
#include "bacnet/iam.h"
|
||||||
#include "address.h"
|
#include "bacnet/config.h"
|
||||||
#include "config.h"
|
#include "bacnet/bacdef.h"
|
||||||
#include "bacdef.h"
|
#include "bacnet/npdu.h"
|
||||||
#include "npdu.h"
|
#include "bacnet/apdu.h"
|
||||||
#include "apdu.h"
|
#include "bacnet/version.h"
|
||||||
#include "device.h"
|
|
||||||
#include "datalink.h"
|
|
||||||
#include "version.h"
|
|
||||||
/* some demo stuff needed */
|
/* some demo stuff needed */
|
||||||
#include "filename.h"
|
#include "bacnet/basic/binding/address.h"
|
||||||
#include "handlers.h"
|
#include "bacnet/basic/object/device.h"
|
||||||
#include "client.h"
|
#include "bacnet/basic/services.h"
|
||||||
#include "txbuf.h"
|
#include "bacnet/basic/sys/filename.h"
|
||||||
#include "dlenv.h"
|
#include "bacnet/basic/tsm/tsm.h"
|
||||||
|
#include "bacnet/datalink/datalink.h"
|
||||||
|
#include "bacnet/datalink/dlenv.h"
|
||||||
|
|
||||||
/* parsed command line parameters */
|
/* parsed command line parameters */
|
||||||
static uint8_t Target_Invoke_ID = 1;
|
static uint8_t Target_Invoke_ID = 1;
|
||||||
@@ -54,8 +53,8 @@ static bool Target_Server = true;
|
|||||||
/* flag for signalling errors */
|
/* flag for signalling errors */
|
||||||
static bool Error_Detected = false;
|
static bool Error_Detected = false;
|
||||||
|
|
||||||
void MyAbortHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
|
static void MyAbortHandler(
|
||||||
uint8_t abort_reason, bool server)
|
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t abort_reason, bool server)
|
||||||
{
|
{
|
||||||
(void)src;
|
(void)src;
|
||||||
(void)invoke_id;
|
(void)invoke_id;
|
||||||
@@ -64,8 +63,8 @@ void MyAbortHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
|
|||||||
Error_Detected = true;
|
Error_Detected = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
|
static void MyRejectHandler(
|
||||||
uint8_t reject_reason)
|
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||||
{
|
{
|
||||||
(void)src;
|
(void)src;
|
||||||
(void)invoke_id;
|
(void)invoke_id;
|
||||||
@@ -83,8 +82,8 @@ static void Init_Service_Handlers(void)
|
|||||||
It is required to send the proper reject message... */
|
It is required to send the proper reject message... */
|
||||||
apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service);
|
apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service);
|
||||||
/* we must implement read property - it's required! */
|
/* we must implement read property - it's required! */
|
||||||
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY,
|
apdu_set_confirmed_handler(
|
||||||
handler_read_property);
|
SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property);
|
||||||
/* handle the reply (request) coming back */
|
/* handle the reply (request) coming back */
|
||||||
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_I_AM, handler_i_am_add);
|
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_I_AM, handler_i_am_add);
|
||||||
/* handle any errors coming back */
|
/* 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 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"
|
"or an Ethernet MAC in hex like 00:21:70:7e:32:bb\n"
|
||||||
"\n");
|
"\n");
|
||||||
printf(
|
printf("abort-reason:\n"
|
||||||
"abort-reason:\n"
|
" number from 0 to 65535\n"
|
||||||
" number from 0 to 65535\n"
|
"invoke-id:\n"
|
||||||
"invoke-id:\n"
|
" number from 1 to 255\n"
|
||||||
" number from 1 to 255\n"
|
"server:\n"
|
||||||
"server:\n"
|
" 0=false, 1=true\n"
|
||||||
" 0=false, 1=true\n"
|
"Example:\n"
|
||||||
"Example:\n"
|
"%s 3 2 1\n",
|
||||||
"%s 3 2 1\n",
|
|
||||||
filename);
|
filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
long dnet = -1;
|
long dnet = -1;
|
||||||
BACNET_MAC_ADDRESS mac = {0};
|
BACNET_MAC_ADDRESS mac = { 0 };
|
||||||
BACNET_MAC_ADDRESS adr = {0};
|
BACNET_MAC_ADDRESS adr = { 0 };
|
||||||
BACNET_ADDRESS dest = {0};
|
BACNET_ADDRESS dest = { 0 };
|
||||||
bool specific_address = false;
|
bool specific_address = false;
|
||||||
int argi = 0;
|
int argi = 0;
|
||||||
unsigned int target_args = 0;
|
unsigned int target_args = 0;
|
||||||
@@ -153,12 +151,11 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
if (strcmp(argv[argi], "--version") == 0) {
|
if (strcmp(argv[argi], "--version") == 0) {
|
||||||
printf("%s %s\n", filename, BACNET_VERSION_TEXT);
|
printf("%s %s\n", filename, BACNET_VERSION_TEXT);
|
||||||
printf(
|
printf("Copyright (C) 2016 by Steve Karg and others.\n"
|
||||||
"Copyright (C) 2016 by Steve Karg and others.\n"
|
"This is free software; see the source for copying "
|
||||||
"This is free software; see the source for copying "
|
"conditions.\n"
|
||||||
"conditions.\n"
|
"There is NO warranty; not even for MERCHANTABILITY or\n"
|
||||||
"There is NO warranty; not even for MERCHANTABILITY or\n"
|
"FITNESS FOR A PARTICULAR PURPOSE.\n");
|
||||||
"FITNESS FOR A PARTICULAR PURPOSE.\n");
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (strcmp(argv[argi], "--mac") == 0) {
|
if (strcmp(argv[argi], "--mac") == 0) {
|
||||||
@@ -235,7 +232,7 @@ int main(int argc, char *argv[])
|
|||||||
atexit(datalink_cleanup);
|
atexit(datalink_cleanup);
|
||||||
/* send the request */
|
/* send the request */
|
||||||
Send_Abort_To_Network(&Handler_Transmit_Buffer[0], &dest, Target_Invoke_ID,
|
Send_Abort_To_Network(&Handler_Transmit_Buffer[0], &dest, Target_Invoke_ID,
|
||||||
Target_Abort_Reason, Target_Server);
|
Target_Abort_Reason, Target_Server);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -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
|
||||||
|
|
||||||
@@ -30,30 +30,30 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <time.h> /* for time */
|
#include <time.h> /* for time */
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include "bactext.h"
|
#include "bacnet/bactext.h"
|
||||||
#include "iam.h"
|
#include "bacnet/iam.h"
|
||||||
#include "arf.h"
|
#include "bacnet/arf.h"
|
||||||
#include "tsm.h"
|
#include "bacnet/basic/tsm/tsm.h"
|
||||||
#include "address.h"
|
#include "bacnet/basic/binding/address.h"
|
||||||
#include "config.h"
|
#include "bacnet/config.h"
|
||||||
#include "bacdef.h"
|
#include "bacnet/bacdef.h"
|
||||||
#include "npdu.h"
|
#include "bacnet/npdu.h"
|
||||||
#include "apdu.h"
|
#include "bacnet/apdu.h"
|
||||||
#include "device.h"
|
#include "bacnet/basic/object/device.h"
|
||||||
#include "net.h"
|
#include "bacport.h"
|
||||||
#include "datalink.h"
|
#include "bacnet/datalink/datalink.h"
|
||||||
#include "whois.h"
|
#include "bacnet/whois.h"
|
||||||
#include "dcc.h"
|
#include "bacnet/dcc.h"
|
||||||
#include "version.h"
|
#include "bacnet/version.h"
|
||||||
/* some demo stuff needed */
|
/* some demo stuff needed */
|
||||||
#include "filename.h"
|
#include "bacnet/basic/sys/filename.h"
|
||||||
#include "handlers.h"
|
#include "bacnet/basic/services.h"
|
||||||
#include "client.h"
|
#include "bacnet/basic/services.h"
|
||||||
#include "txbuf.h"
|
#include "bacnet/basic/tsm/tsm.h"
|
||||||
#include "dlenv.h"
|
#include "bacnet/datalink/dlenv.h"
|
||||||
|
|
||||||
/* buffer used for receive */
|
/* 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 */
|
/* global variables used in this file */
|
||||||
static uint32_t Target_Device_Object_Instance = BACNET_MAX_INSTANCE;
|
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 bool Error_Detected = false;
|
||||||
|
|
||||||
static void MyErrorHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
|
static void MyErrorHandler(BACNET_ADDRESS *src,
|
||||||
BACNET_ERROR_CLASS error_class,
|
uint8_t invoke_id,
|
||||||
BACNET_ERROR_CODE error_code)
|
BACNET_ERROR_CLASS error_class,
|
||||||
|
BACNET_ERROR_CODE error_code)
|
||||||
{
|
{
|
||||||
/* FIXME: verify src and invoke id */
|
/* FIXME: verify src and invoke id */
|
||||||
(void)src;
|
(void)src;
|
||||||
(void)invoke_id;
|
(void)invoke_id;
|
||||||
printf("BACnet Error: %s: %s\n", bactext_error_class_name(error_class),
|
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;
|
Error_Detected = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MyAbortHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
|
static void MyAbortHandler(
|
||||||
uint8_t abort_reason, bool server)
|
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t abort_reason, bool server)
|
||||||
{
|
{
|
||||||
/* FIXME: verify src and invoke id */
|
/* FIXME: verify src and invoke id */
|
||||||
(void)src;
|
(void)src;
|
||||||
@@ -88,8 +89,8 @@ void MyAbortHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
|
|||||||
Error_Detected = true;
|
Error_Detected = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
|
static void MyRejectHandler(
|
||||||
uint8_t reject_reason)
|
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||||
{
|
{
|
||||||
/* FIXME: verify src and invoke id */
|
/* FIXME: verify src and invoke id */
|
||||||
(void)src;
|
(void)src;
|
||||||
@@ -98,8 +99,8 @@ void MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
|
|||||||
Error_Detected = true;
|
Error_Detected = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MyDeviceCommunicationControlSimpleAckHandler(BACNET_ADDRESS *src,
|
static void MyDeviceCommunicationControlSimpleAckHandler(
|
||||||
uint8_t invoke_id)
|
BACNET_ADDRESS *src, uint8_t invoke_id)
|
||||||
{
|
{
|
||||||
(void)src;
|
(void)src;
|
||||||
(void)invoke_id;
|
(void)invoke_id;
|
||||||
@@ -118,18 +119,18 @@ static void Init_Service_Handlers(void)
|
|||||||
It is required to send the proper reject message... */
|
It is required to send the proper reject message... */
|
||||||
apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service);
|
apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service);
|
||||||
/* we must implement read property - it's required! */
|
/* we must implement read property - it's required! */
|
||||||
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY,
|
apdu_set_confirmed_handler(
|
||||||
handler_read_property);
|
SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property);
|
||||||
/* handle communication so we can shutup when asked */
|
/* handle communication so we can shutup when asked */
|
||||||
apdu_set_confirmed_handler(SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL,
|
apdu_set_confirmed_handler(SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL,
|
||||||
handler_device_communication_control);
|
handler_device_communication_control);
|
||||||
/* handle the ack coming back */
|
/* handle the ack coming back */
|
||||||
apdu_set_confirmed_simple_ack_handler(
|
apdu_set_confirmed_simple_ack_handler(
|
||||||
SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL,
|
SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL,
|
||||||
MyDeviceCommunicationControlSimpleAckHandler);
|
MyDeviceCommunicationControlSimpleAckHandler);
|
||||||
/* handle any errors coming back */
|
/* handle any errors coming back */
|
||||||
apdu_set_error_handler(SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL,
|
apdu_set_error_handler(
|
||||||
MyErrorHandler);
|
SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL, MyErrorHandler);
|
||||||
apdu_set_abort_handler(MyAbortHandler);
|
apdu_set_abort_handler(MyAbortHandler);
|
||||||
apdu_set_reject_handler(MyRejectHandler);
|
apdu_set_reject_handler(MyRejectHandler);
|
||||||
}
|
}
|
||||||
@@ -162,7 +163,7 @@ static void print_help(char *filename)
|
|||||||
|
|
||||||
int main(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;
|
uint16_t pdu_len = 0;
|
||||||
unsigned timeout = 100; /* milliseconds */
|
unsigned timeout = 100; /* milliseconds */
|
||||||
unsigned max_apdu = 0;
|
unsigned max_apdu = 0;
|
||||||
@@ -184,12 +185,11 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
if (strcmp(argv[argi], "--version") == 0) {
|
if (strcmp(argv[argi], "--version") == 0) {
|
||||||
printf("%s %s\n", filename, BACNET_VERSION_TEXT);
|
printf("%s %s\n", filename, BACNET_VERSION_TEXT);
|
||||||
printf(
|
printf("Copyright (C) 2014 by Steve Karg and others.\n"
|
||||||
"Copyright (C) 2014 by Steve Karg and others.\n"
|
"This is free software; see the source for copying "
|
||||||
"This is free software; see the source for copying "
|
"conditions.\n"
|
||||||
"conditions.\n"
|
"There is NO warranty; not even for MERCHANTABILITY or\n"
|
||||||
"There is NO warranty; not even for MERCHANTABILITY or\n"
|
"FITNESS FOR A PARTICULAR PURPOSE.\n");
|
||||||
"FITNESS FOR A PARTICULAR PURPOSE.\n");
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -210,7 +210,7 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
if (Target_Device_Object_Instance >= BACNET_MAX_INSTANCE) {
|
if (Target_Device_Object_Instance >= BACNET_MAX_INSTANCE) {
|
||||||
fprintf(stderr, "device-instance=%u - it must be less than %u\n",
|
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;
|
return 1;
|
||||||
}
|
}
|
||||||
/* setup my info */
|
/* setup my info */
|
||||||
@@ -223,11 +223,11 @@ int main(int argc, char *argv[])
|
|||||||
last_seconds = time(NULL);
|
last_seconds = time(NULL);
|
||||||
timeout_seconds = (apdu_timeout() / 1000) * apdu_retries();
|
timeout_seconds = (apdu_timeout() / 1000) * apdu_retries();
|
||||||
/* try to bind with the device */
|
/* try to bind with the device */
|
||||||
found = address_bind_request(Target_Device_Object_Instance, &max_apdu,
|
found = address_bind_request(
|
||||||
&Target_Address);
|
Target_Device_Object_Instance, &max_apdu, &Target_Address);
|
||||||
if (!found) {
|
if (!found) {
|
||||||
Send_WhoIs(Target_Device_Object_Instance,
|
Send_WhoIs(
|
||||||
Target_Device_Object_Instance);
|
Target_Device_Object_Instance, Target_Device_Object_Instance);
|
||||||
}
|
}
|
||||||
/* loop forever */
|
/* loop forever */
|
||||||
for (;;) {
|
for (;;) {
|
||||||
@@ -242,15 +242,16 @@ int main(int argc, char *argv[])
|
|||||||
npdu_handler(&src, &Rx_Buf[0], pdu_len);
|
npdu_handler(&src, &Rx_Buf[0], pdu_len);
|
||||||
}
|
}
|
||||||
/* at least one second has passed */
|
/* at least one second has passed */
|
||||||
if (current_seconds != last_seconds)
|
if (current_seconds != last_seconds) {
|
||||||
tsm_timer_milliseconds(
|
tsm_timer_milliseconds(
|
||||||
(uint16_t)((current_seconds - last_seconds) * 1000));
|
(uint16_t)((current_seconds - last_seconds) * 1000));
|
||||||
|
}
|
||||||
if (Error_Detected)
|
if (Error_Detected)
|
||||||
break;
|
break;
|
||||||
/* wait until the device is bound, or timeout and quit */
|
/* wait until the device is bound, or timeout and quit */
|
||||||
if (!found) {
|
if (!found) {
|
||||||
found = address_bind_request(Target_Device_Object_Instance,
|
found = address_bind_request(
|
||||||
&max_apdu, &Target_Address);
|
Target_Device_Object_Instance, &max_apdu, &Target_Address);
|
||||||
}
|
}
|
||||||
if (found) {
|
if (found) {
|
||||||
if (invoke_id == 0) {
|
if (invoke_id == 0) {
|
||||||
@@ -258,9 +259,9 @@ int main(int argc, char *argv[])
|
|||||||
Target_Device_Object_Instance,
|
Target_Device_Object_Instance,
|
||||||
Communication_Timeout_Minutes, Communication_State,
|
Communication_Timeout_Minutes, Communication_State,
|
||||||
Communication_Password);
|
Communication_Password);
|
||||||
} else if (tsm_invoke_id_free(invoke_id))
|
} else if (tsm_invoke_id_free(invoke_id)) {
|
||||||
break;
|
break;
|
||||||
else if (tsm_invoke_id_failed(invoke_id)) {
|
} else if (tsm_invoke_id_failed(invoke_id)) {
|
||||||
fprintf(stderr, "\rError: TSM Timeout!\n");
|
fprintf(stderr, "\rError: TSM Timeout!\n");
|
||||||
tsm_free_invoke_id(invoke_id);
|
tsm_free_invoke_id(invoke_id);
|
||||||
/* try again or abort? */
|
/* try again or abort? */
|
||||||
@@ -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
|
||||||
|
|
||||||
@@ -0,0 +1,305 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
|
||||||
|
<CodeBlocks_project_file>
|
||||||
|
<FileVersion major="1" minor="6" />
|
||||||
|
<Project>
|
||||||
|
<Option title="BACnet EPICS Demo" />
|
||||||
|
<Option pch_mode="2" />
|
||||||
|
<Option compiler="gcc" />
|
||||||
|
<Build>
|
||||||
|
<Target title="Debug">
|
||||||
|
<Option output="bin/Debug/bacepics" prefix_auto="1" extension_auto="1" />
|
||||||
|
<Option object_output="obj/Debug/" />
|
||||||
|
<Option type="1" />
|
||||||
|
<Option compiler="gcc" />
|
||||||
|
<Compiler>
|
||||||
|
<Add option="-g" />
|
||||||
|
</Compiler>
|
||||||
|
</Target>
|
||||||
|
<Target title="Release">
|
||||||
|
<Option output="bin/Release/bacepics" prefix_auto="1" extension_auto="1" />
|
||||||
|
<Option object_output="obj/Release/" />
|
||||||
|
<Option type="1" />
|
||||||
|
<Option compiler="gcc" />
|
||||||
|
<Compiler>
|
||||||
|
<Add option="-O2" />
|
||||||
|
</Compiler>
|
||||||
|
<Linker>
|
||||||
|
<Add option="-s" />
|
||||||
|
</Linker>
|
||||||
|
</Target>
|
||||||
|
</Build>
|
||||||
|
<Compiler>
|
||||||
|
<Add option="-Wmissing-declarations" />
|
||||||
|
<Add option="-Wall" />
|
||||||
|
<Add option="-m32" />
|
||||||
|
<Add option="-ffunction-sections" />
|
||||||
|
<Add option="-fdata-sections" />
|
||||||
|
<Add option="-DBACDL_BIP" />
|
||||||
|
<Add option="-DPRINT_ENABLED=1" />
|
||||||
|
<Add option="-DBACAPP_ALL" />
|
||||||
|
<Add option="-DBACFILE" />
|
||||||
|
<Add option="-DBACNET_TIME_MASTER" />
|
||||||
|
<Add option="-DBACNET_PROPERTY_LISTS=1" />
|
||||||
|
<Add option="-DBACNET_PROTOCOL_REVISION=17" />
|
||||||
|
<Add option="-D_NO_OLDNAMES" />
|
||||||
|
<Add directory="." />
|
||||||
|
<Add directory="../../ports/win32" />
|
||||||
|
<Add directory="../../src" />
|
||||||
|
</Compiler>
|
||||||
|
<Linker>
|
||||||
|
<Add option="-static" />
|
||||||
|
<Add option="-m32" />
|
||||||
|
<Add option="-Wl,--gc-sections" />
|
||||||
|
<Add library="ws2_32" />
|
||||||
|
<Add library="iphlpapi" />
|
||||||
|
<Add library="gcc" />
|
||||||
|
<Add library="m" />
|
||||||
|
<Add library="winmm" />
|
||||||
|
</Linker>
|
||||||
|
<Unit filename="../../ports/win32/bip-init.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../ports/win32/datetime-init.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../ports/win32/mstimer-init.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/abort.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/access_rule.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/alarm_ack.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/arf.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/assigned_access_rights.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/authentication_factor.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/authentication_factor_format.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/awf.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/bacaddr.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/bacapp.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/bacdcode.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/bacdevobjpropref.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/bacerror.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/bacint.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/bacprop.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/bacpropstates.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/bacreal.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/bacstr.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/bactext.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/bactimevalue.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/binding/address.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/npdu/h_npdu.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/object/client/device-client.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/object/netport.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/h_apdu.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/h_iam.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/h_noserv.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/h_rp.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/h_rp_a.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/h_rpm_a.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/h_whois.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/s_iam.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/s_rp.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/s_rpm.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/s_whois.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/sys/bigend.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/sys/debug.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/sys/fifo.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/sys/filename.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/sys/key.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/sys/keylist.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/sys/mstimer.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/sys/ringbuf.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/sys/sbuf.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/tsm/tsm.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/cov.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/credential_authentication_factor.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/datalink/bip.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/datalink/bvlc.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/datalink/dlenv.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/datetime.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/dcc.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/event.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/get_alarm_sum.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/getevent.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/iam.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/ihave.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/indtext.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/lighting.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/lso.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/memcopy.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/npdu.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/property.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/proplist.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/ptransfer.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/rd.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/readrange.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/reject.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/rp.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/rpm.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/timestamp.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/timesync.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/whohas.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/whois.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/wp.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/wpm.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="main.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Extensions>
|
||||||
|
<code_completion />
|
||||||
|
<envvars />
|
||||||
|
<debugger />
|
||||||
|
</Extensions>
|
||||||
|
</Project>
|
||||||
|
</CodeBlocks_project_file>
|
||||||
Executable → Regular
@@ -33,29 +33,30 @@
|
|||||||
#include <time.h> /* for time */
|
#include <time.h> /* for time */
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include "config.h"
|
#include "bacnet/config.h"
|
||||||
#include "bactext.h"
|
#include "bacnet/bactext.h"
|
||||||
#include "iam.h"
|
#include "bacnet/iam.h"
|
||||||
#include "arf.h"
|
#include "bacnet/arf.h"
|
||||||
#include "tsm.h"
|
#include "bacnet/basic/tsm/tsm.h"
|
||||||
#include "address.h"
|
#include "bacnet/bacdef.h"
|
||||||
#include "bacdef.h"
|
#include "bacnet/npdu.h"
|
||||||
#include "npdu.h"
|
#include "bacnet/apdu.h"
|
||||||
#include "apdu.h"
|
#include "bacport.h"
|
||||||
#include "device.h"
|
#include "bacnet/whois.h"
|
||||||
#include "net.h"
|
#include "bacnet/rp.h"
|
||||||
#include "datalink.h"
|
#include "bacnet/proplist.h"
|
||||||
#include "whois.h"
|
#include "bacnet/property.h"
|
||||||
#include "rp.h"
|
#include "bacnet/version.h"
|
||||||
#include "proplist.h"
|
|
||||||
#include "version.h"
|
|
||||||
/* some demo stuff needed */
|
/* some demo stuff needed */
|
||||||
#include "filename.h"
|
#include "bacnet/basic/binding/address.h"
|
||||||
#include "handlers.h"
|
#include "bacnet/basic/object/device.h"
|
||||||
#include "client.h"
|
#include "bacnet/basic/services.h"
|
||||||
#include "txbuf.h"
|
#include "bacnet/basic/services.h"
|
||||||
#include "dlenv.h"
|
#include "bacnet/basic/sys/filename.h"
|
||||||
#include "keylist.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"
|
#include "bacepics.h"
|
||||||
|
|
||||||
/* (Doxygen note: The next two lines pull all the following Javadoc
|
/* (Doxygen note: The next two lines pull all the following Javadoc
|
||||||
@@ -71,7 +72,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* buffer used for receive */
|
/* 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 */
|
/* target information converted from command line */
|
||||||
static uint32_t Target_Device_Object_Instance = BACNET_MAX_INSTANCE;
|
static uint32_t Target_Device_Object_Instance = BACNET_MAX_INSTANCE;
|
||||||
@@ -132,13 +133,12 @@ struct property_value_list_t {
|
|||||||
BACNET_APPLICATION_DATA_VALUE *value;
|
BACNET_APPLICATION_DATA_VALUE *value;
|
||||||
};
|
};
|
||||||
static struct property_value_list_t Property_Value_List[] = {
|
static struct property_value_list_t Property_Value_List[] = {
|
||||||
{PROP_VENDOR_NAME, NULL},
|
{ PROP_VENDOR_NAME, NULL }, { PROP_MODEL_NAME, NULL },
|
||||||
{PROP_MODEL_NAME, NULL},
|
{ PROP_MAX_APDU_LENGTH_ACCEPTED, NULL },
|
||||||
{PROP_MAX_APDU_LENGTH_ACCEPTED, NULL},
|
{ PROP_PROTOCOL_SERVICES_SUPPORTED, NULL },
|
||||||
{PROP_PROTOCOL_SERVICES_SUPPORTED, NULL},
|
{ PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED, NULL }, { PROP_DESCRIPTION, NULL },
|
||||||
{PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED, NULL},
|
{ -1, NULL }
|
||||||
{PROP_DESCRIPTION, NULL},
|
};
|
||||||
{-1, NULL}};
|
|
||||||
|
|
||||||
static BACNET_APPLICATION_DATA_VALUE *object_property_value(int32_t property_id)
|
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
|
#define PRINT_ERRORS 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void MyErrorHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
|
static void MyErrorHandler(BACNET_ADDRESS *src,
|
||||||
BACNET_ERROR_CLASS error_class,
|
uint8_t invoke_id,
|
||||||
BACNET_ERROR_CODE error_code)
|
BACNET_ERROR_CLASS error_class,
|
||||||
|
BACNET_ERROR_CODE error_code)
|
||||||
{
|
{
|
||||||
if (address_match(&Target_Address, src) &&
|
if (address_match(&Target_Address, src) &&
|
||||||
(invoke_id == Request_Invoke_ID)) {
|
(invoke_id == Request_Invoke_ID)) {
|
||||||
#if PRINT_ERRORS
|
#if PRINT_ERRORS
|
||||||
if (ShowValues) {
|
if (ShowValues) {
|
||||||
fprintf(stderr, "-- BACnet Error: %s: %s\n",
|
fprintf(stderr, "-- BACnet Error: %s: %s\n",
|
||||||
bactext_error_class_name(error_class),
|
bactext_error_class_name(error_class),
|
||||||
bactext_error_code_name(error_code));
|
bactext_error_code_name(error_code));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
Error_Detected = true;
|
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,
|
static void MyAbortHandler(
|
||||||
uint8_t abort_reason, bool server)
|
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t abort_reason, bool server)
|
||||||
{
|
{
|
||||||
(void)server;
|
(void)server;
|
||||||
if (address_match(&Target_Address, src) &&
|
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. */
|
/* It is normal for this to fail, so don't print. */
|
||||||
if ((myState != GET_ALL_RESPONSE) && !IsLongArray && ShowValues) {
|
if ((myState != GET_ALL_RESPONSE) && !IsLongArray && ShowValues) {
|
||||||
fprintf(stderr, "-- BACnet Abort: %s \n",
|
fprintf(stderr, "-- BACnet Abort: %s \n",
|
||||||
bactext_abort_reason_name(abort_reason));
|
bactext_abort_reason_name(abort_reason));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
Error_Detected = true;
|
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,
|
static void MyRejectHandler(
|
||||||
uint8_t reject_reason)
|
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||||
{
|
{
|
||||||
if (address_match(&Target_Address, src) &&
|
if (address_match(&Target_Address, src) &&
|
||||||
(invoke_id == Request_Invoke_ID)) {
|
(invoke_id == Request_Invoke_ID)) {
|
||||||
#if PRINT_ERRORS
|
#if PRINT_ERRORS
|
||||||
if (ShowValues) {
|
if (ShowValues) {
|
||||||
fprintf(stderr, "BACnet Reject: %s\n",
|
fprintf(stderr, "BACnet Reject: %s\n",
|
||||||
bactext_reject_reason_name(reject_reason));
|
bactext_reject_reason_name(reject_reason));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
Error_Detected = true;
|
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,
|
static void MyReadPropertyAckHandler(uint8_t *service_request,
|
||||||
BACNET_ADDRESS *src,
|
uint16_t service_len,
|
||||||
BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data)
|
BACNET_ADDRESS *src,
|
||||||
|
BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data)
|
||||||
{
|
{
|
||||||
int len = 0;
|
int len = 0;
|
||||||
BACNET_READ_ACCESS_DATA *rp_data;
|
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)) {
|
(service_data->invoke_id == Request_Invoke_ID)) {
|
||||||
rp_data = calloc(1, sizeof(BACNET_READ_ACCESS_DATA));
|
rp_data = calloc(1, sizeof(BACNET_READ_ACCESS_DATA));
|
||||||
if (rp_data) {
|
if (rp_data) {
|
||||||
len = rp_ack_fully_decode_service_request(service_request,
|
len = rp_ack_fully_decode_service_request(
|
||||||
service_len, rp_data);
|
service_request, service_len, rp_data);
|
||||||
}
|
}
|
||||||
if (len > 0) {
|
if (len > 0) {
|
||||||
memmove(&Read_Property_Multiple_Data.service_data, service_data,
|
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.rpm_data = rp_data;
|
||||||
Read_Property_Multiple_Data.new_data = true;
|
Read_Property_Multiple_Data.new_data = true;
|
||||||
} else {
|
} else {
|
||||||
@@ -267,8 +269,9 @@ void MyReadPropertyAckHandler(uint8_t *service_request, uint16_t service_len,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MyReadPropertyMultipleAckHandler(
|
static void MyReadPropertyMultipleAckHandler(uint8_t *service_request,
|
||||||
uint8_t *service_request, uint16_t service_len, BACNET_ADDRESS *src,
|
uint16_t service_len,
|
||||||
|
BACNET_ADDRESS *src,
|
||||||
BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data)
|
BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data)
|
||||||
{
|
{
|
||||||
int len = 0;
|
int len = 0;
|
||||||
@@ -278,12 +281,12 @@ void MyReadPropertyMultipleAckHandler(
|
|||||||
(service_data->invoke_id == Request_Invoke_ID)) {
|
(service_data->invoke_id == Request_Invoke_ID)) {
|
||||||
rpm_data = calloc(1, sizeof(BACNET_READ_ACCESS_DATA));
|
rpm_data = calloc(1, sizeof(BACNET_READ_ACCESS_DATA));
|
||||||
if (rpm_data) {
|
if (rpm_data) {
|
||||||
len = rpm_ack_decode_service_request(service_request, service_len,
|
len = rpm_ack_decode_service_request(
|
||||||
rpm_data);
|
service_request, service_len, rpm_data);
|
||||||
}
|
}
|
||||||
if (len > 0) {
|
if (len > 0) {
|
||||||
memmove(&Read_Property_Multiple_Data.service_data, service_data,
|
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.rpm_data = rpm_data;
|
||||||
Read_Property_Multiple_Data.new_data = true;
|
Read_Property_Multiple_Data.new_data = true;
|
||||||
/* Will process and free the RPM data later */
|
/* 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... */
|
It is required to send the proper reject message... */
|
||||||
apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service);
|
apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service);
|
||||||
/* we must implement read property - it's required! */
|
/* we must implement read property - it's required! */
|
||||||
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY,
|
apdu_set_confirmed_handler(
|
||||||
handler_read_property);
|
SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property);
|
||||||
/* handle the data coming back from confirmed requests */
|
/* handle the data coming back from confirmed requests */
|
||||||
apdu_set_confirmed_ack_handler(SERVICE_CONFIRMED_READ_PROPERTY,
|
apdu_set_confirmed_ack_handler(
|
||||||
MyReadPropertyAckHandler);
|
SERVICE_CONFIRMED_READ_PROPERTY, MyReadPropertyAckHandler);
|
||||||
apdu_set_confirmed_ack_handler(SERVICE_CONFIRMED_READ_PROP_MULTIPLE,
|
apdu_set_confirmed_ack_handler(
|
||||||
MyReadPropertyMultipleAckHandler);
|
SERVICE_CONFIRMED_READ_PROP_MULTIPLE, MyReadPropertyMultipleAckHandler);
|
||||||
/* handle any errors coming back */
|
/* handle any errors coming back */
|
||||||
apdu_set_error_handler(SERVICE_CONFIRMED_READ_PROPERTY, MyErrorHandler);
|
apdu_set_error_handler(SERVICE_CONFIRMED_READ_PROPERTY, MyErrorHandler);
|
||||||
apdu_set_abort_handler(MyAbortHandler);
|
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,
|
* @param rpm_property [in] Points to structure holding the Property,
|
||||||
* Value, and Error information.
|
* Value, and Error information.
|
||||||
*/
|
*/
|
||||||
void CheckIsWritableProperty(BACNET_OBJECT_TYPE object_type,
|
static void CheckIsWritableProperty(BACNET_OBJECT_TYPE object_type,
|
||||||
/* uint32_t object_instance, */
|
/* uint32_t object_instance, */
|
||||||
BACNET_PROPERTY_REFERENCE *rpm_property)
|
BACNET_PROPERTY_REFERENCE *rpm_property)
|
||||||
{
|
{
|
||||||
bool bIsWritable = false;
|
bool bIsWritable = false;
|
||||||
if ((object_type == OBJECT_ANALOG_OUTPUT) ||
|
if ((object_type == OBJECT_ANALOG_OUTPUT) ||
|
||||||
@@ -363,7 +366,7 @@ void CheckIsWritableProperty(BACNET_OBJECT_TYPE object_type,
|
|||||||
bIsWritable = true;
|
bIsWritable = true;
|
||||||
}
|
}
|
||||||
} else if ((object_type == OBJECT_LIFE_SAFETY_POINT) ||
|
} 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) {
|
if (rpm_property->propertyIdentifier == PROP_MODE) {
|
||||||
bIsWritable = true;
|
bIsWritable = true;
|
||||||
}
|
}
|
||||||
@@ -376,8 +379,8 @@ void CheckIsWritableProperty(BACNET_OBJECT_TYPE object_type,
|
|||||||
bIsWritable = true;
|
bIsWritable = true;
|
||||||
}
|
}
|
||||||
} else if ((object_type == OBJECT_TRENDLOG) ||
|
} else if ((object_type == OBJECT_TRENDLOG) ||
|
||||||
(object_type == OBJECT_EVENT_LOG) ||
|
(object_type == OBJECT_EVENT_LOG) ||
|
||||||
(object_type == OBJECT_TREND_LOG_MULTIPLE)) {
|
(object_type == OBJECT_TREND_LOG_MULTIPLE)) {
|
||||||
if ((rpm_property->propertyIdentifier == PROP_ENABLE) ||
|
if ((rpm_property->propertyIdentifier == PROP_ENABLE) ||
|
||||||
(rpm_property->propertyIdentifier == PROP_RECORD_COUNT)) {
|
(rpm_property->propertyIdentifier == PROP_RECORD_COUNT)) {
|
||||||
bIsWritable = true;
|
bIsWritable = true;
|
||||||
@@ -391,17 +394,17 @@ void CheckIsWritableProperty(BACNET_OBJECT_TYPE object_type,
|
|||||||
bIsWritable = true;
|
bIsWritable = true;
|
||||||
}
|
}
|
||||||
} else if ((object_type == OBJECT_ACCESS_ZONE) ||
|
} else if ((object_type == OBJECT_ACCESS_ZONE) ||
|
||||||
(object_type == OBJECT_ACCESS_USER) ||
|
(object_type == OBJECT_ACCESS_USER) ||
|
||||||
(object_type == OBJECT_ACCESS_RIGHTS) ||
|
(object_type == OBJECT_ACCESS_RIGHTS) ||
|
||||||
(object_type == OBJECT_ACCESS_CREDENTIAL)) {
|
(object_type == OBJECT_ACCESS_CREDENTIAL)) {
|
||||||
if (rpm_property->propertyIdentifier == PROP_GLOBAL_IDENTIFIER) {
|
if (rpm_property->propertyIdentifier == PROP_GLOBAL_IDENTIFIER) {
|
||||||
bIsWritable = true;
|
bIsWritable = true;
|
||||||
}
|
}
|
||||||
} else if (object_type == OBJECT_NETWORK_SECURITY) {
|
} else if (object_type == OBJECT_NETWORK_SECURITY) {
|
||||||
if ((rpm_property->propertyIdentifier ==
|
if ((rpm_property->propertyIdentifier ==
|
||||||
PROP_BASE_DEVICE_SECURITY_POLICY) ||
|
PROP_BASE_DEVICE_SECURITY_POLICY) ||
|
||||||
(rpm_property->propertyIdentifier ==
|
(rpm_property->propertyIdentifier ==
|
||||||
PROP_NETWORK_ACCESS_SECURITY_POLICIES) ||
|
PROP_NETWORK_ACCESS_SECURITY_POLICIES) ||
|
||||||
(rpm_property->propertyIdentifier == PROP_SECURITY_TIME_WINDOW) ||
|
(rpm_property->propertyIdentifier == PROP_SECURITY_TIME_WINDOW) ||
|
||||||
(rpm_property->propertyIdentifier == PROP_PACKET_REORDER_TIME) ||
|
(rpm_property->propertyIdentifier == PROP_PACKET_REORDER_TIME) ||
|
||||||
(rpm_property->propertyIdentifier == PROP_LAST_KEY_SERVER) ||
|
(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.
|
* @return True if success. Or otherwise.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool PrettyPrintPropertyValue(FILE *stream,
|
static bool PrettyPrintPropertyValue(
|
||||||
BACNET_OBJECT_PROPERTY_VALUE *object_value)
|
FILE *stream, BACNET_OBJECT_PROPERTY_VALUE *object_value)
|
||||||
{
|
{
|
||||||
BACNET_APPLICATION_DATA_VALUE *value = NULL;
|
BACNET_APPLICATION_DATA_VALUE *value = NULL;
|
||||||
bool status = true; /*return value */
|
bool status = true; /*return value */
|
||||||
@@ -466,17 +469,17 @@ bool PrettyPrintPropertyValue(FILE *stream,
|
|||||||
property = object_value->object_property;
|
property = object_value->object_property;
|
||||||
if ((value != NULL) && (value->tag == BACNET_APPLICATION_TAG_BIT_STRING) &&
|
if ((value != NULL) && (value->tag == BACNET_APPLICATION_TAG_BIT_STRING) &&
|
||||||
((property == PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED) ||
|
((property == PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED) ||
|
||||||
(property == PROP_PROTOCOL_SERVICES_SUPPORTED))) {
|
(property == PROP_PROTOCOL_SERVICES_SUPPORTED))) {
|
||||||
len = bitstring_bits_used(&value->type.Bit_String);
|
len = bitstring_bits_used(&value->type.Bit_String);
|
||||||
fprintf(stream, "( \n ");
|
fprintf(stream, "( \n ");
|
||||||
for (i = 0; i < len; i++) {
|
for (i = 0; i < len; i++) {
|
||||||
fprintf(
|
fprintf(stream, "%s",
|
||||||
stream, "%s",
|
|
||||||
bitstring_bit(&value->type.Bit_String, (uint8_t)i) ? "T" : "F");
|
bitstring_bit(&value->type.Bit_String, (uint8_t)i) ? "T" : "F");
|
||||||
if (i < len - 1)
|
if (i < len - 1) {
|
||||||
fprintf(stream, ",");
|
fprintf(stream, ",");
|
||||||
else
|
} else {
|
||||||
fprintf(stream, " ");
|
fprintf(stream, " ");
|
||||||
|
}
|
||||||
/* Tried with 8 per line, but with the comments, got way too long.
|
/* Tried with 8 per line, but with the comments, got way too long.
|
||||||
*/
|
*/
|
||||||
if ((i == (len - 1)) || ((i % 4) == 3)) { /* line break every 4 */
|
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++) {
|
for (j = i - (i % 4); j <= i; j++) {
|
||||||
if (bitstring_bit(&value->type.Bit_String, (uint8_t)j)) {
|
if (bitstring_bit(&value->type.Bit_String, (uint8_t)j)) {
|
||||||
if (property == PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED) {
|
if (property == PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED) {
|
||||||
fprintf(stream, " %s,",
|
fprintf(
|
||||||
bactext_object_type_name(j));
|
stream, " %s,", bactext_object_type_name(j));
|
||||||
} else {
|
} else {
|
||||||
/* PROP_PROTOCOL_SERVICES_SUPPORTED */
|
/* PROP_PROTOCOL_SERVICES_SUPPORTED */
|
||||||
fprintf(stream, " %s,",
|
fprintf(stream, " %s,",
|
||||||
protocol_services_supported_text(j));
|
protocol_services_supported_text(j));
|
||||||
}
|
}
|
||||||
} else /* not supported */
|
} else /* not supported */
|
||||||
fprintf(stream, ",");
|
fprintf(stream, ",");
|
||||||
@@ -506,8 +509,8 @@ bool PrettyPrintPropertyValue(FILE *stream,
|
|||||||
strncpy(short_month, bactext_month_name(value->type.Date.month), 3);
|
strncpy(short_month, bactext_month_name(value->type.Date.month), 3);
|
||||||
short_month[3] = 0;
|
short_month[3] = 0;
|
||||||
fprintf(stream, "(%u-%3s-%u, %u)", (unsigned)value->type.Date.day,
|
fprintf(stream, "(%u-%3s-%u, %u)", (unsigned)value->type.Date.day,
|
||||||
short_month, (unsigned)value->type.Date.year,
|
short_month, (unsigned)value->type.Date.year,
|
||||||
(unsigned)value->type.Date.wday);
|
(unsigned)value->type.Date.wday);
|
||||||
} else if (value != NULL) {
|
} else if (value != NULL) {
|
||||||
assert(false); /* How did I get here? Fix your code. */
|
assert(false); /* How did I get here? Fix your code. */
|
||||||
/* Meanwhile, a fallback plan */
|
/* Meanwhile, a fallback plan */
|
||||||
@@ -528,9 +531,9 @@ bool PrettyPrintPropertyValue(FILE *stream,
|
|||||||
* @param rpm_property [in] Points to structure holding the Property,
|
* @param rpm_property [in] Points to structure holding the Property,
|
||||||
* Value, and Error information.
|
* Value, and Error information.
|
||||||
*/
|
*/
|
||||||
void PrintReadPropertyData(BACNET_OBJECT_TYPE object_type,
|
static void PrintReadPropertyData(BACNET_OBJECT_TYPE object_type,
|
||||||
uint32_t object_instance,
|
uint32_t object_instance,
|
||||||
BACNET_PROPERTY_REFERENCE *rpm_property)
|
BACNET_PROPERTY_REFERENCE *rpm_property)
|
||||||
{
|
{
|
||||||
BACNET_OBJECT_PROPERTY_VALUE object_value; /* for bacapp printing */
|
BACNET_OBJECT_PROPERTY_VALUE object_value; /* for bacapp printing */
|
||||||
BACNET_APPLICATION_DATA_VALUE *value, *old_value;
|
BACNET_APPLICATION_DATA_VALUE *value, *old_value;
|
||||||
@@ -546,8 +549,8 @@ void PrintReadPropertyData(BACNET_OBJECT_TYPE object_type,
|
|||||||
if (value == NULL) {
|
if (value == NULL) {
|
||||||
/* Then we print the error information */
|
/* Then we print the error information */
|
||||||
fprintf(stdout, "? -- BACnet Error: %s: %s\n",
|
fprintf(stdout, "? -- BACnet Error: %s: %s\n",
|
||||||
bactext_error_class_name((int)rpm_property->error.error_class),
|
bactext_error_class_name((int)rpm_property->error.error_class),
|
||||||
bactext_error_code_name((int)rpm_property->error.error_code));
|
bactext_error_code_name((int)rpm_property->error.error_code));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
object_value.object_type = object_type;
|
object_value.object_type = object_type;
|
||||||
@@ -607,7 +610,7 @@ void PrintReadPropertyData(BACNET_OBJECT_TYPE object_type,
|
|||||||
break;
|
break;
|
||||||
} else
|
} else
|
||||||
assert(Walked_List_Index ==
|
assert(Walked_List_Index ==
|
||||||
(uint32_t)rpm_property->propertyArrayIndex);
|
(uint32_t)rpm_property->propertyArrayIndex);
|
||||||
} else {
|
} else {
|
||||||
Walked_List_Index++;
|
Walked_List_Index++;
|
||||||
/* If we got the whole Object List array in one RP call,
|
/* 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 (rpm_property->propertyIdentifier == PROP_OBJECT_LIST) {
|
||||||
if (value->tag != BACNET_APPLICATION_TAG_OBJECT_ID) {
|
if (value->tag != BACNET_APPLICATION_TAG_OBJECT_ID) {
|
||||||
assert(
|
assert(value->tag ==
|
||||||
value->tag ==
|
BACNET_APPLICATION_TAG_OBJECT_ID); /* Something
|
||||||
BACNET_APPLICATION_TAG_OBJECT_ID); /* Something not
|
not right
|
||||||
right here */
|
here */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* Store the object list so we can interrogate
|
/* Store the object list so we can interrogate
|
||||||
each object. */
|
each object. */
|
||||||
object_list_element =
|
object_list_element = KEY_ENCODE(value->type.Object_Id.type,
|
||||||
KEY_ENCODE(value->type.Object_Id.type,
|
value->type.Object_Id.instance);
|
||||||
value->type.Object_Id.instance);
|
|
||||||
/* We don't have anything to put in the data pointer
|
/* We don't have anything to put in the data pointer
|
||||||
* yet, so just leave it null. The key is Key here. */
|
* yet, so just leave it null. The key is Key here. */
|
||||||
Keylist_Data_Add(Object_List, object_list_element, NULL);
|
Keylist_Data_Add(Object_List, object_list_element, NULL);
|
||||||
} else if (rpm_property->propertyIdentifier ==
|
} else if (rpm_property->propertyIdentifier ==
|
||||||
PROP_STATE_TEXT) {
|
PROP_STATE_TEXT) {
|
||||||
/* Make sure it fits within 31 chars for original VTS3
|
/* Make sure it fits within 31 chars for original VTS3
|
||||||
* limitation. If longer, take first 15 dash, and last 15
|
* limitation. If longer, take first 15 dash, and last 15
|
||||||
* chars. */
|
* chars. */
|
||||||
@@ -660,18 +662,18 @@ void PrintReadPropertyData(BACNET_OBJECT_TYPE object_type,
|
|||||||
value->type.Character_String.length - 15;
|
value->type.Character_String.length - 15;
|
||||||
value->type.Character_String.value[15] = '-';
|
value->type.Character_String.value[15] = '-';
|
||||||
memcpy(&value->type.Character_String.value[16],
|
memcpy(&value->type.Character_String.value[16],
|
||||||
&value->type.Character_String.value[iLast15idx],
|
&value->type.Character_String.value[iLast15idx],
|
||||||
15);
|
15);
|
||||||
value->type.Character_String.value[31] = 0;
|
value->type.Character_String.value[31] = 0;
|
||||||
value->type.Character_String.length = 31;
|
value->type.Character_String.length = 31;
|
||||||
}
|
}
|
||||||
} else if (rpm_property->propertyIdentifier ==
|
} else if (rpm_property->propertyIdentifier ==
|
||||||
PROP_SUBORDINATE_LIST) {
|
PROP_SUBORDINATE_LIST) {
|
||||||
if (value->tag != BACNET_APPLICATION_TAG_OBJECT_ID) {
|
if (value->tag != BACNET_APPLICATION_TAG_OBJECT_ID) {
|
||||||
assert(
|
assert(value->tag ==
|
||||||
value->tag ==
|
BACNET_APPLICATION_TAG_OBJECT_ID); /* Something
|
||||||
BACNET_APPLICATION_TAG_OBJECT_ID); /* Something not
|
not right
|
||||||
right here */
|
here */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* TODO: handle Sequence of { Device ObjID, Object ID }, */
|
/* TODO: handle Sequence of { Device ObjID, Object ID }, */
|
||||||
@@ -753,7 +755,7 @@ void PrintReadPropertyData(BACNET_OBJECT_TYPE object_type,
|
|||||||
fprintf(stdout, " }");
|
fprintf(stdout, " }");
|
||||||
}
|
}
|
||||||
CheckIsWritableProperty(object_type, /* object_instance, */
|
CheckIsWritableProperty(object_type, /* object_instance, */
|
||||||
rpm_property);
|
rpm_property);
|
||||||
fprintf(stdout, "\n");
|
fprintf(stdout, "\n");
|
||||||
}
|
}
|
||||||
break;
|
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
|
* @return The invokeID of the message sent, or 0 if reached the end
|
||||||
* of the property list.
|
* of the property list.
|
||||||
*/
|
*/
|
||||||
static uint8_t Read_Properties(uint32_t device_instance,
|
static uint8_t Read_Properties(
|
||||||
BACNET_OBJECT_ID *pMyObject)
|
uint32_t device_instance, BACNET_OBJECT_ID *pMyObject)
|
||||||
{
|
{
|
||||||
uint8_t invoke_id = 0;
|
uint8_t invoke_id = 0;
|
||||||
struct special_property_list_t PropertyListStruct;
|
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);
|
property_list_special(pMyObject->type, &PropertyListStruct);
|
||||||
if (Optional_Properties) {
|
if (Optional_Properties) {
|
||||||
Property_List_Length = PropertyListStruct.Required.count +
|
Property_List_Length = PropertyListStruct.Required.count +
|
||||||
PropertyListStruct.Optional.count;
|
PropertyListStruct.Optional.count;
|
||||||
} else {
|
} else {
|
||||||
Property_List_Length = PropertyListStruct.Required.count;
|
Property_List_Length = PropertyListStruct.Required.count;
|
||||||
}
|
}
|
||||||
@@ -875,9 +877,8 @@ static uint8_t Read_Properties(uint32_t device_instance,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
invoke_id =
|
invoke_id = Send_Read_Property_Request(device_instance, pMyObject->type,
|
||||||
Send_Read_Property_Request(device_instance, pMyObject->type,
|
pMyObject->instance, prop, array_index);
|
||||||
pMyObject->instance, prop, array_index);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return invoke_id;
|
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
|
* if the RPM got good data, or GET_PROPERTY_REQUEST if we have to
|
||||||
* singly process the list of Properties.
|
* singly process the list of Properties.
|
||||||
*/
|
*/
|
||||||
EPICS_STATES ProcessRPMData(BACNET_READ_ACCESS_DATA *rpm_data,
|
static EPICS_STATES ProcessRPMData(
|
||||||
EPICS_STATES myState)
|
BACNET_READ_ACCESS_DATA *rpm_data, EPICS_STATES myState)
|
||||||
{
|
{
|
||||||
BACNET_READ_ACCESS_DATA *old_rpm_data;
|
BACNET_READ_ACCESS_DATA *old_rpm_data;
|
||||||
BACNET_PROPERTY_REFERENCE *rpm_property;
|
BACNET_PROPERTY_REFERENCE *rpm_property;
|
||||||
@@ -947,7 +948,7 @@ EPICS_STATES ProcessRPMData(BACNET_READ_ACCESS_DATA *rpm_data,
|
|||||||
Print_Property_Identifier(rpm_property->propertyIdentifier);
|
Print_Property_Identifier(rpm_property->propertyIdentifier);
|
||||||
fprintf(stdout, ": ");
|
fprintf(stdout, ": ");
|
||||||
PrintReadPropertyData(rpm_data->object_type,
|
PrintReadPropertyData(rpm_data->object_type,
|
||||||
rpm_data->object_instance, rpm_property);
|
rpm_data->object_instance, rpm_property);
|
||||||
}
|
}
|
||||||
old_rpm_property = rpm_property;
|
old_rpm_property = rpm_property;
|
||||||
rpm_property = rpm_property->next;
|
rpm_property = rpm_property->next;
|
||||||
@@ -959,10 +960,10 @@ EPICS_STATES ProcessRPMData(BACNET_READ_ACCESS_DATA *rpm_data,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Now determine the next state */
|
/* Now determine the next state */
|
||||||
if (myState == GET_HEADING_RESPONSE)
|
if (myState == GET_HEADING_RESPONSE) {
|
||||||
nextState = PRINT_HEADING;
|
nextState = PRINT_HEADING;
|
||||||
/* press ahead with or without the data */
|
/* press ahead with or without the data */
|
||||||
else if (bSuccess && (myState == GET_ALL_RESPONSE))
|
} else if (bSuccess && (myState == GET_ALL_RESPONSE))
|
||||||
nextState = NEXT_OBJECT;
|
nextState = NEXT_OBJECT;
|
||||||
else if (bSuccess) { /* and GET_LIST_OF_ALL_RESPONSE */
|
else if (bSuccess) { /* and GET_LIST_OF_ALL_RESPONSE */
|
||||||
/* Now append the properties we waited on. */
|
/* 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)
|
static void print_usage(char *filename)
|
||||||
{
|
{
|
||||||
printf(
|
printf("Usage: %s [-v] [-d] [-p sport] [-t target_mac [-n dnet]]"
|
||||||
"Usage: %s [-v] [-d] [-p sport] [-t target_mac [-n dnet]]"
|
" device-instance\n",
|
||||||
" device-instance\n",
|
|
||||||
filename);
|
filename);
|
||||||
printf(" [--version][--help]\n");
|
printf(" [--version][--help]\n");
|
||||||
}
|
}
|
||||||
@@ -997,12 +997,11 @@ static void print_usage(char *filename)
|
|||||||
static void print_help(char *filename)
|
static void print_help(char *filename)
|
||||||
{
|
{
|
||||||
printf("Generates Full EPICS file, including Object and Property List\n");
|
printf("Generates Full EPICS file, including Object and Property List\n");
|
||||||
printf(
|
printf("device-instance:\n"
|
||||||
"device-instance:\n"
|
"BACnet Device Object Instance number that you are\n"
|
||||||
"BACnet Device Object Instance number that you are\n"
|
"trying to communicate to. This number will be used\n"
|
||||||
"trying to communicate to. This number will be used\n"
|
"to try and bind with the device using Who-Is and\n"
|
||||||
"to try and bind with the device using Who-Is and\n"
|
"I-Am services.\n");
|
||||||
"I-Am services.\n");
|
|
||||||
printf("\n");
|
printf("\n");
|
||||||
printf("-v: show values instead of '?' \n");
|
printf("-v: show values instead of '?' \n");
|
||||||
printf("-d: show only device object properties\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");
|
printf("e.g., bacepics 2701876 > epics-2701876.tpi \n");
|
||||||
}
|
}
|
||||||
|
|
||||||
int CheckCommandLineArgs(int argc, char *argv[])
|
static int CheckCommandLineArgs(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
bool bFoundTarget = false;
|
bool bFoundTarget = false;
|
||||||
@@ -1034,12 +1033,11 @@ int CheckCommandLineArgs(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
if (strcmp(argv[argi], "--version") == 0) {
|
if (strcmp(argv[argi], "--version") == 0) {
|
||||||
printf("%s %s\n", filename, BACNET_VERSION_TEXT);
|
printf("%s %s\n", filename, BACNET_VERSION_TEXT);
|
||||||
printf(
|
printf("Copyright (C) 2014 by Steve Karg and others.\n"
|
||||||
"Copyright (C) 2014 by Steve Karg and others.\n"
|
"This is free software; see the source for copying "
|
||||||
"This is free software; see the source for copying "
|
"conditions.\n"
|
||||||
"conditions.\n"
|
"There is NO warranty; not even for MERCHANTABILITY or\n"
|
||||||
"There is NO warranty; not even for MERCHANTABILITY or\n"
|
"FITNESS FOR A PARTICULAR PURPOSE.\n");
|
||||||
"FITNESS FOR A PARTICULAR PURPOSE.\n");
|
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1071,8 +1069,8 @@ int CheckCommandLineArgs(int argc, char *argv[])
|
|||||||
case 'n':
|
case 'n':
|
||||||
/* Destination Network Number */
|
/* Destination Network Number */
|
||||||
if (Target_Address.mac_len == 0)
|
if (Target_Address.mac_len == 0)
|
||||||
fprintf(stderr,
|
fprintf(
|
||||||
"Must provide a Target MAC before DNET \n");
|
stderr, "Must provide a Target MAC before DNET \n");
|
||||||
if (++i < argc)
|
if (++i < argc)
|
||||||
Target_Address.net = (uint16_t)strtol(argv[i], NULL, 0);
|
Target_Address.net = (uint16_t)strtol(argv[i], NULL, 0);
|
||||||
/* Used strtol so dest.net can be either 0x1234 or 4660 */
|
/* Used strtol so dest.net can be either 0x1234 or 4660 */
|
||||||
@@ -1087,7 +1085,7 @@ int CheckCommandLineArgs(int argc, char *argv[])
|
|||||||
unsigned j;
|
unsigned j;
|
||||||
count =
|
count =
|
||||||
sscanf(argv[i], "%2x:%2x:%2x:%2x:%2x:%2x", &mac[0],
|
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 */
|
if (count == 6) { /* success */
|
||||||
Target_Address.mac_len = count;
|
Target_Address.mac_len = count;
|
||||||
for (j = 0; j < 6; j++) {
|
for (j = 0; j < 6; j++) {
|
||||||
@@ -1097,8 +1095,9 @@ int CheckCommandLineArgs(int argc, char *argv[])
|
|||||||
Target_Address.len = 0; /* No src address */
|
Target_Address.len = 0; /* No src address */
|
||||||
Provided_Targ_MAC = true;
|
Provided_Targ_MAC = true;
|
||||||
break;
|
break;
|
||||||
} else
|
} else {
|
||||||
printf("ERROR: invalid Target MAC %s \n", argv[i]);
|
printf("ERROR: invalid Target MAC %s \n", argv[i]);
|
||||||
|
}
|
||||||
/* And fall through to print_usage */
|
/* And fall through to print_usage */
|
||||||
}
|
}
|
||||||
/* Either break or fall through, as above */
|
/* 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);
|
Target_Device_Object_Instance = strtol(anArg, NULL, 0);
|
||||||
if (Target_Device_Object_Instance > BACNET_MAX_INSTANCE) {
|
if (Target_Device_Object_Instance > BACNET_MAX_INSTANCE) {
|
||||||
fprintf(stdout,
|
fprintf(stdout,
|
||||||
"Error: device-instance=%u - it must be less than %u\n",
|
"Error: 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);
|
||||||
print_usage(filename);
|
print_usage(filename);
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
@@ -1130,7 +1129,7 @@ int CheckCommandLineArgs(int argc, char *argv[])
|
|||||||
return 0; /* All OK if we reach here */
|
return 0; /* All OK if we reach here */
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrintHeading()
|
static void PrintHeading(void)
|
||||||
{
|
{
|
||||||
BACNET_APPLICATION_DATA_VALUE *value = NULL;
|
BACNET_APPLICATION_DATA_VALUE *value = NULL;
|
||||||
BACNET_OBJECT_PROPERTY_VALUE property_value;
|
BACNET_OBJECT_PROPERTY_VALUE property_value;
|
||||||
@@ -1147,7 +1146,7 @@ void PrintHeading()
|
|||||||
if ((value != NULL) &&
|
if ((value != NULL) &&
|
||||||
(value->tag == BACNET_APPLICATION_TAG_CHARACTER_STRING)) {
|
(value->tag == BACNET_APPLICATION_TAG_CHARACTER_STRING)) {
|
||||||
printf("Vendor Name: \"%s\"\n",
|
printf("Vendor Name: \"%s\"\n",
|
||||||
characterstring_value(&value->type.Character_String));
|
characterstring_value(&value->type.Character_String));
|
||||||
} else {
|
} else {
|
||||||
printf("Vendor Name: \"your vendor name here\"\n");
|
printf("Vendor Name: \"your vendor name here\"\n");
|
||||||
}
|
}
|
||||||
@@ -1157,9 +1156,9 @@ void PrintHeading()
|
|||||||
if ((value != NULL) &&
|
if ((value != NULL) &&
|
||||||
(value->tag == BACNET_APPLICATION_TAG_CHARACTER_STRING)) {
|
(value->tag == BACNET_APPLICATION_TAG_CHARACTER_STRING)) {
|
||||||
printf("Product Name: \"%s\"\n",
|
printf("Product Name: \"%s\"\n",
|
||||||
characterstring_value(&value->type.Character_String));
|
characterstring_value(&value->type.Character_String));
|
||||||
printf("Product Model Number: \"%s\"\n",
|
printf("Product Model Number: \"%s\"\n",
|
||||||
characterstring_value(&value->type.Character_String));
|
characterstring_value(&value->type.Character_String));
|
||||||
} else {
|
} else {
|
||||||
printf("Product Name: \"your product name here\"\n");
|
printf("Product Name: \"your product name here\"\n");
|
||||||
printf("Product Model Number: \"your model number here\"\n");
|
printf("Product Model Number: \"your model number here\"\n");
|
||||||
@@ -1169,11 +1168,10 @@ void PrintHeading()
|
|||||||
if ((value != NULL) &&
|
if ((value != NULL) &&
|
||||||
(value->tag == BACNET_APPLICATION_TAG_CHARACTER_STRING)) {
|
(value->tag == BACNET_APPLICATION_TAG_CHARACTER_STRING)) {
|
||||||
printf("Product Description: \"%s\"\n\n",
|
printf("Product Description: \"%s\"\n\n",
|
||||||
characterstring_value(&value->type.Character_String));
|
characterstring_value(&value->type.Character_String));
|
||||||
} else {
|
} else {
|
||||||
printf(
|
printf("Product Description: "
|
||||||
"Product Description: "
|
"\"your product description here\"\n\n");
|
||||||
"\"your product description here\"\n\n");
|
|
||||||
}
|
}
|
||||||
printf("BIBBs Supported:\n");
|
printf("BIBBs Supported:\n");
|
||||||
printf("{\n");
|
printf("{\n");
|
||||||
@@ -1347,9 +1345,8 @@ void PrintHeading()
|
|||||||
printf(
|
printf(
|
||||||
" real: <minimum: -3.40282347E38; maximum: 3.40282347E38; resolution: "
|
" real: <minimum: -3.40282347E38; maximum: 3.40282347E38; resolution: "
|
||||||
"1.0>\n");
|
"1.0>\n");
|
||||||
printf(
|
printf(" double: <minimum: 2.2250738585072016E-38; maximum: "
|
||||||
" double: <minimum: 2.2250738585072016E-38; maximum: "
|
"1.7976931348623157E38; resolution: 0.0001>\n");
|
||||||
"1.7976931348623157E38; resolution: 0.0001>\n");
|
|
||||||
printf(" date: <minimum: 01-January-1970; maximum: 31-December-2038>\n");
|
printf(" date: <minimum: 01-January-1970; maximum: 31-December-2038>\n");
|
||||||
printf(" octet-string: <maximum length string: 122>\n");
|
printf(" octet-string: <maximum length string: 122>\n");
|
||||||
printf(" character-string: <maximum length string: 122>\n");
|
printf(" character-string: <maximum length string: 122>\n");
|
||||||
@@ -1369,7 +1366,7 @@ void PrintHeading()
|
|||||||
printf("}\n\n");
|
printf("}\n\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Print_Device_Heading(void)
|
static void Print_Device_Heading(void)
|
||||||
{
|
{
|
||||||
printf("List of Objects in Test Device:\n");
|
printf("List of Objects in Test Device:\n");
|
||||||
/* Print Opening brace, then kick off the Device Object */
|
/* Print Opening brace, then kick off the Device Object */
|
||||||
@@ -1378,8 +1375,8 @@ void Print_Device_Heading(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize fields for a new Object */
|
/* Initialize fields for a new Object */
|
||||||
void StartNextObject(BACNET_READ_ACCESS_DATA *rpm_object,
|
static void StartNextObject(
|
||||||
BACNET_OBJECT_ID *pNewObject)
|
BACNET_READ_ACCESS_DATA *rpm_object, BACNET_OBJECT_ID *pNewObject)
|
||||||
{
|
{
|
||||||
BACNET_PROPERTY_REFERENCE *rpm_property;
|
BACNET_PROPERTY_REFERENCE *rpm_property;
|
||||||
Error_Detected = false;
|
Error_Detected = false;
|
||||||
@@ -1419,7 +1416,7 @@ int main(int argc, char *argv[])
|
|||||||
time_t timeout_seconds = 0;
|
time_t timeout_seconds = 0;
|
||||||
bool found = false;
|
bool found = false;
|
||||||
BACNET_OBJECT_ID myObject;
|
BACNET_OBJECT_ID myObject;
|
||||||
uint8_t buffer[MAX_PDU] = {0};
|
uint8_t buffer[MAX_PDU] = { 0 };
|
||||||
BACNET_READ_ACCESS_DATA *rpm_object = NULL;
|
BACNET_READ_ACCESS_DATA *rpm_object = NULL;
|
||||||
KEY nextKey;
|
KEY nextKey;
|
||||||
|
|
||||||
@@ -1453,27 +1450,27 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
/* try to bind with the target device */
|
/* try to bind with the target device */
|
||||||
found = address_bind_request(Target_Device_Object_Instance, &max_apdu,
|
found = address_bind_request(
|
||||||
&Target_Address);
|
Target_Device_Object_Instance, &max_apdu, &Target_Address);
|
||||||
if (!found) {
|
if (!found) {
|
||||||
if (Provided_Targ_MAC) {
|
if (Provided_Targ_MAC) {
|
||||||
if (Target_Address.net > 0) {
|
if (Target_Address.net > 0) {
|
||||||
/* We specified a DNET; call Who-Is to find the full
|
/* We specified a DNET; call Who-Is to find the full
|
||||||
* routed path to this Device */
|
* routed path to this Device */
|
||||||
Send_WhoIs_Remote(&Target_Address,
|
Send_WhoIs_Remote(&Target_Address,
|
||||||
Target_Device_Object_Instance,
|
Target_Device_Object_Instance,
|
||||||
Target_Device_Object_Instance);
|
Target_Device_Object_Instance);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
/* Update by adding the MAC address */
|
/* Update by adding the MAC address */
|
||||||
if (max_apdu == 0)
|
if (max_apdu == 0)
|
||||||
max_apdu = MAX_APDU; /* Whatever set for this datalink. */
|
max_apdu = MAX_APDU; /* Whatever set for this datalink. */
|
||||||
address_add_binding(Target_Device_Object_Instance, max_apdu,
|
address_add_binding(
|
||||||
&Target_Address);
|
Target_Device_Object_Instance, max_apdu, &Target_Address);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Send_WhoIs(Target_Device_Object_Instance,
|
Send_WhoIs(
|
||||||
Target_Device_Object_Instance);
|
Target_Device_Object_Instance, Target_Device_Object_Instance);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
myObject.type = OBJECT_DEVICE;
|
myObject.type = OBJECT_DEVICE;
|
||||||
@@ -1500,17 +1497,17 @@ int main(int argc, char *argv[])
|
|||||||
npdu_handler(&src, &Rx_Buf[0], pdu_len);
|
npdu_handler(&src, &Rx_Buf[0], pdu_len);
|
||||||
}
|
}
|
||||||
/* will wait until the device is bound, or timeout and quit */
|
/* will wait until the device is bound, or timeout and quit */
|
||||||
found = address_bind_request(Target_Device_Object_Instance,
|
found = address_bind_request(
|
||||||
&max_apdu, &Target_Address);
|
Target_Device_Object_Instance, &max_apdu, &Target_Address);
|
||||||
if (!found) {
|
if (!found) {
|
||||||
/* increment timer - exit if timed out */
|
/* increment timer - exit if timed out */
|
||||||
elapsed_seconds += (current_seconds - last_seconds);
|
elapsed_seconds += (current_seconds - last_seconds);
|
||||||
if (elapsed_seconds > timeout_seconds) {
|
if (elapsed_seconds > timeout_seconds) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"\rError: Unable to bind to %u"
|
"\rError: Unable to bind to %u"
|
||||||
" after waiting %ld seconds.\n",
|
" after waiting %ld seconds.\n",
|
||||||
Target_Device_Object_Instance,
|
Target_Device_Object_Instance,
|
||||||
(long int)elapsed_seconds);
|
(long int)elapsed_seconds);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* else, loop back and try again */
|
/* else, loop back and try again */
|
||||||
@@ -1580,7 +1577,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
if ((Read_Property_Multiple_Data.new_data) &&
|
if ((Read_Property_Multiple_Data.new_data) &&
|
||||||
(Request_Invoke_ID ==
|
(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;
|
Read_Property_Multiple_Data.new_data = false;
|
||||||
myState = ProcessRPMData(
|
myState = ProcessRPMData(
|
||||||
Read_Property_Multiple_Data.rpm_data, myState);
|
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? */
|
/* Was it because the Device can't do RPM? */
|
||||||
Has_RPM = false;
|
Has_RPM = false;
|
||||||
myState = GET_PROPERTY_REQUEST;
|
myState = GET_PROPERTY_REQUEST;
|
||||||
} else if (
|
} else if (Last_Error_Code ==
|
||||||
Last_Error_Code ==
|
|
||||||
ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED) {
|
ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED) {
|
||||||
myState = GET_PROPERTY_REQUEST;
|
myState = GET_PROPERTY_REQUEST;
|
||||||
StartNextObject(rpm_object, &myObject);
|
StartNextObject(rpm_object, &myObject);
|
||||||
@@ -1639,8 +1635,8 @@ int main(int argc, char *argv[])
|
|||||||
myState = PRINT_HEADING;
|
myState = PRINT_HEADING;
|
||||||
/* just press ahead without the data */
|
/* just press ahead without the data */
|
||||||
else
|
else
|
||||||
myState =
|
myState = NEXT_OBJECT; /* Give up and move on to the
|
||||||
NEXT_OBJECT; /* Give up and move on to the next. */
|
next. */
|
||||||
Error_Count++;
|
Error_Count++;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -1672,7 +1668,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
if ((Read_Property_Multiple_Data.new_data) &&
|
if ((Read_Property_Multiple_Data.new_data) &&
|
||||||
(Request_Invoke_ID ==
|
(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;
|
Read_Property_Multiple_Data.new_data = false;
|
||||||
PrintReadPropertyData(
|
PrintReadPropertyData(
|
||||||
Read_Property_Multiple_Data.rpm_data->object_type,
|
Read_Property_Multiple_Data.rpm_data->object_type,
|
||||||
@@ -1752,8 +1748,8 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
case NEXT_OBJECT:
|
case NEXT_OBJECT:
|
||||||
if (myObject.type == OBJECT_DEVICE) {
|
if (myObject.type == OBJECT_DEVICE) {
|
||||||
printf(" -- Found %d Objects \n",
|
printf(
|
||||||
Keylist_Count(Object_List));
|
" -- Found %d Objects \n", Keylist_Count(Object_List));
|
||||||
Object_List_Index = -1; /* start over (will be incr to 0) */
|
Object_List_Index = -1; /* start over (will be incr to 0) */
|
||||||
if (ShowDeviceObjectOnly) {
|
if (ShowDeviceObjectOnly) {
|
||||||
/* Closing brace for the Device Object */
|
/* Closing brace for the Device Object */
|
||||||
@@ -1814,15 +1810,16 @@ int main(int argc, char *argv[])
|
|||||||
elapsed_seconds += (current_seconds - last_seconds);
|
elapsed_seconds += (current_seconds - last_seconds);
|
||||||
if (elapsed_seconds > timeout_seconds) {
|
if (elapsed_seconds > timeout_seconds) {
|
||||||
fprintf(stderr, "\rError: APDU Timeout! (%lds)\n",
|
fprintf(stderr, "\rError: APDU Timeout! (%lds)\n",
|
||||||
(long int)elapsed_seconds);
|
(long int)elapsed_seconds);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} while (myObject.type < MAX_BACNET_OBJECT_TYPE);
|
} while (myObject.type < MAX_BACNET_OBJECT_TYPE);
|
||||||
|
|
||||||
if (Error_Count > 0)
|
if (Error_Count > 0) {
|
||||||
fprintf(stdout, "\r-- Found %d Errors \n", Error_Count);
|
fprintf(stdout, "\r-- Found %d Errors \n", Error_Count);
|
||||||
|
}
|
||||||
|
|
||||||
/* Closing brace for all Objects, if we got any, and closing footer */
|
/* Closing brace for all Objects, if we got any, and closing footer */
|
||||||
if (myState != INITIAL_BINDING) {
|
if (myState != INITIAL_BINDING) {
|
||||||
@@ -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
|
||||||
|
|
||||||
@@ -30,22 +30,22 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <time.h> /* for time */
|
#include <time.h> /* for time */
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include "bactext.h"
|
#include "bacnet/bactext.h"
|
||||||
#include "iam.h"
|
#include "bacnet/iam.h"
|
||||||
#include "address.h"
|
#include "bacnet/config.h"
|
||||||
#include "config.h"
|
#include "bacnet/bacdef.h"
|
||||||
#include "bacdef.h"
|
#include "bacnet/npdu.h"
|
||||||
#include "npdu.h"
|
#include "bacnet/apdu.h"
|
||||||
#include "apdu.h"
|
#include "bacnet/version.h"
|
||||||
#include "device.h"
|
|
||||||
#include "datalink.h"
|
|
||||||
#include "version.h"
|
|
||||||
/* some demo stuff needed */
|
/* some demo stuff needed */
|
||||||
#include "filename.h"
|
#include "bacnet/basic/binding/address.h"
|
||||||
#include "handlers.h"
|
#include "bacnet/basic/object/device.h"
|
||||||
#include "client.h"
|
#include "bacnet/basic/services.h"
|
||||||
#include "txbuf.h"
|
#include "bacnet/basic/services.h"
|
||||||
#include "dlenv.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 */
|
/* parsed command line parameters */
|
||||||
static uint16_t Target_Error_Class;
|
static uint16_t Target_Error_Class;
|
||||||
@@ -55,8 +55,8 @@ static uint16_t Target_Service = SERVICE_CONFIRMED_READ_PROPERTY;
|
|||||||
/* flag for signalling errors */
|
/* flag for signalling errors */
|
||||||
static bool Error_Detected = false;
|
static bool Error_Detected = false;
|
||||||
|
|
||||||
void MyAbortHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
|
static void MyAbortHandler(
|
||||||
uint8_t abort_reason, bool server)
|
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t abort_reason, bool server)
|
||||||
{
|
{
|
||||||
(void)src;
|
(void)src;
|
||||||
(void)invoke_id;
|
(void)invoke_id;
|
||||||
@@ -65,8 +65,8 @@ void MyAbortHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
|
|||||||
Error_Detected = true;
|
Error_Detected = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
|
static void MyRejectHandler(
|
||||||
uint8_t reject_reason)
|
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||||
{
|
{
|
||||||
(void)src;
|
(void)src;
|
||||||
(void)invoke_id;
|
(void)invoke_id;
|
||||||
@@ -84,8 +84,8 @@ static void Init_Service_Handlers(void)
|
|||||||
It is required to send the proper reject message... */
|
It is required to send the proper reject message... */
|
||||||
apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service);
|
apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service);
|
||||||
/* we must implement read property - it's required! */
|
/* we must implement read property - it's required! */
|
||||||
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY,
|
apdu_set_confirmed_handler(
|
||||||
handler_read_property);
|
SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property);
|
||||||
/* handle the reply (request) coming back */
|
/* handle the reply (request) coming back */
|
||||||
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_I_AM, handler_i_am_add);
|
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_I_AM, handler_i_am_add);
|
||||||
/* handle any errors coming back */
|
/* handle any errors coming back */
|
||||||
@@ -96,7 +96,7 @@ static void Init_Service_Handlers(void)
|
|||||||
static void print_usage(char *filename)
|
static void print_usage(char *filename)
|
||||||
{
|
{
|
||||||
printf("Usage: %s [error-class error-code service-number invoke-id]\n",
|
printf("Usage: %s [error-class error-code service-number invoke-id]\n",
|
||||||
filename);
|
filename);
|
||||||
printf(" [--dnet][--dadr][--mac]\n");
|
printf(" [--dnet][--dadr][--mac]\n");
|
||||||
printf(" [--version][--help]\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 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"
|
"or an Ethernet MAC in hex like 00:21:70:7e:32:bb\n"
|
||||||
"\n");
|
"\n");
|
||||||
printf(
|
printf("error-class:\n"
|
||||||
"error-class:\n"
|
" number from 0 to 65535\n"
|
||||||
" number from 0 to 65535\n"
|
"error-code:\n"
|
||||||
"error-code:\n"
|
" number from 0 to 65535\n"
|
||||||
" number from 0 to 65535\n"
|
"service-number:\n"
|
||||||
"service-number:\n"
|
" number from 0 to 65535 for BACnet Services\n"
|
||||||
" number from 0 to 65535 for BACnet Services\n"
|
"invoke-id:\n"
|
||||||
"invoke-id:\n"
|
" number from 1 to 255\n"
|
||||||
" number from 1 to 255\n"
|
"Example:\n"
|
||||||
"Example:\n"
|
"%s 3 2 1\n",
|
||||||
"%s 3 2 1\n",
|
|
||||||
filename);
|
filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
long dnet = -1;
|
long dnet = -1;
|
||||||
BACNET_MAC_ADDRESS mac = {0};
|
BACNET_MAC_ADDRESS mac = { 0 };
|
||||||
BACNET_MAC_ADDRESS adr = {0};
|
BACNET_MAC_ADDRESS adr = { 0 };
|
||||||
BACNET_ADDRESS dest = {0};
|
BACNET_ADDRESS dest = { 0 };
|
||||||
bool specific_address = false;
|
bool specific_address = false;
|
||||||
int argi = 0;
|
int argi = 0;
|
||||||
unsigned int target_args = 0;
|
unsigned int target_args = 0;
|
||||||
@@ -157,12 +156,11 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
if (strcmp(argv[argi], "--version") == 0) {
|
if (strcmp(argv[argi], "--version") == 0) {
|
||||||
printf("%s %s\n", filename, BACNET_VERSION_TEXT);
|
printf("%s %s\n", filename, BACNET_VERSION_TEXT);
|
||||||
printf(
|
printf("Copyright (C) 2016 by Steve Karg and others.\n"
|
||||||
"Copyright (C) 2016 by Steve Karg and others.\n"
|
"This is free software; see the source for copying "
|
||||||
"This is free software; see the source for copying "
|
"conditions.\n"
|
||||||
"conditions.\n"
|
"There is NO warranty; not even for MERCHANTABILITY or\n"
|
||||||
"There is NO warranty; not even for MERCHANTABILITY or\n"
|
"FITNESS FOR A PARTICULAR PURPOSE.\n");
|
||||||
"FITNESS FOR A PARTICULAR PURPOSE.\n");
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (strcmp(argv[argi], "--mac") == 0) {
|
if (strcmp(argv[argi], "--mac") == 0) {
|
||||||
@@ -242,8 +240,7 @@ int main(int argc, char *argv[])
|
|||||||
atexit(datalink_cleanup);
|
atexit(datalink_cleanup);
|
||||||
/* send the request */
|
/* send the request */
|
||||||
Send_Error_To_Network(&Handler_Transmit_Buffer[0], &dest, Target_Invoke_ID,
|
Send_Error_To_Network(&Handler_Transmit_Buffer[0], &dest, Target_Invoke_ID,
|
||||||
Target_Service, Target_Error_Class,
|
Target_Service, Target_Error_Class, Target_Error_Code);
|
||||||
Target_Error_Code);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -33,31 +33,31 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include "config.h"
|
#include "bacnet/config.h"
|
||||||
#include "gateway.h"
|
#include "gateway.h"
|
||||||
#include "address.h"
|
#include "bacnet/basic/binding/address.h"
|
||||||
#include "bacdef.h"
|
#include "bacnet/bacdef.h"
|
||||||
#include "handlers.h"
|
#include "bacnet/basic/services.h"
|
||||||
#include "client.h"
|
#include "bacnet/basic/services.h"
|
||||||
#include "dlenv.h"
|
#include "bacnet/datalink/dlenv.h"
|
||||||
#include "bacdcode.h"
|
#include "bacnet/bacdcode.h"
|
||||||
#include "npdu.h"
|
#include "bacnet/npdu.h"
|
||||||
#include "apdu.h"
|
#include "bacnet/apdu.h"
|
||||||
#include "iam.h"
|
#include "bacnet/iam.h"
|
||||||
#include "tsm.h"
|
#include "bacnet/basic/tsm/tsm.h"
|
||||||
#include "device.h"
|
#include "bacnet/basic/object/device.h"
|
||||||
#include "bacfile.h"
|
#include "bacnet/basic/object/bacfile.h"
|
||||||
#include "datalink.h"
|
#include "bacnet/datalink/datalink.h"
|
||||||
#include "dcc.h"
|
#include "bacnet/dcc.h"
|
||||||
#include "net.h"
|
#include "bacport.h"
|
||||||
#include "txbuf.h"
|
#include "bacnet/basic/tsm/tsm.h"
|
||||||
#include "lc.h"
|
#include "bacnet/basic/object/lc.h"
|
||||||
#include "debug.h"
|
#include "bacnet/basic/sys/debug.h"
|
||||||
#include "version.h"
|
#include "bacnet/version.h"
|
||||||
/* include the device object */
|
/* include the device object */
|
||||||
#include "device.h"
|
#include "bacnet/basic/object/device.h"
|
||||||
#ifdef BACNET_TEST_VMAC
|
#ifdef BACNET_TEST_VMAC
|
||||||
#include "vmac.h"
|
#include "bacnet/basic/bbmd6/vmac.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** @file gateway/main.c Example virtual gateway application using the BACnet
|
/** @file gateway/main.c Example virtual gateway application using the BACnet
|
||||||
@@ -71,7 +71,7 @@
|
|||||||
/*@{*/
|
/*@{*/
|
||||||
|
|
||||||
/** Buffer used for receiving */
|
/** 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.
|
/** The list of DNETs that our router can reach.
|
||||||
* Only one entry since we don't support downstream routers.
|
* Only one entry since we don't support downstream routers.
|
||||||
@@ -80,6 +80,9 @@ int DNET_list[2] = {
|
|||||||
VIRTUAL_DNET, -1 /* Need -1 terminator */
|
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.
|
/** Initialize the Device Objects and each of the child Object instances.
|
||||||
* @param first_object_instance Set the first (gateway) Device to this
|
* @param first_object_instance Set the first (gateway) Device to this
|
||||||
instance number, and subsequent devices to incremented values.
|
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
|
* Don't need the routed versions, since the npdu handler calls
|
||||||
* each device in turn.
|
* each device in turn.
|
||||||
*/
|
*/
|
||||||
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS,
|
apdu_set_unconfirmed_handler(
|
||||||
handler_who_is_unicast);
|
SERVICE_UNCONFIRMED_WHO_IS, handler_who_is_unicast);
|
||||||
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_HAS, handler_who_has);
|
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_HAS, handler_who_has);
|
||||||
/* set the handler for all the services we don't implement */
|
/* set the handler for all the services we don't implement */
|
||||||
/* It is required to send the proper reject message... */
|
/* It is required to send the proper reject message... */
|
||||||
apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service);
|
apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service);
|
||||||
/* Set the handlers for any confirmed services that we support. */
|
/* Set the handlers for any confirmed services that we support. */
|
||||||
/* We must implement read property - it's required! */
|
/* We must implement read property - it's required! */
|
||||||
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY,
|
apdu_set_confirmed_handler(
|
||||||
handler_read_property);
|
SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property);
|
||||||
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROP_MULTIPLE,
|
apdu_set_confirmed_handler(
|
||||||
handler_read_property_multiple);
|
SERVICE_CONFIRMED_READ_PROP_MULTIPLE, handler_read_property_multiple);
|
||||||
apdu_set_confirmed_handler(SERVICE_CONFIRMED_WRITE_PROPERTY,
|
apdu_set_confirmed_handler(
|
||||||
handler_write_property);
|
SERVICE_CONFIRMED_WRITE_PROPERTY, handler_write_property);
|
||||||
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_RANGE,
|
apdu_set_confirmed_handler(
|
||||||
handler_read_range);
|
SERVICE_CONFIRMED_READ_RANGE, handler_read_range);
|
||||||
#if defined(BACFILE)
|
#if defined(BACFILE)
|
||||||
apdu_set_confirmed_handler(SERVICE_CONFIRMED_ATOMIC_READ_FILE,
|
apdu_set_confirmed_handler(
|
||||||
handler_atomic_read_file);
|
SERVICE_CONFIRMED_ATOMIC_READ_FILE, handler_atomic_read_file);
|
||||||
apdu_set_confirmed_handler(SERVICE_CONFIRMED_ATOMIC_WRITE_FILE,
|
apdu_set_confirmed_handler(
|
||||||
handler_atomic_write_file);
|
SERVICE_CONFIRMED_ATOMIC_WRITE_FILE, handler_atomic_write_file);
|
||||||
#endif
|
#endif
|
||||||
apdu_set_confirmed_handler(SERVICE_CONFIRMED_REINITIALIZE_DEVICE,
|
apdu_set_confirmed_handler(
|
||||||
handler_reinitialize_device);
|
SERVICE_CONFIRMED_REINITIALIZE_DEVICE, handler_reinitialize_device);
|
||||||
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_UTC_TIME_SYNCHRONIZATION,
|
apdu_set_unconfirmed_handler(
|
||||||
handler_timesync_utc);
|
SERVICE_UNCONFIRMED_UTC_TIME_SYNCHRONIZATION, handler_timesync_utc);
|
||||||
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_TIME_SYNCHRONIZATION,
|
apdu_set_unconfirmed_handler(
|
||||||
handler_timesync);
|
SERVICE_UNCONFIRMED_TIME_SYNCHRONIZATION, handler_timesync);
|
||||||
apdu_set_confirmed_handler(SERVICE_CONFIRMED_SUBSCRIBE_COV,
|
apdu_set_confirmed_handler(
|
||||||
handler_cov_subscribe);
|
SERVICE_CONFIRMED_SUBSCRIBE_COV, handler_cov_subscribe);
|
||||||
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_COV_NOTIFICATION,
|
apdu_set_unconfirmed_handler(
|
||||||
handler_ucov_notification);
|
SERVICE_UNCONFIRMED_COV_NOTIFICATION, handler_ucov_notification);
|
||||||
/* handle communication so we can shutup when asked */
|
/* handle communication so we can shutup when asked */
|
||||||
apdu_set_confirmed_handler(SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL,
|
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.
|
/** 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);
|
memcpy(&pDev->bacDevAddr.adr[0], &pDev->bacDevAddr.mac[0], 6);
|
||||||
pDev->bacDevAddr.len = 6;
|
pDev->bacDevAddr.len = 6;
|
||||||
printf(" - Routed device [%d] ID %u at %s \n", i,
|
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)
|
#elif defined(BACDL_MSTP)
|
||||||
/* Todo: set MS/TP net and port #s */
|
/* Todo: set MS/TP net and port #s */
|
||||||
pDev->bacDevAddr.mac_len = 2;
|
pDev->bacDevAddr.mac_len = 2;
|
||||||
@@ -248,7 +251,7 @@ static void Initialize_Device_Addresses()
|
|||||||
*/
|
*/
|
||||||
int main(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;
|
uint16_t pdu_len = 0;
|
||||||
unsigned timeout = 1000; /* milliseconds */
|
unsigned timeout = 1000; /* milliseconds */
|
||||||
time_t last_seconds = 0;
|
time_t last_seconds = 0;
|
||||||
@@ -268,16 +271,15 @@ int main(int argc, char *argv[])
|
|||||||
if ((first_object_instance == 0) ||
|
if ((first_object_instance == 0) ||
|
||||||
(first_object_instance >= BACNET_MAX_INSTANCE)) {
|
(first_object_instance >= BACNET_MAX_INSTANCE)) {
|
||||||
printf("Error: Invalid Object Instance %s \n", argv[1]);
|
printf("Error: Invalid Object Instance %s \n", argv[1]);
|
||||||
printf("Provide a number from 1 to %ul \n",
|
printf(
|
||||||
BACNET_MAX_INSTANCE - 1);
|
"Provide a number from 1 to %ul \n", BACNET_MAX_INSTANCE - 1);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
printf(
|
printf("BACnet Router Demo\n"
|
||||||
"BACnet Router Demo\n"
|
"BACnet Stack Version %s\n"
|
||||||
"BACnet Stack Version %s\n"
|
"BACnet Device ID: %u\n"
|
||||||
"BACnet Device ID: %u\n"
|
"Max APDU: %d\n",
|
||||||
"Max APDU: %d\n",
|
|
||||||
BACnet_Version, first_object_instance, MAX_APDU);
|
BACnet_Version, first_object_instance, MAX_APDU);
|
||||||
Init_Service_Handlers(first_object_instance);
|
Init_Service_Handlers(first_object_instance);
|
||||||
dlenv_init();
|
dlenv_init();
|
||||||
@@ -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
|
||||||
|
|
||||||
Executable → Regular
+60
-61
@@ -29,30 +29,27 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
/* core stuff needed */
|
/* core stuff needed */
|
||||||
#include "bacdef.h"
|
#include "bacnet/bacdef.h"
|
||||||
#include "config.h"
|
#include "bacnet/config.h"
|
||||||
#include "bactext.h"
|
#include "bacnet/bactext.h"
|
||||||
#include "bacerror.h"
|
#include "bacnet/bacerror.h"
|
||||||
#include "iam.h"
|
#include "bacnet/iam.h"
|
||||||
#include "arf.h"
|
#include "bacnet/arf.h"
|
||||||
#include "tsm.h"
|
#include "bacnet/npdu.h"
|
||||||
#include "address.h"
|
#include "bacnet/apdu.h"
|
||||||
#include "npdu.h"
|
#include "bacnet/whois.h"
|
||||||
#include "apdu.h"
|
#include "bacnet/getevent.h"
|
||||||
#include "device.h"
|
|
||||||
#include "net.h"
|
|
||||||
#include "datalink.h"
|
|
||||||
#include "whois.h"
|
|
||||||
#include "getevent.h"
|
|
||||||
|
|
||||||
/* some demo stuff needed */
|
/* some demo stuff needed */
|
||||||
#include "filename.h"
|
#include "bacnet/basic/binding/address.h"
|
||||||
#include "handlers.h"
|
#include "bacnet/basic/object/device.h"
|
||||||
#include "client.h"
|
#include "bacnet/basic/services.h"
|
||||||
#include "txbuf.h"
|
#include "bacnet/basic/sys/filename.h"
|
||||||
#include "dlenv.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),
|
/* Depending on on the max-APDU-length-accepted (varies per device),
|
||||||
the amount of event entries in the GetEventInformation ACK can sum
|
the amount of event entries in the GetEventInformation ACK can sum
|
||||||
@@ -61,7 +58,7 @@
|
|||||||
#define MAX_OBJ_IDS_IN_GE_ACK 24
|
#define MAX_OBJ_IDS_IN_GE_ACK 24
|
||||||
|
|
||||||
/* buffer used for receive */
|
/* buffer used for receive */
|
||||||
static uint8_t Rx_Buf[MAX_MPDU] = {0};
|
static uint8_t Rx_Buf[MAX_MPDU] = { 0 };
|
||||||
|
|
||||||
/* converted command line arguments */
|
/* converted command line arguments */
|
||||||
static uint32_t Target_Device_Object_Instance = BACNET_MAX_INSTANCE;
|
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 bool More_Events = false;
|
||||||
static BACNET_OBJECT_ID LastReceivedObjectIdentifier;
|
static BACNET_OBJECT_ID LastReceivedObjectIdentifier;
|
||||||
|
|
||||||
static void MyErrorHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
|
static void MyErrorHandler(BACNET_ADDRESS *src,
|
||||||
BACNET_ERROR_CLASS error_class,
|
uint8_t invoke_id,
|
||||||
BACNET_ERROR_CODE error_code)
|
BACNET_ERROR_CLASS error_class,
|
||||||
|
BACNET_ERROR_CODE error_code)
|
||||||
{
|
{
|
||||||
if (address_match(&Target_Address, src) &&
|
if (address_match(&Target_Address, src) &&
|
||||||
(invoke_id == Request_Invoke_ID)) {
|
(invoke_id == Request_Invoke_ID)) {
|
||||||
printf("BACnet Error: %s: %s\r\n",
|
printf("BACnet Error: %s: %s\r\n",
|
||||||
bactext_error_class_name((int)error_class),
|
bactext_error_class_name((int)error_class),
|
||||||
bactext_error_code_name((int)error_code));
|
bactext_error_code_name((int)error_code));
|
||||||
Error_Detected = true;
|
Error_Detected = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MyAbortHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
|
static void MyAbortHandler(
|
||||||
uint8_t abort_reason, bool server)
|
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t abort_reason, bool server)
|
||||||
{
|
{
|
||||||
(void)server;
|
(void)server;
|
||||||
if (address_match(&Target_Address, src) &&
|
if (address_match(&Target_Address, src) &&
|
||||||
(invoke_id == Request_Invoke_ID)) {
|
(invoke_id == Request_Invoke_ID)) {
|
||||||
printf("BACnet Abort: %s\r\n",
|
printf("BACnet Abort: %s\r\n",
|
||||||
bactext_abort_reason_name((int)abort_reason));
|
bactext_abort_reason_name((int)abort_reason));
|
||||||
Error_Detected = true;
|
Error_Detected = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
|
static void MyRejectHandler(
|
||||||
uint8_t reject_reason)
|
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||||
{
|
{
|
||||||
if (address_match(&Target_Address, src) &&
|
if (address_match(&Target_Address, src) &&
|
||||||
(invoke_id == Request_Invoke_ID)) {
|
(invoke_id == Request_Invoke_ID)) {
|
||||||
printf("BACnet Reject: %s\r\n",
|
printf("BACnet Reject: %s\r\n",
|
||||||
bactext_reject_reason_name((int)reject_reason));
|
bactext_reject_reason_name((int)reject_reason));
|
||||||
Error_Detected = true;
|
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
|
* @param service_data [in] The BACNET_CONFIRMED_SERVICE_DATA information
|
||||||
* decoded from the APDU header of this message.
|
* decoded from the APDU header of this message.
|
||||||
*/
|
*/
|
||||||
void My_Get_Event_Ack_Handler(uint8_t *service_request, uint16_t service_len,
|
static void My_Get_Event_Ack_Handler(uint8_t *service_request,
|
||||||
BACNET_ADDRESS *src,
|
uint16_t service_len,
|
||||||
BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data)
|
BACNET_ADDRESS *src,
|
||||||
|
BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data)
|
||||||
{
|
{
|
||||||
int len = 0;
|
int len = 0;
|
||||||
int i;
|
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];
|
data[i].next = &data[i + 1];
|
||||||
|
|
||||||
printf("Recieved Ack. Saved invoke ID was %i, service returned %i\n",
|
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) {
|
if (service_data->invoke_id == Request_Invoke_ID) {
|
||||||
len = getevent_ack_decode_service_request(service_request, service_len,
|
len = getevent_ack_decode_service_request(
|
||||||
&data[0], &More_Events);
|
service_request, service_len, &data[0], &More_Events);
|
||||||
printf("Decode of Ack returned length %i. MoreEvents flag was %i \n",
|
printf("Decode of Ack returned length %i. MoreEvents flag was %i \n",
|
||||||
len, More_Events);
|
len, More_Events);
|
||||||
if (len > 0) {
|
if (len > 0) {
|
||||||
ge_ack_print_data(&(data[0]), Target_Device_Object_Instance);
|
ge_ack_print_data(&(data[0]), Target_Device_Object_Instance);
|
||||||
if (More_Events) {
|
if (More_Events) {
|
||||||
@@ -162,11 +161,11 @@ static void Init_Service_Handlers(void)
|
|||||||
It is required to send the proper reject message... */
|
It is required to send the proper reject message... */
|
||||||
apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service);
|
apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service);
|
||||||
/* we must implement getevent - it's required! */
|
/* we must implement getevent - it's required! */
|
||||||
apdu_set_confirmed_handler(SERVICE_CONFIRMED_GET_EVENT_INFORMATION,
|
apdu_set_confirmed_handler(
|
||||||
handler_get_event_information);
|
SERVICE_CONFIRMED_GET_EVENT_INFORMATION, handler_get_event_information);
|
||||||
/* handle the data coming back from confirmed requests */
|
/* handle the data coming back from confirmed requests */
|
||||||
apdu_set_confirmed_ack_handler(SERVICE_CONFIRMED_GET_EVENT_INFORMATION,
|
apdu_set_confirmed_ack_handler(
|
||||||
My_Get_Event_Ack_Handler);
|
SERVICE_CONFIRMED_GET_EVENT_INFORMATION, My_Get_Event_Ack_Handler);
|
||||||
/* handle any errors coming back */
|
/* handle any errors coming back */
|
||||||
apdu_set_error_handler(SERVICE_CONFIRMED_READ_PROPERTY, MyErrorHandler);
|
apdu_set_error_handler(SERVICE_CONFIRMED_READ_PROPERTY, MyErrorHandler);
|
||||||
apdu_set_abort_handler(MyAbortHandler);
|
apdu_set_abort_handler(MyAbortHandler);
|
||||||
@@ -175,21 +174,20 @@ static void Init_Service_Handlers(void)
|
|||||||
|
|
||||||
static int print_help(char *exe_name)
|
static int print_help(char *exe_name)
|
||||||
{
|
{
|
||||||
printf(
|
printf("Usage:\n"
|
||||||
"Usage:\n"
|
"\n"
|
||||||
"\n"
|
"%s device-instance [--help]\n"
|
||||||
"%s device-instance [--help]\n"
|
"\n"
|
||||||
"\n"
|
" Send BACnet GetEventInformation service retruequest to given "
|
||||||
" Send BACnet GetEventInformation service retruequest to given "
|
"device, and wait\n"
|
||||||
"device, and wait\n"
|
" for responses.\n\n",
|
||||||
" for responses.\n\n",
|
|
||||||
exe_name);
|
exe_name);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(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;
|
uint16_t pdu_len = 0;
|
||||||
unsigned timeout = 100; /* milliseconds */
|
unsigned timeout = 100; /* milliseconds */
|
||||||
unsigned max_apdu = 0;
|
unsigned max_apdu = 0;
|
||||||
@@ -220,11 +218,11 @@ int main(int argc, char *argv[])
|
|||||||
last_seconds = time(NULL);
|
last_seconds = time(NULL);
|
||||||
timeout_seconds = (apdu_timeout() / 1000) * apdu_retries();
|
timeout_seconds = (apdu_timeout() / 1000) * apdu_retries();
|
||||||
/* try to bind with the device */
|
/* try to bind with the device */
|
||||||
found = address_bind_request(Target_Device_Object_Instance, &max_apdu,
|
found = address_bind_request(
|
||||||
&Target_Address);
|
Target_Device_Object_Instance, &max_apdu, &Target_Address);
|
||||||
if (!found) {
|
if (!found) {
|
||||||
Send_WhoIs(Target_Device_Object_Instance,
|
Send_WhoIs(
|
||||||
Target_Device_Object_Instance);
|
Target_Device_Object_Instance, Target_Device_Object_Instance);
|
||||||
}
|
}
|
||||||
/* loop forever */
|
/* loop forever */
|
||||||
for (;;) {
|
for (;;) {
|
||||||
@@ -232,17 +230,18 @@ int main(int argc, char *argv[])
|
|||||||
current_seconds = time(NULL);
|
current_seconds = time(NULL);
|
||||||
|
|
||||||
/* at least one second has passed */
|
/* at least one second has passed */
|
||||||
if (current_seconds != last_seconds)
|
if (current_seconds != last_seconds) {
|
||||||
tsm_timer_milliseconds(
|
tsm_timer_milliseconds(
|
||||||
(uint16_t)((current_seconds - last_seconds) * 1000));
|
(uint16_t)((current_seconds - last_seconds) * 1000));
|
||||||
|
}
|
||||||
|
|
||||||
if (Error_Detected) {
|
if (Error_Detected) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* wait until the device is bound, or timeout and quit */
|
/* wait until the device is bound, or timeout and quit */
|
||||||
if (!found) {
|
if (!found) {
|
||||||
found = address_bind_request(Target_Device_Object_Instance,
|
found = address_bind_request(
|
||||||
&max_apdu, &Target_Address);
|
Target_Device_Object_Instance, &max_apdu, &Target_Address);
|
||||||
}
|
}
|
||||||
if (found) {
|
if (found) {
|
||||||
if (Request_Invoke_ID == 0) {
|
if (Request_Invoke_ID == 0) {
|
||||||
@@ -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
|
||||||
|
|
||||||
@@ -30,22 +30,22 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <time.h> /* for time */
|
#include <time.h> /* for time */
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include "bactext.h"
|
#include "bacnet/bactext.h"
|
||||||
#include "iam.h"
|
#include "bacnet/iam.h"
|
||||||
#include "address.h"
|
#include "bacnet/basic/binding/address.h"
|
||||||
#include "config.h"
|
#include "bacnet/config.h"
|
||||||
#include "bacdef.h"
|
#include "bacnet/bacdef.h"
|
||||||
#include "npdu.h"
|
#include "bacnet/npdu.h"
|
||||||
#include "apdu.h"
|
#include "bacnet/apdu.h"
|
||||||
#include "device.h"
|
#include "bacnet/basic/object/device.h"
|
||||||
#include "datalink.h"
|
#include "bacnet/datalink/datalink.h"
|
||||||
#include "version.h"
|
#include "bacnet/version.h"
|
||||||
/* some demo stuff needed */
|
/* some demo stuff needed */
|
||||||
#include "filename.h"
|
#include "bacnet/basic/sys/filename.h"
|
||||||
#include "handlers.h"
|
#include "bacnet/basic/services.h"
|
||||||
#include "client.h"
|
#include "bacnet/basic/services.h"
|
||||||
#include "txbuf.h"
|
#include "bacnet/basic/tsm/tsm.h"
|
||||||
#include "dlenv.h"
|
#include "bacnet/datalink/dlenv.h"
|
||||||
|
|
||||||
/* parsed command line parameters */
|
/* parsed command line parameters */
|
||||||
static uint32_t Target_Device_ID = BACNET_MAX_INSTANCE;
|
static uint32_t Target_Device_ID = BACNET_MAX_INSTANCE;
|
||||||
@@ -55,8 +55,8 @@ static int Target_Segmentation = SEGMENTATION_NONE;
|
|||||||
/* flag for signalling errors */
|
/* flag for signalling errors */
|
||||||
static bool Error_Detected = false;
|
static bool Error_Detected = false;
|
||||||
|
|
||||||
void MyAbortHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
|
static void MyAbortHandler(
|
||||||
uint8_t abort_reason, bool server)
|
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t abort_reason, bool server)
|
||||||
{
|
{
|
||||||
(void)src;
|
(void)src;
|
||||||
(void)invoke_id;
|
(void)invoke_id;
|
||||||
@@ -65,8 +65,8 @@ void MyAbortHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
|
|||||||
Error_Detected = true;
|
Error_Detected = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
|
static void MyRejectHandler(
|
||||||
uint8_t reject_reason)
|
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||||
{
|
{
|
||||||
(void)src;
|
(void)src;
|
||||||
(void)invoke_id;
|
(void)invoke_id;
|
||||||
@@ -84,8 +84,8 @@ static void Init_Service_Handlers(void)
|
|||||||
It is required to send the proper reject message... */
|
It is required to send the proper reject message... */
|
||||||
apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service);
|
apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service);
|
||||||
/* we must implement read property - it's required! */
|
/* we must implement read property - it's required! */
|
||||||
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY,
|
apdu_set_confirmed_handler(
|
||||||
handler_read_property);
|
SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property);
|
||||||
/* handle the reply (request) coming back */
|
/* handle the reply (request) coming back */
|
||||||
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_I_AM, handler_i_am_add);
|
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_I_AM, handler_i_am_add);
|
||||||
/* handle any errors coming back */
|
/* handle any errors coming back */
|
||||||
@@ -96,7 +96,7 @@ static void Init_Service_Handlers(void)
|
|||||||
static void print_usage(char *filename)
|
static void print_usage(char *filename)
|
||||||
{
|
{
|
||||||
printf("Usage: %s [device-instance vendor-id max-apdu segmentation]\n",
|
printf("Usage: %s [device-instance vendor-id max-apdu segmentation]\n",
|
||||||
filename);
|
filename);
|
||||||
printf(" [--dnet][--dadr][--mac]\n");
|
printf(" [--dnet][--dadr][--mac]\n");
|
||||||
printf(" [--version][--help]\n");
|
printf(" [--version][--help]\n");
|
||||||
}
|
}
|
||||||
@@ -104,25 +104,24 @@ static void print_usage(char *filename)
|
|||||||
static void print_help(char *filename)
|
static void print_help(char *filename)
|
||||||
{
|
{
|
||||||
printf("Send BACnet I-Am message for a device.\n");
|
printf("Send BACnet I-Am message for a device.\n");
|
||||||
printf(
|
printf("--mac A\n"
|
||||||
"--mac A\n"
|
"Optional BACnet mac address."
|
||||||
"Optional BACnet mac address."
|
"Valid ranges are from 00 to FF (hex) for MS/TP or ARCNET,\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 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"
|
||||||
"or an Ethernet MAC in hex like 00:21:70:7e:32:bb\n"
|
"\n"
|
||||||
"\n"
|
"--dnet N\n"
|
||||||
"--dnet N\n"
|
"Optional BACnet network number N for directed requests.\n"
|
||||||
"Optional BACnet network number N for directed requests.\n"
|
"Valid range is from 0 to 65535 where 0 is the local connection\n"
|
||||||
"Valid range is from 0 to 65535 where 0 is the local connection\n"
|
"and 65535 is network broadcast.\n"
|
||||||
"and 65535 is network broadcast.\n"
|
"\n"
|
||||||
"\n"
|
"--dadr A\n"
|
||||||
"--dadr A\n"
|
"Optional BACnet mac address on the destination BACnet network "
|
||||||
"Optional BACnet mac address on the destination BACnet network "
|
"number.\n"
|
||||||
"number.\n"
|
"Valid ranges are from 00 to FF (hex) for MS/TP or ARCNET,\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 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"
|
||||||
"or an Ethernet MAC in hex like 00:21:70:7e:32:bb\n"
|
"\n");
|
||||||
"\n");
|
|
||||||
printf(
|
printf(
|
||||||
"device-instance:\n"
|
"device-instance:\n"
|
||||||
" BACnet device-ID 0..4194303\n"
|
" BACnet device-ID 0..4194303\n"
|
||||||
@@ -140,9 +139,9 @@ static void print_help(char *filename)
|
|||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
long dnet = -1;
|
long dnet = -1;
|
||||||
BACNET_MAC_ADDRESS mac = {0};
|
BACNET_MAC_ADDRESS mac = { 0 };
|
||||||
BACNET_MAC_ADDRESS adr = {0};
|
BACNET_MAC_ADDRESS adr = { 0 };
|
||||||
BACNET_ADDRESS dest = {0};
|
BACNET_ADDRESS dest = { 0 };
|
||||||
bool specific_address = false;
|
bool specific_address = false;
|
||||||
int argi = 0;
|
int argi = 0;
|
||||||
unsigned int target_args = 0;
|
unsigned int target_args = 0;
|
||||||
@@ -157,12 +156,11 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
if (strcmp(argv[argi], "--version") == 0) {
|
if (strcmp(argv[argi], "--version") == 0) {
|
||||||
printf("%s %s\n", filename, BACNET_VERSION_TEXT);
|
printf("%s %s\n", filename, BACNET_VERSION_TEXT);
|
||||||
printf(
|
printf("Copyright (C) 2016 by Steve Karg and others.\n"
|
||||||
"Copyright (C) 2016 by Steve Karg and others.\n"
|
"This is free software; see the source for copying "
|
||||||
"This is free software; see the source for copying "
|
"conditions.\n"
|
||||||
"conditions.\n"
|
"There is NO warranty; not even for MERCHANTABILITY or\n"
|
||||||
"There is NO warranty; not even for MERCHANTABILITY or\n"
|
"FITNESS FOR A PARTICULAR PURPOSE.\n");
|
||||||
"FITNESS FOR A PARTICULAR PURPOSE.\n");
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (strcmp(argv[argi], "--mac") == 0) {
|
if (strcmp(argv[argi], "--mac") == 0) {
|
||||||
@@ -242,7 +240,7 @@ int main(int argc, char *argv[])
|
|||||||
atexit(datalink_cleanup);
|
atexit(datalink_cleanup);
|
||||||
/* send the request */
|
/* send the request */
|
||||||
Send_I_Am_To_Network(&dest, Target_Device_ID, Target_Max_APDU,
|
Send_I_Am_To_Network(&dest, Target_Device_ID, Target_Max_APDU,
|
||||||
Target_Segmentation, Target_Vendor_ID);
|
Target_Segmentation, Target_Vendor_ID);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -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
|
||||||
|
|
||||||
@@ -30,31 +30,31 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <time.h> /* for time */
|
#include <time.h> /* for time */
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include "bactext.h"
|
#include "bacnet/bactext.h"
|
||||||
#include "iam.h"
|
#include "bacnet/iam.h"
|
||||||
#include "address.h"
|
#include "bacnet/basic/binding/address.h"
|
||||||
#include "config.h"
|
#include "bacnet/config.h"
|
||||||
#include "bacdef.h"
|
#include "bacnet/bacdef.h"
|
||||||
#include "npdu.h"
|
#include "bacnet/npdu.h"
|
||||||
#include "apdu.h"
|
#include "bacnet/apdu.h"
|
||||||
#include "device.h"
|
#include "bacnet/basic/object/device.h"
|
||||||
#include "datalink.h"
|
#include "bacnet/datalink/datalink.h"
|
||||||
#include "version.h"
|
#include "bacnet/version.h"
|
||||||
/* some demo stuff needed */
|
/* some demo stuff needed */
|
||||||
#include "filename.h"
|
#include "bacnet/basic/sys/filename.h"
|
||||||
#include "handlers.h"
|
#include "bacnet/basic/services.h"
|
||||||
#include "client.h"
|
#include "bacnet/basic/services.h"
|
||||||
#include "txbuf.h"
|
#include "bacnet/basic/tsm/tsm.h"
|
||||||
#include "dlenv.h"
|
#include "bacnet/datalink/dlenv.h"
|
||||||
|
|
||||||
/* global variables used in this file */
|
/* global variables used in this file */
|
||||||
#define MAX_ROUTER_DNETS 64
|
#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;
|
static bool Error_Detected = false;
|
||||||
|
|
||||||
void MyAbortHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
|
static void MyAbortHandler(
|
||||||
uint8_t abort_reason, bool server)
|
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t abort_reason, bool server)
|
||||||
{
|
{
|
||||||
/* FIXME: verify src and invoke id */
|
/* FIXME: verify src and invoke id */
|
||||||
(void)src;
|
(void)src;
|
||||||
@@ -64,8 +64,8 @@ void MyAbortHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
|
|||||||
Error_Detected = true;
|
Error_Detected = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
|
static void MyRejectHandler(
|
||||||
uint8_t reject_reason)
|
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||||
{
|
{
|
||||||
/* FIXME: verify src and invoke id */
|
/* FIXME: verify src and invoke id */
|
||||||
(void)src;
|
(void)src;
|
||||||
@@ -84,8 +84,8 @@ static void Init_Service_Handlers(void)
|
|||||||
It is required to send the proper reject message... */
|
It is required to send the proper reject message... */
|
||||||
apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service);
|
apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service);
|
||||||
/* we must implement read property - it's required! */
|
/* we must implement read property - it's required! */
|
||||||
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY,
|
apdu_set_confirmed_handler(
|
||||||
handler_read_property);
|
SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property);
|
||||||
/* handle the reply (request) coming back */
|
/* handle the reply (request) coming back */
|
||||||
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_I_AM, handler_i_am_add);
|
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_I_AM, handler_i_am_add);
|
||||||
/* handle any errors coming back */
|
/* handle any errors coming back */
|
||||||
@@ -101,16 +101,15 @@ static void print_usage(char *filename)
|
|||||||
|
|
||||||
static void print_help(char *filename)
|
static void print_help(char *filename)
|
||||||
{
|
{
|
||||||
printf(
|
printf("Send BACnet I-Am-Router-To-Network message for \n"
|
||||||
"Send BACnet I-Am-Router-To-Network message for \n"
|
"one or more networks.\n"
|
||||||
"one or more networks.\n"
|
"\nDNET:\n"
|
||||||
"\nDNET:\n"
|
"BACnet destination network number 0-65534\n"
|
||||||
"BACnet destination network number 0-65534\n"
|
"To send a I-Am-Router-To-Network message for DNET 86:\n"
|
||||||
"To send a I-Am-Router-To-Network message for DNET 86:\n"
|
"%s 86\n"
|
||||||
"%s 86\n"
|
"To send a I-Am-Router-To-Network message for multiple DNETs\n"
|
||||||
"To send a I-Am-Router-To-Network message for multiple DNETs\n"
|
"use the following command:\n"
|
||||||
"use the following command:\n"
|
"%s 86 42 24 14\n",
|
||||||
"%s 86 42 24 14\n",
|
|
||||||
filename, filename);
|
filename, filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -129,12 +128,11 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
if (strcmp(argv[argi], "--version") == 0) {
|
if (strcmp(argv[argi], "--version") == 0) {
|
||||||
printf("%s %s\n", filename, BACNET_VERSION_TEXT);
|
printf("%s %s\n", filename, BACNET_VERSION_TEXT);
|
||||||
printf(
|
printf("Copyright (C) 2014 by Steve Karg and others.\n"
|
||||||
"Copyright (C) 2014 by Steve Karg and others.\n"
|
"This is free software; see the source for copying "
|
||||||
"This is free software; see the source for copying "
|
"conditions.\n"
|
||||||
"conditions.\n"
|
"There is NO warranty; not even for MERCHANTABILITY or\n"
|
||||||
"There is NO warranty; not even for MERCHANTABILITY or\n"
|
"FITNESS FOR A PARTICULAR PURPOSE.\n");
|
||||||
"FITNESS FOR A PARTICULAR PURPOSE.\n");
|
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -146,8 +144,8 @@ int main(int argc, char *argv[])
|
|||||||
if (argc > 1) {
|
if (argc > 1) {
|
||||||
for (arg_count = 1; arg_count < argc; arg_count++) {
|
for (arg_count = 1; arg_count < argc; arg_count++) {
|
||||||
if (arg_count > MAX_ROUTER_DNETS) {
|
if (arg_count > MAX_ROUTER_DNETS) {
|
||||||
fprintf(stderr, "Limited to %u DNETS. Sorry!\n",
|
fprintf(
|
||||||
MAX_ROUTER_DNETS);
|
stderr, "Limited to %u DNETS. Sorry!\n", MAX_ROUTER_DNETS);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
Target_Router_Networks[arg_count - 1] =
|
Target_Router_Networks[arg_count - 1] =
|
||||||
@@ -157,7 +155,7 @@ int main(int argc, char *argv[])
|
|||||||
/* invalid DNET? */
|
/* invalid DNET? */
|
||||||
if (Target_Router_Networks[arg_count - 1] >= 65535) {
|
if (Target_Router_Networks[arg_count - 1] >= 65535) {
|
||||||
fprintf(stderr, "DNET=%u - it must be less than %u\n",
|
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;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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
|
||||||
|
|
||||||
@@ -30,29 +30,29 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <time.h> /* for time */
|
#include <time.h> /* for time */
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include "bactext.h"
|
#include "bacnet/bactext.h"
|
||||||
#include "iam.h"
|
#include "bacnet/iam.h"
|
||||||
#include "address.h"
|
#include "bacnet/basic/binding/address.h"
|
||||||
#include "config.h"
|
#include "bacnet/config.h"
|
||||||
#include "bacdef.h"
|
#include "bacnet/bacdef.h"
|
||||||
#include "npdu.h"
|
#include "bacnet/npdu.h"
|
||||||
#include "apdu.h"
|
#include "bacnet/apdu.h"
|
||||||
#include "device.h"
|
#include "bacnet/basic/object/device.h"
|
||||||
#include "datalink.h"
|
#include "bacnet/datalink/datalink.h"
|
||||||
#include "version.h"
|
#include "bacnet/version.h"
|
||||||
/* some demo stuff needed */
|
/* some demo stuff needed */
|
||||||
#ifndef DEBUG_ENABLED
|
#ifndef DEBUG_ENABLED
|
||||||
#define DEBUG_ENABLED 0
|
#define DEBUG_ENABLED 0
|
||||||
#endif
|
#endif
|
||||||
#include "debug.h"
|
#include "bacnet/basic/sys/debug.h"
|
||||||
#include "filename.h"
|
#include "bacnet/basic/sys/filename.h"
|
||||||
#include "handlers.h"
|
#include "bacnet/basic/services.h"
|
||||||
#include "client.h"
|
#include "bacnet/basic/services.h"
|
||||||
#include "txbuf.h"
|
#include "bacnet/basic/tsm/tsm.h"
|
||||||
#include "dlenv.h"
|
#include "bacnet/datalink/dlenv.h"
|
||||||
|
|
||||||
/* buffer used for receive */
|
/* buffer used for receive */
|
||||||
static uint8_t Rx_Buf[MAX_MPDU] = {0};
|
static uint8_t Rx_Buf[MAX_MPDU] = { 0 };
|
||||||
|
|
||||||
/* target address */
|
/* target address */
|
||||||
static BACNET_ADDRESS Target_Router_Address;
|
static BACNET_ADDRESS Target_Router_Address;
|
||||||
@@ -68,8 +68,8 @@ int DNET_list[2] = {
|
|||||||
|
|
||||||
static bool Error_Detected = false;
|
static bool Error_Detected = false;
|
||||||
|
|
||||||
static void MyAbortHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
|
static void MyAbortHandler(
|
||||||
uint8_t abort_reason, bool server)
|
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t abort_reason, bool server)
|
||||||
{
|
{
|
||||||
/* FIXME: verify src and invoke id */
|
/* FIXME: verify src and invoke id */
|
||||||
(void)src;
|
(void)src;
|
||||||
@@ -79,8 +79,8 @@ static void MyAbortHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
|
|||||||
Error_Detected = true;
|
Error_Detected = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
|
static void MyRejectHandler(
|
||||||
uint8_t reject_reason)
|
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||||
{
|
{
|
||||||
/* FIXME: verify src and invoke id */
|
/* FIXME: verify src and invoke id */
|
||||||
(void)src;
|
(void)src;
|
||||||
@@ -89,9 +89,10 @@ static void MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
|
|||||||
Error_Detected = true;
|
Error_Detected = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void My_Router_Handler(BACNET_ADDRESS *src, BACNET_NPDU_DATA *npdu_data,
|
static void My_Router_Handler(BACNET_ADDRESS *src,
|
||||||
uint8_t *npdu, /* PDU data */
|
BACNET_NPDU_DATA *npdu_data,
|
||||||
uint16_t npdu_len)
|
uint8_t *npdu, /* PDU data */
|
||||||
|
uint16_t npdu_len)
|
||||||
{
|
{
|
||||||
uint16_t npdu_offset = 0;
|
uint16_t npdu_offset = 0;
|
||||||
uint16_t dnet = 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 */
|
static void My_NPDU_Handler(BACNET_ADDRESS *src, /* source address */
|
||||||
uint8_t *pdu, /* PDU data */
|
uint8_t *pdu, /* PDU data */
|
||||||
uint16_t pdu_len)
|
uint16_t pdu_len)
|
||||||
{ /* length PDU */
|
{ /* length PDU */
|
||||||
int apdu_offset = 0;
|
int apdu_offset = 0;
|
||||||
BACNET_ADDRESS dest = {0};
|
BACNET_ADDRESS dest = { 0 };
|
||||||
BACNET_NPDU_DATA npdu_data = {0};
|
BACNET_NPDU_DATA npdu_data = { 0 };
|
||||||
|
|
||||||
apdu_offset = npdu_decode(&pdu[0], &dest, src, &npdu_data);
|
apdu_offset = npdu_decode(&pdu[0], &dest, src, &npdu_data);
|
||||||
if (npdu_data.network_layer_message) {
|
if (npdu_data.network_layer_message) {
|
||||||
if (apdu_offset <= pdu_len) {
|
if (apdu_offset <= pdu_len) {
|
||||||
My_Router_Handler(src, &npdu_data, &pdu[apdu_offset],
|
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)) {
|
} else if ((apdu_offset > 0) && (apdu_offset <= pdu_len)) {
|
||||||
if ((npdu_data.protocol_version == BACNET_PROTOCOL_VERSION) &&
|
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 */
|
/* only handle the version that we know how to handle */
|
||||||
/* and we are not a router, so ignore messages with
|
/* and we are not a router, so ignore messages with
|
||||||
routing information cause they are not for us */
|
routing information cause they are not for us */
|
||||||
apdu_handler(src, &pdu[apdu_offset],
|
apdu_handler(
|
||||||
(uint16_t)(pdu_len - apdu_offset));
|
src, &pdu[apdu_offset], (uint16_t)(pdu_len - apdu_offset));
|
||||||
} else {
|
} else {
|
||||||
if (dest.net) {
|
if (dest.net) {
|
||||||
debug_printf("NPDU: DNET=%d. Discarded!\n", dest.net);
|
debug_printf("NPDU: DNET=%d. Discarded!\n", dest.net);
|
||||||
} else {
|
} else {
|
||||||
debug_printf("NPDU: BACnet Protocol Version=%d. Discarded!\n",
|
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... */
|
It is required to send the proper reject message... */
|
||||||
apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service);
|
apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service);
|
||||||
/* we must implement read property - it's required! */
|
/* we must implement read property - it's required! */
|
||||||
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY,
|
apdu_set_confirmed_handler(
|
||||||
handler_read_property);
|
SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property);
|
||||||
/* handle the reply (request) coming back */
|
/* handle the reply (request) coming back */
|
||||||
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_I_AM, handler_i_am_add);
|
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_I_AM, handler_i_am_add);
|
||||||
/* handle any errors coming back */
|
/* handle any errors coming back */
|
||||||
@@ -267,7 +268,7 @@ static void address_parse(BACNET_ADDRESS *dst, int argc, char *argv[])
|
|||||||
|
|
||||||
if (argc > 0) {
|
if (argc > 0) {
|
||||||
count = sscanf(argv[0], "%u.%u.%u.%u:%u", &mac[0], &mac[1], &mac[2],
|
count = sscanf(argv[0], "%u.%u.%u.%u:%u", &mac[0], &mac[1], &mac[2],
|
||||||
&mac[3], &port);
|
&mac[3], &port);
|
||||||
if (count == 5) {
|
if (count == 5) {
|
||||||
dst->mac_len = 6;
|
dst->mac_len = 6;
|
||||||
for (index = 0; index < 4; index++) {
|
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);
|
encode_unsigned16(&dst->mac[4], port);
|
||||||
} else {
|
} else {
|
||||||
count = sscanf(argv[0], "%x:%x:%x:%x:%x:%x", &mac[0], &mac[1],
|
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;
|
dst->mac_len = count;
|
||||||
for (index = 0; index < MAX_MAC_LEN; index++) {
|
for (index = 0; index < MAX_MAC_LEN; index++) {
|
||||||
if (index < count) {
|
if (index < count) {
|
||||||
@@ -296,7 +297,7 @@ static void address_parse(BACNET_ADDRESS *dst, int argc, char *argv[])
|
|||||||
|
|
||||||
int main(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;
|
uint16_t pdu_len = 0;
|
||||||
unsigned timeout = 100; /* milliseconds */
|
unsigned timeout = 100; /* milliseconds */
|
||||||
time_t total_seconds = 0;
|
time_t total_seconds = 0;
|
||||||
@@ -316,12 +317,11 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
if (strcmp(argv[argi], "--version") == 0) {
|
if (strcmp(argv[argi], "--version") == 0) {
|
||||||
printf("%s %s\n", filename, BACNET_VERSION_TEXT);
|
printf("%s %s\n", filename, BACNET_VERSION_TEXT);
|
||||||
printf(
|
printf("Copyright (C) 2014 by Steve Karg and others.\n"
|
||||||
"Copyright (C) 2014 by Steve Karg and others.\n"
|
"This is free software; see the source for copying "
|
||||||
"This is free software; see the source for copying "
|
"conditions.\n"
|
||||||
"conditions.\n"
|
"There is NO warranty; not even for MERCHANTABILITY or\n"
|
||||||
"There is NO warranty; not even for MERCHANTABILITY or\n"
|
"FITNESS FOR A PARTICULAR PURPOSE.\n");
|
||||||
"FITNESS FOR A PARTICULAR PURPOSE.\n");
|
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -373,8 +373,9 @@ int main(int argc, char *argv[])
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
total_seconds += elapsed_seconds;
|
total_seconds += elapsed_seconds;
|
||||||
if (total_seconds > timeout_seconds)
|
if (total_seconds > timeout_seconds) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
/* keep track of time for next check */
|
/* keep track of time for next check */
|
||||||
last_seconds = current_seconds;
|
last_seconds = current_seconds;
|
||||||
}
|
}
|
||||||
@@ -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
|
||||||
@@ -39,19 +39,18 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
/* OS specific include*/
|
#include "bacnet/bytes.h"
|
||||||
#include "net.h"
|
#include "bacnet/iam.h"
|
||||||
#include "timer.h"
|
#include "bacnet/version.h"
|
||||||
/* local includes */
|
/* basic datalink, timer, and filename */
|
||||||
#include "bytes.h"
|
#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 "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
|
#ifdef _WIN32
|
||||||
#define strncasecmp(x, y, z) _strnicmp(x, y, z)
|
#define strncasecmp(x, y, z) _strnicmp(x, y, z)
|
||||||
@@ -78,6 +77,8 @@ static uint8_t TxBuffer[MAX_MPDU];
|
|||||||
static volatile bool Exit_Requested;
|
static volatile bool Exit_Requested;
|
||||||
/* flag to indicate Wireshark is running the show - no stdout or stderr */
|
/* flag to indicate Wireshark is running the show - no stdout or stderr */
|
||||||
static bool Wireshark_Capture;
|
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 */
|
/* statistics derived from monitoring the network for each node */
|
||||||
struct mstp_statistics {
|
struct mstp_statistics {
|
||||||
@@ -139,16 +140,16 @@ static uint32_t timeval_diff_ms(struct timeval *old, struct timeval *now)
|
|||||||
|
|
||||||
/* convert to milliseconds */
|
/* convert to milliseconds */
|
||||||
ms = (now->tv_sec - old->tv_sec) * 1000 +
|
ms = (now->tv_sec - old->tv_sec) * 1000 +
|
||||||
(now->tv_usec - old->tv_usec) / 1000;
|
(now->tv_usec - old->tv_usec) / 1000;
|
||||||
|
|
||||||
return ms;
|
return ms;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mstp_monitor_i_am(uint8_t mac, uint8_t *pdu, uint16_t pdu_len)
|
static void mstp_monitor_i_am(uint8_t mac, uint8_t *pdu, uint16_t pdu_len)
|
||||||
{
|
{
|
||||||
BACNET_ADDRESS src = {0};
|
BACNET_ADDRESS src = { 0 };
|
||||||
BACNET_ADDRESS dest = {0};
|
BACNET_ADDRESS dest = { 0 };
|
||||||
BACNET_NPDU_DATA npdu_data = {0};
|
BACNET_NPDU_DATA npdu_data = { 0 };
|
||||||
int apdu_offset = 0;
|
int apdu_offset = 0;
|
||||||
uint16_t apdu_len = 0;
|
uint16_t apdu_len = 0;
|
||||||
uint8_t *apdu = NULL;
|
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,
|
static void packet_statistics(
|
||||||
volatile struct mstp_port_struct_t *mstp_port)
|
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_frame = 255;
|
||||||
static uint8_t old_src = 255;
|
static uint8_t old_src = 255;
|
||||||
static uint8_t old_dst = 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) &&
|
} else if ((old_frame == FRAME_TYPE_POLL_FOR_MASTER) &&
|
||||||
(old_src == src)) {
|
(old_src == src)) {
|
||||||
/* Tusage_timeout */
|
/* Tusage_timeout */
|
||||||
delta = timeval_diff_ms(&old_tv, tv);
|
delta = timeval_diff_ms(&old_tv, tv);
|
||||||
if (delta > MSTP_Statistics[src].tusage_timeout) {
|
if (delta > MSTP_Statistics[src].tusage_timeout) {
|
||||||
@@ -237,7 +238,7 @@ static void packet_statistics(struct timeval *tv,
|
|||||||
case FRAME_TYPE_POLL_FOR_MASTER:
|
case FRAME_TYPE_POLL_FOR_MASTER:
|
||||||
if (MSTP_Statistics[src].last_pfm_tokens) {
|
if (MSTP_Statistics[src].last_pfm_tokens) {
|
||||||
npoll = MSTP_Statistics[src].token_received_count -
|
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) {
|
if (npoll > MSTP_Statistics[src].npoll) {
|
||||||
MSTP_Statistics[src].npoll = npoll;
|
MSTP_Statistics[src].npoll = npoll;
|
||||||
}
|
}
|
||||||
@@ -288,8 +289,8 @@ static void packet_statistics(struct timeval *tv,
|
|||||||
(mstp_port->ReceivedValidFrameNotForUs)) {
|
(mstp_port->ReceivedValidFrameNotForUs)) {
|
||||||
if ((mstp_port->DataLength <= mstp_port->InputBufferSize) &&
|
if ((mstp_port->DataLength <= mstp_port->InputBufferSize) &&
|
||||||
(mstp_port->DataLength > 0)) {
|
(mstp_port->DataLength > 0)) {
|
||||||
mstp_monitor_i_am(src, &mstp_port->InputBuffer[0],
|
mstp_monitor_i_am(
|
||||||
mstp_port->DataLength);
|
src, &mstp_port->InputBuffer[0], mstp_port->DataLength);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -325,8 +326,7 @@ static void packet_statistics_print(void)
|
|||||||
fprintf(stdout, "\n");
|
fprintf(stdout, "\n");
|
||||||
fprintf(stdout, "==== MS/TP Frame Counts ====\n");
|
fprintf(stdout, "==== MS/TP Frame Counts ====\n");
|
||||||
fprintf(stdout, "%-8s%-8s%-8s%-8s%-8s%-8s%-8s%-8s%-8s%-7s", "MAC", "Device",
|
fprintf(stdout, "%-8s%-8s%-8s%-8s%-8s%-8s%-8s%-8s%-8s%-7s", "MAC", "Device",
|
||||||
"Tokens", "PFM", "RPFM", "DER", "Postpd", "DNER", "TestReq",
|
"Tokens", "PFM", "RPFM", "DER", "Postpd", "DNER", "TestReq", "TestRsp");
|
||||||
"TestRsp");
|
|
||||||
fprintf(stdout, "\n");
|
fprintf(stdout, "\n");
|
||||||
for (i = 0; i < MAX_MSTP_DEVICES; i++) {
|
for (i = 0; i < MAX_MSTP_DEVICES; i++) {
|
||||||
/* check for masters or slaves */
|
/* check for masters or slaves */
|
||||||
@@ -336,20 +336,20 @@ static void packet_statistics_print(void)
|
|||||||
fprintf(stdout, "%-8u", i);
|
fprintf(stdout, "%-8u", i);
|
||||||
if (MSTP_Statistics[i].device_id <= 4194303) {
|
if (MSTP_Statistics[i].device_id <= 4194303) {
|
||||||
fprintf(stdout, "%-8lu",
|
fprintf(stdout, "%-8lu",
|
||||||
(long unsigned int)MSTP_Statistics[i].device_id);
|
(long unsigned int)MSTP_Statistics[i].device_id);
|
||||||
} else {
|
} else {
|
||||||
fprintf(stdout, "%-8s", "-");
|
fprintf(stdout, "%-8s", "-");
|
||||||
}
|
}
|
||||||
fprintf(stdout, "%-8lu%-8lu%-8lu%-8lu",
|
fprintf(stdout, "%-8lu%-8lu%-8lu%-8lu",
|
||||||
(long unsigned int)MSTP_Statistics[i].token_count,
|
(long unsigned int)MSTP_Statistics[i].token_count,
|
||||||
(long unsigned int)MSTP_Statistics[i].pfm_count,
|
(long unsigned int)MSTP_Statistics[i].pfm_count,
|
||||||
(long unsigned int)MSTP_Statistics[i].rpfm_count,
|
(long unsigned int)MSTP_Statistics[i].rpfm_count,
|
||||||
(long unsigned int)MSTP_Statistics[i].der_count);
|
(long unsigned int)MSTP_Statistics[i].der_count);
|
||||||
fprintf(stdout, "%-8lu%-8lu%-8lu%-7lu",
|
fprintf(stdout, "%-8lu%-8lu%-8lu%-7lu",
|
||||||
(long unsigned int)MSTP_Statistics[i].reply_postponed_count,
|
(long unsigned int)MSTP_Statistics[i].reply_postponed_count,
|
||||||
(long unsigned int)MSTP_Statistics[i].dner_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_request_count,
|
||||||
(long unsigned int)MSTP_Statistics[i].test_response_count);
|
(long unsigned int)MSTP_Statistics[i].test_response_count);
|
||||||
fprintf(stdout, "\n");
|
fprintf(stdout, "\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -358,8 +358,8 @@ static void packet_statistics_print(void)
|
|||||||
fprintf(stdout, "\n");
|
fprintf(stdout, "\n");
|
||||||
fprintf(stdout, "==== MS/TP Usage and Timing Maximums ====\n");
|
fprintf(stdout, "==== MS/TP Usage and Timing Maximums ====\n");
|
||||||
fprintf(stdout, "%-8s%-8s%-8s%-8s%-8s%-8s%-8s%-8s%-8s%-7s", "MAC",
|
fprintf(stdout, "%-8s%-8s%-8s%-8s%-8s%-8s%-8s%-8s%-8s%-7s", "MAC",
|
||||||
"MaxMstr", "Retries", "Npoll", "Self/TT", "Treply", "Tusage",
|
"MaxMstr", "Retries", "Npoll", "Self/TT", "Treply", "Tusage", "Trpfm",
|
||||||
"Trpfm", "Tder", "Tpostpd");
|
"Tder", "Tpostpd");
|
||||||
fprintf(stdout, "\n");
|
fprintf(stdout, "\n");
|
||||||
for (i = 0; i < MAX_MSTP_DEVICES; i++) {
|
for (i = 0; i < MAX_MSTP_DEVICES; i++) {
|
||||||
/* check for masters or slaves */
|
/* 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)) {
|
(MSTP_Statistics[i].der_reply) || (MSTP_Statistics[i].pfm_count)) {
|
||||||
node_count++;
|
node_count++;
|
||||||
self_or_ooo_count = MSTP_Statistics[i].self_token_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, "%-8u", i);
|
||||||
fprintf(stdout, "%-8lu%-8lu%-8lu%-8lu%-8lu",
|
fprintf(stdout, "%-8lu%-8lu%-8lu%-8lu%-8lu",
|
||||||
(long unsigned int)MSTP_Statistics[i].max_master,
|
(long unsigned int)MSTP_Statistics[i].max_master,
|
||||||
(long unsigned int)MSTP_Statistics[i].token_retries,
|
(long unsigned int)MSTP_Statistics[i].token_retries,
|
||||||
(long unsigned int)MSTP_Statistics[i].npoll,
|
(long unsigned int)MSTP_Statistics[i].npoll, self_or_ooo_count,
|
||||||
self_or_ooo_count,
|
(long unsigned int)MSTP_Statistics[i].token_reply);
|
||||||
(long unsigned int)MSTP_Statistics[i].token_reply);
|
|
||||||
fprintf(stdout, "%-8lu%-8lu%-8lu%-7lu",
|
fprintf(stdout, "%-8lu%-8lu%-8lu%-7lu",
|
||||||
(long unsigned int)MSTP_Statistics[i].tusage_timeout,
|
(long unsigned int)MSTP_Statistics[i].tusage_timeout,
|
||||||
(long unsigned int)MSTP_Statistics[i].pfm_reply,
|
(long unsigned int)MSTP_Statistics[i].pfm_reply,
|
||||||
(long unsigned int)MSTP_Statistics[i].der_reply,
|
(long unsigned int)MSTP_Statistics[i].der_reply,
|
||||||
(long unsigned int)MSTP_Statistics[i].reply_postponed);
|
(long unsigned int)MSTP_Statistics[i].reply_postponed);
|
||||||
fprintf(stdout, "\n");
|
fprintf(stdout, "\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fprintf(stdout, "Node Count: %u\n", node_count);
|
fprintf(stdout, "Node Count: %u\n", node_count);
|
||||||
fprintf(stdout, "Invalid Frame Count: %lu\n",
|
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)
|
static void packet_statistics_clear(void)
|
||||||
@@ -401,12 +400,12 @@ static void packet_statistics_clear(void)
|
|||||||
|
|
||||||
static uint32_t Timer_Silence(void *pArg)
|
static uint32_t Timer_Silence(void *pArg)
|
||||||
{
|
{
|
||||||
return timer_milliseconds(TIMER_SILENCE);
|
return mstimer_remaining(&Silence_Timer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Timer_Silence_Reset(void *pArg)
|
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 */
|
/* 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 */
|
/* for the MS/TP state machine to use for getting data to send */
|
||||||
/* Return: amount of PDU data */
|
/* Return: amount of PDU data */
|
||||||
uint16_t MSTP_Get_Send(volatile struct mstp_port_struct_t *mstp_port,
|
uint16_t MSTP_Get_Send(
|
||||||
unsigned timeout)
|
volatile struct mstp_port_struct_t *mstp_port, unsigned timeout)
|
||||||
{ /* milliseconds to wait for a packet */
|
{ /* milliseconds to wait for a packet */
|
||||||
(void)mstp_port;
|
(void)mstp_port;
|
||||||
(void)timeout;
|
(void)timeout;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t MSTP_Get_Reply(volatile struct mstp_port_struct_t *mstp_port,
|
uint16_t MSTP_Get_Reply(
|
||||||
unsigned timeout)
|
volatile struct mstp_port_struct_t *mstp_port, unsigned timeout)
|
||||||
{ /* milliseconds to wait for a packet */
|
{ /* milliseconds to wait for a packet */
|
||||||
(void)mstp_port;
|
(void)mstp_port;
|
||||||
(void)timeout;
|
(void)timeout;
|
||||||
@@ -448,16 +447,15 @@ static void named_pipe_create(char *pipe_name)
|
|||||||
while (hPipe == INVALID_HANDLE_VALUE) {
|
while (hPipe == INVALID_HANDLE_VALUE) {
|
||||||
/* use CreateFile rather than CreateNamedPipe */
|
/* use CreateFile rather than CreateNamedPipe */
|
||||||
hPipe = CreateFile(pipe_name, GENERIC_READ | GENERIC_WRITE, 0, NULL,
|
hPipe = CreateFile(pipe_name, GENERIC_READ | GENERIC_WRITE, 0, NULL,
|
||||||
OPEN_EXISTING, 0, NULL);
|
OPEN_EXISTING, 0, NULL);
|
||||||
if (hPipe != INVALID_HANDLE_VALUE) {
|
if (hPipe != INVALID_HANDLE_VALUE) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* if an error occured at handle creation */
|
/* if an error occured at handle creation */
|
||||||
if (!WaitNamedPipe(pipe_name, 20000)) {
|
if (!WaitNamedPipe(pipe_name, 20000)) {
|
||||||
printf(
|
printf("Could not open pipe: waited for 20sec!\n"
|
||||||
"Could not open pipe: waited for 20sec!\n"
|
"If this message was issued before the 20sec finished,\n"
|
||||||
"If this message was issued before the 20sec finished,\n"
|
"then the pipe doesn't exist!\n");
|
||||||
"then the pipe doesn't exist!\n");
|
|
||||||
Exit_Requested = true;
|
Exit_Requested = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -465,30 +463,30 @@ static void named_pipe_create(char *pipe_name)
|
|||||||
ConnectNamedPipe(hPipe, NULL);
|
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;
|
DWORD cbWritten = 0;
|
||||||
if (hPipe != INVALID_HANDLE_VALUE) {
|
if (hPipe != INVALID_HANDLE_VALUE) {
|
||||||
(void)WriteFile(hPipe, /* handle to pipe */
|
(void)WriteFile(hPipe, /* handle to pipe */
|
||||||
ptr, /* buffer to write from */
|
ptr, /* buffer to write from */
|
||||||
size * nitems, /* number of bytes to write */
|
size * nitems, /* number of bytes to write */
|
||||||
&cbWritten, /* number of bytes written */
|
&cbWritten, /* number of bytes written */
|
||||||
NULL); /* not overlapped I/O */
|
NULL); /* not overlapped I/O */
|
||||||
}
|
}
|
||||||
|
|
||||||
return fwrite(ptr, size, nitems, pFile);
|
return fwrite(ptr, size, nitems, pFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t data_write_header(const void *ptr, size_t size, size_t nitems,
|
static size_t data_write_header(
|
||||||
bool pipe_enable)
|
const void *ptr, size_t size, size_t nitems, bool pipe_enable)
|
||||||
{
|
{
|
||||||
DWORD cbWritten = 0;
|
DWORD cbWritten = 0;
|
||||||
if (pipe_enable && (hPipe != INVALID_HANDLE_VALUE)) {
|
if (pipe_enable && (hPipe != INVALID_HANDLE_VALUE)) {
|
||||||
(void)WriteFile(hPipe, /* handle to pipe */
|
(void)WriteFile(hPipe, /* handle to pipe */
|
||||||
ptr, /* buffer to write from */
|
ptr, /* buffer to write from */
|
||||||
size * nitems, /* number of bytes to write */
|
size * nitems, /* number of bytes to write */
|
||||||
&cbWritten, /* number of bytes written */
|
&cbWritten, /* number of bytes written */
|
||||||
NULL); /* not overlapped I/O */
|
NULL); /* not overlapped I/O */
|
||||||
}
|
}
|
||||||
|
|
||||||
return fwrite(ptr, size, nitems, pFile);
|
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;
|
ssize_t bytes = 0;
|
||||||
if (FD_Pipe != -1) {
|
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);
|
return fwrite(ptr, size, nitems, pFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t data_write_header(const void *ptr, size_t size, size_t nitems,
|
static size_t data_write_header(
|
||||||
bool pipe_enable)
|
const void *ptr, size_t size, size_t nitems, bool pipe_enable)
|
||||||
{
|
{
|
||||||
ssize_t bytes = 0;
|
ssize_t bytes = 0;
|
||||||
if (pipe_enable && (FD_Pipe != -1)) {
|
if (pipe_enable && (FD_Pipe != -1)) {
|
||||||
@@ -541,32 +539,32 @@ static void filename_create(char *filename)
|
|||||||
my_time = time(NULL);
|
my_time = time(NULL);
|
||||||
today = localtime(&my_time);
|
today = localtime(&my_time);
|
||||||
sprintf(filename, "mstp_%04d%02d%02d%02d%02d%02d.cap",
|
sprintf(filename, "mstp_%04d%02d%02d%02d%02d%02d.cap",
|
||||||
1900 + today->tm_year, 1 + today->tm_mon, today->tm_mday,
|
1900 + today->tm_year, 1 + today->tm_mon, today->tm_mday,
|
||||||
today->tm_hour, today->tm_min, today->tm_sec);
|
today->tm_hour, today->tm_min, today->tm_sec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* write packet to file in libpcap format */
|
/* write packet to file in libpcap format */
|
||||||
static void write_global_header(const char *filename)
|
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 */
|
uint32_t magic_number = 0xa1b2c3d4; /* magic number */
|
||||||
uint16_t version_major = 2; /* major version number */
|
uint16_t version_major = 2; /* major version number */
|
||||||
uint16_t version_minor = 4; /* minor version number */
|
uint16_t version_minor = 4; /* minor version number */
|
||||||
int32_t thiszone = 0; /* GMT to local correction */
|
int32_t thiszone = 0; /* GMT to local correction */
|
||||||
uint32_t sigfigs = 0; /* accuracy of timestamps */
|
uint32_t sigfigs = 0; /* accuracy of timestamps */
|
||||||
uint32_t snaplen = 65535; /* max length of captured packets, in octets */
|
uint32_t snaplen = 65535; /* max length of captured packets, in octets */
|
||||||
uint32_t network = DLT_BACNET_MS_TP; /* data link type - BACNET_MS_TP */
|
uint32_t network = DLT_BACNET_MS_TP; /* data link type - BACNET_MS_TP */
|
||||||
|
|
||||||
/* create a new file. */
|
/* create a new file. */
|
||||||
pFile = fopen(filename, "wb");
|
pFile = fopen(filename, "wb");
|
||||||
if (pFile) {
|
if (pFile) {
|
||||||
(void)data_write_header(&magic_number, sizeof(magic_number), 1,
|
(void)data_write_header(
|
||||||
pipe_enable);
|
&magic_number, sizeof(magic_number), 1, pipe_enable);
|
||||||
(void)data_write_header(&version_major, sizeof(version_major), 1,
|
(void)data_write_header(
|
||||||
pipe_enable);
|
&version_major, sizeof(version_major), 1, pipe_enable);
|
||||||
(void)data_write_header(&version_minor, sizeof(version_minor), 1,
|
(void)data_write_header(
|
||||||
pipe_enable);
|
&version_minor, sizeof(version_minor), 1, pipe_enable);
|
||||||
(void)data_write_header(&thiszone, sizeof(thiszone), 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(&sigfigs, sizeof(sigfigs), 1, pipe_enable);
|
||||||
(void)data_write_header(&snaplen, sizeof(snaplen), 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 {
|
} else {
|
||||||
fprintf(stderr, "mstpcap[header]: failed to open %s: %s\n", filename,
|
fprintf(stderr, "mstpcap[header]: failed to open %s: %s\n", filename,
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
}
|
}
|
||||||
if (pipe_enable) {
|
if (pipe_enable) {
|
||||||
pipe_enable = false;
|
pipe_enable = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void write_received_packet(volatile struct mstp_port_struct_t *mstp_port,
|
static void write_received_packet(
|
||||||
size_t header_len)
|
volatile struct mstp_port_struct_t *mstp_port, size_t header_len)
|
||||||
{
|
{
|
||||||
uint32_t ts_sec = 0; /* timestamp seconds */
|
uint32_t ts_sec = 0; /* timestamp seconds */
|
||||||
uint32_t ts_usec = 0; /* timestamp microseconds */
|
uint32_t ts_usec = 0; /* timestamp microseconds */
|
||||||
uint32_t incl_len = 0; /* number of octets of packet saved in file */
|
uint32_t incl_len = 0; /* number of octets of packet saved in file */
|
||||||
uint32_t orig_len = 0; /* actual length of packet */
|
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;
|
struct timeval tv;
|
||||||
size_t max_data = 0;
|
size_t max_data = 0;
|
||||||
|
|
||||||
@@ -648,20 +646,20 @@ static void write_received_packet(volatile struct mstp_port_struct_t *mstp_port,
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "mstpcap[packet]: failed to open %s: %s\n",
|
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 */
|
/* read header from file in libpcap format */
|
||||||
static bool test_global_header(const char *filename)
|
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_major = 0; /* major version number */
|
||||||
uint16_t version_minor = 0; /* minor version number */
|
uint16_t version_minor = 0; /* minor version number */
|
||||||
int32_t thiszone = 0; /* GMT to local correction */
|
int32_t thiszone = 0; /* GMT to local correction */
|
||||||
uint32_t sigfigs = 0; /* accuracy of timestamps */
|
uint32_t sigfigs = 0; /* accuracy of timestamps */
|
||||||
uint32_t snaplen = 0; /* max length of captured packets, in octets */
|
uint32_t snaplen = 0; /* max length of captured packets, in octets */
|
||||||
uint32_t network = 0; /* data link type - BACNET_MS_TP */
|
uint32_t network = 0; /* data link type - BACNET_MS_TP */
|
||||||
size_t count = 0;
|
size_t count = 0;
|
||||||
|
|
||||||
/* open existing file. */
|
/* open existing file. */
|
||||||
@@ -718,7 +716,7 @@ static bool test_global_header(const char *filename)
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "mstpcap[scan]: failed to open %s: %s\n", filename,
|
fprintf(stderr, "mstpcap[scan]: failed to open %s: %s\n", filename,
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
return false;
|
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)
|
static bool read_received_packet(volatile struct mstp_port_struct_t *mstp_port)
|
||||||
{
|
{
|
||||||
uint32_t ts_sec = 0; /* timestamp seconds */
|
uint32_t ts_sec = 0; /* timestamp seconds */
|
||||||
uint32_t ts_usec = 0; /* timestamp microseconds */
|
uint32_t ts_usec = 0; /* timestamp microseconds */
|
||||||
uint32_t incl_len = 0; /* number of octets of packet saved in file */
|
uint32_t incl_len = 0; /* number of octets of packet saved in file */
|
||||||
uint32_t orig_len = 0; /* actual length of packet */
|
uint32_t orig_len = 0; /* actual length of packet */
|
||||||
uint8_t header[8] = {0}; /* MS/TP header */
|
uint8_t header[8] = { 0 }; /* MS/TP header */
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
size_t count = 0;
|
size_t count = 0;
|
||||||
unsigned i = 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;
|
mstp_port->DataCRC = 0xFFFF;
|
||||||
for (i = 0; i < mstp_port->DataLength; i++) {
|
for (i = 0; i < mstp_port->DataLength; i++) {
|
||||||
mstp_port->DataCRC = CRC_Calc_Data(mstp_port->InputBuffer[i],
|
mstp_port->DataCRC = CRC_Calc_Data(
|
||||||
mstp_port->DataCRC);
|
mstp_port->InputBuffer[i], mstp_port->DataCRC);
|
||||||
}
|
}
|
||||||
mstp_port->DataCRC =
|
mstp_port->DataCRC =
|
||||||
CRC_Calc_Data(mstp_port->DataCRCActualMSB, 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) {
|
if (mstp_port->ReceivedInvalidFrame) {
|
||||||
Invalid_Frame_Count++;
|
Invalid_Frame_Count++;
|
||||||
} else if ((mstp_port->ReceivedValidFrame) ||
|
} else if ((mstp_port->ReceivedValidFrame) ||
|
||||||
(mstp_port->ReceivedValidFrameNotForUs)) {
|
(mstp_port->ReceivedValidFrameNotForUs)) {
|
||||||
packet_statistics(&tv, mstp_port);
|
packet_statistics(&tv, mstp_port);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -889,7 +887,7 @@ static void sig_int(int signo)
|
|||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void signal_init(void)
|
static void signal_init(void)
|
||||||
{
|
{
|
||||||
signal(SIGINT, sig_int);
|
signal(SIGINT, sig_int);
|
||||||
signal(SIGHUP, sig_int);
|
signal(SIGHUP, sig_int);
|
||||||
@@ -897,7 +895,7 @@ void signal_init(void)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void filename_create_new(void)
|
static void filename_create_new(void)
|
||||||
{
|
{
|
||||||
if (pFile) {
|
if (pFile) {
|
||||||
fclose(pFile);
|
fclose(pFile);
|
||||||
@@ -919,40 +917,37 @@ static void print_usage(char *filename)
|
|||||||
|
|
||||||
static void print_help(char *filename)
|
static void print_help(char *filename)
|
||||||
{
|
{
|
||||||
printf(
|
printf("%s --scan <filename>\n"
|
||||||
"%s --scan <filename>\n"
|
"perform statistic analysis on MS/TP capture file.\n",
|
||||||
"perform statistic analysis on MS/TP capture file.\n",
|
|
||||||
filename);
|
filename);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
printf(
|
printf("Captures MS/TP packets from a serial interface\n"
|
||||||
"Captures MS/TP packets from a serial interface\n"
|
"and saves them to a file. Saves packets in a\n"
|
||||||
"and saves them to a file. Saves packets in a\n"
|
"filename mstp_20090123091200.cap that has data and time.\n"
|
||||||
"filename mstp_20090123091200.cap that has data and time.\n"
|
"After receiving 65535 packets, a new file is created.\n"
|
||||||
"After receiving 65535 packets, a new file is created.\n"
|
"\n"
|
||||||
"\n"
|
"Command line options:\n"
|
||||||
"Command line options:\n"
|
"[--extcap-interface port] - serial interface.\n"
|
||||||
"[--extcap-interface port] - serial interface.\n"
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
" Supported values: COM1, COM2, etc.\n"
|
" Supported values: COM1, COM2, etc.\n"
|
||||||
#else
|
#else
|
||||||
" Supported values: /dev/ttyS0, /dev/ttyUSB0, etc.\n"
|
" Supported values: /dev/ttyS0, /dev/ttyUSB0, etc.\n"
|
||||||
#endif
|
#endif
|
||||||
"[--baud baud] - MS/TP port baud rate.\n"
|
"[--baud baud] - MS/TP port baud rate.\n"
|
||||||
" Supported values: 9600, 19200, 38400, 57600, 76800, 115200.\n"
|
" Supported values: 9600, 19200, 38400, 57600, 76800, 115200.\n"
|
||||||
" Defaults to 38400.\n"
|
" Defaults to 38400.\n"
|
||||||
"[--fifo pipe] - FIFO pipe path and name\n"
|
"[--fifo pipe] - FIFO pipe path and name\n"
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
" Supported values: \\\\.\\pipe\\wireshark\n"
|
" Supported values: \\\\.\\pipe\\wireshark\n"
|
||||||
#else
|
#else
|
||||||
" Supported values: any file name\n"
|
" Supported values: any file name\n"
|
||||||
#endif
|
#endif
|
||||||
" Use that name as the interface name in Wireshark.\n");
|
" Use that name as the interface name in Wireshark.\n");
|
||||||
printf("\n");
|
printf("\n");
|
||||||
printf(
|
printf("%s [--extcap-interfaces][--extcap-dlts][--extcap-config]\n"
|
||||||
"%s [--extcap-interfaces][--extcap-dlts][--extcap-config]\n"
|
"[--capture][--baud baud][--fifo pipe]\n"
|
||||||
"[--capture][--baud baud][--fifo pipe]\n"
|
"[--extcap-interface iface]\n"
|
||||||
"[--extcap-interface iface]\n"
|
"Usage from Wireshark ExtCap interface\n",
|
||||||
"Usage from Wireshark ExtCap interface\n",
|
|
||||||
filename);
|
filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1007,12 +1002,11 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
if (strcmp(argv[argi], "--version") == 0) {
|
if (strcmp(argv[argi], "--version") == 0) {
|
||||||
printf("mstpcap %s\n", BACNET_VERSION_TEXT);
|
printf("mstpcap %s\n", BACNET_VERSION_TEXT);
|
||||||
printf(
|
printf("Copyright (C) 2011-2016 by Steve Karg\n"
|
||||||
"Copyright (C) 2011-2016 by Steve Karg\n"
|
"This is free software; see the source for copying "
|
||||||
"This is free software; see the source for copying "
|
"conditions.\n"
|
||||||
"conditions.\n"
|
"There is NO warranty; not even for MERCHANTABILITY or\n"
|
||||||
"There is NO warranty; not even for MERCHANTABILITY or\n"
|
"FITNESS FOR A PARTICULAR PURPOSE.\n");
|
||||||
"FITNESS FOR A PARTICULAR PURPOSE.\n");
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (strcmp(argv[argi], "--scan") == 0) {
|
if (strcmp(argv[argi], "--scan") == 0) {
|
||||||
@@ -1047,17 +1041,15 @@ int main(int argc, char *argv[])
|
|||||||
printf("An interface must be provided.\n");
|
printf("An interface must be provided.\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
printf(
|
printf("dlt {number=%u}{name=BACnet MS/TP}"
|
||||||
"dlt {number=%u}{name=BACnet MS/TP}"
|
"{display=BACnet MS/TP}\n",
|
||||||
"{display=BACnet MS/TP}\n",
|
|
||||||
DLT_BACNET_MS_TP);
|
DLT_BACNET_MS_TP);
|
||||||
Exit_Requested = true;
|
Exit_Requested = true;
|
||||||
}
|
}
|
||||||
if (strcmp(argv[argi], "--extcap-config") == 0) {
|
if (strcmp(argv[argi], "--extcap-config") == 0) {
|
||||||
printf(
|
printf("arg {number=0}{call=--baud}{display=Baud Rate}"
|
||||||
"arg {number=0}{call=--baud}{display=Baud Rate}"
|
"{tooltip=Serial port baud rate in bits per second}"
|
||||||
"{tooltip=Serial port baud rate in bits per second}"
|
"{type=selector}\n");
|
||||||
"{type=selector}\n");
|
|
||||||
printf("value {arg=0}{value=9600}{display=9600}{default=false}\n");
|
printf("value {arg=0}{value=9600}{display=9600}{default=false}\n");
|
||||||
printf(
|
printf(
|
||||||
"value {arg=0}{value=19200}{display=19200}{default=false}\n");
|
"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) {
|
if (strcmp(argv[argi], "--extcap-interface") == 0) {
|
||||||
argi++;
|
argi++;
|
||||||
if (argi >= argc) {
|
if (argi >= argc) {
|
||||||
printf(
|
printf("An interface must be provided or "
|
||||||
"An interface must be provided or "
|
"the selection must be displayed.\n");
|
||||||
"the selection must be displayed.\n");
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
RS485_Set_Interface(argv[argi]);
|
RS485_Set_Interface(argv[argi]);
|
||||||
@@ -1132,10 +1123,10 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
atexit(cleanup);
|
atexit(cleanup);
|
||||||
RS485_Initialize();
|
RS485_Initialize();
|
||||||
timer_init();
|
mstimer_init();
|
||||||
if (!Wireshark_Capture) {
|
if (!Wireshark_Capture) {
|
||||||
fprintf(stdout, "mstpcap: Using %s for capture at %ld bps.\n",
|
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)
|
#if defined(_WIN32)
|
||||||
SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), ENABLE_PROCESSED_INPUT);
|
SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), ENABLE_PROCESSED_INPUT);
|
||||||
@@ -1191,7 +1182,7 @@ int main(int argc, char *argv[])
|
|||||||
if (!Wireshark_Capture) {
|
if (!Wireshark_Capture) {
|
||||||
if (!(packet_count % 100)) {
|
if (!(packet_count % 100)) {
|
||||||
fprintf(stdout, "\r%hu packets, %hu invalid frames",
|
fprintf(stdout, "\r%hu packets, %hu invalid frames",
|
||||||
packet_count, Invalid_Frame_Count);
|
packet_count, Invalid_Frame_Count);
|
||||||
}
|
}
|
||||||
if (packet_count >= 65535) {
|
if (packet_count >= 65535) {
|
||||||
packet_statistics_print();
|
packet_statistics_print();
|
||||||
@@ -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
|
||||||
@@ -42,12 +42,12 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
/* OS specific include*/
|
/* OS specific include*/
|
||||||
#include "net.h"
|
#include "bacport.h"
|
||||||
#include "timer.h"
|
|
||||||
/* local includes */
|
/* local includes */
|
||||||
#include "bytes.h"
|
#include "bacnet/bytes.h"
|
||||||
#include "crc.h"
|
#include "bacnet/basic/sys/mstimer.h"
|
||||||
#include "version.h"
|
#include "bacnet/datalink/crc.h"
|
||||||
|
#include "bacnet/version.h"
|
||||||
|
|
||||||
#ifndef max
|
#ifndef max
|
||||||
#define max(a, b) (((a)(b)) ? (a) : (b))
|
#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_Cap = false;
|
||||||
static bool MSTP_Text_File = false;
|
static bool MSTP_Text_File = false;
|
||||||
static char Capture_Filename[64] = "mstp_20090123091200.cap";
|
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 */
|
static FILE *pText_File = NULL; /* stream pointer */
|
||||||
|
|
||||||
/******************************************************************
|
/******************************************************************
|
||||||
@@ -162,8 +162,8 @@ static void filename_create(char *filename)
|
|||||||
my_time = time(NULL);
|
my_time = time(NULL);
|
||||||
today = localtime(&my_time);
|
today = localtime(&my_time);
|
||||||
sprintf(filename, "mstp_%04d%02d%02d%02d%02d%02d.cap",
|
sprintf(filename, "mstp_%04d%02d%02d%02d%02d%02d.cap",
|
||||||
1900 + today->tm_year, 1 + today->tm_mon, today->tm_mday,
|
1900 + today->tm_year, 1 + today->tm_mon, today->tm_mday,
|
||||||
today->tm_hour, today->tm_min, today->tm_sec);
|
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)
|
static void write_global_header(const char *filename)
|
||||||
{
|
{
|
||||||
uint32_t magic_number = 0xa1b2c3d4; /* magic number */
|
uint32_t magic_number = 0xa1b2c3d4; /* magic number */
|
||||||
uint16_t version_major = 2; /* major version number */
|
uint16_t version_major = 2; /* major version number */
|
||||||
uint16_t version_minor = 4; /* minor version number */
|
uint16_t version_minor = 4; /* minor version number */
|
||||||
int32_t thiszone = 0; /* GMT to local correction */
|
int32_t thiszone = 0; /* GMT to local correction */
|
||||||
uint32_t sigfigs = 0; /* accuracy of timestamps */
|
uint32_t sigfigs = 0; /* accuracy of timestamps */
|
||||||
uint32_t snaplen = 65535; /* max length of captured packets, in octets */
|
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. */
|
/* create a new file. */
|
||||||
pFile = fopen(filename, "wb");
|
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);
|
fprintf(stdout, "mstpcap: saving capture to %s\n", filename);
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "mstpcap[header]: failed to open %s: %s\n", filename,
|
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)
|
static void write_received_packet(uint8_t *buffer, unsigned length)
|
||||||
{
|
{
|
||||||
uint32_t ts_sec; /* timestamp seconds */
|
uint32_t ts_sec; /* timestamp seconds */
|
||||||
uint32_t ts_usec; /* timestamp microseconds */
|
uint32_t ts_usec; /* timestamp microseconds */
|
||||||
uint32_t incl_len; /* number of octets of packet saved in file */
|
uint32_t incl_len; /* number of octets of packet saved in file */
|
||||||
uint32_t orig_len; /* actual length of packet */
|
uint32_t orig_len; /* actual length of packet */
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
@@ -216,7 +216,7 @@ static void write_received_packet(uint8_t *buffer, unsigned length)
|
|||||||
(void)fwrite(buffer, length, 1, pFile);
|
(void)fwrite(buffer, length, 1, pFile);
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "mstpcrc[packet]: failed to open %s: %s\n",
|
fprintf(stderr, "mstpcrc[packet]: failed to open %s: %s\n",
|
||||||
Capture_Filename, strerror(errno));
|
Capture_Filename, strerror(errno));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Executable → Regular
Executable → Regular
@@ -1,10 +1,10 @@
|
|||||||
#include "bacdef.h"
|
#include "bacnet/bacdef.h"
|
||||||
#include "handlers.h"
|
#include "bacnet/basic/services.h"
|
||||||
#include "bacenum.h"
|
#include "bacnet/bacenum.h"
|
||||||
#include "datalink.h"
|
#include "bacnet/datalink/datalink.h"
|
||||||
#include "device.h"
|
#include "bacnet/basic/object/device.h"
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include "arf.h"
|
#include "bacnet/arf.h"
|
||||||
|
|
||||||
/* Free is redefined as a macro, but Perl does not like that. */
|
/* Free is redefined as a macro, but Perl does not like that. */
|
||||||
#undef free
|
#undef free
|
||||||
@@ -57,41 +57,42 @@ static void __LogAnswer(const char *msg, unsigned append)
|
|||||||
/**************************************/
|
/**************************************/
|
||||||
/* error handlers */
|
/* error handlers */
|
||||||
/*************************************/
|
/*************************************/
|
||||||
static void MyAbortHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
|
static void MyAbortHandler(
|
||||||
uint8_t abort_reason, bool server)
|
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t abort_reason, bool server)
|
||||||
{
|
{
|
||||||
(void)server;
|
(void)server;
|
||||||
if (address_match(&Target_Address, src) &&
|
if (address_match(&Target_Address, src) &&
|
||||||
(invoke_id == Request_Invoke_ID)) {
|
(invoke_id == Request_Invoke_ID)) {
|
||||||
char msg[MAX_ERROR_STRING];
|
char msg[MAX_ERROR_STRING];
|
||||||
sprintf(msg, "BACnet Abort: %s",
|
sprintf(msg, "BACnet Abort: %s",
|
||||||
bactext_abort_reason_name((int)abort_reason));
|
bactext_abort_reason_name((int)abort_reason));
|
||||||
LogError(msg);
|
LogError(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
|
static void MyRejectHandler(
|
||||||
uint8_t reject_reason)
|
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||||
{
|
{
|
||||||
if (address_match(&Target_Address, src) &&
|
if (address_match(&Target_Address, src) &&
|
||||||
(invoke_id == Request_Invoke_ID)) {
|
(invoke_id == Request_Invoke_ID)) {
|
||||||
char msg[MAX_ERROR_STRING];
|
char msg[MAX_ERROR_STRING];
|
||||||
sprintf(msg, "BACnet Reject: %s",
|
sprintf(msg, "BACnet Reject: %s",
|
||||||
bactext_reject_reason_name((int)reject_reason));
|
bactext_reject_reason_name((int)reject_reason));
|
||||||
LogError(msg);
|
LogError(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void My_Error_Handler(BACNET_ADDRESS *src, uint8_t invoke_id,
|
static void My_Error_Handler(BACNET_ADDRESS *src,
|
||||||
BACNET_ERROR_CLASS error_class,
|
uint8_t invoke_id,
|
||||||
BACNET_ERROR_CODE error_code)
|
BACNET_ERROR_CLASS error_class,
|
||||||
|
BACNET_ERROR_CODE error_code)
|
||||||
{
|
{
|
||||||
if (address_match(&Target_Address, src) &&
|
if (address_match(&Target_Address, src) &&
|
||||||
(invoke_id == Request_Invoke_ID)) {
|
(invoke_id == Request_Invoke_ID)) {
|
||||||
char msg[MAX_ERROR_STRING];
|
char msg[MAX_ERROR_STRING];
|
||||||
sprintf(msg, "BACnet Error: %s: %s",
|
sprintf(msg, "BACnet Error: %s: %s",
|
||||||
bactext_error_class_name((int)error_class),
|
bactext_error_class_name((int)error_class),
|
||||||
bactext_error_code_name((int)error_code));
|
bactext_error_code_name((int)error_code));
|
||||||
LogError(msg);
|
LogError(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -109,7 +110,7 @@ void rp_ack_extract_data(BACNET_READ_PROPERTY_DATA *data)
|
|||||||
char ackString[MAX_ACK_STRING] = "";
|
char ackString[MAX_ACK_STRING] = "";
|
||||||
char *pAckString = &ackString[0];
|
char *pAckString = &ackString[0];
|
||||||
BACNET_OBJECT_PROPERTY_VALUE object_value; /* for bacapp printing */
|
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;
|
int len = 0;
|
||||||
uint8_t *application_data;
|
uint8_t *application_data;
|
||||||
int application_data_len;
|
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.array_index = data->array_index;
|
||||||
object_value.value = &value;
|
object_value.value = &value;
|
||||||
bacapp_snprintf_value(pAckString,
|
bacapp_snprintf_value(pAckString,
|
||||||
MAX_ACK_STRING - (pAckString - ackString),
|
MAX_ACK_STRING - (pAckString - ackString), &object_value);
|
||||||
&object_value);
|
|
||||||
if (len > 0) {
|
if (len > 0) {
|
||||||
if (len < application_data_len) {
|
if (len < application_data_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 =
|
object_value.array_index =
|
||||||
listOfProperties->propertyArrayIndex;
|
listOfProperties->propertyArrayIndex;
|
||||||
object_value.value = value;
|
object_value.value = value;
|
||||||
bacapp_snprintf_value(
|
bacapp_snprintf_value(pAckString,
|
||||||
pAckString, MAX_ACK_STRING - (pAckString - ackString),
|
MAX_ACK_STRING - (pAckString - ackString),
|
||||||
&object_value);
|
&object_value);
|
||||||
if (value->next) {
|
if (value->next) {
|
||||||
strncat(pAckString, ",", 1);
|
strncat(pAckString, ",", 1);
|
||||||
@@ -210,10 +210,10 @@ void rpm_ack_extract_data(BACNET_READ_ACCESS_DATA *rpm_data)
|
|||||||
} else {
|
} else {
|
||||||
/* AccessError */
|
/* AccessError */
|
||||||
sprintf(ackString, "BACnet Error: %s: %s",
|
sprintf(ackString, "BACnet Error: %s: %s",
|
||||||
bactext_error_class_name(
|
bactext_error_class_name(
|
||||||
(int)listOfProperties->error.error_class),
|
(int)listOfProperties->error.error_class),
|
||||||
bactext_error_code_name(
|
bactext_error_code_name(
|
||||||
(int)listOfProperties->error.error_code));
|
(int)listOfProperties->error.error_code));
|
||||||
LogError(ackString);
|
LogError(ackString);
|
||||||
}
|
}
|
||||||
listOfProperties = listOfProperties->next;
|
listOfProperties = listOfProperties->next;
|
||||||
@@ -229,8 +229,9 @@ void rpm_ack_extract_data(BACNET_READ_ACCESS_DATA *rpm_data)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void AtomicReadFileAckHandler(
|
static void AtomicReadFileAckHandler(uint8_t *service_request,
|
||||||
uint8_t *service_request, uint16_t service_len, BACNET_ADDRESS *src,
|
uint16_t service_len,
|
||||||
|
BACNET_ADDRESS *src,
|
||||||
BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data)
|
BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data)
|
||||||
{
|
{
|
||||||
int len = 0;
|
int len = 0;
|
||||||
@@ -249,7 +250,7 @@ static void AtomicReadFileAckHandler(
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
sprintf(msg, "EOF=%d,start=%d,", data.endOfFile,
|
sprintf(msg, "EOF=%d,start=%d,", data.endOfFile,
|
||||||
data.type.stream.fileStartPosition);
|
data.type.stream.fileStartPosition);
|
||||||
__LogAnswer(msg, 0);
|
__LogAnswer(msg, 0);
|
||||||
|
|
||||||
pFileData = octetstring_value(&data.fileData);
|
pFileData = octetstring_value(&data.fileData);
|
||||||
@@ -276,8 +277,9 @@ static void AtomicReadFileAckHandler(
|
|||||||
* @param service_data [in] The BACNET_CONFIRMED_SERVICE_DATA information
|
* @param service_data [in] The BACNET_CONFIRMED_SERVICE_DATA information
|
||||||
* decoded from the APDU header of this message.
|
* decoded from the APDU header of this message.
|
||||||
*/
|
*/
|
||||||
static void My_Read_Property_Ack_Handler(
|
static void My_Read_Property_Ack_Handler(uint8_t *service_request,
|
||||||
uint8_t *service_request, uint16_t service_len, BACNET_ADDRESS *src,
|
uint16_t service_len,
|
||||||
|
BACNET_ADDRESS *src,
|
||||||
BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data)
|
BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data)
|
||||||
{
|
{
|
||||||
int len = 0;
|
int len = 0;
|
||||||
@@ -304,8 +306,9 @@ static void My_Read_Property_Ack_Handler(
|
|||||||
* @param service_data [in] The BACNET_CONFIRMED_SERVICE_DATA information
|
* @param service_data [in] The BACNET_CONFIRMED_SERVICE_DATA information
|
||||||
* decoded from the APDU header of this message.
|
* decoded from the APDU header of this message.
|
||||||
*/
|
*/
|
||||||
static void My_Read_Property_Multiple_Ack_Handler(
|
static void My_Read_Property_Multiple_Ack_Handler(uint8_t *service_request,
|
||||||
uint8_t *service_request, uint16_t service_len, BACNET_ADDRESS *src,
|
uint16_t service_len,
|
||||||
|
BACNET_ADDRESS *src,
|
||||||
BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data)
|
BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data)
|
||||||
{
|
{
|
||||||
int len = 0;
|
int len = 0;
|
||||||
@@ -320,8 +323,8 @@ static void My_Read_Property_Multiple_Ack_Handler(
|
|||||||
(service_data->invoke_id == Request_Invoke_ID)) {
|
(service_data->invoke_id == Request_Invoke_ID)) {
|
||||||
rpm_data = calloc(1, sizeof(BACNET_READ_ACCESS_DATA));
|
rpm_data = calloc(1, sizeof(BACNET_READ_ACCESS_DATA));
|
||||||
if (rpm_data) {
|
if (rpm_data) {
|
||||||
len = rpm_ack_decode_service_request(service_request, service_len,
|
len = rpm_ack_decode_service_request(
|
||||||
rpm_data);
|
service_request, service_len, rpm_data);
|
||||||
}
|
}
|
||||||
if (len > 0) {
|
if (len > 0) {
|
||||||
while (rpm_data) {
|
while (rpm_data) {
|
||||||
@@ -388,8 +391,8 @@ static void Init_Service_Handlers()
|
|||||||
apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service);
|
apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service);
|
||||||
|
|
||||||
/* we must implement read property - it's required! */
|
/* we must implement read property - it's required! */
|
||||||
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY,
|
apdu_set_confirmed_handler(
|
||||||
handler_read_property);
|
SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property);
|
||||||
|
|
||||||
/* handle generic errors coming back */
|
/* handle generic errors coming back */
|
||||||
apdu_set_abort_handler(MyAbortHandler);
|
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 timeout_seconds = (apdu_timeout() / 1000) * apdu_retries();
|
||||||
time_t elapsed_seconds = 0;
|
time_t elapsed_seconds = 0;
|
||||||
uint16_t pdu_len = 0;
|
uint16_t pdu_len = 0;
|
||||||
BACNET_ADDRESS src = {0}; /* address where message came from */
|
BACNET_ADDRESS src = { 0 }; /* address where message came from */
|
||||||
uint8_t Rx_Buf[MAX_MPDU] = {0};
|
uint8_t Rx_Buf[MAX_MPDU] = { 0 };
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
time_t current_seconds = time(NULL);
|
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) {
|
} else if (action == waitBind) {
|
||||||
if (address_bind_request(Target_Device_Object_Instance,
|
if (address_bind_request(Target_Device_Object_Instance,
|
||||||
&Target_Max_APDU, &Target_Address)) {
|
&Target_Max_APDU, &Target_Address)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -490,10 +493,10 @@ int BacnetBindToDevice(int deviceInstanceNumber)
|
|||||||
Target_Device_Object_Instance = deviceInstanceNumber;
|
Target_Device_Object_Instance = deviceInstanceNumber;
|
||||||
|
|
||||||
/* try to bind with the device */
|
/* try to bind with the device */
|
||||||
if (!address_bind_request(deviceInstanceNumber, &Target_Max_APDU,
|
if (!address_bind_request(
|
||||||
&Target_Address)) {
|
deviceInstanceNumber, &Target_Max_APDU, &Target_Address)) {
|
||||||
Send_WhoIs(Target_Device_Object_Instance,
|
Send_WhoIs(
|
||||||
Target_Device_Object_Instance);
|
Target_Device_Object_Instance, Target_Device_Object_Instance);
|
||||||
|
|
||||||
/* Wait for timeout, failure, or success */
|
/* Wait for timeout, failure, or success */
|
||||||
Wait_For_Answer_Or_Timeout(100, waitBind);
|
Wait_For_Answer_Or_Timeout(100, waitBind);
|
||||||
@@ -507,26 +510,27 @@ int BacnetBindToDevice(int deviceInstanceNumber)
|
|||||||
/****************************************************/
|
/****************************************************/
|
||||||
/* This is the interface to ReadProperty */
|
/* This is the interface to ReadProperty */
|
||||||
/****************************************************/
|
/****************************************************/
|
||||||
int BacnetReadProperty(int deviceInstanceNumber, int objectType,
|
int BacnetReadProperty(int deviceInstanceNumber,
|
||||||
int objectInstanceNumber, int objectProperty,
|
int objectType,
|
||||||
int objectIndex)
|
int objectInstanceNumber,
|
||||||
|
int objectProperty,
|
||||||
|
int objectIndex)
|
||||||
{
|
{
|
||||||
if (!isReadPropertyHandlerRegistered) {
|
if (!isReadPropertyHandlerRegistered) {
|
||||||
/* handle the data coming back from confirmed requests */
|
/* handle the data coming back from confirmed requests */
|
||||||
apdu_set_confirmed_ack_handler(SERVICE_CONFIRMED_READ_PROPERTY,
|
apdu_set_confirmed_ack_handler(
|
||||||
My_Read_Property_Ack_Handler);
|
SERVICE_CONFIRMED_READ_PROPERTY, My_Read_Property_Ack_Handler);
|
||||||
|
|
||||||
/* handle any errors coming back */
|
/* handle any errors coming back */
|
||||||
apdu_set_error_handler(SERVICE_CONFIRMED_READ_PROPERTY,
|
apdu_set_error_handler(
|
||||||
My_Error_Handler);
|
SERVICE_CONFIRMED_READ_PROPERTY, My_Error_Handler);
|
||||||
|
|
||||||
/* indicate that handlers are now registered */
|
/* indicate that handlers are now registered */
|
||||||
isReadPropertyHandlerRegistered = true;
|
isReadPropertyHandlerRegistered = true;
|
||||||
}
|
}
|
||||||
/* Send the message out */
|
/* Send the message out */
|
||||||
Request_Invoke_ID = Send_Read_Property_Request(
|
Request_Invoke_ID = Send_Read_Property_Request(deviceInstanceNumber,
|
||||||
deviceInstanceNumber, objectType, objectInstanceNumber, objectProperty,
|
objectType, objectInstanceNumber, objectProperty, objectIndex);
|
||||||
objectIndex);
|
|
||||||
Wait_For_Answer_Or_Timeout(100, waitAnswer);
|
Wait_For_Answer_Or_Timeout(100, waitAnswer);
|
||||||
|
|
||||||
int isFailure = Error_Detected;
|
int isFailure = Error_Detected;
|
||||||
@@ -546,7 +550,7 @@ int BacnetReadPropertyMultiple(int deviceInstanceNumber, ...)
|
|||||||
calloc(1, sizeof(BACNET_READ_ACCESS_DATA));
|
calloc(1, sizeof(BACNET_READ_ACCESS_DATA));
|
||||||
BACNET_READ_ACCESS_DATA *Read_Access_Data = rpm_object;
|
BACNET_READ_ACCESS_DATA *Read_Access_Data = rpm_object;
|
||||||
BACNET_PROPERTY_REFERENCE *rpm_property;
|
BACNET_PROPERTY_REFERENCE *rpm_property;
|
||||||
uint8_t buffer[MAX_PDU] = {0};
|
uint8_t buffer[MAX_PDU] = { 0 };
|
||||||
|
|
||||||
while (rpmIndex < Inline_Stack_Items) {
|
while (rpmIndex < Inline_Stack_Items) {
|
||||||
SV *pSV = Inline_Stack_Item(rpmIndex++);
|
SV *pSV = Inline_Stack_Item(rpmIndex++);
|
||||||
@@ -622,11 +626,11 @@ int BacnetReadPropertyMultiple(int deviceInstanceNumber, ...)
|
|||||||
if (!isReadPropertyMultipleHandlerRegistered) {
|
if (!isReadPropertyMultipleHandlerRegistered) {
|
||||||
/* handle the data coming back from confirmed requests */
|
/* handle the data coming back from confirmed requests */
|
||||||
apdu_set_confirmed_ack_handler(SERVICE_CONFIRMED_READ_PROP_MULTIPLE,
|
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 */
|
/* handle any errors coming back */
|
||||||
apdu_set_error_handler(SERVICE_CONFIRMED_READ_PROP_MULTIPLE,
|
apdu_set_error_handler(
|
||||||
My_Error_Handler);
|
SERVICE_CONFIRMED_READ_PROP_MULTIPLE, My_Error_Handler);
|
||||||
|
|
||||||
/* indicate that handlers are now registered */
|
/* indicate that handlers are now registered */
|
||||||
isReadPropertyMultipleHandlerRegistered = true;
|
isReadPropertyMultipleHandlerRegistered = true;
|
||||||
@@ -664,23 +668,26 @@ int BacnetReadPropertyMultiple(int deviceInstanceNumber, ...)
|
|||||||
/****************************************************/
|
/****************************************************/
|
||||||
/* This is the interface to WriteProperty */
|
/* This is the interface to WriteProperty */
|
||||||
/****************************************************/
|
/****************************************************/
|
||||||
int BacnetWriteProperty(int deviceInstanceNumber, int objectType,
|
int BacnetWriteProperty(int deviceInstanceNumber,
|
||||||
int objectInstanceNumber, int objectProperty,
|
int objectType,
|
||||||
int objectPriority, int objectIndex, const char *tag,
|
int objectInstanceNumber,
|
||||||
const char *value)
|
int objectProperty,
|
||||||
|
int objectPriority,
|
||||||
|
int objectIndex,
|
||||||
|
const char *tag,
|
||||||
|
const char *value)
|
||||||
{
|
{
|
||||||
char msg[MAX_ERROR_STRING];
|
char msg[MAX_ERROR_STRING];
|
||||||
int isFailure = 1;
|
int isFailure = 1;
|
||||||
|
|
||||||
if (!isWritePropertyHandlerRegistered) {
|
if (!isWritePropertyHandlerRegistered) {
|
||||||
/* handle the ack coming back */
|
/* handle the ack coming back */
|
||||||
apdu_set_confirmed_simple_ack_handler(
|
apdu_set_confirmed_simple_ack_handler(SERVICE_CONFIRMED_WRITE_PROPERTY,
|
||||||
SERVICE_CONFIRMED_WRITE_PROPERTY,
|
|
||||||
My_Write_Property_SimpleAck_Handler);
|
My_Write_Property_SimpleAck_Handler);
|
||||||
|
|
||||||
/* handle any errors coming back */
|
/* handle any errors coming back */
|
||||||
apdu_set_error_handler(SERVICE_CONFIRMED_WRITE_PROPERTY,
|
apdu_set_error_handler(
|
||||||
My_Error_Handler);
|
SERVICE_CONFIRMED_WRITE_PROPERTY, My_Error_Handler);
|
||||||
|
|
||||||
/* indicate that handlers are now registered */
|
/* indicate that handlers are now registered */
|
||||||
isWritePropertyHandlerRegistered = true;
|
isWritePropertyHandlerRegistered = true;
|
||||||
@@ -707,12 +714,12 @@ int BacnetWriteProperty(int deviceInstanceNumber, int objectType,
|
|||||||
|
|
||||||
if (property_tag >= MAX_BACNET_APPLICATION_TAG) {
|
if (property_tag >= MAX_BACNET_APPLICATION_TAG) {
|
||||||
sprintf(msg, "Error: tag=%u - it must be less than %u",
|
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);
|
LogError(msg);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!bacapp_parse_application_data(property_tag, value,
|
if (!bacapp_parse_application_data(
|
||||||
&propertyValue)) {
|
property_tag, value, &propertyValue)) {
|
||||||
sprintf(msg, "Error: unable to parse the tag value");
|
sprintf(msg, "Error: unable to parse the tag value");
|
||||||
LogError(msg);
|
LogError(msg);
|
||||||
break;
|
break;
|
||||||
@@ -720,9 +727,9 @@ int BacnetWriteProperty(int deviceInstanceNumber, int objectType,
|
|||||||
propertyValue.next = NULL;
|
propertyValue.next = NULL;
|
||||||
|
|
||||||
/* Send out the message */
|
/* Send out the message */
|
||||||
Request_Invoke_ID = Send_Write_Property_Request(
|
Request_Invoke_ID = Send_Write_Property_Request(deviceInstanceNumber,
|
||||||
deviceInstanceNumber, objectType, objectInstanceNumber,
|
objectType, objectInstanceNumber, objectProperty, &propertyValue,
|
||||||
objectProperty, &propertyValue, objectPriority, objectIndex);
|
objectPriority, objectIndex);
|
||||||
Wait_For_Answer_Or_Timeout(100, waitAnswer);
|
Wait_For_Answer_Or_Timeout(100, waitAnswer);
|
||||||
|
|
||||||
/* If we get here, then there were no explicit failures. However, there
|
/* If we get here, then there were no explicit failures. However, there
|
||||||
@@ -736,9 +743,11 @@ int BacnetWriteProperty(int deviceInstanceNumber, int objectType,
|
|||||||
return isFailure;
|
return isFailure;
|
||||||
}
|
}
|
||||||
|
|
||||||
int BacnetAtomicWriteFile(int deviceInstanceNumber, int fileInstanceNumber,
|
int BacnetAtomicWriteFile(int deviceInstanceNumber,
|
||||||
int blockStartAddr, int blockNumBytes,
|
int fileInstanceNumber,
|
||||||
char *nibbleBuffer)
|
int blockStartAddr,
|
||||||
|
int blockNumBytes,
|
||||||
|
char *nibbleBuffer)
|
||||||
{
|
{
|
||||||
BACNET_OCTET_STRING fileData;
|
BACNET_OCTET_STRING fileData;
|
||||||
int i, nibble;
|
int i, nibble;
|
||||||
@@ -747,8 +756,8 @@ int BacnetAtomicWriteFile(int deviceInstanceNumber, int fileInstanceNumber,
|
|||||||
|
|
||||||
if (!isAtomicWriteFileHandlerRegistered) {
|
if (!isAtomicWriteFileHandlerRegistered) {
|
||||||
/* handle any errors coming back */
|
/* handle any errors coming back */
|
||||||
apdu_set_error_handler(SERVICE_CONFIRMED_ATOMIC_WRITE_FILE,
|
apdu_set_error_handler(
|
||||||
My_Error_Handler);
|
SERVICE_CONFIRMED_ATOMIC_WRITE_FILE, My_Error_Handler);
|
||||||
|
|
||||||
/* indicate that handlers are now registered */
|
/* indicate that handlers are now registered */
|
||||||
isAtomicWriteFileHandlerRegistered = true;
|
isAtomicWriteFileHandlerRegistered = true;
|
||||||
@@ -772,9 +781,8 @@ int BacnetAtomicWriteFile(int deviceInstanceNumber, int fileInstanceNumber,
|
|||||||
|
|
||||||
/* Send out the message and wait for answer */
|
/* Send out the message and wait for answer */
|
||||||
if (!Error_Detected) {
|
if (!Error_Detected) {
|
||||||
Request_Invoke_ID = Send_Atomic_Write_File_Stream(
|
Request_Invoke_ID = Send_Atomic_Write_File_Stream(deviceInstanceNumber,
|
||||||
deviceInstanceNumber, fileInstanceNumber, blockStartAddr,
|
fileInstanceNumber, blockStartAddr, &fileData);
|
||||||
&fileData);
|
|
||||||
Wait_For_Answer_Or_Timeout(100, waitAnswer);
|
Wait_For_Answer_Or_Timeout(100, waitAnswer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -811,8 +819,15 @@ int BacnetGetMaxApdu()
|
|||||||
return requestedOctetCount;
|
return requestedOctetCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
int BacnetTimeSync(int deviceInstanceNumber, int year, int month, int day,
|
int BacnetTimeSync(int deviceInstanceNumber,
|
||||||
int hour, int minute, int second, int isUTC, int UTCOffset)
|
int year,
|
||||||
|
int month,
|
||||||
|
int day,
|
||||||
|
int hour,
|
||||||
|
int minute,
|
||||||
|
int second,
|
||||||
|
int isUTC,
|
||||||
|
int UTCOffset)
|
||||||
{
|
{
|
||||||
BACNET_DATE bdate;
|
BACNET_DATE bdate;
|
||||||
BACNET_TIME btime;
|
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_mday = day;
|
||||||
my_time.tm_mon = month - 1;
|
my_time.tm_mon = month - 1;
|
||||||
my_time.tm_year = year - 1900;
|
my_time.tm_year = year - 1900;
|
||||||
my_time.tm_wday = 0; /* does not matter */
|
my_time.tm_wday = 0; /* does not matter */
|
||||||
my_time.tm_yday = 0; /* does not matter */
|
my_time.tm_yday = 0; /* does not matter */
|
||||||
my_time.tm_isdst = 0; /* does not matter */
|
my_time.tm_isdst = 0; /* does not matter */
|
||||||
|
|
||||||
aTime = mktime(&my_time);
|
aTime = mktime(&my_time);
|
||||||
@@ -847,7 +862,7 @@ int BacnetTimeSync(int deviceInstanceNumber, int year, int month, int day,
|
|||||||
int bytes_sent = 0;
|
int bytes_sent = 0;
|
||||||
BACNET_NPDU_DATA npdu_data;
|
BACNET_NPDU_DATA npdu_data;
|
||||||
BACNET_ADDRESS my_address;
|
BACNET_ADDRESS my_address;
|
||||||
uint8_t Handler_Transmit_Buffer[MAX_PDU] = {0};
|
uint8_t Handler_Transmit_Buffer[MAX_PDU] = { 0 };
|
||||||
|
|
||||||
/* Loop for eary exit */
|
/* Loop for eary exit */
|
||||||
do {
|
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);
|
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
|
||||||
datalink_get_my_address(&my_address);
|
datalink_get_my_address(&my_address);
|
||||||
pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], &Target_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 */
|
/* encode the APDU portion of the packet */
|
||||||
len = timesync_encode_apdu(&Handler_Transmit_Buffer[pdu_len], &bdate,
|
len = timesync_encode_apdu(
|
||||||
&btime);
|
&Handler_Transmit_Buffer[pdu_len], &bdate, &btime);
|
||||||
pdu_len += len;
|
pdu_len += len;
|
||||||
|
|
||||||
/* send it out the datalink */
|
/* send it out the datalink */
|
||||||
bytes_sent = datalink_send_pdu(&Target_Address, &npdu_data,
|
bytes_sent = datalink_send_pdu(
|
||||||
&Handler_Transmit_Buffer[0], pdu_len);
|
&Target_Address, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len);
|
||||||
if (bytes_sent <= 0) {
|
if (bytes_sent <= 0) {
|
||||||
char errorMsg[64];
|
char errorMsg[64];
|
||||||
sprintf(errorMsg,
|
sprintf(errorMsg,
|
||||||
"Failed to Send Time-Synchronization Request (%s)!",
|
"Failed to Send Time-Synchronization Request (%s)!",
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
LogError(errorMsg);
|
LogError(errorMsg);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -890,17 +905,19 @@ int BacnetTimeSync(int deviceInstanceNumber, int year, int month, int day,
|
|||||||
/****************************************************/
|
/****************************************************/
|
||||||
/* This is the interface to AtomicReadFile */
|
/* This is the interface to AtomicReadFile */
|
||||||
/****************************************************/
|
/****************************************************/
|
||||||
int BacnetAtomicReadFile(int deviceInstanceNumber, int fileInstanceNumber,
|
int BacnetAtomicReadFile(int deviceInstanceNumber,
|
||||||
int startOffset, int numBytes)
|
int fileInstanceNumber,
|
||||||
|
int startOffset,
|
||||||
|
int numBytes)
|
||||||
{
|
{
|
||||||
if (!isAtomicReadFileHandlerRegistered) {
|
if (!isAtomicReadFileHandlerRegistered) {
|
||||||
/* handle the data coming back from confirmed requests */
|
/* handle the data coming back from confirmed requests */
|
||||||
apdu_set_confirmed_ack_handler(SERVICE_CONFIRMED_ATOMIC_READ_FILE,
|
apdu_set_confirmed_ack_handler(
|
||||||
AtomicReadFileAckHandler);
|
SERVICE_CONFIRMED_ATOMIC_READ_FILE, AtomicReadFileAckHandler);
|
||||||
|
|
||||||
/* handle any errors coming back */
|
/* handle any errors coming back */
|
||||||
apdu_set_error_handler(SERVICE_CONFIRMED_ATOMIC_READ_FILE,
|
apdu_set_error_handler(
|
||||||
My_Error_Handler);
|
SERVICE_CONFIRMED_ATOMIC_READ_FILE, My_Error_Handler);
|
||||||
|
|
||||||
/* indicate that handlers are now registered */
|
/* indicate that handlers are now registered */
|
||||||
isAtomicReadFileHandlerRegistered = true;
|
isAtomicReadFileHandlerRegistered = true;
|
||||||
Executable → Regular
@@ -25,29 +25,29 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string.h> /* for memmove */
|
#include <string.h> /* for memmove */
|
||||||
#include <time.h> /* for timezone, localtime */
|
#include <time.h> /* for timezone, localtime */
|
||||||
#include "bacdef.h"
|
#include "bacnet/bacdef.h"
|
||||||
#include "bacdcode.h"
|
#include "bacnet/bacdcode.h"
|
||||||
#include "bacenum.h"
|
#include "bacnet/bacenum.h"
|
||||||
#include "bacapp.h"
|
#include "bacnet/bacapp.h"
|
||||||
#include "config.h" /* the custom stuff */
|
#include "bacnet/config.h" /* the custom stuff */
|
||||||
#include "apdu.h"
|
#include "bacnet/apdu.h"
|
||||||
#include "wp.h" /* WriteProperty handling */
|
#include "bacnet/wp.h" /* WriteProperty handling */
|
||||||
#include "rp.h" /* ReadProperty handling */
|
#include "bacnet/rp.h" /* ReadProperty handling */
|
||||||
#include "dcc.h" /* DeviceCommunicationControl handling */
|
#include "bacnet/dcc.h" /* DeviceCommunicationControl handling */
|
||||||
#include "version.h"
|
#include "bacnet/version.h"
|
||||||
#include "device.h" /* me */
|
#include "bacnet/basic/object/device.h" /* me */
|
||||||
#include "handlers.h"
|
#include "bacnet/basic/services.h"
|
||||||
#include "datalink.h"
|
#include "bacnet/datalink/datalink.h"
|
||||||
#include "address.h"
|
#include "bacnet/basic/binding/address.h"
|
||||||
/* include the OS specific */
|
/* include the OS specific */
|
||||||
#include "timer.h"
|
#include "bacnet/basic/sys/mstimer.h"
|
||||||
/* include the device object */
|
/* include the device object */
|
||||||
#include "device.h"
|
#include "bacnet/basic/object/device.h"
|
||||||
#include "bi.h"
|
#include "bacnet/basic/object/bi.h"
|
||||||
#include "bo.h"
|
#include "bacnet/basic/object/bo.h"
|
||||||
#if (BACNET_PROTOCOL_REVISION >= 17)
|
#if (BACNET_PROTOCOL_REVISION >= 17)
|
||||||
#include "netport.h"
|
#include "bacnet/basic/object/netport.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* local forward (semi-private) and external prototypes */
|
/* 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 *Object_Table;
|
||||||
|
|
||||||
static object_functions_t My_Object_Table[] = {
|
static object_functions_t My_Object_Table[] = {
|
||||||
{OBJECT_DEVICE, NULL /* Init - don't init Device or it will recourse! */,
|
{ OBJECT_DEVICE, NULL /* Init - don't init Device or it will recourse! */,
|
||||||
Device_Count, Device_Index_To_Instance,
|
Device_Count, Device_Index_To_Instance,
|
||||||
Device_Valid_Object_Instance_Number, Device_Object_Name,
|
Device_Valid_Object_Instance_Number, Device_Object_Name,
|
||||||
Device_Read_Property_Local, Device_Write_Property_Local,
|
Device_Read_Property_Local, Device_Write_Property_Local,
|
||||||
Device_Property_Lists, DeviceGetRRInfo, NULL /* Iterator */,
|
Device_Property_Lists, DeviceGetRRInfo, NULL /* Iterator */,
|
||||||
NULL /* Value_Lists */, NULL /* COV */, NULL /* COV Clear */,
|
NULL /* Value_Lists */, NULL /* COV */, NULL /* COV Clear */,
|
||||||
NULL /* Intrinsic Reporting */},
|
NULL /* Intrinsic Reporting */ },
|
||||||
#if (BACNET_PROTOCOL_REVISION >= 17)
|
#if (BACNET_PROTOCOL_REVISION >= 17)
|
||||||
{OBJECT_NETWORK_PORT, Network_Port_Init, Network_Port_Count,
|
{ OBJECT_NETWORK_PORT, Network_Port_Init, Network_Port_Count,
|
||||||
Network_Port_Index_To_Instance, Network_Port_Valid_Instance,
|
Network_Port_Index_To_Instance, Network_Port_Valid_Instance,
|
||||||
Network_Port_Object_Name, Network_Port_Read_Property,
|
Network_Port_Object_Name, Network_Port_Read_Property,
|
||||||
Network_Port_Write_Property, Network_Port_Property_Lists,
|
Network_Port_Write_Property, Network_Port_Property_Lists,
|
||||||
NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */,
|
NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */,
|
||||||
NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */},
|
NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */ },
|
||||||
#endif
|
#endif
|
||||||
{OBJECT_BINARY_INPUT, Binary_Input_Init, Binary_Input_Count,
|
{ OBJECT_BINARY_INPUT, Binary_Input_Init, Binary_Input_Count,
|
||||||
Binary_Input_Index_To_Instance, Binary_Input_Valid_Instance,
|
Binary_Input_Index_To_Instance, Binary_Input_Valid_Instance,
|
||||||
Binary_Input_Object_Name, Binary_Input_Read_Property,
|
Binary_Input_Object_Name, Binary_Input_Read_Property,
|
||||||
Binary_Input_Write_Property, Binary_Input_Property_Lists,
|
Binary_Input_Write_Property, Binary_Input_Property_Lists,
|
||||||
NULL /* ReadRangeInfo */, NULL /* Iterator */,
|
NULL /* ReadRangeInfo */, NULL /* Iterator */,
|
||||||
Binary_Input_Encode_Value_List, Binary_Input_Change_Of_Value,
|
Binary_Input_Encode_Value_List, Binary_Input_Change_Of_Value,
|
||||||
Binary_Input_Change_Of_Value_Clear, NULL /* Intrinsic Reporting */},
|
Binary_Input_Change_Of_Value_Clear, NULL /* Intrinsic Reporting */ },
|
||||||
{OBJECT_BINARY_OUTPUT, Binary_Output_Init, Binary_Output_Count,
|
{ OBJECT_BINARY_OUTPUT, Binary_Output_Init, Binary_Output_Count,
|
||||||
Binary_Output_Index_To_Instance, Binary_Output_Valid_Instance,
|
Binary_Output_Index_To_Instance, Binary_Output_Valid_Instance,
|
||||||
Binary_Output_Object_Name, Binary_Output_Read_Property,
|
Binary_Output_Object_Name, Binary_Output_Read_Property,
|
||||||
Binary_Output_Write_Property, Binary_Output_Property_Lists,
|
Binary_Output_Write_Property, Binary_Output_Property_Lists,
|
||||||
NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */,
|
NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */,
|
||||||
NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */},
|
NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */ },
|
||||||
{MAX_BACNET_OBJECT_TYPE, NULL /* Init */, NULL /* Count */,
|
{ MAX_BACNET_OBJECT_TYPE, NULL /* Init */, NULL /* Count */,
|
||||||
NULL /* Index_To_Instance */, NULL /* Valid_Instance */,
|
NULL /* Index_To_Instance */, NULL /* Valid_Instance */,
|
||||||
NULL /* Object_Name */, NULL /* Read_Property */,
|
NULL /* Object_Name */, NULL /* Read_Property */,
|
||||||
NULL /* Write_Property */, NULL /* Property_Lists */,
|
NULL /* Write_Property */, NULL /* Property_Lists */,
|
||||||
NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */,
|
NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */,
|
||||||
NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */}};
|
NULL /* COV */, NULL /* COV Clear */,
|
||||||
|
NULL /* Intrinsic Reporting */ }
|
||||||
|
};
|
||||||
|
|
||||||
/** Glue function to let the Device object, when called by a handler,
|
/** Glue function to let the Device object, when called by a handler,
|
||||||
* lookup which Object type needs to be invoked.
|
* 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.
|
* properties with their counts.
|
||||||
*/
|
*/
|
||||||
void Device_Objects_Property_List(BACNET_OBJECT_TYPE object_type,
|
void Device_Objects_Property_List(BACNET_OBJECT_TYPE object_type,
|
||||||
uint32_t object_instance,
|
uint32_t object_instance,
|
||||||
struct special_property_list_t *pPropertyList)
|
struct special_property_list_t *pPropertyList)
|
||||||
{
|
{
|
||||||
struct object_functions *pObject = NULL;
|
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);
|
pObject = Device_Objects_Find_Functions(object_type);
|
||||||
if ((pObject != NULL) && (pObject->Object_RPM_List != NULL)) {
|
if ((pObject != NULL) && (pObject->Object_RPM_List != NULL)) {
|
||||||
pObject->Object_RPM_List(&pPropertyList->Required.pList,
|
pObject->Object_RPM_List(&pPropertyList->Required.pList,
|
||||||
&pPropertyList->Optional.pList,
|
&pPropertyList->Optional.pList, &pPropertyList->Proprietary.pList);
|
||||||
&pPropertyList->Proprietary.pList);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fetch the counts if available otherwise zero them */
|
/* Fetch the counts if available otherwise zero them */
|
||||||
pPropertyList->Required.count =
|
pPropertyList->Required.count = pPropertyList->Required.pList == NULL
|
||||||
pPropertyList->Required.pList == NULL
|
? 0
|
||||||
? 0
|
: property_list_count(pPropertyList->Required.pList);
|
||||||
: property_list_count(pPropertyList->Required.pList);
|
|
||||||
|
|
||||||
pPropertyList->Optional.count =
|
pPropertyList->Optional.count = pPropertyList->Optional.pList == NULL
|
||||||
pPropertyList->Optional.pList == NULL
|
? 0
|
||||||
? 0
|
: property_list_count(pPropertyList->Optional.pList);
|
||||||
: property_list_count(pPropertyList->Optional.pList);
|
|
||||||
|
|
||||||
pPropertyList->Proprietary.count =
|
pPropertyList->Proprietary.count = pPropertyList->Proprietary.pList == NULL
|
||||||
pPropertyList->Proprietary.pList == NULL
|
? 0
|
||||||
? 0
|
: property_list_count(pPropertyList->Proprietary.pList);
|
||||||
: property_list_count(pPropertyList->Proprietary.pList);
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* These three arrays are used by the ReadPropertyMultiple handler */
|
/* These three arrays are used by the ReadPropertyMultiple handler */
|
||||||
static const int Device_Properties_Required[] = {
|
static const int Device_Properties_Required[] = { PROP_OBJECT_IDENTIFIER,
|
||||||
PROP_OBJECT_IDENTIFIER,
|
PROP_OBJECT_NAME, PROP_OBJECT_TYPE, PROP_SYSTEM_STATUS, PROP_VENDOR_NAME,
|
||||||
PROP_OBJECT_NAME,
|
PROP_VENDOR_IDENTIFIER, PROP_MODEL_NAME, PROP_FIRMWARE_REVISION,
|
||||||
PROP_OBJECT_TYPE,
|
PROP_APPLICATION_SOFTWARE_VERSION, PROP_PROTOCOL_VERSION,
|
||||||
PROP_SYSTEM_STATUS,
|
PROP_PROTOCOL_REVISION, PROP_PROTOCOL_SERVICES_SUPPORTED,
|
||||||
PROP_VENDOR_NAME,
|
PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED, PROP_OBJECT_LIST,
|
||||||
PROP_VENDOR_IDENTIFIER,
|
PROP_MAX_APDU_LENGTH_ACCEPTED, PROP_SEGMENTATION_SUPPORTED,
|
||||||
PROP_MODEL_NAME,
|
PROP_APDU_TIMEOUT, PROP_NUMBER_OF_APDU_RETRIES, PROP_DEVICE_ADDRESS_BINDING,
|
||||||
PROP_FIRMWARE_REVISION,
|
PROP_DATABASE_REVISION, -1 };
|
||||||
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[] = {
|
static const int Device_Properties_Optional[] = {
|
||||||
#if defined(BACDL_MSTP)
|
#if defined(BACDL_MSTP)
|
||||||
PROP_MAX_MASTER,
|
PROP_MAX_MASTER, PROP_MAX_INFO_FRAMES,
|
||||||
PROP_MAX_INFO_FRAMES,
|
|
||||||
#endif
|
#endif
|
||||||
PROP_DESCRIPTION,
|
PROP_DESCRIPTION, PROP_LOCAL_TIME, PROP_UTC_OFFSET, PROP_LOCAL_DATE,
|
||||||
PROP_LOCAL_TIME,
|
PROP_DAYLIGHT_SAVINGS_STATUS, PROP_LOCATION, PROP_ACTIVE_COV_SUBSCRIPTIONS,
|
||||||
PROP_UTC_OFFSET,
|
-1
|
||||||
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,
|
void Device_Property_Lists(
|
||||||
const int **pProprietary)
|
const int **pRequired, const int **pOptional, const int **pProprietary)
|
||||||
{
|
{
|
||||||
if (pRequired)
|
if (pRequired) {
|
||||||
*pRequired = Device_Properties_Required;
|
*pRequired = Device_Properties_Required;
|
||||||
if (pOptional)
|
}
|
||||||
|
if (pOptional) {
|
||||||
*pOptional = Device_Properties_Optional;
|
*pOptional = Device_Properties_Optional;
|
||||||
if (pProprietary)
|
}
|
||||||
|
if (pProprietary) {
|
||||||
*pProprietary = Device_Properties_Proprietary;
|
*pProprietary = Device_Properties_Proprietary;
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -258,6 +241,7 @@ static char *Vendor_Name = BACNET_VENDOR_NAME;
|
|||||||
static uint16_t Vendor_Identifier = BACNET_VENDOR_ID;
|
static uint16_t Vendor_Identifier = BACNET_VENDOR_ID;
|
||||||
static char Model_Name[MAX_DEV_MOD_LEN + 1] = "PiFace Digital";
|
static char Model_Name[MAX_DEV_MOD_LEN + 1] = "PiFace Digital";
|
||||||
static char Application_Software_Version[MAX_DEV_VER_LEN + 1] = "1.0";
|
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 Location[MAX_DEV_LOC_LEN + 1] = "USA";
|
||||||
static char Description[MAX_DEV_DESC_LEN + 1] = "Raspberry PiFace Digital Demo";
|
static char Description[MAX_DEV_DESC_LEN + 1] = "Raspberry PiFace Digital Demo";
|
||||||
/* static uint8_t Protocol_Version = 1; - constant, not settable */
|
/* 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);
|
return (Object_Instance_Number == object_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Device_Object_Name(uint32_t object_instance,
|
bool Device_Object_Name(
|
||||||
BACNET_CHARACTER_STRING *object_name)
|
uint32_t object_instance, BACNET_CHARACTER_STRING *object_name)
|
||||||
{
|
{
|
||||||
bool status = false;
|
bool status = false;
|
||||||
|
|
||||||
@@ -660,8 +644,8 @@ unsigned Device_Object_List_Count(void)
|
|||||||
* @param instance [out] The object's instance number, if found.
|
* @param instance [out] The object's instance number, if found.
|
||||||
* @return True if found, else false.
|
* @return True if found, else false.
|
||||||
*/
|
*/
|
||||||
bool Device_Object_List_Identifier(uint32_t array_index, int *object_type,
|
bool Device_Object_List_Identifier(
|
||||||
uint32_t *instance)
|
uint32_t array_index, int *object_type, uint32_t *instance)
|
||||||
{
|
{
|
||||||
bool status = false;
|
bool status = false;
|
||||||
uint32_t count = 0;
|
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.
|
* @return True on success or else False if not found.
|
||||||
*/
|
*/
|
||||||
bool Device_Valid_Object_Name(BACNET_CHARACTER_STRING *object_name1,
|
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;
|
bool found = false;
|
||||||
int type = 0;
|
int type = 0;
|
||||||
@@ -736,7 +721,7 @@ bool Device_Valid_Object_Name(BACNET_CHARACTER_STRING *object_name1,
|
|||||||
pObject = Device_Objects_Find_Functions(type);
|
pObject = Device_Objects_Find_Functions(type);
|
||||||
if ((pObject != NULL) && (pObject->Object_Name != NULL) &&
|
if ((pObject != NULL) && (pObject->Object_Name != NULL) &&
|
||||||
(pObject->Object_Name(instance, &object_name2) &&
|
(pObject->Object_Name(instance, &object_name2) &&
|
||||||
characterstring_same(object_name1, &object_name2))) {
|
characterstring_same(object_name1, &object_name2))) {
|
||||||
found = true;
|
found = true;
|
||||||
if (object_type) {
|
if (object_type) {
|
||||||
*object_type = 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.
|
* @return True on success or else False if not found.
|
||||||
*/
|
*/
|
||||||
bool Device_Object_Name_Copy(BACNET_OBJECT_TYPE object_type,
|
bool Device_Object_Name_Copy(BACNET_OBJECT_TYPE object_type,
|
||||||
uint32_t object_instance,
|
uint32_t object_instance,
|
||||||
BACNET_CHARACTER_STRING *object_name)
|
BACNET_CHARACTER_STRING *object_name)
|
||||||
{
|
{
|
||||||
struct object_functions *pObject = NULL;
|
struct object_functions *pObject = NULL;
|
||||||
bool found = false;
|
bool found = false;
|
||||||
@@ -823,15 +808,14 @@ int tm_isdst Daylight Savings flag.
|
|||||||
|
|
||||||
if (tblock) {
|
if (tblock) {
|
||||||
datetime_set_date(&Local_Date, (uint16_t)tblock->tm_year + 1900,
|
datetime_set_date(&Local_Date, (uint16_t)tblock->tm_year + 1900,
|
||||||
(uint8_t)tblock->tm_mon + 1,
|
(uint8_t)tblock->tm_mon + 1, (uint8_t)tblock->tm_mday);
|
||||||
(uint8_t)tblock->tm_mday);
|
|
||||||
#if !defined(_MSC_VER)
|
#if !defined(_MSC_VER)
|
||||||
datetime_set_time(&Local_Time, (uint8_t)tblock->tm_hour,
|
datetime_set_time(&Local_Time, (uint8_t)tblock->tm_hour,
|
||||||
(uint8_t)tblock->tm_min, (uint8_t)tblock->tm_sec,
|
(uint8_t)tblock->tm_min, (uint8_t)tblock->tm_sec,
|
||||||
(uint8_t)(tv.tv_usec / 10000));
|
(uint8_t)(tv.tv_usec / 10000));
|
||||||
#else
|
#else
|
||||||
datetime_set_time(&Local_Time, (uint8_t)tblock->tm_hour,
|
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
|
#endif
|
||||||
if (tblock->tm_isdst) {
|
if (tblock->tm_isdst) {
|
||||||
Daylight_Savings_Status = true;
|
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 Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA *rpdata)
|
||||||
{
|
{
|
||||||
int apdu_len = 0; /* return value */
|
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 = {0};
|
BACNET_BIT_STRING bit_string = { 0 };
|
||||||
BACNET_CHARACTER_STRING char_string = {0};
|
BACNET_CHARACTER_STRING char_string = { 0 };
|
||||||
uint32_t i = 0;
|
uint32_t i = 0;
|
||||||
int object_type = 0;
|
int object_type = 0;
|
||||||
uint32_t instance = 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;
|
apdu_max = rpdata->application_data_len;
|
||||||
switch (rpdata->object_property) {
|
switch (rpdata->object_property) {
|
||||||
case PROP_OBJECT_IDENTIFIER:
|
case PROP_OBJECT_IDENTIFIER:
|
||||||
apdu_len = encode_application_object_id(&apdu[0], OBJECT_DEVICE,
|
apdu_len = encode_application_object_id(
|
||||||
Object_Instance_Number);
|
&apdu[0], OBJECT_DEVICE, Object_Instance_Number);
|
||||||
break;
|
break;
|
||||||
case PROP_OBJECT_NAME:
|
case PROP_OBJECT_NAME:
|
||||||
apdu_len =
|
apdu_len =
|
||||||
@@ -929,8 +913,8 @@ int Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA *rpdata)
|
|||||||
encode_application_character_string(&apdu[0], &char_string);
|
encode_application_character_string(&apdu[0], &char_string);
|
||||||
break;
|
break;
|
||||||
case PROP_APPLICATION_SOFTWARE_VERSION:
|
case PROP_APPLICATION_SOFTWARE_VERSION:
|
||||||
characterstring_init_ansi(&char_string,
|
characterstring_init_ansi(
|
||||||
Application_Software_Version);
|
&char_string, Application_Software_Version);
|
||||||
apdu_len =
|
apdu_len =
|
||||||
encode_application_character_string(&apdu[0], &char_string);
|
encode_application_character_string(&apdu[0], &char_string);
|
||||||
break;
|
break;
|
||||||
@@ -957,20 +941,19 @@ int Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA *rpdata)
|
|||||||
encode_application_boolean(&apdu[0], Daylight_Savings_Status);
|
encode_application_boolean(&apdu[0], Daylight_Savings_Status);
|
||||||
break;
|
break;
|
||||||
case PROP_PROTOCOL_VERSION:
|
case PROP_PROTOCOL_VERSION:
|
||||||
apdu_len = encode_application_unsigned(&apdu[0],
|
apdu_len = encode_application_unsigned(
|
||||||
Device_Protocol_Version());
|
&apdu[0], Device_Protocol_Version());
|
||||||
break;
|
break;
|
||||||
case PROP_PROTOCOL_REVISION:
|
case PROP_PROTOCOL_REVISION:
|
||||||
apdu_len = encode_application_unsigned(&apdu[0],
|
apdu_len = encode_application_unsigned(
|
||||||
Device_Protocol_Revision());
|
&apdu[0], Device_Protocol_Revision());
|
||||||
break;
|
break;
|
||||||
case PROP_PROTOCOL_SERVICES_SUPPORTED:
|
case PROP_PROTOCOL_SERVICES_SUPPORTED:
|
||||||
/* Note: list of services that are executed, not initiated. */
|
/* Note: list of services that are executed, not initiated. */
|
||||||
bitstring_init(&bit_string);
|
bitstring_init(&bit_string);
|
||||||
for (i = 0; i < MAX_BACNET_SERVICES_SUPPORTED; i++) {
|
for (i = 0; i < MAX_BACNET_SERVICES_SUPPORTED; i++) {
|
||||||
/* automatic lookup based on handlers set */
|
/* automatic lookup based on handlers set */
|
||||||
bitstring_set_bit(
|
bitstring_set_bit(&bit_string, (uint8_t)i,
|
||||||
&bit_string, (uint8_t)i,
|
|
||||||
apdu_service_supported((BACNET_SERVICES_SUPPORTED)i));
|
apdu_service_supported((BACNET_SERVICES_SUPPORTED)i));
|
||||||
}
|
}
|
||||||
apdu_len = encode_application_bitstring(&apdu[0], &bit_string);
|
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. */
|
/* your maximum APDU size. */
|
||||||
else if (rpdata->array_index == BACNET_ARRAY_ALL) {
|
else if (rpdata->array_index == BACNET_ARRAY_ALL) {
|
||||||
for (i = 1; i <= count; i++) {
|
for (i = 1; i <= count; i++) {
|
||||||
found = Device_Object_List_Identifier(i, &object_type,
|
found = Device_Object_List_Identifier(
|
||||||
&instance);
|
i, &object_type, &instance);
|
||||||
if (found) {
|
if (found) {
|
||||||
len = encode_application_object_id(
|
len = encode_application_object_id(
|
||||||
&apdu[apdu_len], object_type, instance);
|
&apdu[apdu_len], object_type, instance);
|
||||||
@@ -1030,8 +1013,8 @@ int Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA *rpdata)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
found = Device_Object_List_Identifier(rpdata->array_index,
|
found = Device_Object_List_Identifier(
|
||||||
&object_type, &instance);
|
rpdata->array_index, &object_type, &instance);
|
||||||
if (found) {
|
if (found) {
|
||||||
apdu_len = encode_application_object_id(
|
apdu_len = encode_application_object_id(
|
||||||
&apdu[0], object_type, instance);
|
&apdu[0], object_type, instance);
|
||||||
@@ -1132,8 +1115,8 @@ bool Device_Write_Property_Local(BACNET_WRITE_PROPERTY_DATA *wp_data)
|
|||||||
int temp;
|
int temp;
|
||||||
|
|
||||||
/* decode the some of the request */
|
/* decode the some of the request */
|
||||||
len = bacapp_decode_application_data(wp_data->application_data,
|
len = bacapp_decode_application_data(
|
||||||
wp_data->application_data_len, &value);
|
wp_data->application_data, wp_data->application_data_len, &value);
|
||||||
if (len < 0) {
|
if (len < 0) {
|
||||||
/* error while decoding - a value larger than we can handle */
|
/* error while decoding - a value larger than we can handle */
|
||||||
wp_data->error_class = ERROR_CLASS_PROPERTY;
|
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? */
|
/* FIXME: len < application_data_len: more data? */
|
||||||
switch (wp_data->object_property) {
|
switch (wp_data->object_property) {
|
||||||
case PROP_OBJECT_IDENTIFIER:
|
case PROP_OBJECT_IDENTIFIER:
|
||||||
status =
|
status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_OBJECT_ID,
|
||||||
WPValidateArgType(&value, BACNET_APPLICATION_TAG_OBJECT_ID,
|
&wp_data->error_class, &wp_data->error_code);
|
||||||
&wp_data->error_class, &wp_data->error_code);
|
|
||||||
if (status) {
|
if (status) {
|
||||||
if ((value.type.Object_Id.type == OBJECT_DEVICE) &&
|
if ((value.type.Object_Id.type == OBJECT_DEVICE) &&
|
||||||
(Device_Set_Object_Instance_Number(
|
(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:
|
case PROP_NUMBER_OF_APDU_RETRIES:
|
||||||
status =
|
status =
|
||||||
WPValidateArgType(&value, BACNET_APPLICATION_TAG_UNSIGNED_INT,
|
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 (status) {
|
||||||
/* FIXME: bounds check? */
|
/* FIXME: bounds check? */
|
||||||
apdu_retries_set((uint8_t)value.type.Unsigned_Int);
|
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:
|
case PROP_APDU_TIMEOUT:
|
||||||
status =
|
status =
|
||||||
WPValidateArgType(&value, BACNET_APPLICATION_TAG_UNSIGNED_INT,
|
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 (status) {
|
||||||
/* FIXME: bounds check? */
|
/* FIXME: bounds check? */
|
||||||
apdu_timeout_set((uint16_t)value.type.Unsigned_Int);
|
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:
|
case PROP_VENDOR_IDENTIFIER:
|
||||||
status =
|
status =
|
||||||
WPValidateArgType(&value, BACNET_APPLICATION_TAG_UNSIGNED_INT,
|
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 (status) {
|
||||||
/* FIXME: bounds check? */
|
/* FIXME: bounds check? */
|
||||||
Device_Set_Vendor_Identifier((uint16_t)value.type.Unsigned_Int);
|
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:
|
case PROP_SYSTEM_STATUS:
|
||||||
status =
|
status =
|
||||||
WPValidateArgType(&value, BACNET_APPLICATION_TAG_ENUMERATED,
|
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 (status) {
|
||||||
temp = Device_Set_System_Status(
|
temp = Device_Set_System_Status(
|
||||||
(BACNET_DEVICE_STATUS)value.type.Enumerated, false);
|
(BACNET_DEVICE_STATUS)value.type.Enumerated, false);
|
||||||
@@ -1213,13 +1195,13 @@ bool Device_Write_Property_Local(BACNET_WRITE_PROPERTY_DATA *wp_data)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PROP_OBJECT_NAME:
|
case PROP_OBJECT_NAME:
|
||||||
status = WPValidateString(
|
status = WPValidateString(&value,
|
||||||
&value, characterstring_capacity(&My_Object_Name), false,
|
characterstring_capacity(&My_Object_Name), false,
|
||||||
&wp_data->error_class, &wp_data->error_code);
|
&wp_data->error_class, &wp_data->error_code);
|
||||||
if (status) {
|
if (status) {
|
||||||
/* All the object names in a device must be unique */
|
/* All the object names in a device must be unique */
|
||||||
if (Device_Valid_Object_Name(&value.type.Character_String,
|
if (Device_Valid_Object_Name(&value.type.Character_String,
|
||||||
&object_type, &object_instance)) {
|
&object_type, &object_instance)) {
|
||||||
if ((object_type == wp_data->object_type) &&
|
if ((object_type == wp_data->object_type) &&
|
||||||
(object_instance == wp_data->object_instance)) {
|
(object_instance == wp_data->object_instance)) {
|
||||||
/* writing same name to same object */
|
/* writing same name to same object */
|
||||||
@@ -1235,9 +1217,8 @@ bool Device_Write_Property_Local(BACNET_WRITE_PROPERTY_DATA *wp_data)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PROP_LOCATION:
|
case PROP_LOCATION:
|
||||||
status =
|
status = WPValidateString(&value, MAX_DEV_LOC_LEN, true,
|
||||||
WPValidateString(&value, MAX_DEV_LOC_LEN, true,
|
&wp_data->error_class, &wp_data->error_code);
|
||||||
&wp_data->error_class, &wp_data->error_code);
|
|
||||||
if (status) {
|
if (status) {
|
||||||
Device_Set_Location(
|
Device_Set_Location(
|
||||||
characterstring_value(&value.type.Character_String),
|
characterstring_value(&value.type.Character_String),
|
||||||
@@ -1246,9 +1227,8 @@ bool Device_Write_Property_Local(BACNET_WRITE_PROPERTY_DATA *wp_data)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case PROP_DESCRIPTION:
|
case PROP_DESCRIPTION:
|
||||||
status =
|
status = WPValidateString(&value, MAX_DEV_DESC_LEN, true,
|
||||||
WPValidateString(&value, MAX_DEV_DESC_LEN, true,
|
&wp_data->error_class, &wp_data->error_code);
|
||||||
&wp_data->error_class, &wp_data->error_code);
|
|
||||||
if (status) {
|
if (status) {
|
||||||
Device_Set_Description(
|
Device_Set_Description(
|
||||||
characterstring_value(&value.type.Character_String),
|
characterstring_value(&value.type.Character_String),
|
||||||
@@ -1256,9 +1236,8 @@ bool Device_Write_Property_Local(BACNET_WRITE_PROPERTY_DATA *wp_data)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PROP_MODEL_NAME:
|
case PROP_MODEL_NAME:
|
||||||
status =
|
status = WPValidateString(&value, MAX_DEV_MOD_LEN, true,
|
||||||
WPValidateString(&value, MAX_DEV_MOD_LEN, true,
|
&wp_data->error_class, &wp_data->error_code);
|
||||||
&wp_data->error_class, &wp_data->error_code);
|
|
||||||
if (status) {
|
if (status) {
|
||||||
Device_Set_Model_Name(
|
Device_Set_Model_Name(
|
||||||
characterstring_value(&value.type.Character_String),
|
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)
|
#if defined(BACDL_MSTP)
|
||||||
status =
|
status =
|
||||||
WPValidateArgType(&value, BACNET_APPLICATION_TAG_UNSIGNED_INT,
|
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 (status) {
|
||||||
if (value.type.Unsigned_Int <= 255) {
|
if (value.type.Unsigned_Int <= 255) {
|
||||||
dlmstp_set_max_info_frames(
|
dlmstp_set_max_info_frames(
|
||||||
@@ -1287,7 +1266,7 @@ bool Device_Write_Property_Local(BACNET_WRITE_PROPERTY_DATA *wp_data)
|
|||||||
#if defined(BACDL_MSTP)
|
#if defined(BACDL_MSTP)
|
||||||
status =
|
status =
|
||||||
WPValidateArgType(&value, BACNET_APPLICATION_TAG_UNSIGNED_INT,
|
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 (status) {
|
||||||
if ((value.type.Unsigned_Int > 0) &&
|
if ((value.type.Unsigned_Int > 0) &&
|
||||||
(value.type.Unsigned_Int <= 127)) {
|
(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.
|
* @return True if the object instance supports this feature and value changed.
|
||||||
*/
|
*/
|
||||||
bool Device_Encode_Value_List(BACNET_OBJECT_TYPE object_type,
|
bool Device_Encode_Value_List(BACNET_OBJECT_TYPE object_type,
|
||||||
uint32_t object_instance,
|
uint32_t object_instance,
|
||||||
BACNET_PROPERTY_VALUE *value_list)
|
BACNET_PROPERTY_VALUE *value_list)
|
||||||
{
|
{
|
||||||
bool status = false; /* Ever the pessamist! */
|
bool status = false; /* Ever the pessamist! */
|
||||||
struct object_functions *pObject = NULL;
|
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 */
|
bool DeviceGetRRInfo(BACNET_READ_RANGE_DATA *pRequest, /* Info on the request */
|
||||||
RR_PROP_INFO *pInfo)
|
RR_PROP_INFO *pInfo)
|
||||||
{ /* Where to put the response */
|
{ /* Where to put the response */
|
||||||
bool status = false; /* return value */
|
bool status = false; /* return value */
|
||||||
|
|
||||||
switch (pRequest->object_property) {
|
switch (pRequest->object_property) {
|
||||||
@@ -1612,8 +1591,9 @@ void Routing_Device_Init(uint32_t first_object_instance)
|
|||||||
#include "ctest.h"
|
#include "ctest.h"
|
||||||
|
|
||||||
bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue,
|
bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue,
|
||||||
uint8_t ucExpectedTag, BACNET_ERROR_CLASS *pErrorClass,
|
uint8_t ucExpectedTag,
|
||||||
BACNET_ERROR_CODE *pErrorCode)
|
BACNET_ERROR_CLASS *pErrorClass,
|
||||||
|
BACNET_ERROR_CODE *pErrorCode)
|
||||||
{
|
{
|
||||||
pValue = pValue;
|
pValue = pValue;
|
||||||
ucExpectedTag = ucExpectedTag;
|
ucExpectedTag = ucExpectedTag;
|
||||||
@@ -1623,9 +1603,11 @@ bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WPValidateString(BACNET_APPLICATION_DATA_VALUE *pValue, int iMaxLen,
|
bool WPValidateString(BACNET_APPLICATION_DATA_VALUE *pValue,
|
||||||
bool bEmptyAllowed, BACNET_ERROR_CLASS *pErrorClass,
|
int iMaxLen,
|
||||||
BACNET_ERROR_CODE *pErrorCode)
|
bool bEmptyAllowed,
|
||||||
|
BACNET_ERROR_CLASS *pErrorClass,
|
||||||
|
BACNET_ERROR_CODE *pErrorCode)
|
||||||
{
|
{
|
||||||
pValue = pValue;
|
pValue = pValue;
|
||||||
iMaxLen = iMaxLen;
|
iMaxLen = iMaxLen;
|
||||||
@@ -1656,12 +1638,12 @@ void testDevice(Test *pTest)
|
|||||||
ct_test(pTest, Device_Object_Instance_Number() == BACNET_MAX_INSTANCE);
|
ct_test(pTest, Device_Object_Instance_Number() == BACNET_MAX_INSTANCE);
|
||||||
ct_test(pTest, status == true);
|
ct_test(pTest, status == true);
|
||||||
status = Device_Set_Object_Instance_Number(BACNET_MAX_INSTANCE / 2);
|
status = Device_Set_Object_Instance_Number(BACNET_MAX_INSTANCE / 2);
|
||||||
ct_test(pTest,
|
ct_test(
|
||||||
Device_Object_Instance_Number() == (BACNET_MAX_INSTANCE / 2));
|
pTest, Device_Object_Instance_Number() == (BACNET_MAX_INSTANCE / 2));
|
||||||
ct_test(pTest, status == true);
|
ct_test(pTest, status == true);
|
||||||
status = Device_Set_Object_Instance_Number(BACNET_MAX_INSTANCE + 1);
|
status = Device_Set_Object_Instance_Number(BACNET_MAX_INSTANCE + 1);
|
||||||
ct_test(pTest,
|
ct_test(
|
||||||
Device_Object_Instance_Number() != (BACNET_MAX_INSTANCE + 1));
|
pTest, Device_Object_Instance_Number() != (BACNET_MAX_INSTANCE + 1));
|
||||||
ct_test(pTest, status == false);
|
ct_test(pTest, status == false);
|
||||||
|
|
||||||
Device_Set_System_Status(STATUS_NON_OPERATIONAL, true);
|
Device_Set_System_Status(STATUS_NON_OPERATIONAL, true);
|
||||||
@@ -29,30 +29,30 @@
|
|||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
#include "config.h"
|
#include "bacnet/config.h"
|
||||||
#include "address.h"
|
#include "bacnet/basic/binding/address.h"
|
||||||
#include "bacdef.h"
|
#include "bacnet/bacdef.h"
|
||||||
#include "handlers.h"
|
#include "bacnet/basic/services.h"
|
||||||
#include "client.h"
|
#include "bacnet/basic/services.h"
|
||||||
#include "dlenv.h"
|
#include "bacnet/datalink/dlenv.h"
|
||||||
#include "bacdcode.h"
|
#include "bacnet/bacdcode.h"
|
||||||
#include "npdu.h"
|
#include "bacnet/npdu.h"
|
||||||
#include "apdu.h"
|
#include "bacnet/apdu.h"
|
||||||
#include "iam.h"
|
#include "bacnet/iam.h"
|
||||||
#include "tsm.h"
|
#include "bacnet/basic/tsm/tsm.h"
|
||||||
#include "device.h"
|
#include "bacnet/basic/object/device.h"
|
||||||
#include "bacfile.h"
|
#include "bacnet/basic/object/bacfile.h"
|
||||||
#include "datalink.h"
|
#include "bacnet/datalink/datalink.h"
|
||||||
#include "dcc.h"
|
#include "bacnet/dcc.h"
|
||||||
#include "getevent.h"
|
#include "bacnet/getevent.h"
|
||||||
#include "net.h"
|
#include "bacport.h"
|
||||||
#include "txbuf.h"
|
#include "bacnet/basic/tsm/tsm.h"
|
||||||
#include "tsm.h"
|
#include "bacnet/basic/tsm/tsm.h"
|
||||||
#include "version.h"
|
#include "bacnet/version.h"
|
||||||
/* include the device object */
|
/* include the device object */
|
||||||
#include "device.h"
|
#include "bacnet/basic/object/device.h"
|
||||||
#include "bi.h"
|
#include "bacnet/basic/object/bi.h"
|
||||||
#include "bo.h"
|
#include "bacnet/basic/object/bo.h"
|
||||||
#include "pifacedigital.h"
|
#include "pifacedigital.h"
|
||||||
|
|
||||||
/** @file server/main.c Example server application using the BACnet Stack. */
|
/** @file server/main.c Example server application using the BACnet Stack. */
|
||||||
@@ -63,7 +63,10 @@
|
|||||||
/*@{*/
|
/*@{*/
|
||||||
|
|
||||||
/** Buffer used for receiving */
|
/** 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.
|
/** Initialize the handlers we will utilize.
|
||||||
* @see Device_Init, apdu_set_unconfirmed_handler, apdu_set_confirmed_handler
|
* @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);
|
apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service);
|
||||||
/* Set the handlers for any confirmed services that we support. */
|
/* Set the handlers for any confirmed services that we support. */
|
||||||
/* We must implement read property - it's required! */
|
/* We must implement read property - it's required! */
|
||||||
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY,
|
apdu_set_confirmed_handler(
|
||||||
handler_read_property);
|
SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property);
|
||||||
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROP_MULTIPLE,
|
apdu_set_confirmed_handler(
|
||||||
handler_read_property_multiple);
|
SERVICE_CONFIRMED_READ_PROP_MULTIPLE, handler_read_property_multiple);
|
||||||
apdu_set_confirmed_handler(SERVICE_CONFIRMED_WRITE_PROPERTY,
|
apdu_set_confirmed_handler(
|
||||||
handler_write_property);
|
SERVICE_CONFIRMED_WRITE_PROPERTY, handler_write_property);
|
||||||
apdu_set_confirmed_handler(SERVICE_CONFIRMED_WRITE_PROP_MULTIPLE,
|
apdu_set_confirmed_handler(
|
||||||
handler_write_property_multiple);
|
SERVICE_CONFIRMED_WRITE_PROP_MULTIPLE, handler_write_property_multiple);
|
||||||
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_RANGE,
|
apdu_set_confirmed_handler(
|
||||||
handler_read_range);
|
SERVICE_CONFIRMED_READ_RANGE, handler_read_range);
|
||||||
apdu_set_confirmed_handler(SERVICE_CONFIRMED_REINITIALIZE_DEVICE,
|
apdu_set_confirmed_handler(
|
||||||
handler_reinitialize_device);
|
SERVICE_CONFIRMED_REINITIALIZE_DEVICE, handler_reinitialize_device);
|
||||||
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_UTC_TIME_SYNCHRONIZATION,
|
apdu_set_unconfirmed_handler(
|
||||||
handler_timesync_utc);
|
SERVICE_UNCONFIRMED_UTC_TIME_SYNCHRONIZATION, handler_timesync_utc);
|
||||||
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_TIME_SYNCHRONIZATION,
|
apdu_set_unconfirmed_handler(
|
||||||
handler_timesync);
|
SERVICE_UNCONFIRMED_TIME_SYNCHRONIZATION, handler_timesync);
|
||||||
apdu_set_confirmed_handler(SERVICE_CONFIRMED_SUBSCRIBE_COV,
|
apdu_set_confirmed_handler(
|
||||||
handler_cov_subscribe);
|
SERVICE_CONFIRMED_SUBSCRIBE_COV, handler_cov_subscribe);
|
||||||
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_COV_NOTIFICATION,
|
apdu_set_unconfirmed_handler(
|
||||||
handler_ucov_notification);
|
SERVICE_UNCONFIRMED_COV_NOTIFICATION, handler_ucov_notification);
|
||||||
/* handle communication so we can shutup when asked */
|
/* handle communication so we can shutup when asked */
|
||||||
apdu_set_confirmed_handler(SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL,
|
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 */
|
/* handle the data coming back from private requests */
|
||||||
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_PRIVATE_TRANSFER,
|
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_PRIVATE_TRANSFER,
|
||||||
handler_unconfirmed_private_transfer);
|
handler_unconfirmed_private_transfer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void piface_init(void)
|
static void piface_init(void)
|
||||||
@@ -131,9 +134,8 @@ static void piface_init(void)
|
|||||||
if (intenable == 0) {
|
if (intenable == 0) {
|
||||||
printf("Interrupts enabled.\n");
|
printf("Interrupts enabled.\n");
|
||||||
} else {
|
} else {
|
||||||
printf(
|
printf("Could not enable interrupts. "
|
||||||
"Could not enable interrupts. "
|
"Try running using sudo to enable PiFaceDigital interrupts.\n");
|
||||||
"Try running using sudo to enable PiFaceDigital interrupts.\n");
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -205,7 +207,7 @@ static void piface_task(void)
|
|||||||
*/
|
*/
|
||||||
int main(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;
|
uint16_t pdu_len = 0;
|
||||||
unsigned timeout = 1; /* milliseconds */
|
unsigned timeout = 1; /* milliseconds */
|
||||||
time_t last_seconds = 0;
|
time_t last_seconds = 0;
|
||||||
@@ -218,11 +220,10 @@ int main(int argc, char *argv[])
|
|||||||
if (argc > 1) {
|
if (argc > 1) {
|
||||||
Device_Set_Object_Instance_Number(strtol(argv[1], NULL, 0));
|
Device_Set_Object_Instance_Number(strtol(argv[1], NULL, 0));
|
||||||
}
|
}
|
||||||
printf(
|
printf("BACnet Raspberry Pi PiFace Digital Demo\n"
|
||||||
"BACnet Raspberry Pi PiFace Digital Demo\n"
|
"BACnet Stack Version %s\n"
|
||||||
"BACnet Stack Version %s\n"
|
"BACnet Device ID: %u\n"
|
||||||
"BACnet Device ID: %u\n"
|
"Max APDU: %d\n",
|
||||||
"Max APDU: %d\n",
|
|
||||||
BACnet_Version, Device_Object_Instance_Number(), MAX_APDU);
|
BACnet_Version, Device_Object_Instance_Number(), MAX_APDU);
|
||||||
/* load any static address bindings to show up
|
/* load any static address bindings to show up
|
||||||
in our device bindings list */
|
in our device bindings list */
|
||||||
@@ -27,21 +27,15 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include "config.h"
|
#include "bacnet/config.h"
|
||||||
#include "txbuf.h"
|
#include "bacnet/bacdef.h"
|
||||||
#include "bacdef.h"
|
#include "bacnet/bacdcode.h"
|
||||||
#include "bacdcode.h"
|
#include "bacnet/apdu.h"
|
||||||
#include "apdu.h"
|
#include "bacnet/npdu.h"
|
||||||
#include "npdu.h"
|
#include "bacnet/abort.h"
|
||||||
#include "abort.h"
|
#include "bacnet/ptransfer.h"
|
||||||
/*#include "arf.h" */
|
#include "bacnet/basic/services.h"
|
||||||
/* demo objects */
|
#include "bacnet/basic/tsm/tsm.h"
|
||||||
#if defined(BACFILE)
|
|
||||||
#include "bacfile.h"
|
|
||||||
#endif
|
|
||||||
#include "mydata.h"
|
|
||||||
#include "ptransfer.h"
|
|
||||||
#include "handlers.h"
|
|
||||||
|
|
||||||
/** @file h_pt.c Handles Confirmed Private Transfer requests. */
|
/** @file h_pt.c Handles Confirmed Private Transfer requests. */
|
||||||
|
|
||||||
@@ -65,8 +59,8 @@ static void ProcessPT(BACNET_PRIVATE_TRANSFER_DATA *data)
|
|||||||
iLen = 0;
|
iLen = 0;
|
||||||
|
|
||||||
/* Decode the block number */
|
/* Decode the block number */
|
||||||
tag_len = decode_tag_number_and_value(&data->serviceParameters[iLen],
|
tag_len = decode_tag_number_and_value(
|
||||||
&tag_number, &len_value_type);
|
&data->serviceParameters[iLen], &tag_number, &len_value_type);
|
||||||
iLen += tag_len;
|
iLen += tag_len;
|
||||||
if (tag_number != BACNET_APPLICATION_TAG_UNSIGNED_INT) {
|
if (tag_number != BACNET_APPLICATION_TAG_UNSIGNED_INT) {
|
||||||
/* Bail out early if wrong type */
|
/* Bail out early if wrong type */
|
||||||
@@ -75,8 +69,8 @@ static void ProcessPT(BACNET_PRIVATE_TRANSFER_DATA *data)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
iLen += decode_unsigned(&data->serviceParameters[iLen], len_value_type,
|
iLen += decode_unsigned(
|
||||||
&ulTemp);
|
&data->serviceParameters[iLen], len_value_type, &ulTemp);
|
||||||
cBlockNumber = (char)ulTemp;
|
cBlockNumber = (char)ulTemp;
|
||||||
if (cBlockNumber < MY_MAX_BLOCK) {
|
if (cBlockNumber < MY_MAX_BLOCK) {
|
||||||
if (data->serviceNumber == MY_SVC_READ) {
|
if (data->serviceNumber == MY_SVC_READ) {
|
||||||
@@ -124,8 +118,8 @@ static void ProcessPT(BACNET_PRIVATE_TRANSFER_DATA *data)
|
|||||||
data->serviceParametersLen = 0;
|
data->serviceParametersLen = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
iLen += decode_unsigned(&data->serviceParameters[iLen],
|
iLen += decode_unsigned(
|
||||||
len_value_type, &ulTemp);
|
&data->serviceParameters[iLen], len_value_type, &ulTemp);
|
||||||
MyData[(int8_t)cBlockNumber].cMyByte1 = (char)ulTemp;
|
MyData[(int8_t)cBlockNumber].cMyByte1 = (char)ulTemp;
|
||||||
|
|
||||||
tag_len = decode_tag_number_and_value(
|
tag_len = decode_tag_number_and_value(
|
||||||
@@ -135,8 +129,8 @@ static void ProcessPT(BACNET_PRIVATE_TRANSFER_DATA *data)
|
|||||||
data->serviceParametersLen = 0;
|
data->serviceParametersLen = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
iLen += decode_unsigned(&data->serviceParameters[iLen],
|
iLen += decode_unsigned(
|
||||||
len_value_type, &ulTemp);
|
&data->serviceParameters[iLen], len_value_type, &ulTemp);
|
||||||
MyData[(int8_t)cBlockNumber].cMyByte2 = (char)ulTemp;
|
MyData[(int8_t)cBlockNumber].cMyByte2 = (char)ulTemp;
|
||||||
|
|
||||||
tag_len = decode_tag_number_and_value(
|
tag_len = decode_tag_number_and_value(
|
||||||
@@ -147,7 +141,7 @@ static void ProcessPT(BACNET_PRIVATE_TRANSFER_DATA *data)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
iLen += decode_real(&data->serviceParameters[iLen],
|
iLen += decode_real(&data->serviceParameters[iLen],
|
||||||
&MyData[(int8_t)cBlockNumber].fMyReal);
|
&MyData[(int8_t)cBlockNumber].fMyReal);
|
||||||
|
|
||||||
tag_len = decode_tag_number_and_value(
|
tag_len = decode_tag_number_and_value(
|
||||||
&data->serviceParameters[iLen], &tag_number, &len_value_type);
|
&data->serviceParameters[iLen], &tag_number, &len_value_type);
|
||||||
@@ -156,11 +150,11 @@ static void ProcessPT(BACNET_PRIVATE_TRANSFER_DATA *data)
|
|||||||
data->serviceParametersLen = 0;
|
data->serviceParametersLen = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
decode_character_string(&data->serviceParameters[iLen],
|
decode_character_string(
|
||||||
len_value_type, &bsTemp);
|
&data->serviceParameters[iLen], len_value_type, &bsTemp);
|
||||||
/* Only copy as much as we can accept */
|
/* Only copy as much as we can accept */
|
||||||
strncpy((char *)MyData[(int8_t)cBlockNumber].sMyString,
|
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 */
|
/* Make sure it is nul terminated */
|
||||||
MyData[(int8_t)cBlockNumber].sMyString[MY_MAX_STR] = '\0';
|
MyData[(int8_t)cBlockNumber].sMyString[MY_MAX_STR] = '\0';
|
||||||
/* Signal success */
|
/* 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,
|
void handler_conf_private_trans(uint8_t *service_request,
|
||||||
BACNET_ADDRESS *src,
|
uint16_t service_len,
|
||||||
BACNET_CONFIRMED_SERVICE_DATA *service_data)
|
BACNET_ADDRESS *src,
|
||||||
|
BACNET_CONFIRMED_SERVICE_DATA *service_data)
|
||||||
{
|
{
|
||||||
BACNET_PRIVATE_TRANSFER_DATA data;
|
BACNET_PRIVATE_TRANSFER_DATA data;
|
||||||
int len;
|
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);
|
datalink_get_my_address(&my_address);
|
||||||
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
|
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
|
||||||
pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address,
|
pdu_len = npdu_encode_pdu(
|
||||||
&npdu_data);
|
&Handler_Transmit_Buffer[0], src, &my_address, &npdu_data);
|
||||||
|
|
||||||
if (service_data->segmented_message) {
|
if (service_data->segmented_message) {
|
||||||
len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||||
service_data->invoke_id,
|
service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED,
|
||||||
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true);
|
true);
|
||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED
|
||||||
fprintf(stderr, "CPT: Segmented Message. Sending Abort!\n");
|
fprintf(stderr, "CPT: Segmented Message. Sending Abort!\n");
|
||||||
#endif
|
#endif
|
||||||
@@ -230,8 +225,7 @@ void handler_conf_private_trans(uint8_t *service_request, uint16_t service_len,
|
|||||||
/* bad decoding - send an abort */
|
/* bad decoding - send an abort */
|
||||||
if (len < 0) {
|
if (len < 0) {
|
||||||
len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||||
service_data->invoke_id, ABORT_REASON_OTHER,
|
service_data->invoke_id, ABORT_REASON_OTHER, true);
|
||||||
true);
|
|
||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED
|
||||||
fprintf(stderr, "CPT: Bad Encoding. Sending Abort!\n");
|
fprintf(stderr, "CPT: Bad Encoding. Sending Abort!\n");
|
||||||
#endif
|
#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");
|
fprintf(stderr, "CPT: Error servicing request!\n");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
len = ptransfer_ack_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
len = ptransfer_ack_encode_apdu(
|
||||||
service_data->invoke_id, &data);
|
&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, &data);
|
||||||
} else { /* Not our vendor ID or bad service parameter */
|
} else { /* Not our vendor ID or bad service parameter */
|
||||||
|
|
||||||
error = true;
|
error = true;
|
||||||
@@ -272,13 +266,12 @@ void handler_conf_private_trans(uint8_t *service_request, uint16_t service_len,
|
|||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
len = ptransfer_error_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
len = ptransfer_error_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||||
service_data->invoke_id, error_class,
|
service_data->invoke_id, error_class, error_code, &data);
|
||||||
error_code, &data);
|
|
||||||
}
|
}
|
||||||
CPT_ABORT:
|
CPT_ABORT:
|
||||||
pdu_len += len;
|
pdu_len += len;
|
||||||
bytes_sent = datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0],
|
bytes_sent = datalink_send_pdu(
|
||||||
pdu_len);
|
src, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len);
|
||||||
|
|
||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED
|
||||||
if (bytes_sent <= 0) {
|
if (bytes_sent <= 0) {
|
||||||
@@ -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 <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#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
|
||||||
@@ -27,21 +27,15 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include "config.h"
|
#include "bacnet/config.h"
|
||||||
#include "txbuf.h"
|
#include "bacnet/bacdef.h"
|
||||||
#include "bacdef.h"
|
#include "bacnet/bacdcode.h"
|
||||||
#include "bacdcode.h"
|
#include "bacnet/apdu.h"
|
||||||
#include "apdu.h"
|
#include "bacnet/npdu.h"
|
||||||
#include "npdu.h"
|
#include "bacnet/abort.h"
|
||||||
#include "abort.h"
|
#include "bacnet/ptransfer.h"
|
||||||
/*#include "arf.h" */
|
#include "bacnet/basic/services.h"
|
||||||
/* demo objects */
|
#include "bacnet/basic/tsm/tsm.h"
|
||||||
#include "ptransfer.h"
|
|
||||||
#include "mydata.h"
|
|
||||||
#if defined(BACFILE)
|
|
||||||
#include "bacfile.h"
|
|
||||||
#endif
|
|
||||||
#include "handlers.h"
|
|
||||||
|
|
||||||
/** @file h_pt_a.c Handles Confirmed Private Transfer Acknowledgment. */
|
/** @file h_pt_a.c Handles Confirmed Private Transfer Acknowledgment. */
|
||||||
|
|
||||||
@@ -96,8 +90,8 @@ static void DecodeBlock(char cBlockNum, uint8_t *pData)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
iLen += decode_character_string(&pData[iLen], len_value_type, &bsName);
|
iLen += decode_character_string(&pData[iLen], len_value_type, &bsName);
|
||||||
strncpy((char *)Response.sMyString, characterstring_value(&bsName),
|
strncpy(
|
||||||
MY_MAX_STR);
|
(char *)Response.sMyString, characterstring_value(&bsName), MY_MAX_STR);
|
||||||
Response.sMyString[MY_MAX_STR] = '\0'; /* Make sure it is nul terminated */
|
Response.sMyString[MY_MAX_STR] = '\0'; /* Make sure it is nul terminated */
|
||||||
|
|
||||||
printf("Private Transfer Read Block Response\n");
|
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 */
|
/* Error code is returned for read and write operations */
|
||||||
|
|
||||||
tag_len = decode_tag_number_and_value(&data->serviceParameters[iLen],
|
tag_len = decode_tag_number_and_value(
|
||||||
&tag_number, &len_value_type);
|
&data->serviceParameters[iLen], &tag_number, &len_value_type);
|
||||||
iLen += tag_len;
|
iLen += tag_len;
|
||||||
if (tag_number != BACNET_APPLICATION_TAG_UNSIGNED_INT) {
|
if (tag_number != BACNET_APPLICATION_TAG_UNSIGNED_INT) {
|
||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED
|
||||||
@@ -131,8 +125,8 @@ static void ProcessPTA(BACNET_PRIVATE_TRANSFER_DATA *data)
|
|||||||
#endif
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
iLen += decode_unsigned(&data->serviceParameters[iLen], len_value_type,
|
iLen += decode_unsigned(
|
||||||
&uiErrorCode);
|
&data->serviceParameters[iLen], len_value_type, &uiErrorCode);
|
||||||
|
|
||||||
if (data->serviceNumber == MY_SVC_READ) { /* Read I/O block so should be
|
if (data->serviceNumber == MY_SVC_READ) { /* Read I/O block so should be
|
||||||
full block of data or error */
|
full block of data or error */
|
||||||
@@ -151,18 +145,18 @@ static void ProcessPTA(BACNET_PRIVATE_TRANSFER_DATA *data)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
iLen += decode_unsigned(&data->serviceParameters[iLen],
|
iLen += decode_unsigned(
|
||||||
len_value_type, &ulTemp);
|
&data->serviceParameters[iLen], len_value_type, &ulTemp);
|
||||||
cBlockNumber = (char)ulTemp;
|
cBlockNumber = (char)ulTemp;
|
||||||
DecodeBlock(cBlockNumber, &data->serviceParameters[iLen]);
|
DecodeBlock(cBlockNumber, &data->serviceParameters[iLen]);
|
||||||
} else { /* Read error */
|
} else { /* Read error */
|
||||||
printf("Private Transfer read operation returned error code: %lu\n",
|
printf("Private Transfer read operation returned error code: %lu\n",
|
||||||
(unsigned long)uiErrorCode);
|
(unsigned long)uiErrorCode);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else { /* Write I/O block - should just be an OK type message */
|
} else { /* Write I/O block - should just be an OK type message */
|
||||||
printf("Private Transfer write operation returned error code: %lu\n",
|
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...
|
* and decide what to do next...
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void handler_conf_private_trans_ack(
|
void handler_conf_private_trans_ack(uint8_t *service_request,
|
||||||
uint8_t *service_request, uint16_t service_len, BACNET_ADDRESS *src,
|
uint16_t service_len,
|
||||||
|
BACNET_ADDRESS *src,
|
||||||
BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data)
|
BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data)
|
||||||
{
|
{
|
||||||
BACNET_PRIVATE_TRANSFER_DATA data;
|
BACNET_PRIVATE_TRANSFER_DATA data;
|
||||||
@@ -195,8 +190,7 @@ void handler_conf_private_trans_ack(
|
|||||||
printf("Received Confirmed Private Transfer Ack!\n");
|
printf("Received Confirmed Private Transfer Ack!\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
len = ptransfer_decode_service_request(
|
len = ptransfer_decode_service_request(service_request, service_len,
|
||||||
service_request, service_len,
|
|
||||||
&data); /* Same decode for ack as for service request! */
|
&data); /* Same decode for ack as for service request! */
|
||||||
if (len < 0) {
|
if (len < 0) {
|
||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED
|
||||||
@@ -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 <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#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
|
||||||
@@ -28,48 +28,54 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <time.h> /* for time */
|
#include <time.h> /* for time */
|
||||||
#include <ctype.h> /* for tupper */
|
#include <ctype.h> /* for tupper */
|
||||||
#if defined(WIN32) || defined(__BORLANDC__)
|
#if defined(WIN32) || defined(__BORLANDC__)
|
||||||
#include <conio.h>
|
#include <conio.h>
|
||||||
#endif
|
#endif
|
||||||
#define PRINT_ENABLED 1
|
#define PRINT_ENABLED 1
|
||||||
|
|
||||||
#include "bacdef.h"
|
#include "bacnet/bacdef.h"
|
||||||
#include "config.h"
|
#include "bacnet/config.h"
|
||||||
#include "bactext.h"
|
#include "bacnet/bactext.h"
|
||||||
#include "bacerror.h"
|
#include "bacnet/bacerror.h"
|
||||||
#include "iam.h"
|
#include "bacnet/iam.h"
|
||||||
#include "arf.h"
|
#include "bacnet/arf.h"
|
||||||
#include "tsm.h"
|
#include "bacnet/npdu.h"
|
||||||
#include "address.h"
|
#include "bacnet/apdu.h"
|
||||||
#include "npdu.h"
|
#include "bacnet/whois.h"
|
||||||
#include "apdu.h"
|
|
||||||
#include "device.h"
|
|
||||||
#include "net.h"
|
|
||||||
#include "datalink.h"
|
|
||||||
#include "whois.h"
|
|
||||||
/* some demo stuff needed */
|
/* some demo stuff needed */
|
||||||
#include "filename.h"
|
#include "bacnet/basic/tsm/tsm.h"
|
||||||
#include "handlers.h"
|
#include "bacnet/basic/binding/address.h"
|
||||||
#include "client.h"
|
#include "bacnet/basic/object/device.h"
|
||||||
#include "txbuf.h"
|
#include "bacnet/basic/sys/filename.h"
|
||||||
#include "dlenv.h"
|
#include "bacnet/basic/services.h"
|
||||||
#include "mydata.h"
|
#include "bacnet/datalink/datalink.h"
|
||||||
|
#include "bacnet/datalink/dlenv.h"
|
||||||
|
|
||||||
#if defined(__BORLANDC__)
|
#if defined(__BORLANDC__)
|
||||||
#define _kbhit kbhit
|
#define _kbhit kbhit
|
||||||
#define _stricmp stricmp
|
#define _stricmp stricmp
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern uint8_t Send_Private_Transfer_Request(uint32_t device_id,
|
#define MY_MAX_STR 32
|
||||||
uint16_t vendor_id,
|
#define MY_MAX_BLOCK 8
|
||||||
uint32_t service_number,
|
|
||||||
char block_number,
|
#define MY_SVC_READ 0
|
||||||
DATABLOCK *block);
|
#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 */
|
/* 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 */
|
/* global variables used in this file */
|
||||||
static uint32_t Target_Device_Object_Instance = BACNET_MAX_INSTANCE;
|
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 BACNET_ADDRESS Target_Address;
|
||||||
static bool Error_Detected = false;
|
static bool Error_Detected = false;
|
||||||
|
|
||||||
static void MyErrorHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
|
static void MyErrorHandler(BACNET_ADDRESS *src,
|
||||||
BACNET_ERROR_CLASS error_class,
|
uint8_t invoke_id,
|
||||||
BACNET_ERROR_CODE error_code)
|
BACNET_ERROR_CLASS error_class,
|
||||||
|
BACNET_ERROR_CODE error_code)
|
||||||
{
|
{
|
||||||
/* FIXME: verify src and invoke id */
|
/* FIXME: verify src and invoke id */
|
||||||
(void)src;
|
(void)src;
|
||||||
(void)invoke_id;
|
(void)invoke_id;
|
||||||
printf("BACnet Error: %s: %s\r\n",
|
printf("BACnet Error: %s: %s\r\n",
|
||||||
bactext_error_class_name((int)error_class),
|
bactext_error_class_name((int)error_class),
|
||||||
bactext_error_code_name((int)error_code));
|
bactext_error_code_name((int)error_code));
|
||||||
/* Error_Detected = true; */
|
/* Error_Detected = true; */
|
||||||
}
|
}
|
||||||
|
|
||||||
void MyAbortHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
|
static void MyAbortHandler(
|
||||||
uint8_t abort_reason, bool server)
|
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t abort_reason, bool server)
|
||||||
{
|
{
|
||||||
/* FIXME: verify src and invoke id */
|
/* FIXME: verify src and invoke id */
|
||||||
(void)src;
|
(void)src;
|
||||||
(void)invoke_id;
|
(void)invoke_id;
|
||||||
(void)server;
|
(void)server;
|
||||||
printf("BACnet Abort: %s\r\n",
|
printf(
|
||||||
bactext_abort_reason_name((int)abort_reason));
|
"BACnet Abort: %s\r\n", bactext_abort_reason_name((int)abort_reason));
|
||||||
Error_Detected = true;
|
Error_Detected = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
|
static void MyRejectHandler(
|
||||||
uint8_t reject_reason)
|
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||||
{
|
{
|
||||||
/* FIXME: verify src and invoke id */
|
/* FIXME: verify src and invoke id */
|
||||||
(void)src;
|
(void)src;
|
||||||
(void)invoke_id;
|
(void)invoke_id;
|
||||||
printf("BACnet Reject: %s\r\n",
|
printf("BACnet Reject: %s\r\n",
|
||||||
bactext_reject_reason_name((int)reject_reason));
|
bactext_reject_reason_name((int)reject_reason));
|
||||||
Error_Detected = true;
|
Error_Detected = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -127,17 +134,17 @@ static void Init_Service_Handlers(void)
|
|||||||
It is required to send the proper reject message... */
|
It is required to send the proper reject message... */
|
||||||
apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service);
|
apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service);
|
||||||
/* we must implement read property - it's required! */
|
/* we must implement read property - it's required! */
|
||||||
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY,
|
apdu_set_confirmed_handler(
|
||||||
handler_read_property);
|
SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property);
|
||||||
|
|
||||||
apdu_set_confirmed_handler(SERVICE_CONFIRMED_PRIVATE_TRANSFER,
|
apdu_set_confirmed_handler(
|
||||||
handler_conf_private_trans);
|
SERVICE_CONFIRMED_PRIVATE_TRANSFER, handler_conf_private_trans);
|
||||||
/* handle the data coming back from confirmed requests */
|
/* handle the data coming back from confirmed requests */
|
||||||
apdu_set_confirmed_ack_handler(SERVICE_CONFIRMED_READ_PROPERTY,
|
apdu_set_confirmed_ack_handler(
|
||||||
handler_read_property_ack);
|
SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property_ack);
|
||||||
|
|
||||||
apdu_set_confirmed_ack_handler(SERVICE_CONFIRMED_PRIVATE_TRANSFER,
|
apdu_set_confirmed_ack_handler(
|
||||||
handler_conf_private_trans_ack);
|
SERVICE_CONFIRMED_PRIVATE_TRANSFER, handler_conf_private_trans_ack);
|
||||||
|
|
||||||
/* handle any errors coming back */
|
/* handle any errors coming back */
|
||||||
apdu_set_error_handler(SERVICE_CONFIRMED_READ_PROPERTY, MyErrorHandler);
|
apdu_set_error_handler(SERVICE_CONFIRMED_READ_PROPERTY, MyErrorHandler);
|
||||||
@@ -146,9 +153,22 @@ static void Init_Service_Handlers(void)
|
|||||||
apdu_set_reject_handler(MyRejectHandler);
|
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[])
|
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;
|
uint16_t pdu_len = 0;
|
||||||
unsigned timeout = 100; /* milliseconds */
|
unsigned timeout = 100; /* milliseconds */
|
||||||
unsigned max_apdu = 0;
|
unsigned max_apdu = 0;
|
||||||
@@ -166,9 +186,8 @@ int main(int argc, char *argv[])
|
|||||||
if (((argc != 2) && (argc != 3)) ||
|
if (((argc != 2) && (argc != 3)) ||
|
||||||
((argc >= 2) && (strcmp(argv[1], "--help") == 0))) {
|
((argc >= 2) && (strcmp(argv[1], "--help") == 0))) {
|
||||||
printf("%s\n", argv[0]);
|
printf("%s\n", argv[0]);
|
||||||
printf(
|
printf("Usage: %s server local-device-instance\r\n or\r\n"
|
||||||
"Usage: %s server local-device-instance\r\n or\r\n"
|
" %s remote-device-instance\r\n",
|
||||||
" %s remote-device-instance\r\n",
|
|
||||||
filename_remove_path(argv[0]), filename_remove_path(argv[0]));
|
filename_remove_path(argv[0]), filename_remove_path(argv[0]));
|
||||||
if ((argc > 1) && (strcmp(argv[1], "--help") == 0)) {
|
if ((argc > 1) && (strcmp(argv[1], "--help") == 0)) {
|
||||||
printf(
|
printf(
|
||||||
@@ -194,24 +213,27 @@ int main(int argc, char *argv[])
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/* decode the command line parameters */
|
/* decode the command line parameters */
|
||||||
if (_stricmp(argv[1], "server") == 0)
|
if (_stricmp(argv[1], "server") == 0) {
|
||||||
Target_Mode = 1;
|
Target_Mode = 1;
|
||||||
else
|
} else {
|
||||||
Target_Mode = 0;
|
Target_Mode = 0;
|
||||||
|
}
|
||||||
|
|
||||||
Target_Device_Object_Instance = strtol(argv[1 + Target_Mode], NULL, 0);
|
Target_Device_Object_Instance = strtol(argv[1 + Target_Mode], NULL, 0);
|
||||||
|
|
||||||
if (Target_Device_Object_Instance > BACNET_MAX_INSTANCE) {
|
if (Target_Device_Object_Instance > BACNET_MAX_INSTANCE) {
|
||||||
fprintf(stderr, "device-instance=%u - it must be less than %u\r\n",
|
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;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* setup my info */
|
/* setup my info */
|
||||||
if (Target_Mode)
|
if (Target_Mode) {
|
||||||
Device_Set_Object_Instance_Number(Target_Device_Object_Instance);
|
Device_Set_Object_Instance_Number(Target_Device_Object_Instance);
|
||||||
else
|
} else {
|
||||||
Device_Set_Object_Instance_Number(BACNET_MAX_INSTANCE);
|
Device_Set_Object_Instance_Number
|
||||||
|
}
|
||||||
|
(BACNET_MAX_INSTANCE);
|
||||||
|
|
||||||
address_init();
|
address_init();
|
||||||
Init_Service_Handlers();
|
Init_Service_Handlers();
|
||||||
@@ -255,11 +277,11 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* try to bind with the device */
|
/* try to bind with the device */
|
||||||
found = address_bind_request(Target_Device_Object_Instance, &max_apdu,
|
found = address_bind_request(
|
||||||
&Target_Address);
|
Target_Device_Object_Instance, &max_apdu, &Target_Address);
|
||||||
if (!found) {
|
if (!found) {
|
||||||
Send_WhoIs(Target_Device_Object_Instance,
|
Send_WhoIs(
|
||||||
Target_Device_Object_Instance);
|
Target_Device_Object_Instance, Target_Device_Object_Instance);
|
||||||
}
|
}
|
||||||
/* loop forever */
|
/* loop forever */
|
||||||
for (;;) {
|
for (;;) {
|
||||||
@@ -274,15 +296,16 @@ int main(int argc, char *argv[])
|
|||||||
npdu_handler(&src, &Rx_Buf[0], pdu_len);
|
npdu_handler(&src, &Rx_Buf[0], pdu_len);
|
||||||
}
|
}
|
||||||
/* at least one second has passed */
|
/* at least one second has passed */
|
||||||
if (current_seconds != last_seconds)
|
if (current_seconds != last_seconds) {
|
||||||
tsm_timer_milliseconds(
|
tsm_timer_milliseconds(
|
||||||
((current_seconds - last_seconds) * 1000));
|
((current_seconds - last_seconds) * 1000));
|
||||||
|
}
|
||||||
if (Error_Detected)
|
if (Error_Detected)
|
||||||
break;
|
break;
|
||||||
/* wait until the device is bound, or timeout and quit */
|
/* wait until the device is bound, or timeout and quit */
|
||||||
if (!found)
|
if (!found)
|
||||||
found = address_bind_request(Target_Device_Object_Instance,
|
found = address_bind_request(
|
||||||
&max_apdu, &Target_Address);
|
Target_Device_Object_Instance, &max_apdu, &Target_Address);
|
||||||
if (found) {
|
if (found) {
|
||||||
if (invoke_id == 0) { /* Safe to send a new request */
|
if (invoke_id == 0) { /* Safe to send a new request */
|
||||||
switch (iType) {
|
switch (iType) {
|
||||||
@@ -290,10 +313,11 @@ int main(int argc, char *argv[])
|
|||||||
NewData.cMyByte1 = iCount;
|
NewData.cMyByte1 = iCount;
|
||||||
NewData.cMyByte2 = 255 - iCount;
|
NewData.cMyByte2 = 255 - iCount;
|
||||||
NewData.fMyReal = (float)iCount;
|
NewData.fMyReal = (float)iCount;
|
||||||
strcpy((char *)NewData.sMyString,
|
strcpy(
|
||||||
"Test Data - [x]");
|
(char *)NewData.sMyString, "Test Data - [x]");
|
||||||
NewData.sMyString[13] = 'a' + iCount;
|
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(
|
invoke_id = Send_Private_Transfer_Request(
|
||||||
Target_Device_Object_Instance, BACNET_VENDOR_ID,
|
Target_Device_Object_Instance, BACNET_VENDOR_ID,
|
||||||
1, iCount, &NewData);
|
1, iCount, &NewData);
|
||||||
@@ -326,9 +350,8 @@ int main(int argc, char *argv[])
|
|||||||
case 3:
|
case 3:
|
||||||
case 5:
|
case 5:
|
||||||
case 7:
|
case 7:
|
||||||
printf(
|
printf("Requesting block %d with invalid "
|
||||||
"Requesting block %d with invalid "
|
"Vendor ID\n",
|
||||||
"Vendor ID\n",
|
|
||||||
iCount);
|
iCount);
|
||||||
invoke_id = Send_Private_Transfer_Request(
|
invoke_id = Send_Private_Transfer_Request(
|
||||||
Target_Device_Object_Instance,
|
Target_Device_Object_Instance,
|
||||||
@@ -348,8 +371,9 @@ int main(int argc, char *argv[])
|
|||||||
iCount = 0;
|
iCount = 0;
|
||||||
invoke_id = 0;
|
invoke_id = 0;
|
||||||
|
|
||||||
if (iType > 2)
|
if (iType > 2) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (tsm_invoke_id_failed(invoke_id)) {
|
} else if (tsm_invoke_id_failed(invoke_id)) {
|
||||||
fprintf(stderr, "\rError: TSM Timeout!\r\n");
|
fprintf(stderr, "\rError: TSM Timeout!\r\n");
|
||||||
@@ -0,0 +1,123 @@
|
|||||||
|
/**************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright (C) 2006 Steve Karg <skarg@users.sourceforge.net>
|
||||||
|
*
|
||||||
|
* 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 <stdlib.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <string.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 "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;
|
||||||
|
}
|
||||||
@@ -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 <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#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
|
||||||
@@ -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
|
||||||
|
|
||||||
@@ -31,29 +31,29 @@
|
|||||||
#include <time.h> /* for time */
|
#include <time.h> /* for time */
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <ctype.h> /* for toupper */
|
#include <ctype.h> /* for toupper */
|
||||||
#include "bactext.h"
|
#include "bacnet/bactext.h"
|
||||||
#include "iam.h"
|
#include "bacnet/iam.h"
|
||||||
#include "address.h"
|
#include "bacnet/basic/binding/address.h"
|
||||||
#include "config.h"
|
#include "bacnet/config.h"
|
||||||
#include "bacdef.h"
|
#include "bacnet/bacdef.h"
|
||||||
#include "npdu.h"
|
#include "bacnet/npdu.h"
|
||||||
#include "apdu.h"
|
#include "bacnet/apdu.h"
|
||||||
#include "device.h"
|
#include "bacnet/basic/object/device.h"
|
||||||
#include "datalink.h"
|
#include "bacnet/datalink/datalink.h"
|
||||||
#include "bvlc.h"
|
#include "bacnet/datalink/bvlc.h"
|
||||||
/* some demo stuff needed */
|
/* some demo stuff needed */
|
||||||
#ifndef DEBUG_ENABLED
|
#ifndef DEBUG_ENABLED
|
||||||
#define DEBUG_ENABLED 0
|
#define DEBUG_ENABLED 0
|
||||||
#endif
|
#endif
|
||||||
#include "debug.h"
|
#include "bacnet/basic/sys/debug.h"
|
||||||
#include "filename.h"
|
#include "bacnet/basic/sys/filename.h"
|
||||||
#include "handlers.h"
|
#include "bacnet/basic/services.h"
|
||||||
#include "client.h"
|
#include "bacnet/basic/services.h"
|
||||||
#include "txbuf.h"
|
#include "bacnet/basic/tsm/tsm.h"
|
||||||
#include "dlenv.h"
|
#include "bacnet/datalink/dlenv.h"
|
||||||
|
|
||||||
/* buffer used for receive */
|
/* 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 */
|
/* targets interpreted from the command line options */
|
||||||
static uint32_t Target_BBMD_Address;
|
static uint32_t Target_BBMD_Address;
|
||||||
@@ -61,8 +61,8 @@ static uint16_t Target_BBMD_Port;
|
|||||||
|
|
||||||
static bool Error_Detected = false;
|
static bool Error_Detected = false;
|
||||||
|
|
||||||
static void MyAbortHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
|
static void MyAbortHandler(
|
||||||
uint8_t abort_reason, bool server)
|
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t abort_reason, bool server)
|
||||||
{
|
{
|
||||||
/* FIXME: verify src and invoke id */
|
/* FIXME: verify src and invoke id */
|
||||||
(void)src;
|
(void)src;
|
||||||
@@ -72,8 +72,8 @@ static void MyAbortHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
|
|||||||
Error_Detected = true;
|
Error_Detected = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
|
static void MyRejectHandler(
|
||||||
uint8_t reject_reason)
|
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||||
{
|
{
|
||||||
/* FIXME: verify src and invoke id */
|
/* FIXME: verify src and invoke id */
|
||||||
(void)src;
|
(void)src;
|
||||||
@@ -92,8 +92,8 @@ static void Init_Service_Handlers(void)
|
|||||||
It is required to send the proper reject message... */
|
It is required to send the proper reject message... */
|
||||||
apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service);
|
apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service);
|
||||||
/* we must implement read property - it's required! */
|
/* we must implement read property - it's required! */
|
||||||
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY,
|
apdu_set_confirmed_handler(
|
||||||
handler_read_property);
|
SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property);
|
||||||
/* handle the reply (request) coming back */
|
/* handle the reply (request) coming back */
|
||||||
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_I_AM, handler_i_am_add);
|
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_I_AM, handler_i_am_add);
|
||||||
/* handle any errors coming back */
|
/* handle any errors coming back */
|
||||||
@@ -103,7 +103,7 @@ static void Init_Service_Handlers(void)
|
|||||||
|
|
||||||
int main(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;
|
uint16_t pdu_len = 0;
|
||||||
unsigned timeout = 100; /* milliseconds */
|
unsigned timeout = 100; /* milliseconds */
|
||||||
time_t total_seconds = 0;
|
time_t total_seconds = 0;
|
||||||
@@ -145,8 +145,8 @@ int main(int argc, char *argv[])
|
|||||||
if ((port > 0) && (port <= 65535)) {
|
if ((port > 0) && (port <= 65535)) {
|
||||||
Target_BBMD_Port = htons(port);
|
Target_BBMD_Port = htons(port);
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "port=%ld - port must be between 0-65535.\r\n",
|
fprintf(
|
||||||
port);
|
stderr, "port=%ld - port must be between 0-65535.\r\n", port);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -183,8 +183,9 @@ int main(int argc, char *argv[])
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
total_seconds += elapsed_seconds;
|
total_seconds += elapsed_seconds;
|
||||||
if (total_seconds > timeout_seconds)
|
if (total_seconds > timeout_seconds) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
/* keep track of time for next check */
|
/* keep track of time for next check */
|
||||||
last_seconds = current_seconds;
|
last_seconds = current_seconds;
|
||||||
}
|
}
|
||||||
@@ -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
|
||||||
|
|
||||||
@@ -30,29 +30,29 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <time.h> /* for time */
|
#include <time.h> /* for time */
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include "bactext.h"
|
#include "bacnet/bactext.h"
|
||||||
#include "iam.h"
|
#include "bacnet/iam.h"
|
||||||
#include "arf.h"
|
#include "bacnet/arf.h"
|
||||||
#include "tsm.h"
|
#include "bacnet/basic/tsm/tsm.h"
|
||||||
#include "address.h"
|
#include "bacnet/basic/binding/address.h"
|
||||||
#include "config.h"
|
#include "bacnet/config.h"
|
||||||
#include "bacdef.h"
|
#include "bacnet/bacdef.h"
|
||||||
#include "npdu.h"
|
#include "bacnet/npdu.h"
|
||||||
#include "apdu.h"
|
#include "bacnet/apdu.h"
|
||||||
#include "device.h"
|
#include "bacnet/basic/object/device.h"
|
||||||
#include "net.h"
|
#include "bacport.h"
|
||||||
#include "datalink.h"
|
#include "bacnet/datalink/datalink.h"
|
||||||
#include "whois.h"
|
#include "bacnet/whois.h"
|
||||||
#include "version.h"
|
#include "bacnet/version.h"
|
||||||
/* some demo stuff needed */
|
/* some demo stuff needed */
|
||||||
#include "filename.h"
|
#include "bacnet/basic/sys/filename.h"
|
||||||
#include "handlers.h"
|
#include "bacnet/basic/services.h"
|
||||||
#include "client.h"
|
#include "bacnet/basic/services.h"
|
||||||
#include "txbuf.h"
|
#include "bacnet/basic/tsm/tsm.h"
|
||||||
#include "dlenv.h"
|
#include "bacnet/datalink/dlenv.h"
|
||||||
|
|
||||||
/* buffer used for receive */
|
/* 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 */
|
/* global variables used in this file */
|
||||||
static uint32_t Target_File_Object_Instance = BACNET_MAX_INSTANCE;
|
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 uint8_t Request_Invoke_ID = 0;
|
||||||
|
|
||||||
static void Atomic_Read_File_Error_Handler(BACNET_ADDRESS *src,
|
static void Atomic_Read_File_Error_Handler(BACNET_ADDRESS *src,
|
||||||
uint8_t invoke_id,
|
uint8_t invoke_id,
|
||||||
BACNET_ERROR_CLASS error_class,
|
BACNET_ERROR_CLASS error_class,
|
||||||
BACNET_ERROR_CODE error_code)
|
BACNET_ERROR_CODE error_code)
|
||||||
{
|
{
|
||||||
if (address_match(&Target_Address, src) &&
|
if (address_match(&Target_Address, src) &&
|
||||||
(invoke_id == Request_Invoke_ID)) {
|
(invoke_id == Request_Invoke_ID)) {
|
||||||
printf("BACnet Error: %s: %s\n",
|
printf("BACnet Error: %s: %s\n",
|
||||||
bactext_error_class_name((int)error_class),
|
bactext_error_class_name((int)error_class),
|
||||||
bactext_error_code_name((int)error_code));
|
bactext_error_code_name((int)error_code));
|
||||||
Error_Detected = true;
|
Error_Detected = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MyAbortHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
|
static void MyAbortHandler(
|
||||||
uint8_t abort_reason, bool server)
|
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t abort_reason, bool server)
|
||||||
{
|
{
|
||||||
(void)server;
|
(void)server;
|
||||||
if (address_match(&Target_Address, src) &&
|
if (address_match(&Target_Address, src) &&
|
||||||
(invoke_id == Request_Invoke_ID)) {
|
(invoke_id == Request_Invoke_ID)) {
|
||||||
printf("BACnet Abort: %s\n",
|
printf(
|
||||||
bactext_abort_reason_name((int)abort_reason));
|
"BACnet Abort: %s\n", bactext_abort_reason_name((int)abort_reason));
|
||||||
Error_Detected = true;
|
Error_Detected = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
|
static void MyRejectHandler(
|
||||||
uint8_t reject_reason)
|
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||||
{
|
{
|
||||||
if (address_match(&Target_Address, src) &&
|
if (address_match(&Target_Address, src) &&
|
||||||
(invoke_id == Request_Invoke_ID)) {
|
(invoke_id == Request_Invoke_ID)) {
|
||||||
printf("BACnet Reject: %s\n",
|
printf("BACnet Reject: %s\n",
|
||||||
bactext_reject_reason_name((int)reject_reason));
|
bactext_reject_reason_name((int)reject_reason));
|
||||||
Error_Detected = true;
|
Error_Detected = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void AtomicReadFileAckHandler(
|
static void AtomicReadFileAckHandler(uint8_t *service_request,
|
||||||
uint8_t *service_request, uint16_t service_len, BACNET_ADDRESS *src,
|
uint16_t service_len,
|
||||||
|
BACNET_ADDRESS *src,
|
||||||
BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data)
|
BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data)
|
||||||
{
|
{
|
||||||
int len = 0;
|
int len = 0;
|
||||||
@@ -130,12 +131,12 @@ static void AtomicReadFileAckHandler(
|
|||||||
in our case, an octet is one byte */
|
in our case, an octet is one byte */
|
||||||
octets_written =
|
octets_written =
|
||||||
fwrite(octetstring_value(&data.fileData[0]), 1,
|
fwrite(octetstring_value(&data.fileData[0]), 1,
|
||||||
octetstring_length(&data.fileData[0]), pFile);
|
octetstring_length(&data.fileData[0]), pFile);
|
||||||
if (octets_written !=
|
if (octets_written !=
|
||||||
octetstring_length(&data.fileData[0])) {
|
octetstring_length(&data.fileData[0])) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Unable to write data to file \"%s\".\n",
|
"Unable to write data to file \"%s\".\n",
|
||||||
Local_File_Name);
|
Local_File_Name);
|
||||||
} else if (octets_written == 0) {
|
} else if (octets_written == 0) {
|
||||||
fprintf(stderr, "Received 0 byte octet string!.\n");
|
fprintf(stderr, "Received 0 byte octet string!.\n");
|
||||||
} else {
|
} else {
|
||||||
@@ -146,7 +147,7 @@ static void AtomicReadFileAckHandler(
|
|||||||
fflush(pFile);
|
fflush(pFile);
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "Unable to seek to %d!\n",
|
fprintf(stderr, "Unable to seek to %d!\n",
|
||||||
data.type.stream.fileStartPosition);
|
data.type.stream.fileStartPosition);
|
||||||
}
|
}
|
||||||
fclose(pFile);
|
fclose(pFile);
|
||||||
}
|
}
|
||||||
@@ -159,12 +160,12 @@ static void AtomicReadFileAckHandler(
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "Address & Invoke ID mismatch! Invoke ID=%d\n",
|
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,
|
static void LocalIAmHandler(
|
||||||
BACNET_ADDRESS *src)
|
uint8_t *service_request, uint16_t service_len, BACNET_ADDRESS *src)
|
||||||
{
|
{
|
||||||
int len = 0;
|
int len = 0;
|
||||||
uint32_t device_id = 0;
|
uint32_t device_id = 0;
|
||||||
@@ -174,12 +175,13 @@ static void LocalIAmHandler(uint8_t *service_request, uint16_t service_len,
|
|||||||
|
|
||||||
(void)src;
|
(void)src;
|
||||||
(void)service_len;
|
(void)service_len;
|
||||||
len = iam_decode_service_request(service_request, &device_id, &max_apdu,
|
len = iam_decode_service_request(
|
||||||
&segmentation, &vendor_id);
|
service_request, &device_id, &max_apdu, &segmentation, &vendor_id);
|
||||||
if (len != -1) {
|
if (len != -1) {
|
||||||
address_add(device_id, max_apdu, src);
|
address_add(device_id, max_apdu, src);
|
||||||
} else
|
} else {
|
||||||
fprintf(stderr, "!\n");
|
fprintf(stderr, "!\n");
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -196,14 +198,14 @@ static void Init_Service_Handlers(void)
|
|||||||
It is required to send the proper reject message... */
|
It is required to send the proper reject message... */
|
||||||
apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service);
|
apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service);
|
||||||
/* we must implement read property - it's required! */
|
/* we must implement read property - it's required! */
|
||||||
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY,
|
apdu_set_confirmed_handler(
|
||||||
handler_read_property);
|
SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property);
|
||||||
/* handle the data coming back from confirmed requests */
|
/* handle the data coming back from confirmed requests */
|
||||||
apdu_set_confirmed_ack_handler(SERVICE_CONFIRMED_ATOMIC_READ_FILE,
|
apdu_set_confirmed_ack_handler(
|
||||||
AtomicReadFileAckHandler);
|
SERVICE_CONFIRMED_ATOMIC_READ_FILE, AtomicReadFileAckHandler);
|
||||||
/* handle any errors coming back */
|
/* handle any errors coming back */
|
||||||
apdu_set_error_handler(SERVICE_CONFIRMED_ATOMIC_READ_FILE,
|
apdu_set_error_handler(
|
||||||
Atomic_Read_File_Error_Handler);
|
SERVICE_CONFIRMED_ATOMIC_READ_FILE, Atomic_Read_File_Error_Handler);
|
||||||
apdu_set_abort_handler(MyAbortHandler);
|
apdu_set_abort_handler(MyAbortHandler);
|
||||||
apdu_set_reject_handler(MyRejectHandler);
|
apdu_set_reject_handler(MyRejectHandler);
|
||||||
}
|
}
|
||||||
@@ -241,7 +243,7 @@ static void print_help(char *filename)
|
|||||||
|
|
||||||
int main(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;
|
uint16_t pdu_len = 0;
|
||||||
unsigned timeout = 100; /* milliseconds */
|
unsigned timeout = 100; /* milliseconds */
|
||||||
unsigned max_apdu = 0;
|
unsigned max_apdu = 0;
|
||||||
@@ -265,12 +267,11 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
if (strcmp(argv[argi], "--version") == 0) {
|
if (strcmp(argv[argi], "--version") == 0) {
|
||||||
printf("%s %s\n", filename, BACNET_VERSION_TEXT);
|
printf("%s %s\n", filename, BACNET_VERSION_TEXT);
|
||||||
printf(
|
printf("Copyright (C) 2014 by Steve Karg and others.\n"
|
||||||
"Copyright (C) 2014 by Steve Karg and others.\n"
|
"This is free software; see the source for copying "
|
||||||
"This is free software; see the source for copying "
|
"conditions.\n"
|
||||||
"conditions.\n"
|
"There is NO warranty; not even for MERCHANTABILITY or\n"
|
||||||
"There is NO warranty; not even for MERCHANTABILITY or\n"
|
"FITNESS FOR A PARTICULAR PURPOSE.\n");
|
||||||
"FITNESS FOR A PARTICULAR PURPOSE.\n");
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -284,12 +285,12 @@ int main(int argc, char *argv[])
|
|||||||
Local_File_Name = argv[3];
|
Local_File_Name = argv[3];
|
||||||
if (Target_Device_Object_Instance >= BACNET_MAX_INSTANCE) {
|
if (Target_Device_Object_Instance >= BACNET_MAX_INSTANCE) {
|
||||||
fprintf(stderr, "device-instance=%u - it must be less than %u\n",
|
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;
|
return 1;
|
||||||
}
|
}
|
||||||
if (Target_File_Object_Instance >= BACNET_MAX_INSTANCE) {
|
if (Target_File_Object_Instance >= BACNET_MAX_INSTANCE) {
|
||||||
fprintf(stderr, "file-instance=%u - it must be less than %u\n",
|
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;
|
return 1;
|
||||||
}
|
}
|
||||||
/* setup my info */
|
/* setup my info */
|
||||||
@@ -302,11 +303,11 @@ int main(int argc, char *argv[])
|
|||||||
last_seconds = time(NULL);
|
last_seconds = time(NULL);
|
||||||
timeout_seconds = (apdu_timeout() / 1000) * apdu_retries();
|
timeout_seconds = (apdu_timeout() / 1000) * apdu_retries();
|
||||||
/* try to bind with the device */
|
/* try to bind with the device */
|
||||||
found = address_bind_request(Target_Device_Object_Instance, &max_apdu,
|
found = address_bind_request(
|
||||||
&Target_Address);
|
Target_Device_Object_Instance, &max_apdu, &Target_Address);
|
||||||
if (!found) {
|
if (!found) {
|
||||||
Send_WhoIs(Target_Device_Object_Instance,
|
Send_WhoIs(
|
||||||
Target_Device_Object_Instance);
|
Target_Device_Object_Instance, Target_Device_Object_Instance);
|
||||||
}
|
}
|
||||||
/* loop forever */
|
/* loop forever */
|
||||||
for (;;) {
|
for (;;) {
|
||||||
@@ -326,8 +327,8 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
/* wait until the device is bound, or timeout and quit */
|
/* wait until the device is bound, or timeout and quit */
|
||||||
if (!found) {
|
if (!found) {
|
||||||
found = address_bind_request(Target_Device_Object_Instance,
|
found = address_bind_request(
|
||||||
&max_apdu, &Target_Address);
|
Target_Device_Object_Instance, &max_apdu, &Target_Address);
|
||||||
}
|
}
|
||||||
if (found) {
|
if (found) {
|
||||||
/* calculate the smaller of our APDU size or theirs
|
/* 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 */
|
/* the ACK will increment the start position if OK */
|
||||||
/* we'll read the file in chunks
|
/* we'll read the file in chunks
|
||||||
less than max_apdu to keep unsegmented */
|
less than max_apdu to keep unsegmented */
|
||||||
invoke_id = Send_Atomic_Read_File_Stream(
|
invoke_id =
|
||||||
Target_Device_Object_Instance, Target_File_Object_Instance,
|
Send_Atomic_Read_File_Stream(Target_Device_Object_Instance,
|
||||||
Target_File_Start_Position,
|
Target_File_Object_Instance, Target_File_Start_Position,
|
||||||
Target_File_Requested_Octet_Count);
|
Target_File_Requested_Octet_Count);
|
||||||
Request_Invoke_ID = invoke_id;
|
Request_Invoke_ID = invoke_id;
|
||||||
} else if (tsm_invoke_id_failed(invoke_id)) {
|
} else if (tsm_invoke_id_failed(invoke_id)) {
|
||||||
fprintf(stderr, "\rError: TSM Timeout!\n");
|
fprintf(stderr, "\rError: TSM Timeout!\n");
|
||||||
@@ -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
|
||||||
|
|
||||||
@@ -32,30 +32,30 @@
|
|||||||
|
|
||||||
#define PRINT_ENABLED 1
|
#define PRINT_ENABLED 1
|
||||||
|
|
||||||
#include "bacdef.h"
|
#include "bacnet/bacdef.h"
|
||||||
#include "config.h"
|
#include "bacnet/config.h"
|
||||||
#include "bactext.h"
|
#include "bacnet/bactext.h"
|
||||||
#include "bacerror.h"
|
#include "bacnet/bacerror.h"
|
||||||
#include "iam.h"
|
#include "bacnet/iam.h"
|
||||||
#include "arf.h"
|
#include "bacnet/arf.h"
|
||||||
#include "tsm.h"
|
#include "bacnet/basic/tsm/tsm.h"
|
||||||
#include "address.h"
|
#include "bacnet/basic/binding/address.h"
|
||||||
#include "npdu.h"
|
#include "bacnet/npdu.h"
|
||||||
#include "apdu.h"
|
#include "bacnet/apdu.h"
|
||||||
#include "device.h"
|
#include "bacnet/basic/object/device.h"
|
||||||
#include "net.h"
|
#include "bacport.h"
|
||||||
#include "datalink.h"
|
#include "bacnet/datalink/datalink.h"
|
||||||
#include "whois.h"
|
#include "bacnet/whois.h"
|
||||||
#include "version.h"
|
#include "bacnet/version.h"
|
||||||
/* some demo stuff needed */
|
/* some demo stuff needed */
|
||||||
#include "filename.h"
|
#include "bacnet/basic/sys/filename.h"
|
||||||
#include "handlers.h"
|
#include "bacnet/basic/services.h"
|
||||||
#include "client.h"
|
#include "bacnet/basic/services.h"
|
||||||
#include "txbuf.h"
|
#include "bacnet/basic/tsm/tsm.h"
|
||||||
#include "dlenv.h"
|
#include "bacnet/datalink/dlenv.h"
|
||||||
|
|
||||||
/* buffer used for receive */
|
/* buffer used for receive */
|
||||||
static uint8_t Rx_Buf[MAX_MPDU] = {0};
|
static uint8_t Rx_Buf[MAX_MPDU] = { 0 };
|
||||||
|
|
||||||
/* converted command line arguments */
|
/* converted command line arguments */
|
||||||
static uint32_t Target_Device_Object_Instance = BACNET_MAX_INSTANCE;
|
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 BACNET_ADDRESS Target_Address;
|
||||||
static bool Error_Detected = false;
|
static bool Error_Detected = false;
|
||||||
|
|
||||||
static void MyErrorHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
|
static void MyErrorHandler(BACNET_ADDRESS *src,
|
||||||
BACNET_ERROR_CLASS error_class,
|
uint8_t invoke_id,
|
||||||
BACNET_ERROR_CODE error_code)
|
BACNET_ERROR_CLASS error_class,
|
||||||
|
BACNET_ERROR_CODE error_code)
|
||||||
{
|
{
|
||||||
if (address_match(&Target_Address, src) &&
|
if (address_match(&Target_Address, src) &&
|
||||||
(invoke_id == Request_Invoke_ID)) {
|
(invoke_id == Request_Invoke_ID)) {
|
||||||
printf("BACnet Error: %s: %s\n",
|
printf("BACnet Error: %s: %s\n",
|
||||||
bactext_error_class_name((int)error_class),
|
bactext_error_class_name((int)error_class),
|
||||||
bactext_error_code_name((int)error_code));
|
bactext_error_code_name((int)error_code));
|
||||||
Error_Detected = true;
|
Error_Detected = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MyAbortHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
|
static void MyAbortHandler(
|
||||||
uint8_t abort_reason, bool server)
|
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t abort_reason, bool server)
|
||||||
{
|
{
|
||||||
(void)server;
|
(void)server;
|
||||||
if (address_match(&Target_Address, src) &&
|
if (address_match(&Target_Address, src) &&
|
||||||
(invoke_id == Request_Invoke_ID)) {
|
(invoke_id == Request_Invoke_ID)) {
|
||||||
printf("BACnet Abort: %s\n",
|
printf(
|
||||||
bactext_abort_reason_name((int)abort_reason));
|
"BACnet Abort: %s\n", bactext_abort_reason_name((int)abort_reason));
|
||||||
Error_Detected = true;
|
Error_Detected = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
|
static void MyRejectHandler(
|
||||||
uint8_t reject_reason)
|
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||||
{
|
{
|
||||||
if (address_match(&Target_Address, src) &&
|
if (address_match(&Target_Address, src) &&
|
||||||
(invoke_id == Request_Invoke_ID)) {
|
(invoke_id == Request_Invoke_ID)) {
|
||||||
printf("BACnet Reject: %s\n",
|
printf("BACnet Reject: %s\n",
|
||||||
bactext_reject_reason_name((int)reject_reason));
|
bactext_reject_reason_name((int)reject_reason));
|
||||||
Error_Detected = true;
|
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
|
* @param service_data [in] The BACNET_CONFIRMED_SERVICE_DATA information
|
||||||
* decoded from the APDU header of this message.
|
* decoded from the APDU header of this message.
|
||||||
*/
|
*/
|
||||||
void My_Read_Property_Ack_Handler(
|
static void My_Read_Property_Ack_Handler(uint8_t *service_request,
|
||||||
uint8_t *service_request, uint16_t service_len, BACNET_ADDRESS *src,
|
uint16_t service_len,
|
||||||
|
BACNET_ADDRESS *src,
|
||||||
BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data)
|
BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data)
|
||||||
{
|
{
|
||||||
int len = 0;
|
int len = 0;
|
||||||
@@ -146,11 +148,11 @@ static void Init_Service_Handlers(void)
|
|||||||
It is required to send the proper reject message... */
|
It is required to send the proper reject message... */
|
||||||
apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service);
|
apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service);
|
||||||
/* we must implement read property - it's required! */
|
/* we must implement read property - it's required! */
|
||||||
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY,
|
apdu_set_confirmed_handler(
|
||||||
handler_read_property);
|
SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property);
|
||||||
/* handle the data coming back from confirmed requests */
|
/* handle the data coming back from confirmed requests */
|
||||||
apdu_set_confirmed_ack_handler(SERVICE_CONFIRMED_READ_PROPERTY,
|
apdu_set_confirmed_ack_handler(
|
||||||
My_Read_Property_Ack_Handler);
|
SERVICE_CONFIRMED_READ_PROPERTY, My_Read_Property_Ack_Handler);
|
||||||
/* handle any errors coming back */
|
/* handle any errors coming back */
|
||||||
apdu_set_error_handler(SERVICE_CONFIRMED_READ_PROPERTY, MyErrorHandler);
|
apdu_set_error_handler(SERVICE_CONFIRMED_READ_PROPERTY, MyErrorHandler);
|
||||||
apdu_set_abort_handler(MyAbortHandler);
|
apdu_set_abort_handler(MyAbortHandler);
|
||||||
@@ -159,9 +161,8 @@ static void Init_Service_Handlers(void)
|
|||||||
|
|
||||||
static void print_usage(char *filename)
|
static void print_usage(char *filename)
|
||||||
{
|
{
|
||||||
printf(
|
printf("Usage: %s device-instance object-type object-instance "
|
||||||
"Usage: %s device-instance object-type object-instance "
|
"property [index]\n",
|
||||||
"property [index]\n",
|
|
||||||
filename);
|
filename);
|
||||||
printf(" [--dnet][--dadr][--mac]\n");
|
printf(" [--dnet][--dadr][--mac]\n");
|
||||||
printf(" [--version][--help]\n");
|
printf(" [--version][--help]\n");
|
||||||
@@ -169,67 +170,64 @@ static void print_usage(char *filename)
|
|||||||
|
|
||||||
static void print_help(char *filename)
|
static void print_help(char *filename)
|
||||||
{
|
{
|
||||||
printf(
|
printf("Read a property from an object in a BACnet device\n"
|
||||||
"Read a property from an object in a BACnet device\n"
|
"and print the value.\n");
|
||||||
"and print the value.\n");
|
printf("--mac A\n"
|
||||||
printf(
|
"Optional BACnet mac address."
|
||||||
"--mac A\n"
|
"Valid ranges are from 00 to FF (hex) for MS/TP or ARCNET,\n"
|
||||||
"Optional BACnet mac address."
|
"or an IP string with optional port number like 10.1.2.3:47808\n"
|
||||||
"Valid ranges are from 00 to FF (hex) for MS/TP or ARCNET,\n"
|
"or an Ethernet MAC in hex like 00:21:70:7e:32:bb\n"
|
||||||
"or an IP string with optional port number like 10.1.2.3:47808\n"
|
"\n"
|
||||||
"or an Ethernet MAC in hex like 00:21:70:7e:32:bb\n"
|
"--dnet N\n"
|
||||||
"\n"
|
"Optional BACnet network number N for directed requests.\n"
|
||||||
"--dnet N\n"
|
"Valid range is from 0 to 65535 where 0 is the local connection\n"
|
||||||
"Optional BACnet network number N for directed requests.\n"
|
"and 65535 is network broadcast.\n"
|
||||||
"Valid range is from 0 to 65535 where 0 is the local connection\n"
|
"\n"
|
||||||
"and 65535 is network broadcast.\n"
|
"--dadr A\n"
|
||||||
"\n"
|
"Optional BACnet mac address on the destination BACnet network "
|
||||||
"--dadr A\n"
|
"number.\n"
|
||||||
"Optional BACnet mac address on the destination BACnet network "
|
"Valid ranges are from 00 to FF (hex) for MS/TP or ARCNET,\n"
|
||||||
"number.\n"
|
"or an IP string with optional port number like 10.1.2.3:47808\n"
|
||||||
"Valid ranges are from 00 to FF (hex) for MS/TP or ARCNET,\n"
|
"or an Ethernet MAC in hex like 00:21:70:7e:32:bb\n"
|
||||||
"or an IP string with optional port number like 10.1.2.3:47808\n"
|
"\n");
|
||||||
"or an Ethernet MAC in hex like 00:21:70:7e:32:bb\n"
|
printf("device-instance:\n"
|
||||||
"\n");
|
"BACnet Device Object Instance number that you are\n"
|
||||||
printf(
|
"trying to communicate to. This number will be used\n"
|
||||||
"device-instance:\n"
|
"to try and bind with the device using Who-Is and\n"
|
||||||
"BACnet Device Object Instance number that you are\n"
|
"I-Am services. For example, if you were reading\n"
|
||||||
"trying to communicate to. This number will be used\n"
|
"Device Object 123, the device-instance would be 123.\n"
|
||||||
"to try and bind with the device using Who-Is and\n"
|
"\nobject-type:\n"
|
||||||
"I-Am services. For example, if you were reading\n"
|
"The object type is the integer value of the enumeration\n"
|
||||||
"Device Object 123, the device-instance would be 123.\n"
|
"BACNET_OBJECT_TYPE in bacenum.h. It is the object\n"
|
||||||
"\nobject-type:\n"
|
"that you are reading. For example if you were\n"
|
||||||
"The object type is the integer value of the enumeration\n"
|
"reading Analog Output 2, the object-type would be 1.\n"
|
||||||
"BACNET_OBJECT_TYPE in bacenum.h. It is the object\n"
|
"\nobject-instance:\n"
|
||||||
"that you are reading. For example if you were\n"
|
"This is the object instance number of the object that\n"
|
||||||
"reading Analog Output 2, the object-type would be 1.\n"
|
"you are reading. For example, if you were reading\n"
|
||||||
"\nobject-instance:\n"
|
"Analog Output 2, the object-instance would be 2.\n"
|
||||||
"This is the object instance number of the object that\n"
|
"\nproperty:\n"
|
||||||
"you are reading. For example, if you were reading\n"
|
"The property is an integer value of the enumeration\n"
|
||||||
"Analog Output 2, the object-instance would be 2.\n"
|
"BACNET_PROPERTY_ID in bacenum.h. It is the property\n"
|
||||||
"\nproperty:\n"
|
"you are reading. For example, if you were reading the\n"
|
||||||
"The property is an integer value of the enumeration\n"
|
"Present Value property, use 85 as the property.\n"
|
||||||
"BACNET_PROPERTY_ID in bacenum.h. It is the property\n"
|
"\nindex:\n"
|
||||||
"you are reading. For example, if you were reading the\n"
|
"This integer parameter is the index number of an array.\n"
|
||||||
"Present Value property, use 85 as the property.\n"
|
"If the property is an array, individual elements can\n"
|
||||||
"\nindex:\n"
|
"be read. If this parameter is missing and the property\n"
|
||||||
"This integer parameter is the index number of an array.\n"
|
"is an array, the entire array will be read.\n"
|
||||||
"If the property is an array, individual elements can\n"
|
"\nExample:\n"
|
||||||
"be read. If this parameter is missing and the property\n"
|
"If you want read the Present-Value of Analog Output 101\n"
|
||||||
"is an array, the entire array will be read.\n"
|
"in Device 123, you could send the following command:\n"
|
||||||
"\nExample:\n"
|
"%s 123 1 101 85\n"
|
||||||
"If you want read the Present-Value of Analog Output 101\n"
|
"If you want read the Priority-Array of Analog Output 101\n"
|
||||||
"in Device 123, you could send the following command:\n"
|
"in Device 123, you could send the following command:\n"
|
||||||
"%s 123 1 101 85\n"
|
"%s 123 1 101 87\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);
|
filename, filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(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;
|
uint16_t pdu_len = 0;
|
||||||
unsigned timeout = 100; /* milliseconds */
|
unsigned timeout = 100; /* milliseconds */
|
||||||
unsigned max_apdu = 0;
|
unsigned max_apdu = 0;
|
||||||
@@ -239,9 +237,9 @@ int main(int argc, char *argv[])
|
|||||||
time_t timeout_seconds = 0;
|
time_t timeout_seconds = 0;
|
||||||
bool found = false;
|
bool found = false;
|
||||||
long dnet = -1;
|
long dnet = -1;
|
||||||
BACNET_MAC_ADDRESS mac = {0};
|
BACNET_MAC_ADDRESS mac = { 0 };
|
||||||
BACNET_MAC_ADDRESS adr = {0};
|
BACNET_MAC_ADDRESS adr = { 0 };
|
||||||
BACNET_ADDRESS dest = {0};
|
BACNET_ADDRESS dest = { 0 };
|
||||||
bool specific_address = false;
|
bool specific_address = false;
|
||||||
int argi = 0;
|
int argi = 0;
|
||||||
unsigned int target_args = 0;
|
unsigned int target_args = 0;
|
||||||
@@ -256,12 +254,11 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
if (strcmp(argv[argi], "--version") == 0) {
|
if (strcmp(argv[argi], "--version") == 0) {
|
||||||
printf("%s %s\n", filename, BACNET_VERSION_TEXT);
|
printf("%s %s\n", filename, BACNET_VERSION_TEXT);
|
||||||
printf(
|
printf("Copyright (C) 2015 by Steve Karg and others.\n"
|
||||||
"Copyright (C) 2015 by Steve Karg and others.\n"
|
"This is free software; see the source for copying "
|
||||||
"This is free software; see the source for copying "
|
"conditions.\n"
|
||||||
"conditions.\n"
|
"There is NO warranty; not even for MERCHANTABILITY or\n"
|
||||||
"There is NO warranty; not even for MERCHANTABILITY or\n"
|
"FITNESS FOR A PARTICULAR PURPOSE.\n");
|
||||||
"FITNESS FOR A PARTICULAR PURPOSE.\n");
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (strcmp(argv[argi], "--mac") == 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) {
|
if (Target_Device_Object_Instance > BACNET_MAX_INSTANCE) {
|
||||||
fprintf(stderr, "device-instance=%u - it must be less than %u\n",
|
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;
|
return 1;
|
||||||
}
|
}
|
||||||
address_init();
|
address_init();
|
||||||
@@ -355,11 +352,11 @@ int main(int argc, char *argv[])
|
|||||||
last_seconds = time(NULL);
|
last_seconds = time(NULL);
|
||||||
timeout_seconds = (apdu_timeout() / 1000) * apdu_retries();
|
timeout_seconds = (apdu_timeout() / 1000) * apdu_retries();
|
||||||
/* try to bind with the device */
|
/* try to bind with the device */
|
||||||
found = address_bind_request(Target_Device_Object_Instance, &max_apdu,
|
found = address_bind_request(
|
||||||
&Target_Address);
|
Target_Device_Object_Instance, &max_apdu, &Target_Address);
|
||||||
if (!found) {
|
if (!found) {
|
||||||
Send_WhoIs(Target_Device_Object_Instance,
|
Send_WhoIs(
|
||||||
Target_Device_Object_Instance);
|
Target_Device_Object_Instance, Target_Device_Object_Instance);
|
||||||
}
|
}
|
||||||
/* loop forever */
|
/* loop forever */
|
||||||
for (;;) {
|
for (;;) {
|
||||||
@@ -367,25 +364,26 @@ int main(int argc, char *argv[])
|
|||||||
current_seconds = time(NULL);
|
current_seconds = time(NULL);
|
||||||
|
|
||||||
/* at least one second has passed */
|
/* at least one second has passed */
|
||||||
if (current_seconds != last_seconds)
|
if (current_seconds != last_seconds) {
|
||||||
tsm_timer_milliseconds(
|
tsm_timer_milliseconds(
|
||||||
(uint16_t)((current_seconds - last_seconds) * 1000));
|
(uint16_t)((current_seconds - last_seconds) * 1000));
|
||||||
|
}
|
||||||
if (Error_Detected)
|
if (Error_Detected)
|
||||||
break;
|
break;
|
||||||
/* wait until the device is bound, or timeout and quit */
|
/* wait until the device is bound, or timeout and quit */
|
||||||
if (!found) {
|
if (!found) {
|
||||||
found = address_bind_request(Target_Device_Object_Instance,
|
found = address_bind_request(
|
||||||
&max_apdu, &Target_Address);
|
Target_Device_Object_Instance, &max_apdu, &Target_Address);
|
||||||
}
|
}
|
||||||
if (found) {
|
if (found) {
|
||||||
if (Request_Invoke_ID == 0) {
|
if (Request_Invoke_ID == 0) {
|
||||||
Request_Invoke_ID = Send_Read_Property_Request(
|
Request_Invoke_ID =
|
||||||
Target_Device_Object_Instance, Target_Object_Type,
|
Send_Read_Property_Request(Target_Device_Object_Instance,
|
||||||
Target_Object_Instance, Target_Object_Property,
|
Target_Object_Type, Target_Object_Instance,
|
||||||
Target_Object_Index);
|
Target_Object_Property, Target_Object_Index);
|
||||||
} else if (tsm_invoke_id_free(Request_Invoke_ID))
|
} else if (tsm_invoke_id_free(Request_Invoke_ID)) {
|
||||||
break;
|
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");
|
fprintf(stderr, "\rError: TSM Timeout!\n");
|
||||||
tsm_free_invoke_id(Request_Invoke_ID);
|
tsm_free_invoke_id(Request_Invoke_ID);
|
||||||
Error_Detected = true;
|
Error_Detected = true;
|
||||||
@@ -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
|
||||||
|
|
||||||
@@ -32,31 +32,31 @@
|
|||||||
|
|
||||||
#define PRINT_ENABLED 1
|
#define PRINT_ENABLED 1
|
||||||
|
|
||||||
#include "bacdef.h"
|
#include "bacnet/bacdef.h"
|
||||||
#include "config.h"
|
#include "bacnet/config.h"
|
||||||
#include "bactext.h"
|
#include "bacnet/bactext.h"
|
||||||
#include "bacerror.h"
|
#include "bacnet/bacerror.h"
|
||||||
#include "iam.h"
|
#include "bacnet/iam.h"
|
||||||
#include "arf.h"
|
#include "bacnet/arf.h"
|
||||||
#include "tsm.h"
|
#include "bacnet/basic/tsm/tsm.h"
|
||||||
#include "address.h"
|
#include "bacnet/basic/binding/address.h"
|
||||||
#include "npdu.h"
|
#include "bacnet/npdu.h"
|
||||||
#include "apdu.h"
|
#include "bacnet/apdu.h"
|
||||||
#include "device.h"
|
#include "bacnet/basic/object/device.h"
|
||||||
#include "net.h"
|
#include "bacport.h"
|
||||||
#include "datalink.h"
|
#include "bacnet/datalink/datalink.h"
|
||||||
#include "whois.h"
|
#include "bacnet/whois.h"
|
||||||
#include "version.h"
|
#include "bacnet/version.h"
|
||||||
/* some demo stuff needed */
|
/* some demo stuff needed */
|
||||||
#include "rpm.h"
|
#include "bacnet/rpm.h"
|
||||||
#include "filename.h"
|
#include "bacnet/basic/sys/filename.h"
|
||||||
#include "handlers.h"
|
#include "bacnet/basic/services.h"
|
||||||
#include "client.h"
|
#include "bacnet/basic/services.h"
|
||||||
#include "txbuf.h"
|
#include "bacnet/basic/tsm/tsm.h"
|
||||||
#include "dlenv.h"
|
#include "bacnet/datalink/dlenv.h"
|
||||||
|
|
||||||
/* buffer used for receive */
|
/* 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 */
|
/* global variables used in this file */
|
||||||
static uint32_t Target_Device_Object_Instance = BACNET_MAX_INSTANCE;
|
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 */
|
/* needed for return value of main application */
|
||||||
static bool Error_Detected = false;
|
static bool Error_Detected = false;
|
||||||
|
|
||||||
static void MyErrorHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
|
static void MyErrorHandler(BACNET_ADDRESS *src,
|
||||||
BACNET_ERROR_CLASS error_class,
|
uint8_t invoke_id,
|
||||||
BACNET_ERROR_CODE error_code)
|
BACNET_ERROR_CLASS error_class,
|
||||||
|
BACNET_ERROR_CODE error_code)
|
||||||
{
|
{
|
||||||
if (address_match(&Target_Address, src) &&
|
if (address_match(&Target_Address, src) &&
|
||||||
(invoke_id == Request_Invoke_ID)) {
|
(invoke_id == Request_Invoke_ID)) {
|
||||||
printf("BACnet Error: %s: %s\n",
|
printf("BACnet Error: %s: %s\n",
|
||||||
bactext_error_class_name((int)error_class),
|
bactext_error_class_name((int)error_class),
|
||||||
bactext_error_code_name((int)error_code));
|
bactext_error_code_name((int)error_code));
|
||||||
Error_Detected = true;
|
Error_Detected = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MyAbortHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
|
static void MyAbortHandler(
|
||||||
uint8_t abort_reason, bool server)
|
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t abort_reason, bool server)
|
||||||
{
|
{
|
||||||
(void)server;
|
(void)server;
|
||||||
if (address_match(&Target_Address, src) &&
|
if (address_match(&Target_Address, src) &&
|
||||||
(invoke_id == Request_Invoke_ID)) {
|
(invoke_id == Request_Invoke_ID)) {
|
||||||
printf("BACnet Abort: %s\n",
|
printf(
|
||||||
bactext_abort_reason_name((int)abort_reason));
|
"BACnet Abort: %s\n", bactext_abort_reason_name((int)abort_reason));
|
||||||
Error_Detected = true;
|
Error_Detected = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
|
static void MyRejectHandler(
|
||||||
uint8_t reject_reason)
|
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||||
{
|
{
|
||||||
/* FIXME: verify src and invoke id */
|
/* FIXME: verify src and invoke id */
|
||||||
if (address_match(&Target_Address, src) &&
|
if (address_match(&Target_Address, src) &&
|
||||||
(invoke_id == Request_Invoke_ID)) {
|
(invoke_id == Request_Invoke_ID)) {
|
||||||
printf("BACnet Reject: %s\n",
|
printf("BACnet Reject: %s\n",
|
||||||
bactext_reject_reason_name((int)reject_reason));
|
bactext_reject_reason_name((int)reject_reason));
|
||||||
Error_Detected = true;
|
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
|
* @param service_data [in] The BACNET_CONFIRMED_SERVICE_DATA information
|
||||||
* decoded from the APDU header of this message.
|
* decoded from the APDU header of this message.
|
||||||
*/
|
*/
|
||||||
void My_Read_Property_Multiple_Ack_Handler(
|
static void My_Read_Property_Multiple_Ack_Handler(uint8_t *service_request,
|
||||||
uint8_t *service_request, uint16_t service_len, BACNET_ADDRESS *src,
|
uint16_t service_len,
|
||||||
|
BACNET_ADDRESS *src,
|
||||||
BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data)
|
BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data)
|
||||||
{
|
{
|
||||||
int len = 0;
|
int len = 0;
|
||||||
@@ -131,8 +133,8 @@ void My_Read_Property_Multiple_Ack_Handler(
|
|||||||
(service_data->invoke_id == Request_Invoke_ID)) {
|
(service_data->invoke_id == Request_Invoke_ID)) {
|
||||||
rpm_data = calloc(1, sizeof(BACNET_READ_ACCESS_DATA));
|
rpm_data = calloc(1, sizeof(BACNET_READ_ACCESS_DATA));
|
||||||
if (rpm_data) {
|
if (rpm_data) {
|
||||||
len = rpm_ack_decode_service_request(service_request, service_len,
|
len = rpm_ack_decode_service_request(
|
||||||
rpm_data);
|
service_request, service_len, rpm_data);
|
||||||
}
|
}
|
||||||
if (len > 0) {
|
if (len > 0) {
|
||||||
while (rpm_data) {
|
while (rpm_data) {
|
||||||
@@ -188,18 +190,18 @@ static void Init_Service_Handlers(void)
|
|||||||
It is required to send the proper reject message... */
|
It is required to send the proper reject message... */
|
||||||
apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service);
|
apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service);
|
||||||
/* we must implement read property - it's required! */
|
/* we must implement read property - it's required! */
|
||||||
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY,
|
apdu_set_confirmed_handler(
|
||||||
handler_read_property);
|
SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property);
|
||||||
/* handle the data coming back from confirmed requests */
|
/* handle the data coming back from confirmed requests */
|
||||||
apdu_set_confirmed_ack_handler(SERVICE_CONFIRMED_READ_PROP_MULTIPLE,
|
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 */
|
/* handle any errors coming back */
|
||||||
apdu_set_error_handler(SERVICE_CONFIRMED_READ_PROPERTY, MyErrorHandler);
|
apdu_set_error_handler(SERVICE_CONFIRMED_READ_PROPERTY, MyErrorHandler);
|
||||||
apdu_set_abort_handler(MyAbortHandler);
|
apdu_set_abort_handler(MyAbortHandler);
|
||||||
apdu_set_reject_handler(MyRejectHandler);
|
apdu_set_reject_handler(MyRejectHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cleanup(void)
|
static void cleanup(void)
|
||||||
{
|
{
|
||||||
BACNET_READ_ACCESS_DATA *rpm_object;
|
BACNET_READ_ACCESS_DATA *rpm_object;
|
||||||
BACNET_READ_ACCESS_DATA *old_rpm_object;
|
BACNET_READ_ACCESS_DATA *old_rpm_object;
|
||||||
@@ -223,67 +225,65 @@ void cleanup(void)
|
|||||||
|
|
||||||
static void print_usage(char *filename)
|
static void print_usage(char *filename)
|
||||||
{
|
{
|
||||||
printf(
|
printf("Usage: %s device-instance object-type object-instance "
|
||||||
"Usage: %s device-instance object-type object-instance "
|
"property[index][,property[index]] [object-type ...]\n",
|
||||||
"property[index][,property[index]] [object-type ...]\n",
|
|
||||||
filename);
|
filename);
|
||||||
printf(" [--version][--help]\n");
|
printf(" [--version][--help]\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void print_help(char *filename)
|
static void print_help(char *filename)
|
||||||
{
|
{
|
||||||
printf(
|
printf("Read one or more properties from one or more objects\n"
|
||||||
"Read one or more properties from one or more objects\n"
|
"in a BACnet device and print the value(s).\n"
|
||||||
"in a BACnet device and print the value(s).\n"
|
"device-instance:\n"
|
||||||
"device-instance:\n"
|
"BACnet Device Object Instance number that you are\n"
|
||||||
"BACnet Device Object Instance number that you are\n"
|
"trying to communicate to. This number will be used\n"
|
||||||
"trying to communicate to. This number will be used\n"
|
"to try and bind with the device using Who-Is and\n"
|
||||||
"to try and bind with the device using Who-Is and\n"
|
"I-Am services. For example, if you were reading\n"
|
||||||
"I-Am services. For example, if you were reading\n"
|
"Device Object 123, the device-instance would be 123.\n"
|
||||||
"Device Object 123, the device-instance would be 123.\n"
|
"\nobject-type:\n"
|
||||||
"\nobject-type:\n"
|
"The object type is the integer value of the enumeration\n"
|
||||||
"The object type is the integer value of the enumeration\n"
|
"BACNET_OBJECT_TYPE in bacenum.h. It is the object\n"
|
||||||
"BACNET_OBJECT_TYPE in bacenum.h. It is the object\n"
|
"that you are reading. For example if you were\n"
|
||||||
"that you are reading. For example if you were\n"
|
"reading Analog Output 2, the object-type would be 1.\n"
|
||||||
"reading Analog Output 2, the object-type would be 1.\n"
|
"\nobject-instance:\n"
|
||||||
"\nobject-instance:\n"
|
"This is the object instance number of the object that\n"
|
||||||
"This is the object instance number of the object that\n"
|
"you are reading. For example, if you were reading\n"
|
||||||
"you are reading. For example, if you were reading\n"
|
"Analog Output 2, the object-instance would be 2.\n"
|
||||||
"Analog Output 2, the object-instance would be 2.\n"
|
"\nproperty:\n"
|
||||||
"\nproperty:\n"
|
"The property is an integer value of the enumeration\n"
|
||||||
"The property is an integer value of the enumeration\n"
|
"BACNET_PROPERTY_ID in bacenum.h. It is the property\n"
|
||||||
"BACNET_PROPERTY_ID in bacenum.h. It is the property\n"
|
"you are reading. For example, if you were reading the\n"
|
||||||
"you are reading. For example, if you were reading the\n"
|
"Present Value property, use 85 as the property.\n"
|
||||||
"Present Value property, use 85 as the property.\n"
|
"\n[index]:\n"
|
||||||
"\n[index]:\n"
|
"This optional integer parameter is the index number of \n"
|
||||||
"This optional integer parameter is the index number of \n"
|
"an array property. Individual elements of an array can\n"
|
||||||
"an array property. Individual elements of an array can\n"
|
"be read. If this parameter is missing and the property\n"
|
||||||
"be read. If this parameter is missing and the property\n"
|
"is an array, the entire array will be read.\n"
|
||||||
"is an array, the entire array will be read.\n"
|
"\nExample:\n"
|
||||||
"\nExample:\n"
|
"If you want read the PRESENT_VALUE property and various\n"
|
||||||
"If you want read the PRESENT_VALUE property and various\n"
|
"array elements of the PRIORITY_ARRAY in Device 123\n"
|
||||||
"array elements of the PRIORITY_ARRAY in Device 123\n"
|
"Analog Output object 99, use the following command:\n"
|
||||||
"Analog Output object 99, use the following command:\n"
|
"%s 123 1 99 85,87[0],87\n"
|
||||||
"%s 123 1 99 85,87[0],87\n"
|
"If you want read the PRESENT_VALUE property in objects\n"
|
||||||
"If you want read the PRESENT_VALUE property in objects\n"
|
"Analog Input 77 and Analog Input 78 in Device 123\n"
|
||||||
"Analog Input 77 and Analog Input 78 in Device 123\n"
|
"use the following command:\n"
|
||||||
"use the following command:\n"
|
"%s 123 0 77 85 0 78 85\n"
|
||||||
"%s 123 0 77 85 0 78 85\n"
|
"If you want read the ALL property in\n"
|
||||||
"If you want read the ALL property in\n"
|
"Device object 123, you would use the following command:\n"
|
||||||
"Device object 123, you would use the following command:\n"
|
"%s 123 8 123 8\n"
|
||||||
"%s 123 8 123 8\n"
|
"If you want read the OPTIONAL property in\n"
|
||||||
"If you want read the OPTIONAL property in\n"
|
"Device object 123, you would use the following command:\n"
|
||||||
"Device object 123, you would use the following command:\n"
|
"%s 123 8 123 80\n"
|
||||||
"%s 123 8 123 80\n"
|
"If you want read the REQUIRED property in\n"
|
||||||
"If you want read the REQUIRED property in\n"
|
"Device object 123, you would use the following command:\n"
|
||||||
"Device object 123, you would use the following command:\n"
|
"%s 123 8 123 105\n",
|
||||||
"%s 123 8 123 105\n",
|
|
||||||
filename, filename, filename, filename, filename);
|
filename, filename, filename, filename, filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(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;
|
uint16_t pdu_len = 0;
|
||||||
unsigned timeout = 100; /* milliseconds */
|
unsigned timeout = 100; /* milliseconds */
|
||||||
unsigned max_apdu = 0;
|
unsigned max_apdu = 0;
|
||||||
@@ -293,7 +293,7 @@ int main(int argc, char *argv[])
|
|||||||
time_t current_seconds = 0;
|
time_t current_seconds = 0;
|
||||||
time_t timeout_seconds = 0;
|
time_t timeout_seconds = 0;
|
||||||
bool found = false;
|
bool found = false;
|
||||||
uint8_t buffer[MAX_PDU] = {0};
|
uint8_t buffer[MAX_PDU] = { 0 };
|
||||||
BACNET_READ_ACCESS_DATA *rpm_object;
|
BACNET_READ_ACCESS_DATA *rpm_object;
|
||||||
BACNET_PROPERTY_REFERENCE *rpm_property;
|
BACNET_PROPERTY_REFERENCE *rpm_property;
|
||||||
char *property_token = NULL;
|
char *property_token = NULL;
|
||||||
@@ -312,12 +312,11 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
if (strcmp(argv[argi], "--version") == 0) {
|
if (strcmp(argv[argi], "--version") == 0) {
|
||||||
printf("%s %s\n", filename, BACNET_VERSION_TEXT);
|
printf("%s %s\n", filename, BACNET_VERSION_TEXT);
|
||||||
printf(
|
printf("Copyright (C) 2014 by Steve Karg and others.\n"
|
||||||
"Copyright (C) 2014 by Steve Karg and others.\n"
|
"This is free software; see the source for copying "
|
||||||
"This is free software; see the source for copying "
|
"conditions.\n"
|
||||||
"conditions.\n"
|
"There is NO warranty; not even for MERCHANTABILITY or\n"
|
||||||
"There is NO warranty; not even for MERCHANTABILITY or\n"
|
"FITNESS FOR A PARTICULAR PURPOSE.\n");
|
||||||
"FITNESS FOR A PARTICULAR PURPOSE.\n");
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -329,7 +328,7 @@ int main(int argc, char *argv[])
|
|||||||
Target_Device_Object_Instance = strtol(argv[1], NULL, 0);
|
Target_Device_Object_Instance = strtol(argv[1], NULL, 0);
|
||||||
if (Target_Device_Object_Instance >= BACNET_MAX_INSTANCE) {
|
if (Target_Device_Object_Instance >= BACNET_MAX_INSTANCE) {
|
||||||
fprintf(stderr, "device-instance=%u - it must be less than %u\n",
|
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;
|
return 1;
|
||||||
}
|
}
|
||||||
atexit(cleanup);
|
atexit(cleanup);
|
||||||
@@ -348,7 +347,7 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
if (rpm_object->object_type >= MAX_BACNET_OBJECT_TYPE) {
|
if (rpm_object->object_type >= MAX_BACNET_OBJECT_TYPE) {
|
||||||
fprintf(stderr, "object-type=%u - it must be less than %u\n",
|
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;
|
return 1;
|
||||||
}
|
}
|
||||||
rpm_object->object_instance = strtol(argv[tag_value_arg], NULL, 0);
|
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) {
|
if (rpm_object->object_instance > BACNET_MAX_INSTANCE) {
|
||||||
fprintf(stderr, "object-instance=%u - it must be less than %u\n",
|
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;
|
return 1;
|
||||||
}
|
}
|
||||||
rpm_property = calloc(1, sizeof(BACNET_PROPERTY_REFERENCE));
|
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], ",");
|
property_token = strtok(argv[tag_value_arg], ",");
|
||||||
/* add all the properties and optional index to our list */
|
/* add all the properties and optional index to our list */
|
||||||
while (rpm_property) {
|
while (rpm_property) {
|
||||||
scan_count = sscanf(property_token, "%u[%u]", &property_id,
|
scan_count = sscanf(
|
||||||
&property_array_index);
|
property_token, "%u[%u]", &property_id, &property_array_index);
|
||||||
if (scan_count > 0) {
|
if (scan_count > 0) {
|
||||||
rpm_property->propertyIdentifier = property_id;
|
rpm_property->propertyIdentifier = property_id;
|
||||||
if (rpm_property->propertyIdentifier > MAX_BACNET_PROPERTY_ID) {
|
if (rpm_property->propertyIdentifier > MAX_BACNET_PROPERTY_ID) {
|
||||||
fprintf(stderr, "property=%u - it must be less than %u\n",
|
fprintf(stderr, "property=%u - it must be less than %u\n",
|
||||||
rpm_property->propertyIdentifier,
|
rpm_property->propertyIdentifier,
|
||||||
MAX_BACNET_PROPERTY_ID + 1);
|
MAX_BACNET_PROPERTY_ID + 1);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -416,11 +415,11 @@ int main(int argc, char *argv[])
|
|||||||
last_seconds = time(NULL);
|
last_seconds = time(NULL);
|
||||||
timeout_seconds = (apdu_timeout() / 1000) * apdu_retries();
|
timeout_seconds = (apdu_timeout() / 1000) * apdu_retries();
|
||||||
/* try to bind with the device */
|
/* try to bind with the device */
|
||||||
found = address_bind_request(Target_Device_Object_Instance, &max_apdu,
|
found = address_bind_request(
|
||||||
&Target_Address);
|
Target_Device_Object_Instance, &max_apdu, &Target_Address);
|
||||||
if (!found) {
|
if (!found) {
|
||||||
Send_WhoIs(Target_Device_Object_Instance,
|
Send_WhoIs(
|
||||||
Target_Device_Object_Instance);
|
Target_Device_Object_Instance, Target_Device_Object_Instance);
|
||||||
}
|
}
|
||||||
/* loop forever */
|
/* loop forever */
|
||||||
for (;;) {
|
for (;;) {
|
||||||
@@ -428,23 +427,24 @@ int main(int argc, char *argv[])
|
|||||||
current_seconds = time(NULL);
|
current_seconds = time(NULL);
|
||||||
|
|
||||||
/* at least one second has passed */
|
/* at least one second has passed */
|
||||||
if (current_seconds != last_seconds)
|
if (current_seconds != last_seconds) {
|
||||||
tsm_timer_milliseconds(((current_seconds - last_seconds) * 1000));
|
tsm_timer_milliseconds(((current_seconds - last_seconds) * 1000));
|
||||||
|
}
|
||||||
if (Error_Detected)
|
if (Error_Detected)
|
||||||
break;
|
break;
|
||||||
/* wait until the device is bound, or timeout and quit */
|
/* wait until the device is bound, or timeout and quit */
|
||||||
if (!found) {
|
if (!found) {
|
||||||
found = address_bind_request(Target_Device_Object_Instance,
|
found = address_bind_request(
|
||||||
&max_apdu, &Target_Address);
|
Target_Device_Object_Instance, &max_apdu, &Target_Address);
|
||||||
}
|
}
|
||||||
if (found) {
|
if (found) {
|
||||||
if (Request_Invoke_ID == 0) {
|
if (Request_Invoke_ID == 0) {
|
||||||
Request_Invoke_ID = Send_Read_Property_Multiple_Request(
|
Request_Invoke_ID = Send_Read_Property_Multiple_Request(
|
||||||
&buffer[0], sizeof(buffer), Target_Device_Object_Instance,
|
&buffer[0], sizeof(buffer), Target_Device_Object_Instance,
|
||||||
Read_Access_Data);
|
Read_Access_Data);
|
||||||
} else if (tsm_invoke_id_free(Request_Invoke_ID))
|
} else if (tsm_invoke_id_free(Request_Invoke_ID)) {
|
||||||
break;
|
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");
|
fprintf(stderr, "\rError: TSM Timeout!\n");
|
||||||
tsm_free_invoke_id(Request_Invoke_ID);
|
tsm_free_invoke_id(Request_Invoke_ID);
|
||||||
Error_Detected = true;
|
Error_Detected = true;
|
||||||
@@ -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
|
||||||
|
|
||||||
@@ -31,30 +31,30 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <time.h> /* for time */
|
#include <time.h> /* for time */
|
||||||
#include "bacdef.h"
|
#include "bacnet/bacdef.h"
|
||||||
#include "config.h"
|
#include "bacnet/config.h"
|
||||||
#include "bactext.h"
|
#include "bacnet/bactext.h"
|
||||||
#include "bacerror.h"
|
#include "bacnet/bacerror.h"
|
||||||
#include "iam.h"
|
#include "bacnet/iam.h"
|
||||||
#include "tsm.h"
|
#include "bacnet/basic/tsm/tsm.h"
|
||||||
#include "address.h"
|
#include "bacnet/basic/binding/address.h"
|
||||||
#include "npdu.h"
|
#include "bacnet/npdu.h"
|
||||||
#include "apdu.h"
|
#include "bacnet/apdu.h"
|
||||||
#include "device.h"
|
#include "bacnet/basic/object/device.h"
|
||||||
#include "net.h"
|
#include "bacport.h"
|
||||||
#include "datalink.h"
|
#include "bacnet/datalink/datalink.h"
|
||||||
#include "whois.h"
|
#include "bacnet/whois.h"
|
||||||
#include "version.h"
|
#include "bacnet/version.h"
|
||||||
/* some demo stuff needed */
|
/* some demo stuff needed */
|
||||||
#include "filename.h"
|
#include "bacnet/basic/sys/filename.h"
|
||||||
#include "handlers.h"
|
#include "bacnet/basic/services.h"
|
||||||
#include "client.h"
|
#include "bacnet/basic/services.h"
|
||||||
#include "txbuf.h"
|
#include "bacnet/basic/tsm/tsm.h"
|
||||||
#include "dlenv.h"
|
#include "bacnet/datalink/dlenv.h"
|
||||||
#include "readrange.h"
|
#include "bacnet/readrange.h"
|
||||||
|
|
||||||
/* buffer used for receive */
|
/* buffer used for receive */
|
||||||
static uint8_t Rx_Buf[MAX_MPDU] = {0};
|
static uint8_t Rx_Buf[MAX_MPDU] = { 0 };
|
||||||
|
|
||||||
/* converted command line arguments */
|
/* converted command line arguments */
|
||||||
static uint32_t Target_Device_Object_Instance = BACNET_MAX_INSTANCE;
|
static uint32_t Target_Device_Object_Instance = BACNET_MAX_INSTANCE;
|
||||||
@@ -71,38 +71,39 @@ static bool Error_Detected = false;
|
|||||||
/* specific request data */
|
/* specific request data */
|
||||||
static BACNET_READ_RANGE_DATA RR_Request;
|
static BACNET_READ_RANGE_DATA RR_Request;
|
||||||
|
|
||||||
static void MyErrorHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
|
static void MyErrorHandler(BACNET_ADDRESS *src,
|
||||||
BACNET_ERROR_CLASS error_class,
|
uint8_t invoke_id,
|
||||||
BACNET_ERROR_CODE error_code)
|
BACNET_ERROR_CLASS error_class,
|
||||||
|
BACNET_ERROR_CODE error_code)
|
||||||
{
|
{
|
||||||
if (address_match(&Target_Address, src) &&
|
if (address_match(&Target_Address, src) &&
|
||||||
(invoke_id == Request_Invoke_ID)) {
|
(invoke_id == Request_Invoke_ID)) {
|
||||||
printf("BACnet Error: %s: %s\r\n",
|
printf("BACnet Error: %s: %s\r\n",
|
||||||
bactext_error_class_name((int)error_class),
|
bactext_error_class_name((int)error_class),
|
||||||
bactext_error_code_name((int)error_code));
|
bactext_error_code_name((int)error_code));
|
||||||
Error_Detected = true;
|
Error_Detected = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MyAbortHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
|
static void MyAbortHandler(
|
||||||
uint8_t abort_reason, bool server)
|
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t abort_reason, bool server)
|
||||||
{
|
{
|
||||||
(void)server;
|
(void)server;
|
||||||
if (address_match(&Target_Address, src) &&
|
if (address_match(&Target_Address, src) &&
|
||||||
(invoke_id == Request_Invoke_ID)) {
|
(invoke_id == Request_Invoke_ID)) {
|
||||||
printf("BACnet Abort: %s\n",
|
printf(
|
||||||
bactext_abort_reason_name((int)abort_reason));
|
"BACnet Abort: %s\n", bactext_abort_reason_name((int)abort_reason));
|
||||||
Error_Detected = true;
|
Error_Detected = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
|
static void MyRejectHandler(
|
||||||
uint8_t reject_reason)
|
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||||
{
|
{
|
||||||
if (address_match(&Target_Address, src) &&
|
if (address_match(&Target_Address, src) &&
|
||||||
(invoke_id == Request_Invoke_ID)) {
|
(invoke_id == Request_Invoke_ID)) {
|
||||||
printf("BACnet Reject: %s\n",
|
printf("BACnet Reject: %s\n",
|
||||||
bactext_reject_reason_name((int)reject_reason));
|
bactext_reject_reason_name((int)reject_reason));
|
||||||
Error_Detected = true;
|
Error_Detected = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -119,11 +120,11 @@ static void Init_Service_Handlers(void)
|
|||||||
It is required to send the proper reject message... */
|
It is required to send the proper reject message... */
|
||||||
apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service);
|
apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service);
|
||||||
/* we must implement read property - it's required! */
|
/* we must implement read property - it's required! */
|
||||||
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY,
|
apdu_set_confirmed_handler(
|
||||||
handler_read_property);
|
SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property);
|
||||||
/* handle the data coming back from confirmed requests */
|
/* handle the data coming back from confirmed requests */
|
||||||
apdu_set_confirmed_ack_handler(SERVICE_CONFIRMED_READ_RANGE,
|
apdu_set_confirmed_ack_handler(
|
||||||
handler_read_range_ack);
|
SERVICE_CONFIRMED_READ_RANGE, handler_read_range_ack);
|
||||||
|
|
||||||
/* handle any errors coming back */
|
/* handle any errors coming back */
|
||||||
apdu_set_error_handler(SERVICE_CONFIRMED_READ_PROPERTY, MyErrorHandler);
|
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)
|
static void print_usage(char *filename)
|
||||||
{
|
{
|
||||||
printf("Usage: %s device-instance object-type object-instance property\n",
|
printf("Usage: %s device-instance object-type object-instance property\n",
|
||||||
filename);
|
filename);
|
||||||
printf(" range-type <index|<date time>> count\n");
|
printf(" range-type <index|<date time>> count\n");
|
||||||
printf(" [--version][--help]\n");
|
printf(" [--version][--help]\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void print_help(char *filename)
|
static void print_help(char *filename)
|
||||||
{
|
{
|
||||||
printf(
|
printf("Read a range of properties from an array or list property\n"
|
||||||
"Read a range of properties from an array or list property\n"
|
"in an object in a BACnet device and print the values.\n"
|
||||||
"in an object in a BACnet device and print the values.\n"
|
"device-instance:\n"
|
||||||
"device-instance:\n"
|
"BACnet Device Object Instance number that you are\n"
|
||||||
"BACnet Device Object Instance number that you are\n"
|
"trying to communicate to. This number will be used\n"
|
||||||
"trying to communicate to. This number will be used\n"
|
"to try and bind with the device using Who-Is and\n"
|
||||||
"to try and bind with the device using Who-Is and\n"
|
"I-Am services. For example, if you were reading\n"
|
||||||
"I-Am services. For example, if you were reading\n"
|
"Device Object 123, the device-instance would be 123.\n"
|
||||||
"Device Object 123, the device-instance would be 123.\n"
|
"\nobject-type:\n"
|
||||||
"\nobject-type:\n"
|
"The object type is the integer value of the enumeration\n"
|
||||||
"The object type is the integer value of the enumeration\n"
|
"BACNET_OBJECT_TYPE in bacenum.h. It is the object\n"
|
||||||
"BACNET_OBJECT_TYPE in bacenum.h. It is the object\n"
|
"that you are reading. For example if you were\n"
|
||||||
"that you are reading. For example if you were\n"
|
"reading Trend Log 2, the object-type would be 20.\n"
|
||||||
"reading Trend Log 2, the object-type would be 20.\n"
|
"\nobject-instance:\n"
|
||||||
"\nobject-instance:\n"
|
"This is the object instance number of the object that\n"
|
||||||
"This is the object instance number of the object that\n"
|
"you are reading. For example, if you were reading\n"
|
||||||
"you are reading. For example, if you were reading\n"
|
"Trend Log 2, the object-instance would be 2.\n"
|
||||||
"Trend Log 2, the object-instance would be 2.\n"
|
"\nproperty:\n"
|
||||||
"\nproperty:\n"
|
"The property is an integer value of the enumeration\n"
|
||||||
"The property is an integer value of the enumeration\n"
|
"BACNET_PROPERTY_ID in bacenum.h. It is the property\n"
|
||||||
"BACNET_PROPERTY_ID in bacenum.h. It is the property\n"
|
"you are reading. For example, if you were reading the\n"
|
||||||
"you are reading. For example, if you were reading the\n"
|
"Log_Buffer property, use 131 as the property.\n"
|
||||||
"Log_Buffer property, use 131 as the property.\n"
|
"\nrange-type:\n"
|
||||||
"\nrange-type:\n"
|
"1=By Position\n"
|
||||||
"1=By Position\n"
|
"2=By Sequence\n"
|
||||||
"2=By Sequence\n"
|
"3=By Time\n"
|
||||||
"3=By Time\n"
|
"4=All\n"
|
||||||
"4=All\n"
|
"\nindex or date/time:\n"
|
||||||
"\nindex or date/time:\n"
|
"This integer parameter is the starting index, or date & time.\n"
|
||||||
"This integer parameter is the starting index, or date & time.\n"
|
"\ncount:\n"
|
||||||
"\ncount:\n"
|
"This integer parameter is the number of elements to read.\n"
|
||||||
"This integer parameter is the number of elements to read.\n"
|
"\nExample:\n"
|
||||||
"\nExample:\n"
|
"If you want read the Log_Buffer of Trend Log 2\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"
|
||||||
"in Device 123, from starting position 1 and read 10 entries,\n"
|
"you could send the following command:\n"
|
||||||
"you could send the following command:\n"
|
"%s 123 20 2 131 1 1 10\n",
|
||||||
"%s 123 20 2 131 1 1 10\n",
|
|
||||||
filename);
|
filename);
|
||||||
printf("%s 123 20 2 131 2 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);
|
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[])
|
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;
|
uint16_t pdu_len = 0;
|
||||||
unsigned timeout = 100; /* milliseconds */
|
unsigned timeout = 100; /* milliseconds */
|
||||||
unsigned max_apdu = 0;
|
unsigned max_apdu = 0;
|
||||||
@@ -210,12 +210,11 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
if (strcmp(argv[argi], "--version") == 0) {
|
if (strcmp(argv[argi], "--version") == 0) {
|
||||||
printf("%s %s\n", filename, BACNET_VERSION_TEXT);
|
printf("%s %s\n", filename, BACNET_VERSION_TEXT);
|
||||||
printf(
|
printf("Copyright (C) 2014 by Steve Karg and others.\n"
|
||||||
"Copyright (C) 2014 by Steve Karg and others.\n"
|
"This is free software; see the source for copying "
|
||||||
"This is free software; see the source for copying "
|
"conditions.\n"
|
||||||
"conditions.\n"
|
"There is NO warranty; not even for MERCHANTABILITY or\n"
|
||||||
"There is NO warranty; not even for MERCHANTABILITY or\n"
|
"FITNESS FOR A PARTICULAR PURPOSE.\n");
|
||||||
"FITNESS FOR A PARTICULAR PURPOSE.\n");
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -232,7 +231,7 @@ int main(int argc, char *argv[])
|
|||||||
/* some bounds checking */
|
/* some bounds checking */
|
||||||
if (Target_Device_Object_Instance > BACNET_MAX_INSTANCE) {
|
if (Target_Device_Object_Instance > BACNET_MAX_INSTANCE) {
|
||||||
fprintf(stderr, "device-instance=%u - it must be less than %u\r\n",
|
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;
|
return 1;
|
||||||
}
|
}
|
||||||
if (Target_Object_Range_Type == 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);
|
count = sscanf(argv[6], "%4d/%3d/%3d:%3d", &year, &month, &day, &wday);
|
||||||
if (count == 3) {
|
if (count == 3) {
|
||||||
datetime_set_date(&RR_Request.Range.RefTime.date, (uint16_t)year,
|
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) {
|
} else if (count == 4) {
|
||||||
RR_Request.Range.RefTime.date.year = (uint16_t)year;
|
RR_Request.Range.RefTime.date.year = (uint16_t)year;
|
||||||
RR_Request.Range.RefTime.date.month = (uint8_t)month;
|
RR_Request.Range.RefTime.date.month = (uint8_t)month;
|
||||||
@@ -318,11 +317,11 @@ int main(int argc, char *argv[])
|
|||||||
last_seconds = time(NULL);
|
last_seconds = time(NULL);
|
||||||
timeout_seconds = (apdu_timeout() / 1000) * apdu_retries();
|
timeout_seconds = (apdu_timeout() / 1000) * apdu_retries();
|
||||||
/* try to bind with the device */
|
/* try to bind with the device */
|
||||||
found = address_bind_request(Target_Device_Object_Instance, &max_apdu,
|
found = address_bind_request(
|
||||||
&Target_Address);
|
Target_Device_Object_Instance, &max_apdu, &Target_Address);
|
||||||
if (!found) {
|
if (!found) {
|
||||||
Send_WhoIs(Target_Device_Object_Instance,
|
Send_WhoIs(
|
||||||
Target_Device_Object_Instance);
|
Target_Device_Object_Instance, Target_Device_Object_Instance);
|
||||||
}
|
}
|
||||||
/* loop forever */
|
/* loop forever */
|
||||||
for (;;) {
|
for (;;) {
|
||||||
@@ -330,23 +329,24 @@ int main(int argc, char *argv[])
|
|||||||
current_seconds = time(NULL);
|
current_seconds = time(NULL);
|
||||||
|
|
||||||
/* at least one second has passed */
|
/* at least one second has passed */
|
||||||
if (current_seconds != last_seconds)
|
if (current_seconds != last_seconds) {
|
||||||
tsm_timer_milliseconds(
|
tsm_timer_milliseconds(
|
||||||
(uint16_t)((current_seconds - last_seconds) * 1000));
|
(uint16_t)((current_seconds - last_seconds) * 1000));
|
||||||
|
}
|
||||||
if (Error_Detected)
|
if (Error_Detected)
|
||||||
break;
|
break;
|
||||||
/* wait until the device is bound, or timeout and quit */
|
/* wait until the device is bound, or timeout and quit */
|
||||||
if (!found) {
|
if (!found) {
|
||||||
found = address_bind_request(Target_Device_Object_Instance,
|
found = address_bind_request(
|
||||||
&max_apdu, &Target_Address);
|
Target_Device_Object_Instance, &max_apdu, &Target_Address);
|
||||||
}
|
}
|
||||||
if (found) {
|
if (found) {
|
||||||
if (Request_Invoke_ID == 0) {
|
if (Request_Invoke_ID == 0) {
|
||||||
Request_Invoke_ID = Send_ReadRange_Request(
|
Request_Invoke_ID = Send_ReadRange_Request(
|
||||||
Target_Device_Object_Instance, &RR_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;
|
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");
|
fprintf(stderr, "\rError: TSM Timeout!\n");
|
||||||
tsm_free_invoke_id(Request_Invoke_ID);
|
tsm_free_invoke_id(Request_Invoke_ID);
|
||||||
Error_Detected = true;
|
Error_Detected = true;
|
||||||
@@ -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
|
||||||
|
|
||||||
@@ -30,29 +30,29 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <time.h> /* for time */
|
#include <time.h> /* for time */
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include "bactext.h"
|
#include "bacnet/bactext.h"
|
||||||
#include "iam.h"
|
#include "bacnet/iam.h"
|
||||||
#include "arf.h"
|
#include "bacnet/arf.h"
|
||||||
#include "tsm.h"
|
#include "bacnet/basic/tsm/tsm.h"
|
||||||
#include "address.h"
|
#include "bacnet/basic/binding/address.h"
|
||||||
#include "config.h"
|
#include "bacnet/config.h"
|
||||||
#include "bacdef.h"
|
#include "bacnet/bacdef.h"
|
||||||
#include "npdu.h"
|
#include "bacnet/npdu.h"
|
||||||
#include "apdu.h"
|
#include "bacnet/apdu.h"
|
||||||
#include "device.h"
|
#include "bacnet/basic/object/device.h"
|
||||||
#include "net.h"
|
#include "bacport.h"
|
||||||
#include "datalink.h"
|
#include "bacnet/datalink/datalink.h"
|
||||||
#include "whois.h"
|
#include "bacnet/whois.h"
|
||||||
#include "rd.h"
|
#include "bacnet/rd.h"
|
||||||
/* some demo stuff needed */
|
/* some demo stuff needed */
|
||||||
#include "filename.h"
|
#include "bacnet/basic/sys/filename.h"
|
||||||
#include "handlers.h"
|
#include "bacnet/basic/services.h"
|
||||||
#include "client.h"
|
#include "bacnet/basic/services.h"
|
||||||
#include "txbuf.h"
|
#include "bacnet/basic/tsm/tsm.h"
|
||||||
#include "dlenv.h"
|
#include "bacnet/datalink/dlenv.h"
|
||||||
|
|
||||||
/* buffer used for receive */
|
/* 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 */
|
/* global variables used in this file */
|
||||||
static uint32_t Target_Device_Object_Instance = BACNET_MAX_INSTANCE;
|
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 bool Error_Detected = false;
|
||||||
|
|
||||||
static void MyErrorHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
|
static void MyErrorHandler(BACNET_ADDRESS *src,
|
||||||
BACNET_ERROR_CLASS error_class,
|
uint8_t invoke_id,
|
||||||
BACNET_ERROR_CODE error_code)
|
BACNET_ERROR_CLASS error_class,
|
||||||
|
BACNET_ERROR_CODE error_code)
|
||||||
{
|
{
|
||||||
/* FIXME: verify src and invoke id */
|
/* FIXME: verify src and invoke id */
|
||||||
(void)src;
|
(void)src;
|
||||||
(void)invoke_id;
|
(void)invoke_id;
|
||||||
printf("BACnet Error: %s: %s\r\n", bactext_error_class_name(error_class),
|
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;
|
Error_Detected = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MyAbortHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
|
static void MyAbortHandler(
|
||||||
uint8_t abort_reason, bool server)
|
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t abort_reason, bool server)
|
||||||
{
|
{
|
||||||
/* FIXME: verify src and invoke id */
|
/* FIXME: verify src and invoke id */
|
||||||
(void)src;
|
(void)src;
|
||||||
@@ -85,8 +86,8 @@ void MyAbortHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
|
|||||||
Error_Detected = true;
|
Error_Detected = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
|
static void MyRejectHandler(
|
||||||
uint8_t reject_reason)
|
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||||
{
|
{
|
||||||
/* FIXME: verify src and invoke id */
|
/* FIXME: verify src and invoke id */
|
||||||
(void)src;
|
(void)src;
|
||||||
@@ -95,8 +96,8 @@ void MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
|
|||||||
Error_Detected = true;
|
Error_Detected = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MyReinitializeDeviceSimpleAckHandler(BACNET_ADDRESS *src,
|
static void MyReinitializeDeviceSimpleAckHandler(
|
||||||
uint8_t invoke_id)
|
BACNET_ADDRESS *src, uint8_t invoke_id)
|
||||||
{
|
{
|
||||||
(void)src;
|
(void)src;
|
||||||
(void)invoke_id;
|
(void)invoke_id;
|
||||||
@@ -115,21 +116,21 @@ static void Init_Service_Handlers(void)
|
|||||||
It is required to send the proper reject message... */
|
It is required to send the proper reject message... */
|
||||||
apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service);
|
apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service);
|
||||||
/* we must implement read property - it's required! */
|
/* we must implement read property - it's required! */
|
||||||
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY,
|
apdu_set_confirmed_handler(
|
||||||
handler_read_property);
|
SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property);
|
||||||
/* handle the ack coming back */
|
/* handle the ack coming back */
|
||||||
apdu_set_confirmed_simple_ack_handler(SERVICE_CONFIRMED_REINITIALIZE_DEVICE,
|
apdu_set_confirmed_simple_ack_handler(SERVICE_CONFIRMED_REINITIALIZE_DEVICE,
|
||||||
MyReinitializeDeviceSimpleAckHandler);
|
MyReinitializeDeviceSimpleAckHandler);
|
||||||
/* handle any errors coming back */
|
/* handle any errors coming back */
|
||||||
apdu_set_error_handler(SERVICE_CONFIRMED_REINITIALIZE_DEVICE,
|
apdu_set_error_handler(
|
||||||
MyErrorHandler);
|
SERVICE_CONFIRMED_REINITIALIZE_DEVICE, MyErrorHandler);
|
||||||
apdu_set_abort_handler(MyAbortHandler);
|
apdu_set_abort_handler(MyAbortHandler);
|
||||||
apdu_set_reject_handler(MyRejectHandler);
|
apdu_set_reject_handler(MyRejectHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(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;
|
uint16_t pdu_len = 0;
|
||||||
unsigned timeout = 100; /* milliseconds */
|
unsigned timeout = 100; /* milliseconds */
|
||||||
unsigned max_apdu = 0;
|
unsigned max_apdu = 0;
|
||||||
@@ -142,21 +143,20 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
if (argc < 3) {
|
if (argc < 3) {
|
||||||
/* note: priority 16 and 0 should produce the same end results... */
|
/* note: priority 16 and 0 should produce the same end results... */
|
||||||
printf(
|
printf("Usage: %s device-instance state [password]\r\n"
|
||||||
"Usage: %s device-instance state [password]\r\n"
|
"Send BACnet ReinitializeDevice service to device.\r\n"
|
||||||
"Send BACnet ReinitializeDevice service to device.\r\n"
|
"\r\n"
|
||||||
"\r\n"
|
"The device-instance can be 0 to %d.\r\n"
|
||||||
"The device-instance can be 0 to %d.\r\n"
|
"Possible state values:\r\n"
|
||||||
"Possible state values:\r\n"
|
" 0=coldstart\r\n"
|
||||||
" 0=coldstart\r\n"
|
" 1=warmstart\r\n"
|
||||||
" 1=warmstart\r\n"
|
" 2=startbackup\r\n"
|
||||||
" 2=startbackup\r\n"
|
" 3=endbackup\r\n"
|
||||||
" 3=endbackup\r\n"
|
" 4=startrestore\r\n"
|
||||||
" 4=startrestore\r\n"
|
" 5=endrestore\r\n"
|
||||||
" 5=endrestore\r\n"
|
" 6=abortrestore\r\n"
|
||||||
" 6=abortrestore\r\n"
|
"The optional password is a character string of 1 to 20 "
|
||||||
"The optional password is a character string of 1 to 20 "
|
"characters.\r\n",
|
||||||
"characters.\r\n",
|
|
||||||
filename_remove_path(argv[0]), BACNET_MAX_INSTANCE - 1);
|
filename_remove_path(argv[0]), BACNET_MAX_INSTANCE - 1);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -164,12 +164,13 @@ int main(int argc, char *argv[])
|
|||||||
Target_Device_Object_Instance = strtol(argv[1], NULL, 0);
|
Target_Device_Object_Instance = strtol(argv[1], NULL, 0);
|
||||||
Reinitialize_State = strtol(argv[2], NULL, 0);
|
Reinitialize_State = strtol(argv[2], NULL, 0);
|
||||||
/* optional password */
|
/* optional password */
|
||||||
if (argc > 3)
|
if (argc > 3) {
|
||||||
Reinitialize_Password = argv[3];
|
Reinitialize_Password = argv[3];
|
||||||
|
}
|
||||||
|
|
||||||
if (Target_Device_Object_Instance >= BACNET_MAX_INSTANCE) {
|
if (Target_Device_Object_Instance >= BACNET_MAX_INSTANCE) {
|
||||||
fprintf(stderr, "device-instance=%u - it must be less than %u\r\n",
|
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;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -183,11 +184,11 @@ int main(int argc, char *argv[])
|
|||||||
last_seconds = time(NULL);
|
last_seconds = time(NULL);
|
||||||
timeout_seconds = (apdu_timeout() / 1000) * apdu_retries();
|
timeout_seconds = (apdu_timeout() / 1000) * apdu_retries();
|
||||||
/* try to bind with the device */
|
/* try to bind with the device */
|
||||||
found = address_bind_request(Target_Device_Object_Instance, &max_apdu,
|
found = address_bind_request(
|
||||||
&Target_Address);
|
Target_Device_Object_Instance, &max_apdu, &Target_Address);
|
||||||
if (!found) {
|
if (!found) {
|
||||||
Send_WhoIs(Target_Device_Object_Instance,
|
Send_WhoIs(
|
||||||
Target_Device_Object_Instance);
|
Target_Device_Object_Instance, Target_Device_Object_Instance);
|
||||||
}
|
}
|
||||||
/* loop forever */
|
/* loop forever */
|
||||||
for (;;) {
|
for (;;) {
|
||||||
@@ -202,23 +203,24 @@ int main(int argc, char *argv[])
|
|||||||
npdu_handler(&src, &Rx_Buf[0], pdu_len);
|
npdu_handler(&src, &Rx_Buf[0], pdu_len);
|
||||||
}
|
}
|
||||||
/* at least one second has passed */
|
/* at least one second has passed */
|
||||||
if (current_seconds != last_seconds)
|
if (current_seconds != last_seconds) {
|
||||||
tsm_timer_milliseconds(((current_seconds - last_seconds) * 1000));
|
tsm_timer_milliseconds(((current_seconds - last_seconds) * 1000));
|
||||||
|
}
|
||||||
if (Error_Detected)
|
if (Error_Detected)
|
||||||
break;
|
break;
|
||||||
/* wait until the device is bound, or timeout and quit */
|
/* wait until the device is bound, or timeout and quit */
|
||||||
if (!found) {
|
if (!found) {
|
||||||
found = address_bind_request(Target_Device_Object_Instance,
|
found = address_bind_request(
|
||||||
&max_apdu, &Target_Address);
|
Target_Device_Object_Instance, &max_apdu, &Target_Address);
|
||||||
}
|
}
|
||||||
if (found) {
|
if (found) {
|
||||||
if (invoke_id == 0) {
|
if (invoke_id == 0) {
|
||||||
invoke_id = Send_Reinitialize_Device_Request(
|
invoke_id = Send_Reinitialize_Device_Request(
|
||||||
Target_Device_Object_Instance, Reinitialize_State,
|
Target_Device_Object_Instance, Reinitialize_State,
|
||||||
Reinitialize_Password);
|
Reinitialize_Password);
|
||||||
} else if (tsm_invoke_id_free(invoke_id))
|
} else if (tsm_invoke_id_free(invoke_id)) {
|
||||||
break;
|
break;
|
||||||
else if (tsm_invoke_id_failed(invoke_id)) {
|
} else if (tsm_invoke_id_failed(invoke_id)) {
|
||||||
fprintf(stderr, "\rError: TSM Timeout!\r\n");
|
fprintf(stderr, "\rError: TSM Timeout!\r\n");
|
||||||
tsm_free_invoke_id(invoke_id);
|
tsm_free_invoke_id(invoke_id);
|
||||||
/* try again or abort? */
|
/* try again or abort? */
|
||||||
@@ -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
|
||||||
@@ -36,28 +36,33 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
#include "bacdef.h"
|
#include "bacnet/bacdef.h"
|
||||||
#include "config.h"
|
#include "bacnet/config.h"
|
||||||
#include "debug.h"
|
#include "bacnet/bactext.h"
|
||||||
#include "bactext.h"
|
#include "bacnet/bacerror.h"
|
||||||
#include "bacerror.h"
|
#include "bacnet/iam.h"
|
||||||
#include "iam.h"
|
#include "bacnet/arf.h"
|
||||||
#include "arf.h"
|
#include "bacnet/npdu.h"
|
||||||
#include "tsm.h"
|
#include "bacnet/apdu.h"
|
||||||
#include "address.h"
|
#include "bacnet/version.h"
|
||||||
#include "npdu.h"
|
/* some demo modules we use */
|
||||||
#include "apdu.h"
|
#include "bacnet/basic/sys/debug.h"
|
||||||
#include "client.h"
|
#include "bacnet/basic/tsm/tsm.h"
|
||||||
#include "net.h"
|
#include "bacnet/basic/binding/address.h"
|
||||||
#include "version.h"
|
#include "bacnet/basic/services.h"
|
||||||
|
/* port agnostic file */
|
||||||
|
#include "bacport.h"
|
||||||
/* our datalink layers */
|
/* our datalink layers */
|
||||||
#include "bvlc6.h"
|
#include "bacnet/datalink/bvlc6.h"
|
||||||
#include "bip6.h"
|
#include "bacnet/datalink/bip6.h"
|
||||||
|
#include "bacnet/basic/bbmd6/h_bbmd6.h"
|
||||||
#undef MAX_HEADER
|
#undef MAX_HEADER
|
||||||
#undef MAX_MPDU
|
#undef MAX_MPDU
|
||||||
#include "bip.h"
|
#include "bacnet/datalink/bip.h"
|
||||||
#include "bvlc.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
|
* 6.6.1 Routing Tables
|
||||||
@@ -320,9 +325,11 @@ static void datalink_get_broadcast_address(BACNET_ADDRESS *dest)
|
|||||||
*
|
*
|
||||||
* @return number of bytes sent
|
* @return number of bytes sent
|
||||||
*/
|
*/
|
||||||
static int datalink_send_pdu(uint16_t snet, BACNET_ADDRESS *dest,
|
static int datalink_send_pdu(uint16_t snet,
|
||||||
BACNET_NPDU_DATA *npdu_data, uint8_t *pdu,
|
BACNET_ADDRESS *dest,
|
||||||
unsigned int pdu_len)
|
BACNET_NPDU_DATA *npdu_data,
|
||||||
|
uint8_t *pdu,
|
||||||
|
unsigned int pdu_len)
|
||||||
{
|
{
|
||||||
int bytes_sent = 0;
|
int bytes_sent = 0;
|
||||||
|
|
||||||
@@ -341,36 +348,6 @@ static int datalink_send_pdu(uint16_t snet, BACNET_ADDRESS *dest,
|
|||||||
return bytes_sent;
|
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
|
* 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);
|
datalink_get_broadcast_address(&dest);
|
||||||
npdu_encode_npdu_network(&npdu_data, NETWORK_MESSAGE_I_AM_ROUTER_TO_NETWORK,
|
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
|
/* We don't need src information, since a message can't originate from
|
||||||
our downstream BACnet network. */
|
our downstream BACnet network. */
|
||||||
pdu_len = npdu_encode_pdu(&Tx_Buffer[0], &dest, NULL, &npdu_data);
|
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,
|
* Optionally may designate a particular router destination,
|
||||||
* especially when ACKing receipt of this message type.
|
* 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;
|
BACNET_ADDRESS dest;
|
||||||
bool data_expecting_reply = false;
|
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);
|
datalink_get_broadcast_address(&dest);
|
||||||
}
|
}
|
||||||
npdu_encode_npdu_network(&npdu_data, NETWORK_MESSAGE_INIT_RT_TABLE_ACK,
|
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
|
/* We don't need src information, since a message can't originate from
|
||||||
our downstream BACnet network. */
|
our downstream BACnet network. */
|
||||||
pdu_len = npdu_encode_pdu(&Tx_Buffer[0], &dest, NULL, &npdu_data);
|
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.
|
* destination.
|
||||||
* @param reject_reason [in] One of the BACNET_NETWORK_REJECT_REASONS codes.
|
* @param reject_reason [in] One of the BACNET_NETWORK_REJECT_REASONS codes.
|
||||||
*/
|
*/
|
||||||
void send_reject_message_to_network(uint16_t snet, BACNET_ADDRESS *dst,
|
static void send_reject_message_to_network(
|
||||||
uint8_t reject_reason, uint16_t dnet)
|
uint16_t snet, BACNET_ADDRESS *dst, uint8_t reject_reason, uint16_t dnet)
|
||||||
{
|
{
|
||||||
BACNET_ADDRESS dest;
|
BACNET_ADDRESS dest;
|
||||||
bool data_expecting_reply = false;
|
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);
|
datalink_get_broadcast_address(&dest);
|
||||||
}
|
}
|
||||||
npdu_encode_npdu_network(&npdu_data,
|
npdu_encode_npdu_network(&npdu_data,
|
||||||
NETWORK_MESSAGE_REJECT_MESSAGE_TO_NETWORK,
|
NETWORK_MESSAGE_REJECT_MESSAGE_TO_NETWORK, data_expecting_reply,
|
||||||
data_expecting_reply, MESSAGE_PRIORITY_NORMAL);
|
MESSAGE_PRIORITY_NORMAL);
|
||||||
/* We don't need src information, since a message can't originate from
|
/* We don't need src information, since a message can't originate from
|
||||||
our downstream BACnet network. */
|
our downstream BACnet network. */
|
||||||
pdu_len = npdu_encode_pdu(&Tx_Buffer[0], &dest, NULL, &npdu_data);
|
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);
|
datalink_get_broadcast_address(&dest);
|
||||||
npdu_encode_npdu_network(&npdu_data,
|
npdu_encode_npdu_network(&npdu_data,
|
||||||
NETWORK_MESSAGE_WHO_IS_ROUTER_TO_NETWORK,
|
NETWORK_MESSAGE_WHO_IS_ROUTER_TO_NETWORK, data_expecting_reply,
|
||||||
data_expecting_reply, MESSAGE_PRIORITY_NORMAL);
|
MESSAGE_PRIORITY_NORMAL);
|
||||||
pdu_len = npdu_encode_pdu(&Tx_Buffer[0], &dest, NULL, &npdu_data);
|
pdu_len = npdu_encode_pdu(&Tx_Buffer[0], &dest, NULL, &npdu_data);
|
||||||
if (dnet) {
|
if (dnet) {
|
||||||
len = encode_unsigned16(&Tx_Buffer[pdu_len], 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.
|
* bytes that have already been decoded.
|
||||||
* @param npdu_len [in] The length of the remaining NPDU message in npdu[].
|
* @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,
|
static void who_is_router_to_network_handler(uint16_t snet,
|
||||||
BACNET_NPDU_DATA *npdu_data,
|
BACNET_ADDRESS *src,
|
||||||
uint8_t *npdu, uint16_t npdu_len)
|
BACNET_NPDU_DATA *npdu_data,
|
||||||
|
uint8_t *npdu,
|
||||||
|
uint16_t npdu_len)
|
||||||
{
|
{
|
||||||
DNET *port = NULL;
|
DNET *port = NULL;
|
||||||
uint16_t network = 0;
|
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.
|
* bytes that have already been decoded.
|
||||||
* @param npdu_len [in] The length of the remaining NPDU message in npdu[].
|
* @param npdu_len [in] The length of the remaining NPDU message in npdu[].
|
||||||
*/
|
*/
|
||||||
static void network_control_handler(uint16_t snet, BACNET_ADDRESS *src,
|
static void network_control_handler(uint16_t snet,
|
||||||
BACNET_NPDU_DATA *npdu_data, uint8_t *npdu,
|
BACNET_ADDRESS *src,
|
||||||
uint16_t npdu_len)
|
BACNET_NPDU_DATA *npdu_data,
|
||||||
|
uint8_t *npdu,
|
||||||
|
uint16_t npdu_len)
|
||||||
{
|
{
|
||||||
uint16_t npdu_offset = 0;
|
uint16_t npdu_offset = 0;
|
||||||
uint16_t dnet = 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);
|
fprintf(stderr, "Received %s\n", msg_name);
|
||||||
switch (npdu_data->network_message_type) {
|
switch (npdu_data->network_message_type) {
|
||||||
case NETWORK_MESSAGE_WHO_IS_ROUTER_TO_NETWORK:
|
case NETWORK_MESSAGE_WHO_IS_ROUTER_TO_NETWORK:
|
||||||
who_is_router_to_network_handler(snet, src, npdu_data, npdu,
|
who_is_router_to_network_handler(
|
||||||
npdu_len);
|
snet, src, npdu_data, npdu, npdu_len);
|
||||||
break;
|
break;
|
||||||
case NETWORK_MESSAGE_I_AM_ROUTER_TO_NETWORK:
|
case NETWORK_MESSAGE_I_AM_ROUTER_TO_NETWORK:
|
||||||
/* add its DNETs to our routing table */
|
/* 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");
|
fprintf(stderr, "Reason: Network is busy.\n");
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
fprintf(stderr,
|
fprintf(
|
||||||
"Reason: Unknown network message type.\n");
|
stderr, "Reason: Unknown network message type.\n");
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
fprintf(stderr, "Reason: Message too long.\n");
|
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 snet [in] The source network port where the message came from
|
||||||
* @param src [in] The BACNET_ADDRESS of the message's original src.
|
* @param src [in] The BACNET_ADDRESS of the message's original src.
|
||||||
*/
|
*/
|
||||||
static void routed_src_address(BACNET_ADDRESS *router_src, uint16_t snet,
|
static void routed_src_address(
|
||||||
BACNET_ADDRESS *src)
|
BACNET_ADDRESS *router_src, uint16_t snet, BACNET_ADDRESS *src)
|
||||||
{
|
{
|
||||||
unsigned int i = 0;
|
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 [in] The apdu portion of the request, to be processed.
|
||||||
* @param apdu_len [in] The total (remaining) length of the apdu.
|
* @param apdu_len [in] The total (remaining) length of the apdu.
|
||||||
*/
|
*/
|
||||||
static void routed_apdu_handler(uint16_t snet, BACNET_NPDU_DATA *npdu,
|
static void routed_apdu_handler(uint16_t snet,
|
||||||
BACNET_ADDRESS *src, BACNET_ADDRESS *dest,
|
BACNET_NPDU_DATA *npdu,
|
||||||
uint8_t *apdu, uint16_t apdu_len)
|
BACNET_ADDRESS *src,
|
||||||
|
BACNET_ADDRESS *dest,
|
||||||
|
uint8_t *apdu,
|
||||||
|
uint16_t apdu_len)
|
||||||
{
|
{
|
||||||
DNET *port = NULL;
|
DNET *port = NULL;
|
||||||
BACNET_ADDRESS local_dest;
|
BACNET_ADDRESS local_dest;
|
||||||
@@ -874,7 +858,7 @@ static void routed_apdu_handler(uint16_t snet, BACNET_NPDU_DATA *npdu,
|
|||||||
while (port != NULL) {
|
while (port != NULL) {
|
||||||
if (port->net != snet) {
|
if (port->net != snet) {
|
||||||
datalink_send_pdu(port->net, &local_dest, npdu, &Tx_Buffer[0],
|
datalink_send_pdu(port->net, &local_dest, npdu, &Tx_Buffer[0],
|
||||||
npdu_len + apdu_len);
|
npdu_len + apdu_len);
|
||||||
}
|
}
|
||||||
port = port->next;
|
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);
|
npdu_encode_pdu(&Tx_Buffer[0], &local_dest, &router_src, npdu);
|
||||||
memmove(&Tx_Buffer[npdu_len], apdu, apdu_len);
|
memmove(&Tx_Buffer[npdu_len], apdu, apdu_len);
|
||||||
datalink_send_pdu(port->net, &local_dest, npdu, &Tx_Buffer[0],
|
datalink_send_pdu(port->net, &local_dest, npdu, &Tx_Buffer[0],
|
||||||
npdu_len + apdu_len);
|
npdu_len + apdu_len);
|
||||||
} else {
|
} else {
|
||||||
debug_printf("Routing to another Router %u\n",
|
debug_printf(
|
||||||
(unsigned)remote_dest.net);
|
"Routing to another Router %u\n", (unsigned)remote_dest.net);
|
||||||
/* Case 2: the message must be
|
/* Case 2: the message must be
|
||||||
relayed to another router for further transmission */
|
relayed to another router for further transmission */
|
||||||
/* In the second case, if the Hop Count is greater than zero,
|
/* 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);
|
npdu_encode_pdu(&Tx_Buffer[0], &remote_dest, &router_src, npdu);
|
||||||
memmove(&Tx_Buffer[npdu_len], apdu, apdu_len);
|
memmove(&Tx_Buffer[npdu_len], apdu, apdu_len);
|
||||||
datalink_send_pdu(port->net, &remote_dest, npdu, &Tx_Buffer[0],
|
datalink_send_pdu(port->net, &remote_dest, npdu, &Tx_Buffer[0],
|
||||||
npdu_len + apdu_len);
|
npdu_len + apdu_len);
|
||||||
}
|
}
|
||||||
} else if (dest->net) {
|
} else if (dest->net) {
|
||||||
debug_printf("Routing to Unknown Route %u\n", (unsigned)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);
|
routed_src_address(&router_src, snet, src);
|
||||||
npdu_len = npdu_encode_pdu(&Tx_Buffer[0], dest, &router_src, npdu);
|
npdu_len = npdu_encode_pdu(&Tx_Buffer[0], dest, &router_src, npdu);
|
||||||
memmove(&Tx_Buffer[npdu_len], apdu, apdu_len);
|
memmove(&Tx_Buffer[npdu_len], apdu, apdu_len);
|
||||||
datalink_send_pdu(port->net, dest, npdu, &Tx_Buffer[0],
|
datalink_send_pdu(
|
||||||
npdu_len + apdu_len);
|
port->net, dest, npdu, &Tx_Buffer[0], npdu_len + apdu_len);
|
||||||
/* If the next router is unknown, an attempt shall be made to
|
/* If the next router is unknown, an attempt shall be made to
|
||||||
identify it using a Who-Is-Router-To-Network message. */
|
identify it using a Who-Is-Router-To-Network message. */
|
||||||
send_who_is_router_to_network(0, dest->net);
|
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 [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.
|
* @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,
|
static void my_routing_npdu_handler(
|
||||||
uint8_t *pdu, uint16_t pdu_len)
|
uint16_t snet, BACNET_ADDRESS *src, uint8_t *pdu, uint16_t pdu_len)
|
||||||
{
|
{
|
||||||
int apdu_offset = 0;
|
int apdu_offset = 0;
|
||||||
BACNET_ADDRESS dest = {0};
|
BACNET_ADDRESS dest = { 0 };
|
||||||
BACNET_NPDU_DATA npdu_data = {0};
|
BACNET_NPDU_DATA npdu_data = { 0 };
|
||||||
|
|
||||||
if (!pdu) {
|
if (!pdu) {
|
||||||
/* no packet */
|
/* 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) {
|
} else if (npdu_data.network_layer_message) {
|
||||||
if ((dest.net == 0) || (dest.net == BACNET_BROADCAST_NETWORK)) {
|
if ((dest.net == 0) || (dest.net == BACNET_BROADCAST_NETWORK)) {
|
||||||
network_control_handler(snet, src, &npdu_data,
|
network_control_handler(snet, src, &npdu_data,
|
||||||
&pdu[apdu_offset],
|
&pdu[apdu_offset], (uint16_t)(pdu_len - apdu_offset));
|
||||||
(uint16_t)(pdu_len - apdu_offset));
|
|
||||||
} else {
|
} else {
|
||||||
/* The DNET is set, but we don't support downstream routers,
|
/* The DNET is set, but we don't support downstream routers,
|
||||||
* so we just silently drop this network layer message,
|
* 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 */
|
routing information cause they are not for us */
|
||||||
if ((dest.net == BACNET_BROADCAST_NETWORK) &&
|
if ((dest.net == BACNET_BROADCAST_NETWORK) &&
|
||||||
((pdu[apdu_offset] & 0xF0) ==
|
((pdu[apdu_offset] & 0xF0) ==
|
||||||
PDU_TYPE_CONFIRMED_SERVICE_REQUEST)) {
|
PDU_TYPE_CONFIRMED_SERVICE_REQUEST)) {
|
||||||
/* hack for 5.4.5.1 - IDLE */
|
/* hack for 5.4.5.1 - IDLE */
|
||||||
/* ConfirmedBroadcastReceived */
|
/* ConfirmedBroadcastReceived */
|
||||||
/* then enter IDLE - ignore the PDU */
|
/* then enter IDLE - ignore the PDU */
|
||||||
} else {
|
} else {
|
||||||
routed_apdu_handler(snet, &npdu_data, src, &dest,
|
routed_apdu_handler(snet, &npdu_data, src, &dest,
|
||||||
&pdu[apdu_offset],
|
&pdu[apdu_offset], (uint16_t)(pdu_len - apdu_offset));
|
||||||
(uint16_t)(pdu_len - apdu_offset));
|
|
||||||
/* add a Device object and application layer */
|
/* add a Device object and application layer */
|
||||||
if ((dest.net == 0) ||
|
if ((dest.net == 0) ||
|
||||||
(dest.net == BACNET_BROADCAST_NETWORK)) {
|
(dest.net == BACNET_BROADCAST_NETWORK)) {
|
||||||
apdu_handler(src, &pdu[apdu_offset],
|
apdu_handler(src, &pdu[apdu_offset],
|
||||||
(uint16_t)(pdu_len - apdu_offset));
|
(uint16_t)(pdu_len - apdu_offset));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "NPDU: DNET=%u. Discarded!\n",
|
fprintf(
|
||||||
(unsigned)dest.net);
|
stderr, "NPDU: DNET=%u. Discarded!\n", (unsigned)dest.net);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -1015,7 +997,7 @@ static void my_routing_npdu_handler(uint16_t snet, BACNET_ADDRESS *src,
|
|||||||
static void datalink_init(void)
|
static void datalink_init(void)
|
||||||
{
|
{
|
||||||
char *pEnv = NULL;
|
char *pEnv = NULL;
|
||||||
BACNET_ADDRESS my_address = {0};
|
BACNET_ADDRESS my_address = { 0 };
|
||||||
extern bool BIP_Debug;
|
extern bool BIP_Debug;
|
||||||
|
|
||||||
/* BACnet/IP Initialization */
|
/* BACnet/IP Initialization */
|
||||||
@@ -1047,7 +1029,7 @@ static void datalink_init(void)
|
|||||||
if (pEnv) {
|
if (pEnv) {
|
||||||
BACNET_IP6_ADDRESS addr;
|
BACNET_IP6_ADDRESS addr;
|
||||||
bvlc6_address_set(&addr, (uint16_t)strtol(pEnv, NULL, 0), 0, 0, 0, 0, 0,
|
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);
|
bip6_set_broadcast_addr(&addr);
|
||||||
}
|
}
|
||||||
if (!bip6_init(getenv("BACNET_BIP6_IFACE"))) {
|
if (!bip6_init(getenv("BACNET_BIP6_IFACE"))) {
|
||||||
@@ -1110,7 +1092,7 @@ static BOOL WINAPI CtrlCHandler(DWORD dwCtrlType)
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void control_c_hooks(void)
|
static void control_c_hooks(void)
|
||||||
{
|
{
|
||||||
SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), ENABLE_PROCESSED_INPUT);
|
SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), ENABLE_PROCESSED_INPUT);
|
||||||
SetConsoleCtrlHandler((PHANDLER_ROUTINE)CtrlCHandler, TRUE);
|
SetConsoleCtrlHandler((PHANDLER_ROUTINE)CtrlCHandler, TRUE);
|
||||||
@@ -1123,14 +1105,14 @@ static void sig_int(int signo)
|
|||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void signal_init(void)
|
static void signal_init(void)
|
||||||
{
|
{
|
||||||
signal(SIGINT, sig_int);
|
signal(SIGINT, sig_int);
|
||||||
signal(SIGHUP, sig_int);
|
signal(SIGHUP, sig_int);
|
||||||
signal(SIGTERM, sig_int);
|
signal(SIGTERM, sig_int);
|
||||||
}
|
}
|
||||||
|
|
||||||
void control_c_hooks(void)
|
static void control_c_hooks(void)
|
||||||
{
|
{
|
||||||
signal_init();
|
signal_init();
|
||||||
}
|
}
|
||||||
@@ -1145,7 +1127,7 @@ void control_c_hooks(void)
|
|||||||
*/
|
*/
|
||||||
int main(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;
|
uint16_t pdu_len = 0;
|
||||||
time_t last_seconds = 0;
|
time_t last_seconds = 0;
|
||||||
time_t current_seconds = 0;
|
time_t current_seconds = 0;
|
||||||
@@ -1179,8 +1161,8 @@ int main(int argc, char *argv[])
|
|||||||
/* process */
|
/* process */
|
||||||
if (pdu_len) {
|
if (pdu_len) {
|
||||||
debug_printf("BACnet/IPv6 Received packet\n");
|
debug_printf("BACnet/IPv6 Received packet\n");
|
||||||
my_routing_npdu_handler(BIP6_Net, &src, &BIP6_Rx_Buffer[0],
|
my_routing_npdu_handler(
|
||||||
pdu_len);
|
BIP6_Net, &src, &BIP6_Rx_Buffer[0], pdu_len);
|
||||||
}
|
}
|
||||||
/* at least one second has passed */
|
/* at least one second has passed */
|
||||||
elapsed_seconds = (uint32_t)(current_seconds - last_seconds);
|
elapsed_seconds = (uint32_t)(current_seconds - last_seconds);
|
||||||
@@ -30,17 +30,17 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "ipmodule.h"
|
#include "ipmodule.h"
|
||||||
#include "bacint.h"
|
#include "bacnet/bacint.h"
|
||||||
|
|
||||||
#ifdef TEST_PACKET
|
#ifdef TEST_PACKET
|
||||||
uint8_t test_packet[] = {0x81, 0x0a, 0x00, 0x16, /* BVLC header */
|
uint8_t test_packet[] = { 0x81, 0x0a, 0x00, 0x16, /* BVLC header */
|
||||||
0x01, 0x24, 0x00, 0x01, 0x01, 0x0b, 0xff, /* NPDU */
|
0x01, 0x24, 0x00, 0x01, 0x01, 0x0b, 0xff, /* NPDU */
|
||||||
0x00, 0x03, 0x01, 0x0c, 0x0c, 0x00, 0x00,
|
0x00, 0x03, 0x01, 0x0c, 0x0c, 0x00, 0x00, 0x00, 0x02, 0x19,
|
||||||
0x00, 0x02, 0x19, 0x55}; /* APDU */
|
0x55 }; /* APDU */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern int get_local_address_ioctl(char *ifname, struct in_addr *addr,
|
extern int get_local_address_ioctl(
|
||||||
int request);
|
char *ifname, struct in_addr *addr, int request);
|
||||||
|
|
||||||
void *dl_ip_thread(void *pArgs)
|
void *dl_ip_thread(void *pArgs)
|
||||||
{
|
{
|
||||||
@@ -49,7 +49,7 @@ void *dl_ip_thread(void *pArgs)
|
|||||||
MSG_DATA *msg_data;
|
MSG_DATA *msg_data;
|
||||||
ROUTER_PORT *port = (ROUTER_PORT *)pArgs;
|
ROUTER_PORT *port = (ROUTER_PORT *)pArgs;
|
||||||
IP_DATA ip_data; /* port specific parameters */
|
IP_DATA ip_data; /* port specific parameters */
|
||||||
BACNET_ADDRESS address = {0};
|
BACNET_ADDRESS address = { 0 };
|
||||||
int status;
|
int status;
|
||||||
uint8_t shutdown = 0;
|
uint8_t shutdown = 0;
|
||||||
|
|
||||||
@@ -88,11 +88,11 @@ void *dl_ip_thread(void *pArgs)
|
|||||||
msg_data = (MSG_DATA *)bacmsg->data;
|
msg_data = (MSG_DATA *)bacmsg->data;
|
||||||
memmove(&address.net, &msg_data->dest.net, 2);
|
memmove(&address.net, &msg_data->dest.net, 2);
|
||||||
memmove(&address.mac_len, &msg_data->dest.len, 1);
|
memmove(&address.mac_len, &msg_data->dest.len, 1);
|
||||||
memmove(&address.mac[0], &msg_data->dest.adr[0],
|
memmove(
|
||||||
MAX_MAC_LEN);
|
&address.mac[0], &msg_data->dest.adr[0], MAX_MAC_LEN);
|
||||||
|
|
||||||
dl_ip_send(&ip_data, &address, msg_data->pdu,
|
dl_ip_send(
|
||||||
msg_data->pdu_len);
|
&ip_data, &address, msg_data->pdu, msg_data->pdu_len);
|
||||||
|
|
||||||
check_data(msg_data);
|
check_data(msg_data);
|
||||||
|
|
||||||
@@ -152,28 +152,29 @@ bool dl_ip_init(ROUTER_PORT *port, IP_DATA *ip_data)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
/* get broadcast address */
|
/* get broadcast address */
|
||||||
status = get_local_address_ioctl(port->iface, &ip_data->broadcast_addr,
|
status = get_local_address_ioctl(
|
||||||
SIOCGIFBRDADDR);
|
port->iface, &ip_data->broadcast_addr, SIOCGIFBRDADDR);
|
||||||
if (status < 0) {
|
if (status < 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ip_data->socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
ip_data->socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||||
if (ip_data->socket < 0)
|
if (ip_data->socket < 0) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/* setup socket options */
|
/* setup socket options */
|
||||||
|
|
||||||
socket_opt = 1;
|
socket_opt = 1;
|
||||||
status = setsockopt(ip_data->socket, SOL_SOCKET, SO_REUSEADDR, &socket_opt,
|
status = setsockopt(ip_data->socket, SOL_SOCKET, SO_REUSEADDR, &socket_opt,
|
||||||
sizeof(socket_opt));
|
sizeof(socket_opt));
|
||||||
if (status < 0) {
|
if (status < 0) {
|
||||||
close(ip_data->socket);
|
close(ip_data->socket);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
status = setsockopt(ip_data->socket, SOL_SOCKET, SO_BROADCAST, &socket_opt,
|
status = setsockopt(ip_data->socket, SOL_SOCKET, SO_BROADCAST, &socket_opt,
|
||||||
sizeof(socket_opt));
|
sizeof(socket_opt));
|
||||||
if (status < 0) {
|
if (status < 0) {
|
||||||
close(ip_data->socket);
|
close(ip_data->socket);
|
||||||
return false;
|
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));
|
memset(&sin.sin_zero, '\0', sizeof(sin.sin_zero));
|
||||||
|
|
||||||
status = bind(ip_data->socket, (const struct sockaddr *)&sin,
|
status = bind(ip_data->socket, (const struct sockaddr *)&sin,
|
||||||
sizeof(struct sockaddr));
|
sizeof(struct sockaddr));
|
||||||
if (status < 0) {
|
if (status < 0) {
|
||||||
close(ip_data->socket);
|
close(ip_data->socket);
|
||||||
return false;
|
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, "Interface: %s\n", port->iface);
|
||||||
PRINT(INFO, "IP Address: %s\n", inet_ntoa(ip_data->local_addr));
|
PRINT(INFO, "IP Address: %s\n", inet_ntoa(ip_data->local_addr));
|
||||||
PRINT(INFO, "IP Broadcast Address: %s\n",
|
PRINT(
|
||||||
inet_ntoa(ip_data->broadcast_addr));
|
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),
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dl_ip_send(IP_DATA *data, BACNET_ADDRESS *dest, uint8_t *pdu,
|
int dl_ip_send(
|
||||||
unsigned pdu_len)
|
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 buff_len = 0;
|
||||||
int bytes_sent = 0;
|
int bytes_sent = 0;
|
||||||
|
|
||||||
if (data->socket < 0)
|
if (data->socket < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
data->buff[0] = BVLL_TYPE_BACNET_IP;
|
data->buff[0] = BVLL_TYPE_BACNET_IP;
|
||||||
bip_dest.sin_family = AF_INET;
|
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 = 2;
|
||||||
buff_len += encode_unsigned16(&data->buff[buff_len],
|
buff_len += encode_unsigned16(
|
||||||
(uint16_t)(pdu_len + 4 /*inclusive */));
|
&data->buff[buff_len], (uint16_t)(pdu_len + 4 /*inclusive */));
|
||||||
memcpy(&data->buff[buff_len], pdu, pdu_len);
|
memcpy(&data->buff[buff_len], pdu, pdu_len);
|
||||||
buff_len += pdu_len;
|
buff_len += pdu_len;
|
||||||
|
|
||||||
/* send the packet */
|
/* send the packet */
|
||||||
bytes_sent = sendto(data->socket, (char *)data->buff, buff_len, 0,
|
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));
|
PRINT(DEBUG, "send to %s\n", inet_ntoa(bip_dest.sin_addr));
|
||||||
|
|
||||||
return bytes_sent;
|
return bytes_sent;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dl_ip_recv(IP_DATA *data, MSG_DATA **msg_data, BACNET_ADDRESS *src,
|
int dl_ip_recv(
|
||||||
unsigned timeout)
|
IP_DATA *data, MSG_DATA **msg_data, BACNET_ADDRESS *src, unsigned timeout)
|
||||||
{
|
{
|
||||||
int received_bytes = 0;
|
int received_bytes = 0;
|
||||||
uint16_t buff_len = 0; /* return value */
|
uint16_t buff_len = 0; /* return value */
|
||||||
fd_set read_fds;
|
fd_set read_fds;
|
||||||
struct timeval select_timeout;
|
struct timeval select_timeout;
|
||||||
struct sockaddr_in sin = {0};
|
struct sockaddr_in sin = { 0 };
|
||||||
socklen_t sin_len = sizeof(sin);
|
socklen_t sin_len = sizeof(sin);
|
||||||
|
|
||||||
/* make sure the socket is open */
|
/* make sure the socket is open */
|
||||||
if (data->socket < 0)
|
if (data->socket < 0) {
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (timeout >= 1000) {
|
if (timeout >= 1000) {
|
||||||
select_timeout.tv_sec = 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
|
#else
|
||||||
int ret = select(data->socket + 1, &read_fds, NULL, NULL, &select_timeout);
|
int ret = select(data->socket + 1, &read_fds, NULL, NULL, &select_timeout);
|
||||||
/* see if there is a packet for us */
|
/* see if there is a packet for us */
|
||||||
if (ret > 0)
|
if (ret > 0) {
|
||||||
received_bytes =
|
received_bytes = recvfrom(data->socket, (char *)&data->buff[0],
|
||||||
recvfrom(data->socket, (char *)&data->buff[0], data->max_buff, 0,
|
data->max_buff, 0, (struct sockaddr *)&sin, &sin_len);
|
||||||
(struct sockaddr *)&sin, &sin_len);
|
} else {
|
||||||
else
|
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
PRINT(DEBUG, "received from %s\n", inet_ntoa(sin.sin_addr));
|
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);
|
(*msg_data)->pdu = (uint8_t *)malloc((*msg_data)->pdu_len);
|
||||||
/* fill up data message structure */
|
/* fill up data message structure */
|
||||||
memmove(&(*msg_data)->pdu[0], &data->buff[4],
|
memmove(&(*msg_data)->pdu[0], &data->buff[4],
|
||||||
(*msg_data)->pdu_len);
|
(*msg_data)->pdu_len);
|
||||||
memmove(&(*msg_data)->src, src, sizeof(BACNET_ADDRESS));
|
memmove(&(*msg_data)->src, src, sizeof(BACNET_ADDRESS));
|
||||||
}
|
}
|
||||||
/* ignore packets that are too large */
|
/* 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);
|
(*msg_data)->pdu = (uint8_t *)malloc((*msg_data)->pdu_len);
|
||||||
/* fill up data message structure */
|
/* fill up data message structure */
|
||||||
memmove(&(*msg_data)->pdu[0], &data->buff[4 + 6],
|
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));
|
memmove(&(*msg_data)->src, src, sizeof(BACNET_ADDRESS));
|
||||||
} else {
|
} else {
|
||||||
/* ignore packets that are too large */
|
/* 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)
|
void dl_ip_cleanup(IP_DATA *ip_data)
|
||||||
{
|
{
|
||||||
/* free buffer */
|
/* free buffer */
|
||||||
if (ip_data->buff)
|
if (ip_data->buff) {
|
||||||
free(ip_data->buff);
|
free(ip_data->buff);
|
||||||
|
}
|
||||||
/* close socket */
|
/* close socket */
|
||||||
if (ip_data->socket > 0)
|
if (ip_data->socket > 0) {
|
||||||
close(ip_data->socket);
|
close(ip_data->socket);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -32,7 +32,7 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include "portthread.h"
|
#include "portthread.h"
|
||||||
#include "bip.h"
|
#include "bacnet/datalink/bip.h"
|
||||||
|
|
||||||
#define MAX_BIP_APDU 1476
|
#define MAX_BIP_APDU 1476
|
||||||
#define MAX_BIP_PDU (MAX_NPDU + MAX_BIP_APDU)
|
#define MAX_BIP_PDU (MAX_NPDU + MAX_BIP_APDU)
|
||||||
@@ -40,8 +40,8 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <libconfig.h> /* read config files */
|
#include <libconfig.h> /* read config files */
|
||||||
#include <unistd.h> /* for getopt */
|
#include <unistd.h> /* for getopt */
|
||||||
#include <termios.h> /* used in kbhit() */
|
#include <termios.h> /* used in kbhit() */
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <net/if.h>
|
#include <net/if.h>
|
||||||
@@ -103,8 +103,8 @@ int main(int argc, char *argv[])
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
send_network_message(NETWORK_MESSAGE_I_AM_ROUTER_TO_NETWORK, msg_data,
|
send_network_message(
|
||||||
&buff, NULL);
|
NETWORK_MESSAGE_I_AM_ROUTER_TO_NETWORK, msg_data, &buff, NULL);
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
if (kbhit()) {
|
if (kbhit()) {
|
||||||
@@ -160,7 +160,7 @@ int main(int argc, char *argv[])
|
|||||||
msg_data->ref_count = 1;
|
msg_data->ref_count = 1;
|
||||||
send_to_msgbox(msg_src, &msg_storage);
|
send_to_msgbox(msg_src, &msg_storage);
|
||||||
} else if (msg_data->dest.net !=
|
} else if (msg_data->dest.net !=
|
||||||
BACNET_BROADCAST_NETWORK) {
|
BACNET_BROADCAST_NETWORK) {
|
||||||
msg_data->ref_count = 1;
|
msg_data->ref_count = 1;
|
||||||
port =
|
port =
|
||||||
find_dnet(msg_data->dest.net, &msg_data->dest);
|
find_dnet(msg_data->dest.net, &msg_data->dest);
|
||||||
@@ -232,7 +232,7 @@ bool read_config(char *filepath)
|
|||||||
/* open configuration file */
|
/* open configuration file */
|
||||||
if (!config_read_file(&cfg, filepath)) {
|
if (!config_read_file(&cfg, filepath)) {
|
||||||
PRINT(ERROR, "Config file error: %d - %s\n", config_error_line(&cfg),
|
PRINT(ERROR, "Config file error: %d - %s\n", config_error_line(&cfg),
|
||||||
config_error_text(&cfg));
|
config_error_text(&cfg));
|
||||||
config_destroy(&cfg);
|
config_destroy(&cfg);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -281,13 +281,13 @@ bool read_config(char *filepath)
|
|||||||
if (fd) {
|
if (fd) {
|
||||||
struct ifreq ifr;
|
struct ifreq ifr;
|
||||||
strncpy(ifr.ifr_name, current->iface,
|
strncpy(ifr.ifr_name, current->iface,
|
||||||
sizeof(ifr.ifr_name) - 1);
|
sizeof(ifr.ifr_name) - 1);
|
||||||
result = ioctl(fd, SIOCGIFADDR, &ifr);
|
result = ioctl(fd, SIOCGIFADDR, &ifr);
|
||||||
if (result != -1) {
|
if (result != -1) {
|
||||||
close(fd);
|
close(fd);
|
||||||
} else {
|
} else {
|
||||||
PRINT(ERROR,
|
PRINT(ERROR,
|
||||||
"Error: Invalid interface for BIP device\n");
|
"Error: Invalid interface for BIP device\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -324,7 +324,7 @@ bool read_config(char *filepath)
|
|||||||
close(fd);
|
close(fd);
|
||||||
} else {
|
} else {
|
||||||
PRINT(ERROR,
|
PRINT(ERROR,
|
||||||
"Error: Invalid interface for MSTP device\n");
|
"Error: Invalid interface for MSTP device\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -338,15 +338,15 @@ bool read_config(char *filepath)
|
|||||||
current->route_info.mac[0] = 127;
|
current->route_info.mac[0] = 127;
|
||||||
current->route_info.mac_len = 1;
|
current->route_info.mac_len = 1;
|
||||||
}
|
}
|
||||||
result = config_setting_lookup_int(port, "max_master",
|
result = config_setting_lookup_int(
|
||||||
(int *)¶m);
|
port, "max_master", (int *)¶m);
|
||||||
if (result) {
|
if (result) {
|
||||||
current->params.mstp_params.max_master = param;
|
current->params.mstp_params.max_master = param;
|
||||||
} else {
|
} else {
|
||||||
current->params.mstp_params.max_master = 127;
|
current->params.mstp_params.max_master = 127;
|
||||||
}
|
}
|
||||||
result = config_setting_lookup_int(port, "max_frames",
|
result = config_setting_lookup_int(
|
||||||
(int *)¶m);
|
port, "max_frames", (int *)¶m);
|
||||||
if (result) {
|
if (result) {
|
||||||
current->params.mstp_params.max_frames = param;
|
current->params.mstp_params.max_frames = param;
|
||||||
} else {
|
} else {
|
||||||
@@ -418,17 +418,17 @@ bool parse_cmd(int argc, char *argv[])
|
|||||||
const char *bipString = "p:n:D:";
|
const char *bipString = "p:n:D:";
|
||||||
const char *mstpString = "m:b:p:d:s:n:D:";
|
const char *mstpString = "m:b:p:d:s:n:D:";
|
||||||
const struct option Options[] = {
|
const struct option Options[] = {
|
||||||
{"config", required_argument, NULL, 'c'},
|
{ "config", required_argument, NULL, 'c' },
|
||||||
{"device", required_argument, NULL, 'D'},
|
{ "device", required_argument, NULL, 'D' },
|
||||||
{"network", required_argument, NULL, 'n'},
|
{ "network", required_argument, NULL, 'n' },
|
||||||
{"port", required_argument, NULL, 'P'},
|
{ "port", required_argument, NULL, 'P' },
|
||||||
{"mac", required_argument, NULL, 'm'},
|
{ "mac", required_argument, NULL, 'm' },
|
||||||
{"baud", required_argument, NULL, 'b'},
|
{ "baud", required_argument, NULL, 'b' },
|
||||||
{"parity", required_argument, NULL, 'p'},
|
{ "parity", required_argument, NULL, 'p' },
|
||||||
{"databits", required_argument, NULL, 'd'},
|
{ "databits", required_argument, NULL, 'd' },
|
||||||
{"stopbits", required_argument, NULL, 's'},
|
{ "stopbits", required_argument, NULL, 's' },
|
||||||
{"help", no_argument, NULL, 'h'},
|
{ "help", no_argument, NULL, 'h' },
|
||||||
{NULL, no_argument, NULL, 0},
|
{ NULL, no_argument, NULL, 0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
int opt, dev_opt, index, result, fd;
|
int opt, dev_opt, index, result, fd;
|
||||||
@@ -485,13 +485,13 @@ bool parse_cmd(int argc, char *argv[])
|
|||||||
if (fd) {
|
if (fd) {
|
||||||
struct ifreq ifr;
|
struct ifreq ifr;
|
||||||
strncpy(ifr.ifr_name, current->iface,
|
strncpy(ifr.ifr_name, current->iface,
|
||||||
sizeof(ifr.ifr_name) - 1);
|
sizeof(ifr.ifr_name) - 1);
|
||||||
result = ioctl(fd, SIOCGIFADDR, &ifr);
|
result = ioctl(fd, SIOCGIFADDR, &ifr);
|
||||||
if (result != -1) {
|
if (result != -1) {
|
||||||
close(fd);
|
close(fd);
|
||||||
} else {
|
} else {
|
||||||
PRINT(ERROR,
|
PRINT(ERROR,
|
||||||
"Error: Invalid interface for BIP device \n");
|
"Error: Invalid interface for BIP device \n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -538,7 +538,7 @@ bool parse_cmd(int argc, char *argv[])
|
|||||||
close(fd);
|
close(fd);
|
||||||
} else {
|
} else {
|
||||||
PRINT(ERROR,
|
PRINT(ERROR,
|
||||||
"Error: Invalid interface for MSTP device\n");
|
"Error: Invalid interface for MSTP device\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -621,8 +621,8 @@ bool parse_cmd(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
dev_opt = getopt_long(argc, argv, mstpString, Options,
|
dev_opt = getopt_long(
|
||||||
&index);
|
argc, argv, mstpString, Options, &index);
|
||||||
}
|
}
|
||||||
opt = dev_opt;
|
opt = dev_opt;
|
||||||
} else {
|
} else {
|
||||||
@@ -666,8 +666,9 @@ bool init_router()
|
|||||||
ROUTER_PORT *port;
|
ROUTER_PORT *port;
|
||||||
|
|
||||||
msgboxid = create_msgbox();
|
msgboxid = create_msgbox();
|
||||||
if (msgboxid == INVALID_MSGBOX_ID)
|
if (msgboxid == INVALID_MSGBOX_ID) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
port = head;
|
port = head;
|
||||||
/* add main message box id to all ports */
|
/* add main message box id to all ports */
|
||||||
@@ -702,8 +703,9 @@ void cleanup()
|
|||||||
ROUTER_PORT *port;
|
ROUTER_PORT *port;
|
||||||
BACMSG msg;
|
BACMSG msg;
|
||||||
|
|
||||||
if (head == NULL)
|
if (head == NULL) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
msg.origin = head->main_id;
|
msg.origin = head->main_id;
|
||||||
msg.type = SERVICE;
|
msg.type = SERVICE;
|
||||||
@@ -714,8 +716,9 @@ void cleanup()
|
|||||||
/* send shutdown message to all router ports */
|
/* send shutdown message to all router ports */
|
||||||
port = head;
|
port = head;
|
||||||
while (port != NULL) {
|
while (port != NULL) {
|
||||||
if (port->state == RUNNING)
|
if (port->state == RUNNING) {
|
||||||
send_to_msgbox(port->port_id, &msg);
|
send_to_msgbox(port->port_id, &msg);
|
||||||
|
}
|
||||||
port = port->next;
|
port = port->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -741,8 +744,9 @@ void print_msg(BACMSG *msg)
|
|||||||
|
|
||||||
if (data->pdu_len) {
|
if (data->pdu_len) {
|
||||||
PRINT(DEBUG, "Message PDU: ");
|
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, "%02X ", data->pdu[i]);
|
||||||
|
}
|
||||||
PRINT(DEBUG, "\n");
|
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);
|
*buff = (uint8_t *)malloc(buff_len);
|
||||||
memmove(*buff, npdu, npdu_len); /* copy newly formed NPDU */
|
memmove(*buff, npdu, npdu_len); /* copy newly formed NPDU */
|
||||||
memmove(*buff + npdu_len, &data->pdu[apdu_offset],
|
memmove(*buff + npdu_len, &data->pdu[apdu_offset],
|
||||||
apdu_len); /* copy APDU */
|
apdu_len); /* copy APDU */
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
/* request net search */
|
/* request net search */
|
||||||
@@ -73,10 +73,11 @@ BACMSG *recv_from_msgbox(MSGBOX_ID src, BACMSG *msg)
|
|||||||
|
|
||||||
void del_msgbox(MSGBOX_ID msgboxid)
|
void del_msgbox(MSGBOX_ID msgboxid)
|
||||||
{
|
{
|
||||||
if (msgboxid == INVALID_MSGBOX_ID)
|
if (msgboxid == INVALID_MSGBOX_ID) {
|
||||||
return;
|
return;
|
||||||
else
|
} else {
|
||||||
msgctl(msgboxid, IPC_RMID, NULL);
|
msgctl(msgboxid, IPC_RMID, NULL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void free_data(MSG_DATA *data)
|
void free_data(MSG_DATA *data)
|
||||||
@@ -34,8 +34,8 @@
|
|||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/ipc.h>
|
#include <sys/ipc.h>
|
||||||
#include <sys/msg.h>
|
#include <sys/msg.h>
|
||||||
#include "bacdef.h"
|
#include "bacnet/bacdef.h"
|
||||||
#include "npdu.h"
|
#include "bacnet/npdu.h"
|
||||||
|
|
||||||
extern pthread_mutex_t msg_lock;
|
extern pthread_mutex_t msg_lock;
|
||||||
|
|
||||||
@@ -30,7 +30,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "mstpmodule.h"
|
#include "mstpmodule.h"
|
||||||
#include "bacint.h"
|
#include "bacnet/bacint.h"
|
||||||
#include "dlmstp_linux.h"
|
#include "dlmstp_linux.h"
|
||||||
#include <termios.h>
|
#include <termios.h>
|
||||||
|
|
||||||
@@ -44,8 +44,8 @@
|
|||||||
void *dl_mstp_thread(void *pArgs)
|
void *dl_mstp_thread(void *pArgs)
|
||||||
{
|
{
|
||||||
ROUTER_PORT *port = (ROUTER_PORT *)pArgs;
|
ROUTER_PORT *port = (ROUTER_PORT *)pArgs;
|
||||||
struct mstp_port_struct_t mstp_port = {(MSTP_RECEIVE_STATE)0};
|
struct mstp_port_struct_t mstp_port = { (MSTP_RECEIVE_STATE)0 };
|
||||||
volatile SHARED_MSTP_DATA shared_port_data = {0};
|
volatile SHARED_MSTP_DATA shared_port_data = { 0 };
|
||||||
uint16_t pdu_len;
|
uint16_t pdu_len;
|
||||||
uint8_t shutdown = 0;
|
uint8_t shutdown = 0;
|
||||||
|
|
||||||
@@ -121,7 +121,7 @@ void *dl_mstp_thread(void *pArgs)
|
|||||||
}
|
}
|
||||||
|
|
||||||
dlmstp_send_pdu(&mstp_port, &(msg_data->dest),
|
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);
|
check_data(msg_data);
|
||||||
|
|
||||||
@@ -144,16 +144,15 @@ void *dl_mstp_thread(void *pArgs)
|
|||||||
|
|
||||||
if (pdu_len > 0) {
|
if (pdu_len > 0) {
|
||||||
msg_data = (MSG_DATA *)malloc(sizeof(MSG_DATA));
|
msg_data = (MSG_DATA *)malloc(sizeof(MSG_DATA));
|
||||||
memmove(
|
memmove(&(msg_data->src),
|
||||||
&(msg_data->src),
|
|
||||||
(const void *)&(shared_port_data.Receive_Packet.address),
|
(const void *)&(shared_port_data.Receive_Packet.address),
|
||||||
sizeof(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.adr[0] = msg_data->src.mac[0];
|
||||||
msg_data->src.len = 1;
|
msg_data->src.len = 1;
|
||||||
msg_data->pdu = (uint8_t *)malloc(pdu_len);
|
msg_data->pdu = (uint8_t *)malloc(pdu_len);
|
||||||
memmove(msg_data->pdu,
|
memmove(msg_data->pdu,
|
||||||
(const void *)&(shared_port_data.Receive_Packet.pdu),
|
(const void *)&(shared_port_data.Receive_Packet.pdu),
|
||||||
pdu_len);
|
pdu_len);
|
||||||
msg_data->pdu_len = pdu_len;
|
msg_data->pdu_len = pdu_len;
|
||||||
|
|
||||||
msg_storage.type = DATA;
|
msg_storage.type = DATA;
|
||||||
@@ -30,7 +30,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "network_layer.h"
|
#include "network_layer.h"
|
||||||
#include "bacint.h"
|
#include "bacnet/bacint.h"
|
||||||
|
|
||||||
uint16_t process_network_message(BACMSG *msg, MSG_DATA *data, uint8_t **buff)
|
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;
|
int i;
|
||||||
for (i = 0; i < net_count; i++) {
|
for (i = 0; i < net_count; i++) {
|
||||||
decode_unsigned16(&data->pdu[apdu_offset + 2 * 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,
|
add_dnet(&srcport->route_info, net,
|
||||||
data->src); /* and update routing table */
|
data->src); /* and update routing table */
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -125,9 +125,9 @@ uint16_t process_network_message(BACMSG *msg, MSG_DATA *data, uint8_t **buff)
|
|||||||
while (net_count--) {
|
while (net_count--) {
|
||||||
int i = 1;
|
int i = 1;
|
||||||
decode_unsigned16(&data->pdu[apdu_offset + i],
|
decode_unsigned16(&data->pdu[apdu_offset + i],
|
||||||
&net); /* decode received NET values */
|
&net); /* decode received NET values */
|
||||||
add_dnet(&srcport->route_info, net,
|
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] >
|
if (data->pdu[apdu_offset + i + 3] >
|
||||||
0) /* find next NET value */
|
0) /* find next NET value */
|
||||||
i = data->pdu[apdu_offset + i + 3] + 4;
|
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--) {
|
while (net_count--) {
|
||||||
int i = 1;
|
int i = 1;
|
||||||
decode_unsigned16(&data->pdu[apdu_offset + i],
|
decode_unsigned16(&data->pdu[apdu_offset + i],
|
||||||
&net); /* decode received NET values */
|
&net); /* decode received NET values */
|
||||||
add_dnet(&srcport->route_info, net,
|
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] >
|
if (data->pdu[apdu_offset + i + 3] >
|
||||||
0) /* find next NET value */
|
0) /* find next NET value */
|
||||||
i = data->pdu[apdu_offset + i + 3] + 4;
|
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 */
|
/* security messages */
|
||||||
break;
|
break;
|
||||||
case NETWORK_MESSAGE_WHAT_IS_NETWORK_NUMBER:
|
case NETWORK_MESSAGE_WHAT_IS_NETWORK_NUMBER:
|
||||||
buff_len = create_network_message(NETWORK_MESSAGE_NETWORK_NUMBER_IS,
|
buff_len = create_network_message(
|
||||||
data, buff, &buff);
|
NETWORK_MESSAGE_NETWORK_NUMBER_IS, data, buff, &buff);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -193,8 +193,10 @@ uint16_t process_network_message(BACMSG *msg, MSG_DATA *data, uint8_t **buff)
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint16_t create_network_message(
|
uint16_t create_network_message(
|
||||||
BACNET_NETWORK_MESSAGE_TYPE network_message_type, MSG_DATA *data,
|
BACNET_NETWORK_MESSAGE_TYPE network_message_type,
|
||||||
uint8_t **buff, void *val)
|
MSG_DATA *data,
|
||||||
|
uint8_t **buff,
|
||||||
|
void *val)
|
||||||
{
|
{
|
||||||
int16_t buff_len;
|
int16_t buff_len;
|
||||||
bool data_expecting_reply = false;
|
bool data_expecting_reply = false;
|
||||||
@@ -229,8 +231,8 @@ uint16_t create_network_message(
|
|||||||
DNET *dnet;
|
DNET *dnet;
|
||||||
while (port != NULL) {
|
while (port != NULL) {
|
||||||
if (port->route_info.net != data->src.net) {
|
if (port->route_info.net != data->src.net) {
|
||||||
buff_len += encode_unsigned16(*buff + buff_len,
|
buff_len += encode_unsigned16(
|
||||||
port->route_info.net);
|
*buff + buff_len, port->route_info.net);
|
||||||
dnet = port->route_info.dnets;
|
dnet = port->route_info.dnets;
|
||||||
while (dnet != NULL) {
|
while (dnet != NULL) {
|
||||||
buff_len +=
|
buff_len +=
|
||||||
@@ -267,8 +269,8 @@ uint16_t create_network_message(
|
|||||||
uint8_t portID = 1;
|
uint8_t portID = 1;
|
||||||
|
|
||||||
while (port != NULL) {
|
while (port != NULL) {
|
||||||
buff_len += encode_unsigned16(*buff + buff_len,
|
buff_len += encode_unsigned16(
|
||||||
port->route_info.net);
|
*buff + buff_len, port->route_info.net);
|
||||||
(*buff)[buff_len++] = portID++;
|
(*buff)[buff_len++] = portID++;
|
||||||
(*buff)[buff_len++] = 0;
|
(*buff)[buff_len++] = 0;
|
||||||
port = port->next;
|
port = port->next;
|
||||||
@@ -307,7 +309,9 @@ uint16_t create_network_message(
|
|||||||
}
|
}
|
||||||
|
|
||||||
void send_network_message(BACNET_NETWORK_MESSAGE_TYPE network_message_type,
|
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;
|
BACMSG msg;
|
||||||
ROUTER_PORT *port = head;
|
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,
|
void init_npdu(BACNET_NPDU_DATA *npdu_data,
|
||||||
BACNET_NETWORK_MESSAGE_TYPE network_message_type,
|
BACNET_NETWORK_MESSAGE_TYPE network_message_type,
|
||||||
bool data_expecting_reply)
|
bool data_expecting_reply)
|
||||||
{
|
{
|
||||||
if (npdu_data) {
|
if (npdu_data) {
|
||||||
npdu_data->data_expecting_reply = data_expecting_reply;
|
npdu_data->data_expecting_reply = data_expecting_reply;
|
||||||
@@ -34,10 +34,10 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "bacenum.h"
|
#include "bacnet/bacenum.h"
|
||||||
#include "bacdef.h"
|
#include "bacnet/bacdef.h"
|
||||||
#include "npdu.h"
|
#include "bacnet/npdu.h"
|
||||||
#include "net.h"
|
#include "bacport.h"
|
||||||
#include "portthread.h"
|
#include "portthread.h"
|
||||||
|
|
||||||
uint16_t process_network_message(
|
uint16_t process_network_message(
|
||||||
@@ -36,8 +36,9 @@ ROUTER_PORT *find_snet(MSGBOX_ID id)
|
|||||||
ROUTER_PORT *port = head;
|
ROUTER_PORT *port = head;
|
||||||
|
|
||||||
while (port != NULL) {
|
while (port != NULL) {
|
||||||
if (port->port_id == id)
|
if (port->port_id == id) {
|
||||||
return port;
|
return port;
|
||||||
|
}
|
||||||
port = port->next;
|
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;
|
route_info->dnets->next = NULL;
|
||||||
} else {
|
} else {
|
||||||
while (dnet != NULL) {
|
while (dnet != NULL) {
|
||||||
if (dnet->net == net) /* make sure NETs are not repeated */
|
if (dnet->net == net) { /* make sure NETs are not repeated */
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
tmp = dnet;
|
tmp = dnet;
|
||||||
dnet = dnet->next;
|
dnet = dnet->next;
|
||||||
}
|
}
|
||||||
@@ -33,8 +33,8 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include "msgqueue.h"
|
#include "msgqueue.h"
|
||||||
#include "bacdef.h"
|
#include "bacnet/bacdef.h"
|
||||||
#include "npdu.h"
|
#include "bacnet/npdu.h"
|
||||||
|
|
||||||
#define ERROR 1
|
#define ERROR 1
|
||||||
#define INFO 2
|
#define INFO 2
|
||||||
@@ -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
|
||||||
|
|
||||||
+101
-102
@@ -28,34 +28,34 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <time.h> /* for time */
|
#include <time.h> /* for time */
|
||||||
#include <ctype.h> /* for toupper */
|
#include <ctype.h> /* for toupper */
|
||||||
|
|
||||||
#define PRINT_ENABLED 1
|
#define PRINT_ENABLED 1
|
||||||
|
|
||||||
#include "bacdef.h"
|
#include "bacnet/bacdef.h"
|
||||||
#include "config.h"
|
#include "bacnet/config.h"
|
||||||
#include "bactext.h"
|
#include "bacnet/bactext.h"
|
||||||
#include "bacerror.h"
|
#include "bacnet/bacerror.h"
|
||||||
#include "iam.h"
|
#include "bacnet/iam.h"
|
||||||
#include "arf.h"
|
#include "bacnet/arf.h"
|
||||||
#include "tsm.h"
|
#include "bacnet/basic/tsm/tsm.h"
|
||||||
#include "address.h"
|
#include "bacnet/basic/binding/address.h"
|
||||||
#include "npdu.h"
|
#include "bacnet/npdu.h"
|
||||||
#include "apdu.h"
|
#include "bacnet/apdu.h"
|
||||||
#include "device.h"
|
#include "bacnet/basic/object/device.h"
|
||||||
#include "net.h"
|
#include "bacport.h"
|
||||||
#include "datalink.h"
|
#include "bacnet/datalink/datalink.h"
|
||||||
#include "whois.h"
|
#include "bacnet/whois.h"
|
||||||
/* some demo stuff needed */
|
/* some demo stuff needed */
|
||||||
#include "filename.h"
|
#include "bacnet/basic/sys/filename.h"
|
||||||
#include "handlers.h"
|
#include "bacnet/basic/services.h"
|
||||||
#include "client.h"
|
#include "bacnet/basic/services.h"
|
||||||
#include "txbuf.h"
|
#include "bacnet/basic/tsm/tsm.h"
|
||||||
#include "dlenv.h"
|
#include "bacnet/datalink/dlenv.h"
|
||||||
|
|
||||||
/* buffer used for receive */
|
/* buffer used for receive */
|
||||||
static uint8_t Rx_Buf[MAX_MPDU] = {0};
|
static uint8_t Rx_Buf[MAX_MPDU] = { 0 };
|
||||||
|
|
||||||
/* converted command line arguments */
|
/* converted command line arguments */
|
||||||
static uint32_t Target_Device_Object_Instance = BACNET_MAX_INSTANCE;
|
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 Simple_Ack_Detected = false;
|
||||||
static bool Cancel_Requested = false;
|
static bool Cancel_Requested = false;
|
||||||
|
|
||||||
static void MyErrorHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
|
static void MyErrorHandler(BACNET_ADDRESS *src,
|
||||||
BACNET_ERROR_CLASS error_class,
|
uint8_t invoke_id,
|
||||||
BACNET_ERROR_CODE error_code)
|
BACNET_ERROR_CLASS error_class,
|
||||||
|
BACNET_ERROR_CODE error_code)
|
||||||
{
|
{
|
||||||
if (address_match(&Target_Address, src) &&
|
if (address_match(&Target_Address, src) &&
|
||||||
(invoke_id == Request_Invoke_ID)) {
|
(invoke_id == Request_Invoke_ID)) {
|
||||||
printf("BACnet Error: %s: %s\r\n",
|
printf("BACnet Error: %s: %s\r\n",
|
||||||
bactext_error_class_name((int)error_class),
|
bactext_error_class_name((int)error_class),
|
||||||
bactext_error_code_name((int)error_code));
|
bactext_error_code_name((int)error_code));
|
||||||
Error_Detected = true;
|
Error_Detected = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MyAbortHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
|
static void MyAbortHandler(
|
||||||
uint8_t abort_reason, bool server)
|
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t abort_reason, bool server)
|
||||||
{
|
{
|
||||||
(void)server;
|
(void)server;
|
||||||
if (address_match(&Target_Address, src) &&
|
if (address_match(&Target_Address, src) &&
|
||||||
(invoke_id == Request_Invoke_ID)) {
|
(invoke_id == Request_Invoke_ID)) {
|
||||||
printf("BACnet Abort: %s\r\n",
|
printf("BACnet Abort: %s\r\n",
|
||||||
bactext_abort_reason_name((int)abort_reason));
|
bactext_abort_reason_name((int)abort_reason));
|
||||||
Error_Detected = true;
|
Error_Detected = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
|
static void MyRejectHandler(
|
||||||
uint8_t reject_reason)
|
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||||
{
|
{
|
||||||
if (address_match(&Target_Address, src) &&
|
if (address_match(&Target_Address, src) &&
|
||||||
(invoke_id == Request_Invoke_ID)) {
|
(invoke_id == Request_Invoke_ID)) {
|
||||||
printf("BACnet Reject: %s\r\n",
|
printf("BACnet Reject: %s\r\n",
|
||||||
bactext_reject_reason_name((int)reject_reason));
|
bactext_reject_reason_name((int)reject_reason));
|
||||||
Error_Detected = true;
|
Error_Detected = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void My_Unconfirmed_COV_Notification_Handler(uint8_t *service_request,
|
static void My_Unconfirmed_COV_Notification_Handler(
|
||||||
uint16_t service_len,
|
uint8_t *service_request, uint16_t service_len, BACNET_ADDRESS *src)
|
||||||
BACNET_ADDRESS *src)
|
|
||||||
{
|
{
|
||||||
handler_ucov_notification(service_request, service_len, src);
|
handler_ucov_notification(service_request, service_len, src);
|
||||||
}
|
}
|
||||||
|
|
||||||
void My_Confirmed_COV_Notification_Handler(
|
static void My_Confirmed_COV_Notification_Handler(uint8_t *service_request,
|
||||||
uint8_t *service_request, uint16_t service_len, BACNET_ADDRESS *src,
|
uint16_t service_len,
|
||||||
|
BACNET_ADDRESS *src,
|
||||||
BACNET_CONFIRMED_SERVICE_DATA *service_data)
|
BACNET_CONFIRMED_SERVICE_DATA *service_data)
|
||||||
{
|
{
|
||||||
handler_ccov_notification(service_request, service_len, src, 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) &&
|
if (address_match(&Target_Address, src) &&
|
||||||
(invoke_id == Request_Invoke_ID)) {
|
(invoke_id == Request_Invoke_ID)) {
|
||||||
@@ -144,23 +146,23 @@ static void Init_Service_Handlers(void)
|
|||||||
It is required to send the proper reject message... */
|
It is required to send the proper reject message... */
|
||||||
apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service);
|
apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service);
|
||||||
/* we must implement read property - it's required! */
|
/* we must implement read property - it's required! */
|
||||||
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY,
|
apdu_set_confirmed_handler(
|
||||||
handler_read_property);
|
SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property);
|
||||||
/* handle the data coming back from COV subscriptions */
|
/* handle the data coming back from COV subscriptions */
|
||||||
apdu_set_confirmed_handler(SERVICE_CONFIRMED_COV_NOTIFICATION,
|
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,
|
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 */
|
/* handle the Simple ack coming back from SubscribeCOV */
|
||||||
apdu_set_confirmed_simple_ack_handler(SERVICE_CONFIRMED_SUBSCRIBE_COV,
|
apdu_set_confirmed_simple_ack_handler(
|
||||||
MyWritePropertySimpleAckHandler);
|
SERVICE_CONFIRMED_SUBSCRIBE_COV, MyWritePropertySimpleAckHandler);
|
||||||
/* handle any errors coming back */
|
/* handle any errors coming back */
|
||||||
apdu_set_error_handler(SERVICE_CONFIRMED_SUBSCRIBE_COV, MyErrorHandler);
|
apdu_set_error_handler(SERVICE_CONFIRMED_SUBSCRIBE_COV, MyErrorHandler);
|
||||||
apdu_set_abort_handler(MyAbortHandler);
|
apdu_set_abort_handler(MyAbortHandler);
|
||||||
apdu_set_reject_handler(MyRejectHandler);
|
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 = NULL;
|
||||||
BACNET_SUBSCRIBE_COV_DATA *cov_data_old = NULL;
|
BACNET_SUBSCRIBE_COV_DATA *cov_data_old = NULL;
|
||||||
@@ -175,7 +177,7 @@ void cleanup(void)
|
|||||||
|
|
||||||
int main(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;
|
uint16_t pdu_len = 0;
|
||||||
unsigned timeout = 100; /* milliseconds */
|
unsigned timeout = 100; /* milliseconds */
|
||||||
unsigned max_apdu = 0;
|
unsigned max_apdu = 0;
|
||||||
@@ -201,54 +203,52 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
if (print_usage_terse) {
|
if (print_usage_terse) {
|
||||||
filename = filename_remove_path(argv[0]);
|
filename = filename_remove_path(argv[0]);
|
||||||
printf(
|
printf("Usage: %s device-id object-type object-instance "
|
||||||
"Usage: %s device-id object-type object-instance "
|
"process-id <[un]confirmed lifetime|cancel>\r\n",
|
||||||
"process-id <[un]confirmed lifetime|cancel>\r\n",
|
|
||||||
filename);
|
filename);
|
||||||
if (!print_usage_verbose) {
|
if (!print_usage_verbose) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (print_usage_verbose) {
|
if (print_usage_verbose) {
|
||||||
printf(
|
printf("\r\n"
|
||||||
"\r\n"
|
"device-id:\r\n"
|
||||||
"device-id:\r\n"
|
"The subscriber BACnet Device Object Instance number.\r\n"
|
||||||
"The subscriber BACnet Device Object Instance number.\r\n"
|
"\r\n"
|
||||||
"\r\n"
|
"object-type:\r\n"
|
||||||
"object-type:\r\n"
|
"The monitored object type is the integer value of the\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"
|
||||||
"enumeration BACNET_OBJECT_TYPE in bacenum.h. For example,\r\n"
|
"if you were monitoring Analog Output 2, the object-type\r\n"
|
||||||
"if you were monitoring Analog Output 2, the object-type\r\n"
|
"would be 1.\r\n"
|
||||||
"would be 1.\r\n"
|
"\r\n"
|
||||||
"\r\n"
|
"object-instance:\r\n"
|
||||||
"object-instance:\r\n"
|
"The monitored object instance number.\r\n"
|
||||||
"The monitored object instance number.\r\n"
|
"\r\n"
|
||||||
"\r\n"
|
"process-id:\r\n"
|
||||||
"process-id:\r\n"
|
"Process Identifier for this COV subscription.\r\n"
|
||||||
"Process Identifier for this COV subscription.\r\n"
|
"\r\n"
|
||||||
"\r\n"
|
"confirmed:\r\n"
|
||||||
"confirmed:\r\n"
|
"Optional flag to subscribe using Confirmed notifications.\r\n"
|
||||||
"Optional flag to subscribe using Confirmed notifications.\r\n"
|
"Use the word \'confirmed\' or \'unconfirmed\'.\r\n"
|
||||||
"Use the word \'confirmed\' or \'unconfirmed\'.\r\n"
|
"\r\n"
|
||||||
"\r\n"
|
"lifetime:\r\n"
|
||||||
"lifetime:\r\n"
|
"Optional subscription lifetime is conveyed in seconds.\r\n"
|
||||||
"Optional subscription lifetime is conveyed in seconds.\r\n"
|
"\r\n"
|
||||||
"\r\n"
|
"cancel:\r\n"
|
||||||
"cancel:\r\n"
|
"Use the word \'cancel\' instead of confirm and lifetime.\r\n"
|
||||||
"Use the word \'cancel\' instead of confirm and lifetime.\r\n"
|
"This shall indicate a cancellation request.\r\n"
|
||||||
"This shall indicate a cancellation request.\r\n"
|
"\r\n"
|
||||||
"\r\n"
|
"Example:\r\n"
|
||||||
"Example:\r\n"
|
"If you want subscribe to Device 123 Analog Input 9 object\r\n"
|
||||||
"If you want subscribe to Device 123 Analog Input 9 object\r\n"
|
"using confirmed COV notifications for 5 minutes,\r\n"
|
||||||
"using confirmed COV notifications for 5 minutes,\r\n"
|
"you could send the following command:\r\n"
|
||||||
"you could send the following command:\r\n"
|
"%s 123 0 9 1 confirmed 600\r\n"
|
||||||
"%s 123 0 9 1 confirmed 600\r\n"
|
"To send the same COV subscription request for unconfirmed\r\n"
|
||||||
"To send the same COV subscription request for unconfirmed\r\n"
|
"notifications, send the following command:\r\n"
|
||||||
"notifications, send the following command:\r\n"
|
"%s 123 0 9 1 unconfirmed 600\r\n"
|
||||||
"%s 123 0 9 1 unconfirmed 600\r\n"
|
"To cancel the same COV subscription request,\r\n"
|
||||||
"To cancel the same COV subscription request,\r\n"
|
"send the following command:\r\n"
|
||||||
"send the following command:\r\n"
|
"%s 123 0 9 1 cancel\r\n",
|
||||||
"%s 123 0 9 1 cancel\r\n",
|
|
||||||
filename, filename, filename);
|
filename, filename, filename);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -256,7 +256,7 @@ int main(int argc, char *argv[])
|
|||||||
Target_Device_Object_Instance = strtol(argv[1], NULL, 0);
|
Target_Device_Object_Instance = strtol(argv[1], NULL, 0);
|
||||||
if (Target_Device_Object_Instance >= BACNET_MAX_INSTANCE) {
|
if (Target_Device_Object_Instance >= BACNET_MAX_INSTANCE) {
|
||||||
fprintf(stderr, "device-instance=%u - it must be less than %u\r\n",
|
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;
|
return 1;
|
||||||
}
|
}
|
||||||
atexit(cleanup);
|
atexit(cleanup);
|
||||||
@@ -268,8 +268,8 @@ int main(int argc, char *argv[])
|
|||||||
if (cov_data->monitoredObjectIdentifier.type >=
|
if (cov_data->monitoredObjectIdentifier.type >=
|
||||||
MAX_BACNET_OBJECT_TYPE) {
|
MAX_BACNET_OBJECT_TYPE) {
|
||||||
fprintf(stderr, "object-type=%u - it must be less than %u\r\n",
|
fprintf(stderr, "object-type=%u - it must be less than %u\r\n",
|
||||||
cov_data->monitoredObjectIdentifier.type,
|
cov_data->monitoredObjectIdentifier.type,
|
||||||
MAX_BACNET_OBJECT_TYPE);
|
MAX_BACNET_OBJECT_TYPE);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
argi++;
|
argi++;
|
||||||
@@ -278,8 +278,8 @@ int main(int argc, char *argv[])
|
|||||||
if (cov_data->monitoredObjectIdentifier.instance >
|
if (cov_data->monitoredObjectIdentifier.instance >
|
||||||
BACNET_MAX_INSTANCE) {
|
BACNET_MAX_INSTANCE) {
|
||||||
fprintf(stderr, "object-instance=%u - it must be less than %u\r\n",
|
fprintf(stderr, "object-instance=%u - it must be less than %u\r\n",
|
||||||
cov_data->monitoredObjectIdentifier.instance,
|
cov_data->monitoredObjectIdentifier.instance,
|
||||||
BACNET_MAX_INSTANCE + 1);
|
BACNET_MAX_INSTANCE + 1);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
argi++;
|
argi++;
|
||||||
@@ -325,11 +325,11 @@ int main(int argc, char *argv[])
|
|||||||
last_seconds = time(NULL);
|
last_seconds = time(NULL);
|
||||||
timeout_seconds = (apdu_timeout() / 1000) * apdu_retries();
|
timeout_seconds = (apdu_timeout() / 1000) * apdu_retries();
|
||||||
/* try to bind with the device */
|
/* try to bind with the device */
|
||||||
found = address_bind_request(Target_Device_Object_Instance, &max_apdu,
|
found = address_bind_request(
|
||||||
&Target_Address);
|
Target_Device_Object_Instance, &max_apdu, &Target_Address);
|
||||||
if (!found) {
|
if (!found) {
|
||||||
Send_WhoIs(Target_Device_Object_Instance,
|
Send_WhoIs(
|
||||||
Target_Device_Object_Instance);
|
Target_Device_Object_Instance, Target_Device_Object_Instance);
|
||||||
}
|
}
|
||||||
/* start at the beginning of the subscribe list */
|
/* start at the beginning of the subscribe list */
|
||||||
cov_data = COV_Subscribe_Data;
|
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 */
|
/* wait until the device is bound, or timeout and quit */
|
||||||
if (!found) {
|
if (!found) {
|
||||||
found = address_bind_request(Target_Device_Object_Instance,
|
found = address_bind_request(
|
||||||
&max_apdu, &Target_Address);
|
Target_Device_Object_Instance, &max_apdu, &Target_Address);
|
||||||
}
|
}
|
||||||
if (found) {
|
if (found) {
|
||||||
if (Request_Invoke_ID == 0) {
|
if (Request_Invoke_ID == 0) {
|
||||||
@@ -371,9 +371,8 @@ int main(int argc, char *argv[])
|
|||||||
/* increase the timeout to the longest lifetime */
|
/* increase the timeout to the longest lifetime */
|
||||||
timeout_seconds = cov_data->lifetime;
|
timeout_seconds = cov_data->lifetime;
|
||||||
}
|
}
|
||||||
printf(
|
printf("Sent SubscribeCOV request. "
|
||||||
"Sent SubscribeCOV request. "
|
" Waiting up to %u seconds....\r\n",
|
||||||
" Waiting up to %u seconds....\r\n",
|
|
||||||
(unsigned)(timeout_seconds - elapsed_seconds));
|
(unsigned)(timeout_seconds - elapsed_seconds));
|
||||||
} else if (tsm_invoke_id_free(Request_Invoke_ID)) {
|
} else if (tsm_invoke_id_free(Request_Invoke_ID)) {
|
||||||
if (cov_data->next) {
|
if (cov_data->next) {
|
||||||
@@ -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
|
||||||
|
|
||||||
@@ -0,0 +1,673 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
|
||||||
|
<CodeBlocks_project_file>
|
||||||
|
<FileVersion major="1" minor="6" />
|
||||||
|
<Project>
|
||||||
|
<Option title="BACnet Server Demo" />
|
||||||
|
<Option pch_mode="2" />
|
||||||
|
<Option compiler="gcc" />
|
||||||
|
<Build>
|
||||||
|
<Target title="Debug">
|
||||||
|
<Option output="bin/Debug/bacserv" prefix_auto="1" extension_auto="1" />
|
||||||
|
<Option object_output="obj/Debug/" />
|
||||||
|
<Option type="1" />
|
||||||
|
<Option compiler="gcc" />
|
||||||
|
<Compiler>
|
||||||
|
<Add option="-Wall" />
|
||||||
|
<Add option="-g" />
|
||||||
|
<Add directory="../../ports/linux" />
|
||||||
|
<Add directory="../../src" />
|
||||||
|
</Compiler>
|
||||||
|
</Target>
|
||||||
|
<Target title="Release">
|
||||||
|
<Option output="bin/Release/bacserv" prefix_auto="1" extension_auto="1" />
|
||||||
|
<Option object_output="obj/Release/" />
|
||||||
|
<Option type="1" />
|
||||||
|
<Option compiler="gcc" />
|
||||||
|
<Compiler>
|
||||||
|
<Add option="-O2" />
|
||||||
|
<Add option="-Wall" />
|
||||||
|
<Add directory="." />
|
||||||
|
<Add directory="../../ports/linux" />
|
||||||
|
<Add directory="../../src" />
|
||||||
|
</Compiler>
|
||||||
|
<Linker>
|
||||||
|
<Add option="-s" />
|
||||||
|
</Linker>
|
||||||
|
</Target>
|
||||||
|
</Build>
|
||||||
|
<Compiler>
|
||||||
|
<Add option="-O" />
|
||||||
|
<Add option="-Wall" />
|
||||||
|
<Add option="-fexceptions" />
|
||||||
|
<Add option="-DBACDL_BIP" />
|
||||||
|
<Add option="-DPRINT_ENABLED=1" />
|
||||||
|
<Add option="-DBACAPP_ALL" />
|
||||||
|
<Add directory="../../ports/linux" />
|
||||||
|
<Add directory="../../src" />
|
||||||
|
</Compiler>
|
||||||
|
<Unit filename="../../ports/linux/bacport.h" />
|
||||||
|
<Unit filename="../../ports/linux/bip-init.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../ports/linux/datetime-init.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../ports/linux/mstimer-init.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/abort.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/abort.h" />
|
||||||
|
<Unit filename="../../src/bacnet/access_rule.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/access_rule.h" />
|
||||||
|
<Unit filename="../../src/bacnet/alarm_ack.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/alarm_ack.h" />
|
||||||
|
<Unit filename="../../src/bacnet/apdu.h" />
|
||||||
|
<Unit filename="../../src/bacnet/arf.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/arf.h" />
|
||||||
|
<Unit filename="../../src/bacnet/assigned_access_rights.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/assigned_access_rights.h" />
|
||||||
|
<Unit filename="../../src/bacnet/authentication_factor.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/authentication_factor.h" />
|
||||||
|
<Unit filename="../../src/bacnet/authentication_factor_format.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/authentication_factor_format.h" />
|
||||||
|
<Unit filename="../../src/bacnet/awf.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/awf.h" />
|
||||||
|
<Unit filename="../../src/bacnet/bacaddr.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/bacaddr.h" />
|
||||||
|
<Unit filename="../../src/bacnet/bacapp.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/bacapp.h" />
|
||||||
|
<Unit filename="../../src/bacnet/bacdcode.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/bacdcode.h" />
|
||||||
|
<Unit filename="../../src/bacnet/bacdef.h" />
|
||||||
|
<Unit filename="../../src/bacnet/bacdevobjpropref.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/bacdevobjpropref.h" />
|
||||||
|
<Unit filename="../../src/bacnet/bacenum.h" />
|
||||||
|
<Unit filename="../../src/bacnet/bacerror.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/bacerror.h" />
|
||||||
|
<Unit filename="../../src/bacnet/bacint.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/bacint.h" />
|
||||||
|
<Unit filename="../../src/bacnet/bacprop.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/bacprop.h" />
|
||||||
|
<Unit filename="../../src/bacnet/bacpropstates.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/bacpropstates.h" />
|
||||||
|
<Unit filename="../../src/bacnet/bacreal.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/bacreal.h" />
|
||||||
|
<Unit filename="../../src/bacnet/bacstr.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/bacstr.h" />
|
||||||
|
<Unit filename="../../src/bacnet/bactext.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/bactext.h" />
|
||||||
|
<Unit filename="../../src/bacnet/bactimevalue.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/bactimevalue.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/binding/address.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/binding/address.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/npdu/h_npdu.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/npdu/h_npdu.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/object/access_credential.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/object/access_credential.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/object/access_door.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/object/access_door.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/object/access_point.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/object/access_point.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/object/access_rights.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/object/access_rights.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/object/access_user.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/object/access_user.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/object/access_zone.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/object/access_zone.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/object/ai.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/object/ai.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/object/ao.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/object/ao.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/object/av.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/object/av.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/object/bacfile.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/object/bacfile.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/object/bi.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/object/bi.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/object/bo.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/object/bo.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/object/bv.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/object/bv.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/object/channel.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/object/channel.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/object/command.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/object/command.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/object/credential_data_input.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/object/credential_data_input.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/object/csv.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/object/csv.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/object/device.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/object/device.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/object/iv.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/object/iv.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/object/lc.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/object/lc.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/object/lo.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/object/lo.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/object/lsp.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/object/lsp.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/object/ms-input.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/object/ms-input.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/object/mso.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/object/mso.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/object/msv.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/object/msv.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/object/nc.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/object/nc.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/object/netport.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/object/netport.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/object/objects.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/object/osv.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/object/osv.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/object/piv.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/object/piv.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/object/schedule.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/object/schedule.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/object/trendlog.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/object/trendlog.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/h_alarm_ack.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/h_alarm_ack.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/h_apdu.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/h_apdu.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/h_arf.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/h_arf.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/h_arf_a.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/h_arf_a.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/h_awf.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/h_awf.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/h_ccov.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/h_ccov.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/h_cov.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/h_cov.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/h_dcc.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/h_dcc.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/h_gas_a.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/h_gas_a.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/h_get_alarm_sum.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/h_get_alarm_sum.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/h_getevent.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/h_getevent.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/h_getevent_a.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/h_getevent_a.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/h_iam.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/h_iam.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/h_ihave.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/h_ihave.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/h_lso.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/h_lso.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/h_noserv.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/h_noserv.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/h_rd.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/h_rd.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/h_rp.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/h_rp.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/h_rp_a.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/h_rp_a.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/h_rpm.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/h_rpm.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/h_rpm_a.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/h_rpm_a.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/h_rr.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/h_rr.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/h_rr_a.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/h_rr_a.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/h_ts.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/h_ts.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/h_ucov.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/h_ucov.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/h_upt.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/h_upt.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/h_whohas.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/h_whohas.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/h_whois.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/h_whois.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/h_wp.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/h_wp.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/h_wpm.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/h_wpm.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/s_abort.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/s_abort.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/s_ack_alarm.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/s_ack_alarm.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/s_arfs.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/s_arfs.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/s_awfs.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/s_awfs.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/s_cevent.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/s_cevent.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/s_cov.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/s_cov.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/s_dcc.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/s_dcc.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/s_error.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/s_error.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/s_get_alarm_sum.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/s_get_alarm_sum.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/s_get_event.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/s_get_event.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/s_getevent.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/s_getevent.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/s_iam.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/s_iam.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/s_ihave.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/s_ihave.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/s_lso.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/s_lso.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/s_rd.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/s_rd.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/s_readrange.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/s_readrange.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/s_rp.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/s_rp.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/s_rpm.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/s_rpm.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/s_ts.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/s_ts.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/s_uevent.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/s_uevent.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/s_upt.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/s_upt.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/s_whohas.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/s_whohas.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/s_whois.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/s_whois.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/s_wp.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/s_wp.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/s_wpm.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/service/s_wpm.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/services.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/sys/bigend.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/sys/bigend.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/sys/debug.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/sys/debug.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/sys/fifo.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/sys/fifo.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/sys/filename.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/sys/filename.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/sys/key.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/sys/key.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/sys/keylist.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/sys/keylist.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/sys/mstimer.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/sys/mstimer.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/sys/ringbuf.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/sys/ringbuf.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/sys/sbuf.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/sys/sbuf.h" />
|
||||||
|
<Unit filename="../../src/bacnet/basic/tsm/tsm.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/basic/tsm/tsm.h" />
|
||||||
|
<Unit filename="../../src/bacnet/bits.h" />
|
||||||
|
<Unit filename="../../src/bacnet/bytes.h" />
|
||||||
|
<Unit filename="../../src/bacnet/config.h" />
|
||||||
|
<Unit filename="../../src/bacnet/cov.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/cov.h" />
|
||||||
|
<Unit filename="../../src/bacnet/credential_authentication_factor.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/credential_authentication_factor.h" />
|
||||||
|
<Unit filename="../../src/bacnet/datalink/bip.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/datalink/bip.h" />
|
||||||
|
<Unit filename="../../src/bacnet/datalink/bvlc.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/datalink/bvlc.h" />
|
||||||
|
<Unit filename="../../src/bacnet/datalink/datalink.h" />
|
||||||
|
<Unit filename="../../src/bacnet/datalink/dlenv.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/datalink/dlenv.h" />
|
||||||
|
<Unit filename="../../src/bacnet/datetime.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/datetime.h" />
|
||||||
|
<Unit filename="../../src/bacnet/dcc.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/dcc.h" />
|
||||||
|
<Unit filename="../../src/bacnet/event.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/event.h" />
|
||||||
|
<Unit filename="../../src/bacnet/get_alarm_sum.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/get_alarm_sum.h" />
|
||||||
|
<Unit filename="../../src/bacnet/getevent.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/getevent.h" />
|
||||||
|
<Unit filename="../../src/bacnet/iam.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/iam.h" />
|
||||||
|
<Unit filename="../../src/bacnet/ihave.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/ihave.h" />
|
||||||
|
<Unit filename="../../src/bacnet/indtext.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/indtext.h" />
|
||||||
|
<Unit filename="../../src/bacnet/lighting.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/lighting.h" />
|
||||||
|
<Unit filename="../../src/bacnet/lso.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/lso.h" />
|
||||||
|
<Unit filename="../../src/bacnet/memcopy.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/memcopy.h" />
|
||||||
|
<Unit filename="../../src/bacnet/npdu.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/npdu.h" />
|
||||||
|
<Unit filename="../../src/bacnet/property.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/property.h" />
|
||||||
|
<Unit filename="../../src/bacnet/proplist.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/proplist.h" />
|
||||||
|
<Unit filename="../../src/bacnet/ptransfer.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/ptransfer.h" />
|
||||||
|
<Unit filename="../../src/bacnet/rd.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/rd.h" />
|
||||||
|
<Unit filename="../../src/bacnet/readrange.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/readrange.h" />
|
||||||
|
<Unit filename="../../src/bacnet/reject.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/reject.h" />
|
||||||
|
<Unit filename="../../src/bacnet/rp.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/rp.h" />
|
||||||
|
<Unit filename="../../src/bacnet/rpm.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/rpm.h" />
|
||||||
|
<Unit filename="../../src/bacnet/timestamp.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/timestamp.h" />
|
||||||
|
<Unit filename="../../src/bacnet/timesync.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/timesync.h" />
|
||||||
|
<Unit filename="../../src/bacnet/version.h" />
|
||||||
|
<Unit filename="../../src/bacnet/whohas.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/whohas.h" />
|
||||||
|
<Unit filename="../../src/bacnet/whois.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/whois.h" />
|
||||||
|
<Unit filename="../../src/bacnet/wp.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/wp.h" />
|
||||||
|
<Unit filename="../../src/bacnet/wpm.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="../../src/bacnet/wpm.h" />
|
||||||
|
<Unit filename="main.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Extensions>
|
||||||
|
<code_completion />
|
||||||
|
<envvars />
|
||||||
|
<debugger />
|
||||||
|
</Extensions>
|
||||||
|
</Project>
|
||||||
|
</CodeBlocks_project_file>
|
||||||
@@ -0,0 +1,676 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
|
||||||
|
<CodeBlocks_project_file>
|
||||||
|
<FileVersion major="1" minor="6" />
|
||||||
|
<Project>
|
||||||
|
<Option title="BACnet Server Demo" />
|
||||||
|
<Option pch_mode="2" />
|
||||||
|
<Option compiler="gcc" />
|
||||||
|
<Build>
|
||||||
|
<Target title="Debug">
|
||||||
|
<Option output="bin\Debug\bacserv" prefix_auto="1" extension_auto="1" />
|
||||||
|
<Option object_output="obj\Debug\" />
|
||||||
|
<Option type="1" />
|
||||||
|
<Option compiler="gcc" />
|
||||||
|
<Compiler>
|
||||||
|
<Add option="-Wall" />
|
||||||
|
<Add option="-g" />
|
||||||
|
<Add directory="..\..\ports\win32" />
|
||||||
|
<Add directory="..\..\src" />
|
||||||
|
</Compiler>
|
||||||
|
</Target>
|
||||||
|
<Target title="Release">
|
||||||
|
<Option output="bin\Release\bacserv" prefix_auto="1" extension_auto="1" />
|
||||||
|
<Option object_output="obj\Release\" />
|
||||||
|
<Option type="1" />
|
||||||
|
<Option compiler="gcc" />
|
||||||
|
<Compiler>
|
||||||
|
<Add option="-O2" />
|
||||||
|
<Add option="-Wall" />
|
||||||
|
<Add directory="..\..\ports\win32" />
|
||||||
|
<Add directory="..\..\src" />
|
||||||
|
</Compiler>
|
||||||
|
<Linker>
|
||||||
|
<Add option="-s" />
|
||||||
|
</Linker>
|
||||||
|
</Target>
|
||||||
|
</Build>
|
||||||
|
<Compiler>
|
||||||
|
<Add option="-O" />
|
||||||
|
<Add option="-Wall" />
|
||||||
|
<Add option="-fexceptions" />
|
||||||
|
<Add option="-DBACDL_BIP" />
|
||||||
|
<Add option="-DPRINT_ENABLED=1" />
|
||||||
|
<Add option="-DBACAPP_ALL" />
|
||||||
|
<Add directory="..\..\ports\win32" />
|
||||||
|
<Add directory="..\..\src" />
|
||||||
|
</Compiler>
|
||||||
|
<Linker>
|
||||||
|
<Add library="ws2_32" />
|
||||||
|
<Add library="iphlpapi" />
|
||||||
|
</Linker>
|
||||||
|
<Unit filename="..\..\ports\win32\bacport.h" />
|
||||||
|
<Unit filename="..\..\ports\win32\bip-init.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\ports\win32\datetime-init.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\ports\win32\mstimer-init.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\abort.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\abort.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\access_rule.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\access_rule.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\alarm_ack.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\alarm_ack.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\apdu.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\arf.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\arf.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\assigned_access_rights.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\assigned_access_rights.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\authentication_factor.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\authentication_factor.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\authentication_factor_format.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\authentication_factor_format.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\awf.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\awf.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\bacaddr.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\bacaddr.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\bacapp.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\bacapp.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\bacdcode.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\bacdcode.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\bacdef.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\bacdevobjpropref.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\bacdevobjpropref.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\bacenum.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\bacerror.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\bacerror.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\bacint.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\bacint.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\bacprop.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\bacprop.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\bacpropstates.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\bacpropstates.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\bacreal.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\bacreal.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\bacstr.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\bacstr.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\bactext.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\bactext.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\bactimevalue.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\bactimevalue.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\binding\address.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\binding\address.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\npdu\h_npdu.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\npdu\h_npdu.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\object\access_credential.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\object\access_credential.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\object\access_door.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\object\access_door.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\object\access_point.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\object\access_point.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\object\access_rights.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\object\access_rights.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\object\access_user.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\object\access_user.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\object\access_zone.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\object\access_zone.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\object\ai.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\object\ai.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\object\ao.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\object\ao.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\object\av.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\object\av.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\object\bacfile.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\object\bacfile.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\object\bi.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\object\bi.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\object\bo.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\object\bo.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\object\bv.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\object\bv.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\object\channel.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\object\channel.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\object\command.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\object\command.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\object\credential_data_input.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\object\credential_data_input.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\object\csv.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\object\csv.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\object\device.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\object\device.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\object\iv.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\object\iv.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\object\lc.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\object\lc.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\object\lo.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\object\lo.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\object\lsp.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\object\lsp.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\object\ms-input.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\object\ms-input.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\object\mso.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\object\mso.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\object\msv.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\object\msv.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\object\nc.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\object\nc.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\object\netport.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\object\netport.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\object\objects.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\object\osv.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\object\osv.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\object\piv.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\object\piv.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\object\schedule.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\object\schedule.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\object\trendlog.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\object\trendlog.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\h_alarm_ack.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\h_alarm_ack.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\h_apdu.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\h_apdu.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\h_arf.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\h_arf.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\h_arf_a.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\h_arf_a.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\h_awf.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\h_awf.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\h_ccov.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\h_ccov.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\h_cov.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\h_cov.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\h_dcc.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\h_dcc.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\h_gas_a.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\h_gas_a.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\h_get_alarm_sum.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\h_get_alarm_sum.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\h_getevent.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\h_getevent.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\h_getevent_a.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\h_getevent_a.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\h_iam.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\h_iam.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\h_ihave.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\h_ihave.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\h_lso.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\h_lso.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\h_noserv.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\h_noserv.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\h_rd.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\h_rd.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\h_rp.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\h_rp.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\h_rp_a.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\h_rp_a.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\h_rpm.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\h_rpm.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\h_rpm_a.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\h_rpm_a.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\h_rr.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\h_rr.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\h_rr_a.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\h_rr_a.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\h_ts.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\h_ts.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\h_ucov.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\h_ucov.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\h_upt.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\h_upt.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\h_whohas.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\h_whohas.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\h_whois.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\h_whois.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\h_wp.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\h_wp.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\h_wpm.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\h_wpm.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\s_abort.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\s_abort.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\s_ack_alarm.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\s_ack_alarm.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\s_arfs.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\s_arfs.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\s_awfs.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\s_awfs.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\s_cevent.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\s_cevent.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\s_cov.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\s_cov.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\s_dcc.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\s_dcc.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\s_error.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\s_error.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\s_get_alarm_sum.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\s_get_alarm_sum.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\s_get_event.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\s_get_event.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\s_getevent.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\s_getevent.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\s_iam.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\s_iam.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\s_ihave.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\s_ihave.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\s_lso.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\s_lso.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\s_rd.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\s_rd.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\s_readrange.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\s_readrange.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\s_rp.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\s_rp.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\s_rpm.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\s_rpm.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\s_ts.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\s_ts.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\s_uevent.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\s_uevent.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\s_upt.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\s_upt.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\s_whohas.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\s_whohas.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\s_whois.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\s_whois.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\s_wp.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\s_wp.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\s_wpm.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\service\s_wpm.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic/services.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\sys\bigend.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\sys\bigend.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\sys\debug.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\sys\debug.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\sys\fifo.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\sys\fifo.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\sys\filename.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\sys\filename.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\sys\key.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\sys\key.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\sys\keylist.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\sys\keylist.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\sys\mstimer.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\sys\mstimer.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\sys\ringbuf.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\sys\ringbuf.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\sys\sbuf.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\sys\sbuf.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\tsm\tsm.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\basic\tsm\tsm.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\bits.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\bytes.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\config.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\cov.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\cov.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\credential_authentication_factor.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\credential_authentication_factor.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\datalink\bip.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\datalink\bip.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\datalink\bvlc.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\datalink\bvlc.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\datalink\datalink.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\datalink\dlenv.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\datalink\dlenv.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\datetime.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\datetime.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\dcc.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\dcc.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\event.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\event.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\get_alarm_sum.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\get_alarm_sum.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\getevent.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\getevent.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\iam.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\iam.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\ihave.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\ihave.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\indtext.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\indtext.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\lighting.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\lighting.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\lso.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\lso.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\memcopy.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\memcopy.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\npdu.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\npdu.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\property.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\property.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\proplist.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\proplist.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\ptransfer.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\ptransfer.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\rd.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\rd.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\readrange.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\readrange.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\reject.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\reject.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\rp.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\rp.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\rpm.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\rpm.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\timestamp.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\timestamp.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\timesync.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\timesync.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\version.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\whohas.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\whohas.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\whois.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\whois.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\wp.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\wp.h" />
|
||||||
|
<Unit filename="..\..\src\bacnet\wpm.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="..\..\src\bacnet\wpm.h" />
|
||||||
|
<Unit filename="main.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Extensions>
|
||||||
|
<code_completion />
|
||||||
|
<envvars />
|
||||||
|
<debugger />
|
||||||
|
</Extensions>
|
||||||
|
</Project>
|
||||||
|
</CodeBlocks_project_file>
|
||||||
Executable
BIN
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user