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:
Steve Karg
2019-12-13 15:19:10 -06:00
committed by GitHub
parent 8a38dbe2cf
commit d50c190957
912 changed files with 36206 additions and 52502 deletions
+10 -2
View File
@@ -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
... ...
+10
View File
@@ -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
View File
@@ -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
-2
View File
@@ -1,2 +0,0 @@
[patterns]
** = native
-40
View File
@@ -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
+84 -101
View File
@@ -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
+1 -2
View File
@@ -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
View File
@@ -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 $@
+50
View File
@@ -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
+37 -40
View File
@@ -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;
} }
+50
View File
@@ -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
+54 -53
View File
@@ -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? */
+50
View File
@@ -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
+305
View File
@@ -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>
View File
+173 -176
View File
@@ -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) {
+47
View File
@@ -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
+41 -44
View File
@@ -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;
} }
+59 -57
View File
@@ -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();
+50
View File
@@ -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
+60 -61
View File
@@ -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) {
+47
View File
@@ -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
+49 -51
View File
@@ -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;
} }
+47
View File
@@ -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
+39 -41
View File
@@ -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;
} }
} }
+47
View File
@@ -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;
} }
+70
View File
@@ -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
+145 -154
View File
@@ -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();
+51
View File
@@ -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
+17 -17
View File
@@ -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));
} }
} }
View File
@@ -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;
View File
+154 -172
View File
@@ -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);
+56 -55
View File
@@ -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 */
+35 -42
View File
@@ -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) {
+52
View File
@@ -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
+52
View File
@@ -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
+95 -71
View File
@@ -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");
+123
View File
@@ -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;
}
+51
View File
@@ -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
+47
View File
@@ -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
+28 -27
View File
@@ -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;
} }
+52
View File
@@ -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
+70 -69
View File
@@ -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");
+50
View File
@@ -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
+119 -121
View File
@@ -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;
+56
View File
@@ -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
+115 -115
View File
@@ -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;
+50
View File
@@ -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
+93 -93
View File
@@ -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;
+53
View File
@@ -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
+64 -62
View File
@@ -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? */
+78
View File
@@ -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)
+38 -34
View File
@@ -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 *)&param); port, "max_master", (int *)&param);
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 *)&param); port, "max_frames", (int *)&param);
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
+51
View File
@@ -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
View File
@@ -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) {
+71
View File
@@ -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
+673
View File
@@ -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>
+676
View 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>
BIN
View File
Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More