From 427eb31e8d06717767728f8039e249135d819a77 Mon Sep 17 00:00:00 2001 From: skarg Date: Mon, 23 Jan 2006 13:04:29 +0000 Subject: [PATCH] Added demo for BACnet simple server in the demo/server directory. Added demo for BACnet ReadProperty service. Added demo for BACnet WriteProperty service. --- bacnet-stack/bacapp.ide | Bin 0 -> 31664 bytes bacnet-stack/bacdcode.c | 4 +- bacnet-stack/bacenum.h | 9 +- bacnet-stack/bip.c | 2 +- bacnet-stack/demo/handler/client.h | 2 +- bacnet-stack/demo/handler/h_iam.c | 30 ++- bacnet-stack/demo/handler/handlers.h | 10 + bacnet-stack/demo/handler/s_rp.c | 10 +- bacnet-stack/demo/handler/s_whois.c | 4 +- bacnet-stack/demo/handler/s_wp.c | 14 +- bacnet-stack/demo/object/bacfile.c | 2 + bacnet-stack/demo/object/bacfile.h | 2 + bacnet-stack/demo/object/device.c | 2 +- bacnet-stack/demo/readfile/makefile.mak | 2 +- bacnet-stack/demo/readfile/readfile.c | 4 +- bacnet-stack/demo/readprop/makefile.mak | 146 +++++++++++ bacnet-stack/demo/readprop/readprop.c | 275 ++++++++++++++++++++ bacnet-stack/demo/server/makefile.mak | 143 +++++++++++ bacnet-stack/demo/server/server.c | 165 ++++++++++++ bacnet-stack/demo/writeprop/makefile.mak | 145 +++++++++++ bacnet-stack/demo/writeprop/writeprop.c | 312 +++++++++++++++++++++++ bacnet-stack/filename.c | 103 ++++++++ bacnet-stack/filename.h | 47 ++++ bacnet-stack/filename.ide | Bin 0 -> 29058 bytes bacnet-stack/iam.c | 26 -- bacnet-stack/iam.h | 5 - bacnet-stack/ports/win32/MAKEFILE.MAK | 2 +- bacnet-stack/ports/win32/bacnet.ide | Bin 64426 -> 64666 bytes bacnet-stack/ports/win32/bip-init.c | 20 +- bacnet-stack/ports/win32/main.c | 2 +- 30 files changed, 1420 insertions(+), 68 deletions(-) create mode 100644 bacnet-stack/bacapp.ide create mode 100644 bacnet-stack/demo/readprop/makefile.mak create mode 100644 bacnet-stack/demo/readprop/readprop.c create mode 100644 bacnet-stack/demo/server/makefile.mak create mode 100644 bacnet-stack/demo/server/server.c create mode 100644 bacnet-stack/demo/writeprop/makefile.mak create mode 100644 bacnet-stack/demo/writeprop/writeprop.c create mode 100644 bacnet-stack/filename.c create mode 100644 bacnet-stack/filename.h create mode 100644 bacnet-stack/filename.ide diff --git a/bacnet-stack/bacapp.ide b/bacnet-stack/bacapp.ide new file mode 100644 index 0000000000000000000000000000000000000000..6ac399ae9211d5d2548d81d2ef9e8e32b59ed142 GIT binary patch literal 31664 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 q!KZTMU*_=D4nGD=`ga|kG>CKIMzcWNc{w literal 0 HcmV?d00001 diff --git a/bacnet-stack/bacdcode.c b/bacnet-stack/bacdcode.c index 8c7c985c..b146da3b 100644 --- a/bacnet-stack/bacdcode.c +++ b/bacnet-stack/bacdcode.c @@ -1678,7 +1678,7 @@ void testBACDCodeSignedValue(Test * pTest, int32_t value) { uint8_t array[5] = { 0 }; uint8_t encoded_array[5] = { 0 }; - int decoded_value = 0; + long decoded_value = 0; int len = 0, apdu_len = 0; uint8_t apdu[MAX_APDU] = { 0 }; uint8_t tag_number = 0; @@ -1692,7 +1692,7 @@ void testBACDCodeSignedValue(Test * pTest, int32_t value) ct_test(pTest, decoded_value == value); if (decoded_value != value) { - printf("value=%d decoded_value=%d\n", value, decoded_value); + printf("value=%d decoded_value=%ld\n", value, decoded_value); print_apdu(&array[0],sizeof(array)); } encode_tagged_signed(&encoded_array[0], decoded_value); diff --git a/bacnet-stack/bacenum.h b/bacnet-stack/bacenum.h index c100ba9c..e9732f1a 100644 --- a/bacnet-stack/bacenum.h +++ b/bacnet-stack/bacenum.h @@ -228,7 +228,7 @@ typedef enum PROP_UPDATE_TIME = 189, PROP_VALUE_BEFORE_CHANGE = 190, PROP_VALUE_SET = 191, - PROP_VALUE_CHANGE_TIME = 192 + PROP_VALUE_CHANGE_TIME = 192, // The special property identifiers all, optional, and required // are reserved for use in the ReadPropertyConditional and @@ -237,6 +237,7 @@ typedef enum // Enumerated values 512-4194303 may be used by others subject to the // procedures and constraints described in Clause 23. // The highest enumeration used in this version is 168. + MAX_BACNET_PROPERTY_ID = 4194303 } BACNET_PROPERTY_ID; typedef enum @@ -701,7 +702,8 @@ typedef enum // Enumerated values 0-127 are reserved for definition by ASHRAE. // Enumerated values 128-1023 may be used by others subject to // the procedures and constraints described in Clause 23. - MAX_BACNET_OBJECT_TYPES = 25 // used for bit string loop + MAX_ASHRAE_OBJECT_TYPE = 25, // used for bit string loop + MAX_BACNET_OBJECT_TYPE = 1023 } BACNET_OBJECT_TYPE; typedef enum @@ -753,7 +755,8 @@ typedef enum { BACNET_APPLICATION_TAG_OBJECT_ID = 12, BACNET_APPLICATION_TAG_RESERVED1 = 13, BACNET_APPLICATION_TAG_RESERVED2 = 14, - BACNET_APPLICATION_TAG_RESERVED3 = 15 + BACNET_APPLICATION_TAG_RESERVED3 = 15, + MAX_BACNET_APPLICATION_TAG = 16 } BACNET_APPLICATION_TAG; // note: these are not the real values, diff --git a/bacnet-stack/bip.c b/bacnet-stack/bip.c index 42837c3e..c0dcb35a 100644 --- a/bacnet-stack/bip.c +++ b/bacnet-stack/bip.c @@ -40,7 +40,7 @@ static int BIP_Socket = -1; /* port to use - stored in host byte order */ -static uint16_t BIP_Port = 0; +static uint16_t BIP_Port = 0xBAC0; /* IP Address - stored in host byte order */ static struct in_addr BIP_Address; /* Broadcast Address - stored in host byte order */ diff --git a/bacnet-stack/demo/handler/client.h b/bacnet-stack/demo/handler/client.h index b3b6d58e..8eb1bdd8 100644 --- a/bacnet-stack/demo/handler/client.h +++ b/bacnet-stack/demo/handler/client.h @@ -54,7 +54,7 @@ bool Send_Write_Property_Request( BACNET_OBJECT_TYPE object_type, uint32_t object_instance, BACNET_PROPERTY_ID object_property, - BACNET_APPLICATION_DATA_VALUE object_value, + BACNET_APPLICATION_DATA_VALUE *object_value, uint8_t priority, int32_t array_index); diff --git a/bacnet-stack/demo/handler/h_iam.c b/bacnet-stack/demo/handler/h_iam.c index d3eedb4e..a002aeb1 100644 --- a/bacnet-stack/demo/handler/h_iam.c +++ b/bacnet-stack/demo/handler/h_iam.c @@ -32,7 +32,7 @@ #include "iam.h" #include "address.h" -void handler_i_am( +void handler_i_am_add( uint8_t *service_request, uint16_t service_len, BACNET_ADDRESS *src) @@ -43,7 +43,6 @@ void handler_i_am( int segmentation = 0; uint16_t vendor_id = 0; - (void)src; (void)service_len; len = iam_decode_service_request( service_request, @@ -64,3 +63,30 @@ void handler_i_am( return; } + +void handler_i_am_bind( + uint8_t *service_request, + uint16_t service_len, + BACNET_ADDRESS *src) +{ + int len = 0; + uint32_t device_id = 0; + unsigned max_apdu = 0; + int segmentation = 0; + uint16_t vendor_id = 0; + + (void)service_len; + len = iam_decode_service_request( + service_request, + &device_id, + &max_apdu, + &segmentation, + &vendor_id); + // only add address if requested to bind + address_add_binding(device_id, + max_apdu, + src); + + return; +} + diff --git a/bacnet-stack/demo/handler/handlers.h b/bacnet-stack/demo/handler/handlers.h index c10080b7..e9852b92 100644 --- a/bacnet-stack/demo/handler/handlers.h +++ b/bacnet-stack/demo/handler/handlers.h @@ -50,6 +50,16 @@ void handler_who_is( uint16_t service_len, BACNET_ADDRESS *src); +void handler_i_am_add( + uint8_t *service_request, + uint16_t service_len, + BACNET_ADDRESS *src); + +void handler_i_am_bind( + uint8_t *service_request, + uint16_t service_len, + BACNET_ADDRESS *src); + void handler_read_property( uint8_t *service_request, uint16_t service_len, diff --git a/bacnet-stack/demo/handler/s_rp.c b/bacnet-stack/demo/handler/s_rp.c index daa63b0f..43f3c01b 100644 --- a/bacnet-stack/demo/handler/s_rp.c +++ b/bacnet-stack/demo/handler/s_rp.c @@ -41,8 +41,8 @@ #include "handlers.h" #include "txbuf.h" -/* returns false if device is not bound or no tsm available */ -bool Send_Read_Property_Request( +/* returns invoke id of 0 if device is not bound or no tsm available */ +uint8_t Send_Read_Property_Request( uint32_t device_id, /* destination device */ BACNET_OBJECT_TYPE object_type, uint32_t object_instance, @@ -99,9 +99,7 @@ bool Send_Read_Property_Request( &dest, // destination address &Handler_Transmit_Buffer[0], pdu_len); // number of bytes of data - if (bytes_sent > 0) - fprintf(stderr,"Sent ReadProperty Request!\n"); - else + if (bytes_sent <= 0) fprintf(stderr,"Failed to Send ReadProperty Request (%s)!\n", strerror(errno)); } @@ -110,5 +108,5 @@ bool Send_Read_Property_Request( "(exceeds destination maximum APDU)!\n"); } - return status; + return invoke_id; } diff --git a/bacnet-stack/demo/handler/s_whois.c b/bacnet-stack/demo/handler/s_whois.c index 0f661d26..9ab7a2e0 100644 --- a/bacnet-stack/demo/handler/s_whois.c +++ b/bacnet-stack/demo/handler/s_whois.c @@ -71,8 +71,6 @@ void Send_WhoIs( &dest, // destination address &Handler_Transmit_Buffer[0], pdu_len); // number of bytes of data - if (bytes_sent > 0) - fprintf(stderr,"Sent Who-Is Request!\n"); - else + if (bytes_sent <= 0) fprintf(stderr,"Failed to Send Who-Is Request (%s)!\n", strerror(errno)); } diff --git a/bacnet-stack/demo/handler/s_wp.c b/bacnet-stack/demo/handler/s_wp.c index 8327b1b3..4e19e836 100644 --- a/bacnet-stack/demo/handler/s_wp.c +++ b/bacnet-stack/demo/handler/s_wp.c @@ -41,13 +41,13 @@ #include "handlers.h" #include "txbuf.h" -/* FIXME: probably should return the invoke ID for confirmed request */ -bool Send_Write_Property_Request( +/* returns the invoke ID for confirmed request, or zero on failure */ +uint8_t Send_Write_Property_Request( uint32_t device_id, // destination device BACNET_OBJECT_TYPE object_type, uint32_t object_instance, BACNET_PROPERTY_ID object_property, - BACNET_APPLICATION_DATA_VALUE object_value, + BACNET_APPLICATION_DATA_VALUE *object_value, uint8_t priority, int32_t array_index) { @@ -81,7 +81,7 @@ bool Send_Write_Property_Request( data.object_instance = object_instance; data.object_property = object_property; data.array_index = array_index; - data.value = object_value; + bacapp_copy(&data.value,object_value); data.priority = priority; pdu_len += wp_encode_apdu( &Handler_Transmit_Buffer[pdu_len], @@ -103,9 +103,7 @@ bool Send_Write_Property_Request( &dest, // destination address &Handler_Transmit_Buffer[0], pdu_len); // number of bytes of data - if (bytes_sent > 0) - fprintf(stderr,"Sent ReadProperty Request!\n"); - else + if (bytes_sent <= 0) fprintf(stderr,"Failed to Send WriteProperty Request (%s)!\n", strerror(errno)); } @@ -114,6 +112,6 @@ bool Send_Write_Property_Request( "(exceeds destination maximum APDU)!\n"); } - return status; + return invoke_id; } diff --git a/bacnet-stack/demo/object/bacfile.c b/bacnet-stack/demo/object/bacfile.c index 4f316da4..8b8cf6a6 100644 --- a/bacnet-stack/demo/object/bacfile.c +++ b/bacnet-stack/demo/object/bacfile.c @@ -239,6 +239,7 @@ uint32_t bacfile_instance(char *filename) return instance; } +#if TSM_ENABLED // this is one way to match up the invoke ID with // the file ID from the AtomicReadFile request. // Another way would be to store the @@ -300,6 +301,7 @@ uint32_t bacfile_instance_from_tsm( return object_instance; } +#endif bool bacfile_read_data(BACNET_ATOMIC_READ_FILE_DATA *data) { diff --git a/bacnet-stack/demo/object/bacfile.h b/bacnet-stack/demo/object/bacfile.h index 3c83f990..e046caed 100644 --- a/bacnet-stack/demo/object/bacfile.h +++ b/bacnet-stack/demo/object/bacfile.h @@ -50,6 +50,7 @@ bool bacfile_valid_instance(uint32_t object_instance); uint32_t bacfile_count(void); uint32_t bacfile_index_to_instance(unsigned find_index); uint32_t bacfile_instance(char *filename); +#if TSM_ENABLED // this is one way to match up the invoke ID with // the file ID from the AtomicReadFile request. // Another way would be to store the @@ -57,6 +58,7 @@ uint32_t bacfile_instance(char *filename); // when the request was sent uint32_t bacfile_instance_from_tsm( uint8_t invokeID); +#endif // AtomicReadFile ACK helper bool bacfile_read_data(BACNET_ATOMIC_READ_FILE_DATA *data); diff --git a/bacnet-stack/demo/object/device.c b/bacnet-stack/demo/object/device.c index ba5c4a65..e1ee2afd 100644 --- a/bacnet-stack/demo/object/device.c +++ b/bacnet-stack/demo/object/device.c @@ -478,7 +478,7 @@ int Device_Encode_Property_APDU( break; case PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED: bitstring_init(&bit_string); - for (i = 0; i < MAX_BACNET_OBJECT_TYPES; i++) + for (i = 0; i < MAX_ASHRAE_OBJECT_TYPE; i++) { // initialize all the object types to not-supported bitstring_set_bit(&bit_string, (uint8_t)i, false); diff --git a/bacnet-stack/demo/readfile/makefile.mak b/bacnet-stack/demo/readfile/makefile.mak index e3994290..d457fbbf 100644 --- a/bacnet-stack/demo/readfile/makefile.mak +++ b/bacnet-stack/demo/readfile/makefile.mak @@ -15,7 +15,7 @@ PRODUCT = bacarf PRODUCT_EXE = $(PRODUCT).exe # Choose the Data Link Layer to Enable -DEFINES = -DBACDL_BIP=1 +DEFINES = -DBACDL_BIP=1;TSM_ENABLED=1 SRCS = readfile.c \ ..\..\ports\win32\bip-init.c \ diff --git a/bacnet-stack/demo/readfile/readfile.c b/bacnet-stack/demo/readfile/readfile.c index b6f83e63..7143fb4f 100644 --- a/bacnet-stack/demo/readfile/readfile.c +++ b/bacnet-stack/demo/readfile/readfile.c @@ -51,8 +51,8 @@ static uint8_t Rx_Buf[MAX_MPDU] = {0}; /* global variables used in this file */ -static uint32_t Target_File_Object_Instance = 4194303; -static uint32_t Target_Device_Object_Instance = 4194303; +static uint32_t Target_File_Object_Instance = BACNET_MAX_INSTANCE; +static uint32_t Target_Device_Object_Instance = BACNET_MAX_INSTANCE; static BACNET_ADDRESS Target_Address; static char *Local_File_Name = NULL; static bool End_Of_File_Detected = false; diff --git a/bacnet-stack/demo/readprop/makefile.mak b/bacnet-stack/demo/readprop/makefile.mak new file mode 100644 index 00000000..60f006b4 --- /dev/null +++ b/bacnet-stack/demo/readprop/makefile.mak @@ -0,0 +1,146 @@ +# +# Simple makefile to build an executable for Win32 +# +# This makefile assumes Borland bcc32 development environment +# on Windows NT/9x/2000/XP +# + +!ifndef BORLAND_DIR +BORLAND_DIR_Not_Defined: + @echo . + @echo You must define environment variable BORLAND_DIR to compile. +!endif + +PRODUCT = bacrp +PRODUCT_EXE = $(PRODUCT).exe + +# Choose the Data Link Layer to Enable +DEFINES = -DBACDL_BIP=1;TSM_ENABLED=1 + +SRCS = readprop.c \ + ..\..\ports\win32\bip-init.c \ + ..\..\filename.c \ + ..\..\bip.c \ + ..\..\demo\handler\txbuf.c \ + ..\..\demo\handler\noserv.c \ + ..\..\demo\handler\h_whois.c \ + ..\..\demo\handler\h_iam.c \ + ..\..\demo\handler\h_rp.c \ + ..\..\demo\handler\h_rp_a.c \ + ..\..\demo\handler\s_rp.c \ + ..\..\demo\handler\s_whois.c \ + ..\..\bacdcode.c \ + ..\..\bacapp.c \ + ..\..\bacstr.c \ + ..\..\bactext.c \ + ..\..\indtext.c \ + ..\..\bigend.c \ + ..\..\whois.c \ + ..\..\iam.c \ + ..\..\rp.c \ + ..\..\wp.c \ + ..\..\arf.c \ + ..\..\awf.c \ + ..\..\demo\object\bacfile.c \ + ..\..\demo\object\device.c \ + ..\..\demo\object\ai.c \ + ..\..\demo\object\ao.c \ + ..\..\datalink.c \ + ..\..\tsm.c \ + ..\..\address.c \ + ..\..\abort.c \ + ..\..\reject.c \ + ..\..\bacerror.c \ + ..\..\apdu.c \ + ..\..\npdu.c + +OBJS = $(SRCS:.c=.obj) + +# Compiler definitions +# +CC = $(BORLAND_DIR)\bin\bcc32 +bcc32.cfg +#LINK = $(BORLAND_DIR)\bin\tlink32 +LINK = $(BORLAND_DIR)\bin\ilink32 +TLIB = $(BORLAND_DIR)\bin\tlib + +# +# Include directories +# +CC_DIR = $(BORLAND_DIR)\BIN +INCL_DIRS = -I$(BORLAND_DIR)\include;..\..\;..\..\demo\object\;..\..\demo\handler\;..\..\ports\win32\;. + +CFLAGS = $(INCL_DIRS) $(CS_FLAGS) $(DEFINES) + +# Libraries +# +C_LIB_DIR = $(BORLAND_DIR)\lib + +LIBS = $(C_LIB_DIR)\IMPORT32.lib \ +$(C_LIB_DIR)\CW32MT.lib + +# +# Main target +# +# This should be the first one in the makefile + +all : bcc32.cfg $(PRODUCT_EXE) + +# Linker specific: the link below is for BCC linker/compiler. If you link +# with a different linker - please change accordingly. +# + +# need a temp response file (@&&) because command line is too long +$(PRODUCT_EXE) : $(OBJS) + @echo Running Linker for $(PRODUCT_EXE) + $(LINK) -L$(C_LIB_DIR) -m -c -s -v @&&| # temp response file, starts with | + $(BORLAND_DIR)\lib\c0x32.obj $** # $** lists each dependency + $< + $*.map + $(LIBS) +| # end of temp response file + +# +# Utilities + +clean : + @echo Deleting obj files, $(PRODUCT_EXE) and map files. +# del $(OBJS) # command too long, bummer! + del *.obj + del ..\..\*.obj + del ..\..\demo\handler\*.obj + del ..\..\demo\object\*.obj + del ..\..\ports\win32\*.obj + del $(PRODUCT_EXE) + del *.map + del bcc32.cfg + +# +# Generic rules +# +.SUFFIXES: .cpp .c .sbr .obj + +# +# cc generic rule +# +.c.obj: + $(CC) -o$@ $< + +# Compiler configuration file +bcc32.cfg : + Copy &&| +$(CFLAGS) +-c +-y #include line numbers in OBJ's +-v #include debug info +-w+ #turn on all warnings +-Od #disable all optimizations +#-a4 #32 bit data alignment +#-M # generate link map +#-ls # linker options +#-WM- #not multithread +-WM #multithread +-w-aus # ignore warning assigned a value that is never used +-w-sig # ignore warning conversion may lose sig digits +| $@ + +# EOF: makefile diff --git a/bacnet-stack/demo/readprop/readprop.c b/bacnet-stack/demo/readprop/readprop.c new file mode 100644 index 00000000..d66f67af --- /dev/null +++ b/bacnet-stack/demo/readprop/readprop.c @@ -0,0 +1,275 @@ +/************************************************************************** +* +* Copyright (C) 2006 Steve Karg +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +* +*********************************************************************/ + +/* READPROP: command line tool that reads a property from a BACnet device. */ +#include +#include +#include +#include +#include /* for time */ +#include +#include "bactext.h" +#include "iam.h" +#include "arf.h" +#include "tsm.h" +#include "address.h" +#include "config.h" +#include "bacdef.h" +#include "npdu.h" +#include "apdu.h" +#include "device.h" +#include "net.h" +#include "datalink.h" +#include "whois.h" +/* some demo stuff needed */ +#include "filename.h" +#include "handlers.h" +#include "client.h" +#include "txbuf.h" + +// buffer used for receive +static uint8_t Rx_Buf[MAX_MPDU] = {0}; + +/* global variables used in this file */ +static uint32_t Target_Device_Object_Instance = BACNET_MAX_INSTANCE; +static uint32_t Target_Object_Instance = BACNET_MAX_INSTANCE; +static BACNET_OBJECT_TYPE Target_Object_Type = OBJECT_ANALOG_INPUT; +static BACNET_PROPERTY_ID Target_Object_Property = PROP_ACKED_TRANSITIONS; +static int32_t Target_Object_Index = BACNET_ARRAY_ALL; + +static BACNET_ADDRESS Target_Address; +static bool Error_Detected = false; + +static void MyErrorHandler( + BACNET_ADDRESS *src, + uint8_t invoke_id, + BACNET_ERROR_CLASS error_class, + BACNET_ERROR_CODE error_code) +{ + /* FIXME: verify src and invoke id */ + (void)src; + (void)invoke_id; + printf("\r\nBACnet Error!\r\n"); + printf("Error Class: %s\r\n", + bactext_error_class_name(error_class)); + printf("Error Code: %s\r\n", + bactext_error_code_name(error_code)); + Error_Detected = true; +} + +void MyAbortHandler( + BACNET_ADDRESS *src, + uint8_t invoke_id, + uint8_t abort_reason) +{ + /* FIXME: verify src and invoke id */ + (void)src; + (void)invoke_id; + printf("\r\nBACnet Abort!\r\n"); + printf("Abort Reason: %s\r\n", + bactext_abort_reason_name(abort_reason)); + Error_Detected = true; +} + +void MyRejectHandler( + BACNET_ADDRESS *src, + uint8_t invoke_id, + uint8_t reject_reason) +{ + /* FIXME: verify src and invoke id */ + (void)src; + (void)invoke_id; + printf("\r\nBACnet Reject!\r\n"); + printf("Reject Reason: %s\r\n", + bactext_reject_reason_name(reject_reason)); + Error_Detected = true; +} + +static void Init_Service_Handlers(void) +{ + /* we need to handle who-is + to support dynamic device binding to us */ + apdu_set_unconfirmed_handler( + SERVICE_UNCONFIRMED_WHO_IS, + handler_who_is); + /* handle i-am to support binding to other devices */ + apdu_set_unconfirmed_handler( + SERVICE_UNCONFIRMED_I_AM, + handler_i_am_bind); + /* set the handler for all the services we don't implement + It is required to send the proper reject message... */ + apdu_set_unrecognized_service_handler_handler( + handler_unrecognized_service); + /* we must implement read property - it's required! */ + apdu_set_confirmed_handler( + SERVICE_CONFIRMED_READ_PROPERTY, + handler_read_property); + /* handle the data coming back from confirmed requests */ + apdu_set_confirmed_ack_handler( + SERVICE_CONFIRMED_READ_PROPERTY, + handler_read_property_ack); + /* handle any errors coming back */ + apdu_set_error_handler( + SERVICE_CONFIRMED_READ_PROPERTY, + MyErrorHandler); + apdu_set_abort_handler( + MyAbortHandler); + apdu_set_reject_handler( + MyRejectHandler); +} + +int main(int argc, char *argv[]) +{ + BACNET_ADDRESS src = {0}; // address where message came from + uint16_t pdu_len = 0; + unsigned timeout = 100; // milliseconds + unsigned max_apdu = 0; + time_t elapsed_seconds = 0; + time_t last_seconds = 0; + time_t current_seconds = 0; + time_t timeout_seconds = 0; + int fileStartPosition = 0; + uint8_t invoke_id = 0; + bool found = false; + + if (argc < 5) + { + printf("%s device-instance object-type object-instance property [index]\r\n", + filename_remove_path(argv[0])); + return 0; + } + /* decode the command line parameters */ + Target_Device_Object_Instance = strtol(argv[1],NULL,0); + Target_Object_Type = strtol(argv[2],NULL,0); + Target_Object_Instance = strtol(argv[3],NULL,0); + Target_Object_Property = strtol(argv[4],NULL,0); + if (argc > 5) + Target_Object_Index = strtol(argv[5],NULL,0); + if (Target_Device_Object_Instance >= BACNET_MAX_INSTANCE) + { + fprintf(stderr,"device-instance=%u - it must be less than %u\r\n", + Target_Device_Object_Instance,BACNET_MAX_INSTANCE); + return 1; + } + if (Target_Object_Type > MAX_BACNET_OBJECT_TYPE) + { + fprintf(stderr,"object-type=%u - it must be less than %u\r\n", + Target_Object_Type,MAX_BACNET_OBJECT_TYPE+1); + return 1; + } + if (Target_Object_Instance > BACNET_MAX_INSTANCE) + { + fprintf(stderr,"object-instance=%u - it must be less than %u\r\n", + Target_Object_Instance,BACNET_MAX_INSTANCE+1); + return 1; + } + if (Target_Object_Property > MAX_BACNET_PROPERTY_ID) + { + fprintf(stderr,"object-type=%u - it must be less than %u\r\n", + Target_Object_Property,MAX_BACNET_PROPERTY_ID+1); + return 1; + } + + /* setup my info */ + Device_Set_Object_Instance_Number(BACNET_MAX_INSTANCE); + address_init(); + Init_Service_Handlers(); + /* configure standard BACnet/IP port */ + bip_set_interface("eth0"); /* for linux */ + bip_set_port(0xBAC0); + if (!bip_init()) + return 1; + /* configure the timeout values */ + last_seconds = time(NULL); + timeout_seconds = (Device_APDU_Timeout() / 1000) * + Device_Number_Of_APDU_Retries(); + /* try to bind with the device */ + Send_WhoIs(Target_Device_Object_Instance,Target_Device_Object_Instance); + /* loop forever */ + for (;;) + { + /* increment timer - exit if timed out */ + current_seconds = time(NULL); + + /* returns 0 bytes on timeout */ + pdu_len = bip_receive( + &src, + &Rx_Buf[0], + MAX_MPDU, + timeout); + + /* process */ + if (pdu_len) + { + npdu_handler( + &src, + &Rx_Buf[0], + pdu_len); + } + /* at least one second has passed */ + if (current_seconds != last_seconds) + tsm_timer_milliseconds(((current_seconds - last_seconds) * 1000)); + if (Error_Detected) + break; + if (I_Am_Request) + { + I_Am_Request = false; + iam_send(&Handler_Transmit_Buffer[0]); + } + else + { + /* wait until the device is bound, or timeout and quit */ + found = address_bind_request( + Target_Device_Object_Instance, + &max_apdu, + &Target_Address); + if (found) + { + if (invoke_id == 0) + { + invoke_id = Send_Read_Property_Request( + Target_Device_Object_Instance, + Target_Object_Type, + Target_Object_Instance, + Target_Object_Property, + Target_Object_Index); + } + else if (tsm_invoke_id_free(invoke_id)) + break; + } + else + { + /* increment timer - exit if timed out */ + elapsed_seconds += (current_seconds - last_seconds); + if (elapsed_seconds > timeout_seconds) + break; + } + } + /* keep track of time for next check */ + last_seconds = current_seconds; + } + + return 0; +} diff --git a/bacnet-stack/demo/server/makefile.mak b/bacnet-stack/demo/server/makefile.mak new file mode 100644 index 00000000..20a6b982 --- /dev/null +++ b/bacnet-stack/demo/server/makefile.mak @@ -0,0 +1,143 @@ +# +# Simple makefile to build an executable for Win32 +# +# This makefile assumes Borland bcc32 development environment +# on Windows NT/9x/2000/XP +# + +!ifndef BORLAND_DIR +BORLAND_DIR_Not_Defined: + @echo . + @echo You must define environment variable BORLAND_DIR to compile. +!endif + +PRODUCT = bacserv +PRODUCT_EXE = $(PRODUCT).exe + +# Choose the Data Link Layer to Enable +# Note: unless some other drivers are installed, BIP is the only +# datalink layer that Win32 supports +DEFINES = -DBACDL_BIP=1;USE_INADDR=1 + +SRCS = server.c \ + ..\..\ports\win32\bip-init.c \ + ..\..\bip.c \ + ..\..\demo\handler\txbuf.c \ + ..\..\demo\handler\noserv.c \ + ..\..\demo\handler\h_whois.c \ + ..\..\demo\handler\h_rp.c \ + ..\..\demo\handler\h_wp.c \ + ..\..\demo\handler\h_arf.c \ + ..\..\bacdcode.c \ + ..\..\bacapp.c \ + ..\..\bacstr.c \ + ..\..\bactext.c \ + ..\..\indtext.c \ + ..\..\bigend.c \ + ..\..\whois.c \ + ..\..\iam.c \ + ..\..\rp.c \ + ..\..\wp.c \ + ..\..\arf.c \ + ..\..\awf.c \ + ..\..\demo\object\bacfile.c \ + ..\..\demo\object\device.c \ + ..\..\demo\object\ai.c \ + ..\..\demo\object\ao.c \ + ..\..\datalink.c \ + ..\..\abort.c \ + ..\..\reject.c \ + ..\..\bacerror.c \ + ..\..\apdu.c \ + ..\..\npdu.c + +OBJS = $(SRCS:.c=.obj) + +# Compiler definitions +# +CC = $(BORLAND_DIR)\bin\bcc32 +bcc32.cfg +#LINK = $(BORLAND_DIR)\bin\tlink32 +LINK = $(BORLAND_DIR)\bin\ilink32 +TLIB = $(BORLAND_DIR)\bin\tlib + +# +# Include directories +# +CC_DIR = $(BORLAND_DIR)\BIN +INCL_DIRS = -I$(BORLAND_DIR)\include;..\..\;..\..\demo\object\;..\..\demo\handler\;..\..\ports\win32\;. + +CFLAGS = $(INCL_DIRS) $(CS_FLAGS) $(DEFINES) + +# Libraries +# +C_LIB_DIR = $(BORLAND_DIR)\lib + +LIBS = $(C_LIB_DIR)\IMPORT32.lib \ +$(C_LIB_DIR)\CW32MT.lib + +# +# Main target +# +# This should be the first one in the makefile + +all : bcc32.cfg $(PRODUCT_EXE) + +# Linker specific: the link below is for BCC linker/compiler. If you link +# with a different linker - please change accordingly. +# + +# need a temp response file (@&&) because command line is too long +$(PRODUCT_EXE) : $(OBJS) + @echo Running Linker for $(PRODUCT_EXE) + $(LINK) -L$(C_LIB_DIR) -m -c -s -v @&&| # temp response file, starts with | + $(BORLAND_DIR)\lib\c0x32.obj $** # $** lists each dependency + $< + $*.map + $(LIBS) +| # end of temp response file + +# +# Utilities + +clean : + @echo Deleting obj files, $(PRODUCT_EXE) and map files. +# del $(OBJS) # command too long, bummer! + del *.obj + del ..\..\*.obj + del ..\..\demo\handler\*.obj + del ..\..\demo\object\*.obj + del ..\..\ports\win32\*.obj + del $(PRODUCT_EXE) + del *.map + del bcc32.cfg + +# +# Generic rules +# +.SUFFIXES: .cpp .c .sbr .obj + +# +# cc generic rule +# +.c.obj: + $(CC) -o$@ $< + +# Compiler configuration file +bcc32.cfg : + Copy &&| +$(CFLAGS) +-c +-y #include line numbers in OBJ's +-v #include debug info +-w+ #turn on all warnings +-Od #disable all optimizations +#-a4 #32 bit data alignment +#-M # generate link map +#-ls # linker options +#-WM- #not multithread +-WM #multithread +-w-aus # ignore warning assigned a value that is never used +-w-sig # ignore warning conversion may lose sig digits +| $@ + +# EOF: makefile diff --git a/bacnet-stack/demo/server/server.c b/bacnet-stack/demo/server/server.c new file mode 100644 index 00000000..afe8bc3a --- /dev/null +++ b/bacnet-stack/demo/server/server.c @@ -0,0 +1,165 @@ +/************************************************************************** +* +* Copyright (C) 2006 Steve Karg +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +* +*********************************************************************/ +#include +#include +#include +#include +#include +#include +#include "config.h" +#include "address.h" +#include "bacdef.h" +#include "handlers.h" +#include "client.h" +#include "bacdcode.h" +#include "npdu.h" +#include "apdu.h" +#include "iam.h" +#include "tsm.h" +#include "device.h" +#include "bacfile.h" +#include "datalink.h" +#include "net.h" +#include "txbuf.h" + +/* This is an example application using the BACnet Stack */ + +/* buffers used for receiving */ +static uint8_t Rx_Buf[MAX_MPDU] = {0}; + +static void Init_Service_Handlers(void) +{ + /* we need to handle who-is to support dynamic device binding */ + apdu_set_unconfirmed_handler( + SERVICE_UNCONFIRMED_WHO_IS, + handler_who_is); + + /* set the handler for all the services we don't implement */ + /* It is required to send the proper reject message... */ + apdu_set_unrecognized_service_handler_handler( + handler_unrecognized_service); + /* Set the handlers for any confirmed services that we support. */ + /* We must implement read property - it's required! */ + apdu_set_confirmed_handler( + SERVICE_CONFIRMED_READ_PROPERTY, + handler_read_property); + apdu_set_confirmed_handler( + SERVICE_CONFIRMED_WRITE_PROPERTY, + handler_write_property); + apdu_set_confirmed_handler( + SERVICE_CONFIRMED_ATOMIC_READ_FILE, + handler_atomic_read_file); +} + +static void cleanup(void) +{ + datalink_cleanup(); +} + +static void print_address( + char *name, + BACNET_ADDRESS *dest) // destination address +{ + int i = 0; // counter + + if (dest) + { + printf("%s: ",name); + for (i = 0; i < dest->mac_len; i++) + { + printf("%02X",dest->mac[i]); + } + printf("\n"); + } +} + +int main(int argc, char *argv[]) +{ + BACNET_ADDRESS src = {0}; // address where message came from + uint16_t pdu_len = 0; + unsigned timeout = 100; // milliseconds + BACNET_ADDRESS my_address, broadcast_address; + + /* allow the device ID to be set */ + if (argc > 1) + Device_Set_Object_Instance_Number(strtol(argv[1],NULL,0)); + if (argc > 2) + bip_set_port(strtol(argv[2],NULL,0)); + printf("BACnet Server Demo - Device #%lu\r\n", + Device_Object_Instance_Number()); + Init_Service_Handlers(); + #ifdef BACDL_ETHERNET + // init the physical layer + if (!ethernet_init("eth0")) + return 1; + #endif + #ifdef BACDL_BIP + bip_set_interface("eth0"); + if (!bip_init()) + return 1; + printf("bip: using port %hu\r\n",bip_get_port()); + #endif + #ifdef BACDL_ARCNET + if (!arcnet_init("arc0")) + return 1; + #endif + datalink_get_broadcast_address(&broadcast_address); + print_address("Broadcast",&broadcast_address); + datalink_get_my_address(&my_address); + print_address("Address",&my_address); + atexit(cleanup); + + /* broadcast an I-Am on startup */ + I_Am_Request = true; + // loop forever + for (;;) + { + // input + + // returns 0 bytes on timeout + pdu_len = datalink_receive( + &src, + &Rx_Buf[0], + MAX_MPDU, + timeout); + + // process + if (pdu_len) + { + npdu_handler( + &src, + &Rx_Buf[0], + pdu_len); + } + if (I_Am_Request) + { + I_Am_Request = false; + iam_send(&Handler_Transmit_Buffer[0]); + } + // output + + // blink LEDs, Turn on or off outputs, etc + } +} diff --git a/bacnet-stack/demo/writeprop/makefile.mak b/bacnet-stack/demo/writeprop/makefile.mak new file mode 100644 index 00000000..3bc492cd --- /dev/null +++ b/bacnet-stack/demo/writeprop/makefile.mak @@ -0,0 +1,145 @@ +# +# Simple makefile to build an executable for Win32 +# +# This makefile assumes Borland bcc32 development environment +# on Windows NT/9x/2000/XP +# + +!ifndef BORLAND_DIR +BORLAND_DIR_Not_Defined: + @echo . + @echo You must define environment variable BORLAND_DIR to compile. +!endif + +PRODUCT = bacwp +PRODUCT_EXE = $(PRODUCT).exe + +# Choose the Data Link Layer to Enable +DEFINES = -DBACDL_BIP=1;TSM_ENABLED=1 + +SRCS = writeprop.c \ + ..\..\ports\win32\bip-init.c \ + ..\..\filename.c \ + ..\..\bip.c \ + ..\..\demo\handler\txbuf.c \ + ..\..\demo\handler\noserv.c \ + ..\..\demo\handler\h_whois.c \ + ..\..\demo\handler\h_iam.c \ + ..\..\demo\handler\h_rp.c \ + ..\..\demo\handler\s_wp.c \ + ..\..\demo\handler\s_whois.c \ + ..\..\bacdcode.c \ + ..\..\bacapp.c \ + ..\..\bacstr.c \ + ..\..\bactext.c \ + ..\..\indtext.c \ + ..\..\bigend.c \ + ..\..\whois.c \ + ..\..\iam.c \ + ..\..\rp.c \ + ..\..\wp.c \ + ..\..\arf.c \ + ..\..\awf.c \ + ..\..\demo\object\bacfile.c \ + ..\..\demo\object\device.c \ + ..\..\demo\object\ai.c \ + ..\..\demo\object\ao.c \ + ..\..\datalink.c \ + ..\..\tsm.c \ + ..\..\address.c \ + ..\..\abort.c \ + ..\..\reject.c \ + ..\..\bacerror.c \ + ..\..\apdu.c \ + ..\..\npdu.c + +OBJS = $(SRCS:.c=.obj) + +# Compiler definitions +# +CC = $(BORLAND_DIR)\bin\bcc32 +bcc32.cfg +#LINK = $(BORLAND_DIR)\bin\tlink32 +LINK = $(BORLAND_DIR)\bin\ilink32 +TLIB = $(BORLAND_DIR)\bin\tlib + +# +# Include directories +# +CC_DIR = $(BORLAND_DIR)\BIN +INCL_DIRS = -I$(BORLAND_DIR)\include;..\..\;..\..\demo\object\;..\..\demo\handler\;..\..\ports\win32\;. + +CFLAGS = $(INCL_DIRS) $(CS_FLAGS) $(DEFINES) + +# Libraries +# +C_LIB_DIR = $(BORLAND_DIR)\lib + +LIBS = $(C_LIB_DIR)\IMPORT32.lib \ +$(C_LIB_DIR)\CW32MT.lib + +# +# Main target +# +# This should be the first one in the makefile + +all : bcc32.cfg $(PRODUCT_EXE) + +# Linker specific: the link below is for BCC linker/compiler. If you link +# with a different linker - please change accordingly. +# + +# need a temp response file (@&&) because command line is too long +$(PRODUCT_EXE) : $(OBJS) + @echo Running Linker for $(PRODUCT_EXE) + $(LINK) -L$(C_LIB_DIR) -m -c -s -v @&&| # temp response file, starts with | + $(BORLAND_DIR)\lib\c0x32.obj $** # $** lists each dependency + $< + $*.map + $(LIBS) +| # end of temp response file + +# +# Utilities + +clean : + @echo Deleting obj files, $(PRODUCT_EXE) and map files. +# del $(OBJS) # command too long, bummer! + del *.obj + del ..\..\*.obj + del ..\..\demo\handler\*.obj + del ..\..\demo\object\*.obj + del ..\..\ports\win32\*.obj + del $(PRODUCT_EXE) + del *.map + del bcc32.cfg + +# +# Generic rules +# +.SUFFIXES: .cpp .c .sbr .obj + +# +# cc generic rule +# +.c.obj: + $(CC) -o$@ $< + +# Compiler configuration file +bcc32.cfg : + Copy &&| +$(CFLAGS) +-c +-y #include line numbers in OBJ's +-v #include debug info +-w+ #turn on all warnings +-Od #disable all optimizations +#-a4 #32 bit data alignment +#-M # generate link map +#-ls # linker options +#-WM- #not multithread +-WM #multithread +-w-aus # ignore warning assigned a value that is never used +-w-sig # ignore warning conversion may lose sig digits +| $@ + +# EOF: makefile diff --git a/bacnet-stack/demo/writeprop/writeprop.c b/bacnet-stack/demo/writeprop/writeprop.c new file mode 100644 index 00000000..71bfe1bd --- /dev/null +++ b/bacnet-stack/demo/writeprop/writeprop.c @@ -0,0 +1,312 @@ +/************************************************************************** +* +* Copyright (C) 2006 Steve Karg +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +* +*********************************************************************/ + +/* WRITEPROP: command line tool that writes a property to a BACnet device. */ +#include +#include +#include +#include +#include /* for time */ +#include +#include "bactext.h" +#include "iam.h" +#include "arf.h" +#include "tsm.h" +#include "address.h" +#include "config.h" +#include "bacdef.h" +#include "npdu.h" +#include "apdu.h" +#include "device.h" +#include "net.h" +#include "datalink.h" +#include "whois.h" +/* some demo stuff needed */ +#include "filename.h" +#include "handlers.h" +#include "client.h" +#include "txbuf.h" + +// buffer used for receive +static uint8_t Rx_Buf[MAX_MPDU] = {0}; + +/* global variables used in this file */ +static uint32_t Target_Device_Object_Instance = BACNET_MAX_INSTANCE; +static uint32_t Target_Object_Instance = BACNET_MAX_INSTANCE; +static BACNET_OBJECT_TYPE Target_Object_Type = OBJECT_ANALOG_INPUT; +static BACNET_PROPERTY_ID Target_Object_Property = PROP_ACKED_TRANSITIONS; +static int32_t Target_Object_Property_Index = BACNET_ARRAY_ALL; +static BACNET_APPLICATION_TAG Target_Object_Property_Tag = BACNET_APPLICATION_TAG_NULL; +static BACNET_APPLICATION_DATA_VALUE Target_Object_Property_Value = {0}; + +static BACNET_ADDRESS Target_Address; +static bool Error_Detected = false; + +static void MyErrorHandler( + BACNET_ADDRESS *src, + uint8_t invoke_id, + BACNET_ERROR_CLASS error_class, + BACNET_ERROR_CODE error_code) +{ + /* FIXME: verify src and invoke id */ + (void)src; + (void)invoke_id; + printf("\r\nBACnet Error!\r\n"); + printf("Error Class: %s\r\n", + bactext_error_class_name(error_class)); + printf("Error Code: %s\r\n", + bactext_error_code_name(error_code)); + Error_Detected = true; +} + +void MyAbortHandler( + BACNET_ADDRESS *src, + uint8_t invoke_id, + uint8_t abort_reason) +{ + /* FIXME: verify src and invoke id */ + (void)src; + (void)invoke_id; + printf("\r\nBACnet Abort!\r\n"); + printf("Abort Reason: %s\r\n", + bactext_abort_reason_name(abort_reason)); + Error_Detected = true; +} + +void MyRejectHandler( + BACNET_ADDRESS *src, + uint8_t invoke_id, + uint8_t reject_reason) +{ + /* FIXME: verify src and invoke id */ + (void)src; + (void)invoke_id; + printf("\r\nBACnet Reject!\r\n"); + printf("Reject Reason: %s\r\n", + bactext_reject_reason_name(reject_reason)); + Error_Detected = true; +} + +static void Init_Service_Handlers(void) +{ + /* we need to handle who-is + to support dynamic device binding to us */ + apdu_set_unconfirmed_handler( + SERVICE_UNCONFIRMED_WHO_IS, + handler_who_is); + /* handle i-am to support binding to other devices */ + apdu_set_unconfirmed_handler( + SERVICE_UNCONFIRMED_I_AM, + handler_i_am_bind); + /* set the handler for all the services we don't implement + It is required to send the proper reject message... */ + apdu_set_unrecognized_service_handler_handler( + handler_unrecognized_service); + /* we must implement read property - it's required! */ + apdu_set_confirmed_handler( + SERVICE_CONFIRMED_READ_PROPERTY, + handler_read_property); + /* handle the data coming back from confirmed requests */ + apdu_set_confirmed_ack_handler( + SERVICE_CONFIRMED_READ_PROPERTY, + handler_read_property_ack); + /* handle any errors coming back */ + apdu_set_error_handler( + SERVICE_CONFIRMED_READ_PROPERTY, + MyErrorHandler); + apdu_set_abort_handler( + MyAbortHandler); + apdu_set_reject_handler( + MyRejectHandler); +} + +int main(int argc, char *argv[]) +{ + BACNET_ADDRESS src = {0}; // address where message came from + uint16_t pdu_len = 0; + unsigned timeout = 100; // milliseconds + unsigned max_apdu = 0; + time_t elapsed_seconds = 0; + time_t last_seconds = 0; + time_t current_seconds = 0; + time_t timeout_seconds = 0; + int fileStartPosition = 0; + uint8_t invoke_id = 0; + bool found = false; + char *value_string = NULL; + + if (argc < 7) + { + printf("%s device-instance object-type object-instance property [index] tag value\r\n", + filename_remove_path(argv[0])); + return 0; + } + /* decode the command line parameters */ + Target_Device_Object_Instance = strtol(argv[1],NULL,0); + Target_Object_Type = strtol(argv[2],NULL,0); + Target_Object_Instance = strtol(argv[3],NULL,0); + Target_Object_Property = strtol(argv[4],NULL,0); + /* optional index */ + if (argc > 7) + { + Target_Object_Property_Index = strtol(argv[5],NULL,0); + Target_Object_Property_Tag = strtol(argv[6],NULL,0); + value_string = argv[7]; + } + else + { + Target_Object_Property_Tag = strtol(argv[5],NULL,0); + value_string = argv[6]; + } + + if (Target_Device_Object_Instance >= BACNET_MAX_INSTANCE) + { + fprintf(stderr,"device-instance=%u - it must be less than %u\r\n", + Target_Device_Object_Instance,BACNET_MAX_INSTANCE); + return 1; + } + if (Target_Object_Type > MAX_BACNET_OBJECT_TYPE) + { + fprintf(stderr,"object-type=%u - it must be less than %u\r\n", + Target_Object_Type,MAX_BACNET_OBJECT_TYPE+1); + return 1; + } + if (Target_Object_Instance > BACNET_MAX_INSTANCE) + { + fprintf(stderr,"object-instance=%u - it must be less than %u\r\n", + Target_Object_Instance,BACNET_MAX_INSTANCE+1); + return 1; + } + if (Target_Object_Property > MAX_BACNET_PROPERTY_ID) + { + fprintf(stderr,"object-type=%u - it must be less than %u\r\n", + Target_Object_Property,MAX_BACNET_PROPERTY_ID+1); + return 1; + } + if (Target_Object_Property_Tag >= MAX_BACNET_APPLICATION_TAG) + { + fprintf(stderr,"tag=%u - it must be less than %u\r\n", + Target_Object_Property_Tag,MAX_BACNET_APPLICATION_TAG); + return 1; + } + status = bacapp_parse_application_data( + Target_Object_Property_Tag, + value_string, + &Target_Object_Property_Value); + if (!status) + { + /* FIXME: show the expected entry format for the tag */ + fprintf(stderr,"unable to parse the tag value\r\n"); + return 1; + } + + /* setup my info */ + Device_Set_Object_Instance_Number(BACNET_MAX_INSTANCE); + address_init(); + Init_Service_Handlers(); + /* configure standard BACnet/IP port */ + bip_set_interface("eth0"); /* for linux */ + bip_set_port(0xBAC0); + if (!bip_init()) + return 1; + /* configure the timeout values */ + last_seconds = time(NULL); + timeout_seconds = (Device_APDU_Timeout() / 1000) * + Device_Number_Of_APDU_Retries(); + /* try to bind with the device */ + Send_WhoIs(Target_Device_Object_Instance,Target_Device_Object_Instance); + /* loop forever */ + for (;;) + { + /* increment timer - exit if timed out */ + current_seconds = time(NULL); + + /* returns 0 bytes on timeout */ + pdu_len = bip_receive( + &src, + &Rx_Buf[0], + MAX_MPDU, + timeout); + + /* process */ + if (pdu_len) + { + npdu_handler( + &src, + &Rx_Buf[0], + pdu_len); + } + /* at least one second has passed */ + if (current_seconds != last_seconds) + tsm_timer_milliseconds(((current_seconds - last_seconds) * 1000)); + if (Error_Detected) + break; + if (I_Am_Request) + { + I_Am_Request = false; + iam_send(&Handler_Transmit_Buffer[0]); + } + else + { + /* wait until the device is bound, or timeout and quit */ + found = address_bind_request( + Target_Device_Object_Instance, + &max_apdu, + &Target_Address); + if (found) + { + if (invoke_id == 0) + { + invoke_id = Send_Write_Property_Request( + uint32_t device_id, // destination device + BACNET_OBJECT_TYPE object_type, + uint32_t object_instance, + BACNET_PROPERTY_ID object_property, + BACNET_APPLICATION_DATA_VALUE object_value, + uint8_t priority, + int32_t array_index) + Target_Device_Object_Instance, + Target_Object_Type, + Target_Object_Instance, + Target_Object_Property, + Target_Object_Property_Index); + } + else if (tsm_invoke_id_free(invoke_id)) + break; + } + else + { + /* increment timer - exit if timed out */ + elapsed_seconds += (current_seconds - last_seconds); + if (elapsed_seconds > timeout_seconds) + break; + } + } + /* keep track of time for next check */ + last_seconds = current_seconds; + } + + return 0; +} diff --git a/bacnet-stack/filename.c b/bacnet-stack/filename.c new file mode 100644 index 00000000..dd9313b8 --- /dev/null +++ b/bacnet-stack/filename.c @@ -0,0 +1,103 @@ +/*####COPYRIGHTBEGIN#### + ------------------------------------------- + Copyright (C) 2006 Steve Karg + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to: + The Free Software Foundation, Inc. + 59 Temple Place - Suite 330 + Boston, MA 02111-1307, USA. + + As a special exception, if other files instantiate templates or + use macros or inline functions from this file, or you compile + this file and link it with other works to produce a work based + on this file, this file does not by itself cause the resulting + work to be covered by the GNU General Public License. However + the source code for this file must still be made available in + accordance with section (3) of the GNU General Public License. + + This exception does not invalidate any other reasons why a work + based on this file might be covered by the GNU General Public + License. + ------------------------------------------- +####COPYRIGHTEND####*/ +#include +#include + +char *filename_remove_path(const char *filename_in) +{ + char *filename_out = NULL; + + /* allow the device ID to be set */ + if (filename_in) + { + filename_out = strrchr(filename_in,'\\'); + if (!filename_out) + filename_out = strrchr(filename_in,'/'); + /* go beyond the slash */ + if (filename_out) + filename_out++; + } + + return filename_out; +} + +#ifdef TEST +#include +#include + +#include "ctest.h" + +void testFilename(Test* pTest) +{ + char *data1 = "c:\\Joshua\\run"; + char *data2 = "/home/Anna/run"; + char *data3 = "c:\\Program Files\\Christopher\\run.exe"; + char *data4 = "//Mary/data/run"; + char *filename = NULL; + + filename = filename_remove_path(data1); + ct_test(pTest,strcmp("run",filename) == 0); + filename = filename_remove_path(data2); + ct_test(pTest,strcmp("run",filename) == 0); + filename = filename_remove_path(data3); + ct_test(pTest,strcmp("run.exe",filename) == 0); + filename = filename_remove_path(data4); + ct_test(pTest,strcmp("run",filename) == 0); + + return; +} + +#ifdef TEST_FILENAME +int main(void) +{ + Test *pTest; + bool rc; + + pTest = ct_create("filename remove path", NULL); + + /* individual tests */ + rc = ct_addTestFunction(pTest, testFilename); + assert(rc); + + ct_setStream(pTest, stdout); + ct_run(pTest); + (void)ct_report(pTest); + + ct_destroy(pTest); + + return 0; +} +#endif /* TEST_FILENAME */ +#endif /* TEST */ + diff --git a/bacnet-stack/filename.h b/bacnet-stack/filename.h new file mode 100644 index 00000000..8ef78d22 --- /dev/null +++ b/bacnet-stack/filename.h @@ -0,0 +1,47 @@ +/*####COPYRIGHTBEGIN#### + ------------------------------------------- + Copyright (C) 2006 Steve Karg + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to: + The Free Software Foundation, Inc. + 59 Temple Place - Suite 330 + Boston, MA 02111-1307, USA. + + As a special exception, if other files instantiate templates or + use macros or inline functions from this file, or you compile + this file and link it with other works to produce a work based + on this file, this file does not by itself cause the resulting + work to be covered by the GNU General Public License. However + the source code for this file must still be made available in + accordance with section (3) of the GNU General Public License. + + This exception does not invalidate any other reasons why a work + based on this file might be covered by the GNU General Public + License. + ------------------------------------------- +####COPYRIGHTEND####*/ +#ifndef FILENAME_H +#define FILENAME_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +char *filename_remove_path(const char *filename_in); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif diff --git a/bacnet-stack/filename.ide b/bacnet-stack/filename.ide new file mode 100644 index 0000000000000000000000000000000000000000..38d3cdf89835c1f3900a7dc7b61f4d02ea1178de GIT binary patch literal 29058 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 literal 0 HcmV?d00001 diff --git a/bacnet-stack/iam.c b/bacnet-stack/iam.c index cfa0f67b..a070841b 100755 --- a/bacnet-stack/iam.c +++ b/bacnet-stack/iam.c @@ -199,32 +199,6 @@ int iam_send(uint8_t *buffer) return bytes_sent; } -void iam_handler( - uint8_t *service_request, - uint16_t service_len, - BACNET_ADDRESS *src) -{ - int len = 0; - uint32_t device_id = 0; - unsigned max_apdu = 0; - int segmentation = 0; - uint16_t vendor_id = 0; - - (void)service_len; - len = iam_decode_service_request( - service_request, - &device_id, - &max_apdu, - &segmentation, - &vendor_id); - // only add address if requested to bind - address_add_binding(device_id, - max_apdu, - src); - - return; -} - #ifdef TEST #include #include diff --git a/bacnet-stack/iam.h b/bacnet-stack/iam.h index 2691f136..ebce3ea8 100644 --- a/bacnet-stack/iam.h +++ b/bacnet-stack/iam.h @@ -63,11 +63,6 @@ int iam_decode_apdu( int *pSegmentation, uint16_t *pVendor_id); -void iam_handler( - uint8_t *service_request, - uint16_t service_len, - BACNET_ADDRESS *src); - int iam_send(uint8_t *buffer); #ifdef TEST diff --git a/bacnet-stack/ports/win32/MAKEFILE.MAK b/bacnet-stack/ports/win32/MAKEFILE.MAK index 5dc8303d..163f0afb 100644 --- a/bacnet-stack/ports/win32/MAKEFILE.MAK +++ b/bacnet-stack/ports/win32/MAKEFILE.MAK @@ -15,7 +15,7 @@ PRODUCT = bacnet PRODUCT_EXE = $(PRODUCT).exe # Choose the Data Link Layer to Enable -DEFINES = -DBACDL_BIP=1 +DEFINES = -DBACDL_BIP=1;TSM_ENABLED=1 SRCS = main.c bip-init.c \ ..\..\bip.c \ diff --git a/bacnet-stack/ports/win32/bacnet.ide b/bacnet-stack/ports/win32/bacnet.ide index dd35334a8092da450768620859e052f8ea839326..7c541de79c97a6ebb810ff05e78a97dcec287e73 100644 GIT binary patch delta 17325 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 literal 64426 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 diff --git a/bacnet-stack/ports/win32/bip-init.c b/bacnet-stack/ports/win32/bip-init.c index 4a3180a4..2aee7027 100644 --- a/bacnet-stack/ports/win32/bip-init.c +++ b/bacnet-stack/ports/win32/bip-init.c @@ -63,7 +63,8 @@ static void set_broadcast_address(uint32_t net_address) long broadcast_address = 0; long mask = 0; - #if 0 + #if USE_INADDR + (void)net_address; bip_set_broadcast_addr(INADDR_BROADCAST); #else if (IN_CLASSA(ntohl(net_address))) @@ -102,7 +103,8 @@ bool bip_init(void) WSADATA wd; struct in_addr address; - Result = WSAStartup(MAKEWORD(2,2), &wd); + Result = WSAStartup((1 << 8) | 1, &wd); + //Result = WSAStartup(MAKEWORD(2,2), &wd); if (Result != 0) { Code = WSAGetLastError(); @@ -124,11 +126,14 @@ bool bip_init(void) bip_set_addr(address.s_addr); set_broadcast_address(address.s_addr); - // assumes that the driver has already been initialized + /* assumes that the driver has already been initialized */ sock_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); bip_set_socket(sock_fd); if (sock_fd < 0) + { + fprintf(stderr,"bip: failed to allocate a socket.\n"); return false; + } // Allow us to use the same socket for sending and receiving // This makes sure that the src port is correct when sending @@ -136,6 +141,7 @@ bool bip_init(void) (char *)&value, sizeof(value)); if (rv < 0) { + fprintf(stderr,"bip: failed to set REUSEADDR socket option.\n"); close(sock_fd); bip_set_socket(-1); return false; @@ -145,6 +151,7 @@ bool bip_init(void) (char *)&value, sizeof(value)); if (rv < 0) { + fprintf(stderr,"bip: failed to set BROADCAST socket option.\n"); close(sock_fd); bip_set_socket(-1); return false; @@ -168,11 +175,14 @@ bool bip_init(void) Note: sometimes INADDR_ANY does not let me get any unicast messages. Not sure why... */ - /* sin.sin_addr.s_addr = htonl(INADDR_ANY); */ + #if USE_INADDR + sin.sin_addr.s_addr = htonl(INADDR_ANY); + #else /* or we could use the specific adapter address note: already in network byte order */ - sin.sin_addr.s_addr = address.s_addr; + //sin.sin_addr.s_addr = address.s_addr; sin.sin_port = htons(bip_get_port()); + #endif memset(&(sin.sin_zero), '\0', sizeof(sin.sin_zero)); rv = bind(sock_fd, (const struct sockaddr*)&sin, sizeof(struct sockaddr)); diff --git a/bacnet-stack/ports/win32/main.c b/bacnet-stack/ports/win32/main.c index 6987b210..8ed7c228 100644 --- a/bacnet-stack/ports/win32/main.c +++ b/bacnet-stack/ports/win32/main.c @@ -286,7 +286,7 @@ int main(int argc, char *argv[]) } else { - //Read_Properties(); + Read_Properties(); } // output